chainlesschain 0.51.0 → 0.66.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/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AppLayout-Rvi759IS.js → AppLayout-6SPt_8Y_.js} +1 -1
- package/src/assets/web-panel/assets/{Dashboard-DBhFxXYQ.js → Dashboard-Br7kCwKJ.js} +2 -2
- package/src/assets/web-panel/assets/Dashboard-CKeMmCoT.css +1 -0
- package/src/assets/web-panel/assets/{index-uL0cZ8N_.js → index-tN-8TosE.js} +2 -2
- package/src/assets/web-panel/index.html +2 -2
- package/src/commands/agent-network.js +785 -0
- package/src/commands/automation.js +654 -0
- package/src/commands/dao.js +565 -0
- package/src/commands/did-v2.js +620 -0
- package/src/commands/economy.js +578 -0
- package/src/commands/evolution.js +391 -0
- package/src/commands/hmemory.js +442 -0
- package/src/commands/perf.js +433 -0
- package/src/commands/pipeline.js +449 -0
- package/src/commands/plugin-ecosystem.js +517 -0
- package/src/commands/sandbox.js +401 -0
- package/src/commands/social.js +311 -0
- package/src/commands/sso.js +798 -0
- package/src/commands/workflow.js +320 -0
- package/src/commands/zkp.js +227 -1
- package/src/index.js +21 -0
- package/src/lib/agent-economy.js +479 -0
- package/src/lib/agent-network.js +1121 -0
- package/src/lib/automation-engine.js +948 -0
- package/src/lib/dao-governance.js +569 -0
- package/src/lib/did-v2-manager.js +1127 -0
- package/src/lib/evolution-system.js +453 -0
- package/src/lib/hierarchical-memory.js +481 -0
- package/src/lib/perf-tuning.js +734 -0
- package/src/lib/pipeline-orchestrator.js +928 -0
- package/src/lib/plugin-ecosystem.js +1109 -0
- package/src/lib/sandbox-v2.js +306 -0
- package/src/lib/social-graph-analytics.js +707 -0
- package/src/lib/sso-manager.js +841 -0
- package/src/lib/workflow-engine.js +454 -1
- package/src/lib/zkp-engine.js +249 -20
- package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +0 -1
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cc pipeline` — CLI port of Phase 26 开发流水线编排.
|
|
3
|
+
*
|
|
4
|
+
* 7-stage pipeline (需求→架构→代码→测试→审查→部署→监控) with 4
|
|
5
|
+
* templates (feature / bugfix / refactor / security-audit) and 6
|
|
6
|
+
* deployment strategies. Gate approval at code-review & deploy stages.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { Command } from "commander";
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
PIPELINE_STATUS,
|
|
13
|
+
STAGE_STATUS,
|
|
14
|
+
DEPLOY_STRATEGY,
|
|
15
|
+
DEPLOY_STATUS,
|
|
16
|
+
ARTIFACT_TYPE,
|
|
17
|
+
ensurePipelineTables,
|
|
18
|
+
createPipeline,
|
|
19
|
+
startPipeline,
|
|
20
|
+
pausePipeline,
|
|
21
|
+
resumePipeline,
|
|
22
|
+
cancelPipeline,
|
|
23
|
+
completeStage,
|
|
24
|
+
failStage,
|
|
25
|
+
retryStage,
|
|
26
|
+
approveGate,
|
|
27
|
+
rejectGate,
|
|
28
|
+
addArtifact,
|
|
29
|
+
listArtifacts,
|
|
30
|
+
getPipeline,
|
|
31
|
+
listPipelines,
|
|
32
|
+
getStage,
|
|
33
|
+
getTemplates,
|
|
34
|
+
getConfig,
|
|
35
|
+
recordDeploy,
|
|
36
|
+
getDeploy,
|
|
37
|
+
listDeploys,
|
|
38
|
+
rollbackDeploy,
|
|
39
|
+
recordMonitorEvent,
|
|
40
|
+
listMonitorEvents,
|
|
41
|
+
getMonitorStatus,
|
|
42
|
+
exportPipeline,
|
|
43
|
+
getStats,
|
|
44
|
+
} from "../lib/pipeline-orchestrator.js";
|
|
45
|
+
|
|
46
|
+
function _dbFromCtx(cmd) {
|
|
47
|
+
const root = cmd?.parent?.parent ?? cmd?.parent;
|
|
48
|
+
return root?._db;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function _json(v) {
|
|
52
|
+
console.log(JSON.stringify(v, null, 2));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function _parseJsonArg(s, fallback) {
|
|
56
|
+
if (s == null) return fallback;
|
|
57
|
+
try {
|
|
58
|
+
return JSON.parse(s);
|
|
59
|
+
} catch {
|
|
60
|
+
return fallback;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function registerPipelineCommand(program) {
|
|
65
|
+
const pipeline = new Command("pipeline")
|
|
66
|
+
.alias("pipe")
|
|
67
|
+
.description(
|
|
68
|
+
"Development Pipeline Orchestration (Phase 26) — 7-stage AI dev pipeline + gates + deploys",
|
|
69
|
+
)
|
|
70
|
+
.hook("preAction", (thisCmd) => {
|
|
71
|
+
const db = _dbFromCtx(thisCmd);
|
|
72
|
+
if (db) ensurePipelineTables(db);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
/* ── Catalogs ────────────────────────────────────── */
|
|
76
|
+
|
|
77
|
+
pipeline
|
|
78
|
+
.command("config")
|
|
79
|
+
.description("Show pipeline system config (stages, statuses, strategies)")
|
|
80
|
+
.action(() => _json(getConfig()));
|
|
81
|
+
|
|
82
|
+
pipeline
|
|
83
|
+
.command("templates")
|
|
84
|
+
.description(
|
|
85
|
+
"List project templates (feature / bugfix / refactor / security-audit)",
|
|
86
|
+
)
|
|
87
|
+
.action(() => _json(getTemplates()));
|
|
88
|
+
|
|
89
|
+
pipeline
|
|
90
|
+
.command("stages")
|
|
91
|
+
.description("List all 7 pipeline stage names")
|
|
92
|
+
.action(() => _json(getConfig().stages));
|
|
93
|
+
|
|
94
|
+
pipeline
|
|
95
|
+
.command("deploy-strategies")
|
|
96
|
+
.description("List 6 deployment strategies")
|
|
97
|
+
.action(() => _json(Object.values(DEPLOY_STRATEGY)));
|
|
98
|
+
|
|
99
|
+
pipeline
|
|
100
|
+
.command("statuses")
|
|
101
|
+
.description("List pipeline + stage status values")
|
|
102
|
+
.action(() =>
|
|
103
|
+
_json({
|
|
104
|
+
pipeline: Object.values(PIPELINE_STATUS),
|
|
105
|
+
stage: Object.values(STAGE_STATUS),
|
|
106
|
+
deploy: Object.values(DEPLOY_STATUS),
|
|
107
|
+
}),
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
/* ── Pipeline lifecycle ──────────────────────────── */
|
|
111
|
+
|
|
112
|
+
pipeline
|
|
113
|
+
.command("create")
|
|
114
|
+
.description("Create a new pipeline from a template")
|
|
115
|
+
.requiredOption(
|
|
116
|
+
"-t, --template <name>",
|
|
117
|
+
"Template (feature/bugfix/refactor/security-audit)",
|
|
118
|
+
)
|
|
119
|
+
.option("-n, --name <name>", "Pipeline display name")
|
|
120
|
+
.option("-c, --config <json>", "Pipeline config as JSON")
|
|
121
|
+
.action((opts, cmd) => {
|
|
122
|
+
const db = _dbFromCtx(cmd);
|
|
123
|
+
if (!db) return console.error("No database");
|
|
124
|
+
const p = createPipeline(db, {
|
|
125
|
+
template: opts.template,
|
|
126
|
+
name: opts.name || null,
|
|
127
|
+
config: _parseJsonArg(opts.config, {}),
|
|
128
|
+
});
|
|
129
|
+
_json(p);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
pipeline
|
|
133
|
+
.command("start <pipelineId>")
|
|
134
|
+
.description("Start pipeline execution (advances to first stage)")
|
|
135
|
+
.action((pipelineId, _opts, cmd) => {
|
|
136
|
+
const db = _dbFromCtx(cmd);
|
|
137
|
+
if (!db) return console.error("No database");
|
|
138
|
+
_json(startPipeline(db, pipelineId));
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
pipeline
|
|
142
|
+
.command("pause <pipelineId>")
|
|
143
|
+
.description("Pause running pipeline")
|
|
144
|
+
.action((pipelineId, _opts, cmd) => {
|
|
145
|
+
const db = _dbFromCtx(cmd);
|
|
146
|
+
if (!db) return console.error("No database");
|
|
147
|
+
_json(pausePipeline(db, pipelineId));
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
pipeline
|
|
151
|
+
.command("resume <pipelineId>")
|
|
152
|
+
.description("Resume paused pipeline")
|
|
153
|
+
.action((pipelineId, _opts, cmd) => {
|
|
154
|
+
const db = _dbFromCtx(cmd);
|
|
155
|
+
if (!db) return console.error("No database");
|
|
156
|
+
_json(resumePipeline(db, pipelineId));
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
pipeline
|
|
160
|
+
.command("cancel <pipelineId>")
|
|
161
|
+
.description("Cancel pipeline")
|
|
162
|
+
.option("-r, --reason <text>", "Cancellation reason")
|
|
163
|
+
.action((pipelineId, opts, cmd) => {
|
|
164
|
+
const db = _dbFromCtx(cmd);
|
|
165
|
+
if (!db) return console.error("No database");
|
|
166
|
+
_json(cancelPipeline(db, pipelineId, opts.reason || "cancelled by user"));
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
/* ── Stage execution ─────────────────────────────── */
|
|
170
|
+
|
|
171
|
+
pipeline
|
|
172
|
+
.command("complete <pipelineId>")
|
|
173
|
+
.description("Complete current stage with output and advance")
|
|
174
|
+
.option("-o, --output <json>", "Stage output as JSON")
|
|
175
|
+
.option("-a, --artifacts <json>", "Artifacts array as JSON")
|
|
176
|
+
.action((pipelineId, opts, cmd) => {
|
|
177
|
+
const db = _dbFromCtx(cmd);
|
|
178
|
+
if (!db) return console.error("No database");
|
|
179
|
+
_json(
|
|
180
|
+
completeStage(db, pipelineId, {
|
|
181
|
+
output: _parseJsonArg(opts.output, null),
|
|
182
|
+
artifacts: _parseJsonArg(opts.artifacts, []),
|
|
183
|
+
}),
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
pipeline
|
|
188
|
+
.command("fail <pipelineId>")
|
|
189
|
+
.description("Fail current stage and pipeline")
|
|
190
|
+
.option("-e, --error <message>", "Error message")
|
|
191
|
+
.action((pipelineId, opts, cmd) => {
|
|
192
|
+
const db = _dbFromCtx(cmd);
|
|
193
|
+
if (!db) return console.error("No database");
|
|
194
|
+
_json(failStage(db, pipelineId, opts.error || "stage failed"));
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
pipeline
|
|
198
|
+
.command("retry <pipelineId>")
|
|
199
|
+
.description("Retry a specific stage (reset to running)")
|
|
200
|
+
.requiredOption("-s, --stage <index>", "Stage index (0-based)", (v) =>
|
|
201
|
+
parseInt(v, 10),
|
|
202
|
+
)
|
|
203
|
+
.action((pipelineId, opts, cmd) => {
|
|
204
|
+
const db = _dbFromCtx(cmd);
|
|
205
|
+
if (!db) return console.error("No database");
|
|
206
|
+
_json(retryStage(db, pipelineId, opts.stage));
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
/* ── Gate approval ───────────────────────────────── */
|
|
210
|
+
|
|
211
|
+
pipeline
|
|
212
|
+
.command("approve <pipelineId>")
|
|
213
|
+
.description("Approve current gate (code-review / deploy)")
|
|
214
|
+
.action((pipelineId, _opts, cmd) => {
|
|
215
|
+
const db = _dbFromCtx(cmd);
|
|
216
|
+
if (!db) return console.error("No database");
|
|
217
|
+
_json(approveGate(db, pipelineId));
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
pipeline
|
|
221
|
+
.command("reject <pipelineId>")
|
|
222
|
+
.description("Reject current gate (fails the pipeline)")
|
|
223
|
+
.option("-r, --reason <text>", "Rejection reason")
|
|
224
|
+
.action((pipelineId, opts, cmd) => {
|
|
225
|
+
const db = _dbFromCtx(cmd);
|
|
226
|
+
if (!db) return console.error("No database");
|
|
227
|
+
_json(rejectGate(db, pipelineId, opts.reason || "gate rejected"));
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
/* ── Artifacts ───────────────────────────────────── */
|
|
231
|
+
|
|
232
|
+
pipeline
|
|
233
|
+
.command("artifact-add <pipelineId>")
|
|
234
|
+
.description("Add an artifact to a stage")
|
|
235
|
+
.requiredOption("-s, --stage <index>", "Stage index", (v) =>
|
|
236
|
+
parseInt(v, 10),
|
|
237
|
+
)
|
|
238
|
+
.requiredOption("-n, --name <name>", "Artifact name")
|
|
239
|
+
.option(
|
|
240
|
+
"-t, --type <type>",
|
|
241
|
+
"Artifact type (document/code/report/config/deploy-result)",
|
|
242
|
+
ARTIFACT_TYPE.DOCUMENT,
|
|
243
|
+
)
|
|
244
|
+
.option("-c, --content <text>", "Artifact content (inline)")
|
|
245
|
+
.option("-m, --metadata <json>", "Metadata JSON")
|
|
246
|
+
.action((pipelineId, opts, cmd) => {
|
|
247
|
+
const db = _dbFromCtx(cmd);
|
|
248
|
+
if (!db) return console.error("No database");
|
|
249
|
+
_json(
|
|
250
|
+
addArtifact(db, pipelineId, opts.stage, {
|
|
251
|
+
name: opts.name,
|
|
252
|
+
type: opts.type,
|
|
253
|
+
content: opts.content || "",
|
|
254
|
+
metadata: _parseJsonArg(opts.metadata, {}),
|
|
255
|
+
}),
|
|
256
|
+
);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
pipeline
|
|
260
|
+
.command("artifacts <pipelineId>")
|
|
261
|
+
.description("List artifacts for a pipeline")
|
|
262
|
+
.option("-s, --stage <index>", "Filter by stage index", (v) =>
|
|
263
|
+
parseInt(v, 10),
|
|
264
|
+
)
|
|
265
|
+
.action((pipelineId, opts, cmd) => {
|
|
266
|
+
const db = _dbFromCtx(cmd);
|
|
267
|
+
if (!db) return console.error("No database");
|
|
268
|
+
_json(
|
|
269
|
+
listArtifacts(db, pipelineId, opts.stage != null ? opts.stage : null),
|
|
270
|
+
);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
/* ── Queries ─────────────────────────────────────── */
|
|
274
|
+
|
|
275
|
+
pipeline
|
|
276
|
+
.command("show <pipelineId>")
|
|
277
|
+
.description("Show pipeline with stages")
|
|
278
|
+
.action((pipelineId, _opts, cmd) => {
|
|
279
|
+
const db = _dbFromCtx(cmd);
|
|
280
|
+
if (!db) return console.error("No database");
|
|
281
|
+
const p = getPipeline(db, pipelineId);
|
|
282
|
+
if (!p) return console.error(`Pipeline not found: ${pipelineId}`);
|
|
283
|
+
_json(p);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
pipeline
|
|
287
|
+
.command("list")
|
|
288
|
+
.description("List pipelines")
|
|
289
|
+
.option("-t, --template <name>", "Filter by template")
|
|
290
|
+
.option("-s, --status <name>", "Filter by status")
|
|
291
|
+
.option("-l, --limit <n>", "Max rows", (v) => parseInt(v, 10), 100)
|
|
292
|
+
.action((opts, cmd) => {
|
|
293
|
+
const db = _dbFromCtx(cmd);
|
|
294
|
+
if (!db) return console.error("No database");
|
|
295
|
+
_json(
|
|
296
|
+
listPipelines(db, {
|
|
297
|
+
template: opts.template,
|
|
298
|
+
status: opts.status,
|
|
299
|
+
limit: opts.limit,
|
|
300
|
+
}),
|
|
301
|
+
);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
pipeline
|
|
305
|
+
.command("stage <pipelineId> <stageIndex>")
|
|
306
|
+
.description("Show a specific stage")
|
|
307
|
+
.action((pipelineId, stageIndex, _opts, cmd) => {
|
|
308
|
+
const db = _dbFromCtx(cmd);
|
|
309
|
+
if (!db) return console.error("No database");
|
|
310
|
+
_json(getStage(db, pipelineId, parseInt(stageIndex, 10)));
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
/* ── Deployments ─────────────────────────────────── */
|
|
314
|
+
|
|
315
|
+
pipeline
|
|
316
|
+
.command("deploy")
|
|
317
|
+
.description("Record a deployment (CLI does not actually deploy)")
|
|
318
|
+
.requiredOption(
|
|
319
|
+
"-s, --strategy <name>",
|
|
320
|
+
"Strategy (git-pr/docker/npm-publish/local/staging/custom)",
|
|
321
|
+
)
|
|
322
|
+
.option("-p, --pipeline <id>", "Associated pipeline ID")
|
|
323
|
+
.option("-c, --config <json>", "Deploy config as JSON")
|
|
324
|
+
.option("-r, --result <json>", "Deploy result as JSON")
|
|
325
|
+
.option("--status <value>", "Initial status", DEPLOY_STATUS.SUCCEEDED)
|
|
326
|
+
.option("-e, --error <msg>", "Error message (for failed status)")
|
|
327
|
+
.action((opts, cmd) => {
|
|
328
|
+
const db = _dbFromCtx(cmd);
|
|
329
|
+
if (!db) return console.error("No database");
|
|
330
|
+
_json(
|
|
331
|
+
recordDeploy(db, {
|
|
332
|
+
pipelineId: opts.pipeline || null,
|
|
333
|
+
strategy: opts.strategy,
|
|
334
|
+
config: _parseJsonArg(opts.config, {}),
|
|
335
|
+
result: _parseJsonArg(opts.result, null),
|
|
336
|
+
status: opts.status,
|
|
337
|
+
errorMessage: opts.error || null,
|
|
338
|
+
}),
|
|
339
|
+
);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
pipeline
|
|
343
|
+
.command("deploys")
|
|
344
|
+
.description("List deployments")
|
|
345
|
+
.option("-p, --pipeline <id>", "Filter by pipeline ID")
|
|
346
|
+
.option("-s, --strategy <name>", "Filter by strategy")
|
|
347
|
+
.option("--status <value>", "Filter by status")
|
|
348
|
+
.option("-l, --limit <n>", "Max rows", (v) => parseInt(v, 10), 100)
|
|
349
|
+
.action((opts, cmd) => {
|
|
350
|
+
const db = _dbFromCtx(cmd);
|
|
351
|
+
if (!db) return console.error("No database");
|
|
352
|
+
_json(
|
|
353
|
+
listDeploys(db, {
|
|
354
|
+
pipelineId: opts.pipeline,
|
|
355
|
+
strategy: opts.strategy,
|
|
356
|
+
status: opts.status,
|
|
357
|
+
limit: opts.limit,
|
|
358
|
+
}),
|
|
359
|
+
);
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
pipeline
|
|
363
|
+
.command("deploy-show <deployId>")
|
|
364
|
+
.description("Show a deployment record")
|
|
365
|
+
.action((deployId, _opts, cmd) => {
|
|
366
|
+
const db = _dbFromCtx(cmd);
|
|
367
|
+
if (!db) return console.error("No database");
|
|
368
|
+
_json(getDeploy(db, deployId));
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
pipeline
|
|
372
|
+
.command("rollback <deployId>")
|
|
373
|
+
.description("Rollback a succeeded deployment")
|
|
374
|
+
.option("-r, --reason <text>", "Rollback reason")
|
|
375
|
+
.action((deployId, opts, cmd) => {
|
|
376
|
+
const db = _dbFromCtx(cmd);
|
|
377
|
+
if (!db) return console.error("No database");
|
|
378
|
+
_json(rollbackDeploy(db, deployId, opts.reason || "rollback requested"));
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
/* ── Monitoring ──────────────────────────────────── */
|
|
382
|
+
|
|
383
|
+
pipeline
|
|
384
|
+
.command("monitor-record <deployId>")
|
|
385
|
+
.description("Record a post-deploy monitoring event (health check)")
|
|
386
|
+
.option(
|
|
387
|
+
"-t, --type <name>",
|
|
388
|
+
"Event type (health-check/alert/rollback-trigger)",
|
|
389
|
+
"health-check",
|
|
390
|
+
)
|
|
391
|
+
.option(
|
|
392
|
+
"-s, --status <name>",
|
|
393
|
+
"Health status (healthy/degraded/unhealthy)",
|
|
394
|
+
"healthy",
|
|
395
|
+
)
|
|
396
|
+
.option("-m, --metrics <json>", "Metrics JSON", "{}")
|
|
397
|
+
.action((deployId, opts, cmd) => {
|
|
398
|
+
const db = _dbFromCtx(cmd);
|
|
399
|
+
if (!db) return console.error("No database");
|
|
400
|
+
_json(
|
|
401
|
+
recordMonitorEvent(db, deployId, {
|
|
402
|
+
eventType: opts.type,
|
|
403
|
+
healthStatus: opts.status,
|
|
404
|
+
metrics: _parseJsonArg(opts.metrics, {}),
|
|
405
|
+
}),
|
|
406
|
+
);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
pipeline
|
|
410
|
+
.command("monitor-events <deployId>")
|
|
411
|
+
.description("List monitoring events for a deploy")
|
|
412
|
+
.option("-l, --limit <n>", "Max rows", (v) => parseInt(v, 10), 100)
|
|
413
|
+
.action((deployId, opts, cmd) => {
|
|
414
|
+
const db = _dbFromCtx(cmd);
|
|
415
|
+
if (!db) return console.error("No database");
|
|
416
|
+
_json(listMonitorEvents(db, deployId, { limit: opts.limit }));
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
pipeline
|
|
420
|
+
.command("monitor-status <deployId>")
|
|
421
|
+
.description("Show latest monitoring status")
|
|
422
|
+
.action((deployId, _opts, cmd) => {
|
|
423
|
+
const db = _dbFromCtx(cmd);
|
|
424
|
+
if (!db) return console.error("No database");
|
|
425
|
+
_json(getMonitorStatus(db, deployId));
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
/* ── Export / Stats ──────────────────────────────── */
|
|
429
|
+
|
|
430
|
+
pipeline
|
|
431
|
+
.command("export <pipelineId>")
|
|
432
|
+
.description("Export pipeline + stages + artifacts + deploys as JSON")
|
|
433
|
+
.action((pipelineId, _opts, cmd) => {
|
|
434
|
+
const db = _dbFromCtx(cmd);
|
|
435
|
+
if (!db) return console.error("No database");
|
|
436
|
+
_json(exportPipeline(db, pipelineId));
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
pipeline
|
|
440
|
+
.command("stats")
|
|
441
|
+
.description("Show pipeline system stats")
|
|
442
|
+
.action((_opts, cmd) => {
|
|
443
|
+
const db = _dbFromCtx(cmd);
|
|
444
|
+
if (!db) return console.error("No database");
|
|
445
|
+
_json(getStats(db));
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
program.addCommand(pipeline);
|
|
449
|
+
}
|