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,348 @@
1
+ /**
2
+ * TUI rendering for the task tool.
3
+ *
4
+ * Pure display functions — no I/O, no subprocess knowledge.
5
+ * Takes typed data, returns pi-tui Components.
6
+ */
7
+ import { ABORT_UI_LABEL_INLINE } from '../../../core/abort.js';
8
+ import { Text } from '../../../tui/index.js';
9
+ // ---------------------------------------------------------------------------
10
+ // Formatting helpers (pure functions, exported for testing)
11
+ // ---------------------------------------------------------------------------
12
+ export function formatTokens(count) {
13
+ if (count < 1_000)
14
+ return count.toString();
15
+ // Upper bound is 9_950 so that toFixed(1) never rounds up to "10.0k"
16
+ // (9_949 → "9.9k", 9_950 would → "10.0k" which collides with the rounded tier).
17
+ if (count < 9_950)
18
+ return `${(count / 1_000).toFixed(1)}k`;
19
+ if (count < 1_000_000)
20
+ return `${Math.round(count / 1_000)}k`;
21
+ return `${(count / 1_000_000).toFixed(1)}M`;
22
+ }
23
+ /**
24
+ * Format usage stats for display.
25
+ *
26
+ * When contextWindow is provided, shows "X% context used" instead of $cost
27
+ * (appropriate for credit-based models like shortcut-opus where cost is meaningless).
28
+ */
29
+ export function formatUsage(usage, model, contextWindow, toolCallCount) {
30
+ const parts = [];
31
+ if (toolCallCount)
32
+ parts.push(`${toolCallCount} step${toolCallCount > 1 ? 's' : ''}`);
33
+ if (usage.input)
34
+ parts.push(`↑${formatTokens(usage.input)}`);
35
+ if (usage.output)
36
+ parts.push(`↓${formatTokens(usage.output)}`);
37
+ // Show context % instead of cost when we have a context window
38
+ if (contextWindow && contextWindow > 0 && usage.lastTurnInput > 0) {
39
+ const percent = (usage.lastTurnInput / contextWindow) * 100;
40
+ parts.push(`${percent.toFixed(1)}% context used`);
41
+ }
42
+ else if (!contextWindow && usage.cost) {
43
+ // Fallback: show cost only when no context window info
44
+ parts.push(`$${usage.cost.toFixed(4)}`);
45
+ }
46
+ if (model)
47
+ parts.push(model);
48
+ return parts.join(' ');
49
+ }
50
+ const MAX_TOOL_DESC = 50;
51
+ function truncate(s, max) {
52
+ return s.length > max ? s.slice(0, max) + '...' : s;
53
+ }
54
+ /**
55
+ * Format a tool call for display in the task result.
56
+ *
57
+ * bash and excel_exec show a short description (up to 50 chars).
58
+ * read/write/edit are omitted (returns null) — not useful in task context.
59
+ */
60
+ export function formatToolCall(tc) {
61
+ switch (tc.name) {
62
+ case 'bash': {
63
+ const desc = tc.args.description;
64
+ if (desc)
65
+ return `$ ${truncate(desc, MAX_TOOL_DESC)}`;
66
+ const cmd = tc.args.command ?? '...';
67
+ return `$ ${truncate(cmd, MAX_TOOL_DESC)}`;
68
+ }
69
+ case 'excel_exec': {
70
+ const desc = tc.args.description ?? '';
71
+ return `𝕏 ${truncate(desc || '(code)', MAX_TOOL_DESC)}`;
72
+ }
73
+ case 'read':
74
+ case 'write':
75
+ case 'edit':
76
+ return null;
77
+ default: {
78
+ const argsStr = JSON.stringify(tc.args);
79
+ return `${tc.name} ${truncate(argsStr, MAX_TOOL_DESC)}`;
80
+ }
81
+ }
82
+ }
83
+ /** Resolve the icon, label, and color for a completed (non-running) task state. */
84
+ function taskStatus(isError, isAborted, theme) {
85
+ if (isError)
86
+ return { icon: theme.fg('error', '✗'), word: 'failed', color: 'error' };
87
+ if (isAborted)
88
+ return { icon: theme.fg('warning', '⊘'), word: ABORT_UI_LABEL_INLINE, color: 'warning' };
89
+ return { icon: theme.fg('success', '✓'), word: 'done', color: 'success' };
90
+ }
91
+ /** Max length for the query preview in the header */
92
+ const MAX_QUERY_PREVIEW = 120;
93
+ /**
94
+ * Render the task tool call header (shown while running / before result).
95
+ *
96
+ * Collapsed: name + truncated single-line query
97
+ * Expanded: name + full query
98
+ */
99
+ export function renderTaskCall(data, expanded, theme) {
100
+ const title = theme.fg('toolTitle', theme.bold(data.name || 'task'));
101
+ if (data.query) {
102
+ if (expanded) {
103
+ return new Text(`${title}\n${theme.fg('text', data.query)}`, 0, 0);
104
+ }
105
+ // Collapsed: first line, truncated
106
+ const firstLine = data.query.split('\n')[0] ?? '';
107
+ const preview = firstLine.length > MAX_QUERY_PREVIEW
108
+ ? firstLine.slice(0, MAX_QUERY_PREVIEW) + '...'
109
+ : firstLine;
110
+ return new Text(`${title}\n${theme.fg('text', preview)}`, 0, 0);
111
+ }
112
+ return new Text(title, 0, 0);
113
+ }
114
+ /**
115
+ * Get the "currently doing" description from the latest tool call.
116
+ * Walks backwards to find the last displayable tool call.
117
+ */
118
+ export function getCurrentActivity(toolCalls) {
119
+ for (let i = toolCalls.length - 1; i >= 0; i--) {
120
+ const formatted = formatToolCall(toolCalls[i]);
121
+ if (formatted)
122
+ return formatted;
123
+ }
124
+ return null;
125
+ }
126
+ /**
127
+ * Render the task tool result.
128
+ *
129
+ * Collapsed: compact 1-line status — "currently doing: X" or "✓ done"
130
+ * Expanded: full details — all tool calls, output text, usage stats
131
+ */
132
+ export function renderTaskResult(data, expanded, theme) {
133
+ const icon = data.isRunning
134
+ ? ' '
135
+ : data.isError
136
+ ? theme.fg('error', '✗')
137
+ : theme.fg('success', '✓');
138
+ // ── Collapsed view: compact single-line status ──────────────────────
139
+ if (!expanded) {
140
+ if (data.isRunning) {
141
+ const activity = getCurrentActivity(data.toolCalls);
142
+ const activityStr = activity
143
+ ? `${theme.fg('muted', 'currently doing:')} ${theme.fg('toolOutput', activity)}`
144
+ : theme.fg('muted', 'starting...');
145
+ const tcCount = data.toolCalls.length;
146
+ const usageStr = formatUsage(data.usage, undefined, data.contextWindow, tcCount);
147
+ const footer = usageStr ? `\n${theme.fg('dim', usageStr)}` : '';
148
+ return new Text(`${activityStr}${footer}`, 0, 0);
149
+ }
150
+ // Completed (error, aborted, or done)
151
+ const s = taskStatus(data.isError, data.isAborted, theme);
152
+ const errMsg = data.isError && data.errorMessage
153
+ ? ` ${theme.fg('error', truncate(data.errorMessage, 80))}`
154
+ : '';
155
+ const tcCount = data.toolCalls.length;
156
+ const usageStr = formatUsage(data.usage, undefined, data.contextWindow, tcCount);
157
+ const usageSuffix = usageStr ? ` ${theme.fg('dim', usageStr)}` : '';
158
+ return new Text(`${icon} ${theme.fg(s.color, s.word)}${errMsg}${usageSuffix}`, 0, 0);
159
+ }
160
+ // ── Expanded view: full details ─────────────────────────────────────
161
+ const s = data.isRunning ? undefined : taskStatus(data.isError, data.isAborted, theme);
162
+ const statusWord = data.isRunning ? 'running...' : s.word;
163
+ let text = `${icon} ${theme.fg('accent', statusWord)}`;
164
+ // Error message
165
+ if (data.isError && data.errorMessage) {
166
+ text += `\n${theme.fg('error', data.errorMessage)}`;
167
+ }
168
+ // All tool calls
169
+ const calls = data.toolCalls;
170
+ if (calls.length > 0) {
171
+ for (const tc of calls) {
172
+ const formatted = formatToolCall(tc);
173
+ if (formatted) {
174
+ text += `\n${theme.fg('muted', '→ ')}${theme.fg('toolOutput', formatted)}`;
175
+ }
176
+ }
177
+ }
178
+ // Final output text
179
+ if (data.text) {
180
+ text += `\n\n${theme.fg('toolOutput', data.text)}`;
181
+ }
182
+ else if (!data.isRunning && !data.isError) {
183
+ text += `\n${theme.fg('muted', '(no output)')}`;
184
+ }
185
+ // Usage
186
+ const tcCount = data.toolCalls.length;
187
+ const usageStr = formatUsage(data.usage, data.model, data.contextWindow, tcCount);
188
+ if (usageStr) {
189
+ text += `\n${theme.fg('dim', usageStr)}`;
190
+ }
191
+ return new Text(text, 0, 0);
192
+ }
193
+ // ---------------------------------------------------------------------------
194
+ // Grouped rendering (for renderGroup — multiple concurrent tasks as one tree)
195
+ // ---------------------------------------------------------------------------
196
+ // Tree drawing characters — all prefixes are 3 chars wide for alignment
197
+ const BRANCH_MID = '├─ ';
198
+ const BRANCH_END = '└─ ';
199
+ const PIPE_MID = '│ ';
200
+ const PIPE_END = ' ';
201
+ const MAX_GROUP_QUERY_PREVIEW = 100;
202
+ const MAX_EXPANDED_TOOL_CALLS = 15;
203
+ /**
204
+ * Render a group of concurrent task calls as a single tree.
205
+ *
206
+ * Pure function — takes member snapshots from the framework, returns a Component.
207
+ *
208
+ * ✓ General Subagent
209
+ * ├─ Revenue Sheet: Analyze Q3 revenue data...
210
+ * │ ✓ done 18 steps claude-opus-4-6
211
+ * ├─ Income Statement: Build income statement...
212
+ * │ Step 3: >_ Running calculations claude-opus-4-6
213
+ * └─ Format Summary: Apply formatting...
214
+ * ⏳ starting...
215
+ */
216
+ export function renderTaskGroup(members, options, theme) {
217
+ const { expanded } = options;
218
+ const lines = [];
219
+ // Determine agent type from first member's args
220
+ const firstArgs = members[0]?.args;
221
+ const agentType = firstArgs?.subagent_type ?? 'general';
222
+ const agentLabel = formatAgentGroupLabel(agentType, members.length);
223
+ // Header icon: all done or any error; no icon when still running
224
+ const allDone = members.every((m) => !m.isPartial);
225
+ const headerIcon = groupHeaderIcon(members, theme);
226
+ const header = allDone
227
+ ? `${headerIcon} ${theme.fg('toolTitle', theme.bold(agentLabel))}`
228
+ : theme.fg('toolTitle', theme.bold(agentLabel));
229
+ lines.push(header);
230
+ // Tree entries
231
+ for (let i = 0; i < members.length; i++) {
232
+ const member = members[i];
233
+ const isLast = i === members.length - 1;
234
+ const branch = isLast ? BRANCH_END : BRANCH_MID;
235
+ const cont = isLast ? PIPE_END : PIPE_MID;
236
+ const name = member.args?.name || `Agent ${i + 1}`;
237
+ const query = member.args?.query;
238
+ const details = member.result?.details;
239
+ const isRunning = member.isPartial;
240
+ const isError = member.result?.isError ?? false;
241
+ if (expanded) {
242
+ lines.push(...renderGroupEntryExpanded(name, query, details, isRunning, isError, branch, cont, theme));
243
+ }
244
+ else {
245
+ lines.push(...renderGroupEntryCollapsed(name, query, details, isRunning, isError, branch, cont, theme));
246
+ }
247
+ }
248
+ return new Text(lines.join('\n'), 0, 0);
249
+ }
250
+ function groupHeaderIcon(members, theme) {
251
+ const allDone = members.every((m) => !m.isPartial);
252
+ if (!allDone)
253
+ return ' ';
254
+ if (members.some((m) => m.result?.isError))
255
+ return theme.fg('error', '✗');
256
+ return theme.fg('success', '✓');
257
+ }
258
+ function renderGroupEntryCollapsed(name, query, details, isRunning, isError, branch, cont, theme) {
259
+ const line1 = `${theme.fg('dim', branch)}${theme.fg('accent', name)}`;
260
+ const prefix = theme.fg('dim', cont);
261
+ const queryLine = query ? `${prefix}${groupQueryPreview(query, theme)}` : undefined;
262
+ if (isRunning) {
263
+ const stepCount = details?.toolCalls.length ?? 0;
264
+ const activity = details ? getCurrentActivity(details.toolCalls) : null;
265
+ let status;
266
+ if (activity) {
267
+ status = `${theme.fg('muted', `Step ${stepCount}:`)} ${theme.fg('toolOutput', activity)}`;
268
+ }
269
+ else if (stepCount > 0) {
270
+ status = `${theme.fg('muted', `Step ${stepCount}: thinking...`)}`;
271
+ }
272
+ else {
273
+ status = theme.fg('muted', 'starting...');
274
+ }
275
+ const lines = [line1];
276
+ if (queryLine)
277
+ lines.push(queryLine);
278
+ lines.push(`${prefix} ${status}`);
279
+ return lines;
280
+ }
281
+ const s = taskStatus(isError, details?.isAborted, theme);
282
+ const steps = details?.toolCalls.length ?? 0;
283
+ const stepStr = steps > 0 ? ` ${theme.fg('dim', `${steps} step${steps > 1 ? 's' : ''}`)}` : '';
284
+ const lines = [line1];
285
+ if (queryLine)
286
+ lines.push(queryLine);
287
+ lines.push(`${prefix}${s.icon} ${theme.fg(s.color, s.word)}${stepStr}`);
288
+ return lines;
289
+ }
290
+ function renderGroupEntryExpanded(name, query, details, isRunning, isError, branch, cont, theme) {
291
+ const c = theme.fg('dim', cont);
292
+ const lines = [];
293
+ lines.push(`${theme.fg('dim', branch)}${theme.fg('accent', name)}`);
294
+ if (query)
295
+ lines.push(`${c}${groupQueryPreview(query, theme)}`);
296
+ const usageStr = details
297
+ ? formatUsage(details.usage, details.model, details.contextWindow, details.toolCalls.length)
298
+ : '';
299
+ const usageSuffix = usageStr ? ` ${theme.fg('dim', usageStr)}` : '';
300
+ if (isRunning) {
301
+ lines.push(`${c}${theme.fg('accent', 'running...')}${usageSuffix}`);
302
+ }
303
+ else {
304
+ const s = taskStatus(isError, details?.isAborted, theme);
305
+ lines.push(`${c}${s.icon} ${theme.fg('accent', s.word)}${usageSuffix}`);
306
+ }
307
+ if (details) {
308
+ if (isError && details.errorMessage) {
309
+ lines.push(`${c}${theme.fg('error', details.errorMessage)}`);
310
+ }
311
+ const displayCalls = details.toolCalls.slice(-MAX_EXPANDED_TOOL_CALLS);
312
+ if (details.toolCalls.length > MAX_EXPANDED_TOOL_CALLS) {
313
+ lines.push(`${c}${theme.fg('muted', `... (${details.toolCalls.length - MAX_EXPANDED_TOOL_CALLS} earlier steps)`)}`);
314
+ }
315
+ for (const tc of displayCalls) {
316
+ const formatted = formatToolCall(tc);
317
+ if (formatted) {
318
+ lines.push(`${c}${theme.fg('muted', '→ ')}${theme.fg('toolOutput', formatted)}`);
319
+ }
320
+ }
321
+ if (details.text && !isRunning) {
322
+ const outputLines = details.text.split('\n');
323
+ const maxLines = 5;
324
+ for (const line of outputLines.slice(0, maxLines)) {
325
+ lines.push(`${c}${theme.fg('toolOutput', line)}`);
326
+ }
327
+ if (outputLines.length > maxLines) {
328
+ lines.push(`${c}${theme.fg('muted', `... (${outputLines.length - maxLines} more lines)`)}`);
329
+ }
330
+ }
331
+ }
332
+ return lines;
333
+ }
334
+ function groupQueryPreview(query, theme) {
335
+ const firstLine = query.split('\n')[0] ?? '';
336
+ const preview = firstLine.length > MAX_GROUP_QUERY_PREVIEW
337
+ ? firstLine.slice(0, MAX_GROUP_QUERY_PREVIEW) + '...'
338
+ : firstLine;
339
+ return theme.fg('text', preview);
340
+ }
341
+ export function formatAgentTypeLabel(agentType) {
342
+ return agentType.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()) + ' Subagent';
343
+ }
344
+ export function formatAgentGroupLabel(agentType, count) {
345
+ const name = agentType.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
346
+ return `${count} ${name} Agent${count > 1 ? 's' : ''}`;
347
+ }
348
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1,320 @@
1
+ /**
2
+ * Spawn a child agent process in JSON mode and collect structured results.
3
+ *
4
+ * This module is the only place that knows about child_process.
5
+ * It emits a stream of typed events and resolves to a SubagentResult.
6
+ *
7
+ * Zero UI knowledge — callers decide what to do with progress callbacks.
8
+ */
9
+ import { spawn } from 'node:child_process';
10
+ import { mkdtempSync, readdirSync, readFileSync, rmdirSync, unlinkSync, writeFileSync } from 'node:fs';
11
+ import { tmpdir } from 'node:os';
12
+ import { dirname, join } from 'node:path';
13
+ // ---------------------------------------------------------------------------
14
+ // Implementation
15
+ // ---------------------------------------------------------------------------
16
+ function emptyUsage() {
17
+ return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0, lastTurnInput: 0 };
18
+ }
19
+ /**
20
+ * Parse a single JSON event line from the agent's --mode json output.
21
+ * Returns extracted data or null if the line is not relevant.
22
+ */
23
+ export function parseJsonEvent(line) {
24
+ if (!line.trim())
25
+ return null;
26
+ let event;
27
+ try {
28
+ event = JSON.parse(line);
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ // Assistant message completed
34
+ if (event.type === 'message_end' && event.message?.role === 'assistant') {
35
+ const msg = event.message;
36
+ const textParts = [];
37
+ for (const part of msg.content ?? []) {
38
+ if (part.type === 'text')
39
+ textParts.push(part.text);
40
+ }
41
+ const u = msg.usage ?? {};
42
+ return {
43
+ type: 'assistant_message',
44
+ text: textParts.join(''),
45
+ usage: {
46
+ input: u.input ?? 0,
47
+ output: u.output ?? 0,
48
+ cacheRead: u.cacheRead ?? 0,
49
+ cacheWrite: u.cacheWrite ?? 0,
50
+ cost: u.cost?.total ?? 0
51
+ },
52
+ model: msg.model,
53
+ stopReason: msg.stopReason,
54
+ errorMessage: msg.errorMessage
55
+ };
56
+ }
57
+ // Tool call started (we grab the name + args for display)
58
+ if (event.type === 'tool_execution_start') {
59
+ return {
60
+ type: 'tool_call',
61
+ name: event.toolName ?? 'unknown',
62
+ args: event.args ?? {}
63
+ };
64
+ }
65
+ return null;
66
+ }
67
+ /**
68
+ * Write a system prompt to a temp file. Returns the file path.
69
+ * The caller is responsible for cleanup via cleanupTempFile().
70
+ */
71
+ export function writeSystemPromptFile(prompt) {
72
+ const dir = mkdtempSync(join(tmpdir(), 'shortcut-subagent-'));
73
+ const filePath = join(dir, 'system-prompt.md');
74
+ writeFileSync(filePath, prompt, { encoding: 'utf-8', mode: 0o600 });
75
+ return filePath;
76
+ }
77
+ /**
78
+ * Clean up a temp file created by writeSystemPromptFile.
79
+ */
80
+ export function cleanupTempFile(filePath) {
81
+ try {
82
+ unlinkSync(filePath);
83
+ }
84
+ catch {
85
+ /* ignore */
86
+ }
87
+ try {
88
+ rmdirSync(dirname(filePath));
89
+ }
90
+ catch {
91
+ /* ignore */
92
+ }
93
+ }
94
+ /**
95
+ * Spawn a child agent process in JSON mode and collect results.
96
+ *
97
+ * The child runs: <command> --mode json [agentArgs...] "Task: <task>"
98
+ *
99
+ * Each subagent persists its own session JSONL to a temp directory.
100
+ * The session ID is returned in SubagentResult.sessionId for trace linking.
101
+ *
102
+ * JSON events are parsed line-by-line. Progress callbacks fire on each
103
+ * assistant message and tool call.
104
+ */
105
+ export function spawnSubagent(options) {
106
+ const { task, cwd, command, agentArgs = [], signal, onProgress } = options;
107
+ // Each subagent gets its own temp session dir to avoid file lock contention
108
+ const sessionDir = mkdtempSync(join(tmpdir(), 'shortcut-subtrace-'));
109
+ // Write the query to a file to avoid cmd.exe argument splitting on Windows.
110
+ // With shell: true, cmd.exe splits positional args on spaces and mangles
111
+ // special characters (&, |, ^, etc.). Passing a .txt file path (no spaces)
112
+ // as the positional arg sidesteps this entirely. The subagent entry resolves
113
+ // .txt paths to their contents (same pattern as the backend task tool).
114
+ // If the query is already a .txt file path, pass it through directly.
115
+ const trimmedTask = task.trim();
116
+ let taskArg;
117
+ if (trimmedTask.endsWith('.txt') && !trimmedTask.includes(' ')) {
118
+ taskArg = trimmedTask;
119
+ }
120
+ else {
121
+ const taskFile = join(sessionDir, 'query.txt');
122
+ writeFileSync(taskFile, `Task: ${task}`, { encoding: 'utf-8', mode: 0o600 });
123
+ taskArg = taskFile;
124
+ }
125
+ const [bin, ...binPrefixArgs] = command;
126
+ const args = [
127
+ ...binPrefixArgs,
128
+ '--subagent',
129
+ '--mode',
130
+ 'json',
131
+ '--session-dir',
132
+ sessionDir,
133
+ ...agentArgs,
134
+ taskArg
135
+ ];
136
+ return new Promise((resolve) => {
137
+ const proc = spawn(bin, args, {
138
+ cwd,
139
+ shell: process.platform === 'win32',
140
+ stdio: ['ignore', 'pipe', 'pipe']
141
+ });
142
+ const usage = emptyUsage();
143
+ const toolCalls = [];
144
+ let lastText = '';
145
+ let model;
146
+ let stopReason;
147
+ let errorMessage;
148
+ let stderr = '';
149
+ let buffer = '';
150
+ let wasAborted = false;
151
+ const emitProgress = () => {
152
+ onProgress?.({
153
+ text: lastText,
154
+ toolCalls: [...toolCalls],
155
+ usage: { ...usage },
156
+ model
157
+ });
158
+ };
159
+ const processLine = (line) => {
160
+ const parsed = parseJsonEvent(line);
161
+ if (!parsed)
162
+ return;
163
+ if (parsed.type === 'assistant_message') {
164
+ lastText = parsed.text;
165
+ usage.turns++;
166
+ usage.input += parsed.usage.input ?? 0;
167
+ usage.output += parsed.usage.output ?? 0;
168
+ usage.cacheRead += parsed.usage.cacheRead ?? 0;
169
+ usage.cacheWrite += parsed.usage.cacheWrite ?? 0;
170
+ usage.cost += parsed.usage.cost ?? 0;
171
+ usage.lastTurnInput = parsed.usage.input ?? 0;
172
+ if (parsed.model)
173
+ model = parsed.model;
174
+ if (parsed.stopReason)
175
+ stopReason = parsed.stopReason;
176
+ if (parsed.errorMessage)
177
+ errorMessage = parsed.errorMessage;
178
+ emitProgress();
179
+ }
180
+ if (parsed.type === 'tool_call') {
181
+ toolCalls.push({ name: parsed.name, args: parsed.args });
182
+ emitProgress();
183
+ }
184
+ };
185
+ proc.stdout.on('data', (data) => {
186
+ buffer += data.toString();
187
+ const lines = buffer.split('\n');
188
+ buffer = lines.pop() || '';
189
+ for (const line of lines)
190
+ processLine(line);
191
+ });
192
+ proc.stderr.on('data', (data) => {
193
+ stderr += data.toString();
194
+ });
195
+ proc.on('close', (code) => {
196
+ if (buffer.trim())
197
+ processLine(buffer);
198
+ // Read subagent session ID and file path from the persisted JSONL
199
+ let sessionId;
200
+ let sessionFile;
201
+ try {
202
+ const files = readdirSync(sessionDir).filter((f) => f.endsWith('.jsonl'));
203
+ if (files.length > 0) {
204
+ sessionFile = join(sessionDir, files[0]);
205
+ const firstLine = readFileSync(sessionFile, 'utf-8').split('\n')[0];
206
+ const header = JSON.parse(firstLine);
207
+ if (header.type === 'session')
208
+ sessionId = header.id;
209
+ }
210
+ }
211
+ catch {
212
+ /* ignore — session may not have been written */
213
+ }
214
+ resolve({
215
+ text: lastText,
216
+ toolCalls,
217
+ usage,
218
+ model,
219
+ exitCode: code ?? (wasAborted ? 130 : 1),
220
+ stderr,
221
+ stopReason,
222
+ errorMessage,
223
+ aborted: wasAborted,
224
+ sessionId,
225
+ sessionFile
226
+ });
227
+ });
228
+ proc.on('error', (err) => {
229
+ resolve({
230
+ text: lastText,
231
+ toolCalls,
232
+ usage,
233
+ model,
234
+ exitCode: 1,
235
+ stderr: stderr || `Failed to spawn process: ${err.message}`,
236
+ stopReason: 'error',
237
+ errorMessage: `Failed to spawn process: ${err.message}`
238
+ });
239
+ });
240
+ // Cancellation
241
+ if (signal) {
242
+ const killProc = () => {
243
+ wasAborted = true;
244
+ if (process.platform === 'win32' && proc.pid) {
245
+ // On Windows, shell: true means proc is cmd.exe — SIGTERM only kills
246
+ // the shell, not the child node process. Use taskkill /T to kill the
247
+ // entire process tree.
248
+ spawn('taskkill', ['/T', '/F', '/PID', String(proc.pid)], {
249
+ stdio: 'ignore'
250
+ });
251
+ }
252
+ else {
253
+ proc.kill('SIGTERM');
254
+ setTimeout(() => {
255
+ if (!proc.killed)
256
+ proc.kill('SIGKILL');
257
+ }, 5000);
258
+ }
259
+ };
260
+ if (signal.aborted)
261
+ killProc();
262
+ else
263
+ signal.addEventListener('abort', killProc, { once: true });
264
+ }
265
+ });
266
+ }
267
+ // ---------------------------------------------------------------------------
268
+ // CLI args builder — translates AgentDefinition into child process args
269
+ // ---------------------------------------------------------------------------
270
+ import { CORE_TOOL_NAMES } from '../../../tool-names.js';
271
+ /**
272
+ * Build CLI args for spawning a child process from an AgentDefinition.
273
+ *
274
+ * The agent's flat tools array is split into --tools (core) and
275
+ * --custom-tools (everything else) for the CLI flags.
276
+ *
277
+ * System prompt is written to a temp file to avoid shell escaping issues.
278
+ * The caller MUST clean up the temp file after the subprocess exits.
279
+ */
280
+ export function buildAgentArgs(config) {
281
+ const args = [];
282
+ let promptFile;
283
+ // Model + thinking level
284
+ if (config.model) {
285
+ args.push('--model', config.model);
286
+ }
287
+ if (config.thinkingLevel) {
288
+ args.push('--thinking', config.thinkingLevel);
289
+ }
290
+ // Split flat tools list into core vs custom for CLI flags
291
+ const coreTools = [];
292
+ const customTools = [];
293
+ for (const t of config.tools) {
294
+ if (CORE_TOOL_NAMES.has(t)) {
295
+ coreTools.push(t);
296
+ }
297
+ else {
298
+ customTools.push(t);
299
+ }
300
+ }
301
+ if (coreTools.length > 0) {
302
+ args.push('--tools', coreTools.join(','));
303
+ }
304
+ else {
305
+ args.push('--no-tools');
306
+ }
307
+ if (customTools.length > 0) {
308
+ args.push('--custom-tools', customTools.join(','));
309
+ }
310
+ else {
311
+ args.push('--no-custom-tools');
312
+ }
313
+ // System prompt — replace entirely via temp file
314
+ if (config.systemPrompt) {
315
+ promptFile = writeSystemPromptFile(config.systemPrompt);
316
+ args.push('--system-prompt', promptFile);
317
+ }
318
+ return { args, promptFile };
319
+ }
320
+ //# sourceMappingURL=subprocess.js.map