@openparachute/agent 0.1.2 → 0.2.2

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 (608) hide show
  1. package/.parachute/module.json +124 -8
  2. package/LICENSE +2 -16
  3. package/README.md +118 -166
  4. package/package.json +35 -42
  5. package/scripts/spawn-agent.ts +371 -0
  6. package/src/_parked/interactive-spawn.test.ts +324 -0
  7. package/src/_parked/interactive-spawn.ts +701 -0
  8. package/src/agent-defs.test.ts +1504 -0
  9. package/src/agent-defs.ts +1702 -0
  10. package/src/agent-mcp-config.test.ts +115 -0
  11. package/src/agent-mcp-config.ts +115 -0
  12. package/src/agents.test.ts +360 -0
  13. package/src/agents.ts +379 -0
  14. package/src/auth.test.ts +46 -0
  15. package/src/auth.ts +140 -0
  16. package/src/backends/attached-queue.test.ts +376 -0
  17. package/src/backends/attached-queue.ts +372 -0
  18. package/src/backends/programmatic.test.ts +1715 -0
  19. package/src/backends/programmatic.ts +927 -0
  20. package/src/backends/registry.test.ts +1494 -0
  21. package/src/backends/registry.ts +1202 -0
  22. package/src/backends/stream-json.test.ts +570 -0
  23. package/src/backends/stream-json.ts +392 -0
  24. package/src/backends/types.ts +223 -0
  25. package/src/bridge.ts +417 -0
  26. package/src/channel-backend-wiring.test.ts +237 -0
  27. package/src/credentials.test.ts +274 -0
  28. package/src/credentials.ts +380 -0
  29. package/src/cron.test.ts +342 -0
  30. package/src/cron.ts +380 -0
  31. package/src/daemon-agent-def-api.test.ts +166 -0
  32. package/src/daemon-agent-defs-api.test.ts +953 -0
  33. package/src/daemon-agent-env-api.test.ts +338 -0
  34. package/src/daemon-attached-queue-store.test.ts +65 -0
  35. package/src/daemon-config-api.test.ts +962 -0
  36. package/src/daemon-jobs-api.test.ts +271 -0
  37. package/src/daemon-vault-chat.test.ts +250 -0
  38. package/src/daemon.test.ts +746 -0
  39. package/src/daemon.ts +3314 -0
  40. package/src/def-vaults.test.ts +136 -0
  41. package/src/def-vaults.ts +165 -0
  42. package/src/delivery-state.test.ts +110 -0
  43. package/src/delivery-state.ts +154 -0
  44. package/src/effective-env.test.ts +114 -0
  45. package/src/effective-env.ts +184 -0
  46. package/src/env-compat.ts +39 -0
  47. package/src/grants.test.ts +638 -0
  48. package/src/grants.ts +675 -0
  49. package/src/hub-jwt.test.ts +161 -0
  50. package/src/hub-jwt.ts +182 -0
  51. package/src/jobs.test.ts +245 -0
  52. package/src/jobs.ts +266 -0
  53. package/src/mcp-http.test.ts +265 -0
  54. package/src/mcp-http.ts +771 -0
  55. package/src/mint-token.test.ts +152 -0
  56. package/src/mint-token.ts +139 -0
  57. package/src/module-manifest.test.ts +158 -0
  58. package/src/oauth-discovery.ts +134 -0
  59. package/src/programmatic-wiring.test.ts +838 -0
  60. package/src/registry.test.ts +227 -0
  61. package/src/registry.ts +228 -0
  62. package/src/resolve-port.test.ts +64 -0
  63. package/src/routing.test.ts +184 -0
  64. package/src/routing.ts +76 -0
  65. package/src/runner.test.ts +506 -0
  66. package/src/runner.ts +255 -0
  67. package/src/sandbox/config.test.ts +150 -0
  68. package/src/sandbox/config.ts +102 -0
  69. package/src/sandbox/egress.test.ts +113 -0
  70. package/src/sandbox/egress.ts +123 -0
  71. package/src/sandbox/index.ts +180 -0
  72. package/src/sandbox/live-seatbelt.test.ts +277 -0
  73. package/src/sandbox/mounts.test.ts +154 -0
  74. package/src/sandbox/mounts.ts +133 -0
  75. package/src/sandbox/sandbox.test.ts +168 -0
  76. package/src/sandbox/types.ts +382 -0
  77. package/src/services-manifest.test.ts +106 -0
  78. package/src/services-manifest.ts +95 -0
  79. package/src/spa-serve.test.ts +116 -0
  80. package/src/spa-serve.ts +116 -0
  81. package/src/spawn-agent-cli.test.ts +172 -0
  82. package/src/spawn-agent.test.ts +1218 -0
  83. package/src/spawn-agent.ts +569 -0
  84. package/src/spawn-deps.test.ts +54 -0
  85. package/src/spawn-deps.ts +166 -0
  86. package/src/telegram/api.ts +153 -0
  87. package/src/terminal-assets.test.ts +50 -0
  88. package/src/terminal-assets.ts +79 -0
  89. package/src/terminal-ui.ts +305 -0
  90. package/src/terminal.test.ts +530 -0
  91. package/src/terminal.ts +458 -0
  92. package/src/transport.ts +270 -0
  93. package/src/transports/http-ui.test.ts +455 -0
  94. package/src/transports/http-ui.ts +201 -0
  95. package/src/transports/telegram.test.ts +174 -0
  96. package/src/transports/telegram.ts +426 -0
  97. package/src/transports/vault.test.ts +2011 -0
  98. package/src/transports/vault.ts +1790 -0
  99. package/src/ui-kit.test.ts +178 -0
  100. package/src/ui-kit.ts +402 -0
  101. package/tsconfig.json +8 -14
  102. package/web/ui/dist/assets/index-C-iWdFFV.css +1 -0
  103. package/web/ui/dist/assets/index-VFETBk0a.js +60 -0
  104. package/web/ui/dist/index.html +15 -0
  105. package/web/ui/tsconfig.json +2 -1
  106. package/.claude/scheduled_tasks.lock +0 -1
  107. package/.claude/settings.json +0 -5
  108. package/.claude/skills/add-atomic-chat-tool/SKILL.md +0 -243
  109. package/.claude/skills/add-atomic-chat-tool/atomic-chat-mcp-stdio.ts +0 -229
  110. package/.claude/skills/add-codex/SKILL.md +0 -161
  111. package/.claude/skills/add-dashboard/SKILL.md +0 -138
  112. package/.claude/skills/add-dashboard/resources/dashboard-pusher.ts +0 -495
  113. package/.claude/skills/add-emacs/SKILL.md +0 -296
  114. package/.claude/skills/add-gcal-tool/SKILL.md +0 -210
  115. package/.claude/skills/add-gchat/REMOVE.md +0 -6
  116. package/.claude/skills/add-gchat/SKILL.md +0 -92
  117. package/.claude/skills/add-gchat/VERIFY.md +0 -3
  118. package/.claude/skills/add-github/REMOVE.md +0 -6
  119. package/.claude/skills/add-github/SKILL.md +0 -148
  120. package/.claude/skills/add-github/VERIFY.md +0 -3
  121. package/.claude/skills/add-gmail-tool/SKILL.md +0 -229
  122. package/.claude/skills/add-imessage/REMOVE.md +0 -6
  123. package/.claude/skills/add-imessage/SKILL.md +0 -113
  124. package/.claude/skills/add-imessage/VERIFY.md +0 -3
  125. package/.claude/skills/add-karpathy-llm-wiki/SKILL.md +0 -110
  126. package/.claude/skills/add-karpathy-llm-wiki/llm-wiki.md +0 -75
  127. package/.claude/skills/add-linear/REMOVE.md +0 -6
  128. package/.claude/skills/add-linear/SKILL.md +0 -168
  129. package/.claude/skills/add-linear/VERIFY.md +0 -3
  130. package/.claude/skills/add-macos-statusbar/SKILL.md +0 -133
  131. package/.claude/skills/add-macos-statusbar/add/src/statusbar.swift +0 -147
  132. package/.claude/skills/add-matrix/REMOVE.md +0 -6
  133. package/.claude/skills/add-matrix/SKILL.md +0 -148
  134. package/.claude/skills/add-matrix/VERIFY.md +0 -3
  135. package/.claude/skills/add-ollama-provider/SKILL.md +0 -179
  136. package/.claude/skills/add-ollama-tool/SKILL.md +0 -193
  137. package/.claude/skills/add-opencode/SKILL.md +0 -229
  138. package/.claude/skills/add-parallel/SKILL.md +0 -290
  139. package/.claude/skills/add-resend/REMOVE.md +0 -6
  140. package/.claude/skills/add-resend/SKILL.md +0 -93
  141. package/.claude/skills/add-resend/VERIFY.md +0 -3
  142. package/.claude/skills/add-signal/REMOVE.md +0 -13
  143. package/.claude/skills/add-signal/SKILL.md +0 -318
  144. package/.claude/skills/add-signal/VERIFY.md +0 -5
  145. package/.claude/skills/add-slack/REMOVE.md +0 -6
  146. package/.claude/skills/add-slack/SKILL.md +0 -112
  147. package/.claude/skills/add-slack/VERIFY.md +0 -3
  148. package/.claude/skills/add-teams/REMOVE.md +0 -6
  149. package/.claude/skills/add-teams/SKILL.md +0 -207
  150. package/.claude/skills/add-teams/VERIFY.md +0 -3
  151. package/.claude/skills/add-vercel/SKILL.md +0 -147
  152. package/.claude/skills/add-vercel/container-skills/vercel-cli/SKILL.md +0 -103
  153. package/.claude/skills/add-webex/REMOVE.md +0 -6
  154. package/.claude/skills/add-webex/SKILL.md +0 -88
  155. package/.claude/skills/add-webex/VERIFY.md +0 -3
  156. package/.claude/skills/add-wechat/REMOVE.md +0 -49
  157. package/.claude/skills/add-wechat/SKILL.md +0 -170
  158. package/.claude/skills/add-wechat/scripts/wire-dm.ts +0 -172
  159. package/.claude/skills/add-whatsapp/SKILL.md +0 -264
  160. package/.claude/skills/add-whatsapp-cloud/REMOVE.md +0 -6
  161. package/.claude/skills/add-whatsapp-cloud/SKILL.md +0 -95
  162. package/.claude/skills/add-whatsapp-cloud/VERIFY.md +0 -3
  163. package/.claude/skills/claw/SKILL.md +0 -131
  164. package/.claude/skills/claw/scripts/claw +0 -374
  165. package/.claude/skills/convert-to-apple-container/SKILL.md +0 -212
  166. package/.claude/skills/customize/SKILL.md +0 -110
  167. package/.claude/skills/debug/SKILL.md +0 -349
  168. package/.claude/skills/get-qodo-rules/SKILL.md +0 -122
  169. package/.claude/skills/get-qodo-rules/references/output-format.md +0 -41
  170. package/.claude/skills/get-qodo-rules/references/pagination.md +0 -33
  171. package/.claude/skills/get-qodo-rules/references/repository-scope.md +0 -26
  172. package/.claude/skills/init-first-agent/SKILL.md +0 -120
  173. package/.claude/skills/init-onecli/SKILL.md +0 -270
  174. package/.claude/skills/manage-channels/SKILL.md +0 -87
  175. package/.claude/skills/manage-mounts/SKILL.md +0 -47
  176. package/.claude/skills/migrate-from-openclaw/MIGRATE_CRONS.md +0 -100
  177. package/.claude/skills/migrate-from-openclaw/SKILL.md +0 -447
  178. package/.claude/skills/migrate-from-openclaw/scripts/discover-openclaw.ts +0 -734
  179. package/.claude/skills/migrate-from-openclaw/scripts/extract-channel-credentials.ts +0 -476
  180. package/.claude/skills/migrate-nanoclaw/SKILL.md +0 -484
  181. package/.claude/skills/migrate-nanoclaw/diagnostics.md +0 -51
  182. package/.claude/skills/qodo-pr-resolver/SKILL.md +0 -326
  183. package/.claude/skills/qodo-pr-resolver/resources/providers.md +0 -329
  184. package/.claude/skills/update-nanoclaw/SKILL.md +0 -243
  185. package/.claude/skills/update-nanoclaw/diagnostics.md +0 -48
  186. package/.claude/skills/update-skills/SKILL.md +0 -130
  187. package/.claude/skills/use-native-credential-proxy/SKILL.md +0 -167
  188. package/.claude/skills/x-integration/SKILL.md +0 -417
  189. package/.claude/skills/x-integration/agent.ts +0 -243
  190. package/.claude/skills/x-integration/host.ts +0 -155
  191. package/.claude/skills/x-integration/lib/browser.ts +0 -148
  192. package/.claude/skills/x-integration/lib/config.ts +0 -62
  193. package/.claude/skills/x-integration/scripts/like.ts +0 -56
  194. package/.claude/skills/x-integration/scripts/post.ts +0 -66
  195. package/.claude/skills/x-integration/scripts/quote.ts +0 -80
  196. package/.claude/skills/x-integration/scripts/reply.ts +0 -74
  197. package/.claude/skills/x-integration/scripts/retweet.ts +0 -62
  198. package/.claude/skills/x-integration/scripts/setup.ts +0 -87
  199. package/.github/CODEOWNERS +0 -10
  200. package/.github/PULL_REQUEST_TEMPLATE.md +0 -18
  201. package/.github/workflows/bump-version.yml +0 -35
  202. package/.github/workflows/ci.yml +0 -39
  203. package/.github/workflows/label-pr.yml +0 -40
  204. package/.github/workflows/update-tokens.yml +0 -43
  205. package/.husky/pre-commit +0 -1
  206. package/.mcp.json +0 -3
  207. package/.nvmrc +0 -1
  208. package/.prettierrc +0 -4
  209. package/CHANGELOG.md +0 -263
  210. package/CLAUDE.md +0 -307
  211. package/CODE_OF_CONDUCT.md +0 -128
  212. package/CONTRIBUTING.md +0 -159
  213. package/CONTRIBUTORS.md +0 -26
  214. package/LICENSE-NANOCLAW-MIT +0 -21
  215. package/README_ja.md +0 -194
  216. package/README_zh.md +0 -194
  217. package/assets/nanoclaw-favicon.png +0 -0
  218. package/assets/nanoclaw-icon.png +0 -0
  219. package/assets/nanoclaw-logo-dark.png +0 -0
  220. package/assets/nanoclaw-logo.png +0 -0
  221. package/assets/nanoclaw-profile.jpeg +0 -0
  222. package/assets/nanoclaw-sales.png +0 -0
  223. package/assets/social-preview.jpg +0 -0
  224. package/config-examples/mount-allowlist.json +0 -25
  225. package/container/.dockerignore +0 -2
  226. package/container/CLAUDE.md +0 -21
  227. package/container/Dockerfile +0 -121
  228. package/container/agent-runner/bun.lock +0 -243
  229. package/container/agent-runner/package.json +0 -22
  230. package/container/agent-runner/scripts/sdk-signal-probe.ts +0 -169
  231. package/container/agent-runner/src/config.ts +0 -55
  232. package/container/agent-runner/src/db/connection.ts +0 -267
  233. package/container/agent-runner/src/db/index.ts +0 -20
  234. package/container/agent-runner/src/db/messages-in.ts +0 -138
  235. package/container/agent-runner/src/db/messages-out.ts +0 -143
  236. package/container/agent-runner/src/db/session-routing.ts +0 -30
  237. package/container/agent-runner/src/db/session-state.test.ts +0 -100
  238. package/container/agent-runner/src/db/session-state.ts +0 -79
  239. package/container/agent-runner/src/destinations.ts +0 -135
  240. package/container/agent-runner/src/formatter.test.ts +0 -167
  241. package/container/agent-runner/src/formatter.ts +0 -260
  242. package/container/agent-runner/src/index.ts +0 -110
  243. package/container/agent-runner/src/integration.test.ts +0 -121
  244. package/container/agent-runner/src/mcp-tools/agents.instructions.md +0 -26
  245. package/container/agent-runner/src/mcp-tools/agents.ts +0 -66
  246. package/container/agent-runner/src/mcp-tools/core.instructions.md +0 -27
  247. package/container/agent-runner/src/mcp-tools/core.ts +0 -262
  248. package/container/agent-runner/src/mcp-tools/index.ts +0 -22
  249. package/container/agent-runner/src/mcp-tools/interactive.instructions.md +0 -22
  250. package/container/agent-runner/src/mcp-tools/interactive.ts +0 -169
  251. package/container/agent-runner/src/mcp-tools/scheduling.instructions.md +0 -40
  252. package/container/agent-runner/src/mcp-tools/scheduling.ts +0 -299
  253. package/container/agent-runner/src/mcp-tools/self-mod.instructions.md +0 -25
  254. package/container/agent-runner/src/mcp-tools/self-mod.ts +0 -120
  255. package/container/agent-runner/src/mcp-tools/server.ts +0 -54
  256. package/container/agent-runner/src/mcp-tools/types.ts +0 -6
  257. package/container/agent-runner/src/poll-loop.test.ts +0 -248
  258. package/container/agent-runner/src/poll-loop.ts +0 -437
  259. package/container/agent-runner/src/providers/claude.ts +0 -379
  260. package/container/agent-runner/src/providers/factory.test.ts +0 -19
  261. package/container/agent-runner/src/providers/factory.ts +0 -13
  262. package/container/agent-runner/src/providers/index.ts +0 -6
  263. package/container/agent-runner/src/providers/mock.ts +0 -77
  264. package/container/agent-runner/src/providers/provider-registry.ts +0 -33
  265. package/container/agent-runner/src/providers/types.ts +0 -82
  266. package/container/agent-runner/src/scheduling/task-script.ts +0 -121
  267. package/container/agent-runner/src/timezone.test.ts +0 -93
  268. package/container/agent-runner/src/timezone.ts +0 -107
  269. package/container/agent-runner/tsconfig.json +0 -14
  270. package/container/build.sh +0 -48
  271. package/container/entrypoint.sh +0 -16
  272. package/container/skills/agent-browser/SKILL.md +0 -159
  273. package/container/skills/frontend-engineer/SKILL.md +0 -157
  274. package/container/skills/self-customize/SKILL.md +0 -87
  275. package/container/skills/slack-formatting/SKILL.md +0 -94
  276. package/container/skills/vercel-cli/SKILL.md +0 -111
  277. package/container/skills/welcome/SKILL.md +0 -85
  278. package/docs/APPLE-CONTAINER-NETWORKING.md +0 -90
  279. package/docs/BRANCH-FORK-MAINTENANCE.md +0 -81
  280. package/docs/README.md +0 -25
  281. package/docs/SDK_DEEP_DIVE.md +0 -643
  282. package/docs/SECURITY.md +0 -162
  283. package/docs/agent-runner-details.md +0 -749
  284. package/docs/api-details.md +0 -365
  285. package/docs/architecture-diagram.html +0 -422
  286. package/docs/architecture-diagram.md +0 -215
  287. package/docs/architecture.md +0 -751
  288. package/docs/audit/2026-04-30-channel-endpoint-audit.md +0 -36
  289. package/docs/build-and-runtime.md +0 -80
  290. package/docs/cross-mount-stress/README.md +0 -112
  291. package/docs/cross-mount-stress/container-writer-retry.mjs +0 -55
  292. package/docs/cross-mount-stress/container-writer-slow.mjs +0 -42
  293. package/docs/cross-mount-stress/container-writer.mjs +0 -47
  294. package/docs/cross-mount-stress/host-writer-retry.mjs +0 -55
  295. package/docs/cross-mount-stress/host-writer-slow.mjs +0 -43
  296. package/docs/cross-mount-stress/host-writer.mjs +0 -47
  297. package/docs/db-central.md +0 -316
  298. package/docs/db-session.md +0 -183
  299. package/docs/db.md +0 -119
  300. package/docs/design/2026-04-29-vault-management-ui.md +0 -231
  301. package/docs/design/2026-04-30-channel-wiring-rework.md +0 -234
  302. package/docs/design/2026-05-01-channel-wiring-approvals-deep-dive.md +0 -272
  303. package/docs/design/2026-05-02-channel-policy-and-approval-routing.md +0 -250
  304. package/docs/docker-sandboxes.md +0 -359
  305. package/docs/isolation-model.md +0 -88
  306. package/docs/ollama.md +0 -79
  307. package/docs/parachute-integration.md +0 -109
  308. package/docs/post-night-rebirth-reflections.md +0 -151
  309. package/eslint.config.js +0 -32
  310. package/pnpm-workspace.yaml +0 -8
  311. package/repo-tokens/README.md +0 -113
  312. package/repo-tokens/action.yml +0 -186
  313. package/repo-tokens/badge.svg +0 -23
  314. package/repo-tokens/examples/green.svg +0 -14
  315. package/repo-tokens/examples/red.svg +0 -14
  316. package/repo-tokens/examples/yellow-green.svg +0 -14
  317. package/repo-tokens/examples/yellow.svg +0 -14
  318. package/scripts/chat.ts +0 -101
  319. package/scripts/cleanup-sessions.sh +0 -150
  320. package/scripts/init-cli-agent.ts +0 -172
  321. package/scripts/init-first-agent.ts +0 -378
  322. package/scripts/parachute.ts +0 -158
  323. package/scripts/run-migrations.ts +0 -105
  324. package/scripts/sanity-live-poll.ts +0 -95
  325. package/scripts/seed-discord.ts +0 -80
  326. package/scripts/test-v2-agent.ts +0 -106
  327. package/scripts/test-v2-channel-e2e.ts +0 -265
  328. package/scripts/test-v2-host.ts +0 -184
  329. package/src/channels/adapter.ts +0 -214
  330. package/src/channels/api-translator.test.ts +0 -306
  331. package/src/channels/api-translator.ts +0 -214
  332. package/src/channels/ask-question.ts +0 -46
  333. package/src/channels/channel-registry.test.ts +0 -421
  334. package/src/channels/channel-registry.ts +0 -313
  335. package/src/channels/chat-sdk-bridge.test.ts +0 -84
  336. package/src/channels/chat-sdk-bridge.ts +0 -652
  337. package/src/channels/cli.ts +0 -276
  338. package/src/channels/discord.ts +0 -90
  339. package/src/channels/index.ts +0 -17
  340. package/src/channels/telegram-markdown-sanitize.test.ts +0 -78
  341. package/src/channels/telegram-markdown-sanitize.ts +0 -55
  342. package/src/channels/telegram-pairing.test.ts +0 -254
  343. package/src/channels/telegram-pairing.ts +0 -339
  344. package/src/channels/telegram.ts +0 -279
  345. package/src/channels/trust-hint.test.ts +0 -48
  346. package/src/channels/trust-hint.ts +0 -75
  347. package/src/claude-md-compose.migrate.test.ts +0 -64
  348. package/src/claude-md-compose.ts +0 -205
  349. package/src/command-gate.ts +0 -63
  350. package/src/config.test.ts +0 -93
  351. package/src/config.ts +0 -128
  352. package/src/container-config.ts +0 -167
  353. package/src/container-runner.test.ts +0 -32
  354. package/src/container-runner.ts +0 -576
  355. package/src/container-runtime.test.ts +0 -269
  356. package/src/container-runtime.ts +0 -167
  357. package/src/db/_bun-sqlite-shim.ts +0 -88
  358. package/src/db/agent-activity.test.ts +0 -155
  359. package/src/db/agent-activity.ts +0 -121
  360. package/src/db/agent-groups.ts +0 -77
  361. package/src/db/connection.migrate.test.ts +0 -176
  362. package/src/db/connection.ts +0 -259
  363. package/src/db/db-v2.test.ts +0 -440
  364. package/src/db/dropped-messages.ts +0 -44
  365. package/src/db/index.ts +0 -40
  366. package/src/db/messaging-groups.ts +0 -252
  367. package/src/db/migrations/001-initial.ts +0 -112
  368. package/src/db/migrations/002-chat-sdk-state.ts +0 -36
  369. package/src/db/migrations/008-dropped-messages.ts +0 -27
  370. package/src/db/migrations/009-drop-pending-credentials.ts +0 -13
  371. package/src/db/migrations/010-engage-modes.ts +0 -103
  372. package/src/db/migrations/011-pending-sender-approvals.ts +0 -40
  373. package/src/db/migrations/012-channel-registration.ts +0 -48
  374. package/src/db/migrations/013-approval-render-metadata.ts +0 -27
  375. package/src/db/migrations/014-secrets.ts +0 -44
  376. package/src/db/migrations/015-secrets-drop-host-pattern.ts +0 -18
  377. package/src/db/migrations/016-secret-assignments.ts +0 -30
  378. package/src/db/migrations/017-agent-activity.ts +0 -40
  379. package/src/db/migrations/018-oauth-app-configs.ts +0 -34
  380. package/src/db/migrations/019-oauth-app-connections.ts +0 -48
  381. package/src/db/migrations/020-agent-app-connections.ts +0 -28
  382. package/src/db/migrations/021-pending-oauth-states.ts +0 -35
  383. package/src/db/migrations/022-app-connections-provider.ts +0 -25
  384. package/src/db/migrations/023-agent-group-secret-mode.test.ts +0 -124
  385. package/src/db/migrations/023-agent-group-secret-mode.ts +0 -65
  386. package/src/db/migrations/024-collapse-approvals.test.ts +0 -249
  387. package/src/db/migrations/024-collapse-approvals.ts +0 -182
  388. package/src/db/migrations/025-secret-mode-check.test.ts +0 -155
  389. package/src/db/migrations/025-secret-mode-check.ts +0 -49
  390. package/src/db/migrations/026-user-dms-bot-id.test.ts +0 -116
  391. package/src/db/migrations/026-user-dms-bot-id.ts +0 -54
  392. package/src/db/migrations/027-provider-credentials.ts +0 -41
  393. package/src/db/migrations/_test-helpers.ts +0 -41
  394. package/src/db/migrations/index.ts +0 -127
  395. package/src/db/migrations/module-agent-to-agent-destinations.ts +0 -84
  396. package/src/db/migrations/module-approvals-pending-approvals.ts +0 -42
  397. package/src/db/migrations/module-approvals-title-options.ts +0 -40
  398. package/src/db/schema.ts +0 -258
  399. package/src/db/session-db.test.ts +0 -93
  400. package/src/db/session-db.ts +0 -325
  401. package/src/db/sessions.ts +0 -241
  402. package/src/delivery.test.ts +0 -148
  403. package/src/delivery.ts +0 -445
  404. package/src/env.ts +0 -74
  405. package/src/group-folder.test.ts +0 -35
  406. package/src/group-folder.ts +0 -44
  407. package/src/group-init.ts +0 -92
  408. package/src/host-core.test.ts +0 -456
  409. package/src/host-sweep.test.ts +0 -146
  410. package/src/host-sweep.ts +0 -287
  411. package/src/index.ts +0 -232
  412. package/src/install-slug.ts +0 -33
  413. package/src/log.test.ts +0 -81
  414. package/src/log.ts +0 -117
  415. package/src/mcp/http.ts +0 -72
  416. package/src/mcp/server.ts +0 -92
  417. package/src/mcp/stdio.ts +0 -51
  418. package/src/mcp/tools/activity.ts +0 -88
  419. package/src/mcp/tools/agent-groups.ts +0 -183
  420. package/src/mcp/tools/approvals.ts +0 -122
  421. package/src/mcp/tools/channels.test.ts +0 -126
  422. package/src/mcp/tools/channels.ts +0 -134
  423. package/src/mcp/tools/index.ts +0 -27
  424. package/src/mcp/tools/oauth.ts +0 -48
  425. package/src/mcp/tools/secrets.ts +0 -169
  426. package/src/mcp/tools/sessions.ts +0 -135
  427. package/src/mcp/types.ts +0 -51
  428. package/src/modules/agent-to-agent/agent-route.test.ts +0 -46
  429. package/src/modules/agent-to-agent/agent-route.ts +0 -223
  430. package/src/modules/agent-to-agent/create-agent.ts +0 -127
  431. package/src/modules/agent-to-agent/db/agent-destinations.ts +0 -135
  432. package/src/modules/agent-to-agent/index.ts +0 -22
  433. package/src/modules/agent-to-agent/write-destinations.ts +0 -59
  434. package/src/modules/approvals/agent.md +0 -45
  435. package/src/modules/approvals/index.ts +0 -21
  436. package/src/modules/approvals/picks.test.ts +0 -291
  437. package/src/modules/approvals/primitive.ts +0 -279
  438. package/src/modules/approvals/project.md +0 -27
  439. package/src/modules/approvals/response-handler.ts +0 -87
  440. package/src/modules/index.ts +0 -24
  441. package/src/modules/interactive/agent.md +0 -21
  442. package/src/modules/interactive/index.ts +0 -69
  443. package/src/modules/interactive/project.md +0 -12
  444. package/src/modules/mount-security/expand-path.test.ts +0 -82
  445. package/src/modules/mount-security/index.ts +0 -459
  446. package/src/modules/mount-security/migrate.test.ts +0 -91
  447. package/src/modules/permissions/access.ts +0 -28
  448. package/src/modules/permissions/channel-approval.test.ts +0 -389
  449. package/src/modules/permissions/channel-approval.ts +0 -188
  450. package/src/modules/permissions/db/agent-group-members.ts +0 -44
  451. package/src/modules/permissions/db/pending-channel-approvals.test.ts +0 -86
  452. package/src/modules/permissions/db/pending-channel-approvals.ts +0 -66
  453. package/src/modules/permissions/db/pending-sender-approvals.ts +0 -60
  454. package/src/modules/permissions/db/user-dms.ts +0 -58
  455. package/src/modules/permissions/db/user-roles.ts +0 -85
  456. package/src/modules/permissions/db/users.ts +0 -38
  457. package/src/modules/permissions/index.ts +0 -421
  458. package/src/modules/permissions/permissions.test.ts +0 -358
  459. package/src/modules/permissions/sender-approval.test.ts +0 -641
  460. package/src/modules/permissions/sender-approval.ts +0 -165
  461. package/src/modules/permissions/user-dm.ts +0 -200
  462. package/src/modules/provider-credentials/db.ts +0 -121
  463. package/src/modules/provider-credentials/index.ts +0 -12
  464. package/src/modules/provider-credentials/spawn.test.ts +0 -206
  465. package/src/modules/provider-credentials/spawn.ts +0 -114
  466. package/src/modules/scheduling/actions.ts +0 -113
  467. package/src/modules/scheduling/db.test.ts +0 -282
  468. package/src/modules/scheduling/db.ts +0 -148
  469. package/src/modules/scheduling/index.ts +0 -34
  470. package/src/modules/scheduling/recurrence.test.ts +0 -98
  471. package/src/modules/scheduling/recurrence.ts +0 -54
  472. package/src/modules/self-mod/agent.md +0 -30
  473. package/src/modules/self-mod/apply.ts +0 -85
  474. package/src/modules/self-mod/index.ts +0 -30
  475. package/src/modules/self-mod/project.md +0 -39
  476. package/src/modules/self-mod/request.ts +0 -91
  477. package/src/modules/typing/index.ts +0 -165
  478. package/src/oauth/agent-app-connections.ts +0 -103
  479. package/src/oauth/app-configs.test.ts +0 -64
  480. package/src/oauth/app-configs.ts +0 -114
  481. package/src/oauth/app-connections.test.ts +0 -109
  482. package/src/oauth/app-connections.ts +0 -178
  483. package/src/oauth/crypto.ts +0 -56
  484. package/src/oauth/flow.ts +0 -104
  485. package/src/oauth/providers/google.test.ts +0 -38
  486. package/src/oauth/providers/google.ts +0 -46
  487. package/src/oauth/providers/index.ts +0 -48
  488. package/src/oauth/state-store.test.ts +0 -54
  489. package/src/oauth/state-store.ts +0 -93
  490. package/src/parachute/README.md +0 -27
  491. package/src/parachute/create-agent.test.ts +0 -83
  492. package/src/parachute/create-agent.ts +0 -122
  493. package/src/parachute/group-status.test.ts +0 -165
  494. package/src/parachute/group-status.ts +0 -136
  495. package/src/parachute/types.ts +0 -41
  496. package/src/parachute/vault-mcp.test.ts +0 -251
  497. package/src/parachute/vault-mcp.ts +0 -232
  498. package/src/platform-id.test.ts +0 -104
  499. package/src/platform-id.ts +0 -109
  500. package/src/providers/index.ts +0 -6
  501. package/src/providers/provider-container-registry.ts +0 -58
  502. package/src/response-registry.ts +0 -45
  503. package/src/router.ts +0 -530
  504. package/src/secrets/crypto.test.ts +0 -45
  505. package/src/secrets/crypto.ts +0 -55
  506. package/src/secrets/index.ts +0 -461
  507. package/src/secrets/master-key.ts +0 -70
  508. package/src/secrets/secrets.test.ts +0 -651
  509. package/src/session-manager.attachments.test.ts +0 -171
  510. package/src/session-manager.dup-skip.test.ts +0 -173
  511. package/src/session-manager.migrate.test.ts +0 -59
  512. package/src/session-manager.ts +0 -451
  513. package/src/startup-bootstrap.test.ts +0 -226
  514. package/src/startup-bootstrap.ts +0 -207
  515. package/src/state-sqlite.ts +0 -182
  516. package/src/timezone.test.ts +0 -64
  517. package/src/timezone.ts +0 -37
  518. package/src/types.ts +0 -233
  519. package/src/web/auth.test.ts +0 -335
  520. package/src/web/auth.ts +0 -214
  521. package/src/web/discord-validate.test.ts +0 -77
  522. package/src/web/discord-validate.ts +0 -88
  523. package/src/web/hub-discovery.test.ts +0 -98
  524. package/src/web/hub-discovery.ts +0 -69
  525. package/src/web/routes/activity.ts +0 -106
  526. package/src/web/routes/agent-provider.test.ts +0 -282
  527. package/src/web/routes/agent-provider.ts +0 -309
  528. package/src/web/routes/approvals.ts +0 -185
  529. package/src/web/routes/apps.ts +0 -434
  530. package/src/web/routes/channels-mg-detail.test.ts +0 -324
  531. package/src/web/routes/channels-mga-detail.test.ts +0 -472
  532. package/src/web/routes/channels.ts +0 -311
  533. package/src/web/routes/oauth-providers.ts +0 -42
  534. package/src/web/routes/secrets.test.ts +0 -220
  535. package/src/web/routes/secrets.ts +0 -317
  536. package/src/web/routes/sessions.ts +0 -123
  537. package/src/web/routes/settings.test.ts +0 -106
  538. package/src/web/routes/settings.ts +0 -247
  539. package/src/web/routes/setup-status.ts +0 -205
  540. package/src/web/routes/vaults.test.ts +0 -389
  541. package/src/web/routes/vaults.ts +0 -225
  542. package/src/web/server-version.test.ts +0 -16
  543. package/src/web/server.ts +0 -1024
  544. package/src/web/services-manifest.test.ts +0 -148
  545. package/src/web/services-manifest.ts +0 -66
  546. package/src/web/static-serve.test.ts +0 -255
  547. package/src/web/static-serve.ts +0 -104
  548. package/src/web/telegram-validate.test.ts +0 -116
  549. package/src/web/telegram-validate.ts +0 -107
  550. package/src/web/vault-proxy.test.ts +0 -214
  551. package/src/web/vault-proxy.ts +0 -120
  552. package/src/web/wire-channel.ts +0 -181
  553. package/src/webhook-server.ts +0 -134
  554. package/vitest.config.ts +0 -18
  555. package/web/README.md +0 -63
  556. package/web/ui/index.html +0 -13
  557. package/web/ui/package.json +0 -35
  558. package/web/ui/pnpm-lock.yaml +0 -2164
  559. package/web/ui/scripts/verify-base.mjs +0 -31
  560. package/web/ui/src/App.tsx +0 -88
  561. package/web/ui/src/components/ActivityFeed.tsx +0 -444
  562. package/web/ui/src/components/AgentGroupPicker.tsx +0 -263
  563. package/web/ui/src/components/AgentProviderCards.tsx +0 -220
  564. package/web/ui/src/components/CredentialForm.tsx +0 -214
  565. package/web/ui/src/components/ScopeGrants.tsx +0 -74
  566. package/web/ui/src/components/StatusDot.tsx +0 -43
  567. package/web/ui/src/components/VaultPicker.tsx +0 -127
  568. package/web/ui/src/components/setup/AdapterInstallStep.tsx +0 -178
  569. package/web/ui/src/components/setup/AgentGroupStep.tsx +0 -43
  570. package/web/ui/src/components/setup/ChannelPickStep.tsx +0 -74
  571. package/web/ui/src/components/setup/DoneStep.tsx +0 -49
  572. package/web/ui/src/components/setup/PrereqStep.tsx +0 -129
  573. package/web/ui/src/components/setup/TestConnectionStep.tsx +0 -108
  574. package/web/ui/src/components/setup/TestMessageStep.tsx +0 -104
  575. package/web/ui/src/components/setup/WireChannelStep.tsx +0 -166
  576. package/web/ui/src/components/setup/types.ts +0 -105
  577. package/web/ui/src/lib/api.test.ts +0 -410
  578. package/web/ui/src/lib/api.ts +0 -1248
  579. package/web/ui/src/lib/auth.test.ts +0 -352
  580. package/web/ui/src/lib/auth.ts +0 -405
  581. package/web/ui/src/lib/channel-adapters.ts +0 -136
  582. package/web/ui/src/main.tsx +0 -19
  583. package/web/ui/src/routes/ApprovalsList.tsx +0 -294
  584. package/web/ui/src/routes/Apps.tsx +0 -613
  585. package/web/ui/src/routes/ChannelWireDetail.test.tsx +0 -233
  586. package/web/ui/src/routes/ChannelWireDetail.tsx +0 -403
  587. package/web/ui/src/routes/ChannelsList.tsx +0 -158
  588. package/web/ui/src/routes/GroupDetail.test.tsx +0 -206
  589. package/web/ui/src/routes/GroupDetail.tsx +0 -880
  590. package/web/ui/src/routes/GroupList.tsx +0 -187
  591. package/web/ui/src/routes/MessagingGroupDetail.test.tsx +0 -233
  592. package/web/ui/src/routes/MessagingGroupDetail.tsx +0 -306
  593. package/web/ui/src/routes/NewGroupWizard.tsx +0 -390
  594. package/web/ui/src/routes/OAuthCallback.tsx +0 -56
  595. package/web/ui/src/routes/SecretsList.tsx +0 -942
  596. package/web/ui/src/routes/SessionsList.tsx +0 -220
  597. package/web/ui/src/routes/SettingsAgentProvider.tsx +0 -109
  598. package/web/ui/src/routes/SettingsApprovals.tsx +0 -234
  599. package/web/ui/src/routes/SetupWizard.tsx +0 -219
  600. package/web/ui/src/routes/VaultDetail.test.tsx +0 -363
  601. package/web/ui/src/routes/VaultDetail.tsx +0 -960
  602. package/web/ui/src/routes/VaultsList.tsx +0 -295
  603. package/web/ui/src/routes/WireChannelPage.tsx +0 -413
  604. package/web/ui/src/styles.css +0 -608
  605. package/web/ui/src/test/setup.ts +0 -23
  606. package/web/ui/src/vite-env.d.ts +0 -10
  607. package/web/ui/vite.config.ts +0 -34
  608. package/web/ui/vitest.config.ts +0 -25
@@ -1,62 +0,0 @@
1
- #!/usr/bin/env pnpm exec tsx
2
- /**
3
- * X Integration - Retweet
4
- * Usage: echo '{"tweetUrl":"https://x.com/user/status/123"}' | pnpm exec tsx retweet.ts
5
- */
6
-
7
- import { getBrowserContext, navigateToTweet, runScript, config, ScriptResult } from '../lib/browser.js';
8
-
9
- interface RetweetInput {
10
- tweetUrl: string;
11
- }
12
-
13
- async function retweet(input: RetweetInput): Promise<ScriptResult> {
14
- const { tweetUrl } = input;
15
-
16
- if (!tweetUrl) {
17
- return { success: false, message: 'Please provide a tweet URL' };
18
- }
19
-
20
- let context = null;
21
- try {
22
- context = await getBrowserContext();
23
- const { page, success, error } = await navigateToTweet(context, tweetUrl);
24
-
25
- if (!success) {
26
- return { success: false, message: error || 'Navigation failed' };
27
- }
28
-
29
- const tweet = page.locator('article[data-testid="tweet"]').first();
30
- const unretweetButton = tweet.locator('[data-testid="unretweet"]');
31
- const retweetButton = tweet.locator('[data-testid="retweet"]');
32
-
33
- // Check if already retweeted
34
- const alreadyRetweeted = await unretweetButton.isVisible().catch(() => false);
35
- if (alreadyRetweeted) {
36
- return { success: true, message: 'Tweet already retweeted' };
37
- }
38
-
39
- await retweetButton.waitFor({ timeout: config.timeouts.elementWait });
40
- await retweetButton.click();
41
- await page.waitForTimeout(config.timeouts.afterClick);
42
-
43
- // Click retweet confirm option
44
- const retweetConfirm = page.locator('[data-testid="retweetConfirm"]');
45
- await retweetConfirm.waitFor({ timeout: config.timeouts.elementWait });
46
- await retweetConfirm.click();
47
- await page.waitForTimeout(config.timeouts.afterClick * 2);
48
-
49
- // Verify
50
- const nowRetweeted = await unretweetButton.isVisible().catch(() => false);
51
- if (nowRetweeted) {
52
- return { success: true, message: 'Retweet successful' };
53
- }
54
-
55
- return { success: false, message: 'Retweet action completed but could not verify success' };
56
-
57
- } finally {
58
- if (context) await context.close();
59
- }
60
- }
61
-
62
- runScript<RetweetInput>(retweet);
@@ -1,87 +0,0 @@
1
- #!/usr/bin/env pnpm exec tsx
2
- /**
3
- * X Integration - Authentication Setup
4
- * Usage: pnpm exec tsx setup.ts
5
- *
6
- * Interactive script - opens browser for manual login
7
- */
8
-
9
- import { chromium } from 'playwright';
10
- import * as readline from 'readline';
11
- import fs from 'fs';
12
- import path from 'path';
13
- import { config, cleanupLockFiles } from '../lib/browser.js';
14
-
15
- async function setup(): Promise<void> {
16
- console.log('=== X (Twitter) Authentication Setup ===\n');
17
- console.log('This will open Chrome for you to log in to X.');
18
- console.log('Your login session will be saved for automated interactions.\n');
19
- console.log(`Chrome path: ${config.chromePath}`);
20
- console.log(`Profile dir: ${config.browserDataDir}\n`);
21
-
22
- // Ensure directories exist
23
- fs.mkdirSync(path.dirname(config.authPath), { recursive: true });
24
- fs.mkdirSync(config.browserDataDir, { recursive: true });
25
-
26
- cleanupLockFiles();
27
-
28
- console.log('Launching browser...\n');
29
-
30
- const context = await chromium.launchPersistentContext(config.browserDataDir, {
31
- executablePath: config.chromePath,
32
- headless: false,
33
- viewport: config.viewport,
34
- args: config.chromeArgs.slice(0, 3), // Use first 3 args for setup (less restrictive)
35
- ignoreDefaultArgs: config.chromeIgnoreDefaultArgs,
36
- });
37
-
38
- const page = context.pages()[0] || await context.newPage();
39
-
40
- // Navigate to login page
41
- await page.goto('https://x.com/login');
42
-
43
- console.log('Please log in to X in the browser window.');
44
- console.log('After you see your home feed, come back here and press Enter.\n');
45
-
46
- // Wait for user to complete login
47
- const rl = readline.createInterface({
48
- input: process.stdin,
49
- output: process.stdout
50
- });
51
-
52
- await new Promise<void>(resolve => {
53
- rl.question('Press Enter when logged in... ', () => {
54
- rl.close();
55
- resolve();
56
- });
57
- });
58
-
59
- // Verify login by navigating to home and checking for account button
60
- console.log('\nVerifying login status...');
61
- await page.goto('https://x.com/home');
62
- await page.waitForTimeout(config.timeouts.pageLoad);
63
-
64
- const isLoggedIn = await page.locator('[data-testid="SideNav_AccountSwitcher_Button"]').isVisible().catch(() => false);
65
-
66
- if (isLoggedIn) {
67
- // Save auth marker
68
- fs.writeFileSync(config.authPath, JSON.stringify({
69
- authenticated: true,
70
- timestamp: new Date().toISOString()
71
- }, null, 2));
72
-
73
- console.log('\n✅ Authentication successful!');
74
- console.log(`Session saved to: ${config.browserDataDir}`);
75
- console.log('\nYou can now use X integration features.');
76
- } else {
77
- console.log('\n❌ Could not verify login status.');
78
- console.log('Please try again and make sure you are logged in to X.');
79
- }
80
-
81
- await context.close();
82
- }
83
-
84
- setup().catch(err => {
85
- console.error('Setup failed:', err.message);
86
- process.exit(1);
87
- });
@@ -1,10 +0,0 @@
1
- # Core code - maintainer only
2
- /src/ @gavrielc @gabi-simons
3
- /container/ @gavrielc @gabi-simons
4
- /groups/ @gavrielc @gabi-simons
5
- /launchd/ @gavrielc @gabi-simons
6
- /package.json @gavrielc @gabi-simons
7
- /package-lock.json @gavrielc @gabi-simons
8
-
9
- # Skills - open to contributors
10
- /.claude/skills/
@@ -1,18 +0,0 @@
1
- <!-- contributing-guide: v1 -->
2
- ## Type of Change
3
-
4
- - [ ] **Feature skill** - adds a channel or integration (source code changes + SKILL.md)
5
- - [ ] **Utility skill** - adds a standalone tool (code files in `.claude/skills/<name>/`, no source changes)
6
- - [ ] **Operational/container skill** - adds a workflow or agent skill (SKILL.md only, no source changes)
7
- - [ ] **Fix** - bug fix or security fix to source code
8
- - [ ] **Simplification** - reduces or simplifies source code
9
- - [ ] **Documentation** - docs, README, or CONTRIBUTING changes only
10
-
11
- ## Description
12
-
13
-
14
- ## For Skills
15
-
16
- - [ ] SKILL.md contains instructions, not inline code (code goes in separate files)
17
- - [ ] SKILL.md is under 500 lines
18
- - [ ] I tested this skill on a fresh clone
@@ -1,35 +0,0 @@
1
- name: Bump version
2
-
3
- on:
4
- push:
5
- branches: [main]
6
- paths: ['src/**', 'container/**']
7
-
8
- jobs:
9
- bump-version:
10
- if: github.repository == 'qwibitai/nanoclaw'
11
- runs-on: ubuntu-latest
12
- steps:
13
- - uses: actions/create-github-app-token@v1
14
- id: app-token
15
- with:
16
- app-id: ${{ secrets.APP_ID }}
17
- private-key: ${{ secrets.APP_PRIVATE_KEY }}
18
-
19
- - uses: actions/checkout@v4
20
- with:
21
- token: ${{ steps.app-token.outputs.token }}
22
-
23
- - uses: pnpm/action-setup@v4
24
-
25
- - name: Bump patch version
26
- run: |
27
- pnpm version patch --no-git-tag-version
28
- git add package.json
29
- git diff --cached --quiet && exit 0
30
- git config user.name "github-actions[bot]"
31
- git config user.email "github-actions[bot]@users.noreply.github.com"
32
- VERSION=$(node -p "require('./package.json').version")
33
- git commit -m "chore: bump version to $VERSION"
34
- git pull --rebase
35
- git push
@@ -1,39 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- pull_request:
5
- branches: [main]
6
-
7
- jobs:
8
- ci:
9
- runs-on: ubuntu-latest
10
- steps:
11
- - uses: actions/checkout@v4
12
- - uses: pnpm/action-setup@v4
13
- - uses: actions/setup-node@v4
14
- with:
15
- node-version: 20
16
- cache: pnpm
17
- - uses: oven-sh/setup-bun@v2
18
- with:
19
- bun-version: 1.3.12
20
- - run: pnpm install --frozen-lockfile
21
- - name: Install agent-runner deps (Bun)
22
- working-directory: container/agent-runner
23
- run: bun install --frozen-lockfile
24
-
25
- - name: Format check
26
- run: pnpm run format:check
27
-
28
- - name: Typecheck host
29
- run: pnpm exec tsc --noEmit
30
-
31
- - name: Typecheck container
32
- run: pnpm exec tsc -p container/agent-runner/tsconfig.json --noEmit
33
-
34
- - name: Host tests
35
- run: pnpm exec vitest run
36
-
37
- - name: Container tests
38
- working-directory: container/agent-runner
39
- run: bun test
@@ -1,40 +0,0 @@
1
- name: Label PR
2
-
3
- # SECURITY: this workflow runs with write access to the base repo on fork PRs,
4
- # because `pull_request_target` executes in the context of the base branch.
5
- # Keep it metadata-only — do NOT add actions/checkout or any step that
6
- # executes PR-supplied content (install scripts, build commands, etc.).
7
- # See https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
8
- on:
9
- pull_request_target:
10
- types: [opened, edited]
11
-
12
- jobs:
13
- label:
14
- runs-on: ubuntu-latest
15
- permissions:
16
- pull-requests: write
17
- steps:
18
- - uses: actions/github-script@v7
19
- with:
20
- script: |
21
- const body = context.payload.pull_request.body || '';
22
- const labels = [];
23
-
24
- if (body.includes('[x] **Feature skill**')) { labels.push('PR: Skill'); labels.push('PR: Feature'); }
25
- else if (body.includes('[x] **Utility skill**')) labels.push('PR: Skill');
26
- else if (body.includes('[x] **Operational/container skill**')) labels.push('PR: Skill');
27
- else if (body.includes('[x] **Fix**')) labels.push('PR: Fix');
28
- else if (body.includes('[x] **Simplification**')) labels.push('PR: Refactor');
29
- else if (body.includes('[x] **Documentation**')) labels.push('PR: Docs');
30
-
31
- if (body.includes('contributing-guide: v1')) labels.push('follows-guidelines');
32
-
33
- if (labels.length > 0) {
34
- await github.rest.issues.addLabels({
35
- owner: context.repo.owner,
36
- repo: context.repo.repo,
37
- issue_number: context.payload.pull_request.number,
38
- labels,
39
- });
40
- }
@@ -1,43 +0,0 @@
1
- name: Update token count
2
-
3
- on:
4
- workflow_dispatch:
5
- push:
6
- branches: [main]
7
- paths: ['src/**', 'container/**', 'launchd/**', 'CLAUDE.md']
8
-
9
- jobs:
10
- update-tokens:
11
- if: github.repository == 'qwibitai/nanoclaw'
12
- runs-on: ubuntu-latest
13
- steps:
14
- - uses: actions/create-github-app-token@v1
15
- id: app-token
16
- with:
17
- app-id: ${{ secrets.APP_ID }}
18
- private-key: ${{ secrets.APP_PRIVATE_KEY }}
19
-
20
- - uses: actions/checkout@v4
21
- with:
22
- token: ${{ steps.app-token.outputs.token }}
23
-
24
- - uses: actions/setup-python@v5
25
- with:
26
- python-version: '3.12'
27
-
28
- - uses: ./repo-tokens
29
- id: tokens
30
- with:
31
- include: 'src/**/*.ts container/agent-runner/src/**/*.ts container/Dockerfile container/build.sh launchd/com.nanoclaw.plist CLAUDE.md'
32
- exclude: 'src/**/*.test.ts'
33
- badge-path: 'repo-tokens/badge.svg'
34
-
35
- - name: Commit if changed
36
- run: |
37
- git add README.md repo-tokens/badge.svg
38
- git diff --cached --quiet && exit 0
39
- git config user.name "github-actions[bot]"
40
- git config user.email "github-actions[bot]@users.noreply.github.com"
41
- git commit -m "docs: update token count to ${{ steps.tokens.outputs.badge }}"
42
- git pull --rebase
43
- git push
package/.husky/pre-commit DELETED
@@ -1 +0,0 @@
1
- pnpm run format:fix
package/.mcp.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "mcpServers": {}
3
- }
package/.nvmrc DELETED
@@ -1 +0,0 @@
1
- 22
package/.prettierrc DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "singleQuote": true,
3
- "printWidth": 120
4
- }
package/CHANGELOG.md DELETED
@@ -1,263 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to parachute-agent will be documented in this file.
4
-
5
- ## [0.1.2] - 2026-05-05
6
-
7
- The first patch series after the 0.1.0 paraclaw → parachute-agent rename. Fourteen iterative cuts (rc.1 through rc.14) collapsed into one stable. No operator action required: every change is either a transparent fix, an additive UI affordance, or a behind-the-scenes test addition.
8
-
9
- ### Fixed
10
-
11
- - **Master-key migration: detect the both-exist split-state explicitly.** `migrateMasterKeyLocation` previously silent-no-op'd when both `<PARACHUTE_DIR>/claw/master.key` and `<PARACHUTE_DIR>/agent/master.key` existed — masking the case where an earlier 0.1.x boot generated a fresh key at the new path before the legacy was copied (so encrypted secrets sealed under the legacy key became undecryptable). The function now logs a `warn` with both paths and copy-pasteable recovery commands. Standalone scripts (`init-cli-agent`, `init-first-agent`, `seed-discord`) that ran `migrateCentralDbLocation` now also run `migrateMasterKeyLocation` before opening the DB, so a script-driven first touch no longer skips the key copy. Also: SPA browser title `<title>Paraclaw</title>` → `<title>Parachute Agent</title>` and two stale GitHub repo links pointing at the renamed-from `paraclaw` URL — small follow-ups to the 0.1.0 brand sweep that landed in the same cut.
12
-
13
- - **Auto-retag the per-install container image when `INSTALL_SLUG` shifts (paraclaw#114).** `INSTALL_SLUG = sha1(process.cwd())[:8]`, so an operator dir-rename (the trigger that exposed this: `mv paraclaw parachute-agent`) flips the slug. Previously-built images carried the old slug; new container spawns went out under the new slug; `docker run` returned `code=125` ("image not found") and every Telegram message produced a silent crashloop. New `ensureContainerImage()` step at boot detects the mismatch and `docker tag`s any `parachute-agent-image-<peer-slug>:latest` it finds onto the expected name. Pre-0.1.0 `paraclaw-agent-<slug>:latest` peers also match (one cycle of compat). When no peer is on disk, the daemon now fails visibly at startup with an actionable error instead of crashlooping silently.
14
-
15
- - **Inbound: extract attachment files only after the row commits (paraclaw#96).** `writeSessionMessage` previously decoded base64 attachments and wrote files to `inbox/<messageId>/` *before* `INSERT … ON CONFLICT(id) DO NOTHING` returned. Once duplicate dispatch became a warm code path (sender-approval replay, Telegram getUpdates retry, chat-sdk re-emit), a replay carrying the same `messages_in.id` but mutated bytes silently clobbered the on-disk file under the original message id while the DB row stayed unchanged — divergent state with no audit trail. Reordered: insert with raw inline-base64 content, check `inserted`, and only when `inserted === true` extract files and `UPDATE messages_in SET content = ?` with the path-replaced form. Disk state now stays strictly downstream of the row commit.
16
-
17
- - **Wire-side `senderScope` vocabulary clash (paraclaw#94).** The wire vocab `'allowlist' | 'all'` shared the literal `'all'` with the DB-side `'all' | 'known'` — both meant "no sender filter", but the literal collision meant a grep-based rename of either side would silently break translation without a compile error. Renamed wire-side `'all'` → `'unrestricted'` so the two unions are now literal-disjoint; DB schema untouched (no migration). Touchpoints: HTTP + MCP translators, MCP `update-channel-wire` schema enum (now `['allowlist', 'unrestricted']`), `web/ui/src/lib/api.ts:SenderScope`, and the dropdown copy in `ChannelWireDetail.tsx`. Plus a defensive validation gate on the MCP handler — the SDK does not enforce `inputSchema` against `tools/call` arguments, so a stale-schema client sending the legacy `senderScope: 'all'` (or `ignoredMessagePolicy: 'accumulate'`, or a typo'd `engageMode`) would previously land past the rename gate, never match any branch, and silently no-op. Now explicitly rejected with a diagnostic error. **Breaking change to the API/MCP wire vocabulary** — pre-1.0, no operator-data risk.
18
-
19
- - **Mount-security imports `HOME_DIR` from `src/config.ts` (paraclaw#99).** `expandPath` in `src/modules/mount-security/index.ts` previously called `process.env.HOME || os.homedir()` directly — the only remaining offender after the rest of the host's HOME-derived paths routed through `config.ts`. Now imports the canonical `HOME_DIR`, so a future precedence-rule refactor (e.g. add a `PARACHUTE_AGENT_HOME` override) is one edit upstream. Default behavior unchanged. Mount-allowlist's on-disk location intentionally stays at `<HOME>/.config/parachute-agent/` (operator-host policy, not per-install runtime state) — pinned with a regression test.
20
-
21
- - **`putSecret` auto-seeds the owner assignment for scoped creates (paraclaw#127).** The default `agent_groups.secret_mode` is `selective` (migration 023). Before this fix, `putSecret(name, value, { agent_group_id })` inserted the `secrets` row without writing the matching `secret_assignments` row — leaving the row silently invisible to `resolveInjectableSecrets` (which gates on `secret_mode='all' OR assignment row exists`). The "+ New secret" → CredentialForm "free" mode in the SPA called only `putSecret` with no follow-up `setSecretAssignments`, so the standard create flow produced orphan rows whose values would never reach the agent container. Fix: `putSecret` writes the (id, owning_group) assignment row in the same transaction on INSERT (idempotent via `ON CONFLICT … DO NOTHING`); UPDATE/rotate leaves the assignment set alone (operator may have deliberately revoked an assignment, and a value rotation must not undo that).
22
-
23
- - **SPA OAuth bootstrap — three narrowing fixes (paraclaw#136, #137, #138).** (1) Drop `vault:read vault:write` from `REQUESTED_SCOPES` — the agent SPA is self-contained, every vault flow already runs the per-vault re-consent pattern (`vault:<name>:admin` via `extraScopes`), so the broad bootstrap scopes were dead weight on the consent screen ("this app wants to read/write all your vaults" — wrong story for an SPA whose vault touches are narrowly per-vault and on-demand). (2) Regression-pin OAuth `client_name` in the registerClient body — the hub renders this string verbatim on its DCR consent screen; the 0.1.0 brand sweep renamed it from `Paraclaw web UI` to `Parachute Agent web UI`, this pins the wire-level test. (3) Re-register OAuth client when `redirect_uri` changes — the hub binds each DCR `client_id` to the redirect_uri it registered with; if the SPA's mount path changes (operator flips `PARACHUTE_AGENT_WEB_MOUNT` from `/claw/` → `/agent/`, or any custom remount), the cached client_id stops matching and `/oauth/authorize` errors out before the consent screen. Extended `ClientRecord` to `{ client_id, redirect_uri }`, compare in `ensureClient`, treat mismatch (or legacy missing-field record) as cache miss → re-register. Legacy records self-heal on first 0.1.x reload.
24
-
25
- ### Changed
26
-
27
- - **`services.json` self-registers `installDir` (paraclaw#115).** The agent's startup self-registration into `~/.parachute/services.json` now includes `installDir: process.cwd()` alongside the existing `name`/`port`/`paths`/`health`/`version` fields. Without it, hub's third-party-module lifecycle resolution (parachute-hub#84) couldn't locate the start command for `parachute restart agent` — the agent had a `.parachute/module.json` with `startCmd`, but hub needed `installDir` to know which checkout to drive.
28
-
29
- - **GroupDetail "Secrets" panel — what the agent will receive at next session spawn (paraclaw#104).** `/agent/groups/:folder` now surfaces a read-only Secrets section showing the same set `resolveInjectableSecrets()` would inject into a new container, with three scope badges that explain *why* each row is included: `scoped` (owned by this group), `assigned` (global with explicit assignment row), `global` (global reaching the group only because `secret_mode='all'`). On a name collision the scoped row wins and reports `scoped`, mirroring the host's resolution rule. Click-through routes to `/secrets?edit=<id>` with a deep-link param for SecretEditor. New `GET /api/groups/:folder/secrets` endpoint (scope `agent:read`) — metadata only, never decrypts. Empty state distinguishes between mode='selective' (reads as "by design") and mode='all' (suggests creating a secret).
30
-
31
- - **GroupDetail Secrets section — Retry button on error state (paraclaw#128).** Mirrors the existing AgentProviderSection pattern: the error banner now renders a Retry button bound to the same fetch callback so operators don't have to navigate away after a transient API failure.
32
-
33
- - **Channel-wire translator extracted into a single shared module (paraclaw#123).** `src/web/routes/channels.ts` and `src/mcp/tools/channels.ts` each maintained their own copy of the `Api*` types, the `VALID_API_*` enum arrays, the `dbToApi*` translator pair, and the `ChannelWireView` shape. That duplication was the structural drift hazard paraclaw#94 surfaced concretely. Lifted everything into `src/channels/api-translator.ts`; the HTTP route file now owns only the transport layer, the MCP file only the tool-def plumbing. A future enum change touches one file and both surfaces pick it up automatically. (Behavioral side note: the inline MCP handler used to silently *drop* `engagePattern='.'` because the DB sentinel for `engageMode='all'` would round-trip back as `'all'` on the next read; the shared validator now hard-rejects that input identically on both surfaces. Use `'\\.'` to match a literal dot.)
34
-
35
- - **Depersonalize test fixtures + comments.** Removed a real install-slug (`16f7e9e8`, the sha1 prefix of one operator's specific path) that had snuck into `src/container-runtime.test.ts` peer-image fixtures, plus a comment in `src/container-runtime.ts` that named the specific `mv` command from one operator's environment. Codebase should be operator-agnostic. Replaced with synthetic `cafef00d`. No behavior change.
36
-
37
- ### Tests
38
-
39
- - **Integration coverage for `writeSessionMessage` dup-skip + sender-approval replay (paraclaw#97).** The unit test added with #95 proved `insertMessage` returns `inserted=false` on a duplicate id, but the write-path side effects layered above it were never asserted at the integration level. New `src/session-manager.dup-skip.test.ts` (4 tests using real session DBs and real fs: dup dispatch doesn't bump `sessions.last_active`, log payload shape, N-concurrent same-id absorption to one row + one inbox file, distinct ids in the same burst still land), plus 2 new tests in `src/modules/permissions/sender-approval.test.ts` exercising the approval-replay chain end-to-end (file at `inbox/<id>:<agentGroupId>/photo.jpg`, byte-preserved on `original_message` mutation under accumulate-mode wiring). Stash-and-rerun confirmed both regression tests catch the underlying #92/#95/#96 bugs.
40
-
41
- - **Parallel-equality lockstep guard for `resolveInjectableSecrets ↔ listInjectableSecretsForGroup` (paraclaw#129).** The two functions in `src/secrets/index.ts` are SQL-identical mirrors with a load-bearing doc-comment requiring lockstep edits — previously preserved only by careful reading and a #126-era reviewer note. Adds a `describe('… lockstep …')` block with an `expectLockstep` helper that calls both functions, asserts name-set equality, and walks each name through `getSecret` to verify the chosen row id (the `ORDER BY s.agent_group_id IS NULL` scoped-wins ordering) agrees with the plaintext returned. Five fixtures cover the rich-mix (scoped+all + global+assigned + global+mode=all + name collision), mode=selective, the orphaned-scoped corner, the unknown-agent-group selective-default path, and an empty store. Mechanical guard, no production code change.
42
-
43
- ---
44
-
45
- For per-rc commit-level detail of the 0.1.2 patch series, see `git log v0.1.1..v0.1.2 -- src/ web/ui/src/` or the merged PRs (#113 through #139).
46
-
47
- ## [0.1.1] - 2026-05-05
48
-
49
- ### Changed
50
-
51
- - **License.** parachute-agent now declares **AGPL-3.0** in `package.json` and `LICENSE`, matching the rest of the Parachute ecosystem (vault, hub, scribe, notes). The original NanoClaw MIT license is preserved verbatim as `LICENSE-NANOCLAW-MIT` to honor the upstream copyright (Copyright (c) 2026 Gavriel — https://github.com/qwibitai/nanoclaw). Modifications and the combined work are AGPL-3.0; the original NanoClaw code remains MIT-licensed and obtainable from the upstream project. Resolves the npm "Proprietary" display that came from the missing `license` field at 0.1.0.
52
-
53
- ## [0.1.0] - 2026-05-05
54
-
55
- Renamed paraclaw → **parachute-agent**, joining the Parachute ecosystem's named-after-purpose convention (vault, notes, scribe, hub). The name on disk, in the npm registry, on the mount path, and on the wire all change. Operator data migrates automatically on first boot; tokens, container labels, and module manifests carry one cycle of back-compat.
56
-
57
- - **npm package.** `paraclaw` → `@openparachute/agent`. The `parachute-agent` bin wraps the same entry point.
58
- - **`.parachute/module.json` `name`** → `parachute-agent`. The hub picks up the new identifier from the manifest; old installs that re-pull will see the rename without intervention.
59
- - **Mount path.** `/claw/*` → `/agent/*`. Hub-fronted UI lives under `/agent/`. The SPA derives its mount from `import.meta.env.BASE_URL`, so the same bundle works at any prefix. **No 301 redirect** — hard cut. Re-bookmark.
60
- - **Data dir.** `~/.parachute/claw/{paraclaw.db,master.key}` → `~/.parachute/agent/{agent.db,master.key}`. **Auto-migrated on startup** the first time 0.1.x boots: the legacy file copies to the new path with mode 0600, and the legacy file is left in place as a manual-rm backup. Honors `PARACHUTE_HOME`. Both legacies (pre-0.0.6 in-tree `data/v2.db` and pre-0.1.0 `~/.parachute/claw/paraclaw.db`) are preferred over an absent current; if both exist, the paraclaw-era file wins.
61
- - **Container labels.** Spawn label is now `parachute-agent-install=<slug>`. Cleanup reaps both the new label and the legacy `paraclaw-install=<slug>` label for one upgrade cycle, so a 0.1.x host coming up against pre-0.1.0 orphan containers cleans them up correctly. **Drop `paraclaw-install` compat in 0.2.0** (tracked as a follow-up issue).
62
- - **Container image tag.** `paraclaw-agent-<slug>:latest` → `parachute-agent-image-<slug>:latest`. `container/build.sh` produces the new tag; `container-runner` spawns from it. The `-image-` infix avoids colliding with the npm package name.
63
- - **MCP scope strings + symbols.** Wire scopes are `agent:read|write|admin` (was `claw:*`). Hub-issued JWTs carrying legacy `claw:*` grants still pass — they normalize to their `agent:*` equivalents inside `hasScope` and `pickEffectiveScope`. **Drop `claw:*` normalization in 0.2.0.** TS symbols renamed: `ClawScope` → `AgentScope`; `SCOPE_CLAW_*` → `SCOPE_AGENT_*`.
64
- - **MCP server name.** `paraclaw` → `parachute-agent`. Tools advertise as `mcp__parachute_agent__<verb>-<noun>` to clients. Renamed in three places that all need to agree: the host-side stdio entrypoint (operator wires this into Claude Code via `claude mcp add parachute-agent …`), the host-side HTTP `/mcp` endpoint, and the container-side built-in MCP server that the in-container agent calls. **⚠ Operator action**: restart any active sessions on first boot — existing in-flight sessions have message history referencing `mcp__paraclaw__*` tool calls and need a fresh container to pick up the new tool prefix. New tool calls in restarted sessions use the new prefix; the historical log entries stay (they're conversation history, not tool routing). Closes paraclaw#110.
65
- - **Service registry.** `services-manifest` displayName `Paraclaw` → `Parachute Agent`; service identifiers (`parachute-agent-web-server`) and the `name: 'agent'` route entry follow.
66
- - **launchd / systemd.** No service-file generator changes in this PR — service install is now owned by the hub install path. Operators on existing installs who still have the old `computer.parachute.claw-<slug>.plist` / `paraclaw-<slug>.service` units will continue to work; re-running the hub installer rewrites them with the new label/unit name.
67
-
68
- ### Operator migration steps (existing installs)
69
-
70
- 1. **Stop the daemon** (so the migration sees a quiescent state):
71
- - macOS: `launchctl unload ~/Library/LaunchAgents/computer.parachute.claw-<slug>.plist`
72
- - Linux: `systemctl --user stop paraclaw-<slug>`
73
- 2. **Pull the rename**: `git pull --ff-only` on the install dir, then `pnpm install` (the `postinstall` hook rebuilds the SPA bundle).
74
- 3. **Start the daemon**. On first boot, you'll see one or both of these log lines once and only once:
75
- ```
76
- Central DB migrated from legacy location from=…/paraclaw.db to=…/agent.db
77
- Master key migrated from legacy location from=…/claw/master.key to=…/agent/master.key
78
- ```
79
- 4. **Verify** via the web UI at the new mount: `/agent/` (was `/claw/`).
80
- 5. **Re-register the MCP server** in any Claude Code (or other MCP client) configs. The stdio entrypoint hasn't moved, but the server name has — old `claude mcp add paraclaw …` registrations keep pointing at the old name and tools advertise as `mcp__paraclaw__*` instead of `mcp__parachute_agent__*`:
81
- ```sh
82
- claude mcp remove paraclaw
83
- claude mcp add parachute-agent bun /path/to/install/src/mcp/stdio.ts
84
- ```
85
- 6. **Cleanup (optional)**: once you've verified the new install boots and decrypts secrets, delete the legacy backups: `rm ~/.parachute/claw/paraclaw.db ~/.parachute/claw/master.key && rmdir ~/.parachute/claw`.
86
-
87
- Browser sessions auto-migrate the SPA's `paraclaw.*` localStorage / sessionStorage keys (cached OAuth discovery, DCR client_id, tokens, in-flight flow state, setup-wizard resume state) to `parachute-agent.*` on first reload after the upgrade — no manual action required.
88
-
89
- - **Log filenames.** `logs/paraclaw.log` + `logs/paraclaw.error.log` → `logs/parachute-agent.log` + `logs/parachute-agent.error.log`. **Auto-renamed on first 0.1.0 boot** so historical entries stay accessible under the new name. The supervisor (launchd plist / systemd unit) is what routes the *live* daemon's stdout/stderr — until the operator re-runs `parachute install parachute-agent` to regenerate the unit, new entries continue landing in `paraclaw.log` (recreated by the supervisor after the rename) and the next supervisor-driven respawn opens it fresh. Once the unit is regenerated, subsequent boots write to `parachute-agent.log` directly. Operators tailing the new path see migrated history immediately; live writes follow on the next install-run.
90
- - **Env var prefix.** `PARACLAW_*` → `PARACHUTE_AGENT_*` (six vars: `_HUB_ORIGIN`, `_WEB_PORT`, `_WEB_BIND`, `_WEB_MOUNT`, `_WEB_ORIGIN`, `_CENTRAL_DB_PATH`). Each callsite reads the new name first, falls back to the legacy `PARACLAW_*` name if only that's set, and emits a one-shot deprecation warning per legacy name read. Operators can update their `.env` files at their leisure through 0.1.x; the legacy compat-read drops in 0.2.0. The Vite type declaration `VITE_PARACLAW_WEB_SERVER_URL` is also renamed to `VITE_PARACHUTE_AGENT_WEB_SERVER_URL` (the SPA doesn't read the value — it's a leftover declaration), no operator action needed.
91
- - **Allowlist directory.** `~/.config/paraclaw/{mount,sender}-allowlist.json` → `~/.config/parachute-agent/{mount,sender}-allowlist.json`. **Auto-moved on first 0.1.0 boot**: the legacy directory is left in place (operators may have stashed unrelated files there) but each known allowlist file is renamed to the new dir if the new path is absent. If both exist (e.g. operator pre-populated the new dir before upgrading), the new file wins and the legacy orphan is left for the operator to `rm`. Drop the auto-move in 0.2.0.
92
- - **Vault token-label default.** Fresh mints from the web UI's attach-vault flow and the new-group wizard now default to `agent-<folder>` (was `claw-<folder>`). Existing operator-typed labels keep working — the label is opaque to the vault, so prior `claw-<folder>` tokens continue to authenticate. Operators who want consistency can re-mint via the vault tokens UI. Reverses the parachute-agent#108 §2 deliberation in favor of brand consistency at the 0.1.0-stable cut.
93
- - **HKDF info strings — intentionally NOT renamed.** Five HKDF info constants (`paraclaw.secrets.v1`, `paraclaw.oauth.{client,access,refresh}.v1`, `paraclaw.provider-credentials.v1`) keep the `paraclaw.` prefix forever. They're cryptographic domain separators mixed into key derivation, not user-facing strings — renaming them would derive a different key and render every existing ciphertext row (secrets, OAuth tokens, provider credentials) undecryptable. Documented at each constant-definition site so a future brand sweep knows to skip these five lines. No operator action.
94
-
95
- ## [Unreleased]
96
-
97
- Hard fork from NanoClaw v2. Paraclaw is now its own service: single Bun process (host + web merged), native AES-GCM secrets layer, channels inlined permanently, skills system retired, capability card published at `/.well-known/parachute.json`. OneCLI is no longer a dependency.
98
-
99
- - **Schema relocate.** Central DB moved to `~/.parachute/claw/paraclaw.db`. Per-session two-file split (`inbound.db` + `outbound.db`) preserved — empirically validated as the only safe shape across Docker bind-mounts.
100
- - **Native secrets.** Master key at `~/.parachute/claw/master.key` (32 bytes, mode 0600), AES-256-GCM with HKDF domain separation per subsystem, redacted error messages. Migration 015 drops the vestigial `host_pattern` column.
101
- - **Web UI** ships native pages for paraclaw primitives: `/secrets`, `/approvals`, `/sessions`, `/channels`. Wizard's credential-capture step removed (replaced by `/secrets`).
102
- - **Lifecycle.** Install via `parachute install paraclaw`; start runs `bun src/index.ts`. Module manifest at `.parachute/module.json`.
103
- - **fix(secrets):** per-secret mode radio for global secrets was a silent UI illusion (paraclaw#9-era migration moved mode to `agent_groups.secret_mode`). Globals now hide the radio with explainer; scoped secrets reframe the radio as `<group> accepts: [all in-scope | only assigned]`, surfacing the per-group nature of the setting.
104
- - **feat(secrets):** post-save staleness banner detects running containers spawned before the secret update + per-session `[Restart]` + `Restart all N`. Calls existing `closeSession`; next inbound message respawns fresh with new env. New `GET /api/secrets/:id/stale-sessions` (claw:read).
105
- - **feat(GroupDetail):** per-session `[Restart]` button on the Live status list + inline help on the spawn-time env model — operators can restart any running container without leaving the agent group page, for code/env/agent-provider changes too, not just secrets.
106
-
107
- ## [2.0.0] - 2026-04-22 (NanoClaw v2 — paraclaw's ancestor)
108
-
109
- Major version. NanoClaw v2 was a substantial architectural rewrite that paraclaw forks from.
110
-
111
- - [BREAKING] **New entity model.** Users, roles (owner/admin), messaging groups, and agent groups are now tracked as separate entities, wired via `messaging_group_agents`. Privilege is user-level instead of channel-level, so the old "main channel = admin" concept is retired. See [docs/architecture.md](docs/architecture.md) and [docs/isolation-model.md](docs/isolation-model.md).
112
- - [BREAKING] **Two-DB session split.** Each session now has `inbound.db` (host writes, container reads) and `outbound.db` (container writes, host reads) with exactly one writer each. Replaces the single shared session DB and eliminates cross-mount SQLite contention. See [docs/db-session.md](docs/db-session.md).
113
- - [BREAKING] **Install flow replaced.** `bash nanoclaw.sh` is the new default: a scripted installer that hands off to Claude Code for error recovery and guided decisions. The `/setup` Claude-guided skill still works as an alternative.
114
- - [BREAKING] **Channels moved to the `channels` branch.** Trunk no longer ships Discord, Slack, Telegram, WhatsApp, iMessage, Teams, Linear, GitHub, WeChat, Matrix, Google Chat, Webex, Resend, or WhatsApp Cloud. Install them per fork via `/add-<channel>` skills, which copy from the `channels` branch. `/update-nanoclaw` will re-install the channels your fork had.
115
- - [BREAKING] **Alternative providers moved to the `providers` branch.** OpenCode, Codex, and Ollama install via `/add-opencode`, `/add-codex`, `/add-ollama-provider`. Claude remains the default provider baked into trunk.
116
- - [BREAKING] **Three-level channel isolation.** Wire channels to their own agent (separate agent groups), share an agent with independent conversations (`session_mode: 'shared'`), or merge channels into one shared session (`session_mode: 'agent-shared'`). Chosen per channel via `/manage-channels`.
117
- - [BREAKING] **Apple Container removed from default setup.** Still available as an opt-in via `/convert-to-apple-container`.
118
- - **Shared-source agent-runner.** Per-group `agent-runner-src/` overlays are gone; all groups mount the same agent-runner read-only. Per-group customization flows through composed `CLAUDE.md` (shared base + per-group fragments).
119
- - **Agent-runner runtime moved from Node to Bun.** Container image is self-contained; no host-side impact. Host remains on Node + pnpm.
120
- - **OneCLI Agent Vault is the sole credential path.** Containers never receive raw API keys; credentials are injected at request time.
121
-
122
- ## [1.2.36] - 2026-03-26
123
-
124
- - [BREAKING] Replaced pino logger with built-in logger. WhatsApp users must re-merge the WhatsApp fork to pick up the Baileys logger compatibility fix: `git fetch whatsapp main && git merge whatsapp/main`. If the `whatsapp` remote is not configured: `git remote add whatsapp https://github.com/qwibitai/nanoclaw-whatsapp.git`.
125
-
126
- ## [1.2.35] - 2026-03-26
127
-
128
- - [BREAKING] OneCLI Agent Vault replaces the built-in credential proxy. Check your runtime: `grep CONTAINER_RUNTIME_BIN src/container-runtime.ts` — if it shows `'container'` you are on Apple Container, if `'docker'` you are on Docker. Docker users: run `/init-onecli` to install OneCLI and migrate `.env` credentials to the vault. Apple Container users: re-merge the skill branch (`git fetch upstream skill/apple-container && git merge upstream/skill/apple-container`) then run `/convert-to-apple-container` and follow all instructions (configures credential proxy networking) — do NOT run `/init-onecli`, it requires Docker.
129
-
130
- ## [1.2.21] - 2026-03-22
131
-
132
- - Added opt-in diagnostics via PostHog with explicit user consent (Yes / No / Never ask again)
133
-
134
- ## [1.2.20] - 2026-03-21
135
-
136
- - Added ESLint configuration with error-handling rules
137
-
138
- ## [1.2.19] - 2026-03-19
139
-
140
- - Reduced `docker stop` timeout for faster container restarts (`-t 1` flag)
141
-
142
- ## [1.2.18] - 2026-03-19
143
-
144
- - User prompt content no longer logged on container errors — only input metadata
145
- - Added Japanese README translation
146
-
147
- ## [1.2.17] - 2026-03-18
148
-
149
- - Added `/capabilities` and `/status` container-agent skills
150
-
151
- ## [1.2.16] - 2026-03-18
152
-
153
- - Tasks snapshot now refreshes immediately after IPC task mutations
154
-
155
- ## [1.2.15] - 2026-03-16
156
-
157
- - Fixed remote-control prompt auto-accept to prevent immediate exit
158
- - Added `KillMode=process` so remote-control survives service restarts
159
-
160
- ## [1.2.14] - 2026-03-14
161
-
162
- - Added `/remote-control` command for host-level Claude Code access from within containers
163
-
164
- ## [1.2.13] - 2026-03-14
165
-
166
- **Breaking:** Skills are now git branches, channels are separate fork repos.
167
-
168
- - Skills live as `skill/*` git branches merged via `git merge`
169
- - Added Docker Sandboxes support
170
- - Fixed setup registration to use correct CLI commands
171
-
172
- ## [1.2.12] - 2026-03-08
173
-
174
- - Added `/compact` skill for manual context compaction
175
- - Enhanced container environment isolation via credential proxy
176
-
177
- ## [1.2.11] - 2026-03-08
178
-
179
- - Added PDF reader, image vision, and WhatsApp reactions skills
180
- - Fixed task container to close promptly when agent uses IPC-only messaging
181
-
182
- ## [1.2.10] - 2026-03-06
183
-
184
- - Added `LIMIT` to unbounded message history queries for better performance
185
-
186
- ## [1.2.9] - 2026-03-06
187
-
188
- - Agent prompts now include timezone context for accurate time references
189
-
190
- ## [1.2.8] - 2026-03-06
191
-
192
- - Fixed misleading `send_message` tool description for scheduled tasks
193
-
194
- ## [1.2.7] - 2026-03-06
195
-
196
- - Added `/add-ollama` skill for local model inference
197
- - Added `update_task` tool and return task ID from `schedule_task`
198
-
199
- ## [1.2.6] - 2026-03-04
200
-
201
- - Updated `claude-agent-sdk` to 0.2.68
202
-
203
- ## [1.2.5] - 2026-03-04
204
-
205
- - CI formatting fix
206
-
207
- ## [1.2.4] - 2026-03-04
208
-
209
- - Fixed `_chatJid` rename to `chatJid` in `onMessage` callback
210
-
211
- ## [1.2.3] - 2026-03-04
212
-
213
- - Added sender allowlist for per-chat access control
214
-
215
- ## [1.2.2] - 2026-03-04
216
-
217
- - Added `/use-local-whisper` skill for local voice transcription
218
- - Atomic task claims prevent scheduled tasks from executing twice
219
-
220
- ## [1.2.1] - 2026-03-02
221
-
222
- - Version bump (no functional changes)
223
-
224
- ## [1.2.0] - 2026-03-02
225
-
226
- **Breaking:** WhatsApp removed from core, now a skill. Run `/add-whatsapp` to re-add.
227
-
228
- - Channel registry: channels self-register at startup via `registerChannel()` factory pattern
229
- - `isMain` flag replaces folder-name-based main group detection
230
- - `ENABLED_CHANNELS` removed — channels detected by credential presence
231
- - Prevent scheduled tasks from executing twice when container runtime exceeds poll interval
232
-
233
- ## [1.1.6] - 2026-03-01
234
-
235
- - Added CJK font support for Chromium screenshots
236
-
237
- ## [1.1.5] - 2026-03-01
238
-
239
- - Fixed wrapped WhatsApp message normalization
240
-
241
- ## [1.1.4] - 2026-03-01
242
-
243
- - Added third-party model support
244
- - Added `/update-nanoclaw` skill for syncing with upstream
245
-
246
- ## [1.1.3] - 2026-02-25
247
-
248
- - Added `/add-slack` skill
249
- - Restructured Gmail skill for new architecture
250
-
251
- ## [1.1.2] - 2026-02-24
252
-
253
- - Improved error handling for WhatsApp Web version fetch
254
-
255
- ## [1.1.1] - 2026-02-24
256
-
257
- - Added Qodo skills and codebase intelligence
258
- - Fixed WhatsApp 405 connection failures
259
-
260
- ## [1.1.0] - 2026-02-23
261
-
262
- - Added `/update` skill to pull upstream changes from within Claude Code
263
- - Enhanced container environment isolation via credential proxy