@pentoshi/clai 4.0.3 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +31 -9
  2. package/dist/agent/confirm-port.js +6 -3
  3. package/dist/agent/confirm-port.js.map +1 -1
  4. package/dist/agent/runner.js +3 -3
  5. package/dist/agent/runner.js.map +1 -1
  6. package/dist/agent/turn-outcome.d.ts +1 -1
  7. package/dist/agent/turn-outcome.js +2 -12
  8. package/dist/agent/turn-outcome.js.map +1 -1
  9. package/dist/app/commands/catalog.js +0 -17
  10. package/dist/app/commands/catalog.js.map +1 -1
  11. package/dist/app/controllers/session-controller.d.ts +2 -0
  12. package/dist/app/controllers/session-controller.js +26 -2
  13. package/dist/app/controllers/session-controller.js.map +1 -1
  14. package/dist/app/controllers/turn-continuation.d.ts +0 -6
  15. package/dist/app/controllers/turn-continuation.js +4 -21
  16. package/dist/app/controllers/turn-continuation.js.map +1 -1
  17. package/dist/app/ports/transcript-item.d.ts +9 -1
  18. package/dist/classic/app/ClassicApp.js +1 -2
  19. package/dist/classic/app/ClassicApp.js.map +1 -1
  20. package/dist/classic/app/wiring-interactions.js +2 -2
  21. package/dist/classic/app/wiring-interactions.js.map +1 -1
  22. package/dist/classic/blocks/TurnSummaryBlock.d.ts +3 -0
  23. package/dist/classic/blocks/TurnSummaryBlock.js +6 -0
  24. package/dist/classic/blocks/TurnSummaryBlock.js.map +1 -0
  25. package/dist/classic/blocks/turn-summary-lines.d.ts +3 -0
  26. package/dist/classic/blocks/turn-summary-lines.js +7 -0
  27. package/dist/classic/blocks/turn-summary-lines.js.map +1 -0
  28. package/dist/classic/chrome/status-rows.d.ts +0 -1
  29. package/dist/classic/chrome/status-rows.js +0 -12
  30. package/dist/classic/chrome/status-rows.js.map +1 -1
  31. package/dist/classic/feed/Feed.js +2 -0
  32. package/dist/classic/feed/Feed.js.map +1 -1
  33. package/dist/classic/feed/feed-blocks.d.ts +1 -1
  34. package/dist/classic/feed/feed-blocks.js +3 -0
  35. package/dist/classic/feed/feed-blocks.js.map +1 -1
  36. package/dist/llm/capabilities.js +9 -1
  37. package/dist/llm/capabilities.js.map +1 -1
  38. package/dist/llm/fireworks.d.ts +3 -0
  39. package/dist/llm/fireworks.js +99 -0
  40. package/dist/llm/fireworks.js.map +1 -0
  41. package/dist/llm/hetzner.d.ts +3 -0
  42. package/dist/llm/hetzner.js +94 -0
  43. package/dist/llm/hetzner.js.map +1 -0
  44. package/dist/llm/http.d.ts +11 -0
  45. package/dist/llm/http.js +48 -3
  46. package/dist/llm/http.js.map +1 -1
  47. package/dist/llm/meta.js +59 -0
  48. package/dist/llm/meta.js.map +1 -1
  49. package/dist/llm/provider.js +131 -21
  50. package/dist/llm/provider.js.map +1 -1
  51. package/dist/llm/router.js +58 -28
  52. package/dist/llm/router.js.map +1 -1
  53. package/dist/llm/tokenrouter.js +6 -5
  54. package/dist/llm/tokenrouter.js.map +1 -1
  55. package/dist/store/config.js +2 -0
  56. package/dist/store/config.js.map +1 -1
  57. package/dist/tools/fs.d.ts +5 -3
  58. package/dist/tools/fs.js +8 -5
  59. package/dist/tools/fs.js.map +1 -1
  60. package/dist/tui-v2/components/plan/plan-view.js +5 -3
  61. package/dist/tui-v2/components/plan/plan-view.js.map +1 -1
  62. package/dist/tui-v2/components/status/status-line.js +1 -14
  63. package/dist/tui-v2/components/status/status-line.js.map +1 -1
  64. package/dist/tui-v2/components/transcript/notice-row.d.ts +3 -1
  65. package/dist/tui-v2/components/transcript/notice-row.js +28 -3
  66. package/dist/tui-v2/components/transcript/notice-row.js.map +1 -1
  67. package/dist/tui-v2/components/transcript/thinking-block.d.ts +0 -5
  68. package/dist/tui-v2/components/transcript/thinking-block.js +3 -8
  69. package/dist/tui-v2/components/transcript/thinking-block.js.map +1 -1
  70. package/dist/tui-v2/components/transcript/tool-card.js +16 -7
  71. package/dist/tui-v2/components/transcript/tool-card.js.map +1 -1
  72. package/dist/tui-v2/components/transcript/transcript-row.d.ts +0 -2
  73. package/dist/tui-v2/components/transcript/transcript-row.js +7 -3
  74. package/dist/tui-v2/components/transcript/transcript-row.js.map +1 -1
  75. package/dist/tui-v2/components/transcript/transcript-view.js +1 -3
  76. package/dist/tui-v2/components/transcript/transcript-view.js.map +1 -1
  77. package/dist/types.d.ts +1 -1
  78. package/dist/types.js +2 -0
  79. package/dist/types.js.map +1 -1
  80. package/dist/ui-core/rendering/duration.d.ts +4 -0
  81. package/dist/ui-core/rendering/duration.js +35 -0
  82. package/dist/ui-core/rendering/duration.js.map +1 -0
  83. package/dist/ui-core/rendering/transcript-semantic.js +2 -0
  84. package/dist/ui-core/rendering/transcript-semantic.js.map +1 -1
  85. package/dist/ui-core/state/transcript-compaction.js +2 -0
  86. package/dist/ui-core/state/transcript-compaction.js.map +1 -1
  87. package/dist/ui-core/state/transcript-hydrate.js +31 -1
  88. package/dist/ui-core/state/transcript-hydrate.js.map +1 -1
  89. package/dist/ui-core/state/transcript-reducer.js +20 -5
  90. package/dist/ui-core/state/transcript-reducer.js.map +1 -1
  91. package/dist/ui-core/state/transcript-types.d.ts +7 -1
  92. package/dist/ui-core/state/transcript-types.js +3 -1
  93. package/dist/ui-core/state/transcript-types.js.map +1 -1
  94. package/dist/version.generated.d.ts +2 -2
  95. package/dist/version.generated.js +2 -2
  96. package/package.json +1 -1
package/README.md CHANGED
@@ -6,14 +6,14 @@
6
6
 
7
7
  Two things make it practical for everyday use:
8
8
 
9
- - **It's cheap-to-free to run.** A fresh install runs **keyless out of the box** on the built-in Free provider — no signup, no API key. Point it at Groq, Google Gemini, NVIDIA NIM, OpenRouter, Bynara, Kimchi, or a local Ollama — all have free access — and clai stacks them. Add several keys per provider; when one hits a rate limit, it rotates to the next automatically. Want frontier models instead? Serve **Kimi K3 on your own Modal endpoint** on Modal's **$30/month of free credit**, or start on **Lightning AI's 40M free tokens**.
9
+ - **It's cheap-to-free to run.** A fresh install runs **keyless out of the box** on the built-in Free provider — no signup, no API key. Point it at Groq, Google Gemini, NVIDIA NIM, OpenRouter, Bynara, Kimchi, Hetzner, or a local Ollama — all have free access — and clai stacks them. Add several keys per provider; when one hits a rate limit, it rotates to the next automatically. Want frontier models instead? Serve **Kimi K3 on your own Modal endpoint** on Modal's **$30/month of free credit**, or start on **Lightning AI's 40M free tokens**.
10
10
  - **It's honest.** Findings need real tool output. Builds get typechecked/run before "done." Compaction and history keep long sessions coherent instead of hallucinating progress.
11
11
 
12
12
  ---
13
13
 
14
14
  ## Highlights
15
15
 
16
- - **Free-tier first.** 17 providers wired in, 7 cloud free tiers + local Ollama. The default provider is the **keyless Free** gateway (`free-1/deepseek-v4-flash-free`) so a fresh install runs at no cost with zero setup — no API key required.
16
+ - **Free-tier first.** 19 providers wired in, 8 cloud free tiers + local Ollama. The default provider is the **keyless Free** gateway (`free-1/deepseek-v4-flash-free`) so a fresh install runs at no cost with zero setup — no API key required.
17
17
  - **Multi-key smart switching.** Up to 10 keys per provider with a *sticky* active key and circular rotation on rate-limit / auth / quota / transient / 5xx / empty-response errors. Disable any key or endpoint row to skip it without deleting it. Optional cross-provider fallback and a free-only filter.
18
18
  - **Bring your own endpoint.** Deploy Kimi K3 (or Qwen / DeepSeek / GLM / GPT-OSS / your own fine-tune) to a [Modal](#modal--run-kimi-k3-on-your-own-endpoint-on-30month-of-free-credit) endpoint and drive it from clai on **$30/month of free compute credit**. Modal, Lightning AI and TokenRouter each keep a list of up to 10 base URLs with a sticky active one, so several deployments live side by side and you switch with one command — same editor, same ★ active row as keys.
19
19
  - **Scope-based pentesting.** Opt-in engagement scope with authorized/excluded targets, allowed phases, rate and concurrency ceilings, redirect and DNS-rebinding escape detection, and out-of-scope flagging — designed for authorized pentests and bug-bounty programs.
@@ -105,7 +105,7 @@ clai # launch the full-screen agent console (already on the free provid
105
105
  Prefer a different provider? Get a free key, add it, and go:
106
106
 
107
107
  ```sh
108
- # Add a free key (Groq shown; NVIDIA/Gemini/OpenRouter/Bynara/Kimchi work the same)
108
+ # Add a free key (Groq shown; NVIDIA/Gemini/OpenRouter/Bynara/Kimchi/Hetzner work the same)
109
109
  clai set groq gsk_your_key_here
110
110
  clai use groq
111
111
 
@@ -151,8 +151,10 @@ This is the core of clai's design: assemble capacity from free tiers, then survi
151
151
  | Qwen Cloud | `qwen3.7-plus` | Paid (DashScope) | `DASHSCOPE_API_KEY` |
152
152
  | Modal | `moonshotai/Kimi-K3` | Usage-based ($30/mo credit) | `MODAL_PROXY_TOKEN_ID` + `MODAL_PROXY_TOKEN_SECRET` |
153
153
  | Lightning AI | `openai/gpt-5` | Per token (40M free to start) | `LIGHTNING_API_KEY` |
154
- | TokenRouter | `kimi-k2p6` | Per token (prepaid) | `TOKENROUTER_API_KEY` |
154
+ | TokenRouter | `moonshotai/kimi-k3` | Per token (prepaid) | `TOKENROUTER_API_KEY` |
155
155
  | Meta (Muse Spark) | `muse-spark-1.2` | Paid (per token) | `MODEL_API_KEY` |
156
+ | Fireworks | `accounts/fireworks/models/kimi-k2p6` | Paid (per token) | `FIREWORKS_API_KEY` |
157
+ | Hetzner | `Qwen/Qwen3.6-35B-A3B-FP8` | Free (experiment — no billing yet) | `HETZNER_API_KEY` |
156
158
 
157
159
  Several "paid" providers also expose limited free allowances — the tier label reflects what the default keys usually buy you. Flip `freeOnly` off to include paid providers in fallback.
158
160
 
@@ -225,11 +227,29 @@ clai use lightning
225
227
 
226
228
  ```sh
227
229
  clai set tokenrouter sk-your-key # key: your account → API Keys
228
- clai use tokenrouter # model defaults to kimi-k2p6
229
- /model deepseek-v4-pro # 1M context · or kimi-k2p7-code, glm-5p1, minimax-m3
230
+ clai use tokenrouter # model defaults to moonshotai/kimi-k3
231
+ /model deepseek/deepseek-v4-pro # 1M context · or moonshotai/kimi-k2.7-code, z-ai/glm-5.1, MiniMax-M3
230
232
  ```
231
233
 
232
- Model ids are short and case-sensitive (`kimi-k2p6`, not `Kimi K2.6`), and `/model` reads the live `/models` list, which is filtered to the channels your key can reach. clai carries the real per-model context windows — 1M for DeepSeek V4, 512K for MiniMax M3, 256K for Kimi/Qwen, 200K for GLM — so the context meter and auto-compaction are accurate instead of guessing 128K. Reasoning arrives as `reasoning_content` and is folded into the normal thinking block, so `/think` and `/effort` work. Base URL defaults to `https://api.tokenrouter.com/v1` and is overridable with `clai set tokenrouter --url <url>` or `TOKENROUTER_BASE_URL` if your account uses a different host.
234
+ Model ids are vendor-namespaced (`moonshotai/kimi-k2.6`, `deepseek/deepseek-v4-pro`, `qwen/qwen3.7-plus`); the old short ids (`kimi-k2p6`, `glm-5p1`, ) are still accepted and silently redirected to the current namespaced id. `/model` reads the live `/models` list, which is filtered to the channels your key can reach. clai carries the real per-model context windows — 1M for DeepSeek V4, 512K for MiniMax M3, 256K for Kimi/Qwen, 200K for GLM — so the context meter and auto-compaction are accurate instead of guessing 128K. Reasoning arrives as `reasoning_content` and is folded into the normal thinking block, so `/think` and `/effort` work. Base URL defaults to `https://api.tokenrouter.com/v1` and is overridable with `clai set tokenrouter --url <url>` or `TOKENROUTER_BASE_URL` if your account uses a different host.
235
+
236
+ #### Fireworks and Hetzner (open-model inference)
237
+
238
+ [Fireworks](https://fireworks.ai) is a per-token inference gateway for open models — Kimi, DeepSeek, GLM, Qwen, GPT-OSS, Llama — with SSE streaming and native tool calling.
239
+
240
+ ```sh
241
+ clai set fireworks fw_your_key # key: fireworks.ai → API keys
242
+ clai use fireworks # model defaults to accounts/fireworks/models/kimi-k2p6
243
+ ```
244
+
245
+ [Hetzner Inference](https://docs.hetzner.com/general/company-and-policy/experiments/inference/) is Hetzner's OpenAI-compatible experiment API serving open-weight models (Qwen3.6-35B with vision, 262K context) from EU servers. It is free while experimental — there is no billing yet — with fair-use per-key rate limits and no SLA or production guarantee.
246
+
247
+ ```sh
248
+ clai set hetzner your-token # token: experiments.hetzner.com → Create API Token
249
+ clai use hetzner # model defaults to Qwen/Qwen3.6-35B-A3B-FP8
250
+ ```
251
+
252
+ Both fetch the live model catalog for `/model` (cached 1h) and rotate keys like every other provider.
233
253
 
234
254
  ### Manage keys
235
255
 
@@ -243,6 +263,8 @@ clai set modal --url https://ws--ep-kimi-k3-server.us-west.modal.direct # endp
243
263
  clai set modal wk-tokenId:ws-tokenSecret # …then the proxy token pair
244
264
  clai set lightning <key> # Lightning AI Model APIs
245
265
  clai set tokenrouter sk-your-key # TokenRouter
266
+ clai set fireworks fw_your_key # Fireworks
267
+ clai set hetzner your-token # Hetzner Inference (experiments.hetzner.com)
246
268
  clai set free <key> # optional: unlock premium models (free is keyless by default)
247
269
  clai unset modal --url # drop stored endpoint URLs, keep the keys
248
270
  clai keys # providers + masked keys (★ active) + endpoint URLs
@@ -368,7 +390,7 @@ The old line REPL has been removed — there are only full surfaces now. An Open
368
390
  | Commands / file mentions | `/` · `@` |
369
391
  | Help / shortcuts | `Ctrl+G` |
370
392
 
371
- Tool cards show the command/input clearly and keep long scan tails in an expandable OUTPUT pager (search, copy, export). File writes show a diff preview. Compaction cards preserve session memory without dropping the plan, and `/history` restores full sessions — prompts, tool results, and the matching plan — even after an abort or autosave.
393
+ Tool cards show the command/input clearly, with a live elapsed timer next to the command name while they run (the final duration stays visible afterwards), and keep long scan tails in an expandable OUTPUT pager (search, copy, export). File writes show a diff preview. When the agent finishes each prompt — naturally or aborted — a `✻ Worked for 1m16s` row is appended under the response, and it is restored when the session is resumed from `/history`. The status line names what the agent is actually doing right now — `responding` while streaming, `compacting` during auto or manual context compaction — instead of holding the last tool name. Prompts typed while the agent is busy are queued and run automatically in order once the turn settles; the queue pauses only when the previous turn was cancelled, errored, or stopped by the loop guard. Compaction cards preserve session memory without dropping the plan, and `/history` restores full sessions — prompts, tool results, and the matching plan — even after an abort or autosave.
372
394
 
373
395
  ---
374
396
 
@@ -560,7 +582,7 @@ clai/
560
582
  ├─ src/
561
583
  │ ├─ index.ts # CLI entry + subcommands
562
584
  │ ├─ agent/ # loop, plans, compaction, resume orientation, tool parsing
563
- │ ├─ llm/ # 17 providers, streaming, native tools, key rotation + fallback
585
+ │ ├─ llm/ # 19 providers, streaming, native tools, key rotation + fallback
564
586
  │ ├─ tools/ # fs, shell, net, http, web, pentest, batch, plan
565
587
  │ ├─ safety/ # risk classifier + engagement (scope) policy
566
588
  │ ├─ store/ # config, history, keys, plans, scope
@@ -34,14 +34,17 @@ export async function ensurePentestAuthorization(call, autoConfirm, session, con
34
34
  return true;
35
35
  }
36
36
  export async function confirmToolExecution(call, autoConfirm, session, confirmPort, options) {
37
- // fs.delete + outside-cwd mutates always prompt even under allow-all / -y.
38
- // Deletion is irreversible; never auto-approve.
39
- if (options?.forceConfirm || call.name === "fs.delete") {
37
+ // fs.delete always prompts at every permission level, even allow-all / -y.
38
+ // Deletion is irreversible; never auto-approve. Everything else (including
39
+ // out-of-cwd writes) honors allow-all.
40
+ if (call.name === "fs.delete") {
40
41
  return confirmPort.confirmTool(call);
41
42
  }
42
43
  const config = getConfig();
43
44
  if (config.permissions === "allow-all")
44
45
  return true;
46
+ if (options?.forceConfirm)
47
+ return confirmPort.confirmTool(call);
45
48
  if (autoConfirm)
46
49
  return true;
47
50
  if (session.allow.has(call.name))
@@ -1 +1 @@
1
- {"version":3,"file":"confirm-port.js","sourceRoot":"","sources":["../../src/agent/confirm-port.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAIhF,OAAO,EAAE,uBAAuB,EAAE,CAAC;AAgBnC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAgB,sBAAsB,EAAE,CAAC;AAEtE,MAAM,kBAAkB,GAAG,qBAAqB,EAAE,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAG1C;IACC,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,IAAc,EACd,WAAoB,EACpB,OAAsB,EACtB,WAAwB;IAExB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,WAAW,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACpD,6DAA6D;IAC7D,IAAI,MAAM,CAAC,iBAAiB;QAAE,OAAO,IAAI,CAAC;IAC1C,+DAA+D;IAC/D,IAAI,OAAO,CAAC,iBAAiB,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAEjD,IAAI,WAAW,EAAE,CAAC;QAChB,sEAAsE;QACtE,oEAAoE;QACpE,OAAO,CAAC,iBAAiB,CAAC,KAAK,GAAG,IAAI,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC,cAAc,EAAE,CAAC;IAC9C,IAAI,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IACtB,OAAO,CAAC,iBAAiB,CAAC,KAAK,GAAG,IAAI,CAAC;IACvC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAc,EACd,WAAoB,EACpB,OAAsB,EACtB,WAAwB,EACxB,OAAgD;IAEhD,6EAA6E;IAC7E,gDAAgD;IAChD,IAAI,OAAO,EAAE,YAAY,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACvD,OAAO,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,WAAW,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACpD,IAAI,WAAW;QAAE,OAAO,IAAI,CAAC;IAC7B,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,uEAAuE;IACvE,wEAAwE;IACxE,qDAAqD;IACrD,IAAI,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7D,OAAO,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"confirm-port.js","sourceRoot":"","sources":["../../src/agent/confirm-port.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAIhF,OAAO,EAAE,uBAAuB,EAAE,CAAC;AAgBnC,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAgB,sBAAsB,EAAE,CAAC;AAEtE,MAAM,kBAAkB,GAAG,qBAAqB,EAAE,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAG1C;IACC,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,IAAc,EACd,WAAoB,EACpB,OAAsB,EACtB,WAAwB;IAExB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,WAAW,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACpD,6DAA6D;IAC7D,IAAI,MAAM,CAAC,iBAAiB;QAAE,OAAO,IAAI,CAAC;IAC1C,+DAA+D;IAC/D,IAAI,OAAO,CAAC,iBAAiB,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAEjD,IAAI,WAAW,EAAE,CAAC;QAChB,sEAAsE;QACtE,oEAAoE;QACpE,OAAO,CAAC,iBAAiB,CAAC,KAAK,GAAG,IAAI,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC,cAAc,EAAE,CAAC;IAC9C,IAAI,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IACtB,OAAO,CAAC,iBAAiB,CAAC,KAAK,GAAG,IAAI,CAAC;IACvC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAc,EACd,WAAoB,EACpB,OAAsB,EACtB,WAAwB,EACxB,OAAgD;IAEhD,6EAA6E;IAC7E,2EAA2E;IAC3E,uCAAuC;IACvC,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9B,OAAO,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,WAAW,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACpD,IAAI,OAAO,EAAE,YAAY;QAAE,OAAO,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAChE,IAAI,WAAW;QAAE,OAAO,IAAI,CAAC;IAC7B,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,uEAAuE;IACvE,wEAAwE;IACxE,qDAAqD;IACrD,IAAI,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7D,OAAO,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC"}
@@ -1802,8 +1802,8 @@ export async function runAgentTurn(prompt, options = {}) {
1802
1802
  if (needsPentestAuth) {
1803
1803
  pentestJustConfirmed = true;
1804
1804
  }
1805
- // Always confirm destructive deletes and any write outside cwd
1806
- // even when permissions=allow-all or -y (user requirement).
1805
+ // fs.delete always confirms (every permission level). Out-of-cwd
1806
+ // writes confirm under default permissions; allow-all auto-approves.
1807
1807
  let forceConfirm = call.name === "fs.delete";
1808
1808
  if (call.name === "fs.write" ||
1809
1809
  call.name === "fs.writeMany" ||
@@ -3004,7 +3004,7 @@ export async function runAgentTurn(prompt, options = {}) {
3004
3004
  // phase on a timer rather than only on token arrival.
3005
3005
  const streamPhase = () => {
3006
3006
  if (generatedTokens > 0 && !inThinking) {
3007
- return "generating response";
3007
+ return "responding";
3008
3008
  }
3009
3009
  if (sawReasoning)
3010
3010
  return "thinking";