chainlesschain 0.66.0 → 0.132.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/bin/chainlesschain.js +0 -0
- package/package.json +1 -1
- package/src/commands/a2a.js +380 -0
- package/src/commands/agent-network.js +254 -1
- package/src/commands/audit.js +302 -0
- package/src/commands/automation.js +271 -1
- package/src/commands/bi.js +348 -0
- package/src/commands/codegen.js +224 -0
- package/src/commands/collab.js +341 -0
- package/src/commands/compliance.js +1035 -0
- package/src/commands/cowork.js +221 -0
- package/src/commands/crosschain.js +218 -0
- package/src/commands/dbevo.js +284 -0
- package/src/commands/dev.js +252 -0
- package/src/commands/did.js +358 -0
- package/src/commands/dlp.js +341 -0
- package/src/commands/encrypt.js +341 -0
- package/src/commands/evomap.js +394 -0
- package/src/commands/export.js +256 -1
- package/src/commands/federation.js +283 -0
- package/src/commands/fusion.js +258 -0
- package/src/commands/governance.js +325 -0
- package/src/commands/hardening.js +411 -0
- package/src/commands/hook.js +148 -0
- package/src/commands/import.js +252 -0
- package/src/commands/incentive.js +322 -0
- package/src/commands/inference.js +318 -0
- package/src/commands/infra.js +244 -0
- package/src/commands/instinct.js +260 -0
- package/src/commands/ipfs.js +318 -0
- package/src/commands/kg.js +387 -0
- package/src/commands/llm.js +263 -0
- package/src/commands/lowcode.js +356 -0
- package/src/commands/marketplace.js +256 -0
- package/src/commands/mcp.js +221 -0
- package/src/commands/memory.js +248 -0
- package/src/commands/multimodal.js +296 -0
- package/src/commands/nlprog.js +356 -0
- package/src/commands/note.js +244 -0
- package/src/commands/ops.js +354 -0
- package/src/commands/orchestrate.js +166 -0
- package/src/commands/org.js +277 -0
- package/src/commands/p2p.js +390 -0
- package/src/commands/perception.js +290 -0
- package/src/commands/permmem.js +251 -0
- package/src/commands/plugin-ecosystem.js +273 -0
- package/src/commands/pqc.js +393 -0
- package/src/commands/privacy.js +321 -0
- package/src/commands/quantization.js +351 -0
- package/src/commands/rcache.js +271 -0
- package/src/commands/recommend.js +340 -0
- package/src/commands/reputation.js +261 -0
- package/src/commands/runtime.js +307 -0
- package/src/commands/scim.js +262 -0
- package/src/commands/session.js +258 -0
- package/src/commands/siem.js +246 -0
- package/src/commands/skill.js +267 -1
- package/src/commands/sla.js +259 -0
- package/src/commands/social.js +256 -0
- package/src/commands/sso.js +186 -1
- package/src/commands/stress.js +230 -0
- package/src/commands/sync.js +256 -0
- package/src/commands/tech.js +338 -0
- package/src/commands/tenant.js +351 -0
- package/src/commands/terraform.js +245 -0
- package/src/commands/tokens.js +269 -0
- package/src/commands/trust.js +249 -0
- package/src/commands/wallet.js +277 -0
- package/src/commands/workflow.js +171 -0
- package/src/commands/zkp.js +335 -0
- package/src/index.js +4 -0
- package/src/lib/a2a-protocol.js +451 -0
- package/src/lib/agent-coordinator.js +325 -0
- package/src/lib/agent-network.js +387 -0
- package/src/lib/agent-router.js +395 -0
- package/src/lib/aiops.js +478 -0
- package/src/lib/app-builder.js +239 -0
- package/src/lib/audit-logger.js +379 -0
- package/src/lib/automation-engine.js +330 -0
- package/src/lib/autonomous-developer.js +350 -0
- package/src/lib/bi-engine.js +338 -0
- package/src/lib/code-agent.js +323 -0
- package/src/lib/collaboration-governance.js +364 -0
- package/src/lib/community-governance.js +436 -0
- package/src/lib/compliance-manager.js +434 -0
- package/src/lib/content-recommendation.js +469 -0
- package/src/lib/cross-chain.js +345 -0
- package/src/lib/crypto-manager.js +350 -0
- package/src/lib/dbevo.js +338 -0
- package/src/lib/decentral-infra.js +340 -0
- package/src/lib/did-manager.js +367 -0
- package/src/lib/dlp-engine.js +389 -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/hardening-manager.js +348 -0
- package/src/lib/hook-manager.js +380 -0
- package/src/lib/inference-network.js +330 -0
- package/src/lib/instinct-manager.js +332 -0
- package/src/lib/ipfs-storage.js +334 -0
- package/src/lib/knowledge-exporter.js +381 -0
- package/src/lib/knowledge-graph.js +432 -0
- package/src/lib/knowledge-importer.js +379 -0
- package/src/lib/llm-providers.js +391 -0
- package/src/lib/mcp-registry.js +333 -0
- package/src/lib/memory-manager.js +330 -0
- package/src/lib/multimodal.js +346 -0
- package/src/lib/nl-programming.js +343 -0
- package/src/lib/note-versioning.js +327 -0
- package/src/lib/org-manager.js +323 -0
- package/src/lib/p2p-manager.js +387 -0
- package/src/lib/perception.js +346 -0
- package/src/lib/perf-tuning.js +4 -1
- package/src/lib/permanent-memory.js +320 -0
- package/src/lib/plugin-ecosystem.js +377 -0
- package/src/lib/pqc-manager.js +368 -0
- package/src/lib/privacy-computing.js +427 -0
- package/src/lib/protocol-fusion.js +417 -0
- package/src/lib/quantization.js +325 -0
- package/src/lib/reputation-optimizer.js +299 -0
- package/src/lib/response-cache.js +327 -0
- package/src/lib/scim-manager.js +329 -0
- package/src/lib/session-manager.js +329 -0
- package/src/lib/siem-exporter.js +333 -0
- package/src/lib/skill-loader.js +377 -0
- package/src/lib/skill-marketplace.js +325 -0
- package/src/lib/sla-manager.js +275 -0
- package/src/lib/social-manager.js +326 -0
- package/src/lib/sso-manager.js +332 -0
- package/src/lib/stress-tester.js +330 -0
- package/src/lib/sync-manager.js +326 -0
- package/src/lib/tech-learning-engine.js +369 -0
- package/src/lib/tenant-saas.js +460 -0
- package/src/lib/terraform-manager.js +363 -0
- package/src/lib/threat-intel.js +335 -0
- package/src/lib/token-incentive.js +293 -0
- package/src/lib/token-tracker.js +329 -0
- package/src/lib/trust-security.js +390 -0
- package/src/lib/ueba.js +389 -0
- package/src/lib/universal-runtime.js +325 -0
- package/src/lib/wallet-manager.js +326 -0
- package/src/lib/workflow-engine.js +322 -0
- package/src/lib/zkp-engine.js +274 -0
package/src/commands/lowcode.js
CHANGED
|
@@ -20,7 +20,22 @@ import {
|
|
|
20
20
|
exportApp,
|
|
21
21
|
listApps,
|
|
22
22
|
deployApp,
|
|
23
|
+
// Phase 93 V2 surface
|
|
24
|
+
COMPONENT_CATEGORY,
|
|
25
|
+
DATASOURCE_TYPE,
|
|
26
|
+
APP_STATUS,
|
|
27
|
+
listComponentsV2,
|
|
28
|
+
registerDataSourceV2,
|
|
29
|
+
testDataSourceConnection,
|
|
30
|
+
updateAppStatus,
|
|
31
|
+
archiveApp,
|
|
32
|
+
getStatusHistory,
|
|
33
|
+
cloneApp,
|
|
34
|
+
exportAppJSON,
|
|
35
|
+
importAppJSON,
|
|
36
|
+
getLowcodeStatsV2,
|
|
23
37
|
} from "../lib/app-builder.js";
|
|
38
|
+
import fs from "fs";
|
|
24
39
|
|
|
25
40
|
export function registerLowcodeCommand(program) {
|
|
26
41
|
const lowcode = program
|
|
@@ -305,6 +320,347 @@ export function registerLowcodeCommand(program) {
|
|
|
305
320
|
}
|
|
306
321
|
});
|
|
307
322
|
|
|
323
|
+
// ─── Phase 93 V2 subcommands ────────────────────────────────
|
|
324
|
+
|
|
325
|
+
// lowcode categories
|
|
326
|
+
lowcode
|
|
327
|
+
.command("categories")
|
|
328
|
+
.description("List component categories (V2)")
|
|
329
|
+
.option("--json", "Output as JSON")
|
|
330
|
+
.action((options) => {
|
|
331
|
+
const categories = Object.values(COMPONENT_CATEGORY);
|
|
332
|
+
if (options.json) {
|
|
333
|
+
console.log(JSON.stringify(categories, null, 2));
|
|
334
|
+
} else {
|
|
335
|
+
logger.log(chalk.bold("Component Categories:"));
|
|
336
|
+
for (const c of categories) logger.log(` ${chalk.cyan(c)}`);
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
// lowcode datasource-types
|
|
341
|
+
lowcode
|
|
342
|
+
.command("datasource-types")
|
|
343
|
+
.description("List supported data source types (V2)")
|
|
344
|
+
.option("--json", "Output as JSON")
|
|
345
|
+
.action((options) => {
|
|
346
|
+
const types = Object.values(DATASOURCE_TYPE);
|
|
347
|
+
if (options.json) {
|
|
348
|
+
console.log(JSON.stringify(types, null, 2));
|
|
349
|
+
} else {
|
|
350
|
+
logger.log(chalk.bold("Data Source Types:"));
|
|
351
|
+
for (const t of types) logger.log(` ${chalk.cyan(t)}`);
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// lowcode statuses
|
|
356
|
+
lowcode
|
|
357
|
+
.command("statuses")
|
|
358
|
+
.description("List canonical app statuses (V2)")
|
|
359
|
+
.option("--json", "Output as JSON")
|
|
360
|
+
.action((options) => {
|
|
361
|
+
const statuses = Object.values(APP_STATUS);
|
|
362
|
+
if (options.json) {
|
|
363
|
+
console.log(JSON.stringify(statuses, null, 2));
|
|
364
|
+
} else {
|
|
365
|
+
logger.log(chalk.bold("App Statuses:"));
|
|
366
|
+
for (const s of statuses) logger.log(` ${chalk.cyan(s)}`);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
// lowcode components-v2
|
|
371
|
+
lowcode
|
|
372
|
+
.command("components-v2")
|
|
373
|
+
.description("List built-in components with category filter (V2)")
|
|
374
|
+
.option("-c, --category <cat>", "Filter by category")
|
|
375
|
+
.option("--json", "Output as JSON")
|
|
376
|
+
.action((options) => {
|
|
377
|
+
try {
|
|
378
|
+
const list = listComponentsV2(
|
|
379
|
+
options.category ? { category: options.category } : {},
|
|
380
|
+
);
|
|
381
|
+
if (options.json) {
|
|
382
|
+
console.log(JSON.stringify(list, null, 2));
|
|
383
|
+
} else {
|
|
384
|
+
logger.log(chalk.bold(`Components (${list.length}):`));
|
|
385
|
+
for (const c of list) {
|
|
386
|
+
logger.log(
|
|
387
|
+
` ${chalk.cyan(c.name)} [${c.category}] props: ${c.props.join(", ")}`,
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
} catch (err) {
|
|
392
|
+
logger.error(err.message);
|
|
393
|
+
process.exit(1);
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
// lowcode datasource-v2 <app-id> <name> <type>
|
|
398
|
+
lowcode
|
|
399
|
+
.command("datasource-v2")
|
|
400
|
+
.description("Register a validated data source (V2)")
|
|
401
|
+
.argument("<app-id>", "Application ID")
|
|
402
|
+
.argument("<name>", "Data source name")
|
|
403
|
+
.argument("<type>", "Type: rest|graphql|database|csv")
|
|
404
|
+
.option("--config <json>", "Config as JSON string", "{}")
|
|
405
|
+
.action(async (appId, name, type, options) => {
|
|
406
|
+
const spinner = ora("Registering data source...").start();
|
|
407
|
+
try {
|
|
408
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
409
|
+
if (!ctx.db) {
|
|
410
|
+
spinner.fail("Database not available");
|
|
411
|
+
process.exit(1);
|
|
412
|
+
}
|
|
413
|
+
const db = ctx.db.getDatabase();
|
|
414
|
+
ensureLowcodeTables(db);
|
|
415
|
+
|
|
416
|
+
let config;
|
|
417
|
+
try {
|
|
418
|
+
config = JSON.parse(options.config);
|
|
419
|
+
} catch (_err) {
|
|
420
|
+
config = {};
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
const result = registerDataSourceV2(db, {
|
|
424
|
+
appId,
|
|
425
|
+
name,
|
|
426
|
+
type,
|
|
427
|
+
config,
|
|
428
|
+
});
|
|
429
|
+
spinner.succeed(
|
|
430
|
+
`Data source "${chalk.cyan(name)}" registered (${type})`,
|
|
431
|
+
);
|
|
432
|
+
logger.log(` ID: ${chalk.gray(result.id)}`);
|
|
433
|
+
|
|
434
|
+
await shutdown();
|
|
435
|
+
} catch (err) {
|
|
436
|
+
spinner.fail(err.message);
|
|
437
|
+
process.exit(1);
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
// lowcode test-connection <datasource-id>
|
|
442
|
+
lowcode
|
|
443
|
+
.command("test-connection")
|
|
444
|
+
.description("Heuristic connection check for a data source (V2)")
|
|
445
|
+
.argument("<datasource-id>", "Data source ID")
|
|
446
|
+
.option("--json", "Output as JSON")
|
|
447
|
+
.action((dsId, options) => {
|
|
448
|
+
const result = testDataSourceConnection(dsId);
|
|
449
|
+
if (options.json) {
|
|
450
|
+
console.log(JSON.stringify(result, null, 2));
|
|
451
|
+
} else {
|
|
452
|
+
const icon = result.ok ? chalk.green("✓") : chalk.red("✗");
|
|
453
|
+
logger.log(
|
|
454
|
+
`${icon} ${chalk.cyan(dsId)} (${result.type || "?"}): ${result.reason}`,
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
// lowcode set-status <app-id> <status>
|
|
460
|
+
lowcode
|
|
461
|
+
.command("set-status")
|
|
462
|
+
.description("Update app status with validated transition (V2)")
|
|
463
|
+
.argument("<app-id>", "Application ID")
|
|
464
|
+
.argument("<status>", "New status: draft|published|archived")
|
|
465
|
+
.action(async (appId, status) => {
|
|
466
|
+
const spinner = ora(`Transitioning to ${status}...`).start();
|
|
467
|
+
try {
|
|
468
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
469
|
+
if (!ctx.db) {
|
|
470
|
+
spinner.fail("Database not available");
|
|
471
|
+
process.exit(1);
|
|
472
|
+
}
|
|
473
|
+
const db = ctx.db.getDatabase();
|
|
474
|
+
ensureLowcodeTables(db);
|
|
475
|
+
|
|
476
|
+
const result = updateAppStatus(db, { appId, status });
|
|
477
|
+
spinner.succeed(
|
|
478
|
+
`${chalk.cyan(appId)}: ${result.previous} → ${chalk.bold(result.status)}`,
|
|
479
|
+
);
|
|
480
|
+
|
|
481
|
+
await shutdown();
|
|
482
|
+
} catch (err) {
|
|
483
|
+
spinner.fail(err.message);
|
|
484
|
+
process.exit(1);
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
// lowcode archive <app-id>
|
|
489
|
+
lowcode
|
|
490
|
+
.command("archive")
|
|
491
|
+
.description("Archive an application (V2)")
|
|
492
|
+
.argument("<app-id>", "Application ID")
|
|
493
|
+
.action(async (appId) => {
|
|
494
|
+
const spinner = ora("Archiving...").start();
|
|
495
|
+
try {
|
|
496
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
497
|
+
if (!ctx.db) {
|
|
498
|
+
spinner.fail("Database not available");
|
|
499
|
+
process.exit(1);
|
|
500
|
+
}
|
|
501
|
+
const db = ctx.db.getDatabase();
|
|
502
|
+
ensureLowcodeTables(db);
|
|
503
|
+
|
|
504
|
+
archiveApp(db, appId);
|
|
505
|
+
spinner.succeed(`${chalk.cyan(appId)} archived`);
|
|
506
|
+
|
|
507
|
+
await shutdown();
|
|
508
|
+
} catch (err) {
|
|
509
|
+
spinner.fail(err.message);
|
|
510
|
+
process.exit(1);
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
// lowcode status-history <app-id>
|
|
515
|
+
lowcode
|
|
516
|
+
.command("status-history")
|
|
517
|
+
.description("Show status transition history for an app (V2)")
|
|
518
|
+
.argument("<app-id>", "Application ID")
|
|
519
|
+
.option("--json", "Output as JSON")
|
|
520
|
+
.action((appId, options) => {
|
|
521
|
+
const hist = getStatusHistory(appId);
|
|
522
|
+
if (options.json) {
|
|
523
|
+
console.log(JSON.stringify(hist, null, 2));
|
|
524
|
+
} else if (hist.length === 0) {
|
|
525
|
+
logger.info("No status transitions recorded");
|
|
526
|
+
} else {
|
|
527
|
+
logger.log(chalk.bold(`Status History (${hist.length}):`));
|
|
528
|
+
for (const h of hist) {
|
|
529
|
+
logger.log(` ${chalk.gray(h.at)} ${h.from} → ${chalk.cyan(h.to)}`);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
// lowcode clone <source-id>
|
|
535
|
+
lowcode
|
|
536
|
+
.command("clone")
|
|
537
|
+
.description("Clone an application (V2)")
|
|
538
|
+
.argument("<source-id>", "Source app ID")
|
|
539
|
+
.option("--name <name>", "New name for the clone")
|
|
540
|
+
.action(async (sourceId, options) => {
|
|
541
|
+
const spinner = ora("Cloning...").start();
|
|
542
|
+
try {
|
|
543
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
544
|
+
if (!ctx.db) {
|
|
545
|
+
spinner.fail("Database not available");
|
|
546
|
+
process.exit(1);
|
|
547
|
+
}
|
|
548
|
+
const db = ctx.db.getDatabase();
|
|
549
|
+
ensureLowcodeTables(db);
|
|
550
|
+
|
|
551
|
+
const result = cloneApp(db, {
|
|
552
|
+
sourceId,
|
|
553
|
+
newName: options.name,
|
|
554
|
+
});
|
|
555
|
+
spinner.succeed(`Cloned ${chalk.cyan(sourceId)} → ${result.clonedId}`);
|
|
556
|
+
logger.log(` Name: ${result.name}`);
|
|
557
|
+
|
|
558
|
+
await shutdown();
|
|
559
|
+
} catch (err) {
|
|
560
|
+
spinner.fail(err.message);
|
|
561
|
+
process.exit(1);
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
// lowcode export-json <app-id>
|
|
566
|
+
lowcode
|
|
567
|
+
.command("export-json")
|
|
568
|
+
.description("Export an app as canonical JSON (V2)")
|
|
569
|
+
.argument("<app-id>", "Application ID")
|
|
570
|
+
.option("-o, --output <file>", "Write to file instead of stdout")
|
|
571
|
+
.action(async (appId, options) => {
|
|
572
|
+
try {
|
|
573
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
574
|
+
if (!ctx.db) {
|
|
575
|
+
logger.error("Database not available");
|
|
576
|
+
process.exit(1);
|
|
577
|
+
}
|
|
578
|
+
const db = ctx.db.getDatabase();
|
|
579
|
+
ensureLowcodeTables(db);
|
|
580
|
+
|
|
581
|
+
const result = exportAppJSON(db, appId);
|
|
582
|
+
const json = JSON.stringify(result, null, 2);
|
|
583
|
+
if (options.output) {
|
|
584
|
+
fs.writeFileSync(options.output, json, "utf-8");
|
|
585
|
+
logger.log(chalk.green(`Wrote ${options.output}`));
|
|
586
|
+
} else {
|
|
587
|
+
console.log(json);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
await shutdown();
|
|
591
|
+
} catch (err) {
|
|
592
|
+
logger.error(err.message);
|
|
593
|
+
process.exit(1);
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
// lowcode import-json <file>
|
|
598
|
+
lowcode
|
|
599
|
+
.command("import-json")
|
|
600
|
+
.description("Import an app from a canonical JSON file (V2)")
|
|
601
|
+
.argument("<file>", "Path to JSON export")
|
|
602
|
+
.action(async (file) => {
|
|
603
|
+
const spinner = ora("Importing...").start();
|
|
604
|
+
try {
|
|
605
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
606
|
+
if (!ctx.db) {
|
|
607
|
+
spinner.fail("Database not available");
|
|
608
|
+
process.exit(1);
|
|
609
|
+
}
|
|
610
|
+
const db = ctx.db.getDatabase();
|
|
611
|
+
ensureLowcodeTables(db);
|
|
612
|
+
|
|
613
|
+
const raw = fs.readFileSync(file, "utf-8");
|
|
614
|
+
const json = JSON.parse(raw);
|
|
615
|
+
const result = importAppJSON(db, json);
|
|
616
|
+
spinner.succeed(
|
|
617
|
+
`Imported "${chalk.cyan(result.name)}" → ${result.importedId}`,
|
|
618
|
+
);
|
|
619
|
+
logger.log(` Data sources: ${result.dataSources}`);
|
|
620
|
+
|
|
621
|
+
await shutdown();
|
|
622
|
+
} catch (err) {
|
|
623
|
+
spinner.fail(err.message);
|
|
624
|
+
process.exit(1);
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
// lowcode stats-v2
|
|
629
|
+
lowcode
|
|
630
|
+
.command("stats-v2")
|
|
631
|
+
.description("Low-code platform statistics (V2)")
|
|
632
|
+
.option("--json", "Output as JSON")
|
|
633
|
+
.action(async (options) => {
|
|
634
|
+
try {
|
|
635
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
636
|
+
if (!ctx.db) {
|
|
637
|
+
logger.error("Database not available");
|
|
638
|
+
process.exit(1);
|
|
639
|
+
}
|
|
640
|
+
const db = ctx.db.getDatabase();
|
|
641
|
+
ensureLowcodeTables(db);
|
|
642
|
+
|
|
643
|
+
const stats = getLowcodeStatsV2(db);
|
|
644
|
+
if (options.json) {
|
|
645
|
+
console.log(JSON.stringify(stats, null, 2));
|
|
646
|
+
} else {
|
|
647
|
+
logger.log(chalk.bold("Low-Code Stats (V2):"));
|
|
648
|
+
logger.log(` Total apps: ${chalk.cyan(stats.totalApps)}`);
|
|
649
|
+
logger.log(` By status: ${JSON.stringify(stats.byStatus)}`);
|
|
650
|
+
logger.log(` By platform: ${JSON.stringify(stats.byPlatform)}`);
|
|
651
|
+
logger.log(
|
|
652
|
+
` Data sources: ${stats.dataSources.total} (${JSON.stringify(stats.dataSources.byType)})`,
|
|
653
|
+
);
|
|
654
|
+
logger.log(` Components: ${stats.componentsAvailable}`);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
await shutdown();
|
|
658
|
+
} catch (err) {
|
|
659
|
+
logger.error(err.message);
|
|
660
|
+
process.exit(1);
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
|
|
308
664
|
// lowcode deploy <app-id>
|
|
309
665
|
lowcode
|
|
310
666
|
.command("deploy")
|
|
@@ -18,6 +18,21 @@ import {
|
|
|
18
18
|
recordInvocation,
|
|
19
19
|
listInvocations,
|
|
20
20
|
getInvocationStats,
|
|
21
|
+
// V2 (Phase 65)
|
|
22
|
+
SERVICE_STATUS_V2,
|
|
23
|
+
INVOCATION_STATUS_V2,
|
|
24
|
+
PRICING_MODEL_V2,
|
|
25
|
+
MARKETPLACE_DEFAULT_MAX_CONCURRENT_INVOCATIONS,
|
|
26
|
+
setMaxConcurrentInvocations,
|
|
27
|
+
getMaxConcurrentInvocations,
|
|
28
|
+
getActiveInvocationCount,
|
|
29
|
+
beginInvocationV2,
|
|
30
|
+
startInvocation,
|
|
31
|
+
completeInvocationV2,
|
|
32
|
+
failInvocationV2,
|
|
33
|
+
timeoutInvocationV2,
|
|
34
|
+
setInvocationStatus,
|
|
35
|
+
getMarketplaceStatsV2,
|
|
21
36
|
} from "../lib/skill-marketplace.js";
|
|
22
37
|
|
|
23
38
|
function _dbFromCtx(ctx) {
|
|
@@ -323,4 +338,245 @@ export function registerMarketplaceCommand(program) {
|
|
|
323
338
|
process.exit(1);
|
|
324
339
|
}
|
|
325
340
|
});
|
|
341
|
+
|
|
342
|
+
/* ── V2 (Phase 65) ───────────────────────────────────────── */
|
|
343
|
+
|
|
344
|
+
mp.command("service-statuses-v2")
|
|
345
|
+
.description("List V2 service statuses (frozen enum)")
|
|
346
|
+
.option("--json", "Output as JSON")
|
|
347
|
+
.action((options) => {
|
|
348
|
+
const values = Object.values(SERVICE_STATUS_V2);
|
|
349
|
+
if (options.json) console.log(JSON.stringify(values, null, 2));
|
|
350
|
+
else for (const v of values) logger.log(` ${chalk.cyan(v)}`);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
mp.command("invocation-statuses-v2")
|
|
354
|
+
.description("List V2 invocation statuses (frozen enum)")
|
|
355
|
+
.option("--json", "Output as JSON")
|
|
356
|
+
.action((options) => {
|
|
357
|
+
const values = Object.values(INVOCATION_STATUS_V2);
|
|
358
|
+
if (options.json) console.log(JSON.stringify(values, null, 2));
|
|
359
|
+
else for (const v of values) logger.log(` ${chalk.cyan(v)}`);
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
mp.command("pricing-models")
|
|
363
|
+
.description("List V2 pricing models (frozen enum)")
|
|
364
|
+
.option("--json", "Output as JSON")
|
|
365
|
+
.action((options) => {
|
|
366
|
+
const values = Object.values(PRICING_MODEL_V2);
|
|
367
|
+
if (options.json) console.log(JSON.stringify(values, null, 2));
|
|
368
|
+
else for (const v of values) logger.log(` ${chalk.cyan(v)}`);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
mp.command("default-max-concurrent")
|
|
372
|
+
.description("Show default per-service concurrency cap")
|
|
373
|
+
.action(() => {
|
|
374
|
+
logger.log(` ${MARKETPLACE_DEFAULT_MAX_CONCURRENT_INVOCATIONS}`);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
mp.command("max-concurrent")
|
|
378
|
+
.description("Show current per-service concurrency cap")
|
|
379
|
+
.action(() => {
|
|
380
|
+
logger.log(` ${getMaxConcurrentInvocations()}`);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
mp.command("active-invocation-count [service-id]")
|
|
384
|
+
.description(
|
|
385
|
+
"Show count of PENDING + RUNNING invocations (all services by default)",
|
|
386
|
+
)
|
|
387
|
+
.action((serviceId) => {
|
|
388
|
+
logger.log(` ${getActiveInvocationCount(serviceId)}`);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
mp.command("set-max-concurrent <n>")
|
|
392
|
+
.description("Set the per-service concurrency cap")
|
|
393
|
+
.action((n) => {
|
|
394
|
+
try {
|
|
395
|
+
const v = setMaxConcurrentInvocations(Number(n));
|
|
396
|
+
logger.success(`Max concurrent invocations = ${v}`);
|
|
397
|
+
} catch (err) {
|
|
398
|
+
logger.error(`Failed: ${err.message}`);
|
|
399
|
+
process.exit(1);
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
mp.command("begin-v2 <service-id>")
|
|
404
|
+
.description("Begin a V2 invocation (creates PENDING, enforces cap)")
|
|
405
|
+
.option("-c, --caller <id>", "Caller ID")
|
|
406
|
+
.option("-i, --input <json>", "JSON-encoded input")
|
|
407
|
+
.option("--json", "Output as JSON")
|
|
408
|
+
.action(async (serviceId, options) => {
|
|
409
|
+
try {
|
|
410
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
411
|
+
const db = _dbFromCtx(ctx);
|
|
412
|
+
let input = null;
|
|
413
|
+
if (options.input) {
|
|
414
|
+
try {
|
|
415
|
+
input = JSON.parse(options.input);
|
|
416
|
+
} catch {
|
|
417
|
+
input = options.input;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
const inv = beginInvocationV2(db, {
|
|
421
|
+
serviceId,
|
|
422
|
+
callerId: options.caller,
|
|
423
|
+
input,
|
|
424
|
+
});
|
|
425
|
+
if (options.json) console.log(JSON.stringify(inv, null, 2));
|
|
426
|
+
else {
|
|
427
|
+
logger.success(`Invocation queued [${inv.status}]`);
|
|
428
|
+
logger.log(` ${chalk.bold("ID:")} ${chalk.cyan(inv.id)}`);
|
|
429
|
+
}
|
|
430
|
+
await shutdown();
|
|
431
|
+
} catch (err) {
|
|
432
|
+
logger.error(`Failed: ${err.message}`);
|
|
433
|
+
process.exit(1);
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
mp.command("start-invocation <invocation-id>")
|
|
438
|
+
.description("Start a V2 invocation (PENDING → RUNNING)")
|
|
439
|
+
.option("--json", "Output as JSON")
|
|
440
|
+
.action(async (invocationId, options) => {
|
|
441
|
+
try {
|
|
442
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
443
|
+
const db = _dbFromCtx(ctx);
|
|
444
|
+
const result = startInvocation(db, invocationId);
|
|
445
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
446
|
+
else logger.success(`Status = ${result.status}`);
|
|
447
|
+
await shutdown();
|
|
448
|
+
} catch (err) {
|
|
449
|
+
logger.error(`Failed: ${err.message}`);
|
|
450
|
+
process.exit(1);
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
mp.command("complete-invocation <invocation-id>")
|
|
455
|
+
.description("Complete a V2 invocation (RUNNING → SUCCESS)")
|
|
456
|
+
.option("-o, --output <json>", "JSON-encoded output")
|
|
457
|
+
.option("-d, --duration-ms <n>", "Duration in milliseconds", parseInt)
|
|
458
|
+
.option("--json", "Output as JSON")
|
|
459
|
+
.action(async (invocationId, options) => {
|
|
460
|
+
try {
|
|
461
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
462
|
+
const db = _dbFromCtx(ctx);
|
|
463
|
+
let output = null;
|
|
464
|
+
if (options.output) {
|
|
465
|
+
try {
|
|
466
|
+
output = JSON.parse(options.output);
|
|
467
|
+
} catch {
|
|
468
|
+
output = options.output;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
const result = completeInvocationV2(db, invocationId, {
|
|
472
|
+
output,
|
|
473
|
+
durationMs: options.durationMs,
|
|
474
|
+
});
|
|
475
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
476
|
+
else logger.success(`Status = ${result.status}`);
|
|
477
|
+
await shutdown();
|
|
478
|
+
} catch (err) {
|
|
479
|
+
logger.error(`Failed: ${err.message}`);
|
|
480
|
+
process.exit(1);
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
mp.command("fail-invocation <invocation-id>")
|
|
485
|
+
.description("Fail a V2 invocation")
|
|
486
|
+
.option("-m, --message <msg>", "Error message")
|
|
487
|
+
.option("-d, --duration-ms <n>", "Duration in milliseconds", parseInt)
|
|
488
|
+
.action(async (invocationId, options) => {
|
|
489
|
+
try {
|
|
490
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
491
|
+
const db = _dbFromCtx(ctx);
|
|
492
|
+
const result = failInvocationV2(db, invocationId, options.message, {
|
|
493
|
+
durationMs: options.durationMs,
|
|
494
|
+
});
|
|
495
|
+
logger.success(`Status = ${result.status}`);
|
|
496
|
+
if (result.error) logger.log(` Error: ${result.error}`);
|
|
497
|
+
await shutdown();
|
|
498
|
+
} catch (err) {
|
|
499
|
+
logger.error(`Failed: ${err.message}`);
|
|
500
|
+
process.exit(1);
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
mp.command("timeout-invocation <invocation-id>")
|
|
505
|
+
.description("Timeout a V2 invocation")
|
|
506
|
+
.option("-d, --duration-ms <n>", "Duration in milliseconds", parseInt)
|
|
507
|
+
.action(async (invocationId, options) => {
|
|
508
|
+
try {
|
|
509
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
510
|
+
const db = _dbFromCtx(ctx);
|
|
511
|
+
const result = timeoutInvocationV2(db, invocationId, {
|
|
512
|
+
durationMs: options.durationMs,
|
|
513
|
+
});
|
|
514
|
+
logger.success(`Status = ${result.status}`);
|
|
515
|
+
await shutdown();
|
|
516
|
+
} catch (err) {
|
|
517
|
+
logger.error(`Failed: ${err.message}`);
|
|
518
|
+
process.exit(1);
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
mp.command("set-invocation-status <invocation-id> <status>")
|
|
523
|
+
.description("Set V2 invocation status via the state machine")
|
|
524
|
+
.option("-m, --message <msg>", "Error message (FAILED/TIMEOUT)")
|
|
525
|
+
.option("--json", "Output as JSON")
|
|
526
|
+
.action(async (invocationId, status, options) => {
|
|
527
|
+
try {
|
|
528
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
529
|
+
const db = _dbFromCtx(ctx);
|
|
530
|
+
const patch = options.message ? { error: options.message } : {};
|
|
531
|
+
const result = setInvocationStatus(db, invocationId, status, patch);
|
|
532
|
+
if (options.json) console.log(JSON.stringify(result, null, 2));
|
|
533
|
+
else logger.success(`Status = ${result.status}`);
|
|
534
|
+
await shutdown();
|
|
535
|
+
} catch (err) {
|
|
536
|
+
logger.error(`Failed: ${err.message}`);
|
|
537
|
+
process.exit(1);
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
mp.command("stats-v2")
|
|
542
|
+
.description("V2 aggregated stats")
|
|
543
|
+
.option("--json", "Output as JSON")
|
|
544
|
+
.action(async (options) => {
|
|
545
|
+
try {
|
|
546
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
547
|
+
_dbFromCtx(ctx);
|
|
548
|
+
const stats = getMarketplaceStatsV2();
|
|
549
|
+
if (options.json) console.log(JSON.stringify(stats, null, 2));
|
|
550
|
+
else {
|
|
551
|
+
logger.log(
|
|
552
|
+
` ${chalk.bold("Services:")} ${stats.totalServices}`,
|
|
553
|
+
);
|
|
554
|
+
logger.log(
|
|
555
|
+
` ${chalk.bold("Invocations:")} ${stats.totalInvocations} (active: ${stats.activeInvocations})`,
|
|
556
|
+
);
|
|
557
|
+
logger.log(
|
|
558
|
+
` ${chalk.bold("Max concurrent:")} ${stats.maxConcurrentInvocations}`,
|
|
559
|
+
);
|
|
560
|
+
logger.log(` ${chalk.bold("Services by status:")}`);
|
|
561
|
+
for (const [k, v] of Object.entries(stats.servicesByStatus))
|
|
562
|
+
logger.log(` ${k.padEnd(12)} ${v}`);
|
|
563
|
+
logger.log(` ${chalk.bold("Services by pricing:")}`);
|
|
564
|
+
for (const [k, v] of Object.entries(stats.servicesByPricing))
|
|
565
|
+
logger.log(` ${k.padEnd(14)} ${v}`);
|
|
566
|
+
logger.log(` ${chalk.bold("Invocations by status:")}`);
|
|
567
|
+
for (const [k, v] of Object.entries(stats.invocationsByStatus))
|
|
568
|
+
logger.log(` ${k.padEnd(10)} ${v}`);
|
|
569
|
+
logger.log(
|
|
570
|
+
` ${chalk.bold("Success rate:")} ${(stats.successRate * 100).toFixed(1)}%`,
|
|
571
|
+
);
|
|
572
|
+
logger.log(
|
|
573
|
+
` ${chalk.bold("Avg duration:")} ${stats.avgDurationMs}ms`,
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
await shutdown();
|
|
577
|
+
} catch (err) {
|
|
578
|
+
logger.error(`Failed: ${err.message}`);
|
|
579
|
+
process.exit(1);
|
|
580
|
+
}
|
|
581
|
+
});
|
|
326
582
|
}
|