@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.
- package/CHANGELOG.md +267 -0
- package/dist/types/cli/daemon-cli.d.ts +3 -1
- package/dist/types/cli/github-release.d.ts +17 -0
- package/dist/types/cli/public-command-entry.d.ts +56 -0
- package/dist/types/cli/public-command-errors.d.ts +126 -0
- package/dist/types/cli/public-command-evidence.d.ts +99 -0
- package/dist/types/cli/public-command-help.d.ts +65 -0
- package/dist/types/cli/public-command-registry.d.ts +69 -0
- package/dist/types/cli/session-picker.d.ts +1 -1
- package/dist/types/cli/setup-cli.d.ts +1 -0
- package/dist/types/cli/skills-cli.d.ts +5 -0
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/commands/daemon.d.ts +4 -50
- package/dist/types/commands/sdk.d.ts +20 -37
- package/dist/types/commands/setup.d.ts +3 -0
- package/dist/types/commands/skills.d.ts +9 -0
- package/dist/types/config/autorouting-tier-map.d.ts +1049 -3
- package/dist/types/config/file-lock.d.ts +13 -3
- package/dist/types/config/model-profile-activation.d.ts +45 -1
- package/dist/types/config/model-registry.d.ts +14 -3
- package/dist/types/config/model-resolver.d.ts +1 -1
- package/dist/types/config/settings-schema.d.ts +11 -0
- package/dist/types/coordinator-mcp/question-state.d.ts +6 -1
- package/dist/types/daemon/operator-contract.d.ts +5 -1
- package/dist/types/eval/js/worker-protocol.d.ts +2 -0
- package/dist/types/exec/bash-executor.d.ts +2 -0
- package/dist/types/extensibility/extensions/types.d.ts +12 -0
- package/dist/types/extensibility/gjc-plugins/registry.d.ts +4 -0
- package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +11 -2
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +18 -0
- package/dist/types/extensibility/shared-events.d.ts +3 -1
- package/dist/types/gjc-runtime/session-state-lock.d.ts +61 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +14 -1
- package/dist/types/harness-control-plane/control-endpoint.d.ts +4 -1
- package/dist/types/harness-control-plane/finalize.d.ts +14 -3
- package/dist/types/internal-urls/embedded-protocol.d.ts +9 -0
- package/dist/types/internal-urls/index.d.ts +1 -0
- package/dist/types/internal-urls/parse.d.ts +9 -1
- package/dist/types/main.d.ts +23 -1
- package/dist/types/modes/acp/acp-agent.d.ts +55 -1
- package/dist/types/modes/acp/startup-provenance.d.ts +16 -0
- package/dist/types/modes/components/custom-provider-wizard.d.ts +19 -1
- package/dist/types/modes/components/session-selector.d.ts +5 -2
- package/dist/types/modes/components/user-message-selector.d.ts +5 -2
- package/dist/types/modes/controllers/command-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +1 -1
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +11 -1
- package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +14 -1
- package/dist/types/modes/types.d.ts +2 -2
- package/dist/types/runtime/process-lifecycle.d.ts +2 -0
- package/dist/types/runtime-mcp/loader.d.ts +2 -0
- package/dist/types/runtime-mcp/manager.d.ts +69 -6
- package/dist/types/runtime-mcp/pool.d.ts +17 -0
- package/dist/types/runtime-mcp/redaction.d.ts +20 -0
- package/dist/types/runtime-mcp/startup-policy.d.ts +6 -0
- package/dist/types/runtime-mcp/tool-bridge.d.ts +9 -0
- package/dist/types/runtime-mcp/transports/http.d.ts +11 -0
- package/dist/types/sdk/broker/broker.d.ts +17 -4
- package/dist/types/sdk/broker/ensure.d.ts +3 -0
- package/dist/types/sdk/broker/identity.d.ts +5 -1
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +23 -3
- package/dist/types/sdk/broker/lifecycle.d.ts +15 -8
- package/dist/types/sdk/broker/managed-task-dag.d.ts +1335 -0
- package/dist/types/sdk/broker/managed-task-verification.d.ts +37 -0
- package/dist/types/sdk/broker/runtime.d.ts +1 -1
- package/dist/types/sdk/broker/session-index.d.ts +22 -3
- package/dist/types/sdk/broker/spawn-authority.d.ts +12 -0
- package/dist/types/sdk/broker/startup-failure.d.ts +4 -0
- package/dist/types/sdk/broker/stderr-drainer.d.ts +13 -0
- package/dist/types/sdk/bus/index.d.ts +19 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +7 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +5 -0
- package/dist/types/sdk/cli/master-cli.d.ts +6 -10
- package/dist/types/sdk/cli/rows.d.ts +19 -1
- package/dist/types/sdk/cli/session-cli.d.ts +22 -5
- package/dist/types/sdk/client/client.d.ts +2 -0
- package/dist/types/sdk/guides/cli.d.ts +3 -4
- package/dist/types/sdk/guides/verify.d.ts +2 -0
- package/dist/types/sdk/host/host.d.ts +9 -0
- package/dist/types/sdk/host/session-runtime.d.ts +31 -0
- package/dist/types/sdk/host/types.d.ts +10 -0
- package/dist/types/sdk/index.d.ts +1 -0
- package/dist/types/sdk/prompt-deadline-flush.d.ts +85 -0
- package/dist/types/sdk/prompt-deadline-manager.d.ts +37 -0
- package/dist/types/sdk/prompt-tool-boundary.d.ts +73 -0
- package/dist/types/sdk/router/session-router.d.ts +2 -0
- package/dist/types/sdk/session.d.ts +3 -3
- package/dist/types/sdk/startup-capability.d.ts +2 -0
- package/dist/types/sdk/transport/relay.d.ts +1 -0
- package/dist/types/sdk/transport/serve-cli.d.ts +48 -4
- package/dist/types/sdk/transport/stdio.d.ts +5 -1
- package/dist/types/session/agent-session.d.ts +175 -23
- package/dist/types/session/fallback-chain-controller.d.ts +6 -6
- package/dist/types/session/fold-coordinator.d.ts +17 -3
- package/dist/types/session/internal/managed-session-storage.d.ts +7 -1
- package/dist/types/session/session-manager.d.ts +64 -1
- package/dist/types/session/session-work-lease.d.ts +14 -0
- package/dist/types/setup/model-onboarding-guidance.d.ts +1 -1
- package/dist/types/setup/provider-onboarding.d.ts +81 -1
- package/dist/types/task/types.d.ts +2 -0
- package/dist/types/tools/bash-interactive.d.ts +1 -0
- package/dist/types/tools/bash.d.ts +37 -11
- package/dist/types/tools/fetch.d.ts +10 -1
- package/dist/types/tools/job.d.ts +1 -1
- package/dist/types/tools/steer-fold.d.ts +31 -0
- package/dist/types/tools/subagent.d.ts +8 -1
- package/dist/types/utils/git.d.ts +28 -2
- package/dist/types/utils/mupdf-embedded.d.ts +2 -0
- package/dist/types/utils/mupdf.d.ts +4 -0
- package/dist/types/utils/session-title-generation.d.ts +6 -0
- package/dist/types/utils/title-generator.d.ts +11 -2
- package/dist/types/web/scrapers/types.d.ts +3 -0
- package/package.json +18 -10
- package/scripts/build-binary.ts +9 -3
- package/scripts/compile-args.ts +0 -9
- package/scripts/embed-mupdf.ts +52 -0
- package/scripts/generate-sdk-operation-inventory.ts +31 -1
- package/scripts/vendor-markit.ts +196 -0
- package/src/async/job-manager.ts +22 -1
- package/src/cli/daemon-cli.ts +53 -18
- package/src/cli/github-release.ts +87 -5
- package/src/cli/mcp-cli.ts +38 -4
- package/src/cli/public-command-entry.ts +450 -0
- package/src/cli/public-command-errors.ts +581 -0
- package/src/cli/public-command-evidence.ts +717 -0
- package/src/cli/public-command-help.ts +360 -0
- package/src/cli/public-command-registry.ts +541 -0
- package/src/cli/session-picker.ts +2 -1
- package/src/cli/setup-cli.ts +10 -1
- package/src/cli/skills-cli.ts +46 -2
- package/src/cli/stats-cli.ts +11 -1
- package/src/cli.ts +61 -1
- package/src/commands/daemon.ts +65 -69
- package/src/commands/sdk.ts +175 -117
- package/src/commands/setup.ts +2 -0
- package/src/commands/skills.ts +11 -0
- package/src/config/autorouting-tier-map.ts +543 -3
- package/src/config/file-lock.ts +206 -65
- package/src/config/model-discovery-manager.ts +4 -4
- package/src/config/model-profile-activation.ts +417 -66
- package/src/config/model-registry.ts +254 -36
- package/src/config/model-resolver.ts +6 -1
- package/src/config/settings-schema.ts +26 -2
- package/src/coordinator-mcp/policy.ts +10 -5
- package/src/coordinator-mcp/question-gate-codec.ts +17 -0
- package/src/coordinator-mcp/question-state.ts +179 -9
- package/src/coordinator-mcp/server.ts +521 -87
- package/src/coordinator-mcp/session-reaper.ts +6 -4
- package/src/crash/record-loader.ts +6 -2
- package/src/daemon/operator-contract.ts +26 -12
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +1 -1
- package/src/eval/js/context-manager.ts +8 -8
- package/src/eval/js/worker-core.ts +9 -4
- package/src/eval/js/worker-protocol.ts +2 -0
- package/src/exec/bash-executor.ts +3 -0
- package/src/extensibility/extensions/runner.ts +52 -4
- package/src/extensibility/extensions/types.ts +10 -0
- package/src/extensibility/gjc-plugins/registry.ts +196 -37
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +46 -8
- package/src/extensibility/runtime-skill-discovery.ts +61 -3
- package/src/extensibility/shared-events.ts +3 -1
- package/src/gjc-runtime/session-state-lock.ts +165 -24
- package/src/gjc-runtime/state-writer.ts +317 -6
- package/src/gjc-runtime/ultragoal-succession.ts +31 -3
- package/src/harness-control-plane/control-endpoint.ts +24 -6
- package/src/harness-control-plane/finalize.ts +312 -25
- package/src/harness-control-plane/owner.ts +323 -89
- package/src/internal-urls/docs-index.generated.ts +23 -20
- package/src/internal-urls/embedded-protocol.ts +83 -0
- package/src/internal-urls/index.ts +1 -0
- package/src/internal-urls/parse.ts +21 -1
- package/src/internal-urls/router.ts +4 -2
- package/src/main.ts +192 -74
- package/src/modes/acp/acp-agent.ts +973 -56
- package/src/modes/acp/startup-provenance.ts +59 -0
- package/src/modes/components/custom-provider-wizard.ts +308 -7
- package/src/modes/components/gjc-bundle-settings.ts +21 -1
- package/src/modes/components/oauth-selector.ts +9 -0
- package/src/modes/components/session-selector.ts +47 -4
- package/src/modes/components/tool-status-header.ts +72 -6
- package/src/modes/components/user-message-selector.ts +57 -15
- package/src/modes/controllers/command-controller.ts +58 -32
- package/src/modes/controllers/extension-ui-controller.ts +33 -7
- package/src/modes/controllers/input-controller.ts +4 -0
- package/src/modes/controllers/runtime-mcp-command-controller.ts +1 -1
- package/src/modes/controllers/selector-controller.ts +161 -15
- package/src/modes/interactive-mode.ts +21 -7
- package/src/modes/runtime-init.ts +1 -0
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +124 -7
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +16 -2
- package/src/modes/types.ts +2 -2
- package/src/prompts/agent-fragments/browser-aside.md +1 -0
- package/src/prompts/system/title-system.md +1 -1
- package/src/prompts/tools/bash.md +1 -1
- package/src/prompts/tools/job.md +1 -1
- package/src/prompts/tools/read.md +2 -0
- package/src/runtime/network-prewarm-service.test.ts +36 -1
- package/src/runtime/network-prewarm-service.ts +28 -3
- package/src/runtime/process-lifecycle.ts +22 -11
- package/src/runtime-mcp/config.ts +16 -1
- package/src/runtime-mcp/loader.ts +6 -3
- package/src/runtime-mcp/manager.ts +845 -109
- package/src/runtime-mcp/pool.test.ts +31 -0
- package/src/runtime-mcp/pool.ts +304 -28
- package/src/runtime-mcp/redaction.ts +42 -0
- package/src/runtime-mcp/startup-policy.ts +7 -0
- package/src/runtime-mcp/tool-bridge.ts +71 -0
- package/src/runtime-mcp/transports/http.ts +108 -25
- package/src/sdk/acp/adapter.ts +27 -8
- package/src/sdk/broker/broker.ts +1431 -198
- package/src/sdk/broker/ensure.ts +21 -3
- package/src/sdk/broker/identity.ts +22 -1
- package/src/sdk/broker/lifecycle-ledger.ts +95 -31
- package/src/sdk/broker/lifecycle.ts +690 -141
- package/src/sdk/broker/managed-task-dag.ts +1927 -0
- package/src/sdk/broker/managed-task-verification.ts +642 -0
- package/src/sdk/broker/runtime.ts +1 -1
- package/src/sdk/broker/session-index.ts +97 -4
- package/src/sdk/broker/spawn-authority.ts +175 -14
- package/src/sdk/broker/startup-failure.ts +80 -1
- package/src/sdk/broker/stderr-drainer.ts +59 -0
- package/src/sdk/broker/transport.ts +1 -0
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/chat-daemon-runtime.ts +1 -0
- package/src/sdk/bus/index.ts +707 -81
- package/src/sdk/bus/telegram-daemon-cli.ts +31 -2
- package/src/sdk/bus/telegram-daemon-contract.ts +7 -1
- package/src/sdk/bus/telegram-daemon.ts +10 -3
- package/src/sdk/cli/master-cli.ts +47 -36
- package/src/sdk/cli/rows.ts +30 -7
- package/src/sdk/cli/session-cli.ts +705 -184
- package/src/sdk/client/client.ts +18 -0
- package/src/sdk/guides/catalog.ts +2 -2
- package/src/sdk/guides/cli.ts +20 -62
- package/src/sdk/guides/verify.ts +14 -0
- package/src/sdk/host/host.ts +49 -5
- package/src/sdk/host/session-runtime.test.ts +184 -2
- package/src/sdk/host/session-runtime.ts +322 -101
- package/src/sdk/host/types.ts +12 -1
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +84 -0
- package/src/sdk/host/websocket-transport.ts +40 -6
- package/src/sdk/index.ts +11 -0
- package/src/sdk/lifecycle/service.ts +2 -0
- package/src/sdk/prompt-deadline-flush.ts +356 -0
- package/src/sdk/prompt-deadline-manager.ts +133 -1
- package/src/sdk/prompt-tool-boundary.ts +121 -0
- package/src/sdk/protocol/operation-inventory.generated.json +106 -0
- package/src/sdk/router/session-router.ts +9 -1
- package/src/sdk/session.ts +763 -116
- package/src/sdk/startup-capability.ts +1 -1
- package/src/sdk/transport/relay.ts +71 -6
- package/src/sdk/transport/serve-cli.ts +397 -42
- package/src/sdk/transport/socket.ts +12 -11
- package/src/sdk/transport/stdio.ts +7 -3
- package/src/session/agent-session.ts +2472 -407
- package/src/session/fallback-chain-controller.ts +6 -7
- package/src/session/fold-coordinator.ts +24 -5
- package/src/session/internal/managed-session-scope.ts +68 -18
- package/src/session/internal/managed-session-storage.ts +334 -12
- package/src/session/session-manager.ts +382 -44
- package/src/session/session-work-lease.ts +34 -0
- package/src/setup/model-onboarding-guidance.ts +1 -1
- package/src/setup/provider-onboarding.ts +397 -24
- package/src/setup/provider-presets.json +2 -1
- package/src/slash-commands/builtin-registry.ts +259 -15
- package/src/task/executor.ts +46 -17
- package/src/task/index.ts +14 -2
- package/src/task/types.ts +2 -0
- package/src/tools/bash-interactive.ts +2 -0
- package/src/tools/bash.ts +118 -78
- package/src/tools/fetch.ts +140 -25
- package/src/tools/job.ts +151 -25
- package/src/tools/output-meta.ts +15 -2
- package/src/tools/path-utils.ts +27 -3
- package/src/tools/read.ts +3 -3
- package/src/tools/steer-fold.ts +107 -0
- package/src/tools/subagent-render.ts +24 -1
- package/src/tools/subagent.ts +27 -1
- package/src/tools/tool-catalog.generated.ts +29 -2
- package/src/tools/tool-errors.ts +4 -0
- package/src/utils/git.ts +53 -3
- package/src/utils/markit.ts +55 -41
- package/src/utils/mupdf-assets.d.ts +4 -0
- package/src/utils/mupdf-embedded.ts +4 -0
- package/src/utils/mupdf.ts +136 -0
- package/src/utils/session-title-generation.ts +29 -0
- package/src/utils/title-generator.ts +46 -2
- package/src/web/scrapers/types.ts +24 -3
- package/vendor/markit-ai/LICENSE +21 -0
- package/vendor/markit-ai/MANIFEST.json +412 -0
- package/vendor/markit-ai/dist/commands/config.d.ts +4 -0
- package/vendor/markit-ai/dist/commands/config.js +139 -0
- package/vendor/markit-ai/dist/commands/convert.d.ts +6 -0
- package/vendor/markit-ai/dist/commands/convert.js +113 -0
- package/vendor/markit-ai/dist/commands/formats.d.ts +2 -0
- package/vendor/markit-ai/dist/commands/formats.js +92 -0
- package/vendor/markit-ai/dist/commands/init.d.ts +2 -0
- package/vendor/markit-ai/dist/commands/init.js +29 -0
- package/vendor/markit-ai/dist/commands/onboard.d.ts +2 -0
- package/vendor/markit-ai/dist/commands/onboard.js +61 -0
- package/vendor/markit-ai/dist/commands/plugin.d.ts +4 -0
- package/vendor/markit-ai/dist/commands/plugin.js +58 -0
- package/vendor/markit-ai/dist/config.d.ts +26 -0
- package/vendor/markit-ai/dist/config.js +42 -0
- package/vendor/markit-ai/dist/converters/audio.d.ts +7 -0
- package/vendor/markit-ai/dist/converters/audio.js +104 -0
- package/vendor/markit-ai/dist/converters/csv.d.ts +7 -0
- package/vendor/markit-ai/dist/converters/csv.js +83 -0
- package/vendor/markit-ai/dist/converters/docx.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/docx.js +57 -0
- package/vendor/markit-ai/dist/converters/epub.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/epub.js +128 -0
- package/vendor/markit-ai/dist/converters/github.d.ts +18 -0
- package/vendor/markit-ai/dist/converters/github.js +148 -0
- package/vendor/markit-ai/dist/converters/html.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/html.js +30 -0
- package/vendor/markit-ai/dist/converters/image.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/image.js +124 -0
- package/vendor/markit-ai/dist/converters/ipynb.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/ipynb.js +75 -0
- package/vendor/markit-ai/dist/converters/iwork.d.ts +20 -0
- package/vendor/markit-ai/dist/converters/iwork.js +391 -0
- package/vendor/markit-ai/dist/converters/json.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/json.js +21 -0
- package/vendor/markit-ai/dist/converters/pdf/columns.d.ts +35 -0
- package/vendor/markit-ai/dist/converters/pdf/columns.js +93 -0
- package/vendor/markit-ai/dist/converters/pdf/extract.d.ts +19 -0
- package/vendor/markit-ai/dist/converters/pdf/extract.js +514 -0
- package/vendor/markit-ai/dist/converters/pdf/grid.d.ts +25 -0
- package/vendor/markit-ai/dist/converters/pdf/grid.js +795 -0
- package/vendor/markit-ai/dist/converters/pdf/headers.d.ts +24 -0
- package/vendor/markit-ai/dist/converters/pdf/headers.js +108 -0
- package/vendor/markit-ai/dist/converters/pdf/index.d.ts +19 -0
- package/vendor/markit-ai/dist/converters/pdf/index.js +136 -0
- package/vendor/markit-ai/dist/converters/pdf/mupdf-loader.js +9 -0
- package/vendor/markit-ai/dist/converters/pdf/render.d.ts +24 -0
- package/vendor/markit-ai/dist/converters/pdf/render.js +513 -0
- package/vendor/markit-ai/dist/converters/pdf/types.d.ts +75 -0
- package/vendor/markit-ai/dist/converters/pdf/types.js +1 -0
- package/vendor/markit-ai/dist/converters/plain-text.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/plain-text.js +87 -0
- package/vendor/markit-ai/dist/converters/pptx.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/pptx.js +289 -0
- package/vendor/markit-ai/dist/converters/rss.d.ts +11 -0
- package/vendor/markit-ai/dist/converters/rss.js +138 -0
- package/vendor/markit-ai/dist/converters/wikipedia.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/wikipedia.js +33 -0
- package/vendor/markit-ai/dist/converters/xlsx.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/xlsx.js +147 -0
- package/vendor/markit-ai/dist/converters/xml.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/xml.js +18 -0
- package/vendor/markit-ai/dist/converters/yaml.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/yaml.js +17 -0
- package/vendor/markit-ai/dist/converters/zip.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/zip.js +57 -0
- package/vendor/markit-ai/dist/index.d.ts +30 -0
- package/vendor/markit-ai/dist/index.js +26 -0
- package/vendor/markit-ai/dist/main.d.ts +2 -0
- package/vendor/markit-ai/dist/main.js +191 -0
- package/vendor/markit-ai/dist/markit.d.ts +45 -0
- package/vendor/markit-ai/dist/markit.js +267 -0
- package/vendor/markit-ai/dist/plugins/api.d.ts +7 -0
- package/vendor/markit-ai/dist/plugins/api.js +42 -0
- package/vendor/markit-ai/dist/plugins/index.d.ts +4 -0
- package/vendor/markit-ai/dist/plugins/index.js +3 -0
- package/vendor/markit-ai/dist/plugins/installer.d.ts +25 -0
- package/vendor/markit-ai/dist/plugins/installer.js +176 -0
- package/vendor/markit-ai/dist/plugins/loader.d.ts +6 -0
- package/vendor/markit-ai/dist/plugins/loader.js +61 -0
- package/vendor/markit-ai/dist/plugins/types.d.ts +25 -0
- package/vendor/markit-ai/dist/plugins/types.js +1 -0
- package/vendor/markit-ai/dist/providers/anthropic.d.ts +2 -0
- package/vendor/markit-ai/dist/providers/anthropic.js +47 -0
- package/vendor/markit-ai/dist/providers/index.d.ts +21 -0
- package/vendor/markit-ai/dist/providers/index.js +56 -0
- package/vendor/markit-ai/dist/providers/openai.d.ts +2 -0
- package/vendor/markit-ai/dist/providers/openai.js +76 -0
- package/vendor/markit-ai/dist/providers/types.d.ts +26 -0
- package/vendor/markit-ai/dist/providers/types.js +1 -0
- package/vendor/markit-ai/dist/types.d.ts +36 -0
- package/vendor/markit-ai/dist/types.js +1 -0
- package/vendor/markit-ai/dist/utils/exit-codes.d.ts +4 -0
- package/vendor/markit-ai/dist/utils/exit-codes.js +4 -0
- package/vendor/markit-ai/dist/utils/output.d.ts +22 -0
- package/vendor/markit-ai/dist/utils/output.js +31 -0
- package/vendor/markit-ai/dist/utils/turndown.d.ts +8 -0
- package/vendor/markit-ai/dist/utils/turndown.js +70 -0
- package/vendor/markit-ai/package.json +74 -0
- package/vendor/markit-ai.patch +49 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { loadAllPlugins } from "../plugins/loader.js";
|
|
2
|
+
import { bold, dim, output } from "../utils/output.js";
|
|
3
|
+
const BUILTIN_FORMATS = [
|
|
4
|
+
{ name: "PDF", extensions: [".pdf"], builtin: true },
|
|
5
|
+
{ name: "Word", extensions: [".docx"], builtin: true },
|
|
6
|
+
{ name: "PowerPoint", extensions: [".pptx"], builtin: true },
|
|
7
|
+
{ name: "Excel", extensions: [".xlsx"], builtin: true },
|
|
8
|
+
{ name: "HTML", extensions: [".html", ".htm"], builtin: true },
|
|
9
|
+
{ name: "EPUB", extensions: [".epub"], builtin: true },
|
|
10
|
+
{ name: "Jupyter", extensions: [".ipynb"], builtin: true },
|
|
11
|
+
{ name: "RSS/Atom", extensions: [".rss", ".atom", ".xml"], builtin: true },
|
|
12
|
+
{ name: "CSV", extensions: [".csv", ".tsv"], builtin: true },
|
|
13
|
+
{ name: "JSON", extensions: [".json"], builtin: true },
|
|
14
|
+
{ name: "YAML", extensions: [".yaml", ".yml"], builtin: true },
|
|
15
|
+
{ name: "XML", extensions: [".xml", ".svg"], builtin: true },
|
|
16
|
+
{
|
|
17
|
+
name: "Images",
|
|
18
|
+
extensions: [".jpg", ".png", ".gif", ".webp"],
|
|
19
|
+
builtin: true,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: "Audio",
|
|
23
|
+
extensions: [".mp3", ".wav", ".m4a", ".flac"],
|
|
24
|
+
builtin: true,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "Pages",
|
|
28
|
+
extensions: [".pages"],
|
|
29
|
+
builtin: true,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: "Keynote",
|
|
33
|
+
extensions: [".key"],
|
|
34
|
+
builtin: true,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "Numbers",
|
|
38
|
+
extensions: [".numbers"],
|
|
39
|
+
builtin: true,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: "GitHub",
|
|
43
|
+
extensions: ["github.com/*", "gist.github.com/*"],
|
|
44
|
+
builtin: true,
|
|
45
|
+
},
|
|
46
|
+
{ name: "ZIP", extensions: [".zip"], builtin: true },
|
|
47
|
+
{
|
|
48
|
+
name: "Plain text",
|
|
49
|
+
extensions: [".txt", ".md", ".rst", ".log"],
|
|
50
|
+
builtin: true,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "Code",
|
|
54
|
+
extensions: [".py", ".js", ".ts", ".go", ".rs", "..."],
|
|
55
|
+
builtin: true,
|
|
56
|
+
},
|
|
57
|
+
{ name: "URLs", extensions: ["http://", "https://"], builtin: true },
|
|
58
|
+
{ name: "Wikipedia", extensions: ["*.wikipedia.org"], builtin: true },
|
|
59
|
+
];
|
|
60
|
+
export async function formats(_args, options) {
|
|
61
|
+
const plugins = await loadAllPlugins();
|
|
62
|
+
const pluginFormats = plugins.flatMap((p) => p.formats.map((f) => ({
|
|
63
|
+
name: f.name,
|
|
64
|
+
extensions: f.extensions,
|
|
65
|
+
builtin: false,
|
|
66
|
+
plugin: p.name,
|
|
67
|
+
})));
|
|
68
|
+
const allFormats = [...BUILTIN_FORMATS, ...pluginFormats];
|
|
69
|
+
output(options, {
|
|
70
|
+
json: () => ({ formats: allFormats }),
|
|
71
|
+
human: () => {
|
|
72
|
+
console.log();
|
|
73
|
+
console.log(bold("Supported formats"));
|
|
74
|
+
console.log();
|
|
75
|
+
for (const fmt of BUILTIN_FORMATS) {
|
|
76
|
+
const exts = fmt.extensions.join(", ");
|
|
77
|
+
const note = fmt.dep ? dim(` (requires: npm i ${fmt.dep})`) : "";
|
|
78
|
+
console.log(` ${fmt.name.padEnd(14)} ${dim(exts)}${note}`);
|
|
79
|
+
}
|
|
80
|
+
if (pluginFormats.length > 0) {
|
|
81
|
+
console.log();
|
|
82
|
+
console.log(bold("Plugin formats"));
|
|
83
|
+
console.log();
|
|
84
|
+
for (const fmt of pluginFormats) {
|
|
85
|
+
const exts = fmt.extensions.join(", ");
|
|
86
|
+
console.log(` ${fmt.name.padEnd(14)} ${dim(exts)} ${dim(`(${fmt.plugin})`)}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
console.log();
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { cmd, hint, output, success } from "../utils/output.js";
|
|
4
|
+
const DATA_DIR = ".markit";
|
|
5
|
+
export async function init(_args, options) {
|
|
6
|
+
const root = join(process.cwd(), DATA_DIR);
|
|
7
|
+
if (existsSync(root)) {
|
|
8
|
+
output(options, {
|
|
9
|
+
json: () => ({ success: true, path: root, message: "already_exists" }),
|
|
10
|
+
human: () => success(`.markit/ already exists`),
|
|
11
|
+
});
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
mkdirSync(root, { recursive: true });
|
|
15
|
+
const config = {
|
|
16
|
+
llm: {},
|
|
17
|
+
};
|
|
18
|
+
writeFileSync(join(root, "config.json"), `${JSON.stringify(config, null, 2)}\n`);
|
|
19
|
+
output(options, {
|
|
20
|
+
json: () => ({ success: true, path: root }),
|
|
21
|
+
human: () => {
|
|
22
|
+
success(`Created .markit/ in ${process.cwd()}`);
|
|
23
|
+
hint("Set your API key for image/audio AI features:");
|
|
24
|
+
console.log(` ${cmd("export OPENAI_API_KEY=sk-...")}`);
|
|
25
|
+
hint("Or configure directly:");
|
|
26
|
+
console.log(` ${cmd("markit config set llm.apiKey sk-...")}`);
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { output, success } from "../utils/output.js";
|
|
4
|
+
const INSTRUCTIONS = `
|
|
5
|
+
<mill>
|
|
6
|
+
Use \`markit\` to convert files and URLs to markdown. Supports PDF, DOCX, HTML, XLSX, CSV, JSON, and plain text.
|
|
7
|
+
|
|
8
|
+
<commands>
|
|
9
|
+
- \`markit <file-or-url>\` - convert to markdown (stdout)
|
|
10
|
+
- \`markit <file-or-url> -o output.md\` - convert to file
|
|
11
|
+
- \`markit formats\` - list supported formats
|
|
12
|
+
</commands>
|
|
13
|
+
|
|
14
|
+
<rules>
|
|
15
|
+
- Use \`--json\` flag to get structured output for parsing
|
|
16
|
+
- Use \`-q\` to get raw markdown without formatting
|
|
17
|
+
- Pipe output directly: \`markit report.pdf | other-tool\`
|
|
18
|
+
</rules>
|
|
19
|
+
</markit>
|
|
20
|
+
`.trim();
|
|
21
|
+
const MARKER = "<mill>";
|
|
22
|
+
export async function onboard(_args, options) {
|
|
23
|
+
const cwd = process.cwd();
|
|
24
|
+
const claudeMd = join(cwd, "CLAUDE.md");
|
|
25
|
+
const agentsMd = join(cwd, "AGENTS.md");
|
|
26
|
+
let targetFile;
|
|
27
|
+
if (existsSync(claudeMd)) {
|
|
28
|
+
targetFile = claudeMd;
|
|
29
|
+
}
|
|
30
|
+
else if (existsSync(agentsMd)) {
|
|
31
|
+
targetFile = agentsMd;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
targetFile = claudeMd;
|
|
35
|
+
}
|
|
36
|
+
let existingContent = "";
|
|
37
|
+
if (existsSync(targetFile)) {
|
|
38
|
+
existingContent = readFileSync(targetFile, "utf-8");
|
|
39
|
+
}
|
|
40
|
+
if (existingContent.includes(MARKER)) {
|
|
41
|
+
output(options, {
|
|
42
|
+
json: () => ({
|
|
43
|
+
success: true,
|
|
44
|
+
file: targetFile,
|
|
45
|
+
message: "already_onboarded",
|
|
46
|
+
}),
|
|
47
|
+
human: () => success(`Already onboarded (${targetFile})`),
|
|
48
|
+
});
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (existingContent) {
|
|
52
|
+
writeFileSync(targetFile, `${existingContent.trimEnd()}\n\n${INSTRUCTIONS}\n`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
writeFileSync(targetFile, `${INSTRUCTIONS}\n`);
|
|
56
|
+
}
|
|
57
|
+
output(options, {
|
|
58
|
+
json: () => ({ success: true, file: targetFile }),
|
|
59
|
+
human: () => success(`Added markit instructions to ${targetFile}`),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { OutputOptions } from "../utils/output.js";
|
|
2
|
+
export declare function pluginInstall(source: string, options: OutputOptions): Promise<void>;
|
|
3
|
+
export declare function pluginRemove(name: string, options: OutputOptions): Promise<void>;
|
|
4
|
+
export declare function pluginList(options: OutputOptions): Promise<void>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { installPlugin, listInstalled, removePlugin, } from "../plugins/installer.js";
|
|
2
|
+
import { EXIT_ERROR } from "../utils/exit-codes.js";
|
|
3
|
+
import { bold, dim, error, output, success } from "../utils/output.js";
|
|
4
|
+
export async function pluginInstall(source, options) {
|
|
5
|
+
try {
|
|
6
|
+
const result = await installPlugin(source);
|
|
7
|
+
output(options, {
|
|
8
|
+
json: () => ({ success: true, ...result }),
|
|
9
|
+
human: () => {
|
|
10
|
+
success(`Installed ${result.name}`);
|
|
11
|
+
console.log(dim(` ${result.path}`));
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
17
|
+
output(options, {
|
|
18
|
+
json: () => ({ success: false, error: msg }),
|
|
19
|
+
human: () => error(msg),
|
|
20
|
+
});
|
|
21
|
+
process.exit(EXIT_ERROR);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export async function pluginRemove(name, options) {
|
|
25
|
+
const removed = removePlugin(name);
|
|
26
|
+
output(options, {
|
|
27
|
+
json: () => ({ success: removed, name }),
|
|
28
|
+
human: () => {
|
|
29
|
+
if (removed) {
|
|
30
|
+
success(`Removed ${name}`);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
error(`Plugin '${name}' not found`);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
if (!removed)
|
|
38
|
+
process.exit(EXIT_ERROR);
|
|
39
|
+
}
|
|
40
|
+
export async function pluginList(options) {
|
|
41
|
+
const plugins = listInstalled();
|
|
42
|
+
output(options, {
|
|
43
|
+
json: () => ({ plugins }),
|
|
44
|
+
human: () => {
|
|
45
|
+
if (plugins.length === 0) {
|
|
46
|
+
console.log(dim(" No plugins installed"));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
console.log();
|
|
50
|
+
console.log(bold("Installed plugins"));
|
|
51
|
+
console.log();
|
|
52
|
+
for (const p of plugins) {
|
|
53
|
+
console.log(` ${p.name.padEnd(20)} ${dim(p.type)} ${dim(p.source)}`);
|
|
54
|
+
}
|
|
55
|
+
console.log();
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface MarkitConfig {
|
|
2
|
+
llm?: {
|
|
3
|
+
/** Provider name: "openai" (default), "anthropic", or any registered provider */
|
|
4
|
+
provider?: string;
|
|
5
|
+
/** API base URL (overrides provider default) */
|
|
6
|
+
apiBase?: string;
|
|
7
|
+
/** API key — prefer env vars over storing here */
|
|
8
|
+
apiKey?: string;
|
|
9
|
+
/** Model override (overrides provider default) */
|
|
10
|
+
model?: string;
|
|
11
|
+
/** Transcription model override */
|
|
12
|
+
transcriptionModel?: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Walk up from cwd to find .markit/ directory.
|
|
17
|
+
*/
|
|
18
|
+
export declare function findConfigDir(): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* Load config from .markit/config.json.
|
|
21
|
+
*/
|
|
22
|
+
export declare function loadConfig(): MarkitConfig;
|
|
23
|
+
/**
|
|
24
|
+
* Save config to .markit/config.json. Creates .markit/ if needed.
|
|
25
|
+
*/
|
|
26
|
+
export declare function saveConfig(config: MarkitConfig): void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
const DATA_DIR = ".markit";
|
|
4
|
+
const CONFIG_FILE = "config.json";
|
|
5
|
+
/**
|
|
6
|
+
* Walk up from cwd to find .markit/ directory.
|
|
7
|
+
*/
|
|
8
|
+
export function findConfigDir() {
|
|
9
|
+
let dir = process.cwd();
|
|
10
|
+
while (true) {
|
|
11
|
+
if (existsSync(join(dir, DATA_DIR))) {
|
|
12
|
+
return join(dir, DATA_DIR);
|
|
13
|
+
}
|
|
14
|
+
const parent = join(dir, "..");
|
|
15
|
+
if (parent === dir)
|
|
16
|
+
return null;
|
|
17
|
+
dir = parent;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Load config from .markit/config.json.
|
|
22
|
+
*/
|
|
23
|
+
export function loadConfig() {
|
|
24
|
+
const configDir = findConfigDir();
|
|
25
|
+
if (!configDir)
|
|
26
|
+
return {};
|
|
27
|
+
const configFile = join(configDir, CONFIG_FILE);
|
|
28
|
+
if (!existsSync(configFile))
|
|
29
|
+
return {};
|
|
30
|
+
const raw = JSON.parse(readFileSync(configFile, "utf-8"));
|
|
31
|
+
return { ...raw, llm: { ...raw.llm } };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Save config to .markit/config.json. Creates .markit/ if needed.
|
|
35
|
+
*/
|
|
36
|
+
export function saveConfig(config) {
|
|
37
|
+
const configDir = findConfigDir();
|
|
38
|
+
const dir = configDir || join(process.cwd(), DATA_DIR);
|
|
39
|
+
if (!existsSync(dir))
|
|
40
|
+
mkdirSync(dir, { recursive: true });
|
|
41
|
+
writeFileSync(join(dir, CONFIG_FILE), `${JSON.stringify(config, null, 2)}\n`);
|
|
42
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ConversionResult, Converter, MarkitOptions, StreamInfo } from "../types.js";
|
|
2
|
+
export declare class AudioConverter implements Converter {
|
|
3
|
+
name: string;
|
|
4
|
+
accepts(streamInfo: StreamInfo): boolean;
|
|
5
|
+
convert(input: Buffer, streamInfo: StreamInfo, options?: MarkitOptions): Promise<ConversionResult>;
|
|
6
|
+
private formatDuration;
|
|
7
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const EXTENSIONS = [
|
|
2
|
+
".mp3",
|
|
3
|
+
".wav",
|
|
4
|
+
".m4a",
|
|
5
|
+
".mp4",
|
|
6
|
+
".ogg",
|
|
7
|
+
".flac",
|
|
8
|
+
".aac",
|
|
9
|
+
".wma",
|
|
10
|
+
];
|
|
11
|
+
const MIMETYPES = ["audio/", "video/mp4"];
|
|
12
|
+
export class AudioConverter {
|
|
13
|
+
name = "audio";
|
|
14
|
+
accepts(streamInfo) {
|
|
15
|
+
if (streamInfo.extension && EXTENSIONS.includes(streamInfo.extension))
|
|
16
|
+
return true;
|
|
17
|
+
if (streamInfo.mimetype &&
|
|
18
|
+
MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m)))
|
|
19
|
+
return true;
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
async convert(input, streamInfo, options) {
|
|
23
|
+
const sections = [];
|
|
24
|
+
// Extract audio metadata
|
|
25
|
+
try {
|
|
26
|
+
const mm = await import("music-metadata");
|
|
27
|
+
const metadata = await mm.parseBuffer(new Uint8Array(input), {
|
|
28
|
+
mimeType: streamInfo.mimetype,
|
|
29
|
+
size: input.length,
|
|
30
|
+
});
|
|
31
|
+
const { common, format } = metadata;
|
|
32
|
+
sections.push("## Metadata\n");
|
|
33
|
+
const fields = {
|
|
34
|
+
Title: common.title,
|
|
35
|
+
Artist: common.artist,
|
|
36
|
+
Album: common.album,
|
|
37
|
+
Genre: common.genre?.join(", "),
|
|
38
|
+
Track: common.track?.no
|
|
39
|
+
? `${common.track.no}${common.track.of ? ` of ${common.track.of}` : ""}`
|
|
40
|
+
: undefined,
|
|
41
|
+
Year: common.year ? String(common.year) : undefined,
|
|
42
|
+
Duration: format.duration
|
|
43
|
+
? this.formatDuration(format.duration)
|
|
44
|
+
: undefined,
|
|
45
|
+
Format: format.codec || format.container,
|
|
46
|
+
SampleRate: format.sampleRate ? `${format.sampleRate} Hz` : undefined,
|
|
47
|
+
Channels: format.numberOfChannels
|
|
48
|
+
? String(format.numberOfChannels)
|
|
49
|
+
: undefined,
|
|
50
|
+
Bitrate: format.bitrate
|
|
51
|
+
? `${Math.round(format.bitrate / 1000)} kbps`
|
|
52
|
+
: undefined,
|
|
53
|
+
};
|
|
54
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
55
|
+
if (value)
|
|
56
|
+
sections.push(`${key}: ${value}`);
|
|
57
|
+
}
|
|
58
|
+
if (common.lyrics?.length) {
|
|
59
|
+
sections.push(`\n## Lyrics\n\n${common.lyrics.join("\n")}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Metadata parsing failed
|
|
64
|
+
}
|
|
65
|
+
// AI transcription
|
|
66
|
+
if (options?.transcribe) {
|
|
67
|
+
try {
|
|
68
|
+
const mimetype = streamInfo.mimetype || guessMimetype(streamInfo.extension);
|
|
69
|
+
const transcript = await options.transcribe(input, mimetype);
|
|
70
|
+
if (transcript) {
|
|
71
|
+
sections.push(`\n## Transcript\n\n${transcript}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Transcription failed
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (sections.length === 0) {
|
|
79
|
+
return { markdown: `*[audio: ${streamInfo.filename || "unknown"}]*` };
|
|
80
|
+
}
|
|
81
|
+
return { markdown: sections.join("\n").trim() };
|
|
82
|
+
}
|
|
83
|
+
formatDuration(seconds) {
|
|
84
|
+
const h = Math.floor(seconds / 3600);
|
|
85
|
+
const m = Math.floor((seconds % 3600) / 60);
|
|
86
|
+
const s = Math.round(seconds % 60);
|
|
87
|
+
if (h > 0)
|
|
88
|
+
return `${h}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
|
|
89
|
+
return `${m}:${String(s).padStart(2, "0")}`;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function guessMimetype(ext) {
|
|
93
|
+
const map = {
|
|
94
|
+
".mp3": "audio/mpeg",
|
|
95
|
+
".wav": "audio/wav",
|
|
96
|
+
".m4a": "audio/mp4",
|
|
97
|
+
".mp4": "video/mp4",
|
|
98
|
+
".ogg": "audio/ogg",
|
|
99
|
+
".flac": "audio/flac",
|
|
100
|
+
".aac": "audio/aac",
|
|
101
|
+
".wma": "audio/x-ms-wma",
|
|
102
|
+
};
|
|
103
|
+
return map[ext || ""] || "audio/mpeg";
|
|
104
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ConversionResult, Converter, StreamInfo } from "../types.js";
|
|
2
|
+
export declare class CsvConverter implements Converter {
|
|
3
|
+
name: string;
|
|
4
|
+
accepts(streamInfo: StreamInfo): boolean;
|
|
5
|
+
convert(input: Buffer, streamInfo: StreamInfo): Promise<ConversionResult>;
|
|
6
|
+
private parseRows;
|
|
7
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const EXTENSIONS = [".csv", ".tsv"];
|
|
2
|
+
const MIMETYPES = ["text/csv", "text/tab-separated-values"];
|
|
3
|
+
export class CsvConverter {
|
|
4
|
+
name = "csv";
|
|
5
|
+
accepts(streamInfo) {
|
|
6
|
+
if (streamInfo.extension && EXTENSIONS.includes(streamInfo.extension)) {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
if (streamInfo.mimetype &&
|
|
10
|
+
MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m))) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
async convert(input, streamInfo) {
|
|
16
|
+
const text = new TextDecoder(streamInfo.charset || "utf-8").decode(input);
|
|
17
|
+
const delimiter = streamInfo.extension === ".tsv" ? "\t" : ",";
|
|
18
|
+
const rows = this.parseRows(text, delimiter);
|
|
19
|
+
if (rows.length === 0) {
|
|
20
|
+
return { markdown: "" };
|
|
21
|
+
}
|
|
22
|
+
const [header, ...body] = rows;
|
|
23
|
+
const lines = [];
|
|
24
|
+
// Header
|
|
25
|
+
lines.push(`| ${header.join(" | ")} |`);
|
|
26
|
+
lines.push(`| ${header.map(() => "---").join(" | ")} |`);
|
|
27
|
+
// Body
|
|
28
|
+
for (const row of body) {
|
|
29
|
+
// Pad row to match header length
|
|
30
|
+
while (row.length < header.length)
|
|
31
|
+
row.push("");
|
|
32
|
+
lines.push(`| ${row.join(" | ")} |`);
|
|
33
|
+
}
|
|
34
|
+
return { markdown: lines.join("\n") };
|
|
35
|
+
}
|
|
36
|
+
parseRows(text, delimiter) {
|
|
37
|
+
const rows = [];
|
|
38
|
+
let current = [];
|
|
39
|
+
let cell = "";
|
|
40
|
+
let inQuotes = false;
|
|
41
|
+
for (let i = 0; i < text.length; i++) {
|
|
42
|
+
const ch = text[i];
|
|
43
|
+
if (inQuotes) {
|
|
44
|
+
if (ch === '"' && text[i + 1] === '"') {
|
|
45
|
+
cell += '"';
|
|
46
|
+
i++;
|
|
47
|
+
}
|
|
48
|
+
else if (ch === '"') {
|
|
49
|
+
inQuotes = false;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
cell += ch;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (ch === '"') {
|
|
56
|
+
inQuotes = true;
|
|
57
|
+
}
|
|
58
|
+
else if (ch === delimiter) {
|
|
59
|
+
current.push(cell.trim());
|
|
60
|
+
cell = "";
|
|
61
|
+
}
|
|
62
|
+
else if (ch === "\n" || (ch === "\r" && text[i + 1] === "\n")) {
|
|
63
|
+
current.push(cell.trim());
|
|
64
|
+
if (current.some((c) => c.length > 0))
|
|
65
|
+
rows.push(current);
|
|
66
|
+
current = [];
|
|
67
|
+
cell = "";
|
|
68
|
+
if (ch === "\r")
|
|
69
|
+
i++;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
cell += ch;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Last row
|
|
76
|
+
if (cell || current.length > 0) {
|
|
77
|
+
current.push(cell.trim());
|
|
78
|
+
if (current.some((c) => c.length > 0))
|
|
79
|
+
rows.push(current);
|
|
80
|
+
}
|
|
81
|
+
return rows;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ConversionResult, Converter, StreamInfo } from "../types.js";
|
|
2
|
+
export declare class DocxConverter implements Converter {
|
|
3
|
+
name: string;
|
|
4
|
+
accepts(streamInfo: StreamInfo): boolean;
|
|
5
|
+
convert(input: Buffer, streamInfo: StreamInfo): Promise<ConversionResult>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import mammoth from "mammoth";
|
|
4
|
+
import { createTurndown, normalizeTablesHtml } from "../utils/turndown.js";
|
|
5
|
+
const EXTENSIONS = [".docx"];
|
|
6
|
+
const MIMETYPES = [
|
|
7
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
8
|
+
];
|
|
9
|
+
export class DocxConverter {
|
|
10
|
+
name = "docx";
|
|
11
|
+
accepts(streamInfo) {
|
|
12
|
+
if (streamInfo.extension && EXTENSIONS.includes(streamInfo.extension)) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
if (streamInfo.mimetype &&
|
|
16
|
+
MIMETYPES.some((m) => streamInfo.mimetype?.startsWith(m))) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
async convert(input, streamInfo) {
|
|
22
|
+
const imageDir = streamInfo.imageDir;
|
|
23
|
+
if (imageDir) {
|
|
24
|
+
mkdirSync(imageDir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
let imageCount = 0;
|
|
27
|
+
const convertImage = imageDir
|
|
28
|
+
? mammoth.images.imgElement((image) => {
|
|
29
|
+
imageCount++;
|
|
30
|
+
const ext = (image.contentType?.split("/")[1] || "png").replace("jpeg", "jpg");
|
|
31
|
+
const filename = `image_${imageCount}.${ext}`;
|
|
32
|
+
const filepath = join(imageDir, filename);
|
|
33
|
+
return image.read("base64").then((base64) => {
|
|
34
|
+
writeFileSync(filepath, Buffer.from(base64, "base64"));
|
|
35
|
+
return { src: filepath, alt: `image_${imageCount}` };
|
|
36
|
+
});
|
|
37
|
+
})
|
|
38
|
+
: mammoth.images.imgElement((image) => {
|
|
39
|
+
imageCount++;
|
|
40
|
+
const contentType = image.contentType || "image/png";
|
|
41
|
+
return image.read("base64").then((base64) => {
|
|
42
|
+
return {
|
|
43
|
+
src: `data:${contentType};base64,${base64.slice(0, 0)}`,
|
|
44
|
+
alt: `image_${imageCount}`,
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
const { value: html } = await mammoth.convertToHtml({ buffer: input }, { convertImage });
|
|
49
|
+
const turndown = createTurndown();
|
|
50
|
+
let markdown = turndown.turndown(normalizeTablesHtml(html));
|
|
51
|
+
// Replace data URI images with comment placeholders when no imageDir
|
|
52
|
+
if (!imageDir) {
|
|
53
|
+
markdown = markdown.replace(/!\[([^\]]*)\]\(data:[^)]*\)/g, "<!-- image: $1 -->");
|
|
54
|
+
}
|
|
55
|
+
return { markdown: markdown.trim() };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ConversionResult, Converter, StreamInfo } from "../types.js";
|
|
2
|
+
export declare class EpubConverter implements Converter {
|
|
3
|
+
name: string;
|
|
4
|
+
accepts(streamInfo: StreamInfo): boolean;
|
|
5
|
+
convert(input: Buffer, _streamInfo: StreamInfo): Promise<ConversionResult>;
|
|
6
|
+
private getText;
|
|
7
|
+
private getTextArray;
|
|
8
|
+
}
|