Repository navigation
SDK atomic structured mutations, lean output, and agent-first envelopes - #624
Conversation
Deliver SDK-backed atomic JSON mutation batches across CLI and MCP, whole-item stdin round trips, lean structured projections, actionable errors, and compact mutation defaults. Export public runtime primitives, update contracts/docs/token budgets, preserve compatibility, and add comprehensive unit/integration coverage plus PM evidence and generated changelog.
There was a problem hiding this comment.
Sorry @unbraind, your pull request is larger than the review limit of 150000 diff characters
|
@greptileai please review the full current head, including the shared SDK control validation and structured CLI/MCP parity. |
|
@coderabbitai full review |
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 59 minutes. |
📝 WalkthroughWalkthroughThis PR adds lean JSON/error output, compact mutation envelopes, full-item stdin JSON for create/update, atomic heterogeneous mutation batches across CLI and MCP, shared SDK parsing/runtime exports, updated contracts and documentation, and extensive unit/integration coverage. ChangesLean output and mutation projections
Structured mutation workflows
Contracts, docs, and validation
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant CLI_or_MCP
participant StructuredMutations
participant CommitItemMutations
Client->>CLI_or_MCP: Submit transaction ID and mutation JSON
CLI_or_MCP->>StructuredMutations: Validate rows and atomic controls
StructuredMutations-->>CLI_or_MCP: Normalized mutations
CLI_or_MCP->>CommitItemMutations: Commit or preview batch
CommitItemMutations-->>CLI_or_MCP: Mutation result
CLI_or_MCP-->>Client: Compact result with mutation count
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
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 |
Merging this PR will degrade performance by 0.03%
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing |
There was a problem hiding this comment.
Code Review
This pull request introduces several significant features to the CLI, including a lean JSON output mode for reduced token usage, support for atomic batch mutations via pm item mutate, and stdin-based item creation/updates. It also includes error handling improvements with a lean error projection mode and various internal refactorings for better command registration and output formatting. My feedback focuses on a potential vulnerability in numeric input parsing where empty strings could be incorrectly coerced to zero.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Greptile SummaryThis PR adds structured mutation workflows and leaner machine-readable output across the CLI, MCP server, and SDK. The main changes are:
Confidence Score: 5/5This PR appears safe to merge based on the reviewed changed paths. The key mutation, MCP, output, parsing, and error-runtime paths use shared validation and targeted tests. The previously reported active-extension and lock-control issues are addressed in the current changes. No new verified functional bugs were found. No files require special attention.
What T-Rex did
Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Agent as CLI/MCP agent
participant Adapter as pm item mutate / pm_mutate
participant Parser as structured-mutations SDK
participant Extensions as Active extension scope
participant Tx as commitItemMutations
participant Store as pm workspace/history
Agent->>Adapter: JSON mutation batch + transaction id
Adapter->>Parser: parse/validate rows and controls
alt dry run
Parser-->>Adapter: normalized mutations
Adapter-->>Agent: dry_run preview envelope
else commit
Adapter->>Extensions: activate extension context
Extensions->>Tx: commit create/update/close steps
Tx->>Store: journal, apply steps, compensate on failure
Store-->>Tx: committed transaction result
Tx-->>Adapter: status, recovered, results
Adapter-->>Agent: compact structured envelope
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Agent as CLI/MCP agent
participant Adapter as pm item mutate / pm_mutate
participant Parser as structured-mutations SDK
participant Extensions as Active extension scope
participant Tx as commitItemMutations
participant Store as pm workspace/history
Agent->>Adapter: JSON mutation batch + transaction id
Adapter->>Parser: parse/validate rows and controls
alt dry run
Parser-->>Adapter: normalized mutations
Adapter-->>Agent: dry_run preview envelope
else commit
Adapter->>Extensions: activate extension context
Extensions->>Tx: commit create/update/close steps
Tx->>Store: journal, apply steps, compensate on failure
Store-->>Tx: committed transaction result
Tx-->>Adapter: status, recovered, results
Adapter-->>Agent: compact structured envelope
end
Reviews (8): Last reviewed commit: "fix(sdk): harden structured mutation ext..." | Re-trigger Greptile |
Greptile SummaryThis PR makes structured item mutations and lean output first-class across the SDK, CLI, and MCP surfaces. The main changes are:
Confidence Score: 5/5Safe to merge based on the reviewed changed paths. No verified functional, security, or contract-breaking issues were found in the structured mutation parser, CLI/MCP adapters, output projection, lean error handling, or supporting tests. No files require special attention.
What T-Rex did
Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Agent as Agent/CLI user
participant CLI as pm item mutate / pm create-update
participant MCP as pm_mutate tool
participant Parser as structured-mutations SDK
participant Tx as commitItemMutations
participant Store as pm workspace store
Agent->>CLI: JSON stdin batch or item document
CLI->>Parser: parseItemMutationBatch / itemDocumentToMutationOptions
Agent->>MCP: pm_mutate(transactionId, mutations)
MCP->>Parser: validateItemMutationRows + parse controls
Parser-->>CLI: normalized mutations/options
Parser-->>MCP: normalized mutations/options
CLI->>Tx: commitItemMutations(pmRoot, transactionId, author, mutations)
MCP->>Tx: commitItemMutations(pmRoot, transactionId, author, mutations)
Tx->>Store: apply create/update/close steps under transaction lock
Store-->>Tx: committed results or compensation outcome
Tx-->>CLI: transaction result + mutation_count
Tx-->>MCP: transaction result + mutation_count
CLI-->>Agent: compact/full/id-only/lean output envelope
MCP-->>Agent: structured mutation result
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Agent as Agent/CLI user
participant CLI as pm item mutate / pm create-update
participant MCP as pm_mutate tool
participant Parser as structured-mutations SDK
participant Tx as commitItemMutations
participant Store as pm workspace store
Agent->>CLI: JSON stdin batch or item document
CLI->>Parser: parseItemMutationBatch / itemDocumentToMutationOptions
Agent->>MCP: pm_mutate(transactionId, mutations)
MCP->>Parser: validateItemMutationRows + parse controls
Parser-->>CLI: normalized mutations/options
Parser-->>MCP: normalized mutations/options
CLI->>Tx: commitItemMutations(pmRoot, transactionId, author, mutations)
MCP->>Tx: commitItemMutations(pmRoot, transactionId, author, mutations)
Tx->>Store: apply create/update/close steps under transaction lock
Store-->>Tx: committed results or compensation outcome
Tx-->>CLI: transaction result + mutation_count
Tx-->>MCP: transaction result + mutation_count
CLI-->>Agent: compact/full/id-only/lean output envelope
MCP-->>Agent: structured mutation result
Reviews (2): Last reviewed commit: "feat(sdk): add atomic structured mutatio..." | Re-trigger Greptile |
Update the Claude plugin inventory and documentation for the 30-tool MCP surface, including pm_mutate and pm_graph. Keep executable smoke code compatible with the repository's static import policy and record final pm-xm7c CI evidence and closeout state.
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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 `@src/cli/register-mutation.ts`:
- Around line 781-787: Update the stdin handling around
runCreateAction/runUpdateAction and the --stdin-json branch to prevent mixing
--stdin-json with any other stdin-based options, including --body, --dep,
--comment, --note, --learning, --file, --test, --doc, --reminder, --event,
--type-option, and --field. Reject the invocation with a clear error when more
than one stdin mode is requested, or reuse a single resolver throughout the full
command so stdin is consumed exactly once.
In `@src/core/output/mutation-projection.ts`:
- Around line 113-134: Update projectCompactMutationEnvelope to validate that
result.item.id is a string before constructing the compact envelope; return null
when it is missing or non-string so normal projection can handle the result,
matching projectIdOnlyResult’s guard.
In `@src/mcp/server.ts`:
- Around line 170-198: Normalize the committed response in pm_mutate to expose
the transaction identifier as transaction_id, matching the dry-run response and
the envelope’s snake_case convention. Map or remove the transactionId field from
commitItemMutations without changing the existing mutation_count or other result
fields.
In `@src/sdk/cli-bootstrap.ts`:
- Line 167: Update the CLI argument parsing around the existing --json and
--quiet handling in the while loop: introduce a local lean flag, set it only
when --lean is encountered before the -- separator, and use that parsed flag
instead of argv.includes("--lean") for the lean option.
🪄 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: 979e8215-cf47-4a8e-ae45-5942be5ee2f7
📒 Files selected for processing (60)
.agents/pm/extensions/.managed-extensions.json.agents/pm/features/pm-cfed.toon.agents/pm/features/pm-g9xk.toon.agents/pm/features/pm-kipd.toon.agents/pm/features/pm-nilh.toon.agents/pm/features/pm-xm7c.toon.agents/pm/history/pm-cfed.jsonl.agents/pm/history/pm-ds3b.jsonl.agents/pm/history/pm-g9xk.jsonl.agents/pm/history/pm-kipd.jsonl.agents/pm/history/pm-mfkv92.jsonl.agents/pm/history/pm-nilh.jsonl.agents/pm/history/pm-xm7c.jsonl.agents/pm/issues/pm-mfkv92.toon.agents/pm/tasks/pm-ds3b.toonCHANGELOG.mddocs/COMMANDS.mddocs/SDK.mdscripts/release/token-budget-gate.mjsscripts/release/token-budgets.jsonsrc/cli/commander-usage.tssrc/cli/commands/contracts.tssrc/cli/error-guidance.tssrc/cli/main.tssrc/cli/register-mutation.tssrc/cli/register-structured-mutation.tssrc/cli/registration-helpers.tssrc/core/output/mutation-projection.tssrc/core/output/output.tssrc/core/shared/command-types.tssrc/mcp/server.tssrc/mcp/tool-definitions.tssrc/sdk/cli-bootstrap.tssrc/sdk/cli-contracts.tssrc/sdk/cli-contracts/enum-contracts.tssrc/sdk/cli-contracts/flag-contracts.tssrc/sdk/cli-program.tssrc/sdk/error-runtime.tssrc/sdk/index.tssrc/sdk/runtime-primitives.tssrc/sdk/structured-mutations.tstests/fixtures/contracts/full.jsontests/helpers/mcp-context-depth.tstests/helpers/withTempPmPath.tstests/integration/extension-startup.integration.spec.tstests/integration/governance-presets.integration.spec.tstests/integration/help-runtime.spec.tstests/integration/mcp-handshake.spec.tstests/integration/structured-mutation-io.integration.spec.tstests/integration/telemetry-otel-nonblocking.spec.tstests/unit/cli/bootstrap-args.spec.tstests/unit/cli/cli-main-errors.spec.tstests/unit/cli/error-handler-projection.spec.tstests/unit/cli/registration-helpers.spec.tstests/unit/cli/structured-mutation-registration.spec.tstests/unit/commands/completion-command.spec.tstests/unit/core/output/mutation-projection.spec.tstests/unit/core/output/output.spec.tstests/unit/scripts/release/token-budget-gate.spec.tstests/unit/sdk/structured-mutations.spec.ts
Encode structured item facet values as JSON strings and decode them through the shared CSV parser while retaining legacy permissive behavior. Add coverage for multiline annotations, embedded quotes, backslashes, and the fallback path, then record the Greptile disposition and final tracker closeout.
|
@greptileai please review the full current head after the CI contract and lossless multiline structured-facet fixes. |
|
@coderabbitai full review |
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 19 minutes. |
Regenerate the pm-changelog 2026.7.18 output after the concurrent v2026.7.20 tag publication and record the CI root cause in pm-xm7c.
Keep JSON tag arrays intact through stdin-json round trips, including tags containing commas, while retaining legacy CSV parsing. Normalize atomic batch identifiers and close reasons and record exact 100% coverage evidence.
|
@greptileai please review the full current head after preserving structured tag-array identities and syncing the v2026.7.20 release window. The compact mutation envelope remains the intentional GH-437 behavior with --full-changed-fields compatibility. |
|
@coderabbitai full review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/core/output/mutation-projection.ts (1)
113-134: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winGuard
result.item.idtype like the siblingprojectIdOnlyResult.
projectIdOnlyResultexplicitly checkstypeof subject.id === "string"and returnsnull(falling back to normal projection) otherwise.projectCompactMutationEnvelopeskips that check and assignsid: result.item.idunconditionally — ifidis ever missing or non-string, the compact envelope silently drops theidkey entirely (sinceJSON.stringifyomitsundefined), rather than falling back gracefully.🩹 Proposed fix
function projectCompactMutationEnvelope(result: unknown): unknown | null { if (!isPlainObject(result) || !isPlainObject(result.item)) return null; const changedFields = result[CHANGED_FIELDS_KEY]; if (!Array.isArray(changedFields)) return null; + if (typeof result.item.id !== "string") return null; const compact: Record<string, unknown> = { id: result.item.id,🤖 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 `@src/core/output/mutation-projection.ts` around lines 113 - 134, Update projectCompactMutationEnvelope to validate result.item.id is a string before constructing the compact envelope, returning null when it is missing or has another type. Preserve the existing normal-projection fallback and leave the remaining compact-field handling unchanged.
🤖 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 `@docs/COMMANDS.md`:
- Line 418: Update the acceptance-criteria documentation to avoid a space inside
the inline code span `;`. Preserve the meaning that criteria are joined by a
semicolon followed by a space, using prose outside the code span.
---
Duplicate comments:
In `@src/core/output/mutation-projection.ts`:
- Around line 113-134: Update projectCompactMutationEnvelope to validate
result.item.id is a string before constructing the compact envelope, returning
null when it is missing or has another type. Preserve the existing
normal-projection fallback and leave the remaining compact-field handling
unchanged.
🪄 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: 4633cc2d-f641-4b49-8588-b9cdf8182160
📒 Files selected for processing (66)
.agents/pm/extensions/.managed-extensions.json.agents/pm/features/pm-cfed.toon.agents/pm/features/pm-g9xk.toon.agents/pm/features/pm-kipd.toon.agents/pm/features/pm-nilh.toon.agents/pm/features/pm-xm7c.toon.agents/pm/history/pm-cfed.jsonl.agents/pm/history/pm-ds3b.jsonl.agents/pm/history/pm-g9xk.jsonl.agents/pm/history/pm-kipd.jsonl.agents/pm/history/pm-mfkv92.jsonl.agents/pm/history/pm-nilh.jsonl.agents/pm/history/pm-xm7c.jsonl.agents/pm/issues/pm-mfkv92.toon.agents/pm/tasks/pm-ds3b.toonCHANGELOG.mddocs/COMMANDS.mddocs/SDK.mdplugins/pm-claude/README.mdplugins/pm-claude/commands/pm-init.mdscripts/release/token-budget-gate.mjsscripts/release/token-budgets.jsonscripts/smoke-claude-plugin.mjssrc/cli/commander-usage.tssrc/cli/commands/contracts.tssrc/cli/error-guidance.tssrc/cli/main.tssrc/cli/register-mutation.tssrc/cli/register-structured-mutation.tssrc/cli/registration-helpers.tssrc/core/item/parse.tssrc/core/output/mutation-projection.tssrc/core/output/output.tssrc/core/shared/command-types.tssrc/mcp/server.tssrc/mcp/tool-definitions.tssrc/sdk/cli-bootstrap.tssrc/sdk/cli-contracts.tssrc/sdk/cli-contracts/enum-contracts.tssrc/sdk/cli-contracts/flag-contracts.tssrc/sdk/cli-program.tssrc/sdk/error-runtime.tssrc/sdk/index.tssrc/sdk/runtime-primitives.tssrc/sdk/structured-mutations.tstests/fixtures/contracts/full.jsontests/helpers/mcp-context-depth.tstests/helpers/withTempPmPath.tstests/integration/extension-startup.integration.spec.tstests/integration/governance-presets.integration.spec.tstests/integration/help-runtime.spec.tstests/integration/mcp-handshake.spec.tstests/integration/structured-mutation-io.integration.spec.tstests/integration/telemetry-otel-nonblocking.spec.tstests/unit/cli/bootstrap-args.spec.tstests/unit/cli/cli-main-errors.spec.tstests/unit/cli/error-handler-projection.spec.tstests/unit/cli/registration-helpers.spec.tstests/unit/cli/structured-mutation-registration.spec.tstests/unit/commands/completion-command.spec.tstests/unit/core/item/parse-utils.spec.tstests/unit/core/output/mutation-projection.spec.tstests/unit/core/output/output.spec.tstests/unit/scripts/release/token-budget-gate.spec.tstests/unit/scripts/smoke-claude-plugin.spec.tstests/unit/sdk/structured-mutations.spec.ts
Resolve the final exact-head review bundle across SDK, CLI, and MCP structured mutation surfaces. Add a public serialized and reentrant extension activation scope, normalize MCP transaction envelopes, enforce positive safe integer lock controls, reject competing stdin consumers, preserve the global flag sentinel boundary, and harden compact projections. Cover every path at exact 100/100/100/100 and record the completed pm lineage.
|
@greptileai please review the latest exact head 9838309. All prior findings were addressed and local Greptile reports 5/5 safe to merge with no comments. |
|
@coderabbitai full review please. Review the latest exact head 9838309; all prior inline findings have been implemented and exact local coverage is 100/100/100/100. |
|
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 8 minutes. |
|
Final bot-comment dispositions on exact head 9838309:
Every bot issue comment and every inline finding has now received an explicit reaction and disposition. |
Summary
This wide SDK/CLI platform change makes structured, token-efficient project mutations a first-class primitive across CLI and MCP:
pm item mutateandpm_mutate, including dry-run, idempotent resume, compensation, and shared transport validationpm createandpm update, with explicit-flag precedence, facet safety, persisted-annotation deduplication, and custom-field extensibilityPM items
Verification
pm-changelog(2026.7.18) generatedCHANGELOG.md; reproducibility check passesnpxsmoke passes; installed SDK import and isolated CLI/MCP mutation workflows pass in a temporary workspaceSummary by cubic
Ships SDK-backed atomic structured mutations across CLI and MCP, makes compact mutation envelopes the default, and adds lean JSON/error modes to cut tokens. Also hardens runtime with a serialized, reentrant extension-activation scope and stricter input validation.
New Features
pm item mutateconsumes a JSON batch on stdin and applies create|update|close atomically with --dry-run, --transaction-id, compensation (close|delete), and lock controls; shared validation, idempotent resume, and exclusive stdin guarding. (Make lean mutation output the CLI default (match the MCP server) #437, pm-xm7c)pm_mutatemirrors the contract, normalizes envelopes, and runs inside the active extension scope; Claude plugin updated to 30 tools (incl.pm_mutate,pm_graph).pm create --stdin-jsonandpm update <id> --stdin-jsonaccept a full item doc; flags win; unknown keys get did-you-mean; JSON tag arrays are preserved (including commas); structured facets keep multiline/quoted values. (Accept a full item as a JSON document on stdin forpm create/pm update#438)--leandrops nulls/empty containers and trims constant error prose; commander usage JSON supports lean projection. (Add a lean JSON output mode that omits null/empty fields (≈50% token cut for --json) #435, Add a lean error mode that drops generic boilerplate #443)structured-mutations,runtime-primitives,error-runtime, andrunWithActiveExtensionsfor parsing batches, stdin resolution, author/root resolution, consistent error handling, and serialized extension activation.Migration
changed_fieldsmust pass--fullor--full-changed-fields, or readidfrom the compact result.--leanfor errors; lean error envelopes only apply when you opt in with--lean.Written for commit 9838309. Summary will update on new commits.