@documentation-robotics/cli 0.1.12 → 0.2.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 +39 -1
- package/dist/analyzers/verify-engine.js +22 -19
- package/dist/analyzers/verify-engine.js.map +2 -2
- package/dist/cli.js +101 -27
- 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 +122 -0
- package/dist/coding-agents/default-permissions.js.map +7 -0
- package/dist/commands/add.js +10 -6
- package/dist/commands/add.js.map +2 -2
- package/dist/commands/analyzer.js +18 -10
- 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.js +238 -145
- package/dist/commands/changeset.js.map +2 -2
- package/dist/commands/delete.js +45 -18
- 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 +657 -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 +107 -0
- package/dist/commands/mcp.js.map +7 -0
- package/dist/commands/relationship.js +53 -30
- 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 +19 -6
- package/dist/commands/update.js.map +2 -2
- 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/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/farm-manifest.js +134 -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 +159 -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 +55 -1
- package/dist/core/migration-registry.js.map +2 -2
- package/dist/core/model.js +177 -16
- package/dist/core/model.js.map +3 -3
- package/dist/core/virtual-projection.js +1 -0
- package/dist/core/virtual-projection.js.map +2 -2
- package/dist/generated/node-types.js +1 -1
- package/dist/generated/node-types.js.map +2 -2
- package/dist/generated/relationship-index.js +45 -9
- package/dist/generated/relationship-index.js.map +2 -2
- package/dist/integrations/claude_code/docs/MCP_SERVER.md +55 -0
- package/dist/integrations/claude_code/docs/README.md +4 -0
- package/dist/mcp/api-key-manager.js +98 -0
- package/dist/mcp/api-key-manager.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 +44 -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-list.js +33 -0
- package/dist/mcp/tools/changeset-list.js.map +7 -0
- package/dist/mcp/tools/changeset-show.js +39 -0
- package/dist/mcp/tools/changeset-show.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 +47 -0
- package/dist/mcp/tools/index.js.map +7 -0
- package/dist/mcp/tools/model-add.js +106 -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 +88 -0
- package/dist/mcp/tools/model-search.js.map +7 -0
- package/dist/mcp/tools/model-show.js +41 -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 +55 -0
- package/dist/mcp/tools/model-trace.js.map +7 -0
- package/dist/mcp/tools/model-update.js +105 -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/shared.js +103 -0
- package/dist/mcp/tools/shared.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 +2 -2
- package/dist/schemas/bundled/analyzers/manifest.json +2 -2
- package/dist/schemas/bundled/api.json +1 -1
- package/dist/schemas/bundled/apm.json +1 -1
- package/dist/schemas/bundled/application.json +12 -1
- package/dist/schemas/bundled/base.json +1 -1
- package/dist/schemas/bundled/business.json +1 -1
- package/dist/schemas/bundled/data-model.json +38 -2
- package/dist/schemas/bundled/data-store.json +1 -1
- package/dist/schemas/bundled/manifest.json +4 -4
- package/dist/schemas/bundled/motivation.json +1 -1
- package/dist/schemas/bundled/navigation.json +1 -1
- package/dist/schemas/bundled/product.json +1 -1
- package/dist/schemas/bundled/security.json +1 -1
- package/dist/schemas/bundled/technology.json +1 -1
- package/dist/schemas/bundled/testing.json +1 -1
- package/dist/schemas/bundled/ux.json +1 -1
- package/dist/server/server.js +45 -7
- package/dist/server/server.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 +25 -0
- package/dist/utils/ansi-suppressor.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/errors.js +69 -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 +24 -2
- 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 +5 -0
- 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 +262 -0
- package/dist/validators/composed-reference-validator.js.map +7 -0
- package/dist/validators/reference-validator.js +59 -8
- package/dist/validators/reference-validator.js.map +3 -3
- package/dist/validators/relationship-schema-validator.js +30 -2
- package/dist/validators/relationship-schema-validator.js.map +3 -3
- package/dist/viewer/README.md +6 -6
- package/dist/viewer/assets/main-B7AOQXXX.js +81 -0
- package/dist/viewer/assets/main-vdrFrG7q.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 +6 -3
- package/dist/viewer/assets/main-BRPZyc36.css +0 -1
- package/dist/viewer/assets/main-BrpLargo.js +0 -81
|
@@ -7,7 +7,8 @@ import { ValidationFormatter } from "../validators/validation-formatter.js";
|
|
|
7
7
|
import * as prompts from "@clack/prompts";
|
|
8
8
|
import path from "path";
|
|
9
9
|
import { isTelemetryEnabled, startSpan, endSpan, startActiveSpan } from "../telemetry/index.js";
|
|
10
|
-
import { getErrorMessage } from "../utils/errors.js";
|
|
10
|
+
import { getErrorMessage, handleSuccess, handleInfo, handleWarning } from "../utils/errors.js";
|
|
11
|
+
import { isJson } from "../utils/globals.js";
|
|
11
12
|
import { findElementLayer } from "../utils/element-utils.js";
|
|
12
13
|
function generateImportedChangesetId() {
|
|
13
14
|
return `imported-${Date.now()}`;
|
|
@@ -18,8 +19,8 @@ async function changesetCreateCommand(name, options) {
|
|
|
18
19
|
"changeset.hasDescription": !!options.description
|
|
19
20
|
}) : null;
|
|
20
21
|
try {
|
|
21
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model);
|
|
22
|
-
await manager.load(name) && (console.error(ansis.red(`Error: Changeset '${name}' already exists`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset already exists" }), endSpan(span), process.exit(1));
|
|
22
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model);
|
|
23
|
+
await manager.load(name) && (isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: `Changeset '${name}' already exists` })) : console.error(ansis.red(`Error: Changeset '${name}' already exists`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset already exists" }), endSpan(span), process.exit(1));
|
|
23
24
|
let description = options.description;
|
|
24
25
|
if (!description) {
|
|
25
26
|
const isInteractive = process.stdin.isTTY;
|
|
@@ -31,24 +32,30 @@ async function changesetCreateCommand(name, options) {
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
const changeset = await manager.create(name, description || void 0), previouslyActive = await manager.getActiveId();
|
|
34
|
-
if (previouslyActive) {
|
|
35
|
+
if (previouslyActive && !isJson()) {
|
|
35
36
|
const previous = await manager.load(previouslyActive);
|
|
36
37
|
console.log(ansis.yellow(` Deactivating changeset: ${ansis.bold(previous?.name ?? previouslyActive)}`));
|
|
37
38
|
}
|
|
38
|
-
await manager.setActive(changeset.id), isTelemetryEnabled && span && (span.setAttribute("changeset.id", changeset.id), span.setStatus({ code: 0 }))
|
|
39
|
+
await manager.setActive(changeset.id), isTelemetryEnabled && span && (span.setAttribute("changeset.id", changeset.id), span.setStatus({ code: 0 }));
|
|
40
|
+
const createDetails = {
|
|
41
|
+
changesetId: changeset.id,
|
|
42
|
+
changesetName: name,
|
|
43
|
+
path: `documentation-robotics/changesets/${changeset.id}/`
|
|
44
|
+
};
|
|
45
|
+
changeset.description && (createDetails.description = changeset.description), handleSuccess(`Created and activated changeset: ${ansis.bold(name)}`, createDetails, { verbose: !0 });
|
|
39
46
|
} catch (error) {
|
|
40
47
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
41
48
|
code: 2,
|
|
42
49
|
message: getErrorMessage(error)
|
|
43
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
50
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
44
51
|
} finally {
|
|
45
52
|
endSpan(span);
|
|
46
53
|
}
|
|
47
54
|
}
|
|
48
|
-
async function changesetListCommand() {
|
|
55
|
+
async function changesetListCommand(options = {}) {
|
|
49
56
|
const span = isTelemetryEnabled ? startSpan("changeset.list") : null;
|
|
50
57
|
try {
|
|
51
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !0 }), changesets = await new StagingAreaManager(model.rootPath, model).list();
|
|
58
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), changesets = await new StagingAreaManager(model.rootPath, model).list();
|
|
52
59
|
if (isTelemetryEnabled && span && span.setAttribute("changeset.count", changesets.length), changesets.length === 0) {
|
|
53
60
|
console.log(ansis.yellow("No changesets found")), console.log(), isTelemetryEnabled && span && span.setStatus({ code: 0 }), endSpan(span);
|
|
54
61
|
return;
|
|
@@ -71,7 +78,7 @@ Changesets (${changesets.length}):
|
|
|
71
78
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
72
79
|
code: 2,
|
|
73
80
|
message: getErrorMessage(error)
|
|
74
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
81
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
75
82
|
} finally {
|
|
76
83
|
endSpan(span);
|
|
77
84
|
}
|
|
@@ -83,92 +90,122 @@ async function changesetApplyCommand(name, options) {
|
|
|
83
90
|
"apply.force": options?.force === !0
|
|
84
91
|
}) : null;
|
|
85
92
|
try {
|
|
86
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
|
|
87
|
-
changeset || (console.error(ansis.red(`Error: Changeset '${name}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), isTelemetryEnabled && span && (span.setAttribute("changeset.id", changeset.id), span.setAttribute("changeset.changeCount", changeset.changes.length)),
|
|
93
|
+
const model = await Model.load(options?.model || process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
|
|
94
|
+
if (changeset || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Changeset '${name}' not found` })) : console.error(ansis.red(`Error: Changeset '${name}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), isTelemetryEnabled && span && (span.setAttribute("changeset.id", changeset.id), span.setAttribute("changeset.changeCount", changeset.changes.length)), !isJson()) {
|
|
95
|
+
console.log(ansis.bold(`
|
|
88
96
|
Applying changeset: ${ansis.cyan(name)}
|
|
89
97
|
`)), console.log(ansis.dim(`Changes: ${changeset.changes.length}`));
|
|
90
|
-
|
|
91
|
-
|
|
98
|
+
const preApplyStats = ValidationFormatter.calculateStats(model);
|
|
99
|
+
preApplyStats.orphanedElements.length > 0 && console.log(ansis.dim(`Model health before apply: ${preApplyStats.orphanedElements.length} orphaned element(s) \u2014 run 'dr validate --orphans' for details`));
|
|
100
|
+
}
|
|
92
101
|
const changesetId = changeset.id || name;
|
|
93
|
-
|
|
102
|
+
if (!changesetId) {
|
|
103
|
+
const errMsg = "Changeset ID could not be determined";
|
|
104
|
+
isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: errMsg })) : console.error(ansis.red("Error: " + errMsg) + `
|
|
94
105
|
` + ansis.dim("This indicates a corrupted changeset. The changeset exists but has no ID field.") + `
|
|
95
106
|
` + ansis.dim(`Try:
|
|
96
107
|
`) + ansis.dim(` 1. Run 'dr changeset list' to see available changesets
|
|
97
108
|
`) + ansis.dim(` 2. Delete and recreate the changeset if possible
|
|
98
|
-
`) + ansis.dim(" 3. Contact support if this persists")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset ID missing" }), endSpan(span), process.exit(1)
|
|
109
|
+
`) + ansis.dim(" 3. Contact support if this persists")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset ID missing" }), endSpan(span), process.exit(1);
|
|
110
|
+
}
|
|
99
111
|
const result = await manager.apply(model, changesetId, {
|
|
100
112
|
validate: options?.validate,
|
|
101
113
|
force: options?.force
|
|
102
114
|
});
|
|
103
|
-
|
|
104
|
-
|
|
115
|
+
handleInfo(""), isTelemetryEnabled && span && (span.setAttribute("apply.committed", result.committed), span.setAttribute("apply.failed", result.failed), span.setAttribute("apply.validationPassed", result.validation.passed));
|
|
116
|
+
const applyDetails = {
|
|
117
|
+
changesetName: name,
|
|
118
|
+
changesetId: changeset.id,
|
|
119
|
+
committed: result.committed,
|
|
120
|
+
failed: result.failed,
|
|
121
|
+
validationPassed: result.validation.passed
|
|
122
|
+
};
|
|
123
|
+
if (result.failed > 0 && (applyDetails.errors = result.validation.errors, !isJson())) {
|
|
124
|
+
handleInfo(ansis.red(`\u2717 Failed to apply ${result.failed} change(s):`));
|
|
105
125
|
for (const error of result.validation.errors)
|
|
106
|
-
|
|
126
|
+
handleInfo(ansis.dim(` - ${error}`));
|
|
107
127
|
}
|
|
108
|
-
model.manifest.changeset_history || (model.manifest.changeset_history = []), model.manifest.changeset_history.push({
|
|
128
|
+
handleSuccess(`Applied ${result.committed} change(s) from changeset`, applyDetails), model.manifest.changeset_history || (model.manifest.changeset_history = []), model.manifest.changeset_history.push({
|
|
109
129
|
name,
|
|
110
130
|
committed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
111
131
|
action: "committed"
|
|
112
|
-
}), await model.saveDirtyLayers(), await model.saveManifest(), result.failed === 0 &&
|
|
132
|
+
}), await model.saveDirtyLayers(), await model.saveManifest(), result.failed === 0 && handleInfo(ansis.dim("Changeset marked as committed")), isTelemetryEnabled && span && span.setStatus({ code: 0 }), handleInfo("");
|
|
113
133
|
} catch (error) {
|
|
114
134
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
115
135
|
code: 2,
|
|
116
136
|
message: getErrorMessage(error)
|
|
117
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
137
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
118
138
|
} finally {
|
|
119
139
|
endSpan(span);
|
|
120
140
|
}
|
|
121
141
|
}
|
|
122
|
-
async function changesetRevertCommand(name) {
|
|
142
|
+
async function changesetRevertCommand(name, options = {}) {
|
|
123
143
|
const span = isTelemetryEnabled ? startSpan("changeset.revert", {
|
|
124
144
|
"changeset.name": name
|
|
125
145
|
}) : null;
|
|
126
146
|
try {
|
|
127
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
|
|
128
|
-
changeset || (console.error(ansis.red(`Error: Changeset '${name}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), isTelemetryEnabled && span && (span.setAttribute("changeset.id", changeset.id), span.setAttribute("changeset.changeCount", changeset.changes.length)), console.log(ansis.bold(`
|
|
147
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
|
|
148
|
+
changeset || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Changeset '${name}' not found` })) : console.error(ansis.red(`Error: Changeset '${name}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), isTelemetryEnabled && span && (span.setAttribute("changeset.id", changeset.id), span.setAttribute("changeset.changeCount", changeset.changes.length)), isJson() || (console.log(ansis.bold(`
|
|
129
149
|
Reverting changeset: ${ansis.cyan(name)}
|
|
130
|
-
`)), console.log(ansis.dim(`Changes to discard: ${changeset.changes.length}`));
|
|
150
|
+
`)), console.log(ansis.dim(`Changes to discard: ${changeset.changes.length}`)));
|
|
131
151
|
const changesetId = changeset.id || name;
|
|
132
|
-
|
|
152
|
+
if (!changesetId) {
|
|
153
|
+
const errMsg = "Changeset ID could not be determined";
|
|
154
|
+
isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: errMsg })) : console.error(ansis.red("Error: " + errMsg) + `
|
|
155
|
+
` + ansis.dim("The changeset must have an ID to proceed with revert.")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset ID missing" }), endSpan(span), process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
await manager.revert(changesetId), handleInfo(""), handleSuccess(`Reverted changeset: ${name}`, {
|
|
158
|
+
changesetName: name,
|
|
159
|
+
changesetId,
|
|
160
|
+
changesetStatus: "discarded"
|
|
161
|
+
}), isTelemetryEnabled && span && span.setStatus({ code: 0 }), handleInfo("");
|
|
133
162
|
} catch (error) {
|
|
134
163
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
135
164
|
code: 2,
|
|
136
165
|
message: getErrorMessage(error)
|
|
137
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
166
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
138
167
|
} finally {
|
|
139
168
|
endSpan(span);
|
|
140
169
|
}
|
|
141
170
|
}
|
|
142
|
-
async function changesetActivateCommand(name) {
|
|
171
|
+
async function changesetActivateCommand(name, options = {}) {
|
|
143
172
|
const span = isTelemetryEnabled ? startSpan("changeset.activate", {
|
|
144
173
|
"changeset.name": name
|
|
145
174
|
}) : null;
|
|
146
175
|
try {
|
|
147
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !0 });
|
|
148
|
-
|
|
176
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
|
|
177
|
+
changeset || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Changeset '${name}' not found` })) : console.error(ansis.red(`Error: Changeset '${name}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), await manager.setActive(name), handleSuccess(`Activated changeset: ${ansis.bold(name)}`, {
|
|
178
|
+
changesetName: name,
|
|
179
|
+
changesetId: changeset.id
|
|
180
|
+
}), isTelemetryEnabled && span && span.setStatus({ code: 0 });
|
|
149
181
|
} catch (error) {
|
|
150
182
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
151
183
|
code: 2,
|
|
152
184
|
message: getErrorMessage(error)
|
|
153
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
185
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
154
186
|
} finally {
|
|
155
187
|
endSpan(span);
|
|
156
188
|
}
|
|
157
189
|
}
|
|
158
|
-
async function changesetDeactivateCommand() {
|
|
190
|
+
async function changesetDeactivateCommand(options = {}) {
|
|
159
191
|
const span = isTelemetryEnabled ? startSpan("changeset.deactivate") : null;
|
|
160
192
|
try {
|
|
161
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), active = await manager.getActiveId();
|
|
193
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), active = await manager.getActiveId();
|
|
162
194
|
if (!active) {
|
|
163
|
-
|
|
195
|
+
handleInfo(ansis.yellow("No active changeset")), isTelemetryEnabled && span && (span.setAttribute("changeset.wasActive", !1), span.setStatus({ code: 0 })), endSpan(span);
|
|
164
196
|
return;
|
|
165
197
|
}
|
|
166
|
-
isTelemetryEnabled && span && (span.setAttribute("changeset.name", active), span.setAttribute("changeset.wasActive", !0))
|
|
198
|
+
isTelemetryEnabled && span && (span.setAttribute("changeset.name", active), span.setAttribute("changeset.wasActive", !0));
|
|
199
|
+
const changeset = await manager.load(active);
|
|
200
|
+
await manager.clearActive(), handleSuccess(`Deactivated changeset: ${ansis.bold(active)}`, {
|
|
201
|
+
changesetId: active,
|
|
202
|
+
name: changeset?.name || active
|
|
203
|
+
}), isTelemetryEnabled && span && span.setStatus({ code: 0 });
|
|
167
204
|
} catch (error) {
|
|
168
205
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
169
206
|
code: 2,
|
|
170
207
|
message: getErrorMessage(error)
|
|
171
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
208
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
172
209
|
} finally {
|
|
173
210
|
endSpan(span);
|
|
174
211
|
}
|
|
@@ -179,34 +216,39 @@ async function changesetDeleteCommand(name, options) {
|
|
|
179
216
|
"delete.force": options.force === !0
|
|
180
217
|
}) : null;
|
|
181
218
|
try {
|
|
182
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
|
|
183
|
-
if (changeset || (console.error(ansis.red(`Error: Changeset '${name}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), await manager.getActiveId() === changeset.id && (console.error(ansis.red(`Error: Cannot delete active changeset '${name}'`)), console.log(ansis.dim(" Run `dr changeset deactivate` first")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Cannot delete active changeset" }), endSpan(span), process.exit(1)), !options.force) {
|
|
219
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
|
|
220
|
+
if (changeset || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Changeset '${name}' not found` })) : console.error(ansis.red(`Error: Changeset '${name}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), await manager.getActiveId() === changeset.id && (isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: `Cannot delete active changeset '${name}'` })) : (console.error(ansis.red(`Error: Cannot delete active changeset '${name}'`)), console.log(ansis.dim(" Run `dr changeset deactivate` first"))), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Cannot delete active changeset" }), endSpan(span), process.exit(1)), !options.force) {
|
|
184
221
|
const isInteractive = process.stdin.isTTY && process.stdout.isTTY;
|
|
185
222
|
if (isTelemetryEnabled && span && span.setAttribute("cli.interactive", isInteractive), isInteractive) {
|
|
186
223
|
const confirm = await prompts.confirm({
|
|
187
224
|
message: `Delete changeset '${name}'? This cannot be undone.`
|
|
188
225
|
});
|
|
189
226
|
if (!confirm || typeof confirm != "boolean") {
|
|
190
|
-
|
|
227
|
+
handleSuccess("Deletion cancelled", {
|
|
228
|
+
status: "cancelled"
|
|
229
|
+
}), isTelemetryEnabled && span && (span.setAttribute("delete.cancelled", !0), span.setStatus({ code: 0 })), endSpan(span);
|
|
191
230
|
return;
|
|
192
231
|
}
|
|
193
232
|
} else
|
|
194
|
-
console.error(ansis.red("Error: Cannot confirm deletion in non-interactive environment")), console.log(ansis.dim(" Use --force flag to confirm deletion")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Interactive confirmation required" }), endSpan(span), process.exit(1);
|
|
233
|
+
isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: "Cannot confirm deletion in non-interactive environment" })) : (console.error(ansis.red("Error: Cannot confirm deletion in non-interactive environment")), console.log(ansis.dim(" Use --force flag to confirm deletion"))), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Interactive confirmation required" }), endSpan(span), process.exit(1);
|
|
195
234
|
}
|
|
196
|
-
await manager.delete(name),
|
|
235
|
+
await manager.delete(name), handleSuccess(`Deleted changeset: ${ansis.bold(name)}`, {
|
|
236
|
+
changesetName: name,
|
|
237
|
+
changesetId: changeset.id
|
|
238
|
+
}), isTelemetryEnabled && span && span.setStatus({ code: 0 });
|
|
197
239
|
} catch (error) {
|
|
198
240
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
199
241
|
code: 2,
|
|
200
242
|
message: getErrorMessage(error)
|
|
201
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
243
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
202
244
|
} finally {
|
|
203
245
|
endSpan(span);
|
|
204
246
|
}
|
|
205
247
|
}
|
|
206
|
-
async function changesetStatusCommand() {
|
|
248
|
+
async function changesetStatusCommand(options = {}) {
|
|
207
249
|
const span = isTelemetryEnabled ? startSpan("changeset.status") : null;
|
|
208
250
|
try {
|
|
209
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), active = await manager.getActiveId();
|
|
251
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), active = await manager.getActiveId();
|
|
210
252
|
if (!active) {
|
|
211
253
|
console.log(ansis.dim("No active changeset")), isTelemetryEnabled && span && (span.setAttribute("changeset.hasActive", !1), span.setStatus({ code: 0 })), endSpan(span);
|
|
212
254
|
return;
|
|
@@ -225,7 +267,7 @@ async function changesetStatusCommand() {
|
|
|
225
267
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
226
268
|
code: 2,
|
|
227
269
|
message: getErrorMessage(error)
|
|
228
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
270
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
229
271
|
} finally {
|
|
230
272
|
endSpan(span);
|
|
231
273
|
}
|
|
@@ -235,49 +277,65 @@ async function changesetStagedCommand(options) {
|
|
|
235
277
|
"staged.layer": options.layer
|
|
236
278
|
}) : null;
|
|
237
279
|
try {
|
|
238
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangeset = await manager.getActiveId();
|
|
280
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangeset = await manager.getActiveId();
|
|
239
281
|
if (!activeChangeset) {
|
|
240
|
-
console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
|
|
282
|
+
isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: "No active changeset" })) : console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
|
|
241
283
|
return;
|
|
242
284
|
}
|
|
243
285
|
const changeset = await manager.load(activeChangeset);
|
|
244
|
-
changeset || (console.error(ansis.red(`Error: Changeset '${activeChangeset}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1));
|
|
286
|
+
changeset || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Changeset '${activeChangeset}' not found` })) : console.error(ansis.red(`Error: Changeset '${activeChangeset}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1));
|
|
245
287
|
let changes = changeset.changes;
|
|
246
288
|
if (options.layer && (changes = changes.filter((c) => c.layerName === options.layer)), isTelemetryEnabled && span && (span.setAttribute("staged.changeCount", changes.length), span.setAttribute("staged.totalChanges", changeset.changes.length)), changes.length === 0) {
|
|
247
|
-
|
|
289
|
+
handleSuccess("No staged changes", {
|
|
290
|
+
changesetId: activeChangeset,
|
|
291
|
+
changeCount: 0,
|
|
292
|
+
changes: []
|
|
293
|
+
}, { verbose: !0 }), isTelemetryEnabled && span && span.setStatus({ code: 0 }), endSpan(span);
|
|
248
294
|
return;
|
|
249
295
|
}
|
|
250
|
-
|
|
296
|
+
if (!isJson()) {
|
|
297
|
+
console.log(ansis.bold(`
|
|
251
298
|
Staged Changes (${changes.length}):
|
|
252
299
|
`));
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
300
|
+
const tableData = changes.map((c) => ({
|
|
301
|
+
"Element ID": c.elementId,
|
|
302
|
+
Layer: c.layerName,
|
|
303
|
+
Type: c.type,
|
|
304
|
+
Timestamp: new Date(c.timestamp || Date.now()).toISOString()
|
|
305
|
+
}));
|
|
306
|
+
console.table(tableData);
|
|
307
|
+
}
|
|
308
|
+
handleSuccess(`Listed ${changes.length} staged change(s)`, {
|
|
309
|
+
changesetId: activeChangeset,
|
|
310
|
+
changeCount: changes.length,
|
|
311
|
+
changes: changes.map((c) => ({
|
|
312
|
+
elementId: c.elementId,
|
|
313
|
+
layer: c.layerName,
|
|
314
|
+
operation: c.type,
|
|
315
|
+
timestamp: new Date(c.timestamp || Date.now()).toISOString()
|
|
316
|
+
}))
|
|
317
|
+
}), isTelemetryEnabled && span && span.setStatus({ code: 0 });
|
|
260
318
|
} catch (error) {
|
|
261
319
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
262
320
|
code: 2,
|
|
263
321
|
message: getErrorMessage(error)
|
|
264
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
322
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
265
323
|
} finally {
|
|
266
324
|
endSpan(span);
|
|
267
325
|
}
|
|
268
326
|
}
|
|
269
|
-
async function changesetExplicitStageCommand(elementId) {
|
|
327
|
+
async function changesetExplicitStageCommand(elementId, options = {}) {
|
|
270
328
|
const span = isTelemetryEnabled ? startSpan("changeset.stage-explicit", { "stage.elementId": elementId }) : null;
|
|
271
329
|
try {
|
|
272
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
|
|
330
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
|
|
273
331
|
if (!activeChangesetId) {
|
|
274
|
-
console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
|
|
332
|
+
isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: "No active changeset" })) : console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
|
|
275
333
|
return;
|
|
276
334
|
}
|
|
277
335
|
const layerName = await findElementLayer(model, elementId);
|
|
278
|
-
layerName || (console.error(ansis.red(`Error: Element '${elementId}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Element not found" }), endSpan(span), process.exit(1));
|
|
336
|
+
layerName || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Element '${elementId}' not found` })) : console.error(ansis.red(`Error: Element '${elementId}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Element not found" }), endSpan(span), process.exit(1));
|
|
279
337
|
const element = (await model.getLayer(layerName))?.getElement(elementId);
|
|
280
|
-
if (element || (console.error(ansis.red(`Error: Element '${elementId}' not found in layer '${layerName}'`)), endSpan(span), process.exit(1)), (await manager.load(activeChangesetId))?.changes.some((c) => c.elementId === elementId)) {
|
|
338
|
+
if (element || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Element '${elementId}' not found in layer '${layerName}'` })) : console.error(ansis.red(`Error: Element '${elementId}' not found in layer '${layerName}'`)), endSpan(span), process.exit(1)), (await manager.load(activeChangesetId))?.changes.some((c) => c.elementId === elementId)) {
|
|
281
339
|
console.warn(ansis.yellow(`Warning: Element '${elementId}' is already staged in the active changeset. Skipping.`)), endSpan(span);
|
|
282
340
|
return;
|
|
283
341
|
}
|
|
@@ -286,63 +344,74 @@ async function changesetExplicitStageCommand(elementId) {
|
|
|
286
344
|
elementId,
|
|
287
345
|
layerName,
|
|
288
346
|
after: element.toJSON()
|
|
289
|
-
}), isTelemetryEnabled && span && (span.setAttribute("stage.layerName", layerName), span.setStatus({ code: 0 })),
|
|
347
|
+
}), isTelemetryEnabled && span && (span.setAttribute("stage.layerName", layerName), span.setStatus({ code: 0 })), handleSuccess(`Staged element: ${elementId}`, {
|
|
348
|
+
elementId,
|
|
349
|
+
layer: layerName,
|
|
350
|
+
changesetId: activeChangesetId,
|
|
351
|
+
operation: "add"
|
|
352
|
+
}, { verbose: !0 });
|
|
290
353
|
} catch (error) {
|
|
291
|
-
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({ code: 2, message: getErrorMessage(error) })), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
354
|
+
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({ code: 2, message: getErrorMessage(error) })), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
292
355
|
} finally {
|
|
293
356
|
endSpan(span);
|
|
294
357
|
}
|
|
295
358
|
}
|
|
296
|
-
async function changesetUnstageCommand(elementId) {
|
|
359
|
+
async function changesetUnstageCommand(elementId, options = {}) {
|
|
297
360
|
const span = isTelemetryEnabled ? startSpan("changeset.unstage", {
|
|
298
361
|
"unstage.elementId": elementId
|
|
299
362
|
}) : null;
|
|
300
363
|
try {
|
|
301
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
|
|
364
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
|
|
302
365
|
if (!activeChangesetId) {
|
|
303
|
-
console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
|
|
366
|
+
isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: "No active changeset" })) : console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
|
|
304
367
|
return;
|
|
305
368
|
}
|
|
306
369
|
const changeset = await manager.load(activeChangesetId);
|
|
307
|
-
changeset || (console.error(ansis.red(`Error: Changeset '${activeChangesetId}' not found`)), process.exit(1));
|
|
370
|
+
changeset || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Changeset '${activeChangesetId}' not found` })) : console.error(ansis.red(`Error: Changeset '${activeChangesetId}' not found`)), process.exit(1));
|
|
308
371
|
const initialCount = changeset.changes.length;
|
|
309
372
|
await manager.unstage(activeChangesetId, elementId);
|
|
310
373
|
const updated = await manager.load(activeChangesetId);
|
|
311
374
|
if (updated && updated.changes.length === initialCount) {
|
|
312
|
-
|
|
375
|
+
handleWarning(`Element '${elementId}' not found in staged changes`), isTelemetryEnabled && span && (span.setAttribute("unstage.found", !1), span.setStatus({ code: 0 })), endSpan(span);
|
|
313
376
|
return;
|
|
314
377
|
}
|
|
315
|
-
isTelemetryEnabled && span && (span.setAttribute("unstage.found", !0), span.setAttribute("unstage.remainingChanges", updated?.getChangeCount() || 0)),
|
|
378
|
+
isTelemetryEnabled && span && (span.setAttribute("unstage.found", !0), span.setAttribute("unstage.remainingChanges", updated?.getChangeCount() || 0)), handleSuccess(`Unstaged element: ${elementId}`, {
|
|
379
|
+
changesetId: activeChangesetId,
|
|
380
|
+
elementId,
|
|
381
|
+
remainingChanges: updated?.getChangeCount() || 0
|
|
382
|
+
}, { verbose: !0 }), isTelemetryEnabled && span && span.setStatus({ code: 0 });
|
|
316
383
|
} catch (error) {
|
|
317
384
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
318
385
|
code: 2,
|
|
319
386
|
message: getErrorMessage(error)
|
|
320
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
387
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
321
388
|
} finally {
|
|
322
389
|
endSpan(span);
|
|
323
390
|
}
|
|
324
391
|
}
|
|
325
|
-
async function changesetDiscardCommand(elementId) {
|
|
392
|
+
async function changesetDiscardCommand(elementId, options = {}) {
|
|
326
393
|
const span = isTelemetryEnabled ? startSpan("changeset.discard", {
|
|
327
394
|
"discard.elementId": elementId,
|
|
328
395
|
"discard.all": !elementId
|
|
329
396
|
}) : null;
|
|
330
397
|
try {
|
|
331
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
|
|
398
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
|
|
332
399
|
if (!activeChangesetId) {
|
|
333
|
-
console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
|
|
400
|
+
isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: "No active changeset" })) : console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
|
|
334
401
|
return;
|
|
335
402
|
}
|
|
336
403
|
const changeset = await manager.load(activeChangesetId);
|
|
337
|
-
if (changeset || (console.error(ansis.red(`Error: Changeset '${activeChangesetId}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), isTelemetryEnabled && span && span.setAttribute("discard.changeCount", changeset.changes.length), elementId) {
|
|
404
|
+
if (changeset || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Changeset '${activeChangesetId}' not found` })) : console.error(ansis.red(`Error: Changeset '${activeChangesetId}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), isTelemetryEnabled && span && span.setAttribute("discard.changeCount", changeset.changes.length), elementId) {
|
|
338
405
|
const initialCount = changeset.changes.length;
|
|
339
406
|
await manager.unstage(activeChangesetId, elementId);
|
|
340
407
|
const updated = await manager.load(activeChangesetId);
|
|
341
408
|
if (updated && updated.changes.length === initialCount) {
|
|
342
|
-
|
|
409
|
+
handleWarning(`Element '${elementId}' not found in staged changes`), isTelemetryEnabled && span && (span.setAttribute("discard.found", !1), span.setStatus({ code: 0 })), endSpan(span);
|
|
343
410
|
return;
|
|
344
411
|
}
|
|
345
|
-
isTelemetryEnabled && span && span.setAttribute("discard.found", !0),
|
|
412
|
+
isTelemetryEnabled && span && span.setAttribute("discard.found", !0), handleSuccess(`Discarded changes for element: ${elementId}`, {
|
|
413
|
+
elementId
|
|
414
|
+
}, { verbose: !0 });
|
|
346
415
|
} else {
|
|
347
416
|
const isInteractive = process.stdin.isTTY && process.stdout.isTTY;
|
|
348
417
|
if (isTelemetryEnabled && span && span.setAttribute("cli.interactive", isInteractive), isInteractive) {
|
|
@@ -350,19 +419,23 @@ async function changesetDiscardCommand(elementId) {
|
|
|
350
419
|
message: `Discard all ${changeset.changes.length} staged changes? This cannot be undone.`
|
|
351
420
|
});
|
|
352
421
|
if (!confirmed || typeof confirmed != "boolean") {
|
|
353
|
-
|
|
422
|
+
handleSuccess("Discard cancelled", {
|
|
423
|
+
status: "cancelled"
|
|
424
|
+
}), isTelemetryEnabled && span && (span.setAttribute("discard.cancelled", !0), span.setStatus({ code: 0 })), endSpan(span);
|
|
354
425
|
return;
|
|
355
426
|
}
|
|
356
427
|
} else
|
|
357
428
|
console.error(ansis.red("Error: Cannot confirm discard of all changes in non-interactive environment")), console.log(ansis.dim(" Specify an element ID to discard only that element")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Interactive confirmation required" }), endSpan(span), process.exit(1);
|
|
358
|
-
await manager.discard(activeChangesetId),
|
|
429
|
+
await manager.discard(activeChangesetId), handleSuccess("Discarded all staged changes", {
|
|
430
|
+
changesetStatus: "discarded"
|
|
431
|
+
}, { verbose: !0 });
|
|
359
432
|
}
|
|
360
|
-
isTelemetryEnabled && span && span.setStatus({ code: 0 }), console.log();
|
|
433
|
+
isTelemetryEnabled && span && span.setStatus({ code: 0 }), isJson() || console.log();
|
|
361
434
|
} catch (error) {
|
|
362
435
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
363
436
|
code: 2,
|
|
364
437
|
message: getErrorMessage(error)
|
|
365
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
438
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
366
439
|
} finally {
|
|
367
440
|
endSpan(span);
|
|
368
441
|
}
|
|
@@ -372,7 +445,7 @@ async function changesetPreviewCommand(options) {
|
|
|
372
445
|
"preview.layer": options.layer
|
|
373
446
|
}) : null;
|
|
374
447
|
try {
|
|
375
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
|
|
448
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
|
|
376
449
|
if (!activeChangesetId) {
|
|
377
450
|
console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
|
|
378
451
|
return;
|
|
@@ -425,7 +498,7 @@ async function changesetDiffCommand(options) {
|
|
|
425
498
|
"diff.layer": options.layer
|
|
426
499
|
}) : null;
|
|
427
500
|
try {
|
|
428
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
|
|
501
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
|
|
429
502
|
if (!activeChangesetId) {
|
|
430
503
|
console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
|
|
431
504
|
return;
|
|
@@ -463,48 +536,52 @@ Diff: Base Model vs Staged Changes
|
|
|
463
536
|
async function changesetCommitCommand(options) {
|
|
464
537
|
await startActiveSpan("changeset.commit", async (span) => {
|
|
465
538
|
try {
|
|
466
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !1 }), stagingManager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await stagingManager.getActiveId();
|
|
539
|
+
const model = await Model.load(options?.model || process.cwd(), { lazyLoad: !1 }), stagingManager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await stagingManager.getActiveId();
|
|
467
540
|
if (!activeChangesetId) {
|
|
468
|
-
console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span.setStatus({ code: 2, message: "No active changeset" });
|
|
541
|
+
isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: "No active changeset" })) : console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span.setStatus({ code: 2, message: "No active changeset" });
|
|
469
542
|
return;
|
|
470
543
|
}
|
|
471
544
|
const changeset = await stagingManager.load(activeChangesetId);
|
|
472
|
-
changeset || (console.error(ansis.red(`Error: Changeset '${activeChangesetId}' not found`)), isTelemetryEnabled && span.setStatus({ code: 2, message: "Changeset not found" }), span.end(), process.exit(1));
|
|
545
|
+
changeset || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Changeset '${activeChangesetId}' not found` })) : console.error(ansis.red(`Error: Changeset '${activeChangesetId}' not found`)), isTelemetryEnabled && span.setStatus({ code: 2, message: "Changeset not found" }), span.end(), process.exit(1));
|
|
473
546
|
const changeCount = changeset.changes.length;
|
|
474
547
|
if (isTelemetryEnabled && (span.setAttribute("changeset.id", activeChangesetId), span.setAttribute("changeset.name", changeset.name), span.setAttribute("changeset.changeCount", changeCount)), changeCount === 0) {
|
|
475
|
-
|
|
548
|
+
handleSuccess("No staged changes to commit", {
|
|
549
|
+
name: changeset.name,
|
|
550
|
+
changesetId: activeChangesetId,
|
|
551
|
+
stagedChanges: 0
|
|
552
|
+
}, { verbose: !0 }), isTelemetryEnabled && span.setStatus({ code: 0 });
|
|
476
553
|
return;
|
|
477
554
|
}
|
|
478
|
-
console.log(ansis.bold(`
|
|
479
|
-
Committing changeset: ${ansis.cyan(changeset.name)}`)), console.log(ansis.dim(`Staged changes: ${changeCount}`)), console.log();
|
|
555
|
+
isJson() || (console.log(ansis.bold(`
|
|
556
|
+
Committing changeset: ${ansis.cyan(changeset.name)}`)), console.log(ansis.dim(`Staged changes: ${changeCount}`)), console.log());
|
|
480
557
|
try {
|
|
481
558
|
const result = await stagingManager.commit(model, activeChangesetId, {
|
|
482
559
|
validate: options?.validate !== !1,
|
|
483
560
|
force: options?.force === !0
|
|
484
561
|
});
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
}
|
|
493
|
-
|
|
562
|
+
await stagingManager.clearActive(), isTelemetryEnabled && (span.setAttribute("commit.committed", result.committed), span.setAttribute("commit.skipped", result.skipped), span.setAttribute("commit.failed", result.failed), span.setAttribute("commit.validationPassed", result.validation.passed));
|
|
563
|
+
const commitDetails = {
|
|
564
|
+
name: changeset.name,
|
|
565
|
+
changesetId: activeChangesetId,
|
|
566
|
+
committedCount: result.committed,
|
|
567
|
+
stagedChanges: changeCount,
|
|
568
|
+
validationPassed: result.validation.passed
|
|
569
|
+
};
|
|
570
|
+
(result.skipped ?? 0) > 0 && (commitDetails.skipped = result.skipped, commitDetails.skippedDetails = (result.skippedDetails ?? []).slice(0, 10)), result.failed > 0 && (commitDetails.failed = result.failed);
|
|
494
571
|
const accountedFor = result.committed + (result.skipped ?? 0) + result.failed;
|
|
495
572
|
if (accountedFor < changeCount) {
|
|
496
573
|
const unaccounted = changeCount - accountedFor;
|
|
497
|
-
console.log(ansis.yellow(`\u26A0 Warning: ${unaccounted} staged change(s) were not applied, skipped, or reported as failed. This is unexpected \u2014 check the changeset log for details.`));
|
|
574
|
+
commitDetails.unaccountedChanges = unaccounted, isJson() || console.log(ansis.yellow(`\u26A0 Warning: ${unaccounted} staged change(s) were not applied, skipped, or reported as failed. This is unexpected \u2014 check the changeset log for details.`));
|
|
498
575
|
}
|
|
499
|
-
result.driftWarning && (console.log(ansis.yellow("\u26A0 Warning: Model had drifted since changeset creation (--force was used)")), isTelemetryEnabled && span.setAttribute("commit.driftDetected", !0)), isTelemetryEnabled && span.setStatus({ code: 0 }), console.log();
|
|
576
|
+
result.driftWarning && (commitDetails.driftDetected = !0, isJson() || console.log(ansis.yellow("\u26A0 Warning: Model had drifted since changeset creation (--force was used)")), isTelemetryEnabled && span.setAttribute("commit.driftDetected", !0)), isTelemetryEnabled && span.setStatus({ code: 0 }), handleSuccess(`Committed ${result.committed} change(s)`, commitDetails, { verbose: !0 }), isJson() || console.log();
|
|
500
577
|
} catch (error) {
|
|
501
|
-
throw console.log(ansis.red(`\u2717 Commit failed and rolled back: ${getErrorMessage(error)}`)), isTelemetryEnabled && span.setAttribute("commit.rolledBack", !0), error;
|
|
578
|
+
throw isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: `Commit failed and rolled back: ${getErrorMessage(error)}` })) : console.log(ansis.red(`\u2717 Commit failed and rolled back: ${getErrorMessage(error)}`)), isTelemetryEnabled && span.setAttribute("commit.rolledBack", !0), error;
|
|
502
579
|
}
|
|
503
580
|
} catch (error) {
|
|
504
581
|
isTelemetryEnabled && (span.recordException(error), span.setStatus({
|
|
505
582
|
code: 2,
|
|
506
583
|
message: getErrorMessage(error)
|
|
507
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), span.end(), process.exit(1);
|
|
584
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), span.end(), process.exit(1);
|
|
508
585
|
}
|
|
509
586
|
}, {
|
|
510
587
|
"commit.validate": options?.validate !== !1,
|
|
@@ -517,13 +594,17 @@ async function changesetExportCommand(changesetId, options) {
|
|
|
517
594
|
"export.format": format
|
|
518
595
|
}) : null;
|
|
519
596
|
try {
|
|
520
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !0 }), exporter = new ChangesetExporter(model.rootPath), ext = format === "patch" ? "patch" : format, outputPath = options.output || `${changesetId}.${ext}`, absolutePath = path.isAbsolute(outputPath) ? outputPath : path.join(process.cwd(), outputPath);
|
|
521
|
-
isTelemetryEnabled && span && span.setAttribute("export.outputPath", outputPath), await exporter.exportToFile(changesetId, absolutePath, format),
|
|
597
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), exporter = new ChangesetExporter(model.rootPath), ext = format === "patch" ? "patch" : format, outputPath = options.output || `${changesetId}.${ext}`, absolutePath = path.isAbsolute(outputPath) ? outputPath : path.join(process.cwd(), outputPath);
|
|
598
|
+
isTelemetryEnabled && span && span.setAttribute("export.outputPath", outputPath), await exporter.exportToFile(changesetId, absolutePath, format), handleSuccess(`Exported changeset to ${outputPath}`, {
|
|
599
|
+
changesetId,
|
|
600
|
+
outputPath,
|
|
601
|
+
format
|
|
602
|
+
}, { verbose: !0 }), isTelemetryEnabled && span && span.setStatus({ code: 0 });
|
|
522
603
|
} catch (error) {
|
|
523
604
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
524
605
|
code: 2,
|
|
525
606
|
message: getErrorMessage(error)
|
|
526
|
-
})), console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
607
|
+
})), isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: getErrorMessage(error) })) : console.error(ansis.red(`Error: ${getErrorMessage(error)}`)), endSpan(span), process.exit(1);
|
|
527
608
|
} finally {
|
|
528
609
|
endSpan(span);
|
|
529
610
|
}
|
|
@@ -534,23 +615,35 @@ async function changesetImportCommand(file, options = {}) {
|
|
|
534
615
|
"import.force": options.force === !0
|
|
535
616
|
}) : null;
|
|
536
617
|
try {
|
|
537
|
-
const model = await Model.load(process.cwd(), { lazyLoad: !1 }), exporter = new ChangesetExporter(model.rootPath), absolutePath = path.isAbsolute(file) ? file : path.join(process.cwd(), file), imported = await exporter.importFromFile(absolutePath);
|
|
618
|
+
const model = await Model.load(options.model || process.cwd(), { lazyLoad: !1 }), exporter = new ChangesetExporter(model.rootPath), absolutePath = path.isAbsolute(file) ? file : path.join(process.cwd(), file), imported = await exporter.importFromFile(absolutePath);
|
|
538
619
|
isTelemetryEnabled && span && (span.setAttribute("changeset.name", imported.name), span.setAttribute("changeset.changeCount", imported.changes.length));
|
|
539
620
|
const compatibility = await exporter.validateCompatibility(imported, model);
|
|
540
621
|
if (isTelemetryEnabled && span && (span.setAttribute("import.compatible", compatibility.compatible), span.setAttribute("import.baseSnapshotMatch", compatibility.baseSnapshotMatch)), !compatibility.compatible) {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
622
|
+
if (isJson())
|
|
623
|
+
console.log(JSON.stringify({ status: "error", code: 1, message: "Changeset is incompatible", warnings: compatibility.warnings }));
|
|
624
|
+
else {
|
|
625
|
+
console.error(ansis.red("\u2717 Import failed: Changeset is incompatible")), console.error(ansis.dim(" Issues:"));
|
|
626
|
+
for (const warning of compatibility.warnings)
|
|
627
|
+
console.error(ansis.dim(` - ${warning}`));
|
|
628
|
+
}
|
|
544
629
|
isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset incompatible" }), endSpan(span), process.exit(1);
|
|
545
630
|
}
|
|
546
|
-
compatibility.baseSnapshotMatch || (options.force || (console.error(ansis.red("Error: Imported changeset has base model drift") + `
|
|
631
|
+
compatibility.baseSnapshotMatch || (options.force || (isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: "Imported changeset has base model drift" })) : console.error(ansis.red("Error: Imported changeset has base model drift") + `
|
|
547
632
|
` + ansis.dim("The model has been modified since this changeset was created.") + `
|
|
548
633
|
` + ansis.dim("This may cause conflicts or unexpected behavior when committing.") + `
|
|
549
634
|
|
|
550
635
|
` + ansis.dim("To import anyway, use: --force")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Drift detected, force required" }), endSpan(span), process.exit(1)), console.warn(ansis.yellow("\u26A0 Warning: Base model drift detected (--force used)") + `
|
|
551
636
|
` + ansis.dim("Review changes carefully before committing.")), console.log(), isTelemetryEnabled && span && span.setAttribute("import.driftOverridden", !0));
|
|
552
637
|
const newId = generateImportedChangesetId();
|
|
553
|
-
imported.id = newId, await new StagedChangesetStorage(model.rootPath).save(imported)
|
|
638
|
+
imported.id = newId, await new StagedChangesetStorage(model.rootPath).save(imported);
|
|
639
|
+
const importDetails = {
|
|
640
|
+
changesetName: imported.name,
|
|
641
|
+
changesetId: newId,
|
|
642
|
+
additions: imported.stats?.additions || 0,
|
|
643
|
+
modifications: imported.stats?.modifications || 0,
|
|
644
|
+
deletions: imported.stats?.deletions || 0
|
|
645
|
+
};
|
|
646
|
+
compatibility.baseSnapshotMatch || (importDetails.driftDetected = !0), handleSuccess(`Imported changeset: ${imported.name}`, importDetails, { verbose: !0 }), isTelemetryEnabled && span && (span.setAttribute("changeset.id", newId), span.setStatus({ code: 0 }));
|
|
554
647
|
} catch (error) {
|
|
555
648
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
|
|
556
649
|
code: 2,
|
|
@@ -562,37 +655,37 @@ async function changesetImportCommand(file, options = {}) {
|
|
|
562
655
|
}
|
|
563
656
|
function changesetCommands(program) {
|
|
564
657
|
const changesetGroup = program.command("changeset").description("Manage changesets");
|
|
565
|
-
changesetGroup.command("create <name>").description("Create a new changeset").option("--description <desc>", "Changeset description").addHelpText("after", `
|
|
658
|
+
changesetGroup.command("create <name>").description("Create a new changeset").option("--model <path>", "Path to model root (contains model/manifest.yaml)").option("--description <desc>", "Changeset description").addHelpText("after", `
|
|
566
659
|
Examples:
|
|
567
660
|
$ dr changeset create "v1.1 migration"
|
|
568
661
|
$ dr changeset create "api-refactoring" --description "Refactor API layer endpoints"`).action(async (name, options) => {
|
|
569
662
|
await changesetCreateCommand(name, options);
|
|
570
|
-
}), changesetGroup.command("list").description("List all changesets").addHelpText("after", `
|
|
663
|
+
}), changesetGroup.command("list").description("List all changesets").option("--model <path>", "Path to model root (contains model/manifest.yaml)").addHelpText("after", `
|
|
571
664
|
Examples:
|
|
572
|
-
$ dr changeset list`).action(async () => {
|
|
573
|
-
await changesetListCommand();
|
|
574
|
-
}), changesetGroup.command("apply <name>").description("Apply a changeset to the model").option("--no-validate", "Skip validation before applying").option("--force", "Force apply even if base model has drifted").addHelpText("after", `
|
|
665
|
+
$ dr changeset list`).action(async (options) => {
|
|
666
|
+
await changesetListCommand(options);
|
|
667
|
+
}), changesetGroup.command("apply <name>").description("Apply a changeset to the model").option("--model <path>", "Path to model root (contains model/manifest.yaml)").option("--no-validate", "Skip validation before applying").option("--force", "Force apply even if base model has drifted").addHelpText("after", `
|
|
575
668
|
Examples:
|
|
576
669
|
$ dr changeset apply "v1.1 migration"
|
|
577
670
|
$ dr changeset apply "v1.1 migration" --no-validate
|
|
578
671
|
$ dr changeset apply "v1.1 migration" --force`).action(async (name, options) => {
|
|
579
672
|
await changesetApplyCommand(name, options);
|
|
580
|
-
}), changesetGroup.command("revert <name>").description("Revert a changeset from the model").addHelpText("after", `
|
|
673
|
+
}), changesetGroup.command("revert <name>").description("Revert a changeset from the model").option("--model <path>", "Path to model root (contains model/manifest.yaml)").addHelpText("after", `
|
|
581
674
|
Examples:
|
|
582
|
-
$ dr changeset revert "v1.1 migration"`).action(async (name) => {
|
|
583
|
-
await changesetRevertCommand(name);
|
|
584
|
-
}), changesetGroup.command("activate <name>").description("Activate a changeset for automatic change tracking").addHelpText("after", `
|
|
675
|
+
$ dr changeset revert "v1.1 migration"`).action(async (name, options) => {
|
|
676
|
+
await changesetRevertCommand(name, options);
|
|
677
|
+
}), changesetGroup.command("activate <name>").description("Activate a changeset for automatic change tracking").option("--model <path>", "Path to model root (contains model/manifest.yaml)").addHelpText("after", `
|
|
585
678
|
Examples:
|
|
586
|
-
$ dr changeset activate "v1.1 migration"`).action(async (name) => {
|
|
587
|
-
await changesetActivateCommand(name);
|
|
588
|
-
}), changesetGroup.command("deactivate").description("Deactivate the currently active changeset").addHelpText("after", `
|
|
679
|
+
$ dr changeset activate "v1.1 migration"`).action(async (name, options) => {
|
|
680
|
+
await changesetActivateCommand(name, options);
|
|
681
|
+
}), changesetGroup.command("deactivate").description("Deactivate the currently active changeset").option("--model <path>", "Path to model root (contains model/manifest.yaml)").addHelpText("after", `
|
|
589
682
|
Examples:
|
|
590
|
-
$ dr changeset deactivate`).action(async () => {
|
|
591
|
-
await changesetDeactivateCommand();
|
|
592
|
-
}), changesetGroup.command("status").description("Show the currently active changeset").addHelpText("after", `
|
|
683
|
+
$ dr changeset deactivate`).action(async (options) => {
|
|
684
|
+
await changesetDeactivateCommand(options);
|
|
685
|
+
}), changesetGroup.command("status").description("Show the currently active changeset").option("--model <path>", "Path to model root (contains model/manifest.yaml)").addHelpText("after", `
|
|
593
686
|
Examples:
|
|
594
|
-
$ dr changeset status`).action(async () => {
|
|
595
|
-
await changesetStatusCommand();
|
|
687
|
+
$ dr changeset status`).action(async (options) => {
|
|
688
|
+
await changesetStatusCommand(options);
|
|
596
689
|
}), changesetGroup.command("show [name]").description("Show changeset details (use: status, staged, diff, or preview)").addHelpText("after", `
|
|
597
690
|
To inspect a changeset, use one of:
|
|
598
691
|
$ dr changeset status # Show the active changeset
|
|
@@ -607,54 +700,54 @@ To inspect a changeset, use one of:
|
|
|
607
700
|
dr changeset staged \u2014 list all staged changes
|
|
608
701
|
dr changeset diff \u2014 show a diff of staged changes
|
|
609
702
|
dr changeset preview \u2014 preview what will be committed`), process.exit(1);
|
|
610
|
-
}), changesetGroup.command("delete <name>").description("Delete a changeset permanently").option("-f, --force", "Skip confirmation prompt").addHelpText("after", `
|
|
703
|
+
}), changesetGroup.command("delete <name>").description("Delete a changeset permanently").option("--model <path>", "Path to model root (contains model/manifest.yaml)").option("-f, --force", "Skip confirmation prompt").addHelpText("after", `
|
|
611
704
|
Examples:
|
|
612
705
|
$ dr changeset delete my-feature
|
|
613
706
|
$ dr changeset delete my-feature --force`).action(async (name, options) => {
|
|
614
707
|
await changesetDeleteCommand(name, options);
|
|
615
|
-
}), changesetGroup.command("staged").description("List all staged changes in the active changeset").option("-l, --layer <layer>", "Filter by layer name").addHelpText("after", `
|
|
708
|
+
}), changesetGroup.command("staged").description("List all staged changes in the active changeset").option("--model <path>", "Path to model root (contains model/manifest.yaml)").option("-l, --layer <layer>", "Filter by layer name").addHelpText("after", `
|
|
616
709
|
Examples:
|
|
617
710
|
$ dr changeset staged
|
|
618
711
|
$ dr changeset staged --layer api`).action(async (options) => {
|
|
619
712
|
await changesetStagedCommand(options);
|
|
620
|
-
}), changesetGroup.command("stage <element-id>").description("Stage a specific element into the active changeset").addHelpText("after", `
|
|
713
|
+
}), changesetGroup.command("stage <element-id>").description("Stage a specific element into the active changeset").option("--model <path>", "Path to model root (contains model/manifest.yaml)").addHelpText("after", `
|
|
621
714
|
Examples:
|
|
622
715
|
$ dr changeset stage api.operation.get-users
|
|
623
|
-
$ dr changeset stage ux.uicomponent.login-form`).action(async (elementId) => {
|
|
624
|
-
await changesetExplicitStageCommand(elementId);
|
|
625
|
-
}), changesetGroup.command("unstage <element-id>").description("Remove specific element from staging area").addHelpText("after", `
|
|
716
|
+
$ dr changeset stage ux.uicomponent.login-form`).action(async (elementId, options) => {
|
|
717
|
+
await changesetExplicitStageCommand(elementId, options);
|
|
718
|
+
}), changesetGroup.command("unstage <element-id>").description("Remove specific element from staging area").option("--model <path>", "Path to model root (contains model/manifest.yaml)").addHelpText("after", `
|
|
626
719
|
Examples:
|
|
627
|
-
$ dr changeset unstage api-endpoint-create-customer`).action(async (elementId) => {
|
|
628
|
-
await changesetUnstageCommand(elementId);
|
|
629
|
-
}), changesetGroup.command("discard [element-id]").description("Discard all or single staged changes").addHelpText("after", `
|
|
720
|
+
$ dr changeset unstage api-endpoint-create-customer`).action(async (elementId, options) => {
|
|
721
|
+
await changesetUnstageCommand(elementId, options);
|
|
722
|
+
}), changesetGroup.command("discard [element-id]").description("Discard all or single staged changes").option("--model <path>", "Path to model root (contains model/manifest.yaml)").addHelpText("after", `
|
|
630
723
|
Examples:
|
|
631
724
|
$ dr changeset discard
|
|
632
|
-
$ dr changeset discard api-endpoint-create-customer`).action(async (elementId) => {
|
|
633
|
-
await changesetDiscardCommand(elementId);
|
|
634
|
-
}), changesetGroup.command("preview").description("Preview the merged model state with staged changes applied").option("-l, --layer <layer>", "Preview specific layer only").addHelpText("after", `
|
|
725
|
+
$ dr changeset discard api-endpoint-create-customer`).action(async (elementId, options) => {
|
|
726
|
+
await changesetDiscardCommand(elementId, options);
|
|
727
|
+
}), changesetGroup.command("preview").description("Preview the merged model state with staged changes applied").option("--model <path>", "Path to model root (contains model/manifest.yaml)").option("-l, --layer <layer>", "Preview specific layer only").addHelpText("after", `
|
|
635
728
|
Examples:
|
|
636
729
|
$ dr changeset preview
|
|
637
730
|
$ dr changeset preview --layer application`).action(async (options) => {
|
|
638
731
|
await changesetPreviewCommand(options);
|
|
639
|
-
}), changesetGroup.command("diff").description("Show delta between base model and staged changes").option("-l, --layer <layer>", "Show diff for specific layer only").addHelpText("after", `
|
|
732
|
+
}), changesetGroup.command("diff").description("Show delta between base model and staged changes").option("--model <path>", "Path to model root (contains model/manifest.yaml)").option("-l, --layer <layer>", "Show diff for specific layer only").addHelpText("after", `
|
|
640
733
|
Examples:
|
|
641
734
|
$ dr changeset diff
|
|
642
735
|
$ dr changeset diff --layer api`).action(async (options) => {
|
|
643
736
|
await changesetDiffCommand(options);
|
|
644
|
-
}), changesetGroup.command("commit").description("Apply staged changes to the base model").option("--validate", "Run validation before commit (default: true)", !0).option("--force", "Commit despite drift warnings", !1).addHelpText("after", `
|
|
737
|
+
}), changesetGroup.command("commit").description("Apply staged changes to the base model").option("--model <path>", "Path to model root (contains model/manifest.yaml)").option("--validate", "Run validation before commit (default: true)", !0).option("--force", "Commit despite drift warnings", !1).addHelpText("after", `
|
|
645
738
|
Examples:
|
|
646
739
|
$ dr changeset commit
|
|
647
740
|
$ dr changeset commit --validate
|
|
648
741
|
$ dr changeset commit --force`).action(async (options) => {
|
|
649
742
|
await changesetCommitCommand(options);
|
|
650
|
-
}), changesetGroup.command("export <changeset-id>").description("Export changeset to portable file").option("-o, --output <file>", "Output file path").option("-f, --format <format>", "Export format (yaml|json|patch)", "yaml").addHelpText("after", `
|
|
743
|
+
}), changesetGroup.command("export <changeset-id>").description("Export changeset to portable file").option("--model <path>", "Path to model root (contains model/manifest.yaml)").option("-o, --output <file>", "Output file path").option("-f, --format <format>", "Export format (yaml|json|patch)", "yaml").addHelpText("after", `
|
|
651
744
|
Examples:
|
|
652
745
|
$ dr changeset export api-updates
|
|
653
746
|
$ dr changeset export api-updates --output changes.yaml
|
|
654
747
|
$ dr changeset export api-updates --format json --output changes.json
|
|
655
748
|
$ dr changeset export api-updates --format patch --output changes.patch`).action(async (changesetId, options) => {
|
|
656
749
|
await changesetExportCommand(changesetId, options);
|
|
657
|
-
}), changesetGroup.command("import <file>").description("Import changeset from file").option("-f, --force", "Import despite base model drift", !1).addHelpText("after", `
|
|
750
|
+
}), changesetGroup.command("import <file>").description("Import changeset from file").option("--model <path>", "Path to model root (contains model/manifest.yaml)").option("-f, --force", "Import despite base model drift", !1).addHelpText("after", `
|
|
658
751
|
Examples:
|
|
659
752
|
$ dr changeset import changes.yaml
|
|
660
753
|
$ dr changeset import ../team-changes.json
|