@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
|
@@ -233,12 +233,7 @@ function resolveStorageField(storage, field) {
|
|
|
233
233
|
return storage.fields?.accessToken ?? storage.fields?.token ?? null;
|
|
234
234
|
return null;
|
|
235
235
|
}
|
|
236
|
-
async function
|
|
237
|
-
const storage = record.storage;
|
|
238
|
-
if (storage.provider === "plaintext") {
|
|
239
|
-
const value = field === "key" ? record.key : field === "token" ? record.token : record.accessToken;
|
|
240
|
-
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
241
|
-
}
|
|
236
|
+
async function readRawFromStorage(storage, field) {
|
|
242
237
|
if (storage.provider === "keychain") {
|
|
243
238
|
try {
|
|
244
239
|
const { stdout } = await execFileAsync("security", [
|
|
@@ -256,6 +251,13 @@ async function readSecretFromStorage(record, field) {
|
|
|
256
251
|
return null;
|
|
257
252
|
}
|
|
258
253
|
}
|
|
254
|
+
if (storage.provider === "env") {
|
|
255
|
+
const envValue = process.env[storage.var];
|
|
256
|
+
if (typeof envValue !== "string")
|
|
257
|
+
return null;
|
|
258
|
+
const trimmed = envValue.trim();
|
|
259
|
+
return trimmed ? trimmed : null;
|
|
260
|
+
}
|
|
259
261
|
if (storage.provider === "1password") {
|
|
260
262
|
const fieldName = resolveStorageField(storage, field);
|
|
261
263
|
if (!fieldName)
|
|
@@ -272,7 +274,10 @@ async function readSecretFromStorage(record, field) {
|
|
|
272
274
|
}
|
|
273
275
|
if (storage.provider === "external") {
|
|
274
276
|
try {
|
|
275
|
-
const
|
|
277
|
+
const command = storage.command ?? storage.syncCommand;
|
|
278
|
+
if (!command)
|
|
279
|
+
return null;
|
|
280
|
+
const { stdout } = await execAsync(command);
|
|
276
281
|
const trimmed = stdout.trim();
|
|
277
282
|
return trimmed ? trimmed : null;
|
|
278
283
|
}
|
|
@@ -282,6 +287,127 @@ async function readSecretFromStorage(record, field) {
|
|
|
282
287
|
}
|
|
283
288
|
return null;
|
|
284
289
|
}
|
|
290
|
+
async function readSecretFromStorage(record, field) {
|
|
291
|
+
const storage = record.storage;
|
|
292
|
+
const raw = await readRawFromStorage(storage, field);
|
|
293
|
+
if (!raw)
|
|
294
|
+
return null;
|
|
295
|
+
const wantsJson = storage.format === "json" || Boolean(storage.jsonPath);
|
|
296
|
+
if (!wantsJson)
|
|
297
|
+
return raw;
|
|
298
|
+
try {
|
|
299
|
+
const parsed = JSON.parse(raw);
|
|
300
|
+
const pathSpec = storage.jsonPath ?? field;
|
|
301
|
+
const resolved = resolveJsonPath(parsed, pathSpec);
|
|
302
|
+
if (typeof resolved === "string")
|
|
303
|
+
return resolved.trim() || null;
|
|
304
|
+
if (typeof resolved === "number")
|
|
305
|
+
return String(resolved);
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
catch {
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
function resolveJsonPath(value, pathSpec) {
|
|
313
|
+
const parts = pathSpec.split(".").filter(Boolean);
|
|
314
|
+
let current = value;
|
|
315
|
+
for (const part of parts) {
|
|
316
|
+
if (!current || typeof current !== "object")
|
|
317
|
+
return undefined;
|
|
318
|
+
const match = /^(.+?)\[(\d+)\]$/.exec(part);
|
|
319
|
+
if (match) {
|
|
320
|
+
const [, key, indexRaw] = match;
|
|
321
|
+
const index = Number.parseInt(indexRaw, 10);
|
|
322
|
+
if (Number.isNaN(index))
|
|
323
|
+
return undefined;
|
|
324
|
+
const next = current[key ?? ""];
|
|
325
|
+
if (!Array.isArray(next))
|
|
326
|
+
return undefined;
|
|
327
|
+
current = next[index];
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
current = current[part];
|
|
331
|
+
}
|
|
332
|
+
return current;
|
|
333
|
+
}
|
|
334
|
+
export function resolveDefaultEnvVar(params) {
|
|
335
|
+
const service = params.service.toLowerCase();
|
|
336
|
+
const type = params.type;
|
|
337
|
+
const known = {
|
|
338
|
+
anthropic: {
|
|
339
|
+
api_key: "ANTHROPIC_API_KEY",
|
|
340
|
+
token: "ANTHROPIC_OAUTH_TOKEN",
|
|
341
|
+
oauth: "ANTHROPIC_OAUTH_TOKEN",
|
|
342
|
+
},
|
|
343
|
+
openai: { api_key: "OPENAI_API_KEY" },
|
|
344
|
+
gemini: { api_key: "GEMINI_API_KEY" },
|
|
345
|
+
"brave-search": { api_key: "BRAVE_API_KEY" },
|
|
346
|
+
github: { token: "GITHUB_TOKEN" },
|
|
347
|
+
"github-copilot": { token: "COPILOT_GITHUB_TOKEN" },
|
|
348
|
+
discord: { token: "DISCORD_BOT_TOKEN" },
|
|
349
|
+
slack: { token: "SLACK_BOT_TOKEN" },
|
|
350
|
+
openrouter: { api_key: "OPENROUTER_API_KEY" },
|
|
351
|
+
zai: { api_key: "ZAI_API_KEY" },
|
|
352
|
+
minimax: { api_key: "MINIMAX_API_KEY", token: "MINIMAX_API_KEY" },
|
|
353
|
+
"openai-codex": { oauth: "NEXUS_OPENAI_CODEX_TOKEN" },
|
|
354
|
+
"google-antigravity": { oauth: "NEXUS_GOOGLE_ANTIGRAVITY_TOKEN" },
|
|
355
|
+
chutes: { oauth: "NEXUS_CHUTES_TOKEN" },
|
|
356
|
+
"nexus-cloud": { token: "NEXUS_CLOUD_TOKEN" },
|
|
357
|
+
"nexus-hub": { token: "NEXUS_HUB_TOKEN" },
|
|
358
|
+
};
|
|
359
|
+
const mapped = known[service]?.[type];
|
|
360
|
+
if (mapped)
|
|
361
|
+
return mapped;
|
|
362
|
+
const suffix = type === "api_key"
|
|
363
|
+
? "API_KEY"
|
|
364
|
+
: type === "oauth"
|
|
365
|
+
? "OAUTH_TOKEN"
|
|
366
|
+
: type === "token"
|
|
367
|
+
? "TOKEN"
|
|
368
|
+
: "CONFIG";
|
|
369
|
+
const normalized = service.toUpperCase().replace(/[^A-Z0-9]+/g, "_");
|
|
370
|
+
return `NEXUS_${normalized}_${suffix}`;
|
|
371
|
+
}
|
|
372
|
+
export async function resolveOAuthBundle(record) {
|
|
373
|
+
if (record.type !== "oauth")
|
|
374
|
+
return {};
|
|
375
|
+
const raw = await readRawFromStorage(record.storage, "accessToken");
|
|
376
|
+
if (!raw)
|
|
377
|
+
return {};
|
|
378
|
+
const wantsJson = record.storage.format === "json" || Boolean(record.storage.jsonPath);
|
|
379
|
+
if (!wantsJson) {
|
|
380
|
+
return { accessToken: raw, expiresAt: record.expiresAt };
|
|
381
|
+
}
|
|
382
|
+
try {
|
|
383
|
+
const parsed = JSON.parse(raw);
|
|
384
|
+
if (record.storage.jsonPath) {
|
|
385
|
+
const access = resolveJsonPath(parsed, record.storage.jsonPath);
|
|
386
|
+
if (typeof access === "string") {
|
|
387
|
+
return { accessToken: access };
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
const accessToken = typeof parsed.accessToken === "string"
|
|
391
|
+
? parsed.accessToken
|
|
392
|
+
: typeof parsed.access_token === "string"
|
|
393
|
+
? parsed.access_token
|
|
394
|
+
: undefined;
|
|
395
|
+
const refreshToken = typeof parsed.refreshToken === "string"
|
|
396
|
+
? parsed.refreshToken
|
|
397
|
+
: typeof parsed.refresh_token === "string"
|
|
398
|
+
? parsed.refresh_token
|
|
399
|
+
: undefined;
|
|
400
|
+
const expiresAt = typeof parsed.expiresAt === "number" || typeof parsed.expiresAt === "string"
|
|
401
|
+
? parsed.expiresAt
|
|
402
|
+
: typeof parsed.expires_at === "number" || typeof parsed.expires_at === "string"
|
|
403
|
+
? parsed.expires_at
|
|
404
|
+
: undefined;
|
|
405
|
+
return { accessToken, refreshToken, expiresAt };
|
|
406
|
+
}
|
|
407
|
+
catch {
|
|
408
|
+
return {};
|
|
409
|
+
}
|
|
410
|
+
}
|
|
285
411
|
export async function storeKeychainSecret(params) {
|
|
286
412
|
try {
|
|
287
413
|
await execFileAsync("security", [
|
package/dist/daemon/launchd.js
CHANGED
|
@@ -74,9 +74,23 @@ export async function readLaunchAgentProgramArguments(env) {
|
|
|
74
74
|
const workingDirectory = workingDirMatch
|
|
75
75
|
? plistUnescape(workingDirMatch[1] ?? "").trim()
|
|
76
76
|
: "";
|
|
77
|
+
const envMatch = plist.match(/<key>EnvironmentVariables<\/key>\s*<dict>([\s\S]*?)<\/dict>/i);
|
|
78
|
+
let environment;
|
|
79
|
+
if (envMatch) {
|
|
80
|
+
const entries = Array.from(envMatch[1].matchAll(/<key>([\s\S]*?)<\/key>\s*<string>([\s\S]*?)<\/string>/gi))
|
|
81
|
+
.map((match) => [
|
|
82
|
+
plistUnescape(match[1] ?? "").trim(),
|
|
83
|
+
plistUnescape(match[2] ?? "").trim(),
|
|
84
|
+
])
|
|
85
|
+
.filter(([key, value]) => key && value);
|
|
86
|
+
if (entries.length > 0) {
|
|
87
|
+
environment = Object.fromEntries(entries);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
77
90
|
return {
|
|
78
91
|
programArguments: args.filter(Boolean),
|
|
79
92
|
...(workingDirectory ? { workingDirectory } : {}),
|
|
93
|
+
...(environment ? { environment } : {}),
|
|
80
94
|
};
|
|
81
95
|
}
|
|
82
96
|
catch {
|
package/dist/entry.js
CHANGED
|
File without changes
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export async function startBrowserControlServerIfEnabled() {
|
|
2
|
-
if (process.env.NEXUS_SKIP_BROWSER_CONTROL_SERVER === "1"
|
|
3
|
-
process.env.NEXUS_SKIP_BROWSER_CONTROL_SERVER === "1")
|
|
2
|
+
if (process.env.NEXUS_SKIP_BROWSER_CONTROL_SERVER === "1")
|
|
4
3
|
return null;
|
|
5
4
|
// Lazy import: keeps startup fast, but still bundles for the embedded
|
|
6
5
|
// gateway (bun --compile) via the static specifier path.
|
|
7
|
-
const override =
|
|
8
|
-
const mod = override
|
|
6
|
+
const override = process.env.NEXUS_BROWSER_CONTROL_MODULE?.trim();
|
|
7
|
+
const mod = override
|
|
8
|
+
? await import(override)
|
|
9
|
+
: await import("../browser/server.js");
|
|
9
10
|
await mod.startBrowserControlServerFromConfig();
|
|
10
11
|
return { stop: mod.stopBrowserControlServer };
|
|
11
12
|
}
|
|
@@ -41,9 +41,19 @@ export const cronHandlers = {
|
|
|
41
41
|
},
|
|
42
42
|
"cron.update": async ({ params, respond, context }) => {
|
|
43
43
|
const normalizedPatch = normalizeCronJobPatch(params?.patch);
|
|
44
|
-
const
|
|
44
|
+
const withPatch = normalizedPatch && typeof params === "object" && params !== null
|
|
45
45
|
? { ...params, patch: normalizedPatch }
|
|
46
46
|
: params;
|
|
47
|
+
const candidate = withPatch && typeof withPatch === "object" && withPatch !== null
|
|
48
|
+
? (() => {
|
|
49
|
+
const entry = withPatch;
|
|
50
|
+
if (!entry.id && entry.jobId) {
|
|
51
|
+
const { jobId, ...rest } = entry;
|
|
52
|
+
return { ...rest, id: jobId };
|
|
53
|
+
}
|
|
54
|
+
return entry;
|
|
55
|
+
})()
|
|
56
|
+
: withPatch;
|
|
47
57
|
if (!validateCronUpdateParams(candidate)) {
|
|
48
58
|
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `invalid cron.update params: ${formatValidationErrors(validateCronUpdateParams.errors)}`));
|
|
49
59
|
return;
|
package/dist/gateway/server.js
CHANGED
|
@@ -2,10 +2,10 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { WebSocketServer } from "ws";
|
|
5
|
-
import { createSubagentRegistry } from "../agents/subagent-registry.js";
|
|
6
5
|
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js";
|
|
7
6
|
import { loadModelCatalog, resetModelCatalogCacheForTest, } from "../agents/model-catalog.js";
|
|
8
7
|
import { resolveConfiguredModelRef } from "../agents/model-selection.js";
|
|
8
|
+
import { createSubagentRegistry } from "../agents/subagent-registry.js";
|
|
9
9
|
import { CANVAS_HOST_PATH } from "../canvas-host/a2ui.js";
|
|
10
10
|
import { createCanvasHostHandler, startCanvasHost, } from "../canvas-host/server.js";
|
|
11
11
|
import { createDefaultDeps } from "../cli/deps.js";
|
|
@@ -256,7 +256,8 @@ export async function startGatewayServer(port = 18789, opts = {}) {
|
|
|
256
256
|
allowTailscale,
|
|
257
257
|
};
|
|
258
258
|
let hooksConfig = resolveHooksConfig(cfgAtStart);
|
|
259
|
-
const canvasHostEnabled = process.env.NEXUS_SKIP_CANVAS_HOST !== "1" &&
|
|
259
|
+
const canvasHostEnabled = process.env.NEXUS_SKIP_CANVAS_HOST !== "1" &&
|
|
260
|
+
cfgAtStart.canvasHost?.enabled !== false;
|
|
260
261
|
assertGatewayAuthConfigured(resolvedAuth);
|
|
261
262
|
if (tailscaleMode === "funnel" && authMode !== "password") {
|
|
262
263
|
throw new Error("tailscale funnel requires gateway auth mode=password (set gateway.auth.password or NEXUS_GATEWAY_PASSWORD)");
|
|
@@ -464,7 +465,7 @@ export async function startGatewayServer(port = 18789, opts = {}) {
|
|
|
464
465
|
return resolveMainSessionKey(cfg);
|
|
465
466
|
return resolveAgentMainSessionKey({ cfg, agentId });
|
|
466
467
|
};
|
|
467
|
-
const
|
|
468
|
+
const _enqueueCronSystemEvent = (text, opts) => {
|
|
468
469
|
const sessionKey = resolveCronMainSessionKey(opts?.agentId);
|
|
469
470
|
if (sessionKey) {
|
|
470
471
|
enqueueSystemEvent(text, { sessionKey });
|
|
@@ -586,7 +587,9 @@ export async function startGatewayServer(port = 18789, opts = {}) {
|
|
|
586
587
|
}
|
|
587
588
|
if (process.env.NEXUS_BRIDGE_PORT !== undefined) {
|
|
588
589
|
const parsed = Number.parseInt(process.env.NEXUS_BRIDGE_PORT, 10);
|
|
589
|
-
return Number.isFinite(parsed) && parsed > 0
|
|
590
|
+
return Number.isFinite(parsed) && parsed > 0
|
|
591
|
+
? parsed
|
|
592
|
+
: deriveDefaultBridgePort(port);
|
|
590
593
|
}
|
|
591
594
|
return deriveDefaultBridgePort(port);
|
|
592
595
|
})();
|
|
@@ -1049,7 +1052,9 @@ export async function startGatewayServer(port = 18789, opts = {}) {
|
|
|
1049
1052
|
type: "hello-ok",
|
|
1050
1053
|
protocol: PROTOCOL_VERSION,
|
|
1051
1054
|
server: {
|
|
1052
|
-
version: process.env.NEXUS_VERSION ??
|
|
1055
|
+
version: process.env.NEXUS_VERSION ??
|
|
1056
|
+
process.env.npm_package_version ??
|
|
1057
|
+
"dev",
|
|
1053
1058
|
commit: process.env.GIT_COMMIT,
|
|
1054
1059
|
host: os.hostname(),
|
|
1055
1060
|
connId,
|
|
@@ -1240,7 +1245,8 @@ export async function startGatewayServer(port = 18789, opts = {}) {
|
|
|
1240
1245
|
}
|
|
1241
1246
|
// Launch configured channels (WhatsApp Web, Discord, Slack, Telegram) so gateway replies via the
|
|
1242
1247
|
// surface the message came from. Tests can opt out via NEXUS_SKIP_CHANNELS (or legacy _PROVIDERS).
|
|
1243
|
-
const skipChannels = process.env.NEXUS_SKIP_CHANNELS === "1" ||
|
|
1248
|
+
const skipChannels = process.env.NEXUS_SKIP_CHANNELS === "1" ||
|
|
1249
|
+
process.env.NEXUS_SKIP_PROVIDERS === "1";
|
|
1244
1250
|
if (!skipChannels) {
|
|
1245
1251
|
try {
|
|
1246
1252
|
await startProviders();
|
|
@@ -1315,7 +1321,8 @@ export async function startGatewayServer(port = 18789, opts = {}) {
|
|
|
1315
1321
|
}
|
|
1316
1322
|
}
|
|
1317
1323
|
if (plan.restartProviders.size > 0) {
|
|
1318
|
-
const skipChannelReload = process.env.NEXUS_SKIP_CHANNELS === "1" ||
|
|
1324
|
+
const skipChannelReload = process.env.NEXUS_SKIP_CHANNELS === "1" ||
|
|
1325
|
+
process.env.NEXUS_SKIP_PROVIDERS === "1";
|
|
1319
1326
|
if (skipChannelReload) {
|
|
1320
1327
|
logChannels.info("skipping channel reload (NEXUS_SKIP_CHANNELS=1)");
|
|
1321
1328
|
}
|
package/dist/infra/bonjour.js
CHANGED
|
@@ -2,7 +2,7 @@ import os from "node:os";
|
|
|
2
2
|
import { logDebug, logWarn } from "../logger.js";
|
|
3
3
|
import { getLogger } from "../logging.js";
|
|
4
4
|
function isDisabledByEnv() {
|
|
5
|
-
if (process.env.NEXUS_DISABLE_BONJOUR === "1"
|
|
5
|
+
if (process.env.NEXUS_DISABLE_BONJOUR === "1")
|
|
6
6
|
return true;
|
|
7
7
|
if (process.env.NODE_ENV === "test")
|
|
8
8
|
return true;
|
package/dist/infra/event-log.js
CHANGED
|
@@ -200,7 +200,11 @@ export function recordCliCommandFinish(status = "ok") {
|
|
|
200
200
|
export function recordCliCommandFailure(error) {
|
|
201
201
|
if (!cliSession?.activeCommand)
|
|
202
202
|
return;
|
|
203
|
-
const message = error instanceof Error
|
|
203
|
+
const message = error instanceof Error
|
|
204
|
+
? error.message
|
|
205
|
+
: typeof error === "string"
|
|
206
|
+
? error
|
|
207
|
+
: "unknown error";
|
|
204
208
|
writeEvent({
|
|
205
209
|
id: createEventId(),
|
|
206
210
|
ts: Date.now(),
|
|
@@ -227,7 +231,9 @@ export function recordCliSessionEnd(params) {
|
|
|
227
231
|
invocation_kind: cliSession.invocationKind,
|
|
228
232
|
status: params.status,
|
|
229
233
|
error: params.error,
|
|
230
|
-
data: params.exitCode !== undefined
|
|
234
|
+
data: params.exitCode !== undefined
|
|
235
|
+
? { exit_code: params.exitCode }
|
|
236
|
+
: undefined,
|
|
231
237
|
});
|
|
232
238
|
cliSession = null;
|
|
233
239
|
}
|
package/dist/infra/path-env.js
CHANGED
|
@@ -79,10 +79,9 @@ function candidateBinDirs(opts) {
|
|
|
79
79
|
* under launchd/minimal environments (and inside the macOS bun bundle).
|
|
80
80
|
*/
|
|
81
81
|
export function ensureNexusCliOnPath(opts = {}) {
|
|
82
|
-
if (process.env.NEXUS_PATH_BOOTSTRAPPED === "1"
|
|
82
|
+
if (process.env.NEXUS_PATH_BOOTSTRAPPED === "1")
|
|
83
83
|
return;
|
|
84
84
|
process.env.NEXUS_PATH_BOOTSTRAPPED = "1";
|
|
85
|
-
process.env.NEXUS_PATH_BOOTSTRAPPED = "1"; // keep for backward compat
|
|
86
85
|
const existing = opts.pathEnv ?? process.env.PATH ?? "";
|
|
87
86
|
const prepend = candidateBinDirs(opts);
|
|
88
87
|
if (prepend.length === 0)
|
|
@@ -2,7 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { CLAUDE_CLI_PROFILE_ID, ensureAuthProfileStore, listProfilesForProvider, resolveApiKeyForProfile, resolveAuthProfileOrder, } from "../agents/auth-profiles.js";
|
|
5
|
-
import { getCustomProviderApiKey, resolveEnvApiKey } from "../agents/model-auth.js";
|
|
5
|
+
import { getCustomProviderApiKey, resolveEnvApiKey, } from "../agents/model-auth.js";
|
|
6
6
|
import { normalizeProviderId } from "../agents/model-selection.js";
|
|
7
7
|
import { loadConfig } from "../config/config.js";
|
|
8
8
|
function parseGoogleToken(apiKey) {
|
|
@@ -53,7 +53,8 @@ function resolveZaiApiKey() {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
function resolveMinimaxApiKey() {
|
|
56
|
-
const envDirect = process.env.MINIMAX_CODE_PLAN_KEY?.trim() ||
|
|
56
|
+
const envDirect = process.env.MINIMAX_CODE_PLAN_KEY?.trim() ||
|
|
57
|
+
process.env.MINIMAX_API_KEY?.trim();
|
|
57
58
|
if (envDirect)
|
|
58
59
|
return envDirect;
|
|
59
60
|
const envResolved = resolveEnvApiKey("minimax");
|
|
@@ -112,7 +113,8 @@ async function resolveOAuthToken(params) {
|
|
|
112
113
|
if (!resolved?.apiKey)
|
|
113
114
|
continue;
|
|
114
115
|
let token = resolved.apiKey;
|
|
115
|
-
if (params.provider === "google-gemini-cli" ||
|
|
116
|
+
if (params.provider === "google-gemini-cli" ||
|
|
117
|
+
params.provider === "google-antigravity") {
|
|
116
118
|
const parsed = parseGoogleToken(resolved.apiKey);
|
|
117
119
|
token = parsed?.token ?? resolved.apiKey;
|
|
118
120
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { fetchJson } from "./provider-usage.fetch.shared.js";
|
|
2
2
|
import { clampPercent, PROVIDER_LABELS } from "./provider-usage.shared.js";
|
|
3
3
|
function resolveClaudeWebSessionKey() {
|
|
4
|
-
const direct = process.env.CLAUDE_AI_SESSION_KEY?.trim() ??
|
|
4
|
+
const direct = process.env.CLAUDE_AI_SESSION_KEY?.trim() ??
|
|
5
|
+
process.env.CLAUDE_WEB_SESSION_KEY?.trim();
|
|
5
6
|
if (direct?.startsWith("sk-ant-"))
|
|
6
7
|
return direct;
|
|
7
8
|
const cookieHeader = process.env.CLAUDE_WEB_COOKIE?.trim();
|
|
@@ -33,14 +34,18 @@ async function fetchClaudeWebUsage(sessionKey, timeoutMs, fetchFn) {
|
|
|
33
34
|
windows.push({
|
|
34
35
|
label: "5h",
|
|
35
36
|
usedPercent: clampPercent(data.five_hour.utilization),
|
|
36
|
-
resetAt: data.five_hour.resets_at
|
|
37
|
+
resetAt: data.five_hour.resets_at
|
|
38
|
+
? new Date(data.five_hour.resets_at).getTime()
|
|
39
|
+
: undefined,
|
|
37
40
|
});
|
|
38
41
|
}
|
|
39
42
|
if (data.seven_day?.utilization !== undefined) {
|
|
40
43
|
windows.push({
|
|
41
44
|
label: "Week",
|
|
42
45
|
usedPercent: clampPercent(data.seven_day.utilization),
|
|
43
|
-
resetAt: data.seven_day.resets_at
|
|
46
|
+
resetAt: data.seven_day.resets_at
|
|
47
|
+
? new Date(data.seven_day.resets_at).getTime()
|
|
48
|
+
: undefined,
|
|
44
49
|
});
|
|
45
50
|
}
|
|
46
51
|
const modelWindow = data.seven_day_sonnet || data.seven_day_opus;
|
|
@@ -82,7 +87,8 @@ export async function fetchClaudeUsage(token, timeoutMs, fetchFn) {
|
|
|
82
87
|
// Claude CLI setup-token yields tokens that can be used for inference, but may not
|
|
83
88
|
// include user:profile scope required by the OAuth usage endpoint. When a claude.ai
|
|
84
89
|
// browser sessionKey is available, fall back to the web API.
|
|
85
|
-
if (res.status === 403 &&
|
|
90
|
+
if (res.status === 403 &&
|
|
91
|
+
message?.includes("scope requirement user:profile")) {
|
|
86
92
|
const sessionKey = resolveClaudeWebSessionKey();
|
|
87
93
|
if (sessionKey) {
|
|
88
94
|
const web = await fetchClaudeWebUsage(sessionKey, timeoutMs, fetchFn);
|
|
@@ -104,14 +110,18 @@ export async function fetchClaudeUsage(token, timeoutMs, fetchFn) {
|
|
|
104
110
|
windows.push({
|
|
105
111
|
label: "5h",
|
|
106
112
|
usedPercent: clampPercent(data.five_hour.utilization),
|
|
107
|
-
resetAt: data.five_hour.resets_at
|
|
113
|
+
resetAt: data.five_hour.resets_at
|
|
114
|
+
? new Date(data.five_hour.resets_at).getTime()
|
|
115
|
+
: undefined,
|
|
108
116
|
});
|
|
109
117
|
}
|
|
110
118
|
if (data.seven_day?.utilization !== undefined) {
|
|
111
119
|
windows.push({
|
|
112
120
|
label: "Week",
|
|
113
121
|
usedPercent: clampPercent(data.seven_day.utilization),
|
|
114
|
-
resetAt: data.seven_day.resets_at
|
|
122
|
+
resetAt: data.seven_day.resets_at
|
|
123
|
+
? new Date(data.seven_day.resets_at).getTime()
|
|
124
|
+
: undefined,
|
|
115
125
|
});
|
|
116
126
|
}
|
|
117
127
|
const modelWindow = data.seven_day_sonnet || data.seven_day_opus;
|
|
@@ -178,8 +178,12 @@ export async function fetchMinimaxUsage(apiKey, timeoutMs, fetchFn) {
|
|
|
178
178
|
error: "Invalid JSON",
|
|
179
179
|
};
|
|
180
180
|
}
|
|
181
|
-
const baseResp = isRecord(data.base_resp)
|
|
182
|
-
|
|
181
|
+
const baseResp = isRecord(data.base_resp)
|
|
182
|
+
? data.base_resp
|
|
183
|
+
: undefined;
|
|
184
|
+
if (baseResp &&
|
|
185
|
+
typeof baseResp.status_code === "number" &&
|
|
186
|
+
baseResp.status_code !== 0) {
|
|
183
187
|
return {
|
|
184
188
|
provider: "minimax",
|
|
185
189
|
displayName: PROVIDER_LABELS.minimax,
|
|
@@ -197,7 +201,8 @@ export async function fetchMinimaxUsage(apiKey, timeoutMs, fetchFn) {
|
|
|
197
201
|
error: "Unsupported response shape",
|
|
198
202
|
};
|
|
199
203
|
}
|
|
200
|
-
const resetAt = parseEpoch(pickString(payload, RESET_KEYS)) ??
|
|
204
|
+
const resetAt = parseEpoch(pickString(payload, RESET_KEYS)) ??
|
|
205
|
+
parseEpoch(pickNumber(payload, RESET_KEYS));
|
|
201
206
|
const windows = [
|
|
202
207
|
{
|
|
203
208
|
label: deriveWindowLabel(payload),
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { resolveProviderAuths } from "./provider-usage.auth.js";
|
|
1
|
+
import { resolveProviderAuths, } from "./provider-usage.auth.js";
|
|
2
2
|
import { fetchClaudeUsage } from "./provider-usage.fetch.claude.js";
|
|
3
3
|
import { fetchMinimaxUsage } from "./provider-usage.fetch.minimax.js";
|
|
4
|
-
import { clampPercent, PROVIDER_LABELS } from "./provider-usage.shared.js";
|
|
5
4
|
import { fetchJson } from "./provider-usage.fetch.shared.js";
|
|
5
|
+
import { clampPercent, PROVIDER_LABELS } from "./provider-usage.shared.js";
|
|
6
6
|
function resolveProviders(params) {
|
|
7
7
|
if (params.providers && params.providers.length > 0) {
|
|
8
8
|
return params.providers;
|
|
@@ -50,7 +50,9 @@ async function fetchZaiUsage(apiKey, timeoutMs, fetchFn) {
|
|
|
50
50
|
const limit = data?.data?.limits?.find((entry) => entry?.type === "TOKENS_LIMIT") ??
|
|
51
51
|
data?.data?.limits?.[0];
|
|
52
52
|
const usedPercent = clampPercent(limit?.percentage ?? 0);
|
|
53
|
-
const resetAt = limit?.nextResetTime
|
|
53
|
+
const resetAt = limit?.nextResetTime
|
|
54
|
+
? Date.parse(limit.nextResetTime)
|
|
55
|
+
: undefined;
|
|
54
56
|
const windows = [];
|
|
55
57
|
if (Number.isFinite(usedPercent)) {
|
|
56
58
|
windows.push({
|
|
@@ -102,7 +104,7 @@ export async function loadProviderUsageSummary(params) {
|
|
|
102
104
|
}
|
|
103
105
|
return { updatedAt: now, providers: snapshots };
|
|
104
106
|
}
|
|
105
|
-
export function formatUsageSummaryLine(summary,
|
|
107
|
+
export function formatUsageSummaryLine(summary, _opts = {}) {
|
|
106
108
|
const providers = summary.providers ?? [];
|
|
107
109
|
let best;
|
|
108
110
|
for (const provider of providers) {
|
|
@@ -133,7 +135,9 @@ export function formatUsageReportLines(summary, opts = {}) {
|
|
|
133
135
|
}
|
|
134
136
|
for (const window of provider.windows) {
|
|
135
137
|
const remaining = Math.max(0, 100 - window.usedPercent);
|
|
136
|
-
const reset = window.resetAt
|
|
138
|
+
const reset = window.resetAt
|
|
139
|
+
? formatResetLabel(window.resetAt, now)
|
|
140
|
+
: null;
|
|
137
141
|
const extras = [provider.plan ? `plan ${provider.plan}` : null, reset]
|
|
138
142
|
.filter(Boolean)
|
|
139
143
|
.join(", ");
|
package/dist/infra/restart.js
CHANGED
|
@@ -4,7 +4,7 @@ const DEFAULT_SYSTEMD_UNIT = "nexus-gateway.service";
|
|
|
4
4
|
export function triggerNexusRestart() {
|
|
5
5
|
if (process.platform !== "darwin") {
|
|
6
6
|
if (process.platform === "linux") {
|
|
7
|
-
const unit = process.env.NEXUS_SYSTEMD_UNIT ||
|
|
7
|
+
const unit = process.env.NEXUS_SYSTEMD_UNIT || DEFAULT_SYSTEMD_UNIT;
|
|
8
8
|
const userRestart = spawnSync("systemctl", ["--user", "restart", unit], {
|
|
9
9
|
stdio: "ignore",
|
|
10
10
|
});
|
|
@@ -21,7 +21,7 @@ export function triggerNexusRestart() {
|
|
|
21
21
|
}
|
|
22
22
|
return "supervisor";
|
|
23
23
|
}
|
|
24
|
-
const label = process.env.NEXUS_LAUNCHD_LABEL ||
|
|
24
|
+
const label = process.env.NEXUS_LAUNCHD_LABEL || DEFAULT_LAUNCHD_LABEL;
|
|
25
25
|
const uid = typeof process.getuid === "function" ? process.getuid() : undefined;
|
|
26
26
|
const target = uid !== undefined ? `gui/${uid}/${label}` : label;
|
|
27
27
|
spawnSync("launchctl", ["kickstart", "-k", target], { stdio: "ignore" });
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const SETTINGS_URL_ENV = "NEXUS_USAGE_SETTINGS_URL";
|
|
2
|
+
const UPLOAD_URL_ENV = "NEXUS_USAGE_UPLOAD_URL";
|
|
3
|
+
const UPLOAD_TOKEN_ENV = "NEXUS_USAGE_UPLOAD_TOKEN";
|
|
4
|
+
export function resolveUsageSettingsUrl(env = process.env) {
|
|
5
|
+
const override = env[SETTINGS_URL_ENV]?.trim();
|
|
6
|
+
if (override)
|
|
7
|
+
return override;
|
|
8
|
+
const uploadUrl = env[UPLOAD_URL_ENV]?.trim();
|
|
9
|
+
if (!uploadUrl)
|
|
10
|
+
return null;
|
|
11
|
+
return uploadUrl.replace(/\/api\/usage\/upload\/?$/, "/api/usage/settings");
|
|
12
|
+
}
|
|
13
|
+
function resolveAuthHeaders(env = process.env) {
|
|
14
|
+
const token = env[UPLOAD_TOKEN_ENV]?.trim();
|
|
15
|
+
if (!token)
|
|
16
|
+
return {};
|
|
17
|
+
return { Authorization: `Bearer ${token}` };
|
|
18
|
+
}
|
|
19
|
+
function parseSettingsResponse(payload) {
|
|
20
|
+
if (!payload || typeof payload !== "object")
|
|
21
|
+
return null;
|
|
22
|
+
const data = payload;
|
|
23
|
+
if (typeof data.canOptOut !== "boolean" || typeof data.optOut !== "boolean") {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
ok: typeof data.ok === "boolean" ? data.ok : true,
|
|
28
|
+
canOptOut: data.canOptOut,
|
|
29
|
+
optOut: data.optOut,
|
|
30
|
+
planName: typeof data.planName === "string" ? data.planName : undefined,
|
|
31
|
+
error: typeof data.error === "string" ? data.error : undefined,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export async function fetchUsageTrackingSettings(env = process.env) {
|
|
35
|
+
const url = resolveUsageSettingsUrl(env);
|
|
36
|
+
if (!url)
|
|
37
|
+
return null;
|
|
38
|
+
const headers = resolveAuthHeaders(env);
|
|
39
|
+
if (!headers.Authorization)
|
|
40
|
+
return null;
|
|
41
|
+
try {
|
|
42
|
+
const res = await fetch(url, { headers });
|
|
43
|
+
const payload = await res.json().catch(() => null);
|
|
44
|
+
const parsed = parseSettingsResponse(payload);
|
|
45
|
+
if (!parsed)
|
|
46
|
+
return null;
|
|
47
|
+
return { ...parsed, ok: res.ok && parsed.ok };
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export async function updateUsageTrackingSettings(optOut, env = process.env) {
|
|
54
|
+
const url = resolveUsageSettingsUrl(env);
|
|
55
|
+
if (!url)
|
|
56
|
+
return null;
|
|
57
|
+
const headers = {
|
|
58
|
+
"Content-Type": "application/json",
|
|
59
|
+
...resolveAuthHeaders(env),
|
|
60
|
+
};
|
|
61
|
+
if (!headers.Authorization)
|
|
62
|
+
return null;
|
|
63
|
+
try {
|
|
64
|
+
const res = await fetch(url, {
|
|
65
|
+
method: "POST",
|
|
66
|
+
headers,
|
|
67
|
+
body: JSON.stringify({ optOut }),
|
|
68
|
+
});
|
|
69
|
+
const payload = await res.json().catch(() => null);
|
|
70
|
+
const parsed = parseSettingsResponse(payload);
|
|
71
|
+
if (!parsed)
|
|
72
|
+
return null;
|
|
73
|
+
return { ...parsed, ok: res.ok && parsed.ok };
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -58,17 +58,26 @@ export async function loadUsageEvents(opts = {}) {
|
|
|
58
58
|
catch {
|
|
59
59
|
continue;
|
|
60
60
|
}
|
|
61
|
-
const sessionId =
|
|
61
|
+
const sessionId = typeof raw.session_id === "string" || typeof raw.session_id === "number"
|
|
62
|
+
? String(raw.session_id)
|
|
63
|
+
: "";
|
|
62
64
|
const seq = Number(raw.seq ?? 0);
|
|
63
65
|
const ts = Number(raw.ts ?? 0);
|
|
64
|
-
const source =
|
|
65
|
-
|
|
66
|
+
const source = typeof raw.source === "string" || typeof raw.source === "number"
|
|
67
|
+
? String(raw.source)
|
|
68
|
+
: "";
|
|
69
|
+
if (!sessionId ||
|
|
70
|
+
!Number.isFinite(seq) ||
|
|
71
|
+
!Number.isFinite(ts) ||
|
|
72
|
+
!source) {
|
|
66
73
|
continue;
|
|
67
74
|
}
|
|
68
75
|
if (opts.sinceMs && ts < opts.sinceMs) {
|
|
69
76
|
continue;
|
|
70
77
|
}
|
|
71
|
-
if (opts.sources &&
|
|
78
|
+
if (opts.sources &&
|
|
79
|
+
opts.sources.length > 0 &&
|
|
80
|
+
!opts.sources.includes(source)) {
|
|
72
81
|
continue;
|
|
73
82
|
}
|
|
74
83
|
const evt = {
|
|
@@ -76,7 +85,10 @@ export async function loadUsageEvents(opts = {}) {
|
|
|
76
85
|
seq,
|
|
77
86
|
ts,
|
|
78
87
|
source,
|
|
79
|
-
eventType:
|
|
88
|
+
eventType: typeof raw.event_type === "string" ||
|
|
89
|
+
typeof raw.event_type === "number"
|
|
90
|
+
? String(raw.event_type)
|
|
91
|
+
: "",
|
|
80
92
|
commandPath: typeof raw.command_path === "string" ? raw.command_path : undefined,
|
|
81
93
|
stream: typeof raw.stream === "string" ? raw.stream : undefined,
|
|
82
94
|
data: raw.data && typeof raw.data === "object"
|