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,87 @@
1
+ import { existsSync, readFileSync } from 'fs';
2
+ /**
3
+ * Parse changelog entries from CHANGELOG.md
4
+ * Scans for ## lines and collects content until next ## or EOF
5
+ */
6
+ export function parseChangelog(changelogPath) {
7
+ if (!existsSync(changelogPath)) {
8
+ return [];
9
+ }
10
+ try {
11
+ const content = readFileSync(changelogPath, 'utf-8');
12
+ const lines = content.split('\n');
13
+ const entries = [];
14
+ let currentLines = [];
15
+ let currentVersion = null;
16
+ for (const line of lines) {
17
+ // Check if this is a version header (## [x.y.z] ...)
18
+ if (line.startsWith('## ')) {
19
+ // Save previous entry if exists
20
+ if (currentVersion && currentLines.length > 0) {
21
+ entries.push({
22
+ ...currentVersion,
23
+ content: currentLines.join('\n').trim()
24
+ });
25
+ }
26
+ // Try to parse version from this line
27
+ const versionMatch = line.match(/##\s+\[?(\d+)\.(\d+)\.(\d+)\]?/);
28
+ if (versionMatch) {
29
+ currentVersion = {
30
+ major: Number.parseInt(versionMatch[1], 10),
31
+ minor: Number.parseInt(versionMatch[2], 10),
32
+ patch: Number.parseInt(versionMatch[3], 10)
33
+ };
34
+ currentLines = [line];
35
+ }
36
+ else {
37
+ // Reset if we can't parse version
38
+ currentVersion = null;
39
+ currentLines = [];
40
+ }
41
+ }
42
+ else if (currentVersion) {
43
+ // Collect lines for current version
44
+ currentLines.push(line);
45
+ }
46
+ }
47
+ // Save last entry
48
+ if (currentVersion && currentLines.length > 0) {
49
+ entries.push({
50
+ ...currentVersion,
51
+ content: currentLines.join('\n').trim()
52
+ });
53
+ }
54
+ return entries;
55
+ }
56
+ catch (error) {
57
+ console.error(`Warning: Could not parse changelog: ${error}`);
58
+ return [];
59
+ }
60
+ }
61
+ /**
62
+ * Compare versions. Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
63
+ */
64
+ function compareVersions(v1, v2) {
65
+ if (v1.major !== v2.major)
66
+ return v1.major - v2.major;
67
+ if (v1.minor !== v2.minor)
68
+ return v1.minor - v2.minor;
69
+ return v1.patch - v2.patch;
70
+ }
71
+ /**
72
+ * Get entries newer than lastVersion
73
+ */
74
+ export function getNewEntries(entries, lastVersion) {
75
+ // Parse lastVersion
76
+ const parts = lastVersion.split('.').map(Number);
77
+ const last = {
78
+ major: parts[0] || 0,
79
+ minor: parts[1] || 0,
80
+ patch: parts[2] || 0,
81
+ content: ''
82
+ };
83
+ return entries.filter((entry) => compareVersions(entry, last) > 0);
84
+ }
85
+ // Re-export getChangelogPath from paths.ts for convenience
86
+ export { getChangelogPath } from '../config.js';
87
+ //# sourceMappingURL=changelog.js.map
@@ -0,0 +1,164 @@
1
+ import { spawnSync } from 'child_process';
2
+ import { clipboard } from './clipboard-native.js';
3
+ import { loadPhoton } from './photon.js';
4
+ const SUPPORTED_IMAGE_MIME_TYPES = ['image/png', 'image/jpeg', 'image/webp', 'image/gif'];
5
+ const DEFAULT_LIST_TIMEOUT_MS = 1000;
6
+ const DEFAULT_READ_TIMEOUT_MS = 3000;
7
+ const DEFAULT_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
8
+ export function isWaylandSession(env = process.env) {
9
+ return Boolean(env.WAYLAND_DISPLAY) || env.XDG_SESSION_TYPE === 'wayland';
10
+ }
11
+ function baseMimeType(mimeType) {
12
+ return mimeType.split(';')[0]?.trim().toLowerCase() ?? mimeType.toLowerCase();
13
+ }
14
+ export function extensionForImageMimeType(mimeType) {
15
+ switch (baseMimeType(mimeType)) {
16
+ case 'image/png':
17
+ return 'png';
18
+ case 'image/jpeg':
19
+ return 'jpg';
20
+ case 'image/webp':
21
+ return 'webp';
22
+ case 'image/gif':
23
+ return 'gif';
24
+ default:
25
+ return null;
26
+ }
27
+ }
28
+ function selectPreferredImageMimeType(mimeTypes) {
29
+ const normalized = mimeTypes
30
+ .map((t) => t.trim())
31
+ .filter(Boolean)
32
+ .map((t) => ({ raw: t, base: baseMimeType(t) }));
33
+ for (const preferred of SUPPORTED_IMAGE_MIME_TYPES) {
34
+ const match = normalized.find((t) => t.base === preferred);
35
+ if (match) {
36
+ return match.raw;
37
+ }
38
+ }
39
+ const anyImage = normalized.find((t) => t.base.startsWith('image/'));
40
+ return anyImage?.raw ?? null;
41
+ }
42
+ function isSupportedImageMimeType(mimeType) {
43
+ const base = baseMimeType(mimeType);
44
+ return SUPPORTED_IMAGE_MIME_TYPES.some((t) => t === base);
45
+ }
46
+ /**
47
+ * Convert unsupported image formats to PNG using Photon.
48
+ * Returns null if conversion is unavailable or fails.
49
+ */
50
+ async function convertToPng(bytes) {
51
+ const photon = await loadPhoton();
52
+ if (!photon) {
53
+ return null;
54
+ }
55
+ try {
56
+ const image = photon.PhotonImage.new_from_byteslice(bytes);
57
+ try {
58
+ return image.get_bytes();
59
+ }
60
+ finally {
61
+ image.free();
62
+ }
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ }
68
+ function runCommand(command, args, options) {
69
+ const timeoutMs = options?.timeoutMs ?? DEFAULT_READ_TIMEOUT_MS;
70
+ const maxBufferBytes = options?.maxBufferBytes ?? DEFAULT_MAX_BUFFER_BYTES;
71
+ const result = spawnSync(command, args, {
72
+ timeout: timeoutMs,
73
+ maxBuffer: maxBufferBytes
74
+ });
75
+ if (result.error) {
76
+ return { ok: false, stdout: Buffer.alloc(0) };
77
+ }
78
+ if (result.status !== 0) {
79
+ return { ok: false, stdout: Buffer.alloc(0) };
80
+ }
81
+ const stdout = Buffer.isBuffer(result.stdout)
82
+ ? result.stdout
83
+ : Buffer.from(result.stdout ?? '', typeof result.stdout === 'string' ? 'utf-8' : undefined);
84
+ return { ok: true, stdout };
85
+ }
86
+ function readClipboardImageViaWlPaste() {
87
+ const list = runCommand('wl-paste', ['--list-types'], { timeoutMs: DEFAULT_LIST_TIMEOUT_MS });
88
+ if (!list.ok) {
89
+ return null;
90
+ }
91
+ const types = list.stdout
92
+ .toString('utf-8')
93
+ .split(/\r?\n/)
94
+ .map((t) => t.trim())
95
+ .filter(Boolean);
96
+ const selectedType = selectPreferredImageMimeType(types);
97
+ if (!selectedType) {
98
+ return null;
99
+ }
100
+ const data = runCommand('wl-paste', ['--type', selectedType, '--no-newline']);
101
+ if (!data.ok || data.stdout.length === 0) {
102
+ return null;
103
+ }
104
+ return { bytes: data.stdout, mimeType: baseMimeType(selectedType) };
105
+ }
106
+ function readClipboardImageViaXclip() {
107
+ const targets = runCommand('xclip', ['-selection', 'clipboard', '-t', 'TARGETS', '-o'], {
108
+ timeoutMs: DEFAULT_LIST_TIMEOUT_MS
109
+ });
110
+ let candidateTypes = [];
111
+ if (targets.ok) {
112
+ candidateTypes = targets.stdout
113
+ .toString('utf-8')
114
+ .split(/\r?\n/)
115
+ .map((t) => t.trim())
116
+ .filter(Boolean);
117
+ }
118
+ const preferred = candidateTypes.length > 0 ? selectPreferredImageMimeType(candidateTypes) : null;
119
+ const tryTypes = preferred
120
+ ? [preferred, ...SUPPORTED_IMAGE_MIME_TYPES]
121
+ : [...SUPPORTED_IMAGE_MIME_TYPES];
122
+ for (const mimeType of tryTypes) {
123
+ const data = runCommand('xclip', ['-selection', 'clipboard', '-t', mimeType, '-o']);
124
+ if (data.ok && data.stdout.length > 0) {
125
+ return { bytes: data.stdout, mimeType: baseMimeType(mimeType) };
126
+ }
127
+ }
128
+ return null;
129
+ }
130
+ export async function readClipboardImage(options) {
131
+ const env = options?.env ?? process.env;
132
+ const platform = options?.platform ?? process.platform;
133
+ if (env.TERMUX_VERSION) {
134
+ return null;
135
+ }
136
+ let image = null;
137
+ if (platform === 'linux' && isWaylandSession(env)) {
138
+ image = readClipboardImageViaWlPaste() ?? readClipboardImageViaXclip();
139
+ }
140
+ else {
141
+ if (!clipboard || !clipboard.hasImage()) {
142
+ return null;
143
+ }
144
+ const imageData = await clipboard.getImageBinary();
145
+ if (!imageData || imageData.length === 0) {
146
+ return null;
147
+ }
148
+ const bytes = imageData instanceof Uint8Array ? imageData : Uint8Array.from(imageData);
149
+ image = { bytes, mimeType: 'image/png' };
150
+ }
151
+ if (!image) {
152
+ return null;
153
+ }
154
+ // Convert unsupported formats (e.g., BMP from WSLg) to PNG
155
+ if (!isSupportedImageMimeType(image.mimeType)) {
156
+ const pngBytes = await convertToPng(image.bytes);
157
+ if (!pngBytes) {
158
+ return null;
159
+ }
160
+ return { bytes: pngBytes, mimeType: 'image/png' };
161
+ }
162
+ return image;
163
+ }
164
+ //# sourceMappingURL=clipboard-image.js.map
@@ -0,0 +1,14 @@
1
+ import { createRequire } from 'module';
2
+ const require = createRequire(import.meta.url);
3
+ let clipboard = null;
4
+ const hasDisplay = process.platform !== 'linux' || Boolean(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
5
+ if (!process.env.TERMUX_VERSION && hasDisplay) {
6
+ try {
7
+ clipboard = require('@mariozechner/clipboard');
8
+ }
9
+ catch {
10
+ clipboard = null;
11
+ }
12
+ }
13
+ export { clipboard };
14
+ //# sourceMappingURL=clipboard-native.js.map
@@ -0,0 +1,67 @@
1
+ import { execSync, spawn } from 'child_process';
2
+ import { platform } from 'os';
3
+ import { isWaylandSession } from './clipboard-image.js';
4
+ export function copyToClipboard(text) {
5
+ // Always emit OSC 52 - works over SSH/mosh, harmless locally
6
+ const encoded = Buffer.from(text).toString('base64');
7
+ process.stdout.write(`\x1b]52;c;${encoded}\x07`);
8
+ // Also try native tools (best effort for local sessions)
9
+ const p = platform();
10
+ const options = { input: text, timeout: 5000 };
11
+ try {
12
+ if (p === 'darwin') {
13
+ execSync('pbcopy', options);
14
+ }
15
+ else if (p === 'win32') {
16
+ execSync('clip', options);
17
+ }
18
+ else {
19
+ // Linux. Try Termux, Wayland, or X11 clipboard tools.
20
+ if (process.env.TERMUX_VERSION) {
21
+ try {
22
+ execSync('termux-clipboard-set', options);
23
+ return;
24
+ }
25
+ catch {
26
+ // Fall back to Wayland or X11 tools.
27
+ }
28
+ }
29
+ const isWayland = isWaylandSession();
30
+ if (isWayland) {
31
+ try {
32
+ // Verify wl-copy exists (spawn errors are async and won't be caught)
33
+ execSync('which wl-copy', { stdio: 'ignore' });
34
+ // wl-copy with execSync hangs due to fork behavior; use spawn instead
35
+ const proc = spawn('wl-copy', [], { stdio: ['pipe', 'ignore', 'ignore'] });
36
+ proc.stdin.on('error', () => {
37
+ // Ignore EPIPE errors if wl-copy exits early
38
+ });
39
+ proc.stdin.write(text);
40
+ proc.stdin.end();
41
+ proc.unref();
42
+ }
43
+ catch {
44
+ // Fall back to xclip/xsel (works on XWayland)
45
+ try {
46
+ execSync('xclip -selection clipboard', options);
47
+ }
48
+ catch {
49
+ execSync('xsel --clipboard --input', options);
50
+ }
51
+ }
52
+ }
53
+ else {
54
+ try {
55
+ execSync('xclip -selection clipboard', options);
56
+ }
57
+ catch {
58
+ execSync('xsel --clipboard --input', options);
59
+ }
60
+ }
61
+ }
62
+ }
63
+ catch {
64
+ // Ignore - OSC 52 already emitted as fallback
65
+ }
66
+ }
67
+ //# sourceMappingURL=clipboard.js.map
@@ -0,0 +1,26 @@
1
+ import { parse } from 'yaml';
2
+ const normalizeNewlines = (value) => value.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
3
+ const extractFrontmatter = (content) => {
4
+ const normalized = normalizeNewlines(content);
5
+ if (!normalized.startsWith('---')) {
6
+ return { yamlString: null, body: normalized };
7
+ }
8
+ const endIndex = normalized.indexOf('\n---', 3);
9
+ if (endIndex === -1) {
10
+ return { yamlString: null, body: normalized };
11
+ }
12
+ return {
13
+ yamlString: normalized.slice(4, endIndex),
14
+ body: normalized.slice(endIndex + 4).trim()
15
+ };
16
+ };
17
+ export const parseFrontmatter = (content) => {
18
+ const { yamlString, body } = extractFrontmatter(content);
19
+ if (!yamlString) {
20
+ return { frontmatter: {}, body };
21
+ }
22
+ const parsed = parse(yamlString);
23
+ return { frontmatter: (parsed ?? {}), body };
24
+ };
25
+ export const stripFrontmatter = (content) => parseFrontmatter(content).body;
26
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1,166 @@
1
+ import hostedGitInfo from 'hosted-git-info';
2
+ function splitRef(url) {
3
+ const scpLikeMatch = url.match(/^git@([^:]+):(.+)$/);
4
+ if (scpLikeMatch) {
5
+ const pathWithMaybeRef = scpLikeMatch[2] ?? '';
6
+ const refSeparator = pathWithMaybeRef.indexOf('@');
7
+ if (refSeparator < 0)
8
+ return { repo: url };
9
+ const repoPath = pathWithMaybeRef.slice(0, refSeparator);
10
+ const ref = pathWithMaybeRef.slice(refSeparator + 1);
11
+ if (!repoPath || !ref)
12
+ return { repo: url };
13
+ return {
14
+ repo: `git@${scpLikeMatch[1] ?? ''}:${repoPath}`,
15
+ ref
16
+ };
17
+ }
18
+ if (url.includes('://')) {
19
+ try {
20
+ const parsed = new URL(url);
21
+ const pathWithMaybeRef = parsed.pathname.replace(/^\/+/, '');
22
+ const refSeparator = pathWithMaybeRef.indexOf('@');
23
+ if (refSeparator < 0)
24
+ return { repo: url };
25
+ const repoPath = pathWithMaybeRef.slice(0, refSeparator);
26
+ const ref = pathWithMaybeRef.slice(refSeparator + 1);
27
+ if (!repoPath || !ref)
28
+ return { repo: url };
29
+ parsed.pathname = `/${repoPath}`;
30
+ return {
31
+ repo: parsed.toString().replace(/\/$/, ''),
32
+ ref
33
+ };
34
+ }
35
+ catch {
36
+ return { repo: url };
37
+ }
38
+ }
39
+ const slashIndex = url.indexOf('/');
40
+ if (slashIndex < 0) {
41
+ return { repo: url };
42
+ }
43
+ const host = url.slice(0, slashIndex);
44
+ const pathWithMaybeRef = url.slice(slashIndex + 1);
45
+ const refSeparator = pathWithMaybeRef.indexOf('@');
46
+ if (refSeparator < 0) {
47
+ return { repo: url };
48
+ }
49
+ const repoPath = pathWithMaybeRef.slice(0, refSeparator);
50
+ const ref = pathWithMaybeRef.slice(refSeparator + 1);
51
+ if (!repoPath || !ref) {
52
+ return { repo: url };
53
+ }
54
+ return {
55
+ repo: `${host}/${repoPath}`,
56
+ ref
57
+ };
58
+ }
59
+ function parseGenericGitUrl(url) {
60
+ const { repo: repoWithoutRef, ref } = splitRef(url);
61
+ let repo = repoWithoutRef;
62
+ let host = '';
63
+ let path = '';
64
+ const scpLikeMatch = repoWithoutRef.match(/^git@([^:]+):(.+)$/);
65
+ if (scpLikeMatch) {
66
+ host = scpLikeMatch[1] ?? '';
67
+ path = scpLikeMatch[2] ?? '';
68
+ }
69
+ else if (repoWithoutRef.startsWith('https://') ||
70
+ repoWithoutRef.startsWith('http://') ||
71
+ repoWithoutRef.startsWith('ssh://') ||
72
+ repoWithoutRef.startsWith('git://')) {
73
+ try {
74
+ const parsed = new URL(repoWithoutRef);
75
+ host = parsed.hostname;
76
+ path = parsed.pathname.replace(/^\/+/, '');
77
+ }
78
+ catch {
79
+ return null;
80
+ }
81
+ }
82
+ else {
83
+ const slashIndex = repoWithoutRef.indexOf('/');
84
+ if (slashIndex < 0) {
85
+ return null;
86
+ }
87
+ host = repoWithoutRef.slice(0, slashIndex);
88
+ path = repoWithoutRef.slice(slashIndex + 1);
89
+ if (!host.includes('.') && host !== 'localhost') {
90
+ return null;
91
+ }
92
+ repo = `https://${repoWithoutRef}`;
93
+ }
94
+ const normalizedPath = path.replace(/\.git$/, '').replace(/^\/+/, '');
95
+ if (!host || !normalizedPath || normalizedPath.split('/').length < 2) {
96
+ return null;
97
+ }
98
+ return {
99
+ type: 'git',
100
+ repo,
101
+ host,
102
+ path: normalizedPath,
103
+ ref,
104
+ pinned: Boolean(ref)
105
+ };
106
+ }
107
+ /**
108
+ * Parse git source into a GitSource.
109
+ *
110
+ * Rules:
111
+ * - With git: prefix, accept all historical shorthand forms.
112
+ * - Without git: prefix, only accept explicit protocol URLs.
113
+ */
114
+ export function parseGitUrl(source) {
115
+ const trimmed = source.trim();
116
+ const hasGitPrefix = trimmed.startsWith('git:');
117
+ const url = hasGitPrefix ? trimmed.slice(4).trim() : trimmed;
118
+ if (!hasGitPrefix && !/^(https?|ssh|git):\/\//i.test(url)) {
119
+ return null;
120
+ }
121
+ const split = splitRef(url);
122
+ const hostedCandidates = [split.ref ? `${split.repo}#${split.ref}` : undefined, url].filter((value) => Boolean(value));
123
+ for (const candidate of hostedCandidates) {
124
+ const info = hostedGitInfo.fromUrl(candidate);
125
+ if (info) {
126
+ if (split.ref && info.project?.includes('@')) {
127
+ continue;
128
+ }
129
+ const useHttpsPrefix = !split.repo.startsWith('http://') &&
130
+ !split.repo.startsWith('https://') &&
131
+ !split.repo.startsWith('ssh://') &&
132
+ !split.repo.startsWith('git://') &&
133
+ !split.repo.startsWith('git@');
134
+ return {
135
+ type: 'git',
136
+ repo: useHttpsPrefix ? `https://${split.repo}` : split.repo,
137
+ host: info.domain || '',
138
+ path: `${info.user}/${info.project}`.replace(/\.git$/, ''),
139
+ ref: info.committish || split.ref || undefined,
140
+ pinned: Boolean(info.committish || split.ref)
141
+ };
142
+ }
143
+ }
144
+ const httpsCandidates = [
145
+ split.ref ? `https://${split.repo}#${split.ref}` : undefined,
146
+ `https://${url}`
147
+ ].filter((value) => Boolean(value));
148
+ for (const candidate of httpsCandidates) {
149
+ const info = hostedGitInfo.fromUrl(candidate);
150
+ if (info) {
151
+ if (split.ref && info.project?.includes('@')) {
152
+ continue;
153
+ }
154
+ return {
155
+ type: 'git',
156
+ repo: `https://${split.repo}`,
157
+ host: info.domain || '',
158
+ path: `${info.user}/${info.project}`.replace(/\.git$/, ''),
159
+ ref: info.committish || split.ref || undefined,
160
+ pinned: Boolean(info.committish || split.ref)
161
+ };
162
+ }
163
+ }
164
+ return parseGenericGitUrl(url);
165
+ }
166
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1,35 @@
1
+ import { loadPhoton } from './photon.js';
2
+ /**
3
+ * Convert image to PNG format for terminal display.
4
+ * Kitty graphics protocol requires PNG format (f=100).
5
+ */
6
+ export async function convertToPng(base64Data, mimeType) {
7
+ // Already PNG, no conversion needed
8
+ if (mimeType === 'image/png') {
9
+ return { data: base64Data, mimeType };
10
+ }
11
+ const photon = await loadPhoton();
12
+ if (!photon) {
13
+ // Photon not available, can't convert
14
+ return null;
15
+ }
16
+ try {
17
+ const bytes = new Uint8Array(Buffer.from(base64Data, 'base64'));
18
+ const image = photon.PhotonImage.new_from_byteslice(bytes);
19
+ try {
20
+ const pngBuffer = image.get_bytes();
21
+ return {
22
+ data: Buffer.from(pngBuffer).toString('base64'),
23
+ mimeType: 'image/png'
24
+ };
25
+ }
26
+ finally {
27
+ image.free();
28
+ }
29
+ }
30
+ catch {
31
+ // Conversion failed
32
+ return null;
33
+ }
34
+ }
35
+ //# sourceMappingURL=image-convert.js.map