@aragon-agent/cli 0.6.35 → 0.6.36

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 (146) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +3173 -3071
  3. package/dist/agent/agent-mode.d.ts +20 -4
  4. package/dist/agent/agent-mode.js +20 -4
  5. package/dist/agent/controller.d.ts +38 -3
  6. package/dist/agent/controller.js +64 -4
  7. package/dist/agent/headless.js +31 -0
  8. package/dist/agent/reducer.d.ts +13 -2
  9. package/dist/agent/reducer.js +1 -0
  10. package/dist/cli.js +12 -0
  11. package/dist/commands/agents-command.d.ts +15 -0
  12. package/dist/commands/agents-command.js +27 -0
  13. package/dist/commands/builtins.js +131 -4
  14. package/dist/commands/perf.d.ts +11 -0
  15. package/dist/commands/perf.js +2 -1
  16. package/dist/commands/registry.d.ts +14 -0
  17. package/dist/config/app-paths.d.ts +15 -0
  18. package/dist/config/app-paths.js +33 -2
  19. package/dist/config/env.d.ts +4 -1
  20. package/dist/config/env.js +28 -2
  21. package/dist/config/load.d.ts +10 -0
  22. package/dist/config/load.js +8 -1
  23. package/dist/config/schema.d.ts +68 -0
  24. package/dist/config/schema.js +39 -0
  25. package/dist/config/store.js +12 -1
  26. package/dist/config/ui-state.d.ts +18 -0
  27. package/dist/config/ui-state.js +9 -0
  28. package/dist/exec/events.d.ts +25 -0
  29. package/dist/exec/events.js +4 -0
  30. package/dist/exec/index.js +16 -1
  31. package/dist/exec/runner.js +10 -0
  32. package/dist/proc/limits.d.ts +16 -0
  33. package/dist/proc/limits.js +16 -0
  34. package/dist/proc/supervisor.d.ts +20 -1
  35. package/dist/proc/supervisor.js +42 -14
  36. package/dist/prompts/command.d.ts +34 -0
  37. package/dist/prompts/command.js +237 -0
  38. package/dist/prompts/copy.d.ts +89 -0
  39. package/dist/prompts/copy.js +131 -0
  40. package/dist/prompts/fill.d.ts +51 -0
  41. package/dist/prompts/fill.js +46 -0
  42. package/dist/prompts/limits.d.ts +53 -0
  43. package/dist/prompts/limits.js +53 -0
  44. package/dist/prompts/normalize.d.ts +53 -0
  45. package/dist/prompts/normalize.js +190 -0
  46. package/dist/prompts/resolve.d.ts +31 -0
  47. package/dist/prompts/resolve.js +60 -0
  48. package/dist/prompts/search.d.ts +58 -0
  49. package/dist/prompts/search.js +146 -0
  50. package/dist/prompts/store.d.ts +86 -0
  51. package/dist/prompts/store.js +453 -0
  52. package/dist/prompts/types.d.ts +204 -0
  53. package/dist/prompts/types.js +13 -0
  54. package/dist/session/checkpoint.d.ts +8 -1
  55. package/dist/session/checkpoint.js +6 -0
  56. package/dist/session/persist.d.ts +19 -1
  57. package/dist/session/persist.js +13 -1
  58. package/dist/session/startup-session.d.ts +7 -2
  59. package/dist/session/startup-session.js +5 -2
  60. package/dist/session/store.js +3 -0
  61. package/dist/session/validate-session.js +64 -1
  62. package/dist/team/limits.d.ts +25 -0
  63. package/dist/team/limits.js +26 -0
  64. package/dist/team/runtime.js +27 -2
  65. package/dist/team/settled.d.ts +57 -0
  66. package/dist/team/settled.js +87 -0
  67. package/dist/team/subagent.js +48 -2
  68. package/dist/team/timeline.d.ts +74 -0
  69. package/dist/team/timeline.js +101 -0
  70. package/dist/team/types.d.ts +24 -1
  71. package/dist/todo/acceptance.d.ts +120 -0
  72. package/dist/todo/acceptance.js +399 -0
  73. package/dist/todo/follow-through.d.ts +48 -23
  74. package/dist/todo/follow-through.js +110 -44
  75. package/dist/todo/limits.d.ts +62 -1
  76. package/dist/todo/limits.js +62 -1
  77. package/dist/todo/panel-rows.d.ts +29 -39
  78. package/dist/todo/panel-rows.js +37 -83
  79. package/dist/todo/plan-sections.d.ts +60 -0
  80. package/dist/todo/plan-sections.js +108 -0
  81. package/dist/todo/prompt.d.ts +17 -12
  82. package/dist/todo/prompt.js +59 -40
  83. package/dist/todo/row-window.d.ts +51 -0
  84. package/dist/todo/row-window.js +107 -0
  85. package/dist/todo/store.d.ts +139 -31
  86. package/dist/todo/store.js +271 -73
  87. package/dist/todo/todo-tool.d.ts +33 -8
  88. package/dist/todo/todo-tool.js +186 -30
  89. package/dist/todo/types.d.ts +58 -0
  90. package/dist/ui/App.js +310 -46
  91. package/dist/ui/Composer.d.ts +6 -2
  92. package/dist/ui/Composer.js +2 -2
  93. package/dist/ui/Header.d.ts +9 -1
  94. package/dist/ui/Header.js +2 -2
  95. package/dist/ui/PromptInput.d.ts +21 -1
  96. package/dist/ui/PromptInput.js +21 -1
  97. package/dist/ui/ScrollbackShell.d.ts +19 -19
  98. package/dist/ui/ScrollbackShell.js +8 -1
  99. package/dist/ui/StatusBar.d.ts +5 -0
  100. package/dist/ui/StatusBar.js +1 -0
  101. package/dist/ui/TeamPanel.d.ts +26 -44
  102. package/dist/ui/TeamPanel.js +46 -135
  103. package/dist/ui/TodoPanel.d.ts +17 -14
  104. package/dist/ui/TodoPanel.js +146 -38
  105. package/dist/ui/Transcript.js +1 -1
  106. package/dist/ui/composer-input.d.ts +10 -0
  107. package/dist/ui/composer-input.js +57 -24
  108. package/dist/ui/entries/TodoCard.d.ts +26 -11
  109. package/dist/ui/entries/TodoCard.js +56 -15
  110. package/dist/ui/glyphs.d.ts +19 -0
  111. package/dist/ui/glyphs.js +4 -0
  112. package/dist/ui/layout/agents-board.d.ts +102 -0
  113. package/dist/ui/layout/agents-board.js +389 -0
  114. package/dist/ui/layout/cells.d.ts +61 -0
  115. package/dist/ui/layout/cells.js +156 -0
  116. package/dist/ui/layout/header-hints.d.ts +13 -3
  117. package/dist/ui/layout/header-hints.js +48 -14
  118. package/dist/ui/layout/status-detail-layout.js +9 -0
  119. package/dist/ui/layout/status-layout.d.ts +13 -0
  120. package/dist/ui/layout/team-row.d.ts +139 -0
  121. package/dist/ui/layout/team-row.js +246 -0
  122. package/dist/ui/layout/todo-layout.d.ts +38 -0
  123. package/dist/ui/layout/todo-layout.js +75 -0
  124. package/dist/ui/layout/virtual-window.js +23 -3
  125. package/dist/ui/overlays/AgentsBoardOverlay.d.ts +57 -0
  126. package/dist/ui/overlays/AgentsBoardOverlay.js +183 -0
  127. package/dist/ui/overlays/HelpOverlay.js +17 -2
  128. package/dist/ui/overlays/PromptEditorPage.d.ts +48 -0
  129. package/dist/ui/overlays/PromptEditorPage.js +227 -0
  130. package/dist/ui/overlays/PromptLibraryOverlay.d.ts +37 -0
  131. package/dist/ui/overlays/PromptLibraryOverlay.js +191 -0
  132. package/dist/ui/overlays/PromptPicker.d.ts +36 -0
  133. package/dist/ui/overlays/PromptPicker.js +129 -0
  134. package/dist/ui/overlays/PromptTextArea.d.ts +86 -0
  135. package/dist/ui/overlays/PromptTextArea.js +141 -0
  136. package/dist/ui/overlays/prompt-library-state.d.ts +162 -0
  137. package/dist/ui/overlays/prompt-library-state.js +335 -0
  138. package/dist/ui/overlays/prompt-picker-state.d.ts +71 -0
  139. package/dist/ui/overlays/prompt-picker-state.js +98 -0
  140. package/dist/ui/scrollback/band.js +14 -1
  141. package/dist/ui/team-status.d.ts +25 -0
  142. package/dist/ui/team-status.js +31 -3
  143. package/dist/ui/use-startup-notices.d.ts +35 -1
  144. package/dist/ui/use-startup-notices.js +29 -2
  145. package/dist/ui/use-wheel-routing.js +9 -1
  146. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  /**
2
- * `TodoStore` — the session's todo list plus its CLI-local event stream
3
- * (todo-plan-execution §3.5).
2
+ * `TodoStore` — the session's todo list, its acceptance table, and its CLI-local
3
+ * event stream (todo-plan-execution §3.5; todo-acceptance-criteria §6.2.3).
4
4
  *
5
5
  * ASCII ONLY: `src/todo/**` is inside the glyph scanner's scope.
6
6
  *
@@ -9,54 +9,105 @@
9
9
  * is why `AgentController` can own this object as unconditionally as it owns
10
10
  * `TeamRuntime`.
11
11
  *
12
- * The list projects the current plan. Explicit clear/reset and a new TUI task
13
- * may remove that projection while the model still remembers the old plan.
14
- * Continuations preserve it; legacy callers retain completion/staleness rules.
12
+ * TWO TABLES, ONE WRITER, ONE COMMIT. `items` and `acceptance` are the plan's two
13
+ * halves: they are replaced together, cleared together, and refused together
14
+ * (I-4). Nothing here is a partial update, which is what makes I-9 ("the panel is
15
+ * never a contradiction of the model") provable rather than argued.
15
16
  *
16
- * Every write is a FULL REPLACEMENT and every clear is a FULL REMOVAL - there is
17
- * no partial update anywhere, which is what makes I-9 ("the panel is never a
18
- * contradiction of the model") provable rather than argued.
17
+ * `snapshot()` IS NOT A COMPUTATION. Every projection is rebuilt at the commit
18
+ * points (`write` / `restore` / `clear` / `reopenAll`, plus
19
+ * `refreshAcceptanceProjection` when `todo.acceptance` is flipped) and merely READ
20
+ * here, because `App` calls `snapshot()` on every event: re-deriving and
21
+ * re-stamping on read would give the reducer a new object every frame, invalidate
22
+ * `TodoCard`'s `React.memo` and the transcript's height cache, and undo the redraw
23
+ * savings `mapEntry` buys with object identity (P1-3).
19
24
  */
20
- import { type NormalizeResult } from './normalize.js';
21
- import type { TodoClearReason, TodoEventListener, TodoSnapshot } from './types.js';
25
+ import type { AcceptanceItem, TodoClearReason, TodoEventListener, TodoItem, TodoSnapshot } from './types.js';
26
+ /**
27
+ * What a `write()` decided.
28
+ *
29
+ * `accepted === false` means the WHOLE payload was refused and both tables are the
30
+ * current, unmodified projections. `refusalKind` decides which `ToolResult` the
31
+ * tool side builds: a `'payload'` refusal is a broken payload (the existing
32
+ * `errorResult`, kept byte for byte), while a `'policy'` refusal is an incomplete
33
+ * plan (a `textResult` - the tool is not broken, so an error result would invite
34
+ * the model to retry the identical payload).
35
+ */
36
+ export interface TodoWriteResult {
37
+ accepted: boolean;
38
+ items: TodoItem[];
39
+ acceptance: AcceptanceItem[];
40
+ repairs: string[];
41
+ /** Non-empty when `accepted === false`: the final, model-readable refusal text. */
42
+ refusal?: string;
43
+ refusalKind?: 'payload' | 'policy';
44
+ }
45
+ /** The one model-readable refusal that is about the PLAN, not about the payload. */
46
+ export declare const FRESH_ACCEPTANCE_REFUSAL: string;
22
47
  export declare class TodoStore {
23
48
  private readonly now;
49
+ private readonly acceptanceEnabled;
24
50
  private items;
51
+ private acceptance;
25
52
  private updatedAt;
26
53
  /** Consecutive `beginUserTurn()` calls since the last `write()`. */
27
54
  private turnsSinceWrite;
55
+ /**
56
+ * The acceptance projection. REBUILT AT COMMIT TIME ONLY — see the file header.
57
+ * `null` when there are no criteria, which is also what keeps the rail's second
58
+ * section, the card's second block and the status chip unrendered.
59
+ */
60
+ private acceptanceSnapshot;
61
+ /**
62
+ * Criteria whose verdict has already been reported as restored. Without it the
63
+ * model would receive the SAME `Note:` on every turn, because it cannot know the
64
+ * server restored anything and keeps re-sending the row as `pending` (P2-4).
65
+ * Cleared by `clear()` / `restore()`; a criterion's key is removed when the criterion
66
+ * itself leaves the table (not when it stops being `pending`, which would delete the
67
+ * key in the same commit that added it - see `pruneRestoredNotes`).
68
+ */
69
+ private readonly restoredNotes;
28
70
  private readonly listeners;
29
71
  /**
30
72
  * @param now Injected clock. Defaults to `Date.now`; a test passes a counter
31
73
  * so `TodoSnapshot.updatedAt` is not wall time (P2-4).
74
+ * @param acceptanceEnabled Live read of `todo.acceptance` (D-11). Read, never
75
+ * snapshotted: `/todo acceptance off` must take effect mid-session,
76
+ * because the tool array cannot change (C-1).
32
77
  */
33
- constructor(now?: () => number);
78
+ constructor(now?: () => number, acceptanceEnabled?: () => boolean);
34
79
  /** `null` means no list, which is what leaves the rail unmounted entirely. */
35
80
  snapshot(): TodoSnapshot | null;
81
+ /** The acceptance table itself, for the transcript entry and the session file. */
82
+ acceptanceItems(): AcceptanceItem[];
36
83
  isEmpty(): boolean;
37
84
  /**
38
85
  * Commit a model payload.
39
86
  *
40
- * ZERO SURVIVORS LEAVES THE PREVIOUS LIST UNTOUCHED (AC-9). A model sending
41
- * nothing usable is a BUG, and destroying a working plan because of one
42
- * malformed call is the worst available reaction; the caller turns the empty
43
- * result into an error the model can act on. Contrast `restore()`, where an
44
- * empty list is a FACT about a file and therefore means "clear".
87
+ * ZERO SURVIVORS LEAVES THE PREVIOUS PLAN UNTOUCHED (AC-9 / I-4), and so does an
88
+ * incomplete fresh plan: a model sending nothing usable is a BUG, and destroying
89
+ * a working plan because of one malformed call is the worst available reaction.
90
+ * The caller turns the refusal into something the model can act on. Contrast
91
+ * `restore()`, where an empty list is a FACT about a file and therefore means
92
+ * "clear".
45
93
  */
46
- write(raw: unknown): NormalizeResult;
94
+ write(raw: unknown): TodoWriteResult;
47
95
  /**
48
- * `/resume`. Runs through `normalizeTodos` — a session file is user-editable
96
+ * `/resume`. Runs through both normalizers — a session file is user-editable
49
97
  * input and gets a model payload's treatment.
50
98
  *
51
- * AN EMPTY (OR ALL-DROPPED) ARRAY CLEARS; IT DOES NOT NO-OP (P0-2 / D-22).
99
+ * AN EMPTY (OR ALL-DROPPED) TODO ARRAY CLEARS; IT DOES NOT NO-OP (P0-2 / D-22).
52
100
  * `/resume` has just called `replaceMessages`, so the conversation the current
53
- * list belonged to is gone; leaving it on screen is I-2 INVERTED — a panel
54
- * that disagrees with the model, which §1.2 ranks below having no panel at
55
- * all. The two entry points share normalization and differ only here, which is
56
- * exactly the difference between "the model sent nothing" (a bug) and "the
57
- * file has nothing" (a fact).
101
+ * plan belonged to is gone; leaving it on screen is I-2 INVERTED — a panel that
102
+ * disagrees with the model, which §1.2 ranks below having no panel at all. The
103
+ * acceptance table goes with it: no plan, no criteria.
104
+ *
105
+ * `enabled: true` is passed to the normalizer on purpose: the file is a fact
106
+ * about what this plan contained, and the current switch only governs RENDERING
107
+ * and PROMPTING. A user who turns the capability off and back on must not find
108
+ * that a resume quietly deleted the stored verdicts.
58
109
  */
59
- restore(items: unknown): void;
110
+ restore(items: unknown, acceptance?: unknown): void;
60
111
  clear(reason: TodoClearReason): void;
61
112
  /**
62
113
  * The turn boundary (§3.2).
@@ -64,15 +115,29 @@ export declare class TodoStore {
64
115
  * Called from `AgentController.prompt()` and NOT from `steer()` — the same
65
116
  * asymmetry, for the same reason, that `askRounds = 0` already has: a steer is
66
117
  * a mid-turn interjection, not a new task. The stale counter inherits that
67
- * asymmetry for free, which is the behaviour you want: a steer must not age
68
- * out the plan it is steering.
118
+ * asymmetry for free, which is the behaviour you want: a steer must not age out
119
+ * the plan it is steering.
69
120
  *
70
- * A new TUI task drops the old plan here, while a continuation preserves it.
71
- * With no policy, legacy callers retain completed/stale-plan expiration.
72
- * Clearing at `agent_end` would erase the final progress before the user can
73
- * inspect it and remove the plan that automatic continuation still needs.
121
+ * "EVERY STEP IS COMPLETED" NO LONGER MEANS "THERE IS NOTHING LEFT" (G-4):
122
+ * the rule is `planIsResolved`, which also asks whether every criterion has a
123
+ * verdict. A plan that is done but unverified is not idle work, it is one step
124
+ * short - so it ages by `staleTurns` instead of vanishing the moment the model
125
+ * ticks its last step.
74
126
  */
75
127
  beginUserTurn(policy?: 'new-task' | 'continue'): void;
128
+ /**
129
+ * Send every verdict back to `pending` and clear the evidence (§6.2.3).
130
+ *
131
+ * THE NAMED WRITER `/todo acceptance reset` NEEDS, so the command layer never
132
+ * walks the table itself. It is not a second writer of the plan: `items` stays
133
+ * exactly as it is, no `cleared` event is emitted (`TodoClearReason` therefore
134
+ * does not change), and only the verdict fields move - the same rule as
135
+ * `reopen: true`, entered from the user's side instead of the model's (AC-6).
136
+ *
137
+ * IDEMPOTENT: with nothing to re-open it returns 0 and emits NOTHING, so an
138
+ * empty command cannot make the transcript card blink for no reason.
139
+ */
140
+ reopenAll(): number;
76
141
  /**
77
142
  * Report a refusal that never reached `write()` (§3.3 steps 1 and 2).
78
143
  *
@@ -82,6 +147,49 @@ export declare class TodoStore {
82
147
  */
83
148
  reject(reason: string): void;
84
149
  subscribe(listener: TodoEventListener): () => void;
150
+ /** A refusal that changed nothing, expressed as a result the tool can branch on. */
151
+ private refusal;
152
+ /** Both tables, both projections, one timestamp, one event. */
153
+ private commit;
154
+ /**
155
+ * THE ONLY PRODUCER OF `in_progress` (P0-1 / AC-43).
156
+ *
157
+ * Normalization only ever DOWNGRADES that state; rendering and phase derivation
158
+ * only READ it. One state, one writer - otherwise the rail's anchor and the
159
+ * derived phase would each pick a different "criterion being checked".
160
+ *
161
+ * Forward only: criteria are promoted once EVERY step is completed, because a
162
+ * criterion cannot be under inspection while its steps are still running.
163
+ */
164
+ private deriveInProgress;
165
+ /**
166
+ * Re-project the acceptance table after `todo.acceptance` was flipped mid-session.
167
+ *
168
+ * THE SWITCH GOVERNS RENDERING, and the rail, the card and the status chip all read
169
+ * `snapshot().acceptance` rather than the flag - so without this, `/todo acceptance
170
+ * off` on a plan that already had criteria would leave the second section on screen
171
+ * until the model's next write, which is exactly the complaint P0-2 raised one path
172
+ * further out. The DATA is kept either way: turning the capability back on restores
173
+ * the same verdicts without a round trip through the model.
174
+ *
175
+ * Emits only when the projection's VISIBILITY actually changed, so a no-op flip can
176
+ * never make the transcript card blink.
177
+ */
178
+ refreshAcceptanceProjection(): boolean;
179
+ /** Rebuild the acceptance projection. The ONLY place `acceptanceSummary` runs. */
180
+ private commitAcceptance;
181
+ /**
182
+ * Forget a restoration note once its criterion has LEFT the table.
183
+ *
184
+ * `filtered on pending` would be the wrong rule and was the first version of this:
185
+ * the criterion that `noteOnce` just announced is restored WITH ITS VERDICT
186
+ * (`passed` / `failed`), so a pending filter deletes the key in the same commit that
187
+ * added it, the model re-sends the row as `pending` on the next turn, and the note is
188
+ * re-printed every turn for the life of the plan - the unbounded billing P2-4 exists
189
+ * to prevent. Keeping the key until the criterion is gone is also free: the set can
190
+ * never hold more than `ACCEPT_LIMITS.maxItems` entries.
191
+ */
192
+ private pruneRestoredNotes;
85
193
  /** Per-listener isolation: one bad subscriber cannot fail a tool call. */
86
194
  private emit;
87
195
  }