aegiscode 6.1.0 → 6.2.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/README.md +121 -78
- package/bin/aegiscode.js +9 -1
- package/package.json +3 -3
- package/scripts/predist.mjs +11 -1
- package/src/agents.js +136 -0
- package/src/app.js +522 -164
- package/src/chatflow.js +1475 -0
- package/src/checkpoint.js +85 -0
- package/src/clipboard.js +62 -0
- package/src/commands.js +1234 -150
- package/src/config.js +163 -0
- package/src/deps.js +14 -1
- package/src/devrun.js +110 -0
- package/src/engine.js +62 -0
- package/src/events.js +278 -0
- package/src/export.js +64 -0
- package/src/history.js +201 -0
- package/src/init.js +162 -0
- package/src/input.js +136 -0
- package/src/keys.js +141 -0
- package/src/panels.js +1171 -0
- package/src/permissions.js +102 -0
- package/src/render.js +33 -1
- package/src/summarize.js +90 -0
- package/src/system.js +37 -0
- package/src/tokens.js +166 -0
- package/vendor/desktop/lib/local/agents.js +102 -0
- package/vendor/desktop/lib/local/engine.js +972 -0
- package/vendor/desktop/lib/local/prompt.js +91 -0
- package/vendor/desktop/lib/local/shell.js +208 -0
- package/vendor/desktop/lib/local/tools.js +882 -0
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ an editor — built on the same two shared pieces and no others:
|
|
|
9
9
|
| `client/aegis.js` | The thin transport. Holds the API key, speaks HTTP/SSE. No brain logic. |
|
|
10
10
|
| `mcp/tools.js` | The tool registry — names, JSON schemas, result formatting. |
|
|
11
11
|
| `desktop/renderer/usage.js` | The token-usage → number mapping, shared with the GUI so the two can never disagree. |
|
|
12
|
+
| `desktop/lib/local/` | The agent-loop engine — persistent-shell exec, read/write/edit/glob/grep, Task subagents. The CLI runs the same loop the GUI does, scoped to the AEGIS class. |
|
|
12
13
|
|
|
13
14
|
Routing, model tiers, memory and billing all stay behind aegiscloud.org.
|
|
14
15
|
|
|
@@ -53,64 +54,46 @@ echo "q" | aegiscode -p - # prompt on stdin
|
|
|
53
54
|
aegiscode -m deepseek/deepseek-v4-flash -p "..." # pin a model
|
|
54
55
|
```
|
|
55
56
|
|
|
56
|
-
In a session, plain text is a prompt. `/help` lists commands
|
|
57
|
+
In a session, plain text is a prompt. `/help` lists commands, grouped by
|
|
58
|
+
category, the way `aegiscodex-dev` does. The registry is that client's, ported
|
|
59
|
+
command for command — 75 entries across nine categories:
|
|
57
60
|
|
|
58
|
-
|
|
|
61
|
+
| Category | Commands |
|
|
59
62
|
|---|---|
|
|
60
|
-
|
|
|
61
|
-
| `/
|
|
62
|
-
| `/
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
| `/
|
|
66
|
-
| `/
|
|
67
|
-
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
##
|
|
63
|
+
| Session & context | `/clear` `/compact` `/cost` `/exit` `/new` `/recap` `/resume` `/rewind` `/agents` `/status` `/teleport` `/version` `/clone` `/schedule` |
|
|
64
|
+
| Workspace | `/run` `/build` `/cd` `/copy` `/init` `/review` `/prs` |
|
|
65
|
+
| Model & behavior | `/model` `/effort` `/thinking` `/theme` `/vim` `/router` `/confirm` `/yolo` `/permissions` `/hooks` `/skills` `/mcp` |
|
|
66
|
+
| Data | `/context` `/export` `/tokens` |
|
|
67
|
+
| Auth | `/credentials` `/byok` `/byok-set` `/byok-rm` |
|
|
68
|
+
| Support | `/help` `/doctor` `/troubleshooting` `/feedback` `/bug` `/issue` `/onboarding` `/benchmark` `/release-notes` `/billing` `/cloud` |
|
|
69
|
+
| Aegis plugin | `/aegis-ask` `/aegis-status` `/aegis-recall` `/aegis-remember` `/memory` `/aegis-council` `/aegis-multi` `/aegis-print` `/aegis-import` `/tool` |
|
|
70
|
+
| Fun | `/radio` `/waifu` |
|
|
71
|
+
|
|
72
|
+
`/help` shows the live list with hints; aliases are searchable in the `/`
|
|
73
|
+
palette exactly as they are there (`/ask` → `/aegis-ask`, `?` → `/help`,
|
|
74
|
+
`quit` → `/exit`, `tok` → `/tokens`, …).
|
|
75
|
+
|
|
76
|
+
Every command that talks to AEGIS names a tool from `mcp/tools.js`, and the test
|
|
77
|
+
suite asserts both directions: no command points at a tool that does not exist,
|
|
78
|
+
and no tool is unreachable from the prompt. Everything else is a real local
|
|
79
|
+
handler — `/run` detects and drives this project's dev command, `/init` sniffs
|
|
80
|
+
the project and writes `AEGIS.md`, `/export` writes the transcript out,
|
|
81
|
+
`/resume` and `/rewind` read the session store, `/cd` moves the working
|
|
82
|
+
directory, `/doctor` runs diagnostics.
|
|
83
|
+
|
|
84
|
+
The only two commands that answer "not available" are `/login` and `/logout`:
|
|
85
|
+
their whole premise is Claude Code's own auth loop, which this client does not
|
|
86
|
+
participate in — it authenticates with an AEGIS key (or your own provider key
|
|
87
|
+
via `/byok-set`). They say so, and point at the working alternative.
|
|
88
|
+
|
|
89
|
+
## The chatflow
|
|
90
|
+
|
|
91
|
+
The session is `aegiscodex-dev`'s loop, ported rather than approximated: an
|
|
92
|
+
alternate-screen frame of header rule, transcript viewport, spinner/effort line,
|
|
93
|
+
input line and status line, driven by a raw key stream.
|
|
87
94
|
|
|
88
95
|
```
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
✦ █████▓▓░ ▓▓▓▓▓▓▓▓▓ ✦ ▒▒▒▒▒▒▒▒▒▒▒▒
|
|
92
|
-
✦ ███▓░ ░░ ▓▓▓▓▓▓▓░░░ ▒▒▒▒▒▒▒▒▒▒▒▒▒
|
|
93
|
-
░░░░ ███▓░ ▓▓▓▓░░░░░░ ██▒▒▒▒▒▒▒▒▒▒▒▒▓▓
|
|
94
|
-
░░░░░░░░ ███▓░ ░░░░░░ ██▒▒▒▒▒▒▒▒▒▒▒▒▓
|
|
95
|
-
░░░░░░░░░░░░ ███▓░ ✦ · · ▒▒▒▒▒▒▒▒▒▒▒▒▒▒
|
|
96
|
-
██▓░░ ▓ ░░░░░░░░░░░░
|
|
97
|
-
░▓▓███▓▓░
|
|
98
|
-
▐▛███▜▌
|
|
99
|
-
▝▜█████▛▘
|
|
100
|
-
▘▘ ▝▝
|
|
101
|
-
|
|
102
|
-
Welcome to AEGIS Code
|
|
103
|
-
v6.1.0 · Cloud brain in your shell.
|
|
104
|
-
|
|
105
|
-
───────────────────────────────── aegiscode ──────────────────────────────────
|
|
106
|
-
version v6.1.0
|
|
107
|
-
model nexus-brain
|
|
108
|
-
base https://aegiscloud.org
|
|
109
|
-
key aegis_••••4f2a
|
|
110
|
-
render streaming
|
|
111
|
-
|
|
112
|
-
type /help for commands · /quit to exit
|
|
113
|
-
|
|
96
|
+
╭───────────────────────────── AEGIS Code v6.2.0 ─────────────────────────────╮
|
|
114
97
|
❯ summarise what changed in the token accounting
|
|
115
98
|
● Three things changed, and one of them was costing you money:
|
|
116
99
|
|
|
@@ -118,16 +101,51 @@ pretending to work.
|
|
|
118
101
|
- cache reads and writes are billed, not ignored
|
|
119
102
|
- a zero-token call no longer refunds its reservation
|
|
120
103
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
⎿ nexus-brain · 1,562 tok · 1,250/312 · €0.0007 · 4.2s
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
104
|
+
● Running 1 shell command…
|
|
105
|
+
⎿ $ git log --oneline -3
|
|
106
|
+
Ran 1 shell command
|
|
107
|
+
✻ Worked for 6s
|
|
108
|
+
⎿ nexus-brain · 1,562 tok · 1,250/312 · €0.0007 · 4.2s
|
|
109
|
+
● high · /effort
|
|
110
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
111
|
+
❯ Try "edit <filepath> to..."
|
|
112
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
113
|
+
⏸ manual mode on · ? for shortcuts · ← for agents
|
|
129
114
|
```
|
|
130
115
|
|
|
116
|
+
What the loop does, in the order a turn happens:
|
|
117
|
+
|
|
118
|
+
- **You type.** The input line has history (`↑`/`↓`), tab completion for `/…`,
|
|
119
|
+
word motions, a rotating suggestion when empty, horizontal scrolling for a
|
|
120
|
+
long line, and a collapsed one-line preview for a multi-line paste (the full
|
|
121
|
+
text is still what gets submitted).
|
|
122
|
+
- **The turn starts.** A random verb from the reference set shimmers in coral
|
|
123
|
+
beside the spinner, with elapsed time and a live token estimate.
|
|
124
|
+
- **The answer streams into a row**, markdown-rendered, opening with `●` and
|
|
125
|
+
trailing a live cursor while it grows.
|
|
126
|
+
- **Tool calls become rows.** `● Running 1 shell command… · 3s` resolves to
|
|
127
|
+
`Ran 1 shell command` when the call returns — paired by tool-call id, so
|
|
128
|
+
parallel same-name calls and nested subagent rows stay separate, and the
|
|
129
|
+
plural is right.
|
|
130
|
+
- **The turn ends** with `✻ Churned for Ns` (no tools) or `✻ Worked for Ns`
|
|
131
|
+
(tools), then an accounting row: `⎿ nexus-brain · 1,562 tok · 1,250/312 ·
|
|
132
|
+
€0.0007 · 4.2s`.
|
|
133
|
+
- **Esc interrupts.** The abort reaches the transport through an
|
|
134
|
+
`AbortSignal`, so the in-flight provider call is genuinely cancelled — it
|
|
135
|
+
does not keep running and billing behind a "stopped" label — and whatever had
|
|
136
|
+
already streamed is kept, marked `(stopped)`.
|
|
137
|
+
- **Keys work mid-turn.** Esc/Ctrl-C abort; PgUp/PgDn and the wheel scroll the
|
|
138
|
+
transcript live (and scrolling up is anchored to an absolute line index, so an
|
|
139
|
+
arriving delta does not drag the reader back to the bottom); everything else
|
|
140
|
+
you type is replayed into the input line afterwards.
|
|
141
|
+
- **Overlays**: `/` the palette, `alt+p` the model picker, `/effort` the effort
|
|
142
|
+
picker, `/resume` the session list, `?` the shortcut grid, and a centred
|
|
143
|
+
Yes/No dialog when a mutating tool needs approval.
|
|
144
|
+
|
|
145
|
+
Anything that is not a real terminal — a pipe, `-p`, a CI run — stays a linear
|
|
146
|
+
transcript written once to scrollback, so output remains pipeable and
|
|
147
|
+
scriptable.
|
|
148
|
+
|
|
131
149
|
Render it yourself, with no key and no network:
|
|
132
150
|
|
|
133
151
|
```bash
|
|
@@ -147,31 +165,56 @@ and art row to that source so the two hosts cannot drift apart. (An earlier
|
|
|
147
165
|
revision of this CLI was a deliberate divergence — a violet/cyan "Signal" theme
|
|
148
166
|
with a test asserting it. That direction is gone.)
|
|
149
167
|
|
|
150
|
-
**A
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
168
|
+
**A full-screen chatflow on a terminal, a linear transcript everywhere else.**
|
|
169
|
+
On a TTY the session is the reference's loop: alternate screen, header rule,
|
|
170
|
+
transcript viewport, spinner, effort line, input line, status line, overlays.
|
|
171
|
+
Anywhere else — a pipe, `-p`, CI — turns are written once to the scrollback
|
|
172
|
+
instead, so output stays selectable, searchable and pipeable. A tool you script
|
|
173
|
+
should not become un-scriptable because the interactive mode got nicer.
|
|
174
|
+
|
|
175
|
+
**The command registry is `aegiscodex-dev`'s, ported.** Names, aliases,
|
|
176
|
+
categories, the palette grouping and the handlers themselves come from it, with
|
|
177
|
+
`test/cli-commands.test.mjs` asserting the full name list so a silent drop
|
|
178
|
+
fails the build. Local capability that the reference has — a dev-server runner,
|
|
179
|
+
project sniffing, an export path, a session store, checkpoints, permission
|
|
180
|
+
rules, subagent presets — was ported with it rather than stubbed.
|
|
154
181
|
|
|
155
182
|
**Tokens beside money, always.** A turn prints what it consumed and what it
|
|
156
183
|
settled at, in the same line: `1,562 tok ∙ 1,250/312 ∙ €0.0007`. Sub-cent
|
|
157
184
|
amounts keep four decimals, because a €0.0007 call rendered at 2dp reads as
|
|
158
185
|
free usage next to a token count.
|
|
159
186
|
|
|
187
|
+
**Esc really stops the call.** The interrupt travels as an `AbortSignal` into
|
|
188
|
+
the transport, and the engine does not re-dispatch after an abort — a cancelled
|
|
189
|
+
turn used to fire a second billed provider request ("the model said nothing"
|
|
190
|
+
recovery, triggered by the empty result an abort produces) and stream the
|
|
191
|
+
partial answer twice. `test/local-engine.test.mjs` pins the dispatch count.
|
|
192
|
+
|
|
160
193
|
## Tests
|
|
161
194
|
|
|
162
195
|
```bash
|
|
163
|
-
node
|
|
164
|
-
node
|
|
165
|
-
node
|
|
166
|
-
node
|
|
167
|
-
node
|
|
168
|
-
node
|
|
169
|
-
node
|
|
170
|
-
node
|
|
196
|
+
node ../test/cli-chatflow.test.mjs # the session loop, driven with a synthetic key stream
|
|
197
|
+
node ../test/cli-commands.test.mjs # the full command table, aliases, dispatch contract
|
|
198
|
+
node ../test/cli-panels.test.mjs # every panel builder, defensive against missing data
|
|
199
|
+
node ../test/cli-support.test.mjs # config/history/tokens/agents/export/checkpoints
|
|
200
|
+
node ../test/cli-conformance.test.mjs # the design guard: palette, glyphs, art, verbs
|
|
201
|
+
node ../test/cli-render.test.mjs # width safety, accounting, live region
|
|
202
|
+
node ../test/cli-overlays.test.mjs # the / palette, model + effort pickers, resume list
|
|
203
|
+
node ../test/cli-fuzzy.test.mjs # palette ranking and match positions
|
|
204
|
+
node ../test/cli-markdown.test.mjs # span-line markdown, cell widths
|
|
205
|
+
node ../test/cli-tools.test.mjs # registry parity with the MCP host + dispatch
|
|
206
|
+
node ../test/cli-run.test.mjs # the real binary against a real backend
|
|
207
|
+
node ../test/cli-package.test.mjs # the published layout, isolated from the repo
|
|
171
208
|
npm test # all of the above
|
|
172
209
|
```
|
|
173
210
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
211
|
+
The chatflow test drives `runSession` for real: a synthetic key stream, stdout
|
|
212
|
+
captured, and the app entered exactly as `bin/aegiscode.js` enters it. It covers
|
|
213
|
+
the turn lifecycle, tool-row pairing, the interrupt reaching the transport, the
|
|
214
|
+
viewport anchor, the input line's cell maths and an abort that must not
|
|
215
|
+
re-dispatch.
|
|
216
|
+
|
|
217
|
+
`npm run predist` stages `client/`, `mcp/tools.js` and the desktop's `usage.js`,
|
|
218
|
+
`local/engine.js` and `local/agents.js` into `cli/vendor/` (gitignored) so the
|
|
219
|
+
published package resolves its own modules. `test/cli-package.test.mjs` copies
|
|
220
|
+
that tree somewhere with no repo around it and runs the binary there.
|
package/bin/aegiscode.js
CHANGED
|
@@ -33,11 +33,14 @@ Options:
|
|
|
33
33
|
--max-tokens <n> output ceiling hint
|
|
34
34
|
--light light theme
|
|
35
35
|
--width <cols> force a render width (useful for piping/logs)
|
|
36
|
+
--yolo skip tool-approval prompts (exec/writeFile/editFile
|
|
37
|
+
run without asking) — same as the in-session /yolo
|
|
36
38
|
-h, --help this text
|
|
37
39
|
-v, --version print the version
|
|
38
40
|
|
|
39
41
|
In-session: type /help for commands, /quit to exit, esc/ctrl+c to interrupt a
|
|
40
|
-
running call. Plain text is a prompt (identical to /ask)
|
|
42
|
+
running call. Plain text is a prompt (identical to /ask) — a question that
|
|
43
|
+
needs a file read, a shell command, or an edit is handled the same turn.
|
|
41
44
|
`;
|
|
42
45
|
|
|
43
46
|
function parseArgs(argv) {
|
|
@@ -50,6 +53,7 @@ function parseArgs(argv) {
|
|
|
50
53
|
maxTokens: undefined,
|
|
51
54
|
light: false,
|
|
52
55
|
width: null,
|
|
56
|
+
yolo: false,
|
|
53
57
|
prompt: null,
|
|
54
58
|
help: false,
|
|
55
59
|
version: false,
|
|
@@ -102,6 +106,9 @@ function parseArgs(argv) {
|
|
|
102
106
|
case '--light':
|
|
103
107
|
opts.light = true;
|
|
104
108
|
break;
|
|
109
|
+
case '--yolo':
|
|
110
|
+
opts.yolo = true;
|
|
111
|
+
break;
|
|
105
112
|
case '--width':
|
|
106
113
|
opts.width = Number(next());
|
|
107
114
|
break;
|
|
@@ -172,6 +179,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
172
179
|
maxTokens: opts.maxTokens,
|
|
173
180
|
width: opts.width ? () => opts.width : undefined,
|
|
174
181
|
interactive: !prompt && Boolean(process.stdin.isTTY),
|
|
182
|
+
confirmMode: !opts.yolo,
|
|
175
183
|
});
|
|
176
184
|
|
|
177
185
|
if (prompt) return app.runOnce(prompt, { json: opts.json });
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aegiscode",
|
|
3
3
|
"productName": "AEGIS Code",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.2.0",
|
|
5
5
|
"description": "aegiscode — the command-line version of AEGIS Desktop. The shared tool surface in your shell, over the same thin transport and tool registry as the MCP plugin and the desktop app. Ships transport + UI only; no brain.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "AEGIS Code",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"start": "node bin/aegiscode.js",
|
|
32
32
|
"predist": "node scripts/predist.mjs",
|
|
33
33
|
"prepublishOnly": "npm run predist",
|
|
34
|
-
"check": "node --check bin/aegiscode.js &&
|
|
35
|
-
"test": "for f in
|
|
34
|
+
"check": "node --check bin/aegiscode.js && for f in src/*.js; do node --check \"$f\" || exit 1; done && node --check scripts/predist.mjs",
|
|
35
|
+
"test": "for f in ../test/cli-*.test.mjs; do node \"$f\" || exit 1; done"
|
|
36
36
|
},
|
|
37
37
|
"keywords": [
|
|
38
38
|
"aegis",
|
package/scripts/predist.mjs
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* cli/ repo/
|
|
12
12
|
* vendor/mcp/tools.js ≡ mcp/tools.js
|
|
13
13
|
* vendor/client/*.js ≡ client/*.js
|
|
14
|
-
* vendor/desktop/... ≡ desktop/renderer/usage.js
|
|
14
|
+
* vendor/desktop/... ≡ desktop/renderer/usage.js,
|
|
15
|
+
* desktop/lib/local/{engine,tools,shell,agents,prompt}.js
|
|
15
16
|
*
|
|
16
17
|
* The shape matters: `mcp/tools.js` requires `../client/foreign-memory.js`, and
|
|
17
18
|
* because the staged tree mirrors the repo, that path resolves *inside* the
|
|
@@ -39,6 +40,15 @@ const FILES = [
|
|
|
39
40
|
'client/foreign-memory.js',
|
|
40
41
|
'mcp/tools.js',
|
|
41
42
|
'desktop/renderer/usage.js',
|
|
43
|
+
// The agent-loop engine (persistent shell, editFile/grep/exec, Task
|
|
44
|
+
// subagents) the desktop app already ships (desktop/lib/local/). The CLI
|
|
45
|
+
// reuses it as-is, scoped to the 'aegis' class only (see src/engine.js) —
|
|
46
|
+
// one tool loop implementation, not a second one drifting alongside it.
|
|
47
|
+
'desktop/lib/local/engine.js',
|
|
48
|
+
'desktop/lib/local/tools.js',
|
|
49
|
+
'desktop/lib/local/shell.js',
|
|
50
|
+
'desktop/lib/local/agents.js',
|
|
51
|
+
'desktop/lib/local/prompt.js',
|
|
42
52
|
];
|
|
43
53
|
|
|
44
54
|
function main() {
|
package/src/agents.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sub-agent prompt presets — ported verbatim from aegiscodex-dev/src/agents.js
|
|
5
|
+
* (which in turn came from the reference's slash-commands builtinCommands.ts
|
|
6
|
+
* buildMultiAgents() and the research-council member prompts). This build has
|
|
7
|
+
* no parallel-agent runtime, so the presets are prompt composition:
|
|
8
|
+
* /agents <role> <task> and /research <question> build the same specialist
|
|
9
|
+
* prompts the reference hands to real sub-agents and run them through the
|
|
10
|
+
* normal chat flow (c.runPrompt).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** Role → system prompt, verbatim from the reference's buildMultiAgents. */
|
|
14
|
+
const AGENT_PRESETS = {
|
|
15
|
+
synthesizer: `You are a senior technical lead. Given analysis from multiple specialist agents, synthesize their findings into a clear, actionable summary.
|
|
16
|
+
Structure your response as: key findings, recommended approach, top action items.
|
|
17
|
+
Be direct, concrete, and avoid repeating everything the agents said.
|
|
18
|
+
Focus on delivering a decision-ready synthesis.`,
|
|
19
|
+
|
|
20
|
+
architect: `You are a System Architect. Design the new application architecture.
|
|
21
|
+
Define: project structure, tech stack, directory layout, key modules, data flow, API design.
|
|
22
|
+
Consider: scalability, maintainability, testing strategy, deployment.
|
|
23
|
+
Output a concrete file tree and architecture decisions log. Be specific.`,
|
|
24
|
+
|
|
25
|
+
scaffolder: `You are a Project Scaffolder. Build the complete application from scratch.
|
|
26
|
+
|
|
27
|
+
YOUR JOB IS TO CREATE ALL PROJECT FILES - not just describe them.
|
|
28
|
+
|
|
29
|
+
Use Write to create: package.json, tsconfig.json, source files, configs, tests.
|
|
30
|
+
Generate COMPLETE, WORKING code - not stubs or placeholders.
|
|
31
|
+
Set up build scripts, lint config, and any necessary tooling.
|
|
32
|
+
|
|
33
|
+
After creating files, use Bash to run: npm/pnpm install, then build/compile.
|
|
34
|
+
Fix any errors until the project builds successfully.
|
|
35
|
+
|
|
36
|
+
Be thorough - a real, runnable project is the goal.`,
|
|
37
|
+
|
|
38
|
+
planner: `You are a Refactoring Planner. Given the analyzer findings, create a step-by-step plan.
|
|
39
|
+
Each step: file path, what to change, why, risk level (LOW/MEDIUM/HIGH).
|
|
40
|
+
Include before/after snippets. Order by impact. Be concrete.`,
|
|
41
|
+
|
|
42
|
+
implementer: `You are an Implementation Engineer. Execute the refactoring plan.
|
|
43
|
+
Use Edit and Write to make actual code changes.
|
|
44
|
+
After each change, use Read to verify correctness. Keep existing code style.
|
|
45
|
+
Run build commands to ensure nothing is broken.`,
|
|
46
|
+
|
|
47
|
+
reviewer: `You are a Code Reviewer. Review the approach and code.
|
|
48
|
+
Check: logic errors, type safety, error handling, performance, security.
|
|
49
|
+
Be critical but constructive. Report specific issues with file paths.`,
|
|
50
|
+
|
|
51
|
+
debugger: `You are a Debugging Specialist. Analyze potential issues and edge cases.
|
|
52
|
+
Identify: failure modes, error handling gaps, testing considerations.
|
|
53
|
+
Think about what could go wrong and how to prevent it.`,
|
|
54
|
+
|
|
55
|
+
scanner: `You are a Security Vulnerability Scanner.
|
|
56
|
+
Scan for: hardcoded API keys/secrets, SQL injection, XSS, unsafe eval/exec, path traversal.
|
|
57
|
+
Use Grep with targeted patterns. Report every finding with: file path, severity (CRITICAL/HIGH/MEDIUM/LOW), line number.`,
|
|
58
|
+
|
|
59
|
+
analyzer: `You are a Code Analyzer. Find refactoring opportunities.
|
|
60
|
+
Look for: duplicated code, long functions (>20 lines), complex conditionals, unused imports,
|
|
61
|
+
circular dependencies, inconsistent patterns. Report with file paths and line numbers.`,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/** Human-readable role label for a preset id (falls back to the id). */
|
|
65
|
+
function agentRoleLabel(role) {
|
|
66
|
+
const labels = {
|
|
67
|
+
synthesizer: 'Technical Lead', architect: 'System Architect',
|
|
68
|
+
scaffolder: 'Project Scaffolder', planner: 'Refactoring Planner',
|
|
69
|
+
implementer: 'Implementation Engineer', reviewer: 'Code Reviewer',
|
|
70
|
+
debugger: 'Debugging Specialist', scanner: 'Vulnerability Scanner',
|
|
71
|
+
analyzer: 'Code Analyzer',
|
|
72
|
+
};
|
|
73
|
+
return labels[role] || role;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Compose a sub-agent prompt: the role's system prompt + the task. */
|
|
77
|
+
function composeAgentPrompt(role, task) {
|
|
78
|
+
return `${AGENT_PRESETS[role]}\n\nTask: ${task}\n\nRespond directly — no preamble.`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Every preset id, in palette order. */
|
|
82
|
+
function agentRoles() {
|
|
83
|
+
return Object.keys(AGENT_PRESETS);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The research-council prompt (Analyst/Architect/Ethicist/Pragmatist),
|
|
88
|
+
* ported from the reference's /research command. Includes the workspace
|
|
89
|
+
* context note so the model can read real files.
|
|
90
|
+
*/
|
|
91
|
+
function composeResearchPrompt(question, workspaceRoot = process.cwd()) {
|
|
92
|
+
return [
|
|
93
|
+
`Research the following question from four perspectives, then synthesize:`,
|
|
94
|
+
``,
|
|
95
|
+
`Question: ${question}`,
|
|
96
|
+
``,
|
|
97
|
+
`You are a research council with these members:`,
|
|
98
|
+
`- Analyst: reasons from data, statistics, and empirical evidence; values measurable outcomes.`,
|
|
99
|
+
`- Architect: evaluates designs, tradeoffs, and architectural decisions; focuses on scalability, maintainability, and system coherence.`,
|
|
100
|
+
`- Ethicist: evaluates safety, fairness, privacy, and societal impact; raises concerns others miss.`,
|
|
101
|
+
`- Pragmatist: evaluates practicality, implementation effort, and real-world constraints; balances idealism with what works in production.`,
|
|
102
|
+
``,
|
|
103
|
+
`Workspace: ${workspaceRoot} — read files with Read, search with Grep, browse with Glob, and check recent git changes with Git to ground your analysis in the real codebase.`,
|
|
104
|
+
``,
|
|
105
|
+
`Format: one reasoned section per perspective, then a Synthesis with a clear recommendation. Always state VOTE: approve, reject, or abstain and REASONING with clear justification.`,
|
|
106
|
+
].join('\n');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* A structured debate prompt for the current model (the reference runs a
|
|
111
|
+
* real multi-model DiscussionRoom; this build simulates the debate on the
|
|
112
|
+
* one configured backend, which the note makes explicit).
|
|
113
|
+
*/
|
|
114
|
+
function composeDebatePrompt(topic, modelId = '') {
|
|
115
|
+
return [
|
|
116
|
+
`Hold a structured debate on: ${topic}`,
|
|
117
|
+
``,
|
|
118
|
+
`Present two opposing positions fairly (with the strongest argument FOR and AGAINST), then act as moderator:`,
|
|
119
|
+
`1. Opening statements for each side.`,
|
|
120
|
+
`2. Rebuttals — each side attacks the other's weakest claim.`,
|
|
121
|
+
`3. Cross-examination questions and answers.`,
|
|
122
|
+
`4. Closing statements.`,
|
|
123
|
+
`5. A moderator verdict summarizing where each side won and a final recommendation.`,
|
|
124
|
+
``,
|
|
125
|
+
`Be rigorous and balanced — steelman both sides before judging.${modelId ? ` (Simulated on ${modelId} — the reference runs a multi-model discussion.)` : ''}`,
|
|
126
|
+
].join('\n');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
module.exports = {
|
|
130
|
+
AGENT_PRESETS,
|
|
131
|
+
agentRoleLabel,
|
|
132
|
+
composeAgentPrompt,
|
|
133
|
+
agentRoles,
|
|
134
|
+
composeResearchPrompt,
|
|
135
|
+
composeDebatePrompt,
|
|
136
|
+
};
|