@globant/coda-windows-x64 1.2.0 → 1.4.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/assets/agents/coda-help.md +6 -5
- package/assets/autonomy/continuation.md +89 -0
- package/assets/autonomy/judge-guidance.md +48 -0
- package/assets/autonomy/judge.md +59 -0
- package/assets/autonomy/maintenance.md +19 -0
- package/assets/autonomy/objective-updated.md +15 -0
- package/assets/autonomy/reminder.md +23 -0
- package/assets/autonomy/wrap-up.md +24 -0
- package/assets/docs/add-mcp-server-skill.md +135 -0
- package/assets/docs/agents.md +1 -1
- package/assets/docs/cli-reference.md +2 -0
- package/assets/docs/config-json.md +42 -45
- package/assets/docs/config-reference.md +50 -36
- package/assets/docs/configuration.md +12 -9
- package/assets/docs/connect-provider.md +3 -3
- package/assets/docs/extensions.md +23 -26
- package/assets/docs/faq.md +17 -7
- package/assets/docs/glossary.md +4 -4
- package/assets/docs/guide-changes.md +4 -4
- package/assets/docs/guide-collaborate.md +4 -4
- package/assets/docs/guide-extend.md +5 -5
- package/assets/docs/hooks.md +32 -68
- package/assets/docs/how-it-works.md +3 -3
- package/assets/docs/index.md +6 -5
- package/assets/docs/installation.md +5 -5
- package/assets/docs/logging.md +1 -1
- package/assets/docs/overview.md +7 -6
- package/assets/docs/permissions.md +16 -12
- package/assets/docs/quickstart.md +8 -4
- package/assets/docs/sessions.md +1 -1
- package/assets/docs/shortcuts.md +1 -1
- package/assets/docs/tools-reference.md +8 -1
- package/assets/docs/workflows.md +2 -1
- package/assets/skills/configure-mcp/SKILL.md +279 -0
- package/assets/skills/create-hook/SKILL.md +4 -4
- package/assets/skills/init-rules/SKILL.md +191 -0
- package/coda.exe +0 -0
- package/lib/keytar/build/Release/keytar.node +0 -0
- package/lib/ripgrep/rg.exe +0 -0
- package/package.json +1 -1
|
@@ -10,9 +10,8 @@ For a field-by-field table of the most common keys, see [Configuration Reference
|
|
|
10
10
|
| --- | --- |
|
|
11
11
|
| `~/.coda/config.json` | Your user-global settings (apply in every project) |
|
|
12
12
|
| `<project>/.coda/config.json` | Project overrides (commit to share with the team) |
|
|
13
|
-
| `<project>/coda.config.ts` | TypeScript config — takes priority over JSON if present |
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
Most settings cascade in priority order: **CLI flags → project config → global config → built-in defaults**. Permission rules accumulate across scopes, and a project cannot raise the starting permission mode above your user-level default. A project file only needs the keys it wants to change.
|
|
16
15
|
|
|
17
16
|
> **Every block below is optional.** A real `config.json` only contains the keys you actually set — most commonly `activeProfile` and a `profiles` map (the wizard writes these). The example here is intentionally exhaustive so you can copy the one block you need.
|
|
18
17
|
|
|
@@ -24,12 +23,13 @@ Settings cascade in priority order: **CLI flags → project config → global co
|
|
|
24
23
|
// This is the ONLY provider config CODA writes to disk. "activeProfile" names
|
|
25
24
|
// the profile currently in use; "profiles" is the map of switchable targets.
|
|
26
25
|
// Both are managed by /providers and /switch-profile — you rarely hand-edit
|
|
27
|
-
// them. Each profile's "provider" is one of:
|
|
26
|
+
// them. Each profile's "provider" is one of:
|
|
27
|
+
// "glob-ai" | "glob-ai-os" | "openai-compat" | "ollama".
|
|
28
28
|
"activeProfile": "geai-oauth",
|
|
29
29
|
"profiles": {
|
|
30
30
|
// Glob.AI OS via OAuth (browser login). Tokens live in the OS keyring, so
|
|
31
|
-
// no key is stored here. "instance" is a preset
|
|
32
|
-
//
|
|
31
|
+
// no key is stored here. "instance" is a known preset or a custom id;
|
|
32
|
+
// a custom id also needs its own "baseUrl".
|
|
33
33
|
"geai-oauth": {
|
|
34
34
|
"provider": "glob-ai",
|
|
35
35
|
"label": "Glob.AI OS (OAuth)",
|
|
@@ -66,7 +66,8 @@ Settings cascade in priority order: **CLI flags → project config → global co
|
|
|
66
66
|
// tools). Default 300. Raise for very long autonomous runs; lower to cap cost.
|
|
67
67
|
"maxSteps": 300,
|
|
68
68
|
|
|
69
|
-
// Background update check: true
|
|
69
|
+
// Background update check: true or "notify" checks and notifies; false disables it.
|
|
70
|
+
// Installation still happens only when you run /upgrade or coda upgrade.
|
|
70
71
|
"autoupdate": "notify",
|
|
71
72
|
|
|
72
73
|
// Error-recovery posture: "balanced" (default), "conservative", "aggressive".
|
|
@@ -107,14 +108,23 @@ Settings cascade in priority order: **CLI flags → project config → global co
|
|
|
107
108
|
},
|
|
108
109
|
|
|
109
110
|
// ── Reasoning (thinking) effort ───────────────────────────────────────
|
|
110
|
-
// effort: "low" | "medium" | "high" | "xhigh" | "max".
|
|
111
|
-
// varies. Change live with /effort.
|
|
111
|
+
// effort: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max".
|
|
112
|
+
// Per-model support varies. Change live with /effort.
|
|
113
|
+
//
|
|
114
|
+
// Headless note: the `coda --reasoning-effort <level>` shell flag sets the
|
|
115
|
+
// effort for a SINGLE run IN MEMORY ONLY — it is deliberately NOT written to
|
|
116
|
+
// this `reasoning` block, so it never collides with (or clobbers) the
|
|
117
|
+
// persisted value here. At launch the flag overrides this value for that run;
|
|
118
|
+
// the file is left exactly as-is, which is what lets two concurrent headless
|
|
119
|
+
// runs use different efforts without racing on config.json.
|
|
112
120
|
"reasoning": {
|
|
113
121
|
"enabled": true, // Default: false
|
|
114
122
|
"effort": "medium"
|
|
115
123
|
},
|
|
116
124
|
|
|
117
|
-
// ── Compaction (
|
|
125
|
+
// ── Compaction (automatic context reduction) ──────────────────────────
|
|
126
|
+
// When reduction is needed, stale tool output is moved aside first.
|
|
127
|
+
// threshold controls when older messages may also be summarized.
|
|
118
128
|
"compaction": {
|
|
119
129
|
"enabled": true,
|
|
120
130
|
"threshold": 0.75,
|
|
@@ -154,16 +164,14 @@ Settings cascade in priority order: **CLI flags → project config → global co
|
|
|
154
164
|
},
|
|
155
165
|
|
|
156
166
|
// ── Vision (examine_images) ───────────────────────────────────────────
|
|
157
|
-
// A LiteLLM-style model id.
|
|
167
|
+
// A LiteLLM-style model id. With Ollama, the product-default vision model
|
|
168
|
+
// follows the main model unless useMainAgentModel is explicitly false.
|
|
158
169
|
"vision": {
|
|
159
170
|
"model": "openai/gpt-5.4"
|
|
160
171
|
},
|
|
161
172
|
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
"provider": "brave", // "exa" | "brave" | "serper"
|
|
165
|
-
"apiKey": "${BRAVE_API_KEY}"
|
|
166
|
-
},
|
|
173
|
+
// The legacy webSearch block is accepted for compatibility but is not used
|
|
174
|
+
// by the current Glob.AI OS-backed web_search tool. Leave it out.
|
|
167
175
|
|
|
168
176
|
// ── Web fetch tool ────────────────────────────────────────────────────
|
|
169
177
|
// Backend priority: the FIRST entry is the primary, the rest are fallbacks.
|
|
@@ -206,23 +214,13 @@ Settings cascade in priority order: **CLI flags → project config → global co
|
|
|
206
214
|
// ── Composer (input area) behavior while CODA is busy ─────────────────
|
|
207
215
|
"composer": {
|
|
208
216
|
"whileBusy": { "delivery": "queue" }, // "queue" | "steer"
|
|
209
|
-
"queueSteer": { "enabled": true
|
|
217
|
+
"queueSteer": { "enabled": true }
|
|
210
218
|
},
|
|
211
219
|
|
|
212
|
-
// ── MCP servers
|
|
213
|
-
//
|
|
214
|
-
// <project>/.coda/mcp.json
|
|
215
|
-
//
|
|
216
|
-
"mcp": {
|
|
217
|
-
"servers": {
|
|
218
|
-
"github": {
|
|
219
|
-
"transport": "stdio",
|
|
220
|
-
"command": "npx",
|
|
221
|
-
"args": ["-y", "@modelcontextprotocol/server-github"],
|
|
222
|
-
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
},
|
|
220
|
+
// ── MCP servers ───────────────────────────────────────────────────────
|
|
221
|
+
// Put active server definitions in ~/.coda/mcp.json or
|
|
222
|
+
// <project>/.coda/mcp.json. Leave the unused legacy "mcp" config block out.
|
|
223
|
+
// See #add-mcp-server-skill.
|
|
226
224
|
|
|
227
225
|
// ── Editor / IDE integration (ACP) ────────────────────────────────────
|
|
228
226
|
"acp": { "enabled": true },
|
|
@@ -239,16 +237,15 @@ Settings cascade in priority order: **CLI flags → project config → global co
|
|
|
239
237
|
"rawViewer": { "enabled": false }
|
|
240
238
|
},
|
|
241
239
|
|
|
242
|
-
// ── Telemetry (
|
|
240
|
+
// ── Telemetry (Glob.AI OS platform gateway only) ──────────────────────
|
|
241
|
+
// The destination is derived from the authenticated provider and cannot be
|
|
242
|
+
// set here. Use /settings → Telemetry for the normal off/basic/full control.
|
|
243
243
|
"telemetry": {
|
|
244
|
-
"
|
|
245
|
-
"exporter": "otlp",
|
|
246
|
-
"otlpProtocol": "http",
|
|
247
|
-
"
|
|
248
|
-
"
|
|
249
|
-
"serviceName": "coda", // custom service name in traces
|
|
250
|
-
"tracesEnabled": true,
|
|
251
|
-
"metricsEnabled": true
|
|
244
|
+
"level": "basic", // "off" | "basic" | "full"
|
|
245
|
+
"exporter": "otlp", // or "console" for local diagnostics
|
|
246
|
+
"otlpProtocol": "http",
|
|
247
|
+
"otlpUseTls": true,
|
|
248
|
+
"serviceName": "coda"
|
|
252
249
|
}
|
|
253
250
|
}
|
|
254
251
|
```
|
|
@@ -257,12 +254,12 @@ Settings cascade in priority order: **CLI flags → project config → global co
|
|
|
257
254
|
|
|
258
255
|
## Secrets: keep keys out of the file
|
|
259
256
|
|
|
260
|
-
Never paste raw API keys into `config.json`. Store them in `~/.coda/.secrets` (dotenv format). API-key profiles reference a secret by **name** via `auth.secretRef`; other
|
|
257
|
+
Never paste raw API keys into `config.json`. Store them in `~/.coda/.secrets` (dotenv format). API-key profiles reference a secret by **name** via `auth.secretRef`; other compatible string fields use `${VAR}` interpolation:
|
|
261
258
|
|
|
262
259
|
```bash
|
|
263
260
|
# ~/.coda/.secrets
|
|
264
261
|
MY_API_KEY=sk-...
|
|
265
|
-
|
|
262
|
+
MCP_TOKEN=...
|
|
266
263
|
```
|
|
267
264
|
|
|
268
265
|
```jsonc
|
|
@@ -288,15 +285,15 @@ The `.secrets` file is never committed and its values are scrubbed from logs bef
|
|
|
288
285
|
| --- | --- |
|
|
289
286
|
| Switch the active model | `profiles.<id>.model` (or `/model` live) |
|
|
290
287
|
| Add a provider | A new entry under `profiles` (use `/providers`); API-key ones reference a `secretRef` in `.secrets` |
|
|
291
|
-
| Switch which provider is active | `activeProfile
|
|
288
|
+
| Switch which provider is active | `activeProfile`, or `/switch-profile` / `/sp` for the next launch |
|
|
292
289
|
| Switch OAuth ↔ API key | the profile's `auth` block (`{ "method": "oauth" }` vs `{ "method": "apikey", "secretRef": "VAR" }`) |
|
|
293
|
-
| Let commands run more without asking | `permissions.defaultMode
|
|
290
|
+
| Let commands run more without asking | Set your user-level `permissions.defaultMode` to `"auto"`, or add narrow `permissions.allow` rules — see [Permissions & Approvals](#permissions) |
|
|
294
291
|
| Change thinking effort | `reasoning.effort` (or `/effort` live) |
|
|
295
292
|
| Cap or widen parallel agents | `agents.maxConcurrent` (1–10) |
|
|
296
293
|
| Turn off a noisy bundled agent | add its name to `agents.disabledDefinitions` |
|
|
297
294
|
| Use the faster search engine | `tools.grep.backend: "fastgrep"` |
|
|
298
295
|
| Set the web-fetch backend priority | `webfetch.order` — e.g. `["client","anthropic"]` (default) or `["anthropic","client"]`; `[]` disables the tool |
|
|
299
|
-
| Add an MCP server |
|
|
296
|
+
| Add an MCP server | `~/.coda/mcp.json` or `<project>/.coda/mcp.json` — see [Configure an MCP Server](#add-mcp-server-skill) |
|
|
300
297
|
| Quiet or verbose logs | `logging.level` / `logging.levels` |
|
|
301
298
|
| Disable update checks | `autoupdate: false` |
|
|
302
299
|
|
|
@@ -311,7 +308,7 @@ A couple of settings are controlled by env vars instead of (or on top of) the fi
|
|
|
311
308
|
|
|
312
309
|
## The legacy `providers` map
|
|
313
310
|
|
|
314
|
-
Older configs (and the runtime, internally) use a top-level **`provider`** string plus a **`providers`** map keyed by provider *type* (`geai`, `openai-compat`, `ollama`, `openai`, `anthropic`, `google`, `groq`, `openrouter`, `azure`, `vertex`). **CODA no longer writes these to disk** — at launch it derives an equivalent runtime map from your active profile. You don't need to add them by hand.
|
|
311
|
+
Older configs (and the runtime, internally) use a top-level **`provider`** string plus a **`providers`** map keyed by provider *type* (`geai`, `openai-compat`, `ollama`, `openai`, `anthropic`, `google`, `groq`, `openrouter`, `azure`, `vertex`). **CODA no longer writes these to disk** — at launch it derives an equivalent runtime map from your active profile. You don't need to add them by hand. The legacy schema still accepts `vertex`, but Vertex AI cannot run yet.
|
|
315
312
|
|
|
316
313
|
If you're maintaining a config that still uses the old shape, it continues to work, but migrate to `activeProfile` + `profiles` (run `/providers`) when you can. A legacy entry looks like:
|
|
317
314
|
|
|
@@ -9,8 +9,7 @@ Reference for the most common configuration options. For how to set these up in
|
|
|
9
9
|
| `~/.coda/config.json` | User-global settings |
|
|
10
10
|
| `~/.coda/.secrets` | API keys (dotenv format, never commit) |
|
|
11
11
|
| `~/.coda/mcp.json` | Global MCP server definitions |
|
|
12
|
-
| `<project>/.coda/config.json` | Project-level
|
|
13
|
-
| `<project>/coda.config.ts` | TypeScript config (takes priority) |
|
|
12
|
+
| `<project>/.coda/config.json` | Project-level settings. Most values override user config; permission rules accumulate and the starting mode can only become more restrictive. |
|
|
14
13
|
| `<project>/.coda/mcp.json` | Project-level MCP servers |
|
|
15
14
|
|
|
16
15
|
## activeProfile and profiles
|
|
@@ -33,7 +32,7 @@ Each profile has a `provider` type that determines its shape:
|
|
|
33
32
|
"work": {
|
|
34
33
|
"provider": "glob-ai",
|
|
35
34
|
"label": "Globant Clients",
|
|
36
|
-
"instance": "clients", //
|
|
35
|
+
"instance": "clients", // known preset or custom id
|
|
37
36
|
"auth": { "method": "oauth" },
|
|
38
37
|
"model": "anthropic/claude-opus-4-8",
|
|
39
38
|
"org": { "id": "org-123", "name": "My Org" }, // set by wizard after login
|
|
@@ -47,13 +46,33 @@ Each profile has a `provider` type that determines its shape:
|
|
|
47
46
|
| --- | --- |
|
|
48
47
|
| `provider` | Must be `"glob-ai"` |
|
|
49
48
|
| `label` | Human-readable name shown in the UI |
|
|
50
|
-
| `instance` |
|
|
49
|
+
| `instance` | Known presets include `"clients"`, `"corp"`, `"saas-europe"`, `"saas-us"`, and `"beta"`; custom IDs require a `baseUrl`. The normal wizard may show only the environments intended for your setup. |
|
|
51
50
|
| `auth` | Auth method: `{ "method": "oauth" }` (browser login, tokens in OS keyring) or `{ "method": "apikey", "secretRef": "ENV_VAR_NAME" }` |
|
|
52
51
|
| `model` | Default model for this profile (optional) |
|
|
53
52
|
| `org` / `project` | Selected org and project (written by wizard after login) |
|
|
54
53
|
| `favoriteModels` | Array of model IDs shown as quick-switch options |
|
|
55
54
|
| `fastModel` / `smartModel` / `deepModel` | Model IDs for the `"fast"`, `"smart"`, and `"deep"` agent shortcut tiers |
|
|
56
|
-
| `strictPin` | When `true`, never auto-heal this profile's model
|
|
55
|
+
| `strictPin` | When `true`, never auto-heal this profile's retired model. Interactive launches already ask through the model picker; this mainly keeps headless/ACP paths from selecting a recommended replacement automatically. Default `false`. |
|
|
56
|
+
|
|
57
|
+
### `glob-ai-os` profiles (custom Glob.AI OS platform gateway)
|
|
58
|
+
|
|
59
|
+
Use `glob-ai-os` when your administrator gives you a platform-gateway URL rather than one of the `glob-ai` presets:
|
|
60
|
+
|
|
61
|
+
```jsonc
|
|
62
|
+
{
|
|
63
|
+
"profiles": {
|
|
64
|
+
"my-os": {
|
|
65
|
+
"provider": "glob-ai-os",
|
|
66
|
+
"label": "My Glob.AI OS",
|
|
67
|
+
"baseUrl": "https://identity.example.com",
|
|
68
|
+
"ingestBaseUrl": "https://gateway.example.com",
|
|
69
|
+
"auth": { "method": "oauth" }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`baseUrl` is required. `ingestBaseUrl`, `signInUrl`, organization/project selections, model, favorite models, and tier models are optional. Telemetry is available only on this platform-gateway profile type.
|
|
57
76
|
|
|
58
77
|
### `openai-compat` profiles (any OpenAI-compatible API)
|
|
59
78
|
|
|
@@ -126,13 +145,13 @@ Each entry maps a key (referenced by `provider`) to a typed config block:
|
|
|
126
145
|
| `groq` | `apiKey` | Groq SDK |
|
|
127
146
|
| `openrouter` | `apiKey` | OpenRouter SDK |
|
|
128
147
|
| `azure` | `resourceName`, `apiKey`, `apiVersion` | Azure OpenAI SDK |
|
|
129
|
-
| `vertex` | project/region config |
|
|
148
|
+
| `vertex` | project/region config | Accepted by the legacy schema, but Vertex AI cannot run yet |
|
|
130
149
|
|
|
131
150
|
Every provider entry also accepts `fastModel`, `smartModel`, `deepModel`, and a `models` map for per-model capability overrides.
|
|
132
151
|
|
|
133
152
|
Keep secrets out of `config.json` — store them in `~/.coda/.secrets` (dotenv format) and reference with `${VAR}`:
|
|
134
153
|
|
|
135
|
-
```
|
|
154
|
+
```jsonc
|
|
136
155
|
{
|
|
137
156
|
"providers": {
|
|
138
157
|
"my-api": {
|
|
@@ -161,13 +180,9 @@ Applies to Glob.AI OS / Globant OAuth sign-in. The wizard manages these; you rar
|
|
|
161
180
|
| `auth.tokenRefreshThreshold` | (built-in) | Seconds before expiry at which an access token is proactively refreshed |
|
|
162
181
|
| `auth.gamRedirectUri` | `http://localhost:XXXX/callback` | OAuth redirect URI. **Deprecated:** prefer `authDefaults` inside the provider entry |
|
|
163
182
|
|
|
164
|
-
## mcp
|
|
183
|
+
## mcp.json files
|
|
165
184
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
| Field | Description |
|
|
169
|
-
| --- | --- |
|
|
170
|
-
| `mcp.servers` | Map of server id → server entry (`command`+`args` for stdio, or `url` for http; plus optional `env`, `headers`, `timeout`, `authorizationToken`). Merged with `~/.coda/mcp.json` and `<project>/.coda/mcp.json`. |
|
|
185
|
+
Put MCP server entries in `~/.coda/mcp.json` or `<project>/.coda/mcp.json`; session overrides live under `~/.coda/sessions/<sessionId>/mcp.json`. The old inline `mcp.servers` block in `config.json` is accepted for compatibility but no longer controls runtime connections. See [Configure an MCP Server](#add-mcp-server-skill).
|
|
171
186
|
|
|
172
187
|
## bash
|
|
173
188
|
|
|
@@ -198,9 +213,9 @@ Admin-only managed-policy lockdown keys (set in a managed policy, not personal c
|
|
|
198
213
|
|
|
199
214
|
| Field | Default | Description |
|
|
200
215
|
| --- | --- | --- |
|
|
201
|
-
| `enabled` | `true` | Enable automatic pre-flight
|
|
202
|
-
| `threshold` | `0.75` | Fraction of
|
|
203
|
-
| `retainFraction` | `0.3` | Fraction of recent messages kept verbatim (0.1–0.9) |
|
|
216
|
+
| `enabled` | `true` | Enable automatic pre-flight context reduction |
|
|
217
|
+
| `threshold` | `0.75` | Fraction of the conversation budget that permits summary condensation (0.3–0.9). Large, stale tool output can start moving aside at 0.65, or at this threshold when it is lower. |
|
|
218
|
+
| `retainFraction` | `0.3` | Fraction of recent messages kept verbatim when condensation runs (0.1–0.9) |
|
|
204
219
|
|
|
205
220
|
## reasoning
|
|
206
221
|
|
|
@@ -211,7 +226,7 @@ Admin-only managed-policy lockdown keys (set in a managed policy, not personal c
|
|
|
211
226
|
|
|
212
227
|
## modelResilience
|
|
213
228
|
|
|
214
|
-
Controls
|
|
229
|
+
Controls recommendations when a configured model has been retired or renamed (see [How CODA Works](#how-it-works) › "Error recovery"). CODA finds the closest same-provider/family replacement. Interactive sessions open the model picker with that recommendation; headless runs apply it only with `CODA_MODEL_AUTOHEAL=1`, while ACP can use it for the current run. Per-profile `strictPin` opts out of automatic replacement.
|
|
215
230
|
|
|
216
231
|
| Field | Default | Description |
|
|
217
232
|
| --- | --- | --- |
|
|
@@ -232,6 +247,7 @@ Controls how CODA heals a configured model that's been retired or renamed on the
|
|
|
232
247
|
| `agents.disabledDefinitions` | — | Array of agent definition names to disable without deleting their files |
|
|
233
248
|
| `checkpoints.enabled` | on (interactive) / off (headless) | Master switch for the checkpoints subsystem |
|
|
234
249
|
| `errorHandling.posture` | `balanced` | How aggressively CODA retries on model/provider failures: `conservative` (fewer retries, fail fast), `balanced`, `aggressive` (more retries and failover attempts). See [How CODA Works](#how-it-works). |
|
|
250
|
+
| `errorHandling.streamIdleTimeoutMs` | posture-derived (`240000` for `balanced`) | Streaming inactivity timeout in milliseconds: the max gap between successive stream chunks before the request is aborted. Overrides the posture default. Raise it further (e.g. `360000`) for reasoning-heavy models or large-context turns that legitimately go silent while the model produces its first token. A non-positive value disables the idle timeout. |
|
|
235
251
|
|
|
236
252
|
## tools
|
|
237
253
|
|
|
@@ -247,7 +263,8 @@ Controls how CODA heals a configured model that's been retired or renamed on the
|
|
|
247
263
|
|
|
248
264
|
| Field | Description |
|
|
249
265
|
| --- | --- |
|
|
250
|
-
| `vision.model` | Model used by `examine_images`
|
|
266
|
+
| `vision.model` | Model used by `examine_images` for Glob.AI OS; Ollama can use this value or follow the main model according to `vision.useMainAgentModel` |
|
|
267
|
+
| `vision.useMainAgentModel` | For Ollama, leave unset/`true` to follow the main model while `vision.model` is still the product default; set `false` to force `vision.model` |
|
|
251
268
|
|
|
252
269
|
## webfetch
|
|
253
270
|
|
|
@@ -300,12 +317,7 @@ These exist for power users and rarely need hand-editing. Most can be reached th
|
|
|
300
317
|
| `fallback.provider` | — | Key of the fallback provider |
|
|
301
318
|
| `fallback.model` | — | Model to use on the fallback provider (optional) |
|
|
302
319
|
|
|
303
|
-
**`webSearch`** —
|
|
304
|
-
|
|
305
|
-
| Field | Default | Description |
|
|
306
|
-
| --- | --- | --- |
|
|
307
|
-
| `webSearch.provider` | `"brave"` | Search backend: `"exa"`, `"brave"`, or `"serper"` |
|
|
308
|
-
| `webSearch.apiKey` | — | API key for the chosen search backend |
|
|
320
|
+
**`webSearch`** — unused compatibility schema for alternate search backends. Leave it out of normal configs: the built-in `web_search` tool uses the active Glob.AI OS credentials instead.
|
|
309
321
|
|
|
310
322
|
**`session`** — session auto-rename behavior:
|
|
311
323
|
|
|
@@ -320,8 +332,8 @@ These exist for power users and rarely need hand-editing. Most can be reached th
|
|
|
320
332
|
| Field | Default | Description |
|
|
321
333
|
| --- | --- | --- |
|
|
322
334
|
| `composer.whileBusy.delivery` | `"queue"` | What to do with messages sent while the agent is running: `"queue"` or `"steer"` |
|
|
323
|
-
| `composer.queueSteer.enabled` | `true` | Enable queue/steer
|
|
324
|
-
| `composer.queueSteer.defaultMode` | `"later"` |
|
|
335
|
+
| `composer.queueSteer.enabled` | `true` | Enable queue/steer behavior |
|
|
336
|
+
| `composer.queueSteer.defaultMode` | `"later"` | Legacy input migrated to `whileBusy.delivery`: `"next"` → `"steer"`, `"later"` → `"queue"` |
|
|
325
337
|
|
|
326
338
|
**`acp`** — agent communication protocol:
|
|
327
339
|
|
|
@@ -329,26 +341,27 @@ These exist for power users and rarely need hand-editing. Most can be reached th
|
|
|
329
341
|
| --- | --- | --- |
|
|
330
342
|
| `acp.enabled` | `true` | Enable ACP headless mode (`coda --acp`) |
|
|
331
343
|
|
|
332
|
-
**`autoupdate`** —
|
|
344
|
+
**`autoupdate`** — background update-check behavior: `true` or `"notify"` checks and notifies; `false` disables the check. Updates are installed only when you run `/upgrade` or `coda upgrade`. Default `true`.
|
|
333
345
|
|
|
334
346
|
**`extensions`** — array of extension file paths to load at startup (e.g. `[".coda/extensions/my-tool.ts"]`).
|
|
335
347
|
|
|
336
348
|
**`reasoning`** — effort/thinking controls for reasoning-capable models.
|
|
337
349
|
|
|
338
|
-
**`telemetry`** — OpenTelemetry export
|
|
350
|
+
**`telemetry`** — OpenTelemetry export. It is available only when the active Glob.AI OS profile uses the platform gateway; the destination is derived from that authenticated profile and cannot be set in `config.json`:
|
|
339
351
|
|
|
340
352
|
| Field | Default | Description |
|
|
341
353
|
| --- | --- | --- |
|
|
342
|
-
| `telemetry.
|
|
343
|
-
| `telemetry.
|
|
344
|
-
| `telemetry.
|
|
354
|
+
| `telemetry.level` | `"basic"` on the platform gateway; `"off"` elsewhere | Consent level: `"off"`, `"basic"`, or `"full"`. You can change it under `/settings` → **Telemetry**. |
|
|
355
|
+
| `telemetry.enabled` | Legacy/raw override | Prefer `telemetry.level`. To disable export, set `level: "off"`; do not rely on `enabled: false` alone. |
|
|
356
|
+
| `telemetry.exporter` | `"otlp"` | Exporter: `"otlp"` or `"console"` |
|
|
345
357
|
| `telemetry.otlpProtocol` | `"http"` | OTLP transport: `"http"` or `"grpc"` |
|
|
346
|
-
| `telemetry.otlpUseTls` | `
|
|
347
|
-
| `telemetry.serviceName` |
|
|
348
|
-
| `telemetry.tracesEnabled` |
|
|
349
|
-
| `telemetry.metricsEnabled` |
|
|
358
|
+
| `telemetry.otlpUseTls` | `true` | Use TLS for OTLP export; credentialed cleartext export is refused |
|
|
359
|
+
| `telemetry.serviceName` | `"coda"` | `service.name` reported by the SDK |
|
|
360
|
+
| `telemetry.tracesEnabled` | unset | Advanced override; otherwise follows `telemetry.level` |
|
|
361
|
+
| `telemetry.metricsEnabled` | unset | Advanced override; otherwise follows `telemetry.level` |
|
|
362
|
+
| `telemetry.logsEnabled` | unset | Advanced override; otherwise follows `telemetry.level` |
|
|
350
363
|
|
|
351
|
-
Settings cascade in priority order: CLI flags override project config, which overrides your global config
|
|
364
|
+
Settings normally cascade in priority order: CLI flags override project config, which overrides your global config. Permission rules accumulate across layers, and a project cannot raise the starting permission mode above your user-level default. See [Configuration](#configuration).
|
|
352
365
|
|
|
353
366
|
## Referencing secrets with `${VAR}`
|
|
354
367
|
|
|
@@ -368,6 +381,7 @@ Keep keys out of `config.json` by storing them in `~/.coda/.secrets` (dotenv for
|
|
|
368
381
|
| --- | --- | --- |
|
|
369
382
|
| `LOG_LEVEL` | `info` | Log verbosity, Rust-style: a bare token sets the global floor, `service:level` overrides per service (e.g. `info,core.agent:debug`) |
|
|
370
383
|
| `CODA_HOME` | `~/.coda` | Alternative home directory for config, secrets, sessions, logs, and checkpoints |
|
|
384
|
+
| `CODA_NPM_REGISTRY` | public npm | HTTPS registry mirror used by native install and upgrade checks/downloads |
|
|
371
385
|
| `CODA_PROPOSE_POLICY` | unset | Overrides `permissions.proposePolicy` without editing config (dev/QA). A truthy value (`1`, `true`, `yes`, `on`) forces it **on**; any other set value (e.g. `0`, `false`, `off`) forces it **off** — so it can override in either direction, winning over config. Blank/unset defers to config (default on). An administrator's `disableProposePolicy` still wins over it. |
|
|
372
386
|
| `CODA_MODEL_AUTOHEAL` | unset | In a headless/batch run, set (e.g. `1`) to let CODA auto-heal a retired model to its recommended replacement instead of exiting non-zero. Interactive runs use the picker and ignore this; a `strictPin` profile is never healed. |
|
|
373
387
|
| `CODA_FETCH_BLOCKED_URLS` | unset | Comma-separated URLs/hosts/extensions the `webfetch` client backend must never fetch (e.g. `competitor.com,tracker.io,.pdf`). Merged with `webfetch.blockedUrls`. |
|
|
@@ -25,14 +25,13 @@ If you've set up more than one provider (say, two Glob.AI OS instances, or a loc
|
|
|
25
25
|
|
|
26
26
|
## Where settings live
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Most settings cascade in priority order — project settings override user settings, and CLI flags override everything. Permission rules accumulate across scopes, and project config cannot raise the starting permission mode:
|
|
29
29
|
|
|
30
30
|
| File | What it's for |
|
|
31
31
|
| --- | --- |
|
|
32
32
|
| `~/.coda/config.json` | Your personal defaults — provider, model, theme |
|
|
33
33
|
| `~/.coda/.secrets` | API keys and credentials (never commit this) |
|
|
34
34
|
| `<project>/.coda/config.json` | Project-level overrides (safe to commit if no secrets) |
|
|
35
|
-
| `<project>/coda.config.ts` | TypeScript config — if present, it replaces the project `config.json` (the JSON is ignored) |
|
|
36
35
|
| `~/.coda/mcp.json` | MCP servers available in all your projects |
|
|
37
36
|
| `<project>/.coda/mcp.json` | MCP servers for this project only |
|
|
38
37
|
| `~/.coda/sessions/<id>/mcp.json` | Per-session MCP overrides (written by `/mcp` commands within a session) |
|
|
@@ -46,37 +45,41 @@ Some settings can be adjusted from the settings panel. Open it from inside CODA:
|
|
|
46
45
|
/settings
|
|
47
46
|
```
|
|
48
47
|
|
|
49
|
-
**Permission mode** — how much CODA runs without asking is set by the session's permission mode: **read-only** (reads only), **default** (asks before risky actions), or **auto** (hands-off). Cycle it with **Ctrl+P**, or set the default with `permissions.defaultMode`. See [Permissions & Approvals](#permissions).
|
|
48
|
+
**Permission mode** — how much CODA runs without asking is set by the session's permission mode: **read-only** (reads only), **default** (asks before risky actions), or **auto** (hands-off). Cycle it with **Ctrl+P**, or set the user default with `permissions.defaultMode` in `~/.coda/config.json`. See [Permissions & Approvals](#permissions).
|
|
50
49
|
|
|
51
50
|
**Shell** — pick the **shell** CODA uses (`auto`, `bash`, `powershell`, `wsl`, or an explicit path) under **Bash Tool Preferences**. Only shells your host actually has are offered, so you can't select one that won't run (for example, `wsl` doesn't appear off Windows). If a *configured* shell isn't available on this host — say a `config.json` synced from Windows that asks for `wsl` on macOS — CODA neither fails to start nor silently runs a different shell: it falls back to a working shell and shows a banner naming what it's running instead and why, with a pointer to change it. The banner clears the moment you pick a shell that works. Press **Enter** to confirm and close, **Esc** to step back to the menu.
|
|
52
51
|
|
|
53
|
-
**Compaction** — to keep context fresh, CODA can
|
|
52
|
+
**Compaction** — to keep context fresh, CODA checks before each model call whether the conversation still fits. When reduction is needed, it can first move stale tool output aside and later condense older conversation at the configured threshold. Tune it under **Context Compaction**:
|
|
54
53
|
|
|
55
54
|
- **Scope** — apply your changes globally or to the current project (project overrides global).
|
|
56
|
-
- **Enable / disable** — turn automatic
|
|
57
|
-
- **Threshold** — how full the context can get (
|
|
55
|
+
- **Enable / disable** — turn automatic reduction on or off. With it off, you can still compact on demand with `/compact`.
|
|
56
|
+
- **Threshold** — how full the context can get before summary condensation begins. Large, stale tool output can start moving aside at **65%** of the conversation budget (or at your lower condensation threshold).
|
|
58
57
|
- **Retain fraction** — how much of the most recent conversation is kept intact when condensing; older messages are summarized.
|
|
59
58
|
|
|
60
59
|
**Chat input** — choose what happens when you send a message while CODA is already working: **Queue message** waits until the current turn finishes (default), while **Steer message** sends your message as the next input to guide the active flow. In `/settings`, this appears under **Composer**. See [Make Changes Safely](#guide-changes) for details.
|
|
61
60
|
|
|
62
61
|
**Theme** — switch the look of the UI between `classic` and `modern` under **UI Theme**.
|
|
63
62
|
|
|
63
|
+
**Autonomy** — enable or tune `/goal` and `/loop`, including goal judging and loop duration limits.
|
|
64
|
+
|
|
65
|
+
**Telemetry** — on an authenticated Glob.AI OS platform-gateway profile, choose **Off**, **Basic**, or **Full**. Basic sends operational metadata without prompt bodies; Full also permits redacted prompt text. Other provider types keep telemetry off.
|
|
66
|
+
|
|
64
67
|
## How settings cascade
|
|
65
68
|
|
|
66
69
|
When the same key is set in more than one place, the most specific wins. From lowest to highest priority:
|
|
67
70
|
|
|
68
71
|
1. **Built-in defaults** — what CODA ships with.
|
|
69
72
|
2. **`~/.coda/config.json`** — your personal, machine-wide settings.
|
|
70
|
-
3. **`<project>/.coda/config.json`**
|
|
73
|
+
3. **`<project>/.coda/config.json`** — project overrides, except that a project cannot raise the starting permission mode above your user-level default.
|
|
71
74
|
4. **CLI flags** — `--model`, `--profile`, `--auto-approve` (headless), and friends, for a single run.
|
|
72
75
|
|
|
73
|
-
|
|
76
|
+
A project can make the starting permission mode more restrictive for everyone who clones it, but it cannot silently raise autonomy. For a one-off headless run, `--auto-approve none|all` chooses fail-closed default mode or unattended auto mode without editing a file.
|
|
74
77
|
|
|
75
78
|
## What's safe to commit
|
|
76
79
|
|
|
77
80
|
- **Commit:** `<project>/.coda/config.json` (no secrets), `<project>/.coda/mcp.json`, `AGENTS.md`, shared skills/agents/workflows.
|
|
78
81
|
- **Never commit:** `~/.coda/.secrets` (it lives in your home directory, not the repo) and your personal `~/.coda/config.json`.
|
|
79
|
-
- **Think twice:** pinning the active `provider` or
|
|
82
|
+
- **Think twice:** pinning the active `provider` or shared permission rules affects teammates. A project `permissions.defaultMode` can tighten their starting mode, but it cannot raise autonomy above their user-level default — see [Collaborate with Your Team](#guide-collaborate).
|
|
80
83
|
|
|
81
84
|
## A minimal `config.json`
|
|
82
85
|
|
|
@@ -81,9 +81,9 @@ coda configure \
|
|
|
81
81
|
| Flag | Purpose |
|
|
82
82
|
| --- | --- |
|
|
83
83
|
| `--profile-name NAME` | Profile ID in `~/.coda/config.json` (required) |
|
|
84
|
-
| `--provider PROVIDER` | `glob-ai` \| `openai-compat` \| `ollama` (required) |
|
|
85
|
-
| `--instance INSTANCE` | glob-ai only: `clients` \| `corp` \| `saas-europe` (default: `clients`) |
|
|
86
|
-
| `--base-url URL` | Required for `openai-compat
|
|
84
|
+
| `--provider PROVIDER` | `glob-ai` \| `glob-ai-os` \| `openai-compat` \| `ollama` (required) |
|
|
85
|
+
| `--instance INSTANCE` | `glob-ai` only: `clients` \| `corp` \| `saas-europe`, or a custom name with `--base-url` (default: `clients`) |
|
|
86
|
+
| `--base-url URL` | Required for `openai-compat` and `glob-ai-os`, for a custom `glob-ai` instance, and optional for `ollama` |
|
|
87
87
|
| `--api-key KEY` | Pass key on the command line (appears in shell history — prefer `--api-key-stdin`) |
|
|
88
88
|
| `--api-key-stdin` | Read key from stdin — safe for scripts and CI |
|
|
89
89
|
| `--force` | Overwrite an existing profile and rotate its API key |
|
|
@@ -23,7 +23,7 @@ The rest of this page is a **reference** for when you want to understand what CO
|
|
|
23
23
|
|
|
24
24
|
An extension is a TypeScript file that exports an `activate` (or `default`) function receiving the `ExtensionAPI`. It lives in `.coda/extensions/` (project) or `~/.coda/extensions/` (global) — no configuration needed.
|
|
25
25
|
|
|
26
|
-
```
|
|
26
|
+
```ts
|
|
27
27
|
import { z, type ExtensionAPI, type AgentTool, type ToolContext } from "@globant/coda-core";
|
|
28
28
|
|
|
29
29
|
export default function activate(api: ExtensionAPI): void {
|
|
@@ -41,16 +41,16 @@ Extensions are auto-discovered, highest priority first:
|
|
|
41
41
|
| --- | --- | --- |
|
|
42
42
|
| 1 | `.coda/extensions/*.ts` | Project-level (highest) |
|
|
43
43
|
| 2 | `~/.coda/extensions/*.ts` | User-global |
|
|
44
|
-
| 3 | `config.json` → `extensions[]` | Configured paths |
|
|
45
|
-
| 4 |
|
|
44
|
+
| 3 | `config.json` → `extensions[]`, including any `-e ./path.ts` values merged by the CLI | Configured or one-run paths |
|
|
45
|
+
| 4 | Enabled plugin extension directories | Plugin-provided |
|
|
46
46
|
|
|
47
|
-
Subdirectory extensions are also discovered. For a folder, CODA resolves the entry file in this order: `package.json` `coda.extensions` → `package.json` `main` → `main.ts` → `<folder-name>.ts` → `index.ts` / `index.js`. To see what's loaded, run `/extensions` inside CODA.
|
|
47
|
+
Duplicate resolved paths are loaded once, preserving the first source in this order. Within the combined `extensions[]` list, configured paths appear before `-e` paths. Subdirectory extensions are also discovered. For a folder, CODA resolves the entry file in this order: `package.json` `coda.extensions` → `package.json` `main` → `main.ts` → `<folder-name>.ts` → `index.ts` / `index.js`. To see what's loaded, run `/extensions` inside CODA.
|
|
48
48
|
|
|
49
49
|
## Registering a tool
|
|
50
50
|
|
|
51
51
|
Tools are functions the agent can call. Use Zod for the parameter schema.
|
|
52
52
|
|
|
53
|
-
```
|
|
53
|
+
```ts
|
|
54
54
|
const myTool: AgentTool<MyParams, string> = {
|
|
55
55
|
name: "my_tool",
|
|
56
56
|
description: "Clear description of what the tool does and when to use it",
|
|
@@ -88,7 +88,7 @@ Inside `execute`, the `ToolContext` gives you what you need:
|
|
|
88
88
|
|
|
89
89
|
Commands are invoked by the user as `/name args`.
|
|
90
90
|
|
|
91
|
-
```
|
|
91
|
+
```ts
|
|
92
92
|
api.registerCommand("deploy", {
|
|
93
93
|
description: "Deploy the application to staging or production",
|
|
94
94
|
getArgumentCompletions: (prefix) => {
|
|
@@ -136,15 +136,15 @@ The handler context (`ExtensionCommandContext`) lets you drive the session:
|
|
|
136
136
|
|
|
137
137
|
```text
|
|
138
138
|
model, models, clear, compact, exit, help, mcp, providers, settings,
|
|
139
|
-
skills, agents, extensions, plugin, plugins, reload-plugins,
|
|
140
|
-
init, timeline, rewind, checkpoint-status
|
|
139
|
+
skills, agents, extensions, plugin, plugins, reload-plugins, usage,
|
|
140
|
+
permissions, init, timeline, rewind, checkpoint-status
|
|
141
141
|
```
|
|
142
142
|
|
|
143
143
|
## Subscribing to lifecycle hooks
|
|
144
144
|
|
|
145
145
|
Hooks let you react to (or modify) what CODA does at key moments.
|
|
146
146
|
|
|
147
|
-
```
|
|
147
|
+
```ts
|
|
148
148
|
api.on("session_start", async ({ sessionId }) => {
|
|
149
149
|
console.error("Session started:", sessionId);
|
|
150
150
|
});
|
|
@@ -169,20 +169,15 @@ api.on("context", async (context) => {
|
|
|
169
169
|
| `tool_result` | `ToolResultEvent` | Modify a tool result |
|
|
170
170
|
| `session_before_compact` | — | Before compaction (return `{ cancel: true }` to cancel) |
|
|
171
171
|
| `session_compact` | — | After compaction completes |
|
|
172
|
-
| `session_before_switch` | `{ sessionId }` | Before switching to a different session |
|
|
173
|
-
| `session_switch` | `{ sessionId }` | After a session switch completes |
|
|
174
172
|
| `session_before_fork` | `{ entryId }` | Before forking from a timeline entry |
|
|
175
173
|
| `session_fork` | `{ sessionId }` | After a fork completes |
|
|
176
|
-
| `session_before_tree` | — | Before the session tree is traversed |
|
|
177
|
-
| `session_tree` | — | After the session tree traversal |
|
|
178
|
-
| `message_start` | `MessageEvent` | When a new message begins streaming |
|
|
179
174
|
| `message_update` | `MessageEvent` | On each incremental message update |
|
|
180
|
-
| `message_end` | `MessageEvent` | When a message finishes streaming |
|
|
181
175
|
| `tool_execution_start` | `ToolExecutionEvent` | When a tool starts executing |
|
|
182
176
|
| `tool_execution_update` | `ToolExecutionEvent` | On tool execution progress update |
|
|
183
177
|
| `tool_execution_end` | `ToolExecutionEvent` | When a tool finishes executing |
|
|
184
|
-
| `resources_discover` |
|
|
185
|
-
|
|
178
|
+
| `resources_discover` | `{ cwd, reason }` | At session start. Returned resource paths are currently diagnostic only. |
|
|
179
|
+
|
|
180
|
+
The API type also reserves `session_before_switch`, `session_switch`, `session_before_tree`, `session_tree`, `message_start`, `message_end`, and `user_bash`, but the current CLI/runtime does not emit them. Do not depend on those names until they are wired.
|
|
186
181
|
|
|
187
182
|
> **`context` hook — important invariant:** The `context` payload also contains a `messageIds` field — a parallel array to `messages` where `messageIds[i]` is the DB row id for `messages[i]` (or `null` for synthetic messages). The invariant `messages.length === messageIds.length` is load-bearing. If your hook appends, inserts, or reorders `payload.messages`, you **must** apply the same operation to `payload.messageIds`, pushing `null` for synthetic entries.
|
|
188
183
|
|
|
@@ -190,23 +185,25 @@ The `input` hook returns one of three actions to control the message: `{ action:
|
|
|
190
185
|
|
|
191
186
|
## Intercepting tool calls
|
|
192
187
|
|
|
193
|
-
Use the `tool_call` hook to
|
|
188
|
+
Use the `tool_call` hook to return an authorization decision or rewrite the input before policy is evaluated:
|
|
194
189
|
|
|
195
|
-
```
|
|
190
|
+
```ts
|
|
196
191
|
api.on("tool_call", async ({ toolName, input }) => {
|
|
197
|
-
if (toolName === "bash" && input.command?.
|
|
198
|
-
return {
|
|
192
|
+
if (toolName === "bash" && input.command?.startsWith("deploy ")) {
|
|
193
|
+
return { decision: "ask", reason: "Confirm deployment command" };
|
|
199
194
|
}
|
|
200
195
|
});
|
|
201
196
|
```
|
|
202
197
|
|
|
203
|
-
|
|
198
|
+
Return `decision: "allow"`, `"ask"`, or `"deny"`, with an optional `reason`. You can also return `updatedInput`; CODA sends that rewritten input back through the authorization engine before execution. Returning nothing lets normal policy decide.
|
|
199
|
+
|
|
200
|
+
> **Migrating an older extension:** legacy `{ deny: true }` and `{ block: true }` responses are still accepted, but both now mean `deny`. If you previously used `{ block: true }` to ask the user, return `{ decision: "ask" }` instead.
|
|
204
201
|
|
|
205
202
|
## Registering shortcuts, providers, and flags
|
|
206
203
|
|
|
207
204
|
Beyond tools, commands, and hooks, an extension can register a few other surfaces (all optional):
|
|
208
205
|
|
|
209
|
-
```
|
|
206
|
+
```ts
|
|
210
207
|
// A keyboard shortcut (CLI only). Pick a key that isn't reserved (see below).
|
|
211
208
|
api.registerShortcut?.("ctrl+k", {
|
|
212
209
|
description: "Run my action",
|
|
@@ -237,20 +234,20 @@ api.registerMessageRenderer?.("my-custom-type", (entry) => {
|
|
|
237
234
|
});
|
|
238
235
|
```
|
|
239
236
|
|
|
240
|
-
**Reserved shortcuts** — extensions can't override these: `escape`, `ctrl+b`, `ctrl+c`, `ctrl+g`, `ctrl+l`, `ctrl+o`, `ctrl+u`, `ctrl+d`, `ctrl+up`, `ctrl+down`, `ctrl+j`, `ctrl+shift+c`.
|
|
237
|
+
**Reserved shortcuts** — extensions can't override these: `escape`, `ctrl+b`, `ctrl+c`, `ctrl+g`, `ctrl+l`, `ctrl+o`, `ctrl+u`, `ctrl+d`, `ctrl+up`, `ctrl+down`, `ctrl+j`, `ctrl+p`, `ctrl+shift+c`. `Ctrl+Up` / `Ctrl+Down` scroll the transcript; `Ctrl+U` / `Ctrl+D` remain reserved for conventional input behavior rather than scrolling.
|
|
241
238
|
|
|
242
239
|
## Loading, testing, and reloading
|
|
243
240
|
|
|
244
241
|
- **Drop-in load.** Save your `.ts` file under `.coda/extensions/` (project) or `~/.coda/extensions/` (global) and CODA picks it up on the next launch — no registration step.
|
|
245
242
|
- **Verify it loaded.** Run `/extensions list` inside CODA to confirm your extension is active and see the tools and commands it registered; `/extensions guide` prints API help.
|
|
246
|
-
- **Iterate quickly.** If your extension is bundled with
|
|
243
|
+
- **Iterate quickly.** If your extension is bundled with a plugin, `/reload-plugins` starts a fresh session with plugins reloaded. Restart the CLI after changing a standalone extension file.
|
|
247
244
|
- **Try one for a single run.** Pass `-e ./path/to/extension.ts` on the command line to load an extra extension just for that session — useful while developing.
|
|
248
245
|
|
|
249
246
|
## Tips for good extensions
|
|
250
247
|
|
|
251
248
|
- **Write tool descriptions for the model, not the user.** Lead with a CAPS category, say *when* to pick this tool over alternatives, and include a short parameter example. CODA chooses tools from these descriptions.
|
|
252
249
|
- **Respect cancellation.** Honor `context.signal` in long-running tool work so **Esc** can interrupt cleanly.
|
|
253
|
-
- **
|
|
250
|
+
- **Let policy own general tool safety.** Extension tools pass through the same authorization engine as built-ins. Use a `tool_call` decision for policy-like `ask` or `deny` behavior. Use `context.hitl.requestAnswer(...)` when the tool genuinely needs a user choice—such as selecting a deployment target—and `context.hitl.requestApproval(...)` only for a separate, tool-specific confirmation that policy cannot express.
|
|
254
251
|
- **Use `context.operations`** for file and shell access instead of importing Node APIs directly — it's the supported, sandbox-aware path.
|
|
255
252
|
|
|
256
253
|
## See also
|