proteum 2.2.8 → 2.3.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.
Files changed (51) hide show
  1. package/AGENTS.md +5 -3
  2. package/README.md +50 -12
  3. package/agents/project/AGENTS.md +47 -10
  4. package/agents/project/CODING_STYLE.md +5 -1
  5. package/agents/project/client/AGENTS.md +2 -0
  6. package/agents/project/diagnostics.md +8 -5
  7. package/agents/project/optimizations.md +1 -0
  8. package/agents/project/root/AGENTS.md +18 -10
  9. package/agents/project/tests/AGENTS.md +6 -1
  10. package/agents/project/tests/e2e/AGENTS.md +13 -0
  11. package/agents/project/tests/e2e/REAL_WORLD_JOURNEY_TESTS.md +192 -0
  12. package/cli/commands/check.ts +21 -3
  13. package/cli/commands/configure.ts +1 -0
  14. package/cli/commands/connect.ts +40 -4
  15. package/cli/commands/diagnose.ts +136 -5
  16. package/cli/commands/doctor.ts +24 -4
  17. package/cli/commands/explain.ts +105 -6
  18. package/cli/commands/mcp.ts +16 -0
  19. package/cli/commands/orient.ts +66 -3
  20. package/cli/commands/perf.ts +118 -13
  21. package/cli/commands/runtime.ts +151 -0
  22. package/cli/commands/trace.ts +116 -21
  23. package/cli/mcp/provider.ts +365 -0
  24. package/cli/mcp/stdio.ts +16 -0
  25. package/cli/presentation/commands.ts +79 -22
  26. package/cli/presentation/devSession.ts +2 -0
  27. package/cli/runtime/commands.ts +95 -12
  28. package/cli/utils/agentOutput.ts +46 -0
  29. package/cli/utils/agents.ts +225 -48
  30. package/common/dev/inspection.ts +30 -9
  31. package/common/dev/mcpPayloads.ts +736 -0
  32. package/common/dev/mcpServer.ts +254 -0
  33. package/docs/agent-routing.md +126 -0
  34. package/docs/dev-commands.md +2 -0
  35. package/docs/dev-sessions.md +2 -1
  36. package/docs/diagnostics.md +68 -23
  37. package/docs/mcp.md +149 -0
  38. package/docs/migrate-from-2.1.3.md +15 -5
  39. package/docs/request-tracing.md +12 -6
  40. package/eslint.js +220 -0
  41. package/package.json +2 -1
  42. package/server/app/devMcp.ts +159 -0
  43. package/server/services/router/http/cache.ts +116 -0
  44. package/server/services/router/http/index.ts +94 -35
  45. package/server/services/router/index.ts +8 -11
  46. package/tests/agents-utils.test.cjs +89 -11
  47. package/tests/dev-transpile-watch.test.cjs +117 -8
  48. package/tests/eslint-rules.test.cjs +110 -0
  49. package/tests/inspection.test.cjs +67 -0
  50. package/tests/mcp.test.cjs +127 -0
  51. package/tests/router-cache-config.test.cjs +74 -0
@@ -21,6 +21,8 @@ export const proteumCommandNames = [
21
21
  'orient',
22
22
  'diagnose',
23
23
  'perf',
24
+ 'runtime',
25
+ 'mcp',
24
26
  'trace',
25
27
  'command',
26
28
  'session',
@@ -49,7 +51,7 @@ export type TProteumCommandDoc = {
49
51
 
50
52
  export const proteumRecommendedFlow: TRow[] = [
51
53
  { label: '1. proteum orient <query>', value: 'Start here for multi-repo, generated, or connected work before reading code.' },
52
- { label: '2. proteum dev', value: 'Start the compiler, SSR server, and hot reload loop.' },
54
+ { label: '2. proteum runtime status', value: 'Reuse an existing tracked dev session before starting a new one.' },
53
55
  { label: '3. proteum diagnose <path> --hit <path>', value: 'Validate the smallest trustworthy request surface before broader checks.' },
54
56
  { label: '4. proteum check', value: 'Refresh, typecheck, and lint before you commit or push.' },
55
57
  ];
@@ -57,7 +59,7 @@ export const proteumRecommendedFlow: TRow[] = [
57
59
  export const proteumCommandGroups: Array<{ title: string; names: TProteumCommandName[] }> = [
58
60
  { title: 'Daily workflow', names: ['dev', 'refresh', 'build'] },
59
61
  { title: 'Quality gates', names: ['typecheck', 'lint', 'check', 'e2e'] },
60
- { title: 'Manifest and contracts', names: ['connect', 'doctor', 'explain', 'orient', 'diagnose', 'perf', 'trace', 'command', 'session', 'verify'] },
62
+ { title: 'Manifest and contracts', names: ['connect', 'doctor', 'explain', 'orient', 'diagnose', 'perf', 'runtime', 'mcp', 'trace', 'command', 'session', 'verify'] },
61
63
  { title: 'Project scaffolding', names: ['init', 'configure', 'create', 'migrate'] },
62
64
  ];
63
65
 
@@ -124,9 +126,9 @@ export const proteumCommands: Record<TProteumCommandName, TProteumCommandDoc> =
124
126
  },
125
127
  ],
126
128
  notes: [
127
- 'This command is interactive. It asks whether the current Proteum app belongs to a monorepo and, if so, which ancestor path should receive the reusable root `AGENTS.md` file.',
129
+ 'This command is interactive. It asks whether the current Proteum app belongs to a monorepo and, if so, which ancestor path should receive the reusable root instruction files.',
128
130
  'Standalone mode writes tracked instruction files into the current Proteum app root.',
129
- 'Monorepo mode writes the reusable root `AGENTS.md` into the chosen monorepo root and the app-root instruction files into the current Proteum app root.',
131
+ 'Monorepo mode writes reusable root documents such as `AGENTS.md`, `CODING_STYLE.md`, `diagnostics.md`, and `optimizations.md` into the chosen monorepo root, then writes only app-root and area instruction files into the current Proteum app root.',
130
132
  'Every managed instruction file contains a `# Proteum Instructions` section with the full embedded Proteum project instruction corpus.',
131
133
  'Existing content outside `# Proteum Instructions` is preserved. Directories and foreign symlinks are replaced only after confirmation.',
132
134
  ],
@@ -310,16 +312,17 @@ export const proteumCommands: Record<TProteumCommandName, TProteumCommandDoc> =
310
312
  name: 'connect',
311
313
  category: 'Manifest and contracts',
312
314
  summary: 'Inspect connected-project config, cached contracts, and imported controllers.',
313
- usage: 'proteum connect [--controllers] [--json] [--strict]',
315
+ usage: 'proteum connect [--controllers] [--full|--human] [--strict]',
314
316
  bestFor:
315
317
  'Auditing the current app connect setup without manually stitching together refresh, explain, env inspection, and contract checks.',
316
318
  examples: [
317
- { description: 'Print a human-readable connected-project summary', command: 'proteum connect' },
319
+ { description: 'Print a compact connected-project summary', command: 'proteum connect' },
318
320
  { description: 'Include imported connected controllers', command: 'proteum connect --controllers' },
319
- { description: 'Emit machine-readable connect output', command: 'proteum connect --json' },
321
+ { description: 'Emit the full connect payload', command: 'proteum connect --full' },
320
322
  { description: 'Fail when connect diagnostics exist', command: 'proteum connect --strict' },
321
323
  ],
322
324
  notes: [
325
+ 'Default output is compact `proteum-agent-v1` JSON.',
323
326
  'Proteum refreshes generated typings before reading the connect manifest state.',
324
327
  'This command inspects explicit `proteum.config.ts` connected sources and URLs, cached `.proteum/connected/*.json` files, and imported connected controllers.',
325
328
  '`--strict` is intended for CI or framework validation when connected contracts must be present and usable.',
@@ -330,27 +333,31 @@ export const proteumCommands: Record<TProteumCommandName, TProteumCommandDoc> =
330
333
  name: 'doctor',
331
334
  category: 'Manifest and contracts',
332
335
  summary: 'Inspect the generated Proteum manifest diagnostics.',
333
- usage: 'proteum doctor [--contracts] [--json] [--strict]',
336
+ usage: 'proteum doctor [--contracts] [--full|--human] [--strict]',
334
337
  bestFor:
335
338
  'Auditing manifest warnings and errors, especially in CI or when route/controller generation behaves unexpectedly.',
336
339
  examples: [
337
- { description: 'Print a human-readable diagnostic summary', command: 'proteum doctor' },
340
+ { description: 'Print a compact diagnostic summary', command: 'proteum doctor' },
338
341
  { description: 'Inspect missing generated contracts and source files', command: 'proteum doctor --contracts' },
339
342
  { description: 'Fail if any diagnostics exist', command: 'proteum doctor --strict' },
340
- { description: 'Emit machine-readable diagnostics', command: 'proteum doctor --json' },
343
+ { description: 'Emit the full diagnostic payload', command: 'proteum doctor --full' },
344
+ ],
345
+ notes: [
346
+ 'Default output is compact `proteum-agent-v1` JSON.',
347
+ '`--strict` is intended for CI and pre-release verification.',
348
+ '`--contracts` checks manifest-owned source files and expected generated artifacts on disk.',
341
349
  ],
342
- notes: ['`--strict` is intended for CI and pre-release verification.', '`--contracts` checks manifest-owned source files and expected generated artifacts on disk.'],
343
350
  status: 'stable',
344
351
  },
345
352
  explain: {
346
353
  name: 'explain',
347
354
  category: 'Manifest and contracts',
348
355
  summary: 'Explain the generated Proteum manifest.',
349
- usage: 'proteum explain [owner <query>] [--all|--app|--conventions|--env|--connected|--services|--controllers|--commands|--routes|--layouts|--diagnostics] [--json]',
356
+ usage: 'proteum explain [owner <query>] [--manifest|--full|--human|--all|--app|--conventions|--env|--connected|--services|--controllers|--commands|--routes|--layouts|--diagnostics]',
350
357
  bestFor:
351
- 'Inspecting how source files became generated routes, controllers, commands, layouts, services, and diagnostics without reading compiler internals.',
358
+ 'Inspecting the compact generated-app summary first, then opening selected manifest sections only when needed.',
352
359
  examples: [
353
- { description: 'Show the default human summary', command: 'proteum explain' },
360
+ { description: 'Show the default compact agent summary', command: 'proteum explain' },
354
361
  {
355
362
  description: 'Inspect generated routes, controllers, and commands together',
356
363
  command: 'proteum explain --routes --controllers --commands',
@@ -360,9 +367,11 @@ export const proteumCommands: Record<TProteumCommandName, TProteumCommandDoc> =
360
367
  command: 'proteum explain --connected --controllers',
361
368
  },
362
369
  { description: 'Resolve the most likely manifest owner for a path or file', command: 'proteum explain owner /api/Auth/CurrentUser' },
363
- { description: 'Emit the selected manifest sections as JSON', command: 'proteum explain --routes --json' },
370
+ { description: 'Emit the full manifest only when needed', command: 'proteum explain --manifest' },
364
371
  ],
365
372
  notes: [
373
+ 'Default output is compact `proteum-agent-v1` JSON because the CLI is optimized for agents.',
374
+ '`--full`, `--manifest`, or explicit section flags are the escape hatch for large details.',
366
375
  'Legacy positional section selection remains supported, for example `proteum explain routes services`.',
367
376
  '`proteum explain owner <query>` ranks matching routes, controllers, services, commands, layouts, and diagnostics from the manifest.',
368
377
  'Connected projects are emitted from explicit `proteum.config.ts` `connect.<Namespace>.*` values plus the resolved connected contract.',
@@ -373,17 +382,17 @@ export const proteumCommands: Record<TProteumCommandName, TProteumCommandDoc> =
373
382
  name: 'orient',
374
383
  category: 'Manifest and contracts',
375
384
  summary: 'Resolve owners, guidance files, connected boundaries, and next steps before opening code.',
376
- usage: 'proteum orient <query> [--port <port>|--url <baseUrl>] [--json]',
385
+ usage: 'proteum orient <query> [--port <port>|--url <baseUrl>] [--full|--human]',
377
386
  bestFor:
378
387
  'Starting multi-repo, generated-artifact, or connected-project work with one explicit orientation step instead of guessing the first files to read.',
379
388
  examples: [
380
389
  { description: 'Orient around a generated controller path', command: 'proteum orient /api/Auth/CurrentUser' },
381
390
  { description: 'Orient around a connected namespace or route', command: 'proteum orient Product.Stats.general' },
382
- { description: 'Use a running dev server when the local manifest is unavailable', command: 'proteum orient /domains --port 3101 --json' },
391
+ { description: 'Use a running dev server when the local manifest is unavailable', command: 'proteum orient /domains --port 3101' },
383
392
  ],
384
393
  notes: [
385
- 'This command combines manifest owner lookup, local or fallback guidance resolution, connected-boundary hints, and three recommended next commands.',
386
- 'Use it before reading source when the query might map to generated code, connected imports, or framework-owned files.',
394
+ 'Default output is compact `proteum-agent-v1` JSON with `mustRead`, conditional docs, owner matches, and next commands.',
395
+ 'Use it before reading source when the query might map to generated code, connected imports, framework-owned files, or area instructions.',
387
396
  'When `--port` or `--url` is provided, Proteum can read the manifest from a running dev server instead of only from disk.',
388
397
  ],
389
398
  status: 'experimental',
@@ -392,7 +401,7 @@ export const proteumCommands: Record<TProteumCommandName, TProteumCommandDoc> =
392
401
  name: 'diagnose',
393
402
  category: 'Manifest and contracts',
394
403
  summary: 'Combine owner lookup, doctor output, contract checks, traces, and server logs into one report.',
395
- usage: 'proteum diagnose [<query>] [--hit <path>] [--method <verb>] [--data-json <json>] [--session-email <email>] [--session-role <role>] [--port <port>|--url <baseUrl>] [--json]',
404
+ usage: 'proteum diagnose [<query>] [--hit <path>] [--method <verb>] [--data-json <json>] [--session-email <email>] [--session-role <role>] [--port <port>|--url <baseUrl>] [--full|--human]',
396
405
  bestFor:
397
406
  'Collapsing the usual explain + doctor + trace + session + server log loop into one structured debugging pass.',
398
407
  examples: [
@@ -401,6 +410,8 @@ export const proteumCommands: Record<TProteumCommandName, TProteumCommandDoc> =
401
410
  { description: 'Diagnose an API call with a JSON payload', command: 'proteum diagnose /api/Auth/CurrentUser --hit /api/Auth/CurrentUser --method POST --data-json "{}"' },
402
411
  ],
403
412
  notes: [
413
+ 'Default output is compact `proteum-agent-v1` JSON and omits raw request events, payloads, and SQL text.',
414
+ 'Use `--full` only when the compact response says lower-level detail is required.',
404
415
  'This command talks to the running app over the dev-only diagnostics, trace, and session endpoints.',
405
416
  'When `--hit` is omitted, Proteum diagnoses the latest matching request trace if one already exists.',
406
417
  ],
@@ -410,7 +421,7 @@ export const proteumCommands: Record<TProteumCommandName, TProteumCommandDoc> =
410
421
  name: 'perf',
411
422
  category: 'Manifest and contracts',
412
423
  summary: 'Inspect shared performance rollups built from live request traces on a running Proteum dev server.',
413
- usage: 'proteum perf [top|request <requestId|path>|compare|memory] [--since <window>] [--baseline <window>] [--target <window>] [--group-by <path|route|controller>] [--limit <n>] [--port <port>|--url <baseUrl>] [--json]',
424
+ usage: 'proteum perf [top|request <requestId|path>|compare|memory] [--since <window>] [--baseline <window>] [--target <window>] [--group-by <path|route|controller>] [--limit <n>] [--port <port>|--url <baseUrl>] [--full|--human]',
414
425
  bestFor:
415
426
  'Finding the routes or controllers with the biggest response-time, CPU, SQL, render, and memory impact without manually stitching traces together.',
416
427
  examples: [
@@ -426,17 +437,61 @@ export const proteumCommands: Record<TProteumCommandName, TProteumCommandDoc> =
426
437
  },
427
438
  ],
428
439
  notes: [
440
+ 'Default output is compact `proteum-agent-v1` JSON with capped rows and next commands.',
429
441
  'Perf data is derived from the same dev-only request trace buffer used by `proteum trace` and the profiler.',
430
442
  'Window values accept `1h`, `6h`, `24h`, `today`, `yesterday`, or an ISO timestamp.',
431
443
  'Older traces captured before the perf runtime metrics were added may not include CPU or memory deltas.',
432
444
  ],
433
445
  status: 'experimental',
434
446
  },
447
+ runtime: {
448
+ name: 'runtime',
449
+ category: 'Manifest and contracts',
450
+ summary: 'Inspect the current app manifest, tracked dev sessions, and runtime health in one compact response.',
451
+ usage: 'proteum runtime status [--session-file <path>] [--full]',
452
+ bestFor:
453
+ 'Reusing a live dev session and avoiding repeated dev-list, manifest, and health-check commands before request diagnostics.',
454
+ examples: [
455
+ { description: 'Resolve the current runtime status', command: 'proteum runtime status' },
456
+ { description: 'Inspect one explicit session file', command: 'proteum runtime status --session-file var/run/proteum/dev/agents/task.json' },
457
+ ],
458
+ notes: [
459
+ 'Default output is compact `proteum-agent-v1` JSON with the selected session, health, and next command.',
460
+ 'Use `--full` to include every tracked session field.',
461
+ ],
462
+ status: 'experimental',
463
+ },
464
+ mcp: {
465
+ name: 'mcp',
466
+ category: 'Manifest and contracts',
467
+ summary: 'Start a read-only Proteum MCP server for compact agent diagnostics and runtime data.',
468
+ usage: 'proteum mcp [--cwd <path>] [--url <baseUrl>] [--session-file <path>]',
469
+ bestFor:
470
+ 'Agent integrations that need repeated low-token access to Proteum manifest, instruction routing, runtime status, trace, perf, diagnose, and log summaries.',
471
+ examples: [
472
+ { description: 'Start the MCP server for the current app over stdio', command: 'proteum mcp' },
473
+ {
474
+ description: 'Point the MCP server at a running dev server',
475
+ command: 'proteum mcp --url http://localhost:3101',
476
+ },
477
+ {
478
+ description: 'Resolve runtime data from an explicit tracked session file',
479
+ command: 'proteum mcp --session-file var/run/proteum/dev/agents/task.json',
480
+ },
481
+ ],
482
+ notes: [
483
+ '`proteum mcp` is read-only in v1 and does not start/stop dev servers, refresh generated code, write files, or mutate traces.',
484
+ 'Tool and resource payloads are compact single-line `proteum-mcp-v1` JSON for low-token agent reads.',
485
+ 'Use the CLI for reproducible build/dev/check workflows; use MCP for repeated agent reads and progressive detail loading.',
486
+ 'A running `proteum dev` server also exposes the same tool contract at `/__proteum/mcp` for runtime-adjacent access.',
487
+ ],
488
+ status: 'experimental',
489
+ },
435
490
  trace: {
436
491
  name: 'trace',
437
492
  category: 'Manifest and contracts',
438
493
  summary: 'Inspect live in-memory request traces from a running Proteum dev server.',
439
- usage: 'proteum trace [latest|show <requestId>|requests|arm|export <requestId>] [--port <port>|--url <baseUrl>] [--json]',
494
+ usage: 'proteum trace [latest|show <requestId>|requests|arm|export <requestId>] [--port <port>|--url <baseUrl>] [--events|--full|--human]',
440
495
  bestFor:
441
496
  'Debugging route resolution, context creation, SSR payloads, renders, and runtime errors without attaching a debugger.',
442
497
  examples: [
@@ -447,6 +502,8 @@ export const proteumCommands: Record<TProteumCommandName, TProteumCommandDoc> =
447
502
  { description: 'Target a custom dev base URL directly', command: 'proteum trace latest --url http://127.0.0.1:3010' },
448
503
  ],
449
504
  notes: [
505
+ 'Default output is compact `proteum-agent-v1` JSON with counts, errors, hot calls, and hot SQL only.',
506
+ 'Use `--events` or `--full` to print the raw event stream, payload summaries, and SQL text.',
450
507
  'This command talks to the running app over the dev-only `__proteum/trace` HTTP endpoints.',
451
508
  'Traces are stored in a bounded in-memory buffer with payload summarization and sensitive-field redaction.',
452
509
  'Use `--port` when the app is not running on the router port declared in `PORT`, or `--url` when the host itself is non-standard.',
@@ -35,6 +35,7 @@ export const renderDevSession = async ({
35
35
  { label: 'root', value: appRoot },
36
36
  { label: 'router', value: `http://localhost:${routerPort}` },
37
37
  { label: 'hmr', value: `http://localhost:${devEventPort}/__proteum_hmr` },
38
+ { label: 'mcp', value: `http://localhost:${routerPort}/__proteum/mcp` },
38
39
  ...(connectedProjects && connectedProjects.length > 0
39
40
  ? connectedProjects.map((connectedProject) => ({
40
41
  label: `connect ${connectedProject.namespace}`,
@@ -91,6 +92,7 @@ export const renderServerReadyBanner = async ({
91
92
  createElement(Text, { dimColor: true }, `Diagnose /: proteum diagnose / --port ${routerPort}`),
92
93
  createElement(Text, { dimColor: true }, `Perf top: proteum perf top --port ${routerPort}`),
93
94
  createElement(Text, { dimColor: true }, `Trace latest: proteum trace latest --port ${routerPort}`),
95
+ createElement(Text, { dimColor: true }, `MCP: ${publicUrl}/__proteum/mcp`),
94
96
  );
95
97
  });
96
98
 
@@ -324,14 +324,16 @@ class ConnectCommand extends ProteumCommand {
324
324
  public controllers = Option.Boolean('--controllers', false, {
325
325
  description: 'Include imported connected controllers in the output.',
326
326
  });
327
- public json = Option.Boolean('--json', false, { description: 'Print JSON output.' });
327
+ public json = Option.Boolean('--json', false, { description: 'Compatibility flag; compact JSON is the default output.' });
328
+ public full = Option.Boolean('--full', false, { description: 'Print the full connect payload.' });
329
+ public human = Option.Boolean('--human', false, { description: 'Print the legacy human-readable report.' });
328
330
  public strict = Option.Boolean('--strict', false, { description: 'Exit with failure if any connect diagnostics exist.' });
329
331
  public legacyArgs = Option.Rest();
330
332
 
331
333
  public async execute() {
332
- const args = { controllers: this.controllers, json: this.json, strict: this.strict } satisfies TArgsObject;
334
+ const args = { controllers: this.controllers, full: this.full, human: this.human, json: this.json, strict: this.strict } satisfies TArgsObject;
333
335
 
334
- applyLegacyBooleanArgs('connect', this.legacyArgs, ['controllers', 'json', 'strict'], args);
336
+ applyLegacyBooleanArgs('connect', this.legacyArgs, ['controllers', 'full', 'human', 'json', 'strict'], args);
335
337
  this.setCliArgs(args);
336
338
  await runCommandModule(() => import('../commands/connect'));
337
339
  }
@@ -345,14 +347,16 @@ class DoctorCommand extends ProteumCommand {
345
347
  public contracts = Option.Boolean('--contracts', false, {
346
348
  description: 'Run contract-focused diagnostics for generated artifacts and manifest-owned source files.',
347
349
  });
348
- public json = Option.Boolean('--json', false, { description: 'Print JSON output.' });
350
+ public json = Option.Boolean('--json', false, { description: 'Compatibility flag; compact JSON is the default output.' });
351
+ public full = Option.Boolean('--full', false, { description: 'Print the full doctor payload.' });
352
+ public human = Option.Boolean('--human', false, { description: 'Print the legacy human-readable report.' });
349
353
  public strict = Option.Boolean('--strict', false, { description: 'Exit with failure if any diagnostics exist.' });
350
354
  public legacyArgs = Option.Rest();
351
355
 
352
356
  public async execute() {
353
- const args = { contracts: this.contracts, json: this.json, strict: this.strict } satisfies TArgsObject;
357
+ const args = { contracts: this.contracts, full: this.full, human: this.human, json: this.json, strict: this.strict } satisfies TArgsObject;
354
358
 
355
- applyLegacyBooleanArgs('doctor', this.legacyArgs, ['contracts', 'json', 'strict'], args);
359
+ applyLegacyBooleanArgs('doctor', this.legacyArgs, ['contracts', 'full', 'human', 'json', 'strict'], args);
356
360
  this.setCliArgs(args);
357
361
  await runCommandModule(() => import('../commands/doctor'));
358
362
  }
@@ -363,7 +367,10 @@ class ExplainCommand extends ProteumCommand {
363
367
 
364
368
  public static usage = buildUsage('explain');
365
369
 
366
- public json = Option.Boolean('--json', false, { description: 'Print JSON output.' });
370
+ public json = Option.Boolean('--json', false, { description: 'Compatibility flag; compact JSON is the default output.' });
371
+ public full = Option.Boolean('--full', false, { description: 'Print the full selected machine-readable detail.' });
372
+ public human = Option.Boolean('--human', false, { description: 'Print the legacy human-readable report.' });
373
+ public manifest = Option.Boolean('--manifest', false, { description: 'Print the full generated manifest.' });
367
374
  public all = Option.Boolean('--all', false, { description: 'Include every explain section.' });
368
375
  public app = Option.Boolean('--app', false, { description: 'Include the app section.' });
369
376
  public conventions = Option.Boolean('--conventions', false, { description: 'Include the conventions section.' });
@@ -384,6 +391,9 @@ class ExplainCommand extends ProteumCommand {
384
391
  if (mode === 'owner') {
385
392
  this.setCliArgs({
386
393
  json: this.json,
394
+ full: this.full,
395
+ human: this.human,
396
+ manifest: this.manifest,
387
397
  ownerQuery: restArgs.join(' ').trim(),
388
398
  });
389
399
  await runCommandModule(() => import('../commands/explain'));
@@ -392,6 +402,9 @@ class ExplainCommand extends ProteumCommand {
392
402
 
393
403
  const args = {
394
404
  json: this.json,
405
+ full: this.full,
406
+ human: this.human,
407
+ manifest: this.manifest,
395
408
  all: this.all,
396
409
  app: this.app,
397
410
  conventions: this.conventions,
@@ -408,7 +421,7 @@ class ExplainCommand extends ProteumCommand {
408
421
  applyLegacyBooleanArgs(
409
422
  'explain',
410
423
  this.args,
411
- ['json', 'all', 'app', 'conventions', 'env', 'connected', 'services', 'controllers', 'commands', 'routes', 'layouts', 'diagnostics'],
424
+ ['json', 'full', 'human', 'manifest', 'all', 'app', 'conventions', 'env', 'connected', 'services', 'controllers', 'commands', 'routes', 'layouts', 'diagnostics'],
412
425
  args,
413
426
  );
414
427
  this.setCliArgs(args);
@@ -423,7 +436,9 @@ class OrientCommand extends ProteumCommand {
423
436
 
424
437
  public port = Option.String('--port', { description: 'Target an existing dev server on the given port.' });
425
438
  public url = Option.String('--url', { description: 'Target an existing dev server at the given base URL.' });
426
- public json = Option.Boolean('--json', false, { description: 'Print JSON output.' });
439
+ public json = Option.Boolean('--json', false, { description: 'Compatibility flag; compact JSON is the default output.' });
440
+ public full = Option.Boolean('--full', false, { description: 'Print the full orientation payload.' });
441
+ public human = Option.Boolean('--human', false, { description: 'Print the legacy human-readable report.' });
427
442
  public args = Option.Rest();
428
443
 
429
444
  public async execute() {
@@ -431,6 +446,8 @@ class OrientCommand extends ProteumCommand {
431
446
 
432
447
  this.setCliArgs({
433
448
  json: this.json,
449
+ full: this.full,
450
+ human: this.human,
434
451
  port: this.port ?? '',
435
452
  query,
436
453
  url: this.url ?? '',
@@ -447,7 +464,10 @@ class TraceCommand extends ProteumCommand {
447
464
 
448
465
  public port = Option.String('--port', { description: 'Override the router port used to query the running dev server.' });
449
466
  public url = Option.String('--url', { description: 'Override the full base URL used to query the running dev server.' });
450
- public json = Option.Boolean('--json', false, { description: 'Print JSON output.' });
467
+ public json = Option.Boolean('--json', false, { description: 'Compatibility flag; compact JSON is the default output.' });
468
+ public full = Option.Boolean('--full', false, { description: 'Print the full trace response.' });
469
+ public events = Option.Boolean('--events', false, { description: 'Include full event, call, SQL, and payload detail.' });
470
+ public human = Option.Boolean('--human', false, { description: 'Print the legacy human-readable trace report.' });
451
471
  public capture = Option.String('--capture', { description: 'Capture mode used by `proteum trace arm`.' });
452
472
  public output = Option.String('--output', { description: 'Output filepath used by `proteum trace export`.' });
453
473
  public args = Option.Rest();
@@ -461,6 +481,9 @@ class TraceCommand extends ProteumCommand {
461
481
  port: this.port ?? '',
462
482
  url: this.url ?? '',
463
483
  json: this.json,
484
+ full: this.full,
485
+ events: this.events,
486
+ human: this.human,
464
487
  capture: this.capture ?? '',
465
488
  output: this.output ?? '',
466
489
  });
@@ -526,7 +549,9 @@ class DiagnoseCommand extends ProteumCommand {
526
549
 
527
550
  public port = Option.String('--port', { description: 'Target an existing dev server on the given port.' });
528
551
  public url = Option.String('--url', { description: 'Target an existing dev server at the given base URL.' });
529
- public json = Option.Boolean('--json', false, { description: 'Print JSON output.' });
552
+ public json = Option.Boolean('--json', false, { description: 'Compatibility flag; compact JSON is the default output.' });
553
+ public full = Option.Boolean('--full', false, { description: 'Print the full diagnose payload.' });
554
+ public human = Option.Boolean('--human', false, { description: 'Print the legacy human-readable report.' });
530
555
  public hit = Option.String('--hit', { description: 'Issue one HTTP request before diagnosing. Defaults to the target path when it starts with /.' });
531
556
  public method = Option.String('--method', { description: 'HTTP method used with `--hit`.' });
532
557
  public dataJson = Option.String('--data-json', { description: 'JSON request body used with `--hit`.' });
@@ -547,6 +572,8 @@ class DiagnoseCommand extends ProteumCommand {
547
572
  dataJson: this.dataJson ?? '',
548
573
  hit: this.hit ?? '',
549
574
  json: this.json,
575
+ full: this.full,
576
+ human: this.human,
550
577
  logsLevel: this.logsLevel ?? '',
551
578
  logsLimit: this.logsLimit ?? '',
552
579
  method: this.method ?? '',
@@ -568,7 +595,9 @@ class PerfCommand extends ProteumCommand {
568
595
 
569
596
  public port = Option.String('--port', { description: 'Target an existing dev server on the given port.' });
570
597
  public url = Option.String('--url', { description: 'Target an existing dev server at the given base URL.' });
571
- public json = Option.Boolean('--json', false, { description: 'Print JSON output.' });
598
+ public json = Option.Boolean('--json', false, { description: 'Compatibility flag; compact JSON is the default output.' });
599
+ public full = Option.Boolean('--full', false, { description: 'Print the full perf payload.' });
600
+ public human = Option.Boolean('--human', false, { description: 'Print the legacy human-readable report.' });
572
601
  public since = Option.String('--since', { description: 'Window used by `top` and `memory`, for example `today`, `yesterday`, or `1h`.' });
573
602
  public baseline = Option.String('--baseline', { description: 'Baseline window used by `compare`.' });
574
603
  public target = Option.String('--target', { description: 'Target window used by `compare`.' });
@@ -584,6 +613,8 @@ class PerfCommand extends ProteumCommand {
584
613
  baseline: this.baseline ?? '',
585
614
  groupBy: this.groupBy ?? '',
586
615
  json: this.json,
616
+ full: this.full,
617
+ human: this.human,
587
618
  limit: this.limit ?? '',
588
619
  port: this.port ?? '',
589
620
  since: this.since ?? '',
@@ -596,6 +627,54 @@ class PerfCommand extends ProteumCommand {
596
627
  }
597
628
  }
598
629
 
630
+ class RuntimeCommand extends ProteumCommand {
631
+ public static paths = [['runtime']];
632
+
633
+ public static usage = buildUsage('runtime');
634
+
635
+ public full = Option.Boolean('--full', false, { description: 'Print full tracked-session and health detail.' });
636
+ public sessionFile = Option.String('--session-file', {
637
+ description: 'Inspect one explicit dev session file instead of the app registry.',
638
+ });
639
+ public args = Option.Rest();
640
+
641
+ public async execute() {
642
+ const [action = 'status'] = this.args;
643
+
644
+ this.setCliArgs({
645
+ action,
646
+ full: this.full,
647
+ sessionFile: this.sessionFile ?? '',
648
+ });
649
+
650
+ await runCommandModule(() => import('../commands/runtime'));
651
+ }
652
+ }
653
+
654
+ class McpCommand extends ProteumCommand {
655
+ public static paths = [['mcp']];
656
+
657
+ public static usage = buildUsage('mcp');
658
+
659
+ public cwd = Option.String('--cwd', { description: 'Run the MCP server against another Proteum app root.' });
660
+ public sessionFile = Option.String('--session-file', {
661
+ description: 'Inspect one explicit dev session file when resolving runtime data.',
662
+ });
663
+ public url = Option.String('--url', { description: 'Use a running Proteum dev server as the live runtime data source.' });
664
+ public legacyArgs = Option.Rest();
665
+
666
+ public async execute() {
667
+ assertNoLegacyArgs('mcp', this.legacyArgs);
668
+ this.setCliArgs({
669
+ sessionFile: this.sessionFile ?? '',
670
+ url: this.url ?? '',
671
+ workdir: this.cwd ?? '',
672
+ });
673
+
674
+ await runCommandModule(() => import('../commands/mcp'));
675
+ }
676
+ }
677
+
599
678
  class VerifyCommand extends ProteumCommand {
600
679
  public static paths = [['verify']];
601
680
 
@@ -672,6 +751,8 @@ export const registeredCommands = {
672
751
  orient: OrientCommand,
673
752
  diagnose: DiagnoseCommand,
674
753
  perf: PerfCommand,
754
+ runtime: RuntimeCommand,
755
+ mcp: McpCommand,
675
756
  trace: TraceCommand,
676
757
  command: CommandCommand,
677
758
  session: SessionCommand,
@@ -705,6 +786,8 @@ export const createCli = (version: string) => {
705
786
  clipanion.register(OrientCommand);
706
787
  clipanion.register(DiagnoseCommand);
707
788
  clipanion.register(PerfCommand);
789
+ clipanion.register(RuntimeCommand);
790
+ clipanion.register(McpCommand);
708
791
  clipanion.register(TraceCommand);
709
792
  clipanion.register(CommandCommand);
710
793
  clipanion.register(SessionCommand);
@@ -0,0 +1,46 @@
1
+ /*----------------------------------
2
+ - TYPES
3
+ ----------------------------------*/
4
+
5
+ export type TAgentNextAction = {
6
+ command: string;
7
+ label: string;
8
+ reason?: string;
9
+ };
10
+
11
+ export type TAgentOmittedDetail = {
12
+ command: string;
13
+ reason: string;
14
+ };
15
+
16
+ export type TAgentResponse<TData extends object> = {
17
+ ok: true;
18
+ format: 'proteum-agent-v1';
19
+ summary: string;
20
+ data: TData;
21
+ nextActions?: TAgentNextAction[];
22
+ omitted?: TAgentOmittedDetail[];
23
+ fullDetailCommand?: string;
24
+ };
25
+
26
+ /*----------------------------------
27
+ - HELPERS
28
+ ----------------------------------*/
29
+
30
+ export const truncateForAgent = (value: string, max = 220) => (value.length <= max ? value : `${value.slice(0, max)}...`);
31
+
32
+ export const compactList = <TValue>(values: TValue[], limit: number) => values.slice(0, Math.max(0, limit));
33
+
34
+ export const printJson = (value: object) => {
35
+ console.log(JSON.stringify(value, null, 2));
36
+ };
37
+
38
+ export const printAgentResponse = <TData extends object>(response: Omit<TAgentResponse<TData>, 'format' | 'ok'>) => {
39
+ printJson({
40
+ ok: true,
41
+ format: 'proteum-agent-v1',
42
+ ...response,
43
+ });
44
+ };
45
+
46
+ export const quoteCommandArgument = (value: string) => JSON.stringify(value);