@callstack/apex 0.2.2 → 0.3.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 +240 -27
- package/bin/apex.js +11 -2
- package/dist/cli.js +4994 -0
- package/package.json +26 -8
- package/src/assistants/aiSdk.js +0 -54
- package/src/assistants/claudeCode.js +0 -37
- package/src/assistants/codex.js +0 -56
- package/src/assistants/cursor.js +0 -30
- package/src/assistants/index.js +0 -11
- package/src/assistants/opencode.js +0 -103
- package/src/assistants/pi.js +0 -55
- package/src/assistants/vscodeCopilot.js +0 -34
- package/src/cli.js +0 -89
- package/src/init.js +0 -91
- package/src/util/detect.js +0 -49
- package/src/util/fsHelpers.js +0 -57
- package/src/util/prompt.js +0 -74
- package/src/util/toml.js +0 -35
package/README.md
CHANGED
|
@@ -1,49 +1,262 @@
|
|
|
1
1
|
# Apex CLI
|
|
2
2
|
|
|
3
|
-
Configures the AI coding assistants
|
|
4
|
-
[Callstack Apex](https://apex.callstack.com/).
|
|
3
|
+
Configures the AI coding assistants on your machine to use
|
|
4
|
+
[Callstack Apex](https://apex.callstack.com/) (`callstack/Apex`).
|
|
5
|
+
|
|
6
|
+
`apex init` detects the assistants on your machine, lets you pick which ones to configure,
|
|
7
|
+
shows every change it wants to make, and only then writes. Nothing changes until you say so.
|
|
5
8
|
|
|
6
9
|
## Install
|
|
7
10
|
|
|
11
|
+
Requires Node.js 22+ and npm. Nothing to install first:
|
|
12
|
+
|
|
8
13
|
```sh
|
|
9
14
|
npx @callstack/apex init
|
|
10
15
|
```
|
|
11
16
|
|
|
12
|
-
|
|
17
|
+
An npx run leaves no `apex` command behind, so after setup it offers to install the same version
|
|
18
|
+
globally (`npm install -g @callstack/apex`), which is what makes `apex undo` and `apex run codex`
|
|
19
|
+
work later; the rest of this README uses that short form. Say no, or run non-interactively, and
|
|
20
|
+
every next step Apex CLI prints is spelled `npx @callstack/apex …` instead. Uninstalling does not
|
|
21
|
+
undo your configs, so run `apex undo` first if you want them back.
|
|
22
|
+
|
|
23
|
+
## Commands
|
|
24
|
+
|
|
25
|
+
| Command | What it does | Writes by default? |
|
|
26
|
+
| --- | --- | --- |
|
|
27
|
+
| `apex detect [--json]` | Finds assistants on `PATH`, in config directories and in macOS `/Applications`; shows what would change | No, never |
|
|
28
|
+
| `apex init` | Interactive setup: multiselect of detected assistants, colourised change preview, confirmation | Only after you confirm |
|
|
29
|
+
| `apex init --no-interactive` | Prints the plan without asking questions | No |
|
|
30
|
+
| `apex init --apply` | Writes the planned changes without asking | Yes |
|
|
31
|
+
| `apex undo` | Reverts the most recent Apex CLI setup, with the same preview and confirmation | Only after you confirm |
|
|
32
|
+
| `apex undo --list` | Shows recorded setups and which are already undone (`--json` prints the journal) | No |
|
|
33
|
+
| `apex run <assistant> [-- <args>]` | Launches the assistant with the gateway, model and credentials in the child environment | No |
|
|
34
|
+
| `apex completion <zsh\|bash\|fish>` | Prints a shell completion script | No |
|
|
13
35
|
|
|
14
|
-
|
|
15
|
-
to point at Apex, backing up any existing file first (`<file>.bak-<timestamp>`):
|
|
36
|
+
Each command accepts only its own flags, and `--help` and the shell completions list exactly those:
|
|
16
37
|
|
|
17
|
-
|
|
|
38
|
+
| Command | Flags |
|
|
18
39
|
| --- | --- |
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
40
|
+
| `init` | `--assistants <ids>`, `--no-interactive`, `--apply`, `--no-diff`, `--json`, `--help` |
|
|
41
|
+
| `detect` | `--json`, `--help` |
|
|
42
|
+
| `undo` | `--no-interactive`, `--apply`, `--no-diff`, `--json`, `--list`, `--help` |
|
|
43
|
+
|
|
44
|
+
`apex init --wat` fails fast, and so does a flag in the wrong command
|
|
45
|
+
(`apex detect --no-diff`). Only `--apply` writes, so there is no "preview *and* write" to argue
|
|
46
|
+
about. `--assistants <ids>` is a comma list of `opencode`, `codex`,
|
|
47
|
+
`claude`, `pi`, `cursor`, `copilot`, `ai-sdk`.
|
|
26
48
|
|
|
27
|
-
|
|
49
|
+
Non-interactive callers (`--no-interactive`, `--json`, pipes, CI) never get a prompt and never
|
|
50
|
+
have files changed unless they also pass `--apply`. `--json` prints a machine-readable plan with
|
|
51
|
+
`mode`, `applied`, `appliedPaths`, per-file `changes` and `nextSteps` instead of the human UI. If a
|
|
52
|
+
write fails halfway through a batch, the payload still reports what already landed plus the `error`,
|
|
53
|
+
and the exit code is 1.
|
|
54
|
+
|
|
55
|
+
### Shell completion
|
|
28
56
|
|
|
29
57
|
```sh
|
|
30
|
-
|
|
31
|
-
#
|
|
32
|
-
|
|
58
|
+
apex completion zsh > "${fpath[1]}/_apex" # then rehash
|
|
59
|
+
apex completion bash >> ~/.bashrc # then source ~/.bashrc
|
|
60
|
+
apex completion fish > ~/.config/fish/completions/apex.fish
|
|
33
61
|
```
|
|
34
62
|
|
|
35
|
-
|
|
36
|
-
`--skip <ids>` (comma-separated, see `apex list` for ids).
|
|
63
|
+
## What a review looks like
|
|
37
64
|
|
|
38
|
-
|
|
65
|
+
```
|
|
66
|
+
┌────────────────────────────────────────────────────────────────────────────┐
|
|
67
|
+
│ Apex CLI · Configure callstack/Apex for your favorite harness │
|
|
68
|
+
│ │
|
|
69
|
+
│ Nothing is written until you confirm. │
|
|
70
|
+
└────────────────────────────────────────────────────────────────────────────┘
|
|
71
|
+
│
|
|
72
|
+
◆ Set up callstack/Apex for which assistants? (space toggles, enter confirms)
|
|
73
|
+
│ OpenCode, Codex
|
|
74
|
+
│
|
|
75
|
+
◇ Set up callstack/Apex for which assistants? (space toggles, enter confirms)
|
|
76
|
+
│ OpenCode, Codex
|
|
39
77
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
78
|
+
|
|
79
|
+
Planned changes:
|
|
80
|
+
|
|
81
|
+
Update ~/.config/opencode/opencode.json
|
|
82
|
+
--- ~/.config/opencode/opencode.json
|
|
83
|
+
+++ ~/.config/opencode/opencode.json
|
|
84
|
+
@@ -1,4 +1,19 @@
|
|
85
|
+
{
|
|
86
|
+
// keep this comment
|
|
87
|
+
- "theme": "dark"
|
|
88
|
+
+ "theme": "dark",
|
|
89
|
+
+ "provider": {
|
|
90
|
+
+ "callstack.ai": { … }
|
|
91
|
+
+ }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
Create ~/.codex/callstack_ai.config.toml
|
|
95
|
+
--- /dev/null
|
|
96
|
+
+++ ~/.codex/callstack_ai.config.toml
|
|
97
|
+
@@ -0,0 +1,10 @@
|
|
98
|
+
+model_provider = "callstack_ai"
|
|
99
|
+
|
|
100
|
+
Existing files get a .apex-backup-<id> copy first. (dimmed)
|
|
101
|
+
│
|
|
102
|
+
◇ Apply these changes?
|
|
103
|
+
✔ ~/.config/opencode/opencode.json backup: opencode.json.apex-backup-b4c42657
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
Environment
|
|
107
|
+
|
|
108
|
+
✓ CALLSTACK_AUTH_TOKEN is set in this shell
|
|
109
|
+
Apex CLI never reads, stores or logs the key itself.
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
Use these commands to run callstack/Apex with your selected harnesses:
|
|
113
|
+
|
|
114
|
+
apex run opencode opencode --model callstack.ai/callstack/Apex (dimmed)
|
|
115
|
+
apex run codex codex --profile callstack_ai
|
|
116
|
+
|
|
117
|
+
...or pick "callstack/Apex" from the UI when setting up manually.
|
|
118
|
+
For more instructions, visit:
|
|
119
|
+
https://app.notion.com/p/callstack/Apex-how-to-use-it-36d5d027c0f880e99d03d1c37a77382f
|
|
120
|
+
|
|
121
|
+
If you want to undo the changes, run apex undo
|
|
122
|
+
```
|
|
123
|
+
`Environment` only shows the `export CALLSTACK_AUTH_TOKEN=…` line while the variable is missing; once
|
|
124
|
+
it is set you get a green `✓ CALLSTACK_AUTH_TOKEN is set in this shell` instead. The closing block shows
|
|
125
|
+
what each `apex run` expands to, links the guide (the URL is never folded, so it stays clickable), and
|
|
126
|
+
mentions `apex undo` only when something was actually written.
|
|
127
|
+
|
|
128
|
+
The diff is the change list: it only shows the lines that actually move, paths are shortened to
|
|
129
|
+
`~/…`, and values under keys like `apiKey`, `token` or `secret` are redacted, so a preview can be
|
|
130
|
+
pasted into a ticket safely. A file Apex CLI created diffs from `/dev/null`, and one it is deleting
|
|
131
|
+
diffs to `/dev/null`. `--no-diff` swaps the diff for one `+ key value` row per setting.
|
|
132
|
+
|
|
133
|
+
## Reversing changes
|
|
134
|
+
|
|
135
|
+
`apex undo` re-applies the inverse of the last setup, named by the time it ran: files Apex CLI
|
|
136
|
+
created are deleted, files it edited go back to their pre-setup bytes. It only touches a file whose current content still hashes
|
|
137
|
+
to what Apex CLI wrote; anything you edited afterwards is left alone and reported. A setup whose
|
|
138
|
+
remaining files can only be left alone does not block the older ones: the next `apex undo` moves on
|
|
139
|
+
to the most recent setup that still has something to restore. Restores create
|
|
140
|
+
their own backup first, so an undo is itself reversible. Apex CLI records each batch in
|
|
141
|
+
`$APEX_STATE_DIR/journal.json` (default `~/.local/state/apex/journal.json`, mode `0600`); the last
|
|
142
|
+
20 batches are kept. Deleting the journal only forgets the history, it never changes a config.
|
|
143
|
+
|
|
144
|
+
## Integrations
|
|
145
|
+
|
|
146
|
+
| Assistant | Configuration | Behavior |
|
|
147
|
+
| --- | --- | --- |
|
|
148
|
+
| OpenCode | `~/.config/opencode/opencode.json` or `.jsonc` | Adds `provider.callstack.ai`, OpenAI-compatible transport, model and environment-key reference; preserves the default model. A config already in OpenCode 2's `providers` format gets the v2 entry instead, and you add the key with `/connect`. |
|
|
149
|
+
| Codex 0.134.0+ | `~/.codex/callstack_ai.config.toml` | Adds a self-contained Responses API provider/profile; leaves base config and default model untouched. |
|
|
150
|
+
| Claude Code | `~/.claude/settings.json` | Merges attribution flag only; use `apex run claude` for gateway credentials and model selection. |
|
|
151
|
+
| Pi | `~/.pi/agent/models.json` and `settings.json` | Adds `providers.callstack` with Chat Completions, Apex and `$CALLSTACK_AUTH_TOKEN`; saves `medium` as Apex's per-model thinking default for direct launches. Preserves other models and their defaults. Requires a Pi version supporting `$VAR` key interpolation and `modelThinkingLevels`. |
|
|
152
|
+
| Cursor | Guided setup | Prints endpoint, API-key and custom-model steps; does not modify private editor storage. |
|
|
153
|
+
| VS Code / Copilot | Guided setup | Detects VS Code, not whether Copilot is installed; prints custom-endpoint steps and model JSON, retaining the editor-generated secret reference. |
|
|
154
|
+
| Vercel AI SDK / Eve | Guided setup | Detected from the `package.json` in the directory you run Apex CLI from (`ai`, `@ai-sdk/openai` or `eve`); prints the connector snippet, which reads the key from `CALLSTACK_AUTH_TOKEN`. Nothing is written into the project. |
|
|
155
|
+
|
|
156
|
+
Apex configs declare tool calling, image input, and the supported
|
|
157
|
+
`none`/`low`/`medium`/`xhigh` reasoning efforts (default `medium`) where supported.
|
|
158
|
+
OpenCode, Pi, Copilot, Claude's launcher, and the AI SDK guidance retain a 32,768-token output
|
|
159
|
+
budget. OpenCode, Pi, Codex, Copilot, and Claude's launcher declare the model's native
|
|
160
|
+
262,144-token context window using each app's documented fields. Input limits and compaction
|
|
161
|
+
thresholds use the harness defaults; Apex CLI does not set a separate input budget or compaction
|
|
162
|
+
reserve.
|
|
163
|
+
Pi's per-model default applies to fresh direct launches and model selection; `apex run pi` also
|
|
164
|
+
selects `medium` explicitly. Resumed Pi sessions retain their saved thinking level.
|
|
165
|
+
|
|
166
|
+
The gateway model ID, authentication, `medium` default, and `off` → `none` translation remain
|
|
167
|
+
Callstack-specific.
|
|
168
|
+
|
|
169
|
+
| Harness | Context field | Output field | Official reference |
|
|
170
|
+
| --- | --- | --- | --- |
|
|
171
|
+
| OpenCode | `limit.context` | `limit.output` | [Custom providers](https://opencode.ai/docs/providers/) |
|
|
172
|
+
| Pi | `contextWindow` | `maxTokens` | [Custom models](https://pi.dev/docs/latest/models) |
|
|
173
|
+
| Codex | `model_context_window` | No output-limit config key | [OpenAI configuration reference](https://developers.openai.com/codex/config-reference/) |
|
|
174
|
+
| Claude Code launcher | `CLAUDE_CODE_MAX_CONTEXT_TOKENS` | `CLAUDE_CODE_MAX_OUTPUT_TOKENS` | [Environment variables](https://code.claude.com/docs/en/env-vars) |
|
|
175
|
+
| VS Code / Copilot | `contextWindow` | `maxOutputTokens` | [Custom endpoint models](https://code.visualstudio.com/docs/agent-customization/language-models) |
|
|
176
|
+
|
|
177
|
+
The Claude launcher sets context/output limits only in the child process and does not set compaction
|
|
178
|
+
window or percentage controls. Pi retains its native compaction settings. The AI SDK
|
|
179
|
+
snippet sets the output budget without inventing a context-window option.
|
|
180
|
+
|
|
181
|
+
Run `apex init` again after updating the CLI to preview upgrades to an existing Apex setup; pass
|
|
182
|
+
`--apply` to save them. Apex context/output metadata and reasoning mappings are updated in place. Older OpenCode input
|
|
183
|
+
limits and Codex compaction overrides are removed so each harness uses its own compaction defaults.
|
|
184
|
+
Codex's obsolete `model_max_output_tokens` key from older Apex versions is removed, and its dedicated
|
|
185
|
+
profile becomes self-contained. Unrelated settings, models, credentials and comments are preserved;
|
|
186
|
+
the ordinary backups and `apex undo` also cover upgrades. `none` remains supported: the gateway
|
|
187
|
+
translates it to thinking off.
|
|
188
|
+
|
|
189
|
+
Respects `XDG_CONFIG_HOME`, `CODEX_HOME`, `CLAUDE_CONFIG_DIR`, `PI_CODING_AGENT_DIR`,
|
|
190
|
+
`XDG_STATE_HOME`/`APEX_STATE_DIR`, and Windows `APPDATA`. Project-specific settings and custom
|
|
191
|
+
`OPENCODE_CONFIG` files are not modified and may override global configuration. A new OpenCode
|
|
192
|
+
config is written in the v1 format, which OpenCode 2 also reads. Older Codex
|
|
193
|
+
releases using inline `[profiles]` need a manual migration or a newer Codex release.
|
|
194
|
+
|
|
195
|
+
Windows: file configuration supports Windows paths, but `apex run` refuses `.cmd`/`.bat` shims to
|
|
196
|
+
avoid shell interpolation; launch the configured assistant directly or use WSL.
|
|
197
|
+
|
|
198
|
+
## Authentication
|
|
199
|
+
|
|
200
|
+
Provide `CALLSTACK_AUTH_TOKEN` through your shell or a secret manager. Apex CLI never prompts for,
|
|
201
|
+
logs, stores or validates the key, and never writes it to a config file; configs only reference it.
|
|
202
|
+
A hidden prompt keeps it out of your shell history:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
read -r -s -p 'Callstack API key: ' CALLSTACK_AUTH_TOKEN; echo
|
|
206
|
+
export CALLSTACK_AUTH_TOKEN
|
|
207
|
+
apex run codex
|
|
43
208
|
```
|
|
44
209
|
|
|
45
|
-
|
|
210
|
+
Other launchers: `apex run opencode`, `apex run claude`, `apex run pi`, `apex run codex -- --help`.
|
|
211
|
+
Launchers pass extra arguments through unchanged (without a shell), can be overridden by explicit
|
|
212
|
+
user arguments, and never run `init`. `apex run claude` sets the gateway URL, token, attribution
|
|
213
|
+
flag and model aliases in the child process only, leaving your default Claude provider alone.
|
|
214
|
+
|
|
215
|
+
## Safety and recovery
|
|
216
|
+
|
|
217
|
+
Apex CLI will not break what you already have.
|
|
218
|
+
|
|
219
|
+
- It shows every change first, and writes nothing until you say yes. If you script it, only
|
|
220
|
+
`--apply` writes.
|
|
221
|
+
- It copies a file next to itself before it edits that file, so you can always put the old one back.
|
|
222
|
+
- It keeps your comments, your other settings, and your default model.
|
|
223
|
+
- It never asks for your API key, writes it down, or sends it anywhere. You keep it in
|
|
224
|
+
`CALLSTACK_AUTH_TOKEN`, and the CLI prints `<redacted>` wherever a secret would show.
|
|
225
|
+
- If a config file is broken, set up another way, or a link to somewhere else, Apex CLI stops and
|
|
226
|
+
tells you. It does not overwrite it.
|
|
227
|
+
- `apex undo` gives your old setup back. It only touches files that still match what Apex CLI wrote.
|
|
228
|
+
|
|
229
|
+
How that works underneath:
|
|
230
|
+
|
|
231
|
+
- Previews print paths and key/value changes, never secrets.
|
|
232
|
+
- All selected configurations are parsed before any write. Malformed files and symlinked files or
|
|
233
|
+
directories are refused, and one bad assistant blocks the
|
|
234
|
+
whole batch instead of half-applying it.
|
|
235
|
+
- The dedicated Codex Apex profile's owned keys are upgraded rather than rejected as conflicts;
|
|
236
|
+
the base `config.toml` and other profiles remain untouched.
|
|
237
|
+
- JSON/JSONC edits preserve comments and unrelated keys. The Callstack endpoint is set to the
|
|
238
|
+
documented one. A key the assistant already has (in OpenCode's own key store, or in Pi's
|
|
239
|
+
`models.json`, where Apex CLI 0.2 put them) is kept, so upgrading never leaves an assistant
|
|
240
|
+
without a key; otherwise the config references `CALLSTACK_AUTH_TOKEN`.
|
|
241
|
+
- Writes use same-directory temporary files plus rename with mode `0600` (new directories `0700`),
|
|
242
|
+
and abort if the file changed on disk between planning and saving. This is not a lock or a
|
|
243
|
+
multi-file transaction: a later I/O failure can leave earlier writes applied. `apex undo`
|
|
244
|
+
cleans that up.
|
|
245
|
+
- Backups and newly created files are printed with every save. To recover by hand, close the
|
|
246
|
+
assistant and restore the printed `*.apex-backup-<id>` file over its config after reviewing any
|
|
247
|
+
intervening edits. Backups can contain previous secrets.
|
|
248
|
+
- No shell startup file is ever edited. The CLI makes no API requests and cannot verify your
|
|
249
|
+
key or gateway access; launch a configured assistant to test the connection.
|
|
250
|
+
|
|
251
|
+
## Configuration references
|
|
252
|
+
|
|
253
|
+
- Official Codex advanced configuration: `https://developers.openai.com/codex/config-advanced/`
|
|
254
|
+
(separate profile files for 0.134.0+; provider is placed in that profile).
|
|
255
|
+
- OpenCode v1 configuration: `https://dev.opencode.ai/docs/config/`
|
|
256
|
+
(JSONC and `{env:VARIABLE}` support).
|
|
257
|
+
- Pi custom models: `https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/models.md`
|
|
258
|
+
(`$VARIABLE` key interpolation; bare uppercase names are literals in current docs).
|
|
259
|
+
|
|
260
|
+
## Contributing
|
|
46
261
|
|
|
47
|
-
|
|
48
|
-
directory (and, for JS projects, to a local `.env`). Never commit these
|
|
49
|
-
files or share the key. Rotate it if you suspect it leaked.
|
|
262
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
package/bin/apex.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
const dist = join(dirname(fileURLToPath(import.meta.url)), '..', 'dist', 'cli.js');
|
|
7
|
+
|
|
8
|
+
if (!existsSync(dist)) {
|
|
9
|
+
process.stderr.write('Missing dist/cli.js bundle. Run `npm run build` first.\n');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
await import(pathToFileURL(dist).href);
|