@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
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import os from "node:os";
|
|
3
|
+
import { streamSimple } from "@mariozechner/pi-ai";
|
|
3
4
|
import { buildSystemPrompt, createAgentSession, discoverAuthStorage, discoverModels, SessionManager, SettingsManager, } from "@mariozechner/pi-coding-agent";
|
|
4
5
|
import { formatToolAggregate } from "../auto-reply/tool-meta.js";
|
|
5
6
|
import { getMachineDisplayName } from "../infra/machine-name.js";
|
|
6
7
|
import { createSubsystemLogger } from "../logging.js";
|
|
7
8
|
import { splitMediaFromOutput } from "../media/parse.js";
|
|
8
9
|
import { enqueueCommandInLane, } from "../process/command-queue.js";
|
|
10
|
+
import { resolveTelegramReactionLevel } from "../telegram/reaction-level.js";
|
|
9
11
|
import { resolveUserPath } from "../utils.js";
|
|
10
12
|
import { resolveNexusAgentDir } from "./agent-paths.js";
|
|
11
13
|
import { markAuthProfileCooldown, markAuthProfileGood, markAuthProfileUsed, } from "./auth-profiles.js";
|
|
@@ -18,7 +20,6 @@ import { extractAssistantText } from "./pi-embedded-utils.js";
|
|
|
18
20
|
import { toToolDefinitions } from "./pi-tool-definition-adapter.js";
|
|
19
21
|
import { createNexusCodingTools } from "./pi-tools.js";
|
|
20
22
|
import { resolveSandboxContext } from "./sandbox.js";
|
|
21
|
-
import { resolveTelegramReactionLevel } from "../telegram/reaction-level.js";
|
|
22
23
|
import { applySkillEnvOverrides, applySkillEnvOverridesFromSnapshot, buildWorkspaceSkillSnapshot, loadWorkspaceSkillEntries, } from "./skills.js";
|
|
23
24
|
import { buildAgentSystemPromptAppend } from "./system-prompt.js";
|
|
24
25
|
import { normalizeUsage } from "./usage.js";
|
|
@@ -46,7 +47,7 @@ const GOOGLE_SCHEMA_UNSUPPORTED_KEYWORDS = new Set([
|
|
|
46
47
|
"minProperties",
|
|
47
48
|
"maxProperties",
|
|
48
49
|
]);
|
|
49
|
-
function
|
|
50
|
+
function _isAntigravityClaudeModel(provider, modelId) {
|
|
50
51
|
if (provider !== "google-antigravity")
|
|
51
52
|
return false;
|
|
52
53
|
return modelId.trim().toLowerCase().includes("claude");
|
|
@@ -69,8 +70,9 @@ function findUnsupportedSchemaKeywords(schema, path) {
|
|
|
69
70
|
}
|
|
70
71
|
return violations;
|
|
71
72
|
}
|
|
72
|
-
function
|
|
73
|
-
if (params.provider !== "google-antigravity" &&
|
|
73
|
+
function _logToolSchemasForGoogle(params) {
|
|
74
|
+
if (params.provider !== "google-antigravity" &&
|
|
75
|
+
params.provider !== "google-gemini-cli") {
|
|
74
76
|
return;
|
|
75
77
|
}
|
|
76
78
|
const toolNames = params.tools.map((tool, index) => `${index}:${tool.name}`);
|
|
@@ -91,6 +93,89 @@ function logToolSchemasForGoogle(params) {
|
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Resolve provider-specific extra params from model config.
|
|
98
|
+
*
|
|
99
|
+
* Example config:
|
|
100
|
+
* agent.models["anthropic/claude-sonnet-4-5"].params.temperature = 0.7
|
|
101
|
+
* agent.models["openai/gpt-4.1-mini"].params.maxTokens = 8192
|
|
102
|
+
*/
|
|
103
|
+
export function resolveExtraParams(params) {
|
|
104
|
+
const modelKey = `${params.provider}/${params.modelId}`;
|
|
105
|
+
const modelConfig = params.cfg?.agent?.models?.[modelKey];
|
|
106
|
+
let extraParams = modelConfig?.params ? { ...modelConfig.params } : undefined;
|
|
107
|
+
// Auto-enable thinking for ZAI GLM-4.x models when not explicitly configured.
|
|
108
|
+
// Skip if user explicitly disabled thinking via --thinking off.
|
|
109
|
+
if (params.provider === "zai" && params.thinkLevel !== "off") {
|
|
110
|
+
const modelIdLower = params.modelId.toLowerCase();
|
|
111
|
+
const isGlm4 = modelIdLower.includes("glm-4");
|
|
112
|
+
if (isGlm4) {
|
|
113
|
+
const hasThinkingConfig = extraParams?.thinking !== undefined;
|
|
114
|
+
if (!hasThinkingConfig) {
|
|
115
|
+
// GLM-4.7 supports preserved thinking (reasoning kept across turns).
|
|
116
|
+
// GLM-4.5/4.6 use interleaved thinking (reasoning cleared each turn).
|
|
117
|
+
const isGlm47 = modelIdLower.includes("glm-4.7");
|
|
118
|
+
const clearThinking = !isGlm47;
|
|
119
|
+
extraParams = {
|
|
120
|
+
...extraParams,
|
|
121
|
+
thinking: {
|
|
122
|
+
type: "enabled",
|
|
123
|
+
clear_thinking: clearThinking,
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
log.debug(`auto-enabled thinking for ${modelKey}: type=enabled, clear_thinking=${clearThinking}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return extraParams;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Create a wrapped streamFn that injects extra params (like temperature) from config.
|
|
134
|
+
*
|
|
135
|
+
* This wraps the default streamSimple with config-driven params for each model.
|
|
136
|
+
*/
|
|
137
|
+
function createStreamFnWithExtraParams(extraParams) {
|
|
138
|
+
if (!extraParams || Object.keys(extraParams).length === 0) {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
const streamParams = {};
|
|
142
|
+
if (typeof extraParams.temperature === "number") {
|
|
143
|
+
streamParams.temperature = extraParams.temperature;
|
|
144
|
+
}
|
|
145
|
+
if (typeof extraParams.maxTokens === "number") {
|
|
146
|
+
streamParams.maxTokens = extraParams.maxTokens;
|
|
147
|
+
}
|
|
148
|
+
if (Object.keys(streamParams).length === 0) {
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
log.debug(`creating streamFn wrapper with params: ${JSON.stringify(streamParams)}`);
|
|
152
|
+
const wrappedStreamFn = (model, context, options) => {
|
|
153
|
+
const mergedOptions = {
|
|
154
|
+
...streamParams,
|
|
155
|
+
...options,
|
|
156
|
+
};
|
|
157
|
+
return streamSimple(model, context, mergedOptions);
|
|
158
|
+
};
|
|
159
|
+
return wrappedStreamFn;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Apply extra params (like temperature) to an agent's streamFn.
|
|
163
|
+
*
|
|
164
|
+
* Call this after createAgentSession to wire up config-driven model params.
|
|
165
|
+
*/
|
|
166
|
+
function applyExtraParamsToAgent(agent, cfg, provider, modelId, thinkLevel) {
|
|
167
|
+
const extraParams = resolveExtraParams({
|
|
168
|
+
cfg,
|
|
169
|
+
provider,
|
|
170
|
+
modelId,
|
|
171
|
+
thinkLevel,
|
|
172
|
+
});
|
|
173
|
+
const wrappedStreamFn = createStreamFnWithExtraParams(extraParams);
|
|
174
|
+
if (wrappedStreamFn) {
|
|
175
|
+
log.debug(`applying extraParams to agent streamFn for ${provider}/${modelId}`);
|
|
176
|
+
agent.streamFn = wrappedStreamFn;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
94
179
|
/**
|
|
95
180
|
* Limits conversation history to the last N user turns (and their associated
|
|
96
181
|
* assistant responses). This reduces token usage for long-running DM sessions.
|
|
@@ -136,7 +221,9 @@ export function getDmHistoryLimitFromSessionKey(sessionKey, config, messageChann
|
|
|
136
221
|
const raw = sessionKey?.trim() ?? "";
|
|
137
222
|
if (!raw)
|
|
138
223
|
return undefined;
|
|
139
|
-
if (raw.startsWith("group:") ||
|
|
224
|
+
if (raw.startsWith("group:") ||
|
|
225
|
+
raw.includes(":group:") ||
|
|
226
|
+
raw.includes(":channel:")) {
|
|
140
227
|
return undefined;
|
|
141
228
|
}
|
|
142
229
|
const parts = raw.split(":").filter(Boolean);
|
|
@@ -176,7 +263,7 @@ export function getDmHistoryLimitFromSessionKey(sessionKey, config, messageChann
|
|
|
176
263
|
return undefined;
|
|
177
264
|
}
|
|
178
265
|
}
|
|
179
|
-
function
|
|
266
|
+
function _resolveReactionGuidance(params) {
|
|
180
267
|
if (!params.config)
|
|
181
268
|
return undefined;
|
|
182
269
|
const rawChannel = params.messageChannel ?? params.messageProvider ?? "";
|
|
@@ -488,6 +575,7 @@ export async function compactEmbeddedPiSession(params) {
|
|
|
488
575
|
skills: promptSkills,
|
|
489
576
|
contextFiles,
|
|
490
577
|
});
|
|
578
|
+
applyExtraParamsToAgent(session.agent, params.config, provider, modelId, params.thinkLevel);
|
|
491
579
|
try {
|
|
492
580
|
const prior = await sanitizeSessionMessagesImages(session.messages, "session:history");
|
|
493
581
|
if (prior.length > 0) {
|
|
@@ -705,6 +793,7 @@ export async function runEmbeddedPiAgent(params) {
|
|
|
705
793
|
skills: promptSkills,
|
|
706
794
|
contextFiles,
|
|
707
795
|
});
|
|
796
|
+
applyExtraParamsToAgent(session.agent, params.config, provider, modelId, thinkLevel);
|
|
708
797
|
const prior = await sanitizeSessionMessagesImages(session.messages, "session:history");
|
|
709
798
|
if (prior.length > 0) {
|
|
710
799
|
session.agent.replaceMessages(prior);
|
|
@@ -837,7 +926,7 @@ export async function runEmbeddedPiAgent(params) {
|
|
|
837
926
|
if (shouldRotate) {
|
|
838
927
|
// Mark current profile for cooldown before rotating
|
|
839
928
|
if (lastProfileId) {
|
|
840
|
-
markAuthProfileCooldown({
|
|
929
|
+
void markAuthProfileCooldown({
|
|
841
930
|
store: authStore,
|
|
842
931
|
profileId: lastProfileId,
|
|
843
932
|
});
|
|
@@ -906,13 +995,16 @@ export async function runEmbeddedPiAgent(params) {
|
|
|
906
995
|
.filter((p) => p.text || p.mediaUrl || (p.mediaUrls && p.mediaUrls.length > 0));
|
|
907
996
|
log.debug(`embedded run done: runId=${params.runId} sessionId=${params.sessionId} durationMs=${Date.now() - started} aborted=${aborted}`);
|
|
908
997
|
if (lastProfileId) {
|
|
909
|
-
markAuthProfileGood({
|
|
998
|
+
void markAuthProfileGood({
|
|
910
999
|
store: authStore,
|
|
911
1000
|
provider,
|
|
912
1001
|
profileId: lastProfileId,
|
|
913
1002
|
});
|
|
914
1003
|
// Track usage for round-robin rotation
|
|
915
|
-
markAuthProfileUsed({
|
|
1004
|
+
void markAuthProfileUsed({
|
|
1005
|
+
store: authStore,
|
|
1006
|
+
profileId: lastProfileId,
|
|
1007
|
+
});
|
|
916
1008
|
}
|
|
917
1009
|
return {
|
|
918
1010
|
payloads: payloads.length ? payloads : undefined,
|
package/dist/agents/sandbox.js
CHANGED
|
@@ -4,7 +4,7 @@ import fs from "node:fs/promises";
|
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { startBrowserBridgeServer, stopBrowserBridgeServer, } from "../browser/bridge-server.js";
|
|
7
|
-
import { resolveProfile } from "../browser/config.js";
|
|
7
|
+
import { resolveProfile, } from "../browser/config.js";
|
|
8
8
|
import { DEFAULT_NEXUS_BROWSER_COLOR } from "../browser/constants.js";
|
|
9
9
|
import { STATE_DIR_NEXUS } from "../config/config.js";
|
|
10
10
|
import { defaultRuntime } from "../runtime.js";
|
|
@@ -27,7 +27,14 @@ const DEFAULT_TOOL_ALLOW = [
|
|
|
27
27
|
"sessions_send",
|
|
28
28
|
"sessions_spawn",
|
|
29
29
|
];
|
|
30
|
-
const DEFAULT_TOOL_DENY = [
|
|
30
|
+
const DEFAULT_TOOL_DENY = [
|
|
31
|
+
"browser",
|
|
32
|
+
"canvas",
|
|
33
|
+
"nodes",
|
|
34
|
+
"cron",
|
|
35
|
+
"discord",
|
|
36
|
+
"gateway",
|
|
37
|
+
];
|
|
31
38
|
export const DEFAULT_SANDBOX_BROWSER_IMAGE = "nexus-sandbox-browser:bookworm-slim";
|
|
32
39
|
export const DEFAULT_SANDBOX_COMMON_IMAGE = "nexus-sandbox-common:bookworm-slim";
|
|
33
40
|
const DEFAULT_SANDBOX_BROWSER_PREFIX = "nexus-sbx-browser-";
|
|
@@ -490,7 +497,9 @@ async function ensureSandboxBrowser(params) {
|
|
|
490
497
|
? await readDockerPort(containerName, params.cfg.browser.noVncPort)
|
|
491
498
|
: null;
|
|
492
499
|
const existing = BROWSER_BRIDGES.get(params.sessionKey);
|
|
493
|
-
const existingProfile = existing
|
|
500
|
+
const existingProfile = existing
|
|
501
|
+
? resolveProfile(existing.bridge.state.resolved, "nexus")
|
|
502
|
+
: null;
|
|
494
503
|
const shouldReuse = existing &&
|
|
495
504
|
existing.containerName === containerName &&
|
|
496
505
|
existingProfile?.cdpPort === mappedCdp;
|
|
@@ -2,15 +2,16 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { loadConfig } from "../config/config.js";
|
|
4
4
|
import { runCommandWithTimeout } from "../process/exec.js";
|
|
5
|
-
import {
|
|
6
|
-
import { DEFAULT_AGENT_WORKSPACE_DIR } from "./workspace.js";
|
|
7
|
-
import { buildWorkspaceSkillStatus } from "./skills-status.js";
|
|
8
|
-
import { getSkillMetadata, hasBinary, loadWorkspaceSkillEntries, } from "./skills.js";
|
|
5
|
+
import { NEXUS_ROOT, resolveUserPath } from "../utils.js";
|
|
9
6
|
import { getSkillExecutionType, getSkillScriptConfig, getSkillToolConfig, } from "./skill-tools.js";
|
|
7
|
+
import { recordSkillUsage } from "./skill-usage.js";
|
|
8
|
+
import { getSkillMetadata, hasBinary, loadWorkspaceSkillEntries, } from "./skills.js";
|
|
9
|
+
import { buildWorkspaceSkillStatus } from "./skills-status.js";
|
|
10
|
+
import { DEFAULT_AGENT_WORKSPACE_DIR } from "./workspace.js";
|
|
10
11
|
function loadSkillContext(name) {
|
|
11
12
|
const config = loadConfig();
|
|
12
13
|
const workspaceDir = resolveUserPath(config.agent?.workspace ?? DEFAULT_AGENT_WORKSPACE_DIR);
|
|
13
|
-
const managedSkillsDir =
|
|
14
|
+
const managedSkillsDir = path.join(NEXUS_ROOT, "skills", "managed");
|
|
14
15
|
const entries = loadWorkspaceSkillEntries(workspaceDir, {
|
|
15
16
|
config,
|
|
16
17
|
managedSkillsDir,
|
|
@@ -90,8 +91,18 @@ export async function runSkill(name, args) {
|
|
|
90
91
|
if (!entry) {
|
|
91
92
|
return { ok: false, error: `Skill not found: ${name}` };
|
|
92
93
|
}
|
|
94
|
+
const startedAt = Date.now();
|
|
95
|
+
const record = (ok) => {
|
|
96
|
+
recordSkillUsage(entry.skill.name, {
|
|
97
|
+
ts: Date.now(),
|
|
98
|
+
event: "run",
|
|
99
|
+
ok,
|
|
100
|
+
durationMs: Date.now() - startedAt,
|
|
101
|
+
});
|
|
102
|
+
};
|
|
93
103
|
const execType = getSkillExecutionType(entry.skill.name);
|
|
94
104
|
if (execType === "prompt") {
|
|
105
|
+
record(false);
|
|
95
106
|
return {
|
|
96
107
|
ok: false,
|
|
97
108
|
error: "Skill is prompt-only and has no runnable command.",
|
|
@@ -100,13 +111,19 @@ export async function runSkill(name, args) {
|
|
|
100
111
|
if (execType === "tool") {
|
|
101
112
|
const toolConfig = getSkillToolConfig(entry.skill.name);
|
|
102
113
|
if (!toolConfig?.tool) {
|
|
114
|
+
record(false);
|
|
103
115
|
return { ok: false, error: "Skill tool configuration missing." };
|
|
104
116
|
}
|
|
105
117
|
if (!hasBinary(toolConfig.tool)) {
|
|
118
|
+
record(false);
|
|
106
119
|
return { ok: false, error: `Missing binary: ${toolConfig.tool}` };
|
|
107
120
|
}
|
|
108
|
-
const result = await runCommandWithTimeout([toolConfig.tool, ...args], {
|
|
121
|
+
const result = await runCommandWithTimeout([toolConfig.tool, ...args], {
|
|
122
|
+
timeoutMs: 300_000,
|
|
123
|
+
cwd: entry.skill.baseDir,
|
|
124
|
+
});
|
|
109
125
|
if (result.code !== 0) {
|
|
126
|
+
record(false);
|
|
110
127
|
return {
|
|
111
128
|
ok: false,
|
|
112
129
|
error: result.stderr || result.stdout || "Skill command failed.",
|
|
@@ -115,6 +132,7 @@ export async function runSkill(name, args) {
|
|
|
115
132
|
code: result.code,
|
|
116
133
|
};
|
|
117
134
|
}
|
|
135
|
+
record(true);
|
|
118
136
|
return {
|
|
119
137
|
ok: true,
|
|
120
138
|
stdout: result.stdout,
|
|
@@ -125,9 +143,11 @@ export async function runSkill(name, args) {
|
|
|
125
143
|
if (execType === "script") {
|
|
126
144
|
const scriptConfig = getSkillScriptConfig(entry.skill.name);
|
|
127
145
|
if (!scriptConfig) {
|
|
146
|
+
record(false);
|
|
128
147
|
return { ok: false, error: "Skill script configuration missing." };
|
|
129
148
|
}
|
|
130
149
|
if (!hasBinary(scriptConfig.runner)) {
|
|
150
|
+
record(false);
|
|
131
151
|
return {
|
|
132
152
|
ok: false,
|
|
133
153
|
error: `Missing runner: ${scriptConfig.runner}`,
|
|
@@ -135,11 +155,13 @@ export async function runSkill(name, args) {
|
|
|
135
155
|
}
|
|
136
156
|
const scriptPath = path.join(entry.skill.baseDir, scriptConfig.script);
|
|
137
157
|
if (!fs.existsSync(scriptPath)) {
|
|
158
|
+
record(false);
|
|
138
159
|
return { ok: false, error: `Script not found: ${scriptConfig.script}` };
|
|
139
160
|
}
|
|
140
161
|
if (scriptConfig.requiredEnv?.length) {
|
|
141
162
|
const missingEnv = scriptConfig.requiredEnv.filter((envName) => !process.env[envName]);
|
|
142
163
|
if (missingEnv.length > 0) {
|
|
164
|
+
record(false);
|
|
143
165
|
return {
|
|
144
166
|
ok: false,
|
|
145
167
|
error: `Missing env: ${missingEnv.join(", ")}`,
|
|
@@ -148,6 +170,7 @@ export async function runSkill(name, args) {
|
|
|
148
170
|
}
|
|
149
171
|
const result = await runCommandWithTimeout([scriptConfig.runner, scriptPath, ...args], { timeoutMs: 300_000, cwd: entry.skill.baseDir });
|
|
150
172
|
if (result.code !== 0) {
|
|
173
|
+
record(false);
|
|
151
174
|
return {
|
|
152
175
|
ok: false,
|
|
153
176
|
error: result.stderr || result.stdout || "Skill script failed.",
|
|
@@ -156,6 +179,7 @@ export async function runSkill(name, args) {
|
|
|
156
179
|
code: result.code,
|
|
157
180
|
};
|
|
158
181
|
}
|
|
182
|
+
record(true);
|
|
159
183
|
return {
|
|
160
184
|
ok: true,
|
|
161
185
|
stdout: result.stdout,
|
|
@@ -163,6 +187,7 @@ export async function runSkill(name, args) {
|
|
|
163
187
|
code: result.code,
|
|
164
188
|
};
|
|
165
189
|
}
|
|
190
|
+
record(false);
|
|
166
191
|
return { ok: false, error: "Unknown skill execution type." };
|
|
167
192
|
}
|
|
168
193
|
export async function verifySkill(name) {
|
|
@@ -175,6 +200,8 @@ export async function verifySkill(name) {
|
|
|
175
200
|
return { ok: false, error: `Missing requirements: ${missingSummary}` };
|
|
176
201
|
}
|
|
177
202
|
const execType = getSkillExecutionType(entry.skill.name);
|
|
203
|
+
const metadata = getSkillMetadata(entry);
|
|
204
|
+
const metaType = metadata?.type;
|
|
178
205
|
if (execType === "prompt") {
|
|
179
206
|
return { ok: true, message: "Prompt-only skill requires no verification." };
|
|
180
207
|
}
|
|
@@ -198,6 +225,14 @@ export async function verifySkill(name) {
|
|
|
198
225
|
}
|
|
199
226
|
return { ok: true, message: "Skill verified successfully." };
|
|
200
227
|
}
|
|
228
|
+
if (execType === "unknown" && (metaType === "tool" || metaType === "connector")) {
|
|
229
|
+
const bins = metadata?.requires?.bins ?? metadata?.requires?.anyBins ?? [];
|
|
230
|
+
const missing = bins.filter((bin) => !hasBinary(bin));
|
|
231
|
+
if (missing.length > 0) {
|
|
232
|
+
return { ok: false, error: `Missing binary: ${missing.join(", ")}` };
|
|
233
|
+
}
|
|
234
|
+
return { ok: true, message: "Skill appears configured." };
|
|
235
|
+
}
|
|
201
236
|
if (execType === "script") {
|
|
202
237
|
const scriptConfig = getSkillScriptConfig(entry.skill.name);
|
|
203
238
|
if (!scriptConfig) {
|
|
@@ -1,43 +1,143 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
1
3
|
import { loadConfig } from "../config/config.js";
|
|
2
|
-
import {
|
|
3
|
-
import { DEFAULT_AGENT_WORKSPACE_DIR } from "./workspace.js";
|
|
4
|
-
import { buildWorkspaceSkillStatus } from "./skills-status.js";
|
|
4
|
+
import { SKILLS_STATE_DIR, resolveUserPath } from "../utils.js";
|
|
5
5
|
import { loadWorkspaceSkillEntries } from "./skills.js";
|
|
6
|
+
import { buildWorkspaceSkillStatus } from "./skills-status.js";
|
|
7
|
+
import { DEFAULT_AGENT_WORKSPACE_DIR } from "./workspace.js";
|
|
6
8
|
function loadSkillEntries() {
|
|
7
9
|
const config = loadConfig();
|
|
8
10
|
const workspaceDir = resolveUserPath(config.agent?.workspace ?? DEFAULT_AGENT_WORKSPACE_DIR);
|
|
9
|
-
const managedSkillsDir = MANAGED_SKILLS_DIR;
|
|
10
11
|
const entries = loadWorkspaceSkillEntries(workspaceDir, {
|
|
11
12
|
config,
|
|
12
|
-
managedSkillsDir,
|
|
13
13
|
});
|
|
14
|
-
return { config, workspaceDir,
|
|
14
|
+
return { config, workspaceDir, entries };
|
|
15
|
+
}
|
|
16
|
+
function resolveUsageLogPath(name) {
|
|
17
|
+
return path.join(SKILLS_STATE_DIR, name, "usage.log");
|
|
18
|
+
}
|
|
19
|
+
function parseUsageEntry(line) {
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(line);
|
|
22
|
+
if (typeof parsed?.ts !== "number")
|
|
23
|
+
return null;
|
|
24
|
+
if (parsed.event !== "use" && parsed.event !== "run")
|
|
25
|
+
return null;
|
|
26
|
+
if (typeof parsed.ok !== "boolean")
|
|
27
|
+
return null;
|
|
28
|
+
return parsed;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function readUsageEntries(name, sinceMs) {
|
|
35
|
+
const logPath = resolveUsageLogPath(name);
|
|
36
|
+
try {
|
|
37
|
+
const raw = fs.readFileSync(logPath, "utf-8");
|
|
38
|
+
const entries = [];
|
|
39
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
40
|
+
if (!line.trim())
|
|
41
|
+
continue;
|
|
42
|
+
const entry = parseUsageEntry(line);
|
|
43
|
+
if (!entry)
|
|
44
|
+
continue;
|
|
45
|
+
if (sinceMs && entry.ts < sinceMs)
|
|
46
|
+
continue;
|
|
47
|
+
entries.push(entry);
|
|
48
|
+
}
|
|
49
|
+
return entries;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function hasUsageEntries(name) {
|
|
56
|
+
const logPath = resolveUsageLogPath(name);
|
|
57
|
+
try {
|
|
58
|
+
const stat = fs.statSync(logPath);
|
|
59
|
+
return stat.isFile() && stat.size > 0;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export function hasSkillUsage(name) {
|
|
66
|
+
return hasUsageEntries(name);
|
|
67
|
+
}
|
|
68
|
+
export function readSkillUsageEntries(name, opts) {
|
|
69
|
+
const entries = readUsageEntries(name, opts?.sinceMs);
|
|
70
|
+
if (opts?.limit && opts.limit > 0) {
|
|
71
|
+
return entries.slice(-opts.limit);
|
|
72
|
+
}
|
|
73
|
+
return entries;
|
|
74
|
+
}
|
|
75
|
+
export function recordSkillUsage(name, entry) {
|
|
76
|
+
const logPath = resolveUsageLogPath(name);
|
|
77
|
+
try {
|
|
78
|
+
fs.mkdirSync(path.dirname(logPath), { recursive: true });
|
|
79
|
+
fs.appendFileSync(logPath, `${JSON.stringify(entry)}\n`, "utf-8");
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// ignore logging failures
|
|
83
|
+
}
|
|
15
84
|
}
|
|
16
|
-
export async function getSkillStats(name) {
|
|
85
|
+
export async function getSkillStats(name, opts) {
|
|
17
86
|
const { entries } = loadSkillEntries();
|
|
18
87
|
const entry = entries.find((item) => item.skill.name.toLowerCase() === name.toLowerCase());
|
|
19
88
|
if (!entry)
|
|
20
89
|
return null;
|
|
90
|
+
const sinceMs = opts?.windowDays && opts.windowDays > 0
|
|
91
|
+
? Date.now() - opts.windowDays * 24 * 60 * 60 * 1000
|
|
92
|
+
: undefined;
|
|
93
|
+
const entriesUsed = readUsageEntries(entry.skill.name, sinceMs);
|
|
94
|
+
const runs = entriesUsed.length;
|
|
95
|
+
const errors = entriesUsed.filter((item) => !item.ok).length;
|
|
96
|
+
const lastTs = entriesUsed.reduce((max, item) => Math.max(max, item.ts), 0);
|
|
97
|
+
const durations = entriesUsed
|
|
98
|
+
.map((item) => item.durationMs)
|
|
99
|
+
.filter((val) => typeof val === "number" && val >= 0);
|
|
100
|
+
const avgDurationMs = durations.length > 0
|
|
101
|
+
? Math.round(durations.reduce((sum, val) => sum + val, 0) / durations.length)
|
|
102
|
+
: undefined;
|
|
21
103
|
return {
|
|
22
|
-
runs
|
|
23
|
-
errors
|
|
24
|
-
lastUsed: undefined,
|
|
25
|
-
avgDurationMs
|
|
104
|
+
runs,
|
|
105
|
+
errors,
|
|
106
|
+
lastUsed: lastTs ? new Date(lastTs).toISOString() : undefined,
|
|
107
|
+
avgDurationMs,
|
|
26
108
|
};
|
|
27
109
|
}
|
|
28
|
-
export async function getAggregateStats() {
|
|
29
|
-
const { config, workspaceDir,
|
|
110
|
+
export async function getAggregateStats(opts) {
|
|
111
|
+
const { config, workspaceDir, entries } = loadSkillEntries();
|
|
30
112
|
const status = buildWorkspaceSkillStatus(workspaceDir, {
|
|
31
113
|
config,
|
|
32
|
-
managedSkillsDir,
|
|
33
114
|
entries,
|
|
34
115
|
});
|
|
116
|
+
const sinceMs = opts?.windowDays && opts.windowDays > 0
|
|
117
|
+
? Date.now() - opts.windowDays * 24 * 60 * 60 * 1000
|
|
118
|
+
: undefined;
|
|
119
|
+
const usageCounts = [];
|
|
120
|
+
let totalRuns = 0;
|
|
121
|
+
for (const entry of entries) {
|
|
122
|
+
const skillRuns = readUsageEntries(entry.skill.name, sinceMs).length;
|
|
123
|
+
if (skillRuns > 0) {
|
|
124
|
+
usageCounts.push({ name: entry.skill.name, runs: skillRuns });
|
|
125
|
+
}
|
|
126
|
+
totalRuns += skillRuns;
|
|
127
|
+
}
|
|
128
|
+
usageCounts.sort((a, b) => b.runs - a.runs);
|
|
129
|
+
const mostUsed = usageCounts[0];
|
|
130
|
+
const limit = typeof opts?.limit === "number" && opts.limit > 0 ? opts.limit : 5;
|
|
131
|
+
const topUsed = usageCounts.slice(0, limit);
|
|
35
132
|
return {
|
|
36
|
-
totalRuns
|
|
133
|
+
totalRuns,
|
|
37
134
|
activeSkills: entries.length,
|
|
38
|
-
mostUsed:
|
|
135
|
+
mostUsed: mostUsed
|
|
136
|
+
? { name: mostUsed.name, runs: mostUsed.runs }
|
|
137
|
+
: undefined,
|
|
138
|
+
topUsed: topUsed.map((item) => ({ name: item.name, runs: item.runs })),
|
|
39
139
|
readyButUnused: status.skills
|
|
40
|
-
.filter((skill) => skill.eligible)
|
|
140
|
+
.filter((skill) => skill.eligible && !hasUsageEntries(skill.name))
|
|
41
141
|
.map((skill) => skill.name),
|
|
42
142
|
};
|
|
43
143
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import { NEXUS_ROOT } from "../utils.js";
|
|
3
3
|
import { getSkillMetadata, hasBinary, isBundledSkillAllowed, isConfigPathTruthy, loadWorkspaceSkillEntries, resolveBundledAllowlist, resolveConfigPath, resolveSkillConfig, resolveSkillsInstallPreferences, } from "./skills.js";
|
|
4
4
|
function resolveSkillKey(entry) {
|
|
5
5
|
return getSkillMetadata(entry)?.skillKey ?? entry.skill.name;
|
|
@@ -92,7 +92,8 @@ function buildSkillStatus(entry, config, prefs) {
|
|
|
92
92
|
continue;
|
|
93
93
|
if (skillConfig?.env?.[envName])
|
|
94
94
|
continue;
|
|
95
|
-
if (skillConfig?.apiKey &&
|
|
95
|
+
if (skillConfig?.apiKey &&
|
|
96
|
+
getSkillMetadata(entry)?.primaryEnv === envName) {
|
|
96
97
|
continue;
|
|
97
98
|
}
|
|
98
99
|
missingEnv.push(envName);
|
|
@@ -146,7 +147,7 @@ function buildSkillStatus(entry, config, prefs) {
|
|
|
146
147
|
};
|
|
147
148
|
}
|
|
148
149
|
export function buildWorkspaceSkillStatus(workspaceDir, opts) {
|
|
149
|
-
const managedSkillsDir = opts?.managedSkillsDir ?? path.join(
|
|
150
|
+
const managedSkillsDir = opts?.managedSkillsDir ?? path.join(NEXUS_ROOT, "skills", "managed");
|
|
150
151
|
const skillEntries = opts?.entries ?? loadWorkspaceSkillEntries(workspaceDir, opts);
|
|
151
152
|
const prefs = resolveSkillsInstallPreferences(opts?.config);
|
|
152
153
|
return {
|