@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/init.js
CHANGED
|
@@ -3,12 +3,18 @@ import fs from "node:fs/promises";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { promisify } from "node:util";
|
|
5
5
|
import { ensureAgentWorkspace } from "../agents/workspace.js";
|
|
6
|
-
import { CONFIG_PATH_NEXUS, writeConfigFile } from "../config/config.js";
|
|
7
|
-
import { resolveStateDir } from "../config/paths.js";
|
|
6
|
+
import { CONFIG_PATH_NEXUS, readConfigFileSnapshot, writeConfigFile, } from "../config/config.js";
|
|
7
|
+
import { resolveGatewayPort, resolveStateDir } from "../config/paths.js";
|
|
8
|
+
import { GATEWAY_LAUNCH_AGENT_LABEL } from "../daemon/constants.js";
|
|
9
|
+
import { resolveGatewayProgramArguments } from "../daemon/program-args.js";
|
|
10
|
+
import { resolveGatewayService } from "../daemon/service.js";
|
|
8
11
|
import { defaultRuntime } from "../runtime.js";
|
|
9
|
-
import { NEXUS_ROOT } from "../utils.js";
|
|
10
|
-
import {
|
|
12
|
+
import { NEXUS_ROOT, SKILLS_STATE_DIR, WORKSPACE_SKILLS_DIR, resolveUserPath, } from "../utils.js";
|
|
13
|
+
import { scanCredentials } from "./credential.js";
|
|
14
|
+
import { writeCursorHooks } from "./cursor-hooks.js";
|
|
11
15
|
import { writeCursorRules } from "./cursor-rules.js";
|
|
16
|
+
import { copyBundledSkills, generateSkillManifest, writeSkillManifest, } from "./skills-manifest.js";
|
|
17
|
+
import { ensureSystemdUserLingerNonInteractive } from "./systemd-linger.js";
|
|
12
18
|
const execFileAsync = promisify(execFile);
|
|
13
19
|
/**
|
|
14
20
|
* Checks if a directory is already a git repository.
|
|
@@ -77,37 +83,289 @@ build/
|
|
|
77
83
|
await fs.writeFile(gitignorePath, gitignoreContent, "utf-8");
|
|
78
84
|
runtime.log(`✓ Created .gitignore`);
|
|
79
85
|
}
|
|
86
|
+
function shouldCopyIdentity(env) {
|
|
87
|
+
return (env.NEXUS_INIT_COPY_IDENTITY === "1" ||
|
|
88
|
+
env.NEXUS_TEST_MODE === "1" ||
|
|
89
|
+
env.VITEST === "true" ||
|
|
90
|
+
env.NODE_ENV === "test");
|
|
91
|
+
}
|
|
92
|
+
function resolveIdentitySourceDir(env) {
|
|
93
|
+
const explicit = env.NEXUS_INIT_IDENTITY_SRC?.trim() || env.NEXUS_IDENTITY_DIR?.trim();
|
|
94
|
+
if (explicit)
|
|
95
|
+
return resolveUserPath(explicit);
|
|
96
|
+
if (!shouldCopyIdentity(env))
|
|
97
|
+
return null;
|
|
98
|
+
return resolveUserPath("~") + "/nexus";
|
|
99
|
+
}
|
|
100
|
+
function stripQuotes(value) {
|
|
101
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
102
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
103
|
+
return value.slice(1, -1);
|
|
104
|
+
}
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
function readFrontmatterName(raw) {
|
|
108
|
+
const normalized = raw.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
109
|
+
if (!normalized.startsWith("---"))
|
|
110
|
+
return null;
|
|
111
|
+
const endIndex = normalized.indexOf("\n---", 3);
|
|
112
|
+
if (endIndex === -1)
|
|
113
|
+
return null;
|
|
114
|
+
const block = normalized.slice(4, endIndex);
|
|
115
|
+
for (const line of block.split("\n")) {
|
|
116
|
+
const match = line.match(/^name\s*:\s*(.+)$/i);
|
|
117
|
+
if (match?.[1])
|
|
118
|
+
return stripQuotes(match[1].trim());
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
function extractName(raw) {
|
|
123
|
+
const frontmatterName = readFrontmatterName(raw);
|
|
124
|
+
if (frontmatterName)
|
|
125
|
+
return frontmatterName;
|
|
126
|
+
const plainMatch = raw.match(/^[-*]?\s*Name\s*:\s*(.+)$/im);
|
|
127
|
+
if (plainMatch?.[1])
|
|
128
|
+
return plainMatch[1].trim();
|
|
129
|
+
const boldMatch = raw.match(/^\s*[-*]?\s*\*\*Name:\*\*\s*(.+)$/im);
|
|
130
|
+
if (boldMatch?.[1])
|
|
131
|
+
return boldMatch[1].trim();
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
function upsertFrontmatterName(raw, name) {
|
|
135
|
+
const normalized = raw.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
136
|
+
if (normalized.startsWith("---")) {
|
|
137
|
+
const endIndex = normalized.indexOf("\n---", 3);
|
|
138
|
+
if (endIndex !== -1) {
|
|
139
|
+
const block = normalized.slice(4, endIndex);
|
|
140
|
+
const hasName = block.split("\n").some((line) => /^name\s*:/i.test(line));
|
|
141
|
+
if (hasName)
|
|
142
|
+
return raw;
|
|
143
|
+
const updatedBlock = `name: ${name}\n${block}`;
|
|
144
|
+
return `---\n${updatedBlock}\n---${normalized.slice(endIndex + 4)}`;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return `---\nname: ${name}\n---\n\n${raw}`;
|
|
148
|
+
}
|
|
149
|
+
async function copyIdentityFile(params) {
|
|
150
|
+
try {
|
|
151
|
+
const raw = await fs.readFile(params.sourcePath, "utf-8");
|
|
152
|
+
let next = raw;
|
|
153
|
+
if (params.ensureNameLine) {
|
|
154
|
+
const name = extractName(raw);
|
|
155
|
+
if (name && !readFrontmatterName(raw)) {
|
|
156
|
+
next = upsertFrontmatterName(raw, name);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
await fs.mkdir(path.dirname(params.destinationPath), { recursive: true });
|
|
160
|
+
await fs.writeFile(params.destinationPath, next, "utf-8");
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async function copyIdentityForInit(params) {
|
|
168
|
+
const sourceDir = resolveIdentitySourceDir(params.env);
|
|
169
|
+
if (!sourceDir)
|
|
170
|
+
return;
|
|
171
|
+
const resolvedSource = path.resolve(sourceDir);
|
|
172
|
+
const agentIdentityPath = params.workspace.identityPath;
|
|
173
|
+
const agentSoulPath = params.workspace.soulPath;
|
|
174
|
+
const agentMemoryPath = params.workspace.memoryPath;
|
|
175
|
+
const userIdentityPath = params.workspace.userPath;
|
|
176
|
+
if (!agentIdentityPath ||
|
|
177
|
+
!userIdentityPath ||
|
|
178
|
+
!agentSoulPath ||
|
|
179
|
+
!agentMemoryPath)
|
|
180
|
+
return;
|
|
181
|
+
const agentId = process.env.NEXUS_AGENT_ID?.trim() || "default";
|
|
182
|
+
const agentSources = [
|
|
183
|
+
path.join(resolvedSource, "IDENTITY.md"),
|
|
184
|
+
path.join(resolvedSource, "AGENT.md"),
|
|
185
|
+
path.join(resolvedSource, "agents", agentId, "IDENTITY.md"),
|
|
186
|
+
path.join(resolvedSource, "state", "agents", agentId, "IDENTITY.md"),
|
|
187
|
+
path.join(resolvedSource, "state", "identity", "AGENT.md"),
|
|
188
|
+
path.join(resolvedSource, "state", "identity", "IDENTITY.md"),
|
|
189
|
+
];
|
|
190
|
+
const userSources = [
|
|
191
|
+
path.join(resolvedSource, "IDENTITY.md"),
|
|
192
|
+
path.join(resolvedSource, "PROFILE.md"),
|
|
193
|
+
path.join(resolvedSource, "USER.md"),
|
|
194
|
+
path.join(resolvedSource, "user", "IDENTITY.md"),
|
|
195
|
+
path.join(resolvedSource, "state", "user", "IDENTITY.md"),
|
|
196
|
+
path.join(resolvedSource, "state", "identity", "PROFILE.md"),
|
|
197
|
+
path.join(resolvedSource, "state", "identity", "USER.md"),
|
|
198
|
+
];
|
|
199
|
+
const soulSources = [
|
|
200
|
+
path.join(resolvedSource, "SOUL.md"),
|
|
201
|
+
path.join(resolvedSource, "agents", agentId, "SOUL.md"),
|
|
202
|
+
path.join(resolvedSource, "state", "agents", agentId, "SOUL.md"),
|
|
203
|
+
path.join(resolvedSource, "state", "identity", "SOUL.md"),
|
|
204
|
+
];
|
|
205
|
+
const memorySources = [
|
|
206
|
+
path.join(resolvedSource, "MEMORY.md"),
|
|
207
|
+
path.join(resolvedSource, "agents", agentId, "MEMORY.md"),
|
|
208
|
+
path.join(resolvedSource, "state", "agents", agentId, "MEMORY.md"),
|
|
209
|
+
path.join(resolvedSource, "state", "identity", "MEMORY.md"),
|
|
210
|
+
];
|
|
211
|
+
const pickExisting = async (candidates) => {
|
|
212
|
+
for (const candidate of candidates) {
|
|
213
|
+
try {
|
|
214
|
+
await fs.access(candidate);
|
|
215
|
+
return candidate;
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
// continue
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
222
|
+
};
|
|
223
|
+
const agentSource = await pickExisting(agentSources);
|
|
224
|
+
const userSource = await pickExisting(userSources);
|
|
225
|
+
const wroteAgent = agentSource
|
|
226
|
+
? await copyIdentityFile({
|
|
227
|
+
sourcePath: agentSource,
|
|
228
|
+
destinationPath: agentIdentityPath,
|
|
229
|
+
ensureNameLine: true,
|
|
230
|
+
})
|
|
231
|
+
: false;
|
|
232
|
+
const wroteUser = userSource
|
|
233
|
+
? await copyIdentityFile({
|
|
234
|
+
sourcePath: userSource,
|
|
235
|
+
destinationPath: userIdentityPath,
|
|
236
|
+
ensureNameLine: true,
|
|
237
|
+
})
|
|
238
|
+
: false;
|
|
239
|
+
const soulSource = await pickExisting(soulSources);
|
|
240
|
+
const memorySource = await pickExisting(memorySources);
|
|
241
|
+
const wroteSoul = soulSource
|
|
242
|
+
? await copyIdentityFile({
|
|
243
|
+
sourcePath: soulSource,
|
|
244
|
+
destinationPath: agentSoulPath,
|
|
245
|
+
})
|
|
246
|
+
: false;
|
|
247
|
+
const wroteMemory = memorySource
|
|
248
|
+
? await copyIdentityFile({
|
|
249
|
+
sourcePath: memorySource,
|
|
250
|
+
destinationPath: agentMemoryPath,
|
|
251
|
+
})
|
|
252
|
+
: false;
|
|
253
|
+
if (wroteAgent || wroteUser || wroteSoul || wroteMemory) {
|
|
254
|
+
params.runtime.log(`✓ Copied identity files from ${resolvedSource} (bootstrap skipped)`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function isGatewayCommandMatch(existing, expected) {
|
|
258
|
+
const existingArgs = existing.programArguments.map((arg) => arg.trim());
|
|
259
|
+
const expectedArgs = expected.programArguments.map((arg) => arg.trim());
|
|
260
|
+
if (existingArgs.length !== expectedArgs.length)
|
|
261
|
+
return false;
|
|
262
|
+
for (let i = 0; i < expectedArgs.length; i += 1) {
|
|
263
|
+
if (existingArgs[i] !== expectedArgs[i])
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
const existingDir = existing.workingDirectory?.trim() || "";
|
|
267
|
+
const expectedDir = expected.workingDirectory?.trim() || "";
|
|
268
|
+
return existingDir === expectedDir;
|
|
269
|
+
}
|
|
270
|
+
function hasGatewayEnvMismatch(existing, expected) {
|
|
271
|
+
const keysToCheck = Object.entries(expected).filter(([key]) => key !== "PATH");
|
|
272
|
+
if (!existing?.environment) {
|
|
273
|
+
return keysToCheck.some(([, value]) => Boolean(value?.trim()));
|
|
274
|
+
}
|
|
275
|
+
for (const [key, value] of keysToCheck) {
|
|
276
|
+
if (!value?.trim())
|
|
277
|
+
continue;
|
|
278
|
+
if (existing.environment[key] !== value) {
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
async function ensureGatewayDaemon(params) {
|
|
285
|
+
if (params.env.NEXUS_INIT_SKIP_DAEMON === "1")
|
|
286
|
+
return;
|
|
287
|
+
const runtime = params.runtime;
|
|
288
|
+
let nextConfig = params.configSnapshot.config ?? {};
|
|
289
|
+
const gateway = { ...nextConfig.gateway };
|
|
290
|
+
let updated = false;
|
|
291
|
+
if (!gateway.mode) {
|
|
292
|
+
gateway.mode = "local";
|
|
293
|
+
updated = true;
|
|
294
|
+
}
|
|
295
|
+
if (!gateway.bind) {
|
|
296
|
+
gateway.bind = "loopback";
|
|
297
|
+
updated = true;
|
|
298
|
+
}
|
|
299
|
+
const tailscaleMode = gateway.tailscale?.mode;
|
|
300
|
+
if (!tailscaleMode) {
|
|
301
|
+
gateway.tailscale = { ...gateway.tailscale, mode: "off" };
|
|
302
|
+
updated = true;
|
|
303
|
+
}
|
|
304
|
+
if (updated) {
|
|
305
|
+
nextConfig = { ...nextConfig, gateway };
|
|
306
|
+
await writeConfigFile(nextConfig);
|
|
307
|
+
runtime.log(`✓ Updated config file: ${CONFIG_PATH_NEXUS}`);
|
|
308
|
+
}
|
|
309
|
+
await ensureSystemdUserLingerNonInteractive({ runtime, env: params.env });
|
|
310
|
+
const service = resolveGatewayService();
|
|
311
|
+
const loaded = await service.isLoaded({ env: params.env });
|
|
312
|
+
const port = resolveGatewayPort(nextConfig, params.env);
|
|
313
|
+
const devMode = process.argv[1]?.includes("/src/") && process.argv[1]?.endsWith(".ts");
|
|
314
|
+
const { programArguments, workingDirectory } = await resolveGatewayProgramArguments({ port, dev: devMode });
|
|
315
|
+
const environment = {
|
|
316
|
+
PATH: params.env.PATH,
|
|
317
|
+
NEXUS_ROOT: params.env.NEXUS_ROOT,
|
|
318
|
+
NEXUS_STATE_DIR: params.env.NEXUS_STATE_DIR,
|
|
319
|
+
NEXUS_AGENT_ID: params.env.NEXUS_AGENT_ID,
|
|
320
|
+
NEXUS_PROFILE: params.env.NEXUS_PROFILE,
|
|
321
|
+
NEXUS_LAUNCHD_LABEL: process.platform === "darwin" ? GATEWAY_LAUNCH_AGENT_LABEL : undefined,
|
|
322
|
+
};
|
|
323
|
+
const existing = loaded ? await service.readCommand(params.env) : null;
|
|
324
|
+
const shouldReinstall = !existing ||
|
|
325
|
+
!isGatewayCommandMatch(existing, { programArguments, workingDirectory }) ||
|
|
326
|
+
hasGatewayEnvMismatch(existing, environment);
|
|
327
|
+
if (!loaded || shouldReinstall) {
|
|
328
|
+
await service.install({
|
|
329
|
+
env: params.env,
|
|
330
|
+
stdout: process.stdout,
|
|
331
|
+
programArguments,
|
|
332
|
+
workingDirectory,
|
|
333
|
+
environment,
|
|
334
|
+
});
|
|
335
|
+
runtime.log(`✓ Installed ${service.label} gateway daemon`);
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
await service.restart({ stdout: process.stdout });
|
|
339
|
+
runtime.log(`✓ Restarted ${service.label} gateway daemon`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
80
342
|
/**
|
|
81
343
|
* Creates the Nexus directory structure:
|
|
82
|
-
* - ~/nexus/ (root with AGENTS.md
|
|
344
|
+
* - ~/nexus/ (root with AGENTS.md, .cursor/rules, .cursor/hooks.json)
|
|
83
345
|
* - ~/nexus/home/ (user workspace)
|
|
84
346
|
* - ~/nexus/state/ (state directory)
|
|
85
347
|
*/
|
|
86
348
|
export async function initCommand(opts, runtime = defaultRuntime) {
|
|
87
|
-
const workspaceDir = opts?.workspace?.trim() ||
|
|
349
|
+
const workspaceDir = opts?.workspace?.trim() ||
|
|
350
|
+
path.join(process.env.HOME || "~", "nexus", "home");
|
|
351
|
+
const createHomeLayout = false;
|
|
88
352
|
// 1. Create workspace directory and Nexus state scaffolding
|
|
89
353
|
const workspace = await ensureAgentWorkspace({
|
|
90
354
|
dir: workspaceDir,
|
|
91
355
|
ensureBootstrapFiles: true,
|
|
356
|
+
bootstrapMode: "minimal",
|
|
357
|
+
createHomeLayout,
|
|
92
358
|
});
|
|
93
359
|
runtime.log(`✓ Created workspace: ${workspace.dir}`);
|
|
94
360
|
if (workspace.agentsPath)
|
|
95
361
|
runtime.log(` - ${path.basename(workspace.agentsPath)}`);
|
|
96
|
-
if (workspace.toolsPath)
|
|
362
|
+
if (workspace.toolsPath && createHomeLayout)
|
|
97
363
|
runtime.log(` - ${path.basename(workspace.toolsPath)}`);
|
|
98
364
|
if (workspace.bootstrapPath)
|
|
99
365
|
runtime.log(` - ${path.basename(workspace.bootstrapPath)}`);
|
|
100
|
-
|
|
366
|
+
await copyIdentityForInit({ env: process.env, runtime, workspace });
|
|
367
|
+
// 2. Resolve user skills directory (may be created later by user)
|
|
101
368
|
const userSkillsDir = path.join(workspace.dir, "skills");
|
|
102
|
-
await fs.mkdir(userSkillsDir, { recursive: true });
|
|
103
|
-
runtime.log(`✓ Created user skills directory: ${userSkillsDir}`);
|
|
104
|
-
// 3. Create memory/ and projects/ directories
|
|
105
|
-
const memoryDir = path.join(workspace.dir, "memory");
|
|
106
|
-
await fs.mkdir(memoryDir, { recursive: true });
|
|
107
|
-
const projectsDir = path.join(workspace.dir, "projects");
|
|
108
|
-
await fs.mkdir(projectsDir, { recursive: true });
|
|
109
|
-
runtime.log(`✓ Created memory directory: ${memoryDir}`);
|
|
110
|
-
runtime.log(`✓ Created projects directory: ${projectsDir}`);
|
|
111
369
|
// 4. Create state directory (~/nexus/state)
|
|
112
370
|
const stateDir = resolveStateDir();
|
|
113
371
|
await fs.mkdir(stateDir, { recursive: true });
|
|
@@ -131,10 +389,21 @@ export async function initCommand(opts, runtime = defaultRuntime) {
|
|
|
131
389
|
};
|
|
132
390
|
await fs.writeFile(workspaceMetaPath, JSON.stringify(workspaceMeta, null, 2), "utf-8");
|
|
133
391
|
runtime.log(`✓ Created workspace metadata: ${workspaceMetaPath}`);
|
|
392
|
+
const configSnapshot = await readConfigFileSnapshot();
|
|
393
|
+
// 5b. Ensure credential index
|
|
394
|
+
await scanCredentials();
|
|
395
|
+
runtime.log(`✓ Created credential index: ${path.join(stateDir, "credentials", "index.json")}`);
|
|
134
396
|
// 6. Create main skills directory (~/nexus/skills) and copy bundled skills
|
|
135
|
-
const skillsDir =
|
|
397
|
+
const skillsDir = WORKSPACE_SKILLS_DIR;
|
|
136
398
|
await fs.mkdir(skillsDir, { recursive: true });
|
|
399
|
+
await fs.mkdir(path.join(skillsDir, "tools"), { recursive: true });
|
|
400
|
+
await fs.mkdir(path.join(skillsDir, "connectors"), { recursive: true });
|
|
401
|
+
await fs.mkdir(path.join(skillsDir, "guides"), { recursive: true });
|
|
402
|
+
await fs.mkdir(path.join(skillsDir, "managed"), { recursive: true });
|
|
137
403
|
runtime.log(`✓ Created skills directory: ${skillsDir}`);
|
|
404
|
+
// 6b. Create skills state directory (state/skills)
|
|
405
|
+
await fs.mkdir(SKILLS_STATE_DIR, { recursive: true });
|
|
406
|
+
runtime.log(`✓ Created skills state directory: ${SKILLS_STATE_DIR}`);
|
|
138
407
|
// Copy bundled skills from installed package to ~/nexus/skills/
|
|
139
408
|
const copyResult = await copyBundledSkills(skillsDir);
|
|
140
409
|
if (copyResult.copied.length > 0) {
|
|
@@ -160,8 +429,23 @@ export async function initCommand(opts, runtime = defaultRuntime) {
|
|
|
160
429
|
includeBootstrap: false,
|
|
161
430
|
});
|
|
162
431
|
runtime.log(`✓ Created Cursor rules: ${cursorRulesPath}`);
|
|
163
|
-
//
|
|
164
|
-
await
|
|
432
|
+
// 8b. Write Cursor hooks (sessionStart bootstrap)
|
|
433
|
+
const cursorHooks = await writeCursorHooks({ workspaceDir: NEXUS_ROOT });
|
|
434
|
+
if (cursorHooks.hooksCreated || cursorHooks.scriptCreated) {
|
|
435
|
+
runtime.log(`✓ Created Cursor hooks: ${cursorHooks.hooksPath}`);
|
|
436
|
+
if (cursorHooks.scriptCreated) {
|
|
437
|
+
runtime.log(` - ${cursorHooks.scriptPath}`);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
runtime.log(`✓ Cursor hooks already present: ${cursorHooks.hooksPath}`);
|
|
442
|
+
}
|
|
443
|
+
// 9. Install and start gateway daemon
|
|
444
|
+
await ensureGatewayDaemon({
|
|
445
|
+
runtime,
|
|
446
|
+
env: process.env,
|
|
447
|
+
configSnapshot,
|
|
448
|
+
});
|
|
165
449
|
runtime.log("\nNexus initialization complete!");
|
|
166
450
|
runtime.log(`\nNext steps:\n - Run 'nexus status' to orient\n - Open ${NEXUS_ROOT} in your editor`);
|
|
167
451
|
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parseDurationMs } from "../cli/parse-duration.js";
|
|
4
|
+
import { readSkillUsageEntries } from "../agents/skill-usage.js";
|
|
5
|
+
import { resolveEventLogDir } from "../infra/event-log.js";
|
|
6
|
+
import { defaultRuntime } from "../runtime.js";
|
|
7
|
+
function parseSince(raw) {
|
|
8
|
+
if (!raw)
|
|
9
|
+
return undefined;
|
|
10
|
+
const trimmed = raw.trim();
|
|
11
|
+
if (!trimmed)
|
|
12
|
+
return undefined;
|
|
13
|
+
const parsedDate = Date.parse(trimmed);
|
|
14
|
+
if (!Number.isNaN(parsedDate)) {
|
|
15
|
+
return parsedDate;
|
|
16
|
+
}
|
|
17
|
+
const ms = parseDurationMs(trimmed, { defaultUnit: "h" });
|
|
18
|
+
return Date.now() - ms;
|
|
19
|
+
}
|
|
20
|
+
function readEventFiles(dir) {
|
|
21
|
+
try {
|
|
22
|
+
return fs
|
|
23
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
24
|
+
.filter((entry) => entry.isFile() &&
|
|
25
|
+
entry.name.startsWith("events-") &&
|
|
26
|
+
entry.name.endsWith(".jsonl"))
|
|
27
|
+
.map((entry) => entry.name)
|
|
28
|
+
.sort();
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function parseEventLine(line) {
|
|
35
|
+
try {
|
|
36
|
+
const parsed = JSON.parse(line);
|
|
37
|
+
if (!parsed || typeof parsed !== "object")
|
|
38
|
+
return null;
|
|
39
|
+
if (typeof parsed.ts !== "number")
|
|
40
|
+
return null;
|
|
41
|
+
return parsed;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function loadEventLogEntries(opts) {
|
|
48
|
+
const dir = resolveEventLogDir();
|
|
49
|
+
const files = readEventFiles(dir);
|
|
50
|
+
const events = [];
|
|
51
|
+
for (const file of files) {
|
|
52
|
+
const filePath = path.join(dir, file);
|
|
53
|
+
let raw = "";
|
|
54
|
+
try {
|
|
55
|
+
raw = fs.readFileSync(filePath, "utf-8");
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
61
|
+
if (!line.trim())
|
|
62
|
+
continue;
|
|
63
|
+
const event = parseEventLine(line);
|
|
64
|
+
if (!event)
|
|
65
|
+
continue;
|
|
66
|
+
if (opts.sinceMs && event.ts < opts.sinceMs)
|
|
67
|
+
continue;
|
|
68
|
+
if (opts.source && event.source !== opts.source)
|
|
69
|
+
continue;
|
|
70
|
+
if (opts.command && event.command_path !== opts.command)
|
|
71
|
+
continue;
|
|
72
|
+
if (opts.errors) {
|
|
73
|
+
const isError = event.status === "error" ||
|
|
74
|
+
event.event_type === "command_failed" ||
|
|
75
|
+
event.event_type === "cli_session_end";
|
|
76
|
+
if (!isError)
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
events.push(event);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (opts.limit && opts.limit > 0 && events.length > opts.limit) {
|
|
83
|
+
return events.slice(-opts.limit);
|
|
84
|
+
}
|
|
85
|
+
return events;
|
|
86
|
+
}
|
|
87
|
+
export async function logCommand(opts, runtime = defaultRuntime) {
|
|
88
|
+
const sinceMs = parseSince(opts.since);
|
|
89
|
+
const limit = opts.limit && opts.limit > 0 ? opts.limit : undefined;
|
|
90
|
+
if (opts.skill) {
|
|
91
|
+
const entries = readSkillUsageEntries(opts.skill, {
|
|
92
|
+
sinceMs,
|
|
93
|
+
limit,
|
|
94
|
+
});
|
|
95
|
+
if (opts.json) {
|
|
96
|
+
runtime.log(JSON.stringify({ skill: opts.skill, entries }, null, 2));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (entries.length === 0) {
|
|
100
|
+
runtime.log("No skill usage found.");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
for (const entry of entries) {
|
|
104
|
+
const time = new Date(entry.ts).toISOString();
|
|
105
|
+
const status = entry.ok ? "ok" : "error";
|
|
106
|
+
const duration = typeof entry.durationMs === "number"
|
|
107
|
+
? ` ${entry.durationMs}ms`
|
|
108
|
+
: "";
|
|
109
|
+
runtime.log(`${time} ${entry.event} ${status}${duration}`);
|
|
110
|
+
}
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const events = loadEventLogEntries({
|
|
114
|
+
sinceMs,
|
|
115
|
+
errors: opts.errors,
|
|
116
|
+
source: opts.source,
|
|
117
|
+
command: opts.command,
|
|
118
|
+
limit,
|
|
119
|
+
});
|
|
120
|
+
if (opts.json) {
|
|
121
|
+
runtime.log(JSON.stringify({ events }, null, 2));
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (events.length === 0) {
|
|
125
|
+
runtime.log("No events found.");
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
for (const event of events) {
|
|
129
|
+
const time = new Date(event.ts).toISOString();
|
|
130
|
+
const status = event.status ?? "-";
|
|
131
|
+
const command = event.command_path ?? event.event_type ?? "-";
|
|
132
|
+
runtime.log(`${time} ${event.source}:${command} ${status}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildModelAliasIndex, resolveModelRefFromString } from "../../agents/model-selection.js";
|
|
1
|
+
import { buildModelAliasIndex, resolveModelRefFromString, } from "../../agents/model-selection.js";
|
|
2
2
|
import { CONFIG_PATH_NEXUS, loadConfig } from "../../config/config.js";
|
|
3
3
|
import { DEFAULT_PROVIDER, ensureFlagCompatibility, modelKey, resolveModelTarget, updateConfig, } from "./shared.js";
|
|
4
4
|
export async function modelsFallbacksListCommand(opts, runtime) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildModelAliasIndex, resolveModelRefFromString } from "../../agents/model-selection.js";
|
|
1
|
+
import { buildModelAliasIndex, resolveModelRefFromString, } from "../../agents/model-selection.js";
|
|
2
2
|
import { CONFIG_PATH_NEXUS, loadConfig } from "../../config/config.js";
|
|
3
3
|
import { DEFAULT_PROVIDER, ensureFlagCompatibility, modelKey, resolveModelTarget, updateConfig, } from "./shared.js";
|
|
4
4
|
export async function modelsImageFallbacksListCommand(opts, runtime) {
|
|
@@ -5,7 +5,7 @@ import { ensureAuthProfileStore, listProfilesForProvider, } from "../../agents/a
|
|
|
5
5
|
import { getCustomProviderApiKey, resolveEnvApiKey, } from "../../agents/model-auth.js";
|
|
6
6
|
import { buildModelAliasIndex, parseModelRef, resolveConfiguredModelRef, resolveModelRefFromString, } from "../../agents/model-selection.js";
|
|
7
7
|
import { ensureNexusModelsJson } from "../../agents/models-config.js";
|
|
8
|
-
import { CONFIG_PATH_NEXUS, loadConfig } from "../../config/config.js";
|
|
8
|
+
import { CONFIG_PATH_NEXUS, loadConfig, } from "../../config/config.js";
|
|
9
9
|
import { info } from "../../globals.js";
|
|
10
10
|
import { DEFAULT_MODEL, DEFAULT_PROVIDER, ensureFlagCompatibility, formatTokenK, modelKey, } from "./shared.js";
|
|
11
11
|
const MODEL_PAD = 42;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cancel, isCancel, multiselect } from "@clack/prompts";
|
|
2
2
|
import { resolveApiKeyForProvider } from "../../agents/model-auth.js";
|
|
3
|
-
import { scanOpenRouterModels } from "../../agents/model-scan.js";
|
|
3
|
+
import { scanOpenRouterModels, } from "../../agents/model-scan.js";
|
|
4
4
|
import { CONFIG_PATH_NEXUS, loadConfig } from "../../config/config.js";
|
|
5
5
|
import { formatMs, formatTokenK, updateConfig } from "./shared.js";
|
|
6
6
|
const MODEL_PAD = 42;
|
|
@@ -1,11 +1,36 @@
|
|
|
1
1
|
import { upsertAuthProfile } from "../agents/auth-profiles.js";
|
|
2
2
|
export async function writeOAuthCredentials(provider, creds) {
|
|
3
|
+
const access = "accessToken" in creds && typeof creds.accessToken === "string"
|
|
4
|
+
? creds.accessToken
|
|
5
|
+
: typeof creds.access === "string"
|
|
6
|
+
? creds.access
|
|
7
|
+
: undefined;
|
|
8
|
+
const refresh = "refreshToken" in creds && typeof creds.refreshToken === "string"
|
|
9
|
+
? creds.refreshToken
|
|
10
|
+
: typeof creds.refresh === "string"
|
|
11
|
+
? creds.refresh
|
|
12
|
+
: undefined;
|
|
13
|
+
const rawExpires = "expiresAt" in creds
|
|
14
|
+
? creds.expiresAt
|
|
15
|
+
: creds.expires;
|
|
16
|
+
const parsedExpires = typeof rawExpires === "number"
|
|
17
|
+
? rawExpires
|
|
18
|
+
: typeof rawExpires === "string"
|
|
19
|
+
? Number.parseInt(rawExpires, 10)
|
|
20
|
+
: undefined;
|
|
21
|
+
const expires = typeof parsedExpires === "number" && Number.isFinite(parsedExpires)
|
|
22
|
+
? parsedExpires
|
|
23
|
+
: undefined;
|
|
24
|
+
const email = typeof creds.email === "string" ? creds.email : undefined;
|
|
3
25
|
upsertAuthProfile({
|
|
4
|
-
profileId: `${provider}:${
|
|
26
|
+
profileId: `${provider}:${email ?? "default"}`,
|
|
5
27
|
credential: {
|
|
6
28
|
type: "oauth",
|
|
7
29
|
provider,
|
|
8
|
-
|
|
30
|
+
access,
|
|
31
|
+
refresh,
|
|
32
|
+
expires,
|
|
33
|
+
email,
|
|
9
34
|
},
|
|
10
35
|
});
|
|
11
36
|
}
|
|
@@ -5,7 +5,10 @@ const execFileAsync = promisify(execFile);
|
|
|
5
5
|
function coerceStringArray(input) {
|
|
6
6
|
if (!Array.isArray(input))
|
|
7
7
|
return [];
|
|
8
|
-
return input
|
|
8
|
+
return input
|
|
9
|
+
.map((v) => String(v))
|
|
10
|
+
.map((s) => s.trim())
|
|
11
|
+
.filter(Boolean);
|
|
9
12
|
}
|
|
10
13
|
function parseEveWhoamiJson(stdout) {
|
|
11
14
|
const raw = stdout.trim();
|
|
@@ -78,21 +81,17 @@ export async function maybeSetupIdentityFromEve(params) {
|
|
|
78
81
|
await prompter.note(`Eve whoami failed: ${err instanceof Error ? err.message : String(err)}`, "Eve whoami");
|
|
79
82
|
return;
|
|
80
83
|
}
|
|
81
|
-
if (!whoami?.name &&
|
|
84
|
+
if (!whoami?.name && !whoami?.phones?.length && !whoami?.emails?.length) {
|
|
82
85
|
await prompter.note("Eve ran, but didn't return identity info in a readable format.", "Eve whoami");
|
|
83
86
|
return;
|
|
84
87
|
}
|
|
85
88
|
const summaryLines = [
|
|
86
89
|
whoami.name ? `Name: ${whoami.name}` : undefined,
|
|
87
|
-
whoami.phones
|
|
88
|
-
|
|
89
|
-
: undefined,
|
|
90
|
-
whoami.emails && whoami.emails.length
|
|
91
|
-
? `Emails: ${whoami.emails.join(", ")}`
|
|
92
|
-
: undefined,
|
|
90
|
+
whoami.phones?.length ? `Phones: ${whoami.phones.join(", ")}` : undefined,
|
|
91
|
+
whoami.emails?.length ? `Emails: ${whoami.emails.join(", ")}` : undefined,
|
|
93
92
|
].filter(Boolean);
|
|
94
93
|
await prompter.note(summaryLines.join("\n"), "Detected identity (Eve)");
|
|
95
|
-
// NOTE: We don't directly edit
|
|
94
|
+
// NOTE: We don't directly edit agent/user IDENTITY.md here yet; the bootstrap ritual
|
|
96
95
|
// should incorporate these values when it runs. Next step: write this into config
|
|
97
96
|
// and/or workspace files once we agree on the exact schema + wording.
|
|
98
97
|
}
|
|
@@ -5,9 +5,9 @@ import { resolveGatewayProgramArguments } from "../daemon/program-args.js";
|
|
|
5
5
|
import { resolveGatewayService } from "../daemon/service.js";
|
|
6
6
|
import { defaultRuntime } from "../runtime.js";
|
|
7
7
|
import { resolveUserPath, sleep } from "../utils.js";
|
|
8
|
+
import { applyBootstrapPreset } from "./bootstrap-preset.js";
|
|
8
9
|
import { healthCommand } from "./health.js";
|
|
9
10
|
import { applyAuthProfileConfig, applyMinimaxConfig, setAnthropicApiKey, } from "./onboard-auth.js";
|
|
10
|
-
import { applyBootstrapPreset } from "./bootstrap-preset.js";
|
|
11
11
|
import { applyWizardMetadata, DEFAULT_WORKSPACE, ensureWorkspaceAndSessions, randomToken, } from "./onboard-helpers.js";
|
|
12
12
|
import { ensureSystemdUserLingerNonInteractive } from "./systemd-linger.js";
|
|
13
13
|
export async function runNonInteractiveOnboarding(opts, runtime = defaultRuntime) {
|
|
@@ -180,7 +180,9 @@ export async function runNonInteractiveOnboarding(opts, runtime = defaultRuntime
|
|
|
180
180
|
skipBootstrap: Boolean(nextConfig.agent?.skipBootstrap),
|
|
181
181
|
});
|
|
182
182
|
// Scripted bootstrap (test harness / automation): fill identity files + delete BOOTSTRAP.md.
|
|
183
|
-
if (opts.bootstrapPreset ||
|
|
183
|
+
if (opts.bootstrapPreset ||
|
|
184
|
+
opts.bootstrapAgentName ||
|
|
185
|
+
opts.bootstrapUserName) {
|
|
184
186
|
await applyBootstrapPreset({
|
|
185
187
|
workspaceDir,
|
|
186
188
|
runtime,
|