@hybridaione/hybridclaw 0.9.6 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +55 -0
  3. package/README.md +17 -6
  4. package/config.example.json +5 -0
  5. package/container/.dockerignore +2 -0
  6. package/container/Dockerfile +48 -20
  7. package/container/dist/approval-policy.js +31 -10
  8. package/container/dist/approval-policy.js.map +1 -1
  9. package/container/dist/browser-tools.js.map +1 -1
  10. package/container/dist/index.js.map +1 -1
  11. package/container/dist/providers/local-openai-compat.js +4 -1
  12. package/container/dist/providers/local-openai-compat.js.map +1 -1
  13. package/container/dist/providers/router.js +3 -0
  14. package/container/dist/providers/router.js.map +1 -1
  15. package/container/dist/providers/shared.js +1 -0
  16. package/container/dist/providers/shared.js.map +1 -1
  17. package/container/dist/tools.js.map +1 -1
  18. package/container/dist/types.js.map +1 -1
  19. package/container/package-lock.json +2 -2
  20. package/container/package.json +1 -1
  21. package/container/shared/model-names.js +1 -0
  22. package/container/shared/provider-context.js +1 -0
  23. package/container/src/approval-policy.ts +33 -8
  24. package/container/src/browser-tools.ts +2 -0
  25. package/container/src/index.ts +2 -0
  26. package/container/src/providers/local-openai-compat.ts +7 -1
  27. package/container/src/providers/router.ts +3 -0
  28. package/container/src/providers/shared.ts +2 -0
  29. package/container/src/tools.ts +2 -0
  30. package/container/src/types.ts +2 -0
  31. package/dist/agent/prompt-hooks.d.ts.map +1 -1
  32. package/dist/agent/prompt-hooks.js +6 -1
  33. package/dist/agent/prompt-hooks.js.map +1 -1
  34. package/dist/channels/imessage/backend-local.d.ts.map +1 -1
  35. package/dist/channels/imessage/backend-local.js +39 -0
  36. package/dist/channels/imessage/backend-local.js.map +1 -1
  37. package/dist/cli/auth-command.d.ts.map +1 -1
  38. package/dist/cli/auth-command.js +103 -5
  39. package/dist/cli/auth-command.js.map +1 -1
  40. package/dist/cli/help.d.ts +1 -0
  41. package/dist/cli/help.d.ts.map +1 -1
  42. package/dist/cli/help.js +27 -5
  43. package/dist/cli/help.js.map +1 -1
  44. package/dist/cli.d.ts.map +1 -1
  45. package/dist/cli.js +1 -0
  46. package/dist/cli.js.map +1 -1
  47. package/dist/command-registry.d.ts.map +1 -1
  48. package/dist/command-registry.js +30 -1
  49. package/dist/command-registry.js.map +1 -1
  50. package/dist/config/config.d.ts +3 -0
  51. package/dist/config/config.d.ts.map +1 -1
  52. package/dist/config/config.js +10 -0
  53. package/dist/config/config.js.map +1 -1
  54. package/dist/config/runtime-config.d.ts +6 -1
  55. package/dist/config/runtime-config.d.ts.map +1 -1
  56. package/dist/config/runtime-config.js +14 -0
  57. package/dist/config/runtime-config.js.map +1 -1
  58. package/dist/doctor/checks/credentials.d.ts.map +1 -1
  59. package/dist/doctor/checks/credentials.js +1 -0
  60. package/dist/doctor/checks/credentials.js.map +1 -1
  61. package/dist/doctor/checks/providers.d.ts.map +1 -1
  62. package/dist/doctor/checks/providers.js +14 -1
  63. package/dist/doctor/checks/providers.js.map +1 -1
  64. package/dist/doctor/provider-probes.d.ts +1 -0
  65. package/dist/doctor/provider-probes.d.ts.map +1 -1
  66. package/dist/doctor/provider-probes.js +33 -1
  67. package/dist/doctor/provider-probes.js.map +1 -1
  68. package/dist/gateway/docs.d.ts +4 -0
  69. package/dist/gateway/docs.d.ts.map +1 -0
  70. package/dist/gateway/{development-docs.js → docs.js} +154 -46
  71. package/dist/gateway/docs.js.map +1 -0
  72. package/dist/gateway/gateway-agent-cards.d.ts.map +1 -1
  73. package/dist/gateway/gateway-agent-cards.js +31 -44
  74. package/dist/gateway/gateway-agent-cards.js.map +1 -1
  75. package/dist/gateway/gateway-http-server.d.ts.map +1 -1
  76. package/dist/gateway/gateway-http-server.js +5 -4
  77. package/dist/gateway/gateway-http-server.js.map +1 -1
  78. package/dist/gateway/gateway-service.d.ts.map +1 -1
  79. package/dist/gateway/gateway-service.js +139 -18
  80. package/dist/gateway/gateway-service.js.map +1 -1
  81. package/dist/gateway/gateway-time.d.ts +1 -0
  82. package/dist/gateway/gateway-time.d.ts.map +1 -1
  83. package/dist/gateway/gateway-time.js +24 -0
  84. package/dist/gateway/gateway-time.js.map +1 -1
  85. package/dist/gateway/gateway-types.d.ts +1 -1
  86. package/dist/gateway/gateway-types.d.ts.map +1 -1
  87. package/dist/gateway/gateway-types.js.map +1 -1
  88. package/dist/memory/db.d.ts +13 -1
  89. package/dist/memory/db.d.ts.map +1 -1
  90. package/dist/memory/db.js +165 -45
  91. package/dist/memory/db.js.map +1 -1
  92. package/dist/onboarding.d.ts +1 -1
  93. package/dist/onboarding.d.ts.map +1 -1
  94. package/dist/onboarding.js +76 -11
  95. package/dist/onboarding.js.map +1 -1
  96. package/dist/providers/auxiliary.d.ts +1 -1
  97. package/dist/providers/auxiliary.d.ts.map +1 -1
  98. package/dist/providers/auxiliary.js.map +1 -1
  99. package/dist/providers/factory.d.ts.map +1 -1
  100. package/dist/providers/factory.js +3 -1
  101. package/dist/providers/factory.js.map +1 -1
  102. package/dist/providers/huggingface-discovery.d.ts.map +1 -1
  103. package/dist/providers/huggingface-discovery.js +1 -11
  104. package/dist/providers/huggingface-discovery.js.map +1 -1
  105. package/dist/providers/mistral-discovery.d.ts +20 -0
  106. package/dist/providers/mistral-discovery.d.ts.map +1 -0
  107. package/dist/providers/mistral-discovery.js +179 -0
  108. package/dist/providers/mistral-discovery.js.map +1 -0
  109. package/dist/providers/mistral-utils.d.ts +6 -0
  110. package/dist/providers/mistral-utils.d.ts.map +1 -0
  111. package/dist/providers/mistral-utils.js +16 -0
  112. package/dist/providers/mistral-utils.js.map +1 -0
  113. package/dist/providers/mistral.d.ts +4 -0
  114. package/dist/providers/mistral.d.ts.map +1 -0
  115. package/dist/providers/mistral.js +30 -0
  116. package/dist/providers/mistral.js.map +1 -0
  117. package/dist/providers/model-catalog.d.ts +1 -1
  118. package/dist/providers/model-catalog.d.ts.map +1 -1
  119. package/dist/providers/model-catalog.js +19 -3
  120. package/dist/providers/model-catalog.js.map +1 -1
  121. package/dist/providers/openrouter-discovery.d.ts.map +1 -1
  122. package/dist/providers/openrouter-discovery.js +1 -11
  123. package/dist/providers/openrouter-discovery.js.map +1 -1
  124. package/dist/providers/recommended-models.d.ts.map +1 -1
  125. package/dist/providers/recommended-models.js +19 -0
  126. package/dist/providers/recommended-models.js.map +1 -1
  127. package/dist/providers/task-routing.d.ts.map +1 -1
  128. package/dist/providers/task-routing.js +9 -0
  129. package/dist/providers/task-routing.js.map +1 -1
  130. package/dist/providers/types.d.ts +2 -2
  131. package/dist/providers/types.d.ts.map +1 -1
  132. package/dist/providers/utils.d.ts +1 -0
  133. package/dist/providers/utils.d.ts.map +1 -1
  134. package/dist/providers/utils.js +10 -0
  135. package/dist/providers/utils.js.map +1 -1
  136. package/dist/security/redact.d.ts +5 -0
  137. package/dist/security/redact.d.ts.map +1 -1
  138. package/dist/security/redact.js +186 -0
  139. package/dist/security/redact.js.map +1 -1
  140. package/dist/security/runtime-secrets.d.ts +1 -1
  141. package/dist/security/runtime-secrets.d.ts.map +1 -1
  142. package/dist/security/runtime-secrets.js +1 -0
  143. package/dist/security/runtime-secrets.js.map +1 -1
  144. package/dist/session/session-preview.d.ts +15 -0
  145. package/dist/session/session-preview.d.ts.map +1 -0
  146. package/dist/session/session-preview.js +49 -0
  147. package/dist/session/session-preview.js.map +1 -0
  148. package/dist/session/session-trace-export.d.ts +16 -0
  149. package/dist/session/session-trace-export.d.ts.map +1 -0
  150. package/dist/session/session-trace-export.js +1296 -0
  151. package/dist/session/session-trace-export.js.map +1 -0
  152. package/dist/tui-slash-command.d.ts.map +1 -1
  153. package/dist/tui-slash-command.js +8 -0
  154. package/dist/tui-slash-command.js.map +1 -1
  155. package/dist/tui.d.ts.map +1 -1
  156. package/dist/tui.js +16 -2
  157. package/dist/tui.js.map +1 -1
  158. package/dist/types/models.d.ts +1 -1
  159. package/dist/types/models.d.ts.map +1 -1
  160. package/dist/types/models.js.map +1 -1
  161. package/dist/utils/secret-prompt.d.ts.map +1 -1
  162. package/dist/utils/secret-prompt.js +4 -0
  163. package/dist/utils/secret-prompt.js.map +1 -1
  164. package/dist/workspace.d.ts.map +1 -1
  165. package/dist/workspace.js +1 -0
  166. package/dist/workspace.js.map +1 -1
  167. package/docs/404.html +6 -6
  168. package/docs/agents.html +1 -1
  169. package/docs/chat.html +244 -14
  170. package/docs/development/README.md +19 -12
  171. package/docs/development/agents.md +66 -0
  172. package/docs/development/getting-started/quickstart.md +1 -1
  173. package/docs/development/index.html +9 -20
  174. package/docs/development/internals/releasing.md +6 -4
  175. package/docs/docs/index.html +33 -0
  176. package/docs/index.html +353 -49
  177. package/docs/static/{development-docs.js → docs.js} +17 -6
  178. package/package.json +2 -2
  179. package/skills/1password/SKILL.md +1 -1
  180. package/skills/apple-calendar/SKILL.md +1 -1
  181. package/skills/apple-music/SKILL.md +1 -1
  182. package/skills/apple-passwords/SKILL.md +1 -1
  183. package/skills/channel-catchup/SKILL.md +1 -1
  184. package/skills/code-review/SKILL.md +1 -1
  185. package/skills/code-simplification/SKILL.md +1 -1
  186. package/skills/current-time/SKILL.md +1 -1
  187. package/skills/discord/SKILL.md +1 -1
  188. package/skills/docx/SKILL.md +1 -1
  189. package/skills/feature-planning/SKILL.md +1 -1
  190. package/skills/github-pr-workflow/SKILL.md +1 -1
  191. package/skills/google-workspace/SKILL.md +1 -1
  192. package/skills/hybridclaw-help/SKILL.md +102 -0
  193. package/skills/iss-position/SKILL.md +1 -1
  194. package/skills/notion/SKILL.md +1 -1
  195. package/skills/obsidian/SKILL.md +113 -0
  196. package/skills/obsidian/agents/openai.yaml +4 -0
  197. package/skills/office-workflows/SKILL.md +1 -1
  198. package/skills/pdf/SKILL.md +1 -1
  199. package/skills/personality/SKILL.md +1 -1
  200. package/skills/pptx/SKILL.md +1 -1
  201. package/skills/project-manager/SKILL.md +1 -1
  202. package/skills/skill-creator/SKILL.md +1 -1
  203. package/skills/stripe/SKILL.md +1 -1
  204. package/skills/trello/SKILL.md +1 -1
  205. package/skills/wordpress/SKILL.md +1 -1
  206. package/skills/write-blog-post/SKILL.md +1 -1
  207. package/skills/xlsx/SKILL.md +1 -1
  208. package/templates/SOUL.md +1 -1
  209. package/dist/gateway/development-docs.d.ts +0 -4
  210. package/dist/gateway/development-docs.d.ts.map +0 -1
  211. package/dist/gateway/development-docs.js.map +0 -1
  212. /package/docs/static/{development-docs.css → docs.css} +0 -0
package/AGENTS.md CHANGED
@@ -21,7 +21,7 @@ HybridClaw is a personal AI assistant bot for Discord, powered by HybridAI.
21
21
  Enterprise-grade Node.js 22 application with gateway service, TUI client, and
22
22
  Docker-sandboxed container runtime.
23
23
 
24
- **Version:** 0.7.1  |  **Package:** `@hybridaione/hybridclaw`
24
+ **Version:** 0.9.7  |  **Package:** `@hybridaione/hybridclaw`
25
25
   |  **License:** see `LICENSE`
26
26
 
27
27
  Architecture: gateway (core runtime, SQLite persistence, REST API, Discord
package/CHANGELOG.md CHANGED
@@ -2,6 +2,61 @@
2
2
 
3
3
  ## [Coming up]
4
4
 
5
+ ## [0.9.7](https://github.com/HybridAIOne/hybridclaw/tree/v0.9.7)
6
+
7
+ ### Added
8
+
9
+ - **Mistral provider support**: Added
10
+ `hybridclaw auth login|status|logout mistral`, support for
11
+ `mistral/...` model ids in selection commands, runtime credential handling
12
+ for Mistral requests, discovered model catalog entries with canonical-name,
13
+ context-window, and vision metadata, and recommended-model coverage in
14
+ selectors and status output.
15
+ - **ATIF-compatible trace export**: Added `export trace [sessionId|all|--all]`
16
+ across gateway, TUI, and chat command surfaces so operators can export
17
+ structured debug trace JSONL with tool calls, token usage, git context,
18
+ attribution metadata, and compatibility fields for downstream trace tooling.
19
+ - **HybridClaw docs and help retrieval**: Added a searchable `/docs` browser
20
+ docs shell, raw-markdown `/docs/agents.md`, the bundled
21
+ `hybridclaw-help` skill, and prompt-hook routing that fetches public docs
22
+ before answering HybridClaw product questions.
23
+ - **Obsidian bundled skill**: Added a first-party `obsidian` skill plus agent
24
+ metadata for vault-aware note search, creation, moves, and link-preserving
25
+ edits.
26
+
27
+ ### Changed
28
+
29
+ - **Web chat streaming and replay UX**: Simplified stream frame state and
30
+ replay reuse, added NDJSON fallback handling plus decoder-tail flushing,
31
+ batched DOM updates, and preserved scroll position during streaming so the
32
+ built-in web chat behaves more smoothly under live output.
33
+ - **Session previews and export UX**: Shared conversation-preview helpers
34
+ across sessions and agent cards, added clearer timestamp/snippet output in
35
+ `/sessions`, and exposed the new `export session` and `export trace`
36
+ subcommands consistently in help text and slash menus.
37
+ - **Docker images and publish pipeline**: Reworked the gateway and agent
38
+ Dockerfiles into clearer multi-stage builds, added the agent `runtime-lite`
39
+ target plus `HYBRIDCLAW_CONTAINER_TARGET`, and added CI Docker preflight
40
+ builds plus explicit runtime targets in publish workflows.
41
+ - **Public docs routing and landing pages**: Moved the browsable docs shell to
42
+ `/docs`, kept the legacy `/development` entry as a redirect, refreshed the
43
+ static docs assets, and added a HybridClaw Cloud callout across the public
44
+ landing page.
45
+
46
+ ### Fixed
47
+
48
+ - **Local iMessage self-chat fallback**: Skipped attributed-body-only
49
+ self-chat rows that look like replayed history or control commands so local
50
+ iMessage polling no longer injects stale self-chat content.
51
+ - **Trace export and secret redaction hardening**: Expanded redaction coverage
52
+ for GitHub/npm tokens, emails, IPs, phone numbers, SSNs, credit cards, and
53
+ high-entropy strings, anonymized runner-home paths in trace exports, and
54
+ restored paused TTY state after hidden secret prompts.
55
+ - **Mistral discovery and container build polish**: Tightened canonical and
56
+ deprecated Mistral model handling plus availability checks, and fixed
57
+ container/gateway Docker builds around native addons, dependency pruning,
58
+ runtime targets, and npm prune failure modes.
59
+
5
60
  ## [0.9.6](https://github.com/HybridAIOne/hybridclaw/tree/v0.9.6)
6
61
 
7
62
  ### Changed
package/README.md CHANGED
@@ -44,6 +44,8 @@ hybridclaw onboarding
44
44
  Prerequisites: Node.js 22. Docker is recommended when you want the default
45
45
  container sandbox. The published install bootstraps the packaged container
46
46
  runtime dependencies during `npm install -g`.
47
+ The current release tag is
48
+ [v0.9.7](https://github.com/HybridAIOne/hybridclaw/releases/tag/v0.9.7).
47
49
  Release notes live in [CHANGELOG.md](./CHANGELOG.md), and the browsable
48
50
  operator and maintainer manual lives under
49
51
  [docs/development/README.md](./docs/development/README.md).
@@ -125,18 +127,21 @@ hybridclaw auth login hybridai --browser
125
127
  hybridclaw auth login hybridai --base-url http://localhost:5000
126
128
  hybridclaw auth login codex --import
127
129
  hybridclaw auth login openrouter anthropic/claude-sonnet-4 --api-key sk-or-...
130
+ hybridclaw auth login mistral mistral-large-latest --api-key mistral_...
128
131
  hybridclaw auth login huggingface meta-llama/Llama-3.1-8B-Instruct --api-key hf_...
129
132
  hybridclaw auth login local ollama llama3.2
130
133
  hybridclaw auth login msteams --app-id 00000000-0000-0000-0000-000000000000 --tenant-id 11111111-1111-1111-1111-111111111111 --app-password secret
131
134
  hybridclaw auth status hybridai
132
135
  hybridclaw auth status codex
133
136
  hybridclaw auth status openrouter
137
+ hybridclaw auth status mistral
134
138
  hybridclaw auth status huggingface
135
139
  hybridclaw auth status local
136
140
  hybridclaw auth status msteams
137
141
  hybridclaw auth logout hybridai
138
142
  hybridclaw auth logout codex
139
143
  hybridclaw auth logout openrouter
144
+ hybridclaw auth logout mistral
140
145
  hybridclaw auth logout huggingface
141
146
  hybridclaw auth logout local
142
147
  hybridclaw auth logout msteams
@@ -155,6 +160,7 @@ hybridclaw local configure ollama llama3.2
155
160
  - `hybridclaw auth login hybridai` auto-selects browser login on local GUI machines and a manual/headless API-key flow on SSH, CI, and container shells. `--import` copies the current `HYBRIDAI_API_KEY` from your shell into `~/.hybridclaw/credentials.json`, and `--base-url` updates `hybridai.baseUrl` before login.
156
161
  - `hybridclaw auth login codex` auto-selects browser PKCE on local GUI machines and device code on headless or remote shells.
157
162
  - `hybridclaw auth login openrouter` accepts `--api-key`, falls back to `OPENROUTER_API_KEY`, or prompts you to paste the key, then enables the provider and can set the global default model.
163
+ - `hybridclaw auth login mistral` accepts `--api-key`, falls back to `MISTRAL_API_KEY`, or prompts you to paste the key, then enables the provider and can set the global default model.
158
164
  - `hybridclaw auth login huggingface` accepts `--api-key`, falls back to `HF_TOKEN`, or prompts you to paste the token, then enables the provider and can set the global default model.
159
165
  - `hybridclaw auth login local` configures Ollama, LM Studio, or vLLM in `~/.hybridclaw/config.json`.
160
166
  - `hybridclaw auth login msteams` enables Microsoft Teams, stores `MSTEAMS_APP_PASSWORD` in `~/.hybridclaw/credentials.json`, and can prompt for the app id, app password, and optional tenant id.
@@ -162,9 +168,9 @@ hybridclaw local configure ollama llama3.2
162
168
  - `hybridclaw auth logout local` disables configured local backends and clears any saved vLLM API key.
163
169
  - `hybridclaw auth logout msteams` clears the stored Teams app password and disables the Teams integration in config.
164
170
  - `hybridclaw auth whatsapp reset` clears linked WhatsApp Web auth without starting a new pairing session.
165
- - HybridAI, OpenRouter, Hugging Face, Discord, email, Teams, and BlueBubbles iMessage secrets are stored in `~/.hybridclaw/credentials.json`. Codex OAuth credentials are stored separately in `~/.hybridclaw/codex-auth.json`.
171
+ - HybridAI, OpenRouter, Mistral, Hugging Face, Discord, email, Teams, and BlueBubbles iMessage secrets are stored in `~/.hybridclaw/credentials.json`. Codex OAuth credentials are stored separately in `~/.hybridclaw/codex-auth.json`.
166
172
  - Only one running HybridClaw process should own `~/.hybridclaw/credentials/whatsapp` at a time. If WhatsApp Web shows duplicate Chrome/Ubuntu linked devices or reconnect/auth drift starts, stop the extra process, run `hybridclaw auth whatsapp reset`, then pair again with `hybridclaw channels whatsapp setup`.
167
- - Use `hybridclaw help`, `hybridclaw help auth`, `hybridclaw help openrouter`, `hybridclaw help huggingface`, or `hybridclaw help local` for CLI-specific reference output.
173
+ - Use `hybridclaw help`, `hybridclaw help auth`, `hybridclaw help openrouter`, `hybridclaw help mistral`, `hybridclaw help huggingface`, or `hybridclaw help local` for CLI-specific reference output.
168
174
 
169
175
  ## Setting Up MS Teams
170
176
 
@@ -188,7 +194,7 @@ See [docs/imessage.md](./docs/imessage.md) for the full setup flow, including:
188
194
 
189
195
  ## Model Selection
190
196
 
191
- Codex models use the `openai-codex/` prefix. OpenRouter models use the `openrouter/` prefix. Hugging Face router models use the `huggingface/` prefix. The default shipped Codex model is `openai-codex/gpt-5-codex`.
197
+ Codex models use the `openai-codex/` prefix. OpenRouter models use the `openrouter/` prefix. Mistral models use the `mistral/` prefix. Hugging Face router models use the `huggingface/` prefix. The default shipped Codex model is `openai-codex/gpt-5-codex`.
192
198
 
193
199
  Examples:
194
200
 
@@ -198,6 +204,8 @@ Examples:
198
204
  /model default openai-codex/gpt-5-codex
199
205
  /model list openrouter
200
206
  /model set openrouter/anthropic/claude-sonnet-4
207
+ /model list mistral
208
+ /model set mistral/mistral-large-latest
201
209
  /model list huggingface
202
210
  /model set huggingface/meta-llama/Llama-3.1-8B-Instruct
203
211
  /model clear
@@ -206,13 +214,15 @@ Examples:
206
214
  /model default openrouter/anthropic/claude-sonnet-4
207
215
  ```
208
216
 
209
- - `hybridai.defaultModel` in `~/.hybridclaw/config.json` can point at a HybridAI model, an `openai-codex/...` model, an `openrouter/...` model, a `huggingface/...` model, or a local backend model such as `ollama/...`.
217
+ - `hybridai.defaultModel` in `~/.hybridclaw/config.json` can point at a HybridAI model, an `openai-codex/...` model, an `openrouter/...` model, a `mistral/...` model, a `huggingface/...` model, or a local backend model such as `ollama/...`.
210
218
  - `codex.models` in runtime config controls the allowed Codex model list shown in selectors and status output.
211
219
  - `openrouter.models` in runtime config controls the allowed OpenRouter model list shown in selectors and status output.
220
+ - `mistral.models` in runtime config controls the allowed Mistral model list shown in selectors and status output.
212
221
  - `huggingface.models` in runtime config controls the allowed Hugging Face model list shown in selectors and status output.
213
222
  - HybridAI model lists are refreshed from the configured HybridAI base URL (`/models`, then `/v1/models` as a compatibility fallback), and discovered `context_length` values feed status and model-info output when the API exposes them.
214
223
  - When the selected model starts with `openai-codex/`, HybridClaw resolves OAuth credentials through the Codex provider instead of `HYBRIDAI_API_KEY`.
215
224
  - When the selected model starts with `openrouter/`, HybridClaw resolves credentials through `OPENROUTER_API_KEY`.
225
+ - When the selected model starts with `mistral/`, HybridClaw resolves credentials through `MISTRAL_API_KEY`.
216
226
  - When the selected model starts with `huggingface/`, HybridClaw resolves credentials through `HF_TOKEN`.
217
227
  - `/model set <name>` is a session-only override.
218
228
  - `/model clear` removes the session override and falls back to the current agent model or the global default.
@@ -565,7 +575,7 @@ CLI runtime commands:
565
575
  - `hybridclaw tui --resume <sessionId>` / `hybridclaw --resume <sessionId>` — Resume an earlier TUI session by canonical session id
566
576
  - `hybridclaw onboarding` — Run trust-model acceptance plus interactive provider onboarding
567
577
  - `hybridclaw auth login [provider] ...` — Namespaced provider setup/login entrypoint
568
- - `hybridclaw auth status <provider>` — Show provider status for `hybridai`, `codex`, `openrouter`, `local`, or `msteams`
578
+ - `hybridclaw auth status <provider>` — Show provider status for `hybridai`, `codex`, `openrouter`, `mistral`, `huggingface`, `local`, or `msteams`
569
579
  - `hybridclaw auth logout <provider>` — Clear provider credentials or disable local backends/Teams
570
580
  - `hybridclaw config`, `check`, `reload`, `set <key> <value>` — Inspect, validate, hot-reload, or edit the local runtime config file
571
581
  - `hybridclaw auth login msteams [--app-id <id>] [--app-password <secret>] [--tenant-id <id>]` — Enable Microsoft Teams, persist the app secret, and print webhook next steps
@@ -578,7 +588,7 @@ CLI runtime commands:
578
588
  - `hybridclaw local status` — Show current local backend config and default model
579
589
  - `hybridclaw local configure <backend> <model-id> [--base-url <url>] [--api-key <key>] [--no-default]` — Enable and configure a local backend
580
590
  - `hybridclaw hybridai ...`, `hybridclaw codex ...`, and `hybridclaw local ...` — Legacy aliases for the older provider-specific command surface
581
- - `hybridclaw help` / `hybridclaw help auth` / `hybridclaw help openrouter` — Print CLI reference for the unified provider commands
591
+ - `hybridclaw help` / `hybridclaw help auth` / `hybridclaw help openrouter` / `hybridclaw help mistral` — Print CLI reference for the unified provider commands
582
592
  - `hybridclaw doctor [--fix|--json|<component>]` — Diagnose runtime, gateway, config, credentials, database, providers, local backends, Docker, channels, skills, security, and disk state
583
593
  - `hybridclaw skill list` — Show skills and any declared installer options
584
594
  - `hybridclaw skill enable <skill-name> [--channel <kind>]`, `disable`, `toggle` — Manage global and per-channel skill availability
@@ -615,6 +625,7 @@ In Discord, use `!claw help` or the slash commands. Key ones:
615
625
  - `!claw audit approvals [n] [--denied]` — Show policy approval decisions
616
626
  - `!claw usage [summary|daily|monthly|model [daily|monthly] [agentId]]` — Show token/cost aggregates
617
627
  - `!claw export session [sessionId]` — Export session snapshot as JSONL
628
+ - `!claw export trace [sessionId|all]` — Export ATIF-compatible trace JSONL for one session or every session
618
629
  - `!claw mcp list` — List configured MCP servers
619
630
  - `!claw mcp add <name> <json>` — Add or update an MCP server config
620
631
  - `!claw schedule add "<cron>" <prompt>` — Add cron scheduled task
@@ -191,6 +191,11 @@
191
191
  "baseUrl": "https://openrouter.ai/api/v1",
192
192
  "models": ["openrouter/anthropic/claude-sonnet-4"]
193
193
  },
194
+ "mistral": {
195
+ "enabled": false,
196
+ "baseUrl": "https://api.mistral.ai/v1",
197
+ "models": ["mistral/mistral-large-latest"]
198
+ },
194
199
  "huggingface": {
195
200
  "enabled": false,
196
201
  "baseUrl": "https://router.huggingface.co/v1",
@@ -14,3 +14,5 @@ yarn-error.log*
14
14
  *.sqlite
15
15
  *.db
16
16
  *.log
17
+ *.md
18
+ scripts/
@@ -1,42 +1,70 @@
1
- FROM node:20-slim
1
+ # --- Build stage ---
2
+ FROM node:22-slim@sha256:80fdb3f57c815e1b638d221f30a826823467c4a56c8f6a8d7aa091cd9b1675ea AS builder
3
+ WORKDIR /app
4
+ COPY package.json package-lock.json ./
5
+ RUN --mount=type=cache,target=/root/.npm \
6
+ npm ci
7
+ COPY tsconfig.json ./
8
+ COPY shared/ shared/
9
+ COPY src/ src/
10
+ RUN npx tsc
11
+
12
+ # --- Runtime base (no LibreOffice) ---
13
+ FROM node:22-slim@sha256:80fdb3f57c815e1b638d221f30a826823467c4a56c8f6a8d7aa091cd9b1675ea AS runtime-lite
2
14
 
3
- RUN apt-get update && apt-get install -y --no-install-recommends \
4
- ripgrep git curl python3 python3-pip poppler-utils qpdf pandoc \
5
- libreoffice-calc libreoffice-impress libreoffice-writer \
6
- && rm -rf /var/lib/apt/lists/*
15
+ LABEL org.opencontainers.image.source="https://github.com/HybridAIOne/hybridclaw"
16
+ LABEL org.opencontainers.image.description="HybridClaw sandboxed agent runtime"
7
17
 
8
- RUN python3 -m pip install --no-cache-dir --break-system-packages \
9
- uv \
18
+ RUN --mount=type=cache,target=/var/cache/apt \
19
+ --mount=type=cache,target=/var/lib/apt/lists \
20
+ apt-get update && apt-get install -y --no-install-recommends \
21
+ ripgrep git curl python3 python3-pip poppler-utils qpdf pandoc
22
+
23
+ RUN --mount=type=cache,target=/root/.cache/pip \
24
+ python3 -m pip install --break-system-packages \
10
25
  pypdf==5.4.0 \
11
26
  pdfplumber==0.11.6 \
12
27
  pdf2image==1.17.0 \
13
28
  reportlab==4.4.4 \
14
29
  pillow==11.3.0
15
30
 
16
- RUN npm install -g \
31
+ RUN --mount=type=cache,target=/root/.npm \
32
+ npm install -g \
17
33
  docx@9.5.1 \
18
34
  pptxgenjs@4.0.1 \
19
35
  csv-parse@6.1.0 \
20
36
  iconv-lite@0.7.0 \
21
37
  xlsx-populate@1.21.0
22
- ENV NODE_PATH=/usr/local/lib/node_modules:/app/node_modules
23
38
 
24
- WORKDIR /app
25
-
26
- COPY package.json tsconfig.json ./
27
- RUN npm install
39
+ ENV NODE_PATH=/usr/local/lib/node_modules:/app/node_modules
28
40
  ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
29
- RUN npx playwright install --with-deps chromium
30
- RUN npx playwright install --with-deps --only-shell chromium
31
41
 
32
- COPY shared/ shared/
33
- COPY src/ src/
34
- RUN npx tsc
42
+ WORKDIR /app
35
43
 
36
- RUN chown -R node:node /app /ms-playwright
44
+ COPY --link --from=builder /app/package.json /app/package-lock.json ./
45
+ RUN --mount=type=cache,target=/root/.npm \
46
+ npm ci --omit=dev
37
47
 
48
+ # System deps need root; browser installed as node user so /ms-playwright stays owned by node:node
49
+ RUN npx playwright install-deps chromium \
50
+ && mkdir -p /ms-playwright \
51
+ && chown -R node:node /app /ms-playwright
38
52
  USER node
53
+ RUN npx playwright install --only-shell chromium
39
54
 
40
- WORKDIR /workspace
55
+ COPY --link --from=builder /app/dist/ dist/
56
+ COPY --link --from=builder /app/shared/ shared/
41
57
 
58
+ STOPSIGNAL SIGTERM
59
+ WORKDIR /workspace
42
60
  ENTRYPOINT ["node", "/app/dist/index.js"]
61
+
62
+ # --- Full runtime (with LibreOffice) ---
63
+ FROM runtime-lite AS runtime
64
+
65
+ USER root
66
+ RUN --mount=type=cache,target=/var/cache/apt \
67
+ --mount=type=cache,target=/var/lib/apt/lists \
68
+ apt-get update && apt-get install -y --no-install-recommends \
69
+ libreoffice-calc libreoffice-impress libreoffice-writer
70
+ USER node
@@ -27,6 +27,7 @@ const DEFAULT_POLICY = {
27
27
  { paths: ['~/.ssh/**', '/etc/**', '.env*'] },
28
28
  { tools: ['force_push'] },
29
29
  ],
30
+ trustedNetworkHosts: ['hybridclaw.io'],
30
31
  workspaceFence: true,
31
32
  maxPendingApprovals: 3,
32
33
  approvalTimeoutSecs: 120,
@@ -264,6 +265,10 @@ function parsePolicyYaml(raw) {
264
265
  if (key === 'workspace_fence') {
265
266
  policy.workspaceFence = parseBool(rawValue, DEFAULT_POLICY.workspaceFence);
266
267
  }
268
+ else if (key === 'trusted_network_hosts') {
269
+ policy.trustedNetworkHosts =
270
+ parseInlineList(rawValue).length > 0 ? parseInlineList(rawValue) : [];
271
+ }
267
272
  else if (key === 'max_pending_approvals') {
268
273
  policy.maxPendingApprovals = Math.max(1, parseIntStrict(rawValue, DEFAULT_POLICY.maxPendingApprovals));
269
274
  }
@@ -310,6 +315,10 @@ function loadPolicyFromDisk(policyPath) {
310
315
  pinnedRed: Array.isArray(filePolicy.pinnedRed) && filePolicy.pinnedRed.length > 0
311
316
  ? filePolicy.pinnedRed
312
317
  : DEFAULT_POLICY.pinnedRed,
318
+ trustedNetworkHosts: Array.isArray(filePolicy.trustedNetworkHosts) &&
319
+ filePolicy.trustedNetworkHosts.length > 0
320
+ ? filePolicy.trustedNetworkHosts.map(normalizeHostScope)
321
+ : DEFAULT_POLICY.trustedNetworkHosts.map(normalizeHostScope),
313
322
  workspaceFence: typeof filePolicy.workspaceFence === 'boolean'
314
323
  ? filePolicy.workspaceFence
315
324
  : DEFAULT_POLICY.workspaceFence,
@@ -767,6 +776,10 @@ export class TrustedCoworkerApprovalRuntime {
767
776
  return (this.fullAutoNeverApprove.has(normalizedTool) ||
768
777
  this.fullAutoNeverApprove.has(normalizedAction));
769
778
  }
779
+ isTrustedNetworkHost(host) {
780
+ const normalized = normalizeHostScope(host);
781
+ return this.loadedPolicy.trustedNetworkHosts.includes(normalized);
782
+ }
770
783
  reloadPolicyIfNeeded(force = false) {
771
784
  let mtimeMs = -1;
772
785
  try {
@@ -1232,15 +1245,19 @@ export class TrustedCoworkerApprovalRuntime {
1232
1245
  }
1233
1246
  })();
1234
1247
  const primaryHost = providerHosts[0] || 'web-search';
1235
- const unseen = providerHosts.filter((host) => !this.seenNetworkHosts.has(host));
1248
+ const unseen = providerHosts.filter((host) => !this.isTrustedNetworkHost(host) && !this.seenNetworkHosts.has(host));
1249
+ const allTrusted = providerHosts.length > 0 &&
1250
+ providerHosts.every((host) => this.isTrustedNetworkHost(host));
1236
1251
  return {
1237
- tier: unseen.length > 0 ? 'red' : 'yellow',
1252
+ tier: allTrusted ? 'green' : unseen.length > 0 ? 'red' : 'yellow',
1238
1253
  actionKey: `network:${primaryHost}`,
1239
1254
  intent: `search the web via ${provider || 'configured providers'}`,
1240
1255
  consequenceIfDenied: 'I will avoid external search providers and continue with local context only.',
1241
- reason: unseen.length > 0
1242
- ? 'this would contact a new external host'
1243
- : 'this is an external network action',
1256
+ reason: allTrusted
1257
+ ? 'this host is allowlisted in approval policy'
1258
+ : unseen.length > 0
1259
+ ? 'this would contact a new external host'
1260
+ : 'this is an external network action',
1244
1261
  commandPreview: normalizePreview(JSON.stringify(args)),
1245
1262
  pathHints: [],
1246
1263
  hostHints: providerHosts,
@@ -1255,15 +1272,19 @@ export class TrustedCoworkerApprovalRuntime {
1255
1272
  const rawUrl = normalizeText(args.url);
1256
1273
  const hostScopes = extractHostScopes(extractHostsFromUrlLikeText(rawUrl));
1257
1274
  const primaryHost = hostScopes[0] || 'unknown-host';
1258
- const unseen = hostScopes.filter((host) => !this.seenNetworkHosts.has(host));
1275
+ const unseen = hostScopes.filter((host) => !this.isTrustedNetworkHost(host) && !this.seenNetworkHosts.has(host));
1276
+ const allTrusted = hostScopes.length > 0 &&
1277
+ hostScopes.every((host) => this.isTrustedNetworkHost(host));
1259
1278
  return {
1260
- tier: unseen.length > 0 ? 'red' : 'yellow',
1279
+ tier: allTrusted ? 'green' : unseen.length > 0 ? 'red' : 'yellow',
1261
1280
  actionKey: `network:${primaryHost}`,
1262
1281
  intent: `access ${primaryHost}`,
1263
1282
  consequenceIfDenied: 'I will avoid contacting that host and use existing local context only.',
1264
- reason: unseen.length > 0
1265
- ? 'this would contact a new external host'
1266
- : 'this is an external network action',
1283
+ reason: allTrusted
1284
+ ? 'this host is allowlisted in approval policy'
1285
+ : unseen.length > 0
1286
+ ? 'this would contact a new external host'
1287
+ : 'this is an external network action',
1267
1288
  commandPreview: normalizePreview(rawUrl),
1268
1289
  pathHints: [],
1269
1290
  hostHints: hostScopes,