subconscious-cli 0.3.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # subconscious-cli
2
2
 
3
- Log in to Subconscious, then run coding agents with the setup maintained in
4
- [`ol-runbook`](https://github.com/subconscious-systems/ol-runbook).
3
+ Log in to Subconscious, then run coding agents against the Subconscious gateway.
5
4
 
6
5
  ## Quick start
7
6
 
@@ -11,39 +10,35 @@ subc login
11
10
  subc claude
12
11
  ```
13
12
 
14
- Login creates both the saved credential and a ready-to-use `default` runbook
15
- profile, so Claude Code, Codex, and OpenCode can launch immediately. To apply
16
- the persistent runbook setup for all six supported agents together, run:
13
+ Login creates both the saved credential and a ready-to-use `default` profile,
14
+ so Claude Code, Codex, and OpenCode can launch immediately. Persistent editor
15
+ and Pi integrations are installed per agent:
17
16
 
18
17
  ```bash
19
- subc setup
18
+ subc cursor install
19
+ subc copilot install
20
+ subc pi install
21
+ subc <agent> uninstall
20
22
  ```
21
23
 
22
24
  Top-level help (`subc`, `subc help`, or `subc --help`) displays the
23
25
  Subconscious logo as portable ASCII art. Set `NO_COLOR=1` for a
24
26
  monochrome version; redirected output automatically uses a plain wordmark.
25
27
 
26
- Each coding agent also has integration-specific help. These commands only read
27
- the selected profile; they do not authenticate, install, configure, or launch
28
- anything:
28
+ Every command accepts `help` as a subcommand. These only read the selected
29
+ profile; they do not authenticate, install, configure, or launch anything:
29
30
 
30
31
  ```bash
31
- subc help claude
32
+ subc claude help
32
33
  subc codex help
33
- subc opencode --help
34
- subc help cursor
35
- subc help copilot
36
- subc pi -h
34
+ subc cursor help
35
+ subc config help
36
+ subc login help
37
37
  ```
38
38
 
39
- Agent help includes launch/setup behavior, supported integration options, and
39
+ Agent help includes launch/install behavior, supported integration options, and
40
40
  every relevant profile setting with API keys redacted.
41
41
 
42
- This writes the Claude environment file; Codex provider, catalog, and hooks;
43
- OpenCode provider and compaction plugin; Cursor and Copilot hooks; and Pi
44
- provider and compaction extension. It configures integrations but does not
45
- install the underlying desktop applications or agent binaries.
46
-
47
42
  `subc claude` launches the normal `claude` executable with the Subconscious
48
43
  gateway environment applied for that process. Arguments pass through as usual:
49
44
 
@@ -56,21 +51,21 @@ subc pi
56
51
 
57
52
  ## Supported agents
58
53
 
59
- The packaged integrations are synced from `ol-runbook/coding-agents`.
54
+ The packaged integrations live in `cli/bin/runbook`.
60
55
 
61
56
  | Command | Behavior |
62
57
  | --- | --- |
63
58
  | `subc claude` | Launch Claude Code with the runbook environment, context limits, subagent limits, and OTEL usage reporting |
64
- | `subc codex` | Launch Codex with the runbook provider, temporary model catalog, and compaction hooks |
59
+ | `subc codex` | Launch Codex with the runbook provider, temporary model catalog, and surgically merged compaction hooks |
65
60
  | `subc opencode` | Launch OpenCode with the runbook provider, client header, and context/output limits |
66
- | `subc cursor` | Install/update the runbook Cursor conversation and compaction hooks |
67
- | `subc copilot` | Install/update the runbook VS Code custom endpoint and Copilot hooks |
68
- | `subc pi` | Launch Pi with the Subconscious provider and active profile model; never installs or rewrites configuration |
61
+ | `subc cursor install` | Install/update Cursor conversation and compaction hooks |
62
+ | `subc copilot install` | Install/update the VS Code custom endpoint and Copilot hooks |
63
+ | `subc pi install` then `subc pi` | Merge the Pi provider, then launch |
69
64
 
70
65
  If Claude Code, Codex, or OpenCode is missing, an interactive terminal offers
71
- to install it before launching. Pi is launch-only: if its executable or
72
- Subconscious configuration is missing, the CLI exits with instructions instead
73
- of installing or changing anything.
66
+ to install it before launching. Pi requires `subc pi install` first; if its
67
+ executable or Subconscious provider is missing, the CLI exits with instructions
68
+ instead of installing the binary.
74
69
 
75
70
  `subc codex` disables Codex apps and plugin tools for that launch by default so
76
71
  requests remain below the gateway's 128-tool limit. Core coding tools remain
@@ -79,53 +74,33 @@ gateway with a larger tool limit. It also defaults reasoning effort to `max`,
79
74
  which is the highest effort accepted by the Subconscious models; override it
80
75
  with `subc codex --reasoning-effort high` when desired.
81
76
 
82
- Cursor and Copilot are setup commands because their runbook integrations write
83
- user-level configuration. Pi's provider and extension are managed only through
84
- the aggregate setup command:
77
+ Persistent writes are merge/unmerge only. They never replace a user's
78
+ `config.toml`, `opencode.json`, `models.json`, `hooks.json`, or VS Code
79
+ provider list. Remove Subconscious files with the matching uninstall command:
85
80
 
86
81
  ```bash
87
- subc cursor status
88
82
  subc cursor uninstall
89
- subc copilot status
90
- ```
91
-
92
- You can inspect or remove every persistent integration together too:
93
-
94
- ```bash
95
- subc setup
96
- subc setup status
97
- subc setup uninstall
98
- ```
99
-
100
- Target one integration by adding its command name. Agent-specific install
101
- options pass through to that integration:
102
-
103
- ```bash
104
- subc setup codex
105
- subc setup codex status
106
- subc setup opencode uninstall
107
- subc setup codex --subagents
108
- subc setup claude --compact-window 900000
83
+ subc copilot uninstall
84
+ subc pi uninstall
85
+ subc codex uninstall
86
+ subc claude uninstall
87
+ subc opencode uninstall
109
88
  ```
110
89
 
111
- Claude Code and Codex also expose the runbook's persistent environment helpers:
112
-
113
- ```bash
114
- subc setup codex use -- --resume
115
- source <(subc setup codex env)
116
- source <(subc setup codex unset)
117
- ```
90
+ `subc claude uninstall` and `subc opencode uninstall` only clean leftover files
91
+ from older overwrite-style setup. Launch those agents with `subc claude` /
92
+ `subc opencode`; they do not need install.
118
93
 
119
- Run `subc setup AGENT --help` for that integration's complete persistent setup
120
- options. A one-off `--api-key` passed to targeted setup takes precedence for
121
- that command but is not saved to the selected profile.
94
+ Inspect a persistent integration with `subc <agent> status`. A one-off
95
+ `--api-key` passed to install takes precedence for that command but is not
96
+ saved to the selected profile.
122
97
 
123
98
  Cursor still requires enabling its OpenAI API Key Override in Cursor Settings.
124
99
  Copilot requires entering the custom endpoint key once through VS Code's
125
- Manage Language Models UI. The setup scripts print the relevant next steps.
100
+ Manage Language Models UI. The install scripts print the relevant next steps.
126
101
 
127
- The runbook scripts require Bash. Cursor and Copilot setup also require `jq`
128
- and `curl`; Pi setup requires `jq`.
102
+ The runbook scripts require Bash. Cursor, Copilot, Pi, and Codex hook merge
103
+ also require `jq`; Cursor and Copilot also require `curl`.
129
104
 
130
105
  ## Runbook profiles
131
106
 
@@ -137,50 +112,44 @@ and `curl`; Pi setup requires `jq`.
137
112
 
138
113
  The file is mode `600` and contains the shared gateway URL, API key, model,
139
114
  optional per-agent key overrides, and all Claude/Codex/OpenCode/Pi/Copilot
140
- context and output settings used by the packaged runbook scripts. You can
141
- inspect or update it through the CLI:
115
+ context and output settings used by the packaged runbook scripts.
142
116
 
143
117
  ```bash
144
- subc config
145
- subc config --model subconscious/glm-5.2
118
+ subc config # list every profile and its file path
119
+ subc -p staging config # print that path and env file
120
+ subc -p staging config --model subconscious/glm-5.2
146
121
  subc config --gateway-url https://gateway.example
147
122
  subc config path
148
- subc config list
149
- ```
150
-
151
- Use the interactive settings wizard to choose or create a profile and edit
152
- shared settings, one agent's complete settings section, or every setting:
153
-
154
- ```bash
155
- subc settings
156
- subc --profile work settings
157
- subc --profile staging config interactive
123
+ subc config edit # open the selected profile in $VISUAL, $EDITOR, vim, or nano
124
+ subc -p staging config edit vim
125
+ subc config edit nano
158
126
  ```
159
127
 
160
- The wizard validates URLs, numeric ranges, and enumerated values; masks API-key
161
- input; and does not write anything until you choose **Save and exit**. Press
162
- Ctrl-C or choose **Cancel** to discard pending changes. In scripts and CI, keep
163
- using `subc config --gateway-url`, `--api-key`, and `--model` or edit the
164
- mode-`600` profile directly.
128
+ `subc config` lists each profile next to its `.env` path. `subc -p NAME config`
129
+ prints that path, then the file (API keys and other secrets redacted). Extra
130
+ `KEY=value` lines in the file are passed through to launches and override
131
+ Subconscious-injected defaults; resolved login identity (`GATEWAY_URL`,
132
+ `API_KEY`, `MODEL`) still comes from login, `--model`, and the matching flags.
133
+ In scripts and CI, keep using `subc config --gateway-url`, `--api-key`, and
134
+ `--model`.
165
135
 
166
136
  Each agent section can hold its own API key. An agent-specific key takes
167
137
  precedence over the shared profile key and can be used on its own, so profiles
168
138
  do not need an `API_KEY` when every configured agent has an explicit key.
169
139
 
170
- Named profiles work like mbta profiles:
140
+ Named profiles work like AWS CLI profiles:
171
141
 
172
142
  ```bash
173
- subc --profile staging config \
143
+ subc -p staging config \
174
144
  --gateway-url https://staging.example \
175
145
  --api-key sk-staging-... \
176
146
  --model subconscious/glm-5.2
177
147
 
178
- subc --profile staging claude
179
- subc --profile staging setup
148
+ subc -p staging claude
149
+ subc -p staging cursor install
180
150
  ```
181
151
 
182
- You can also select one with `SUBC_PROFILE=staging` (`MBTA_PROFILE` is accepted
183
- as a compatibility fallback). Explicit shell variables
152
+ You can also select one with `SUBC_PROFILE=staging`. Explicit shell variables
184
153
  such as `SUBCONSCIOUS_API_KEY`, `SUBCONSCIOUS_BASE_URL`,
185
154
  `SUBCONSCIOUS_MODEL`, and agent-specific tuning variables override profile
186
155
  values. A command-line `--model` override has the highest model precedence.
@@ -208,8 +177,10 @@ The Claude Code, Codex, OpenCode, Pi, and Copilot integrations register all
208
177
  three models with their native model pickers. The profile's `MODEL` remains the
209
178
  active model where the agent supports setting one and is listed first in the
210
179
  other catalogs. Cursor requires adding the three model IDs in its OpenAI API
211
- Key Override settings; `subc cursor` prints the complete list and the model
212
- selected by the active profile.
180
+ Key Override settings; `subc cursor install` prints the complete list and the model
181
+ selected by the active profile. Use the printed `/v1` Base URL in Cursor
182
+ Settings; the profile itself stores the gateway origin so correlation hooks can
183
+ post to `/v1/agent-hooks`.
213
184
 
214
185
  The default gateway is `https://api.subconscious.dev`. Profiles containing
215
186
  the former exact default (`https://api.subconscious.dev`) migrate automatically;
@@ -223,7 +194,8 @@ SUBCONSCIOUS_BASE_URL=http://localhost:9999 subc claude
223
194
  Agent-specific runbook tuning variables are also honored, including
224
195
  `CLAUDE_CODE_AUTO_COMPACT_WINDOW`, `CODEX_CONTEXT_WINDOW`,
225
196
  `OPENCODE_CONTEXT_LIMIT`, `PI_CONTEXT_WINDOW`, and the corresponding output or
226
- max-context settings.
197
+ max-context settings. Extra `KEY=value` lines in the profile env file are
198
+ passed through the same way and override Subconscious-injected defaults.
227
199
 
228
200
  ## Authentication
229
201
 
package/bin/agents.js CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Coding-agent launcher.
3
3
  *
4
- * `subc <agent>` resolves your saved API key and dispatches the vendored
5
- * ol-runbook integration. Terminal agents launch ephemerally; IDE/config-based
6
- * agents run their setup scripts.
4
+ * `subc <agent>` resolves your saved API key and runs the packaged integration.
5
+ * Terminal agents launch ephemerally; IDE/config-based
6
+ * agents and Pi persist a surgical integration via `subc <agent> install`.
7
7
  *
8
8
  * There is NO hardcoded agent data here: everything is read from
9
9
  * `registry.generated.json` (shipped under `bin/`), which is generated from the
@@ -105,62 +105,61 @@ export function agentList() {
105
105
  }));
106
106
  }
107
107
 
108
- export function setupAgentList() {
109
- return AGENTS.filter((agent) => agent.runbook?.setupScript);
108
+ const SETUP_ACTIONS = new Set(['install', 'status', 'uninstall']);
109
+ const DROPPED_SETUP_HELPERS = new Set(['use', 'env', 'unset']);
110
+
111
+ export function agentSetupActions(agent) {
112
+ return Array.isArray(agent.runbook?.setupActions) ? agent.runbook.setupActions : [];
110
113
  }
111
114
 
112
- const SETUP_ACTIONS = new Set(['install', 'status', 'uninstall']);
113
- const SETUP_HELPER_ACTIONS = new Set(['use', 'env', 'unset']);
114
- const SETUP_HELPER_AGENT_IDS = new Set(['claude-code', 'codex']);
115
-
116
- export function parseSetupRequest(argv = []) {
117
- const [first, ...rest] = argv;
118
- if (!first || SETUP_ACTIONS.has(first)) {
119
- if (rest.length) {
120
- throw new Error('Agent-specific setup options require a target agent');
121
- }
122
- return {
123
- agents: setupAgentList(),
124
- args: first ? [first] : [],
125
- action: first || 'install',
126
- targeted: false,
127
- };
128
- }
115
+ export function agentCommandName(agent) {
116
+ return agent.command || agent.id;
117
+ }
118
+
119
+ export function parseAgentAction(agent, argv = []) {
120
+ const command = agentCommandName(agent);
121
+ const first = argv[0];
122
+ const actions = agentSetupActions(agent);
129
123
 
130
- const agent = resolveAgent(first);
131
- if (!agent) throw new Error(`Unknown coding agent or setup action: ${first}`);
132
- if (!agent.runbook?.setupScript) {
133
- throw new Error(`No persistent setup integration is available for ${agent.name}`);
124
+ if (DROPPED_SETUP_HELPERS.has(first)) {
125
+ throw new Error(
126
+ `${agent.name} no longer supports '${first}'. Launch with subc ${command}.`,
127
+ );
134
128
  }
135
129
 
136
- const requestedAction = rest[0];
137
- const helperAction = SETUP_HELPER_ACTIONS.has(requestedAction);
138
- if (helperAction && !SETUP_HELPER_AGENT_IDS.has(agent.id)) {
139
- throw new Error(`${agent.name} does not support the '${requestedAction}' setup action`);
130
+ if (SETUP_ACTIONS.has(first)) {
131
+ if (!agent.runbook?.setupScript || !actions.includes(first)) {
132
+ if (first === 'install') {
133
+ const uninstallHint = actions.includes('uninstall')
134
+ ? ` To remove leftover files: subc ${command} uninstall.`
135
+ : '';
136
+ throw new Error(
137
+ `${agent.name} is launch-only. Run subc ${command}.${uninstallHint}`,
138
+ );
139
+ }
140
+ throw new Error(
141
+ `${agent.name} does not support '${first}'. Try subc ${command} help.`,
142
+ );
143
+ }
144
+ return { action: first, args: argv };
140
145
  }
141
- if (
142
- requestedAction &&
143
- !requestedAction.startsWith('-') &&
144
- !SETUP_ACTIONS.has(requestedAction) &&
145
- !helperAction
146
- ) {
147
- throw new Error(`Unknown setup action for ${agent.name}: ${requestedAction}`);
146
+
147
+ if (agent.runbook?.mode === 'setup') {
148
+ return { action: 'install', args: argv };
148
149
  }
149
150
 
150
- return {
151
- agents: [agent],
152
- args: rest,
153
- action:
154
- SETUP_ACTIONS.has(requestedAction) || helperAction ? requestedAction : 'install',
155
- targeted: true,
156
- };
151
+ return { action: 'launch', args: argv };
157
152
  }
158
153
 
159
154
  const AGENT_HELP = {
160
155
  'claude-code': {
161
- usage: 'subc [--profile NAME] claude [integration options] [Claude arguments...]',
162
- behavior: 'Launches Claude Code with the active Subconscious profile and model picker.',
156
+ usage: 'subc [-p NAME] claude [help|status|uninstall] [Claude arguments...]',
157
+ behavior:
158
+ 'Launches Claude Code with the active Subconscious profile and model picker. Persistent files are leftover-only: subc claude uninstall.',
163
159
  options: [
160
+ ['help', 'Show this help'],
161
+ ['status', 'Inspect leftover ~/.claude/subconscious-gateway.env'],
162
+ ['uninstall', 'Remove leftover ~/.claude/subconscious-gateway.env'],
164
163
  ['--model MODEL', 'Override the profile model for this launch'],
165
164
  ['--compact-window N', 'Override the Claude auto-compact window'],
166
165
  ['--max-context-tokens N', 'Override the maximum context tokens'],
@@ -168,9 +167,14 @@ const AGENT_HELP = {
168
167
  ],
169
168
  },
170
169
  codex: {
171
- usage: 'subc [--profile NAME] codex [integration options] [Codex arguments...]',
172
- behavior: 'Launches Codex with a temporary Subconscious provider catalog and compaction hooks.',
170
+ usage: 'subc [-p NAME] codex [help|install|status|uninstall] [Codex arguments...]',
171
+ behavior:
172
+ 'Launches Codex with a temporary Subconscious provider catalog. Compaction hooks are merged into ~/.codex/hooks.json and removed with subc codex uninstall.',
173
173
  options: [
174
+ ['help', 'Show this help'],
175
+ ['install', 'Install only the Subconscious compaction hooks'],
176
+ ['status', 'Inspect the installed compaction hooks'],
177
+ ['uninstall', 'Remove only the Subconscious Codex hooks'],
174
178
  ['--model MODEL', 'Override the profile model for this launch'],
175
179
  ['--context-window N', 'Override catalog context_window'],
176
180
  ['--max-context-window N', 'Override catalog max_context_window'],
@@ -182,35 +186,47 @@ const AGENT_HELP = {
182
186
  ],
183
187
  },
184
188
  opencode: {
185
- usage: 'subc [--profile NAME] opencode [OpenCode arguments...]',
186
- behavior: 'Launches OpenCode with an ephemeral provider containing every Subconscious model.',
189
+ usage: 'subc [-p NAME] opencode [help|status|uninstall] [OpenCode arguments...]',
190
+ behavior:
191
+ 'Launches OpenCode with an ephemeral provider containing every Subconscious model. Persistent files are leftover-only: subc opencode uninstall.',
187
192
  options: [
193
+ ['help', 'Show this help'],
194
+ ['status', 'Inspect leftover OpenCode Subconscious config'],
195
+ ['uninstall', 'Remove only the Subconscious OpenCode provider and plugin'],
188
196
  ['--model MODEL', 'Override the profile model for this launch'],
189
197
  ['ARGS...', 'Pass arguments directly to OpenCode'],
190
198
  ],
191
199
  },
192
200
  cursor: {
193
- usage: 'subc [--profile NAME] cursor [install|status|uninstall]',
194
- behavior: 'Manages Cursor correlation hooks; model endpoint setup is completed in Cursor Settings.',
201
+ usage: 'subc [-p NAME] cursor [help|install|status|uninstall]',
202
+ behavior:
203
+ 'Manages Cursor correlation hooks; model endpoint setup is completed in Cursor Settings.',
195
204
  options: [
205
+ ['help', 'Show this help'],
196
206
  ['install', 'Install or update the Cursor hooks (default action)'],
197
207
  ['status', 'Inspect the installed hook configuration'],
198
208
  ['uninstall', 'Remove only the Subconscious Cursor hooks'],
199
209
  ],
200
210
  },
201
211
  copilot: {
202
- usage: 'subc [--profile NAME] copilot [install|status|uninstall]',
212
+ usage: 'subc [-p NAME] copilot [help|install|status|uninstall]',
203
213
  behavior: 'Manages the VS Code model provider and Copilot correlation hooks.',
204
214
  options: [
215
+ ['help', 'Show this help'],
205
216
  ['install', 'Install or update the provider and hooks (default action)'],
206
217
  ['status', 'Inspect the installed provider and hooks'],
207
218
  ['uninstall', 'Remove the Subconscious provider and hooks'],
208
219
  ],
209
220
  },
210
221
  pi: {
211
- usage: 'subc [--profile NAME] pi [Pi arguments...]',
212
- behavior: 'Launches Pi read-only against the provider previously configured by subc setup.',
222
+ usage: 'subc [-p NAME] pi [help|install|status|uninstall] [Pi arguments...]',
223
+ behavior:
224
+ 'Launches Pi read-only against the provider previously configured by subc pi install.',
213
225
  options: [
226
+ ['help', 'Show this help'],
227
+ ['install', 'Merge the Subconscious provider into ~/.pi/agent/models.json'],
228
+ ['status', 'Inspect the persistent Pi provider'],
229
+ ['uninstall', 'Remove only the Subconscious Pi provider and extension'],
214
230
  ['--model MODEL', 'Override the profile model for this launch'],
215
231
  ['ARGS...', 'Pass arguments directly to Pi'],
216
232
  ],
@@ -256,9 +272,21 @@ export function printAgentHelp(agent, profile) {
256
272
  console.log(` ${c.cyan}${setting.key.padEnd(settingWidth)}${c.reset} ${value}`);
257
273
  console.log(` ${' '.repeat(settingWidth)} ${c.dim}${setting.description}${c.reset}`);
258
274
  }
259
- console.log(`\n Edit these interactively with ${c.cyan}subc --profile ${profile?.name || 'default'} settings${c.reset}.`);
260
- if (agent.runbook?.setupScript) {
261
- console.log(` Apply persistent integration setup with ${c.cyan}subc setup ${agent.command || agent.id}${c.reset}.`);
275
+ const command = agentCommandName(agent);
276
+ const profileFlag = profile?.name || 'default';
277
+ console.log(
278
+ `\n Edit the env file with ${c.cyan}subc -p ${profileFlag} config edit${c.reset}.`,
279
+ );
280
+ const actions = agentSetupActions(agent);
281
+ if (actions.includes('install')) {
282
+ console.log(
283
+ ` Install the persistent integration with ${c.cyan}subc ${command} install${c.reset}.`,
284
+ );
285
+ }
286
+ if (actions.includes('uninstall')) {
287
+ console.log(
288
+ ` Remove it with ${c.cyan}subc ${command} uninstall${c.reset}.`,
289
+ );
262
290
  }
263
291
  console.log();
264
292
  }
@@ -488,7 +516,7 @@ async function ensureInstalled(agent) {
488
516
  process.exit(0);
489
517
  }
490
518
 
491
- /** Resolve and validate a script inside the packaged ol-runbook snapshot. */
519
+ /** Resolve and validate a script inside the packaged runbook directory. */
492
520
  function runbookScriptPath(agent, relativeScript = agent.runbook.script) {
493
521
  const script = path.resolve(RUNBOOK_DIR, relativeScript);
494
522
  const relative = path.relative(RUNBOOK_DIR, script);
@@ -507,7 +535,7 @@ function spawnRunbook(agent, args, env, relativeScript) {
507
535
  child.on('error', (error) => {
508
536
  if (error.code === 'ENOENT') {
509
537
  reject(
510
- new Error('The ol-runbook integrations require `bash`, but it was not found on PATH.'),
538
+ new Error('These coding-agent integrations require `bash`, but it was not found on PATH.'),
511
539
  );
512
540
  return;
513
541
  }
@@ -526,7 +554,7 @@ function spawnRunbook(agent, args, env, relativeScript) {
526
554
  }
527
555
 
528
556
  function isSetupWithoutAuth(argv) {
529
- return ['status', 'uninstall', 'use', 'env', 'unset', '-h', '--help'].includes(argv[0]);
557
+ return ['status', 'uninstall', '-h', '--help', 'help'].includes(argv[0]);
530
558
  }
531
559
 
532
560
  function optionValue(argv, name) {
@@ -593,20 +621,20 @@ function claudeModelPickerEnv(agent, ctx) {
593
621
  );
594
622
  }
595
623
 
596
- function runbookEnv(apiKey, model, binDir, profile, agent) {
624
+ export function runbookEnv(apiKey, model, binDir, profile, agent) {
597
625
  const ctx = buildContext(apiKey, model, profile);
598
626
  const extraDirs = [binDir, ...candidateBinDirs()].filter(Boolean);
599
627
  const specificApiKey = agentApiKeySetting(agent)?.key;
600
628
  return {
629
+ ...claudeModelPickerEnv(agent, ctx),
601
630
  ...(profile?.values || {}),
602
631
  ...process.env,
603
- ...claudeModelPickerEnv(agent, ctx),
604
632
  GATEWAY_URL: ctx.baseUrl,
605
633
  API_KEY: apiKey,
606
634
  ...(specificApiKey ? { [specificApiKey]: apiKey } : {}),
607
635
  MODEL: model,
608
636
  SUBCONSCIOUS_MODELS: SUPPORTED_MODELS.join('\n'),
609
- MBTA_ENV_FILE: os.devNull,
637
+ SUBC_ENV_FILE: os.devNull,
610
638
  PATH: augmentPath(extraDirs),
611
639
  };
612
640
  }
@@ -616,7 +644,7 @@ async function runRunbookSetup(agent, argv, profile, relativeScript = agent.runb
616
644
  return spawnRunbook(agent, argv, {
617
645
  ...(profile?.values || {}),
618
646
  ...process.env,
619
- MBTA_ENV_FILE: os.devNull,
647
+ SUBC_ENV_FILE: os.devNull,
620
648
  }, relativeScript);
621
649
  }
622
650
 
@@ -638,19 +666,7 @@ async function runRunbookSetup(agent, argv, profile, relativeScript = agent.runb
638
666
  const installed = !['status', 'uninstall'].includes(rest[0]);
639
667
  if (code !== 0 || !installed) return code;
640
668
 
641
- if (agent.id === 'cursor') {
642
- const modelList = SUPPORTED_MODELS.map(
643
- (supportedModel) => ` ${c.cyan}${supportedModel}${c.reset}`,
644
- ).join('\n');
645
- console.log(
646
- `\n ${c.bold}Finish in Cursor Settings${c.reset}\n` +
647
- ` Enable OpenAI API Key Override, then use:\n` +
648
- ` Base URL: ${c.cyan}${ctx.baseUrl}${c.reset}\n` +
649
- ` Add the available custom models:\n${modelList}\n` +
650
- ` Select ${c.cyan}${model}${c.reset} for this profile.\n` +
651
- ` Paste your Subconscious API key there, then fully restart Cursor.\n`,
652
- );
653
- } else if (agent.id === 'pi') {
669
+ if (agent.id === 'pi') {
654
670
  console.log(`\n ${c.dim}Start a fresh session with ${c.reset}${c.cyan}subc pi${c.reset}${c.dim}.${c.reset}\n`);
655
671
  }
656
672
  return code;
@@ -662,18 +678,34 @@ async function runRunbookSetup(agent, argv, profile, relativeScript = agent.runb
662
678
  */
663
679
  export async function runAgent(agent, argv, options = {}) {
664
680
  const profile = options.profile;
665
- if (options.setup) {
666
- if (!agent.runbook?.setupScript) {
667
- throw new Error(`No setup integration is available for ${agent.name}`);
668
- }
669
- return runRunbookSetup(agent, argv, profile, agent.runbook.setupScript);
670
- }
671
681
  if (isAgentHelpRequest(argv)) {
672
682
  printAgentHelp(agent, profile);
673
683
  return 0;
674
684
  }
675
- if (agent.runbook?.mode === 'setup') {
676
- return runRunbookSetup(agent, argv, profile);
685
+
686
+ const parsed = parseAgentAction(agent, argv);
687
+ if (parsed.action !== 'launch') {
688
+ if (!agent.runbook?.setupScript) {
689
+ throw new Error(`No persistent integration is available for ${agent.name}`);
690
+ }
691
+ const setupArgs =
692
+ parsed.args[0] === parsed.action ? parsed.args : [parsed.action, ...parsed.args];
693
+ const code = await runRunbookSetup(
694
+ agent,
695
+ setupArgs,
696
+ profile,
697
+ agent.runbook.setupScript,
698
+ );
699
+ if (code === 0) {
700
+ const message =
701
+ parsed.action === 'status'
702
+ ? `${agent.name} status check complete.`
703
+ : parsed.action === 'uninstall'
704
+ ? `${agent.name} integration removed.`
705
+ : `${agent.name} setup complete.`;
706
+ console.log(`\n ${c.green}${c.bold}✓ ${message}${c.reset}\n`);
707
+ }
708
+ return code;
677
709
  }
678
710
 
679
711
  const { model, rest } = extractModel(argv, profile);
@@ -699,9 +731,9 @@ export async function runAgent(agent, argv, options = {}) {
699
731
  // if it was installed into a dir not yet on the parent shell's PATH.
700
732
  const extraDirs = [binDir, ...candidateBinDirs()].filter(Boolean);
701
733
  const env = {
734
+ ...envMap,
702
735
  ...(profile?.values || {}),
703
736
  ...process.env,
704
- ...envMap,
705
737
  PATH: augmentPath(extraDirs),
706
738
  };
707
739
  const args = [...launchArgs, ...rest];