@kdonev/termscape 0.1.0 → 0.1.2
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 +211 -79
- 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 +119 -2
- package/dist/agents/profiles.d.ts.map +1 -1
- package/dist/agents/profiles.js +224 -4
- package/dist/agents/profiles.js.map +1 -1
- package/dist/agents/templates.d.ts +100 -0
- package/dist/agents/templates.d.ts.map +1 -0
- package/dist/agents/templates.js +165 -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 +182 -10
- package/dist/agents/wiring.js.map +1 -1
- package/dist/cli.js +51 -14
- package/dist/cli.js.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +73 -0
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/store.d.ts +53 -1
- package/dist/db/store.d.ts.map +1 -1
- package/dist/db/store.js +118 -5
- package/dist/db/store.js.map +1 -1
- package/dist/hub.d.ts +264 -6
- package/dist/hub.d.ts.map +1 -1
- package/dist/hub.js +549 -33
- package/dist/hub.js.map +1 -1
- package/dist/hub.tgz +0 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +27 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/protocol/domain.d.ts +88 -0
- package/dist/protocol/domain.d.ts.map +1 -1
- package/dist/protocol/domain.js +114 -0
- package/dist/protocol/domain.js.map +1 -1
- package/dist/protocol/mcp-tools.d.ts +43 -0
- package/dist/protocol/mcp-tools.d.ts.map +1 -1
- package/dist/protocol/mcp-tools.js +65 -0
- package/dist/protocol/mcp-tools.js.map +1 -1
- package/dist/protocol/peer.d.ts +38 -1
- package/dist/protocol/peer.d.ts.map +1 -1
- package/dist/protocol/peer.js +41 -2
- package/dist/protocol/peer.js.map +1 -1
- package/dist/protocol/ws.d.ts +259 -0
- package/dist/protocol/ws.d.ts.map +1 -1
- package/dist/protocol/ws.js +169 -5
- package/dist/protocol/ws.js.map +1 -1
- package/dist/remote/deployer.d.ts.map +1 -1
- package/dist/remote/deployer.js +15 -2
- package/dist/remote/deployer.js.map +1 -1
- package/dist/remote/join-script.d.ts.map +1 -1
- package/dist/remote/join-script.js +34 -2
- package/dist/remote/join-script.js.map +1 -1
- package/dist/remote/lan.d.ts +73 -5
- package/dist/remote/lan.d.ts.map +1 -1
- package/dist/remote/lan.js +119 -10
- package/dist/remote/lan.js.map +1 -1
- package/dist/remote/peer-serve.d.ts.map +1 -1
- package/dist/remote/peer-serve.js +32 -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 +70 -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 +239 -117
- package/dist/server.js.map +1 -1
- package/dist/session/manager.d.ts +60 -4
- package/dist/session/manager.d.ts.map +1 -1
- package/dist/session/manager.js +198 -41
- package/dist/session/manager.js.map +1 -1
- package/dist/session/pty.d.ts +19 -0
- package/dist/session/pty.d.ts.map +1 -1
- package/dist/session/pty.js +84 -1
- package/dist/session/pty.js.map +1 -1
- package/package.json +1 -1
- package/web/assets/{index-BOqZOoep.js → index-9Z_8xZqk.js} +10 -6
- package/web/assets/index-DheUm5dl.css +1 -0
- package/web/index.html +2 -2
- package/web/assets/index-B2JtCtHa.css +0 -1
|
@@ -16,19 +16,136 @@ export interface AgentProfile {
|
|
|
16
16
|
/** Regex matched against the last non-empty line when status = heuristic. */
|
|
17
17
|
readyHint?: string;
|
|
18
18
|
inject: InjectMode;
|
|
19
|
+
/**
|
|
20
|
+
* How the brief reaches the agent.
|
|
21
|
+
*
|
|
22
|
+
* `flag` - the profile's own args point at `{{brief_path}}`, the way Claude
|
|
23
|
+
* Code's `--append-system-prompt-file` does. The brief is part of the
|
|
24
|
+
* system prompt and the agent never sees it as a turn.
|
|
25
|
+
*
|
|
26
|
+
* `typed` - the CLI has no way to *append* to its system prompt, so the
|
|
27
|
+
* brief is typed into the terminal once the CLI is up, ahead of any opening
|
|
28
|
+
* instruction. Both of the other wired CLIs are in this position, and for
|
|
29
|
+
* the same reason: Codex's `base_instructions` and Gemini's
|
|
30
|
+
* `GEMINI_SYSTEM_MD` each *replace* the whole system prompt rather than add
|
|
31
|
+
* to it, so using either would cost the agent its own tool instructions -
|
|
32
|
+
* a far worse trade than a first turn that arrives as text.
|
|
33
|
+
*
|
|
34
|
+
* `none` - nothing is sent. `shell` is the reason this value exists and it
|
|
35
|
+
* is not a value any agent should want: a shell *executes* what is typed at
|
|
36
|
+
* it, so a brief there is not context, it is a series of commands that fail
|
|
37
|
+
* loudly.
|
|
38
|
+
*
|
|
39
|
+
* Absent means `flag` for a wired agent - what every profile written before
|
|
40
|
+
* this did - and `none` for an unwired one, because `mcp: false` has always
|
|
41
|
+
* meant "a plain terminal" and a profile that declared one should not start
|
|
42
|
+
* having text typed into it. An unwired agent that *is* an agent says
|
|
43
|
+
* `brief = "typed"` and gets the shorter brief: no tool list, because it has
|
|
44
|
+
* no tools, but it is still told its address and still told that a
|
|
45
|
+
* `[from ...]` line is a colleague rather than the human.
|
|
46
|
+
*/
|
|
47
|
+
brief?: 'flag' | 'typed' | 'none';
|
|
19
48
|
/**
|
|
20
49
|
* Argument template used to bring a session back with its prior
|
|
21
50
|
* conversation. `{{uuid}}` is replaced with agent_session_uuid. When absent,
|
|
22
51
|
* the profile is not resumable and restarts clean.
|
|
23
52
|
*/
|
|
24
53
|
resumeArgs?: string[];
|
|
54
|
+
/**
|
|
55
|
+
* Environment for the *detection* probes only, not for a session.
|
|
56
|
+
*
|
|
57
|
+
* Detection runs these CLIs on a machine whose owner may never have run them
|
|
58
|
+
* by hand, so a probe that leaves something behind is the hub writing to
|
|
59
|
+
* somebody's home directory uninvited. `opencode models` does exactly that -
|
|
60
|
+
* it creates ~/.config/opencode/opencode.jsonc - and this is how it is told
|
|
61
|
+
* not to.
|
|
62
|
+
*/
|
|
63
|
+
probeEnv?: Record<string, string>;
|
|
64
|
+
/**
|
|
65
|
+
* How to ask this CLI its version. Its stdout is shown to the user and is
|
|
66
|
+
* also the cache key for the model list, so a CLI that updates underneath
|
|
67
|
+
* us re-lists rather than serving last week's answer.
|
|
68
|
+
*/
|
|
69
|
+
versionArgs?: string[];
|
|
70
|
+
/**
|
|
71
|
+
* How to ask this CLI what models it can be pointed at: one
|
|
72
|
+
* `provider/model` (or bare name) per line on stdout. Absent when the CLI
|
|
73
|
+
* has no such command, which is the common case.
|
|
74
|
+
*/
|
|
75
|
+
modelsArgs?: string[];
|
|
76
|
+
/**
|
|
77
|
+
* The answer for a CLI that cannot be asked. Claude Code is the example:
|
|
78
|
+
* it has no listing command, and its --help documents the aliases instead.
|
|
79
|
+
* Used only when `modelsArgs` is absent or its command fails.
|
|
80
|
+
*/
|
|
81
|
+
models?: string[];
|
|
82
|
+
/**
|
|
83
|
+
* How this agent spells a model on the command line. `{{model}}` carries
|
|
84
|
+
* the value a template chose.
|
|
85
|
+
*
|
|
86
|
+
* A template holds *values*, not argv, because no two of these agents agree:
|
|
87
|
+
* Claude Code takes `--model`, opencode takes `-m provider/model`. So the
|
|
88
|
+
* template says which model and the agent says how to write it down.
|
|
89
|
+
*
|
|
90
|
+
* Absent means the agent takes no model here, and a template that names one
|
|
91
|
+
* for it is a configuration error reported at load rather than a flag
|
|
92
|
+
* silently dropped at launch. The whole fragment disappears when a template
|
|
93
|
+
* leaves the value unset - it does not expand to an empty string.
|
|
94
|
+
*/
|
|
95
|
+
modelArgs?: string[];
|
|
96
|
+
/** The same for effort, with `{{effort}}`. */
|
|
97
|
+
effortArgs?: string[];
|
|
98
|
+
/** The effort levels this agent documents, for the dialog to offer. */
|
|
99
|
+
efforts?: string[];
|
|
25
100
|
}
|
|
26
101
|
/**
|
|
27
102
|
* Built-in profiles. All Claude Code flags here are verified against the CLI:
|
|
28
|
-
* --mcp-config, --
|
|
29
|
-
* --
|
|
103
|
+
* --mcp-config, --session-id, --settings, --append-system-prompt-file,
|
|
104
|
+
* --resume.
|
|
105
|
+
*
|
|
106
|
+
* `--mcp-config` deliberately arrives *without* `--strict-mcp-config`. Strict
|
|
107
|
+
* mode makes the named file the whole of the agent's MCP configuration, which
|
|
108
|
+
* silently drops every server the user set up for themselves — an agent
|
|
109
|
+
* started here would be missing the tools it has everywhere else, with nothing
|
|
110
|
+
* on screen to say why. Without it the hub's server is one more entry beside
|
|
111
|
+
* theirs, which is the only version of "wired to the hub" worth having.
|
|
112
|
+
*
|
|
113
|
+
* Codex and Gemini are wired too, and every flag and key below was verified
|
|
114
|
+
* against the CLI actually installed - codex-cli 0.153.4 and gemini 0.58.0 -
|
|
115
|
+
* rather than written from memory. Both reach the hub the same way Claude
|
|
116
|
+
* Code does, over one streamable-HTTP MCP server carrying a bearer token, and
|
|
117
|
+
* neither needs a byte written to config the user owns:
|
|
118
|
+
*
|
|
119
|
+
* - **Codex** takes `-c <dotted.key>=<toml>` on any invocation, so the server
|
|
120
|
+
* is declared in argv for the one run. The token is *not* in argv - it goes
|
|
121
|
+
* in the environment, and `bearer_token_env_var` names the variable to read
|
|
122
|
+
* it from, which keeps it out of every process listing on the machine.
|
|
123
|
+
* - **Gemini** has no per-run config flag, but
|
|
124
|
+
* `GEMINI_CLI_SYSTEM_SETTINGS_PATH` repoints its system settings layer at a
|
|
125
|
+
* file of our choosing, which the hub generates per session.
|
|
126
|
+
*
|
|
127
|
+
* - **opencode** turned out to be the least invasive of the three and was
|
|
128
|
+
* assumed to be the hardest. It reads its entire config from
|
|
129
|
+
* `OPENCODE_CONFIG_CONTENT`, so nothing is written anywhere at all, and what
|
|
130
|
+
* it is given is merged with the user's own config rather than replacing it.
|
|
131
|
+
* The assumption that it had no per-run route came from reading
|
|
132
|
+
* `opencode mcp add` - which does write to the user's file, and ignores
|
|
133
|
+
* `OPENCODE_CONFIG` when it does - and mistaking that command for the only
|
|
134
|
+
* way in.
|
|
135
|
+
*
|
|
136
|
+
* `shell` is the only profile left that is not an agent, and it is not one in
|
|
137
|
+
* a way no flag can fix: it runs a shell, so text typed at it is executed
|
|
138
|
+
* rather than read.
|
|
30
139
|
*/
|
|
31
140
|
export declare const BUILTIN_PROFILES: Record<string, AgentProfile>;
|
|
141
|
+
/**
|
|
142
|
+
* How this profile's brief travels, with the defaults applied.
|
|
143
|
+
*
|
|
144
|
+
* One place, because three callers need the same answer and the interesting
|
|
145
|
+
* part is the default rather than the field: absent means `flag` for a wired
|
|
146
|
+
* agent and `none` for an unwired one.
|
|
147
|
+
*/
|
|
148
|
+
export declare function briefMode(p: AgentProfile): 'flag' | 'typed' | 'none';
|
|
32
149
|
export declare class ProfileRegistry {
|
|
33
150
|
private profiles;
|
|
34
151
|
constructor(profiles?: Record<string, AgentProfile>);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/agents/profiles.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,0EAA0E;IAC1E,GAAG,EAAE,OAAO,CAAC;IACb,mCAAmC;IACnC,MAAM,EAAE,OAAO,GAAG,WAAW,CAAC;IAC9B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/agents/profiles.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,0EAA0E;IAC1E,GAAG,EAAE,OAAO,CAAC;IACb,mCAAmC;IACnC,MAAM,EAAE,OAAO,GAAG,WAAW,CAAC;IAC9B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAClC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAItB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAIlB;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAkNzD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAEpE;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAA+B;gBAEnC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC;IAInD,oEAAoE;IACpE,MAAM,CAAC,IAAI,IAAI,eAAe;IAyC9B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAIpC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY;IAMjC,IAAI,IAAI,YAAY,EAAE;IAItB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;CAIjC;AAED,+EAA+E;AAC/E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAI5E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,CAElF"}
|
package/dist/agents/profiles.js
CHANGED
|
@@ -9,8 +9,42 @@ function defaultShell() {
|
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Built-in profiles. All Claude Code flags here are verified against the CLI:
|
|
12
|
-
* --mcp-config, --
|
|
13
|
-
* --
|
|
12
|
+
* --mcp-config, --session-id, --settings, --append-system-prompt-file,
|
|
13
|
+
* --resume.
|
|
14
|
+
*
|
|
15
|
+
* `--mcp-config` deliberately arrives *without* `--strict-mcp-config`. Strict
|
|
16
|
+
* mode makes the named file the whole of the agent's MCP configuration, which
|
|
17
|
+
* silently drops every server the user set up for themselves — an agent
|
|
18
|
+
* started here would be missing the tools it has everywhere else, with nothing
|
|
19
|
+
* on screen to say why. Without it the hub's server is one more entry beside
|
|
20
|
+
* theirs, which is the only version of "wired to the hub" worth having.
|
|
21
|
+
*
|
|
22
|
+
* Codex and Gemini are wired too, and every flag and key below was verified
|
|
23
|
+
* against the CLI actually installed - codex-cli 0.153.4 and gemini 0.58.0 -
|
|
24
|
+
* rather than written from memory. Both reach the hub the same way Claude
|
|
25
|
+
* Code does, over one streamable-HTTP MCP server carrying a bearer token, and
|
|
26
|
+
* neither needs a byte written to config the user owns:
|
|
27
|
+
*
|
|
28
|
+
* - **Codex** takes `-c <dotted.key>=<toml>` on any invocation, so the server
|
|
29
|
+
* is declared in argv for the one run. The token is *not* in argv - it goes
|
|
30
|
+
* in the environment, and `bearer_token_env_var` names the variable to read
|
|
31
|
+
* it from, which keeps it out of every process listing on the machine.
|
|
32
|
+
* - **Gemini** has no per-run config flag, but
|
|
33
|
+
* `GEMINI_CLI_SYSTEM_SETTINGS_PATH` repoints its system settings layer at a
|
|
34
|
+
* file of our choosing, which the hub generates per session.
|
|
35
|
+
*
|
|
36
|
+
* - **opencode** turned out to be the least invasive of the three and was
|
|
37
|
+
* assumed to be the hardest. It reads its entire config from
|
|
38
|
+
* `OPENCODE_CONFIG_CONTENT`, so nothing is written anywhere at all, and what
|
|
39
|
+
* it is given is merged with the user's own config rather than replacing it.
|
|
40
|
+
* The assumption that it had no per-run route came from reading
|
|
41
|
+
* `opencode mcp add` - which does write to the user's file, and ignores
|
|
42
|
+
* `OPENCODE_CONFIG` when it does - and mistaking that command for the only
|
|
43
|
+
* way in.
|
|
44
|
+
*
|
|
45
|
+
* `shell` is the only profile left that is not an agent, and it is not one in
|
|
46
|
+
* a way no flag can fix: it runs a shell, so text typed at it is executed
|
|
47
|
+
* rather than read.
|
|
14
48
|
*/
|
|
15
49
|
export const BUILTIN_PROFILES = {
|
|
16
50
|
claude: {
|
|
@@ -20,7 +54,6 @@ export const BUILTIN_PROFILES = {
|
|
|
20
54
|
args: [
|
|
21
55
|
'--mcp-config',
|
|
22
56
|
'{{mcp_config_path}}',
|
|
23
|
-
'--strict-mcp-config',
|
|
24
57
|
'--session-id',
|
|
25
58
|
'{{session_uuid}}',
|
|
26
59
|
'--settings',
|
|
@@ -32,13 +65,25 @@ export const BUILTIN_PROFILES = {
|
|
|
32
65
|
mcp: true,
|
|
33
66
|
status: 'hooks',
|
|
34
67
|
inject: 'bracketed',
|
|
68
|
+
versionArgs: ['--version'],
|
|
69
|
+
/*
|
|
70
|
+
* Claude Code has no listing command, so this is the declared half of
|
|
71
|
+
* "ask where you can, declare where you cannot". Exactly the aliases
|
|
72
|
+
* `claude --help` names for --model; a full name like `claude-fable-5` is
|
|
73
|
+
* accepted too, which is why a template must not be limited to this list.
|
|
74
|
+
*/
|
|
75
|
+
models: ['fable', 'opus', 'sonnet'],
|
|
76
|
+
// Both verified against `claude --help`: --model takes an alias or a full
|
|
77
|
+
// name, --effort takes low, medium, high, xhigh or max.
|
|
78
|
+
modelArgs: ['--model', '{{model}}'],
|
|
79
|
+
effortArgs: ['--effort', '{{effort}}'],
|
|
80
|
+
efforts: ['low', 'medium', 'high', 'xhigh', 'max'],
|
|
35
81
|
// Resume swaps --session-id for --resume; everything else is re-templated
|
|
36
82
|
// identically, and crucially the session is relaunched in the same cwd,
|
|
37
83
|
// because Claude Code keys its conversation store by working directory.
|
|
38
84
|
resumeArgs: [
|
|
39
85
|
'--mcp-config',
|
|
40
86
|
'{{mcp_config_path}}',
|
|
41
|
-
'--strict-mcp-config',
|
|
42
87
|
'--resume',
|
|
43
88
|
'{{session_uuid}}',
|
|
44
89
|
'--settings',
|
|
@@ -47,6 +92,151 @@ export const BUILTIN_PROFILES = {
|
|
|
47
92
|
'{{brief_path}}',
|
|
48
93
|
],
|
|
49
94
|
},
|
|
95
|
+
opencode: {
|
|
96
|
+
id: 'opencode',
|
|
97
|
+
description: 'opencode TUI, wired to the hub MCP endpoint',
|
|
98
|
+
command: 'opencode',
|
|
99
|
+
// Bare, which is its default subcommand and starts the TUI. `run` is the
|
|
100
|
+
// one-shot form and is not what a window on the canvas wants.
|
|
101
|
+
args: [],
|
|
102
|
+
/*
|
|
103
|
+
* The least invasive of the four, and the one that was assumed hardest.
|
|
104
|
+
* opencode reads its whole config from this variable, so there is no file
|
|
105
|
+
* anywhere - not even one of ours - and it is *merged* with the user's own
|
|
106
|
+
* config rather than replacing it, so their models, themes and their own
|
|
107
|
+
* MCP servers survive the session.
|
|
108
|
+
*
|
|
109
|
+
* Note what this deliberately does not use: `opencode mcp add` writes to
|
|
110
|
+
* ~/.config/opencode/opencode.json and ignores OPENCODE_CONFIG while doing
|
|
111
|
+
* it. Setting this variable also stops opencode writing its default config
|
|
112
|
+
* file on start, so a session leaves nothing behind at all.
|
|
113
|
+
*/
|
|
114
|
+
env: { OPENCODE_CONFIG_CONTENT: '{{opencode_config}}' },
|
|
115
|
+
// `opencode models` writes ~/.config/opencode/opencode.jsonc when it finds
|
|
116
|
+
// no config at all, and detection runs on machines whose owner may never
|
|
117
|
+
// have run opencode by hand. An empty config is still a config, so this
|
|
118
|
+
// suppresses that without changing what the probe reports.
|
|
119
|
+
probeEnv: { OPENCODE_CONFIG_CONTENT: '{}' },
|
|
120
|
+
mcp: true,
|
|
121
|
+
brief: 'typed',
|
|
122
|
+
status: 'heuristic',
|
|
123
|
+
inject: 'bracketed',
|
|
124
|
+
versionArgs: ['--version'],
|
|
125
|
+
// Real enumeration: one provider/model per line, 395 of them on the
|
|
126
|
+
// machine this was written on.
|
|
127
|
+
modelsArgs: ['models'],
|
|
128
|
+
// `-m provider/model` is a top-level option, so it applies to the TUI and
|
|
129
|
+
// not only to `run`. Verified against `opencode --help`.
|
|
130
|
+
modelArgs: ['-m', '{{model}}'],
|
|
131
|
+
// No effortArgs on purpose: `--variant` is documented under `opencode run`
|
|
132
|
+
// and is not a top-level option, so the TUI this profile starts does not
|
|
133
|
+
// take one. A template asking for an effort here is refused at load.
|
|
134
|
+
},
|
|
135
|
+
codex: {
|
|
136
|
+
id: 'codex',
|
|
137
|
+
description: 'Codex CLI, wired to the hub MCP endpoint',
|
|
138
|
+
command: 'codex',
|
|
139
|
+
/*
|
|
140
|
+
* Bare, which starts the interactive TUI - `exec` is the one-shot form and
|
|
141
|
+
* is not what a window on the canvas wants.
|
|
142
|
+
*
|
|
143
|
+
* The two `-c` overrides are exactly the table `codex mcp add --url` would
|
|
144
|
+
* have written into ~/.codex/config.toml, except they live for one run and
|
|
145
|
+
* touch nothing. The value after `=` is parsed as TOML, which is why the
|
|
146
|
+
* URL is quoted.
|
|
147
|
+
*/
|
|
148
|
+
args: [
|
|
149
|
+
'-c',
|
|
150
|
+
'mcp_servers.termscape.url="{{mcp_url}}"',
|
|
151
|
+
'-c',
|
|
152
|
+
'mcp_servers.termscape.bearer_token_env_var="TERMSCAPE_TOKEN"',
|
|
153
|
+
],
|
|
154
|
+
// The token is named here rather than written into argv: `-c` values land
|
|
155
|
+
// in the process command line, where every other user on the machine can
|
|
156
|
+
// read them.
|
|
157
|
+
env: { TERMSCAPE_TOKEN: '{{token}}' },
|
|
158
|
+
mcp: true,
|
|
159
|
+
brief: 'typed',
|
|
160
|
+
status: 'heuristic',
|
|
161
|
+
inject: 'bracketed',
|
|
162
|
+
versionArgs: ['--version'],
|
|
163
|
+
/*
|
|
164
|
+
* `codex debug models` does render the real catalog, but it is a debug
|
|
165
|
+
* command by its own description and it answers with 500KB of JSON that
|
|
166
|
+
* also carries every model's system prompt - not the one-per-line stdout
|
|
167
|
+
* `modelsArgs` reads. So this is the declared half of "ask where you can,
|
|
168
|
+
* declare where you cannot": the slugs that catalog marks
|
|
169
|
+
* `visibility: "list"`. A full name not in this list is still accepted,
|
|
170
|
+
* which is why a template must not be limited to it.
|
|
171
|
+
*/
|
|
172
|
+
models: ['gpt-6-astra', 'gpt-5.6-sol', 'gpt-5.6-terra', 'gpt-5.6-luna', 'gpt-5.5', 'gpt-5.2'],
|
|
173
|
+
modelArgs: ['-m', '{{model}}'],
|
|
174
|
+
/*
|
|
175
|
+
* Codex has no `--effort`; reasoning depth is a config key, and it takes
|
|
176
|
+
* the same `-c` route as the MCP server above. Verified by reading it back
|
|
177
|
+
* off the `reasoning effort:` line of the session header.
|
|
178
|
+
*
|
|
179
|
+
* The levels are the union of `supported_reasoning_levels` across the
|
|
180
|
+
* listed models. They are per model in the catalog and Codex forwards
|
|
181
|
+
* whatever it is given without checking, so this list is what the dialog
|
|
182
|
+
* offers and never a limit the hub enforces.
|
|
183
|
+
*/
|
|
184
|
+
effortArgs: ['-c', 'model_reasoning_effort="{{effort}}"'],
|
|
185
|
+
efforts: ['low', 'medium', 'high', 'xhigh', 'max', 'ultra'],
|
|
186
|
+
/*
|
|
187
|
+
* No resumeArgs, and not an oversight. `codex resume` takes a session id,
|
|
188
|
+
* but Codex mints that id itself and offers no way to be handed one, so
|
|
189
|
+
* the hub cannot record up front what it would have to ask for later.
|
|
190
|
+
* `--last` is the alternative and it resolves to "the most recent session
|
|
191
|
+
* in this cwd", which is the wrong agent as soon as a workspace holds two
|
|
192
|
+
* of them. Better to say plainly it restarts clean.
|
|
193
|
+
*/
|
|
194
|
+
},
|
|
195
|
+
gemini: {
|
|
196
|
+
id: 'gemini',
|
|
197
|
+
description: 'Gemini CLI, wired to the hub MCP endpoint',
|
|
198
|
+
command: 'gemini',
|
|
199
|
+
/*
|
|
200
|
+
* Gemini refuses to start MCP servers in a folder it does not trust, and
|
|
201
|
+
* says so only as a warning on stderr - the agent would come up looking
|
|
202
|
+
* fine with no tools. `--skip-trust` trusts the workspace for this session
|
|
203
|
+
* and writes nothing; the alternative, turning folder trust off in the
|
|
204
|
+
* settings file below, would disable the check for everything else too.
|
|
205
|
+
*/
|
|
206
|
+
args: ['--skip-trust'],
|
|
207
|
+
// No `--mcp-config` equivalent exists. This repoints the *system* settings
|
|
208
|
+
// layer - normally a machine-wide file - at the per-session one the hub
|
|
209
|
+
// generates, so ~/.gemini/settings.json is never opened, let alone written.
|
|
210
|
+
env: { GEMINI_CLI_SYSTEM_SETTINGS_PATH: '{{gemini_settings_path}}' },
|
|
211
|
+
mcp: true,
|
|
212
|
+
brief: 'typed',
|
|
213
|
+
status: 'heuristic',
|
|
214
|
+
inject: 'bracketed',
|
|
215
|
+
versionArgs: ['--version'],
|
|
216
|
+
// Declared: there is no `gemini models`. These are the model constants the
|
|
217
|
+
// CLI itself names, minus the ones it uses internally for embeddings and
|
|
218
|
+
// its visual agent, which are not things to point an agent window at.
|
|
219
|
+
models: [
|
|
220
|
+
'gemini-3.1-pro-preview',
|
|
221
|
+
'gemini-3-pro-preview',
|
|
222
|
+
'gemini-3.5-flash',
|
|
223
|
+
'gemini-3-flash',
|
|
224
|
+
'gemini-3.1-flash-lite',
|
|
225
|
+
'gemini-2.5-pro',
|
|
226
|
+
'gemini-2.5-flash',
|
|
227
|
+
],
|
|
228
|
+
modelArgs: ['-m', '{{model}}'],
|
|
229
|
+
/*
|
|
230
|
+
* No effortArgs: `gemini --help` documents no reasoning-effort option, so
|
|
231
|
+
* a template naming one for this agent is refused at load rather than
|
|
232
|
+
* dropped at launch.
|
|
233
|
+
*
|
|
234
|
+
* No resumeArgs either, for a narrower reason than Codex's. `--session-id`
|
|
235
|
+
* does accept a UUID of our choosing, but `--resume` takes "latest" or an
|
|
236
|
+
* index into a list - never that UUID - so the id the hub could record is
|
|
237
|
+
* not an id it could resume by.
|
|
238
|
+
*/
|
|
239
|
+
},
|
|
50
240
|
shell: {
|
|
51
241
|
id: 'shell',
|
|
52
242
|
description: 'Plain terminal, no agent wiring',
|
|
@@ -54,11 +244,29 @@ export const BUILTIN_PROFILES = {
|
|
|
54
244
|
args: [],
|
|
55
245
|
env: {},
|
|
56
246
|
mcp: false,
|
|
247
|
+
// Said out loud rather than left to the default, because this is the one
|
|
248
|
+
// profile where being typed at is actively harmful: a shell runs what it
|
|
249
|
+
// is given. It can still be *sent* a message - the router writes to any
|
|
250
|
+
// running window - and that is the human's business, not the hub's.
|
|
251
|
+
brief: 'none',
|
|
57
252
|
status: 'heuristic',
|
|
58
253
|
readyHint: '[$#>%] ?$',
|
|
59
254
|
inject: 'raw',
|
|
255
|
+
// Nothing to detect: it is whatever COMSPEC or SHELL points at, it is
|
|
256
|
+
// always there, and asking a shell its version means something different
|
|
257
|
+
// on every platform.
|
|
60
258
|
},
|
|
61
259
|
};
|
|
260
|
+
/**
|
|
261
|
+
* How this profile's brief travels, with the defaults applied.
|
|
262
|
+
*
|
|
263
|
+
* One place, because three callers need the same answer and the interesting
|
|
264
|
+
* part is the default rather than the field: absent means `flag` for a wired
|
|
265
|
+
* agent and `none` for an unwired one.
|
|
266
|
+
*/
|
|
267
|
+
export function briefMode(p) {
|
|
268
|
+
return p.brief ?? (p.mcp ? 'flag' : 'none');
|
|
269
|
+
}
|
|
62
270
|
export class ProfileRegistry {
|
|
63
271
|
profiles;
|
|
64
272
|
constructor(profiles) {
|
|
@@ -74,6 +282,10 @@ export class ProfileRegistry {
|
|
|
74
282
|
for (const [id, v] of Object.entries(raw)) {
|
|
75
283
|
if (typeof v !== 'object' || v === null)
|
|
76
284
|
continue;
|
|
285
|
+
// `[template.reviewer]` parses as one table named `template`, and it
|
|
286
|
+
// belongs to TemplateRegistry rather than here.
|
|
287
|
+
if (id === 'template')
|
|
288
|
+
continue;
|
|
77
289
|
const base = merged[id];
|
|
78
290
|
merged[id] = {
|
|
79
291
|
id,
|
|
@@ -85,7 +297,15 @@ export class ProfileRegistry {
|
|
|
85
297
|
status: v.status ?? base?.status ?? 'heuristic',
|
|
86
298
|
readyHint: v.ready_hint ?? v.readyHint ?? base?.readyHint,
|
|
87
299
|
inject: v.inject ?? base?.inject ?? 'bracketed',
|
|
300
|
+
brief: v.brief ?? base?.brief,
|
|
88
301
|
resumeArgs: v.resume_args ?? v.resumeArgs ?? base?.resumeArgs,
|
|
302
|
+
probeEnv: v.probe_env ?? v.probeEnv ?? base?.probeEnv,
|
|
303
|
+
versionArgs: v.version_args ?? v.versionArgs ?? base?.versionArgs,
|
|
304
|
+
modelsArgs: v.models_args ?? v.modelsArgs ?? base?.modelsArgs,
|
|
305
|
+
models: v.models ?? base?.models,
|
|
306
|
+
modelArgs: v.model_args ?? v.modelArgs ?? base?.modelArgs,
|
|
307
|
+
effortArgs: v.effort_args ?? v.effortArgs ?? base?.effortArgs,
|
|
308
|
+
efforts: v.efforts ?? base?.efforts,
|
|
89
309
|
};
|
|
90
310
|
}
|
|
91
311
|
}
|
|
@@ -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":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
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
|
+
* Extra environment for the agent process, merged over what its profile
|
|
38
|
+
* sets. Values only — no expansion of any kind, so a value containing
|
|
39
|
+
* `{{...}}` reaches the process as typed.
|
|
40
|
+
*/
|
|
41
|
+
env: Record<string, string>;
|
|
42
|
+
/**
|
|
43
|
+
* Why this template cannot be used, when it cannot.
|
|
44
|
+
*
|
|
45
|
+
* Kept rather than dropped, for the same reason a missing agent stays in the
|
|
46
|
+
* list: a template that silently vanished looks like the config was ignored.
|
|
47
|
+
* A template asking for an effort on an agent that has no effort setting is
|
|
48
|
+
* a configuration error worth reporting here, at load, and not a flag
|
|
49
|
+
* quietly dropped at launch.
|
|
50
|
+
*/
|
|
51
|
+
error?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Where this one came from, which is what decides whether the panel may
|
|
54
|
+
* edit it.
|
|
55
|
+
*
|
|
56
|
+
* - `derived` — the free template every agent gets under its own name.
|
|
57
|
+
* Nothing is stored for it, so editing one means creating a stored
|
|
58
|
+
* template that shadows it, and there is nothing to remove.
|
|
59
|
+
* - `stored` — made from the panel, in `state.db`. Editable and removable.
|
|
60
|
+
* - `file` — declared in `~/.termscape/agents.toml`. Read-only here: it is
|
|
61
|
+
* the user's file and the hub does not write it.
|
|
62
|
+
*/
|
|
63
|
+
source: TemplateSource;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Check a template against the agent it names.
|
|
67
|
+
*
|
|
68
|
+
* Returns the reason it cannot be used, or null. This is where "the agent
|
|
69
|
+
* declares how to spell it" is enforced: a template holds *values*, and a
|
|
70
|
+
* value nobody can spell on the command line is not a template, it is a typo
|
|
71
|
+
* that would otherwise be discovered at launch.
|
|
72
|
+
*/
|
|
73
|
+
export declare function validate(t: AgentTemplate, profiles: ProfileRegistry): string | null;
|
|
74
|
+
/**
|
|
75
|
+
* What a process will actually accept as a variable name.
|
|
76
|
+
*
|
|
77
|
+
* Deliberately strict rather than permissive: a name with a space or an `=` in
|
|
78
|
+
* it is silently dropped by some shells and rejected by others, and finding
|
|
79
|
+
* that out at launch — as a missing key rather than an error — is exactly the
|
|
80
|
+
* kind of thing templates are validated at load to avoid.
|
|
81
|
+
*/
|
|
82
|
+
export declare function isEnvName(name: string): boolean;
|
|
83
|
+
export declare class TemplateRegistry {
|
|
84
|
+
private readonly templates;
|
|
85
|
+
constructor(templates: Record<string, AgentTemplate>);
|
|
86
|
+
/**
|
|
87
|
+
* One bare template per agent, overlaid with `[template.x]` from
|
|
88
|
+
* ~/.termscape/agents.toml.
|
|
89
|
+
*
|
|
90
|
+
* A broken file falls back to the bare set rather than taking the hub down,
|
|
91
|
+
* exactly as the profile loader does - the two live in the same file, and
|
|
92
|
+
* failing differently for the two halves of it would be its own surprise.
|
|
93
|
+
*/
|
|
94
|
+
static load(profiles: ProfileRegistry, store?: Store): TemplateRegistry;
|
|
95
|
+
get(id: string): AgentTemplate | null;
|
|
96
|
+
list(): AgentTemplate[];
|
|
97
|
+
/** What the browser is given to build the picker from. */
|
|
98
|
+
info(): AgentTemplateInfo[];
|
|
99
|
+
}
|
|
100
|
+
//# 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;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;OAUG;IACH,MAAM,EAAE,cAAc,CAAC;CACxB;AA2BD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,CAAC,EAAE,aAAa,EAChB,QAAQ,EAAE,eAAe,GACxB,MAAM,GAAG,IAAI,CAaf;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/C;AAmBD,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;IA4DvE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAIrC,IAAI,IAAI,aAAa,EAAE;IAIvB,0DAA0D;IAC1D,IAAI,IAAI,iBAAiB,EAAE;CAa5B"}
|