@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.
- package/CHANGELOG.md +222 -0
- package/LICENSE +21 -0
- package/README-header.png +0 -0
- package/README.md +462 -0
- package/dist/agents/agent-paths.js +16 -0
- package/dist/agents/agent-scope.js +44 -0
- package/dist/agents/auth-profiles.js +626 -0
- package/dist/agents/bash-process-registry.js +126 -0
- package/dist/agents/bash-tools.js +838 -0
- package/dist/agents/chutes-oauth.js +47 -0
- package/dist/agents/clawdbot-tools.js +62 -0
- package/dist/agents/context.js +34 -0
- package/dist/agents/defaults.js +6 -0
- package/dist/agents/memory-search.js +80 -0
- package/dist/agents/model-auth.js +115 -0
- package/dist/agents/model-catalog.js +55 -0
- package/dist/agents/model-fallback.js +210 -0
- package/dist/agents/model-scan.js +263 -0
- package/dist/agents/model-selection.js +152 -0
- package/dist/agents/models-config.js +171 -0
- package/dist/agents/nexus-tools.js +46 -0
- package/dist/agents/pi-embedded-block-chunker.js +188 -0
- package/dist/agents/pi-embedded-helpers.js +139 -0
- package/dist/agents/pi-embedded-runner.js +932 -0
- package/dist/agents/pi-embedded-subscribe.js +541 -0
- package/dist/agents/pi-embedded-utils.js +20 -0
- package/dist/agents/pi-embedded.js +1 -0
- package/dist/agents/pi-extensions/compaction-safeguard.js +140 -0
- package/dist/agents/pi-tool-definition-adapter.js +17 -0
- package/dist/agents/pi-tools.js +510 -0
- package/dist/agents/pi-tools.schema.js +358 -0
- package/dist/agents/sandbox-paths.js +68 -0
- package/dist/agents/sandbox.js +667 -0
- package/dist/agents/shell-utils.js +53 -0
- package/dist/agents/skill-runner.js +224 -0
- package/dist/agents/skill-state.js +164 -0
- package/dist/agents/skill-tools.js +191 -0
- package/dist/agents/skill-usage.js +43 -0
- package/dist/agents/skills-install.js +244 -0
- package/dist/agents/skills-status.js +157 -0
- package/dist/agents/skills.js +472 -0
- package/dist/agents/subagent-registry.js +321 -0
- package/dist/agents/subagent-registry.store.js +47 -0
- package/dist/agents/system-prompt.js +179 -0
- package/dist/agents/timeout.js +26 -0
- package/dist/agents/tool-display.js +155 -0
- package/dist/agents/tool-display.json +236 -0
- package/dist/agents/tool-images.js +138 -0
- package/dist/agents/tool-policy.js +87 -0
- package/dist/agents/tools/agent-step.js +41 -0
- package/dist/agents/tools/browser-tool.js +295 -0
- package/dist/agents/tools/canvas-tool.js +193 -0
- package/dist/agents/tools/common.js +88 -0
- package/dist/agents/tools/cron-tool.js +141 -0
- package/dist/agents/tools/discord-actions-guild.js +186 -0
- package/dist/agents/tools/discord-actions-messaging.js +313 -0
- package/dist/agents/tools/discord-actions-moderation.js +70 -0
- package/dist/agents/tools/discord-actions.js +56 -0
- package/dist/agents/tools/discord-schema.js +199 -0
- package/dist/agents/tools/discord-tool.js +16 -0
- package/dist/agents/tools/gateway-tool.js +46 -0
- package/dist/agents/tools/gateway.js +28 -0
- package/dist/agents/tools/image-tool.js +140 -0
- package/dist/agents/tools/memory-tool.js +92 -0
- package/dist/agents/tools/nodes-tool.js +413 -0
- package/dist/agents/tools/nodes-utils.js +92 -0
- package/dist/agents/tools/sessions-announce-target.js +35 -0
- package/dist/agents/tools/sessions-helpers.js +88 -0
- package/dist/agents/tools/sessions-history-tool.js +137 -0
- package/dist/agents/tools/sessions-list-tool.js +196 -0
- package/dist/agents/tools/sessions-send-helpers.js +103 -0
- package/dist/agents/tools/sessions-send-tool.js +371 -0
- package/dist/agents/tools/sessions-spawn-tool.js +319 -0
- package/dist/agents/tools/slack-actions.js +129 -0
- package/dist/agents/tools/slack-schema.js +59 -0
- package/dist/agents/tools/slack-tool.js +16 -0
- package/dist/agents/tools/telegram-actions.js +159 -0
- package/dist/agents/tools/telegram-schema.js +28 -0
- package/dist/agents/tools/telegram-tool.js +16 -0
- package/dist/agents/tools/whatsapp-login-tool.js +63 -0
- package/dist/agents/usage.js +58 -0
- package/dist/agents/workspace.js +264 -0
- package/dist/auto-reply/chunk.js +177 -0
- package/dist/auto-reply/command-auth.js +44 -0
- package/dist/auto-reply/command-detection.js +22 -0
- package/dist/auto-reply/envelope.js +30 -0
- package/dist/auto-reply/group-activation.js +20 -0
- package/dist/auto-reply/heartbeat.js +58 -0
- package/dist/auto-reply/model.js +22 -0
- package/dist/auto-reply/reply/abort.js +14 -0
- package/dist/auto-reply/reply/agent-runner.js +426 -0
- package/dist/auto-reply/reply/bash-command.js +314 -0
- package/dist/auto-reply/reply/block-streaming.js +34 -0
- package/dist/auto-reply/reply/body.js +29 -0
- package/dist/auto-reply/reply/commands.js +332 -0
- package/dist/auto-reply/reply/directive-handling.js +626 -0
- package/dist/auto-reply/reply/directives.js +59 -0
- package/dist/auto-reply/reply/dispatch-from-config.js +23 -0
- package/dist/auto-reply/reply/followup-runner.js +181 -0
- package/dist/auto-reply/reply/groups.js +152 -0
- package/dist/auto-reply/reply/mentions.js +64 -0
- package/dist/auto-reply/reply/model-selection.js +209 -0
- package/dist/auto-reply/reply/queue.js +399 -0
- package/dist/auto-reply/reply/reply-dispatcher.js +68 -0
- package/dist/auto-reply/reply/reply-tags.js +26 -0
- package/dist/auto-reply/reply/session-updates.js +103 -0
- package/dist/auto-reply/reply/session.js +169 -0
- package/dist/auto-reply/reply/typing.js +125 -0
- package/dist/auto-reply/reply.js +655 -0
- package/dist/auto-reply/send-policy.js +28 -0
- package/dist/auto-reply/status.js +197 -0
- package/dist/auto-reply/templating.js +9 -0
- package/dist/auto-reply/thinking.js +49 -0
- package/dist/auto-reply/tokens.js +2 -0
- package/dist/auto-reply/tool-meta.js +74 -0
- package/dist/auto-reply/transcription.js +57 -0
- package/dist/auto-reply/types.js +1 -0
- package/dist/browser/bridge-server.js +37 -0
- package/dist/browser/cdp.js +382 -0
- package/dist/browser/chrome.js +432 -0
- package/dist/browser/client-actions-core.js +67 -0
- package/dist/browser/client-actions-observe.js +24 -0
- package/dist/browser/client-actions-types.js +1 -0
- package/dist/browser/client-actions.js +3 -0
- package/dist/browser/client-fetch.js +43 -0
- package/dist/browser/client.js +105 -0
- package/dist/browser/config.js +155 -0
- package/dist/browser/constants.js +5 -0
- package/dist/browser/profiles-service.js +124 -0
- package/dist/browser/profiles.js +96 -0
- package/dist/browser/pw-ai.js +2 -0
- package/dist/browser/pw-session.js +144 -0
- package/dist/browser/pw-tools-core.js +363 -0
- package/dist/browser/routes/agent.js +535 -0
- package/dist/browser/routes/basic.js +155 -0
- package/dist/browser/routes/index.js +8 -0
- package/dist/browser/routes/tabs.js +105 -0
- package/dist/browser/routes/utils.js +62 -0
- package/dist/browser/screenshot.js +40 -0
- package/dist/browser/server-context.js +377 -0
- package/dist/browser/server.js +81 -0
- package/dist/browser/target-id.js +18 -0
- package/dist/browser/trash.js +21 -0
- package/dist/canvas-host/a2ui/a2ui.bundle.js +17768 -0
- package/dist/canvas-host/a2ui/index.html +246 -0
- package/dist/canvas-host/a2ui.js +187 -0
- package/dist/canvas-host/server.js +382 -0
- package/dist/channel-web.js +8 -0
- package/dist/cli/browser-cli-actions-input.js +459 -0
- package/dist/cli/browser-cli-actions-observe.js +56 -0
- package/dist/cli/browser-cli-examples.js +31 -0
- package/dist/cli/browser-cli-inspect.js +97 -0
- package/dist/cli/browser-cli-manage.js +286 -0
- package/dist/cli/browser-cli-shared.js +1 -0
- package/dist/cli/browser-cli.js +26 -0
- package/dist/cli/canvas-cli.js +416 -0
- package/dist/cli/cloud-cli.js +336 -0
- package/dist/cli/credential-cli.js +227 -0
- package/dist/cli/cron-cli.js +454 -0
- package/dist/cli/deps.js +17 -0
- package/dist/cli/dns-cli.js +180 -0
- package/dist/cli/gateway-cli.js +665 -0
- package/dist/cli/gateway-rpc.js +20 -0
- package/dist/cli/hooks-cli.js +135 -0
- package/dist/cli/memory-cli.js +101 -0
- package/dist/cli/models-cli.js +248 -0
- package/dist/cli/nodes-camera.js +57 -0
- package/dist/cli/nodes-canvas.js +26 -0
- package/dist/cli/nodes-cli.js +946 -0
- package/dist/cli/nodes-screen.js +37 -0
- package/dist/cli/pairing-cli.js +100 -0
- package/dist/cli/parse-duration.js +20 -0
- package/dist/cli/plugins-cli.js +158 -0
- package/dist/cli/ports.js +97 -0
- package/dist/cli/profile.js +81 -0
- package/dist/cli/program.js +162 -0
- package/dist/cli/prompt.js +19 -0
- package/dist/cli/run-main.js +48 -0
- package/dist/cli/skills-cli.js +132 -0
- package/dist/cli/skills-hub-cli.js +1093 -0
- package/dist/cli/telegram-cli.js +56 -0
- package/dist/cli/tool-connector-cli.js +118 -0
- package/dist/cli/tui-cli.js +35 -0
- package/dist/cli/upstream-sync-cli.js +2833 -0
- package/dist/cli/usage-cli.js +24 -0
- package/dist/cli/wait.js +8 -0
- package/dist/commands/agent-via-gateway.js +115 -0
- package/dist/commands/agent.js +665 -0
- package/dist/commands/antigravity-oauth.js +327 -0
- package/dist/commands/auth-choice-options.js +80 -0
- package/dist/commands/auth-choice.js +134 -0
- package/dist/commands/auth-token.js +31 -0
- package/dist/commands/bootstrap-preset.js +214 -0
- package/dist/commands/capabilities.js +36 -0
- package/dist/commands/chutes-oauth.js +144 -0
- package/dist/commands/claude-md.js +137 -0
- package/dist/commands/config-view.js +11 -0
- package/dist/commands/configure.js +648 -0
- package/dist/commands/credential.js +236 -0
- package/dist/commands/cursor-rules.js +230 -0
- package/dist/commands/doctor-state-migrations.js +358 -0
- package/dist/commands/doctor-ui.js +113 -0
- package/dist/commands/doctor.js +673 -0
- package/dist/commands/health.js +112 -0
- package/dist/commands/identity.js +54 -0
- package/dist/commands/init.js +167 -0
- package/dist/commands/models/aliases.js +85 -0
- package/dist/commands/models/fallbacks.js +123 -0
- package/dist/commands/models/image-fallbacks.js +123 -0
- package/dist/commands/models/list.js +347 -0
- package/dist/commands/models/scan.js +271 -0
- package/dist/commands/models/set-image.js +27 -0
- package/dist/commands/models/set.js +27 -0
- package/dist/commands/models/shared.js +73 -0
- package/dist/commands/models.js +7 -0
- package/dist/commands/onboard-auth.js +101 -0
- package/dist/commands/onboard-channels.js +814 -0
- package/dist/commands/onboard-eve-identity.js +98 -0
- package/dist/commands/onboard-github.js +153 -0
- package/dist/commands/onboard-helpers.js +303 -0
- package/dist/commands/onboard-interactive.js +17 -0
- package/dist/commands/onboard-non-interactive.js +228 -0
- package/dist/commands/onboard-providers.js +829 -0
- package/dist/commands/onboard-quickstart.js +185 -0
- package/dist/commands/onboard-remote.js +120 -0
- package/dist/commands/onboard-skills.js +148 -0
- package/dist/commands/onboard-types.js +1 -0
- package/dist/commands/onboard.js +19 -0
- package/dist/commands/openai-codex-model-default.js +38 -0
- package/dist/commands/poll.js +64 -0
- package/dist/commands/quest.js +27 -0
- package/dist/commands/reset.js +61 -0
- package/dist/commands/send.js +124 -0
- package/dist/commands/sessions-ingest.js +359 -0
- package/dist/commands/sessions.js +212 -0
- package/dist/commands/setup.js +59 -0
- package/dist/commands/signal-install.js +135 -0
- package/dist/commands/skills-manifest.js +235 -0
- package/dist/commands/status.js +139 -0
- package/dist/commands/suggestions.js +54 -0
- package/dist/commands/systemd-linger.js +71 -0
- package/dist/commands/update.js +16 -0
- package/dist/commands/usage-upload.js +27 -0
- package/dist/config/config.js +6 -0
- package/dist/config/defaults.js +140 -0
- package/dist/config/group-policy.js +49 -0
- package/dist/config/includes.js +183 -0
- package/dist/config/io.js +188 -0
- package/dist/config/legacy-migrate.js +13 -0
- package/dist/config/legacy.js +425 -0
- package/dist/config/paths.js +82 -0
- package/dist/config/port-defaults.js +32 -0
- package/dist/config/schema.js +173 -0
- package/dist/config/sessions.js +611 -0
- package/dist/config/talk.js +31 -0
- package/dist/config/types.js +1 -0
- package/dist/config/validation.js +29 -0
- package/dist/config/zod-schema.js +1110 -0
- package/dist/control-ui/assets/index-D8Q5AI4D.js +2393 -0
- package/dist/control-ui/assets/index-D8Q5AI4D.js.map +1 -0
- package/dist/control-ui/assets/index-g06q5Xc3.css +1 -0
- package/dist/control-ui/favicon.ico +0 -0
- package/dist/control-ui/index.html +16 -0
- package/dist/cron/isolated-agent.js +529 -0
- package/dist/cron/normalize.js +73 -0
- package/dist/cron/parse.js +24 -0
- package/dist/cron/run-log.js +72 -0
- package/dist/cron/schedule.js +24 -0
- package/dist/cron/service.js +471 -0
- package/dist/cron/store.js +43 -0
- package/dist/cron/types.js +1 -0
- package/dist/daemon/constants.js +10 -0
- package/dist/daemon/launchd.js +295 -0
- package/dist/daemon/legacy.js +63 -0
- package/dist/daemon/program-args.js +141 -0
- package/dist/daemon/schtasks.js +269 -0
- package/dist/daemon/service.js +69 -0
- package/dist/daemon/systemd.js +332 -0
- package/dist/discord/index.js +2 -0
- package/dist/discord/monitor.js +1089 -0
- package/dist/discord/probe.js +54 -0
- package/dist/discord/send.js +652 -0
- package/dist/discord/token.js +8 -0
- package/dist/entry.js +16 -0
- package/dist/gateway/auth.js +121 -0
- package/dist/gateway/call.js +103 -0
- package/dist/gateway/chat-attachments.js +41 -0
- package/dist/gateway/client.js +180 -0
- package/dist/gateway/config-reload.js +274 -0
- package/dist/gateway/control-ui.js +184 -0
- package/dist/gateway/hooks-mapping.js +282 -0
- package/dist/gateway/hooks.js +168 -0
- package/dist/gateway/net.js +29 -0
- package/dist/gateway/protocol/index.js +62 -0
- package/dist/gateway/protocol/schema.js +577 -0
- package/dist/gateway/server-bridge-subscriptions.js +93 -0
- package/dist/gateway/server-bridge.js +1066 -0
- package/dist/gateway/server-browser.js +11 -0
- package/dist/gateway/server-channels.js +680 -0
- package/dist/gateway/server-chat.js +159 -0
- package/dist/gateway/server-constants.js +8 -0
- package/dist/gateway/server-discovery.js +62 -0
- package/dist/gateway/server-http.js +165 -0
- package/dist/gateway/server-methods/agent-job.js +114 -0
- package/dist/gateway/server-methods/agent.js +254 -0
- package/dist/gateway/server-methods/channels.js +239 -0
- package/dist/gateway/server-methods/chat.js +207 -0
- package/dist/gateway/server-methods/config.js +50 -0
- package/dist/gateway/server-methods/connect.js +6 -0
- package/dist/gateway/server-methods/cron.js +89 -0
- package/dist/gateway/server-methods/health.js +28 -0
- package/dist/gateway/server-methods/models.js +16 -0
- package/dist/gateway/server-methods/nodes.js +294 -0
- package/dist/gateway/server-methods/providers.js +257 -0
- package/dist/gateway/server-methods/send.js +254 -0
- package/dist/gateway/server-methods/sessions.js +382 -0
- package/dist/gateway/server-methods/skills.js +83 -0
- package/dist/gateway/server-methods/system.js +118 -0
- package/dist/gateway/server-methods/talk.js +22 -0
- package/dist/gateway/server-methods/types.js +1 -0
- package/dist/gateway/server-methods/voicewake.js +30 -0
- package/dist/gateway/server-methods/web.js +81 -0
- package/dist/gateway/server-methods/wizard.js +100 -0
- package/dist/gateway/server-methods.js +53 -0
- package/dist/gateway/server-providers.js +687 -0
- package/dist/gateway/server-shared.js +1 -0
- package/dist/gateway/server-utils.js +35 -0
- package/dist/gateway/server.js +1478 -0
- package/dist/gateway/session-utils.js +355 -0
- package/dist/gateway/ws-log.js +343 -0
- package/dist/gateway/ws-logging.js +8 -0
- package/dist/globals.js +41 -0
- package/dist/hooks/gmail-ops.js +236 -0
- package/dist/hooks/gmail-setup-utils.js +278 -0
- package/dist/hooks/gmail-watcher.js +190 -0
- package/dist/hooks/gmail.js +177 -0
- package/dist/imessage/client.js +165 -0
- package/dist/imessage/index.js +3 -0
- package/dist/imessage/monitor.js +365 -0
- package/dist/imessage/probe.js +26 -0
- package/dist/imessage/send.js +83 -0
- package/dist/imessage/targets.js +176 -0
- package/dist/index.js +55 -0
- package/dist/infra/agent-events.js +46 -0
- package/dist/infra/binaries.js +9 -0
- package/dist/infra/bonjour-discovery.js +163 -0
- package/dist/infra/bonjour.js +200 -0
- package/dist/infra/bridge/server.js +564 -0
- package/dist/infra/canvas-host-url.js +54 -0
- package/dist/infra/channel-summary.js +78 -0
- package/dist/infra/control-ui-assets.js +112 -0
- package/dist/infra/dotenv.js +15 -0
- package/dist/infra/env.js +8 -0
- package/dist/infra/errors.js +28 -0
- package/dist/infra/event-log.js +251 -0
- package/dist/infra/gateway-lock.js +8 -0
- package/dist/infra/git-commit.js +91 -0
- package/dist/infra/heartbeat-events.js +21 -0
- package/dist/infra/heartbeat-runner.js +458 -0
- package/dist/infra/heartbeat-wake.js +61 -0
- package/dist/infra/is-main.js +37 -0
- package/dist/infra/json-file.js +21 -0
- package/dist/infra/machine-name.js +40 -0
- package/dist/infra/nexus-root.js +56 -0
- package/dist/infra/node-pairing.js +212 -0
- package/dist/infra/path-env.js +93 -0
- package/dist/infra/ports.js +87 -0
- package/dist/infra/provider-summary.js +80 -0
- package/dist/infra/provider-usage.auth.js +189 -0
- package/dist/infra/provider-usage.fetch.claude.js +129 -0
- package/dist/infra/provider-usage.fetch.codex.js +62 -0
- package/dist/infra/provider-usage.fetch.copilot.js +42 -0
- package/dist/infra/provider-usage.fetch.gemini.js +57 -0
- package/dist/infra/provider-usage.fetch.js +6 -0
- package/dist/infra/provider-usage.fetch.minimax.js +214 -0
- package/dist/infra/provider-usage.fetch.shared.js +11 -0
- package/dist/infra/provider-usage.fetch.zai.js +62 -0
- package/dist/infra/provider-usage.format.js +77 -0
- package/dist/infra/provider-usage.js +145 -0
- package/dist/infra/provider-usage.load.js +54 -0
- package/dist/infra/provider-usage.shared.js +19 -0
- package/dist/infra/provider-usage.types.js +1 -0
- package/dist/infra/restart.js +29 -0
- package/dist/infra/retry.js +16 -0
- package/dist/infra/runtime-guard.js +59 -0
- package/dist/infra/shell-env.js +88 -0
- package/dist/infra/system-events.js +71 -0
- package/dist/infra/system-presence.js +217 -0
- package/dist/infra/tailnet.js +46 -0
- package/dist/infra/tailscale.js +149 -0
- package/dist/infra/unhandled-rejections.js +19 -0
- package/dist/infra/usage-suggestions.js +241 -0
- package/dist/infra/usage-upload.js +290 -0
- package/dist/infra/voicewake.js +78 -0
- package/dist/infra/widearea-dns.js +123 -0
- package/dist/infra/ws.js +13 -0
- package/dist/logger.js +52 -0
- package/dist/logging.js +506 -0
- package/dist/macos/gateway-daemon.js +145 -0
- package/dist/macos/relay.js +49 -0
- package/dist/media/constants.js +33 -0
- package/dist/media/host.js +42 -0
- package/dist/media/image-ops.js +119 -0
- package/dist/media/mime.js +123 -0
- package/dist/media/parse.js +83 -0
- package/dist/media/server.js +64 -0
- package/dist/media/store.js +139 -0
- package/dist/polls.js +43 -0
- package/dist/process/command-queue.js +97 -0
- package/dist/process/exec.js +75 -0
- package/dist/provider-web.js +8 -0
- package/dist/providers/github-copilot-auth.js +123 -0
- package/dist/providers/github-copilot-models.js +35 -0
- package/dist/providers/github-copilot-token.js +11 -0
- package/dist/providers/location.js +48 -0
- package/dist/providers/web/index.js +2 -0
- package/dist/runtime.js +8 -0
- package/dist/sessions/level-overrides.js +9 -0
- package/dist/sessions/send-policy.js +68 -0
- package/dist/signal/client.js +134 -0
- package/dist/signal/daemon.js +69 -0
- package/dist/signal/index.js +3 -0
- package/dist/signal/monitor.js +411 -0
- package/dist/signal/probe.js +46 -0
- package/dist/signal/send.js +91 -0
- package/dist/slack/actions.js +97 -0
- package/dist/slack/index.js +5 -0
- package/dist/slack/monitor.js +1270 -0
- package/dist/slack/probe.js +47 -0
- package/dist/slack/send.js +131 -0
- package/dist/slack/token.js +10 -0
- package/dist/telegram/allowed-updates.js +8 -0
- package/dist/telegram/bot.js +724 -0
- package/dist/telegram/download.js +34 -0
- package/dist/telegram/index.js +4 -0
- package/dist/telegram/monitor.js +47 -0
- package/dist/telegram/pairing-store.js +77 -0
- package/dist/telegram/probe.js +63 -0
- package/dist/telegram/proxy.js +9 -0
- package/dist/telegram/reaction-level.js +45 -0
- package/dist/telegram/send.js +151 -0
- package/dist/telegram/sent-message-cache.js +65 -0
- package/dist/telegram/token.js +30 -0
- package/dist/telegram/update-offset-store.js +61 -0
- package/dist/telegram/webhook-set.js +12 -0
- package/dist/telegram/webhook.js +56 -0
- package/dist/tui/commands.js +87 -0
- package/dist/tui/components/assistant-message.js +16 -0
- package/dist/tui/components/chat-log.js +92 -0
- package/dist/tui/components/custom-editor.js +55 -0
- package/dist/tui/components/selectors.js +8 -0
- package/dist/tui/components/tool-execution.js +111 -0
- package/dist/tui/components/user-message.js +17 -0
- package/dist/tui/gateway-chat.js +140 -0
- package/dist/tui/theme/theme.js +80 -0
- package/dist/tui/tui.js +708 -0
- package/dist/utils.js +153 -0
- package/dist/version.js +18 -0
- package/dist/web/accounts.js +86 -0
- package/dist/web/active-listener.js +25 -0
- package/dist/web/auto-reply.js +1256 -0
- package/dist/web/inbound.js +649 -0
- package/dist/web/login-qr.js +230 -0
- package/dist/web/login.js +71 -0
- package/dist/web/media.js +175 -0
- package/dist/web/outbound.js +102 -0
- package/dist/web/qr-image.js +97 -0
- package/dist/web/reconnect.js +60 -0
- package/dist/web/session.js +370 -0
- package/dist/wizard/clack-prompter.js +56 -0
- package/dist/wizard/onboarding.js +620 -0
- package/dist/wizard/prompts.js +6 -0
- package/dist/wizard/session.js +203 -0
- package/docs/AGENTS.default.md +116 -0
- package/docs/CAPABILITIES.md +444 -0
- package/docs/CNAME +1 -0
- package/docs/NEXUS_CORE_REWRITE_SPEC.md +226 -0
- package/docs/RELEASING.md +69 -0
- package/docs/_config.yml +53 -0
- package/docs/_layouts/default.html +145 -0
- package/docs/agent-assisted-install.md +95 -0
- package/docs/agent-loop.md +61 -0
- package/docs/agent-send.md +21 -0
- package/docs/agent.md +108 -0
- package/docs/android.md +133 -0
- package/docs/architecture.md +114 -0
- package/docs/assets/markdown.css +133 -0
- package/docs/assets/pixel-lobster.svg +60 -0
- package/docs/assets/terminal.css +470 -0
- package/docs/assets/theme.js +55 -0
- package/docs/audio.md +48 -0
- package/docs/automation/nexus-sync.md +371 -0
- package/docs/background-process.md +74 -0
- package/docs/bash.md +32 -0
- package/docs/bedrock.md +71 -0
- package/docs/bonjour.md +159 -0
- package/docs/browser-linux-troubleshooting.md +114 -0
- package/docs/browser.md +293 -0
- package/docs/bun.md +56 -0
- package/docs/camera.md +152 -0
- package/docs/clawd.md +212 -0
- package/docs/concepts/usage-tracking.md +29 -0
- package/docs/configuration.md +1666 -0
- package/docs/control-ui.md +83 -0
- package/docs/cron.md +385 -0
- package/docs/dashboard.md +17 -0
- package/docs/device-models.md +46 -0
- package/docs/discord.md +308 -0
- package/docs/discovery.md +112 -0
- package/docs/docker.md +258 -0
- package/docs/docs.json +105 -0
- package/docs/doctor.md +68 -0
- package/docs/elevated.md +31 -0
- package/docs/faq.md +736 -0
- package/docs/feature-inventory/overview.md +141 -0
- package/docs/feature-inventory/rollout-checklist.md +53 -0
- package/docs/feature-inventory/test-matrix.md +87 -0
- package/docs/feature-inventory.md +9 -0
- package/docs/gateway/configuration-examples.md +221 -0
- package/docs/gateway/configuration.md +172 -0
- package/docs/gateway/cron.md +61 -0
- package/docs/gateway/heartbeat.md +207 -0
- package/docs/gateway/pairing.md +109 -0
- package/docs/gateway-lock.md +28 -0
- package/docs/gateway.md +227 -0
- package/docs/gmail-pubsub.md +191 -0
- package/docs/grammy.md +27 -0
- package/docs/group-messages.md +73 -0
- package/docs/groups.md +130 -0
- package/docs/health.md +28 -0
- package/docs/heartbeat.md +73 -0
- package/docs/home-userspace.md +277 -0
- package/docs/hubs.md +148 -0
- package/docs/images.md +51 -0
- package/docs/imessage.md +94 -0
- package/docs/index.md +196 -0
- package/docs/ios.md +372 -0
- package/docs/linux.md +11 -0
- package/docs/location-command.md +95 -0
- package/docs/location.md +46 -0
- package/docs/logging.md +110 -0
- package/docs/lore.md +131 -0
- package/docs/mac/bun.md +133 -0
- package/docs/mac/canvas.md +161 -0
- package/docs/mac/child-process.md +72 -0
- package/docs/mac/dev-setup.md +81 -0
- package/docs/mac/health.md +28 -0
- package/docs/mac/icon.md +26 -0
- package/docs/mac/logging.md +51 -0
- package/docs/mac/menu-bar.md +69 -0
- package/docs/mac/peekaboo.md +170 -0
- package/docs/mac/permissions.md +40 -0
- package/docs/mac/release.md +76 -0
- package/docs/mac/remote.md +57 -0
- package/docs/mac/signing.md +41 -0
- package/docs/mac/skills.md +27 -0
- package/docs/mac/voice-overlay.md +52 -0
- package/docs/mac/voicewake.md +56 -0
- package/docs/mac/webchat.md +27 -0
- package/docs/mac/xpc.md +40 -0
- package/docs/macos.md +104 -0
- package/docs/model-failover.md +75 -0
- package/docs/models.md +91 -0
- package/docs/multi-agent.md +74 -0
- package/docs/nix.md +95 -0
- package/docs/nodes.md +157 -0
- package/docs/onboarding-config-protocol.md +34 -0
- package/docs/onboarding.md +189 -0
- package/docs/pairing.md +85 -0
- package/docs/plans/cron-add-hardening.md +72 -0
- package/docs/plans/group-policy-hardening.md +121 -0
- package/docs/poll.md +52 -0
- package/docs/prereqs.md +67 -0
- package/docs/presence.md +133 -0
- package/docs/proposals/model-config.md +147 -0
- package/docs/provider-routing.md +25 -0
- package/docs/queue.md +78 -0
- package/docs/reference/templates/AGENTS.md +164 -0
- package/docs/remote-gateway-readme.md +153 -0
- package/docs/remote.md +61 -0
- package/docs/research/memory.md +227 -0
- package/docs/rpc.md +35 -0
- package/docs/security.md +200 -0
- package/docs/session-ingestion.md +119 -0
- package/docs/session-tool.md +154 -0
- package/docs/session.md +85 -0
- package/docs/sessions.md +8 -0
- package/docs/setup.md +131 -0
- package/docs/showcase.md +37 -0
- package/docs/signal.md +122 -0
- package/docs/skills-config.md +58 -0
- package/docs/skills.md +153 -0
- package/docs/slack.md +221 -0
- package/docs/subagents.md +72 -0
- package/docs/tailscale.md +71 -0
- package/docs/talk.md +79 -0
- package/docs/telegram.md +96 -0
- package/docs/templates/AGENTS.md +286 -0
- package/docs/templates/BOOTSTRAP.md +35 -0
- package/docs/templates/IDENTITY.md +17 -0
- package/docs/templates/PROFILE.md +14 -0
- package/docs/templates/SOUL.md +41 -0
- package/docs/templates/TOOLS.md +41 -0
- package/docs/templates/USER.md +8 -0
- package/docs/test.md +43 -0
- package/docs/testing-onboarding-quickstart.md +76 -0
- package/docs/testing-philosophy.md +211 -0
- package/docs/thinking.md +46 -0
- package/docs/timezone.md +40 -0
- package/docs/tools.md +346 -0
- package/docs/troubleshooting.md +257 -0
- package/docs/tui.md +71 -0
- package/docs/typebox.md +42 -0
- package/docs/updating.md +138 -0
- package/docs/usage-cloud-aggregation-spec.md +133 -0
- package/docs/usage-suggestions-pipeline.md +126 -0
- package/docs/voicewake.md +61 -0
- package/docs/web.md +115 -0
- package/docs/webchat.md +34 -0
- package/docs/webhook.md +132 -0
- package/docs/whatsapp-clawd.jpg +0 -0
- package/docs/whatsapp.md +170 -0
- package/docs/windows.md +11 -0
- package/docs/wizard.md +167 -0
- package/package.json +209 -0
- package/skills/1password/SKILL.md +54 -0
- package/skills/1password/docs/setup.md +85 -0
- package/skills/1password/docs/troubleshooting.md +63 -0
- package/skills/1password/references/cli-examples.md +29 -0
- package/skills/1password/references/get-started.md +17 -0
- package/skills/agent-browser/SKILL.md +450 -0
- package/skills/agent-browser/docs/browser-use-eval.md +95 -0
- package/skills/agent-browser/docs/first-tests.md +261 -0
- package/skills/agent-browser/docs/wordle-nyt-eval.js +32 -0
- package/skills/aix/SKILL.md +93 -0
- package/skills/aix/docs/embeddings.md +40 -0
- package/skills/aix/docs/setup.md +58 -0
- package/skills/aix/docs/troubleshooting.md +41 -0
- package/skills/aix/references/sql.md +48 -0
- package/skills/apple-notes/SKILL.md +50 -0
- package/skills/apple-reminders/SKILL.md +67 -0
- package/skills/bear-notes/SKILL.md +79 -0
- package/skills/bird/SKILL.md +32 -0
- package/skills/bird/docs/auth.md +31 -0
- package/skills/bird/docs/troubleshooting.md +31 -0
- package/skills/blogwatcher/SKILL.md +46 -0
- package/skills/blucli/SKILL.md +27 -0
- package/skills/brave-search/SKILL.md +36 -0
- package/skills/brave-search/docs/setup.md +40 -0
- package/skills/brave-search/docs/troubleshooting.md +37 -0
- package/skills/brave-search/docs/usage.md +28 -0
- package/skills/brave-search/scripts/content.mjs +53 -0
- package/skills/brave-search/scripts/search.mjs +79 -0
- package/skills/browser-use-agent-sdk/SKILL.md +90 -0
- package/skills/camsnap/SKILL.md +25 -0
- package/skills/clawdhub/SKILL.md +53 -0
- package/skills/coding-agent/SKILL.md +274 -0
- package/skills/comms/SKILL.md +249 -0
- package/skills/comms/docs/adapters.md +54 -0
- package/skills/comms/docs/setup.md +56 -0
- package/skills/comms/docs/troubleshooting.md +44 -0
- package/skills/comms/references/schema.md +49 -0
- package/skills/computer-use/SKILL.md +204 -0
- package/skills/computer-use/docs/open-interpreter.md +26 -0
- package/skills/computer-use/docs/peekaboo.md +26 -0
- package/skills/computer-use/docs/setup.md +47 -0
- package/skills/computer-use/docs/troubleshooting.md +33 -0
- package/skills/discord/SKILL.md +370 -0
- package/skills/eightctl/SKILL.md +29 -0
- package/skills/eve/SKILL.md +215 -0
- package/skills/eve/docs/dual-account.md +84 -0
- package/skills/eve/docs/intelligence.md +58 -0
- package/skills/eve/docs/setup.md +60 -0
- package/skills/eve/docs/troubleshooting.md +54 -0
- package/skills/eve/scripts/setup-dual-account.sh +125 -0
- package/skills/filesystem/SKILL.md +217 -0
- package/skills/food-order/SKILL.md +41 -0
- package/skills/gemini/SKILL.md +23 -0
- package/skills/gh/SKILL.md +22 -0
- package/skills/gh/docs/usage.md +41 -0
- package/skills/gifgrep/SKILL.md +47 -0
- package/skills/github/SKILL.md +26 -0
- package/skills/github/docs/setup.md +21 -0
- package/skills/github/docs/troubleshooting.md +24 -0
- package/skills/gog/SKILL.md +104 -0
- package/skills/gog/docs/portability.md +94 -0
- package/skills/gog/docs/setup.md +76 -0
- package/skills/gog/docs/troubleshooting.md +94 -0
- package/skills/gog/scripts/cdp/README.md +90 -0
- package/skills/gog/scripts/cdp/add_test_users.py +69 -0
- package/skills/gog/scripts/cdp/auth_add_accounts.py +209 -0
- package/skills/gog/scripts/cdp/auth_add_accounts_manual.py +206 -0
- package/skills/gog/scripts/cdp/create_oauth_client.py +165 -0
- package/skills/gog/scripts/cdp/launch_cdp_chrome.sh +58 -0
- package/skills/google-oauth/SKILL.md +94 -0
- package/skills/goplaces/SKILL.md +30 -0
- package/skills/imsg/SKILL.md +25 -0
- package/skills/json-render/SKILL.md +154 -0
- package/skills/json-render/assets/components/README.md +21 -0
- package/skills/json-render/assets/components/catalog.ts +78 -0
- package/skills/json-render/assets/components/registry.tsx +172 -0
- package/skills/json-render/assets/demo/App.css +397 -0
- package/skills/json-render/assets/demo/App.tsx +897 -0
- package/skills/json-render/assets/demo/README.md +22 -0
- package/skills/json-render/assets/demo/catalog.ts +78 -0
- package/skills/json-render/assets/demo/data/nexus-core.json +31 -0
- package/skills/json-render/assets/demo/index.css +27 -0
- package/skills/json-render/assets/demo/registry.tsx +150 -0
- package/skills/json-render/docs/nexus-state-demo.md +84 -0
- package/skills/json-render/docs/shadcn-preset.md +33 -0
- package/skills/json-render/scripts/create-vite-demo.sh +45 -0
- package/skills/json-render/scripts/llm-server/README.md +33 -0
- package/skills/json-render/scripts/llm-server/catalog.ts +78 -0
- package/skills/json-render/scripts/llm-server/package-lock.json +702 -0
- package/skills/json-render/scripts/llm-server/package.json +18 -0
- package/skills/json-render/scripts/llm-server/server.ts +285 -0
- package/skills/local-places/SERVER_README.md +101 -0
- package/skills/local-places/SKILL.md +91 -0
- package/skills/local-places/pyproject.toml +27 -0
- package/skills/local-places/src/local_places/__init__.py +2 -0
- package/skills/local-places/src/local_places/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/local-places/src/local_places/__pycache__/google_places.cpython-314.pyc +0 -0
- package/skills/local-places/src/local_places/__pycache__/main.cpython-314.pyc +0 -0
- package/skills/local-places/src/local_places/__pycache__/schemas.cpython-314.pyc +0 -0
- package/skills/local-places/src/local_places/google_places.py +314 -0
- package/skills/local-places/src/local_places/main.py +65 -0
- package/skills/local-places/src/local_places/schemas.py +107 -0
- package/skills/mcporter/SKILL.md +38 -0
- package/skills/model-usage/SKILL.md +45 -0
- package/skills/model-usage/references/codexbar-cli.md +28 -0
- package/skills/model-usage/scripts/model_usage.py +310 -0
- package/skills/nano-banana-pro/SKILL.md +30 -0
- package/skills/nano-banana-pro/scripts/generate_image.py +169 -0
- package/skills/nano-pdf/SKILL.md +20 -0
- package/skills/nexus-cloud/SKILL.md +53 -0
- package/skills/nexus-cloud/docs/security.md +24 -0
- package/skills/nexus-cloud/docs/setup.md +51 -0
- package/skills/nexus-cloud/docs/troubleshooting.md +28 -0
- package/skills/notion/SKILL.md +156 -0
- package/skills/obsidian/SKILL.md +55 -0
- package/skills/onboarding/SKILL.md +515 -0
- package/skills/onboarding/docs/CAPABILITIES.md +444 -0
- package/skills/onboarding/docs/CAPABILITY_TAXONOMY.md +608 -0
- package/skills/onboarding/docs/CLI_GRAMMAR.md +797 -0
- package/skills/onboarding/docs/CLI_GRAMMAR_CREDENTIALS.md +632 -0
- package/skills/onboarding/docs/CLI_GRAMMAR_ONBOARDING.md +815 -0
- package/skills/onboarding/docs/CLI_GRAMMAR_SKILLS.md +449 -0
- package/skills/onboarding/docs/DOCUMENTATION_OVERVIEW.md +290 -0
- package/skills/onboarding/docs/ENTITY_MODEL.md +582 -0
- package/skills/onboarding/docs/GOAL_STATE_ARCHITECTURE.md +395 -0
- package/skills/onboarding/docs/NEXUS_SYSTEM_OVERVIEW.md +476 -0
- package/skills/onboarding/docs/SKILLS_HUB_SPEC.md +477 -0
- package/skills/onboarding/docs/SKILLS_SPECIFICATION.md +947 -0
- package/skills/onboarding/docs/SKILL_GATEWAY_DESIGN.md +702 -0
- package/skills/onboarding/docs/SKILL_GATEWAY_PRD.md +278 -0
- package/skills/onboarding/docs/SKILL_INVENTORY.md +266 -0
- package/skills/onboarding/docs/STATE_ARCHITECTURE.md +547 -0
- package/skills/onboarding/docs/TROUBLESHOOTING.md +363 -0
- package/skills/onboarding/docs/USER_JOURNEY.md +797 -0
- package/skills/onboarding/docs/WOW_MOMENTS.md +232 -0
- package/skills/onboarding/docs/agent-apple-id.md +289 -0
- package/skills/onboarding/docs/skill-deep-dives/1password.md +367 -0
- package/skills/onboarding/docs/skill-deep-dives/TEMPLATE.md +197 -0
- package/skills/onboarding/docs/skill-deep-dives/aix.md +498 -0
- package/skills/onboarding/docs/skill-deep-dives/bird.md +357 -0
- package/skills/onboarding/docs/skill-deep-dives/brave-search.md +601 -0
- package/skills/onboarding/docs/skill-deep-dives/comms.md +607 -0
- package/skills/onboarding/docs/skill-deep-dives/computer-use.md +599 -0
- package/skills/onboarding/docs/skill-deep-dives/cron-and-heartbeat.md +576 -0
- package/skills/onboarding/docs/skill-deep-dives/eve.md +711 -0
- package/skills/onboarding/docs/skill-deep-dives/github.md +333 -0
- package/skills/onboarding/docs/skill-deep-dives/gog.md +640 -0
- package/skills/onboarding/docs/skill-deep-dives/homebrew-prereqs.md +785 -0
- package/skills/onboarding/docs/skill-deep-dives/nexus-cloud.md +689 -0
- package/skills/onboarding/docs/skill-deep-dives/qmd.md +742 -0
- package/skills/onboarding/docs/skill-deep-dives/telegram.md +379 -0
- package/skills/onboarding/docs/skill-deep-dives/wacli.md +399 -0
- package/skills/onboarding/docs/skill-deep-dives/weather.md +513 -0
- package/skills/onboarding/scripts/ralph/prd.json +215 -0
- package/skills/onboarding/scripts/ralph/progress.txt +99 -0
- package/skills/onboarding/scripts/ralph/prompt.md +87 -0
- package/skills/onboarding/scripts/ralph/ralph.log +84 -0
- package/skills/onboarding/scripts/ralph/ralph.sh +45 -0
- package/skills/onboarding/scripts/setup-cursor-skills.sh +40 -0
- package/skills/openai-image-gen/SKILL.md +31 -0
- package/skills/openai-image-gen/scripts/gen.py +173 -0
- package/skills/openai-whisper/SKILL.md +19 -0
- package/skills/openai-whisper-api/SKILL.md +43 -0
- package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
- package/skills/openhue/SKILL.md +30 -0
- package/skills/oracle/SKILL.md +105 -0
- package/skills/ordercli/SKILL.md +47 -0
- package/skills/peekaboo/SKILL.md +153 -0
- package/skills/qmd/SKILL.md +32 -0
- package/skills/qmd/docs/mcp.md +30 -0
- package/skills/qmd/docs/ollama.md +42 -0
- package/skills/qmd/docs/setup.md +44 -0
- package/skills/sag/SKILL.md +62 -0
- package/skills/skill-cli-template/SKILL.md +109 -0
- package/skills/skill-creator/scripts/__pycache__/quick_validate.cpython-311.pyc +0 -0
- package/skills/slack/SKILL.md +144 -0
- package/skills/songsee/SKILL.md +29 -0
- package/skills/sonoscli/SKILL.md +26 -0
- package/skills/spotify-player/SKILL.md +34 -0
- package/skills/summarize/SKILL.md +49 -0
- package/skills/telegram/SKILL.md +20 -0
- package/skills/telegram/docs/pairing.md +30 -0
- package/skills/telegram/docs/setup.md +41 -0
- package/skills/telegram/docs/webhook.md +17 -0
- package/skills/things-mac/SKILL.md +61 -0
- package/skills/tmux/SKILL.md +121 -0
- package/skills/tmux/scripts/find-sessions.sh +112 -0
- package/skills/tmux/scripts/wait-for-text.sh +83 -0
- package/skills/trello/SKILL.md +84 -0
- package/skills/upstream-sync/SKILL.md +151 -0
- package/skills/upstream-sync/scripts/auto-port.sh +227 -0
- package/skills/upstream-sync/scripts/check-all.sh +88 -0
- package/skills/upstream-sync/scripts/check-nexus.sh +146 -0
- package/skills/upstream-sync/scripts/check-pi-ai.sh +129 -0
- package/skills/video-frames/SKILL.md +29 -0
- package/skills/video-frames/scripts/frame.sh +81 -0
- package/skills/wacli/SKILL.md +48 -0
- package/skills/wacli/docs/auth.md +21 -0
- package/skills/wacli/docs/backup.md +9 -0
- package/skills/wacli/docs/troubleshooting.md +21 -0
- package/skills/weather/SKILL.md +53 -0
- 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)* 🦞
|