@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,18 +1,18 @@
1
1
  import net from "node:net";
2
+ import { CLAUDE_CLI_PROFILE_ID, CODEX_CLI_PROFILE_ID, ensureAuthProfileStore, } from "../agents/auth-profiles.js";
2
3
  import { CONFIG_PATH_NEXUS, readConfigFileSnapshot, resolveGatewayPort, writeConfigFile, } from "../config/config.js";
3
- import { resolveGatewayService } from "../daemon/service.js";
4
- import { resolveGatewayProgramArguments } from "../daemon/program-args.js";
5
4
  import { GATEWAY_LAUNCH_AGENT_LABEL } from "../daemon/constants.js";
5
+ import { resolveGatewayProgramArguments } from "../daemon/program-args.js";
6
+ import { resolveGatewayService } from "../daemon/service.js";
6
7
  import { ensureControlUiAssetsBuilt } from "../infra/control-ui-assets.js";
7
8
  import { defaultRuntime } from "../runtime.js";
8
9
  import { resolveUserPath, sleep } from "../utils.js";
10
+ import { applyBootstrapPreset } from "./bootstrap-preset.js";
9
11
  import { healthCommand } from "./health.js";
10
12
  import { applyAuthProfileConfig, setAnthropicApiKey } from "./onboard-auth.js";
11
- import { applyBootstrapPreset } from "./bootstrap-preset.js";
12
13
  import { applyWizardMetadata, DEFAULT_WORKSPACE, detectBrowserOpenSupport, ensureWorkspaceAndSessions, openUrl, resolveControlUiLinks, } from "./onboard-helpers.js";
13
- import { CLAUDE_CLI_PROFILE_ID, CODEX_CLI_PROFILE_ID, ensureAuthProfileStore, } from "../agents/auth-profiles.js";
14
- import { ensureSystemdUserLingerNonInteractive } from "./systemd-linger.js";
15
14
  import { applyOpenAICodexModelDefault } from "./openai-codex-model-default.js";
15
+ import { ensureSystemdUserLingerNonInteractive } from "./systemd-linger.js";
16
16
  async function isPortFree(port) {
17
17
  try {
18
18
  await new Promise((resolve, reject) => {
@@ -51,7 +51,7 @@ async function pickGatewayPort(preferred) {
51
51
  });
52
52
  }
53
53
  function applyQuickstartAuth(cfg, runtime) {
54
- // Sync external credentials (Keychain on macOS, ~/.claude, ~/.codex) into the store.
54
+ // Quickstart only considers credentials already imported into the store.
55
55
  const store = ensureAuthProfileStore();
56
56
  // 1) Prefer OpenAI Codex credentials if present (works without API keys).
57
57
  if (store.profiles[CODEX_CLI_PROFILE_ID]) {
@@ -79,9 +79,9 @@ function applyQuickstartAuth(cfg, runtime) {
79
79
  // valid for general Anthropic API requests. We avoid auto-selecting them here.
80
80
  // Users can still opt in via `nexus onboard` interactive.
81
81
  if (store.profiles[CLAUDE_CLI_PROFILE_ID]) {
82
- runtime.log('Detected Claude Code credentials, but Nexus may require an Anthropic API key (or another provider) for API access. Run `nexus onboard` to choose billing/auth.');
82
+ runtime.log("Detected Claude Code credentials, but Nexus may require an Anthropic API key (or another provider) for API access. Run `nexus onboard` to choose billing/auth.");
83
83
  }
84
- runtime.log("No Claude/Codex credentials detected yet. You can set this later via `nexus onboard` or `nexus configure`.");
84
+ runtime.log("No Claude/Codex credentials detected yet. If you use the CLIs, run `nexus credential import claude-cli` or `nexus credential import codex-cli`.");
85
85
  return cfg;
86
86
  }
87
87
  export async function runQuickstartOnboarding(opts, runtime = defaultRuntime) {
@@ -113,14 +113,19 @@ export async function runQuickstartOnboarding(opts, runtime = defaultRuntime) {
113
113
  },
114
114
  };
115
115
  nextConfig = applyQuickstartAuth(nextConfig, runtime);
116
- nextConfig = applyWizardMetadata(nextConfig, { command: "onboard", mode: "local" });
116
+ nextConfig = applyWizardMetadata(nextConfig, {
117
+ command: "onboard",
118
+ mode: "local",
119
+ });
117
120
  await writeConfigFile(nextConfig);
118
121
  runtime.log(`Updated ${CONFIG_PATH_NEXUS}`);
119
122
  await ensureWorkspaceAndSessions(workspaceDir, runtime, {
120
123
  skipBootstrap: Boolean(nextConfig.agent?.skipBootstrap),
121
124
  });
122
125
  // Scripted bootstrap (test harness / automation): fill identity files + delete BOOTSTRAP.md.
123
- if (opts.bootstrapPreset || opts.bootstrapAgentName || opts.bootstrapUserName) {
126
+ if (opts.bootstrapPreset ||
127
+ opts.bootstrapAgentName ||
128
+ opts.bootstrapUserName) {
124
129
  await applyBootstrapPreset({
125
130
  workspaceDir,
126
131
  runtime,
@@ -142,7 +147,9 @@ export async function runQuickstartOnboarding(opts, runtime = defaultRuntime) {
142
147
  const { programArguments, workingDirectory } = await resolveGatewayProgramArguments({ port, dev: devMode });
143
148
  const environment = {
144
149
  PATH: process.env.PATH,
145
- NEXUS_LAUNCHD_LABEL: process.platform === "darwin" ? GATEWAY_LAUNCH_AGENT_LABEL : undefined,
150
+ NEXUS_LAUNCHD_LABEL: process.platform === "darwin"
151
+ ? GATEWAY_LAUNCH_AGENT_LABEL
152
+ : undefined,
146
153
  };
147
154
  await service.install({
148
155
  env: process.env,
@@ -0,0 +1,271 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { DEFAULT_AGENT_WORKSPACE_DIR } from "../agents/workspace.js";
4
+ import { loadConfig } from "../config/config.js";
5
+ import { resolveUserPath } from "../utils.js";
6
+ const QUEST_CATALOG = [
7
+ {
8
+ id: "identity-setup",
9
+ title: "Identity setup",
10
+ description: "Create the agent + user identity files.",
11
+ path: "core",
12
+ weight: 10,
13
+ quickWin: true,
14
+ },
15
+ {
16
+ id: "filesystem-wow",
17
+ title: "Filesystem organization",
18
+ description: "Use home/ projects + memory for a quick win.",
19
+ path: "core",
20
+ weight: 5,
21
+ quickWin: true,
22
+ },
23
+ {
24
+ id: "credential-manager",
25
+ title: "Credential manager",
26
+ description: "Store your first credentials for secure access.",
27
+ path: "core",
28
+ weight: 15,
29
+ },
30
+ {
31
+ id: "cloud-backup",
32
+ title: "Cloud backup",
33
+ description: "Set up Nexus Cloud sync + rollback.",
34
+ path: "core",
35
+ weight: 10,
36
+ },
37
+ {
38
+ id: "connect-email",
39
+ title: "Connect email",
40
+ description: "Unlock email read/send capabilities.",
41
+ path: "breadth",
42
+ weight: 10,
43
+ },
44
+ {
45
+ id: "connect-messages",
46
+ title: "Connect messages",
47
+ description: "Unlock messaging read/send capabilities.",
48
+ path: "breadth",
49
+ weight: 10,
50
+ },
51
+ {
52
+ id: "connect-calendar",
53
+ title: "Connect calendar",
54
+ description: "Unlock calendar access.",
55
+ path: "breadth",
56
+ weight: 5,
57
+ },
58
+ {
59
+ id: "enable-llm",
60
+ title: "Enable LLM",
61
+ description: "Configure an LLM provider.",
62
+ path: "breadth",
63
+ weight: 5,
64
+ },
65
+ {
66
+ id: "enable-scheduling",
67
+ title: "Enable scheduling",
68
+ description: "Turn on scheduling automation.",
69
+ path: "power",
70
+ weight: 10,
71
+ },
72
+ {
73
+ id: "enable-agent-comms",
74
+ title: "Enable agent comms",
75
+ description: "Let your agent reach you outside the IDE.",
76
+ path: "power",
77
+ weight: 15,
78
+ },
79
+ {
80
+ id: "first-automation",
81
+ title: "First automation",
82
+ description: "Set up a reactive trigger.",
83
+ path: "power",
84
+ weight: 5,
85
+ },
86
+ {
87
+ id: "completionist",
88
+ title: "Completionist",
89
+ description: "Unlock everything in the catalog.",
90
+ path: "secret",
91
+ weight: 5,
92
+ },
93
+ {
94
+ id: "polyglot",
95
+ title: "Polyglot",
96
+ description: "Connect 3+ distinct messaging platforms.",
97
+ path: "secret",
98
+ weight: 5,
99
+ },
100
+ {
101
+ id: "social-butterfly",
102
+ title: "Social butterfly",
103
+ description: "Connect multiple social networks.",
104
+ path: "secret",
105
+ weight: 5,
106
+ },
107
+ {
108
+ id: "home-automation",
109
+ title: "Home automation",
110
+ description: "Activate smart home capabilities.",
111
+ path: "secret",
112
+ weight: 5,
113
+ },
114
+ {
115
+ id: "full-stack",
116
+ title: "Full stack",
117
+ description: "Enable web + automation + dev tooling.",
118
+ path: "secret",
119
+ weight: 5,
120
+ },
121
+ ];
122
+ const QUEST_ORDER = QUEST_CATALOG.map((quest) => quest.id);
123
+ const QUEST_PROGRESS_VERSION = 1;
124
+ const PROGRESS_NOTE = "Progress is computed dynamically; no persistent progress.json.";
125
+ function getCapabilityStatusMap(capabilities) {
126
+ return new Map(capabilities.map((cap) => [cap.id, cap.status]));
127
+ }
128
+ function isCapabilityReady(status) {
129
+ return status === "active" || status === "ready";
130
+ }
131
+ async function dirHasEntries(dir) {
132
+ try {
133
+ const entries = await fs.promises.readdir(dir, { withFileTypes: true });
134
+ return entries.some((entry) => entry.name && !entry.name.startsWith("."));
135
+ }
136
+ catch {
137
+ return false;
138
+ }
139
+ }
140
+ function resolveWorkspaceDir() {
141
+ const config = loadConfig();
142
+ return resolveUserPath(config.agent?.workspace ?? DEFAULT_AGENT_WORKSPACE_DIR);
143
+ }
144
+ function computeQuestAutoCompletion(params) {
145
+ const { identityConfigured, capabilities, credentials, workspaceDir } = params;
146
+ const capabilityMap = getCapabilityStatusMap(capabilities);
147
+ const hasCredentials = Object.keys(credentials.services ?? {}).length > 0;
148
+ const anyReady = (ids) => ids.some((id) => isCapabilityReady(capabilityMap.get(id)));
149
+ return (async () => {
150
+ const hasProjects = await dirHasEntries(path.join(workspaceDir, "projects"));
151
+ const hasMemory = await dirHasEntries(path.join(workspaceDir, "memory"));
152
+ const readySocial = anyReady(["social-x", "social-instagram", "social-linkedin"]) ||
153
+ anyReady(["social", "social-news"]);
154
+ const readyMessaging = anyReady(["messaging-read", "messaging-send"]);
155
+ const readyChat = anyReady(["chat-send", "chat-read"]);
156
+ const readySmartHome = anyReady([
157
+ "smart-lights",
158
+ "smart-audio",
159
+ "smart-sleep",
160
+ "bluetooth",
161
+ "camera-control",
162
+ ]);
163
+ const readyDev = anyReady(["version-control", "terminal-sessions"]);
164
+ const readyWeb = anyReady(["web-search", "url-fetch"]);
165
+ const readyAutomation = anyReady(["reactive-triggers"]);
166
+ return {
167
+ "identity-setup": identityConfigured,
168
+ "filesystem-wow": hasProjects || hasMemory,
169
+ "credential-manager": hasCredentials,
170
+ "cloud-backup": anyReady(["cloud-sync", "rollback"]),
171
+ "connect-email": anyReady(["email-read", "email-send"]),
172
+ "connect-messages": readyMessaging,
173
+ "connect-calendar": anyReady(["calendar"]),
174
+ "enable-llm": anyReady(["anthropic", "openai", "gemini"]),
175
+ "enable-scheduling": anyReady(["scheduling"]),
176
+ "enable-agent-comms": readyChat || readyMessaging,
177
+ "first-automation": readyAutomation,
178
+ completionist: capabilities.every((cap) => cap.status === "active"),
179
+ polyglot: readyMessaging && readyChat,
180
+ "social-butterfly": readySocial,
181
+ "home-automation": readySmartHome,
182
+ "full-stack": readyWeb && readyAutomation && readyDev,
183
+ };
184
+ })();
185
+ }
186
+ function computePower(quests) {
187
+ const baseQuests = quests.filter((quest) => quest.path !== "secret");
188
+ const bonusQuests = quests.filter((quest) => quest.path === "secret" && quest.status === "completed");
189
+ const baseTotal = baseQuests.reduce((sum, quest) => sum + quest.weight, 0);
190
+ const baseScore = baseQuests.reduce((sum, quest) => sum + (quest.status === "completed" ? quest.weight : 0), 0);
191
+ const bonus = bonusQuests.reduce((sum, quest) => sum + quest.weight, 0);
192
+ const percent = baseTotal > 0 ? Math.round((baseScore / baseTotal) * 100) : 0;
193
+ const nextQuest = baseQuests.find((quest) => quest.status !== "completed");
194
+ return {
195
+ score: baseScore + bonus,
196
+ baseTotal,
197
+ percent: Math.min(100, Math.max(0, percent)),
198
+ bonus,
199
+ nextQuest: nextQuest
200
+ ? { id: nextQuest.id, title: nextQuest.title, weight: nextQuest.weight }
201
+ : undefined,
202
+ };
203
+ }
204
+ function buildProgressSnapshot(quests, updatedAt) {
205
+ const entries = {};
206
+ for (const quest of quests) {
207
+ entries[quest.id] = {
208
+ status: quest.status,
209
+ completedAt: quest.status === "completed" ? updatedAt : undefined,
210
+ updatedAt,
211
+ };
212
+ }
213
+ return {
214
+ version: QUEST_PROGRESS_VERSION,
215
+ updatedAt,
216
+ quests: entries,
217
+ };
218
+ }
219
+ function sortQuests(a, b) {
220
+ const aIdx = QUEST_ORDER.indexOf(a.id);
221
+ const bIdx = QUEST_ORDER.indexOf(b.id);
222
+ if (aIdx !== -1 && bIdx !== -1)
223
+ return aIdx - bIdx;
224
+ if (aIdx !== -1)
225
+ return -1;
226
+ if (bIdx !== -1)
227
+ return 1;
228
+ return a.title.localeCompare(b.title);
229
+ }
230
+ export async function resolveQuestState(params) {
231
+ const workspaceDir = params.workspaceDir ?? resolveWorkspaceDir();
232
+ const autoCompletion = await computeQuestAutoCompletion({
233
+ identityConfigured: params.identityConfigured,
234
+ capabilities: params.capabilities,
235
+ credentials: params.credentials,
236
+ workspaceDir,
237
+ });
238
+ const now = new Date().toISOString();
239
+ const quests = QUEST_CATALOG.filter((quest) => params.includeSecrets || quest.path !== "secret").map((quest) => {
240
+ const autoCompleted = Boolean(autoCompletion[quest.id]);
241
+ const status = autoCompleted ? "completed" : "not_started";
242
+ return {
243
+ ...quest,
244
+ status,
245
+ autoCompleted,
246
+ };
247
+ });
248
+ quests.sort(sortQuests);
249
+ const power = computePower(quests);
250
+ const progress = buildProgressSnapshot(quests, now);
251
+ progress.note = PROGRESS_NOTE;
252
+ return { quests, progress, power };
253
+ }
254
+ export async function startQuest(questId) {
255
+ const now = new Date().toISOString();
256
+ return {
257
+ version: QUEST_PROGRESS_VERSION,
258
+ updatedAt: now,
259
+ quests: {
260
+ [questId]: {
261
+ status: "in_progress",
262
+ startedAt: now,
263
+ updatedAt: now,
264
+ },
265
+ },
266
+ note: PROGRESS_NOTE,
267
+ };
268
+ }
269
+ export function getQuestCatalog() {
270
+ return [...QUEST_CATALOG];
271
+ }
@@ -1,27 +1,67 @@
1
- import { defaultRuntime } from "../runtime.js";
1
+ import { resolveIdentitySnapshot } from "../agents/identity-state.js";
2
2
  import { detectCapabilities } from "../capabilities/detector.js";
3
+ import { defaultRuntime } from "../runtime.js";
4
+ import { listCredentials } from "./credential.js";
5
+ import { getQuestCatalog, resolveQuestState, startQuest, } from "./quest-state.js";
3
6
  export async function questCommand(opts, runtime = defaultRuntime) {
7
+ if (opts?.start) {
8
+ const catalog = getQuestCatalog();
9
+ if (!catalog.some((quest) => quest.id === opts.start)) {
10
+ runtime.error(`Unknown quest: ${opts.start}`);
11
+ runtime.exit(1);
12
+ return;
13
+ }
14
+ await startQuest(opts.start);
15
+ if (!opts.json) {
16
+ runtime.log(`Marked quest as in-progress: ${opts.start}`);
17
+ runtime.log("Note: quest progress is computed dynamically (no progress.json).");
18
+ }
19
+ }
4
20
  const snapshot = detectCapabilities();
5
- const suggestions = snapshot.capabilities
6
- .filter((cap) => ["needs_setup", "needs_install", "ready"].includes(cap.status))
7
- .slice(0, 5)
8
- .map((cap) => ({
9
- id: cap.id,
10
- status: cap.status,
11
- providers: cap.providers.map((p) => p.id),
12
- }));
21
+ const credentials = await listCredentials();
22
+ const identityResolution = resolveIdentitySnapshot();
23
+ const identityConfigured = identityResolution.ok
24
+ ? identityResolution.snapshot.hasIdentity
25
+ : false;
26
+ const questState = await resolveQuestState({
27
+ identityConfigured,
28
+ capabilities: snapshot.capabilities,
29
+ credentials,
30
+ includeSecrets: Boolean(opts?.secrets),
31
+ });
32
+ let quests = questState.quests;
33
+ if (opts?.powerPath) {
34
+ quests = quests.filter((quest) => quest.path === "power");
35
+ }
36
+ if (opts?.quickWins) {
37
+ quests = quests.filter((quest) => quest.quickWin);
38
+ }
39
+ if (!opts?.list && !opts?.progress) {
40
+ quests = quests.filter((quest) => quest.status !== "completed").slice(0, 5);
41
+ }
13
42
  if (opts?.json) {
14
43
  runtime.log(JSON.stringify({
15
- suggestions,
44
+ power: questState.power,
45
+ quests,
46
+ progress: questState.progress,
16
47
  }, null, 2));
17
48
  return;
18
49
  }
19
- if (suggestions.length === 0) {
50
+ if (opts?.progress) {
51
+ const completed = quests.filter((quest) => quest.status === "completed").length;
52
+ runtime.log(`Quest progress: ${completed}/${quests.length} complete (${questState.power.percent}%)`);
53
+ if (questState.power.nextQuest) {
54
+ runtime.log(`Next unlock: ${questState.power.nextQuest.title} (+${questState.power.nextQuest.weight}%)`);
55
+ }
56
+ return;
57
+ }
58
+ if (quests.length === 0) {
20
59
  runtime.log("No quests found. You're fully configured.");
21
60
  return;
22
61
  }
23
62
  runtime.log("Quests");
24
- for (const [idx, item] of suggestions.entries()) {
25
- runtime.log(` ${idx + 1}. ${item.id} (${item.status})`);
63
+ for (const [idx, item] of quests.entries()) {
64
+ const pathLabel = item.path === "secret" ? "secret" : item.path;
65
+ runtime.log(` ${idx + 1}. ${item.id} (${pathLabel}, ${item.status})`);
26
66
  }
27
67
  }
@@ -7,7 +7,7 @@ import { defaultRuntime } from "../runtime.js";
7
7
  * Requires --confirm flag to actually delete.
8
8
  */
9
9
  export async function resetCommand(opts = {}, runtime = defaultRuntime) {
10
- const { local = false, state = false, all = false, confirm = false, workspace } = opts;
10
+ const { local = false, state = false, all = false, confirm = false, workspace, } = opts;
11
11
  // Validate: at least one target must be specified
12
12
  if (!local && !state && !all) {
13
13
  throw new Error("Must specify at least one target: --local, --state, or --all");
@@ -56,7 +56,10 @@ function lexicalToPlainText(raw) {
56
56
  }
57
57
  };
58
58
  walk(root);
59
- return out.join("").replace(/\n{3,}/g, "\n\n").trim();
59
+ return out
60
+ .join("")
61
+ .replace(/\n{3,}/g, "\n\n")
62
+ .trim();
60
63
  }
61
64
  catch {
62
65
  return raw;
@@ -119,9 +122,7 @@ async function findCursorWorkspaceStorageDir(params) {
119
122
  return { hash, dir, stateDbPath };
120
123
  }
121
124
  }
122
- catch {
123
- continue;
124
- }
125
+ catch { }
125
126
  }
126
127
  return null;
127
128
  }
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import JSON5 from "json5";
4
- import { DEFAULT_AGENT_WORKSPACE_DIR, ensureAgentWorkspace } from "../agents/workspace.js";
4
+ import { DEFAULT_AGENT_WORKSPACE_DIR, ensureAgentWorkspace, } from "../agents/workspace.js";
5
5
  import { CONFIG_PATH_NEXUS } from "../config/config.js";
6
6
  import { applyModelDefaults } from "../config/defaults.js";
7
7
  import { resolveSessionTranscriptsDir } from "../config/sessions.js";
@@ -21,7 +21,9 @@ async function readConfigFileRaw() {
21
21
  }
22
22
  async function writeConfigFile(cfg) {
23
23
  await fs.mkdir(path.dirname(CONFIG_PATH_NEXUS), { recursive: true });
24
- const json = JSON.stringify(applyModelDefaults(cfg), null, 2).trimEnd().concat("\n");
24
+ const json = JSON.stringify(applyModelDefaults(cfg), null, 2)
25
+ .trimEnd()
26
+ .concat("\n");
25
27
  await fs.writeFile(CONFIG_PATH_NEXUS, json, "utf-8");
26
28
  }
27
29
  export async function setupCommand(opts, runtime = defaultRuntime) {
@@ -2,7 +2,7 @@ import fs from "node:fs";
2
2
  import fsp from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
- import { resolveStateDir } from "../config/paths.js";
5
+ import { SKILLS_STATE_DIR } from "../utils.js";
6
6
  /**
7
7
  * Parse skill frontmatter to extract name and description
8
8
  */
@@ -16,7 +16,7 @@ function parseSkillFrontmatter(content) {
16
16
  return result;
17
17
  const block = normalized.slice(4, endIndex);
18
18
  for (const line of block.split("\n")) {
19
- const match = line.match(/^(name|description):\s*(.*)$/);
19
+ const match = line.match(/^(name|description|type|metadata):\s*(.*)$/);
20
20
  if (!match)
21
21
  continue;
22
22
  const key = match[1];
@@ -26,10 +26,40 @@ function parseSkillFrontmatter(content) {
26
26
  (value.startsWith("'") && value.endsWith("'"))) {
27
27
  value = value.slice(1, -1);
28
28
  }
29
- result[key] = value;
29
+ if (key === "metadata") {
30
+ result.metadataRaw = value;
31
+ }
32
+ else {
33
+ result[key] = value;
34
+ }
30
35
  }
31
36
  return result;
32
37
  }
38
+ function resolveSkillRootDirs(rootDir) {
39
+ const typedDirs = ["tools", "connectors", "guides"].map((segment) => path.join(rootDir, segment));
40
+ const existingTyped = typedDirs.filter((dir) => fs.existsSync(dir));
41
+ if (existingTyped.length > 0)
42
+ return existingTyped;
43
+ return fs.existsSync(rootDir) ? [rootDir] : [];
44
+ }
45
+ function resolveSkillType(frontmatter) {
46
+ if (frontmatter.type === "tool" || frontmatter.type === "connector" || frontmatter.type === "guide") {
47
+ return frontmatter.type;
48
+ }
49
+ if (!frontmatter.metadataRaw)
50
+ return null;
51
+ try {
52
+ const parsed = JSON.parse(frontmatter.metadataRaw);
53
+ const type = parsed?.nexus?.type;
54
+ if (type === "tool" || type === "connector" || type === "guide") {
55
+ return type;
56
+ }
57
+ }
58
+ catch {
59
+ return null;
60
+ }
61
+ return null;
62
+ }
33
63
  /**
34
64
  * Resolve the bundled skills directory from the installed Nexus package.
35
65
  * This finds skills shipped with the CLI, NOT from user workspace.
@@ -98,6 +128,17 @@ async function scanSkillsDir(dir, source) {
98
128
  }
99
129
  return skills;
100
130
  }
131
+ async function scanSkillRoots(rootDir, source) {
132
+ const roots = resolveSkillRootDirs(rootDir);
133
+ const merged = {};
134
+ for (const root of roots) {
135
+ const scanned = await scanSkillsDir(root, source);
136
+ for (const [name, entry] of Object.entries(scanned)) {
137
+ merged[name] = entry;
138
+ }
139
+ }
140
+ return merged;
141
+ }
101
142
  /**
102
143
  * Copy bundled skills from installed package to ~/nexus/skills/
103
144
  */
@@ -113,29 +154,48 @@ export async function copyBundledSkills(targetDir) {
113
154
  return result;
114
155
  }
115
156
  await fsp.mkdir(targetDir, { recursive: true });
116
- const entries = await fsp.readdir(bundledDir, { withFileTypes: true });
117
- for (const entry of entries) {
118
- if (!entry.isDirectory())
119
- continue;
120
- if (entry.name.startsWith("."))
121
- continue;
122
- const sourcePath = path.join(bundledDir, entry.name);
123
- const targetPath = path.join(targetDir, entry.name);
124
- // Check if SKILL.md exists
125
- if (!fs.existsSync(path.join(sourcePath, "SKILL.md")))
126
- continue;
127
- try {
128
- // Check if already exists
129
- if (fs.existsSync(targetPath)) {
130
- result.skipped.push(entry.name);
157
+ const bundledRoots = resolveSkillRootDirs(bundledDir);
158
+ for (const root of bundledRoots) {
159
+ const entries = await fsp.readdir(root, { withFileTypes: true });
160
+ for (const entry of entries) {
161
+ if (!entry.isDirectory())
131
162
  continue;
163
+ if (entry.name.startsWith("."))
164
+ continue;
165
+ const sourcePath = path.join(root, entry.name);
166
+ const skillPath = path.join(sourcePath, "SKILL.md");
167
+ if (!fs.existsSync(skillPath))
168
+ continue;
169
+ let targetBase = targetDir;
170
+ if (root !== bundledDir) {
171
+ targetBase = path.join(targetDir, path.basename(root));
172
+ }
173
+ else {
174
+ try {
175
+ const content = await fsp.readFile(skillPath, "utf-8");
176
+ const frontmatter = parseSkillFrontmatter(content);
177
+ const type = resolveSkillType(frontmatter);
178
+ if (type) {
179
+ targetBase = path.join(targetDir, `${type}s`);
180
+ }
181
+ }
182
+ catch {
183
+ // keep default targetBase
184
+ }
185
+ }
186
+ const targetPath = path.join(targetBase, entry.name);
187
+ try {
188
+ await fsp.mkdir(targetBase, { recursive: true });
189
+ if (fs.existsSync(targetPath)) {
190
+ result.skipped.push(entry.name);
191
+ continue;
192
+ }
193
+ await fsp.cp(sourcePath, targetPath, { recursive: true });
194
+ result.copied.push(entry.name);
195
+ }
196
+ catch (err) {
197
+ result.errors.push(`${entry.name}: ${err instanceof Error ? err.message : String(err)}`);
132
198
  }
133
- // Copy recursively
134
- await fsp.cp(sourcePath, targetPath, { recursive: true });
135
- result.copied.push(entry.name);
136
- }
137
- catch (err) {
138
- result.errors.push(`${entry.name}: ${err instanceof Error ? err.message : String(err)}`);
139
199
  }
140
200
  }
141
201
  return result;
@@ -145,17 +205,17 @@ export async function copyBundledSkills(targetDir) {
145
205
  */
146
206
  export async function generateSkillManifest(skillsDir, userSkillsDir) {
147
207
  // Skills in ~/nexus/skills/ are considered "bundled" (copied from package)
148
- // Skills user installs via NexusHub go in a managed/ subfolder or directly
208
+ // Managed skills live under ~/nexus/skills/managed/
149
209
  // User skills are in ~/nexus/home/skills/
150
- const bundledSkills = await scanSkillsDir(skillsDir, "bundled");
210
+ const bundledSkills = await scanSkillRoots(skillsDir, "bundled");
151
211
  // Check for managed subfolder (NexusHub installs)
152
212
  const managedDir = path.join(skillsDir, "managed");
153
213
  const managedSkills = fs.existsSync(managedDir)
154
- ? await scanSkillsDir(managedDir, "managed")
214
+ ? await scanSkillRoots(managedDir, "managed")
155
215
  : {};
156
216
  // User skills from workspace
157
217
  const userSkills = userSkillsDir
158
- ? await scanSkillsDir(userSkillsDir, "user")
218
+ ? await scanSkillRoots(userSkillsDir, "user")
159
219
  : {};
160
220
  return {
161
221
  version: 1,
@@ -178,7 +238,7 @@ export async function generateSkillManifest(skillsDir, userSkillsDir) {
178
238
  * Get the path to the skills manifest file
179
239
  */
180
240
  export function getSkillManifestPath() {
181
- return path.join(resolveStateDir(), "nexus", "skills", "manifest.json");
241
+ return path.join(SKILLS_STATE_DIR, "manifest.json");
182
242
  }
183
243
  /**
184
244
  * Write the skill manifest to disk