@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.
Files changed (347) hide show
  1. package/dist/agents/agent-id.js +41 -0
  2. package/dist/agents/auth-profiles.js +114 -25
  3. package/dist/agents/identity-state.js +101 -0
  4. package/dist/agents/model-auth.js +1 -0
  5. package/dist/agents/model-fallback.js +15 -9
  6. package/dist/agents/model-selection.js +1 -1
  7. package/dist/agents/models-config.js +17 -11
  8. package/dist/agents/pi-embedded-runner.js +101 -9
  9. package/dist/agents/sandbox.js +12 -3
  10. package/dist/agents/skill-runner.js +41 -6
  11. package/dist/agents/skill-usage.js +117 -17
  12. package/dist/agents/skills-status.js +4 -3
  13. package/dist/agents/skills.js +38 -30
  14. package/dist/agents/subagent-registry.js +25 -11
  15. package/dist/agents/system-prompt.js +16 -0
  16. package/dist/agents/tool-policy.js +19 -3
  17. package/dist/agents/tools/browser-tool.js +5 -2
  18. package/dist/agents/tools/image-tool.js +93 -8
  19. package/dist/agents/tools/sessions-announce-target.js +5 -1
  20. package/dist/agents/workspace.js +81 -59
  21. package/dist/auto-reply/command-detection.js +2 -1
  22. package/dist/auto-reply/reply/directive-handling.js +153 -28
  23. package/dist/auto-reply/reply/directives.js +17 -2
  24. package/dist/auto-reply/reply/model-selection.js +8 -3
  25. package/dist/auto-reply/reply/queue.js +2 -2
  26. package/dist/auto-reply/reply.js +1 -1
  27. package/dist/auto-reply/thinking.js +15 -0
  28. package/dist/browser/chrome.js +1 -1
  29. package/dist/browser/client.js +2 -0
  30. package/dist/browser/config.js +6 -2
  31. package/dist/browser/pw-tools-core.js +3 -0
  32. package/dist/browser/routes/agent.js +14 -0
  33. package/dist/canvas-host/server.js +1 -1
  34. package/dist/capabilities/detector.js +46 -15
  35. package/dist/capabilities/registry.js +2 -1
  36. package/dist/cli/cloud-cli.js +70 -7
  37. package/dist/cli/credential-cli.js +214 -23
  38. package/dist/cli/gateway-cli.js +1 -1
  39. package/dist/cli/log-cli.js +25 -0
  40. package/dist/cli/pairing-cli.js +1 -1
  41. package/dist/cli/program.js +82 -8
  42. package/dist/cli/run-main.js +1 -1
  43. package/dist/cli/skills-cli.js +165 -30
  44. package/dist/cli/skills-hub-cli.js +68 -36
  45. package/dist/cli/tool-connector-cli.js +99 -24
  46. package/dist/cli/upstream-sync-cli.js +253 -96
  47. package/dist/cli/usage-cli.js +14 -0
  48. package/dist/commands/auth-choice-options.js +6 -1
  49. package/dist/commands/auth-choice.js +157 -5
  50. package/dist/commands/bootstrap-preset.js +26 -12
  51. package/dist/commands/capabilities.js +33 -6
  52. package/dist/commands/claude-md.js +3 -2
  53. package/dist/commands/config-view.js +1 -1
  54. package/dist/commands/config.js +85 -0
  55. package/dist/commands/configure.js +4 -4
  56. package/dist/commands/credential.js +497 -36
  57. package/dist/commands/cursor-hooks.js +240 -0
  58. package/dist/commands/cursor-rules.js +14 -188
  59. package/dist/commands/doctor.js +5 -4
  60. package/dist/commands/identity.js +29 -32
  61. package/dist/commands/init.js +304 -20
  62. package/dist/commands/log.js +134 -0
  63. package/dist/commands/models/fallbacks.js +1 -1
  64. package/dist/commands/models/image-fallbacks.js +1 -1
  65. package/dist/commands/models/list.js +1 -1
  66. package/dist/commands/models/scan.js +1 -1
  67. package/dist/commands/onboard-auth.js +27 -2
  68. package/dist/commands/onboard-eve-identity.js +8 -9
  69. package/dist/commands/onboard-non-interactive.js +4 -2
  70. package/dist/commands/onboard-quickstart.js +18 -11
  71. package/dist/commands/quest-state.js +271 -0
  72. package/dist/commands/quest.js +53 -13
  73. package/dist/commands/reset.js +1 -1
  74. package/dist/commands/sessions-ingest.js +5 -4
  75. package/dist/commands/setup.js +4 -2
  76. package/dist/commands/skills-manifest.js +89 -29
  77. package/dist/commands/status.js +193 -73
  78. package/dist/commands/suggestions.js +1 -1
  79. package/dist/commands/usage-tracking.js +32 -0
  80. package/dist/commands/usage-upload.js +6 -1
  81. package/dist/config/defaults.js +1 -3
  82. package/dist/config/includes.js +5 -7
  83. package/dist/config/io.js +88 -16
  84. package/dist/config/legacy.js +4 -2
  85. package/dist/config/paths.js +16 -0
  86. package/dist/config/sessions.js +9 -5
  87. package/dist/config/zod-schema.js +4 -3
  88. package/dist/control-plane/broker/broker.js +131 -78
  89. package/dist/control-plane/compaction.js +3 -5
  90. package/dist/control-plane/factory.js +2 -2
  91. package/dist/control-plane/index.js +2 -2
  92. package/dist/control-plane/odu/agents.js +28 -23
  93. package/dist/control-plane/odu/interaction-tools.js +62 -50
  94. package/dist/control-plane/odu/prompt-loader.js +8 -8
  95. package/dist/control-plane/odu/runtime.js +87 -75
  96. package/dist/control-plane/odu-control-plane.js +14 -12
  97. package/dist/control-plane/single-agent.js +13 -13
  98. package/dist/credentials/store.js +133 -7
  99. package/dist/daemon/launchd.js +14 -0
  100. package/dist/entry.js +0 -0
  101. package/dist/gateway/server-browser.js +5 -4
  102. package/dist/gateway/server-methods/cron.js +11 -1
  103. package/dist/gateway/server.js +14 -7
  104. package/dist/infra/bonjour.js +1 -1
  105. package/dist/infra/event-log.js +8 -2
  106. package/dist/infra/path-env.js +1 -2
  107. package/dist/infra/provider-usage.auth.js +5 -3
  108. package/dist/infra/provider-usage.fetch.claude.js +16 -6
  109. package/dist/infra/provider-usage.fetch.minimax.js +8 -3
  110. package/dist/infra/provider-usage.js +9 -5
  111. package/dist/infra/restart.js +2 -2
  112. package/dist/infra/usage-settings.js +78 -0
  113. package/dist/infra/usage-suggestions.js +17 -5
  114. package/dist/infra/usage-upload.js +38 -1
  115. package/dist/infra/voicewake.js +2 -2
  116. package/dist/media/image-ops.js +3 -1
  117. package/dist/memory/index.js +2 -381
  118. package/dist/native/nexus-cloud/darwin-arm64/nexus-cloud +0 -0
  119. package/dist/native/nexus-cloud/darwin-arm64/nexus-cloud-rs +0 -0
  120. package/dist/pairing/pairing-store.js +24 -0
  121. package/dist/providers/github-copilot-auth.js +1 -1
  122. package/dist/routing/resolve-route.js +6 -6
  123. package/dist/routing/session-key.js +3 -1
  124. package/dist/sessions/send-policy.js +5 -5
  125. package/dist/slack/monitor.js +22 -1
  126. package/dist/telegram/reaction-level.js +2 -1
  127. package/dist/utils.js +8 -3
  128. package/dist/wizard/onboarding.js +29 -7
  129. package/docs/AGENTS.default.md +1 -1
  130. package/docs/configuration.md +1 -1
  131. package/docs/feature-inventory/overview.md +2 -2
  132. package/docs/reference/templates/AGENTS.md +172 -109
  133. package/docs/templates/AGENTS.md +140 -199
  134. package/docs/templates/BOOTSTRAP.md +40 -20
  135. package/docs/templates/IDENTITY.md +6 -0
  136. package/docs/templates/USER.md +22 -2
  137. package/package.json +3 -1
  138. package/skills/{notion → connectors/notion}/SKILL.md +1 -1
  139. package/skills/{filesystem → guides/filesystem}/SKILL.md +1 -1
  140. package/skills/{onboarding → guides/onboarding}/SKILL.md +1 -1
  141. package/skills/{onboarding → guides/onboarding}/docs/CAPABILITY_TAXONOMY.md +5 -5
  142. package/skills/{onboarding → guides/onboarding}/docs/CLI_GRAMMAR.md +8 -8
  143. package/skills/{onboarding → guides/onboarding}/docs/CLI_GRAMMAR_ONBOARDING.md +2 -2
  144. package/skills/{onboarding → guides/onboarding}/docs/CLI_GRAMMAR_SKILLS.md +26 -20
  145. package/skills/{onboarding → guides/onboarding}/docs/GOAL_STATE_ARCHITECTURE.md +38 -43
  146. package/skills/{onboarding → guides/onboarding}/docs/NEXUS_SYSTEM_OVERVIEW.md +4 -4
  147. package/skills/{onboarding → guides/onboarding}/docs/SKILLS_HUB_SPEC.md +1 -1
  148. package/skills/{onboarding → guides/onboarding}/docs/SKILLS_SPECIFICATION.md +8 -7
  149. package/skills/{onboarding → guides/onboarding}/docs/SKILL_GATEWAY_DESIGN.md +16 -16
  150. package/skills/{onboarding → guides/onboarding}/docs/SKILL_GATEWAY_PRD.md +10 -12
  151. package/skills/guides/onboarding/docs/canonical/00_CONFLICT_ANALYSIS.md +463 -0
  152. package/skills/guides/onboarding/docs/canonical/01_NEXUS_OVERVIEW.md +167 -0
  153. package/skills/guides/onboarding/docs/canonical/02_CLI_REFERENCE.md +404 -0
  154. package/skills/guides/onboarding/docs/canonical/03_STATE_ARCHITECTURE.md +357 -0
  155. package/skills/guides/onboarding/docs/canonical/04_SKILL_SPECIFICATION.md +393 -0
  156. package/skills/guides/onboarding/docs/canonical/05_CAPABILITY_TAXONOMY.md +298 -0
  157. package/skills/guides/onboarding/docs/canonical/06_CAPABILITIES_REFERENCE.md +207 -0
  158. package/skills/guides/onboarding/docs/canonical/07_AGENT_BINDINGS.md +85 -0
  159. package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/nexus-cloud.md +2 -2
  160. package/skills/{onboarding → guides/onboarding}/scripts/ralph/progress.txt +1 -1
  161. package/skills/{nexus-cloud → tools/nexus-cloud}/SKILL.md +2 -1
  162. package/skills/{nexus-cloud → tools/nexus-cloud}/docs/setup.md +1 -1
  163. package/docs/templates/PROFILE.md +0 -14
  164. /package/skills/{brave-search → connectors/brave-search}/SKILL.md +0 -0
  165. /package/skills/{brave-search → connectors/brave-search}/docs/setup.md +0 -0
  166. /package/skills/{brave-search → connectors/brave-search}/docs/troubleshooting.md +0 -0
  167. /package/skills/{brave-search → connectors/brave-search}/docs/usage.md +0 -0
  168. /package/skills/{brave-search → connectors/brave-search}/scripts/content.mjs +0 -0
  169. /package/skills/{brave-search → connectors/brave-search}/scripts/search.mjs +0 -0
  170. /package/skills/{discord → connectors/discord}/SKILL.md +0 -0
  171. /package/skills/{gemini → connectors/gemini}/SKILL.md +0 -0
  172. /package/skills/{github → connectors/github}/SKILL.md +0 -0
  173. /package/skills/{github → connectors/github}/docs/setup.md +0 -0
  174. /package/skills/{github → connectors/github}/docs/troubleshooting.md +0 -0
  175. /package/skills/{google-oauth → connectors/google-oauth}/SKILL.md +0 -0
  176. /package/skills/{slack → connectors/slack}/SKILL.md +0 -0
  177. /package/skills/{telegram → connectors/telegram}/SKILL.md +0 -0
  178. /package/skills/{telegram → connectors/telegram}/docs/pairing.md +0 -0
  179. /package/skills/{telegram → connectors/telegram}/docs/setup.md +0 -0
  180. /package/skills/{telegram → connectors/telegram}/docs/webhook.md +0 -0
  181. /package/skills/{wacli → connectors/wacli}/SKILL.md +0 -0
  182. /package/skills/{wacli → connectors/wacli}/docs/auth.md +0 -0
  183. /package/skills/{wacli → connectors/wacli}/docs/backup.md +0 -0
  184. /package/skills/{wacli → connectors/wacli}/docs/troubleshooting.md +0 -0
  185. /package/skills/{browser-use-agent-sdk → guides/browser-use-agent-sdk}/SKILL.md +0 -0
  186. /package/skills/{json-render → guides/json-render}/SKILL.md +0 -0
  187. /package/skills/{json-render → guides/json-render}/assets/components/README.md +0 -0
  188. /package/skills/{json-render → guides/json-render}/assets/components/catalog.ts +0 -0
  189. /package/skills/{json-render → guides/json-render}/assets/components/registry.tsx +0 -0
  190. /package/skills/{json-render → guides/json-render}/assets/demo/App.css +0 -0
  191. /package/skills/{json-render → guides/json-render}/assets/demo/App.tsx +0 -0
  192. /package/skills/{json-render → guides/json-render}/assets/demo/README.md +0 -0
  193. /package/skills/{json-render → guides/json-render}/assets/demo/catalog.ts +0 -0
  194. /package/skills/{json-render → guides/json-render}/assets/demo/data/nexus-core.json +0 -0
  195. /package/skills/{json-render → guides/json-render}/assets/demo/index.css +0 -0
  196. /package/skills/{json-render → guides/json-render}/assets/demo/registry.tsx +0 -0
  197. /package/skills/{json-render → guides/json-render}/docs/nexus-state-demo.md +0 -0
  198. /package/skills/{json-render → guides/json-render}/docs/shadcn-preset.md +0 -0
  199. /package/skills/{json-render → guides/json-render}/scripts/create-vite-demo.sh +0 -0
  200. /package/skills/{json-render → guides/json-render}/scripts/llm-server/README.md +0 -0
  201. /package/skills/{json-render → guides/json-render}/scripts/llm-server/catalog.ts +0 -0
  202. /package/skills/{json-render → guides/json-render}/scripts/llm-server/package-lock.json +0 -0
  203. /package/skills/{json-render → guides/json-render}/scripts/llm-server/package.json +0 -0
  204. /package/skills/{json-render → guides/json-render}/scripts/llm-server/server.ts +0 -0
  205. /package/skills/{onboarding → guides/onboarding}/docs/CAPABILITIES.md +0 -0
  206. /package/skills/{onboarding → guides/onboarding}/docs/CLI_GRAMMAR_CREDENTIALS.md +0 -0
  207. /package/skills/{onboarding → guides/onboarding}/docs/DOCUMENTATION_OVERVIEW.md +0 -0
  208. /package/skills/{onboarding → guides/onboarding}/docs/ENTITY_MODEL.md +0 -0
  209. /package/skills/{onboarding → guides/onboarding}/docs/SKILL_INVENTORY.md +0 -0
  210. /package/skills/{onboarding → guides/onboarding}/docs/STATE_ARCHITECTURE.md +0 -0
  211. /package/skills/{onboarding → guides/onboarding}/docs/TROUBLESHOOTING.md +0 -0
  212. /package/skills/{onboarding → guides/onboarding}/docs/USER_JOURNEY.md +0 -0
  213. /package/skills/{onboarding → guides/onboarding}/docs/WOW_MOMENTS.md +0 -0
  214. /package/skills/{onboarding → guides/onboarding}/docs/agent-apple-id.md +0 -0
  215. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/1password.md +0 -0
  216. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/TEMPLATE.md +0 -0
  217. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/aix.md +0 -0
  218. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/bird.md +0 -0
  219. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/brave-search.md +0 -0
  220. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/comms.md +0 -0
  221. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/computer-use.md +0 -0
  222. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/cron-and-heartbeat.md +0 -0
  223. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/eve.md +0 -0
  224. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/github.md +0 -0
  225. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/gog.md +0 -0
  226. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/homebrew-prereqs.md +0 -0
  227. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/qmd.md +0 -0
  228. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/telegram.md +0 -0
  229. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/wacli.md +0 -0
  230. /package/skills/{onboarding → guides/onboarding}/docs/skill-deep-dives/weather.md +0 -0
  231. /package/skills/{onboarding → guides/onboarding}/scripts/ralph/prd.json +0 -0
  232. /package/skills/{onboarding → guides/onboarding}/scripts/ralph/prompt.md +0 -0
  233. /package/skills/{onboarding → guides/onboarding}/scripts/ralph/ralph.log +0 -0
  234. /package/skills/{onboarding → guides/onboarding}/scripts/ralph/ralph.sh +0 -0
  235. /package/skills/{onboarding → guides/onboarding}/scripts/setup-cursor-skills.sh +0 -0
  236. /package/skills/{1password → tools/1password}/SKILL.md +0 -0
  237. /package/skills/{1password → tools/1password}/docs/setup.md +0 -0
  238. /package/skills/{1password → tools/1password}/docs/troubleshooting.md +0 -0
  239. /package/skills/{1password → tools/1password}/references/cli-examples.md +0 -0
  240. /package/skills/{1password → tools/1password}/references/get-started.md +0 -0
  241. /package/skills/{agent-browser → tools/agent-browser}/SKILL.md +0 -0
  242. /package/skills/{agent-browser → tools/agent-browser}/docs/browser-use-eval.md +0 -0
  243. /package/skills/{agent-browser → tools/agent-browser}/docs/first-tests.md +0 -0
  244. /package/skills/{agent-browser → tools/agent-browser}/docs/wordle-nyt-eval.js +0 -0
  245. /package/skills/{aix → tools/aix}/SKILL.md +0 -0
  246. /package/skills/{aix → tools/aix}/docs/embeddings.md +0 -0
  247. /package/skills/{aix → tools/aix}/docs/setup.md +0 -0
  248. /package/skills/{aix → tools/aix}/docs/troubleshooting.md +0 -0
  249. /package/skills/{aix → tools/aix}/references/sql.md +0 -0
  250. /package/skills/{apple-notes → tools/apple-notes}/SKILL.md +0 -0
  251. /package/skills/{apple-reminders → tools/apple-reminders}/SKILL.md +0 -0
  252. /package/skills/{bear-notes → tools/bear-notes}/SKILL.md +0 -0
  253. /package/skills/{bird → tools/bird}/SKILL.md +0 -0
  254. /package/skills/{bird → tools/bird}/docs/auth.md +0 -0
  255. /package/skills/{bird → tools/bird}/docs/troubleshooting.md +0 -0
  256. /package/skills/{blogwatcher → tools/blogwatcher}/SKILL.md +0 -0
  257. /package/skills/{blucli → tools/blucli}/SKILL.md +0 -0
  258. /package/skills/{camsnap → tools/camsnap}/SKILL.md +0 -0
  259. /package/skills/{clawdhub → tools/clawdhub}/SKILL.md +0 -0
  260. /package/skills/{coding-agent → tools/coding-agent}/SKILL.md +0 -0
  261. /package/skills/{comms → tools/comms}/SKILL.md +0 -0
  262. /package/skills/{comms → tools/comms}/docs/adapters.md +0 -0
  263. /package/skills/{comms → tools/comms}/docs/setup.md +0 -0
  264. /package/skills/{comms → tools/comms}/docs/troubleshooting.md +0 -0
  265. /package/skills/{comms → tools/comms}/references/schema.md +0 -0
  266. /package/skills/{computer-use → tools/computer-use}/SKILL.md +0 -0
  267. /package/skills/{computer-use → tools/computer-use}/docs/open-interpreter.md +0 -0
  268. /package/skills/{computer-use → tools/computer-use}/docs/peekaboo.md +0 -0
  269. /package/skills/{computer-use → tools/computer-use}/docs/setup.md +0 -0
  270. /package/skills/{computer-use → tools/computer-use}/docs/troubleshooting.md +0 -0
  271. /package/skills/{eightctl → tools/eightctl}/SKILL.md +0 -0
  272. /package/skills/{eve → tools/eve}/SKILL.md +0 -0
  273. /package/skills/{eve → tools/eve}/docs/dual-account.md +0 -0
  274. /package/skills/{eve → tools/eve}/docs/intelligence.md +0 -0
  275. /package/skills/{eve → tools/eve}/docs/setup.md +0 -0
  276. /package/skills/{eve → tools/eve}/docs/troubleshooting.md +0 -0
  277. /package/skills/{eve → tools/eve}/scripts/setup-dual-account.sh +0 -0
  278. /package/skills/{food-order → tools/food-order}/SKILL.md +0 -0
  279. /package/skills/{gh → tools/gh}/SKILL.md +0 -0
  280. /package/skills/{gh → tools/gh}/docs/usage.md +0 -0
  281. /package/skills/{gifgrep → tools/gifgrep}/SKILL.md +0 -0
  282. /package/skills/{gog → tools/gog}/SKILL.md +0 -0
  283. /package/skills/{gog → tools/gog}/docs/portability.md +0 -0
  284. /package/skills/{gog → tools/gog}/docs/setup.md +0 -0
  285. /package/skills/{gog → tools/gog}/docs/troubleshooting.md +0 -0
  286. /package/skills/{gog → tools/gog}/scripts/cdp/README.md +0 -0
  287. /package/skills/{gog → tools/gog}/scripts/cdp/add_test_users.py +0 -0
  288. /package/skills/{gog → tools/gog}/scripts/cdp/auth_add_accounts.py +0 -0
  289. /package/skills/{gog → tools/gog}/scripts/cdp/auth_add_accounts_manual.py +0 -0
  290. /package/skills/{gog → tools/gog}/scripts/cdp/create_oauth_client.py +0 -0
  291. /package/skills/{gog → tools/gog}/scripts/cdp/launch_cdp_chrome.sh +0 -0
  292. /package/skills/{goplaces → tools/goplaces}/SKILL.md +0 -0
  293. /package/skills/{imsg → tools/imsg}/SKILL.md +0 -0
  294. /package/skills/{local-places → tools/local-places}/SERVER_README.md +0 -0
  295. /package/skills/{local-places → tools/local-places}/SKILL.md +0 -0
  296. /package/skills/{local-places → tools/local-places}/pyproject.toml +0 -0
  297. /package/skills/{local-places → tools/local-places}/src/local_places/__init__.py +0 -0
  298. /package/skills/{local-places → tools/local-places}/src/local_places/__pycache__/__init__.cpython-314.pyc +0 -0
  299. /package/skills/{local-places → tools/local-places}/src/local_places/__pycache__/google_places.cpython-314.pyc +0 -0
  300. /package/skills/{local-places → tools/local-places}/src/local_places/__pycache__/main.cpython-314.pyc +0 -0
  301. /package/skills/{local-places → tools/local-places}/src/local_places/__pycache__/schemas.cpython-314.pyc +0 -0
  302. /package/skills/{local-places → tools/local-places}/src/local_places/google_places.py +0 -0
  303. /package/skills/{local-places → tools/local-places}/src/local_places/main.py +0 -0
  304. /package/skills/{local-places → tools/local-places}/src/local_places/schemas.py +0 -0
  305. /package/skills/{mcporter → tools/mcporter}/SKILL.md +0 -0
  306. /package/skills/{model-usage → tools/model-usage}/SKILL.md +0 -0
  307. /package/skills/{model-usage → tools/model-usage}/references/codexbar-cli.md +0 -0
  308. /package/skills/{model-usage → tools/model-usage}/scripts/model_usage.py +0 -0
  309. /package/skills/{nano-banana-pro → tools/nano-banana-pro}/SKILL.md +0 -0
  310. /package/skills/{nano-banana-pro → tools/nano-banana-pro}/scripts/generate_image.py +0 -0
  311. /package/skills/{nano-pdf → tools/nano-pdf}/SKILL.md +0 -0
  312. /package/skills/{nexus-cloud → tools/nexus-cloud}/docs/security.md +0 -0
  313. /package/skills/{nexus-cloud → tools/nexus-cloud}/docs/troubleshooting.md +0 -0
  314. /package/skills/{obsidian → tools/obsidian}/SKILL.md +0 -0
  315. /package/skills/{openai-image-gen → tools/openai-image-gen}/SKILL.md +0 -0
  316. /package/skills/{openai-image-gen → tools/openai-image-gen}/scripts/gen.py +0 -0
  317. /package/skills/{openai-whisper → tools/openai-whisper}/SKILL.md +0 -0
  318. /package/skills/{openai-whisper-api → tools/openai-whisper-api}/SKILL.md +0 -0
  319. /package/skills/{openai-whisper-api → tools/openai-whisper-api}/scripts/transcribe.sh +0 -0
  320. /package/skills/{openhue → tools/openhue}/SKILL.md +0 -0
  321. /package/skills/{oracle → tools/oracle}/SKILL.md +0 -0
  322. /package/skills/{ordercli → tools/ordercli}/SKILL.md +0 -0
  323. /package/skills/{peekaboo → tools/peekaboo}/SKILL.md +0 -0
  324. /package/skills/{qmd → tools/qmd}/SKILL.md +0 -0
  325. /package/skills/{qmd → tools/qmd}/docs/mcp.md +0 -0
  326. /package/skills/{qmd → tools/qmd}/docs/ollama.md +0 -0
  327. /package/skills/{qmd → tools/qmd}/docs/setup.md +0 -0
  328. /package/skills/{sag → tools/sag}/SKILL.md +0 -0
  329. /package/skills/{skill-cli-template → tools/skill-cli-template}/SKILL.md +0 -0
  330. /package/skills/{songsee → tools/songsee}/SKILL.md +0 -0
  331. /package/skills/{sonoscli → tools/sonoscli}/SKILL.md +0 -0
  332. /package/skills/{spotify-player → tools/spotify-player}/SKILL.md +0 -0
  333. /package/skills/{summarize → tools/summarize}/SKILL.md +0 -0
  334. /package/skills/{things-mac → tools/things-mac}/SKILL.md +0 -0
  335. /package/skills/{tmux → tools/tmux}/SKILL.md +0 -0
  336. /package/skills/{tmux → tools/tmux}/scripts/find-sessions.sh +0 -0
  337. /package/skills/{tmux → tools/tmux}/scripts/wait-for-text.sh +0 -0
  338. /package/skills/{trello → tools/trello}/SKILL.md +0 -0
  339. /package/skills/{upstream-sync → tools/upstream-sync}/SKILL.md +0 -0
  340. /package/skills/{upstream-sync → tools/upstream-sync}/scripts/auto-port.sh +0 -0
  341. /package/skills/{upstream-sync → tools/upstream-sync}/scripts/check-all.sh +0 -0
  342. /package/skills/{upstream-sync → tools/upstream-sync}/scripts/check-nexus.sh +0 -0
  343. /package/skills/{upstream-sync → tools/upstream-sync}/scripts/check-pi-ai.sh +0 -0
  344. /package/skills/{video-frames → tools/video-frames}/SKILL.md +0 -0
  345. /package/skills/{video-frames → tools/video-frames}/scripts/frame.sh +0 -0
  346. /package/skills/{weather → tools/weather}/SKILL.md +0 -0
  347. /package/skills/{weather → tools/weather}/docs/usage.md +0 -0
@@ -1,39 +1,156 @@
1
1
  import path from "node:path";
2
2
  import chalk from "chalk";
3
- import { getSkillInfo, runSkill, verifySkill } from "../agents/skill-runner.js";
4
- import { getAggregateStats, getSkillStats } from "../agents/skill-usage.js";
5
- import { flattenManifest, readSkillManifest } from "../commands/skills-manifest.js";
6
- import { MANAGED_SKILLS_DIR, NEXUS_ROOT } from "../utils.js";
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 manifest = await readSkillManifest();
15
- if (!manifest) {
16
- console.error("No skills manifest found. Run 'nexus init' to initialize your workspace.");
17
- process.exit(1);
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(manifest, null, 2));
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
- const allSkills = flattenManifest(manifest);
24
- if (allSkills.length === 0) {
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 (${allSkills.length} total)\n`);
29
- for (const skillEntry of allSkills) {
30
- const desc = skillEntry.description
31
- ? ` - ${skillEntry.description.slice(0, 60)}${skillEntry.description.length > 60 ? "..." : ""}`
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
- console.log(` ${skillEntry.name}${desc}`);
146
+ const icon = STATUS_ICON[item.status] ?? "";
147
+ console.log(` ${icon} ${item.name}${desc}`);
34
148
  }
35
- console.log(`\nSkills directory: ${MANAGED_SKILLS_DIR}`);
36
- console.log(`User skills: ${path.join(NEXUS_ROOT, "home", "skills")}\n`);
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
- console.log(JSON.stringify(output, null, 2));
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("Run a skill command with arguments")
80
- .allowUnknownOption()
81
- .action(async (name, _opts, command) => {
82
- const args = command.args.slice(1);
83
- const result = await runSkill(name, args);
84
- if (!result.ok) {
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
- console.log(`Most used: ${stats.mostUsed?.name ?? "none"}`);
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 crypto from "node:crypto";
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 { MANAGED_SKILLS_DIR, resolveUserPath } from "../utils.js";
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" ? value : {};
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
- entry.metadata?.nexus
149
- ? entry.metadata.nexus.provides
150
- : undefined,
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(managedSkillsDir) {
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 && input.trim())
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" ? frontmatter.description : "") ||
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" ? frontmatter.repository : "") ||
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 nexus = manifestEntry.metadata;
534
- nexus.nexus = {
535
- ...(nexus.nexus ?? {}),
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 manifest = await generateSkillManifest(MANAGED_SKILLS_DIR, params.userSkillsDir);
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.command("skills").description("Search and install skills from the Nexus Hub");
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 managedSkillsDir = MANAGED_SKILLS_DIR;
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) => [entry.skill.name, getSkillMetadata(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.map((i) => i.label).filter(Boolean).join(", ")}`);
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
- ].map((cap) => cap.trim()).filter(Boolean);
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" ? opts.description.trim() : undefined,
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" ? opts.repository.trim() : undefined,
886
- homepage: typeof opts.homepage === "string" ? opts.homepage.trim() : undefined,
887
- visibility: typeof opts.visibility === "string" ? opts.visibility.trim() : "public",
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" ? resolveUserPath(opts.source) : undefined,
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 managedSkillsDir = MANAGED_SKILLS_DIR;
1023
- const managedDir = path.join(managedSkillsDir, "managed");
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 { ensureCredentialIndexSync } from "../credentials/store.js";
5
- import { NEXUS_ROOT } from "../utils.js";
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.command("tool").description("Tool verification and paths");
23
- const connector = program.command("connector").description("Connector verification and accounts");
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 entries = loadWorkspaceSkillEntries(path.join(NEXUS_ROOT, "home"));
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 results = tools.map((entry) => {
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 <bin>")
57
- .description("Resolve binary path")
58
- .action((bin) => {
59
- const resolved = resolveBinaryPath(bin);
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: ${bin}`);
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 entries = loadWorkspaceSkillEntries(path.join(NEXUS_ROOT, "home"));
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 = connectors.map((entry) => {
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: hasCredential,
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
- console.log(JSON.stringify(index, null, 2));
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
- for (const [service, info] of Object.entries(index.services ?? {})) {
112
- console.log(service);
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
  }