@aragon-agent/cli 0.6.38 → 0.6.40

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 (209) hide show
  1. package/CHANGELOG.md +263 -0
  2. package/README.md +544 -11
  3. package/dist/agent/controller.d.ts +245 -10
  4. package/dist/agent/controller.js +367 -22
  5. package/dist/agent/model-profile-settings.js +12 -1
  6. package/dist/agent/plan-prompt.d.ts +1 -3
  7. package/dist/agent/plan-prompt.js +13 -7
  8. package/dist/agent/reducer.d.ts +70 -2
  9. package/dist/agent/reducer.js +59 -6
  10. package/dist/agent/skill-triage-prompt.d.ts +42 -0
  11. package/dist/agent/skill-triage-prompt.js +74 -0
  12. package/dist/agent/system-prompt.d.ts +28 -2
  13. package/dist/agent/system-prompt.js +12 -4
  14. package/dist/cli.js +106 -32
  15. package/dist/commands/builtins.js +24 -3
  16. package/dist/commands/keys-command.d.ts +23 -0
  17. package/dist/commands/keys-command.js +38 -0
  18. package/dist/commands/registry.d.ts +39 -0
  19. package/dist/commands/skills.js +86 -1
  20. package/dist/commands/subagent-command.d.ts +25 -0
  21. package/dist/commands/subagent-command.js +242 -0
  22. package/dist/commands/task-command.d.ts +39 -0
  23. package/dist/commands/task-command.js +102 -0
  24. package/dist/compaction/command.js +16 -3
  25. package/dist/compaction/compactor.d.ts +25 -0
  26. package/dist/compaction/compactor.js +111 -10
  27. package/dist/compaction/digest.d.ts +24 -1
  28. package/dist/compaction/digest.js +139 -17
  29. package/dist/compaction/limits.d.ts +21 -0
  30. package/dist/compaction/limits.js +21 -0
  31. package/dist/compaction/reason-text.d.ts +36 -0
  32. package/dist/compaction/reason-text.js +78 -0
  33. package/dist/compaction/types.d.ts +82 -14
  34. package/dist/compaction/wiring.d.ts +13 -8
  35. package/dist/compaction/wiring.js +1 -0
  36. package/dist/config/cli-commands.d.ts +23 -0
  37. package/dist/config/cli-commands.js +36 -0
  38. package/dist/config/env.js +17 -4
  39. package/dist/config/load.js +55 -3
  40. package/dist/config/schema.d.ts +125 -10
  41. package/dist/config/schema.js +138 -14
  42. package/dist/config/store.js +23 -3
  43. package/dist/diagnostics/doctor.d.ts +9 -0
  44. package/dist/diagnostics/doctor.js +34 -0
  45. package/dist/diagnostics/info.d.ts +71 -0
  46. package/dist/diagnostics/info.js +91 -5
  47. package/dist/exec/bridge/caller-tools.d.ts +96 -0
  48. package/dist/exec/bridge/caller-tools.js +213 -0
  49. package/dist/exec/bridge/decisions.d.ts +78 -0
  50. package/dist/exec/bridge/decisions.js +116 -0
  51. package/dist/exec/bridge/human-answers.d.ts +38 -0
  52. package/dist/exec/bridge/human-answers.js +164 -0
  53. package/dist/exec/bridge/limits.d.ts +68 -0
  54. package/dist/exec/bridge/limits.js +68 -0
  55. package/dist/exec/bridge/ndjson.d.ts +17 -0
  56. package/dist/exec/bridge/ndjson.js +83 -0
  57. package/dist/exec/bridge/pending.d.ts +70 -0
  58. package/dist/exec/bridge/pending.js +132 -0
  59. package/dist/exec/bridge/protocol.d.ts +346 -0
  60. package/dist/exec/bridge/protocol.js +256 -0
  61. package/dist/exec/bridge/server.d.ts +142 -0
  62. package/dist/exec/bridge/server.js +502 -0
  63. package/dist/exec/bridge/source.d.ts +58 -0
  64. package/dist/exec/bridge/source.js +145 -0
  65. package/dist/exec/bridge/writer.d.ts +26 -0
  66. package/dist/exec/bridge/writer.js +156 -0
  67. package/dist/exec/cli-commands.js +30 -2
  68. package/dist/exec/emitter.d.ts +16 -2
  69. package/dist/exec/emitter.js +26 -6
  70. package/dist/exec/events.d.ts +465 -10
  71. package/dist/exec/events.js +47 -1
  72. package/dist/exec/hooks/dispatch.d.ts +76 -0
  73. package/dist/exec/hooks/dispatch.js +169 -0
  74. package/dist/exec/hooks/index.d.ts +83 -0
  75. package/dist/exec/hooks/index.js +205 -0
  76. package/dist/exec/hooks/limits.d.ts +56 -0
  77. package/dist/exec/hooks/limits.js +49 -0
  78. package/dist/exec/hooks/registry.d.ts +49 -0
  79. package/dist/exec/hooks/registry.js +91 -0
  80. package/dist/exec/hooks/tool-wrapper.d.ts +94 -0
  81. package/dist/exec/hooks/tool-wrapper.js +154 -0
  82. package/dist/exec/hooks/turn.d.ts +61 -0
  83. package/dist/exec/hooks/turn.js +59 -0
  84. package/dist/exec/hooks/validate.d.ts +85 -0
  85. package/dist/exec/hooks/validate.js +310 -0
  86. package/dist/exec/index.d.ts +130 -4
  87. package/dist/exec/index.js +501 -10
  88. package/dist/exec/options.d.ts +124 -2
  89. package/dist/exec/options.js +413 -6
  90. package/dist/exec/permission.d.ts +9 -1
  91. package/dist/exec/permission.js +7 -1
  92. package/dist/exec/request/limits.d.ts +51 -0
  93. package/dist/exec/request/limits.js +49 -0
  94. package/dist/exec/request/scope.d.ts +106 -0
  95. package/dist/exec/request/scope.js +149 -0
  96. package/dist/exec/result/limits.d.ts +74 -0
  97. package/dist/exec/result/limits.js +72 -0
  98. package/dist/exec/result/prompt.d.ts +28 -0
  99. package/dist/exec/result/prompt.js +74 -0
  100. package/dist/exec/result/schema.d.ts +99 -0
  101. package/dist/exec/result/schema.js +464 -0
  102. package/dist/exec/result/sink.d.ts +56 -0
  103. package/dist/exec/result/sink.js +50 -0
  104. package/dist/exec/result/tool.d.ts +37 -0
  105. package/dist/exec/result/tool.js +118 -0
  106. package/dist/exec/runner.d.ts +395 -1
  107. package/dist/exec/runner.js +860 -8
  108. package/dist/exec/threads/aggregate.d.ts +34 -0
  109. package/dist/exec/threads/aggregate.js +30 -0
  110. package/dist/exec/threads/capacity.d.ts +23 -0
  111. package/dist/exec/threads/capacity.js +38 -0
  112. package/dist/exec/threads/dispatch-source.d.ts +60 -0
  113. package/dist/exec/threads/dispatch-source.js +106 -0
  114. package/dist/exec/threads/execute-threads.d.ts +53 -0
  115. package/dist/exec/threads/execute-threads.js +234 -0
  116. package/dist/exec/threads/gate.d.ts +42 -0
  117. package/dist/exec/threads/gate.js +81 -0
  118. package/dist/exec/threads/identity.d.ts +36 -0
  119. package/dist/exec/threads/identity.js +67 -0
  120. package/dist/exec/threads/interrupt.d.ts +29 -0
  121. package/dist/exec/threads/interrupt.js +79 -0
  122. package/dist/exec/threads/limits.d.ts +58 -0
  123. package/dist/exec/threads/limits.js +35 -0
  124. package/dist/exec/threads/outcome.d.ts +47 -0
  125. package/dist/exec/threads/outcome.js +26 -0
  126. package/dist/exec/threads/registry.d.ts +81 -0
  127. package/dist/exec/threads/registry.js +427 -0
  128. package/dist/exec/threads/runtime.d.ts +107 -0
  129. package/dist/exec/threads/runtime.js +523 -0
  130. package/dist/exec/threads/thread-source.d.ts +20 -0
  131. package/dist/exec/threads/thread-source.js +134 -0
  132. package/dist/fast/limits.d.ts +54 -0
  133. package/dist/fast/limits.js +54 -0
  134. package/dist/fast/summary-call.d.ts +72 -0
  135. package/dist/fast/summary-call.js +133 -0
  136. package/dist/fast/summary-prompt.d.ts +106 -0
  137. package/dist/fast/summary-prompt.js +320 -0
  138. package/dist/fast/task-summary-types.d.ts +66 -0
  139. package/dist/fast/task-summary-types.js +17 -0
  140. package/dist/logging/logger.d.ts +1 -1
  141. package/dist/proc/limits.d.ts +7 -0
  142. package/dist/proc/limits.js +7 -0
  143. package/dist/proc/log-mirror.d.ts +21 -4
  144. package/dist/proc/log-mirror.js +29 -7
  145. package/dist/proc/output-streams.d.ts +50 -0
  146. package/dist/proc/output-streams.js +54 -0
  147. package/dist/skills/service.d.ts +41 -0
  148. package/dist/skills/service.js +62 -0
  149. package/dist/skills/triage.d.ts +194 -0
  150. package/dist/skills/triage.js +393 -0
  151. package/dist/team/forced-dispatch.d.ts +95 -0
  152. package/dist/team/forced-dispatch.js +208 -0
  153. package/dist/team/limits.d.ts +21 -1
  154. package/dist/team/limits.js +21 -1
  155. package/dist/team/normalize.d.ts +15 -0
  156. package/dist/team/normalize.js +21 -4
  157. package/dist/team/prompt.d.ts +6 -3
  158. package/dist/team/prompt.js +9 -5
  159. package/dist/team/runtime.d.ts +9 -0
  160. package/dist/team/runtime.js +8 -0
  161. package/dist/team/subagent.d.ts +15 -0
  162. package/dist/team/subagent.js +45 -1
  163. package/dist/team/task-tool.js +11 -7
  164. package/dist/tools/bash-tool.d.ts +10 -0
  165. package/dist/tools/bash-tool.js +71 -6
  166. package/dist/tools/human-input.d.ts +35 -2
  167. package/dist/tools/human-input.js +38 -0
  168. package/dist/tools/index.d.ts +93 -1
  169. package/dist/tools/index.js +112 -3
  170. package/dist/tools/plan-tools.d.ts +20 -12
  171. package/dist/tools/plan-tools.js +24 -17
  172. package/dist/tools/tool-gate.d.ts +100 -0
  173. package/dist/tools/tool-gate.js +87 -0
  174. package/dist/ui/App.js +238 -12
  175. package/dist/ui/Header.d.ts +28 -16
  176. package/dist/ui/Header.js +21 -19
  177. package/dist/ui/StatusBar.d.ts +1 -0
  178. package/dist/ui/StatusBar.js +1 -0
  179. package/dist/ui/Transcript.js +1 -1
  180. package/dist/ui/entries/CompactionCard.d.ts +11 -1
  181. package/dist/ui/entries/CompactionCard.js +65 -4
  182. package/dist/ui/interaction-hints.js +6 -0
  183. package/dist/ui/layout/OverlayFrame.d.ts +18 -0
  184. package/dist/ui/layout/OverlayFrame.js +19 -4
  185. package/dist/ui/layout/header-hints.d.ts +55 -62
  186. package/dist/ui/layout/header-hints.js +59 -166
  187. package/dist/ui/layout/header-left.d.ts +115 -0
  188. package/dist/ui/layout/header-left.js +206 -0
  189. package/dist/ui/layout/shortcut-panel-layout.d.ts +191 -0
  190. package/dist/ui/layout/shortcut-panel-layout.js +321 -0
  191. package/dist/ui/layout/status-detail-layout.js +5 -1
  192. package/dist/ui/layout/status-layout.d.ts +10 -0
  193. package/dist/ui/layout/status-layout.js +18 -1
  194. package/dist/ui/layout/task-summary-cell.d.ts +61 -0
  195. package/dist/ui/layout/task-summary-cell.js +65 -0
  196. package/dist/ui/overlays/HelpOverlay.d.ts +12 -0
  197. package/dist/ui/overlays/HelpOverlay.js +29 -2
  198. package/dist/ui/overlays/SettingsScreen.js +29 -5
  199. package/dist/ui/overlays/ShortcutPanel.d.ts +39 -0
  200. package/dist/ui/overlays/ShortcutPanel.js +106 -0
  201. package/dist/ui/overlays/TeamFanoutPage.d.ts +35 -0
  202. package/dist/ui/overlays/TeamFanoutPage.js +78 -0
  203. package/dist/ui/overlays/model-profile-state.d.ts +19 -1
  204. package/dist/ui/overlays/model-profile-state.js +12 -0
  205. package/dist/ui/overlays/team-fanout-state.d.ts +73 -0
  206. package/dist/ui/overlays/team-fanout-state.js +97 -0
  207. package/dist/ui/shortcuts.d.ts +81 -0
  208. package/dist/ui/shortcuts.js +221 -0
  209. package/package.json +2 -2
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Settings > Team fan-out: the pure half of the page (subagent-fanout 3.4.2).
3
+ *
4
+ * ASCII ONLY - `src/ui/**` is inside `glyphs.test.ts::inScope`.
5
+ *
6
+ * THE PAGE WRITES THREE KEYS AND CANNOT BE MADE TO WRITE A FOURTH (D-17 /
7
+ * R-P0-1). `TeamFanoutPatch` is `Pick<TeamConfig, 'maxSubagents' |
8
+ * 'maxConcurrent' | 'overseer'>`, and `stepFanoutValue` returns
9
+ * `Partial<TeamFanoutPatch>`: a width adjustment therefore CANNOT carry `model`
10
+ * or `modelProfileId` into `draft.patch.team`. That matters because
11
+ * `releasedSlots` reads those two keys as "the user re-decided the subagent
12
+ * slot", so a page that returned the whole section would silently release the
13
+ * model a session kit had just installed - and no test would notice, because
14
+ * every value on screen would still be right.
15
+ *
16
+ * EVERYTHING HERE IS A PURE FUNCTION over the draft. The page owns exactly one
17
+ * piece of state (its cursor); values come from the reducer, which is the same
18
+ * discipline the rest of this screen follows.
19
+ */
20
+ import { clampTeamConfig, HARD_MAX_SUBAGENTS } from '../../config/schema.js';
21
+ function clampInt(value, min, max) {
22
+ return Math.max(min, Math.min(max, Math.floor(value)));
23
+ }
24
+ /**
25
+ * The CLAMPED team section this draft would save (R-P0-2), for display only.
26
+ *
27
+ * THE CLAMP IS NOT COSMETIC. Without it a patch carrying only
28
+ * `maxSubagents: 6` renders "6 per dispatch, 8 at once" on top of an 8-wide
29
+ * baseline, while `mergePersistedConfig` clamps the same patch to 6/6 on the way
30
+ * to disk - so the screen and the file disagree, and every arrow key makes the
31
+ * user reconcile them by hand.
32
+ */
33
+ export function teamFanoutValues(draft) {
34
+ return clampTeamConfig({ ...draft.baseline.team, ...draft.patch.team });
35
+ }
36
+ /**
37
+ * The PATCH FRAGMENT for one arrow press, clamped exactly like `clampTeamConfig`.
38
+ *
39
+ * `current` must be the value the screen actually shows (`teamFanoutValues`), so
40
+ * a step always starts from a number the user can see.
41
+ *
42
+ * NO WRAPAROUND: a form control is not a ring, and `Left` at 1 jumping to 10
43
+ * would be a way to widen a dispatch while trying to narrow it.
44
+ */
45
+ export function stepFanoutValue(current, field, delta) {
46
+ if (field === 'overseer') {
47
+ // Both arrows toggle: `Supervisor` has two states, so a direction has no
48
+ // meaning beyond "the user pressed an arrow".
49
+ return { overseer: !current.overseer };
50
+ }
51
+ if (field === 'maxConcurrent') {
52
+ const ceiling = Math.min(HARD_MAX_SUBAGENTS, current.maxSubagents);
53
+ return { maxConcurrent: clampInt(current.maxConcurrent + delta, 1, ceiling) };
54
+ }
55
+ const next = clampInt(current.maxSubagents + delta, 1, HARD_MAX_SUBAGENTS);
56
+ // THE FOLLOW-DOWN IS WRITTEN INTO THE PATCH (R-P1-9), not just rendered: a
57
+ // narrower population cannot keep a wider pool, but a DISPLAY-only correction
58
+ // would snap back the moment the user widened again, so "the change I just
59
+ // made" would not stick - the exact complaint this design exists to answer.
60
+ return current.maxConcurrent > next
61
+ ? { maxSubagents: next, maxConcurrent: next }
62
+ : { maxSubagents: next };
63
+ }
64
+ /**
65
+ * The page's three rows.
66
+ *
67
+ * TWO HINTS CARRY A CONDITION THE DESIGN OWNS RATHER THAN DECORATION (R-1 / C-2):
68
+ * the default pool is now 8, which is 8 simultaneous streams against one API key,
69
+ * and the honest mitigation for an HTTP 429 storm is "lower this number" - said
70
+ * HERE, where the number is, not only in a risk table nobody reads.
71
+ */
72
+ export function fanoutRows(team) {
73
+ return [
74
+ {
75
+ field: 'maxSubagents',
76
+ label: 'Max subagents',
77
+ value: String(team.maxSubagents),
78
+ hint: `children per dispatch; ${HARD_MAX_SUBAGENTS} is the hard ceiling`,
79
+ },
80
+ {
81
+ field: 'maxConcurrent',
82
+ label: 'Run at once',
83
+ value: String(team.maxConcurrent),
84
+ hint: 'provider limits: lower this if you see rate-limit errors',
85
+ },
86
+ {
87
+ field: 'overseer',
88
+ label: 'Supervisor',
89
+ value: team.overseer ? 'on' : 'off',
90
+ hint: 'checks stalled children; never kills them',
91
+ },
92
+ ];
93
+ }
94
+ /** The one-line summary the settings root row prints for this page. */
95
+ export function fanoutSummary(team) {
96
+ return `${team.maxSubagents} per dispatch, ${team.maxConcurrent} at once`;
97
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * THE shortcut table (tui-shortcut-drawer-and-task-summary §4.6 / appendix B).
3
+ *
4
+ * ASCII ONLY, AND THAT IS A HARD CONSTRAINT RATHER THAN A STYLE CHOICE: this file
5
+ * is inside `glyphs.test.ts::inScope` (`ui/` prefix), whose `A-1` case fails on a
6
+ * single non-ASCII byte. Every `keyword` and `detail` below is English on
7
+ * purpose; translating them would turn the scanner red, and the only escape
8
+ * hatch - adding this file to the exemptions - is the thing that helper's own
9
+ * comment argues against.
10
+ *
11
+ * THIS IS THE ONLY TRUTH ABOUT SHORTCUTS. The drawer, `/keys` and the tests all
12
+ * derive from it, and `shortcut-table.test.ts` holds it in a BIDIRECTIONAL set
13
+ * relation with `HelpOverlay`'s key column (D-8). The reverse direction is the
14
+ * one that matters: without it `Alt+K`, `Esc twice` and `Esc again` could sit in
15
+ * `/help` forever and never appear in the panel whose entire requirement is
16
+ * "list ALL of them".
17
+ *
18
+ * `keyword` IS CAPPED AT 10 CELLS (`SHORTCUT_PANEL_LIMITS.keywordMaxCells`). A
19
+ * longer one is a spec error, not a width problem: at 80 columns the keyword
20
+ * column is 11 cells wide, and the only remaining remedy would be truncating it -
21
+ * which is the exact defect (a column of `promp...`) this table exists to avoid.
22
+ */
23
+ export type ShortcutGroupId = 'compose' | 'run' | 'panels' | 'session' | 'view';
24
+ /**
25
+ * When a row can actually be used. Unavailable rows are STILL LISTED - the user
26
+ * needs to know the key exists - but they render dim and explain themselves in
27
+ * the detail line when selected.
28
+ */
29
+ export type ShortcutAvailability = 'always' | 'idle' | 'running' | 'app' | 'native';
30
+ export interface ShortcutEntry {
31
+ /** Stable id used by tests and by `/keys <query>`. */
32
+ id: string;
33
+ /** The primary binding, spelled in full the way `HelpOverlay` spells it. */
34
+ keys: string;
35
+ /** One to two words, ASCII only, at most 10 columns. The requirement's second column. */
36
+ keyword: string;
37
+ /** One ASCII sentence, shown when the row is selected. */
38
+ detail: string;
39
+ group: ShortcutGroupId;
40
+ availability: ShortcutAvailability;
41
+ /** Extra spellings that must also resolve in `/keys <query>`. */
42
+ aliases?: readonly string[];
43
+ }
44
+ export declare const SHORTCUT_GROUPS: readonly {
45
+ id: ShortcutGroupId;
46
+ title: string;
47
+ }[];
48
+ /**
49
+ * The 31 rows, in reading order. Group order is fixed by `SHORTCUT_GROUPS`, and
50
+ * within a group the order is "how often a user reaches for it", not alphabetical:
51
+ * a reference panel is scanned from the top.
52
+ */
53
+ export declare const SHORTCUTS: readonly ShortcutEntry[];
54
+ /**
55
+ * The longest `keys` string in cells - the input the column derivation needs.
56
+ *
57
+ * DERIVED, NEVER HARD-CODED: v1 fixed the key column at 21 cells, which left six
58
+ * for the keyword at 80 columns and turned `prompt library` into `promp...`. A
59
+ * derived value cannot go stale the day someone adds a longer binding.
60
+ */
61
+ export declare function widestKeysCells(entries: readonly ShortcutEntry[]): number;
62
+ /**
63
+ * Filter for `/keys <query>`: case-insensitive substring over id, keys, keyword
64
+ * and aliases.
65
+ *
66
+ * NO KEYBOARD SEARCH IN THE PANEL ITSELF (§11 F-2): typing would fight `Esc` for
67
+ * "clear the filter or close the panel", and `Esc` is App-owned. The command is
68
+ * the zero-conflict way to reach the same filter.
69
+ */
70
+ export declare function filterShortcuts(entries: readonly ShortcutEntry[], query: string): ShortcutEntry[];
71
+ /**
72
+ * Whether a row can be used right now.
73
+ *
74
+ * `running` MEANS "ONLY WHILE RUNNING", not "unavailable while running" - the two
75
+ * halves of the table would otherwise need two different predicates, which is the
76
+ * kind of asymmetry a later reader gets backwards.
77
+ */
78
+ export declare function isAvailable(entry: ShortcutEntry, context: {
79
+ native: boolean;
80
+ running: boolean;
81
+ }): boolean;
@@ -0,0 +1,221 @@
1
+ /**
2
+ * THE shortcut table (tui-shortcut-drawer-and-task-summary §4.6 / appendix B).
3
+ *
4
+ * ASCII ONLY, AND THAT IS A HARD CONSTRAINT RATHER THAN A STYLE CHOICE: this file
5
+ * is inside `glyphs.test.ts::inScope` (`ui/` prefix), whose `A-1` case fails on a
6
+ * single non-ASCII byte. Every `keyword` and `detail` below is English on
7
+ * purpose; translating them would turn the scanner red, and the only escape
8
+ * hatch - adding this file to the exemptions - is the thing that helper's own
9
+ * comment argues against.
10
+ *
11
+ * THIS IS THE ONLY TRUTH ABOUT SHORTCUTS. The drawer, `/keys` and the tests all
12
+ * derive from it, and `shortcut-table.test.ts` holds it in a BIDIRECTIONAL set
13
+ * relation with `HelpOverlay`'s key column (D-8). The reverse direction is the
14
+ * one that matters: without it `Alt+K`, `Esc twice` and `Esc again` could sit in
15
+ * `/help` forever and never appear in the panel whose entire requirement is
16
+ * "list ALL of them".
17
+ *
18
+ * `keyword` IS CAPPED AT 10 CELLS (`SHORTCUT_PANEL_LIMITS.keywordMaxCells`). A
19
+ * longer one is a spec error, not a width problem: at 80 columns the keyword
20
+ * column is 11 cells wide, and the only remaining remedy would be truncating it -
21
+ * which is the exact defect (a column of `promp...`) this table exists to avoid.
22
+ */
23
+ import { cellWidth } from './layout/cells.js';
24
+ export const SHORTCUT_GROUPS = [
25
+ { id: 'compose', title: 'COMPOSE' },
26
+ { id: 'run', title: 'RUN' },
27
+ { id: 'panels', title: 'PANELS' },
28
+ { id: 'session', title: 'SESSION' },
29
+ { id: 'view', title: 'VIEW' },
30
+ ];
31
+ /**
32
+ * The 31 rows, in reading order. Group order is fixed by `SHORTCUT_GROUPS`, and
33
+ * within a group the order is "how often a user reaches for it", not alphabetical:
34
+ * a reference panel is scanned from the top.
35
+ */
36
+ export const SHORTCUTS = [
37
+ // --- COMPOSE ---------------------------------------------------------------
38
+ {
39
+ id: 'enter', keys: 'Enter', keyword: 'send', group: 'compose', availability: 'always',
40
+ detail: 'Submits when idle; queues as steering while running;'
41
+ + ' re-pins the view to the newest output.',
42
+ },
43
+ {
44
+ id: 'alt-enter', keys: 'Alt+Enter', keyword: 'newline', group: 'compose',
45
+ availability: 'always',
46
+ detail: 'Multiline input; the host may intercept this combination.',
47
+ },
48
+ {
49
+ id: 'shift-enter', keys: 'Shift+Enter', keyword: 'newline', group: 'compose',
50
+ availability: 'always',
51
+ detail: 'Needs keyboard enhancement; /terminal-setup explains how to bind it.',
52
+ },
53
+ {
54
+ id: 'ctrl-j', keys: 'Ctrl+J', keyword: 'newline', group: 'compose', availability: 'always',
55
+ detail: 'Newline fallback that does not depend on keyboard enhancement.',
56
+ },
57
+ {
58
+ id: 'history', keys: 'Up / Down', keyword: 'history', group: 'compose', availability: 'always',
59
+ detail: 'Recalls earlier prompts when the input box is empty.',
60
+ },
61
+ {
62
+ id: 'paste', keys: 'Paste', keyword: 'paste', group: 'compose', availability: 'always',
63
+ detail: 'Up to 6 lines inserted as-is; larger becomes [Pasted text #N]; --no-paste disables.',
64
+ },
65
+ {
66
+ id: 'ctrl-o', keys: 'Ctrl+O', keyword: 'expand', group: 'compose', availability: 'always',
67
+ detail: 'Expands the newest tool output; in native mode it reprints it as a new block.',
68
+ },
69
+ {
70
+ id: 'ctrl-c', keys: 'Ctrl+C', keyword: 'copy/exit', group: 'compose', availability: 'always',
71
+ aliases: ['Ctrl+C (with a selection)'],
72
+ detail: 'Copies a pending selection; with a draft x2 clears and x3 exits;'
73
+ + ' empty input x2 exits.',
74
+ },
75
+ // --- RUN -------------------------------------------------------------------
76
+ {
77
+ id: 'esc', keys: 'Esc', keyword: 'close', group: 'run', availability: 'always',
78
+ detail: 'Closes the open overlay or menu; with nothing open it arms the interrupt ladder.',
79
+ },
80
+ {
81
+ id: 'esc-twice', keys: 'Esc twice', keyword: 'interrupt', group: 'run', availability: 'running',
82
+ aliases: ['Esc again'],
83
+ detail: 'Requests an interrupt within 1.5s; the next press forces the stop.',
84
+ },
85
+ {
86
+ id: 'shift-tab', keys: 'Shift+Tab', keyword: 'plan mode', group: 'run', availability: 'always',
87
+ detail: 'Toggles BUILD and PLAN; writes are refused and the agent only investigates.',
88
+ },
89
+ {
90
+ id: 'ctrl-n', keys: 'Ctrl+N', keyword: 'plan mode', group: 'run', availability: 'always',
91
+ detail: 'The same toggle, for Windows consoles that cannot deliver Shift+Tab.',
92
+ },
93
+ {
94
+ id: 'ctrl-t', keys: 'Ctrl+T', keyword: 'thinking', group: 'run', availability: 'always',
95
+ detail: "Shows or hides the model's thinking (off by default).",
96
+ },
97
+ {
98
+ id: 'ctrl-r', keys: 'Ctrl+R', keyword: 'redraw', group: 'run', availability: 'always',
99
+ detail: 'Repaints the whole frame; use it when the terminal is garbled.',
100
+ },
101
+ // --- PANELS ----------------------------------------------------------------
102
+ {
103
+ id: 'ctrl-g', keys: 'Ctrl+G', keyword: 'all keys', group: 'panels', availability: 'always',
104
+ detail: 'Opens this panel; a second Ctrl+G closes it. Every shortcut is listed here.',
105
+ },
106
+ {
107
+ id: 'ctrl-b', keys: 'Ctrl+B', keyword: 'agents', group: 'panels', availability: 'always',
108
+ detail: 'Read-only subagent board: every child, its facts and its timeline.',
109
+ },
110
+ {
111
+ id: 'ctrl-p', keys: 'Ctrl+P', keyword: 'prompts', group: 'panels', availability: 'always',
112
+ detail: 'Quick prompt library: pick, edit, reorder.',
113
+ },
114
+ {
115
+ id: 'ctrl-k', keys: 'Ctrl+K', keyword: 'kits', group: 'panels', availability: 'always',
116
+ detail: 'Switch the main / fast / subagent model kit for this session.',
117
+ },
118
+ {
119
+ id: 'ctrl-i', keys: 'Ctrl+I', keyword: 'index', group: 'panels', availability: 'idle',
120
+ detail: 'Unavailable while running; asks first, then runs the project-indexer skill.',
121
+ },
122
+ {
123
+ id: 'alt-k', keys: 'Alt+K', keyword: 'kill line', group: 'panels', availability: 'always',
124
+ detail: 'Deletes from the cursor to the end of the line'
125
+ + ' (this was Ctrl+K before the kit picker).',
126
+ },
127
+ {
128
+ id: 'help', keys: '/help', keyword: 'reference', group: 'panels', availability: 'always',
129
+ detail: 'Full reference: keys, slash commands, plan mode, team, skills.',
130
+ },
131
+ // --- SESSION ---------------------------------------------------------------
132
+ {
133
+ id: 'ctrl-l', keys: 'Ctrl+L', keyword: 'branch', group: 'session', availability: 'always',
134
+ detail: 'Opens this session in a new terminal window with its own session id.',
135
+ },
136
+ {
137
+ id: 'clear', keys: '/clear', keyword: 'new task', group: 'session', availability: 'always',
138
+ detail: 'Archives the old conversation, clears the context;'
139
+ + ' the task summary is cleared with it.',
140
+ },
141
+ {
142
+ id: 'resume', keys: '/resume', keyword: 'switch', group: 'session', availability: 'always',
143
+ detail: 'Loads a saved session; the current session moves to a new id.',
144
+ },
145
+ {
146
+ id: 'session', keys: '/session', keyword: 'identity', group: 'session', availability: 'always',
147
+ detail: 'Shows the session id and file, copies the resume command, pins the id.',
148
+ },
149
+ // --- VIEW ------------------------------------------------------------------
150
+ {
151
+ id: 'page', keys: 'PgUp / PgDn', keyword: 'page', group: 'view', availability: 'always',
152
+ detail: 'Pages the transcript, or the overlay that currently owns the keyboard.',
153
+ },
154
+ {
155
+ id: 'wheel', keys: 'Wheel', keyword: 'scroll', group: 'view', availability: 'app',
156
+ detail: 'Scrolls the transcript in app mode; in native mode the terminal owns this.',
157
+ },
158
+ {
159
+ id: 'shift-wheel', keys: 'Shift+Wheel', keyword: 'page', group: 'view', availability: 'app',
160
+ detail: 'Scrolls a whole page.',
161
+ },
162
+ {
163
+ id: 'shift-arrows', keys: 'Shift+Up / Shift+Down', keyword: 'line', group: 'view',
164
+ availability: 'app',
165
+ detail: 'Scrolls one line; native mode leaves this to the terminal.',
166
+ },
167
+ {
168
+ id: 'drag-edge', keys: 'Drag right edge', keyword: 'scrollbar', group: 'view',
169
+ availability: 'app',
170
+ detail: 'Drags the right-edge scrollbar; the input stays fixed.',
171
+ },
172
+ {
173
+ id: 'drag-text', keys: 'Drag text (left button)', keyword: 'select', group: 'view',
174
+ availability: 'app',
175
+ detail: 'Drags to select on-screen text; the highlight waits for a copy.',
176
+ },
177
+ ];
178
+ /**
179
+ * The longest `keys` string in cells - the input the column derivation needs.
180
+ *
181
+ * DERIVED, NEVER HARD-CODED: v1 fixed the key column at 21 cells, which left six
182
+ * for the keyword at 80 columns and turned `prompt library` into `promp...`. A
183
+ * derived value cannot go stale the day someone adds a longer binding.
184
+ */
185
+ export function widestKeysCells(entries) {
186
+ return entries.reduce((widest, entry) => Math.max(widest, cellWidth(entry.keys)), 0);
187
+ }
188
+ /**
189
+ * Filter for `/keys <query>`: case-insensitive substring over id, keys, keyword
190
+ * and aliases.
191
+ *
192
+ * NO KEYBOARD SEARCH IN THE PANEL ITSELF (§11 F-2): typing would fight `Esc` for
193
+ * "clear the filter or close the panel", and `Esc` is App-owned. The command is
194
+ * the zero-conflict way to reach the same filter.
195
+ */
196
+ export function filterShortcuts(entries, query) {
197
+ const needle = query.trim().toLowerCase();
198
+ if (needle.length === 0)
199
+ return [...entries];
200
+ return entries.filter((entry) => {
201
+ const haystack = [entry.id, entry.keys, entry.keyword, ...(entry.aliases ?? [])];
202
+ return haystack.some((field) => field.toLowerCase().includes(needle));
203
+ });
204
+ }
205
+ /**
206
+ * Whether a row can be used right now.
207
+ *
208
+ * `running` MEANS "ONLY WHILE RUNNING", not "unavailable while running" - the two
209
+ * halves of the table would otherwise need two different predicates, which is the
210
+ * kind of asymmetry a later reader gets backwards.
211
+ */
212
+ export function isAvailable(entry, context) {
213
+ switch (entry.availability) {
214
+ case 'always': return true;
215
+ case 'idle': return !context.running;
216
+ case 'running': return context.running;
217
+ case 'app': return !context.native;
218
+ case 'native': return context.native;
219
+ default: return true;
220
+ }
221
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aragon-agent/cli",
3
- "version": "0.6.38",
3
+ "version": "0.6.40",
4
4
  "description": "AragonAgent CLI — a Claude-Code / Codex-style interactive terminal UI (TUI) on top of the @aragon-agent/core engine. Installable and runnable via npm / npx.",
5
5
  "license": "MIT",
6
6
  "author": "AragonAgent contributors",
@@ -56,7 +56,7 @@
56
56
  "prepublishOnly": "npm run build"
57
57
  },
58
58
  "dependencies": {
59
- "@aragon-agent/core": "^0.2.50",
59
+ "@aragon-agent/core": "^0.2.52",
60
60
  "chalk": "^5.6.2",
61
61
  "cli-highlight": "^2.0.0",
62
62
  "commander": "^12.1.0",