Skip to content

feat: Add Intelligent Watchdog automation kit for competitor intelligence#109

Open
HarshM1010 wants to merge 35 commits intoLamatic:mainfrom
HarshM1010:feat/Add-Intelligent-Watchdog-automation-kit-for-competitor-intelligence
Open

feat: Add Intelligent Watchdog automation kit for competitor intelligence#109
HarshM1010 wants to merge 35 commits intoLamatic:mainfrom
HarshM1010:feat/Add-Intelligent-Watchdog-automation-kit-for-competitor-intelligence

Conversation

@HarshM1010
Copy link
Copy Markdown

@HarshM1010 HarshM1010 commented Mar 27, 2026

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

  • External Providers: Google Gemini (via Lamatic), Firecrawl (for web scraping)
  • Prerequisites: Lamatic.ai account, Firecrawl API Key (configured in Lamatic Studio)

How to Run Locally

Bash

cd kits/automation/Watchdog
npm install
# Create .env.local and add your Lamatic keys
npm run dev

Live Preview

Vercel URL: https://intelligent-watchdog.vercel.app/

Lamatic Flow

  • Watchdog Flow ID: 811a44e5-a5ab-471e-9b1e-9e994b49554f
  • Project ID: be77e472-8fda-41f1-a52d-575cf5b1bb3f

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

  • Multi-Competitor Watchlist: Track up to 10 competitors simultaneously through a centralized dashboard.
  • Automated Web Scraping: Uses the Firecrawl node to bypass bot detection and extract clean content from landing pages.
  • AI Change Analysis: Compares scraped data against previous states to identify pricing hikes, discounts, or new feature rollouts.
  • Sales Counter-Strategies: Automatically generates objection-handling points based on competitor updates.

Technical Implementation

  • Dynamic Dashboard (app/page.tsx): A responsive, dark-mode UI built with Shadcn UI and Lucide React for managing the watchlist and viewing reports.
  • API Orchestration (app/api/analyse/route.ts): A robust POST handler that validates input, handles batching, and communicates with Lamatic’s GraphQL API.
  • State Management: Local React state for real-time UI updates during long-running scraping operations.
  • Schema Validation: Implements strict checking for competitor object structures to prevent runtime failures.

Configuration

  • Environment Variables: LAMATIC_API_URL, LAMATIC_PROJECT_ID, LAMATIC_API_KEY, WATCHDOG_FLOW_ID.
  • Framework: Next.js with TypeScript and Tailwind CSS.
  • Styling: Custom global CSS for glassmorphism effects and modern dashboard aesthetic.

File Structure

  • app/: Contains the core UI and the /analyse API route.
  • config.json: Metadata for the Lamatic marketplace including environment variable mappings.
  • components.json: UI primitive configurations for Shadcn/Tailwind consistency.
  • README.md: Detailed setup instructions and deployment guide.

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 configuration
  • app/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 Lamatic

Configuration Files:

  • config.json - Automation metadata, environment variables (WATCHDOG_FLOW_ID), integrations (Firecrawl, Postgres), and deployment URLs
  • package.json - Next.js 15 project with dependencies: React, Tailwind CSS, Shadcn UI, lucide-react, react-markdown, remark-gfm, lamatic, Upstash Redis/Ratelimit
  • tsconfig.json - TypeScript configuration with strict mode, Next.js plugin, and path aliases
  • tailwind.config.ts - Tailwind CSS configuration with custom pulse-slow animation and typography plugin
  • next.config.mjs - Next.js config ignoring TypeScript errors and disabling image optimization
  • postcss.config.mjs - PostCSS with Tailwind plugin
  • components.json - Shadcn UI configuration (new-york style, RSC enabled, lucide icon library)
  • .gitignore - Node.js/Next.js artifacts exclusions

Flow Metadata & Schema:

  • flows/watchdog-flow/config.json - Webhook trigger at /execute with output mapping for org_name and response
  • flows/watchdog-flow/inputs.json - JSON Schema enforcing competitors array (1-10 items, required org_name and url per item)
  • flows/watchdog-flow/meta.json - Flow metadata (name, description, ShieldCheck icon, Sales category, Intermediate complexity)
  • flows/watchdog-flow/README.md - Flow documentation

Styling & Root Files:

  • global.css - Tailwind CSS imports
  • README.md - Setup instructions, environment variables, repository structure

Documentation:

  • Root CONTRIBUTING.md - Updated to guide kit building workflow
  • Root README.md - Updated hero text and badges

Removed:

  • kits/agentic/stock-analysis - Git submodule removed
  • .env entry from root .gitignore

Flow Architecture & Functionality

Flow Name: Intelligent Watchdog Flow

Three-Node Workflow:

  1. Webhook Trigger - Ingests competitor list (1-10 max) with org_name and url from Next.js app
  2. Firecrawl Scraper - Fetches live content from competitor landing pages, bypassing bot detection
  3. LLM Analyzer - Google Gemini (via Lamatic) compares current scrape against historical data to identify pricing/feature changes and generate tactical "Sales Battle Cards"

Data Flow:

  • Client sends competitors array → Server action validates & rate-limits → GraphQL call to Lamatic → Webhook executes flow → Firecrawl extracts landing page HTML → LLM compares with stored baseline → Returns org_name + analysis response → UI renders markdown-formatted intelligence report

Key Integration Points:

  • Lamatic.ai GraphQL endpoints for workflow orchestration
  • Firecrawl for automated web scraping
  • Google Gemini for AI-driven change analysis
  • Upstash Redis for rate limiting
  • Next.js 15 with React Server Actions for backend coordination

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Your Mission, Should You Choose to Accept

Walkthrough

This 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

Cohort / File(s) Summary
Intelligent Watchdog Kit – Next.js App
kits/automation/Watchdog/app/layout.tsx, kits/automation/Watchdog/app/page.tsx, kits/automation/Watchdog/app/actions.ts
New Next.js dashboard UI with competitor tracking (max 10 entries), real-time analysis orchestration via server actions, rate limiting, Lamatic workflow integration, and markdown-rendered battle card results.
Intelligent Watchdog Kit – Build Configuration
kits/automation/Watchdog/package.json, kits/automation/Watchdog/tsconfig.json, kits/automation/Watchdog/next.config.mjs, kits/automation/Watchdog/tailwind.config.ts, kits/automation/Watchdog/postcss.config.mjs
Next.js and TypeScript setup with Tailwind styling, custom animations, production dependency declarations (React Markdown, Upstash, Lucide), and build configuration tolerating TypeScript errors.
Intelligent Watchdog Kit – Component & UI Setup
kits/automation/Watchdog/components.json, kits/automation/Watchdog/global.css, kits/automation/Watchdog/.gitignore
Shadcn UI configuration, Tailwind CSS imports, and Node.js/.env ignore patterns for the kit environment.
Intelligent Watchdog Kit – Metadata & Documentation
kits/automation/Watchdog/config.json, kits/automation/Watchdog/README.md
Automation metadata (name, tags, author, integrations: Firecrawl & Postgres), feature descriptions, setup instructions, and demo/deployment/documentation URLs.
Intelligent Watchdog Flow – Workflow Definition
kits/automation/Watchdog/flows/watchdog-flow/config.json, kits/automation/Watchdog/flows/watchdog-flow/inputs.json, kits/automation/Watchdog/flows/watchdog-flow/meta.json, kits/automation/Watchdog/flows/watchdog-flow/README.md
Workflow trigger configuration, input schema (1–10 competitor objects with org_name & URL), flow metadata (icon, category, complexity), and workflow documentation.
Repository & CI/CD Updates
.github/workflows/validate-pr.yml, .gitignore, kits/agentic/stock-analysis
Removed PR validation side effects (comment posting, label application, temporary file usage), simplified .env ignore handling, and deleted stock-analysis submodule reference.
Contributing & Marketing Documentation
CONTRIBUTING.md, README.md
Reframed contribution guide to focus on Kit building workflows; updated hero heading to "Stack to Build Agentic SaaS → 10x faster" and re-enabled GitHub Actions badge markup.

Suggested reviewers

  • amanintech
  • d-pamneja

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)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely summarizes the main contribution: adding a new Intelligent Watchdog automation kit for competitor intelligence, which aligns with the substantial new kit added to kits/automation/Watchdog/.
Description check ✅ Passed The PR description comprehensively covers all required checklist items: kit contribution type confirmed, single project focus, no secrets exposed, proper folder structure established, complete file structure with config.json and flow metadata included, setup instructions provided, and live preview URL shared.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Author

@HarshM1010 HarshM1010 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have resolved the issues

@HarshM1010
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai bot requested a review from amanintech March 27, 2026 08:52
@HarshM1010
Copy link
Copy Markdown
Author

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!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5b8dea8 and f6a21b1.

⛔ Files ignored due to path filters (1)
  • kits/automation/Watchdog/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (19)
  • CHALLENGE.md
  • CLAUDE.md
  • kits/automation/Watchdog/.gitignore
  • kits/automation/Watchdog/README.md
  • kits/automation/Watchdog/app/api/analyse/route.ts
  • kits/automation/Watchdog/app/layout.tsx
  • kits/automation/Watchdog/app/page.tsx
  • kits/automation/Watchdog/components.json
  • kits/automation/Watchdog/config.json
  • kits/automation/Watchdog/flows/watchdog-flow/README.md
  • kits/automation/Watchdog/flows/watchdog-flow/config.json
  • kits/automation/Watchdog/flows/watchdog-flow/inputs.json
  • kits/automation/Watchdog/flows/watchdog-flow/meta.json
  • kits/automation/Watchdog/global.css
  • kits/automation/Watchdog/next.config.mjs
  • kits/automation/Watchdog/package.json
  • kits/automation/Watchdog/postcss.config.mjs
  • kits/automation/Watchdog/tailwind.config.ts
  • kits/automation/Watchdog/tsconfig.json
💤 Files with no reviewable changes (2)
  • CHALLENGE.md
  • CLAUDE.md

Comment on lines +19 to +22
useEffect(() => {
const handleKey = (e: KeyboardEvent) => { if (e.key === "Escape") setModalOpen(false); };
window.addEventListener("keydown", handleKey);
return () => window.removeEventListener("keydown", handleKey);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

@HarshM1010
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (4)
kits/automation/Watchdog/config.json (2)

23-25: ⚠️ Potential issue | 🟠 Major

Deploy coordinates still point to wrong extraction zone, Agent.

The deployUrl references root-directory=kits/automation/intelligent-watchdog but the actual kit path is kits/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 | 🟠 Major

Agent, 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-flow but the actual flow folder is watchdog-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.json must 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 | 🟡 Minor

Escape route doesn't follow protocol, Agent.

The closeModal helper (lines 20-25) properly resets all modal state, but the Escape key handler (line 28) still calls setModalOpen(false) directly. This can leave stale newName, newUrl, and error values 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 closeModal in useCallback to 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 | 🟠 Major

Response 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:

  1. Updating the flow's outputMapping to expose a stable, documented structure
  2. 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.ts so 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

📥 Commits

Reviewing files that changed from the base of the PR and between f6a21b1 and 0ab3d9a.

📒 Files selected for processing (5)
  • kits/automation/Watchdog/README.md
  • kits/automation/Watchdog/app/api/analyse/route.ts
  • kits/automation/Watchdog/app/page.tsx
  • kits/automation/Watchdog/config.json
  • kits/automation/Watchdog/package.json

Comment on lines +11 to +14
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"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🚨 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_ID with actual UUID
  • LAMATIC_API_URL with real endpoint
  • LAMATIC_PROJECT_ID with actual UUID
  • LAMATIC_API_KEY with 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-key

Immediate action required:

  1. Rotate/revoke the exposed LAMATIC_API_KEY in your Lamatic dashboard
  2. Replace with placeholder values in this file
  3. Consider adding a .gitignore rule 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.

Suggested change
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.

@HarshM1010
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (4)
kits/automation/Watchdog/app/page.tsx (2)

27-31: ⚠️ Potential issue | 🟡 Minor

Escape route still bypasses decontamination protocol, Agent.

The Escape key handler (line 28) calls setModalOpen(false) directly instead of using the closeModal() 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 closeModal in useCallback or 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 | 🟠 Major

Mission-critical: Response parser references a phantom node, Agent.

Line 78 extracts data from item.codeNode_584?.output?.formatted, but according to the flow configuration at kits/automation/Watchdog/flows/watchdog-flow/config.json, the outputMapping maps result to LLMNode_331.output.generatedResponse — not codeNode_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 | 🔵 Trivial

Intel 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_ID with real UUID
  • LAMATIC_API_URL with actual endpoint
  • LAMATIC_PROJECT_ID with real UUID
  • LAMATIC_API_KEY with actual key value

Static analysis confirms: "Detected a Generic API Key, potentially exposing access to various services and sensitive operations."

Immediate action required:

  1. Rotate/revoke the exposed LAMATIC_API_KEY in your Lamatic dashboard — consider it compromised
  2. 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-key

Based on learnings: "Never commit real API keys, secrets, or credentials; use .env.example with 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

📥 Commits

Reviewing files that changed from the base of the PR and between 0ab3d9a and 3095fd2.

📒 Files selected for processing (5)
  • kits/automation/Watchdog/README.md
  • kits/automation/Watchdog/app/api/analyse/route.ts
  • kits/automation/Watchdog/app/page.tsx
  • kits/automation/Watchdog/flows/watchdog-flow/README.md
  • kits/automation/Watchdog/flows/watchdog-flow/inputs.json

@HarshM1010
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 28, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
kits/automation/Watchdog/flows/watchdog-flow/config.json (1)

2-17: ⚠️ Potential issue | 🔴 Critical

Your mission: verify this flow config was properly exported from Lamatic Studio, Agent.

The outputMapping references nodes forLoopNode_304 and LLMNode_331, but the nodes array only contains the trigger webhook 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 flow config.json files 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 | 🟡 Minor

Your mission: ensure the Escape key uses the extraction protocol, Agent.

The Escape key handler at Line 28 calls setModalOpen(false) directly instead of closeModal(). This bypasses the cleanup logic, leaving newName, newUrl, and error in 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 closeModal in useCallback to 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

📥 Commits

Reviewing files that changed from the base of the PR and between fb945dc and ead9c79.

📒 Files selected for processing (3)
  • kits/automation/Watchdog/app/api/analyse/route.ts
  • kits/automation/Watchdog/app/page.tsx
  • kits/automation/Watchdog/flows/watchdog-flow/config.json

@github-actions
Copy link
Copy Markdown

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:

  1. Read through all CodeRabbit comments carefully
  2. Address each issue raised (or reply explaining why you disagree)
  3. Push your fixes as new commits
  4. Once all issues are resolved, comment here so we can re-review

This helps keep the review process efficient for everyone. Thank you! 🙏

@d-pamneja
Copy link
Copy Markdown
Contributor

Screenshot 2026-03-31 at 1 31 24 PM Here, you could fix the UI to render the markdown of the final answer. Rest LGTM!

@HarshM1010
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

♻️ Duplicate comments (1)
kits/automation/Watchdog/app/page.tsx (1)

58-68: ⚠️ Potential issue | 🟡 Minor

Intel parsing could detonate on malformed payloads, Agent.

If raw is 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

📥 Commits

Reviewing files that changed from the base of the PR and between ead9c79 and b7edf0b.

⛔ Files ignored due to path filters (1)
  • kits/automation/Watchdog/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • kits/agentic/stock-analysis
  • kits/automation/Watchdog/app/actions.ts
  • kits/automation/Watchdog/app/api/analyse/route.ts
  • kits/automation/Watchdog/app/page.tsx
  • kits/automation/Watchdog/package.json
💤 Files with no reviewable changes (1)
  • kits/agentic/stock-analysis

Comment on lines +47 to +62
// 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 },
},
}),
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 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 -C2

Repository: 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/null

Repository: 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.ts

Repository: 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.

@HarshM1010 HarshM1010 force-pushed the feat/Add-Intelligent-Watchdog-automation-kit-for-competitor-intelligence branch from b657c8f to b745f04 Compare March 31, 2026 20:03
@HarshM1010
Copy link
Copy Markdown
Author

Screenshot 2026-03-31 at 1 31 24 PM Here, you could fix the UI to render the markdown of the final answer. Rest LGTM!

Screenshot 2026-03-31 at 1 31 24 PM Here, you could fix the UI to render the markdown of the final answer. Rest LGTM!

Done! I've updated the UI to properly render the Markdown for the final response. It’s much more readable now—thanks for the catch!

HarshM1010 and others added 4 commits April 1, 2026 12:42
Copy link
Copy Markdown
Contributor

@d-pamneja d-pamneja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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!

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 1, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 1, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (3)
kits/automation/Watchdog/app/page.tsx (1)

59-69: ⚠️ Potential issue | 🟠 Major

Intel 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 | 🟡 Minor

Abort signal deployed — but extraction protocol incomplete, Agent.

The timeout mechanism at lines 62-63 is in place, but the catch block doesn't distinguish AbortError from 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 | 🟡 Minor

One asset remains unpinned — mission not yet complete, Agent.

The remark-gfm dependency 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.json with 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

📥 Commits

Reviewing files that changed from the base of the PR and between b7edf0b and e00692f.

⛔ Files ignored due to path filters (2)
  • .DS_Store is excluded by !**/.DS_Store
  • kits/automation/Watchdog/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • .github/workflows/validate-pr.yml
  • .gitignore
  • CONTRIBUTING.md
  • README.md
  • kits/automation/Watchdog/app/actions.ts
  • kits/automation/Watchdog/app/page.tsx
  • kits/automation/Watchdog/package.json

Comment on lines +237 to +239
{results.map((item, index) => (
<div
key={index}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 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).

@HarshM1010
Copy link
Copy Markdown
Author

Hello @d-pamneja Thank you for the feedback. I've reverted all changes to the existing kits. Sorry for the inconvenience :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants