@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.
Files changed (89) hide show
  1. package/README.md +211 -79
  2. package/dist/agents/detect.d.ts +27 -0
  3. package/dist/agents/detect.d.ts.map +1 -0
  4. package/dist/agents/detect.js +210 -0
  5. package/dist/agents/detect.js.map +1 -0
  6. package/dist/agents/profiles.d.ts +119 -2
  7. package/dist/agents/profiles.d.ts.map +1 -1
  8. package/dist/agents/profiles.js +224 -4
  9. package/dist/agents/profiles.js.map +1 -1
  10. package/dist/agents/templates.d.ts +100 -0
  11. package/dist/agents/templates.d.ts.map +1 -0
  12. package/dist/agents/templates.js +165 -0
  13. package/dist/agents/templates.js.map +1 -0
  14. package/dist/agents/wiring.d.ts +30 -1
  15. package/dist/agents/wiring.d.ts.map +1 -1
  16. package/dist/agents/wiring.js +182 -10
  17. package/dist/agents/wiring.js.map +1 -1
  18. package/dist/cli.js +51 -14
  19. package/dist/cli.js.map +1 -1
  20. package/dist/db/migrations.d.ts.map +1 -1
  21. package/dist/db/migrations.js +73 -0
  22. package/dist/db/migrations.js.map +1 -1
  23. package/dist/db/store.d.ts +53 -1
  24. package/dist/db/store.d.ts.map +1 -1
  25. package/dist/db/store.js +118 -5
  26. package/dist/db/store.js.map +1 -1
  27. package/dist/hub.d.ts +264 -6
  28. package/dist/hub.d.ts.map +1 -1
  29. package/dist/hub.js +549 -33
  30. package/dist/hub.js.map +1 -1
  31. package/dist/hub.tgz +0 -0
  32. package/dist/mcp/server.d.ts +3 -0
  33. package/dist/mcp/server.d.ts.map +1 -1
  34. package/dist/mcp/server.js +27 -2
  35. package/dist/mcp/server.js.map +1 -1
  36. package/dist/protocol/domain.d.ts +88 -0
  37. package/dist/protocol/domain.d.ts.map +1 -1
  38. package/dist/protocol/domain.js +114 -0
  39. package/dist/protocol/domain.js.map +1 -1
  40. package/dist/protocol/mcp-tools.d.ts +43 -0
  41. package/dist/protocol/mcp-tools.d.ts.map +1 -1
  42. package/dist/protocol/mcp-tools.js +65 -0
  43. package/dist/protocol/mcp-tools.js.map +1 -1
  44. package/dist/protocol/peer.d.ts +38 -1
  45. package/dist/protocol/peer.d.ts.map +1 -1
  46. package/dist/protocol/peer.js +41 -2
  47. package/dist/protocol/peer.js.map +1 -1
  48. package/dist/protocol/ws.d.ts +259 -0
  49. package/dist/protocol/ws.d.ts.map +1 -1
  50. package/dist/protocol/ws.js +169 -5
  51. package/dist/protocol/ws.js.map +1 -1
  52. package/dist/remote/deployer.d.ts.map +1 -1
  53. package/dist/remote/deployer.js +15 -2
  54. package/dist/remote/deployer.js.map +1 -1
  55. package/dist/remote/join-script.d.ts.map +1 -1
  56. package/dist/remote/join-script.js +34 -2
  57. package/dist/remote/join-script.js.map +1 -1
  58. package/dist/remote/lan.d.ts +73 -5
  59. package/dist/remote/lan.d.ts.map +1 -1
  60. package/dist/remote/lan.js +119 -10
  61. package/dist/remote/lan.js.map +1 -1
  62. package/dist/remote/peer-serve.d.ts.map +1 -1
  63. package/dist/remote/peer-serve.js +32 -3
  64. package/dist/remote/peer-serve.js.map +1 -1
  65. package/dist/remote/peer.d.ts +7 -0
  66. package/dist/remote/peer.d.ts.map +1 -1
  67. package/dist/remote/peer.js +22 -0
  68. package/dist/remote/peer.js.map +1 -1
  69. package/dist/remote/registry.d.ts +70 -2
  70. package/dist/remote/registry.d.ts.map +1 -1
  71. package/dist/remote/registry.js +134 -10
  72. package/dist/remote/registry.js.map +1 -1
  73. package/dist/server.d.ts +22 -3
  74. package/dist/server.d.ts.map +1 -1
  75. package/dist/server.js +239 -117
  76. package/dist/server.js.map +1 -1
  77. package/dist/session/manager.d.ts +60 -4
  78. package/dist/session/manager.d.ts.map +1 -1
  79. package/dist/session/manager.js +198 -41
  80. package/dist/session/manager.js.map +1 -1
  81. package/dist/session/pty.d.ts +19 -0
  82. package/dist/session/pty.d.ts.map +1 -1
  83. package/dist/session/pty.js +84 -1
  84. package/dist/session/pty.js.map +1 -1
  85. package/package.json +1 -1
  86. package/web/assets/{index-BOqZOoep.js → index-9Z_8xZqk.js} +10 -6
  87. package/web/assets/index-DheUm5dl.css +1 -0
  88. package/web/index.html +2 -2
  89. 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, --strict-mcp-config, --session-id, --settings,
29
- * --append-system-prompt-file, --resume.
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;CACvB;AAOD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CA8CzD,CAAC;AAEF,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;IA8B9B,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"}
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"}
@@ -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, --strict-mcp-config, --session-id, --settings,
13
- * --append-system-prompt-file, --resume.
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":"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"}
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;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,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,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,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"}