@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/cli/skills-cli.js
CHANGED
|
@@ -1,39 +1,156 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import chalk from "chalk";
|
|
3
|
-
import { getSkillInfo,
|
|
4
|
-
import { getAggregateStats, getSkillStats } from "../agents/skill-usage.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { getSkillInfo, verifySkill } from "../agents/skill-runner.js";
|
|
4
|
+
import { getAggregateStats, getSkillStats, hasSkillUsage, recordSkillUsage, } from "../agents/skill-usage.js";
|
|
5
|
+
import { getSkillMetadata, loadWorkspaceSkillEntries } from "../agents/skills.js";
|
|
6
|
+
import { buildWorkspaceSkillStatus } from "../agents/skills-status.js";
|
|
7
|
+
import { DEFAULT_AGENT_WORKSPACE_DIR } from "../agents/workspace.js";
|
|
8
|
+
import { loadConfig } from "../config/config.js";
|
|
9
|
+
import { NEXUS_ROOT, SKILLS_STATE_DIR, resolveUserPath } from "../utils.js";
|
|
10
|
+
const STATUS_ICON = {
|
|
11
|
+
active: "✅",
|
|
12
|
+
ready: "⭐",
|
|
13
|
+
needs_setup: "🔧",
|
|
14
|
+
needs_install: "📥",
|
|
15
|
+
unavailable: "⛔",
|
|
16
|
+
};
|
|
17
|
+
function resolveSkillType(entry) {
|
|
18
|
+
const metadata = getSkillMetadata(entry);
|
|
19
|
+
if (metadata?.type)
|
|
20
|
+
return metadata.type;
|
|
21
|
+
const requires = metadata?.requires;
|
|
22
|
+
if (requires?.env?.length || requires?.config?.length)
|
|
23
|
+
return "connector";
|
|
24
|
+
if (requires?.bins?.length || requires?.anyBins?.length)
|
|
25
|
+
return "tool";
|
|
26
|
+
return "guide";
|
|
27
|
+
}
|
|
28
|
+
function resolveSkillStatus(statusEntry) {
|
|
29
|
+
if (statusEntry.disabled || statusEntry.blockedByAllowlist) {
|
|
30
|
+
return "unavailable";
|
|
31
|
+
}
|
|
32
|
+
if (statusEntry.missing.os.length > 0)
|
|
33
|
+
return "unavailable";
|
|
34
|
+
if (statusEntry.missing.bins.length > 0)
|
|
35
|
+
return "needs_install";
|
|
36
|
+
if (statusEntry.missing.env.length > 0 || statusEntry.missing.config.length > 0) {
|
|
37
|
+
return "needs_setup";
|
|
38
|
+
}
|
|
39
|
+
if (hasSkillUsage(statusEntry.name))
|
|
40
|
+
return "active";
|
|
41
|
+
return "ready";
|
|
42
|
+
}
|
|
7
43
|
export function registerSkillsCommand(program) {
|
|
8
44
|
const skill = program.command("skill").description("Use and inspect skills");
|
|
9
45
|
skill
|
|
10
46
|
.command("list")
|
|
11
47
|
.description("List all available skills")
|
|
12
48
|
.option("--json", "Output as JSON")
|
|
49
|
+
.option("--type <type>", "Filter by type (guide|tool|connector)")
|
|
50
|
+
.option("--status <status>", "Filter by status (active|ready|needs-setup|needs-install|unavailable)")
|
|
51
|
+
.option("--active", "Only show active skills")
|
|
52
|
+
.option("--ready", "Only show ready skills")
|
|
53
|
+
.option("--needs-setup", "Only show skills needing setup")
|
|
54
|
+
.option("--needs-install", "Only show skills needing install")
|
|
55
|
+
.option("--unavailable", "Only show unavailable skills")
|
|
56
|
+
.option("--all", "Include unavailable skills")
|
|
13
57
|
.action(async (opts) => {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
58
|
+
const config = loadConfig();
|
|
59
|
+
const workspaceDir = resolveUserPath(config.agent?.workspace ?? DEFAULT_AGENT_WORKSPACE_DIR);
|
|
60
|
+
const managedSkillsDir = path.join(NEXUS_ROOT, "skills", "managed");
|
|
61
|
+
const entries = loadWorkspaceSkillEntries(workspaceDir, {
|
|
62
|
+
config,
|
|
63
|
+
managedSkillsDir,
|
|
64
|
+
});
|
|
65
|
+
const status = buildWorkspaceSkillStatus(workspaceDir, {
|
|
66
|
+
config,
|
|
67
|
+
managedSkillsDir,
|
|
68
|
+
entries,
|
|
69
|
+
});
|
|
70
|
+
const statusMap = new Map(status.skills.map((item) => [item.name.toLowerCase(), item]));
|
|
71
|
+
const items = entries.map((entry) => {
|
|
72
|
+
const statusEntry = statusMap.get(entry.skill.name.toLowerCase());
|
|
73
|
+
const statusValue = statusEntry
|
|
74
|
+
? resolveSkillStatus(statusEntry)
|
|
75
|
+
: "unavailable";
|
|
76
|
+
return {
|
|
77
|
+
name: entry.skill.name,
|
|
78
|
+
description: entry.skill.description,
|
|
79
|
+
type: resolveSkillType(entry),
|
|
80
|
+
status: statusValue,
|
|
81
|
+
source: entry.skill.source,
|
|
82
|
+
filePath: entry.skill.filePath,
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
const typeFilter = opts.type
|
|
86
|
+
? String(opts.type).toLowerCase()
|
|
87
|
+
: undefined;
|
|
88
|
+
const statusFilters = new Set();
|
|
89
|
+
if (opts.status) {
|
|
90
|
+
const raw = String(opts.status)
|
|
91
|
+
.split(",")
|
|
92
|
+
.map((entry) => entry.trim().toLowerCase())
|
|
93
|
+
.filter(Boolean);
|
|
94
|
+
for (const entry of raw) {
|
|
95
|
+
const normalized = entry.replace(/_/g, "-");
|
|
96
|
+
if (normalized === "needs-setup")
|
|
97
|
+
statusFilters.add("needs_setup");
|
|
98
|
+
else if (normalized === "needs-install")
|
|
99
|
+
statusFilters.add("needs_install");
|
|
100
|
+
else if (normalized === "active")
|
|
101
|
+
statusFilters.add("active");
|
|
102
|
+
else if (normalized === "ready")
|
|
103
|
+
statusFilters.add("ready");
|
|
104
|
+
else if (normalized === "unavailable")
|
|
105
|
+
statusFilters.add("unavailable");
|
|
106
|
+
}
|
|
18
107
|
}
|
|
108
|
+
if (opts.active)
|
|
109
|
+
statusFilters.add("active");
|
|
110
|
+
if (opts.ready)
|
|
111
|
+
statusFilters.add("ready");
|
|
112
|
+
if (opts.needsSetup)
|
|
113
|
+
statusFilters.add("needs_setup");
|
|
114
|
+
if (opts.needsInstall)
|
|
115
|
+
statusFilters.add("needs_install");
|
|
116
|
+
if (opts.unavailable)
|
|
117
|
+
statusFilters.add("unavailable");
|
|
118
|
+
const hasStatusFilter = statusFilters.size > 0;
|
|
119
|
+
const filtered = items.filter((item) => {
|
|
120
|
+
if (typeFilter && item.type !== typeFilter)
|
|
121
|
+
return false;
|
|
122
|
+
if (hasStatusFilter && !statusFilters.has(item.status))
|
|
123
|
+
return false;
|
|
124
|
+
if (!hasStatusFilter && !opts.all && item.status === "unavailable")
|
|
125
|
+
return false;
|
|
126
|
+
return true;
|
|
127
|
+
});
|
|
19
128
|
if (opts.json) {
|
|
20
|
-
console.log(JSON.stringify(
|
|
129
|
+
console.log(JSON.stringify({
|
|
130
|
+
workspace: workspaceDir,
|
|
131
|
+
total: items.length,
|
|
132
|
+
filtered: filtered.length,
|
|
133
|
+
skills: filtered,
|
|
134
|
+
}, null, 2));
|
|
21
135
|
return;
|
|
22
136
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
console.log("No skills installed.");
|
|
137
|
+
if (filtered.length === 0) {
|
|
138
|
+
console.log("No skills matched.");
|
|
26
139
|
return;
|
|
27
140
|
}
|
|
28
|
-
console.log(`\n📚 Nexus Skills (${
|
|
29
|
-
for (const
|
|
30
|
-
const desc =
|
|
31
|
-
? ` - ${
|
|
141
|
+
console.log(`\n📚 Nexus Skills (${filtered.length} shown)\n`);
|
|
142
|
+
for (const item of filtered) {
|
|
143
|
+
const desc = item.description
|
|
144
|
+
? ` - ${item.description.slice(0, 60)}${item.description.length > 60 ? "..." : ""}`
|
|
32
145
|
: "";
|
|
33
|
-
|
|
146
|
+
const icon = STATUS_ICON[item.status] ?? "•";
|
|
147
|
+
console.log(` ${icon} ${item.name}${desc}`);
|
|
34
148
|
}
|
|
35
|
-
|
|
36
|
-
console.log(
|
|
149
|
+
const skillsRoot = path.join(NEXUS_ROOT, "skills");
|
|
150
|
+
console.log(`\nSkills directory: ${skillsRoot}`);
|
|
151
|
+
console.log(`Skill types: ${path.join(skillsRoot, "tools")}, ${path.join(skillsRoot, "connectors")}, ${path.join(skillsRoot, "guides")}`);
|
|
152
|
+
console.log(`Skill state: ${SKILLS_STATE_DIR}`);
|
|
153
|
+
console.log(`User skills: ${path.join(workspaceDir, "skills")}\n`);
|
|
37
154
|
});
|
|
38
155
|
skill
|
|
39
156
|
.command("info <name>")
|
|
@@ -42,6 +159,7 @@ export function registerSkillsCommand(program) {
|
|
|
42
159
|
.option("--prompt", "Include the full SKILL.md prompt")
|
|
43
160
|
.action(async (name, opts) => {
|
|
44
161
|
const info = getSkillInfo(name);
|
|
162
|
+
const stats = await getSkillStats(name);
|
|
45
163
|
if (!info.exists) {
|
|
46
164
|
console.error(`Skill not found: ${name}`);
|
|
47
165
|
console.error(`\nRun 'nexus skill list' to see available skills.`);
|
|
@@ -49,7 +167,8 @@ export function registerSkillsCommand(program) {
|
|
|
49
167
|
}
|
|
50
168
|
if (opts.json) {
|
|
51
169
|
const output = opts.prompt ? info : { ...info, prompt: undefined };
|
|
52
|
-
|
|
170
|
+
const payload = stats ? { ...output, usage: stats } : output;
|
|
171
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
53
172
|
return;
|
|
54
173
|
}
|
|
55
174
|
console.log(`\n${chalk.bold.cyan("Skill:")} ${info.name}`);
|
|
@@ -63,12 +182,16 @@ export function registerSkillsCommand(program) {
|
|
|
63
182
|
const statusColor = info.configured ? chalk.green : chalk.yellow;
|
|
64
183
|
const statusIcon = info.configured ? "✓" : "○";
|
|
65
184
|
console.log(`${chalk.bold("Status:")} ${statusColor(`${statusIcon} ${info.configured ? "Configured" : "Not configured"}`)}`);
|
|
66
|
-
if (info.lastUsed) {
|
|
67
|
-
console.log(`${chalk.bold("Last used:")} ${info.lastUsed}`);
|
|
185
|
+
if (stats?.lastUsed ?? info.lastUsed) {
|
|
186
|
+
console.log(`${chalk.bold("Last used:")} ${stats?.lastUsed ?? info.lastUsed}`);
|
|
68
187
|
}
|
|
69
188
|
if (info.lastError) {
|
|
70
189
|
console.log(`${chalk.bold("Last error:")} ${chalk.red(info.lastError)}`);
|
|
71
190
|
}
|
|
191
|
+
if (stats) {
|
|
192
|
+
console.log(`${chalk.bold("Runs:")} ${stats.runs}`);
|
|
193
|
+
console.log(`${chalk.bold("Errors:")} ${stats.errors}`);
|
|
194
|
+
}
|
|
72
195
|
if (opts.prompt && info.prompt) {
|
|
73
196
|
console.log(`\n${chalk.bold.cyan("--- SKILL.md ---")}\n`);
|
|
74
197
|
console.log(info.prompt);
|
|
@@ -76,15 +199,20 @@ export function registerSkillsCommand(program) {
|
|
|
76
199
|
});
|
|
77
200
|
skill
|
|
78
201
|
.command("use <name>")
|
|
79
|
-
.description("
|
|
80
|
-
.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
console.error(result.error);
|
|
202
|
+
.description("Show the SKILL.md guide for a skill")
|
|
203
|
+
.action(async (name) => {
|
|
204
|
+
const info = getSkillInfo(name);
|
|
205
|
+
if (!info.exists) {
|
|
206
|
+
console.error(`Skill not found: ${name}`);
|
|
207
|
+
console.error(`\nRun 'nexus skill list' to see available skills.`);
|
|
86
208
|
process.exit(1);
|
|
87
209
|
}
|
|
210
|
+
if (!info.prompt) {
|
|
211
|
+
console.error(`No SKILL.md found for ${name}.`);
|
|
212
|
+
process.exit(1);
|
|
213
|
+
}
|
|
214
|
+
console.log(info.prompt.trimEnd());
|
|
215
|
+
recordSkillUsage(name, { ts: Date.now(), event: "use", ok: true });
|
|
88
216
|
});
|
|
89
217
|
skill
|
|
90
218
|
.command("verify <name>")
|
|
@@ -126,7 +254,14 @@ export function registerSkillsCommand(program) {
|
|
|
126
254
|
}
|
|
127
255
|
console.log(`Total skill runs: ${stats.totalRuns}`);
|
|
128
256
|
console.log(`Active skills: ${stats.activeSkills}`);
|
|
129
|
-
|
|
257
|
+
if (stats.topUsed && stats.topUsed.length > 0) {
|
|
258
|
+
console.log(`Most used: ${stats.topUsed
|
|
259
|
+
.map((item) => `${item.name} (${item.runs})`)
|
|
260
|
+
.join(", ")}`);
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
console.log("Most used: none");
|
|
264
|
+
}
|
|
130
265
|
console.log(`Ready but unused: ${stats.readyButUnused?.join(", ") || "none"}`);
|
|
131
266
|
});
|
|
132
267
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
1
2
|
import fs from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
3
|
import os from "node:os";
|
|
4
|
-
import
|
|
4
|
+
import path from "node:path";
|
|
5
5
|
import { Readable } from "node:stream";
|
|
6
6
|
import { pipeline } from "node:stream/promises";
|
|
7
7
|
import { fileTypeFromFile } from "file-type";
|
|
8
|
-
import { buildWorkspaceSkillStatus } from "../agents/skills-status.js";
|
|
9
8
|
import { getSkillMetadata, hasBinary, loadWorkspaceSkillEntries, } from "../agents/skills.js";
|
|
9
|
+
import { buildWorkspaceSkillStatus } from "../agents/skills-status.js";
|
|
10
10
|
import { DEFAULT_AGENT_WORKSPACE_DIR } from "../agents/workspace.js";
|
|
11
|
-
import { generateSkillManifest, writeSkillManifest } from "../commands/skills-manifest.js";
|
|
11
|
+
import { generateSkillManifest, writeSkillManifest, } from "../commands/skills-manifest.js";
|
|
12
12
|
import { loadConfig } from "../config/config.js";
|
|
13
|
-
import { runCommandWithTimeout } from "../process/exec.js";
|
|
14
13
|
import { listCredentialEntries, resolveCredentialValue, } from "../credentials/store.js";
|
|
15
|
-
import {
|
|
14
|
+
import { runCommandWithTimeout } from "../process/exec.js";
|
|
15
|
+
import { NEXUS_ROOT, resolveUserPath } from "../utils.js";
|
|
16
16
|
function getHubBaseUrl() {
|
|
17
17
|
return (process.env.NEXUS_HUB_URL ||
|
|
18
18
|
process.env.NEXUS_WEBSITE_URL ||
|
|
@@ -41,7 +41,9 @@ function normalizeStringList(value) {
|
|
|
41
41
|
return [];
|
|
42
42
|
}
|
|
43
43
|
function normalizeHubDependencies(value) {
|
|
44
|
-
const raw = value && typeof value === "object"
|
|
44
|
+
const raw = value && typeof value === "object"
|
|
45
|
+
? value
|
|
46
|
+
: {};
|
|
45
47
|
return {
|
|
46
48
|
dependencies: normalizeStringList(raw.dependencies),
|
|
47
49
|
tools: normalizeStringList(raw.tools),
|
|
@@ -142,16 +144,16 @@ function normalizeMetadata(value) {
|
|
|
142
144
|
return {};
|
|
143
145
|
}
|
|
144
146
|
function resolveCapabilities(entry) {
|
|
147
|
+
const metadata = entry.metadata;
|
|
148
|
+
const metadataNexus = metadata && typeof metadata.nexus === "object"
|
|
149
|
+
? metadata.nexus
|
|
150
|
+
: undefined;
|
|
145
151
|
const candidates = [
|
|
146
152
|
entry.capabilities,
|
|
147
153
|
entry.provides,
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
entry.metadata?.nexus
|
|
152
|
-
? entry.metadata.nexus.capabilities
|
|
153
|
-
: undefined,
|
|
154
|
-
entry.metadata?.capabilities,
|
|
154
|
+
metadataNexus?.provides,
|
|
155
|
+
metadataNexus?.capabilities,
|
|
156
|
+
metadata?.capabilities,
|
|
155
157
|
];
|
|
156
158
|
for (const candidate of candidates) {
|
|
157
159
|
const parsed = normalizeStringList(candidate);
|
|
@@ -282,9 +284,8 @@ function dirNameToSlug(dirName) {
|
|
|
282
284
|
async function ensureDir(dir) {
|
|
283
285
|
await fs.mkdir(dir, { recursive: true });
|
|
284
286
|
}
|
|
285
|
-
async function loadManagedSkillSlugs(
|
|
287
|
+
async function loadManagedSkillSlugs(managedDir) {
|
|
286
288
|
const slugs = new Set();
|
|
287
|
-
const managedDir = path.join(managedSkillsDir, "managed");
|
|
288
289
|
let entries = [];
|
|
289
290
|
try {
|
|
290
291
|
entries = await fs.readdir(managedDir, { withFileTypes: true });
|
|
@@ -456,7 +457,7 @@ async function computeArtifactInfo(filePath) {
|
|
|
456
457
|
return { sha256: hash, bytes: stats.size };
|
|
457
458
|
}
|
|
458
459
|
async function resolveHubToken(input) {
|
|
459
|
-
if (input
|
|
460
|
+
if (input?.trim())
|
|
460
461
|
return input.trim();
|
|
461
462
|
const envToken = process.env.NEXUS_HUB_TOKEN ||
|
|
462
463
|
process.env.NEXUS_WEBSITE_TOKEN ||
|
|
@@ -483,7 +484,9 @@ function buildManifestPayload(input) {
|
|
|
483
484
|
(typeof frontmatter.name === "string" ? frontmatter.name : "") ||
|
|
484
485
|
"";
|
|
485
486
|
const description = overrides.description ||
|
|
486
|
-
(typeof frontmatter.description === "string"
|
|
487
|
+
(typeof frontmatter.description === "string"
|
|
488
|
+
? frontmatter.description
|
|
489
|
+
: "") ||
|
|
487
490
|
"";
|
|
488
491
|
const type = overrides.type ||
|
|
489
492
|
(typeof frontmatter.type === "string" ? frontmatter.type : "") ||
|
|
@@ -496,7 +499,9 @@ function buildManifestPayload(input) {
|
|
|
496
499
|
(typeof frontmatter.license === "string" ? frontmatter.license : "") ||
|
|
497
500
|
"";
|
|
498
501
|
const repository = overrides.repository ||
|
|
499
|
-
(typeof frontmatter.repository === "string"
|
|
502
|
+
(typeof frontmatter.repository === "string"
|
|
503
|
+
? frontmatter.repository
|
|
504
|
+
: "") ||
|
|
500
505
|
(typeof frontmatter.repo === "string" ? frontmatter.repo : "") ||
|
|
501
506
|
"";
|
|
502
507
|
const homepage = overrides.homepage ||
|
|
@@ -530,11 +535,15 @@ function buildManifestPayload(input) {
|
|
|
530
535
|
const capabilities = resolveCapabilities(capabilityCandidates);
|
|
531
536
|
if (capabilities.length > 0) {
|
|
532
537
|
manifestEntry.capabilities = capabilities;
|
|
533
|
-
const
|
|
534
|
-
nexus.nexus
|
|
535
|
-
|
|
538
|
+
const metadata = (manifestEntry.metadata ?? {});
|
|
539
|
+
const existingNexus = metadata.nexus && typeof metadata.nexus === "object"
|
|
540
|
+
? metadata.nexus
|
|
541
|
+
: {};
|
|
542
|
+
metadata.nexus = {
|
|
543
|
+
...existingNexus,
|
|
536
544
|
provides: capabilities,
|
|
537
545
|
};
|
|
546
|
+
manifestEntry.metadata = metadata;
|
|
538
547
|
}
|
|
539
548
|
const readmeExcerpt = extractExcerpt(body || description);
|
|
540
549
|
return {
|
|
@@ -590,12 +599,15 @@ async function installHubSkill(params) {
|
|
|
590
599
|
}
|
|
591
600
|
await extractArchive(artifactPath, destDir);
|
|
592
601
|
await normalizeSkillRoot(destDir);
|
|
593
|
-
const
|
|
602
|
+
const skillsRootDir = path.dirname(params.managedDir);
|
|
603
|
+
const manifest = await generateSkillManifest(skillsRootDir, params.userSkillsDir);
|
|
594
604
|
await writeSkillManifest(manifest);
|
|
595
605
|
return { installed: true, destDir };
|
|
596
606
|
}
|
|
597
607
|
export function registerSkillsHubCommand(program) {
|
|
598
|
-
const skills = program
|
|
608
|
+
const skills = program
|
|
609
|
+
.command("skills")
|
|
610
|
+
.description("Search and install skills from the Nexus Hub");
|
|
599
611
|
skills
|
|
600
612
|
.command("search <query>")
|
|
601
613
|
.description("Search local skills and the Nexus Hub")
|
|
@@ -616,7 +628,8 @@ export function registerSkillsHubCommand(program) {
|
|
|
616
628
|
: 10;
|
|
617
629
|
const cfg = loadConfig();
|
|
618
630
|
const workspaceDir = resolveUserPath(cfg.agent?.workspace ?? DEFAULT_AGENT_WORKSPACE_DIR);
|
|
619
|
-
const
|
|
631
|
+
const skillsRoot = path.join(NEXUS_ROOT, "skills");
|
|
632
|
+
const managedSkillsDir = path.join(skillsRoot, "managed");
|
|
620
633
|
const status = buildWorkspaceSkillStatus(workspaceDir, {
|
|
621
634
|
config: cfg,
|
|
622
635
|
managedSkillsDir,
|
|
@@ -625,7 +638,10 @@ export function registerSkillsHubCommand(program) {
|
|
|
625
638
|
config: cfg,
|
|
626
639
|
managedSkillsDir,
|
|
627
640
|
});
|
|
628
|
-
const metadataByName = new Map(metadataEntries.map((entry) => [
|
|
641
|
+
const metadataByName = new Map(metadataEntries.map((entry) => [
|
|
642
|
+
entry.skill.name,
|
|
643
|
+
getSkillMetadata(entry),
|
|
644
|
+
]));
|
|
629
645
|
const installedNames = new Set(metadataEntries.map((entry) => normalizeSkillKey(entry.skill.name)));
|
|
630
646
|
const installedSlugs = await loadManagedSkillSlugs(managedSkillsDir);
|
|
631
647
|
const installedIndex = {
|
|
@@ -666,7 +682,7 @@ export function registerSkillsHubCommand(program) {
|
|
|
666
682
|
})
|
|
667
683
|
.filter((skill) => skill.score > 0)
|
|
668
684
|
.sort((a, b) => b.score - a.score)
|
|
669
|
-
.map(({ score, ...rest }) => rest);
|
|
685
|
+
.map(({ score: _score, ...rest }) => rest);
|
|
670
686
|
let hubMatches = [];
|
|
671
687
|
if (!opts.localOnly) {
|
|
672
688
|
try {
|
|
@@ -801,7 +817,10 @@ export function registerSkillsHubCommand(program) {
|
|
|
801
817
|
console.log(` Requires → ${deps.join(" | ")}`);
|
|
802
818
|
}
|
|
803
819
|
if (skill.install.length > 0) {
|
|
804
|
-
console.log(` Install → ${skill.install
|
|
820
|
+
console.log(` Install → ${skill.install
|
|
821
|
+
.map((i) => i.label)
|
|
822
|
+
.filter(Boolean)
|
|
823
|
+
.join(", ")}`);
|
|
805
824
|
}
|
|
806
825
|
}
|
|
807
826
|
console.log("");
|
|
@@ -873,20 +892,32 @@ export function registerSkillsHubCommand(program) {
|
|
|
873
892
|
const capOverrides = [
|
|
874
893
|
...(Array.isArray(opts.capability) ? opts.capability : []),
|
|
875
894
|
...normalizeStringList(opts.capabilities),
|
|
876
|
-
]
|
|
895
|
+
]
|
|
896
|
+
.map((cap) => cap.trim())
|
|
897
|
+
.filter(Boolean);
|
|
877
898
|
const overrides = {
|
|
878
899
|
path: skillDir,
|
|
879
900
|
slug: typeof opts.slug === "string" ? opts.slug.trim() : undefined,
|
|
880
901
|
name: typeof opts.name === "string" ? opts.name.trim() : undefined,
|
|
881
|
-
description: typeof opts.description === "string"
|
|
902
|
+
description: typeof opts.description === "string"
|
|
903
|
+
? opts.description.trim()
|
|
904
|
+
: undefined,
|
|
882
905
|
type: typeof opts.type === "string" ? opts.type.trim() : undefined,
|
|
883
906
|
version: typeof opts.version === "string" ? opts.version.trim() : undefined,
|
|
884
907
|
license: typeof opts.license === "string" ? opts.license.trim() : undefined,
|
|
885
|
-
repository: typeof opts.repository === "string"
|
|
886
|
-
|
|
887
|
-
|
|
908
|
+
repository: typeof opts.repository === "string"
|
|
909
|
+
? opts.repository.trim()
|
|
910
|
+
: undefined,
|
|
911
|
+
homepage: typeof opts.homepage === "string"
|
|
912
|
+
? opts.homepage.trim()
|
|
913
|
+
: undefined,
|
|
914
|
+
visibility: typeof opts.visibility === "string"
|
|
915
|
+
? opts.visibility.trim()
|
|
916
|
+
: "public",
|
|
888
917
|
capabilities: capOverrides.length > 0 ? capOverrides : undefined,
|
|
889
|
-
sourcePath: typeof opts.source === "string"
|
|
918
|
+
sourcePath: typeof opts.source === "string"
|
|
919
|
+
? resolveUserPath(opts.source)
|
|
920
|
+
: undefined,
|
|
890
921
|
sourceCommit: typeof opts.sourceCommit === "string"
|
|
891
922
|
? opts.sourceCommit.trim()
|
|
892
923
|
: undefined,
|
|
@@ -1019,8 +1050,9 @@ export function registerSkillsHubCommand(program) {
|
|
|
1019
1050
|
const cfg = loadConfig();
|
|
1020
1051
|
const workspaceDir = resolveUserPath(cfg.agent?.workspace ?? DEFAULT_AGENT_WORKSPACE_DIR);
|
|
1021
1052
|
const userSkillsDir = path.join(workspaceDir, "skills");
|
|
1022
|
-
const
|
|
1023
|
-
const
|
|
1053
|
+
const skillsRoot = path.join(NEXUS_ROOT, "skills");
|
|
1054
|
+
const managedSkillsDir = path.join(skillsRoot, "managed");
|
|
1055
|
+
const managedDir = managedSkillsDir;
|
|
1024
1056
|
const metadataEntries = loadWorkspaceSkillEntries(workspaceDir, {
|
|
1025
1057
|
config: cfg,
|
|
1026
1058
|
managedSkillsDir,
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { getSkillMetadata, hasBinary, loadWorkspaceSkillEntries, } from "../agents/skills.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { DEFAULT_AGENT_WORKSPACE_DIR } from "../agents/workspace.js";
|
|
5
|
+
import { loadConfig } from "../config/config.js";
|
|
6
|
+
import { ensureCredentialIndexSync, } from "../credentials/store.js";
|
|
7
|
+
import { verifyCredentials } from "../commands/credential.js";
|
|
8
|
+
import { resolveUserPath } from "../utils.js";
|
|
6
9
|
function resolveBinaryPath(bin) {
|
|
7
10
|
const pathEnv = process.env.PATH ?? "";
|
|
8
11
|
const parts = pathEnv.split(path.delimiter).filter(Boolean);
|
|
@@ -19,16 +22,29 @@ function resolveBinaryPath(bin) {
|
|
|
19
22
|
return null;
|
|
20
23
|
}
|
|
21
24
|
export function registerToolConnectorCli(program) {
|
|
22
|
-
const tool = program
|
|
23
|
-
|
|
25
|
+
const tool = program
|
|
26
|
+
.command("tool")
|
|
27
|
+
.description("Tool verification and paths");
|
|
28
|
+
const connector = program
|
|
29
|
+
.command("connector")
|
|
30
|
+
.description("Connector verification and accounts");
|
|
24
31
|
tool
|
|
25
|
-
.command("verify")
|
|
32
|
+
.command("verify [name]")
|
|
26
33
|
.description("Verify tool dependencies")
|
|
27
34
|
.option("--json", "Output as JSON")
|
|
28
|
-
.action((opts) => {
|
|
29
|
-
const
|
|
35
|
+
.action((name, opts) => {
|
|
36
|
+
const config = loadConfig();
|
|
37
|
+
const workspaceDir = resolveUserPath(config.agent?.workspace ?? DEFAULT_AGENT_WORKSPACE_DIR);
|
|
38
|
+
const entries = loadWorkspaceSkillEntries(workspaceDir);
|
|
30
39
|
const tools = entries.filter((entry) => getSkillMetadata(entry)?.type === "tool");
|
|
31
|
-
const
|
|
40
|
+
const scoped = name?.trim() && name.trim().length > 0
|
|
41
|
+
? tools.filter((entry) => entry.skill.name.toLowerCase() === name.toLowerCase())
|
|
42
|
+
: tools;
|
|
43
|
+
if (name && scoped.length === 0) {
|
|
44
|
+
console.error(`Tool skill not found: ${name}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
const results = scoped.map((entry) => {
|
|
32
48
|
const meta = getSkillMetadata(entry);
|
|
33
49
|
const bins = meta?.requires?.bins ?? [];
|
|
34
50
|
const missing = bins.filter((bin) => !hasBinary(bin));
|
|
@@ -53,38 +69,80 @@ export function registerToolConnectorCli(program) {
|
|
|
53
69
|
}
|
|
54
70
|
});
|
|
55
71
|
tool
|
|
56
|
-
.command("path <
|
|
57
|
-
.description("Resolve binary path")
|
|
58
|
-
.action((
|
|
59
|
-
const
|
|
72
|
+
.command("path <name>")
|
|
73
|
+
.description("Resolve binary path for a tool skill or bin")
|
|
74
|
+
.action((name) => {
|
|
75
|
+
const config = loadConfig();
|
|
76
|
+
const workspaceDir = resolveUserPath(config.agent?.workspace ?? DEFAULT_AGENT_WORKSPACE_DIR);
|
|
77
|
+
const entries = loadWorkspaceSkillEntries(workspaceDir);
|
|
78
|
+
const match = entries.find((entry) => entry.skill.name.toLowerCase() === name.toLowerCase());
|
|
79
|
+
if (match) {
|
|
80
|
+
const meta = getSkillMetadata(match);
|
|
81
|
+
const bins = meta?.requires?.bins ?? [];
|
|
82
|
+
if (bins.length === 0) {
|
|
83
|
+
console.error(`No binaries listed for tool: ${match.skill.name}`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
const resolvedBins = bins.map((bin) => ({
|
|
87
|
+
bin,
|
|
88
|
+
path: resolveBinaryPath(bin),
|
|
89
|
+
}));
|
|
90
|
+
const missing = resolvedBins.filter((item) => !item.path);
|
|
91
|
+
if (missing.length > 0) {
|
|
92
|
+
console.error(`Missing binaries: ${missing.map((item) => item.bin).join(", ")}`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
for (const item of resolvedBins) {
|
|
96
|
+
if (item.path)
|
|
97
|
+
console.log(item.path);
|
|
98
|
+
}
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const resolved = resolveBinaryPath(name);
|
|
60
102
|
if (!resolved) {
|
|
61
|
-
console.error(`Binary not found: ${
|
|
103
|
+
console.error(`Binary not found: ${name}`);
|
|
62
104
|
process.exit(1);
|
|
63
105
|
}
|
|
64
106
|
console.log(resolved);
|
|
65
107
|
});
|
|
66
108
|
connector
|
|
67
|
-
.command("verify")
|
|
109
|
+
.command("verify [name]")
|
|
68
110
|
.description("Verify connector credentials")
|
|
69
111
|
.option("--json", "Output as JSON")
|
|
70
|
-
.action((opts) => {
|
|
71
|
-
const
|
|
112
|
+
.action(async (name, opts) => {
|
|
113
|
+
const config = loadConfig();
|
|
114
|
+
const workspaceDir = resolveUserPath(config.agent?.workspace ?? DEFAULT_AGENT_WORKSPACE_DIR);
|
|
115
|
+
const entries = loadWorkspaceSkillEntries(workspaceDir);
|
|
72
116
|
const connectors = entries.filter((entry) => getSkillMetadata(entry)?.type === "connector");
|
|
117
|
+
const scoped = name?.trim() && name.trim().length > 0
|
|
118
|
+
? connectors.filter((entry) => entry.skill.name.toLowerCase() === name.toLowerCase())
|
|
119
|
+
: connectors;
|
|
120
|
+
if (name && scoped.length === 0) {
|
|
121
|
+
console.error(`Connector skill not found: ${name}`);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
73
124
|
const index = ensureCredentialIndexSync();
|
|
74
125
|
const services = new Set(Object.keys(index.services ?? {}).map((id) => id.toLowerCase()));
|
|
75
|
-
const results =
|
|
126
|
+
const results = await Promise.all(scoped.map(async (entry) => {
|
|
76
127
|
const meta = getSkillMetadata(entry);
|
|
77
128
|
const provides = meta?.provides ?? [];
|
|
78
129
|
const requires = meta?.requires?.credentials ?? [];
|
|
79
130
|
const hints = [...requires, entry.skill.name].map((value) => value.toLowerCase());
|
|
80
131
|
const hasCredential = hints.some((hint) => services.has(hint));
|
|
132
|
+
const verified = hasCredential
|
|
133
|
+
? await Promise.all(hints.map((hint) => verifyCredentials({ service: hint }).catch(() => null)))
|
|
134
|
+
: [];
|
|
135
|
+
const ok = hasCredential
|
|
136
|
+
? verified.every((result) => result?.ok !== false)
|
|
137
|
+
: false;
|
|
81
138
|
return {
|
|
82
139
|
skill: entry.skill.name,
|
|
83
140
|
provides,
|
|
84
141
|
requires,
|
|
85
|
-
ok
|
|
142
|
+
ok,
|
|
143
|
+
verified,
|
|
86
144
|
};
|
|
87
|
-
});
|
|
145
|
+
}));
|
|
88
146
|
if (opts.json) {
|
|
89
147
|
console.log(JSON.stringify(results, null, 2));
|
|
90
148
|
return;
|
|
@@ -99,17 +157,34 @@ export function registerToolConnectorCli(program) {
|
|
|
99
157
|
}
|
|
100
158
|
});
|
|
101
159
|
connector
|
|
102
|
-
.command("accounts")
|
|
160
|
+
.command("accounts [service]")
|
|
103
161
|
.description("List credential accounts")
|
|
104
162
|
.option("--json", "Output as JSON")
|
|
105
|
-
.action((opts) => {
|
|
163
|
+
.action((service, opts) => {
|
|
106
164
|
const index = ensureCredentialIndexSync();
|
|
165
|
+
const filter = service?.trim();
|
|
107
166
|
if (opts.json) {
|
|
108
|
-
|
|
167
|
+
if (!filter) {
|
|
168
|
+
console.log(JSON.stringify(index, null, 2));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const entry = index.services?.[filter];
|
|
172
|
+
if (!entry) {
|
|
173
|
+
console.error(`Service not found: ${filter}`);
|
|
174
|
+
process.exit(1);
|
|
175
|
+
}
|
|
176
|
+
console.log(JSON.stringify({ [filter]: entry }, null, 2));
|
|
109
177
|
return;
|
|
110
178
|
}
|
|
111
|
-
|
|
112
|
-
|
|
179
|
+
const entries = filter
|
|
180
|
+
? index.services?.[filter]
|
|
181
|
+
? [[filter, index.services[filter]]]
|
|
182
|
+
: []
|
|
183
|
+
: Object.entries(index.services ?? {});
|
|
184
|
+
for (const [serviceId, info] of entries) {
|
|
185
|
+
if (!info)
|
|
186
|
+
continue;
|
|
187
|
+
console.log(serviceId);
|
|
113
188
|
for (const account of info.accounts ?? []) {
|
|
114
189
|
console.log(` - ${account.id}`);
|
|
115
190
|
}
|