@llm-dev-ops/agentics-cli 1.4.13 → 1.4.15

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.
Files changed (116) hide show
  1. package/dist/adapters/base-adapter.d.ts.map +1 -1
  2. package/dist/adapters/base-adapter.js +66 -18
  3. package/dist/adapters/base-adapter.js.map +1 -1
  4. package/dist/agents/cli-ux-agent.d.ts +9 -3
  5. package/dist/agents/cli-ux-agent.d.ts.map +1 -1
  6. package/dist/agents/cli-ux-agent.js +13 -67
  7. package/dist/agents/cli-ux-agent.js.map +1 -1
  8. package/dist/agents/decision-event.d.ts +1 -1
  9. package/dist/agents/decision-event.d.ts.map +1 -1
  10. package/dist/agents/decision-event.js +12 -7
  11. package/dist/agents/decision-event.js.map +1 -1
  12. package/dist/auth/internal-allowlist.d.ts +19 -17
  13. package/dist/auth/internal-allowlist.d.ts.map +1 -1
  14. package/dist/auth/internal-allowlist.js +20 -90
  15. package/dist/auth/internal-allowlist.js.map +1 -1
  16. package/dist/auth/role-permissions.d.ts +23 -6
  17. package/dist/auth/role-permissions.d.ts.map +1 -1
  18. package/dist/auth/role-permissions.js +25 -37
  19. package/dist/auth/role-permissions.js.map +1 -1
  20. package/dist/cli/index.js +346 -33
  21. package/dist/cli/index.js.map +1 -1
  22. package/dist/commands/demo.d.ts +30 -0
  23. package/dist/commands/demo.d.ts.map +1 -0
  24. package/dist/commands/demo.js +393 -0
  25. package/dist/commands/demo.js.map +1 -0
  26. package/dist/commands/diligence.d.ts.map +1 -1
  27. package/dist/commands/diligence.js +10 -15
  28. package/dist/commands/diligence.js.map +1 -1
  29. package/dist/commands/export.d.ts.map +1 -1
  30. package/dist/commands/export.js +5 -7
  31. package/dist/commands/export.js.map +1 -1
  32. package/dist/commands/inspect.d.ts +17 -4
  33. package/dist/commands/inspect.d.ts.map +1 -1
  34. package/dist/commands/inspect.js +189 -77
  35. package/dist/commands/inspect.js.map +1 -1
  36. package/dist/commands/quantify.d.ts.map +1 -1
  37. package/dist/commands/quantify.js +12 -0
  38. package/dist/commands/quantify.js.map +1 -1
  39. package/dist/commands/readiness.d.ts +47 -0
  40. package/dist/commands/readiness.d.ts.map +1 -0
  41. package/dist/commands/readiness.js +270 -0
  42. package/dist/commands/readiness.js.map +1 -0
  43. package/dist/commands/simulate.d.ts +6 -0
  44. package/dist/commands/simulate.d.ts.map +1 -1
  45. package/dist/commands/simulate.js +167 -123
  46. package/dist/commands/simulate.js.map +1 -1
  47. package/dist/commands/whoami.js +3 -3
  48. package/dist/commands/whoami.js.map +1 -1
  49. package/dist/config/endpoints.js +2 -2
  50. package/dist/config/endpoints.js.map +1 -1
  51. package/dist/contracts/adr-command-semantics.js +3 -3
  52. package/dist/contracts/adr-command-semantics.js.map +1 -1
  53. package/dist/contracts/canonical.d.ts +207 -0
  54. package/dist/contracts/canonical.d.ts.map +1 -0
  55. package/dist/contracts/canonical.js +191 -0
  56. package/dist/contracts/canonical.js.map +1 -0
  57. package/dist/contracts/index.d.ts +3 -1
  58. package/dist/contracts/index.d.ts.map +1 -1
  59. package/dist/contracts/index.js +2 -0
  60. package/dist/contracts/index.js.map +1 -1
  61. package/dist/contracts/schemas/index.d.ts +194 -5
  62. package/dist/contracts/schemas/index.d.ts.map +1 -1
  63. package/dist/contracts/schemas/index.js +106 -0
  64. package/dist/contracts/schemas/index.js.map +1 -1
  65. package/dist/contracts/validator.d.ts +1 -1
  66. package/dist/contracts/validator.d.ts.map +1 -1
  67. package/dist/contracts/validator.js +17 -5
  68. package/dist/contracts/validator.js.map +1 -1
  69. package/dist/gates/argument-guard.js +1 -1
  70. package/dist/gates/argument-guard.js.map +1 -1
  71. package/dist/gates/execution-gate.d.ts +24 -54
  72. package/dist/gates/execution-gate.d.ts.map +1 -1
  73. package/dist/gates/execution-gate.js +79 -166
  74. package/dist/gates/execution-gate.js.map +1 -1
  75. package/dist/gates/index.d.ts +6 -0
  76. package/dist/gates/index.d.ts.map +1 -1
  77. package/dist/gates/index.js +8 -0
  78. package/dist/gates/index.js.map +1 -1
  79. package/dist/gates/meta-simulation-detector.d.ts +48 -0
  80. package/dist/gates/meta-simulation-detector.d.ts.map +1 -0
  81. package/dist/gates/meta-simulation-detector.js +45 -0
  82. package/dist/gates/meta-simulation-detector.js.map +1 -0
  83. package/dist/gates/readiness-gate.d.ts +108 -0
  84. package/dist/gates/readiness-gate.d.ts.map +1 -0
  85. package/dist/gates/readiness-gate.js +194 -0
  86. package/dist/gates/readiness-gate.js.map +1 -0
  87. package/dist/gates/ruvector-acceptance-gate.d.ts +78 -0
  88. package/dist/gates/ruvector-acceptance-gate.d.ts.map +1 -0
  89. package/dist/gates/ruvector-acceptance-gate.js +191 -0
  90. package/dist/gates/ruvector-acceptance-gate.js.map +1 -0
  91. package/dist/modules/artifact-handoff.d.ts.map +1 -1
  92. package/dist/modules/artifact-handoff.js +26 -0
  93. package/dist/modules/artifact-handoff.js.map +1 -1
  94. package/dist/modules/command-parser.d.ts +1 -1
  95. package/dist/modules/command-parser.d.ts.map +1 -1
  96. package/dist/modules/command-parser.js +3 -1
  97. package/dist/modules/command-parser.js.map +1 -1
  98. package/dist/modules/output-renderer.d.ts +13 -1
  99. package/dist/modules/output-renderer.d.ts.map +1 -1
  100. package/dist/modules/output-renderer.js +68 -0
  101. package/dist/modules/output-renderer.js.map +1 -1
  102. package/dist/runtime/claude-code-runner.d.ts.map +1 -1
  103. package/dist/runtime/claude-code-runner.js +165 -0
  104. package/dist/runtime/claude-code-runner.js.map +1 -1
  105. package/dist/synthesis/dynamic-router.d.ts +80 -0
  106. package/dist/synthesis/dynamic-router.d.ts.map +1 -0
  107. package/dist/synthesis/dynamic-router.js +63 -0
  108. package/dist/synthesis/dynamic-router.js.map +1 -0
  109. package/dist/synthesis/prompts/index.d.ts.map +1 -1
  110. package/dist/synthesis/prompts/index.js +100 -23
  111. package/dist/synthesis/prompts/index.js.map +1 -1
  112. package/dist/types/index.d.ts +59 -0
  113. package/dist/types/index.d.ts.map +1 -1
  114. package/dist/types/index.js +8 -0
  115. package/dist/types/index.js.map +1 -1
  116. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -72,6 +72,23 @@ import { executeDiligenceCommand } from '../commands/diligence.js';
72
72
  import { executeUsageCommand, executeUsageHistoryCommand, executeUsageLimitsCommand, executeUsageResetCommand, formatUsageForDisplay, formatHistoryForDisplay, formatLimitsForDisplay, } from '../commands/usage.js';
73
73
  import { executePolicyListCommand, executePolicyInspectCommand, executePolicyCreateCommand, executePolicyEditCommand, executePolicyDeleteCommand, executePolicyEnableCommand, executePolicyDisableCommand, executePolicyDryRunCommand, executePolicyScopeCommand, formatPolicyForDisplay, formatPoliciesListForDisplay, formatDryRunForDisplay, formatScopeForDisplay, } from '../commands/policy.js';
74
74
  import { executeErpListCommand, executeErpInspectCommand, executeErpSurfaceCommand, executeErpMapCommand, executeErpExportCommand, formatErpListForDisplay, formatErpInspectForDisplay, formatErpSurfaceForDisplay, formatErpMapForDisplay, formatErpExportForDisplay, } from '../commands/erp.js';
75
+ import { executeReadinessShowCommand, executeReadinessExplainCommand, formatReadinessForDisplay, formatReadinessExplainForDisplay, } from '../commands/readiness.js';
76
+ import { executeDemoStartCommand, } from '../commands/demo.js';
77
+ // ============================================================================
78
+ // Utility Helpers
79
+ // ============================================================================
80
+ /**
81
+ * Slugify a description string into a short kebab-case policy name.
82
+ * Takes the first ~40 characters, lowercases, replaces non-alphanum with hyphens,
83
+ * collapses runs, and trims leading/trailing hyphens.
84
+ */
85
+ function slugifyPolicyName(description) {
86
+ return description
87
+ .slice(0, 40)
88
+ .toLowerCase()
89
+ .replace(/[^a-z0-9]+/g, '-')
90
+ .replace(/^-+|-+$/g, '');
91
+ }
75
92
  // ============================================================================
76
93
  // CONTROL PLANE HARDENING GATES
77
94
  // ============================================================================
@@ -95,12 +112,16 @@ import { enforceOutputFormatGate, requiresStructuredOutput, getDefaultFormat } f
95
112
  import { enforceArgumentGuard, requiresArgumentValidation } from '../gates/argument-guard.js';
96
113
  // Lineage Gate - Enforces simulation traceability per ADR-004
97
114
  import { enforceLineageGate, requiresLineageValidation } from '../gates/lineage-gate.js';
115
+ // Readiness Gate - Enforces execution safety when execution-gated
116
+ import { enforceReadinessGate, requiresReadinessValidation } from '../gates/readiness-gate.js';
98
117
  // Help Renderer - Schema-driven help from COMMAND_REGISTRY (ADR-002 Decision 1)
99
118
  import { renderHelp } from '../modules/help-renderer.js';
100
119
  // Synthesis Router - ADR-006/007/008 Claude Code integration
101
120
  import { routeSynthesis, isDecisionGrade } from '../synthesis/router.js';
102
121
  import { createArtifactWriter } from '../synthesis/artifact-writer.js';
103
122
  import { lookupCommand } from '../contracts/adr-command-semantics.js';
123
+ // Dynamic routing — resolves downstream repos/agents based on request content
124
+ // dynamic-router import removed — routing is now platform-side
104
125
  // ============================================================================
105
126
  // Synthesis Artifact Persistence (ADR-008)
106
127
  // ============================================================================
@@ -202,7 +223,7 @@ async function main() {
202
223
  // execution is explicitly enabled. Only identity/help commands are allowed
203
224
  // when execution is disabled. This gate does NOT check entitlements, usage,
204
225
  // or billing - it is a binary on/off switch.
205
- enforceExecutionGate(parsed.command);
226
+ await enforceExecutionGate(parsed.command);
206
227
  // ============================================================================
207
228
  // GATE 2: AUTHENTICATION SESSION GATE - Requires valid credentials
208
229
  // ============================================================================
@@ -254,6 +275,17 @@ async function main() {
254
275
  if (requiresLineageValidation(parsed.command, parsed.subcommand)) {
255
276
  enforceLineageGate(parsed);
256
277
  }
278
+ // ============================================================================
279
+ // GATE 7: READINESS GATE - Enforces execution safety
280
+ // ============================================================================
281
+ // Write-path commands (deploy run, deploy rollback) are blocked when the
282
+ // platform readiness state is not EXECUTION_READY. This gate reads from
283
+ // ~/.agentics/exports/decision-readiness/readiness-state.json and prevents
284
+ // production writes until all prerequisites are met.
285
+ // CRITICAL: No ERP writes or production deployments without readiness.
286
+ if (requiresReadinessValidation(parsed.command, parsed.subcommand)) {
287
+ enforceReadinessGate(parsed);
288
+ }
257
289
  // Dispatch to command handlers
258
290
  try {
259
291
  let result = null;
@@ -462,16 +494,28 @@ async function main() {
462
494
  },
463
495
  });
464
496
  if (synthesisResult) {
465
- // Create the simulation using the synthesis output as metadata
497
+ // Extract actual synthesis content (scenario, steps, etc.)
498
+ const synthData = synthesisResult.data;
499
+ const scenario = synthData?.['scenario'];
500
+ const synthDescription = (scenario?.['description'] ??
501
+ synthData?.['description'] ??
502
+ parsed.options['description'] ??
503
+ simName);
504
+ const synthName = (scenario?.['name'] ??
505
+ synthData?.['name'] ??
506
+ simName);
507
+ // Create the simulation record with synthesis-derived content
466
508
  const simCreateResult = await executeSimulateCreateCommand({
467
- name: simName,
468
- description: parsed.options['description'],
509
+ name: synthName || simName,
510
+ description: synthDescription,
469
511
  plan_id: parsed.options['plan-id'],
470
512
  iterations: parsed.options['iterations'] ? parseInt(parsed.options['iterations'], 10) : undefined,
471
513
  metadata: {
472
514
  ...(parsed.options['metadata'] ? JSON.parse(parsed.options['metadata']) : {}),
473
515
  synthesis_run_id: synthesisResult.runId,
474
516
  synthesis_model: synthesisResult.model,
517
+ // Store the full synthesis content in metadata
518
+ synthesis_data: synthData,
475
519
  },
476
520
  }, options);
477
521
  // Persist synthesis artifacts (ADR-008)
@@ -488,9 +532,12 @@ async function main() {
488
532
  orgId: 'cli-org',
489
533
  traceId: options.trace_id ?? '',
490
534
  });
535
+ // Routing profile is now platform-side — not resolved locally.
491
536
  if (options.format === 'json') {
537
+ // Output the FULL synthesis content — not just the CRUD record
492
538
  console.log(JSON.stringify({
493
539
  simulation: simCreateResult.simulation,
540
+ data: synthData,
494
541
  synthesis: {
495
542
  run_id: synthesisResult.runId,
496
543
  model: synthesisResult.model,
@@ -820,7 +867,7 @@ async function main() {
820
867
  process.exit(EXIT_CODES.SUCCESS);
821
868
  }
822
869
  // Default quantify behavior (execute via orchestration)
823
- const quantifyInput = parsed.positionalArgs[0] ?? '';
870
+ const quantifyInput = parsed.positionalArgs[0] ?? parsed.subcommand ?? '';
824
871
  const quantifyFlexibleInput = parseFlexibleInput(quantifyInput);
825
872
  result = await executeQuantifyCommand({
826
873
  simRef: isNaturalLanguage(quantifyFlexibleInput)
@@ -934,7 +981,7 @@ async function main() {
934
981
  process.exit(EXIT_CODES.SUCCESS);
935
982
  }
936
983
  // Default deploy behavior (execute via orchestration)
937
- const deployInput = parsed.positionalArgs[0] ?? '';
984
+ const deployInput = parsed.positionalArgs[0] ?? parsed.subcommand ?? '';
938
985
  const deployFlexibleInput = parseFlexibleInput(deployInput);
939
986
  result = await executeDeployCommand({
940
987
  simRef: isNaturalLanguage(deployFlexibleInput)
@@ -1023,7 +1070,9 @@ async function main() {
1023
1070
  process.exit(EXIT_CODES.SUCCESS);
1024
1071
  }
1025
1072
  // Default export behavior (execute via orchestration)
1026
- const exportInput = parsed.positionalArgs[0] ?? '';
1073
+ // Note: parser consumes first arg as subcommand for commands with subcommands,
1074
+ // so use subcommand as input if it wasn't a known subcommand and no positional args
1075
+ const exportInput = parsed.positionalArgs[0] ?? parsed.subcommand ?? '';
1027
1076
  const exportFlexibleInput = parseFlexibleInput(exportInput);
1028
1077
  result = await executeExportCommand({
1029
1078
  intentRef: isNaturalLanguage(exportFlexibleInput)
@@ -1158,6 +1207,78 @@ async function main() {
1158
1207
  console.error('Supported subcommands: list, inspect, surface, map, export');
1159
1208
  process.exit(EXIT_CODES.USAGE_ERROR);
1160
1209
  }
1210
+ case 'readiness': {
1211
+ // Handle readiness subcommands: show, explain
1212
+ if (parsed.subcommand === 'show' || !parsed.subcommand) {
1213
+ const scenario = parsed.positionalArgs[0] ?? '';
1214
+ const readinessResult = await executeReadinessShowCommand({ scenario }, options);
1215
+ if (options.format === 'json') {
1216
+ console.log(JSON.stringify({
1217
+ state: readinessResult.state,
1218
+ found: readinessResult.found,
1219
+ scenario: readinessResult.scenario,
1220
+ timing: readinessResult.timing,
1221
+ }, null, parsed.flags['pretty'] ? 2 : 0));
1222
+ }
1223
+ else {
1224
+ console.log(formatReadinessForDisplay(readinessResult));
1225
+ }
1226
+ if (options.verbose) {
1227
+ console.error(`Query completed in ${readinessResult.timing}ms`);
1228
+ }
1229
+ process.exit(EXIT_CODES.SUCCESS);
1230
+ }
1231
+ if (parsed.subcommand === 'explain') {
1232
+ const scenario = parsed.positionalArgs[0] ?? '';
1233
+ const explainResult = await executeReadinessExplainCommand({ scenario }, options);
1234
+ // explain is always human-readable — no JSON mode
1235
+ console.log(formatReadinessExplainForDisplay(explainResult));
1236
+ if (options.verbose) {
1237
+ console.error(`Query completed in ${explainResult.timing}ms`);
1238
+ }
1239
+ process.exit(EXIT_CODES.SUCCESS);
1240
+ }
1241
+ // Unknown readiness subcommand
1242
+ console.error(`Unknown readiness subcommand: ${parsed.subcommand}`);
1243
+ console.error('Supported subcommands: show, explain');
1244
+ process.exit(EXIT_CODES.USAGE_ERROR);
1245
+ }
1246
+ case 'demo': {
1247
+ // Demo mode: read-only, gate-exempt, human-readable only
1248
+ const executionKeywords = ['execute', 'run', 'deploy', 'rollback', 'unlock', 'force', 'override'];
1249
+ if (parsed.subcommand && executionKeywords.includes(parsed.subcommand.toLowerCase())) {
1250
+ console.error(`Demo mode does not support "${parsed.subcommand}".`);
1251
+ console.error('');
1252
+ console.error('Demo mode is a read-only walkthrough of the platform. It cannot:');
1253
+ console.error(' - Execute deployments');
1254
+ console.error(' - Unlock the execution gate');
1255
+ console.error(' - Write to any system');
1256
+ console.error(' - Modify the readiness state');
1257
+ console.error('');
1258
+ console.error('Usage: agentics demo start [scenario]');
1259
+ process.exit(EXIT_CODES.USAGE_ERROR);
1260
+ }
1261
+ if (parsed.subcommand !== 'start' && parsed.subcommand) {
1262
+ console.error(`Unknown demo subcommand: ${parsed.subcommand}`);
1263
+ console.error('Usage: agentics demo start [scenario]');
1264
+ console.error('');
1265
+ console.error('Demo mode is read-only. The only valid subcommand is "start".');
1266
+ process.exit(EXIT_CODES.USAGE_ERROR);
1267
+ }
1268
+ const demoScenario = parsed.positionalArgs[0] ?? '';
1269
+ const demoResult = await executeDemoStartCommand({
1270
+ scenario: demoScenario,
1271
+ extraArgs: parsed.subcommand ? parsed.positionalArgs : [],
1272
+ });
1273
+ // Demo is always human-readable — never JSON
1274
+ console.log(demoResult.output);
1275
+ if (options.verbose) {
1276
+ console.error(`Demo completed in ${demoResult.timing}ms`);
1277
+ }
1278
+ console.log('');
1279
+ console.log('This demo is read-only. No systems were contacted. No data was written.');
1280
+ process.exit(EXIT_CODES.SUCCESS);
1281
+ }
1161
1282
  case 'diligence': {
1162
1283
  const diligenceInput = parsed.positionalArgs[0] ?? '';
1163
1284
  const diligenceFlexibleInput = parseFlexibleInput(diligenceInput);
@@ -1298,10 +1419,16 @@ async function main() {
1298
1419
  process.exit(EXIT_CODES.SUCCESS);
1299
1420
  }
1300
1421
  if (parsed.subcommand === 'create') {
1301
- const policyName = parsed.options['name'] ?? parsed.positionalArgs[0] ?? '';
1422
+ const positionalDesc = parsed.positionalArgs[0];
1423
+ const explicitName = parsed.options['name'];
1424
+ const explicitDesc = parsed.options['description'];
1425
+ // Derive description: --description flag > positional arg > fallback to name
1426
+ const description = explicitDesc ?? positionalDesc ?? explicitName ?? '';
1427
+ // Derive name: --name flag > slugified description
1428
+ const policyName = explicitName ?? slugifyPolicyName(description);
1302
1429
  const policyCreateResult = await executePolicyCreateCommand({
1303
1430
  name: policyName,
1304
- description: parsed.options['description'],
1431
+ description,
1305
1432
  type: parsed.options['type'],
1306
1433
  rules: parsed.options['rules'] ? JSON.parse(parsed.options['rules']) : undefined,
1307
1434
  metadata: parsed.options['metadata'] ? JSON.parse(parsed.options['metadata']) : undefined,
@@ -1494,36 +1621,222 @@ async function main() {
1494
1621
  process.exit(EXIT_CODES.GENERAL_ERROR);
1495
1622
  }
1496
1623
  }
1497
- // ============================================================================
1498
- // Status Line (Claude Code UI integration)
1499
- // ============================================================================
1500
- function printStatusLine(json) {
1501
- const hasAuth = process.env['AGENTICS_API_KEY'] || process.env['AGENTICS_INTERNAL_KEY'];
1502
- // Quick credential check without async
1503
- let authenticated = !!hasAuth;
1624
+ function gatherStatusState() {
1625
+ const agenticsDir = path.join(process.env['HOME'] ?? '', '.agentics');
1626
+ const state = {
1627
+ authenticated: false,
1628
+ tier: 'none',
1629
+ plans: 0,
1630
+ simulations: 0,
1631
+ deployments: 0,
1632
+ policies: 0,
1633
+ erp: 0,
1634
+ artifacts: 0,
1635
+ inspections: 0,
1636
+ totalRuns: 0,
1637
+ tools: 48,
1638
+ agentsRunning: 0,
1639
+ agentsAvailable: 100,
1640
+ activeAgentTypes: [],
1641
+ activeCalls: 0,
1642
+ activeCallServices: [],
1643
+ };
1644
+ // Auth & identity
1504
1645
  try {
1505
- const credPath = path.join(process.env['HOME'] ?? '', '.agentics', 'credentials.json');
1506
- if (!authenticated && fs.existsSync(credPath)) {
1507
- authenticated = true;
1646
+ const credRaw = fs.readFileSync(path.join(agenticsDir, 'credentials.json'), 'utf-8');
1647
+ const creds = JSON.parse(credRaw);
1648
+ if (creds.api_key) {
1649
+ state.authenticated = true;
1650
+ state.email = creds.email;
1651
+ state.tier = creds.payment_status === 'paid' ? 'paid'
1652
+ : creds.api_key.startsWith('agentics_internal_') ? 'internal'
1653
+ : creds.payment_status === 'free' ? 'free'
1654
+ : 'active';
1508
1655
  }
1509
1656
  }
1510
- catch {
1511
- // ignore
1657
+ catch { /* not logged in */ }
1658
+ // Identity file (display name, org, role)
1659
+ try {
1660
+ const idRaw = fs.readFileSync(path.join(agenticsDir, 'identity.json'), 'utf-8');
1661
+ const id = JSON.parse(idRaw);
1662
+ state.displayName = id.user?.display_name;
1663
+ state.orgName = id.org?.org_name;
1664
+ state.role = id.role;
1512
1665
  }
1513
- const status = authenticated ? 'ready' : 'not authenticated';
1514
- if (json) {
1515
- console.log(JSON.stringify({
1516
- name: 'agentics-cli',
1517
- version: VERSION,
1518
- status,
1519
- authenticated,
1520
- mcp: true,
1521
- }));
1666
+ catch { /* no identity */ }
1667
+ // Check internal allowlist for tier override
1668
+ if (state.authenticated && state.email) {
1669
+ try {
1670
+ const allowRaw = fs.readFileSync(path.join(agenticsDir, 'internal-allowlist.json'), 'utf-8');
1671
+ const allowlist = JSON.parse(allowRaw);
1672
+ const emailLower = state.email.toLowerCase();
1673
+ const domain = emailLower.split('@')[1];
1674
+ if (allowlist.emails?.includes(emailLower) || allowlist.domains?.includes(domain)) {
1675
+ state.tier = 'internal';
1676
+ }
1677
+ }
1678
+ catch { /* no allowlist */ }
1522
1679
  }
1523
- else {
1524
- const icon = authenticated ? '\u25CA' : '\u25CB';
1525
- console.log(`${icon} Agentics CLI v${VERSION} | ${status}`);
1680
+ // Count runs by category + artifacts
1681
+ try {
1682
+ const runsDir = path.join(agenticsDir, 'runs');
1683
+ if (fs.existsSync(runsDir)) {
1684
+ const entries = fs.readdirSync(runsDir);
1685
+ state.totalRuns = entries.length;
1686
+ for (const entry of entries) {
1687
+ try {
1688
+ const entryDir = path.join(runsDir, entry);
1689
+ const metaPath = path.join(entryDir, 'meta.json');
1690
+ if (fs.existsSync(metaPath)) {
1691
+ const meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));
1692
+ const cmd = meta.command ?? meta.type ?? '';
1693
+ if (cmd.includes('plan'))
1694
+ state.plans++;
1695
+ else if (cmd.includes('sim'))
1696
+ state.simulations++;
1697
+ else if (cmd.includes('deploy'))
1698
+ state.deployments++;
1699
+ else if (cmd.includes('erp'))
1700
+ state.erp++;
1701
+ else if (cmd.includes('inspect') || cmd.includes('query'))
1702
+ state.inspections++;
1703
+ }
1704
+ // Count artifact files (everything except meta.json)
1705
+ const files = fs.readdirSync(entryDir);
1706
+ state.artifacts += files.filter(f => f !== 'meta.json').length;
1707
+ }
1708
+ catch { /* skip bad entry */ }
1709
+ }
1710
+ }
1711
+ }
1712
+ catch { /* no runs */ }
1713
+ // Count policies
1714
+ try {
1715
+ const policiesPath = path.join(agenticsDir, 'policies');
1716
+ if (fs.existsSync(policiesPath)) {
1717
+ state.policies = fs.readdirSync(policiesPath).filter(f => f.endsWith('.json')).length;
1718
+ }
1719
+ }
1720
+ catch { /* no policies */ }
1721
+ // Running agents (tracked via per-agent JSON files in ~/.agentics/agents/)
1722
+ try {
1723
+ const agentsTrackDir = path.join(agenticsDir, 'agents');
1724
+ if (fs.existsSync(agentsTrackDir)) {
1725
+ const agentFiles = fs.readdirSync(agentsTrackDir).filter(f => f.endsWith('.json'));
1726
+ state.agentsRunning = agentFiles.length;
1727
+ const types = new Set();
1728
+ for (const file of agentFiles) {
1729
+ try {
1730
+ const raw = fs.readFileSync(path.join(agentsTrackDir, file), 'utf-8');
1731
+ const data = JSON.parse(raw);
1732
+ if (data.type)
1733
+ types.add(data.type);
1734
+ }
1735
+ catch { /* skip bad file */ }
1736
+ }
1737
+ state.activeAgentTypes = Array.from(types);
1738
+ }
1739
+ }
1740
+ catch { /* no agents dir */ }
1741
+ // Active downstream calls (tracked via per-call JSON files in ~/.agentics/calls/)
1742
+ try {
1743
+ const callsDir = path.join(agenticsDir, 'calls');
1744
+ if (fs.existsSync(callsDir)) {
1745
+ const callFiles = fs.readdirSync(callsDir).filter(f => f.endsWith('.json'));
1746
+ state.activeCalls = callFiles.length;
1747
+ const services = new Set();
1748
+ for (const file of callFiles) {
1749
+ try {
1750
+ const raw = fs.readFileSync(path.join(callsDir, file), 'utf-8');
1751
+ const data = JSON.parse(raw);
1752
+ if (data.service) {
1753
+ const short = data.service
1754
+ .replace(/^agentics-simulation-/, '')
1755
+ .replace(/^agentics-deployment-/, '')
1756
+ .replace(/^agentics-org-/, '')
1757
+ .replace(/^agentics-/, '')
1758
+ .replace(/^enterprise-/, '');
1759
+ services.add(short);
1760
+ }
1761
+ }
1762
+ catch { /* skip bad file */ }
1763
+ }
1764
+ state.activeCallServices = Array.from(services);
1765
+ }
1766
+ }
1767
+ catch { /* no calls dir */ }
1768
+ return state;
1769
+ }
1770
+ function printStatusLine(jsonMode) {
1771
+ const s = gatherStatusState();
1772
+ if (jsonMode) {
1773
+ console.log(JSON.stringify({ name: 'agentics-cli', version: VERSION, ...s }));
1774
+ return;
1775
+ }
1776
+ // ANSI colors (matching claude-flow CLI style)
1777
+ const R = '\x1b[0m';
1778
+ const D = '\x1b[2m';
1779
+ const PP = '\x1b[1;35m'; // bright purple
1780
+ const CC = '\x1b[1;36m'; // bright cyan
1781
+ const BB = '\x1b[1;34m'; // bright blue
1782
+ const GG = '\x1b[1;32m'; // bright green
1783
+ const YY = '\x1b[1;33m'; // bright yellow
1784
+ const WW = '\x1b[1;37m'; // bright white
1785
+ const cn = '\x1b[0;36m'; // cyan (labels)
1786
+ const sep = `${D}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${R}`;
1787
+ const pipe = ` ${D}\u2502${R} `;
1788
+ if (!s.authenticated) {
1789
+ const lines = [
1790
+ `${PP}\u258A Agentics.dev v${VERSION}${R} ${D}\u25C7 not authenticated${R}`,
1791
+ sep,
1792
+ `${cn}Run ${WW}agentics login${R}${cn} to get started${R}`,
1793
+ sep,
1794
+ ];
1795
+ console.log(lines.join('\n'));
1796
+ return;
1797
+ }
1798
+ const user = s.displayName
1799
+ ?? (s.email ? s.email.split('@')[0] ?? 'user' : 'user');
1800
+ const tierBadge = s.tier === 'internal' ? 'INT'
1801
+ : s.tier === 'paid' ? 'PRO'
1802
+ : s.tier === 'free' ? 'FREE'
1803
+ : 'ACT';
1804
+ // Header: ▊ Agentics v1.4.5 ● user │ PRO │ owner
1805
+ let header = `${PP}\u258A Agentics.dev v${VERSION}${R}`;
1806
+ header += ` ${CC}\u25CF ${user}${R}`;
1807
+ header += pipe + `${BB}${tierBadge}${R}`;
1808
+ if (s.role)
1809
+ header += pipe + `${D}${s.role}${R}`;
1810
+ if (s.orgName)
1811
+ header += pipe + `${D}${s.orgName}${R}`;
1812
+ // Line 1: 🤖 Agents ● [2] coder,tester │ ⇅ Calls [1] planner │ 📋 Plans 0 🧪 Simulate 0 🚀 Deploy 0
1813
+ const agentOn = s.agentsRunning > 0;
1814
+ const agentDot = agentOn ? `${GG}\u25C9${R}` : `${D}\u25CB${R}`;
1815
+ const agentClr = agentOn ? GG : D;
1816
+ let line1 = `${YY}\uD83E\uDD16 Agents${R} ${agentDot} [${agentClr}${s.agentsRunning}${R}]`;
1817
+ if (s.activeAgentTypes.length > 0) {
1818
+ line1 += ` ${D}${s.activeAgentTypes.join(',')}${R}`;
1819
+ }
1820
+ if (s.activeCalls > 0) {
1821
+ line1 += pipe + `${CC}\u21C5 Calls${R} [${CC}${s.activeCalls}${R}]`;
1822
+ if (s.activeCallServices.length > 0) {
1823
+ line1 += ` ${D}${s.activeCallServices.join(',')}${R}`;
1824
+ }
1526
1825
  }
1826
+ line1 += pipe;
1827
+ line1 += `${cn}\uD83D\uDCCB Plans${R} ${WW}${s.plans}${R}`;
1828
+ line1 += ` ${cn}\uD83E\uDDEA Simulate${R} ${WW}${s.simulations}${R}`;
1829
+ line1 += ` ${cn}\uD83D\uDE80 Deploy${R} ${WW}${s.deployments}${R}`;
1830
+ // Line 2: 📜 Policy 0 🏭 ERP 0 │ 📦 Artifacts 0 🔍 Inspect 0 📊 Usage 0
1831
+ let line2 = `${cn}\uD83D\uDCDC Policy${R} ${WW}${s.policies}${R}`;
1832
+ line2 += ` ${cn}\uD83C\uDFED ERP${R} ${WW}${s.erp}${R}`;
1833
+ line2 += pipe;
1834
+ line2 += `${cn}\uD83D\uDCE6 Artifacts${R} ${WW}${s.artifacts}${R}`;
1835
+ line2 += ` ${cn}\uD83D\uDD0D Inspect${R} ${WW}${s.inspections}${R}`;
1836
+ line2 += ` ${cn}\uD83D\uDCCA Usage${R} ${WW}${s.totalRuns}${R}`;
1837
+ line2 += pipe;
1838
+ line2 += `${D}\uD83D\uDEE0\uFE0F ${s.tools} tools${R}`;
1839
+ console.log([header, sep, line1, line2, sep].join('\n'));
1527
1840
  }
1528
1841
  // ============================================================================
1529
1842
  // Help Output