@xopcai/xopc 0.0.102 → 0.0.104

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 (995) hide show
  1. package/README.md +8 -5
  2. package/README.zh-CN.md +8 -5
  3. package/dist/_virtual/_rolldown/runtime.js +2 -3
  4. package/dist/browser-ext/manifest.json +1 -1
  5. package/dist/extensions/feishu/src/adapters/cli-login.d.ts +1 -1
  6. package/dist/extensions/feishu/src/adapters/cli-login.js +1 -1
  7. package/dist/extensions/feishu/src/adapters/cli-login.js.map +1 -1
  8. package/dist/extensions/feishu/src/adapters/gateway-setup.d.ts +2 -0
  9. package/dist/extensions/feishu/src/adapters/gateway-setup.js +225 -0
  10. package/dist/extensions/feishu/src/adapters/gateway-setup.js.map +1 -0
  11. package/dist/extensions/feishu/src/index.d.ts +8 -1
  12. package/dist/extensions/feishu/src/index.js +14 -1
  13. package/dist/extensions/feishu/src/index.js.map +1 -0
  14. package/dist/extensions/feishu/src/outbound/outbound-adapter.js +1 -1
  15. package/dist/extensions/feishu/src/plugin.d.ts +2 -1
  16. package/dist/extensions/feishu/src/plugin.js +2 -0
  17. package/dist/extensions/feishu/src/plugin.js.map +1 -1
  18. package/dist/extensions/feishu/src/streaming/streaming-adapter.js +1 -1
  19. package/dist/extensions/feishu/src/transport/webhook/monitor.js +2 -2
  20. package/dist/extensions/feishu/src/transport/webhook/monitor.js.map +1 -1
  21. package/dist/extensions/feishu/xopc.extension.json +66 -1
  22. package/dist/extensions/telegram/src/adapters/gateway-setup.d.ts +2 -0
  23. package/dist/extensions/telegram/src/adapters/gateway-setup.js +146 -0
  24. package/dist/extensions/telegram/src/adapters/gateway-setup.js.map +1 -0
  25. package/dist/extensions/telegram/src/adapters/security-adapter.js +1 -1
  26. package/dist/extensions/telegram/src/command-handler.js +1 -2
  27. package/dist/extensions/telegram/src/command-handler.js.map +1 -1
  28. package/dist/extensions/telegram/src/config-schema.js +2 -2
  29. package/dist/extensions/telegram/src/config-schema.js.map +1 -1
  30. package/dist/extensions/telegram/src/doctor.d.ts +1 -0
  31. package/dist/extensions/telegram/src/doctor.js +68 -0
  32. package/dist/extensions/telegram/src/doctor.js.map +1 -1
  33. package/dist/extensions/telegram/src/index.d.ts +8 -1
  34. package/dist/extensions/telegram/src/index.js +15 -2
  35. package/dist/extensions/telegram/src/index.js.map +1 -0
  36. package/dist/extensions/telegram/src/plugin.d.ts +13 -5
  37. package/dist/extensions/telegram/src/plugin.js +32 -12
  38. package/dist/extensions/telegram/src/plugin.js.map +1 -1
  39. package/dist/extensions/telegram/src/proxy-fetch.js +22 -5
  40. package/dist/extensions/telegram/src/proxy-fetch.js.map +1 -1
  41. package/dist/extensions/telegram/src/send-options.js +8 -5
  42. package/dist/extensions/telegram/src/send-options.js.map +1 -1
  43. package/dist/extensions/telegram/xopc.extension.json +412 -5
  44. package/dist/extensions/weixin/src/adapters/onboard-cli.js +2 -2
  45. package/dist/extensions/weixin/src/adapters/onboard-cli.js.map +1 -1
  46. package/dist/extensions/weixin/src/api/api.js +1 -1
  47. package/dist/extensions/weixin/src/index.d.ts +8 -0
  48. package/dist/extensions/weixin/src/index.js +12 -1
  49. package/dist/extensions/weixin/src/index.js.map +1 -0
  50. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  51. package/dist/extensions/weixin/src/plugin.d.ts +2 -1
  52. package/dist/extensions/weixin/src/plugin.js +77 -2
  53. package/dist/extensions/weixin/src/plugin.js.map +1 -1
  54. package/dist/extensions/weixin/xopc.extension.json +52 -0
  55. package/dist/gateway/static/root/assets/agents-CvsBrBfi.js +396 -0
  56. package/dist/gateway/static/root/assets/{apps-page-Uv4kOmDE.js → apps-page-L-IwQTe0.js} +1 -1
  57. package/dist/gateway/static/root/assets/browser-BLJWD7WI.js +8 -0
  58. package/dist/gateway/static/root/assets/channels-settings-D95KuPeP.js +1 -0
  59. package/dist/gateway/static/root/assets/cron-page-CfkWXDAI.js +1 -0
  60. package/dist/gateway/static/root/assets/{dist-DH4IuRV0.js → dist-C6vclgEL.js} +1 -1
  61. package/dist/gateway/static/root/assets/{extension-debug-page-BNkhvRQW.js → extension-debug-page-D4JYAbsX.js} +1 -1
  62. package/dist/gateway/static/root/assets/{extension-page-CcIGQah2.js → extension-page-_T62gi6e.js} +1 -1
  63. package/dist/gateway/static/root/assets/extension-settings-page-CkJbjyM-.js +1 -0
  64. package/dist/gateway/static/root/assets/{fetch-drJUxxKP.js → fetch-B5aiIguv.js} +1 -1
  65. package/dist/gateway/static/root/assets/gateway-startup-retry-DqmLXhs6.js +1 -0
  66. package/dist/gateway/static/root/assets/heartbeat-config-api-HwJV1K_Y.js +1 -0
  67. package/dist/gateway/static/root/assets/index-BPYKW7FB.css +1 -0
  68. package/dist/gateway/static/root/assets/index-DvTb6wNR.js +4845 -0
  69. package/dist/gateway/static/root/assets/{logs-page-CiG0m81R.js → logs-page-DsjtTjBy.js} +2 -2
  70. package/dist/gateway/static/root/assets/{note-detail-page-DG3DVFTf.js → note-detail-page-B2V7RhgD.js} +43 -43
  71. package/dist/gateway/static/root/assets/{note-time-DjlllCF3.js → note-time-BG8GCTr4.js} +1 -1
  72. package/dist/gateway/static/root/assets/notes-page-xrcVBQ6Z.js +1 -0
  73. package/dist/gateway/static/root/assets/schema-form-S-QUvhul.js +1 -0
  74. package/dist/gateway/static/root/assets/sessions-page-CrQer6Au.js +1 -0
  75. package/dist/gateway/static/root/assets/settings-advanced-gate-DujQl9c7.js +2 -0
  76. package/dist/gateway/static/root/assets/{settings-form-section-C3_sEFfD.js → settings-form-section-r1V7dRV6.js} +1 -1
  77. package/dist/gateway/static/root/assets/settings-page-C9nrONQ2.js +3 -0
  78. package/dist/gateway/static/root/assets/share-preview-page-DOFy0FNt.js +2 -0
  79. package/dist/gateway/static/root/assets/skills-page-DmTsrs_a.js +2 -0
  80. package/dist/gateway/static/root/assets/{theme-store-B6KXPHgK.js → theme-store-Bo3j5Ovv.js} +1 -1
  81. package/dist/gateway/static/root/assets/url-WgQIjFZu.js +3 -0
  82. package/dist/gateway/static/root/assets/voice-api-key-field-AjmUAlEQ.js +1 -0
  83. package/dist/gateway/static/root/assets/{workflow-page.utils-g57BRfEd.js → workflow-page.utils-DLEJ92gK.js} +1 -1
  84. package/dist/gateway/static/root/assets/workflows-page-BnjjKrM1.js +27 -0
  85. package/dist/gateway/static/root/index.html +6 -5
  86. package/dist/package.js +1 -1
  87. package/dist/src/agent/agent-manager.d.ts +18 -6
  88. package/dist/src/agent/agent-manager.js +60 -35
  89. package/dist/src/agent/agent-manager.js.map +1 -1
  90. package/dist/src/agent/builtin-agent-ids.d.ts +2 -0
  91. package/dist/src/agent/builtin-agent-ids.js +17 -0
  92. package/dist/src/agent/builtin-agent-ids.js.map +1 -0
  93. package/dist/src/agent/child-agent-factory.d.ts +4 -0
  94. package/dist/src/agent/child-agent-factory.js +28 -8
  95. package/dist/src/agent/child-agent-factory.js.map +1 -1
  96. package/dist/src/agent/context/workspace-seed.js +1 -1
  97. package/dist/src/agent/context/workspace-templates/AGENTS.md +23 -184
  98. package/dist/src/agent/embedded/run-turn.js +8 -2
  99. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  100. package/dist/src/agent/embedded/session-tool-result-guard.js +1 -1
  101. package/dist/src/agent/embedded/subscribe-session.js +33 -51
  102. package/dist/src/agent/embedded/subscribe-session.js.map +1 -1
  103. package/dist/src/agent/embedded/types.d.ts +36 -35
  104. package/dist/src/agent/fallback/candidates.js +1 -1
  105. package/dist/src/agent/fallback/candidates.js.map +1 -1
  106. package/dist/src/agent/inbound/attachment-pipeline.js +2 -2
  107. package/dist/src/agent/inbound/attachment-pipeline.js.map +1 -1
  108. package/dist/src/agent/inbound/inbound-loop.js +1 -1
  109. package/dist/src/agent/inbound/turn-dispatcher.d.ts +1 -0
  110. package/dist/src/agent/inbound/turn-dispatcher.js +24 -5
  111. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  112. package/dist/src/agent/models/manager.d.ts +1 -1
  113. package/dist/src/agent/models/manager.js +1 -1
  114. package/dist/src/agent/models/manager.js.map +1 -1
  115. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +1 -1
  116. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +1 -1
  117. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +1 -1
  118. package/dist/src/agent/prompt/sections/tooling.js +4 -0
  119. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  120. package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -0
  121. package/dist/src/agent/service/direct-turn-helpers.js +1 -1
  122. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  123. package/dist/src/agent/service/process-direct-streaming.d.ts +1 -0
  124. package/dist/src/agent/service/process-direct-streaming.js +35 -18
  125. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  126. package/dist/src/agent/service-inbound-utils.d.ts +0 -1
  127. package/dist/src/agent/service-inbound-utils.js +1 -17
  128. package/dist/src/agent/service-inbound-utils.js.map +1 -1
  129. package/dist/src/agent/service.d.ts +4 -4
  130. package/dist/src/agent/service.js +27 -15
  131. package/dist/src/agent/service.js.map +1 -1
  132. package/dist/src/agent/session/session-config-service.d.ts +1 -0
  133. package/dist/src/agent/session/session-config-service.js +9 -1
  134. package/dist/src/agent/session/session-config-service.js.map +1 -1
  135. package/dist/src/agent/session/session-inspector.d.ts +2 -1
  136. package/dist/src/agent/session/session-inspector.js +4 -0
  137. package/dist/src/agent/session/session-inspector.js.map +1 -1
  138. package/dist/src/agent/skills/config.js +1 -3
  139. package/dist/src/agent/skills/config.js.map +1 -1
  140. package/dist/src/agent/skills/format-skills-prompt.d.ts +1 -0
  141. package/dist/src/agent/skills/format-skills-prompt.js +3 -2
  142. package/dist/src/agent/skills/format-skills-prompt.js.map +1 -1
  143. package/dist/src/agent/skills/hub-pull.js +1 -1
  144. package/dist/src/agent/skills/index.js +20 -5
  145. package/dist/src/agent/skills/index.js.map +1 -1
  146. package/dist/src/agent/skills/installer.js +14 -27
  147. package/dist/src/agent/skills/installer.js.map +1 -1
  148. package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +11 -1
  149. package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js.map +1 -1
  150. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +18 -4
  151. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
  152. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +11 -2
  153. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js.map +1 -1
  154. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +2 -2
  155. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js.map +1 -1
  156. package/dist/src/agent/skills/skill-manager.d.ts +4 -1
  157. package/dist/src/agent/skills/skill-manager.js +3 -3
  158. package/dist/src/agent/skills/skill-manager.js.map +1 -1
  159. package/dist/src/agent/skills/skill-view-path.d.ts +1 -17
  160. package/dist/src/agent/skills/skill-view-path.js +3 -66
  161. package/dist/src/agent/skills/skill-view-path.js.map +1 -1
  162. package/dist/src/agent/skills/test-framework.js +2 -3
  163. package/dist/src/agent/skills/test-framework.js.map +1 -1
  164. package/dist/src/agent/streaming/reasoning-visibility-sse.js +1 -0
  165. package/dist/src/agent/streaming/reasoning-visibility-sse.js.map +1 -1
  166. package/dist/src/agent/tool-manuals/browser.d.ts +1 -0
  167. package/{skills/browser/SKILL.md → dist/src/agent/tool-manuals/browser.js} +51 -54
  168. package/dist/src/agent/tool-manuals/browser.js.map +1 -0
  169. package/dist/src/agent/tool-manuals/index.d.ts +10 -0
  170. package/dist/src/agent/tool-manuals/index.js +28 -0
  171. package/dist/src/agent/tool-manuals/index.js.map +1 -0
  172. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -1
  173. package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
  174. package/dist/src/agent/tools/factory.js +7 -5
  175. package/dist/src/agent/tools/factory.js.map +1 -1
  176. package/dist/src/agent/tools/index.d.ts +1 -0
  177. package/dist/src/agent/tools/index.js +5 -4
  178. package/dist/src/agent/tools/send-media.js +1 -2
  179. package/dist/src/agent/tools/send-media.js.map +1 -1
  180. package/dist/src/agent/tools/session-search-tool.js +1 -1
  181. package/dist/src/agent/tools/shell.js +1 -1
  182. package/dist/src/agent/tools/skills-tools.js +37 -8
  183. package/dist/src/agent/tools/skills-tools.js.map +1 -1
  184. package/dist/src/agent/tools/tool-manual-tool.d.ts +6 -0
  185. package/dist/src/agent/tools/tool-manual-tool.js +34 -0
  186. package/dist/src/agent/tools/tool-manual-tool.js.map +1 -0
  187. package/dist/src/agent/tools/web-extract.js +2 -2
  188. package/dist/src/agent/tools/web.js +1 -1
  189. package/dist/src/agent/workflow/catalog.d.ts +7 -2
  190. package/dist/src/agent/workflow/catalog.js +66 -25
  191. package/dist/src/agent/workflow/catalog.js.map +1 -1
  192. package/dist/src/agent/workflow/subagent-runner.d.ts +3 -0
  193. package/dist/src/agent/workflow/subagent-runner.js +50 -4
  194. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  195. package/dist/src/agent/workflow/types.d.ts +10 -0
  196. package/dist/src/auth/credentials.d.ts +7 -0
  197. package/dist/src/auth/credentials.js +45 -7
  198. package/dist/src/auth/credentials.js.map +1 -1
  199. package/dist/src/auth/index.d.ts +1 -1
  200. package/dist/src/auth/index.js.map +1 -1
  201. package/dist/src/auth/oauth/github-copilot.d.ts +1 -1
  202. package/dist/src/auth/oauth/google-antigravity.d.ts +1 -3
  203. package/dist/src/auth/oauth/google-antigravity.js +1 -1
  204. package/dist/src/auth/oauth/google-gemini-cli.d.ts +1 -3
  205. package/dist/src/auth/oauth/google-gemini-cli.js +1 -1
  206. package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/google-antigravity.js +3 -5
  207. package/dist/src/auth/oauth/google-oauth/google-antigravity.js.map +1 -0
  208. package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/google-gemini-cli.js +4 -5
  209. package/dist/src/auth/oauth/google-oauth/google-gemini-cli.js.map +1 -0
  210. package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/oauth-page.js +12 -4
  211. package/dist/src/auth/oauth/google-oauth/oauth-page.js.map +1 -0
  212. package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/pkce.d.ts +1 -1
  213. package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/pkce.js +2 -2
  214. package/dist/src/auth/oauth/google-oauth/pkce.js.map +1 -0
  215. package/dist/src/auth/oauth/index.js +2 -2
  216. package/dist/src/auth/oauth/kimi-coding.d.ts +1 -1
  217. package/dist/src/auth/oauth/kimi-coding.js +1 -1
  218. package/dist/src/auth/oauth/kimi-coding.js.map +1 -1
  219. package/dist/src/auth/oauth/minimax-cn.js +1 -1
  220. package/dist/src/auth/oauth/minimax-cn.js.map +1 -1
  221. package/dist/src/auth/oauth/minimax.js +1 -1
  222. package/dist/src/auth/oauth/minimax.js.map +1 -1
  223. package/dist/src/auth/oauth/openai-codex.d.ts +7 -2
  224. package/dist/src/auth/oauth/openai-codex.js +318 -1
  225. package/dist/src/auth/oauth/openai-codex.js.map +1 -0
  226. package/dist/src/auth/profiles/store.js +3 -2
  227. package/dist/src/auth/profiles/store.js.map +1 -1
  228. package/dist/src/browser/actions/extension-registry-bridge.js +1 -1
  229. package/dist/src/browser/actions/registry.js +2 -2
  230. package/dist/src/browser/cdp-local-launcher.js +1 -1
  231. package/dist/src/browser/index.js +3 -3
  232. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  233. package/dist/src/browser/providers/cloakbrowser.js +1 -1
  234. package/dist/src/channels/attachments/attachment-classifiers.d.ts +1 -0
  235. package/dist/src/channels/attachments/attachment-classifiers.js +13 -2
  236. package/dist/src/channels/attachments/attachment-classifiers.js.map +1 -1
  237. package/dist/src/channels/catalog/channel-catalog-service.d.ts +11 -0
  238. package/dist/src/channels/catalog/channel-catalog-service.js +168 -0
  239. package/dist/src/channels/catalog/channel-catalog-service.js.map +1 -0
  240. package/dist/src/channels/catalog/channel-catalog-types.d.ts +22 -0
  241. package/dist/src/channels/catalog/channel-catalog-types.js +1 -0
  242. package/dist/src/channels/dock.d.ts +0 -7
  243. package/dist/src/channels/dock.js +1 -21
  244. package/dist/src/channels/index.d.ts +1 -3
  245. package/dist/src/channels/index.js +1 -5
  246. package/dist/src/channels/lifecycle-supervisor.d.ts +1 -0
  247. package/dist/src/channels/lifecycle-supervisor.js +11 -0
  248. package/dist/src/channels/lifecycle-supervisor.js.map +1 -1
  249. package/dist/src/channels/manager.d.ts +1 -0
  250. package/dist/src/channels/manager.js +3 -0
  251. package/dist/src/channels/manager.js.map +1 -1
  252. package/dist/src/channels/pairing/pairing-channel.d.ts +2 -3
  253. package/dist/src/channels/pairing/pairing-messages.js +1 -1
  254. package/dist/src/channels/pairing/pairing-messages.js.map +1 -1
  255. package/dist/src/channels/pairing/pairing-service.d.ts +1 -1
  256. package/dist/src/channels/pairing/pairing-service.js +8 -27
  257. package/dist/src/channels/pairing/pairing-service.js.map +1 -1
  258. package/dist/src/channels/plugin-types.d.ts +3 -1
  259. package/dist/src/channels/plugins/types.adapters.d.ts +55 -2
  260. package/dist/src/channels/telegram/index.js +1 -1
  261. package/dist/src/chat-commands/builtins/config.js +4 -4
  262. package/dist/src/chat-commands/builtins/config.js.map +1 -1
  263. package/dist/src/chat-commands/builtins/model.js +2 -2
  264. package/dist/src/chat-commands/builtins/model.js.map +1 -1
  265. package/dist/src/chat-commands/config-paths.js +1 -1
  266. package/dist/src/chat-commands/config-paths.js.map +1 -1
  267. package/dist/src/chat-commands/context.js +1 -1
  268. package/dist/src/chat-commands/context.js.map +1 -1
  269. package/dist/src/cli/bin.js +1 -1
  270. package/dist/src/cli/command-manifest.js +2 -2
  271. package/dist/src/cli/command-manifest.js.map +1 -1
  272. package/dist/src/cli/commands/agent.js +2 -2
  273. package/dist/src/cli/commands/agent.js.map +1 -1
  274. package/dist/src/cli/commands/agents.js +2 -4
  275. package/dist/src/cli/commands/agents.js.map +1 -1
  276. package/dist/src/cli/commands/auth.js +40 -52
  277. package/dist/src/cli/commands/auth.js.map +1 -1
  278. package/dist/src/cli/commands/browser-cli-helpers.js +1 -1
  279. package/dist/src/cli/commands/channels.d.ts +1 -5
  280. package/dist/src/cli/commands/channels.js +115 -281
  281. package/dist/src/cli/commands/channels.js.map +1 -1
  282. package/dist/src/cli/commands/config.js +2 -2
  283. package/dist/src/cli/commands/config.js.map +1 -1
  284. package/dist/src/cli/commands/doctor/checks/channel-config.js +16 -69
  285. package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
  286. package/dist/src/cli/commands/doctor/checks/channel-pairing-pending.js +6 -4
  287. package/dist/src/cli/commands/doctor/checks/channel-pairing-pending.js.map +1 -1
  288. package/dist/src/cli/commands/doctor/checks/channel-plugins.js +2 -2
  289. package/dist/src/cli/commands/doctor/checks/channel-plugins.js.map +1 -1
  290. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  291. package/dist/src/cli/commands/doctor/checks/provider-auth.js +13 -9
  292. package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -1
  293. package/dist/src/cli/commands/extension-dev.js +2 -1
  294. package/dist/src/cli/commands/extension-dev.js.map +1 -1
  295. package/dist/src/cli/commands/extension-marketplace.js +2 -1
  296. package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
  297. package/dist/src/cli/commands/extension-pack.js +2 -1
  298. package/dist/src/cli/commands/extension-pack.js.map +1 -1
  299. package/dist/src/cli/commands/models.js +192 -54
  300. package/dist/src/cli/commands/models.js.map +1 -1
  301. package/dist/src/cli/commands/onboard/channels/index.js +1 -1
  302. package/dist/src/cli/commands/onboard/channels/index.js.map +1 -1
  303. package/dist/src/cli/commands/onboard/channels/registry.d.ts +2 -1
  304. package/dist/src/cli/commands/onboard/channels/registry.js +32 -8
  305. package/dist/src/cli/commands/onboard/channels/registry.js.map +1 -1
  306. package/dist/src/cli/commands/onboard/model.d.ts +1 -4
  307. package/dist/src/cli/commands/onboard/model.js +257 -184
  308. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  309. package/dist/src/cli/commands/onboard.js +4 -6
  310. package/dist/src/cli/commands/onboard.js.map +1 -1
  311. package/dist/src/cli/commands/setup-shared/runner.d.ts +1 -1
  312. package/dist/src/cli/commands/setup-shared/runner.js.map +1 -1
  313. package/dist/src/cli/commands/setup-shared/types.d.ts +1 -1
  314. package/dist/src/cli/commands/setup-shared/types.js.map +1 -1
  315. package/dist/src/cli/commands/tui.js +13 -5
  316. package/dist/src/cli/commands/tui.js.map +1 -1
  317. package/dist/src/cli/extension-cli-register.js +1 -1
  318. package/dist/src/cli/utils/oauth-login.d.ts +17 -0
  319. package/dist/src/cli/utils/oauth-login.js +93 -0
  320. package/dist/src/cli/utils/oauth-login.js.map +1 -0
  321. package/dist/src/cli/utils/oauth-providers.js +2 -2
  322. package/dist/src/commands/agents.config.d.ts +3 -3
  323. package/dist/src/commands/agents.config.js +7 -7
  324. package/dist/src/commands/agents.config.js.map +1 -1
  325. package/dist/src/config/agent-profile.d.ts +1 -1
  326. package/dist/src/config/agent-profile.js +6 -2
  327. package/dist/src/config/agent-profile.js.map +1 -1
  328. package/dist/src/config/agent-typed-models.d.ts +2 -2
  329. package/dist/src/config/agent-typed-models.js +13 -2
  330. package/dist/src/config/agent-typed-models.js.map +1 -1
  331. package/dist/src/config/index.js +3 -3
  332. package/dist/src/config/integration.d.ts +1 -1
  333. package/dist/src/config/loader.d.ts +0 -1
  334. package/dist/src/config/loader.js +4 -9
  335. package/dist/src/config/loader.js.map +1 -1
  336. package/dist/src/config/models-json.d.ts +6 -6
  337. package/dist/src/config/rules.js +2 -12
  338. package/dist/src/config/rules.js.map +1 -1
  339. package/dist/src/config/schema.d.ts +74 -47
  340. package/dist/src/config/schema.js +28 -66
  341. package/dist/src/config/schema.js.map +1 -1
  342. package/dist/src/config/validate-channel-configs.d.ts +0 -3
  343. package/dist/src/config/validate-channel-configs.js +29 -10
  344. package/dist/src/config/validate-channel-configs.js.map +1 -1
  345. package/dist/src/cron/executor.js +1 -4
  346. package/dist/src/cron/executor.js.map +1 -1
  347. package/dist/src/extensions/activation-context.js +3 -1
  348. package/dist/src/extensions/activation-context.js.map +1 -1
  349. package/dist/src/extensions/activation-planner.js +12 -0
  350. package/dist/src/extensions/activation-planner.js.map +1 -1
  351. package/dist/src/extensions/api.d.ts +5 -1
  352. package/dist/src/extensions/api.js +12 -0
  353. package/dist/src/extensions/api.js.map +1 -1
  354. package/dist/src/extensions/discover-extensions.js +17 -13
  355. package/dist/src/extensions/discover-extensions.js.map +1 -1
  356. package/dist/src/extensions/extension-metadata-snapshot.js +11 -5
  357. package/dist/src/extensions/extension-metadata-snapshot.js.map +1 -1
  358. package/dist/src/extensions/index.js +12 -4
  359. package/dist/src/extensions/index.js.map +1 -0
  360. package/dist/src/extensions/loader.d.ts +5 -1
  361. package/dist/src/extensions/loader.js +12 -11
  362. package/dist/src/extensions/loader.js.map +1 -1
  363. package/dist/src/extensions/manifest-registry.js +98 -93
  364. package/dist/src/extensions/manifest-registry.js.map +1 -1
  365. package/dist/src/extensions/normalize-manifest.js +91 -15
  366. package/dist/src/extensions/normalize-manifest.js.map +1 -1
  367. package/dist/src/extensions/sdk/index.js +1 -1
  368. package/dist/src/extensions/sdk/testing.js +4 -0
  369. package/dist/src/extensions/sdk/testing.js.map +1 -1
  370. package/dist/src/extensions/types/core.d.ts +32 -1
  371. package/dist/src/extensions/types/manifest.d.ts +60 -0
  372. package/dist/src/extensions/types/tui.d.ts +414 -5
  373. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  374. package/dist/src/gateway/agent-builtin-tools.js +16 -0
  375. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  376. package/dist/src/gateway/agent-run-relay.d.ts +2 -3
  377. package/dist/src/gateway/agent-run-relay.js +10 -3
  378. package/dist/src/gateway/agent-run-relay.js.map +1 -1
  379. package/dist/src/gateway/agents-admin.d.ts +32 -19
  380. package/dist/src/gateway/agents-admin.js +113 -93
  381. package/dist/src/gateway/agents-admin.js.map +1 -1
  382. package/dist/src/gateway/chat-stream/mapper.d.ts +34 -0
  383. package/dist/src/gateway/chat-stream/mapper.js +244 -0
  384. package/dist/src/gateway/chat-stream/mapper.js.map +1 -0
  385. package/dist/src/gateway/chat-stream/protocol.d.ts +100 -0
  386. package/dist/src/gateway/chat-stream/protocol.js +1 -0
  387. package/dist/src/gateway/hono/lib/agent-model.d.ts +4 -4
  388. package/dist/src/gateway/hono/lib/agent-model.js +13 -11
  389. package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
  390. package/dist/src/gateway/hono/lib/config-payload.d.ts +19 -7
  391. package/dist/src/gateway/hono/lib/config-payload.js +16 -15
  392. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  393. package/dist/src/gateway/hono/oauth-async.js +2 -2
  394. package/dist/src/gateway/hono/oauth.js +2 -2
  395. package/dist/src/gateway/hono/routes/agents.js +83 -48
  396. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  397. package/dist/src/gateway/hono/routes/channels.js +134 -214
  398. package/dist/src/gateway/hono/routes/channels.js.map +1 -1
  399. package/dist/src/gateway/hono/routes/commands-skills.js +10 -4
  400. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  401. package/dist/src/gateway/hono/routes/config-patch/agents.js +26 -13
  402. package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
  403. package/dist/src/gateway/hono/routes/config-patch/channels.d.ts +1 -11
  404. package/dist/src/gateway/hono/routes/config-patch/channels.js +18 -165
  405. package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
  406. package/dist/src/gateway/hono/routes/config.js +5 -2
  407. package/dist/src/gateway/hono/routes/config.js.map +1 -1
  408. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  409. package/dist/src/gateway/hono/routes/lazy-bundles.js +13 -1
  410. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  411. package/dist/src/gateway/hono/routes/models.js +25 -5
  412. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  413. package/dist/src/gateway/hono/routes/public-gateway.js +2 -4
  414. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  415. package/dist/src/gateway/hono/routes/sessions.js +179 -0
  416. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  417. package/dist/src/gateway/hono/routes/tui.d.ts +3 -0
  418. package/dist/src/gateway/hono/routes/tui.js +16 -0
  419. package/dist/src/gateway/hono/routes/tui.js.map +1 -0
  420. package/dist/src/gateway/hono/routes/workflows.js +25 -1
  421. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  422. package/dist/src/gateway/hono/sse.d.ts +5 -7
  423. package/dist/src/gateway/hono/sse.js +21 -38
  424. package/dist/src/gateway/hono/sse.js.map +1 -1
  425. package/dist/src/gateway/protocol.js.map +1 -1
  426. package/dist/src/gateway/service/agent-runner.d.ts +2 -4
  427. package/dist/src/gateway/service/agent-runner.js +1 -1
  428. package/dist/src/gateway/service/agent-runner.js.map +1 -1
  429. package/dist/src/gateway/service/marketplace-service.d.ts +4 -3
  430. package/dist/src/gateway/service/marketplace-service.js +7 -4
  431. package/dist/src/gateway/service/marketplace-service.js.map +1 -1
  432. package/dist/src/gateway/service/run-gateway-agent.d.ts +2 -6
  433. package/dist/src/gateway/service/run-gateway-agent.js +63 -36
  434. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  435. package/dist/src/gateway/service/sessions-api.d.ts +19 -0
  436. package/dist/src/gateway/service/sessions-api.js +12 -0
  437. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  438. package/dist/src/gateway/service.d.ts +6 -0
  439. package/dist/src/gateway/service.js +73 -57
  440. package/dist/src/gateway/service.js.map +1 -1
  441. package/dist/src/mcp/channel-bridge.js +1 -1
  442. package/dist/src/media/store.js +3 -0
  443. package/dist/src/media/store.js.map +1 -1
  444. package/dist/src/notes/service.js +1 -1
  445. package/dist/src/notes/service.js.map +1 -1
  446. package/dist/src/project-trust/trust-store.d.ts +30 -0
  447. package/dist/src/project-trust/trust-store.js +194 -0
  448. package/dist/src/project-trust/trust-store.js.map +1 -0
  449. package/dist/src/providers/index.d.ts +4 -4
  450. package/dist/src/providers/index.js +41 -22
  451. package/dist/src/providers/index.js.map +1 -1
  452. package/dist/src/providers/presentation.d.ts +34 -0
  453. package/dist/src/providers/presentation.js +162 -0
  454. package/dist/src/providers/presentation.js.map +1 -0
  455. package/dist/src/routing/resolve-route.d.ts +0 -3
  456. package/dist/src/routing/resolve-route.js.map +1 -1
  457. package/dist/src/routing/resolve-tui-session-key.d.ts +2 -0
  458. package/dist/src/routing/resolve-tui-session-key.js +8 -3
  459. package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
  460. package/dist/src/session/client-history.d.ts +32 -0
  461. package/dist/src/session/client-history.js +232 -1
  462. package/dist/src/session/client-history.js.map +1 -1
  463. package/dist/src/session/manager.d.ts +37 -4
  464. package/dist/src/session/manager.js +39 -15
  465. package/dist/src/session/manager.js.map +1 -1
  466. package/dist/src/session/session-context-for-llm.d.ts +93 -1
  467. package/dist/src/session/session-context-for-llm.js +105 -2
  468. package/dist/src/session/session-context-for-llm.js.map +1 -1
  469. package/dist/src/session/store.d.ts +37 -0
  470. package/dist/src/session/store.js +127 -2
  471. package/dist/src/session/store.js.map +1 -1
  472. package/dist/src/session/stored-rows-to-file-entries.js +37 -1
  473. package/dist/src/session/stored-rows-to-file-entries.js.map +1 -1
  474. package/dist/src/session/types.d.ts +14 -1
  475. package/dist/src/session/types.js.map +1 -1
  476. package/dist/src/share/share-thumbnail.js +1 -1
  477. package/dist/src/storage/sqlite/migrations/004_add_session_type_metadata.sql +15 -0
  478. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  479. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  480. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  481. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  482. package/dist/src/storage/sqlite/row-mappers.d.ts +14 -1
  483. package/dist/src/storage/sqlite/row-mappers.js +14 -1
  484. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  485. package/dist/src/storage/sqlite/schema.js +1 -1
  486. package/dist/src/storage/sqlite/session-metadata.js +1 -0
  487. package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
  488. package/dist/src/storage/sqlite/session-repository.js +52 -25
  489. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  490. package/dist/src/tui/backends/embedded-backend.d.ts +53 -4
  491. package/dist/src/tui/backends/embedded-backend.js +227 -39
  492. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  493. package/dist/src/tui/backends/gateway-sse-backend.d.ts +59 -3
  494. package/dist/src/tui/backends/gateway-sse-backend.js +416 -26
  495. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  496. package/dist/src/tui/chat-history.d.ts +5 -1
  497. package/dist/src/tui/chat-history.js +78 -8
  498. package/dist/src/tui/chat-history.js.map +1 -1
  499. package/dist/src/tui/clipboard-text.d.ts +5 -0
  500. package/dist/src/tui/clipboard-text.js +46 -0
  501. package/dist/src/tui/clipboard-text.js.map +1 -0
  502. package/dist/src/tui/components/assistant-message.d.ts +19 -3
  503. package/dist/src/tui/components/assistant-message.js +115 -9
  504. package/dist/src/tui/components/assistant-message.js.map +1 -1
  505. package/dist/src/tui/components/bash-execution.d.ts +3 -2
  506. package/dist/src/tui/components/bash-execution.js +31 -3
  507. package/dist/src/tui/components/bash-execution.js.map +1 -1
  508. package/dist/src/tui/components/bash-summary.d.ts +23 -0
  509. package/dist/src/tui/components/bash-summary.js +87 -0
  510. package/dist/src/tui/components/bash-summary.js.map +1 -0
  511. package/dist/src/tui/components/branch-message-summary.d.ts +17 -0
  512. package/dist/src/tui/components/branch-message-summary.js +43 -0
  513. package/dist/src/tui/components/branch-message-summary.js.map +1 -0
  514. package/dist/src/tui/components/branch-summary.d.ts +13 -0
  515. package/dist/src/tui/components/branch-summary.js +51 -0
  516. package/dist/src/tui/components/branch-summary.js.map +1 -0
  517. package/dist/src/tui/components/chat-log.d.ts +46 -6
  518. package/dist/src/tui/components/chat-log.js +183 -21
  519. package/dist/src/tui/components/chat-log.js.map +1 -1
  520. package/dist/src/tui/components/compaction-summary.d.ts +13 -0
  521. package/dist/src/tui/components/compaction-summary.js +46 -0
  522. package/dist/src/tui/components/compaction-summary.js.map +1 -0
  523. package/dist/src/tui/components/custom-editor.d.ts +1 -0
  524. package/dist/src/tui/components/custom-editor.js +2 -0
  525. package/dist/src/tui/components/custom-editor.js.map +1 -1
  526. package/dist/src/tui/components/custom-message.d.ts +23 -0
  527. package/dist/src/tui/components/custom-message.js +65 -0
  528. package/dist/src/tui/components/custom-message.js.map +1 -0
  529. package/dist/src/tui/components/extension-dialog.d.ts +42 -0
  530. package/dist/src/tui/components/extension-dialog.js +127 -0
  531. package/dist/src/tui/components/extension-dialog.js.map +1 -0
  532. package/dist/src/tui/components/scoped-models-selector.d.ts +7 -2
  533. package/dist/src/tui/components/scoped-models-selector.js +89 -16
  534. package/dist/src/tui/components/scoped-models-selector.js.map +1 -1
  535. package/dist/src/tui/components/searchable-select-list.d.ts +30 -3
  536. package/dist/src/tui/components/searchable-select-list.js +82 -10
  537. package/dist/src/tui/components/searchable-select-list.js.map +1 -1
  538. package/dist/src/tui/components/session-selector.d.ts +18 -4
  539. package/dist/src/tui/components/session-selector.js +207 -40
  540. package/dist/src/tui/components/session-selector.js.map +1 -1
  541. package/dist/src/tui/components/settings-selector.d.ts +6 -2
  542. package/dist/src/tui/components/settings-selector.js +126 -7
  543. package/dist/src/tui/components/settings-selector.js.map +1 -1
  544. package/dist/src/tui/components/thinking-selector.d.ts +12 -0
  545. package/dist/src/tui/components/thinking-selector.js +48 -0
  546. package/dist/src/tui/components/thinking-selector.js.map +1 -0
  547. package/dist/src/tui/components/tool-execution.d.ts +57 -3
  548. package/dist/src/tui/components/tool-execution.js +378 -28
  549. package/dist/src/tui/components/tool-execution.js.map +1 -1
  550. package/dist/src/tui/components/tui-bottom-bar.d.ts +9 -1
  551. package/dist/src/tui/components/tui-bottom-bar.js +56 -11
  552. package/dist/src/tui/components/tui-bottom-bar.js.map +1 -1
  553. package/dist/src/tui/components/tui-header.d.ts +9 -2
  554. package/dist/src/tui/components/tui-header.js +25 -5
  555. package/dist/src/tui/components/tui-header.js.map +1 -1
  556. package/dist/src/tui/components/user-message.d.ts +4 -2
  557. package/dist/src/tui/components/user-message.js +42 -9
  558. package/dist/src/tui/components/user-message.js.map +1 -1
  559. package/dist/src/tui/components/visual-truncate.d.ts +11 -0
  560. package/dist/src/tui/components/visual-truncate.js +27 -0
  561. package/dist/src/tui/components/visual-truncate.js.map +1 -0
  562. package/dist/src/tui/extension-host/autocomplete.d.ts +43 -0
  563. package/dist/src/tui/extension-host/autocomplete.js +116 -0
  564. package/dist/src/tui/extension-host/autocomplete.js.map +1 -0
  565. package/dist/src/tui/extension-host/host.d.ts +31 -1
  566. package/dist/src/tui/extension-host/host.js +123 -6
  567. package/dist/src/tui/extension-host/host.js.map +1 -1
  568. package/dist/src/tui/extension-host/load-extensions.d.ts +6 -1
  569. package/dist/src/tui/extension-host/load-extensions.js +4 -3
  570. package/dist/src/tui/extension-host/load-extensions.js.map +1 -1
  571. package/dist/src/tui/extension-host/runtime-context.d.ts +21 -0
  572. package/dist/src/tui/extension-host/runtime-context.js +152 -0
  573. package/dist/src/tui/extension-host/runtime-context.js.map +1 -0
  574. package/dist/src/tui/extension-host/runtime.d.ts +52 -4
  575. package/dist/src/tui/extension-host/runtime.js +547 -85
  576. package/dist/src/tui/extension-host/runtime.js.map +1 -1
  577. package/dist/src/tui/extension-host/surface.d.ts +20 -0
  578. package/dist/src/tui/extension-host/surface.js +30 -6
  579. package/dist/src/tui/extension-host/surface.js.map +1 -1
  580. package/dist/src/tui/extension-host/tool-renderers.d.ts +6 -3
  581. package/dist/src/tui/extension-host/tool-renderers.js +43 -5
  582. package/dist/src/tui/extension-host/tool-renderers.js.map +1 -1
  583. package/dist/src/tui/format-tui-hotkeys.d.ts +12 -2
  584. package/dist/src/tui/format-tui-hotkeys.js +22 -5
  585. package/dist/src/tui/format-tui-hotkeys.js.map +1 -1
  586. package/dist/src/tui/tui-agent-events.d.ts +8 -6
  587. package/dist/src/tui/tui-agent-events.js +200 -59
  588. package/dist/src/tui/tui-agent-events.js.map +1 -1
  589. package/dist/src/tui/tui-backend.d.ts +169 -3
  590. package/dist/src/tui/tui-command-formatters.d.ts +76 -0
  591. package/dist/src/tui/tui-command-formatters.js +594 -0
  592. package/dist/src/tui/tui-command-formatters.js.map +1 -0
  593. package/dist/src/tui/tui-commands.d.ts +57 -7
  594. package/dist/src/tui/tui-commands.js +639 -43
  595. package/dist/src/tui/tui-commands.js.map +1 -1
  596. package/dist/src/tui/tui-context-usage.d.ts +1 -1
  597. package/dist/src/tui/tui-context-usage.js +9 -1
  598. package/dist/src/tui/tui-context-usage.js.map +1 -1
  599. package/dist/src/tui/tui-extension-user-message.d.ts +8 -0
  600. package/dist/src/tui/tui-extension-user-message.js +32 -0
  601. package/dist/src/tui/tui-extension-user-message.js.map +1 -0
  602. package/dist/src/tui/tui-follow-up-queue.d.ts +9 -0
  603. package/dist/src/tui/tui-follow-up-queue.js +18 -0
  604. package/dist/src/tui/tui-follow-up-queue.js.map +1 -0
  605. package/dist/src/tui/tui-local-shell.d.ts +11 -1
  606. package/dist/src/tui/tui-local-shell.js +50 -8
  607. package/dist/src/tui/tui-local-shell.js.map +1 -1
  608. package/dist/src/tui/tui-model-picker.d.ts +26 -0
  609. package/dist/src/tui/tui-model-picker.js +152 -0
  610. package/dist/src/tui/tui-model-picker.js.map +1 -0
  611. package/dist/src/tui/tui-oauth-login.d.ts +16 -0
  612. package/dist/src/tui/tui-oauth-login.js +189 -0
  613. package/dist/src/tui/tui-oauth-login.js.map +1 -0
  614. package/dist/src/tui/tui-overlays.d.ts +3 -3
  615. package/dist/src/tui/tui-overlays.js +6 -7
  616. package/dist/src/tui/tui-overlays.js.map +1 -1
  617. package/dist/src/tui/tui-picker-overlay.d.ts +27 -32
  618. package/dist/src/tui/tui-picker-overlay.js +340 -30
  619. package/dist/src/tui/tui-picker-overlay.js.map +1 -1
  620. package/dist/src/tui/tui-picker-services.d.ts +41 -0
  621. package/dist/src/tui/tui-picker-services.js +1 -0
  622. package/dist/src/tui/tui-run-state.d.ts +11 -0
  623. package/dist/src/tui/tui-run-state.js +114 -0
  624. package/dist/src/tui/tui-run-state.js.map +1 -0
  625. package/dist/src/tui/tui-runtime-hints.d.ts +4 -0
  626. package/dist/src/tui/tui-runtime-hints.js +18 -0
  627. package/dist/src/tui/tui-runtime-hints.js.map +1 -0
  628. package/dist/src/tui/tui-scoped-models.d.ts +1 -1
  629. package/dist/src/tui/tui-scoped-models.js +2 -2
  630. package/dist/src/tui/tui-scoped-models.js.map +1 -1
  631. package/dist/src/tui/tui-session-actions.d.ts +5 -3
  632. package/dist/src/tui/tui-session-actions.js +21 -9
  633. package/dist/src/tui/tui-session-actions.js.map +1 -1
  634. package/dist/src/tui/tui-session-format.d.ts +4 -1
  635. package/dist/src/tui/tui-session-format.js +17 -3
  636. package/dist/src/tui/tui-session-format.js.map +1 -1
  637. package/dist/src/tui/tui-session-snapshot.d.ts +82 -0
  638. package/dist/src/tui/tui-session-snapshot.js +184 -0
  639. package/dist/src/tui/tui-session-snapshot.js.map +1 -0
  640. package/dist/src/tui/tui-session-stats.d.ts +3 -0
  641. package/dist/src/tui/tui-session-stats.js +59 -0
  642. package/dist/src/tui/tui-session-stats.js.map +1 -0
  643. package/dist/src/tui/tui-settings.d.ts +21 -0
  644. package/dist/src/tui/tui-settings.js +28 -1
  645. package/dist/src/tui/tui-settings.js.map +1 -1
  646. package/dist/src/tui/tui-skills-autocomplete.js +1 -1
  647. package/dist/src/tui/tui-skills-autocomplete.js.map +1 -1
  648. package/dist/src/tui/tui-startup-resources.d.ts +3 -0
  649. package/dist/src/tui/tui-startup-resources.js +39 -0
  650. package/dist/src/tui/tui-startup-resources.js.map +1 -0
  651. package/dist/src/tui/tui-startup-text.d.ts +10 -0
  652. package/dist/src/tui/tui-startup-text.js +58 -0
  653. package/dist/src/tui/tui-startup-text.js.map +1 -0
  654. package/dist/src/tui/tui-stdio-filter.d.ts +1 -0
  655. package/dist/src/tui/tui-stdio-filter.js +11 -7
  656. package/dist/src/tui/tui-stdio-filter.js.map +1 -1
  657. package/dist/src/tui/tui-submit.d.ts +2 -0
  658. package/dist/src/tui/tui-submit.js +2 -1
  659. package/dist/src/tui/tui-submit.js.map +1 -1
  660. package/dist/src/tui/tui-tool-diff.js +61 -7
  661. package/dist/src/tui/tui-tool-diff.js.map +1 -1
  662. package/dist/src/tui/tui-tool-result.d.ts +17 -0
  663. package/dist/src/tui/tui-tool-result.js +74 -0
  664. package/dist/src/tui/tui-tool-result.js.map +1 -0
  665. package/dist/src/tui/tui-transcript-tree-picker.d.ts +57 -0
  666. package/dist/src/tui/tui-transcript-tree-picker.js +604 -0
  667. package/dist/src/tui/tui-transcript-tree-picker.js.map +1 -0
  668. package/dist/src/tui/tui-transcript-tree.d.ts +7 -0
  669. package/dist/src/tui/tui-transcript-tree.js +316 -0
  670. package/dist/src/tui/tui-transcript-tree.js.map +1 -0
  671. package/dist/src/tui/tui-types.d.ts +25 -34
  672. package/dist/src/tui/tui-types.js +12 -0
  673. package/dist/src/tui/tui-types.js.map +1 -1
  674. package/dist/src/tui/tui.js +1288 -112
  675. package/dist/src/tui/tui.js.map +1 -1
  676. package/dist/src/tui/xopc-tui-keybindings.d.ts +127 -2
  677. package/dist/src/tui/xopc-tui-keybindings.js +127 -2
  678. package/dist/src/tui/xopc-tui-keybindings.js.map +1 -1
  679. package/dist/src/workflows/domain/definition-utils.d.ts +2 -1
  680. package/dist/src/workflows/domain/definition-utils.js +18 -8
  681. package/dist/src/workflows/domain/definition-utils.js.map +1 -1
  682. package/dist/src/workflows/domain/definition.d.ts +25 -0
  683. package/dist/src/workflows/domain/event.d.ts +1 -0
  684. package/dist/src/workflows/domain/result.d.ts +15 -0
  685. package/dist/src/workflows/domain/run.d.ts +2 -0
  686. package/dist/src/workflows/domain/run.js.map +1 -1
  687. package/dist/src/workflows/engine/projector.js +4 -0
  688. package/dist/src/workflows/engine/projector.js.map +1 -1
  689. package/dist/src/workflows/engine/workflow-engine.d.ts +37 -1
  690. package/dist/src/workflows/engine/workflow-engine.js +75 -11
  691. package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
  692. package/dist/src/workflows/index.d.ts +1 -0
  693. package/dist/src/workflows/index.js +4 -1
  694. package/dist/src/workflows/registry/catalog-workflow-definition-registry.d.ts +9 -0
  695. package/dist/src/workflows/registry/catalog-workflow-definition-registry.js +40 -0
  696. package/dist/src/workflows/registry/catalog-workflow-definition-registry.js.map +1 -0
  697. package/dist/src/workflows/registry/index.d.ts +2 -0
  698. package/dist/src/workflows/registry/index.js +2 -0
  699. package/dist/src/workflows/registry/workflow-definition-registry.d.ts +15 -0
  700. package/dist/src/workflows/registry/workflow-definition-registry.js +1 -0
  701. package/dist/src/workflows/runtime/index.d.ts +2 -0
  702. package/dist/src/workflows/runtime/index.js +2 -1
  703. package/dist/src/workflows/runtime/script-workflow-runtime.d.ts +5 -0
  704. package/dist/src/workflows/runtime/script-workflow-runtime.js +15 -0
  705. package/dist/src/workflows/runtime/script-workflow-runtime.js.map +1 -0
  706. package/dist/src/workflows/runtime/workflow-runtime-port.d.ts +16 -0
  707. package/dist/src/workflows/runtime/workflow-runtime-port.js +1 -0
  708. package/dist/src/workflows/service/run-view-to-snapshot.js +3 -0
  709. package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -1
  710. package/dist/src/workflows/service/workflow-run-service.d.ts +3 -0
  711. package/dist/src/workflows/service/workflow-run-service.js +10 -15
  712. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  713. package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -1
  714. package/dist/src/workflows/service/workflow-session-bridge.js +4 -1
  715. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  716. package/package.json +21 -15
  717. package/skills/creative/frontend-design/SKILL.md +1 -1
  718. package/skills/creative/theme-factory/SKILL.md +1 -1
  719. package/skills/documents/xlsx/SKILL.md +1 -1
  720. package/skills/engineering/diagnose/SKILL.md +2 -2
  721. package/skills/engineering/tdd/SKILL.md +1 -1
  722. package/skills/tools/github/SKILL.md +6 -1
  723. package/skills/tools/webapp-testing/SKILL.md +4 -1
  724. package/dist/extensions/telegram/src/adapters/config-surface.d.ts +0 -2
  725. package/dist/extensions/telegram/src/adapters/config-surface.js +0 -26
  726. package/dist/extensions/telegram/src/adapters/config-surface.js.map +0 -1
  727. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +0 -158
  728. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +0 -1
  729. package/dist/gateway/static/root/assets/agents-DQ0mQxIA.js +0 -222
  730. package/dist/gateway/static/root/assets/channels-settings-BEtP53V6.js +0 -1
  731. package/dist/gateway/static/root/assets/channels-status-swr-CxTtS1hI.js +0 -8
  732. package/dist/gateway/static/root/assets/cron-api-CznlPIZT.js +0 -1
  733. package/dist/gateway/static/root/assets/cron-page-Dx6dE3eD.js +0 -1
  734. package/dist/gateway/static/root/assets/extension-settings-page-DuDCSb3J.js +0 -1
  735. package/dist/gateway/static/root/assets/field-primitives-BUwUiDf5.js +0 -1
  736. package/dist/gateway/static/root/assets/heartbeat-config-api-BjFW1cl-.js +0 -1
  737. package/dist/gateway/static/root/assets/index-DKgHC1Ta.js +0 -4840
  738. package/dist/gateway/static/root/assets/index-DjNDHzwG.css +0 -1
  739. package/dist/gateway/static/root/assets/notes-page-D40ZpS0Y.js +0 -1
  740. package/dist/gateway/static/root/assets/sessions-page-BvtdbmW8.js +0 -1
  741. package/dist/gateway/static/root/assets/settings-advanced-gate-BQamRjkV.js +0 -2
  742. package/dist/gateway/static/root/assets/settings-page-D972_jaS.js +0 -3
  743. package/dist/gateway/static/root/assets/share-preview-page-CKCTMo0_.js +0 -2
  744. package/dist/gateway/static/root/assets/skills-page-QwFCB4yV.js +0 -2
  745. package/dist/gateway/static/root/assets/url-q28QhI7l.js +0 -3
  746. package/dist/gateway/static/root/assets/utils-DCm11_KW.js +0 -1
  747. package/dist/gateway/static/root/assets/voice-api-key-field-CywiB7Dw.js +0 -1
  748. package/dist/gateway/static/root/assets/workflows-page-Be7l_SWw.js +0 -27
  749. package/dist/src/agent/embedded/map-stream-events.d.ts +0 -9
  750. package/dist/src/agent/embedded/map-stream-events.js +0 -63
  751. package/dist/src/agent/embedded/map-stream-events.js.map +0 -1
  752. package/dist/src/auth/oauth/vendor-pi-google/google-antigravity.js.map +0 -1
  753. package/dist/src/auth/oauth/vendor-pi-google/google-gemini-cli.js.map +0 -1
  754. package/dist/src/auth/oauth/vendor-pi-google/oauth-page.js.map +0 -1
  755. package/dist/src/auth/oauth/vendor-pi-google/pkce.js.map +0 -1
  756. package/dist/src/channels/dock.js.map +0 -1
  757. package/dist/src/channels/plugins/bundled.d.ts +0 -11
  758. package/dist/src/channels/plugins/bundled.js +0 -10
  759. package/dist/src/channels/plugins/bundled.js.map +0 -1
  760. package/dist/src/channels/registry.d.ts +0 -25
  761. package/dist/src/channels/registry.js +0 -82
  762. package/dist/src/channels/registry.js.map +0 -1
  763. package/dist/src/config/localized-text.d.ts +0 -6
  764. package/dist/src/config/localized-text.js +0 -42
  765. package/dist/src/config/localized-text.js.map +0 -1
  766. package/dist/src/generated/bundled-channel-plugins.d.ts +0 -10
  767. package/dist/src/generated/bundled-channel-plugins.js +0 -16
  768. package/dist/src/generated/bundled-channel-plugins.js.map +0 -1
  769. package/dist/src/tui/stream-assembler.d.ts +0 -22
  770. package/dist/src/tui/stream-assembler.js +0 -63
  771. package/dist/src/tui/stream-assembler.js.map +0 -1
  772. package/skills/browser/SKILL-zh.md +0 -188
  773. package/skills/business/company-values/SKILL-zh.md +0 -80
  774. package/skills/business/company-values/SKILL.md +0 -80
  775. package/skills/business/find-community/SKILL-zh.md +0 -50
  776. package/skills/business/find-community/SKILL.md +0 -50
  777. package/skills/business/first-customers/SKILL-zh.md +0 -76
  778. package/skills/business/first-customers/SKILL.md +0 -76
  779. package/skills/business/grow-sustainably/SKILL-zh.md +0 -92
  780. package/skills/business/grow-sustainably/SKILL.md +0 -92
  781. package/skills/business/marketing-plan/SKILL-zh.md +0 -100
  782. package/skills/business/marketing-plan/SKILL.md +0 -100
  783. package/skills/business/minimalist-review/SKILL-zh.md +0 -82
  784. package/skills/business/minimalist-review/SKILL.md +0 -82
  785. package/skills/business/mvp/SKILL-zh.md +0 -81
  786. package/skills/business/mvp/SKILL.md +0 -81
  787. package/skills/business/pricing/SKILL-zh.md +0 -64
  788. package/skills/business/pricing/SKILL.md +0 -64
  789. package/skills/business/processize/SKILL-zh.md +0 -91
  790. package/skills/business/processize/SKILL.md +0 -91
  791. package/skills/business/validate-idea/SKILL-zh.md +0 -68
  792. package/skills/business/validate-idea/SKILL.md +0 -68
  793. package/skills/creative/algorithmic-art/LICENSE.txt +0 -202
  794. package/skills/creative/algorithmic-art/SKILL-zh.md +0 -405
  795. package/skills/creative/algorithmic-art/SKILL.md +0 -405
  796. package/skills/creative/algorithmic-art/templates/generator_template.js +0 -223
  797. package/skills/creative/algorithmic-art/templates/viewer.html +0 -599
  798. package/skills/creative/frontend-design/SKILL-zh.md +0 -42
  799. package/skills/creative/theme-factory/SKILL-zh.md +0 -59
  800. package/skills/creative/web-artifacts-builder/LICENSE.txt +0 -202
  801. package/skills/creative/web-artifacts-builder/SKILL-zh.md +0 -74
  802. package/skills/creative/web-artifacts-builder/SKILL.md +0 -74
  803. package/skills/creative/web-artifacts-builder/scripts/bundle-artifact.sh +0 -54
  804. package/skills/creative/web-artifacts-builder/scripts/init-artifact.sh +0 -322
  805. package/skills/creative/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  806. package/skills/documents/doc-coauthoring/SKILL-zh.md +0 -375
  807. package/skills/documents/doc-coauthoring/SKILL.md +0 -375
  808. package/skills/documents/docx/LICENSE.txt +0 -30
  809. package/skills/documents/docx/SKILL-zh.md +0 -590
  810. package/skills/documents/docx/SKILL.md +0 -590
  811. package/skills/documents/docx/scripts/__init__.py +0 -1
  812. package/skills/documents/docx/scripts/accept_changes.py +0 -135
  813. package/skills/documents/docx/scripts/comment.py +0 -318
  814. package/skills/documents/docx/scripts/office/helpers/__init__.py +0 -0
  815. package/skills/documents/docx/scripts/office/helpers/merge_runs.py +0 -199
  816. package/skills/documents/docx/scripts/office/helpers/simplify_redlines.py +0 -197
  817. package/skills/documents/docx/scripts/office/pack.py +0 -159
  818. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  819. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  820. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  821. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  822. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  823. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  824. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  825. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  826. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  827. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  828. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  829. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  830. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  831. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  832. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  833. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  834. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  835. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  836. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  837. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  838. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  839. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  840. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  841. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  842. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  843. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  844. package/skills/documents/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  845. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  846. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  847. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  848. package/skills/documents/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  849. package/skills/documents/docx/scripts/office/schemas/mce/mc.xsd +0 -75
  850. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  851. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  852. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  853. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  854. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  855. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  856. package/skills/documents/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  857. package/skills/documents/docx/scripts/office/soffice.py +0 -183
  858. package/skills/documents/docx/scripts/office/unpack.py +0 -132
  859. package/skills/documents/docx/scripts/office/validate.py +0 -111
  860. package/skills/documents/docx/scripts/office/validators/__init__.py +0 -15
  861. package/skills/documents/docx/scripts/office/validators/base.py +0 -847
  862. package/skills/documents/docx/scripts/office/validators/docx.py +0 -446
  863. package/skills/documents/docx/scripts/office/validators/pptx.py +0 -275
  864. package/skills/documents/docx/scripts/office/validators/redlining.py +0 -247
  865. package/skills/documents/docx/scripts/templates/comments.xml +0 -3
  866. package/skills/documents/docx/scripts/templates/commentsExtended.xml +0 -3
  867. package/skills/documents/docx/scripts/templates/commentsExtensible.xml +0 -3
  868. package/skills/documents/docx/scripts/templates/commentsIds.xml +0 -3
  869. package/skills/documents/docx/scripts/templates/people.xml +0 -3
  870. package/skills/documents/pdf/LICENSE.txt +0 -30
  871. package/skills/documents/pdf/SKILL-zh.md +0 -314
  872. package/skills/documents/pdf/SKILL.md +0 -314
  873. package/skills/documents/pdf/forms.md +0 -294
  874. package/skills/documents/pdf/reference.md +0 -612
  875. package/skills/documents/pdf/scripts/check_bounding_boxes.py +0 -65
  876. package/skills/documents/pdf/scripts/check_fillable_fields.py +0 -11
  877. package/skills/documents/pdf/scripts/convert_pdf_to_images.py +0 -33
  878. package/skills/documents/pdf/scripts/create_validation_image.py +0 -37
  879. package/skills/documents/pdf/scripts/extract_form_field_info.py +0 -122
  880. package/skills/documents/pdf/scripts/extract_form_structure.py +0 -115
  881. package/skills/documents/pdf/scripts/fill_fillable_fields.py +0 -98
  882. package/skills/documents/pdf/scripts/fill_pdf_form_with_annotations.py +0 -107
  883. package/skills/documents/pptx/LICENSE.txt +0 -30
  884. package/skills/documents/pptx/SKILL-zh.md +0 -232
  885. package/skills/documents/pptx/SKILL.md +0 -232
  886. package/skills/documents/pptx/editing.md +0 -205
  887. package/skills/documents/pptx/pptxgenjs.md +0 -420
  888. package/skills/documents/pptx/scripts/__init__.py +0 -0
  889. package/skills/documents/pptx/scripts/add_slide.py +0 -195
  890. package/skills/documents/pptx/scripts/clean.py +0 -286
  891. package/skills/documents/pptx/scripts/office/helpers/__init__.py +0 -0
  892. package/skills/documents/pptx/scripts/office/helpers/merge_runs.py +0 -199
  893. package/skills/documents/pptx/scripts/office/helpers/simplify_redlines.py +0 -197
  894. package/skills/documents/pptx/scripts/office/pack.py +0 -159
  895. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  896. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  897. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  898. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  899. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  900. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  901. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  902. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  903. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  904. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  905. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  906. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  907. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  908. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  909. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  910. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  911. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  912. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  913. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  914. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  915. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  916. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  917. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  918. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  919. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  920. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  921. package/skills/documents/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  922. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  923. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  924. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  925. package/skills/documents/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  926. package/skills/documents/pptx/scripts/office/schemas/mce/mc.xsd +0 -75
  927. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  928. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  929. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  930. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  931. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  932. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  933. package/skills/documents/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  934. package/skills/documents/pptx/scripts/office/soffice.py +0 -183
  935. package/skills/documents/pptx/scripts/office/unpack.py +0 -132
  936. package/skills/documents/pptx/scripts/office/validate.py +0 -111
  937. package/skills/documents/pptx/scripts/office/validators/__init__.py +0 -15
  938. package/skills/documents/pptx/scripts/office/validators/base.py +0 -847
  939. package/skills/documents/pptx/scripts/office/validators/docx.py +0 -446
  940. package/skills/documents/pptx/scripts/office/validators/pptx.py +0 -275
  941. package/skills/documents/pptx/scripts/office/validators/redlining.py +0 -247
  942. package/skills/documents/pptx/scripts/thumbnail.py +0 -289
  943. package/skills/documents/xlsx/SKILL-zh.md +0 -292
  944. package/skills/engineering/diagnose/SKILL-zh.md +0 -117
  945. package/skills/engineering/grill-with-docs/ADR-FORMAT.md +0 -47
  946. package/skills/engineering/grill-with-docs/CONTEXT-FORMAT.md +0 -77
  947. package/skills/engineering/grill-with-docs/SKILL-zh.md +0 -88
  948. package/skills/engineering/grill-with-docs/SKILL.md +0 -88
  949. package/skills/engineering/improve-codebase-architecture/DEEPENING.md +0 -37
  950. package/skills/engineering/improve-codebase-architecture/INTERFACE-DESIGN.md +0 -44
  951. package/skills/engineering/improve-codebase-architecture/LANGUAGE.md +0 -53
  952. package/skills/engineering/improve-codebase-architecture/SKILL-zh.md +0 -71
  953. package/skills/engineering/improve-codebase-architecture/SKILL.md +0 -71
  954. package/skills/engineering/tdd/SKILL-zh.md +0 -109
  955. package/skills/engineering/to-issues/SKILL-zh.md +0 -81
  956. package/skills/engineering/to-issues/SKILL.md +0 -81
  957. package/skills/engineering/to-prd/SKILL-zh.md +0 -76
  958. package/skills/engineering/to-prd/SKILL.md +0 -74
  959. package/skills/engineering/zoom-out/SKILL-zh.md +0 -7
  960. package/skills/engineering/zoom-out/SKILL.md +0 -7
  961. package/skills/tools/find-skills/SKILL-zh.md +0 -440
  962. package/skills/tools/github/SKILL-zh.md +0 -48
  963. package/skills/tools/internal-comms/LICENSE.txt +0 -202
  964. package/skills/tools/internal-comms/SKILL-zh.md +0 -32
  965. package/skills/tools/internal-comms/SKILL.md +0 -32
  966. package/skills/tools/internal-comms/examples/3p-updates.md +0 -47
  967. package/skills/tools/internal-comms/examples/company-newsletter.md +0 -65
  968. package/skills/tools/internal-comms/examples/faq-answers.md +0 -30
  969. package/skills/tools/internal-comms/examples/general-comms.md +0 -16
  970. package/skills/tools/skill-creator/LICENSE.txt +0 -202
  971. package/skills/tools/skill-creator/SKILL-zh.md +0 -483
  972. package/skills/tools/skill-creator/SKILL.md +0 -485
  973. package/skills/tools/skill-creator/agents/analyzer.md +0 -274
  974. package/skills/tools/skill-creator/agents/comparator.md +0 -202
  975. package/skills/tools/skill-creator/agents/grader.md +0 -223
  976. package/skills/tools/skill-creator/assets/eval_review.html +0 -146
  977. package/skills/tools/skill-creator/eval-viewer/generate_review.py +0 -471
  978. package/skills/tools/skill-creator/eval-viewer/viewer.html +0 -1325
  979. package/skills/tools/skill-creator/references/schemas.md +0 -430
  980. package/skills/tools/skill-creator/scripts/__init__.py +0 -0
  981. package/skills/tools/skill-creator/scripts/aggregate_benchmark.py +0 -401
  982. package/skills/tools/skill-creator/scripts/generate_report.py +0 -326
  983. package/skills/tools/skill-creator/scripts/improve_description.py +0 -247
  984. package/skills/tools/skill-creator/scripts/package_skill.py +0 -136
  985. package/skills/tools/skill-creator/scripts/quick_validate.py +0 -103
  986. package/skills/tools/skill-creator/scripts/run_eval.py +0 -310
  987. package/skills/tools/skill-creator/scripts/run_loop.py +0 -328
  988. package/skills/tools/skill-creator/scripts/utils.py +0 -47
  989. package/skills/tools/summarize/SKILL-zh.md +0 -47
  990. package/skills/tools/weather/SKILL-zh.md +0 -46
  991. package/skills/tools/weather/SKILL.md +0 -46
  992. package/skills/tools/webapp-testing/SKILL-zh.md +0 -96
  993. /package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/google-antigravity.d.ts +0 -0
  994. /package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/google-gemini-cli.d.ts +0 -0
  995. /package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/oauth-page.d.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"installer.js","names":[],"sources":["../../../../src/agent/skills/installer.ts"],"sourcesContent":["/**\n * Skill Installer\n * \n * Handles installation of skill dependencies via various package managers.\n *\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { createLogger } from '../../utils/logger.js';\nimport type { SkillEntry, SkillInstallResult, SkillInstallSpec } from './types.js';\n\nconst execAsync = promisify(exec);\n\nconst log = createLogger('SkillInstaller');\n\nexport interface InstallerPreferences {\n preferBrew: boolean;\n nodeManager: 'pnpm' | 'npm' | 'yarn' | 'bun';\n}\n\nexport interface InstallContext {\n workspaceDir: string;\n skillEntry: SkillEntry;\n installSpec: SkillInstallSpec;\n timeoutMs: number;\n preferences: InstallerPreferences;\n}\n\n/**\n * Check if a binary exists\n */\nexport function hasBinary(name: string): boolean {\n try {\n const { which } = require('which');\n return !!which.sync(name, { nothrow: true });\n } catch {\n // Fallback: try to execute the command\n try {\n const { execSync } = require('child_process');\n execSync(`which ${name}`, { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n }\n}\n\n/**\n * Resolve brew executable path\n */\nexport function resolveBrewExecutable(): string | undefined {\n const candidates = [\n '/opt/homebrew/bin/brew',\n '/usr/local/bin/brew',\n ];\n \n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n \n return undefined;\n}\n\n/**\n * Build install command for Node.js packages\n */\nfunction buildNodeInstallCommand(packageName: string, manager: InstallerPreferences['nodeManager']): string[] {\n switch (manager) {\n case 'pnpm':\n return ['pnpm', 'add', '-g', '--ignore-scripts', packageName];\n case 'yarn':\n return ['yarn', 'global', 'add', '--ignore-scripts', packageName];\n case 'bun':\n return ['bun', 'add', '-g', '--ignore-scripts', packageName];\n default:\n return ['npm', 'install', '-g', '--ignore-scripts', packageName];\n }\n}\n\n/**\n * Build install command from spec\n */\nfunction buildInstallCommand(spec: SkillInstallSpec, prefs: InstallerPreferences): {\n argv: string[] | null;\n error?: string;\n} {\n switch (spec.kind) {\n case 'brew': {\n if (!spec.formula) {\n return { argv: null, error: 'Missing brew formula' };\n }\n return { argv: ['brew', 'install', spec.formula] };\n }\n \n case 'pnpm':\n case 'npm':\n case 'yarn':\n case 'bun': {\n if (!spec.package) {\n return { argv: null, error: 'Missing package name' };\n }\n return {\n argv: buildNodeInstallCommand(spec.package, prefs.nodeManager),\n };\n }\n \n case 'go': {\n if (!spec.module) {\n return { argv: null, error: 'Missing go module' };\n }\n return { argv: ['go', 'install', spec.module] };\n }\n \n case 'uv': {\n if (!spec.package) {\n return { argv: null, error: 'Missing uv package' };\n }\n return { argv: ['uv', 'tool', 'install', spec.package] };\n }\n \n case 'download': {\n return { argv: null, error: 'Download install handled separately' };\n }\n \n default: {\n const _exhaustive: never = spec.kind;\n return { argv: null, error: `Unsupported installer: ${spec.kind}` };\n }\n }\n}\n\n/**\n * Run command with timeout\n */\nasync function runCommandWithTimeout(\n argv: string[],\n timeoutMs: number,\n env?: NodeJS.ProcessEnv\n): Promise<{ code: number | null; stdout: string; stderr: string }> {\n const [cmd, ...args] = argv;\n \n try {\n const { stdout, stderr } = await execAsync(`${cmd} ${args.join(' ')}`, {\n timeout: timeoutMs,\n env,\n maxBuffer: 10 * 1024 * 1024, // 10MB\n });\n \n return {\n code: 0,\n stdout: stdout.toString(),\n stderr: stderr.toString(),\n };\n } catch (err: unknown) {\n if (err instanceof Error) {\n const execError = err as Error & { code?: number; stdout?: string; stderr?: string };\n return {\n code: execError.code ?? null,\n stdout: execError.stdout?.toString() ?? '',\n stderr: execError.stderr?.toString() ?? '',\n };\n }\n \n return {\n code: null,\n stdout: '',\n stderr: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n/**\n * Ensure uv is installed\n */\nasync function ensureUvInstalled(timeoutMs: number): Promise<SkillInstallResult | undefined> {\n if (hasBinary('uv')) {\n return undefined;\n }\n \n // Try to install via brew\n const brewExe = resolveBrewExecutable();\n if (!brewExe) {\n return {\n ok: false,\n message: 'uv not installed — install manually: https://docs.astral.sh/uv/getting-started/installation/',\n stdout: '',\n stderr: '',\n code: null,\n };\n }\n \n const result = await runCommandWithTimeout([brewExe, 'install', 'uv'], timeoutMs);\n if (result.code === 0) {\n return undefined;\n }\n \n return {\n ok: false,\n message: 'Failed to install uv (brew)',\n stdout: result.stdout,\n stderr: result.stderr,\n code: result.code,\n };\n}\n\n/**\n * Ensure Go is installed\n */\nasync function ensureGoInstalled(timeoutMs: number): Promise<SkillInstallResult | undefined> {\n if (hasBinary('go')) {\n return undefined;\n }\n \n const brewExe = resolveBrewExecutable();\n if (brewExe) {\n const result = await runCommandWithTimeout([brewExe, 'install', 'go'], timeoutMs);\n if (result.code === 0) {\n return undefined;\n }\n \n return {\n ok: false,\n message: 'Failed to install go (brew)',\n stdout: result.stdout,\n stderr: result.stderr,\n code: result.code,\n };\n }\n \n // Try apt-get on Linux\n if (hasBinary('apt-get')) {\n const isRoot = process.getuid?.() === 0;\n const aptCmd = isRoot \n ? ['apt-get', 'install', '-y', 'golang-go']\n : ['sudo', 'apt-get', 'install', '-y', 'golang-go'];\n \n // Update package index first\n if (!isRoot) {\n await runCommandWithTimeout(['sudo', 'apt-get', 'update', '-qq'], Math.min(timeoutMs, 30000));\n }\n \n const result = await runCommandWithTimeout(aptCmd, timeoutMs);\n if (result.code === 0) {\n return undefined;\n }\n \n return {\n ok: false,\n message: 'go not installed — automatic install via apt failed. Install manually: https://go.dev/doc/install',\n stdout: result.stdout,\n stderr: result.stderr,\n code: result.code,\n };\n }\n \n return {\n ok: false,\n message: 'go not installed — install manually: https://go.dev/doc/install',\n stdout: '',\n stderr: '',\n code: null,\n };\n}\n\n/**\n * Create install failure result\n */\nfunction createInstallFailure(params: {\n message: string;\n stdout?: string;\n stderr?: string;\n code?: number | null;\n}): SkillInstallResult {\n return {\n ok: false,\n message: params.message,\n stdout: params.stdout?.trim() ?? '',\n stderr: params.stderr?.trim() ?? '',\n code: params.code ?? null,\n };\n}\n\n/**\n * Create install success result\n */\nfunction createInstallSuccess(result: { code: number | null; stdout: string; stderr: string }): SkillInstallResult {\n return {\n ok: true,\n message: 'Installed',\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n code: result.code,\n };\n}\n\n/**\n * Find install spec by ID\n */\nexport function findInstallSpec(entry: SkillEntry, installId: string): SkillInstallSpec | undefined {\n const specs = entry.metadata.install ?? [];\n \n for (const [index, spec] of specs.entries()) {\n const id = spec.id ?? `${spec.kind}-${index}`;\n if (id === installId) {\n return spec;\n }\n }\n \n return undefined;\n}\n\n/**\n * Install a skill dependency\n */\nexport async function installSkill(ctx: InstallContext): Promise<SkillInstallResult> {\n const { installSpec, timeoutMs, preferences } = ctx;\n \n log.info({ skill: ctx.skillEntry.skill.name, kind: installSpec.kind }, 'Installing skill dependency');\n \n // Handle download installer separately\n if (installSpec.kind === 'download') {\n return createInstallFailure({\n message: 'Download installer not yet implemented',\n });\n }\n \n // Check and install prerequisites\n if (installSpec.kind === 'uv') {\n const uvFailure = await ensureUvInstalled(timeoutMs);\n if (uvFailure) {\n return uvFailure;\n }\n }\n \n if (installSpec.kind === 'go') {\n const goFailure = await ensureGoInstalled(timeoutMs);\n if (goFailure) {\n return goFailure;\n }\n }\n \n // Build install command\n const command = buildInstallCommand(installSpec, preferences);\n if (command.error) {\n return createInstallFailure({\n message: command.error,\n });\n }\n \n if (!command.argv) {\n return createInstallFailure({\n message: 'Invalid install command',\n });\n }\n \n // Resolve brew executable\n let argv = [...command.argv];\n if (installSpec.kind === 'brew') {\n const brewExe = resolveBrewExecutable();\n if (!brewExe) {\n const hint = process.platform === 'linux'\n ? 'Homebrew is not installed. Install it from https://brew.sh or use your system package manager.'\n : 'Homebrew is not installed. Install it from https://brew.sh';\n \n return createInstallFailure({\n message: `brew not installed — ${hint}`,\n });\n }\n argv[0] = brewExe;\n }\n \n // Set up environment for go installations\n let env: NodeJS.ProcessEnv | undefined;\n if (installSpec.kind === 'go') {\n const brewExe = resolveBrewExecutable();\n if (brewExe) {\n try {\n const { stdout } = await execAsync(`${brewExe} --prefix`);\n const prefix = stdout.trim();\n if (prefix) {\n env = { ...process.env, GOBIN: join(prefix, 'bin') };\n }\n } catch {\n // Use default GOBIN\n }\n }\n }\n \n // Execute install command\n const result = await runCommandWithTimeout(argv, timeoutMs, env);\n \n if (result.code === 0) {\n log.info({ skill: ctx.skillEntry.skill.name }, 'Skill dependency installed successfully');\n return createInstallSuccess(result);\n }\n \n log.warn({ \n skill: ctx.skillEntry.skill.name, \n stderr: result.stderr \n }, 'Skill dependency installation failed');\n \n return createInstallFailure({\n message: result.stderr || `Installation failed with exit code ${result.code}`,\n stdout: result.stdout,\n stderr: result.stderr,\n code: result.code,\n });\n}\n\n/**\n * Get default installer preferences from config\n */\nexport function getDefaultInstallerPreferences(): InstallerPreferences {\n return {\n preferBrew: true,\n nodeManager: 'pnpm', // Default to pnpm as per project guidelines\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"installer.js","names":[],"sources":["../../../../src/agent/skills/installer.ts"],"sourcesContent":["/**\n * Skill Installer\n * \n * Handles installation of skill dependencies via various package managers.\n *\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { accessSync, constants, existsSync } from 'fs';\nimport { delimiter, join } from 'path';\nimport { createLogger } from '../../utils/logger.js';\nimport type { SkillEntry, SkillInstallResult, SkillInstallSpec } from './types.js';\n\nconst execAsync = promisify(exec);\n\nconst log = createLogger('SkillInstaller');\n\nexport interface InstallerPreferences {\n preferBrew: boolean;\n nodeManager: 'pnpm' | 'npm' | 'yarn' | 'bun';\n}\n\nexport interface InstallContext {\n workspaceDir: string;\n skillEntry: SkillEntry;\n installSpec: SkillInstallSpec;\n timeoutMs: number;\n preferences: InstallerPreferences;\n}\n\n/**\n * Check if a binary exists\n */\nexport function hasBinary(name: string): boolean {\n if (!name || name.includes('/') || name.includes('\\\\')) {\n return false;\n }\n\n const pathEntries = (process.env.PATH || '').split(delimiter).filter(Boolean);\n const extensions = process.platform === 'win32'\n ? (process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM').split(';').filter(Boolean)\n : [''];\n\n for (const dir of pathEntries) {\n for (const ext of extensions) {\n const candidate = join(dir, `${name}${ext}`);\n try {\n accessSync(candidate, constants.X_OK);\n return true;\n } catch {\n // Continue searching PATH.\n }\n }\n }\n\n return false;\n}\n\n/**\n * Resolve brew executable path\n */\nexport function resolveBrewExecutable(): string | undefined {\n const candidates = [\n '/opt/homebrew/bin/brew',\n '/usr/local/bin/brew',\n ];\n \n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n \n return undefined;\n}\n\n/**\n * Build install command for Node.js packages\n */\nfunction buildNodeInstallCommand(packageName: string, manager: InstallerPreferences['nodeManager']): string[] {\n switch (manager) {\n case 'pnpm':\n return ['pnpm', 'add', '-g', '--ignore-scripts', packageName];\n case 'yarn':\n return ['yarn', 'global', 'add', '--ignore-scripts', packageName];\n case 'bun':\n return ['bun', 'add', '-g', '--ignore-scripts', packageName];\n default:\n return ['npm', 'install', '-g', '--ignore-scripts', packageName];\n }\n}\n\n/**\n * Build install command from spec\n */\nfunction buildInstallCommand(spec: SkillInstallSpec, prefs: InstallerPreferences): {\n argv: string[] | null;\n error?: string;\n} {\n switch (spec.kind) {\n case 'brew': {\n if (!spec.formula) {\n return { argv: null, error: 'Missing brew formula' };\n }\n return { argv: ['brew', 'install', spec.formula] };\n }\n \n case 'pnpm':\n case 'npm':\n case 'yarn':\n case 'bun': {\n if (!spec.package) {\n return { argv: null, error: 'Missing package name' };\n }\n return {\n argv: buildNodeInstallCommand(spec.package, prefs.nodeManager),\n };\n }\n \n case 'go': {\n if (!spec.module) {\n return { argv: null, error: 'Missing go module' };\n }\n return { argv: ['go', 'install', spec.module] };\n }\n \n case 'uv': {\n if (!spec.package) {\n return { argv: null, error: 'Missing uv package' };\n }\n return { argv: ['uv', 'tool', 'install', spec.package] };\n }\n \n case 'download': {\n return { argv: null, error: 'Download install handled separately' };\n }\n \n default: {\n const _exhaustive: never = spec.kind;\n return { argv: null, error: `Unsupported installer: ${spec.kind}` };\n }\n }\n}\n\n/**\n * Run command with timeout\n */\nasync function runCommandWithTimeout(\n argv: string[],\n timeoutMs: number,\n env?: NodeJS.ProcessEnv\n): Promise<{ code: number | null; stdout: string; stderr: string }> {\n const [cmd, ...args] = argv;\n \n try {\n const { stdout, stderr } = await execAsync(`${cmd} ${args.join(' ')}`, {\n timeout: timeoutMs,\n env,\n maxBuffer: 10 * 1024 * 1024, // 10MB\n });\n \n return {\n code: 0,\n stdout: stdout.toString(),\n stderr: stderr.toString(),\n };\n } catch (err: unknown) {\n if (err instanceof Error) {\n const execError = err as Error & { code?: number; stdout?: string; stderr?: string };\n return {\n code: execError.code ?? null,\n stdout: execError.stdout?.toString() ?? '',\n stderr: execError.stderr?.toString() ?? '',\n };\n }\n \n return {\n code: null,\n stdout: '',\n stderr: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n/**\n * Ensure uv is installed\n */\nasync function ensureUvInstalled(timeoutMs: number): Promise<SkillInstallResult | undefined> {\n if (hasBinary('uv')) {\n return undefined;\n }\n \n // Try to install via brew\n const brewExe = resolveBrewExecutable();\n if (!brewExe) {\n return {\n ok: false,\n message: 'uv not installed — install manually: https://docs.astral.sh/uv/getting-started/installation/',\n stdout: '',\n stderr: '',\n code: null,\n };\n }\n \n const result = await runCommandWithTimeout([brewExe, 'install', 'uv'], timeoutMs);\n if (result.code === 0) {\n return undefined;\n }\n \n return {\n ok: false,\n message: 'Failed to install uv (brew)',\n stdout: result.stdout,\n stderr: result.stderr,\n code: result.code,\n };\n}\n\n/**\n * Ensure Go is installed\n */\nasync function ensureGoInstalled(timeoutMs: number): Promise<SkillInstallResult | undefined> {\n if (hasBinary('go')) {\n return undefined;\n }\n \n const brewExe = resolveBrewExecutable();\n if (brewExe) {\n const result = await runCommandWithTimeout([brewExe, 'install', 'go'], timeoutMs);\n if (result.code === 0) {\n return undefined;\n }\n \n return {\n ok: false,\n message: 'Failed to install go (brew)',\n stdout: result.stdout,\n stderr: result.stderr,\n code: result.code,\n };\n }\n \n // Try apt-get on Linux\n if (hasBinary('apt-get')) {\n const isRoot = process.getuid?.() === 0;\n const aptCmd = isRoot \n ? ['apt-get', 'install', '-y', 'golang-go']\n : ['sudo', 'apt-get', 'install', '-y', 'golang-go'];\n \n // Update package index first\n if (!isRoot) {\n await runCommandWithTimeout(['sudo', 'apt-get', 'update', '-qq'], Math.min(timeoutMs, 30000));\n }\n \n const result = await runCommandWithTimeout(aptCmd, timeoutMs);\n if (result.code === 0) {\n return undefined;\n }\n \n return {\n ok: false,\n message: 'go not installed — automatic install via apt failed. Install manually: https://go.dev/doc/install',\n stdout: result.stdout,\n stderr: result.stderr,\n code: result.code,\n };\n }\n \n return {\n ok: false,\n message: 'go not installed — install manually: https://go.dev/doc/install',\n stdout: '',\n stderr: '',\n code: null,\n };\n}\n\n/**\n * Create install failure result\n */\nfunction createInstallFailure(params: {\n message: string;\n stdout?: string;\n stderr?: string;\n code?: number | null;\n}): SkillInstallResult {\n return {\n ok: false,\n message: params.message,\n stdout: params.stdout?.trim() ?? '',\n stderr: params.stderr?.trim() ?? '',\n code: params.code ?? null,\n };\n}\n\n/**\n * Create install success result\n */\nfunction createInstallSuccess(result: { code: number | null; stdout: string; stderr: string }): SkillInstallResult {\n return {\n ok: true,\n message: 'Installed',\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n code: result.code,\n };\n}\n\n/**\n * Find install spec by ID\n */\nexport function findInstallSpec(entry: SkillEntry, installId: string): SkillInstallSpec | undefined {\n const specs = entry.metadata.install ?? [];\n \n for (const [index, spec] of specs.entries()) {\n const id = spec.id ?? `${spec.kind}-${index}`;\n if (id === installId) {\n return spec;\n }\n }\n \n return undefined;\n}\n\n/**\n * Install a skill dependency\n */\nexport async function installSkill(ctx: InstallContext): Promise<SkillInstallResult> {\n const { installSpec, timeoutMs, preferences } = ctx;\n \n log.info({ skill: ctx.skillEntry.skill.name, kind: installSpec.kind }, 'Installing skill dependency');\n \n // Handle download installer separately\n if (installSpec.kind === 'download') {\n return createInstallFailure({\n message: 'Download installer not yet implemented',\n });\n }\n \n // Check and install prerequisites\n if (installSpec.kind === 'uv') {\n const uvFailure = await ensureUvInstalled(timeoutMs);\n if (uvFailure) {\n return uvFailure;\n }\n }\n \n if (installSpec.kind === 'go') {\n const goFailure = await ensureGoInstalled(timeoutMs);\n if (goFailure) {\n return goFailure;\n }\n }\n \n // Build install command\n const command = buildInstallCommand(installSpec, preferences);\n if (command.error) {\n return createInstallFailure({\n message: command.error,\n });\n }\n \n if (!command.argv) {\n return createInstallFailure({\n message: 'Invalid install command',\n });\n }\n \n // Resolve brew executable\n let argv = [...command.argv];\n if (installSpec.kind === 'brew') {\n const brewExe = resolveBrewExecutable();\n if (!brewExe) {\n const hint = process.platform === 'linux'\n ? 'Homebrew is not installed. Install it from https://brew.sh or use your system package manager.'\n : 'Homebrew is not installed. Install it from https://brew.sh';\n \n return createInstallFailure({\n message: `brew not installed — ${hint}`,\n });\n }\n argv[0] = brewExe;\n }\n \n // Set up environment for go installations\n let env: NodeJS.ProcessEnv | undefined;\n if (installSpec.kind === 'go') {\n const brewExe = resolveBrewExecutable();\n if (brewExe) {\n try {\n const { stdout } = await execAsync(`${brewExe} --prefix`);\n const prefix = stdout.trim();\n if (prefix) {\n env = { ...process.env, GOBIN: join(prefix, 'bin') };\n }\n } catch {\n // Use default GOBIN\n }\n }\n }\n \n // Execute install command\n const result = await runCommandWithTimeout(argv, timeoutMs, env);\n \n if (result.code === 0) {\n log.info({ skill: ctx.skillEntry.skill.name }, 'Skill dependency installed successfully');\n return createInstallSuccess(result);\n }\n \n log.warn({ \n skill: ctx.skillEntry.skill.name, \n stderr: result.stderr \n }, 'Skill dependency installation failed');\n \n return createInstallFailure({\n message: result.stderr || `Installation failed with exit code ${result.code}`,\n stdout: result.stdout,\n stderr: result.stderr,\n code: result.code,\n });\n}\n\n/**\n * Get default installer preferences from config\n */\nexport function getDefaultInstallerPreferences(): InstallerPreferences {\n return {\n preferBrew: true,\n nodeManager: 'pnpm', // Default to pnpm as per project guidelines\n };\n}\n"],"mappings":";;;;;;;;;;;;;aAWqD;AAGrD,MAAM,YAAY,UAAU,KAAK;AAEjC,MAAM,MAAM,aAAa,iBAAiB;;;;AAkB1C,SAAgB,UAAU,MAAuB;AAC/C,KAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,KAAK,CACpD,QAAO;CAGT,MAAM,eAAe,QAAQ,IAAI,QAAQ,IAAI,MAAM,UAAU,CAAC,OAAO,QAAQ;CAC7E,MAAM,aAAa,QAAQ,aAAa,WACnC,QAAQ,IAAI,WAAW,uBAAuB,MAAM,IAAI,CAAC,OAAO,QAAQ,GACzE,CAAC,GAAG;AAER,MAAK,MAAM,OAAO,YAChB,MAAK,MAAM,OAAO,YAAY;EAC5B,MAAM,YAAY,KAAK,KAAK,GAAG,OAAO,MAAM;AAC5C,MAAI;AACF,cAAW,WAAW,UAAU,KAAK;AACrC,UAAO;UACD;;AAMZ,QAAO;;;;;AAMT,SAAgB,wBAA4C;AAM1D,MAAK,MAAM,aAAa,CAJtB,0BACA,sBAGgC,CAChC,KAAI,WAAW,UAAU,CACvB,QAAO;;;;;AAUb,SAAS,wBAAwB,aAAqB,SAAwD;AAC5G,SAAQ,SAAR;EACE,KAAK,OACH,QAAO;GAAC;GAAQ;GAAO;GAAM;GAAoB;GAAY;EAC/D,KAAK,OACH,QAAO;GAAC;GAAQ;GAAU;GAAO;GAAoB;GAAY;EACnE,KAAK,MACH,QAAO;GAAC;GAAO;GAAO;GAAM;GAAoB;GAAY;EAC9D,QACE,QAAO;GAAC;GAAO;GAAW;GAAM;GAAoB;GAAY;;;;;;AAOtE,SAAS,oBAAoB,MAAwB,OAGnD;AACA,SAAQ,KAAK,MAAb;EACE,KAAK;AACH,OAAI,CAAC,KAAK,QACR,QAAO;IAAE,MAAM;IAAM,OAAO;IAAwB;AAEtD,UAAO,EAAE,MAAM;IAAC;IAAQ;IAAW,KAAK;IAAQ,EAAE;EAGpD,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;AACH,OAAI,CAAC,KAAK,QACR,QAAO;IAAE,MAAM;IAAM,OAAO;IAAwB;AAEtD,UAAO,EACL,MAAM,wBAAwB,KAAK,SAAS,MAAM,YAAY,EAC/D;EAGH,KAAK;AACH,OAAI,CAAC,KAAK,OACR,QAAO;IAAE,MAAM;IAAM,OAAO;IAAqB;AAEnD,UAAO,EAAE,MAAM;IAAC;IAAM;IAAW,KAAK;IAAO,EAAE;EAGjD,KAAK;AACH,OAAI,CAAC,KAAK,QACR,QAAO;IAAE,MAAM;IAAM,OAAO;IAAsB;AAEpD,UAAO,EAAE,MAAM;IAAC;IAAM;IAAQ;IAAW,KAAK;IAAQ,EAAE;EAG1D,KAAK,WACH,QAAO;GAAE,MAAM;GAAM,OAAO;GAAuC;EAGrE;AAC6B,QAAK;AAChC,UAAO;IAAE,MAAM;IAAM,OAAO,0BAA0B,KAAK;IAAQ;;;;;;AAQzE,eAAe,sBACb,MACA,WACA,KACkE;CAClE,MAAM,CAAC,KAAK,GAAG,QAAQ;AAEvB,KAAI;EACF,MAAM,EAAE,QAAQ,WAAW,MAAM,UAAU,GAAG,IAAI,GAAG,KAAK,KAAK,IAAI,IAAI;GACrE,SAAS;GACT;GACA,WAAW,KAAK,OAAO;GACxB,CAAC;AAEF,SAAO;GACL,MAAM;GACN,QAAQ,OAAO,UAAU;GACzB,QAAQ,OAAO,UAAU;GAC1B;UACM,KAAc;AACrB,MAAI,eAAe,OAAO;GACxB,MAAM,YAAY;AAClB,UAAO;IACL,MAAM,UAAU,QAAQ;IACxB,QAAQ,UAAU,QAAQ,UAAU,IAAI;IACxC,QAAQ,UAAU,QAAQ,UAAU,IAAI;IACzC;;AAGH,SAAO;GACL,MAAM;GACN,QAAQ;GACR,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;GACzD;;;;;;AAOL,eAAe,kBAAkB,WAA4D;AAC3F,KAAI,UAAU,KAAK,CACjB;CAIF,MAAM,UAAU,uBAAuB;AACvC,KAAI,CAAC,QACH,QAAO;EACL,IAAI;EACJ,SAAS;EACT,QAAQ;EACR,QAAQ;EACR,MAAM;EACP;CAGH,MAAM,SAAS,MAAM,sBAAsB;EAAC;EAAS;EAAW;EAAK,EAAE,UAAU;AACjF,KAAI,OAAO,SAAS,EAClB;AAGF,QAAO;EACL,IAAI;EACJ,SAAS;EACT,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,MAAM,OAAO;EACd;;;;;AAMH,eAAe,kBAAkB,WAA4D;AAC3F,KAAI,UAAU,KAAK,CACjB;CAGF,MAAM,UAAU,uBAAuB;AACvC,KAAI,SAAS;EACX,MAAM,SAAS,MAAM,sBAAsB;GAAC;GAAS;GAAW;GAAK,EAAE,UAAU;AACjF,MAAI,OAAO,SAAS,EAClB;AAGF,SAAO;GACL,IAAI;GACJ,SAAS;GACT,QAAQ,OAAO;GACf,QAAQ,OAAO;GACf,MAAM,OAAO;GACd;;AAIH,KAAI,UAAU,UAAU,EAAE;EACxB,MAAM,SAAS,QAAQ,UAAU,KAAK;EACtC,MAAM,SAAS,SACX;GAAC;GAAW;GAAW;GAAM;GAAY,GACzC;GAAC;GAAQ;GAAW;GAAW;GAAM;GAAY;AAGrD,MAAI,CAAC,OACH,OAAM,sBAAsB;GAAC;GAAQ;GAAW;GAAU;GAAM,EAAE,KAAK,IAAI,WAAW,IAAM,CAAC;EAG/F,MAAM,SAAS,MAAM,sBAAsB,QAAQ,UAAU;AAC7D,MAAI,OAAO,SAAS,EAClB;AAGF,SAAO;GACL,IAAI;GACJ,SAAS;GACT,QAAQ,OAAO;GACf,QAAQ,OAAO;GACf,MAAM,OAAO;GACd;;AAGH,QAAO;EACL,IAAI;EACJ,SAAS;EACT,QAAQ;EACR,QAAQ;EACR,MAAM;EACP;;;;;AAMH,SAAS,qBAAqB,QAKP;AACrB,QAAO;EACL,IAAI;EACJ,SAAS,OAAO;EAChB,QAAQ,OAAO,QAAQ,MAAM,IAAI;EACjC,QAAQ,OAAO,QAAQ,MAAM,IAAI;EACjC,MAAM,OAAO,QAAQ;EACtB;;;;;AAMH,SAAS,qBAAqB,QAAqF;AACjH,QAAO;EACL,IAAI;EACJ,SAAS;EACT,QAAQ,OAAO,OAAO,MAAM;EAC5B,QAAQ,OAAO,OAAO,MAAM;EAC5B,MAAM,OAAO;EACd;;;;;AAMH,SAAgB,gBAAgB,OAAmB,WAAiD;CAClG,MAAM,QAAQ,MAAM,SAAS,WAAW,EAAE;AAE1C,MAAK,MAAM,CAAC,OAAO,SAAS,MAAM,SAAS,CAEzC,MADW,KAAK,MAAM,GAAG,KAAK,KAAK,GAAG,aAC3B,UACT,QAAO;;;;;AAUb,eAAsB,aAAa,KAAkD;CACnF,MAAM,EAAE,aAAa,WAAW,gBAAgB;AAEhD,KAAI,KAAK;EAAE,OAAO,IAAI,WAAW,MAAM;EAAM,MAAM,YAAY;EAAM,EAAE,8BAA8B;AAGrG,KAAI,YAAY,SAAS,WACvB,QAAO,qBAAqB,EAC1B,SAAS,0CACV,CAAC;AAIJ,KAAI,YAAY,SAAS,MAAM;EAC7B,MAAM,YAAY,MAAM,kBAAkB,UAAU;AACpD,MAAI,UACF,QAAO;;AAIX,KAAI,YAAY,SAAS,MAAM;EAC7B,MAAM,YAAY,MAAM,kBAAkB,UAAU;AACpD,MAAI,UACF,QAAO;;CAKX,MAAM,UAAU,oBAAoB,aAAa,YAAY;AAC7D,KAAI,QAAQ,MACV,QAAO,qBAAqB,EAC1B,SAAS,QAAQ,OAClB,CAAC;AAGJ,KAAI,CAAC,QAAQ,KACX,QAAO,qBAAqB,EAC1B,SAAS,2BACV,CAAC;CAIJ,IAAI,OAAO,CAAC,GAAG,QAAQ,KAAK;AAC5B,KAAI,YAAY,SAAS,QAAQ;EAC/B,MAAM,UAAU,uBAAuB;AACvC,MAAI,CAAC,QAKH,QAAO,qBAAqB,EAC1B,SAAS,wBALE,QAAQ,aAAa,UAC9B,mGACA,gEAIH,CAAC;AAEJ,OAAK,KAAK;;CAIZ,IAAI;AACJ,KAAI,YAAY,SAAS,MAAM;EAC7B,MAAM,UAAU,uBAAuB;AACvC,MAAI,QACF,KAAI;GACF,MAAM,EAAE,WAAW,MAAM,UAAU,GAAG,QAAQ,WAAW;GACzD,MAAM,SAAS,OAAO,MAAM;AAC5B,OAAI,OACF,OAAM;IAAE,GAAG,QAAQ;IAAK,OAAO,KAAK,QAAQ,MAAM;IAAE;UAEhD;;CAOZ,MAAM,SAAS,MAAM,sBAAsB,MAAM,WAAW,IAAI;AAEhE,KAAI,OAAO,SAAS,GAAG;AACrB,MAAI,KAAK,EAAE,OAAO,IAAI,WAAW,MAAM,MAAM,EAAE,0CAA0C;AACzF,SAAO,qBAAqB,OAAO;;AAGrC,KAAI,KAAK;EACP,OAAO,IAAI,WAAW,MAAM;EAC5B,QAAQ,OAAO;EAChB,EAAE,uCAAuC;AAE1C,QAAO,qBAAqB;EAC1B,SAAS,OAAO,UAAU,sCAAsC,OAAO;EACvE,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,MAAM,OAAO;EACd,CAAC;;;;;AAMJ,SAAgB,iCAAuD;AACrE,QAAO;EACL,YAAY;EACZ,aAAa;EACd"}
@@ -1,5 +1,9 @@
1
1
  import { registerMarketplaceAdapter } from "../../registry.js";
2
+ import { buildSkillMarkdownPreviewFromRaw } from "../../../skill-markdown-preview-from-raw.js";
2
3
  //#region src/agent/skills/marketplace/adapters/clawhub/adapter.ts
4
+ /**
5
+ * ClawHub (clawhub.ai) skills marketplace adapter.
6
+ */
3
7
  const DEFAULT_CLAWHUB_BASE = "https://clawhub.ai";
4
8
  const MAX_CLAWHUB_FILE_BYTES = 512 * 1024;
5
9
  const MAX_SKILL_ZIP_BYTES = 15 * 1024 * 1024;
@@ -274,12 +278,18 @@ const clawHubMarketplaceAdapter = {
274
278
  if (!readme) readme = fallbackReadmeMarkdown(detail);
275
279
  const changelog = detail.latestVersion.changelog?.trim();
276
280
  if (changelog) readme = `${readme}\n\n---\n\n## Changelog\n\n${changelog}`;
281
+ const description = detail.skill.summary || "";
282
+ const skillDocPreview = buildSkillMarkdownPreviewFromRaw(readme, {
283
+ name: slug,
284
+ description
285
+ });
277
286
  return {
278
287
  id: slug,
279
288
  name: slug,
280
289
  type: "skill",
281
- description: detail.skill.summary || "",
290
+ description,
282
291
  readme,
292
+ skillDocPreview,
283
293
  downloads: detail.skill.stats.downloads,
284
294
  author: {
285
295
  username: detail.owner.handle,
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","names":[],"sources":["../../../../../../../src/agent/skills/marketplace/adapters/clawhub/adapter.ts"],"sourcesContent":["/**\n * ClawHub (clawhub.ai) skills marketplace adapter.\n */\n\nimport type { SkillsMarketplaceAdapter } from '../../adapter.types.js';\nimport { registerMarketplaceAdapter } from '../../registry.js';\n\n// ─── Constants ───────────────────────────────────────────────────────────────\n\nconst DEFAULT_CLAWHUB_BASE = 'https://clawhub.ai';\nconst MAX_CLAWHUB_FILE_BYTES = 512 * 1024;\nconst MAX_SKILL_ZIP_BYTES = 15 * 1024 * 1024;\nconst SKILL_ID_RE = /^[a-zA-Z0-9]([a-zA-Z0-9._-]{0,62})$/;\nconst LIST_BATCH_SIZE = 200;\n\nconst DEFAULT_CACHE_MS = 5 * 60 * 1000;\nconst MAX_LIST_CACHE_KEYS = 24;\nconst MAX_DETAIL_CACHE_KEYS = 48;\n\n// ─── Inline helpers ──────────────────────────────────────────────────────────\n\nfunction isValidSkillId(id: string): boolean {\n return SKILL_ID_RE.test(id);\n}\n\nfunction resolveClawHubBaseUrl(): string {\n const env = process.env.CLAWHUB_REGISTRY?.trim();\n if (env) {\n try {\n return new URL(env).toString().replace(/\\/$/, '');\n } catch {\n // fall through\n }\n }\n return DEFAULT_CLAWHUB_BASE;\n}\n\n// ─── ClawHub API types ───────────────────────────────────────────────────────\n\ninterface ClawHubSkillListItem {\n slug: string;\n displayName: string;\n summary: string;\n tags: Record<string, string>;\n stats: {\n comments: number;\n downloads: number;\n installsAllTime: number;\n installsCurrent: number;\n stars: number;\n versions: number;\n };\n createdAt: number;\n updatedAt: number;\n latestVersion: {\n version: string;\n createdAt: number;\n changelog: string | null;\n license: string | null;\n };\n metadata: { os: string[] | null; systems: string[] | null } | null;\n}\n\ninterface ClawHubSkillListResponse {\n items: ClawHubSkillListItem[];\n nextCursor: string | null;\n}\n\ninterface ClawHubSearchResultItem {\n score: number;\n slug: string;\n displayName: string;\n summary: string;\n version: string | null;\n updatedAt: number;\n ownerHandle: string;\n owner: {\n handle: string;\n displayName: string;\n image: string | null;\n };\n}\n\ninterface ClawHubSearchResponse {\n results: ClawHubSearchResultItem[];\n}\n\ninterface ClawHubSkillDetail {\n skill: {\n slug: string;\n displayName: string;\n summary: string;\n tags: Record<string, string>;\n stats: {\n comments: number;\n downloads: number;\n installsAllTime: number;\n installsCurrent: number;\n stars: number;\n versions: number;\n };\n createdAt: number;\n updatedAt: number;\n };\n latestVersion: {\n version: string;\n createdAt: number;\n changelog: string | null;\n license: string | null;\n };\n metadata: { os: string[] | null; systems: string[] | null } | null;\n owner: {\n handle: string;\n userId: string;\n displayName: string;\n image: string | null;\n };\n moderation: {\n isSuspicious: boolean;\n isMalwareBlocked: boolean;\n verdict: string;\n } | null;\n}\n\ninterface ClawHubVersionFile {\n path: string;\n size: number;\n sha256: string;\n contentType: string;\n}\n\ninterface ClawHubVersionDetail {\n skill: { slug: string; displayName: string };\n version: {\n version: string;\n createdAt: number;\n changelog: string | null;\n changelogSource: string | null;\n license: string | null;\n files: ClawHubVersionFile[];\n security: {\n status: string;\n hasWarnings: boolean;\n hasScanResult: boolean;\n } | null;\n };\n}\n\ntype ClawHubListSort = 'updated' | 'newest' | 'downloads' | 'stars' | 'trending';\n\ninterface ClawHubListParams {\n limit?: number;\n cursor?: string;\n sort?: ClawHubListSort;\n}\n\n// ─── ClawHub HTTP helpers ────────────────────────────────────────────────────\n\nasync function clawHubFetch(path: string, init?: { signal?: AbortSignal }): Promise<Response> {\n const base = resolveClawHubBaseUrl();\n const url = `${base}${path}`;\n const res = await fetch(url, {\n headers: { Accept: 'application/json' },\n signal: init?.signal,\n });\n return res as unknown as Response;\n}\n\nfunction assertOk(res: Response, context: string): void {\n if (!res.ok) {\n throw new Error(`ClawHub ${context} failed (${res.status})`);\n }\n}\n\nasync function listClawHubSkills(params?: ClawHubListParams): Promise<ClawHubSkillListResponse> {\n const sp = new URLSearchParams();\n if (params?.limit) sp.set('limit', String(params.limit));\n if (params?.cursor) sp.set('cursor', params.cursor);\n if (params?.sort) sp.set('sort', params.sort);\n sp.set('nonSuspiciousOnly', 'true');\n const qs = sp.toString();\n const res = await clawHubFetch(`/api/v1/skills${qs ? `?${qs}` : ''}`);\n assertOk(res, 'list skills');\n return (await res.json()) as ClawHubSkillListResponse;\n}\n\nasync function searchClawHubSkills(query: string, limit?: number): Promise<ClawHubSearchResponse> {\n const sp = new URLSearchParams({ q: query, nonSuspiciousOnly: 'true' });\n if (limit) sp.set('limit', String(limit));\n const res = await clawHubFetch(`/api/v1/search?${sp.toString()}`);\n assertOk(res, 'search');\n return (await res.json()) as ClawHubSearchResponse;\n}\n\nasync function getClawHubSkillDetail(slug: string): Promise<ClawHubSkillDetail> {\n const enc = encodeURIComponent(slug.trim());\n const res = await clawHubFetch(`/api/v1/skills/${enc}`);\n assertOk(res, `skill detail [${slug}]`);\n return (await res.json()) as ClawHubSkillDetail;\n}\n\nasync function getClawHubVersionDetail(slug: string, version: string): Promise<ClawHubVersionDetail> {\n const enc = encodeURIComponent(slug.trim());\n const ver = encodeURIComponent(version.trim());\n const res = await clawHubFetch(`/api/v1/skills/${enc}/versions/${ver}`);\n assertOk(res, `version detail [${slug}@${version}]`);\n return (await res.json()) as ClawHubVersionDetail;\n}\n\nasync function getClawHubSkillFileText(slug: string, filePath: string, version?: string): Promise<string> {\n const enc = encodeURIComponent(slug.trim());\n const sp = new URLSearchParams({ path: filePath });\n if (version?.trim()) sp.set('version', version.trim());\n const base = resolveClawHubBaseUrl();\n const url = `${base}/api/v1/skills/${enc}/file?${sp.toString()}`;\n const res = await fetch(url, { headers: { Accept: 'text/markdown,text/plain,*/*' } });\n if (!res.ok) {\n throw new Error(`ClawHub file fetch [${slug}/${filePath}] failed (${res.status})`);\n }\n const text = await res.text();\n return text.length > MAX_CLAWHUB_FILE_BYTES ? text.slice(0, MAX_CLAWHUB_FILE_BYTES) : text;\n}\n\nasync function downloadClawHubSkillZip(\n slug: string,\n version?: string,\n): Promise<{ buffer: Buffer; version: string }> {\n const enc = encodeURIComponent(slug.trim());\n const sp = version?.trim() ? `?version=${encodeURIComponent(version.trim())}` : '';\n const base = resolveClawHubBaseUrl();\n const url = `${base}/api/v1/packages/${enc}/download${sp}`;\n const res = await fetch(url, { redirect: 'follow' });\n if (!res.ok) {\n const body = await res.text().catch(() => '');\n throw new Error(`ClawHub download [${slug}] failed (${res.status}): ${body.slice(0, 200)}`);\n }\n const contentType = res.headers.get('content-type') ?? '';\n if (!contentType.includes('zip') && !contentType.includes('octet-stream')) {\n throw new Error(`ClawHub download [${slug}] unexpected content-type: ${contentType}`);\n }\n const arrayBuf = await res.arrayBuffer();\n if (arrayBuf.byteLength > MAX_SKILL_ZIP_BYTES) {\n throw new Error(\n `ClawHub download [${slug}] exceeds size limit (${arrayBuf.byteLength} > ${MAX_SKILL_ZIP_BYTES})`,\n );\n }\n return { buffer: Buffer.from(arrayBuf), version: version?.trim() || 'latest' };\n}\n\nfunction pickClawHubDocFilePath(files: ClawHubVersionFile[]): string | null {\n const rows = files.map((f) => ({\n path: f.path.replace(/\\\\/g, '/'),\n base: f.path.replace(/\\\\/g, '/').split('/').pop()?.toLowerCase() ?? '',\n }));\n const find = (name: string) => rows.find((r) => r.base === name.toLowerCase());\n const skillMd = find('SKILL.md') ?? find('skill.md');\n if (skillMd) return skillMd.path;\n const readme = find('README.md') ?? find('readme.md');\n if (readme) return readme.path;\n return null;\n}\n\n// ─── In-memory TTL cache ─────────────────────────────────────────────────────\n\ntype CacheEntry<T> = { value: T; expiresAt: number };\n\nfunction cacheTtlMs(): number {\n const raw = process.env.XOPC_CLAWHUB_CACHE_MS?.trim();\n if (raw === '0' || raw === 'false') return 0;\n const parsed = Number(raw);\n if (!Number.isFinite(parsed) || parsed < 0) return DEFAULT_CACHE_MS;\n return parsed;\n}\n\nfunction getFresh<T>(entry: CacheEntry<T> | undefined): T | undefined {\n if (!entry || entry.expiresAt <= Date.now()) return undefined;\n return entry.value;\n}\n\nfunction evictOldest<T>(map: Map<string, CacheEntry<T>>): void {\n const first = map.keys().next().value;\n if (first !== undefined) map.delete(first);\n}\n\nconst listCache = new Map<string, CacheEntry<ClawHubSkillListResponse>>();\nconst searchCache = new Map<string, CacheEntry<ClawHubSearchResponse>>();\nconst detailCache = new Map<string, CacheEntry<ClawHubSkillDetail>>();\n\nasync function cachedListClawHubSkills(params?: ClawHubListParams): Promise<ClawHubSkillListResponse> {\n const ttl = cacheTtlMs();\n const key = JSON.stringify(params ?? {});\n if (ttl > 0) {\n const hit = getFresh(listCache.get(key));\n if (hit) return hit;\n }\n const value = await listClawHubSkills(params);\n if (ttl > 0) {\n while (listCache.size >= MAX_LIST_CACHE_KEYS) evictOldest(listCache);\n listCache.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\nasync function cachedSearchClawHubSkills(query: string, limit?: number): Promise<ClawHubSearchResponse> {\n const ttl = cacheTtlMs();\n const key = `${query}::${limit ?? ''}`;\n if (ttl > 0) {\n const hit = getFresh(searchCache.get(key));\n if (hit) return hit;\n }\n const value = await searchClawHubSkills(query, limit);\n if (ttl > 0) {\n while (searchCache.size >= MAX_LIST_CACHE_KEYS) evictOldest(searchCache);\n searchCache.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\nasync function cachedGetClawHubSkillDetail(slug: string): Promise<ClawHubSkillDetail> {\n const ttl = cacheTtlMs();\n const key = slug.trim();\n if (ttl > 0) {\n const hit = getFresh(detailCache.get(key));\n if (hit) return hit;\n }\n const value = await getClawHubSkillDetail(slug);\n if (ttl > 0) {\n while (detailCache.size >= MAX_DETAIL_CACHE_KEYS) evictOldest(detailCache);\n detailCache.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\n// ─── Adapter conversion helpers ──────────────────────────────────────────────\n\ninterface PackageListItem {\n id: string;\n name: string;\n type: string;\n description: string;\n downloads: number;\n author: { username: string; avatarUrl: string | null };\n latestVersion?: string;\n updatedAt: string;\n categories?: string[];\n stars?: number;\n sourceLabel?: string;\n}\n\nfunction convertListItemToPackageItem(item: ClawHubSkillListItem): PackageListItem {\n return {\n id: item.slug,\n name: item.displayName || item.slug,\n type: 'skill',\n description: item.summary || '',\n downloads: item.stats.downloads,\n author: { username: 'clawhub', avatarUrl: null },\n latestVersion: item.latestVersion?.version ?? item.tags.latest ?? '1.0.0',\n updatedAt: String(item.updatedAt),\n categories: item.metadata?.os ?? [],\n stars: item.stats.stars,\n sourceLabel: 'ClawHub',\n };\n}\n\nfunction convertSearchResultToPackageItem(\n item: ClawHubSearchResultItem,\n enrichment?: ClawHubSkillListItem,\n): PackageListItem {\n return {\n id: item.slug,\n name: item.displayName || item.slug,\n type: 'skill',\n description: item.summary || '',\n downloads: enrichment?.stats.downloads ?? 0,\n author: {\n username: item.owner?.handle ?? item.ownerHandle ?? 'clawhub',\n avatarUrl: item.owner?.image ?? null,\n },\n latestVersion: item.version ?? enrichment?.latestVersion?.version ?? '1.0.0',\n updatedAt: String(item.updatedAt),\n categories: enrichment?.metadata?.os ?? [],\n stars: enrichment?.stats.stars ?? 0,\n sourceLabel: 'ClawHub',\n };\n}\n\nfunction mapSortParam(sort?: string): ClawHubListSort | undefined {\n if (sort === 'downloads') return 'downloads';\n if (sort === 'newest') return 'newest';\n return undefined;\n}\n\nfunction fallbackReadmeMarkdown(detail: {\n skill: { slug: string; displayName: string; summary: string };\n latestVersion: { version: string };\n}): string {\n const title = detail.skill.displayName || detail.skill.slug;\n const body = detail.skill.summary || '_No description._';\n return `## ${title}\\n\\n**${detail.skill.slug}** · v${detail.latestVersion.version}\\n\\n${body}`;\n}\n\nexport const clawHubMarketplaceAdapter: SkillsMarketplaceAdapter = {\n id: 'clawhub',\n\n async listCategories() {\n return [];\n },\n\n async listPackages(_config, params) {\n const pageSize = params.pageSize ?? 20;\n const page = params.page ?? 1;\n\n if (params.q?.trim()) {\n // Search results from /search omit downloads/stars/metadata. We pull the cached list\n // snapshot in parallel and merge by slug — costs nothing when the list cache is hot\n // (which it is after any preceding browse), and adds at most one round-trip on a cold\n // cache. We still tolerate a list-fetch failure: enrichment becomes a no-op.\n const [searchResponse, listSettled] = await Promise.allSettled([\n cachedSearchClawHubSkills(params.q.trim(), LIST_BATCH_SIZE),\n cachedListClawHubSkills({ limit: LIST_BATCH_SIZE }),\n ]);\n if (searchResponse.status === 'rejected') throw searchResponse.reason;\n const enrichmentBySlug = new Map<string, ClawHubSkillListItem>();\n if (listSettled.status === 'fulfilled') {\n for (const it of listSettled.value.items) enrichmentBySlug.set(it.slug, it);\n }\n let rows = searchResponse.value.results.map((r) =>\n convertSearchResultToPackageItem(r, enrichmentBySlug.get(r.slug)),\n );\n if (params.sort === 'downloads') {\n rows = [...rows].sort((a, b) => b.downloads - a.downloads);\n } else if (params.sort === 'newest') {\n rows = [...rows].sort((a, b) => Number(b.updatedAt) - Number(a.updatedAt));\n }\n const total = rows.length;\n const start = (page - 1) * pageSize;\n const items = rows.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'clawhub' };\n }\n\n const sort = mapSortParam(params.sort);\n const listResponse = await cachedListClawHubSkills({ limit: LIST_BATCH_SIZE, sort });\n const rows = listResponse.items.map(convertListItemToPackageItem);\n const total = rows.length;\n const start = (page - 1) * pageSize;\n const items = rows.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'clawhub' };\n },\n\n async getPackageDetail(_config, packageName) {\n const detail = await cachedGetClawHubSkillDetail(packageName);\n const slug = detail.skill.slug;\n const version = detail.latestVersion.version;\n\n let readme: string | null = null;\n\n try {\n const versionDetail = await getClawHubVersionDetail(slug, version);\n const docPath = pickClawHubDocFilePath(versionDetail.version.files);\n if (docPath) {\n const rawText = await getClawHubSkillFileText(slug, docPath, version);\n const trimmed = rawText.trim();\n if (trimmed) readme = trimmed;\n }\n } catch {\n // version detail or file fetch failed — use fallback\n }\n\n if (!readme) {\n readme = fallbackReadmeMarkdown(detail);\n }\n\n const changelog = detail.latestVersion.changelog?.trim();\n if (changelog) {\n readme = `${readme}\\n\\n---\\n\\n## Changelog\\n\\n${changelog}`;\n }\n\n return {\n id: slug,\n name: slug,\n type: 'skill',\n description: detail.skill.summary || '',\n readme,\n downloads: detail.skill.stats.downloads,\n author: {\n username: detail.owner.handle,\n avatarUrl: detail.owner.image,\n },\n latestVersion: {\n version: detail.latestVersion.version,\n changelog: detail.latestVersion.changelog,\n publishedAt: String(detail.latestVersion.createdAt),\n },\n provider: 'clawhub',\n };\n },\n\n async downloadPackage(_config, packageName, version) {\n const slug = packageName.trim();\n const result = await downloadClawHubSkillZip(slug, version);\n return {\n buffer: result.buffer,\n skillId: isValidSkillId(slug) ? slug : 'unknown',\n version: result.version,\n };\n },\n};\n\nregisterMarketplaceAdapter({\n adapter: clawHubMarketplaceAdapter,\n displayName: 'ClawHub',\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"adapter.js","names":[],"sources":["../../../../../../../src/agent/skills/marketplace/adapters/clawhub/adapter.ts"],"sourcesContent":["/**\n * ClawHub (clawhub.ai) skills marketplace adapter.\n */\n\nimport { buildSkillMarkdownPreviewFromRaw } from '../../../skill-markdown-preview-from-raw.js';\nimport type { SkillsMarketplaceAdapter } from '../../adapter.types.js';\nimport { registerMarketplaceAdapter } from '../../registry.js';\n\n// ─── Constants ───────────────────────────────────────────────────────────────\n\nconst DEFAULT_CLAWHUB_BASE = 'https://clawhub.ai';\nconst MAX_CLAWHUB_FILE_BYTES = 512 * 1024;\nconst MAX_SKILL_ZIP_BYTES = 15 * 1024 * 1024;\nconst SKILL_ID_RE = /^[a-zA-Z0-9]([a-zA-Z0-9._-]{0,62})$/;\nconst LIST_BATCH_SIZE = 200;\n\nconst DEFAULT_CACHE_MS = 5 * 60 * 1000;\nconst MAX_LIST_CACHE_KEYS = 24;\nconst MAX_DETAIL_CACHE_KEYS = 48;\n\n// ─── Inline helpers ──────────────────────────────────────────────────────────\n\nfunction isValidSkillId(id: string): boolean {\n return SKILL_ID_RE.test(id);\n}\n\nfunction resolveClawHubBaseUrl(): string {\n const env = process.env.CLAWHUB_REGISTRY?.trim();\n if (env) {\n try {\n return new URL(env).toString().replace(/\\/$/, '');\n } catch {\n // fall through\n }\n }\n return DEFAULT_CLAWHUB_BASE;\n}\n\n// ─── ClawHub API types ───────────────────────────────────────────────────────\n\ninterface ClawHubSkillListItem {\n slug: string;\n displayName: string;\n summary: string;\n tags: Record<string, string>;\n stats: {\n comments: number;\n downloads: number;\n installsAllTime: number;\n installsCurrent: number;\n stars: number;\n versions: number;\n };\n createdAt: number;\n updatedAt: number;\n latestVersion: {\n version: string;\n createdAt: number;\n changelog: string | null;\n license: string | null;\n };\n metadata: { os: string[] | null; systems: string[] | null } | null;\n}\n\ninterface ClawHubSkillListResponse {\n items: ClawHubSkillListItem[];\n nextCursor: string | null;\n}\n\ninterface ClawHubSearchResultItem {\n score: number;\n slug: string;\n displayName: string;\n summary: string;\n version: string | null;\n updatedAt: number;\n ownerHandle: string;\n owner: {\n handle: string;\n displayName: string;\n image: string | null;\n };\n}\n\ninterface ClawHubSearchResponse {\n results: ClawHubSearchResultItem[];\n}\n\ninterface ClawHubSkillDetail {\n skill: {\n slug: string;\n displayName: string;\n summary: string;\n tags: Record<string, string>;\n stats: {\n comments: number;\n downloads: number;\n installsAllTime: number;\n installsCurrent: number;\n stars: number;\n versions: number;\n };\n createdAt: number;\n updatedAt: number;\n };\n latestVersion: {\n version: string;\n createdAt: number;\n changelog: string | null;\n license: string | null;\n };\n metadata: { os: string[] | null; systems: string[] | null } | null;\n owner: {\n handle: string;\n userId: string;\n displayName: string;\n image: string | null;\n };\n moderation: {\n isSuspicious: boolean;\n isMalwareBlocked: boolean;\n verdict: string;\n } | null;\n}\n\ninterface ClawHubVersionFile {\n path: string;\n size: number;\n sha256: string;\n contentType: string;\n}\n\ninterface ClawHubVersionDetail {\n skill: { slug: string; displayName: string };\n version: {\n version: string;\n createdAt: number;\n changelog: string | null;\n changelogSource: string | null;\n license: string | null;\n files: ClawHubVersionFile[];\n security: {\n status: string;\n hasWarnings: boolean;\n hasScanResult: boolean;\n } | null;\n };\n}\n\ntype ClawHubListSort = 'updated' | 'newest' | 'downloads' | 'stars' | 'trending';\n\ninterface ClawHubListParams {\n limit?: number;\n cursor?: string;\n sort?: ClawHubListSort;\n}\n\n// ─── ClawHub HTTP helpers ────────────────────────────────────────────────────\n\nasync function clawHubFetch(path: string, init?: { signal?: AbortSignal }): Promise<Response> {\n const base = resolveClawHubBaseUrl();\n const url = `${base}${path}`;\n const res = await fetch(url, {\n headers: { Accept: 'application/json' },\n signal: init?.signal,\n });\n return res as unknown as Response;\n}\n\nfunction assertOk(res: Response, context: string): void {\n if (!res.ok) {\n throw new Error(`ClawHub ${context} failed (${res.status})`);\n }\n}\n\nasync function listClawHubSkills(params?: ClawHubListParams): Promise<ClawHubSkillListResponse> {\n const sp = new URLSearchParams();\n if (params?.limit) sp.set('limit', String(params.limit));\n if (params?.cursor) sp.set('cursor', params.cursor);\n if (params?.sort) sp.set('sort', params.sort);\n sp.set('nonSuspiciousOnly', 'true');\n const qs = sp.toString();\n const res = await clawHubFetch(`/api/v1/skills${qs ? `?${qs}` : ''}`);\n assertOk(res, 'list skills');\n return (await res.json()) as ClawHubSkillListResponse;\n}\n\nasync function searchClawHubSkills(query: string, limit?: number): Promise<ClawHubSearchResponse> {\n const sp = new URLSearchParams({ q: query, nonSuspiciousOnly: 'true' });\n if (limit) sp.set('limit', String(limit));\n const res = await clawHubFetch(`/api/v1/search?${sp.toString()}`);\n assertOk(res, 'search');\n return (await res.json()) as ClawHubSearchResponse;\n}\n\nasync function getClawHubSkillDetail(slug: string): Promise<ClawHubSkillDetail> {\n const enc = encodeURIComponent(slug.trim());\n const res = await clawHubFetch(`/api/v1/skills/${enc}`);\n assertOk(res, `skill detail [${slug}]`);\n return (await res.json()) as ClawHubSkillDetail;\n}\n\nasync function getClawHubVersionDetail(slug: string, version: string): Promise<ClawHubVersionDetail> {\n const enc = encodeURIComponent(slug.trim());\n const ver = encodeURIComponent(version.trim());\n const res = await clawHubFetch(`/api/v1/skills/${enc}/versions/${ver}`);\n assertOk(res, `version detail [${slug}@${version}]`);\n return (await res.json()) as ClawHubVersionDetail;\n}\n\nasync function getClawHubSkillFileText(slug: string, filePath: string, version?: string): Promise<string> {\n const enc = encodeURIComponent(slug.trim());\n const sp = new URLSearchParams({ path: filePath });\n if (version?.trim()) sp.set('version', version.trim());\n const base = resolveClawHubBaseUrl();\n const url = `${base}/api/v1/skills/${enc}/file?${sp.toString()}`;\n const res = await fetch(url, { headers: { Accept: 'text/markdown,text/plain,*/*' } });\n if (!res.ok) {\n throw new Error(`ClawHub file fetch [${slug}/${filePath}] failed (${res.status})`);\n }\n const text = await res.text();\n return text.length > MAX_CLAWHUB_FILE_BYTES ? text.slice(0, MAX_CLAWHUB_FILE_BYTES) : text;\n}\n\nasync function downloadClawHubSkillZip(\n slug: string,\n version?: string,\n): Promise<{ buffer: Buffer; version: string }> {\n const enc = encodeURIComponent(slug.trim());\n const sp = version?.trim() ? `?version=${encodeURIComponent(version.trim())}` : '';\n const base = resolveClawHubBaseUrl();\n const url = `${base}/api/v1/packages/${enc}/download${sp}`;\n const res = await fetch(url, { redirect: 'follow' });\n if (!res.ok) {\n const body = await res.text().catch(() => '');\n throw new Error(`ClawHub download [${slug}] failed (${res.status}): ${body.slice(0, 200)}`);\n }\n const contentType = res.headers.get('content-type') ?? '';\n if (!contentType.includes('zip') && !contentType.includes('octet-stream')) {\n throw new Error(`ClawHub download [${slug}] unexpected content-type: ${contentType}`);\n }\n const arrayBuf = await res.arrayBuffer();\n if (arrayBuf.byteLength > MAX_SKILL_ZIP_BYTES) {\n throw new Error(\n `ClawHub download [${slug}] exceeds size limit (${arrayBuf.byteLength} > ${MAX_SKILL_ZIP_BYTES})`,\n );\n }\n return { buffer: Buffer.from(arrayBuf), version: version?.trim() || 'latest' };\n}\n\nfunction pickClawHubDocFilePath(files: ClawHubVersionFile[]): string | null {\n const rows = files.map((f) => ({\n path: f.path.replace(/\\\\/g, '/'),\n base: f.path.replace(/\\\\/g, '/').split('/').pop()?.toLowerCase() ?? '',\n }));\n const find = (name: string) => rows.find((r) => r.base === name.toLowerCase());\n const skillMd = find('SKILL.md') ?? find('skill.md');\n if (skillMd) return skillMd.path;\n const readme = find('README.md') ?? find('readme.md');\n if (readme) return readme.path;\n return null;\n}\n\n// ─── In-memory TTL cache ─────────────────────────────────────────────────────\n\ntype CacheEntry<T> = { value: T; expiresAt: number };\n\nfunction cacheTtlMs(): number {\n const raw = process.env.XOPC_CLAWHUB_CACHE_MS?.trim();\n if (raw === '0' || raw === 'false') return 0;\n const parsed = Number(raw);\n if (!Number.isFinite(parsed) || parsed < 0) return DEFAULT_CACHE_MS;\n return parsed;\n}\n\nfunction getFresh<T>(entry: CacheEntry<T> | undefined): T | undefined {\n if (!entry || entry.expiresAt <= Date.now()) return undefined;\n return entry.value;\n}\n\nfunction evictOldest<T>(map: Map<string, CacheEntry<T>>): void {\n const first = map.keys().next().value;\n if (first !== undefined) map.delete(first);\n}\n\nconst listCache = new Map<string, CacheEntry<ClawHubSkillListResponse>>();\nconst searchCache = new Map<string, CacheEntry<ClawHubSearchResponse>>();\nconst detailCache = new Map<string, CacheEntry<ClawHubSkillDetail>>();\n\nasync function cachedListClawHubSkills(params?: ClawHubListParams): Promise<ClawHubSkillListResponse> {\n const ttl = cacheTtlMs();\n const key = JSON.stringify(params ?? {});\n if (ttl > 0) {\n const hit = getFresh(listCache.get(key));\n if (hit) return hit;\n }\n const value = await listClawHubSkills(params);\n if (ttl > 0) {\n while (listCache.size >= MAX_LIST_CACHE_KEYS) evictOldest(listCache);\n listCache.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\nasync function cachedSearchClawHubSkills(query: string, limit?: number): Promise<ClawHubSearchResponse> {\n const ttl = cacheTtlMs();\n const key = `${query}::${limit ?? ''}`;\n if (ttl > 0) {\n const hit = getFresh(searchCache.get(key));\n if (hit) return hit;\n }\n const value = await searchClawHubSkills(query, limit);\n if (ttl > 0) {\n while (searchCache.size >= MAX_LIST_CACHE_KEYS) evictOldest(searchCache);\n searchCache.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\nasync function cachedGetClawHubSkillDetail(slug: string): Promise<ClawHubSkillDetail> {\n const ttl = cacheTtlMs();\n const key = slug.trim();\n if (ttl > 0) {\n const hit = getFresh(detailCache.get(key));\n if (hit) return hit;\n }\n const value = await getClawHubSkillDetail(slug);\n if (ttl > 0) {\n while (detailCache.size >= MAX_DETAIL_CACHE_KEYS) evictOldest(detailCache);\n detailCache.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\n// ─── Adapter conversion helpers ──────────────────────────────────────────────\n\ninterface PackageListItem {\n id: string;\n name: string;\n type: string;\n description: string;\n downloads: number;\n author: { username: string; avatarUrl: string | null };\n latestVersion?: string;\n updatedAt: string;\n categories?: string[];\n stars?: number;\n sourceLabel?: string;\n}\n\nfunction convertListItemToPackageItem(item: ClawHubSkillListItem): PackageListItem {\n return {\n id: item.slug,\n name: item.displayName || item.slug,\n type: 'skill',\n description: item.summary || '',\n downloads: item.stats.downloads,\n author: { username: 'clawhub', avatarUrl: null },\n latestVersion: item.latestVersion?.version ?? item.tags.latest ?? '1.0.0',\n updatedAt: String(item.updatedAt),\n categories: item.metadata?.os ?? [],\n stars: item.stats.stars,\n sourceLabel: 'ClawHub',\n };\n}\n\nfunction convertSearchResultToPackageItem(\n item: ClawHubSearchResultItem,\n enrichment?: ClawHubSkillListItem,\n): PackageListItem {\n return {\n id: item.slug,\n name: item.displayName || item.slug,\n type: 'skill',\n description: item.summary || '',\n downloads: enrichment?.stats.downloads ?? 0,\n author: {\n username: item.owner?.handle ?? item.ownerHandle ?? 'clawhub',\n avatarUrl: item.owner?.image ?? null,\n },\n latestVersion: item.version ?? enrichment?.latestVersion?.version ?? '1.0.0',\n updatedAt: String(item.updatedAt),\n categories: enrichment?.metadata?.os ?? [],\n stars: enrichment?.stats.stars ?? 0,\n sourceLabel: 'ClawHub',\n };\n}\n\nfunction mapSortParam(sort?: string): ClawHubListSort | undefined {\n if (sort === 'downloads') return 'downloads';\n if (sort === 'newest') return 'newest';\n return undefined;\n}\n\nfunction fallbackReadmeMarkdown(detail: {\n skill: { slug: string; displayName: string; summary: string };\n latestVersion: { version: string };\n}): string {\n const title = detail.skill.displayName || detail.skill.slug;\n const body = detail.skill.summary || '_No description._';\n return `## ${title}\\n\\n**${detail.skill.slug}** · v${detail.latestVersion.version}\\n\\n${body}`;\n}\n\nexport const clawHubMarketplaceAdapter: SkillsMarketplaceAdapter = {\n id: 'clawhub',\n\n async listCategories() {\n return [];\n },\n\n async listPackages(_config, params) {\n const pageSize = params.pageSize ?? 20;\n const page = params.page ?? 1;\n\n if (params.q?.trim()) {\n // Search results from /search omit downloads/stars/metadata. We pull the cached list\n // snapshot in parallel and merge by slug — costs nothing when the list cache is hot\n // (which it is after any preceding browse), and adds at most one round-trip on a cold\n // cache. We still tolerate a list-fetch failure: enrichment becomes a no-op.\n const [searchResponse, listSettled] = await Promise.allSettled([\n cachedSearchClawHubSkills(params.q.trim(), LIST_BATCH_SIZE),\n cachedListClawHubSkills({ limit: LIST_BATCH_SIZE }),\n ]);\n if (searchResponse.status === 'rejected') throw searchResponse.reason;\n const enrichmentBySlug = new Map<string, ClawHubSkillListItem>();\n if (listSettled.status === 'fulfilled') {\n for (const it of listSettled.value.items) enrichmentBySlug.set(it.slug, it);\n }\n let rows = searchResponse.value.results.map((r) =>\n convertSearchResultToPackageItem(r, enrichmentBySlug.get(r.slug)),\n );\n if (params.sort === 'downloads') {\n rows = [...rows].sort((a, b) => b.downloads - a.downloads);\n } else if (params.sort === 'newest') {\n rows = [...rows].sort((a, b) => Number(b.updatedAt) - Number(a.updatedAt));\n }\n const total = rows.length;\n const start = (page - 1) * pageSize;\n const items = rows.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'clawhub' };\n }\n\n const sort = mapSortParam(params.sort);\n const listResponse = await cachedListClawHubSkills({ limit: LIST_BATCH_SIZE, sort });\n const rows = listResponse.items.map(convertListItemToPackageItem);\n const total = rows.length;\n const start = (page - 1) * pageSize;\n const items = rows.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'clawhub' };\n },\n\n async getPackageDetail(_config, packageName) {\n const detail = await cachedGetClawHubSkillDetail(packageName);\n const slug = detail.skill.slug;\n const version = detail.latestVersion.version;\n\n let readme: string | null = null;\n\n try {\n const versionDetail = await getClawHubVersionDetail(slug, version);\n const docPath = pickClawHubDocFilePath(versionDetail.version.files);\n if (docPath) {\n const rawText = await getClawHubSkillFileText(slug, docPath, version);\n const trimmed = rawText.trim();\n if (trimmed) readme = trimmed;\n }\n } catch {\n // version detail or file fetch failed — use fallback\n }\n\n if (!readme) {\n readme = fallbackReadmeMarkdown(detail);\n }\n\n const changelog = detail.latestVersion.changelog?.trim();\n if (changelog) {\n readme = `${readme}\\n\\n---\\n\\n## Changelog\\n\\n${changelog}`;\n }\n\n const description = detail.skill.summary || '';\n const skillDocPreview = buildSkillMarkdownPreviewFromRaw(readme, {\n name: slug,\n description,\n });\n\n return {\n id: slug,\n name: slug,\n type: 'skill',\n description,\n readme,\n skillDocPreview,\n downloads: detail.skill.stats.downloads,\n author: {\n username: detail.owner.handle,\n avatarUrl: detail.owner.image,\n },\n latestVersion: {\n version: detail.latestVersion.version,\n changelog: detail.latestVersion.changelog,\n publishedAt: String(detail.latestVersion.createdAt),\n },\n provider: 'clawhub',\n };\n },\n\n async downloadPackage(_config, packageName, version) {\n const slug = packageName.trim();\n const result = await downloadClawHubSkillZip(slug, version);\n return {\n buffer: result.buffer,\n skillId: isValidSkillId(slug) ? slug : 'unknown',\n version: result.version,\n };\n },\n};\n\nregisterMarketplaceAdapter({\n adapter: clawHubMarketplaceAdapter,\n displayName: 'ClawHub',\n});\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { registerMarketplaceAdapter } from "../../registry.js";
2
+ import { buildSkillMarkdownPreviewFromRaw } from "../../../skill-markdown-preview-from-raw.js";
2
3
  import { sortMarketplaceCategories } from "../../marketplace-category-order.js";
3
4
  import { basename } from "node:path";
4
5
  //#region src/agent/skills/marketplace/adapters/skillhub/adapter.ts
@@ -334,12 +335,19 @@ function packageDetailFromCuratedSkill(skill) {
334
335
  const version = (skill.version ?? "").trim() || "1.0.0";
335
336
  const categories = (skill.categories ?? []).map((c) => String(c).trim()).filter(Boolean);
336
337
  const sourceLabel = sourceLabelFromHomepage(skill.homepage);
338
+ const name = (skill.name ?? slug).trim() || slug;
339
+ const description = (skill.description ?? "").trim();
340
+ const readme = curatedSkillFallbackReadmeMarkdown(skill);
337
341
  return {
338
342
  id: slug,
339
- name: (skill.name ?? slug).trim() || slug,
343
+ name,
340
344
  type: "skill",
341
- description: (skill.description ?? "").trim(),
342
- readme: curatedSkillFallbackReadmeMarkdown(skill),
345
+ description,
346
+ readme,
347
+ skillDocPreview: buildSkillMarkdownPreviewFromRaw(readme, {
348
+ name,
349
+ description
350
+ }),
343
351
  downloads: typeof skill.downloads === "number" ? skill.downloads : 0,
344
352
  author: {
345
353
  username: sourceLabel?.toLowerCase() ?? "skillhub",
@@ -761,12 +769,18 @@ const skillHubMarketplaceAdapter = {
761
769
  readme = trimmed;
762
770
  if (changelog?.trim() && !isPipelineOnlyChangelog(changelog)) readme = `${trimmed}\n\n---\n\n## Changelog\n\n${changelog.trim()}`;
763
771
  }
772
+ const description = detail.skill.summary_zh || detail.skill.summary;
773
+ const skillDocPreview = buildSkillMarkdownPreviewFromRaw(readme, {
774
+ name: detail.skill.slug,
775
+ description
776
+ });
764
777
  return {
765
778
  id: detail.skill.slug,
766
779
  name: detail.skill.slug,
767
780
  type: "skill",
768
- description: detail.skill.summary_zh || detail.skill.summary,
781
+ description,
769
782
  readme,
783
+ skillDocPreview,
770
784
  downloads: detail.skill.stats.downloads,
771
785
  author: {
772
786
  username: detail.owner.handle,
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","names":[],"sources":["../../../../../../../src/agent/skills/marketplace/adapters/skillhub/adapter.ts"],"sourcesContent":["/**\n * SkillHub (skillhub.cn) skills marketplace adapter.\n */\n\nimport { basename } from 'node:path';\n\nimport type { MarketplaceCategoryOption } from '../store/store-api-client.js';\nimport type { SkillsMarketplaceAdapter } from '../../adapter.types.js';\nimport { sortMarketplaceCategories } from '../../marketplace-category-order.js';\nimport { registerMarketplaceAdapter } from '../../registry.js';\n\n// ─── Constants ───────────────────────────────────────────────────────────────\n\nconst SKILLHUB_API_BASE = 'https://api.skillhub.cn';\nconst MAX_SKILL_ZIP_BYTES = 15 * 1024 * 1024;\nconst MAX_SKILLHUB_README_BYTES = 512 * 1024;\nconst SKILL_ID_RE = /^[a-zA-Z0-9]([a-zA-Z0-9._-]{0,62})$/;\nconst REGISTRY_SKILL_BATCH_CHUNK = 80;\n\nconst DEFAULT_SKILLS_INDEX_URL = 'https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/skills.json';\nconst DEFAULT_SEARCH_URL = 'https://lightmake.site/api/v1/search';\nconst DEFAULT_PRIMARY_DOWNLOAD_TEMPLATE = 'https://lightmake.site/api/v1/download?slug={slug}';\nconst DEFAULT_FALLBACK_DOWNLOAD_TEMPLATE =\n 'https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/skills/{slug}.zip';\nconst DEFAULT_ALLOWED_DOWNLOAD_HOSTS = new Set([\n 'lightmake.site',\n 'api.skillhub.cn',\n 'skillhub-1388575217.cos.ap-guangzhou.myqcloud.com',\n]);\nconst LIGHTMAKE_SEARCH_MAX = 100;\nconst SKILLSET_DISCOVERY_PAGE_CAP = 25;\nconst MAX_DEFAULT_SLUGS = 200;\n\nconst DEFAULT_CACHE_MS = 5 * 60 * 1000;\nconst MAX_BATCH_CACHE_KEYS = 48;\n\n// ─── Inline helpers ──────────────────────────────────────────────────────────\n\nfunction isValidSkillId(id: string): boolean {\n return SKILL_ID_RE.test(id);\n}\n\n// ─── SkillHub registry types ─────────────────────────────────────────────────\n\ninterface SkillHubSkill {\n slug: string;\n displayName: string;\n summary: string;\n summary_zh?: string;\n category: string;\n iconUrl: string | null;\n source: string;\n labels: { requires_api_key?: string };\n stats: {\n downloads: number;\n installs: number;\n stars: number;\n comments: number;\n versions: number;\n };\n createdAt: number;\n updatedAt: number;\n tags: Record<string, string>;\n}\n\ninterface SkillHubSkillDetail {\n skill: SkillHubSkill;\n latestVersion: {\n version: string;\n changelog: string | null;\n createdAt: number;\n securityReports?: {\n keen?: { status: string; statusText: string; reportUrl?: string };\n sanbu?: { status: string; statusText: string; reportUrl?: string };\n };\n };\n owner: { handle: string; displayName: string; image: string | null };\n}\n\ninterface SkillHubFile { path: string; sha256: string; size: number }\n\ninterface SkillHubRegistryCategoryItem {\n key: string;\n name: string;\n nameEn: string;\n sortOrder: number;\n active: boolean;\n}\n\ninterface SkillHubSkillset {\n id: number;\n slug: string;\n displayName: string;\n summary: string;\n scene: string;\n subScene: string;\n content: string;\n skillSlugs: string[];\n skillCount: number;\n createdAt: number;\n updatedAt: number;\n}\n\n// ─── Ecosystem types ─────────────────────────────────────────────────────────\n\ninterface EcosystemUrls {\n skillsIndexUrl: string;\n searchUrl: string;\n primaryDownloadTemplate: string;\n fallbackDownloadTemplate: string;\n}\n\ninterface CuratedIndexSkill {\n rank?: number;\n slug: string;\n name?: string;\n description?: string;\n version?: string;\n homepage?: string;\n downloads?: number;\n stars?: number;\n score?: number;\n categories?: string[];\n}\n\ninterface CuratedIndex {\n total?: number;\n skills: CuratedIndexSkill[];\n}\n\ninterface LightmakeSearchHit {\n slug: string;\n displayName?: string;\n name?: string;\n summary?: string;\n description?: string;\n description_zh?: string;\n version?: string;\n downloads?: number;\n installs?: number;\n stars?: number;\n owner_name?: string;\n category?: string;\n score?: number;\n updatedAt?: number;\n updated_at?: number;\n /** Origin registry label from Lightmake (e.g. clawhub, community). Detail/download still go\n * through api.skillhub.cn for synced skills. */\n source?: string;\n}\n\ninterface PackageListItem {\n id: string;\n name: string;\n type: string;\n description: string;\n downloads: number;\n author: { username: string; avatarUrl: string | null };\n latestVersion?: string;\n updatedAt: string;\n categories?: string[];\n stars?: number;\n sourceLabel?: string;\n}\n\n// ─── Registry HTTP helpers ───────────────────────────────────────────────────\n\nasync function registryFetchJson<T>(url: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, {\n ...init,\n headers: { Accept: 'application/json', ...(init?.headers as Record<string, string> | undefined) },\n });\n const text = await res.text();\n if (!res.ok) {\n let msg = `SkillHub request failed (${res.status})`;\n try {\n const j = JSON.parse(text) as { message?: string; error?: string };\n if (j.message) msg = j.message;\n else if (j.error) msg = j.error;\n } catch { if (text) msg = text.slice(0, 200); }\n throw new Error(msg);\n }\n try { return JSON.parse(text) as T; }\n catch { throw new Error('SkillHub returned invalid JSON'); }\n}\n\nfunction basenameSkillPath(p: string): string {\n const norm = p.replace(/\\\\/g, '/');\n const parts = norm.split('/');\n return parts[parts.length - 1] || norm;\n}\n\nfunction pickSkillHubDocFilePath(files: SkillHubFile[]): string | null {\n const rows = files.map((f) => ({\n path: f.path.replace(/\\\\/g, '/'),\n base: basenameSkillPath(f.path).toLowerCase(),\n }));\n const firstBase = (name: string) => rows.find((r) => r.base === name.toLowerCase());\n const skillMd = firstBase('SKILL.md') ?? firstBase('skill.md');\n if (skillMd) return skillMd.path;\n const readme = firstBase('README.md') ?? firstBase('readme.md');\n if (readme) return readme.path;\n const how = firstBase('HOW_TO_USE.md');\n if (how) return how.path;\n return null;\n}\n\nfunction assertSkillHubReadmeResponseUrl(finalUrl: string): void {\n let u: URL;\n try { u = new URL(finalUrl); } catch { throw new Error('Invalid SkillHub file response URL'); }\n if (u.protocol !== 'https:') throw new Error('SkillHub file response must use HTTPS');\n const host = u.hostname.toLowerCase();\n if (host === 'api.skillhub.cn') return;\n if (host.endsWith('.myqcloud.com')) return;\n throw new Error('SkillHub file redirect host is not allowlisted');\n}\n\nasync function getSkillHubSkillFileText(slug: string, filePath: string, version?: string): Promise<string> {\n const enc = encodeURIComponent(slug.trim());\n const normPath = filePath.replace(/\\\\/g, '/');\n const sp = new URLSearchParams({ path: normPath });\n if (version?.trim()) sp.set('version', version.trim());\n const url = `${SKILLHUB_API_BASE}/api/v1/skills/${enc}/file?${sp.toString()}`;\n const res = await fetch(url, { redirect: 'follow', headers: { Accept: 'text/markdown,text/plain,*/*' } });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n let msg = `SkillHub file request failed (${res.status})`;\n try {\n const j = JSON.parse(text) as { message?: string; error?: string };\n if (typeof j.message === 'string') msg = j.message;\n else if (typeof j.error === 'string') msg = j.error;\n } catch { if (text) msg = text.slice(0, 200); }\n throw new Error(msg);\n }\n assertSkillHubReadmeResponseUrl(res.url);\n const len = res.headers.get('content-length');\n if (len) {\n const n = Number(len);\n if (Number.isFinite(n) && n > MAX_SKILLHUB_README_BYTES) throw new Error(`SkillHub file exceeds max size`);\n }\n const ab = await res.arrayBuffer();\n if (ab.byteLength > MAX_SKILLHUB_README_BYTES) throw new Error(`SkillHub file exceeds max size`);\n return new TextDecoder('utf-8').decode(ab);\n}\n\nasync function getSkillHubSkill(slug: string): Promise<SkillHubSkillDetail> {\n return registryFetchJson<SkillHubSkillDetail>(`${SKILLHUB_API_BASE}/api/v1/skills/${encodeURIComponent(slug.trim())}`);\n}\n\nasync function getSkillHubSkillFiles(slug: string, version?: string): Promise<{ files: SkillHubFile[]; version: string }> {\n const enc = encodeURIComponent(slug.trim());\n const sp = version ? `?version=${encodeURIComponent(version)}` : '';\n return registryFetchJson<{ files: SkillHubFile[]; version: string }>(`${SKILLHUB_API_BASE}/api/v1/skills/${enc}/files${sp}`);\n}\n\nasync function downloadSkillHubZipBuffer(slug: string, version?: string): Promise<{ buffer: Buffer; version: string }> {\n const enc = encodeURIComponent(slug.trim());\n let url = `${SKILLHUB_API_BASE}/api/v1/download?slug=${enc}`;\n if (version?.trim()) url += `&version=${encodeURIComponent(version.trim())}`;\n const res = await fetch(url, { redirect: 'follow' });\n if (!res.ok) throw new Error(`Failed to download skill archive (${res.status})`);\n const len = res.headers.get('content-length');\n if (len) { const n = Number(len); if (Number.isFinite(n) && n > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`); }\n const ab = await res.arrayBuffer();\n const buf = Buffer.from(ab);\n if (buf.length > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`);\n let resolvedVersion = version ?? '1.0.0';\n if (!version?.trim()) {\n try { resolvedVersion = (await getSkillHubSkillFiles(slug)).version; } catch { /* keep default */ }\n }\n return { buffer: buf, version: resolvedVersion };\n}\n\nasync function batchGetSkillHubSkills(slugs: string[]): Promise<SkillHubSkillDetail[]> {\n if (slugs.length === 0) return [];\n const response = await registryFetchJson<{ count: number; items: SkillHubSkillDetail[]; missing: string[] }>(\n `${SKILLHUB_API_BASE}/api/v1/skills/batch`,\n { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ slugs }) },\n );\n return response.items ?? [];\n}\n\nasync function listSkillHubRegistryCategories(): Promise<SkillHubRegistryCategoryItem[]> {\n const raw = await registryFetchJson<{ count?: number; items?: SkillHubRegistryCategoryItem[] }>(\n `${SKILLHUB_API_BASE}/api/v1/categories`,\n );\n const items = Array.isArray(raw.items) ? raw.items : [];\n return items.filter((c) => c && typeof c.key === 'string' && c.key.trim().length > 0 && c.active !== false);\n}\n\nasync function listSkillHubSkillsets(opts: { page?: number; pageSize?: number; keyword?: string; scene?: string } = {}): Promise<{ skillSets: SkillHubSkillset[]; total: number }> {\n const page = opts.page ?? 1;\n const pageSize = opts.pageSize ?? 20;\n const sp = new URLSearchParams({ page: String(page), pageSize: String(pageSize) });\n if (opts.keyword?.trim()) sp.set('keyword', opts.keyword.trim());\n if (opts.scene?.trim()) sp.set('scene', opts.scene.trim());\n return registryFetchJson<{ skillSets: SkillHubSkillset[]; total: number }>(`${SKILLHUB_API_BASE}/api/v1/skillsets?${sp.toString()}`);\n}\n\nasync function getDefaultSkillSlugs(): Promise<string[]> {\n const slugs = new Set<string>();\n let page = 1;\n const pageSize = 50;\n let total = Infinity;\n while (page <= SKILLSET_DISCOVERY_PAGE_CAP && slugs.size < MAX_DEFAULT_SLUGS) {\n const response = await listSkillHubSkillsets({ page, pageSize });\n total = response.total;\n for (const skillset of response.skillSets) {\n for (const slug of skillset.skillSlugs) slugs.add(slug);\n }\n if (page * pageSize >= total) break;\n page += 1;\n }\n return Array.from(slugs).slice(0, MAX_DEFAULT_SLUGS);\n}\n\nasync function searchSkillHubSkills(query: string, maxSlugs = 200): Promise<{ slugs: string[]; total: number }> {\n const keyword = query.trim();\n if (!keyword) return { slugs: [], total: 0 };\n const slugs: string[] = [];\n const seen = new Set<string>();\n let page = 1;\n const batchSize = 50;\n while (page <= SKILLSET_DISCOVERY_PAGE_CAP) {\n const response = await listSkillHubSkillsets({ page, pageSize: batchSize, keyword });\n for (const skillset of response.skillSets) {\n for (const slug of skillset.skillSlugs) {\n if (!seen.has(slug)) { seen.add(slug); slugs.push(slug); }\n }\n }\n if (page * batchSize >= response.total) break;\n page += 1;\n }\n const capped = slugs.slice(0, maxSlugs);\n return { slugs: capped, total: capped.length };\n}\n\n// ─── Ecosystem helpers ───────────────────────────────────────────────────────\n\nfunction templateWithSlug(template: string, slug: string): string {\n const raw = template.trim();\n if (!raw) return '';\n if (raw.includes('{slug}')) return raw.replaceAll('{slug}', encodeURIComponent(slug.trim()));\n const base = raw.replace(/\\/$/, '');\n return `${base}/${encodeURIComponent(slug.trim())}.zip`;\n}\n\nfunction hostFromTemplate(template: string): string | undefined {\n const t = templateWithSlug(template, 'x');\n try { return new URL(t).hostname.toLowerCase(); } catch { return undefined; }\n}\n\nfunction resolveSkillHubEcosystemUrls(): EcosystemUrls {\n return {\n skillsIndexUrl: process.env.XOPC_SKILLHUB_SKILLS_INDEX_URL?.trim() || DEFAULT_SKILLS_INDEX_URL,\n searchUrl: process.env.XOPC_SKILLHUB_SEARCH_URL?.trim() || DEFAULT_SEARCH_URL,\n primaryDownloadTemplate: process.env.XOPC_SKILLHUB_PRIMARY_DOWNLOAD_TEMPLATE?.trim() || DEFAULT_PRIMARY_DOWNLOAD_TEMPLATE,\n fallbackDownloadTemplate: process.env.XOPC_SKILLHUB_FALLBACK_DOWNLOAD_TEMPLATE?.trim() || DEFAULT_FALLBACK_DOWNLOAD_TEMPLATE,\n };\n}\n\nfunction allowedDownloadHosts(urls: EcosystemUrls): Set<string> {\n const hosts = new Set(DEFAULT_ALLOWED_DOWNLOAD_HOSTS);\n for (const h of [hostFromTemplate(urls.primaryDownloadTemplate), hostFromTemplate(urls.fallbackDownloadTemplate)]) { if (h) hosts.add(h); }\n try { hosts.add(new URL(urls.skillsIndexUrl).hostname.toLowerCase()); } catch { /* ignore */ }\n try { hosts.add(new URL(urls.searchUrl).hostname.toLowerCase()); } catch { /* ignore */ }\n return hosts;\n}\n\nfunction assertSkillHubDownloadUrlAllowed(downloadUrl: string, urls: EcosystemUrls): URL {\n let u: URL;\n try { u = new URL(downloadUrl); } catch { throw new Error('Invalid SkillHub download URL'); }\n if (u.protocol !== 'https:') throw new Error('SkillHub download URL must use HTTPS');\n if (!allowedDownloadHosts(urls).has(u.hostname.toLowerCase())) throw new Error('SkillHub download URL host is not allowlisted');\n return u;\n}\n\nasync function ecoFetchJson<T>(url: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, { ...init, headers: { Accept: 'application/json', ...init?.headers } });\n const text = await res.text();\n if (!res.ok) {\n let msg = `SkillHub ecosystem request failed (${res.status})`;\n try { const j = JSON.parse(text) as { message?: string; error?: string }; if (j.message) msg = j.message; else if (j.error) msg = j.error; } catch { if (text) msg = text.slice(0, 200); }\n throw new Error(msg);\n }\n try { return JSON.parse(text) as T; } catch { throw new Error('SkillHub ecosystem returned invalid JSON'); }\n}\n\nasync function fetchSkillHubCuratedIndex(urls: EcosystemUrls): Promise<CuratedIndex> {\n const raw = await ecoFetchJson<unknown>(urls.skillsIndexUrl);\n if (Array.isArray(raw)) return { skills: raw as CuratedIndexSkill[] };\n if (raw && typeof raw === 'object' && Array.isArray((raw as CuratedIndex).skills)) return raw as CuratedIndex;\n throw new Error('SkillHub index JSON must be an object with a skills array');\n}\n\nfunction sourceLabelFromHomepage(homepage?: string): string | undefined {\n const h = homepage?.trim().toLowerCase() ?? '';\n if (h.includes('clawhub')) return 'ClawHub';\n if (h.includes('skillhub')) return 'SkillHub';\n return undefined;\n}\n\nfunction curatedSkillsToPackageItems(skills: CuratedIndexSkill[]): PackageListItem[] {\n return skills.map((s) => ({\n id: s.slug,\n name: (s.name ?? s.slug).trim() || s.slug,\n type: 'skill',\n description: (s.description ?? '').trim(),\n downloads: typeof s.downloads === 'number' ? s.downloads : 0,\n author: { username: 'skillhub', avatarUrl: null },\n latestVersion: (s.version ?? '').trim() || undefined,\n updatedAt: String(s.rank ?? s.score ?? 0),\n categories: (s.categories ?? []).map((c) => String(c).trim()).filter(Boolean),\n stars: typeof s.stars === 'number' ? s.stars : undefined,\n sourceLabel: sourceLabelFromHomepage(s.homepage),\n }));\n}\n\nasync function findCuratedIndexSkill(slug: string): Promise<CuratedIndexSkill | null> {\n const want = slug.trim();\n if (!want) return null;\n const ecoUrls = resolveSkillHubEcosystemUrls();\n try {\n const idx = await cachedFetchSkillHubCuratedIndex(ecoUrls);\n return idx.skills.find((s) => s.slug?.trim() === want) ?? null;\n } catch {\n return null;\n }\n}\n\nfunction curatedSkillFallbackReadmeMarkdown(skill: CuratedIndexSkill): string {\n const title = (skill.name ?? skill.slug).trim() || skill.slug;\n const desc = (skill.description ?? '').trim() || '_No description._';\n const version = (skill.version ?? '').trim() || '1.0.0';\n return `## ${title}\\n\\n**${skill.slug}** · v${version}\\n\\n${desc}`;\n}\n\nfunction packageDetailFromCuratedSkill(skill: CuratedIndexSkill) {\n const slug = skill.slug.trim();\n const version = (skill.version ?? '').trim() || '1.0.0';\n const categories = (skill.categories ?? []).map((c) => String(c).trim()).filter(Boolean);\n const sourceLabel = sourceLabelFromHomepage(skill.homepage);\n return {\n id: slug,\n name: (skill.name ?? slug).trim() || slug,\n type: 'skill',\n description: (skill.description ?? '').trim(),\n readme: curatedSkillFallbackReadmeMarkdown(skill),\n downloads: typeof skill.downloads === 'number' ? skill.downloads : 0,\n author: {\n username: sourceLabel?.toLowerCase() ?? 'skillhub',\n avatarUrl: null,\n },\n latestVersion: {\n version,\n changelog: null,\n publishedAt: String(skill.rank ?? skill.score ?? 0),\n },\n provider: 'skillhub',\n skillHubInfo: {\n category: categories[0] ?? '',\n installs: 0,\n stars: typeof skill.stars === 'number' ? skill.stars : 0,\n },\n };\n}\n\nfunction lightmakeHitToPackageItem(hit: LightmakeSearchHit): PackageListItem {\n const slug = String(hit.slug || '').trim();\n const desc = (hit.summary ?? hit.description_zh ?? hit.description ?? '').trim() || '';\n const updated = hit.updatedAt ?? hit.updated_at ?? 0;\n const cat = hit.category?.trim();\n return {\n id: slug,\n name: (hit.displayName ?? hit.name ?? slug).trim() || slug,\n type: 'skill',\n description: desc,\n downloads: typeof hit.downloads === 'number' ? hit.downloads : 0,\n author: { username: (hit.owner_name ?? 'skillhub').trim() || 'skillhub', avatarUrl: null },\n latestVersion: (hit.version ?? '').trim() || undefined,\n updatedAt: String(updated),\n categories: cat ? [cat] : [],\n stars: typeof hit.stars === 'number' ? hit.stars : undefined,\n sourceLabel: sourceLabelFromSkillSource(hit.source) ?? 'Lightmake',\n };\n}\n\nasync function searchSkillHubLightmake(urls: EcosystemUrls, query: string, limit: number, timeoutMs = 4000): Promise<PackageListItem[]> {\n const q = query.trim().toLowerCase();\n if (!q) return [];\n const search = new URL(urls.searchUrl);\n if (search.protocol !== 'https:') throw new Error('SkillHub search URL must use HTTPS');\n search.searchParams.set('q', q);\n search.searchParams.set('limit', String(Math.max(1, Math.min(LIGHTMAKE_SEARCH_MAX, limit))));\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const raw = await ecoFetchJson<{ results?: LightmakeSearchHit[] }>(search.toString(), { signal: controller.signal });\n const results = raw.results;\n if (!Array.isArray(results)) return [];\n const out: PackageListItem[] = [];\n for (const item of results) {\n if (!item || typeof item !== 'object') continue;\n const hit = item as LightmakeSearchHit;\n const slug = String(hit.slug ?? '').trim();\n if (!slug) continue;\n out.push(lightmakeHitToPackageItem(hit));\n }\n return out;\n } finally { clearTimeout(timer); }\n}\n\nasync function downloadSkillHubZipFromAllowlistedUrl(urls: EcosystemUrls, downloadUrl: string): Promise<Buffer> {\n const normalized = assertSkillHubDownloadUrlAllowed(downloadUrl, urls);\n const res = await fetch(normalized.toString(), { redirect: 'follow' });\n if (!res.ok) throw new Error(`Failed to download skill archive (${res.status})`);\n const len = res.headers.get('content-length');\n if (len) { const n = Number(len); if (Number.isFinite(n) && n > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`); }\n const ab = await res.arrayBuffer();\n const buf = Buffer.from(ab);\n if (buf.length > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`);\n return buf;\n}\n\nasync function downloadSkillHubZipFromEcosystem(urls: EcosystemUrls, slug: string): Promise<Buffer> {\n const primary = templateWithSlug(urls.primaryDownloadTemplate, slug);\n const fallback = templateWithSlug(urls.fallbackDownloadTemplate, slug);\n const candidates = [primary, fallback].filter(Boolean);\n const seen = new Set<string>();\n let lastErr: Error | undefined;\n for (const url of candidates) {\n if (seen.has(url)) continue;\n seen.add(url);\n try { return await downloadSkillHubZipFromAllowlistedUrl(urls, url); }\n catch (e) { lastErr = e instanceof Error ? e : new Error(String(e)); }\n }\n throw lastErr ?? new Error('SkillHub ecosystem download failed');\n}\n\n// ─── In-memory TTL cache ─────────────────────────────────────────────────────\n\ntype CacheEntry<T> = { value: T; expiresAt: number };\n\nfunction cacheTtlMs(): number {\n const raw = process.env.XOPC_SKILLHUB_CACHE_MS?.trim();\n if (raw === '0' || raw === 'false') return 0;\n const n = Number(raw);\n if (!Number.isFinite(n) || n < 0) return DEFAULT_CACHE_MS;\n return n;\n}\n\nfunction getFresh<T>(entry: CacheEntry<T> | undefined): T | undefined {\n if (!entry || entry.expiresAt <= Date.now()) return undefined;\n return entry.value;\n}\n\nconst curatedByIndexUrl = new Map<string, CacheEntry<CuratedIndex>>();\nlet defaultSlugsEntry: CacheEntry<string[]> | undefined;\nlet registryCategoriesEntry: CacheEntry<SkillHubRegistryCategoryItem[]> | undefined;\nconst batchBySlugsKey = new Map<string, CacheEntry<SkillHubSkillDetail[]>>();\nconst lightmakeSearchByQuery = new Map<string, CacheEntry<PackageListItem[]>>();\n\nfunction evictOldestBatchKey(): void {\n const first = batchBySlugsKey.keys().next().value;\n if (first !== undefined) batchBySlugsKey.delete(first);\n}\n\nfunction evictOldestSearchKey(): void {\n const first = lightmakeSearchByQuery.keys().next().value;\n if (first !== undefined) lightmakeSearchByQuery.delete(first);\n}\n\nfunction batchSlugsCacheKey(slugs: string[]): string {\n if (slugs.length === 0) return '';\n return [...slugs].sort().join('\\n');\n}\n\nasync function cachedFetchSkillHubCuratedIndex(urls: EcosystemUrls): Promise<CuratedIndex> {\n const ttl = cacheTtlMs();\n const key = urls.skillsIndexUrl;\n if (ttl > 0) { const hit = getFresh(curatedByIndexUrl.get(key)); if (hit) return hit; }\n const value = await fetchSkillHubCuratedIndex(urls);\n if (ttl > 0) curatedByIndexUrl.set(key, { value, expiresAt: Date.now() + ttl });\n return value;\n}\n\nasync function cachedGetDefaultSkillSlugs(): Promise<string[]> {\n const ttl = cacheTtlMs();\n if (ttl > 0) { const hit = getFresh(defaultSlugsEntry); if (hit) return hit; }\n const value = await getDefaultSkillSlugs();\n if (ttl > 0) defaultSlugsEntry = { value, expiresAt: Date.now() + ttl };\n return value;\n}\n\nasync function cachedListSkillHubRegistryCategories(): Promise<SkillHubRegistryCategoryItem[]> {\n const ttl = cacheTtlMs();\n if (ttl > 0) { const hit = getFresh(registryCategoriesEntry); if (hit) return hit; }\n const value = await listSkillHubRegistryCategories();\n if (ttl > 0) registryCategoriesEntry = { value, expiresAt: Date.now() + ttl };\n return value;\n}\n\nasync function cachedBatchGetSkillHubSkills(slugs: string[]): Promise<SkillHubSkillDetail[]> {\n if (slugs.length === 0) return [];\n const ttl = cacheTtlMs();\n const key = batchSlugsCacheKey(slugs);\n if (ttl > 0) { const hit = getFresh(batchBySlugsKey.get(key)); if (hit) return hit; }\n const value = await batchGetSkillHubSkills(slugs);\n if (ttl > 0) {\n while (batchBySlugsKey.size >= MAX_BATCH_CACHE_KEYS) evictOldestBatchKey();\n batchBySlugsKey.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\nasync function cachedSearchSkillHubLightmake(\n urls: EcosystemUrls,\n query: string,\n limit: number,\n): Promise<PackageListItem[]> {\n const q = query.trim().toLowerCase();\n if (!q) return [];\n const ttl = cacheTtlMs();\n const key = `${urls.searchUrl}|${q}|${limit}`;\n if (ttl > 0) { const hit = getFresh(lightmakeSearchByQuery.get(key)); if (hit) return hit; }\n const value = await searchSkillHubLightmake(urls, q, limit);\n if (ttl > 0) {\n while (lightmakeSearchByQuery.size >= MAX_BATCH_CACHE_KEYS) evictOldestSearchKey();\n lightmakeSearchByQuery.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\n// ─── Adapter conversion helpers ──────────────────────────────────────────────\n\nfunction humanizeRegistryCategoryKey(slug: string): string {\n return slug.replace(/_/g, '-').split('-').filter(Boolean)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(' ');\n}\n\nfunction sourceLabelFromSkillSource(source: string | undefined): string | undefined {\n const s = source?.trim();\n if (!s) return undefined;\n const lower = s.toLowerCase();\n if (lower === 'clawhub') return 'ClawHub';\n if (lower === 'lightmake') return 'Lightmake';\n if (lower === 'skillhub') return 'SkillHub';\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction filterByCategory(rows: PackageListItem[], category?: string): PackageListItem[] {\n const want = category?.trim();\n if (!want) return rows;\n return rows.filter((r) => (r.categories ?? []).includes(want));\n}\n\nasync function collectRegistryCategoryKeysFromSlugs(slugs: string[]): Promise<Set<string>> {\n const used = new Set<string>();\n for (let i = 0; i < slugs.length; i += REGISTRY_SKILL_BATCH_CHUNK) {\n const chunk = slugs.slice(i, i + REGISTRY_SKILL_BATCH_CHUNK);\n const details = await cachedBatchGetSkillHubSkills(chunk);\n for (const d of details) {\n const k = d.skill.category?.trim();\n if (k) used.add(k);\n }\n }\n return used;\n}\n\nfunction isPipelineOnlyChangelog(text: string | null | undefined): boolean {\n if (!text?.trim()) return true;\n return /^synced by skillhub pipeline\\.?$/i.test(text.trim());\n}\n\nfunction skillHubFallbackReadmeMarkdown(detail: { skill: SkillHubSkill; latestVersion: { version: string } }): string {\n const s = detail.skill;\n const title = s.displayName?.trim() || s.slug;\n const zh = s.summary_zh?.trim();\n const en = s.summary?.trim();\n const body = zh && en && zh !== en ? `${zh}\\n\\n${en}` : zh || en || '_No description._';\n return `## ${title}\\n\\n**${s.slug}** · v${detail.latestVersion.version}\\n\\n${body}`;\n}\n\nfunction convertSkillHubToPackageListItem(detail: SkillHubSkill): PackageListItem {\n const cat = detail.category?.trim();\n return {\n id: detail.slug,\n name: detail.displayName?.trim() || detail.slug,\n type: 'skill',\n description: detail.summary_zh || detail.summary,\n downloads: detail.stats.downloads,\n author: { username: detail.source || 'skillhub', avatarUrl: null },\n latestVersion: detail.tags.latest || '1.0.0',\n updatedAt: String(detail.updatedAt),\n categories: cat ? [cat] : [],\n stars: detail.stats.stars,\n sourceLabel: sourceLabelFromSkillSource(detail.source),\n };\n}\n\nexport const skillHubMarketplaceAdapter: SkillsMarketplaceAdapter = {\n id: 'skillhub',\n\n async listCategories(_config) {\n const sortByLabel = (a: MarketplaceCategoryOption, b: MarketplaceCategoryOption) =>\n a.label.localeCompare(b.label, 'zh-Hans-CN', { sensitivity: 'base' });\n const ecoUrls = resolveSkillHubEcosystemUrls();\n try {\n const idx = await cachedFetchSkillHubCuratedIndex(ecoUrls);\n if (idx.skills?.length) {\n const map = new Map<string, MarketplaceCategoryOption>();\n for (const s of idx.skills) {\n for (const raw of s.categories ?? []) {\n const label = String(raw).trim();\n if (label) map.set(label, { id: label, label });\n }\n }\n return sortMarketplaceCategories(\n Array.from(map.values()).filter((c) => c.id.trim() && c.label.trim()),\n sortByLabel,\n );\n }\n } catch { /* fall through: registry-backed catalog */ }\n try {\n const [taxonomy, slugs] = await Promise.all([\n cachedListSkillHubRegistryCategories(),\n cachedGetDefaultSkillSlugs(),\n ]);\n const usedKeys = await collectRegistryCategoryKeysFromSlugs(slugs);\n const taxByKey = new Map(taxonomy.map((t) => [t.key, t] as const));\n const options: MarketplaceCategoryOption[] = [];\n for (const key of usedKeys) {\n const t = taxByKey.get(key);\n const label = t?.name?.trim() || t?.nameEn?.trim() || humanizeRegistryCategoryKey(key).trim();\n if (!label) continue;\n options.push({ id: key, label });\n }\n return sortMarketplaceCategories(options, (a, b) => {\n const oa = taxByKey.get(a.id)?.sortOrder ?? 999;\n const ob = taxByKey.get(b.id)?.sortOrder ?? 999;\n if (oa !== ob) return oa - ob;\n return sortByLabel(a, b);\n });\n } catch { return []; }\n },\n\n async listPackages(_config, params) {\n const pageSize = params.pageSize ?? 20;\n const page = params.page ?? 1;\n const ecoUrls = resolveSkillHubEcosystemUrls();\n\n if (params.q?.trim()) {\n const q = params.q.trim();\n let rows: PackageListItem[] = [];\n try {\n rows = await cachedSearchSkillHubLightmake(ecoUrls, q, 100);\n } catch {\n // Lightmake unavailable — fall back to the registry skillset scan. We do NOT run this\n // when Lightmake returned zero hits: that would queue ~40 sequential HTTP calls just to\n // confirm \"no results\", and the empty state UI is the better answer for the user.\n try {\n const searchResult = await searchSkillHubSkills(q, 200);\n const details = await cachedBatchGetSkillHubSkills(searchResult.slugs);\n rows = details.map((d) => convertSkillHubToPackageListItem(d.skill));\n } catch {\n rows = [];\n }\n }\n rows = filterByCategory(rows, params.category);\n if (params.sort === 'downloads') rows = [...rows].sort((a, b) => b.downloads - a.downloads);\n else if (params.sort === 'newest') rows = [...rows].sort((a, b) => Number(b.updatedAt) - Number(a.updatedAt));\n const total = rows.length;\n const start = (page - 1) * pageSize;\n const items = rows.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n }\n\n try {\n const idx = await cachedFetchSkillHubCuratedIndex(ecoUrls);\n let skills = [...idx.skills].filter((s) => s.slug?.trim());\n if (skills.length > 0) {\n if (params.category?.trim()) {\n const want = params.category.trim();\n skills = skills.filter((s) => (s.categories ?? []).some((x) => String(x).trim() === want));\n }\n if (params.sort === 'downloads') skills.sort((a, b) => (b.downloads ?? 0) - (a.downloads ?? 0));\n else if (params.sort === 'newest') skills.sort((a, b) => (a.rank ?? 999) - (b.rank ?? 999));\n const rows = curatedSkillsToPackageItems(skills);\n const total = rows.length;\n const start = (page - 1) * pageSize;\n const items = rows.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n }\n } catch { /* fall through */ }\n\n const slugs = await cachedGetDefaultSkillSlugs();\n if (params.category?.trim()) {\n const details = await cachedBatchGetSkillHubSkills(slugs);\n let allItems = details.map((d) => convertSkillHubToPackageListItem(d.skill));\n allItems = filterByCategory(allItems, params.category);\n if (params.sort === 'downloads') allItems = [...allItems].sort((a, b) => b.downloads - a.downloads);\n else if (params.sort === 'newest') allItems = [...allItems].sort((a, b) => Number(b.updatedAt) - Number(a.updatedAt));\n const total = allItems.length;\n const start = (page - 1) * pageSize;\n const items = allItems.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n }\n\n const total = slugs.length;\n const start = (page - 1) * pageSize;\n const paginatedSlugs = slugs.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const details = await cachedBatchGetSkillHubSkills(paginatedSlugs);\n const items = details.map((d) => convertSkillHubToPackageListItem(d.skill));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n },\n\n async getPackageDetail(_config, packageName) {\n const slug = packageName.trim();\n let detail: SkillHubSkillDetail;\n try {\n detail = await getSkillHubSkill(slug);\n } catch (registryErr) {\n const curated = await findCuratedIndexSkill(slug);\n if (curated) return packageDetailFromCuratedSkill(curated);\n throw registryErr;\n }\n const version = detail.latestVersion.version;\n const changelog = detail.latestVersion.changelog;\n\n let readme: string | null = null;\n let docPath: string | null = null;\n try {\n const { files } = await getSkillHubSkillFiles(slug, version);\n docPath = pickSkillHubDocFilePath(files);\n if (docPath) readme = await getSkillHubSkillFileText(slug, docPath, version);\n } catch { readme = null; }\n\n const trimmed = readme?.trim() ?? '';\n const docBase = docPath ? basename(docPath.replace(/\\\\/g, '/')).toLowerCase() : '';\n const isSkillMd = docBase === 'skill.md';\n\n if (!trimmed) {\n readme = skillHubFallbackReadmeMarkdown(detail);\n } else if (isSkillMd) {\n readme = trimmed;\n if (changelog?.trim() && !isPipelineOnlyChangelog(changelog)) {\n readme = `${trimmed}\\n\\n---\\n\\n## Changelog\\n\\n${changelog.trim()}`;\n }\n } else {\n readme = trimmed;\n if (changelog?.trim() && !isPipelineOnlyChangelog(changelog)) {\n readme = `${trimmed}\\n\\n---\\n\\n## Changelog\\n\\n${changelog.trim()}`;\n }\n }\n\n return {\n id: detail.skill.slug,\n name: detail.skill.slug,\n type: 'skill',\n description: detail.skill.summary_zh || detail.skill.summary,\n readme,\n downloads: detail.skill.stats.downloads,\n author: {\n username: detail.owner.handle,\n avatarUrl: detail.owner.image,\n },\n latestVersion: {\n version: detail.latestVersion.version,\n changelog: detail.latestVersion.changelog,\n publishedAt: String(detail.latestVersion.createdAt),\n },\n provider: 'skillhub',\n skillHubInfo: {\n category: detail.skill.category,\n installs: detail.skill.stats.installs,\n stars: detail.skill.stats.stars,\n securityReports: detail.latestVersion.securityReports,\n },\n };\n },\n\n async downloadPackage(_config, packageName, version) {\n const slug = packageName.trim();\n if (version?.trim()) {\n const { buffer, version: resolvedVersion } = await downloadSkillHubZipBuffer(slug, version);\n return { buffer, skillId: isValidSkillId(slug) ? slug : 'unknown', version: resolvedVersion };\n }\n const ecoUrls = resolveSkillHubEcosystemUrls();\n try {\n const buffer = await downloadSkillHubZipFromEcosystem(ecoUrls, slug);\n let resolvedVersion = '1.0.0';\n try { resolvedVersion = (await getSkillHubSkillFiles(slug)).version; } catch { /* keep default */ }\n return { buffer, skillId: isValidSkillId(slug) ? slug : 'unknown', version: resolvedVersion };\n } catch {\n const { buffer, version: resolvedVersion } = await downloadSkillHubZipBuffer(slug);\n return { buffer, skillId: isValidSkillId(slug) ? slug : 'unknown', version: resolvedVersion };\n }\n },\n};\n\nregisterMarketplaceAdapter({\n adapter: skillHubMarketplaceAdapter,\n displayName: 'SkillHub',\n});\n"],"mappings":";;;;;;;AAaA,MAAM,oBAAoB;AAC1B,MAAM,sBAAsB,KAAK,OAAO;AACxC,MAAM,4BAA4B,MAAM;AACxC,MAAM,cAAc;AACpB,MAAM,6BAA6B;AAEnC,MAAM,2BAA2B;AACjC,MAAM,qBAAqB;AAC3B,MAAM,oCAAoC;AAC1C,MAAM,qCACJ;AACF,MAAM,iCAAiC,IAAI,IAAI;CAC7C;CACA;CACA;CACD,CAAC;AACF,MAAM,uBAAuB;AAC7B,MAAM,8BAA8B;AACpC,MAAM,oBAAoB;AAE1B,MAAM,mBAAmB,MAAS;AAClC,MAAM,uBAAuB;AAI7B,SAAS,eAAe,IAAqB;AAC3C,QAAO,YAAY,KAAK,GAAG;;AAgI7B,eAAe,kBAAqB,KAAa,MAAgC;CAC/E,MAAM,MAAM,MAAM,MAAM,KAAK;EAC3B,GAAG;EACH,SAAS;GAAE,QAAQ;GAAoB,GAAI,MAAM;GAAgD;EAClG,CAAC;CACF,MAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,KAAI,CAAC,IAAI,IAAI;EACX,IAAI,MAAM,4BAA4B,IAAI,OAAO;AACjD,MAAI;GACF,MAAM,IAAI,KAAK,MAAM,KAAK;AAC1B,OAAI,EAAE,QAAS,OAAM,EAAE;YACd,EAAE,MAAO,OAAM,EAAE;UACpB;AAAE,OAAI,KAAM,OAAM,KAAK,MAAM,GAAG,IAAI;;AAC5C,QAAM,IAAI,MAAM,IAAI;;AAEtB,KAAI;AAAE,SAAO,KAAK,MAAM,KAAK;SACvB;AAAE,QAAM,IAAI,MAAM,iCAAiC;;;AAG3D,SAAS,kBAAkB,GAAmB;CAC5C,MAAM,OAAO,EAAE,QAAQ,OAAO,IAAI;CAClC,MAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAO,MAAM,MAAM,SAAS,MAAM;;AAGpC,SAAS,wBAAwB,OAAsC;CACrE,MAAM,OAAO,MAAM,KAAK,OAAO;EAC7B,MAAM,EAAE,KAAK,QAAQ,OAAO,IAAI;EAChC,MAAM,kBAAkB,EAAE,KAAK,CAAC,aAAa;EAC9C,EAAE;CACH,MAAM,aAAa,SAAiB,KAAK,MAAM,MAAM,EAAE,SAAS,KAAK,aAAa,CAAC;CACnF,MAAM,UAAU,UAAU,WAAW,IAAI,UAAU,WAAW;AAC9D,KAAI,QAAS,QAAO,QAAQ;CAC5B,MAAM,SAAS,UAAU,YAAY,IAAI,UAAU,YAAY;AAC/D,KAAI,OAAQ,QAAO,OAAO;CAC1B,MAAM,MAAM,UAAU,gBAAgB;AACtC,KAAI,IAAK,QAAO,IAAI;AACpB,QAAO;;AAGT,SAAS,gCAAgC,UAAwB;CAC/D,IAAI;AACJ,KAAI;AAAE,MAAI,IAAI,IAAI,SAAS;SAAU;AAAE,QAAM,IAAI,MAAM,qCAAqC;;AAC5F,KAAI,EAAE,aAAa,SAAU,OAAM,IAAI,MAAM,wCAAwC;CACrF,MAAM,OAAO,EAAE,SAAS,aAAa;AACrC,KAAI,SAAS,kBAAmB;AAChC,KAAI,KAAK,SAAS,gBAAgB,CAAE;AACpC,OAAM,IAAI,MAAM,iDAAiD;;AAGnE,eAAe,yBAAyB,MAAc,UAAkB,SAAmC;CACzG,MAAM,MAAM,mBAAmB,KAAK,MAAM,CAAC;CAC3C,MAAM,WAAW,SAAS,QAAQ,OAAO,IAAI;CAC7C,MAAM,KAAK,IAAI,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAClD,KAAI,SAAS,MAAM,CAAE,IAAG,IAAI,WAAW,QAAQ,MAAM,CAAC;CACtD,MAAM,MAAM,GAAG,kBAAkB,iBAAiB,IAAI,QAAQ,GAAG,UAAU;CAC3E,MAAM,MAAM,MAAM,MAAM,KAAK;EAAE,UAAU;EAAU,SAAS,EAAE,QAAQ,gCAAgC;EAAE,CAAC;AACzG,KAAI,CAAC,IAAI,IAAI;EACX,MAAM,OAAO,MAAM,IAAI,MAAM,CAAC,YAAY,GAAG;EAC7C,IAAI,MAAM,iCAAiC,IAAI,OAAO;AACtD,MAAI;GACF,MAAM,IAAI,KAAK,MAAM,KAAK;AAC1B,OAAI,OAAO,EAAE,YAAY,SAAU,OAAM,EAAE;YAClC,OAAO,EAAE,UAAU,SAAU,OAAM,EAAE;UACxC;AAAE,OAAI,KAAM,OAAM,KAAK,MAAM,GAAG,IAAI;;AAC5C,QAAM,IAAI,MAAM,IAAI;;AAEtB,iCAAgC,IAAI,IAAI;CACxC,MAAM,MAAM,IAAI,QAAQ,IAAI,iBAAiB;AAC7C,KAAI,KAAK;EACP,MAAM,IAAI,OAAO,IAAI;AACrB,MAAI,OAAO,SAAS,EAAE,IAAI,IAAI,0BAA2B,OAAM,IAAI,MAAM,iCAAiC;;CAE5G,MAAM,KAAK,MAAM,IAAI,aAAa;AAClC,KAAI,GAAG,aAAa,0BAA2B,OAAM,IAAI,MAAM,iCAAiC;AAChG,QAAO,IAAI,YAAY,QAAQ,CAAC,OAAO,GAAG;;AAG5C,eAAe,iBAAiB,MAA4C;AAC1E,QAAO,kBAAuC,GAAG,kBAAkB,iBAAiB,mBAAmB,KAAK,MAAM,CAAC,GAAG;;AAGxH,eAAe,sBAAsB,MAAc,SAAuE;AAGxH,QAAO,kBAA8D,GAAG,kBAAkB,iBAF9E,mBAAmB,KAAK,MAAM,CAEoE,CAAC,QADpG,UAAU,YAAY,mBAAmB,QAAQ,KAAK,KAC2D;;AAG9H,eAAe,0BAA0B,MAAc,SAAgE;CAErH,IAAI,MAAM,GAAG,kBAAkB,wBADnB,mBAAmB,KAAK,MAAM,CACgB;AAC1D,KAAI,SAAS,MAAM,CAAE,QAAO,YAAY,mBAAmB,QAAQ,MAAM,CAAC;CAC1E,MAAM,MAAM,MAAM,MAAM,KAAK,EAAE,UAAU,UAAU,CAAC;AACpD,KAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,qCAAqC,IAAI,OAAO,GAAG;CAChF,MAAM,MAAM,IAAI,QAAQ,IAAI,iBAAiB;AAC7C,KAAI,KAAK;EAAE,MAAM,IAAI,OAAO,IAAI;AAAE,MAAI,OAAO,SAAS,EAAE,IAAI,IAAI,oBAAqB,OAAM,IAAI,MAAM,uBAAuB;;CAC5H,MAAM,KAAK,MAAM,IAAI,aAAa;CAClC,MAAM,MAAM,OAAO,KAAK,GAAG;AAC3B,KAAI,IAAI,SAAS,oBAAqB,OAAM,IAAI,MAAM,uBAAuB;CAC7E,IAAI,kBAAkB,WAAW;AACjC,KAAI,CAAC,SAAS,MAAM,CAClB,KAAI;AAAE,qBAAmB,MAAM,sBAAsB,KAAK,EAAE;SAAiB;AAE/E,QAAO;EAAE,QAAQ;EAAK,SAAS;EAAiB;;AAGlD,eAAe,uBAAuB,OAAiD;AACrF,KAAI,MAAM,WAAW,EAAG,QAAO,EAAE;AAKjC,SAAO,MAJgB,kBACrB,GAAG,kBAAkB,uBACrB;EAAE,QAAQ;EAAQ,SAAS,EAAE,gBAAgB,oBAAoB;EAAE,MAAM,KAAK,UAAU,EAAE,OAAO,CAAC;EAAE,CACrG,EACe,SAAS,EAAE;;AAG7B,eAAe,iCAA0E;CACvF,MAAM,MAAM,MAAM,kBAChB,GAAG,kBAAkB,oBACtB;AAED,SADc,MAAM,QAAQ,IAAI,MAAM,GAAG,IAAI,QAAQ,EAAE,EAC1C,QAAQ,MAAM,KAAK,OAAO,EAAE,QAAQ,YAAY,EAAE,IAAI,MAAM,CAAC,SAAS,KAAK,EAAE,WAAW,MAAM;;AAG7G,eAAe,sBAAsB,OAA+E,EAAE,EAA6D;CACjL,MAAM,OAAO,KAAK,QAAQ;CAC1B,MAAM,WAAW,KAAK,YAAY;CAClC,MAAM,KAAK,IAAI,gBAAgB;EAAE,MAAM,OAAO,KAAK;EAAE,UAAU,OAAO,SAAS;EAAE,CAAC;AAClF,KAAI,KAAK,SAAS,MAAM,CAAE,IAAG,IAAI,WAAW,KAAK,QAAQ,MAAM,CAAC;AAChE,KAAI,KAAK,OAAO,MAAM,CAAE,IAAG,IAAI,SAAS,KAAK,MAAM,MAAM,CAAC;AAC1D,QAAO,kBAAoE,GAAG,kBAAkB,oBAAoB,GAAG,UAAU,GAAG;;AAGtI,eAAe,uBAA0C;CACvD,MAAM,wBAAQ,IAAI,KAAa;CAC/B,IAAI,OAAO;CACX,MAAM,WAAW;CACjB,IAAI,QAAQ;AACZ,QAAO,QAAQ,+BAA+B,MAAM,OAAO,mBAAmB;EAC5E,MAAM,WAAW,MAAM,sBAAsB;GAAE;GAAM;GAAU,CAAC;AAChE,UAAQ,SAAS;AACjB,OAAK,MAAM,YAAY,SAAS,UAC9B,MAAK,MAAM,QAAQ,SAAS,WAAY,OAAM,IAAI,KAAK;AAEzD,MAAI,OAAO,YAAY,MAAO;AAC9B,UAAQ;;AAEV,QAAO,MAAM,KAAK,MAAM,CAAC,MAAM,GAAG,kBAAkB;;AAGtD,eAAe,qBAAqB,OAAe,WAAW,KAAkD;CAC9G,MAAM,UAAU,MAAM,MAAM;AAC5B,KAAI,CAAC,QAAS,QAAO;EAAE,OAAO,EAAE;EAAE,OAAO;EAAG;CAC5C,MAAM,QAAkB,EAAE;CAC1B,MAAM,uBAAO,IAAI,KAAa;CAC9B,IAAI,OAAO;CACX,MAAM,YAAY;AAClB,QAAO,QAAQ,6BAA6B;EAC1C,MAAM,WAAW,MAAM,sBAAsB;GAAE;GAAM,UAAU;GAAW;GAAS,CAAC;AACpF,OAAK,MAAM,YAAY,SAAS,UAC9B,MAAK,MAAM,QAAQ,SAAS,WAC1B,KAAI,CAAC,KAAK,IAAI,KAAK,EAAE;AAAE,QAAK,IAAI,KAAK;AAAE,SAAM,KAAK,KAAK;;AAG3D,MAAI,OAAO,aAAa,SAAS,MAAO;AACxC,UAAQ;;CAEV,MAAM,SAAS,MAAM,MAAM,GAAG,SAAS;AACvC,QAAO;EAAE,OAAO;EAAQ,OAAO,OAAO;EAAQ;;AAKhD,SAAS,iBAAiB,UAAkB,MAAsB;CAChE,MAAM,MAAM,SAAS,MAAM;AAC3B,KAAI,CAAC,IAAK,QAAO;AACjB,KAAI,IAAI,SAAS,SAAS,CAAE,QAAO,IAAI,WAAW,UAAU,mBAAmB,KAAK,MAAM,CAAC,CAAC;AAE5F,QAAO,GADM,IAAI,QAAQ,OAAO,GAClB,CAAC,GAAG,mBAAmB,KAAK,MAAM,CAAC,CAAC;;AAGpD,SAAS,iBAAiB,UAAsC;CAC9D,MAAM,IAAI,iBAAiB,UAAU,IAAI;AACzC,KAAI;AAAE,SAAO,IAAI,IAAI,EAAE,CAAC,SAAS,aAAa;SAAU;AAAE;;;AAG5D,SAAS,+BAA8C;AACrD,QAAO;EACL,gBAAgB,QAAQ,IAAI,gCAAgC,MAAM,IAAI;EACtE,WAAW,QAAQ,IAAI,0BAA0B,MAAM,IAAI;EAC3D,yBAAyB,QAAQ,IAAI,yCAAyC,MAAM,IAAI;EACxF,0BAA0B,QAAQ,IAAI,0CAA0C,MAAM,IAAI;EAC3F;;AAGH,SAAS,qBAAqB,MAAkC;CAC9D,MAAM,QAAQ,IAAI,IAAI,+BAA+B;AACrD,MAAK,MAAM,KAAK,CAAC,iBAAiB,KAAK,wBAAwB,EAAE,iBAAiB,KAAK,yBAAyB,CAAC,CAAI,KAAI,EAAG,OAAM,IAAI,EAAE;AACxI,KAAI;AAAE,QAAM,IAAI,IAAI,IAAI,KAAK,eAAe,CAAC,SAAS,aAAa,CAAC;SAAU;AAC9E,KAAI;AAAE,QAAM,IAAI,IAAI,IAAI,KAAK,UAAU,CAAC,SAAS,aAAa,CAAC;SAAU;AACzE,QAAO;;AAGT,SAAS,iCAAiC,aAAqB,MAA0B;CACvF,IAAI;AACJ,KAAI;AAAE,MAAI,IAAI,IAAI,YAAY;SAAU;AAAE,QAAM,IAAI,MAAM,gCAAgC;;AAC1F,KAAI,EAAE,aAAa,SAAU,OAAM,IAAI,MAAM,uCAAuC;AACpF,KAAI,CAAC,qBAAqB,KAAK,CAAC,IAAI,EAAE,SAAS,aAAa,CAAC,CAAE,OAAM,IAAI,MAAM,gDAAgD;AAC/H,QAAO;;AAGT,eAAe,aAAgB,KAAa,MAAgC;CAC1E,MAAM,MAAM,MAAM,MAAM,KAAK;EAAE,GAAG;EAAM,SAAS;GAAE,QAAQ;GAAoB,GAAG,MAAM;GAAS;EAAE,CAAC;CACpG,MAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,KAAI,CAAC,IAAI,IAAI;EACX,IAAI,MAAM,sCAAsC,IAAI,OAAO;AAC3D,MAAI;GAAE,MAAM,IAAI,KAAK,MAAM,KAAK;AAA0C,OAAI,EAAE,QAAS,OAAM,EAAE;YAAkB,EAAE,MAAO,OAAM,EAAE;UAAe;AAAE,OAAI,KAAM,OAAM,KAAK,MAAM,GAAG,IAAI;;AACvL,QAAM,IAAI,MAAM,IAAI;;AAEtB,KAAI;AAAE,SAAO,KAAK,MAAM,KAAK;SAAe;AAAE,QAAM,IAAI,MAAM,2CAA2C;;;AAG3G,eAAe,0BAA0B,MAA4C;CACnF,MAAM,MAAM,MAAM,aAAsB,KAAK,eAAe;AAC5D,KAAI,MAAM,QAAQ,IAAI,CAAE,QAAO,EAAE,QAAQ,KAA4B;AACrE,KAAI,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAS,IAAqB,OAAO,CAAE,QAAO;AAC1F,OAAM,IAAI,MAAM,4DAA4D;;AAG9E,SAAS,wBAAwB,UAAuC;CACtE,MAAM,IAAI,UAAU,MAAM,CAAC,aAAa,IAAI;AAC5C,KAAI,EAAE,SAAS,UAAU,CAAE,QAAO;AAClC,KAAI,EAAE,SAAS,WAAW,CAAE,QAAO;;AAIrC,SAAS,4BAA4B,QAAgD;AACnF,QAAO,OAAO,KAAK,OAAO;EACxB,IAAI,EAAE;EACN,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,IAAI,EAAE;EACrC,MAAM;EACN,cAAc,EAAE,eAAe,IAAI,MAAM;EACzC,WAAW,OAAO,EAAE,cAAc,WAAW,EAAE,YAAY;EAC3D,QAAQ;GAAE,UAAU;GAAY,WAAW;GAAM;EACjD,gBAAgB,EAAE,WAAW,IAAI,MAAM,IAAI,KAAA;EAC3C,WAAW,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE;EACzC,aAAa,EAAE,cAAc,EAAE,EAAE,KAAK,MAAM,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,QAAQ;EAC7E,OAAO,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ,KAAA;EAC/C,aAAa,wBAAwB,EAAE,SAAS;EACjD,EAAE;;AAGL,eAAe,sBAAsB,MAAiD;CACpF,MAAM,OAAO,KAAK,MAAM;AACxB,KAAI,CAAC,KAAM,QAAO;CAClB,MAAM,UAAU,8BAA8B;AAC9C,KAAI;AAEF,UAAO,MADW,gCAAgC,QAAQ,EAC/C,OAAO,MAAM,MAAM,EAAE,MAAM,MAAM,KAAK,KAAK,IAAI;SACpD;AACN,SAAO;;;AAIX,SAAS,mCAAmC,OAAkC;CAC5E,MAAM,SAAS,MAAM,QAAQ,MAAM,MAAM,MAAM,IAAI,MAAM;CACzD,MAAM,QAAQ,MAAM,eAAe,IAAI,MAAM,IAAI;CACjD,MAAM,WAAW,MAAM,WAAW,IAAI,MAAM,IAAI;AAChD,QAAO,MAAM,MAAM,QAAQ,MAAM,KAAK,QAAQ,QAAQ,MAAM;;AAG9D,SAAS,8BAA8B,OAA0B;CAC/D,MAAM,OAAO,MAAM,KAAK,MAAM;CAC9B,MAAM,WAAW,MAAM,WAAW,IAAI,MAAM,IAAI;CAChD,MAAM,cAAc,MAAM,cAAc,EAAE,EAAE,KAAK,MAAM,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,QAAQ;CACxF,MAAM,cAAc,wBAAwB,MAAM,SAAS;AAC3D,QAAO;EACL,IAAI;EACJ,OAAO,MAAM,QAAQ,MAAM,MAAM,IAAI;EACrC,MAAM;EACN,cAAc,MAAM,eAAe,IAAI,MAAM;EAC7C,QAAQ,mCAAmC,MAAM;EACjD,WAAW,OAAO,MAAM,cAAc,WAAW,MAAM,YAAY;EACnE,QAAQ;GACN,UAAU,aAAa,aAAa,IAAI;GACxC,WAAW;GACZ;EACD,eAAe;GACb;GACA,WAAW;GACX,aAAa,OAAO,MAAM,QAAQ,MAAM,SAAS,EAAE;GACpD;EACD,UAAU;EACV,cAAc;GACZ,UAAU,WAAW,MAAM;GAC3B,UAAU;GACV,OAAO,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;GACxD;EACF;;AAGH,SAAS,0BAA0B,KAA0C;CAC3E,MAAM,OAAO,OAAO,IAAI,QAAQ,GAAG,CAAC,MAAM;CAC1C,MAAM,QAAQ,IAAI,WAAW,IAAI,kBAAkB,IAAI,eAAe,IAAI,MAAM,IAAI;CACpF,MAAM,UAAU,IAAI,aAAa,IAAI,cAAc;CACnD,MAAM,MAAM,IAAI,UAAU,MAAM;AAChC,QAAO;EACL,IAAI;EACJ,OAAO,IAAI,eAAe,IAAI,QAAQ,MAAM,MAAM,IAAI;EACtD,MAAM;EACN,aAAa;EACb,WAAW,OAAO,IAAI,cAAc,WAAW,IAAI,YAAY;EAC/D,QAAQ;GAAE,WAAW,IAAI,cAAc,YAAY,MAAM,IAAI;GAAY,WAAW;GAAM;EAC1F,gBAAgB,IAAI,WAAW,IAAI,MAAM,IAAI,KAAA;EAC7C,WAAW,OAAO,QAAQ;EAC1B,YAAY,MAAM,CAAC,IAAI,GAAG,EAAE;EAC5B,OAAO,OAAO,IAAI,UAAU,WAAW,IAAI,QAAQ,KAAA;EACnD,aAAa,2BAA2B,IAAI,OAAO,IAAI;EACxD;;AAGH,eAAe,wBAAwB,MAAqB,OAAe,OAAe,YAAY,KAAkC;CACtI,MAAM,IAAI,MAAM,MAAM,CAAC,aAAa;AACpC,KAAI,CAAC,EAAG,QAAO,EAAE;CACjB,MAAM,SAAS,IAAI,IAAI,KAAK,UAAU;AACtC,KAAI,OAAO,aAAa,SAAU,OAAM,IAAI,MAAM,qCAAqC;AACvF,QAAO,aAAa,IAAI,KAAK,EAAE;AAC/B,QAAO,aAAa,IAAI,SAAS,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,sBAAsB,MAAM,CAAC,CAAC,CAAC;CAC5F,MAAM,aAAa,IAAI,iBAAiB;CACxC,MAAM,QAAQ,iBAAiB,WAAW,OAAO,EAAE,UAAU;AAC7D,KAAI;EAEF,MAAM,WAAU,MADE,aAAiD,OAAO,UAAU,EAAE,EAAE,QAAQ,WAAW,QAAQ,CAAC,EAChG;AACpB,MAAI,CAAC,MAAM,QAAQ,QAAQ,CAAE,QAAO,EAAE;EACtC,MAAM,MAAyB,EAAE;AACjC,OAAK,MAAM,QAAQ,SAAS;AAC1B,OAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;GACvC,MAAM,MAAM;AAEZ,OAAI,CADS,OAAO,IAAI,QAAQ,GAAG,CAAC,MAC3B,CAAE;AACX,OAAI,KAAK,0BAA0B,IAAI,CAAC;;AAE1C,SAAO;WACC;AAAE,eAAa,MAAM;;;AAGjC,eAAe,sCAAsC,MAAqB,aAAsC;CAC9G,MAAM,aAAa,iCAAiC,aAAa,KAAK;CACtE,MAAM,MAAM,MAAM,MAAM,WAAW,UAAU,EAAE,EAAE,UAAU,UAAU,CAAC;AACtE,KAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,qCAAqC,IAAI,OAAO,GAAG;CAChF,MAAM,MAAM,IAAI,QAAQ,IAAI,iBAAiB;AAC7C,KAAI,KAAK;EAAE,MAAM,IAAI,OAAO,IAAI;AAAE,MAAI,OAAO,SAAS,EAAE,IAAI,IAAI,oBAAqB,OAAM,IAAI,MAAM,uBAAuB;;CAC5H,MAAM,KAAK,MAAM,IAAI,aAAa;CAClC,MAAM,MAAM,OAAO,KAAK,GAAG;AAC3B,KAAI,IAAI,SAAS,oBAAqB,OAAM,IAAI,MAAM,uBAAuB;AAC7E,QAAO;;AAGT,eAAe,iCAAiC,MAAqB,MAA+B;CAGlG,MAAM,aAAa,CAFH,iBAAiB,KAAK,yBAAyB,KAEpC,EADV,iBAAiB,KAAK,0BAA0B,KAC5B,CAAC,CAAC,OAAO,QAAQ;CACtD,MAAM,uBAAO,IAAI,KAAa;CAC9B,IAAI;AACJ,MAAK,MAAM,OAAO,YAAY;AAC5B,MAAI,KAAK,IAAI,IAAI,CAAE;AACnB,OAAK,IAAI,IAAI;AACb,MAAI;AAAE,UAAO,MAAM,sCAAsC,MAAM,IAAI;WAC5D,GAAG;AAAE,aAAU,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,EAAE,CAAC;;;AAErE,OAAM,2BAAW,IAAI,MAAM,qCAAqC;;AAOlE,SAAS,aAAqB;CAC5B,MAAM,MAAM,QAAQ,IAAI,wBAAwB,MAAM;AACtD,KAAI,QAAQ,OAAO,QAAQ,QAAS,QAAO;CAC3C,MAAM,IAAI,OAAO,IAAI;AACrB,KAAI,CAAC,OAAO,SAAS,EAAE,IAAI,IAAI,EAAG,QAAO;AACzC,QAAO;;AAGT,SAAS,SAAY,OAAiD;AACpE,KAAI,CAAC,SAAS,MAAM,aAAa,KAAK,KAAK,CAAE,QAAO,KAAA;AACpD,QAAO,MAAM;;AAGf,MAAM,oCAAoB,IAAI,KAAuC;AACrE,IAAI;AACJ,IAAI;AACJ,MAAM,kCAAkB,IAAI,KAAgD;AAC5E,MAAM,yCAAyB,IAAI,KAA4C;AAE/E,SAAS,sBAA4B;CACnC,MAAM,QAAQ,gBAAgB,MAAM,CAAC,MAAM,CAAC;AAC5C,KAAI,UAAU,KAAA,EAAW,iBAAgB,OAAO,MAAM;;AAGxD,SAAS,uBAA6B;CACpC,MAAM,QAAQ,uBAAuB,MAAM,CAAC,MAAM,CAAC;AACnD,KAAI,UAAU,KAAA,EAAW,wBAAuB,OAAO,MAAM;;AAG/D,SAAS,mBAAmB,OAAyB;AACnD,KAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAO,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,KAAK;;AAGrC,eAAe,gCAAgC,MAA4C;CACzF,MAAM,MAAM,YAAY;CACxB,MAAM,MAAM,KAAK;AACjB,KAAI,MAAM,GAAG;EAAE,MAAM,MAAM,SAAS,kBAAkB,IAAI,IAAI,CAAC;AAAE,MAAI,IAAK,QAAO;;CACjF,MAAM,QAAQ,MAAM,0BAA0B,KAAK;AACnD,KAAI,MAAM,EAAG,mBAAkB,IAAI,KAAK;EAAE;EAAO,WAAW,KAAK,KAAK,GAAG;EAAK,CAAC;AAC/E,QAAO;;AAGT,eAAe,6BAAgD;CAC7D,MAAM,MAAM,YAAY;AACxB,KAAI,MAAM,GAAG;EAAE,MAAM,MAAM,SAAS,kBAAkB;AAAE,MAAI,IAAK,QAAO;;CACxE,MAAM,QAAQ,MAAM,sBAAsB;AAC1C,KAAI,MAAM,EAAG,qBAAoB;EAAE;EAAO,WAAW,KAAK,KAAK,GAAG;EAAK;AACvE,QAAO;;AAGT,eAAe,uCAAgF;CAC7F,MAAM,MAAM,YAAY;AACxB,KAAI,MAAM,GAAG;EAAE,MAAM,MAAM,SAAS,wBAAwB;AAAE,MAAI,IAAK,QAAO;;CAC9E,MAAM,QAAQ,MAAM,gCAAgC;AACpD,KAAI,MAAM,EAAG,2BAA0B;EAAE;EAAO,WAAW,KAAK,KAAK,GAAG;EAAK;AAC7E,QAAO;;AAGT,eAAe,6BAA6B,OAAiD;AAC3F,KAAI,MAAM,WAAW,EAAG,QAAO,EAAE;CACjC,MAAM,MAAM,YAAY;CACxB,MAAM,MAAM,mBAAmB,MAAM;AACrC,KAAI,MAAM,GAAG;EAAE,MAAM,MAAM,SAAS,gBAAgB,IAAI,IAAI,CAAC;AAAE,MAAI,IAAK,QAAO;;CAC/E,MAAM,QAAQ,MAAM,uBAAuB,MAAM;AACjD,KAAI,MAAM,GAAG;AACX,SAAO,gBAAgB,QAAQ,qBAAsB,sBAAqB;AAC1E,kBAAgB,IAAI,KAAK;GAAE;GAAO,WAAW,KAAK,KAAK,GAAG;GAAK,CAAC;;AAElE,QAAO;;AAGT,eAAe,8BACb,MACA,OACA,OAC4B;CAC5B,MAAM,IAAI,MAAM,MAAM,CAAC,aAAa;AACpC,KAAI,CAAC,EAAG,QAAO,EAAE;CACjB,MAAM,MAAM,YAAY;CACxB,MAAM,MAAM,GAAG,KAAK,UAAU,GAAG,EAAE,GAAG;AACtC,KAAI,MAAM,GAAG;EAAE,MAAM,MAAM,SAAS,uBAAuB,IAAI,IAAI,CAAC;AAAE,MAAI,IAAK,QAAO;;CACtF,MAAM,QAAQ,MAAM,wBAAwB,MAAM,GAAG,MAAM;AAC3D,KAAI,MAAM,GAAG;AACX,SAAO,uBAAuB,QAAQ,qBAAsB,uBAAsB;AAClF,yBAAuB,IAAI,KAAK;GAAE;GAAO,WAAW,KAAK,KAAK,GAAG;GAAK,CAAC;;AAEzE,QAAO;;AAKT,SAAS,4BAA4B,MAAsB;AACzD,QAAO,KAAK,QAAQ,MAAM,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,QAAQ,CACtD,KAAK,MAAM,EAAE,OAAO,EAAE,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,CAAC,aAAa,CAAC,CAAC,KAAK,IAAI;;AAG/E,SAAS,2BAA2B,QAAgD;CAClF,MAAM,IAAI,QAAQ,MAAM;AACxB,KAAI,CAAC,EAAG,QAAO,KAAA;CACf,MAAM,QAAQ,EAAE,aAAa;AAC7B,KAAI,UAAU,UAAW,QAAO;AAChC,KAAI,UAAU,YAAa,QAAO;AAClC,KAAI,UAAU,WAAY,QAAO;AACjC,QAAO,EAAE,OAAO,EAAE,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE;;AAG/C,SAAS,iBAAiB,MAAyB,UAAsC;CACvF,MAAM,OAAO,UAAU,MAAM;AAC7B,KAAI,CAAC,KAAM,QAAO;AAClB,QAAO,KAAK,QAAQ,OAAO,EAAE,cAAc,EAAE,EAAE,SAAS,KAAK,CAAC;;AAGhE,eAAe,qCAAqC,OAAuC;CACzF,MAAM,uBAAO,IAAI,KAAa;AAC9B,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,4BAA4B;EAEjE,MAAM,UAAU,MAAM,6BADR,MAAM,MAAM,GAAG,IAAI,2BACuB,CAAC;AACzD,OAAK,MAAM,KAAK,SAAS;GACvB,MAAM,IAAI,EAAE,MAAM,UAAU,MAAM;AAClC,OAAI,EAAG,MAAK,IAAI,EAAE;;;AAGtB,QAAO;;AAGT,SAAS,wBAAwB,MAA0C;AACzE,KAAI,CAAC,MAAM,MAAM,CAAE,QAAO;AAC1B,QAAO,oCAAoC,KAAK,KAAK,MAAM,CAAC;;AAG9D,SAAS,+BAA+B,QAA8E;CACpH,MAAM,IAAI,OAAO;CACjB,MAAM,QAAQ,EAAE,aAAa,MAAM,IAAI,EAAE;CACzC,MAAM,KAAK,EAAE,YAAY,MAAM;CAC/B,MAAM,KAAK,EAAE,SAAS,MAAM;CAC5B,MAAM,OAAO,MAAM,MAAM,OAAO,KAAK,GAAG,GAAG,MAAM,OAAO,MAAM,MAAM;AACpE,QAAO,MAAM,MAAM,QAAQ,EAAE,KAAK,QAAQ,OAAO,cAAc,QAAQ,MAAM;;AAG/E,SAAS,iCAAiC,QAAwC;CAChF,MAAM,MAAM,OAAO,UAAU,MAAM;AACnC,QAAO;EACL,IAAI,OAAO;EACX,MAAM,OAAO,aAAa,MAAM,IAAI,OAAO;EAC3C,MAAM;EACN,aAAa,OAAO,cAAc,OAAO;EACzC,WAAW,OAAO,MAAM;EACxB,QAAQ;GAAE,UAAU,OAAO,UAAU;GAAY,WAAW;GAAM;EAClE,eAAe,OAAO,KAAK,UAAU;EACrC,WAAW,OAAO,OAAO,UAAU;EACnC,YAAY,MAAM,CAAC,IAAI,GAAG,EAAE;EAC5B,OAAO,OAAO,MAAM;EACpB,aAAa,2BAA2B,OAAO,OAAO;EACvD;;AAGH,MAAa,6BAAuD;CAClE,IAAI;CAEJ,MAAM,eAAe,SAAS;EAC5B,MAAM,eAAe,GAA8B,MACjD,EAAE,MAAM,cAAc,EAAE,OAAO,cAAc,EAAE,aAAa,QAAQ,CAAC;EACvE,MAAM,UAAU,8BAA8B;AAC9C,MAAI;GACF,MAAM,MAAM,MAAM,gCAAgC,QAAQ;AAC1D,OAAI,IAAI,QAAQ,QAAQ;IACtB,MAAM,sBAAM,IAAI,KAAwC;AACxD,SAAK,MAAM,KAAK,IAAI,OAClB,MAAK,MAAM,OAAO,EAAE,cAAc,EAAE,EAAE;KACpC,MAAM,QAAQ,OAAO,IAAI,CAAC,MAAM;AAChC,SAAI,MAAO,KAAI,IAAI,OAAO;MAAE,IAAI;MAAO;MAAO,CAAC;;AAGnD,WAAO,0BACL,MAAM,KAAK,IAAI,QAAQ,CAAC,CAAC,QAAQ,MAAM,EAAE,GAAG,MAAM,IAAI,EAAE,MAAM,MAAM,CAAC,EACrE,YACD;;UAEG;AACR,MAAI;GACF,MAAM,CAAC,UAAU,SAAS,MAAM,QAAQ,IAAI,CAC1C,sCAAsC,EACtC,4BAA4B,CAC7B,CAAC;GACF,MAAM,WAAW,MAAM,qCAAqC,MAAM;GAClE,MAAM,WAAW,IAAI,IAAI,SAAS,KAAK,MAAM,CAAC,EAAE,KAAK,EAAE,CAAU,CAAC;GAClE,MAAM,UAAuC,EAAE;AAC/C,QAAK,MAAM,OAAO,UAAU;IAC1B,MAAM,IAAI,SAAS,IAAI,IAAI;IAC3B,MAAM,QAAQ,GAAG,MAAM,MAAM,IAAI,GAAG,QAAQ,MAAM,IAAI,4BAA4B,IAAI,CAAC,MAAM;AAC7F,QAAI,CAAC,MAAO;AACZ,YAAQ,KAAK;KAAE,IAAI;KAAK;KAAO,CAAC;;AAElC,UAAO,0BAA0B,UAAU,GAAG,MAAM;IAClD,MAAM,KAAK,SAAS,IAAI,EAAE,GAAG,EAAE,aAAa;IAC5C,MAAM,KAAK,SAAS,IAAI,EAAE,GAAG,EAAE,aAAa;AAC5C,QAAI,OAAO,GAAI,QAAO,KAAK;AAC3B,WAAO,YAAY,GAAG,EAAE;KACxB;UACI;AAAE,UAAO,EAAE;;;CAGrB,MAAM,aAAa,SAAS,QAAQ;EAClC,MAAM,WAAW,OAAO,YAAY;EACpC,MAAM,OAAO,OAAO,QAAQ;EAC5B,MAAM,UAAU,8BAA8B;AAE9C,MAAI,OAAO,GAAG,MAAM,EAAE;GACpB,MAAM,IAAI,OAAO,EAAE,MAAM;GACzB,IAAI,OAA0B,EAAE;AAChC,OAAI;AACF,WAAO,MAAM,8BAA8B,SAAS,GAAG,IAAI;WACrD;AAIN,QAAI;AAGF,aAAO,MADe,8BAA6B,MADxB,qBAAqB,GAAG,IAAI,EACS,MAAM,EACvD,KAAK,MAAM,iCAAiC,EAAE,MAAM,CAAC;YAC9D;AACN,YAAO,EAAE;;;AAGb,UAAO,iBAAiB,MAAM,OAAO,SAAS;AAC9C,OAAI,OAAO,SAAS,YAAa,QAAO,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,UAAU;YAClF,OAAO,SAAS,SAAU,QAAO,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,OAAO,EAAE,UAAU,GAAG,OAAO,EAAE,UAAU,CAAC;GAC7G,MAAM,QAAQ,KAAK;GACnB,MAAM,SAAS,OAAO,KAAK;AAG3B,UAAO;IAAE,OAFK,KAAK,MAAM,OAAO,QAAQ,SAE1B;IAAE,MAAM;KAAE;KAAM;KAAU;KAAO,YAD5B,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,SAAS,CACD;KAAE;IAAE,UAAU;IAAY;;AAGrF,MAAI;GAEF,IAAI,SAAS,CAAC,IAAG,MADC,gCAAgC,QAAQ,EACrC,OAAO,CAAC,QAAQ,MAAM,EAAE,MAAM,MAAM,CAAC;AAC1D,OAAI,OAAO,SAAS,GAAG;AACrB,QAAI,OAAO,UAAU,MAAM,EAAE;KAC3B,MAAM,OAAO,OAAO,SAAS,MAAM;AACnC,cAAS,OAAO,QAAQ,OAAO,EAAE,cAAc,EAAE,EAAE,MAAM,MAAM,OAAO,EAAE,CAAC,MAAM,KAAK,KAAK,CAAC;;AAE5F,QAAI,OAAO,SAAS,YAAa,QAAO,MAAM,GAAG,OAAO,EAAE,aAAa,MAAM,EAAE,aAAa,GAAG;aACtF,OAAO,SAAS,SAAU,QAAO,MAAM,GAAG,OAAO,EAAE,QAAQ,QAAQ,EAAE,QAAQ,KAAK;IAC3F,MAAM,OAAO,4BAA4B,OAAO;IAChD,MAAM,QAAQ,KAAK;IACnB,MAAM,SAAS,OAAO,KAAK;AAG3B,WAAO;KAAE,OAFK,KAAK,MAAM,OAAO,QAAQ,SAE1B;KAAE,MAAM;MAAE;MAAM;MAAU;MAAO,YAD5B,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,SAAS,CACD;MAAE;KAAE,UAAU;KAAY;;UAE/E;EAER,MAAM,QAAQ,MAAM,4BAA4B;AAChD,MAAI,OAAO,UAAU,MAAM,EAAE;GAE3B,IAAI,YAAW,MADO,6BAA6B,MAAM,EAClC,KAAK,MAAM,iCAAiC,EAAE,MAAM,CAAC;AAC5E,cAAW,iBAAiB,UAAU,OAAO,SAAS;AACtD,OAAI,OAAO,SAAS,YAAa,YAAW,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,UAAU;YAC1F,OAAO,SAAS,SAAU,YAAW,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,MAAM,OAAO,EAAE,UAAU,GAAG,OAAO,EAAE,UAAU,CAAC;GACrH,MAAM,QAAQ,SAAS;GACvB,MAAM,SAAS,OAAO,KAAK;AAG3B,UAAO;IAAE,OAFK,SAAS,MAAM,OAAO,QAAQ,SAE9B;IAAE,MAAM;KAAE;KAAM;KAAU;KAAO,YAD5B,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,SAAS,CACD;KAAE;IAAE,UAAU;IAAY;;EAGrF,MAAM,QAAQ,MAAM;EACpB,MAAM,SAAS,OAAO,KAAK;EAC3B,MAAM,iBAAiB,MAAM,MAAM,OAAO,QAAQ,SAAS;EAC3D,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,SAAS,CAAC;AAG3D,SAAO;GAAE,QADK,MADQ,6BAA6B,eAAe,EAC5C,KAAK,MAAM,iCAAiC,EAAE,MAAM,CAC5D;GAAE,MAAM;IAAE;IAAM;IAAU;IAAO;IAAY;GAAE,UAAU;GAAY;;CAGrF,MAAM,iBAAiB,SAAS,aAAa;EAC3C,MAAM,OAAO,YAAY,MAAM;EAC/B,IAAI;AACJ,MAAI;AACF,YAAS,MAAM,iBAAiB,KAAK;WAC9B,aAAa;GACpB,MAAM,UAAU,MAAM,sBAAsB,KAAK;AACjD,OAAI,QAAS,QAAO,8BAA8B,QAAQ;AAC1D,SAAM;;EAER,MAAM,UAAU,OAAO,cAAc;EACrC,MAAM,YAAY,OAAO,cAAc;EAEvC,IAAI,SAAwB;EAC5B,IAAI,UAAyB;AAC7B,MAAI;GACF,MAAM,EAAE,UAAU,MAAM,sBAAsB,MAAM,QAAQ;AAC5D,aAAU,wBAAwB,MAAM;AACxC,OAAI,QAAS,UAAS,MAAM,yBAAyB,MAAM,SAAS,QAAQ;UACtE;AAAE,YAAS;;EAEnB,MAAM,UAAU,QAAQ,MAAM,IAAI;EAElC,MAAM,aADU,UAAU,SAAS,QAAQ,QAAQ,OAAO,IAAI,CAAC,CAAC,aAAa,GAAG,QAClD;AAE9B,MAAI,CAAC,QACH,UAAS,+BAA+B,OAAO;WACtC,WAAW;AACpB,YAAS;AACT,OAAI,WAAW,MAAM,IAAI,CAAC,wBAAwB,UAAU,CAC1D,UAAS,GAAG,QAAQ,6BAA6B,UAAU,MAAM;SAE9D;AACL,YAAS;AACT,OAAI,WAAW,MAAM,IAAI,CAAC,wBAAwB,UAAU,CAC1D,UAAS,GAAG,QAAQ,6BAA6B,UAAU,MAAM;;AAIrE,SAAO;GACL,IAAI,OAAO,MAAM;GACjB,MAAM,OAAO,MAAM;GACnB,MAAM;GACN,aAAa,OAAO,MAAM,cAAc,OAAO,MAAM;GACrD;GACA,WAAW,OAAO,MAAM,MAAM;GAC9B,QAAQ;IACN,UAAU,OAAO,MAAM;IACvB,WAAW,OAAO,MAAM;IACzB;GACD,eAAe;IACb,SAAS,OAAO,cAAc;IAC9B,WAAW,OAAO,cAAc;IAChC,aAAa,OAAO,OAAO,cAAc,UAAU;IACpD;GACD,UAAU;GACV,cAAc;IACZ,UAAU,OAAO,MAAM;IACvB,UAAU,OAAO,MAAM,MAAM;IAC7B,OAAO,OAAO,MAAM,MAAM;IAC1B,iBAAiB,OAAO,cAAc;IACvC;GACF;;CAGH,MAAM,gBAAgB,SAAS,aAAa,SAAS;EACnD,MAAM,OAAO,YAAY,MAAM;AAC/B,MAAI,SAAS,MAAM,EAAE;GACnB,MAAM,EAAE,QAAQ,SAAS,oBAAoB,MAAM,0BAA0B,MAAM,QAAQ;AAC3F,UAAO;IAAE;IAAQ,SAAS,eAAe,KAAK,GAAG,OAAO;IAAW,SAAS;IAAiB;;EAE/F,MAAM,UAAU,8BAA8B;AAC9C,MAAI;GACF,MAAM,SAAS,MAAM,iCAAiC,SAAS,KAAK;GACpE,IAAI,kBAAkB;AACtB,OAAI;AAAE,uBAAmB,MAAM,sBAAsB,KAAK,EAAE;WAAiB;AAC7E,UAAO;IAAE;IAAQ,SAAS,eAAe,KAAK,GAAG,OAAO;IAAW,SAAS;IAAiB;UACvF;GACN,MAAM,EAAE,QAAQ,SAAS,oBAAoB,MAAM,0BAA0B,KAAK;AAClF,UAAO;IAAE;IAAQ,SAAS,eAAe,KAAK,GAAG,OAAO;IAAW,SAAS;IAAiB;;;CAGlG;AAED,2BAA2B;CACzB,SAAS;CACT,aAAa;CACd,CAAC"}
1
+ {"version":3,"file":"adapter.js","names":[],"sources":["../../../../../../../src/agent/skills/marketplace/adapters/skillhub/adapter.ts"],"sourcesContent":["/**\n * SkillHub (skillhub.cn) skills marketplace adapter.\n */\n\nimport { basename } from 'node:path';\n\nimport { buildSkillMarkdownPreviewFromRaw } from '../../../skill-markdown-preview-from-raw.js';\nimport type { MarketplaceCategoryOption } from '../store/store-api-client.js';\nimport type { SkillsMarketplaceAdapter } from '../../adapter.types.js';\nimport { sortMarketplaceCategories } from '../../marketplace-category-order.js';\nimport { registerMarketplaceAdapter } from '../../registry.js';\n\n// ─── Constants ───────────────────────────────────────────────────────────────\n\nconst SKILLHUB_API_BASE = 'https://api.skillhub.cn';\nconst MAX_SKILL_ZIP_BYTES = 15 * 1024 * 1024;\nconst MAX_SKILLHUB_README_BYTES = 512 * 1024;\nconst SKILL_ID_RE = /^[a-zA-Z0-9]([a-zA-Z0-9._-]{0,62})$/;\nconst REGISTRY_SKILL_BATCH_CHUNK = 80;\n\nconst DEFAULT_SKILLS_INDEX_URL = 'https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/skills.json';\nconst DEFAULT_SEARCH_URL = 'https://lightmake.site/api/v1/search';\nconst DEFAULT_PRIMARY_DOWNLOAD_TEMPLATE = 'https://lightmake.site/api/v1/download?slug={slug}';\nconst DEFAULT_FALLBACK_DOWNLOAD_TEMPLATE =\n 'https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/skills/{slug}.zip';\nconst DEFAULT_ALLOWED_DOWNLOAD_HOSTS = new Set([\n 'lightmake.site',\n 'api.skillhub.cn',\n 'skillhub-1388575217.cos.ap-guangzhou.myqcloud.com',\n]);\nconst LIGHTMAKE_SEARCH_MAX = 100;\nconst SKILLSET_DISCOVERY_PAGE_CAP = 25;\nconst MAX_DEFAULT_SLUGS = 200;\n\nconst DEFAULT_CACHE_MS = 5 * 60 * 1000;\nconst MAX_BATCH_CACHE_KEYS = 48;\n\n// ─── Inline helpers ──────────────────────────────────────────────────────────\n\nfunction isValidSkillId(id: string): boolean {\n return SKILL_ID_RE.test(id);\n}\n\n// ─── SkillHub registry types ─────────────────────────────────────────────────\n\ninterface SkillHubSkill {\n slug: string;\n displayName: string;\n summary: string;\n summary_zh?: string;\n category: string;\n iconUrl: string | null;\n source: string;\n labels: { requires_api_key?: string };\n stats: {\n downloads: number;\n installs: number;\n stars: number;\n comments: number;\n versions: number;\n };\n createdAt: number;\n updatedAt: number;\n tags: Record<string, string>;\n}\n\ninterface SkillHubSkillDetail {\n skill: SkillHubSkill;\n latestVersion: {\n version: string;\n changelog: string | null;\n createdAt: number;\n securityReports?: {\n keen?: { status: string; statusText: string; reportUrl?: string };\n sanbu?: { status: string; statusText: string; reportUrl?: string };\n };\n };\n owner: { handle: string; displayName: string; image: string | null };\n}\n\ninterface SkillHubFile { path: string; sha256: string; size: number }\n\ninterface SkillHubRegistryCategoryItem {\n key: string;\n name: string;\n nameEn: string;\n sortOrder: number;\n active: boolean;\n}\n\ninterface SkillHubSkillset {\n id: number;\n slug: string;\n displayName: string;\n summary: string;\n scene: string;\n subScene: string;\n content: string;\n skillSlugs: string[];\n skillCount: number;\n createdAt: number;\n updatedAt: number;\n}\n\n// ─── Ecosystem types ─────────────────────────────────────────────────────────\n\ninterface EcosystemUrls {\n skillsIndexUrl: string;\n searchUrl: string;\n primaryDownloadTemplate: string;\n fallbackDownloadTemplate: string;\n}\n\ninterface CuratedIndexSkill {\n rank?: number;\n slug: string;\n name?: string;\n description?: string;\n version?: string;\n homepage?: string;\n downloads?: number;\n stars?: number;\n score?: number;\n categories?: string[];\n}\n\ninterface CuratedIndex {\n total?: number;\n skills: CuratedIndexSkill[];\n}\n\ninterface LightmakeSearchHit {\n slug: string;\n displayName?: string;\n name?: string;\n summary?: string;\n description?: string;\n description_zh?: string;\n version?: string;\n downloads?: number;\n installs?: number;\n stars?: number;\n owner_name?: string;\n category?: string;\n score?: number;\n updatedAt?: number;\n updated_at?: number;\n /** Origin registry label from Lightmake (e.g. clawhub, community). Detail/download still go\n * through api.skillhub.cn for synced skills. */\n source?: string;\n}\n\ninterface PackageListItem {\n id: string;\n name: string;\n type: string;\n description: string;\n downloads: number;\n author: { username: string; avatarUrl: string | null };\n latestVersion?: string;\n updatedAt: string;\n categories?: string[];\n stars?: number;\n sourceLabel?: string;\n}\n\n// ─── Registry HTTP helpers ───────────────────────────────────────────────────\n\nasync function registryFetchJson<T>(url: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, {\n ...init,\n headers: { Accept: 'application/json', ...(init?.headers as Record<string, string> | undefined) },\n });\n const text = await res.text();\n if (!res.ok) {\n let msg = `SkillHub request failed (${res.status})`;\n try {\n const j = JSON.parse(text) as { message?: string; error?: string };\n if (j.message) msg = j.message;\n else if (j.error) msg = j.error;\n } catch { if (text) msg = text.slice(0, 200); }\n throw new Error(msg);\n }\n try { return JSON.parse(text) as T; }\n catch { throw new Error('SkillHub returned invalid JSON'); }\n}\n\nfunction basenameSkillPath(p: string): string {\n const norm = p.replace(/\\\\/g, '/');\n const parts = norm.split('/');\n return parts[parts.length - 1] || norm;\n}\n\nfunction pickSkillHubDocFilePath(files: SkillHubFile[]): string | null {\n const rows = files.map((f) => ({\n path: f.path.replace(/\\\\/g, '/'),\n base: basenameSkillPath(f.path).toLowerCase(),\n }));\n const firstBase = (name: string) => rows.find((r) => r.base === name.toLowerCase());\n const skillMd = firstBase('SKILL.md') ?? firstBase('skill.md');\n if (skillMd) return skillMd.path;\n const readme = firstBase('README.md') ?? firstBase('readme.md');\n if (readme) return readme.path;\n const how = firstBase('HOW_TO_USE.md');\n if (how) return how.path;\n return null;\n}\n\nfunction assertSkillHubReadmeResponseUrl(finalUrl: string): void {\n let u: URL;\n try { u = new URL(finalUrl); } catch { throw new Error('Invalid SkillHub file response URL'); }\n if (u.protocol !== 'https:') throw new Error('SkillHub file response must use HTTPS');\n const host = u.hostname.toLowerCase();\n if (host === 'api.skillhub.cn') return;\n if (host.endsWith('.myqcloud.com')) return;\n throw new Error('SkillHub file redirect host is not allowlisted');\n}\n\nasync function getSkillHubSkillFileText(slug: string, filePath: string, version?: string): Promise<string> {\n const enc = encodeURIComponent(slug.trim());\n const normPath = filePath.replace(/\\\\/g, '/');\n const sp = new URLSearchParams({ path: normPath });\n if (version?.trim()) sp.set('version', version.trim());\n const url = `${SKILLHUB_API_BASE}/api/v1/skills/${enc}/file?${sp.toString()}`;\n const res = await fetch(url, { redirect: 'follow', headers: { Accept: 'text/markdown,text/plain,*/*' } });\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n let msg = `SkillHub file request failed (${res.status})`;\n try {\n const j = JSON.parse(text) as { message?: string; error?: string };\n if (typeof j.message === 'string') msg = j.message;\n else if (typeof j.error === 'string') msg = j.error;\n } catch { if (text) msg = text.slice(0, 200); }\n throw new Error(msg);\n }\n assertSkillHubReadmeResponseUrl(res.url);\n const len = res.headers.get('content-length');\n if (len) {\n const n = Number(len);\n if (Number.isFinite(n) && n > MAX_SKILLHUB_README_BYTES) throw new Error(`SkillHub file exceeds max size`);\n }\n const ab = await res.arrayBuffer();\n if (ab.byteLength > MAX_SKILLHUB_README_BYTES) throw new Error(`SkillHub file exceeds max size`);\n return new TextDecoder('utf-8').decode(ab);\n}\n\nasync function getSkillHubSkill(slug: string): Promise<SkillHubSkillDetail> {\n return registryFetchJson<SkillHubSkillDetail>(`${SKILLHUB_API_BASE}/api/v1/skills/${encodeURIComponent(slug.trim())}`);\n}\n\nasync function getSkillHubSkillFiles(slug: string, version?: string): Promise<{ files: SkillHubFile[]; version: string }> {\n const enc = encodeURIComponent(slug.trim());\n const sp = version ? `?version=${encodeURIComponent(version)}` : '';\n return registryFetchJson<{ files: SkillHubFile[]; version: string }>(`${SKILLHUB_API_BASE}/api/v1/skills/${enc}/files${sp}`);\n}\n\nasync function downloadSkillHubZipBuffer(slug: string, version?: string): Promise<{ buffer: Buffer; version: string }> {\n const enc = encodeURIComponent(slug.trim());\n let url = `${SKILLHUB_API_BASE}/api/v1/download?slug=${enc}`;\n if (version?.trim()) url += `&version=${encodeURIComponent(version.trim())}`;\n const res = await fetch(url, { redirect: 'follow' });\n if (!res.ok) throw new Error(`Failed to download skill archive (${res.status})`);\n const len = res.headers.get('content-length');\n if (len) { const n = Number(len); if (Number.isFinite(n) && n > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`); }\n const ab = await res.arrayBuffer();\n const buf = Buffer.from(ab);\n if (buf.length > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`);\n let resolvedVersion = version ?? '1.0.0';\n if (!version?.trim()) {\n try { resolvedVersion = (await getSkillHubSkillFiles(slug)).version; } catch { /* keep default */ }\n }\n return { buffer: buf, version: resolvedVersion };\n}\n\nasync function batchGetSkillHubSkills(slugs: string[]): Promise<SkillHubSkillDetail[]> {\n if (slugs.length === 0) return [];\n const response = await registryFetchJson<{ count: number; items: SkillHubSkillDetail[]; missing: string[] }>(\n `${SKILLHUB_API_BASE}/api/v1/skills/batch`,\n { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ slugs }) },\n );\n return response.items ?? [];\n}\n\nasync function listSkillHubRegistryCategories(): Promise<SkillHubRegistryCategoryItem[]> {\n const raw = await registryFetchJson<{ count?: number; items?: SkillHubRegistryCategoryItem[] }>(\n `${SKILLHUB_API_BASE}/api/v1/categories`,\n );\n const items = Array.isArray(raw.items) ? raw.items : [];\n return items.filter((c) => c && typeof c.key === 'string' && c.key.trim().length > 0 && c.active !== false);\n}\n\nasync function listSkillHubSkillsets(opts: { page?: number; pageSize?: number; keyword?: string; scene?: string } = {}): Promise<{ skillSets: SkillHubSkillset[]; total: number }> {\n const page = opts.page ?? 1;\n const pageSize = opts.pageSize ?? 20;\n const sp = new URLSearchParams({ page: String(page), pageSize: String(pageSize) });\n if (opts.keyword?.trim()) sp.set('keyword', opts.keyword.trim());\n if (opts.scene?.trim()) sp.set('scene', opts.scene.trim());\n return registryFetchJson<{ skillSets: SkillHubSkillset[]; total: number }>(`${SKILLHUB_API_BASE}/api/v1/skillsets?${sp.toString()}`);\n}\n\nasync function getDefaultSkillSlugs(): Promise<string[]> {\n const slugs = new Set<string>();\n let page = 1;\n const pageSize = 50;\n let total = Infinity;\n while (page <= SKILLSET_DISCOVERY_PAGE_CAP && slugs.size < MAX_DEFAULT_SLUGS) {\n const response = await listSkillHubSkillsets({ page, pageSize });\n total = response.total;\n for (const skillset of response.skillSets) {\n for (const slug of skillset.skillSlugs) slugs.add(slug);\n }\n if (page * pageSize >= total) break;\n page += 1;\n }\n return Array.from(slugs).slice(0, MAX_DEFAULT_SLUGS);\n}\n\nasync function searchSkillHubSkills(query: string, maxSlugs = 200): Promise<{ slugs: string[]; total: number }> {\n const keyword = query.trim();\n if (!keyword) return { slugs: [], total: 0 };\n const slugs: string[] = [];\n const seen = new Set<string>();\n let page = 1;\n const batchSize = 50;\n while (page <= SKILLSET_DISCOVERY_PAGE_CAP) {\n const response = await listSkillHubSkillsets({ page, pageSize: batchSize, keyword });\n for (const skillset of response.skillSets) {\n for (const slug of skillset.skillSlugs) {\n if (!seen.has(slug)) { seen.add(slug); slugs.push(slug); }\n }\n }\n if (page * batchSize >= response.total) break;\n page += 1;\n }\n const capped = slugs.slice(0, maxSlugs);\n return { slugs: capped, total: capped.length };\n}\n\n// ─── Ecosystem helpers ───────────────────────────────────────────────────────\n\nfunction templateWithSlug(template: string, slug: string): string {\n const raw = template.trim();\n if (!raw) return '';\n if (raw.includes('{slug}')) return raw.replaceAll('{slug}', encodeURIComponent(slug.trim()));\n const base = raw.replace(/\\/$/, '');\n return `${base}/${encodeURIComponent(slug.trim())}.zip`;\n}\n\nfunction hostFromTemplate(template: string): string | undefined {\n const t = templateWithSlug(template, 'x');\n try { return new URL(t).hostname.toLowerCase(); } catch { return undefined; }\n}\n\nfunction resolveSkillHubEcosystemUrls(): EcosystemUrls {\n return {\n skillsIndexUrl: process.env.XOPC_SKILLHUB_SKILLS_INDEX_URL?.trim() || DEFAULT_SKILLS_INDEX_URL,\n searchUrl: process.env.XOPC_SKILLHUB_SEARCH_URL?.trim() || DEFAULT_SEARCH_URL,\n primaryDownloadTemplate: process.env.XOPC_SKILLHUB_PRIMARY_DOWNLOAD_TEMPLATE?.trim() || DEFAULT_PRIMARY_DOWNLOAD_TEMPLATE,\n fallbackDownloadTemplate: process.env.XOPC_SKILLHUB_FALLBACK_DOWNLOAD_TEMPLATE?.trim() || DEFAULT_FALLBACK_DOWNLOAD_TEMPLATE,\n };\n}\n\nfunction allowedDownloadHosts(urls: EcosystemUrls): Set<string> {\n const hosts = new Set(DEFAULT_ALLOWED_DOWNLOAD_HOSTS);\n for (const h of [hostFromTemplate(urls.primaryDownloadTemplate), hostFromTemplate(urls.fallbackDownloadTemplate)]) { if (h) hosts.add(h); }\n try { hosts.add(new URL(urls.skillsIndexUrl).hostname.toLowerCase()); } catch { /* ignore */ }\n try { hosts.add(new URL(urls.searchUrl).hostname.toLowerCase()); } catch { /* ignore */ }\n return hosts;\n}\n\nfunction assertSkillHubDownloadUrlAllowed(downloadUrl: string, urls: EcosystemUrls): URL {\n let u: URL;\n try { u = new URL(downloadUrl); } catch { throw new Error('Invalid SkillHub download URL'); }\n if (u.protocol !== 'https:') throw new Error('SkillHub download URL must use HTTPS');\n if (!allowedDownloadHosts(urls).has(u.hostname.toLowerCase())) throw new Error('SkillHub download URL host is not allowlisted');\n return u;\n}\n\nasync function ecoFetchJson<T>(url: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, { ...init, headers: { Accept: 'application/json', ...init?.headers } });\n const text = await res.text();\n if (!res.ok) {\n let msg = `SkillHub ecosystem request failed (${res.status})`;\n try { const j = JSON.parse(text) as { message?: string; error?: string }; if (j.message) msg = j.message; else if (j.error) msg = j.error; } catch { if (text) msg = text.slice(0, 200); }\n throw new Error(msg);\n }\n try { return JSON.parse(text) as T; } catch { throw new Error('SkillHub ecosystem returned invalid JSON'); }\n}\n\nasync function fetchSkillHubCuratedIndex(urls: EcosystemUrls): Promise<CuratedIndex> {\n const raw = await ecoFetchJson<unknown>(urls.skillsIndexUrl);\n if (Array.isArray(raw)) return { skills: raw as CuratedIndexSkill[] };\n if (raw && typeof raw === 'object' && Array.isArray((raw as CuratedIndex).skills)) return raw as CuratedIndex;\n throw new Error('SkillHub index JSON must be an object with a skills array');\n}\n\nfunction sourceLabelFromHomepage(homepage?: string): string | undefined {\n const h = homepage?.trim().toLowerCase() ?? '';\n if (h.includes('clawhub')) return 'ClawHub';\n if (h.includes('skillhub')) return 'SkillHub';\n return undefined;\n}\n\nfunction curatedSkillsToPackageItems(skills: CuratedIndexSkill[]): PackageListItem[] {\n return skills.map((s) => ({\n id: s.slug,\n name: (s.name ?? s.slug).trim() || s.slug,\n type: 'skill',\n description: (s.description ?? '').trim(),\n downloads: typeof s.downloads === 'number' ? s.downloads : 0,\n author: { username: 'skillhub', avatarUrl: null },\n latestVersion: (s.version ?? '').trim() || undefined,\n updatedAt: String(s.rank ?? s.score ?? 0),\n categories: (s.categories ?? []).map((c) => String(c).trim()).filter(Boolean),\n stars: typeof s.stars === 'number' ? s.stars : undefined,\n sourceLabel: sourceLabelFromHomepage(s.homepage),\n }));\n}\n\nasync function findCuratedIndexSkill(slug: string): Promise<CuratedIndexSkill | null> {\n const want = slug.trim();\n if (!want) return null;\n const ecoUrls = resolveSkillHubEcosystemUrls();\n try {\n const idx = await cachedFetchSkillHubCuratedIndex(ecoUrls);\n return idx.skills.find((s) => s.slug?.trim() === want) ?? null;\n } catch {\n return null;\n }\n}\n\nfunction curatedSkillFallbackReadmeMarkdown(skill: CuratedIndexSkill): string {\n const title = (skill.name ?? skill.slug).trim() || skill.slug;\n const desc = (skill.description ?? '').trim() || '_No description._';\n const version = (skill.version ?? '').trim() || '1.0.0';\n return `## ${title}\\n\\n**${skill.slug}** · v${version}\\n\\n${desc}`;\n}\n\nfunction packageDetailFromCuratedSkill(skill: CuratedIndexSkill) {\n const slug = skill.slug.trim();\n const version = (skill.version ?? '').trim() || '1.0.0';\n const categories = (skill.categories ?? []).map((c) => String(c).trim()).filter(Boolean);\n const sourceLabel = sourceLabelFromHomepage(skill.homepage);\n const name = (skill.name ?? slug).trim() || slug;\n const description = (skill.description ?? '').trim();\n const readme = curatedSkillFallbackReadmeMarkdown(skill);\n return {\n id: slug,\n name,\n type: 'skill',\n description,\n readme,\n skillDocPreview: buildSkillMarkdownPreviewFromRaw(readme, { name, description }),\n downloads: typeof skill.downloads === 'number' ? skill.downloads : 0,\n author: {\n username: sourceLabel?.toLowerCase() ?? 'skillhub',\n avatarUrl: null,\n },\n latestVersion: {\n version,\n changelog: null,\n publishedAt: String(skill.rank ?? skill.score ?? 0),\n },\n provider: 'skillhub',\n skillHubInfo: {\n category: categories[0] ?? '',\n installs: 0,\n stars: typeof skill.stars === 'number' ? skill.stars : 0,\n },\n };\n}\n\nfunction lightmakeHitToPackageItem(hit: LightmakeSearchHit): PackageListItem {\n const slug = String(hit.slug || '').trim();\n const desc = (hit.summary ?? hit.description_zh ?? hit.description ?? '').trim() || '';\n const updated = hit.updatedAt ?? hit.updated_at ?? 0;\n const cat = hit.category?.trim();\n return {\n id: slug,\n name: (hit.displayName ?? hit.name ?? slug).trim() || slug,\n type: 'skill',\n description: desc,\n downloads: typeof hit.downloads === 'number' ? hit.downloads : 0,\n author: { username: (hit.owner_name ?? 'skillhub').trim() || 'skillhub', avatarUrl: null },\n latestVersion: (hit.version ?? '').trim() || undefined,\n updatedAt: String(updated),\n categories: cat ? [cat] : [],\n stars: typeof hit.stars === 'number' ? hit.stars : undefined,\n sourceLabel: sourceLabelFromSkillSource(hit.source) ?? 'Lightmake',\n };\n}\n\nasync function searchSkillHubLightmake(urls: EcosystemUrls, query: string, limit: number, timeoutMs = 4000): Promise<PackageListItem[]> {\n const q = query.trim().toLowerCase();\n if (!q) return [];\n const search = new URL(urls.searchUrl);\n if (search.protocol !== 'https:') throw new Error('SkillHub search URL must use HTTPS');\n search.searchParams.set('q', q);\n search.searchParams.set('limit', String(Math.max(1, Math.min(LIGHTMAKE_SEARCH_MAX, limit))));\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const raw = await ecoFetchJson<{ results?: LightmakeSearchHit[] }>(search.toString(), { signal: controller.signal });\n const results = raw.results;\n if (!Array.isArray(results)) return [];\n const out: PackageListItem[] = [];\n for (const item of results) {\n if (!item || typeof item !== 'object') continue;\n const hit = item as LightmakeSearchHit;\n const slug = String(hit.slug ?? '').trim();\n if (!slug) continue;\n out.push(lightmakeHitToPackageItem(hit));\n }\n return out;\n } finally { clearTimeout(timer); }\n}\n\nasync function downloadSkillHubZipFromAllowlistedUrl(urls: EcosystemUrls, downloadUrl: string): Promise<Buffer> {\n const normalized = assertSkillHubDownloadUrlAllowed(downloadUrl, urls);\n const res = await fetch(normalized.toString(), { redirect: 'follow' });\n if (!res.ok) throw new Error(`Failed to download skill archive (${res.status})`);\n const len = res.headers.get('content-length');\n if (len) { const n = Number(len); if (Number.isFinite(n) && n > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`); }\n const ab = await res.arrayBuffer();\n const buf = Buffer.from(ab);\n if (buf.length > MAX_SKILL_ZIP_BYTES) throw new Error(`Zip exceeds max size`);\n return buf;\n}\n\nasync function downloadSkillHubZipFromEcosystem(urls: EcosystemUrls, slug: string): Promise<Buffer> {\n const primary = templateWithSlug(urls.primaryDownloadTemplate, slug);\n const fallback = templateWithSlug(urls.fallbackDownloadTemplate, slug);\n const candidates = [primary, fallback].filter(Boolean);\n const seen = new Set<string>();\n let lastErr: Error | undefined;\n for (const url of candidates) {\n if (seen.has(url)) continue;\n seen.add(url);\n try { return await downloadSkillHubZipFromAllowlistedUrl(urls, url); }\n catch (e) { lastErr = e instanceof Error ? e : new Error(String(e)); }\n }\n throw lastErr ?? new Error('SkillHub ecosystem download failed');\n}\n\n// ─── In-memory TTL cache ─────────────────────────────────────────────────────\n\ntype CacheEntry<T> = { value: T; expiresAt: number };\n\nfunction cacheTtlMs(): number {\n const raw = process.env.XOPC_SKILLHUB_CACHE_MS?.trim();\n if (raw === '0' || raw === 'false') return 0;\n const n = Number(raw);\n if (!Number.isFinite(n) || n < 0) return DEFAULT_CACHE_MS;\n return n;\n}\n\nfunction getFresh<T>(entry: CacheEntry<T> | undefined): T | undefined {\n if (!entry || entry.expiresAt <= Date.now()) return undefined;\n return entry.value;\n}\n\nconst curatedByIndexUrl = new Map<string, CacheEntry<CuratedIndex>>();\nlet defaultSlugsEntry: CacheEntry<string[]> | undefined;\nlet registryCategoriesEntry: CacheEntry<SkillHubRegistryCategoryItem[]> | undefined;\nconst batchBySlugsKey = new Map<string, CacheEntry<SkillHubSkillDetail[]>>();\nconst lightmakeSearchByQuery = new Map<string, CacheEntry<PackageListItem[]>>();\n\nfunction evictOldestBatchKey(): void {\n const first = batchBySlugsKey.keys().next().value;\n if (first !== undefined) batchBySlugsKey.delete(first);\n}\n\nfunction evictOldestSearchKey(): void {\n const first = lightmakeSearchByQuery.keys().next().value;\n if (first !== undefined) lightmakeSearchByQuery.delete(first);\n}\n\nfunction batchSlugsCacheKey(slugs: string[]): string {\n if (slugs.length === 0) return '';\n return [...slugs].sort().join('\\n');\n}\n\nasync function cachedFetchSkillHubCuratedIndex(urls: EcosystemUrls): Promise<CuratedIndex> {\n const ttl = cacheTtlMs();\n const key = urls.skillsIndexUrl;\n if (ttl > 0) { const hit = getFresh(curatedByIndexUrl.get(key)); if (hit) return hit; }\n const value = await fetchSkillHubCuratedIndex(urls);\n if (ttl > 0) curatedByIndexUrl.set(key, { value, expiresAt: Date.now() + ttl });\n return value;\n}\n\nasync function cachedGetDefaultSkillSlugs(): Promise<string[]> {\n const ttl = cacheTtlMs();\n if (ttl > 0) { const hit = getFresh(defaultSlugsEntry); if (hit) return hit; }\n const value = await getDefaultSkillSlugs();\n if (ttl > 0) defaultSlugsEntry = { value, expiresAt: Date.now() + ttl };\n return value;\n}\n\nasync function cachedListSkillHubRegistryCategories(): Promise<SkillHubRegistryCategoryItem[]> {\n const ttl = cacheTtlMs();\n if (ttl > 0) { const hit = getFresh(registryCategoriesEntry); if (hit) return hit; }\n const value = await listSkillHubRegistryCategories();\n if (ttl > 0) registryCategoriesEntry = { value, expiresAt: Date.now() + ttl };\n return value;\n}\n\nasync function cachedBatchGetSkillHubSkills(slugs: string[]): Promise<SkillHubSkillDetail[]> {\n if (slugs.length === 0) return [];\n const ttl = cacheTtlMs();\n const key = batchSlugsCacheKey(slugs);\n if (ttl > 0) { const hit = getFresh(batchBySlugsKey.get(key)); if (hit) return hit; }\n const value = await batchGetSkillHubSkills(slugs);\n if (ttl > 0) {\n while (batchBySlugsKey.size >= MAX_BATCH_CACHE_KEYS) evictOldestBatchKey();\n batchBySlugsKey.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\nasync function cachedSearchSkillHubLightmake(\n urls: EcosystemUrls,\n query: string,\n limit: number,\n): Promise<PackageListItem[]> {\n const q = query.trim().toLowerCase();\n if (!q) return [];\n const ttl = cacheTtlMs();\n const key = `${urls.searchUrl}|${q}|${limit}`;\n if (ttl > 0) { const hit = getFresh(lightmakeSearchByQuery.get(key)); if (hit) return hit; }\n const value = await searchSkillHubLightmake(urls, q, limit);\n if (ttl > 0) {\n while (lightmakeSearchByQuery.size >= MAX_BATCH_CACHE_KEYS) evictOldestSearchKey();\n lightmakeSearchByQuery.set(key, { value, expiresAt: Date.now() + ttl });\n }\n return value;\n}\n\n// ─── Adapter conversion helpers ──────────────────────────────────────────────\n\nfunction humanizeRegistryCategoryKey(slug: string): string {\n return slug.replace(/_/g, '-').split('-').filter(Boolean)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(' ');\n}\n\nfunction sourceLabelFromSkillSource(source: string | undefined): string | undefined {\n const s = source?.trim();\n if (!s) return undefined;\n const lower = s.toLowerCase();\n if (lower === 'clawhub') return 'ClawHub';\n if (lower === 'lightmake') return 'Lightmake';\n if (lower === 'skillhub') return 'SkillHub';\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction filterByCategory(rows: PackageListItem[], category?: string): PackageListItem[] {\n const want = category?.trim();\n if (!want) return rows;\n return rows.filter((r) => (r.categories ?? []).includes(want));\n}\n\nasync function collectRegistryCategoryKeysFromSlugs(slugs: string[]): Promise<Set<string>> {\n const used = new Set<string>();\n for (let i = 0; i < slugs.length; i += REGISTRY_SKILL_BATCH_CHUNK) {\n const chunk = slugs.slice(i, i + REGISTRY_SKILL_BATCH_CHUNK);\n const details = await cachedBatchGetSkillHubSkills(chunk);\n for (const d of details) {\n const k = d.skill.category?.trim();\n if (k) used.add(k);\n }\n }\n return used;\n}\n\nfunction isPipelineOnlyChangelog(text: string | null | undefined): boolean {\n if (!text?.trim()) return true;\n return /^synced by skillhub pipeline\\.?$/i.test(text.trim());\n}\n\nfunction skillHubFallbackReadmeMarkdown(detail: { skill: SkillHubSkill; latestVersion: { version: string } }): string {\n const s = detail.skill;\n const title = s.displayName?.trim() || s.slug;\n const zh = s.summary_zh?.trim();\n const en = s.summary?.trim();\n const body = zh && en && zh !== en ? `${zh}\\n\\n${en}` : zh || en || '_No description._';\n return `## ${title}\\n\\n**${s.slug}** · v${detail.latestVersion.version}\\n\\n${body}`;\n}\n\nfunction convertSkillHubToPackageListItem(detail: SkillHubSkill): PackageListItem {\n const cat = detail.category?.trim();\n return {\n id: detail.slug,\n name: detail.displayName?.trim() || detail.slug,\n type: 'skill',\n description: detail.summary_zh || detail.summary,\n downloads: detail.stats.downloads,\n author: { username: detail.source || 'skillhub', avatarUrl: null },\n latestVersion: detail.tags.latest || '1.0.0',\n updatedAt: String(detail.updatedAt),\n categories: cat ? [cat] : [],\n stars: detail.stats.stars,\n sourceLabel: sourceLabelFromSkillSource(detail.source),\n };\n}\n\nexport const skillHubMarketplaceAdapter: SkillsMarketplaceAdapter = {\n id: 'skillhub',\n\n async listCategories(_config) {\n const sortByLabel = (a: MarketplaceCategoryOption, b: MarketplaceCategoryOption) =>\n a.label.localeCompare(b.label, 'zh-Hans-CN', { sensitivity: 'base' });\n const ecoUrls = resolveSkillHubEcosystemUrls();\n try {\n const idx = await cachedFetchSkillHubCuratedIndex(ecoUrls);\n if (idx.skills?.length) {\n const map = new Map<string, MarketplaceCategoryOption>();\n for (const s of idx.skills) {\n for (const raw of s.categories ?? []) {\n const label = String(raw).trim();\n if (label) map.set(label, { id: label, label });\n }\n }\n return sortMarketplaceCategories(\n Array.from(map.values()).filter((c) => c.id.trim() && c.label.trim()),\n sortByLabel,\n );\n }\n } catch { /* fall through: registry-backed catalog */ }\n try {\n const [taxonomy, slugs] = await Promise.all([\n cachedListSkillHubRegistryCategories(),\n cachedGetDefaultSkillSlugs(),\n ]);\n const usedKeys = await collectRegistryCategoryKeysFromSlugs(slugs);\n const taxByKey = new Map(taxonomy.map((t) => [t.key, t] as const));\n const options: MarketplaceCategoryOption[] = [];\n for (const key of usedKeys) {\n const t = taxByKey.get(key);\n const label = t?.name?.trim() || t?.nameEn?.trim() || humanizeRegistryCategoryKey(key).trim();\n if (!label) continue;\n options.push({ id: key, label });\n }\n return sortMarketplaceCategories(options, (a, b) => {\n const oa = taxByKey.get(a.id)?.sortOrder ?? 999;\n const ob = taxByKey.get(b.id)?.sortOrder ?? 999;\n if (oa !== ob) return oa - ob;\n return sortByLabel(a, b);\n });\n } catch { return []; }\n },\n\n async listPackages(_config, params) {\n const pageSize = params.pageSize ?? 20;\n const page = params.page ?? 1;\n const ecoUrls = resolveSkillHubEcosystemUrls();\n\n if (params.q?.trim()) {\n const q = params.q.trim();\n let rows: PackageListItem[] = [];\n try {\n rows = await cachedSearchSkillHubLightmake(ecoUrls, q, 100);\n } catch {\n // Lightmake unavailable — fall back to the registry skillset scan. We do NOT run this\n // when Lightmake returned zero hits: that would queue ~40 sequential HTTP calls just to\n // confirm \"no results\", and the empty state UI is the better answer for the user.\n try {\n const searchResult = await searchSkillHubSkills(q, 200);\n const details = await cachedBatchGetSkillHubSkills(searchResult.slugs);\n rows = details.map((d) => convertSkillHubToPackageListItem(d.skill));\n } catch {\n rows = [];\n }\n }\n rows = filterByCategory(rows, params.category);\n if (params.sort === 'downloads') rows = [...rows].sort((a, b) => b.downloads - a.downloads);\n else if (params.sort === 'newest') rows = [...rows].sort((a, b) => Number(b.updatedAt) - Number(a.updatedAt));\n const total = rows.length;\n const start = (page - 1) * pageSize;\n const items = rows.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n }\n\n try {\n const idx = await cachedFetchSkillHubCuratedIndex(ecoUrls);\n let skills = [...idx.skills].filter((s) => s.slug?.trim());\n if (skills.length > 0) {\n if (params.category?.trim()) {\n const want = params.category.trim();\n skills = skills.filter((s) => (s.categories ?? []).some((x) => String(x).trim() === want));\n }\n if (params.sort === 'downloads') skills.sort((a, b) => (b.downloads ?? 0) - (a.downloads ?? 0));\n else if (params.sort === 'newest') skills.sort((a, b) => (a.rank ?? 999) - (b.rank ?? 999));\n const rows = curatedSkillsToPackageItems(skills);\n const total = rows.length;\n const start = (page - 1) * pageSize;\n const items = rows.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n }\n } catch { /* fall through */ }\n\n const slugs = await cachedGetDefaultSkillSlugs();\n if (params.category?.trim()) {\n const details = await cachedBatchGetSkillHubSkills(slugs);\n let allItems = details.map((d) => convertSkillHubToPackageListItem(d.skill));\n allItems = filterByCategory(allItems, params.category);\n if (params.sort === 'downloads') allItems = [...allItems].sort((a, b) => b.downloads - a.downloads);\n else if (params.sort === 'newest') allItems = [...allItems].sort((a, b) => Number(b.updatedAt) - Number(a.updatedAt));\n const total = allItems.length;\n const start = (page - 1) * pageSize;\n const items = allItems.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n }\n\n const total = slugs.length;\n const start = (page - 1) * pageSize;\n const paginatedSlugs = slugs.slice(start, start + pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const details = await cachedBatchGetSkillHubSkills(paginatedSlugs);\n const items = details.map((d) => convertSkillHubToPackageListItem(d.skill));\n return { items, meta: { page, pageSize, total, totalPages }, provider: 'skillhub' };\n },\n\n async getPackageDetail(_config, packageName) {\n const slug = packageName.trim();\n let detail: SkillHubSkillDetail;\n try {\n detail = await getSkillHubSkill(slug);\n } catch (registryErr) {\n const curated = await findCuratedIndexSkill(slug);\n if (curated) return packageDetailFromCuratedSkill(curated);\n throw registryErr;\n }\n const version = detail.latestVersion.version;\n const changelog = detail.latestVersion.changelog;\n\n let readme: string | null = null;\n let docPath: string | null = null;\n try {\n const { files } = await getSkillHubSkillFiles(slug, version);\n docPath = pickSkillHubDocFilePath(files);\n if (docPath) readme = await getSkillHubSkillFileText(slug, docPath, version);\n } catch { readme = null; }\n\n const trimmed = readme?.trim() ?? '';\n const docBase = docPath ? basename(docPath.replace(/\\\\/g, '/')).toLowerCase() : '';\n const isSkillMd = docBase === 'skill.md';\n\n if (!trimmed) {\n readme = skillHubFallbackReadmeMarkdown(detail);\n } else if (isSkillMd) {\n readme = trimmed;\n if (changelog?.trim() && !isPipelineOnlyChangelog(changelog)) {\n readme = `${trimmed}\\n\\n---\\n\\n## Changelog\\n\\n${changelog.trim()}`;\n }\n } else {\n readme = trimmed;\n if (changelog?.trim() && !isPipelineOnlyChangelog(changelog)) {\n readme = `${trimmed}\\n\\n---\\n\\n## Changelog\\n\\n${changelog.trim()}`;\n }\n }\n\n const description = detail.skill.summary_zh || detail.skill.summary;\n const skillDocPreview = buildSkillMarkdownPreviewFromRaw(readme, {\n name: detail.skill.slug,\n description,\n });\n\n return {\n id: detail.skill.slug,\n name: detail.skill.slug,\n type: 'skill',\n description,\n readme,\n skillDocPreview,\n downloads: detail.skill.stats.downloads,\n author: {\n username: detail.owner.handle,\n avatarUrl: detail.owner.image,\n },\n latestVersion: {\n version: detail.latestVersion.version,\n changelog: detail.latestVersion.changelog,\n publishedAt: String(detail.latestVersion.createdAt),\n },\n provider: 'skillhub',\n skillHubInfo: {\n category: detail.skill.category,\n installs: detail.skill.stats.installs,\n stars: detail.skill.stats.stars,\n securityReports: detail.latestVersion.securityReports,\n },\n };\n },\n\n async downloadPackage(_config, packageName, version) {\n const slug = packageName.trim();\n if (version?.trim()) {\n const { buffer, version: resolvedVersion } = await downloadSkillHubZipBuffer(slug, version);\n return { buffer, skillId: isValidSkillId(slug) ? slug : 'unknown', version: resolvedVersion };\n }\n const ecoUrls = resolveSkillHubEcosystemUrls();\n try {\n const buffer = await downloadSkillHubZipFromEcosystem(ecoUrls, slug);\n let resolvedVersion = '1.0.0';\n try { resolvedVersion = (await getSkillHubSkillFiles(slug)).version; } catch { /* keep default */ }\n return { buffer, skillId: isValidSkillId(slug) ? slug : 'unknown', version: resolvedVersion };\n } catch {\n const { buffer, version: resolvedVersion } = await downloadSkillHubZipBuffer(slug);\n return { buffer, skillId: isValidSkillId(slug) ? slug : 'unknown', version: resolvedVersion };\n }\n },\n};\n\nregisterMarketplaceAdapter({\n adapter: skillHubMarketplaceAdapter,\n displayName: 'SkillHub',\n});\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { registerMarketplaceAdapter } from "../../registry.js";
2
2
  import { downloadSkillZipBuffer, fetchMarketplacePackageDetail, listSkillPackages, resolveSkillZipDownloadUrl, resolveSkillsStoreBaseUrl, skillIdForMarketplaceInstall } from "./store-api-client.js";
3
+ import { buildSkillMarkdownPreviewFromRaw } from "../../../skill-markdown-preview-from-raw.js";
3
4
  //#region src/agent/skills/marketplace/adapters/store/adapter.ts
4
5
  const storeMarketplaceAdapter = {
5
6
  id: "store",
@@ -15,9 +16,17 @@ const storeMarketplaceAdapter = {
15
16
  };
16
17
  },
17
18
  async getPackageDetail(config, packageName) {
19
+ const detail = await fetchMarketplacePackageDetail(resolveSkillsStoreBaseUrl(config), packageName);
20
+ const readme = detail.readme?.trim();
21
+ if (!readme) throw new Error(`Store skill package [${packageName}] did not include readme`);
18
22
  return {
19
- ...await fetchMarketplacePackageDetail(resolveSkillsStoreBaseUrl(config), packageName),
20
- provider: "store"
23
+ ...detail,
24
+ readme,
25
+ provider: "store",
26
+ skillDocPreview: buildSkillMarkdownPreviewFromRaw(readme, {
27
+ name: detail.name,
28
+ description: detail.description
29
+ })
21
30
  };
22
31
  },
23
32
  async downloadPackage(config, packageName, version) {