pi-legion 3.0.3 → 4.0.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 (67) hide show
  1. package/CHANGELOG.md +263 -2
  2. package/CONTRIBUTING.md +4 -17
  3. package/README.md +29 -22
  4. package/agents/worker.md +1 -1
  5. package/docs/contracts/display-liveness-v1.md +373 -0
  6. package/docs/contracts/drop-non-pi-kinds-v4.md +198 -0
  7. package/docs/contracts/esc-abort-v1.md +4 -4
  8. package/docs/contracts/esc-no-retire-v3.md +2 -2
  9. package/docs/contracts/launch-admission-queue-v1.md +839 -0
  10. package/docs/contracts/status-panel-v1.md +174 -0
  11. package/docs/inprocess-supervisor.md +37 -4
  12. package/docs/legion-v2-contract.md +18 -2
  13. package/docs/performance-2026-10-19.md +199 -0
  14. package/docs/spawn-mode-visibility-v1.md +206 -0
  15. package/docs/vexillatio-contract.md +3 -1
  16. package/index.ts +633 -84
  17. package/package.json +4 -2
  18. package/skills/pi-legion/SKILL.md +2 -3
  19. package/src/agents/agents.ts +17 -10
  20. package/src/agents/overrides.ts +0 -1
  21. package/src/agents/presets.ts +14 -40
  22. package/src/agents/settings.ts +26 -77
  23. package/src/agents/step-model.ts +7 -22
  24. package/src/api.ts +1 -35
  25. package/src/extension/event-bus.ts +80 -8
  26. package/src/extension/legion-commands.ts +43 -17
  27. package/src/extension/legion-doctor.ts +1 -1
  28. package/src/extension/legion-stop.ts +39 -13
  29. package/src/extension/legion-tools.ts +21 -4
  30. package/src/extension/liveness.ts +200 -0
  31. package/src/extension/notify.ts +6 -6
  32. package/src/extension/playbook.ts +6 -6
  33. package/src/extension/recycle.ts +6 -2
  34. package/src/extension/runtime.ts +422 -18
  35. package/src/extension/slash.ts +0 -21
  36. package/src/extension/spawn-render.ts +183 -0
  37. package/src/extension/summary.ts +1 -1
  38. package/src/legion/db.ts +165 -1
  39. package/src/legion/events.ts +81 -16
  40. package/src/legion/nodes.ts +13 -2
  41. package/src/legion/rebuild.ts +7 -1
  42. package/src/legion/usage.ts +58 -4
  43. package/src/runs/orchestrator.ts +1165 -62
  44. package/src/runs/worktree.ts +190 -21
  45. package/src/shared/ignored-kind.ts +57 -0
  46. package/src/shared/progress.ts +11 -0
  47. package/src/shared/session.ts +199 -19
  48. package/src/shared/types.ts +50 -66
  49. package/src/supervisor/admission-queue.ts +516 -0
  50. package/src/supervisor/inprocess-supervisor.ts +108 -33
  51. package/src/supervisor/proc-memory.ts +67 -0
  52. package/src/supervisor/routing-supervisor.ts +58 -1
  53. package/src/tui/live-overlay.ts +14 -0
  54. package/src/tui/session-messages-file.ts +100 -0
  55. package/src/tui/status.ts +103 -21
  56. package/src/tui/tree-view.ts +36 -3
  57. package/src/tui/viz/layout.ts +54 -3
  58. package/src/tui/viz/model.ts +67 -14
  59. package/src/tui/viz/palette.ts +11 -0
  60. package/src/tui/viz/panels.ts +222 -8
  61. package/src/tui/viz/railway.ts +28 -25
  62. package/src/tui/viz/view.ts +110 -23
  63. package/src/backends/legacy/client.ts +0 -638
  64. package/src/backends/legacy/cursor-chat.ts +0 -348
  65. package/src/backends/legacy/runner.ts +0 -101
  66. package/src/backends/legacy/types.ts +0 -138
  67. package/src/runs/kind.ts +0 -260
@@ -17,36 +17,19 @@ export type AgentScope = "user" | "project" | "both";
17
17
 
18
18
  export type SystemPromptMode = "replace" | "append";
19
19
 
20
- /** Agent kinds parsed from role files; the RPC supervisor accepts only `pi`. */
21
- export const AGENT_KINDS = [
22
- "pi",
23
- "claude",
24
- "codex",
25
- "gemini",
26
- "cursor",
27
- "devin",
28
- "agy",
29
- "cline",
30
- "omp",
31
- "mastracode",
32
- "opencode",
33
- "copilot",
34
- "kimi",
35
- "kiro",
36
- "droid",
37
- "amp",
38
- "grok",
39
- "hermes",
40
- "kilo",
41
- "qodercli",
42
- "qwen",
43
- "maki",
44
- "muse",
45
- ] as const;
20
+ /**
21
+ * Agent kinds accepted from role files, presets and overrides.
22
+ *
23
+ * v4 runs `pi` only. The field and the type stay (plumbing and `run.json`
24
+ * records depend on them), but a non-`pi` value is ignored at parse time and
25
+ * the role launches as `pi` — see `parseAgentDocument` / `parsePreset` /
26
+ * `parseAgentOverride`, which report the ignored value once.
27
+ */
28
+ export const AGENT_KINDS = ["pi"] as const;
46
29
 
47
30
  export type AgentKind = (typeof AGENT_KINDS)[number];
48
31
 
49
- /** How Legion launches a child session: omit → `inprocess` (with automatic rpc fallback when the agent needs a worktree or `kind !== "pi"`). */
32
+ /** How Legion launches a child session: omit → `inprocess` (with automatic rpc fallback when the agent needs a worktree). */
50
33
  export const SPAWN_MODES = ["rpc", "inprocess"] as const;
51
34
  export type SpawnMode = (typeof SPAWN_MODES)[number];
52
35
 
@@ -226,6 +209,8 @@ export interface ModelScopeViolation {
226
209
 
227
210
  /** Lifecycle state. Independent of execution outcome. */
228
211
  export type TaskState =
212
+ /** D3: name allocated, no ledger row and no session file yet (launch queue). */
213
+ | "queued"
229
214
  | "launching"
230
215
  | "working"
231
216
  | "awaiting"
@@ -362,8 +347,6 @@ export interface ChildRecord {
362
347
  /** Model actually started with (resolved + fallback). */
363
348
  model?: string;
364
349
  thinking?: string | false;
365
- /** Models that were requested but cannot be represented by the RPC child. */
366
- modelDropped?: string[];
367
350
  /**
368
351
  * Backend this child was actually spawned on, as arbitrated by
369
352
  * `Orchestrator.launch` (#209). Optional because run.json records written
@@ -371,6 +354,10 @@ export interface ChildRecord {
371
354
  * unknown, never guess a backend.
372
355
  */
373
356
  spawnMode?: SpawnMode;
357
+ /** D4: 1-based queue position at the moment of enqueue; cleared once admitted. */
358
+ queuePosition?: number;
359
+ /** D6/D8: actual queue wait in ms (written on admission; absent when never queued). */
360
+ queueWaitedMs?: number;
374
361
  }
375
362
 
376
363
  export interface RunRecord {
@@ -430,6 +417,16 @@ export interface ParsedSession {
430
417
  /** True when the last user prompt has no assistant reply (F29 abort signal). */
431
418
  lastTurnMissing: boolean;
432
419
  tornLines: number;
420
+ /**
421
+ * Context size of the FINAL assistant message of the session: its
422
+ * `input + cacheRead + cacheWrite`, i.e. the prompt the model actually saw.
423
+ *
424
+ * Unlike `usage` (a cumulative total across every message) this is a current
425
+ * value, so it stops growing when the session stops. Optional because a
426
+ * session with no assistant message has no context yet — and there is no
427
+ * percentage to derive: session JSONL carries no `contextWindow`.
428
+ */
429
+ lastContextTokens?: number;
433
430
  /**
434
431
  * Cumulative model-generation wall time in ms: each completed assistant
435
432
  * message timestamp minus the preceding user or toolResult timestamp when
@@ -497,6 +494,23 @@ export interface Handle {
497
494
  * result, #209). Callers render this instead of assuming `rpc`.
498
495
  */
499
496
  spawnMode: SpawnMode;
497
+ /**
498
+ * OS process of an `rpc` child, when the supervisor reported one.
499
+ *
500
+ * Deliberately not persisted (no `run.json` / `legion.db` field): a pid is
501
+ * only meaningful inside the host that spawned it, so a later session would
502
+ * read a number that now belongs to some unrelated process. `inprocess`
503
+ * children have no pid of their own — they share this process.
504
+ */
505
+ pid?: number;
506
+ /**
507
+ * D4: this launch is still in the queue and has not spawned.
508
+ * `child.state === "queued"`, `sessionFile` is a placeholder path, and
509
+ * `pid` is necessarily absent.
510
+ */
511
+ queued?: boolean;
512
+ /** D4: 1-based queue position at enqueue time (always set when `queued === true`). */
513
+ queuePosition?: number;
500
514
  }
501
515
 
502
516
  // =============================================================================
@@ -504,11 +518,10 @@ export interface Handle {
504
518
  // =============================================================================
505
519
 
506
520
  /**
507
- * One named kind+model+thinking bundle in `subagents.presets`.
521
+ * One named (`kind`) model+thinking bundle in `subagents.presets`.
508
522
  *
509
- * `kind` and `model` travel together — a preset whose model does not fit the
510
- * target kind is rejected at expansion time (see `assertKindModelCoherent`),
511
- * because `nativeModelFor()` would otherwise silently drop the model.
523
+ * `kind` is kept for shape compatibility but only `pi` is accepted; any other
524
+ * value is ignored (reported once) and the preset applies as `pi`.
512
525
  */
513
526
  export interface PresetConfig {
514
527
  kind?: AgentKind;
@@ -516,22 +529,6 @@ export interface PresetConfig {
516
529
  thinking?: string | false;
517
530
  }
518
531
 
519
- /** @deprecated Transitional herdr.* settings retained until v3. */
520
- export interface HerdrSettings {
521
- /** @deprecated Parsed for transition compatibility; ignored by RPC v2. */
522
- defaultPlacement?: "split-down" | "split-right" | "new-tab";
523
- /** @deprecated Legacy concurrency hint; ignored by RPC v2. */
524
- maxConcurrentAgents?: number;
525
- /** @deprecated Legacy Herdr launch retry setting. */
526
- startRetries?: number;
527
- /** @deprecated Legacy Herdr launch retry setting. */
528
- startRetryBackoffMs?: number;
529
- /** @deprecated Legacy session retention setting. */
530
- sessionRetentionDays?: number;
531
- /** @deprecated Legacy session retention setting. */
532
- sessionRetentionMaxBytesPerRun?: number;
533
- }
534
-
535
532
  export interface LegionPhaseTimeouts {
536
533
  planning?: number;
537
534
  implementing?: number;
@@ -630,6 +627,10 @@ export interface InProcessLimits {
630
627
  maxActive?: number;
631
628
  maxChildrenPerNode?: number;
632
629
  waitTimeoutMs?: number;
630
+ /** D10: queued-launch cap (`positiveInt`, default 32; 0 is invalid). */
631
+ maxQueuedLaunches?: number;
632
+ /** D10: longest wait for one queued launch in ms (`positiveInt`, default 900000). */
633
+ launchQueueTimeoutMs?: number;
633
634
  }
634
635
 
635
636
  /**
@@ -699,8 +700,6 @@ export interface SubagentsSettings {
699
700
  disableBuiltins?: boolean;
700
701
  disableThinking?: boolean;
701
702
  maxSubagentSpawnsPerSession?: number;
702
- /** @deprecated Transitional herdr.* keys are parsed and ignored by RPC v2. */
703
- herdr?: HerdrSettings;
704
703
  legion?: LegionSettings;
705
704
  /** Completion-notice merge mode. Default "smart". */
706
705
  joinMode?: "each" | "smart";
@@ -766,10 +765,7 @@ export class SubagentError extends Error {
766
765
  }
767
766
 
768
767
  export const ErrorCodes = {
769
- HERDR_UNAVAILABLE: "HERDR_UNAVAILABLE",
770
768
  DISABLED: "DISABLED",
771
- /** @deprecated Legacy Herdr client error retained for API compatibility. */
772
- PANE_BUSY: "PANE_BUSY",
773
769
  START_FAILED: "START_FAILED",
774
770
  START_TIMEOUT: "START_TIMEOUT",
775
771
  NAME_TAKEN: "NAME_TAKEN",
@@ -788,20 +784,8 @@ export const ErrorCodes = {
788
784
  // =============================================================================
789
785
 
790
786
  export const DEFAULTS = {
791
- /** @deprecated Legacy Herdr start-retry settings retained by the archived backend. */
792
- startRetries: 40,
793
- startRetryBackoffMs: 150,
794
787
  /** F8: agent wait covers a turn; generous default. */
795
788
  turnTimeoutMs: 900_000,
796
789
  /** jsonl quiet window before declaring a turn settled. */
797
790
  settleQuietMs: 2_500,
798
- /** @deprecated Legacy Herdr concurrency hint retained during migration. */
799
- maxConcurrentAgents: 6,
800
- /** @deprecated Legacy Herdr session retention setting. */
801
- sessionRetentionDays: 7,
802
- /** @deprecated Legacy Herdr probe settings; retained for the archived backend. */
803
- startTimeoutMs: 45_000,
804
- binaryProbeTimeoutMs: 3_000,
805
- /** @deprecated Legacy Herdr command timeout retained for the archived backend. */
806
- commandTimeoutMs: 15_000,
807
791
  } as const;