feat: Add prd-copilot kit#195
Conversation
WalkthroughThis PR introduces a new "PRD Copilot" kit under kits/prd-copilot: agent and flow documentation, a default constitution, a Lamatic orchestration server action and client, and a full Next.js app scaffold (layout, styling, config, dependencies) with a Mermaid-rendering PRD workflow UI. ChangesPRD Copilot Kit
Suggested reviewers: Your mission, should you choose to accept it: review this PRD Copilot kit before it self-destructs in five seconds. Good luck. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Biome (2.5.1)kits/prd-copilot/apps/app/globals.cssFile contains syntax errors that prevent linting: Line 4: Tailwind-specific syntax is disabled.; Line 77: Tailwind-specific syntax is disabled.; Line 120: Tailwind-specific syntax is disabled.; Line 123: Tailwind-specific syntax is disabled. 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 |
:robot_face: AgentKit Structural ValidationNew Contributions Detected
Check Results
🎉 All checks passed! This contribution follows the AgentKit structure. |
There was a problem hiding this comment.
Actionable comments posted: 10
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@kits/prd-copilot/apps/actions/orchestrate.ts`:
- Line 92: The logging in orchestrate.ts is exposing the full Lamatic response
payload via JSON.stringify(resData), which can leak user ideas, answers, and
generated PRDs. Update the console.log in orchestrate flow handling to log only
a minimal non-sensitive summary or metadata (for example, status or identifiers)
instead of the raw payload, and keep the rest of the response out of logs.
In `@kits/prd-copilot/apps/app/layout.tsx`:
- Around line 6-7: The Geist and Geist Mono fonts are created in layout.tsx but
never applied, so their generated font-face values won’t be used. Update the
layout component to attach the appropriate font className/variable from _geist
and _geistMono to the root DOM element (typically body), and then change
globals.css to reference those font variables instead of the literal Geist
family name. Make sure the fix is centered around the existing Geist and
Geist_Mono declarations in layout.tsx and the font-sans / font-mono settings in
globals.css.
- Around line 9-13: Update the metadata in layout.tsx so the exported metadata
for the app uses PRD Copilot branding instead of the default v0 template values.
In the metadata object, change the title, description, and generator fields in
the metadata export to match the PRD Copilot kit identity, keeping the rest of
the metadata structure intact.
In `@kits/prd-copilot/apps/app/page.tsx`:
- Around line 252-268: The clarifying questions form in the page component is
still using raw inputs with manual answer state, so replace that form handling
with react-hook-form and zod in the questions section. Update the form logic
around the questions rendering to use a schema-based resolver, register each
question field through the form API, and move the existing
handleAnswerChange/answers state flow to react-hook-form-managed values while
keeping the current UI and validation behavior compatible with React 19.
In `@kits/prd-copilot/apps/components/MermaidDiagram.tsx`:
- Around line 17-29: The Mermaid initialization in MermaidDiagram is using a
permissive security setting that can allow unsafe HTML through diagram labels.
Update the mermaid.initialize call to use strict sanitization by changing the
securityLevel setting from loose to strict while keeping the existing theme and
themeVariables configuration intact.
In `@kits/prd-copilot/apps/next.config.mjs`:
- Around line 3-5: Remove the TypeScript build override from next.config.mjs by
updating the Next.js config object so it no longer sets ignoreBuildErrors inside
the typescript block. Keep the rest of the configuration, including
images.unoptimized, unchanged, and make sure the exported config from the
Next.js settings enforces type checking during builds.
In `@kits/prd-copilot/apps/orchestrate.js`:
- Around line 1-27: Convert the orchestrate config from the current JavaScript
module to a TypeScript module so the exported shape is typed instead of inferred
as any. Define explicit interfaces/types for the config object and the nested
flow entry used by config.flows["prd-copilot"], then export config with that
type so consumers like lamatic-client.ts and orchestrate.ts get compile-time
checking for fields such as workflowId, expectedOutput, and api properties.
Update the module name/imports accordingly so the typed config remains the
single source of truth and catches drift or typos in the orchestrate contract.
In `@kits/prd-copilot/apps/package.json`:
- Line 46: Remove the redundant Tailwind v3-era dependencies from the package
manifest: drop autoprefixer and tailwindcss-animate from the apps package so
Tailwind CSS v4 relies on its built-in Lightning CSS prefixing and the existing
tw-animate-css plugin instead. Update the dependency list in the package.json
used by the app, keeping only the v4-compatible animation package, and make sure
no build/config files still reference autoprefixer or tailwindcss-animate after
the cleanup.
- Line 53: The dependency list in package.json still pins lamatic to latest, and
react-markdown should be fixed too; replace both with explicit version numbers
instead of floating tags so installs are reproducible. Update the dependencies
entries for lamatic and react-markdown together, keeping the rest of the package
manifest unchanged.
In `@kits/prd-copilot/apps/tsconfig.json`:
- Line 9: The TypeScript compiler target in the main tsconfig is too old for the
Next.js 16 / React 19 setup, so update the tsconfig `target` setting from ES6 to
ES2017 or higher. Use the existing `target` entry in the tsconfig file and keep
the rest of the compiler options unchanged unless needed, so type checking can
recognize modern built-ins like `Object.entries` and async/await without extra
lib tweaks.
🪄 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: 6425f034-fb84-4622-b9b4-3c79763c3e2b
⛔ Files ignored due to path filters (1)
kits/prd-copilot/apps/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (19)
kits/prd-copilot/README.mdkits/prd-copilot/agent.mdkits/prd-copilot/apps/.env.examplekits/prd-copilot/apps/.gitignorekits/prd-copilot/apps/actions/orchestrate.tskits/prd-copilot/apps/app/globals.csskits/prd-copilot/apps/app/layout.tsxkits/prd-copilot/apps/app/page.tsxkits/prd-copilot/apps/components.jsonkits/prd-copilot/apps/components/MermaidDiagram.tsxkits/prd-copilot/apps/lib/lamatic-client.tskits/prd-copilot/apps/next.config.mjskits/prd-copilot/apps/orchestrate.jskits/prd-copilot/apps/package.jsonkits/prd-copilot/apps/postcss.config.mjskits/prd-copilot/apps/tsconfig.jsonkits/prd-copilot/constitutions/default.mdkits/prd-copilot/flows/prd-copilot.tskits/prd-copilot/lamatic.config.ts
| const _geist = Geist({ subsets: ["latin"] }); | ||
| const _geistMono = Geist_Mono({ subsets: ["latin"] }); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Fonts declared but never applied — Geist fonts won't load.
The _geist and _geistMono variables are created but their .className or .variable properties are never applied to the DOM. In Next.js, next/font/google generates @font-face declarations with hashed font-family names (e.g., __Geist_hash), not the literal 'Geist'. The --font-sans: 'Geist' reference in globals.css won't match, so the app silently falls back to system fonts.
Apply the font CSS variables to <body> and update globals.css to reference them.
🔧 Proposed fix
In layout.tsx:
-const _geist = Geist({ subsets: ["latin"] });
-const _geistMono = Geist_Mono({ subsets: ["latin"] });
+const geist = Geist({ subsets: ["latin"], variable: "--font-geist" });
+const geistMono = Geist_Mono({ subsets: ["latin"], variable: "--font-geist-mono" });- <body className={`font-sans antialiased`}>
+ <body className={`${geist.variable} ${geistMono.variable} font-sans antialiased`}>In globals.css (lines 78-79):
- --font-sans: 'Geist', 'Geist Fallback';
- --font-mono: 'Geist Mono', 'Geist Mono Fallback';
+ --font-sans: var(--font-geist), 'Geist Fallback';
+ --font-mono: var(--font-geist-mono), 'Geist Mono Fallback';Also applies to: 39-39
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/prd-copilot/apps/app/layout.tsx` around lines 6 - 7, The Geist and Geist
Mono fonts are created in layout.tsx but never applied, so their generated
font-face values won’t be used. Update the layout component to attach the
appropriate font className/variable from _geist and _geistMono to the root DOM
element (typically body), and then change globals.css to reference those font
variables instead of the literal Geist family name. Make sure the fix is
centered around the existing Geist and Geist_Mono declarations in layout.tsx and
the font-sans / font-mono settings in globals.css.
| <div className="space-y-6"> | ||
| {questions.map((q, index) => ( | ||
| <div key={index} className="space-y-2"> | ||
| <label className="text-sm font-medium text-slate-200 flex items-start space-x-2"> | ||
| <ChevronRight className="h-4 w-4 mt-0.5 text-blue-500 shrink-0" /> | ||
| <span>{q}</span> | ||
| </label> | ||
| <input | ||
| type="text" | ||
| value={answers[index] || ""} | ||
| onChange={(e) => handleAnswerChange(index, e.target.value)} | ||
| placeholder="Your answer..." | ||
| className="w-full rounded-xl border border-slate-800 bg-slate-950/60 p-3 text-sm text-slate-100 placeholder:text-slate-700 focus:border-blue-500/50 focus:outline-none transition" | ||
| /> | ||
| </div> | ||
| ))} | ||
| </div> |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Use react-hook-form + zod for the questions form per coding guidelines.
The clarifying questions form uses raw <input> elements with manual state management. The kit coding guidelines require react-hook-form + zod for forms. While the current implementation works, migrating would add validation, cleaner state handling, and guideline compliance.
Based on learnings, the platform standard is Next.js 16.0.0 and React 19.2.0, so ensure any react-hook-form usage is compatible with React 19. As per coding guidelines, kit Next.js apps must use react-hook-form + zod for forms.
♻️ Suggested refactor for the questions form
+import { useForm } from "react-hook-form";
+import { z } from "zod";
+const answersSchema = z.object({
+ answers: z.array(z.string().default("")),
+});
// Inside component:
+const { register, handleSubmit, watch } = useForm({
+ defaultValues: { answers: new Array(questions.length).fill("") },
+});
// Replace the manual input mapping:
-<input
- type="text"
- value={answers[index] || ""}
- onChange={(e) => handleAnswerChange(index, e.target.value)}
- placeholder="Your answer..."
- className="..."
-/>
+<input
+ type="text"
+ {...register(`answers.${index}`)}
+ placeholder="Your answer..."
+ className="..."
+/>
// Replace handleFinalizePRD call:
-<button onClick={handleFinalizePRD} ...>
+<button onClick={handleSubmit((data) => handleFinalizePRD(data.answers))} ...>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/prd-copilot/apps/app/page.tsx` around lines 252 - 268, The clarifying
questions form in the page component is still using raw inputs with manual
answer state, so replace that form handling with react-hook-form and zod in the
questions section. Update the form logic around the questions rendering to use a
schema-based resolver, register each question field through the form API, and
move the existing handleAnswerChange/answers state flow to
react-hook-form-managed values while keeping the current UI and validation
behavior compatible with React 19.
Sources: Coding guidelines, Learnings
| export const config = { | ||
| "type": "atomic", | ||
| "flows": { | ||
| "prd-copilot": { | ||
| "name": "PRD Copilot", | ||
| "type": "graphQL", | ||
| "workflowId": process.env.PRD_COPILOT_FLOW_ID, | ||
| "description": "Draft and refine a Product Requirement Document (PRD) and generate a Mermaid flowchart", | ||
| "expectedOutput": ["answer"], | ||
| "inputSchema": { | ||
| "mode": "string", | ||
| "instructions": "string", | ||
| "answers": "string" | ||
| }, | ||
| "outputSchema": { | ||
| "answer": "string" | ||
| }, | ||
| "mode": "sync", | ||
| "polling": "false" | ||
| } | ||
| }, | ||
| "api": { | ||
| "endpoint": process.env.LAMATIC_API_URL, | ||
| "projectId": process.env.LAMATIC_PROJECT_ID, | ||
| "apiKey": process.env.LAMATIC_API_KEY | ||
| } | ||
| }; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Consider converting orchestrate.js to TypeScript for type safety.
This .js config is imported by .ts files (lamatic-client.ts, orchestrate.ts). With allowJs: true, TypeScript infers any for the export, so config.flows, config.api, and field names like workflowId are untyped. Converting to orchestrate.ts with an explicit interface would catch typos and contract drift at compile time.
♻️ Proposed TypeScript version
export interface FlowConfig {
name: string;
type: string;
workflowId: string | undefined;
description: string;
expectedOutput: string[];
inputSchema: Record<string, string>;
outputSchema: Record<string, string>;
mode: string;
polling: boolean;
}
export interface AppConfig {
type: string;
flows: Record<string, FlowConfig>;
api: {
endpoint: string | undefined;
projectId: string | undefined;
apiKey: string | undefined;
};
}
export const config: AppConfig = {
type: "atomic",
flows: {
"prd-copilot": {
name: "PRD Copilot",
type: "graphQL",
workflowId: process.env.PRD_COPILOT_FLOW_ID,
description: "Draft and refine a Product Requirement Document (PRD) and generate a Mermaid flowchart",
expectedOutput: ["answer"],
inputSchema: { mode: "string", instructions: "string", answers: "string" },
outputSchema: { answer: "string" },
mode: "sync",
polling: false,
},
},
api: {
endpoint: process.env.LAMATIC_API_URL,
projectId: process.env.LAMATIC_PROJECT_ID,
apiKey: process.env.LAMATIC_API_KEY,
},
};🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/prd-copilot/apps/orchestrate.js` around lines 1 - 27, Convert the
orchestrate config from the current JavaScript module to a TypeScript module so
the exported shape is typed instead of inferred as any. Define explicit
interfaces/types for the config object and the nested flow entry used by
config.flows["prd-copilot"], then export config with that type so consumers like
lamatic-client.ts and orchestrate.ts get compile-time checking for fields such
as workflowId, expectedOutput, and api properties. Update the module
name/imports accordingly so the typed config remains the single source of truth
and catches drift or typos in the orchestrate contract.
…and ts migrations
|
@coderabbitai Please re-review the pull request. We have addressed all your review feedback in the latest commits:
Please verify these fixes and update the PR status accordingly. Thanks! |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
cd /tmp 2>/dev/null || true
# Check orchestrate.ts logging
echo "=== orchestrate.ts ==="
fd orchestrate.ts kits/prd-copilot || true
cat kits/prd-copilot/apps/actions/orchestrate.ts 2>/dev/null || true
echo "=== orchestrate.ts (root, formerly .js) ==="
cat kits/prd-copilot/apps/orchestrate.ts 2>/dev/null || echo "not found"
fd 'orchestrate.js' kits/prd-copilot || echo "orchestrate.js not found"
echo "=== MermaidDiagram.tsx ==="
cat kits/prd-copilot/apps/components/MermaidDiagram.tsx 2>/dev/null
echo "=== layout.tsx ==="
cat kits/prd-copilot/apps/app/layout.tsx 2>/dev/null
echo "=== globals.css ==="
cat kits/prd-copilot/apps/app/globals.css 2>/dev/null
echo "=== package.json ==="
cat kits/prd-copilot/apps/package.json 2>/dev/nullLength of output: 1418 🏁 Script executed: #!/bin/bash
set -euo pipefail
pwd
ls
echo "=== find kits ==="
fd -t d prd-copilot
echo "=== orchestrate files ==="
fd orchestrate kits/prd-copilotLength of output: 569 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== actions/orchestrate.ts ==="
cat kits/prd-copilot/apps/actions/orchestrate.ts
echo "=== apps/orchestrate.ts ==="
cat kits/prd-copilot/apps/orchestrate.ts
echo "=== MermaidDiagram.tsx ==="
cat kits/prd-copilot/apps/components/MermaidDiagram.tsx
echo "=== layout.tsx ==="
cat kits/prd-copilot/apps/app/layout.tsx
echo "=== globals.css (head) ==="
sed -n '1,40p' kits/prd-copilot/apps/app/globals.css
echo "=== package.json ==="
cat kits/prd-copilot/apps/package.jsonLength of output: 13517
This message will self-destruct... just kidding, but the mission is a success. Triggering a fresh review now to lock in the verification. ✅ Action performedReview finished.
|
|
@coderabbitai Please verify if all review checks are now complete and resolved with the latest commits. If everything is perfect and ready for merge, |
|
Tip For best results, initiate chat on the files or code changes.
This tape will self-destruct in five seconds — but before it does: Good luck, and godspeed. 🫡 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@kits/prd-copilot/apps/actions/orchestrate.ts`:
- Line 95: The fallback in orchestrate.ts currently uses an unsafe as any cast
on the Lamatic response path, which bypasses type checking. Update the rawAnswer
assignment to use a precise type assertion for the alternate output.answer shape
instead of any, and keep the existing resData/result/answer access pattern
intact. Use the surrounding symbols rawAnswer and resData to locate the change.
🪄 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: a32b01d9-4d40-4eb8-a40f-84093c13cb6e
📒 Files selected for processing (9)
kits/prd-copilot/apps/actions/orchestrate.tskits/prd-copilot/apps/app/globals.csskits/prd-copilot/apps/app/layout.tsxkits/prd-copilot/apps/components/MermaidDiagram.tsxkits/prd-copilot/apps/lib/lamatic-client.tskits/prd-copilot/apps/next.config.mjskits/prd-copilot/apps/orchestrate.tskits/prd-copilot/apps/package.jsonkits/prd-copilot/apps/tsconfig.json
💤 Files with no reviewable changes (1)
- kits/prd-copilot/apps/next.config.mjs
| console.log("[PRD Copilot] Flow execution completed. Status:", resData?.status); | ||
|
|
||
| // Lamatic SDK response mapping normally puts the output inside result?.answer | ||
| const rawAnswer = resData?.result?.answer || (resData as any)?.output?.answer; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Replace as any with a precise type assertion.
The as any cast disables all type checking on the Lamatic response fallback path. A targeted type assertion preserves compile-time safety while accommodating the alternative output.answer shape.
♻️ Proposed refactor
- const rawAnswer = resData?.result?.answer || (resData as any)?.output?.answer;
+ const rawAnswer = resData?.result?.answer || (resData as { output?: { answer?: string } })?.output?.answer;📝 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.
| const rawAnswer = resData?.result?.answer || (resData as any)?.output?.answer; | |
| const rawAnswer = resData?.result?.answer || (resData as { output?: { answer?: string } })?.output?.answer; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@kits/prd-copilot/apps/actions/orchestrate.ts` at line 95, The fallback in
orchestrate.ts currently uses an unsafe as any cast on the Lamatic response
path, which bypasses type checking. Update the rawAnswer assignment to use a
precise type assertion for the alternate output.answer shape instead of any, and
keep the existing resData/result/answer access pattern intact. Use the
surrounding symbols rawAnswer and resData to locate the change.
|
Hi @Mahajan-Sachin! 👋 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! 🙏 |
Description
This Pull Request introduces the PRD Copilot Kit to AgentKit. The PRD Copilot is an agentic tool that automates the generation of detailed Product Requirements Documents (PRDs) and visual application flowcharts from raw user ideas, incorporating interactive clarifying questions.
Key Features:
mode: draftvsmode: refine).PR Checklist
1. Select Contribution Type
kits/<category>/<kit-name>/)bundles/<bundle-name>/)templates/<template-name>/)2. General Requirements
kebab-caseand matches the flow IDREADME.md(purpose, setup, usage)3. File Structure (Check what applies)
lamatic.config.tspresent with valid metadata (name, description, tags, steps, author, env keys).env.examplewith placeholder values only (kits only)4. Validation
npm install && npm run devworks locally (kits: UI runs; bundles/templates: flows are valid)feat: Add prd-copilot kit)kits/prd-copilot/README.md,kits/prd-copilot/agent.md,kits/prd-copilot/lamatic.config.ts,.env.examplefiles, andconstitutions/default.md.kits/prd-copilot/apps/, including Next.js config, TypeScript config, PostCSS config, package metadata,.gitignore, shadcn config, global styles, root layout, and the main page.kits/prd-copilot/apps/actions/orchestrate.ts,apps/orchestrate.ts, andapps/lib/lamatic-client.tsto call the Lamatic flow and parse draft/refine responses.kits/prd-copilot/apps/components/MermaidDiagram.tsxfor visualizing generated flowcharts.kits/prd-copilot/flows/prd-copilot.ts.meta, emptyinputs, a constitution reference, and emptynodes/edges; no node types are defined yet in the checked-in flow file.