@imdigitalashish/zpi 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (604) hide show
  1. package/CHANGELOG.md +2801 -0
  2. package/README.md +95 -0
  3. package/dist/cli/args.d.ts +47 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +293 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/config-selector.d.ts +14 -0
  8. package/dist/cli/config-selector.d.ts.map +1 -0
  9. package/dist/cli/config-selector.js +31 -0
  10. package/dist/cli/config-selector.js.map +1 -0
  11. package/dist/cli/file-processor.d.ts +15 -0
  12. package/dist/cli/file-processor.d.ts.map +1 -0
  13. package/dist/cli/file-processor.js +79 -0
  14. package/dist/cli/file-processor.js.map +1 -0
  15. package/dist/cli/list-models.d.ts +9 -0
  16. package/dist/cli/list-models.d.ts.map +1 -0
  17. package/dist/cli/list-models.js +92 -0
  18. package/dist/cli/list-models.js.map +1 -0
  19. package/dist/cli/session-picker.d.ts +9 -0
  20. package/dist/cli/session-picker.d.ts.map +1 -0
  21. package/dist/cli/session-picker.js +34 -0
  22. package/dist/cli/session-picker.js.map +1 -0
  23. package/dist/cli.d.ts +3 -0
  24. package/dist/cli.d.ts.map +1 -0
  25. package/dist/cli.js +11 -0
  26. package/dist/cli.js.map +1 -0
  27. package/dist/config.d.ts +68 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +203 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/core/agent-session.d.ts +571 -0
  32. package/dist/core/agent-session.d.ts.map +1 -0
  33. package/dist/core/agent-session.js +2353 -0
  34. package/dist/core/agent-session.js.map +1 -0
  35. package/dist/core/auth-storage.d.ts +129 -0
  36. package/dist/core/auth-storage.d.ts.map +1 -0
  37. package/dist/core/auth-storage.js +394 -0
  38. package/dist/core/auth-storage.js.map +1 -0
  39. package/dist/core/bash-executor.d.ts +47 -0
  40. package/dist/core/bash-executor.d.ts.map +1 -0
  41. package/dist/core/bash-executor.js +212 -0
  42. package/dist/core/bash-executor.js.map +1 -0
  43. package/dist/core/compaction/branch-summarization.d.ts +86 -0
  44. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  45. package/dist/core/compaction/branch-summarization.js +242 -0
  46. package/dist/core/compaction/branch-summarization.js.map +1 -0
  47. package/dist/core/compaction/compaction.d.ts +121 -0
  48. package/dist/core/compaction/compaction.d.ts.map +1 -0
  49. package/dist/core/compaction/compaction.js +607 -0
  50. package/dist/core/compaction/compaction.js.map +1 -0
  51. package/dist/core/compaction/index.d.ts +7 -0
  52. package/dist/core/compaction/index.d.ts.map +1 -0
  53. package/dist/core/compaction/index.js +7 -0
  54. package/dist/core/compaction/index.js.map +1 -0
  55. package/dist/core/compaction/utils.d.ts +35 -0
  56. package/dist/core/compaction/utils.d.ts.map +1 -0
  57. package/dist/core/compaction/utils.js +138 -0
  58. package/dist/core/compaction/utils.js.map +1 -0
  59. package/dist/core/defaults.d.ts +3 -0
  60. package/dist/core/defaults.d.ts.map +1 -0
  61. package/dist/core/defaults.js +2 -0
  62. package/dist/core/defaults.js.map +1 -0
  63. package/dist/core/diagnostics.d.ts +15 -0
  64. package/dist/core/diagnostics.d.ts.map +1 -0
  65. package/dist/core/diagnostics.js +2 -0
  66. package/dist/core/diagnostics.js.map +1 -0
  67. package/dist/core/event-bus.d.ts +9 -0
  68. package/dist/core/event-bus.d.ts.map +1 -0
  69. package/dist/core/event-bus.js +25 -0
  70. package/dist/core/event-bus.js.map +1 -0
  71. package/dist/core/exec.d.ts +29 -0
  72. package/dist/core/exec.d.ts.map +1 -0
  73. package/dist/core/exec.js +71 -0
  74. package/dist/core/exec.js.map +1 -0
  75. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  76. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  77. package/dist/core/export-html/ansi-to-html.js +249 -0
  78. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  79. package/dist/core/export-html/index.d.ts +34 -0
  80. package/dist/core/export-html/index.d.ts.map +1 -0
  81. package/dist/core/export-html/index.js +222 -0
  82. package/dist/core/export-html/index.js.map +1 -0
  83. package/dist/core/export-html/template.css +971 -0
  84. package/dist/core/export-html/template.html +54 -0
  85. package/dist/core/export-html/template.js +1586 -0
  86. package/dist/core/export-html/tool-renderer.d.ts +35 -0
  87. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  88. package/dist/core/export-html/tool-renderer.js +57 -0
  89. package/dist/core/export-html/tool-renderer.js.map +1 -0
  90. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  91. package/dist/core/export-html/vendor/marked.min.js +6 -0
  92. package/dist/core/extensions/index.d.ts +11 -0
  93. package/dist/core/extensions/index.d.ts.map +1 -0
  94. package/dist/core/extensions/index.js +9 -0
  95. package/dist/core/extensions/index.js.map +1 -0
  96. package/dist/core/extensions/loader.d.ts +25 -0
  97. package/dist/core/extensions/loader.d.ts.map +1 -0
  98. package/dist/core/extensions/loader.js +402 -0
  99. package/dist/core/extensions/loader.js.map +1 -0
  100. package/dist/core/extensions/runner.d.ts +146 -0
  101. package/dist/core/extensions/runner.d.ts.map +1 -0
  102. package/dist/core/extensions/runner.js +626 -0
  103. package/dist/core/extensions/runner.js.map +1 -0
  104. package/dist/core/extensions/types.d.ts +984 -0
  105. package/dist/core/extensions/types.d.ts.map +1 -0
  106. package/dist/core/extensions/types.js +35 -0
  107. package/dist/core/extensions/types.js.map +1 -0
  108. package/dist/core/extensions/wrapper.d.ts +27 -0
  109. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  110. package/dist/core/extensions/wrapper.js +102 -0
  111. package/dist/core/extensions/wrapper.js.map +1 -0
  112. package/dist/core/footer-data-provider.d.ts +32 -0
  113. package/dist/core/footer-data-provider.d.ts.map +1 -0
  114. package/dist/core/footer-data-provider.js +134 -0
  115. package/dist/core/footer-data-provider.js.map +1 -0
  116. package/dist/core/index.d.ts +9 -0
  117. package/dist/core/index.d.ts.map +1 -0
  118. package/dist/core/index.js +9 -0
  119. package/dist/core/index.js.map +1 -0
  120. package/dist/core/keybindings.d.ts +55 -0
  121. package/dist/core/keybindings.d.ts.map +1 -0
  122. package/dist/core/keybindings.js +153 -0
  123. package/dist/core/keybindings.js.map +1 -0
  124. package/dist/core/memory.d.ts +64 -0
  125. package/dist/core/memory.d.ts.map +1 -0
  126. package/dist/core/memory.js +247 -0
  127. package/dist/core/memory.js.map +1 -0
  128. package/dist/core/messages.d.ts +77 -0
  129. package/dist/core/messages.d.ts.map +1 -0
  130. package/dist/core/messages.js +149 -0
  131. package/dist/core/messages.js.map +1 -0
  132. package/dist/core/model-registry.d.ts +102 -0
  133. package/dist/core/model-registry.d.ts.map +1 -0
  134. package/dist/core/model-registry.js +515 -0
  135. package/dist/core/model-registry.js.map +1 -0
  136. package/dist/core/model-resolver.d.ts +104 -0
  137. package/dist/core/model-resolver.d.ts.map +1 -0
  138. package/dist/core/model-resolver.js +403 -0
  139. package/dist/core/model-resolver.js.map +1 -0
  140. package/dist/core/package-manager.d.ts +151 -0
  141. package/dist/core/package-manager.d.ts.map +1 -0
  142. package/dist/core/package-manager.js +1426 -0
  143. package/dist/core/package-manager.js.map +1 -0
  144. package/dist/core/prompt-templates.d.ts +50 -0
  145. package/dist/core/prompt-templates.d.ts.map +1 -0
  146. package/dist/core/prompt-templates.js +251 -0
  147. package/dist/core/prompt-templates.js.map +1 -0
  148. package/dist/core/resolve-config-value.d.ts +17 -0
  149. package/dist/core/resolve-config-value.d.ts.map +1 -0
  150. package/dist/core/resolve-config-value.js +59 -0
  151. package/dist/core/resolve-config-value.js.map +1 -0
  152. package/dist/core/resource-loader.d.ts +184 -0
  153. package/dist/core/resource-loader.d.ts.map +1 -0
  154. package/dist/core/resource-loader.js +673 -0
  155. package/dist/core/resource-loader.js.map +1 -0
  156. package/dist/core/sdk.d.ts +90 -0
  157. package/dist/core/sdk.d.ts.map +1 -0
  158. package/dist/core/sdk.js +238 -0
  159. package/dist/core/sdk.js.map +1 -0
  160. package/dist/core/session-manager.d.ts +323 -0
  161. package/dist/core/session-manager.d.ts.map +1 -0
  162. package/dist/core/session-manager.js +1091 -0
  163. package/dist/core/session-manager.js.map +1 -0
  164. package/dist/core/settings-manager.d.ts +230 -0
  165. package/dist/core/settings-manager.d.ts.map +1 -0
  166. package/dist/core/settings-manager.js +656 -0
  167. package/dist/core/settings-manager.js.map +1 -0
  168. package/dist/core/skills.d.ts +58 -0
  169. package/dist/core/skills.d.ts.map +1 -0
  170. package/dist/core/skills.js +364 -0
  171. package/dist/core/skills.js.map +1 -0
  172. package/dist/core/slash-commands.d.ts +15 -0
  173. package/dist/core/slash-commands.d.ts.map +1 -0
  174. package/dist/core/slash-commands.js +23 -0
  175. package/dist/core/slash-commands.js.map +1 -0
  176. package/dist/core/system-prompt.d.ts +26 -0
  177. package/dist/core/system-prompt.d.ts.map +1 -0
  178. package/dist/core/system-prompt.js +150 -0
  179. package/dist/core/system-prompt.js.map +1 -0
  180. package/dist/core/timings.d.ts +7 -0
  181. package/dist/core/timings.d.ts.map +1 -0
  182. package/dist/core/timings.js +25 -0
  183. package/dist/core/timings.js.map +1 -0
  184. package/dist/core/tools/bash.d.ts +55 -0
  185. package/dist/core/tools/bash.d.ts.map +1 -0
  186. package/dist/core/tools/bash.js +242 -0
  187. package/dist/core/tools/bash.js.map +1 -0
  188. package/dist/core/tools/edit-diff.d.ts +63 -0
  189. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  190. package/dist/core/tools/edit-diff.js +243 -0
  191. package/dist/core/tools/edit-diff.js.map +1 -0
  192. package/dist/core/tools/edit.d.ts +39 -0
  193. package/dist/core/tools/edit.d.ts.map +1 -0
  194. package/dist/core/tools/edit.js +146 -0
  195. package/dist/core/tools/edit.js.map +1 -0
  196. package/dist/core/tools/find.d.ts +39 -0
  197. package/dist/core/tools/find.d.ts.map +1 -0
  198. package/dist/core/tools/find.js +206 -0
  199. package/dist/core/tools/find.js.map +1 -0
  200. package/dist/core/tools/grep.d.ts +45 -0
  201. package/dist/core/tools/grep.d.ts.map +1 -0
  202. package/dist/core/tools/grep.js +239 -0
  203. package/dist/core/tools/grep.js.map +1 -0
  204. package/dist/core/tools/index.d.ts +102 -0
  205. package/dist/core/tools/index.d.ts.map +1 -0
  206. package/dist/core/tools/index.js +71 -0
  207. package/dist/core/tools/index.js.map +1 -0
  208. package/dist/core/tools/ls.d.ts +40 -0
  209. package/dist/core/tools/ls.d.ts.map +1 -0
  210. package/dist/core/tools/ls.js +118 -0
  211. package/dist/core/tools/ls.js.map +1 -0
  212. package/dist/core/tools/memory.d.ts +45 -0
  213. package/dist/core/tools/memory.d.ts.map +1 -0
  214. package/dist/core/tools/memory.js +346 -0
  215. package/dist/core/tools/memory.js.map +1 -0
  216. package/dist/core/tools/path-utils.d.ts +8 -0
  217. package/dist/core/tools/path-utils.d.ts.map +1 -0
  218. package/dist/core/tools/path-utils.js +81 -0
  219. package/dist/core/tools/path-utils.js.map +1 -0
  220. package/dist/core/tools/read.d.ts +39 -0
  221. package/dist/core/tools/read.d.ts.map +1 -0
  222. package/dist/core/tools/read.js +166 -0
  223. package/dist/core/tools/read.js.map +1 -0
  224. package/dist/core/tools/truncate.d.ts +70 -0
  225. package/dist/core/tools/truncate.d.ts.map +1 -0
  226. package/dist/core/tools/truncate.js +205 -0
  227. package/dist/core/tools/truncate.js.map +1 -0
  228. package/dist/core/tools/write.d.ts +29 -0
  229. package/dist/core/tools/write.d.ts.map +1 -0
  230. package/dist/core/tools/write.js +78 -0
  231. package/dist/core/tools/write.js.map +1 -0
  232. package/dist/index.d.ts +28 -0
  233. package/dist/index.d.ts.map +1 -0
  234. package/dist/index.js +43 -0
  235. package/dist/index.js.map +1 -0
  236. package/dist/main.d.ts +8 -0
  237. package/dist/main.d.ts.map +1 -0
  238. package/dist/main.js +651 -0
  239. package/dist/main.js.map +1 -0
  240. package/dist/migrations.d.ts +33 -0
  241. package/dist/migrations.d.ts.map +1 -0
  242. package/dist/migrations.js +261 -0
  243. package/dist/migrations.js.map +1 -0
  244. package/dist/modes/index.d.ts +9 -0
  245. package/dist/modes/index.d.ts.map +1 -0
  246. package/dist/modes/index.js +8 -0
  247. package/dist/modes/index.js.map +1 -0
  248. package/dist/modes/interactive/components/armin.d.ts +34 -0
  249. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  250. package/dist/modes/interactive/components/armin.js +333 -0
  251. package/dist/modes/interactive/components/armin.js.map +1 -0
  252. package/dist/modes/interactive/components/assistant-message.d.ts +16 -0
  253. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  254. package/dist/modes/interactive/components/assistant-message.js +96 -0
  255. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  256. package/dist/modes/interactive/components/bash-execution.d.ts +35 -0
  257. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  258. package/dist/modes/interactive/components/bash-execution.js +162 -0
  259. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  260. package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  261. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  262. package/dist/modes/interactive/components/bordered-loader.js +51 -0
  263. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  264. package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  265. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  266. package/dist/modes/interactive/components/branch-summary-message.js +44 -0
  267. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  268. package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  269. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  270. package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
  271. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  272. package/dist/modes/interactive/components/config-selector.d.ts +71 -0
  273. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  274. package/dist/modes/interactive/components/config-selector.js +479 -0
  275. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  276. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  277. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  278. package/dist/modes/interactive/components/countdown-timer.js +33 -0
  279. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  280. package/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  281. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  282. package/dist/modes/interactive/components/custom-editor.js +70 -0
  283. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  284. package/dist/modes/interactive/components/custom-message.d.ts +20 -0
  285. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  286. package/dist/modes/interactive/components/custom-message.js +79 -0
  287. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  288. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  289. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  290. package/dist/modes/interactive/components/daxnuts.js +140 -0
  291. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  292. package/dist/modes/interactive/components/diff.d.ts +12 -0
  293. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  294. package/dist/modes/interactive/components/diff.js +133 -0
  295. package/dist/modes/interactive/components/diff.js.map +1 -0
  296. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  297. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  298. package/dist/modes/interactive/components/dynamic-border.js +21 -0
  299. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  300. package/dist/modes/interactive/components/extension-editor.d.ts +17 -0
  301. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  302. package/dist/modes/interactive/components/extension-editor.js +102 -0
  303. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  304. package/dist/modes/interactive/components/extension-input.d.ts +23 -0
  305. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  306. package/dist/modes/interactive/components/extension-input.js +61 -0
  307. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  308. package/dist/modes/interactive/components/extension-selector.d.ts +24 -0
  309. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  310. package/dist/modes/interactive/components/extension-selector.js +78 -0
  311. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  312. package/dist/modes/interactive/components/footer.d.ts +26 -0
  313. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  314. package/dist/modes/interactive/components/footer.js +213 -0
  315. package/dist/modes/interactive/components/footer.js.map +1 -0
  316. package/dist/modes/interactive/components/index.d.ts +32 -0
  317. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  318. package/dist/modes/interactive/components/index.js +33 -0
  319. package/dist/modes/interactive/components/index.js.map +1 -0
  320. package/dist/modes/interactive/components/keybinding-hints.d.ts +41 -0
  321. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  322. package/dist/modes/interactive/components/keybinding-hints.js +61 -0
  323. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  324. package/dist/modes/interactive/components/login-dialog.d.ts +42 -0
  325. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  326. package/dist/modes/interactive/components/login-dialog.js +145 -0
  327. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  328. package/dist/modes/interactive/components/model-selector.d.ts +47 -0
  329. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  330. package/dist/modes/interactive/components/model-selector.js +271 -0
  331. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  332. package/dist/modes/interactive/components/oauth-selector.d.ts +19 -0
  333. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  334. package/dist/modes/interactive/components/oauth-selector.js +97 -0
  335. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  336. package/dist/modes/interactive/components/scoped-models-selector.d.ts +49 -0
  337. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  338. package/dist/modes/interactive/components/scoped-models-selector.js +275 -0
  339. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  340. package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  341. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  342. package/dist/modes/interactive/components/session-selector-search.js +155 -0
  343. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  344. package/dist/modes/interactive/components/session-selector.d.ts +95 -0
  345. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  346. package/dist/modes/interactive/components/session-selector.js +851 -0
  347. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  348. package/dist/modes/interactive/components/settings-selector.d.ts +58 -0
  349. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  350. package/dist/modes/interactive/components/settings-selector.js +299 -0
  351. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  352. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  353. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  354. package/dist/modes/interactive/components/show-images-selector.js +35 -0
  355. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  356. package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  357. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  358. package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
  359. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  360. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  361. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  362. package/dist/modes/interactive/components/theme-selector.js +46 -0
  363. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  364. package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  365. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  366. package/dist/modes/interactive/components/thinking-selector.js +47 -0
  367. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  368. package/dist/modes/interactive/components/tool-execution.d.ts +70 -0
  369. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  370. package/dist/modes/interactive/components/tool-execution.js +636 -0
  371. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  372. package/dist/modes/interactive/components/tree-selector.d.ts +68 -0
  373. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  374. package/dist/modes/interactive/components/tree-selector.js +934 -0
  375. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  376. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  377. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  378. package/dist/modes/interactive/components/user-message-selector.js +113 -0
  379. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  380. package/dist/modes/interactive/components/user-message.d.ts +8 -0
  381. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  382. package/dist/modes/interactive/components/user-message.js +16 -0
  383. package/dist/modes/interactive/components/user-message.js.map +1 -0
  384. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  385. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  386. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  387. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  388. package/dist/modes/interactive/interactive-mode.d.ts +316 -0
  389. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  390. package/dist/modes/interactive/interactive-mode.js +3848 -0
  391. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  392. package/dist/modes/interactive/theme/dark.json +85 -0
  393. package/dist/modes/interactive/theme/light.json +84 -0
  394. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  395. package/dist/modes/interactive/theme/theme.d.ts +78 -0
  396. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  397. package/dist/modes/interactive/theme/theme.js +944 -0
  398. package/dist/modes/interactive/theme/theme.js.map +1 -0
  399. package/dist/modes/print-mode.d.ts +28 -0
  400. package/dist/modes/print-mode.d.ts.map +1 -0
  401. package/dist/modes/print-mode.js +101 -0
  402. package/dist/modes/print-mode.js.map +1 -0
  403. package/dist/modes/rpc/rpc-client.d.ts +217 -0
  404. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  405. package/dist/modes/rpc/rpc-client.js +405 -0
  406. package/dist/modes/rpc/rpc-client.js.map +1 -0
  407. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  408. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  409. package/dist/modes/rpc/rpc-mode.js +511 -0
  410. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  411. package/dist/modes/rpc/rpc-types.d.ts +409 -0
  412. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  413. package/dist/modes/rpc/rpc-types.js +8 -0
  414. package/dist/modes/rpc/rpc-types.js.map +1 -0
  415. package/dist/utils/changelog.d.ts +21 -0
  416. package/dist/utils/changelog.d.ts.map +1 -0
  417. package/dist/utils/changelog.js +87 -0
  418. package/dist/utils/changelog.js.map +1 -0
  419. package/dist/utils/clipboard-image.d.ts +11 -0
  420. package/dist/utils/clipboard-image.d.ts.map +1 -0
  421. package/dist/utils/clipboard-image.js +162 -0
  422. package/dist/utils/clipboard-image.js.map +1 -0
  423. package/dist/utils/clipboard-native.d.ts +7 -0
  424. package/dist/utils/clipboard-native.d.ts.map +1 -0
  425. package/dist/utils/clipboard-native.js +14 -0
  426. package/dist/utils/clipboard-native.js.map +1 -0
  427. package/dist/utils/clipboard.d.ts +2 -0
  428. package/dist/utils/clipboard.d.ts.map +1 -0
  429. package/dist/utils/clipboard.js +67 -0
  430. package/dist/utils/clipboard.js.map +1 -0
  431. package/dist/utils/frontmatter.d.ts +8 -0
  432. package/dist/utils/frontmatter.d.ts.map +1 -0
  433. package/dist/utils/frontmatter.js +26 -0
  434. package/dist/utils/frontmatter.js.map +1 -0
  435. package/dist/utils/git.d.ts +26 -0
  436. package/dist/utils/git.d.ts.map +1 -0
  437. package/dist/utils/git.js +163 -0
  438. package/dist/utils/git.js.map +1 -0
  439. package/dist/utils/image-convert.d.ts +9 -0
  440. package/dist/utils/image-convert.d.ts.map +1 -0
  441. package/dist/utils/image-convert.js +35 -0
  442. package/dist/utils/image-convert.js.map +1 -0
  443. package/dist/utils/image-resize.d.ts +36 -0
  444. package/dist/utils/image-resize.d.ts.map +1 -0
  445. package/dist/utils/image-resize.js +181 -0
  446. package/dist/utils/image-resize.js.map +1 -0
  447. package/dist/utils/mime.d.ts +2 -0
  448. package/dist/utils/mime.d.ts.map +1 -0
  449. package/dist/utils/mime.js +26 -0
  450. package/dist/utils/mime.js.map +1 -0
  451. package/dist/utils/photon.d.ts +21 -0
  452. package/dist/utils/photon.d.ts.map +1 -0
  453. package/dist/utils/photon.js +121 -0
  454. package/dist/utils/photon.js.map +1 -0
  455. package/dist/utils/shell.d.ts +26 -0
  456. package/dist/utils/shell.d.ts.map +1 -0
  457. package/dist/utils/shell.js +186 -0
  458. package/dist/utils/shell.js.map +1 -0
  459. package/dist/utils/sleep.d.ts +5 -0
  460. package/dist/utils/sleep.d.ts.map +1 -0
  461. package/dist/utils/sleep.js +17 -0
  462. package/dist/utils/sleep.js.map +1 -0
  463. package/dist/utils/tools-manager.d.ts +3 -0
  464. package/dist/utils/tools-manager.d.ts.map +1 -0
  465. package/dist/utils/tools-manager.js +207 -0
  466. package/dist/utils/tools-manager.js.map +1 -0
  467. package/docs/compaction.md +390 -0
  468. package/docs/custom-provider.md +548 -0
  469. package/docs/development.md +69 -0
  470. package/docs/extensions.md +1935 -0
  471. package/docs/images/doom-extension.png +0 -0
  472. package/docs/images/exy.png +0 -0
  473. package/docs/images/interactive-mode.png +0 -0
  474. package/docs/images/tree-view.png +0 -0
  475. package/docs/json.md +79 -0
  476. package/docs/keybindings.md +174 -0
  477. package/docs/models.md +293 -0
  478. package/docs/packages.md +209 -0
  479. package/docs/prompt-templates.md +67 -0
  480. package/docs/providers.md +186 -0
  481. package/docs/rpc.md +1317 -0
  482. package/docs/sdk.md +968 -0
  483. package/docs/session.md +412 -0
  484. package/docs/settings.md +223 -0
  485. package/docs/shell-aliases.md +13 -0
  486. package/docs/skills.md +231 -0
  487. package/docs/terminal-setup.md +70 -0
  488. package/docs/termux.md +127 -0
  489. package/docs/themes.md +295 -0
  490. package/docs/tree.md +219 -0
  491. package/docs/tui.md +887 -0
  492. package/docs/windows.md +17 -0
  493. package/examples/README.md +25 -0
  494. package/examples/extensions/README.md +203 -0
  495. package/examples/extensions/antigravity-image-gen.ts +413 -0
  496. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  497. package/examples/extensions/bash-spawn-hook.ts +30 -0
  498. package/examples/extensions/bookmark.ts +50 -0
  499. package/examples/extensions/claude-rules.ts +86 -0
  500. package/examples/extensions/commands.ts +72 -0
  501. package/examples/extensions/confirm-destructive.ts +59 -0
  502. package/examples/extensions/custom-compaction.ts +114 -0
  503. package/examples/extensions/custom-footer.ts +64 -0
  504. package/examples/extensions/custom-header.ts +73 -0
  505. package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  506. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  507. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  508. package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
  509. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  510. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  511. package/examples/extensions/custom-provider-qwen-cli/index.ts +345 -0
  512. package/examples/extensions/custom-provider-qwen-cli/package.json +16 -0
  513. package/examples/extensions/dirty-repo-guard.ts +56 -0
  514. package/examples/extensions/doom-overlay/README.md +46 -0
  515. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  516. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  517. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  518. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  519. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  520. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  521. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  522. package/examples/extensions/doom-overlay/index.ts +74 -0
  523. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  524. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  525. package/examples/extensions/dynamic-resources/dynamic.json +79 -0
  526. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  527. package/examples/extensions/dynamic-resources/index.ts +15 -0
  528. package/examples/extensions/event-bus.ts +43 -0
  529. package/examples/extensions/file-trigger.ts +41 -0
  530. package/examples/extensions/git-checkpoint.ts +53 -0
  531. package/examples/extensions/handoff.ts +150 -0
  532. package/examples/extensions/hello.ts +25 -0
  533. package/examples/extensions/inline-bash.ts +94 -0
  534. package/examples/extensions/input-transform.ts +43 -0
  535. package/examples/extensions/interactive-shell.ts +196 -0
  536. package/examples/extensions/mac-system-theme.ts +47 -0
  537. package/examples/extensions/message-renderer.ts +59 -0
  538. package/examples/extensions/minimal-mode.ts +426 -0
  539. package/examples/extensions/modal-editor.ts +85 -0
  540. package/examples/extensions/model-status.ts +31 -0
  541. package/examples/extensions/notify.ts +55 -0
  542. package/examples/extensions/overlay-qa-tests.ts +881 -0
  543. package/examples/extensions/overlay-test.ts +150 -0
  544. package/examples/extensions/permission-gate.ts +34 -0
  545. package/examples/extensions/pirate.ts +47 -0
  546. package/examples/extensions/plan-mode/README.md +65 -0
  547. package/examples/extensions/plan-mode/index.ts +340 -0
  548. package/examples/extensions/plan-mode/utils.ts +168 -0
  549. package/examples/extensions/preset.ts +398 -0
  550. package/examples/extensions/protected-paths.ts +30 -0
  551. package/examples/extensions/qna.ts +119 -0
  552. package/examples/extensions/question.ts +264 -0
  553. package/examples/extensions/questionnaire.ts +427 -0
  554. package/examples/extensions/rainbow-editor.ts +88 -0
  555. package/examples/extensions/reload-runtime.ts +37 -0
  556. package/examples/extensions/rpc-demo.ts +124 -0
  557. package/examples/extensions/sandbox/index.ts +318 -0
  558. package/examples/extensions/sandbox/package-lock.json +92 -0
  559. package/examples/extensions/sandbox/package.json +19 -0
  560. package/examples/extensions/send-user-message.ts +97 -0
  561. package/examples/extensions/session-name.ts +27 -0
  562. package/examples/extensions/shutdown-command.ts +63 -0
  563. package/examples/extensions/snake.ts +343 -0
  564. package/examples/extensions/space-invaders.ts +560 -0
  565. package/examples/extensions/ssh.ts +220 -0
  566. package/examples/extensions/status-line.ts +40 -0
  567. package/examples/extensions/subagent/README.md +172 -0
  568. package/examples/extensions/subagent/agents/planner.md +37 -0
  569. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  570. package/examples/extensions/subagent/agents/scout.md +50 -0
  571. package/examples/extensions/subagent/agents/worker.md +24 -0
  572. package/examples/extensions/subagent/agents.ts +127 -0
  573. package/examples/extensions/subagent/index.ts +964 -0
  574. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  575. package/examples/extensions/subagent/prompts/implement.md +10 -0
  576. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  577. package/examples/extensions/summarize.ts +195 -0
  578. package/examples/extensions/system-prompt-header.ts +17 -0
  579. package/examples/extensions/timed-confirm.ts +70 -0
  580. package/examples/extensions/titlebar-spinner.ts +58 -0
  581. package/examples/extensions/todo.ts +299 -0
  582. package/examples/extensions/tool-override.ts +143 -0
  583. package/examples/extensions/tools.ts +146 -0
  584. package/examples/extensions/trigger-compact.ts +40 -0
  585. package/examples/extensions/truncated-tool.ts +192 -0
  586. package/examples/extensions/widget-placement.ts +17 -0
  587. package/examples/extensions/with-deps/index.ts +36 -0
  588. package/examples/extensions/with-deps/package-lock.json +31 -0
  589. package/examples/extensions/with-deps/package.json +22 -0
  590. package/examples/rpc-extension-ui.ts +632 -0
  591. package/examples/sdk/01-minimal.ts +22 -0
  592. package/examples/sdk/02-custom-model.ts +49 -0
  593. package/examples/sdk/03-custom-prompt.ts +55 -0
  594. package/examples/sdk/04-skills.ts +46 -0
  595. package/examples/sdk/05-tools.ts +56 -0
  596. package/examples/sdk/06-extensions.ts +88 -0
  597. package/examples/sdk/07-context-files.ts +40 -0
  598. package/examples/sdk/08-prompt-templates.ts +47 -0
  599. package/examples/sdk/09-api-keys-and-oauth.ts +48 -0
  600. package/examples/sdk/10-settings.ts +51 -0
  601. package/examples/sdk/11-sessions.ts +48 -0
  602. package/examples/sdk/12-full-control.ts +82 -0
  603. package/examples/sdk/README.md +144 -0
  604. package/package.json +96 -0
@@ -0,0 +1,162 @@
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 ? [preferred, ...SUPPORTED_IMAGE_MIME_TYPES] : [...SUPPORTED_IMAGE_MIME_TYPES];
120
+ for (const mimeType of tryTypes) {
121
+ const data = runCommand("xclip", ["-selection", "clipboard", "-t", mimeType, "-o"]);
122
+ if (data.ok && data.stdout.length > 0) {
123
+ return { bytes: data.stdout, mimeType: baseMimeType(mimeType) };
124
+ }
125
+ }
126
+ return null;
127
+ }
128
+ export async function readClipboardImage(options) {
129
+ const env = options?.env ?? process.env;
130
+ const platform = options?.platform ?? process.platform;
131
+ if (env.TERMUX_VERSION) {
132
+ return null;
133
+ }
134
+ let image = null;
135
+ if (platform === "linux" && isWaylandSession(env)) {
136
+ image = readClipboardImageViaWlPaste() ?? readClipboardImageViaXclip();
137
+ }
138
+ else {
139
+ if (!clipboard || !clipboard.hasImage()) {
140
+ return null;
141
+ }
142
+ const imageData = await clipboard.getImageBinary();
143
+ if (!imageData || imageData.length === 0) {
144
+ return null;
145
+ }
146
+ const bytes = imageData instanceof Uint8Array ? imageData : Uint8Array.from(imageData);
147
+ image = { bytes, mimeType: "image/png" };
148
+ }
149
+ if (!image) {
150
+ return null;
151
+ }
152
+ // Convert unsupported formats (e.g., BMP from WSLg) to PNG
153
+ if (!isSupportedImageMimeType(image.mimeType)) {
154
+ const pngBytes = await convertToPng(image.bytes);
155
+ if (!pngBytes) {
156
+ return null;
157
+ }
158
+ return { bytes: pngBytes, mimeType: "image/png" };
159
+ }
160
+ return image;
161
+ }
162
+ //# sourceMappingURL=clipboard-image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clipboard-image.js","sourceRoot":"","sources":["../../src/utils/clipboard-image.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawnSync } from \"child_process\";\r\n\r\nimport { clipboard } from \"./clipboard-native.js\";\r\nimport { loadPhoton } from \"./photon.js\";\r\n\r\nexport type ClipboardImage = {\r\n\tbytes: Uint8Array;\r\n\tmimeType: string;\r\n};\r\n\r\nconst SUPPORTED_IMAGE_MIME_TYPES = [\"image/png\", \"image/jpeg\", \"image/webp\", \"image/gif\"] as const;\r\n\r\nconst DEFAULT_LIST_TIMEOUT_MS = 1000;\r\nconst DEFAULT_READ_TIMEOUT_MS = 3000;\r\nconst DEFAULT_MAX_BUFFER_BYTES = 50 * 1024 * 1024;\r\n\r\nexport function isWaylandSession(env: NodeJS.ProcessEnv = process.env): boolean {\r\n\treturn Boolean(env.WAYLAND_DISPLAY) || env.XDG_SESSION_TYPE === \"wayland\";\r\n}\r\n\r\nfunction baseMimeType(mimeType: string): string {\r\n\treturn mimeType.split(\";\")[0]?.trim().toLowerCase() ?? mimeType.toLowerCase();\r\n}\r\n\r\nexport function extensionForImageMimeType(mimeType: string): string | null {\r\n\tswitch (baseMimeType(mimeType)) {\r\n\t\tcase \"image/png\":\r\n\t\t\treturn \"png\";\r\n\t\tcase \"image/jpeg\":\r\n\t\t\treturn \"jpg\";\r\n\t\tcase \"image/webp\":\r\n\t\t\treturn \"webp\";\r\n\t\tcase \"image/gif\":\r\n\t\t\treturn \"gif\";\r\n\t\tdefault:\r\n\t\t\treturn null;\r\n\t}\r\n}\r\n\r\nfunction selectPreferredImageMimeType(mimeTypes: string[]): string | null {\r\n\tconst normalized = mimeTypes\r\n\t\t.map((t) => t.trim())\r\n\t\t.filter(Boolean)\r\n\t\t.map((t) => ({ raw: t, base: baseMimeType(t) }));\r\n\r\n\tfor (const preferred of SUPPORTED_IMAGE_MIME_TYPES) {\r\n\t\tconst match = normalized.find((t) => t.base === preferred);\r\n\t\tif (match) {\r\n\t\t\treturn match.raw;\r\n\t\t}\r\n\t}\r\n\r\n\tconst anyImage = normalized.find((t) => t.base.startsWith(\"image/\"));\r\n\treturn anyImage?.raw ?? null;\r\n}\r\n\r\nfunction isSupportedImageMimeType(mimeType: string): boolean {\r\n\tconst base = baseMimeType(mimeType);\r\n\treturn SUPPORTED_IMAGE_MIME_TYPES.some((t) => t === base);\r\n}\r\n\r\n/**\r\n * Convert unsupported image formats to PNG using Photon.\r\n * Returns null if conversion is unavailable or fails.\r\n */\r\nasync function convertToPng(bytes: Uint8Array): Promise<Uint8Array | null> {\r\n\tconst photon = await loadPhoton();\r\n\tif (!photon) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\ttry {\r\n\t\tconst image = photon.PhotonImage.new_from_byteslice(bytes);\r\n\t\ttry {\r\n\t\t\treturn image.get_bytes();\r\n\t\t} finally {\r\n\t\t\timage.free();\r\n\t\t}\r\n\t} catch {\r\n\t\treturn null;\r\n\t}\r\n}\r\n\r\nfunction runCommand(\r\n\tcommand: string,\r\n\targs: string[],\r\n\toptions?: { timeoutMs?: number; maxBufferBytes?: number },\r\n): { stdout: Buffer; ok: boolean } {\r\n\tconst timeoutMs = options?.timeoutMs ?? DEFAULT_READ_TIMEOUT_MS;\r\n\tconst maxBufferBytes = options?.maxBufferBytes ?? DEFAULT_MAX_BUFFER_BYTES;\r\n\r\n\tconst result = spawnSync(command, args, {\r\n\t\ttimeout: timeoutMs,\r\n\t\tmaxBuffer: maxBufferBytes,\r\n\t});\r\n\r\n\tif (result.error) {\r\n\t\treturn { ok: false, stdout: Buffer.alloc(0) };\r\n\t}\r\n\r\n\tif (result.status !== 0) {\r\n\t\treturn { ok: false, stdout: Buffer.alloc(0) };\r\n\t}\r\n\r\n\tconst stdout = Buffer.isBuffer(result.stdout)\r\n\t\t? result.stdout\r\n\t\t: Buffer.from(result.stdout ?? \"\", typeof result.stdout === \"string\" ? \"utf-8\" : undefined);\r\n\r\n\treturn { ok: true, stdout };\r\n}\r\n\r\nfunction readClipboardImageViaWlPaste(): ClipboardImage | null {\r\n\tconst list = runCommand(\"wl-paste\", [\"--list-types\"], { timeoutMs: DEFAULT_LIST_TIMEOUT_MS });\r\n\tif (!list.ok) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tconst types = list.stdout\r\n\t\t.toString(\"utf-8\")\r\n\t\t.split(/\\r?\\n/)\r\n\t\t.map((t) => t.trim())\r\n\t\t.filter(Boolean);\r\n\r\n\tconst selectedType = selectPreferredImageMimeType(types);\r\n\tif (!selectedType) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tconst data = runCommand(\"wl-paste\", [\"--type\", selectedType, \"--no-newline\"]);\r\n\tif (!data.ok || data.stdout.length === 0) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\treturn { bytes: data.stdout, mimeType: baseMimeType(selectedType) };\r\n}\r\n\r\nfunction readClipboardImageViaXclip(): ClipboardImage | null {\r\n\tconst targets = runCommand(\"xclip\", [\"-selection\", \"clipboard\", \"-t\", \"TARGETS\", \"-o\"], {\r\n\t\ttimeoutMs: DEFAULT_LIST_TIMEOUT_MS,\r\n\t});\r\n\r\n\tlet candidateTypes: string[] = [];\r\n\tif (targets.ok) {\r\n\t\tcandidateTypes = targets.stdout\r\n\t\t\t.toString(\"utf-8\")\r\n\t\t\t.split(/\\r?\\n/)\r\n\t\t\t.map((t) => t.trim())\r\n\t\t\t.filter(Boolean);\r\n\t}\r\n\r\n\tconst preferred = candidateTypes.length > 0 ? selectPreferredImageMimeType(candidateTypes) : null;\r\n\tconst tryTypes = preferred ? [preferred, ...SUPPORTED_IMAGE_MIME_TYPES] : [...SUPPORTED_IMAGE_MIME_TYPES];\r\n\r\n\tfor (const mimeType of tryTypes) {\r\n\t\tconst data = runCommand(\"xclip\", [\"-selection\", \"clipboard\", \"-t\", mimeType, \"-o\"]);\r\n\t\tif (data.ok && data.stdout.length > 0) {\r\n\t\t\treturn { bytes: data.stdout, mimeType: baseMimeType(mimeType) };\r\n\t\t}\r\n\t}\r\n\r\n\treturn null;\r\n}\r\n\r\nexport async function readClipboardImage(options?: {\r\n\tenv?: NodeJS.ProcessEnv;\r\n\tplatform?: NodeJS.Platform;\r\n}): Promise<ClipboardImage | null> {\r\n\tconst env = options?.env ?? process.env;\r\n\tconst platform = options?.platform ?? process.platform;\r\n\r\n\tif (env.TERMUX_VERSION) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tlet image: ClipboardImage | null = null;\r\n\r\n\tif (platform === \"linux\" && isWaylandSession(env)) {\r\n\t\timage = readClipboardImageViaWlPaste() ?? readClipboardImageViaXclip();\r\n\t} else {\r\n\t\tif (!clipboard || !clipboard.hasImage()) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tconst imageData = await clipboard.getImageBinary();\r\n\t\tif (!imageData || imageData.length === 0) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\tconst bytes = imageData instanceof Uint8Array ? imageData : Uint8Array.from(imageData);\r\n\t\timage = { bytes, mimeType: \"image/png\" };\r\n\t}\r\n\r\n\tif (!image) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\t// Convert unsupported formats (e.g., BMP from WSLg) to PNG\r\n\tif (!isSupportedImageMimeType(image.mimeType)) {\r\n\t\tconst pngBytes = await convertToPng(image.bytes);\r\n\t\tif (!pngBytes) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\treturn { bytes: pngBytes, mimeType: \"image/png\" };\r\n\t}\r\n\r\n\treturn image;\r\n}\r\n"]}
@@ -0,0 +1,7 @@
1
+ export type ClipboardModule = {
2
+ hasImage: () => boolean;
3
+ getImageBinary: () => Promise<Array<number>>;
4
+ };
5
+ declare let clipboard: ClipboardModule | null;
6
+ export { clipboard };
7
+ //# sourceMappingURL=clipboard-native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clipboard-native.d.ts","sourceRoot":"","sources":["../../src/utils/clipboard-native.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,MAAM,OAAO,CAAC;IACxB,cAAc,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;CAC7C,CAAC;AAGF,QAAA,IAAI,SAAS,EAAE,eAAe,GAAG,IAAW,CAAC;AAY7C,OAAO,EAAE,SAAS,EAAE,CAAC","sourcesContent":["import { createRequire } from \"module\";\r\n\r\nexport type ClipboardModule = {\r\n\thasImage: () => boolean;\r\n\tgetImageBinary: () => Promise<Array<number>>;\r\n};\r\n\r\nconst require = createRequire(import.meta.url);\r\nlet clipboard: ClipboardModule | null = null;\r\n\r\nconst hasDisplay = process.platform !== \"linux\" || Boolean(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);\r\n\r\nif (!process.env.TERMUX_VERSION && hasDisplay) {\r\n\ttry {\r\n\t\tclipboard = require(\"@mariozechner/clipboard\") as ClipboardModule;\r\n\t} catch {\r\n\t\tclipboard = null;\r\n\t}\r\n}\r\n\r\nexport { clipboard };\r\n"]}
@@ -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 @@
1
+ {"version":3,"file":"clipboard-native.js","sourceRoot":"","sources":["../../src/utils/clipboard-native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAOvC,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,IAAI,SAAS,GAA2B,IAAI,CAAC;AAE7C,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AAE/G,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,UAAU,EAAE,CAAC;IAC/C,IAAI,CAAC;QACJ,SAAS,GAAG,OAAO,CAAC,yBAAyB,CAAoB,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACR,SAAS,GAAG,IAAI,CAAC;IAClB,CAAC;AACF,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,CAAC","sourcesContent":["import { createRequire } from \"module\";\r\n\r\nexport type ClipboardModule = {\r\n\thasImage: () => boolean;\r\n\tgetImageBinary: () => Promise<Array<number>>;\r\n};\r\n\r\nconst require = createRequire(import.meta.url);\r\nlet clipboard: ClipboardModule | null = null;\r\n\r\nconst hasDisplay = process.platform !== \"linux\" || Boolean(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);\r\n\r\nif (!process.env.TERMUX_VERSION && hasDisplay) {\r\n\ttry {\r\n\t\tclipboard = require(\"@mariozechner/clipboard\") as ClipboardModule;\r\n\t} catch {\r\n\t\tclipboard = null;\r\n\t}\r\n}\r\n\r\nexport { clipboard };\r\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function copyToClipboard(text: string): void;
2
+ //# sourceMappingURL=clipboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clipboard.d.ts","sourceRoot":"","sources":["../../src/utils/clipboard.ts"],"names":[],"mappings":"AAIA,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAyDlD","sourcesContent":["import { execSync, spawn } from \"child_process\";\r\nimport { platform } from \"os\";\r\nimport { isWaylandSession } from \"./clipboard-image.js\";\r\n\r\nexport function copyToClipboard(text: string): void {\r\n\t// Always emit OSC 52 - works over SSH/mosh, harmless locally\r\n\tconst encoded = Buffer.from(text).toString(\"base64\");\r\n\tprocess.stdout.write(`\\x1b]52;c;${encoded}\\x07`);\r\n\r\n\t// Also try native tools (best effort for local sessions)\r\n\tconst p = platform();\r\n\tconst options = { input: text, timeout: 5000 };\r\n\r\n\ttry {\r\n\t\tif (p === \"darwin\") {\r\n\t\t\texecSync(\"pbcopy\", options);\r\n\t\t} else if (p === \"win32\") {\r\n\t\t\texecSync(\"clip\", options);\r\n\t\t} else {\r\n\t\t\t// Linux. Try Termux, Wayland, or X11 clipboard tools.\r\n\t\t\tif (process.env.TERMUX_VERSION) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\texecSync(\"termux-clipboard-set\", options);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t} catch {\r\n\t\t\t\t\t// Fall back to Wayland or X11 tools.\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tconst isWayland = isWaylandSession();\r\n\t\t\tif (isWayland) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\t// Verify wl-copy exists (spawn errors are async and won't be caught)\r\n\t\t\t\t\texecSync(\"which wl-copy\", { stdio: \"ignore\" });\r\n\t\t\t\t\t// wl-copy with execSync hangs due to fork behavior; use spawn instead\r\n\t\t\t\t\tconst proc = spawn(\"wl-copy\", [], { stdio: [\"pipe\", \"ignore\", \"ignore\"] });\r\n\t\t\t\t\tproc.stdin.on(\"error\", () => {\r\n\t\t\t\t\t\t// Ignore EPIPE errors if wl-copy exits early\r\n\t\t\t\t\t});\r\n\t\t\t\t\tproc.stdin.write(text);\r\n\t\t\t\t\tproc.stdin.end();\r\n\t\t\t\t\tproc.unref();\r\n\t\t\t\t} catch {\r\n\t\t\t\t\t// Fall back to xclip/xsel (works on XWayland)\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\texecSync(\"xclip -selection clipboard\", options);\r\n\t\t\t\t\t} catch {\r\n\t\t\t\t\t\texecSync(\"xsel --clipboard --input\", options);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\ttry {\r\n\t\t\t\t\texecSync(\"xclip -selection clipboard\", options);\r\n\t\t\t\t} catch {\r\n\t\t\t\t\texecSync(\"xsel --clipboard --input\", options);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t} catch {\r\n\t\t// Ignore - OSC 52 already emitted as fallback\r\n\t}\r\n}\r\n"]}
@@ -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 @@
1
+ {"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../../src/utils/clipboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,UAAU,eAAe,CAAC,IAAY,EAAQ;IACnD,6DAA6D;IAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,OAAO,MAAM,CAAC,CAAC;IAEjD,yDAAyD;IACzD,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;IACrB,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAE/C,IAAI,CAAC;QACJ,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;YACpB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC7B,CAAC;aAAM,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC;YAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACP,sDAAsD;YACtD,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;gBAChC,IAAI,CAAC;oBACJ,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;oBAC1C,OAAO;gBACR,CAAC;gBAAC,MAAM,CAAC;oBACR,qCAAqC;gBACtC,CAAC;YACF,CAAC;YAED,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC;YACrC,IAAI,SAAS,EAAE,CAAC;gBACf,IAAI,CAAC;oBACJ,qEAAqE;oBACrE,QAAQ,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;oBAC/C,sEAAsE;oBACtE,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;oBAC3E,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC;wBAC5B,6CAA6C;oBADhB,CAE7B,CAAC,CAAC;oBACH,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACvB,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;oBACjB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACd,CAAC;gBAAC,MAAM,CAAC;oBACR,8CAA8C;oBAC9C,IAAI,CAAC;wBACJ,QAAQ,CAAC,4BAA4B,EAAE,OAAO,CAAC,CAAC;oBACjD,CAAC;oBAAC,MAAM,CAAC;wBACR,QAAQ,CAAC,0BAA0B,EAAE,OAAO,CAAC,CAAC;oBAC/C,CAAC;gBACF,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,IAAI,CAAC;oBACJ,QAAQ,CAAC,4BAA4B,EAAE,OAAO,CAAC,CAAC;gBACjD,CAAC;gBAAC,MAAM,CAAC;oBACR,QAAQ,CAAC,0BAA0B,EAAE,OAAO,CAAC,CAAC;gBAC/C,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,8CAA8C;IAC/C,CAAC;AAAA,CACD","sourcesContent":["import { execSync, spawn } from \"child_process\";\r\nimport { platform } from \"os\";\r\nimport { isWaylandSession } from \"./clipboard-image.js\";\r\n\r\nexport function copyToClipboard(text: string): void {\r\n\t// Always emit OSC 52 - works over SSH/mosh, harmless locally\r\n\tconst encoded = Buffer.from(text).toString(\"base64\");\r\n\tprocess.stdout.write(`\\x1b]52;c;${encoded}\\x07`);\r\n\r\n\t// Also try native tools (best effort for local sessions)\r\n\tconst p = platform();\r\n\tconst options = { input: text, timeout: 5000 };\r\n\r\n\ttry {\r\n\t\tif (p === \"darwin\") {\r\n\t\t\texecSync(\"pbcopy\", options);\r\n\t\t} else if (p === \"win32\") {\r\n\t\t\texecSync(\"clip\", options);\r\n\t\t} else {\r\n\t\t\t// Linux. Try Termux, Wayland, or X11 clipboard tools.\r\n\t\t\tif (process.env.TERMUX_VERSION) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\texecSync(\"termux-clipboard-set\", options);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t} catch {\r\n\t\t\t\t\t// Fall back to Wayland or X11 tools.\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tconst isWayland = isWaylandSession();\r\n\t\t\tif (isWayland) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\t// Verify wl-copy exists (spawn errors are async and won't be caught)\r\n\t\t\t\t\texecSync(\"which wl-copy\", { stdio: \"ignore\" });\r\n\t\t\t\t\t// wl-copy with execSync hangs due to fork behavior; use spawn instead\r\n\t\t\t\t\tconst proc = spawn(\"wl-copy\", [], { stdio: [\"pipe\", \"ignore\", \"ignore\"] });\r\n\t\t\t\t\tproc.stdin.on(\"error\", () => {\r\n\t\t\t\t\t\t// Ignore EPIPE errors if wl-copy exits early\r\n\t\t\t\t\t});\r\n\t\t\t\t\tproc.stdin.write(text);\r\n\t\t\t\t\tproc.stdin.end();\r\n\t\t\t\t\tproc.unref();\r\n\t\t\t\t} catch {\r\n\t\t\t\t\t// Fall back to xclip/xsel (works on XWayland)\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\texecSync(\"xclip -selection clipboard\", options);\r\n\t\t\t\t\t} catch {\r\n\t\t\t\t\t\texecSync(\"xsel --clipboard --input\", options);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\ttry {\r\n\t\t\t\t\texecSync(\"xclip -selection clipboard\", options);\r\n\t\t\t\t} catch {\r\n\t\t\t\t\texecSync(\"xsel --clipboard --input\", options);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t} catch {\r\n\t\t// Ignore - OSC 52 already emitted as fallback\r\n\t}\r\n}\r\n"]}
@@ -0,0 +1,8 @@
1
+ type ParsedFrontmatter<T extends Record<string, unknown>> = {
2
+ frontmatter: T;
3
+ body: string;
4
+ };
5
+ export declare const parseFrontmatter: <T extends Record<string, unknown> = Record<string, unknown>>(content: string) => ParsedFrontmatter<T>;
6
+ export declare const stripFrontmatter: (content: string) => string;
7
+ export {};
8
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../src/utils/frontmatter.ts"],"names":[],"mappings":"AAEA,KAAK,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IAC3D,WAAW,EAAE,CAAC,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACb,CAAC;AAsBF,eAAO,MAAM,gBAAgB,GAAI,CAAC,oGASjC,CAAC;AAEF,eAAO,MAAM,gBAAgB,6BAA8D,CAAC","sourcesContent":["import { parse } from \"yaml\";\r\n\r\ntype ParsedFrontmatter<T extends Record<string, unknown>> = {\r\n\tfrontmatter: T;\r\n\tbody: string;\r\n};\r\n\r\nconst normalizeNewlines = (value: string): string => value.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\r\n\r\nconst extractFrontmatter = (content: string): { yamlString: string | null; body: string } => {\r\n\tconst normalized = normalizeNewlines(content);\r\n\r\n\tif (!normalized.startsWith(\"---\")) {\r\n\t\treturn { yamlString: null, body: normalized };\r\n\t}\r\n\r\n\tconst endIndex = normalized.indexOf(\"\\n---\", 3);\r\n\tif (endIndex === -1) {\r\n\t\treturn { yamlString: null, body: normalized };\r\n\t}\r\n\r\n\treturn {\r\n\t\tyamlString: normalized.slice(4, endIndex),\r\n\t\tbody: normalized.slice(endIndex + 4).trim(),\r\n\t};\r\n};\r\n\r\nexport const parseFrontmatter = <T extends Record<string, unknown> = Record<string, unknown>>(\r\n\tcontent: string,\r\n): ParsedFrontmatter<T> => {\r\n\tconst { yamlString, body } = extractFrontmatter(content);\r\n\tif (!yamlString) {\r\n\t\treturn { frontmatter: {} as T, body };\r\n\t}\r\n\tconst parsed = parse(yamlString);\r\n\treturn { frontmatter: (parsed ?? {}) as T, body };\r\n};\r\n\r\nexport const stripFrontmatter = (content: string): string => parseFrontmatter(content).body;\r\n"]}
@@ -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 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/utils/frontmatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAO7B,MAAM,iBAAiB,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAEvG,MAAM,kBAAkB,GAAG,CAAC,OAAe,EAA+C,EAAE,CAAC;IAC5F,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAE9C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAChD,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAC/C,CAAC;IAED,OAAO;QACN,UAAU,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;QACzC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE;KAC3C,CAAC;AAAA,CACF,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC/B,OAAe,EACQ,EAAE,CAAC;IAC1B,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,OAAO,EAAE,WAAW,EAAE,EAAO,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;IACjC,OAAO,EAAE,WAAW,EAAE,CAAC,MAAM,IAAI,EAAE,CAAM,EAAE,IAAI,EAAE,CAAC;AAAA,CAClD,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAU,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC","sourcesContent":["import { parse } from \"yaml\";\r\n\r\ntype ParsedFrontmatter<T extends Record<string, unknown>> = {\r\n\tfrontmatter: T;\r\n\tbody: string;\r\n};\r\n\r\nconst normalizeNewlines = (value: string): string => value.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\r\n\r\nconst extractFrontmatter = (content: string): { yamlString: string | null; body: string } => {\r\n\tconst normalized = normalizeNewlines(content);\r\n\r\n\tif (!normalized.startsWith(\"---\")) {\r\n\t\treturn { yamlString: null, body: normalized };\r\n\t}\r\n\r\n\tconst endIndex = normalized.indexOf(\"\\n---\", 3);\r\n\tif (endIndex === -1) {\r\n\t\treturn { yamlString: null, body: normalized };\r\n\t}\r\n\r\n\treturn {\r\n\t\tyamlString: normalized.slice(4, endIndex),\r\n\t\tbody: normalized.slice(endIndex + 4).trim(),\r\n\t};\r\n};\r\n\r\nexport const parseFrontmatter = <T extends Record<string, unknown> = Record<string, unknown>>(\r\n\tcontent: string,\r\n): ParsedFrontmatter<T> => {\r\n\tconst { yamlString, body } = extractFrontmatter(content);\r\n\tif (!yamlString) {\r\n\t\treturn { frontmatter: {} as T, body };\r\n\t}\r\n\tconst parsed = parse(yamlString);\r\n\treturn { frontmatter: (parsed ?? {}) as T, body };\r\n};\r\n\r\nexport const stripFrontmatter = (content: string): string => parseFrontmatter(content).body;\r\n"]}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Parsed git URL information.
3
+ */
4
+ export type GitSource = {
5
+ /** Always "git" for git sources */
6
+ type: "git";
7
+ /** Clone URL (always valid for git clone, without ref suffix) */
8
+ repo: string;
9
+ /** Git host domain (e.g., "github.com") */
10
+ host: string;
11
+ /** Repository path (e.g., "user/repo") */
12
+ path: string;
13
+ /** Git ref (branch, tag, commit) if specified */
14
+ ref?: string;
15
+ /** True if ref was specified (package won't be auto-updated) */
16
+ pinned: boolean;
17
+ };
18
+ /**
19
+ * Parse git source into a GitSource.
20
+ *
21
+ * Rules:
22
+ * - With git: prefix, accept all historical shorthand forms.
23
+ * - Without git: prefix, only accept explicit protocol URLs.
24
+ */
25
+ export declare function parseGitUrl(source: string): GitSource | null;
26
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACvB,mCAAmC;IACnC,IAAI,EAAE,KAAK,CAAC;IACZ,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,MAAM,EAAE,OAAO,CAAC;CAChB,CAAC;AA4GF;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CA0D5D","sourcesContent":["import hostedGitInfo from \"hosted-git-info\";\r\n\r\n/**\r\n * Parsed git URL information.\r\n */\r\nexport type GitSource = {\r\n\t/** Always \"git\" for git sources */\r\n\ttype: \"git\";\r\n\t/** Clone URL (always valid for git clone, without ref suffix) */\r\n\trepo: string;\r\n\t/** Git host domain (e.g., \"github.com\") */\r\n\thost: string;\r\n\t/** Repository path (e.g., \"user/repo\") */\r\n\tpath: string;\r\n\t/** Git ref (branch, tag, commit) if specified */\r\n\tref?: string;\r\n\t/** True if ref was specified (package won't be auto-updated) */\r\n\tpinned: boolean;\r\n};\r\n\r\nfunction splitRef(url: string): { repo: string; ref?: string } {\r\n\tconst scpLikeMatch = url.match(/^git@([^:]+):(.+)$/);\r\n\tif (scpLikeMatch) {\r\n\t\tconst pathWithMaybeRef = scpLikeMatch[2] ?? \"\";\r\n\t\tconst refSeparator = pathWithMaybeRef.indexOf(\"@\");\r\n\t\tif (refSeparator < 0) return { repo: url };\r\n\t\tconst repoPath = pathWithMaybeRef.slice(0, refSeparator);\r\n\t\tconst ref = pathWithMaybeRef.slice(refSeparator + 1);\r\n\t\tif (!repoPath || !ref) return { repo: url };\r\n\t\treturn {\r\n\t\t\trepo: `git@${scpLikeMatch[1] ?? \"\"}:${repoPath}`,\r\n\t\t\tref,\r\n\t\t};\r\n\t}\r\n\r\n\tif (url.includes(\"://\")) {\r\n\t\ttry {\r\n\t\t\tconst parsed = new URL(url);\r\n\t\t\tconst pathWithMaybeRef = parsed.pathname.replace(/^\\/+/, \"\");\r\n\t\t\tconst refSeparator = pathWithMaybeRef.indexOf(\"@\");\r\n\t\t\tif (refSeparator < 0) return { repo: url };\r\n\t\t\tconst repoPath = pathWithMaybeRef.slice(0, refSeparator);\r\n\t\t\tconst ref = pathWithMaybeRef.slice(refSeparator + 1);\r\n\t\t\tif (!repoPath || !ref) return { repo: url };\r\n\t\t\tparsed.pathname = `/${repoPath}`;\r\n\t\t\treturn {\r\n\t\t\t\trepo: parsed.toString().replace(/\\/$/, \"\"),\r\n\t\t\t\tref,\r\n\t\t\t};\r\n\t\t} catch {\r\n\t\t\treturn { repo: url };\r\n\t\t}\r\n\t}\r\n\r\n\tconst slashIndex = url.indexOf(\"/\");\r\n\tif (slashIndex < 0) {\r\n\t\treturn { repo: url };\r\n\t}\r\n\tconst host = url.slice(0, slashIndex);\r\n\tconst pathWithMaybeRef = url.slice(slashIndex + 1);\r\n\tconst refSeparator = pathWithMaybeRef.indexOf(\"@\");\r\n\tif (refSeparator < 0) {\r\n\t\treturn { repo: url };\r\n\t}\r\n\tconst repoPath = pathWithMaybeRef.slice(0, refSeparator);\r\n\tconst ref = pathWithMaybeRef.slice(refSeparator + 1);\r\n\tif (!repoPath || !ref) {\r\n\t\treturn { repo: url };\r\n\t}\r\n\treturn {\r\n\t\trepo: `${host}/${repoPath}`,\r\n\t\tref,\r\n\t};\r\n}\r\n\r\nfunction parseGenericGitUrl(url: string): GitSource | null {\r\n\tconst { repo: repoWithoutRef, ref } = splitRef(url);\r\n\tlet repo = repoWithoutRef;\r\n\tlet host = \"\";\r\n\tlet path = \"\";\r\n\r\n\tconst scpLikeMatch = repoWithoutRef.match(/^git@([^:]+):(.+)$/);\r\n\tif (scpLikeMatch) {\r\n\t\thost = scpLikeMatch[1] ?? \"\";\r\n\t\tpath = scpLikeMatch[2] ?? \"\";\r\n\t} else if (\r\n\t\trepoWithoutRef.startsWith(\"https://\") ||\r\n\t\trepoWithoutRef.startsWith(\"http://\") ||\r\n\t\trepoWithoutRef.startsWith(\"ssh://\") ||\r\n\t\trepoWithoutRef.startsWith(\"git://\")\r\n\t) {\r\n\t\ttry {\r\n\t\t\tconst parsed = new URL(repoWithoutRef);\r\n\t\t\thost = parsed.hostname;\r\n\t\t\tpath = parsed.pathname.replace(/^\\/+/, \"\");\r\n\t\t} catch {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t} else {\r\n\t\tconst slashIndex = repoWithoutRef.indexOf(\"/\");\r\n\t\tif (slashIndex < 0) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\thost = repoWithoutRef.slice(0, slashIndex);\r\n\t\tpath = repoWithoutRef.slice(slashIndex + 1);\r\n\t\tif (!host.includes(\".\") && host !== \"localhost\") {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\trepo = `https://${repoWithoutRef}`;\r\n\t}\r\n\r\n\tconst normalizedPath = path.replace(/\\.git$/, \"\").replace(/^\\/+/, \"\");\r\n\tif (!host || !normalizedPath || normalizedPath.split(\"/\").length < 2) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\treturn {\r\n\t\ttype: \"git\",\r\n\t\trepo,\r\n\t\thost,\r\n\t\tpath: normalizedPath,\r\n\t\tref,\r\n\t\tpinned: Boolean(ref),\r\n\t};\r\n}\r\n\r\n/**\r\n * Parse git source into a GitSource.\r\n *\r\n * Rules:\r\n * - With git: prefix, accept all historical shorthand forms.\r\n * - Without git: prefix, only accept explicit protocol URLs.\r\n */\r\nexport function parseGitUrl(source: string): GitSource | null {\r\n\tconst trimmed = source.trim();\r\n\tconst hasGitPrefix = trimmed.startsWith(\"git:\");\r\n\tconst url = hasGitPrefix ? trimmed.slice(4).trim() : trimmed;\r\n\r\n\tif (!hasGitPrefix && !/^(https?|ssh|git):\\/\\//i.test(url)) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tconst split = splitRef(url);\r\n\r\n\tconst hostedCandidates = [split.ref ? `${split.repo}#${split.ref}` : undefined, url].filter(\r\n\t\t(value): value is string => Boolean(value),\r\n\t);\r\n\tfor (const candidate of hostedCandidates) {\r\n\t\tconst info = hostedGitInfo.fromUrl(candidate);\r\n\t\tif (info) {\r\n\t\t\tif (split.ref && info.project?.includes(\"@\")) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tconst useHttpsPrefix =\r\n\t\t\t\t!split.repo.startsWith(\"http://\") &&\r\n\t\t\t\t!split.repo.startsWith(\"https://\") &&\r\n\t\t\t\t!split.repo.startsWith(\"ssh://\") &&\r\n\t\t\t\t!split.repo.startsWith(\"git://\") &&\r\n\t\t\t\t!split.repo.startsWith(\"git@\");\r\n\t\t\treturn {\r\n\t\t\t\ttype: \"git\",\r\n\t\t\t\trepo: useHttpsPrefix ? `https://${split.repo}` : split.repo,\r\n\t\t\t\thost: info.domain || \"\",\r\n\t\t\t\tpath: `${info.user}/${info.project}`.replace(/\\.git$/, \"\"),\r\n\t\t\t\tref: info.committish || split.ref || undefined,\r\n\t\t\t\tpinned: Boolean(info.committish || split.ref),\r\n\t\t\t};\r\n\t\t}\r\n\t}\r\n\r\n\tconst httpsCandidates = [split.ref ? `https://${split.repo}#${split.ref}` : undefined, `https://${url}`].filter(\r\n\t\t(value): value is string => Boolean(value),\r\n\t);\r\n\tfor (const candidate of httpsCandidates) {\r\n\t\tconst info = hostedGitInfo.fromUrl(candidate);\r\n\t\tif (info) {\r\n\t\t\tif (split.ref && info.project?.includes(\"@\")) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\treturn {\r\n\t\t\t\ttype: \"git\",\r\n\t\t\t\trepo: `https://${split.repo}`,\r\n\t\t\t\thost: info.domain || \"\",\r\n\t\t\t\tpath: `${info.user}/${info.project}`.replace(/\\.git$/, \"\"),\r\n\t\t\t\tref: info.committish || split.ref || undefined,\r\n\t\t\t\tpinned: Boolean(info.committish || split.ref),\r\n\t\t\t};\r\n\t\t}\r\n\t}\r\n\r\n\treturn parseGenericGitUrl(url);\r\n}\r\n"]}
@@ -0,0 +1,163 @@
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 = [split.ref ? `https://${split.repo}#${split.ref}` : undefined, `https://${url}`].filter((value) => Boolean(value));
145
+ for (const candidate of httpsCandidates) {
146
+ const info = hostedGitInfo.fromUrl(candidate);
147
+ if (info) {
148
+ if (split.ref && info.project?.includes("@")) {
149
+ continue;
150
+ }
151
+ return {
152
+ type: "git",
153
+ repo: `https://${split.repo}`,
154
+ host: info.domain || "",
155
+ path: `${info.user}/${info.project}`.replace(/\.git$/, ""),
156
+ ref: info.committish || split.ref || undefined,
157
+ pinned: Boolean(info.committish || split.ref),
158
+ };
159
+ }
160
+ }
161
+ return parseGenericGitUrl(url);
162
+ }
163
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"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","sourcesContent":["import hostedGitInfo from \"hosted-git-info\";\r\n\r\n/**\r\n * Parsed git URL information.\r\n */\r\nexport type GitSource = {\r\n\t/** Always \"git\" for git sources */\r\n\ttype: \"git\";\r\n\t/** Clone URL (always valid for git clone, without ref suffix) */\r\n\trepo: string;\r\n\t/** Git host domain (e.g., \"github.com\") */\r\n\thost: string;\r\n\t/** Repository path (e.g., \"user/repo\") */\r\n\tpath: string;\r\n\t/** Git ref (branch, tag, commit) if specified */\r\n\tref?: string;\r\n\t/** True if ref was specified (package won't be auto-updated) */\r\n\tpinned: boolean;\r\n};\r\n\r\nfunction splitRef(url: string): { repo: string; ref?: string } {\r\n\tconst scpLikeMatch = url.match(/^git@([^:]+):(.+)$/);\r\n\tif (scpLikeMatch) {\r\n\t\tconst pathWithMaybeRef = scpLikeMatch[2] ?? \"\";\r\n\t\tconst refSeparator = pathWithMaybeRef.indexOf(\"@\");\r\n\t\tif (refSeparator < 0) return { repo: url };\r\n\t\tconst repoPath = pathWithMaybeRef.slice(0, refSeparator);\r\n\t\tconst ref = pathWithMaybeRef.slice(refSeparator + 1);\r\n\t\tif (!repoPath || !ref) return { repo: url };\r\n\t\treturn {\r\n\t\t\trepo: `git@${scpLikeMatch[1] ?? \"\"}:${repoPath}`,\r\n\t\t\tref,\r\n\t\t};\r\n\t}\r\n\r\n\tif (url.includes(\"://\")) {\r\n\t\ttry {\r\n\t\t\tconst parsed = new URL(url);\r\n\t\t\tconst pathWithMaybeRef = parsed.pathname.replace(/^\\/+/, \"\");\r\n\t\t\tconst refSeparator = pathWithMaybeRef.indexOf(\"@\");\r\n\t\t\tif (refSeparator < 0) return { repo: url };\r\n\t\t\tconst repoPath = pathWithMaybeRef.slice(0, refSeparator);\r\n\t\t\tconst ref = pathWithMaybeRef.slice(refSeparator + 1);\r\n\t\t\tif (!repoPath || !ref) return { repo: url };\r\n\t\t\tparsed.pathname = `/${repoPath}`;\r\n\t\t\treturn {\r\n\t\t\t\trepo: parsed.toString().replace(/\\/$/, \"\"),\r\n\t\t\t\tref,\r\n\t\t\t};\r\n\t\t} catch {\r\n\t\t\treturn { repo: url };\r\n\t\t}\r\n\t}\r\n\r\n\tconst slashIndex = url.indexOf(\"/\");\r\n\tif (slashIndex < 0) {\r\n\t\treturn { repo: url };\r\n\t}\r\n\tconst host = url.slice(0, slashIndex);\r\n\tconst pathWithMaybeRef = url.slice(slashIndex + 1);\r\n\tconst refSeparator = pathWithMaybeRef.indexOf(\"@\");\r\n\tif (refSeparator < 0) {\r\n\t\treturn { repo: url };\r\n\t}\r\n\tconst repoPath = pathWithMaybeRef.slice(0, refSeparator);\r\n\tconst ref = pathWithMaybeRef.slice(refSeparator + 1);\r\n\tif (!repoPath || !ref) {\r\n\t\treturn { repo: url };\r\n\t}\r\n\treturn {\r\n\t\trepo: `${host}/${repoPath}`,\r\n\t\tref,\r\n\t};\r\n}\r\n\r\nfunction parseGenericGitUrl(url: string): GitSource | null {\r\n\tconst { repo: repoWithoutRef, ref } = splitRef(url);\r\n\tlet repo = repoWithoutRef;\r\n\tlet host = \"\";\r\n\tlet path = \"\";\r\n\r\n\tconst scpLikeMatch = repoWithoutRef.match(/^git@([^:]+):(.+)$/);\r\n\tif (scpLikeMatch) {\r\n\t\thost = scpLikeMatch[1] ?? \"\";\r\n\t\tpath = scpLikeMatch[2] ?? \"\";\r\n\t} else if (\r\n\t\trepoWithoutRef.startsWith(\"https://\") ||\r\n\t\trepoWithoutRef.startsWith(\"http://\") ||\r\n\t\trepoWithoutRef.startsWith(\"ssh://\") ||\r\n\t\trepoWithoutRef.startsWith(\"git://\")\r\n\t) {\r\n\t\ttry {\r\n\t\t\tconst parsed = new URL(repoWithoutRef);\r\n\t\t\thost = parsed.hostname;\r\n\t\t\tpath = parsed.pathname.replace(/^\\/+/, \"\");\r\n\t\t} catch {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t} else {\r\n\t\tconst slashIndex = repoWithoutRef.indexOf(\"/\");\r\n\t\tif (slashIndex < 0) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\thost = repoWithoutRef.slice(0, slashIndex);\r\n\t\tpath = repoWithoutRef.slice(slashIndex + 1);\r\n\t\tif (!host.includes(\".\") && host !== \"localhost\") {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\trepo = `https://${repoWithoutRef}`;\r\n\t}\r\n\r\n\tconst normalizedPath = path.replace(/\\.git$/, \"\").replace(/^\\/+/, \"\");\r\n\tif (!host || !normalizedPath || normalizedPath.split(\"/\").length < 2) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\treturn {\r\n\t\ttype: \"git\",\r\n\t\trepo,\r\n\t\thost,\r\n\t\tpath: normalizedPath,\r\n\t\tref,\r\n\t\tpinned: Boolean(ref),\r\n\t};\r\n}\r\n\r\n/**\r\n * Parse git source into a GitSource.\r\n *\r\n * Rules:\r\n * - With git: prefix, accept all historical shorthand forms.\r\n * - Without git: prefix, only accept explicit protocol URLs.\r\n */\r\nexport function parseGitUrl(source: string): GitSource | null {\r\n\tconst trimmed = source.trim();\r\n\tconst hasGitPrefix = trimmed.startsWith(\"git:\");\r\n\tconst url = hasGitPrefix ? trimmed.slice(4).trim() : trimmed;\r\n\r\n\tif (!hasGitPrefix && !/^(https?|ssh|git):\\/\\//i.test(url)) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tconst split = splitRef(url);\r\n\r\n\tconst hostedCandidates = [split.ref ? `${split.repo}#${split.ref}` : undefined, url].filter(\r\n\t\t(value): value is string => Boolean(value),\r\n\t);\r\n\tfor (const candidate of hostedCandidates) {\r\n\t\tconst info = hostedGitInfo.fromUrl(candidate);\r\n\t\tif (info) {\r\n\t\t\tif (split.ref && info.project?.includes(\"@\")) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tconst useHttpsPrefix =\r\n\t\t\t\t!split.repo.startsWith(\"http://\") &&\r\n\t\t\t\t!split.repo.startsWith(\"https://\") &&\r\n\t\t\t\t!split.repo.startsWith(\"ssh://\") &&\r\n\t\t\t\t!split.repo.startsWith(\"git://\") &&\r\n\t\t\t\t!split.repo.startsWith(\"git@\");\r\n\t\t\treturn {\r\n\t\t\t\ttype: \"git\",\r\n\t\t\t\trepo: useHttpsPrefix ? `https://${split.repo}` : split.repo,\r\n\t\t\t\thost: info.domain || \"\",\r\n\t\t\t\tpath: `${info.user}/${info.project}`.replace(/\\.git$/, \"\"),\r\n\t\t\t\tref: info.committish || split.ref || undefined,\r\n\t\t\t\tpinned: Boolean(info.committish || split.ref),\r\n\t\t\t};\r\n\t\t}\r\n\t}\r\n\r\n\tconst httpsCandidates = [split.ref ? `https://${split.repo}#${split.ref}` : undefined, `https://${url}`].filter(\r\n\t\t(value): value is string => Boolean(value),\r\n\t);\r\n\tfor (const candidate of httpsCandidates) {\r\n\t\tconst info = hostedGitInfo.fromUrl(candidate);\r\n\t\tif (info) {\r\n\t\t\tif (split.ref && info.project?.includes(\"@\")) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\treturn {\r\n\t\t\t\ttype: \"git\",\r\n\t\t\t\trepo: `https://${split.repo}`,\r\n\t\t\t\thost: info.domain || \"\",\r\n\t\t\t\tpath: `${info.user}/${info.project}`.replace(/\\.git$/, \"\"),\r\n\t\t\t\tref: info.committish || split.ref || undefined,\r\n\t\t\t\tpinned: Boolean(info.committish || split.ref),\r\n\t\t\t};\r\n\t\t}\r\n\t}\r\n\r\n\treturn parseGenericGitUrl(url);\r\n}\r\n"]}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Convert image to PNG format for terminal display.
3
+ * Kitty graphics protocol requires PNG format (f=100).
4
+ */
5
+ export declare function convertToPng(base64Data: string, mimeType: string): Promise<{
6
+ data: string;
7
+ mimeType: string;
8
+ } | null>;
9
+ //# sourceMappingURL=image-convert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-convert.d.ts","sourceRoot":"","sources":["../../src/utils/image-convert.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAsB,YAAY,CACjC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA4BpD","sourcesContent":["import { loadPhoton } from \"./photon.js\";\r\n\r\n/**\r\n * Convert image to PNG format for terminal display.\r\n * Kitty graphics protocol requires PNG format (f=100).\r\n */\r\nexport async function convertToPng(\r\n\tbase64Data: string,\r\n\tmimeType: string,\r\n): Promise<{ data: string; mimeType: string } | null> {\r\n\t// Already PNG, no conversion needed\r\n\tif (mimeType === \"image/png\") {\r\n\t\treturn { data: base64Data, mimeType };\r\n\t}\r\n\r\n\tconst photon = await loadPhoton();\r\n\tif (!photon) {\r\n\t\t// Photon not available, can't convert\r\n\t\treturn null;\r\n\t}\r\n\r\n\ttry {\r\n\t\tconst bytes = new Uint8Array(Buffer.from(base64Data, \"base64\"));\r\n\t\tconst image = photon.PhotonImage.new_from_byteslice(bytes);\r\n\t\ttry {\r\n\t\t\tconst pngBuffer = image.get_bytes();\r\n\t\t\treturn {\r\n\t\t\t\tdata: Buffer.from(pngBuffer).toString(\"base64\"),\r\n\t\t\t\tmimeType: \"image/png\",\r\n\t\t\t};\r\n\t\t} finally {\r\n\t\t\timage.free();\r\n\t\t}\r\n\t} catch {\r\n\t\t// Conversion failed\r\n\t\treturn null;\r\n\t}\r\n}\r\n"]}