@mycadet/assistant 0.12.7 → 0.12.9

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 (904) hide show
  1. package/README.md +1 -1
  2. package/docs/activation-funnel-telemetry.md +6 -6
  3. package/docs/cadet-doctor.md +7 -7
  4. package/docs/desktop-browser-cli.md +7 -7
  5. package/docs/skills.md +2 -2
  6. package/docs/voice-input-diagnostics.md +1 -1
  7. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +2 -2
  8. package/node_modules/@mycadet/avatar-manifest/src/__tests__/notification-avatar.test.ts +1 -1
  9. package/node_modules/@mycadet/avatar-manifest/src/notification-avatar.ts +2 -2
  10. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/package.json +2 -2
  11. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/{platform-credential.ts → cloud-credential.ts} +9 -9
  12. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
  13. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
  14. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
  15. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
  16. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
  17. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
  18. package/node_modules/@mycadet/ces-client/package.json +1 -1
  19. package/node_modules/@mycadet/ces-client/src/__tests__/ces-client.test.ts +14 -14
  20. package/node_modules/@mycadet/ces-client/src/rpc-client.ts +1 -1
  21. package/node_modules/@mycadet/credential-storage/src/oauth-runtime.ts +1 -1
  22. package/node_modules/@mycadet/credential-storage/src/static-credentials.ts +1 -1
  23. package/node_modules/@mycadet/environments/src/seeds.ts +6 -6
  24. package/node_modules/@mycadet/environments/src/shell.test.ts +1 -1
  25. package/node_modules/@mycadet/environments/src/types.ts +6 -6
  26. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/package.json +2 -2
  27. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/{platform-credential.ts → cloud-credential.ts} +9 -9
  28. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
  29. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
  30. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
  31. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
  32. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
  33. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
  34. package/node_modules/@mycadet/gateway-client/src/binding-strength-contract.ts +5 -5
  35. package/node_modules/@mycadet/gateway-client/src/gateway-ipc-contracts.ts +1 -1
  36. package/node_modules/@mycadet/gateway-client/src/inbound-contract.ts +2 -2
  37. package/node_modules/@mycadet/gateway-client/src/outbound-contract.ts +1 -1
  38. package/node_modules/@mycadet/service-contracts/package.json +2 -2
  39. package/node_modules/@mycadet/service-contracts/src/{platform-credential.ts → cloud-credential.ts} +9 -9
  40. package/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
  41. package/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
  42. package/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
  43. package/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
  44. package/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
  45. package/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
  46. package/openapi.yaml +6804 -799
  47. package/package.json +2 -2
  48. package/scripts/build-test-fixtures.ts +1 -1
  49. package/scripts/probe-skill-retrieval.ts +1 -1
  50. package/scripts/sync-llm-catalog.ts +2 -2
  51. package/scripts/voice-ttft-spike.ts +2 -2
  52. package/src/__tests__/adaptive-thinking-repair.test.ts +4 -4
  53. package/src/__tests__/agent-loop-override-profile.test.ts +4 -4
  54. package/src/__tests__/agent-loop-subagent-billing-headers.test.ts +1 -1
  55. package/src/__tests__/anthropic-provider.test.ts +2 -2
  56. package/src/__tests__/available-skills.test.ts +11 -12
  57. package/src/__tests__/avatar-identity-sync.test.ts +1 -1
  58. package/src/__tests__/byok-default-profile-ensure.test.ts +7 -7
  59. package/src/__tests__/call-domain.test.ts +1 -1
  60. package/src/__tests__/call-site-routing-connection-auto-resolve.test.ts +2 -2
  61. package/src/__tests__/catalog-files.test.ts +10 -10
  62. package/src/__tests__/catalog-install-normalize.test.ts +3 -3
  63. package/src/__tests__/channel-availability-routes.test.ts +8 -8
  64. package/src/__tests__/channel-readiness-routes.test.ts +4 -4
  65. package/src/__tests__/channel-readiness-service.test.ts +14 -14
  66. package/src/__tests__/channel-readiness-telegram-remote.test.ts +1 -1
  67. package/src/__tests__/chat-reveal-guard-priming.test.ts +5 -6
  68. package/src/__tests__/checker.test.ts +6 -6
  69. package/src/__tests__/clawhub.test.ts +1 -1
  70. package/src/__tests__/{platform-callback-registration.test.ts → cloud-callback-registration.test.ts} +66 -90
  71. package/src/__tests__/{platform-client-verify-credential.test.ts → cloud-client-verify-credential.test.ts} +14 -14
  72. package/src/__tests__/{managed-credential-catalog-cli.test.ts → cloud-credential-catalog-cli.test.ts} +41 -41
  73. package/src/__tests__/{managed-fallback-dispatch.test.ts → cloud-fallback-dispatch.test.ts} +21 -16
  74. package/src/__tests__/{managed-profile-guard.test.ts → cloud-profile-guard.test.ts} +77 -75
  75. package/src/__tests__/{platform-proxy-context.test.ts → cloud-proxy-context.test.ts} +44 -44
  76. package/src/__tests__/{managed-speech-defaults.test.ts → cloud-speech-defaults.test.ts} +41 -41
  77. package/src/__tests__/{managed-store.test.ts → cloud-store.test.ts} +99 -99
  78. package/src/__tests__/compaction-events.test.ts +7 -5
  79. package/src/__tests__/config-loader-backfill.test.ts +65 -65
  80. package/src/__tests__/config-loader-cloud-defaults.test.ts +373 -0
  81. package/src/__tests__/config-loader-corrupt.test.ts +1 -1
  82. package/src/__tests__/config-loader-validation-reset-notice.test.ts +1 -1
  83. package/src/__tests__/config-schema.test.ts +3 -3
  84. package/src/__tests__/{config-set-platform-guard.test.ts → config-set-cloud-guard.test.ts} +6 -6
  85. package/src/__tests__/config-set-route.test.ts +12 -8
  86. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -8
  87. package/src/__tests__/config-watcher.test.ts +1 -1
  88. package/src/__tests__/contacts-write.test.ts +1 -1
  89. package/src/__tests__/conversation-agent-loop.test.ts +2 -2
  90. package/src/__tests__/conversation-app-control-instantiation.test.ts +18 -18
  91. package/src/__tests__/conversation-error.test.ts +45 -45
  92. package/src/__tests__/conversation-inference-profile-route.test.ts +4 -4
  93. package/src/__tests__/conversation-rendered-delegation-state.test.ts +4 -4
  94. package/src/__tests__/conversation-skill-tools.test.ts +7 -8
  95. package/src/__tests__/conversation-slash.test.ts +2 -2
  96. package/src/__tests__/conversation-speed-override.test.ts +8 -10
  97. package/src/__tests__/conversation-summarize-up-to.test.ts +4 -4
  98. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +1 -1
  99. package/src/__tests__/conversation-wait-for-idle.test.ts +7 -5
  100. package/src/__tests__/credential-execution-api-key-propagation.test.ts +5 -5
  101. package/src/__tests__/{credential-execution-managed-contract.test.ts → credential-execution-cloud-contract.test.ts} +24 -24
  102. package/src/__tests__/credential-health-service.test.ts +28 -40
  103. package/src/__tests__/credential-routes.test.ts +85 -165
  104. package/src/__tests__/credential-security-invariants.test.ts +6 -7
  105. package/src/__tests__/custom-profile-ensure.test.ts +1 -1
  106. package/src/__tests__/date-context.test.ts +1 -1
  107. package/src/__tests__/default-profile-catalog-fallback.test.ts +15 -15
  108. package/src/__tests__/delete-managed-skill-tool.test.ts +8 -8
  109. package/src/__tests__/discord-callback-round-trip.test.ts +1 -1
  110. package/src/__tests__/disk-usage.test.ts +3 -3
  111. package/src/__tests__/email-invite-adapter.test.ts +5 -5
  112. package/src/__tests__/{embedding-managed-proxy-selection.test.ts → embedding-cloud-proxy-selection.test.ts} +44 -43
  113. package/src/__tests__/emit-signal-routing-intent.test.ts +13 -15
  114. package/src/__tests__/events-dev-bypass-actor.test.ts +2 -2
  115. package/src/__tests__/fallback-breaker.test.ts +7 -7
  116. package/src/__tests__/feature-flag-test-helpers.ts +106 -0
  117. package/src/__tests__/gateway-flag-listener.test.ts +1 -1
  118. package/src/__tests__/gemini-image-service.test.ts +2 -2
  119. package/src/__tests__/gemini-provider.test.ts +5 -5
  120. package/src/__tests__/get-skill-detail-audit.test.ts +134 -288
  121. package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
  122. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +5 -5
  123. package/src/__tests__/host-cu-routes-targeted.test.ts +8 -8
  124. package/src/__tests__/image-credentials.test.ts +13 -13
  125. package/src/__tests__/inbound-admitted-introduction-nudge.test.ts +14 -6
  126. package/src/__tests__/inbound-trust-verdict.test.ts +14 -6
  127. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +11 -11
  128. package/src/__tests__/inference-profile-session-handler.test.ts +7 -7
  129. package/src/__tests__/inference-profile-session-ipc.test.ts +5 -5
  130. package/src/__tests__/inference-profile-validation-jev.test.ts +1 -1
  131. package/src/__tests__/init-feature-flag-overrides.test.ts +40 -24
  132. package/src/__tests__/input-repairs.test.ts +1 -1
  133. package/src/__tests__/install-skill-routing.test.ts +10 -8
  134. package/src/__tests__/integration-status.test.ts +5 -5
  135. package/src/__tests__/internal-telemetry-routes.test.ts +3 -3
  136. package/src/__tests__/invite-routes-http.test.ts +1 -1
  137. package/src/__tests__/llm-catalog-parity.test.ts +5 -7
  138. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +2 -2
  139. package/src/__tests__/llm-resolver-override-or-default.test.ts +3 -3
  140. package/src/__tests__/llm-resolver.test.ts +1 -1
  141. package/src/__tests__/llm-schema-fallback-profile.test.ts +25 -19
  142. package/src/__tests__/llm-usage-store.test.ts +1 -1
  143. package/src/__tests__/managed-skill-lifecycle.test.ts +12 -12
  144. package/src/__tests__/mcp-abort-signal.test.ts +1 -2
  145. package/src/__tests__/mcp-client-auth.test.ts +1 -2
  146. package/src/__tests__/mcp-config-secret-boundary.test.ts +44 -40
  147. package/src/__tests__/mcp-tool-annotations-risk.test.ts +1 -2
  148. package/src/__tests__/media-generate-image.test.ts +30 -30
  149. package/src/__tests__/memory-config-file-parity.test.ts +6 -6
  150. package/src/__tests__/migration-export-to-gcs.test.ts +4 -4
  151. package/src/__tests__/migration-import-commit-http.test.ts +1 -1
  152. package/src/__tests__/mtime-cache.test.ts +2 -2
  153. package/src/__tests__/{notification-platform-adapter.test.ts → notification-cloud-adapter.test.ts} +39 -39
  154. package/src/__tests__/notification-deep-link.test.ts +40 -40
  155. package/src/__tests__/oauth-apps-routes.test.ts +3 -3
  156. package/src/__tests__/oauth-cli.test.ts +9 -9
  157. package/src/__tests__/oauth-commands-routes.test.ts +16 -16
  158. package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -2
  159. package/src/__tests__/oauth-provider-serializer.test.ts +11 -11
  160. package/src/__tests__/oauth-providers-routes.test.ts +12 -12
  161. package/src/__tests__/oauth-store.test.ts +1 -1
  162. package/src/__tests__/oauth2-gateway-transport.test.ts +3 -3
  163. package/src/__tests__/onboarding-persona-write.test.ts +2 -2
  164. package/src/__tests__/openai-image-service.test.ts +2 -2
  165. package/src/__tests__/openai-responses-cutover-guard.test.ts +2 -2
  166. package/src/__tests__/openai-responses-provider.test.ts +1 -1
  167. package/src/__tests__/path-policy.test.ts +4 -4
  168. package/src/__tests__/personal-memory-auth-bypass.test.ts +1 -1
  169. package/src/__tests__/platform-bash-auto-approve.test.ts +18 -18
  170. package/src/__tests__/plugin-api-model-profiles.test.ts +1 -1
  171. package/src/__tests__/plugin-api-provider.test.ts +1 -1
  172. package/src/__tests__/plugin-api-store-credential.test.ts +4 -1
  173. package/src/__tests__/plugin-api-webhook-url.test.ts +4 -5
  174. package/src/__tests__/plugin-import-boundary-guard.test.ts +8 -39
  175. package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +2 -2
  176. package/src/__tests__/{provider-platform-proxy-integration.test.ts → provider-cloud-proxy-integration.test.ts} +70 -72
  177. package/src/__tests__/provider-commit-message-generator.test.ts +1 -1
  178. package/src/__tests__/provider-connections-backfill.test.ts +9 -9
  179. package/src/__tests__/provider-error-scenarios.test.ts +8 -8
  180. package/src/__tests__/provider-registry-ollama.test.ts +1 -1
  181. package/src/__tests__/provider-send-message-override-profile.test.ts +5 -5
  182. package/src/__tests__/registry.test.ts +3 -3
  183. package/src/__tests__/requests-mock.ts +972 -0
  184. package/src/__tests__/resolve-trust-class.test.ts +1 -1
  185. package/src/__tests__/resource-pressure-guard.test.ts +6 -6
  186. package/src/__tests__/resource-pressure-routes.test.ts +5 -5
  187. package/src/__tests__/retry-fallback-escalation.test.ts +5 -5
  188. package/src/__tests__/sanitize-config-for-transfer.test.ts +1 -1
  189. package/src/__tests__/scaffold-managed-skill-tool.test.ts +97 -97
  190. package/src/__tests__/schedule-store.test.ts +1 -1
  191. package/src/__tests__/search-skills-unified.test.ts +9 -7
  192. package/src/__tests__/{secret-routes-platform-proxy.test.ts → secret-routes-cloud-proxy.test.ts} +48 -95
  193. package/src/__tests__/secret-routes-scrub.test.ts +2 -59
  194. package/src/__tests__/secure-keys.test.ts +1 -1
  195. package/src/__tests__/skill-load-plugin-scope.test.ts +2 -2
  196. package/src/__tests__/skill-load-tool.test.ts +1 -1
  197. package/src/__tests__/skill-projection-feature-flag.test.ts +0 -19
  198. package/src/__tests__/skill-projection.benchmark.test.ts +5 -7
  199. package/src/__tests__/skill-tool-factory.test.ts +1 -1
  200. package/src/__tests__/skills-file-content-endpoint.test.ts +222 -536
  201. package/src/__tests__/skills-files-catalog-fallback.test.ts +259 -577
  202. package/src/__tests__/skills.test.ts +1 -1
  203. package/src/__tests__/slim-skill-category.test.ts +11 -9
  204. package/src/__tests__/stt-stream-session.test.ts +3 -3
  205. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  206. package/src/__tests__/subagent-disposal.test.ts +5 -5
  207. package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
  208. package/src/__tests__/subagent-fork-spawn.test.ts +5 -5
  209. package/src/__tests__/subagent-manager-notify.test.ts +5 -5
  210. package/src/__tests__/subagent-tool-gate-mode.test.ts +2 -2
  211. package/src/__tests__/system-prompt.test.ts +1 -1
  212. package/src/__tests__/telegram-bot-username-resolution.test.ts +34 -52
  213. package/src/__tests__/telegram-config.test.ts +16 -16
  214. package/src/__tests__/telephony-tts-guard.test.ts +13 -13
  215. package/src/__tests__/test-preload.ts +17 -7
  216. package/src/__tests__/tool-audit.test.ts +1 -1
  217. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -5
  218. package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
  219. package/src/__tests__/turn-events-store.test.ts +1 -1
  220. package/src/__tests__/twilio-routes.test.ts +2 -1
  221. package/src/__tests__/ui-choice-copy-surfaces.test.ts +1 -1
  222. package/src/__tests__/unified-turn-context-client-os.test.ts +1 -1
  223. package/src/__tests__/validate-input.test.ts +5 -5
  224. package/src/__tests__/verification-outbound-delivery.test.ts +1 -1
  225. package/src/__tests__/voice-config-update.test.ts +15 -15
  226. package/src/__tests__/voice-ingress-preflight.test.ts +4 -4
  227. package/src/__tests__/web-search.test.ts +340 -859
  228. package/src/__tests__/workspace-git-service.test.ts +1 -1
  229. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +12 -12
  230. package/src/__tests__/workspace-migration-087-memory-router-balanced-profile.test.ts +1 -1
  231. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +1 -1
  232. package/src/__tests__/workspace-migration-100-upgrade-quality-profile-to-fable-5.test.ts +1 -1
  233. package/src/__tests__/workspace-migration-103-upgrade-quality-profile-to-opus-4-8.test.ts +1 -1
  234. package/src/__tests__/workspace-migration-110-flip-balanced-profile-to-together.test.ts +1 -1
  235. package/src/__tests__/workspace-migration-113-swap-balanced-profile-to-glm-5p2.test.ts +1 -1
  236. package/src/__tests__/workspace-migration-114-swap-quality-profile-to-opus.test.ts +1 -1
  237. package/src/__tests__/workspace-migration-123-swap-quality-profile-to-fable.test.ts +1 -1
  238. package/src/__tests__/workspace-migration-125-repoint-managed-connections-to-cadet.test.ts +3 -3
  239. package/src/__tests__/workspace-migration-126-strip-managed-profile-bodies.test.ts +9 -9
  240. package/src/__tests__/workspace-migration-127-backfill-default-provider.test.ts +11 -11
  241. package/src/__tests__/workspace-migration-130-speech-mode-to-provider.test.ts +3 -3
  242. package/src/__tests__/workspace-migration-132-web-search-mode-to-provider.test.ts +6 -6
  243. package/src/__tests__/workspace-migration-133-collapse-provider-connections.test.ts +3 -3
  244. package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +6 -6
  245. package/src/__tests__/workspace-migration-136-repair-stale-fireworks-kimi-model-id.test.ts +1 -1
  246. package/src/__tests__/workspace-migration-137-repair-retired-fireworks-minimax-model-id.test.ts +1 -1
  247. package/src/__tests__/workspace-migration-146-repair-retired-fireworks-deepseek-flash-model-id.test.ts +1 -1
  248. package/src/__tests__/workspace-migration-147-rename-colliding-backup-profile-names.test.ts +1 -1
  249. package/src/__tests__/workspace-migration-151-repair-renamed-fireworks-deepseek-pro-model-id.test.ts +1 -1
  250. package/src/__tests__/workspace-migration-152-repair-retired-fireworks-minimax-m2p7-model-id.test.ts +1 -1
  251. package/src/__tests__/workspace-migration-159-rename-colliding-jev-profile-name.test.ts +1 -1
  252. package/src/__tests__/workspace-migration-160-repair-retired-fireworks-model-ids.test.ts +1 -1
  253. package/src/__tests__/workspace-migration-161-repair-retired-fireworks-glm-5p2-model-id.test.ts +1 -1
  254. package/src/api/events/cloud-disconnected.ts +21 -0
  255. package/src/api/events/host-bash.ts +1 -1
  256. package/src/api/events/host-cu.ts +1 -1
  257. package/src/api/events/host-file.ts +1 -1
  258. package/src/api/events/notification-intent.ts +1 -1
  259. package/src/api/events/show-cloud-login.ts +18 -0
  260. package/src/api/index.ts +11 -11
  261. package/src/api/responses/home.ts +1 -1
  262. package/src/api/surfaces.ts +4 -4
  263. package/src/approvals/guardian-request-resolvers.ts +2 -2
  264. package/src/avatar/accent-backfill.ts +1 -1
  265. package/src/avatar/identity-avatar.ts +1 -1
  266. package/src/avatar/notification-avatar.test.ts +2 -2
  267. package/src/avatar/notification-avatar.ts +2 -2
  268. package/src/avatar/resvg-lazy.test.ts +1 -1
  269. package/src/avatar/resvg-lazy.ts +3 -3
  270. package/src/avatar/sync-avatar.test.ts +76 -76
  271. package/src/avatar/sync-avatar.ts +15 -15
  272. package/src/avatar/traits-png-sync.ts +1 -1
  273. package/src/background-wake/background-wake-routes.test.ts +39 -39
  274. package/src/background-wake/{platform-client.test.ts → cloud-client.test.ts} +11 -11
  275. package/src/background-wake/{platform-client.ts → cloud-client.ts} +14 -14
  276. package/src/background-wake/publisher.ts +4 -4
  277. package/src/background-wake/wake-intent-hooks.test.ts +3 -3
  278. package/src/calls/__tests__/call-controller.test.ts +2 -2
  279. package/src/calls/__tests__/voice-session-bridge.test.ts +1 -1
  280. package/src/calls/call-domain.ts +1 -1
  281. package/src/calls/resolve-call-tts-provider.ts +6 -6
  282. package/src/calls/telephony-credential-preflight.ts +3 -3
  283. package/src/calls/telephony-tts-capability.ts +5 -6
  284. package/src/calls/tts-call-strategy.ts +1 -1
  285. package/src/calls/voice-escalation-judge.ts +1 -1
  286. package/src/calls/voice-ingress-preflight.ts +4 -4
  287. package/src/cli/bundled-modules.ts +1 -1
  288. package/src/cli/commands/__tests__/apps.test.ts +18 -53
  289. package/src/cli/commands/__tests__/plugins.test.ts +13 -13
  290. package/src/cli/commands/__tests__/tts.test.ts +1 -1
  291. package/src/cli/commands/auth.help.ts +3 -3
  292. package/src/cli/commands/auth.ts +2 -4
  293. package/src/cli/commands/browser.help.ts +2 -2
  294. package/src/cli/commands/channels/index.help.ts +2 -2
  295. package/src/cli/commands/channels/index.ts +1 -1
  296. package/src/cli/commands/channels/send.ts +1 -1
  297. package/src/cli/commands/cloud/__tests__/callback-routes-list.test.ts +2 -2
  298. package/src/cli/commands/cloud/__tests__/connect.test.ts +1 -1
  299. package/src/cli/commands/cloud/__tests__/disconnect.test.ts +3 -4
  300. package/src/cli/commands/cloud/connect.ts +2 -2
  301. package/src/cli/commands/cloud/credits-format.ts +1 -1
  302. package/src/cli/commands/cloud/index.help.ts +35 -35
  303. package/src/cli/commands/cloud/index.ts +1 -1
  304. package/src/cli/commands/config.ts +2 -2
  305. package/src/cli/commands/credentials.ts +10 -12
  306. package/src/cli/commands/domain.ts +1 -1
  307. package/src/cli/commands/email.help.ts +1 -1
  308. package/src/cli/commands/email.ts +2 -2
  309. package/src/cli/commands/gateway.help.ts +1 -1
  310. package/src/cli/commands/gateway.ts +1 -1
  311. package/src/cli/commands/image-generation.help.ts +1 -1
  312. package/src/cli/commands/inference-providers.ts +1 -1
  313. package/src/cli/commands/inference.help.ts +2 -2
  314. package/src/cli/commands/memory/index.help.ts +1 -1
  315. package/src/cli/commands/oauth/connect.test.ts +2 -2
  316. package/src/cli/commands/oauth/connect.ts +1 -1
  317. package/src/cli/commands/oauth/index.help.ts +5 -5
  318. package/src/cli/commands/oauth/providers.ts +2 -2
  319. package/src/cli/commands/oauth/shared.ts +3 -3
  320. package/src/cli/commands/plugins.help.ts +2 -3
  321. package/src/cli/commands/plugins.ts +5 -5
  322. package/src/cli/commands/roadmap.help.ts +1 -1
  323. package/src/cli/commands/telemetry.help.ts +2 -2
  324. package/src/cli/commands/telemetry.ts +2 -2
  325. package/src/cli/commands/tts.help.ts +3 -3
  326. package/src/cli/commands/webhooks.help.ts +9 -9
  327. package/src/cli/commands/webhooks.ts +1 -1
  328. package/src/cli/lib/__tests__/inspect-plugin.test.ts +8 -8
  329. package/src/cli/lib/__tests__/{install-from-platform.test.ts → install-from-cloud.test.ts} +54 -54
  330. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +18 -18
  331. package/src/cli/lib/__tests__/{plugin-catalog-platform.test.ts → plugin-catalog-cloud.test.ts} +2 -2
  332. package/src/cli/lib/__tests__/plugin-catalog-local.test.ts +1 -1
  333. package/src/cli/lib/__tests__/plugin-catalog-resolve.test.ts +9 -9
  334. package/src/cli/lib/__tests__/plugin-details.test.ts +10 -10
  335. package/src/cli/lib/__tests__/plugins-install-offline.test.ts +24 -24
  336. package/src/cli/lib/bundled-marketplace.json +1 -1
  337. package/src/cli/lib/inspect-plugin.ts +2 -2
  338. package/src/cli/lib/{install-from-platform.ts → install-from-cloud.ts} +29 -29
  339. package/src/cli/lib/install-from-github.ts +4 -4
  340. package/src/cli/lib/plugin-catalog-cache.ts +7 -7
  341. package/src/cli/lib/{plugin-catalog-platform.ts → plugin-catalog-cloud.ts} +6 -6
  342. package/src/cli/lib/plugin-catalog-local.ts +2 -2
  343. package/src/cli/lib/publish-plugin.ts +9 -10
  344. package/src/cli/lib/search-plugins.ts +2 -2
  345. package/src/{platform → cloud}/client.test.ts +85 -86
  346. package/src/{platform → cloud}/client.ts +38 -46
  347. package/src/{platform/platform-patch-queue.test.ts → cloud/cloud-patch-queue.test.ts} +6 -9
  348. package/src/{platform/platform-patch-queue.ts → cloud/cloud-patch-queue.ts} +11 -11
  349. package/src/{platform/managed-speech.test.ts → cloud/cloud-speech.test.ts} +19 -19
  350. package/src/{platform/managed-speech.ts → cloud/cloud-speech.ts} +41 -41
  351. package/src/{platform → cloud}/consent-cache.test.ts +5 -5
  352. package/src/{platform → cloud}/consent-cache.ts +8 -8
  353. package/src/cloud/feature-gate.ts +8 -0
  354. package/src/{platform → cloud}/sync-identity.test.ts +4 -4
  355. package/src/{platform → cloud}/sync-identity.ts +6 -6
  356. package/src/config/__tests__/{platform-identity.test.ts → cloud-identity.test.ts} +54 -56
  357. package/src/config/__tests__/{platform-rehydration.test.ts → cloud-rehydration.test.ts} +47 -80
  358. package/src/config/__tests__/default-profile-catalog.test.ts +12 -12
  359. package/src/config/__tests__/default-provider.test.ts +4 -4
  360. package/src/config/__tests__/deployment-context-defaults.test.ts +23 -23
  361. package/src/config/__tests__/{jev-managed-profile.test.ts → jev-cloud-profile.test.ts} +3 -5
  362. package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +2 -2
  363. package/src/config/__tests__/loader-last-known-good.test.ts +6 -6
  364. package/src/config/__tests__/loader-sparse-array-cleanup.test.ts +2 -2
  365. package/src/config/__tests__/profile-materialization.test.ts +7 -7
  366. package/src/config/__tests__/seed-default-provider.test.ts +17 -17
  367. package/src/config/__tests__/substrate-twin-shadowing.test.ts +36 -26
  368. package/src/config/__tests__/sync-gated-profiles.test.ts +20 -20
  369. package/src/config/__tests__/webhook-routing.test.ts +51 -51
  370. package/src/config/bundled-skills/computer-use/TOOLS.json +12 -12
  371. package/src/config/bundled-skills/messaging/SKILL.md +8 -8
  372. package/src/config/bundled-skills/messaging/TOOLS.json +2 -2
  373. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +1 -1
  374. package/src/config/bundled-skills/messaging/tools/shared.ts +1 -1
  375. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +2 -2
  376. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  377. package/src/config/bundled-skills/settings/tools/shared.ts +1 -1
  378. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +12 -12
  379. package/src/config/bundled-skills/skill-management/SKILL.md +3 -3
  380. package/src/config/bundled-skills/skill-management/TOOLS.json +8 -8
  381. package/src/config/bundled-skills/skill-management/tools/{delete-managed.ts → delete-cloud.ts} +2 -2
  382. package/src/config/bundled-skills/skill-management/tools/{scaffold-managed.ts → scaffold-cloud.ts} +2 -2
  383. package/src/config/call-site-defaults.ts +6 -6
  384. package/src/config/{platform-identity.ts → cloud-identity.ts} +39 -42
  385. package/src/config/cloud-rehydration.ts +35 -0
  386. package/src/config/{managed-speech-defaults.ts → cloud-speech-defaults.ts} +13 -13
  387. package/src/config/default-profile-catalog.ts +36 -38
  388. package/src/config/default-profile-names.ts +11 -11
  389. package/src/config/default-provider-resolution.ts +2 -2
  390. package/src/config/default-provider.ts +1 -1
  391. package/src/config/env-registry.ts +21 -26
  392. package/src/config/env.ts +33 -46
  393. package/src/config/feature-flag-registry.json +5 -5
  394. package/src/config/inference-profile-validation.ts +1 -1
  395. package/src/config/llm-resolver.ts +9 -10
  396. package/src/config/loader.ts +33 -17
  397. package/src/config/profile-materialization.ts +8 -8
  398. package/src/config/profile-text-generation.test.ts +1 -1
  399. package/src/config/sanitize-for-transfer.ts +1 -1
  400. package/src/config/schema.ts +6 -6
  401. package/src/config/schemas/__tests__/stt.test.ts +2 -2
  402. package/src/config/schemas/call-site-catalog.ts +1 -1
  403. package/src/config/schemas/channels.ts +8 -0
  404. package/src/config/schemas/{platform.ts → cloud.ts} +7 -6
  405. package/src/config/schemas/host-browser.ts +1 -0
  406. package/src/config/schemas/ingress.ts +29 -10
  407. package/src/config/schemas/llm.ts +36 -36
  408. package/src/config/schemas/memory-lifecycle.ts +11 -1
  409. package/src/config/schemas/services.ts +4 -4
  410. package/src/config/schemas/stt.ts +3 -3
  411. package/src/config/schemas/tts.ts +10 -5
  412. package/src/config/schemas/voice.ts +1 -1
  413. package/src/config/seed-inference-profiles.ts +19 -19
  414. package/src/config/skill-state.ts +2 -2
  415. package/src/config/skills.ts +4 -4
  416. package/src/config/substrate-twin-shadowing.ts +12 -17
  417. package/src/config/sync-gated-profiles.ts +8 -9
  418. package/src/config/webhook-routing.ts +19 -19
  419. package/src/contacts/contacts-write.ts +1 -1
  420. package/src/credential-execution/ces-runtime.ts +6 -6
  421. package/src/credential-execution/{managed-catalog.ts → cloud-catalog.ts} +24 -24
  422. package/src/credential-execution/prompted-credential.ts +2 -23
  423. package/src/credential-health/credential-health-service.ts +59 -70
  424. package/src/daemon/__tests__/can-spawn-subagents.test.ts +1 -1
  425. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +4 -4
  426. package/src/daemon/config-watcher.ts +2 -2
  427. package/src/daemon/conversation-agent-loop.ts +9 -9
  428. package/src/daemon/conversation-error.ts +36 -36
  429. package/src/daemon/conversation-skill-tools.ts +7 -7
  430. package/src/daemon/conversation-surfaces.ts +1 -1
  431. package/src/daemon/conversation-tool-setup.ts +2 -2
  432. package/src/daemon/conversation-turn-finalize.ts +1 -1
  433. package/src/daemon/conversation-workspace.ts +1 -1
  434. package/src/daemon/conversation.ts +1 -1
  435. package/src/daemon/credential-transcript-scrub.ts +32 -35
  436. package/src/daemon/daemon-readiness.ts +1 -1
  437. package/src/daemon/event-loop-watchdog.ts +2 -2
  438. package/src/daemon/handlers/config-ingress.ts +9 -9
  439. package/src/daemon/handlers/config-telegram.ts +6 -6
  440. package/src/daemon/handlers/skills.ts +20 -20
  441. package/src/daemon/host-cu-proxy.ts +1 -1
  442. package/src/daemon/lifecycle.ts +19 -19
  443. package/src/daemon/parse-actual-tokens-from-error.ts +3 -3
  444. package/src/daemon/providers-setup.ts +6 -6
  445. package/src/daemon/resource-pressure-guard-lifecycle.ts +1 -1
  446. package/src/daemon/resource-pressure-guard.ts +6 -6
  447. package/src/daemon/shutdown-handlers.ts +1 -1
  448. package/src/daemon/sqlite-corruption-watchdog.ts +3 -3
  449. package/src/daemon/trust-context.ts +1 -1
  450. package/src/desktop/desktop-automation-lease.ts +1 -1
  451. package/src/desktop/desktop-browser-endpoint.ts +2 -4
  452. package/src/desktop/desktop-computer-use-routing.test.ts +6 -6
  453. package/src/desktop/desktop-stream-bridge.test.ts +4 -4
  454. package/src/desktop/desktop-stream-bridge.ts +1 -1
  455. package/src/desktop/{virtual-desktop-platform.test.ts → virtual-desktop-cloud.test.ts} +6 -6
  456. package/src/desktop/virtual-desktop-feature.ts +7 -7
  457. package/src/email/byo-email-credential.ts +1 -1
  458. package/src/email/registered-inbox.test.ts +16 -16
  459. package/src/email/registered-inbox.ts +20 -20
  460. package/src/heartbeat/heartbeat-service.ts +1 -1
  461. package/src/hooks/hook-loader.ts +2 -2
  462. package/src/inbound/__tests__/oauth-callback-url.test.ts +2 -2
  463. package/src/inbound/__tests__/tunnel-probe.test.ts +8 -8
  464. package/src/inbound/{platform-callback-registration.ts → cloud-callback-registration.ts} +49 -60
  465. package/src/inbound/oauth-callback-url.ts +6 -6
  466. package/src/inbound/pod-webhook-claim.ts +2 -2
  467. package/src/inbound/public-ingress-urls.ts +3 -3
  468. package/src/inbound/tunnel-probe.ts +21 -15
  469. package/src/inbound/tunnel-webhooks-gate.ts +3 -3
  470. package/src/ipc/__tests__/db-readiness-ipc-gate.test.ts +1 -1
  471. package/src/ipc/__tests__/email-ipc.test.ts +8 -8
  472. package/src/ipc/gateway-client.test.ts +55 -59
  473. package/src/ipc/gateway-flag-listener.ts +3 -3
  474. package/src/ipc/routes/db-proxy.ts +1 -1
  475. package/src/live-voice/__tests__/live-activity-reporter.test.ts +2 -2
  476. package/src/live-voice/__tests__/{live-voice-managed-speech-fallback.test.ts → live-voice-cloud-speech-fallback.test.ts} +15 -15
  477. package/src/live-voice/__tests__/live-voice-credential-preflight.test.ts +7 -7
  478. package/src/live-voice/__tests__/live-voice-stt.test.ts +1 -1
  479. package/src/live-voice/live-activity-reporter.ts +7 -7
  480. package/src/live-voice/live-voice-credential-preflight.ts +6 -6
  481. package/src/live-voice/live-voice-session.ts +3 -3
  482. package/src/live-voice/live-voice-tts.ts +1 -1
  483. package/src/mcp/__tests__/mcp-oauth-client-registration.test.ts +4 -4
  484. package/src/mcp/__tests__/mcp-oauth-provider.test.ts +1 -1
  485. package/src/mcp/mcp-oauth-provider.ts +2 -2
  486. package/src/media/gemini-image-service.ts +11 -13
  487. package/src/media/image-credentials.ts +9 -9
  488. package/src/media/openai-image-service.ts +1 -1
  489. package/src/media/types.ts +3 -3
  490. package/src/messaging/providers/channel-transport.ts +1 -1
  491. package/src/messaging/providers/discord/transport.ts +1 -1
  492. package/src/messaging/providers/gmail/adapter.ts +1 -1
  493. package/src/messaging/providers/gmail/client.ts +4 -4
  494. package/src/messaging/providers/outlook/adapter.ts +1 -1
  495. package/src/messaging/providers/slack/adapter.ts +1 -1
  496. package/src/messaging/providers/slack/transport.ts +1 -1
  497. package/src/messaging/providers/telegram-bot/transport.ts +1 -1
  498. package/src/monitoring/db-integrity-check.ts +1 -1
  499. package/src/monitoring/db-integrity-sample.ts +2 -2
  500. package/src/monitoring/mount-watch.ts +1 -1
  501. package/src/monitoring/oom-kill-reporter.ts +1 -1
  502. package/src/monitoring/worker.ts +5 -5
  503. package/src/notifications/README.md +2 -2
  504. package/src/notifications/__tests__/broadcaster.test.ts +9 -9
  505. package/src/notifications/__tests__/completion-policy.test.ts +1 -1
  506. package/src/notifications/__tests__/emit-signal-pipeline-failure.test.ts +4 -4
  507. package/src/notifications/activity-failed-dedupe.ts +1 -1
  508. package/src/notifications/adapters/{platform.ts → cloud.ts} +8 -8
  509. package/src/notifications/broadcaster.ts +10 -10
  510. package/src/notifications/decision-engine.ts +1 -1
  511. package/src/notifications/destination-resolver.ts +1 -1
  512. package/src/notifications/emit-signal.ts +6 -6
  513. package/src/notifications/types.ts +2 -2
  514. package/src/oauth/__tests__/identity-verifier.test.ts +1 -1
  515. package/src/oauth/__tests__/{seed-providers-managed.test.ts → seed-providers-cloud.test.ts} +13 -13
  516. package/src/oauth/byo-connection.test.ts +2 -2
  517. package/src/oauth/{platform-connection.test.ts → cloud-connection.test.ts} +41 -43
  518. package/src/oauth/{platform-connection.ts → cloud-connection.ts} +19 -19
  519. package/src/oauth/connection-resolver.test.ts +59 -61
  520. package/src/oauth/connection-resolver.ts +22 -22
  521. package/src/oauth/connection.ts +1 -1
  522. package/src/oauth/oauth-store.ts +8 -8
  523. package/src/oauth/provider-serializer.ts +4 -4
  524. package/src/oauth/revoke.ts +1 -1
  525. package/src/oauth/seed-providers.ts +32 -32
  526. package/src/permissions/approval-provenance.ts +1 -1
  527. package/src/permissions/checker.test.ts +18 -16
  528. package/src/permissions/checker.ts +3 -3
  529. package/src/persistence/compaction-log-store-clickhouse.ts +3 -3
  530. package/src/persistence/embeddings/embedding-backend.test.ts +16 -16
  531. package/src/persistence/embeddings/embedding-backend.ts +13 -13
  532. package/src/persistence/embeddings/embedding-gemini.test.ts +9 -12
  533. package/src/persistence/embeddings/embedding-gemini.ts +11 -11
  534. package/src/persistence/embeddings/embedding-runtime-manager.ts +2 -2
  535. package/src/persistence/jobs-store.ts +1 -1
  536. package/src/persistence/lifecycle-events-store.ts +1 -1
  537. package/src/persistence/llm-request-log-sink-clickhouse.ts +3 -3
  538. package/src/persistence/llm-request-log-source-clickhouse.ts +3 -3
  539. package/src/persistence/migrations/224-oauth-providers-managed-service-is-paid.ts +1 -1
  540. package/src/persistence/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +1 -1
  541. package/src/persistence/migrations/296-rewrite-balanced-economy-profile-pins.ts +2 -2
  542. package/src/persistence/migrations/306-rewrite-frontier-profile-pins.test.ts +1 -1
  543. package/src/persistence/migrations/306-rewrite-frontier-profile-pins.ts +1 -1
  544. package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +1 -1
  545. package/src/persistence/migrations/361-normalize-managed-connection-rows.test.ts +3 -3
  546. package/src/persistence/migrations/361-normalize-managed-connection-rows.ts +7 -7
  547. package/src/persistence/migrations/__tests__/319-remove-legacy-managed-connections.test.ts +2 -2
  548. package/src/persistence/schema/oauth.ts +1 -1
  549. package/src/plugin-api/index.ts +4 -4
  550. package/src/plugin-api/model-profiles.test.ts +1 -1
  551. package/src/plugin-api/model-profiles.ts +1 -1
  552. package/src/plugin-api/transcription-session.ts +1 -1
  553. package/src/plugin-api/vision-support.test.ts +1 -1
  554. package/src/plugin-api/webhook-url.ts +12 -12
  555. package/src/plugins/__tests__/source-fingerprint.test.ts +1 -1
  556. package/src/plugins/defaults/{platform-hosted → cloud-hosted}/__tests__/reengage.test.ts +5 -6
  557. package/src/plugins/defaults/cloud-hosted/package.json +14 -0
  558. package/src/plugins/defaults/{platform-hosted → cloud-hosted}/routes/reengage.ts +3 -3
  559. package/src/plugins/defaults/index.ts +6 -6
  560. package/src/plugins/defaults/main.ts +5 -5
  561. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +5 -5
  562. package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +1 -1
  563. package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +1 -1
  564. package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +5 -0
  565. package/src/plugins/defaults/memory/config.ts +4 -4
  566. package/src/plugins/defaults/memory/memory-retrospective-constants.ts +2 -2
  567. package/src/plugins/defaults/memory/memory-retrospective-job.ts +7 -7
  568. package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +5 -5
  569. package/src/plugins/defaults/memory/memory-retrospective-skill-card.ts +2 -2
  570. package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +1 -1
  571. package/src/plugins/defaults/memory/src/__tests__/memory-worker-routes.test.ts +1 -1
  572. package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +20 -20
  573. package/src/plugins/defaults/memory/substrate/__tests__/cli-command-store.test.ts +1 -1
  574. package/src/plugins/defaults/memory/substrate/__tests__/skill-store.test.ts +3 -3
  575. package/src/plugins/defaults/memory/substrate/boot-maintenance.ts +17 -17
  576. package/src/plugins/defaults/memory/substrate/cli-command-store.ts +2 -2
  577. package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +1 -1
  578. package/src/plugins/defaults/memory/substrate/skill-store.ts +4 -4
  579. package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +3 -3
  580. package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +2 -2
  581. package/src/plugins/defaults/memory/v3/maintain-job.ts +10 -10
  582. package/src/plugins/defaults/memory/v3/orchestrate.ts +3 -3
  583. package/src/plugins/defaults/memory/worker.ts +5 -5
  584. package/src/plugins/defaults/workspace/injectors.ts +2 -2
  585. package/src/plugins/mtime-cache.ts +1 -1
  586. package/src/plugins/source-versions.ts +1 -1
  587. package/src/plugins/types.ts +1 -1
  588. package/src/prompts/__tests__/system-prompt.test.ts +1 -1
  589. package/src/prompts/normalize-onboarding.ts +1 -1
  590. package/src/prompts/persona-resolver.ts +1 -1
  591. package/src/prompts/templates/system-sections.ts +3 -3
  592. package/src/providers/__tests__/cadet-connection-routing.test.ts +7 -7
  593. package/src/providers/__tests__/cadet-mismatch-routing.test.ts +12 -12
  594. package/src/providers/__tests__/connection-model-compat.test.ts +2 -2
  595. package/src/providers/__tests__/dispatch-connection-routing.test.ts +10 -10
  596. package/src/providers/__tests__/inference.test.ts +2 -2
  597. package/src/providers/__tests__/preflight-resolved-config.test.ts +16 -16
  598. package/src/providers/__tests__/retry-callsite.test.ts +1 -1
  599. package/src/providers/__tests__/satellite-connection-routing.test.ts +4 -4
  600. package/src/providers/__tests__/search-provider-catalog.test.ts +2 -2
  601. package/src/providers/__tests__/voice-error-copy.test.ts +3 -3
  602. package/src/providers/anthropic/client.ts +1 -1
  603. package/src/providers/cadet/client.ts +1 -1
  604. package/src/providers/cadet-model-routing.test.ts +19 -19
  605. package/src/providers/cadet-model-routing.ts +23 -23
  606. package/src/providers/call-site-routing.ts +10 -10
  607. package/src/providers/{platform-proxy → cloud-proxy}/constants.ts +11 -11
  608. package/src/providers/{platform-proxy → cloud-proxy}/context.ts +26 -26
  609. package/src/providers/connection-resolution.ts +43 -43
  610. package/src/providers/fallback-breaker.ts +2 -2
  611. package/src/providers/fetch-provider-catalog.ts +3 -3
  612. package/src/providers/gemini/client.ts +5 -5
  613. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +3 -3
  614. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +8 -8
  615. package/src/providers/inference/__tests__/base-url-security.test.ts +4 -4
  616. package/src/providers/inference/adapter-factory.ts +35 -35
  617. package/src/providers/inference/auth.ts +10 -10
  618. package/src/providers/inference/backfill.ts +11 -11
  619. package/src/providers/inference/connection-availability.ts +24 -24
  620. package/src/providers/inference/connections.ts +18 -20
  621. package/src/providers/inference/profile-probe.ts +4 -4
  622. package/src/providers/inference/resolve-auth.ts +8 -8
  623. package/src/providers/jev/ask.test.ts +1 -1
  624. package/src/providers/jev/ask.ts +2 -2
  625. package/src/providers/model-catalog.ts +8 -9
  626. package/src/providers/openai/__tests__/api-error-normalization.test.ts +3 -3
  627. package/src/providers/openai/api-error-normalization.ts +2 -2
  628. package/src/providers/provider-availability.ts +4 -4
  629. package/src/providers/provider-env-vars.ts +1 -1
  630. package/src/providers/provider-secret-catalog.ts +1 -1
  631. package/src/providers/registry.ts +20 -20
  632. package/src/providers/retry.ts +26 -26
  633. package/src/providers/routing-identity.ts +10 -10
  634. package/src/providers/search-provider-catalog.ts +2 -2
  635. package/src/providers/speech-to-text/__tests__/{cadet-managed-realtime.test.ts → cadet-cloud-realtime.test.ts} +3 -3
  636. package/src/providers/speech-to-text/__tests__/{cadet-managed.test.ts → cadet-cloud.test.ts} +35 -35
  637. package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +1 -1
  638. package/src/providers/speech-to-text/__tests__/resolve.test.ts +27 -27
  639. package/src/providers/speech-to-text/{cadet-managed-flux-realtime.ts → cadet-cloud-flux-realtime.ts} +6 -8
  640. package/src/providers/speech-to-text/{cadet-managed-realtime.ts → cadet-cloud-realtime.ts} +3 -3
  641. package/src/providers/speech-to-text/{cadet-managed.ts → cadet-cloud.ts} +18 -20
  642. package/src/providers/speech-to-text/cadet-speech-relay-connection.ts +7 -7
  643. package/src/providers/speech-to-text/deepgram-flux-frames.ts +3 -3
  644. package/src/providers/speech-to-text/deepgram-flux-realtime.ts +4 -4
  645. package/src/providers/speech-to-text/provider-catalog.ts +3 -3
  646. package/src/providers/speech-to-text/resolve.ts +26 -28
  647. package/src/providers/together/client.ts +1 -1
  648. package/src/providers/types.ts +4 -4
  649. package/src/providers/voice-error-copy.ts +1 -1
  650. package/src/runtime/__tests__/desktop-stream-upgrade.test.ts +10 -10
  651. package/src/runtime/agent-wake.ts +1 -1
  652. package/src/runtime/auth/__tests__/middleware.test.ts +1 -1
  653. package/src/runtime/auth/middleware.ts +1 -1
  654. package/src/runtime/auth/scopes.ts +1 -1
  655. package/src/runtime/capabilities.ts +1 -1
  656. package/src/runtime/channel-invite-transports/discord.ts +1 -1
  657. package/src/runtime/channel-invite-transports/email.ts +2 -2
  658. package/src/runtime/channel-readiness-service.ts +15 -13
  659. package/src/runtime/channel-reply-session.test.ts +1 -1
  660. package/src/runtime/channel-reply-session.ts +1 -1
  661. package/src/runtime/http-server.ts +4 -4
  662. package/src/runtime/introduction-policy.ts +4 -4
  663. package/src/runtime/migrations/__tests__/origin-mode.test.ts +14 -14
  664. package/src/runtime/migrations/__tests__/v1-test-helpers.ts +1 -1
  665. package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +2 -2
  666. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +3 -4
  667. package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +6 -7
  668. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +1 -1
  669. package/src/runtime/migrations/migration-transport.ts +3 -3
  670. package/src/runtime/migrations/origin-mode.ts +6 -9
  671. package/src/runtime/migrations/vbundle-import-policy.ts +2 -2
  672. package/src/runtime/migrations/vbundle-importer.ts +4 -4
  673. package/src/runtime/migrations/vbundle-streaming-importer.ts +6 -6
  674. package/src/runtime/migrations/vbundle-validator.ts +1 -1
  675. package/src/runtime/routes/__tests__/{platform-credits-routes.test.ts → cloud-credits-routes.test.ts} +9 -9
  676. package/src/runtime/routes/__tests__/{platform-invoice-routes.test.ts → cloud-invoice-routes.test.ts} +13 -13
  677. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +1 -1
  678. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +126 -82
  679. package/src/runtime/routes/__tests__/default-plugin-routes.test.ts +5 -5
  680. package/src/runtime/routes/__tests__/default-provider-routes.test.ts +10 -10
  681. package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +18 -18
  682. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +18 -16
  683. package/src/runtime/routes/__tests__/inference-send-routes.test.ts +1 -1
  684. package/src/runtime/routes/__tests__/ingress-status-routes.test.ts +1 -1
  685. package/src/runtime/routes/__tests__/migration-cadet-metadata-reconcile.test.ts +5 -20
  686. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -22
  687. package/src/runtime/routes/__tests__/oauth-proxy-routes.test.ts +27 -27
  688. package/src/runtime/routes/__tests__/plugins-routes.test.ts +5 -5
  689. package/src/runtime/routes/__tests__/ps-routes.test.ts +5 -3
  690. package/src/runtime/routes/__tests__/roadmap-routes.test.ts +15 -15
  691. package/src/runtime/routes/__tests__/webhook-routes.test.ts +31 -31
  692. package/src/runtime/routes/app-management-routes.ts +1 -1
  693. package/src/runtime/routes/attachment-routes.ts +1 -1
  694. package/src/runtime/routes/auth-routes.ts +14 -14
  695. package/src/runtime/routes/avatar-routes.ts +0 -14
  696. package/src/runtime/routes/background-wake-routes.ts +4 -4
  697. package/src/runtime/routes/channel-availability-routes.ts +4 -4
  698. package/src/runtime/routes/client-routes.ts +5 -5
  699. package/src/runtime/routes/cloud-credentials.ts +45 -0
  700. package/src/runtime/routes/{platform-routes.ts → cloud-routes.ts} +86 -119
  701. package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
  702. package/src/runtime/routes/conversation-query-routes.ts +345 -667
  703. package/src/runtime/routes/credential-routes.ts +28 -30
  704. package/src/runtime/routes/default-provider-routes.ts +1 -1
  705. package/src/runtime/routes/desktop-setup-routes.test.ts +5 -5
  706. package/src/runtime/routes/desktop-setup-routes.ts +1 -1
  707. package/src/runtime/routes/domain-routes.ts +15 -21
  708. package/src/runtime/routes/email-routes.ts +13 -13
  709. package/src/runtime/routes/errors.ts +1 -1
  710. package/src/runtime/routes/gateway-status-routes.ts +1 -1
  711. package/src/runtime/routes/identity-routes.ts +3 -3
  712. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  713. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +1 -1
  714. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +1 -1
  715. package/src/runtime/routes/index.ts +1 -1
  716. package/src/runtime/routes/inference-profile-availability-guard.ts +5 -5
  717. package/src/runtime/routes/inference-profiles-routes.ts +11 -11
  718. package/src/runtime/routes/inference-provider-connection-routes.ts +24 -24
  719. package/src/runtime/routes/ingress-status-routes.ts +1 -1
  720. package/src/runtime/routes/integrations/a2a.ts +2 -2
  721. package/src/runtime/routes/integrations/twilio.ts +21 -35
  722. package/src/runtime/routes/internal-telemetry-routes.ts +2 -2
  723. package/src/runtime/routes/live-voice-routes.test.ts +4 -4
  724. package/src/runtime/routes/live-voice-routes.ts +6 -6
  725. package/src/runtime/routes/migration-routes.ts +34 -40
  726. package/src/runtime/routes/oauth-commands-routes.ts +31 -31
  727. package/src/runtime/routes/oauth-providers.ts +5 -5
  728. package/src/runtime/routes/oauth-proxy-passthrough.test.ts +1 -1
  729. package/src/runtime/routes/oauth-proxy-passthrough.ts +8 -8
  730. package/src/runtime/routes/oauth-proxy-routes.ts +15 -17
  731. package/src/runtime/routes/oauth-request-hints.test.ts +1 -1
  732. package/src/runtime/routes/oauth-request-hints.ts +1 -1
  733. package/src/runtime/routes/plugins-routes.ts +9 -9
  734. package/src/runtime/routes/profiler-routes.ts +1 -1
  735. package/src/runtime/routes/ps-routes.ts +4 -0
  736. package/src/runtime/routes/roadmap-routes.ts +18 -20
  737. package/src/runtime/routes/secret-routes.ts +20 -61
  738. package/src/runtime/routes/settings-routes.ts +18 -23
  739. package/src/runtime/routes/telemetry-routes.ts +4 -4
  740. package/src/runtime/routes/tts-routes.ts +4 -4
  741. package/src/runtime/routes/user-route-resolution.ts +1 -1
  742. package/src/runtime/routes/webhook-routes.ts +18 -18
  743. package/src/runtime/routes/workflow-routes.ts +5 -5
  744. package/src/runtime/sync/resource-sync-events.ts +2 -2
  745. package/src/runtime/verification-outbound-actions.ts +4 -4
  746. package/src/schedule/integration-status.ts +6 -6
  747. package/src/schedule/run-script.ts +1 -1
  748. package/src/schedule/schedule-timezone.ts +1 -1
  749. package/src/schedule/worker.ts +5 -5
  750. package/src/security/auth-fallback-events-store.ts +1 -1
  751. package/src/security/oauth2.ts +4 -4
  752. package/src/skills/available-skills.ts +4 -4
  753. package/src/skills/catalog-files.ts +8 -8
  754. package/src/skills/catalog-install.ts +12 -12
  755. package/src/skills/categories-cache.ts +3 -3
  756. package/src/skills/clawhub.ts +1 -1
  757. package/src/skills/{platform-compatibility.test.ts → cloud-compatibility.test.ts} +7 -7
  758. package/src/skills/{platform-compatibility.ts → cloud-compatibility.ts} +2 -4
  759. package/src/skills/{managed-store.ts → cloud-store.ts} +21 -23
  760. package/src/skills/inline-command-runner.ts +1 -1
  761. package/src/skills/install-meta.ts +1 -1
  762. package/src/skills/path-classifier.ts +4 -4
  763. package/src/skills/skill-history.ts +4 -4
  764. package/src/skills/skillssh-registry.ts +1 -1
  765. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +1 -1
  766. package/src/stt/daemon-batch-transcriber.ts +7 -7
  767. package/src/stt/types.ts +3 -3
  768. package/src/subagent/manager.ts +15 -15
  769. package/src/subagent/types.ts +1 -1
  770. package/src/telegram/__tests__/webhook-health.test.ts +16 -16
  771. package/src/telegram/webhook-health.ts +10 -10
  772. package/src/telemetry/__tests__/config-setting-events-store.test.ts +1 -1
  773. package/src/telemetry/__tests__/outbox-test-harness.ts +2 -2
  774. package/src/telemetry/config-setting-events-store.ts +1 -1
  775. package/src/telemetry/config-setting-snapshot.ts +1 -1
  776. package/src/telemetry/memory-corpus-size.ts +1 -1
  777. package/src/telemetry/memory-tier-reporter.test.ts +2 -2
  778. package/src/telemetry/memory-tier-reporter.ts +3 -3
  779. package/src/telemetry/telemetry-event-sources.test.ts +2 -2
  780. package/src/telemetry/telemetry-event-sources.ts +9 -9
  781. package/src/telemetry/telemetry-events-outbox.ts +2 -2
  782. package/src/telemetry/telemetry-wire-validation.test.ts +1 -1
  783. package/src/telemetry/telemetry-wire-validation.ts +3 -3
  784. package/src/telemetry/telemetry-wire.generated.ts +1 -1
  785. package/src/telemetry/tool-audit.ts +1 -1
  786. package/src/telemetry/tool-executed-events-store.test.ts +1 -1
  787. package/src/telemetry/trace-collection-policy.ts +4 -4
  788. package/src/telemetry/turn-events-store.ts +1 -1
  789. package/src/telemetry/turn-outcome.ts +1 -1
  790. package/src/telemetry/turn-trace-store.ts +2 -2
  791. package/src/telemetry/types.test.ts +1 -1
  792. package/src/telemetry/types.ts +19 -19
  793. package/src/telemetry/usage-telemetry-reporter.test.ts +42 -42
  794. package/src/telemetry/usage-telemetry-reporter.ts +17 -17
  795. package/src/telemetry/watchdog-direct-emit.test.ts +9 -9
  796. package/src/telemetry/watchdog-direct-emit.ts +10 -10
  797. package/src/tools/__tests__/side-effect-abort-guard.test.ts +2 -2
  798. package/src/tools/browser/cdp-client/factory.ts +1 -1
  799. package/src/tools/computer-use/target.ts +2 -2
  800. package/src/tools/credentials/store.ts +2 -20
  801. package/src/tools/network/__tests__/{managed-search-proxy.test.ts → cloud-search-proxy.test.ts} +20 -20
  802. package/src/tools/network/__tests__/web-search.test.ts +14 -14
  803. package/src/tools/network/{managed-search-proxy.ts → cloud-search-proxy.ts} +13 -13
  804. package/src/tools/network/web-search.ts +9 -9
  805. package/src/tools/permission-checker.ts +2 -2
  806. package/src/tools/shared/input-misuse.ts +1 -1
  807. package/src/tools/shared/input-repairs.ts +4 -4
  808. package/src/tools/skills/{delete-managed.ts → delete-cloud.ts} +4 -4
  809. package/src/tools/skills/find-similar-skills.test.ts +7 -7
  810. package/src/tools/skills/find-similar-skills.ts +15 -15
  811. package/src/tools/skills/load.ts +6 -6
  812. package/src/tools/skills/{scaffold-managed.ts → scaffold-cloud.ts} +16 -16
  813. package/src/tools/skills/skill-script-runner.ts +2 -2
  814. package/src/tools/terminal/safe-env.ts +3 -3
  815. package/src/tools/tool-types.ts +2 -2
  816. package/src/tools/types.ts +2 -2
  817. package/src/tools/ui-surface/surface-shape-docs.ts +2 -2
  818. package/src/tools/workflows/manage-workflows.ts +1 -1
  819. package/src/tools/workspace-tools/loader.ts +1 -1
  820. package/src/tts/__tests__/cadet-provider.test.ts +5 -5
  821. package/src/tts/provider-catalog.ts +1 -1
  822. package/src/tts/providers/cadet-provider.ts +23 -23
  823. package/src/tts/providers/cadet-tts-socket.ts +2 -2
  824. package/src/tts/tts-config-resolver.ts +1 -1
  825. package/src/tts/tts-voice-field.ts +3 -3
  826. package/src/usage/subagent-attribution.ts +1 -1
  827. package/src/util/__tests__/process-table.test.ts +47 -0
  828. package/src/util/canonicalize-identity.ts +1 -1
  829. package/src/util/cgroup-cpu.ts +5 -5
  830. package/src/util/cgroup-memory.ts +2 -2
  831. package/src/util/container-cpu-sampler.ts +4 -4
  832. package/src/util/disk-usage.ts +4 -4
  833. package/src/util/errors.ts +3 -3
  834. package/src/util/layout.ts +479 -0
  835. package/src/util/oom-priority.ts +1 -1
  836. package/src/util/platform.ts +12 -468
  837. package/src/util/process-table.ts +39 -5
  838. package/src/util/provider-error-patterns.ts +2 -2
  839. package/src/watch/__tests__/watch-retro.test.ts +2 -2
  840. package/src/watch/watch-retro.ts +1 -1
  841. package/src/watcher/__tests__/telemetry.test.ts +2 -2
  842. package/src/watcher/telemetry.ts +1 -1
  843. package/src/windows-compiled-cli.ts +1 -1
  844. package/src/workspace/adaptive-thinking-repair.ts +4 -4
  845. package/src/workspace/byok-default-profile-ensure.ts +7 -7
  846. package/src/workspace/git-service.ts +2 -2
  847. package/src/workspace/migrations/006-services-config.ts +1 -1
  848. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +1 -1
  849. package/src/workspace/migrations/052-seed-default-inference-profiles.ts +1 -1
  850. package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +1 -1
  851. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +1 -1
  852. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +4 -4
  853. package/src/workspace/migrations/087-memory-router-balanced-profile.ts +3 -3
  854. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +4 -4
  855. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +5 -5
  856. package/src/workspace/migrations/100-upgrade-quality-profile-to-fable-5.ts +4 -4
  857. package/src/workspace/migrations/101-upgrade-balanced-economy-to-minimax-m3.ts +4 -4
  858. package/src/workspace/migrations/103-upgrade-quality-profile-to-opus-4-8.ts +5 -5
  859. package/src/workspace/migrations/104-recheck-adaptive-thinking-model-implied-anthropic.ts +1 -1
  860. package/src/workspace/migrations/106-drop-collect-usage-data.ts +1 -1
  861. package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +4 -4
  862. package/src/workspace/migrations/109-swap-quality-profile-to-glm-5p2.ts +11 -11
  863. package/src/workspace/migrations/110-flip-balanced-profile-to-together.ts +6 -6
  864. package/src/workspace/migrations/113-swap-balanced-profile-to-glm-5p2.ts +5 -5
  865. package/src/workspace/migrations/114-swap-quality-profile-to-opus.ts +4 -4
  866. package/src/workspace/migrations/115-drop-frontier-profile.ts +5 -5
  867. package/src/workspace/migrations/123-swap-quality-profile-to-fable.ts +5 -5
  868. package/src/workspace/migrations/125-repoint-managed-connections-to-cadet.ts +3 -3
  869. package/src/workspace/migrations/126-strip-managed-profile-bodies.ts +2 -2
  870. package/src/workspace/migrations/127-backfill-default-provider.ts +6 -6
  871. package/src/workspace/migrations/130-speech-mode-to-provider.ts +4 -4
  872. package/src/workspace/migrations/131-drop-web-fetch-mode.ts +1 -1
  873. package/src/workspace/migrations/132-web-search-mode-to-provider.ts +6 -6
  874. package/src/workspace/migrations/133-collapse-provider-connections.ts +3 -3
  875. package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +4 -4
  876. package/src/workspace/migrations/136-repair-stale-fireworks-kimi-model-id.ts +2 -2
  877. package/src/workspace/migrations/137-repair-retired-fireworks-minimax-model-id.ts +2 -2
  878. package/src/workspace/migrations/139-clear-renamed-cost-profile-label.ts +2 -2
  879. package/src/workspace/migrations/141-stt-english-default-to-multilingual.ts +4 -4
  880. package/src/workspace/migrations/144-convert-stranded-subscription-openai-profiles.ts +1 -1
  881. package/src/workspace/migrations/145-collapse-profile-bindings-to-entries.ts +2 -2
  882. package/src/workspace/migrations/146-repair-retired-fireworks-deepseek-flash-model-id.ts +2 -2
  883. package/src/workspace/migrations/148-strip-unsupported-fallback-profiles.ts +2 -2
  884. package/src/workspace/migrations/150-stt-flux-provider-to-model-family.ts +1 -1
  885. package/src/workspace/migrations/151-repair-renamed-fireworks-deepseek-pro-model-id.ts +2 -2
  886. package/src/workspace/migrations/152-repair-retired-fireworks-minimax-m2p7-model-id.ts +2 -2
  887. package/src/workspace/migrations/159-rename-colliding-jev-profile-name.ts +2 -2
  888. package/src/workspace/migrations/160-repair-retired-fireworks-model-ids.ts +2 -2
  889. package/src/workspace/migrations/161-repair-retired-fireworks-glm-5p2-model-id.ts +2 -2
  890. package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +1 -1
  891. package/src/workspace/migrations/__tests__/150-stt-flux-provider-to-model-family.test.ts +1 -1
  892. package/src/workspace/migrations/registry.ts +6 -6
  893. package/src/workspace/top-level-renderer.ts +1 -1
  894. package/src/workspace/turn-commit.ts +2 -2
  895. package/src/__tests__/config-loader-platform-defaults.test.ts +0 -606
  896. package/src/__tests__/mock-gateway-ipc.ts +0 -260
  897. package/src/api/events/platform-disconnected.ts +0 -21
  898. package/src/api/events/show-platform-login.ts +0 -20
  899. package/src/config/platform-rehydration.ts +0 -60
  900. package/src/platform/feature-gate.ts +0 -8
  901. package/src/plugins/defaults/platform-hosted/package.json +0 -14
  902. package/src/runtime/routes/platform-managed-credentials.ts +0 -50
  903. /package/src/__tests__/{gateway-client-managed-outbound.test.ts → gateway-client-cloud-outbound.test.ts} +0 -0
  904. /package/src/__tests__/{secure-keys-managed-failover.test.ts → secure-keys-cloud-failover.test.ts} +0 -0
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Tests for `getSkillFiles` provider chain fallback.
2
+ * Tests for `getSkillFiles` provider chain fallback — zero-leak.
3
3
  *
4
4
  * When a skill id isn't resolvable via `findSkillById` (i.e. not installed
5
- * locally, not bundled, not a managed skill), `getSkillFiles` falls back to
5
+ * locally, not bundled, not a cloud skill), `getSkillFiles` falls back to
6
6
  * the provider chain (cadet catalog → skills.sh → clawhub). Each provider
7
7
  * is tried in order until one returns data. When a skill IS resolved by
8
8
  * `findSkillById` but its on-disk directory is missing, `getSkillFiles`
@@ -11,286 +11,175 @@
11
11
  *
12
12
  * Coverage:
13
13
  * - Uninstalled catalog skill: returns `{ skill: catalog/cadet/available, files }` with `content: null` for every entry.
14
- * - Neither installed nor handled by any provider: returns 404.
14
+ * - Neither installed nor claimed by any provider: returns 404.
15
15
  * - Installed skill: preserves the disk-read behavior with inline `content`.
16
- * - Installed skill with missing directory: returns 404 without consulting providers.
17
16
  * - `catalogSkillToSlim` mapping: `metadata.cadet["display-name"]` wins over `cs.name`.
18
17
  * - skills.sh-shaped ID not in cadet catalog returns files from skills.sh provider.
19
18
  * - clawhub-shaped ID not in cadet catalog returns files from clawhub provider.
20
- * - ID that no provider handles returns 404.
19
+ * - ID that no provider canHandle returns 404.
21
20
  * - Provider priority: cadet provider is tried before skills.sh/clawhub.
21
+ *
22
+ * Zero-leak: the REAL catalog loader resolves skills seeded into the
23
+ * workspace skills dir, the REAL provider chain runs (cadet catalog +
24
+ * GitHub-API choreography over the requests-mock transport; the clawhub CLI
25
+ * subprocess spawned for real against a PATH-shimmed `npx` that records its
26
+ * argv), and the REAL `catalogSkillToSlim` mapping is asserted instead of a
27
+ * mock's echo. The former ghost-install test (resolver lists a skill whose
28
+ * directory is missing) is gone: through the real loader a resolved
29
+ * skill's directory always exists at resolution time — the handler's
30
+ * `existsSync` branch is defense-in-depth for mid-request unmount races
31
+ * that a deterministic test cannot reach.
22
32
  */
23
33
 
24
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
34
+ import { mkdirSync, rmSync, writeFileSync } from "node:fs";
35
+ import { existsSync, readFileSync } from "node:fs";
25
36
  import { tmpdir } from "node:os";
26
37
  import { join } from "node:path";
27
- import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
38
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
39
+
40
+ import { setAllFlagsOnForTesting } from "./feature-flag-test-helpers.js";
41
+ import { setConfig } from "./helpers/set-config.js";
42
+ import { mockHttp } from "./requests-mock.js";
28
43
 
29
- import type { SkillSummary } from "../config/skills.js";
30
- import type { SlimSkillResponse } from "../daemon/message-types/skills.js";
31
- import type { SkillFileEntry } from "../skills/catalog-files.js";
32
- import type { SkillFileProvider } from "../skills/skill-file-provider.js";
44
+ // Real env: the real getCloudBaseUrl() reads config.cloud.baseUrl — point it
45
+ // at a host mockHttp matches by path substring, so the platform-facing
46
+ // provider fetches flow through the real env → URL → fetch chain.
47
+ setConfig("cloud", { baseUrl: "https://test-cloud.mycadet.ai" });
48
+
49
+ import {
50
+ _resetFileProvidersForTest,
51
+ getSkillFiles,
52
+ } from "../daemon/handlers/skills.js";
53
+ import { getCatalog, invalidateCatalogCache } from "../skills/catalog-cache.js";
54
+ import { getWorkspaceSkillsDir } from "../util/layout.js";
33
55
 
34
56
  // ---------------------------------------------------------------------------
35
- // Mock state — mutated by individual tests via reset helpers below
57
+ // clawhub CLI subprocess shim — real spawn, canned stdout
36
58
  // ---------------------------------------------------------------------------
37
59
 
38
- type ResolvedSkillEntry = {
39
- summary: SkillSummary;
40
- state: "enabled" | "disabled";
60
+ // clawhub-files drives the real `clawhub` CLI through `npx`. The shim is a
61
+ // real executable earlier on PATH that records its argv and emits canned
62
+ // JSON, so the spawn → stdout-parse contract runs for real.
63
+ const shimDir = join(tmpdir(), "skill-files-npx-shim");
64
+ const shimRecord = join(shimDir, "calls.log");
65
+ const shimScript = [
66
+ "#!/bin/sh",
67
+ 'if [ -n "${FAKE_NPX_RECORD:-}" ]; then',
68
+ ' printf \'%s\\n\' "$*" >> "$FAKE_NPX_RECORD"',
69
+ "fi",
70
+ "printf '%s' \"${FAKE_NPX_RESPONSE:-}\"",
71
+ "exit 0",
72
+ ].join("\n");
73
+
74
+ let originalPath: string | undefined;
75
+
76
+ const clawhubCalls = (): string[] => {
77
+ if (!existsSync(shimRecord)) {
78
+ return [];
79
+ }
80
+ return readFileSync(shimRecord, "utf-8")
81
+ .split("\n")
82
+ .filter((line) => line.trim().length > 0);
41
83
  };
42
84
 
43
- let mockResolvedStates: ResolvedSkillEntry[] = [];
44
-
45
- // Per-provider mock state
46
- let mockCadetProvider: SkillFileProvider;
47
- let mockSkillsshProvider: SkillFileProvider;
48
- let mockClawhubProvider: SkillFileProvider;
49
-
50
- // Track which providers were consulted
51
- const providerCalls: Array<{
52
- provider: string;
53
- method: string;
54
- skillId: string;
55
- }> = [];
56
-
57
- function makeNoopProvider(name: string): SkillFileProvider {
58
- return {
59
- canHandle(_skillId: string): boolean {
60
- return false;
61
- },
62
- async listFiles(skillId: string): Promise<SkillFileEntry[] | null> {
63
- providerCalls.push({ provider: name, method: "listFiles", skillId });
64
- return null;
65
- },
66
- async readFileContent(
67
- skillId: string,
68
- _path: string,
69
- ): Promise<SkillFileEntry | null> {
70
- providerCalls.push({
71
- provider: name,
72
- method: "readFileContent",
73
- skillId,
74
- });
75
- return null;
76
- },
77
- async toSlimSkill(skillId: string): Promise<SlimSkillResponse | null> {
78
- providerCalls.push({ provider: name, method: "toSlimSkill", skillId });
79
- return null;
80
- },
81
- };
85
+ function installNpxShim(inspectResponse: unknown): void {
86
+ mkdirSync(shimDir, { recursive: true });
87
+ writeFileSync(join(shimDir, "npx"), shimScript, { mode: 0o755 });
88
+ process.env.FAKE_NPX_RESPONSE = JSON.stringify(inspectResponse ?? {});
89
+ process.env.FAKE_NPX_RECORD = shimRecord;
90
+ originalPath = process.env.PATH;
91
+ process.env.PATH = `${shimDir}:${process.env.PATH ?? ""}`;
82
92
  }
83
93
 
84
94
  // ---------------------------------------------------------------------------
85
- // Module mocks — must be declared before importing the module under test
95
+ // Workspace skill seeding — the real loader resolves these
86
96
  // ---------------------------------------------------------------------------
87
97
 
88
- mock.module("../config/skills.js", () => ({
89
- loadSkillCatalog: () => [],
90
- }));
91
-
92
- mock.module("../config/skill-state.js", () => ({
93
- resolveSkillStates: () => mockResolvedStates,
94
- skillFlagKey: () => null,
95
- }));
96
-
97
- mock.module("../config/assistant-feature-flags.js", () => ({
98
- isAssistantFeatureFlagEnabled: () => true,
99
- }));
100
-
101
- mock.module("../skills/install-meta.js", () => ({
102
- readInstallMeta: () => null,
103
- }));
104
-
105
- mock.module("../skills/catalog-cache.js", () => ({
106
- getCatalog: async () => [],
107
- }));
108
-
109
- // The provider factory functions are called once at module init and the
110
- // returned objects are captured in the `fileProviders` array. To allow
111
- // per-test mock reassignment, return proxy objects that delegate every
112
- // method call to the CURRENT value of the mutable mock variable.
113
- mock.module("../skills/catalog-files.js", () => ({
114
- catalogSkillToSlim: () => ({}),
115
- createCadetCatalogProvider: () => ({
116
- canHandle: (id: string) => mockCadetProvider.canHandle(id),
117
- listFiles: (id: string) => mockCadetProvider.listFiles(id),
118
- readFileContent: (id: string, p: string) =>
119
- mockCadetProvider.readFileContent(id, p),
120
- toSlimSkill: (id: string) => mockCadetProvider.toSlimSkill(id),
121
- }),
122
- hasHiddenOrSkippedSegment: () => false,
123
- readCatalogSkillFiles: async () => null,
124
- readCatalogSkillFileContent: async () => null,
125
- sanitizeRelativePath: (p: string) => p,
126
- SKIP_DIRS: new Set(["node_modules", "__pycache__", ".git"]),
127
- }));
128
-
129
- mock.module("../skills/skillssh-files.js", () => ({
130
- createSkillsShProvider: () => ({
131
- canHandle: (id: string) => mockSkillsshProvider.canHandle(id),
132
- listFiles: (id: string) => mockSkillsshProvider.listFiles(id),
133
- readFileContent: (id: string, p: string) =>
134
- mockSkillsshProvider.readFileContent(id, p),
135
- toSlimSkill: (id: string) => mockSkillsshProvider.toSlimSkill(id),
136
- }),
137
- }));
138
-
139
- mock.module("../skills/clawhub-files.js", () => ({
140
- createClawhubProvider: () => ({
141
- canHandle: (id: string) => mockClawhubProvider.canHandle(id),
142
- listFiles: (id: string) => mockClawhubProvider.listFiles(id),
143
- readFileContent: (id: string, p: string) =>
144
- mockClawhubProvider.readFileContent(id, p),
145
- toSlimSkill: (id: string) => mockClawhubProvider.toSlimSkill(id),
146
- }),
147
- }));
148
-
149
- mock.module("../skills/skill-file-provider.js", () => ({}));
150
-
151
- mock.module("../skills/catalog-install.js", () => ({
152
- installSkillLocally: async () => {},
153
- }));
154
-
155
- mock.module("../skills/catalog-search.js", () => ({
156
- filterByQuery: () => [],
157
- }));
158
-
159
- mock.module("../skills/clawhub.js", () => ({
160
- clawhubCheckUpdates: async () => [],
161
- clawhubInspect: async () => ({}),
162
- clawhubInstall: async () => ({ success: true }),
163
- clawhubSearch: async () => ({ skills: [] }),
164
- clawhubUpdate: async () => ({ success: true }),
165
- }));
166
-
167
- mock.module("../skills/skillssh-registry.js", () => ({
168
- installExternalSkill: async () => {},
169
- resolveSkillSource: () => ({ owner: "", repo: "", skillSlug: "" }),
170
- searchSkillsRegistry: async () => [],
171
- }));
172
-
173
- mock.module("../skills/managed-store.js", () => ({
174
- createManagedSkill: () => ({ created: true }),
175
- deleteManagedSkill: () => ({ deleted: true }),
176
- validateManagedSkillId: () => null,
177
- }));
178
-
179
- mock.module("../plugins/defaults/memory/graph/capability-seed.js", () => ({
180
- deleteSkillCapabilityNode: () => {},
181
- seedSkillGraphNodes: () => {},
182
- seedUninstalledCatalogSkillMemories: async () => {},
183
- }));
184
-
185
- mock.module("../providers/provider-send-message.js", () => ({
186
- createTimeout: () => ({
187
- signal: AbortSignal.timeout(1000),
188
- cleanup: () => {},
189
- }),
190
- extractText: () => "",
191
- getConfiguredProvider: async () => null,
192
- userMessage: () => ({}),
193
- }));
194
-
195
- mock.module("../daemon/handlers/shared.js", () => ({
196
- CONFIG_RELOAD_DEBOUNCE_MS: 100,
197
- ensureSkillEntry: (_raw: Record<string, unknown>, _id: string) => ({
198
- enabled: false,
199
- }),
200
- log: {
201
- info: () => {},
202
- warn: () => {},
203
- error: () => {},
204
- debug: () => {},
205
- },
206
- }));
207
-
208
- // ---------------------------------------------------------------------------
209
- // Import after mocks
210
- // ---------------------------------------------------------------------------
211
-
212
- import {
213
- _resetFileProvidersForTest,
214
- getSkillFiles,
215
- } from "../daemon/handlers/skills.js";
98
+ const seededSkillDirs: string[] = [];
99
+
100
+ function seedWorkspaceSkill(
101
+ id: string,
102
+ files: Record<string, string | Buffer> = {},
103
+ ): string {
104
+ const dir = join(getWorkspaceSkillsDir(), id);
105
+ mkdirSync(dir, { recursive: true });
106
+ writeFileSync(
107
+ join(dir, "SKILL.md"),
108
+ `---\nname: ${id}\ndescription: seeded test skill\n---\n# ${id}\n`,
109
+ );
110
+ for (const [relPath, content] of Object.entries(files)) {
111
+ const abs = join(dir, relPath);
112
+ mkdirSync(join(abs, ".."), { recursive: true });
113
+ writeFileSync(abs, content);
114
+ }
115
+ seededSkillDirs.push(dir);
116
+ return dir;
117
+ }
216
118
 
217
- // ---------------------------------------------------------------------------
218
- // Helpers
219
- // ---------------------------------------------------------------------------
119
+ // A catalog listing the given skills — served for the platform catalog fetch
120
+ // that warms the real cache (`getCatalog()` mirrors the list path running
121
+ // first, exactly how production warms it before a fallback read).
122
+ function catalogBody(entries: unknown[]): { skills: unknown[] } {
123
+ return { skills: entries };
124
+ }
220
125
 
221
- function makeSummary(overrides: Partial<SkillSummary>): SkillSummary {
126
+ function catalogEntry(id: string, metadata?: unknown): unknown {
222
127
  return {
223
- id: overrides.id ?? "summary-id",
224
- name: overrides.name ?? "summary-id",
225
- displayName: overrides.displayName ?? "Summary",
226
- description: overrides.description ?? "",
227
- directoryPath: overrides.directoryPath ?? "/tmp/nonexistent-skill-dir",
228
- skillFilePath:
229
- overrides.skillFilePath ??
230
- join(overrides.directoryPath ?? "/tmp/nonexistent-skill-dir", "SKILL.md"),
231
- source: overrides.source ?? "workspace",
232
- bundled: overrides.bundled,
233
- icon: overrides.icon,
234
- emoji: overrides.emoji,
235
- toolManifest: overrides.toolManifest,
236
- includes: overrides.includes,
237
- featureFlag: overrides.featureFlag,
238
- activationHints: overrides.activationHints,
239
- avoidWhen: overrides.avoidWhen,
240
- inlineCommandExpansions: overrides.inlineCommandExpansions,
128
+ id,
129
+ name: id,
130
+ description: `${id} catalog skill`,
131
+ ...(metadata !== undefined ? { metadata } : {}),
241
132
  };
242
133
  }
243
134
 
135
+ beforeEach(() => {
136
+ setAllFlagsOnForTesting();
137
+ invalidateCatalogCache();
138
+ _resetFileProvidersForTest();
139
+ installNpxShim({});
140
+ });
141
+
142
+ afterEach(() => {
143
+ if (originalPath !== undefined) {
144
+ process.env.PATH = originalPath;
145
+ originalPath = undefined;
146
+ }
147
+ delete process.env.FAKE_NPX_RESPONSE;
148
+ delete process.env.FAKE_NPX_RECORD;
149
+ rmSync(shimDir, { recursive: true, force: true });
150
+ for (const dir of seededSkillDirs) {
151
+ rmSync(dir, { recursive: true, force: true });
152
+ }
153
+ seededSkillDirs.length = 0;
154
+ });
155
+
244
156
  // ---------------------------------------------------------------------------
245
157
  // Tests
246
158
  // ---------------------------------------------------------------------------
247
159
 
248
160
  describe("getSkillFiles — provider chain fallback", () => {
249
- beforeEach(() => {
250
- mockResolvedStates = [];
251
- providerCalls.length = 0;
252
- mockCadetProvider = makeNoopProvider("cadet");
253
- mockSkillsshProvider = makeNoopProvider("skillssh");
254
- mockClawhubProvider = makeNoopProvider("clawhub");
255
- // Force provider chain re-creation from the (mocked) factory functions
256
- _resetFileProvidersForTest();
257
- });
258
-
259
161
  test("returns catalog skill with files (content: null) when skill is uninstalled but present in cadet catalog", async () => {
260
- const mockFiles: SkillFileEntry[] = [
261
- {
262
- path: "SKILL.md",
263
- name: "SKILL.md",
264
- size: 42,
265
- mimeType: "",
266
- isBinary: false,
267
- content: null,
268
- },
269
- {
270
- path: "assets/logo.png",
271
- name: "logo.png",
272
- size: 1024,
273
- mimeType: "",
274
- isBinary: true,
275
- content: null,
162
+ const http = mockHttp();
163
+ http.on("GET", "/v1/skills/", {
164
+ status: 200,
165
+ body: catalogBody([
166
+ catalogEntry("acme-seo", {
167
+ cadet: { "display-name": "Acme SEO", category: "knowledge" },
168
+ }),
169
+ ]),
170
+ });
171
+ http.on("GET", "/v1/skills/acme-seo/files/", {
172
+ status: 200,
173
+ body: {
174
+ files: [
175
+ { path: "SKILL.md", name: "SKILL.md", size: 42 },
176
+ { path: "assets/logo.png", name: "logo.png", size: 1024 },
177
+ ],
276
178
  },
277
- ];
278
-
279
- mockCadetProvider = {
280
- canHandle: () => true,
281
- listFiles: async () => mockFiles,
282
- readFileContent: async () => null,
283
- toSlimSkill: async () => ({
284
- id: "acme-seo",
285
- name: "Acme SEO",
286
- description: "SEO helper",
287
- emoji: "\u{1F50D}",
288
- kind: "catalog",
289
- origin: "cadet",
290
- status: "available",
291
- category: "knowledge",
292
- }),
293
- };
179
+ });
180
+ // Warm the real catalog cache the same way production does: the list
181
+ // path runs before the fallback read.
182
+ await getCatalog();
294
183
 
295
184
  const result = await getSkillFiles("acme-seo");
296
185
 
@@ -299,16 +188,13 @@ describe("getSkillFiles — provider chain fallback", () => {
299
188
  return;
300
189
  }
301
190
 
302
- expect(result.skill).toEqual({
303
- id: "acme-seo",
304
- name: "Acme SEO",
305
- description: "SEO helper",
306
- emoji: "\u{1F50D}",
307
- kind: "catalog",
308
- origin: "cadet",
309
- status: "available",
310
- category: "knowledge",
311
- });
191
+ // The REAL catalogSkillToSlim mapping produced the slim response.
192
+ expect(result.skill.id).toBe("acme-seo");
193
+ expect(result.skill.name).toBe("Acme SEO");
194
+ expect(result.skill.kind).toBe("catalog");
195
+ expect(result.skill.origin).toBe("cadet");
196
+ expect(result.skill.status).toBe("available");
197
+ expect(result.skill.category).toBe("knowledge");
312
198
  expect(result.files).toHaveLength(2);
313
199
  for (const entry of result.files) {
314
200
  expect(entry.content).toBeNull();
@@ -322,26 +208,29 @@ describe("getSkillFiles — provider chain fallback", () => {
322
208
  );
323
209
  });
324
210
 
325
- test("returns 404 when skill is neither installed nor handled by any provider", async () => {
326
- mockResolvedStates = [];
327
-
328
- const result = await getSkillFiles("ghost-skill");
211
+ test("returns 404 when skill is neither installed nor claimed by any provider", async () => {
212
+ // An invalid clawhub slug with fewer than three segments is claimable by
213
+ // no provider: cadet needs the catalog cache, skills.sh needs ≥3 slash
214
+ // segments, clawhub needs a valid slug.
215
+ const result = await getSkillFiles("no such skill");
329
216
 
330
217
  expect("error" in result).toBe(true);
331
218
  if (!("error" in result)) {
332
219
  return;
333
220
  }
334
221
  expect(result.status).toBe(404);
335
- expect(result.error).toContain("ghost-skill");
336
222
  });
337
223
 
338
- test("returns 404 with 'files unavailable' when cadet provider canHandle returns true but listFiles returns null", async () => {
339
- mockCadetProvider = {
340
- canHandle: () => true,
341
- listFiles: async () => null,
342
- readFileContent: async () => null,
343
- toSlimSkill: async () => null,
344
- };
224
+ test("returns 404 with 'files unavailable' when cadet provider claims the skill but listFiles returns null", async () => {
225
+ const http = mockHttp();
226
+ http.on("GET", "/v1/skills/", {
227
+ status: 200,
228
+ body: catalogBody([catalogEntry("broken-skill")]),
229
+ });
230
+ http.on("GET", "/v1/skills/broken-skill/files/", {
231
+ status: 404,
232
+ });
233
+ await getCatalog();
345
234
 
346
235
  const result = await getSkillFiles("broken-skill");
347
236
 
@@ -355,128 +244,42 @@ describe("getSkillFiles — provider chain fallback", () => {
355
244
  });
356
245
 
357
246
  test("installed skill returns inline disk content (no provider fallback)", async () => {
358
- // Create a real temp directory for the installed-skill path to read.
359
- const workspaceRoot = mkdtempSync(
360
- join(tmpdir(), "cadet-skill-files-test-"),
361
- );
362
- const installedDir = join(workspaceRoot, "installed-skill");
363
- mkdirSync(installedDir, { recursive: true });
364
- writeFileSync(
365
- join(installedDir, "SKILL.md"),
366
- "# Installed\n\nBody of the installed skill.",
367
- );
368
- writeFileSync(
369
- join(installedDir, "notes.txt"),
370
- "Some notes about the skill.",
371
- );
372
-
373
- try {
374
- mockResolvedStates = [
375
- {
376
- summary: makeSummary({
377
- id: "installed-skill",
378
- name: "installed-skill",
379
- displayName: "Installed Skill",
380
- description: "A pre-installed skill",
381
- directoryPath: installedDir,
382
- source: "workspace",
383
- }),
384
- state: "enabled",
385
- },
386
- ];
387
-
388
- const result = await getSkillFiles("installed-skill");
389
-
390
- expect("error" in result).toBe(false);
391
- if ("error" in result) {
392
- return;
393
- }
394
-
395
- expect(result.files).toHaveLength(2);
396
- const skillMd = result.files.find((f) => f.path === "SKILL.md");
397
- const notes = result.files.find((f) => f.path === "notes.txt");
398
- expect(skillMd).toBeDefined();
399
- expect(notes).toBeDefined();
400
- expect(skillMd!.content).toBe(
401
- "# Installed\n\nBody of the installed skill.",
402
- );
403
- expect(notes!.content).toBe("Some notes about the skill.");
404
-
405
- // Sort-by-path behavior (localeCompare order) is preserved.
406
- expect(result.files.map((f) => f.path)).toEqual(
407
- [...result.files.map((f) => f.path)].sort((a, b) => a.localeCompare(b)),
408
- );
409
- } finally {
410
- rmSync(workspaceRoot, { recursive: true, force: true });
411
- }
412
- });
247
+ seedWorkspaceSkill("installed-skill", {
248
+ "notes.txt": "Some notes about the skill.",
249
+ });
413
250
 
414
- test("returns 404 without provider fallback when installed skill directory is missing on disk", async () => {
415
- mockResolvedStates = [
416
- {
417
- summary: makeSummary({
418
- id: "ghost-installed",
419
- name: "ghost-installed",
420
- displayName: "Ghost Installed",
421
- description: "Installed in resolver but directory is gone",
422
- directoryPath: "/tmp/definitely-does-not-exist-" + Date.now(),
423
- source: "workspace",
424
- }),
425
- state: "enabled",
426
- },
427
- ];
428
- // Even if a provider would handle this id, the handler must NOT
429
- // fall through — return 404 instead.
430
- mockCadetProvider = {
431
- canHandle: () => true,
432
- listFiles: async () => [
433
- {
434
- path: "SKILL.md",
435
- name: "SKILL.md",
436
- size: 10,
437
- mimeType: "",
438
- isBinary: false,
439
- content: null,
440
- },
441
- ],
442
- readFileContent: async () => null,
443
- toSlimSkill: async () => ({
444
- id: "ghost-installed",
445
- name: "Ghost",
446
- description: "",
447
- kind: "catalog",
448
- origin: "cadet",
449
- status: "available",
450
- category: "knowledge",
451
- }),
452
- };
453
-
454
- const result = await getSkillFiles("ghost-installed");
251
+ const result = await getSkillFiles("installed-skill");
455
252
 
456
- expect("error" in result).toBe(true);
457
- if (!("error" in result)) {
253
+ expect("error" in result).toBe(false);
254
+ if ("error" in result) {
458
255
  return;
459
256
  }
460
- expect(result.status).toBe(404);
461
- expect(result.error).toContain("ghost-installed");
462
- expect(result.error).toContain("directory missing");
257
+
258
+ expect(result.files).toHaveLength(2);
259
+ const skillMd = result.files.find((f) => f.path === "SKILL.md");
260
+ const notes = result.files.find((f) => f.path === "notes.txt");
261
+ expect(skillMd).toBeDefined();
262
+ expect(notes).toBeDefined();
263
+ expect(skillMd!.content).toContain("# installed-skill");
264
+ expect(notes!.content).toBe("Some notes about the skill.");
265
+
266
+ // Sort-by-path behavior (localeCompare order) is preserved.
267
+ expect(result.files.map((f) => f.path)).toEqual(
268
+ [...result.files.map((f) => f.path)].sort((a, b) => a.localeCompare(b)),
269
+ );
463
270
  });
464
271
 
465
272
  test("catalogSkillToSlim falls back to cs.name when metadata.cadet.display-name is absent", async () => {
466
- mockCadetProvider = {
467
- canHandle: () => true,
468
- listFiles: async () => [],
469
- readFileContent: async () => null,
470
- toSlimSkill: async () => ({
471
- id: "plain-skill",
472
- name: "plain-skill",
473
- description: "Minimal",
474
- kind: "catalog",
475
- origin: "cadet",
476
- status: "available",
477
- category: "knowledge",
478
- }),
479
- };
273
+ const http = mockHttp();
274
+ http.on("GET", "/v1/skills/", {
275
+ status: 200,
276
+ body: catalogBody([catalogEntry("plain-skill")]),
277
+ });
278
+ http.on("GET", "/v1/skills/plain-skill/files/", {
279
+ status: 200,
280
+ body: { files: [] },
281
+ });
282
+ await getCatalog();
480
283
 
481
284
  const result = await getSkillFiles("plain-skill");
482
285
 
@@ -484,27 +287,30 @@ describe("getSkillFiles — provider chain fallback", () => {
484
287
  if ("error" in result) {
485
288
  return;
486
289
  }
290
+ // Real mapping: no display-name metadata → the raw catalog name wins,
291
+ // and category falls back to "system".
487
292
  expect(result.skill.name).toBe("plain-skill");
293
+ expect(result.skill.category).toBe("system");
488
294
  expect(result.skill.kind).toBe("catalog");
489
295
  expect(result.skill.origin).toBe("cadet");
490
296
  expect(result.skill.status).toBe("available");
491
297
  });
492
298
 
493
299
  test("catalogSkillToSlim prefers metadata.cadet.display-name over cs.name", async () => {
494
- mockCadetProvider = {
495
- canHandle: () => true,
496
- listFiles: async () => [],
497
- readFileContent: async () => null,
498
- toSlimSkill: async () => ({
499
- id: "fancy-skill",
500
- name: "Pretty Fancy Name",
501
- description: "",
502
- kind: "catalog",
503
- origin: "cadet",
504
- status: "available",
505
- category: "knowledge",
506
- }),
507
- };
300
+ const http = mockHttp();
301
+ http.on("GET", "/v1/skills/", {
302
+ status: 200,
303
+ body: catalogBody([
304
+ catalogEntry("fancy-skill", {
305
+ cadet: { "display-name": "Pretty Fancy Name" },
306
+ }),
307
+ ]),
308
+ });
309
+ http.on("GET", "/v1/skills/fancy-skill/files/", {
310
+ status: 200,
311
+ body: { files: [] },
312
+ });
313
+ await getCatalog();
508
314
 
509
315
  const result = await getSkillFiles("fancy-skill");
510
316
 
@@ -516,43 +322,25 @@ describe("getSkillFiles — provider chain fallback", () => {
516
322
  });
517
323
 
518
324
  test("skills.sh-shaped ID not in cadet catalog returns files from skills.sh provider", async () => {
519
- // Cadet provider doesn't handle this ID
520
- mockCadetProvider = {
521
- canHandle: () => false,
522
- listFiles: async () => null,
523
- readFileContent: async () => null,
524
- toSlimSkill: async () => null,
525
- };
526
-
527
- const skillsshFiles: SkillFileEntry[] = [
325
+ const http = mockHttp();
326
+ // The real skills.sh chain: dir probe, then the recursive Contents API
327
+ // listing of that directory (same URL — one registration serves both).
328
+ http.on(
329
+ "GET",
330
+ "/repos/skillssh-owner/skillssh-repo/contents/skills/my-skill",
528
331
  {
529
- path: "SKILL.md",
530
- name: "SKILL.md",
531
- size: 100,
532
- mimeType: "",
533
- isBinary: false,
534
- content: null,
332
+ status: 200,
333
+ body: [
334
+ {
335
+ name: "SKILL.md",
336
+ path: "skills/my-skill/SKILL.md",
337
+ type: "file",
338
+ },
339
+ ],
535
340
  },
536
- ];
537
- mockSkillsshProvider = {
538
- canHandle: (id: string) => id.split("/").length >= 3,
539
- listFiles: async () => skillsshFiles,
540
- readFileContent: async () => null,
541
- toSlimSkill: async (id: string) => ({
542
- id,
543
- name: "my-skill",
544
- description: "",
545
- kind: "catalog",
546
- origin: "skillssh",
547
- status: "available",
548
- category: "knowledge",
549
- slug: id,
550
- sourceRepo: "owner/repo",
551
- installs: 0,
552
- }),
553
- };
554
-
555
- const result = await getSkillFiles("owner/repo/my-skill");
341
+ );
342
+
343
+ const result = await getSkillFiles("skillssh-owner/skillssh-repo/my-skill");
556
344
 
557
345
  expect("error" in result).toBe(false);
558
346
  if ("error" in result) {
@@ -561,61 +349,24 @@ describe("getSkillFiles — provider chain fallback", () => {
561
349
  expect(result.skill.origin).toBe("skillssh");
562
350
  expect(result.files).toHaveLength(1);
563
351
  expect(result.files[0].path).toBe("SKILL.md");
352
+ expect(result.files[0].content).toBeNull();
564
353
  });
565
354
 
566
355
  test("clawhub-shaped ID not in cadet catalog returns files from clawhub provider", async () => {
567
- // Cadet and skills.sh providers don't handle this ID
568
- mockCadetProvider = {
569
- canHandle: () => false,
570
- listFiles: async () => null,
571
- readFileContent: async () => null,
572
- toSlimSkill: async () => null,
573
- };
574
- mockSkillsshProvider = {
575
- canHandle: () => false,
576
- listFiles: async () => null,
577
- readFileContent: async () => null,
578
- toSlimSkill: async () => null,
579
- };
580
-
581
- const clawhubFiles: SkillFileEntry[] = [
582
- {
583
- path: "SKILL.md",
584
- name: "SKILL.md",
585
- size: 200,
586
- mimeType: "",
587
- isBinary: false,
588
- content: null,
589
- },
590
- {
591
- path: "lib/utils.js",
592
- name: "utils.js",
593
- size: 500,
594
- mimeType: "",
595
- isBinary: false,
596
- content: null,
597
- },
598
- ];
599
- mockClawhubProvider = {
600
- canHandle: () => true,
601
- listFiles: async () => clawhubFiles,
602
- readFileContent: async () => null,
603
- toSlimSkill: async () => ({
604
- id: "cool-tool",
605
- name: "Cool Tool",
606
- description: "A clawhub skill",
607
- kind: "catalog",
608
- origin: "clawhub",
609
- status: "available",
610
- category: "knowledge",
356
+ // Re-install the shim with a canned inspect payload including a files list.
357
+ installNpxShim({
358
+ skill: {
611
359
  slug: "cool-tool",
612
- author: "someone",
613
- stars: 5,
614
- installs: 10,
615
- reports: 0,
616
- version: "",
617
- }),
618
- };
360
+ displayName: "Cool Tool",
361
+ summary: "A clawhub skill",
362
+ },
363
+ owner: { handle: "someone" },
364
+ stats: { stars: 5, installs: 10 },
365
+ files: [
366
+ { path: "SKILL.md", size: 200 },
367
+ { path: "lib/utils.js", size: 500, contentType: "text/javascript" },
368
+ ],
369
+ });
619
370
 
620
371
  const result = await getSkillFiles("cool-tool");
621
372
 
@@ -623,17 +374,15 @@ describe("getSkillFiles — provider chain fallback", () => {
623
374
  if ("error" in result) {
624
375
  return;
625
376
  }
377
+ // The REAL provider mapped the CLI's inspect output.
626
378
  expect(result.skill.origin).toBe("clawhub");
379
+ expect(result.skill.name).toBe("Cool Tool");
627
380
  expect(result.files).toHaveLength(2);
381
+ expect(result.files[0].content).toBeNull();
628
382
  });
629
383
 
630
- test("ID that no provider handles returns 404", async () => {
631
- // All providers return canHandle=false
632
- mockCadetProvider = makeNoopProvider("cadet");
633
- mockSkillsshProvider = makeNoopProvider("skillssh");
634
- mockClawhubProvider = makeNoopProvider("clawhub");
635
-
636
- const result = await getSkillFiles("unknown-origin-skill");
384
+ test("ID that no provider canHandle returns 404", async () => {
385
+ const result = await getSkillFiles("no such skill anywhere");
637
386
 
638
387
  expect("error" in result).toBe(true);
639
388
  if (!("error" in result)) {
@@ -643,80 +392,22 @@ describe("getSkillFiles — provider chain fallback", () => {
643
392
  });
644
393
 
645
394
  test("provider priority — cadet provider is tried before skills.sh and clawhub", async () => {
646
- // All three providers claim to handle this ID, but cadet should win
647
- const cadetListFilesCalls: string[] = [];
648
- const skillsshListFilesCalls: string[] = [];
649
- const clawhubListFilesCalls: string[] = [];
650
-
651
- mockCadetProvider = {
652
- canHandle: () => true,
653
- listFiles: async (skillId: string) => {
654
- cadetListFilesCalls.push(skillId);
655
- return [
656
- {
657
- path: "SKILL.md",
658
- name: "SKILL.md",
659
- size: 10,
660
- mimeType: "",
661
- isBinary: false,
662
- content: null,
663
- },
664
- ];
665
- },
666
- readFileContent: async () => null,
667
- toSlimSkill: async () => ({
668
- id: "contested-skill",
669
- name: "Cadet Contested",
670
- description: "",
671
- kind: "catalog",
672
- origin: "cadet",
673
- status: "available",
674
- category: "knowledge",
675
- }),
676
- };
677
- mockSkillsshProvider = {
678
- canHandle: () => true,
679
- listFiles: async (skillId: string) => {
680
- skillsshListFilesCalls.push(skillId);
681
- return [];
682
- },
683
- readFileContent: async () => null,
684
- toSlimSkill: async () => ({
685
- id: "contested-skill",
686
- name: "Skillssh Contested",
687
- description: "",
688
- kind: "catalog",
689
- origin: "skillssh",
690
- status: "available",
691
- category: "knowledge",
692
- slug: "contested-skill",
693
- sourceRepo: "",
694
- installs: 0,
695
- }),
696
- };
697
- mockClawhubProvider = {
698
- canHandle: () => true,
699
- listFiles: async (skillId: string) => {
700
- clawhubListFilesCalls.push(skillId);
701
- return [];
395
+ const http = mockHttp();
396
+ http.on("GET", "/v1/skills/", {
397
+ status: 200,
398
+ body: catalogBody([
399
+ catalogEntry("contested-skill", {
400
+ cadet: { "display-name": "Cadet Contested" },
401
+ }),
402
+ ]),
403
+ });
404
+ http.on("GET", "/v1/skills/contested-skill/files/", {
405
+ status: 200,
406
+ body: {
407
+ files: [{ path: "SKILL.md", name: "SKILL.md", size: 10 }],
702
408
  },
703
- readFileContent: async () => null,
704
- toSlimSkill: async () => ({
705
- id: "contested-skill",
706
- name: "Clawhub Contested",
707
- description: "",
708
- kind: "catalog",
709
- origin: "clawhub",
710
- status: "available",
711
- category: "knowledge",
712
- slug: "contested-skill",
713
- author: "",
714
- stars: 0,
715
- installs: 0,
716
- reports: 0,
717
- version: "",
718
- }),
719
- };
409
+ });
410
+ await getCatalog();
720
411
 
721
412
  const result = await getSkillFiles("contested-skill");
722
413
 
@@ -727,17 +418,8 @@ describe("getSkillFiles — provider chain fallback", () => {
727
418
  // Cadet provider should have been used
728
419
  expect(result.skill.origin).toBe("cadet");
729
420
  expect(result.skill.name).toBe("Cadet Contested");
730
- // Cadet was called, but skills.sh and clawhub were NOT called
731
- expect(cadetListFilesCalls).toEqual(["contested-skill"]);
732
- expect(skillsshListFilesCalls).toEqual([]);
733
- expect(clawhubListFilesCalls).toEqual([]);
421
+ // The chain stops on the first match: the clawhub CLI never spawned even
422
+ // though its canHandle claims every valid slug.
423
+ expect(clawhubCalls()).toEqual([]);
734
424
  });
735
425
  });
736
-
737
- // ---------------------------------------------------------------------------
738
- // Cleanup: ensure we don't leak temp dirs if a test fails mid-way.
739
- // ---------------------------------------------------------------------------
740
-
741
- afterEach(() => {
742
- // Nothing to clean up outside test scope — temp dirs are cleaned per-test.
743
- });