@armadra/agent 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +65 -0
- package/CHANGELOG.zh-CN.md +41 -0
- package/dist/agent/session-cache.d.ts +4 -2
- package/dist/agent/session-cache.js +5 -3
- package/dist/agent/session-compaction.d.ts +13 -1
- package/dist/agent/session-compaction.js +36 -0
- package/dist/agent/session-core.d.ts +2 -0
- package/dist/agent/session-state.d.ts +9 -3
- package/dist/agent/session-state.js +8 -6
- package/dist/agent/session.js +3 -3
- package/dist/agent/types-w5.d.ts +3 -0
- package/dist/agent/types.d.ts +18 -0
- package/dist/agents/task-record.d.ts +4 -0
- package/dist/agents/task-record.js +18 -0
- package/dist/ai/context.d.ts +7 -2
- package/dist/ai/context.js +45 -7
- package/dist/ai/providers/catalog-data.js +1 -1
- package/dist/auth/oauth/token-store.d.ts +2 -0
- package/dist/auth/oauth/token-store.js +7 -2
- package/dist/bundle/ama.cjs +1684 -490
- package/dist/checkpoints/shadow-git.js +2 -1
- package/dist/compaction/breakdown.d.ts +51 -0
- package/dist/compaction/breakdown.js +159 -0
- package/dist/compaction/estimate.d.ts +6 -0
- package/dist/compaction/estimate.js +1 -1
- package/dist/compaction/prefix-estimate.d.ts +23 -0
- package/dist/compaction/prefix-estimate.js +34 -0
- package/dist/config/auth-file.js +10 -2
- package/dist/config/fs-retry.d.ts +18 -0
- package/dist/config/fs-retry.js +33 -0
- package/dist/config/json-schema.js +1 -0
- package/dist/config/key-docs.js +1 -0
- package/dist/config/schema.js +2 -0
- package/dist/config/settings-registry.js +1 -0
- package/dist/config/types.d.ts +2 -0
- package/dist/drivers/native/codex-app-server.js +6 -0
- package/dist/drivers/runner.js +17 -0
- package/dist/drivers/store.d.ts +3 -0
- package/dist/drivers/store.js +4 -0
- package/dist/i18n/catalog.d.ts +53 -0
- package/dist/i18n/messages/agents.d.ts +3 -0
- package/dist/i18n/messages/agents.js +3 -0
- package/dist/i18n/messages/config-keys.d.ts +2 -0
- package/dist/i18n/messages/config-keys.js +2 -0
- package/dist/i18n/messages/config.d.ts +2 -0
- package/dist/i18n/messages/interactive.d.ts +6 -0
- package/dist/i18n/messages/interactive.js +6 -0
- package/dist/i18n/messages/panels.d.ts +3 -0
- package/dist/i18n/messages/panels.js +5 -2
- package/dist/i18n/messages/report-context.d.ts +94 -0
- package/dist/i18n/messages/report-context.js +95 -0
- package/dist/i18n/messages/report.d.ts +96 -0
- package/dist/i18n/messages/report.js +13 -2
- package/dist/i18n/messages/settings.d.ts +2 -0
- package/dist/i18n/messages/settings.js +2 -0
- package/dist/i18n/messages/subcommands.js +2 -2
- package/dist/modes/acp/acp-events.d.ts +17 -4
- package/dist/modes/acp/acp-events.js +32 -6
- package/dist/modes/commands-core.js +4 -0
- package/dist/modes/context-report.d.ts +35 -0
- package/dist/modes/context-report.js +172 -0
- package/dist/modes/interactive/agent-bar.d.ts +2 -0
- package/dist/modes/interactive/agent-bar.js +6 -0
- package/dist/modes/interactive/commands.d.ts +2 -1
- package/dist/modes/interactive/commands.js +10 -1
- package/dist/modes/interactive/interactive-mode.d.ts +3 -0
- package/dist/modes/interactive/interactive-mode.js +6 -1
- package/dist/modes/interactive/panels.d.ts +2 -1
- package/dist/modes/interactive/panels.js +13 -5
- package/dist/modes/interactive/program-status-ui.d.ts +72 -0
- package/dist/modes/interactive/program-status-ui.js +229 -0
- package/dist/modes/interactive/session-events.d.ts +4 -0
- package/dist/modes/interactive/session-events.js +24 -2
- package/dist/modes/interactive/status-bar.d.ts +21 -3
- package/dist/modes/interactive/status-bar.js +64 -25
- package/dist/modes/interactive/status-ctx.d.ts +55 -0
- package/dist/modes/interactive/status-ctx.js +125 -0
- package/dist/modes/interactive/status-line.d.ts +2 -1
- package/dist/modes/interactive/status-line.js +3 -2
- package/dist/modes/interactive/tasks-report.js +4 -0
- package/dist/modes/print/print-mode.js +12 -0
- package/dist/modes/session-report.d.ts +10 -2
- package/dist/modes/session-report.js +26 -2
- package/dist/sdk.d.ts +1 -1
- package/dist/tools/types.d.ts +6 -0
- package/dist/tui/components/meter.d.ts +2 -0
- package/dist/tui/components/meter.js +1 -1
- package/dist/tui/program-status.d.ts +90 -0
- package/dist/tui/program-status.js +259 -0
- package/docs/acp.md +4 -4
- package/docs/agents.md +1 -1
- package/docs/en/acp.md +4 -4
- package/docs/en/providers.md +5 -3
- package/docs/en/rpc.md +3 -0
- package/docs/en/sessions.md +24 -1
- package/docs/en/tui.md +79 -22
- package/docs/providers.md +8 -5
- package/docs/rpc.md +1 -0
- package/docs/session-format.md +3 -3
- package/docs/sessions.md +23 -1
- package/docs/tui-design.md +2 -2
- package/docs/tui.md +79 -22
- package/package.json +1 -1
package/docs/en/tui.md
CHANGED
|
@@ -39,8 +39,8 @@ The visual spec (colors, glyphs, screen-by-screen mockups) is in [tui-design.md]
|
|
|
39
39
|
────────────────────────────────────────────────
|
|
40
40
|
› Type a message, / commands, @ files, Shift+Enter newline ← input box (placeholder)
|
|
41
41
|
────────────────────────────────────────────────
|
|
42
|
-
codemode on tps: 100 tok/s • 546 tok / 5.5s (avg 100 · ttft 1.4s) ·
|
|
43
|
-
Accept edits | shift+tab to cycle claude-opus-5-5 medium | Ctx 3.0% | proj ⎇ main 5ae9e54 ↑2 (+12,-3) | $0.26 | 2h24m
|
|
42
|
+
codemode on tps: 100 tok/s • 546 tok / 5.5s (avg 100 · ttft 1.4s) · Σ↑12k ↓1.2k R9.6k · cache 80% ♨ · [-] ← rate line (full)
|
|
43
|
+
Accept edits | shift+tab to cycle claude-opus-5-5 medium | Ctx 3.0% 8.2k/272k auto | proj ⎇ main 5ae9e54 ↑2 (+12,-3) | $0.26 | 2h24m
|
|
44
44
|
Session: 10.0% | Reset: 2h 18m | Weekly: 31.0% | Weekly Reset: 6d 5h ← subscription quota line (full, ChatGPT subscription model)
|
|
45
45
|
```
|
|
46
46
|
|
|
@@ -50,16 +50,17 @@ Accept edits | shift+tab to cycle claude-opus-5-5 medium | Ctx 3.0% | proj
|
|
|
50
50
|
- **Notices**: `✗` errors, `↻ retry n/m`, `!` warnings (cache misses, remaining context), `⛔` hook blocks, host notifications, explanations of denied or timed-out approvals; compaction / branch summaries are left-bar cards (`▎ context compacted 128k → 24k tokens`).
|
|
51
51
|
- **Running**: `⠋ verb · elapsed · …`, with the verb taken from the deepest current state: waiting for confirmation (approval open), `running bash` / `running 3 tools`, `retry 2/3 · in 2s`, compacting context, replying `· ↓≈1.2k` (estimated tokens of this output), thinking. While a foreground sub-agent task blocks the turn, `Ctrl+B to background` is appended; while the agent bar has tasks, `↓ Agent bar` is appended (`↓ handle approval` instead when an approval is docked): `⠏ running task · 4s · Esc to interrupt · Ctrl+B to background · ↓ Agent bar`; items are dropped whole from the end when the line does not fit. With text in the input box, `Enter queue · Ctrl+X interrupt & send` comes first (`Enter interrupt & send · Ctrl+X queue` with `ui.enterWhileRunning: "interrupt"`); with queued steers the queue's last line reads `Alt+↑ take back · Ctrl+X send now · Esc refill and interrupt`.
|
|
52
52
|
- **Status bar**: the mode is always on the far left; `full` splits into two sides — the left column holds state and switches (permission mode, the `shift+tab` hint, codemode, sandbox, preset, fallback), the right column holds metrics and the model (tps, usage, model, Ctx, git, cost, duration, quota), right-aligned, and a line with nothing on the left sits flush right; the status bar is the last line except for the subscription quota line in the `full` layout (`compact` always keeps it last). In `compact` the separator is always `·` (embedding hosts parse it), in `full` it is `|`. The layout follows `ui.statusLine`: `full` (two lines) by default in a standalone terminal, `compact` (one line, same layout as before) by default in an embedding host with a profile; `Ctrl+G` or `/statusline [full|compact]` switches at runtime for this session only. With `full` the input box is the 4th line from the bottom (`compact` keeps it 3rd from the bottom).
|
|
53
|
-
- **`full` top line (rate line)**: the left side holds switches: `codemode on|only` (with `net!` when the network is not isolated) · `sandbox` · `preset <name>` (when not default) · `→ <fallback model>` (during a fallback, yellow) · queue count · host status; it is empty when there are none. The right side is `tps: <rate> tok/s • <output tokens> tok / <elapsed> (avg <session average> · ttft <time to first token>) ·
|
|
54
|
-
- **`full` bottom line**: on the left `permission mode | shift+tab to switch`, on the right `model thinking-level | Ctx 3.0% | <dir name> ⎇ <branch> <short commit> ↑N ↓N (+a,-d) | $cost | session duration` (Ctx with one decimal, no meter even when wide); when narrow, these drop in order: the switch hint, thinking level, line changes, directory name, branch and commit, duration, cost, context, model.
|
|
53
|
+
- **`full` top line (rate line)**: the left side holds switches: `codemode on|only` (with `net!` when the network is not isolated) · `sandbox` · `preset <name>` (when not default) · `→ <fallback model>` (during a fallback, yellow) · queue count · host status; it is empty when there are none. The right side is `tps: <rate> tok/s • <output tokens> tok / <elapsed> (avg <session average> · ttft <time to first token>) · Σ↑<input> ↓<output> R<cache read> W<cache write> · cache · re-billing · [-]`. While streaming the rate is the instantaneous value over the last 2 s (`tps:` in the accent color); afterwards it is the request's average; whole replies generated in under 0.25 s get no rate and show `—`; elapsed time starts at the first token; `Σ` marks the **session total** of billed tokens (not context usage), `↑` input includes cache reads and writes, which are also listed as `R` / `W` (hidden when 0; `Σ` is `sum ` in ASCII); in ASCII `•` becomes `*` and `→` becomes `->`; `[-]` at the end hints that it folds. Only chat requests count (compaction summaries, warming and the classifier do not). When narrow, the right-side metrics drop first (output / elapsed, tokens, cache, re-billing, avg, ttft), then the left-side switches (host status, queue count, preset, fallback, sandbox, codemode); `tps` and `[-]` never drop.
|
|
54
|
+
- **`full` bottom line**: on the left `permission mode | shift+tab to switch`, on the right `model thinking-level | Ctx 3.0% 8.2k/272k auto | <dir name> ⎇ <branch> <short commit> ↑N ↓N (+a,-d) | $cost | session duration` (Ctx with one decimal, no meter even when wide). The Ctx part is the current context: the percentage, used / window, and `auto` while auto-compaction is on (hidden when it is off, tripped after repeated failures, or the window is unknown); the numbers get a leading `≈` when they do not come from usage reported by the model (the baseline estimated from the system prompt and tool declarations before the first request, or the full estimate after a compaction until the next request); without a window it reads `Ctx ? 8.2k`. When narrow, these drop in order: `auto`, the switch hint, thinking level, `/window`, line changes, directory name, branch and commit, used tokens, duration, cost, the context percentage, model.
|
|
55
55
|
- **Subscription quota line** (third `full` line, below the status bar): when the current model uses a ChatGPT subscription (the `chatgpt` provider) it shows `Session: <used %> | Reset: <time to reset> | Weekly: <used %> | Weekly Reset: <time to reset>` (Chinese labels in the Chinese interface), from the latest `quota_update` (the codex flavor's `x-codex-primary/secondary-*` response headers and `codex.rate_limits` events; siwc only has it after a 429). Reset times are relative (`2h 18m`, `6d 5h`) and refresh once a minute. Before the first request the codex flavor shows "Quota: shown after the first request" (the first request brings the quota back, so holding the line avoids the row count jumping); siwc without data takes no line (it only gets a quota when over the limit, so a placeholder would stay forever); non-subscription models show nothing. Below 80 columns it compresses to `5h 10% ↻2h18m · wk 31% ↻6d5h`, dropping the reset times first when narrower. The quota line is right-aligned. Labels follow the window length rather than the primary / secondary slot: 300 minutes is `Session`, 10080 minutes is `Weekly`, any other length shows the length itself (`1d: `); without a length, primary counts as Session and secondary as Weekly (or the other one if that name is taken); windows are ordered shortest first. A window with 0 % used, no length and no reset time is the server saying "no such window" and is not shown (some plans get a single weekly window from codex, sent as primary). `Ctrl+G` / `/statusline compact` folds the quota line together with the rate line (`compact` stays a single line; hosts anchor on "last line = status bar").
|
|
56
|
-
- **Colors** (`full`): labels, units, separators and parentheses dim gray; the rate number purple, output / elapsed / avg blue, ttft purple; model and thinking level blue; Ctx
|
|
56
|
+
- **Colors** (`full`): labels, units, separators and parentheses dim gray; the rate number purple, output / elapsed / avg blue, ttft purple; model and thinking level blue; Ctx by threshold green / yellow / red (yellow once past the tier-one pruning threshold — 0.7 × (window − reserve), a little under 70%; red at ≥ 90%; ≥ 70% yellow when there is no threshold), quota percentages yellow at ≥ 70% and red at ≥ 90%; directory and branch green, short commit dim, `↑N` ahead orange, `↓N` behind red, `(+a,-d)` green / red; cost yellow; duration and reset times purple. All come from theme semantic colors with dark / light and 16-color mappings; `NO_COLOR` and ASCII drop the colors and keep the structure. `compact` colors are unchanged.
|
|
57
57
|
- **`compact`**: one line; on the right model · thinking level · `↑ ↓` · cache · cost · re-billing · context usage · dir ⎇ branch commit +a −b · session duration · queue count · codemode · preset · host status · a short subscription quota item (`5h 10% wk 31%`, only with quota data; no `·` inside the item); when narrow, these drop in order: the quota item, the switch hint, host status, preset, re-billing, cost, cache, tokens, thinking level, queue count, codemode, line changes, directory name, branch and commit, duration, context, model.
|
|
58
58
|
- **git**: branch and short commit are read directly from `.git/HEAD` (worktrees understood; detached shows only the short commit; outside git the whole part is omitted, leaving only the directory name). `+a −b` is the working tree (staged included) line diff against HEAD, computed in the background with `git diff --numstat HEAD` after a turn ends, a writing tool finishes, a rewind or `/tree`, at most once every 10 seconds; if it takes longer than 2 seconds or fails, line changes are hidden for the rest of the session; `AMA_STATUS_GIT=0` turns it off. In `full`, `↑N` / `↓N` count the commits the current branch is ahead of / behind its upstream: when the branch has an upstream in the git config (`branch.<name>.merge`), the same throttled cycle then runs `git rev-list --left-right --count @{upstream}...HEAD` (same 2-second timeout; after a timeout it stops for the session); zero, no upstream or detached shows nothing; ASCII uses `^N` / `vN`.
|
|
59
59
|
- **Cost** includes sub-tasks, warming, the classifier and external agent usage priced in USD (other units only in `/session`); **duration** counts from when this process opened the current session (`Ns` / `Nm` / `NhMm`).
|
|
60
60
|
- When bash commands run in the OS sandbox (`sandbox.bash: "auto"` and available on this machine, see [sandbox.md](../sandbox.md), Chinese), the usage items gain a sandbox marker, dropped first together with codemode when space runs out.
|
|
61
61
|
- During a model fallback (`fallbackModel`: when the main model is overloaded or retries are exhausted, one retry with the fallback model) the `compact` model item shows `main model → fallback model` (the fallback in yellow), while `full` keeps only the main model there and shows `→ fallback model` on the left of the rate line; it disappears once the fallback model replies and the main model is restored, and the message area gets an explanatory line.
|
|
62
|
-
-
|
|
62
|
+
- **Context refresh**: it updates right after a message is submitted (the new message counted as an estimate); while streaming, once the reply carries usage (some protocols report input tokens at the start) it switches to the measured value of the in-flight request, at most twice a second; after the reply ends, a compaction or a model change it goes back to the session stats.
|
|
63
|
+
- Model names abbreviate with width (provider dropped below 100 columns, channel below 60, version suffix below 48); `compact` at ≥ 110 columns shows context as a meter `ctx ▮▮▮▯▯▯▯▯▯▯ 34%`, keeping one decimal below 1% (`ctx ≈0.4%` rather than 0%), with the same `≈` for estimates; changing numbers reserve their widest shape, so items never flicker in and out as values change. In ASCII mode `⎇` → `git`, `−` → `-`, `♨` → `~`, `↻` → `@`.
|
|
63
64
|
- **Exit**: a session summary line and the resume command are appended at the end of the message area and stay in the terminal scrollback:
|
|
64
65
|
|
|
65
66
|
```
|
|
@@ -78,7 +79,7 @@ Status bar items:
|
|
|
78
79
|
| `cache` "not reported" | The endpoint does not report cache usage (`silent`: reads and writes were 0 for 3 comparable requests in a row, or `compat.cacheReporting: "silent"`); such requests stay out of the hit-rate denominator |
|
|
79
80
|
| `♨` | Warming timer running (during long tool runs the prefix is replayed per TTL; `/cache warm` switches it) |
|
|
80
81
|
| `rebill $0.11` | Re-billing caused by cache misses in this session; token count for models without prices; hidden when 0 |
|
|
81
|
-
| `ctx 72%` | Context usage:
|
|
82
|
+
| `ctx 72%` | Context usage: yellow past the pruning threshold, red at ≥ 90%; `≈` an estimate; `ctx ?` no window information |
|
|
82
83
|
| `codemode only` | codemode active (`on` / `only`); a red `net!` is appended when the network is not isolated (Node 22 / 24 without an OS sandbox, see sandbox.md) |
|
|
83
84
|
|
|
84
85
|
The message area (stderr with an `ama: ` prefix in line mode) shows one line in only two cases; `cache.missNotices: false` turns them off:
|
|
@@ -91,10 +92,10 @@ The message area (stderr with an `ama: ` prefix in line mode) shows one line in
|
|
|
91
92
|
|
|
92
93
|
```
|
|
93
94
|
▎ Session 3f2a9c1e ~/.local/share/ama/sessions/…/3f2a9c1e.jsonl
|
|
94
|
-
▎ Model
|
|
95
|
-
▎ Messages
|
|
96
|
-
▎
|
|
97
|
-
▎ Context
|
|
95
|
+
▎ Model anthropic/claude-sonnet-4-5 · thinking medium · permission Accept edits
|
|
96
|
+
▎ Messages user 7 · assistant 9 · tool calls 23
|
|
97
|
+
▎ Total usage input 3.4k · output 9.4k · cache read 118k · cache write 6.2k · $0.42
|
|
98
|
+
▎ Context ▮▮▮▯▯▯▯▯▯▯ 34% · 68k / 200k · ≈ 116k until auto-compaction
|
|
98
99
|
▎
|
|
99
100
|
▎ Cache
|
|
100
101
|
▎ Input 3.4k = cache read 2.2k (65%) + uncached 1.2k
|
|
@@ -219,6 +220,38 @@ Design in [rewind-plan.md](../rewind-plan.md) (Chinese). Every user message that
|
|
|
219
220
|
- `/plan`: the current plan panel (see "Plan approval" below); `/plan <goal>` enters Plan mode and sends the goal; `/plan approve [mode|fresh]` and `/plan reject` approve / discard directly without a dialog.
|
|
220
221
|
- `/tasks`: focus the agent bar, `/tasks <id>` opens the sub-agent view; `/agents`: the available sub-agent types (see "Sub-agents" below).
|
|
221
222
|
- `/paste`: same as `Ctrl+V`.
|
|
223
|
+
- `/context`: a per-category breakdown of the context (see the next section).
|
|
224
|
+
|
|
225
|
+
### /context
|
|
226
|
+
|
|
227
|
+
`/context` answers "what is taking up the context". Interactive mode draws a left-bar panel; line mode, and interactive mode without a panel, print the same content as plain text:
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
▎ Context
|
|
231
|
+
▎ Used 10.6k / 200k (5.3%)
|
|
232
|
+
▎ Left 189k tokens
|
|
233
|
+
▎ Source reported usage 9k + estimated 1.6k
|
|
234
|
+
▎ Auto-compact at 184k, ≈ 173k to go
|
|
235
|
+
▎ Pruning old tool results trimmed from 129k
|
|
236
|
+
▎
|
|
237
|
+
▎ By category (estimated, 5.8k)
|
|
238
|
+
▎ System prompt and tool declarations are counted from the stored system messages; the full estimate can differ from reported usage.
|
|
239
|
+
▎ System prompt 600 ▮▯▯▯▯▯▯▯▯▯ 10% rules 500 · preamble 100 · cwd 0
|
|
240
|
+
▎ Tool declarations 333 ▮▯▯▯▯▯▯▯▯▯ 6% bash 241 · read 91
|
|
241
|
+
▎ …
|
|
242
|
+
▎ Tool results 3.2k ▮▮▮▮▮▯▯▯▯▯ 55% read 3k · bash 203
|
|
243
|
+
▎ Images 1.6k ▮▮▮▯▯▯▯▯▯▯ 27% 1 image · user 1.6k
|
|
244
|
+
▎
|
|
245
|
+
▎ Largest tool results (top 5)
|
|
246
|
+
▎ #1 3k read
|
|
247
|
+
▎ #2 203 bash
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
- **Top**: used / window and percentage (the same measure as `/session`: the latest usable usage plus an estimate of the messages after it), tokens left, the source ("reported usage X + estimated Y"; "estimated in full" when there is no usable usage yet, or a compaction / context edit happened after it), the auto-compact trigger (window − `compaction.reserveTokens`; "off" when disabled, "window unknown" without a window) and where tier-one pruning starts.
|
|
251
|
+
- **By category**: system prompt (per section), tool declarations (per tool), user messages, assistant text, reasoning, tool-call arguments (per tool), tool results (summed per tool name), images (1,600 each), summaries (compaction / branch) and custom messages, each with an estimated token count, share and bar. The categories add up to the character-based estimate of the whole projection (one token per CJK character, other characters / 4), so the total in the heading can differ from "Used" at the top, which prefers the usage reported by the model.
|
|
252
|
+
- **System prompt and tool declarations** come from the system messages stored in the session (the first full one and later patches, matching the estimate); before the first request the branch has no system message yet, both categories are 0 and the panel says they are counted after the first request.
|
|
253
|
+
- **Bottom**: only the ordinal (which tool result in the projection), tool name and size of the 5 largest tool results — **never their content**.
|
|
254
|
+
- Read-only: no session entries are written and the request body is untouched, so the prompt-cache prefix is unaffected.
|
|
222
255
|
|
|
223
256
|
## Entering Bypass
|
|
224
257
|
|
|
@@ -449,10 +482,33 @@ Requires memory to be enabled (`ama memory enable` or `--memory`, see [memory.md
|
|
|
449
482
|
|
|
450
483
|
`ui.quietStartup` / `--quiet-startup`: `normal` shows an "AMA" logo with an info column: version, model and thinking level, directory (`~` abbreviated) and trust state, permission mode / preset / codemode, loaded context files / Skills / prompt templates / hooks, warning count and common keys. At 72 columns or wider the logo sits on the left and the info on the right; at 48–71 columns the logo is on top; below 48 columns a two-line header is shown instead (version · model · thinking / mode · directory · trust). `ui.logo: "off"` or `ui.compact` shows only the info column. The logo takes the theme's accent → user → tool colors letter by letter; ASCII mode swaps in a glyph made of `_ / \ |`. On startup a one-off "light-up" sweep plays for about a second (the glyph starts dim, a highlight band sweeps left to right, then it settles); it redraws in place and leaves no frames in the scrollback, and any key settles it at once while the key still goes to the input box. The settled frame is shown directly with `ui.animation: false`, `NO_COLOR` / a colorless terminal, a non-TTY, an embedding host (profile.host), a `CI` environment, a prompt given on the command line (`ama "…"`), a terminal shorter than 16 rows or content taller than one screen; the line interface, `-p`, RPC and ACP draw no startup header. `header` is a single line `✻ ama version · model · mode · /help` (the profile default); `silent` shows nothing. When `--resume` has no id, the model has no key, the session directory does not exist or project resources need trust, a small selection / input prompt appears before the interface starts, collapsing into one line on screen once answered.
|
|
451
484
|
|
|
485
|
+
## Terminal program status (OSC 7501)
|
|
486
|
+
|
|
487
|
+
The interactive interface reports its run state to the terminal with the [OSC 7501 Program Status Protocol](https://www.superlogical.com/rex/docs/build/program-status) (rev 0.3), so a supporting terminal can show "running / waiting for you / done / failed" in tabs, sidebars or notifications. Reports always carry `app=ama`; each report replaces that record as a whole.
|
|
488
|
+
|
|
489
|
+
| When | Root record |
|
|
490
|
+
| -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
491
|
+
| Startup, switching sessions (`/new` `/resume` `/fork`) | `idle` |
|
|
492
|
+
| A turn starts | `working`, msg is the current activity (Thinking / Replying / Running bash / Compacting context; throttled to 500 ms, unchanged values not resent) |
|
|
493
|
+
| An approval needs a person (including sub-agents' ones) | `blocked` `kind=permission`, msg is "tool · target" |
|
|
494
|
+
| A plan awaits approval | `blocked` `kind=question` |
|
|
495
|
+
| A turn failed because the login expired (`auth_expired`) | `blocked` `kind=auth`, msg is the first line of the error; cleared when the next turn starts or the model changes |
|
|
496
|
+
| The approval / plan is handled | back to `working` (or whatever the turn ended with) |
|
|
497
|
+
| A turn ends normally | `done`; any key pressed in ama afterwards goes back to `idle` |
|
|
498
|
+
| A turn fails | `error`, msg is the first line of the error |
|
|
499
|
+
| The user interrupts (Esc etc.) | `idle` |
|
|
500
|
+
| Leaving interactive mode | `clear` without an id (removes all of this program's records) |
|
|
501
|
+
|
|
502
|
+
- Sub-agent tasks get child records `id=task/<short id>` with the task description as title: `working` (msg is the tool in use) → `blocked` while an approval waits → `done` when finished, `error` on failure or the turn limit, `idle` when interrupted; finished task records are cleared when the next main turn starts.
|
|
503
|
+
- Exiting sends `clear`, not `done`: when the user quits, the result is already on screen and a lingering "done" record would only be noise.
|
|
504
|
+
- `ui.programStatus`: `auto` (default) sends `OSC 7501 ; ?` and `CSI c` (DA1) at startup and only reports once the `?` reply arrives; if DA1 answers first or nothing arrives within 300 ms it stays silent. Both replies (late ones too) are swallowed by the input parser and never reach the input box. `on` sends without detecting (the spec allows it: conforming terminals ignore unknown OSCs). `off` neither detects nor sends. Changes take effect after a restart.
|
|
505
|
+
- tmux: it drops unknown OSCs by default, and the spec does not cover multiplexers. tmux does not forward the outer terminal's reply to a passthrough query to the pane, so detection is unreliable and `auto` equals `off` inside tmux; to use it set `on` and `set -g allow-passthrough on` in tmux, and reports are wrapped in DCS passthrough (`ESC P tmux; … ESC \`).
|
|
506
|
+
- Interactive interface only. The stdout of `-p`, RPC and ACP is data or protocol, so nothing is sent there; `-p` sends nothing even when stderr is a terminal: it is a one-shot process whose result is the exit code, the next prompt drops working records anyway, and a leftover done / error is only noise for scripted runs.
|
|
507
|
+
|
|
452
508
|
## In tmux / Armadra terminal nodes
|
|
453
509
|
|
|
454
510
|
- Bracketed paste: enabled at startup; pasted multi-line content enters the input box as a whole (folded into a paste placeholder with the line count beyond 10 lines or 1 000 characters), and an Enter right after a paste sends directly, which suits writes from external programs.
|
|
455
|
-
-
|
|
511
|
+
- Apart from program status detection (see the previous section; none inside tmux), terminal capabilities are not queried, and mouse and the Kitty keyboard protocol are not enabled, so no replies get mixed into input; tmux ≥ 3.4 passes synchronized output through, and older versions display fine too.
|
|
456
512
|
- tmux's default prefix `C-b` is taken by the tmux client: to move tasks to the background press `C-b C-b` (`send-prefix` passes it through), or `↓` into the agent bar and press `b`; entering the bar uses `↓`, which the prefix does not affect.
|
|
457
513
|
- When the window size changes the last screen is redrawn in full; history in the scrollback is unaffected.
|
|
458
514
|
- Automatic fallback: non-TTY, `TERM=dumb`, `--no-tui` or a failed terminal initialization use line mode, with the same commands and approval prompts.
|
|
@@ -461,16 +517,17 @@ Requires memory to be enabled (`ama memory enable` or `--memory`, see [memory.md
|
|
|
461
517
|
|
|
462
518
|
The `ui` section of `config.json` (settable at project level too):
|
|
463
519
|
|
|
464
|
-
| Key
|
|
465
|
-
|
|
|
466
|
-
| `ui.theme`
|
|
467
|
-
| `ui.ascii`
|
|
468
|
-
| `ui.compact`
|
|
469
|
-
| `ui.logo`
|
|
470
|
-
| `ui.animation`
|
|
471
|
-
| `ui.markdown`
|
|
472
|
-
| `ui.showThinking`
|
|
473
|
-
| `ui.quietStartup`
|
|
520
|
+
| Key | Default | Effect |
|
|
521
|
+
| ------------------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
522
|
+
| `ui.theme` | `dark` | `dark` / `light` / `auto`; auto only looks at `COLORFGBG` (no terminal query) and uses dark when unsure; configuring it explicitly is recommended |
|
|
523
|
+
| `ui.ascii` | auto-detected | ASCII glyphs (`›` → `>`, `⏺` → `*`, `⎿` → `L`, box lines → `+ - \|`, a 4-frame spinner) |
|
|
524
|
+
| `ui.compact` | `false` | No blank lines between message blocks, no logo in the startup header |
|
|
525
|
+
| `ui.logo` | `auto` | The "AMA" logo in the startup header; `off` shows only the info column |
|
|
526
|
+
| `ui.animation` | `true` | `false`: the spinner stays still as `·` while running and redraws only when seconds change; the startup logo does not animate |
|
|
527
|
+
| `ui.markdown` | `true` | `false`: assistant text is not rendered as Markdown |
|
|
528
|
+
| `ui.showThinking` | `collapsed` | See "Layout" |
|
|
529
|
+
| `ui.quietStartup` | `normal` | See "Startup screen" |
|
|
530
|
+
| `ui.programStatus` | `auto` | Terminal program status OSC 7501: `auto` / `on` / `off`, see "Terminal program status" |
|
|
474
531
|
|
|
475
532
|
- **ASCII mode**: `AMA_ASCII=1` (or `ui.ascii: true`) forces it on, `AMA_ASCII=0` forces it off; auto-detection turns it on when the locale (`LC_ALL` > `LC_CTYPE` > `LANG`) is set but lacks UTF-8, with `TERM=linux`, or on Windows without `WT_SESSION` or `TERM_PROGRAM` (legacy conhost). Windows Terminal uses Unicode.
|
|
476
533
|
- **Misaligned characters**: `⏺` (U+23FA), `⎿` and `▎` render two cells wide in some fonts (emoji fallback fonts in particular), while width is computed per wcwidth (one cell), causing misaligned columns or ghosting; switch to a monospace font or set `AMA_ASCII=1`.
|
package/docs/providers.md
CHANGED
|
@@ -561,7 +561,7 @@ src/ai/providers/catalog.test.ts` 自动删除并重新生成 `catalog-data.ts`
|
|
|
561
561
|
| `requiresReasoningContentOnAssistantMessages` | 推理模型的历史助手消息带 `reasoning_content`(DeepSeek) |
|
|
562
562
|
| `requiresToolResultName` | 工具结果消息带 `name`(Mistral) |
|
|
563
563
|
| `requiresAssistantAfterToolResult` | 工具结果后紧跟用户消息时插入一条助手消息 |
|
|
564
|
-
| `supportsMidConvoSystemMessages` | 后续系统提示补丁按位置作为 system
|
|
564
|
+
| `supportsMidConvoSystemMessages` | 后续系统提示补丁按位置作为 system 消息插回;关闭(缺省)时作为尾部上下文送达,见「缓存」 |
|
|
565
565
|
| `cacheControlFormat` | `anthropic`:在 system、最后一个工具、最后一条 user/tool 消息上打 `cache_control` |
|
|
566
566
|
| `supportsStrictTools` | 对严格兼容的工具 schema 发 `strict: true` |
|
|
567
567
|
| `supportsStore` | 发 `store: false` |
|
|
@@ -603,6 +603,8 @@ OpenRouter 的 Messages 接口只在 `message_delta` 里给缓存 usage,解析
|
|
|
603
603
|
|
|
604
604
|
前缀稳定由组装保证:系统提示节顺序固定、不含时间戳,工具按名排序,会话中途的变化只以 system 补丁追加在末尾([session-format.md](session-format.md)「消息」)。
|
|
605
605
|
|
|
606
|
+
对话开始之后的节补丁(resume 时 AGENTS.md、Skills 或 SessionStart Hook 输出变了,宿主 instructions 刷新,压缩后记忆节重新渲染)**不改写开头的 system**:没有打开 `supportsMidConvoSystemMessages` 的协议把它渲染成 `<system-reminder>` 包裹的 user 消息,插在补丁所在的位置,之前的请求仍是逐字节前缀。只有移除工具的补丁例外——工具表本身已经变了,前缀必然失效,这时全部补丁照旧折回开头。实测 DeepSeek 接受对话中途的 system 消息、前缀缓存也保持,但模型仍按开头那条回答,所以 DeepSeek 不打开这个开关([cache-midconvo-2026-10-09](benchmarks/cache-midconvo-2026-10-09.md))。下一次压缩时,这些补丁随 system 检查点并回开头。
|
|
607
|
+
|
|
606
608
|
### 请求字段
|
|
607
609
|
|
|
608
610
|
| 协议 | 字段 | 条件 |
|
|
@@ -650,9 +652,10 @@ Anthropic 的 `baseUrl` 以 `/v1` 结尾时请求 `{baseUrl}/messages`,不会
|
|
|
650
652
|
### 模型目录 `promptCache`
|
|
651
653
|
|
|
652
654
|
只写有公开依据的值(秒 / token):Anthropic 全部 `short 300 / long 3600`,`minTokens` 按模型 512–4096;OpenAI
|
|
653
|
-
全部 `short 300 / long 86400 / minTokens 1024`;Kimi 全部 `short 300
|
|
654
|
-
|
|
655
|
-
|
|
655
|
+
全部 `short 300 / long 86400 / minTokens 1024`;Kimi 全部 `short 300`;DeepSeek 全部 `short 3600 / minTokens 2048`
|
|
656
|
+
(官方只说未使用的缓存「几小时到几天」后清除,取保守的 1 小时;缓存读实测按 2048 token 一块计)。智谱、通义、Groq、
|
|
657
|
+
xAI、Mistral、OpenRouter、Google 没有承诺的 TTL,留空:不保温、不按猜测的寿命提前裁剪,只有未命中归因按隐式缓存
|
|
658
|
+
10 分钟估。可在 `models[]` / `modelOverrides[]` 里自填;中转上的 DeepSeek 模型不继承官方目录的值,需要时照填。
|
|
656
659
|
|
|
657
660
|
### 会话层:指纹、未命中与三态
|
|
658
661
|
|
|
@@ -717,7 +720,7 @@ ama models cache-probe <provider/id> [--tokens 2048] [--gap-ms 3000] [--json] [-
|
|
|
717
720
|
|
|
718
721
|
用一个确定性的固定前缀(约 `--tokens` token)+ `Reply with: ok`,`maxTokens: 16`,相隔 `--gap-ms` 发两次,判定:
|
|
719
722
|
|
|
720
|
-
- `reported`:第二次 cacheRead ≥ 前缀的 50%;目录没有 `promptCache`
|
|
723
|
+
- `reported`:第二次 cacheRead ≥ 前缀的 50%;目录没有 `promptCache` 时提示寿命未知(不保温、不提前裁剪),只有上游文档写明寿命时才自填,不给猜测值——偏短的值会在缓存仍有效时触发保温和提前裁剪;
|
|
721
724
|
- `silent`:两次读写都是 0;建议设 `compat.cacheReporting: "silent"`。响应里有缓存字段但恒为 0 时另提示可能是写入延迟(同一中转的 kimi-k2.5 间隔 3 秒两次都是 0、间隔 8 秒第二次读满前缀),可加大 `--gap-ms` 重试;
|
|
722
725
|
- `inconclusive`:读到一点或只有写入,多半是缓存粒度或 TTL 问题。
|
|
723
726
|
|
package/docs/rpc.md
CHANGED
|
@@ -292,6 +292,7 @@
|
|
|
292
292
|
| `tokens` | `{ input, output, cacheRead, cacheWrite, total }`,含保温请求的用量 |
|
|
293
293
|
| `cost` | 美元;任一条消息缺成本时缺省(界面显示 `$?`) |
|
|
294
294
|
| `contextTokens` / `contextWindow` / `contextPercent` | 当前上下文估算、窗口与占用(0–100);模型没有窗口时缺省 |
|
|
295
|
+
| `context` | 估算来源与自动压缩阈值(字段与缺省语义见 sessions.md) |
|
|
295
296
|
| `cacheHitRate` | 旧口径命中率:cacheRead /(input + cacheRead + cacheWrite),全部请求进分母 |
|
|
296
297
|
| `cache` | `SessionCacheStats`(下例),会话层缓存控制器接线时才有 |
|
|
297
298
|
|
package/docs/session-format.md
CHANGED
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
|
|
48
48
|
### 消息
|
|
49
49
|
|
|
50
|
-
- `system`:`{ role: "system", sections, toolsAdded?, toolsRemoved?, timestamp }`。首条是全量:系统提示的命名节(固定顺序 `preamble → tools → rules → project_context → skills → memory → hooks → cwd → host → role`;`memory` 是第六波的记忆索引节,未开启记忆时不出现)与工具声明表;之后只落**补丁**——节名级替换、值为 `null` 表示删除该节,`toolsAdded` / `toolsRemoved`
|
|
50
|
+
- `system`:`{ role: "system", sections, toolsAdded?, toolsRemoved?, timestamp }`。首条是全量:系统提示的命名节(固定顺序 `preamble → tools → rules → project_context → skills → memory → hooks → cwd → host → role`;`memory` 是第六波的记忆索引节,未开启记忆时不出现)与工具声明表;之后只落**补丁**——节名级替换、值为 `null` 表示删除该节,`toolsAdded` / `toolsRemoved` 增删工具。依次重放得到当前系统提示;请求时由协议层重装:首条非 system 消息之前的部分折进开头,之后的节补丁作为尾部上下文送达、不改写开头(移除工具的补丁除外,见 [providers.md](providers.md)「缓存」)。首条 system 消息在首次请求前落盘,也就是建文件的时刻。
|
|
51
51
|
- `user`:`content`、`origin?`(缺省 = 普通用户输入;`steer` / `followUp` 是运行中插话与排队,`host` 是宿主 `sendUser` 注入,`interrupt` 是打断并立即发送开的新回合(TUI `Ctrl+X`、line 模式 `/interrupt`、RPC / SDK 的 `interrupt: true`;投影与普通 user 消息相同),`direct` 是用户在子 Agent 视图里直接发给该子 Agent 的消息(第六波 W6-A,写在子会话里;投影与普通 user 消息相同),其它字符串原样记录)。
|
|
52
52
|
- `assistant`:`content`(文本 / 思考 / 工具调用块)、`api`、`provider`、`model`、`usage`、`stopReason`,以及可选的 `responseId`、`thinkingLevel`、`providerThinkingLevel`、`rawStopReason`、`errorMessage`。`usage` 是 `{ input, output, cacheRead, cacheWrite, cacheWrite1h?, reasoning?, totalTokens, cost?, cacheReported? }`:`input` 不含缓存部分,`cost` 是 `{ input, output, cacheRead, cacheWrite, total }`(美元,模型无价格时缺省),`cacheReported` 表示原始响应里出现过缓存字段。
|
|
53
53
|
- `toolResult`:对应工具调用的结果(`toolCallId`、`toolName`、`content`、`isError`、`details?`)。
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
|
|
115
115
|
`ama.task`(第五波 W5-G):子会话首条的 `data` 另带 `taskId`、`agent`;父会话在任务开始、每次续聊与结束时各写一条,
|
|
116
116
|
`data` = `TaskInfo`(`taskId, agent, runner, description, background, status, startedAt, endedAt?, turns?, usage?, costUsd?,
|
|
117
|
-
outputFile?, sessionRef
|
|
117
|
+
contextTokens?, contextWindow?, outputFile?, sessionRef?`;`contextTokens / contextWindow` 只有外部 Agent 报告时才有)+ `parentToolCallId`、`cwd`。同一 `taskId` 取分支上最后一条;resume 时据此重建任务注册表,
|
|
118
118
|
`status: "running"` 视为 `interrupted`(`taskId` 续聊重开 `sessionRef.sessionFile`)。没有 `status` 的是子会话自己的首条。
|
|
119
119
|
|
|
120
120
|
第五波登记的类型(docs/wave5-plan.md;括号里是开始写入的批次,之前的版本不会产生,读到未知 `customType` 一律忽略)。`custom_message` 类都是 `display: false`,经扩展点 `beforePrompts` 追加在末尾,不改缓存前缀:
|
|
@@ -129,7 +129,7 @@ outputFile?, sessionRef?`)+ `parentToolCallId`、`cwd`。同一 `taskId` 取
|
|
|
129
129
|
| `ama.post_compact` | (不单独成条) | 回注改为 `compaction.summary` 末尾的 `<post-compact-state>` 块(清单与指针,不含正文;见 `compaction/post-compact.ts`) | 写 compaction 条目时(W5-H1),模型看到「摘要 → 回注 → 保留区」 |
|
|
130
130
|
| `ama.reminder` | `custom_message` | `content`:提醒(todo 复述、外部文件改动、上下文用量、预算余量、后台命令退出),`<system-reminder>` 包起来 | 新提示之前按 `reminders.*` 追加(W5-H2);run 进行中的提醒不单独成条,追加在工具批次最后一条 toolResult 的末尾 |
|
|
131
131
|
| `ama.agent-session` | `custom` | `data: { agent, runner, sessionId, cwd?, taskId? }`:外部 Agent 自己的会话引用(不含原始事件与转录) | 外部 Agent 会话建立 / 续聊时(W5-E) |
|
|
132
|
-
| `ama.agent-usage` | `custom` | `data: { agent, sessionId, unit: usd \| tokens \| requests, amount, tokens? }
|
|
132
|
+
| `ama.agent-usage` | `custom` | `data: { agent, sessionId, unit: usd \| tokens \| requests, amount, tokens?, contextTokens?, contextWindow? }`(上下文只记数字) | 外部 Agent 每个回合结束(W5-E);`SessionStats.external` 据此汇总 |
|
|
133
133
|
|
|
134
134
|
第六波登记的类型(docs/wave6-plan.md §2.2;之前的版本不会产生):
|
|
135
135
|
|
package/docs/sessions.md
CHANGED
|
@@ -55,6 +55,28 @@ packy/deepseek-v4-flash 1 3 1 4.6k 980 2k 0 30.8
|
|
|
55
55
|
- 每个文件的摘要缓存在 `<数据目录>/stats-index.json`,按文件 mtime 与大小失效;时区变化整份作废;扫描全部时顺带删掉已不存在的文件。`--no-cache` 不读也不写。
|
|
56
56
|
- 实测(本机,`src/session/stats-perf.test.ts`):1000 个会话、67 MB(每个 12 回合、24 次工具调用、2 KB 工具结果),冷扫描约 160 ms,命中索引约 15 ms。
|
|
57
57
|
|
|
58
|
+
## 当前会话的上下文用量(`getStats()` / `get_session_stats`)
|
|
59
|
+
|
|
60
|
+
`ama stats` 统计的是历史计费量;正在进行的会话「上下文还剩多少」看 `SessionStats` 的上下文字段(SDK `session.getStats()`、
|
|
61
|
+
RPC `get_session_stats` 原样输出,状态栏与 `/session` 也读它们):
|
|
62
|
+
|
|
63
|
+
| 字段 | 含义 |
|
|
64
|
+
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
65
|
+
| `contextTokens` | 下一次请求要带的上下文 token 估算(口径见 `context.source`) |
|
|
66
|
+
| `contextWindow` | 当前模型的窗口;模型没有窗口信息时**缺省**(`ama models discover` 或在配置里为模型设 `contextWindow` 补上) |
|
|
67
|
+
| `contextPercent` | `contextTokens / contextWindow`,0–100,一位小数,封顶 100;窗口缺省时**缺省**(界面显示 `ctx ?`) |
|
|
68
|
+
| `context.source` | `usage`:最后一条有效助手消息的 usage + 其后消息的估算;`estimate`:没有可信的 usage,按当前上下文全量估算;`prefix`:第一次请求前的基线 |
|
|
69
|
+
| `context.usageTokens` | 来自 usage 的部分;`estimate` / `prefix` 时为 0 |
|
|
70
|
+
| `context.trailingTokens` | 估算的部分(usage 之后的消息,或全量估算 / 基线本身) |
|
|
71
|
+
| `context.autoCompactAt` | 自动摘要(档二)的阈值 = 窗口 − `compaction.reserveTokens`;自动压缩关闭、连续失败熔断或窗口缺省时**缺省** |
|
|
72
|
+
| `context.pruneAt` | 工具结果裁剪(档一)的阈值 = 0.7 ×(窗口 − `reserveTokens`);缺省条件同上 |
|
|
73
|
+
|
|
74
|
+
- **估算口径**:CJK 表意文字 / 假名 / 谚文每字 1 token,其余字符 / 4,图片每张 1 600;usage 取 `totalTokens`(缺则输入 + 输出 + 缓存读写,含输出)。
|
|
75
|
+
- **第一次请求前**(`prefix`):系统提示与工具表要到第一次请求时才写进会话,在此之前按「将要发送的那一份」(命名节文本 + 工具声明 JSON)估算,所以新会话一打开就不是 0。只用于统计,不写会话、不改请求体。
|
|
76
|
+
- **压缩 / 上下文编辑之后**(`estimate`):最后那条 usage 不再代表当前上下文,改为全量估算,直到下一次请求带回新的 usage;界面在数字前加 `≈`。
|
|
77
|
+
- **字段缺省就是「不知道」**,不是 0:`contextWindow`、`contextPercent`、`context.autoCompactAt`、`context.pruneAt` 缺省时 JSON 里没有这个键。旧版本或自定义会话实现可能没有 `context`,按 `contextTokens` 读即可。
|
|
78
|
+
- `tokens`(`{ input, output, cacheRead, cacheWrite, total }`)是**会话累计**计费量,含压缩摘要、保温等不进上下文的请求,不能当上下文用量看。
|
|
79
|
+
|
|
58
80
|
## 检索:`ama sessions search`
|
|
59
81
|
|
|
60
82
|
```
|
|
@@ -160,7 +182,7 @@ ama sessions trace <id|文件> [--html [文件]] [--json] [--output <文件>] [-
|
|
|
160
182
|
- **快照**:新回合开始时 `git add -A` + `write-tree` + `commit-tree`(父为上一个影子提交),提交 id 记进检查点的 `shadowCommit`。影子仓库用固定身份、空的全局 / 系统配置(不读你的签名、钩子、过滤器与模板),`core.autocrlf=false` 且关掉换行转换,存的是磁盘原字节;`gc.auto=0`。
|
|
161
183
|
- **忽略**:工作目录里的 `.gitignore` 生效;工作目录在 git 仓库里时,你的仓库判定为忽略的路径(上级目录的 `.gitignore`、`info/exclude`、全局忽略文件)同样不进影子仓库;`.git` 一律排除。
|
|
162
184
|
- **恢复**:把当前工作目录写成树,与目标提交比较,只处理有差异的文件;冲突与安全检查与 `tools` 相同(符号链接、硬链接、非普通文件、路径上的目录被换成链接都跳过)。「已知」的当前内容 = 最近一个影子快照里的、ama 最后写入的或最近检查点记录的,其余视为回合外的改动,缺省跳过。被忽略的文件不碰;edit / write 改过、但不在影子仓库里的文件(工作目录外、被忽略)按 `tools` 记录恢复。目标检查点没有影子提交(降级之后、或影子仓库已删)时整次按 `tools` 恢复。
|
|
163
|
-
- **护栏**:以下情况本会话降级为 `tools` 并提示一次——PATH 里找不到 `git`;工作目录(不含忽略的)超过 20 000 个文件(第一次快照前检查);单次快照超过 3
|
|
185
|
+
- **护栏**:以下情况本会话降级为 `tools` 并提示一次——PATH 里找不到 `git`;工作目录(不含忽略的)超过 20 000 个文件(第一次快照前检查);单次快照超过 3 秒(这次的提交保留;不含第一次建影子仓库的时间)。工作目录是家目录或文件系统根目录时不启用。
|
|
164
186
|
- **限制**:
|
|
165
187
|
- 最近一个回合里 bash 的改动要到下一个回合开始才进快照;在那之前回滚,这些改动与手动修改分不开,算冲突(可选择覆盖)。
|
|
166
188
|
- git 只记可执行位:恢复时只调整可执行位,其它权限位保留;符号链接与子模块不恢复。
|
package/docs/tui-design.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 适用:`src/tui/**`(组件库)与 `src/modes/interactive/**`(交互模式)。基线 main 217017c。
|
|
4
4
|
> 约束不变:主屏模式(不用备用屏,历史进终端回滚,tmux `capture-pane` 可读)、差分渲染、运行时零依赖、`NO_COLOR` / 16 / 256 / truecolor 降级、40 列可用、中文宽字符正确、Windows Terminal 可用、括号粘贴。
|
|
5
|
-
>
|
|
5
|
+
> 吸收终端 Agent 的常见设计:组件模型、主题 JSON 的角色划分,以及视觉语言(`›` 输入、`⏺` / `⎿` 工具层级、spinner 动词、底部模式提示、编号审批)。
|
|
6
6
|
|
|
7
7
|
## 0. 现状诊断(对照 test/fixtures/tui/*.txt)
|
|
8
8
|
|
|
@@ -480,7 +480,7 @@ tmux 节点里宿主要解析最后一行:嵌入缺省 `compact`,字段顺
|
|
|
480
480
|
|
|
481
481
|
- 标题由原因决定:`需要确认`(mode)/ `危险命令`(dangerous)/ `Hook 要求确认`;来源标注见下文「来源标注」(第五波 W5-U)。边框颜色随预览严重度:danger `error`、warn `warning`、其余 `border`。
|
|
482
482
|
- 工具名 `tool` 粗体,原因标签 `error` / `warning` / `dim`;命令 `code`;预览行按严重度着色(现有);Auto 判定行 `warning`。
|
|
483
|
-
-
|
|
483
|
+
- 选项编号列表:选中行 `›` + `selection` bg;右侧按键提示 `dim`。缺省选中:dangerous → 拒绝;其余 → 允许。按键 `y / a / n / Esc / 1 2 3 / ↑↓ Enter / v` 全部有效(旧按键不废)。edit / write 的输入摘要(`−/+` 摘要、`写入 N 行`、本会话未读过标黄)保留。
|
|
484
484
|
- 覆盖层仍为 `bottom` 锚定全宽;对话框打开时输入框提示符变 `dim`,Loader 动词 `等待确认`。
|
|
485
485
|
|
|
486
486
|
40 列:
|
package/docs/tui.md
CHANGED
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
────────────────────────────────────────────────
|
|
34
34
|
› 输入消息,/ 命令,@ 文件,Shift+Enter 换行 ← 输入框(占位)
|
|
35
35
|
────────────────────────────────────────────────
|
|
36
|
-
codemode on tps: 100 tok/s • 546 tok / 5.5s (avg 100 · ttft 1.4s) ·
|
|
37
|
-
Accept edits | shift+tab 切换 claude-opus-5-5 medium | Ctx 3.0% | proj ⎇ main 5ae9e54 ↑2 (+12,-3) | $0.26 | 2h24m
|
|
36
|
+
codemode on tps: 100 tok/s • 546 tok / 5.5s (avg 100 · ttft 1.4s) · Σ↑12k ↓1.2k R9.6k · cache 80% ♨ · [-] ← 速率行(full)
|
|
37
|
+
Accept edits | shift+tab 切换 claude-opus-5-5 medium | Ctx 3.0% 8.2k/272k auto | proj ⎇ main 5ae9e54 ↑2 (+12,-3) | $0.26 | 2h24m
|
|
38
38
|
5 小时:10.0% | 重置:2h 18m | 本周:31.0% | 本周重置:6d 5h ← 订阅配额行(full,ChatGPT 订阅模型)
|
|
39
39
|
```
|
|
40
40
|
|
|
@@ -44,16 +44,17 @@ Accept edits | shift+tab 切换 claude-opus-5-5 medium | Ctx 3.0% | proj ⎇
|
|
|
44
44
|
- **提示**:`✗` 错误、`↻ 重试 n/m`、`!` 警告(缓存未命中、上下文余量)、`⛔ Hook 阻止`、宿主通知、审批被拒或超时的说明;压缩 / 分支摘要是左竖条卡片(`▎ 上下文已压缩 128k → 24k token`)。
|
|
45
45
|
- **运行中**:`⠋ 动词 · 已用时 · …`,动词按当前最深状态取:`等待确认`(审批打开)、`运行 bash` / `运行 3 个工具`、`重试 2/3 · 2s 后`、`压缩上下文`、`回复中 · ↓≈1.2k`(本条输出的估算 token)、`思考中`。有阻塞中的前台子 Agent 任务时加 `Ctrl+B 转后台`,Agent 栏里有任务时加 `↓ Agent 栏`(有停靠的审批时换成 `↓ 处理审批`):`⠏ 运行 task · 4s · Esc 中断 · Ctrl+B 转后台 · ↓ Agent 栏`,一行放不下时从后往前整项丢掉。输入框有字时最前面加 `Enter 排队 · Ctrl+X 打断并发送`(`ui.enterWhileRunning: "interrupt"` 时是 `Enter 打断并发送 · Ctrl+X 排队`);有排队的插话时队列末行是 `Alt+↑ 取回 · Ctrl+X 立即发送 · Esc 回填并中断`。
|
|
46
46
|
- **状态栏**:模式永远在最左;`full` 左右分区——左列是状态与开关(权限模式、`shift+tab` 提示、codemode、沙箱、预设、回退),右列是度量与模型(tps、用量、模型、Ctx、git、费用、时长、配额),右列右对齐、左列为空时整行靠右;除 full 布局下的订阅配额行外,状态栏是最后一行(`compact` 永远是最后一行)。`compact` 的分隔符固定为 `·`(嵌入宿主按此解析),`full` 用 `|`。布局由 `ui.statusLine` 决定:独立终端缺省 `full`(两行),有 profile 的嵌入宿主缺省 `compact`(一行,布局与以前相同);运行时 `Ctrl+G` 或 `/statusline [full|compact]` 切换,只影响本会话。`full` 时输入框在倒数第 4 行(`compact` 仍是倒数第 3 行)。
|
|
47
|
-
- **`full` 上行(速率行)**:左区是开关类项 `codemode on|only`(网络未隔离时追加 `net!`)· `沙箱` · `preset <名>`(非 default 时)· `→ <回退模型>`(回退中,黄色)· 排队数 · 宿主状态,没有时左区为空。右区 `tps: <速率> tok/s • <输出 token> tok / <耗时> (avg <会话均速> · ttft <首 token 延迟>) ·
|
|
48
|
-
- **`full` 下行**:左区 `权限模式 | shift+tab 切换`,右区 `模型 思考级别 | Ctx 3.0% | <目录名> ⎇ <分支> <短提交> ↑N ↓N (+a,-d) | $费用 | 会话时长`(Ctx
|
|
47
|
+
- **`full` 上行(速率行)**:左区是开关类项 `codemode on|only`(网络未隔离时追加 `net!`)· `沙箱` · `preset <名>`(非 default 时)· `→ <回退模型>`(回退中,黄色)· 排队数 · 宿主状态,没有时左区为空。右区 `tps: <速率> tok/s • <输出 token> tok / <耗时> (avg <会话均速> · ttft <首 token 延迟>) · Σ↑<输入> ↓<输出> R<缓存读> W<缓存写> · 缓存 · 重计费 · [-]`——速率在流式中是最近 2 s 的瞬时值(`tps:` 强调色),结束后是该请求的平均值,生成不足 0.25 s 的整块回复不算速率、显示 `—`;耗时从首 token 起;`Σ` 表示**会话累计**计费量(不是上下文占用),`↑` 输入含缓存读写,其中缓存读 / 写另列为 `R` / `W`(为 0 不显示,ASCII 下 `Σ` 为 `sum `);ASCII 下 `•` 为 `*`、`→` 为 `->`;行尾 `[-]` 提示可折叠。只统计对话请求(压缩摘要、保温、分类器不计)。窄时先丢右区度量(输出量 / 耗时、token、缓存、重计费、avg、ttft),再丢左区开关(宿主状态、排队数、预设、回退、沙箱、codemode);`tps` 与 `[-]` 不丢。
|
|
48
|
+
- **`full` 下行**:左区 `权限模式 | shift+tab 切换`,右区 `模型 思考级别 | Ctx 3.0% 8.2k/272k auto | <目录名> ⎇ <分支> <短提交> ↑N ↓N (+a,-d) | $费用 | 会话时长`(Ctx 一位小数,宽屏也不换余量表)。Ctx 段是当前上下文:百分比、已用量 / 窗口,`auto` 表示自动压缩开着(关闭、连续失败熔断或窗口未知时不显示);数字不是来自模型回传的 usage 时前面加 `≈`(第一次请求前按系统提示 + 工具声明估算的基线,或压缩之后、下一次请求之前的全量估算),窗口未知时是 `Ctx ? 8.2k`。窄时依次丢弃 `auto`、切换提示、思考级别、`/窗口`、增删行、目录名、分支与提交、已用量、时长、费用、上下文百分比、模型。
|
|
49
49
|
- **订阅配额行**(`full` 第三行,在状态栏下方):当前模型走 ChatGPT 订阅(`chatgpt` 供应商)时显示 `5 小时:<已用%> | 重置:<距重置> | 本周:<已用%> | 本周重置:<距重置>`(英文界面 `Session: … | Reset: … | Weekly: … | Weekly Reset: …`),数据来自最近一次 `quota_update`(codex 方式的 `x-codex-primary/secondary-*` 响应头与 `codex.rate_limits` 事件;siwc 只有超限 429 时才有)。重置时间是相对时长(`2h 18m`、`6d 5h`),每分钟刷新一次。codex 方式在第一次请求前显示「配额:首次请求后显示」(第一次请求就会带回配额,先占住行免得行数跳动);siwc 没有数据时不占行(只有超限才有配额,占位会一直挂着);非订阅模型不显示。窄于 80 列时压缩为 `5h 10% ↻2h18m · 周 31% ↻6d5h`,再窄先丢重置时间。配额行在右区右对齐。标签按窗口时长认而不是按 primary / secondary 槽位:300 分钟是「5 小时」、10080 分钟是「本周」,其它时长用实际时长(`1d:`);缺时长时 primary 当 5 小时、secondary 当本周(与另一个窗口撞名时取另一种);按时长从短到长排。用量 0、无时长、无重置时间的窗口是服务端的「没有这个窗口」,不显示(有的套餐 codex 只送一个周窗口,放在 primary)。`Ctrl+G` / `/statusline compact` 折叠时配额行与速率行一起收起(`compact` 只保留一行,宿主按「最后一行 = 状态栏」锚定)。
|
|
50
|
-
- **配色**(`full`):标签、单位、分隔符与括号暗灰;速率数字紫、输出量 / 耗时 / avg 蓝、ttft 紫;模型与思考级别蓝;Ctx
|
|
50
|
+
- **配色**(`full`):标签、单位、分隔符与括号暗灰;速率数字紫、输出量 / 耗时 / avg 蓝、ttft 紫;模型与思考级别蓝;Ctx 按阈值绿 / 黄 / 红(越过档一裁剪阈值即黄——0.7 ×(窗口 − 预留),比 70% 略低;≥ 90% 红;没有阈值时 ≥ 70% 黄),配额百分比 ≥ 70% 黄、≥ 90% 红;目录与分支绿、短提交暗灰、`↑N` 领先橙、`↓N` 落后红、`(+a,-d)` 绿 / 红;费用黄;时长与重置时间紫。都取主题语义色,深 / 浅主题与 16 色各有对应;`NO_COLOR` 与 ASCII 不着色、结构不变。`compact` 的着色不变。
|
|
51
51
|
- **`compact`**:一行,右区 模型 · 思考级别 · `↑ ↓` · 缓存 · 费用 · 重计费 · 上下文占用 · 目录 ⎇ 分支 提交 +a −b · 会话时长 · 排队数 · codemode · 预设 · 宿主状态 · 订阅配额短项(`5h 10% 周 31%`,只在有配额数据时;项内不含 `·`);窄时依次丢弃配额短项、切换提示、宿主状态、预设、重计费、费用、缓存、token、思考级别、排队数、codemode、增删行、目录名、分支与提交、时长、上下文、模型。
|
|
52
52
|
- **git**:分支与短提交直接读 `.git/HEAD`(worktree 认;detached 只显示短提交;非 git 目录整段省略,只剩目录名);`+a −b` 是工作区(含暂存)相对 HEAD 的增删行,回合结束、写类工具结束、回滚、`/tree` 之后在后台跑 `git diff --numstat HEAD`,至多 10 秒一次,超过 2 秒或失败就本会话不再显示增删;`AMA_STATUS_GIT=0` 关闭。`full` 的 `↑N` / `↓N` 是当前分支领先 / 落后上游的提交数:分支在 git 配置里有上游(`branch.<名>.merge`)时,同一节流周期接着跑 `git rev-list --left-right --count @{upstream}...HEAD`(同样 2 秒超时,超时本会话不再统计);为 0、没有上游或 detached 不显示;ASCII 下为 `^N` / `vN`。
|
|
53
53
|
- **费用**含子任务、保温、分类器与外部 Agent 以美元计的用量(其它单位只在 `/session`);**时长**从本进程打开当前会话起算(`Ns` / `Nm` / `NhMm`)。
|
|
54
54
|
- bash 命令在操作系统沙箱里跑时(`sandbox.bash: "auto"` 且本机可用,见 [sandbox.md](sandbox.md))用量类项多一个 `沙箱`,宽度不够时与 codemode 一起先丢。
|
|
55
55
|
- 模型回退中(`fallbackModel`,主模型过载或重试用尽后改用回退模型重试一次)`compact` 的模型项显示 `主模型 → 回退模型`(回退模型黄色),`full` 的模型项只留主模型、速率行左区显示 `→ 回退模型`,回退模型回复、切回主模型后消失;消息区同时有一行说明。
|
|
56
|
-
-
|
|
56
|
+
- **上下文的刷新**:提交消息后立刻更新(新消息按估算计入);流式中回复带回 usage(有的协议在开头就给输入量)时按每秒至多 2 次换成在途请求的实测值;回复结束、压缩、换模型后回到统计值。
|
|
57
|
+
- 模型名随宽度缩写(< 100 列去供应商、< 60 去渠道、< 48 去版本后缀);`compact` ≥ 110 列时上下文显示为余量表 `ctx ▮▮▮▯▯▯▯▯▯▯ 34%`,占用 < 1% 时保留一位小数(`ctx ≈0.4%`,不显示成 0%),估算值同样带 `≈`;会变的数字按最宽形状占位,数值变化不会让某项时有时无。ASCII 模式 `⎇` → `git`、`−` → `-`、`♨` → `~`、`↻` → `@`。
|
|
57
58
|
- **退出**:消息区最后追加一行会话摘要与恢复命令,留在终端回滚里:
|
|
58
59
|
|
|
59
60
|
```
|
|
@@ -72,7 +73,7 @@ Accept edits | shift+tab 切换 claude-opus-5-5 medium | Ctx 3.0% | proj ⎇
|
|
|
72
73
|
| `cache 未报告` | 端点不报缓存(`silent`:连续 3 个可比请求读写都是 0,或 `compat.cacheReporting: "silent"`);这类请求不进命中率分母 |
|
|
73
74
|
| `♨` | 保温计时中(工具长时间运行时按 TTL 重放前缀,`/cache warm` 可切换) |
|
|
74
75
|
| `rebill $0.11` | 本会话缓存未命中导致的重计费金额;模型没有价格时显示 token 数;为 0 不显示 |
|
|
75
|
-
| `ctx 72%` |
|
|
76
|
+
| `ctx 72%` | 上下文占用,越过档一裁剪阈值黄色、≥ 90% 红色;`≈` 为估算值;`ctx ?` 为模型没有窗口信息 |
|
|
76
77
|
| `codemode only` | codemode 生效(`on` / `only`);网络未隔离(Node 22 / 24 且没有操作系统沙箱,见 sandbox.md)时追加红色 `net!` |
|
|
77
78
|
|
|
78
79
|
消息区(line 模式写 stderr,前缀 `ama: `)只在两种情况下提示一行,`cache.missNotices: false` 可关:
|
|
@@ -85,10 +86,10 @@ Accept edits | shift+tab 切换 claude-opus-5-5 medium | Ctx 3.0% | proj ⎇
|
|
|
85
86
|
|
|
86
87
|
```
|
|
87
88
|
▎ 会话 3f2a9c1e ~/.local/share/ama/sessions/…/3f2a9c1e.jsonl
|
|
88
|
-
▎ 模型
|
|
89
|
-
▎ 消息
|
|
90
|
-
▎
|
|
91
|
-
▎ 上下文
|
|
89
|
+
▎ 模型 anthropic/claude-sonnet-4-5 · 思考 medium · 权限 Accept edits
|
|
90
|
+
▎ 消息 用户 7 · 助手 9 · 工具调用 23
|
|
91
|
+
▎ 累计用量 输入 3.4k · 输出 9.4k · 缓存读 118k · 缓存写 6.2k · $0.42
|
|
92
|
+
▎ 上下文 ▮▮▮▯▯▯▯▯▯▯ 34% · 68k / 200k · 距自动压缩 ≈ 116k
|
|
92
93
|
▎
|
|
93
94
|
▎ 缓存
|
|
94
95
|
▎ 输入 3.4k = 缓存读 2.2k(65%)+ 未缓存 1.2k
|
|
@@ -213,6 +214,38 @@ line 模式(`--no-tui`)运行中输入 `/interrupt <文本>` 效果相同(
|
|
|
213
214
|
- `/plan`:当前计划面板(见下文「Plan 审批」);`/plan <目标>` 进入 Plan 模式并发出目标;`/plan approve [模式|fresh]`、`/plan reject` 不开对话框直接批准 / 放弃。
|
|
214
215
|
- `/tasks`:聚焦 Agent 栏,`/tasks <id>` 打开子 Agent 视图;`/agents`:可用的子 Agent 类型(见下文「子 Agent」)。
|
|
215
216
|
- `/paste`:同 `Ctrl+V`。
|
|
217
|
+
- `/context`:上下文按类别的明细面板(见下一节)。
|
|
218
|
+
|
|
219
|
+
### /context
|
|
220
|
+
|
|
221
|
+
`/context` 回答「上下文被什么占着」。交互模式画左竖条面板,line 模式与无面板时是同样内容的纯文本:
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
▎ 上下文
|
|
225
|
+
▎ 已用 10.6k / 200k(5.3%)
|
|
226
|
+
▎ 剩余 189k token
|
|
227
|
+
▎ 来源 usage 实测 9k + 估算 1.6k
|
|
228
|
+
▎ 自动压缩 184k 触发,还差 ≈ 173k
|
|
229
|
+
▎ 裁剪 超过 129k 时清理旧工具结果
|
|
230
|
+
▎
|
|
231
|
+
▎ 按类别(估算,5.8k)
|
|
232
|
+
▎ 系统提示与工具声明按会话里存的 system 消息计入;全量估算可能与 usage 实测不同。
|
|
233
|
+
▎ 系统提示 600 ▮▯▯▯▯▯▯▯▯▯ 10% rules 500 · preamble 100 · cwd 0
|
|
234
|
+
▎ 工具声明 333 ▮▯▯▯▯▯▯▯▯▯ 6% bash 241 · read 91
|
|
235
|
+
▎ …
|
|
236
|
+
▎ 工具结果 3.2k ▮▮▮▮▮▯▯▯▯▯ 55% read 3k · bash 203
|
|
237
|
+
▎ 附件图片 1.6k ▮▮▮▯▯▯▯▯▯▯ 27% 1 张 · 用户 1.6k
|
|
238
|
+
▎
|
|
239
|
+
▎ 最大的工具结果(前 5)
|
|
240
|
+
▎ #1 3k read
|
|
241
|
+
▎ #2 203 bash
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
- **顶部**:已用 / 窗口与百分比(与 `/session` 同一口径:最后一条可用 usage + 其后消息的估算)、剩余、来源(「usage 实测 X + 估算 Y」;还没有可用 usage,或 usage 之后发生过压缩 / 上下文编辑时为「全量估算」)、自动压缩触发点(窗口 − `compaction.reserveTokens`,关闭时显示「关闭」,没有窗口时「窗口未知」)与档一裁剪的起点。
|
|
245
|
+
- **按类别**:系统提示(按节)、工具声明(按工具)、用户消息、助手文本、推理、工具调用参数(按工具)、工具结果(按工具名汇总)、附件图片(每张按 1 600 计)、摘要(压缩 / 分支)、自定义消息;每类给 token 估算、占比与条形。各类之和等于整个投影的字符估算(CJK 每字 1,其余 / 4),所以标题里的合计可能与顶部的「已用」不同——后者优先采信模型回报的 usage。
|
|
246
|
+
- **系统提示与工具声明**来自会话里存的 system 消息(首条全量、之后的补丁也计入,与估算口径一致);首次请求前分支上还没有 system 消息,这两类为 0,面板注明「首次请求后才计入」。
|
|
247
|
+
- **底部**只列最大的 5 个工具结果的序号(投影里第几个工具结果)、工具名与大小,**不显示正文**。
|
|
248
|
+
- 统计只读:不写会话条目、不改请求体,提示词缓存前缀不受影响。
|
|
216
249
|
|
|
217
250
|
## 进入 Bypass
|
|
218
251
|
|
|
@@ -456,10 +489,33 @@ t2 explore · 运行中 1m05s · 3 轮 · ↑12k ↓3.4k · Esc 返回 · /tasks
|
|
|
456
489
|
|
|
457
490
|
`ui.quietStartup` / `--quiet-startup`:`normal` 显示「AMA」字符画与信息列——版本、模型与思考级别、目录(`~` 缩写)与信任状态、权限模式 / 预设 / codemode、已加载的上下文文件 / Skill / 提示模板 / Hook、警告数与常用按键;宽 ≥ 72 列字符画在左、信息在右,48–71 列字符画在上,窄于 48 列退回两行简洁头(版本 · 模型 · 思考 / 模式 · 目录 · 信任);`ui.logo: "off"` 或 `ui.compact` 只显示信息列。字符画按字母取主题的 accent → user → tool 三色,ASCII 模式换成 `_ / \ |` 拼的字形。启动时播放一次约 1 秒的「点亮」扫描(字形先暗后亮,高亮带从左扫到右,结束定格),只在原地重画、不在回滚里留帧;按任意键立即定格,按键照常进入输入框。以下情况直接显示定格帧:`ui.animation: false`、`NO_COLOR` / 无色终端、非 TTY、嵌入宿主(profile.host)、`CI` 环境、启动即带提示(`ama "…"`)、终端矮于 16 行或内容超出一屏;行式界面、`-p`、RPC、ACP 不画启动头。`header` 只有一行 `✻ ama 版本 · 模型 · 模式 · /help`(profile 缺省);`silent` 不显示。`--resume` 不带 id、模型没有 key、会话目录不存在、项目资源需要信任时,界面启动前会先出现一个小的选择 / 输入提示,答完收成一行留在屏幕上。
|
|
458
491
|
|
|
492
|
+
## 终端程序状态(OSC 7501)
|
|
493
|
+
|
|
494
|
+
交互界面用 [OSC 7501 程序状态协议](https://www.superlogical.com/rex/docs/build/program-status)(rev 0.3)把运行状态报告给终端,支持的终端可以在标签页、侧栏或通知里显示「在跑 / 等你确认 / 完成 / 出错」。报告固定带 `app=ama`;每次报告整体替换该记录。
|
|
495
|
+
|
|
496
|
+
| 时机 | 根记录 |
|
|
497
|
+
| ------------------------------------------ | ---------------------------------------------------------------------------------------------- |
|
|
498
|
+
| 启动、切换会话(`/new` `/resume` `/fork`) | `idle` |
|
|
499
|
+
| 回合开始 | `working`,msg 是当前活动(思考中 / 回复中 / 运行 bash / 压缩上下文,节流 500 ms、同值不重发) |
|
|
500
|
+
| 出现待人处理的审批(含子 Agent 发起的) | `blocked` `kind=permission`,msg 是「工具 · 目标」 |
|
|
501
|
+
| 计划待审批 | `blocked` `kind=question` |
|
|
502
|
+
| 回合因登录失效失败(`auth_expired`) | `blocked` `kind=auth`,msg 是错误首行;下一回合开始或换模型时解除 |
|
|
503
|
+
| 审批 / 计划处理完 | 回到 `working`(或回合结束后的状态) |
|
|
504
|
+
| 回合正常结束 | `done`;之后在 ama 里按任意键回到 `idle` |
|
|
505
|
+
| 回合出错 | `error`,msg 是错误首行 |
|
|
506
|
+
| 用户中断(Esc 等) | `idle` |
|
|
507
|
+
| 退出交互模式 | 不带 id 的 `clear`(清掉本程序的全部记录) |
|
|
508
|
+
|
|
509
|
+
- 子 Agent 任务另有子记录 `id=task/<短 id>`、title 为任务描述:`working`(msg 是正在用的工具)→ 审批时 `blocked` → 结束时 `done`,失败 / 到达回合上限为 `error`,被中断为 `idle`;下一个主回合开始时清掉已结束的任务记录。
|
|
510
|
+
- 退出用 `clear` 而不是 `done`:用户主动退出时结果已经在屏幕上,留一条「完成」记录只是噪声。
|
|
511
|
+
- `ui.programStatus`:`auto`(缺省)启动时发 `OSC 7501 ; ?` 与 `CSI c`(DA1),先收到 `?` 回复才发报告,DA1 先到或 300 ms 内没有回复就不发;两种回复(含迟到的)都在输入解析里吞掉,不会进输入框。`on` 不检测直接发(规范允许:不认识的 OSC 合规终端会忽略)。`off` 不发也不检测。改动重启生效。
|
|
512
|
+
- tmux:缺省丢弃不认识的 OSC,规范也没覆盖多路复用器。tmux 不把外层终端对透传查询的回复转给窗格,检测不可靠,所以 tmux 里 `auto` 等同 `off`;要用就设 `on`,并在 tmux 里 `set -g allow-passthrough on`,报告会用 DCS passthrough(`ESC P tmux; … ESC \`)包裹。
|
|
513
|
+
- 只用于交互界面。`-p`、RPC、ACP 的 stdout 是数据或协议,不发;`-p` 即使 stderr 是终端也不发——它是一次性进程,结果看退出码,退出后新提示符本来就会丢掉 working 记录,留下 done / error 对脚本化调用只是噪声。
|
|
514
|
+
|
|
459
515
|
## 在 tmux / Armadra 终端节点里
|
|
460
516
|
|
|
461
517
|
- 括号粘贴:启动时开启;粘贴的多行内容整体进入输入框(超过 10 行或 1 000 字符折叠为 `[粘贴 #N · M 行]`),粘贴后紧跟的回车直接发送,适合由外部程序写入。
|
|
462
|
-
-
|
|
518
|
+
- 除程序状态检测(见上一节,tmux 里不检测)外不查询终端能力、不开鼠标与 Kitty 键盘协议,避免回包混进输入;tmux ≥ 3.4 透传同步输出,旧版本也能正常显示。
|
|
463
519
|
- tmux 的缺省前缀 `C-b` 会被 tmux 客户端吃掉:转后台按 `C-b C-b`(`send-prefix` 透传),或 `↓` 进 Agent 栏按 `b`;进栏用 `↓`,不受前缀影响。
|
|
464
520
|
- 窗口尺寸变化时整屏重画最后一屏,回滚里的历史不受影响。
|
|
465
521
|
- 自动降级:非 TTY、`TERM=dumb`、`--no-tui` 或终端初始化失败时使用行式界面,命令与审批问答相同。
|
|
@@ -468,16 +524,17 @@ t2 explore · 运行中 1m05s · 3 轮 · ↑12k ↓3.4k · Esc 返回 · /tasks
|
|
|
468
524
|
|
|
469
525
|
`config.json` 的 `ui` 段(项目级也可设):
|
|
470
526
|
|
|
471
|
-
| 键
|
|
472
|
-
|
|
|
473
|
-
| `ui.theme`
|
|
474
|
-
| `ui.ascii`
|
|
475
|
-
| `ui.compact`
|
|
476
|
-
| `ui.logo`
|
|
477
|
-
| `ui.animation`
|
|
478
|
-
| `ui.markdown`
|
|
479
|
-
| `ui.showThinking`
|
|
480
|
-
| `ui.quietStartup`
|
|
527
|
+
| 键 | 缺省 | 作用 |
|
|
528
|
+
| ------------------ | ----------- | --------------------------------------------------------------------------------------------- |
|
|
529
|
+
| `ui.theme` | `dark` | `dark` / `light` / `auto`;auto 只看 `COLORFGBG`(不发终端查询),猜不出用 dark,建议显式配置 |
|
|
530
|
+
| `ui.ascii` | 自动检测 | ASCII 字形(`›` → `>`、`⏺` → `*`、`⎿` → `L`、框线 → `+ - \|`、spinner 4 帧) |
|
|
531
|
+
| `ui.compact` | `false` | 消息区块间不空行、启动头不画字符画 |
|
|
532
|
+
| `ui.logo` | `auto` | 启动头的「AMA」字符画;`off` 只显示信息列 |
|
|
533
|
+
| `ui.animation` | `true` | `false`:运行中 spinner 静止为 `·`,只在秒数变化时重绘;启动字符画不播放动画 |
|
|
534
|
+
| `ui.markdown` | `true` | `false`:助手正文不做 Markdown 渲染 |
|
|
535
|
+
| `ui.showThinking` | `collapsed` | 见「布局」 |
|
|
536
|
+
| `ui.quietStartup` | `normal` | 见「启动画面」 |
|
|
537
|
+
| `ui.programStatus` | `auto` | 终端程序状态 OSC 7501:`auto` / `on` / `off`,见「终端程序状态」 |
|
|
481
538
|
|
|
482
539
|
- **ASCII 模式**:`AMA_ASCII=1`(或 `ui.ascii: true`)强制开启,`AMA_ASCII=0` 强制关闭;自动检测在区域设置(`LC_ALL` > `LC_CTYPE` > `LANG`)已设置但不含 UTF-8、`TERM=linux`、Windows 上既没有 `WT_SESSION` 也没有 `TERM_PROGRAM`(旧 conhost)时开启。Windows Terminal 走 Unicode。
|
|
483
540
|
- **字符错位**:`⏺`(U+23FA)、`⎿`、`▎` 在个别字体(尤其 emoji 回退字体)下画成两格,宽度计算按 wcwidth(一格),会出现列错位或残影——换等宽字体或设 `AMA_ASCII=1`。
|