@globant/coda-windows-x64 1.0.0 → 1.2.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 +16 -4
- package/assets/docs/agents.md +1 -1
- package/assets/docs/cli-reference.md +61 -61
- package/assets/docs/cli-vs-batch.md +0 -1
- package/assets/docs/config-json.md +31 -6
- package/assets/docs/config-reference.md +49 -3
- package/assets/docs/configuration.md +7 -11
- package/assets/docs/connect-provider.md +36 -0
- package/assets/docs/faq.md +30 -6
- package/assets/docs/glossary.md +6 -2
- package/assets/docs/guide-automate.md +5 -4
- package/assets/docs/guide-changes.md +7 -8
- package/assets/docs/guide-collaborate.md +1 -1
- package/assets/docs/how-it-works.md +3 -2
- package/assets/docs/index.md +1 -1
- package/assets/docs/overview.md +1 -1
- package/assets/docs/permissions.md +279 -34
- package/assets/docs/shortcuts.md +5 -1
- package/assets/docs/tools-reference.md +46 -4
- package/coda.exe +0 -0
- package/lib/grammars/tree-sitter-bash.wasm +0 -0
- package/lib/grammars/tree-sitter-powershell.wasm +0 -0
- package/lib/grammars/tree-sitter.wasm +0 -0
- package/lib/keytar/build/Release/keytar.node +0 -0
- package/lib/ripgrep/rg.exe +0 -0
- package/package.json +1 -1
|
@@ -67,9 +67,8 @@ fi
|
|
|
67
67
|
| `-p` / `--prompt "…"` | The prompt to run |
|
|
68
68
|
| `--prompt-file` / `-pf path` | Read the prompt from a file |
|
|
69
69
|
| `--output text\|json` | Output format. `json` emits newline-delimited events — ideal for parsing in a pipeline |
|
|
70
|
-
| `--auto-approve all\|none` | How to handle approval prompts headlessly. `all` approves
|
|
70
|
+
| `--auto-approve all\|none` | How to handle approval prompts headlessly. `all` auto-approves the ask tier (needed in CI — the un-relaxable catastrophic floor still refuses `rm -rf /`, `sudo`, etc.); `none` denies and aborts on the first request |
|
|
71
71
|
| `--timeout ms` | Abort after N milliseconds. Default `0` = no limit. |
|
|
72
|
-
| `--bash-security lvl` | Override the bash auto-approve level for this run (`safe`, `low`, `medium`, `high`). Affects which shell commands auto-run without a prompt. |
|
|
73
72
|
| `--lastsession` | Resume the most recent session for this project (mutually exclusive with `--session-id`). |
|
|
74
73
|
| `--tools default\|all\|*list*` | Limit available tools, e.g. `read,glob,grep` for a read-only run |
|
|
75
74
|
| `--model` / `-m id` | Override the model for this run |
|
|
@@ -81,7 +80,9 @@ fi
|
|
|
81
80
|
| `--base-url url` | Base URL for an ephemeral `openai-compat` / `ollama` run |
|
|
82
81
|
| `--api-key key` | Ephemeral, run-only API key — held in memory, never persisted, redacted in logs |
|
|
83
82
|
|
|
84
|
-
> **Approvals in CI.** In headless mode `--auto-approve` defaults to `all`, so CODA runs without stopping for prompts. Pass `--auto-approve none` if you instead want it to refuse anything that would need approval and abort on the first such request.
|
|
83
|
+
> **Approvals in CI.** In headless mode `--auto-approve` defaults to `all`, so CODA runs without stopping for prompts. Pass `--auto-approve none` if you instead want it to refuse anything that would need approval and abort on the first such request. Headless runs default to the `auto` permission mode; set `permissions.defaultMode` in `config.json` to change it.
|
|
84
|
+
|
|
85
|
+
> **A retired model in CI.** If the configured model has been removed or renamed on the provider, a headless run exits non-zero with a `/switch-model` hint rather than guessing. Set `CODA_MODEL_AUTOHEAL=1` to let it auto-switch to the closest available replacement (same provider/family; recorded on stderr) and keep running; a profile with `strictPin: true` is never auto-healed. See [FAQ](#faq) › "What happens if my model is removed or renamed?".
|
|
85
86
|
|
|
86
87
|
## Authenticating in batch mode
|
|
87
88
|
|
|
@@ -121,7 +122,7 @@ Always check the **exit code**: a non-zero status means the run failed (an error
|
|
|
121
122
|
Unattended runs are safest when you limit what the agent can touch:
|
|
122
123
|
|
|
123
124
|
- **Restrict tools** with `--tools` — e.g. `--tools read,glob,grep` for a read-only review that can't edit or run commands.
|
|
124
|
-
- **
|
|
125
|
+
- **Set the permission mode** with `permissions.defaultMode` (or `--auto-approve` for a headless run) so an unattended run stays within the posture you choose.
|
|
125
126
|
- **Cap runtime** with `--timeout` so a stuck run can't hang the pipeline.
|
|
126
127
|
|
|
127
128
|
## What batch mode can't do
|
|
@@ -14,14 +14,13 @@ For how checkpoints work in detail — the shadow repo, Git requirements, and ho
|
|
|
14
14
|
|
|
15
15
|
When CODA wants to run a shell command, it shows you what it's about to execute and waits for your approval — press **Y** to allow it or **N** to skip it. By default, CODA auto-approves low-risk commands (like `git status` or `cat`) and asks before anything that writes or deletes files.
|
|
16
16
|
|
|
17
|
-
How much runs without asking depends on your **
|
|
17
|
+
How much runs without asking depends on your **permission mode**, which you cycle with **Ctrl+P** or set via `permissions.defaultMode`:
|
|
18
18
|
|
|
19
|
-
|
|
|
19
|
+
| Mode | What it allows |
|
|
20
20
|
| --- | --- |
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
24
|
-
| `high` | Everything except clearly destructive operations (`rm -rf /`, disk format) |
|
|
21
|
+
| `read-only` | Reads only — file reads and searches; no edits and no commands that change anything |
|
|
22
|
+
| `default` | Auto-approves safe reads and in-`cwd` edits, but asks before risky actions — `git commit`, edits outside the working directory, and overwriting a file it never read this session (**default**) |
|
|
23
|
+
| `auto` | Hands-off — runs without asking; only the un-relaxable catastrophic floor (`rm -rf /`, `sudo`, fork bombs) and managed-policy denials still refuse |
|
|
25
24
|
|
|
26
25
|
See [Configuration](#configuration) for more on adjusting this per project.
|
|
27
26
|
|
|
@@ -97,5 +96,5 @@ If your project has an `AGENTS.md` with a "quality gate" section, CODA follows i
|
|
|
97
96
|
## See also
|
|
98
97
|
|
|
99
98
|
- [Sessions & Checkpoints](#sessions) — the shadow repo, drift detection, and what a snapshot captures.
|
|
100
|
-
- [Permissions & Approvals](#permissions) —
|
|
101
|
-
- [Configuration](#configuration) — set your default
|
|
99
|
+
- [Permissions & Approvals](#permissions) — permission modes and the anti-clobber guard in depth.
|
|
100
|
+
- [Configuration](#configuration) — set your default permission mode and composer behavior.
|
|
@@ -64,7 +64,7 @@ The most valuable things to share live in the repo and apply to everyone who clo
|
|
|
64
64
|
A project-level `<project>/.coda/config.json` is also **safe to commit** — it never holds secrets (those live in `~/.coda/.secrets`, which is never committed). But be selective about what you put there:
|
|
65
65
|
|
|
66
66
|
- **Don't commit the active provider.** Which provider you use (a specific Glob.AI OS instance, or a local Ollama) is a personal, machine-specific choice, and provider profiles are defined in each developer's own global config. Pinning it in the repo can break teammates who don't have that profile.
|
|
67
|
-
- **Think twice before committing an elevated
|
|
67
|
+
- **Think twice before committing an elevated permission mode.** Setting `permissions.defaultMode: "auto"` in the project's `.coda/config.json` means everyone who clones the repo runs more commands without being asked — a safety trade-off your team should agree on first.
|
|
68
68
|
|
|
69
69
|
In short: share **conventions and workflows**, keep **personal and security preferences** local.
|
|
70
70
|
|
|
@@ -21,7 +21,7 @@ CODA picks which tools to use automatically based on the task. You don't need to
|
|
|
21
21
|
|
|
22
22
|
Each turn runs a loop: CODA reads your message, decides on the next action, calls one or more tools, observes the results, and repeats — until the task is done or it needs your input. A few properties of this loop are worth knowing:
|
|
23
23
|
|
|
24
|
-
- **It pauses for approval** before risky actions (shell commands
|
|
24
|
+
- **It pauses for approval** before risky actions (shell commands your permission mode or rules gate to `ask`, overwriting an unread file). See [Permissions & Approvals](#permissions).
|
|
25
25
|
- **It has a step budget.** A single turn is capped at a maximum number of loop steps (`maxSteps`, default 300) so a runaway turn can't loop forever. You'll rarely hit this in normal use.
|
|
26
26
|
- **You can interrupt it.** Press **Esc** to stop the loop mid-turn and redirect.
|
|
27
27
|
- **It can delegate.** For big or parallelizable work, the loop can spawn child [agents](#agents) or a [workflow](#workflows) instead of doing everything inline.
|
|
@@ -68,6 +68,7 @@ Model calls don't always succeed — providers rate-limit, time out, or return t
|
|
|
68
68
|
- **Retries with guidance** when the model can fix it — for example, telling it exactly which tool arguments were wrong — and **backs off with jitter** (honoring any `Retry-After`) within a bounded per-turn budget.
|
|
69
69
|
- **Continues a truncated answer** that hit the output-length cap, resuming where it stopped.
|
|
70
70
|
- **Fails over** to your configured `fallback` model when a provider keeps failing, with a circuit breaker so it stops hammering a service that's down.
|
|
71
|
-
- **
|
|
71
|
+
- **Heals a retired model** — if your configured model has been removed or renamed on the provider, CODA finds the closest available replacement (same provider and family) instead of just failing. Interactively it opens the model picker pre-selected to the recommendation, naming the retired id; a headless run auto-heals only when you set `CODA_MODEL_AUTOHEAL` (otherwise it exits non-zero with a `/switch-model` hint, so nothing changes silently). Pin a profile with `strictPin: true` to opt out and always be asked. On a provider without a live catalog (e.g. local Ollama), or when nothing suitable exists, you get a clear switch-model message. See [Configuration Reference](#config-reference) › "modelResilience".
|
|
72
|
+
- **Escalates immediately** for problems retrying can't fix — auth failures, content-policy blocks, and hard quota/billing limits — surfacing a clear classified message.
|
|
72
73
|
|
|
73
74
|
In the TUI you'll see a live row like `↻ Backing off… / Failing over… / Continuing…` while this happens. You can tune how aggressively CODA retries with `errorHandling.posture` (`conservative` / `balanced` / `aggressive`) and set `fallback.enabled: true` along with `fallback.provider` (and optionally `fallback.model`) to opt in to failover — see [Configuration Reference](#config-reference).
|
package/assets/docs/index.md
CHANGED
|
@@ -29,7 +29,7 @@ If you are brand new, read these in order:
|
|
|
29
29
|
- [Commands & Flags](#cli-reference) — every slash command and shell flag.
|
|
30
30
|
- [Keyboard Shortcuts](#shortcuts) — TUI key bindings.
|
|
31
31
|
- [Tools Reference](#tools-reference) — the built-in tools the agent can call.
|
|
32
|
-
- [Permissions & Approvals](#permissions) — the human-in-the-loop model and
|
|
32
|
+
- [Permissions & Approvals](#permissions) — the human-in-the-loop model and permission modes.
|
|
33
33
|
- [Sessions & Checkpoints](#sessions) — resuming work and undoing changes.
|
|
34
34
|
|
|
35
35
|
### Task guides
|
package/assets/docs/overview.md
CHANGED
|
@@ -65,7 +65,7 @@ Every turn follows the same shape. Understanding it makes CODA predictable:
|
|
|
65
65
|
1. **You send a message.** CODA snapshots your files (a checkpoint) before doing anything.
|
|
66
66
|
2. **It reasons and plans.** For non-trivial work it sketches the steps first.
|
|
67
67
|
3. **It calls tools.** Reading files, searching, editing, running shell commands — one or more at a time.
|
|
68
|
-
4. **It pauses for approval** before anything risky (a shell command
|
|
68
|
+
4. **It pauses for approval** before anything risky (a shell command your permission mode or rules gate to `ask`, or overwriting a file it never read). You answer with a single key.
|
|
69
69
|
5. **It summarizes** what changed and why, then hands the turn back to you.
|
|
70
70
|
|
|
71
71
|
At any point you can press **Esc** to interrupt and redirect — that is almost always faster than letting it finish and undoing the result.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Permissions & Approvals
|
|
2
2
|
|
|
3
|
-
CODA can read files, run shell commands, and edit your code — but it asks before doing anything risky. This human-in-the-loop (HITL) design keeps you in control: CODA proposes an action, you approve or skip it, and nothing irreversible happens behind your back.
|
|
3
|
+
CODA can read files, run shell commands, and edit your code — but it asks before doing anything risky. Every tool call goes through an always-on **authorization engine** that decides `allow` / `ask` / `deny`. This human-in-the-loop (HITL) design keeps you in control: CODA proposes an action, you approve or skip it, and nothing irreversible happens behind your back.
|
|
4
|
+
|
|
5
|
+
Rules and modes combine to form a layered safety net — you stay in control even when the agent runs largely on its own. This page covers the permission modes, the easy plain-English way to change permissions (`propose_policy`), the rule syntax the agent writes for you, how decisions are made, and the un-relaxable catastrophic floor.
|
|
4
6
|
|
|
5
7
|
## How approvals work
|
|
6
8
|
|
|
@@ -11,65 +13,267 @@ When CODA wants to do something that could change your system, it pauses and sho
|
|
|
11
13
|
|
|
12
14
|
Some prompts are **questions** rather than yes/no approvals — for example when a tool needs you to pick from a numbered list or type a short answer. There you type your choice (or the number) and press **Enter**.
|
|
13
15
|
|
|
14
|
-
How often CODA stops to ask depends on your
|
|
16
|
+
How often CODA stops to ask depends on your **permission mode** and your **rules** (below). The goal is to auto-approve the safe, routine things (reading files, listing directories) and pause on the things that write, delete, or reach outside your project.
|
|
17
|
+
|
|
18
|
+
## Permission modes
|
|
19
|
+
|
|
20
|
+
The main approval control is the **permission mode** — the master dial that sets the agent's default level of autonomy. Press **Ctrl+P** to cycle the session between three modes; set the default with `permissions.defaultMode` in your config (globally in `~/.coda/config.json`, or per project in `.coda/config.json`).
|
|
21
|
+
|
|
22
|
+
The three valid values are `"read-only"`, `"default"`, and `"auto"`.
|
|
23
|
+
|
|
24
|
+
| Mode | What runs without asking | What asks | What's refused |
|
|
25
|
+
| --- | --- | --- | --- |
|
|
26
|
+
| **read-only** | Reads & inspections only (`cat`, `ls`, `git log`, `grep`, `Get-Content`, `dir` …) | — | Everything that changes state — writes, mutators, **and code-exec/build** (`python -c`, `node -e`, `cargo build`) |
|
|
27
|
+
| **default** | Reads, plus edits **inside your project** (`Edit`/`Write` in the cwd) | Risky commands (`git commit`, out-of-cwd edits, overwriting an unread file), MCP tools not covered by a rule | Destructive ones — unless you add an `allow` rule |
|
|
28
|
+
| **auto** | Reads, edits, and risky commands — for unattended / CI runs | — | Only catastrophic actions (the un-relaxable floor, below) |
|
|
29
|
+
|
|
30
|
+
- **read-only** allows a command *iff* it is positively classified read-safe (a curated read or inspector), on bash, PowerShell, **and** cmd alike. Interpreters, build/test verbs (`cargo build`, `tsc`, `go test`), and mutators are **not** read-safe — they are refused, even though a build isn't a "write."
|
|
31
|
+
- **default** is the shipped mode. It auto-approves an in-project `Edit`/`Write` (as long as the file was read this session, or is brand new) but still asks for edits outside the cwd, risky bash, overwriting a file it hasn't read this session, and MCP calls with no explicit allow rule.
|
|
32
|
+
- **auto** relaxes the `ask` tier to `allow` for hands-off runs — but the un-relaxable floor, managed policy, your own `deny`/`ask` rules, and sensitive-path protections still bite.
|
|
33
|
+
|
|
34
|
+
> **Legacy mode aliases:** `"plan"` → `read-only`, `"acceptEdits"` → `default`, `"bypassPermissions"` or `"bypass"` → `auto`. These still work but the new names are preferred.
|
|
35
|
+
|
|
36
|
+
**Mode is the fallback baseline** — explicit rules always take priority over it (see [precedence](#how-decisions-are-made-precedence)).
|
|
37
|
+
|
|
38
|
+
### Sub-agents and mode inheritance
|
|
39
|
+
|
|
40
|
+
When CODA spawns a sub-agent (for example to run a workflow), the sub-agent's mode can only be **equal to or more restrictive** than the parent's. A sub-agent can never widen the autonomy the parent runs under.
|
|
41
|
+
|
|
42
|
+
## The easy way to change permissions: just ask the agent
|
|
15
43
|
|
|
16
|
-
|
|
44
|
+
You rarely need to hand-edit `config.json` to change what the agent can do. The everyday way to loosen (or tighten) a permission is to **tell the agent in plain English**, right in the chat:
|
|
17
45
|
|
|
18
|
-
|
|
46
|
+
```
|
|
47
|
+
Allow running pnpm commands
|
|
48
|
+
Always allow git push to origin main
|
|
49
|
+
Never allow rm -rf
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
CODA recognizes this as a request to change your permissions and calls its built-in **`propose_policy`** tool to draft the exact rule, then shows you the resulting change for approval before writing anything to disk. You don't need to know the rule-string syntax up front — the agent writes it for you (see [Rule syntax](#rule-syntax) if you'd rather write rules by hand).
|
|
19
53
|
|
|
20
|
-
|
|
54
|
+
### When the agent needs permission it doesn't have
|
|
55
|
+
|
|
56
|
+
When CODA tries to run something not covered by your policy, it pauses and shows a **HITL prompt** (e.g. `Allow bash: git push origin main?`). Your choices:
|
|
57
|
+
|
|
58
|
+
| Choice | What it does |
|
|
21
59
|
| --- | --- |
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
60
|
+
| **Allow** (once) | Permits this single call. You'll be asked again next time. |
|
|
61
|
+
| **Allow always** | Writes a permanent allow rule to your project config and proceeds. Shows a confirmation screen first. |
|
|
62
|
+
| **Reject** | Blocks this specific call. The agent is told it was denied. |
|
|
63
|
+
|
|
64
|
+
> **In headless / non-interactive mode:** any action that would trigger a prompt is automatically denied — you'll see `Denied — approval is required, but no operator is present`.
|
|
65
|
+
|
|
66
|
+
### What denial messages look like
|
|
67
|
+
|
|
68
|
+
When an action is blocked, CODA shows a structured reason:
|
|
69
|
+
|
|
70
|
+
| Message | Cause |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `Denied by rule policy` | An explicit `deny` rule matched |
|
|
73
|
+
| `Denied — read-only mode does not allow this action` | The current mode blocks it |
|
|
74
|
+
| `Denied — rm -rf / is a destructive system operation (cannot be overridden)` | A catastrophic floor block |
|
|
75
|
+
| `Denied — git push --force is an irreversible git operation (data loss)` | Reversibility floor |
|
|
76
|
+
| `Denied — writing to ~/.ssh/id_rsa (a credential / persistence path)` | Sensitive-path protection |
|
|
77
|
+
| `Denied by a PreToolUse hook` | A lifecycle hook you configured rejected the call |
|
|
78
|
+
| `Denied — this MCP server is not in the managed allowlist` | Organization managed policy block |
|
|
79
|
+
|
|
80
|
+
CODA may also suggest up to 3 alternatives drawn from your existing allow rules — for example, if `git push` is denied it might suggest `git status` or `git log`.
|
|
26
81
|
|
|
27
|
-
|
|
82
|
+
### How `propose_policy` works
|
|
83
|
+
|
|
84
|
+
Instead of just failing, the agent can proactively ask you to make a permanent permission change — either because you asked in plain English, or on its own initiative after being denied. It can propose:
|
|
85
|
+
|
|
86
|
+
- **Add a rule** — e.g. always allow `git push origin main`, or always ask before `npm publish`.
|
|
87
|
+
- **Remove a rule** — take away a previously added allow or deny rule.
|
|
88
|
+
- **Change the permission mode** — switch between `read-only`, `default`, and `auto`.
|
|
89
|
+
|
|
90
|
+
Every proposal has a **scope**: `project` (this repo only) or `global` (all your projects).
|
|
91
|
+
|
|
92
|
+
The **direction** of the change decides what happens next:
|
|
93
|
+
|
|
94
|
+
- **Tightening** (adding a `deny`, lowering the mode) applies on its own. It only ever removes capability, so there is nothing to approve.
|
|
95
|
+
- **Widening** (an `allow`/`ask` rule, removing *any* existing rule, raising the mode) **always asks you first** — there is no mode, including `auto`, in which it applies by itself. The prompt may carry warning bullets such as `- Unlocks many commands`, `- Broader than what you asked about`, `- Targets a path outside your workspace`, or `- Won't take effect` (the rule can't override a hard floor).
|
|
96
|
+
|
|
97
|
+
After you approve, the rule is written to your config and takes effect immediately in the running session.
|
|
98
|
+
|
|
99
|
+
### What you actually approve
|
|
100
|
+
|
|
101
|
+
The approval prompt does not repeat CODA's argument for the change; it shows a summary the engine computes from the rule itself:
|
|
102
|
+
|
|
103
|
+
- what the rule would really let it do (a `Write(package.json)` grant reads as **create/overwrite**, not a vague "access"),
|
|
104
|
+
- how broad it is, and which project or global config it lands in,
|
|
105
|
+
- warnings for the risky shapes — unbounded grants, reaching outside your project, rules that apply in *all* your projects, or a look-alike command name using confusable characters,
|
|
106
|
+
- and that the change is **permanent** — it is written to your config and applies in future sessions.
|
|
107
|
+
|
|
108
|
+
So you are approving the *effect*, not the pitch. If the summary and the explanation disagree, trust the summary.
|
|
109
|
+
|
|
110
|
+
A few limits worth knowing:
|
|
111
|
+
|
|
112
|
+
- **You can say no.** Declining changes nothing, and CODA carries on with the action still blocked.
|
|
113
|
+
- **Headless runs never auto-approve.** With no one to ask, a widening is simply refused (see [Approvals in headless (batch) mode](#permissions)).
|
|
114
|
+
- **A repository can't grant itself more autonomy.** A project-scoped request to raise the permission mode is rejected outright, not offered to you.
|
|
115
|
+
- **The protected set stays protected.** Proposing cannot reach the un-relaxable floor below, your organization's managed policy, or CODA's own control-plane files.
|
|
116
|
+
|
|
117
|
+
Every proposal — applied, declined, or refused — is recorded in the authorization log, marked as agent-proposed.
|
|
118
|
+
|
|
119
|
+
### Turning `propose_policy` off
|
|
120
|
+
|
|
121
|
+
It is **on by default**. To stop the agent from ever suggesting permanent rule changes:
|
|
122
|
+
|
|
123
|
+
| How | Effect |
|
|
124
|
+
| --- | --- |
|
|
125
|
+
| `"proposePolicy": false` under `permissions` in `config.json` | Off for that config's scope (global or project) |
|
|
126
|
+
| `CODA_PROPOSE_POLICY` env var | Overrides config either way for one run: a truthy value (`1`, `true`, `yes`, `on`) forces it **on**; any other set value (`0`, `false`, `off`, …) forces it **off**. Blank/unset defers to config. |
|
|
127
|
+
| Admin managed `disableProposePolicy` | Off fleet-wide, and **one-way** — neither `permissions.proposePolicy` nor `CODA_PROPOSE_POLICY` can switch it back on |
|
|
128
|
+
|
|
129
|
+
## Rules — always-allow / always-ask / always-deny
|
|
130
|
+
|
|
131
|
+
To pin a specific command regardless of mode, add rules under `permissions` in `config.json`:
|
|
132
|
+
|
|
133
|
+
```jsonc
|
|
134
|
+
"permissions": {
|
|
135
|
+
"defaultMode": "default",
|
|
136
|
+
"allow": ["Bash(git status)", "Bash(npm test)"],
|
|
137
|
+
"ask": ["Bash(git push:*)"],
|
|
138
|
+
"deny": ["Bash(rm:*)"]
|
|
139
|
+
}
|
|
140
|
+
```
|
|
28
141
|
|
|
29
|
-
**
|
|
142
|
+
The engine is **deny-first**: an explicit `deny` always wins, then your `ask`, then your `allow` rules fill the gaps, then the permission mode decides everything else. So `cat file` reads freely, `git commit` asks in `default`, and an `allow Bash(git push:*)` lets pushes through without a prompt.
|
|
30
143
|
|
|
31
|
-
|
|
32
|
-
- `low` (default) — everyday development; CODA runs safe reads and low-risk writes (creating files, package installs, `git add`/`commit`) but asks before anything that moves or deletes.
|
|
33
|
-
- `medium` — you're moving fast in a repo you know and are comfortable auto-approving `mv`/`rm`, `git push`/`reset`, and permission changes.
|
|
34
|
-
- `high` — trusted, recoverable environments where you want minimal interruptions; still stops on clearly destructive commands.
|
|
144
|
+
### Rule syntax
|
|
35
145
|
|
|
36
|
-
|
|
146
|
+
Most rules take the form `ToolName(subcommand-or-identifier:argument-pattern)`, but the grammar also accepts a **bare tool name** (no parentheses) and **MCP server/tool** rules. This is the same syntax `propose_policy` writes for you.
|
|
147
|
+
|
|
148
|
+
| Rule string | Meaning |
|
|
149
|
+
| --- | --- |
|
|
150
|
+
| `Bash(git log:*)` | Any `git log` command (any arguments) |
|
|
151
|
+
| `Bash(git push origin main)` | Exact match — only that command, no other arguments |
|
|
152
|
+
| `Bash(npm:*)` | Any command starting with `npm` |
|
|
153
|
+
| `Bash(npm install:*)` | Only commands starting with `npm install` |
|
|
154
|
+
| `Bash(*)` | Any bash command at all |
|
|
155
|
+
| `Bash` | **Bare tool name** — the whole tool, i.e. *every* command it can run. A bare `deny Bash` also removes the tool from the agent's tool list entirely. |
|
|
156
|
+
| `Read(//etc/passwd)` | The absolute system path `/etc/passwd` |
|
|
157
|
+
| `mcp__filesystem` | Any call to the `filesystem` MCP server |
|
|
158
|
+
| `mcp__filesystem__read_file` | Only that one tool on that server |
|
|
159
|
+
|
|
160
|
+
A bare tool name is the broadest possible rule for that tool — use it deliberately. It is most useful as a `deny` (`deny: ["Bash"]` turns bash off completely); as an `allow` it is a blanket grant.
|
|
161
|
+
|
|
162
|
+
Beyond `Bash`, command rules can name a PowerShell dialect (`pwsh(...)`, `powershell(...)`) and file tools take glob specifiers (`Read`, `Edit`, `Write`, `Glob`, `Grep`, `MultiEdit`, `NotebookEdit`).
|
|
163
|
+
|
|
164
|
+
Effect types: `allow` (permit, no prompt), `ask` (always prompt, even in `auto`), `deny` (always block, no exceptions). An invalid rule string is rejected at startup rather than silently ignored.
|
|
165
|
+
|
|
166
|
+
> **Path gotcha:** a *single* leading slash in a file rule (`Read(/etc/passwd)`) is treated as *relative to your project root* (matching `<project>/etc/passwd`), **not** the real `/etc/passwd`. Use a **double slash** (`Read(//etc/passwd)`) for absolute filesystem paths. CODA warns when it detects this likely mistake on a `deny` rule.
|
|
167
|
+
>
|
|
168
|
+
> **Command gotcha — rules match the command name exactly as written.** `Bash(curl:*)` matches `curl` but **not** `/usr/bin/curl`. This holds for *both* directions, and it cuts differently for each:
|
|
169
|
+
>
|
|
170
|
+
> - As an **`allow`**, exactness is a safety property: `allow Bash(rm:*)` cannot be abused to run some other `rm` further up a path (`/tmp/evil/rm`).
|
|
171
|
+
> - As a **`deny`**, it is a limitation you need to know about: `deny Bash(mytool:*)` does **not** block `/usr/local/bin/mytool` or `./sub/mytool`. A `deny` rule is a policy pin for the spelling you wrote, not an escape-proof block. If you need one command name blocked in every spelling, deny the paths too, or rely on the floor for the genuinely dangerous ones.
|
|
172
|
+
>
|
|
173
|
+
> The catastrophic floor and the built-in danger lists are **not** subject to this: they fold a command down to its base name, so `/bin/rm -rf /` is caught exactly like `rm -rf /`, however it is spelled.
|
|
174
|
+
|
|
175
|
+
### Project-scoped vs. global-scoped rules
|
|
176
|
+
|
|
177
|
+
| Scope | Config file written | Who it affects |
|
|
178
|
+
| --- | --- | --- |
|
|
179
|
+
| **project** | `<your-project>/.coda/config.json` | Only CODA sessions inside this repository |
|
|
180
|
+
| **global** | `~/.coda/config.json` | Every CODA session you run, in any project |
|
|
181
|
+
|
|
182
|
+
A project-scoped rule committed to the repo means teammates see the same rules. A project config can only make the permission mode **more** restrictive than your global or managed policy — never more permissive.
|
|
183
|
+
|
|
184
|
+
## How decisions are made (precedence)
|
|
185
|
+
|
|
186
|
+
When the agent wants to run a tool or command, CODA evaluates rules and mode in this strict order:
|
|
187
|
+
|
|
188
|
+
1. **Explicit `deny` rules win first** — a `deny` in any config (global or project) blocks the call outright. `deny` rules from both files are *unioned*; nothing can override a deny.
|
|
189
|
+
2. **Explicit `ask` rules** — if no deny matched, a matching `ask` prompts you before proceeding.
|
|
190
|
+
3. **Explicit `allow` rules** — a match here proceeds without prompting.
|
|
191
|
+
4. **The active mode** fills in anything not covered by a rule.
|
|
192
|
+
5. **The catastrophic floor** clamps down last, unconditionally — it is applied *after* rules and mode precisely so that no `allow` rule and no mode (not even `auto`) can relax it. When several things in one command line disagree, the **most restrictive** outcome wins.
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
Incoming action
|
|
196
|
+
↓
|
|
197
|
+
[Deny rule matches?] → YES → Blocked
|
|
198
|
+
↓ NO
|
|
199
|
+
[Ask rule matches?] → YES → Prompt user
|
|
200
|
+
↓ NO
|
|
201
|
+
[Allow rule matches?] → YES → Proceed
|
|
202
|
+
↓ NO
|
|
203
|
+
[Mode baseline] → allow / ask / deny based on action type
|
|
204
|
+
↓
|
|
205
|
+
[Catastrophic floor] → Always blocks certain dangerous actions
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## The catastrophic floor — protections that can never be turned off
|
|
209
|
+
|
|
210
|
+
Below every rule and every mode sits a fixed floor. These protections are **un-relaxable**: no `allow` rule, no `auto` mode, and no `--auto-approve all` can unlock them, and `propose_policy` cannot reach them either.
|
|
211
|
+
|
|
212
|
+
> **A broad `allow` is a real grant — scope it tightly.** Allowing a command that reaches another machine hands over that capability in full. In particular, `allow Bash(ssh:*)` grants the agent **arbitrary command execution on the remote host**: CODA mediates only what runs *locally* (it still blocks reading your private key or exfiltrating a secret), but it cannot police what happens on the far side of an `ssh` session. Prefer specific rules (`Bash(ssh deploy@host:*)`) over blanket ones.
|
|
213
|
+
|
|
214
|
+
### What is never auto-approved
|
|
215
|
+
|
|
216
|
+
- **Self-protection** — writes to CODA's own control-plane files (`~/.coda/config.json`, project `.coda/config.json`, extension scripts) are blocked by shell command, file-write tool, redirect, or MCP call. The agent can't quietly widen its own permissions.
|
|
217
|
+
- **Sensitive-path writes** — writing to credential/system paths (`~/.ssh/`, `authorized_keys`, `/etc/`, `.gitconfig`, `.git/config`, `.git/hooks/`) is always blocked.
|
|
218
|
+
- **Secret reads (exfiltration)** — reading the *contents* of a private key or credential file (`cat ~/.ssh/id_rsa`, `cp ~/.aws/credentials …`, `Get-Content` on the same) is always blocked, and **not** relaxable — a broad `allow Bash(cat:*)` does not unlock it. Ordinary *config* files are unaffected: reading `~/.ssh/config`, `.bashrc`, or a project `.env` stays allowed, as do name/metadata-only checks like `test -f ~/.ssh/known_hosts`.
|
|
219
|
+
- **Git remote code execution** — config injection that makes git silently run code (`git config core.hooksPath …`, `core.sshCommand`, `git rebase -x '… | sh'`, `git fetch ext::…`) is always blocked.
|
|
220
|
+
- **Container escape** — flags that grant a container host access (`--privileged`, `-v /:/host`, mounting the Docker socket, `--pid=host`, `--cap-add SYS_ADMIN`/`ALL`) are always blocked. A plain `docker run` follows normal ask/allow logic.
|
|
221
|
+
- **Shell-redirect abuse** — using `>`/`>>` to write into credential or system paths is always blocked, even with a broad allow rule.
|
|
222
|
+
- **Catastrophic commands** — `rm -rf /`, disk formatting, `sudo`, fork bombs, `curl … | sh`, writes to raw devices, and their PowerShell/cmd equivalents.
|
|
223
|
+
|
|
224
|
+
| Protection | Relaxable with a rule? | Blocked example |
|
|
225
|
+
| --- | --- | --- |
|
|
226
|
+
| Self-protection (permission config files) | **No** | `cp evil.json ~/.coda/config.json` |
|
|
227
|
+
| Sensitive-path *writes* | **No** | `cp malicious .git/hooks/pre-commit` |
|
|
228
|
+
| Secret / private-key *reads* | **No** | `cat ~/.ssh/id_rsa` |
|
|
229
|
+
| Git RCE injection | **No** | `git config core.hooksPath /tmp/evil` |
|
|
230
|
+
| Git irreversible history ops (`--force`, `reset --hard`) | Yes — with an explicit allow rule | `git push --force` |
|
|
231
|
+
| Container escape flags | **No** | `docker run --privileged ubuntu` |
|
|
232
|
+
| Credential redirect | **No** | `echo key >> ~/.ssh/authorized_keys` |
|
|
37
233
|
|
|
38
234
|
## Choosing the shell
|
|
39
235
|
|
|
40
|
-
CODA runs bash commands through a shell you can pick from
|
|
236
|
+
CODA runs bash commands through a shell you can pick from `/settings`. The **shell mode** can be `auto` (let CODA detect the best option), or you can pin it to `bash`, `powershell`, or `wsl` — handy on Windows. The engine parses and classifies commands in whichever dialect actually runs them, so a decision on one shell matches the equivalent command on another.
|
|
41
237
|
|
|
42
238
|
## Other actions that ask first
|
|
43
239
|
|
|
44
|
-
Bash isn't the only thing gated by approvals. CODA also pauses before:
|
|
240
|
+
Bash isn't the only thing gated by approvals. In `default` mode CODA also pauses before:
|
|
45
241
|
|
|
46
|
-
- **Overwriting a file it never read this session** — an anti-clobber guard
|
|
47
|
-
- **
|
|
48
|
-
|
|
242
|
+
- **Overwriting a file it never read this session** — an anti-clobber guard, so it can't silently clobber work it hasn't seen.
|
|
243
|
+
- **MCP and other tools** — external tools you've connected route through your MCP configuration and your rules; a managed policy can restrict which MCP servers are allowed at all.
|
|
244
|
+
|
|
245
|
+
(Its own `memory` notes are always allowed — that's the agent's own state, not a change to your system.)
|
|
246
|
+
|
|
247
|
+
## Managed (organization) policy
|
|
248
|
+
|
|
249
|
+
Admins can ship a **managed policy** that everyone inherits: extra `deny` rules that can't be overridden locally, a locked permission mode (e.g. forbid `auto` via `disableAutoMode`), a restricted set of allowed MCP servers (`allowManagedMcpServersOnly`), a lockdown that drops non-managed `allow` rules (`allowManagedRulesOnly`), and a switch that turns off rule proposals entirely (`disableProposePolicy`). Managed rules sit above your personal config — a managed `deny` is final, and a managed `disableProposePolicy` cannot be switched back on by your config or by `CODA_PROPOSE_POLICY`.
|
|
49
250
|
|
|
50
251
|
## Approvals in headless (batch) mode
|
|
51
252
|
|
|
52
253
|
Headless runs can't show you a prompt, so the rules are stricter and more autonomous by design:
|
|
53
254
|
|
|
54
|
-
- The **`ask_user`** tool isn't available — there's no one to answer.
|
|
55
|
-
-
|
|
255
|
+
- The **`ask_user`** tool isn't available — there's no one to answer, so it fails closed.
|
|
256
|
+
- Any residual `ask` (something the mode would have prompted for) becomes a **`deny`** — a headless run never silently auto-approves an `ask`.
|
|
56
257
|
|
|
57
|
-
You control
|
|
258
|
+
You control the headless posture from the command line:
|
|
58
259
|
|
|
59
260
|
```bash
|
|
60
|
-
#
|
|
61
|
-
coda -p "Run the test suite and report failures" --bash-security high
|
|
62
|
-
|
|
63
|
-
# Auto-approve everything for a fully unattended run (this is the default when --auto-approve is omitted)
|
|
261
|
+
# Auto-approve the ask tier for a fully unattended run (this is the default — maps to `auto`)
|
|
64
262
|
coda -p "Format the codebase" --auto-approve all
|
|
65
263
|
|
|
66
|
-
#
|
|
264
|
+
# Fail-closed: any pending approval immediately aborts the run — useful for CI
|
|
67
265
|
coda -p "Run the test suite and report failures" --auto-approve none
|
|
68
266
|
```
|
|
69
267
|
|
|
70
|
-
When `--auto-approve` is omitted, headless
|
|
268
|
+
When `--auto-approve` is omitted, headless defaults to `all` (→ `auto`). Even so, `--auto-approve all` does **not** run *everything*: the un-relaxable catastrophic floor, self-protection, sensitive-path protections, and managed `deny` rules still refuse `rm -rf /`, `sudo`, fork bombs, and the like. Pass `--auto-approve none` (→ `default`, fail-closed) when silent auto-approval is unacceptable.
|
|
269
|
+
|
|
270
|
+
## Every decision is logged
|
|
271
|
+
|
|
272
|
+
Every authorization decision — allowed, prompted, or denied — is recorded in CODA's structured log as an `authorization.decision` entry, including the tool name, the decision, the matched rule (if any), the active mode, and the denial category. Proposed policy changes are logged separately, capturing whether they were approved, rejected, or declined. Review these to understand every permission decision made during a session (see [View & Share Logs](#logging)).
|
|
71
273
|
|
|
72
|
-
|
|
274
|
+
## Migrating from `bash.autoApproveLevel`
|
|
275
|
+
|
|
276
|
+
Older configs used a `bash.autoApproveLevel` (`safe` / `low` / `medium` / `high`). That per-command risk tier is **retired** in favor of permission modes. On startup CODA migrates it once, in place: `high` → `permissions.defaultMode: "auto"`, and the more cautious `safe`/`low`/`medium` → `"default"`. You'll see a one-time note confirming the rewrite; after that the field is gone. (If your config has comments, CODA leaves it untouched and asks you to set `permissions.defaultMode` by hand.)
|
|
73
277
|
|
|
74
278
|
## Trust and external code
|
|
75
279
|
|
|
@@ -80,14 +284,55 @@ Approvals protect you from CODA's *own* actions. A separate concern is the **cod
|
|
|
80
284
|
- **Keep approvals on** (don't blanket `--auto-approve all`) when running with untrusted extensions or MCP servers active.
|
|
81
285
|
- **Don't put secrets into prompts or project files** that an untrusted extension could read.
|
|
82
286
|
|
|
287
|
+
## Seeing what applies right now
|
|
288
|
+
|
|
289
|
+
The rest of this page describes how permissions *work*. To see what is actually in
|
|
290
|
+
force for you, in this project, run:
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
/permissions
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
It lists every allow / ask / deny rule and **where each one comes from** — your
|
|
297
|
+
`~/.coda/config.json`, the project's `.coda/config.json`, or a managed policy your
|
|
298
|
+
organization deployed — plus the current permission mode, any organization locks,
|
|
299
|
+
and any "don't ask again" grants you approved in this session.
|
|
300
|
+
|
|
301
|
+
Outside an interactive session — in CI, or to check a machine's policy without
|
|
302
|
+
starting the agent — the same view is available as a command:
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
coda permissions
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
This is the right way to confirm what a **managed policy** actually permits on a
|
|
309
|
+
given machine: it reads the same configuration a session would, so what it prints is
|
|
310
|
+
what a session started in that directory would enforce.
|
|
311
|
+
|
|
312
|
+
Both views are **read-only**. To change a rule, ask the agent (see the section
|
|
313
|
+
"The easy way to change permissions: just ask the agent" above) or edit the config
|
|
314
|
+
files described in "Where to set it" below.
|
|
315
|
+
|
|
316
|
+
Two things to know when reading the output:
|
|
317
|
+
|
|
318
|
+
- **Rules are only part of the policy.** The permission mode's baseline, the
|
|
319
|
+
per-command shell policy, and the catastrophic floor also apply to every call, and
|
|
320
|
+
are not rules that can be listed. The output says so explicitly — an empty rule
|
|
321
|
+
list does **not** mean "everything is allowed".
|
|
322
|
+
- **A rule set in two places is listed once**, under the more authoritative one, with
|
|
323
|
+
a note like `(also set in your config)`.
|
|
324
|
+
|
|
83
325
|
## Where to set it
|
|
84
326
|
|
|
85
|
-
- **
|
|
86
|
-
- **
|
|
87
|
-
- **
|
|
327
|
+
- **See what applies first:** run `/permissions` (or `coda permissions` outside a session) — see the section "Seeing what applies right now" above.
|
|
328
|
+
- **In the session:** press **Ctrl+P** to cycle the permission mode.
|
|
329
|
+
- **Just ask:** tell the agent in plain English (`allow pnpm build`, `never allow rm -rf`) and it drafts the rule via `propose_policy` for your approval.
|
|
330
|
+
- **Default / per project:** `permissions.defaultMode` and `permissions.allow`/`ask`/`deny` in `~/.coda/config.json` or a project's `.coda/config.json` (project config overrides your personal default) — see [Configuration](#configuration).
|
|
331
|
+
- **For a headless run:** the `--auto-approve none|all` flag (see [Commands & Flags](#cli-reference)).
|
|
88
332
|
|
|
89
333
|
## See also
|
|
90
334
|
|
|
91
335
|
- [Make Changes Safely](#guide-changes) — staying in control while CODA edits code.
|
|
92
336
|
- [How CODA Works](#how-it-works) — tools, memory, and the agent loop.
|
|
93
337
|
- [Configuration](#configuration) — where settings live and how they cascade.
|
|
338
|
+
- [Tools Reference](#tools-reference) — the built-in tools the engine gates.
|
package/assets/docs/shortcuts.md
CHANGED
|
@@ -18,7 +18,6 @@ These shortcuts work inside the interactive TUI. Type `?` at any time to open th
|
|
|
18
18
|
| `Ctrl+J` | Insert a newline without sending |
|
|
19
19
|
| `↑` / `↓` | Navigate input history |
|
|
20
20
|
| `/` | Open the slash command palette |
|
|
21
|
-
| `@` | Attach a file — opens the file-path browser |
|
|
22
21
|
| `?` | Open the keyboard-shortcuts overlay |
|
|
23
22
|
|
|
24
23
|
> **Tip — attach screenshots.** Paste a path to an image file (or paste the image itself where your terminal supports it) and CODA picks it up as visual context — it shows a short `[Image N]` marker so you know it'll be sent. Useful for sharing a screenshot of an error or a UI mockup.
|
|
@@ -45,6 +44,11 @@ These shortcuts work inside the interactive TUI. Type `?` at any time to open th
|
|
|
45
44
|
| Shortcut | Action |
|
|
46
45
|
| --- | --- |
|
|
47
46
|
| `Shift+Tab` | Cycle through favorite models |
|
|
47
|
+
| `Ctrl+R` | Refresh the model catalog (inside the `/switch-model` picker) |
|
|
48
|
+
|
|
49
|
+
The picker shows the catalog CODA loaded at startup. If you have just added or
|
|
50
|
+
retired a model on your provider and want the list re-read from the server
|
|
51
|
+
rather than from CODA's cache, press `Ctrl+R` while the picker is open.
|
|
48
52
|
|
|
49
53
|
Mark models as favorites from the `/switch-model` picker; `Shift+Tab` then rotates through just that shortlist, so you can flip between (say) a strong reasoning model and a cheaper everyday one without opening a menu.
|
|
50
54
|
|
|
@@ -11,7 +11,7 @@ CODA builds a **tool registry** for each session. Which tools are available depe
|
|
|
11
11
|
- **Agents** — delegation tools appear only when agents are enabled.
|
|
12
12
|
- **Extensions and plugins** — these can register additional tools.
|
|
13
13
|
|
|
14
|
-
Some tools pause for **approval** before doing something risky — see [Permissions & Approvals](#permissions). Headless runs use a stricter set: the `ask_user` tool isn't available, and bash
|
|
14
|
+
Some tools pause for **approval** before doing something risky — see [Permissions & Approvals](#permissions). Headless runs use a stricter set: the `ask_user` tool isn't available, and bash runs under the `auto` permission mode.
|
|
15
15
|
|
|
16
16
|
To limit which tools a single run may use, pass `coda --tools …` (see [Commands & Flags](#cli-reference)).
|
|
17
17
|
|
|
@@ -22,13 +22,14 @@ To limit which tools a single run may use, pass `coda --tools …` (see [Command
|
|
|
22
22
|
| `read` | Read file contents, with pagination and encoding handling |
|
|
23
23
|
| `write` | Create or overwrite files; asks before overwriting a file it never read this session |
|
|
24
24
|
| `edit` | Apply structured search-and-replace edits to existing files |
|
|
25
|
-
| `bash` | Run shell commands,
|
|
25
|
+
| `bash` | Run shell commands, classified by capability and gated by your permission mode |
|
|
26
26
|
| `glob` | Find files by path pattern (fast file finder) |
|
|
27
27
|
| `grep` | Search file contents (powered by ripgrep) |
|
|
28
28
|
| `think` | A lightweight scratchpad step the model can use to reason |
|
|
29
29
|
| `memory` | Read or update `MEMORY.md` notes; consolidating can ask for approval |
|
|
30
30
|
| `ask_user` | Ask you a question in the UI (interactive sessions only) |
|
|
31
31
|
| `web_search` | Search the web (Glob.AI OS profiles with search configured) |
|
|
32
|
+
| `webfetch` | Fetch a web page by URL and return it as markdown, plain text, or raw HTML |
|
|
32
33
|
| `examine_images` | Analyze image files with a vision model (Glob.AI OS) |
|
|
33
34
|
| `omni_parser` | Extract text and data from documents and media (Glob.AI OS) |
|
|
34
35
|
| `mcp_execute` | Call a tool on an MCP server you've connected |
|
|
@@ -46,7 +47,7 @@ You never name a tool — CODA picks based on the task. A few patterns are worth
|
|
|
46
47
|
- **To find text inside files**, it uses `grep` (ripgrep) rather than reading file after file.
|
|
47
48
|
- **To read a known file**, it uses `read`, often with an offset/limit on large files.
|
|
48
49
|
- **To change a file**, it prefers `edit` (surgical search-and-replace) over `write` (whole-file overwrite), and `write` asks before clobbering a file it never read this session.
|
|
49
|
-
- **To run anything in your shell** — tests, linters, git — it uses `bash`, gated by your
|
|
50
|
+
- **To run anything in your shell** — tests, linters, git — it uses `bash`, gated by your permission mode.
|
|
50
51
|
- **For big or parallel work**, it may delegate with `run_agent` (see [Agents](#agents)) instead of doing it all inline.
|
|
51
52
|
|
|
52
53
|
The search tools deserve special mention because they're the backbone of fast, accurate work: `glob` and `grep` let CODA locate the right code without loading the whole repo into context.
|
|
@@ -57,14 +58,55 @@ Tool behavior is configured in a few different places — some from the `/settin
|
|
|
57
58
|
|
|
58
59
|
| Area | What you control | Where |
|
|
59
60
|
| --- | --- | --- |
|
|
60
|
-
| **Bash** |
|
|
61
|
+
| **Bash** | Permission mode (Ctrl+P / `permissions.defaultMode`) and shell mode — how often CODA asks before running commands, and which shell it uses. See [Permissions & Approvals](#permissions). | `Ctrl+P` / config (`permissions.defaultMode`) |
|
|
61
62
|
| **Search** | Enable or disable `glob` and `grep`, the `grep` backend (ripgrep or fastgrep), and result limits. Ripgrep ships bundled — no separate install needed. | Config file (`tools.glob`, `tools.grep`) |
|
|
62
63
|
| **Vision** | The model used by `examine_images`. | Config file (`vision.model`) |
|
|
63
64
|
| **Web search** | The model used for web search (Glob.AI OS). | `CODA_WEBSEARCH_MODEL` env var (falls back to the built-in default) |
|
|
65
|
+
| **Web fetch** | Backend order, URL blocklist/allowlist, provenance, and the model-backend timeout for `webfetch`. Disable it entirely, or deny it via a permission rule. See [Web fetch](#web-fetch) below. | Config file (`webfetch.*`) / `permissions.deny: ["WebFetch"]` |
|
|
64
66
|
| **OmniParser** | How much extracted document text is inlined in a result vs written to `.coda/omni-parser/`. | `CODA_OMNI_PARSER_INLINE_THRESHOLD_CHARS` env var |
|
|
65
67
|
| **MCP** | Which servers load — which in turn decides whether `mcp_execute` is useful. | The `/mcp` manager |
|
|
66
68
|
| **Agents** | Whether the delegation tools exist, and how runs behave. See [Agents](#agents). | Config (`agents.*`) + the `/agents` manager |
|
|
67
69
|
|
|
70
|
+
## Web fetch
|
|
71
|
+
|
|
72
|
+
The `webfetch` tool retrieves the contents of an `http(s)` URL and hands it back as **markdown** (default), **plain text**, or **raw HTML**. It's a single, visible, permission-gated tool — one tool call, one approval prompt — with **two selectable backends** chosen by a preference order (`webfetch.order`), with automatic **runtime fallback** (if the first backend fails, the next available one runs):
|
|
73
|
+
|
|
74
|
+
- **`client`** — a fetch CODA controls end-to-end, with SSRF protection (it pins the connection to the validated IP so a hostname can't rebind to a private/metadata address), a URL blocklist/allowlist, main-content extraction that strips nav/sidebar/footer chrome (with a guard that keeps the **whole page** for link-rich homepages and index pages), and HTML→Markdown conversion. Always available; no model call. This is the **default primary** backend.
|
|
75
|
+
- **`anthropic`** — makes a call to a fixed model that runs the provider's server-side web-fetch tool and returns the parsed page. It handles content the client backend can't parse (notably **PDFs**), and is available only when a Glob.AI OS (GEAI) profile is configured. Used as the fallback by default.
|
|
76
|
+
|
|
77
|
+
The default order is **`["client", "anthropic"]`**: fetch locally first, fall back to the model backend (e.g. for a PDF) when it's available. Without a Glob.AI OS profile, the order simply falls through to `client`, and a PDF returns a short "can't fetch this here" message.
|
|
78
|
+
|
|
79
|
+
There is **no headless-browser rendering** — CODA deliberately does not bundle or require a browser. A client-rendered single-page app that ships little server-side content gets an actionable notice (try the model backend or a direct content URL) rather than being rendered.
|
|
80
|
+
|
|
81
|
+
### Configuring web fetch
|
|
82
|
+
|
|
83
|
+
Set the backend priority (and other options) with a `webfetch` block in your config file — the **first** entry in `order` is the primary, the rest are fallbacks:
|
|
84
|
+
|
|
85
|
+
```jsonc
|
|
86
|
+
{
|
|
87
|
+
// ... other config ...
|
|
88
|
+
"webfetch": {
|
|
89
|
+
"order": ["client", "anthropic"]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
All settings live under `webfetch` (all optional):
|
|
95
|
+
|
|
96
|
+
| Field | Default | What it does |
|
|
97
|
+
| --- | --- | --- |
|
|
98
|
+
| `webfetch.order` | `["client", "anthropic"]` | Backend preference order. First entry is the primary; the rest are fallbacks. Use `["client"]` for client-only, `["anthropic"]` for model-backend-only, or `[]` to **disable** the tool. |
|
|
99
|
+
| `webfetch.blockedUrls` | — | URLs/hosts/extensions the tool must never fetch (client backend). Merged with the `CODA_FETCH_BLOCKED_URLS` env var. |
|
|
100
|
+
| `webfetch.allowedHosts` | — | Strict allowlist (client backend) — when set, only these hosts and their subdomains may be fetched. |
|
|
101
|
+
| `webfetch.requireProvenance` | `true` | Anti-exfiltration: only fetch URLs that already appeared in the conversation (your messages or prior tool results), never model-invented URLs. Set `false` to allow model-composed URLs. |
|
|
102
|
+
| `webfetch.anthropicTimeoutSeconds` | `240` | Timeout budget for the model backend, decoupled from a request's own `timeout` — a server-side parse of a large PDF can take minutes. Raise it if large PDFs still time out. |
|
|
103
|
+
|
|
104
|
+
You can also disable the tool through the authorization engine with a `permissions.deny: ["WebFetch"]` rule (see [Permissions & Approvals](#permissions)), which takes precedence over `webfetch.order`.
|
|
105
|
+
|
|
106
|
+
The tool can also write a fetched page straight to a file (always confined to `.coda/docs`) instead of returning it inline — useful for large pages you want to keep without spending tokens.
|
|
107
|
+
|
|
108
|
+
`webfetch` is **main-agent-only** — it is not available inside delegated agent runs or workflows.
|
|
109
|
+
|
|
68
110
|
## Tools inside agent runs
|
|
69
111
|
|
|
70
112
|
When a delegated [agent](#agents) run executes, it uses a trimmed tool set. Two categories are removed from every child session:
|
package/coda.exe
CHANGED
|
Binary file
|
|
Binary file
|