@intent-systems/nexus 2026.1.5-4 → 2026.1.5-8
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/dist/agents/agent-id.js +41 -0
- package/dist/agents/auth-profiles.js +114 -25
- package/dist/agents/identity-state.js +101 -0
- package/dist/agents/model-auth.js +1 -0
- package/dist/agents/model-fallback.js +15 -9
- package/dist/agents/model-selection.js +1 -1
- package/dist/agents/models-config.js +17 -11
- package/dist/agents/pi-embedded-runner.js +101 -9
- package/dist/agents/sandbox.js +12 -3
- package/dist/agents/skill-runner.js +41 -6
- package/dist/agents/skill-usage.js +117 -17
- package/dist/agents/skills-status.js +4 -3
- package/dist/agents/skills.js +38 -30
- package/dist/agents/subagent-registry.js +25 -11
- package/dist/agents/system-prompt.js +16 -0
- package/dist/agents/tool-policy.js +19 -3
- package/dist/agents/tools/browser-tool.js +5 -2
- package/dist/agents/tools/image-tool.js +93 -8
- package/dist/agents/tools/sessions-announce-target.js +5 -1
- package/dist/agents/workspace.js +81 -59
- package/dist/auto-reply/command-detection.js +2 -1
- package/dist/auto-reply/reply/directive-handling.js +153 -28
- package/dist/auto-reply/reply/directives.js +17 -2
- package/dist/auto-reply/reply/model-selection.js +8 -3
- package/dist/auto-reply/reply/queue.js +2 -2
- package/dist/auto-reply/reply.js +1 -1
- package/dist/auto-reply/thinking.js +15 -0
- package/dist/browser/chrome.js +1 -1
- package/dist/browser/client.js +2 -0
- package/dist/browser/config.js +6 -2
- package/dist/browser/pw-tools-core.js +3 -0
- package/dist/browser/routes/agent.js +14 -0
- package/dist/canvas-host/server.js +1 -1
- package/dist/capabilities/detector.js +46 -15
- package/dist/capabilities/registry.js +2 -1
- package/dist/cli/cloud-cli.js +70 -7
- package/dist/cli/credential-cli.js +214 -23
- package/dist/cli/gateway-cli.js +1 -1
- package/dist/cli/log-cli.js +25 -0
- package/dist/cli/pairing-cli.js +1 -1
- package/dist/cli/program.js +82 -8
- package/dist/cli/run-main.js +1 -1
- package/dist/cli/skills-cli.js +165 -30
- package/dist/cli/skills-hub-cli.js +68 -36
- package/dist/cli/tool-connector-cli.js +99 -24
- package/dist/cli/upstream-sync-cli.js +253 -96
- package/dist/cli/usage-cli.js +14 -0
- package/dist/commands/auth-choice-options.js +6 -1
- package/dist/commands/auth-choice.js +157 -5
- package/dist/commands/bootstrap-preset.js +26 -12
- package/dist/commands/capabilities.js +33 -6
- package/dist/commands/claude-md.js +3 -2
- package/dist/commands/config-view.js +1 -1
- package/dist/commands/config.js +85 -0
- package/dist/commands/configure.js +4 -4
- package/dist/commands/credential.js +497 -36
- package/dist/commands/cursor-hooks.js +240 -0
- package/dist/commands/cursor-rules.js +14 -188
- package/dist/commands/doctor.js +5 -4
- package/dist/commands/identity.js +29 -32
- package/dist/commands/init.js +304 -20
- package/dist/commands/log.js +134 -0
- package/dist/commands/models/fallbacks.js +1 -1
- package/dist/commands/models/image-fallbacks.js +1 -1
- package/dist/commands/models/list.js +1 -1
- package/dist/commands/models/scan.js +1 -1
- package/dist/commands/onboard-auth.js +27 -2
- package/dist/commands/onboard-eve-identity.js +8 -9
- package/dist/commands/onboard-non-interactive.js +4 -2
- package/dist/commands/onboard-quickstart.js +18 -11
- package/dist/commands/quest-state.js +271 -0
- package/dist/commands/quest.js +53 -13
- package/dist/commands/reset.js +1 -1
- package/dist/commands/sessions-ingest.js +5 -4
- package/dist/commands/setup.js +4 -2
- package/dist/commands/skills-manifest.js +89 -29
- package/dist/commands/status.js +193 -73
- package/dist/commands/suggestions.js +1 -1
- package/dist/commands/usage-tracking.js +32 -0
- package/dist/commands/usage-upload.js +6 -1
- package/dist/config/defaults.js +1 -3
- package/dist/config/includes.js +5 -7
- package/dist/config/io.js +88 -16
- package/dist/config/legacy.js +4 -2
- package/dist/config/paths.js +16 -0
- package/dist/config/sessions.js +9 -5
- package/dist/config/zod-schema.js +4 -3
- package/dist/control-plane/broker/broker.js +131 -78
- package/dist/control-plane/compaction.js +3 -5
- package/dist/control-plane/factory.js +2 -2
- package/dist/control-plane/index.js +2 -2
- package/dist/control-plane/odu/agents.js +28 -23
- package/dist/control-plane/odu/interaction-tools.js +62 -50
- package/dist/control-plane/odu/prompt-loader.js +8 -8
- package/dist/control-plane/odu/runtime.js +87 -75
- package/dist/control-plane/odu-control-plane.js +14 -12
- package/dist/control-plane/single-agent.js +13 -13
- package/dist/credentials/store.js +133 -7
- package/dist/daemon/launchd.js +14 -0
- package/dist/entry.js +0 -0
- package/dist/gateway/server-browser.js +5 -4
- package/dist/gateway/server-methods/cron.js +11 -1
- package/dist/gateway/server.js +14 -7
- package/dist/infra/bonjour.js +1 -1
- package/dist/infra/event-log.js +8 -2
- package/dist/infra/path-env.js +1 -2
- package/dist/infra/provider-usage.auth.js +5 -3
- package/dist/infra/provider-usage.fetch.claude.js +16 -6
- package/dist/infra/provider-usage.fetch.minimax.js +8 -3
- package/dist/infra/provider-usage.js +9 -5
- package/dist/infra/restart.js +2 -2
- package/dist/infra/usage-settings.js +78 -0
- package/dist/infra/usage-suggestions.js +17 -5
- package/dist/infra/usage-upload.js +38 -1
- package/dist/infra/voicewake.js +2 -2
- package/dist/media/image-ops.js +3 -1
- package/dist/memory/index.js +2 -381
- package/dist/native/nexus-cloud/darwin-arm64/nexus-cloud +0 -0
- package/dist/native/nexus-cloud/darwin-arm64/nexus-cloud-rs +0 -0
- package/dist/pairing/pairing-store.js +24 -0
- package/dist/providers/github-copilot-auth.js +1 -1
- package/dist/routing/resolve-route.js +6 -6
- package/dist/routing/session-key.js +3 -1
- package/dist/sessions/send-policy.js +5 -5
- package/dist/slack/monitor.js +22 -1
- package/dist/telegram/reaction-level.js +2 -1
- package/dist/utils.js +8 -3
- package/dist/wizard/onboarding.js +29 -7
- package/docs/AGENTS.default.md +1 -1
- package/docs/configuration.md +1 -1
- package/docs/feature-inventory/overview.md +2 -2
- package/docs/reference/templates/AGENTS.md +172 -109
- package/docs/templates/AGENTS.md +140 -199
- package/docs/templates/BOOTSTRAP.md +40 -20
- package/docs/templates/IDENTITY.md +6 -0
- package/docs/templates/USER.md +22 -2
- package/package.json +3 -1
- package/skills/{notion → connectors/notion}/SKILL.md +1 -1
- package/skills/{filesystem → guides/filesystem}/SKILL.md +1 -1
- package/skills/{onboarding → guides/onboarding}/SKILL.md +1 -1
- package/skills/{onboarding → guides/onboarding}/docs/CAPABILITY_TAXONOMY.md +5 -5
- package/skills/{onboarding → guides/onboarding}/docs/CLI_GRAMMAR.md +8 -8
- package/skills/{onboarding → guides/onboarding}/docs/CLI_GRAMMAR_ONBOARDING.md +2 -2
- package/skills/{onboarding → guides/onboarding}/docs/CLI_GRAMMAR_SKILLS.md +26 -20
- package/skills/{onboarding → guides/onboarding}/docs/GOAL_STATE_ARCHITECTURE.md +38 -43
- package/skills/{onboarding → guides/onboarding}/docs/NEXUS_SYSTEM_OVERVIEW.md +4 -4
- package/skills/{onboarding → guides/onboarding}/docs/SKILLS_HUB_SPEC.md +1 -1
- package/skills/{onboarding → guides/onboarding}/docs/SKILLS_SPECIFICATION.md +8 -7
- package/skills/{onboarding → guides/onboarding}/docs/SKILL_GATEWAY_DESIGN.md +16 -16
- package/skills/{onboarding → guides/onboarding}/docs/SKILL_GATEWAY_PRD.md +10 -12
- package/skills/guides/onboarding/docs/canonical/00_CONFLICT_ANALYSIS.md +463 -0
- package/skills/guides/onboarding/docs/canonical/01_NEXUS_OVERVIEW.md +167 -0
- package/skills/guides/onboarding/docs/canonical/02_CLI_REFERENCE.md +404 -0
- package/skills/guides/onboarding/docs/canonical/03_STATE_ARCHITECTURE.md +357 -0
- package/skills/guides/onboarding/docs/canonical/04_SKILL_SPECIFICATION.md +393 -0
- package/skills/guides/onboarding/docs/canonical/05_CAPABILITY_TAXONOMY.md +298 -0
- package/skills/guides/onboarding/docs/canonical/06_CAPABILITIES_REFERENCE.md +207 -0
- package/skills/guides/onboarding/docs/canonical/07_AGENT_BINDINGS.md +85 -0
- package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/nexus-cloud.md +2 -2
- package/skills/{onboarding → guides/onboarding}/scripts/ralph/progress.txt +1 -1
- package/skills/{nexus-cloud → tools/nexus-cloud}/SKILL.md +2 -1
- package/skills/{nexus-cloud → tools/nexus-cloud}/docs/setup.md +1 -1
- package/docs/templates/PROFILE.md +0 -14
- /package/skills/{brave-search → connectors/brave-search}/SKILL.md +0 -0
- /package/skills/{brave-search → connectors/brave-search}/docs/setup.md +0 -0
- /package/skills/{brave-search → connectors/brave-search}/docs/troubleshooting.md +0 -0
- /package/skills/{brave-search → connectors/brave-search}/docs/usage.md +0 -0
- /package/skills/{brave-search → connectors/brave-search}/scripts/content.mjs +0 -0
- /package/skills/{brave-search → connectors/brave-search}/scripts/search.mjs +0 -0
- /package/skills/{discord → connectors/discord}/SKILL.md +0 -0
- /package/skills/{gemini → connectors/gemini}/SKILL.md +0 -0
- /package/skills/{github → connectors/github}/SKILL.md +0 -0
- /package/skills/{github → connectors/github}/docs/setup.md +0 -0
- /package/skills/{github → connectors/github}/docs/troubleshooting.md +0 -0
- /package/skills/{google-oauth → connectors/google-oauth}/SKILL.md +0 -0
- /package/skills/{slack → connectors/slack}/SKILL.md +0 -0
- /package/skills/{telegram → connectors/telegram}/SKILL.md +0 -0
- /package/skills/{telegram → connectors/telegram}/docs/pairing.md +0 -0
- /package/skills/{telegram → connectors/telegram}/docs/setup.md +0 -0
- /package/skills/{telegram → connectors/telegram}/docs/webhook.md +0 -0
- /package/skills/{wacli → connectors/wacli}/SKILL.md +0 -0
- /package/skills/{wacli → connectors/wacli}/docs/auth.md +0 -0
- /package/skills/{wacli → connectors/wacli}/docs/backup.md +0 -0
- /package/skills/{wacli → connectors/wacli}/docs/troubleshooting.md +0 -0
- /package/skills/{browser-use-agent-sdk → guides/browser-use-agent-sdk}/SKILL.md +0 -0
- /package/skills/{json-render → guides/json-render}/SKILL.md +0 -0
- /package/skills/{json-render → guides/json-render}/assets/components/README.md +0 -0
- /package/skills/{json-render → guides/json-render}/assets/components/catalog.ts +0 -0
- /package/skills/{json-render → guides/json-render}/assets/components/registry.tsx +0 -0
- /package/skills/{json-render → guides/json-render}/assets/demo/App.css +0 -0
- /package/skills/{json-render → guides/json-render}/assets/demo/App.tsx +0 -0
- /package/skills/{json-render → guides/json-render}/assets/demo/README.md +0 -0
- /package/skills/{json-render → guides/json-render}/assets/demo/catalog.ts +0 -0
- /package/skills/{json-render → guides/json-render}/assets/demo/data/nexus-core.json +0 -0
- /package/skills/{json-render → guides/json-render}/assets/demo/index.css +0 -0
- /package/skills/{json-render → guides/json-render}/assets/demo/registry.tsx +0 -0
- /package/skills/{json-render → guides/json-render}/docs/nexus-state-demo.md +0 -0
- /package/skills/{json-render → guides/json-render}/docs/shadcn-preset.md +0 -0
- /package/skills/{json-render → guides/json-render}/scripts/create-vite-demo.sh +0 -0
- /package/skills/{json-render → guides/json-render}/scripts/llm-server/README.md +0 -0
- /package/skills/{json-render → guides/json-render}/scripts/llm-server/catalog.ts +0 -0
- /package/skills/{json-render → guides/json-render}/scripts/llm-server/package-lock.json +0 -0
- /package/skills/{json-render → guides/json-render}/scripts/llm-server/package.json +0 -0
- /package/skills/{json-render → guides/json-render}/scripts/llm-server/server.ts +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/CAPABILITIES.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/CLI_GRAMMAR_CREDENTIALS.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/DOCUMENTATION_OVERVIEW.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/ENTITY_MODEL.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/SKILL_INVENTORY.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/STATE_ARCHITECTURE.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/TROUBLESHOOTING.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/USER_JOURNEY.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/WOW_MOMENTS.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/agent-apple-id.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/1password.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/TEMPLATE.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/aix.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/bird.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/brave-search.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/comms.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/computer-use.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/cron-and-heartbeat.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/eve.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/github.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/gog.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/homebrew-prereqs.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/qmd.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/telegram.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/wacli.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/weather.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/scripts/ralph/prd.json +0 -0
- /package/skills/{onboarding → guides/onboarding}/scripts/ralph/prompt.md +0 -0
- /package/skills/{onboarding → guides/onboarding}/scripts/ralph/ralph.log +0 -0
- /package/skills/{onboarding → guides/onboarding}/scripts/ralph/ralph.sh +0 -0
- /package/skills/{onboarding → guides/onboarding}/scripts/setup-cursor-skills.sh +0 -0
- /package/skills/{1password → tools/1password}/SKILL.md +0 -0
- /package/skills/{1password → tools/1password}/docs/setup.md +0 -0
- /package/skills/{1password → tools/1password}/docs/troubleshooting.md +0 -0
- /package/skills/{1password → tools/1password}/references/cli-examples.md +0 -0
- /package/skills/{1password → tools/1password}/references/get-started.md +0 -0
- /package/skills/{agent-browser → tools/agent-browser}/SKILL.md +0 -0
- /package/skills/{agent-browser → tools/agent-browser}/docs/browser-use-eval.md +0 -0
- /package/skills/{agent-browser → tools/agent-browser}/docs/first-tests.md +0 -0
- /package/skills/{agent-browser → tools/agent-browser}/docs/wordle-nyt-eval.js +0 -0
- /package/skills/{aix → tools/aix}/SKILL.md +0 -0
- /package/skills/{aix → tools/aix}/docs/embeddings.md +0 -0
- /package/skills/{aix → tools/aix}/docs/setup.md +0 -0
- /package/skills/{aix → tools/aix}/docs/troubleshooting.md +0 -0
- /package/skills/{aix → tools/aix}/references/sql.md +0 -0
- /package/skills/{apple-notes → tools/apple-notes}/SKILL.md +0 -0
- /package/skills/{apple-reminders → tools/apple-reminders}/SKILL.md +0 -0
- /package/skills/{bear-notes → tools/bear-notes}/SKILL.md +0 -0
- /package/skills/{bird → tools/bird}/SKILL.md +0 -0
- /package/skills/{bird → tools/bird}/docs/auth.md +0 -0
- /package/skills/{bird → tools/bird}/docs/troubleshooting.md +0 -0
- /package/skills/{blogwatcher → tools/blogwatcher}/SKILL.md +0 -0
- /package/skills/{blucli → tools/blucli}/SKILL.md +0 -0
- /package/skills/{camsnap → tools/camsnap}/SKILL.md +0 -0
- /package/skills/{clawdhub → tools/clawdhub}/SKILL.md +0 -0
- /package/skills/{coding-agent → tools/coding-agent}/SKILL.md +0 -0
- /package/skills/{comms → tools/comms}/SKILL.md +0 -0
- /package/skills/{comms → tools/comms}/docs/adapters.md +0 -0
- /package/skills/{comms → tools/comms}/docs/setup.md +0 -0
- /package/skills/{comms → tools/comms}/docs/troubleshooting.md +0 -0
- /package/skills/{comms → tools/comms}/references/schema.md +0 -0
- /package/skills/{computer-use → tools/computer-use}/SKILL.md +0 -0
- /package/skills/{computer-use → tools/computer-use}/docs/open-interpreter.md +0 -0
- /package/skills/{computer-use → tools/computer-use}/docs/peekaboo.md +0 -0
- /package/skills/{computer-use → tools/computer-use}/docs/setup.md +0 -0
- /package/skills/{computer-use → tools/computer-use}/docs/troubleshooting.md +0 -0
- /package/skills/{eightctl → tools/eightctl}/SKILL.md +0 -0
- /package/skills/{eve → tools/eve}/SKILL.md +0 -0
- /package/skills/{eve → tools/eve}/docs/dual-account.md +0 -0
- /package/skills/{eve → tools/eve}/docs/intelligence.md +0 -0
- /package/skills/{eve → tools/eve}/docs/setup.md +0 -0
- /package/skills/{eve → tools/eve}/docs/troubleshooting.md +0 -0
- /package/skills/{eve → tools/eve}/scripts/setup-dual-account.sh +0 -0
- /package/skills/{food-order → tools/food-order}/SKILL.md +0 -0
- /package/skills/{gh → tools/gh}/SKILL.md +0 -0
- /package/skills/{gh → tools/gh}/docs/usage.md +0 -0
- /package/skills/{gifgrep → tools/gifgrep}/SKILL.md +0 -0
- /package/skills/{gog → tools/gog}/SKILL.md +0 -0
- /package/skills/{gog → tools/gog}/docs/portability.md +0 -0
- /package/skills/{gog → tools/gog}/docs/setup.md +0 -0
- /package/skills/{gog → tools/gog}/docs/troubleshooting.md +0 -0
- /package/skills/{gog → tools/gog}/scripts/cdp/README.md +0 -0
- /package/skills/{gog → tools/gog}/scripts/cdp/add_test_users.py +0 -0
- /package/skills/{gog → tools/gog}/scripts/cdp/auth_add_accounts.py +0 -0
- /package/skills/{gog → tools/gog}/scripts/cdp/auth_add_accounts_manual.py +0 -0
- /package/skills/{gog → tools/gog}/scripts/cdp/create_oauth_client.py +0 -0
- /package/skills/{gog → tools/gog}/scripts/cdp/launch_cdp_chrome.sh +0 -0
- /package/skills/{goplaces → tools/goplaces}/SKILL.md +0 -0
- /package/skills/{imsg → tools/imsg}/SKILL.md +0 -0
- /package/skills/{local-places → tools/local-places}/SERVER_README.md +0 -0
- /package/skills/{local-places → tools/local-places}/SKILL.md +0 -0
- /package/skills/{local-places → tools/local-places}/pyproject.toml +0 -0
- /package/skills/{local-places → tools/local-places}/src/local_places/__init__.py +0 -0
- /package/skills/{local-places → tools/local-places}/src/local_places/__pycache__/__init__.cpython-314.pyc +0 -0
- /package/skills/{local-places → tools/local-places}/src/local_places/__pycache__/google_places.cpython-314.pyc +0 -0
- /package/skills/{local-places → tools/local-places}/src/local_places/__pycache__/main.cpython-314.pyc +0 -0
- /package/skills/{local-places → tools/local-places}/src/local_places/__pycache__/schemas.cpython-314.pyc +0 -0
- /package/skills/{local-places → tools/local-places}/src/local_places/google_places.py +0 -0
- /package/skills/{local-places → tools/local-places}/src/local_places/main.py +0 -0
- /package/skills/{local-places → tools/local-places}/src/local_places/schemas.py +0 -0
- /package/skills/{mcporter → tools/mcporter}/SKILL.md +0 -0
- /package/skills/{model-usage → tools/model-usage}/SKILL.md +0 -0
- /package/skills/{model-usage → tools/model-usage}/references/codexbar-cli.md +0 -0
- /package/skills/{model-usage → tools/model-usage}/scripts/model_usage.py +0 -0
- /package/skills/{nano-banana-pro → tools/nano-banana-pro}/SKILL.md +0 -0
- /package/skills/{nano-banana-pro → tools/nano-banana-pro}/scripts/generate_image.py +0 -0
- /package/skills/{nano-pdf → tools/nano-pdf}/SKILL.md +0 -0
- /package/skills/{nexus-cloud → tools/nexus-cloud}/docs/security.md +0 -0
- /package/skills/{nexus-cloud → tools/nexus-cloud}/docs/troubleshooting.md +0 -0
- /package/skills/{obsidian → tools/obsidian}/SKILL.md +0 -0
- /package/skills/{openai-image-gen → tools/openai-image-gen}/SKILL.md +0 -0
- /package/skills/{openai-image-gen → tools/openai-image-gen}/scripts/gen.py +0 -0
- /package/skills/{openai-whisper → tools/openai-whisper}/SKILL.md +0 -0
- /package/skills/{openai-whisper-api → tools/openai-whisper-api}/SKILL.md +0 -0
- /package/skills/{openai-whisper-api → tools/openai-whisper-api}/scripts/transcribe.sh +0 -0
- /package/skills/{openhue → tools/openhue}/SKILL.md +0 -0
- /package/skills/{oracle → tools/oracle}/SKILL.md +0 -0
- /package/skills/{ordercli → tools/ordercli}/SKILL.md +0 -0
- /package/skills/{peekaboo → tools/peekaboo}/SKILL.md +0 -0
- /package/skills/{qmd → tools/qmd}/SKILL.md +0 -0
- /package/skills/{qmd → tools/qmd}/docs/mcp.md +0 -0
- /package/skills/{qmd → tools/qmd}/docs/ollama.md +0 -0
- /package/skills/{qmd → tools/qmd}/docs/setup.md +0 -0
- /package/skills/{sag → tools/sag}/SKILL.md +0 -0
- /package/skills/{skill-cli-template → tools/skill-cli-template}/SKILL.md +0 -0
- /package/skills/{songsee → tools/songsee}/SKILL.md +0 -0
- /package/skills/{sonoscli → tools/sonoscli}/SKILL.md +0 -0
- /package/skills/{spotify-player → tools/spotify-player}/SKILL.md +0 -0
- /package/skills/{summarize → tools/summarize}/SKILL.md +0 -0
- /package/skills/{things-mac → tools/things-mac}/SKILL.md +0 -0
- /package/skills/{tmux → tools/tmux}/SKILL.md +0 -0
- /package/skills/{tmux → tools/tmux}/scripts/find-sessions.sh +0 -0
- /package/skills/{tmux → tools/tmux}/scripts/wait-for-text.sh +0 -0
- /package/skills/{trello → tools/trello}/SKILL.md +0 -0
- /package/skills/{upstream-sync → tools/upstream-sync}/SKILL.md +0 -0
- /package/skills/{upstream-sync → tools/upstream-sync}/scripts/auto-port.sh +0 -0
- /package/skills/{upstream-sync → tools/upstream-sync}/scripts/check-all.sh +0 -0
- /package/skills/{upstream-sync → tools/upstream-sync}/scripts/check-nexus.sh +0 -0
- /package/skills/{upstream-sync → tools/upstream-sync}/scripts/check-pi-ai.sh +0 -0
- /package/skills/{video-frames → tools/video-frames}/SKILL.md +0 -0
- /package/skills/{video-frames → tools/video-frames}/scripts/frame.sh +0 -0
- /package/skills/{weather → tools/weather}/SKILL.md +0 -0
- /package/skills/{weather → tools/weather}/docs/usage.md +0 -0
package/dist/commands/status.js
CHANGED
|
@@ -1,131 +1,251 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import
|
|
2
|
+
import { resolveIdentitySnapshot } from "../agents/identity-state.js";
|
|
3
|
+
import { getAggregateStats } from "../agents/skill-usage.js";
|
|
3
4
|
import { detectCapabilities } from "../capabilities/detector.js";
|
|
4
|
-
import { listCredentials } from "./credential.js";
|
|
5
|
-
import { resolveStateDir } from "../config/paths.js";
|
|
6
5
|
import { defaultRuntime } from "../runtime.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
return undefined;
|
|
16
|
-
}
|
|
6
|
+
import { listCredentials } from "./credential.js";
|
|
7
|
+
const STATUS_BOX_WIDTH = 62;
|
|
8
|
+
function clampText(text, width) {
|
|
9
|
+
if (text.length <= width)
|
|
10
|
+
return text;
|
|
11
|
+
return text.slice(0, width);
|
|
17
12
|
}
|
|
18
|
-
function
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const agentIdentityPath = path.join(agentIdentityDir, "IDENTITY.md");
|
|
25
|
-
const agentSoulPath = path.join(agentIdentityDir, "SOUL.md");
|
|
26
|
-
const agentMemoryPath = path.join(agentIdentityDir, "MEMORY.md");
|
|
27
|
-
const userProfilePath = path.join(userIdentityDir, "PROFILE.md");
|
|
28
|
-
const bootstrapPath = path.join(onboardingDir, "BOOTSTRAP.md");
|
|
29
|
-
const hasIdentity = fs.existsSync(agentIdentityPath) && fs.existsSync(userProfilePath);
|
|
30
|
-
const agentName = readField(agentIdentityPath, "Name");
|
|
31
|
-
const userName = readField(userProfilePath, "Name");
|
|
32
|
-
return {
|
|
33
|
-
agentId,
|
|
34
|
-
agentName,
|
|
35
|
-
userName,
|
|
36
|
-
agentIdentityPath,
|
|
37
|
-
agentSoulPath,
|
|
38
|
-
agentMemoryPath,
|
|
39
|
-
userProfilePath,
|
|
40
|
-
bootstrapPath,
|
|
41
|
-
hasIdentity,
|
|
42
|
-
};
|
|
13
|
+
function centerText(text, width) {
|
|
14
|
+
const clamped = clampText(text, width);
|
|
15
|
+
const pad = Math.max(0, width - clamped.length);
|
|
16
|
+
const left = Math.floor(pad / 2);
|
|
17
|
+
const right = pad - left;
|
|
18
|
+
return `${" ".repeat(left)}${clamped}${" ".repeat(right)}`;
|
|
43
19
|
}
|
|
20
|
+
function renderBox(lines, width) {
|
|
21
|
+
const top = `╔${"═".repeat(width)}╗`;
|
|
22
|
+
const bottom = `╚${"═".repeat(width)}╝`;
|
|
23
|
+
const body = lines.map((line) => `║${centerText(line, width)}║`);
|
|
24
|
+
return [top, ...body, bottom];
|
|
25
|
+
}
|
|
26
|
+
const FALLBACK_BOOTSTRAP_PROMPT = `# BOOTSTRAP.md - Welcome to Nexus
|
|
27
|
+
|
|
28
|
+
Identity setup is required.
|
|
29
|
+
|
|
30
|
+
For humans: start a short conversation and share your name, goals, and preferences.
|
|
31
|
+
For agents: write IDENTITY.md, SOUL.md, and MEMORY.md for the agent, plus state/user/IDENTITY.md for the user.
|
|
32
|
+
`;
|
|
44
33
|
function readBootstrapPrompt(pathname) {
|
|
45
34
|
try {
|
|
46
35
|
return fs.readFileSync(pathname, "utf-8");
|
|
47
36
|
}
|
|
48
37
|
catch {
|
|
49
|
-
return
|
|
38
|
+
return FALLBACK_BOOTSTRAP_PROMPT;
|
|
50
39
|
}
|
|
51
40
|
}
|
|
52
41
|
function formatSuggestions(capabilities) {
|
|
53
42
|
const picks = capabilities.filter((cap) => ["ready", "needs_setup", "needs_install", "broken"].includes(cap.status));
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
43
|
+
const priority = ["broken", "ready", "needs_setup", "needs_install"];
|
|
44
|
+
const sorted = picks.sort((a, b) => priority.indexOf(a.status) - priority.indexOf(b.status));
|
|
45
|
+
return sorted.slice(0, 3).map((cap, idx) => {
|
|
46
|
+
const action = cap.status === "broken"
|
|
47
|
+
? "nexus credential list"
|
|
48
|
+
: `nexus capabilities --status ${cap.status.replace("_", "-")}`;
|
|
49
|
+
const title = cap.status === "ready"
|
|
50
|
+
? `Try ${cap.id} (ready, never used)`
|
|
51
|
+
: cap.status === "needs_setup"
|
|
52
|
+
? `Set up ${cap.id}`
|
|
53
|
+
: cap.status === "needs_install"
|
|
54
|
+
? `Install ${cap.id}`
|
|
55
|
+
: `Fix ${cap.id}`;
|
|
56
|
+
return {
|
|
57
|
+
id: cap.id,
|
|
58
|
+
status: cap.status,
|
|
59
|
+
index: idx + 1,
|
|
60
|
+
title,
|
|
61
|
+
action,
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function reindexSuggestions(suggestions) {
|
|
66
|
+
return suggestions.map((suggestion, idx) => ({
|
|
67
|
+
...suggestion,
|
|
58
68
|
index: idx + 1,
|
|
59
69
|
}));
|
|
60
70
|
}
|
|
61
71
|
export async function statusCommand(opts, runtime = defaultRuntime) {
|
|
62
|
-
const
|
|
72
|
+
const identityResolution = resolveIdentitySnapshot();
|
|
73
|
+
if (!identityResolution.ok) {
|
|
74
|
+
const payload = {
|
|
75
|
+
ok: false,
|
|
76
|
+
error: "multiple_agents",
|
|
77
|
+
agents: identityResolution.agentOptions,
|
|
78
|
+
};
|
|
79
|
+
if (opts.json) {
|
|
80
|
+
runtime.log(JSON.stringify(payload, null, 2));
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
runtime.error("Multiple agents detected in state/agents.");
|
|
84
|
+
runtime.error(`Set NEXUS_AGENT_ID to one of: ${identityResolution.agentOptions.join(", ")}`);
|
|
85
|
+
}
|
|
86
|
+
runtime.exit(2);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const identity = identityResolution.snapshot;
|
|
63
90
|
const bootstrapPrompt = !identity.hasIdentity
|
|
64
91
|
? readBootstrapPrompt(identity.bootstrapPath)
|
|
65
92
|
: null;
|
|
66
93
|
const showBrief = opts.brief === true;
|
|
67
94
|
const showCredentials = opts.credentials === true || (!opts.capabilities && !showBrief);
|
|
68
95
|
const showCapabilities = opts.capabilities === true || (!opts.credentials && !showBrief);
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
const
|
|
96
|
+
const showUsage = opts.usage === true ||
|
|
97
|
+
(!showBrief && !opts.capabilities && !opts.credentials);
|
|
98
|
+
const shouldLoadCredentials = showCredentials || !showBrief;
|
|
99
|
+
const shouldLoadCapabilities = showCapabilities || !showBrief;
|
|
100
|
+
const credentials = shouldLoadCredentials ? await listCredentials() : null;
|
|
101
|
+
const capabilitySnapshot = shouldLoadCapabilities
|
|
102
|
+
? detectCapabilities()
|
|
103
|
+
: null;
|
|
104
|
+
const suggestions = capabilitySnapshot
|
|
105
|
+
? formatSuggestions(capabilitySnapshot.capabilities)
|
|
106
|
+
: [];
|
|
107
|
+
const usage = showUsage
|
|
108
|
+
? await getAggregateStats({ windowDays: 7, limit: 3 })
|
|
109
|
+
: null;
|
|
110
|
+
if (opts.quiet) {
|
|
111
|
+
runtime.exit(bootstrapPrompt ? 2 : 0);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
72
114
|
if (opts.json) {
|
|
73
115
|
runtime.log(JSON.stringify({
|
|
74
116
|
platform: `${process.platform}/${process.arch}`,
|
|
75
117
|
identity,
|
|
76
|
-
bootstrap: bootstrapPrompt
|
|
118
|
+
bootstrap: bootstrapPrompt
|
|
119
|
+
? { required: true, prompt: bootstrapPrompt }
|
|
120
|
+
: undefined,
|
|
77
121
|
credentials: credentials ?? undefined,
|
|
78
122
|
capabilities: capabilitySnapshot ?? undefined,
|
|
79
123
|
suggestions,
|
|
124
|
+
usage: usage ?? undefined,
|
|
80
125
|
}, null, 2));
|
|
81
126
|
return;
|
|
82
127
|
}
|
|
83
|
-
|
|
128
|
+
for (const line of renderBox(["Nexus Status", `${process.platform}/${process.arch}`], STATUS_BOX_WIDTH)) {
|
|
129
|
+
runtime.log(line);
|
|
130
|
+
}
|
|
84
131
|
if (bootstrapPrompt) {
|
|
85
|
-
runtime.log("
|
|
132
|
+
runtime.log("");
|
|
133
|
+
for (const line of renderBox(["Welcome to Nexus!", "Identity setup required."], STATUS_BOX_WIDTH)) {
|
|
134
|
+
runtime.log(line);
|
|
135
|
+
}
|
|
86
136
|
runtime.log(`\nBootstrap prompt (${identity.bootstrapPath}):\n`);
|
|
87
137
|
runtime.log(bootstrapPrompt.trimEnd());
|
|
88
138
|
return;
|
|
89
139
|
}
|
|
90
|
-
runtime.log("\
|
|
91
|
-
runtime.log(` User: ${identity.userName ?? "(unknown)"} → ${identity.
|
|
140
|
+
runtime.log("\n👤 Identity");
|
|
141
|
+
runtime.log(` User: ${identity.userName ?? "(unknown)"} → ${identity.userIdentityPath}`);
|
|
92
142
|
runtime.log(` Agent: ${identity.agentName ?? "(unknown)"} (${identity.agentId}) → ${identity.agentIdentityPath}`);
|
|
93
143
|
runtime.log(` → ${identity.agentSoulPath}`);
|
|
94
|
-
|
|
144
|
+
const credentialServices = credentials
|
|
145
|
+
? Object.entries(credentials.services ?? {})
|
|
146
|
+
: [];
|
|
147
|
+
const credentialAccountCount = credentialServices.reduce((sum, [, info]) => sum + (info.accounts?.length ?? 0), 0);
|
|
95
148
|
if (showCredentials && credentials) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
149
|
+
runtime.log(`\n🔑 Credentials (${credentialAccountCount} configured)`);
|
|
150
|
+
const statusIcon = {
|
|
151
|
+
active: "✅",
|
|
152
|
+
ready: "⭐",
|
|
153
|
+
broken: "❌",
|
|
154
|
+
};
|
|
155
|
+
const maxServices = 6;
|
|
156
|
+
const visibleServices = credentialServices.slice(0, maxServices);
|
|
157
|
+
for (const [service, info] of visibleServices) {
|
|
99
158
|
const accounts = info.accounts ?? [];
|
|
100
|
-
|
|
101
|
-
|
|
159
|
+
if (accounts.length === 0) {
|
|
160
|
+
runtime.log(` ${service}: none`);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
runtime.log(` ${service}`);
|
|
164
|
+
for (const account of accounts) {
|
|
165
|
+
const status = account.status ?? "ready";
|
|
166
|
+
const icon = statusIcon[status] ?? "•";
|
|
167
|
+
const suffix = account.lastError ? ` - ${account.lastError}` : "";
|
|
168
|
+
runtime.log(` ${icon} ${account.id} (${status})${suffix}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (credentialServices.length > maxServices) {
|
|
172
|
+
runtime.log(` … +${credentialServices.length - maxServices} more services`);
|
|
102
173
|
}
|
|
174
|
+
runtime.log(` Run 'nexus credential list' for full details`);
|
|
103
175
|
}
|
|
104
176
|
if (showCapabilities && capabilitySnapshot) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
177
|
+
const { summary } = capabilitySnapshot;
|
|
178
|
+
runtime.log("\n🎯 Capabilities");
|
|
179
|
+
runtime.log(` ✅ active: ${summary.active} ⭐ ready: ${summary.ready} 🔧 needs-setup: ${summary.needs_setup} 📥 needs-install: ${summary.needs_install}`);
|
|
180
|
+
if (summary.broken > 0) {
|
|
181
|
+
runtime.log(` ❌ broken: ${summary.broken}`);
|
|
182
|
+
}
|
|
183
|
+
if (summary.unavailable > 0) {
|
|
184
|
+
runtime.log(` ⛔ unavailable: ${summary.unavailable}`);
|
|
185
|
+
}
|
|
186
|
+
const quickWins = capabilitySnapshot.capabilities
|
|
187
|
+
.filter((cap) => cap.status === "ready")
|
|
188
|
+
.slice(0, 4);
|
|
189
|
+
if (quickWins.length > 0) {
|
|
190
|
+
runtime.log(" Quick wins:");
|
|
191
|
+
for (const cap of quickWins) {
|
|
114
192
|
const providers = cap.providers.map((p) => p.id).join(", ");
|
|
115
|
-
runtime.log(` - ${cap.id}
|
|
193
|
+
runtime.log(` - ${cap.id}${providers ? ` (${providers})` : ""}`);
|
|
116
194
|
}
|
|
117
195
|
}
|
|
196
|
+
runtime.log(` Run 'nexus capabilities' for the full map`);
|
|
197
|
+
}
|
|
198
|
+
if (showUsage && usage) {
|
|
199
|
+
runtime.log("\n📊 Usage (last 7 days)");
|
|
200
|
+
const mostUsed = usage.topUsed && usage.topUsed.length > 0
|
|
201
|
+
? usage.topUsed
|
|
202
|
+
.map((item) => `${item.name} (${item.runs})`)
|
|
203
|
+
.join(", ")
|
|
204
|
+
: usage.mostUsed
|
|
205
|
+
? `${usage.mostUsed.name} (${usage.mostUsed.runs})`
|
|
206
|
+
: "none";
|
|
207
|
+
const readyUnused = usage.readyButUnused && usage.readyButUnused.length > 0
|
|
208
|
+
? usage.readyButUnused.join(", ")
|
|
209
|
+
: "none";
|
|
210
|
+
runtime.log(` Most used: ${mostUsed}`);
|
|
211
|
+
runtime.log(` Ready but unused: ${readyUnused}`);
|
|
118
212
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
213
|
+
let finalSuggestions = suggestions;
|
|
214
|
+
if (showCredentials && credentials && credentialAccountCount === 0) {
|
|
215
|
+
finalSuggestions = [
|
|
216
|
+
{
|
|
217
|
+
id: "credentials",
|
|
218
|
+
status: "ready",
|
|
219
|
+
index: 1,
|
|
220
|
+
title: "Set up credentials",
|
|
221
|
+
action: "nexus credential scan --deep",
|
|
222
|
+
},
|
|
223
|
+
...finalSuggestions,
|
|
224
|
+
];
|
|
225
|
+
}
|
|
226
|
+
finalSuggestions = reindexSuggestions(finalSuggestions).slice(0, 3);
|
|
227
|
+
if (finalSuggestions.length > 0) {
|
|
228
|
+
runtime.log("\n🎯 Suggestions");
|
|
229
|
+
for (const suggestion of finalSuggestions) {
|
|
230
|
+
runtime.log(` ${suggestion.index}. ${suggestion.title}`);
|
|
231
|
+
runtime.log(` → ${suggestion.action}`);
|
|
123
232
|
}
|
|
124
233
|
}
|
|
125
234
|
runtime.log(`\nNext: run 'nexus capabilities' or 'nexus credential list' for details.`);
|
|
126
235
|
}
|
|
127
236
|
export async function getStatusSummary() {
|
|
128
|
-
const
|
|
237
|
+
const resolution = resolveIdentitySnapshot();
|
|
238
|
+
if (!resolution.ok) {
|
|
239
|
+
return {
|
|
240
|
+
ok: false,
|
|
241
|
+
platform: `${process.platform}/${process.arch}`,
|
|
242
|
+
identity: {
|
|
243
|
+
agentId: "unknown",
|
|
244
|
+
hasIdentity: false,
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
const identity = resolution.snapshot;
|
|
129
249
|
return {
|
|
130
250
|
ok: true,
|
|
131
251
|
platform: `${process.platform}/${process.arch}`,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { fetchUsageTrackingSettings, updateUsageTrackingSettings, } from "../infra/usage-settings.js";
|
|
2
|
+
import { defaultRuntime } from "../runtime.js";
|
|
3
|
+
export async function usageTrackingCommand(opts, runtime = defaultRuntime) {
|
|
4
|
+
if (opts.enable && opts.disable) {
|
|
5
|
+
runtime.error("Choose either --enable or --disable.");
|
|
6
|
+
runtime.exit(1);
|
|
7
|
+
}
|
|
8
|
+
const requestedOptOut = opts.disable ? true : opts.enable ? false : null;
|
|
9
|
+
const result = requestedOptOut === null
|
|
10
|
+
? await fetchUsageTrackingSettings()
|
|
11
|
+
: await updateUsageTrackingSettings(requestedOptOut);
|
|
12
|
+
if (!result) {
|
|
13
|
+
runtime.error("Usage tracking settings are unavailable (missing URL or token).");
|
|
14
|
+
runtime.exit(1);
|
|
15
|
+
}
|
|
16
|
+
if (opts.json) {
|
|
17
|
+
runtime.log(JSON.stringify(result, null, 2));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (!result.ok) {
|
|
21
|
+
const errorMessage = result.error === "not_allowed"
|
|
22
|
+
? "Usage tracking is required for free accounts."
|
|
23
|
+
: result.error || "Failed to update usage tracking settings.";
|
|
24
|
+
runtime.error(errorMessage);
|
|
25
|
+
runtime.exit(1);
|
|
26
|
+
}
|
|
27
|
+
if (!result.canOptOut) {
|
|
28
|
+
runtime.log("Usage tracking is required for free accounts.");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
runtime.log(`Usage tracking ${result.optOut ? "disabled" : "enabled"}${result.planName ? ` (${result.planName})` : ""}`);
|
|
32
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defaultRuntime } from "../runtime.js";
|
|
2
1
|
import { runUsageUpload } from "../infra/usage-upload.js";
|
|
2
|
+
import { defaultRuntime } from "../runtime.js";
|
|
3
3
|
export async function usageUploadCommand(opts, runtime = defaultRuntime) {
|
|
4
4
|
const result = await runUsageUpload({
|
|
5
5
|
limit: opts.limit,
|
|
@@ -23,5 +23,10 @@ export async function usageUploadCommand(opts, runtime = defaultRuntime) {
|
|
|
23
23
|
runtime.log(` uploaded: ${result.uploaded ?? 0}`);
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
|
+
if (result.status === "disabled") {
|
|
27
|
+
runtime.log(`\nUsage upload disabled`);
|
|
28
|
+
runtime.log(` cleared_outbox: ${result.cleared ?? 0}`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
26
31
|
runtime.log("\nUsage upload complete");
|
|
27
32
|
}
|
package/dist/config/defaults.js
CHANGED
|
@@ -99,9 +99,7 @@ export function applyModelDefaults(cfg) {
|
|
|
99
99
|
if (Object.keys(existingModels).length === 0)
|
|
100
100
|
return cfg;
|
|
101
101
|
let mutated = false;
|
|
102
|
-
const nextModels = {
|
|
103
|
-
...existingModels,
|
|
104
|
-
};
|
|
102
|
+
const nextModels = { ...existingModels };
|
|
105
103
|
for (const [alias, target] of Object.entries(DEFAULT_MODEL_ALIASES)) {
|
|
106
104
|
const entry = nextModels[target];
|
|
107
105
|
if (!entry)
|
package/dist/config/includes.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @example
|
|
5
5
|
* ```json5
|
|
6
6
|
* {
|
|
7
|
-
* "$include": "./base.json5",
|
|
7
|
+
* "$include": "./base.json5", // single file
|
|
8
8
|
* "$include": ["./a.json5", "./b.json5"] // merge multiple
|
|
9
9
|
* }
|
|
10
10
|
* ```
|
|
@@ -52,7 +52,8 @@ export function deepMerge(target, source) {
|
|
|
52
52
|
if (isPlainObject(target) && isPlainObject(source)) {
|
|
53
53
|
const result = { ...target };
|
|
54
54
|
for (const key of Object.keys(source)) {
|
|
55
|
-
result[key] =
|
|
55
|
+
result[key] =
|
|
56
|
+
key in result ? deepMerge(result[key], source[key]) : source[key];
|
|
56
57
|
}
|
|
57
58
|
return result;
|
|
58
59
|
}
|
|
@@ -92,14 +93,11 @@ class IncludeProcessor {
|
|
|
92
93
|
}
|
|
93
94
|
processInclude(obj) {
|
|
94
95
|
const includeValue = obj[INCLUDE_KEY];
|
|
95
|
-
const otherKeys = Object.keys(obj).filter((
|
|
96
|
+
const otherKeys = Object.keys(obj).filter((key) => key !== INCLUDE_KEY);
|
|
96
97
|
const included = this.resolveInclude(includeValue);
|
|
97
98
|
if (otherKeys.length === 0) {
|
|
98
99
|
return included;
|
|
99
100
|
}
|
|
100
|
-
if (!isPlainObject(included)) {
|
|
101
|
-
throw new ConfigIncludeError("Sibling keys require included content to be an object", typeof includeValue === "string" ? includeValue : INCLUDE_KEY);
|
|
102
|
-
}
|
|
103
101
|
// Merge included content with sibling keys
|
|
104
102
|
const rest = {};
|
|
105
103
|
for (const key of otherKeys) {
|
|
@@ -172,7 +170,7 @@ class IncludeProcessor {
|
|
|
172
170
|
// Public API
|
|
173
171
|
// ============================================================================
|
|
174
172
|
const defaultResolver = {
|
|
175
|
-
readFile: (
|
|
173
|
+
readFile: (filePath) => fs.readFileSync(filePath, "utf-8"),
|
|
176
174
|
parseJson: (raw) => JSON5.parse(raw),
|
|
177
175
|
};
|
|
178
176
|
/**
|
package/dist/config/io.js
CHANGED
|
@@ -4,10 +4,12 @@ import path from "node:path";
|
|
|
4
4
|
import JSON5 from "json5";
|
|
5
5
|
import { loadShellEnvFallback, resolveShellEnvFallbackTimeoutMs, shouldEnableShellEnvFallback, } from "../infra/shell-env.js";
|
|
6
6
|
import { applyIdentityDefaults, applyLoggingDefaults, applyMessageDefaults, applyModelDefaults, applySessionDefaults, applyTalkApiKey, } from "./defaults.js";
|
|
7
|
+
import { ConfigIncludeError, resolveConfigIncludes } from "./includes.js";
|
|
7
8
|
import { findLegacyConfigIssues } from "./legacy.js";
|
|
8
|
-
import {
|
|
9
|
+
import { migrateLegacyConfig } from "./legacy-migrate.js";
|
|
10
|
+
import { resolveConfigPath, resolveStateDir } from "./paths.js";
|
|
9
11
|
import { validateConfigObject } from "./validation.js";
|
|
10
|
-
|
|
12
|
+
export { CircularIncludeError, ConfigIncludeError } from "./includes.js";
|
|
11
13
|
const SHELL_ENV_EXPECTED_KEYS = [
|
|
12
14
|
"OPENAI_API_KEY",
|
|
13
15
|
"ANTHROPIC_API_KEY",
|
|
@@ -23,6 +25,22 @@ const SHELL_ENV_EXPECTED_KEYS = [
|
|
|
23
25
|
"NEXUS_GATEWAY_TOKEN",
|
|
24
26
|
"NEXUS_GATEWAY_PASSWORD",
|
|
25
27
|
];
|
|
28
|
+
function attachChannelAliases(cfg) {
|
|
29
|
+
const channels = cfg.channels ?? {};
|
|
30
|
+
const nextChannels = {
|
|
31
|
+
...channels,
|
|
32
|
+
whatsapp: channels.whatsapp ?? cfg.whatsapp,
|
|
33
|
+
telegram: channels.telegram ?? cfg.telegram,
|
|
34
|
+
discord: channels.discord ?? cfg.discord,
|
|
35
|
+
slack: channels.slack ?? cfg.slack,
|
|
36
|
+
signal: channels.signal ?? cfg.signal,
|
|
37
|
+
imessage: channels.imessage ?? cfg.imessage,
|
|
38
|
+
};
|
|
39
|
+
const hasAny = Object.values(nextChannels).some((value) => value !== undefined);
|
|
40
|
+
if (!hasAny)
|
|
41
|
+
return cfg;
|
|
42
|
+
return { ...cfg, channels: nextChannels };
|
|
43
|
+
}
|
|
26
44
|
function resolveConfigPathForDeps(deps) {
|
|
27
45
|
if (deps.configPath)
|
|
28
46
|
return deps.configPath;
|
|
@@ -48,8 +66,9 @@ export function parseConfigJson5(raw, json5 = JSON5) {
|
|
|
48
66
|
}
|
|
49
67
|
export function createConfigIO(overrides = {}) {
|
|
50
68
|
const deps = normalizeDeps(overrides);
|
|
51
|
-
const
|
|
69
|
+
const resolveConfigPath = () => resolveConfigPathForDeps(deps);
|
|
52
70
|
function loadConfig() {
|
|
71
|
+
const configPath = resolveConfigPath();
|
|
53
72
|
try {
|
|
54
73
|
if (!deps.fs.existsSync(configPath)) {
|
|
55
74
|
if (shouldEnableShellEnvFallback(deps.env)) {
|
|
@@ -65,17 +84,33 @@ export function createConfigIO(overrides = {}) {
|
|
|
65
84
|
}
|
|
66
85
|
const raw = deps.fs.readFileSync(configPath, "utf-8");
|
|
67
86
|
const parsed = deps.json5.parse(raw);
|
|
68
|
-
|
|
87
|
+
const resolved = resolveConfigIncludes(parsed, configPath, {
|
|
88
|
+
readFile: (p) => deps.fs.readFileSync(p, "utf-8"),
|
|
89
|
+
parseJson: (json) => deps.json5.parse(json),
|
|
90
|
+
});
|
|
91
|
+
if (typeof resolved !== "object" || resolved === null)
|
|
69
92
|
return {};
|
|
70
|
-
const
|
|
71
|
-
|
|
93
|
+
const migrated = migrateLegacyConfig(resolved);
|
|
94
|
+
const candidate = migrated.config ?? resolved;
|
|
95
|
+
const validated = validateConfigObject(candidate);
|
|
96
|
+
if (!validated.ok) {
|
|
72
97
|
deps.logger.error("Invalid config:");
|
|
73
|
-
for (const iss of validated.
|
|
74
|
-
deps.logger.error(`- ${iss.path
|
|
98
|
+
for (const iss of validated.issues) {
|
|
99
|
+
deps.logger.error(`- ${iss.path}: ${iss.message}`);
|
|
75
100
|
}
|
|
76
101
|
return {};
|
|
77
102
|
}
|
|
78
|
-
|
|
103
|
+
if (migrated.config && migrated.changes.length > 0) {
|
|
104
|
+
deps.logger.warn(`Auto-migrated config: ${migrated.changes.join(" ")}`);
|
|
105
|
+
try {
|
|
106
|
+
deps.fs.writeFileSync(configPath, `${JSON.stringify(migrated.config, null, 2)}\n`);
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
deps.logger.warn(`Failed to write migrated config: ${String(err)}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const cfg = applyModelDefaults(applySessionDefaults(applyLoggingDefaults(applyMessageDefaults(applyIdentityDefaults(validated.config)))));
|
|
113
|
+
const normalized = attachChannelAliases(cfg);
|
|
79
114
|
const enabled = shouldEnableShellEnvFallback(deps.env) ||
|
|
80
115
|
cfg.env?.shellEnv?.enabled === true;
|
|
81
116
|
if (enabled) {
|
|
@@ -88,7 +123,7 @@ export function createConfigIO(overrides = {}) {
|
|
|
88
123
|
resolveShellEnvFallbackTimeoutMs(deps.env),
|
|
89
124
|
});
|
|
90
125
|
}
|
|
91
|
-
return
|
|
126
|
+
return normalized;
|
|
92
127
|
}
|
|
93
128
|
catch (err) {
|
|
94
129
|
deps.logger.error(`Failed to read config at ${configPath}`, err);
|
|
@@ -96,9 +131,10 @@ export function createConfigIO(overrides = {}) {
|
|
|
96
131
|
}
|
|
97
132
|
}
|
|
98
133
|
async function readConfigFileSnapshot() {
|
|
134
|
+
const configPath = resolveConfigPath();
|
|
99
135
|
const exists = deps.fs.existsSync(configPath);
|
|
100
136
|
if (!exists) {
|
|
101
|
-
const config = applyTalkApiKey(applyModelDefaults(applySessionDefaults(applyMessageDefaults({}))));
|
|
137
|
+
const config = attachChannelAliases(applyTalkApiKey(applyModelDefaults(applySessionDefaults(applyMessageDefaults({})))));
|
|
102
138
|
const legacyIssues = [];
|
|
103
139
|
return {
|
|
104
140
|
path: configPath,
|
|
@@ -128,8 +164,34 @@ export function createConfigIO(overrides = {}) {
|
|
|
128
164
|
legacyIssues: [],
|
|
129
165
|
};
|
|
130
166
|
}
|
|
131
|
-
|
|
132
|
-
|
|
167
|
+
let resolved;
|
|
168
|
+
try {
|
|
169
|
+
resolved = resolveConfigIncludes(parsedRes.parsed, configPath, {
|
|
170
|
+
readFile: (p) => deps.fs.readFileSync(p, "utf-8"),
|
|
171
|
+
parseJson: (json) => deps.json5.parse(json),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
const message = err instanceof ConfigIncludeError
|
|
176
|
+
? err.message
|
|
177
|
+
: `Include resolution failed: ${String(err)}`;
|
|
178
|
+
return {
|
|
179
|
+
path: configPath,
|
|
180
|
+
exists: true,
|
|
181
|
+
raw,
|
|
182
|
+
parsed: parsedRes.parsed,
|
|
183
|
+
valid: false,
|
|
184
|
+
config: {},
|
|
185
|
+
issues: [{ path: "", message }],
|
|
186
|
+
legacyIssues: [],
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
const migrated = migrateLegacyConfig(resolved);
|
|
190
|
+
const candidate = migrated.config ?? resolved;
|
|
191
|
+
const legacyIssues = migrated.config
|
|
192
|
+
? []
|
|
193
|
+
: findLegacyConfigIssues(candidate);
|
|
194
|
+
const validated = validateConfigObject(candidate);
|
|
133
195
|
if (!validated.ok) {
|
|
134
196
|
return {
|
|
135
197
|
path: configPath,
|
|
@@ -142,13 +204,22 @@ export function createConfigIO(overrides = {}) {
|
|
|
142
204
|
legacyIssues,
|
|
143
205
|
};
|
|
144
206
|
}
|
|
207
|
+
if (migrated.config && migrated.changes.length > 0) {
|
|
208
|
+
deps.logger.warn(`Auto-migrated config: ${migrated.changes.join(" ")}`);
|
|
209
|
+
try {
|
|
210
|
+
deps.fs.writeFileSync(configPath, `${JSON.stringify(migrated.config, null, 2)}\n`);
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
deps.logger.warn(`Failed to write migrated config: ${String(err)}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
145
216
|
return {
|
|
146
217
|
path: configPath,
|
|
147
218
|
exists: true,
|
|
148
219
|
raw,
|
|
149
220
|
parsed: parsedRes.parsed,
|
|
150
221
|
valid: true,
|
|
151
|
-
config: applyTalkApiKey(applyModelDefaults(applySessionDefaults(applyLoggingDefaults(applyMessageDefaults(validated.config))))),
|
|
222
|
+
config: attachChannelAliases(applyTalkApiKey(applyModelDefaults(applySessionDefaults(applyLoggingDefaults(applyMessageDefaults(validated.config)))))),
|
|
152
223
|
issues: [],
|
|
153
224
|
legacyIssues,
|
|
154
225
|
};
|
|
@@ -167,6 +238,7 @@ export function createConfigIO(overrides = {}) {
|
|
|
167
238
|
}
|
|
168
239
|
}
|
|
169
240
|
async function writeConfigFile(cfg) {
|
|
241
|
+
const configPath = resolveConfigPath();
|
|
170
242
|
await deps.fs.promises.mkdir(path.dirname(configPath), {
|
|
171
243
|
recursive: true,
|
|
172
244
|
});
|
|
@@ -176,13 +248,13 @@ export function createConfigIO(overrides = {}) {
|
|
|
176
248
|
await deps.fs.promises.writeFile(configPath, json, "utf-8");
|
|
177
249
|
}
|
|
178
250
|
return {
|
|
179
|
-
configPath,
|
|
251
|
+
configPath: resolveConfigPath(),
|
|
180
252
|
loadConfig,
|
|
181
253
|
readConfigFileSnapshot,
|
|
182
254
|
writeConfigFile,
|
|
183
255
|
};
|
|
184
256
|
}
|
|
185
|
-
const defaultIO = createConfigIO(
|
|
257
|
+
const defaultIO = createConfigIO();
|
|
186
258
|
export const loadConfig = defaultIO.loadConfig;
|
|
187
259
|
export const readConfigFileSnapshot = defaultIO.readConfigFileSnapshot;
|
|
188
260
|
export const writeConfigFile = defaultIO.writeConfigFile;
|
package/dist/config/legacy.js
CHANGED
|
@@ -138,7 +138,8 @@ const LEGACY_CONFIG_MIGRATIONS = [
|
|
|
138
138
|
if (!match || typeof match !== "object")
|
|
139
139
|
continue;
|
|
140
140
|
const matchRecord = match;
|
|
141
|
-
if (matchRecord.channel === undefined &&
|
|
141
|
+
if (matchRecord.channel === undefined &&
|
|
142
|
+
matchRecord.provider !== undefined) {
|
|
142
143
|
matchRecord.channel = matchRecord.provider;
|
|
143
144
|
delete matchRecord.provider;
|
|
144
145
|
touched = true;
|
|
@@ -202,7 +203,8 @@ const LEGACY_CONFIG_MIGRATIONS = [
|
|
|
202
203
|
if (!match || typeof match !== "object")
|
|
203
204
|
continue;
|
|
204
205
|
const matchRecord = match;
|
|
205
|
-
if (matchRecord.channel === undefined &&
|
|
206
|
+
if (matchRecord.channel === undefined &&
|
|
207
|
+
matchRecord.provider !== undefined) {
|
|
206
208
|
matchRecord.channel = matchRecord.provider;
|
|
207
209
|
delete matchRecord.provider;
|
|
208
210
|
touched = true;
|