@xagent-ai/cli 1.2.2 → 1.3.1

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 (602) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -38
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
  3. package/.github/release.yml +76 -0
  4. package/.github/workflows/ci.yml +75 -0
  5. package/.github/workflows/release.yml +103 -0
  6. package/.gitmodules +3 -3
  7. package/README.md +326 -280
  8. package/README_CN.md +325 -279
  9. package/dist/agents.d.ts.map +1 -1
  10. package/dist/agents.js +7 -3
  11. package/dist/agents.js.map +1 -1
  12. package/dist/ai-client/factory.d.ts +40 -0
  13. package/dist/ai-client/factory.d.ts.map +1 -0
  14. package/dist/ai-client/factory.js +100 -0
  15. package/dist/ai-client/factory.js.map +1 -0
  16. package/dist/ai-client/index.d.ts +20 -0
  17. package/dist/ai-client/index.d.ts.map +1 -0
  18. package/dist/ai-client/index.js +49 -0
  19. package/dist/ai-client/index.js.map +1 -0
  20. package/dist/ai-client/providers/anthropic.d.ts +57 -0
  21. package/dist/ai-client/providers/anthropic.d.ts.map +1 -0
  22. package/dist/ai-client/providers/anthropic.js +406 -0
  23. package/dist/ai-client/providers/anthropic.js.map +1 -0
  24. package/dist/ai-client/providers/openai.d.ts +57 -0
  25. package/dist/ai-client/providers/openai.d.ts.map +1 -0
  26. package/dist/ai-client/providers/openai.js +290 -0
  27. package/dist/ai-client/providers/openai.js.map +1 -0
  28. package/dist/ai-client/providers/remote.d.ts +110 -0
  29. package/dist/ai-client/providers/remote.d.ts.map +1 -0
  30. package/dist/ai-client/providers/remote.js +352 -0
  31. package/dist/ai-client/providers/remote.js.map +1 -0
  32. package/dist/ai-client/registry.d.ts +51 -0
  33. package/dist/ai-client/registry.d.ts.map +1 -0
  34. package/dist/ai-client/registry.js +81 -0
  35. package/dist/ai-client/registry.js.map +1 -0
  36. package/dist/ai-client/types.d.ts +274 -0
  37. package/dist/ai-client/types.d.ts.map +1 -0
  38. package/dist/ai-client/types.js +90 -0
  39. package/dist/ai-client/types.js.map +1 -0
  40. package/dist/ai-client-factory.d.ts +62 -0
  41. package/dist/ai-client-factory.d.ts.map +1 -0
  42. package/dist/ai-client-factory.js +157 -0
  43. package/dist/ai-client-factory.js.map +1 -0
  44. package/dist/auth.d.ts +23 -1
  45. package/dist/auth.d.ts.map +1 -1
  46. package/dist/auth.js +164 -174
  47. package/dist/auth.js.map +1 -1
  48. package/dist/cancellation.d.ts +5 -4
  49. package/dist/cancellation.d.ts.map +1 -1
  50. package/dist/cancellation.js +53 -32
  51. package/dist/cancellation.js.map +1 -1
  52. package/dist/checkpoint.d.ts +2 -1
  53. package/dist/checkpoint.d.ts.map +1 -1
  54. package/dist/checkpoint.js +39 -6
  55. package/dist/checkpoint.js.map +1 -1
  56. package/dist/cli.js +742 -29
  57. package/dist/cli.js.map +1 -1
  58. package/dist/config.d.ts +10 -4
  59. package/dist/config.d.ts.map +1 -1
  60. package/dist/config.js +62 -25
  61. package/dist/config.js.map +1 -1
  62. package/dist/context-compressor.d.ts +82 -18
  63. package/dist/context-compressor.d.ts.map +1 -1
  64. package/dist/context-compressor.js +718 -154
  65. package/dist/context-compressor.js.map +1 -1
  66. package/dist/conversation.d.ts +1 -1
  67. package/dist/conversation.d.ts.map +1 -1
  68. package/dist/conversation.js +8 -7
  69. package/dist/conversation.js.map +1 -1
  70. package/dist/gui-subagent/action-parser/actionParser.d.ts.map +1 -1
  71. package/dist/gui-subagent/action-parser/actionParser.js +6 -4
  72. package/dist/gui-subagent/action-parser/actionParser.js.map +1 -1
  73. package/dist/gui-subagent/agent/gui-agent.d.ts +39 -2
  74. package/dist/gui-subagent/agent/gui-agent.d.ts.map +1 -1
  75. package/dist/gui-subagent/agent/gui-agent.js +189 -74
  76. package/dist/gui-subagent/agent/gui-agent.js.map +1 -1
  77. package/dist/gui-subagent/index.d.ts +23 -1
  78. package/dist/gui-subagent/index.d.ts.map +1 -1
  79. package/dist/gui-subagent/index.js +6 -0
  80. package/dist/gui-subagent/index.js.map +1 -1
  81. package/dist/gui-subagent/operator/base-operator.d.ts.map +1 -1
  82. package/dist/gui-subagent/operator/base-operator.js +0 -1
  83. package/dist/gui-subagent/operator/base-operator.js.map +1 -1
  84. package/dist/gui-subagent/operator/computer-operator.d.ts.map +1 -1
  85. package/dist/gui-subagent/operator/computer-operator.js +31 -8
  86. package/dist/gui-subagent/operator/computer-operator.js.map +1 -1
  87. package/dist/gui-subagent/types/actions.d.ts +1 -1
  88. package/dist/gui-subagent/types/actions.d.ts.map +1 -1
  89. package/dist/gui-subagent/types/actions.js +0 -1
  90. package/dist/gui-subagent/types/actions.js.map +1 -1
  91. package/dist/gui-subagent/types/operator.d.ts +1 -1
  92. package/dist/gui-subagent/types/operator.d.ts.map +1 -1
  93. package/dist/index.d.ts +1 -2
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +1 -2
  96. package/dist/index.js.map +1 -1
  97. package/dist/input-processor.d.ts.map +1 -1
  98. package/dist/input-processor.js +8 -5
  99. package/dist/input-processor.js.map +1 -1
  100. package/dist/logger.d.ts.map +1 -1
  101. package/dist/logger.js +1 -1
  102. package/dist/logger.js.map +1 -1
  103. package/dist/mcp.d.ts +7 -1
  104. package/dist/mcp.d.ts.map +1 -1
  105. package/dist/mcp.js +157 -49
  106. package/dist/mcp.js.map +1 -1
  107. package/dist/memory.d.ts.map +1 -1
  108. package/dist/memory.js +3 -3
  109. package/dist/memory.js.map +1 -1
  110. package/dist/output-util.d.ts +27 -0
  111. package/dist/output-util.d.ts.map +1 -0
  112. package/dist/output-util.js +74 -0
  113. package/dist/output-util.js.map +1 -0
  114. package/dist/retry.js +1 -1
  115. package/dist/retry.js.map +1 -1
  116. package/dist/ripgrep.d.ts +29 -0
  117. package/dist/ripgrep.d.ts.map +1 -0
  118. package/dist/ripgrep.js +294 -0
  119. package/dist/ripgrep.js.map +1 -0
  120. package/dist/sdk-output-adapter.d.ts +34 -1
  121. package/dist/sdk-output-adapter.d.ts.map +1 -1
  122. package/dist/sdk-output-adapter.js +67 -2
  123. package/dist/sdk-output-adapter.js.map +1 -1
  124. package/dist/sdk-session.d.ts.map +1 -1
  125. package/dist/sdk-session.js +2 -0
  126. package/dist/sdk-session.js.map +1 -1
  127. package/dist/session-manager.js +3 -3
  128. package/dist/session-manager.js.map +1 -1
  129. package/dist/session.d.ts +116 -6
  130. package/dist/session.d.ts.map +1 -1
  131. package/dist/session.js +1416 -448
  132. package/dist/session.js.map +1 -1
  133. package/dist/shell.d.ts +33 -0
  134. package/dist/shell.d.ts.map +1 -0
  135. package/dist/shell.js +126 -0
  136. package/dist/shell.js.map +1 -0
  137. package/dist/skill-installer.d.ts +38 -0
  138. package/dist/skill-installer.d.ts.map +1 -0
  139. package/dist/skill-installer.js +447 -0
  140. package/dist/skill-installer.js.map +1 -0
  141. package/dist/skill-invoker.d.ts +8 -2
  142. package/dist/skill-invoker.d.ts.map +1 -1
  143. package/dist/skill-invoker.js +36 -15
  144. package/dist/skill-invoker.js.map +1 -1
  145. package/dist/skill-loader.d.ts +8 -3
  146. package/dist/skill-loader.d.ts.map +1 -1
  147. package/dist/skill-loader.js +51 -48
  148. package/dist/skill-loader.js.map +1 -1
  149. package/dist/skill-manager.d.ts +85 -0
  150. package/dist/skill-manager.d.ts.map +1 -0
  151. package/dist/skill-manager.js +341 -0
  152. package/dist/skill-manager.js.map +1 -0
  153. package/dist/slash-commands.d.ts +39 -2
  154. package/dist/slash-commands.d.ts.map +1 -1
  155. package/dist/slash-commands.js +934 -305
  156. package/dist/slash-commands.js.map +1 -1
  157. package/dist/smart-approval.d.ts +20 -1
  158. package/dist/smart-approval.d.ts.map +1 -1
  159. package/dist/smart-approval.js +125 -56
  160. package/dist/smart-approval.js.map +1 -1
  161. package/dist/system-prompt-generator.d.ts +6 -0
  162. package/dist/system-prompt-generator.d.ts.map +1 -1
  163. package/dist/system-prompt-generator.js +86 -36
  164. package/dist/system-prompt-generator.js.map +1 -1
  165. package/dist/terminal.d.ts +28 -0
  166. package/dist/terminal.d.ts.map +1 -0
  167. package/dist/terminal.js +82 -0
  168. package/dist/terminal.js.map +1 -0
  169. package/dist/theme.d.ts.map +1 -1
  170. package/dist/theme.js +8 -7
  171. package/dist/theme.js.map +1 -1
  172. package/dist/tools.d.ts +38 -7
  173. package/dist/tools.d.ts.map +1 -1
  174. package/dist/tools.js +1249 -617
  175. package/dist/tools.js.map +1 -1
  176. package/dist/truncate.d.ts +55 -0
  177. package/dist/truncate.d.ts.map +1 -0
  178. package/dist/truncate.js +130 -0
  179. package/dist/truncate.js.map +1 -0
  180. package/dist/types.d.ts +84 -9
  181. package/dist/types.d.ts.map +1 -1
  182. package/dist/types.js +49 -0
  183. package/dist/types.js.map +1 -1
  184. package/dist/update.d.ts.map +1 -1
  185. package/dist/update.js +28 -36
  186. package/dist/update.js.map +1 -1
  187. package/dist/workflow.d.ts +5 -1
  188. package/dist/workflow.d.ts.map +1 -1
  189. package/dist/workflow.js +61 -49
  190. package/dist/workflow.js.map +1 -1
  191. package/docs/architecture/mcp-integration-guide.md +304 -194
  192. package/docs/architecture/overview.md +169 -169
  193. package/docs/architecture/tool-system-design.md +134 -134
  194. package/docs/cli/commands.md +349 -238
  195. package/docs/smart-mode.md +281 -281
  196. package/docs/third-party-models.md +440 -439
  197. package/find-skills/SKILL.md +133 -0
  198. package/package.json +91 -90
  199. package/scripts/install-ripgrep.js +241 -0
  200. package/src/agents.ts +7 -3
  201. package/src/ai-client/factory.ts +116 -0
  202. package/src/ai-client/index.ts +61 -0
  203. package/src/ai-client/providers/anthropic.ts +475 -0
  204. package/src/ai-client/providers/openai.ts +348 -0
  205. package/src/ai-client/providers/remote.ts +439 -0
  206. package/src/ai-client/registry.ts +97 -0
  207. package/src/ai-client/types.ts +364 -0
  208. package/src/ai-client-factory.ts +204 -0
  209. package/src/auth.ts +661 -614
  210. package/src/cancellation.ts +202 -176
  211. package/src/checkpoint.ts +255 -219
  212. package/src/cli.ts +1523 -743
  213. package/src/config.ts +341 -297
  214. package/src/context-compressor.ts +987 -290
  215. package/src/conversation.ts +290 -288
  216. package/src/gui-subagent/action-parser/actionParser.ts +318 -315
  217. package/src/gui-subagent/action-parser/constants.ts +14 -14
  218. package/src/gui-subagent/action-parser/index.ts +8 -8
  219. package/src/gui-subagent/action-parser/types.ts +31 -31
  220. package/src/gui-subagent/agent/gui-agent.ts +1234 -1089
  221. package/src/gui-subagent/agent/index.ts +5 -5
  222. package/src/gui-subagent/index.ts +185 -163
  223. package/src/gui-subagent/operator/base-operator.ts +244 -245
  224. package/src/gui-subagent/operator/computer-operator.ts +541 -520
  225. package/src/gui-subagent/operator/index.ts +6 -6
  226. package/src/gui-subagent/types/actions.ts +260 -262
  227. package/src/gui-subagent/types/index.ts +6 -6
  228. package/src/gui-subagent/types/operator.ts +106 -106
  229. package/src/gui-subagent/utils.ts +51 -51
  230. package/src/index.ts +17 -18
  231. package/src/input-processor.ts +8 -5
  232. package/src/logger.ts +436 -438
  233. package/src/mcp.ts +793 -682
  234. package/src/memory.ts +343 -344
  235. package/src/output-util.ts +80 -0
  236. package/src/retry.ts +1 -1
  237. package/src/ripgrep.ts +370 -0
  238. package/src/sdk-output-adapter.ts +842 -0
  239. package/src/sdk-session.ts +62 -0
  240. package/src/session-manager.ts +308 -308
  241. package/src/session.ts +1775 -573
  242. package/src/shell.ts +134 -0
  243. package/src/skill-installer.ts +518 -0
  244. package/src/skill-invoker.ts +959 -935
  245. package/src/skill-loader.ts +501 -496
  246. package/src/skill-manager.ts +385 -0
  247. package/src/slash-commands.ts +2189 -1389
  248. package/src/smart-approval.ts +193 -74
  249. package/src/system-prompt-generator.ts +91 -36
  250. package/src/terminal.ts +96 -0
  251. package/src/theme.ts +739 -738
  252. package/src/tools.ts +1790 -931
  253. package/src/truncate.ts +173 -0
  254. package/src/types.ts +337 -198
  255. package/src/update.ts +33 -40
  256. package/src/workflow.ts +521 -508
  257. package/test/cli-launch.test.ts +279 -0
  258. package/tsconfig.json +22 -22
  259. package/vitest.config.ts +21 -19
  260. package/dist/ai-client.d.ts +0 -86
  261. package/dist/ai-client.d.ts.map +0 -1
  262. package/dist/ai-client.js +0 -1372
  263. package/dist/ai-client.js.map +0 -1
  264. package/dist/gui-subagent/operator/browser-operator.d.ts +0 -36
  265. package/dist/gui-subagent/operator/browser-operator.d.ts.map +0 -1
  266. package/dist/gui-subagent/operator/browser-operator.js +0 -306
  267. package/dist/gui-subagent/operator/browser-operator.js.map +0 -1
  268. package/dist/gui-subagent/operator/desktop-operator.d.ts +0 -55
  269. package/dist/gui-subagent/operator/desktop-operator.d.ts.map +0 -1
  270. package/dist/gui-subagent/operator/desktop-operator.js +0 -527
  271. package/dist/gui-subagent/operator/desktop-operator.js.map +0 -1
  272. package/dist/hook.d.ts +0 -73
  273. package/dist/hook.d.ts.map +0 -1
  274. package/dist/hook.js +0 -156
  275. package/dist/hook.js.map +0 -1
  276. package/dist/input-history.d.ts +0 -24
  277. package/dist/input-history.d.ts.map +0 -1
  278. package/dist/input-history.js +0 -94
  279. package/dist/input-history.js.map +0 -1
  280. package/dist/keyboard-manager.d.ts +0 -151
  281. package/dist/keyboard-manager.d.ts.map +0 -1
  282. package/dist/keyboard-manager.js +0 -396
  283. package/dist/keyboard-manager.js.map +0 -1
  284. package/dist/print-system-prompt.d.ts +0 -2
  285. package/dist/print-system-prompt.d.ts.map +0 -1
  286. package/dist/print-system-prompt.js +0 -40
  287. package/dist/print-system-prompt.js.map +0 -1
  288. package/dist/remote-ai-client.d.ts +0 -104
  289. package/dist/remote-ai-client.d.ts.map +0 -1
  290. package/dist/remote-ai-client.js +0 -552
  291. package/dist/remote-ai-client.js.map +0 -1
  292. package/dist/sdk-session-v2.d.ts +0 -13
  293. package/dist/sdk-session-v2.d.ts.map +0 -1
  294. package/dist/sdk-session-v2.js +0 -46
  295. package/dist/sdk-session-v2.js.map +0 -1
  296. package/dist/test-boundary-conditions.d.ts.map +0 -1
  297. package/dist/test-boundary-conditions.js.map +0 -1
  298. package/dist/test-cancellation-fix.d.ts.map +0 -1
  299. package/dist/test-cancellation-fix.js.map +0 -1
  300. package/dist/test-input-history.d.ts.map +0 -1
  301. package/dist/test-input-history.js.map +0 -1
  302. package/dist/test-interaction-flow.d.ts.map +0 -1
  303. package/dist/test-interaction-flow.js.map +0 -1
  304. package/dist/test-quick.d.ts.map +0 -1
  305. package/dist/test-quick.js.map +0 -1
  306. package/dist/test-user-interaction.d.ts.map +0 -1
  307. package/dist/test-user-interaction.js.map +0 -1
  308. package/dist/tools/edit-diff.d.ts +0 -32
  309. package/dist/tools/edit-diff.d.ts.map +0 -1
  310. package/dist/tools/edit-diff.js +0 -185
  311. package/dist/tools/edit-diff.js.map +0 -1
  312. package/dist/tools/edit.d.ts +0 -11
  313. package/dist/tools/edit.d.ts.map +0 -1
  314. package/dist/tools/edit.js +0 -129
  315. package/dist/tools/edit.js.map +0 -1
  316. package/dist/unified-session.d.ts +0 -42
  317. package/dist/unified-session.d.ts.map +0 -1
  318. package/dist/unified-session.js +0 -271
  319. package/dist/unified-session.js.map +0 -1
  320. package/skills/.claude-plugin/marketplace.json +0 -45
  321. package/skills/README.md +0 -94
  322. package/skills/THIRD_PARTY_NOTICES.md +0 -405
  323. package/skills/skills/algorithmic-art/LICENSE.txt +0 -202
  324. package/skills/skills/algorithmic-art/SKILL.md +0 -405
  325. package/skills/skills/algorithmic-art/templates/generator_template.js +0 -223
  326. package/skills/skills/algorithmic-art/templates/viewer.html +0 -599
  327. package/skills/skills/brand-guidelines/LICENSE.txt +0 -202
  328. package/skills/skills/brand-guidelines/SKILL.md +0 -73
  329. package/skills/skills/canvas-design/LICENSE.txt +0 -202
  330. package/skills/skills/canvas-design/SKILL.md +0 -130
  331. package/skills/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +0 -93
  332. package/skills/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  333. package/skills/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  334. package/skills/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +0 -93
  335. package/skills/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  336. package/skills/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +0 -93
  337. package/skills/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
  338. package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  339. package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +0 -93
  340. package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  341. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  342. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  343. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +0 -93
  344. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  345. package/skills/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +0 -93
  346. package/skills/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
  347. package/skills/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +0 -94
  348. package/skills/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
  349. package/skills/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
  350. package/skills/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +0 -93
  351. package/skills/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
  352. package/skills/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +0 -93
  353. package/skills/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
  354. package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  355. package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +0 -93
  356. package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  357. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  358. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  359. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  360. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  361. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  362. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  363. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  364. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +0 -93
  365. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  366. package/skills/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  367. package/skills/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  368. package/skills/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +0 -93
  369. package/skills/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
  370. package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  371. package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +0 -93
  372. package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  373. package/skills/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
  374. package/skills/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
  375. package/skills/skills/canvas-design/canvas-fonts/Jura-OFL.txt +0 -93
  376. package/skills/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +0 -93
  377. package/skills/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  378. package/skills/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
  379. package/skills/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  380. package/skills/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
  381. package/skills/skills/canvas-design/canvas-fonts/Lora-OFL.txt +0 -93
  382. package/skills/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
  383. package/skills/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
  384. package/skills/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +0 -93
  385. package/skills/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
  386. package/skills/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +0 -93
  387. package/skills/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  388. package/skills/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
  389. package/skills/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +0 -93
  390. package/skills/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
  391. package/skills/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  392. package/skills/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +0 -93
  393. package/skills/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +0 -93
  394. package/skills/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  395. package/skills/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  396. package/skills/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +0 -93
  397. package/skills/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  398. package/skills/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +0 -93
  399. package/skills/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  400. package/skills/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  401. package/skills/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +0 -93
  402. package/skills/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
  403. package/skills/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +0 -93
  404. package/skills/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
  405. package/skills/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
  406. package/skills/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  407. package/skills/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
  408. package/skills/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +0 -93
  409. package/skills/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
  410. package/skills/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +0 -93
  411. package/skills/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  412. package/skills/skills/doc-coauthoring/SKILL.md +0 -375
  413. package/skills/skills/docx/LICENSE.txt +0 -30
  414. package/skills/skills/docx/SKILL.md +0 -197
  415. package/skills/skills/docx/docx-js.md +0 -350
  416. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  417. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  418. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  419. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  420. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  421. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  422. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  423. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  424. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  425. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  426. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  427. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  428. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  429. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  430. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  431. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  432. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  433. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  434. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  435. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  436. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  437. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  438. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  439. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  440. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  441. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  442. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  443. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  444. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  445. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  446. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  447. package/skills/skills/docx/ooxml/schemas/mce/mc.xsd +0 -75
  448. package/skills/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
  449. package/skills/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
  450. package/skills/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
  451. package/skills/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
  452. package/skills/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
  453. package/skills/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  454. package/skills/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
  455. package/skills/skills/docx/ooxml/scripts/pack.py +0 -159
  456. package/skills/skills/docx/ooxml/scripts/unpack.py +0 -29
  457. package/skills/skills/docx/ooxml/scripts/validate.py +0 -69
  458. package/skills/skills/docx/ooxml/scripts/validation/__init__.py +0 -15
  459. package/skills/skills/docx/ooxml/scripts/validation/base.py +0 -951
  460. package/skills/skills/docx/ooxml/scripts/validation/docx.py +0 -274
  461. package/skills/skills/docx/ooxml/scripts/validation/pptx.py +0 -315
  462. package/skills/skills/docx/ooxml/scripts/validation/redlining.py +0 -279
  463. package/skills/skills/docx/ooxml.md +0 -610
  464. package/skills/skills/docx/scripts/__init__.py +0 -1
  465. package/skills/skills/docx/scripts/document.py +0 -1276
  466. package/skills/skills/docx/scripts/templates/comments.xml +0 -3
  467. package/skills/skills/docx/scripts/templates/commentsExtended.xml +0 -3
  468. package/skills/skills/docx/scripts/templates/commentsExtensible.xml +0 -3
  469. package/skills/skills/docx/scripts/templates/commentsIds.xml +0 -3
  470. package/skills/skills/docx/scripts/templates/people.xml +0 -3
  471. package/skills/skills/docx/scripts/utilities.py +0 -374
  472. package/skills/skills/frontend-design/LICENSE.txt +0 -177
  473. package/skills/skills/frontend-design/SKILL.md +0 -42
  474. package/skills/skills/internal-comms/LICENSE.txt +0 -202
  475. package/skills/skills/internal-comms/SKILL.md +0 -32
  476. package/skills/skills/internal-comms/examples/3p-updates.md +0 -47
  477. package/skills/skills/internal-comms/examples/company-newsletter.md +0 -65
  478. package/skills/skills/internal-comms/examples/faq-answers.md +0 -30
  479. package/skills/skills/internal-comms/examples/general-comms.md +0 -16
  480. package/skills/skills/mcp-builder/LICENSE.txt +0 -202
  481. package/skills/skills/mcp-builder/SKILL.md +0 -236
  482. package/skills/skills/mcp-builder/reference/evaluation.md +0 -602
  483. package/skills/skills/mcp-builder/reference/mcp_best_practices.md +0 -249
  484. package/skills/skills/mcp-builder/reference/node_mcp_server.md +0 -970
  485. package/skills/skills/mcp-builder/reference/python_mcp_server.md +0 -719
  486. package/skills/skills/mcp-builder/scripts/connections.py +0 -151
  487. package/skills/skills/mcp-builder/scripts/evaluation.py +0 -373
  488. package/skills/skills/mcp-builder/scripts/example_evaluation.xml +0 -22
  489. package/skills/skills/mcp-builder/scripts/requirements.txt +0 -2
  490. package/skills/skills/pdf/LICENSE.txt +0 -30
  491. package/skills/skills/pdf/SKILL.md +0 -294
  492. package/skills/skills/pdf/forms.md +0 -205
  493. package/skills/skills/pdf/reference.md +0 -612
  494. package/skills/skills/pdf/scripts/check_bounding_boxes.py +0 -70
  495. package/skills/skills/pdf/scripts/check_bounding_boxes_test.py +0 -226
  496. package/skills/skills/pdf/scripts/check_fillable_fields.py +0 -12
  497. package/skills/skills/pdf/scripts/convert_pdf_to_images.py +0 -35
  498. package/skills/skills/pdf/scripts/create_validation_image.py +0 -41
  499. package/skills/skills/pdf/scripts/extract_form_field_info.py +0 -152
  500. package/skills/skills/pdf/scripts/fill_fillable_fields.py +0 -114
  501. package/skills/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -108
  502. package/skills/skills/pptx/LICENSE.txt +0 -30
  503. package/skills/skills/pptx/SKILL.md +0 -484
  504. package/skills/skills/pptx/html2pptx.md +0 -625
  505. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  506. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  507. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  508. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  509. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  510. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  511. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  512. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  513. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  514. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  515. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  516. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  517. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  518. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  519. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  520. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  521. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  522. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  523. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  524. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  525. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  526. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  527. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  528. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  529. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  530. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  531. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  532. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  533. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  534. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  535. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  536. package/skills/skills/pptx/ooxml/schemas/mce/mc.xsd +0 -75
  537. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
  538. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
  539. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
  540. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
  541. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
  542. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  543. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
  544. package/skills/skills/pptx/ooxml/scripts/pack.py +0 -159
  545. package/skills/skills/pptx/ooxml/scripts/unpack.py +0 -29
  546. package/skills/skills/pptx/ooxml/scripts/validate.py +0 -69
  547. package/skills/skills/pptx/ooxml/scripts/validation/__init__.py +0 -15
  548. package/skills/skills/pptx/ooxml/scripts/validation/base.py +0 -951
  549. package/skills/skills/pptx/ooxml/scripts/validation/docx.py +0 -274
  550. package/skills/skills/pptx/ooxml/scripts/validation/pptx.py +0 -315
  551. package/skills/skills/pptx/ooxml/scripts/validation/redlining.py +0 -279
  552. package/skills/skills/pptx/ooxml.md +0 -427
  553. package/skills/skills/pptx/scripts/html2pptx.js +0 -979
  554. package/skills/skills/pptx/scripts/inventory.py +0 -1020
  555. package/skills/skills/pptx/scripts/rearrange.py +0 -231
  556. package/skills/skills/pptx/scripts/replace.py +0 -385
  557. package/skills/skills/pptx/scripts/thumbnail.py +0 -450
  558. package/skills/skills/skill-creator/LICENSE.txt +0 -202
  559. package/skills/skills/skill-creator/SKILL.md +0 -356
  560. package/skills/skills/skill-creator/references/output-patterns.md +0 -82
  561. package/skills/skills/skill-creator/references/workflows.md +0 -28
  562. package/skills/skills/skill-creator/scripts/init_skill.py +0 -303
  563. package/skills/skills/skill-creator/scripts/package_skill.py +0 -110
  564. package/skills/skills/skill-creator/scripts/quick_validate.py +0 -95
  565. package/skills/skills/slack-gif-creator/LICENSE.txt +0 -202
  566. package/skills/skills/slack-gif-creator/SKILL.md +0 -254
  567. package/skills/skills/slack-gif-creator/core/easing.py +0 -234
  568. package/skills/skills/slack-gif-creator/core/frame_composer.py +0 -176
  569. package/skills/skills/slack-gif-creator/core/gif_builder.py +0 -269
  570. package/skills/skills/slack-gif-creator/core/validators.py +0 -136
  571. package/skills/skills/slack-gif-creator/requirements.txt +0 -4
  572. package/skills/skills/theme-factory/LICENSE.txt +0 -202
  573. package/skills/skills/theme-factory/SKILL.md +0 -59
  574. package/skills/skills/theme-factory/theme-showcase.pdf +0 -0
  575. package/skills/skills/theme-factory/themes/arctic-frost.md +0 -19
  576. package/skills/skills/theme-factory/themes/botanical-garden.md +0 -19
  577. package/skills/skills/theme-factory/themes/desert-rose.md +0 -19
  578. package/skills/skills/theme-factory/themes/forest-canopy.md +0 -19
  579. package/skills/skills/theme-factory/themes/golden-hour.md +0 -19
  580. package/skills/skills/theme-factory/themes/midnight-galaxy.md +0 -19
  581. package/skills/skills/theme-factory/themes/modern-minimalist.md +0 -19
  582. package/skills/skills/theme-factory/themes/ocean-depths.md +0 -19
  583. package/skills/skills/theme-factory/themes/sunset-boulevard.md +0 -19
  584. package/skills/skills/theme-factory/themes/tech-innovation.md +0 -19
  585. package/skills/skills/web-artifacts-builder/LICENSE.txt +0 -202
  586. package/skills/skills/web-artifacts-builder/SKILL.md +0 -74
  587. package/skills/skills/web-artifacts-builder/scripts/bundle-artifact.sh +0 -54
  588. package/skills/skills/web-artifacts-builder/scripts/init-artifact.sh +0 -322
  589. package/skills/skills/webapp-testing/LICENSE.txt +0 -202
  590. package/skills/skills/webapp-testing/SKILL.md +0 -96
  591. package/skills/skills/webapp-testing/examples/console_logging.py +0 -35
  592. package/skills/skills/webapp-testing/examples/element_discovery.py +0 -40
  593. package/skills/skills/webapp-testing/examples/static_html_automation.py +0 -33
  594. package/skills/skills/webapp-testing/scripts/with_server.py +0 -106
  595. package/skills/skills/xlsx/LICENSE.txt +0 -30
  596. package/skills/skills/xlsx/SKILL.md +0 -289
  597. package/skills/skills/xlsx/recalc.py +0 -178
  598. package/skills/spec/agent-skills-spec.md +0 -3
  599. package/skills/template/SKILL.md +0 -6
  600. package/src/ai-client.ts +0 -1560
  601. package/src/remote-ai-client.ts +0 -664
  602. /package/{.eslintrc.js → .eslintrc.cjs} +0 -0
package/src/shell.ts ADDED
@@ -0,0 +1,134 @@
1
+ import { existsSync } from 'fs';
2
+ import { spawn, spawnSync } from 'child_process';
3
+ import { output as logOutput } from './output-util.js';
4
+
5
+ /**
6
+ * Find bash executable on PATH (Windows).
7
+ */
8
+ function _findBashOnPath(): string | null {
9
+ try {
10
+ const result = spawnSync('where', ['bash.exe'], { encoding: 'utf-8', timeout: 5000 });
11
+ if (result.status === 0 && result.stdout) {
12
+ const firstMatch = result.stdout.trim().split(/\r?\n/)[0];
13
+ if (firstMatch && existsSync(firstMatch)) {
14
+ return firstMatch;
15
+ }
16
+ }
17
+ } catch {
18
+ // Ignore errors
19
+ }
20
+ return null;
21
+ }
22
+
23
+ /**
24
+ * Get PowerShell version on Windows.
25
+ * @returns Version string (e.g., "5.1.22621") or "Unknown" if detection fails
26
+ */
27
+ export function getPowerShellVersion(): string {
28
+ if (process.platform !== 'win32') {
29
+ return 'N/A';
30
+ }
31
+
32
+ try {
33
+ const result = spawnSync('powershell', ['-NoProfile', '-Command', '($PSVersionTable.PSVersion | Select-Object -ExpandProperty Major), ($PSVersionTable.PSVersion | Select-Object -ExpandProperty Minor), ($PSVersionTable.PSVersion | Select-Object -ExpandProperty Build) -join "."'], {
34
+ encoding: 'utf-8',
35
+ timeout: 5000
36
+ });
37
+
38
+ if (result.status === 0 && result.stdout.trim()) {
39
+ return result.stdout.trim();
40
+ }
41
+ } catch {
42
+ // Ignore errors
43
+ }
44
+ return 'Unknown';
45
+ }
46
+
47
+ interface ShellConfig {
48
+ /** Path to the shell executable */
49
+ shell: string;
50
+ /** Arguments to pass to the shell */
51
+ args: string[];
52
+ }
53
+
54
+ let cachedShellConfig: ShellConfig | null = null;
55
+
56
+ /**
57
+ * Get shell configuration based on platform.
58
+ * Resolution order:
59
+ * 1. On Windows: PowerShell (preferred), then Git Bash as fallback
60
+ * 2. On Unix: /bin/bash
61
+ *
62
+ * @returns ShellConfig with shell path and args
63
+ */
64
+ export function getShellConfig(): ShellConfig {
65
+ if (cachedShellConfig) {
66
+ return cachedShellConfig;
67
+ }
68
+
69
+ if (process.platform === 'win32') {
70
+ // On Windows, prefer PowerShell for better compatibility and output handling
71
+ // Use -NoProfile to avoid profile script interference
72
+ // -Command executes the command string as PowerShell script
73
+ cachedShellConfig = {
74
+ shell: 'powershell',
75
+ args: ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command']
76
+ };
77
+ return cachedShellConfig;
78
+ }
79
+
80
+ // Unix: prefer bash over sh
81
+ if (existsSync('/bin/bash')) {
82
+ cachedShellConfig = { shell: '/bin/bash', args: ['-c'] };
83
+ } else {
84
+ cachedShellConfig = { shell: 'sh', args: ['-c'] };
85
+ }
86
+ return cachedShellConfig;
87
+ }
88
+
89
+ /**
90
+ * Get a shell command string with proper quoting for the platform.
91
+ * @param command The command to execute
92
+ * @returns A properly quoted command string
93
+ */
94
+ export function quoteShellCommand(command: string): string {
95
+ if (process.platform === 'win32') {
96
+ // For PowerShell -Command, the command string is passed directly
97
+ // PowerShell will parse and execute it as a script
98
+ // No additional quoting needed - just return the command as-is
99
+ return command;
100
+ } else {
101
+ // For bash/sh, use single quotes
102
+ return `'${command.replace(/'/g, "'\\''")}'`;
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Kill a process and all its children (cross-platform).
108
+ * @param pid Process ID to kill
109
+ */
110
+ export function killProcessTree(pid: number): void {
111
+ if (process.platform === 'win32') {
112
+ // Use taskkill on Windows to kill process tree
113
+ try {
114
+ spawn('taskkill', ['/F', '/T', '/PID', String(pid)], {
115
+ stdio: 'ignore',
116
+ detached: true,
117
+ });
118
+ } catch (error) {
119
+ logOutput('warning', `[shell] Failed to kill process tree (PID ${pid})`, { error: error instanceof Error ? error.message : String(error) });
120
+ }
121
+ } else {
122
+ // Use SIGKILL on Unix/Linux/Mac
123
+ try {
124
+ process.kill(-pid, 'SIGKILL');
125
+ } catch {
126
+ // Fallback to killing just the child if process group kill fails
127
+ try {
128
+ process.kill(pid, 'SIGKILL');
129
+ } catch (fallbackError) {
130
+ logOutput('warning', `[shell] Failed to kill process (PID ${pid})`, { error: fallbackError instanceof Error ? fallbackError.message : String(fallbackError) });
131
+ }
132
+ }
133
+ }
134
+ }
@@ -0,0 +1,518 @@
1
+ /**
2
+ * Skill Installer - Handles remote skill installation
3
+ * Supports: GitHub shorthand, GitHub URLs, direct SKILL.md URLs
4
+ */
5
+
6
+ import fs from 'fs/promises';
7
+ import path from 'path';
8
+ import os from 'os';
9
+ import { mkdtemp, rm } from 'fs/promises';
10
+ import { tmpdir } from 'os';
11
+ import simpleGit from 'simple-git';
12
+ import { getConfigManager } from './config.js';
13
+ import { getLogger } from './logger.js';
14
+
15
+ const _logger = getLogger();
16
+ const CLONE_TIMEOUT_MS = 60000; // 60 seconds
17
+
18
+ export interface RemoteSource {
19
+ type: 'github' | 'direct-url' | 'local';
20
+ url: string;
21
+ ref?: string; // Branch/tag
22
+ subpath?: string; // Path to skill within repo
23
+ skillName?: string; // For @owner/repo@syntax
24
+ }
25
+
26
+ export interface InstallResult {
27
+ success: boolean;
28
+ skillName?: string;
29
+ skillPath?: string;
30
+ error?: string;
31
+ }
32
+
33
+ /**
34
+ * Parse a source string into structured format
35
+ */
36
+ export function parseSource(input: string): RemoteSource {
37
+ const trimmed = input.trim();
38
+
39
+ // Check if local path
40
+ if (isLocalPath(trimmed)) {
41
+ return { type: 'local', url: trimmed };
42
+ }
43
+
44
+ // Direct SKILL.md URL (non-GitHub)
45
+ if (isDirectSkillUrl(trimmed)) {
46
+ return { type: 'direct-url', url: trimmed };
47
+ }
48
+
49
+ // GitHub URL with path: https://github.com/owner/repo/tree/branch/path/to/skill
50
+ const githubTreeWithPathMatch = trimmed.match(/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)/);
51
+ if (githubTreeWithPathMatch) {
52
+ const [, owner, repo, ref, subpath] = githubTreeWithPathMatch;
53
+ return {
54
+ type: 'github',
55
+ url: `https://github.com/${owner}/${repo}.git`,
56
+ ref,
57
+ subpath
58
+ };
59
+ }
60
+
61
+ // GitHub URL with branch only: https://github.com/owner/repo/tree/branch
62
+ const githubTreeMatch = trimmed.match(/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)$/);
63
+ if (githubTreeMatch) {
64
+ const [, owner, repo, ref] = githubTreeMatch;
65
+ return {
66
+ type: 'github',
67
+ url: `https://github.com/${owner}/${repo}.git`,
68
+ ref
69
+ };
70
+ }
71
+
72
+ // GitHub URL: https://github.com/owner/repo
73
+ const githubRepoMatch = trimmed.match(/github\.com\/([^/]+)\/([^/]+)/);
74
+ if (githubRepoMatch) {
75
+ const [, owner, repo] = githubRepoMatch;
76
+ const cleanRepo = repo.replace(/\.git$/, '');
77
+ return {
78
+ type: 'github',
79
+ url: `https://github.com/${owner}/${cleanRepo}.git`
80
+ };
81
+ }
82
+
83
+ // GitHub shorthand: owner/repo, owner/repo@skill-name
84
+ const atSkillMatch = trimmed.match(/^([^/]+)\/([^/@]+)@(.+)$/);
85
+ if (atSkillMatch && !trimmed.includes(':') && !trimmed.startsWith('.') && !trimmed.startsWith('/')) {
86
+ const [, owner, repo, skillName] = atSkillMatch;
87
+ return {
88
+ type: 'github',
89
+ url: `https://github.com/${owner}/${repo}.git`,
90
+ skillName
91
+ };
92
+ }
93
+
94
+ const shorthandMatch = trimmed.match(/^([^/]+)\/([^/]+)(?:\/(.+))?$/);
95
+ if (shorthandMatch && !trimmed.includes(':') && !trimmed.startsWith('.') && !trimmed.startsWith('/')) {
96
+ const [, owner, repo, subpath] = shorthandMatch;
97
+ return {
98
+ type: 'github',
99
+ url: `https://github.com/${owner}/${repo}.git`,
100
+ subpath
101
+ };
102
+ }
103
+
104
+ // Fallback: treat as direct URL
105
+ return { type: 'direct-url', url: trimmed };
106
+ }
107
+
108
+ /**
109
+ * Check if input is a local path
110
+ */
111
+ function isLocalPath(input: string): boolean {
112
+ return (
113
+ path.isAbsolute(input) ||
114
+ input.startsWith('./') ||
115
+ input.startsWith('../') ||
116
+ input === '.' ||
117
+ input === '..' ||
118
+ /^[a-zA-Z]:[/\\]/.test(input)
119
+ );
120
+ }
121
+
122
+ /**
123
+ * Check if URL is a direct link to SKILL.md file
124
+ */
125
+ function isDirectSkillUrl(input: string): boolean {
126
+ if (!input.startsWith('http://') && !input.startsWith('https://')) {
127
+ return false;
128
+ }
129
+
130
+ if (!input.toLowerCase().endsWith('/skill.md') && !input.toLowerCase().endsWith('/skill')) {
131
+ return false;
132
+ }
133
+
134
+ // Exclude GitHub/GitLab URLs (they have their own handling)
135
+ if (input.includes('github.com/') && !input.includes('raw.githubusercontent.com')) {
136
+ return false;
137
+ }
138
+ if (input.includes('gitlab.com/') && !input.includes('/-/raw/')) {
139
+ return false;
140
+ }
141
+
142
+ return true;
143
+ }
144
+
145
+ /**
146
+ * Extract skill name from SKILL.md content
147
+ */
148
+ function extractSkillName(content: string): string | null {
149
+ const nameMatch = content.match(/^name:\s*(.+)$/m);
150
+ return nameMatch ? nameMatch[1].trim() : null;
151
+ }
152
+
153
+ /**
154
+ * Ensure directory exists
155
+ */
156
+ async function ensureDir(dirPath: string): Promise<void> {
157
+ await fs.mkdir(dirPath, { recursive: true });
158
+ }
159
+
160
+ /**
161
+ * Remove directory recursively
162
+ */
163
+ async function removeDir(dirPath: string): Promise<void> {
164
+ try {
165
+ await fs.rm(dirPath, { recursive: true, force: true });
166
+ } catch {
167
+ // Ignore if doesn't exist
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Copy directory contents
173
+ */
174
+ async function copyDir(src: string, dest: string): Promise<void> {
175
+ await ensureDir(dest);
176
+ const entries = await fs.readdir(src, { withFileTypes: true });
177
+
178
+ for (const entry of entries) {
179
+ const srcPath = path.join(src, entry.name);
180
+ const destPath = path.join(dest, entry.name);
181
+
182
+ if (entry.isDirectory()) {
183
+ await copyDir(srcPath, destPath);
184
+ } else if (entry.isFile()) {
185
+ await fs.copyFile(srcPath, destPath);
186
+ }
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Find SKILL.md in a directory
192
+ */
193
+ async function findSkillMd(dirPath: string): Promise<string | null> {
194
+ try {
195
+ const entries = await fs.readdir(dirPath, { withFileTypes: true });
196
+
197
+ for (const entry of entries) {
198
+ const fullPath = path.join(dirPath, entry.name);
199
+
200
+ if (entry.isDirectory()) {
201
+ // Skip hidden directories (except .)
202
+ if (entry.name.startsWith('.') && entry.name !== '.') continue;
203
+
204
+ // Check subdirectory for SKILL.md
205
+ const result = await findSkillMd(fullPath);
206
+ if (result) return result;
207
+ } else if (entry.isFile() && entry.name.toUpperCase() === 'SKILL.MD') {
208
+ return fullPath;
209
+ }
210
+ }
211
+ } catch {
212
+ // Ignore errors
213
+ }
214
+ return null;
215
+ }
216
+
217
+ /**
218
+ * Fetch remote file content via HTTP with timeout
219
+ */
220
+ async function fetchRemoteFile(url: string, timeoutMs: number = 30000): Promise<string> {
221
+ const controller = new AbortController();
222
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
223
+
224
+ try {
225
+ const response = await fetch(url, { signal: controller.signal });
226
+ clearTimeout(timeoutId);
227
+
228
+ if (!response.ok) {
229
+ throw new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);
230
+ }
231
+ return response.text();
232
+ } catch (error) {
233
+ clearTimeout(timeoutId);
234
+ if (error instanceof Error && error.name === 'AbortError') {
235
+ throw new Error(`Request timed out after ${timeoutMs}ms: ${url}`);
236
+ }
237
+ throw error;
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Clone a GitHub repository to a temporary directory
243
+ */
244
+ async function cloneRepo(url: string, ref?: string): Promise<string> {
245
+ const tempDir = await mkdtemp(path.join(tmpdir(), 'xagent-skills-'));
246
+ const git = simpleGit({ timeout: { block: CLONE_TIMEOUT_MS } });
247
+ const cloneOptions = ref ? ['--depth', '1', '--branch', ref] : ['--depth', '1'];
248
+
249
+ try {
250
+ await git.clone(url, tempDir, cloneOptions);
251
+ return tempDir;
252
+ } catch (error) {
253
+ // Clean up temp dir on failure
254
+ await rm(tempDir, { recursive: true, force: true }).catch(() => {});
255
+
256
+ const errorMessage = error instanceof Error ? error.message : String(error);
257
+ const isTimeout = errorMessage.includes('block timeout') || errorMessage.includes('timed out');
258
+
259
+ if (isTimeout) {
260
+ throw new Error(
261
+ `Clone timed out after 60s. This often happens with private repos that require authentication.\n` +
262
+ ` Ensure you have access and your SSH keys or credentials are configured.`
263
+ );
264
+ }
265
+
266
+ throw new Error(`Failed to clone ${url}: ${errorMessage}`);
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Install skill from direct URL (single SKILL.md file)
272
+ */
273
+ async function installFromDirectUrl(source: RemoteSource): Promise<InstallResult> {
274
+ const configManager = getConfigManager();
275
+ const userSkillsPath = configManager.getUserSkillsPath() || path.join(os.homedir(), '.xagent', 'skills');
276
+
277
+ try {
278
+ const content = await fetchRemoteFile(source.url);
279
+ const skillName = extractSkillName(content);
280
+
281
+ if (!skillName) {
282
+ return { success: false, error: 'Could not extract skill name from SKILL.md' };
283
+ }
284
+
285
+ const skillPath = path.join(userSkillsPath, skillName);
286
+
287
+ // Check if skill already exists
288
+ try {
289
+ await fs.access(skillPath);
290
+ return { success: false, error: `Skill "${skillName}" already installed` };
291
+ } catch {
292
+ // Doesn't exist, proceed
293
+ }
294
+
295
+ // Create skill directory
296
+ await ensureDir(skillPath);
297
+
298
+ // Write SKILL.md
299
+ await fs.writeFile(path.join(skillPath, 'SKILL.md'), content, 'utf-8');
300
+
301
+ return { success: true, skillName, skillPath };
302
+ } catch (error) {
303
+ return { success: false, error: error instanceof Error ? error.message : String(error) };
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Install skill from GitHub repository using git clone
309
+ */
310
+ async function installFromGitHub(source: RemoteSource): Promise<InstallResult> {
311
+ const configManager = getConfigManager();
312
+ const userSkillsPath = configManager.getUserSkillsPath() || path.join(os.homedir(), '.xagent', 'skills');
313
+
314
+ // Parse owner/repo from URL
315
+ const urlMatch = source.url.match(/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/);
316
+ if (!urlMatch) {
317
+ return { success: false, error: 'Invalid GitHub URL' };
318
+ }
319
+
320
+ const [, _owner, repo] = urlMatch;
321
+ const _cleanRepo = repo.replace(/\.git$/, '');
322
+ const ref = source.ref || 'main';
323
+
324
+ let tempDir: string | null = null;
325
+
326
+ try {
327
+ // Clone the repository to a temporary directory
328
+ tempDir = await cloneRepo(source.url, ref);
329
+
330
+ // Find the skill directory in the cloned repo
331
+ let skillDir: string;
332
+
333
+ if (source.subpath) {
334
+ // Specific path to skill provided
335
+ skillDir = path.join(tempDir, source.subpath);
336
+ try {
337
+ await fs.access(skillDir);
338
+ } catch {
339
+ return { success: false, error: `Path "${source.subpath}" not found in repository` };
340
+ }
341
+ } else if (source.skillName) {
342
+ // @owner/repo@syntax - skill is in skills/<skill-name>/
343
+ skillDir = path.join(tempDir, 'skills', source.skillName);
344
+ try {
345
+ await fs.access(skillDir);
346
+ } catch {
347
+ return { success: false, error: `Skill "${source.skillName}" not found in skills/` };
348
+ }
349
+ } else {
350
+ // No specific path - find SKILL.md in the repo
351
+ const skillMdPath = await findSkillMd(tempDir);
352
+ if (!skillMdPath) {
353
+ return { success: false, error: 'No SKILL.md found in repository' };
354
+ }
355
+ skillDir = path.dirname(skillMdPath);
356
+ }
357
+
358
+ // Read SKILL.md to get skill name
359
+ const skillMdPath = path.join(skillDir, 'SKILL.md');
360
+ let skillContent: string;
361
+ try {
362
+ skillContent = await fs.readFile(skillMdPath, 'utf-8');
363
+ } catch {
364
+ return { success: false, error: 'SKILL.md not found in skill directory' };
365
+ }
366
+
367
+ const skillName = extractSkillName(skillContent);
368
+ if (!skillName) {
369
+ return { success: false, error: 'Could not extract skill name from SKILL.md' };
370
+ }
371
+
372
+ const skillPath = path.join(userSkillsPath, skillName);
373
+
374
+ // Check if skill already exists
375
+ try {
376
+ await fs.access(skillPath);
377
+ return { success: false, error: `Skill "${skillName}" already installed` };
378
+ } catch {
379
+ // Doesn't exist, proceed
380
+ }
381
+
382
+ // Copy skill files to user skills directory
383
+ await copyDir(skillDir, skillPath);
384
+
385
+ return { success: true, skillName, skillPath };
386
+ } catch (error) {
387
+ return { success: false, error: error instanceof Error ? error.message : String(error) };
388
+ } finally {
389
+ // Clean up temporary directory
390
+ if (tempDir) {
391
+ await rm(tempDir, { recursive: true, force: true }).catch(() => {});
392
+ }
393
+ }
394
+ }
395
+
396
+ /**
397
+ * Install skill from local path
398
+ */
399
+ async function installFromLocal(source: RemoteSource): Promise<InstallResult> {
400
+ const configManager = getConfigManager();
401
+ const userSkillsPath = configManager.getUserSkillsPath() || path.join(os.homedir(), '.xagent', 'skills');
402
+
403
+ try {
404
+ const resolvedPath = path.resolve(source.url);
405
+
406
+ // Check if source exists
407
+ await fs.access(resolvedPath);
408
+
409
+ // Find SKILL.md
410
+ const skillMdPath = await findSkillMd(resolvedPath);
411
+ if (!skillMdPath) {
412
+ return { success: false, error: 'SKILL.md not found in source directory' };
413
+ }
414
+
415
+ const content = await fs.readFile(skillMdPath, 'utf-8');
416
+ const skillName = extractSkillName(content);
417
+
418
+ if (!skillName) {
419
+ return { success: false, error: 'Could not extract skill name from SKILL.md' };
420
+ }
421
+
422
+ const skillPath = path.join(userSkillsPath, skillName);
423
+
424
+ // Check if skill already exists
425
+ try {
426
+ await fs.access(skillPath);
427
+ return { success: false, error: `Skill "${skillName}" already installed` };
428
+ } catch {
429
+ // Doesn't exist, proceed
430
+ }
431
+
432
+ // Copy the skill directory
433
+ const sourceDir = path.dirname(skillMdPath);
434
+ await copyDir(sourceDir, skillPath);
435
+
436
+ return { success: true, skillName, skillPath };
437
+ } catch (error) {
438
+ return { success: false, error: error instanceof Error ? error.message : String(error) };
439
+ }
440
+ }
441
+
442
+ /**
443
+ * Main function to install a skill from source
444
+ */
445
+ export async function installSkill(source: string): Promise<InstallResult> {
446
+ const parsed = parseSource(source);
447
+
448
+ switch (parsed.type) {
449
+ case 'direct-url':
450
+ return installFromDirectUrl(parsed);
451
+ case 'github':
452
+ return installFromGitHub(parsed);
453
+ case 'local':
454
+ return installFromLocal(parsed);
455
+ default:
456
+ return { success: false, error: 'Unknown source type' };
457
+ }
458
+ }
459
+
460
+ /**
461
+ * Remove an installed skill
462
+ */
463
+ export async function removeSkill(skillName: string): Promise<InstallResult> {
464
+ const configManager = getConfigManager();
465
+ const userSkillsPath = configManager.getUserSkillsPath() || path.join(os.homedir(), '.xagent', 'skills');
466
+ const skillPath = path.join(userSkillsPath, skillName);
467
+
468
+ try {
469
+ await fs.access(skillPath);
470
+ await removeDir(skillPath);
471
+ return { success: true, skillName, skillPath };
472
+ } catch {
473
+ return { success: false, error: `Skill "${skillName}" not found` };
474
+ }
475
+ }
476
+
477
+ /**
478
+ * List installed user skills
479
+ */
480
+ export async function listUserSkills(): Promise<Array<{ name: string; description: string; path: string }>> {
481
+ const configManager = getConfigManager();
482
+ const userSkillsPath = configManager.getUserSkillsPath() || path.join(os.homedir(), '.xagent', 'skills');
483
+
484
+ const skills: Array<{ name: string; description: string; path: string }> = [];
485
+
486
+ try {
487
+ const entries = await fs.readdir(userSkillsPath, { withFileTypes: true });
488
+
489
+ for (const entry of entries) {
490
+ if (entry.isDirectory()) {
491
+ const skillPath = path.join(userSkillsPath, entry.name);
492
+ const skillMdPath = path.join(skillPath, 'SKILL.md');
493
+
494
+ try {
495
+ const content = await fs.readFile(skillMdPath, 'utf-8');
496
+ const nameMatch = content.match(/^name:\s*(.+)$/m);
497
+ const descMatch = content.match(/^description:\s*(.+)$/m);
498
+
499
+ skills.push({
500
+ name: nameMatch ? nameMatch[1].trim() : entry.name,
501
+ description: descMatch ? descMatch[1].trim() : 'No description',
502
+ path: skillPath
503
+ });
504
+ } catch {
505
+ skills.push({
506
+ name: entry.name,
507
+ description: '(Missing SKILL.md)',
508
+ path: skillPath
509
+ });
510
+ }
511
+ }
512
+ }
513
+ } catch {
514
+ // Directory doesn't exist or is empty
515
+ }
516
+
517
+ return skills;
518
+ }