@kdonev/termscape 0.1.0 → 0.1.1
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 +176 -13
- package/dist/agents/detect.d.ts +27 -0
- package/dist/agents/detect.d.ts.map +1 -0
- package/dist/agents/detect.js +210 -0
- package/dist/agents/detect.js.map +1 -0
- package/dist/agents/profiles.d.ts +110 -0
- package/dist/agents/profiles.d.ts.map +1 -1
- package/dist/agents/profiles.js +215 -0
- package/dist/agents/profiles.js.map +1 -1
- package/dist/agents/templates.d.ts +85 -0
- package/dist/agents/templates.d.ts.map +1 -0
- package/dist/agents/templates.js +133 -0
- package/dist/agents/templates.js.map +1 -0
- package/dist/agents/wiring.d.ts +30 -1
- package/dist/agents/wiring.d.ts.map +1 -1
- package/dist/agents/wiring.js +179 -10
- package/dist/agents/wiring.js.map +1 -1
- package/dist/cli.js +41 -14
- package/dist/cli.js.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +55 -0
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/store.d.ts +41 -0
- package/dist/db/store.d.ts.map +1 -1
- package/dist/db/store.js +75 -2
- package/dist/db/store.js.map +1 -1
- package/dist/hub.d.ts +227 -6
- package/dist/hub.d.ts.map +1 -1
- package/dist/hub.js +504 -33
- package/dist/hub.js.map +1 -1
- package/dist/hub.tgz +0 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +19 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/protocol/domain.d.ts +87 -0
- package/dist/protocol/domain.d.ts.map +1 -1
- package/dist/protocol/domain.js +104 -0
- package/dist/protocol/domain.js.map +1 -1
- package/dist/protocol/mcp-tools.d.ts +30 -0
- package/dist/protocol/mcp-tools.d.ts.map +1 -1
- package/dist/protocol/mcp-tools.js +50 -0
- package/dist/protocol/mcp-tools.js.map +1 -1
- package/dist/protocol/peer.d.ts +36 -0
- package/dist/protocol/peer.d.ts.map +1 -1
- package/dist/protocol/peer.js +35 -1
- package/dist/protocol/peer.js.map +1 -1
- package/dist/protocol/ws.d.ts +254 -0
- package/dist/protocol/ws.d.ts.map +1 -1
- package/dist/protocol/ws.js +160 -5
- package/dist/protocol/ws.js.map +1 -1
- package/dist/remote/lan.d.ts +45 -0
- package/dist/remote/lan.d.ts.map +1 -1
- package/dist/remote/lan.js +44 -0
- package/dist/remote/lan.js.map +1 -1
- package/dist/remote/peer-serve.d.ts.map +1 -1
- package/dist/remote/peer-serve.js +31 -3
- package/dist/remote/peer-serve.js.map +1 -1
- package/dist/remote/peer.d.ts +7 -0
- package/dist/remote/peer.d.ts.map +1 -1
- package/dist/remote/peer.js +22 -0
- package/dist/remote/peer.js.map +1 -1
- package/dist/remote/registry.d.ts +69 -2
- package/dist/remote/registry.d.ts.map +1 -1
- package/dist/remote/registry.js +134 -10
- package/dist/remote/registry.js.map +1 -1
- package/dist/server.d.ts +22 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +237 -117
- package/dist/server.js.map +1 -1
- package/dist/session/manager.d.ts +44 -4
- package/dist/session/manager.d.ts.map +1 -1
- package/dist/session/manager.js +161 -34
- package/dist/session/manager.js.map +1 -1
- package/package.json +1 -1
- package/web/assets/{index-BOqZOoep.js → index-Bq_Y0JcC.js} +6 -6
- package/web/assets/{index-B2JtCtHa.css → index-DQYDkOwJ.css} +1 -1
- package/web/index.html +2 -2
package/dist/agents/profiles.js
CHANGED
|
@@ -11,6 +11,33 @@ function defaultShell() {
|
|
|
11
11
|
* Built-in profiles. All Claude Code flags here are verified against the CLI:
|
|
12
12
|
* --mcp-config, --strict-mcp-config, --session-id, --settings,
|
|
13
13
|
* --append-system-prompt-file, --resume.
|
|
14
|
+
*
|
|
15
|
+
* Codex and Gemini are wired too, and every flag and key below was verified
|
|
16
|
+
* against the CLI actually installed - codex-cli 0.153.4 and gemini 0.58.0 -
|
|
17
|
+
* rather than written from memory. Both reach the hub the same way Claude
|
|
18
|
+
* Code does, over one streamable-HTTP MCP server carrying a bearer token, and
|
|
19
|
+
* neither needs a byte written to config the user owns:
|
|
20
|
+
*
|
|
21
|
+
* - **Codex** takes `-c <dotted.key>=<toml>` on any invocation, so the server
|
|
22
|
+
* is declared in argv for the one run. The token is *not* in argv - it goes
|
|
23
|
+
* in the environment, and `bearer_token_env_var` names the variable to read
|
|
24
|
+
* it from, which keeps it out of every process listing on the machine.
|
|
25
|
+
* - **Gemini** has no per-run config flag, but
|
|
26
|
+
* `GEMINI_CLI_SYSTEM_SETTINGS_PATH` repoints its system settings layer at a
|
|
27
|
+
* file of our choosing, which the hub generates per session.
|
|
28
|
+
*
|
|
29
|
+
* - **opencode** turned out to be the least invasive of the three and was
|
|
30
|
+
* assumed to be the hardest. It reads its entire config from
|
|
31
|
+
* `OPENCODE_CONFIG_CONTENT`, so nothing is written anywhere at all, and what
|
|
32
|
+
* it is given is merged with the user's own config rather than replacing it.
|
|
33
|
+
* The assumption that it had no per-run route came from reading
|
|
34
|
+
* `opencode mcp add` - which does write to the user's file, and ignores
|
|
35
|
+
* `OPENCODE_CONFIG` when it does - and mistaking that command for the only
|
|
36
|
+
* way in.
|
|
37
|
+
*
|
|
38
|
+
* `shell` is the only profile left that is not an agent, and it is not one in
|
|
39
|
+
* a way no flag can fix: it runs a shell, so text typed at it is executed
|
|
40
|
+
* rather than read.
|
|
14
41
|
*/
|
|
15
42
|
export const BUILTIN_PROFILES = {
|
|
16
43
|
claude: {
|
|
@@ -32,6 +59,19 @@ export const BUILTIN_PROFILES = {
|
|
|
32
59
|
mcp: true,
|
|
33
60
|
status: 'hooks',
|
|
34
61
|
inject: 'bracketed',
|
|
62
|
+
versionArgs: ['--version'],
|
|
63
|
+
/*
|
|
64
|
+
* Claude Code has no listing command, so this is the declared half of
|
|
65
|
+
* "ask where you can, declare where you cannot". Exactly the aliases
|
|
66
|
+
* `claude --help` names for --model; a full name like `claude-fable-5` is
|
|
67
|
+
* accepted too, which is why a template must not be limited to this list.
|
|
68
|
+
*/
|
|
69
|
+
models: ['fable', 'opus', 'sonnet'],
|
|
70
|
+
// Both verified against `claude --help`: --model takes an alias or a full
|
|
71
|
+
// name, --effort takes low, medium, high, xhigh or max.
|
|
72
|
+
modelArgs: ['--model', '{{model}}'],
|
|
73
|
+
effortArgs: ['--effort', '{{effort}}'],
|
|
74
|
+
efforts: ['low', 'medium', 'high', 'xhigh', 'max'],
|
|
35
75
|
// Resume swaps --session-id for --resume; everything else is re-templated
|
|
36
76
|
// identically, and crucially the session is relaunched in the same cwd,
|
|
37
77
|
// because Claude Code keys its conversation store by working directory.
|
|
@@ -47,6 +87,151 @@ export const BUILTIN_PROFILES = {
|
|
|
47
87
|
'{{brief_path}}',
|
|
48
88
|
],
|
|
49
89
|
},
|
|
90
|
+
opencode: {
|
|
91
|
+
id: 'opencode',
|
|
92
|
+
description: 'opencode TUI, wired to the hub MCP endpoint',
|
|
93
|
+
command: 'opencode',
|
|
94
|
+
// Bare, which is its default subcommand and starts the TUI. `run` is the
|
|
95
|
+
// one-shot form and is not what a window on the canvas wants.
|
|
96
|
+
args: [],
|
|
97
|
+
/*
|
|
98
|
+
* The least invasive of the four, and the one that was assumed hardest.
|
|
99
|
+
* opencode reads its whole config from this variable, so there is no file
|
|
100
|
+
* anywhere - not even one of ours - and it is *merged* with the user's own
|
|
101
|
+
* config rather than replacing it, so their models, themes and their own
|
|
102
|
+
* MCP servers survive the session.
|
|
103
|
+
*
|
|
104
|
+
* Note what this deliberately does not use: `opencode mcp add` writes to
|
|
105
|
+
* ~/.config/opencode/opencode.json and ignores OPENCODE_CONFIG while doing
|
|
106
|
+
* it. Setting this variable also stops opencode writing its default config
|
|
107
|
+
* file on start, so a session leaves nothing behind at all.
|
|
108
|
+
*/
|
|
109
|
+
env: { OPENCODE_CONFIG_CONTENT: '{{opencode_config}}' },
|
|
110
|
+
// `opencode models` writes ~/.config/opencode/opencode.jsonc when it finds
|
|
111
|
+
// no config at all, and detection runs on machines whose owner may never
|
|
112
|
+
// have run opencode by hand. An empty config is still a config, so this
|
|
113
|
+
// suppresses that without changing what the probe reports.
|
|
114
|
+
probeEnv: { OPENCODE_CONFIG_CONTENT: '{}' },
|
|
115
|
+
mcp: true,
|
|
116
|
+
brief: 'typed',
|
|
117
|
+
status: 'heuristic',
|
|
118
|
+
inject: 'bracketed',
|
|
119
|
+
versionArgs: ['--version'],
|
|
120
|
+
// Real enumeration: one provider/model per line, 395 of them on the
|
|
121
|
+
// machine this was written on.
|
|
122
|
+
modelsArgs: ['models'],
|
|
123
|
+
// `-m provider/model` is a top-level option, so it applies to the TUI and
|
|
124
|
+
// not only to `run`. Verified against `opencode --help`.
|
|
125
|
+
modelArgs: ['-m', '{{model}}'],
|
|
126
|
+
// No effortArgs on purpose: `--variant` is documented under `opencode run`
|
|
127
|
+
// and is not a top-level option, so the TUI this profile starts does not
|
|
128
|
+
// take one. A template asking for an effort here is refused at load.
|
|
129
|
+
},
|
|
130
|
+
codex: {
|
|
131
|
+
id: 'codex',
|
|
132
|
+
description: 'Codex CLI, wired to the hub MCP endpoint',
|
|
133
|
+
command: 'codex',
|
|
134
|
+
/*
|
|
135
|
+
* Bare, which starts the interactive TUI - `exec` is the one-shot form and
|
|
136
|
+
* is not what a window on the canvas wants.
|
|
137
|
+
*
|
|
138
|
+
* The two `-c` overrides are exactly the table `codex mcp add --url` would
|
|
139
|
+
* have written into ~/.codex/config.toml, except they live for one run and
|
|
140
|
+
* touch nothing. The value after `=` is parsed as TOML, which is why the
|
|
141
|
+
* URL is quoted.
|
|
142
|
+
*/
|
|
143
|
+
args: [
|
|
144
|
+
'-c',
|
|
145
|
+
'mcp_servers.termscape.url="{{mcp_url}}"',
|
|
146
|
+
'-c',
|
|
147
|
+
'mcp_servers.termscape.bearer_token_env_var="TERMSCAPE_TOKEN"',
|
|
148
|
+
],
|
|
149
|
+
// The token is named here rather than written into argv: `-c` values land
|
|
150
|
+
// in the process command line, where every other user on the machine can
|
|
151
|
+
// read them.
|
|
152
|
+
env: { TERMSCAPE_TOKEN: '{{token}}' },
|
|
153
|
+
mcp: true,
|
|
154
|
+
brief: 'typed',
|
|
155
|
+
status: 'heuristic',
|
|
156
|
+
inject: 'bracketed',
|
|
157
|
+
versionArgs: ['--version'],
|
|
158
|
+
/*
|
|
159
|
+
* `codex debug models` does render the real catalog, but it is a debug
|
|
160
|
+
* command by its own description and it answers with 500KB of JSON that
|
|
161
|
+
* also carries every model's system prompt - not the one-per-line stdout
|
|
162
|
+
* `modelsArgs` reads. So this is the declared half of "ask where you can,
|
|
163
|
+
* declare where you cannot": the slugs that catalog marks
|
|
164
|
+
* `visibility: "list"`. A full name not in this list is still accepted,
|
|
165
|
+
* which is why a template must not be limited to it.
|
|
166
|
+
*/
|
|
167
|
+
models: ['gpt-6-astra', 'gpt-5.6-sol', 'gpt-5.6-terra', 'gpt-5.6-luna', 'gpt-5.5', 'gpt-5.2'],
|
|
168
|
+
modelArgs: ['-m', '{{model}}'],
|
|
169
|
+
/*
|
|
170
|
+
* Codex has no `--effort`; reasoning depth is a config key, and it takes
|
|
171
|
+
* the same `-c` route as the MCP server above. Verified by reading it back
|
|
172
|
+
* off the `reasoning effort:` line of the session header.
|
|
173
|
+
*
|
|
174
|
+
* The levels are the union of `supported_reasoning_levels` across the
|
|
175
|
+
* listed models. They are per model in the catalog and Codex forwards
|
|
176
|
+
* whatever it is given without checking, so this list is what the dialog
|
|
177
|
+
* offers and never a limit the hub enforces.
|
|
178
|
+
*/
|
|
179
|
+
effortArgs: ['-c', 'model_reasoning_effort="{{effort}}"'],
|
|
180
|
+
efforts: ['low', 'medium', 'high', 'xhigh', 'max', 'ultra'],
|
|
181
|
+
/*
|
|
182
|
+
* No resumeArgs, and not an oversight. `codex resume` takes a session id,
|
|
183
|
+
* but Codex mints that id itself and offers no way to be handed one, so
|
|
184
|
+
* the hub cannot record up front what it would have to ask for later.
|
|
185
|
+
* `--last` is the alternative and it resolves to "the most recent session
|
|
186
|
+
* in this cwd", which is the wrong agent as soon as a workspace holds two
|
|
187
|
+
* of them. Better to say plainly it restarts clean.
|
|
188
|
+
*/
|
|
189
|
+
},
|
|
190
|
+
gemini: {
|
|
191
|
+
id: 'gemini',
|
|
192
|
+
description: 'Gemini CLI, wired to the hub MCP endpoint',
|
|
193
|
+
command: 'gemini',
|
|
194
|
+
/*
|
|
195
|
+
* Gemini refuses to start MCP servers in a folder it does not trust, and
|
|
196
|
+
* says so only as a warning on stderr - the agent would come up looking
|
|
197
|
+
* fine with no tools. `--skip-trust` trusts the workspace for this session
|
|
198
|
+
* and writes nothing; the alternative, turning folder trust off in the
|
|
199
|
+
* settings file below, would disable the check for everything else too.
|
|
200
|
+
*/
|
|
201
|
+
args: ['--skip-trust'],
|
|
202
|
+
// No `--mcp-config` equivalent exists. This repoints the *system* settings
|
|
203
|
+
// layer - normally a machine-wide file - at the per-session one the hub
|
|
204
|
+
// generates, so ~/.gemini/settings.json is never opened, let alone written.
|
|
205
|
+
env: { GEMINI_CLI_SYSTEM_SETTINGS_PATH: '{{gemini_settings_path}}' },
|
|
206
|
+
mcp: true,
|
|
207
|
+
brief: 'typed',
|
|
208
|
+
status: 'heuristic',
|
|
209
|
+
inject: 'bracketed',
|
|
210
|
+
versionArgs: ['--version'],
|
|
211
|
+
// Declared: there is no `gemini models`. These are the model constants the
|
|
212
|
+
// CLI itself names, minus the ones it uses internally for embeddings and
|
|
213
|
+
// its visual agent, which are not things to point an agent window at.
|
|
214
|
+
models: [
|
|
215
|
+
'gemini-3.1-pro-preview',
|
|
216
|
+
'gemini-3-pro-preview',
|
|
217
|
+
'gemini-3.5-flash',
|
|
218
|
+
'gemini-3-flash',
|
|
219
|
+
'gemini-3.1-flash-lite',
|
|
220
|
+
'gemini-2.5-pro',
|
|
221
|
+
'gemini-2.5-flash',
|
|
222
|
+
],
|
|
223
|
+
modelArgs: ['-m', '{{model}}'],
|
|
224
|
+
/*
|
|
225
|
+
* No effortArgs: `gemini --help` documents no reasoning-effort option, so
|
|
226
|
+
* a template naming one for this agent is refused at load rather than
|
|
227
|
+
* dropped at launch.
|
|
228
|
+
*
|
|
229
|
+
* No resumeArgs either, for a narrower reason than Codex's. `--session-id`
|
|
230
|
+
* does accept a UUID of our choosing, but `--resume` takes "latest" or an
|
|
231
|
+
* index into a list - never that UUID - so the id the hub could record is
|
|
232
|
+
* not an id it could resume by.
|
|
233
|
+
*/
|
|
234
|
+
},
|
|
50
235
|
shell: {
|
|
51
236
|
id: 'shell',
|
|
52
237
|
description: 'Plain terminal, no agent wiring',
|
|
@@ -54,11 +239,29 @@ export const BUILTIN_PROFILES = {
|
|
|
54
239
|
args: [],
|
|
55
240
|
env: {},
|
|
56
241
|
mcp: false,
|
|
242
|
+
// Said out loud rather than left to the default, because this is the one
|
|
243
|
+
// profile where being typed at is actively harmful: a shell runs what it
|
|
244
|
+
// is given. It can still be *sent* a message - the router writes to any
|
|
245
|
+
// running window - and that is the human's business, not the hub's.
|
|
246
|
+
brief: 'none',
|
|
57
247
|
status: 'heuristic',
|
|
58
248
|
readyHint: '[$#>%] ?$',
|
|
59
249
|
inject: 'raw',
|
|
250
|
+
// Nothing to detect: it is whatever COMSPEC or SHELL points at, it is
|
|
251
|
+
// always there, and asking a shell its version means something different
|
|
252
|
+
// on every platform.
|
|
60
253
|
},
|
|
61
254
|
};
|
|
255
|
+
/**
|
|
256
|
+
* How this profile's brief travels, with the defaults applied.
|
|
257
|
+
*
|
|
258
|
+
* One place, because three callers need the same answer and the interesting
|
|
259
|
+
* part is the default rather than the field: absent means `flag` for a wired
|
|
260
|
+
* agent and `none` for an unwired one.
|
|
261
|
+
*/
|
|
262
|
+
export function briefMode(p) {
|
|
263
|
+
return p.brief ?? (p.mcp ? 'flag' : 'none');
|
|
264
|
+
}
|
|
62
265
|
export class ProfileRegistry {
|
|
63
266
|
profiles;
|
|
64
267
|
constructor(profiles) {
|
|
@@ -74,6 +277,10 @@ export class ProfileRegistry {
|
|
|
74
277
|
for (const [id, v] of Object.entries(raw)) {
|
|
75
278
|
if (typeof v !== 'object' || v === null)
|
|
76
279
|
continue;
|
|
280
|
+
// `[template.reviewer]` parses as one table named `template`, and it
|
|
281
|
+
// belongs to TemplateRegistry rather than here.
|
|
282
|
+
if (id === 'template')
|
|
283
|
+
continue;
|
|
77
284
|
const base = merged[id];
|
|
78
285
|
merged[id] = {
|
|
79
286
|
id,
|
|
@@ -85,7 +292,15 @@ export class ProfileRegistry {
|
|
|
85
292
|
status: v.status ?? base?.status ?? 'heuristic',
|
|
86
293
|
readyHint: v.ready_hint ?? v.readyHint ?? base?.readyHint,
|
|
87
294
|
inject: v.inject ?? base?.inject ?? 'bracketed',
|
|
295
|
+
brief: v.brief ?? base?.brief,
|
|
88
296
|
resumeArgs: v.resume_args ?? v.resumeArgs ?? base?.resumeArgs,
|
|
297
|
+
probeEnv: v.probe_env ?? v.probeEnv ?? base?.probeEnv,
|
|
298
|
+
versionArgs: v.version_args ?? v.versionArgs ?? base?.versionArgs,
|
|
299
|
+
modelsArgs: v.models_args ?? v.modelsArgs ?? base?.modelsArgs,
|
|
300
|
+
models: v.models ?? base?.models,
|
|
301
|
+
modelArgs: v.model_args ?? v.modelArgs ?? base?.modelArgs,
|
|
302
|
+
effortArgs: v.effort_args ?? v.effortArgs ?? base?.effortArgs,
|
|
303
|
+
efforts: v.efforts ?? base?.efforts,
|
|
89
304
|
};
|
|
90
305
|
}
|
|
91
306
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/agents/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/agents/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AA4GpC,SAAS,YAAY;IACnB,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,gBAAgB,CAAC;IACzE,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,WAAW,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAiC;IAC5D,MAAM,EAAE;QACN,EAAE,EAAE,QAAQ;QACZ,WAAW,EAAE,4CAA4C;QACzD,OAAO,EAAE,QAAQ;QACjB,IAAI,EAAE;YACJ,cAAc;YACd,qBAAqB;YACrB,qBAAqB;YACrB,cAAc;YACd,kBAAkB;YAClB,YAAY;YACZ,mBAAmB;YACnB,6BAA6B;YAC7B,gBAAgB;SACjB;QACD,GAAG,EAAE,EAAE;QACP,GAAG,EAAE,IAAI;QACT,MAAM,EAAE,OAAO;QACf,MAAM,EAAE,WAAW;QACnB,WAAW,EAAE,CAAC,WAAW,CAAC;QAC1B;;;;;WAKG;QACH,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC;QACnC,0EAA0E;QAC1E,wDAAwD;QACxD,SAAS,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC;QACnC,UAAU,EAAE,CAAC,UAAU,EAAE,YAAY,CAAC;QACtC,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;QAClD,0EAA0E;QAC1E,wEAAwE;QACxE,wEAAwE;QACxE,UAAU,EAAE;YACV,cAAc;YACd,qBAAqB;YACrB,qBAAqB;YACrB,UAAU;YACV,kBAAkB;YAClB,YAAY;YACZ,mBAAmB;YACnB,6BAA6B;YAC7B,gBAAgB;SACjB;KACF;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,UAAU;QACd,WAAW,EAAE,6CAA6C;QAC1D,OAAO,EAAE,UAAU;QACnB,yEAAyE;QACzE,8DAA8D;QAC9D,IAAI,EAAE,EAAE;QACR;;;;;;;;;;;WAWG;QACH,GAAG,EAAE,EAAE,uBAAuB,EAAE,qBAAqB,EAAE;QACvD,2EAA2E;QAC3E,yEAAyE;QACzE,wEAAwE;QACxE,2DAA2D;QAC3D,QAAQ,EAAE,EAAE,uBAAuB,EAAE,IAAI,EAAE;QAC3C,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,WAAW;QACnB,MAAM,EAAE,WAAW;QACnB,WAAW,EAAE,CAAC,WAAW,CAAC;QAC1B,oEAAoE;QACpE,+BAA+B;QAC/B,UAAU,EAAE,CAAC,QAAQ,CAAC;QACtB,0EAA0E;QAC1E,yDAAyD;QACzD,SAAS,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC;QAC9B,2EAA2E;QAC3E,yEAAyE;QACzE,qEAAqE;KACtE;IACD,KAAK,EAAE;QACL,EAAE,EAAE,OAAO;QACX,WAAW,EAAE,0CAA0C;QACvD,OAAO,EAAE,OAAO;QAChB;;;;;;;;WAQG;QACH,IAAI,EAAE;YACJ,IAAI;YACJ,yCAAyC;YACzC,IAAI;YACJ,8DAA8D;SAC/D;QACD,0EAA0E;QAC1E,yEAAyE;QACzE,aAAa;QACb,GAAG,EAAE,EAAE,eAAe,EAAE,WAAW,EAAE;QACrC,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,WAAW;QACnB,MAAM,EAAE,WAAW;QACnB,WAAW,EAAE,CAAC,WAAW,CAAC;QAC1B;;;;;;;;WAQG;QACH,MAAM,EAAE,CAAC,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,CAAC;QAC7F,SAAS,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC;QAC9B;;;;;;;;;WASG;QACH,UAAU,EAAE,CAAC,IAAI,EAAE,qCAAqC,CAAC;QACzD,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC;QAC3D;;;;;;;WAOG;KACJ;IACD,MAAM,EAAE;QACN,EAAE,EAAE,QAAQ;QACZ,WAAW,EAAE,2CAA2C;QACxD,OAAO,EAAE,QAAQ;QACjB;;;;;;WAMG;QACH,IAAI,EAAE,CAAC,cAAc,CAAC;QACtB,2EAA2E;QAC3E,wEAAwE;QACxE,4EAA4E;QAC5E,GAAG,EAAE,EAAE,+BAA+B,EAAE,0BAA0B,EAAE;QACpE,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,WAAW;QACnB,MAAM,EAAE,WAAW;QACnB,WAAW,EAAE,CAAC,WAAW,CAAC;QAC1B,2EAA2E;QAC3E,yEAAyE;QACzE,sEAAsE;QACtE,MAAM,EAAE;YACN,wBAAwB;YACxB,sBAAsB;YACtB,kBAAkB;YAClB,gBAAgB;YAChB,uBAAuB;YACvB,gBAAgB;YAChB,kBAAkB;SACnB;QACD,SAAS,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC;QAC9B;;;;;;;;;WASG;KACJ;IACD,KAAK,EAAE;QACL,EAAE,EAAE,OAAO;QACX,WAAW,EAAE,iCAAiC;QAC9C,OAAO,EAAE,YAAY,EAAE;QACvB,IAAI,EAAE,EAAE;QACR,GAAG,EAAE,EAAE;QACP,GAAG,EAAE,KAAK;QACV,yEAAyE;QACzE,yEAAyE;QACzE,wEAAwE;QACxE,oEAAoE;QACpE,KAAK,EAAE,MAAM;QACb,MAAM,EAAE,WAAW;QACnB,SAAS,EAAE,WAAW;QACtB,MAAM,EAAE,KAAK;QACb,sEAAsE;QACtE,yEAAyE;QACzE,qBAAqB;KACtB;CACF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,CAAe;IACvC,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,OAAO,eAAe;IAClB,QAAQ,CAA+B;IAE/C,YAAY,QAAuC;QACjD,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,EAAE,GAAG,gBAAgB,EAAE,CAAC;IACtD,CAAC;IAED,oEAAoE;IACpE,MAAM,CAAC,IAAI;QACT,MAAM,MAAM,GAAiC,EAAE,GAAG,gBAAgB,EAAE,CAAC;QACrE,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAwB,CAAC;gBACzE,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC1C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI;wBAAE,SAAS;oBAClD,qEAAqE;oBACrE,gDAAgD;oBAChD,IAAI,EAAE,KAAK,UAAU;wBAAE,SAAS;oBAChC,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;oBACxB,MAAM,CAAC,EAAE,CAAC,GAAG;wBACX,EAAE;wBACF,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI,EAAE,WAAW,IAAI,EAAE;wBACrD,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,IAAI,EAAE,OAAO,IAAI,EAAE;wBACzC,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,EAAE;wBAChC,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,GAAG,IAAI,EAAE;wBAC7B,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,GAAG,IAAI,IAAI;wBAC/B,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI,EAAE,MAAM,IAAI,WAAW;wBAC/C,SAAS,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,EAAE,SAAS;wBACzD,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI,EAAE,MAAM,IAAI,WAAW;wBAC/C,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,EAAE,KAAK;wBAC7B,UAAU,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,UAAU,IAAI,IAAI,EAAE,UAAU;wBAC7D,QAAQ,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,QAAQ,IAAI,IAAI,EAAE,QAAQ;wBACrD,WAAW,EAAE,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,WAAW,IAAI,IAAI,EAAE,WAAW;wBACjE,UAAU,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,UAAU,IAAI,IAAI,EAAE,UAAU;wBAC7D,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI,EAAE,MAAM;wBAChC,SAAS,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,EAAE,SAAS;wBACzD,UAAU,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,UAAU,IAAI,IAAI,EAAE,UAAU;wBAC7D,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,IAAI,EAAE,OAAO;qBACpC,CAAC;gBACJ,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,sEAAsE;gBACtE,OAAO,CAAC,KAAK,CAAC,uBAAuB,IAAI,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC;QACD,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;IACnC,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvB,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;QACzD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI;QACF,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAED,WAAW,CAAC,EAAU;QACpB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvB,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC;IACzB,CAAC;CACF;AAED,+EAA+E;AAC/E,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,IAA4B;IAClE,OAAO,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE,CAC5D,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAE,CAAC,CAAC,CAAC,KAAK,CACjC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAc,EAAE,IAA4B;IACtE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { AgentTemplateInfo, TemplateSource } from '../protocol/index.js';
|
|
2
|
+
import type { Store } from '../db/store.js';
|
|
3
|
+
import type { ProfileRegistry } from './profiles.js';
|
|
4
|
+
/**
|
|
5
|
+
* A template is an agent plus a model, an effort and an opening instruction.
|
|
6
|
+
*
|
|
7
|
+
* Starting an agent used to ask exactly one question - which CLI - and
|
|
8
|
+
* everything that actually distinguishes one agent from another was missing.
|
|
9
|
+
* A template is a saved answer to all four, picked once instead of typed every
|
|
10
|
+
* time.
|
|
11
|
+
*
|
|
12
|
+
* On the words, because this file cannot be written without settling them:
|
|
13
|
+
*
|
|
14
|
+
* - **agent** is the CLI program, which the code calls a *profile*. That name
|
|
15
|
+
* stays internal: it is the recipe for launching one CLI.
|
|
16
|
+
* - **template** is what a human picks from a list.
|
|
17
|
+
* - **session** is one running instance, with an address and a window.
|
|
18
|
+
*
|
|
19
|
+
* A template that names only an agent is exactly today's behaviour, which is
|
|
20
|
+
* why every profile gets one for free and nothing that works now stops
|
|
21
|
+
* working.
|
|
22
|
+
*/
|
|
23
|
+
export interface AgentTemplate {
|
|
24
|
+
id: string;
|
|
25
|
+
description: string;
|
|
26
|
+
/** Profile id. */
|
|
27
|
+
agent: string;
|
|
28
|
+
model?: string;
|
|
29
|
+
effort?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Typed into the terminal once the CLI is up, not written into argv - in
|
|
32
|
+
* argv it would be a different thing entirely, and written immediately it
|
|
33
|
+
* lands before the program is reading.
|
|
34
|
+
*/
|
|
35
|
+
prompt?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Why this template cannot be used, when it cannot.
|
|
38
|
+
*
|
|
39
|
+
* Kept rather than dropped, for the same reason a missing agent stays in the
|
|
40
|
+
* list: a template that silently vanished looks like the config was ignored.
|
|
41
|
+
* A template asking for an effort on an agent that has no effort setting is
|
|
42
|
+
* a configuration error worth reporting here, at load, and not a flag
|
|
43
|
+
* quietly dropped at launch.
|
|
44
|
+
*/
|
|
45
|
+
error?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Where this one came from, which is what decides whether the panel may
|
|
48
|
+
* edit it.
|
|
49
|
+
*
|
|
50
|
+
* - `derived` — the free template every agent gets under its own name.
|
|
51
|
+
* Nothing is stored for it, so editing one means creating a stored
|
|
52
|
+
* template that shadows it, and there is nothing to remove.
|
|
53
|
+
* - `stored` — made from the panel, in `state.db`. Editable and removable.
|
|
54
|
+
* - `file` — declared in `~/.termscape/agents.toml`. Read-only here: it is
|
|
55
|
+
* the user's file and the hub does not write it.
|
|
56
|
+
*/
|
|
57
|
+
source: TemplateSource;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check a template against the agent it names.
|
|
61
|
+
*
|
|
62
|
+
* Returns the reason it cannot be used, or null. This is where "the agent
|
|
63
|
+
* declares how to spell it" is enforced: a template holds *values*, and a
|
|
64
|
+
* value nobody can spell on the command line is not a template, it is a typo
|
|
65
|
+
* that would otherwise be discovered at launch.
|
|
66
|
+
*/
|
|
67
|
+
export declare function validate(t: AgentTemplate, profiles: ProfileRegistry): string | null;
|
|
68
|
+
export declare class TemplateRegistry {
|
|
69
|
+
private readonly templates;
|
|
70
|
+
constructor(templates: Record<string, AgentTemplate>);
|
|
71
|
+
/**
|
|
72
|
+
* One bare template per agent, overlaid with `[template.x]` from
|
|
73
|
+
* ~/.termscape/agents.toml.
|
|
74
|
+
*
|
|
75
|
+
* A broken file falls back to the bare set rather than taking the hub down,
|
|
76
|
+
* exactly as the profile loader does - the two live in the same file, and
|
|
77
|
+
* failing differently for the two halves of it would be its own surprise.
|
|
78
|
+
*/
|
|
79
|
+
static load(profiles: ProfileRegistry, store?: Store): TemplateRegistry;
|
|
80
|
+
get(id: string): AgentTemplate | null;
|
|
81
|
+
list(): AgentTemplate[];
|
|
82
|
+
/** What the browser is given to build the picker from. */
|
|
83
|
+
info(): AgentTemplateInfo[];
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/agents/templates.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE7E,OAAO,KAAK,EAAE,KAAK,EAAkB,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAgB,eAAe,EAAE,MAAM,eAAe,CAAC;AAEnE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;OAUG;IACH,MAAM,EAAE,cAAc,CAAC;CACxB;AAyBD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,CAAC,EAAE,aAAa,EAChB,QAAQ,EAAE,eAAe,GACxB,MAAM,GAAG,IAAI,CAUf;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;gBAE9C,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IAIpD;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,gBAAgB;IA2DvE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAIrC,IAAI,IAAI,aAAa,EAAE;IAIvB,0DAA0D;IAC1D,IAAI,IAAI,iBAAiB,EAAE;CAY5B"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { parse as parseToml } from 'smol-toml';
|
|
3
|
+
import { paths } from '../paths.js';
|
|
4
|
+
/** The trivial template for a profile: this agent, nothing else specified. */
|
|
5
|
+
function bare(profile) {
|
|
6
|
+
return {
|
|
7
|
+
id: profile.id,
|
|
8
|
+
description: profile.description,
|
|
9
|
+
agent: profile.id,
|
|
10
|
+
source: 'derived',
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/** One the user made from the panel, as it comes out of the database. */
|
|
14
|
+
function fromStored(t, profiles) {
|
|
15
|
+
return {
|
|
16
|
+
id: t.id,
|
|
17
|
+
description: t.description ?? profiles.get(t.agent)?.description ?? t.id,
|
|
18
|
+
agent: t.agent,
|
|
19
|
+
model: t.model ?? undefined,
|
|
20
|
+
effort: t.effort ?? undefined,
|
|
21
|
+
prompt: t.prompt ?? undefined,
|
|
22
|
+
source: 'stored',
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Check a template against the agent it names.
|
|
27
|
+
*
|
|
28
|
+
* Returns the reason it cannot be used, or null. This is where "the agent
|
|
29
|
+
* declares how to spell it" is enforced: a template holds *values*, and a
|
|
30
|
+
* value nobody can spell on the command line is not a template, it is a typo
|
|
31
|
+
* that would otherwise be discovered at launch.
|
|
32
|
+
*/
|
|
33
|
+
export function validate(t, profiles) {
|
|
34
|
+
const agent = profiles.get(t.agent);
|
|
35
|
+
if (!agent)
|
|
36
|
+
return `unknown agent "${t.agent}"`;
|
|
37
|
+
if (t.model !== undefined && !agent.modelArgs) {
|
|
38
|
+
return `${t.agent} does not take a model on the command line`;
|
|
39
|
+
}
|
|
40
|
+
if (t.effort !== undefined && !agent.effortArgs) {
|
|
41
|
+
return `${t.agent} has no effort setting`;
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
export class TemplateRegistry {
|
|
46
|
+
templates;
|
|
47
|
+
constructor(templates) {
|
|
48
|
+
this.templates = templates;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* One bare template per agent, overlaid with `[template.x]` from
|
|
52
|
+
* ~/.termscape/agents.toml.
|
|
53
|
+
*
|
|
54
|
+
* A broken file falls back to the bare set rather than taking the hub down,
|
|
55
|
+
* exactly as the profile loader does - the two live in the same file, and
|
|
56
|
+
* failing differently for the two halves of it would be its own surprise.
|
|
57
|
+
*/
|
|
58
|
+
static load(profiles, store) {
|
|
59
|
+
const merged = Object.fromEntries(profiles.list().map((p) => [p.id, bare(p)]));
|
|
60
|
+
/*
|
|
61
|
+
* Stored over derived, file over stored.
|
|
62
|
+
*
|
|
63
|
+
* Stored beats derived because a bare template is only a default: making
|
|
64
|
+
* one called `claude` with a model on it is exactly how you say "when I
|
|
65
|
+
* pick claude, I mean this". File beats stored because someone who wrote a
|
|
66
|
+
* template by hand meant it, and a UI silently overriding their file is
|
|
67
|
+
* worse than a UI refusing an id the file has claimed - which is what the
|
|
68
|
+
* hub does on create.
|
|
69
|
+
*/
|
|
70
|
+
if (store) {
|
|
71
|
+
for (const t of store.listStoredTemplates()) {
|
|
72
|
+
merged[t.id] = fromStored(t, profiles);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const file = paths.profiles();
|
|
76
|
+
if (existsSync(file)) {
|
|
77
|
+
try {
|
|
78
|
+
const raw = parseToml(readFileSync(file, 'utf8'));
|
|
79
|
+
// `[template.reviewer]` parses as one table named `template`, which is
|
|
80
|
+
// also why "template" is not usable as an agent id.
|
|
81
|
+
const declared = raw.template;
|
|
82
|
+
if (typeof declared === 'object' && declared !== null) {
|
|
83
|
+
for (const [id, v] of Object.entries(declared)) {
|
|
84
|
+
if (typeof v !== 'object' || v === null)
|
|
85
|
+
continue;
|
|
86
|
+
const t = v;
|
|
87
|
+
const agent = typeof t.agent === 'string' ? t.agent : id;
|
|
88
|
+
merged[id] = {
|
|
89
|
+
id,
|
|
90
|
+
description: typeof t.description === 'string'
|
|
91
|
+
? t.description
|
|
92
|
+
: (profiles.get(agent)?.description ?? id),
|
|
93
|
+
agent,
|
|
94
|
+
model: typeof t.model === 'string' ? t.model : undefined,
|
|
95
|
+
effort: typeof t.effort === 'string' ? t.effort : undefined,
|
|
96
|
+
prompt: typeof t.prompt === 'string' ? t.prompt : undefined,
|
|
97
|
+
source: 'file',
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
console.error(`[templates] ignoring ${file}: ${err.message}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
for (const t of Object.values(merged)) {
|
|
107
|
+
const problem = validate(t, profiles);
|
|
108
|
+
if (problem)
|
|
109
|
+
t.error = problem;
|
|
110
|
+
}
|
|
111
|
+
return new TemplateRegistry(merged);
|
|
112
|
+
}
|
|
113
|
+
get(id) {
|
|
114
|
+
return this.templates[id] ?? null;
|
|
115
|
+
}
|
|
116
|
+
list() {
|
|
117
|
+
return Object.values(this.templates);
|
|
118
|
+
}
|
|
119
|
+
/** What the browser is given to build the picker from. */
|
|
120
|
+
info() {
|
|
121
|
+
return this.list().map((t) => ({
|
|
122
|
+
id: t.id,
|
|
123
|
+
description: t.description,
|
|
124
|
+
agent: t.agent,
|
|
125
|
+
model: t.model ?? null,
|
|
126
|
+
effort: t.effort ?? null,
|
|
127
|
+
prompt: t.prompt ?? null,
|
|
128
|
+
error: t.error ?? null,
|
|
129
|
+
source: t.source,
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/agents/templates.ts"],"names":[],"mappings":"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"}
|
package/dist/agents/wiring.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AgentProfile } from './profiles.js';
|
|
2
2
|
/**
|
|
3
3
|
* Everything an agent process needs on disk before it starts: its MCP config,
|
|
4
4
|
* its hook settings, and its brief. All generated per launch into
|
|
@@ -20,11 +20,40 @@ export interface WiringOutput {
|
|
|
20
20
|
mcpConfigPath: string;
|
|
21
21
|
settingsPath: string;
|
|
22
22
|
briefPath: string;
|
|
23
|
+
/**
|
|
24
|
+
* Gemini CLI reads no `--mcp-config`; the only per-run way in is
|
|
25
|
+
* GEMINI_CLI_SYSTEM_SETTINGS_PATH, which points its *system* settings layer
|
|
26
|
+
* at a file of our choosing. Written for every wired session rather than
|
|
27
|
+
* only for gemini, so a profile stays a config entry naming a path and not
|
|
28
|
+
* a special case in this file.
|
|
29
|
+
*/
|
|
30
|
+
geminiSettingsPath: string;
|
|
31
|
+
/**
|
|
32
|
+
* opencode's whole config, as a JSON string for an environment variable.
|
|
33
|
+
*
|
|
34
|
+
* The odd one out, and the least invasive of the three: opencode reads
|
|
35
|
+
* `OPENCODE_CONFIG_CONTENT` directly, so there is no file at all - not even
|
|
36
|
+
* one of ours. It is merged with the user's own config rather than replacing
|
|
37
|
+
* it, so their models, themes and their own MCP servers survive the session.
|
|
38
|
+
*/
|
|
39
|
+
opencodeConfig: string;
|
|
23
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Where a session's brief is written. Exported because an agent with no
|
|
43
|
+
* `--append-system-prompt-file` has its brief typed into the terminal
|
|
44
|
+
* instead, and the hub needs to read back what was written here.
|
|
45
|
+
*/
|
|
46
|
+
export declare function briefFileFor(sessionId: string): string;
|
|
24
47
|
export declare function writeWiring(input: WiringInput): WiringOutput;
|
|
25
48
|
/**
|
|
26
49
|
* Without this an agent has no idea why text is appearing in its input, or
|
|
27
50
|
* that it has an identity and peers at all.
|
|
51
|
+
*
|
|
52
|
+
* An unwired agent gets a shorter one. It is not a courtesy: the router writes
|
|
53
|
+
* to any running window it can resolve an address for, so such an agent can be
|
|
54
|
+
* messaged whether or not it was ever told messaging exists - and the
|
|
55
|
+
* paragraph telling it that a `[from ...]` line is a colleague rather than the
|
|
56
|
+
* human is exactly the paragraph it would otherwise be missing.
|
|
28
57
|
*/
|
|
29
58
|
export declare function renderBrief(input: WiringInput): string;
|
|
30
59
|
//# sourceMappingURL=wiring.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wiring.d.ts","sourceRoot":"","sources":["../../src/agents/wiring.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"wiring.d.ts","sourceRoot":"","sources":["../../src/agents/wiring.ts"],"names":[],"mappings":"AAGA,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7D;;;;GAIG;AAEH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtD;AAOD,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CAgD5D;AAwID;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAuEtD"}
|