sanook-cli 0.5.1 → 0.5.5

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 (217) hide show
  1. package/.env.example +161 -3
  2. package/CHANGELOG.md +148 -10
  3. package/README.md +255 -26
  4. package/README.th.md +95 -7
  5. package/dist/approval.js +13 -0
  6. package/dist/bin.js +3552 -155
  7. package/dist/brain-consolidate.js +335 -0
  8. package/dist/brain-context.js +262 -0
  9. package/dist/brain-doctor.js +318 -0
  10. package/dist/brain-eval.js +186 -0
  11. package/dist/brain-final.js +377 -0
  12. package/dist/brain-metrics.js +277 -0
  13. package/dist/brain-new.js +402 -0
  14. package/dist/brain-pack.js +210 -0
  15. package/dist/brain-repair.js +280 -0
  16. package/dist/brain-review.js +382 -0
  17. package/dist/brain.js +15 -1
  18. package/dist/brand.js +1 -1
  19. package/dist/cli-args.js +190 -0
  20. package/dist/cli-option-values.js +16 -0
  21. package/dist/clipboard.js +65 -0
  22. package/dist/commands.js +266 -27
  23. package/dist/compaction.js +96 -11
  24. package/dist/config.js +149 -33
  25. package/dist/context-compression.js +191 -0
  26. package/dist/context-pack.js +145 -0
  27. package/dist/cost.js +49 -15
  28. package/dist/dashboard/api-helpers.js +87 -0
  29. package/dist/dashboard/server.js +179 -0
  30. package/dist/dashboard/static/app.js +277 -0
  31. package/dist/dashboard/static/index.html +39 -0
  32. package/dist/dashboard/static/styles.css +85 -0
  33. package/dist/diff.js +10 -2
  34. package/dist/first-run.js +21 -0
  35. package/dist/gateway/auth.js +49 -9
  36. package/dist/gateway/bluebubbles.js +205 -0
  37. package/dist/gateway/config.js +929 -0
  38. package/dist/gateway/deliver.js +399 -0
  39. package/dist/gateway/discord.js +124 -0
  40. package/dist/gateway/doctor.js +456 -0
  41. package/dist/gateway/email.js +501 -0
  42. package/dist/gateway/googlechat.js +207 -0
  43. package/dist/gateway/homeassistant.js +256 -0
  44. package/dist/gateway/ledger.js +38 -1
  45. package/dist/gateway/line.js +171 -0
  46. package/dist/gateway/lock.js +3 -1
  47. package/dist/gateway/matrix.js +366 -0
  48. package/dist/gateway/mattermost.js +322 -0
  49. package/dist/gateway/ntfy.js +218 -0
  50. package/dist/gateway/schedule.js +31 -4
  51. package/dist/gateway/serve.js +267 -7
  52. package/dist/gateway/server.js +253 -19
  53. package/dist/gateway/service.js +224 -0
  54. package/dist/gateway/session.js +362 -0
  55. package/dist/gateway/signal.js +351 -0
  56. package/dist/gateway/slack.js +124 -0
  57. package/dist/gateway/sms.js +169 -0
  58. package/dist/gateway/targets.js +576 -0
  59. package/dist/gateway/teams.js +106 -0
  60. package/dist/gateway/telegram.js +38 -15
  61. package/dist/gateway/webhooks.js +220 -0
  62. package/dist/gateway/whatsapp.js +230 -0
  63. package/dist/hooks.js +13 -2
  64. package/dist/hotkeys.js +21 -0
  65. package/dist/i18n/en.js +98 -0
  66. package/dist/i18n/index.js +19 -0
  67. package/dist/i18n/th.js +98 -0
  68. package/dist/i18n/types.js +1 -0
  69. package/dist/insights-args.js +55 -0
  70. package/dist/insights.js +86 -0
  71. package/dist/knowledge.js +55 -29
  72. package/dist/loop.js +157 -29
  73. package/dist/lsp/index.js +23 -5
  74. package/dist/mcp-hub.js +33 -0
  75. package/dist/mcp-registry.js +494 -0
  76. package/dist/mcp-risk.js +71 -0
  77. package/dist/mcp-server.js +1 -1
  78. package/dist/mcp.js +120 -10
  79. package/dist/memory-log.js +90 -0
  80. package/dist/memory-store.js +37 -1
  81. package/dist/memory.js +148 -37
  82. package/dist/model-picker.js +58 -0
  83. package/dist/orchestrate.js +51 -19
  84. package/dist/personality.js +58 -0
  85. package/dist/plan-handoff.js +17 -0
  86. package/dist/polyglot.js +162 -0
  87. package/dist/process-runner.js +96 -0
  88. package/dist/project-init.js +91 -0
  89. package/dist/project-registry.js +143 -0
  90. package/dist/project-scaffold.js +124 -0
  91. package/dist/prompt-size.js +155 -0
  92. package/dist/providers/codex-login.js +138 -0
  93. package/dist/providers/codex.js +89 -43
  94. package/dist/providers/keys.js +22 -1
  95. package/dist/providers/models.js +2 -2
  96. package/dist/providers/registry.js +14 -47
  97. package/dist/search/chunk.js +7 -8
  98. package/dist/search/cli.js +83 -0
  99. package/dist/search/embed-store.js +3 -0
  100. package/dist/search/embedding-config.js +22 -0
  101. package/dist/search/engine.js +2 -13
  102. package/dist/search/indexer.js +44 -1
  103. package/dist/search/store.js +23 -1
  104. package/dist/session-distill.js +84 -0
  105. package/dist/session.js +92 -16
  106. package/dist/skill-install.js +53 -13
  107. package/dist/skills.js +33 -0
  108. package/dist/slash-completion.js +155 -0
  109. package/dist/support-dump.js +206 -0
  110. package/dist/tool-catalog.js +59 -0
  111. package/dist/tools/edit.js +45 -15
  112. package/dist/tools/git.js +10 -5
  113. package/dist/tools/homeassistant.js +106 -0
  114. package/dist/tools/index.js +10 -0
  115. package/dist/tools/list.js +19 -6
  116. package/dist/tools/permission.js +992 -12
  117. package/dist/tools/polyglot.js +126 -0
  118. package/dist/tools/read.js +16 -4
  119. package/dist/tools/sandbox.js +38 -13
  120. package/dist/tools/schedule.js +19 -3
  121. package/dist/tools/search.js +226 -15
  122. package/dist/tools/task.js +40 -9
  123. package/dist/tools/timeout.js +23 -3
  124. package/dist/tools/web-fetch-tool.js +33 -0
  125. package/dist/trust.js +11 -1
  126. package/dist/turn-retrieval.js +83 -0
  127. package/dist/ui/app.js +878 -32
  128. package/dist/ui/banner.js +78 -4
  129. package/dist/ui/history.js +37 -5
  130. package/dist/ui/markdown.js +122 -0
  131. package/dist/ui/mentions.js +3 -2
  132. package/dist/ui/overlay.js +496 -0
  133. package/dist/ui/queue.js +23 -0
  134. package/dist/ui/render.js +20 -1
  135. package/dist/ui/session-panel.js +115 -0
  136. package/dist/ui/setup-providers.js +40 -0
  137. package/dist/ui/setup.js +172 -46
  138. package/dist/ui/status.js +142 -0
  139. package/dist/ui/thinking-panel.js +36 -0
  140. package/dist/ui/tool-trail.js +97 -0
  141. package/dist/ui/transcript.js +26 -0
  142. package/dist/ui/useBusyElapsed.js +19 -0
  143. package/dist/ui/useEditor.js +144 -5
  144. package/dist/ui/useGitBranch.js +57 -0
  145. package/dist/update.js +56 -17
  146. package/dist/web-fetch.js +637 -0
  147. package/dist/web-surface.js +190 -0
  148. package/dist/worktree.js +175 -4
  149. package/package.json +5 -5
  150. package/second-brain/AGENTS.md +6 -4
  151. package/second-brain/CLAUDE.md +7 -1
  152. package/second-brain/Evals/_Index.md +10 -2
  153. package/second-brain/Evals/quality-ledger.md +9 -1
  154. package/second-brain/Evals/second-brain-benchmarks.md +62 -0
  155. package/second-brain/GEMINI.md +5 -4
  156. package/second-brain/Home.md +1 -1
  157. package/second-brain/Projects/_Index.md +19 -4
  158. package/second-brain/Projects/sanook-cli/_Index.md +30 -0
  159. package/second-brain/Projects/sanook-cli/context.md +35 -0
  160. package/second-brain/Projects/sanook-cli/current-state.md +32 -0
  161. package/second-brain/Projects/sanook-cli/overview.md +41 -0
  162. package/second-brain/Projects/sanook-cli/repo.md +34 -0
  163. package/second-brain/Projects/sanook-cli/second-brain-feature-roadmap.md +197 -0
  164. package/second-brain/README.md +1 -1
  165. package/second-brain/Research/2026-06-17-ai-second-brain-method-experiment.md +108 -0
  166. package/second-brain/Research/2026-06-18-ai-token-reduction-frameworks.md +55 -0
  167. package/second-brain/Research/2026-06-18-hermes-cli-second-brain-expansion-research.md +160 -0
  168. package/second-brain/Research/2026-06-18-hermes-tui-parity-map.md +129 -0
  169. package/second-brain/Research/2026-06-18-sanook-mcp-ecosystem-and-ux-roadmap.md +181 -0
  170. package/second-brain/Research/2026-06-19-hermes-python-architecture-for-sanook.md +49 -0
  171. package/second-brain/Research/2026-06-19-terminal-ui-brand-research.md +52 -0
  172. package/second-brain/Research/_Index.md +8 -1
  173. package/second-brain/Reviews/2026-06-18-auto-improve-maintenance.md +54 -0
  174. package/second-brain/Reviews/_Index.md +1 -1
  175. package/second-brain/Runbooks/_Index.md +6 -1
  176. package/second-brain/Runbooks/ai-second-brain-operating-sequence.md +108 -0
  177. package/second-brain/SANOOK.md +45 -0
  178. package/second-brain/Sessions/2026-06-17-ai-framework-additional-zones.md +68 -0
  179. package/second-brain/Sessions/2026-06-17-ai-second-brain-sequence-experiment.md +63 -0
  180. package/second-brain/Sessions/2026-06-18-cli-args-release-readiness.md +59 -0
  181. package/second-brain/Sessions/2026-06-18-final-gate-template-final.md +192 -0
  182. package/second-brain/Sessions/2026-06-18-final-gate-template.md +71 -0
  183. package/second-brain/Sessions/2026-06-18-framework-dogfood-permission-and-memory.md +58 -0
  184. package/second-brain/Sessions/2026-06-18-hermes-second-brain-expansion-research.md +52 -0
  185. package/second-brain/Sessions/2026-06-18-mcp-ecosystem-and-sanook-ux-scan.md +81 -0
  186. package/second-brain/Sessions/2026-06-18-sanook-brain-cli-p0-implementation.md +86 -0
  187. package/second-brain/Sessions/2026-06-18-sanook-brain-final-cli-final.md +246 -0
  188. package/second-brain/Sessions/2026-06-18-sanook-brain-final-cli.md +78 -0
  189. package/second-brain/Sessions/2026-06-18-sanook-cli-second-brain-roadmap-correction.md +54 -0
  190. package/second-brain/Sessions/2026-06-18-token-reduction-framework-integration.md +69 -0
  191. package/second-brain/Sessions/_Index.md +15 -1
  192. package/second-brain/Shared/AI-Context-Index.md +22 -0
  193. package/second-brain/Shared/Context-Packs/_Index.md +9 -1
  194. package/second-brain/Shared/Context-Packs/coding-release.md +51 -0
  195. package/second-brain/Shared/Context-Packs/research-to-framework.md +51 -0
  196. package/second-brain/Shared/Context-Packs/second-brain-maintenance.md +41 -0
  197. package/second-brain/Shared/Operating-State/current-state.md +14 -4
  198. package/second-brain/Shared/Scripts/_Index.md +3 -1
  199. package/second-brain/Shared/Scripts/ai-second-brain-method-eval.mjs +198 -0
  200. package/second-brain/Shared/Tech-Standards/_Index.md +6 -1
  201. package/second-brain/Shared/Tech-Standards/mcp-integration-roadmap.md +86 -0
  202. package/second-brain/Shared/Tech-Standards/polyglot-runtime-strategy.md +46 -0
  203. package/second-brain/Shared/Tech-Standards/verification-standard.md +24 -0
  204. package/second-brain/Shared/Tech-Standards/web-search-grounding-policy.md +70 -0
  205. package/second-brain/Shared/User-Memory/_Index.md +4 -1
  206. package/second-brain/Shared/User-Memory/response-examples.md +98 -0
  207. package/second-brain/Shared/User-Memory/user-preferences.md +1 -0
  208. package/second-brain/Templates/_Index.md +9 -0
  209. package/second-brain/Templates/final-lite.md +111 -0
  210. package/second-brain/Templates/final.md +231 -0
  211. package/second-brain/Templates/project-workspace/_Index.md +31 -0
  212. package/second-brain/Templates/project-workspace/context.md +28 -0
  213. package/second-brain/Templates/project-workspace/current-state.md +29 -0
  214. package/second-brain/Templates/project-workspace/overview.md +39 -0
  215. package/second-brain/Templates/project-workspace/repo.md +33 -0
  216. package/second-brain/Vault Structure Map.md +2 -1
  217. package/skills/structured-output-llm/SKILL.md +1 -1
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **The open-source terminal AI coding agent that remembers across sessions.**
6
6
 
7
- Bring your own key · 12 providers · MCP · a built-in **"second brain"** that gives the AI durable memory across sessions — the thing Claude Code, Codex, and Gemini CLI lose at the session boundary.
7
+ Bring your own key · 9 providers · MCP · a built-in **"second brain"** that gives the AI durable memory across sessions — the thing Claude Code, Codex, and Gemini CLI lose at the session boundary.
8
8
 
9
9
  🇹🇭 [อ่านภาษาไทย](README.th.md)
10
10
 
@@ -13,7 +13,7 @@ Bring your own key · 12 providers · MCP · a built-in **"second brain"** that
13
13
  [![License](https://img.shields.io/badge/license-Apache--2.0-22c55e.svg)](LICENSE)
14
14
  [![Node](https://img.shields.io/badge/node-%E2%89%A5%2022-339933.svg?logo=node.js&logoColor=white)](https://nodejs.org)
15
15
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6.svg?logo=typescript&logoColor=white)](https://www.typescriptlang.org)
16
- [![Tests](https://img.shields.io/badge/tests-381%20passing-22c55e.svg)](#development)
16
+ [![Tests](https://img.shields.io/badge/tests-passing-22c55e.svg)](#development)
17
17
  [![CI](https://github.com/Sir-chawakorn/sanook-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/Sir-chawakorn/sanook-cli/actions/workflows/ci.yml)
18
18
 
19
19
  [Quickstart](#quickstart) · [Providers](#providers) · [Usage](#usage) · [Gateway](#gateway--scheduling) · [Skills](#skills) · [MCP](#mcp) · [Security](#security)
@@ -45,7 +45,7 @@ The agent loop, BYOK, and MCP are table stakes now. What Sanook has that the big
45
45
  |---|:---:|:---:|:---:|:---:|
46
46
  | Open-source | ✅ | ❌ | ✅ | ✅ |
47
47
  | Bring your own key | ✅ | — | ✅ | ✅ |
48
- | Providers | **12** | 1 | 1 | 1 |
48
+ | Providers | **9** | 1 | 1 | 1 |
49
49
  | Local models (Ollama / LM Studio) | ✅ | ❌ | ❌ | ❌ |
50
50
  | MCP (stdio **+ remote HTTP**) | ✅ | ✅ | ✅ | ✅ |
51
51
  | OS sandbox (Seatbelt / bubblewrap) | ✅ | ✅ | ✅ | ✅ |
@@ -53,7 +53,7 @@ The agent loop, BYOK, and MCP are table stakes now. What Sanook has that the big
53
53
  | Image / vision input | ✅ | ✅ | ✅ | ✅ |
54
54
  | Prompt caching | ✅ | ✅ | ✅ | ✅ |
55
55
  | **Durable cross-session memory** | ✅ | ❌ | ❌ | ❌ |
56
- | **Local gateway + cron + Telegram** | ✅ | ❌ | ❌ | ❌ |
56
+ | **Local gateway + cron + messaging** | ✅ | ❌ | ❌ | ❌ |
57
57
 
58
58
  On raw benchmark scores the frontier vendors win — Sanook's bet is **portability + persistent memory**, not beating Opus on SWE-bench. Use whatever fits; this one remembers.
59
59
 
@@ -68,9 +68,13 @@ npm install -g sanook-cli
68
68
  > ⚠️ **`'sanook' is not recognized` / command not found?** You installed it locally — `npm i sanook-cli` (without `-g`) drops it into the current folder, **not on your PATH**, so the `sanook` command isn't found. Fix: reinstall with `npm install -g sanook-cli`, or just run it via **`npx sanook`** (uses the local copy you already installed).
69
69
  > Run **`npx sanook doctor`** to auto-diagnose Node version / PATH / install state and print the exact fix for your OS (incl. a safe Windows PATH one-liner).
70
70
 
71
- Set an API key (or run `sanook` with no task for the interactive setup wizard):
71
+ Run the setup wizard or set an API key manually:
72
72
 
73
73
  ```bash
74
+ sanook setup # provider + model wizard; offers to create a second brain
75
+ sanook model # re-run provider/model setup later
76
+ sanook auth add anthropic --api-key sk-ant-... --use
77
+
74
78
  export ANTHROPIC_API_KEY=sk-ant-... # macOS / Linux
75
79
  setx ANTHROPIC_API_KEY "sk-ant-..." # Windows (export won't work in cmd) — then open a NEW terminal
76
80
 
@@ -82,7 +86,14 @@ Run `sanook` with no task to drop into an interactive REPL. On the very first ru
82
86
  ```bash
83
87
  sanook # interactive REPL
84
88
  sanook "fix the failing test" # one-shot, headless
89
+ sanook chat -q "fix the failing test" --provider anthropic
90
+ sanook -z "summarise the diff" # one-shot, final output only
85
91
  sanook --json "..." # JSONL output for CI / scripts
92
+ sanook status # redacted provider/key/brain/gateway status
93
+ sanook web status # true web-search/fetch readiness + grounding policy
94
+ sanook sessions # list saved sessions for this project
95
+ sanook --resume <session_id> "continue here"
96
+ sanook dump # support snapshot; raw secrets are never printed
86
97
  ```
87
98
 
88
99
  ## Features
@@ -90,40 +101,42 @@ sanook --json "..." # JSONL output for CI / scripts
90
101
  | Area | What you get |
91
102
  |---|---|
92
103
  | **Agent loop** | Built on the Vercel AI SDK 6 (`streamText` + `stopWhen` + `fullStream`), with streamed output, a cost meter, a budget cap, Anthropic **prompt caching** on the static preamble, and rate-limit-aware retry/backoff (distinct from auth failures) with model fallback. |
93
- | **Tools** | `read_file` · `write_file` · `edit_file` (multi-tier matcher) · `list_dir` · `glob` · `grep` · `run_bash`, plus git tools — gated by a permission layer that denies destructive commands, protected paths, and paths outside the workspace/brain by default. Non-bash tools are timeout-guarded so a runaway read/grep can't hang the loop. |
104
+ | **Tools** | `read_file` · `write_file` · `edit_file` (multi-tier matcher) · `list_dir` · `glob` · `grep` · `run_bash` · `run_python` · `run_rust`, plus git tools — gated by a permission layer that denies destructive commands, protected paths, and paths outside the workspace/brain by default. Non-bash tools are timeout-guarded so a runaway read/grep can't hang the loop. |
94
105
  | **Sandbox** | `run_bash` is confined by an OS sandbox — **Seatbelt** on macOS, **bubblewrap** on Linux — so shell writes stay inside the workspace/brain/tmp (reads + network unaffected). Opt out with `SANOOK_NO_SANDBOX=1`. |
95
106
  | **Approval** | `ask` mode is the default and prompts `y/n` before any file write or shell command. `--yes` for auto-approve; headless ask-mode safely denies mutations when no approval UI exists. |
96
107
  | **Input** | Multiline editing, `↑`/`↓` persisted prompt history, readline keys (Ctrl-A/E/U/K/W), and `@file` mentions that inline a file's contents (or attach an **image** for vision-capable models). |
97
108
  | **Checkpoint** | A shadow-git snapshot is taken before each turn; `/rewind` restores the files **and** truncates the conversation — recoverable (it stashes the current state first). |
98
- | **Memory** | The agent writes its own notes (`remember`), recalls them across past sessions (`recall`), and `--continue` resumes the latest run for the current project. |
109
+ | **Memory** | The agent writes its own notes (`remember`), recalls them across past sessions (`recall`), `--continue` resumes the latest run for the current project, `--resume <id>` resumes a specific run, and `sanook sessions` audits/exports/renames/prunes saved conversations. |
110
+ | **Familiar CLI surfaces** | `sanook setup`, `sanook model`, `sanook auth`, `sanook chat -q`, `sanook gateway`, `sanook status`, `sanook sessions`, `sanook dump`, `sanook tools`, and `sanook send` provide familiar management entry points, all Sanook-branded. |
111
+ | **Startup cockpit** | The interactive REPL opens with a Sanook-branded wordmark, service routes (Code, Brain, Connect, Ship), and live readiness signals for second-brain, MCP servers, installed skills, and the current git branch. |
112
+ | **Web grounding** | `sanook web status` separates local brain search from true internet search, detects configured MCP web/search/fetch candidates, and prints Sanook's citation + prompt-injection policy for current external facts. |
99
113
  | **Repo map** | A lightweight symbol map of the repo (zero-dep, git-aware) is injected at session start so the agent picks the right files without blind grepping. |
100
114
  | **Skills** | Built-in skills + install your own from a GitHub repo, URL, or local path. The agent can also author new skills after a repeatable task. |
101
- | **Custom commands** | Drop a `.sanook/commands/<name>.md` prompt template and call it as `/<name>` (project commands require trust). |
115
+ | **Custom commands** | Drop a `.sanook/commands/<name>.md` prompt template and call it as `/<name>` (project commands require trust). Arguments replace `$ARGUMENTS` or `{{ args }}`; without a placeholder they are appended. |
102
116
  | **Subagents** | A `task` tool spawns a fresh-context sub-agent for scoped exploration without bloating the main context — read-only by default, depth-guarded. |
103
- | **Gateway + cron** | `sanook serve` runs a long-lived daemon: a loopback OpenAI-compatible HTTP endpoint plus a cron scheduler. Ask it in plain language and it schedules itself. |
104
- | **Channels** | A Telegram adapter (long-polling, no public URL) lets you drive the agent from your phone locked down with a required allowlist and private-chat-only policy. |
117
+ | **Gateway + cron** | `sanook gateway run` (alias: `sanook serve`) runs a long-lived daemon: a loopback OpenAI-compatible HTTP endpoint plus a cron scheduler. Scheduled tasks can use `--to` to deliver results back through the messaging gateway. |
118
+ | **Channels** | `sanook gateway setup telegram|discord|slack|mattermost|homeassistant|email|line|sms|ntfy|signal|whatsapp|matrix|googlechat|bluebubbles|teams|webhooks` stores messaging adapter config, and `sanook gateway run` starts Telegram long-polling, lightweight Discord Gateway / Slack Socket Mode / Mattermost REST+WebSocket adapters, Home Assistant state-change WebSocket filters, Email IMAP polling, LINE webhooks, Twilio SMS webhooks, ntfy topic streams, Signal via `signal-cli` HTTP/SSE, WhatsApp Cloud webhooks, Matrix Client-Server sync, and generic event webhooks when configured. Chat/event history is persisted per platform target, and final responses of `[SILENT]`, `SILENT`, `NO_REPLY`, or `NO REPLY` are stored but not delivered. `sanook send --to telegram|discord|slack|mattermost|homeassistant|email|line|sms|ntfy|signal|whatsapp|matrix|googlechat|bluebubbles|teams`, `sanook webhook subscribe`, and `sanook cron add --to ...` use the same outbound delivery rules. |
105
119
  | **MCP** | Connect any Model Context Protocol server over **stdio or remote Streamable-HTTP** (filesystem, GitHub, Postgres, hosted servers, …) via `~/.sanook/mcp.json`. |
106
120
  | **Git** | Branch, uncommitted changes, and recent commits are injected automatically, with `git_status` / `git_diff` / `git_log` / `git_commit` tools. |
107
121
  | **Hooks** | Run your own command before/after any tool. A non-zero `PreToolUse` exit blocks the tool — enforce lint, format, or policy. |
108
122
  | **Plan mode** | `--plan` restricts the agent to read-only tools and asks it to produce a plan before touching anything. |
109
123
  | **Auto-compaction** | A token-aware sliding window keeps long sessions under the context limit with zero extra LLM cost. |
124
+ | **Prompt budget inspectability** | `sanook prompt-size [--json]` reports the offline size of Sanook's system prompt, personality overlay, auto-memory, skills index, second-brain context, project memory, repo map, git context, and built-in tool schemas. |
125
+ | **Polyglot runtime surface** | `sanook runtimes [--json]` shows optional Python/Rust readiness. The agent gets `run_python` for data/document/ML-style helper scripts and `run_rust` for small performance/safety-critical helpers, both approval-gated and no-shell. |
110
126
  | **Second brain** | `sanook brain init` scaffolds a structured Obsidian "second-brain" workspace (folders + `_Index` + a portable AI operating constitution) for organising work and giving the agent durable, cross-session memory. |
111
127
 
112
128
  ## Providers
113
129
 
114
- One model spec, twelve providers. Switch with `-m <spec>` on the command line or `/model` in the REPL.
130
+ One model spec, nine providers. Switch with `-m <spec>` on the command line or `/model` in the REPL.
115
131
 
116
132
  | Provider | Spec example | Key |
117
133
  |---|---|---|
118
134
  | Anthropic (Claude) | `-m sonnet`, `-m opus`, `-m haiku` | `ANTHROPIC_API_KEY` |
119
135
  | Google (Gemini) | `-m gemini`, `-m google:gemini-2.5-flash` | `GOOGLE_GENERATIVE_AI_API_KEY` |
120
136
  | OpenAI | `-m gpt`, `-m openai:gpt-5.5` | `OPENAI_API_KEY` |
121
- | DeepSeek | `-m deepseek` | `DEEPSEEK_API_KEY` |
122
137
  | xAI (Grok) | `-m grok` | `XAI_API_KEY` |
123
138
  | Mistral | `-m mistral` | `MISTRAL_API_KEY` |
124
139
  | Groq | `-m groq:fast` | `GROQ_API_KEY` |
125
- | MiniMax | `-m minimax` | `MINIMAX_API_KEY` |
126
- | GLM (Zhipu) | `-m glm` | `ZHIPU_API_KEY` |
127
140
  | Ollama | `-m ollama` | — (local) |
128
141
  | LM Studio | `-m lmstudio` | — (local) |
129
142
  | OpenAI Codex | `-m codex` | via the official Codex CLI |
@@ -133,27 +146,51 @@ A spec is an alias (`sonnet`), a `provider:model-id` pair (`openai:gpt-5.5`), or
133
146
  ```bash
134
147
  sanook models # list all providers
135
148
  sanook models anthropic # curated ids (+ live verification if a key is set)
149
+ sanook auth list # redacted key status for every provider
150
+ sanook auth status openai # env/store/console details
136
151
  ```
137
152
 
138
153
  ## Usage
139
154
 
140
155
  ```
141
156
  sanook "<task>" run one task (headless)
157
+ sanook -z "<task>" one-shot final output (script-friendly)
158
+ sanook chat -q "<query>" direct one-shot query
142
159
  sanook interactive REPL
160
+ sanook setup [section] setup model/gateway/tools/agent/brain
161
+ sanook model choose provider + model
162
+ sanook status redacted install/config status
163
+ sanook auth list redacted provider key status
164
+ sanook auth add openai --api-key <key> [--use]
165
+ sanook sessions list saved sessions for this project
166
+ sanook sessions show <id>
167
+ sanook sessions export <id> [--format json|markdown] [--output path]
168
+ sanook sessions rename <id> <title>
169
+ sanook sessions stats [--all]
170
+ sanook sessions prune --keep N [--all] [--yes]
171
+ sanook sessions rm <id>
172
+ sanook dump [--show-keys] support dump (keys are still redacted)
173
+ sanook prompt-size [--json] inspect system/brain/skill/tool context budget
174
+ sanook runtimes [--json] inspect optional Python/Rust runtime surface
175
+ sanook web status [--json] inspect true web-search/fetch readiness
176
+ sanook web doctor [--json] probe web/search/fetch MCP candidates
143
177
  sanook -c "<task>" resume the latest session for this project
178
+ sanook --resume <id> resume a specific saved session
144
179
  sanook --continue-any resume the newest session across all projects
145
180
  sanook --plan "<task>" plan mode (read-only)
146
181
  sanook --json "<task>" JSONL output for scripts / CI
147
182
  sanook update update the CLI to the latest npm release
148
183
 
149
184
  -m, --model <spec> model or provider:model-id
185
+ --provider <id> provider shortcut for `sanook chat`
150
186
  -b, --budget <usd> stop when estimated cost exceeds this
151
187
  -y, --yes auto-approve tool calls (skip ask-mode)
188
+ --yolo alias for --yes
152
189
  -v, --version print version
153
190
  -h, --help show help
154
191
  ```
155
192
 
156
- **REPL slash commands:** `/model` · `/tools` · `/skills` · `/cost` · `/diff` · `/undo` · `/rewind` · `/clear` · `/compact` · `/help` · `/quit` — plus your own `.sanook/commands/*.md`. Input supports `↑`/`↓` history, `@file` mentions (text or image), and multiline (trailing `\` or Alt+Enter).
193
+ **REPL slash commands:** `/new` · `/reset` · `/status` · `/model` · `/personality` · `/platforms` · `/tools` · `/skills` · `/cost` · `/usage` · `/insights` · `/diff` · `/retry` · `/stop` · `/undo` · `/rewind` · `/clear` · `/compact` · `/compress` · `/help` · `/quit` — plus your own `.sanook/commands/*.md`. Input supports `↑`/`↓` history, `@file` mentions (text or image), and multiline (trailing `\` or Alt+Enter).
157
194
 
158
195
  ## Updating
159
196
 
@@ -170,11 +207,19 @@ When you launch the interactive TUI with plain `sanook`, the CLI checks for upda
170
207
 
171
208
  ## Gateway & scheduling
172
209
 
173
- `sanook serve` starts a single long-lived process that hosts an HTTP API, a cron scheduler, and optional chat channels — all driving the same agent core.
210
+ `sanook gateway run` starts a single long-lived foreground process that hosts an HTTP API, a cron scheduler, and optional chat channels — all driving the same agent core. `sanook gateway start` runs the same gateway in the background and records its pid/log path under `~/.sanook/gateway/`. `sanook serve` remains as a compatibility alias.
174
211
 
175
212
  ```bash
176
- sanook serve --port 8787 # HTTP (127.0.0.1 only) + scheduler
213
+ sanook gateway status # redacted gateway config + token path
214
+ sanook gateway run --port 8787 # HTTP (127.0.0.1 only) + scheduler
215
+ sanook gateway start --port 8787 # background process + pid/log tracking
216
+ sanook gateway stop
217
+ sanook gateway restart
218
+ sanook gateway install # write launchd/systemd helper file
219
+ sanook serve --port 8787 # compatibility alias
177
220
  sanook cron add "every 30m" "check the CI" # also "09:00", an ISO time, or "now"
221
+ sanook cron add "every 30m" "check the CI" --to slack:C01ABCDEF
222
+ sanook cron add "09:00" "summarise calendar" --to email:owner@example.com --model openai:gpt-5.1
178
223
  sanook cron list
179
224
  sanook cron rm <id>
180
225
  ```
@@ -194,17 +239,174 @@ curl http://127.0.0.1:8787/v1/chat/completions \
194
239
  | `POST` | `/v1/chat/completions` | run the agent (OpenAI-compatible) |
195
240
  | `GET` / `POST` | `/tasks` | list / enqueue scheduled tasks |
196
241
 
197
- ### Telegram channel
242
+ ### Messaging channels
243
+
244
+ Use the setup command, or set environment variables before `sanook gateway run`. Telegram uses long-polling (no public URL needed), Discord uses the Gateway websocket, Slack uses Socket Mode, Mattermost uses REST API v4 plus websocket events, Home Assistant uses `/api/websocket` for watched `state_changed` events plus REST `persistent_notification.create` for replies, Email uses IMAP polling plus SMTP threaded replies, LINE uses the official Messaging API webhook + Reply/Push endpoints, SMS uses Twilio Programmable Messaging with `X-Twilio-Signature` validation, ntfy uses the HTTP JSON stream + publish API, Signal uses `signal-cli daemon --http` with JSON-RPC + Server-Sent Events, WhatsApp Cloud uses Meta's official webhook + Graph Messages API, Matrix uses the Matrix Client-Server sync/send API, Google Chat uses incoming webhooks or service-account Chat REST API sends with Pub/Sub config saved for future inbound, BlueBubbles/iMessage uses the BlueBubbles REST API for outbound text with webhook settings saved for inbound parity, Microsoft Teams supports Incoming Webhook delivery and Graph chat/channel delivery, and generic Webhooks accept GitHub/GitLab/Jira/Stripe-style events with HMAC validation.
245
+
246
+ ```bash
247
+ sanook gateway setup # platform menu
248
+ sanook gateway setup telegram --bot-token 123:abc --allowed-chats 5222385839
249
+ sanook gateway setup discord --bot-token "$DISCORD_BOT_TOKEN" --channel 123456789012345678
250
+ sanook gateway setup slack --bot-token "$SLACK_BOT_TOKEN" --app-token "$SLACK_APP_TOKEN" --channel C01ABCDEF
251
+ sanook gateway setup mattermost --url https://mm.example.com --token "$MATTERMOST_TOKEN" \
252
+ --allowed-users user_id_1 --home-channel chan_home_id --thread-replies
253
+ sanook gateway setup homeassistant --url http://homeassistant.local:8123 --token "$HASS_TOKEN" \
254
+ --home-channel sanook_agent --watch-domains light,binary_sensor,climate
255
+ sanook gateway setup email --address bot@example.com --password "$EMAIL_PASSWORD" \
256
+ --imap-host imap.example.com --smtp-host smtp.example.com --home-address owner@example.com
257
+ sanook gateway setup line --channel-access-token "$LINE_CHANNEL_ACCESS_TOKEN" \
258
+ --channel-secret "$LINE_CHANNEL_SECRET" --home-channel U1234567890abcdef
259
+ sanook gateway setup sms --account-sid "$TWILIO_ACCOUNT_SID" --auth-token "$TWILIO_AUTH_TOKEN" \
260
+ --phone-number "$TWILIO_PHONE_NUMBER" --home-channel +15551234567 \
261
+ --webhook-url https://your-tunnel.example.com/sms/webhook
262
+ sanook gateway setup ntfy --topic sanook-yourname-2026 --token "$NTFY_TOKEN" --markdown
263
+ sanook gateway setup signal --account +15550000000 --home-channel +15551234567 \
264
+ --http-url http://127.0.0.1:8080
265
+ sanook gateway setup whatsapp --phone-number-id "$WHATSAPP_CLOUD_PHONE_NUMBER_ID" \
266
+ --access-token "$WHATSAPP_CLOUD_ACCESS_TOKEN" --app-secret "$WHATSAPP_CLOUD_APP_SECRET" \
267
+ --home-channel 15551234567 --public-url https://your-tunnel.example.com
268
+ sanook gateway setup matrix --homeserver https://matrix.example.org \
269
+ --access-token "$MATRIX_ACCESS_TOKEN" --allowed-users @alice:matrix.org \
270
+ --home-room '!abc123:matrix.example.org'
271
+ sanook gateway setup googlechat --service-account-json "$GOOGLE_CHAT_SERVICE_ACCOUNT_JSON" \
272
+ --home-channel spaces/AAAA --allowed-spaces spaces/AAAA
273
+ sanook gateway setup googlechat --incoming-webhook-url "$GOOGLE_CHAT_INCOMING_WEBHOOK_URL"
274
+ sanook gateway setup bluebubbles --server-url http://localhost:1234 --password "$BLUEBUBBLES_PASSWORD" \
275
+ --home-channel user@example.com --allowed-users user@example.com,+15551234567
276
+ sanook gateway setup teams --incoming-webhook-url "$TEAMS_INCOMING_WEBHOOK_URL"
277
+ sanook gateway setup teams --delivery-mode graph --graph-access-token "$TEAMS_GRAPH_ACCESS_TOKEN" \
278
+ --chat-id '19:chatid@thread.v2'
279
+ sanook gateway setup webhooks --secret "$WEBHOOK_SECRET" --public-url https://your-tunnel.example.com
280
+ sanook webhook subscribe github-issues --events issues \
281
+ --prompt "New issue #{issue.number}: {issue.title}\n{issue.html_url}" --to slack:C01ABCDEF
282
+ sanook webhook subscribe deploy-notify --events push --deliver-only \
283
+ --prompt "Push to {repository.full_name}: {head_commit.message}" --to sms
284
+ sanook gateway run
285
+ sanook send --to telegram "deploy finished"
286
+ sanook send --to discord "deploy finished"
287
+ sanook send --to slack:C01ABCDEF "deploy finished"
288
+ sanook send --to mattermost:chan_home_id "deploy finished"
289
+ sanook send --to homeassistant:doorbell "deploy finished"
290
+ sanook send --to email:owner@example.com --subject "[CI]" "deploy finished"
291
+ sanook send --to line "deploy finished"
292
+ sanook send --to sms "deploy finished"
293
+ sanook send --to ntfy "deploy finished"
294
+ sanook send --to signal "deploy finished"
295
+ sanook send --to whatsapp "deploy finished"
296
+ sanook send --to matrix "deploy finished"
297
+ sanook send --to matrix:'!ops:matrix.example.org' "deploy finished"
298
+ sanook send --to googlechat "deploy finished"
299
+ sanook send --to googlechat:spaces/AAAA/threads/thread-1 "threaded update"
300
+ sanook send --to bluebubbles "deploy finished"
301
+ sanook send --to bluebubbles:'iMessage;-;user@example.com' "deploy finished"
302
+ sanook send --to teams "deploy finished"
303
+ sanook send --to teams:'19:chatid@thread.v2' "deploy finished"
304
+ sanook cron add "every 30m" "check the CI" --to line
305
+ sanook cron add "09:00" "daily check-in" --to sms
306
+ sanook cron add "09:00" "daily check-in" --to ntfy
307
+ sanook cron add "09:00" "daily check-in" --to mattermost
308
+ sanook cron add "09:00" "daily check-in" --to homeassistant
309
+ sanook cron add "09:00" "daily check-in" --to signal
310
+ sanook cron add "09:00" "daily check-in" --to whatsapp
311
+ sanook cron add "09:00" "daily check-in" --to matrix
312
+ sanook cron add "09:00" "daily check-in" --to googlechat
313
+ sanook cron add "09:00" "daily check-in" --to bluebubbles
314
+ sanook cron add "09:00" "daily check-in" --to teams
315
+ sanook send --to telegram --subject "[CI]" --file build.log
316
+ echo "RAM 92%" | sanook send --to telegram --quiet
317
+ sanook send --to telegram:5222385839:17585 "threaded reply"
318
+ sanook webhook list
319
+ sanook webhook test github-issues --payload '{"event_type":"issues","issue":{"number":42,"title":"Test"}}'
320
+ sanook send --list --json
321
+ ```
198
322
 
199
- Set two environment variables before `sanook serve` and the gateway adds a Telegram adapter via long-polling (no public URL needed):
323
+ Environment overrides still work:
200
324
 
201
325
  ```bash
202
326
  export TELEGRAM_BOT_TOKEN=123:abc
203
327
  export TELEGRAM_ALLOWED_CHATS=5222385839 # required — comma-separated chat ids
204
- sanook serve
328
+ export LINE_CHANNEL_ACCESS_TOKEN=xxx
329
+ export LINE_HOME_CHANNEL=U1234567890abcdef
330
+ export TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
331
+ export TWILIO_AUTH_TOKEN=xxx
332
+ export TWILIO_PHONE_NUMBER=+15550000000
333
+ export SMS_HOME_CHANNEL=+15551234567
334
+ export SMS_WEBHOOK_URL=https://your-tunnel.example.com/sms/webhook
335
+ export NTFY_TOPIC=sanook-yourname-2026
336
+ export NTFY_ALLOWED_USERS=sanook-yourname-2026
337
+ export NTFY_HOME_CHANNEL=sanook-yourname-2026
338
+ export MATTERMOST_URL=https://mm.example.com
339
+ export MATTERMOST_TOKEN=xxx
340
+ export MATTERMOST_HOME_CHANNEL=chan_home_id
341
+ export MATTERMOST_ALLOWED_USERS=user_id_1,user_id_2
342
+ export MATTERMOST_ALLOWED_CHANNELS=chan_home_id,chan_ops_id
343
+ export MATTERMOST_REQUIRE_MENTION=true
344
+ export MATTERMOST_REPLY_MODE=thread
345
+ export HASS_URL=http://homeassistant.local:8123
346
+ export HASS_TOKEN=xxx
347
+ export HASS_HOME_CHANNEL=sanook_agent
348
+ export HASS_WATCH_DOMAINS=light,binary_sensor,climate
349
+ export HASS_WATCH_ENTITIES=sensor.temp,alarm_control_panel.home
350
+ export HASS_COOLDOWN_SECONDS=30
351
+ export SIGNAL_HTTP_URL=http://127.0.0.1:8080
352
+ export SIGNAL_ACCOUNT=+15550000000
353
+ export SIGNAL_HOME_CHANNEL=+15551234567
354
+ export SIGNAL_ALLOWED_USERS=+15551234567
355
+ export SIGNAL_GROUP_ALLOWED_USERS=groupIdBase64
356
+ export WHATSAPP_CLOUD_PHONE_NUMBER_ID=123456789012345
357
+ export WHATSAPP_CLOUD_ACCESS_TOKEN=EAA...
358
+ export WHATSAPP_CLOUD_APP_SECRET=xxx
359
+ export WHATSAPP_CLOUD_VERIFY_TOKEN=choose-a-long-random-token
360
+ export WHATSAPP_CLOUD_HOME_CHANNEL=15551234567
361
+ export WHATSAPP_CLOUD_ALLOWED_USERS=15551234567,15557654321
362
+ export WHATSAPP_CLOUD_PUBLIC_URL=https://your-tunnel.example.com
363
+ export WHATSAPP_CLOUD_API_VERSION=v20.0
364
+ export MATRIX_HOMESERVER=https://matrix.example.org
365
+ export MATRIX_ACCESS_TOKEN=syt_...
366
+ export MATRIX_USER_ID=@sanook:matrix.example.org
367
+ export MATRIX_HOME_ROOM='!abc123:matrix.example.org'
368
+ export MATRIX_ALLOWED_USERS=@alice:matrix.org,@bob:matrix.org
369
+ export MATRIX_ALLOWED_ROOMS='!abc123:matrix.example.org,!ops:matrix.example.org'
370
+ export MATRIX_REQUIRE_MENTION=true
371
+ export MATRIX_FREE_RESPONSE_ROOMS='!free:matrix.example.org'
372
+ export TEAMS_DELIVERY_MODE=incoming_webhook
373
+ export TEAMS_INCOMING_WEBHOOK_URL=https://...
374
+ export TEAMS_GRAPH_ACCESS_TOKEN=xxx
375
+ export TEAMS_CHAT_ID='19:chatid@thread.v2'
376
+ export TEAMS_HOME_CHANNEL='19:chatid@thread.v2'
377
+ export WEBHOOK_ENABLED=true
378
+ export WEBHOOK_SECRET=xxx
379
+ export WEBHOOK_PUBLIC_URL=https://your-tunnel.example.com
380
+ sanook gateway run
205
381
  ```
206
382
 
207
- The channel is **fail-closed**: with no allowlist it refuses to start, it accepts private chats only, and it never leaks internal errors back to the sender. See [Security](#security).
383
+ Messaging channels are **fail-closed** by default: configure a home target or allowlist before accepting remote users, and internal errors are redacted before they reach chat surfaces. See [Security](#security).
384
+
385
+ Inside Telegram/Discord/Slack/Mattermost/Email/LINE/SMS/ntfy/Signal/WhatsApp/Matrix conversations, Hermes-style commands are handled without calling the model: `/new`, `/reset`, `/model`, `/personality`, `/retry`, `/undo`, `/compress`, `/usage`, `/insights`, `/stop`, `/status`, `/sethome`, and `/help`. Matrix and Mattermost also accept `!new`, `!reset`, `!status`, and `!help` aliases for clients that reserve `/`.
386
+
387
+ For ntfy, the topic is the identity and trust boundary: use a long random topic, a private/reserved topic with `NTFY_TOKEN`, or a self-hosted ntfy server with ACLs. Sanook authorizes inbound ntfy messages by topic, not by the user-controlled notification title.
388
+
389
+ For Mattermost, use a dedicated bot account/token, set `MATTERMOST_ALLOWED_USERS` to Mattermost user IDs, and optionally restrict shared channels with `MATTERMOST_ALLOWED_CHANNELS`. DMs respond without a mention; public/private channels require `@botname` unless `MATTERMOST_REQUIRE_MENTION=false` or the channel is listed in `MATTERMOST_FREE_RESPONSE_CHANNELS`. Cron/send uses `MATTERMOST_HOME_CHANNEL`, `mattermost:channel_id`, or `mattermost:channel_id:root_post_id` for a threaded reply.
390
+
391
+ For Home Assistant, create a Long-Lived Access Token, keep `HASS_WATCH_DOMAINS`/`HASS_WATCH_ENTITIES` narrow, and use `HASS_IGNORE_ENTITIES` plus `HASS_COOLDOWN_SECONDS` for noisy sensors. No state events are forwarded unless a watch filter or `HASS_WATCH_ALL=true` is configured. Conversation tools can read entities/states/services, while `ha_call_service` is approval-gated and blocks unsafe domains such as `shell_command`, `command_line`, `python_script`, `pyscript`, `hassio`, and `rest_command`.
392
+
393
+ For Signal, run `signal-cli daemon --http 127.0.0.1:8080` locally, set `SIGNAL_ACCOUNT`, and keep `SIGNAL_ALLOWED_USERS` or `SIGNAL_HOME_CHANNEL` set so inbound DMs fail closed. Groups are disabled unless explicitly listed in `SIGNAL_GROUP_ALLOWED_USERS` or set to `*`; group send targets use `signal:group:<groupId>`.
394
+
395
+ For WhatsApp Cloud inbound messages, expose the gateway through a tunnel and set the Meta webhook callback URL to `https://<your-tunnel>/whatsapp/webhook`. Use the generated verify token for Meta's GET challenge, keep `WHATSAPP_CLOUD_APP_SECRET` set so Sanook can validate `X-Hub-Signature-256`, and check `GET /whatsapp/webhook/health` first. Send targets use country-code digits without `+` (for example `whatsapp:15551234567`), and normal WhatsApp 24-hour customer-service window limits still apply.
396
+
397
+ For Matrix, create a bot account on your homeserver, copy an access token from Element (or use `MATRIX_USER_ID` + `MATRIX_PASSWORD`), invite the bot to rooms, and keep `MATRIX_ALLOWED_USERS` set so inbound users fail closed. DMs respond without a mention; shared rooms require a bot mention unless `MATRIX_REQUIRE_MENTION=false` or the room is listed in `MATRIX_FREE_RESPONSE_ROOMS`. Cron/send uses `MATRIX_HOME_ROOM` or an explicit target like `matrix:!abc123:matrix.example.org`.
398
+
399
+ For Google Chat, use `GOOGLE_CHAT_INCOMING_WEBHOOK_URL` for the fastest proactive send path, or configure `GOOGLE_CHAT_SERVICE_ACCOUNT_JSON` plus `GOOGLE_CHAT_HOME_CHANNEL` (`spaces/...`) for Chat REST API delivery. Pub/Sub fields (`GOOGLE_CHAT_PROJECT_ID`, `GOOGLE_CHAT_SUBSCRIPTION_NAME`, `GOOGLE_CHAT_ALLOWED_USERS`) are saved now for inbound parity work. Cron/send uses `googlechat`, `googlechat:spaces/...`, or `googlechat:spaces/.../threads/...`.
400
+
401
+ For BlueBubbles/iMessage, run a BlueBubbles Server and configure `BLUEBUBBLES_SERVER_URL`, `BLUEBUBBLES_PASSWORD`, and `BLUEBUBBLES_HOME_CHANNEL` (chat GUID, email, or `+E.164` phone). Sanook resolves email/phone targets through `/api/v1/chat/query`, sends text via `/api/v1/message/text`, and keeps webhook fields (`BLUEBUBBLES_WEBHOOK_HOST`, `BLUEBUBBLES_WEBHOOK_PORT`, `BLUEBUBBLES_WEBHOOK_PATH`, mention gating) ready for inbound parity work.
402
+
403
+ For Microsoft Teams, use `TEAMS_DELIVERY_MODE=incoming_webhook` with a channel Incoming Webhook for simple proactive send/cron delivery, or `TEAMS_DELIVERY_MODE=graph` with `TEAMS_GRAPH_ACCESS_TOKEN` plus `TEAMS_CHAT_ID` or `TEAMS_TEAM_ID` + `TEAMS_CHANNEL_ID`. Teams chat IDs can contain colons, so quote explicit targets such as `teams:'19:chatid@thread.v2'` in shells.
404
+
405
+ For LINE inbound messages, expose the gateway through a tunnel and set the LINE Developers Console webhook URL to `https://<your-tunnel>/line/webhook`. Check the tunnel with `GET /line/webhook/health` first.
406
+
407
+ For SMS inbound messages, expose the gateway through a tunnel and set the Twilio Messaging webhook URL to `https://<your-tunnel>/sms/webhook`. Set `SMS_WEBHOOK_URL` to that exact URL so Sanook can validate `X-Twilio-Signature`; check `GET /sms/webhook/health` first.
408
+
409
+ For generic webhooks, create routes with `sanook webhook subscribe <route>` and point external services at `https://<your-tunnel>/webhooks/<route>`. Sanook accepts GitHub `X-Hub-Signature-256`, GitLab `X-Gitlab-Token`, or generic `X-Webhook-Signature`; check `GET /webhooks/health` first.
208
410
 
209
411
  ## Skills
210
412
 
@@ -229,7 +431,7 @@ sanook brain init # interactive — asks where + a few identity
229
431
  sanook brain init ~/notes/brain # non-interactive (with --yes)
230
432
  ```
231
433
 
232
- It creates a full folder taxonomy (`Projects/`, `Sessions/`, `Shared/` memory layer, `Goals/`, `Research/`, `Skills/`, …), an `_Index.md` in every folder, seed memory files, and a portable AI **operating constitution** (`CLAUDE.md` / `GEMINI.md` / `AGENTS.md`) so any AI agent works with the vault consistently. It ships with research-backed operating rules — context-assembly (anti context-rot), an intake quarantine + injection-scan gate, bi-temporal fact validity, provenance tracking, a verification-gated `Skills/` library, and sleep-time consolidation. The first-run setup wizard also offers to create one.
434
+ It creates a full folder taxonomy (`Projects/`, `Sessions/`, `Shared/` memory layer, `Goals/`, `Research/`, `Skills/`, …), an `_Index.md` in every folder, seed memory files, and a portable AI **operating constitution** (`CLAUDE.md` / `GEMINI.md` / `AGENTS.md` / `SANOOK.md`) so any AI agent works with the vault consistently. It ships with research-backed operating rules — context-assembly (anti context-rot), an intake quarantine + injection-scan gate, bi-temporal fact validity, provenance tracking, a verification-gated `Skills/` library, and sleep-time consolidation. The first-run setup wizard also offers to create one.
233
435
 
234
436
  Everything is **create-if-missing** — re-running never overwrites your notes. Point an Obsidian or filesystem MCP server at the workspace to let the agent read and write it.
235
437
 
@@ -263,9 +465,23 @@ Connect Model Context Protocol servers over **stdio or remote Streamable-HTTP**
263
465
  }
264
466
  ```
265
467
 
266
- Add servers from the CLI too: `sanook mcp add fs npx -y @modelcontextprotocol/server-filesystem /path` (stdio) or `sanook mcp add remote https://example.com/mcp` (a URL is detected as remote HTTP).
468
+ Discover and install servers from the official MCP registry:
469
+
470
+ ```bash
471
+ sanook mcp search gitlab
472
+ sanook mcp info com.gitlab/mcp
473
+ sanook mcp install com.gitlab/mcp --name gitlab
474
+ sanook mcp preset dev
475
+ sanook mcp preset research
476
+ sanook mcp test gitlab
477
+ sanook mcp doctor
478
+ sanook web status
479
+ sanook web doctor
480
+ ```
481
+
482
+ Use `--env KEY=value` or `--header KEY=value` when a registry entry requires secrets, and `--project` to write to a trusted project `.sanook/mcp.json`. Some hosted MCP endpoints may return `401 Unauthorized` until you pass an auth header, even when the registry entry does not declare it yet. You can still add servers manually: `sanook mcp add fs npx -y @modelcontextprotocol/server-filesystem /path` (stdio) or `sanook mcp add remote https://example.com/mcp` (a URL is detected as remote HTTP).
267
483
 
268
- Their tools are merged into the agent's toolset automatically. `/tools` in the REPL lists everything currently available.
484
+ Their tools are merged into the agent's toolset automatically. `/tools` in the REPL lists everything currently available. `sanook search` is local retrieval over the second brain, sessions, memory, and skills; true internet search comes from configured MCP web/search/fetch servers. Use `sanook web status` to see which web candidates are configured, and `sanook web doctor` to probe their advertised tools.
269
485
 
270
486
  sanook is also an MCP **server**: `sanook mcp serve` exposes your brain (`sanook_search` / `sanook_recall` / `sanook_remember` / `sanook_index` / `sanook_stats`) over stdio, so Claude Desktop, Cursor, or any MCP host can query it:
271
487
 
@@ -308,10 +524,13 @@ Quality-neutral knobs in `~/.sanook/config.json` (or the matching `SANOOK_*` env
308
524
  | `config set …` | env | effect |
309
525
  |---|---|---|
310
526
  | `cacheTtl 1h` | `SANOOK_CACHE_TTL=1h` | keep the cached system preamble alive for 1h (default `5m`) — cheaper to resume after a pause |
527
+ | `contextCompression selective` | `SANOOK_CONTEXT_COMPRESSION=selective` | zero-LLM, query-aware selective compression for stale, very large tool outputs before each model step (default `selective`; set `off` to disable) |
528
+ | `contextCompression headroom` | `SANOOK_CONTEXT_COMPRESSION=headroom` | wrap the Vercel AI SDK model with `headroom-ai` when you run a Headroom proxy/cloud setup (`SANOOK_HEADROOM_BASE_URL` / `SANOOK_HEADROOM_API_KEY`) |
311
529
  | `compaction summarize` | `SANOOK_COMPACTION=summarize` | when context gets long, condense it with a **cheap model** instead of truncating — better recall at the same budget (default `truncate`, zero-LLM) |
312
530
  | — | `SANOOK_SUBAGENT_MODEL=haiku` | run all sub-agent work (exploration/search) on a cheaper model while the main agent keeps the strong one |
313
531
  | `summaryModel <spec>` | `SANOOK_SUMMARY_MODEL=<spec>` | model used for summarize-compaction (default: the fast sibling of your main model) |
314
- | `thinking 4000` | `SANOOK_THINKING=4000` | opt-in Anthropic extended thinking on the main agent with a `budgetTokens` cap (default off) |
532
+ | `embeddingModel <spec>` | `SANOOK_EMBEDDING_MODEL=<spec>` | model used for semantic search embeddings (for example `openai:text-embedding-3-small`) |
533
+ | `thinking on` / `thinking 4000` | `SANOOK_THINKING=on` / `4000` | opt-in Anthropic extended thinking on the main agent; use `on`, `true`, or `yes` for the default budget, `off`, `false`, or `no` to disable, or a positive integer for `budgetTokens` |
315
534
 
316
535
  Read-side savings are automatic: the agent reads file ranges (`read_file` with `offset`/`limit`) and edits with minimal `old_string` / `replace_all` rather than rewriting whole files.
317
536
 
@@ -322,7 +541,7 @@ SANOOK_MODEL=sonnet # default model alias or provider:model
322
541
  SANOOK_ALLOW_OUTSIDE_WORKSPACE=1 # allow file tools outside cwd/brain
323
542
  SANOOK_GATEWAY_ALLOW_WRITE=1 # let sanook serve run mutating tools unattended
324
543
  SANOOK_HOOKS_INHERIT_ENV=1 # pass full env to hooks instead of a minimal safe env
325
- SANOOK_DISABLE_PERSISTENCE=1 # do not save sessions or memory
544
+ SANOOK_DISABLE_PERSISTENCE=1 # do not save sessions, memory, prompt history, or worklogs
326
545
  SANOOK_DISABLE_UPDATE_CHECK=1 # do not show interactive update prompts
327
546
  SANOOK_DISABLE_WORKLOG=1 # do not append second-brain worklogs
328
547
  SANOOK_TRUST_PROJECT=1 # temporary trust override for project .sanook extensions
@@ -340,6 +559,16 @@ Sanook runs shell commands and edits files, so safety is built into the core rat
340
559
  - **Safe fallback** — provider fallback does not retry after a mutating tool call has already happened, avoiding duplicate side effects.
341
560
  - **Gateway** — HTTP binds to `127.0.0.1` only and requires a bearer token on every non-health endpoint.
342
561
  - **Telegram** — fail-closed: a required allowlist, private-chat-only, per-chat rate-limiting, and generic error replies that never reveal internal paths.
562
+ - **Email** — use a dedicated mailbox and app password; store only app passwords, require an allowlist/home address by default, and keep SMTP/IMAP credentials in `~/.sanook/gateway/config.json` (chmod 600).
563
+ - **LINE** — use a long-lived Messaging API channel access token, keep a home/allowed target list by default, and store the token/secret in `~/.sanook/gateway/config.json` (chmod 600).
564
+ - **ntfy** — treat the topic as a shared secret unless you protect it with ntfy auth/ACLs; Sanook requires `NTFY_ALLOWED_USERS`/home topic or `NTFY_ALLOW_ALL_USERS` before subscribing.
565
+ - **Mattermost** — use a dedicated bot token, require `MATTERMOST_ALLOWED_USERS` by default, optionally restrict channels with `MATTERMOST_ALLOWED_CHANNELS`, and keep public/private channels on mention-only mode unless you deliberately list free-response channels.
566
+ - **Home Assistant** — use a dedicated Long-Lived Access Token, keep watch filters narrow, leave `HASS_WATCH_ALL` off by default, and require approval for device-control calls through `ha_call_service`.
567
+ - **Signal** — keep `signal-cli` HTTP bound to loopback, require DM allowlists by default, and enable groups only with `SIGNAL_GROUP_ALLOWED_USERS` (or `*` deliberately).
568
+ - **WhatsApp Cloud** — use a dedicated Meta app/access token, keep `WHATSAPP_CLOUD_APP_SECRET` and a long verify token configured, require home/allowed wa_ids by default, and verify every inbound POST with `X-Hub-Signature-256`.
569
+ - **Matrix** — use a dedicated bot account/access token, require `MATRIX_ALLOWED_USERS` by default, optionally restrict shared rooms with `MATRIX_ALLOWED_ROOMS`, and treat password login as a convenience fallback rather than the preferred production mode.
570
+ - **Google Chat** — keep service account JSON files chmod 600, do not paste private keys into shell history, keep incoming webhook URLs out of logs/support dumps, and restrict proactive sends with `GOOGLE_CHAT_HOME_CHANNEL` or `GOOGLE_CHAT_ALLOWED_SPACES`.
571
+ - **Microsoft Teams** — prefer narrowly scoped Graph permissions or a dedicated channel Incoming Webhook, keep tokens out of logs/support dumps, and treat `TEAMS_CLIENT_SECRET` as future inbound bot credential material.
343
572
 
344
573
  Hardened across several adversarial security reviews covering command injection, prompt injection, concurrency, and credential leakage.
345
574
 
package/README.th.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **AI coding agent ใน terminal ที่ "จำงานข้ามวันได้" — open-source**
6
6
 
7
- ใส่ API key ของคุณเอง (BYOK) · 12 providers · MCP · มี **"สมองที่สอง" (second brain)** ที่ทำให้ AI จำ context ข้าม session ได้ — สิ่งที่ Claude Code / Codex / Gemini CLI ลืมทุกครั้งที่ปิด terminal
7
+ ใส่ API key ของคุณเอง (BYOK) · 9 providers · MCP · มี **"สมองที่สอง" (second brain)** ที่ทำให้ AI จำ context ข้าม session ได้ — สิ่งที่ Claude Code / Codex / Gemini CLI ลืมทุกครั้งที่ปิด terminal
8
8
 
9
9
  [![npm](https://img.shields.io/npm/v/sanook-cli.svg?color=2563eb)](https://www.npmjs.com/package/sanook-cli)
10
10
  [![downloads](https://img.shields.io/npm/dm/sanook-cli.svg?color=2563eb)](https://www.npmjs.com/package/sanook-cli)
@@ -39,9 +39,13 @@ npm install -g sanook-cli
39
39
  > แก้: ลงใหม่ด้วย `npm install -g sanook-cli` · หรือเรียกผ่าน **`npx sanook`** (ใช้ตัวที่ลง local ไปแล้วได้เลย)
40
40
  > หรือรัน **`npx sanook doctor`** — ตรวจ Node/PATH/สถานะการติดตั้งให้ แล้วบอกคำสั่งแก้ที่ตรงกับ OS (มีบรรทัดแก้ PATH บน Windows แบบปลอดภัยให้ก็อปด้วย)
41
41
 
42
- ตั้ง API key (หรือรัน `sanook` เฉย ๆ ครั้งแรกจะมี setup wizard ให้เลือก provider + วาง key):
42
+ เริ่มด้วย setup wizard แบบเป็นทางการ หรือจะตั้ง API key เองก็ได้:
43
43
 
44
44
  ```bash
45
+ sanook setup # เลือก provider + model และเสนอสร้าง second brain
46
+ sanook model # กลับมาเปลี่ยน provider/model ภายหลัง
47
+ sanook auth add anthropic --api-key sk-ant-... --use
48
+
45
49
  # macOS / Linux
46
50
  export ANTHROPIC_API_KEY=sk-ant-...
47
51
 
@@ -54,16 +58,87 @@ setx ANTHROPIC_API_KEY "sk-ant-..."
54
58
  ```bash
55
59
  sanook # REPL (ครั้งแรก = setup wizard)
56
60
  sanook "อ่าน package.json แล้วบอกว่ามี dependencies อะไรบ้าง"
61
+ sanook chat -q "อ่าน package.json แล้วสรุป dependencies" --provider anthropic
62
+ sanook -z "สรุป diff นี้" # one-shot เฉพาะคำตอบสุดท้าย เหมาะกับ script
63
+ sanook status # ดู provider/key/brain/gateway แบบ redact secret
64
+ sanook sessions # ดู saved sessions ของ project นี้
65
+ sanook --resume <session_id> "ทำต่อจาก session นี้"
66
+ sanook dump # diagnostic/support snapshot โดยไม่โชว์ raw secret
57
67
  sanook -c "ทำต่อจาก session ล่าสุดของ project นี้"
58
68
  sanook --continue-any "ทำต่อจาก session ล่าสุดข้าม project"
59
69
  ```
60
70
 
71
+ ตัวอย่างตั้งค่า messaging:
72
+
73
+ ```bash
74
+ sanook gateway setup line --channel-access-token "$LINE_CHANNEL_ACCESS_TOKEN" \
75
+ --channel-secret "$LINE_CHANNEL_SECRET" --home-channel U1234567890abcdef
76
+ sanook gateway setup sms --account-sid "$TWILIO_ACCOUNT_SID" --auth-token "$TWILIO_AUTH_TOKEN" \
77
+ --phone-number "$TWILIO_PHONE_NUMBER" --home-channel +15551234567 \
78
+ --webhook-url https://your-tunnel.example.com/sms/webhook
79
+ sanook gateway setup ntfy --topic sanook-yourname-2026 --token "$NTFY_TOKEN" --markdown
80
+ sanook gateway setup mattermost --url https://mm.example.com --token "$MATTERMOST_TOKEN" \
81
+ --allowed-users user_id_1 --home-channel chan_home_id --thread-replies
82
+ sanook gateway setup homeassistant --url http://homeassistant.local:8123 --token "$HASS_TOKEN" \
83
+ --home-channel sanook_agent --watch-domains light,binary_sensor,climate
84
+ sanook gateway setup signal --account +15550000000 --home-channel +15551234567 \
85
+ --http-url http://127.0.0.1:8080
86
+ sanook gateway setup whatsapp --phone-number-id "$WHATSAPP_CLOUD_PHONE_NUMBER_ID" \
87
+ --access-token "$WHATSAPP_CLOUD_ACCESS_TOKEN" --app-secret "$WHATSAPP_CLOUD_APP_SECRET" \
88
+ --home-channel 15551234567 --public-url https://your-tunnel.example.com
89
+ sanook gateway setup matrix --homeserver https://matrix.example.org \
90
+ --access-token "$MATRIX_ACCESS_TOKEN" --allowed-users @alice:matrix.org \
91
+ --home-room '!abc123:matrix.example.org'
92
+ sanook gateway setup googlechat --service-account-json "$GOOGLE_CHAT_SERVICE_ACCOUNT_JSON" \
93
+ --home-channel spaces/AAAA --allowed-spaces spaces/AAAA
94
+ sanook gateway setup googlechat --incoming-webhook-url "$GOOGLE_CHAT_INCOMING_WEBHOOK_URL"
95
+ sanook gateway setup bluebubbles --server-url http://localhost:1234 --password "$BLUEBUBBLES_PASSWORD" \
96
+ --home-channel user@example.com --allowed-users user@example.com,+15551234567
97
+ sanook gateway setup teams --incoming-webhook-url "$TEAMS_INCOMING_WEBHOOK_URL"
98
+ sanook gateway setup webhooks --secret "$WEBHOOK_SECRET" --public-url https://your-tunnel.example.com
99
+ sanook webhook subscribe github-issues --events issues \
100
+ --prompt "Issue #{issue.number}: {issue.title}" --to slack:C01ABCDEF
101
+ sanook send --to sms "deploy finished"
102
+ sanook send --to ntfy "deploy finished"
103
+ sanook send --to mattermost "deploy finished"
104
+ sanook send --to homeassistant "deploy finished"
105
+ sanook send --to signal "deploy finished"
106
+ sanook send --to whatsapp "deploy finished"
107
+ sanook send --to matrix "deploy finished"
108
+ sanook send --to googlechat "deploy finished"
109
+ sanook send --to bluebubbles "deploy finished"
110
+ sanook send --to teams "deploy finished"
111
+ sanook cron add "09:00" "สรุปงานเช้านี้" --to ntfy
112
+ sanook cron add "09:00" "สรุปงานเช้านี้" --to mattermost
113
+ sanook cron add "09:00" "สรุปงานเช้านี้" --to homeassistant
114
+ sanook cron add "09:00" "สรุปงานเช้านี้" --to whatsapp
115
+ sanook cron add "09:00" "สรุปงานเช้านี้" --to matrix
116
+ sanook cron add "09:00" "สรุปงานเช้านี้" --to googlechat
117
+ sanook cron add "09:00" "สรุปงานเช้านี้" --to bluebubbles
118
+ sanook cron add "09:00" "สรุปงานเช้านี้" --to teams
119
+ ```
120
+
121
+ ใน Telegram/Discord/Slack/Mattermost/Email/LINE/SMS/ntfy/Signal/WhatsApp/Matrix ใช้คำสั่งสไตล์ Hermes ได้โดยไม่เรียก model: `/new`, `/reset`, `/model`, `/personality`, `/retry`, `/undo`, `/compress`, `/usage`, `/insights`, `/stop`, `/status`, `/sethome`, และ `/help`; Matrix/Mattermost ใช้ `!new`, `!reset`, `!status`, `!help` ได้ด้วยสำหรับ client ที่กันคำสั่ง `/`
122
+
123
+ Home Assistant ใช้ Long-Lived Access Token, รับเฉพาะ `state_changed` ที่ตรง `--watch-domains`, `--watch-entities` หรือ `--watch-all`, และตอบกลับผ่าน persistent notification (`homeassistant[:notification_id]`). Tools อ่านสถานะ/บริการได้ ส่วน `ha_call_service` ต้องผ่าน approval และ block domain เสี่ยงเช่น `shell_command`, `command_line`, `python_script`, `pyscript`, `hassio`, `rest_command`
124
+
125
+ Google Chat ตอนนี้รองรับ proactive delivery/cron ผ่าน incoming webhook (`googlechat`) หรือ Service Account + Chat REST API (`googlechat:spaces/...`). ค่าของ Pub/Sub (`GOOGLE_CHAT_PROJECT_ID`, `GOOGLE_CHAT_SUBSCRIPTION_NAME`, `GOOGLE_CHAT_ALLOWED_USERS`) บันทึกไว้เพื่อทำ inbound parity ต่อ
126
+
127
+ BlueBubbles/iMessage ตอนนี้รองรับ proactive delivery/cron ผ่าน BlueBubbles REST API (`bluebubbles`, `imessage:user@example.com`, หรือ raw chat GUID). ใช้ `sanook gateway setup bluebubbles --server-url ... --password ... --home-channel ...`; ค่า webhook/mention (`BLUEBUBBLES_WEBHOOK_*`, `BLUEBUBBLES_REQUIRE_MENTION`) ถูกบันทึกไว้เพื่อทำ inbound parity ต่อ
128
+
129
+ Microsoft Teams ตอนนี้รองรับ proactive delivery/cron ผ่าน Incoming Webhook (`teams`) หรือ Graph mode (`teams:'19:chatid@thread.v2'`). ใช้ `sanook gateway setup teams --incoming-webhook-url ...` สำหรับเริ่มง่ายที่สุด
130
+
61
131
  ## ทำอะไรได้บ้าง
62
132
 
63
- - **BYOK + 12 providers** — Anthropic, Google, OpenAI, DeepSeek, xAI, Mistral, Groq, MiniMax, GLM, Ollama, LM Studio, Codex
133
+ - **BYOK + 9 providers** — Anthropic, Google, OpenAI, xAI, Mistral, Groq, Ollama, LM Studio, Codex
134
+ - **Familiar CLI** — `sanook setup`, `sanook model`, `sanook auth`, `sanook chat -q`, `sanook gateway`, `sanook status`, `sanook sessions`, `sanook dump`, `sanook tools`, `sanook send`
64
135
  - **Second brain** — `sanook brain init` สร้าง workspace Obsidian ให้ AI จำงานข้ามวัน
65
- - **Tools** — อ่าน/เขียน/แก้ไฟล์ · รัน bash · git · grep/glob พร้อม permission gate
66
- - **Gateway + cron** — `sanook serve` รันเป็น service 24/7 + ตั้งงานล่วงหน้า + ต่อ Telegram
136
+ - **Startup cockpit** — เปิด `sanook` แล้วเห็น wordmark, service routes (Code, Brain, Connect, Ship), และสัญญาณ readiness จริงของ second-brain, MCP, skills, git branch ทันที
137
+ - **Web grounding** — `sanook web status` แยก local brain search ออกจาก true internet search, ตรวจ MCP web/search/fetch ที่ตั้งไว้, และโชว์ policy เรื่อง citation + prompt-injection จากเว็บ
138
+ - **Tools** — อ่าน/เขียน/แก้ไฟล์ · รัน bash/Python/Rust แบบ approval-gated · git · grep/glob พร้อม permission gate
139
+ - **Polyglot runtime** — TypeScript เป็น control plane หลัก; Python ใช้กับ data/document/ML helper ผ่าน `run_python`; Rust ใช้กับ helper ที่ต้องเร็ว/type-safe ผ่าน `run_rust`; ไม่มี runtime ก็ไม่ทำให้ Sanook install พัง
140
+ - **Gateway + cron** — `sanook gateway run` (alias: `sanook serve`) รัน 24/7 + ตั้งงานล่วงหน้า + ต่อ Telegram/Discord/Slack/Mattermost/Home Assistant/Email/LINE/SMS/ntfy/Signal/WhatsApp/Matrix/Google Chat/BlueBubbles/Teams/Webhooks; task ใช้ `--to` เพื่อส่งผลลัพธ์กลับไปยัง messaging target ได้
141
+ - **Messaging setup/send** — `sanook gateway setup telegram|discord|slack|mattermost|homeassistant|email|line|sms|ntfy|signal|whatsapp|matrix|googlechat|bluebubbles|teams|webhooks` บันทึก token/allowlist หรือ SMTP/IMAP/LINE/Twilio/ntfy/Mattermost/Home Assistant/Signal/WhatsApp/Matrix/Google Chat/BlueBubbles/Teams/Webhook config; `sanook gateway run` เริ่ม Telegram long-polling, Discord Gateway, Slack Socket Mode, Mattermost REST/WebSocket, Home Assistant state-change WebSocket, Email IMAP polling + SMTP threaded replies, LINE webhook, Twilio SMS webhook, ntfy topic stream, Signal ผ่าน `signal-cli` HTTP/SSE, WhatsApp Cloud webhook + Graph Messages API, Matrix Client-Server sync/send, Google Chat outbound ผ่าน incoming webhook/Chat REST API, BlueBubbles outbound ผ่าน REST API, Teams Incoming Webhook/Graph delivery และ generic webhooks เมื่อ config พร้อม; history ถูกเก็บต่อ platform/target และถ้าคำตอบสุดท้ายเป็น `[SILENT]`, `SILENT`, `NO_REPLY`, หรือ `NO REPLY` จะบันทึกไว้แต่ไม่ส่งกลับ; `sanook send --to telegram|discord|slack|mattermost|homeassistant|email|line|sms|ntfy|signal|whatsapp|matrix|googlechat|bluebubbles|teams "..."`, `sanook webhook subscribe` และ `sanook cron add --to ...` ใช้กฎส่งออกชุดเดียวกัน
67
142
  - **MCP + Skills** — ต่อ MCP server ได้ + มี built-in skills และติดตั้งเพิ่มได้
68
143
  - **Update ง่าย** — ใช้ `sanook update` เพื่ออัปเดต CLI เป็นเวอร์ชันล่าสุดจาก npm
69
144
 
@@ -72,8 +147,21 @@ sanook --continue-any "ทำต่อจาก session ล่าสุดข้
72
147
  ```bash
73
148
  sanook -m sonnet "..." # Claude
74
149
  sanook -m gemini "..." # Gemini
75
- sanook -m glm:smart "..." # GLM (z.ai Coding Plan)
76
150
  sanook -m ollama "..." # local ไม่ต้องมี key
151
+ sanook auth list # ดู key/provider status แบบ redact secret
152
+ sanook auth status openai # ดู env/store/console ของ provider
153
+ sanook sessions # ดู session ที่บันทึกไว้ของ project นี้
154
+ sanook sessions show <id> # ดูรายละเอียด session แบบย่อ
155
+ sanook sessions export <id> --format markdown --output session.md
156
+ sanook sessions rename <id> "ชื่อ session"
157
+ sanook sessions stats --all
158
+ sanook sessions prune --keep 20 --yes
159
+ sanook sessions rm <id> # ลบ session
160
+ sanook dump [--show-keys] # support dump; key ยังถูก redact
161
+ sanook prompt-size # ดู context/prompt budget แบบ offline
162
+ sanook runtimes # ดู Python/Rust optional runtime ที่ Sanook ใช้ได้
163
+ sanook web status # ดู true web-search/fetch readiness ผ่าน MCP
164
+ sanook web doctor # probe MCP web/search/fetch candidates
77
165
  ```
78
166
 
79
167
  ตั้งค่า default model ได้ด้วย:
@@ -114,7 +202,7 @@ sanook trust remove
114
202
  ```
115
203
 
116
204
  - gateway bind ที่ `127.0.0.1` และต้องใช้ bearer token ยกเว้น `/health`; mutating tools ใน `sanook serve` เป็น `ask` โดย default และ opt-in unattended write ได้ด้วย `sanook config set permissionMode auto` หรือ `SANOOK_GATEWAY_ALLOW_WRITE=1`
117
- - session/memory/worklog redact API keys ก่อนบันทึก และปิด persistence ได้ด้วย `SANOOK_DISABLE_PERSISTENCE=1`
205
+ - session/memory/prompt history/worklog redact API keys ก่อนบันทึก และปิด persistence ทั้งหมดได้ด้วย `SANOOK_DISABLE_PERSISTENCE=1`
118
206
 
119
207
  ## พัฒนา
120
208