@documentation-robotics/cli 0.1.13 → 0.3.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 +74 -2
- package/dist/analysis/relationship-classifier.js +2 -9
- package/dist/analysis/relationship-classifier.js.map +2 -2
- 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 +171 -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/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/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 +195 -171
- package/dist/analyzers/cbm-analyzer.js.map +2 -2
- package/dist/analyzers/cbm-responses.js +336 -0
- package/dist/analyzers/cbm-responses.js.map +7 -0
- package/dist/analyzers/edge-relationships.js +45 -0
- package/dist/analyzers/edge-relationships.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/analyzers/verify-engine.js +22 -19
- package/dist/analyzers/verify-engine.js.map +2 -2
- 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 +112 -28
- package/dist/cli.js.map +3 -3
- package/dist/coding-agents/agents/claude-code.js +3 -1
- package/dist/coding-agents/agents/claude-code.js.map +2 -2
- package/dist/coding-agents/claude-code-client.js +2 -1
- package/dist/coding-agents/claude-code-client.js.map +2 -2
- package/dist/coding-agents/copilot-client.js +17 -12
- package/dist/coding-agents/copilot-client.js.map +2 -2
- package/dist/coding-agents/default-permissions.js +152 -0
- package/dist/coding-agents/default-permissions.js.map +7 -0
- package/dist/coding-agents/drbot-mcp.js +167 -0
- package/dist/coding-agents/drbot-mcp.js.map +7 -0
- package/dist/commands/add.js +12 -7
- package/dist/commands/add.js.map +2 -2
- package/dist/commands/analyzer.js +134 -23
- package/dist/commands/analyzer.js.map +2 -2
- package/dist/commands/audit.js +6 -6
- package/dist/commands/audit.js.map +2 -2
- package/dist/commands/changeset-verify.js +55 -0
- package/dist/commands/changeset-verify.js.map +7 -0
- package/dist/commands/changeset.js +261 -147
- package/dist/commands/changeset.js.map +2 -2
- package/dist/commands/delete.js +52 -19
- package/dist/commands/delete.js.map +3 -3
- package/dist/commands/element.js +3 -2
- package/dist/commands/element.js.map +2 -2
- package/dist/commands/farm.js +773 -0
- package/dist/commands/farm.js.map +7 -0
- package/dist/commands/init.js +11 -1
- package/dist/commands/init.js.map +2 -2
- package/dist/commands/mcp.js +122 -0
- package/dist/commands/mcp.js.map +7 -0
- package/dist/commands/relationship.js +251 -47
- package/dist/commands/relationship.js.map +2 -2
- package/dist/commands/reports.js +1 -1
- package/dist/commands/reports.js.map +2 -2
- package/dist/commands/update.js +56 -24
- package/dist/commands/update.js.map +2 -2
- package/dist/commands/upgrade.js +99 -11
- package/dist/commands/upgrade.js.map +3 -3
- package/dist/commands/validate.js +41 -3
- package/dist/commands/validate.js.map +2 -2
- package/dist/commands/version.js +2 -2
- package/dist/commands/version.js.map +2 -2
- package/dist/commands/visualize.js +4 -3
- package/dist/commands/visualize.js.map +2 -2
- package/dist/config.js +83 -0
- package/dist/config.js.map +7 -0
- package/dist/core/annotation-store.js +138 -0
- package/dist/core/annotation-store.js.map +7 -0
- package/dist/core/catalog-migration.js +33 -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 +153 -0
- package/dist/core/changeset-base-index.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 +518 -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/farm-manifest.js +140 -0
- package/dist/core/farm-manifest.js.map +7 -0
- package/dist/core/farm-sync-engine.js +346 -0
- package/dist/core/farm-sync-engine.js.map +7 -0
- package/dist/core/farm-sync-state.js +167 -0
- package/dist/core/farm-sync-state.js.map +7 -0
- package/dist/core/manifest.js +6 -3
- package/dist/core/manifest.js.map +2 -2
- package/dist/core/migration-registry.js +84 -1
- 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 +257 -44
- package/dist/core/model.js.map +3 -3
- package/dist/core/mutation-handler.js +71 -6
- package/dist/core/mutation-handler.js.map +2 -2
- 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 +68 -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 +64 -17
- 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 +83 -18
- package/dist/core/staging-area.js.map +2 -2
- package/dist/core/virtual-projection.js +14 -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 +2209 -7727
- package/dist/generated/relationship-index.js.map +2 -2
- package/dist/integrations/claude_code/agents/dr-architect.md +16 -3
- package/dist/integrations/claude_code/agents/dr-extractor.md +1 -1
- package/dist/integrations/claude_code/commands/dr-analyzer.md +565 -0
- package/dist/integrations/claude_code/commands/dr-map.md +13 -0
- package/dist/integrations/claude_code/commands/dr-plan.md +40 -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 +79 -0
- package/dist/integrations/claude_code/docs/QUICK_START.md +37 -8
- package/dist/integrations/claude_code/docs/README.md +52 -1
- 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 +92 -15
- package/dist/integrations/claude_code/skills/dr_change_planning/SKILL.md +119 -0
- package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +3 -0
- package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +1 -1
- package/dist/integrations/github_copilot/agents/dr-architect.md +1 -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 +222 -102
- package/dist/integrations/github_copilot/skills/dr_change_planning/SKILL.md +119 -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 +111 -0
- package/dist/mcp/api-key-manager.js.map +7 -0
- package/dist/mcp/changeset-only.js +34 -0
- package/dist/mcp/changeset-only.js.map +7 -0
- package/dist/mcp/http-transport.js +176 -0
- package/dist/mcp/http-transport.js.map +7 -0
- package/dist/mcp/resource-registry.js +97 -0
- package/dist/mcp/resource-registry.js.map +7 -0
- package/dist/mcp/tool-registry.js +60 -0
- package/dist/mcp/tool-registry.js.map +7 -0
- package/dist/mcp/tools/annotation-create.js +39 -0
- package/dist/mcp/tools/annotation-create.js.map +7 -0
- package/dist/mcp/tools/annotation-delete.js +29 -0
- package/dist/mcp/tools/annotation-delete.js.map +7 -0
- package/dist/mcp/tools/annotation-get.js +29 -0
- package/dist/mcp/tools/annotation-get.js.map +7 -0
- package/dist/mcp/tools/annotation-list.js +24 -0
- package/dist/mcp/tools/annotation-list.js.map +7 -0
- package/dist/mcp/tools/annotation-reply.js +34 -0
- package/dist/mcp/tools/annotation-reply.js.map +7 -0
- package/dist/mcp/tools/annotation-shared.js +10 -0
- package/dist/mcp/tools/annotation-shared.js.map +7 -0
- package/dist/mcp/tools/annotation-update.js +39 -0
- package/dist/mcp/tools/annotation-update.js.map +7 -0
- package/dist/mcp/tools/changeset-analysis-tools.js +78 -0
- package/dist/mcp/tools/changeset-analysis-tools.js.map +7 -0
- package/dist/mcp/tools/changeset-editing.js +184 -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-list.js +33 -0
- package/dist/mcp/tools/changeset-list.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 +55 -0
- package/dist/mcp/tools/changeset-show.js.map +7 -0
- package/dist/mcp/tools/changeset-verify.js +43 -0
- package/dist/mcp/tools/changeset-verify.js.map +7 -0
- package/dist/mcp/tools/chat-launch.js +50 -0
- package/dist/mcp/tools/chat-launch.js.map +7 -0
- package/dist/mcp/tools/chat-status.js +26 -0
- package/dist/mcp/tools/chat-status.js.map +7 -0
- package/dist/mcp/tools/index.js +65 -0
- package/dist/mcp/tools/index.js.map +7 -0
- package/dist/mcp/tools/model-add.js +107 -0
- package/dist/mcp/tools/model-add.js.map +7 -0
- package/dist/mcp/tools/model-delete.js +99 -0
- package/dist/mcp/tools/model-delete.js.map +7 -0
- package/dist/mcp/tools/model-export.js +72 -0
- package/dist/mcp/tools/model-export.js.map +7 -0
- package/dist/mcp/tools/model-info.js +51 -0
- package/dist/mcp/tools/model-info.js.map +7 -0
- package/dist/mcp/tools/model-list.js +53 -0
- package/dist/mcp/tools/model-list.js.map +7 -0
- package/dist/mcp/tools/model-reload.js +34 -0
- package/dist/mcp/tools/model-reload.js.map +7 -0
- package/dist/mcp/tools/model-search.js +102 -0
- package/dist/mcp/tools/model-search.js.map +7 -0
- package/dist/mcp/tools/model-show.js +68 -0
- package/dist/mcp/tools/model-show.js.map +7 -0
- package/dist/mcp/tools/model-stats.js +22 -0
- package/dist/mcp/tools/model-stats.js.map +7 -0
- package/dist/mcp/tools/model-trace.js +118 -0
- package/dist/mcp/tools/model-trace.js.map +7 -0
- package/dist/mcp/tools/model-update.js +121 -0
- package/dist/mcp/tools/model-update.js.map +7 -0
- package/dist/mcp/tools/model-validate.js +78 -0
- package/dist/mcp/tools/model-validate.js.map +7 -0
- package/dist/mcp/tools/relationship-tools.js +98 -0
- package/dist/mcp/tools/relationship-tools.js.map +7 -0
- package/dist/mcp/tools/shared.js +126 -0
- package/dist/mcp/tools/shared.js.map +7 -0
- package/dist/mcp/tools/spec-type.js +90 -0
- package/dist/mcp/tools/spec-type.js.map +7 -0
- package/dist/reports/model-layer-report-generator.js +5 -3
- package/dist/reports/model-layer-report-generator.js.map +2 -2
- package/dist/reports/model-readme-generator.js +116 -0
- package/dist/reports/model-readme-generator.js.map +7 -0
- package/dist/reports/model-report-data.js +37 -1
- package/dist/reports/model-report-data.js.map +2 -2
- package/dist/reports/model-report-orchestrator.js +29 -6
- package/dist/reports/model-report-orchestrator.js.map +2 -2
- package/dist/reports/model-report-utils.js +9 -0
- package/dist/reports/model-report-utils.js.map +7 -0
- package/dist/schemas/bundled/analyzers/cbm.json +1186 -68
- 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 +745 -370
- package/dist/schemas/bundled/base.json +3 -220
- package/dist/schemas/bundled/business.json +452 -366
- package/dist/schemas/bundled/data-model.json +403 -383
- 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 +718 -1643
- 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 +234 -31
- package/dist/server/server.js.map +2 -2
- package/dist/server-entry.js +2 -1
- package/dist/server-entry.js.map +2 -2
- package/dist/telemetry/config.js +2 -40
- package/dist/telemetry/config.js.map +2 -2
- package/dist/telemetry/index.js +1 -1
- package/dist/types/index.js.map +2 -2
- package/dist/utils/ansi-suppressor.js +23 -0
- package/dist/utils/ansi-suppressor.js.map +7 -0
- package/dist/utils/attribute-patch.js +41 -0
- package/dist/utils/attribute-patch.js.map +7 -0
- package/dist/utils/color-utils.js +34 -0
- package/dist/utils/color-utils.js.map +7 -0
- package/dist/utils/element-reference-shape.js +15 -1
- package/dist/utils/element-reference-shape.js.map +3 -3
- package/dist/utils/error-hints.js +29 -0
- package/dist/utils/error-hints.js.map +7 -0
- package/dist/utils/errors.js +75 -10
- package/dist/utils/errors.js.map +2 -2
- package/dist/utils/globals.js +17 -1
- package/dist/utils/globals.js.map +2 -2
- package/dist/utils/project-paths.js +50 -3
- package/dist/utils/project-paths.js.map +2 -2
- package/dist/utils/reference-path-parser.js +49 -0
- package/dist/utils/reference-path-parser.js.map +7 -0
- package/dist/utils/source-reference.js +17 -10
- package/dist/utils/source-reference.js.map +2 -2
- package/dist/utils/spec-version.js +10 -2
- package/dist/utils/spec-version.js.map +2 -2
- package/dist/validators/composed-reference-validator.js +240 -0
- package/dist/validators/composed-reference-validator.js.map +7 -0
- package/dist/validators/reference-validator.js +57 -13
- package/dist/validators/reference-validator.js.map +3 -3
- package/dist/validators/relationship-schema-validator.js +33 -5
- package/dist/validators/relationship-schema-validator.js.map +3 -3
- 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-CxzcuU_o.js +84 -0
- package/dist/viewer/assets/main-j-7ULYpm.css +1 -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 +7 -3
- package/dist/viewer/assets/main-B7AOQXXX.js +0 -81
- package/dist/viewer/assets/main-vdrFrG7q.css +0 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { AnnotationStore } from "../../core/annotation-store.js";
|
|
2
|
+
import { findElementLayer } from "../../utils/element-utils.js";
|
|
3
|
+
import { CLIError, ErrorCategory } from "../../utils/errors.js";
|
|
4
|
+
import { annotationAuthorSchema, annotationContentSchema, annotationTagsSchema, elementIdSchema } from "./annotation-shared.js";
|
|
5
|
+
import { jsonResult, loadModel, rootPathSchema, runTool } from "./shared.js";
|
|
6
|
+
const inputSchema = {
|
|
7
|
+
elementId: elementIdSchema,
|
|
8
|
+
content: annotationContentSchema,
|
|
9
|
+
author: annotationAuthorSchema,
|
|
10
|
+
tags: annotationTagsSchema,
|
|
11
|
+
rootPath: rootPathSchema
|
|
12
|
+
};
|
|
13
|
+
async function annotationCreateHandler(args) {
|
|
14
|
+
return runTool(async () => {
|
|
15
|
+
const model = await loadModel(args.rootPath);
|
|
16
|
+
if (!await findElementLayer(model, args.elementId))
|
|
17
|
+
throw new CLIError(`Element ${args.elementId} not found`, ErrorCategory.NOT_FOUND, [
|
|
18
|
+
'Use "model_search" to find similar elements'
|
|
19
|
+
]);
|
|
20
|
+
const annotation = await new AnnotationStore(model.rootPath).create({
|
|
21
|
+
elementId: args.elementId,
|
|
22
|
+
content: args.content,
|
|
23
|
+
author: args.author,
|
|
24
|
+
tags: args.tags
|
|
25
|
+
});
|
|
26
|
+
return jsonResult(annotation);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const annotationCreateTool = {
|
|
30
|
+
name: "annotation_create",
|
|
31
|
+
description: "Create a new annotation on a model element.",
|
|
32
|
+
inputSchema,
|
|
33
|
+
handler: annotationCreateHandler
|
|
34
|
+
};
|
|
35
|
+
export {
|
|
36
|
+
annotationCreateHandler,
|
|
37
|
+
annotationCreateTool
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=annotation-create.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/tools/annotation-create.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * annotation_create \u2014 create a new annotation on a model element. Mirrors\n * `POST /api/annotations` on the REST server.\n */\n\nimport type { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { AnnotationStore } from \"../../core/annotation-store.js\";\nimport { findElementLayer } from \"../../utils/element-utils.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\nimport {\n annotationAuthorSchema,\n annotationContentSchema,\n annotationTagsSchema,\n elementIdSchema,\n} from \"./annotation-shared.js\";\nimport { jsonResult, loadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n elementId: elementIdSchema,\n content: annotationContentSchema,\n author: annotationAuthorSchema,\n tags: annotationTagsSchema,\n rootPath: rootPathSchema,\n};\n\nexport type AnnotationCreateArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function annotationCreateHandler(args: AnnotationCreateArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n\n const layerName = await findElementLayer(model, args.elementId);\n if (!layerName) {\n throw new CLIError(`Element ${args.elementId} not found`, ErrorCategory.NOT_FOUND, [\n 'Use \"model_search\" to find similar elements',\n ]);\n }\n\n const store = new AnnotationStore(model.rootPath);\n const annotation = await store.create({\n elementId: args.elementId,\n content: args.content,\n author: args.author,\n tags: args.tags,\n });\n\n return jsonResult(annotation);\n });\n}\n\nexport const annotationCreateTool: McpToolDefinition<typeof inputSchema> = {\n name: \"annotation_create\",\n description: \"Create a new annotation on a model element.\",\n inputSchema,\n handler: annotationCreateHandler,\n};\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AACjC,SAAS,UAAU,qBAAqB;AACxC,SACE,wBACA,yBACA,sBACA,uBACK;AACP,SAAS,YAAY,WAAW,gBAAgB,eAAuC;AAEvF,MAAM,cAAc;EAClB,WAAW;EACX,SAAS;EACT,QAAQ;EACR,MAAM;EACN,UAAU;;AAKZ,eAAsB,wBAAwB,MAA0B;AACtE,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ;AAG3C,QAAI,CADc,MAAM,iBAAiB,OAAO,KAAK,SAAS;AAE5D,YAAM,IAAI,SAAS,WAAW,KAAK,SAAS,cAAc,cAAc,WAAW;QACjF;OACD;AAIH,UAAM,aAAa,MADL,IAAI,gBAAgB,MAAM,QAAQ,EACjB,OAAO;MACpC,WAAW,KAAK;MAChB,SAAS,KAAK;MACd,QAAQ,KAAK;MACb,MAAM,KAAK;KACZ;AAED,WAAO,WAAW,UAAU;EAC9B,CAAC;AACH;AAEO,MAAM,uBAA8D;EACzE,MAAM;EACN,aAAa;EACb;EACA,SAAS;;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AnnotationStore } from "../../core/annotation-store.js";
|
|
2
|
+
import { CLIError, ErrorCategory } from "../../utils/errors.js";
|
|
3
|
+
import { annotationIdSchema } from "./annotation-shared.js";
|
|
4
|
+
import { jsonResult, loadModel, rootPathSchema, runTool } from "./shared.js";
|
|
5
|
+
const inputSchema = {
|
|
6
|
+
annotationId: annotationIdSchema,
|
|
7
|
+
rootPath: rootPathSchema
|
|
8
|
+
};
|
|
9
|
+
async function annotationDeleteHandler(args) {
|
|
10
|
+
return runTool(async () => {
|
|
11
|
+
const model = await loadModel(args.rootPath);
|
|
12
|
+
if (!await new AnnotationStore(model.rootPath).delete(args.annotationId))
|
|
13
|
+
throw new CLIError(`Annotation ${args.annotationId} not found`, ErrorCategory.NOT_FOUND, [
|
|
14
|
+
'Use "annotation_list" to find existing annotations'
|
|
15
|
+
]);
|
|
16
|
+
return jsonResult({ status: "deleted", annotationId: args.annotationId });
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
const annotationDeleteTool = {
|
|
20
|
+
name: "annotation_delete",
|
|
21
|
+
description: "Delete an annotation and its replies.",
|
|
22
|
+
inputSchema,
|
|
23
|
+
handler: annotationDeleteHandler
|
|
24
|
+
};
|
|
25
|
+
export {
|
|
26
|
+
annotationDeleteHandler,
|
|
27
|
+
annotationDeleteTool
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=annotation-delete.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/tools/annotation-delete.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * annotation_delete \u2014 delete an annotation and its replies. Mirrors\n * `DELETE /api/annotations/:annotationId` on the REST server.\n */\n\nimport type { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { AnnotationStore } from \"../../core/annotation-store.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\nimport { annotationIdSchema } from \"./annotation-shared.js\";\nimport { jsonResult, loadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n annotationId: annotationIdSchema,\n rootPath: rootPathSchema,\n};\n\nexport type AnnotationDeleteArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function annotationDeleteHandler(args: AnnotationDeleteArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const store = new AnnotationStore(model.rootPath);\n const deleted = await store.delete(args.annotationId);\n\n if (!deleted) {\n throw new CLIError(`Annotation ${args.annotationId} not found`, ErrorCategory.NOT_FOUND, [\n 'Use \"annotation_list\" to find existing annotations',\n ]);\n }\n\n return jsonResult({ status: \"deleted\", annotationId: args.annotationId });\n });\n}\n\nexport const annotationDeleteTool: McpToolDefinition<typeof inputSchema> = {\n name: \"annotation_delete\",\n description: \"Delete an annotation and its replies.\",\n inputSchema,\n handler: annotationDeleteHandler,\n};\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,uBAAuB;AAChC,SAAS,UAAU,qBAAqB;AACxC,SAAS,0BAA0B;AACnC,SAAS,YAAY,WAAW,gBAAgB,eAAuC;AAEvF,MAAM,cAAc;EAClB,cAAc;EACd,UAAU;;AAKZ,eAAsB,wBAAwB,MAA0B;AACtE,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ;AAI3C,QAAI,CAFY,MADF,IAAI,gBAAgB,MAAM,QAAQ,EACpB,OAAO,KAAK,YAAY;AAGlD,YAAM,IAAI,SAAS,cAAc,KAAK,YAAY,cAAc,cAAc,WAAW;QACvF;OACD;AAGH,WAAO,WAAW,EAAE,QAAQ,WAAW,cAAc,KAAK,aAAY,CAAE;EAC1E,CAAC;AACH;AAEO,MAAM,uBAA8D;EACzE,MAAM;EACN,aAAa;EACb;EACA,SAAS;;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AnnotationStore } from "../../core/annotation-store.js";
|
|
2
|
+
import { CLIError, ErrorCategory } from "../../utils/errors.js";
|
|
3
|
+
import { annotationIdSchema } from "./annotation-shared.js";
|
|
4
|
+
import { jsonResult, loadModel, rootPathSchema, runTool } from "./shared.js";
|
|
5
|
+
const inputSchema = {
|
|
6
|
+
annotationId: annotationIdSchema,
|
|
7
|
+
rootPath: rootPathSchema
|
|
8
|
+
};
|
|
9
|
+
async function annotationGetHandler(args) {
|
|
10
|
+
return runTool(async () => {
|
|
11
|
+
const model = await loadModel(args.rootPath), annotation = await new AnnotationStore(model.rootPath).get(args.annotationId);
|
|
12
|
+
if (!annotation)
|
|
13
|
+
throw new CLIError(`Annotation ${args.annotationId} not found`, ErrorCategory.NOT_FOUND, [
|
|
14
|
+
'Use "annotation_list" to find existing annotations'
|
|
15
|
+
]);
|
|
16
|
+
return jsonResult(annotation);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
const annotationGetTool = {
|
|
20
|
+
name: "annotation_get",
|
|
21
|
+
description: "Get a single annotation by ID, including its replies.",
|
|
22
|
+
inputSchema,
|
|
23
|
+
handler: annotationGetHandler
|
|
24
|
+
};
|
|
25
|
+
export {
|
|
26
|
+
annotationGetHandler,
|
|
27
|
+
annotationGetTool
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=annotation-get.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/tools/annotation-get.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * annotation_get \u2014 retrieve a single annotation (with its replies) by ID.\n * Mirrors `GET /api/annotations/:annotationId` on the REST server.\n */\n\nimport type { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { AnnotationStore } from \"../../core/annotation-store.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\nimport { annotationIdSchema } from \"./annotation-shared.js\";\nimport { jsonResult, loadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n annotationId: annotationIdSchema,\n rootPath: rootPathSchema,\n};\n\nexport type AnnotationGetArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function annotationGetHandler(args: AnnotationGetArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const store = new AnnotationStore(model.rootPath);\n const annotation = await store.get(args.annotationId);\n if (!annotation) {\n throw new CLIError(`Annotation ${args.annotationId} not found`, ErrorCategory.NOT_FOUND, [\n 'Use \"annotation_list\" to find existing annotations',\n ]);\n }\n return jsonResult(annotation);\n });\n}\n\nexport const annotationGetTool: McpToolDefinition<typeof inputSchema> = {\n name: \"annotation_get\",\n description: \"Get a single annotation by ID, including its replies.\",\n inputSchema,\n handler: annotationGetHandler,\n};\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,uBAAuB;AAChC,SAAS,UAAU,qBAAqB;AACxC,SAAS,0BAA0B;AACnC,SAAS,YAAY,WAAW,gBAAgB,eAAuC;AAEvF,MAAM,cAAc;EAClB,cAAc;EACd,UAAU;;AAKZ,eAAsB,qBAAqB,MAAuB;AAChE,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GAErC,aAAa,MADL,IAAI,gBAAgB,MAAM,QAAQ,EACjB,IAAI,KAAK,YAAY;AACpD,QAAI,CAAC;AACH,YAAM,IAAI,SAAS,cAAc,KAAK,YAAY,cAAc,cAAc,WAAW;QACvF;OACD;AAEH,WAAO,WAAW,UAAU;EAC9B,CAAC;AACH;AAEO,MAAM,oBAA2D;EACtE,MAAM;EACN,aAAa;EACb;EACA,SAAS;;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { AnnotationStore } from "../../core/annotation-store.js";
|
|
2
|
+
import { elementIdSchema } from "./annotation-shared.js";
|
|
3
|
+
import { jsonResult, loadModel, rootPathSchema, runTool } from "./shared.js";
|
|
4
|
+
const inputSchema = {
|
|
5
|
+
elementId: elementIdSchema.optional().describe("If provided, only return annotations on this element."),
|
|
6
|
+
rootPath: rootPathSchema
|
|
7
|
+
};
|
|
8
|
+
async function annotationListHandler(args) {
|
|
9
|
+
return runTool(async () => {
|
|
10
|
+
const model = await loadModel(args.rootPath), annotations = await new AnnotationStore(model.rootPath).list(args.elementId);
|
|
11
|
+
return jsonResult({ annotations });
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
const annotationListTool = {
|
|
15
|
+
name: "annotation_list",
|
|
16
|
+
description: "List annotations on model elements, optionally filtered to a single element.",
|
|
17
|
+
inputSchema,
|
|
18
|
+
handler: annotationListHandler
|
|
19
|
+
};
|
|
20
|
+
export {
|
|
21
|
+
annotationListHandler,
|
|
22
|
+
annotationListTool
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=annotation-list.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/tools/annotation-list.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * annotation_list \u2014 list annotations, optionally filtered to a single\n * element. Mirrors `GET /api/annotations` on the REST server.\n */\n\nimport type { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { AnnotationStore } from \"../../core/annotation-store.js\";\nimport { elementIdSchema } from \"./annotation-shared.js\";\nimport { jsonResult, loadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n elementId: elementIdSchema.optional().describe(\"If provided, only return annotations on this element.\"),\n rootPath: rootPathSchema,\n};\n\nexport type AnnotationListArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function annotationListHandler(args: AnnotationListArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const store = new AnnotationStore(model.rootPath);\n const annotations = await store.list(args.elementId);\n return jsonResult({ annotations });\n });\n}\n\nexport const annotationListTool: McpToolDefinition<typeof inputSchema> = {\n name: \"annotation_list\",\n description: \"List annotations on model elements, optionally filtered to a single element.\",\n inputSchema,\n handler: annotationListHandler,\n};\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAChC,SAAS,YAAY,WAAW,gBAAgB,eAAuC;AAEvF,MAAM,cAAc;EAClB,WAAW,gBAAgB,SAAQ,EAAG,SAAS,uDAAuD;EACtG,UAAU;;AAKZ,eAAsB,sBAAsB,MAAwB;AAClE,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GAErC,cAAc,MADN,IAAI,gBAAgB,MAAM,QAAQ,EAChB,KAAK,KAAK,SAAS;AACnD,WAAO,WAAW,EAAE,YAAW,CAAE;EACnC,CAAC;AACH;AAEO,MAAM,qBAA4D;EACvE,MAAM;EACN,aAAa;EACb;EACA,SAAS;;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AnnotationStore } from "../../core/annotation-store.js";
|
|
2
|
+
import { CLIError, ErrorCategory } from "../../utils/errors.js";
|
|
3
|
+
import { annotationAuthorSchema, annotationContentSchema, annotationIdSchema } from "./annotation-shared.js";
|
|
4
|
+
import { jsonResult, loadModel, rootPathSchema, runTool } from "./shared.js";
|
|
5
|
+
const inputSchema = {
|
|
6
|
+
annotationId: annotationIdSchema,
|
|
7
|
+
content: annotationContentSchema,
|
|
8
|
+
author: annotationAuthorSchema,
|
|
9
|
+
rootPath: rootPathSchema
|
|
10
|
+
};
|
|
11
|
+
async function annotationReplyHandler(args) {
|
|
12
|
+
return runTool(async () => {
|
|
13
|
+
const model = await loadModel(args.rootPath), reply = await new AnnotationStore(model.rootPath).addReply(args.annotationId, {
|
|
14
|
+
author: args.author?.trim() || "Anonymous",
|
|
15
|
+
content: args.content
|
|
16
|
+
});
|
|
17
|
+
if (!reply)
|
|
18
|
+
throw new CLIError(`Annotation ${args.annotationId} not found`, ErrorCategory.NOT_FOUND, [
|
|
19
|
+
'Use "annotation_list" to find existing annotations'
|
|
20
|
+
]);
|
|
21
|
+
return jsonResult(reply);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
const annotationReplyTool = {
|
|
25
|
+
name: "annotation_reply",
|
|
26
|
+
description: "Add a reply to an existing annotation.",
|
|
27
|
+
inputSchema,
|
|
28
|
+
handler: annotationReplyHandler
|
|
29
|
+
};
|
|
30
|
+
export {
|
|
31
|
+
annotationReplyHandler,
|
|
32
|
+
annotationReplyTool
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=annotation-reply.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/tools/annotation-reply.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * annotation_reply \u2014 add a reply to an annotation. Mirrors\n * `POST /api/annotations/:annotationId/replies` on the REST server.\n */\n\nimport type { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { AnnotationStore } from \"../../core/annotation-store.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\nimport { annotationAuthorSchema, annotationContentSchema, annotationIdSchema } from \"./annotation-shared.js\";\nimport { jsonResult, loadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n annotationId: annotationIdSchema,\n content: annotationContentSchema,\n author: annotationAuthorSchema,\n rootPath: rootPathSchema,\n};\n\nexport type AnnotationReplyArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function annotationReplyHandler(args: AnnotationReplyArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const store = new AnnotationStore(model.rootPath);\n const reply = await store.addReply(args.annotationId, {\n author: args.author?.trim() || \"Anonymous\",\n content: args.content,\n });\n\n if (!reply) {\n throw new CLIError(`Annotation ${args.annotationId} not found`, ErrorCategory.NOT_FOUND, [\n 'Use \"annotation_list\" to find existing annotations',\n ]);\n }\n\n return jsonResult(reply);\n });\n}\n\nexport const annotationReplyTool: McpToolDefinition<typeof inputSchema> = {\n name: \"annotation_reply\",\n description: \"Add a reply to an existing annotation.\",\n inputSchema,\n handler: annotationReplyHandler,\n};\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,uBAAuB;AAChC,SAAS,UAAU,qBAAqB;AACxC,SAAS,wBAAwB,yBAAyB,0BAA0B;AACpF,SAAS,YAAY,WAAW,gBAAgB,eAAuC;AAEvF,MAAM,cAAc;EAClB,cAAc;EACd,SAAS;EACT,QAAQ;EACR,UAAU;;AAKZ,eAAsB,uBAAuB,MAAyB;AACpE,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GAErC,QAAQ,MADA,IAAI,gBAAgB,MAAM,QAAQ,EACtB,SAAS,KAAK,cAAc;MACpD,QAAQ,KAAK,QAAQ,KAAI,KAAM;MAC/B,SAAS,KAAK;KACf;AAED,QAAI,CAAC;AACH,YAAM,IAAI,SAAS,cAAc,KAAK,YAAY,cAAc,cAAc,WAAW;QACvF;OACD;AAGH,WAAO,WAAW,KAAK;EACzB,CAAC;AACH;AAEO,MAAM,sBAA6D;EACxE,MAAM;EACN,aAAa;EACb;EACA,SAAS;;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const annotationIdSchema = z.string().min(1).describe("Annotation ID (e.g. 'ann-1700000000000-a1b2c3d4')."), elementIdSchema = z.string().min(1).describe("Target element ID (e.g. 'api.operation.create-order')."), annotationContentSchema = z.string().min(1, "Content is required").max(5e3, "Content too long (max 5000 characters)"), annotationAuthorSchema = z.string().max(100, "Author name too long (max 100 characters)").optional().describe("Author name. Defaults to 'Anonymous'."), annotationTagsSchema = z.array(z.string()).optional().describe("Tags to attach to the annotation.");
|
|
3
|
+
export {
|
|
4
|
+
annotationAuthorSchema,
|
|
5
|
+
annotationContentSchema,
|
|
6
|
+
annotationIdSchema,
|
|
7
|
+
annotationTagsSchema,
|
|
8
|
+
elementIdSchema
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=annotation-shared.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/tools/annotation-shared.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Shared input field schemas for the annotation_* MCP tools.\n */\n\nimport { z } from \"zod\";\n\nexport const annotationIdSchema = z.string().min(1).describe(\"Annotation ID (e.g. 'ann-1700000000000-a1b2c3d4').\");\n\nexport const elementIdSchema = z\n .string()\n .min(1)\n .describe(\"Target element ID (e.g. 'api.operation.create-order').\");\n\nexport const annotationContentSchema = z\n .string()\n .min(1, \"Content is required\")\n .max(5000, \"Content too long (max 5000 characters)\");\n\nexport const annotationAuthorSchema = z\n .string()\n .max(100, \"Author name too long (max 100 characters)\")\n .optional()\n .describe(\"Author name. Defaults to 'Anonymous'.\");\n\nexport const annotationTagsSchema = z\n .array(z.string())\n .optional()\n .describe(\"Tags to attach to the annotation.\");\n"],
|
|
5
|
+
"mappings": "AAIA,SAAS,SAAS;AAEX,MAAM,qBAAqB,EAAE,OAAM,EAAG,IAAI,CAAC,EAAE,SAAS,oDAAoD,GAEpG,kBAAkB,EAC5B,OAAM,EACN,IAAI,CAAC,EACL,SAAS,wDAAwD,GAEvD,0BAA0B,EACpC,OAAM,EACN,IAAI,GAAG,qBAAqB,EAC5B,IAAI,KAAM,wCAAwC,GAExC,yBAAyB,EACnC,OAAM,EACN,IAAI,KAAK,2CAA2C,EACpD,SAAQ,EACR,SAAS,uCAAuC,GAEtC,uBAAuB,EACjC,MAAM,EAAE,OAAM,CAAE,EAChB,SAAQ,EACR,SAAS,mCAAmC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { AnnotationStore } from "../../core/annotation-store.js";
|
|
3
|
+
import { CLIError, ErrorCategory } from "../../utils/errors.js";
|
|
4
|
+
import { annotationContentSchema, annotationIdSchema, annotationTagsSchema } from "./annotation-shared.js";
|
|
5
|
+
import { jsonResult, loadModel, rootPathSchema, runTool } from "./shared.js";
|
|
6
|
+
const inputSchema = {
|
|
7
|
+
annotationId: annotationIdSchema,
|
|
8
|
+
content: annotationContentSchema.optional(),
|
|
9
|
+
tags: annotationTagsSchema,
|
|
10
|
+
resolved: z.boolean().optional().describe("Mark the annotation resolved or unresolved."),
|
|
11
|
+
rootPath: rootPathSchema
|
|
12
|
+
};
|
|
13
|
+
async function annotationUpdateHandler(args) {
|
|
14
|
+
return runTool(async () => {
|
|
15
|
+
if (args.content === void 0 && args.tags === void 0 && args.resolved === void 0)
|
|
16
|
+
throw new CLIError("At least one of content, tags, or resolved must be provided", ErrorCategory.USER);
|
|
17
|
+
const model = await loadModel(args.rootPath), updated = await new AnnotationStore(model.rootPath).update(args.annotationId, {
|
|
18
|
+
content: args.content,
|
|
19
|
+
tags: args.tags,
|
|
20
|
+
resolved: args.resolved
|
|
21
|
+
});
|
|
22
|
+
if (!updated)
|
|
23
|
+
throw new CLIError(`Annotation ${args.annotationId} not found`, ErrorCategory.NOT_FOUND, [
|
|
24
|
+
'Use "annotation_list" to find existing annotations'
|
|
25
|
+
]);
|
|
26
|
+
return jsonResult(updated);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const annotationUpdateTool = {
|
|
30
|
+
name: "annotation_update",
|
|
31
|
+
description: "Partially update an annotation's content, tags, or resolved state.",
|
|
32
|
+
inputSchema,
|
|
33
|
+
handler: annotationUpdateHandler
|
|
34
|
+
};
|
|
35
|
+
export {
|
|
36
|
+
annotationUpdateHandler,
|
|
37
|
+
annotationUpdateTool
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=annotation-update.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/tools/annotation-update.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * annotation_update \u2014 partially update an annotation's content, tags, or\n * resolved state. Mirrors `PATCH /api/annotations/:annotationId` (and the\n * REST server's equivalently-partial `PUT`) on the REST server.\n */\n\nimport { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { AnnotationStore } from \"../../core/annotation-store.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\nimport { annotationContentSchema, annotationIdSchema, annotationTagsSchema } from \"./annotation-shared.js\";\nimport { jsonResult, loadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n annotationId: annotationIdSchema,\n content: annotationContentSchema.optional(),\n tags: annotationTagsSchema,\n resolved: z.boolean().optional().describe(\"Mark the annotation resolved or unresolved.\"),\n rootPath: rootPathSchema,\n};\n\nexport type AnnotationUpdateArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function annotationUpdateHandler(args: AnnotationUpdateArgs): Promise<CallToolResult> {\n return runTool(async () => {\n if (args.content === undefined && args.tags === undefined && args.resolved === undefined) {\n throw new CLIError(\"At least one of content, tags, or resolved must be provided\", ErrorCategory.USER);\n }\n\n const model = await loadModel(args.rootPath);\n const store = new AnnotationStore(model.rootPath);\n const updated = await store.update(args.annotationId, {\n content: args.content,\n tags: args.tags,\n resolved: args.resolved,\n });\n\n if (!updated) {\n throw new CLIError(`Annotation ${args.annotationId} not found`, ErrorCategory.NOT_FOUND, [\n 'Use \"annotation_list\" to find existing annotations',\n ]);\n }\n\n return jsonResult(updated);\n });\n}\n\nexport const annotationUpdateTool: McpToolDefinition<typeof inputSchema> = {\n name: \"annotation_update\",\n description: \"Partially update an annotation's content, tags, or resolved state.\",\n inputSchema,\n handler: annotationUpdateHandler,\n};\n"],
|
|
5
|
+
"mappings": "AAMA,SAAS,SAAS;AAElB,SAAS,uBAAuB;AAChC,SAAS,UAAU,qBAAqB;AACxC,SAAS,yBAAyB,oBAAoB,4BAA4B;AAClF,SAAS,YAAY,WAAW,gBAAgB,eAAuC;AAEvF,MAAM,cAAc;EAClB,cAAc;EACd,SAAS,wBAAwB,SAAQ;EACzC,MAAM;EACN,UAAU,EAAE,QAAO,EAAG,SAAQ,EAAG,SAAS,6CAA6C;EACvF,UAAU;;AAKZ,eAAsB,wBAAwB,MAA0B;AACtE,SAAO,QAAQ,YAAW;AACxB,QAAI,KAAK,YAAY,UAAa,KAAK,SAAS,UAAa,KAAK,aAAa;AAC7E,YAAM,IAAI,SAAS,+DAA+D,cAAc,IAAI;AAGtG,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GAErC,UAAU,MADF,IAAI,gBAAgB,MAAM,QAAQ,EACpB,OAAO,KAAK,cAAc;MACpD,SAAS,KAAK;MACd,MAAM,KAAK;MACX,UAAU,KAAK;KAChB;AAED,QAAI,CAAC;AACH,YAAM,IAAI,SAAS,cAAc,KAAK,YAAY,cAAc,cAAc,WAAW;QACvF;OACD;AAGH,WAAO,WAAW,OAAO;EAC3B,CAAC;AACH;AAEO,MAAM,uBAA8D;EACzE,MAAM;EACN,aAAa;EACb;EACA,SAAS;;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { AnnotationStore } from "../../core/annotation-store.js";
|
|
3
|
+
import { buildBrief, computeImpact, DEFAULT_HUB_THRESHOLD } from "../../core/changeset-analysis.js";
|
|
4
|
+
import { briefDelta } from "../../core/changeset-brief-delta.js";
|
|
5
|
+
import { describeDrift } from "../../core/changeset-base-index.js";
|
|
6
|
+
import { getErrorMessage } from "../../utils/errors.js";
|
|
7
|
+
import { jsonResult, loadModel, rootPathSchema, runTool } from "./shared.js";
|
|
8
|
+
import { loadChangesetGraph } from "./changeset-shared.js";
|
|
9
|
+
const changesetIdSchema = z.string().optional().describe("Changeset ID or name. Defaults to the active changeset."), impactInputSchema = {
|
|
10
|
+
changesetId: changesetIdSchema,
|
|
11
|
+
depth: z.number().int().min(1).max(6).optional().describe("Hops to walk out from the changed elements (default 2)."),
|
|
12
|
+
maxElements: z.number().int().positive().optional().describe("Stop after this many reached elements (default 200)."),
|
|
13
|
+
from: z.array(z.string()).optional().describe("Element ids or paths to walk from instead of every changed element. Ids the projected model does not have are listed in unknownFrom."),
|
|
14
|
+
hubThreshold: z.number().int().min(0).optional().describe(`An element with more relationships than this is a hub: listed in hubs with its degree and not walked through (default ${DEFAULT_HUB_THRESHOLD}).`),
|
|
15
|
+
expandHubs: z.boolean().optional().describe("Walk through hubs too (default false)."),
|
|
16
|
+
rootPath: rootPathSchema
|
|
17
|
+
};
|
|
18
|
+
async function changesetImpactHandler(args) {
|
|
19
|
+
return runTool(async () => {
|
|
20
|
+
const model = await loadModel(args.rootPath), { changeset, graph } = await loadChangesetGraph(model, args.changesetId), report = computeImpact(graph, {
|
|
21
|
+
depth: args.depth,
|
|
22
|
+
maxElements: args.maxElements,
|
|
23
|
+
from: args.from,
|
|
24
|
+
hubThreshold: args.hubThreshold,
|
|
25
|
+
expandHubs: args.expandHubs
|
|
26
|
+
});
|
|
27
|
+
return jsonResult({ changeset: { id: changeset.id, name: changeset.name }, ...report });
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const changesetImpactTool = {
|
|
31
|
+
name: "changeset_impact",
|
|
32
|
+
description: "Walk the model outward from everything a changeset adds, changes or removes (relationships included), or from the elements named in `from`, and list the existing elements it reaches, by layer, with how each was reached and its source files, plus how many each hop reached (perHop). These are what the change can break or must update. Hubs (elements with more than hubThreshold relationships) are listed with their degree and not walked through unless expandHubs is set.",
|
|
33
|
+
inputSchema: impactInputSchema,
|
|
34
|
+
handler: changesetImpactHandler
|
|
35
|
+
}, briefInputSchema = {
|
|
36
|
+
changesetId: changesetIdSchema,
|
|
37
|
+
unwired: z.enum(["summary", "full", "none"]).optional().describe("Unwired connections (catalog connections an added or updated element has no relationship for): summary (default) counts them per layer and lists the ones in layers the change already reaches whose other type the model has (existing or added), counting the rest as typesNotInModel; full lists them all; none omits them."),
|
|
38
|
+
unwiredLayers: z.array(z.string()).optional().describe("Only show unwired connections whose other end is in these layers (and list them)."),
|
|
39
|
+
since: z.union([z.number().int().min(-1), z.string().regex(/^(-1|\d+):[0-9a-f]+$/, "a revisionToken from a brief")]).optional().describe("A revision (or, better, the revisionToken) an earlier brief returned. Adds a delta: elements added, removed or updated (with the fields), relationships added or removed, changes unstaged, gaps opened and closed, unwired connections wired, layers newly reached or no longer reached, intent newly traced since then. Unstaging does not invalidate it. With the token, the delta warns when a change up to that revision was rewritten in place since."),
|
|
40
|
+
rootPath: rootPathSchema
|
|
41
|
+
};
|
|
42
|
+
async function changesetBriefHandler(args) {
|
|
43
|
+
return runTool(async () => {
|
|
44
|
+
const model = await loadModel(args.rootPath), { manager, changeset, graph } = await loadChangesetGraph(model, args.changesetId), annotations = await new AnnotationStore(model.rootPath).list();
|
|
45
|
+
let drift;
|
|
46
|
+
if (changeset.status === "staged") {
|
|
47
|
+
let hash;
|
|
48
|
+
try {
|
|
49
|
+
hash = await manager.detectDrift(changeset.id);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
hash = { isDrifted: !1, warnings: [`Drift check failed: ${getErrorMessage(error)}`] };
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
drift = await describeDrift(model, graph, hash);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
drift = {
|
|
57
|
+
isDrifted: hash.isDrifted,
|
|
58
|
+
warnings: [...hash.warnings, `Could not name what drifted: ${getErrorMessage(error)}`]
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const brief = buildBrief({ graph, annotations, drift, unwired: args.unwired, unwiredLayers: args.unwiredLayers });
|
|
63
|
+
return args.since === void 0 ? jsonResult(brief, { compact: !0 }) : jsonResult({ ...brief, delta: await briefDelta(model, { graph, brief }, args.since) }, { compact: !0 });
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
const changesetBriefTool = {
|
|
67
|
+
name: "changeset_brief",
|
|
68
|
+
description: "Render a changeset as the spec for its change: every added, updated and deleted element by layer with its connections; which layers the change reaches and which it does not; gaps (unconnected additions, missing required relationships, connections its peers have); unwired connections (every catalog connection an added or updated element has no relationship for, by the other end's layer, with how many elements of the other type exist); changes that trace to no goal, requirement or feature; the source files touched; open review annotations; and how the base drifted since the changeset was created (staged adds the base already has are counted as alreadyInBase, apart from the adds). It returns a revision and a revisionToken: pass the token back as since on the next pass to get what changed. Use it to pressure-test a plan and as the input to building it.",
|
|
69
|
+
inputSchema: briefInputSchema,
|
|
70
|
+
handler: changesetBriefHandler
|
|
71
|
+
};
|
|
72
|
+
export {
|
|
73
|
+
changesetBriefHandler,
|
|
74
|
+
changesetBriefTool,
|
|
75
|
+
changesetImpactHandler,
|
|
76
|
+
changesetImpactTool
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=changeset-analysis-tools.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/tools/changeset-analysis-tools.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * changeset_impact, changeset_brief \u2014 pressure-test a planned change against the model.\n * See `cli/src/core/changeset-analysis.ts` and docs/CHANGE_MODELING.md.\n */\n\nimport { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { AnnotationStore } from \"../../core/annotation-store.js\";\nimport { buildBrief, computeImpact, DEFAULT_HUB_THRESHOLD, type BriefDrift } from \"../../core/changeset-analysis.js\";\nimport { briefDelta } from \"../../core/changeset-brief-delta.js\";\nimport { describeDrift } from \"../../core/changeset-base-index.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { jsonResult, loadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\nimport { loadChangesetGraph } from \"./changeset-shared.js\";\n\nconst changesetIdSchema = z.string().optional().describe(\"Changeset ID or name. Defaults to the active changeset.\");\n\n// ---------------------------------------------------------------------------\n// changeset_impact\n// ---------------------------------------------------------------------------\n\nconst impactInputSchema = {\n changesetId: changesetIdSchema,\n depth: z.number().int().min(1).max(6).optional().describe(\"Hops to walk out from the changed elements (default 2).\"),\n maxElements: z.number().int().positive().optional().describe(\"Stop after this many reached elements (default 200).\"),\n from: z\n .array(z.string())\n .optional()\n .describe(\n \"Element ids or paths to walk from instead of every changed element. Ids the projected model does not have \" +\n \"are listed in unknownFrom.\"\n ),\n hubThreshold: z\n .number()\n .int()\n .min(0)\n .optional()\n .describe(\n `An element with more relationships than this is a hub: listed in hubs with its degree and not walked ` +\n `through (default ${DEFAULT_HUB_THRESHOLD}).`\n ),\n expandHubs: z.boolean().optional().describe(\"Walk through hubs too (default false).\"),\n rootPath: rootPathSchema,\n};\n\nexport type ChangesetImpactArgs = z.infer<z.ZodObject<typeof impactInputSchema>>;\n\nexport async function changesetImpactHandler(args: ChangesetImpactArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const { changeset, graph } = await loadChangesetGraph(model, args.changesetId);\n const report = computeImpact(graph, {\n depth: args.depth,\n maxElements: args.maxElements,\n from: args.from,\n hubThreshold: args.hubThreshold,\n expandHubs: args.expandHubs,\n });\n return jsonResult({ changeset: { id: changeset.id, name: changeset.name }, ...report });\n });\n}\n\nexport const changesetImpactTool: McpToolDefinition<typeof impactInputSchema> = {\n name: \"changeset_impact\",\n description:\n \"Walk the model outward from everything a changeset adds, changes or removes (relationships included), or \" +\n \"from the elements named in `from`, and list the existing elements it reaches, by layer, with how each was \" +\n \"reached and its source files, plus how many each hop reached (perHop). These are what the change can break \" +\n \"or must update. Hubs (elements with more than hubThreshold relationships) are listed with their degree and \" +\n \"not walked through unless expandHubs is set.\",\n inputSchema: impactInputSchema,\n handler: changesetImpactHandler,\n};\n\n// ---------------------------------------------------------------------------\n// changeset_brief\n// ---------------------------------------------------------------------------\n\nconst briefInputSchema = {\n changesetId: changesetIdSchema,\n unwired: z\n .enum([\"summary\", \"full\", \"none\"])\n .optional()\n .describe(\n \"Unwired connections (catalog connections an added or updated element has no relationship for): summary \" +\n \"(default) counts them per layer and lists the ones in layers the change already reaches whose other type \" +\n \"the model has (existing or added), counting the rest as typesNotInModel; full lists them all; none omits them.\"\n ),\n unwiredLayers: z\n .array(z.string())\n .optional()\n .describe(\"Only show unwired connections whose other end is in these layers (and list them).\"),\n since: z\n .union([z.number().int().min(-1), z.string().regex(/^(-1|\\d+):[0-9a-f]+$/, \"a revisionToken from a brief\")])\n .optional()\n .describe(\n \"A revision (or, better, the revisionToken) an earlier brief returned. Adds a delta: elements added, removed \" +\n \"or updated (with the fields), relationships added or removed, changes unstaged, gaps opened and closed, \" +\n \"unwired connections wired, layers newly reached or no longer reached, intent newly traced since then. \" +\n \"Unstaging does not invalidate it. With the token, the delta warns when a change up to that revision was \" +\n \"rewritten in place since.\"\n ),\n rootPath: rootPathSchema,\n};\n\nexport type ChangesetBriefArgs = z.infer<z.ZodObject<typeof briefInputSchema>>;\n\nexport async function changesetBriefHandler(args: ChangesetBriefArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const { manager, changeset, graph } = await loadChangesetGraph(model, args.changesetId);\n\n const annotations = await new AnnotationStore(model.rootPath).list();\n\n let drift: BriefDrift | undefined;\n if (changeset.status === \"staged\") {\n // Each part is reported on failure and the brief goes on: the hash check, then the structured view.\n let hash: { isDrifted: boolean; warnings: string[]; baseSnapshotId?: string; currentSnapshotId?: string };\n try {\n hash = await manager.detectDrift(changeset.id);\n } catch (error) {\n hash = { isDrifted: false, warnings: [`Drift check failed: ${getErrorMessage(error)}`] };\n }\n try {\n drift = await describeDrift(model, graph, hash);\n } catch (error) {\n drift = {\n isDrifted: hash.isDrifted,\n warnings: [...hash.warnings, `Could not name what drifted: ${getErrorMessage(error)}`],\n };\n }\n }\n\n const brief = buildBrief({ graph, annotations, drift, unwired: args.unwired, unwiredLayers: args.unwiredLayers });\n // The brief is the largest result: same JSON, short objects kept on one line.\n if (args.since === undefined) return jsonResult(brief, { compact: true });\n return jsonResult({ ...brief, delta: await briefDelta(model, { graph, brief }, args.since) }, { compact: true });\n });\n}\n\nexport const changesetBriefTool: McpToolDefinition<typeof briefInputSchema> = {\n name: \"changeset_brief\",\n description:\n \"Render a changeset as the spec for its change: every added, updated and deleted element by layer with its \" +\n \"connections; which layers the change reaches and which it does not; gaps (unconnected additions, missing \" +\n \"required relationships, connections its peers have); unwired connections (every catalog connection an added \" +\n \"or updated element has no relationship for, by the other end's layer, with how many elements of the other \" +\n \"type exist); changes that trace to no goal, requirement or feature; the source files touched; open review \" +\n \"annotations; and how the base drifted since the changeset was created (staged adds the base already has are \" +\n \"counted as alreadyInBase, apart from the adds). It returns a revision and a revisionToken: pass the token back \" +\n \"as since on the next pass to get what changed. Use it to pressure-test a plan and as the input to building it.\",\n inputSchema: briefInputSchema,\n handler: changesetBriefHandler,\n};\n"],
|
|
5
|
+
"mappings": "AAKA,SAAS,SAAS;AAElB,SAAS,uBAAuB;AAChC,SAAS,YAAY,eAAe,6BAA8C;AAClF,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,YAAY,WAAW,gBAAgB,eAAuC;AACvF,SAAS,0BAA0B;AAEnC,MAAM,oBAAoB,EAAE,OAAM,EAAG,SAAQ,EAAG,SAAS,yDAAyD,GAM5G,oBAAoB;EACxB,aAAa;EACb,OAAO,EAAE,OAAM,EAAG,IAAG,EAAG,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAQ,EAAG,SAAS,yDAAyD;EACnH,aAAa,EAAE,OAAM,EAAG,IAAG,EAAG,SAAQ,EAAG,SAAQ,EAAG,SAAS,sDAAsD;EACnH,MAAM,EACH,MAAM,EAAE,OAAM,CAAE,EAChB,SAAQ,EACR,SACC,sIAC8B;EAElC,cAAc,EACX,OAAM,EACN,IAAG,EACH,IAAI,CAAC,EACL,SAAQ,EACR,SACC,yHACsB,qBAAqB,IAAI;EAEnD,YAAY,EAAE,QAAO,EAAG,SAAQ,EAAG,SAAS,wCAAwC;EACpF,UAAU;;AAKZ,eAAsB,uBAAuB,MAAyB;AACpE,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GACrC,EAAE,WAAW,MAAK,IAAK,MAAM,mBAAmB,OAAO,KAAK,WAAW,GACvE,SAAS,cAAc,OAAO;MAClC,OAAO,KAAK;MACZ,aAAa,KAAK;MAClB,MAAM,KAAK;MACX,cAAc,KAAK;MACnB,YAAY,KAAK;KAClB;AACD,WAAO,WAAW,EAAE,WAAW,EAAE,IAAI,UAAU,IAAI,MAAM,UAAU,KAAI,GAAI,GAAG,OAAM,CAAE;EACxF,CAAC;AACH;AAEO,MAAM,sBAAmE;EAC9E,MAAM;EACN,aACE;EAKF,aAAa;EACb,SAAS;GAOL,mBAAmB;EACvB,aAAa;EACb,SAAS,EACN,KAAK,CAAC,WAAW,QAAQ,MAAM,CAAC,EAChC,SAAQ,EACR,SACC,gUAEkH;EAEtH,eAAe,EACZ,MAAM,EAAE,OAAM,CAAE,EAChB,SAAQ,EACR,SAAS,mFAAmF;EAC/F,OAAO,EACJ,MAAM,CAAC,EAAE,OAAM,EAAG,IAAG,EAAG,IAAI,EAAE,GAAG,EAAE,OAAM,EAAG,MAAM,wBAAwB,8BAA8B,CAAC,CAAC,EAC1G,SAAQ,EACR,SACC,6bAI6B;EAEjC,UAAU;;AAKZ,eAAsB,sBAAsB,MAAwB;AAClE,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GACrC,EAAE,SAAS,WAAW,MAAK,IAAK,MAAM,mBAAmB,OAAO,KAAK,WAAW,GAEhF,cAAc,MAAM,IAAI,gBAAgB,MAAM,QAAQ,EAAE,KAAI;AAElE,QAAI;AACJ,QAAI,UAAU,WAAW,UAAU;AAEjC,UAAI;AACJ,UAAI;AACF,eAAO,MAAM,QAAQ,YAAY,UAAU,EAAE;MAC/C,SAAS,OAAO;AACd,eAAO,EAAE,WAAW,IAAO,UAAU,CAAC,uBAAuB,gBAAgB,KAAK,CAAC,EAAE,EAAC;MACxF;AACA,UAAI;AACF,gBAAQ,MAAM,cAAc,OAAO,OAAO,IAAI;MAChD,SAAS,OAAO;AACd,gBAAQ;UACN,WAAW,KAAK;UAChB,UAAU,CAAC,GAAG,KAAK,UAAU,gCAAgC,gBAAgB,KAAK,CAAC,EAAE;;MAEzF;IACF;AAEA,UAAM,QAAQ,WAAW,EAAE,OAAO,aAAa,OAAO,SAAS,KAAK,SAAS,eAAe,KAAK,cAAa,CAAE;AAEhH,WAAI,KAAK,UAAU,SAAkB,WAAW,OAAO,EAAE,SAAS,GAAI,CAAE,IACjE,WAAW,EAAE,GAAG,OAAO,OAAO,MAAM,WAAW,OAAO,EAAE,OAAO,MAAK,GAAI,KAAK,KAAK,EAAC,GAAI,EAAE,SAAS,GAAI,CAAE;EACjH,CAAC;AACH;AAEO,MAAM,qBAAiE;EAC5E,MAAM;EACN,aACE;EAQF,aAAa;EACb,SAAS;;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ChangesetGraph } from "../../core/changeset-graph.js";
|
|
3
|
+
import { StagingAreaManager } from "../../core/staging-area.js";
|
|
4
|
+
import { stagedRelationshipChangesAtEnds, stagedRelationshipTriple } from "../../core/relationship-staging.js";
|
|
5
|
+
import { CLIError, ErrorCategory, getErrorMessage } from "../../utils/errors.js";
|
|
6
|
+
import { jsonResult, loadModel, reloadModel, rootPathSchema, runTool } from "./shared.js";
|
|
7
|
+
import { resolveChangeset } from "./changeset-shared.js";
|
|
8
|
+
const changesetIdSchema = z.string().optional().describe("Changeset ID or name. Defaults to the active changeset.");
|
|
9
|
+
function requireStaged(changeset, action) {
|
|
10
|
+
if (changeset.status !== "staged")
|
|
11
|
+
throw new CLIError(`Changeset '${changeset.name}' is ${changeset.status}; cannot ${action}`, ErrorCategory.USER, [
|
|
12
|
+
'Use "changeset_list" to find a staged changeset, or "changeset_create" to start a new one'
|
|
13
|
+
]);
|
|
14
|
+
}
|
|
15
|
+
async function asUserError(fn, suggestions) {
|
|
16
|
+
try {
|
|
17
|
+
return await fn();
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw error instanceof CLIError ? error : new CLIError(getErrorMessage(error), ErrorCategory.USER, suggestions);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function summarize(change) {
|
|
23
|
+
const triple = change.type.startsWith("relationship-") ? stagedRelationshipTriple(change) : null;
|
|
24
|
+
return {
|
|
25
|
+
type: change.type,
|
|
26
|
+
elementId: change.elementId,
|
|
27
|
+
layer: change.layerName,
|
|
28
|
+
...triple ? { relationship: triple } : {}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const updateInputSchema = {
|
|
32
|
+
changesetId: changesetIdSchema,
|
|
33
|
+
name: z.string().min(1).optional().describe("New name. Must not be another changeset's name."),
|
|
34
|
+
description: z.string().optional().describe("New description: the change's intent and what done looks like. An empty string clears it."),
|
|
35
|
+
rootPath: rootPathSchema
|
|
36
|
+
};
|
|
37
|
+
async function changesetUpdateHandler(args) {
|
|
38
|
+
return runTool(async () => {
|
|
39
|
+
if (args.name === void 0 && args.description === void 0)
|
|
40
|
+
throw new CLIError("Nothing to update", ErrorCategory.USER, ['Pass "name" and/or "description"']);
|
|
41
|
+
const model = await loadModel(args.rootPath), manager = new StagingAreaManager(model.rootPath, model), changeset = await resolveChangeset(manager, args.changesetId), updated = await asUserError(() => manager.update(changeset.id, { name: args.name, description: args.description }), ['Use "changeset_list" to see the names already taken']);
|
|
42
|
+
return await reloadModel(args.rootPath), jsonResult({
|
|
43
|
+
id: updated.id,
|
|
44
|
+
name: updated.name,
|
|
45
|
+
...changeset.name !== updated.name ? { previousName: changeset.name } : {},
|
|
46
|
+
description: updated.description ?? null,
|
|
47
|
+
status: updated.status,
|
|
48
|
+
changes: updated.changes.length
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
const changesetUpdateTool = {
|
|
53
|
+
name: "changeset_update",
|
|
54
|
+
description: "Rename a changeset or change its description (the change's intent). Staged changes are untouched. Defaults to the active changeset.",
|
|
55
|
+
inputSchema: updateInputSchema,
|
|
56
|
+
handler: changesetUpdateHandler
|
|
57
|
+
}, unstageInputSchema = {
|
|
58
|
+
changesetId: changesetIdSchema,
|
|
59
|
+
elementId: z.string().optional().describe("Drop every staged change to this element (its add, updates or delete). ID or path."),
|
|
60
|
+
source: z.string().optional().describe("Drop staged relationship changes (adds and deletes) from this element: to target when given, otherwise to any element. The element's own changes are not touched."),
|
|
61
|
+
target: z.string().optional().describe("Drop staged relationship changes (adds and deletes) to this element: from source when given, otherwise from any element. The element's own changes are not touched."),
|
|
62
|
+
predicate: z.string().optional().describe("Only relationship changes with this predicate. Omit for any."),
|
|
63
|
+
keepRelationships: z.boolean().optional().describe("With elementId: keep the staged relationship changes that depend on the element's change. By default, unstaging an element's add also drops staged relationships to it (they would dangle), and unstaging its delete also drops the relationship removals its cascade staged (removals staged before the delete are kept)."),
|
|
64
|
+
rootPath: rootPathSchema
|
|
65
|
+
};
|
|
66
|
+
function describeEnds(args) {
|
|
67
|
+
return args.source && args.target ? `from ${args.source} to ${args.target}` : args.source ? `from ${args.source}` : `to ${args.target}`;
|
|
68
|
+
}
|
|
69
|
+
async function changesetUnstageHandler(args) {
|
|
70
|
+
return runTool(async () => {
|
|
71
|
+
const byElement = args.elementId !== void 0, byRelationship = args.source !== void 0 || args.target !== void 0;
|
|
72
|
+
if (byElement === byRelationship)
|
|
73
|
+
throw new CLIError("Name either an element or a relationship to unstage", ErrorCategory.USER, [
|
|
74
|
+
`Pass "elementId" to drop an element's staged changes`,
|
|
75
|
+
'Or pass "source" and/or "target" (and optionally "predicate") to drop staged relationship changes'
|
|
76
|
+
]);
|
|
77
|
+
if (byRelationship && !args.source && !args.target)
|
|
78
|
+
throw new CLIError('"source" or "target" must not be empty', ErrorCategory.USER);
|
|
79
|
+
const model = await loadModel(args.rootPath), manager = new StagingAreaManager(model.rootPath, model), changeset = await resolveChangeset(manager, args.changesetId);
|
|
80
|
+
requireStaged(changeset, "unstage changes");
|
|
81
|
+
const graph = await ChangesetGraph.build(model, changeset), changes = changeset.changes, keys = /* @__PURE__ */ new Set(), notes = [];
|
|
82
|
+
if (byElement) {
|
|
83
|
+
const element = graph.getElement(args.elementId), ids = /* @__PURE__ */ new Set([args.elementId, ...element ? [element.id, element.uuid ?? element.id] : []]), own = changes.filter((c) => !c.type.startsWith("relationship-") && ids.has(c.elementId));
|
|
84
|
+
for (const change of own)
|
|
85
|
+
keys.add(change.elementId);
|
|
86
|
+
const dependentType = own.some((c) => c.type === "add") ? "relationship-add" : own.some((c) => c.type === "delete") ? "relationship-delete" : null, touching = dependentType ? changes.filter((c) => {
|
|
87
|
+
if (c.type !== dependentType)
|
|
88
|
+
return !1;
|
|
89
|
+
const triple = stagedRelationshipTriple(c);
|
|
90
|
+
return !!triple && (ids.has(triple.source) || ids.has(triple.target) || element && (graph.resolve(triple.source) === element.id || graph.resolve(triple.target) === element.id));
|
|
91
|
+
}) : [], seq = (c) => c.sequenceNumber ?? changes.indexOf(c), deleteSeqs = own.filter((c) => c.type === "delete").map(seq), firstDelete = deleteSeqs.length > 0 ? Math.min(...deleteSeqs) : -1, dependent = dependentType === "relationship-delete" ? touching.filter((c) => seq(c) > firstDelete) : touching, deliberate = touching.filter((c) => !dependent.includes(c));
|
|
92
|
+
if (deliberate.length > 0 && notes.push(`${deliberate.length} relationship removal(s) on ${args.elementId} staged before its delete were kept (${deliberate.map((c) => c.elementId).join(", ")}); unstage them by source and target if they should go too`), dependent.length > 0)
|
|
93
|
+
if (args.keepRelationships)
|
|
94
|
+
notes.push(`${dependent.length} staged relationship change(s) on ${args.elementId} were kept (keepRelationships)` + (dependentType === "relationship-add" ? "; they will dangle unless the element is staged again" : ""));
|
|
95
|
+
else
|
|
96
|
+
for (const change of dependent)
|
|
97
|
+
keys.add(change.elementId);
|
|
98
|
+
} else {
|
|
99
|
+
const matched = stagedRelationshipChangesAtEnds(graph, changeset, {
|
|
100
|
+
source: args.source || void 0,
|
|
101
|
+
target: args.target || void 0,
|
|
102
|
+
predicate: args.predicate
|
|
103
|
+
}), seq = (c) => c.sequenceNumber ?? changes.indexOf(c), deleteSeq = /* @__PURE__ */ new Map();
|
|
104
|
+
for (const change of changes) {
|
|
105
|
+
if (change.type !== "delete")
|
|
106
|
+
continue;
|
|
107
|
+
const id = graph.resolve(change.elementId);
|
|
108
|
+
deleteSeq.set(id, Math.min(deleteSeq.get(id) ?? 1 / 0, seq(change)));
|
|
109
|
+
}
|
|
110
|
+
const deletedEndOf = (change) => {
|
|
111
|
+
if (change.type !== "relationship-delete")
|
|
112
|
+
return;
|
|
113
|
+
const triple = stagedRelationshipTriple(change);
|
|
114
|
+
if (triple)
|
|
115
|
+
return [graph.resolve(triple.source), graph.resolve(triple.target)].find((end) => deleteSeq.has(end) && deleteSeq.get(end) < seq(change));
|
|
116
|
+
}, cascaded = matched.filter((c) => deletedEndOf(c) !== void 0), deletedEnds = [...new Set(cascaded.map((c) => deletedEndOf(c)))].join(", "), cascadeList = cascaded.map((c) => c.elementId).join(", "), bothEnds = !!args.source && !!args.target;
|
|
117
|
+
for (const change of matched)
|
|
118
|
+
!bothEnds && cascaded.includes(change) || keys.add(change.elementId);
|
|
119
|
+
cascaded.length > 0 && bothEnds ? notes.push(`Unstaged ${cascaded.length} relationship removal(s) cascaded from the staged delete of ${deletedEnds} (${cascadeList}): those relationships now dangle, so the changeset will not commit until they are removed again or the delete is unstaged ("changeset_unstage" with elementId)`) : cascaded.length > 0 && notes.push(`Kept ${cascaded.length} relationship removal(s) cascaded from the staged delete of ${deletedEnds} (${cascadeList}): dropping them would leave those relationships dangling. Unstage the delete ("changeset_unstage" with elementId) to restore them, or name both source and target to drop one anyway`);
|
|
120
|
+
}
|
|
121
|
+
const removed = changes.filter((c) => keys.has(c.elementId));
|
|
122
|
+
if (removed.length === 0)
|
|
123
|
+
return jsonResult({
|
|
124
|
+
status: "not-staged",
|
|
125
|
+
changeset: changeset.name,
|
|
126
|
+
message: byElement ? `No staged change to ${args.elementId} in '${changeset.name}'` : `No staged relationship change ${describeEnds(args)}${args.predicate ? ` (${args.predicate})` : ""} in '${changeset.name}'`,
|
|
127
|
+
suggestions: ['Use "changeset_show" to list the staged changes'],
|
|
128
|
+
...notes.length > 0 ? { notes } : {}
|
|
129
|
+
});
|
|
130
|
+
for (const key of keys)
|
|
131
|
+
await manager.unstage(changeset.id, key);
|
|
132
|
+
return await reloadModel(args.rootPath), jsonResult({
|
|
133
|
+
status: "unstaged",
|
|
134
|
+
changeset: changeset.name,
|
|
135
|
+
unstaged: removed.map(summarize),
|
|
136
|
+
remainingChanges: changes.length - removed.length,
|
|
137
|
+
...notes.length > 0 ? { notes } : {}
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const changesetUnstageTool = {
|
|
142
|
+
name: "changeset_unstage",
|
|
143
|
+
description: "Undo part of a staged changeset: drop the staged changes to one element (elementId), or the staged relationship adds/deletes between source and target, or every one from source alone or to target alone (optionally one predicate). The base model is not touched. Defaults to the active changeset. Use changeset_show to see what is staged.",
|
|
144
|
+
inputSchema: unstageInputSchema,
|
|
145
|
+
handler: changesetUnstageHandler
|
|
146
|
+
}, discardInputSchema = {
|
|
147
|
+
changesetId: z.string().describe("Changeset ID or name to discard. Required: discard is never implied."),
|
|
148
|
+
confirm: z.boolean().describe("Must be true. Discarding deletes the changeset's staged changes permanently (only its name, description and a 'discarded' status remain), so confirm only when the plan is to be abandoned."),
|
|
149
|
+
rootPath: rootPathSchema
|
|
150
|
+
};
|
|
151
|
+
async function changesetDiscardHandler(args) {
|
|
152
|
+
return runTool(async () => {
|
|
153
|
+
const model = await loadModel(args.rootPath), manager = new StagingAreaManager(model.rootPath, model), changeset = await resolveChangeset(manager, args.changesetId);
|
|
154
|
+
if (requireStaged(changeset, "discard it"), args.confirm !== !0)
|
|
155
|
+
throw new CLIError(`Discarding '${changeset.name}' deletes its ${changeset.changes.length} staged change(s) permanently`, ErrorCategory.USER, [
|
|
156
|
+
'Pass "confirm": true to discard it',
|
|
157
|
+
'Use "changeset_unstage" to drop individual changes instead',
|
|
158
|
+
'Use "changeset_deactivate" to stop staging into it and keep its changes'
|
|
159
|
+
]);
|
|
160
|
+
const wasActive = await manager.getActiveId() === changeset.id, discardedChanges = changeset.changes.length;
|
|
161
|
+
return await manager.discard(changeset.id), wasActive && await manager.clearActive(), await reloadModel(args.rootPath), jsonResult({
|
|
162
|
+
id: changeset.id,
|
|
163
|
+
name: changeset.name,
|
|
164
|
+
status: "discarded",
|
|
165
|
+
discardedChanges,
|
|
166
|
+
deactivated: wasActive
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
const changesetDiscardTool = {
|
|
171
|
+
name: "changeset_discard",
|
|
172
|
+
description: "Abandon a staged changeset: PERMANENTLY deletes its staged changes and marks it discarded (deactivating it if active). Not recoverable, so it requires confirm: true. The base model is not touched. To undo part of a plan use changeset_unstage; to pause it use changeset_deactivate.",
|
|
173
|
+
inputSchema: discardInputSchema,
|
|
174
|
+
handler: changesetDiscardHandler
|
|
175
|
+
};
|
|
176
|
+
export {
|
|
177
|
+
changesetDiscardHandler,
|
|
178
|
+
changesetDiscardTool,
|
|
179
|
+
changesetUnstageHandler,
|
|
180
|
+
changesetUnstageTool,
|
|
181
|
+
changesetUpdateHandler,
|
|
182
|
+
changesetUpdateTool
|
|
183
|
+
};
|
|
184
|
+
//# sourceMappingURL=changeset-editing.js.map
|