@globant/coda-windows-x64 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/agents/coda-help.md +166 -0
- package/assets/agents/create-workflow.md +264 -0
- package/assets/agents/explore.md +26 -0
- package/assets/docs/agents.md +162 -0
- package/assets/docs/cli-reference.md +131 -0
- package/assets/docs/cli-vs-batch.md +58 -0
- package/assets/docs/config-json.md +314 -0
- package/assets/docs/config-reference.md +329 -0
- package/assets/docs/configuration.md +105 -0
- package/assets/docs/connect-provider.md +77 -0
- package/assets/docs/extensions.md +260 -0
- package/assets/docs/faq.md +152 -0
- package/assets/docs/glossary.md +41 -0
- package/assets/docs/guide-automate.md +135 -0
- package/assets/docs/guide-changes.md +101 -0
- package/assets/docs/guide-collaborate.md +119 -0
- package/assets/docs/guide-extend.md +120 -0
- package/assets/docs/guide-understand.md +95 -0
- package/assets/docs/hooks.md +704 -0
- package/assets/docs/how-it-works.md +73 -0
- package/assets/docs/index.md +62 -0
- package/assets/docs/installation.md +71 -0
- package/assets/docs/logging.md +123 -0
- package/assets/docs/overview.md +91 -0
- package/assets/docs/permissions.md +93 -0
- package/assets/docs/quickstart.md +104 -0
- package/assets/docs/sessions.md +139 -0
- package/assets/docs/shortcuts.md +61 -0
- package/assets/docs/tools-reference.md +81 -0
- package/assets/docs/workflows.md +146 -0
- package/assets/skills/create-extension/SKILL.md +293 -0
- package/assets/skills/create-hook/SKILL.md +442 -0
- package/assets/skills/create-skill/SKILL.md +180 -0
- package/assets/skills/plan/SKILL.md +25 -0
- package/coda.exe +0 -0
- package/lib/keytar/build/Release/keytar.node +0 -0
- package/lib/keytar/lib/keytar.js +43 -0
- package/lib/opentui/assets/javascript/highlights.scm +205 -0
- package/lib/opentui/assets/javascript/tree-sitter-javascript.wasm +0 -0
- package/lib/opentui/assets/markdown/highlights.scm +150 -0
- package/lib/opentui/assets/markdown/injections.scm +27 -0
- package/lib/opentui/assets/markdown/tree-sitter-markdown.wasm +0 -0
- package/lib/opentui/assets/markdown_inline/highlights.scm +115 -0
- package/lib/opentui/assets/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
- package/lib/opentui/assets/typescript/highlights.scm +604 -0
- package/lib/opentui/assets/typescript/tree-sitter-typescript.wasm +0 -0
- package/lib/opentui/assets/zig/highlights.scm +284 -0
- package/lib/opentui/assets/zig/tree-sitter-zig.wasm +0 -0
- package/lib/opentui/parser.worker.js +4244 -0
- package/lib/opentui/tree-sitter-3jzf13jk.wasm +0 -0
- package/lib/ripgrep/COPYING +3 -0
- package/lib/ripgrep/LICENSE-MIT +21 -0
- package/lib/ripgrep/UNLICENSE +24 -0
- package/lib/ripgrep/rg.exe +0 -0
- package/package.json +20 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# Writing Extensions
|
|
2
|
+
|
|
3
|
+
Extensions are TypeScript modules that plug into CODA. Use them when you want CODA to integrate with an internal system that has no MCP server, or to automate a workflow that's too complex for a skill. An extension can register custom **tools**, **slash commands**, and **lifecycle hooks** — and even intercept tool calls.
|
|
4
|
+
|
|
5
|
+
> Looking for the high-level overview of skills, extensions, and plugins? See [Extend CODA](#guide-extend).
|
|
6
|
+
|
|
7
|
+
## The easy way: let CODA write it
|
|
8
|
+
|
|
9
|
+
You don't have to learn the API to build an extension. CODA ships with a **`create-extension`** skill that scaffolds one for you — just describe what you want in plain language:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
/create-extension
|
|
13
|
+
|
|
14
|
+
I want an extension that adds a /deploy slash command which deploys
|
|
15
|
+
the app to staging or production.
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
CODA generates the extension file, places it in the right folder, and explains how to use it. This is the recommended path for most people.
|
|
19
|
+
|
|
20
|
+
The rest of this page is a **reference** for when you want to understand what CODA generated, or hand-write and fine-tune an extension yourself — you don't need to read it to get started.
|
|
21
|
+
|
|
22
|
+
## Anatomy of an extension
|
|
23
|
+
|
|
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
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { z, type ExtensionAPI, type AgentTool, type ToolContext } from "@globant/coda-core";
|
|
28
|
+
|
|
29
|
+
export default function activate(api: ExtensionAPI): void {
|
|
30
|
+
// Register tools, commands, hooks
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`@globant/coda-core` re-exports `z` (Zod) so your extension needs only one import source.
|
|
35
|
+
|
|
36
|
+
## Where extensions load from
|
|
37
|
+
|
|
38
|
+
Extensions are auto-discovered, highest priority first:
|
|
39
|
+
|
|
40
|
+
| Priority | Source | Scope |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| 1 | `.coda/extensions/*.ts` | Project-level (highest) |
|
|
43
|
+
| 2 | `~/.coda/extensions/*.ts` | User-global |
|
|
44
|
+
| 3 | `config.json` → `extensions[]` | Configured paths |
|
|
45
|
+
| 4 | `-e ./path.ts` | CLI flag |
|
|
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.
|
|
48
|
+
|
|
49
|
+
## Registering a tool
|
|
50
|
+
|
|
51
|
+
Tools are functions the agent can call. Use Zod for the parameter schema.
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
const myTool: AgentTool<MyParams, string> = {
|
|
55
|
+
name: "my_tool",
|
|
56
|
+
description: "Clear description of what the tool does and when to use it",
|
|
57
|
+
parameters: z.object({
|
|
58
|
+
query: z.string().describe("What to search for"),
|
|
59
|
+
limit: z.number().int().positive().optional().describe("Max results"),
|
|
60
|
+
}),
|
|
61
|
+
label: "My Tool",
|
|
62
|
+
execute: async (toolCallId, params, context: ToolContext) => {
|
|
63
|
+
const cwd = context.cwd ?? process.cwd();
|
|
64
|
+
// ... do the work ...
|
|
65
|
+
return "result string returned to the agent";
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
api.registerTool(myTool);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Inside `execute`, the `ToolContext` gives you what you need:
|
|
73
|
+
|
|
74
|
+
| Field | Purpose |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| `cwd` | Project directory |
|
|
77
|
+
| `signal` | Cancellation signal (`AbortSignal`) |
|
|
78
|
+
| `hitl` | Human-in-the-loop prompts (ask for approval) |
|
|
79
|
+
| `operations` | File and shell helpers: `readFile`, `writeFile`, `glob`, `stat`, `exists`, `exec`, … |
|
|
80
|
+
| `sessionId` | Current session ID |
|
|
81
|
+
| `mcp` | MCP server access |
|
|
82
|
+
| `onUpdate` | Stream progress updates back to the UI |
|
|
83
|
+
| `model` | Current model info |
|
|
84
|
+
|
|
85
|
+
**Description tips:** lead with the category in CAPS, explain when the agent should pick this tool over alternatives, and include short parameter examples in the description.
|
|
86
|
+
|
|
87
|
+
## Registering a slash command
|
|
88
|
+
|
|
89
|
+
Commands are invoked by the user as `/name args`.
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
api.registerCommand("deploy", {
|
|
93
|
+
description: "Deploy the application to staging or production",
|
|
94
|
+
getArgumentCompletions: (prefix) => {
|
|
95
|
+
const options = [
|
|
96
|
+
{ value: "staging", label: "staging — deploy to staging" },
|
|
97
|
+
{ value: "production", label: "production — deploy to production" },
|
|
98
|
+
];
|
|
99
|
+
const p = prefix.trim().toLowerCase();
|
|
100
|
+
return p ? options.filter((o) => o.value.startsWith(p)) : options;
|
|
101
|
+
},
|
|
102
|
+
handler: async (args, ctx) => {
|
|
103
|
+
if (!args.trim()) {
|
|
104
|
+
ctx.addMessage?.("system", "Usage: /deploy [staging|production]");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
await ctx.sendMessage?.(`Deploy to ${args.trim()}`);
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The handler context (`ExtensionCommandContext`) lets you drive the session:
|
|
113
|
+
|
|
114
|
+
| Field | Purpose |
|
|
115
|
+
| --- | --- |
|
|
116
|
+
| `addMessage(role, content)` | Add a system/error/user message to chat |
|
|
117
|
+
| `sendMessage(text)` | Send as a user message (triggers an agent response) |
|
|
118
|
+
| `clearMessages()` | Clear the conversation |
|
|
119
|
+
| `setModel(id)` | Switch the model |
|
|
120
|
+
| `session` | The AgentSession (read-only) |
|
|
121
|
+
| `ui` | `select`, `confirm`, `input`, `notify`, `setStatus` |
|
|
122
|
+
| `showModelPicker()` / `showSettings()` / `showMcpManager()` | Open overlays |
|
|
123
|
+
| `showProvidersManager?()` | Open the providers manager overlay |
|
|
124
|
+
| `newSession?(options?)` | Start a new session (optionally parented) |
|
|
125
|
+
| `fork?(entryId)` | Fork the session from a given timeline entry |
|
|
126
|
+
| `navigateTree?(targetId, options?)` | Navigate to a specific node in the session tree |
|
|
127
|
+
| `switchSession?(sessionPath)` | Switch to an existing session by path |
|
|
128
|
+
| `reload?()` | Trigger a session reload |
|
|
129
|
+
| `waitForIdle()` | Wait until the agent finishes the current turn |
|
|
130
|
+
| `exit()` | Close the CLI |
|
|
131
|
+
| `cwd` | The current working directory |
|
|
132
|
+
| `sessionId` | The active session id |
|
|
133
|
+
| `mcp` | Reference to the MCP service (for inspecting connected servers) |
|
|
134
|
+
|
|
135
|
+
**Reserved command names** — extensions can't override these built-ins:
|
|
136
|
+
|
|
137
|
+
```text
|
|
138
|
+
model, models, clear, compact, exit, help, mcp, providers, settings,
|
|
139
|
+
skills, agents, extensions, plugin, plugins, reload-plugins,
|
|
140
|
+
init, timeline, rewind, checkpoint-status
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Subscribing to lifecycle hooks
|
|
144
|
+
|
|
145
|
+
Hooks let you react to (or modify) what CODA does at key moments.
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
api.on("session_start", async ({ sessionId }) => {
|
|
149
|
+
console.error("Session started:", sessionId);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
api.on("context", async (context) => {
|
|
153
|
+
// Mutate in place before each LLM call
|
|
154
|
+
context.systemPrompt += "\n\n## My custom instructions\n...";
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
| Hook | Payload | When it fires |
|
|
159
|
+
| --- | --- | --- |
|
|
160
|
+
| `session_start` / `session_end` | `{ sessionId }` | After session creation / when it ends |
|
|
161
|
+
| `session_shutdown` | `{}` | Process exit — flush buffers |
|
|
162
|
+
| `before_agent_start` | `{ text, sessionId }` | Before the agent loop |
|
|
163
|
+
| `agent_start` / `agent_end` | `{ turnId }` | Agent loop boundaries |
|
|
164
|
+
| `turn_start` / `turn_end` | `{ turnId }` | Per-LLM-turn boundaries |
|
|
165
|
+
| `context` | `{ systemPrompt, messages, tools }` | Mutate before each LLM call |
|
|
166
|
+
| `input` | `InputEvent` | Transform user input before send |
|
|
167
|
+
| `model_select` | `{ model }` | After `setModel()` switches the active model |
|
|
168
|
+
| `tool_call` | `ToolCallEvent` | Intercept or deny a tool call |
|
|
169
|
+
| `tool_result` | `ToolResultEvent` | Modify a tool result |
|
|
170
|
+
| `session_before_compact` | — | Before compaction (return `{ cancel: true }` to cancel) |
|
|
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
|
+
| `session_before_fork` | `{ entryId }` | Before forking from a timeline entry |
|
|
175
|
+
| `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
|
+
| `message_update` | `MessageEvent` | On each incremental message update |
|
|
180
|
+
| `message_end` | `MessageEvent` | When a message finishes streaming |
|
|
181
|
+
| `tool_execution_start` | `ToolExecutionEvent` | When a tool starts executing |
|
|
182
|
+
| `tool_execution_update` | `ToolExecutionEvent` | On tool execution progress update |
|
|
183
|
+
| `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 |
|
|
186
|
+
|
|
187
|
+
> **`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
|
+
|
|
189
|
+
The `input` hook returns one of three actions to control the message: `{ action: "continue" }` passes it through unchanged, `{ action: "transform", text }` replaces the text, and `{ action: "handled" }` swallows the message entirely (CODA does nothing further with it).
|
|
190
|
+
|
|
191
|
+
## Intercepting tool calls
|
|
192
|
+
|
|
193
|
+
Use the `tool_call` hook to block dangerous commands or rewrite inputs before they run:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
api.on("tool_call", async ({ toolName, input }) => {
|
|
197
|
+
if (toolName === "bash" && input.command?.includes("rm -rf /")) {
|
|
198
|
+
return { deny: true, reason: "Blocked destructive command" };
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
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.
|
|
204
|
+
|
|
205
|
+
## Registering shortcuts, providers, and flags
|
|
206
|
+
|
|
207
|
+
Beyond tools, commands, and hooks, an extension can register a few other surfaces (all optional):
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
// A keyboard shortcut (CLI only). Pick a key that isn't reserved (see below).
|
|
211
|
+
api.registerShortcut?.("ctrl+k", {
|
|
212
|
+
description: "Run my action",
|
|
213
|
+
handler: (ctx) => ctx.addMessage("system", "Triggered!"),
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// A custom model provider.
|
|
217
|
+
api.registerProvider?.("my-provider", {
|
|
218
|
+
baseUrl: "https://api.example.com/v1",
|
|
219
|
+
apiKey: process.env.MY_KEY,
|
|
220
|
+
models: [{ id: "my-model", name: "My Model", contextWindow: 128000 }],
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// A CLI flag parsed from process.argv. `type` is required ("boolean" or "string";
|
|
224
|
+
// a string flag reads --name=value).
|
|
225
|
+
api.registerFlag?.("my-flag", { type: "boolean", description: "Enable my feature" });
|
|
226
|
+
|
|
227
|
+
// Read a flag value registered above.
|
|
228
|
+
const isEnabled = api.getFlag?.("my-flag");
|
|
229
|
+
|
|
230
|
+
// Dynamically unregister a tool previously added with registerTool.
|
|
231
|
+
api.removeTool("my_tool");
|
|
232
|
+
|
|
233
|
+
// Register a custom renderer for a custom message type.
|
|
234
|
+
api.registerMessageRenderer?.("my-custom-type", (entry) => {
|
|
235
|
+
// Return a React node or string representation for the custom message.
|
|
236
|
+
return entry.content;
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
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`.
|
|
241
|
+
|
|
242
|
+
## Loading, testing, and reloading
|
|
243
|
+
|
|
244
|
+
- **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
|
+
- **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.
|
|
247
|
+
- **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
|
+
|
|
249
|
+
## Tips for good extensions
|
|
250
|
+
|
|
251
|
+
- **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
|
+
- **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.
|
|
254
|
+
- **Use `context.operations`** for file and shell access instead of importing Node APIs directly — it's the supported, sandbox-aware path.
|
|
255
|
+
|
|
256
|
+
## See also
|
|
257
|
+
|
|
258
|
+
- [Extend CODA](#guide-extend) — when to use skills vs extensions vs plugins.
|
|
259
|
+
- [Tools Reference](#tools-reference) — the built-in tools your extension sits alongside.
|
|
260
|
+
- [Permissions & Approvals](#permissions) — the HITL flow your tools should hook into.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# FAQ
|
|
2
|
+
|
|
3
|
+
Common questions, organized by what you're trying to do.
|
|
4
|
+
|
|
5
|
+
## Getting started
|
|
6
|
+
|
|
7
|
+
### How do I check which version I'm running?
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
coda --version
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### How do I add or change a provider?
|
|
14
|
+
|
|
15
|
+
From your terminal (outside a session): `coda --reconfigure`. From inside an active session: `/providers`. Note that `/providers` changes require restarting CODA to take effect.
|
|
16
|
+
|
|
17
|
+
### How do I set up two projects (e.g. two Clients projects) and switch between them?
|
|
18
|
+
|
|
19
|
+
Configure each one as its own profile, then switch with `/switch-profile`:
|
|
20
|
+
|
|
21
|
+
1. Run `/providers` and sign in to the first Clients project (OAuth or API key). CODA saves it as a named profile.
|
|
22
|
+
2. Run `/providers` again and sign in to the **second** Clients project. Because it's a different organization/project, CODA stores it as a **separate** profile rather than overwriting the first.
|
|
23
|
+
3. From then on, flip between them with `/switch-profile` (alias `/sp`) — no argument opens a picker, or pass the profile id directly (`/switch-profile geai-clients`). The switch is saved as `activeProfile` and applies on the next launch.
|
|
24
|
+
|
|
25
|
+
Use `/switch-profile` when you only want to change which configured profile is active; use `/providers` to add, edit, or remove one. See [Connect a Provider](#connect-provider) › "Switch between configured providers".
|
|
26
|
+
|
|
27
|
+
### I'm logged in with OAuth. How do I switch to a different project?
|
|
28
|
+
|
|
29
|
+
You have two options:
|
|
30
|
+
|
|
31
|
+
- **Stay in the session** — run `/project` (Glob.AI OS OAuth only). It lists the organizations and projects your account can access; pick one, or run `/project <id>` directly. This re-targets the active project without a restart. See [Connect a Provider](#connect-provider) › "Switching the active Glob.AI OS project".
|
|
32
|
+
- **Switch profiles** — if you've configured the other project as its own profile (see above), `/switch-profile` selects it instead. That change applies on the next launch.
|
|
33
|
+
|
|
34
|
+
Reach for `/project` for a quick in-session project change on the same login; use `/switch-profile` to move between separately configured profiles (which may also differ in environment or auth method).
|
|
35
|
+
|
|
36
|
+
### How do I run CODA in batch mode, and how does it authenticate?
|
|
37
|
+
|
|
38
|
+
Run a single prompt headlessly with `-p` (or `--prompt`):
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
coda -p "Summarize the open TODOs in this repo"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
By default a batch run uses your **active profile** (`activeProfile` from `~/.coda/config.json`) — the same credentials you set up interactively, including a stored OAuth session. So the usual flow is: log in once with `/providers` in the TUI, then run `coda -p …` in CI. To target a specific saved profile instead of the active one, pass `--profile <id>`.
|
|
45
|
+
|
|
46
|
+
You can't start an interactive **OAuth browser login** in batch mode — there's no browser to hand off to. For headless OAuth, reuse a profile you already authenticated interactively (`--profile <id>` or the active profile). To provide credentials inline for a one-off run without saving them, use the ephemeral flags — for example `--provider openai-compat --base-url … --api-key …`, or `--provider glob-ai --instance clients --api-key …`. The key is held only in memory and never written to disk. See [Automate with headless mode](#guide-automate) › "Authenticating in batch mode".
|
|
47
|
+
|
|
48
|
+
### CODA opened and immediately shows a setup wizard. Is that normal?
|
|
49
|
+
|
|
50
|
+
Yes. The wizard appears automatically on first launch if no provider is configured. Follow the prompts to add your credentials. You can also trigger it manually at any time with `coda --reconfigure`.
|
|
51
|
+
|
|
52
|
+
### How do I get help from inside CODA?
|
|
53
|
+
|
|
54
|
+
A few ways: type `/help` for the command list, press `?` for the keyboard-shortcuts overlay, or just **ask CODA in plain language** ("how do I undo a change?"). When you ask about CODA itself, it delegates to the built-in **`coda-help`** agent, which answers from the local user guide. You can also call it directly with `/agents run coda-help "<your question>"`. See [Agents](#agents) for more.
|
|
55
|
+
|
|
56
|
+
## Working with sessions
|
|
57
|
+
|
|
58
|
+
### How do I pick up where I left off?
|
|
59
|
+
|
|
60
|
+
Use `coda --lastsession` to resume the most recent session. For a specific session, use `coda --session-id <id>` — when you exit, CODA prints the exact `coda --session-id <id>` command, ready to copy and paste. From inside CODA, browse sessions with `/sessions`.
|
|
61
|
+
|
|
62
|
+
### What does the context percentage in the status bar mean?
|
|
63
|
+
|
|
64
|
+
It shows how full the current conversation context is. When it approaches 100%, CODA automatically compacts the session history. If you're seeing degraded quality near 100%, run `/compact` manually or start a `/new` session.
|
|
65
|
+
|
|
66
|
+
### CODA seems to have "forgotten" something from earlier in the session. Why?
|
|
67
|
+
|
|
68
|
+
Automatic compaction condenses older messages into a summary to keep the session running. If you need full history for debugging, open `/settings` → **Context Compaction** to disable it or adjust when it kicks in.
|
|
69
|
+
|
|
70
|
+
## Making changes
|
|
71
|
+
|
|
72
|
+
### How do I undo what CODA just did?
|
|
73
|
+
|
|
74
|
+
Type `/timeline` (or `/rewind`, or press **Esc** twice) to see all snapshots from this session. Pick the checkpoint from before the message that caused the bad change: CODA restores your files to the state they had right before that message was processed. Requires Git 2.5.0+.
|
|
75
|
+
|
|
76
|
+
### How do I stop CODA from asking me to approve every command?
|
|
77
|
+
|
|
78
|
+
Raise the bash approval level from `/settings` → **Bash Tool Preferences**. Levels are:
|
|
79
|
+
- `safe` — only truly read-only commands; everything else asks.
|
|
80
|
+
- `low` — the default; a conservative set of safe commands and low-risk writes auto-approve.
|
|
81
|
+
- `medium` — more destructive operations auto-approve.
|
|
82
|
+
- `high` — everything auto-approves except the most destructive operations.
|
|
83
|
+
|
|
84
|
+
For a single headless run, pass `--bash-security <level>` (e.g. `--bash-security high`) to override the approval level without changing your saved config. See [Configuration](#configuration) for details.
|
|
85
|
+
|
|
86
|
+
### What is AGENTS.md and should I have one?
|
|
87
|
+
|
|
88
|
+
It's optional, but recommended — especially for shared projects. It's a Markdown file at your project root that CODA reads at the start of every session, where you document your coding conventions, how to run tests, what files not to touch, etc. Generate one with `/init` (or write it by hand), customize it, and commit it to Git so the whole team benefits.
|
|
89
|
+
|
|
90
|
+
## Extensions and tools
|
|
91
|
+
|
|
92
|
+
### How do I connect an MCP server?
|
|
93
|
+
|
|
94
|
+
Open the `/mcp` manager inside CODA and add the server — paste its JSON or import it from a file. From the same place you can check its status, view its tools, and enable or disable it. See [Extend CODA](#guide-extend) for details.
|
|
95
|
+
|
|
96
|
+
### How do I create a skill?
|
|
97
|
+
|
|
98
|
+
Create a `.md` file with YAML frontmatter (`name` and `description` are required) and place it in `<project>/.coda/skills/` or `~/.coda/skills/`. The slash command `/skill-name` invokes it. See [Extend CODA](#guide-extend) for a complete example.
|
|
99
|
+
|
|
100
|
+
### How do I create an extension?
|
|
101
|
+
|
|
102
|
+
The easiest way is to ask CODA: run `/create-extension` and describe what you want in plain language — the built-in `create-extension` skill scaffolds the TypeScript file and places it in the right folder for you. If you'd rather hand-write or fine-tune one, see [Writing Extensions](#extensions) for the full API reference.
|
|
103
|
+
|
|
104
|
+
### What are agents?
|
|
105
|
+
|
|
106
|
+
Agents are Markdown-defined profiles that CODA can use to delegate subtasks — like spawning a second CODA instance to explore one area of the codebase while the main session works on another. CODA picks when to use them automatically, or you can trigger them explicitly with `/agents run <profile> <task>`.
|
|
107
|
+
|
|
108
|
+
### What's the difference between an agent and a workflow?
|
|
109
|
+
|
|
110
|
+
An **agent** handles one delegated task. A **workflow** orchestrates **many** agents — running them in parallel, in pipelines, or in loops — for jobs too big for a single agent, like a repo-wide audit. Ask CODA to build one (it uses the built-in `create-workflow` agent), run it by name in plain language, and monitor it with `/workflows`. See [Workflows](#workflows).
|
|
111
|
+
|
|
112
|
+
### How do I stop a running workflow?
|
|
113
|
+
|
|
114
|
+
Open `/workflows` and press **`c`** on a running entry, or run `/workflows stop <runId>`. Omitting the id (`/workflows stop`) stops **all** in-flight runs for the session. See [Workflows](#workflows).
|
|
115
|
+
|
|
116
|
+
### How do I install a plugin or browse the marketplace?
|
|
117
|
+
|
|
118
|
+
From inside CODA, open the `/plugin` manager to install, enable, disable, and browse the marketplace. From your terminal, `coda plugin install <source>` works too, where `<source>` is an npm package (prefix `npm:`), a Git/HTTPS URL, a local directory path, a `.zip` archive, or a `file://…` URL. CODA is compatible with the Claude Code plugin ecosystem. To browse a marketplace catalog, first register one with `coda marketplace install <source>`; then `/plugin` lists available plugins from that catalog. See [Extend CODA](#guide-extend).
|
|
119
|
+
|
|
120
|
+
## Models and cost
|
|
121
|
+
|
|
122
|
+
### How do I switch models?
|
|
123
|
+
|
|
124
|
+
Press `Shift+Tab` to cycle your favorite models, or run `/switch-model` (alias `/sm`) to open the picker — apply it to just this session or save it as your new default. For a single headless run, pass `--model <name>`.
|
|
125
|
+
|
|
126
|
+
### Where do I see token usage and cost?
|
|
127
|
+
|
|
128
|
+
The TUI status bar shows the context fill percentage and running token/cost figures for the session, so you can keep an eye on how much a long session is consuming.
|
|
129
|
+
|
|
130
|
+
## Operations
|
|
131
|
+
|
|
132
|
+
### Where are my config, sessions, and logs stored?
|
|
133
|
+
|
|
134
|
+
Everything lives under `~/.coda/` — `config.json`, `.secrets`, the session database `coda.db` (with per-session override files under `sessions/<id>/`), `logs/`, `checkpoints/`, and `exports/`. Point `CODA_HOME` at a different directory to relocate all of it — or pass `--coda-home <path>` on the command line (both have the same effect; the flag wins when the env var is not set). See [Configuration Reference](#config-reference).
|
|
135
|
+
|
|
136
|
+
### How do I view or share logs safely?
|
|
137
|
+
|
|
138
|
+
Run `coda logs` for the viewer (filter by `--level`, `--service`, `--since`, or `--follow`). To share with support, `coda logs export` writes a redacted, path-scrubbed bundle to `~/.coda/exports/` — nothing is ever uploaded. Secrets are scrubbed before anything hits disk. See [View & Share Logs](#logging).
|
|
139
|
+
|
|
140
|
+
### Can I use checkpoints in CI?
|
|
141
|
+
|
|
142
|
+
Not for rollback — the `/timeline` picker is a TUI feature. In headless mode checkpoints are off by default; you can pass `--checkpoints=true` to record snapshots as an audit trail, but you can't restore from them without the interactive UI. See [Sessions & Checkpoints](#sessions).
|
|
143
|
+
|
|
144
|
+
### How does CODA behave in a monorepo?
|
|
145
|
+
|
|
146
|
+
It loads exactly one `AGENTS.md` — the one in the directory you launch it from. There's no upward walk or merging. Launch from the package you're working in (`cd packages/billing && coda`). See [Collaborate with Your Team](#guide-collaborate).
|
|
147
|
+
|
|
148
|
+
## See also
|
|
149
|
+
|
|
150
|
+
- [Glossary](#glossary) — definitions for every term used in these answers.
|
|
151
|
+
- [Commands & Flags](#cli-reference) — the complete command and flag reference.
|
|
152
|
+
- [Configuration](#configuration) — where settings live and how they cascade.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Glossary
|
|
2
|
+
|
|
3
|
+
Quick definitions for terms used throughout the docs.
|
|
4
|
+
|
|
5
|
+
| Term | Definition |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| **AGENTS.md** | A Markdown file at your project root that CODA reads at the start of every session. Use it to document your project's conventions, quality gates, and constraints for the agent. |
|
|
8
|
+
| **Agent** | In CODA, an agent is a Markdown-defined profile that describes a specialist persona. CODA can delegate subtasks to agents, running them in parallel for complex work. |
|
|
9
|
+
| **Batch mode** | Headless, non-interactive mode. Run with `coda -p "prompt"`. No TUI, no multi-turn conversation — use in scripts and CI. |
|
|
10
|
+
| **Checkpoint** | A file snapshot taken before each turn — the state from before CODA acts on the message you just sent. Restored via `/timeline` or `/rewind`; your project's Git history is untouched. |
|
|
11
|
+
| **CLI** | The `coda` command-line tool. It runs in two modes: interactive (the TUI) and headless (batch). |
|
|
12
|
+
| **coda-help** | A built-in agent that answers questions about how to use CODA by searching the local user guide. CODA delegates to it automatically when you ask about itself. |
|
|
13
|
+
| **Compaction** | Automatic condensing of older conversation history to free up context window space. Triggered at a configurable fill threshold. |
|
|
14
|
+
| **Extension** | A TypeScript module that registers custom tools, slash commands, or lifecycle hooks into CODA. |
|
|
15
|
+
| **Glob.AI OS** | Globant's internal AI gateway — the primary provider for CODA at Globant. |
|
|
16
|
+
| **MCP** | Model Context Protocol. A standard for connecting AI models to external tools and services. CODA uses MCP servers to talk to GitHub, databases, CI systems, and other integrations. |
|
|
17
|
+
| **MEMORY.md** | Durable notes the agent keeps across sessions — preferences, decisions, and gotchas it learns. Unlike AGENTS.md (which you write), CODA maintains this itself, and it survives checkpoint rollbacks. |
|
|
18
|
+
| **Plugin** | A versioned, installable package that can bundle skills, agents, extensions, and MCP fragments. More structured than an extension; installable via `coda plugin install`. |
|
|
19
|
+
| **Provider** | The AI backend CODA sends prompts to — for example a Glob.AI OS instance, a local Ollama server, or any OpenAI-compatible endpoint. Managed with `/providers`. |
|
|
20
|
+
| **Session** | A persistent CODA conversation. Stored on disk; resumable at any time. |
|
|
21
|
+
| **Skill** | A Markdown file that encodes a repeatable workflow. Invoked with a slash command like `/skill-name`. |
|
|
22
|
+
| **TUI** | Terminal User Interface — the full-screen interface you see when you run `coda` interactively. |
|
|
23
|
+
| **Workflow** | A deterministic script that orchestrates multiple agents — parallel fan-out, multi-stage pipelines, and loops. Authored by the built-in `create-workflow` agent, stored in `.coda/workflows/`, run in the background, and monitored with `/workflows`. |
|
|
24
|
+
| **ACP** | Agent Client Protocol — the integration that lets editors like Zed and JetBrains drive CODA. |
|
|
25
|
+
| **Anti-clobber guard** | The safety check that makes CODA ask before overwriting a file it never read during the current session. |
|
|
26
|
+
| **Approval level** | See *Bash approval level*. The tier (`safe`/`low`/`medium`/`high`) that decides which shell commands run without asking. |
|
|
27
|
+
| **Bash approval level** | The setting (`safe`, `low`, `medium`, `high`) controlling how many shell commands CODA auto-approves. Set from `/settings` → Bash Tool Preferences. |
|
|
28
|
+
| **`.codaignore`** | A gitignore-syntax file at your project root with glob patterns (and optional `!negation` lines) to exclude from — or forcibly include in — checkpoints. Shares `.gitignore` semantics, so patterns, directory globs, and negations all work. |
|
|
29
|
+
| **Context window** | The amount of conversation CODA can hold at once. The status-bar percentage shows how full it is; compaction frees room as it fills. |
|
|
30
|
+
| **Drift** | Uncaptured changes in your worktree at restore time. CODA stops the restore so you don't lose work; press **F** to force it. |
|
|
31
|
+
| **`fastModel`** | The model the literal `model: "fast"` shortcut resolves to, used for cheap, high-volume agent runs. Can be configured per-provider (`providers.<key>.fastModel`) or globally under `agents.fastModel`; CODA also supplies a built-in Glob.AI OS fallback when neither is set. |
|
|
32
|
+
| **`smartModel`** | The model the literal `model: "smart"` shortcut resolves to — the balanced mid-tier for agent runs. Configured under `agents.smartModel` or per-provider. |
|
|
33
|
+
| **`deepModel`** | The model the literal `model: "deep"` shortcut resolves to — the highest-capability, most expensive tier. Configured under `agents.deepModel` or per-provider. |
|
|
34
|
+
| **HITL** | Human-in-the-loop — the approval model where CODA pauses to ask before risky actions. |
|
|
35
|
+
| **Headless mode** | See *Batch mode*. |
|
|
36
|
+
| **Marketplace** | The catalog of installable plugins, reachable from the `/plugin` manager; Claude Code-ecosystem compatible. |
|
|
37
|
+
| **Redaction** | The always-on scrubbing of secret-looking keys and values from logs before they're written to disk. |
|
|
38
|
+
| **ripgrep / fastgrep** | The two content-search backends behind the `grep` tool. ripgrep ships bundled and is the default. |
|
|
39
|
+
| **Shadow repository** | The private Git repo where checkpoints are stored, separate from your project's own `.git`. Located at `~/.coda/checkpoints/<hash>/` by default (one per project, keyed by a SHA-256 of the project path). The base directory can be relocated via `CODA_HOME`. |
|
|
40
|
+
| **Steering / Queuing** | What happens when you send a message mid-turn: *queue* delivers it as the next turn (default); *steer* injects it into the run in progress. Set under `/settings` → Composer. |
|
|
41
|
+
| **Timeline** | The `/timeline` (alias `/rewind`) picker for viewing and restoring checkpoints. |
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Automate with Batch Mode
|
|
2
|
+
|
|
3
|
+
Batch mode (also called headless mode) lets you run CODA from a shell script or CI pipeline — no terminal UI, no interaction. You give it a prompt, it runs, and it exits. This is how you integrate CODA into automated workflows.
|
|
4
|
+
|
|
5
|
+
## When to use batch mode
|
|
6
|
+
|
|
7
|
+
- Running CODA as a step in a CI pipeline (generate docs, run a code review, apply a linting fix)
|
|
8
|
+
- Scripting repetitive tasks across multiple repos
|
|
9
|
+
- Triggering CODA from a webhook or external event
|
|
10
|
+
- Running a long analysis job and checking the result later
|
|
11
|
+
|
|
12
|
+
For day-to-day coding where you want to review changes as they happen, use the [interactive TUI](#cli-vs-batch) instead.
|
|
13
|
+
|
|
14
|
+
## Basic usage
|
|
15
|
+
|
|
16
|
+
The simplest batch run: pass a prompt with `-p`.
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
cd /path/to/project
|
|
20
|
+
coda -p "Summarize what this repo does in five bullet points"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
CODA runs, prints the result, and exits. No UI, no interaction.
|
|
24
|
+
|
|
25
|
+
## Practical examples
|
|
26
|
+
|
|
27
|
+
**Generate a changelog from recent commits**
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
coda -p "Look at the last 20 git commits and write a CHANGELOG entry for this week's changes."
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Check for security issues before merging**
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
coda -p "Review the changes in this PR for potential security issues. Focus on input validation, SQL queries, and authentication checks."
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Run from a prompt file**
|
|
40
|
+
|
|
41
|
+
For longer or more structured prompts, put the prompt in a file:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
coda --prompt-file ./scripts/review-prompt.txt
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Use in a CI pipeline**
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
#!/bin/bash
|
|
51
|
+
coda -p "Run the test suite and report any failures" \
|
|
52
|
+
--auto-approve all \
|
|
53
|
+
--output json \
|
|
54
|
+
--timeout 600000
|
|
55
|
+
|
|
56
|
+
EXIT=$?
|
|
57
|
+
if [ $EXIT -ne 0 ]; then
|
|
58
|
+
echo "CODA run failed with exit code $EXIT"
|
|
59
|
+
exit $EXIT
|
|
60
|
+
fi
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Important flags for automation
|
|
64
|
+
|
|
65
|
+
| Flag | What it does |
|
|
66
|
+
| --- | --- |
|
|
67
|
+
| `-p` / `--prompt "…"` | The prompt to run |
|
|
68
|
+
| `--prompt-file` / `-pf path` | Read the prompt from a file |
|
|
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 everything (needed in CI); `none` denies and aborts on the first request |
|
|
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
|
+
| `--lastsession` | Resume the most recent session for this project (mutually exclusive with `--session-id`). |
|
|
74
|
+
| `--tools default\|all\|*list*` | Limit available tools, e.g. `read,glob,grep` for a read-only run |
|
|
75
|
+
| `--model` / `-m id` | Override the model for this run |
|
|
76
|
+
| `--session-id` / `-s id` | Resume or create a session with a specific id |
|
|
77
|
+
| `--checkpoints=true` | Enable file snapshots (off by default in headless runs) |
|
|
78
|
+
| `--profile id` | Use a specific persisted profile for this run (read-only; doesn't change your saved `activeProfile`) |
|
|
79
|
+
| `--provider name` | Ephemeral run provider: `glob-ai`, `openai-compat`, or `ollama` (default `glob-ai`) |
|
|
80
|
+
| `--instance id` | Glob.AI OS instance for an ephemeral run (`clients`, `corp`, `saas-europe`; default `saas-europe`) |
|
|
81
|
+
| `--base-url url` | Base URL for an ephemeral `openai-compat` / `ollama` run |
|
|
82
|
+
| `--api-key key` | Ephemeral, run-only API key — held in memory, never persisted, redacted in logs |
|
|
83
|
+
|
|
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. For finer control over which shell commands run, also set `bash.autoApproveLevel` in `config.json` (it defaults to `high` in headless mode).
|
|
85
|
+
|
|
86
|
+
## Authenticating in batch mode
|
|
87
|
+
|
|
88
|
+
A batch run needs credentials just like an interactive one, but there's no wizard and no browser. There are three ways it finds them, in order of precedence:
|
|
89
|
+
|
|
90
|
+
1. **Ephemeral flags (one-off)** — pass credentials inline for a single run: `--provider`, `--instance`, `--base-url`, `--api-key`. CODA builds a run-only profile; the key is kept in memory and never written to disk. Examples:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# OpenAI-compatible endpoint, key from an environment variable
|
|
94
|
+
coda -p "Review this diff" --provider openai-compat \
|
|
95
|
+
--base-url https://api.example.com/v1 --api-key "$MY_API_KEY"
|
|
96
|
+
|
|
97
|
+
# Glob.AI OS Clients instance with an API key
|
|
98
|
+
coda -p "Summarize the changes" --provider glob-ai \
|
|
99
|
+
--instance clients --api-key "$CODA_GEAI_CLIENTS_API_KEY"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
2. **A named profile** — `--profile <id>` reuses a profile you already configured in the TUI, **including its stored OAuth session**. This is the recommended way to use OAuth in CI: sign in once interactively with `/providers`, then reference that profile from your pipeline.
|
|
103
|
+
|
|
104
|
+
3. **The active profile** — with no provider flags at all, the run uses `activeProfile` from `~/.coda/config.json` (the same profile the TUI would open with).
|
|
105
|
+
|
|
106
|
+
> **OAuth can't be *started* headlessly.** The interactive browser sign-in only works in the TUI. For OAuth in batch mode, authenticate once interactively and then reuse that profile (`--profile <id>` or the active profile). Passing `--api-key` to a `glob-ai` run uses key-based auth instead, which needs no browser.
|
|
107
|
+
|
|
108
|
+
## Reading the output
|
|
109
|
+
|
|
110
|
+
With `--output text` (the default), CODA prints its final answer to stdout. With `--output json`, it emits **newline-delimited JSON events** — one object per line — so a pipeline can parse progress and the final result. Successful runs emit a `{ type: "agent_response", payload: { status: "ok", response: "..." } }` event; failures emit `{ type: "headless_error", payload: { ... } }`. Pair it with `jq` in a script:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
coda -p "Summarize the open TODOs in this repo" --output json \
|
|
114
|
+
| jq -r 'select(.type=="agent_response") | .payload.response'
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Always check the **exit code**: a non-zero status means the run failed (an error, a timeout, or — with `--auto-approve none` — a denied approval), so your CI step can fail fast.
|
|
118
|
+
|
|
119
|
+
## Scope it down for safety
|
|
120
|
+
|
|
121
|
+
Unattended runs are safest when you limit what the agent can touch:
|
|
122
|
+
|
|
123
|
+
- **Restrict tools** with `--tools` — e.g. `--tools read,glob,grep` for a read-only review that can't edit or run commands.
|
|
124
|
+
- **Tune bash** with `--bash-security` (or `bash.autoApproveLevel` in config) so even an auto-approved run won't run beyond the tier you set.
|
|
125
|
+
- **Cap runtime** with `--timeout` so a stuck run can't hang the pipeline.
|
|
126
|
+
|
|
127
|
+
## What batch mode can't do
|
|
128
|
+
|
|
129
|
+
Batch mode runs a single turn — one prompt, one response. It doesn't support multi-turn conversation or interactive review. The `ask_user` tool isn't available (there's no one to answer), and there's no `/timeline` to roll back from — pass `--checkpoints=true` only if you want snapshots recorded for an audit trail. For tasks that require back-and-forth, use the [interactive TUI](#cli-vs-batch).
|
|
130
|
+
|
|
131
|
+
## See also
|
|
132
|
+
|
|
133
|
+
- [Interactive vs Headless](#cli-vs-batch) — choosing between the two modes.
|
|
134
|
+
- [Commands & Flags](#cli-reference) — the complete flag and subcommand reference.
|
|
135
|
+
- [Permissions & Approvals](#permissions) — how approvals behave when no one is watching.
|