Conversation
Add architecture analysis suite: cycle detection, smell detection, graph metrics, Mermaid export
- Add GraphBranch, BranchDiff, NodeDiff, EdgeDiff types to schema.ts - Create branches.ts with createBranch() and diffBranches() logic - Add branch persistence to store.ts (saveBranch, loadBranches, loadBranch, deleteBranch) - Add API routes: POST/GET /api/branches, POST /api/branches/diff, GET/DELETE /api/branches/[id] - Update blueprint-workbench.tsx with full branch panel UI - Add CSS styles for branch panel and diff visualization - Add 23 unit/integration tests covering branches.ts and both new API routes Co-authored-by: nehraa <187715469+nehraa@users.noreply.github.com>
…ntic IDE Co-authored-by: nehraa <187715469+nehraa@users.noreply.github.com>
…uals Co-authored-by: nehraa <187715469+nehraa@users.noreply.github.com>
Co-authored-by: nehraa <187715469+nehraa@users.noreply.github.com>
Co-authored-by: nehraa <187715469+nehraa@users.noreply.github.com>
Co-authored-by: nehraa <187715469+nehraa@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…dashboard feat: Heatmap observability dashboard with live trace visuals and auto-polling
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Add attachObservabilitySnapshot, attachRiskReport, attachSessionSnapshot helpers and integrate them into createBranch as attachObservability, attachRisk, attachSession options. attachRisk requires runPlan. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New @abhinav2203/codeflow-prd package for PRD markdown parsing and BlueprintGraph building. Includes: - parsePrd(): converts PRD markdown to BlueprintNode/Edge/Workflow structures - buildBlueprintGraph(): assembles a full BlueprintGraph from parsed PRD - Inline utils (slugify, createNode, mergeContracts, dedupeEdges) from core - withSpecDrafts(): adds scaffold status to code-bearing nodes Wired src/app/api/blueprint/route.ts and src/app/api/generate-blueprint/route.ts to import from the package. Updated imports to use @abhinav2203/codeflow-core/schema and internal/utils. Note: Repo analysis (analyzeTypeScriptRepo) and CodeRag integration are deferred to a future version once those dependencies are packaged. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change markCompleted to take explicit success boolean instead of duck-typing - Add retry logic to executeTask using maxRetries config - Add tests for getFailedCount(), circular dependency detection, and non-existent dependency task ID handling Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace placeholder spawnAgent() with opencode run integration using execa - Add --serve and --acp CLI flags to start opencode headless/ACP servers - Update coder-prompt.ts for CLI-optimized prompts - Add execa@^9.0.0 dependency - Update test to reflect new behavior (returns failure result instead of throwing) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add `src/agent/blueprint.ts` with `blueprintToTasks()` to convert BlueprintGraph to AgentTask[] - Add `src/store/reasoning.ts` with `saveReasoningTrace()` and `appendReasoningStep()` for reasoning traces - Update `src/agent/execution-context.ts` with `executeBlueprint()` for blueprint-based orchestration - Update CLI in `src/cli/index.ts` to support `--blueprint <file>` flag for blueprint execution Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…eneration Add comprehensive AI-powered orchestration for codeflow-agent: - NVIDIA Llama blueprint generation via `generateBlueprint()` - Per-node prompt building via `buildNodePrompt()` - OpenCode HTTP API code generation via `generateNodeCode()` - Permission system with yolo/always-ask/important modes New files: - src/ai/blueprint-generator.ts: Blueprint generation using NVIDIA API - src/ai/node-prompts.ts: Build implementation prompts for blueprint nodes - src/ai/code-generator.ts: OpenCode HTTP client for code generation - src/ai/opencode-client.ts: OpenCode session management and HTTP client - src/permissions/manager.ts: Permission modes and approval logic - src/types/blueprint.ts: BlueprintGraph and BlueprintNode types CLI updates: - Add --generate "<prompt>" for AI blueprint generation - Add --permission=yolo|always-ask|important mode selection - Add --inspect to show prompts before generation - Add --nvidia-api-key and --opencode-url options Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… from execution chore(execution): remove codegen, strip utils, update runtime imports Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Delete src/types/blueprint.ts and update all importers to use @abhinav2203/codeflow-core/schema directly. RiskLevel is now defined locally in permissions/manager.ts since it doesn't exist in core schema. Updated files: - ai/blueprint-generator.ts: import from @abhinav2203/codeflow-core/schema - ai/node-prompts.ts: import from @abhinav2203/codeflow-core/schema - ai/index.ts: removed blueprint type re-exports, re-export RiskLevel from permissions/manager - cli/index.ts: import BlueprintGraph from @abhinav2203/codeflow-core/schema - permissions/manager.ts: define RiskLevel locally (not in core schema) - ai/doc-generator.ts, ai/multi-language-codegen.ts: updated imports - ai/multi-language-codegen.test.ts, ai/test-generator.test.ts: updated imports - ai/doc-generator.test.ts: fixed import path and removed generateMarkdownDocs alias test Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rator - Add execution-context.ts for agent execution management - Add blueprint.ts for workflow blueprint definitions - Add refactor-suggester.ts for code improvement suggestions - Add test-generator.ts for automated test generation - Update ai module with minimax-client integration - Add execution span and runtime contract types - Add VCR and sandbox execution modules Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restructure the monorepo to consolidate all 14 packages under packages/ and add comprehensive per-package documentation. - Add docs/ folder with architecture docs for every package (codeflow-core, analysis, prd, execution, agent, store, canvas, versioning, dtwin, evolution, CodeRag, mcp, master) - Replace the README with a comprehensive monorepo overview - Update .gitignore to exclude .env, dist/, *.tgz, .DS_Store, and other build artifacts and secrets Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bring the source code from the standalone CodeRag and Codeflow_master repositories into this monorepo under packages/. These packages were previously developed as separate repos (nehraa/CodeRag and nehraa/Codeflow_master) but are now first-class packages within the CodeFlow monorepo. - packages/CodeRag: local semantic search, vector store, and CodeRag pipeline (TypeScript, LanceDB, ONNX embeddings) - packages/Codeflow_master: the Next.js 15 / React 19 IDE that mounts every other package behind a unified canvas Build artifacts, .env files, node_modules, and editor caches are excluded via .gitignore. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… .gitignore Root-level directories AGENTS.md/BACKLOG.md/FEATURES.md/PLAN.md, root codeflow-core/ (duplicate of packages/codeflow-core), root prd/ (duplicate of packages/codeflow-prd), root src/ (the IDE's source, now in packages/Codeflow_master/src), scripts/, e2e/, Codeflow_IDE/, claude-code/, .playwright-mcp/, .qwen/, .serena/, .github/, plus root package.json, pnpm-lock.yaml, eslint.config.mjs, next.config.ts, tsconfig.json, vitest.config.ts, full-demo.mjs, test-npm-packages.mjs, cat-*.png are all gone. README quick start now uses pnpm at the workspace root to install every package in one shot, with a fallback path for working on a single package. pnpm-workspace.yaml stays because it is what makes packages/ a real workspace. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…on MCP (#34) Auto-merged by DevPulse PR Watcher (CI green, all checks pass).
…*.loca (#33) Auto-merged by DevPulse PR Watcher (CI green, all checks pass).
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 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 |
PR Summary by QodoDecompose CodeFlow into modular workspace packages
AI Description
Diagram
High-Level Assessment
Files changed (129)
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0efd3be168
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "name": "@abhinav2203/codeflow-core", | ||
| "version": "1.1.5", | ||
| "type": "module", | ||
| "main": "./dist/index.js", |
There was a problem hiding this comment.
Restore the codeflow-core package contents
This package now contains only package.json; it has no src/, dist/, or build script, while this entry point and every declared subpath point into dist/. npm pack --dry-run therefore produces a tarball containing only package.json, so installing or linking the workspace's @abhinav2203/codeflow-core@1.1.5 makes every import from it fail with ERR_MODULE_NOT_FOUND. Restore the implementation/artifacts (and a build path) before publishing or using this workspace package.
Useful? React with 👍 / 👎.
| "types": "./dist/index.d.ts", | ||
| "exports": { | ||
| ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, | ||
| "./build": { "types": "./dist/build/index.d.ts", "default": "./dist/build/index.js" } |
There was a problem hiding this comment.
Point the build export to its emitted file
tsc --outDir dist emits src/build.ts as dist/build.js, but this export resolves @abhinav2203/codeflow-prd/build to the nonexistent dist/build/index.js. That deep import is documented as part of the public API, and importing it currently throws ERR_MODULE_NOT_FOUND; point it at the flat emitted file or add the matching barrel.
Useful? React with 👍 / 👎.
| "types": "./dist/index.d.ts", | ||
| "exports": { | ||
| ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, | ||
| "./agent": { "types": "./dist/agent/index.d.ts", "default": "./dist/agent/index.js" }, |
There was a problem hiding this comment.
Add the documented agent barrel
The advertised @abhinav2203/codeflow-agent/agent entry resolves to dist/agent/index.js, but there is no src/agent/index.ts and the committed build output likewise has no such file. The package documentation imports TaskQueue and AgentSpawner through this path, so those documented consumer examples always fail with ERR_MODULE_NOT_FOUND; add an agent barrel or expose the actual module paths.
Useful? React with 👍 / 👎.
Code Review by Qodo
1. The core package cannot be consumed
|
| const state = await this.indexer.loadState(); | ||
| if (isStateLoaded(state.snapshot, state.documents)) { | ||
| return this.hydrateState(state.snapshot, state.documents); |
There was a problem hiding this comment.
19. Queries can use stale repository data 📘 Rule violation ≡ Correctness
CodeRag.ensureLoadedState() unconditionally reuses its first in-memory state or hydrates persisted documents and graph data without comparing manifest hashes, repository revision, or the on-disk index with the current repository. When files change or a post-commit hook reindexes in another process, the process-lifetime HTTP service keeps serving the pre-commit state through lookup, query, explain, and impact until an explicit local reindex occurs.
Agent Prompt
## Issue description
CodeRag serves cached repository state without validating it against the live repository or observing indexes rebuilt by another process, causing long-running servers to retain stale documents, vectors, and graph data after repository changes.
## Fix Focus Areas
- packages/CodeRag/src/service/coderag.ts[84-100]
- packages/CodeRag/src/indexer/indexer.ts[108-123]
- packages/CodeRag/src/indexer/git-hook.ts[83-85]
## Recommended Fix
Track a persisted manifest revision, file hashes, or index modification time when loading state, and compare that marker with the live repository and on-disk index before reusing or hydrating cached state. If it differs, reload or reindex the documents, vectors, and graph data; synchronize reloads so queries cannot observe partially loaded state, and replace the cache only after the authoritative read succeeds.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| const answerMode: QueryResult["answerMode"] = | ||
| options.includeAnswer === false || !this.config.llm.enabled || !this.config.llmTransport ? "context-only" : "llm"; |
There was a problem hiding this comment.
20. Retrieval-only mode looks normal 📘 Rule violation ◔ Observability
query() uses the same context-only value for an explicit caller request and for unavailable answer generation, without recording whether or why degradation occurred. When the language model is disabled or no transport exists, the command-line path prints only the fallback answer and no retrieval-only warning.
Agent Prompt
## Issue description
Retrieval-only fallback caused by unavailable answer generation is indistinguishable from an intentionally requested context-only response and has no CLI warning.
## Fix Focus Areas
- packages/CodeRag/src/service/coderag.ts[239-240]
- packages/CodeRag/src/service/coderag.ts[284-291]
- packages/CodeRag/src/cli.ts[181-187]
## Recommended Fix
Add explicit degradation and reason fields for involuntary retrieval-only operation, keep them unset for caller-requested context-only mode, and print a clear retrieval-only degradation banner before CLI fallback output.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| for (const event of events) { | ||
| for (const payload of parseSseEvent(event)) { | ||
| const token = extractAnswerToken(JSON.parse(payload) as Record<string, unknown>); |
There was a problem hiding this comment.
21. Model streams bypass validation 📘 Rule violation ≡ Correctness
readSseResponse() and readNdjsonResponse() cast parsed server payloads to `Record<string, unknown>` rather than validating a supported response schema. Invalid stream frames can therefore be silently ignored or surface raw parsing errors across every streaming language-model transport.
Agent Prompt
## Issue description
Streaming LLM responses are parsed and cast without schema validation or deterministic handling of malformed frames.
## Fix Focus Areas
- packages/CodeRag/src/llm/transports.ts[138-153]
- packages/CodeRag/src/llm/transports.ts[191-203]
## Recommended Fix
Define schemas for supported SSE and NDJSON payload variants, validate every parsed frame before extracting tokens, and convert malformed JSON or invalid shapes into controlled transport errors.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| const data = await response.json() as { message?: { content?: string } }; | ||
| const content = data.message?.content ?? "[]"; | ||
|
|
||
| const jsonMatch = content.match(/```(?:json)?\n?([\s\S]*?)\n?```/)?.[1] ?? content; | ||
| return JSON.parse(jsonMatch) as GhostNode[]; |
There was a problem hiding this comment.
22. Invalid suggestions enter the graph 📘 Rule violation ≡ Correctness
suggestGhostNodes() casts the Ollama response and its embedded JSON directly to GhostNode[] without validating required fields, enums, or relationships. A malformed or adversarial local-model response reaches architecture evolution as trusted graph suggestions.
Agent Prompt
## Issue description
Ollama response data is trusted as graph suggestions without validating its HTTP response shape or generated node array.
## Fix Focus Areas
- packages/codeflow-evolution/src/providers/ollama.ts[36-40]
## Recommended Fix
Create schemas for the Ollama envelope and `GhostNode` array, validate both stages before returning suggestions, and produce a controlled provider error when either payload is invalid.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| constructor(private readonly config: CodeRagConfig, configPath?: string) { | ||
| this.manifestStore = new ManifestStore(config.storageRoot); | ||
| this.indexLock = new IndexLock(config.storageRoot, config.locking, config.logger); | ||
| this.configPath = configPath ?? null; |
There was a problem hiding this comment.
23. Indexing is tied to disk persistence 📘 Rule violation ⌂ Architecture
RepoIndexer constructs ManifestStore and IndexLock directly instead of accepting persistence and locking ports from composition code. Alternative hosts must modify indexing business logic to replace JSON-file storage or filesystem locking.
Agent Prompt
## Issue description
Repository indexing directly constructs concrete filesystem persistence and locking implementations instead of depending on adapter interfaces.
## Fix Focus Areas
- packages/CodeRag/src/indexer/indexer.ts[61-69]
- packages/CodeRag/src/types.ts[428-475]
## Recommended Fix
Define manifest persistence and index-lock interfaces in the ports/types module, inject them into `RepoIndexer`, and move construction of the filesystem implementations to configuration or bootstrap wiring.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| import { NextResponse } from "next/server"; | ||
|
|
||
| import { detectCycles } from "@/lib/blueprint/cycles"; | ||
| import { blueprintGraphSchema } from "@/lib/blueprint/schema"; |
There was a problem hiding this comment.
15. Analysis api endpoints disappear 🐞 Bug ≡ Correctness
The PR deletes the Next route modules for the cycles and smells endpoints and replaces them only with package-internal handlers. The package does not export or mount those handlers in the application route tree, so Next cannot discover /api/analysis/cycles or /api/analysis/smells.
Agent Prompt
## Issue description
The public analysis routes were removed without replacement route modules that Next can discover.
## Fix Focus Areas
- src/app/api/analysis/cycles/route.ts[1-20]
- src/app/api/analysis/smells/route.ts[1-20]
- packages/codeflow-analysis/src/handlers/cycles.ts[15-29]
- packages/codeflow-analysis/src/handlers/smells.ts[15-29]
## Recommended Fix
Keep thin Next route adapters in the application that delegate to the package handlers, or move the handlers into the active Next app route tree. Exercise both endpoints through application-level route tests.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| "use client"; | ||
|
|
||
| import path from "node:path"; | ||
|
|
There was a problem hiding this comment.
16. The canvas client bundle imports node code 🐞 Bug ≡ Correctness
file-tree.tsx declares itself as a client component but imports node:path to compute the displayed repository name. Browser builds cannot rely on this Node builtin, so rendering the file tree can fail client compilation or bundling.
Agent Prompt
## Issue description
A browser client component imports Node's path module.
## Fix Focus Areas
- packages/codeflow-canvas/src/components/file-tree.tsx[1-4]
- packages/codeflow-canvas/src/components/file-tree.tsx[58-68]
## Recommended Fix
Replace `path.basename` with a small browser-safe pathname splitter, or pass the display name from a server boundary. Ensure the client-component build has no `node:` runtime imports.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| const computedSnapshot: DigitalTwinSnapshot = { | ||
| projectName: session.graph.projectName, | ||
| computedAt: new Date().toISOString(), | ||
| maturity: "preview", | ||
| activeNodeIds: request.nodeIds, | ||
| flows: [], | ||
| observedSpanCount: snapshot.spans.filter(s => s.provenance === "observed").length, | ||
| simulatedSpanCount: snapshot.spans.filter(s => s.provenance === "simulated").length, | ||
| observedFlowCount: 0, | ||
| simulatedFlowCount: 1, | ||
| activeWindowSecs: 60 |
There was a problem hiding this comment.
17. Digital twin simulations report no flows 🐞 Bug ≡ Correctness
simulateAction() creates spans but hard-codes both the snapshot and returned flow arrays to empty values. The generated spans share a trace ID and buildUserFlows() groups them into flows, so successful simulations incorrectly report zero flows.
Agent Prompt
## Issue description
Simulation responses discard flows that can be derived from their generated trace spans.
## Fix Focus Areas
- packages/codeflow-dtwin/src/api/simulate/route.ts[50-68]
- packages/codeflow-dtwin/src/digital-twin.ts[76-87]
- packages/codeflow-dtwin/src/digital-twin.ts[197-205]
## Recommended Fix
Build flows from the generated spans, preferably by using the package's snapshot computation helper, and return the same computed flows in both the snapshot and response. Add a simulation test that expects a non-empty flow for valid node IDs.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| if (request.method === "initialize") { | ||
| const response = await handleJsonRpc(request); | ||
| process.stdout.write(JSON.stringify(response) + "\n"); | ||
| // Send notification that we're ready | ||
| process.stdout.write(JSON.stringify(jsonRpcResult(null, {})) + "\n"); | ||
| continue; |
There was a problem hiding this comment.
18. Mcp initialization sends an invalid response 🐞 Bug ≡ Correctness
startStdioServer() writes the proper initialization response and then writes `jsonRpcResult(null,
{})` as a second message. That helper creates a JSON-RPC response object rather than a notification,
so MCP clients receive an unsolicited response with no matching request ID.
Agent Prompt
## Issue description
The stdio MCP server emits an extra JSON-RPC response after initialization.
## Fix Focus Areas
- packages/codeflow-mcp/src/invoke/index.ts[149-154]
- packages/codeflow-mcp/src/invoke/index.ts[75-77]
## Recommended Fix
Write only the response returned for the `initialize` request, and emit a protocol-valid notification only when one is required by MCP. Add a protocol test asserting exactly one response per request.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| let request: JsonRpcRequest; | ||
| try { | ||
| request = JSON.parse(body); | ||
| } catch { | ||
| sendJson(res, { | ||
| jsonrpc: "2.0", | ||
| id: null, | ||
| error: { code: -32700, message: "Parse error" }, | ||
| }); | ||
| return; | ||
| } | ||
|
|
||
| const response = await handleJsonRpc(request); | ||
| sendJson(res, response); |
There was a problem hiding this comment.
36. Malformed mcp requests receive no response 🐞 Bug ☼ Reliability
The HTTP route passes any JSON value directly to handleJsonRpc(), which immediately destructures its request argument. A valid body containing null therefore throws before an error response is formed, leaving the request to fail outside the route's protocol error handling.
Agent Prompt
## Issue description
A syntactically valid but non-object HTTP JSON body can throw before producing a JSON-RPC error.
## Fix Focus Areas
- packages/codeflow-mcp/src/invoke/index.ts[81-82]
- packages/codeflow-mcp/src/invoke/index.ts[268-281]
## Recommended Fix
Validate that parsed JSON is a non-null request object before dispatching, and wrap dispatch in a route-level error handler that returns a JSON-RPC invalid-request response. Add tests for `null`, arrays, and malformed request objects.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Original task: task_1780281408931_95sihyp7i
PR branch: claude-lane/task_1780281408931_95sihyp7i-20260602150330
CI failure: merge-conflict
Strategy: rebase
Hint: PR has merge conflicts with main. Run: git fetch origin && git rebase origin/main && git push --force-with-lease. The watcher's open_pr_for_task will detect the existing PR.
Failure log (last 3000 chars)
Workflow
git log origin/main..claude-lane/task_1780281408931_95sihyp7i-20260602150330)claude-lane/task_1780281408931_95sihyp7i-20260602150330) — the worktree is already set up by the dispatcherfix(ci): <one-line summary>(single line)Automated by DevPulse dispatcher.