@pentoshi/clai 3.7.5 → 3.7.7

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 (70) hide show
  1. package/README.md +54 -19
  2. package/dist/agent/events.d.ts +7 -0
  3. package/dist/agent/runner.js +7 -0
  4. package/dist/agent/runner.js.map +1 -1
  5. package/dist/agent/tool-call-parser.js +7 -0
  6. package/dist/agent/tool-call-parser.js.map +1 -1
  7. package/dist/app/adapters/agent-event-adapter.js +9 -0
  8. package/dist/app/adapters/agent-event-adapter.js.map +1 -1
  9. package/dist/app/controllers/session-controller.d.ts +20 -1
  10. package/dist/app/controllers/session-controller.js +39 -1
  11. package/dist/app/controllers/session-controller.js.map +1 -1
  12. package/dist/app/events/app-event.d.ts +7 -0
  13. package/dist/app/events/app-event.js.map +1 -1
  14. package/dist/commands/update.js +1 -1
  15. package/dist/llm/agentrouter.js +3 -15
  16. package/dist/llm/agentrouter.js.map +1 -1
  17. package/dist/llm/anthropic.js +26 -2
  18. package/dist/llm/anthropic.js.map +1 -1
  19. package/dist/llm/aws-mantle.js +3 -15
  20. package/dist/llm/aws-mantle.js.map +1 -1
  21. package/dist/llm/bynara.js +3 -15
  22. package/dist/llm/bynara.js.map +1 -1
  23. package/dist/llm/gemini.js +8 -0
  24. package/dist/llm/gemini.js.map +1 -1
  25. package/dist/llm/groq.js +3 -15
  26. package/dist/llm/groq.js.map +1 -1
  27. package/dist/llm/http.d.ts +4 -1
  28. package/dist/llm/http.js +29 -1
  29. package/dist/llm/http.js.map +1 -1
  30. package/dist/llm/kimchi.js +3 -15
  31. package/dist/llm/kimchi.js.map +1 -1
  32. package/dist/llm/nvidia.js +3 -15
  33. package/dist/llm/nvidia.js.map +1 -1
  34. package/dist/llm/ollama.js +14 -0
  35. package/dist/llm/ollama.js.map +1 -1
  36. package/dist/llm/openai.js +3 -15
  37. package/dist/llm/openai.js.map +1 -1
  38. package/dist/llm/openrouter.js +3 -15
  39. package/dist/llm/openrouter.js.map +1 -1
  40. package/dist/llm/qwen-cloud.js +3 -15
  41. package/dist/llm/qwen-cloud.js.map +1 -1
  42. package/dist/llm/token-usage.d.ts +70 -0
  43. package/dist/llm/token-usage.js +210 -0
  44. package/dist/llm/token-usage.js.map +1 -0
  45. package/dist/prompts/embedded.js +2 -2
  46. package/dist/prompts/embedded.js.map +1 -1
  47. package/dist/prompts/index.js +2 -2
  48. package/dist/prompts/system.agent.md +2 -2
  49. package/dist/prompts/system.ask.md +1 -1
  50. package/dist/tools/batch-fail-policy.d.ts +55 -0
  51. package/dist/tools/batch-fail-policy.js +261 -0
  52. package/dist/tools/batch-fail-policy.js.map +1 -0
  53. package/dist/tools/definitions.js +82 -3
  54. package/dist/tools/definitions.js.map +1 -1
  55. package/dist/tools/registry.d.ts +1 -0
  56. package/dist/tools/registry.js +263 -34
  57. package/dist/tools/registry.js.map +1 -1
  58. package/dist/tui-v2/app/commands/session-commands.js +11 -5
  59. package/dist/tui-v2/app/commands/session-commands.js.map +1 -1
  60. package/dist/tui-v2/bootstrap/composition-root.js +10 -2
  61. package/dist/tui-v2/bootstrap/composition-root.js.map +1 -1
  62. package/dist/tui-v2/components/status/status-line.js +23 -5
  63. package/dist/tui-v2/components/status/status-line.js.map +1 -1
  64. package/dist/tui-v2/rendering/batch-sections.d.ts +3 -0
  65. package/dist/tui-v2/rendering/batch-sections.js +40 -17
  66. package/dist/tui-v2/rendering/batch-sections.js.map +1 -1
  67. package/dist/tui-v2/state/transcript-reducer.js +2 -0
  68. package/dist/tui-v2/state/transcript-reducer.js.map +1 -1
  69. package/dist/types.d.ts +10 -0
  70. package/package.json +1 -1
package/README.md CHANGED
@@ -117,6 +117,7 @@ Inside a session:
117
117
  | **Network** | `net.scan` (nmap wrapper, SYN with privilege / TCP fallback), `net.context`, `net.pingSweep`, `pentest.recon` (whois + dig + top ports) |
118
118
  | **HTTP evidence** | `http.fetch` — status, headers, cookies, TLS, body for **raw protocol / pentest** work (not casual page reading) |
119
119
  | **Web reading / OSINT** | `web.search`, `web.fetch` (readable pages), plus shell for specialized CLIs |
120
+ | **Batch recon** | `tool.batch` — up to 20 lookups in one call; optional `on_fail` fail-fast or selective cancel when dependents need a prerequisite |
120
121
  | **Discovery** | `tool.check`, `pkg.install`, `wordlist.find` — install only what is missing; locate wordlists per OS (no Kali-only path guesses) |
121
122
  | **DNS / ownership** | `dns.lookup`, `whois.lookup` for narrow questions |
122
123
  | **Shell** | Full toolbox: `nmap`, `ffuf`, `gobuster`, `feroxbuster`, `sqlmap`, `hydra`, `nikto`, `masscan`, `nuclei`, `tshark`, … via `shell.exec` |
@@ -156,18 +157,19 @@ Default posture is **non-destructive proof**. Escalate impact only when you ask
156
157
  - Full plan + notes pager (`Ctrl+P` / `/plan`)
157
158
  - Approve with `/implement`, revise in chat, cancel with `/discard`
158
159
  - Plans **survive context compaction** and **reload with `/history`**
160
+ - Agent mode: working checklist + evidence-before-done; plan mode: roadmap you approve before execution
159
161
 
160
162
  ---
161
163
 
162
164
  ## Terminal UI (operator console)
163
165
 
164
- Full-screen UI by default: streaming chat, tool cards, plan pane, pickers, history, secure key prompts. Falls back to a classic line REPL if the terminal cannot host the UI.
166
+ Full-screen OpenTUI console by default: streaming chat, nested tool cards (including `tool.batch` sub-sections), file diffs, plan pane, pickers, history, secure key prompts. Falls back to a classic line REPL if the terminal cannot host the UI.
165
167
 
166
168
  | Action | How |
167
169
  |--------|-----|
168
170
  | Send | `Enter` |
169
171
  | Newline | `Shift+Enter` |
170
- | Abort turn | `Esc` |
172
+ | Abort turn | `Esc` / `Ctrl+C` (cancels in-flight tools cleanly) |
171
173
  | Expand thinking | `Ctrl+T` (clickable on status strip) |
172
174
  | Expand tool / compacted output | `Ctrl+O` |
173
175
  | Plan pane | `Ctrl+H` |
@@ -176,9 +178,9 @@ Full-screen UI by default: streaming chat, tool cards, plan pane, pickers, histo
176
178
  | Commands / files | `/` · `@` |
177
179
  | Exit | `Ctrl+C` twice |
178
180
 
179
- Tool cards show **command/input** clearly and keep long scan tails in **OUTPUT** (expand or open pager). Compaction cards preserve engagement memory without dropping the plan.
181
+ Tool cards show **command/input** clearly and keep long scan tails in **OUTPUT** (expand or open pager). File writes show a **diff preview**. Deletes always ask for confirmation (`y`/`n`); press **`v`** to preview the path before confirming. Compaction cards preserve engagement memory without dropping the plan.
180
182
 
181
- **`/history`** restores full sessions — prompts, tools, findings context, and the matching plan when present.
183
+ **`/history`** restores full sessions — prompts, tool results, findings context, and the matching plan when present (including after abort / autosave).
182
184
 
183
185
  ---
184
186
 
@@ -198,14 +200,18 @@ Coding and general sysadmin work use the same agent (scaffold, debug, packages)
198
200
  ## Features (summary)
199
201
 
200
202
  - **Pentest-first agent loop** — recon-before-plan, stack-aware enum, evidence-backed findings
201
- - **Durable plans** — `plan.create` / `task.update`, side pane, approve/refine/discard
202
- - **11 LLM providers** with streaming (many free tiers + local Ollama)
203
- - **Safety gate** + pentest authorization + optional engagement scope
203
+ - **Durable plans** — `plan.create` / `task.update`, side pane, approve/refine/discard; agent vs plan task workflows
204
+ - **Parallel multi-tool turns** independent reads run together; failures do **not** cancel siblings by default
205
+ - **`tool.batch` fail policy** opt-in `on_fail=cancel_pending` or selective `cancel_on_fail` / rules when later work depends on earlier success
206
+ - **Native + text tool calling** — `toolCalling: auto|native|text`
207
+ - **11+ LLM providers** with streaming (free tiers + local Ollama)
208
+ - **Safety gate** + pentest authorization + optional engagement scope (deletes always confirm with preview)
204
209
  - **OS-aware** installs and wordlist discovery (macOS / Linux / Windows)
205
210
  - **Context compaction** (auto + `/compact`) that keeps the plan alive
206
- - **Session history** with full transcript restore
211
+ - **Session history** with full transcript + plan restore
207
212
  - **Background jobs** for long scanners and listeners
208
213
  - **Web OSINT** — `web.search` / `web.fetch` alongside raw `http.fetch`
214
+ - **Stall / cancel robustness** — tool heartbeats, hard deadlines, clean Esc abort with results recorded
209
215
 
210
216
  ---
211
217
 
@@ -265,15 +271,44 @@ CLI mirrors: `clai authorize-pentest`, `clai scope add`, `clai doctor` (missing
265
271
 
266
272
  | Tool | Role in engagements |
267
273
  |------|---------------------|
268
- | `shell.exec` / `shell.start` | nmap, ffuf, sqlmap, hydra, custom PoCs, listeners |
269
- | `net.scan` · `net.context` · `pentest.recon` | Host/port/service discovery |
274
+ | `shell.exec` / `shell.start` · `shell.jobs` / `tail` / `stop` | nmap, ffuf, sqlmap, hydra, custom PoCs, listeners, background jobs |
275
+ | `net.scan` · `net.context` · `net.pingSweep` · `pentest.recon` | Host/port/service discovery |
270
276
  | `http.fetch` | Raw HTTP/TLS evidence |
271
277
  | `web.search` · `web.fetch` | OSINT / docs (readable), not raw exploit traffic |
272
278
  | `dns.lookup` · `whois.lookup` | Narrow DNS / ownership |
279
+ | `tool.batch` | Fan-out up to 20 tools; `concurrency` 1–6; `on_fail` continue (default) / cancel_pending / rules; per-call `cancel_on_fail` |
273
280
  | `tool.check` · `pkg.install` · `wordlist.find` | Tooling readiness |
274
- | `fs.*` | Loot, notes, report files (sandboxed roots) |
275
- | `plan.create` · `task.update` | Engagement checklist |
281
+ | `fs.read` · `fs.list` · `fs.search` · `fs.write` · `fs.writeMany` · `fs.edit` · `fs.replaceLines` · `fs.append` · `fs.delete` | Files (sandboxed roots; delete always confirms + optional preview) |
282
+ | `plan.create` · `task.update` | Engagement checklist / working tasks |
276
283
  | `sysinfo` · `image.ocr` · `pdf.read` | Host context, report/screenshot OCR |
284
+ | `agent.handoff` | Ask mode → offer agent mode when the user wants action, not explanation |
285
+
286
+ ### `tool.batch` fail policy (opt-in)
287
+
288
+ Default is **continue** — one failed lookup never kills the rest (best for recon).
289
+
290
+ ```json
291
+ // Fail-fast: stop remaining calls after the first failure
292
+ {"name":"tool.batch","args":{
293
+ "on_fail":"cancel_pending",
294
+ "calls":[
295
+ {"name":"net.scan","args":{"target":"lab.example"}},
296
+ {"name":"http.fetch","args":{"url":"https://lab.example/"}}
297
+ ]
298
+ }}
299
+
300
+ // Selective: if scan fails, cancel only fuzz (dns still runs)
301
+ {"name":"tool.batch","args":{
302
+ "calls":[
303
+ {"id":"dns","name":"dns.lookup","args":{"target":"lab.example"}},
304
+ {"id":"scan","name":"net.scan","args":{"target":"lab.example"},
305
+ "cancel_on_fail":["fuzz"]},
306
+ {"id":"fuzz","name":"shell.exec","args":{"command":"ffuf …"}}
307
+ ]
308
+ }}
309
+ ```
310
+
311
+ Top-level multi-tool messages (several separate tool blocks) never cancel siblings; use `tool.batch` when you need a fail policy.
277
312
 
278
313
  ### Search providers (OSINT)
279
314
 
@@ -334,10 +369,10 @@ Node.js ≥ 20.
334
369
  Tag-driven CI (`.github/workflows/release.yml`): tests → multi-platform binaries → GitHub Release → npm `@pentoshi/clai` → Homebrew tap.
335
370
 
336
371
  ```sh
337
- npm version 2.0.34 --no-git-tag-version
372
+ npm version 3.7.6 --no-git-tag-version
338
373
  # bump FALLBACK_VERSION / manifests as needed
339
- git commit -am "v2.0.34" && git push origin main
340
- git tag -a v2.0.34 -m "clai v2.0.34" && git push origin v2.0.34
374
+ git commit -am "v3.7.6" && git push origin main
375
+ git tag -a v3.7.6 -m "clai v3.7.6" && git push origin v3.7.6
341
376
  ```
342
377
 
343
378
  Secrets: `NPM_TOKEN`, `TAP_GITHUB_TOKEN`. Optional: `NPM_PROVENANCE=true`.
@@ -352,13 +387,13 @@ clai/
352
387
  │ ├─ index.ts # CLI entry
353
388
  │ ├─ modes/ # ask · agent
354
389
  │ ├─ agent/ # loop, plans, compaction, tool parsing
355
- │ ├─ llm/ # providers + streaming
356
- │ ├─ tools/ # shell, net, http, web, fs, pentest, …
390
+ │ ├─ llm/ # providers + streaming + native tools
391
+ │ ├─ tools/ # shell, net, http, web, fs, batch, pentest, …
357
392
  │ ├─ safety/ # classifier + patterns
358
393
  │ ├─ store/ # config, history, keys, plans, scope, logs
359
- │ ├─ tui/ # full-screen terminal UI
394
+ │ ├─ tui-v2/ # full-screen OpenTUI (primary)
360
395
  │ ├─ app/ # session, commands, events
361
- │ └─ prompts/ # agent methodology (incl. pentest)
396
+ │ └─ prompts/ # agent methodology (incl. pentest; embedded for bun)
362
397
  ├─ bin/clai.mjs
363
398
  ├─ install/ · manifests/
364
399
  └─ package.json
@@ -1,4 +1,5 @@
1
1
  import type { SessionPlan } from "../store/plan.js";
2
+ import type { TokenUsage } from "../types.js";
2
3
  import type { TurnOutcome } from "./turn-outcome.js";
3
4
  export type AgentEvent = {
4
5
  type: "turn-start";
@@ -78,4 +79,10 @@ export type AgentEvent = {
78
79
  summary: string;
79
80
  beforeTokens: number;
80
81
  afterTokens: number;
82
+ }
83
+ /** Provider-reported token usage after a model completion. */
84
+ | {
85
+ type: "token-usage";
86
+ usage: TokenUsage;
87
+ model?: string | undefined;
81
88
  };
@@ -2163,6 +2163,13 @@ export async function runAgentTurn(prompt, options = {}) {
2163
2163
  }
2164
2164
  provider = completion.provider;
2165
2165
  model = completion.model;
2166
+ if (completion.usage) {
2167
+ emit({
2168
+ type: "token-usage",
2169
+ usage: completion.usage,
2170
+ model: completion.model,
2171
+ });
2172
+ }
2166
2173
  deltaParser?.finish();
2167
2174
  // Sticky text-only may have flipped dialect during stream retry.
2168
2175
  ({ dialect: toolDialect, native: nativeToolsActive } =