@armadra/agent 0.6.2 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/CHANGELOG.zh-CN.md +59 -0
  3. package/README.md +168 -575
  4. package/README.zh-CN.md +165 -596
  5. package/dist/agent/queue.d.ts +9 -0
  6. package/dist/agent/queue.js +27 -0
  7. package/dist/agent/session-subagent.d.ts +1 -0
  8. package/dist/agent/session-subagent.js +9 -0
  9. package/dist/agent/session.d.ts +11 -0
  10. package/dist/agent/session.js +29 -2
  11. package/dist/agent/subagent-background.d.ts +75 -0
  12. package/dist/agent/subagent-background.js +209 -0
  13. package/dist/agent/subagent-direct.d.ts +5 -2
  14. package/dist/agent/subagent-direct.js +34 -1
  15. package/dist/agent/subagent-registry.d.ts +26 -6
  16. package/dist/agent/subagent-registry.js +66 -94
  17. package/dist/agent/types-w5.d.ts +11 -1
  18. package/dist/agent/types.d.ts +12 -0
  19. package/dist/agents/builtin.js +0 -1
  20. package/dist/agents/external.js +0 -1
  21. package/dist/agents/parse.js +4 -3
  22. package/dist/agents/result.d.ts +7 -1
  23. package/dist/agents/result.js +20 -1
  24. package/dist/agents/task-control.d.ts +13 -2
  25. package/dist/agents/task-record.d.ts +16 -4
  26. package/dist/agents/task-record.js +32 -0
  27. package/dist/agents/types.d.ts +5 -1
  28. package/dist/ai/apis/chatgpt-rate-limits.js +7 -2
  29. package/dist/ai/providers/discovered-cache.d.ts +10 -4
  30. package/dist/ai/providers/discovered-cache.js +30 -14
  31. package/dist/ai/types.d.ts +2 -1
  32. package/dist/auth/chatgpt/backend-client.d.ts +6 -5
  33. package/dist/auth/chatgpt/backend-client.js +8 -7
  34. package/dist/bundle/ama.cjs +2034 -552
  35. package/dist/cli/compose-agents.d.ts +2 -1
  36. package/dist/cli/compose-agents.js +11 -2
  37. package/dist/cli/subcommands/models-discover.d.ts +1 -0
  38. package/dist/cli/subcommands/models-discover.js +12 -2
  39. package/dist/config/json-schema.js +10 -2
  40. package/dist/config/key-docs.js +9 -2
  41. package/dist/config/merge.d.ts +1 -1
  42. package/dist/config/merge.js +20 -3
  43. package/dist/config/schema-w5.js +4 -2
  44. package/dist/config/schema.js +4 -0
  45. package/dist/config/settings-registry.js +5 -0
  46. package/dist/config/types-w5.d.ts +10 -0
  47. package/dist/config/types-w5.js +2 -0
  48. package/dist/config/types.d.ts +5 -1
  49. package/dist/drivers/runner.js +29 -2
  50. package/dist/git/info.d.ts +19 -0
  51. package/dist/git/info.js +64 -8
  52. package/dist/i18n/catalog.d.ts +58 -8
  53. package/dist/i18n/messages/agents.d.ts +60 -0
  54. package/dist/i18n/messages/agents.js +62 -2
  55. package/dist/i18n/messages/config-keys.d.ts +8 -0
  56. package/dist/i18n/messages/config-keys.js +18 -10
  57. package/dist/i18n/messages/config.d.ts +8 -0
  58. package/dist/i18n/messages/interactive-startup.d.ts +0 -16
  59. package/dist/i18n/messages/interactive-startup.js +0 -16
  60. package/dist/i18n/messages/interactive-view.d.ts +8 -0
  61. package/dist/i18n/messages/interactive-view.js +10 -0
  62. package/dist/i18n/messages/interactive.d.ts +33 -16
  63. package/dist/i18n/messages/interactive.js +31 -0
  64. package/dist/i18n/messages/print.d.ts +4 -0
  65. package/dist/i18n/messages/print.js +4 -0
  66. package/dist/i18n/messages/report.d.ts +8 -0
  67. package/dist/i18n/messages/report.js +12 -4
  68. package/dist/i18n/messages/settings.d.ts +8 -0
  69. package/dist/i18n/messages/settings.js +8 -0
  70. package/dist/i18n/messages/subcommands-config.d.ts +4 -0
  71. package/dist/i18n/messages/subcommands-config.js +4 -0
  72. package/dist/i18n/messages/subcommands.d.ts +4 -0
  73. package/dist/index.d.ts +1 -0
  74. package/dist/modes/commands-core.js +19 -4
  75. package/dist/modes/interactive/agent-bar.d.ts +3 -1
  76. package/dist/modes/interactive/agent-bar.js +12 -5
  77. package/dist/modes/interactive/agent-ui.d.ts +21 -3
  78. package/dist/modes/interactive/agent-ui.js +82 -12
  79. package/dist/modes/interactive/agent-view.d.ts +9 -0
  80. package/dist/modes/interactive/agent-view.js +28 -4
  81. package/dist/modes/interactive/approval-dock.d.ts +51 -0
  82. package/dist/modes/interactive/approval-dock.js +112 -0
  83. package/dist/modes/interactive/approval-ui.d.ts +43 -0
  84. package/dist/modes/interactive/approval-ui.js +64 -0
  85. package/dist/modes/interactive/commands.js +4 -1
  86. package/dist/modes/interactive/event-notices.d.ts +6 -1
  87. package/dist/modes/interactive/event-notices.js +7 -1
  88. package/dist/modes/interactive/interactive-mode.d.ts +4 -2
  89. package/dist/modes/interactive/interactive-mode.js +46 -39
  90. package/dist/modes/interactive/interrupt-send.d.ts +25 -0
  91. package/dist/modes/interactive/interrupt-send.js +32 -0
  92. package/dist/modes/interactive/key-dispatch.d.ts +29 -5
  93. package/dist/modes/interactive/key-dispatch.js +97 -8
  94. package/dist/modes/interactive/line/line-mode.d.ts +1 -0
  95. package/dist/modes/interactive/line/line-mode.js +34 -7
  96. package/dist/modes/interactive/run-indicator.d.ts +34 -2
  97. package/dist/modes/interactive/run-indicator.js +62 -8
  98. package/dist/modes/interactive/session-events.js +5 -1
  99. package/dist/modes/interactive/startup-header.d.ts +29 -14
  100. package/dist/modes/interactive/startup-header.js +93 -59
  101. package/dist/modes/interactive/startup-logo.d.ts +83 -0
  102. package/dist/modes/interactive/startup-logo.js +183 -0
  103. package/dist/modes/interactive/status-area.d.ts +18 -0
  104. package/dist/modes/interactive/status-area.js +67 -1
  105. package/dist/modes/interactive/status-bar.d.ts +13 -2
  106. package/dist/modes/interactive/status-bar.js +60 -17
  107. package/dist/modes/interactive/status-line.d.ts +11 -8
  108. package/dist/modes/interactive/status-line.js +52 -39
  109. package/dist/modes/interactive/status-quota.d.ts +58 -0
  110. package/dist/modes/interactive/status-quota.js +155 -0
  111. package/dist/modes/interactive/subagent-view.d.ts +1 -0
  112. package/dist/modes/interactive/subagent-view.js +8 -0
  113. package/dist/modes/interactive/task-background.d.ts +31 -0
  114. package/dist/modes/interactive/task-background.js +68 -0
  115. package/dist/modes/interactive/tool-view.d.ts +7 -1
  116. package/dist/modes/interactive/tool-view.js +24 -1
  117. package/dist/modes/print/print-mode.d.ts +11 -0
  118. package/dist/modes/print/print-mode.js +36 -1
  119. package/dist/modes/rpc/commands.d.ts +4 -1
  120. package/dist/modes/rpc/commands.js +24 -2
  121. package/dist/rpc.d.ts +20 -0
  122. package/dist/rpc.js +3 -0
  123. package/dist/tools/task-ctl.d.ts +2 -0
  124. package/dist/tools/task-ctl.js +7 -2
  125. package/dist/tools/task.d.ts +11 -0
  126. package/dist/tools/task.js +20 -2
  127. package/dist/tools/types.d.ts +6 -0
  128. package/dist/tui/components/editor.d.ts +2 -0
  129. package/dist/tui/components/editor.js +4 -0
  130. package/dist/tui/components/loader.d.ts +5 -1
  131. package/dist/tui/components/loader.js +18 -5
  132. package/dist/tui/keybindings.d.ts +15 -3
  133. package/dist/tui/keybindings.js +15 -3
  134. package/docs/agents.md +52 -28
  135. package/docs/en/host-api.md +5 -1
  136. package/docs/en/providers.md +1 -1
  137. package/docs/en/rpc.md +28 -14
  138. package/docs/en/sessions.md +3 -1
  139. package/docs/en/tui.md +106 -70
  140. package/docs/host-api.md +5 -1
  141. package/docs/providers.md +4 -2
  142. package/docs/rpc.md +28 -14
  143. package/docs/session-format.md +1 -1
  144. package/docs/sessions.md +2 -1
  145. package/docs/tui-design.md +42 -29
  146. package/docs/tui.md +106 -70
  147. package/package.json +1 -1
package/README.md CHANGED
@@ -3,560 +3,152 @@
3
3
  [![CI](https://github.com/Owlbay/armadra-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/Owlbay/armadra-agent/actions/workflows/ci.yml)
4
4
  [![npm](https://img.shields.io/npm/v/@armadra/agent)](https://www.npmjs.com/package/@armadra/agent)
5
5
  [![license](https://img.shields.io/npm/l/@armadra/agent)](LICENSE)
6
+ [![node](https://img.shields.io/node/v/@armadra/agent)](https://nodejs.org)
6
7
 
7
8
  English · [简体中文](README.zh-CN.md)
8
9
 
9
- A coding agent for the terminal that can also be embedded in the [Armadra](https://github.com/yovinchen/Armadra) canvas as a coordinator. Written in TypeScript with zero runtime dependencies, and also shipped as a single-file build.
10
+ A coding agent for your terminal that can also coordinate other agents. Use it on its own, or embed it in the [Armadra](https://github.com/Owlbay/Armadra) canvas.
10
11
 
11
- ```sh
12
- npm i -g @armadra/agent
13
- export ANTHROPIC_API_KEY=sk-... # a key from any supported provider works
14
- ama
12
+ ```text
13
+ ▄███▄ ██▄ ▄██ ▄███▄ ama
14
+ ██▀ ▀██ ███▄ ▄███ ██▀ ▀██ anthropic/claude-sonnet-4-5@messages · thinking medium
15
+ ███████ ██ ▀█▀ ██ ███████ ~/Projects/demo · trusted
16
+ ██ ██ ██ ██ ██ ██ Accept edits · preset default
17
+ ▀▀ ▀▀ ▀▀ ▀▀ ▀▀ ▀▀ AGENTS.md · 2 Skill
18
+ /help commands · Shift+Tab mode · Ctrl+O expand tool output
15
19
  ```
16
20
 
17
- ## Contents
18
-
19
- - [Why ama](#why-ama)
20
- - [Features](#features)
21
- - [Install](#install)
21
+ - [What is ama](#what-is-ama)
22
22
  - [Quick start](#quick-start)
23
- - [Configuration](#configuration)
24
- - [Relays and gateways](#relays-and-gateways)
25
- - [ChatGPT login](#chatgpt-login)
26
- - [Tools and presets](#tools-and-presets)
27
- - [Caching](#caching)
28
- - [Safety](#safety)
29
- - [Sandbox](#sandbox)
30
- - [Plan](#plan)
31
- - [Sub-agents](#sub-agents)
32
- - [External agents](#external-agents)
33
- - [Rewind](#rewind)
34
- - [Memory](#memory)
35
- - [Traces](#traces)
36
- - [Interfaces and entry points](#interfaces-and-entry-points)
37
- - [Embedding in Armadra](#embedding-in-armadra)
23
+ - [Capabilities](#capabilities)
24
+ - [Embedding and integration](#embedding-and-integration)
25
+ - [Command reference](#command-reference)
26
+ - [Exit codes](#exit-codes)
38
27
  - [Documentation](#documentation)
39
28
  - [Known limitations](#known-limitations)
40
29
  - [Development](#development)
30
+ - [License and acknowledgements](#license-and-acknowledgements)
41
31
 
42
- ## Why ama
43
-
44
- - **An agent built to be called**: ama is driven by other programs as often as by people. One-shot `-p` runs, `--mode rpc`, the SDK and host adapters are all first-class entry points; exit codes and JSON shapes are contracts.
45
- - **Clean layering**: following Pi's layering, protocol implementations are separate from provider data. Four protocol lines (Anthropic Messages, OpenAI Chat Completions, OpenAI Responses, Google Generative AI) are written once; a provider is just "baseUrl + key + model table + compat switches".
46
- - **Minimal configuration**: one environment variable is enough to start; the common settings are five keys and everything else has a default. API keys only (official or relay), Skills and built-in tools only, no MCP.
47
- - **Cache first**: most of the usage in long tasks is cache reads. ama keeps the request prefix byte-stable, places cache breakpoints the way each provider expects, and shows whether the cache works and why it missed.
48
- - **Two ways to use it**: standalone it is a terminal coding agent; embedded in Armadra it is the coordinator on the canvas, dispatching work to CLI agents such as Claude Code, Codex and OpenCode, collecting their reports and summarizing.
49
-
50
- ## Features
51
-
52
- | Area | What you get |
53
- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
54
- | Protocols and providers | 4 protocol lines, 18 built-in providers (Anthropic, OpenAI, Google, DeepSeek, Moonshot, Zhipu, Qwen, OpenRouter, Groq, xAI, Mistral, MiniMax, StepFun, Volcengine Ark, Tencent, ChatGPT plan login, Ollama, LM Studio), built-in channels (Messages / Responses preferred, Chat as fallback), custom providers, per-model protocols |
55
- | Zero config and relays | With a key present, the first available provider is picked (relays pick a default model by price rules); `OPENAI_BASE_URL` / `ANTHROPIC_BASE_URL` are recognized; `ama providers add` connects a relay from just a baseUrl and key: lists models, probes channels and writes the config back |
56
- | Model metadata | Context window, output limit, image input, reasoning and prices come from a bundled models.dev snapshot (no network at startup or runtime; `ama models refresh` updates explicitly); one provider can mount several channels (Chat / Responses / Messages), `provider/model@channel` |
57
- | Image input | `-p --image`, `@image-path` in the interface, `Ctrl+V` / `/paste` for clipboard images; per-endpoint size tiers with automatic resizing; models without image input refuse up front and suggest switching |
58
- | Tools and presets | read / edit / write / bash / grep / glob, plus ls, todo, task / task_ctl (sub-agents) and codemode; four presets `default` / `minimal` / `codemode-only` / `coordinator` |
59
- | Plan and sub-agents | Plan mode researches read-only, proposes a plan and executes after approval; `task` delegates to sub-agents (built-in general / explore / plan, custom types, foreground / background / follow-up / worktree isolation); an agent bar and a live sub-agent view you can talk to directly |
60
- | External agents | `task(agent="claude" \| "codex" \| "acp:<program>")` drives external coding agents with each CLI's own login, and approvals go to a human only; `ama --mode acp` exposes ama as an ACP agent |
61
- | Rewind and sandbox | A checkpoint per turn; `/rewind` / double Esc returns to before any message (code, conversation or both); an OS sandbox on macOS / Linux isolates codemode and (optionally) bash |
62
- | codemode | The model writes a piece of JS that orchestrates many tool calls in a child process constrained by the Node permission model; only the output goes back to the model |
63
- | Skills | `SKILL.md` directories; the model reads them from an index, users invoke them with `/skill:<name>`; prompt templates too |
64
- | Two hook layers | Command hooks (`hooks.json`, 11 events, user policy) and the in-process host adapter HostApi (for embedders) |
65
- | Permissions | Four modes, allow / deny rules, dangerous-command detection (sees through `sh -c` / `eval` / `xargs` / `find -exec`), project trust, a pre-execution preview in approvals |
66
- | Caching | A stable prefix, cache fields and compat switches, miss attribution, a three-state "reports / does not report cache" model, warming during long tool runs, compaction summaries that continue the session prefix |
67
- | Sessions | A JSONL entry tree with forks and `/tree` navigation; two-tier compaction (prune large tool results → summarize) with a circuit breaker; budgets (`--max-turns` / `--max-cost`), repeated-call detection, model fallback |
68
- | Memory and traces | Opt-in cross-session memory (Markdown files, an index in the system prompt); a trace of every turn, request and tool with TTFT / decode / tool timing, in the TUI (`/trace`), as a single-file HTML page or over RPC |
69
- | Settings and language | `/config` settings panel and `ama config get / set`; Chinese and English interface (`--lang`, `ui.language`, `AMA_LANG`) |
70
- | Entry points | A differential-rendering terminal UI, `--no-tui` line mode, `-p` (text / json / stream-json), `--mode rpc`, `--mode acp`, the SDK |
71
-
72
- ## Install
73
-
74
- Requires **Node ≥ 22**.
75
-
76
- ### npm
77
-
78
- ```sh
79
- npm i -g @armadra/agent
80
- ama --version
81
- ```
82
-
83
- ### Single-file release
84
-
85
- [Releases](https://github.com/Owlbay/armadra-agent/releases) ship `ama.cjs`, `ama-sandbox.cjs`, `package.tgz` and `SHA256SUMS`. `ama.cjs` is a fully inlined single file and `ama-sandbox.cjs` is the codemode sandbox child-process entry; keep both in the **same directory**:
86
-
87
- ```sh
88
- sha256sum -c --ignore-missing SHA256SUMS # macOS: shasum -a 256 -c --ignore-missing SHA256SUMS
89
- node ama.cjs --version
90
- alias ama="node /path/to/ama.cjs"
91
- ```
92
-
93
- `package.tgz` has the same content as the npm package and can be installed offline: `npm i -g ./package.tgz`.
94
-
95
- ### Build from source
96
-
97
- ```sh
98
- git clone https://github.com/Owlbay/armadra-agent.git && cd armadra-agent
99
- corepack enable && pnpm install
100
- pnpm build # produces dist/ and dist/bundle/ama.cjs, dist/bundle/ama-sandbox.cjs
101
- node dist/bundle/ama.cjs --version
102
- ```
32
+ ## What is ama
103
33
 
104
- ### Node version, codemode and sandbox
34
+ ama reads, edits and runs code in your project from a terminal UI, and answers one-shot questions with `ama -p`. It can also hand work to other agents: its own sub-agents, or external coding agents such as Claude Code, Codex and any ACP agent, each using that CLI's own login. Inside Armadra it acts as the coordinator on the canvas: it dispatches work to other CLI agents, collects their reports and summarizes them.
105
35
 
106
- | Node / platform | codemode | bash sandbox (`sandbox.bash: "auto"`) |
107
- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
108
- | ≥ 25 | File system and network both isolated; `codemode` counts as a read-only tool and needs no approval in `default` permission mode; the `default` preset **enables** codemode by default | Depends on the platform (next two rows) |
109
- | 22 / 24 + OS sandbox (macOS, most Linux) | The child process starts through `sandbox-exec` / bubblewrap and the kernel denies network; same as Node ≥ 25: read-only class, enabled by default in the `default` preset | Available with macOS `sandbox-exec` or Linux bubblewrap (`unshare` does not count) |
110
- | 22 / 24 without an OS sandbox (e.g. Windows) | File system isolated, **network not isolated**; `codemode` counts as an execute-class tool and needs approval every time (red `net!` in the status bar); the `default` preset does **not** enable codemode, with a one-time notice per config directory | Not available; bash asks for approval as usual |
36
+ Design choices:
111
37
 
112
- Everything else works the same from Node 22 on. `ama doctor` shows the OS sandbox capabilities of the machine ([docs/sandbox.md](docs/sandbox.md), Chinese); `sandbox.enabled: "off"` or `AMA_SANDBOX=off` turns it off. To use codemode without network isolation, enable it explicitly: `--codemode on` or `"codemode": { "mode": "on" }` in the config. `codemode.requireStrict: true` disables codemode outright when the network is not isolated.
38
+ - **Small and self-contained**: TypeScript with zero runtime dependencies; also shipped as a single `ama.cjs` file. Requires Node ≥ 22.
39
+ - **Built to be called**: `-p`, `--mode rpc`, `--mode acp`, the SDK and host adapters are first-class entry points; exit codes and JSON shapes are contracts.
40
+ - **Cache first**: the request prefix stays byte-stable, cache breakpoints follow each provider, and the UI shows whether the cache works and why it missed. The system prompt plus tool table of the main presets stays within token budgets enforced by tests.
41
+ - **Approvals are never answered for you**: neither ama nor the model answers a permission prompt on a person's behalf; when nobody can approve, the answer is "deny".
42
+ - **Skills, not MCP**: extend ama with `SKILL.md` directories, prompt templates, command hooks and host adapters.
43
+ - **Little configuration**: one environment variable is enough to start; everything else has a default.
113
44
 
114
45
  ## Quick start
115
46
 
116
- **Zero config**: set the standard environment variable of any provider and go. ama picks the first provider with a key in built-in order, and that provider's default model (`ama config show` explains which and why). Without any key, startup tells you how to configure one instead of silently using the test `fake` provider.
117
-
118
- ```sh
119
- export ANTHROPIC_API_KEY=sk-... # or OPENAI_API_KEY, GEMINI_API_KEY, DEEPSEEK_API_KEY, MOONSHOT_API_KEY …
120
- cd your-project
121
- ama # terminal UI
122
- ```
123
-
124
- **Store a key**: if you prefer not to keep it in the environment, store it in `~/.config/ama/auth.json` (0600). The key is read from stdin, never from command-line arguments, so it stays out of shell history:
125
-
126
- ```sh
127
- ama auth set deepseek # type it in the terminal (not echoed)
128
- ama auth list # lists providers and key shapes only, never the key
129
- ama auth remove deepseek
130
- ```
131
-
132
- **One-shot runs**: `-p` exits when done, for scripts and pipes.
133
-
134
- ```sh
135
- ama -p "explain src/index.ts"
136
- git diff | ama -p "review this change" # the prompt can come from stdin too
137
- ama -p "list the TODOs" --model deepseek/deepseek-v4-pro --output-format json
138
- ```
139
-
140
- **Common flags**:
141
-
142
- | Flag | Effect |
143
- | ------------------------------------------------------- | --------------------------------------------------------------------------- |
144
- | `--model provider/id` | Pick a model (same syntax in config, command line, `/model` and the SDK) |
145
- | `--thinking off\|minimal\|low\|medium\|high\|xhigh` | Thinking level (default `medium`) |
146
- | `--permission-mode plan\|default\|auto-edit\|full-auto` | Permission mode (default `default`) |
147
- | `-c` / `-r [id]` | Continue the latest session in this directory / pick a session to resume |
148
- | `--tools-preset <name>` | Tool preset (see below) |
149
- | `--allow <rule>` / `--deny <rule>` | Add permission rules; repeatable |
150
- | `--max-turns N` / `--max-cost USD` | Turn / USD limit per run (`-p` exits with 8 when reached) |
151
- | `--agent-dir <dir>` | Extra sub-agent definition directory; repeatable |
152
- | `--lang zh\|en` | Interface language (also `AMA_LANG` and `ui.language`) |
153
- | `--memory` / `--no-memory` | Turn memory on / off for this launch |
154
- | `--mode rpc` / `--mode acp` | Speak RPC (JSONL) / ACP (JSON-RPC) on stdio, for hosts and editors to drive |
155
-
156
- **Built-in providers** (18): Anthropic, OpenAI, Google, DeepSeek, Moonshot (Kimi), Zhipu, Qwen (DashScope), OpenRouter, Groq, xAI, Mistral, MiniMax, StepFun, Volcengine Ark, Tencent TokenHub, ChatGPT (sign in with your plan, see "ChatGPT login"), Ollama, LM Studio. Multi-protocol providers ship built-in channels with Messages / Responses preferred and Chat as fallback: OpenAI, xAI and Volcengine Ark use Responses; Qwen, MiniMax, StepFun and Tencent use Messages; DeepSeek, Zhipu and Kimi use Chat for now (`@messages` is optional). `provider/model@channel` picks a channel. The full table is in [docs/en/providers.md](docs/en/providers.md) "Built-in providers".
157
-
158
- Local Ollama / LM Studio need no key: `ama --model ollama/<model>`. `ama --help` lists every flag and subcommand; for tests and troubleshooting use the free `--model fake/echo` (echoes the last user message; the model picker, `models list` and `doctor` hide this test provider unless `AMA_SHOW_FAKE=1`).
159
-
160
- ## Configuration
161
-
162
- One file: `~/.config/ama/config.json`. The first time you enter a conversation (interactive, `-p`, RPC) or run `ama providers add`, ama creates the directory (0700), a minimal `config.json` and a `config.schema.json` for editors; read-only commands such as `config show`, `doctor` and `models list` never write the config directory. You can also run `ama init` by hand (existing files are not overwritten). The generated `config.json` holds only `$schema`, `version` and empty `providers`, with no hard-coded defaults, so old configs follow when defaults change later. `ama config path` prints where each file lives, `ama config edit` opens it with `$VISUAL` / `$EDITOR`, and `config.schema.json` carries a description and default for every key, visible on hover in editors. The common settings are just five keys:
163
-
164
- ```json
165
- {
166
- "$schema": "./config.schema.json",
167
- "version": 1,
168
- "defaultModel": "anthropic/<model-id>",
169
- "thinkingLevel": "medium",
170
- "permission": { "mode": "default", "allow": ["bash(git status*)"], "deny": ["write(**/.env*)"] },
171
- "tools": { "preset": "default" },
172
- "providers": {}
173
- }
174
- ```
175
-
176
- Everything else (`compaction`, `retry`, `codemode`, `hooks`, `ui`, `skills`, `cache`, `request`) has defaults. `ama config show` lists the effective value and source (default / user / profile / project / cli) of every key, and also accepts `--tools-preset` / `--codemode` to preview overrides.
177
-
178
- **Request timeout**: model requests have an idle timeout, 300 s by default. Waiting longer than that for response headers, or between two chunks of the stream, counts as stuck and is retried with `retry` backoff as a retryable error (any byte received resets the timer, so long answers are unaffected). Adjust with `request.idleTimeoutMs` (user level only) or the `AMA_IDLE_TIMEOUT_MS` environment variable; 0 disables it.
179
-
180
- **Interface language**: choose it with `ui.language` (`auto` / `zh` / `en`, default `auto`), `--lang zh|en` or the `AMA_LANG` environment variable. `auto` decides from `LC_ALL` / `LC_MESSAGES` / `LANG`: `zh*` is Chinese, anything else English (to keep Chinese regardless: `ama config set ui.language zh`). It affects the interface and config descriptions only (`config.schema.json` is written in the current language; run `ama init` again after switching to rewrite it); text sent to the model is always English. To have the model reply in a given language, set `ui.replyLanguage`. See [docs/i18n.md](docs/i18n.md) (Chinese).
181
-
182
- **Proxy**: when `HTTPS_PROXY` / `HTTP_PROXY` is set (`NO_PROXY` excludes), ama enables Node's built-in environment proxy at startup (equivalent to `NODE_USE_ENV_PROXY=1`, zero dependencies). It works directly on Node 24+; on Node 22 only 22.21+ with `NODE_USE_ENV_PROXY=1` works, older versions print a one-time notice and connect directly. The "Proxy" section of `ama doctor` shows the current state (credentials in the proxy URL are masked).
183
-
184
- ### File locations and layers
185
-
186
- | Location | Contents |
187
- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
188
- | `~/.config/ama/` | User level: `config.json`, `config.schema.json` (generated by ama), `auth.json` (0600), `hooks.json`, `keybindings.json`, `trust.json`, `AGENTS.md`, `skills/` |
189
- | `~/.local/share/ama/` | Data: `sessions/` (session JSONL), `plans/` (plan files), `file-history/` (checkpoint backups), `memory/` (memories, when enabled), `models-dev.json` (override from `ama models refresh`), input history |
190
- | `<project>/.ama/` | Project level: `config.json` (can only tighten), `hooks.json` / `skills/` / `prompts/` (require trust) |
191
- | `<project>/AGENTS.md` | Project conventions, looked up from cwd upwards and added to the system prompt automatically |
192
- | `--profile <file>` | Host profile (for embedders, see "Embedding in Armadra") |
193
-
194
- `AMA_CONFIG_DIR` / `AMA_DATA_DIR` change the two directories; `XDG_CONFIG_HOME` / `XDG_DATA_HOME` are honored too, and on Windows they are `%APPDATA%\ama` and `%LOCALAPPDATA%\ama`.
195
-
196
- Layers merge as **built-in defaults ← user ← profile ← project**, but the project level can only tighten: it can add deny rules, make the permission mode stricter, narrow the tool preset and turn codemode off. Loosening items such as `allow` rules, laxer modes, `cache` and `tools.default` are ignored with a warning. Cloning an unfamiliar repository therefore never widens permissions through its config.
197
-
198
- ### `/config` and `ama config`
199
-
200
- `/config` in the terminal UI opens a settings panel: scalar settings by group with their effective value, source and when a change takes effect; ↑↓ Enter / Space change a value, `/` searches, Tab switches between user and project level (project level may only tighten). Changes are written at once (one key only, `.bak` kept); `/config key=value` sets one key without the panel. From the shell:
201
-
202
- ```sh
203
- ama config get ui.language
204
- ama config set ui.language en # --project writes .ama/config.json (tighten-only)
205
- ama config set tools.disabled '["bash"]' --json-value
206
- ama config unset ui.language
207
- ama config list ui # value, source, when it applies
208
- ```
209
-
210
- Unknown keys, invalid values and loosening at project level exit with 3 and leave the file alone. See [docs/en/tui.md](docs/en/tui.md) "The `/config` settings panel and `ama config`".
211
-
212
- ### Checking
213
-
214
- ```sh
215
- ama config show # effective value and source of every key, providers, the model to be used, tools
216
- ama config show --json
217
- ama doctor # config layers, project trust, key sources, hooks, terminal capabilities
218
- ```
219
-
220
- ## Relays and gateways
221
-
222
- **One-step setup**: give just a baseUrl and a key.
223
-
224
- ```sh
225
- export PACKY_API_KEY=sk-...
226
- ama providers add packy --base-url https://proxy.example/v1 --key-env PACKY_API_KEY --probe --limit 8 --yes
227
- ama -p "hi" --model packy/kimi-k2.5 # preferred channel
228
- ama -p "hi" --model packy/kimi-k2.5@messages # a specific channel (Anthropic Messages)
229
- ama -p "what colors are in this picture" --image shot.png --model packy/kimi-k2.5
230
- ama providers list # provider → channels → model count, key source
231
- ```
232
-
233
- `add` lists the models from `GET {baseUrl}/models`, derives three candidate channels (chat / responses / messages) from the baseUrl, and with `--probe` sends a minimal request per channel and writes the working channels into each model's `channels`. Context window, output limit, images, reasoning and prices are not written to the config; at runtime they come from the bundled models.dev snapshot (`ama models list` marks where each field comes from). Without `--key-env` the key is read from stdin (not echoed) and stored in `auth.json`. The resulting config:
234
-
235
- ```json
236
- {
237
- "providers": {
238
- "packy": {
239
- "apiKey": "$PACKY_API_KEY",
240
- "channels": {
241
- "chat": { "api": "openai-completions", "baseUrl": "https://proxy.example/v1" },
242
- "responses": { "api": "openai-responses", "baseUrl": "https://proxy.example/v1" },
243
- "messages": { "api": "anthropic-messages", "baseUrl": "https://proxy.example" }
244
- },
245
- "defaultChannel": "chat",
246
- "models": [
247
- { "id": "kimi-k2.5", "channels": ["chat", "messages"] },
248
- { "id": "grok-4.7", "channels": ["responses"] }
249
- ]
250
- }
251
- }
252
- }
253
- ```
254
-
255
- **Zero config**: the built-in `openai` / `anthropic` providers recognize `OPENAI_BASE_URL` / `ANTHROPIC_BASE_URL`. When the baseUrl is not an official host, model ids outside the catalog are accepted and cache-related fields use conservative defaults.
47
+ ### Install
256
48
 
257
49
  ```sh
258
- OPENAI_BASE_URL=https://proxy.example/v1 OPENAI_API_KEY=$PACKY_API_KEY \
259
- ama -p "hi" --model openai/qwen3.8-flash
50
+ npm i -g @armadra/agent
51
+ ama --version
260
52
  ```
261
53
 
262
- **One provider, per-model protocols**: under one relay, different models often support different protocols. Instead of a provider per protocol, put `api` on the model:
263
-
264
- ```json
265
- {
266
- "version": 1,
267
- "providers": {
268
- "packy": {
269
- "baseUrl": "https://proxy.example/v1",
270
- "apiKey": "$PACKY_API_KEY",
271
- "models": [
272
- { "id": "deepseek-v4-flash" },
273
- { "id": "grok-4.7", "api": "openai-responses" },
274
- { "id": "MiniMax-M2.7", "api": "anthropic-messages" }
275
- ]
276
- }
277
- }
278
- }
279
- ```
54
+ [Releases](https://github.com/Owlbay/armadra-agent/releases) also ship a single-file build (`ama.cjs` plus the codemode sandbox entry `ama-sandbox.cjs`, kept in the same directory) and `package.tgz` for offline installs.
280
55
 
281
- - `api` defaults to `openai-completions`; also `openai-responses`, `anthropic-messages`, `google-generative-ai`.
282
- - `apiKey` supports `$ENV` / `${ENV}` (read an environment variable) and `!command` (run a command for the value); never put a key in the config in plain text.
283
- - Custom model metadata defaults to the bundled models.dev snapshot (no network at startup; `ama models refresh` refreshes explicitly into the data directory, `refresh-catalog` is the old name). Without a match `contextWindow` is not guessed and automatic compaction is off; add it to the model entry when needed, or point to an entry with `"modelsDev": "provider/model"`.
56
+ ### Connect a model
284
57
 
285
- **Don't want to write the model table by hand**: let ama ask the relay.
58
+ Pick one:
286
59
 
287
60
  ```sh
288
- ama models discover packy # list GET {baseUrl}/models
289
- ama models discover packy --probe --write --limit 8 # probe each model's protocols and write back to the config
290
- ama models check packy/grok-4.7 # one minimal request to confirm connectivity
291
- ama models cache-probe packy/grok-4.7 # does this endpoint report cache usage
61
+ export ANTHROPIC_API_KEY=sk-... # or OPENAI_API_KEY, GEMINI_API_KEY, DEEPSEEK_API_KEY, …
62
+ ama auth set deepseek # store a key in ~/.config/ama/auth.json (0600), read from stdin
63
+ ama providers add packy --base-url https://proxy.example/v1 --probe # a relay or gateway: baseUrl + key
64
+ ama auth login chatgpt # your own ChatGPT Plus / Pro plan instead of an API key
65
+ ama --model ollama/<model> # local Ollama / LM Studio need no key
292
66
  ```
293
67
 
294
- `--probe` tries a few protocols per model and records the first that works; `--write` merges into the user-level `config.json` (the original is backed up as `config.json.bak`, existing entries are not overwritten). Both `--probe` and `cache-probe` send real requests: they print an estimate first and stop on 401 / 403 / 429; `cache-probe` needs `--yes` when not interactive. Details in [docs/en/providers.md](docs/en/providers.md).
68
+ With a key present, ama picks the first provider that has one and that provider's default model; `ama config show` explains which and why.
295
69
 
296
- ## ChatGPT login
297
-
298
- Use your own ChatGPT Plus / Pro plan instead of an API key (built-in provider `chatgpt`; for your own personal use only):
70
+ ### First conversation
299
71
 
300
72
  ```sh
301
- ama auth login chatgpt # official Sign in with ChatGPT in the browser; --paste over SSH
302
- ama auth status # flavor, plan, masked email, token lifetime
303
- ama models discover chatgpt # models available to the account
304
- ama --model chatgpt/<model>
305
- ama auth logout chatgpt
306
- ```
307
-
308
- Credentials are an OAuth entry in `auth.json` (0600), refreshed automatically and serialized across processes; tokens never reach logs, sessions or events. Plan requests cost 0 and show as "subscription" in `/session` and `ama stats`; an exhausted quota reports `quota_exceeded`, an expired login `auth_expired`. `--flavor codex` is an opt-in fallback path. See [docs/en/providers.md](docs/en/providers.md) "ChatGPT login".
309
-
310
- ## Tools and presets
311
-
312
- | Preset | Tools the model sees directly | Good for |
313
- | --------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
314
- | `default` | read, edit, write, bash, grep, glob; plus `codemode` with network isolation | The default (for todo, set `tools.default: ["+todo"]`) |
315
- | `minimal` | read, edit, write, bash | Small models, small contexts; `full-auto` |
316
- | `codemode-only` | only `codemode` | Long workflows heavy on tool calls |
317
- | `coordinator` | read and the canvas tools registered by the host | The coordinator embedded in Armadra: writes no files, runs no bash; codemode is off by default, and when enabled explicitly scripts can call only these tools |
318
-
319
- - Pick a preset with `--tools-preset <name>` or `tools.preset`. `codemode` is the old name of `codemode-only` (0.3.0); config, command line, RPC and SDK still accept it, and `ama config show` shows the canonical name with a hint.
320
- - `tools.default` tweaks the preset: `["+task", "+todo", "-glob"]`; bare names replace the whole set. `task` and `task_ctl` go together (`+task` adds both).
321
- - There are also `--tools a,b,c` (enable only these), `--exclude-tools a,b` and `/tools` in interactive mode.
322
-
323
- **codemode** lets the model write a piece of JavaScript that orchestrates many tool calls with `tools.<name>(args)` (concurrently with `Promise.all`); only the script's output goes back to the model. The script runs in a vm inside a `node --permission` child process: no `require` / `import` / `process` / `fetch`, and every inner call still goes through hooks, permissions and approval one by one.
324
-
325
- **Default exposure**: when `codemode.mode` is unset it follows the preset: `default` → `on` (six tools + codemode, only inside a network-isolating sandbox: Node ≥ 25, or Node 22 / 24 + an OS sandbox; otherwise `off`), `codemode-only` → `only`, `minimal` / `coordinator` → `off`. An explicit `--codemode off|on|only` or `codemode.mode` wins; the project level can only write `off`. In `on` mode the codemode description lists, in one line, the direct tools callable from scripts (same parameters) and the script-only tool names, without re-declaring them, adding only about 400 tokens to the prefix (the [three-preset benchmark](https://github.com/Owlbay/armadra-agent/blob/main/docs/benchmarks/presets-2026-10-02.md) measured the codemode preset before deduplication: about 45% more input on small tasks, no fewer turns). Long workflows with many read-only lookups and many calls can use `codemode-only`.
326
-
327
- ## Caching
328
-
329
- Most usage in long tasks is cache reads: once the prefix changes, every later request re-reads it at full price. ama handles this in three layers:
330
-
331
- - **Protocol layer**: the system prompt sections have a fixed order and no timestamps, tools are sorted by name, and mid-session changes are only appended at the end; cache breakpoints follow each provider's style (Anthropic `cache_control`, OpenAI `prompt_cache_key`, …), and when an endpoint rejects a cache field with 400 it is dropped and the request resent.
332
- - **Session layer**: every request records a prefix fingerprint to detect and attribute misses (idle timeout, sub-task, model switch, system prompt / tool table change, server eviction), decides whether the endpoint reports cache usage, and warms the cache during long tool runs.
333
- - **Display layer**: the status bar, `/session`, `/cache`, RPC stats and `ama models cache-probe`.
334
-
335
- ### Reading the status bar
336
-
337
- A standalone terminal shows two lines by default (`Ctrl+G` / `/statusline` switches to one; embedding hosts default to one):
338
-
339
- ```
340
- tps: 100 tok/s • 546 tok / 5.5s (avg 100 · ttft 1.4s) ↑412k ↓8.1k · cache 83% ♨ · rebill $0.11 · [-]
341
- Accept edits claude-opus-5-5 medium | Ctx 34.0% | proj ⎇ main 5ae9e54 (+12,-3) | $0.84 | 2h24m
73
+ cd your-project
74
+ ama # terminal UI
75
+ ama -p "explain src/index.ts" # one-shot: prints the answer and exits
76
+ git diff | ama -p "review this change" # piped input is appended to the prompt
77
+ ama -p "list the TODOs" --output-format json
342
78
  ```
343
79
 
344
- The top line is throughput and usage; the bottom line is permission mode, model and thinking level, context, directory and git branch (with working-tree line changes), cost and session duration. The cache-related items:
345
-
346
- | Item | How to read it |
347
- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
348
- | `cache 83%` | Hit rate of the **latest** request; the session total is in `/session` |
349
- | `cache —` | The endpoint has not reported cache usage yet (no long enough comparable request so far) |
350
- | `cache` "not reported" | The endpoint does not report cache usage (reads and writes were 0 three times in a row); such requests are left out of the hit rate rather than shown as 0% |
351
- | `♨` | Warming timer running |
352
- | `rebill $0.11` | Extra spend in this session caused by cache misses (tokens for models without prices); hidden when 0 |
353
- | `Ctx 34.0%` | Context usage; yellow at ≥ 70%, red at ≥ 90%, with an "about N turns left" note in the message area when crossed |
354
-
355
- When one miss re-bills ≥ 20k tokens or ≥ $0.10, the message area gets one line with the reason. `/cache` shows cache stats and `/cache fingerprint` the prefix fingerprint (if the hash changed between two requests, the system prompt or tool table was modified).
356
-
357
- ### Three states, warming and summary continuation
358
-
359
- - **Three states**: each endpoint (provider + host + model) is classified as `unknown` / `reported` / `silent`. Only `reported` shows a hit rate, detects misses and warms; relays that do not report cache usage are never misreported as 0%. For models known not to report on a relay, set `compat.cacheReporting: "silent"`.
360
- - **Warming**: while a tool runs for a long time (long tests, `task` sub-tasks, codemode scripts), the previous request is replayed once before the cache TTL expires (`maxTokens: 1`), paying only the read price to keep the cache alive. `cache.warming` is `off` / `streaming` (default, only while running) / `idle` (also while idle, for expensive models); `/cache warm …` switches it for the session; nothing is sent when the expected saving is below `cache.minSavingsUsd` (default $0.05).
361
- - **Summary continuation**: the compaction summary request follows a prefix byte-identical to the last real request, so the whole history is billed at the read price; on failure it falls back to a standalone summary request.
362
-
363
- ### Measurements
364
-
365
- [Cache acceptance experiment](https://github.com/Owlbay/armadra-agent/blob/main/docs/benchmarks/cache-2026-10-02.md) (2026-10-02, through one test relay):
366
-
367
- | Scenario | Result |
368
- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
369
- | Kimi summary continuation | The summary request read 20.2k / 20.5k from cache, **98.8% hit** (0% before the fix: sending `tool_choice` broke the prefix at the tools section) |
370
- | DeepSeek reporting cache in 2048 units | False misses 3 → **0** (cache granularity inferred per endpoint) |
371
- | Baseline hit rate (5-turn coding task) | Kimi 86% cumulative, MiniMax 75%, 0 misses each |
372
-
373
- All cache settings and the fields for each protocol are in [docs/en/providers.md](docs/en/providers.md) "Caching".
374
-
375
- ## Safety
376
-
377
- **Permission modes** (`--permission-mode`, config `permission.mode`, the `/permission` picker, and in interactive mode `Shift+Tab`, or `Tab` on an empty input, to cycle):
378
-
379
- | Mode | Display name | Read | Write | Execute (bash etc.) |
380
- | ----------- | ------------------ | ---- | --------------------------------------------------------------------------------------- | ----------------------------------- |
381
- | `default` | Manual | ✓ | ask | ask |
382
- | `auto-edit` | Accept edits | ✓ | ✓ | ask |
383
- | `plan` | Plan | ✓ | deny | deny |
384
- | `auto` | Auto | ✓ | ✓ ¹ | safe ones allowed, risky ones ask ² |
385
- | `full-auto` | Bypass permissions | ✓ | ✓ | ✓ |
386
- | `allowlist` | Allowlist only | ✓ | only calls matching allow rules pass, everything else is denied without asking (for CI) | same |
387
-
388
- ¹ Secret files (`.env`, private keys, `.ssh/` …), `.git/` and `.ama/`, and writes outside the project directory still ask.
389
- ² Three tiers: the rule tier (dangerous commands, network, deletion, protected paths → ask) → static judgement (a safe list: `ls`, `cat`, `grep`, `git status/diff/log`, `npm test`, `tsc --noEmit`, `cargo test` … → allow) → when neither decides, one question to a model classifier (a separate request that leaves the main session cache untouched; `permission.autoModel` can name a cheap model). Details in [docs/en/permissions.md](docs/en/permissions.md).
390
-
391
- **Decision order**: deny rules (including hook deny) → dangerous commands → (auto's rule tier) → mode / static judgement → allow rules turn "ask" into "allow" → (auto's classifier). A later step can never loosen an earlier decision. When unattended (`-p`, RPC without approvals) "ask" always means deny. Project config can only make the mode stricter and cannot set `auto` / `full-auto`.
392
-
393
- - **Rules**: `bash(git push*)`, `write(src/**)`, `read(**)`, `canvas_*`; `--allow` / `--deny` are repeatable. Built-in deny: writes to `.git/**`, reads and writes to `.ssh/**`.
394
- - **Dangerous commands**: `rm -rf /`, `sudo`, `git push --force`, `git reset --hard`, `git clean -f`, `curl … | sh`, `chmod -R 777`, `npm publish`, `shutdown` and so on ask even with an allow rule. Detection sees through `sh -c '…'`, `eval`, `xargs`, `find -exec` and git global options.
395
- - **bash sandbox** (off by default): see "Sandbox" below.
396
- - **Project trust**: `.ama/hooks.json`, `.ama/skills/` and `.ama/prompts/` execute or inject content from the project, so the directory must be trusted first (asked once in interactive mode, can be remembered; `--trust` / `--no-trust`; untrusted by default when non-interactive). `AGENTS.md` and `.ama/config.json` need no trust, since the latter can only tighten.
397
- - **Pre-execution preview**: besides an input summary, the approval dialog lists what the step will touch: for `rm` / `mv` / `git clean` / `git reset --hard` / redirections in bash, whether the target paths exist, their size and how many files a directory holds; for write, the path and line count; for edit, a −/+ summary per change. `y` allows, `n` denies, `a` stops asking for the same kind this session, `v` shows the full input.
398
- - **Hooks**: `hooks.json` runs shell commands on 11 events such as `PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `Stop`, `PostCompact` and `PostRewind`; hooks can veto tool calls, rewrite input, add context or make the run go another round. See [docs/hooks.md](docs/hooks.md) (Chinese).
399
- - **Approval origin**: approvals raised by sub-agents and external agents show their origin in the dialog title (`[task:explore]`, `[claude · session abc12345]`, "first run of an external agent"); see [docs/en/permissions.md](docs/en/permissions.md) "Origin labels in the approval dialog".
400
-
401
- ## Sandbox
402
-
403
- macOS uses `sandbox-exec` and Linux uses bubblewrap (falling back to `unshare -r -n`, which isolates the network only). At startup a minimal probe runs with the target profile to confirm it really works (degrading for nested sandboxes or missing user namespaces), and `ama doctor` shows the result. Windows has no OS sandbox.
404
-
405
- - **codemode**: the child process starts inside the sandbox and the kernel denies network and all writes; with a sandbox, Node 22 / 24 behaves like Node ≥ 25: read-only class and enabled by default in the `default` preset (see "Node version, codemode and sandbox" above).
406
- - **bash** (off by default): with `"sandbox": { "bash": "auto" }`, bash (including background bash) runs in the sandbox. It can only write the workspace, the system temp directory and directories added via `sandbox.writable`; the workspace's `.ama/`, `.git/hooks` and `.git/config` are read-only; credentials such as `~/.ssh` cannot be read; and there is no network by default (`sandbox.network: "allow"` opens it). In `default` / `auto-edit`, sandboxed commands need no approval (dangerous commands, deny rules and hook asks still apply); when the sandbox blocks something the model may ask to rerun with `sandbox: false` outside it, which is approved as usual and denied when unattended. The status bar shows an extra sandbox marker.
407
- - `sandbox.*` is user level / profile only; the project level can only write the tightening `network: "deny"`. `sandbox.enabled: "off"` or `AMA_SANDBOX=off` turns it all off.
408
-
409
- Details, per-platform policies and known bypasses are in [docs/sandbox.md](docs/sandbox.md) (Chinese).
410
-
411
- ## Plan
412
-
413
- In Plan mode (`Shift+Tab`, `/permission plan`, `/plan <goal>`, `--permission-mode plan`) the model researches read-only: only read tools, read-only commands (`ls`, `rg`, `git log / diff` …) and read-only sub-agents are allowed. It ends with a `<proposed_plan>` block. ama extracts the steps, saves the plan under `<data dir>/plans/` and opens an approval dialog:
414
-
415
- - **Approve and execute** / **Approve, execute in a fresh context** (a new session that opens with the full plan), then pick the execution mode (back to the previous mode / Accept edits / Auto); steps become todos and are worked through one by one (with `todo update` when the todo tool exists, otherwise the model writes a `[DONE:S1]` line per finished step);
416
- - **Keep revising** (feedback goes to the model to rewrite the plan) / **Discard and leave Plan**; `e` edits the plan in an external editor, Esc discards but stays in Plan.
417
-
418
- Line mode uses `/plan approve [mode|fresh]` / `/plan reject`; RPC clients approve after declaring the `plans` capability; the SDK uses `createAgentSession({ plan: { onProposed } })`. **ama never approves on a person's behalf**: `-p` stops at "plan awaiting approval" and exits with 9 by default; only the user-level config `"plan": { "unattended": "approve" }` approves and executes automatically when unattended. `plan.model` lets planning and execution use different models. See [docs/plan.md](docs/plan.md) (Chinese).
419
-
420
- ## Sub-agents
421
-
422
- The `task` tool hands a sub-task to a sub-agent with a fresh context (same process, its own session file, depth 1); the result returns to the parent session as a tool result. Under the `default` preset `task` is only available inside codemode scripts; expose it directly with `--tools …,task` or `tools.default: ["+task"]`.
423
-
424
- - Built-in types `general` (default), `explore` and `plan` (the last two are forced read-only and never prompt for approval); define your own types (tool allowlist, model, permissions, turns, worktree isolation) in `~/.config/ama/agents/*.md`, `.ama/agents/*.md` (requires trust) or `--agent-dir`.
425
- - Several tasks in one reply run in parallel (`subagents.maxConcurrent`, default 4); `background: true` returns a `taskId` immediately and the parent session receives a `<task-notification>` when done; `task{taskId}` continues the conversation; `task_ctl` lists / waits / stops / reads output; `isolation: "worktree"` runs in a separate git worktree.
426
- - The sub-session's tool table is byte-identical to the parent's, so its first request reuses the parent's cache prefix. In the interface the task tool line folds and shows progress; `/agents` lists the available types.
427
- - **Agent bar and sub-agent view**: running tasks are listed above the status line; with an empty input press `Ctrl+B` (or `↓`, e.g. in tmux) to focus the bar, ↑↓ to pick and Enter to open a full-screen live view of that sub-agent, where your input goes straight to it (Esc goes back without interrupting). `/tasks` focuses the bar, `/tasks <id>` opens a view, `/tasks stop <id>` stops a task. See [docs/en/tui.md](docs/en/tui.md) "Agent bar".
428
-
429
- See [docs/agents.md](docs/agents.md) (Chinese) "Sub-agents".
430
-
431
- ## External agents
432
-
433
- `task(agent="claude")`, `"codex"` or `"acp:<program>"` (any ACP agent: Gemini CLI, OpenCode, Kimi, ama itself …) drives an external coding agent with your **existing login** in that CLI. Foreground / background / follow-up / `task_ctl` work as with ama's own sub-agents, and results are treated as reference material.
434
-
435
- - **Approvals go to a human only**: operations the external agent wants confirmed go to the interface / host; neither the auto classifier nor the model takes part, and unattended runs always deny. The first run of a given external agent in each session is confirmed once (the allow rule `task(claude)` or `full-auto` lets it through).
436
- - An external agent's mode is never wider than ama's current mode (read-only under plan / allowlist). By default the child process is stripped of provider keys, `*_BASE_URL` and `AMA_*`, so subscriptions are never switched to API billing; it only starts in trusted directories; there is a concurrency pool, a USD budget and a watchdog.
437
- - When embedded in a host, ama does not start external CLIs itself; it only uses runners injected by the host through `HostApi.runners`.
438
- - **ama as an ACP agent**: `ama --mode acp` can be driven by Zed, JetBrains and Armadra's ACP nodes; `@armadra/agent/acp` exports a client, a driver and a fake agent.
439
-
440
- See [docs/agents.md](docs/agents.md) "External agents" and [docs/acp.md](docs/acp.md) (both Chinese).
441
-
442
- ## Rewind
80
+ `-p` has nobody to approve, so writes and commands are denied unless you allow them (`--permission-mode auto-edit`, `auto`, or `--allow "bash(npm test*)"`).
443
81
 
444
- Every user message that starts a new turn is a rewind point: edit / write back up a file before writing it the first time, and each new turn re-snapshots tracked files (with `checkpoints.mode: "shadow-git"` the whole working directory goes into a shadow repository, so bash changes can be rolled back too).
82
+ ### Keys to know
445
83
 
446
- - `/rewind`, or double Esc while idle, opens the list; the confirmation panel offers: restore code and conversation / restore conversation / restore code / summarize from here / summarize up to here, each with a preview. Files changed by hand outside the turn are listed as conflicts and skipped by default, with an option to overwrite; if git HEAD moved, ama only suggests commands and never touches git.
447
- - When Esc interrupts a run before this turn produced any output, the message is withdrawn and put back into the input box (`ui.restoreOnCancel`).
448
- - Line mode `/rewind <n> [both|conversation|code] [overwrite]`; RPC `get_rewind_points` / `rewind`; SDK `session.rewind()`; hook `PostRewind`.
84
+ | Key / command | Effect |
85
+ | ---------------------- | --------------------------------------------------------------------------- |
86
+ | Shift+Tab (Tab, empty) | Cycle permission modes; entering Bypass asks to confirm |
87
+ | `/model` (Ctrl+L) | Pick a model; Tab shows all providers, Space adds the model to your list |
88
+ | ↓ on an empty input | Focus the agent bar; Enter opens a live view of a sub-agent |
89
+ | Ctrl+B | Move a blocking foreground sub-agent to the background (in tmux: `C-b C-b`) |
90
+ | Esc / Esc Esc | Interrupt the run / (idle, empty input) open the rewind list |
91
+ | Ctrl+G | Status bar: full ↔ compact |
92
+ | Ctrl+O | Expand / fold tool output and thinking |
93
+ | `/config` | Settings panel |
94
+ | Ctrl+C twice | Quit (the resume command stays in the scrollback) |
449
95
 
450
- See [docs/en/tui.md](docs/en/tui.md) "Rewind", [docs/rewind-plan.md](docs/rewind-plan.md) (Chinese) and [docs/en/sessions.md](docs/en/sessions.md).
96
+ `/help` lists every command. Keys can be remapped in `~/.config/ama/keybindings.json`; see [docs/en/tui.md](docs/en/tui.md#keys).
451
97
 
452
- ## Memory
98
+ ## Capabilities
453
99
 
454
- Cross-session personal notes, **off by default**. Turn it on with `ama memory enable` (or `--memory` / `AMA_MEMORY=1` for one launch); then saying "remember …" lets the model write a Markdown entry with the `memory` tool. Entries live under `<data dir>/memory/` in a user scope and a per-project scope (trusted projects only); an index goes into the system prompt at session start and bodies are read on demand. Writes ask in `default` mode, content that looks like a credential is refused, and sub-agents are read-only. Manage entries with `/memory` or `ama memory list | show | edit | rm | path | enable | disable`. When disabled, requests are byte-for-byte unchanged. See [docs/memory.md](docs/memory.md) (Chinese).
100
+ ### Models and providers
455
101
 
456
- ## Traces
102
+ Four protocol lines (Anthropic Messages, OpenAI Responses, OpenAI Chat Completions, Google Generative AI) and 18 built-in providers: Anthropic, OpenAI, Google, DeepSeek, Moonshot (Kimi), Zhipu, Qwen (DashScope), OpenRouter, Groq, xAI, Mistral, MiniMax, StepFun, Volcengine Ark, Tencent, ChatGPT (plan login), Ollama and LM Studio. One provider can mount several channels; Messages / Responses are preferred and Chat is the fallback, and `provider/model@channel` picks one explicitly. Relays connect with `ama providers add`, which lists the models, probes the channels and writes the config. Context window, output limit, image input, reasoning and prices come from a bundled models.dev snapshot, so startup needs no network (`ama models refresh` updates it on demand). `models.enabled` (`ama models enable|disable`, or Space in `/model`) keeps the picker to the models you use. See [docs/en/providers.md](docs/en/providers.md) and [ChatGPT login](docs/en/providers.md#chatgpt-login).
457
103
 
458
- Every model request records timing (time to first token, decode, tools, retries, compaction) in the session file, without content. `/trace` opens a tree of turns → requests → tools → sub-agents with timing bars, tokens and cache hits; `/trace <task id>` shows one task. To share or inspect outside the terminal:
104
+ ### Permissions and sandbox
459
105
 
460
- ```sh
461
- ama sessions trace 3f9a1c2e --html trace.html # self-contained single file, redacted, no external loads
462
- ama sessions trace 3f9a1c2e --json # same shape as RPC get_trace
463
- ```
464
-
465
- RPC clients use `get_trace` (tail-first paging, increments after `entry_appended`) and the SDK `session.trace()`. See [docs/en/tui.md](docs/en/tui.md) "Traces", [docs/en/sessions.md](docs/en/sessions.md) and [docs/en/rpc.md](docs/en/rpc.md).
466
-
467
- ## Interfaces and entry points
468
-
469
- ### Terminal UI
470
-
471
- Running `ama` (with stdin / stdout both TTYs) enters interactive mode. The interface uses the main screen only; the conversation history stays in the terminal scrollback, so tmux `capture-pane` can read the whole conversation.
472
-
473
- | Key | Effect |
474
- | ------------------------ | --------------------------------------------------------------------------------------- |
475
- | Enter | Send; while running, steer |
476
- | Alt+Enter | While running, queue after this turn (followUp) |
477
- | Shift+Enter / Ctrl+J | New line |
478
- | Esc | Interrupt the current run |
479
- | Esc Esc (idle) | Empty input: open the rewind list (same as `/rewind`); with text: clear it into history |
480
- | Shift+Tab / Tab | Cycle permission modes (Tab only on an empty input; entering Bypass asks to confirm) |
481
- | Ctrl+O | Expand / collapse tool output |
482
- | Ctrl+L / Ctrl+T | Pick model / thinking level |
483
- | Ctrl+G | Bottom info line, two lines ↔ one (same as `/statusline`) |
484
- | Ctrl+V | Paste an image from the clipboard and insert `@<path>` (same as `/paste`) |
485
- | Ctrl+B / ↓ (empty input) | Focus the agent bar when there are sub-agent tasks (↓ in tmux) |
486
- | Ctrl+C | Clear the input; on an empty input, press again within 1.5 s to quit |
487
- | Tab | Complete: `/` commands, templates and Skills, `@` file paths |
488
-
489
- Common commands: `/model`, `/thinking`, `/permission`, `/tools`, `/compact`, `/tree` (branch again from before a message), `/fork`, `/resume`, `/new`, `/session`, `/cache`, `/hooks`, `/skill:<name>`, `/help`; wave 5 added `/plan` (plan panel and approval; `/plan <goal>` enters Plan), `/tasks` (sub-agent tasks), `/agents` (available types and external agents), `/paste` (clipboard image), `/rewind` and `/statusline [full|compact]`; wave 6 added `/config` (settings panel), `/trace` (trace), `/memory` (memories), and `/tasks` now focuses the agent bar (`/tasks <id>` opens the sub-agent view). An `@image-path` in the input (or a pasted / dropped image path) is sent to the model as an image attachment; `/model` groups models by "provider · channel" and marks context size and `img`. Key bindings can be overridden in `~/.config/ama/keybindings.json`. See [docs/en/tui.md](docs/en/tui.md).
490
-
491
- `--no-tui` (or when stdin / stdout is not a TTY, or `TERM=dumb`) enters line mode: readline with bracketed paste and the same commands.
106
+ | Mode | Display name | Writes | Commands |
107
+ | ----------- | ------------------ | ----------- | --------------------------------- |
108
+ | `default` | Manual | ask | ask |
109
+ | `auto-edit` | Accept edits | allow | ask |
110
+ | `plan` | Plan | deny | read-only commands only |
111
+ | `auto` | Auto | allow ¹ | safe ones allowed, risky ones ask |
112
+ | `full-auto` | Bypass permissions | allow | allow (dangerous commands ask) |
113
+ | `allowlist` | Allowlist only | allow rules | allow rules (for CI) |
492
114
 
493
- ### One-shot `-p`
115
+ ¹ Secrets, `.git/`, `.ama/` and paths outside the project still ask. `auto` decides in three tiers: rules, then a static safe list, then a model classifier on a separate request. Allow / deny rules (`bash(git push*)`, `write(src/**)`), dangerous-command detection that sees through `sh -c` / `eval` / `xargs`, and project trust apply in every mode; project config can only tighten. On macOS (`sandbox-exec`) and Linux (bubblewrap) an OS sandbox isolates codemode, and optionally bash (`sandbox.bash: "auto"`). See [docs/en/permissions.md](docs/en/permissions.md) and [docs/sandbox.md](docs/sandbox.md) (Chinese).
494
116
 
495
- | `--output-format` | stdout |
496
- | ----------------- | -------------------------------------------------------------------------------------- |
497
- | `text` (default) | The text of the final answer |
498
- | `json` | One `result` object: session id, model, `stopReason`, `text`, usage, cost, cache stats |
499
- | `stream-json` | One event per line, same shapes as RPC events |
117
+ ### Sub-agents and external agents
500
118
 
501
- **stdin**: piped content is appended after the prompt (`git diff | ama -p "review"`); without a prompt argument the piped content is the prompt. With a prompt argument ama waits only 2 seconds for the pipe's first byte (`AMA_STDIN_WAIT_MS` adjusts it, 0 = don't wait): if not a single byte arrives, stdin is ignored, the run continues and stderr gets one line, so a pipe a parent process leaves open never hangs `-p`; once the first byte arrives it reads to EOF. When the upstream command runs a long time before printing, add a trailing `-` to wait for EOF (`npm test 2>&1 | ama -p "find why it fails" -`); `--no-stdin` never reads. A `< file` redirect is always read.
119
+ The `task` tool hands a sub-task to a sub-agent with a fresh context: built-in `general`, `explore` and `plan`, or your own types defined in `~/.config/ama/agents/*.md`, `.ama/agents/*.md` (trusted projects) or `--agent-dir`. Under the `default` preset `task` is callable from codemode scripts; `tools.default: ["+task"]` exposes it directly. In the terminal UI, RPC and ACP a task runs in the background by default and reports back with a notification; `-p` waits for it. Running tasks appear in the agent bar above the status line, where you can open a live view and talk to a sub-agent directly. `task(agent="claude" | "codex" | "acp:<program>")` drives an external agent with your existing login in that CLI; its approvals go to a human only and its mode is never wider than ama's. `ama --mode acp` exposes ama itself as an ACP agent. See [docs/agents.md](docs/agents.md) (Chinese) and [docs/en/tui.md](docs/en/tui.md#agent-bar).
502
120
 
503
- `--image <file>` is repeatable and sends images with the prompt (PNG / JPEG / GIF / WebP; the per-image limit is tiered by endpoint and measured after base64: official Anthropic 10 MB, Gemini / OpenAI 20 MB, relays 5 MB; oversized images are resized with sips / ImageMagick when possible); `@image-path` in the prompt is attached too. When the current model does not accept images, ama exits with 2 without sending a request.
121
+ ### Plan mode
504
122
 
505
- `--max-turns N` caps a run at N turns (one model request plus its tool executions is one turn), and `--max-cost USD` caps a run's USD spend (config `limits.maxTurns / maxCostUsd` mean the same). When a limit is reached the run ends early (event `limit_reached`) with **exit code 8** (`--max-turns` exited with 1 in 0.4.x), and the `json` result carries `limitReached{kind, value, limit}` (plus `maxTurnsReached: true` for the turn limit). In Plan mode a plan awaiting approval exits with 9 (see "Plan" above).
123
+ In Plan mode (`Shift+Tab`, `/plan <goal>`, `--permission-mode plan`) the model researches read-only and ends with a plan. ama saves it and opens an approval dialog: approve and execute (optionally in a fresh context, with a choice of execution mode), keep revising, or discard. Steps become todos. Unattended `-p` stops with exit code 9 instead of approving; `plan.model` lets planning and execution use different models. See [docs/plan.md](docs/plan.md) (Chinese).
506
124
 
507
- `--system-prompt <text|@file>` adds to the system prompt (in every mode): by default it is appended as the last rule, keeping the preamble and tool table, the longest cache prefix, unchanged; `--system-prompt-mode replace` replaces the opening role description instead, while the tool table, rules and AGENTS.md stay.
125
+ ### Rewind and checkpoints
508
126
 
509
- `--no-session` keeps the session in memory only and writes no session file (for CI and one-off calls; `--resume` is impossible afterwards); new sessions started with `/new` in interactive mode are not saved either.
127
+ Each turn is a checkpoint: files are backed up before ama first writes them, and `checkpoints.mode: "shadow-git"` snapshots the whole working directory so bash changes can be undone too. Double Esc (or `/rewind`) returns to before any message, restoring code, conversation or both, or summarizing from that point. Files you changed by hand are listed as conflicts and skipped by default. See [docs/en/tui.md](docs/en/tui.md#rewind) and [docs/en/sessions.md](docs/en/sessions.md).
510
128
 
511
- **Unattended**: `-p` has nobody to approve, so calls that would ask under the default permission mode (writing files, running commands) are always denied. When something is denied, stderr summarizes the denied tools and reasons in one line, the `json` result carries `deniedTools`, `stream-json`'s `tool_execution_end` carries `denied: true`, and the exit code is 7. To allow them use `--permission-mode auto-edit` (allows writes) / `auto` (ama judges each step), or allow by rule with `--allow "bash(npm test*)"`.
129
+ ### Context and caching
512
130
 
513
- | Exit code | Meaning |
514
- | --------- | --------------------------------------------------------------------------------- |
515
- | 0 | Success |
516
- | 1 | Runtime error (the model ultimately failed, etc.) |
517
- | 2 | Usage error; the current model does not accept images |
518
- | 3 | Config / profile / path error; `ama config set` rejected a key or value |
519
- | 4 | No usable model or key |
520
- | 5 | Session missing / corrupted |
521
- | 6 | Host / hook startup failure |
522
- | 7 | `-p` had tool calls denied (no approver, deny rules, plan, …) |
523
- | 8 | `-p` reached a budget limit (`--max-turns` / `--max-cost` / `limits`) |
524
- | 9 | `-p` produced a plan that was saved and awaits approval (`plan.unattended: stop`) |
525
- | 78 | Host API version mismatch |
526
- | 130 | SIGINT; 143 = SIGTERM |
131
+ Long sessions compact automatically in two tiers: large old tool results are pruned first, then the history is summarized, with the summary request reusing the cached prefix. ama keeps the prefix byte-stable, detects and explains cache misses, tells endpoints that report cache usage from those that do not, and can warm the cache during long tool runs (`cache.warming`). Cross-session memory is off by default; `ama memory enable` turns it on, and requests are byte-identical while it is off. See [docs/en/providers.md](docs/en/providers.md#caching) and [docs/memory.md](docs/memory.md) (Chinese).
527
132
 
528
- ### Session stats, search and reuse
133
+ ### Observability
529
134
 
530
- Sessions are JSONL files under `<data dir>/sessions`. These commands only read (by default they look at sessions of the current directory; `--all` looks at all):
135
+ The status bar shows throughput (tok/s, time to first token), usage and cache hit rate on the first line; mode, model, context, git branch, cost and duration on the second; and with a ChatGPT plan a third line with quota usage and reset times. `Ctrl+G` folds it to one line. `/trace` opens a tree of turns, requests, tools and sub-agents with timing; `ama sessions trace <id> --html` writes the same as a redacted single-file page. `ama stats` aggregates requests, tokens, cache hit rate and cost across sessions. See [docs/en/tui.md](docs/en/tui.md#layout) and [docs/en/sessions.md](docs/en/sessions.md).
531
136
 
532
- ```sh
533
- ama stats --since 7d --by model # requests, tokens, cache hit rate, cost, top N tool calls (--json available)
534
- ama sessions search "parser" --role user # full-text search across sessions; /regex/ works too
535
- ama sessions show 3f9a1c2e # lists user message numbers at the end
536
- ama -p --from 3f9a1c2e#2 --model packy/kimi-k2.5 # ask that message (images included) again with another model
537
- ama sessions export 3f9a1c2e --format md --output s.md # md / json / jsonl, redacted before export
538
- ama sessions trace 3f9a1c2e --html t.html # trace as a single HTML file (see "Traces")
539
- ```
137
+ ### codemode and tool presets
540
138
 
541
- How the numbers are computed (hit rate only over endpoints that report cache usage, cost only over priced requests, …) and the export formats are in [docs/en/sessions.md](docs/en/sessions.md).
139
+ codemode lets the model write a short JavaScript that orchestrates many tool calls; it runs in a `node --permission` child process (inside the OS sandbox when available) and only its output goes back to the model. Every inner call still passes hooks and permissions. Tool presets: `default` (read, edit, write, bash, grep, glob, plus codemode when the network is isolated), `minimal`, `codemode-only` and `coordinator`. See [docs/codemode.md](docs/codemode.md) (Chinese).
542
140
 
543
- ### RPC
141
+ ### Configuration
544
142
 
545
- `ama --mode rpc` speaks JSONL on stdin / stdout: it first sends `hello` and `session_start`, then accepts commands such as `prompt`, `steer`, `abort`, `set_model`, `get_session_stats` and `fork`, and pushes stream events and approval requests.
143
+ One user file, `~/.config/ama/config.json`, created on first use with a JSON schema for editors. Layers merge as built-in defaults ← user ← profile ← project ← command line; the project level (`.ama/config.json`) can only tighten. `/config` opens a settings panel; from the shell use `ama config get|set|unset|list`, and `ama config show` prints every effective value with its source. Project conventions in `AGENTS.md` are picked up automatically. `ama doctor` checks layers, trust, key sources, hooks and sandbox. See [docs/en/tui.md](docs/en/tui.md#the-config-settings-panel-and-ama-config).
546
144
 
547
- ```sh
548
- printf '{"id":"1","type":"prompt","message":"hi"}\n' | ama --mode rpc --model fake/echo
549
- ```
145
+ ### Interface language
550
146
 
551
- `hello.capabilities` lists server capabilities (`approvals`, `images`, `hooks`, `plans`); clients declare with `set_client_capabilities` which approvals and plan approvals they take over. Wave 5 added plan (`plan_response` / `get_plan` / `get_todos`), task (`get_tasks` / `get_agents`) and rewind (`get_rewind_points` / `rewind` / `summarize_*`) commands, plus events such as `subagent_*`, `plan_*`, `limit_reached` and `telemetry_tick`; wave 6 added `get_trace` and the `quota_update` event. Decide by `code`, never by the human-readable `error` text, which follows the interface language. The protocol is in [docs/en/rpc.md](docs/en/rpc.md); import the types from `@armadra/agent/rpc`.
147
+ The interface is available in Chinese and English: `ui.language` (`auto` / `zh` / `en`), `--lang` or `AMA_LANG`; `auto` follows `LANG`. Text sent to the model is always English, so requests are identical in both languages; set `ui.replyLanguage` (for example `"Chinese"`) to have the model reply in another language.
552
148
 
553
- `ama --mode acp` speaks ACP (JSON-RPC over NDJSON); see [docs/acp.md](docs/acp.md) (Chinese).
149
+ ## Embedding and integration
554
150
 
555
- ### SDK
556
-
557
- ```sh
558
- npm i @armadra/agent
559
- ```
151
+ **SDK**: `npm i @armadra/agent`.
560
152
 
561
153
  ```ts
562
154
  import { createAgentSession } from "@armadra/agent";
@@ -570,114 +162,115 @@ const session = await createAgentSession({
570
162
  ask: async (request) => (request.toolName === "read" ? "allow" : "deny"),
571
163
  },
572
164
  });
573
- session.subscribe((event) => {
574
- if (event.type === "tool_execution_start") console.error(`→ ${event.toolName}`);
575
- });
576
165
  await session.prompt("list the entry files under src");
577
166
  console.log(session.getLastAssistantText());
578
- console.log(session.getStats().cache?.hitRate);
579
167
  await session.dispose();
580
168
  ```
581
169
 
582
- - `createAgentSession` does not read file-system config: an in-memory session, explicit tools and callback approvals, suited for embedding in other programs.
583
- - Rewind: `session.rewindPoints()` lists the user messages on the active path that start new turns; `session.rewind({ entryId, mode: "both" | "conversation" | "code", dryRun?, onConflict? })` returns to before that message (returning the original message as a draft and the code restore result; in-memory sessions support conversation only); `session.summarizeFrom(entryId, instructions?)` / `session.summarizeUpTo(entryId, instructions?)` correspond to "summarize from here" / "summarize up to here". Design in [docs/rewind-plan.md](docs/rewind-plan.md) (Chinese).
584
- - Plans: `createAgentSession({ plan: { onProposed } })` calls back for approval once a plan is proposed (return `{ decision: "approve" | "approve_fresh" | "revise" | "reject", mode?, feedback? }`), or use `session.plan.respond()` later; `session.plan.current()` / `todos()` read the current plan and todos. Types such as `SessionPlanOptions` and `PlanDecision` are exported from the package entry; see [docs/plan.md](docs/plan.md) (Chinese) "Interfaces".
585
- - `createRuntime({ argv })` runs the same startup sequence as the `ama` command line (config, AGENTS.md, Skills, hooks.json, auth.json).
586
- - Subpaths: `@armadra/agent/host` (host adapter types), `@armadra/agent/rpc` (RPC types), `@armadra/agent/tui` (terminal component library), `@armadra/agent/acp` (ACP types, client, driver and fake agent), `@armadra/agent/bundle` (the single-file `ama.cjs`; `require.resolve` gives its path to start with `node` or `ELECTRON_RUN_AS_NODE=1`).
170
+ `createAgentSession` reads no config files; `createRuntime({ argv })` runs the same startup as the `ama` command. A fuller example is [examples/sdk-demo.ts](https://github.com/Owlbay/armadra-agent/blob/main/examples/sdk-demo.ts).
171
+
172
+ | Entry point | Use | Docs |
173
+ | -------------------- | ----------------------------------------------------------------- | ------------------------------------------ |
174
+ | `ama --mode rpc` | JSONL over stdio for hosts; types in `@armadra/agent/rpc` | [docs/en/rpc.md](docs/en/rpc.md) |
175
+ | `ama --mode acp` | ACP agent for editors and Armadra; client in `@armadra/agent/acp` | [docs/acp.md](docs/acp.md) (Chinese) |
176
+ | `--profile <file>` | Host adapter: canvas tools, approvals, injected messages, status | [docs/en/host-api.md](docs/en/host-api.md) |
177
+ | `@armadra/agent/tui` | The terminal component library | [docs/en/tui.md](docs/en/tui.md) |
178
+
179
+ Armadra starts ama with `ama --profile <path>` and the `coordinator` preset: the coordinator reads files and calls canvas tools but never edits code itself.
180
+
181
+ ## Command reference
182
+
183
+ | Command | Purpose |
184
+ | -------------------------------------------------------- | --------------------------------------------------------- |
185
+ | `ama` / `ama --no-tui` | Terminal UI / line mode |
186
+ | `ama -p "<prompt>"` | One-shot run (`--output-format text\|json\|stream-json`) |
187
+ | `ama -c` / `ama -r [id]` | Continue the latest session here / resume a session |
188
+ | `ama auth set\|list\|remove <provider>` | Manage stored API keys |
189
+ | `ama auth login\|logout\|status chatgpt` | ChatGPT plan login |
190
+ | `ama providers add\|list\|channels\|remove\|refresh` | Relays and custom providers |
191
+ | `ama models list\|check\|discover\|refresh` | Models, availability, relay discovery, models.dev refresh |
192
+ | `ama models enable\|disable` | The `/model` list (`models.enabled`) |
193
+ | `ama models cache-probe <provider/id>` | Whether an endpoint reports cache usage |
194
+ | `ama config show\|path\|edit\|get\|set\|unset\|list` | Settings |
195
+ | `ama sessions list\|show\|search\|export\|trace\|prune` | Sessions, full-text search, export, traces |
196
+ | `ama stats [--since 7d] [--by model]` | Usage across sessions |
197
+ | `ama memory list\|show\|edit\|rm\|path\|enable\|disable` | Memory |
198
+ | `ama doctor` / `ama init` | Diagnostics / create the config directory |
199
+
200
+ Common flags: `--model`, `--thinking`, `--permission-mode`, `--allow` / `--deny`, `--tools-preset`, `--max-turns`, `--max-cost`, `--image`, `--lang`. `ama --help` lists everything.
201
+
202
+ ## Exit codes
203
+
204
+ | Code | Meaning |
205
+ | ---- | ----------------------------------------------------------------------- |
206
+ | 0 | Success |
207
+ | 1 | Runtime error (the model ultimately failed, etc.) |
208
+ | 2 | Usage error; the current model does not accept images |
209
+ | 3 | Config / profile / path error; `ama config set` rejected a key or value |
210
+ | 4 | No usable model or key |
211
+ | 5 | Session missing or corrupted |
212
+ | 6 | Host / hook startup failure |
213
+ | 7 | `-p` had tool calls denied (no approver, deny rules, plan, …) |
214
+ | 8 | `-p` reached a budget limit (`--max-turns` / `--max-cost` / `limits`) |
215
+ | 9 | `-p` saved a plan that awaits approval |
216
+ | 78 | Host API version mismatch |
217
+ | 130 | SIGINT; 143 = SIGTERM |
218
+
219
+ ## Documentation
587
220
 
588
- A complete example is [examples/sdk-demo.ts](https://github.com/Owlbay/armadra-agent/blob/main/examples/sdk-demo.ts) (custom tools, streaming output, usage stats).
221
+ Six user docs have English versions; the rest are in Chinese.
589
222
 
590
- ## Embedding in Armadra
223
+ **User docs**
591
224
 
592
- Armadra starts ama with `ama --profile <path>`. The profile is a JSON file naming the host adapter (`host`), instructions (`instructions`), Skill and prompt template directories, the hook file, the key file (`authFile`; `authEnv: false` skips environment variables), the session directory and `trustProject`.
225
+ - [Providers and models](docs/en/providers.md) ([中文](docs/providers.md)): providers, channels, keys, ChatGPT login, relays, models.dev, images, caching
226
+ - [Terminal UI](docs/en/tui.md) ([中文](docs/tui.md)): layout, status bar, keys, commands, rewind, approvals, agent bar, traces, `/config`
227
+ - [Permissions](docs/en/permissions.md) ([中文](docs/permissions.md)): modes, decision order, auto's three tiers
228
+ - [Sessions](docs/en/sessions.md) ([中文](docs/sessions.md)): stats, search, `--from`, export, traces, checkpoints
229
+ - [Sub-agents and external agents](docs/agents.md), [Plan mode](docs/plan.md), [Memory](docs/memory.md), [Sandbox](docs/sandbox.md), [codemode](docs/codemode.md), [Command hooks](docs/hooks.md) (Chinese)
593
230
 
594
- The host adapter is a local JS module exporting `hostApi` and `create(api)`; through `HostApi` it registers canvas tools (`canvas_*` / `context_*`), appends to the system prompt, takes over approvals, injects messages and shows status. When the same profile runs outside the canvas the adapter stays inactive and ama falls back to plain standalone mode. With the `coordinator` preset the coordinator only reads files and calls canvas tools, never changing code itself.
231
+ **Integration docs**
595
232
 
596
- - ama's side of the interface: [docs/en/host-api.md](docs/en/host-api.md)
597
- - Coordinator design and contract: [docs/design/coordinator-agent.md](https://github.com/yovinchen/Armadra/blob/main/docs/design/coordinator-agent.md) in the Armadra repository
233
+ - [RPC protocol](docs/en/rpc.md) ([中文](docs/rpc.md)), [Host adapter API](docs/en/host-api.md) ([中文](docs/host-api.md))
234
+ - [ACP](docs/acp.md), [Session file format](docs/session-format.md) (Chinese)
598
235
 
599
- ## Documentation
236
+ **Design and research** (Chinese)
600
237
 
601
- English versions exist for six user docs; the rest are in Chinese.
602
-
603
- | Document | Contents |
604
- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
605
- | [docs/en/providers.md](docs/en/providers.md) ([中文](docs/providers.md)) | Built-in providers and channels, API keys, ChatGPT login, custom providers and relays, model metadata snapshot, image input, compat, caching |
606
- | [docs/en/tui.md](docs/en/tui.md) ([中文](docs/tui.md)) | Terminal UI: layout, status bar, keys, commands, rewind, approvals, Plan approval, sub-agents and the agent bar, traces, memory, `/config`, component library |
607
- | [docs/en/permissions.md](docs/en/permissions.md) ([中文](docs/permissions.md)) | Permission modes, read-only commands in plan, decision order, approval-free sandboxed commands, auto's three tiers, approval origin labels |
608
- | [docs/en/host-api.md](docs/en/host-api.md) ([中文](docs/host-api.md)) | Host adapter API |
609
- | [docs/en/rpc.md](docs/en/rpc.md) ([中文](docs/rpc.md)) | RPC protocol (stdio JSONL) |
610
- | [docs/en/sessions.md](docs/en/sessions.md) ([中文](docs/sessions.md)) | Session stats, search, `--from` reuse, export, traces, checkpoints and shadow git |
611
- | [docs/memory.md](docs/memory.md) | Memory: enabling, storage, the `memory` tool and permissions, system prompt and cache, commands (Chinese) |
612
- | [docs/plan.md](docs/plan.md) | Plan mode: flow, plan format, approval, separate models, config and persistence (Chinese) |
613
- | [docs/agents.md](docs/agents.md) | Sub-agents (types, definition files, background, follow-up, worktree) and external agents (drivers, permissions, environment, budget) (Chinese) |
614
- | [docs/acp.md](docs/acp.md) | ACP: `ama --mode acp` and ama as an ACP client (Chinese) |
615
- | [docs/sandbox.md](docs/sandbox.md) | OS sandbox: codemode and bash, per-platform implementation, config and known bypasses (Chinese) |
616
- | [docs/codemode.md](docs/codemode.md) | codemode scripts, sandbox and permissions (Chinese) |
617
- | [docs/hooks.md](docs/hooks.md) | Command hooks (hooks.json) (Chinese) |
618
- | [docs/session-format.md](docs/session-format.md) | Session file format (Chinese) |
619
- | [docs/rewind-plan.md](docs/rewind-plan.md) | Checkpoint and rewind design (Chinese) |
620
- | [docs/tui-design.md](docs/tui-design.md) | Terminal UI visual spec and screen-by-screen mockups (Chinese) |
621
- | [docs/design.md][design] | Overall design and decision log (Chinese) |
622
- | [docs/extensions.md][extensions] | Local extensions (draft design, not implemented) (Chinese) |
623
- | [docs/benchmarks/][benchmarks] | Preset benchmarks, the D20 todo retest and the cache acceptance experiment (reports and raw data) |
624
- | [docs/wave6-plan.md][wave6] | Wave 6 design: agent bar and sub-agent view, traces, memory, ChatGPT login, bilingual UI, `/config` (Chinese) |
625
- | [docs/i18n.md][i18n] | Bilingual development conventions: language selection, message catalogs and key naming, model-side isolation, check script (Chinese) |
626
- | [docs/wave5-plan.md][wave5] | Wave 5 design (Chinese) |
627
- | [docs/implementation-plan.md][impl], [wave3-plan][w3] | Early implementation plans (for history) (Chinese) |
628
- | [docs/research/][research] | Wave 5 and wave 6 research reports (for history) (Chinese) |
629
-
630
- The npm package includes the first sixteen user docs above (both languages where available); the rest are design and history material linked on GitHub.
238
+ - [Overall design and decision log][design], [terminal UI visual spec](docs/tui-design.md), [rewind design](docs/rewind-plan.md), [bilingual conventions][i18n]
239
+ - [Local extensions (draft, not implemented)][extensions], [benchmarks][benchmarks], [research reports][research]
240
+ - Wave plans: [wave 3][w3], [wave 5][wave5], [wave 6][wave6], [early implementation plan][impl]
631
241
 
632
242
  [design]: https://github.com/Owlbay/armadra-agent/blob/main/docs/design.md
243
+ [i18n]: https://github.com/Owlbay/armadra-agent/blob/main/docs/i18n.md
633
244
  [extensions]: https://github.com/Owlbay/armadra-agent/blob/main/docs/extensions.md
634
245
  [benchmarks]: https://github.com/Owlbay/armadra-agent/tree/main/docs/benchmarks
635
- [wave6]: https://github.com/Owlbay/armadra-agent/blob/main/docs/wave6-plan.md
636
- [i18n]: https://github.com/Owlbay/armadra-agent/blob/main/docs/i18n.md
246
+ [research]: https://github.com/Owlbay/armadra-agent/tree/main/docs/research
247
+ [w3]: https://github.com/Owlbay/armadra-agent/blob/main/docs/wave3-plan.md
637
248
  [wave5]: https://github.com/Owlbay/armadra-agent/blob/main/docs/wave5-plan.md
249
+ [wave6]: https://github.com/Owlbay/armadra-agent/blob/main/docs/wave6-plan.md
638
250
  [impl]: https://github.com/Owlbay/armadra-agent/blob/main/docs/implementation-plan.md
639
- [w3]: https://github.com/Owlbay/armadra-agent/blob/main/docs/wave3-plan.md
640
- [research]: https://github.com/Owlbay/armadra-agent/tree/main/docs/research
251
+
252
+ Release notes: [CHANGELOG.md](CHANGELOG.md) (English, from 0.6.0) and [CHANGELOG.zh-CN.md](CHANGELOG.zh-CN.md) (Chinese, complete history).
641
253
 
642
254
  ## Known limitations
643
255
 
644
- - **The Linux sandbox is not verified on real machines**: the bubblewrap policies are only verified by unit tests and Ubuntu CI, never on a Linux desktop / server; without bwrap ama falls back to `unshare -r -n` (network isolation only, unusable for the bash sandbox), and with neither it behaves as if there were no sandbox (codemode back to the execute class, approval every time).
645
- - **Real-CLI tests for external agents only run locally**: CI runs only recorded replays and ama driving ama; end-to-end tests against `claude` / `codex` need a logged-in machine and run with `AMA_E2E_AGENTS=1` (using your subscription quota); see [docs/agents.md](docs/agents.md) (Chinese).
646
- - **DeepSeek, Zhipu and Kimi still default to Chat**: their Messages channels (`@messages`) have only been tested through relays; the default switches once direct official endpoints pass the measurement gate (`scripts/channel-probe.mjs`).
647
- - **models.dev refresh PRs do not trigger CI automatically**: without the repository secret `MODELS_DEV_PR_TOKEN`, the weekly workflow opens the PR with the default token (after running `pnpm run ci` itself and putting the result in the description).
648
- - **ChatGPT login is not yet verified with a real account**: both flavors are tested against a local mock only. Still to be confirmed with a real Plus / Pro account: the tool `namespace` shape on the official (siwc) path (`toolsInNamespace` stays off), whether the codex device code needs enabling in ChatGPT security settings, and the fields of the codex `wham/usage` quota response. Real-account checks run locally with `AMA_E2E_CHATGPT=1` (see [docs/en/providers.md](docs/en/providers.md)).
649
- - Sub-agents have depth 1, do not read `.claude/agents` and have no fork mode that inherits the parent conversation; Windows has no OS sandbox.
256
+ - **Linux sandbox not verified on real machines**: bubblewrap policies are covered by unit tests and Ubuntu CI only. Windows has no OS sandbox: on Node 22 / 24 codemode there is not network-isolated and asks for approval every time.
257
+ - **External agents against real CLIs run locally only**: CI uses recorded replays and ama driving ama; real `claude` / `codex` runs need a logged-in machine and `AMA_E2E_AGENTS=1`.
258
+ - **ChatGPT login not yet verified with a real account**: both login flavors are tested against a local mock; real-account checks run locally with `AMA_E2E_CHATGPT=1`.
259
+ - **DeepSeek, Zhipu and Kimi default to the Chat channel**: their Messages channels (`@messages`) have only been tested through relays.
260
+ - Sub-agents have depth 1 and no fork mode that inherits the parent conversation.
650
261
 
651
262
  ## Development
652
263
 
653
- Requires Node ≥ 22 and pnpm (version in `packageManager` of `package.json`; `corepack enable` is enough).
264
+ Requires Node ≥ 22 and pnpm (`corepack enable`).
654
265
 
655
266
  ```sh
656
267
  pnpm install
657
- pnpm run ci # typecheck, fmt:check, check:deps, check:i18n, release:check, test, build, then bundle --version
658
- AMA_E2E=1 pnpm test:e2e # bundle-level end-to-end: print / rpc / acp / plan / sub-agents / rewind / codemode / cache / host / auth / config / memory / trace / i18n (fake provider, free)
268
+ pnpm run ci # typecheck, format, dependency and i18n checks, release check, tests, build
269
+ AMA_E2E=1 pnpm test:e2e # bundle-level end-to-end tests with the free fake provider
659
270
  ```
660
271
 
661
- Since pnpm 10, `pnpm ci` is the built-in "clean install", so run the checks with `pnpm run ci`. Common single steps: `pnpm test`, `pnpm typecheck`, `pnpm fmt`, `pnpm build`. Tests always use the fake provider: `AMA_FAKE_SCRIPT=<script.json>` makes it produce text, tool calls, 429s, dropped streams and so on from a script; examples are in `test/fixtures/scripts/`.
662
-
663
- **Real-model scripts** (run locally, not in CI; `pnpm build` first):
664
-
665
- | Script | Purpose |
666
- | -------------------------------------------------------- | ----------------------------------------------------------- |
667
- | `node scripts/bench-presets.mjs` (`pnpm bench:presets`) | Preset benchmark (`--tasks long` for long multi-step tasks) |
668
- | `node scripts/cache-experiment.mjs` (`pnpm bench:cache`) | Cache acceptance experiments E1–E5 |
669
- | `node scripts/record-sse.mjs` | Record SSE samples of each protocol as test fixtures |
670
-
671
- The first two share budget controls: `--config` / `AMA_REAL_CONFIG` (a config.json with key references), `--models` / `AMA_REAL_MODELS`, `--max-requests` / `AMA_REAL_MAX_REQUESTS` (default 60), `--budget-usd` / `AMA_REAL_BUDGET_USD` (default 3). They stop as soon as the request count or budget is exceeded and output the data collected so far; config and data directories point to temp directories, never your user config.
672
-
673
- **Constraints**: runtime dependencies must be zero; `src/` may only use `node:` built-ins and relative paths (guarded by `pnpm check:deps`). `src/` is organized by layer (`ai` model access, `agent` loop, `session` session tree, `tools`, `codemode`, `permissions`, `hooks`, `host` host contract, `tui` component library, `modes` entry points, `cli` startup), and each directory's `types.ts` is the contract between modules.
674
-
675
- **Releasing**: bump the version in `package.json`, update both changelogs (English [CHANGELOG.md](CHANGELOG.md) and Chinese [CHANGELOG.zh-CN.md](CHANGELOG.zh-CN.md), turning "Unreleased" into the version), merge into main and push a `v<version>` tag. Once CI is green the release job creates a GitHub Release (`ama.cjs`, `ama-sandbox.cjs`, `package.tgz`, `SHA256SUMS`) and publishes to npm with provenance. It prefers OIDC trusted publishing (npm ≥ 11.5.1, upgraded inside the job): add a GitHub Actions trusted publisher in the `@armadra/agent` package settings on npmjs.com (organization `Owlbay`, repository `armadra-agent`, workflow `ci.yml`, environment empty) and no long-lived token is needed; the repository secret `NPM_TOKEN` stays as a fallback, and the job fails with a hint when neither exists. `pnpm release:check` checks that the tag matches the version, requires a breaking version bump when protocol constants change, and checks that both READMEs / changelogs and `docs/en/` exist and link to each other and that both changelogs have a section for the current version (English from 0.6.0 on).
676
-
677
- ## Changelog
678
-
679
- See [CHANGELOG.md](CHANGELOG.md) (English, from 0.6.0) and [CHANGELOG.zh-CN.md](CHANGELOG.zh-CN.md) (Chinese, complete history since 0.1).
272
+ Tests use the scripted `fake` provider (`AMA_FAKE_SCRIPT`), never a real model. `src/` may only use `node:` built-ins and relative imports (`pnpm check:deps`). To release, bump the version, update both changelogs and push a `v<version>` tag; GitHub Actions creates the release and publishes to npm through trusted publishing.
680
273
 
681
- ## License
274
+ ## License and acknowledgements
682
275
 
683
- [MIT](LICENSE)
276
+ [MIT](LICENSE). Model metadata comes from [models.dev](https://models.dev) (MIT); see [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).