shortcutxl 0.2.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 (423) hide show
  1. package/README.md +59 -0
  2. package/agent-docs/README.md +397 -0
  3. package/agent-docs/docs/compaction.md +390 -0
  4. package/agent-docs/docs/custom-provider.md +580 -0
  5. package/agent-docs/docs/development.md +69 -0
  6. package/agent-docs/docs/extensions.md +1971 -0
  7. package/agent-docs/docs/json.md +79 -0
  8. package/agent-docs/docs/keybindings.md +174 -0
  9. package/agent-docs/docs/models.md +293 -0
  10. package/agent-docs/docs/packages.md +209 -0
  11. package/agent-docs/docs/prompt-templates.md +67 -0
  12. package/agent-docs/docs/providers.md +186 -0
  13. package/agent-docs/docs/rpc.md +1317 -0
  14. package/agent-docs/docs/sdk.md +962 -0
  15. package/agent-docs/docs/session.md +412 -0
  16. package/agent-docs/docs/settings.md +223 -0
  17. package/agent-docs/docs/shell-aliases.md +13 -0
  18. package/agent-docs/docs/skills.md +231 -0
  19. package/agent-docs/docs/terminal-setup.md +70 -0
  20. package/agent-docs/docs/termux.md +127 -0
  21. package/agent-docs/docs/themes.md +295 -0
  22. package/agent-docs/docs/tree.md +219 -0
  23. package/agent-docs/docs/tui.md +887 -0
  24. package/agent-docs/docs/windows.md +17 -0
  25. package/agent-docs/examples/README.md +25 -0
  26. package/agent-docs/examples/extensions/README.md +205 -0
  27. package/agent-docs/examples/extensions/antigravity-image-gen.ts +447 -0
  28. package/agent-docs/examples/extensions/auto-commit-on-exit.ts +49 -0
  29. package/agent-docs/examples/extensions/bash-spawn-hook.ts +30 -0
  30. package/agent-docs/examples/extensions/bookmark.ts +50 -0
  31. package/agent-docs/examples/extensions/built-in-tool-renderer.ts +256 -0
  32. package/agent-docs/examples/extensions/claude-rules.ts +86 -0
  33. package/agent-docs/examples/extensions/commands.ts +75 -0
  34. package/agent-docs/examples/extensions/confirm-destructive.ts +59 -0
  35. package/agent-docs/examples/extensions/custom-compaction.ts +126 -0
  36. package/agent-docs/examples/extensions/custom-footer.ts +63 -0
  37. package/agent-docs/examples/extensions/custom-header.ts +73 -0
  38. package/agent-docs/examples/extensions/custom-provider-anthropic/index.ts +660 -0
  39. package/agent-docs/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  40. package/agent-docs/examples/extensions/custom-provider-anthropic/package.json +19 -0
  41. package/agent-docs/examples/extensions/custom-provider-gitlab-duo/index.ts +362 -0
  42. package/agent-docs/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  43. package/agent-docs/examples/extensions/custom-provider-gitlab-duo/test.ts +88 -0
  44. package/agent-docs/examples/extensions/custom-provider-qwen-cli/index.ts +349 -0
  45. package/agent-docs/examples/extensions/custom-provider-qwen-cli/package.json +16 -0
  46. package/agent-docs/examples/extensions/dirty-repo-guard.ts +56 -0
  47. package/agent-docs/examples/extensions/doom-overlay/README.md +46 -0
  48. package/agent-docs/examples/extensions/doom-overlay/doom/build.sh +152 -0
  49. package/agent-docs/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  50. package/agent-docs/examples/extensions/doom-overlay/doom-component.ts +133 -0
  51. package/agent-docs/examples/extensions/doom-overlay/doom-engine.ts +186 -0
  52. package/agent-docs/examples/extensions/doom-overlay/doom-keys.ts +108 -0
  53. package/agent-docs/examples/extensions/doom-overlay/index.ts +74 -0
  54. package/agent-docs/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  55. package/agent-docs/examples/extensions/dynamic-resources/SKILL.md +8 -0
  56. package/agent-docs/examples/extensions/dynamic-resources/dynamic.json +79 -0
  57. package/agent-docs/examples/extensions/dynamic-resources/dynamic.md +5 -0
  58. package/agent-docs/examples/extensions/dynamic-resources/index.ts +15 -0
  59. package/agent-docs/examples/extensions/dynamic-tools.ts +77 -0
  60. package/agent-docs/examples/extensions/event-bus.ts +43 -0
  61. package/agent-docs/examples/extensions/file-trigger.ts +41 -0
  62. package/agent-docs/examples/extensions/git-checkpoint.ts +53 -0
  63. package/agent-docs/examples/extensions/handoff.ts +155 -0
  64. package/agent-docs/examples/extensions/hello.ts +25 -0
  65. package/agent-docs/examples/extensions/inline-bash.ts +94 -0
  66. package/agent-docs/examples/extensions/input-transform.ts +43 -0
  67. package/agent-docs/examples/extensions/interactive-shell.ts +209 -0
  68. package/agent-docs/examples/extensions/mac-system-theme.ts +47 -0
  69. package/agent-docs/examples/extensions/message-renderer.ts +59 -0
  70. package/agent-docs/examples/extensions/minimal-mode.ts +430 -0
  71. package/agent-docs/examples/extensions/modal-editor.ts +90 -0
  72. package/agent-docs/examples/extensions/model-status.ts +31 -0
  73. package/agent-docs/examples/extensions/notify.ts +55 -0
  74. package/agent-docs/examples/extensions/overlay-qa-tests.ts +936 -0
  75. package/agent-docs/examples/extensions/overlay-test.ts +159 -0
  76. package/agent-docs/examples/extensions/permission-gate.ts +37 -0
  77. package/agent-docs/examples/extensions/pirate.ts +47 -0
  78. package/agent-docs/examples/extensions/plan-mode/README.md +65 -0
  79. package/agent-docs/examples/extensions/plan-mode/index.ts +363 -0
  80. package/agent-docs/examples/extensions/plan-mode/utils.ts +173 -0
  81. package/agent-docs/examples/extensions/preset.ts +418 -0
  82. package/agent-docs/examples/extensions/protected-paths.ts +30 -0
  83. package/agent-docs/examples/extensions/qna.ts +122 -0
  84. package/agent-docs/examples/extensions/question.ts +278 -0
  85. package/agent-docs/examples/extensions/questionnaire.ts +440 -0
  86. package/agent-docs/examples/extensions/rainbow-editor.ts +90 -0
  87. package/agent-docs/examples/extensions/reload-runtime.ts +37 -0
  88. package/agent-docs/examples/extensions/rpc-demo.ts +124 -0
  89. package/agent-docs/examples/extensions/sandbox/index.ts +324 -0
  90. package/agent-docs/examples/extensions/sandbox/package-lock.json +92 -0
  91. package/agent-docs/examples/extensions/sandbox/package.json +19 -0
  92. package/agent-docs/examples/extensions/send-user-message.ts +97 -0
  93. package/agent-docs/examples/extensions/session-name.ts +27 -0
  94. package/agent-docs/examples/extensions/shutdown-command.ts +69 -0
  95. package/agent-docs/examples/extensions/snake.ts +343 -0
  96. package/agent-docs/examples/extensions/space-invaders.ts +566 -0
  97. package/agent-docs/examples/extensions/ssh.ts +233 -0
  98. package/agent-docs/examples/extensions/status-line.ts +40 -0
  99. package/agent-docs/examples/extensions/subagent/README.md +172 -0
  100. package/agent-docs/examples/extensions/subagent/agents/planner.md +37 -0
  101. package/agent-docs/examples/extensions/subagent/agents/reviewer.md +35 -0
  102. package/agent-docs/examples/extensions/subagent/agents/scout.md +50 -0
  103. package/agent-docs/examples/extensions/subagent/agents/worker.md +24 -0
  104. package/agent-docs/examples/extensions/subagent/agents.ts +130 -0
  105. package/agent-docs/examples/extensions/subagent/index.ts +1068 -0
  106. package/agent-docs/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  107. package/agent-docs/examples/extensions/subagent/prompts/implement.md +10 -0
  108. package/agent-docs/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  109. package/agent-docs/examples/extensions/summarize.ts +206 -0
  110. package/agent-docs/examples/extensions/system-prompt-header.ts +17 -0
  111. package/agent-docs/examples/extensions/timed-confirm.ts +72 -0
  112. package/agent-docs/examples/extensions/titlebar-spinner.ts +58 -0
  113. package/agent-docs/examples/extensions/todo.ts +314 -0
  114. package/agent-docs/examples/extensions/tool-override.ts +146 -0
  115. package/agent-docs/examples/extensions/tools.ts +145 -0
  116. package/agent-docs/examples/extensions/trigger-compact.ts +40 -0
  117. package/agent-docs/examples/extensions/truncated-tool.ts +194 -0
  118. package/agent-docs/examples/extensions/widget-placement.ts +17 -0
  119. package/agent-docs/examples/extensions/with-deps/index.ts +37 -0
  120. package/agent-docs/examples/extensions/with-deps/package-lock.json +31 -0
  121. package/agent-docs/examples/extensions/with-deps/package.json +22 -0
  122. package/agent-docs/examples/rpc-extension-ui.ts +654 -0
  123. package/agent-docs/examples/sdk/01-minimal.ts +22 -0
  124. package/agent-docs/examples/sdk/02-custom-model.ts +48 -0
  125. package/agent-docs/examples/sdk/03-custom-prompt.ts +55 -0
  126. package/agent-docs/examples/sdk/04-skills.ts +53 -0
  127. package/agent-docs/examples/sdk/05-tools.ts +56 -0
  128. package/agent-docs/examples/sdk/06-extensions.ts +88 -0
  129. package/agent-docs/examples/sdk/07-context-files.ts +40 -0
  130. package/agent-docs/examples/sdk/08-prompt-templates.ts +47 -0
  131. package/agent-docs/examples/sdk/09-api-keys-and-oauth.ts +48 -0
  132. package/agent-docs/examples/sdk/10-settings.ts +54 -0
  133. package/agent-docs/examples/sdk/11-sessions.ts +48 -0
  134. package/agent-docs/examples/sdk/12-full-control.ts +82 -0
  135. package/agent-docs/examples/sdk/README.md +144 -0
  136. package/agent-docs/xll-skill.md +61 -0
  137. package/agent-docs/xll-spec.md +110 -0
  138. package/dist/cli/args.js +290 -0
  139. package/dist/cli/config-selector.js +31 -0
  140. package/dist/cli/file-processor.js +79 -0
  141. package/dist/cli/list-models.js +92 -0
  142. package/dist/cli/package-commands.js +210 -0
  143. package/dist/cli/report-settings-errors.js +11 -0
  144. package/dist/cli/session-picker.js +34 -0
  145. package/dist/cli.js +19 -0
  146. package/dist/config.js +288 -0
  147. package/dist/core/abort.js +15 -0
  148. package/dist/core/agent-loop.js +352 -0
  149. package/dist/core/agent-session.js +2019 -0
  150. package/dist/core/agent.js +410 -0
  151. package/dist/core/auth-storage.js +456 -0
  152. package/dist/core/bash-executor.js +222 -0
  153. package/dist/core/compaction/branch-summarization.js +242 -0
  154. package/dist/core/compaction/compaction.js +610 -0
  155. package/dist/core/compaction/index.js +7 -0
  156. package/dist/core/compaction/utils.js +139 -0
  157. package/dist/core/defaults.js +6 -0
  158. package/dist/core/diagnostics.js +2 -0
  159. package/dist/core/event-bus.js +25 -0
  160. package/dist/core/exec.js +71 -0
  161. package/dist/core/export-html/ansi-to-html.js +256 -0
  162. package/dist/core/export-html/index.js +238 -0
  163. package/dist/core/export-html/session-view-model.js +342 -0
  164. package/dist/core/export-html/template.css +1110 -0
  165. package/dist/core/export-html/template.html +76 -0
  166. package/dist/core/export-html/template.js +1990 -0
  167. package/dist/core/export-html/tool-renderer.js +63 -0
  168. package/dist/core/export-html/vendor/highlight.min.js +7725 -0
  169. package/dist/core/export-html/vendor/marked.min.js +1803 -0
  170. package/dist/core/extensions/index.js +9 -0
  171. package/dist/core/extensions/loader.js +422 -0
  172. package/dist/core/extensions/runner.js +651 -0
  173. package/dist/core/extensions/types.js +35 -0
  174. package/dist/core/extensions/wrapper.js +102 -0
  175. package/dist/core/footer-data-provider.js +162 -0
  176. package/dist/core/index.js +9 -0
  177. package/dist/core/keybindings.js +153 -0
  178. package/dist/core/messages.js +133 -0
  179. package/dist/core/model-registry.js +539 -0
  180. package/dist/core/model-resolver.js +370 -0
  181. package/dist/core/package-manager.js +1485 -0
  182. package/dist/core/prompt-templates.js +253 -0
  183. package/dist/core/resolve-config-value.js +59 -0
  184. package/dist/core/resource-loader.js +700 -0
  185. package/dist/core/sdk.js +197 -0
  186. package/dist/core/session-bash.js +99 -0
  187. package/dist/core/session-compaction.js +165 -0
  188. package/dist/core/session-manager.js +1153 -0
  189. package/dist/core/session-models.js +99 -0
  190. package/dist/core/session-retry.js +155 -0
  191. package/dist/core/settings-manager.js +572 -0
  192. package/dist/core/skills.js +382 -0
  193. package/dist/core/slash-commands.js +31 -0
  194. package/dist/core/system-prompt.js +161 -0
  195. package/dist/core/theme.js +770 -0
  196. package/dist/core/timings.js +26 -0
  197. package/dist/core/tools/bash.js +258 -0
  198. package/dist/core/tools/edit-diff.js +245 -0
  199. package/dist/core/tools/edit.js +148 -0
  200. package/dist/core/tools/find.js +208 -0
  201. package/dist/core/tools/grep.js +246 -0
  202. package/dist/core/tools/index.js +67 -0
  203. package/dist/core/tools/ls.js +123 -0
  204. package/dist/core/tools/path-utils.js +81 -0
  205. package/dist/core/tools/read.js +160 -0
  206. package/dist/core/tools/truncate.js +70 -0
  207. package/dist/core/tools/write.js +82 -0
  208. package/dist/custom/agents/action.js +13 -0
  209. package/dist/custom/agents/document-reader.js +70 -0
  210. package/dist/custom/agents/general.js +26 -0
  211. package/dist/custom/agents/index.js +49 -0
  212. package/dist/custom/agents/installation.js +13 -0
  213. package/dist/custom/agents/types.js +7 -0
  214. package/dist/custom/auth/refresh-timer.js +33 -0
  215. package/dist/custom/auth/shortcut-oauth.js +145 -0
  216. package/dist/custom/constants.js +21 -0
  217. package/dist/custom/context/workbook-summary.js +73 -0
  218. package/dist/custom/credits/shortcut-credits.js +29 -0
  219. package/dist/custom/cron/cron-daemon-entry.js +18 -0
  220. package/dist/custom/cron/daemon-ipc.js +131 -0
  221. package/dist/custom/cron/daemon.js +224 -0
  222. package/dist/custom/cron/jobs.js +226 -0
  223. package/dist/custom/cron/run-log.js +51 -0
  224. package/dist/custom/cron/schedule.js +72 -0
  225. package/dist/custom/cron/status-line.js +98 -0
  226. package/dist/custom/cron/store.js +87 -0
  227. package/dist/custom/cron/types.js +8 -0
  228. package/dist/custom/dev/index.js +59 -0
  229. package/dist/custom/dev/trace-export.js +58 -0
  230. package/dist/custom/ensure-excel.js +63 -0
  231. package/dist/custom/excel-config.js +36 -0
  232. package/dist/custom/preflight.js +422 -0
  233. package/dist/custom/prompts/action.js +100 -0
  234. package/dist/custom/prompts/api.js +66 -0
  235. package/dist/custom/prompts/installation.js +124 -0
  236. package/dist/custom/prompts/shared.js +138 -0
  237. package/dist/custom/providers/llm-usage.js +42 -0
  238. package/dist/custom/providers/message-converter.js +74 -0
  239. package/dist/custom/providers/provider-ids.js +9 -0
  240. package/dist/custom/providers/register-openai-codex-provider.js +27 -0
  241. package/dist/custom/providers/register-shortcut-provider.js +52 -0
  242. package/dist/custom/providers/shortcut-invoke.js +117 -0
  243. package/dist/custom/providers/shortcut-stream.js +252 -0
  244. package/dist/custom/providers/sse-protocol.js +38 -0
  245. package/dist/custom/sync-xll.js +130 -0
  246. package/dist/custom/tools/cron.js +413 -0
  247. package/dist/custom/tools/excel-exec.js +167 -0
  248. package/dist/custom/tools/excel-range.js +50 -0
  249. package/dist/custom/tools/llm-analysis.js +265 -0
  250. package/dist/custom/tools/render-helpers.js +38 -0
  251. package/dist/custom/tools/switch-mode.js +94 -0
  252. package/dist/custom/tools/task/agents.js +6 -0
  253. package/dist/custom/tools/task/index.js +8 -0
  254. package/dist/custom/tools/task/render.js +348 -0
  255. package/dist/custom/tools/task/subprocess.js +320 -0
  256. package/dist/custom/tools/task/task.js +205 -0
  257. package/dist/custom/tools/todo-list.js +195 -0
  258. package/dist/custom/tracing/session-upload.js +93 -0
  259. package/dist/index.js +45 -0
  260. package/dist/main.js +613 -0
  261. package/dist/migrations.js +265 -0
  262. package/dist/modes/index.js +8 -0
  263. package/dist/modes/interactive/components/armin.js +337 -0
  264. package/dist/modes/interactive/components/assistant-message.js +94 -0
  265. package/dist/modes/interactive/components/bash-execution.js +171 -0
  266. package/dist/modes/interactive/components/bordered-loader.js +51 -0
  267. package/dist/modes/interactive/components/branch-summary-message.js +45 -0
  268. package/dist/modes/interactive/components/compaction-summary-message.js +46 -0
  269. package/dist/modes/interactive/components/config-selector.js +488 -0
  270. package/dist/modes/interactive/components/countdown-timer.js +33 -0
  271. package/dist/modes/interactive/components/custom-editor.js +93 -0
  272. package/dist/modes/interactive/components/custom-message.js +81 -0
  273. package/dist/modes/interactive/components/daxnuts.js +140 -0
  274. package/dist/modes/interactive/components/diff.js +133 -0
  275. package/dist/modes/interactive/components/dynamic-border.js +21 -0
  276. package/dist/modes/interactive/components/extension-editor.js +105 -0
  277. package/dist/modes/interactive/components/extension-input.js +61 -0
  278. package/dist/modes/interactive/components/extension-selector.js +78 -0
  279. package/dist/modes/interactive/components/footer.js +309 -0
  280. package/dist/modes/interactive/components/index.js +33 -0
  281. package/dist/modes/interactive/components/keybinding-hints.js +61 -0
  282. package/dist/modes/interactive/components/layout.js +64 -0
  283. package/dist/modes/interactive/components/login-dialog.js +148 -0
  284. package/dist/modes/interactive/components/model-selector.js +237 -0
  285. package/dist/modes/interactive/components/oauth-selector.js +111 -0
  286. package/dist/modes/interactive/components/session-selector-search.js +157 -0
  287. package/dist/modes/interactive/components/session-selector.js +860 -0
  288. package/dist/modes/interactive/components/settings-selector.js +123 -0
  289. package/dist/modes/interactive/components/show-images-selector.js +35 -0
  290. package/dist/modes/interactive/components/skill-invocation-message.js +48 -0
  291. package/dist/modes/interactive/components/theme-selector.js +47 -0
  292. package/dist/modes/interactive/components/thinking-selector.js +47 -0
  293. package/dist/modes/interactive/components/tool-execution.js +789 -0
  294. package/dist/modes/interactive/components/tool-group.js +106 -0
  295. package/dist/modes/interactive/components/tree-selector.js +962 -0
  296. package/dist/modes/interactive/components/user-message-selector.js +115 -0
  297. package/dist/modes/interactive/components/user-message.js +48 -0
  298. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  299. package/dist/modes/interactive/file-attachments.js +135 -0
  300. package/dist/modes/interactive/interactive-mode.js +3775 -0
  301. package/dist/modes/interactive/theme/dark.json +85 -0
  302. package/dist/modes/interactive/theme/light.json +85 -0
  303. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  304. package/dist/modes/interactive/theme/theme.js +177 -0
  305. package/dist/modes/print-mode.js +101 -0
  306. package/dist/modes/rpc/rpc-client.js +387 -0
  307. package/dist/modes/rpc/rpc-mode.js +509 -0
  308. package/dist/modes/rpc/rpc-types.js +8 -0
  309. package/dist/subagent-entry.js +145 -0
  310. package/dist/tool-names.js +34 -0
  311. package/dist/tui/autocomplete.js +596 -0
  312. package/dist/tui/components/box.js +104 -0
  313. package/dist/tui/components/cancellable-loader.js +35 -0
  314. package/dist/tui/components/editor.js +1679 -0
  315. package/dist/tui/components/image.js +69 -0
  316. package/dist/tui/components/input.js +433 -0
  317. package/dist/tui/components/loader.js +49 -0
  318. package/dist/tui/components/markdown.js +629 -0
  319. package/dist/tui/components/select-list.js +152 -0
  320. package/dist/tui/components/settings-list.js +185 -0
  321. package/dist/tui/components/spacer.js +23 -0
  322. package/dist/tui/components/text.js +89 -0
  323. package/dist/tui/components/truncated-text.js +51 -0
  324. package/dist/tui/editor-component.js +2 -0
  325. package/dist/tui/fuzzy.js +107 -0
  326. package/dist/tui/get-east-asian-width/index.js +32 -0
  327. package/dist/tui/get-east-asian-width/lookup.js +404 -0
  328. package/dist/tui/index.js +32 -0
  329. package/dist/tui/keybindings.js +114 -0
  330. package/dist/tui/keys.js +959 -0
  331. package/dist/tui/kill-ring.js +44 -0
  332. package/dist/tui/stdin-buffer.js +317 -0
  333. package/dist/tui/terminal-image.js +288 -0
  334. package/dist/tui/terminal.js +249 -0
  335. package/dist/tui/tui/autocomplete.js +596 -0
  336. package/dist/tui/tui/components/box.js +106 -0
  337. package/dist/tui/tui/components/cancellable-loader.js +35 -0
  338. package/dist/tui/tui/components/editor.js +1679 -0
  339. package/dist/tui/tui/components/image.js +69 -0
  340. package/dist/tui/tui/components/input.js +433 -0
  341. package/dist/tui/tui/components/loader.js +49 -0
  342. package/dist/tui/tui/components/markdown.js +629 -0
  343. package/dist/tui/tui/components/select-list.js +152 -0
  344. package/dist/tui/tui/components/settings-list.js +185 -0
  345. package/dist/tui/tui/components/spacer.js +23 -0
  346. package/dist/tui/tui/components/text.js +91 -0
  347. package/dist/tui/tui/components/truncated-text.js +51 -0
  348. package/dist/tui/tui/editor-component.js +2 -0
  349. package/dist/tui/tui/fuzzy.js +107 -0
  350. package/dist/tui/tui/get-east-asian-width/index.js +32 -0
  351. package/dist/tui/tui/get-east-asian-width/lookup.js +404 -0
  352. package/dist/tui/tui/index.js +32 -0
  353. package/dist/tui/tui/keybindings.js +114 -0
  354. package/dist/tui/tui/keys.js +959 -0
  355. package/dist/tui/tui/kill-ring.js +44 -0
  356. package/dist/tui/tui/stdin-buffer.js +317 -0
  357. package/dist/tui/tui/terminal-image.js +288 -0
  358. package/dist/tui/tui/terminal.js +249 -0
  359. package/dist/tui/tui/tui.js +955 -0
  360. package/dist/tui/tui/undo-stack.js +25 -0
  361. package/dist/tui/tui/utils.js +800 -0
  362. package/dist/tui/tui.js +955 -0
  363. package/dist/tui/undo-stack.js +25 -0
  364. package/dist/tui/utils.js +800 -0
  365. package/dist/utils/changelog.js +87 -0
  366. package/dist/utils/clipboard-image.js +164 -0
  367. package/dist/utils/clipboard-native.js +14 -0
  368. package/dist/utils/clipboard.js +67 -0
  369. package/dist/utils/frontmatter.js +26 -0
  370. package/dist/utils/git.js +166 -0
  371. package/dist/utils/image-convert.js +35 -0
  372. package/dist/utils/image-resize.js +183 -0
  373. package/dist/utils/mime.js +26 -0
  374. package/dist/utils/photon.js +121 -0
  375. package/dist/utils/shell.js +217 -0
  376. package/dist/utils/sleep.js +17 -0
  377. package/dist/utils/tools-manager.js +259 -0
  378. package/package.json +78 -0
  379. package/skills/excel-com-api/SKILL.md +74 -0
  380. package/skills/excel-com-api/excel-type-library.py +27767 -0
  381. package/skills/excel-com-api/office-type-library.py +10867 -0
  382. package/skills/integrations/SKILL.md +138 -0
  383. package/skills/integrations/alphasense.md +457 -0
  384. package/skills/integrations/bloomberg.md +803 -0
  385. package/skills/integrations/calcbench.md +315 -0
  386. package/skills/integrations/capiq.md +848 -0
  387. package/skills/integrations/dynamics-365-finance.md +354 -0
  388. package/skills/integrations/earnings_transcripts.md +387 -0
  389. package/skills/integrations/factset.md +758 -0
  390. package/skills/integrations/ice-fixed-income.md +344 -0
  391. package/skills/integrations/moodys-analytics.md +313 -0
  392. package/skills/integrations/morningstar.md +433 -0
  393. package/skills/integrations/nasdaq-data-link.md +249 -0
  394. package/skills/integrations/pitchbook.md +413 -0
  395. package/skills/integrations/preqin.md +422 -0
  396. package/skills/integrations/quickbooks.md +289 -0
  397. package/skills/integrations/quickfs.md +314 -0
  398. package/skills/integrations/refinitiv.md +473 -0
  399. package/skills/integrations/sage-intacct.md +401 -0
  400. package/skills/integrations/visible-alpha.md +320 -0
  401. package/skills/integrations/xero.md +393 -0
  402. package/skills/integrations/ycharts.md +306 -0
  403. package/skills/pdf-creation/SKILL.md +93 -0
  404. package/skills/pdf-extraction/SKILL.md +32 -0
  405. package/skills/powerpoint-creation/SKILL.md +110 -0
  406. package/skills/sec-edgar/SKILL.md +127 -0
  407. package/skills/sec-edgar/sec_to_pdf.py +109 -0
  408. package/xll/ShortcutXL.xll +0 -0
  409. package/xll/modules/debug_render.py +272 -0
  410. package/xll/modules/gameboy.py +241 -0
  411. package/xll/modules/pong.py +188 -0
  412. package/xll/modules/shortcut_xl/__init__.py +18 -0
  413. package/xll/modules/shortcut_xl/_categorize.py +200 -0
  414. package/xll/modules/shortcut_xl/_com.py +108 -0
  415. package/xll/modules/shortcut_xl/_format.py +252 -0
  416. package/xll/modules/shortcut_xl/_log.py +12 -0
  417. package/xll/modules/shortcut_xl/_managed.py +116 -0
  418. package/xll/modules/shortcut_xl/_registry.py +44 -0
  419. package/xll/modules/shortcut_xl/_threading.py +161 -0
  420. package/xll/modules/shortcut_xl/_tracking.py +283 -0
  421. package/xll/modules/stocks.py +100 -0
  422. package/xll/python3.dll +0 -0
  423. package/xll/python312.dll +0 -0
@@ -0,0 +1,183 @@
1
+ import { loadPhoton } from './photon.js';
2
+ // 4.5MB - provides headroom below Anthropic's 5MB limit
3
+ const DEFAULT_MAX_BYTES = 4.5 * 1024 * 1024;
4
+ const DEFAULT_OPTIONS = {
5
+ maxWidth: 2000,
6
+ maxHeight: 2000,
7
+ maxBytes: DEFAULT_MAX_BYTES,
8
+ jpegQuality: 80
9
+ };
10
+ /** Helper to pick the smaller of two buffers */
11
+ function pickSmaller(a, b) {
12
+ return a.buffer.length <= b.buffer.length ? a : b;
13
+ }
14
+ /**
15
+ * Resize an image to fit within the specified max dimensions and file size.
16
+ * Returns the original image if it already fits within the limits.
17
+ *
18
+ * Uses Photon (Rust/WASM) for image processing. If Photon is not available,
19
+ * returns the original image unchanged.
20
+ *
21
+ * Strategy for staying under maxBytes:
22
+ * 1. First resize to maxWidth/maxHeight
23
+ * 2. Try both PNG and JPEG formats, pick the smaller one
24
+ * 3. If still too large, try JPEG with decreasing quality
25
+ * 4. If still too large, progressively reduce dimensions
26
+ */
27
+ export async function resizeImage(img, options) {
28
+ const opts = { ...DEFAULT_OPTIONS, ...options };
29
+ const inputBuffer = Buffer.from(img.data, 'base64');
30
+ const photon = await loadPhoton();
31
+ if (!photon) {
32
+ // Photon not available, return original image
33
+ return {
34
+ data: img.data,
35
+ mimeType: img.mimeType,
36
+ originalWidth: 0,
37
+ originalHeight: 0,
38
+ width: 0,
39
+ height: 0,
40
+ wasResized: false
41
+ };
42
+ }
43
+ let image;
44
+ try {
45
+ image = photon.PhotonImage.new_from_byteslice(new Uint8Array(inputBuffer));
46
+ const originalWidth = image.get_width();
47
+ const originalHeight = image.get_height();
48
+ const format = img.mimeType?.split('/')[1] ?? 'png';
49
+ // Check if already within all limits (dimensions AND size)
50
+ const originalSize = inputBuffer.length;
51
+ if (originalWidth <= opts.maxWidth &&
52
+ originalHeight <= opts.maxHeight &&
53
+ originalSize <= opts.maxBytes) {
54
+ return {
55
+ data: img.data,
56
+ mimeType: img.mimeType ?? `image/${format}`,
57
+ originalWidth,
58
+ originalHeight,
59
+ width: originalWidth,
60
+ height: originalHeight,
61
+ wasResized: false
62
+ };
63
+ }
64
+ // Calculate initial dimensions respecting max limits
65
+ let targetWidth = originalWidth;
66
+ let targetHeight = originalHeight;
67
+ if (targetWidth > opts.maxWidth) {
68
+ targetHeight = Math.round((targetHeight * opts.maxWidth) / targetWidth);
69
+ targetWidth = opts.maxWidth;
70
+ }
71
+ if (targetHeight > opts.maxHeight) {
72
+ targetWidth = Math.round((targetWidth * opts.maxHeight) / targetHeight);
73
+ targetHeight = opts.maxHeight;
74
+ }
75
+ // Helper to resize and encode in both formats, returning the smaller one
76
+ function tryBothFormats(width, height, jpegQuality) {
77
+ const resized = photon.resize(image, width, height, photon.SamplingFilter.Lanczos3);
78
+ try {
79
+ const pngBuffer = resized.get_bytes();
80
+ const jpegBuffer = resized.get_bytes_jpeg(jpegQuality);
81
+ return pickSmaller({ buffer: pngBuffer, mimeType: 'image/png' }, { buffer: jpegBuffer, mimeType: 'image/jpeg' });
82
+ }
83
+ finally {
84
+ resized.free();
85
+ }
86
+ }
87
+ // Try to produce an image under maxBytes
88
+ const qualitySteps = [85, 70, 55, 40];
89
+ const scaleSteps = [1.0, 0.75, 0.5, 0.35, 0.25];
90
+ let best;
91
+ let finalWidth = targetWidth;
92
+ let finalHeight = targetHeight;
93
+ // First attempt: resize to target dimensions, try both formats
94
+ best = tryBothFormats(targetWidth, targetHeight, opts.jpegQuality);
95
+ if (best.buffer.length <= opts.maxBytes) {
96
+ return {
97
+ data: Buffer.from(best.buffer).toString('base64'),
98
+ mimeType: best.mimeType,
99
+ originalWidth,
100
+ originalHeight,
101
+ width: finalWidth,
102
+ height: finalHeight,
103
+ wasResized: true
104
+ };
105
+ }
106
+ // Still too large - try JPEG with decreasing quality
107
+ for (const quality of qualitySteps) {
108
+ best = tryBothFormats(targetWidth, targetHeight, quality);
109
+ if (best.buffer.length <= opts.maxBytes) {
110
+ return {
111
+ data: Buffer.from(best.buffer).toString('base64'),
112
+ mimeType: best.mimeType,
113
+ originalWidth,
114
+ originalHeight,
115
+ width: finalWidth,
116
+ height: finalHeight,
117
+ wasResized: true
118
+ };
119
+ }
120
+ }
121
+ // Still too large - reduce dimensions progressively
122
+ for (const scale of scaleSteps) {
123
+ finalWidth = Math.round(targetWidth * scale);
124
+ finalHeight = Math.round(targetHeight * scale);
125
+ if (finalWidth < 100 || finalHeight < 100) {
126
+ break;
127
+ }
128
+ for (const quality of qualitySteps) {
129
+ best = tryBothFormats(finalWidth, finalHeight, quality);
130
+ if (best.buffer.length <= opts.maxBytes) {
131
+ return {
132
+ data: Buffer.from(best.buffer).toString('base64'),
133
+ mimeType: best.mimeType,
134
+ originalWidth,
135
+ originalHeight,
136
+ width: finalWidth,
137
+ height: finalHeight,
138
+ wasResized: true
139
+ };
140
+ }
141
+ }
142
+ }
143
+ // Last resort: return smallest version we produced
144
+ return {
145
+ data: Buffer.from(best.buffer).toString('base64'),
146
+ mimeType: best.mimeType,
147
+ originalWidth,
148
+ originalHeight,
149
+ width: finalWidth,
150
+ height: finalHeight,
151
+ wasResized: true
152
+ };
153
+ }
154
+ catch {
155
+ // Failed to load image
156
+ return {
157
+ data: img.data,
158
+ mimeType: img.mimeType,
159
+ originalWidth: 0,
160
+ originalHeight: 0,
161
+ width: 0,
162
+ height: 0,
163
+ wasResized: false
164
+ };
165
+ }
166
+ finally {
167
+ if (image) {
168
+ image.free();
169
+ }
170
+ }
171
+ }
172
+ /**
173
+ * Format a dimension note for resized images.
174
+ * This helps the model understand the coordinate mapping.
175
+ */
176
+ export function formatDimensionNote(result) {
177
+ if (!result.wasResized) {
178
+ return undefined;
179
+ }
180
+ const scale = result.originalWidth / result.width;
181
+ return `[Image: original ${result.originalWidth}x${result.originalHeight}, displayed at ${result.width}x${result.height}. Multiply coordinates by ${scale.toFixed(2)} to map to original image.]`;
182
+ }
183
+ //# sourceMappingURL=image-resize.js.map
@@ -0,0 +1,26 @@
1
+ import { fileTypeFromBuffer } from 'file-type';
2
+ import { open } from 'node:fs/promises';
3
+ const IMAGE_MIME_TYPES = new Set(['image/jpeg', 'image/png', 'image/gif', 'image/webp']);
4
+ const FILE_TYPE_SNIFF_BYTES = 4100;
5
+ export async function detectSupportedImageMimeTypeFromFile(filePath) {
6
+ const fileHandle = await open(filePath, 'r');
7
+ try {
8
+ const buffer = Buffer.alloc(FILE_TYPE_SNIFF_BYTES);
9
+ const { bytesRead } = await fileHandle.read(buffer, 0, FILE_TYPE_SNIFF_BYTES, 0);
10
+ if (bytesRead === 0) {
11
+ return null;
12
+ }
13
+ const fileType = await fileTypeFromBuffer(buffer.subarray(0, bytesRead));
14
+ if (!fileType) {
15
+ return null;
16
+ }
17
+ if (!IMAGE_MIME_TYPES.has(fileType.mime)) {
18
+ return null;
19
+ }
20
+ return fileType.mime;
21
+ }
22
+ finally {
23
+ await fileHandle.close();
24
+ }
25
+ }
26
+ //# sourceMappingURL=mime.js.map
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Photon image processing wrapper.
3
+ *
4
+ * This module provides a unified interface to @silvia-odwyer/photon-node that works in:
5
+ * 1. Node.js (development, npm run build)
6
+ * 2. Bun compiled binaries (standalone distribution)
7
+ *
8
+ * The challenge: photon-node's CJS entry uses fs.readFileSync(__dirname + '/photon_rs_bg.wasm')
9
+ * which bakes the build machine's absolute path into Bun compiled binaries.
10
+ *
11
+ * Solution:
12
+ * 1. Patch fs.readFileSync to redirect missing photon_rs_bg.wasm reads
13
+ * 2. Copy photon_rs_bg.wasm next to the executable in build:binary
14
+ */
15
+ import { createRequire } from 'module';
16
+ import * as path from 'path';
17
+ import { fileURLToPath } from 'url';
18
+ const require = createRequire(import.meta.url);
19
+ const fs = require('fs');
20
+ const WASM_FILENAME = 'photon_rs_bg.wasm';
21
+ // Lazy-loaded photon module
22
+ let photonModule = null;
23
+ let loadPromise = null;
24
+ function pathOrNull(file) {
25
+ if (typeof file === 'string') {
26
+ return file;
27
+ }
28
+ if (file instanceof URL) {
29
+ return fileURLToPath(file);
30
+ }
31
+ return null;
32
+ }
33
+ function getFallbackWasmPaths() {
34
+ const execDir = path.dirname(process.execPath);
35
+ return [
36
+ path.join(execDir, WASM_FILENAME),
37
+ path.join(execDir, 'photon', WASM_FILENAME),
38
+ path.join(process.cwd(), WASM_FILENAME)
39
+ ];
40
+ }
41
+ function patchPhotonWasmRead() {
42
+ const originalReadFileSync = fs.readFileSync.bind(fs);
43
+ const fallbackPaths = getFallbackWasmPaths();
44
+ const mutableFs = fs;
45
+ const patchedReadFileSync = ((...args) => {
46
+ const [file, options] = args;
47
+ const resolvedPath = pathOrNull(file);
48
+ if (resolvedPath?.endsWith(WASM_FILENAME)) {
49
+ try {
50
+ return originalReadFileSync(...args);
51
+ }
52
+ catch (error) {
53
+ const err = error;
54
+ if (err?.code && err.code !== 'ENOENT') {
55
+ throw error;
56
+ }
57
+ for (const fallbackPath of fallbackPaths) {
58
+ if (!fs.existsSync(fallbackPath)) {
59
+ continue;
60
+ }
61
+ if (options === undefined) {
62
+ return originalReadFileSync(fallbackPath);
63
+ }
64
+ return originalReadFileSync(fallbackPath, options);
65
+ }
66
+ throw error;
67
+ }
68
+ }
69
+ return originalReadFileSync(...args);
70
+ });
71
+ try {
72
+ mutableFs.readFileSync = patchedReadFileSync;
73
+ }
74
+ catch {
75
+ Object.defineProperty(fs, 'readFileSync', {
76
+ value: patchedReadFileSync,
77
+ writable: true,
78
+ configurable: true
79
+ });
80
+ }
81
+ return () => {
82
+ try {
83
+ mutableFs.readFileSync = originalReadFileSync;
84
+ }
85
+ catch {
86
+ Object.defineProperty(fs, 'readFileSync', {
87
+ value: originalReadFileSync,
88
+ writable: true,
89
+ configurable: true
90
+ });
91
+ }
92
+ };
93
+ }
94
+ /**
95
+ * Load the photon module asynchronously.
96
+ * Returns cached module on subsequent calls.
97
+ */
98
+ export async function loadPhoton() {
99
+ if (photonModule) {
100
+ return photonModule;
101
+ }
102
+ if (loadPromise) {
103
+ return loadPromise;
104
+ }
105
+ loadPromise = (async () => {
106
+ const restoreReadFileSync = patchPhotonWasmRead();
107
+ try {
108
+ photonModule = await import('@silvia-odwyer/photon-node');
109
+ return photonModule;
110
+ }
111
+ catch {
112
+ photonModule = null;
113
+ return photonModule;
114
+ }
115
+ finally {
116
+ restoreReadFileSync();
117
+ }
118
+ })();
119
+ return loadPromise;
120
+ }
121
+ //# sourceMappingURL=photon.js.map
@@ -0,0 +1,217 @@
1
+ import { spawn, spawnSync } from 'child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { delimiter } from 'node:path';
4
+ import { getBinDir, getSettingsPath } from '../config.js';
5
+ let cachedShellConfig = null;
6
+ /**
7
+ * Clear cached shell config so the next getShellConfig() call re-detects.
8
+ * Call after installing Git so subsequent commands use the new bash.
9
+ */
10
+ export function resetShellConfig() {
11
+ cachedShellConfig = null;
12
+ }
13
+ /**
14
+ * Find bash executable on PATH (cross-platform)
15
+ */
16
+ /**
17
+ * Verify a bash executable actually works by running a simple command.
18
+ * Guards against WSL stubs that fall back to cmd.exe when WSL isn't configured.
19
+ */
20
+ function isBashWorking(bashPath) {
21
+ try {
22
+ const result = spawnSync(bashPath, ['-c', 'echo __bash_ok__'], {
23
+ encoding: 'utf-8',
24
+ timeout: 5000,
25
+ stdio: ['ignore', 'pipe', 'pipe']
26
+ });
27
+ return result.status === 0 && result.stdout.includes('__bash_ok__');
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ }
33
+ function findBashOnPath() {
34
+ if (process.platform === 'win32') {
35
+ // Windows: Use 'where' and verify file exists (where can return non-existent paths)
36
+ try {
37
+ const result = spawnSync('where', ['bash.exe'], { encoding: 'utf-8', timeout: 5000 });
38
+ if (result.status === 0 && result.stdout) {
39
+ // Try each match — skip WSL stubs and broken installs
40
+ for (const match of result.stdout.trim().split(/\r?\n/)) {
41
+ const trimmed = match.trim();
42
+ if (trimmed && existsSync(trimmed) && isBashWorking(trimmed)) {
43
+ return trimmed;
44
+ }
45
+ }
46
+ }
47
+ }
48
+ catch {
49
+ // Ignore errors
50
+ }
51
+ return null;
52
+ }
53
+ // Unix: Use 'which' and trust its output (handles Termux and special filesystems)
54
+ try {
55
+ const result = spawnSync('which', ['bash'], { encoding: 'utf-8', timeout: 5000 });
56
+ if (result.status === 0 && result.stdout) {
57
+ const firstMatch = result.stdout.trim().split(/\r?\n/)[0];
58
+ if (firstMatch) {
59
+ return firstMatch;
60
+ }
61
+ }
62
+ }
63
+ catch {
64
+ // Ignore errors
65
+ }
66
+ return null;
67
+ }
68
+ /**
69
+ * Get shell configuration based on platform.
70
+ * Resolution order:
71
+ * 1. User-specified shellPath in settings.json
72
+ * 2. On Windows: Git Bash in known locations, then bash on PATH
73
+ * 3. On Unix: /bin/bash, then bash on PATH, then fallback to sh
74
+ */
75
+ export function getShellConfig(customShellPath) {
76
+ if (cachedShellConfig) {
77
+ return cachedShellConfig;
78
+ }
79
+ // 1. Check user-specified shell path
80
+ if (customShellPath) {
81
+ // Reject cmd.exe / powershell — the bash tool requires a POSIX shell
82
+ const shellBasename = customShellPath.replace(/.*[/\\]/, '').toLowerCase();
83
+ if (['cmd.exe', 'cmd', 'powershell.exe', 'powershell', 'pwsh.exe', 'pwsh'].includes(shellBasename)) {
84
+ throw new Error(`shellPath is set to "${customShellPath}" but Shortcut requires a bash-compatible shell.\n` +
85
+ `Please remove shellPath from ${getSettingsPath()} or set it to a bash executable.\n` +
86
+ `Install Git for Windows if needed: https://git-scm.com/download/win`);
87
+ }
88
+ if (existsSync(customShellPath)) {
89
+ cachedShellConfig = { shell: customShellPath, args: ['-c'] };
90
+ return cachedShellConfig;
91
+ }
92
+ throw new Error(`Custom shell path not found: ${customShellPath}\nPlease update shellPath in ${getSettingsPath()}`);
93
+ }
94
+ if (process.platform === 'win32') {
95
+ // 2. Try Git Bash in known locations
96
+ const paths = [];
97
+ const programFiles = process.env.ProgramFiles;
98
+ if (programFiles) {
99
+ paths.push(`${programFiles}\\Git\\bin\\bash.exe`);
100
+ }
101
+ const programFilesX86 = process.env['ProgramFiles(x86)'];
102
+ if (programFilesX86) {
103
+ paths.push(`${programFilesX86}\\Git\\bin\\bash.exe`);
104
+ }
105
+ for (const path of paths) {
106
+ if (existsSync(path)) {
107
+ cachedShellConfig = { shell: path, args: ['-c'] };
108
+ return cachedShellConfig;
109
+ }
110
+ }
111
+ // 3. Fallback: search bash.exe on PATH (Cygwin, MSYS2, WSL, etc.)
112
+ const bashOnPath = findBashOnPath();
113
+ if (bashOnPath) {
114
+ cachedShellConfig = { shell: bashOnPath, args: ['-c'] };
115
+ return cachedShellConfig;
116
+ }
117
+ // 4. No bash at all — fall back to cmd.exe for bootstrapping.
118
+ // Do NOT cache this result so we auto-detect bash once Git is installed.
119
+ return { shell: 'cmd.exe', args: ['/c'] };
120
+ }
121
+ // Unix: try /bin/bash, then bash on PATH, then fallback to sh
122
+ if (existsSync('/bin/bash')) {
123
+ cachedShellConfig = { shell: '/bin/bash', args: ['-c'] };
124
+ return cachedShellConfig;
125
+ }
126
+ const bashOnPath = findBashOnPath();
127
+ if (bashOnPath) {
128
+ cachedShellConfig = { shell: bashOnPath, args: ['-c'] };
129
+ return cachedShellConfig;
130
+ }
131
+ cachedShellConfig = { shell: 'sh', args: ['-c'] };
132
+ return cachedShellConfig;
133
+ }
134
+ export function getShellEnv() {
135
+ const binDir = getBinDir();
136
+ const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === 'path') ?? 'PATH';
137
+ const currentPath = process.env[pathKey] ?? '';
138
+ const pathEntries = currentPath.split(delimiter).filter(Boolean);
139
+ const hasBinDir = pathEntries.includes(binDir);
140
+ const updatedPath = hasBinDir
141
+ ? currentPath
142
+ : [binDir, currentPath].filter(Boolean).join(delimiter);
143
+ return {
144
+ ...process.env,
145
+ [pathKey]: updatedPath
146
+ };
147
+ }
148
+ /**
149
+ * Sanitize binary output for display/storage.
150
+ * Removes characters that crash string-width or cause display issues:
151
+ * - Control characters (except tab, newline, carriage return)
152
+ * - Lone surrogates
153
+ * - Unicode Format characters (crash string-width due to a bug)
154
+ * - Characters with undefined code points
155
+ */
156
+ export function sanitizeBinaryOutput(str) {
157
+ // Use Array.from to properly iterate over code points (not code units)
158
+ // This handles surrogate pairs correctly and catches edge cases where
159
+ // codePointAt() might return undefined
160
+ return Array.from(str)
161
+ .filter((char) => {
162
+ // Filter out characters that cause string-width to crash
163
+ // This includes:
164
+ // - Unicode format characters
165
+ // - Lone surrogates (already filtered by Array.from)
166
+ // - Control chars except \t \n \r
167
+ // - Characters with undefined code points
168
+ const code = char.codePointAt(0);
169
+ // Skip if code point is undefined (edge case with invalid strings)
170
+ if (code === undefined)
171
+ return false;
172
+ // Allow tab, newline, carriage return
173
+ if (code === 0x09 || code === 0x0a || code === 0x0d)
174
+ return true;
175
+ // Filter out control characters (0x00-0x1F, except 0x09, 0x0a, 0x0x0d)
176
+ if (code <= 0x1f)
177
+ return false;
178
+ // Filter out Unicode format characters
179
+ if (code >= 0xfff9 && code <= 0xfffb)
180
+ return false;
181
+ return true;
182
+ })
183
+ .join('');
184
+ }
185
+ /**
186
+ * Kill a process and all its children (cross-platform)
187
+ */
188
+ export function killProcessTree(pid) {
189
+ if (process.platform === 'win32') {
190
+ // Use taskkill on Windows to kill process tree
191
+ try {
192
+ spawn('taskkill', ['/F', '/T', '/PID', String(pid)], {
193
+ stdio: 'ignore',
194
+ detached: true
195
+ });
196
+ }
197
+ catch {
198
+ // Ignore errors if taskkill fails
199
+ }
200
+ }
201
+ else {
202
+ // Use SIGKILL on Unix/Linux/Mac
203
+ try {
204
+ process.kill(-pid, 'SIGKILL');
205
+ }
206
+ catch {
207
+ // Fallback to killing just the child if process group kill fails
208
+ try {
209
+ process.kill(pid, 'SIGKILL');
210
+ }
211
+ catch {
212
+ // Process already dead
213
+ }
214
+ }
215
+ }
216
+ }
217
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Sleep helper that respects abort signal.
3
+ */
4
+ export function sleep(ms, signal) {
5
+ return new Promise((resolve, reject) => {
6
+ if (signal?.aborted) {
7
+ reject(new Error('Aborted'));
8
+ return;
9
+ }
10
+ const timeout = setTimeout(resolve, ms);
11
+ signal?.addEventListener('abort', () => {
12
+ clearTimeout(timeout);
13
+ reject(new Error('Aborted'));
14
+ });
15
+ });
16
+ }
17
+ //# sourceMappingURL=sleep.js.map