@gajae-code/coding-agent 0.17.2 → 0.17.5

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 (390) hide show
  1. package/CHANGELOG.md +267 -0
  2. package/dist/types/cli/daemon-cli.d.ts +3 -1
  3. package/dist/types/cli/github-release.d.ts +17 -0
  4. package/dist/types/cli/public-command-entry.d.ts +56 -0
  5. package/dist/types/cli/public-command-errors.d.ts +126 -0
  6. package/dist/types/cli/public-command-evidence.d.ts +99 -0
  7. package/dist/types/cli/public-command-help.d.ts +65 -0
  8. package/dist/types/cli/public-command-registry.d.ts +69 -0
  9. package/dist/types/cli/session-picker.d.ts +1 -1
  10. package/dist/types/cli/setup-cli.d.ts +1 -0
  11. package/dist/types/cli/skills-cli.d.ts +5 -0
  12. package/dist/types/cli.d.ts +3 -0
  13. package/dist/types/commands/daemon.d.ts +4 -50
  14. package/dist/types/commands/sdk.d.ts +20 -37
  15. package/dist/types/commands/setup.d.ts +3 -0
  16. package/dist/types/commands/skills.d.ts +9 -0
  17. package/dist/types/config/autorouting-tier-map.d.ts +1049 -3
  18. package/dist/types/config/file-lock.d.ts +13 -3
  19. package/dist/types/config/model-profile-activation.d.ts +45 -1
  20. package/dist/types/config/model-registry.d.ts +14 -3
  21. package/dist/types/config/model-resolver.d.ts +1 -1
  22. package/dist/types/config/settings-schema.d.ts +11 -0
  23. package/dist/types/coordinator-mcp/question-state.d.ts +6 -1
  24. package/dist/types/daemon/operator-contract.d.ts +5 -1
  25. package/dist/types/eval/js/worker-protocol.d.ts +2 -0
  26. package/dist/types/exec/bash-executor.d.ts +2 -0
  27. package/dist/types/extensibility/extensions/types.d.ts +12 -0
  28. package/dist/types/extensibility/gjc-plugins/registry.d.ts +4 -0
  29. package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +11 -2
  30. package/dist/types/extensibility/runtime-skill-discovery.d.ts +18 -0
  31. package/dist/types/extensibility/shared-events.d.ts +3 -1
  32. package/dist/types/gjc-runtime/session-state-lock.d.ts +61 -0
  33. package/dist/types/gjc-runtime/state-writer.d.ts +14 -1
  34. package/dist/types/harness-control-plane/control-endpoint.d.ts +4 -1
  35. package/dist/types/harness-control-plane/finalize.d.ts +14 -3
  36. package/dist/types/internal-urls/embedded-protocol.d.ts +9 -0
  37. package/dist/types/internal-urls/index.d.ts +1 -0
  38. package/dist/types/internal-urls/parse.d.ts +9 -1
  39. package/dist/types/main.d.ts +23 -1
  40. package/dist/types/modes/acp/acp-agent.d.ts +55 -1
  41. package/dist/types/modes/acp/startup-provenance.d.ts +16 -0
  42. package/dist/types/modes/components/custom-provider-wizard.d.ts +19 -1
  43. package/dist/types/modes/components/session-selector.d.ts +5 -2
  44. package/dist/types/modes/components/user-message-selector.d.ts +5 -2
  45. package/dist/types/modes/controllers/command-controller.d.ts +1 -1
  46. package/dist/types/modes/controllers/selector-controller.d.ts +1 -1
  47. package/dist/types/modes/interactive-mode.d.ts +1 -1
  48. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +11 -1
  49. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +14 -1
  50. package/dist/types/modes/types.d.ts +2 -2
  51. package/dist/types/runtime/process-lifecycle.d.ts +2 -0
  52. package/dist/types/runtime-mcp/loader.d.ts +2 -0
  53. package/dist/types/runtime-mcp/manager.d.ts +69 -6
  54. package/dist/types/runtime-mcp/pool.d.ts +17 -0
  55. package/dist/types/runtime-mcp/redaction.d.ts +20 -0
  56. package/dist/types/runtime-mcp/startup-policy.d.ts +6 -0
  57. package/dist/types/runtime-mcp/tool-bridge.d.ts +9 -0
  58. package/dist/types/runtime-mcp/transports/http.d.ts +11 -0
  59. package/dist/types/sdk/broker/broker.d.ts +17 -4
  60. package/dist/types/sdk/broker/ensure.d.ts +3 -0
  61. package/dist/types/sdk/broker/identity.d.ts +5 -1
  62. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +23 -3
  63. package/dist/types/sdk/broker/lifecycle.d.ts +15 -8
  64. package/dist/types/sdk/broker/managed-task-dag.d.ts +1335 -0
  65. package/dist/types/sdk/broker/managed-task-verification.d.ts +37 -0
  66. package/dist/types/sdk/broker/runtime.d.ts +1 -1
  67. package/dist/types/sdk/broker/session-index.d.ts +22 -3
  68. package/dist/types/sdk/broker/spawn-authority.d.ts +12 -0
  69. package/dist/types/sdk/broker/startup-failure.d.ts +4 -0
  70. package/dist/types/sdk/broker/stderr-drainer.d.ts +13 -0
  71. package/dist/types/sdk/bus/index.d.ts +19 -0
  72. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +7 -1
  73. package/dist/types/sdk/bus/telegram-daemon.d.ts +5 -0
  74. package/dist/types/sdk/cli/master-cli.d.ts +6 -10
  75. package/dist/types/sdk/cli/rows.d.ts +19 -1
  76. package/dist/types/sdk/cli/session-cli.d.ts +22 -5
  77. package/dist/types/sdk/client/client.d.ts +2 -0
  78. package/dist/types/sdk/guides/cli.d.ts +3 -4
  79. package/dist/types/sdk/guides/verify.d.ts +2 -0
  80. package/dist/types/sdk/host/host.d.ts +9 -0
  81. package/dist/types/sdk/host/session-runtime.d.ts +31 -0
  82. package/dist/types/sdk/host/types.d.ts +10 -0
  83. package/dist/types/sdk/index.d.ts +1 -0
  84. package/dist/types/sdk/prompt-deadline-flush.d.ts +85 -0
  85. package/dist/types/sdk/prompt-deadline-manager.d.ts +37 -0
  86. package/dist/types/sdk/prompt-tool-boundary.d.ts +73 -0
  87. package/dist/types/sdk/router/session-router.d.ts +2 -0
  88. package/dist/types/sdk/session.d.ts +3 -3
  89. package/dist/types/sdk/startup-capability.d.ts +2 -0
  90. package/dist/types/sdk/transport/relay.d.ts +1 -0
  91. package/dist/types/sdk/transport/serve-cli.d.ts +48 -4
  92. package/dist/types/sdk/transport/stdio.d.ts +5 -1
  93. package/dist/types/session/agent-session.d.ts +175 -23
  94. package/dist/types/session/fallback-chain-controller.d.ts +6 -6
  95. package/dist/types/session/fold-coordinator.d.ts +17 -3
  96. package/dist/types/session/internal/managed-session-storage.d.ts +7 -1
  97. package/dist/types/session/session-manager.d.ts +64 -1
  98. package/dist/types/session/session-work-lease.d.ts +14 -0
  99. package/dist/types/setup/model-onboarding-guidance.d.ts +1 -1
  100. package/dist/types/setup/provider-onboarding.d.ts +81 -1
  101. package/dist/types/task/types.d.ts +2 -0
  102. package/dist/types/tools/bash-interactive.d.ts +1 -0
  103. package/dist/types/tools/bash.d.ts +37 -11
  104. package/dist/types/tools/fetch.d.ts +10 -1
  105. package/dist/types/tools/job.d.ts +1 -1
  106. package/dist/types/tools/steer-fold.d.ts +31 -0
  107. package/dist/types/tools/subagent.d.ts +8 -1
  108. package/dist/types/utils/git.d.ts +28 -2
  109. package/dist/types/utils/mupdf-embedded.d.ts +2 -0
  110. package/dist/types/utils/mupdf.d.ts +4 -0
  111. package/dist/types/utils/session-title-generation.d.ts +6 -0
  112. package/dist/types/utils/title-generator.d.ts +11 -2
  113. package/dist/types/web/scrapers/types.d.ts +3 -0
  114. package/package.json +18 -10
  115. package/scripts/build-binary.ts +9 -3
  116. package/scripts/compile-args.ts +0 -9
  117. package/scripts/embed-mupdf.ts +52 -0
  118. package/scripts/generate-sdk-operation-inventory.ts +31 -1
  119. package/scripts/vendor-markit.ts +196 -0
  120. package/src/async/job-manager.ts +22 -1
  121. package/src/cli/daemon-cli.ts +53 -18
  122. package/src/cli/github-release.ts +87 -5
  123. package/src/cli/mcp-cli.ts +38 -4
  124. package/src/cli/public-command-entry.ts +450 -0
  125. package/src/cli/public-command-errors.ts +581 -0
  126. package/src/cli/public-command-evidence.ts +717 -0
  127. package/src/cli/public-command-help.ts +360 -0
  128. package/src/cli/public-command-registry.ts +541 -0
  129. package/src/cli/session-picker.ts +2 -1
  130. package/src/cli/setup-cli.ts +10 -1
  131. package/src/cli/skills-cli.ts +46 -2
  132. package/src/cli/stats-cli.ts +11 -1
  133. package/src/cli.ts +61 -1
  134. package/src/commands/daemon.ts +65 -69
  135. package/src/commands/sdk.ts +175 -117
  136. package/src/commands/setup.ts +2 -0
  137. package/src/commands/skills.ts +11 -0
  138. package/src/config/autorouting-tier-map.ts +543 -3
  139. package/src/config/file-lock.ts +206 -65
  140. package/src/config/model-discovery-manager.ts +4 -4
  141. package/src/config/model-profile-activation.ts +417 -66
  142. package/src/config/model-registry.ts +254 -36
  143. package/src/config/model-resolver.ts +6 -1
  144. package/src/config/settings-schema.ts +26 -2
  145. package/src/coordinator-mcp/policy.ts +10 -5
  146. package/src/coordinator-mcp/question-gate-codec.ts +17 -0
  147. package/src/coordinator-mcp/question-state.ts +179 -9
  148. package/src/coordinator-mcp/server.ts +521 -87
  149. package/src/coordinator-mcp/session-reaper.ts +6 -4
  150. package/src/crash/record-loader.ts +6 -2
  151. package/src/daemon/operator-contract.ts +26 -12
  152. package/src/defaults/gjc/skills/ultragoal/SKILL.md +1 -1
  153. package/src/eval/js/context-manager.ts +8 -8
  154. package/src/eval/js/worker-core.ts +9 -4
  155. package/src/eval/js/worker-protocol.ts +2 -0
  156. package/src/exec/bash-executor.ts +3 -0
  157. package/src/extensibility/extensions/runner.ts +52 -4
  158. package/src/extensibility/extensions/types.ts +10 -0
  159. package/src/extensibility/gjc-plugins/registry.ts +196 -37
  160. package/src/extensibility/gjc-plugins/runtime-adapters.ts +46 -8
  161. package/src/extensibility/runtime-skill-discovery.ts +61 -3
  162. package/src/extensibility/shared-events.ts +3 -1
  163. package/src/gjc-runtime/session-state-lock.ts +165 -24
  164. package/src/gjc-runtime/state-writer.ts +317 -6
  165. package/src/gjc-runtime/ultragoal-succession.ts +31 -3
  166. package/src/harness-control-plane/control-endpoint.ts +24 -6
  167. package/src/harness-control-plane/finalize.ts +312 -25
  168. package/src/harness-control-plane/owner.ts +323 -89
  169. package/src/internal-urls/docs-index.generated.ts +23 -20
  170. package/src/internal-urls/embedded-protocol.ts +83 -0
  171. package/src/internal-urls/index.ts +1 -0
  172. package/src/internal-urls/parse.ts +21 -1
  173. package/src/internal-urls/router.ts +4 -2
  174. package/src/main.ts +192 -74
  175. package/src/modes/acp/acp-agent.ts +973 -56
  176. package/src/modes/acp/startup-provenance.ts +59 -0
  177. package/src/modes/components/custom-provider-wizard.ts +308 -7
  178. package/src/modes/components/gjc-bundle-settings.ts +21 -1
  179. package/src/modes/components/oauth-selector.ts +9 -0
  180. package/src/modes/components/session-selector.ts +47 -4
  181. package/src/modes/components/tool-status-header.ts +72 -6
  182. package/src/modes/components/user-message-selector.ts +57 -15
  183. package/src/modes/controllers/command-controller.ts +58 -32
  184. package/src/modes/controllers/extension-ui-controller.ts +33 -7
  185. package/src/modes/controllers/input-controller.ts +4 -0
  186. package/src/modes/controllers/runtime-mcp-command-controller.ts +1 -1
  187. package/src/modes/controllers/selector-controller.ts +161 -15
  188. package/src/modes/interactive-mode.ts +21 -7
  189. package/src/modes/runtime-init.ts +1 -0
  190. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +124 -7
  191. package/src/modes/shared/agent-wire/workflow-gate-types.ts +16 -2
  192. package/src/modes/types.ts +2 -2
  193. package/src/prompts/agent-fragments/browser-aside.md +1 -0
  194. package/src/prompts/system/title-system.md +1 -1
  195. package/src/prompts/tools/bash.md +1 -1
  196. package/src/prompts/tools/job.md +1 -1
  197. package/src/prompts/tools/read.md +2 -0
  198. package/src/runtime/network-prewarm-service.test.ts +36 -1
  199. package/src/runtime/network-prewarm-service.ts +28 -3
  200. package/src/runtime/process-lifecycle.ts +22 -11
  201. package/src/runtime-mcp/config.ts +16 -1
  202. package/src/runtime-mcp/loader.ts +6 -3
  203. package/src/runtime-mcp/manager.ts +845 -109
  204. package/src/runtime-mcp/pool.test.ts +31 -0
  205. package/src/runtime-mcp/pool.ts +304 -28
  206. package/src/runtime-mcp/redaction.ts +42 -0
  207. package/src/runtime-mcp/startup-policy.ts +7 -0
  208. package/src/runtime-mcp/tool-bridge.ts +71 -0
  209. package/src/runtime-mcp/transports/http.ts +108 -25
  210. package/src/sdk/acp/adapter.ts +27 -8
  211. package/src/sdk/broker/broker.ts +1431 -198
  212. package/src/sdk/broker/ensure.ts +21 -3
  213. package/src/sdk/broker/identity.ts +22 -1
  214. package/src/sdk/broker/lifecycle-ledger.ts +95 -31
  215. package/src/sdk/broker/lifecycle.ts +690 -141
  216. package/src/sdk/broker/managed-task-dag.ts +1927 -0
  217. package/src/sdk/broker/managed-task-verification.ts +642 -0
  218. package/src/sdk/broker/runtime.ts +1 -1
  219. package/src/sdk/broker/session-index.ts +97 -4
  220. package/src/sdk/broker/spawn-authority.ts +175 -14
  221. package/src/sdk/broker/startup-failure.ts +80 -1
  222. package/src/sdk/broker/stderr-drainer.ts +59 -0
  223. package/src/sdk/broker/transport.ts +1 -0
  224. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  225. package/src/sdk/bus/chat-daemon-runtime.ts +1 -0
  226. package/src/sdk/bus/index.ts +707 -81
  227. package/src/sdk/bus/telegram-daemon-cli.ts +31 -2
  228. package/src/sdk/bus/telegram-daemon-contract.ts +7 -1
  229. package/src/sdk/bus/telegram-daemon.ts +10 -3
  230. package/src/sdk/cli/master-cli.ts +47 -36
  231. package/src/sdk/cli/rows.ts +30 -7
  232. package/src/sdk/cli/session-cli.ts +705 -184
  233. package/src/sdk/client/client.ts +18 -0
  234. package/src/sdk/guides/catalog.ts +2 -2
  235. package/src/sdk/guides/cli.ts +20 -62
  236. package/src/sdk/guides/verify.ts +14 -0
  237. package/src/sdk/host/host.ts +49 -5
  238. package/src/sdk/host/session-runtime.test.ts +184 -2
  239. package/src/sdk/host/session-runtime.ts +322 -101
  240. package/src/sdk/host/types.ts +12 -1
  241. package/src/sdk/host/websocket-transport.lifecycle.test.ts +84 -0
  242. package/src/sdk/host/websocket-transport.ts +40 -6
  243. package/src/sdk/index.ts +11 -0
  244. package/src/sdk/lifecycle/service.ts +2 -0
  245. package/src/sdk/prompt-deadline-flush.ts +356 -0
  246. package/src/sdk/prompt-deadline-manager.ts +133 -1
  247. package/src/sdk/prompt-tool-boundary.ts +121 -0
  248. package/src/sdk/protocol/operation-inventory.generated.json +106 -0
  249. package/src/sdk/router/session-router.ts +9 -1
  250. package/src/sdk/session.ts +763 -116
  251. package/src/sdk/startup-capability.ts +1 -1
  252. package/src/sdk/transport/relay.ts +71 -6
  253. package/src/sdk/transport/serve-cli.ts +397 -42
  254. package/src/sdk/transport/socket.ts +12 -11
  255. package/src/sdk/transport/stdio.ts +7 -3
  256. package/src/session/agent-session.ts +2472 -407
  257. package/src/session/fallback-chain-controller.ts +6 -7
  258. package/src/session/fold-coordinator.ts +24 -5
  259. package/src/session/internal/managed-session-scope.ts +68 -18
  260. package/src/session/internal/managed-session-storage.ts +334 -12
  261. package/src/session/session-manager.ts +382 -44
  262. package/src/session/session-work-lease.ts +34 -0
  263. package/src/setup/model-onboarding-guidance.ts +1 -1
  264. package/src/setup/provider-onboarding.ts +397 -24
  265. package/src/setup/provider-presets.json +2 -1
  266. package/src/slash-commands/builtin-registry.ts +259 -15
  267. package/src/task/executor.ts +46 -17
  268. package/src/task/index.ts +14 -2
  269. package/src/task/types.ts +2 -0
  270. package/src/tools/bash-interactive.ts +2 -0
  271. package/src/tools/bash.ts +118 -78
  272. package/src/tools/fetch.ts +140 -25
  273. package/src/tools/job.ts +151 -25
  274. package/src/tools/output-meta.ts +15 -2
  275. package/src/tools/path-utils.ts +27 -3
  276. package/src/tools/read.ts +3 -3
  277. package/src/tools/steer-fold.ts +107 -0
  278. package/src/tools/subagent-render.ts +24 -1
  279. package/src/tools/subagent.ts +27 -1
  280. package/src/tools/tool-catalog.generated.ts +29 -2
  281. package/src/tools/tool-errors.ts +4 -0
  282. package/src/utils/git.ts +53 -3
  283. package/src/utils/markit.ts +55 -41
  284. package/src/utils/mupdf-assets.d.ts +4 -0
  285. package/src/utils/mupdf-embedded.ts +4 -0
  286. package/src/utils/mupdf.ts +136 -0
  287. package/src/utils/session-title-generation.ts +29 -0
  288. package/src/utils/title-generator.ts +46 -2
  289. package/src/web/scrapers/types.ts +24 -3
  290. package/vendor/markit-ai/LICENSE +21 -0
  291. package/vendor/markit-ai/MANIFEST.json +412 -0
  292. package/vendor/markit-ai/dist/commands/config.d.ts +4 -0
  293. package/vendor/markit-ai/dist/commands/config.js +139 -0
  294. package/vendor/markit-ai/dist/commands/convert.d.ts +6 -0
  295. package/vendor/markit-ai/dist/commands/convert.js +113 -0
  296. package/vendor/markit-ai/dist/commands/formats.d.ts +2 -0
  297. package/vendor/markit-ai/dist/commands/formats.js +92 -0
  298. package/vendor/markit-ai/dist/commands/init.d.ts +2 -0
  299. package/vendor/markit-ai/dist/commands/init.js +29 -0
  300. package/vendor/markit-ai/dist/commands/onboard.d.ts +2 -0
  301. package/vendor/markit-ai/dist/commands/onboard.js +61 -0
  302. package/vendor/markit-ai/dist/commands/plugin.d.ts +4 -0
  303. package/vendor/markit-ai/dist/commands/plugin.js +58 -0
  304. package/vendor/markit-ai/dist/config.d.ts +26 -0
  305. package/vendor/markit-ai/dist/config.js +42 -0
  306. package/vendor/markit-ai/dist/converters/audio.d.ts +7 -0
  307. package/vendor/markit-ai/dist/converters/audio.js +104 -0
  308. package/vendor/markit-ai/dist/converters/csv.d.ts +7 -0
  309. package/vendor/markit-ai/dist/converters/csv.js +83 -0
  310. package/vendor/markit-ai/dist/converters/docx.d.ts +6 -0
  311. package/vendor/markit-ai/dist/converters/docx.js +57 -0
  312. package/vendor/markit-ai/dist/converters/epub.d.ts +8 -0
  313. package/vendor/markit-ai/dist/converters/epub.js +128 -0
  314. package/vendor/markit-ai/dist/converters/github.d.ts +18 -0
  315. package/vendor/markit-ai/dist/converters/github.js +148 -0
  316. package/vendor/markit-ai/dist/converters/html.d.ts +6 -0
  317. package/vendor/markit-ai/dist/converters/html.js +30 -0
  318. package/vendor/markit-ai/dist/converters/image.d.ts +6 -0
  319. package/vendor/markit-ai/dist/converters/image.js +124 -0
  320. package/vendor/markit-ai/dist/converters/ipynb.d.ts +6 -0
  321. package/vendor/markit-ai/dist/converters/ipynb.js +75 -0
  322. package/vendor/markit-ai/dist/converters/iwork.d.ts +20 -0
  323. package/vendor/markit-ai/dist/converters/iwork.js +391 -0
  324. package/vendor/markit-ai/dist/converters/json.d.ts +6 -0
  325. package/vendor/markit-ai/dist/converters/json.js +21 -0
  326. package/vendor/markit-ai/dist/converters/pdf/columns.d.ts +35 -0
  327. package/vendor/markit-ai/dist/converters/pdf/columns.js +93 -0
  328. package/vendor/markit-ai/dist/converters/pdf/extract.d.ts +19 -0
  329. package/vendor/markit-ai/dist/converters/pdf/extract.js +514 -0
  330. package/vendor/markit-ai/dist/converters/pdf/grid.d.ts +25 -0
  331. package/vendor/markit-ai/dist/converters/pdf/grid.js +795 -0
  332. package/vendor/markit-ai/dist/converters/pdf/headers.d.ts +24 -0
  333. package/vendor/markit-ai/dist/converters/pdf/headers.js +108 -0
  334. package/vendor/markit-ai/dist/converters/pdf/index.d.ts +19 -0
  335. package/vendor/markit-ai/dist/converters/pdf/index.js +136 -0
  336. package/vendor/markit-ai/dist/converters/pdf/mupdf-loader.js +9 -0
  337. package/vendor/markit-ai/dist/converters/pdf/render.d.ts +24 -0
  338. package/vendor/markit-ai/dist/converters/pdf/render.js +513 -0
  339. package/vendor/markit-ai/dist/converters/pdf/types.d.ts +75 -0
  340. package/vendor/markit-ai/dist/converters/pdf/types.js +1 -0
  341. package/vendor/markit-ai/dist/converters/plain-text.d.ts +6 -0
  342. package/vendor/markit-ai/dist/converters/plain-text.js +87 -0
  343. package/vendor/markit-ai/dist/converters/pptx.d.ts +8 -0
  344. package/vendor/markit-ai/dist/converters/pptx.js +289 -0
  345. package/vendor/markit-ai/dist/converters/rss.d.ts +11 -0
  346. package/vendor/markit-ai/dist/converters/rss.js +138 -0
  347. package/vendor/markit-ai/dist/converters/wikipedia.d.ts +6 -0
  348. package/vendor/markit-ai/dist/converters/wikipedia.js +33 -0
  349. package/vendor/markit-ai/dist/converters/xlsx.d.ts +8 -0
  350. package/vendor/markit-ai/dist/converters/xlsx.js +147 -0
  351. package/vendor/markit-ai/dist/converters/xml.d.ts +6 -0
  352. package/vendor/markit-ai/dist/converters/xml.js +18 -0
  353. package/vendor/markit-ai/dist/converters/yaml.d.ts +6 -0
  354. package/vendor/markit-ai/dist/converters/yaml.js +17 -0
  355. package/vendor/markit-ai/dist/converters/zip.d.ts +8 -0
  356. package/vendor/markit-ai/dist/converters/zip.js +57 -0
  357. package/vendor/markit-ai/dist/index.d.ts +30 -0
  358. package/vendor/markit-ai/dist/index.js +26 -0
  359. package/vendor/markit-ai/dist/main.d.ts +2 -0
  360. package/vendor/markit-ai/dist/main.js +191 -0
  361. package/vendor/markit-ai/dist/markit.d.ts +45 -0
  362. package/vendor/markit-ai/dist/markit.js +267 -0
  363. package/vendor/markit-ai/dist/plugins/api.d.ts +7 -0
  364. package/vendor/markit-ai/dist/plugins/api.js +42 -0
  365. package/vendor/markit-ai/dist/plugins/index.d.ts +4 -0
  366. package/vendor/markit-ai/dist/plugins/index.js +3 -0
  367. package/vendor/markit-ai/dist/plugins/installer.d.ts +25 -0
  368. package/vendor/markit-ai/dist/plugins/installer.js +176 -0
  369. package/vendor/markit-ai/dist/plugins/loader.d.ts +6 -0
  370. package/vendor/markit-ai/dist/plugins/loader.js +61 -0
  371. package/vendor/markit-ai/dist/plugins/types.d.ts +25 -0
  372. package/vendor/markit-ai/dist/plugins/types.js +1 -0
  373. package/vendor/markit-ai/dist/providers/anthropic.d.ts +2 -0
  374. package/vendor/markit-ai/dist/providers/anthropic.js +47 -0
  375. package/vendor/markit-ai/dist/providers/index.d.ts +21 -0
  376. package/vendor/markit-ai/dist/providers/index.js +56 -0
  377. package/vendor/markit-ai/dist/providers/openai.d.ts +2 -0
  378. package/vendor/markit-ai/dist/providers/openai.js +76 -0
  379. package/vendor/markit-ai/dist/providers/types.d.ts +26 -0
  380. package/vendor/markit-ai/dist/providers/types.js +1 -0
  381. package/vendor/markit-ai/dist/types.d.ts +36 -0
  382. package/vendor/markit-ai/dist/types.js +1 -0
  383. package/vendor/markit-ai/dist/utils/exit-codes.d.ts +4 -0
  384. package/vendor/markit-ai/dist/utils/exit-codes.js +4 -0
  385. package/vendor/markit-ai/dist/utils/output.d.ts +22 -0
  386. package/vendor/markit-ai/dist/utils/output.js +31 -0
  387. package/vendor/markit-ai/dist/utils/turndown.d.ts +8 -0
  388. package/vendor/markit-ai/dist/utils/turndown.js +70 -0
  389. package/vendor/markit-ai/package.json +74 -0
  390. package/vendor/markit-ai.patch +49 -0
@@ -0,0 +1,289 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { XMLParser } from "fast-xml-parser";
4
+ import JSZip from "jszip";
5
+ const EXTENSIONS = [".pptx"];
6
+ const MIMETYPES = [
7
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
8
+ ];
9
+ export class PptxConverter {
10
+ name = "pptx";
11
+ accepts(streamInfo) {
12
+ if (streamInfo.extension && EXTENSIONS.includes(streamInfo.extension))
13
+ return true;
14
+ if (streamInfo.mimetype &&
15
+ MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m)))
16
+ return true;
17
+ return false;
18
+ }
19
+ async convert(input, streamInfo) {
20
+ const zip = await JSZip.loadAsync(input);
21
+ const parser = new XMLParser({
22
+ ignoreAttributes: false,
23
+ attributeNamePrefix: "@_",
24
+ textNodeName: "#text",
25
+ processEntities: { maxTotalExpansions: 1_000_000 },
26
+ });
27
+ // Get slide order from presentation.xml
28
+ const presXml = await zip.file("ppt/presentation.xml")?.async("string");
29
+ if (!presXml)
30
+ throw new Error("Invalid PPTX: missing presentation.xml");
31
+ const pres = parser.parse(presXml);
32
+ const sldIdList = pres["p:presentation"]?.["p:sldIdLst"]?.["p:sldId"];
33
+ const sldIds = Array.isArray(sldIdList)
34
+ ? sldIdList
35
+ : sldIdList
36
+ ? [sldIdList]
37
+ : [];
38
+ // Get relationship mappings
39
+ const relsXml = await zip
40
+ .file("ppt/_rels/presentation.xml.rels")
41
+ ?.async("string");
42
+ const rels = relsXml ? parser.parse(relsXml) : null;
43
+ const relList = rels?.Relationships?.Relationship;
44
+ const relArray = Array.isArray(relList)
45
+ ? relList
46
+ : relList
47
+ ? [relList]
48
+ : [];
49
+ const relMap = new Map();
50
+ for (const r of relArray) {
51
+ relMap.set(r["@_Id"], r["@_Target"]);
52
+ }
53
+ // Map slide IDs to file paths in order
54
+ const slidePaths = [];
55
+ for (const sld of sldIds) {
56
+ const rId = sld["@_r:id"];
57
+ const target = relMap.get(rId);
58
+ if (target)
59
+ slidePaths.push(`ppt/${target}`);
60
+ }
61
+ // If we couldn't resolve from rels, fall back to finding slide files
62
+ if (slidePaths.length === 0) {
63
+ const slideFiles = Object.keys(zip.files)
64
+ .filter((f) => /^ppt\/slides\/slide\d+\.xml$/.test(f))
65
+ .sort((a, b) => {
66
+ const na = parseInt(a.match(/slide(\d+)/)?.[1] || "0", 10);
67
+ const nb = parseInt(b.match(/slide(\d+)/)?.[1] || "0", 10);
68
+ return na - nb;
69
+ });
70
+ slidePaths.push(...slideFiles);
71
+ }
72
+ const imageDir = streamInfo.imageDir;
73
+ if (imageDir) {
74
+ mkdirSync(imageDir, { recursive: true });
75
+ }
76
+ const sections = [];
77
+ let imageCount = 0;
78
+ for (let i = 0; i < slidePaths.length; i++) {
79
+ const slideXml = await zip.file(slidePaths[i])?.async("string");
80
+ if (!slideXml)
81
+ continue;
82
+ const slide = parser.parse(slideXml);
83
+ const spTree = slide["p:sld"]?.["p:cSld"]?.["p:spTree"];
84
+ if (!spTree)
85
+ continue;
86
+ // Parse slide-level rels for image references
87
+ const slideRelsPath = `${slidePaths[i].replace("slides/slide", "slides/_rels/slide")}.rels`;
88
+ const slideRelsXml = await zip.file(slideRelsPath)?.async("string");
89
+ const slideRelMap = new Map();
90
+ if (slideRelsXml) {
91
+ const slideRels = parser.parse(slideRelsXml);
92
+ const relItems = toList(slideRels?.Relationships?.Relationship);
93
+ for (const r of relItems) {
94
+ slideRelMap.set(r["@_Id"], r["@_Target"]);
95
+ }
96
+ }
97
+ const slideLines = [`<!-- Slide ${i + 1} -->`];
98
+ const shapes = spTree["p:sp"];
99
+ const shapeList = Array.isArray(shapes) ? shapes : shapes ? [shapes] : [];
100
+ let isTitle = true;
101
+ for (const shape of shapeList) {
102
+ const text = this.extractText(shape);
103
+ if (!text)
104
+ continue;
105
+ if (isTitle) {
106
+ slideLines.push(`# ${text}`);
107
+ isTitle = false;
108
+ }
109
+ else {
110
+ slideLines.push(text);
111
+ }
112
+ }
113
+ // Extract embedded images
114
+ const pics = toList(spTree["p:pic"]);
115
+ for (const pic of pics) {
116
+ const blipFill = pic["p:blipFill"];
117
+ const rEmbed = blipFill?.["a:blip"]?.["@_r:embed"];
118
+ if (!rEmbed)
119
+ continue;
120
+ const target = slideRelMap.get(rEmbed);
121
+ if (!target)
122
+ continue;
123
+ // Resolve relative target against slide directory
124
+ const imagePath = target.startsWith("/")
125
+ ? target.slice(1)
126
+ : `ppt/slides/${target}`;
127
+ // Normalize path (e.g. ppt/slides/../media/image1.png → ppt/media/image1.png)
128
+ const normalizedPath = imagePath
129
+ .split("/")
130
+ .reduce((parts, seg) => {
131
+ if (seg === "..")
132
+ parts.pop();
133
+ else
134
+ parts.push(seg);
135
+ return parts;
136
+ }, [])
137
+ .join("/");
138
+ const imageFile = zip.file(normalizedPath);
139
+ if (!imageFile)
140
+ continue;
141
+ imageCount++;
142
+ const name = pic["p:nvSpPr"]?.["p:cNvPr"]?.["@_name"] ||
143
+ pic["p:nvPicPr"]?.["p:cNvPr"]?.["@_name"] ||
144
+ `image_${imageCount}`;
145
+ if (imageDir) {
146
+ try {
147
+ const ext = normalizedPath.split(".").pop() || "png";
148
+ const filename = `slide${i + 1}_${imageCount}.${ext}`;
149
+ const filepath = join(imageDir, filename);
150
+ const buf = await imageFile.async("nodebuffer");
151
+ writeFileSync(filepath, buf);
152
+ slideLines.push(`![${name}](${filepath})`);
153
+ }
154
+ catch {
155
+ slideLines.push(`<!-- image: ${name} (slide ${i + 1}) -->`);
156
+ }
157
+ }
158
+ else {
159
+ slideLines.push(`<!-- image: ${name} (slide ${i + 1}) -->`);
160
+ }
161
+ }
162
+ // Tables
163
+ const graphicFrames = spTree["p:graphicFrame"];
164
+ const gfList = Array.isArray(graphicFrames)
165
+ ? graphicFrames
166
+ : graphicFrames
167
+ ? [graphicFrames]
168
+ : [];
169
+ for (const gf of gfList) {
170
+ const table = this.extractTable(gf);
171
+ if (table)
172
+ slideLines.push(table);
173
+ }
174
+ // Slide notes
175
+ const noteFile = slidePaths[i].replace("slides/slide", "notesSlides/notesSlide");
176
+ const noteXml = await zip.file(noteFile)?.async("string");
177
+ if (noteXml) {
178
+ const note = parser.parse(noteXml);
179
+ const noteSpTree = note["p:notes"]?.["p:cSld"]?.["p:spTree"];
180
+ if (noteSpTree) {
181
+ const noteShapes = noteSpTree["p:sp"];
182
+ const noteList = Array.isArray(noteShapes)
183
+ ? noteShapes
184
+ : noteShapes
185
+ ? [noteShapes]
186
+ : [];
187
+ const noteTexts = [];
188
+ for (const ns of noteList) {
189
+ // Skip slide image placeholder
190
+ const phType = ns["p:nvSpPr"]?.["p:nvPr"]?.["p:ph"]?.["@_type"];
191
+ if (phType === "sldImg")
192
+ continue;
193
+ const t = this.extractText(ns);
194
+ if (t)
195
+ noteTexts.push(t);
196
+ }
197
+ if (noteTexts.length > 0) {
198
+ slideLines.push("\n### Notes:");
199
+ slideLines.push(noteTexts.join("\n"));
200
+ }
201
+ }
202
+ }
203
+ sections.push(slideLines.join("\n"));
204
+ }
205
+ return { markdown: sections.join("\n\n").trim() };
206
+ }
207
+ extractText(shape) {
208
+ const txBody = shape["p:txBody"];
209
+ if (!txBody)
210
+ return "";
211
+ const paragraphs = txBody["a:p"];
212
+ const pList = Array.isArray(paragraphs)
213
+ ? paragraphs
214
+ : paragraphs
215
+ ? [paragraphs]
216
+ : [];
217
+ const lines = [];
218
+ for (const p of pList) {
219
+ const runs = p["a:r"];
220
+ const rList = Array.isArray(runs) ? runs : runs ? [runs] : [];
221
+ const parts = [];
222
+ for (const r of rList) {
223
+ const t = r["a:t"];
224
+ if (t != null)
225
+ parts.push(typeof t === "object" ? t["#text"] || "" : String(t));
226
+ }
227
+ if (parts.length > 0)
228
+ lines.push(parts.join(""));
229
+ }
230
+ return lines.join("\n").trim();
231
+ }
232
+ extractTable(gf) {
233
+ const tbl = gf?.["a:graphic"]?.["a:graphicData"]?.["a:tbl"];
234
+ if (!tbl)
235
+ return null;
236
+ const rows = tbl["a:tr"];
237
+ const rowList = Array.isArray(rows) ? rows : rows ? [rows] : [];
238
+ if (rowList.length === 0)
239
+ return null;
240
+ const mdRows = [];
241
+ for (const row of rowList) {
242
+ const cells = row["a:tc"];
243
+ const cellList = Array.isArray(cells) ? cells : cells ? [cells] : [];
244
+ const cellTexts = [];
245
+ for (const cell of cellList) {
246
+ const txBody = cell["a:txBody"];
247
+ if (!txBody) {
248
+ cellTexts.push("");
249
+ continue;
250
+ }
251
+ const paragraphs = txBody["a:p"];
252
+ const pList = Array.isArray(paragraphs)
253
+ ? paragraphs
254
+ : paragraphs
255
+ ? [paragraphs]
256
+ : [];
257
+ const parts = [];
258
+ for (const p of pList) {
259
+ const runs = p["a:r"];
260
+ const rList = Array.isArray(runs) ? runs : runs ? [runs] : [];
261
+ for (const r of rList) {
262
+ const t = r["a:t"];
263
+ if (t != null)
264
+ parts.push(typeof t === "object" ? t["#text"] || "" : String(t));
265
+ }
266
+ }
267
+ cellTexts.push(parts.join(" "));
268
+ }
269
+ mdRows.push(cellTexts);
270
+ }
271
+ if (mdRows.length === 0)
272
+ return null;
273
+ const [header, ...body] = mdRows;
274
+ const lines = [];
275
+ lines.push(`| ${header.join(" | ")} |`);
276
+ lines.push(`| ${header.map(() => "---").join(" | ")} |`);
277
+ for (const row of body) {
278
+ while (row.length < header.length)
279
+ row.push("");
280
+ lines.push(`| ${row.join(" | ")} |`);
281
+ }
282
+ return lines.join("\n");
283
+ }
284
+ }
285
+ function toList(val) {
286
+ if (!val)
287
+ return [];
288
+ return Array.isArray(val) ? val : [val];
289
+ }
@@ -0,0 +1,11 @@
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
+ export declare class RssConverter implements Converter {
3
+ name: string;
4
+ accepts(streamInfo: StreamInfo): boolean;
5
+ convert(input: Buffer, _streamInfo: StreamInfo): Promise<ConversionResult>;
6
+ private parseRss;
7
+ private parseAtom;
8
+ private htmlToMd;
9
+ private extract;
10
+ private extractAll;
11
+ }
@@ -0,0 +1,138 @@
1
+ import { createTurndown } from "../utils/turndown.js";
2
+ const _EXTENSIONS = [".rss", ".atom", ".xml"];
3
+ const MIMETYPES = [
4
+ "application/rss+xml",
5
+ "application/rss",
6
+ "application/atom+xml",
7
+ "application/atom",
8
+ "text/xml",
9
+ "application/xml",
10
+ ];
11
+ export class RssConverter {
12
+ name = "rss";
13
+ accepts(streamInfo) {
14
+ // Only accept known RSS/Atom extensions directly
15
+ if (streamInfo.extension &&
16
+ [".rss", ".atom"].includes(streamInfo.extension))
17
+ return true;
18
+ // For .xml, we'll try and fail gracefully
19
+ if (streamInfo.extension === ".xml")
20
+ return true;
21
+ if (streamInfo.mimetype &&
22
+ MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m)))
23
+ return true;
24
+ return false;
25
+ }
26
+ async convert(input, _streamInfo) {
27
+ const text = new TextDecoder("utf-8").decode(input);
28
+ // Detect feed type
29
+ if (text.includes("<rss")) {
30
+ return this.parseRss(text);
31
+ }
32
+ else if (text.includes("<feed")) {
33
+ return this.parseAtom(text);
34
+ }
35
+ // Not a feed — fall through for XML as generic text
36
+ throw new Error("Not an RSS or Atom feed");
37
+ }
38
+ parseRss(xml) {
39
+ const turndown = createTurndown();
40
+ const sections = [];
41
+ // Extract from the <channel> block specifically
42
+ const channelMatch = xml.match(/<channel>([\s\S]*?)<\/channel>/i);
43
+ const channelXml = channelMatch ? channelMatch[1] : xml;
44
+ const channelTitle = this.extract(channelXml, "title");
45
+ const channelDesc = this.extract(channelXml, "description");
46
+ if (channelTitle)
47
+ sections.push(`# ${channelTitle}`);
48
+ if (channelDesc)
49
+ sections.push(this.htmlToMd(channelDesc, turndown));
50
+ // Extract items
51
+ const items = this.extractAll(xml, "item");
52
+ for (const item of items) {
53
+ const title = this.extract(item, "title");
54
+ const pubDate = this.extract(item, "pubDate");
55
+ const description = this.extract(item, "description");
56
+ const content = this.extract(item, "content:encoded");
57
+ const link = this.extract(item, "link");
58
+ const parts = [];
59
+ if (title)
60
+ parts.push(`## ${title}`);
61
+ if (pubDate)
62
+ parts.push(`Published: ${pubDate}`);
63
+ if (link)
64
+ parts.push(`[Link](${link})`);
65
+ if (content) {
66
+ parts.push(this.htmlToMd(content, turndown));
67
+ }
68
+ else if (description) {
69
+ parts.push(this.htmlToMd(description, turndown));
70
+ }
71
+ if (parts.length > 0)
72
+ sections.push(parts.join("\n"));
73
+ }
74
+ return { markdown: sections.join("\n\n").trim(), title: channelTitle };
75
+ }
76
+ parseAtom(xml) {
77
+ const turndown = createTurndown();
78
+ const sections = [];
79
+ const feedTitle = this.extract(xml, "title");
80
+ const subtitle = this.extract(xml, "subtitle");
81
+ if (feedTitle)
82
+ sections.push(`# ${feedTitle}`);
83
+ if (subtitle)
84
+ sections.push(subtitle);
85
+ const entries = this.extractAll(xml, "entry");
86
+ for (const entry of entries) {
87
+ const title = this.extract(entry, "title");
88
+ const updated = this.extract(entry, "updated");
89
+ const summary = this.extract(entry, "summary");
90
+ const content = this.extract(entry, "content");
91
+ const parts = [];
92
+ if (title)
93
+ parts.push(`## ${title}`);
94
+ if (updated)
95
+ parts.push(`Updated: ${updated}`);
96
+ if (content) {
97
+ parts.push(this.htmlToMd(content, turndown));
98
+ }
99
+ else if (summary) {
100
+ parts.push(this.htmlToMd(summary, turndown));
101
+ }
102
+ if (parts.length > 0)
103
+ sections.push(parts.join("\n"));
104
+ }
105
+ return { markdown: sections.join("\n\n").trim(), title: feedTitle };
106
+ }
107
+ htmlToMd(html, turndown) {
108
+ // Unescape CDATA and HTML entities that might be in RSS
109
+ const unescaped = html
110
+ .replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, "$1")
111
+ .replace(/&lt;/g, "<")
112
+ .replace(/&gt;/g, ">")
113
+ .replace(/&amp;/g, "&");
114
+ // If it looks like HTML, convert it
115
+ if (unescaped.includes("<")) {
116
+ return turndown.turndown(unescaped).trim();
117
+ }
118
+ return unescaped.trim();
119
+ }
120
+ extract(xml, tag) {
121
+ // Handle both <tag>content</tag> and <tag><![CDATA[content]]></tag>
122
+ const re = new RegExp(`<${tag}[^>]*>([\\s\\S]*?)</${tag}>`, "i");
123
+ const match = xml.match(re);
124
+ if (!match)
125
+ return undefined;
126
+ return (match[1].replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, "$1").trim() || undefined);
127
+ }
128
+ extractAll(xml, tag) {
129
+ const results = [];
130
+ const re = new RegExp(`<${tag}[^>]*>[\\s\\S]*?</${tag}>`, "gi");
131
+ let match = re.exec(xml);
132
+ while (match !== null) {
133
+ results.push(match[0]);
134
+ match = re.exec(xml);
135
+ }
136
+ return results;
137
+ }
138
+ }
@@ -0,0 +1,6 @@
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
+ export declare class WikipediaConverter implements Converter {
3
+ name: string;
4
+ accepts(streamInfo: StreamInfo): boolean;
5
+ convert(input: Buffer, streamInfo: StreamInfo): Promise<ConversionResult>;
6
+ }
@@ -0,0 +1,33 @@
1
+ import { createTurndown } from "../utils/turndown.js";
2
+ const WIKIPEDIA_RE = /^https?:\/\/[a-zA-Z]{2,3}\.wikipedia\.org\//;
3
+ export class WikipediaConverter {
4
+ name = "wikipedia";
5
+ accepts(streamInfo) {
6
+ if (!streamInfo.url)
7
+ return false;
8
+ return WIKIPEDIA_RE.test(streamInfo.url);
9
+ }
10
+ async convert(input, streamInfo) {
11
+ const html = new TextDecoder(streamInfo.charset || "utf-8").decode(input);
12
+ // Extract the main content div
13
+ const contentMatch = html.match(/<div[^>]*id="mw-content-text"[^>]*>([\s\S]*?)<\/div>\s*(?:<\/div>|$)/i);
14
+ // Extract title
15
+ const titleMatch = html.match(/<span[^>]*class="mw-page-title-main"[^>]*>([\s\S]*?)<\/span>/i) || html.match(/<title[^>]*>([\s\S]*?)<\/title>/i);
16
+ const title = titleMatch
17
+ ? titleMatch[1].replace(/ - Wikipedia$/, "").trim()
18
+ : undefined;
19
+ const turndown = createTurndown();
20
+ // Clean up Wikipedia-specific elements
21
+ let content = contentMatch ? contentMatch[1] : html;
22
+ content = content
23
+ .replace(/<script[\s\S]*?<\/script>/gi, "")
24
+ .replace(/<style[\s\S]*?<\/style>/gi, "")
25
+ .replace(/<div[^>]*class="[^"]*mw-editsection[^"]*"[\s\S]*?<\/div>/gi, "") // edit links
26
+ .replace(/<sup[^>]*class="[^"]*reference[^"]*"[\s\S]*?<\/sup>/gi, "") // reference numbers
27
+ .replace(/<div[^>]*class="[^"]*navbox[\s\S]*?<\/div>/gi, "") // navboxes
28
+ .replace(/<table[^>]*class="[^"]*sidebar[\s\S]*?<\/table>/gi, ""); // sidebars
29
+ const markdown = turndown.turndown(content).trim();
30
+ const result = title ? `# ${title}\n\n${markdown}` : markdown;
31
+ return { markdown: result, title };
32
+ }
33
+ }
@@ -0,0 +1,8 @@
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
+ export declare class XlsxConverter implements Converter {
3
+ name: string;
4
+ accepts(streamInfo: StreamInfo): boolean;
5
+ convert(input: Buffer, _streamInfo: StreamInfo): Promise<ConversionResult>;
6
+ private getCellValue;
7
+ private getSharedString;
8
+ }
@@ -0,0 +1,147 @@
1
+ import { XMLParser } from "fast-xml-parser";
2
+ import JSZip from "jszip";
3
+ const EXTENSIONS = [".xlsx"];
4
+ const MIMETYPES = [
5
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
6
+ ];
7
+ export class XlsxConverter {
8
+ name = "xlsx";
9
+ accepts(streamInfo) {
10
+ if (streamInfo.extension && EXTENSIONS.includes(streamInfo.extension))
11
+ return true;
12
+ if (streamInfo.mimetype &&
13
+ MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m)))
14
+ return true;
15
+ return false;
16
+ }
17
+ async convert(input, _streamInfo) {
18
+ const zip = await JSZip.loadAsync(input);
19
+ const parser = new XMLParser({
20
+ ignoreAttributes: false,
21
+ attributeNamePrefix: "@_",
22
+ textNodeName: "#text",
23
+ processEntities: { maxTotalExpansions: 1_000_000 },
24
+ });
25
+ // Parse shared strings
26
+ const ssXml = await zip.file("xl/sharedStrings.xml")?.async("string");
27
+ const ss = ssXml ? parser.parse(ssXml) : null;
28
+ const siList = ss?.sst?.si;
29
+ const shared = toArray(siList);
30
+ // Parse workbook for sheet names
31
+ const wbXml = await zip.file("xl/workbook.xml")?.async("string");
32
+ if (!wbXml)
33
+ throw new Error("Invalid XLSX: missing workbook.xml");
34
+ const wb = parser.parse(wbXml);
35
+ const sheets = toArray(wb.workbook?.sheets?.sheet);
36
+ // Parse workbook rels to map rIds to sheet files
37
+ const relsXml = await zip
38
+ .file("xl/_rels/workbook.xml.rels")
39
+ ?.async("string");
40
+ const rels = relsXml ? parser.parse(relsXml) : null;
41
+ const relList = toArray(rels?.Relationships?.Relationship);
42
+ const relMap = new Map();
43
+ for (const r of relList) {
44
+ relMap.set(r["@_Id"], r["@_Target"]);
45
+ }
46
+ const sections = [];
47
+ for (const sheet of sheets) {
48
+ const sheetName = sheet["@_name"];
49
+ const rId = sheet["@_r:id"];
50
+ const target = relMap.get(rId);
51
+ if (!target)
52
+ continue;
53
+ const sheetPath = target.startsWith("/")
54
+ ? target.slice(1)
55
+ : `xl/${target}`;
56
+ const sheetXml = await zip.file(sheetPath)?.async("string");
57
+ if (!sheetXml)
58
+ continue;
59
+ const parsed = parser.parse(sheetXml);
60
+ const rows = toArray(parsed.worksheet?.sheetData?.row);
61
+ if (rows.length === 0)
62
+ continue;
63
+ // Extract all rows as string arrays
64
+ const tableRows = [];
65
+ for (const row of rows) {
66
+ const cells = toArray(row.c);
67
+ const values = [];
68
+ for (const cell of cells) {
69
+ values.push(this.getCellValue(cell, shared));
70
+ }
71
+ tableRows.push(values);
72
+ }
73
+ if (tableRows.length === 0)
74
+ continue;
75
+ // Normalize column count
76
+ const maxCols = Math.max(...tableRows.map((r) => r.length));
77
+ for (const row of tableRows) {
78
+ while (row.length < maxCols)
79
+ row.push("");
80
+ }
81
+ sections.push(`## ${sheetName}`);
82
+ const [header, ...body] = tableRows;
83
+ const lines = [];
84
+ lines.push(`| ${header.join(" | ")} |`);
85
+ lines.push(`| ${header.map(() => "---").join(" | ")} |`);
86
+ for (const row of body) {
87
+ lines.push(`| ${row.join(" | ")} |`);
88
+ }
89
+ sections.push(lines.join("\n"));
90
+ }
91
+ return { markdown: sections.join("\n\n") };
92
+ }
93
+ getCellValue(cell, shared) {
94
+ // Shared string
95
+ if (cell["@_t"] === "s") {
96
+ return this.getSharedString(shared, Number(cell.v));
97
+ }
98
+ // Inline string
99
+ if (cell["@_t"] === "inlineStr") {
100
+ const is = cell.is;
101
+ if (!is)
102
+ return "";
103
+ if (is.t != null)
104
+ return textValue(is.t);
105
+ if (is.r)
106
+ return toArray(is.r)
107
+ .map((r) => textValue(r.t))
108
+ .join("");
109
+ return "";
110
+ }
111
+ // Boolean
112
+ if (cell["@_t"] === "b") {
113
+ return cell.v === 1 || cell.v === "1" ? "TRUE" : "FALSE";
114
+ }
115
+ // Number or formula result
116
+ if (cell.v != null)
117
+ return String(cell.v);
118
+ return "";
119
+ }
120
+ getSharedString(shared, idx) {
121
+ const si = shared[idx];
122
+ if (!si)
123
+ return "";
124
+ // Simple text
125
+ if (si.t != null)
126
+ return textValue(si.t);
127
+ // Rich text runs
128
+ if (si.r) {
129
+ return toArray(si.r)
130
+ .map((r) => textValue(r.t))
131
+ .join("");
132
+ }
133
+ return "";
134
+ }
135
+ }
136
+ function textValue(t) {
137
+ if (t == null)
138
+ return "";
139
+ if (typeof t === "object")
140
+ return t["#text"] || "";
141
+ return String(t);
142
+ }
143
+ function toArray(val) {
144
+ if (!val)
145
+ return [];
146
+ return Array.isArray(val) ? val : [val];
147
+ }
@@ -0,0 +1,6 @@
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
+ export declare class XmlConverter implements Converter {
3
+ name: string;
4
+ accepts(streamInfo: StreamInfo): boolean;
5
+ convert(input: Buffer, streamInfo: StreamInfo): Promise<ConversionResult>;
6
+ }
@@ -0,0 +1,18 @@
1
+ const EXTENSIONS = [".xml", ".svg"];
2
+ const MIMETYPES = ["text/xml", "application/xml"];
3
+ export class XmlConverter {
4
+ name = "xml";
5
+ accepts(streamInfo) {
6
+ if (streamInfo.extension && EXTENSIONS.includes(streamInfo.extension))
7
+ return true;
8
+ if (streamInfo.mimetype &&
9
+ MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m)))
10
+ return true;
11
+ return false;
12
+ }
13
+ async convert(input, streamInfo) {
14
+ const text = new TextDecoder(streamInfo.charset || "utf-8").decode(input);
15
+ const ext = streamInfo.extension?.slice(1) || "xml";
16
+ return { markdown: `\`\`\`${ext}\n${text}\n\`\`\`` };
17
+ }
18
+ }
@@ -0,0 +1,6 @@
1
+ import type { ConversionResult, Converter, StreamInfo } from "../types.js";
2
+ export declare class YamlConverter implements Converter {
3
+ name: string;
4
+ accepts(streamInfo: StreamInfo): boolean;
5
+ convert(input: Buffer, streamInfo: StreamInfo): Promise<ConversionResult>;
6
+ }