@documentation-robotics/cli 0.2.0 → 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 +36 -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/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 +12 -2
- 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 +167 -0
- package/dist/coding-agents/drbot-mcp.js.map +7 -0
- package/dist/commands/add.js +3 -2
- package/dist/commands/add.js.map +2 -2
- package/dist/commands/analyzer.js +117 -14
- package/dist/commands/analyzer.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 +43 -22
- 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/mcp.js +19 -4
- package/dist/commands/mcp.js.map +2 -2
- package/dist/commands/relationship.js +207 -26
- package/dist/commands/relationship.js.map +2 -2
- package/dist/commands/update.js +42 -23
- 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/version.js +1 -1
- package/dist/commands/visualize.js +4 -3
- package/dist/commands/visualize.js.map +2 -2
- 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 +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 +75 -46
- 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/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 +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 +2236 -7790
- 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 +26 -2
- package/dist/integrations/claude_code/docs/QUICK_START.md +37 -8
- package/dist/integrations/claude_code/docs/README.md +48 -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 +14 -1
- package/dist/mcp/api-key-manager.js.map +2 -2
- package/dist/mcp/changeset-only.js +34 -0
- package/dist/mcp/changeset-only.js.map +7 -0
- package/dist/mcp/tool-registry.js +19 -3
- package/dist/mcp/tool-registry.js.map +2 -2
- 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-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 +43 -0
- package/dist/mcp/tools/changeset-verify.js.map +7 -0
- package/dist/mcp/tools/index.js +19 -1
- package/dist/mcp/tools/index.js.map +2 -2
- package/dist/mcp/tools/model-add.js +6 -5
- 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 +35 -19
- package/dist/mcp/tools/model-update.js.map +2 -2
- 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 +25 -2
- 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/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 +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 +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 +218 -34
- 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/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/project-paths.js +26 -1
- package/dist/utils/project-paths.js.map +2 -2
- package/dist/utils/source-reference.js +14 -12
- 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/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-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 +2 -1
- package/dist/viewer/assets/main-B7AOQXXX.js +0 -81
- package/dist/viewer/assets/main-vdrFrG7q.css +0 -1
|
@@ -2,11 +2,14 @@ import path from "path";
|
|
|
2
2
|
import ansis from "ansis";
|
|
3
3
|
import { StagedChangesetStorage } from "./staged-changeset-storage.js";
|
|
4
4
|
import { BaseSnapshotManager } from "./base-snapshot-manager.js";
|
|
5
|
+
import { withSequenceNumbers } from "./changeset.js";
|
|
5
6
|
import { ChangesetValidator } from "./changeset-validator.js";
|
|
6
7
|
import { fileExists } from "../utils/file-io.js";
|
|
7
8
|
import { createSha256Hash } from "../types/index.js";
|
|
8
9
|
import { getErrorMessage } from "../utils/errors.js";
|
|
9
10
|
import { Layer } from "./layer.js";
|
|
11
|
+
import { canonicalStagedSnapshot } from "./staged-source-reference.js";
|
|
12
|
+
import { elementIdentifiers } from "./relationships.js";
|
|
10
13
|
import { isValidLayerName } from "./layers.js";
|
|
11
14
|
import { isTelemetryEnabled, startSpan, startActiveSpan, endSpan, emitLog, SeverityNumber } from "../telemetry/index.js";
|
|
12
15
|
import { ModelReportOrchestrator } from "../reports/model-report-orchestrator.js";
|
|
@@ -49,7 +52,7 @@ class StagingAreaManager {
|
|
|
49
52
|
* @returns VirtualProjectionEngine instance for computing merged model views
|
|
50
53
|
*/
|
|
51
54
|
async getProjectionEngine() {
|
|
52
|
-
if (!this.projectionEngine) {
|
|
55
|
+
if (!this.projectionEngine && typeof this.model?.getVirtualProjectionEngine == "function" && (this.projectionEngine = this.model.getVirtualProjectionEngine()), !this.projectionEngine) {
|
|
53
56
|
const { VirtualProjectionEngine } = await import("./virtual-projection.js");
|
|
54
57
|
this.projectionEngine = new VirtualProjectionEngine(this.rootPath);
|
|
55
58
|
}
|
|
@@ -62,7 +65,14 @@ class StagingAreaManager {
|
|
|
62
65
|
if (!this.model)
|
|
63
66
|
throw new Error("Model required for creating changesets");
|
|
64
67
|
const id = this.generateChangesetId(), baseSnapshotId = await this.snapshotManager.captureSnapshot(this.model), changeset = await this.storage.create(id, name, description, baseSnapshotId);
|
|
65
|
-
|
|
68
|
+
changeset.id = id, changeset.markStaged(), await this.storage.save(changeset);
|
|
69
|
+
try {
|
|
70
|
+
const { captureBaseIndex, writeBaseIndex } = await import("./changeset-base-index.js");
|
|
71
|
+
await writeBaseIndex(this.rootPath, changeset.id, await captureBaseIndex(this.model));
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.warn(`Warning: could not record the base index for changeset '${name}': ${getErrorMessage(error)}. Verify and brief will fall back to what they can tell without it.`);
|
|
74
|
+
}
|
|
75
|
+
return changeset;
|
|
66
76
|
}
|
|
67
77
|
/**
|
|
68
78
|
* Load a changeset by name or ID
|
|
@@ -91,6 +101,30 @@ class StagingAreaManager {
|
|
|
91
101
|
const activeChangeset = await this.getActive();
|
|
92
102
|
activeChangeset && activeChangeset.id === changeset.id && await this.clearActive(), await this.storage.delete(changeset.id);
|
|
93
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Rename a changeset and/or change its description (its stated intent). Staged changes,
|
|
106
|
+
* status and the active marker are untouched. Names stay unique: renaming to a name another
|
|
107
|
+
* changeset already has is refused.
|
|
108
|
+
*
|
|
109
|
+
* @param nameOrId - Changeset ID or current name
|
|
110
|
+
* @param patch - Fields to change; an empty description clears it
|
|
111
|
+
* @throws Error if the changeset is not found, or the new name is taken
|
|
112
|
+
*/
|
|
113
|
+
async update(nameOrId, patch) {
|
|
114
|
+
const changeset = await this.load(nameOrId);
|
|
115
|
+
if (!changeset || !changeset.id)
|
|
116
|
+
throw new Error(`Changeset '${nameOrId}' not found`);
|
|
117
|
+
if (patch.name !== void 0) {
|
|
118
|
+
const name = patch.name.trim();
|
|
119
|
+
if (!name)
|
|
120
|
+
throw new Error("Changeset name cannot be empty");
|
|
121
|
+
const clash = (await this.storage.list()).find((cs) => cs.name === name && cs.id !== changeset.id);
|
|
122
|
+
if (clash)
|
|
123
|
+
throw new Error(`Another changeset (${clash.id}) is already named '${name}'`);
|
|
124
|
+
patch = { ...patch, name };
|
|
125
|
+
}
|
|
126
|
+
return this.storage.updateMetadata(changeset.id, patch);
|
|
127
|
+
}
|
|
94
128
|
/**
|
|
95
129
|
* Stage a change in the changeset.
|
|
96
130
|
* Records the change in the staging area without applying to the base model.
|
|
@@ -111,7 +145,26 @@ class StagingAreaManager {
|
|
|
111
145
|
...change,
|
|
112
146
|
timestamp: change.timestamp || (/* @__PURE__ */ new Date()).toISOString()
|
|
113
147
|
};
|
|
114
|
-
await this.storage.addChange(changesetId, stagedChange), (await this.getProjectionEngine()).invalidateOnStage(changesetId, change.layerName);
|
|
148
|
+
await this.storage.addChange(changesetId, stagedChange), !change.type.startsWith("relationship-") && typeof this.model?.noteStagedLayer == "function" && this.model.noteStagedLayer(changesetId, change.layerName), (await this.getProjectionEngine()).invalidateOnStage(changesetId, change.layerName);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Rewrite a staged change in place, keeping its sequence number: e.g. to fold an update of an
|
|
152
|
+
* element into the changeset's add of it. The changeset must be in 'staged' status.
|
|
153
|
+
*
|
|
154
|
+
* @param elementId - The key (`elementId`) of the change to rewrite
|
|
155
|
+
* @throws Error if the changeset is not found, not staged, or has no change with that key
|
|
156
|
+
*/
|
|
157
|
+
async restage(changesetId, elementId, change) {
|
|
158
|
+
this.validateChangesetId(changesetId);
|
|
159
|
+
const changeset = await this.load(changesetId);
|
|
160
|
+
if (!changeset)
|
|
161
|
+
throw new Error(`Changeset '${changesetId}' not found`);
|
|
162
|
+
if (changeset.status !== "staged")
|
|
163
|
+
throw new Error(`Cannot change staged changes on changeset with status '${changeset.status}'. Changeset must have status 'staged'.`);
|
|
164
|
+
await this.storage.updateChange(changesetId, elementId, {
|
|
165
|
+
...change,
|
|
166
|
+
timestamp: change.timestamp || (/* @__PURE__ */ new Date()).toISOString()
|
|
167
|
+
}), (await this.getProjectionEngine()).invalidateOnStage(changesetId, change.layerName);
|
|
115
168
|
}
|
|
116
169
|
/**
|
|
117
170
|
* Unstage a specific element from the changeset.
|
|
@@ -144,7 +197,7 @@ class StagingAreaManager {
|
|
|
144
197
|
const changeset = await this.load(changesetId);
|
|
145
198
|
if (!changeset)
|
|
146
199
|
throw new Error(`Changeset '${changesetId}' not found`);
|
|
147
|
-
changeset.changes = [], changeset.status = "discarded", changeset.updateModified(), await this.storage.save(changeset), (await this.getProjectionEngine()).invalidateOnDiscard(changesetId);
|
|
200
|
+
changeset.changes = [], changeset.unstaged = [], changeset.status = "discarded", changeset.updateModified(), await this.storage.save(changeset), (await this.getProjectionEngine()).invalidateOnDiscard(changesetId);
|
|
148
201
|
}
|
|
149
202
|
/**
|
|
150
203
|
* Capture a base snapshot of the current model state for drift detection.
|
|
@@ -251,21 +304,32 @@ class StagingAreaManager {
|
|
|
251
304
|
failed: 0,
|
|
252
305
|
validation: {
|
|
253
306
|
passed: !0,
|
|
254
|
-
errors: []
|
|
307
|
+
errors: [],
|
|
308
|
+
ran: shouldValidate
|
|
255
309
|
}
|
|
256
310
|
};
|
|
257
311
|
if (shouldValidate && await startActiveSpan("staging.validate", async (validationSpan) => {
|
|
258
|
-
const
|
|
259
|
-
if (
|
|
260
|
-
|
|
312
|
+
const report = await this.validator.validateChangesetReport(model, changesetId), validation = report.result;
|
|
313
|
+
if (result.validation.preExistingErrors = report.preExistingErrors.length, report.preExistingErrors.length > 0 && (result.validation.preExistingSample = report.preExistingErrors.slice(0, 10).map((e) => e.message), emitLog(SeverityNumber.WARN, "Pre-existing validation errors not counted against the changeset", {
|
|
314
|
+
"validation.preExistingErrorCount": report.preExistingErrors.length
|
|
315
|
+
})), report.baseValidationFailure && (result.validation.baseValidationFailure = report.baseValidationFailure, emitLog(SeverityNumber.WARN, "Base model could not be validated; every error counts", {
|
|
316
|
+
"validation.baseValidationFailure": report.baseValidationFailure
|
|
317
|
+
})), validationSpan.setAttribute("validation.passed", validation.isValid()), validationSpan.setAttribute("validation.errorCount", validation.errors.length), validationSpan.setAttribute("validation.preExistingErrorCount", report.preExistingErrors.length), validationSpan.setStatus({ code: 0 }), !validation.isValid()) {
|
|
318
|
+
result.validation.passed = !1, result.validation.errors = validation.errors.map((e) => e.message), emitLog(SeverityNumber.ERROR, "Validation failed", {
|
|
261
319
|
"validation.errorCount": result.validation.errors.length,
|
|
262
320
|
"validation.errors": result.validation.errors.slice(0, 10)
|
|
263
321
|
// First 10 errors
|
|
264
|
-
})
|
|
322
|
+
});
|
|
323
|
+
const notes = [];
|
|
324
|
+
throw report.preExistingErrors.length > 0 && notes.push(`${report.preExistingErrors.length} pre-existing error(s) in the base model were not counted against this changeset.`), report.baseValidationFailure && notes.push(`The base model could not be validated (${report.baseValidationFailure}), so every error was counted.`), new Error(`Validation failed with ${result.validation.errors.length} error(s) introduced by this changeset:
|
|
265
325
|
` + result.validation.errors.map((e) => ` - ${e}`).join(`
|
|
266
|
-
`) + `
|
|
326
|
+
`) + (notes.length > 0 ? `
|
|
327
|
+
|
|
328
|
+
${notes.join(`
|
|
329
|
+
`)}` : "") + `
|
|
267
330
|
|
|
268
|
-
Fix these validation errors before committing.`);
|
|
331
|
+
Fix these validation errors before committing, or skip validation with --no-validate.`);
|
|
332
|
+
}
|
|
269
333
|
}), isDryRun)
|
|
270
334
|
return result.committed = changeset.changes.length, drift.isDrifted && (result.driftWarning = drift), result;
|
|
271
335
|
let backup;
|
|
@@ -274,7 +338,8 @@ Fix these validation errors before committing.`);
|
|
|
274
338
|
} catch (backupError) {
|
|
275
339
|
throw new Error(`Failed to create backup before commit. No changes have been applied. ${backupError instanceof Error ? backupError.message : String(backupError)}`);
|
|
276
340
|
}
|
|
277
|
-
const sortedChanges =
|
|
341
|
+
const sortedChanges = withSequenceNumbers(changeset.changes).sort((a, b) => a.sequenceNumber - b.sequenceNumber);
|
|
342
|
+
let relationshipsPurged = !1;
|
|
278
343
|
try {
|
|
279
344
|
const applySpan = isTelemetryEnabled ? startSpan("staging.apply", {
|
|
280
345
|
"apply.changeCount": changeset.changes.length
|
|
@@ -309,19 +374,19 @@ Fix these validation errors before committing.`);
|
|
|
309
374
|
"change.layer": change.layerName
|
|
310
375
|
});
|
|
311
376
|
else {
|
|
312
|
-
const element = new Element(elementData);
|
|
377
|
+
const element = new Element(canonicalStagedSnapshot(elementData).data);
|
|
313
378
|
layer.addElement(element), result.committed++;
|
|
314
379
|
}
|
|
315
380
|
} else if (change.type === "update" && change.after) {
|
|
316
381
|
const element = layer.getElement(change.elementId);
|
|
317
382
|
if (element) {
|
|
318
|
-
const elementData = change.after;
|
|
319
|
-
Object.assign(element, elementData), layer.updateElement(element), result.committed++;
|
|
383
|
+
const { data: elementData, sourceReference } = canonicalStagedSnapshot(change.after);
|
|
384
|
+
Object.assign(element, elementData), sourceReference.present && element.setSourceReference(sourceReference.value), layer.updateElement(element), result.committed++;
|
|
320
385
|
} else
|
|
321
386
|
result.failed++, result.validation.passed = !1, result.validation.errors.push(`Cannot update '${change.elementId}' in '${change.layerName}': element not found in base model`);
|
|
322
387
|
} else if (change.type === "delete") {
|
|
323
|
-
const element = layer.getElement(change.elementId);
|
|
324
|
-
element ? (layer.deleteElement(element.path || element.id), result.committed++) : (result.skipped = (result.skipped ?? 0) + 1, result.skippedDetails = result.skippedDetails ?? [], result.skippedDetails.push(`'${change.elementId}' in '${change.layerName}' not found \u2014 already deleted`));
|
|
388
|
+
const element = layer.getElement(change.elementId), before = change.before ?? {};
|
|
389
|
+
model.relationships.deleteForElement(elementIdentifiers(element ?? before, before.id, before.path, change.elementId)) > 0 && (relationshipsPurged = !0), element ? (layer.deleteElement(element.path || element.id), result.committed++) : (result.skipped = (result.skipped ?? 0) + 1, result.skippedDetails = result.skippedDetails ?? [], result.skippedDetails.push(`'${change.elementId}' in '${change.layerName}' not found \u2014 already deleted`));
|
|
325
390
|
} else
|
|
326
391
|
result.failed++, result.validation.passed = !1, result.validation.errors.push(`Cannot apply change '${change.type}' for '${change.elementId}': missing payload or unrecognised type`);
|
|
327
392
|
} catch (error) {
|
|
@@ -346,7 +411,7 @@ Fix these validation errors before committing.`);
|
|
|
346
411
|
} catch (error) {
|
|
347
412
|
throw new Error(`Failed to save layer '${layerName}': ${getErrorMessage(error)}`);
|
|
348
413
|
}
|
|
349
|
-
if (hasRelationshipChanges)
|
|
414
|
+
if (hasRelationshipChanges || relationshipsPurged)
|
|
350
415
|
try {
|
|
351
416
|
await model.saveRelationships();
|
|
352
417
|
} catch (error) {
|