feat: Add Intelligent Watchdog automation kit for competitor intelligence#109
Conversation
…/AgentKit_Watchdog into feat/agentic_watchdog
…/AgentKit_Watchdog into feat/agentic_watchdog
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Your Mission, Should You Choose to AcceptWalkthroughThis PR introduces the complete "Intelligent Watchdog" competitor monitoring automation kit featuring a Next.js dashboard and workflow integration, removes a submodule reference, streamlines CI/CD validation logic, and updates contribution guidelines to focus on Kit development. Changes
Suggested reviewers
This message will self-destruct in 5 seconds. ✓ Mission accepted. Your Watchdog is now in the field—monitor those competitors carefully. The automation kit is ready for deployment. 🚥 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: 3
♻️ Duplicate comments (2)
kits/automation/Watchdog/flows/watchdog-flow/config.json (1)
2-17:⚠️ Potential issue | 🔴 CriticalYour mission: verify this flow config was properly exported from Lamatic Studio, Agent.
The
outputMappingreferences nodesforLoopNode_304andLLMNode_331, but thenodesarray only contains thetriggerwebhook node. This config appears incomplete — either it was hand-edited or partially exported.Based on learnings: "Flows in
flows/directories must be valid Lamatic Studio exports; do not hand-edit flowconfig.jsonfiles unless you know the node/edge schema."Re-export the complete flow from Lamatic Studio to ensure all referenced nodes are present in the configuration.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kits/automation/Watchdog/flows/watchdog-flow/config.json` around lines 2 - 17, The config's outputMapping references nodes forLoopNode_304 and LLMNode_331 but the nodes array only contains the trigger webhook node, indicating an incomplete/partial export; open the flow in Lamatic Studio and re-export the full flow so the nodes array includes definitions for forLoopNode_304 and LLMNode_331 (and any edges/metadata) rather than hand-editing config.json, or restore the missing node entries and their connections exactly as exported so outputMapping resolves correctly.kits/automation/Watchdog/app/page.tsx (1)
27-31:⚠️ Potential issue | 🟡 MinorYour mission: ensure the Escape key uses the extraction protocol, Agent.
The
Escapekey handler at Line 28 callssetModalOpen(false)directly instead ofcloseModal(). This bypasses the cleanup logic, leavingnewName,newUrl, anderrorin stale state when the modal reopens.🔧 Proposed tactical adjustment
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
closeModalinuseCallbackto use it as a dependency:const closeModal = useCallback(() => { setError(""); setModalOpen(false); setNewName(""); setNewUrl(""); }, []);🤖 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 inside the useEffect currently calls setModalOpen(false) directly and bypasses modal cleanup; change the handler (handleKey) to call the existing closeModal() so newName/newUrl/error are reset, and ensure closeModal is wrapped in useCallback (e.g., closeModal uses setError(""), setModalOpen(false), setNewName(""), setNewUrl("") and is memoized) so it can be safely referenced from the useEffect dependency list.
🤖 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 29-32: The comment notes a missing enforcement for rate limiting:
add a real limiter at the start of the request handler (the function that reads
req.headers.get("x-forwarded-for") and uses the WATCHDOG_APP_SECRET) so callers
can't bypass auth or exhaust external quotas. In production wire in
`@upstash/ratelimit` backed by Upstash Redis and use the request IP (const ip =
req.headers.get("x-forwarded-for") || "anonymous") as the key; for local/dev use
a simple in-memory counter with a 1-minute window; ensure the limiter is checked
before any downstream calls to Lamatic/Firecrawl/Gemini and return a 429 when
exceeded; additionally, make WATCHDOG_APP_SECRET mandatory in production (fail
fast if unset) so optional auth is not allowed.
In `@kits/automation/Watchdog/app/page.tsx`:
- Around line 57-67: The normalizeWatchdogData function can throw when
JSON.parse(raw) receives malformed input; wrap the parse in a try/catch inside
normalizeWatchdogData, attempt JSON.parse only if typeof raw === "string", and
on any parse error set parsed to null (or an empty object) so the subsequent
checks (parsed?.results, parsed?.Result, Array.isArray(parsed)) safely fall
through to the fallback; optionally log or surface the parse error before
returning { results: [] } to aid debugging.
- Around line 77-84: The client component in page.tsx is sending the server
secret via Authorization using process.env.WATCHDOG_APP_SECRET (resulting in
"Bearer undefined"); fix by moving the call that currently does
fetch("/api/analyse", ...) out of the client component into a server-side
context (either implement a server action or add a new API endpoint like
/api/analyse-client that calls the existing
kits/automation/Watchdog/app/api/analyse/route.ts internals), so the secret can
be read on the server and forwarded in the Authorization header when calling the
analyse logic; alternatively implement a token endpoint (/api/token) that mints
short-lived tokens the client can request and then use when calling
/api/analyse—do not expose WATCHDOG_APP_SECRET to the client or convert it to
NEXT_PUBLIC_.
---
Duplicate comments:
In `@kits/automation/Watchdog/app/page.tsx`:
- Around line 27-31: The Escape key handler inside the useEffect currently calls
setModalOpen(false) directly and bypasses modal cleanup; change the handler
(handleKey) to call the existing closeModal() so newName/newUrl/error are reset,
and ensure closeModal is wrapped in useCallback (e.g., closeModal uses
setError(""), setModalOpen(false), setNewName(""), setNewUrl("") and is
memoized) so it can be safely referenced from the useEffect dependency list.
In `@kits/automation/Watchdog/flows/watchdog-flow/config.json`:
- Around line 2-17: The config's outputMapping references nodes forLoopNode_304
and LLMNode_331 but the nodes array only contains the trigger webhook node,
indicating an incomplete/partial export; open the flow in Lamatic Studio and
re-export the full flow so the nodes array includes definitions for
forLoopNode_304 and LLMNode_331 (and any edges/metadata) rather than
hand-editing config.json, or restore the missing node entries and their
connections exactly as exported so outputMapping resolves correctly.
🪄 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: 0e613ba5-43d3-4564-a691-10f52eec5892
📒 Files selected for processing (3)
kits/automation/Watchdog/app/api/analyse/route.tskits/automation/Watchdog/app/page.tsxkits/automation/Watchdog/flows/watchdog-flow/config.json
|
Hi @HarshM1010! 👋 Before this PR can be reviewed by maintainers, please resolve all comments and requested changes from the CodeRabbit automated review. Steps to follow:
This helps keep the review process efficient for everyone. Thank you! 🙏 |
…tion-kit-for-competitor-intelligence
…tion-kit-for-competitor-intelligence
…itor-intelligence' of https://github.com/HarshM1010/AgentKit_Watchdog into feat/Add-Intelligent-Watchdog-automation-kit-for-competitor-intelligence
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 6
♻️ Duplicate comments (1)
kits/automation/Watchdog/app/page.tsx (1)
58-68:⚠️ Potential issue | 🟡 MinorIntel parsing could detonate on malformed payloads, Agent.
If
rawis a malformed JSON string,JSON.parse(raw)at line 60 will throw an unhandled exception, crashing the analysis flow and leaving the UI in an error state without a clear message.🛡️ Proposed defensive protocol
const normalizeWatchdogData = (raw: any): { results: any[] } => { // Handle stringified JSON from GraphQL - const parsed = typeof raw === "string" ? JSON.parse(raw) : raw; + let parsed: any; + try { + parsed = typeof raw === "string" ? JSON.parse(raw) : raw; + } catch { + console.warn("Failed to parse watchdog response:", raw); + return { results: [] }; + } // Detect and convert to Canonical Form: { results: [...] }🤖 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 58 - 68, The normalizeWatchdogData function currently calls JSON.parse(raw) directly which will throw on malformed JSON; wrap the string parsing in a try/catch (or implement a small safeParse helper) inside normalizeWatchdogData so that if JSON.parse fails you catch the error, optionally log or surface a concise error message, and return the safe fallback { results: [] } instead of letting the exception propagate; keep the existing detection for parsed?.results, parsed?.Result, and Array.isArray(parsed) after successful parse.
🤖 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/actions.ts`:
- Line 16: The analyzeCompetitorsAction function accepts competitors: any[] with
no validation; add input validation at the start of analyzeCompetitorsAction to
enforce 1–10 items and that each item has a non-empty string org_name and a
valid URL string for url (matching the flow inputs.json schema),
returning/rejecting early with an error if validation fails; use the function
name analyzeCompetitorsAction to locate the entry point and perform checks
(length, types, string emptiness, and URL format via a simple URL parse or
regex) before sending the payload to the Lamatic API so malformed payloads are
blocked.
- Around line 48-62: Add an AbortController-based timeout around the fetch to
LAMATIC_API_URL (the block that posts query EXECUTE_WORKFLOW with variables
including WATCHDOG_FLOW_ID and competitors): create an AbortController, set a
timer (e.g. setTimeout) to call controller.abort() after a chosen timeout, pass
controller.signal into fetch options, and clear the timer when the response
arrives; also update the surrounding catch to detect error.name === 'AbortError'
and throw a clear timeout Error (e.g. "Request timeout - Lamatic API did not
respond in time") while rethrowing other errors with their messages.
- Around line 47-62: Replace the raw GraphQL fetch in app/actions.ts that posts
to LAMATIC_API_URL (using LAMATIC_API_KEY, LAMATIC_PROJECT_ID, EXECUTE_WORKFLOW,
WATCHDOG_FLOW_ID and competitors) with the Lamatic SDK client: create
lib/lamatic-client.ts exporting lamaticClient (per the provided pattern that
validates env vars and instantiates Lamatic with endpoint/projectId/apiKey) and
then call the flow execution via lamaticClient (instead of fetch) in the action
that currently references EXECUTE_WORKFLOW and WATCHDOG_FLOW_ID; ensure you
propagate the same payload ({ competitors }), handle SDK errors, and remove the
direct fetch usage so the file matches embed/search and embed/chat patterns.
In `@kits/automation/Watchdog/app/api/analyse/route.ts`:
- Around line 1-206: The file contains a fully commented-out POST handler and
related symbols (EXECUTE_WORKFLOW, localRateLimitMap, POST) and should not
remain as dead code; either delete this route.ts file entirely, or convert it
into a short reference file by removing the commented implementation and
replacing it with a clear top-of-file comment that states the file is
decommissioned, points to kits/automation/Watchdog/app/actions.ts for the active
logic, and documents when/why it can be restored (keep git history for full code
recovery); ensure no exports or build artifacts remain that could confuse the
runtime.
In `@kits/automation/Watchdog/package.json`:
- Around line 21-22: The package.json currently uses caret ranges for
`@upstash/ratelimit` and `@upstash/redis` which violates the pinned-version policy;
update the dependencies entry for "@upstash/ratelimit" and "@upstash/redis" to
use exact version strings (no ^ or ~) matching the tested versions (e.g.,
replace "^2.0.8" and "^1.37.0" with the equivalent exact versions "2.0.8" and
"1.37.0"); ensure you save package.json and run a quick install to verify there
are no resolution issues.
- Line 26: The package.json in this kit pins "next": "16.2.1" while the sibling
kit kits/automation/blog-automation pins "next": "15.5.9", so confirm whether
the major-version divergence is intentional; if not, align versions by updating
one of the package.json files so both kits use the same Next.js major (either
both 16.x or both 15.x) and run npm/yarn install + test to ensure compatibility;
if the divergence is intentional, add a short comment in each package.json (or
in the repo README) documenting why the kits target different Next versions to
avoid future confusion.
---
Duplicate comments:
In `@kits/automation/Watchdog/app/page.tsx`:
- Around line 58-68: The normalizeWatchdogData function currently calls
JSON.parse(raw) directly which will throw on malformed JSON; wrap the string
parsing in a try/catch (or implement a small safeParse helper) inside
normalizeWatchdogData so that if JSON.parse fails you catch the error,
optionally log or surface a concise error message, and return the safe fallback
{ results: [] } instead of letting the exception propagate; keep the existing
detection for parsed?.results, parsed?.Result, and Array.isArray(parsed) after
successful parse.
🪄 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: b0ca74fb-6486-457e-badb-e1225575593c
⛔ Files ignored due to path filters (1)
kits/automation/Watchdog/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (5)
kits/agentic/stock-analysiskits/automation/Watchdog/app/actions.tskits/automation/Watchdog/app/api/analyse/route.tskits/automation/Watchdog/app/page.tsxkits/automation/Watchdog/package.json
💤 Files with no reviewable changes (1)
- kits/agentic/stock-analysis
| // 3. 🚀 Secure Fetch: Performed entirely on the server | ||
| const res = await fetch(LAMATIC_API_URL, { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| 'Authorization': `Bearer ${LAMATIC_API_KEY}`, | ||
| 'x-project-id': LAMATIC_PROJECT_ID, | ||
| }, | ||
| body: JSON.stringify({ | ||
| query: EXECUTE_WORKFLOW, | ||
| variables: { | ||
| workflowId: WATCHDOG_FLOW_ID, | ||
| payload: { competitors }, | ||
| }, | ||
| }), | ||
| }); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check how other kits in this repo call Lamatic flows
echo "=== Searching for Lamatic SDK usage ==="
rg -n "from ['\"]lamatic['\"]" --type=ts -C2
echo ""
echo "=== Searching for executeWorkflow GraphQL pattern ==="
rg -n "executeWorkflow" --type=ts -C2Repository: Lamatic/AgentKit
Length of output: 13413
🏁 Script executed:
# Check if Watchdog has a lamatic-client.ts file
echo "=== Checking Watchdog kit structure ==="
find kits/automation/Watchdog -type f -name "*.ts" -o -name "*.tsx" -o -name "*.json" | head -20
echo ""
echo "=== Checking if app/actions.ts is a server action file ==="
head -20 kits/automation/Watchdog/app/actions.ts
echo ""
echo "=== Checking Watchdog orchestrate or related config files ==="
find kits/automation/Watchdog -name "config.json" -o -name "orchestrate.*" | xargs ls -la 2>/dev/nullRepository: Lamatic/AgentKit
Length of output: 1631
🏁 Script executed:
# Check for CLAUDE.md or README in Watchdog kit
echo "=== Checking for design docs in Watchdog ==="
find kits/automation/Watchdog -name "CLAUDE.md" -o -name "README.md" | xargs cat 2>/dev/null
echo ""
echo "=== Checking full app/actions.ts file ==="
wc -l kits/automation/Watchdog/app/actions.ts
cat -n kits/automation/Watchdog/app/actions.ts
echo ""
echo "=== Comparing with standard lamatic-client.ts pattern (from hiring kit) ==="
head -60 kits/automation/hiring/lib/lamatic-client.tsRepository: Lamatic/AgentKit
Length of output: 7545
Mission briefing: Migrate to SDK client for server action.
Your server action file (app/actions.ts) must use the Lamatic SDK via lamatic-client.ts pattern, not raw GraphQL fetch. This is the established requirement across the codebase—other server action files in embed/search and embed/chat implement this correctly.
Create lib/lamatic-client.ts following the standard pattern:
import { Lamatic } from "lamatic";
if (!process.env.LAMATIC_API_URL || !process.env.LAMATIC_PROJECT_ID || !process.env.LAMATIC_API_KEY) {
throw new Error("Missing Lamatic credentials in environment variables");
}
export const lamaticClient = new Lamatic({
endpoint: process.env.LAMATIC_API_URL,
projectId: process.env.LAMATIC_PROJECT_ID,
apiKey: process.env.LAMATIC_API_KEY,
});Then call the flow via SDK in app/actions.ts rather than direct fetch. The SDK provides type safety, error handling, and consistency with the rest of the kit ecosystem.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@kits/automation/Watchdog/app/actions.ts` around lines 47 - 62, Replace the
raw GraphQL fetch in app/actions.ts that posts to LAMATIC_API_URL (using
LAMATIC_API_KEY, LAMATIC_PROJECT_ID, EXECUTE_WORKFLOW, WATCHDOG_FLOW_ID and
competitors) with the Lamatic SDK client: create lib/lamatic-client.ts exporting
lamaticClient (per the provided pattern that validates env vars and instantiates
Lamatic with endpoint/projectId/apiKey) and then call the flow execution via
lamaticClient (instead of fetch) in the action that currently references
EXECUTE_WORKFLOW and WATCHDOG_FLOW_ID; ensure you propagate the same payload ({
competitors }), handle SDK errors, and remove the direct fetch usage so the file
matches embed/search and embed/chat patterns.
b657c8f to
b745f04
Compare
…tion-kit-for-competitor-intelligence
…tion-kit-for-competitor-intelligence
…itor-intelligence' of https://github.com/HarshM1010/AgentKit_Watchdog into feat/Add-Intelligent-Watchdog-automation-kit-for-competitor-intelligence
d-pamneja
left a comment
There was a problem hiding this comment.
Kindly do not edit the files not pertaining to your kit, only makes changes to your kit. Otherwise LGTM, we could merge post this fix. Thanks!
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (3)
kits/automation/Watchdog/app/page.tsx (1)
59-69:⚠️ Potential issue | 🟠 MajorIntel parsing could detonate on malformed payloads, Agent.
The
JSON.parse(raw)at line 61 operates without extraction cover. If the GraphQL response contains malformed JSON, this will throw an unhandled exception and crash the analysis flow. Previous surveillance flagged this vulnerability.🛡️ Proposed defensive protocol
const normalizeWatchdogData = (raw: any): { results: any[] } => { // Handle stringified JSON from GraphQL - const parsed = typeof raw === "string" ? JSON.parse(raw) : raw; + let parsed: any; + try { + parsed = typeof raw === "string" ? JSON.parse(raw) : raw; + } catch { + console.warn("Failed to parse watchdog response:", raw); + return { results: [] }; + } // Detect and convert to Canonical Form: { results: [...] }🤖 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 59 - 69, The normalizeWatchdogData function currently calls JSON.parse(raw) directly which can throw on malformed input; wrap the parse in a try/catch and fall back to treating raw as-is (or returning { results: [] }) on parse error or when raw is null/undefined, so the function never throws; update the parsing logic inside normalizeWatchdogData to safely attempt JSON.parse in a try block, catch and log or ignore the error, then continue the existing detection/conversion steps (checking parsed?.results, parsed?.Result, Array.isArray(parsed)) using the safe fallback when parsing fails.kits/automation/Watchdog/app/actions.ts (1)
95-97:⚠️ Potential issue | 🟡 MinorAbort signal deployed — but extraction protocol incomplete, Agent.
The timeout mechanism at lines 62-63 is in place, but the catch block doesn't distinguish
AbortErrorfrom other failures. When the 80-second timeout fires, operatives receive a generic error message instead of clear timeout intel.⏱️ Proposed extraction protocol
} catch (error: any) { + if (error.name === 'AbortError') { + throw new Error("Request timeout - Lamatic API did not respond within 80 seconds."); + } throw new Error(error.message || "An unexpected error occurred"); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kits/automation/Watchdog/app/actions.ts` around lines 95 - 97, The catch block in actions.ts currently throws a generic Error for all failures; update it to detect AbortError and rethrow a clear timeout error message: inside the existing catch (error: any) { ... } check if error.name === 'AbortError' (or error instanceof DOMException if appropriate) and throw a new Error like "Operation timed out after 80 seconds"; otherwise preserve the current behavior (throw new Error(error.message || "An unexpected error occurred")). This change should be applied where the timeout/AbortController logic lives so timeout cases are distinguishable from other failures.kits/automation/Watchdog/package.json (1)
30-30:⚠️ Potential issue | 🟡 MinorOne asset remains unpinned — mission not yet complete, Agent.
The
remark-gfmdependency still uses a caret range (^4.0.1), which violates operational protocols. All other dependencies were correctly pinned in previous operations, but this one slipped through surveillance.As per coding guidelines: "Each kit must have its own
package.jsonwith pinned dependency versions; do not rely on workspace-level hoisting or a root package.json"📌 Proposed fix — pin the version
- "remark-gfm": "^4.0.1" + "remark-gfm": "4.0.1"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kits/automation/Watchdog/package.json` at line 30, The remark-gfm dependency in this kit's package.json is using a caret range ("remark-gfm": "^4.0.1"); update the package.json entry for remark-gfm to a pinned exact version (e.g., "remark-gfm": "4.0.1") so it no longer uses ^ or ~, and verify the file contains only explicitly pinned versions for all dependencies in this kit (not relying on root/workspace hoisting).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.gitignore:
- Line 1: Restore the sensitive entries back into .gitignore by adding back the
lines excluding `.env` and `.env.local` (and any related variants like `.env.*`
if desired) so that local credential files are not tracked; locate the
repository .gitignore and re-add `.env` and `.env.local` entries (or a single
pattern such as `.env*`) ensuring they are not commented out, then verify by
running git status to confirm no .env files are staged and update
CONTRIBUTING.md guidance if needed.
In `@CONTRIBUTING.md`:
- Around line 193-214: The fenced code block showing the folder tree for
kits/<category>/<kit-name>/ in CONTRIBUTING.md is missing a language identifier;
update the opening ``` fence to include a hint like ```text or ```plaintext so
Markdown renderers consistently preserve formatting (modify the code block that
begins with the kits/<category>/<kit-name>/ tree).
- Line 507: The file CONTRIBUTING.md is missing a terminal newline character;
update the file so it ends with exactly one newline (no extra blank lines) to
satisfy POSIX and MD047—open CONTRIBUTING.md, add a single '\n' at the end,
remove any trailing blank lines if present, and re-run your markdown linting to
confirm the file now passes MD047.
In `@kits/automation/Watchdog/app/actions.ts`:
- Line 16: The analyzeCompetitorsAction function uses a broad any[]; replace it
with a concrete interface (e.g., Competitor) that mirrors the flow's inputs.json
schema and use Competitor[] as the parameter type for analyzeCompetitorsAction;
add the Competitor interface (or export it from a nearby types module) with the
exact fields from inputs.json, update any internal uses/calls to satisfy the new
type, and adjust imports/exports so analyzeCompetitorsAction and the new type
are correctly referenced across the codebase.
In `@kits/automation/Watchdog/app/page.tsx`:
- Around line 237-239: The current JSX uses array index as the React key in the
results rendering (results.map(...) key={index}), which can be acceptable now
but is fragible; update the rendering to use a stable ID on each result instead
of index: ensure the data normalization that produces the results array attaches
a stable identifier (e.g., a result.id generated in the normalization step) and
change the map key to use that property (key={item.id}) so the component uses
stable keys (refer to results.map, key={index} and the result objects).
---
Duplicate comments:
In `@kits/automation/Watchdog/app/actions.ts`:
- Around line 95-97: The catch block in actions.ts currently throws a generic
Error for all failures; update it to detect AbortError and rethrow a clear
timeout error message: inside the existing catch (error: any) { ... } check if
error.name === 'AbortError' (or error instanceof DOMException if appropriate)
and throw a new Error like "Operation timed out after 80 seconds"; otherwise
preserve the current behavior (throw new Error(error.message || "An unexpected
error occurred")). This change should be applied where the
timeout/AbortController logic lives so timeout cases are distinguishable from
other failures.
In `@kits/automation/Watchdog/app/page.tsx`:
- Around line 59-69: The normalizeWatchdogData function currently calls
JSON.parse(raw) directly which can throw on malformed input; wrap the parse in a
try/catch and fall back to treating raw as-is (or returning { results: [] }) on
parse error or when raw is null/undefined, so the function never throws; update
the parsing logic inside normalizeWatchdogData to safely attempt JSON.parse in a
try block, catch and log or ignore the error, then continue the existing
detection/conversion steps (checking parsed?.results, parsed?.Result,
Array.isArray(parsed)) using the safe fallback when parsing fails.
In `@kits/automation/Watchdog/package.json`:
- Line 30: The remark-gfm dependency in this kit's package.json is using a caret
range ("remark-gfm": "^4.0.1"); update the package.json entry for remark-gfm to
a pinned exact version (e.g., "remark-gfm": "4.0.1") so it no longer uses ^ or
~, and verify the file contains only explicitly pinned versions for all
dependencies in this kit (not relying on root/workspace hoisting).
🪄 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: b3544644-52fd-4b8c-8898-9f20fe6645c2
⛔ Files ignored due to path filters (2)
.DS_Storeis excluded by!**/.DS_Storekits/automation/Watchdog/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (7)
.github/workflows/validate-pr.yml.gitignoreCONTRIBUTING.mdREADME.mdkits/automation/Watchdog/app/actions.tskits/automation/Watchdog/app/page.tsxkits/automation/Watchdog/package.json
| {results.map((item, index) => ( | ||
| <div | ||
| key={index} |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Results rendered with index keys — acceptable given operational parameters.
While array indices as React keys are generally discouraged, the results array is replaced wholesale (never mutated in place), so React reconciliation risks are minimal here. The competitor list correctly uses stable UUIDs. Low-priority optimization if desired.
🔧 Optional: Add stable IDs to results
If results ever need to persist across partial updates, consider generating IDs during normalization:
const cleanResults: Result[] = rawResults.map((item: any, idx: number) => ({
id: `result-${idx}-${Date.now()}`,
org_name: item.org_name || "Unknown",
response: item.response || (typeof item === "string" ? item : JSON.stringify(item)),
}));🤖 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 237 - 239, The current
JSX uses array index as the React key in the results rendering (results.map(...)
key={index}), which can be acceptable now but is fragible; update the rendering
to use a stable ID on each result instead of index: ensure the data
normalization that produces the results array attaches a stable identifier
(e.g., a result.id generated in the normalization step) and change the map key
to use that property (key={item.id}) so the component uses stable keys (refer to
results.map, key={index} and the result objects).
|
Hello @d-pamneja Thank you for the feedback. I've reverted all changes to the existing kits. Sorry for the inconvenience :) |


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
Core Application Files:
app/page.tsx- Main Next.js dashboard component with competitor watchlist management (add/remove competitors, real-time analysis UI, markdown rendering of intelligence reports)app/layout.tsx- Root layout component with metadata configurationapp/actions.ts- Server action for competitor analysis with input validation (1-10 competitors), rate limiting via Upstash Redis (5 requests/60s), and GraphQL integration with LamaticConfiguration Files:
config.json- Automation metadata, environment variables (WATCHDOG_FLOW_ID), integrations (Firecrawl, Postgres), and deployment URLspackage.json- Next.js 15 project with dependencies: React, Tailwind CSS, Shadcn UI, lucide-react, react-markdown, remark-gfm, lamatic, Upstash Redis/Ratelimittsconfig.json- TypeScript configuration with strict mode, Next.js plugin, and path aliasestailwind.config.ts- Tailwind CSS configuration with custompulse-slowanimation and typography pluginnext.config.mjs- Next.js config ignoring TypeScript errors and disabling image optimizationpostcss.config.mjs- PostCSS with Tailwind plugincomponents.json- Shadcn UI configuration (new-york style, RSC enabled, lucide icon library).gitignore- Node.js/Next.js artifacts exclusionsFlow Metadata & Schema:
flows/watchdog-flow/config.json- Webhook trigger at/executewith output mapping fororg_nameandresponseflows/watchdog-flow/inputs.json- JSON Schema enforcing competitors array (1-10 items, requiredorg_nameandurlper item)flows/watchdog-flow/meta.json- Flow metadata (name, description, ShieldCheck icon, Sales category, Intermediate complexity)flows/watchdog-flow/README.md- Flow documentationStyling & Root Files:
global.css- Tailwind CSS importsREADME.md- Setup instructions, environment variables, repository structureDocumentation:
CONTRIBUTING.md- Updated to guide kit building workflowREADME.md- Updated hero text and badgesRemoved:
kits/agentic/stock-analysis- Git submodule removed.enventry from root.gitignoreFlow Architecture & Functionality
Flow Name: Intelligent Watchdog Flow
Three-Node Workflow:
org_nameandurlfrom Next.js appData Flow:
Key Integration Points: