@intent-systems/nexus 2026.1.5-3

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 (827) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/LICENSE +21 -0
  3. package/README-header.png +0 -0
  4. package/README.md +462 -0
  5. package/dist/agents/agent-paths.js +16 -0
  6. package/dist/agents/agent-scope.js +44 -0
  7. package/dist/agents/auth-profiles.js +626 -0
  8. package/dist/agents/bash-process-registry.js +126 -0
  9. package/dist/agents/bash-tools.js +838 -0
  10. package/dist/agents/chutes-oauth.js +47 -0
  11. package/dist/agents/clawdbot-tools.js +62 -0
  12. package/dist/agents/context.js +34 -0
  13. package/dist/agents/defaults.js +6 -0
  14. package/dist/agents/memory-search.js +80 -0
  15. package/dist/agents/model-auth.js +115 -0
  16. package/dist/agents/model-catalog.js +55 -0
  17. package/dist/agents/model-fallback.js +210 -0
  18. package/dist/agents/model-scan.js +263 -0
  19. package/dist/agents/model-selection.js +152 -0
  20. package/dist/agents/models-config.js +171 -0
  21. package/dist/agents/nexus-tools.js +46 -0
  22. package/dist/agents/pi-embedded-block-chunker.js +188 -0
  23. package/dist/agents/pi-embedded-helpers.js +139 -0
  24. package/dist/agents/pi-embedded-runner.js +932 -0
  25. package/dist/agents/pi-embedded-subscribe.js +541 -0
  26. package/dist/agents/pi-embedded-utils.js +20 -0
  27. package/dist/agents/pi-embedded.js +1 -0
  28. package/dist/agents/pi-extensions/compaction-safeguard.js +140 -0
  29. package/dist/agents/pi-tool-definition-adapter.js +17 -0
  30. package/dist/agents/pi-tools.js +510 -0
  31. package/dist/agents/pi-tools.schema.js +358 -0
  32. package/dist/agents/sandbox-paths.js +68 -0
  33. package/dist/agents/sandbox.js +667 -0
  34. package/dist/agents/shell-utils.js +53 -0
  35. package/dist/agents/skill-runner.js +224 -0
  36. package/dist/agents/skill-state.js +164 -0
  37. package/dist/agents/skill-tools.js +191 -0
  38. package/dist/agents/skill-usage.js +43 -0
  39. package/dist/agents/skills-install.js +244 -0
  40. package/dist/agents/skills-status.js +157 -0
  41. package/dist/agents/skills.js +472 -0
  42. package/dist/agents/subagent-registry.js +321 -0
  43. package/dist/agents/subagent-registry.store.js +47 -0
  44. package/dist/agents/system-prompt.js +179 -0
  45. package/dist/agents/timeout.js +26 -0
  46. package/dist/agents/tool-display.js +155 -0
  47. package/dist/agents/tool-display.json +236 -0
  48. package/dist/agents/tool-images.js +138 -0
  49. package/dist/agents/tool-policy.js +87 -0
  50. package/dist/agents/tools/agent-step.js +41 -0
  51. package/dist/agents/tools/browser-tool.js +295 -0
  52. package/dist/agents/tools/canvas-tool.js +193 -0
  53. package/dist/agents/tools/common.js +88 -0
  54. package/dist/agents/tools/cron-tool.js +141 -0
  55. package/dist/agents/tools/discord-actions-guild.js +186 -0
  56. package/dist/agents/tools/discord-actions-messaging.js +313 -0
  57. package/dist/agents/tools/discord-actions-moderation.js +70 -0
  58. package/dist/agents/tools/discord-actions.js +56 -0
  59. package/dist/agents/tools/discord-schema.js +199 -0
  60. package/dist/agents/tools/discord-tool.js +16 -0
  61. package/dist/agents/tools/gateway-tool.js +46 -0
  62. package/dist/agents/tools/gateway.js +28 -0
  63. package/dist/agents/tools/image-tool.js +140 -0
  64. package/dist/agents/tools/memory-tool.js +92 -0
  65. package/dist/agents/tools/nodes-tool.js +413 -0
  66. package/dist/agents/tools/nodes-utils.js +92 -0
  67. package/dist/agents/tools/sessions-announce-target.js +35 -0
  68. package/dist/agents/tools/sessions-helpers.js +88 -0
  69. package/dist/agents/tools/sessions-history-tool.js +137 -0
  70. package/dist/agents/tools/sessions-list-tool.js +196 -0
  71. package/dist/agents/tools/sessions-send-helpers.js +103 -0
  72. package/dist/agents/tools/sessions-send-tool.js +371 -0
  73. package/dist/agents/tools/sessions-spawn-tool.js +319 -0
  74. package/dist/agents/tools/slack-actions.js +129 -0
  75. package/dist/agents/tools/slack-schema.js +59 -0
  76. package/dist/agents/tools/slack-tool.js +16 -0
  77. package/dist/agents/tools/telegram-actions.js +159 -0
  78. package/dist/agents/tools/telegram-schema.js +28 -0
  79. package/dist/agents/tools/telegram-tool.js +16 -0
  80. package/dist/agents/tools/whatsapp-login-tool.js +63 -0
  81. package/dist/agents/usage.js +58 -0
  82. package/dist/agents/workspace.js +264 -0
  83. package/dist/auto-reply/chunk.js +177 -0
  84. package/dist/auto-reply/command-auth.js +44 -0
  85. package/dist/auto-reply/command-detection.js +22 -0
  86. package/dist/auto-reply/envelope.js +30 -0
  87. package/dist/auto-reply/group-activation.js +20 -0
  88. package/dist/auto-reply/heartbeat.js +58 -0
  89. package/dist/auto-reply/model.js +22 -0
  90. package/dist/auto-reply/reply/abort.js +14 -0
  91. package/dist/auto-reply/reply/agent-runner.js +426 -0
  92. package/dist/auto-reply/reply/bash-command.js +314 -0
  93. package/dist/auto-reply/reply/block-streaming.js +34 -0
  94. package/dist/auto-reply/reply/body.js +29 -0
  95. package/dist/auto-reply/reply/commands.js +332 -0
  96. package/dist/auto-reply/reply/directive-handling.js +626 -0
  97. package/dist/auto-reply/reply/directives.js +59 -0
  98. package/dist/auto-reply/reply/dispatch-from-config.js +23 -0
  99. package/dist/auto-reply/reply/followup-runner.js +181 -0
  100. package/dist/auto-reply/reply/groups.js +152 -0
  101. package/dist/auto-reply/reply/mentions.js +64 -0
  102. package/dist/auto-reply/reply/model-selection.js +209 -0
  103. package/dist/auto-reply/reply/queue.js +399 -0
  104. package/dist/auto-reply/reply/reply-dispatcher.js +68 -0
  105. package/dist/auto-reply/reply/reply-tags.js +26 -0
  106. package/dist/auto-reply/reply/session-updates.js +103 -0
  107. package/dist/auto-reply/reply/session.js +169 -0
  108. package/dist/auto-reply/reply/typing.js +125 -0
  109. package/dist/auto-reply/reply.js +655 -0
  110. package/dist/auto-reply/send-policy.js +28 -0
  111. package/dist/auto-reply/status.js +197 -0
  112. package/dist/auto-reply/templating.js +9 -0
  113. package/dist/auto-reply/thinking.js +49 -0
  114. package/dist/auto-reply/tokens.js +2 -0
  115. package/dist/auto-reply/tool-meta.js +74 -0
  116. package/dist/auto-reply/transcription.js +57 -0
  117. package/dist/auto-reply/types.js +1 -0
  118. package/dist/browser/bridge-server.js +37 -0
  119. package/dist/browser/cdp.js +382 -0
  120. package/dist/browser/chrome.js +432 -0
  121. package/dist/browser/client-actions-core.js +67 -0
  122. package/dist/browser/client-actions-observe.js +24 -0
  123. package/dist/browser/client-actions-types.js +1 -0
  124. package/dist/browser/client-actions.js +3 -0
  125. package/dist/browser/client-fetch.js +43 -0
  126. package/dist/browser/client.js +105 -0
  127. package/dist/browser/config.js +155 -0
  128. package/dist/browser/constants.js +5 -0
  129. package/dist/browser/profiles-service.js +124 -0
  130. package/dist/browser/profiles.js +96 -0
  131. package/dist/browser/pw-ai.js +2 -0
  132. package/dist/browser/pw-session.js +144 -0
  133. package/dist/browser/pw-tools-core.js +363 -0
  134. package/dist/browser/routes/agent.js +535 -0
  135. package/dist/browser/routes/basic.js +155 -0
  136. package/dist/browser/routes/index.js +8 -0
  137. package/dist/browser/routes/tabs.js +105 -0
  138. package/dist/browser/routes/utils.js +62 -0
  139. package/dist/browser/screenshot.js +40 -0
  140. package/dist/browser/server-context.js +377 -0
  141. package/dist/browser/server.js +81 -0
  142. package/dist/browser/target-id.js +18 -0
  143. package/dist/browser/trash.js +21 -0
  144. package/dist/canvas-host/a2ui/a2ui.bundle.js +17768 -0
  145. package/dist/canvas-host/a2ui/index.html +246 -0
  146. package/dist/canvas-host/a2ui.js +187 -0
  147. package/dist/canvas-host/server.js +382 -0
  148. package/dist/channel-web.js +8 -0
  149. package/dist/cli/browser-cli-actions-input.js +459 -0
  150. package/dist/cli/browser-cli-actions-observe.js +56 -0
  151. package/dist/cli/browser-cli-examples.js +31 -0
  152. package/dist/cli/browser-cli-inspect.js +97 -0
  153. package/dist/cli/browser-cli-manage.js +286 -0
  154. package/dist/cli/browser-cli-shared.js +1 -0
  155. package/dist/cli/browser-cli.js +26 -0
  156. package/dist/cli/canvas-cli.js +416 -0
  157. package/dist/cli/cloud-cli.js +336 -0
  158. package/dist/cli/credential-cli.js +227 -0
  159. package/dist/cli/cron-cli.js +454 -0
  160. package/dist/cli/deps.js +17 -0
  161. package/dist/cli/dns-cli.js +180 -0
  162. package/dist/cli/gateway-cli.js +665 -0
  163. package/dist/cli/gateway-rpc.js +20 -0
  164. package/dist/cli/hooks-cli.js +135 -0
  165. package/dist/cli/memory-cli.js +101 -0
  166. package/dist/cli/models-cli.js +248 -0
  167. package/dist/cli/nodes-camera.js +57 -0
  168. package/dist/cli/nodes-canvas.js +26 -0
  169. package/dist/cli/nodes-cli.js +946 -0
  170. package/dist/cli/nodes-screen.js +37 -0
  171. package/dist/cli/pairing-cli.js +100 -0
  172. package/dist/cli/parse-duration.js +20 -0
  173. package/dist/cli/plugins-cli.js +158 -0
  174. package/dist/cli/ports.js +97 -0
  175. package/dist/cli/profile.js +81 -0
  176. package/dist/cli/program.js +162 -0
  177. package/dist/cli/prompt.js +19 -0
  178. package/dist/cli/run-main.js +48 -0
  179. package/dist/cli/skills-cli.js +132 -0
  180. package/dist/cli/skills-hub-cli.js +1093 -0
  181. package/dist/cli/telegram-cli.js +56 -0
  182. package/dist/cli/tool-connector-cli.js +118 -0
  183. package/dist/cli/tui-cli.js +35 -0
  184. package/dist/cli/upstream-sync-cli.js +2833 -0
  185. package/dist/cli/usage-cli.js +24 -0
  186. package/dist/cli/wait.js +8 -0
  187. package/dist/commands/agent-via-gateway.js +115 -0
  188. package/dist/commands/agent.js +665 -0
  189. package/dist/commands/antigravity-oauth.js +327 -0
  190. package/dist/commands/auth-choice-options.js +80 -0
  191. package/dist/commands/auth-choice.js +134 -0
  192. package/dist/commands/auth-token.js +31 -0
  193. package/dist/commands/bootstrap-preset.js +214 -0
  194. package/dist/commands/capabilities.js +36 -0
  195. package/dist/commands/chutes-oauth.js +144 -0
  196. package/dist/commands/claude-md.js +137 -0
  197. package/dist/commands/config-view.js +11 -0
  198. package/dist/commands/configure.js +648 -0
  199. package/dist/commands/credential.js +236 -0
  200. package/dist/commands/cursor-rules.js +230 -0
  201. package/dist/commands/doctor-state-migrations.js +358 -0
  202. package/dist/commands/doctor-ui.js +113 -0
  203. package/dist/commands/doctor.js +673 -0
  204. package/dist/commands/health.js +112 -0
  205. package/dist/commands/identity.js +54 -0
  206. package/dist/commands/init.js +167 -0
  207. package/dist/commands/models/aliases.js +85 -0
  208. package/dist/commands/models/fallbacks.js +123 -0
  209. package/dist/commands/models/image-fallbacks.js +123 -0
  210. package/dist/commands/models/list.js +347 -0
  211. package/dist/commands/models/scan.js +271 -0
  212. package/dist/commands/models/set-image.js +27 -0
  213. package/dist/commands/models/set.js +27 -0
  214. package/dist/commands/models/shared.js +73 -0
  215. package/dist/commands/models.js +7 -0
  216. package/dist/commands/onboard-auth.js +101 -0
  217. package/dist/commands/onboard-channels.js +814 -0
  218. package/dist/commands/onboard-eve-identity.js +98 -0
  219. package/dist/commands/onboard-github.js +153 -0
  220. package/dist/commands/onboard-helpers.js +303 -0
  221. package/dist/commands/onboard-interactive.js +17 -0
  222. package/dist/commands/onboard-non-interactive.js +228 -0
  223. package/dist/commands/onboard-providers.js +829 -0
  224. package/dist/commands/onboard-quickstart.js +185 -0
  225. package/dist/commands/onboard-remote.js +120 -0
  226. package/dist/commands/onboard-skills.js +148 -0
  227. package/dist/commands/onboard-types.js +1 -0
  228. package/dist/commands/onboard.js +19 -0
  229. package/dist/commands/openai-codex-model-default.js +38 -0
  230. package/dist/commands/poll.js +64 -0
  231. package/dist/commands/quest.js +27 -0
  232. package/dist/commands/reset.js +61 -0
  233. package/dist/commands/send.js +124 -0
  234. package/dist/commands/sessions-ingest.js +359 -0
  235. package/dist/commands/sessions.js +212 -0
  236. package/dist/commands/setup.js +59 -0
  237. package/dist/commands/signal-install.js +135 -0
  238. package/dist/commands/skills-manifest.js +235 -0
  239. package/dist/commands/status.js +139 -0
  240. package/dist/commands/suggestions.js +54 -0
  241. package/dist/commands/systemd-linger.js +71 -0
  242. package/dist/commands/update.js +16 -0
  243. package/dist/commands/usage-upload.js +27 -0
  244. package/dist/config/config.js +6 -0
  245. package/dist/config/defaults.js +140 -0
  246. package/dist/config/group-policy.js +49 -0
  247. package/dist/config/includes.js +183 -0
  248. package/dist/config/io.js +188 -0
  249. package/dist/config/legacy-migrate.js +13 -0
  250. package/dist/config/legacy.js +425 -0
  251. package/dist/config/paths.js +82 -0
  252. package/dist/config/port-defaults.js +32 -0
  253. package/dist/config/schema.js +173 -0
  254. package/dist/config/sessions.js +611 -0
  255. package/dist/config/talk.js +31 -0
  256. package/dist/config/types.js +1 -0
  257. package/dist/config/validation.js +29 -0
  258. package/dist/config/zod-schema.js +1110 -0
  259. package/dist/control-ui/assets/index-D8Q5AI4D.js +2393 -0
  260. package/dist/control-ui/assets/index-D8Q5AI4D.js.map +1 -0
  261. package/dist/control-ui/assets/index-g06q5Xc3.css +1 -0
  262. package/dist/control-ui/favicon.ico +0 -0
  263. package/dist/control-ui/index.html +16 -0
  264. package/dist/cron/isolated-agent.js +529 -0
  265. package/dist/cron/normalize.js +73 -0
  266. package/dist/cron/parse.js +24 -0
  267. package/dist/cron/run-log.js +72 -0
  268. package/dist/cron/schedule.js +24 -0
  269. package/dist/cron/service.js +471 -0
  270. package/dist/cron/store.js +43 -0
  271. package/dist/cron/types.js +1 -0
  272. package/dist/daemon/constants.js +10 -0
  273. package/dist/daemon/launchd.js +295 -0
  274. package/dist/daemon/legacy.js +63 -0
  275. package/dist/daemon/program-args.js +141 -0
  276. package/dist/daemon/schtasks.js +269 -0
  277. package/dist/daemon/service.js +69 -0
  278. package/dist/daemon/systemd.js +332 -0
  279. package/dist/discord/index.js +2 -0
  280. package/dist/discord/monitor.js +1089 -0
  281. package/dist/discord/probe.js +54 -0
  282. package/dist/discord/send.js +652 -0
  283. package/dist/discord/token.js +8 -0
  284. package/dist/entry.js +16 -0
  285. package/dist/gateway/auth.js +121 -0
  286. package/dist/gateway/call.js +103 -0
  287. package/dist/gateway/chat-attachments.js +41 -0
  288. package/dist/gateway/client.js +180 -0
  289. package/dist/gateway/config-reload.js +274 -0
  290. package/dist/gateway/control-ui.js +184 -0
  291. package/dist/gateway/hooks-mapping.js +282 -0
  292. package/dist/gateway/hooks.js +168 -0
  293. package/dist/gateway/net.js +29 -0
  294. package/dist/gateway/protocol/index.js +62 -0
  295. package/dist/gateway/protocol/schema.js +577 -0
  296. package/dist/gateway/server-bridge-subscriptions.js +93 -0
  297. package/dist/gateway/server-bridge.js +1066 -0
  298. package/dist/gateway/server-browser.js +11 -0
  299. package/dist/gateway/server-channels.js +680 -0
  300. package/dist/gateway/server-chat.js +159 -0
  301. package/dist/gateway/server-constants.js +8 -0
  302. package/dist/gateway/server-discovery.js +62 -0
  303. package/dist/gateway/server-http.js +165 -0
  304. package/dist/gateway/server-methods/agent-job.js +114 -0
  305. package/dist/gateway/server-methods/agent.js +254 -0
  306. package/dist/gateway/server-methods/channels.js +239 -0
  307. package/dist/gateway/server-methods/chat.js +207 -0
  308. package/dist/gateway/server-methods/config.js +50 -0
  309. package/dist/gateway/server-methods/connect.js +6 -0
  310. package/dist/gateway/server-methods/cron.js +89 -0
  311. package/dist/gateway/server-methods/health.js +28 -0
  312. package/dist/gateway/server-methods/models.js +16 -0
  313. package/dist/gateway/server-methods/nodes.js +294 -0
  314. package/dist/gateway/server-methods/providers.js +257 -0
  315. package/dist/gateway/server-methods/send.js +254 -0
  316. package/dist/gateway/server-methods/sessions.js +382 -0
  317. package/dist/gateway/server-methods/skills.js +83 -0
  318. package/dist/gateway/server-methods/system.js +118 -0
  319. package/dist/gateway/server-methods/talk.js +22 -0
  320. package/dist/gateway/server-methods/types.js +1 -0
  321. package/dist/gateway/server-methods/voicewake.js +30 -0
  322. package/dist/gateway/server-methods/web.js +81 -0
  323. package/dist/gateway/server-methods/wizard.js +100 -0
  324. package/dist/gateway/server-methods.js +53 -0
  325. package/dist/gateway/server-providers.js +687 -0
  326. package/dist/gateway/server-shared.js +1 -0
  327. package/dist/gateway/server-utils.js +35 -0
  328. package/dist/gateway/server.js +1478 -0
  329. package/dist/gateway/session-utils.js +355 -0
  330. package/dist/gateway/ws-log.js +343 -0
  331. package/dist/gateway/ws-logging.js +8 -0
  332. package/dist/globals.js +41 -0
  333. package/dist/hooks/gmail-ops.js +236 -0
  334. package/dist/hooks/gmail-setup-utils.js +278 -0
  335. package/dist/hooks/gmail-watcher.js +190 -0
  336. package/dist/hooks/gmail.js +177 -0
  337. package/dist/imessage/client.js +165 -0
  338. package/dist/imessage/index.js +3 -0
  339. package/dist/imessage/monitor.js +365 -0
  340. package/dist/imessage/probe.js +26 -0
  341. package/dist/imessage/send.js +83 -0
  342. package/dist/imessage/targets.js +176 -0
  343. package/dist/index.js +55 -0
  344. package/dist/infra/agent-events.js +46 -0
  345. package/dist/infra/binaries.js +9 -0
  346. package/dist/infra/bonjour-discovery.js +163 -0
  347. package/dist/infra/bonjour.js +200 -0
  348. package/dist/infra/bridge/server.js +564 -0
  349. package/dist/infra/canvas-host-url.js +54 -0
  350. package/dist/infra/channel-summary.js +78 -0
  351. package/dist/infra/control-ui-assets.js +112 -0
  352. package/dist/infra/dotenv.js +15 -0
  353. package/dist/infra/env.js +8 -0
  354. package/dist/infra/errors.js +28 -0
  355. package/dist/infra/event-log.js +251 -0
  356. package/dist/infra/gateway-lock.js +8 -0
  357. package/dist/infra/git-commit.js +91 -0
  358. package/dist/infra/heartbeat-events.js +21 -0
  359. package/dist/infra/heartbeat-runner.js +458 -0
  360. package/dist/infra/heartbeat-wake.js +61 -0
  361. package/dist/infra/is-main.js +37 -0
  362. package/dist/infra/json-file.js +21 -0
  363. package/dist/infra/machine-name.js +40 -0
  364. package/dist/infra/nexus-root.js +56 -0
  365. package/dist/infra/node-pairing.js +212 -0
  366. package/dist/infra/path-env.js +93 -0
  367. package/dist/infra/ports.js +87 -0
  368. package/dist/infra/provider-summary.js +80 -0
  369. package/dist/infra/provider-usage.auth.js +189 -0
  370. package/dist/infra/provider-usage.fetch.claude.js +129 -0
  371. package/dist/infra/provider-usage.fetch.codex.js +62 -0
  372. package/dist/infra/provider-usage.fetch.copilot.js +42 -0
  373. package/dist/infra/provider-usage.fetch.gemini.js +57 -0
  374. package/dist/infra/provider-usage.fetch.js +6 -0
  375. package/dist/infra/provider-usage.fetch.minimax.js +214 -0
  376. package/dist/infra/provider-usage.fetch.shared.js +11 -0
  377. package/dist/infra/provider-usage.fetch.zai.js +62 -0
  378. package/dist/infra/provider-usage.format.js +77 -0
  379. package/dist/infra/provider-usage.js +145 -0
  380. package/dist/infra/provider-usage.load.js +54 -0
  381. package/dist/infra/provider-usage.shared.js +19 -0
  382. package/dist/infra/provider-usage.types.js +1 -0
  383. package/dist/infra/restart.js +29 -0
  384. package/dist/infra/retry.js +16 -0
  385. package/dist/infra/runtime-guard.js +59 -0
  386. package/dist/infra/shell-env.js +88 -0
  387. package/dist/infra/system-events.js +71 -0
  388. package/dist/infra/system-presence.js +217 -0
  389. package/dist/infra/tailnet.js +46 -0
  390. package/dist/infra/tailscale.js +149 -0
  391. package/dist/infra/unhandled-rejections.js +19 -0
  392. package/dist/infra/usage-suggestions.js +241 -0
  393. package/dist/infra/usage-upload.js +290 -0
  394. package/dist/infra/voicewake.js +78 -0
  395. package/dist/infra/widearea-dns.js +123 -0
  396. package/dist/infra/ws.js +13 -0
  397. package/dist/logger.js +52 -0
  398. package/dist/logging.js +506 -0
  399. package/dist/macos/gateway-daemon.js +145 -0
  400. package/dist/macos/relay.js +49 -0
  401. package/dist/media/constants.js +33 -0
  402. package/dist/media/host.js +42 -0
  403. package/dist/media/image-ops.js +119 -0
  404. package/dist/media/mime.js +123 -0
  405. package/dist/media/parse.js +83 -0
  406. package/dist/media/server.js +64 -0
  407. package/dist/media/store.js +139 -0
  408. package/dist/polls.js +43 -0
  409. package/dist/process/command-queue.js +97 -0
  410. package/dist/process/exec.js +75 -0
  411. package/dist/provider-web.js +8 -0
  412. package/dist/providers/github-copilot-auth.js +123 -0
  413. package/dist/providers/github-copilot-models.js +35 -0
  414. package/dist/providers/github-copilot-token.js +11 -0
  415. package/dist/providers/location.js +48 -0
  416. package/dist/providers/web/index.js +2 -0
  417. package/dist/runtime.js +8 -0
  418. package/dist/sessions/level-overrides.js +9 -0
  419. package/dist/sessions/send-policy.js +68 -0
  420. package/dist/signal/client.js +134 -0
  421. package/dist/signal/daemon.js +69 -0
  422. package/dist/signal/index.js +3 -0
  423. package/dist/signal/monitor.js +411 -0
  424. package/dist/signal/probe.js +46 -0
  425. package/dist/signal/send.js +91 -0
  426. package/dist/slack/actions.js +97 -0
  427. package/dist/slack/index.js +5 -0
  428. package/dist/slack/monitor.js +1270 -0
  429. package/dist/slack/probe.js +47 -0
  430. package/dist/slack/send.js +131 -0
  431. package/dist/slack/token.js +10 -0
  432. package/dist/telegram/allowed-updates.js +8 -0
  433. package/dist/telegram/bot.js +724 -0
  434. package/dist/telegram/download.js +34 -0
  435. package/dist/telegram/index.js +4 -0
  436. package/dist/telegram/monitor.js +47 -0
  437. package/dist/telegram/pairing-store.js +77 -0
  438. package/dist/telegram/probe.js +63 -0
  439. package/dist/telegram/proxy.js +9 -0
  440. package/dist/telegram/reaction-level.js +45 -0
  441. package/dist/telegram/send.js +151 -0
  442. package/dist/telegram/sent-message-cache.js +65 -0
  443. package/dist/telegram/token.js +30 -0
  444. package/dist/telegram/update-offset-store.js +61 -0
  445. package/dist/telegram/webhook-set.js +12 -0
  446. package/dist/telegram/webhook.js +56 -0
  447. package/dist/tui/commands.js +87 -0
  448. package/dist/tui/components/assistant-message.js +16 -0
  449. package/dist/tui/components/chat-log.js +92 -0
  450. package/dist/tui/components/custom-editor.js +55 -0
  451. package/dist/tui/components/selectors.js +8 -0
  452. package/dist/tui/components/tool-execution.js +111 -0
  453. package/dist/tui/components/user-message.js +17 -0
  454. package/dist/tui/gateway-chat.js +140 -0
  455. package/dist/tui/theme/theme.js +80 -0
  456. package/dist/tui/tui.js +708 -0
  457. package/dist/utils.js +153 -0
  458. package/dist/version.js +18 -0
  459. package/dist/web/accounts.js +86 -0
  460. package/dist/web/active-listener.js +25 -0
  461. package/dist/web/auto-reply.js +1256 -0
  462. package/dist/web/inbound.js +649 -0
  463. package/dist/web/login-qr.js +230 -0
  464. package/dist/web/login.js +71 -0
  465. package/dist/web/media.js +175 -0
  466. package/dist/web/outbound.js +102 -0
  467. package/dist/web/qr-image.js +97 -0
  468. package/dist/web/reconnect.js +60 -0
  469. package/dist/web/session.js +370 -0
  470. package/dist/wizard/clack-prompter.js +56 -0
  471. package/dist/wizard/onboarding.js +620 -0
  472. package/dist/wizard/prompts.js +6 -0
  473. package/dist/wizard/session.js +203 -0
  474. package/docs/AGENTS.default.md +116 -0
  475. package/docs/CAPABILITIES.md +444 -0
  476. package/docs/CNAME +1 -0
  477. package/docs/NEXUS_CORE_REWRITE_SPEC.md +226 -0
  478. package/docs/RELEASING.md +69 -0
  479. package/docs/_config.yml +53 -0
  480. package/docs/_layouts/default.html +145 -0
  481. package/docs/agent-assisted-install.md +95 -0
  482. package/docs/agent-loop.md +61 -0
  483. package/docs/agent-send.md +21 -0
  484. package/docs/agent.md +108 -0
  485. package/docs/android.md +133 -0
  486. package/docs/architecture.md +114 -0
  487. package/docs/assets/markdown.css +133 -0
  488. package/docs/assets/pixel-lobster.svg +60 -0
  489. package/docs/assets/terminal.css +470 -0
  490. package/docs/assets/theme.js +55 -0
  491. package/docs/audio.md +48 -0
  492. package/docs/automation/nexus-sync.md +371 -0
  493. package/docs/background-process.md +74 -0
  494. package/docs/bash.md +32 -0
  495. package/docs/bedrock.md +71 -0
  496. package/docs/bonjour.md +159 -0
  497. package/docs/browser-linux-troubleshooting.md +114 -0
  498. package/docs/browser.md +293 -0
  499. package/docs/bun.md +56 -0
  500. package/docs/camera.md +152 -0
  501. package/docs/clawd.md +212 -0
  502. package/docs/concepts/usage-tracking.md +29 -0
  503. package/docs/configuration.md +1666 -0
  504. package/docs/control-ui.md +83 -0
  505. package/docs/cron.md +385 -0
  506. package/docs/dashboard.md +17 -0
  507. package/docs/device-models.md +46 -0
  508. package/docs/discord.md +308 -0
  509. package/docs/discovery.md +112 -0
  510. package/docs/docker.md +258 -0
  511. package/docs/docs.json +105 -0
  512. package/docs/doctor.md +68 -0
  513. package/docs/elevated.md +31 -0
  514. package/docs/faq.md +736 -0
  515. package/docs/feature-inventory/overview.md +141 -0
  516. package/docs/feature-inventory/rollout-checklist.md +53 -0
  517. package/docs/feature-inventory/test-matrix.md +87 -0
  518. package/docs/feature-inventory.md +9 -0
  519. package/docs/gateway/configuration-examples.md +221 -0
  520. package/docs/gateway/configuration.md +172 -0
  521. package/docs/gateway/cron.md +61 -0
  522. package/docs/gateway/heartbeat.md +207 -0
  523. package/docs/gateway/pairing.md +109 -0
  524. package/docs/gateway-lock.md +28 -0
  525. package/docs/gateway.md +227 -0
  526. package/docs/gmail-pubsub.md +191 -0
  527. package/docs/grammy.md +27 -0
  528. package/docs/group-messages.md +73 -0
  529. package/docs/groups.md +130 -0
  530. package/docs/health.md +28 -0
  531. package/docs/heartbeat.md +73 -0
  532. package/docs/home-userspace.md +277 -0
  533. package/docs/hubs.md +148 -0
  534. package/docs/images.md +51 -0
  535. package/docs/imessage.md +94 -0
  536. package/docs/index.md +196 -0
  537. package/docs/ios.md +372 -0
  538. package/docs/linux.md +11 -0
  539. package/docs/location-command.md +95 -0
  540. package/docs/location.md +46 -0
  541. package/docs/logging.md +110 -0
  542. package/docs/lore.md +131 -0
  543. package/docs/mac/bun.md +133 -0
  544. package/docs/mac/canvas.md +161 -0
  545. package/docs/mac/child-process.md +72 -0
  546. package/docs/mac/dev-setup.md +81 -0
  547. package/docs/mac/health.md +28 -0
  548. package/docs/mac/icon.md +26 -0
  549. package/docs/mac/logging.md +51 -0
  550. package/docs/mac/menu-bar.md +69 -0
  551. package/docs/mac/peekaboo.md +170 -0
  552. package/docs/mac/permissions.md +40 -0
  553. package/docs/mac/release.md +76 -0
  554. package/docs/mac/remote.md +57 -0
  555. package/docs/mac/signing.md +41 -0
  556. package/docs/mac/skills.md +27 -0
  557. package/docs/mac/voice-overlay.md +52 -0
  558. package/docs/mac/voicewake.md +56 -0
  559. package/docs/mac/webchat.md +27 -0
  560. package/docs/mac/xpc.md +40 -0
  561. package/docs/macos.md +104 -0
  562. package/docs/model-failover.md +75 -0
  563. package/docs/models.md +91 -0
  564. package/docs/multi-agent.md +74 -0
  565. package/docs/nix.md +95 -0
  566. package/docs/nodes.md +157 -0
  567. package/docs/onboarding-config-protocol.md +34 -0
  568. package/docs/onboarding.md +189 -0
  569. package/docs/pairing.md +85 -0
  570. package/docs/plans/cron-add-hardening.md +72 -0
  571. package/docs/plans/group-policy-hardening.md +121 -0
  572. package/docs/poll.md +52 -0
  573. package/docs/prereqs.md +67 -0
  574. package/docs/presence.md +133 -0
  575. package/docs/proposals/model-config.md +147 -0
  576. package/docs/provider-routing.md +25 -0
  577. package/docs/queue.md +78 -0
  578. package/docs/reference/templates/AGENTS.md +164 -0
  579. package/docs/remote-gateway-readme.md +153 -0
  580. package/docs/remote.md +61 -0
  581. package/docs/research/memory.md +227 -0
  582. package/docs/rpc.md +35 -0
  583. package/docs/security.md +200 -0
  584. package/docs/session-ingestion.md +119 -0
  585. package/docs/session-tool.md +154 -0
  586. package/docs/session.md +85 -0
  587. package/docs/sessions.md +8 -0
  588. package/docs/setup.md +131 -0
  589. package/docs/showcase.md +37 -0
  590. package/docs/signal.md +122 -0
  591. package/docs/skills-config.md +58 -0
  592. package/docs/skills.md +153 -0
  593. package/docs/slack.md +221 -0
  594. package/docs/subagents.md +72 -0
  595. package/docs/tailscale.md +71 -0
  596. package/docs/talk.md +79 -0
  597. package/docs/telegram.md +96 -0
  598. package/docs/templates/AGENTS.md +286 -0
  599. package/docs/templates/BOOTSTRAP.md +35 -0
  600. package/docs/templates/IDENTITY.md +17 -0
  601. package/docs/templates/PROFILE.md +14 -0
  602. package/docs/templates/SOUL.md +41 -0
  603. package/docs/templates/TOOLS.md +41 -0
  604. package/docs/templates/USER.md +8 -0
  605. package/docs/test.md +43 -0
  606. package/docs/testing-onboarding-quickstart.md +76 -0
  607. package/docs/testing-philosophy.md +211 -0
  608. package/docs/thinking.md +46 -0
  609. package/docs/timezone.md +40 -0
  610. package/docs/tools.md +346 -0
  611. package/docs/troubleshooting.md +257 -0
  612. package/docs/tui.md +71 -0
  613. package/docs/typebox.md +42 -0
  614. package/docs/updating.md +138 -0
  615. package/docs/usage-cloud-aggregation-spec.md +133 -0
  616. package/docs/usage-suggestions-pipeline.md +126 -0
  617. package/docs/voicewake.md +61 -0
  618. package/docs/web.md +115 -0
  619. package/docs/webchat.md +34 -0
  620. package/docs/webhook.md +132 -0
  621. package/docs/whatsapp-clawd.jpg +0 -0
  622. package/docs/whatsapp.md +170 -0
  623. package/docs/windows.md +11 -0
  624. package/docs/wizard.md +167 -0
  625. package/package.json +209 -0
  626. package/skills/1password/SKILL.md +54 -0
  627. package/skills/1password/docs/setup.md +85 -0
  628. package/skills/1password/docs/troubleshooting.md +63 -0
  629. package/skills/1password/references/cli-examples.md +29 -0
  630. package/skills/1password/references/get-started.md +17 -0
  631. package/skills/agent-browser/SKILL.md +450 -0
  632. package/skills/agent-browser/docs/browser-use-eval.md +95 -0
  633. package/skills/agent-browser/docs/first-tests.md +261 -0
  634. package/skills/agent-browser/docs/wordle-nyt-eval.js +32 -0
  635. package/skills/aix/SKILL.md +93 -0
  636. package/skills/aix/docs/embeddings.md +40 -0
  637. package/skills/aix/docs/setup.md +58 -0
  638. package/skills/aix/docs/troubleshooting.md +41 -0
  639. package/skills/aix/references/sql.md +48 -0
  640. package/skills/apple-notes/SKILL.md +50 -0
  641. package/skills/apple-reminders/SKILL.md +67 -0
  642. package/skills/bear-notes/SKILL.md +79 -0
  643. package/skills/bird/SKILL.md +32 -0
  644. package/skills/bird/docs/auth.md +31 -0
  645. package/skills/bird/docs/troubleshooting.md +31 -0
  646. package/skills/blogwatcher/SKILL.md +46 -0
  647. package/skills/blucli/SKILL.md +27 -0
  648. package/skills/brave-search/SKILL.md +36 -0
  649. package/skills/brave-search/docs/setup.md +40 -0
  650. package/skills/brave-search/docs/troubleshooting.md +37 -0
  651. package/skills/brave-search/docs/usage.md +28 -0
  652. package/skills/brave-search/scripts/content.mjs +53 -0
  653. package/skills/brave-search/scripts/search.mjs +79 -0
  654. package/skills/browser-use-agent-sdk/SKILL.md +90 -0
  655. package/skills/camsnap/SKILL.md +25 -0
  656. package/skills/clawdhub/SKILL.md +53 -0
  657. package/skills/coding-agent/SKILL.md +274 -0
  658. package/skills/comms/SKILL.md +249 -0
  659. package/skills/comms/docs/adapters.md +54 -0
  660. package/skills/comms/docs/setup.md +56 -0
  661. package/skills/comms/docs/troubleshooting.md +44 -0
  662. package/skills/comms/references/schema.md +49 -0
  663. package/skills/computer-use/SKILL.md +204 -0
  664. package/skills/computer-use/docs/open-interpreter.md +26 -0
  665. package/skills/computer-use/docs/peekaboo.md +26 -0
  666. package/skills/computer-use/docs/setup.md +47 -0
  667. package/skills/computer-use/docs/troubleshooting.md +33 -0
  668. package/skills/discord/SKILL.md +370 -0
  669. package/skills/eightctl/SKILL.md +29 -0
  670. package/skills/eve/SKILL.md +215 -0
  671. package/skills/eve/docs/dual-account.md +84 -0
  672. package/skills/eve/docs/intelligence.md +58 -0
  673. package/skills/eve/docs/setup.md +60 -0
  674. package/skills/eve/docs/troubleshooting.md +54 -0
  675. package/skills/eve/scripts/setup-dual-account.sh +125 -0
  676. package/skills/filesystem/SKILL.md +217 -0
  677. package/skills/food-order/SKILL.md +41 -0
  678. package/skills/gemini/SKILL.md +23 -0
  679. package/skills/gh/SKILL.md +22 -0
  680. package/skills/gh/docs/usage.md +41 -0
  681. package/skills/gifgrep/SKILL.md +47 -0
  682. package/skills/github/SKILL.md +26 -0
  683. package/skills/github/docs/setup.md +21 -0
  684. package/skills/github/docs/troubleshooting.md +24 -0
  685. package/skills/gog/SKILL.md +104 -0
  686. package/skills/gog/docs/portability.md +94 -0
  687. package/skills/gog/docs/setup.md +76 -0
  688. package/skills/gog/docs/troubleshooting.md +94 -0
  689. package/skills/gog/scripts/cdp/README.md +90 -0
  690. package/skills/gog/scripts/cdp/add_test_users.py +69 -0
  691. package/skills/gog/scripts/cdp/auth_add_accounts.py +209 -0
  692. package/skills/gog/scripts/cdp/auth_add_accounts_manual.py +206 -0
  693. package/skills/gog/scripts/cdp/create_oauth_client.py +165 -0
  694. package/skills/gog/scripts/cdp/launch_cdp_chrome.sh +58 -0
  695. package/skills/google-oauth/SKILL.md +94 -0
  696. package/skills/goplaces/SKILL.md +30 -0
  697. package/skills/imsg/SKILL.md +25 -0
  698. package/skills/json-render/SKILL.md +154 -0
  699. package/skills/json-render/assets/components/README.md +21 -0
  700. package/skills/json-render/assets/components/catalog.ts +78 -0
  701. package/skills/json-render/assets/components/registry.tsx +172 -0
  702. package/skills/json-render/assets/demo/App.css +397 -0
  703. package/skills/json-render/assets/demo/App.tsx +897 -0
  704. package/skills/json-render/assets/demo/README.md +22 -0
  705. package/skills/json-render/assets/demo/catalog.ts +78 -0
  706. package/skills/json-render/assets/demo/data/nexus-core.json +31 -0
  707. package/skills/json-render/assets/demo/index.css +27 -0
  708. package/skills/json-render/assets/demo/registry.tsx +150 -0
  709. package/skills/json-render/docs/nexus-state-demo.md +84 -0
  710. package/skills/json-render/docs/shadcn-preset.md +33 -0
  711. package/skills/json-render/scripts/create-vite-demo.sh +45 -0
  712. package/skills/json-render/scripts/llm-server/README.md +33 -0
  713. package/skills/json-render/scripts/llm-server/catalog.ts +78 -0
  714. package/skills/json-render/scripts/llm-server/package-lock.json +702 -0
  715. package/skills/json-render/scripts/llm-server/package.json +18 -0
  716. package/skills/json-render/scripts/llm-server/server.ts +285 -0
  717. package/skills/local-places/SERVER_README.md +101 -0
  718. package/skills/local-places/SKILL.md +91 -0
  719. package/skills/local-places/pyproject.toml +27 -0
  720. package/skills/local-places/src/local_places/__init__.py +2 -0
  721. package/skills/local-places/src/local_places/__pycache__/__init__.cpython-314.pyc +0 -0
  722. package/skills/local-places/src/local_places/__pycache__/google_places.cpython-314.pyc +0 -0
  723. package/skills/local-places/src/local_places/__pycache__/main.cpython-314.pyc +0 -0
  724. package/skills/local-places/src/local_places/__pycache__/schemas.cpython-314.pyc +0 -0
  725. package/skills/local-places/src/local_places/google_places.py +314 -0
  726. package/skills/local-places/src/local_places/main.py +65 -0
  727. package/skills/local-places/src/local_places/schemas.py +107 -0
  728. package/skills/mcporter/SKILL.md +38 -0
  729. package/skills/model-usage/SKILL.md +45 -0
  730. package/skills/model-usage/references/codexbar-cli.md +28 -0
  731. package/skills/model-usage/scripts/model_usage.py +310 -0
  732. package/skills/nano-banana-pro/SKILL.md +30 -0
  733. package/skills/nano-banana-pro/scripts/generate_image.py +169 -0
  734. package/skills/nano-pdf/SKILL.md +20 -0
  735. package/skills/nexus-cloud/SKILL.md +53 -0
  736. package/skills/nexus-cloud/docs/security.md +24 -0
  737. package/skills/nexus-cloud/docs/setup.md +51 -0
  738. package/skills/nexus-cloud/docs/troubleshooting.md +28 -0
  739. package/skills/notion/SKILL.md +156 -0
  740. package/skills/obsidian/SKILL.md +55 -0
  741. package/skills/onboarding/SKILL.md +515 -0
  742. package/skills/onboarding/docs/CAPABILITIES.md +444 -0
  743. package/skills/onboarding/docs/CAPABILITY_TAXONOMY.md +608 -0
  744. package/skills/onboarding/docs/CLI_GRAMMAR.md +797 -0
  745. package/skills/onboarding/docs/CLI_GRAMMAR_CREDENTIALS.md +632 -0
  746. package/skills/onboarding/docs/CLI_GRAMMAR_ONBOARDING.md +815 -0
  747. package/skills/onboarding/docs/CLI_GRAMMAR_SKILLS.md +449 -0
  748. package/skills/onboarding/docs/DOCUMENTATION_OVERVIEW.md +290 -0
  749. package/skills/onboarding/docs/ENTITY_MODEL.md +582 -0
  750. package/skills/onboarding/docs/GOAL_STATE_ARCHITECTURE.md +395 -0
  751. package/skills/onboarding/docs/NEXUS_SYSTEM_OVERVIEW.md +476 -0
  752. package/skills/onboarding/docs/SKILLS_HUB_SPEC.md +477 -0
  753. package/skills/onboarding/docs/SKILLS_SPECIFICATION.md +947 -0
  754. package/skills/onboarding/docs/SKILL_GATEWAY_DESIGN.md +702 -0
  755. package/skills/onboarding/docs/SKILL_GATEWAY_PRD.md +278 -0
  756. package/skills/onboarding/docs/SKILL_INVENTORY.md +266 -0
  757. package/skills/onboarding/docs/STATE_ARCHITECTURE.md +547 -0
  758. package/skills/onboarding/docs/TROUBLESHOOTING.md +363 -0
  759. package/skills/onboarding/docs/USER_JOURNEY.md +797 -0
  760. package/skills/onboarding/docs/WOW_MOMENTS.md +232 -0
  761. package/skills/onboarding/docs/agent-apple-id.md +289 -0
  762. package/skills/onboarding/docs/skill-deep-dives/1password.md +367 -0
  763. package/skills/onboarding/docs/skill-deep-dives/TEMPLATE.md +197 -0
  764. package/skills/onboarding/docs/skill-deep-dives/aix.md +498 -0
  765. package/skills/onboarding/docs/skill-deep-dives/bird.md +357 -0
  766. package/skills/onboarding/docs/skill-deep-dives/brave-search.md +601 -0
  767. package/skills/onboarding/docs/skill-deep-dives/comms.md +607 -0
  768. package/skills/onboarding/docs/skill-deep-dives/computer-use.md +599 -0
  769. package/skills/onboarding/docs/skill-deep-dives/cron-and-heartbeat.md +576 -0
  770. package/skills/onboarding/docs/skill-deep-dives/eve.md +711 -0
  771. package/skills/onboarding/docs/skill-deep-dives/github.md +333 -0
  772. package/skills/onboarding/docs/skill-deep-dives/gog.md +640 -0
  773. package/skills/onboarding/docs/skill-deep-dives/homebrew-prereqs.md +785 -0
  774. package/skills/onboarding/docs/skill-deep-dives/nexus-cloud.md +689 -0
  775. package/skills/onboarding/docs/skill-deep-dives/qmd.md +742 -0
  776. package/skills/onboarding/docs/skill-deep-dives/telegram.md +379 -0
  777. package/skills/onboarding/docs/skill-deep-dives/wacli.md +399 -0
  778. package/skills/onboarding/docs/skill-deep-dives/weather.md +513 -0
  779. package/skills/onboarding/scripts/ralph/prd.json +215 -0
  780. package/skills/onboarding/scripts/ralph/progress.txt +99 -0
  781. package/skills/onboarding/scripts/ralph/prompt.md +87 -0
  782. package/skills/onboarding/scripts/ralph/ralph.log +84 -0
  783. package/skills/onboarding/scripts/ralph/ralph.sh +45 -0
  784. package/skills/onboarding/scripts/setup-cursor-skills.sh +40 -0
  785. package/skills/openai-image-gen/SKILL.md +31 -0
  786. package/skills/openai-image-gen/scripts/gen.py +173 -0
  787. package/skills/openai-whisper/SKILL.md +19 -0
  788. package/skills/openai-whisper-api/SKILL.md +43 -0
  789. package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
  790. package/skills/openhue/SKILL.md +30 -0
  791. package/skills/oracle/SKILL.md +105 -0
  792. package/skills/ordercli/SKILL.md +47 -0
  793. package/skills/peekaboo/SKILL.md +153 -0
  794. package/skills/qmd/SKILL.md +32 -0
  795. package/skills/qmd/docs/mcp.md +30 -0
  796. package/skills/qmd/docs/ollama.md +42 -0
  797. package/skills/qmd/docs/setup.md +44 -0
  798. package/skills/sag/SKILL.md +62 -0
  799. package/skills/skill-cli-template/SKILL.md +109 -0
  800. package/skills/skill-creator/scripts/__pycache__/quick_validate.cpython-311.pyc +0 -0
  801. package/skills/slack/SKILL.md +144 -0
  802. package/skills/songsee/SKILL.md +29 -0
  803. package/skills/sonoscli/SKILL.md +26 -0
  804. package/skills/spotify-player/SKILL.md +34 -0
  805. package/skills/summarize/SKILL.md +49 -0
  806. package/skills/telegram/SKILL.md +20 -0
  807. package/skills/telegram/docs/pairing.md +30 -0
  808. package/skills/telegram/docs/setup.md +41 -0
  809. package/skills/telegram/docs/webhook.md +17 -0
  810. package/skills/things-mac/SKILL.md +61 -0
  811. package/skills/tmux/SKILL.md +121 -0
  812. package/skills/tmux/scripts/find-sessions.sh +112 -0
  813. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  814. package/skills/trello/SKILL.md +84 -0
  815. package/skills/upstream-sync/SKILL.md +151 -0
  816. package/skills/upstream-sync/scripts/auto-port.sh +227 -0
  817. package/skills/upstream-sync/scripts/check-all.sh +88 -0
  818. package/skills/upstream-sync/scripts/check-nexus.sh +146 -0
  819. package/skills/upstream-sync/scripts/check-pi-ai.sh +129 -0
  820. package/skills/video-frames/SKILL.md +29 -0
  821. package/skills/video-frames/scripts/frame.sh +81 -0
  822. package/skills/wacli/SKILL.md +48 -0
  823. package/skills/wacli/docs/auth.md +21 -0
  824. package/skills/wacli/docs/backup.md +9 -0
  825. package/skills/wacli/docs/troubleshooting.md +21 -0
  826. package/skills/weather/SKILL.md +53 -0
  827. package/skills/weather/docs/usage.md +40 -0
@@ -0,0 +1,1666 @@
1
+ ---
2
+ summary: "All configuration options for ~/nexus/state/nexus.json with examples"
3
+ read_when:
4
+ - Adding or modifying config fields
5
+ ---
6
+ # Configuration 🔧
7
+
8
+ NEXUS reads an optional **JSON5** config from `~/nexus/state/nexus.json` (comments + trailing commas allowed).
9
+
10
+ If the file is missing, NEXUS uses safe-ish defaults (embedded Pi agent + per-sender sessions + workspace `~/nexus`). You usually only need a config to:
11
+ - restrict who can trigger the bot (`whatsapp.allowFrom`, `telegram.allowFrom`, etc.)
12
+ - control group allowlists + mention behavior (`whatsapp.groups`, `telegram.groups`, `discord.guilds`, `routing.groupChat`)
13
+ - customize message prefixes (`messages`)
14
+ - set the agent's workspace (`agent.workspace`)
15
+ - tune the embedded agent (`agent`) and session behavior (`session`)
16
+ - set the agent's identity (`identity`)
17
+
18
+ ## Schema + UI hints
19
+
20
+ The Gateway exposes a JSON Schema representation of the config via `config.schema` for UI editors.
21
+ The Control UI renders a form from this schema, with a **Raw JSON** editor as an escape hatch.
22
+
23
+ Hints (labels, grouping, sensitive fields) ship alongside the schema so clients can render
24
+ better forms without hard-coding config knowledge.
25
+
26
+ ## Minimal config (recommended starting point)
27
+
28
+ ```json5
29
+ {
30
+ agent: { workspace: "~/nexus" },
31
+ whatsapp: { allowFrom: ["+15555550123"] }
32
+ }
33
+ ```
34
+
35
+ Build the default image once with:
36
+ ```bash
37
+ scripts/sandbox-setup.sh
38
+ ```
39
+
40
+ ## Self-chat mode (recommended for group control)
41
+
42
+ To prevent the bot from responding to WhatsApp @-mentions in groups (only respond to specific text triggers):
43
+
44
+ ```json5
45
+ {
46
+ agent: { workspace: "~/nexus" },
47
+ whatsapp: {
48
+ // Allowlist is DMs only; including your own number enables self-chat mode.
49
+ allowFrom: ["+15555550123"],
50
+ groups: { "*": { requireMention: true } }
51
+ },
52
+ routing: {
53
+ groupChat: {
54
+ mentionPatterns: ["@nexus", "reisponde"]
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ ## Config Includes (`$include`)
61
+
62
+ Split your config into multiple files using the `$include` directive. This is useful for:
63
+ - Organizing large configs (e.g., per-client agent definitions)
64
+ - Sharing common settings across environments
65
+ - Keeping sensitive configs separate
66
+
67
+ ### Basic usage
68
+
69
+ ```json5
70
+ // ~/nexus/state/nexus.json
71
+ {
72
+ gateway: { port: 18789 },
73
+
74
+ // Include a single file (replaces the key's value)
75
+ agent: { "$include": "./agent.json5" },
76
+
77
+ // Include multiple files (deep-merged in order)
78
+ routing: {
79
+ "$include": [
80
+ "./routing/base.json5",
81
+ "./routing/clients.json5"
82
+ ]
83
+ }
84
+ }
85
+ ```
86
+
87
+ ```json5
88
+ // ~/nexus/state/agent.json5
89
+ {
90
+ workspace: "~/nexus"
91
+ }
92
+ ```
93
+
94
+ ### Merge behavior
95
+
96
+ - **Single file**: Replaces the object containing `$include`
97
+ - **Array of files**: Deep-merges files in order (later files override earlier ones)
98
+ - **With sibling keys**: Sibling keys are merged after includes (override included values)
99
+ - **Sibling keys + arrays/primitives**: Not supported (included content must be an object)
100
+
101
+ ```json5
102
+ // Sibling keys override included values
103
+ {
104
+ "$include": "./base.json5", // { a: 1, b: 2 }
105
+ b: 99 // Result: { a: 1, b: 99 }
106
+ }
107
+ ```
108
+
109
+ ### Nested includes
110
+
111
+ Included files can themselves contain `$include` directives (up to 10 levels deep):
112
+
113
+ ```json5
114
+ // routing/clients.json5
115
+ {
116
+ routing: { "$include": "./clients/routing.json5" }
117
+ }
118
+ ```
119
+
120
+ ### Path resolution
121
+
122
+ - **Relative paths**: Resolved relative to the including file
123
+ - **Absolute paths**: Used as-is
124
+ - **Parent directories**: `../` references work as expected
125
+
126
+ ```json5
127
+ { "$include": "./sub/config.json5" } // relative
128
+ { "$include": "/etc/nexus/base.json5" } // absolute
129
+ { "$include": "../shared/common.json5" } // parent dir
130
+ ```
131
+
132
+ ### Error handling
133
+
134
+ - **Missing file**: Clear error with resolved path
135
+ - **Parse error**: Shows which included file failed
136
+ - **Circular includes**: Detected and reported with include chain
137
+
138
+ ### Example: Multi-client setup
139
+
140
+ ```json5
141
+ // ~/nexus/state/nexus.json
142
+ {
143
+ gateway: { port: 18789, auth: { token: "secret" } },
144
+
145
+ // Common agent defaults
146
+ agent: { "$include": "./agent.json5" },
147
+
148
+ // Merge routing configs
149
+ routing: { "$include": [
150
+ "./clients/mueller/routing.json5",
151
+ "./clients/schmidt/routing.json5"
152
+ ]},
153
+
154
+ whatsapp: { dmPolicy: "pairing", allowFrom: ["+15555550123"] }
155
+ }
156
+ ```
157
+
158
+ ```json5
159
+ // ~/nexus/state/clients/mueller/routing.json5
160
+ {
161
+ groupChat: {
162
+ mentionPatterns: ["@mueller"]
163
+ }
164
+ }
165
+ ```
166
+
167
+ ## Common options
168
+
169
+ ### Env vars + `.env`
170
+
171
+ NEXUS reads env vars from the parent process (shell, launchd/systemd, CI, etc.).
172
+
173
+ Additionally, it loads:
174
+ - `.env` from the current working directory (if present)
175
+ - a global fallback `.env` from `~/nexus/state/.env` (aka `$NEXUS_STATE_DIR/.env`)
176
+
177
+ Neither `.env` file overrides existing env vars.
178
+
179
+ ### `env.shellEnv` (optional)
180
+
181
+ Opt-in convenience: if enabled and none of the expected keys are set yet, NEXUS runs your login shell and imports only the missing expected keys (never overrides).
182
+ This effectively sources your shell profile.
183
+
184
+ ```json5
185
+ {
186
+ env: {
187
+ shellEnv: {
188
+ enabled: true,
189
+ timeoutMs: 15000
190
+ }
191
+ }
192
+ }
193
+ ```
194
+
195
+ Env var equivalent:
196
+ - `NEXUS_LOAD_SHELL_ENV=1`
197
+ - `NEXUS_SHELL_ENV_TIMEOUT_MS=15000`
198
+
199
+ ### Auth storage (OAuth + API keys)
200
+
201
+ Nexus stores **per-agent** auth profiles (OAuth + API keys) in:
202
+ - `<agentDir>/auth-profiles.json` (default: `~/nexus/state/agents/<agentId>/agent/auth-profiles.json`)
203
+
204
+ Legacy OAuth imports:
205
+ - `~/nexus/state/credentials/oauth.json` (or `$NEXUS_STATE_DIR/credentials/oauth.json`)
206
+
207
+ The embedded Pi agent maintains a runtime cache at:
208
+ - `<agentDir>/auth.json` (managed automatically; don’t edit manually)
209
+
210
+ Legacy agent dir (pre multi-agent):
211
+ - `~/nexus/state/agent/*` (migrated by `nexus doctor` into `~/nexus/state/agents/<defaultAgentId>/agent/*`)
212
+
213
+ Overrides:
214
+ - OAuth dir (legacy import only): `NEXUS_OAUTH_DIR`
215
+ - Agent dir (legacy/default agent only): `NEXUS_AGENT_DIR` (preferred), `PI_CODING_AGENT_DIR` (legacy)
216
+
217
+ On first use, Nexus imports `oauth.json` entries into `auth-profiles.json`.
218
+
219
+ ### `auth`
220
+
221
+ Optional metadata for auth profiles. This does **not** store secrets; it maps
222
+ profile IDs to a provider + mode (and optional email) and defines the provider
223
+ rotation order used for failover.
224
+
225
+ ```json5
226
+ {
227
+ auth: {
228
+ profiles: {
229
+ "anthropic:default": { provider: "anthropic", mode: "oauth", email: "me@example.com" },
230
+ "anthropic:work": { provider: "anthropic", mode: "api_key" }
231
+ },
232
+ order: {
233
+ anthropic: ["anthropic:default", "anthropic:work"]
234
+ }
235
+ }
236
+ }
237
+ ```
238
+
239
+ ### `identity`
240
+
241
+ Optional agent identity used for defaults and UX. This is written by the macOS onboarding assistant.
242
+
243
+ If set, NEXUS derives defaults (only when you haven’t set them explicitly):
244
+ - `messages.ackReaction` from `identity.emoji` (falls back to 👀)
245
+ - `routing.groupChat.mentionPatterns` from `identity.name` (so “@Samantha” works in groups across Telegram/Slack/Discord/iMessage/WhatsApp)
246
+
247
+ ```json5
248
+ {
249
+ identity: { name: "Samantha", theme: "helpful sloth", emoji: "🦥" }
250
+ }
251
+ ```
252
+
253
+ ### `wizard`
254
+
255
+ Metadata written by CLI wizards (`onboard`, `configure`, `doctor`, `update`).
256
+
257
+ ```json5
258
+ {
259
+ wizard: {
260
+ lastRunAt: "2026-01-01T00:00:00.000Z",
261
+ lastRunVersion: "2026.1.4",
262
+ lastRunCommit: "abc1234",
263
+ lastRunCommand: "configure",
264
+ lastRunMode: "local"
265
+ }
266
+ }
267
+ ```
268
+
269
+ ### `logging`
270
+
271
+ - Default log file: `~/nexus/state/logs/nexus-YYYY-MM-DD.log`
272
+ - If you want a stable path, set `logging.file` to `~/nexus/state/logs/nexus.log`.
273
+ - Console output can be tuned separately via:
274
+ - `logging.consoleLevel` (defaults to `info`, bumps to `debug` when `--verbose`)
275
+ - `logging.consoleStyle` (`pretty` | `compact` | `json`)
276
+ - Tool summaries can be redacted to avoid leaking secrets:
277
+ - `logging.redactSensitive` (`off` | `tools`, default: `tools`)
278
+ - `logging.redactPatterns` (array of regex strings; overrides defaults)
279
+
280
+ ```json5
281
+ {
282
+ logging: {
283
+ level: "info",
284
+ file: "~/nexus/state/logs/nexus.log",
285
+ consoleLevel: "info",
286
+ consoleStyle: "pretty",
287
+ redactSensitive: "tools",
288
+ redactPatterns: [
289
+ // Example: override defaults with your own rules.
290
+ "\\bTOKEN\\b\\s*[=:]\\s*([\"']?)([^\\s\"']+)\\1",
291
+ "/\\bsk-[A-Za-z0-9_-]{8,}\\b/gi"
292
+ ]
293
+ }
294
+ }
295
+ ```
296
+
297
+ ### `whatsapp.dmPolicy`
298
+
299
+ Controls how WhatsApp direct chats (DMs) are handled:
300
+ - `"pairing"` (default): unknown senders get a pairing code; owner must approve
301
+ - `"allowlist"`: only allow senders in `whatsapp.allowFrom` (or paired allow store)
302
+ - `"open"`: allow all inbound DMs (**requires** `whatsapp.allowFrom` to include `"*"`)
303
+ - `"disabled"`: ignore all inbound DMs
304
+
305
+ Pairing approvals:
306
+ - `nexus pairing list --provider whatsapp`
307
+ - `nexus pairing approve --provider whatsapp <code>`
308
+
309
+ ### `whatsapp.allowFrom`
310
+
311
+ Allowlist of E.164 phone numbers that may trigger WhatsApp auto-replies (**DMs only**).
312
+ If empty and `whatsapp.dmPolicy="pairing"`, unknown senders will receive a pairing code.
313
+ For groups, use `whatsapp.groupPolicy` + `whatsapp.groupAllowFrom`.
314
+
315
+ ```json5
316
+ {
317
+ whatsapp: {
318
+ dmPolicy: "pairing", // pairing | allowlist | open | disabled
319
+ allowFrom: ["+15555550123", "+447700900123"],
320
+ textChunkLimit: 4000 // optional outbound chunk size (chars)
321
+ }
322
+ }
323
+ ```
324
+
325
+ ### `whatsapp.accounts` (multi-account)
326
+
327
+ Run multiple WhatsApp accounts in one gateway:
328
+
329
+ ```json5
330
+ {
331
+ whatsapp: {
332
+ accounts: {
333
+ default: {}, // optional; keeps the default id stable
334
+ personal: {},
335
+ biz: {
336
+ // Optional override. Default: ~/nexus/state/credentials/whatsapp/biz
337
+ // authDir: "~/nexus/state/credentials/whatsapp/biz",
338
+ }
339
+ }
340
+ }
341
+ }
342
+ ```
343
+
344
+ Notes:
345
+ - Outbound commands default to account `default` if present; otherwise the first configured account id (sorted).
346
+ - The legacy single-account Baileys auth dir is migrated by `nexus doctor` into `whatsapp/default`.
347
+
348
+ ### `routing.groupChat`
349
+
350
+ Group messages default to **require mention** (either metadata mention or regex patterns). Applies to WhatsApp, Telegram, Discord, and iMessage group chats.
351
+
352
+ **Mention types:**
353
+ - **Metadata mentions**: Native platform @-mentions (e.g., WhatsApp tap-to-mention). Ignored in WhatsApp self-chat mode (see `whatsapp.allowFrom`).
354
+ - **Text patterns**: Regex patterns defined in `mentionPatterns`. Always checked regardless of self-chat mode.
355
+ - Mention gating is enforced only when mention detection is possible (native mentions or at least one `mentionPattern`).
356
+
357
+ ```json5
358
+ {
359
+ routing: {
360
+ groupChat: {
361
+ mentionPatterns: ["@nexus", "nexus", "nexus"],
362
+ historyLimit: 50
363
+ }
364
+ }
365
+ }
366
+ ```
367
+
368
+ Mention gating defaults live per provider (`whatsapp.groups`, `telegram.groups`, `imessage.groups`, `discord.guilds`). When `*.groups` is set, it also acts as a group allowlist; include `"*"` to allow all groups.
369
+
370
+ To respond **only** to specific text triggers (ignoring native @-mentions):
371
+ ```json5
372
+ {
373
+ whatsapp: {
374
+ // Include your own number to enable self-chat mode (ignore native @-mentions).
375
+ allowFrom: ["+15555550123"],
376
+ groups: { "*": { requireMention: true } }
377
+ },
378
+ routing: {
379
+ groupChat: {
380
+ // Only these text patterns will trigger responses
381
+ mentionPatterns: ["reisponde", "@nexus"]
382
+ }
383
+ }
384
+ }
385
+ ```
386
+
387
+ ### Group policy (per provider)
388
+
389
+ Use `*.groupPolicy` to control whether group/room messages are accepted at all:
390
+
391
+ ```json5
392
+ {
393
+ whatsapp: {
394
+ groupPolicy: "allowlist",
395
+ groupAllowFrom: ["+15551234567"]
396
+ },
397
+ telegram: {
398
+ groupPolicy: "allowlist",
399
+ groupAllowFrom: ["tg:123456789", "@alice"]
400
+ },
401
+ signal: {
402
+ groupPolicy: "allowlist",
403
+ groupAllowFrom: ["+15551234567"]
404
+ },
405
+ imessage: {
406
+ groupPolicy: "allowlist",
407
+ groupAllowFrom: ["chat_id:123"]
408
+ },
409
+ discord: {
410
+ groupPolicy: "allowlist",
411
+ guilds: {
412
+ "GUILD_ID": {
413
+ channels: { help: { allow: true } }
414
+ }
415
+ }
416
+ },
417
+ slack: {
418
+ groupPolicy: "allowlist",
419
+ channels: { "#general": { allow: true } }
420
+ }
421
+ }
422
+ ```
423
+
424
+ Notes:
425
+ - `"open"` (default): groups bypass allowlists; mention-gating still applies.
426
+ - `"disabled"`: block all group/room messages.
427
+ - `"allowlist"`: only allow groups/rooms that match the configured allowlist.
428
+ - WhatsApp/Telegram/Signal/iMessage use `groupAllowFrom` (fallback: explicit `allowFrom`).
429
+ - Discord/Slack use channel allowlists (`discord.guilds.*.channels`, `slack.channels`).
430
+ - Group DMs (Discord/Slack) are still controlled by `dm.groupEnabled` + `dm.groupChannels`.
431
+
432
+ ### Multi-agent routing (`routing.agents` + `routing.bindings`)
433
+
434
+ Run multiple isolated agents (separate workspace, `agentDir`, sessions) inside one Gateway. Inbound messages are routed to an agent via bindings.
435
+
436
+ - `routing.defaultAgentId`: fallback when no binding matches (default: `main`).
437
+ - `routing.agents.<agentId>`: per-agent overrides.
438
+ - `workspace`: default `~/nexus-<agentId>` (for `main`, falls back to legacy `agent.workspace`).
439
+ - `agentDir`: default `~/nexus/state/agents/<agentId>/agent`.
440
+ - `routing.bindings[]`: routes inbound messages to an `agentId`.
441
+ - `match.provider` (required)
442
+ - `match.accountId` (optional; `*` = any account; omitted = default account)
443
+ - `match.peer` (optional; `{ kind: dm|group|channel, id }`)
444
+ - `match.guildId` / `match.teamId` (optional; provider-specific)
445
+
446
+ Deterministic match order:
447
+ 1) `match.peer`
448
+ 2) `match.guildId`
449
+ 3) `match.teamId`
450
+ 4) `match.accountId` (exact, no peer/guild/team)
451
+ 5) `match.accountId: "*"` (provider-wide, no peer/guild/team)
452
+ 6) `routing.defaultAgentId`
453
+
454
+ Within each match tier, the first matching entry in `routing.bindings` wins.
455
+
456
+ Example: two WhatsApp accounts → two agents:
457
+
458
+ ```json5
459
+ {
460
+ routing: {
461
+ defaultAgentId: "home",
462
+ agents: {
463
+ home: { workspace: "~/nexus-home" },
464
+ work: { workspace: "~/nexus-work" },
465
+ },
466
+ bindings: [
467
+ { agentId: "home", match: { provider: "whatsapp", accountId: "personal" } },
468
+ { agentId: "work", match: { provider: "whatsapp", accountId: "biz" } },
469
+ ],
470
+ },
471
+ whatsapp: {
472
+ accounts: {
473
+ personal: {},
474
+ biz: {},
475
+ }
476
+ }
477
+ }
478
+ ```
479
+
480
+ ### `routing.agentToAgent` (optional)
481
+
482
+ Agent-to-agent messaging is opt-in:
483
+
484
+ ```json5
485
+ {
486
+ routing: {
487
+ agentToAgent: {
488
+ enabled: false,
489
+ allow: ["home", "work"]
490
+ }
491
+ }
492
+ }
493
+ ```
494
+
495
+ ### `routing.queue`
496
+
497
+ Controls how inbound messages behave when an agent run is already active.
498
+
499
+ ```json5
500
+ {
501
+ routing: {
502
+ queue: {
503
+ mode: "collect", // steer | followup | collect | steer-backlog (steer+backlog ok) | interrupt (queue=steer legacy)
504
+ debounceMs: 1000,
505
+ cap: 20,
506
+ drop: "summarize", // old | new | summarize
507
+ byProvider: {
508
+ whatsapp: "collect",
509
+ telegram: "collect",
510
+ discord: "collect",
511
+ imessage: "collect",
512
+ webchat: "collect"
513
+ }
514
+ }
515
+ }
516
+ }
517
+ ```
518
+
519
+ ### `web` (WhatsApp web provider)
520
+
521
+ WhatsApp runs through the gateway’s web provider. It starts automatically when a linked session exists.
522
+ Set `web.enabled: false` to keep it off by default.
523
+
524
+ ```json5
525
+ {
526
+ web: {
527
+ enabled: true,
528
+ heartbeatSeconds: 60,
529
+ reconnect: {
530
+ initialMs: 2000,
531
+ maxMs: 120000,
532
+ factor: 1.4,
533
+ jitter: 0.2,
534
+ maxAttempts: 0
535
+ }
536
+ }
537
+ }
538
+ ```
539
+
540
+ ### `telegram` (bot transport)
541
+
542
+ Nexus starts Telegram only when a `telegram` config section exists. The bot token is resolved from `TELEGRAM_BOT_TOKEN` or `telegram.botToken`.
543
+ Set `telegram.enabled: false` to disable automatic startup.
544
+
545
+ ```json5
546
+ {
547
+ telegram: {
548
+ enabled: true,
549
+ botToken: "your-bot-token",
550
+ dmPolicy: "pairing", // pairing | allowlist | open | disabled
551
+ allowFrom: ["tg:123456789"], // optional; "open" requires ["*"]
552
+ groups: { "*": { requireMention: true } },
553
+ mediaMaxMb: 5,
554
+ proxy: "socks5://localhost:9050",
555
+ webhookUrl: "https://example.com/telegram-webhook",
556
+ webhookSecret: "secret",
557
+ webhookPath: "/telegram-webhook"
558
+ }
559
+ }
560
+ ```
561
+
562
+ ### `discord` (bot transport)
563
+
564
+ Configure the Discord bot by setting the bot token and optional gating:
565
+
566
+ ```json5
567
+ {
568
+ discord: {
569
+ enabled: true,
570
+ token: "your-bot-token",
571
+ mediaMaxMb: 8, // clamp inbound media size
572
+ actions: { // tool action gates (false disables)
573
+ reactions: true,
574
+ stickers: true,
575
+ polls: true,
576
+ permissions: true,
577
+ messages: true,
578
+ threads: true,
579
+ pins: true,
580
+ search: true,
581
+ memberInfo: true,
582
+ roleInfo: true,
583
+ roles: false,
584
+ channelInfo: true,
585
+ channels: false,
586
+ voiceStatus: true,
587
+ events: true,
588
+ moderation: false
589
+ },
590
+ replyToMode: "off", // off | first | all
591
+ slashCommand: { // user-installed app slash commands
592
+ enabled: true,
593
+ name: "nexus",
594
+ sessionPrefix: "discord:slash",
595
+ ephemeral: true
596
+ },
597
+ dm: {
598
+ enabled: true, // disable all DMs when false
599
+ policy: "pairing", // pairing | allowlist | open | disabled
600
+ allowFrom: ["1234567890", "steipete"], // optional DM allowlist ("open" requires ["*"])
601
+ groupEnabled: false, // enable group DMs
602
+ groupChannels: ["nexus-dm"] // optional group DM allowlist
603
+ },
604
+ guilds: {
605
+ "123456789012345678": { // guild id (preferred) or slug
606
+ slug: "friends-of-nexus",
607
+ requireMention: false, // per-guild default
608
+ reactionNotifications: "own", // off | own | all | allowlist
609
+ users: ["987654321098765432"], // optional per-guild user allowlist
610
+ channels: {
611
+ general: { allow: true },
612
+ help: { allow: true, requireMention: true }
613
+ }
614
+ }
615
+ },
616
+ historyLimit: 20 // include last N guild messages as context
617
+ }
618
+ }
619
+ ```
620
+
621
+ Nexus starts Discord only when a `discord` config section exists. The token is resolved from `DISCORD_BOT_TOKEN` or `discord.token` (unless `discord.enabled` is `false`). Use `user:<id>` (DM) or `channel:<id>` (guild channel) when specifying delivery targets for cron/CLI commands.
622
+ Guild slugs are lowercase with spaces replaced by `-`; channel keys use the slugged channel name (no leading `#`). Prefer guild ids as keys to avoid rename ambiguity.
623
+ Reaction notification modes:
624
+ - `off`: no reaction events.
625
+ - `own`: reactions on the bot's own messages (default).
626
+ - `all`: all reactions on all messages.
627
+ - `allowlist`: reactions from `guilds.<id>.users` on all messages (empty list disables).
628
+
629
+ ### `slack` (socket mode)
630
+
631
+ Slack runs in Socket Mode and requires both a bot token and app token:
632
+
633
+ ```json5
634
+ {
635
+ slack: {
636
+ enabled: true,
637
+ botToken: "xoxb-...",
638
+ appToken: "xapp-...",
639
+ dm: {
640
+ enabled: true,
641
+ policy: "pairing", // pairing | allowlist | open | disabled
642
+ allowFrom: ["U123", "U456", "*"], // optional; "open" requires ["*"]
643
+ groupEnabled: false,
644
+ groupChannels: ["G123"]
645
+ },
646
+ channels: {
647
+ C123: { allow: true, requireMention: true },
648
+ "#general": { allow: true, requireMention: false }
649
+ },
650
+ reactionNotifications: "own", // off | own | all | allowlist
651
+ reactionAllowlist: ["U123"],
652
+ actions: {
653
+ reactions: true,
654
+ messages: true,
655
+ pins: true,
656
+ memberInfo: true,
657
+ emojiList: true
658
+ },
659
+ slashCommand: {
660
+ enabled: true,
661
+ name: "nexus",
662
+ sessionPrefix: "slack:slash",
663
+ ephemeral: true
664
+ },
665
+ textChunkLimit: 4000,
666
+ mediaMaxMb: 20
667
+ }
668
+ }
669
+ ```
670
+
671
+ Nexus starts Slack when the provider is enabled and both tokens are set (via config or `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`). Use `user:<id>` (DM) or `channel:<id>` when specifying delivery targets for cron/CLI commands.
672
+
673
+ Reaction notification modes:
674
+ - `off`: no reaction events.
675
+ - `own`: reactions on the bot's own messages (default).
676
+ - `all`: all reactions on all messages.
677
+ - `allowlist`: reactions from `slack.reactionAllowlist` on all messages (empty list disables).
678
+
679
+ Slack action groups (gate `slack` tool actions):
680
+ | Action group | Default | Notes |
681
+ | --- | --- | --- |
682
+ | reactions | enabled | React + list reactions |
683
+ | messages | enabled | Read/send/edit/delete |
684
+ | pins | enabled | Pin/unpin/list |
685
+ | memberInfo | enabled | Member info |
686
+ | emojiList | enabled | Custom emoji list |
687
+ ### `imessage` (imsg CLI)
688
+
689
+ Nexus spawns `imsg rpc` (JSON-RPC over stdio). No daemon or port required.
690
+
691
+ ```json5
692
+ {
693
+ imessage: {
694
+ enabled: true,
695
+ cliPath: "imsg",
696
+ dbPath: "~/Library/Messages/chat.db",
697
+ dmPolicy: "pairing", // pairing | allowlist | open | disabled
698
+ allowFrom: ["+15555550123", "user@example.com", "chat_id:123"],
699
+ includeAttachments: false,
700
+ mediaMaxMb: 16,
701
+ service: "auto",
702
+ region: "US"
703
+ }
704
+ }
705
+ ```
706
+
707
+ Notes:
708
+ - Requires Full Disk Access to the Messages DB.
709
+ - The first send will prompt for Messages automation permission.
710
+ - Prefer `chat_id:<id>` targets. Use `imsg chats --limit 20` to list chats.
711
+
712
+ ### `agent.workspace`
713
+
714
+ Sets the **single global workspace directory** used by the agent for file operations.
715
+
716
+ Default: `~/nexus`.
717
+
718
+ ```json5
719
+ {
720
+ agent: { workspace: "~/nexus" }
721
+ }
722
+ ```
723
+
724
+ If `agent.sandbox` is enabled, non-main sessions can override this with their
725
+ own per-session workspaces under `agent.sandbox.workspaceRoot`.
726
+
727
+ ### `agent.skipBootstrap`
728
+
729
+ Disables automatic creation of the workspace bootstrap files (`AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `PROFILE.md`, and `BOOTSTRAP.md`).
730
+
731
+ Use this for pre-seeded deployments where your workspace files come from a repo.
732
+
733
+ ```json5
734
+ {
735
+ agent: { skipBootstrap: true }
736
+ }
737
+ ```
738
+
739
+ ### `agent.userTimezone`
740
+
741
+ Sets the user’s timezone for **system prompt context** (not for timestamps in
742
+ message envelopes). If unset, Nexus uses the host timezone at runtime.
743
+
744
+ ```json5
745
+ {
746
+ agent: { userTimezone: "America/Chicago" }
747
+ }
748
+ ```
749
+
750
+ ### `messages`
751
+
752
+ Controls inbound/outbound prefixes and optional ack reactions.
753
+
754
+ ```json5
755
+ {
756
+ messages: {
757
+ messagePrefix: "[nexus]",
758
+ responsePrefix: "🦞",
759
+ ackReaction: "👀",
760
+ ackReactionScope: "group-mentions"
761
+ }
762
+ }
763
+ ```
764
+
765
+ `responsePrefix` is applied to **all outbound replies** (tool summaries, block
766
+ streaming, final replies) across providers unless already present.
767
+
768
+ `ackReaction` sends a best-effort emoji reaction to acknowledge inbound messages
769
+ on providers that support reactions (Slack/Discord/Telegram). Defaults to the
770
+ configured `identity.emoji` when set, otherwise `"👀"`. Set it to `""` to disable.
771
+
772
+ `ackReactionScope` controls when reactions fire:
773
+ - `group-mentions` (default): only when a group/room requires mentions **and** the bot was mentioned
774
+ - `group-all`: all group/room messages
775
+ - `direct`: direct messages only
776
+ - `all`: all messages
777
+
778
+ ### `talk`
779
+
780
+ Defaults for Talk mode (macOS/iOS/Android). Voice IDs fall back to `ELEVENLABS_VOICE_ID` or `SAG_VOICE_ID` when unset.
781
+ `apiKey` falls back to `ELEVENLABS_API_KEY` (or the gateway’s shell profile) when unset.
782
+ `voiceAliases` lets Talk directives use friendly names (e.g. `"voice":"Nexus"`).
783
+
784
+ ```json5
785
+ {
786
+ talk: {
787
+ voiceId: "elevenlabs_voice_id",
788
+ voiceAliases: {
789
+ Nexus: "EXAVITQu4vr4xnSDxMaL",
790
+ Roger: "CwhRBWXzGAHq8TQ4Fs17"
791
+ },
792
+ modelId: "eleven_v3",
793
+ outputFormat: "mp3_44100_128",
794
+ apiKey: "elevenlabs_api_key",
795
+ interruptOnSpeech: true
796
+ }
797
+ }
798
+ ```
799
+
800
+ ### `agent`
801
+
802
+ Controls the embedded agent runtime (model/thinking/verbose/timeouts).
803
+ `agent.models` defines the configured model catalog (and acts as the allowlist for `/model`).
804
+ `agent.model.primary` sets the default model; `agent.model.fallbacks` are global failovers.
805
+ `agent.imageModel` is optional and is **only used if the primary model lacks image input**.
806
+
807
+ Nexus also ships a few built-in alias shorthands. Defaults only apply when the model
808
+ is already present in `agent.models`:
809
+
810
+ - `opus` -> `anthropic/claude-opus-4-5`
811
+ - `sonnet` -> `anthropic/claude-sonnet-4-5`
812
+ - `gpt` -> `openai/gpt-5.2`
813
+ - `gpt-mini` -> `openai/gpt-5-mini`
814
+ - `gemini` -> `google/gemini-3-pro-preview`
815
+ - `gemini-flash` -> `google/gemini-3-flash-preview`
816
+
817
+ If you configure the same alias name (case-insensitive) yourself, your value wins (defaults never override).
818
+
819
+ ```json5
820
+ {
821
+ agent: {
822
+ models: {
823
+ "anthropic/claude-opus-4-5": { alias: "Opus" },
824
+ "anthropic/claude-sonnet-4-1": { alias: "Sonnet" },
825
+ "openrouter/deepseek/deepseek-r1:free": {}
826
+ },
827
+ model: {
828
+ primary: "anthropic/claude-opus-4-5",
829
+ fallbacks: [
830
+ "openrouter/deepseek/deepseek-r1:free",
831
+ "openrouter/meta-llama/llama-3.3-70b-instruct:free"
832
+ ]
833
+ },
834
+ imageModel: {
835
+ primary: "openrouter/qwen/qwen-2.5-vl-72b-instruct:free",
836
+ fallbacks: [
837
+ "openrouter/google/gemini-2.0-flash-vision:free"
838
+ ]
839
+ },
840
+ thinkingDefault: "low",
841
+ verboseDefault: "off",
842
+ elevatedDefault: "on",
843
+ timeoutSeconds: 600,
844
+ mediaMaxMb: 5,
845
+ heartbeat: {
846
+ every: "30m",
847
+ target: "last"
848
+ },
849
+ maxConcurrent: 3,
850
+ bash: {
851
+ backgroundMs: 10000,
852
+ timeoutSec: 1800,
853
+ cleanupMs: 1800000
854
+ },
855
+ contextTokens: 200000
856
+ }
857
+ }
858
+ ```
859
+
860
+ Block streaming:
861
+ - `agent.blockStreamingDefault`: `"on"`/`"off"` (default on).
862
+ - `agent.blockStreamingBreak`: `"text_end"` or `"message_end"` (default: text_end).
863
+ - `agent.blockStreamingChunk`: soft chunking for streamed blocks. Defaults to
864
+ 800–1200 chars, prefers paragraph breaks (`\n\n`), then newlines, then sentences.
865
+ Example:
866
+ ```json5
867
+ {
868
+ agent: {
869
+ blockStreamingChunk: { minChars: 800, maxChars: 1200 }
870
+ }
871
+ }
872
+ ```
873
+
874
+ `agent.model.primary` should be set as `provider/model` (e.g. `anthropic/claude-opus-4-5`).
875
+ Aliases come from `agent.models.*.alias` (e.g. `Opus`).
876
+ If you omit the provider, NEXUS currently assumes `anthropic` as a temporary
877
+ deprecation fallback.
878
+ Z.AI models are available as `zai/<model>` (e.g. `zai/glm-4.7`) and require
879
+ `ZAI_API_KEY` (or legacy `Z_AI_API_KEY`) in the environment.
880
+
881
+ `agent.heartbeat` configures periodic heartbeat runs:
882
+ - `every`: duration string (`ms`, `s`, `m`, `h`); default unit minutes. Omit or set
883
+ `0m` to disable.
884
+ - `model`: optional override model for heartbeat runs (`provider/model`).
885
+ - `target`: optional delivery provider (`last`, `whatsapp`, `telegram`, `discord`, `imessage`, `none`). Default: `last`.
886
+ - `to`: optional recipient override (E.164 for WhatsApp, chat id for Telegram).
887
+ - `prompt`: optional override for the heartbeat body (default: `HEARTBEAT`).
888
+ - `ackMaxChars`: max chars allowed after `HEARTBEAT_OK` before delivery (default: 30).
889
+
890
+ `agent.bash` configures background bash defaults:
891
+ - `backgroundMs`: time before auto-background (ms, default 10000)
892
+ - `timeoutSec`: auto-kill after this runtime (seconds, default 1800)
893
+ - `cleanupMs`: how long to keep finished sessions in memory (ms, default 1800000)
894
+
895
+ `agent.tools` configures a global tool allow/deny policy (deny wins).
896
+ This is applied even when the Docker sandbox is **off**.
897
+
898
+ Example (disable browser/canvas everywhere):
899
+ ```json5
900
+ {
901
+ agent: {
902
+ tools: {
903
+ deny: ["browser", "canvas"]
904
+ }
905
+ }
906
+ }
907
+ ```
908
+
909
+ Tool groups (shorthands) work in **global**, **per-agent**, and **sandbox** tool policies:
910
+ - `group:runtime`: `exec`, `process`
911
+ - `group:fs`: `read`, `write`, `edit`, `apply_patch`
912
+ - `group:sessions`: `sessions_list`, `sessions_history`, `sessions_send`, `sessions_spawn`
913
+ - `group:memory`: `memory_search`, `memory_get`
914
+ - `group:ui`: `browser`, `canvas`
915
+ - `group:automation`: `cron`, `gateway`
916
+ - `group:messaging`: `discord`, `slack`
917
+ - `group:nodes`: `nodes`
918
+ - `group:nexus`: all built-in Nexus tools (excludes provider plugins)
919
+
920
+ `agent.elevated` controls elevated (host) exec access:
921
+ - `enabled`: allow elevated mode (default true)
922
+ - `allowFrom`: per-provider allowlists (empty = disabled)
923
+ - `whatsapp`: E.164 numbers
924
+ - `telegram`: chat ids or usernames
925
+ - `discord`: user ids or usernames (falls back to `discord.dm.allowFrom` if omitted)
926
+ - `signal`: E.164 numbers
927
+ - `imessage`: handles/chat ids
928
+ - `webchat`: session ids or usernames
929
+
930
+ Example:
931
+ ```json5
932
+ {
933
+ agent: {
934
+ elevated: {
935
+ enabled: true,
936
+ allowFrom: {
937
+ whatsapp: ["+15555550123"],
938
+ discord: ["steipete", "1234567890123"]
939
+ }
940
+ }
941
+ }
942
+ }
943
+ ```
944
+
945
+ `agent.maxConcurrent` sets the maximum number of embedded agent runs that can
946
+ execute in parallel across sessions. Each session is still serialized (one run
947
+ per session key at a time). Default: 1.
948
+
949
+ ### `agent.sandbox`
950
+
951
+ Optional per-session **Docker sandboxing** for the embedded agent. Intended for
952
+ non-main sessions so they cannot access your host system.
953
+
954
+ Defaults (if enabled):
955
+ - one container per session
956
+ - Debian bookworm-slim based image
957
+ - workspace per session under `~/nexus/state/sandboxes`
958
+ - auto-prune: idle > 24h OR age > 7d
959
+ - tools: allow only `bash`, `process`, `read`, `write`, `edit`, `sessions_list`, `sessions_history`, `sessions_send`, `sessions_spawn` (deny wins)
960
+ - optional sandboxed browser (Chromium + CDP, noVNC observer)
961
+ - hardening knobs: `network`, `user`, `pidsLimit`, `memory`, `cpus`, `ulimits`, `seccompProfile`, `apparmorProfile`
962
+
963
+ ```json5
964
+ {
965
+ agent: {
966
+ sandbox: {
967
+ mode: "non-main", // off | non-main | all
968
+ perSession: true,
969
+ workspaceRoot: "~/nexus/state/sandboxes",
970
+ docker: {
971
+ image: "nexus-sandbox:bookworm-slim",
972
+ containerPrefix: "nexus-sbx-",
973
+ workdir: "/workspace",
974
+ readOnlyRoot: true,
975
+ tmpfs: ["/tmp", "/var/tmp", "/run"],
976
+ network: "none",
977
+ user: "1000:1000",
978
+ capDrop: ["ALL"],
979
+ env: { LANG: "C.UTF-8" },
980
+ setupCommand: "apt-get update && apt-get install -y git curl jq",
981
+ pidsLimit: 256,
982
+ memory: "1g",
983
+ memorySwap: "2g",
984
+ cpus: 1,
985
+ ulimits: {
986
+ nofile: { soft: 1024, hard: 2048 },
987
+ nproc: 256
988
+ },
989
+ seccompProfile: "/path/to/seccomp.json",
990
+ apparmorProfile: "nexus-sandbox",
991
+ dns: ["1.1.1.1", "8.8.8.8"],
992
+ extraHosts: ["internal.service:10.0.0.5"]
993
+ },
994
+ browser: {
995
+ enabled: false,
996
+ image: "nexus-sandbox-browser:bookworm-slim",
997
+ containerPrefix: "nexus-sbx-browser-",
998
+ cdpPort: 9222,
999
+ vncPort: 5900,
1000
+ noVncPort: 6080,
1001
+ headless: false,
1002
+ enableNoVnc: true
1003
+ },
1004
+ tools: {
1005
+ allow: ["bash", "process", "read", "write", "edit", "sessions_list", "sessions_history", "sessions_send", "sessions_spawn"],
1006
+ deny: ["browser", "canvas", "nodes", "cron", "discord", "gateway"]
1007
+ },
1008
+ prune: {
1009
+ idleHours: 24, // 0 disables idle pruning
1010
+ maxAgeDays: 7 // 0 disables max-age pruning
1011
+ }
1012
+ }
1013
+ }
1014
+ }
1015
+ ```
1016
+
1017
+ Build the default sandbox image once with:
1018
+ ```bash
1019
+ scripts/sandbox-setup.sh
1020
+ ```
1021
+
1022
+ Note: sandbox containers default to `network: "none"`; set `agent.sandbox.docker.network`
1023
+ to `"bridge"` (or your custom network) if the agent needs outbound access.
1024
+
1025
+ Build the optional browser image with:
1026
+ ```bash
1027
+ scripts/sandbox-browser-setup.sh
1028
+ ```
1029
+
1030
+ When `agent.sandbox.browser.enabled=true`, the browser tool uses a sandboxed
1031
+ Chromium instance (CDP). If noVNC is enabled (default when headless=false),
1032
+ the noVNC URL is injected into the system prompt so the agent can reference it.
1033
+ This does not require `browser.enabled` in the main config; the sandbox control
1034
+ URL is injected per session.
1035
+
1036
+ ### `controlPlane` (agent orchestration mode)
1037
+
1038
+ Controls the agent orchestration architecture. Nexus supports two modes:
1039
+
1040
+ - **`single`** (default): Classic single-agent-per-session behavior (current NexusBot mode)
1041
+ - **`odu`**: Orchestration Domain Unit pattern with separate Interaction Agent (IA) and Execution Agents (EA)
1042
+
1043
+ The ODU mode uses a coordinator agent (IA) for user interaction and delegates concrete tasks to execution agents (EA). This enables:
1044
+ - Task parallelization (multiple EAs can work concurrently)
1045
+ - Model separation (use different models for orchestration vs execution)
1046
+ - Clear separation of concerns (IA handles routing, EA handles work)
1047
+
1048
+ ```json5
1049
+ {
1050
+ controlPlane: {
1051
+ mode: "odu",
1052
+ odu: {
1053
+ // Model for Interaction Agent (orchestration layer)
1054
+ iaModel: {
1055
+ primary: "anthropic/claude-opus-4-5",
1056
+ fallbacks: ["anthropic/claude-sonnet-4-5"]
1057
+ },
1058
+ // Model for Execution Agents (task execution layer)
1059
+ eaModel: {
1060
+ primary: "anthropic/claude-sonnet-4-5",
1061
+ fallbacks: ["anthropic/claude-opus-4-5"]
1062
+ }
1063
+ }
1064
+ }
1065
+ }
1066
+ ```
1067
+
1068
+ **Model resolution cascade:**
1069
+
1070
+ For **Interaction Agent (IA)**:
1071
+ 1. `controlPlane.odu.iaModel.primary` (if set)
1072
+ 2. `agent.model.primary` (fallback)
1073
+ 3. Built-in default (`claude-opus-4-5`)
1074
+
1075
+ For **Execution Agents (EA)**:
1076
+ 1. `controlPlane.odu.eaModel.primary` (if set)
1077
+ 2. `agent.model.primary` (fallback)
1078
+ 3. Built-in default (`claude-opus-4-5`)
1079
+
1080
+ **Why separate IA/EA models?**
1081
+
1082
+ You might use:
1083
+ - **Opus for IA + Sonnet for EA**: High-quality orchestration with cost-effective execution
1084
+ - **Opus for both**: Maximum quality throughout (higher cost)
1085
+ - **Sonnet for both**: Cost-effective for simpler workflows
1086
+
1087
+ Example: Cost-optimized ODU setup:
1088
+
1089
+ ```json5
1090
+ {
1091
+ agent: {
1092
+ model: { primary: "anthropic/claude-sonnet-4-5" } // Default fallback
1093
+ },
1094
+ controlPlane: {
1095
+ mode: "odu",
1096
+ odu: {
1097
+ iaModel: { primary: "anthropic/claude-opus-4-5" }, // Better orchestration
1098
+ eaModel: { primary: "anthropic/claude-sonnet-4-5" } // Cost-effective execution
1099
+ }
1100
+ }
1101
+ }
1102
+ ```
1103
+
1104
+ **Note:** When `controlPlane.mode` is `"single"` (default), the `odu` config is ignored.
1105
+
1106
+ ### `models` (custom providers + base URLs)
1107
+
1108
+ Nexus uses the **pi-coding-agent** model catalog. You can add custom providers
1109
+ (LiteLLM, local OpenAI-compatible servers, Anthropic proxies, etc.) by writing
1110
+ `~/nexus/state/agent/models.json` or by defining the same schema inside your
1111
+ Nexus config under `models.providers`.
1112
+
1113
+ When `models.providers` is present, Nexus writes/merges a `models.json` into
1114
+ `~/nexus/state/agent/` on startup:
1115
+ - default behavior: **merge** (keeps existing providers, overrides on name)
1116
+ - set `models.mode: "replace"` to overwrite the file contents
1117
+
1118
+ Select the model via `agent.model.primary` (provider/model).
1119
+
1120
+ ```json5
1121
+ {
1122
+ agent: {
1123
+ model: { primary: "custom-proxy/llama-3.1-8b" },
1124
+ models: {
1125
+ "custom-proxy/llama-3.1-8b": {}
1126
+ }
1127
+ },
1128
+ models: {
1129
+ mode: "merge",
1130
+ providers: {
1131
+ "custom-proxy": {
1132
+ baseUrl: "http://localhost:4000/v1",
1133
+ apiKey: "LITELLM_KEY",
1134
+ api: "openai-completions",
1135
+ models: [
1136
+ {
1137
+ id: "llama-3.1-8b",
1138
+ name: "Llama 3.1 8B",
1139
+ reasoning: false,
1140
+ input: ["text"],
1141
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1142
+ contextWindow: 128000,
1143
+ maxTokens: 32000
1144
+ }
1145
+ ]
1146
+ }
1147
+ }
1148
+ }
1149
+ }
1150
+ ```
1151
+
1152
+ ### Local models (LM Studio) — recommended setup
1153
+
1154
+ Best current local setup (what we’re running): **MiniMax M2.1** on a beefy Mac Studio
1155
+ via **LM Studio** using the **Responses API**.
1156
+
1157
+ ```json5
1158
+ {
1159
+ agent: {
1160
+ model: { primary: "lmstudio/minimax-m2.1-gs32" },
1161
+ models: {
1162
+ "anthropic/claude-opus-4-5": { alias: "Opus" },
1163
+ "lmstudio/minimax-m2.1-gs32": { alias: "Minimax" }
1164
+ }
1165
+ },
1166
+ models: {
1167
+ mode: "merge",
1168
+ providers: {
1169
+ lmstudio: {
1170
+ baseUrl: "http://127.0.0.1:1234/v1",
1171
+ apiKey: "lmstudio",
1172
+ api: "openai-responses",
1173
+ models: [
1174
+ {
1175
+ id: "minimax-m2.1-gs32",
1176
+ name: "MiniMax M2.1 GS32",
1177
+ reasoning: false,
1178
+ input: ["text"],
1179
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1180
+ contextWindow: 196608,
1181
+ maxTokens: 8192
1182
+ }
1183
+ ]
1184
+ }
1185
+ }
1186
+ }
1187
+ }
1188
+ ```
1189
+
1190
+ Notes:
1191
+ - LM Studio must have the model loaded and the local server enabled (default URL above).
1192
+ - Responses API enables clean reasoning/output separation; WhatsApp sees only final text.
1193
+ - Adjust `contextWindow`/`maxTokens` if your LM Studio context length differs.
1194
+
1195
+ Notes:
1196
+ - Supported APIs: `openai-completions`, `openai-responses`, `anthropic-messages`,
1197
+ `google-generative-ai`
1198
+ - Use `authHeader: true` + `headers` for custom auth needs.
1199
+ - Override the agent config root with `NEXUS_AGENT_DIR` (or `PI_CODING_AGENT_DIR`)
1200
+ if you want `models.json` stored elsewhere.
1201
+
1202
+ ### `session`
1203
+
1204
+ Controls session scoping, idle expiry, reset triggers, and where the session store is written.
1205
+
1206
+ ```json5
1207
+ {
1208
+ session: {
1209
+ scope: "per-sender",
1210
+ idleMinutes: 60,
1211
+ resetTriggers: ["/new", "/reset"],
1212
+ // Default is already per-agent under ~/nexus/state/agents/<agentId>/sessions/sessions.json
1213
+ // You can override with {agentId} templating:
1214
+ store: "~/nexus/state/agents/{agentId}/sessions/sessions.json",
1215
+ // Direct chats collapse to agent:<agentId>:<mainKey> (default: "main").
1216
+ mainKey: "main",
1217
+ agentToAgent: {
1218
+ // Max ping-pong reply turns between requester/target (0–5).
1219
+ maxPingPongTurns: 5
1220
+ },
1221
+ sendPolicy: {
1222
+ rules: [
1223
+ { action: "deny", match: { provider: "discord", chatType: "group" } }
1224
+ ],
1225
+ default: "allow"
1226
+ }
1227
+ }
1228
+ }
1229
+ ```
1230
+
1231
+ Fields:
1232
+ - `mainKey`: direct-chat bucket key (default: `"main"`). Useful when you want to “rename” the primary DM thread without changing `agentId`.
1233
+ - `agentToAgent.maxPingPongTurns`: max reply-back turns between requester/target (0–5, default 5).
1234
+ - `sendPolicy.default`: `allow` or `deny` fallback when no rule matches.
1235
+ - `sendPolicy.rules[]`: match by `provider`, `chatType` (`direct|group|room`), or `keyPrefix` (e.g. `cron:`). First deny wins; otherwise allow.
1236
+
1237
+ ### `skills` (skills config)
1238
+
1239
+ Controls bundled allowlist, install preferences, extra skill folders, and per-skill
1240
+ overrides. Applies to bundled baseline skills plus any loaded skill source (home/project/extraDirs).
1241
+ Precedence on name conflict is: project > home > bundled.
1242
+
1243
+ Fields:
1244
+ - `allowBundled`: optional allowlist for **bundled** skills only. If set, only those
1245
+ bundled skills are eligible (home/project/extraDirs skills unaffected).
1246
+ - `load.extraDirs`: additional skill directories to scan (lowest precedence).
1247
+ - `install.preferBrew`: prefer brew installers when available (default: true).
1248
+ - `install.nodeManager`: node installer preference (`npm` | `pnpm` | `yarn`, default: npm).
1249
+ - `entries.<skillKey>`: per-skill config overrides.
1250
+
1251
+ Per-skill fields:
1252
+ - `enabled`: set `false` to disable a skill even if it’s bundled/installed.
1253
+ - `env`: environment variables injected for the agent run (only if not already set).
1254
+ - `apiKey`: optional convenience for skills that declare a primary env var (e.g. `nano-banana-pro` → `GEMINI_API_KEY`).
1255
+
1256
+ Example:
1257
+
1258
+ ```json5
1259
+ {
1260
+ skills: {
1261
+ allowBundled: ["brave-search", "gemini"],
1262
+ load: {
1263
+ extraDirs: [
1264
+ "~/Projects/agent-scripts/skills",
1265
+ "~/Projects/oss/some-skill-pack/skills"
1266
+ ]
1267
+ },
1268
+ install: {
1269
+ preferBrew: true,
1270
+ nodeManager: "npm"
1271
+ },
1272
+ entries: {
1273
+ "nano-banana-pro": {
1274
+ apiKey: "GEMINI_KEY_HERE",
1275
+ env: {
1276
+ GEMINI_API_KEY: "GEMINI_KEY_HERE"
1277
+ }
1278
+ },
1279
+ peekaboo: { enabled: true },
1280
+ sag: { enabled: false }
1281
+ }
1282
+ }
1283
+ }
1284
+ ```
1285
+
1286
+ ### `browser` (nexus-managed Chrome)
1287
+
1288
+ Nexus can start a **dedicated, isolated** Chrome/Chromium instance for nexus and expose a small loopback control server.
1289
+ Profiles can point at a **remote** Chrome via `profiles.<name>.cdpUrl`. Remote
1290
+ profiles are attach-only (start/stop/reset are disabled).
1291
+
1292
+ `browser.cdpUrl` remains for legacy single-profile configs and as the base
1293
+ scheme/host for profiles that only set `cdpPort`.
1294
+
1295
+ Defaults:
1296
+ - enabled: `true`
1297
+ - control URL: `http://127.0.0.1:18791` (CDP uses `18792`)
1298
+ - CDP URL: `http://127.0.0.1:18792` (control URL + 1, legacy single-profile)
1299
+ - profile color: `#FF4500` (lobster-orange)
1300
+ - Note: the control server is started by the running gateway (Nexus.app menubar, or `nexus gateway`).
1301
+
1302
+ ```json5
1303
+ {
1304
+ browser: {
1305
+ enabled: true,
1306
+ controlUrl: "http://127.0.0.1:18791",
1307
+ // cdpUrl: "http://127.0.0.1:18792", // legacy single-profile override
1308
+ defaultProfile: "nexus",
1309
+ profiles: {
1310
+ nexus: { cdpPort: 18800, color: "#FF4500" },
1311
+ work: { cdpPort: 18801, color: "#0066CC" },
1312
+ remote: { cdpUrl: "http://10.0.0.42:9222", color: "#00AA00" }
1313
+ },
1314
+ color: "#FF4500",
1315
+ // Advanced:
1316
+ // headless: false,
1317
+ // noSandbox: false,
1318
+ // executablePath: "/usr/bin/chromium",
1319
+ // attachOnly: false, // set true when tunneling a remote CDP to localhost
1320
+ }
1321
+ }
1322
+ ```
1323
+
1324
+ ### `ui` (Appearance)
1325
+
1326
+ Optional accent color used by the native apps for UI chrome (e.g. Talk Mode bubble tint).
1327
+
1328
+ If unset, clients fall back to a muted light-blue.
1329
+
1330
+ ```json5
1331
+ {
1332
+ ui: {
1333
+ seamColor: "#FF4500" // hex (RRGGBB or #RRGGBB)
1334
+ }
1335
+ }
1336
+ ```
1337
+
1338
+ ### `gateway` (Gateway server mode + bind)
1339
+
1340
+ Use `gateway.mode` to explicitly declare whether this machine should run the Gateway.
1341
+
1342
+ Defaults:
1343
+ - mode: **unset** (treated as “do not auto-start”)
1344
+ - bind: `loopback`
1345
+ - port: `18789` (single port for WS + HTTP)
1346
+
1347
+ ```json5
1348
+ {
1349
+ gateway: {
1350
+ mode: "local", // or "remote"
1351
+ port: 18789, // WS + HTTP multiplex
1352
+ bind: "loopback",
1353
+ // controlUi: { enabled: true, basePath: "/nexus" }
1354
+ // auth: { mode: "token", token: "your-token" } // token is for multi-machine CLI access
1355
+ // tailscale: { mode: "off" | "serve" | "funnel" }
1356
+ }
1357
+ }
1358
+ ```
1359
+
1360
+ Control UI base path:
1361
+ - `gateway.controlUi.basePath` sets the URL prefix where the Control UI is served.
1362
+ - Examples: `"/ui"`, `"/nexus"`, `"/apps/nexus"`.
1363
+ - Default: root (`/`) (unchanged).
1364
+
1365
+ Notes:
1366
+ - `nexus gateway` refuses to start unless `gateway.mode` is set to `local` (or you pass the override flag).
1367
+ - `gateway.port` controls the single multiplexed port used for WebSocket + HTTP (control UI, hooks, A2UI).
1368
+ - Precedence: `--port` > `NEXUS_GATEWAY_PORT` > `gateway.port` > default `18789`.
1369
+
1370
+ Auth and Tailscale:
1371
+ - `gateway.auth.mode` sets the handshake requirements (`token` or `password`).
1372
+ - `gateway.auth.token` stores the shared token for token auth (used by the CLI on the same machine).
1373
+ - When `gateway.auth.mode` is set, only that method is accepted (plus optional Tailscale headers).
1374
+ - `gateway.auth.password` can be set here, or via `NEXUS_GATEWAY_PASSWORD` (recommended).
1375
+ - `gateway.auth.allowTailscale` controls whether Tailscale identity headers can satisfy auth.
1376
+ - `gateway.tailscale.mode: "serve"` uses Tailscale Serve (tailnet only, loopback bind).
1377
+ - `gateway.tailscale.mode: "funnel"` exposes the dashboard publicly; requires auth.
1378
+ - `gateway.tailscale.resetOnExit` resets Serve/Funnel config on shutdown.
1379
+
1380
+ Remote client defaults (CLI):
1381
+ - `gateway.remote.url` sets the default Gateway WebSocket URL for CLI calls when `gateway.mode = "remote"`.
1382
+ - `gateway.remote.token` supplies the token for remote calls (leave unset for no auth).
1383
+ - `gateway.remote.password` supplies the password for remote calls (leave unset for no auth).
1384
+
1385
+ macOS app behavior:
1386
+ - Nexus.app watches `~/nexus/state/nexus.json` and switches modes live when `gateway.mode` or `gateway.remote.url` changes.
1387
+ - If `gateway.mode` is unset but `gateway.remote.url` is set, the macOS app treats it as remote mode.
1388
+ - When you change connection mode in the macOS app, it writes `gateway.mode` (and `gateway.remote.url` in remote mode) back to the config file.
1389
+
1390
+ ```json5
1391
+ {
1392
+ gateway: {
1393
+ mode: "remote",
1394
+ remote: {
1395
+ url: "ws://gateway.tailnet:18789",
1396
+ token: "your-token",
1397
+ password: "your-password"
1398
+ }
1399
+ }
1400
+ }
1401
+ ```
1402
+
1403
+ ### `gateway.reload` (Config hot reload)
1404
+
1405
+ The Gateway watches `~/nexus/state/nexus.json` (or `NEXUS_CONFIG_PATH`) and applies changes automatically.
1406
+
1407
+ Modes:
1408
+ - `hybrid` (default): hot-apply safe changes; restart the Gateway for critical changes.
1409
+ - `hot`: only apply hot-safe changes; log when a restart is required.
1410
+ - `restart`: restart the Gateway on any config change.
1411
+ - `off`: disable hot reload.
1412
+
1413
+ ```json5
1414
+ {
1415
+ gateway: {
1416
+ reload: {
1417
+ mode: "hybrid",
1418
+ debounceMs: 300
1419
+ }
1420
+ }
1421
+ }
1422
+ ```
1423
+
1424
+ #### Hot reload matrix (files + impact)
1425
+
1426
+ Files watched:
1427
+ - `~/nexus/state/nexus.json` (or `NEXUS_CONFIG_PATH`)
1428
+
1429
+ Hot-applied (no full gateway restart):
1430
+ - `hooks` (webhook auth/path/mappings) + `hooks.gmail` (Gmail watcher restarted)
1431
+ - `browser` (browser control server restart)
1432
+ - `cron` (cron service restart + concurrency update)
1433
+ - `agent.heartbeat` (heartbeat runner restart)
1434
+ - `web` (WhatsApp web provider restart)
1435
+ - `telegram`, `discord`, `signal`, `imessage` (provider restarts)
1436
+ - `agent`, `models`, `routing`, `messages`, `session`, `whatsapp`, `logging`, `skills`, `ui`, `talk`, `identity`, `wizard` (dynamic reads)
1437
+
1438
+ Requires full Gateway restart:
1439
+ - `gateway` (port/bind/auth/control UI/tailscale)
1440
+ - `bridge`
1441
+ - `discovery`
1442
+ - `canvasHost`
1443
+ - Any unknown/unsupported config path (defaults to restart for safety)
1444
+
1445
+ ### Multi-instance isolation
1446
+
1447
+ To run multiple gateways on one host, isolate per-instance state + config and use unique ports:
1448
+ - `NEXUS_CONFIG_PATH` (per-instance config)
1449
+ - `NEXUS_STATE_DIR` (sessions/creds)
1450
+ - `agent.workspace` (memories)
1451
+ - `gateway.port` (unique per instance)
1452
+
1453
+ Convenience flags (CLI):
1454
+ - `nexus --dev …` → uses `~/nexus/state-dev` + shifts ports from base `19001`
1455
+ - `nexus --profile <name> …` → uses `~/nexus/state-<name>` (port via config/env/flags)
1456
+
1457
+ See [`docs/gateway.md`](https://docs.nexus.bot/gateway) for the derived port mapping (gateway/bridge/browser/canvas).
1458
+
1459
+ Example:
1460
+ ```bash
1461
+ NEXUS_CONFIG_PATH=~/nexus/state/a.json \
1462
+ NEXUS_STATE_DIR=~/nexus/state-a \
1463
+ nexus gateway --port 19001
1464
+ ```
1465
+
1466
+ ### `hooks` (Gateway webhooks)
1467
+
1468
+ Enable a simple HTTP webhook endpoint on the Gateway HTTP server.
1469
+
1470
+ Defaults:
1471
+ - enabled: `false`
1472
+ - path: `/hooks`
1473
+ - maxBodyBytes: `262144` (256 KB)
1474
+
1475
+ ```json5
1476
+ {
1477
+ hooks: {
1478
+ enabled: true,
1479
+ token: "shared-secret",
1480
+ path: "/hooks",
1481
+ presets: ["gmail"],
1482
+ transformsDir: "~/nexus/state/hooks",
1483
+ mappings: [
1484
+ {
1485
+ match: { path: "gmail" },
1486
+ action: "agent",
1487
+ wakeMode: "now",
1488
+ name: "Gmail",
1489
+ sessionKey: "hook:gmail:{{messages[0].id}}",
1490
+ messageTemplate:
1491
+ "From: {{messages[0].from}}\nSubject: {{messages[0].subject}}\n{{messages[0].snippet}}",
1492
+ },
1493
+ ],
1494
+ }
1495
+ }
1496
+ ```
1497
+
1498
+ Requests must include the hook token:
1499
+ - `Authorization: Bearer <token>` **or**
1500
+ - `x-nexus-token: <token>` **or**
1501
+ - `?token=<token>`
1502
+
1503
+ Endpoints:
1504
+ - `POST /hooks/wake` → `{ text, mode?: "now"|"next-heartbeat" }`
1505
+ - `POST /hooks/agent` → `{ message, name?, sessionKey?, wakeMode?, deliver?, provider?, to?, thinking?, timeoutSeconds? }`
1506
+ - `POST /hooks/<name>` → resolved via `hooks.mappings`
1507
+
1508
+ `/hooks/agent` always posts a summary into the main session (and can optionally trigger an immediate heartbeat via `wakeMode: "now"`).
1509
+
1510
+ Mapping notes:
1511
+ - `match.path` matches the sub-path after `/hooks` (e.g. `/hooks/gmail` → `gmail`).
1512
+ - `match.source` matches a payload field (e.g. `{ source: "gmail" }`) so you can use a generic `/hooks/ingest` path.
1513
+ - Templates like `{{messages[0].subject}}` read from the payload.
1514
+ - `transform` can point to a JS/TS module that returns a hook action.
1515
+
1516
+ Gmail helper config (used by `nexus hooks gmail setup` / `run`):
1517
+
1518
+ ```json5
1519
+ {
1520
+ hooks: {
1521
+ gmail: {
1522
+ account: "nexus@gmail.com",
1523
+ topic: "projects/<project-id>/topics/gog-gmail-watch",
1524
+ subscription: "gog-gmail-watch-push",
1525
+ pushToken: "shared-push-token",
1526
+ hookUrl: "http://127.0.0.1:18789/hooks/gmail",
1527
+ includeBody: true,
1528
+ maxBytes: 20000,
1529
+ renewEveryMinutes: 720,
1530
+ serve: { bind: "127.0.0.1", port: 8788, path: "/" },
1531
+ tailscale: { mode: "funnel", path: "/gmail-pubsub" },
1532
+ }
1533
+ }
1534
+ }
1535
+ ```
1536
+
1537
+ Gateway auto-start:
1538
+ - If `hooks.enabled=true` and `hooks.gmail.account` is set, the Gateway starts
1539
+ `gog gmail watch serve` on boot and auto-renews the watch.
1540
+ - Set `NEXUS_SKIP_GMAIL_WATCHER=1` to disable the auto-start (for manual runs).
1541
+ - Avoid running a separate `gog gmail watch serve` alongside the Gateway; it will
1542
+ fail with `listen tcp 127.0.0.1:8788: bind: address already in use`.
1543
+
1544
+ Note: when `tailscale.mode` is on, Nexus defaults `serve.path` to `/` so
1545
+ Tailscale can proxy `/gmail-pubsub` correctly (it strips the set-path prefix).
1546
+
1547
+ ### `canvasHost` (LAN/tailnet Canvas file server + live reload)
1548
+
1549
+ The Gateway serves a directory of HTML/CSS/JS over HTTP so iOS/Android nodes can simply `canvas.navigate` to it.
1550
+
1551
+ Default root: `~/nexus/canvas`
1552
+ Default port: `18793` (chosen to avoid the nexus browser CDP port `18792`)
1553
+ The server listens on the **bridge bind host** (LAN or Tailnet) so nodes can reach it.
1554
+
1555
+ The server:
1556
+ - serves files under `canvasHost.root`
1557
+ - injects a tiny live-reload client into served HTML
1558
+ - watches the directory and broadcasts reloads over a WebSocket endpoint at `/__nexus/ws`
1559
+ - auto-creates a starter `index.html` when the directory is empty (so you see something immediately)
1560
+ - also serves A2UI at `/__nexus__/a2ui/` and is advertised to nodes as `canvasHostUrl`
1561
+ (always used by nodes for Canvas/A2UI)
1562
+
1563
+ Disable live reload (and file watching) if the directory is large or you hit `EMFILE`:
1564
+ - config: `canvasHost: { liveReload: false }`
1565
+
1566
+ ```json5
1567
+ {
1568
+ canvasHost: {
1569
+ root: "~/nexus/canvas",
1570
+ port: 18793,
1571
+ liveReload: true
1572
+ }
1573
+ }
1574
+ ```
1575
+
1576
+ Changes to `canvasHost.*` require a gateway restart (config reload will restart).
1577
+
1578
+ Disable with:
1579
+ - config: `canvasHost: { enabled: false }`
1580
+ - env: `NEXUS_SKIP_CANVAS_HOST=1`
1581
+
1582
+ ### `bridge` (node bridge server)
1583
+
1584
+ The Gateway can expose a simple TCP bridge for nodes (iOS/Android), typically on port `18790`.
1585
+
1586
+ Defaults:
1587
+ - enabled: `true`
1588
+ - port: `18790`
1589
+ - bind: `lan` (binds to `0.0.0.0`)
1590
+
1591
+ Bind modes:
1592
+ - `lan`: `0.0.0.0` (reachable on any interface, including LAN/Wi‑Fi and Tailscale)
1593
+ - `tailnet`: bind only to the machine’s Tailscale IP (recommended for Vienna ⇄ London)
1594
+ - `loopback`: `127.0.0.1` (local only)
1595
+ - `auto`: prefer tailnet IP if present, else `lan`
1596
+
1597
+ ```json5
1598
+ {
1599
+ bridge: {
1600
+ enabled: true,
1601
+ port: 18790,
1602
+ bind: "tailnet"
1603
+ }
1604
+ }
1605
+ ```
1606
+
1607
+ ### `discovery.wideArea` (Wide-Area Bonjour / unicast DNS‑SD)
1608
+
1609
+ When enabled, the Gateway writes a unicast DNS-SD zone for `_nexus-bridge._tcp` under `~/nexus/state/dns/` using the standard discovery domain `nexus.internal.`
1610
+
1611
+ To make iOS/Android discover across networks (Vienna ⇄ London), pair this with:
1612
+ - a DNS server on the gateway host serving `nexus.internal.` (CoreDNS is recommended)
1613
+ - Tailscale **split DNS** so clients resolve `nexus.internal` via that server
1614
+
1615
+ One-time setup helper (gateway host):
1616
+
1617
+ ```bash
1618
+ nexus dns setup --apply
1619
+ ```
1620
+
1621
+ ```json5
1622
+ {
1623
+ discovery: { wideArea: { enabled: true } }
1624
+ }
1625
+ ```
1626
+
1627
+ ## Template variables
1628
+
1629
+ Template placeholders are expanded in `routing.transcribeAudio.command` (and any future templated command fields).
1630
+
1631
+ | Variable | Description |
1632
+ |----------|-------------|
1633
+ | `{{Body}}` | Full inbound message body |
1634
+ | `{{BodyStripped}}` | Body with group mentions stripped (best default for agents) |
1635
+ | `{{From}}` | Sender identifier (E.164 for WhatsApp; may differ per provider) |
1636
+ | `{{To}}` | Destination identifier |
1637
+ | `{{MessageSid}}` | Provider message id (when available) |
1638
+ | `{{SessionId}}` | Current session UUID |
1639
+ | `{{IsNewSession}}` | `"true"` when a new session was created |
1640
+ | `{{MediaUrl}}` | Inbound media pseudo-URL (if present) |
1641
+ | `{{MediaPath}}` | Local media path (if downloaded) |
1642
+ | `{{MediaType}}` | Media type (image/audio/document/…) |
1643
+ | `{{Transcript}}` | Audio transcript (when enabled) |
1644
+ | `{{ChatType}}` | `"direct"` or `"group"` |
1645
+ | `{{GroupSubject}}` | Group subject (best effort) |
1646
+ | `{{GroupMembers}}` | Group members preview (best effort) |
1647
+ | `{{SenderName}}` | Sender display name (best effort) |
1648
+ | `{{SenderE164}}` | Sender phone number (best effort) |
1649
+ | `{{Provider}}` | Provider hint (whatsapp|telegram|discord|imessage|webchat|…) |
1650
+
1651
+ ## Cron (Gateway scheduler)
1652
+
1653
+ Cron is a Gateway-owned scheduler for wakeups and scheduled jobs. See [Cron + wakeups](https://docs.nexus.bot/cron) for the full RFC and CLI examples.
1654
+
1655
+ ```json5
1656
+ {
1657
+ cron: {
1658
+ enabled: true,
1659
+ maxConcurrentRuns: 2
1660
+ }
1661
+ }
1662
+ ```
1663
+
1664
+ ---
1665
+
1666
+ *Next: [Agent Runtime](https://docs.nexus.bot/agent)* 🦞