@ytinnovation/harness-core 0.0.0

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 (397) hide show
  1. package/README.md +17 -0
  2. package/dist/assets/fetch-published-by-name.d.ts +16 -0
  3. package/dist/assets/fetch-published-by-name.d.ts.map +1 -0
  4. package/dist/assets/fetch-published-by-name.js +40 -0
  5. package/dist/assets/fetch-published-by-name.js.map +1 -0
  6. package/dist/assets/install-content.d.ts +7 -0
  7. package/dist/assets/install-content.d.ts.map +1 -0
  8. package/dist/assets/install-content.js +24 -0
  9. package/dist/assets/install-content.js.map +1 -0
  10. package/dist/assets/install-from.d.ts +6 -0
  11. package/dist/assets/install-from.d.ts.map +1 -0
  12. package/dist/assets/install-from.js +13 -0
  13. package/dist/assets/install-from.js.map +1 -0
  14. package/dist/assets/install.d.ts +36 -0
  15. package/dist/assets/install.d.ts.map +1 -0
  16. package/dist/assets/install.js +199 -0
  17. package/dist/assets/install.js.map +1 -0
  18. package/dist/assets/mcp-config-format.d.ts +11 -0
  19. package/dist/assets/mcp-config-format.d.ts.map +1 -0
  20. package/dist/assets/mcp-config-format.js +101 -0
  21. package/dist/assets/mcp-config-format.js.map +1 -0
  22. package/dist/assets/metadata.d.ts +65 -0
  23. package/dist/assets/metadata.d.ts.map +1 -0
  24. package/dist/assets/metadata.js +164 -0
  25. package/dist/assets/metadata.js.map +1 -0
  26. package/dist/assets/project-manifest.d.ts +80 -0
  27. package/dist/assets/project-manifest.d.ts.map +1 -0
  28. package/dist/assets/project-manifest.js +556 -0
  29. package/dist/assets/project-manifest.js.map +1 -0
  30. package/dist/assets/published-content.d.ts +28 -0
  31. package/dist/assets/published-content.d.ts.map +1 -0
  32. package/dist/assets/published-content.js +137 -0
  33. package/dist/assets/published-content.js.map +1 -0
  34. package/dist/assets/registry-entry.d.ts +9 -0
  35. package/dist/assets/registry-entry.d.ts.map +1 -0
  36. package/dist/assets/registry-entry.js +72 -0
  37. package/dist/assets/registry-entry.js.map +1 -0
  38. package/dist/assets/remote-list.d.ts +15 -0
  39. package/dist/assets/remote-list.d.ts.map +1 -0
  40. package/dist/assets/remote-list.js +36 -0
  41. package/dist/assets/remote-list.js.map +1 -0
  42. package/dist/cli-output/clipboard.d.ts +9 -0
  43. package/dist/cli-output/clipboard.d.ts.map +1 -0
  44. package/dist/cli-output/clipboard.js +56 -0
  45. package/dist/cli-output/clipboard.js.map +1 -0
  46. package/dist/cli-output/renderers.d.ts +99 -0
  47. package/dist/cli-output/renderers.d.ts.map +1 -0
  48. package/dist/cli-output/renderers.js +267 -0
  49. package/dist/cli-output/renderers.js.map +1 -0
  50. package/dist/cloud/enterprise-asset-client.d.ts +32 -0
  51. package/dist/cloud/enterprise-asset-client.d.ts.map +1 -0
  52. package/dist/cloud/enterprise-asset-client.js +179 -0
  53. package/dist/cloud/enterprise-asset-client.js.map +1 -0
  54. package/dist/cloud/enterprise-asset-types.d.ts +74 -0
  55. package/dist/cloud/enterprise-asset-types.d.ts.map +1 -0
  56. package/dist/cloud/enterprise-asset-types.js +2 -0
  57. package/dist/cloud/enterprise-asset-types.js.map +1 -0
  58. package/dist/cloud/harness-service-url.d.ts +3 -0
  59. package/dist/cloud/harness-service-url.d.ts.map +1 -0
  60. package/dist/cloud/harness-service-url.js +13 -0
  61. package/dist/cloud/harness-service-url.js.map +1 -0
  62. package/dist/cloud/rag-client.d.ts +18 -0
  63. package/dist/cloud/rag-client.d.ts.map +1 -0
  64. package/dist/cloud/rag-client.js +57 -0
  65. package/dist/cloud/rag-client.js.map +1 -0
  66. package/dist/cloud/redaction.d.ts +2 -0
  67. package/dist/cloud/redaction.d.ts.map +1 -0
  68. package/dist/cloud/redaction.js +53 -0
  69. package/dist/cloud/redaction.js.map +1 -0
  70. package/dist/cloud/telemetry-client.d.ts +21 -0
  71. package/dist/cloud/telemetry-client.d.ts.map +1 -0
  72. package/dist/cloud/telemetry-client.js +39 -0
  73. package/dist/cloud/telemetry-client.js.map +1 -0
  74. package/dist/contracts/config.d.ts +9 -0
  75. package/dist/contracts/config.d.ts.map +1 -0
  76. package/dist/contracts/config.defaults.d.ts +5 -0
  77. package/dist/contracts/config.defaults.d.ts.map +1 -0
  78. package/dist/contracts/config.defaults.js +5 -0
  79. package/dist/contracts/config.defaults.js.map +1 -0
  80. package/dist/contracts/config.js +5 -0
  81. package/dist/contracts/config.js.map +1 -0
  82. package/dist/contracts/config.loader.d.ts +3 -0
  83. package/dist/contracts/config.loader.d.ts.map +1 -0
  84. package/dist/contracts/config.loader.js +38 -0
  85. package/dist/contracts/config.loader.js.map +1 -0
  86. package/dist/contracts/errors.d.ts +8 -0
  87. package/dist/contracts/errors.d.ts.map +1 -0
  88. package/dist/contracts/errors.js +10 -0
  89. package/dist/contracts/errors.js.map +1 -0
  90. package/dist/cursor-acp-demo/index.d.ts +2 -0
  91. package/dist/cursor-acp-demo/index.d.ts.map +1 -0
  92. package/dist/cursor-acp-demo/index.js +63 -0
  93. package/dist/cursor-acp-demo/index.js.map +1 -0
  94. package/dist/dashboard/command.d.ts +15 -0
  95. package/dist/dashboard/command.d.ts.map +1 -0
  96. package/dist/dashboard/command.js +283 -0
  97. package/dist/dashboard/command.js.map +1 -0
  98. package/dist/dashboard/http-api.d.ts +3 -0
  99. package/dist/dashboard/http-api.d.ts.map +1 -0
  100. package/dist/dashboard/http-api.js +376 -0
  101. package/dist/dashboard/http-api.js.map +1 -0
  102. package/dist/dashboard/telemetry-snapshot.d.ts +11 -0
  103. package/dist/dashboard/telemetry-snapshot.d.ts.map +1 -0
  104. package/dist/dashboard/telemetry-snapshot.js +27 -0
  105. package/dist/dashboard/telemetry-snapshot.js.map +1 -0
  106. package/dist/dashboard-assets/assets/index-BNx5sFKx.css +1 -0
  107. package/dist/dashboard-assets/assets/index-ruRt5sDA.js +40 -0
  108. package/dist/dashboard-assets/index.html +13 -0
  109. package/dist/gateway/auth.d.ts +44 -0
  110. package/dist/gateway/auth.d.ts.map +1 -0
  111. package/dist/gateway/auth.js +2 -0
  112. package/dist/gateway/auth.js.map +1 -0
  113. package/dist/gateway/client.d.ts +65 -0
  114. package/dist/gateway/client.d.ts.map +1 -0
  115. package/dist/gateway/client.js +133 -0
  116. package/dist/gateway/client.js.map +1 -0
  117. package/dist/gateway/command.d.ts +4 -0
  118. package/dist/gateway/command.d.ts.map +1 -0
  119. package/dist/gateway/command.js +213 -0
  120. package/dist/gateway/command.js.map +1 -0
  121. package/dist/gateway/service-http-exchange.d.ts +17 -0
  122. package/dist/gateway/service-http-exchange.d.ts.map +1 -0
  123. package/dist/gateway/service-http-exchange.js +183 -0
  124. package/dist/gateway/service-http-exchange.js.map +1 -0
  125. package/dist/gateway/token-exchange.d.ts +10 -0
  126. package/dist/gateway/token-exchange.d.ts.map +1 -0
  127. package/dist/gateway/token-exchange.js +8 -0
  128. package/dist/gateway/token-exchange.js.map +1 -0
  129. package/dist/index.d.ts +111 -0
  130. package/dist/index.d.ts.map +1 -0
  131. package/dist/index.js +62 -0
  132. package/dist/index.js.map +1 -0
  133. package/dist/init/cloud-asset-client.d.ts +74 -0
  134. package/dist/init/cloud-asset-client.d.ts.map +1 -0
  135. package/dist/init/cloud-asset-client.js +399 -0
  136. package/dist/init/cloud-asset-client.js.map +1 -0
  137. package/dist/init/cloud-auto.d.ts +16 -0
  138. package/dist/init/cloud-auto.d.ts.map +1 -0
  139. package/dist/init/cloud-auto.js +61 -0
  140. package/dist/init/cloud-auto.js.map +1 -0
  141. package/dist/init/command.d.ts +17 -0
  142. package/dist/init/command.d.ts.map +1 -0
  143. package/dist/init/command.js +783 -0
  144. package/dist/init/command.js.map +1 -0
  145. package/dist/init/cursor-adapter.d.ts +24 -0
  146. package/dist/init/cursor-adapter.d.ts.map +1 -0
  147. package/dist/init/cursor-adapter.js +71 -0
  148. package/dist/init/cursor-adapter.js.map +1 -0
  149. package/dist/init/fingerprint.d.ts +6 -0
  150. package/dist/init/fingerprint.d.ts.map +1 -0
  151. package/dist/init/fingerprint.js +157 -0
  152. package/dist/init/fingerprint.js.map +1 -0
  153. package/dist/init/git-identity-catalog.d.ts +17 -0
  154. package/dist/init/git-identity-catalog.d.ts.map +1 -0
  155. package/dist/init/git-identity-catalog.js +48 -0
  156. package/dist/init/git-identity-catalog.js.map +1 -0
  157. package/dist/init/local-fallback-config-packs.d.ts +5 -0
  158. package/dist/init/local-fallback-config-packs.d.ts.map +1 -0
  159. package/dist/init/local-fallback-config-packs.js +6 -0
  160. package/dist/init/local-fallback-config-packs.js.map +1 -0
  161. package/dist/init/manifest-records.d.ts +34 -0
  162. package/dist/init/manifest-records.d.ts.map +1 -0
  163. package/dist/init/manifest-records.js +296 -0
  164. package/dist/init/manifest-records.js.map +1 -0
  165. package/dist/init/matched-init.d.ts +64 -0
  166. package/dist/init/matched-init.d.ts.map +1 -0
  167. package/dist/init/matched-init.js +263 -0
  168. package/dist/init/matched-init.js.map +1 -0
  169. package/dist/init/plan.d.ts +8 -0
  170. package/dist/init/plan.d.ts.map +1 -0
  171. package/dist/init/plan.js +165 -0
  172. package/dist/init/plan.js.map +1 -0
  173. package/dist/init/project-fingerprint-catalog.d.ts +17 -0
  174. package/dist/init/project-fingerprint-catalog.d.ts.map +1 -0
  175. package/dist/init/project-fingerprint-catalog.js +105 -0
  176. package/dist/init/project-fingerprint-catalog.js.map +1 -0
  177. package/dist/init/prompt.d.ts +38 -0
  178. package/dist/init/prompt.d.ts.map +1 -0
  179. package/dist/init/prompt.js +217 -0
  180. package/dist/init/prompt.js.map +1 -0
  181. package/dist/init/questions.d.ts +5 -0
  182. package/dist/init/questions.d.ts.map +1 -0
  183. package/dist/init/questions.js +71 -0
  184. package/dist/init/questions.js.map +1 -0
  185. package/dist/init/template-match.d.ts +10 -0
  186. package/dist/init/template-match.d.ts.map +1 -0
  187. package/dist/init/template-match.js +125 -0
  188. package/dist/init/template-match.js.map +1 -0
  189. package/dist/init/types.d.ts +162 -0
  190. package/dist/init/types.d.ts.map +1 -0
  191. package/dist/init/types.js +2 -0
  192. package/dist/init/types.js.map +1 -0
  193. package/dist/init/write.d.ts +7 -0
  194. package/dist/init/write.d.ts.map +1 -0
  195. package/dist/init/write.js +155 -0
  196. package/dist/init/write.js.map +1 -0
  197. package/dist/install/command.d.ts +25 -0
  198. package/dist/install/command.d.ts.map +1 -0
  199. package/dist/install/command.js +251 -0
  200. package/dist/install/command.js.map +1 -0
  201. package/dist/install/prompt.d.ts +21 -0
  202. package/dist/install/prompt.d.ts.map +1 -0
  203. package/dist/install/prompt.js +60 -0
  204. package/dist/install/prompt.js.map +1 -0
  205. package/dist/kernel/commands/init.d.ts +11 -0
  206. package/dist/kernel/commands/init.d.ts.map +1 -0
  207. package/dist/kernel/commands/init.js +144 -0
  208. package/dist/kernel/commands/init.js.map +1 -0
  209. package/dist/kernel/create.d.ts +3 -0
  210. package/dist/kernel/create.d.ts.map +1 -0
  211. package/dist/kernel/create.js +31 -0
  212. package/dist/kernel/create.js.map +1 -0
  213. package/dist/kernel/router.d.ts +14 -0
  214. package/dist/kernel/router.d.ts.map +1 -0
  215. package/dist/kernel/router.js +73 -0
  216. package/dist/kernel/router.js.map +1 -0
  217. package/dist/kernel/types.d.ts +6 -0
  218. package/dist/kernel/types.d.ts.map +1 -0
  219. package/dist/kernel/types.js +2 -0
  220. package/dist/kernel/types.js.map +1 -0
  221. package/dist/knowledge/command.d.ts +6 -0
  222. package/dist/knowledge/command.d.ts.map +1 -0
  223. package/dist/knowledge/command.js +151 -0
  224. package/dist/knowledge/command.js.map +1 -0
  225. package/dist/knowledge/query.d.ts +23 -0
  226. package/dist/knowledge/query.d.ts.map +1 -0
  227. package/dist/knowledge/query.js +133 -0
  228. package/dist/knowledge/query.js.map +1 -0
  229. package/dist/knowledge/rag.d.ts +74 -0
  230. package/dist/knowledge/rag.d.ts.map +1 -0
  231. package/dist/knowledge/rag.js +55 -0
  232. package/dist/knowledge/rag.js.map +1 -0
  233. package/dist/knowledge/types.d.ts +40 -0
  234. package/dist/knowledge/types.d.ts.map +1 -0
  235. package/dist/knowledge/types.js +13 -0
  236. package/dist/knowledge/types.js.map +1 -0
  237. package/dist/mcp/command.d.ts +19 -0
  238. package/dist/mcp/command.d.ts.map +1 -0
  239. package/dist/mcp/command.js +359 -0
  240. package/dist/mcp/command.js.map +1 -0
  241. package/dist/mcp/server.d.ts +14 -0
  242. package/dist/mcp/server.d.ts.map +1 -0
  243. package/dist/mcp/server.js +44 -0
  244. package/dist/mcp/server.js.map +1 -0
  245. package/dist/mcp/tool-registry.d.ts +38 -0
  246. package/dist/mcp/tool-registry.d.ts.map +1 -0
  247. package/dist/mcp/tool-registry.js +50 -0
  248. package/dist/mcp/tool-registry.js.map +1 -0
  249. package/dist/mcp/tools/add-skill.d.ts +29 -0
  250. package/dist/mcp/tools/add-skill.d.ts.map +1 -0
  251. package/dist/mcp/tools/add-skill.js +184 -0
  252. package/dist/mcp/tools/add-skill.js.map +1 -0
  253. package/dist/mcp/tools/assemble-init-assets.d.ts +26 -0
  254. package/dist/mcp/tools/assemble-init-assets.d.ts.map +1 -0
  255. package/dist/mcp/tools/assemble-init-assets.js +136 -0
  256. package/dist/mcp/tools/assemble-init-assets.js.map +1 -0
  257. package/dist/mcp/tools/query-knowledge.d.ts +28 -0
  258. package/dist/mcp/tools/query-knowledge.d.ts.map +1 -0
  259. package/dist/mcp/tools/query-knowledge.js +92 -0
  260. package/dist/mcp/tools/query-knowledge.js.map +1 -0
  261. package/dist/mcp/tools/read-instructions.d.ts +14 -0
  262. package/dist/mcp/tools/read-instructions.d.ts.map +1 -0
  263. package/dist/mcp/tools/read-instructions.js +81 -0
  264. package/dist/mcp/tools/read-instructions.js.map +1 -0
  265. package/dist/mcp/tools/sync-spec.d.ts +17 -0
  266. package/dist/mcp/tools/sync-spec.d.ts.map +1 -0
  267. package/dist/mcp/tools/sync-spec.js +80 -0
  268. package/dist/mcp/tools/sync-spec.js.map +1 -0
  269. package/dist/mcp/tools/update-rule.d.ts +49 -0
  270. package/dist/mcp/tools/update-rule.d.ts.map +1 -0
  271. package/dist/mcp/tools/update-rule.js +188 -0
  272. package/dist/mcp/tools/update-rule.js.map +1 -0
  273. package/dist/mcp/types.d.ts +21 -0
  274. package/dist/mcp/types.d.ts.map +1 -0
  275. package/dist/mcp/types.js +8 -0
  276. package/dist/mcp/types.js.map +1 -0
  277. package/dist/prompt/command.d.ts +10 -0
  278. package/dist/prompt/command.d.ts.map +1 -0
  279. package/dist/prompt/command.js +260 -0
  280. package/dist/prompt/command.js.map +1 -0
  281. package/dist/rule/command.d.ts +10 -0
  282. package/dist/rule/command.d.ts.map +1 -0
  283. package/dist/rule/command.js +120 -0
  284. package/dist/rule/command.js.map +1 -0
  285. package/dist/skills/command.d.ts +23 -0
  286. package/dist/skills/command.d.ts.map +1 -0
  287. package/dist/skills/command.js +713 -0
  288. package/dist/skills/command.js.map +1 -0
  289. package/dist/skills/default-internal-skill-provider.d.ts +4 -0
  290. package/dist/skills/default-internal-skill-provider.d.ts.map +1 -0
  291. package/dist/skills/default-internal-skill-provider.js +23 -0
  292. package/dist/skills/default-internal-skill-provider.js.map +1 -0
  293. package/dist/skills/gitlab-skill-publish-client.d.ts +13 -0
  294. package/dist/skills/gitlab-skill-publish-client.d.ts.map +1 -0
  295. package/dist/skills/gitlab-skill-publish-client.js +255 -0
  296. package/dist/skills/gitlab-skill-publish-client.js.map +1 -0
  297. package/dist/skills/install.d.ts +23 -0
  298. package/dist/skills/install.d.ts.map +1 -0
  299. package/dist/skills/install.js +143 -0
  300. package/dist/skills/install.js.map +1 -0
  301. package/dist/skills/list-scan.d.ts +29 -0
  302. package/dist/skills/list-scan.d.ts.map +1 -0
  303. package/dist/skills/list-scan.js +230 -0
  304. package/dist/skills/list-scan.js.map +1 -0
  305. package/dist/skills/metadata.d.ts +5 -0
  306. package/dist/skills/metadata.d.ts.map +1 -0
  307. package/dist/skills/metadata.js +44 -0
  308. package/dist/skills/metadata.js.map +1 -0
  309. package/dist/skills/providers/harness-service.d.ts +11 -0
  310. package/dist/skills/providers/harness-service.d.ts.map +1 -0
  311. package/dist/skills/providers/harness-service.js +111 -0
  312. package/dist/skills/providers/harness-service.js.map +1 -0
  313. package/dist/skills/providers/stub.d.ts +4 -0
  314. package/dist/skills/providers/stub.d.ts.map +1 -0
  315. package/dist/skills/providers/stub.js +18 -0
  316. package/dist/skills/providers/stub.js.map +1 -0
  317. package/dist/skills/publish.d.ts +35 -0
  318. package/dist/skills/publish.d.ts.map +1 -0
  319. package/dist/skills/publish.js +115 -0
  320. package/dist/skills/publish.js.map +1 -0
  321. package/dist/skills/registry.d.ts +24 -0
  322. package/dist/skills/registry.d.ts.map +1 -0
  323. package/dist/skills/registry.js +124 -0
  324. package/dist/skills/registry.js.map +1 -0
  325. package/dist/skills/remove.d.ts +14 -0
  326. package/dist/skills/remove.d.ts.map +1 -0
  327. package/dist/skills/remove.js +44 -0
  328. package/dist/skills/remove.js.map +1 -0
  329. package/dist/skills/search.d.ts +9 -0
  330. package/dist/skills/search.d.ts.map +1 -0
  331. package/dist/skills/search.js +65 -0
  332. package/dist/skills/search.js.map +1 -0
  333. package/dist/skills/skill-markdown-manifest.d.ts +6 -0
  334. package/dist/skills/skill-markdown-manifest.d.ts.map +1 -0
  335. package/dist/skills/skill-markdown-manifest.js +57 -0
  336. package/dist/skills/skill-markdown-manifest.js.map +1 -0
  337. package/dist/skills/types.d.ts +138 -0
  338. package/dist/skills/types.d.ts.map +1 -0
  339. package/dist/skills/types.js +2 -0
  340. package/dist/skills/types.js.map +1 -0
  341. package/dist/skills/update.d.ts +11 -0
  342. package/dist/skills/update.d.ts.map +1 -0
  343. package/dist/skills/update.js +55 -0
  344. package/dist/skills/update.js.map +1 -0
  345. package/dist/spec/command.d.ts +11 -0
  346. package/dist/spec/command.d.ts.map +1 -0
  347. package/dist/spec/command.js +201 -0
  348. package/dist/spec/command.js.map +1 -0
  349. package/dist/telemetry/reporter.d.ts +14 -0
  350. package/dist/telemetry/reporter.d.ts.map +1 -0
  351. package/dist/telemetry/reporter.js +31 -0
  352. package/dist/telemetry/reporter.js.map +1 -0
  353. package/dist/telemetry/sink.d.ts +7 -0
  354. package/dist/telemetry/sink.d.ts.map +1 -0
  355. package/dist/telemetry/sink.js +309 -0
  356. package/dist/telemetry/sink.js.map +1 -0
  357. package/dist/telemetry/types.d.ts +48 -0
  358. package/dist/telemetry/types.d.ts.map +1 -0
  359. package/dist/telemetry/types.js +2 -0
  360. package/dist/telemetry/types.js.map +1 -0
  361. package/dist/update/apply.d.ts +11 -0
  362. package/dist/update/apply.d.ts.map +1 -0
  363. package/dist/update/apply.js +94 -0
  364. package/dist/update/apply.js.map +1 -0
  365. package/dist/update/command.d.ts +43 -0
  366. package/dist/update/command.d.ts.map +1 -0
  367. package/dist/update/command.js +524 -0
  368. package/dist/update/command.js.map +1 -0
  369. package/dist/update/config-pack-sync.d.ts +11 -0
  370. package/dist/update/config-pack-sync.d.ts.map +1 -0
  371. package/dist/update/config-pack-sync.js +88 -0
  372. package/dist/update/config-pack-sync.js.map +1 -0
  373. package/dist/update/enterprise-update-provider.d.ts +8 -0
  374. package/dist/update/enterprise-update-provider.d.ts.map +1 -0
  375. package/dist/update/enterprise-update-provider.js +76 -0
  376. package/dist/update/enterprise-update-provider.js.map +1 -0
  377. package/dist/update/manifest-source.d.ts +33 -0
  378. package/dist/update/manifest-source.d.ts.map +1 -0
  379. package/dist/update/manifest-source.js +111 -0
  380. package/dist/update/manifest-source.js.map +1 -0
  381. package/dist/update/plan-utils.d.ts +5 -0
  382. package/dist/update/plan-utils.d.ts.map +1 -0
  383. package/dist/update/plan-utils.js +13 -0
  384. package/dist/update/plan-utils.js.map +1 -0
  385. package/dist/update/prompt.d.ts +19 -0
  386. package/dist/update/prompt.d.ts.map +1 -0
  387. package/dist/update/prompt.js +72 -0
  388. package/dist/update/prompt.js.map +1 -0
  389. package/dist/update/resolve-action.d.ts +7 -0
  390. package/dist/update/resolve-action.d.ts.map +1 -0
  391. package/dist/update/resolve-action.js +14 -0
  392. package/dist/update/resolve-action.js.map +1 -0
  393. package/dist/update/types.d.ts +33 -0
  394. package/dist/update/types.d.ts.map +1 -0
  395. package/dist/update/types.js +2 -0
  396. package/dist/update/types.js.map +1 -0
  397. package/package.json +42 -0
@@ -0,0 +1,713 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { homedir } from 'node:os';
3
+ import { dirname, isAbsolute, join } from 'node:path';
4
+ import { HarnessError } from '../contracts/errors.js';
5
+ import { prepareSkillInstallByName, prepareSkillInstallByUrl, resolveSkillPackageFromUrl } from './install.js';
6
+ import { createGitLabSkillPublishBackend, prepareSkillPublish, resolveLocalSkillGitIdentity } from './publish.js';
7
+ import { createGitLabRestSkillPublishClient } from './gitlab-skill-publish-client.js';
8
+ import { createDefaultInternalSkillProvider } from './default-internal-skill-provider.js';
9
+ import { createStubExternalProvider } from './providers/stub.js';
10
+ import { parseEnterpriseAssetIdFromSourceRef } from './providers/harness-service.js';
11
+ import { createFileSkillRegistry } from './registry.js';
12
+ import { scanWorkspaceSkills } from './list-scan.js';
13
+ import { searchSkills } from './search.js';
14
+ import { createHarnessTelemetryEvent, reportHarnessTelemetryEvents } from '../cloud/telemetry-client.js';
15
+ import { listRemoteTopAssets } from '../assets/remote-list.js';
16
+ import { parseInstallTargets, resolveSkillRegistryPath, resolveSkillTargetDir } from '../assets/install.js';
17
+ import { resolveProjectManifestPath } from '../assets/project-manifest.js';
18
+ import { renderDebugBoundary, renderErrorBlock, renderJson, renderRemoteAssetList, renderSearchResults, renderSkillLocalList, renderSuccessBlock, renderWarningBlock, } from '../cli-output/renderers.js';
19
+ const DEFAULT_REGISTRY_RELATIVE_PATH = ['.harness', 'registry.json'];
20
+ function resolveRegistryPath(options) {
21
+ if (options.registryPath) {
22
+ return options.registryPath;
23
+ }
24
+ return join(options.homeDir ?? homedir(), ...DEFAULT_REGISTRY_RELATIVE_PATH);
25
+ }
26
+ function resolveHomeRegistryPath(options) {
27
+ return join(options.homeDir ?? homedir(), ...DEFAULT_REGISTRY_RELATIVE_PATH);
28
+ }
29
+ function renderSkillHelp(programName = 'harness') {
30
+ return [
31
+ '管理 Harness Skill 资产。',
32
+ '',
33
+ '用法:',
34
+ ` ${programName} skill <subcommand> [args]`,
35
+ '',
36
+ '子命令:',
37
+ ' list [--remote] [--json] 查看本地或远程热门 Skills。',
38
+ ' search <query> [--json] 搜索可安装的 Skill。',
39
+ ' install <name> [--global] [--agents] [--target cursor,agents] 按名称安装 Skill。',
40
+ ' install --url <url> [--agents] [--target cursor,agents] 按 URL 安装 Skill。',
41
+ ' remove <name> 移除已安装 Skill。',
42
+ ' publish --manifest <path> [--repo <path>] [--target-dir <dir>] [--branch <name>] [--target-branch <name>] [--message <message>]',
43
+ ' -h, --help 查看帮助。',
44
+ ].join('\n');
45
+ }
46
+ function resolveInstallTargetDir(options) {
47
+ const workspaceRoot = options.workspaceRoot ?? process.cwd();
48
+ if (!options.installTargetDir) {
49
+ return join(workspaceRoot, '.cursor', 'skills');
50
+ }
51
+ if (isAbsolute(options.installTargetDir)) {
52
+ return options.installTargetDir;
53
+ }
54
+ return join(workspaceRoot, options.installTargetDir);
55
+ }
56
+ function toInstallTargetPath(targetDir, skillName) {
57
+ const normalizedSkillName = skillName.trim();
58
+ return join(targetDir, normalizedSkillName, 'SKILL.md');
59
+ }
60
+ async function planSkillInstall(skillName, targetPath, nextContent) {
61
+ try {
62
+ const existingContent = await readFile(targetPath, 'utf8');
63
+ if (existingContent === nextContent) {
64
+ return {
65
+ action: 'skip',
66
+ skillName,
67
+ targetPath,
68
+ reason: 'Existing file content is identical to the incoming skill package.',
69
+ };
70
+ }
71
+ return {
72
+ action: 'update',
73
+ skillName,
74
+ targetPath,
75
+ reason: 'Target skill file already exists with different local content; review before update.',
76
+ };
77
+ }
78
+ catch (error) {
79
+ if (error.code === 'ENOENT') {
80
+ return {
81
+ action: 'create',
82
+ skillName,
83
+ targetPath,
84
+ reason: 'Target skill file does not exist yet.',
85
+ };
86
+ }
87
+ throw error;
88
+ }
89
+ }
90
+ function renderSkillPublishUsage() {
91
+ return [
92
+ 'Usage: harness skill publish --manifest <path> [--repo <path>] [--target-dir <dir>] [--branch <name>] [--target-branch <name>] [--message <message>]',
93
+ 'Default: when HARNESS_SERVICE_URL is configured, upload the Skill to harness-service for Admin Console review/governance.',
94
+ 'Legacy GitLab example: harness skill publish --manifest ./skills/review-helper/manifest.json --repo git@gitlab.example.com:harness/skills.git --target-dir skills/review-helper --target-branch main',
95
+ 'Config fallback: HARNESS_SKILL_PUBLISH_REPO, HARNESS_SKILL_PUBLISH_TARGET_DIR, HARNESS_SKILL_PUBLISH_TARGET_BRANCH',
96
+ 'GitLab publish: set HARNESS_SKILL_PUBLISH_TOKEN or HARNESS_GITLAB_TOKEN (project access token, api scope); optional HARNESS_GITLAB_API_BASE_URL for self-hosted (must include /api/v4). Without a token, publish runs in offline mock mode for tests only.',
97
+ ].join('\n');
98
+ }
99
+ function resolveHarnessServiceBaseUrl() {
100
+ const baseUrl = process.env.HARNESS_SERVICE_URL?.trim() || process.env.HARNESS_CLOUD_BASE_URL?.trim();
101
+ return baseUrl ? baseUrl.replace(/\/+$/, '') : null;
102
+ }
103
+ async function publishSkillToHarnessService(args) {
104
+ const packageRoot = dirname(args.manifestPath);
105
+ const entrypointPath = join(packageRoot, ...args.manifest.entrypoint.replace(/\\/g, '/').replace(/^\.\//, '').split('/'));
106
+ const [manifestRaw, entryRaw] = await Promise.all([
107
+ readFile(args.manifestPath, 'utf8'),
108
+ readFile(entrypointPath, 'utf8'),
109
+ ]);
110
+ const response = await fetch(`${args.baseUrl}/assets`, {
111
+ method: 'POST',
112
+ headers: { 'content-type': 'application/json' },
113
+ body: JSON.stringify({
114
+ type: 'skill',
115
+ name: args.manifest.name,
116
+ version: args.manifest.version,
117
+ content: [
118
+ '# Skill Package',
119
+ '',
120
+ '## manifest.json',
121
+ '```json',
122
+ manifestRaw.trim(),
123
+ '```',
124
+ '',
125
+ `## ${args.manifest.entrypoint}`,
126
+ '```markdown',
127
+ entryRaw.trim(),
128
+ '```',
129
+ ].join('\n'),
130
+ description: args.manifest.description,
131
+ tags: args.manifest.tags,
132
+ createdBy: `${args.authorName} <${args.authorEmail}>`,
133
+ metadata: {
134
+ source: 'cli-skill-publish',
135
+ targetPath: `.cursor/skills/${args.manifest.name}/SKILL.md`,
136
+ manifest: args.manifest,
137
+ },
138
+ }),
139
+ });
140
+ const text = await response.text();
141
+ const body = text ? JSON.parse(text) : null;
142
+ if (!response.ok) {
143
+ throw new HarnessError('SKILL_PUBLISH_SERVICE_FAILED', `harness-service skill publish failed with HTTP ${response.status}: ${text || response.statusText}`);
144
+ }
145
+ return body;
146
+ }
147
+ function resolveDefaultSkillPublishBackend() {
148
+ const token = process.env.HARNESS_SKILL_PUBLISH_TOKEN?.trim() || process.env.HARNESS_GITLAB_TOKEN?.trim();
149
+ if (token) {
150
+ return createGitLabSkillPublishBackend({
151
+ client: createGitLabRestSkillPublishClient({ token }),
152
+ });
153
+ }
154
+ return {
155
+ prepare: async (request) => ({
156
+ repositoryPath: request.repositoryPath,
157
+ mergeRequest: {
158
+ id: `mock-${request.manifest.name}-${request.manifest.version}`,
159
+ title: request.mergeRequestTitle,
160
+ description: request.mergeRequestDescription,
161
+ branchName: request.branchName,
162
+ targetBranch: request.targetBranch,
163
+ },
164
+ }),
165
+ };
166
+ }
167
+ function toOutputValue(value) {
168
+ const normalized = value?.trim();
169
+ return normalized ? normalized : 'unknown';
170
+ }
171
+ function toInstallOutputMetadata(record) {
172
+ return {
173
+ source: toOutputValue(record.source),
174
+ sourceRef: toOutputValue(record.sourceRef),
175
+ revision: toOutputValue(record.revision),
176
+ version: toOutputValue(record.manifest?.version),
177
+ };
178
+ }
179
+ function normalizeSkillManifest(candidate) {
180
+ if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) {
181
+ return null;
182
+ }
183
+ const value = candidate;
184
+ const name = typeof value.name === 'string' ? value.name.trim() : '';
185
+ const version = typeof value.version === 'string' ? value.version.trim() : '';
186
+ const description = typeof value.description === 'string' ? value.description.trim() : '';
187
+ const entrypoint = typeof value.entrypoint === 'string' ? value.entrypoint.trim() : '';
188
+ const tags = Array.isArray(value.tags) ? value.tags.filter((tag) => typeof tag === 'string') : [];
189
+ if (!name || !version || !description || !entrypoint) {
190
+ return null;
191
+ }
192
+ const manifest = {
193
+ name,
194
+ version,
195
+ description,
196
+ entrypoint,
197
+ tags,
198
+ };
199
+ if (typeof value.author === 'string' && value.author.trim()) {
200
+ manifest.author = value.author.trim();
201
+ }
202
+ if (typeof value.repository === 'string' && value.repository.trim()) {
203
+ manifest.repository = value.repository.trim();
204
+ }
205
+ if (value.managedBy === 'harness') {
206
+ manifest.managedBy = 'harness';
207
+ }
208
+ return manifest;
209
+ }
210
+ async function readPublishManifest(manifestPath) {
211
+ let raw;
212
+ try {
213
+ raw = await readFile(manifestPath, 'utf8');
214
+ }
215
+ catch (error) {
216
+ if (error.code === 'ENOENT') {
217
+ throw new Error(`Missing skill manifest at ${manifestPath}.`);
218
+ }
219
+ throw error;
220
+ }
221
+ let parsed;
222
+ try {
223
+ parsed = JSON.parse(raw);
224
+ }
225
+ catch {
226
+ throw new Error(`Invalid JSON in skill manifest: ${manifestPath}.`);
227
+ }
228
+ const manifest = normalizeSkillManifest(parsed);
229
+ if (!manifest) {
230
+ throw new Error(`Invalid skill manifest shape at ${manifestPath}.`);
231
+ }
232
+ return manifest;
233
+ }
234
+ function parseSkillPublishArgs(args) {
235
+ const out = {
236
+ manifestPath: '',
237
+ };
238
+ for (let i = 0; i < args.length; i += 1) {
239
+ const token = args[i];
240
+ const value = args[i + 1];
241
+ if (!token?.startsWith('--') || !value) {
242
+ return null;
243
+ }
244
+ if (token === '--manifest') {
245
+ out.manifestPath = value;
246
+ }
247
+ else if (token === '--repo') {
248
+ out.repositoryPath = value;
249
+ }
250
+ else if (token === '--target-dir') {
251
+ out.targetDirectory = value;
252
+ }
253
+ else if (token === '--branch') {
254
+ out.branchName = value;
255
+ }
256
+ else if (token === '--target-branch') {
257
+ out.targetBranch = value;
258
+ }
259
+ else if (token === '--message') {
260
+ out.commitMessage = value;
261
+ }
262
+ else {
263
+ return null;
264
+ }
265
+ i += 1;
266
+ }
267
+ if (!out.manifestPath) {
268
+ return null;
269
+ }
270
+ return out;
271
+ }
272
+ export async function runSkillCommand(args, options = {}) {
273
+ const startedAt = Date.now();
274
+ const workspaceRoot = options.workspaceRoot ?? process.cwd();
275
+ const registryPath = options.registryPath ?? resolveProjectManifestPath(workspaceRoot);
276
+ const registry = createFileSkillRegistry(registryPath);
277
+ const internalProvider = options.internalProvider ?? createDefaultInternalSkillProvider();
278
+ const externalProvider = options.externalProvider ?? createStubExternalProvider();
279
+ try {
280
+ if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
281
+ console.log(renderSkillHelp());
282
+ return 0;
283
+ }
284
+ const json = args.includes('--json');
285
+ const commandArgs = args.filter((arg) => arg !== '--json');
286
+ const subcommand = commandArgs[0];
287
+ if (subcommand === 'list') {
288
+ const listArgs = commandArgs.slice(1);
289
+ if (listArgs.some((arg) => arg !== '--remote')) {
290
+ console.error(renderErrorBlock({
291
+ title: 'Skill 列表参数无效',
292
+ message: 'skill list 仅支持 --remote 和 --json。',
293
+ code: 'SKILL_INVALID_ARGS',
294
+ suggestions: ['运行 harness skill list 或 harness skill list --remote。'],
295
+ }));
296
+ return 1;
297
+ }
298
+ const isRemote = listArgs.includes('--remote');
299
+ if (isRemote) {
300
+ try {
301
+ const assets = await listRemoteTopAssets({ type: 'skill' });
302
+ console.log(json ? renderJson({ assets }) : renderRemoteAssetList('远程热门 Skills', assets));
303
+ return 0;
304
+ }
305
+ catch (error) {
306
+ if (error instanceof HarnessError) {
307
+ console.error(renderErrorBlock({
308
+ title: '远程 Skill 列表读取失败',
309
+ message: error.message,
310
+ code: error.code,
311
+ suggestions: ['检查 HARNESS_SERVICE_URL / HARNESS_CLOUD_BASE_URL 是否已配置并可访问。'],
312
+ }));
313
+ return 1;
314
+ }
315
+ const message = error instanceof Error ? error.message : String(error);
316
+ console.error(renderErrorBlock({ title: '远程 Skill 列表读取失败', message }));
317
+ return 1;
318
+ }
319
+ }
320
+ const scan = await scanWorkspaceSkills(workspaceRoot);
321
+ const registryInstalled = await registry.list();
322
+ const payload = {
323
+ workspaceRoot,
324
+ scannedRoots: ['.agents', '.cursor'],
325
+ maintained: scan.maintained,
326
+ other: scan.other,
327
+ registry: registryInstalled,
328
+ };
329
+ console.log(json ? renderJson(payload) : renderSkillLocalList(payload));
330
+ return 0;
331
+ }
332
+ if (subcommand === 'search') {
333
+ const query = commandArgs.slice(1).join(' ').trim();
334
+ if (!query) {
335
+ console.error(renderErrorBlock({
336
+ title: '缺少搜索关键词',
337
+ message: '请提供要搜索的 Skill 名称、标签或描述关键词。',
338
+ code: 'SKILL_INVALID_ARGS',
339
+ suggestions: ['示例:harness skill search code review'],
340
+ }));
341
+ return 1;
342
+ }
343
+ const results = await searchSkills(query, {
344
+ internalProvider,
345
+ externalProvider,
346
+ maxResults: options.searchMaxResults,
347
+ vettingProvider: options.externalVettingProvider,
348
+ });
349
+ void reportHarnessTelemetryEvents([
350
+ createHarnessTelemetryEvent('asset.used', {
351
+ source: 'cli',
352
+ command: 'skill search',
353
+ success: true,
354
+ payload: { query, resultCount: results.length },
355
+ }),
356
+ ], { workspaceRoot: options.workspaceRoot ?? process.cwd() });
357
+ console.log(json ? renderJson({ query, results }) : renderSearchResults({ query, results }));
358
+ return 0;
359
+ }
360
+ if (subcommand === 'install') {
361
+ const globalInstall = commandArgs.includes('--global');
362
+ const { targets, rest: installArgs } = parseInstallTargets(commandArgs.slice(1).filter((arg) => arg !== '--global'));
363
+ const activeRegistryPath = resolveSkillRegistryPath({
364
+ workspaceRoot,
365
+ homeRegistryPath: resolveHomeRegistryPath(options),
366
+ explicitRegistryPath: options.registryPath,
367
+ global: globalInstall,
368
+ });
369
+ const activeRegistry = createFileSkillRegistry(activeRegistryPath);
370
+ const isInstallByUrl = installArgs.length === 2 && installArgs[0] === '--url';
371
+ const isInstallByName = installArgs.length === 1 && installArgs[0] !== '--url';
372
+ if (!isInstallByUrl && !isInstallByName) {
373
+ console.error(renderErrorBlock({
374
+ title: 'Skill 安装参数无效',
375
+ message: '请二选一:按名称安装,或通过 --url 安装。',
376
+ code: 'SKILL_INVALID_ARGS',
377
+ suggestions: ['harness skill install review-helper', 'harness skill install --url https://example.com/skills/review-helper.md'],
378
+ }));
379
+ return 1;
380
+ }
381
+ if (isInstallByUrl) {
382
+ const urlValue = installArgs[1];
383
+ if (!urlValue) {
384
+ console.error(renderErrorBlock({
385
+ title: '缺少 Skill URL',
386
+ message: '使用 --url 安装时必须提供 http/https URL。',
387
+ code: 'SKILL_INVALID_ARGS',
388
+ }));
389
+ return 1;
390
+ }
391
+ const resolveByUrl = options.resolveByUrl ??
392
+ resolveSkillPackageFromUrl;
393
+ try {
394
+ const prepared = await prepareSkillInstallByUrl(urlValue, {
395
+ resolveByUrl,
396
+ now: options.now,
397
+ });
398
+ const targetDir = resolveSkillTargetDir({
399
+ workspaceRoot,
400
+ homeDir: options.homeDir ?? homedir(),
401
+ installTargetDir: options.installTargetDir,
402
+ target: targets[0] ?? 'cursor',
403
+ global: false,
404
+ });
405
+ const targetPath = toInstallTargetPath(targetDir, prepared.installedRecord.skillName);
406
+ const skillPlan = await planSkillInstall(prepared.installedRecord.skillName, targetPath, prepared.packageContent);
407
+ if (skillPlan.action === 'update') {
408
+ const installMetadata = toInstallOutputMetadata(prepared.installedRecord);
409
+ const payload = {
410
+ status: 'planned',
411
+ action: skillPlan.action,
412
+ skillName: prepared.installedRecord.skillName,
413
+ sourceUrl: prepared.installedRecord.sourceRef,
414
+ source: installMetadata.source,
415
+ sourceRef: installMetadata.sourceRef,
416
+ revision: prepared.installedRecord.revision,
417
+ revisionLabel: installMetadata.revision,
418
+ version: prepared.installedRecord.manifest.version,
419
+ versionLabel: installMetadata.version,
420
+ hash: prepared.installedRecord.assetMetadata.hash,
421
+ installPath: skillPlan.targetPath,
422
+ reason: skillPlan.reason,
423
+ };
424
+ console.log(json ? renderJson(payload) : renderWarningBlock('Skill 更新需要人工确认', [
425
+ ['名称', prepared.installedRecord.skillName],
426
+ ['来源', installMetadata.sourceRef],
427
+ ['版本', installMetadata.version],
428
+ ['安装路径', skillPlan.targetPath],
429
+ ['原因', skillPlan.reason],
430
+ ], ['目标文件已有本地修改,本次仅生成计划,不会覆盖文件。']));
431
+ return 0;
432
+ }
433
+ if (skillPlan.action === 'create') {
434
+ await mkdir(dirname(skillPlan.targetPath), { recursive: true });
435
+ await writeFile(skillPlan.targetPath, prepared.packageContent, 'utf8');
436
+ }
437
+ const installedRecord = {
438
+ ...prepared.installedRecord,
439
+ installPath: skillPlan.targetPath,
440
+ };
441
+ const installMetadata = toInstallOutputMetadata(installedRecord);
442
+ const payload = {
443
+ status: 'installed',
444
+ action: skillPlan.action,
445
+ skillName: installedRecord.skillName,
446
+ sourceUrl: installedRecord.sourceRef,
447
+ source: installMetadata.source,
448
+ sourceRef: installMetadata.sourceRef,
449
+ revision: installMetadata.revision,
450
+ version: installMetadata.version,
451
+ hash: installedRecord.assetMetadata.hash,
452
+ installPath: installedRecord.installPath,
453
+ reason: skillPlan.reason,
454
+ };
455
+ console.log(json ? renderJson(payload) : renderSuccessBlock('Skill 安装完成', [
456
+ ['动作', skillPlan.action === 'create' ? '创建' : '跳过'],
457
+ ['名称', installedRecord.skillName],
458
+ ['来源', installMetadata.sourceRef],
459
+ ['版本', installMetadata.version],
460
+ ['Revision', installMetadata.revision],
461
+ ['安装路径', installedRecord.installPath],
462
+ ]));
463
+ void reportHarnessTelemetryEvents([
464
+ createHarnessTelemetryEvent('asset.installed', {
465
+ source: 'cli',
466
+ command: 'skill install --url',
467
+ success: true,
468
+ payload: {
469
+ skillName: installedRecord.skillName,
470
+ sourceRef: installedRecord.sourceRef,
471
+ installPath: installedRecord.installPath,
472
+ },
473
+ }),
474
+ ], { workspaceRoot: options.workspaceRoot ?? process.cwd() });
475
+ return 0;
476
+ }
477
+ catch (error) {
478
+ const message = error instanceof Error ? error.message : String(error);
479
+ console.error(renderErrorBlock({ title: 'Skill 安装失败', message }));
480
+ return 1;
481
+ }
482
+ }
483
+ const skillName = installArgs[0]?.trim();
484
+ if (!skillName) {
485
+ console.error(renderErrorBlock({
486
+ title: '缺少 Skill 名称',
487
+ message: '按名称安装时必须提供 Skill 名称。',
488
+ code: 'SKILL_INVALID_ARGS',
489
+ }));
490
+ return 1;
491
+ }
492
+ try {
493
+ const prepared = await prepareSkillInstallByName(skillName, {
494
+ provider: internalProvider,
495
+ now: options.now,
496
+ });
497
+ const installedRecord = prepared.installedRecord;
498
+ const targetDir = resolveSkillTargetDir({
499
+ workspaceRoot,
500
+ homeDir: options.homeDir ?? homedir(),
501
+ installTargetDir: options.installTargetDir,
502
+ target: targets[0] ?? 'cursor',
503
+ global: globalInstall,
504
+ });
505
+ const targetPath = toInstallTargetPath(targetDir, installedRecord.skillName);
506
+ const skillPlan = await planSkillInstall(installedRecord.skillName, targetPath, prepared.packageContent);
507
+ if (skillPlan.action === 'create') {
508
+ await mkdir(dirname(skillPlan.targetPath), { recursive: true });
509
+ await writeFile(skillPlan.targetPath, prepared.packageContent, 'utf8');
510
+ }
511
+ const recordWithPath = {
512
+ ...installedRecord,
513
+ installPath: skillPlan.targetPath,
514
+ };
515
+ await activeRegistry.add(recordWithPath);
516
+ const assetId = parseEnterpriseAssetIdFromSourceRef(installedRecord.sourceRef);
517
+ void reportHarnessTelemetryEvents([
518
+ createHarnessTelemetryEvent('asset.installed', {
519
+ source: 'cli',
520
+ command: 'skill install',
521
+ success: true,
522
+ asset_id: assetId ?? undefined,
523
+ payload: {
524
+ skillName: installedRecord.skillName,
525
+ sourceRef: installedRecord.sourceRef,
526
+ },
527
+ }),
528
+ ], { workspaceRoot: options.workspaceRoot ?? process.cwd() });
529
+ const installMetadata = toInstallOutputMetadata(recordWithPath);
530
+ const payload = {
531
+ status: 'installed',
532
+ skillName: recordWithPath.skillName,
533
+ source: installMetadata.source,
534
+ sourceRef: installMetadata.sourceRef,
535
+ revision: installMetadata.revision,
536
+ version: installMetadata.version,
537
+ installPath: recordWithPath.installPath,
538
+ };
539
+ console.log(json ? renderJson(payload) : renderSuccessBlock('Skill 安装完成', [
540
+ ['名称', recordWithPath.skillName],
541
+ ['来源', installMetadata.source],
542
+ ['Source Ref', installMetadata.sourceRef],
543
+ ['版本', installMetadata.version],
544
+ ['Revision', installMetadata.revision],
545
+ ['安装路径', recordWithPath.installPath],
546
+ ]));
547
+ return 0;
548
+ }
549
+ catch (error) {
550
+ const message = error instanceof Error ? error.message : String(error);
551
+ console.error(renderErrorBlock({ title: 'Skill 安装失败', message }));
552
+ return 1;
553
+ }
554
+ }
555
+ if (subcommand === 'remove') {
556
+ const skillName = commandArgs[1]?.trim();
557
+ if (!skillName) {
558
+ console.error(renderErrorBlock({
559
+ title: '缺少 Skill 名称',
560
+ message: '移除 Skill 时必须提供名称。',
561
+ code: 'SKILL_INVALID_ARGS',
562
+ }));
563
+ return 1;
564
+ }
565
+ const removed = await registry.remove(skillName);
566
+ if (!removed) {
567
+ console.error(renderErrorBlock({
568
+ title: '未找到 Skill',
569
+ message: `本地注册表中没有找到 ${skillName}。`,
570
+ code: 'SKILL_NOT_FOUND',
571
+ }));
572
+ return 1;
573
+ }
574
+ const payload = { status: 'removed', skillName };
575
+ console.log(json ? renderJson(payload) : renderSuccessBlock('Skill 已移除', [['名称', skillName]]));
576
+ return 0;
577
+ }
578
+ if (subcommand === 'publish') {
579
+ const publishArgs = parseSkillPublishArgs(commandArgs.slice(1));
580
+ if (!publishArgs) {
581
+ console.error(renderErrorBlock({
582
+ title: 'Skill 发布参数无效',
583
+ message: renderSkillPublishUsage(),
584
+ code: 'SKILL_INVALID_ARGS',
585
+ }));
586
+ return 1;
587
+ }
588
+ const backend = options.publishBackend ?? resolveDefaultSkillPublishBackend();
589
+ try {
590
+ const cwdForManifest = options.workspaceRoot ?? process.cwd();
591
+ const resolvedManifestPath = isAbsolute(publishArgs.manifestPath)
592
+ ? publishArgs.manifestPath
593
+ : join(cwdForManifest, publishArgs.manifestPath);
594
+ const manifest = await readPublishManifest(resolvedManifestPath);
595
+ const serviceBaseUrl = resolveHarnessServiceBaseUrl();
596
+ if (serviceBaseUrl && !publishArgs.repositoryPath?.trim()) {
597
+ const gitIdentity = await (options.resolveGitIdentity ?? resolveLocalSkillGitIdentity)(options.workspaceRoot ?? process.cwd());
598
+ if (!gitIdentity.name || !gitIdentity.email) {
599
+ throw new HarnessError('SKILL_PUBLISH_MISSING_GIT_IDENTITY', 'Missing local Git identity. Configure user.name and user.email before publishing a skill.');
600
+ }
601
+ const serviceResult = await publishSkillToHarnessService({
602
+ baseUrl: serviceBaseUrl,
603
+ manifest,
604
+ manifestPath: resolvedManifestPath,
605
+ authorName: gitIdentity.name,
606
+ authorEmail: gitIdentity.email,
607
+ });
608
+ const payload = {
609
+ status: 'uploaded',
610
+ serviceUrl: serviceBaseUrl,
611
+ review: 'admin-console',
612
+ result: serviceResult,
613
+ };
614
+ console.log(json ? renderJson(payload) : renderSuccessBlock('Skill 已上传,等待审核', [
615
+ ['服务地址', serviceBaseUrl],
616
+ ['审核入口', 'Admin Console'],
617
+ ['结果', JSON.stringify(serviceResult)],
618
+ ]));
619
+ return 0;
620
+ }
621
+ const repositoryPath = publishArgs.repositoryPath?.trim() ?? process.env.HARNESS_SKILL_PUBLISH_REPO?.trim();
622
+ if (!repositoryPath) {
623
+ console.error(renderErrorBlock({
624
+ title: '缺少发布目标仓库',
625
+ message: '未配置企业 GitLab 仓库路径。',
626
+ code: 'SKILL_PUBLISH_MISSING_REPOSITORY',
627
+ suggestions: ['传入 --repo <path>,或设置 HARNESS_SKILL_PUBLISH_REPO。'],
628
+ }));
629
+ return 1;
630
+ }
631
+ const targetDirectory = publishArgs.targetDirectory?.trim() ??
632
+ process.env.HARNESS_SKILL_PUBLISH_TARGET_DIR?.trim() ??
633
+ `skills/${manifest.name}`;
634
+ const branchName = publishArgs.branchName?.trim() || `publish/${manifest.name}-${manifest.version}`;
635
+ const targetBranch = publishArgs.targetBranch?.trim() ?? process.env.HARNESS_SKILL_PUBLISH_TARGET_BRANCH?.trim() ?? 'main';
636
+ const commitMessage = publishArgs.commitMessage?.trim() || `Publish ${manifest.name} ${manifest.version}`;
637
+ const prepared = await prepareSkillPublish(manifest, {
638
+ backend,
639
+ repositoryPath,
640
+ targetDirectory,
641
+ branchName,
642
+ targetBranch,
643
+ commitMessage,
644
+ cwd: options.workspaceRoot ?? process.cwd(),
645
+ resolveGitIdentity: options.resolveGitIdentity,
646
+ manifestPath: resolvedManifestPath,
647
+ });
648
+ const payload = {
649
+ status: 'prepared',
650
+ repositoryPath: prepared.repositoryPath,
651
+ targetDirectory,
652
+ branchName: prepared.mergeRequest.branchName,
653
+ targetBranch: prepared.mergeRequest.targetBranch,
654
+ mergeRequest: prepared.mergeRequest,
655
+ };
656
+ console.log(json ? renderJson(payload) : renderSuccessBlock('Skill 发布请求已准备', [
657
+ ['仓库', prepared.repositoryPath],
658
+ ['目标目录', targetDirectory],
659
+ ['分支', prepared.mergeRequest.branchName],
660
+ ['目标分支', prepared.mergeRequest.targetBranch],
661
+ ['Merge Request', prepared.mergeRequest.webUrl ?? prepared.mergeRequest.id],
662
+ ]));
663
+ return 0;
664
+ }
665
+ catch (error) {
666
+ if (error instanceof HarnessError) {
667
+ console.error(renderErrorBlock({ title: 'Skill 发布失败', message: error.message, code: error.code }));
668
+ if (error.code === 'SKILL_PUBLISH_MISSING_GIT_IDENTITY') {
669
+ console.error(renderWarningBlock('需要配置 Git 身份', [], [
670
+ 'git config --local user.name "Your Name"',
671
+ 'git config --local user.email "you@example.com"',
672
+ ]));
673
+ }
674
+ return 1;
675
+ }
676
+ const message = error instanceof Error ? error.message : String(error);
677
+ if (message.includes('Missing local Git identity')) {
678
+ console.error(renderErrorBlock({
679
+ title: 'Skill 发布失败',
680
+ message,
681
+ suggestions: [
682
+ 'git config --local user.name "Your Name"',
683
+ 'git config --local user.email "you@example.com"',
684
+ ],
685
+ }));
686
+ return 1;
687
+ }
688
+ console.error(renderErrorBlock({ title: 'Skill 发布失败', message }));
689
+ return 1;
690
+ }
691
+ }
692
+ console.error(renderErrorBlock({
693
+ title: '未知 Skill 子命令',
694
+ message: `无法识别子命令:${subcommand}`,
695
+ code: 'SKILL_INVALID_ARGS',
696
+ suggestions: ['运行 harness skill --help 查看可用命令。'],
697
+ }));
698
+ return 1;
699
+ }
700
+ finally {
701
+ const durationMs = Date.now() - startedAt;
702
+ const budgetMs = 3_000;
703
+ const debugLine = renderDebugBoundary('skill', durationMs, budgetMs);
704
+ if (debugLine) {
705
+ console.log(debugLine);
706
+ }
707
+ }
708
+ }
709
+ export function registerSkillCommand(router) {
710
+ router.register('skill', runSkillCommand);
711
+ }
712
+ export { renderSkillHelp };
713
+ //# sourceMappingURL=command.js.map