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.
- package/AGENTS.md +5 -3
- package/README.md +50 -12
- package/agents/project/AGENTS.md +47 -10
- package/agents/project/CODING_STYLE.md +5 -1
- package/agents/project/client/AGENTS.md +2 -0
- package/agents/project/diagnostics.md +8 -5
- package/agents/project/optimizations.md +1 -0
- package/agents/project/root/AGENTS.md +18 -10
- package/agents/project/tests/AGENTS.md +6 -1
- package/agents/project/tests/e2e/AGENTS.md +13 -0
- package/agents/project/tests/e2e/REAL_WORLD_JOURNEY_TESTS.md +192 -0
- package/cli/commands/check.ts +21 -3
- package/cli/commands/configure.ts +1 -0
- package/cli/commands/connect.ts +40 -4
- package/cli/commands/diagnose.ts +136 -5
- package/cli/commands/doctor.ts +24 -4
- package/cli/commands/explain.ts +105 -6
- package/cli/commands/mcp.ts +16 -0
- package/cli/commands/orient.ts +66 -3
- package/cli/commands/perf.ts +118 -13
- package/cli/commands/runtime.ts +151 -0
- package/cli/commands/trace.ts +116 -21
- package/cli/mcp/provider.ts +365 -0
- package/cli/mcp/stdio.ts +16 -0
- package/cli/presentation/commands.ts +79 -22
- package/cli/presentation/devSession.ts +2 -0
- package/cli/runtime/commands.ts +95 -12
- package/cli/utils/agentOutput.ts +46 -0
- package/cli/utils/agents.ts +225 -48
- package/common/dev/inspection.ts +30 -9
- package/common/dev/mcpPayloads.ts +736 -0
- package/common/dev/mcpServer.ts +254 -0
- package/docs/agent-routing.md +126 -0
- package/docs/dev-commands.md +2 -0
- package/docs/dev-sessions.md +2 -1
- package/docs/diagnostics.md +68 -23
- package/docs/mcp.md +149 -0
- package/docs/migrate-from-2.1.3.md +15 -5
- package/docs/request-tracing.md +12 -6
- package/eslint.js +220 -0
- package/package.json +2 -1
- package/server/app/devMcp.ts +159 -0
- package/server/services/router/http/cache.ts +116 -0
- package/server/services/router/http/index.ts +94 -35
- package/server/services/router/index.ts +8 -11
- package/tests/agents-utils.test.cjs +89 -11
- package/tests/dev-transpile-watch.test.cjs +117 -8
- package/tests/eslint-rules.test.cjs +110 -0
- package/tests/inspection.test.cjs +67 -0
- package/tests/mcp.test.cjs +127 -0
- 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
|
|
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
|
|
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
|
|
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] [--
|
|
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
|
|
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
|
|
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] [--
|
|
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
|
|
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
|
|
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]
|
|
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
|
|
358
|
+
'Inspecting the compact generated-app summary first, then opening selected manifest sections only when needed.',
|
|
352
359
|
examples: [
|
|
353
|
-
{ description: 'Show the default
|
|
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
|
|
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>] [--
|
|
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
|
|
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
|
-
'
|
|
386
|
-
'Use it before reading source when the query might map to generated code, connected imports,
|
|
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>] [--
|
|
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>] [--
|
|
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>] [--
|
|
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
|
|
package/cli/runtime/commands.ts
CHANGED
|
@@ -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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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);
|