feat: Add Intelligent Watchdog automation kit for competitor intelligence#109
Conversation
…/AgentKit_Watchdog into feat/agentic_watchdog
…/AgentKit_Watchdog into feat/agentic_watchdog
WalkthroughRemoved two legacy docs ( Changes
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
HarshM1010
left a comment
There was a problem hiding this comment.
i have resolved the issues
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
Hi @maintainers! All validation checks are now passing, and I've added the required flow directory and metadata. I don't have permissions to add labels myself—could you please add the agentkit-challenge label to this PR so it can be officially tracked? Thank you! |
There was a problem hiding this comment.
Actionable comments posted: 18
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@kits/automation/Watchdog/app/api/analyse/route.ts`:
- Around line 39-41: The handler currently calls req.json() directly and any
malformed JSON bubbles to the outer try/catch producing a generic 500; wrap the
JSON parse in its own try/catch (around the req.json() that assigns body and the
subsequent competitors extraction) and when parsing fails return a 400 Bad
Request Response with a clear message (e.g., "Malformed JSON" or similar)
instead of letting the outer catch handle it; ensure you reference and adjust
the code around the existing req.json() call and the competitors variable so
only the parse error is handled locally.
- Around line 61-76: The fetch to LAMATIC_API_URL in route.ts (the POST using
EXECUTE_WORKFLOW / WATCHDOG_FLOW_ID and payload { competitors }) lacks an
AbortController timeout; create an AbortController, set a setTimeout to call
controller.abort() after a reasonable delay (e.g., 5–10s), pass
controller.signal into the fetch options, and clear the timeout after the
response arrives; also update the catch in the surrounding try/catch to detect
err.name === 'AbortError' and return a 504 NextResponse JSON indicating a
request timeout, otherwise continue returning a 500 for other errors.
In `@kits/automation/Watchdog/app/page.tsx`:
- Around line 149-153: The icon-only remove button (using the Trash2 icon and
calling removeCompetitor(i)) and the icon-only dialog-close control must have
accessible names; add an aria-label (e.g., aria-label="Remove competitor" for
the Trash2 button) and also include a title attribute for hover tooltips, and do
the same for the dialog close control (the close button rendered around lines
274-278—add aria-label="Close dialog" and title="Close dialog" or similar).
Ensure the attributes are added to the actual <button> elements that invoke
removeCompetitor and the dialog close handler so assistive tech and sighted
users both receive a descriptive label.
- Around line 55-63: The parser in page.tsx incorrectly assumes data.result is
raw JSON and references flow internals (raw = data.result; JSON.parse(raw);
codeNode_584), causing failures—update the client to consume the stable API
contract returned by the analyse route ({ status, result }) and the typed result
shape instead of flow-node keys: change code that reads data.result/rawResults
to expect the API's typed result (e.g., the LLMNode_331.output.generatedResponse
mapping) and normalize that single stable field into your Result[] shape before
mapping to cleanResults; remove any hard-coded node ids like codeNode_584 and
JSON.parse calls, validate the result type at runtime, and coerce/convert the
API's result into the Result[] shape used by cleanResults.
- Around line 19-22: Create a shared close handler that not only sets modalOpen
false but also resets newName, newUrl, and error, then replace inline close
logic in the Escape key listener (handleKey in useEffect) and the other close
paths (the handlers around lines 263–267, 275, and 321) to call this single
function; ensure the new function (e.g., closeModal or handleCloseModal) is
referenced wherever modalOpen is currently toggled to false so reopening the
modal never resurrects stale values or validation errors.
- Around line 25-34: When editing the watchlist in addCompetitor or
removeCompetitor (and other edit helpers around those lines), clear the current
reports and protect against stale in-flight responses by adding a request
version/token: 1) call setResults([]) (or setReports([])) immediately after
setCompetitors to clear the UI; 2) increment a requestVersionRef
(useRef<number>) or setRequestVersion(state) whenever the watchlist changes; 3)
in the async runner that commits server responses (the function that currently
writes the response at "line 82" — e.g.,
runWatchlist/fetchReports/handleResponse), capture the current requestVersion
when the request starts and ignore the response unless it matches the latest
requestVersionRef; reference addCompetitor, removeCompetitor, setCompetitors,
setResults (or setReports), and the async response handler to implement this.
- Around line 284-311: Add proper associations between each label and its input
by giving the Organisation Name input (the one bound to newName and using
setNewName/onKeyDown -> addCompetitor) a unique id and set the corresponding
label's htmlFor to that id, and do the same for the Pricing / features / updates
/ Landing URL input (the one bound to newUrl and using setNewUrl/onKeyDown ->
addCompetitor). Ensure ids are unique and stable (e.g., orgNameId and orgUrlId
or generated constants) and keep existing props like autoFocus and onKeyDown
unchanged so clicking the label or using assistive tech focuses and describes
the correct input.
In `@kits/automation/Watchdog/components.json`:
- Around line 6-8: The Tailwind config path under the "tailwind" object is
incorrect (currently set to ".js"); update the "config" value to the actual file
name "tailwind.config.ts" so the shadcn configuration points to the existing
Tailwind config file (edit the "tailwind" -> "config" entry in components.json).
In `@kits/automation/Watchdog/config.json`:
- Around line 22-25: Update the incorrect URLs in config.json: change the
deployUrl's root-directory and repository URL to point to the actual kit path
(use root-directory=kits/automation/Watchdog and repository-url pointing at the
main AgentKit repo), replace githubUrl with the main AgentKit repository URL
(and optionally include a tree path to kits/automation/Watchdog), and update
documentationUrl to the correct docs for this kit (use intelligent-watchdog or
Watchdog path). Edit the keys deployUrl, githubUrl, and documentationUrl to
reflect these corrected coordinates (leave demoUrl as-is if it is correct).
- Around line 9-15: Update the step ID in kits/automation/Watchdog/config.json
from "pricing-watchdog-flow" to match the actual flow folder name
"watchdog-flow" so the step ID aligns with the flow folder; also verify the
envKey "WATCHDOG_FLOW_ID" corresponds to the same flow and adjust it if your
environment variable naming convention requires the folder name (e.g.,
WATCHDOG_FLOW_ID) to match the step ID change.
In `@kits/automation/Watchdog/flows/watchdog-flow/config.json`:
- Around line 12-14: The outputMapping currently points to a non-existent node
id LLMNode_331 (result: "{{LLMNode_331.output.generatedResponse}}"), so update
the mapping to reference a real node or regenerate the flow from Lamatic Studio;
specifically, either replace LLMNode_331 with the actual node id that produces
generatedResponse (or change the property name to match the existing trigger
node's output) in the outputMapping entry, or open Lamatic Studio and re-export
the flow so the config contains the correct node IDs and mappings.
In `@kits/automation/Watchdog/flows/watchdog-flow/inputs.json`:
- Around line 4-13: The "competitors" JSON schema currently allows an unbounded
array; add a maxItems constraint to enforce the "up to 10" contract by setting
"maxItems": 10 on the "competitors" array definition (update the competitors
schema object where "type": "array" is declared) so flow invocations cannot pass
more than 10 entries; optionally add "minItems": 0 if an explicit lower bound is
desired.
In `@kits/automation/Watchdog/flows/watchdog-flow/README.md`:
- Around line 5-11: The README has markdown-structure issues: change the
top-level heading hierarchy so you add or convert an h2 before the existing h3
sections (e.g., introduce a "## Overview" or convert "### Nodes:" and "###
Setup:" to "## Nodes:" and "## Setup:"), ensure there is a blank line above and
below each heading (so add an empty line before each "## Nodes:" and "## Setup:"
and after their titles), and ensure the file ends with exactly one newline; also
keep the referenced environment variable WATCHDOG_FLOW_ID text unchanged while
applying these formatting fixes.
In `@kits/automation/Watchdog/package.json`:
- Line 2: The package.json "name" field currently has an invalid value with a
space ("Intelligent Watchdog"); update the "name" value to a valid npm package
identifier (e.g., lowercase, hyphenated like "intelligent-watchdog") while
leaving "private": true as-is; if you need a human-friendly title, add a
separate "displayName" or document it elsewhere rather than using the "name"
field.
- Around line 18-36: The dependencies in package.json use caret ranges (e.g.,
"@tailwindcss/postcss", "@tailwindcss/typography", "next", "react", "react-dom",
"typescript", etc.), which violates the pinned-version policy; update both
"dependencies" and "devDependencies" entries to use exact (pinned) versions
instead of caret ranges by removing the leading "^" and locking each package to
the current intended version string (for all listed packages such as
"@tailwindcss/postcss", "lamatic", "lucide-react", "react-markdown",
"@types/node", "@types/react", "autoprefixer", "postcss", "tailwindcss",
"typescript"), ensuring no range specifiers remain so installs are reproducible.
In `@kits/automation/Watchdog/README.md`:
- Around line 60-66: The README's environment variable entry uses the wrong key
AGENTIC_GENERATE_CONTENT; update the README environment variables section to
match the actual key validated in app/api/analyse/route.ts by replacing
AGENTIC_GENERATE_CONTENT with WATCHDOG_FLOW_ID and provide realistic example
values for WATCHDOG_FLOW_ID, LAMATIC_API_URL, LAMATIC_PROJECT_ID, and
LAMATIC_API_KEY so the documented names match the route's validation and usage
of WATCHDOG_FLOW_ID.
- Around line 77-94: README's "Repo Structure" block is out of sync with the
actual Watchdog kit; update the documented tree to reflect real assets by
replacing references to non-existent paths (/actions, /lib, /components/ui) and
showing actual files and folders such as /app (including page.tsx, layout.tsx,
api/analyse/route.ts), /flows/watchdog-flow, /public, global.css, config.json
and package.json; ensure the README's code block lists these exact symbols
(page.tsx, layout.tsx, api/analyse/route.ts, watchdog-flow, global.css,
config.json, package.json) and remove the outdated entries so the displayed
structure matches the repo.
- Around line 1-12: The README header is copy-pasted from the wrong kit; update
the top metadata so it correctly represents the Watchdog kit: change the title
string "Agent Kit Generation" to "Intelligent Watchdog", update the Live Demo
badge URL to the Watchdog demo, and fix the Deploy with Vercel link query param
repository-root to point to kits/automation/Watchdog (replace
kits/agentic/generation). Edit the visible header lines and the hrefs in the
README to reflect these new values so the title, demo badge, and Deploy button
all reference the Watchdog kit.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: 32cab4bc-7e2a-471b-8f9d-1e5049f98933
⛔ Files ignored due to path filters (1)
kits/automation/Watchdog/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (19)
CHALLENGE.mdCLAUDE.mdkits/automation/Watchdog/.gitignorekits/automation/Watchdog/README.mdkits/automation/Watchdog/app/api/analyse/route.tskits/automation/Watchdog/app/layout.tsxkits/automation/Watchdog/app/page.tsxkits/automation/Watchdog/components.jsonkits/automation/Watchdog/config.jsonkits/automation/Watchdog/flows/watchdog-flow/README.mdkits/automation/Watchdog/flows/watchdog-flow/config.jsonkits/automation/Watchdog/flows/watchdog-flow/inputs.jsonkits/automation/Watchdog/flows/watchdog-flow/meta.jsonkits/automation/Watchdog/global.csskits/automation/Watchdog/next.config.mjskits/automation/Watchdog/package.jsonkits/automation/Watchdog/postcss.config.mjskits/automation/Watchdog/tailwind.config.tskits/automation/Watchdog/tsconfig.json
💤 Files with no reviewable changes (2)
- CHALLENGE.md
- CLAUDE.md
| useEffect(() => { | ||
| const handleKey = (e: KeyboardEvent) => { if (e.key === "Escape") setModalOpen(false); }; | ||
| window.addEventListener("keydown", handleKey); | ||
| return () => window.removeEventListener("keydown", handleKey); |
There was a problem hiding this comment.
Mission note: reset modal state on every close path.
Escape and backdrop close only flip modalOpen, unlike Line 275 and Line 321. Reopening the modal can resurrect stale values and validation errors. Extract a shared close handler that also clears newName, newUrl, and error.
Also applies to: 263-267
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@kits/automation/Watchdog/app/page.tsx` around lines 19 - 22, Create a shared
close handler that not only sets modalOpen false but also resets newName,
newUrl, and error, then replace inline close logic in the Escape key listener
(handleKey in useEffect) and the other close paths (the handlers around lines
263–267, 275, and 321) to call this single function; ensure the new function
(e.g., closeModal or handleCloseModal) is referenced wherever modalOpen is
currently toggled to false so reopening the modal never resurrects stale values
or validation errors.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (4)
kits/automation/Watchdog/config.json (2)
23-25:⚠️ Potential issue | 🟠 MajorDeploy coordinates still point to wrong extraction zone, Agent.
The
deployUrlreferencesroot-directory=kits/automation/intelligent-watchdogbut the actual kit path iskits/automation/Watchdog. This mismatch will cause Vercel deployments to fail when attempting to locate the project root.🔧 Proposed URL fix
"demoUrl": "https://intelligent-watchdog.vercel.app/", "githubUrl": "https://github.com/HarshM1010/AgentKit/tree/feat/Add-Intelligent-Watchdog-automation-kit-for-competitor-intelligence/kits/automation/Watchdog", - "deployUrl": "https://vercel.com/new/clone?repository-url=https://github.com/HarshM1010/AgentKit_Watchdog&root-directory=kits/automation/intelligent-watchdog&env=WATCHDOG_FLOW_ID,LAMATIC_API_URL,LAMATIC_PROJECT_ID,LAMATIC_API_KEY&envDescription=Your%20Intelligent%20Watchdog%20flow%20ID%20and%20Lamatic%20API%20keys%20are%20required.&envLink=https://lamatic.ai/templates/agentkits/automation/intelligent-watchdog", + "deployUrl": "https://vercel.com/new/clone?repository-url=https://github.com/Lamatic/AgentKit&root-directory=kits/automation/Watchdog&env=WATCHDOG_FLOW_ID,LAMATIC_API_URL,LAMATIC_PROJECT_ID,LAMATIC_API_KEY&envDescription=Your%20Intelligent%20Watchdog%20flow%20ID%20and%20Lamatic%20API%20keys%20are%20required.&envLink=https://lamatic.ai/templates/agentkits/automation/intelligent-watchdog", "documentationUrl": "https://lamatic.ai/templates/agentkits/automation/intelligent-watchdog"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kits/automation/Watchdog/config.json` around lines 23 - 25, The deployUrl in config.json has an incorrect root-directory; update the deployUrl string so the query param root-directory is kits/automation/Watchdog (instead of kits/automation/intelligent-watchdog) so Vercel can locate the project root—modify the "deployUrl" value to reference the correct path while keeping the rest of the URL intact (key: deployUrl, param: root-directory, correct path: kits/automation/Watchdog).
9-15:⚠️ Potential issue | 🟠 MajorAgent, your step ID still doesn't match the flow folder — mission coordination compromised.
Per directive, step IDs must align with flow folder names. The step ID remains
pricing-watchdog-flowbut the actual flow folder iswatchdog-flow. This discrepancy could cause deployment failures when the system attempts to locate the flow.🔧 Proposed fix — align step ID with flow folder
"steps": [ { - "id": "pricing-watchdog-flow", + "id": "watchdog-flow", "type": "mandatory", "envKey": "WATCHDOG_FLOW_ID" } ],As per coding guidelines: "Kit step IDs in
config.jsonmust align with flow folder names and corresponding environment variable keys"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kits/automation/Watchdog/config.json` around lines 9 - 15, The step id "pricing-watchdog-flow" in the steps array does not match the actual flow folder name "watchdog-flow"; update the step object's "id" value to "watchdog-flow" so the Kit step ID aligns with the flow folder name (leave the envKey "WATCHDOG_FLOW_ID" as-is unless your environment variable also needs renaming). Ensure the change is applied to the steps entry that currently contains "id": "pricing-watchdog-flow".kits/automation/Watchdog/app/page.tsx (2)
27-31:⚠️ Potential issue | 🟡 MinorEscape route doesn't follow protocol, Agent.
The
closeModalhelper (lines 20-25) properly resets all modal state, but the Escape key handler (line 28) still callssetModalOpen(false)directly. This can leave stalenewName,newUrl, anderrorvalues when reopening the modal.🔧 Proposed fix
useEffect(() => { - const handleKey = (e: KeyboardEvent) => { if (e.key === "Escape") setModalOpen(false); }; + const handleKey = (e: KeyboardEvent) => { if (e.key === "Escape") closeModal(); }; window.addEventListener("keydown", handleKey); return () => window.removeEventListener("keydown", handleKey); - }, []); + }, [closeModal]);Note: You may need to wrap
closeModalinuseCallbackto avoid re-registering the listener on every render.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kits/automation/Watchdog/app/page.tsx` around lines 27 - 31, The Escape key handler directly calls setModalOpen(false) which skips the cleanup logic in closeModal and can leave stale newName/newUrl/error state; update the useEffect to call closeModal from the handleKey instead of setModalOpen, and if closeModal is defined inline, wrap closeModal with useCallback so the effect doesn't re-register the listener on every render; ensure handleKey references closeModal (not setModalOpen) to fully reset modal state when Escape is pressed.
77-95:⚠️ Potential issue | 🟠 MajorResponse parser still references flow internals — fragile mission intel, Agent.
The parser hard-codes
codeNode_584(line 78), which is a flow-specific node ID. If the Lamatic flow is modified or re-exported, this ID will change and break the UI without any compile-time warning.Consider either:
- Updating the flow's
outputMappingto expose a stable, documented structure- Having the API route normalize the response before returning it
🛡️ Suggested defensive parsing
const cleanResults: Result[] = rawResults.map((item: any) => { - const formatted = item.codeNode_584?.output?.formatted; + // Try multiple known structures to be resilient to flow changes + const formatted = + item.formatted || + item.codeNode_584?.output?.formatted || + item.output?.formatted; if (formatted && typeof formatted === "object") {Better yet, normalize the response shape in
route.tsso the client receives a stable contract.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kits/automation/Watchdog/app/page.tsx` around lines 77 - 95, The parser in the cleanResults mapping depends on a hard-coded flow node ID (codeNode_584) which is brittle; update the implementation so the UI does not reference flow internals: either adjust the server-side normalization in route.ts to return a stable shape (e.g., { org_name, response }) and have cleanResults/rawResults expect that, or change the client parsing in page.tsx (the cleanResults mapping that produces Result) to defensively locate output (search known keys, prefer an exported "output" property, or fallback to item.response/item) instead of using codeNode_584; update types (Result) and any callers accordingly so the client uses a documented, stable contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@kits/automation/Watchdog/app/api/analyse/route.ts`:
- Around line 70-71: The hardcoded 400000ms timeout in the AbortController setup
(const controller = new AbortController(); const timeoutId = setTimeout(() =>
controller.abort(), 400000);) is too long for serverless environments; change
this to a safer default (e.g., 60000–120000ms) or make the timeout configurable
via an environment variable, and ensure the timeoutId is cleared when the
operation completes; update any callers in route.ts that rely on controller to
use the new configurable value.
In `@kits/automation/Watchdog/app/page.tsx`:
- Around line 289-293: The backdrop click handler currently calls
setModalOpen(false) directly (in the modal rendering block checking modalOpen),
which bypasses the cleanup in closeModal; change the onClick handler on the
backdrop div to invoke closeModal() when e.target === e.currentTarget so the
modal closes and form/state cleanup runs (refer to closeModal, setModalOpen,
modalOpen, and the backdrop div's onClick).
In `@kits/automation/Watchdog/README.md`:
- Around line 11-14: The README exposes real Lamatic credentials
(WATCHDOG_FLOW_ID, LAMATIC_API_URL, LAMATIC_PROJECT_ID, LAMATIC_API_KEY);
immediately revoke/rotate the exposed LAMATIC_API_KEY in Lamatic, then edit the
README to replace those four symbols with clearly labeled placeholder values
(e.g., "<WATCHDOG_FLOW_ID_PLACEHOLDER>") and add a short note instructing users
to set real credentials via environment variables or a secrets manager;
additionally, add or update project safeguards (a .gitignore entry and/or a
pre-commit hook) to prevent committing real secrets in the future.
- Around line 1-43: Update the README.md markdown structure: change the
top-level heading from "## Intelligent Watchdog by Lamatic.ai" to "# Intelligent
Watchdog by Lamatic.ai", split the long compressed intro paragraphs (the live
demo and overview text around the top) into distinct sections (e.g., "##
Overview", "## Prerequisites", "## Setup", "## Environment Variables", "##
Running Locally", "## Deployment"), and fix the broken ordered list under
"Environment Variables" so list items use proper Markdown numbering or fenced
code blocks for the .env example (ensure a blank line before lists/code blocks);
reference the existing headings and section names in README.md to locate and
adjust the content.
---
Duplicate comments:
In `@kits/automation/Watchdog/app/page.tsx`:
- Around line 27-31: The Escape key handler directly calls setModalOpen(false)
which skips the cleanup logic in closeModal and can leave stale
newName/newUrl/error state; update the useEffect to call closeModal from the
handleKey instead of setModalOpen, and if closeModal is defined inline, wrap
closeModal with useCallback so the effect doesn't re-register the listener on
every render; ensure handleKey references closeModal (not setModalOpen) to fully
reset modal state when Escape is pressed.
- Around line 77-95: The parser in the cleanResults mapping depends on a
hard-coded flow node ID (codeNode_584) which is brittle; update the
implementation so the UI does not reference flow internals: either adjust the
server-side normalization in route.ts to return a stable shape (e.g., {
org_name, response }) and have cleanResults/rawResults expect that, or change
the client parsing in page.tsx (the cleanResults mapping that produces Result)
to defensively locate output (search known keys, prefer an exported "output"
property, or fallback to item.response/item) instead of using codeNode_584;
update types (Result) and any callers accordingly so the client uses a
documented, stable contract.
In `@kits/automation/Watchdog/config.json`:
- Around line 23-25: The deployUrl in config.json has an incorrect
root-directory; update the deployUrl string so the query param root-directory is
kits/automation/Watchdog (instead of kits/automation/intelligent-watchdog) so
Vercel can locate the project root—modify the "deployUrl" value to reference the
correct path while keeping the rest of the URL intact (key: deployUrl, param:
root-directory, correct path: kits/automation/Watchdog).
- Around line 9-15: The step id "pricing-watchdog-flow" in the steps array does
not match the actual flow folder name "watchdog-flow"; update the step object's
"id" value to "watchdog-flow" so the Kit step ID aligns with the flow folder
name (leave the envKey "WATCHDOG_FLOW_ID" as-is unless your environment variable
also needs renaming). Ensure the change is applied to the steps entry that
currently contains "id": "pricing-watchdog-flow".
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8b63f828-ea06-44c6-aa12-e3c34e5bb438
📒 Files selected for processing (5)
kits/automation/Watchdog/README.mdkits/automation/Watchdog/app/api/analyse/route.tskits/automation/Watchdog/app/page.tsxkits/automation/Watchdog/config.jsonkits/automation/Watchdog/package.json
| WATCHDOG_FLOW_ID = "811a44e5-a5ab-471e-9b1e-9e994b49554f" | ||
| LAMATIC_API_URL = "https://harshsorganization186-watchdog623.lamatic.dev/graphql" | ||
| LAMATIC_PROJECT_ID = "be77e472-8fda-41f1-a52d-575cf5b1bb3f" | ||
| LAMATIC_API_KEY = "36dfd9791177adaee07cb4976a9e40f4" |
There was a problem hiding this comment.
🚨 ABORT MISSION — Actual API credentials exposed in documentation, Agent!
This is a critical security breach. Lines 11-14 contain what appear to be real Lamatic API credentials:
WATCHDOG_FLOW_IDwith actual UUIDLAMATIC_API_URLwith real endpointLAMATIC_PROJECT_IDwith actual UUIDLAMATIC_API_KEYwith actual API key value
These credentials must be revoked immediately and replaced with placeholder examples. Once committed to version control, secrets are considered compromised even if later removed.
🔐 Proposed fix — use placeholder values
-WATCHDOG_FLOW_ID = "811a44e5-a5ab-471e-9b1e-9e994b49554f"
-LAMATIC_API_URL = "https://harshsorganization186-watchdog623.lamatic.dev/graphql"
-LAMATIC_PROJECT_ID = "be77e472-8fda-41f1-a52d-575cf5b1bb3f"
-LAMATIC_API_KEY = "36dfd9791177adaee07cb4976a9e40f4"
+WATCHDOG_FLOW_ID=your-watchdog-flow-id
+LAMATIC_API_URL=https://your-org.lamatic.dev/graphql
+LAMATIC_PROJECT_ID=your-project-id
+LAMATIC_API_KEY=your-api-keyImmediate action required:
- Rotate/revoke the exposed
LAMATIC_API_KEYin your Lamatic dashboard - Replace with placeholder values in this file
- Consider adding a
.gitignorerule or pre-commit hook to prevent future credential leaks
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| WATCHDOG_FLOW_ID = "811a44e5-a5ab-471e-9b1e-9e994b49554f" | |
| LAMATIC_API_URL = "https://harshsorganization186-watchdog623.lamatic.dev/graphql" | |
| LAMATIC_PROJECT_ID = "be77e472-8fda-41f1-a52d-575cf5b1bb3f" | |
| LAMATIC_API_KEY = "36dfd9791177adaee07cb4976a9e40f4" | |
| WATCHDOG_FLOW_ID=your-watchdog-flow-id | |
| LAMATIC_API_URL=https://your-org.lamatic.dev/graphql | |
| LAMATIC_PROJECT_ID=your-project-id | |
| LAMATIC_API_KEY=your-api-key |
🧰 Tools
🪛 Betterleaks (1.1.1)
[high] 14-14: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@kits/automation/Watchdog/README.md` around lines 11 - 14, The README exposes
real Lamatic credentials (WATCHDOG_FLOW_ID, LAMATIC_API_URL, LAMATIC_PROJECT_ID,
LAMATIC_API_KEY); immediately revoke/rotate the exposed LAMATIC_API_KEY in
Lamatic, then edit the README to replace those four symbols with clearly labeled
placeholder values (e.g., "<WATCHDOG_FLOW_ID_PLACEHOLDER>") and add a short note
instructing users to set real credentials via environment variables or a secrets
manager; additionally, add or update project safeguards (a .gitignore entry
and/or a pre-commit hook) to prevent committing real secrets in the future.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (4)
kits/automation/Watchdog/app/page.tsx (2)
27-31:⚠️ Potential issue | 🟡 MinorEscape route still bypasses decontamination protocol, Agent.
The Escape key handler (line 28) calls
setModalOpen(false)directly instead of using thecloseModal()function, which means stale form values (newName,newUrl,error) will persist if the user reopens the modal.🔧 Proposed extraction fix
useEffect(() => { - const handleKey = (e: KeyboardEvent) => { if (e.key === "Escape") setModalOpen(false); }; + const handleKey = (e: KeyboardEvent) => { if (e.key === "Escape") closeModal(); }; window.addEventListener("keydown", handleKey); return () => window.removeEventListener("keydown", handleKey); - }, []); + }, [closeModal]);Note: You'll need to wrap
closeModalinuseCallbackor move it inside the effect to satisfy the dependency array.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kits/automation/Watchdog/app/page.tsx` around lines 27 - 31, The Escape key handler currently calls setModalOpen(false) directly which bypasses the cleanup logic in closeModal and leaves stale state (newName, newUrl, error); update the useEffect handler (handleKey) to call closeModal instead of setModalOpen, and ensure closeModal is stable by wrapping it in useCallback or by defining closeModal inside the same useEffect so it can be referenced in the dependency array—this ensures modal state and form fields are reset when Escape is pressed.
77-95:⚠️ Potential issue | 🟠 MajorMission-critical: Response parser references a phantom node, Agent.
Line 78 extracts data from
item.codeNode_584?.output?.formatted, but according to the flow configuration atkits/automation/Watchdog/flows/watchdog-flow/config.json, theoutputMappingmapsresulttoLLMNode_331.output.generatedResponse— notcodeNode_584.This means the parser may fail to extract valid responses when the LLM node returns data under the correct key, causing fallback to
JSON.stringify(item)which produces unreadable reports.Verify the actual response structure from the Lamatic workflow:
#!/bin/bash # Check the config.json outputMapping to confirm the expected response structure cat kits/automation/Watchdog/flows/watchdog-flow/config.json | jq '.outputMapping // .output // .'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kits/automation/Watchdog/app/page.tsx` around lines 77 - 95, The parser currently reads item.codeNode_584?.output?.formatted (codeNode_584) but the flow maps outputs to LLMNode_331.output.generatedResponse; update the cleanResults mapping to first check item.LLMNode_331?.output?.generatedResponse (and its formatted/response fields if present), then fall back to item.codeNode_584 for backward compatibility, and finally to item.org_name/item.response before JSON-stringifying; ensure you reference the symbols codeNode_584 and LLMNode_331 in the conditional checks so the correct node payload is extracted and readable responses are returned.kits/automation/Watchdog/README.md (2)
6-6: 🧹 Nitpick | 🔵 TrivialIntel formatting needs cleanup for field operatives, Agent.
The documentation is compressed into wall-of-text paragraphs (line 6) making it difficult for operatives to quickly extract mission-critical setup steps. Static analysis also flagged spelling/grammar issues from concatenated text.
Consider breaking into proper markdown sections:
## Overview## Prerequisites## Lamatic Setup## Environment Variables## Running Locally🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kits/automation/Watchdog/README.md` at line 6, The README text is a single compressed paragraph with concatenated sentences and grammar issues; split and reformat it into clear Markdown sections (for example: "## Overview", "## Prerequisites", "## Lamatic Setup", "## Environment Variables", "## Running Locally", and "## Deploy to Vercel") and move the existing content into those sections, preserving the Lamatic Setup steps (Webhook Trigger, Firecrawl Scraper, LLM Node), the .env.local instructions (add LAMATIC_API_KEY, WATCHDOG_FLOW_ID, LAMATIC_PROJECT_ID), and the npm/Vercel commands; also fix punctuation and spacing errors, use bullet or numbered lists for step sequences, and ensure each credential entry in the "Environment Variables" section includes the purpose and where to get it.
11-14:⚠️ Potential issue | 🔴 Critical🚨 ABORT MISSION — Your cover is blown, Agent! Real credentials are still exposed!
Despite prior intelligence indicating this was addressed, lines 11-14 still contain what appear to be actual Lamatic API credentials:
WATCHDOG_FLOW_IDwith real UUIDLAMATIC_API_URLwith actual endpointLAMATIC_PROJECT_IDwith real UUIDLAMATIC_API_KEYwith actual key valueStatic analysis confirms: "Detected a Generic API Key, potentially exposing access to various services and sensitive operations."
Immediate action required:
- Rotate/revoke the exposed
LAMATIC_API_KEYin your Lamatic dashboard — consider it compromised- Replace all four values with clearly labeled placeholders
🔐 Proposed fix — sanitize the credentials
-WATCHDOG_FLOW_ID = "811a44e5-a5ab-471e-9b1e-9e994b49554f" -LAMATIC_API_URL = "https://harshsorganization186-watchdog623.lamatic.dev/graphql" -LAMATIC_PROJECT_ID = "be77e472-8fda-41f1-a52d-575cf5b1bb3f" -LAMATIC_API_KEY = "36dfd9791177adaee07cb4976a9e40f4" +WATCHDOG_FLOW_ID=your-watchdog-flow-id +LAMATIC_API_URL=https://your-org.lamatic.dev/graphql +LAMATIC_PROJECT_ID=your-project-id +LAMATIC_API_KEY=your-api-keyBased on learnings: "Never commit real API keys, secrets, or credentials; use
.env.examplewith placeholders only"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kits/automation/Watchdog/README.md` around lines 11 - 14, Replace the exposed secrets by revoking/rotating the compromised LAMATIC_API_KEY immediately, then sanitize the README entries by replacing WATCHDOG_FLOW_ID, LAMATIC_API_URL, LAMATIC_PROJECT_ID, and LAMATIC_API_KEY with descriptive placeholders (e.g., WATCHDOG_FLOW_ID="<YOUR_FLOW_ID>", LAMATIC_API_URL="<YOUR_API_URL>", etc.) and add a note directing developers to use environment variables or a .env.example for real credentials; ensure no real keys remain in the file.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@kits/automation/Watchdog/app/api/analyse/route.ts`:
- Around line 50-68: The API validation allows any number of competitors,
bypassing the inputs.json maxItems:10 limit; update the validation around the
competitors variable and isValid check to also enforce competitors.length <= 10
(or a constant MAX_COMPETITORS) and return the 400 NextResponse.json error when
exceeded; reference the competitors array and isValid logic in route.ts to add
the length check and a clear error message about the maximum allowed.
In `@kits/automation/Watchdog/app/page.tsx`:
- Around line 348-354: The Cancel button is duplicating cleanup by calling
setModalOpen(false); setNewName(""); setNewUrl(""); setError("") inline instead
of using the shared closeModal() handler; replace the inline reset with a call
to closeModal() so the modal teardown logic is centralized (locate the Cancel
button's onClick and swap the current inline calls to invoke closeModal(),
ensuring closeModal handles all state resets performed previously).
In `@kits/automation/Watchdog/flows/watchdog-flow/inputs.json`:
- Around line 11-12: The JSON schema mistakenly applies "format": "uri" to the
org_name property; remove the format key from org_name (leave it as type:
"string" for plain company names) and add "format": "uri" to the url property so
url is validated as a URI; specifically update the org_name and url entries in
the inputs.json schema (properties "org_name" and "url") to swap the format
constraint.
---
Duplicate comments:
In `@kits/automation/Watchdog/app/page.tsx`:
- Around line 27-31: The Escape key handler currently calls setModalOpen(false)
directly which bypasses the cleanup logic in closeModal and leaves stale state
(newName, newUrl, error); update the useEffect handler (handleKey) to call
closeModal instead of setModalOpen, and ensure closeModal is stable by wrapping
it in useCallback or by defining closeModal inside the same useEffect so it can
be referenced in the dependency array—this ensures modal state and form fields
are reset when Escape is pressed.
- Around line 77-95: The parser currently reads
item.codeNode_584?.output?.formatted (codeNode_584) but the flow maps outputs to
LLMNode_331.output.generatedResponse; update the cleanResults mapping to first
check item.LLMNode_331?.output?.generatedResponse (and its formatted/response
fields if present), then fall back to item.codeNode_584 for backward
compatibility, and finally to item.org_name/item.response before
JSON-stringifying; ensure you reference the symbols codeNode_584 and LLMNode_331
in the conditional checks so the correct node payload is extracted and readable
responses are returned.
In `@kits/automation/Watchdog/README.md`:
- Line 6: The README text is a single compressed paragraph with concatenated
sentences and grammar issues; split and reformat it into clear Markdown sections
(for example: "## Overview", "## Prerequisites", "## Lamatic Setup", "##
Environment Variables", "## Running Locally", and "## Deploy to Vercel") and
move the existing content into those sections, preserving the Lamatic Setup
steps (Webhook Trigger, Firecrawl Scraper, LLM Node), the .env.local
instructions (add LAMATIC_API_KEY, WATCHDOG_FLOW_ID, LAMATIC_PROJECT_ID), and
the npm/Vercel commands; also fix punctuation and spacing errors, use bullet or
numbered lists for step sequences, and ensure each credential entry in the
"Environment Variables" section includes the purpose and where to get it.
- Around line 11-14: Replace the exposed secrets by revoking/rotating the
compromised LAMATIC_API_KEY immediately, then sanitize the README entries by
replacing WATCHDOG_FLOW_ID, LAMATIC_API_URL, LAMATIC_PROJECT_ID, and
LAMATIC_API_KEY with descriptive placeholders (e.g.,
WATCHDOG_FLOW_ID="<YOUR_FLOW_ID>", LAMATIC_API_URL="<YOUR_API_URL>", etc.) and
add a note directing developers to use environment variables or a .env.example
for real credentials; ensure no real keys remain in the file.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: ea10a562-e136-466b-bffc-e0bd6a7458a8
📒 Files selected for processing (5)
kits/automation/Watchdog/README.mdkits/automation/Watchdog/app/api/analyse/route.tskits/automation/Watchdog/app/page.tsxkits/automation/Watchdog/flows/watchdog-flow/README.mdkits/automation/Watchdog/flows/watchdog-flow/inputs.json
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
kits/automation/Watchdog/app/page.tsx (1)
27-31:⚠️ Potential issue | 🟡 MinorEscape route compromised, Agent — extraction leaves traces behind.
The Escape key handler (line 28) calls
setModalOpen(false)directly instead of the sharedcloseModal()function. This bypasses the cleanup logic that resetsnewName,newUrl, anderror, causing stale form state to resurface when the modal reopens.🔧 Proposed fix — use the established extraction protocol
useEffect(() => { - const handleKey = (e: KeyboardEvent) => { if (e.key === "Escape") setModalOpen(false); }; + const handleKey = (e: KeyboardEvent) => { if (e.key === "Escape") closeModal(); }; window.addEventListener("keydown", handleKey); return () => window.removeEventListener("keydown", handleKey); - }, []); + }, [closeModal]);Note: Adding
closeModalto the dependency array or wrapping it inuseCallbackensures the handler always references the current function.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kits/automation/Watchdog/app/page.tsx` around lines 27 - 31, The keydown handler currently calls setModalOpen(false) which bypasses the cleanup in closeModal and leaves newName, newUrl, and error populated; update the handleKey callback to call closeModal() instead of setModalOpen(false) and ensure closeModal is stable in the effect by either wrapping closeModal with useCallback or adding closeModal to the useEffect dependency array so the handler always references the current cleanup logic that resets newName/newUrl/error.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@kits/automation/Watchdog/app/api/analyse/route.ts`:
- Around line 53-68: Validation currently allows an empty competitors array
because it only checks competitors.length <= 10 and relies on every(...)
(vacuously true); update the validation in route.ts to first ensure competitors
is a non-empty array and has 1–10 items (e.g., Array.isArray(competitors) &&
competitors.length >= 1 && competitors.length <= 10) and then run the existing
per-item checks (the same competitors.every(...) logic); return the same 400
NextResponse.json error when that combined check fails.
In `@kits/automation/Watchdog/app/page.tsx`:
- Around line 77-95: The code currently depends on a hard-coded flow node key
codeNode_584 when transforming rawResults into cleanResults, creating fragile
coupling; change the API/producer to normalize outputs into a stable shape
(e.g., { org_name, response }) and update the consumer logic in page.tsx (the
cleanResults mapping over rawResults and the Result type) to read only that
stable shape (falling back to item.org_name/item.response or
JSON.stringify(item) only if those normalized fields are missing), and remove
reliance on codeNode_584 so the UI consumes a consistent contract from the API
rather than flow-internal keys.
---
Duplicate comments:
In `@kits/automation/Watchdog/app/page.tsx`:
- Around line 27-31: The keydown handler currently calls setModalOpen(false)
which bypasses the cleanup in closeModal and leaves newName, newUrl, and error
populated; update the handleKey callback to call closeModal() instead of
setModalOpen(false) and ensure closeModal is stable in the effect by either
wrapping closeModal with useCallback or adding closeModal to the useEffect
dependency array so the handler always references the current cleanup logic that
resets newName/newUrl/error.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: a0a5ffbd-5763-4643-a6ea-2a16e9f9b2e4
📒 Files selected for processing (3)
kits/automation/Watchdog/app/api/analyse/route.tskits/automation/Watchdog/app/page.tsxkits/automation/Watchdog/flows/watchdog-flow/inputs.json
| const cleanResults: Result[] = rawResults.map((item: any) => { | ||
| const formatted = item.codeNode_584?.output?.formatted; | ||
|
|
||
| if (formatted && typeof formatted === "object") { | ||
| return { | ||
| org_name: formatted.org_name || item.org_name || "Unknown", | ||
| response: formatted.response || JSON.stringify(formatted), | ||
| }; | ||
| } | ||
|
|
||
| if (item.org_name && item.response) return item; | ||
|
|
||
| return { | ||
| org_name: item.org_name || "Unknown", | ||
| response: typeof formatted === "string" | ||
| ? formatted | ||
| : JSON.stringify(item), | ||
| }; | ||
| }); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Intel parsing has fallback protocols — but the hard-coded asset ID remains a liability, Agent.
Line 78 references codeNode_584, a flow-internal node ID that could change if the Lamatic flow is re-exported. The defensive fallback logic (lines 80-94) mitigates immediate breakage by attempting multiple extraction paths, but this creates fragile coupling to flow internals.
Consider defining the expected response contract in the API route and returning a stable, normalized shape to the client — insulating the UI from workflow implementation details.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@kits/automation/Watchdog/app/page.tsx` around lines 77 - 95, The code
currently depends on a hard-coded flow node key codeNode_584 when transforming
rawResults into cleanResults, creating fragile coupling; change the API/producer
to normalize outputs into a stable shape (e.g., { org_name, response }) and
update the consumer logic in page.tsx (the cleanResults mapping over rawResults
and the Result type) to read only that stable shape (falling back to
item.org_name/item.response or JSON.stringify(item) only if those normalized
fields are missing), and remove reliance on codeNode_584 so the UI consumes a
consistent contract from the API rather than flow-internal keys.
What This Kit Does
Intelligent Watchdog is an AI-powered competitor intelligence agent. It automates the tedious task of monitoring rival websites by scraping landing pages, detecting changes in pricing, features or updates, and generating tactical "battle cards" for sales teams to win more deals.
Providers & Prerequisites
How to Run Locally
Bash
Live Preview
Vercel URL: https://intelligent-watchdog.vercel.app/
Lamatic Flow
Intelligent Watchdog: AI-Powered Competitor Monitor
Overview
Adds a production-ready automation kit (kits/automation/Watchdog/) that transforms raw competitor URLs into actionable sales intelligence. Built with Next.js 15 and integrated with Lamatic.ai GraphQL endpoints.
Core Features
Technical Implementation
Configuration
File Structure
Files added (Watchdog kit)
Flow nodes and high-level behavior (from flows/watchdog-flow/config.json + README)