chainlesschain 0.51.0 → 0.81.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/a2a.js +380 -0
- package/src/commands/agent-network.js +785 -0
- package/src/commands/automation.js +654 -0
- package/src/commands/bi.js +348 -0
- package/src/commands/crosschain.js +218 -0
- package/src/commands/dao.js +565 -0
- package/src/commands/did-v2.js +620 -0
- package/src/commands/dlp.js +341 -0
- package/src/commands/economy.js +578 -0
- package/src/commands/evolution.js +391 -0
- package/src/commands/evomap.js +394 -0
- package/src/commands/federation.js +283 -0
- package/src/commands/hmemory.js +442 -0
- package/src/commands/inference.js +318 -0
- package/src/commands/lowcode.js +356 -0
- package/src/commands/marketplace.js +256 -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/privacy.js +321 -0
- package/src/commands/reputation.js +261 -0
- package/src/commands/sandbox.js +401 -0
- package/src/commands/siem.js +246 -0
- package/src/commands/sla.js +259 -0
- package/src/commands/social.js +311 -0
- package/src/commands/sso.js +798 -0
- package/src/commands/stress.js +230 -0
- package/src/commands/terraform.js +245 -0
- package/src/commands/workflow.js +320 -0
- package/src/commands/zkp.js +562 -1
- package/src/index.js +21 -0
- package/src/lib/a2a-protocol.js +451 -0
- package/src/lib/agent-economy.js +479 -0
- package/src/lib/agent-network.js +1121 -0
- package/src/lib/app-builder.js +239 -0
- package/src/lib/automation-engine.js +948 -0
- package/src/lib/bi-engine.js +338 -0
- package/src/lib/cross-chain.js +345 -0
- package/src/lib/dao-governance.js +569 -0
- package/src/lib/did-v2-manager.js +1127 -0
- package/src/lib/dlp-engine.js +389 -0
- package/src/lib/evolution-system.js +453 -0
- package/src/lib/evomap-federation.js +177 -0
- package/src/lib/evomap-governance.js +276 -0
- package/src/lib/federation-hardening.js +259 -0
- package/src/lib/hierarchical-memory.js +481 -0
- package/src/lib/inference-network.js +330 -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/privacy-computing.js +427 -0
- package/src/lib/reputation-optimizer.js +299 -0
- package/src/lib/sandbox-v2.js +306 -0
- package/src/lib/siem-exporter.js +333 -0
- package/src/lib/skill-marketplace.js +325 -0
- package/src/lib/sla-manager.js +275 -0
- package/src/lib/social-graph-analytics.js +707 -0
- package/src/lib/sso-manager.js +841 -0
- package/src/lib/stress-tester.js +330 -0
- package/src/lib/terraform-manager.js +363 -0
- package/src/lib/workflow-engine.js +454 -1
- package/src/lib/zkp-engine.js +523 -20
- package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +0 -1
package/src/commands/stress.js
CHANGED
|
@@ -15,6 +15,22 @@ import {
|
|
|
15
15
|
analyzeBottlenecks,
|
|
16
16
|
generateCapacityPlan,
|
|
17
17
|
listLoadLevels,
|
|
18
|
+
// V2
|
|
19
|
+
RUN_STATUS_V2,
|
|
20
|
+
LEVEL_NAME_V2,
|
|
21
|
+
BOTTLENECK_KIND_V2,
|
|
22
|
+
BOTTLENECK_SEVERITY_V2,
|
|
23
|
+
STRESS_DEFAULT_MAX_CONCURRENT,
|
|
24
|
+
setMaxConcurrentTests,
|
|
25
|
+
getMaxConcurrentTests,
|
|
26
|
+
getActiveTestCount,
|
|
27
|
+
startStressTestV2,
|
|
28
|
+
completeStressTest,
|
|
29
|
+
stopStressTestV2,
|
|
30
|
+
failStressTest,
|
|
31
|
+
setRunStatus,
|
|
32
|
+
recommendLevelV2,
|
|
33
|
+
getStressStatsV2,
|
|
18
34
|
} from "../lib/stress-tester.js";
|
|
19
35
|
|
|
20
36
|
function _dbFromCtx(ctx) {
|
|
@@ -249,4 +265,218 @@ export function registerStressCommand(program) {
|
|
|
249
265
|
}
|
|
250
266
|
}
|
|
251
267
|
});
|
|
268
|
+
|
|
269
|
+
// ---------- V2 (Phase 59) ----------
|
|
270
|
+
const withDb = async (fn) => {
|
|
271
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
272
|
+
if (!ctx.db) {
|
|
273
|
+
logger.error("Database not available");
|
|
274
|
+
process.exit(1);
|
|
275
|
+
}
|
|
276
|
+
try {
|
|
277
|
+
const db = ctx.db.getDatabase();
|
|
278
|
+
ensureStressTables(db);
|
|
279
|
+
return await fn(db);
|
|
280
|
+
} finally {
|
|
281
|
+
await shutdown();
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
stress
|
|
286
|
+
.command("run-statuses")
|
|
287
|
+
.description("List RUN_STATUS_V2 values")
|
|
288
|
+
.action(() => {
|
|
289
|
+
console.log(JSON.stringify(Object.values(RUN_STATUS_V2), null, 2));
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
stress
|
|
293
|
+
.command("level-names")
|
|
294
|
+
.description("List LEVEL_NAME_V2 values")
|
|
295
|
+
.action(() => {
|
|
296
|
+
console.log(JSON.stringify(Object.values(LEVEL_NAME_V2), null, 2));
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
stress
|
|
300
|
+
.command("bottleneck-kinds")
|
|
301
|
+
.description("List BOTTLENECK_KIND_V2 values")
|
|
302
|
+
.action(() => {
|
|
303
|
+
console.log(JSON.stringify(Object.values(BOTTLENECK_KIND_V2), null, 2));
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
stress
|
|
307
|
+
.command("bottleneck-severities")
|
|
308
|
+
.description("List BOTTLENECK_SEVERITY_V2 values")
|
|
309
|
+
.action(() => {
|
|
310
|
+
console.log(
|
|
311
|
+
JSON.stringify(Object.values(BOTTLENECK_SEVERITY_V2), null, 2),
|
|
312
|
+
);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
stress
|
|
316
|
+
.command("default-max-concurrent")
|
|
317
|
+
.description("Show STRESS_DEFAULT_MAX_CONCURRENT")
|
|
318
|
+
.action(() => {
|
|
319
|
+
console.log(STRESS_DEFAULT_MAX_CONCURRENT);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
stress
|
|
323
|
+
.command("max-concurrent")
|
|
324
|
+
.description("Show current max concurrent test limit")
|
|
325
|
+
.action(() => {
|
|
326
|
+
console.log(getMaxConcurrentTests());
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
stress
|
|
330
|
+
.command("active-test-count")
|
|
331
|
+
.description("Show current active (RUNNING) test count")
|
|
332
|
+
.action(() => {
|
|
333
|
+
console.log(getActiveTestCount());
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
stress
|
|
337
|
+
.command("set-max-concurrent <n>")
|
|
338
|
+
.description("Set max concurrent test admission limit")
|
|
339
|
+
.action((n) => {
|
|
340
|
+
try {
|
|
341
|
+
const v = setMaxConcurrentTests(Number(n));
|
|
342
|
+
logger.success(`maxConcurrentTests=${v}`);
|
|
343
|
+
} catch (err) {
|
|
344
|
+
logger.error(`Failed: ${err.message}`);
|
|
345
|
+
process.exit(1);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
stress
|
|
350
|
+
.command("start-v2")
|
|
351
|
+
.description("Start a V2 stress run (RUNNING, no metrics until complete)")
|
|
352
|
+
.option(
|
|
353
|
+
"-l, --level <level>",
|
|
354
|
+
"Load level (light|medium|heavy|extreme)",
|
|
355
|
+
"medium",
|
|
356
|
+
)
|
|
357
|
+
.option("-c, --concurrency <n>", "Override concurrency", parseInt)
|
|
358
|
+
.option("-r, --rps <n>", "Override requests per second", parseInt)
|
|
359
|
+
.option("-d, --duration <ms>", "Override duration in ms", parseInt)
|
|
360
|
+
.option("--json", "Output as JSON")
|
|
361
|
+
.action(async (options) => {
|
|
362
|
+
try {
|
|
363
|
+
await withDb((db) => {
|
|
364
|
+
const run = startStressTestV2(db, {
|
|
365
|
+
level: options.level,
|
|
366
|
+
concurrency: options.concurrency,
|
|
367
|
+
requestsPerSecond: options.rps,
|
|
368
|
+
duration: options.duration,
|
|
369
|
+
});
|
|
370
|
+
if (options.json) {
|
|
371
|
+
console.log(JSON.stringify(run, null, 2));
|
|
372
|
+
} else {
|
|
373
|
+
logger.success(
|
|
374
|
+
`Started ${run.testId.slice(0, 8)} [${run.loadLevel}] → ${run.status}`,
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
} catch (err) {
|
|
379
|
+
logger.error(`Failed: ${err.message}`);
|
|
380
|
+
process.exit(1);
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
stress
|
|
385
|
+
.command("complete <test-id>")
|
|
386
|
+
.description("Complete a RUNNING run and compute metrics")
|
|
387
|
+
.option("--json", "Output as JSON")
|
|
388
|
+
.action(async (testId, options) => {
|
|
389
|
+
try {
|
|
390
|
+
await withDb((db) => {
|
|
391
|
+
const r = completeStressTest(db, testId);
|
|
392
|
+
if (options.json) {
|
|
393
|
+
console.log(JSON.stringify(r, null, 2));
|
|
394
|
+
} else {
|
|
395
|
+
logger.success(
|
|
396
|
+
`${r.testId.slice(0, 8)} → ${r.status} (tps=${r.result.tps})`,
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
} catch (err) {
|
|
401
|
+
logger.error(`Failed: ${err.message}`);
|
|
402
|
+
process.exit(1);
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
stress
|
|
407
|
+
.command("stop-v2 <test-id>")
|
|
408
|
+
.description("Stop a RUNNING run (→ STOPPED)")
|
|
409
|
+
.action(async (testId) => {
|
|
410
|
+
try {
|
|
411
|
+
await withDb((db) => {
|
|
412
|
+
const r = stopStressTestV2(db, testId);
|
|
413
|
+
logger.success(`${r.testId.slice(0, 8)} → ${r.status}`);
|
|
414
|
+
});
|
|
415
|
+
} catch (err) {
|
|
416
|
+
logger.error(`Failed: ${err.message}`);
|
|
417
|
+
process.exit(1);
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
stress
|
|
422
|
+
.command("fail <test-id> <error-message>")
|
|
423
|
+
.description("Fail a RUNNING run with an error message (→ FAILED)")
|
|
424
|
+
.action(async (testId, errorMessage) => {
|
|
425
|
+
try {
|
|
426
|
+
await withDb((db) => {
|
|
427
|
+
const r = failStressTest(db, testId, errorMessage);
|
|
428
|
+
logger.success(
|
|
429
|
+
`${r.testId.slice(0, 8)} → ${r.status} (${r.errorMessage})`,
|
|
430
|
+
);
|
|
431
|
+
});
|
|
432
|
+
} catch (err) {
|
|
433
|
+
logger.error(`Failed: ${err.message}`);
|
|
434
|
+
process.exit(1);
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
stress
|
|
439
|
+
.command("set-status <test-id> <status>")
|
|
440
|
+
.description("Transition run to a given status (state-machine guarded)")
|
|
441
|
+
.option("--error-message <msg>", "Attach error message (for failed)")
|
|
442
|
+
.action(async (testId, status, options) => {
|
|
443
|
+
try {
|
|
444
|
+
await withDb((db) => {
|
|
445
|
+
const patch = {};
|
|
446
|
+
if (options.errorMessage) patch.errorMessage = options.errorMessage;
|
|
447
|
+
const r = setRunStatus(db, testId, status, patch);
|
|
448
|
+
logger.success(`${r.testId.slice(0, 8)} → ${r.status}`);
|
|
449
|
+
});
|
|
450
|
+
} catch (err) {
|
|
451
|
+
logger.error(`Failed: ${err.message}`);
|
|
452
|
+
process.exit(1);
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
stress
|
|
457
|
+
.command("recommend-level <target-rps>")
|
|
458
|
+
.description("Recommend the largest built-in level ≤ targetRps")
|
|
459
|
+
.option("--json", "Output as JSON")
|
|
460
|
+
.action((targetRps, options) => {
|
|
461
|
+
try {
|
|
462
|
+
const level = recommendLevelV2(Number(targetRps));
|
|
463
|
+
if (options.json) {
|
|
464
|
+
console.log(JSON.stringify(level, null, 2));
|
|
465
|
+
} else {
|
|
466
|
+
logger.log(
|
|
467
|
+
` ${chalk.cyan(level.name)} concurrency=${level.concurrency} rps=${level.requestsPerSecond} duration=${level.duration}ms`,
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
} catch (err) {
|
|
471
|
+
logger.error(`Failed: ${err.message}`);
|
|
472
|
+
process.exit(1);
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
stress
|
|
477
|
+
.command("stats-v2")
|
|
478
|
+
.description("Show aggregate V2 stats (byStatus/byLevel/bottlenecks)")
|
|
479
|
+
.action(() => {
|
|
480
|
+
console.log(JSON.stringify(getStressStatsV2(), null, 2));
|
|
481
|
+
});
|
|
252
482
|
}
|
|
@@ -12,6 +12,22 @@ import {
|
|
|
12
12
|
createWorkspace,
|
|
13
13
|
planRun,
|
|
14
14
|
listRuns,
|
|
15
|
+
// V2
|
|
16
|
+
RUN_STATUS_V2,
|
|
17
|
+
RUN_TYPE_V2,
|
|
18
|
+
WORKSPACE_STATUS_V2,
|
|
19
|
+
TERRAFORM_DEFAULT_MAX_CONCURRENT,
|
|
20
|
+
setMaxConcurrentRuns,
|
|
21
|
+
getMaxConcurrentRuns,
|
|
22
|
+
createWorkspaceV2,
|
|
23
|
+
setWorkspaceStatus,
|
|
24
|
+
archiveWorkspace,
|
|
25
|
+
planRunV2,
|
|
26
|
+
setRunStatus,
|
|
27
|
+
cancelRun,
|
|
28
|
+
failRun,
|
|
29
|
+
getActiveRunCount,
|
|
30
|
+
getTerraformStatsV2,
|
|
15
31
|
} from "../lib/terraform-manager.js";
|
|
16
32
|
|
|
17
33
|
export function registerTerraformCommand(program) {
|
|
@@ -145,4 +161,233 @@ export function registerTerraformCommand(program) {
|
|
|
145
161
|
process.exit(1);
|
|
146
162
|
}
|
|
147
163
|
});
|
|
164
|
+
|
|
165
|
+
/* ── V2 Subcommands (Phase 56) ──────────────────────────── */
|
|
166
|
+
|
|
167
|
+
const withDb = async (fn) => {
|
|
168
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
169
|
+
if (!ctx.db) {
|
|
170
|
+
logger.error("Database not available");
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const db = ctx.db.getDatabase();
|
|
175
|
+
ensureTerraformTables(db);
|
|
176
|
+
return await fn(db);
|
|
177
|
+
} finally {
|
|
178
|
+
await shutdown();
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
terraform
|
|
183
|
+
.command("run-statuses")
|
|
184
|
+
.description("List RUN_STATUS_V2 enum values")
|
|
185
|
+
.action(() => {
|
|
186
|
+
console.log(JSON.stringify(Object.values(RUN_STATUS_V2), null, 2));
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
terraform
|
|
190
|
+
.command("run-types")
|
|
191
|
+
.description("List RUN_TYPE_V2 enum values")
|
|
192
|
+
.action(() => {
|
|
193
|
+
console.log(JSON.stringify(Object.values(RUN_TYPE_V2), null, 2));
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
terraform
|
|
197
|
+
.command("workspace-statuses")
|
|
198
|
+
.description("List WORKSPACE_STATUS_V2 enum values")
|
|
199
|
+
.action(() => {
|
|
200
|
+
console.log(JSON.stringify(Object.values(WORKSPACE_STATUS_V2), null, 2));
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
terraform
|
|
204
|
+
.command("default-max-concurrent")
|
|
205
|
+
.description("Show TERRAFORM_DEFAULT_MAX_CONCURRENT")
|
|
206
|
+
.action(() => {
|
|
207
|
+
console.log(TERRAFORM_DEFAULT_MAX_CONCURRENT);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
terraform
|
|
211
|
+
.command("active-run-count")
|
|
212
|
+
.description("Show current active (non-terminal) run count")
|
|
213
|
+
.action(() => {
|
|
214
|
+
console.log(getActiveRunCount());
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
terraform
|
|
218
|
+
.command("set-max-concurrent <n>")
|
|
219
|
+
.description("Set max concurrent runs")
|
|
220
|
+
.action(async (n) => {
|
|
221
|
+
try {
|
|
222
|
+
const value = setMaxConcurrentRuns(Number(n));
|
|
223
|
+
logger.success(`maxConcurrentRuns = ${value}`);
|
|
224
|
+
} catch (err) {
|
|
225
|
+
logger.error(`Failed: ${err.message}`);
|
|
226
|
+
process.exit(1);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
terraform
|
|
231
|
+
.command("max-concurrent")
|
|
232
|
+
.description("Show current max concurrent runs")
|
|
233
|
+
.action(() => {
|
|
234
|
+
console.log(getMaxConcurrentRuns());
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
terraform
|
|
238
|
+
.command("create-workspace-v2 <name>")
|
|
239
|
+
.description("Create workspace (V2, unique-name enforced)")
|
|
240
|
+
.option("-d, --description <text>", "Workspace description")
|
|
241
|
+
.option("--tf-version <version>", "Terraform version")
|
|
242
|
+
.option("--auto-apply", "Enable auto-apply")
|
|
243
|
+
.option("--providers <list>", "Comma-separated providers")
|
|
244
|
+
.action(async (name, options) => {
|
|
245
|
+
await withDb(async (db) => {
|
|
246
|
+
try {
|
|
247
|
+
const ws = createWorkspaceV2(db, {
|
|
248
|
+
name,
|
|
249
|
+
description: options.description,
|
|
250
|
+
terraformVersion: options.tfVersion,
|
|
251
|
+
autoApply: options.autoApply,
|
|
252
|
+
providers: options.providers
|
|
253
|
+
? options.providers.split(",").map((s) => s.trim())
|
|
254
|
+
: undefined,
|
|
255
|
+
});
|
|
256
|
+
logger.success("Workspace created (V2)");
|
|
257
|
+
logger.log(` ID: ${chalk.cyan(ws.id)}`);
|
|
258
|
+
logger.log(` Name: ${ws.name}`);
|
|
259
|
+
logger.log(` Status: ${ws.status}`);
|
|
260
|
+
} catch (err) {
|
|
261
|
+
logger.error(`Failed: ${err.message}`);
|
|
262
|
+
process.exit(1);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
terraform
|
|
268
|
+
.command("set-workspace-status <workspace-id> <status>")
|
|
269
|
+
.description("Set workspace status (state-machine guarded)")
|
|
270
|
+
.action(async (workspaceId, status) => {
|
|
271
|
+
await withDb(async (db) => {
|
|
272
|
+
try {
|
|
273
|
+
const result = setWorkspaceStatus(db, workspaceId, status);
|
|
274
|
+
logger.success(
|
|
275
|
+
`Workspace ${workspaceId.slice(0, 8)} → ${result.status}`,
|
|
276
|
+
);
|
|
277
|
+
} catch (err) {
|
|
278
|
+
logger.error(`Failed: ${err.message}`);
|
|
279
|
+
process.exit(1);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
terraform
|
|
285
|
+
.command("archive-workspace <workspace-id>")
|
|
286
|
+
.description("Archive a workspace (shortcut)")
|
|
287
|
+
.action(async (workspaceId) => {
|
|
288
|
+
await withDb(async (db) => {
|
|
289
|
+
try {
|
|
290
|
+
const result = archiveWorkspace(db, workspaceId);
|
|
291
|
+
logger.success(`Workspace archived: ${result.status}`);
|
|
292
|
+
} catch (err) {
|
|
293
|
+
logger.error(`Failed: ${err.message}`);
|
|
294
|
+
process.exit(1);
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
terraform
|
|
300
|
+
.command("plan-run-v2 <workspace-id>")
|
|
301
|
+
.description("Create a V2 run (pending state, concurrency-limited)")
|
|
302
|
+
.option("-t, --run-type <type>", "Run type: plan|apply|destroy", "plan")
|
|
303
|
+
.option("--triggered-by <who>", "Who triggered the run")
|
|
304
|
+
.action(async (workspaceId, options) => {
|
|
305
|
+
await withDb(async (db) => {
|
|
306
|
+
try {
|
|
307
|
+
const run = planRunV2(db, {
|
|
308
|
+
workspaceId,
|
|
309
|
+
runType: options.runType,
|
|
310
|
+
triggeredBy: options.triggeredBy,
|
|
311
|
+
});
|
|
312
|
+
logger.success("Run created (V2)");
|
|
313
|
+
logger.log(` ID: ${chalk.cyan(run.id)}`);
|
|
314
|
+
logger.log(` Type: ${run.runType}`);
|
|
315
|
+
logger.log(` Status: ${run.status}`);
|
|
316
|
+
} catch (err) {
|
|
317
|
+
logger.error(`Failed: ${err.message}`);
|
|
318
|
+
process.exit(1);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
terraform
|
|
324
|
+
.command("set-run-status <run-id> <status>")
|
|
325
|
+
.description("Set run status (state-machine guarded)")
|
|
326
|
+
.option("--plan-output <text>", "Plan output summary")
|
|
327
|
+
.option("--apply-output <text>", "Apply output summary")
|
|
328
|
+
.option("--resources-added <n>", "Resources added count")
|
|
329
|
+
.option("--resources-changed <n>", "Resources changed count")
|
|
330
|
+
.option("--resources-destroyed <n>", "Resources destroyed count")
|
|
331
|
+
.option("--error-message <text>", "Error message")
|
|
332
|
+
.action(async (runId, status, options) => {
|
|
333
|
+
await withDb(async (db) => {
|
|
334
|
+
try {
|
|
335
|
+
const patch = {};
|
|
336
|
+
if (options.planOutput) patch.planOutput = options.planOutput;
|
|
337
|
+
if (options.applyOutput) patch.applyOutput = options.applyOutput;
|
|
338
|
+
if (options.resourcesAdded !== undefined)
|
|
339
|
+
patch.resourcesAdded = Number(options.resourcesAdded);
|
|
340
|
+
if (options.resourcesChanged !== undefined)
|
|
341
|
+
patch.resourcesChanged = Number(options.resourcesChanged);
|
|
342
|
+
if (options.resourcesDestroyed !== undefined)
|
|
343
|
+
patch.resourcesDestroyed = Number(options.resourcesDestroyed);
|
|
344
|
+
if (options.errorMessage) patch.errorMessage = options.errorMessage;
|
|
345
|
+
const run = setRunStatus(db, runId, status, patch);
|
|
346
|
+
logger.success(`Run ${runId.slice(0, 8)} → ${run.status}`);
|
|
347
|
+
} catch (err) {
|
|
348
|
+
logger.error(`Failed: ${err.message}`);
|
|
349
|
+
process.exit(1);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
terraform
|
|
355
|
+
.command("cancel-run <run-id>")
|
|
356
|
+
.description("Cancel a run (shortcut)")
|
|
357
|
+
.action(async (runId) => {
|
|
358
|
+
await withDb(async (db) => {
|
|
359
|
+
try {
|
|
360
|
+
const run = cancelRun(db, runId);
|
|
361
|
+
logger.success(`Run cancelled: ${run.status}`);
|
|
362
|
+
} catch (err) {
|
|
363
|
+
logger.error(`Failed: ${err.message}`);
|
|
364
|
+
process.exit(1);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
terraform
|
|
370
|
+
.command("fail-run <run-id> <error-message>")
|
|
371
|
+
.description("Mark a run as errored (shortcut)")
|
|
372
|
+
.action(async (runId, errorMessage) => {
|
|
373
|
+
await withDb(async (db) => {
|
|
374
|
+
try {
|
|
375
|
+
const run = failRun(db, runId, errorMessage);
|
|
376
|
+
logger.success(`Run errored: ${run.errorMessage}`);
|
|
377
|
+
} catch (err) {
|
|
378
|
+
logger.error(`Failed: ${err.message}`);
|
|
379
|
+
process.exit(1);
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
terraform
|
|
385
|
+
.command("stats-v2")
|
|
386
|
+
.description("Show V2 terraform stats")
|
|
387
|
+
.action(async () => {
|
|
388
|
+
await withDb(async () => {
|
|
389
|
+
const stats = getTerraformStatsV2();
|
|
390
|
+
console.log(JSON.stringify(stats, null, 2));
|
|
391
|
+
});
|
|
392
|
+
});
|
|
148
393
|
}
|