@documentation-robotics/cli 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -16
- package/dist/analysis/relationship-classifier.js +2 -9
- package/dist/analysis/relationship-classifier.js.map +2 -2
- package/dist/analyzers/active-analyzer.js +62 -0
- package/dist/analyzers/active-analyzer.js.map +7 -0
- package/dist/analyzers/call-graph-utils.js +2 -2
- package/dist/analyzers/call-graph-utils.js.map +2 -2
- package/dist/analyzers/cards/build.js +191 -0
- package/dist/analyzers/cards/build.js.map +7 -0
- package/dist/analyzers/cards/classify.js +42 -0
- package/dist/analyzers/cards/classify.js.map +7 -0
- package/dist/analyzers/cards/edge-index.js +44 -0
- package/dist/analyzers/cards/edge-index.js.map +7 -0
- package/dist/analyzers/cards/extract.js +138 -0
- package/dist/analyzers/cards/extract.js.map +7 -0
- package/dist/analyzers/cards/facts.js +46 -0
- package/dist/analyzers/cards/facts.js.map +7 -0
- package/dist/analyzers/cards/graph.js +42 -0
- package/dist/analyzers/cards/graph.js.map +7 -0
- package/dist/analyzers/cards/index.js +8 -0
- package/dist/analyzers/cards/index.js.map +7 -0
- package/dist/analyzers/cards/routes.js +96 -0
- package/dist/analyzers/cards/routes.js.map +7 -0
- package/dist/analyzers/cards/tier0.js +18 -0
- package/dist/analyzers/cards/tier0.js.map +7 -0
- package/dist/analyzers/cards/types.js +1 -0
- package/dist/analyzers/cards/types.js.map +7 -0
- package/dist/analyzers/cbm-analyzer.js +270 -174
- package/dist/analyzers/cbm-analyzer.js.map +2 -2
- package/dist/analyzers/cbm-responses.js +342 -0
- package/dist/analyzers/cbm-responses.js.map +7 -0
- package/dist/analyzers/code-changes.js +159 -0
- package/dist/analyzers/code-changes.js.map +7 -0
- package/dist/analyzers/edge-relationships.js +49 -0
- package/dist/analyzers/edge-relationships.js.map +7 -0
- package/dist/analyzers/extraction-plan.js +541 -0
- package/dist/analyzers/extraction-plan.js.map +7 -0
- package/dist/analyzers/index-job.js +229 -0
- package/dist/analyzers/index-job.js.map +7 -0
- package/dist/analyzers/mapping-loader.js +9 -0
- package/dist/analyzers/mapping-loader.js.map +2 -2
- package/dist/analyzers/tier0-rules.js +153 -0
- package/dist/analyzers/tier0-rules.js.map +7 -0
- package/dist/analyzers/types.js.map +1 -1
- package/dist/audit/relationships/ai/prompts.js +10 -10
- package/dist/audit/relationships/ai/prompts.js.map +2 -2
- package/dist/audit/relationships/analysis/layer-templates.js +52 -52
- package/dist/audit/relationships/analysis/layer-templates.js.map +1 -1
- package/dist/cli.js +23 -11
- package/dist/cli.js.map +2 -2
- package/dist/coding-agents/default-permissions.js +31 -1
- package/dist/coding-agents/default-permissions.js.map +2 -2
- package/dist/coding-agents/drbot-mcp.js +269 -0
- package/dist/coding-agents/drbot-mcp.js.map +7 -0
- package/dist/commands/add.js +7 -4
- package/dist/commands/add.js.map +2 -2
- package/dist/commands/analyzer.js +143 -40
- package/dist/commands/analyzer.js.map +2 -2
- package/dist/commands/changeset-verify.js +63 -0
- package/dist/commands/changeset-verify.js.map +7 -0
- package/dist/commands/changeset.js +80 -29
- package/dist/commands/changeset.js.map +2 -2
- package/dist/commands/delete.js +10 -4
- package/dist/commands/delete.js.map +2 -2
- package/dist/commands/farm.js +176 -60
- package/dist/commands/farm.js.map +2 -2
- package/dist/commands/init.js +9 -26
- package/dist/commands/init.js.map +2 -2
- package/dist/commands/mcp.js +40 -21
- package/dist/commands/mcp.js.map +3 -3
- package/dist/commands/relationship.js +208 -37
- package/dist/commands/relationship.js.map +2 -2
- package/dist/commands/reports.js +3 -3
- package/dist/commands/reports.js.map +2 -2
- package/dist/commands/update.js +52 -32
- package/dist/commands/update.js.map +2 -2
- package/dist/commands/upgrade.js +99 -103
- package/dist/commands/upgrade.js.map +3 -3
- package/dist/commands/validate.js +19 -3
- package/dist/commands/validate.js.map +2 -2
- package/dist/commands/version.js +1 -1
- package/dist/commands/visualize.js +34 -15
- package/dist/commands/visualize.js.map +2 -2
- package/dist/core/annotation-store.js +15 -5
- package/dist/core/annotation-store.js.map +2 -2
- package/dist/core/catalog-migration.js +34 -0
- package/dist/core/catalog-migration.js.map +7 -0
- package/dist/core/changeset-analysis.js +421 -0
- package/dist/core/changeset-analysis.js.map +7 -0
- package/dist/core/changeset-base-index.js +160 -0
- package/dist/core/changeset-base-index.js.map +7 -0
- package/dist/core/changeset-brief-compact.js +256 -0
- package/dist/core/changeset-brief-compact.js.map +7 -0
- package/dist/core/changeset-brief-delta.js +102 -0
- package/dist/core/changeset-brief-delta.js.map +7 -0
- package/dist/core/changeset-graph.js +281 -0
- package/dist/core/changeset-graph.js.map +7 -0
- package/dist/core/changeset-only-guard.js +32 -0
- package/dist/core/changeset-only-guard.js.map +7 -0
- package/dist/core/changeset-summary.js +68 -0
- package/dist/core/changeset-summary.js.map +7 -0
- package/dist/core/changeset-validator.js +66 -20
- package/dist/core/changeset-validator.js.map +2 -2
- package/dist/core/changeset-verify.js +848 -0
- package/dist/core/changeset-verify.js.map +7 -0
- package/dist/core/changeset.js +56 -9
- package/dist/core/changeset.js.map +2 -2
- package/dist/core/element-type-migration.js +145 -0
- package/dist/core/element-type-migration.js.map +7 -0
- package/dist/core/extraction-observability.js +161 -0
- package/dist/core/extraction-observability.js.map +7 -0
- package/dist/core/farm-manifest.js +12 -6
- package/dist/core/farm-manifest.js.map +2 -2
- package/dist/core/farm-sync-engine.js +1 -1
- package/dist/core/farm-sync-engine.js.map +2 -2
- package/dist/core/farm-sync-state.js +10 -2
- package/dist/core/farm-sync-state.js.map +2 -2
- package/dist/core/migration-registry.js +88 -47
- package/dist/core/migration-registry.js.map +2 -2
- package/dist/core/model-upgrade.js +102 -0
- package/dist/core/model-upgrade.js.map +7 -0
- package/dist/core/model.js +82 -30
- package/dist/core/model.js.map +2 -2
- package/dist/core/mutation-handler.js +71 -6
- package/dist/core/mutation-handler.js.map +2 -2
- package/dist/core/project-init.js +53 -0
- package/dist/core/project-init.js.map +7 -0
- package/dist/core/relationship-migration-table.js +6639 -0
- package/dist/core/relationship-migration-table.js.map +7 -0
- package/dist/core/relationship-migration.js +272 -0
- package/dist/core/relationship-migration.js.map +7 -0
- package/dist/core/relationship-prune.js +49 -0
- package/dist/core/relationship-prune.js.map +7 -0
- package/dist/core/relationship-staging.js +161 -0
- package/dist/core/relationship-staging.js.map +7 -0
- package/dist/core/relationships.js +26 -4
- package/dist/core/relationships.js.map +2 -2
- package/dist/core/report-data-model.js +7 -13
- package/dist/core/report-data-model.js.map +2 -2
- package/dist/core/staged-changeset-storage.js +145 -18
- package/dist/core/staged-changeset-storage.js.map +2 -2
- package/dist/core/staged-source-reference.js +28 -0
- package/dist/core/staged-source-reference.js.map +7 -0
- package/dist/core/staging-area.js +166 -24
- package/dist/core/staging-area.js.map +2 -2
- package/dist/core/upgrade-plan.js +117 -0
- package/dist/core/upgrade-plan.js.map +7 -0
- package/dist/core/virtual-projection.js +13 -5
- package/dist/core/virtual-projection.js.map +2 -2
- package/dist/export/archimate-exporter.js +1 -0
- package/dist/export/archimate-exporter.js.map +2 -2
- package/dist/generated/compiled-validators.js +2 -2
- package/dist/generated/compiled-validators.js.map +2 -2
- package/dist/generated/layer-registry.js +16 -16
- package/dist/generated/layer-registry.js.map +2 -2
- package/dist/generated/node-types.js +186 -168
- package/dist/generated/node-types.js.map +2 -2
- package/dist/generated/relationship-index.js +2468 -7913
- package/dist/generated/relationship-index.js.map +2 -2
- package/dist/integrations/claude_code/.claude-plugin/plugin.json +24 -0
- package/dist/integrations/claude_code/agents/dr-architect.md +30 -3
- package/dist/integrations/claude_code/agents/dr-extractor.md +8 -2
- package/dist/integrations/claude_code/commands/dr-analyzer.md +565 -0
- package/dist/integrations/claude_code/commands/dr-changeset.md +2 -1
- package/dist/integrations/claude_code/commands/dr-map.md +20 -1
- package/dist/integrations/claude_code/commands/dr-plan.md +66 -0
- package/dist/integrations/claude_code/commands/dr-relate.md +106 -96
- package/dist/integrations/claude_code/commands/dr-verify.md +45 -2
- package/dist/integrations/claude_code/docs/END_TO_END_WALKTHROUGH.md +14 -0
- package/dist/integrations/claude_code/docs/MCP_SERVER.md +47 -26
- package/dist/integrations/claude_code/docs/QUICK_START.md +37 -8
- package/dist/integrations/claude_code/docs/README.md +68 -2
- package/dist/integrations/claude_code/plugin-agents/dr-advisor.md +255 -0
- package/dist/integrations/claude_code/plugin-agents/dr-architect.md +306 -0
- package/dist/integrations/claude_code/skills/dr_01_motivation_layer/SKILL.md +93 -72
- package/dist/integrations/claude_code/skills/dr_02_business_layer/SKILL.md +163 -126
- package/dist/integrations/claude_code/skills/dr_03_product_layer/SKILL.md +161 -126
- package/dist/integrations/claude_code/skills/dr_04_security_layer/SKILL.md +153 -133
- package/dist/integrations/claude_code/skills/dr_05_application_layer/SKILL.md +129 -100
- package/dist/integrations/claude_code/skills/dr_06_technology_layer/SKILL.md +111 -94
- package/dist/integrations/claude_code/skills/dr_07_api_layer/SKILL.md +143 -157
- package/dist/integrations/claude_code/skills/dr_08_data_model_layer/SKILL.md +117 -33
- package/dist/integrations/claude_code/skills/dr_09_dataset_layer/SKILL.md +74 -25
- package/dist/integrations/claude_code/skills/dr_10_ux_layer/SKILL.md +88 -12
- package/dist/integrations/claude_code/skills/dr_11_navigation_layer/SKILL.md +83 -24
- package/dist/integrations/claude_code/skills/dr_12_apm_layer/SKILL.md +57 -12
- package/dist/integrations/claude_code/skills/dr_13_testing_layer/SKILL.md +95 -15
- package/dist/integrations/claude_code/skills/dr_change_planning/SKILL.md +178 -0
- package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +8 -0
- package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +6 -1
- package/dist/integrations/github_copilot/agents/dr-architect.md +3 -1
- package/dist/integrations/github_copilot/skills/dr_01_motivation_layer/SKILL.md +182 -102
- package/dist/integrations/github_copilot/skills/dr_02_business_layer/SKILL.md +266 -148
- package/dist/integrations/github_copilot/skills/dr_03_product_layer/SKILL.md +547 -86
- package/dist/integrations/github_copilot/skills/dr_04_security_layer/SKILL.md +164 -169
- package/dist/integrations/github_copilot/skills/dr_05_application_layer/SKILL.md +420 -150
- package/dist/integrations/github_copilot/skills/dr_06_technology_layer/SKILL.md +331 -138
- package/dist/integrations/github_copilot/skills/dr_07_api_layer/SKILL.md +265 -201
- package/dist/integrations/github_copilot/skills/dr_08_data_model_layer/SKILL.md +181 -58
- package/dist/integrations/github_copilot/skills/dr_09_dataset_layer/SKILL.md +209 -57
- package/dist/integrations/github_copilot/skills/dr_10_ux_layer/SKILL.md +277 -112
- package/dist/integrations/github_copilot/skills/dr_11_navigation_layer/SKILL.md +219 -70
- package/dist/integrations/github_copilot/skills/dr_12_apm_layer/SKILL.md +189 -105
- package/dist/integrations/github_copilot/skills/dr_13_testing_layer/SKILL.md +225 -102
- package/dist/integrations/github_copilot/skills/dr_change_planning/SKILL.md +177 -0
- package/dist/integrations/github_copilot/skills/dr_changeset_reviewer/SKILL.md +3 -0
- package/dist/integrations/hash-utils.js.map +2 -2
- package/dist/mcp/api-key-manager.js +14 -1
- package/dist/mcp/api-key-manager.js.map +2 -2
- package/dist/mcp/changeset-only.js +45 -0
- package/dist/mcp/changeset-only.js.map +7 -0
- package/dist/mcp/project-root.js +85 -0
- package/dist/mcp/project-root.js.map +7 -0
- package/dist/mcp/server-instructions.js +27 -0
- package/dist/mcp/server-instructions.js.map +7 -0
- package/dist/mcp/strict-schema.js +52 -0
- package/dist/mcp/strict-schema.js.map +7 -0
- package/dist/mcp/tool-registry.js +55 -5
- package/dist/mcp/tool-registry.js.map +2 -2
- package/dist/mcp/tools/changeset-analysis-tools.js +98 -0
- package/dist/mcp/tools/changeset-analysis-tools.js.map +7 -0
- package/dist/mcp/tools/changeset-commit.js +224 -0
- package/dist/mcp/tools/changeset-commit.js.map +7 -0
- package/dist/mcp/tools/changeset-editing.js +260 -0
- package/dist/mcp/tools/changeset-editing.js.map +7 -0
- package/dist/mcp/tools/changeset-lifecycle.js +83 -0
- package/dist/mcp/tools/changeset-lifecycle.js.map +7 -0
- package/dist/mcp/tools/changeset-shared.js +31 -0
- package/dist/mcp/tools/changeset-shared.js.map +7 -0
- package/dist/mcp/tools/changeset-show.js +17 -1
- package/dist/mcp/tools/changeset-show.js.map +2 -2
- package/dist/mcp/tools/changeset-verify.js +49 -0
- package/dist/mcp/tools/changeset-verify.js.map +7 -0
- package/dist/mcp/tools/codebase-extract.js +836 -0
- package/dist/mcp/tools/codebase-extract.js.map +7 -0
- package/dist/mcp/tools/codebase-index.js +125 -0
- package/dist/mcp/tools/codebase-index.js.map +7 -0
- package/dist/mcp/tools/codebase-shared.js +265 -0
- package/dist/mcp/tools/codebase-shared.js.map +7 -0
- package/dist/mcp/tools/codebase-verify.js +48 -0
- package/dist/mcp/tools/codebase-verify.js.map +7 -0
- package/dist/mcp/tools/index.js +34 -1
- package/dist/mcp/tools/index.js.map +2 -2
- package/dist/mcp/tools/model-add.js +191 -74
- package/dist/mcp/tools/model-add.js.map +2 -2
- package/dist/mcp/tools/model-delete.js +2 -2
- package/dist/mcp/tools/model-delete.js.map +2 -2
- package/dist/mcp/tools/model-search.js +14 -0
- package/dist/mcp/tools/model-search.js.map +2 -2
- package/dist/mcp/tools/model-show.js +29 -2
- package/dist/mcp/tools/model-show.js.map +2 -2
- package/dist/mcp/tools/model-trace.js +93 -30
- package/dist/mcp/tools/model-trace.js.map +2 -2
- package/dist/mcp/tools/model-update.js +46 -26
- package/dist/mcp/tools/model-update.js.map +2 -2
- package/dist/mcp/tools/model-validate.js +46 -4
- package/dist/mcp/tools/model-validate.js.map +2 -2
- package/dist/mcp/tools/project-status-collectors.js +381 -0
- package/dist/mcp/tools/project-status-collectors.js.map +7 -0
- package/dist/mcp/tools/project-status.js +237 -0
- package/dist/mcp/tools/project-status.js.map +7 -0
- package/dist/mcp/tools/project-tools.js +505 -0
- package/dist/mcp/tools/project-tools.js.map +7 -0
- package/dist/mcp/tools/relationship-tools.js +167 -0
- package/dist/mcp/tools/relationship-tools.js.map +7 -0
- package/dist/mcp/tools/review-open.js +210 -0
- package/dist/mcp/tools/review-open.js.map +7 -0
- package/dist/mcp/tools/shared.js +35 -4
- package/dist/mcp/tools/shared.js.map +2 -2
- package/dist/mcp/tools/spec-type.js +90 -0
- package/dist/mcp/tools/spec-type.js.map +7 -0
- package/dist/reports/model-report-orchestrator.js +31 -2
- package/dist/reports/model-report-orchestrator.js.map +2 -2
- package/dist/schemas/bundled/analyzers/cbm.json +1200 -70
- package/dist/schemas/bundled/analyzers/manifest.json +2 -2
- package/dist/schemas/bundled/api.json +1029 -1658
- package/dist/schemas/bundled/apm.json +499 -734
- package/dist/schemas/bundled/application.json +735 -371
- package/dist/schemas/bundled/base.json +3 -220
- package/dist/schemas/bundled/business.json +452 -366
- package/dist/schemas/bundled/data-model.json +395 -411
- package/dist/schemas/bundled/data-store.json +334 -558
- package/dist/schemas/bundled/manifest.json +18 -18
- package/dist/schemas/bundled/motivation.json +349 -368
- package/dist/schemas/bundled/navigation.json +415 -731
- package/dist/schemas/bundled/product.json +325 -159
- package/dist/schemas/bundled/security.json +864 -1232
- package/dist/schemas/bundled/technology.json +574 -703
- package/dist/schemas/bundled/testing.json +865 -1646
- package/dist/schemas/bundled/ux.json +739 -1352
- package/dist/server/schemas.js +8 -0
- package/dist/server/schemas.js.map +2 -2
- package/dist/server/server.js +686 -231
- package/dist/server/server.js.map +3 -3
- package/dist/server/viewer-registry.js +264 -0
- package/dist/server/viewer-registry.js.map +7 -0
- package/dist/server-entry.js +2 -1
- package/dist/server-entry.js.map +2 -2
- package/dist/telemetry/index.js +1 -1
- package/dist/utils/ansi-suppressor.js +6 -8
- package/dist/utils/ansi-suppressor.js.map +2 -2
- package/dist/utils/attribute-patch.js +41 -0
- package/dist/utils/attribute-patch.js.map +7 -0
- package/dist/utils/error-hints.js +29 -0
- package/dist/utils/error-hints.js.map +7 -0
- package/dist/utils/errors.js +9 -3
- package/dist/utils/errors.js.map +2 -2
- package/dist/utils/id-generator.js +5 -2
- package/dist/utils/id-generator.js.map +2 -2
- package/dist/utils/project-paths.js +26 -1
- package/dist/utils/project-paths.js.map +2 -2
- package/dist/utils/source-reference.js +64 -31
- package/dist/utils/source-reference.js.map +2 -2
- package/dist/utils/spec-version.js +2 -2
- package/dist/utils/spec-version.js.map +1 -1
- package/dist/validators/composed-reference-validator.js +5 -27
- package/dist/validators/composed-reference-validator.js.map +2 -2
- package/dist/validators/model-warnings.js +28 -0
- package/dist/validators/model-warnings.js.map +7 -0
- package/dist/validators/reference-validator.js +0 -7
- package/dist/validators/reference-validator.js.map +2 -2
- package/dist/validators/relationship-schema-validator.js +3 -3
- package/dist/validators/relationship-schema-validator.js.map +2 -2
- package/dist/validators/schema-validator.js +27 -9
- package/dist/validators/schema-validator.js.map +2 -2
- package/dist/validators/types.js.map +1 -1
- package/dist/viewer/README.md +6 -6
- package/dist/viewer/assets/main-CUOQGGRA.css +1 -0
- package/dist/viewer/assets/main-DvH3gYrI.js +84 -0
- package/dist/viewer/index.html +2 -2
- package/dist/viewer/manifest.json +10 -10
- package/dist/viewer/version.json +1 -1
- package/package.json +2 -1
- package/dist/viewer/assets/main-B7AOQXXX.js +0 -81
- package/dist/viewer/assets/main-vdrFrG7q.css +0 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/tools/changeset-editing.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * changeset_update, changeset_unstage, changeset_discard \u2014 revise a staged changeset while\n * planning a change. Mirror `dr changeset unstage|discard` and add the rename / re-describe step\n * the CLI has no command for, all through StagingAreaManager.\n *\n * Every mutation reloads the cached model afterwards, like changeset-lifecycle.ts: the model\n * projects the active changeset's elements at load time, and the projection cache is keyed by\n * what is staged.\n *\n * Landing a change is the human's step: changeset_commit (changeset-commit.ts) asks a person to\n * confirm it. Discard is exposed because an agent must be able to abandon its own plan, but it\n * clears the staged changes for good, so it needs `confirm: true`. See docs/CHANGE_MODELING.md.\n */\n\nimport { z } from \"zod\";\nimport { strictItem } from \"../strict-schema.js\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { ChangesetGraph } from \"../../core/changeset-graph.js\";\nimport type { Changeset, StagedChange } from \"../../core/changeset.js\";\nimport { StagingAreaManager } from \"../../core/staging-area.js\";\nimport { stagedRelationshipChangesAtEnds, stagedRelationshipTriple } from \"../../core/relationship-staging.js\";\nimport { CLIError, ErrorCategory, getErrorMessage } from \"../../utils/errors.js\";\nimport { jsonResult, loadModel, reloadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\nimport { resolveChangeset } from \"./changeset-shared.js\";\n\nconst changesetIdSchema = z\n .string()\n .optional()\n .describe(\"Changeset ID or name. Defaults to the active changeset.\");\n\nfunction requireStaged(changeset: Changeset, action: string): void {\n if (changeset.status !== \"staged\") {\n throw new CLIError(`Changeset '${changeset.name}' is ${changeset.status}; cannot ${action}`, ErrorCategory.USER, [\n 'Use \"changeset_list\" to find a staged changeset, or \"changeset_create\" to start a new one',\n ]);\n }\n}\n\n/** Wraps a StagingAreaManager error (plain Error) as a user error the agent can act on. */\nasync function asUserError<T>(fn: () => Promise<T>, suggestions: string[]): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n if (error instanceof CLIError) throw error;\n throw new CLIError(getErrorMessage(error), ErrorCategory.USER, suggestions);\n }\n}\n\nfunction summarize(change: StagedChange): Record<string, unknown> {\n const triple = change.type.startsWith(\"relationship-\") ? stagedRelationshipTriple(change) : null;\n return {\n type: change.type,\n elementId: change.elementId,\n layer: change.layerName,\n ...(triple ? { relationship: triple } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// changeset_update\n// ---------------------------------------------------------------------------\n\nconst updateInputSchema = {\n changesetId: changesetIdSchema,\n name: z.string().min(1).optional().describe(\"New name. Must not be another changeset's name.\"),\n description: z\n .string()\n .optional()\n .describe(\"New description: the change's intent and what done looks like. An empty string clears it.\"),\n rootPath: rootPathSchema,\n};\n\nexport type ChangesetUpdateArgs = z.infer<z.ZodObject<typeof updateInputSchema>>;\n\nexport async function changesetUpdateHandler(args: ChangesetUpdateArgs): Promise<CallToolResult> {\n return runTool(async () => {\n if (args.name === undefined && args.description === undefined) {\n throw new CLIError(\"Nothing to update\", ErrorCategory.USER, ['Pass \"name\" and/or \"description\"']);\n }\n const model = await loadModel(args.rootPath);\n const manager = new StagingAreaManager(model.rootPath, model);\n const changeset = await resolveChangeset(manager, args.changesetId);\n\n const updated = await asUserError(\n () => manager.update(changeset.id!, { name: args.name, description: args.description }),\n ['Use \"changeset_list\" to see the names already taken']\n );\n await reloadModel(args.rootPath);\n\n return jsonResult({\n id: updated.id,\n name: updated.name,\n ...(changeset.name !== updated.name ? { previousName: changeset.name } : {}),\n description: updated.description ?? null,\n status: updated.status,\n changes: updated.changes.length,\n });\n });\n}\n\nexport const changesetUpdateTool: McpToolDefinition<typeof updateInputSchema> = {\n name: \"changeset_update\",\n description:\n \"Rename a changeset or change its description (the change's intent). Staged changes are untouched. \" +\n \"Defaults to the active changeset.\",\n inputSchema: updateInputSchema,\n handler: changesetUpdateHandler,\n};\n\n// ---------------------------------------------------------------------------\n// changeset_unstage\n// ---------------------------------------------------------------------------\n\nconst elementIdField = z\n .string()\n .optional()\n .describe(\"Drop every staged change to this element (its add, updates or delete). ID or path.\");\nconst sourceField = z\n .string()\n .optional()\n .describe(\n \"Drop staged relationship changes (adds and deletes) from this element: to target when given, otherwise to \" +\n \"any element. The element's own changes are not touched.\"\n );\nconst targetField = z\n .string()\n .optional()\n .describe(\n \"Drop staged relationship changes (adds and deletes) to this element: from source when given, otherwise from \" +\n \"any element. The element's own changes are not touched.\"\n );\nconst predicateField = z.string().optional().describe(\"Only relationship changes with this predicate. Omit for any.\");\nconst keepRelationshipsField = z\n .boolean()\n .optional()\n .describe(\n \"With elementId: keep the staged relationship changes that depend on the element's change. By default, \" +\n \"unstaging an element's add also drops staged relationships to it (they would dangle), and unstaging its \" +\n \"delete also drops the relationship removals its cascade staged (removals staged before the delete are kept).\"\n );\n\nconst unstageItemSchema = strictItem(\"A changes[] item\", {\n elementId: elementIdField,\n source: sourceField,\n target: targetField,\n predicate: predicateField,\n keepRelationships: keepRelationshipsField,\n});\n\ntype UnstageSpec = z.infer<typeof unstageItemSchema>;\n\nconst unstageInputSchema = {\n changesetId: changesetIdSchema,\n elementId: elementIdField,\n source: sourceField,\n target: targetField,\n predicate: predicateField,\n keepRelationships: keepRelationshipsField,\n changes: z\n .array(unstageItemSchema)\n .min(1)\n .optional()\n .describe(\n \"Several unstages at once, each {elementId} or {source, predicate?, target} or {source} or {target}, with the \" +\n \"same meaning as the single form. All are removed in one write, with a result per item: unstaged, \" +\n \"already-unstaged (an earlier item took its changes), not-staged, or invalid with the reason. Cannot be \" +\n \"combined with the single-form fields.\"\n ),\n rootPath: rootPathSchema,\n};\n\nexport type ChangesetUnstageArgs = z.infer<z.ZodObject<typeof unstageInputSchema>>;\n\nfunction describeEnds(args: { source?: string; target?: string }): string {\n if (args.source && args.target) return `from ${args.source} to ${args.target}`;\n return args.source ? `from ${args.source}` : `to ${args.target}`;\n}\n\n/** Refuses a spec that names neither or both of an element and a relationship. */\nfunction checkUnstageSpec(spec: UnstageSpec): void {\n const byElement = spec.elementId !== undefined;\n const byRelationship = spec.source !== undefined || spec.target !== undefined;\n if (byElement === byRelationship) {\n throw new CLIError(\"Name either an element or a relationship to unstage\", ErrorCategory.USER, [\n 'Pass \"elementId\" to drop an element\\'s staged changes',\n 'Or pass \"source\" and/or \"target\" (and optionally \"predicate\") to drop staged relationship changes',\n ]);\n }\n if (byRelationship && !spec.source && !spec.target) {\n throw new CLIError('\"source\" or \"target\" must not be empty', ErrorCategory.USER);\n }\n}\n\n/** The change keys one unstage spec selects, and what it kept or should say. */\nfunction selectUnstage(\n spec: UnstageSpec,\n graph: ChangesetGraph,\n changeset: Changeset\n): { keys: Set<string>; notes: string[] } {\n const changes = changeset.changes as StagedChange[];\n const keys = new Set<string>();\n const notes: string[] = [];\n\n if (spec.elementId !== undefined) {\n const element = graph.getElement(spec.elementId);\n const ids = new Set([spec.elementId, ...(element ? [element.id, element.uuid ?? element.id] : [])]);\n const own = changes.filter((c) => !c.type.startsWith(\"relationship-\") && ids.has(c.elementId));\n for (const change of own) keys.add(change.elementId);\n\n // Relationship changes that only make sense with the element's change.\n const dependentType = own.some((c) => c.type === \"add\")\n ? \"relationship-add\"\n : own.some((c) => c.type === \"delete\")\n ? \"relationship-delete\"\n : null;\n const touching = dependentType\n ? changes.filter((c) => {\n if (c.type !== dependentType) return false;\n const triple = stagedRelationshipTriple(c);\n return (\n !!triple &&\n (ids.has(triple.source) ||\n ids.has(triple.target) ||\n (element && (graph.resolve(triple.source) === element.id || graph.resolve(triple.target) === element.id)))\n );\n })\n : [];\n // A delete cascades into relationship removals staged right after it. Removals staged before the\n // delete were the agent's own decisions, not the cascade's, so they stay.\n const seq = (c: StagedChange): number => c.sequenceNumber ?? changes.indexOf(c);\n const deleteSeqs = own.filter((c) => c.type === \"delete\").map(seq);\n const firstDelete = deleteSeqs.length > 0 ? Math.min(...deleteSeqs) : -1;\n const dependent =\n dependentType === \"relationship-delete\" ? touching.filter((c) => seq(c) > firstDelete) : touching;\n const deliberate = touching.filter((c) => !dependent.includes(c));\n if (deliberate.length > 0) {\n notes.push(\n `${deliberate.length} relationship removal(s) on ${spec.elementId} staged before its delete were kept ` +\n `(${deliberate.map((c) => c.elementId).join(\", \")}); unstage them by source and target if they should go too`\n );\n }\n if (dependent.length > 0) {\n if (spec.keepRelationships) {\n notes.push(\n `${dependent.length} staged relationship change(s) on ${spec.elementId} were kept (keepRelationships)` +\n (dependentType === \"relationship-add\" ? \"; they will dangle unless the element is staged again\" : \"\")\n );\n } else {\n for (const change of dependent) keys.add(change.elementId);\n }\n }\n return { keys, notes };\n }\n\n const matched = stagedRelationshipChangesAtEnds(graph, changeset, {\n source: spec.source || undefined,\n target: spec.target || undefined,\n predicate: spec.predicate,\n });\n // A relationship removal staged after the delete of one of its ends is that delete's cascade:\n // without it the deleted element's relationship dangles and the changeset no longer commits.\n const seq = (c: StagedChange): number => c.sequenceNumber ?? changes.indexOf(c);\n const deleteSeq = new Map<string, number>();\n for (const change of changes) {\n if (change.type !== \"delete\") continue;\n const id = graph.resolve(change.elementId);\n deleteSeq.set(id, Math.min(deleteSeq.get(id) ?? Infinity, seq(change)));\n }\n const deletedEndOf = (change: StagedChange): string | undefined => {\n if (change.type !== \"relationship-delete\") return undefined;\n const triple = stagedRelationshipTriple(change);\n if (!triple) return undefined;\n return [graph.resolve(triple.source), graph.resolve(triple.target)].find(\n (end) => deleteSeq.has(end) && deleteSeq.get(end)! < seq(change)\n );\n };\n const cascaded = matched.filter((c) => deletedEndOf(c) !== undefined);\n const deletedEnds = [...new Set(cascaded.map((c) => deletedEndOf(c)!))].join(\", \");\n const cascadeList = cascaded.map((c) => c.elementId).join(\", \");\n // One end sweeps every relationship there, so it leaves a delete's cascade alone. Naming both\n // ends asks for those relationships specifically, so they go, with a warning.\n const bothEnds = !!spec.source && !!spec.target;\n for (const change of matched) {\n if (!bothEnds && cascaded.includes(change)) continue;\n keys.add(change.elementId);\n }\n if (cascaded.length > 0 && bothEnds) {\n notes.push(\n `Unstaged ${cascaded.length} relationship removal(s) cascaded from the staged delete of ${deletedEnds} ` +\n `(${cascadeList}): those relationships now dangle, so the changeset will not commit until they are ` +\n `removed again or the delete is unstaged (\"changeset_unstage\" with elementId)`\n );\n } else if (cascaded.length > 0) {\n notes.push(\n `Kept ${cascaded.length} relationship removal(s) cascaded from the staged delete of ${deletedEnds} ` +\n `(${cascadeList}): dropping them would leave those relationships dangling. Unstage the delete ` +\n `(\"changeset_unstage\" with elementId) to restore them, or name both source and target to drop one anyway`\n );\n }\n return { keys, notes };\n}\n\nfunction notStagedMessage(spec: UnstageSpec, changesetName: string): string {\n return spec.elementId !== undefined\n ? `No staged change to ${spec.elementId} in '${changesetName}'`\n : `No staged relationship change ${describeEnds(spec)}` +\n `${spec.predicate ? ` (${spec.predicate})` : \"\"} in '${changesetName}'`;\n}\n\nconst SINGLE_FORM_FIELDS = [\"elementId\", \"source\", \"target\", \"predicate\", \"keepRelationships\"] as const;\n\nexport async function changesetUnstageHandler(args: ChangesetUnstageArgs): Promise<CallToolResult> {\n return runTool(async () => {\n if (args.changes) {\n const mixed = SINGLE_FORM_FIELDS.filter((field) => args[field] !== undefined);\n if (mixed.length > 0) {\n throw new CLIError(`\"changes\" cannot be combined with ${mixed.map((f) => `\"${f}\"`).join(\", \")}`, ErrorCategory.USER, [\n 'Put those fields on the items of the \"changes\" list',\n ]);\n }\n return unstageBatch(args.changes, args.changesetId, args.rootPath);\n }\n\n checkUnstageSpec(args);\n\n const model = await loadModel(args.rootPath);\n const manager = new StagingAreaManager(model.rootPath, model);\n const changeset = await resolveChangeset(manager, args.changesetId);\n requireStaged(changeset, \"unstage changes\");\n const graph = await ChangesetGraph.build(model, changeset);\n const changes = changeset.changes as StagedChange[];\n const { keys, notes } = selectUnstage(args, graph, changeset);\n\n const removed = changes.filter((c) => keys.has(c.elementId));\n if (removed.length === 0) {\n return jsonResult({\n status: \"not-staged\",\n changeset: changeset.name,\n message: notStagedMessage(args, changeset.name),\n suggestions: ['Use \"changeset_show\" to list the staged changes'],\n ...(notes.length > 0 ? { notes } : {}),\n });\n }\n\n // Each key is a revision of its own, as before the list form: briefs count unstages by revision.\n for (const key of keys) {\n await manager.unstage(changeset.id!, key);\n }\n await reloadModel(args.rootPath);\n\n return jsonResult({\n status: \"unstaged\",\n changeset: changeset.name,\n unstaged: removed.map(summarize),\n remainingChanges: changes.length - removed.length,\n ...(notes.length > 0 ? { notes } : {}),\n });\n });\n}\n\ninterface UnstageBatchResult {\n index: number;\n status: \"unstaged\" | \"already-unstaged\" | \"not-staged\" | \"invalid\";\n elementId?: string;\n source?: string;\n target?: string;\n predicate?: string;\n unstaged?: Record<string, unknown>[];\n message?: string;\n reason?: string;\n suggestions?: string[];\n notes?: string[];\n}\n\n/**\n * changeset_unstage's list form: select each item's changes against the changeset as it stands,\n * then remove them all in one write. A change two items select is reported under the first.\n */\nasync function unstageBatch(specs: UnstageSpec[], changesetId: string | undefined, rootPath: string | undefined) {\n const model = await loadModel(rootPath);\n const manager = new StagingAreaManager(model.rootPath, model);\n const changeset = await resolveChangeset(manager, changesetId);\n requireStaged(changeset, \"unstage changes\");\n const graph = await ChangesetGraph.build(model, changeset);\n const changes = changeset.changes as StagedChange[];\n\n const claimed = new Set<string>();\n const results: UnstageBatchResult[] = [];\n for (const [index, spec] of specs.entries()) {\n const asSent: UnstageBatchResult = {\n index,\n status: \"unstaged\",\n ...(spec.elementId !== undefined ? { elementId: spec.elementId } : {}),\n ...(spec.source !== undefined ? { source: spec.source } : {}),\n ...(spec.target !== undefined ? { target: spec.target } : {}),\n ...(spec.predicate !== undefined ? { predicate: spec.predicate } : {}),\n };\n let selection: { keys: Set<string>; notes: string[] };\n try {\n checkUnstageSpec(spec);\n selection = selectUnstage(spec, graph, changeset);\n } catch (error) {\n results.push({\n ...asSent,\n status: \"invalid\",\n reason: getErrorMessage(error),\n ...(error instanceof CLIError && error.suggestions?.length ? { suggestions: error.suggestions } : {}),\n });\n continue;\n }\n const notes = [...selection.notes];\n const fresh = [...selection.keys].filter((key) => !claimed.has(key));\n const earlier = selection.keys.size - fresh.length;\n for (const key of fresh) claimed.add(key);\n const removed = changes.filter((c) => fresh.includes(c.elementId));\n const status: UnstageBatchResult[\"status\"] =\n removed.length > 0 ? \"unstaged\" : earlier > 0 ? \"already-unstaged\" : \"not-staged\";\n if (earlier > 0) notes.push(`${earlier} of its change(s) were already unstaged by an earlier item`);\n results.push({\n ...asSent,\n status,\n ...(removed.length > 0 ? { unstaged: removed.map(summarize) } : {}),\n ...(status === \"not-staged\" ? { message: notStagedMessage(spec, changeset.name) } : {}),\n ...(notes.length > 0 ? { notes } : {}),\n });\n }\n\n if (claimed.size > 0) {\n await manager.unstageMany(changeset.id!, [...claimed]);\n await reloadModel(rootPath);\n }\n\n const counts: Record<string, number> = {};\n for (const result of results) counts[result.status] = (counts[result.status] ?? 0) + 1;\n const removedCount = changes.filter((c) => claimed.has(c.elementId)).length;\n return jsonResult({\n changeset: changeset.name,\n counts,\n results,\n unstagedChanges: removedCount,\n remainingChanges: changes.length - removedCount,\n ...(results.some((r) => r.status === \"not-staged\")\n ? { suggestions: ['Use \"changeset_show\" to list the staged changes'] }\n : {}),\n });\n}\n\nexport const changesetUnstageTool: McpToolDefinition<typeof unstageInputSchema> = {\n name: \"changeset_unstage\",\n description:\n \"Undo part of a staged changeset: drop the staged changes to one element (elementId), or the staged \" +\n \"relationship adds/deletes between source and target, or every one from source alone or to target alone \" +\n \"(optionally one predicate). To drop several, send changes: [...] (one write, a result per item). The base \" +\n \"model is not touched. Defaults to the active changeset. Use changeset_show to see what is staged.\",\n inputSchema: unstageInputSchema,\n handler: changesetUnstageHandler,\n};\n\n// ---------------------------------------------------------------------------\n// changeset_discard\n// ---------------------------------------------------------------------------\n\nconst discardInputSchema = {\n changesetId: z.string().describe(\"Changeset ID or name to discard. Required: discard is never implied.\"),\n confirm: z\n .boolean()\n .describe(\n \"Must be true. Discarding deletes the changeset's staged changes permanently (only its name, description and \" +\n \"a 'discarded' status remain), so confirm only when the plan is to be abandoned.\"\n ),\n rootPath: rootPathSchema,\n};\n\nexport type ChangesetDiscardArgs = z.infer<z.ZodObject<typeof discardInputSchema>>;\n\nexport async function changesetDiscardHandler(args: ChangesetDiscardArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const manager = new StagingAreaManager(model.rootPath, model);\n const changeset = await resolveChangeset(manager, args.changesetId);\n requireStaged(changeset, \"discard it\");\n\n if (args.confirm !== true) {\n throw new CLIError(\n `Discarding '${changeset.name}' deletes its ${changeset.changes.length} staged change(s) permanently`,\n ErrorCategory.USER,\n [\n 'Pass \"confirm\": true to discard it',\n 'Use \"changeset_unstage\" to drop individual changes instead',\n 'Use \"changeset_deactivate\" to stop staging into it and keep its changes',\n ]\n );\n }\n\n const wasActive = (await manager.getActiveId()) === changeset.id;\n const discardedChanges = changeset.changes.length;\n await manager.discard(changeset.id!);\n if (wasActive) {\n await manager.clearActive();\n }\n await reloadModel(args.rootPath);\n\n return jsonResult({\n id: changeset.id,\n name: changeset.name,\n status: \"discarded\",\n discardedChanges,\n deactivated: wasActive,\n });\n });\n}\n\nexport const changesetDiscardTool: McpToolDefinition<typeof discardInputSchema> = {\n name: \"changeset_discard\",\n description:\n \"Abandon a staged changeset: PERMANENTLY deletes its staged changes and marks it discarded (deactivating it if \" +\n \"active). Not recoverable, so it requires confirm: true. The base model is not touched. To undo part of a \" +\n \"plan use changeset_unstage; to pause it use changeset_deactivate.\",\n inputSchema: discardInputSchema,\n handler: changesetDiscardHandler,\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["seq"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { StagingAreaManager } from "../../core/staging-area.js";
|
|
3
|
+
import { CLIError, ErrorCategory } from "../../utils/errors.js";
|
|
4
|
+
import { jsonResult, loadModel, reloadModel, rootPathSchema, runTool } from "./shared.js";
|
|
5
|
+
import { resolveChangeset } from "./changeset-shared.js";
|
|
6
|
+
const createInputSchema = {
|
|
7
|
+
name: z.string().min(1).describe("Short name for the change, e.g. 'add-order-export'."),
|
|
8
|
+
description: z.string().optional().describe("The change's intent: what it is for and what done looks like. Shown to the human reviewing it."),
|
|
9
|
+
activate: z.boolean().optional().describe("Make it the active changeset so mutations stage into it (default true)."),
|
|
10
|
+
rootPath: rootPathSchema
|
|
11
|
+
};
|
|
12
|
+
async function changesetCreateHandler(args) {
|
|
13
|
+
return runTool(async () => {
|
|
14
|
+
const model = await loadModel(args.rootPath), manager = new StagingAreaManager(model.rootPath, model);
|
|
15
|
+
if (await manager.load(args.name))
|
|
16
|
+
throw new CLIError(`Changeset '${args.name}' already exists`, ErrorCategory.USER, [
|
|
17
|
+
`Use "changeset_activate" with "${args.name}" to continue it`,
|
|
18
|
+
"Or choose another name"
|
|
19
|
+
]);
|
|
20
|
+
const changeset = await manager.create(args.name, args.description), activate = args.activate ?? !0, previouslyActive = activate ? await manager.getActiveId() : null;
|
|
21
|
+
return activate && (await manager.setActive(changeset.id), await reloadModel(args.rootPath)), jsonResult({
|
|
22
|
+
id: changeset.id,
|
|
23
|
+
name: changeset.name,
|
|
24
|
+
...changeset.description ? { description: changeset.description } : {},
|
|
25
|
+
status: changeset.status,
|
|
26
|
+
active: activate,
|
|
27
|
+
...previouslyActive && previouslyActive !== changeset.id ? { deactivated: previouslyActive } : {}
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
const changesetCreateTool = {
|
|
32
|
+
name: "changeset_create",
|
|
33
|
+
description: "Start planning a change: create a changeset carrying the change's intent and (by default) activate it, so model_add / model_update / model_delete / relationship_add / relationship_delete stage into it instead of writing the model. Before calling it, propose the changeset's name and intent (description) to the user and confirm both with them. Landing it is the user's step: changeset_commit commits only after they confirm it, or they commit it in the viewer.",
|
|
34
|
+
inputSchema: createInputSchema,
|
|
35
|
+
handler: changesetCreateHandler
|
|
36
|
+
}, activateInputSchema = {
|
|
37
|
+
changesetId: z.string().describe("Changeset ID or name."),
|
|
38
|
+
rootPath: rootPathSchema
|
|
39
|
+
};
|
|
40
|
+
async function changesetActivateHandler(args) {
|
|
41
|
+
return runTool(async () => {
|
|
42
|
+
const model = await loadModel(args.rootPath), manager = new StagingAreaManager(model.rootPath, model), changeset = await resolveChangeset(manager, args.changesetId);
|
|
43
|
+
if (changeset.status !== "staged")
|
|
44
|
+
throw new CLIError(`Changeset '${changeset.name}' is ${changeset.status} and cannot accept changes`, ErrorCategory.USER, ['Use "changeset_create" to start a new one']);
|
|
45
|
+
const previouslyActive = await manager.getActiveId();
|
|
46
|
+
return await manager.setActive(changeset.id), await reloadModel(args.rootPath), jsonResult({
|
|
47
|
+
id: changeset.id,
|
|
48
|
+
name: changeset.name,
|
|
49
|
+
active: !0,
|
|
50
|
+
changes: changeset.changes.length,
|
|
51
|
+
...previouslyActive && previouslyActive !== changeset.id ? { deactivated: previouslyActive } : {}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
const changesetActivateTool = {
|
|
56
|
+
name: "changeset_activate",
|
|
57
|
+
description: "Make an existing staged changeset the active one, so mutations stage into it.",
|
|
58
|
+
inputSchema: activateInputSchema,
|
|
59
|
+
handler: changesetActivateHandler
|
|
60
|
+
}, deactivateInputSchema = {
|
|
61
|
+
rootPath: rootPathSchema
|
|
62
|
+
};
|
|
63
|
+
async function changesetDeactivateHandler(args) {
|
|
64
|
+
return runTool(async () => {
|
|
65
|
+
const model = await loadModel(args.rootPath), manager = new StagingAreaManager(model.rootPath, model), activeId = await manager.getActiveId();
|
|
66
|
+
return activeId && (await manager.clearActive(), await reloadModel(args.rootPath)), jsonResult({ deactivated: activeId ?? null });
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const changesetDeactivateTool = {
|
|
70
|
+
name: "changeset_deactivate",
|
|
71
|
+
description: "Deactivate the active changeset. Its changes stay staged; afterwards mutations write the base model directly.",
|
|
72
|
+
inputSchema: deactivateInputSchema,
|
|
73
|
+
handler: changesetDeactivateHandler
|
|
74
|
+
};
|
|
75
|
+
export {
|
|
76
|
+
changesetActivateHandler,
|
|
77
|
+
changesetActivateTool,
|
|
78
|
+
changesetCreateHandler,
|
|
79
|
+
changesetCreateTool,
|
|
80
|
+
changesetDeactivateHandler,
|
|
81
|
+
changesetDeactivateTool
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=changeset-lifecycle.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/tools/changeset-lifecycle.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * changeset_create, changeset_activate, changeset_deactivate \u2014 open and switch the changeset\n * that model and relationship mutations stage into. Mirrors `dr changeset create|activate|deactivate`.\n *\n * Every one of these reloads the cached model afterwards: the model decides at load time whether\n * its layers are projected through an active changeset.\n *\n * Commit, apply and delete are deliberately not exposed over MCP: landing a change is the\n * human's step (viewer or CLI). Rename, unstage and (confirmed) discard are in\n * changeset-editing.ts. See docs/CHANGE_MODELING.md.\n */\n\nimport { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { StagingAreaManager } from \"../../core/staging-area.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\nimport { jsonResult, loadModel, reloadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\nimport { resolveChangeset } from \"./changeset-shared.js\";\n\n// ---------------------------------------------------------------------------\n// changeset_create\n// ---------------------------------------------------------------------------\n\nconst createInputSchema = {\n name: z.string().min(1).describe(\"Short name for the change, e.g. 'add-order-export'.\"),\n description: z\n .string()\n .optional()\n .describe(\"The change's intent: what it is for and what done looks like. Shown to the human reviewing it.\"),\n activate: z\n .boolean()\n .optional()\n .describe(\"Make it the active changeset so mutations stage into it (default true).\"),\n rootPath: rootPathSchema,\n};\n\nexport type ChangesetCreateArgs = z.infer<z.ZodObject<typeof createInputSchema>>;\n\nexport async function changesetCreateHandler(args: ChangesetCreateArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const manager = new StagingAreaManager(model.rootPath, model);\n\n if (await manager.load(args.name)) {\n throw new CLIError(`Changeset '${args.name}' already exists`, ErrorCategory.USER, [\n `Use \"changeset_activate\" with \"${args.name}\" to continue it`,\n \"Or choose another name\",\n ]);\n }\n\n const changeset = await manager.create(args.name, args.description);\n const activate = args.activate ?? true;\n const previouslyActive = activate ? await manager.getActiveId() : null;\n if (activate) {\n await manager.setActive(changeset.id);\n await reloadModel(args.rootPath);\n }\n\n return jsonResult({\n id: changeset.id,\n name: changeset.name,\n ...(changeset.description ? { description: changeset.description } : {}),\n status: changeset.status,\n active: activate,\n ...(previouslyActive && previouslyActive !== changeset.id ? { deactivated: previouslyActive } : {}),\n });\n });\n}\n\nexport const changesetCreateTool: McpToolDefinition<typeof createInputSchema> = {\n name: \"changeset_create\",\n description:\n \"Start planning a change: create a changeset carrying the change's intent and (by default) activate it, \" +\n \"so model_add / model_update / model_delete / relationship_add / relationship_delete stage into it instead \" +\n \"of writing the model. Before calling it, propose the changeset's name and intent (description) to the user \" +\n \"and confirm both with them. Landing it is the user's step: changeset_commit commits only after they confirm \" +\n \"it, or they commit it in the viewer.\",\n inputSchema: createInputSchema,\n handler: changesetCreateHandler,\n};\n\n// ---------------------------------------------------------------------------\n// changeset_activate\n// ---------------------------------------------------------------------------\n\nconst activateInputSchema = {\n changesetId: z.string().describe(\"Changeset ID or name.\"),\n rootPath: rootPathSchema,\n};\n\nexport type ChangesetActivateArgs = z.infer<z.ZodObject<typeof activateInputSchema>>;\n\nexport async function changesetActivateHandler(args: ChangesetActivateArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const manager = new StagingAreaManager(model.rootPath, model);\n const changeset = await resolveChangeset(manager, args.changesetId);\n\n if (changeset.status !== \"staged\") {\n throw new CLIError(\n `Changeset '${changeset.name}' is ${changeset.status} and cannot accept changes`,\n ErrorCategory.USER,\n ['Use \"changeset_create\" to start a new one']\n );\n }\n\n const previouslyActive = await manager.getActiveId();\n await manager.setActive(changeset.id);\n await reloadModel(args.rootPath);\n\n return jsonResult({\n id: changeset.id,\n name: changeset.name,\n active: true,\n changes: changeset.changes.length,\n ...(previouslyActive && previouslyActive !== changeset.id ? { deactivated: previouslyActive } : {}),\n });\n });\n}\n\nexport const changesetActivateTool: McpToolDefinition<typeof activateInputSchema> = {\n name: \"changeset_activate\",\n description: \"Make an existing staged changeset the active one, so mutations stage into it.\",\n inputSchema: activateInputSchema,\n handler: changesetActivateHandler,\n};\n\n// ---------------------------------------------------------------------------\n// changeset_deactivate\n// ---------------------------------------------------------------------------\n\nconst deactivateInputSchema = {\n rootPath: rootPathSchema,\n};\n\nexport type ChangesetDeactivateArgs = z.infer<z.ZodObject<typeof deactivateInputSchema>>;\n\nexport async function changesetDeactivateHandler(args: ChangesetDeactivateArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const manager = new StagingAreaManager(model.rootPath, model);\n const activeId = await manager.getActiveId();\n if (activeId) {\n await manager.clearActive();\n await reloadModel(args.rootPath);\n }\n return jsonResult({ deactivated: activeId ?? null });\n });\n}\n\nexport const changesetDeactivateTool: McpToolDefinition<typeof deactivateInputSchema> = {\n name: \"changeset_deactivate\",\n description:\n \"Deactivate the active changeset. Its changes stay staged; afterwards mutations write the base model directly.\",\n inputSchema: deactivateInputSchema,\n handler: changesetDeactivateHandler,\n};\n"],
|
|
5
|
+
"mappings": "AAYA,SAAS,SAAS;AAElB,SAAS,0BAA0B;AACnC,SAAS,UAAU,qBAAqB;AACxC,SAAS,YAAY,WAAW,aAAa,gBAAgB,eAAuC;AACpG,SAAS,wBAAwB;AAMjC,MAAM,oBAAoB;EACxB,MAAM,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,SAAS,qDAAqD;EACtF,aAAa,EACV,OAAM,EACN,SAAQ,EACR,SAAS,gGAAgG;EAC5G,UAAU,EACP,QAAO,EACP,SAAQ,EACR,SAAS,yEAAyE;EACrF,UAAU;;AAKZ,eAAsB,uBAAuB,MAAyB;AACpE,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GACrC,UAAU,IAAI,mBAAmB,MAAM,UAAU,KAAK;AAE5D,QAAI,MAAM,QAAQ,KAAK,KAAK,IAAI;AAC9B,YAAM,IAAI,SAAS,cAAc,KAAK,IAAI,oBAAoB,cAAc,MAAM;QAChF,kCAAkC,KAAK,IAAI;QAC3C;OACD;AAGH,UAAM,YAAY,MAAM,QAAQ,OAAO,KAAK,MAAM,KAAK,WAAW,GAC5D,WAAW,KAAK,YAAY,IAC5B,mBAAmB,WAAW,MAAM,QAAQ,YAAW,IAAK;AAClE,WAAI,aACF,MAAM,QAAQ,UAAU,UAAU,EAAE,GACpC,MAAM,YAAY,KAAK,QAAQ,IAG1B,WAAW;MAChB,IAAI,UAAU;MACd,MAAM,UAAU;MAChB,GAAI,UAAU,cAAc,EAAE,aAAa,UAAU,YAAW,IAAK,CAAA;MACrE,QAAQ,UAAU;MAClB,QAAQ;MACR,GAAI,oBAAoB,qBAAqB,UAAU,KAAK,EAAE,aAAa,iBAAgB,IAAK,CAAA;KACjG;EACH,CAAC;AACH;AAEO,MAAM,sBAAmE;EAC9E,MAAM;EACN,aACE;EAKF,aAAa;EACb,SAAS;GAOL,sBAAsB;EAC1B,aAAa,EAAE,OAAM,EAAG,SAAS,uBAAuB;EACxD,UAAU;;AAKZ,eAAsB,yBAAyB,MAA2B;AACxE,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GACrC,UAAU,IAAI,mBAAmB,MAAM,UAAU,KAAK,GACtD,YAAY,MAAM,iBAAiB,SAAS,KAAK,WAAW;AAElE,QAAI,UAAU,WAAW;AACvB,YAAM,IAAI,SACR,cAAc,UAAU,IAAI,QAAQ,UAAU,MAAM,8BACpD,cAAc,MACd,CAAC,2CAA2C,CAAC;AAIjD,UAAM,mBAAmB,MAAM,QAAQ,YAAW;AAClD,iBAAM,QAAQ,UAAU,UAAU,EAAE,GACpC,MAAM,YAAY,KAAK,QAAQ,GAExB,WAAW;MAChB,IAAI,UAAU;MACd,MAAM,UAAU;MAChB,QAAQ;MACR,SAAS,UAAU,QAAQ;MAC3B,GAAI,oBAAoB,qBAAqB,UAAU,KAAK,EAAE,aAAa,iBAAgB,IAAK,CAAA;KACjG;EACH,CAAC;AACH;AAEO,MAAM,wBAAuE;EAClF,MAAM;EACN,aAAa;EACb,aAAa;EACb,SAAS;GAOL,wBAAwB;EAC5B,UAAU;;AAKZ,eAAsB,2BAA2B,MAA6B;AAC5E,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GACrC,UAAU,IAAI,mBAAmB,MAAM,UAAU,KAAK,GACtD,WAAW,MAAM,QAAQ,YAAW;AAC1C,WAAI,aACF,MAAM,QAAQ,YAAW,GACzB,MAAM,YAAY,KAAK,QAAQ,IAE1B,WAAW,EAAE,aAAa,YAAY,KAAI,CAAE;EACrD,CAAC;AACH;AAEO,MAAM,0BAA2E;EACtF,MAAM;EACN,aACE;EACF,aAAa;EACb,SAAS;;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ChangesetGraph } from "../../core/changeset-graph.js";
|
|
2
|
+
import { StagingAreaManager } from "../../core/staging-area.js";
|
|
3
|
+
import { CLIError, ErrorCategory } from "../../utils/errors.js";
|
|
4
|
+
async function resolveChangeset(manager, changesetId, parameter = "changesetId") {
|
|
5
|
+
const id = changesetId ?? await manager.getActiveId();
|
|
6
|
+
if (!id)
|
|
7
|
+
throw new CLIError("No changeset named and none is active", ErrorCategory.USER, [
|
|
8
|
+
`Pass "${parameter}", or use "changeset_create" / "changeset_activate" first`,
|
|
9
|
+
'Use "changeset_list" to see existing changesets'
|
|
10
|
+
]);
|
|
11
|
+
const changeset = await manager.load(id);
|
|
12
|
+
if (!changeset)
|
|
13
|
+
throw new CLIError(`Changeset ${id} not found`, ErrorCategory.NOT_FOUND, [
|
|
14
|
+
'Use "changeset_list" to see all available changesets'
|
|
15
|
+
]);
|
|
16
|
+
return changeset;
|
|
17
|
+
}
|
|
18
|
+
async function activeStagedChangeset(manager) {
|
|
19
|
+
const active = await manager.getActive();
|
|
20
|
+
return active && active.status === "staged" ? active : null;
|
|
21
|
+
}
|
|
22
|
+
async function loadChangesetGraph(model, changesetId) {
|
|
23
|
+
const manager = new StagingAreaManager(model.rootPath, model), changeset = await resolveChangeset(manager, changesetId), graph = await ChangesetGraph.build(model, changeset);
|
|
24
|
+
return { manager, changeset, graph };
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
activeStagedChangeset,
|
|
28
|
+
loadChangesetGraph,
|
|
29
|
+
resolveChangeset
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=changeset-shared.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/tools/changeset-shared.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Helpers shared by the changeset-planning MCP tools.\n */\n\nimport type { Changeset } from \"../../core/changeset.js\";\nimport { ChangesetGraph } from \"../../core/changeset-graph.js\";\nimport type { Model } from \"../../core/model.js\";\nimport { StagingAreaManager } from \"../../core/staging-area.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\n\n/** Loads a changeset by id or name, or the active one when none is named. */\nexport async function resolveChangeset(\n manager: StagingAreaManager,\n changesetId?: string,\n /** The tool parameter that names the changeset, for the hint when none is named or active. */\n parameter = \"changesetId\"\n): Promise<Changeset> {\n const id = changesetId ?? (await manager.getActiveId());\n if (!id) {\n throw new CLIError(\"No changeset named and none is active\", ErrorCategory.USER, [\n `Pass \"${parameter}\", or use \"changeset_create\" / \"changeset_activate\" first`,\n 'Use \"changeset_list\" to see existing changesets',\n ]);\n }\n const changeset = await manager.load(id);\n if (!changeset) {\n throw new CLIError(`Changeset ${id} not found`, ErrorCategory.NOT_FOUND, [\n 'Use \"changeset_list\" to see all available changesets',\n ]);\n }\n return changeset;\n}\n\n/** The active changeset when it can still accept changes, else null. */\nexport async function activeStagedChangeset(manager: StagingAreaManager): Promise<Changeset | null> {\n const active = await manager.getActive();\n return active && active.status === \"staged\" ? active : null;\n}\n\n/** Builds the projected graph for a changeset (by id/name, or the active one). */\nexport async function loadChangesetGraph(\n model: Model,\n changesetId?: string\n): Promise<{ manager: StagingAreaManager; changeset: Changeset; graph: ChangesetGraph }> {\n const manager = new StagingAreaManager(model.rootPath, model);\n const changeset = await resolveChangeset(manager, changesetId);\n const graph = await ChangesetGraph.build(model, changeset);\n return { manager, changeset, graph };\n}\n"],
|
|
5
|
+
"mappings": "AAKA,SAAS,sBAAsB;AAE/B,SAAS,0BAA0B;AACnC,SAAS,UAAU,qBAAqB;AAGxC,eAAsB,iBACpB,SACA,aAEA,YAAY,eAAa;AAEzB,QAAM,KAAK,eAAgB,MAAM,QAAQ,YAAW;AACpD,MAAI,CAAC;AACH,UAAM,IAAI,SAAS,yCAAyC,cAAc,MAAM;MAC9E,SAAS,SAAS;MAClB;KACD;AAEH,QAAM,YAAY,MAAM,QAAQ,KAAK,EAAE;AACvC,MAAI,CAAC;AACH,UAAM,IAAI,SAAS,aAAa,EAAE,cAAc,cAAc,WAAW;MACvE;KACD;AAEH,SAAO;AACT;AAGA,eAAsB,sBAAsB,SAA2B;AACrE,QAAM,SAAS,MAAM,QAAQ,UAAS;AACtC,SAAO,UAAU,OAAO,WAAW,WAAW,SAAS;AACzD;AAGA,eAAsB,mBACpB,OACA,aAAoB;AAEpB,QAAM,UAAU,IAAI,mBAAmB,MAAM,UAAU,KAAK,GACtD,YAAY,MAAM,iBAAiB,SAAS,WAAW,GACvD,QAAQ,MAAM,eAAe,MAAM,OAAO,SAAS;AACzD,SAAO,EAAE,SAAS,WAAW,MAAK;AACpC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { StagingAreaManager } from "../../core/staging-area.js";
|
|
3
|
+
import { summarizeChangeset } from "../../core/changeset-summary.js";
|
|
3
4
|
import { CLIError, ErrorCategory } from "../../utils/errors.js";
|
|
4
5
|
import { jsonResult, loadModel, rootPathSchema, runTool } from "./shared.js";
|
|
5
6
|
const inputSchema = {
|
|
6
7
|
changesetId: z.string().describe("Changeset ID or name."),
|
|
8
|
+
detail: z.enum(["full", "summary"]).optional().describe('"full" (default): every change with its before/after snapshots. "summary": one entry per change (sequence, operation, element id and type or relationship source/predicate/target, and for updates the changed field names such as attributes.summary), plus totals per operation, without snapshots.'),
|
|
7
9
|
rootPath: rootPathSchema
|
|
8
10
|
};
|
|
9
11
|
async function changesetShowHandler(args) {
|
|
@@ -13,6 +15,20 @@ async function changesetShowHandler(args) {
|
|
|
13
15
|
throw new CLIError(`Changeset ${args.changesetId} not found`, ErrorCategory.NOT_FOUND, [
|
|
14
16
|
'Use "changeset_list" to see all available changesets'
|
|
15
17
|
]);
|
|
18
|
+
if (args.detail === "summary") {
|
|
19
|
+
const summary = summarizeChangeset(changeset.changes);
|
|
20
|
+
return jsonResult({
|
|
21
|
+
id: changeset.id,
|
|
22
|
+
name: changeset.name,
|
|
23
|
+
description: changeset.description,
|
|
24
|
+
status: changeset.status,
|
|
25
|
+
created: changeset.created,
|
|
26
|
+
modified: changeset.modified,
|
|
27
|
+
detail: "summary",
|
|
28
|
+
totals: summary.totals,
|
|
29
|
+
changes: summary.changes
|
|
30
|
+
});
|
|
31
|
+
}
|
|
16
32
|
return jsonResult({
|
|
17
33
|
id: changeset.id,
|
|
18
34
|
name: changeset.name,
|
|
@@ -28,7 +44,7 @@ async function changesetShowHandler(args) {
|
|
|
28
44
|
}
|
|
29
45
|
const changesetShowTool = {
|
|
30
46
|
name: "changeset_show",
|
|
31
|
-
description:
|
|
47
|
+
description: `Show a single changeset's detail including its description, stats, and list of changes. Pass detail: "summary" for one compact line per change (operation, element or relationship, changed fields) and totals per operation, without the before/after snapshots.`,
|
|
32
48
|
inputSchema,
|
|
33
49
|
handler: changesetShowHandler
|
|
34
50
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/mcp/tools/changeset-show.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * changeset_show \u2014 show a single changeset's full detail, including its list\n * of changes. Mirrors the REST `GET /api/changesets/:changesetId` endpoint\n * (see `ChangesetDetailSchema` in `cli/src/server/schemas.ts`).\n */\n\nimport { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { StagingAreaManager } from \"../../core/staging-area.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\nimport { jsonResult, loadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n changesetId: z.string().describe(\"Changeset ID or name.\"),\n rootPath: rootPathSchema,\n};\n\nexport type ChangesetShowArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function changesetShowHandler(args: ChangesetShowArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const manager = new StagingAreaManager(model.rootPath, model);\n const changeset = await manager.load(args.changesetId);\n\n if (!changeset) {\n throw new CLIError(`Changeset ${args.changesetId} not found`, ErrorCategory.NOT_FOUND, [\n 'Use \"changeset_list\" to see all available changesets',\n ]);\n }\n\n return jsonResult({\n id: changeset.id,\n name: changeset.name,\n description: changeset.description,\n status: changeset.status,\n created: changeset.created,\n modified: changeset.modified,\n baseSnapshot: changeset.baseSnapshot,\n stats: changeset.stats,\n changes: changeset.changes,\n });\n });\n}\n\nexport const changesetShowTool: McpToolDefinition<typeof inputSchema> = {\n name: \"changeset_show\",\n description
|
|
5
|
-
"mappings": "AAMA,SAAS,SAAS;AAElB,SAAS,0BAA0B;AACnC,SAAS,UAAU,qBAAqB;AACxC,SAAS,YAAY,WAAW,gBAAgB,eAAuC;AAEvF,MAAM,cAAc;EAClB,aAAa,EAAE,OAAM,EAAG,SAAS,uBAAuB;EACxD,UAAU;;AAKZ,eAAsB,qBAAqB,MAAuB;AAChE,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GAErC,YAAY,MADF,IAAI,mBAAmB,MAAM,UAAU,KAAK,EAC5B,KAAK,KAAK,WAAW;AAErD,QAAI,CAAC;AACH,YAAM,IAAI,SAAS,aAAa,KAAK,WAAW,cAAc,cAAc,WAAW;QACrF;OACD;AAGH,WAAO,WAAW;MAChB,IAAI,UAAU;MACd,MAAM,UAAU;MAChB,aAAa,UAAU;MACvB,QAAQ,UAAU;MAClB,SAAS,UAAU;MACnB,UAAU,UAAU;MACpB,cAAc,UAAU;MACxB,OAAO,UAAU;MACjB,SAAS,UAAU;KACpB;EACH,CAAC;AACH;AAEO,MAAM,oBAA2D;EACtE,MAAM;EACN,
|
|
4
|
+
"sourcesContent": ["/**\n * changeset_show \u2014 show a single changeset's full detail, including its list\n * of changes. Mirrors the REST `GET /api/changesets/:changesetId` endpoint\n * (see `ChangesetDetailSchema` in `cli/src/server/schemas.ts`).\n */\n\nimport { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { StagingAreaManager } from \"../../core/staging-area.js\";\nimport { summarizeChangeset } from \"../../core/changeset-summary.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\nimport { jsonResult, loadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n changesetId: z.string().describe(\"Changeset ID or name.\"),\n detail: z\n .enum([\"full\", \"summary\"])\n .optional()\n .describe(\n '\"full\" (default): every change with its before/after snapshots. \"summary\": one entry per change ' +\n \"(sequence, operation, element id and type or relationship source/predicate/target, and for updates the \" +\n \"changed field names such as attributes.summary), plus totals per operation, without snapshots.\"\n ),\n rootPath: rootPathSchema,\n};\n\nexport type ChangesetShowArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function changesetShowHandler(args: ChangesetShowArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const manager = new StagingAreaManager(model.rootPath, model);\n const changeset = await manager.load(args.changesetId);\n\n if (!changeset) {\n throw new CLIError(`Changeset ${args.changesetId} not found`, ErrorCategory.NOT_FOUND, [\n 'Use \"changeset_list\" to see all available changesets',\n ]);\n }\n\n if (args.detail === \"summary\") {\n const summary = summarizeChangeset(changeset.changes);\n return jsonResult({\n id: changeset.id,\n name: changeset.name,\n description: changeset.description,\n status: changeset.status,\n created: changeset.created,\n modified: changeset.modified,\n detail: \"summary\",\n totals: summary.totals,\n changes: summary.changes,\n });\n }\n\n return jsonResult({\n id: changeset.id,\n name: changeset.name,\n description: changeset.description,\n status: changeset.status,\n created: changeset.created,\n modified: changeset.modified,\n baseSnapshot: changeset.baseSnapshot,\n stats: changeset.stats,\n changes: changeset.changes,\n });\n });\n}\n\nexport const changesetShowTool: McpToolDefinition<typeof inputSchema> = {\n name: \"changeset_show\",\n description:\n \"Show a single changeset's detail including its description, stats, and list of changes. Pass \" +\n 'detail: \"summary\" for one compact line per change (operation, element or relationship, changed fields) ' +\n \"and totals per operation, without the before/after snapshots.\",\n inputSchema,\n handler: changesetShowHandler,\n};\n"],
|
|
5
|
+
"mappings": "AAMA,SAAS,SAAS;AAElB,SAAS,0BAA0B;AACnC,SAAS,0BAA0B;AACnC,SAAS,UAAU,qBAAqB;AACxC,SAAS,YAAY,WAAW,gBAAgB,eAAuC;AAEvF,MAAM,cAAc;EAClB,aAAa,EAAE,OAAM,EAAG,SAAS,uBAAuB;EACxD,QAAQ,EACL,KAAK,CAAC,QAAQ,SAAS,CAAC,EACxB,SAAQ,EACR,SACC,uSAEkG;EAEtG,UAAU;;AAKZ,eAAsB,qBAAqB,MAAuB;AAChE,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GAErC,YAAY,MADF,IAAI,mBAAmB,MAAM,UAAU,KAAK,EAC5B,KAAK,KAAK,WAAW;AAErD,QAAI,CAAC;AACH,YAAM,IAAI,SAAS,aAAa,KAAK,WAAW,cAAc,cAAc,WAAW;QACrF;OACD;AAGH,QAAI,KAAK,WAAW,WAAW;AAC7B,YAAM,UAAU,mBAAmB,UAAU,OAAO;AACpD,aAAO,WAAW;QAChB,IAAI,UAAU;QACd,MAAM,UAAU;QAChB,aAAa,UAAU;QACvB,QAAQ,UAAU;QAClB,SAAS,UAAU;QACnB,UAAU,UAAU;QACpB,QAAQ;QACR,QAAQ,QAAQ;QAChB,SAAS,QAAQ;OAClB;IACH;AAEA,WAAO,WAAW;MAChB,IAAI,UAAU;MACd,MAAM,UAAU;MAChB,aAAa,UAAU;MACvB,QAAQ,UAAU;MAClB,SAAS,UAAU;MACnB,UAAU,UAAU;MACpB,cAAc,UAAU;MACxB,OAAO,UAAU;MACjB,SAAS,UAAU;KACpB;EACH,CAAC;AACH;AAEO,MAAM,oBAA2D;EACtE,MAAM;EACN,aACE;EAGF;EACA,SAAS;;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { strictItem } from "../strict-schema.js";
|
|
3
|
+
import { verifyChangesetInModel } from "../../core/changeset-verify.js";
|
|
4
|
+
import { StagingAreaManager } from "../../core/staging-area.js";
|
|
5
|
+
import { CLIError, ErrorCategory } from "../../utils/errors.js";
|
|
6
|
+
import { jsonResult, reloadModel, rootPathSchema, runTool } from "./shared.js";
|
|
7
|
+
import { resolveChangeset } from "./changeset-shared.js";
|
|
8
|
+
const inputSchema = {
|
|
9
|
+
planned: z.string().optional().describe("The planned changeset, by ID or name. Defaults to the active changeset."),
|
|
10
|
+
against: strictItem("against", {
|
|
11
|
+
changesetId: z.string().optional().describe("The as-built changeset (by ID or name). It should come from codebase_extract with since, not be written by the agent: a copy of the plan matches by definition."),
|
|
12
|
+
base: z.boolean().optional().describe("Compare with the base model, e.g. after the as-built changeset was committed on the branch."),
|
|
13
|
+
extracted: z.boolean().optional().describe("With base: the base holds a landed extraction of the build, so what extraction can't see is unverifiable rather than missing, as against an extracted as-built changeset.")
|
|
14
|
+
}).describe('What was built: {"changesetId": "..."} or {"base": true} (with "extracted": true after an extraction landed).'),
|
|
15
|
+
matchBySource: z.boolean().optional().describe("Also match elements of the same layer and type that share a source file (default true)."),
|
|
16
|
+
rootPath: rootPathSchema
|
|
17
|
+
};
|
|
18
|
+
async function changesetVerifyHandler(args) {
|
|
19
|
+
return runTool(async () => {
|
|
20
|
+
if (args.against?.changesetId && args.against.base)
|
|
21
|
+
throw new CLIError('Pass either "against.changesetId" or "against.base", not both', ErrorCategory.USER);
|
|
22
|
+
if (args.against?.extracted && !args.against.base)
|
|
23
|
+
throw new CLIError('"against.extracted" goes with "against.base"', ErrorCategory.USER, [
|
|
24
|
+
"An as-built changeset from codebase_extract is recognised on its own"
|
|
25
|
+
]);
|
|
26
|
+
if (!args.against?.changesetId && !args.against?.base)
|
|
27
|
+
throw new CLIError("Nothing to verify against", ErrorCategory.USER, [
|
|
28
|
+
'Pass "against": {"changesetId": "<as-built changeset>"} to compare with another changeset',
|
|
29
|
+
'Pass "against": {"base": true} to compare with the base model'
|
|
30
|
+
]);
|
|
31
|
+
const model = await reloadModel(args.rootPath), manager = new StagingAreaManager(model.rootPath, model), planned = await resolveChangeset(manager, args.planned, "planned"), asBuilt = args.against?.changesetId ? await resolveChangeset(manager, args.against.changesetId) : void 0;
|
|
32
|
+
return jsonResult(await verifyChangesetInModel(model, {
|
|
33
|
+
planned,
|
|
34
|
+
against: asBuilt ? { changeset: asBuilt } : { base: !0, extracted: args.against.extracted === !0 },
|
|
35
|
+
matchBySource: args.matchBySource
|
|
36
|
+
}));
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const changesetVerifyTool = {
|
|
40
|
+
name: "changeset_verify",
|
|
41
|
+
description: "Compare a planned changeset with what was built: the as-built changeset codebase_extract wrote (with since, the branch's base), or the base model. Elements match by id, then by layer + type + name ignoring case and separators, then by source file; relationships match through those element matches. Reports matched, missing (planned, not built), unverifiable (planned, but extraction can't see it: intent, re-exports, tests in languages without test cards, relationships no code edge maps to; not part of the verdict), unplanned (built, not planned), divergent (matched but type, name or attributes differ, with both values), and planned deletions that still exist, with a verdict. Description differences are notes on a match, not divergence: don't edit the plan to match extracted text. extraction.asBuilt counts the as-built elements extraction really staged, from its own record (not the sourceProvenance they declare); the rest are agentAdded, with why, and a warning says when they are more than half. Fuzzy matches are marked probable with their reason; confirm them. Reads the model fresh from disk, so a commit made outside MCP is seen. Read-only.",
|
|
42
|
+
inputSchema,
|
|
43
|
+
handler: changesetVerifyHandler
|
|
44
|
+
};
|
|
45
|
+
export {
|
|
46
|
+
changesetVerifyHandler,
|
|
47
|
+
changesetVerifyTool
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=changeset-verify.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/tools/changeset-verify.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * changeset_verify \u2014 compare a planned changeset with what was built.\n * See `cli/src/core/changeset-verify.ts` and docs/CHANGE_MODELING.md.\n */\n\nimport { z } from \"zod\";\nimport { strictItem } from \"../strict-schema.js\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { verifyChangesetInModel } from \"../../core/changeset-verify.js\";\nimport { StagingAreaManager } from \"../../core/staging-area.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\nimport { jsonResult, reloadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\nimport { resolveChangeset } from \"./changeset-shared.js\";\n\nconst inputSchema = {\n planned: z\n .string()\n .optional()\n .describe(\"The planned changeset, by ID or name. Defaults to the active changeset.\"),\n against: strictItem(\"against\", {\n changesetId: z\n .string()\n .optional()\n .describe(\n \"The as-built changeset (by ID or name). It should come from codebase_extract with since, not be written \" +\n \"by the agent: a copy of the plan matches by definition.\"\n ),\n base: z\n .boolean()\n .optional()\n .describe(\"Compare with the base model, e.g. after the as-built changeset was committed on the branch.\"),\n extracted: z\n .boolean()\n .optional()\n .describe(\n \"With base: the base holds a landed extraction of the build, so what extraction can't see is \" +\n \"unverifiable rather than missing, as against an extracted as-built changeset.\"\n ),\n }).describe('What was built: {\"changesetId\": \"...\"} or {\"base\": true} (with \"extracted\": true after an extraction landed).'),\n matchBySource: z\n .boolean()\n .optional()\n .describe(\"Also match elements of the same layer and type that share a source file (default true).\"),\n rootPath: rootPathSchema,\n};\n\nexport type ChangesetVerifyArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function changesetVerifyHandler(args: ChangesetVerifyArgs): Promise<CallToolResult> {\n return runTool(async () => {\n if (args.against?.changesetId && args.against.base) {\n throw new CLIError('Pass either \"against.changesetId\" or \"against.base\", not both', ErrorCategory.USER);\n }\n if (args.against?.extracted && !args.against.base) {\n throw new CLIError('\"against.extracted\" goes with \"against.base\"', ErrorCategory.USER, [\n \"An as-built changeset from codebase_extract is recognised on its own\",\n ]);\n }\n if (!args.against?.changesetId && !args.against?.base) {\n throw new CLIError(\"Nothing to verify against\", ErrorCategory.USER, [\n 'Pass \"against\": {\"changesetId\": \"<as-built changeset>\"} to compare with another changeset',\n 'Pass \"against\": {\"base\": true} to compare with the base model',\n ]);\n }\n // Always read the model fresh: the build is often committed outside MCP (`dr changeset commit` is\n // not exposed here), and a cached model would compare against the base as it was when the server\n // started. Verify is read-only and infrequent, so the reload is cheap insurance.\n const model = await reloadModel(args.rootPath);\n const manager = new StagingAreaManager(model.rootPath, model);\n const planned = await resolveChangeset(manager, args.planned, \"planned\");\n const asBuilt = args.against?.changesetId ? await resolveChangeset(manager, args.against.changesetId) : undefined;\n return jsonResult(\n await verifyChangesetInModel(model, {\n planned,\n against: asBuilt ? { changeset: asBuilt } : { base: true, extracted: args.against.extracted === true },\n matchBySource: args.matchBySource,\n })\n );\n });\n}\n\nexport const changesetVerifyTool: McpToolDefinition<typeof inputSchema> = {\n name: \"changeset_verify\",\n description:\n \"Compare a planned changeset with what was built: the as-built changeset codebase_extract wrote (with since, \" +\n \"the branch's base), or the base model. Elements match by id, then by layer + type + name ignoring case and \" +\n \"separators, then by source file; relationships match through those element matches. Reports matched, \" +\n \"missing (planned, not built), unverifiable (planned, but extraction can't see it: intent, re-exports, tests \" +\n \"in languages without test cards, relationships no code edge maps to; not part of the verdict), unplanned \" +\n \"(built, not planned), divergent (matched but type, name or attributes differ, with both values), and planned \" +\n \"deletions that still exist, with a verdict. Description differences are notes on a match, not divergence: \" +\n \"don't edit the plan to match extracted text. extraction.asBuilt counts the as-built elements extraction \" +\n \"really staged, from its own record (not the sourceProvenance they declare); the rest are agentAdded, with \" +\n \"why, and a warning says when they are more than half. Fuzzy matches are marked probable with their reason; \" +\n \"confirm them. Reads the model fresh from disk, so a commit made outside MCP is seen. Read-only.\",\n inputSchema,\n handler: changesetVerifyHandler,\n};\n"],
|
|
5
|
+
"mappings": "AAKA,SAAS,SAAS;AAClB,SAAS,kBAAkB;AAE3B,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC,SAAS,UAAU,qBAAqB;AACxC,SAAS,YAAY,aAAa,gBAAgB,eAAuC;AACzF,SAAS,wBAAwB;AAEjC,MAAM,cAAc;EAClB,SAAS,EACN,OAAM,EACN,SAAQ,EACR,SAAS,yEAAyE;EACrF,SAAS,WAAW,WAAW;IAC7B,aAAa,EACV,OAAM,EACN,SAAQ,EACR,SACC,iKAC2D;IAE/D,MAAM,EACH,QAAO,EACP,SAAQ,EACR,SAAS,6FAA6F;IACzG,WAAW,EACR,QAAO,EACP,SAAQ,EACR,SACC,2KACiF;GAEtF,EAAE,SAAS,+GAA+G;EAC3H,eAAe,EACZ,QAAO,EACP,SAAQ,EACR,SAAS,yFAAyF;EACrG,UAAU;;AAKZ,eAAsB,uBAAuB,MAAyB;AACpE,SAAO,QAAQ,YAAW;AACxB,QAAI,KAAK,SAAS,eAAe,KAAK,QAAQ;AAC5C,YAAM,IAAI,SAAS,iEAAiE,cAAc,IAAI;AAExG,QAAI,KAAK,SAAS,aAAa,CAAC,KAAK,QAAQ;AAC3C,YAAM,IAAI,SAAS,gDAAgD,cAAc,MAAM;QACrF;OACD;AAEH,QAAI,CAAC,KAAK,SAAS,eAAe,CAAC,KAAK,SAAS;AAC/C,YAAM,IAAI,SAAS,6BAA6B,cAAc,MAAM;QAClE;QACA;OACD;AAKH,UAAM,QAAQ,MAAM,YAAY,KAAK,QAAQ,GACvC,UAAU,IAAI,mBAAmB,MAAM,UAAU,KAAK,GACtD,UAAU,MAAM,iBAAiB,SAAS,KAAK,SAAS,SAAS,GACjE,UAAU,KAAK,SAAS,cAAc,MAAM,iBAAiB,SAAS,KAAK,QAAQ,WAAW,IAAI;AACxG,WAAO,WACL,MAAM,uBAAuB,OAAO;MAClC;MACA,SAAS,UAAU,EAAE,WAAW,QAAO,IAAK,EAAE,MAAM,IAAM,WAAW,KAAK,QAAQ,cAAc,GAAI;MACpG,eAAe,KAAK;KACrB,CAAC;EAEN,CAAC;AACH;AAEO,MAAM,sBAA6D;EACxE,MAAM;EACN,aACE;EAWF;EACA,SAAS;;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|