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/.env.example CHANGED
@@ -8,12 +8,9 @@ GOOGLE_GENERATIVE_AI_API_KEY=AIzaxxx # aistudio.google.com/apikey (restrict
8
8
 
9
9
  # ── Cloud BYOK ──
10
10
  OPENAI_API_KEY=sk-xxx # platform.openai.com (รวม Codex: model gpt-5-codex)
11
- DEEPSEEK_API_KEY=sk-xxx # platform.deepseek.com
12
11
  XAI_API_KEY=xai-xxx # console.x.ai
13
12
  MISTRAL_API_KEY=xxx # console.mistral.ai
14
13
  GROQ_API_KEY=gsk_xxx # console.groq.com
15
- MINIMAX_API_KEY=xxx # platform.minimax.io (MINIMAX_BASE_URL สลับ region)
16
- ZHIPU_API_KEY=xxx # z.ai / open.bigmodel.cn (GLM — GLM_BASE_URL สลับ region)
17
14
 
18
15
  # ── Local (ไม่ต้อง key — ตั้ง baseURL ถ้าไม่ใช่ default) ──
19
16
  # OLLAMA_BASE_URL=http://localhost:11434/v1
@@ -40,3 +37,164 @@ SANOOK_MODEL=sonnet
40
37
  # SANOOK_DISABLE_PERSISTENCE=1 # ไม่บันทึก sessions/memory
41
38
  # SANOOK_DISABLE_WORKLOG=1 # ไม่เขียน worklog เข้า second-brain
42
39
  # SANOOK_TRUST_PROJECT=1 # trust project .sanook mcp/hooks/skills/commands ชั่วคราว
40
+
41
+ # ── Messaging gateway (optional; ใช้กับ sanook gateway / sanook send) ──
42
+ # Telegram
43
+ # TELEGRAM_BOT_TOKEN=123:abc
44
+ # TELEGRAM_ALLOWED_CHATS=5222385839
45
+
46
+ # Discord
47
+ # DISCORD_BOT_TOKEN=xxx
48
+ # DISCORD_DEFAULT_CHANNEL=123456789012345678
49
+ # DISCORD_ALLOWED_CHANNELS=123456789012345678
50
+
51
+ # Slack
52
+ # SLACK_BOT_TOKEN=xoxb-xxx
53
+ # SLACK_APP_TOKEN=xapp-xxx # ต้องมีถ้าจะรับข้อความผ่าน Socket Mode
54
+ # SLACK_DEFAULT_CHANNEL=C01ABCDEF
55
+ # SLACK_ALLOWED_CHANNELS=C01ABCDEF
56
+
57
+ # Email
58
+ # EMAIL_ADDRESS=bot@example.com
59
+ # EMAIL_PASSWORD=app-password
60
+ # EMAIL_IMAP_HOST=imap.example.com
61
+ # EMAIL_SMTP_HOST=smtp.example.com
62
+ # EMAIL_HOME_ADDRESS=you@example.com
63
+
64
+ # LINE Messaging API (webhook inbound + Push/send + cron delivery)
65
+ # LINE_CHANNEL_ACCESS_TOKEN=xxx
66
+ # LINE_CHANNEL_SECRET=xxx # ใช้ verify x-line-signature ของ webhook
67
+ # LINE_HOME_CHANNEL=U1234567890abcdef # U=user, C=group, R=room
68
+ # LINE_ALLOWED_USERS=U1234567890abcdef
69
+ # LINE_ALLOWED_GROUPS=C1234567890abcdef
70
+ # LINE_ALLOWED_ROOMS=R1234567890abcdef
71
+ # LINE_PUBLIC_URL=https://your-tunnel.example.com
72
+
73
+ # SMS / Twilio (webhook inbound + REST send + cron delivery)
74
+ # TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
75
+ # TWILIO_AUTH_TOKEN=xxx # ใช้ส่ง SMS และ verify x-twilio-signature
76
+ # TWILIO_PHONE_NUMBER=+15550000000
77
+ # SMS_HOME_CHANNEL=+15551234567
78
+ # SMS_ALLOWED_USERS=+15551234567,+15557654321
79
+ # SMS_WEBHOOK_URL=https://your-tunnel.example.com/sms/webhook
80
+ # SMS_INSECURE_NO_SIGNATURE=false # local dev only; production ควร false/ไม่ตั้ง
81
+
82
+ # ntfy (HTTP push + JSON stream subscribe)
83
+ # NTFY_TOPIC=sanook-yourname-2026
84
+ # NTFY_SERVER_URL=https://ntfy.sh
85
+ # NTFY_TOKEN=tk_xxx # optional; หรือ user:pass สำหรับ Basic auth
86
+ # NTFY_PUBLISH_TOPIC=sanook-yourname-2026
87
+ # NTFY_ALLOWED_USERS=sanook-yourname-2026
88
+ # NTFY_HOME_CHANNEL=sanook-yourname-2026
89
+ # NTFY_HOME_CHANNEL_NAME=Owner phone
90
+ # NTFY_MARKDOWN=true
91
+
92
+ # Mattermost REST API v4 + WebSocket inbound
93
+ # MATTERMOST_URL=https://mm.example.com
94
+ # MATTERMOST_TOKEN=xxx # token ของ bot/dedicated account
95
+ # MATTERMOST_HOME_CHANNEL=chan_home_id
96
+ # MATTERMOST_HOME_CHANNEL_NAME=Owner Mattermost
97
+ # MATTERMOST_ALLOWED_USERS=user_id_1,user_id_2 # fail-closed; ใช้ Mattermost user IDs
98
+ # MATTERMOST_ALLOWED_CHANNELS=chan_home_id,chan_ops_id
99
+ # MATTERMOST_FREE_RESPONSE_CHANNELS=chan_dm_like_id
100
+ # MATTERMOST_REQUIRE_MENTION=true # public/private channels ต้อง @mention; DM ตอบทุกข้อความ
101
+ # MATTERMOST_GROUP_SESSIONS_PER_USER=true
102
+ # MATTERMOST_REPLY_MODE=thread # off|thread
103
+ # MATTERMOST_ALLOW_ALL_USERS=false # production ควร false/ไม่ตั้ง
104
+
105
+ # Home Assistant (state_changed WebSocket inbound + persistent_notification send)
106
+ # HASS_URL=http://homeassistant.local:8123
107
+ # HASS_TOKEN=xxx # Long-Lived Access Token
108
+ # HASS_HOME_CHANNEL=sanook_agent # persistent_notification notification_id
109
+ # HASS_HOME_CHANNEL_NAME=Owner Home Assistant
110
+ # HASS_WATCH_DOMAINS=light,binary_sensor,climate
111
+ # HASS_WATCH_ENTITIES=sensor.temp,alarm_control_panel.home
112
+ # HASS_IGNORE_ENTITIES=sensor.noisy
113
+ # HASS_WATCH_ALL=false # production ควร false/ไม่ตั้ง
114
+ # HASS_COOLDOWN_SECONDS=30
115
+
116
+ # Signal via signal-cli daemon --http (JSON-RPC send + SSE inbound)
117
+ # SIGNAL_HTTP_URL=http://127.0.0.1:8080
118
+ # SIGNAL_ACCOUNT=+15550000000
119
+ # SIGNAL_HOME_CHANNEL=+15551234567
120
+ # SIGNAL_HOME_CHANNEL_NAME=Owner Signal
121
+ # SIGNAL_ALLOWED_USERS=+15551234567,+15557654321
122
+ # SIGNAL_GROUP_ALLOWED_USERS=groupIdBase64 # หรือ * เพื่อเปิดทุกกลุ่มโดยตั้งใจ
123
+ # SIGNAL_REQUIRE_MENTION=false # true = group ต้อง mention เบอร์ account
124
+
125
+ # WhatsApp Cloud API (Meta webhook inbound + Graph Messages API send)
126
+ # WHATSAPP_CLOUD_PHONE_NUMBER_ID=123456789012345
127
+ # WHATSAPP_CLOUD_ACCESS_TOKEN=EAA...
128
+ # WHATSAPP_CLOUD_APP_SECRET=xxx # ใช้ verify x-hub-signature-256 ของ webhook
129
+ # WHATSAPP_CLOUD_VERIFY_TOKEN=choose-a-long-random-token
130
+ # WHATSAPP_CLOUD_HOME_CHANNEL=15551234567 # wa_id digits, ไม่ต้องมี +
131
+ # WHATSAPP_CLOUD_HOME_CHANNEL_NAME=Owner WhatsApp
132
+ # WHATSAPP_CLOUD_ALLOWED_USERS=15551234567,15557654321
133
+ # WHATSAPP_CLOUD_PUBLIC_URL=https://your-tunnel.example.com
134
+ # WHATSAPP_CLOUD_API_VERSION=v20.0
135
+ # WHATSAPP_CLOUD_ALLOW_ALL_USERS=false # production ควร false/ไม่ตั้ง
136
+
137
+ # Matrix Client-Server API (sync inbound + room send)
138
+ # MATRIX_HOMESERVER=https://matrix.example.org
139
+ # MATRIX_ACCESS_TOKEN=syt_xxx # แนะนำ: token ของ bot account
140
+ # MATRIX_USER_ID=@sanook:matrix.example.org # optional ถ้าใช้ access token; required ถ้าใช้ password login
141
+ # MATRIX_PASSWORD=xxx # fallback แทน access token
142
+ # MATRIX_HOME_ROOM=!abc123:matrix.example.org
143
+ # MATRIX_HOME_ROOM_NAME=Owner Matrix
144
+ # MATRIX_ALLOWED_USERS=@alice:matrix.org,@bob:matrix.org
145
+ # MATRIX_ALLOWED_ROOMS=!abc123:matrix.example.org,!ops:matrix.example.org
146
+ # MATRIX_FREE_RESPONSE_ROOMS=!free:matrix.example.org
147
+ # MATRIX_REQUIRE_MENTION=true # shared rooms ต้อง mention bot; DM ตอบทุกข้อความ
148
+ # MATRIX_GROUP_SESSIONS_PER_USER=true
149
+ # MATRIX_AUTO_JOIN=true
150
+ # MATRIX_POLL_TIMEOUT_MS=30000
151
+
152
+ # Google Chat (Chat REST API outbound; Pub/Sub config saved for future inbound)
153
+ # GOOGLE_CHAT_PROJECT_ID=my-chat-bot-123
154
+ # GOOGLE_CHAT_SUBSCRIPTION_NAME=projects/my-chat-bot-123/subscriptions/sanook-chat-events-sub
155
+ # GOOGLE_CHAT_SERVICE_ACCOUNT_JSON=/home/you/.sanook/google-chat-sa.json
156
+ # GOOGLE_CHAT_API_BASE_URL=https://chat.googleapis.com
157
+ # GOOGLE_CHAT_HOME_CHANNEL=spaces/AAAA # use googlechat:spaces/AAAA/threads/thread-id for thread replies
158
+ # GOOGLE_CHAT_HOME_CHANNEL_NAME=Owner Google Chat
159
+ # GOOGLE_CHAT_ALLOWED_USERS=you@yourdomain.com,coworker@yourdomain.com
160
+ # GOOGLE_CHAT_ALLOWED_SPACES=spaces/AAAA,spaces/BBBB # explicit proactive send targets; home channel is allowed by default
161
+ # GOOGLE_CHAT_FREE_RESPONSE_SPACES=spaces/FREE
162
+ # GOOGLE_CHAT_MAX_MESSAGES=1
163
+ # GOOGLE_CHAT_MAX_BYTES=16777216
164
+ # GOOGLE_CHAT_ALLOW_ALL_USERS=false
165
+ # GOOGLE_CHAT_ALLOW_ALL_SPACES=false
166
+ # GOOGLE_CHAT_INCOMING_WEBHOOK_URL=https://chat.googleapis.com/v1/spaces/AAAA/messages?key=xxx&token=xxx
167
+
168
+ # BlueBubbles / iMessage (REST outbound now; webhook config saved for inbound parity)
169
+ # BLUEBUBBLES_SERVER_URL=http://localhost:1234
170
+ # BLUEBUBBLES_PASSWORD=xxx
171
+ # BLUEBUBBLES_WEBHOOK_HOST=127.0.0.1
172
+ # BLUEBUBBLES_WEBHOOK_PORT=8645
173
+ # BLUEBUBBLES_WEBHOOK_PATH=/bluebubbles-webhook
174
+ # BLUEBUBBLES_HOME_CHANNEL=user@example.com # chat GUID, email, or +E.164 phone; raw GUID like iMessage;-;user@example.com also works
175
+ # BLUEBUBBLES_HOME_CHANNEL_NAME=Owner iMessage
176
+ # BLUEBUBBLES_ALLOWED_USERS=user@example.com,+15551234567
177
+ # BLUEBUBBLES_ALLOW_ALL_USERS=false # production ควร false/ไม่ตั้ง
178
+ # BLUEBUBBLES_REQUIRE_MENTION=false # group chat inbound gate for future gateway run parity
179
+ # BLUEBUBBLES_MENTION_PATTERNS=["(?<![\\w@])@?sanook\\b[,:\\-]?"]
180
+
181
+ # Microsoft Teams (Incoming Webhook delivery now; Graph delivery for chat/channel targets)
182
+ # TEAMS_DELIVERY_MODE=incoming_webhook # incoming_webhook|graph
183
+ # TEAMS_INCOMING_WEBHOOK_URL=https://...
184
+ # TEAMS_GRAPH_ACCESS_TOKEN=xxx # Graph mode: delegated/application token with ChatMessage.Send/ChannelMessage.Send
185
+ # TEAMS_CHAT_ID=19:...
186
+ # TEAMS_TEAM_ID=team-id
187
+ # TEAMS_CHANNEL_ID=channel-id
188
+ # TEAMS_HOME_CHANNEL=19:... # หรือ team/<team-id>/channel/<channel-id>
189
+ # TEAMS_HOME_CHANNEL_NAME=Owner Teams
190
+ # TEAMS_CLIENT_ID=app-client-id # สำหรับ future Bot Framework inbound parity
191
+ # TEAMS_CLIENT_SECRET=xxx
192
+ # TEAMS_TENANT_ID=tenant-id
193
+ # TEAMS_ALLOWED_USERS=alice@example.com,bob@example.com
194
+ # TEAMS_PORT=3978
195
+
196
+ # Generic Webhooks (GitHub/GitLab/Jira/Stripe/etc. inbound events)
197
+ # WEBHOOK_ENABLED=true
198
+ # WEBHOOK_SECRET=xxx # global fallback HMAC secret
199
+ # WEBHOOK_PUBLIC_URL=https://your-tunnel.example.com
200
+ # WEBHOOK_RATE_LIMIT_PER_MINUTE=30
package/CHANGELOG.md CHANGED
@@ -1,6 +1,131 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 0.5.5
4
+
5
+ ### Hermes-style setup, dashboard, and terminal parity
6
+
7
+ - **Localized setup wizard (EN/TH)** — language picker on first run; steps for provider, model, **agent** (permission mode), **tools**, **gateway**, second brain, and complete (~10 steps).
8
+ - **`sanook dashboard`** — local web UI on port 9119 with pages: Home, **Chat**, Models, Sessions, **Files**, **Logs**, **Cron**, **Channels**, Config, MCP, Brain; REST APIs for status, config, files, logs, cron, and channels.
9
+ - **Two-phase `/model` picker** — choose provider, then model (Hermes-style); `Esc` returns to provider list.
10
+ - **New slash commands** — `/setup` (setup section hints), `/dashboard` (open web dashboard).
11
+ - **Codex device-code login** — Hermes-style OAuth device flow in setup wizard (`src/providers/codex-login.ts`).
12
+ - **i18n foundation** — `src/i18n/` with English and Thai strings; locale persisted in global config.
13
+
14
+ ## 0.5.4
15
+
16
+ ### Multi-project vault — project workspace auto-detect
17
+
18
+ - **`Projects/<slug>/` workspace standard** — `overview.md`, `current-state.md`, `context.md`, `repo.md` with `repo_path` for machine-readable repo mapping.
19
+ - **`sanook brain new project --title "..." --repo /path`** — scaffolds full `Projects/<slug>/` workspace from `Templates/project-workspace/` and links it from `Projects/_Index.md`.
20
+ - **`sanook brain projects list`** — shows registered project workspaces and marks the active project for the current cwd.
21
+ - **Project auto-detect in agent context** — when cwd is inside a project's `repo_path`, Sanook injects `<project_workspace>` hot context (current-state, context, overview) into `loadBrainContext()` and `sanook brain context`.
22
+ - **`sanook brain context --project <slug>`** — force a project workspace without cwd matching.
23
+ - **Scaffold policy** — `sanook brain init` no longer copies bundled `Projects/<slug>/` dogfood folders into new vaults (only `Projects/_Index.md`); add projects explicitly with `brain new project`.
24
+
25
+ ## 0.5.3
26
+
27
+ ### Second-brain CLI — pack, create, repair, consolidate, metrics
28
+
29
+ - **`sanook brain pack list|show <name>`** — makes `Shared/Context-Packs/` first-class: list packs with descriptions and index status; show load order, done criteria, and wiki-link sources.
30
+ - **`sanook brain new <type> [--title "..."]`** — template-backed note creation for `session`, `bug`, `handoff`, `project`, `golden-case`, and `checklist`; fills frontmatter, sets `parent`/`up::`, appends to destination `_Index.md`, and rejects wrong-folder output paths.
31
+ - **`sanook brain repair [--dry-run]`** — safe one-line fixes after `doctor`/`review`: missing purpose blockquote, `parent`, `up::`, unlinked context packs, and missing scaffold folders.
32
+ - **`sanook brain consolidate [--apply] [--apply --archive] [--memory]`** — sleep-time consolidation runner (inbox dedup, stale → archive, retrieval eval, optional auto-memory merge); dry-run by default.
33
+ - **`sanook brain metrics [--no-retrieval]`** — vault counts, stale notes, index freshness, and retrieval coverage with non-zero exit on issues.
34
+ - **Context pack auto-select** — `buildBrainContext({ taskQuery })` and per-turn retrieval now inject the best-matching context pack before broader vault context.
35
+
36
+ ### MCP trust & safety
37
+
38
+ - **`sanook mcp enable|disable <name>`** — toggle MCP servers without removing config (`enabled` flag in `mcp.json`; disabled servers are skipped by the agent, web probes, and doctor).
39
+ - **401 auth hints** — `mcp test` / `mcp doctor` print setup hints when hosted remotes return Unauthorized.
40
+ - **Risk labels** — classify servers as `read-only`, `file-write`, `network-write`, `database-write`, or `infra/admin` in search/info/list/test and the MCP hub overlay.
41
+ - **Registry cache** — official MCP registry responses are cached for 5 minutes to reduce repeated network fetches.
42
+
43
+ ### Agent loop — web fetch, plan handoff, background tasks
44
+
45
+ - **`web_fetch` agent tool** — built-in ethical fetch ladder (direct HTML → reader → Tavily → Wayback); read-only, no approval gate; same policy as `sanook web fetch`.
46
+ - **`sanook plan "<task>"`** — read-only plan mode with stderr execute handoff (`sanook --yes "…"`) after success.
47
+ - **`/tasks` overlay + `bg N` status** — inspect running `task_spawn` background jobs from the REPL.
48
+
49
+ ### Gateway — doctor, richer status, mobile replies
50
+
51
+ - **`sanook gateway doctor`** — validate configured channel tokens, webhooks, and allowlists with live probes where possible.
52
+ - **`sanook gateway status` (enhanced)** — pending cron jobs, recent delivery failures, and config-based channel health summary.
53
+ - **Mobile chat formatting** — truncate fenced code blocks and cap reply length before delivering to Telegram/Discord/Slack/LINE/WhatsApp and other chat platforms.
54
+
55
+ ### TUI — sessions, transcript, launchpad
56
+
57
+ - **Session rename** — `/sessions` → `r` to rename inline.
58
+ - **Cross-project sessions** — list sessions from all projects (`≠` marker); resume cross-project with `--continue-any`-style cwd note.
59
+ - **Virtual transcript** — viewport windowing with PgUp/PgDn scroll instead of rendering full scrollback.
60
+ - **Collapsible launchpad** — keys `1`/`2`/`3` toggle Tools/Skills/MCP startup sections.
61
+
62
+ ### Developer experience
63
+
64
+ - **`sanook init [--trust]`** — scaffold `.sanook/commands/` starter templates and print brain/MCP/trust next-step hints.
65
+ - **`sanook skill install <name|path>`** — install from bundled catalog or local path (shared resolver with `skill add`).
66
+
67
+ ## 0.5.2
68
+
69
+ ### TUI startup polish — SANOOK AI Launchpad
70
+
71
+ - **Live startup cockpit signals** — the Sanook launchpad now shows real local readiness, not just brand copy: second-brain configured/missing, MCP server count, loaded skill count, and current git branch. This turns the first screen into a useful service cockpit for Code, Brain, Connect, and Ship workflows, while keeping medium/tiny terminal fallbacks readable.
72
+ - **Big `SANOOK AI` startup banner** — the REPL now opens with a large gradient wordmark plus a compact launchpad for version, account mode, live model, automation mode, cwd, and high-signal slash-command hints. The banner now carries the Sanook identity directly (`งานหนักให้เบาลง · ไม่เบาความรับผิดชอบ · local-first memory`), a signature workflow (`plan -> patch -> prove -> remember`), and a service promise (`readable · recoverable · remembered`). It gives users four memorable service routes: Code (`@file`, tools, diff), Brain (`brain context`, skills, compression), Connect (`MCP`, gateway, webhooks), and Ship (`copy`, cost guard, undo). Hermes-style responsive tiers keep it usable across terminal widths: wide wordmark, compact panel, and tiny text-only fallback. It still renders only before conversation history exists, so command turns do not redraw it into terminal scrollback.
73
+ - **Startup service routes panel** — the empty REPL now also shows a Hermes-style Sanook service-routes panel with Code, Brain, Connect, Ship, System, and Runtime lanes. It tells new users what the CLI can do immediately: edit/run/read tools, second-brain context and worklogs, reusable skills, MCP registry/install/doctor/serve, gateway/webhook work, `/copy` handoff, ask-mode approvals, queued follow-ups, and `/hotkeys`. The panel has compact copy for medium terminals and hides on tiny terminals so the prompt stays usable.
74
+ - **Floating overlay foundation** — `/help` now opens a Hermes-style paged overlay with line/page navigation instead of dumping the full command reference into scrollback. Typing slash-command prefixes or path-like tokens such as `@src/foo`, `./src/`, `~/notes/`, or `/tmp/` now shows a Hermes-style completion float box with command/file metadata; ↑/↓ chooses a row and Tab/Enter completes before the command or prompt is submitted. `/tools` opens a Sanook Tools Hub overlay for built-in file/git/memory/schedule/sub-agent/diagnostics lanes, while `/mcp` opens a Sanook MCP Hub overlay, mapping Hermes' plugins hub idea onto Sanook's extension surface: configured MCP servers, stdio/http transport, target, secret summary, and lazy selected-server testing with `t` so users can see PASS/FAIL and browse the selected server's advertised tool catalog with ↑/↓ or j/k before leaving the REPL. `/hotkeys` opens a dismissible TUI overlay (`Esc`, `Enter`, or `q`). `/model` without args opens an interactive model picker overlay with ↑/↓ or j/k navigation and Enter-to-switch, while `/model <spec>` keeps the existing direct canonical switch behavior. `/skills` opens a read-only Skills Hub overlay for browsing loaded skills and inspecting description/path metadata. `/sessions` opens a Hermes-style Session Switcher for saved sessions in the current project, resumes the highlighted session with Enter, inspects session metadata with `i`, and deletes with a two-press `d` confirmation. This is the reusable Sanook overlay path for the remaining richer help/session surfaces.
75
+ - **Hermes-inspired REPL affordances** — added `/hotkeys`, a bounded queued-message window (`queued (n)` + `…and N more`) with an active row plus `Ctrl+X` deletion while busy, a Sanook tool trail for `tool-call`/`tool-result` events that persists into the assistant transcript after the turn completes and can be toggled with `/trail [compact|expanded]` or `Ctrl+T`, and a Sanook status rule that prioritizes state/model/mode/context/queue over secondary hints, shows elapsed time while working, shows context-compression mode (`cmp sel/hdr/off`) on roomy terminals, shows cost plus cwd/branch on wider terminals, and lets the cwd/branch segment yield before it can wrap or crowd the important left side.
76
+ - **Hermes-style details controls** — `/details thinking hidden|collapsed|expanded` now controls a capped Sanook thinking panel fed by provider reasoning deltas, and `/details tools hidden|collapsed|expanded` maps Hermes' tools section visibility onto Sanook's persisted tool trail (`hidden`, compact/collapsed, expanded). This gives users a cleaner way to tune how much live agent work is visible without losing the quick `/trail` toggle.
77
+ - **Streaming markdown rendering** — assistant live output and saved assistant turns now render common Markdown blocks instead of raw text: headings, block quotes, bullet/numbered lists, fenced code blocks, inline code, and bold spans. The live renderer keeps a Hermes-inspired stable-prefix/unstable-tail split at blank-line boundaries outside code fences, so streaming fenced code and partially-written paragraphs stay readable without pulling in a heavyweight renderer.
78
+ - **Grapheme-safe prompt editing** — the REPL editor now moves the cursor and backspaces by grapheme cluster instead of raw JavaScript code unit. Thai combining marks, emoji, and ZWJ emoji stay intact while editing, matching the direction of Hermes' custom TextInput correctness work without importing its runtime.
79
+ - **Hermes-style paste collapse** — bracketed or multiline paste now normalizes CRLF/newlines and collapses long pasted text (5+ lines or 2k+ chars) into a readable `[[ paste ... ]]` token in the composer. On submit Sanook expands the token back to the original pasted text before running the agent, so the terminal stays readable while the model still receives the full context.
80
+ - **Terminal clipboard bridge** — `/copy [last]` copies the latest assistant response from the REPL. Sanook first tries the native system clipboard (`pbcopy`, PowerShell, `wl-copy`, `xclip`, `xsel`) and falls back to OSC52 terminal clipboard sequences when native tools are unavailable, covering the practical core of Hermes' clipboard work while leaving full mouse-selection parity for later.
81
+ - **Hermes TUI parity map** — added `second-brain/Research/2026-06-18-hermes-tui-parity-map.md` so the remaining rebrand/port work is explicit: overlays, model/session/skills hubs, status rule, virtual transcript, terminal clipboard/mouse support, streaming markdown/persistent tool trails, and skin/theme parity.
82
+
83
+ ### Token reduction — selective context compression for stale tool output
84
+
85
+ - **`sanook prompt-size [--json]`** — Hermes-inspired offline prompt budget diagnostic. It reports the current system prompt, personality overlay, auto-memory, skills index, second-brain context, project memory, repo map, git context, built-in tool schemas, and total rough token/byte footprint without calling a model or spawning MCP servers, so users can tune large second-brain/skill setups before context cost becomes invisible.
86
+ - **`contextCompression: "selective" | "headroom" | "off"`** (env `SANOOK_CONTEXT_COMPRESSION`) — default `"selective"` is a zero-LLM, per-step compressor inspired by Selective Context, LongLLMLingua-style query awareness, and Headroom-style context pruning. It keeps the latest tool results full, but compresses older huge tool outputs with recency-aware budgets and preserves anchors plus high-information lines (current-query matches, errors, paths, diffs, code structure, rare terms) before the next model request. `"headroom"` optionally wraps the Vercel AI SDK model with the `headroom-ai` GitHub/npm framework when a Headroom proxy/cloud setup is available; `"off"` disables compression.
87
+
88
+ ### Polyglot runtime foundation — Python/Rust without mandatory native deps
89
+
90
+ - **`sanook runtimes [--json]`** — new runtime surface report for Sanook's language strategy. TypeScript remains the npm-distributed control plane; Python is the optional analysis/data/document/ML helper plane; Rust is the optional performance/safety/native-helper plane. The command detects Python, uv, rustc, Cargo, Pyright, and rust-analyzer, then prints install hints without making any of them required for basic Sanook usage.
91
+ - **`run_python` / `run_rust` agent tools** — approval-gated, no-shell runtime tools. `run_python` runs a Python snippet or workspace `.py` file for JSON/CSV transforms, document/text parsing, OCR/ML glue, and research scripts. `run_rust` compiles and runs a single-file Rust snippet or workspace `.rs` file for fast parsers/checkers and type-safe native-helper prototypes. Missing runtimes degrade to clear install messages instead of breaking the agent loop.
92
+
93
+ ### Web grounding — true search readiness and source policy
94
+
95
+ - **`sanook web status [--json]` / `sanook web doctor [--json]`** — new diagnostic surface for true web/search/fetch readiness. It clearly separates `sanook search` local retrieval (vault, memory, sessions, skills) from internet search through MCP servers, detects configured web/search/fetch candidates, and optionally probes advertised tools. The report also prints the recommended `research` MCP preset and Sanook's grounding policy.
96
+ - **Agent web-use policy** — the system prompt now tells the agent to use configured web/search/fetch MCP tools for current or volatile external facts, prefer primary sources for technical work, cite source URLs/titles, and treat fetched/search content as untrusted data rather than instructions.
97
+
98
+ ### MCP registry UX — discover, install, and diagnose servers
99
+
100
+ - **`sanook mcp search/info/install`** — browse the official MCP registry, inspect transports/packages/secret requirements, and write a ready-to-use stdio or Streamable-HTTP config into `~/.sanook/mcp.json` (or trusted project config with `--project`).
101
+ - **`sanook mcp test` / `sanook mcp doctor` / `sanook mcp list --tools`** — probe configured MCP servers, show advertised tools, and fail clearly when a server is missing credentials, unreachable, or misconfigured.
102
+ - **`sanook mcp preset`** — curated starter bundles (`dev`, `research`, `pm`, `ops`) for common Sanook workflows.
103
+
104
+ ### Second-brain CLI tooling — doctor, context, eval
105
+
106
+ - **`sanook brain context [--task "..."]`** — shows the exact `<brain_vault>` context Sanook injects from `Shared/AI-Context-Index.md`, `current-state.md`, and Memory-Inbox, with source char counts and stale/missing index warnings. With `--task`, it also runs focused retrieval over vault/session/skill hits.
107
+ - **`sanook brain eval`** — turns `Evals/second-brain-benchmarks.md` into a lightweight runner: static vault sanity checks, context-size/missing-source checks, index freshness, and retrieval probes for key rules/ledgers.
108
+ - **`sanook brain review`** — curator-style vault review for Memory-Inbox duplicates/possible contradictions, stale or incomplete context packs, session notes missing from the search manifest, eval freshness after framework changes, and markdown routing hygiene.
109
+ - **`sanook brain final [--task "..."] [--from-diff] [--lite]`** — creates an evidence-backed final gate note in `Sessions/`, optionally prefilled from the current git diff, and links it from `Sessions/_Index.md`. `brain review` now validates final gates for missing evidence/TODO placeholders, while `brain eval` keeps the full and lite templates covered.
110
+ - **Context assembly is inspectable without drift**: `buildBrainContext()` now exposes typed source parts and renders from the same parts used by the agent prompt.
111
+ - **Fresh scaffold discoverability**: generated `Shared/Context-Packs/_Index.md` now links the bundled context packs, so review/search can find them immediately.
112
+
113
+ ### Whole-codebase audit — confirmed bugs fixed across the CLI
114
+
115
+ A multi-agent review swept every subsystem (agent loop, tools, providers, gateway, MCP, search, orchestration) and adversarially verified each finding. The ones fixed here:
116
+
117
+ **High**
118
+ - **`edit_file` silently stripped indentation.** The whitespace-flexible match tier matched an indented block by trimmed lines but spliced the (un-indented) replacement verbatim — de-indenting code and breaking Python/YAML, invisibly. It now re-applies the file's indentation to the replacement.
119
+ - **Codex delegate could never edit files + ran in the wrong directory.** `sanook -m codex` ran with `--sandbox read-only` unconditionally (a "coding agent" that silently couldn't write) and ignored worktree `cwd`. It now uses `workspace-write` in auto mode (read-only under plan/ask), threads `cwd`, and passes prior conversation so REPL turns aren't contextless.
120
+ - **Worktree rollback could lose a renamed file.** The pre-apply snapshot only captured destination paths, so a failed 3-way apply of a rename didn't restore the deleted source. Snapshots now cover both sides of renames/copies (and parse git-quoted paths).
121
+
122
+ **Medium** — git tools now run in the sub-agent's worktree (`git_commit --addAll` no longer commits the main repo); LSP child process no longer leaks on init failure/timeout (+ init timeout, + Windows `.cmd` shell, + Windows-critical env); Codex no longer crashes the CLI on an EPIPE; the model-fallback path no longer duplicates streamed output; MCP server stderr is drained (was hanging when the pipe filled); an untrusted project can no longer disable the budget cap or spoof pricing; the Telegram bot skips its backlog on startup (no replaying old commands); hooks get Windows-critical env.
123
+
124
+ **Low** — `replace_all` reports the real replacement count; the multi-match hint no longer suggests `replace_all` for flex matches (dead-end); a malformed trusted-project `hooks.json` no longer crashes the run; frontmatter-only notes with no trailing newline no longer leak the frontmatter into the indexed body; the gateway returns 400/413 (not 500) for bad/oversized request bodies.
125
+
126
+ **Follow-up medium fixes** — `sanook index` now builds and saves the semantic vector sidecar, so `--mode semantic|hybrid` no longer silently degrades to BM25 after a reindex; subagent fan-out has a global process-wide concurrency cap; `budgetUsd` is shared across the whole agent tree instead of resetting per subagent; isolated write subagents no longer inherit the interactive approval loop inside their temp worktree after the parent approved `task_parallel`; `/v1/chat/completions` now supports OpenAI-style `stream:true` SSE chunks.
127
+
128
+ **Follow-up low fixes** — protected path checks resolve symlink ancestors before allowing writes; search chunk ids use a stronger SHA-256-derived path hash; oversized MCP tool text is capped before entering model context; malformed search manifests are sanitized on load without discarding a valid index; a setup-wizard timing test now waits for the rendered validation frame instead of flaking under full-suite load.
4
129
 
5
130
  ### Fix: couldn't type in the REPL after first-run setup
6
131
 
@@ -21,13 +146,27 @@ A multi-agent review of the first-run + setup + REPL flow surfaced (and independ
21
146
 
22
147
  ### Fix: duplicate / empty model choices in the setup wizard
23
148
 
24
- `mergeModelOptions` only deduped *remote* model ids against the curated list — never the curated list against itself. So aliases pointing at the same id rendered as **two identical-looking choices** (e.g. `haiku — claude-haiku-4-5` and `fast — claude-haiku-4-5`; OpenAI's `smart`/`gpt` both → `gpt-5.5`), which also collided on React keys (`Encountered two children with the same key` → options could duplicate or vanish). It now groups by model id and merges the alias names into one option (`haiku / fast — claude-haiku-4-5`). Separately, the old code dropped the `default` alias entirely, which **emptied the model list for LM Studio** (`{ default: 'local-model' }`) and hid Ollama's `qwen3` — those models are now selectable again. Locked in with tests (every provider yields unique option values; LM Studio/Ollama are non-empty).
149
+ `mergeModelOptions` only deduped *remote* model ids against the curated list — never the curated list against itself. So aliases pointing at the same id rendered as **two identical-looking choices** (e.g. `haiku — claude-haiku-4-5` and `fast — claude-haiku-4-5`; OpenAI's `smart`/`gpt` both → `gpt-5.5`), which also collided on React keys (`Encountered two children with the same key` → options could duplicate or vanish). It now groups by model id and merges the alias names into one option (`haiku / fast — claude-haiku-4-5`). Separately, the old code dropped the `default` alias entirely, which **emptied the model list for LM Studio** (`{ default: 'local-model' }`) and hid Ollama's default model — those models are now selectable again. Locked in with tests (every provider yields unique option values; LM Studio/Ollama are non-empty).
150
+
151
+ ### CLI audit follow-ups
152
+
153
+ - **`--continue-any` actually works as a resume flag now.** The headless arg parser forgot to consume it, so `sanook --continue-any` became a literal prompt instead of opening the REPL with the latest cross-project session. The parser is now split into a tested module and consumes all resume/headless aliases.
154
+ - **Search flags are validated.** `sanook search q --mode nope` used to silently fall back to FTS, and `--limit -5` could produce odd slice behavior. Search args now reject invalid modes, sources, missing queries, and non-positive limits with a clear usage line.
155
+ - **`sanook serve --port` missing values now report a human-readable error.** Empty or missing port values now surface `ต้องระบุค่า` instead of leaking `"undefined"` into the validation message.
156
+ - **`SANOOK_DISABLE_PERSISTENCE=1` now includes second-brain worklogs.** Sessions, auto-memory, prompt history, and worklogs all honor the global persistence kill switch; `SANOOK_DISABLE_WORKLOG=1` remains available for worklog-only opt-out.
157
+ - **First-run Codex readiness is real.** `sanook -m codex` no longer skips setup just because Codex does not use an API key; it only skips when the official `codex` CLI is installed and logged in.
158
+ - **Existing broken model config now reopens setup instead of entering a dead REPL.** If `~/.sanook/config.json` points at OpenAI without a usable key (or Codex without a logged-in CLI), interactive `sanook` brings back the setup wizard so the recovery hint is actually actionable.
159
+ - **Provider menu env-key labels now use the same key policy as runtime.** Malformed/OAuth env keys show as unusable instead of a misleading ready checkmark.
160
+ - **`/model gpt` no longer leaves the REPL in a raw alias state.** Slash-command model changes now store canonical `provider:model-id` specs (for example `openai:gpt-5.5`), and missing OpenAI-key messages point ChatGPT-plan users to `/model codex` + `codex login`.
161
+ - **The REPL banner no longer redraws after every command on terminals that keep Ink frames in scrollback.** The welcome banner renders only before history exists; the live model stays visible in the footer.
162
+ - **`config set embeddingModel ...` is now supported.** The README documented this semantic-search setting, but the config allowlist/schema did not accept it.
163
+ - **Help/docs cleanup.** The CLI help no longer points at the deprecated OpenAI Codex model id, and the README test badge was refreshed.
25
164
 
26
165
  ### Setup wizard — better provider selection + working OpenAI Codex login
27
166
 
28
- - **Provider menu**: each option now shows a one-line hint — `✓ เจอ key ใน env`, `local · ไม่ต้อง key`, `login ChatGPT · ไม่ใช้ API key`, or `ต้องมี API key` — and the list is ordered (popular cloud → others → local → Codex). The API-key step shows the expected key format.
167
+ - **Provider menu**: each option now shows a one-line hint — `✓ key ใน env ใช้ได้`, `key ใน env ใช้ไม่ได้`, `local · ไม่ต้อง key`, `login ChatGPT · ไม่ใช้ API key`, or `ต้องมี API key` — and the list is ordered (popular cloud → others → local → Codex). The API-key step shows the expected key format.
29
168
  - **OpenAI Codex (ChatGPT plan)**: picking Codex used to skip straight past auth. It now runs a dedicated step that detects whether the `codex` CLI is installed and logged in (reads `~/.codex/auth.json` — robust inside sandboxes where `codex login status` can panic), and guides you: `npm i -g @openai/codex` → `codex login` → re-check, then continues automatically once you're signed in. No API key required.
30
- - **Codex runs**: `codex exec` now passes `--ask-for-approval never` (no hang waiting on approvals; safe under the default read-only sandbox) and removes `OPENAI_API_KEY` from the child env so it can't fight the ChatGPT-plan login (codex #2733/#3286). Verified the exact CLI surface against the official OpenAI Codex docs.
169
+ - **Codex runs**: `codex exec` now runs through the current non-interactive JSON CLI surface, uses the requested sandbox (`read-only` by default, `workspace-write` in auto mode), and removes `OPENAI_API_KEY` from the child env so it can't fight the ChatGPT-plan login (codex #2733/#3286). Verified against the installed Codex CLI surface.
31
170
 
32
171
  ## 0.5.0
33
172
 
@@ -120,8 +259,8 @@ A Node-native, zero-dependency Language Server Protocol client (`src/lsp/`) give
120
259
  The interactive REPL was input-locked while the agent worked, and Ctrl+C quit the whole app. Now a turn is steerable:
121
260
 
122
261
  - **Interrupt mid-turn**: the running turn gets a real `AbortController` (wired into `runAgent`'s `signal`). Press **Esc** (or Ctrl+C) to stop the stream/tool loop right away and return to the prompt — without exiting the app. Partial output is kept for reference, the turn is dropped from the model history, and any files a tool already changed are recoverable via `/rewind`.
123
- - **Type-ahead queue**: you can type while the agent is busy; pressing Enter **queues** the message (shown as `⏳ คิว …`) and it runs automatically as the next turn when the current one finishes. Interrupting clears the queue.
124
- - Covered by an Ink integration test (mocked agent) asserting the signal is passed, input queues while busy, and Esc both aborts and clears the queue.
262
+ - **Type-ahead queue**: you can type while the agent is busy; pressing Enter **queues** the message and it runs automatically as the next turn when the current one finishes. The queue view now keeps an active row, ↑/↓ moves it while the draft is empty, and **Ctrl+X** deletes the selected queued prompt. Interrupting clears the queue.
263
+ - Covered by Ink integration tests (mocked agent) asserting the signal is passed, input queues while busy, Ctrl+X deletes active queued prompts, and Esc both aborts and clears the queue.
125
264
 
126
265
  ### Worktree isolation — safe parallel WRITE subagents (`task_parallel isolate:true`)
127
266
 
@@ -173,20 +312,19 @@ A Node-native search subsystem (`src/search/`) over the second-brain vault **plu
173
312
 
174
313
  - Tests: remote-MCP, sandbox, repo map, prompt-caching/system-preservation, rate-limit classification, tool timeout, checkpoint restore, cost merge, custom commands (≈200 total).
175
314
 
176
- ## 0.4.0 — second brain, GLM Coding Plan, Telegram, hardening
315
+ ## 0.4.0 — second brain, Telegram, hardening
177
316
 
178
317
  - **Second brain**: `sanook brain init` scaffolds a portable Obsidian "second-brain" workspace — full folder taxonomy (each with `_Index.md`), a central `Vault Structure Map.md`, seed memory files, and a portable AI operating constitution (`CLAUDE/GEMINI/AGENTS.md`). Research-backed rules: context-assembly (anti context-rot), intake quarantine + injection-scan, bi-temporal fact validity, provenance tracking, a verification-gated `Skills/` library, sleep-time consolidation. The agent now **loads the vault** into context, and `brain init` **auto-wires a filesystem MCP** to it. First-run wizard offers to create one (personalized).
179
- - **GLM Coding Plan**: GLM routes through the Anthropic-compatible endpoint (`/api/anthropic`), so Coding Plan keys work; curated ids `glm-4.6 / glm-5.1 / glm-4.5-air`.
180
318
  - **Telegram channel**: drive the agent from your phone (long-polling, fail-closed allowlist, private-only). Remote surface defaults to ask-mode (mutations denied) unless `TELEGRAM_ALLOW_WRITE=1`.
181
319
  - **Auto-compaction**: token-aware sliding window keeps long sessions under the limit.
182
320
  - **Interactive approval** (`ask` mode) + capability-based gating — any non-read-only tool (incl. MCP) is confirmed before running.
183
321
  - **REPL resume** (`sanook -c`), **stdin piping** (`git diff | sanook "review"`), gateway multi-turn history, and `sanook config` / `sanook mcp` management commands.
184
- - **Provider audit**: corrected stale model ids (OpenAI `gpt-5.3-codex`, DeepSeek `v4-flash/pro`, xAI `grok-4.3`).
322
+ - **Provider audit**: corrected stale model ids (OpenAI `gpt-5.3-codex`, xAI `grok-4.3`).
185
323
  - **Hardening**: budget cap now actually fires on the default fast model; write paths confined (no `~/.sanook` / shell-rc / ssh backdoors); MCP child processes get a minimal env (no secret leakage); provider errors surface a clean one-line message; versions read from `package.json`. Added tests for the BYOK/redaction core and budget cap.
186
324
 
187
325
  ## 0.3.0 — providers, memory, gateway, MCP, git
188
326
 
189
- - **Providers**: data-driven registry, now 12 providers (added MiniMax, GLM, and OpenAI Codex via the official CLI). Per-provider model picker that fetches the live model list.
327
+ - **Providers**: data-driven registry, now 9 providers (including OpenAI Codex via the official CLI). Per-provider model picker that fetches the live model list.
190
328
  - **Memory**: auto-memory (`remember` / `recall`), session resume (`--continue`), and in-session REPL conversation history.
191
329
  - **Gateway + cron**: `sanook serve` runs a loopback HTTP endpoint (OpenAI-compatible) plus a cron scheduler with natural-language scheduling, backed by a file-locked JSON task ledger.
192
330
  - **Skills**: load `SKILL.md` files on demand; the agent can author its own with `create_skill`.