@globant/coda-darwin-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.
Files changed (41) hide show
  1. package/assets/agents/coda-help.md +6 -5
  2. package/assets/autonomy/continuation.md +89 -0
  3. package/assets/autonomy/judge-guidance.md +48 -0
  4. package/assets/autonomy/judge.md +59 -0
  5. package/assets/autonomy/maintenance.md +19 -0
  6. package/assets/autonomy/objective-updated.md +15 -0
  7. package/assets/autonomy/reminder.md +23 -0
  8. package/assets/autonomy/wrap-up.md +24 -0
  9. package/assets/docs/add-mcp-server-skill.md +135 -0
  10. package/assets/docs/agents.md +1 -1
  11. package/assets/docs/cli-reference.md +2 -0
  12. package/assets/docs/config-json.md +42 -45
  13. package/assets/docs/config-reference.md +50 -36
  14. package/assets/docs/configuration.md +12 -9
  15. package/assets/docs/connect-provider.md +3 -3
  16. package/assets/docs/extensions.md +23 -26
  17. package/assets/docs/faq.md +17 -7
  18. package/assets/docs/glossary.md +4 -4
  19. package/assets/docs/guide-changes.md +4 -4
  20. package/assets/docs/guide-collaborate.md +4 -4
  21. package/assets/docs/guide-extend.md +5 -5
  22. package/assets/docs/hooks.md +32 -68
  23. package/assets/docs/how-it-works.md +3 -3
  24. package/assets/docs/index.md +6 -5
  25. package/assets/docs/installation.md +5 -5
  26. package/assets/docs/logging.md +1 -1
  27. package/assets/docs/overview.md +7 -6
  28. package/assets/docs/permissions.md +16 -12
  29. package/assets/docs/quickstart.md +8 -4
  30. package/assets/docs/sessions.md +1 -1
  31. package/assets/docs/shortcuts.md +1 -1
  32. package/assets/docs/tools-reference.md +8 -1
  33. package/assets/docs/workflows.md +2 -1
  34. package/assets/skills/configure-mcp/SKILL.md +279 -0
  35. package/assets/skills/create-hook/SKILL.md +4 -4
  36. package/assets/skills/init-rules/SKILL.md +191 -0
  37. package/coda +0 -0
  38. package/lib/keytar/build/Release/keytar.node +0 -0
  39. package/lib/opentui/libopentui.dylib +0 -0
  40. package/lib/ripgrep/rg +0 -0
  41. 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
- Settings cascade in priority order: **CLI flags → project config → global config → built-in defaults**. A project file only needs the keys it wants to override; everything else falls back to your global file and then to defaults.
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: "glob-ai" | "openai-compat" | "ollama".
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 ("clients" | "corp" |
32
- // "saas-europe") or a custom id (a custom id also needs its own "baseUrl").
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 (check + notify), false (off), or "notify".
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". Per-model support
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 (auto context trimming) ────────────────────────────────
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. Set useMainAgentModel:true to reuse the chat model.
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
- // ── Web search tool ───────────────────────────────────────────────────
163
- "webSearch": {
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, "defaultMode": "later" } // defaultMode: "next" | "later"
217
+ "queueSteer": { "enabled": true }
210
218
  },
211
219
 
212
- // ── MCP servers (inline) ──────────────────────────────────────────────
213
- // Optional. You can also declare these in ~/.coda/mcp.json or
214
- // <project>/.coda/mcp.json (all tiers are merged). stdio uses command+args;
215
- // http uses url. See #tools-reference.
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 (OpenTelemetry export) ──────────────────────────────────
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
- "enabled": false,
245
- "exporter": "otlp",
246
- "otlpProtocol": "http", // "http" | "grpc"
247
- "otlpHost": "http://localhost:4318", // collector; omit to use the build default
248
- "otlpUseTls": false, // true for HTTPS/gRPC TLS
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 blocks (like `webSearch`) use `${VAR}` interpolation:
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
- BRAVE_API_KEY=...
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` (or `/switch-profile` / `/sp` live) |
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: "auto"`, or add `permissions.allow` rules — see [Permissions & Approvals](#permissions) |
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 | `mcp.servers` here, or `~/.coda/mcp.json` — see [Tools Reference](#tools-reference) |
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 overrides |
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", // "clients" | "corp" | "saas-europe" | custom id
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` | Preset environment: `"clients"`, `"corp"`, `"saas-europe"`, or a custom ID. Custom instances require a `baseUrl`. |
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 if it's retired on the provider always ask instead (see "modelResilience" below and [How it works](#how-it-works) › "Error recovery"). Default `false`. |
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 | Google Vertex AI SDK |
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
- ```json
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 (inline servers)
183
+ ## mcp.json files
165
184
 
166
- You can define [MCP](#tools-reference) servers inline instead of in `mcp.json`:
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 compaction |
202
- | `threshold` | `0.75` | Fraction of token budget that triggers compaction (0.3–0.9) |
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 how CODA heals a configured model that's been retired or renamed on the provider (see [How it works](#how-it-works) › "Error recovery"). A retired model is auto-healed to the closest same-provider/family replacement; per-profile `strictPin` (above) opts out.
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` (Glob.AI OS profiles) |
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`** — web search tool settings:
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 feature |
324
- | `composer.queueSteer.defaultMode` | `"later"` | Default mode when queuing: `"next"` (run next) or `"later"` (append to queue) |
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`** — automatic update behavior: `true` (auto-install), `"notify"` (notify only), or `false` (disable). Default `true`.
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.enabled` | `false` | Master switch for OTel export |
343
- | `telemetry.exporter` | `"otlp"` | Exporter: `"otlp"` (send to a collector) or `"console"` (print spans locally) |
344
- | `telemetry.otlpHost` | (build-injected) | Collector host/URL for the OTLP exporter |
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` | `false` | Use HTTPS / gRPC TLS to the collector |
347
- | `telemetry.serviceName` | | Custom `service.name` reported in traces |
348
- | `telemetry.tracesEnabled` | `true` | Emit traces |
349
- | `telemetry.metricsEnabled` | `true` | Emit metrics |
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 (see [Configuration](#configuration)).
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
- Settings cascade in priority order — project settings override user settings, and CLI flags override everything:
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 automatically condense older conversation before it runs out of room. Tune it under **Context Compaction**:
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 compaction on or off. With it off, you can still compact on demand with `/compact`.
57
- - **Threshold** — how full the context can get (as a percentage) before CODA condenses.
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`** (or `<project>/coda.config.ts`, which replaces it) project overrides.
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
- So a project can set the permission mode (`permissions.defaultMode`) for everyone who clones it, and a headless run can override the approval posture with `--auto-approve none|all` without editing any file.
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 an elevated `permissions.defaultMode` (e.g. `"auto"`) in a project config affects every teammate — see [Collaborate with Your Team](#guide-collaborate).
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`; optional for `ollama` |
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
- ```typescript
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 | `-e ./path.ts` | CLI flag |
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
- ```typescript
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
- ```typescript
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
- ```typescript
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` | | When CODA discovers extension resources |
185
- | `user_bash` | `UserBashEvent` | When the user runs a shell command via the bash tool |
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 block dangerous commands or rewrite inputs before they run:
188
+ Use the `tool_call` hook to return an authorization decision or rewrite the input before policy is evaluated:
194
189
 
195
- ```typescript
190
+ ```ts
196
191
  api.on("tool_call", async ({ toolName, input }) => {
197
- if (toolName === "bash" && input.command?.includes("rm -rf /")) {
198
- return { deny: true, reason: "Blocked destructive command" };
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
- The hook can return `{ deny: true, reason }` to cancel the call with an error, or `{ block: true, reason }` to pause it and wait for explicit user approval before proceeding. Returning nothing (or `undefined`) lets the call proceed normally.
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
- ```typescript
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 plugins, `/reload-plugins` re-reads them after you change the files on disk. Otherwise, relaunch CODA to reload a standalone extension file.
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
- - **Ask before doing harm.** Route risky actions through `context.hitl` so they go through the same approval flow as built-in tools.
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