@aragon-agent/cli 0.6.40 → 0.6.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +2632 -2589
  2. package/README.md +3720 -3706
  3. package/dist/agent/controller.d.ts +36 -5
  4. package/dist/agent/controller.js +112 -33
  5. package/dist/agent/headless.js +6 -2
  6. package/dist/agent/system-prompt.d.ts +19 -0
  7. package/dist/agent/system-prompt.js +5 -0
  8. package/dist/commands/builtins.js +16 -182
  9. package/dist/commands/subagent-command.d.ts +21 -16
  10. package/dist/commands/subagent-command.js +22 -225
  11. package/dist/commands/team-command.d.ts +49 -0
  12. package/dist/commands/team-command.js +259 -0
  13. package/dist/config/model-kits.d.ts +2 -1
  14. package/dist/config/store.js +3 -2
  15. package/dist/exec/runner.js +2 -1
  16. package/dist/team/bus.d.ts +4 -0
  17. package/dist/team/bus.js +12 -2
  18. package/dist/team/comm-tools.js +3 -0
  19. package/dist/team/dispatch-gate.d.ts +86 -0
  20. package/dist/team/dispatch-gate.js +75 -0
  21. package/dist/team/forced-mode.d.ts +116 -0
  22. package/dist/team/forced-mode.js +156 -0
  23. package/dist/team/forced-prompt.d.ts +48 -0
  24. package/dist/team/forced-prompt.js +84 -0
  25. package/dist/team/limits.d.ts +41 -1
  26. package/dist/team/limits.js +49 -1
  27. package/dist/team/model.d.ts +22 -6
  28. package/dist/team/model.js +19 -5
  29. package/dist/team/overseer.d.ts +4 -0
  30. package/dist/team/overseer.js +38 -6
  31. package/dist/team/prompt.js +3 -3
  32. package/dist/team/report.d.ts +21 -0
  33. package/dist/team/report.js +40 -9
  34. package/dist/team/runtime.d.ts +3 -0
  35. package/dist/team/runtime.js +61 -5
  36. package/dist/team/subagent.js +25 -7
  37. package/dist/ui/App.js +140 -20
  38. package/dist/ui/StatusBar.d.ts +14 -0
  39. package/dist/ui/StatusBar.js +1 -0
  40. package/dist/ui/layout/status-layout.d.ts +17 -0
  41. package/dist/ui/layout/status-layout.js +9 -0
  42. package/dist/ui/overlays/HelpOverlay.js +8 -4
  43. package/dist/ui/overlays/SettingsScreen.d.ts +14 -0
  44. package/dist/ui/overlays/SettingsScreen.js +17 -7
  45. package/dist/ui/overlays/TeamFanoutPage.d.ts +17 -1
  46. package/dist/ui/overlays/TeamFanoutPage.js +23 -11
  47. package/dist/ui/overlays/kit-settings-state.js +3 -2
  48. package/dist/ui/overlays/model-profile-state.d.ts +1 -1
  49. package/dist/ui/overlays/team-fanout-state.d.ts +46 -13
  50. package/dist/ui/overlays/team-fanout-state.js +78 -20
  51. package/package.json +81 -81
@@ -1,10 +1,11 @@
1
1
  /**
2
- * Settings > Team fan-out: the pure half of the page (subagent-fanout 3.4.2).
2
+ * Settings > Team: the pure half of the page (subagent-fanout 3.4.2, extended by
3
+ * team-command-forced-dispatch §3.9).
3
4
  *
4
5
  * ASCII ONLY - `src/ui/**` is inside `glyphs.test.ts::inScope`.
5
6
  *
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' |
7
+ * THE PAGE WRITES FOUR KEYS AND CANNOT BE MADE TO WRITE A FIFTH (D-17 / R-P0-1).
8
+ * `TeamFanoutPatch` is `Pick<TeamConfig, 'enabled' | 'maxSubagents' |
8
9
  * 'maxConcurrent' | 'overseer'>`, and `stepFanoutValue` returns
9
10
  * `Partial<TeamFanoutPatch>`: a width adjustment therefore CANNOT carry `model`
10
11
  * or `modelProfileId` into `draft.patch.team`. That matters because
@@ -13,20 +14,26 @@
13
14
  * model a session kit had just installed - and no test would notice, because
14
15
  * every value on screen would still be right.
15
16
  *
17
+ * FOUR KEYS BECAUSE `enabled` MOVED HERE (team-command-forced-dispatch D-3): the
18
+ * team switch used to be reachable only as `/team on|off`, which also wrote
19
+ * `config.json`. The switch belongs on the same page as width, concurrency and
20
+ * supervision - they are four faces of one decision - and `/team` is now the ACT
21
+ * ("arm this session"), never a configuration write (I-4).
22
+ *
16
23
  * EVERYTHING HERE IS A PURE FUNCTION over the draft. The page owns exactly one
17
24
  * piece of state (its cursor); values come from the reducer, which is the same
18
25
  * discipline the rest of this screen follows.
19
26
  */
20
27
  import type { TeamConfig } from '../../config/schema.js';
21
28
  import type { ModelSettingsDraft } from '../../config/model-profile-store.js';
22
- export type TeamFanoutField = 'maxSubagents' | 'maxConcurrent' | 'overseer';
29
+ export type TeamFanoutField = 'enabled' | 'maxSubagents' | 'maxConcurrent' | 'overseer';
23
30
  /**
24
31
  * THE ONLY KEYS THIS PAGE MAY WRITE (R-P0-1).
25
32
  *
26
33
  * Not `Partial<TeamConfig>`: a fragment that could carry `model` would make a
27
34
  * width adjustment read as a model decision at save time.
28
35
  */
29
- export type TeamFanoutPatch = Pick<TeamConfig, 'maxSubagents' | 'maxConcurrent' | 'overseer'>;
36
+ export type TeamFanoutPatch = Pick<TeamConfig, 'enabled' | 'maxSubagents' | 'maxConcurrent' | 'overseer'>;
30
37
  export interface TeamFanoutRow {
31
38
  field: TeamFanoutField;
32
39
  label: string;
@@ -36,7 +43,7 @@ export interface TeamFanoutRow {
36
43
  hint: string;
37
44
  }
38
45
  export interface TeamFanoutView {
39
- /** Exactly three, in the fixed order the cursor indexes. */
46
+ /** Exactly four, in the fixed order the cursor indexes. */
40
47
  rows: TeamFanoutRow[];
41
48
  error?: string;
42
49
  }
@@ -58,16 +65,42 @@ export declare function teamFanoutValues(draft: ModelSettingsDraft): TeamConfig;
58
65
  *
59
66
  * NO WRAPAROUND: a form control is not a ring, and `Left` at 1 jumping to 10
60
67
  * would be a way to widen a dispatch while trying to narrow it.
68
+ *
69
+ * EVERY MEMBER IS HANDLED EXPLICITLY AND THE TAIL IS `never` (P0-1). The old
70
+ * body was three `if`s with the `maxSubagents` branch as the FALLTHROUGH, so
71
+ * adding `'enabled'` to the union compiled cleanly and made the new `Team mode`
72
+ * row adjust `Max subagents` instead - every number on screen self-consistent,
73
+ * no test red, and the user's intent to switch the team OFF arrived as a wider
74
+ * fan-out. The `never` assignment below turns that class of mistake into a
75
+ * compile error, which is the only place it can be caught cheaply.
61
76
  */
62
77
  export declare function stepFanoutValue(current: TeamConfig, field: TeamFanoutField, delta: -1 | 1): Partial<TeamFanoutPatch>;
63
78
  /**
64
- * The page's three rows.
79
+ * The page's four rows, in cursor order.
80
+ *
81
+ * `Team mode` IS FIRST because it is the premise of the other three: with `task`
82
+ * out of the tool list there is no width to configure and no supervisor to run,
83
+ * and a page that listed the numbers first would invite the user to tune a
84
+ * capability they had switched off.
65
85
  *
66
86
  * TWO HINTS CARRY A CONDITION THE DESIGN OWNS RATHER THAN DECORATION (R-1 / C-2):
67
- * the default pool is now 8, which is 8 simultaneous streams against one API key,
68
- * and the honest mitigation for an HTTP 429 storm is "lower this number" - said
69
- * HERE, where the number is, not only in a risk table nobody reads.
87
+ * the default pool is 8, which is 8 simultaneous streams against one API key, and
88
+ * the honest mitigation for an HTTP 429 storm is "lower this number" - said HERE,
89
+ * where the number is, not only in a risk table nobody reads.
90
+ *
91
+ * `teamRegistered === false` (a `--no-team` session) changes TWO things on the
92
+ * `enabled` row and nothing else: `on (next launch)` because the tool array is
93
+ * immutable (I-7), and a hint that says why. Absent means "not disclosed",
94
+ * which every existing fixture relies on.
95
+ */
96
+ export declare function fanoutRows(team: TeamConfig, teamRegistered?: boolean): TeamFanoutRow[];
97
+ /**
98
+ * The one-line summary the settings root row prints for this page.
99
+ *
100
+ * `off - no subagents` rather than the numbers, because with the capability off
101
+ * the numbers describe nothing the user can spend. This replaced
102
+ * `fanoutSummary()` outright instead of living beside it: two summary functions
103
+ * over one page is two authorities for one line, and the root row would sooner or
104
+ * later disagree with the page it summarises.
70
105
  */
71
- export declare function fanoutRows(team: TeamConfig): TeamFanoutRow[];
72
- /** The one-line summary the settings root row prints for this page. */
73
- export declare function fanoutSummary(team: TeamConfig): string;
106
+ export declare function teamSummary(team: TeamConfig): string;
@@ -1,10 +1,11 @@
1
1
  /**
2
- * Settings > Team fan-out: the pure half of the page (subagent-fanout 3.4.2).
2
+ * Settings > Team: the pure half of the page (subagent-fanout 3.4.2, extended by
3
+ * team-command-forced-dispatch §3.9).
3
4
  *
4
5
  * ASCII ONLY - `src/ui/**` is inside `glyphs.test.ts::inScope`.
5
6
  *
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' |
7
+ * THE PAGE WRITES FOUR KEYS AND CANNOT BE MADE TO WRITE A FIFTH (D-17 / R-P0-1).
8
+ * `TeamFanoutPatch` is `Pick<TeamConfig, 'enabled' | 'maxSubagents' |
8
9
  * 'maxConcurrent' | 'overseer'>`, and `stepFanoutValue` returns
9
10
  * `Partial<TeamFanoutPatch>`: a width adjustment therefore CANNOT carry `model`
10
11
  * or `modelProfileId` into `draft.patch.team`. That matters because
@@ -13,6 +14,12 @@
13
14
  * model a session kit had just installed - and no test would notice, because
14
15
  * every value on screen would still be right.
15
16
  *
17
+ * FOUR KEYS BECAUSE `enabled` MOVED HERE (team-command-forced-dispatch D-3): the
18
+ * team switch used to be reachable only as `/team on|off`, which also wrote
19
+ * `config.json`. The switch belongs on the same page as width, concurrency and
20
+ * supervision - they are four faces of one decision - and `/team` is now the ACT
21
+ * ("arm this session"), never a configuration write (I-4).
22
+ *
16
23
  * EVERYTHING HERE IS A PURE FUNCTION over the draft. The page owns exactly one
17
24
  * piece of state (its cursor); values come from the reducer, which is the same
18
25
  * discipline the rest of this screen follows.
@@ -41,36 +48,77 @@ export function teamFanoutValues(draft) {
41
48
  *
42
49
  * NO WRAPAROUND: a form control is not a ring, and `Left` at 1 jumping to 10
43
50
  * would be a way to widen a dispatch while trying to narrow it.
51
+ *
52
+ * EVERY MEMBER IS HANDLED EXPLICITLY AND THE TAIL IS `never` (P0-1). The old
53
+ * body was three `if`s with the `maxSubagents` branch as the FALLTHROUGH, so
54
+ * adding `'enabled'` to the union compiled cleanly and made the new `Team mode`
55
+ * row adjust `Max subagents` instead - every number on screen self-consistent,
56
+ * no test red, and the user's intent to switch the team OFF arrived as a wider
57
+ * fan-out. The `never` assignment below turns that class of mistake into a
58
+ * compile error, which is the only place it can be caught cheaply.
44
59
  */
45
60
  export function stepFanoutValue(current, field, delta) {
61
+ if (field === 'enabled') {
62
+ // Both arrows toggle: `Team mode` has two states, and a direction has no
63
+ // meaning beyond "the user pressed an arrow" (the `Supervisor` rule below).
64
+ return { enabled: !current.enabled };
65
+ }
46
66
  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
67
  return { overseer: !current.overseer };
50
68
  }
51
69
  if (field === 'maxConcurrent') {
52
70
  const ceiling = Math.min(HARD_MAX_SUBAGENTS, current.maxSubagents);
53
71
  return { maxConcurrent: clampInt(current.maxConcurrent + delta, 1, ceiling) };
54
72
  }
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 };
73
+ if (field === 'maxSubagents') {
74
+ const next = clampInt(current.maxSubagents + delta, 1, HARD_MAX_SUBAGENTS);
75
+ // THE FOLLOW-DOWN IS WRITTEN INTO THE PATCH (R-P1-9), not just rendered: a
76
+ // narrower population cannot keep a wider pool, but a DISPLAY-only correction
77
+ // would snap back the moment the user widened again, so "the change I just
78
+ // made" would not stick - the exact complaint this design exists to answer.
79
+ return current.maxConcurrent > next
80
+ ? { maxSubagents: next, maxConcurrent: next }
81
+ : { maxSubagents: next };
82
+ }
83
+ // THE EXHAUSTIVE GUARD IS THE POINT (P0-1): a new member of `TeamFanoutField`
84
+ // must fail to COMPILE here, not silently fall through to `maxSubagents`.
85
+ //
86
+ // IT SITS AFTER EVERY BRANCH RETURNS, not before the last one. §3.9's snippet
87
+ // shows it above the `maxSubagents` branch, where TypeScript rejects the file
88
+ // outright (`'maxSubagents' is not assignable to 'never'`) - the intent
89
+ // survives, the position does not.
90
+ const _exhaustive = field;
91
+ return _exhaustive;
63
92
  }
64
93
  /**
65
- * The page's three rows.
94
+ * The page's four rows, in cursor order.
95
+ *
96
+ * `Team mode` IS FIRST because it is the premise of the other three: with `task`
97
+ * out of the tool list there is no width to configure and no supervisor to run,
98
+ * and a page that listed the numbers first would invite the user to tune a
99
+ * capability they had switched off.
66
100
  *
67
101
  * 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.
102
+ * the default pool is 8, which is 8 simultaneous streams against one API key, and
103
+ * the honest mitigation for an HTTP 429 storm is "lower this number" - said HERE,
104
+ * where the number is, not only in a risk table nobody reads.
105
+ *
106
+ * `teamRegistered === false` (a `--no-team` session) changes TWO things on the
107
+ * `enabled` row and nothing else: `on (next launch)` because the tool array is
108
+ * immutable (I-7), and a hint that says why. Absent means "not disclosed",
109
+ * which every existing fixture relies on.
71
110
  */
72
- export function fanoutRows(team) {
111
+ export function fanoutRows(team, teamRegistered) {
112
+ const blocked = teamRegistered === false && team.enabled;
73
113
  return [
114
+ {
115
+ field: 'enabled',
116
+ label: 'Team mode',
117
+ value: blocked ? 'on (next launch)' : team.enabled ? 'on' : 'off',
118
+ hint: blocked
119
+ ? '--no-team session: the task tool cannot be added live'
120
+ : 'off: no task tool next launch; this session may lack it',
121
+ },
74
122
  {
75
123
  field: 'maxSubagents',
76
124
  label: 'Max subagents',
@@ -91,7 +139,17 @@ export function fanoutRows(team) {
91
139
  },
92
140
  ];
93
141
  }
94
- /** The one-line summary the settings root row prints for this page. */
95
- export function fanoutSummary(team) {
142
+ /**
143
+ * The one-line summary the settings root row prints for this page.
144
+ *
145
+ * `off - no subagents` rather than the numbers, because with the capability off
146
+ * the numbers describe nothing the user can spend. This replaced
147
+ * `fanoutSummary()` outright instead of living beside it: two summary functions
148
+ * over one page is two authorities for one line, and the root row would sooner or
149
+ * later disagree with the page it summarises.
150
+ */
151
+ export function teamSummary(team) {
152
+ if (!team.enabled)
153
+ return 'off - no subagents';
96
154
  return `${team.maxSubagents} per dispatch, ${team.maxConcurrent} at once`;
97
155
  }
package/package.json CHANGED
@@ -1,81 +1,81 @@
1
- {
2
- "name": "@aragon-agent/cli",
3
- "version": "0.6.40",
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
- "license": "MIT",
6
- "author": "AragonAgent contributors",
7
- "keywords": [
8
- "agent",
9
- "ai-agent",
10
- "llm",
11
- "cli",
12
- "tui",
13
- "terminal",
14
- "ink",
15
- "anthropic",
16
- "openai",
17
- "google",
18
- "aragonagent",
19
- "exec",
20
- "headless",
21
- "automation",
22
- "ci"
23
- ],
24
- "repository": {
25
- "type": "git",
26
- "url": "git+https://github.com/xdrshjr/AragonAgent.git",
27
- "directory": "packages/cli"
28
- },
29
- "homepage": "https://github.com/xdrshjr/AragonAgent#readme",
30
- "bugs": {
31
- "url": "https://github.com/xdrshjr/AragonAgent/issues"
32
- },
33
- "type": "module",
34
- "bin": {
35
- "aragon": "./dist/launcher.js"
36
- },
37
- "files": [
38
- "dist",
39
- "runtime",
40
- "skills",
41
- "README.md",
42
- "CHANGELOG.md"
43
- ],
44
- "engines": {
45
- "node": ">=18"
46
- },
47
- "publishConfig": {
48
- "access": "public"
49
- },
50
- "scripts": {
51
- "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json && node scripts/prepend-shebang.mjs",
52
- "dev": "tsc -p tsconfig.json --watch",
53
- "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit",
54
- "test": "vitest run",
55
- "start": "node dist/cli.js",
56
- "prepublishOnly": "npm run build"
57
- },
58
- "dependencies": {
59
- "@aragon-agent/core": "^0.2.52",
60
- "chalk": "^5.6.2",
61
- "cli-highlight": "^2.0.0",
62
- "commander": "^12.1.0",
63
- "dotenv": "^16.6.1",
64
- "env-paths": "^3.0.0",
65
- "fflate": "^0.8.3",
66
- "ink": "^5.0.1",
67
- "ink-select-input": "^6.0.0",
68
- "ink-spinner": "^5.0.0",
69
- "react": "^18.3.1",
70
- "string-width": "^7.2.0",
71
- "strip-ansi": "^7.1.0",
72
- "tinyglobby": "^0.2.17"
73
- },
74
- "devDependencies": {
75
- "@types/node": "^22.0.0",
76
- "@types/react": "^18.3.0",
77
- "ink-testing-library": "^4.0.0",
78
- "typescript": "^5.9.3",
79
- "vitest": "4.1.9"
80
- }
81
- }
1
+ {
2
+ "name": "@aragon-agent/cli",
3
+ "version": "0.6.43",
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
+ "license": "MIT",
6
+ "author": "AragonAgent contributors",
7
+ "keywords": [
8
+ "agent",
9
+ "ai-agent",
10
+ "llm",
11
+ "cli",
12
+ "tui",
13
+ "terminal",
14
+ "ink",
15
+ "anthropic",
16
+ "openai",
17
+ "google",
18
+ "aragonagent",
19
+ "exec",
20
+ "headless",
21
+ "automation",
22
+ "ci"
23
+ ],
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/xdrshjr/AragonAgent.git",
27
+ "directory": "packages/cli"
28
+ },
29
+ "homepage": "https://github.com/xdrshjr/AragonAgent#readme",
30
+ "bugs": {
31
+ "url": "https://github.com/xdrshjr/AragonAgent/issues"
32
+ },
33
+ "type": "module",
34
+ "bin": {
35
+ "aragon": "./dist/launcher.js"
36
+ },
37
+ "files": [
38
+ "dist",
39
+ "runtime",
40
+ "skills",
41
+ "README.md",
42
+ "CHANGELOG.md"
43
+ ],
44
+ "engines": {
45
+ "node": ">=18"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public"
49
+ },
50
+ "scripts": {
51
+ "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json && node scripts/prepend-shebang.mjs",
52
+ "dev": "tsc -p tsconfig.json --watch",
53
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit",
54
+ "test": "vitest run",
55
+ "start": "node dist/cli.js",
56
+ "prepublishOnly": "npm run build"
57
+ },
58
+ "dependencies": {
59
+ "@aragon-agent/core": "^0.2.55",
60
+ "chalk": "^5.6.2",
61
+ "cli-highlight": "^2.0.0",
62
+ "commander": "^12.1.0",
63
+ "dotenv": "^16.6.1",
64
+ "env-paths": "^3.0.0",
65
+ "fflate": "^0.8.3",
66
+ "ink": "^5.0.1",
67
+ "ink-select-input": "^6.0.0",
68
+ "ink-spinner": "^5.0.0",
69
+ "react": "^18.3.1",
70
+ "string-width": "^7.2.0",
71
+ "strip-ansi": "^7.1.0",
72
+ "tinyglobby": "^0.2.17"
73
+ },
74
+ "devDependencies": {
75
+ "@types/node": "^22.0.0",
76
+ "@types/react": "^18.3.0",
77
+ "ink-testing-library": "^4.0.0",
78
+ "typescript": "^5.9.3",
79
+ "vitest": "4.1.9"
80
+ }
81
+ }