@evalops/maestro 0.10.22 → 0.10.24
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/README.md +4 -4
- package/dist/agent/agent.d.ts +2 -2
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +1 -1
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/keys.d.ts +2 -5
- package/dist/agent/keys.d.ts.map +1 -1
- package/dist/agent/keys.js +4 -5
- package/dist/agent/keys.js.map +1 -1
- package/dist/agent/modes.d.ts +2 -2
- package/dist/agent/modes.d.ts.map +1 -1
- package/dist/agent/modes.js +6 -7
- package/dist/agent/modes.js.map +1 -1
- package/dist/agent/providers/anthropic.d.ts.map +1 -1
- package/dist/agent/providers/anthropic.js +4 -4
- package/dist/agent/providers/anthropic.js.map +1 -1
- package/dist/agent/providers/google.js +1 -1
- package/dist/agent/swarm/executor.d.ts +2 -0
- package/dist/agent/swarm/executor.d.ts.map +1 -1
- package/dist/agent/swarm/executor.js +208 -35
- package/dist/agent/swarm/executor.js.map +1 -1
- package/dist/agent/swarm/types.d.ts +2 -0
- package/dist/agent/swarm/types.d.ts.map +1 -1
- package/dist/agent/swarm/types.js.map +1 -1
- package/dist/agent/tool-capability-types.d.ts +36 -0
- package/dist/agent/tool-capability-types.d.ts.map +1 -0
- package/dist/agent/tool-capability-types.js +2 -0
- package/dist/agent/tool-capability-types.js.map +1 -0
- package/dist/agent/transport/tool-execution-bridge.d.ts +13 -0
- package/dist/agent/transport/tool-execution-bridge.d.ts.map +1 -1
- package/dist/agent/transport/tool-execution-bridge.js +28 -15
- package/dist/agent/transport/tool-execution-bridge.js.map +1 -1
- package/dist/agent/transport/transport-utils.d.ts.map +1 -1
- package/dist/agent/transport/transport-utils.js +2 -3
- package/dist/agent/transport/transport-utils.js.map +1 -1
- package/dist/agent/transport.js +1 -1
- package/dist/agent/transport.js.map +1 -1
- package/dist/agent/type-guards.d.ts +1 -1
- package/dist/agent/type-guards.js +1 -1
- package/dist/agent/type-guards.js.map +1 -1
- package/dist/agent/types.d.ts +5 -3
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +2 -2
- package/dist/agent/types.js.map +1 -1
- package/dist/app-server/daemon-lifecycle-api.d.ts +31 -0
- package/dist/app-server/daemon-lifecycle-api.d.ts.map +1 -0
- package/dist/app-server/daemon-lifecycle-api.js +259 -0
- package/dist/app-server/daemon-lifecycle-api.js.map +1 -0
- package/dist/app-server/external-agent-import-api.d.ts +30 -0
- package/dist/app-server/external-agent-import-api.d.ts.map +1 -0
- package/dist/app-server/external-agent-import-api.js +553 -0
- package/dist/app-server/external-agent-import-api.js.map +1 -0
- package/dist/app-server/host-control-api.d.ts +30 -0
- package/dist/app-server/host-control-api.d.ts.map +1 -0
- package/dist/app-server/host-control-api.js +343 -0
- package/dist/app-server/host-control-api.js.map +1 -0
- package/dist/app-server/in-process-client.d.ts +2 -2
- package/dist/app-server/in-process-client.d.ts.map +1 -1
- package/dist/app-server/in-process-client.js.map +1 -1
- package/dist/app-server/network-governance-api.d.ts +26 -0
- package/dist/app-server/network-governance-api.d.ts.map +1 -0
- package/dist/app-server/network-governance-api.js +476 -0
- package/dist/app-server/network-governance-api.js.map +1 -0
- package/dist/app-server/plugin-bundle-api.d.ts +17 -0
- package/dist/app-server/plugin-bundle-api.d.ts.map +1 -0
- package/dist/app-server/plugin-bundle-api.js +219 -0
- package/dist/app-server/plugin-bundle-api.js.map +1 -0
- package/dist/app-server/policy-control-api.d.ts +14 -0
- package/dist/app-server/policy-control-api.d.ts.map +1 -0
- package/dist/app-server/policy-control-api.js +200 -0
- package/dist/app-server/policy-control-api.js.map +1 -0
- package/dist/app-server/protocol-modes-api.d.ts +22 -0
- package/dist/app-server/protocol-modes-api.d.ts.map +1 -0
- package/dist/app-server/protocol-modes-api.js +124 -0
- package/dist/app-server/protocol-modes-api.js.map +1 -0
- package/dist/app-server/sandbox-proof-api.d.ts +21 -0
- package/dist/app-server/sandbox-proof-api.d.ts.map +1 -0
- package/dist/app-server/sandbox-proof-api.js +127 -0
- package/dist/app-server/sandbox-proof-api.js.map +1 -0
- package/dist/app-server/session-api.d.ts +93 -3
- package/dist/app-server/session-api.d.ts.map +1 -1
- package/dist/app-server/session-api.js +706 -18
- package/dist/app-server/session-api.js.map +1 -1
- package/dist/audit/logger.d.ts +1 -1
- package/dist/bootstrap/auth-setup.d.ts.map +1 -1
- package/dist/bootstrap/auth-setup.js +17 -2
- package/dist/bootstrap/auth-setup.js.map +1 -1
- package/dist/bootstrap/model-resolution-setup.d.ts.map +1 -1
- package/dist/bootstrap/model-resolution-setup.js +19 -4
- package/dist/bootstrap/model-resolution-setup.js.map +1 -1
- package/dist/cli/args.d.ts +2 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/commands/a2a.d.ts.map +1 -1
- package/dist/cli/commands/a2a.js +226 -14
- package/dist/cli/commands/a2a.js.map +1 -1
- package/dist/cli/commands/anthropic.d.ts +1 -1
- package/dist/cli/commands/anthropic.d.ts.map +1 -1
- package/dist/cli/commands/anthropic.js +3 -68
- package/dist/cli/commands/anthropic.js.map +1 -1
- package/dist/cli/commands/modes.js +1 -1
- package/dist/cli/commands/modes.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +5 -7
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/rpc-mode.d.ts +1 -1
- package/dist/cli/rpc-mode.js +1 -1
- package/dist/cli/rpc-mode.js.map +1 -1
- package/dist/cli/session.js +1 -1
- package/dist/cli/session.js.map +1 -1
- package/dist/cli-tui/commands/command-catalog.d.ts.map +1 -1
- package/dist/cli-tui/commands/command-catalog.js +7 -12
- package/dist/cli-tui/commands/command-catalog.js.map +1 -1
- package/dist/cli-tui/commands/subcommands/auth-commands.d.ts +1 -1
- package/dist/cli-tui/commands/subcommands/auth-commands.d.ts.map +1 -1
- package/dist/cli-tui/commands/subcommands/auth-commands.js +4 -12
- package/dist/cli-tui/commands/subcommands/auth-commands.js.map +1 -1
- package/dist/cli-tui/custom-editor.d.ts +1 -1
- package/dist/cli-tui/custom-editor.js +2 -2
- package/dist/cli-tui/custom-editor.js.map +1 -1
- package/dist/cli-tui/oauth/oauth-flow-controller.d.ts.map +1 -1
- package/dist/cli-tui/oauth/oauth-flow-controller.js +19 -23
- package/dist/cli-tui/oauth/oauth-flow-controller.js.map +1 -1
- package/dist/cli-tui/selectors/model-selector.d.ts.map +1 -1
- package/dist/cli-tui/selectors/model-selector.js +0 -1
- package/dist/cli-tui/selectors/model-selector.js.map +1 -1
- package/dist/cli-tui/selectors/oauth-selector-view.d.ts +2 -2
- package/dist/cli-tui/selectors/oauth-selector-view.d.ts.map +1 -1
- package/dist/cli-tui/selectors/oauth-selector-view.js.map +1 -1
- package/dist/cli-tui/selectors/oauth-selector.d.ts +2 -2
- package/dist/cli-tui/selectors/oauth-selector.d.ts.map +1 -1
- package/dist/cli-tui/selectors/oauth-selector.js +3 -4
- package/dist/cli-tui/selectors/oauth-selector.js.map +1 -1
- package/dist/cli-tui/tui-renderer/mcp-events-setup.js +1 -1
- package/dist/cli-tui/tui-renderer/mcp-events-setup.js.map +1 -1
- package/dist/cli-tui/tui-renderer.js +2 -2
- package/dist/cli-tui/tui-renderer.js.map +1 -1
- package/dist/cli-tui/utils/footer-utils.d.ts +1 -1
- package/dist/cli-tui/utils/footer-utils.js +1 -1
- package/dist/cli-tui/utils/footer-utils.js.map +1 -1
- package/dist/cli.js +15171 -14298
- package/dist/commands/prompts.d.ts +1 -1
- package/dist/commands/prompts.js +1 -1
- package/dist/commands/prompts.js.map +1 -1
- package/dist/config/constants.d.ts +2 -2
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +2 -2
- package/dist/config/constants.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/toml-config.js +3 -3
- package/dist/config/toml-config.js.map +1 -1
- package/dist/db/client.d.ts +2 -2
- package/dist/db/client.js +2 -2
- package/dist/db/client.js.map +1 -1
- package/dist/db/migrate.d.ts +1 -1
- package/dist/db/migrate.js +1 -1
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/schema.d.ts +2 -2
- package/dist/db/schema.js +1 -1
- package/dist/db/schema.js.map +1 -1
- package/dist/errors/index.d.ts +2 -2
- package/dist/errors/index.js +2 -2
- package/dist/errors/index.js.map +1 -1
- package/dist/main.d.ts +4 -5
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +17 -14
- package/dist/main.js.map +1 -1
- package/dist/mcp/config.d.ts +15 -2
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/config.js +50 -26
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/fathom-cua.d.ts.map +1 -1
- package/dist/mcp/fathom-cua.js +10 -0
- package/dist/mcp/fathom-cua.js.map +1 -1
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/manager.js +32 -1
- package/dist/mcp/manager.js.map +1 -1
- package/dist/mcp/tool-bridge.d.ts.map +1 -1
- package/dist/mcp/tool-bridge.js +12 -3
- package/dist/mcp/tool-bridge.js.map +1 -1
- package/dist/mcp/tool-capabilities.d.ts +5 -0
- package/dist/mcp/tool-capabilities.d.ts.map +1 -0
- package/dist/mcp/tool-capabilities.js +271 -0
- package/dist/mcp/tool-capabilities.js.map +1 -0
- package/dist/mcp/types.d.ts +6 -1
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/mcp/types.js.map +1 -1
- package/dist/models/config-loader.d.ts +1 -1
- package/dist/models/factory-integration.d.ts +1 -1
- package/dist/models/factory-integration.js +1 -1
- package/dist/models/factory-integration.js.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/artifacts.d.ts +58 -0
- package/dist/node_modules/@evalops/contracts/dist/artifacts.d.ts.map +1 -0
- package/dist/node_modules/@evalops/contracts/dist/artifacts.js +191 -0
- package/dist/node_modules/@evalops/contracts/dist/artifacts.js.map +1 -0
- package/dist/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.d.ts +10 -10
- package/dist/node_modules/@evalops/contracts/dist/index.d.ts +4 -3
- package/dist/node_modules/@evalops/contracts/dist/index.d.ts.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/index.js +3 -2
- package/dist/node_modules/@evalops/contracts/dist/index.js.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/maestro-app-server.d.ts +1182 -14
- package/dist/node_modules/@evalops/contracts/dist/maestro-app-server.d.ts.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/maestro-app-server.js +450 -1
- package/dist/node_modules/@evalops/contracts/dist/maestro-app-server.js.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/runtime-app-server.d.ts +1 -1
- package/dist/node_modules/@evalops/contracts/dist/runtime-server-request.d.ts +3 -3
- package/dist/node_modules/@evalops/contracts/package.json +1 -1
- package/dist/node_modules/@evalops/tui/package.json +1 -1
- package/dist/oauth/connectors.d.ts +2 -2
- package/dist/oauth/connectors.d.ts.map +1 -1
- package/dist/oauth/connectors.js +3 -5
- package/dist/oauth/connectors.js.map +1 -1
- package/dist/oauth/github-copilot.d.ts +1 -1
- package/dist/oauth/github-copilot.js +1 -1
- package/dist/oauth/github-copilot.js.map +1 -1
- package/dist/oauth/index.d.ts +10 -8
- package/dist/oauth/index.d.ts.map +1 -1
- package/dist/oauth/index.js +54 -31
- package/dist/oauth/index.js.map +1 -1
- package/dist/oauth/openai.d.ts +1 -1
- package/dist/oauth/openai.js +2 -2
- package/dist/oauth/openai.js.map +1 -1
- package/dist/platform/a2a-completion-audit.d.ts +41 -0
- package/dist/platform/a2a-completion-audit.d.ts.map +1 -0
- package/dist/platform/a2a-completion-audit.js +177 -0
- package/dist/platform/a2a-completion-audit.js.map +1 -0
- package/dist/platform/a2a-task-ledger.d.ts.map +1 -1
- package/dist/platform/a2a-task-ledger.js +17 -0
- package/dist/platform/a2a-task-ledger.js.map +1 -1
- package/dist/platform/a2a-telemetry-inspect.d.ts +58 -0
- package/dist/platform/a2a-telemetry-inspect.d.ts.map +1 -0
- package/dist/platform/a2a-telemetry-inspect.js +224 -0
- package/dist/platform/a2a-telemetry-inspect.js.map +1 -0
- package/dist/platform/agent-registry-client.d.ts +8 -0
- package/dist/platform/agent-registry-client.d.ts.map +1 -1
- package/dist/platform/agent-registry-client.js +9 -1
- package/dist/platform/agent-registry-client.js.map +1 -1
- package/dist/providers/api-keys.d.ts +2 -2
- package/dist/providers/api-keys.js +2 -2
- package/dist/providers/api-keys.js.map +1 -1
- package/dist/providers/auth.d.ts +3 -6
- package/dist/providers/auth.d.ts.map +1 -1
- package/dist/providers/auth.js +1 -40
- package/dist/providers/auth.js.map +1 -1
- package/dist/rpc/index.d.ts +2 -2
- package/dist/rpc/index.js +2 -2
- package/dist/rpc/index.js.map +1 -1
- package/dist/rpc/rpc-types.d.ts +1 -1
- package/dist/rpc/rpc-types.js +1 -1
- package/dist/rpc/rpc-types.js.map +1 -1
- package/dist/safety/nested-agent-guard.js +1 -1
- package/dist/safety/nested-agent-guard.js.map +1 -1
- package/dist/safety/policy.d.ts +2 -2
- package/dist/safety/policy.js +2 -2
- package/dist/safety/policy.js.map +1 -1
- package/dist/safety/validators/network-policy-validator.d.ts +8 -0
- package/dist/safety/validators/network-policy-validator.d.ts.map +1 -1
- package/dist/safety/validators/network-policy-validator.js +29 -4
- package/dist/safety/validators/network-policy-validator.js.map +1 -1
- package/dist/sandbox/local-sandbox.d.ts +1 -1
- package/dist/sandbox/local-sandbox.js +1 -1
- package/dist/sandbox/local-sandbox.js.map +1 -1
- package/dist/server/app-context.d.ts +2 -0
- package/dist/server/app-context.d.ts.map +1 -1
- package/dist/server/app-context.js.map +1 -1
- package/dist/server/handlers/attachments.d.ts.map +1 -1
- package/dist/server/handlers/attachments.js +1 -0
- package/dist/server/handlers/attachments.js.map +1 -1
- package/dist/server/handlers/models.d.ts.map +1 -1
- package/dist/server/handlers/models.js +3 -1
- package/dist/server/handlers/models.js.map +1 -1
- package/dist/server/handlers/session-artifacts.d.ts.map +1 -1
- package/dist/server/handlers/session-artifacts.js +13 -74
- package/dist/server/handlers/session-artifacts.js.map +1 -1
- package/dist/server/handlers/session-attachments.d.ts.map +1 -1
- package/dist/server/handlers/session-attachments.js +2 -0
- package/dist/server/handlers/session-attachments.js.map +1 -1
- package/dist/server/handlers/sessions.js +1 -1
- package/dist/server/handlers/sessions.js.map +1 -1
- package/dist/server/handlers/status.d.ts +2 -0
- package/dist/server/handlers/status.d.ts.map +1 -1
- package/dist/server/handlers/status.js +3 -2
- package/dist/server/handlers/status.js.map +1 -1
- package/dist/server/headless-runtime-service.d.ts.map +1 -1
- package/dist/server/headless-runtime-service.js +32 -3
- package/dist/server/headless-runtime-service.js.map +1 -1
- package/dist/server/hosted-session-manager.d.ts +2 -0
- package/dist/server/hosted-session-manager.d.ts.map +1 -1
- package/dist/server/hosted-session-manager.js +9 -0
- package/dist/server/hosted-session-manager.js.map +1 -1
- package/dist/server/model-selection.d.ts.map +1 -1
- package/dist/server/model-selection.js +9 -1
- package/dist/server/model-selection.js.map +1 -1
- package/dist/server/rate-limiter.d.ts +1 -1
- package/dist/server/rate-limiter.js +1 -1
- package/dist/server/rate-limiter.js.map +1 -1
- package/dist/server/router.d.ts +2 -2
- package/dist/server/router.js.map +1 -1
- package/dist/server/session-serialization.d.ts +9 -9
- package/dist/server/session-serialization.js +15 -15
- package/dist/server/session-serialization.js.map +1 -1
- package/dist/session/manager.d.ts +5 -0
- package/dist/session/manager.d.ts.map +1 -1
- package/dist/session/manager.js +56 -8
- package/dist/session/manager.js.map +1 -1
- package/dist/session/session-catalog.d.ts +2 -0
- package/dist/session/session-catalog.d.ts.map +1 -1
- package/dist/session/session-catalog.js +6 -0
- package/dist/session/session-catalog.js.map +1 -1
- package/dist/session/session-context.d.ts +2 -0
- package/dist/session/session-context.d.ts.map +1 -1
- package/dist/session/session-context.js +15 -0
- package/dist/session/session-context.js.map +1 -1
- package/dist/session/types.d.ts +7 -0
- package/dist/session/types.d.ts.map +1 -1
- package/dist/session/types.js.map +1 -1
- package/dist/session/wire-format.generated.d.ts +1 -0
- package/dist/session/wire-format.generated.d.ts.map +1 -1
- package/dist/session/wire-format.generated.js +1 -0
- package/dist/session/wire-format.generated.js.map +1 -1
- package/dist/shared-memory/contract.d.ts +4 -4
- package/dist/shared-memory/contract.js +2 -2
- package/dist/shared-memory/contract.js.map +1 -1
- package/dist/telemetry/index.d.ts +2 -2
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/index.js +2 -2
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/maestro-event-bus.d.ts +57 -0
- package/dist/telemetry/maestro-event-bus.d.ts.map +1 -1
- package/dist/telemetry/maestro-event-bus.js +59 -1
- package/dist/telemetry/maestro-event-bus.js.map +1 -1
- package/dist/telemetry/maestro-event-catalog.d.ts +17 -1
- package/dist/telemetry/maestro-event-catalog.d.ts.map +1 -1
- package/dist/telemetry/maestro-event-catalog.js +24 -0
- package/dist/telemetry/maestro-event-catalog.js.map +1 -1
- package/dist/telemetry/mcp-beacon.d.ts +2 -0
- package/dist/telemetry/mcp-beacon.d.ts.map +1 -1
- package/dist/telemetry/mcp-beacon.js +15 -0
- package/dist/telemetry/mcp-beacon.js.map +1 -1
- package/dist/telemetry/metrics.d.ts +62 -0
- package/dist/telemetry/metrics.d.ts.map +1 -1
- package/dist/telemetry/metrics.js +84 -0
- package/dist/telemetry/metrics.js.map +1 -1
- package/dist/telemetry.d.ts +44 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +84 -2
- package/dist/telemetry.js.map +1 -1
- package/dist/theme/theme-loader.js +2 -2
- package/dist/theme/theme-loader.js.map +1 -1
- package/dist/theme/theme-schema.json +2 -2
- package/dist/theme/theme.d.ts +1 -1
- package/dist/theme/theme.js.map +1 -1
- package/dist/tools/background/task-types.d.ts +1 -1
- package/dist/tools/extract-document.d.ts +1 -0
- package/dist/tools/extract-document.d.ts.map +1 -1
- package/dist/tools/extract-document.js +2 -1
- package/dist/tools/extract-document.js.map +1 -1
- package/dist/tools/index.d.ts +55 -55
- package/dist/tools/index.js +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/tool-dsl.d.ts +1 -1
- package/dist/tools/tool-dsl.js +1 -1
- package/dist/tools/tool-dsl.js.map +1 -1
- package/dist/utils/document-extractor.d.ts +1 -0
- package/dist/utils/document-extractor.d.ts.map +1 -1
- package/dist/utils/document-extractor.js +320 -40
- package/dist/utils/document-extractor.js.map +1 -1
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.js +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/version.json +2 -2
- package/dist/web-server.d.ts +1 -1
- package/dist/web-server.d.ts.map +1 -1
- package/dist/web-server.js +12 -8
- package/dist/web-server.js.map +1 -1
- package/package.json +4 -2
- package/dist/oauth/anthropic.d.ts +0 -17
- package/dist/oauth/anthropic.d.ts.map +0 -1
- package/dist/oauth/anthropic.js +0 -81
- package/dist/oauth/anthropic.js.map +0 -1
- package/dist/providers/anthropic-auth.d.ts +0 -75
- package/dist/providers/anthropic-auth.d.ts.map +0 -1
- package/dist/providers/anthropic-auth.js +0 -221
- package/dist/providers/anthropic-auth.js.map +0 -1
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { extname, join } from "node:path";
|
|
1
5
|
import ExcelJS from "exceljs";
|
|
2
6
|
import JSZip from "jszip";
|
|
3
7
|
import mammoth from "mammoth";
|
|
4
8
|
import { PDFParse } from "pdf-parse";
|
|
5
9
|
const DEFAULT_MAX_CHARS = 200_000;
|
|
6
10
|
const MAX_INPUT_BYTES = 50 * 1024 * 1024;
|
|
11
|
+
const MARKITDOWN_TIMEOUT_MS = 20_000;
|
|
12
|
+
const MARKITDOWN_TIMEOUT_KILL_GRACE_MS = 500;
|
|
13
|
+
const MARKITDOWN_TIMEOUT_CLOSE_GRACE_MS = 1_000;
|
|
14
|
+
const NODE_TIMER_MAX_MS = 2_147_483_647;
|
|
7
15
|
const XLSX_MIME = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
8
16
|
function clampText(text, maxChars) {
|
|
9
17
|
if (text.length <= maxChars)
|
|
@@ -47,6 +55,249 @@ function detectFormat(fileName, mimeType) {
|
|
|
47
55
|
return "text";
|
|
48
56
|
return "unknown";
|
|
49
57
|
}
|
|
58
|
+
function splitCommandArgs(value) {
|
|
59
|
+
const input = value?.trim() ?? "";
|
|
60
|
+
if (!input)
|
|
61
|
+
return [];
|
|
62
|
+
const args = [];
|
|
63
|
+
let current = "";
|
|
64
|
+
let quote = null;
|
|
65
|
+
let tokenStarted = false;
|
|
66
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
67
|
+
const char = input.charAt(index);
|
|
68
|
+
if (quote === "'") {
|
|
69
|
+
if (char === "'") {
|
|
70
|
+
quote = null;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
current += char;
|
|
74
|
+
}
|
|
75
|
+
tokenStarted = true;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (quote === '"') {
|
|
79
|
+
if (char === '"') {
|
|
80
|
+
quote = null;
|
|
81
|
+
tokenStarted = true;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (char === "\\") {
|
|
85
|
+
const next = input[index + 1];
|
|
86
|
+
if (next && ['"', "\\", "$", "`", "\n"].includes(next)) {
|
|
87
|
+
current += next;
|
|
88
|
+
index += 1;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
current += char;
|
|
92
|
+
}
|
|
93
|
+
tokenStarted = true;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
current += char;
|
|
97
|
+
tokenStarted = true;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (char === "\\") {
|
|
101
|
+
const next = input[index + 1];
|
|
102
|
+
if (next && (/\s/u.test(next) || ["'", '"', "\\"].includes(next))) {
|
|
103
|
+
current += next;
|
|
104
|
+
index += 1;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
current += char;
|
|
108
|
+
}
|
|
109
|
+
tokenStarted = true;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (char === "'" || char === '"') {
|
|
113
|
+
quote = char;
|
|
114
|
+
tokenStarted = true;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (/\s/u.test(char)) {
|
|
118
|
+
if (tokenStarted) {
|
|
119
|
+
args.push(current);
|
|
120
|
+
current = "";
|
|
121
|
+
tokenStarted = false;
|
|
122
|
+
}
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
current += char;
|
|
126
|
+
tokenStarted = true;
|
|
127
|
+
}
|
|
128
|
+
if (quote) {
|
|
129
|
+
throw new Error("Unterminated quote in MAESTRO_MARKITDOWN_ARGS");
|
|
130
|
+
}
|
|
131
|
+
if (tokenStarted) {
|
|
132
|
+
args.push(current);
|
|
133
|
+
}
|
|
134
|
+
return args;
|
|
135
|
+
}
|
|
136
|
+
function isMarkitdownDisabled() {
|
|
137
|
+
return /^(0|false|off|no)$/i.test(process.env.MAESTRO_MARKITDOWN ?? "");
|
|
138
|
+
}
|
|
139
|
+
function markitdownCandidates() {
|
|
140
|
+
const configured = process.env.MAESTRO_MARKITDOWN_CMD?.trim();
|
|
141
|
+
if (configured) {
|
|
142
|
+
return [
|
|
143
|
+
{
|
|
144
|
+
command: configured,
|
|
145
|
+
argsPrefix: splitCommandArgs(process.env.MAESTRO_MARKITDOWN_ARGS),
|
|
146
|
+
},
|
|
147
|
+
];
|
|
148
|
+
}
|
|
149
|
+
return [
|
|
150
|
+
{ command: "markitdown", argsPrefix: [] },
|
|
151
|
+
{ command: "uvx", argsPrefix: ["markitdown"] },
|
|
152
|
+
];
|
|
153
|
+
}
|
|
154
|
+
function shouldTryMarkitdown(format, fileName, mimeType) {
|
|
155
|
+
if (isMarkitdownDisabled())
|
|
156
|
+
return false;
|
|
157
|
+
if (/^(1|true|on|yes)$/i.test(process.env.MAESTRO_MARKITDOWN_PREFER ?? "")) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
const lowerName = fileName.toLowerCase();
|
|
161
|
+
const type = (mimeType ?? "").toLowerCase();
|
|
162
|
+
if (format === "unknown")
|
|
163
|
+
return true;
|
|
164
|
+
if (lowerName.endsWith(".html") || lowerName.endsWith(".htm"))
|
|
165
|
+
return true;
|
|
166
|
+
if (type.includes("text/html"))
|
|
167
|
+
return true;
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
function readPositiveIntegerEnv(name, fallback) {
|
|
171
|
+
const value = process.env[name]?.trim();
|
|
172
|
+
if (!value)
|
|
173
|
+
return fallback;
|
|
174
|
+
const parsed = Number(value);
|
|
175
|
+
if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed <= 0) {
|
|
176
|
+
return fallback;
|
|
177
|
+
}
|
|
178
|
+
return Math.min(parsed, NODE_TIMER_MAX_MS);
|
|
179
|
+
}
|
|
180
|
+
function signalMarkitdownProcessTree(child, signal) {
|
|
181
|
+
if (process.platform !== "win32" && child.pid) {
|
|
182
|
+
try {
|
|
183
|
+
process.kill(-child.pid, signal);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
if (error.code === "ESRCH") {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
child.kill(signal);
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
// The process may have exited between timeout handling and signal delivery.
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function runMarkitdownCandidate(candidate, args) {
|
|
200
|
+
return new Promise((resolve, reject) => {
|
|
201
|
+
const child = spawn(candidate.command, [...candidate.argsPrefix, ...args], {
|
|
202
|
+
detached: process.platform !== "win32",
|
|
203
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
204
|
+
});
|
|
205
|
+
let stdout = "";
|
|
206
|
+
let stderr = "";
|
|
207
|
+
let timedOut = false;
|
|
208
|
+
let settled = false;
|
|
209
|
+
let killTimer;
|
|
210
|
+
let closeGraceTimer;
|
|
211
|
+
const timer = setTimeout(() => {
|
|
212
|
+
timedOut = true;
|
|
213
|
+
signalMarkitdownProcessTree(child, "SIGTERM");
|
|
214
|
+
killTimer = setTimeout(() => {
|
|
215
|
+
signalMarkitdownProcessTree(child, "SIGKILL");
|
|
216
|
+
closeGraceTimer = setTimeout(() => {
|
|
217
|
+
child.stdout.destroy();
|
|
218
|
+
child.stderr.destroy();
|
|
219
|
+
child.unref();
|
|
220
|
+
finish(new Error("MarkItDown conversion timed out"));
|
|
221
|
+
}, readPositiveIntegerEnv("MAESTRO_MARKITDOWN_CLOSE_GRACE_MS", MARKITDOWN_TIMEOUT_CLOSE_GRACE_MS));
|
|
222
|
+
}, readPositiveIntegerEnv("MAESTRO_MARKITDOWN_KILL_GRACE_MS", MARKITDOWN_TIMEOUT_KILL_GRACE_MS));
|
|
223
|
+
}, readPositiveIntegerEnv("MAESTRO_MARKITDOWN_TIMEOUT_MS", MARKITDOWN_TIMEOUT_MS));
|
|
224
|
+
function finish(error, output) {
|
|
225
|
+
if (settled)
|
|
226
|
+
return;
|
|
227
|
+
settled = true;
|
|
228
|
+
clearTimeout(timer);
|
|
229
|
+
if (killTimer)
|
|
230
|
+
clearTimeout(killTimer);
|
|
231
|
+
if (closeGraceTimer)
|
|
232
|
+
clearTimeout(closeGraceTimer);
|
|
233
|
+
if (error) {
|
|
234
|
+
reject(error);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
resolve(output ?? "");
|
|
238
|
+
}
|
|
239
|
+
child.stdout.setEncoding("utf8");
|
|
240
|
+
child.stderr.setEncoding("utf8");
|
|
241
|
+
child.stdout.on("data", (chunk) => {
|
|
242
|
+
stdout += chunk;
|
|
243
|
+
});
|
|
244
|
+
child.stderr.on("data", (chunk) => {
|
|
245
|
+
stderr += chunk;
|
|
246
|
+
});
|
|
247
|
+
child.on("error", (error) => {
|
|
248
|
+
if (timedOut) {
|
|
249
|
+
finish(new Error("MarkItDown conversion timed out"));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
finish(error);
|
|
253
|
+
});
|
|
254
|
+
child.on("close", (code) => {
|
|
255
|
+
if (timedOut) {
|
|
256
|
+
finish(new Error("MarkItDown conversion timed out"));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (code === 0) {
|
|
260
|
+
finish(null, stdout);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
finish(new Error(`MarkItDown exited with ${code}${stderr ? `: ${stderr.slice(0, 500)}` : ""}`));
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
async function extractWithMarkitdown(input) {
|
|
268
|
+
const tempDir = await mkdtemp(join(tmpdir(), "maestro-markitdown-"));
|
|
269
|
+
const extension = extname(input.fileName) || ".bin";
|
|
270
|
+
const tempPath = join(tempDir, `input${extension}`);
|
|
271
|
+
try {
|
|
272
|
+
await writeFile(tempPath, input.buffer);
|
|
273
|
+
const args = [tempPath];
|
|
274
|
+
if (input.mimeType) {
|
|
275
|
+
args.push("--mime-type", input.mimeType);
|
|
276
|
+
}
|
|
277
|
+
let lastError;
|
|
278
|
+
for (const candidate of markitdownCandidates()) {
|
|
279
|
+
try {
|
|
280
|
+
const output = await runMarkitdownCandidate(candidate, args);
|
|
281
|
+
const text = output.trim();
|
|
282
|
+
if (text)
|
|
283
|
+
return text;
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
lastError = error;
|
|
287
|
+
if (error.code === "ENOENT")
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
if (process.env.MAESTRO_MARKITDOWN_CMD) {
|
|
292
|
+
const message = lastError instanceof Error ? lastError.message : String(lastError);
|
|
293
|
+
throw new Error(`MarkItDown extraction failed: ${message}`);
|
|
294
|
+
}
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
finally {
|
|
298
|
+
await rm(tempDir, { force: true, recursive: true });
|
|
299
|
+
}
|
|
300
|
+
}
|
|
50
301
|
function worksheetToRows(worksheet) {
|
|
51
302
|
const rows = [];
|
|
52
303
|
worksheet.eachRow({ includeEmpty: false }, (row) => {
|
|
@@ -104,59 +355,88 @@ export async function extractDocumentText(input) {
|
|
|
104
355
|
throw new Error(`Document is too large (${(buffer.byteLength / 1024 / 1024).toFixed(1)}MB). Maximum supported size is 50MB.`);
|
|
105
356
|
}
|
|
106
357
|
const format = detectFormat(fileName, input.mimeType);
|
|
358
|
+
const markitdownFirst = /^(1|true|on|yes)$/i.test(process.env.MAESTRO_MARKITDOWN_PREFER ?? "") &&
|
|
359
|
+
!isMarkitdownDisabled();
|
|
107
360
|
let extractedText = "";
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
361
|
+
let extractor = "native";
|
|
362
|
+
if (markitdownFirst) {
|
|
363
|
+
const markitdownText = await extractWithMarkitdown({
|
|
364
|
+
buffer,
|
|
365
|
+
fileName,
|
|
366
|
+
mimeType: input.mimeType,
|
|
367
|
+
});
|
|
368
|
+
if (markitdownText) {
|
|
369
|
+
extractedText = markitdownText;
|
|
370
|
+
extractor = "markitdown";
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (!extractedText) {
|
|
374
|
+
switch (format) {
|
|
375
|
+
case "pdf": {
|
|
376
|
+
const parser = new PDFParse({ data: buffer });
|
|
116
377
|
try {
|
|
117
|
-
await parser.
|
|
378
|
+
const result = await parser.getText();
|
|
379
|
+
extractedText = result.text || "";
|
|
118
380
|
}
|
|
119
|
-
|
|
120
|
-
|
|
381
|
+
finally {
|
|
382
|
+
try {
|
|
383
|
+
await parser.destroy();
|
|
384
|
+
}
|
|
385
|
+
catch {
|
|
386
|
+
// ignore
|
|
387
|
+
}
|
|
121
388
|
}
|
|
389
|
+
break;
|
|
122
390
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
391
|
+
case "docx": {
|
|
392
|
+
const result = await mammoth.extractRawText({ buffer });
|
|
393
|
+
extractedText = result.value || "";
|
|
394
|
+
break;
|
|
395
|
+
}
|
|
396
|
+
case "xlsx": {
|
|
397
|
+
const workbook = new ExcelJS.Workbook();
|
|
398
|
+
await workbook.xlsx.load(buffer);
|
|
399
|
+
const parts = [];
|
|
400
|
+
for (const worksheet of workbook.worksheets) {
|
|
401
|
+
const rows = worksheetToRows(worksheet);
|
|
402
|
+
if (rows.length === 0)
|
|
403
|
+
continue;
|
|
404
|
+
parts.push(`# Sheet: ${worksheet.name}\n${rows.map((row) => row.join("\t")).join("\n")}`);
|
|
405
|
+
}
|
|
406
|
+
extractedText = parts.join("\n\n");
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
case "pptx": {
|
|
410
|
+
extractedText = await extractPptxText(buffer);
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
case "text": {
|
|
414
|
+
extractedText = buffer.toString("utf8");
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
default: {
|
|
418
|
+
extractedText = "";
|
|
419
|
+
break;
|
|
139
420
|
}
|
|
140
|
-
extractedText = parts.join("\n\n");
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
case "pptx": {
|
|
144
|
-
extractedText = await extractPptxText(buffer);
|
|
145
|
-
break;
|
|
146
|
-
}
|
|
147
|
-
case "text": {
|
|
148
|
-
extractedText = buffer.toString("utf8");
|
|
149
|
-
break;
|
|
150
421
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
422
|
+
}
|
|
423
|
+
if (extractor !== "markitdown" &&
|
|
424
|
+
shouldTryMarkitdown(format, fileName, input.mimeType)) {
|
|
425
|
+
const markitdownText = await extractWithMarkitdown({
|
|
426
|
+
buffer,
|
|
427
|
+
fileName,
|
|
428
|
+
mimeType: input.mimeType,
|
|
429
|
+
});
|
|
430
|
+
if (markitdownText) {
|
|
431
|
+
extractedText = markitdownText;
|
|
432
|
+
extractor = "markitdown";
|
|
154
433
|
}
|
|
155
434
|
}
|
|
156
435
|
const { text, truncated } = clampText(extractedText, maxChars);
|
|
157
436
|
return {
|
|
158
437
|
extractedText: text,
|
|
159
438
|
format,
|
|
439
|
+
extractor,
|
|
160
440
|
truncated,
|
|
161
441
|
sizeBytes: buffer.byteLength,
|
|
162
442
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-extractor.js","sourceRoot":"","sources":["../../src/utils/document-extractor.ts"],"names":[],"mappings":"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","sourcesContent":["import ExcelJS from \"exceljs\";\nimport JSZip from \"jszip\";\nimport mammoth from \"mammoth\";\nimport { PDFParse } from \"pdf-parse\";\n\nexport type ExtractedDocumentFormat =\n\t| \"pdf\"\n\t| \"docx\"\n\t| \"xlsx\"\n\t| \"pptx\"\n\t| \"text\"\n\t| \"unknown\";\n\nexport interface ExtractDocumentInput {\n\tbuffer: Buffer;\n\tfileName: string;\n\tmimeType?: string;\n\tmaxChars?: number;\n}\n\nexport interface ExtractDocumentOutput {\n\textractedText: string;\n\tformat: ExtractedDocumentFormat;\n\ttruncated: boolean;\n\tsizeBytes: number;\n}\n\ntype ExcelWorkbookLoadInput = Parameters<ExcelJS.Workbook[\"xlsx\"][\"load\"]>[0];\n\nconst DEFAULT_MAX_CHARS = 200_000;\nconst MAX_INPUT_BYTES = 50 * 1024 * 1024;\nconst XLSX_MIME =\n\t\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\";\n\nfunction clampText(\n\ttext: string,\n\tmaxChars: number,\n): { text: string; truncated: boolean } {\n\tif (text.length <= maxChars) return { text, truncated: false };\n\treturn { text: text.slice(0, maxChars), truncated: true };\n}\n\nfunction detectFormat(\n\tfileName: string,\n\tmimeType?: string,\n): ExtractedDocumentFormat {\n\tconst lowerName = fileName.toLowerCase();\n\tconst type = (mimeType || \"\").toLowerCase();\n\n\tif (type === \"application/pdf\" || lowerName.endsWith(\".pdf\")) return \"pdf\";\n\tif (\n\t\ttype ===\n\t\t\t\"application/vnd.openxmlformats-officedocument.wordprocessingml.document\" ||\n\t\tlowerName.endsWith(\".docx\")\n\t)\n\t\treturn \"docx\";\n\tif (type === XLSX_MIME || lowerName.endsWith(\".xlsx\")) return \"xlsx\";\n\tif (\n\t\ttype ===\n\t\t\t\"application/vnd.openxmlformats-officedocument.presentationml.presentation\" ||\n\t\tlowerName.endsWith(\".pptx\")\n\t)\n\t\treturn \"pptx\";\n\tif (type.startsWith(\"text/\")) return \"text\";\n\n\tconst textExtensions = [\n\t\t\".txt\",\n\t\t\".md\",\n\t\t\".markdown\",\n\t\t\".json\",\n\t\t\".yaml\",\n\t\t\".yml\",\n\t\t\".csv\",\n\t\t\".ts\",\n\t\t\".tsx\",\n\t\t\".js\",\n\t\t\".jsx\",\n\t\t\".html\",\n\t\t\".css\",\n\t\t\".xml\",\n\t];\n\tif (textExtensions.some((ext) => lowerName.endsWith(ext))) return \"text\";\n\n\treturn \"unknown\";\n}\n\nfunction worksheetToRows(worksheet: ExcelJS.Worksheet): string[][] {\n\tconst rows: string[][] = [];\n\tworksheet.eachRow({ includeEmpty: false }, (row) => {\n\t\tconst cells: string[] = [];\n\t\tfor (let column = 1; column <= row.cellCount; column++) {\n\t\t\tcells.push((row.getCell(column).text || \"\").trim());\n\t\t}\n\t\twhile (cells.length > 0 && cells[cells.length - 1] === \"\") {\n\t\t\tcells.pop();\n\t\t}\n\t\tif (cells.some((value) => value !== \"\")) {\n\t\t\trows.push(cells);\n\t\t}\n\t});\n\treturn rows;\n}\n\nasync function extractPptxText(buffer: Buffer): Promise<string> {\n\tconst zip = await JSZip.loadAsync(buffer);\n\n\tconst slidePaths = Object.keys(zip.files)\n\t\t.filter((p) => /^ppt\\/slides\\/slide\\d+\\.xml$/i.test(p))\n\t\t.sort((a, b) => {\n\t\t\tconst an = Number.parseInt(a.match(/slide(\\d+)\\.xml/i)?.[1] || \"0\", 10);\n\t\t\tconst bn = Number.parseInt(b.match(/slide(\\d+)\\.xml/i)?.[1] || \"0\", 10);\n\t\t\treturn an - bn;\n\t\t});\n\n\tif (slidePaths.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst parts: string[] = [];\n\tfor (const slidePath of slidePaths) {\n\t\tconst slideNumber = slidePath.match(/slide(\\d+)\\.xml/i)?.[1] || \"?\";\n\t\tconst xml = await zip.file(slidePath)?.async(\"string\");\n\t\tif (!xml) continue;\n\n\t\tconst texts = Array.from(xml.matchAll(/<a:t>(.*?)<\\/a:t>/g))\n\t\t\t.map((m) => m[1] || \"\")\n\t\t\t.map((s) =>\n\t\t\t\ts\n\t\t\t\t\t.replaceAll(\"<\", \"<\")\n\t\t\t\t\t.replaceAll(\">\", \">\")\n\t\t\t\t\t.replaceAll(\"&\", \"&\")\n\t\t\t\t\t.replaceAll(\""\", '\"')\n\t\t\t\t\t.replaceAll(\"'\", \"'\"),\n\t\t\t)\n\t\t\t.map((s) => s.trim())\n\t\t\t.filter(Boolean);\n\n\t\tif (texts.length === 0) continue;\n\t\tparts.push(`# Slide ${slideNumber}\\n${texts.join(\" \")}`);\n\t}\n\n\treturn parts.join(\"\\n\\n\");\n}\n\nexport async function extractDocumentText(\n\tinput: ExtractDocumentInput,\n): Promise<ExtractDocumentOutput> {\n\tconst { buffer, fileName } = input;\n\tconst maxChars = Math.max(1, input.maxChars ?? DEFAULT_MAX_CHARS);\n\n\tif (buffer.byteLength > MAX_INPUT_BYTES) {\n\t\tthrow new Error(\n\t\t\t`Document is too large (${(buffer.byteLength / 1024 / 1024).toFixed(1)}MB). Maximum supported size is 50MB.`,\n\t\t);\n\t}\n\n\tconst format = detectFormat(fileName, input.mimeType);\n\n\tlet extractedText = \"\";\n\tswitch (format) {\n\t\tcase \"pdf\": {\n\t\t\tconst parser = new PDFParse({ data: buffer });\n\t\t\ttry {\n\t\t\t\tconst result = await parser.getText();\n\t\t\t\textractedText = result.text || \"\";\n\t\t\t} finally {\n\t\t\t\ttry {\n\t\t\t\t\tawait parser.destroy();\n\t\t\t\t} catch {\n\t\t\t\t\t// ignore\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase \"docx\": {\n\t\t\tconst result = await mammoth.extractRawText({ buffer });\n\t\t\textractedText = result.value || \"\";\n\t\t\tbreak;\n\t\t}\n\t\tcase \"xlsx\": {\n\t\t\tconst workbook = new ExcelJS.Workbook();\n\t\t\tawait workbook.xlsx.load(buffer as unknown as ExcelWorkbookLoadInput);\n\t\t\tconst parts: string[] = [];\n\t\t\tfor (const worksheet of workbook.worksheets) {\n\t\t\t\tconst rows = worksheetToRows(worksheet);\n\t\t\t\tif (rows.length === 0) continue;\n\t\t\t\tparts.push(\n\t\t\t\t\t`# Sheet: ${worksheet.name}\\n${rows.map((row) => row.join(\"\\t\")).join(\"\\n\")}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\textractedText = parts.join(\"\\n\\n\");\n\t\t\tbreak;\n\t\t}\n\t\tcase \"pptx\": {\n\t\t\textractedText = await extractPptxText(buffer);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"text\": {\n\t\t\textractedText = buffer.toString(\"utf8\");\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\textractedText = \"\";\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst { text, truncated } = clampText(extractedText, maxChars);\n\treturn {\n\t\textractedText: text,\n\t\tformat,\n\t\ttruncated,\n\t\tsizeBytes: buffer.byteLength,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"document-extractor.js","sourceRoot":"","sources":["../../src/utils/document-extractor.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { extname, join } from \"node:path\";\nimport ExcelJS from \"exceljs\";\nimport JSZip from \"jszip\";\nimport mammoth from \"mammoth\";\nimport { PDFParse } from \"pdf-parse\";\n\nexport type ExtractedDocumentFormat =\n\t| \"pdf\"\n\t| \"docx\"\n\t| \"xlsx\"\n\t| \"pptx\"\n\t| \"text\"\n\t| \"unknown\";\n\nexport interface ExtractDocumentInput {\n\tbuffer: Buffer;\n\tfileName: string;\n\tmimeType?: string;\n\tmaxChars?: number;\n}\n\nexport interface ExtractDocumentOutput {\n\textractedText: string;\n\tformat: ExtractedDocumentFormat;\n\textractor: \"native\" | \"markitdown\";\n\ttruncated: boolean;\n\tsizeBytes: number;\n}\n\ntype ExcelWorkbookLoadInput = Parameters<ExcelJS.Workbook[\"xlsx\"][\"load\"]>[0];\n\nconst DEFAULT_MAX_CHARS = 200_000;\nconst MAX_INPUT_BYTES = 50 * 1024 * 1024;\nconst MARKITDOWN_TIMEOUT_MS = 20_000;\nconst MARKITDOWN_TIMEOUT_KILL_GRACE_MS = 500;\nconst MARKITDOWN_TIMEOUT_CLOSE_GRACE_MS = 1_000;\nconst NODE_TIMER_MAX_MS = 2_147_483_647;\nconst XLSX_MIME =\n\t\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\";\n\nfunction clampText(\n\ttext: string,\n\tmaxChars: number,\n): { text: string; truncated: boolean } {\n\tif (text.length <= maxChars) return { text, truncated: false };\n\treturn { text: text.slice(0, maxChars), truncated: true };\n}\n\nfunction detectFormat(\n\tfileName: string,\n\tmimeType?: string,\n): ExtractedDocumentFormat {\n\tconst lowerName = fileName.toLowerCase();\n\tconst type = (mimeType || \"\").toLowerCase();\n\n\tif (type === \"application/pdf\" || lowerName.endsWith(\".pdf\")) return \"pdf\";\n\tif (\n\t\ttype ===\n\t\t\t\"application/vnd.openxmlformats-officedocument.wordprocessingml.document\" ||\n\t\tlowerName.endsWith(\".docx\")\n\t)\n\t\treturn \"docx\";\n\tif (type === XLSX_MIME || lowerName.endsWith(\".xlsx\")) return \"xlsx\";\n\tif (\n\t\ttype ===\n\t\t\t\"application/vnd.openxmlformats-officedocument.presentationml.presentation\" ||\n\t\tlowerName.endsWith(\".pptx\")\n\t)\n\t\treturn \"pptx\";\n\tif (type.startsWith(\"text/\")) return \"text\";\n\n\tconst textExtensions = [\n\t\t\".txt\",\n\t\t\".md\",\n\t\t\".markdown\",\n\t\t\".json\",\n\t\t\".yaml\",\n\t\t\".yml\",\n\t\t\".csv\",\n\t\t\".ts\",\n\t\t\".tsx\",\n\t\t\".js\",\n\t\t\".jsx\",\n\t\t\".html\",\n\t\t\".css\",\n\t\t\".xml\",\n\t];\n\tif (textExtensions.some((ext) => lowerName.endsWith(ext))) return \"text\";\n\n\treturn \"unknown\";\n}\n\nfunction splitCommandArgs(value: string | undefined): string[] {\n\tconst input = value?.trim() ?? \"\";\n\tif (!input) return [];\n\n\tconst args: string[] = [];\n\tlet current = \"\";\n\tlet quote: \"'\" | '\"' | null = null;\n\tlet tokenStarted = false;\n\n\tfor (let index = 0; index < input.length; index += 1) {\n\t\tconst char = input.charAt(index);\n\n\t\tif (quote === \"'\") {\n\t\t\tif (char === \"'\") {\n\t\t\t\tquote = null;\n\t\t\t} else {\n\t\t\t\tcurrent += char;\n\t\t\t}\n\t\t\ttokenStarted = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (quote === '\"') {\n\t\t\tif (char === '\"') {\n\t\t\t\tquote = null;\n\t\t\t\ttokenStarted = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"\\\\\") {\n\t\t\t\tconst next = input[index + 1];\n\t\t\t\tif (next && ['\"', \"\\\\\", \"$\", \"`\", \"\\n\"].includes(next)) {\n\t\t\t\t\tcurrent += next;\n\t\t\t\t\tindex += 1;\n\t\t\t\t} else {\n\t\t\t\t\tcurrent += char;\n\t\t\t\t}\n\t\t\t\ttokenStarted = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tcurrent += char;\n\t\t\ttokenStarted = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"\\\\\") {\n\t\t\tconst next = input[index + 1];\n\t\t\tif (next && (/\\s/u.test(next) || [\"'\", '\"', \"\\\\\"].includes(next))) {\n\t\t\t\tcurrent += next;\n\t\t\t\tindex += 1;\n\t\t\t} else {\n\t\t\t\tcurrent += char;\n\t\t\t}\n\t\t\ttokenStarted = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"'\" || char === '\"') {\n\t\t\tquote = char;\n\t\t\ttokenStarted = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (/\\s/u.test(char)) {\n\t\t\tif (tokenStarted) {\n\t\t\t\targs.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t\ttokenStarted = false;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += char;\n\t\ttokenStarted = true;\n\t}\n\n\tif (quote) {\n\t\tthrow new Error(\"Unterminated quote in MAESTRO_MARKITDOWN_ARGS\");\n\t}\n\tif (tokenStarted) {\n\t\targs.push(current);\n\t}\n\treturn args;\n}\n\nfunction isMarkitdownDisabled(): boolean {\n\treturn /^(0|false|off|no)$/i.test(process.env.MAESTRO_MARKITDOWN ?? \"\");\n}\n\nfunction markitdownCandidates(): Array<{\n\tcommand: string;\n\targsPrefix: string[];\n}> {\n\tconst configured = process.env.MAESTRO_MARKITDOWN_CMD?.trim();\n\tif (configured) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tcommand: configured,\n\t\t\t\targsPrefix: splitCommandArgs(process.env.MAESTRO_MARKITDOWN_ARGS),\n\t\t\t},\n\t\t];\n\t}\n\treturn [\n\t\t{ command: \"markitdown\", argsPrefix: [] },\n\t\t{ command: \"uvx\", argsPrefix: [\"markitdown\"] },\n\t];\n}\n\nfunction shouldTryMarkitdown(\n\tformat: ExtractedDocumentFormat,\n\tfileName: string,\n\tmimeType?: string,\n): boolean {\n\tif (isMarkitdownDisabled()) return false;\n\tif (/^(1|true|on|yes)$/i.test(process.env.MAESTRO_MARKITDOWN_PREFER ?? \"\")) {\n\t\treturn true;\n\t}\n\tconst lowerName = fileName.toLowerCase();\n\tconst type = (mimeType ?? \"\").toLowerCase();\n\tif (format === \"unknown\") return true;\n\tif (lowerName.endsWith(\".html\") || lowerName.endsWith(\".htm\")) return true;\n\tif (type.includes(\"text/html\")) return true;\n\treturn false;\n}\n\nfunction readPositiveIntegerEnv(name: string, fallback: number): number {\n\tconst value = process.env[name]?.trim();\n\tif (!value) return fallback;\n\tconst parsed = Number(value);\n\tif (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed <= 0) {\n\t\treturn fallback;\n\t}\n\treturn Math.min(parsed, NODE_TIMER_MAX_MS);\n}\n\nfunction signalMarkitdownProcessTree(\n\tchild: ReturnType<typeof spawn>,\n\tsignal: NodeJS.Signals,\n): void {\n\tif (process.platform !== \"win32\" && child.pid) {\n\t\ttry {\n\t\t\tprocess.kill(-child.pid, signal);\n\t\t\treturn;\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code === \"ESRCH\") {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\ttry {\n\t\tchild.kill(signal);\n\t} catch {\n\t\t// The process may have exited between timeout handling and signal delivery.\n\t}\n}\n\nfunction runMarkitdownCandidate(\n\tcandidate: { command: string; argsPrefix: string[] },\n\targs: string[],\n): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst child = spawn(candidate.command, [...candidate.argsPrefix, ...args], {\n\t\t\tdetached: process.platform !== \"win32\",\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t});\n\t\tlet stdout = \"\";\n\t\tlet stderr = \"\";\n\t\tlet timedOut = false;\n\t\tlet settled = false;\n\t\tlet killTimer: NodeJS.Timeout | undefined;\n\t\tlet closeGraceTimer: NodeJS.Timeout | undefined;\n\t\tconst timer = setTimeout(\n\t\t\t() => {\n\t\t\t\ttimedOut = true;\n\t\t\t\tsignalMarkitdownProcessTree(child, \"SIGTERM\");\n\t\t\t\tkillTimer = setTimeout(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tsignalMarkitdownProcessTree(child, \"SIGKILL\");\n\t\t\t\t\t\tcloseGraceTimer = setTimeout(\n\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\tchild.stdout.destroy();\n\t\t\t\t\t\t\t\tchild.stderr.destroy();\n\t\t\t\t\t\t\t\tchild.unref();\n\t\t\t\t\t\t\t\tfinish(new Error(\"MarkItDown conversion timed out\"));\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\treadPositiveIntegerEnv(\n\t\t\t\t\t\t\t\t\"MAESTRO_MARKITDOWN_CLOSE_GRACE_MS\",\n\t\t\t\t\t\t\t\tMARKITDOWN_TIMEOUT_CLOSE_GRACE_MS,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\treadPositiveIntegerEnv(\n\t\t\t\t\t\t\"MAESTRO_MARKITDOWN_KILL_GRACE_MS\",\n\t\t\t\t\t\tMARKITDOWN_TIMEOUT_KILL_GRACE_MS,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t},\n\t\t\treadPositiveIntegerEnv(\n\t\t\t\t\"MAESTRO_MARKITDOWN_TIMEOUT_MS\",\n\t\t\t\tMARKITDOWN_TIMEOUT_MS,\n\t\t\t),\n\t\t);\n\n\t\tfunction finish(error: Error | null, output?: string) {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tclearTimeout(timer);\n\t\t\tif (killTimer) clearTimeout(killTimer);\n\t\t\tif (closeGraceTimer) clearTimeout(closeGraceTimer);\n\t\t\tif (error) {\n\t\t\t\treject(error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(output ?? \"\");\n\t\t}\n\n\t\tchild.stdout.setEncoding(\"utf8\");\n\t\tchild.stderr.setEncoding(\"utf8\");\n\t\tchild.stdout.on(\"data\", (chunk) => {\n\t\t\tstdout += chunk;\n\t\t});\n\t\tchild.stderr.on(\"data\", (chunk) => {\n\t\t\tstderr += chunk;\n\t\t});\n\t\tchild.on(\"error\", (error) => {\n\t\t\tif (timedOut) {\n\t\t\t\tfinish(new Error(\"MarkItDown conversion timed out\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfinish(error);\n\t\t});\n\t\tchild.on(\"close\", (code) => {\n\t\t\tif (timedOut) {\n\t\t\t\tfinish(new Error(\"MarkItDown conversion timed out\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (code === 0) {\n\t\t\t\tfinish(null, stdout);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfinish(\n\t\t\t\tnew Error(\n\t\t\t\t\t`MarkItDown exited with ${code}${stderr ? `: ${stderr.slice(0, 500)}` : \"\"}`,\n\t\t\t\t),\n\t\t\t);\n\t\t});\n\t});\n}\n\nasync function extractWithMarkitdown(input: {\n\tbuffer: Buffer;\n\tfileName: string;\n\tmimeType?: string;\n}): Promise<string | null> {\n\tconst tempDir = await mkdtemp(join(tmpdir(), \"maestro-markitdown-\"));\n\tconst extension = extname(input.fileName) || \".bin\";\n\tconst tempPath = join(tempDir, `input${extension}`);\n\ttry {\n\t\tawait writeFile(tempPath, input.buffer);\n\t\tconst args = [tempPath];\n\t\tif (input.mimeType) {\n\t\t\targs.push(\"--mime-type\", input.mimeType);\n\t\t}\n\n\t\tlet lastError: unknown;\n\t\tfor (const candidate of markitdownCandidates()) {\n\t\t\ttry {\n\t\t\t\tconst output = await runMarkitdownCandidate(candidate, args);\n\t\t\t\tconst text = output.trim();\n\t\t\t\tif (text) return text;\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error;\n\t\t\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") continue;\n\t\t\t}\n\t\t}\n\n\t\tif (process.env.MAESTRO_MARKITDOWN_CMD) {\n\t\t\tconst message =\n\t\t\t\tlastError instanceof Error ? lastError.message : String(lastError);\n\t\t\tthrow new Error(`MarkItDown extraction failed: ${message}`);\n\t\t}\n\t\treturn null;\n\t} finally {\n\t\tawait rm(tempDir, { force: true, recursive: true });\n\t}\n}\n\nfunction worksheetToRows(worksheet: ExcelJS.Worksheet): string[][] {\n\tconst rows: string[][] = [];\n\tworksheet.eachRow({ includeEmpty: false }, (row) => {\n\t\tconst cells: string[] = [];\n\t\tfor (let column = 1; column <= row.cellCount; column++) {\n\t\t\tcells.push((row.getCell(column).text || \"\").trim());\n\t\t}\n\t\twhile (cells.length > 0 && cells[cells.length - 1] === \"\") {\n\t\t\tcells.pop();\n\t\t}\n\t\tif (cells.some((value) => value !== \"\")) {\n\t\t\trows.push(cells);\n\t\t}\n\t});\n\treturn rows;\n}\n\nasync function extractPptxText(buffer: Buffer): Promise<string> {\n\tconst zip = await JSZip.loadAsync(buffer);\n\n\tconst slidePaths = Object.keys(zip.files)\n\t\t.filter((p) => /^ppt\\/slides\\/slide\\d+\\.xml$/i.test(p))\n\t\t.sort((a, b) => {\n\t\t\tconst an = Number.parseInt(a.match(/slide(\\d+)\\.xml/i)?.[1] || \"0\", 10);\n\t\t\tconst bn = Number.parseInt(b.match(/slide(\\d+)\\.xml/i)?.[1] || \"0\", 10);\n\t\t\treturn an - bn;\n\t\t});\n\n\tif (slidePaths.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst parts: string[] = [];\n\tfor (const slidePath of slidePaths) {\n\t\tconst slideNumber = slidePath.match(/slide(\\d+)\\.xml/i)?.[1] || \"?\";\n\t\tconst xml = await zip.file(slidePath)?.async(\"string\");\n\t\tif (!xml) continue;\n\n\t\tconst texts = Array.from(xml.matchAll(/<a:t>(.*?)<\\/a:t>/g))\n\t\t\t.map((m) => m[1] || \"\")\n\t\t\t.map((s) =>\n\t\t\t\ts\n\t\t\t\t\t.replaceAll(\"<\", \"<\")\n\t\t\t\t\t.replaceAll(\">\", \">\")\n\t\t\t\t\t.replaceAll(\"&\", \"&\")\n\t\t\t\t\t.replaceAll(\""\", '\"')\n\t\t\t\t\t.replaceAll(\"'\", \"'\"),\n\t\t\t)\n\t\t\t.map((s) => s.trim())\n\t\t\t.filter(Boolean);\n\n\t\tif (texts.length === 0) continue;\n\t\tparts.push(`# Slide ${slideNumber}\\n${texts.join(\" \")}`);\n\t}\n\n\treturn parts.join(\"\\n\\n\");\n}\n\nexport async function extractDocumentText(\n\tinput: ExtractDocumentInput,\n): Promise<ExtractDocumentOutput> {\n\tconst { buffer, fileName } = input;\n\tconst maxChars = Math.max(1, input.maxChars ?? DEFAULT_MAX_CHARS);\n\n\tif (buffer.byteLength > MAX_INPUT_BYTES) {\n\t\tthrow new Error(\n\t\t\t`Document is too large (${(buffer.byteLength / 1024 / 1024).toFixed(1)}MB). Maximum supported size is 50MB.`,\n\t\t);\n\t}\n\n\tconst format = detectFormat(fileName, input.mimeType);\n\tconst markitdownFirst =\n\t\t/^(1|true|on|yes)$/i.test(process.env.MAESTRO_MARKITDOWN_PREFER ?? \"\") &&\n\t\t!isMarkitdownDisabled();\n\n\tlet extractedText = \"\";\n\tlet extractor: ExtractDocumentOutput[\"extractor\"] = \"native\";\n\tif (markitdownFirst) {\n\t\tconst markitdownText = await extractWithMarkitdown({\n\t\t\tbuffer,\n\t\t\tfileName,\n\t\t\tmimeType: input.mimeType,\n\t\t});\n\t\tif (markitdownText) {\n\t\t\textractedText = markitdownText;\n\t\t\textractor = \"markitdown\";\n\t\t}\n\t}\n\n\tif (!extractedText) {\n\t\tswitch (format) {\n\t\t\tcase \"pdf\": {\n\t\t\t\tconst parser = new PDFParse({ data: buffer });\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await parser.getText();\n\t\t\t\t\textractedText = result.text || \"\";\n\t\t\t\t} finally {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait parser.destroy();\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// ignore\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"docx\": {\n\t\t\t\tconst result = await mammoth.extractRawText({ buffer });\n\t\t\t\textractedText = result.value || \"\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"xlsx\": {\n\t\t\t\tconst workbook = new ExcelJS.Workbook();\n\t\t\t\tawait workbook.xlsx.load(buffer as unknown as ExcelWorkbookLoadInput);\n\t\t\t\tconst parts: string[] = [];\n\t\t\t\tfor (const worksheet of workbook.worksheets) {\n\t\t\t\t\tconst rows = worksheetToRows(worksheet);\n\t\t\t\t\tif (rows.length === 0) continue;\n\t\t\t\t\tparts.push(\n\t\t\t\t\t\t`# Sheet: ${worksheet.name}\\n${rows.map((row) => row.join(\"\\t\")).join(\"\\n\")}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\textractedText = parts.join(\"\\n\\n\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"pptx\": {\n\t\t\t\textractedText = await extractPptxText(buffer);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"text\": {\n\t\t\t\textractedText = buffer.toString(\"utf8\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\textractedText = \"\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (\n\t\textractor !== \"markitdown\" &&\n\t\tshouldTryMarkitdown(format, fileName, input.mimeType)\n\t) {\n\t\tconst markitdownText = await extractWithMarkitdown({\n\t\t\tbuffer,\n\t\t\tfileName,\n\t\t\tmimeType: input.mimeType,\n\t\t});\n\t\tif (markitdownText) {\n\t\t\textractedText = markitdownText;\n\t\t\textractor = \"markitdown\";\n\t\t}\n\t}\n\n\tconst { text, truncated } = clampText(extractedText, maxChars);\n\treturn {\n\t\textractedText: text,\n\t\tformat,\n\t\textractor,\n\t\ttruncated,\n\t\tsizeBytes: buffer.byteLength,\n\t};\n}\n"]}
|
package/dist/utils/logger.d.ts
CHANGED
package/dist/utils/logger.js
CHANGED
package/dist/utils/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Structured logging service for Composer CLI.\n * Replaces scattered console.log/error calls with centralized, level-based logging.\n */\n\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { PATHS } from \"../config/constants.js\";\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface LogContext {\n\t[key: string]: unknown;\n}\n\ninterface LogEntry {\n\tlevel: LogLevel;\n\tmessage: string;\n\ttimestamp: string;\n\tcontext?: LogContext;\n\terror?: {\n\t\tname: string;\n\t\tmessage: string;\n\t\tstack?: string;\n\t};\n}\n\n/**\n * Logger configuration\n */\ninterface LoggerConfig {\n\t/** Minimum log level to output (debug < info < warn < error) */\n\tminLevel: LogLevel;\n\t/** Whether to output JSON format (useful for log aggregation) */\n\tjsonFormat: boolean;\n\t/** Whether to route debug/info logs to stdout while preserving warnings/errors on stderr */\n\tsplitStreams: boolean;\n\t/** Whether to include timestamps */\n\ttimestamps: boolean;\n\t/** Custom output function (defaults to stderr) */\n\toutput?: (entry: LogEntry) => void;\n}\n\nconst originalConsole = {\n\tlog: console.log.bind(console),\n\tinfo: console.info.bind(console),\n\twarn: console.warn.bind(console),\n\terror: console.error.bind(console),\n\tdebug: console.debug.bind(console),\n};\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n\tdebug: 0,\n\tinfo: 1,\n\twarn: 2,\n\terror: 3,\n};\n\nconst LOG_SEVERITIES: Record<LogLevel, string> = {\n\tdebug: \"DEBUG\",\n\tinfo: \"INFO\",\n\twarn: \"WARNING\",\n\terror: \"ERROR\",\n};\n\nclass Logger {\n\tprivate config: LoggerConfig;\n\n\tconstructor(config?: Partial<LoggerConfig>) {\n\t\tthis.config = {\n\t\t\tminLevel: (process.env.MAESTRO_LOG_LEVEL as LogLevel) ?? \"info\",\n\t\t\tjsonFormat: process.env.MAESTRO_LOG_JSON === \"1\",\n\t\t\tsplitStreams: process.env.MAESTRO_LOG_SPLIT_STREAMS === \"1\",\n\t\t\ttimestamps: true,\n\t\t\t...config,\n\t\t};\n\t}\n\n\t/**\n\t * Check if a log level should be output\n\t */\n\tprivate shouldLog(level: LogLevel): boolean {\n\t\treturn LOG_LEVELS[level] >= LOG_LEVELS[this.config.minLevel];\n\t}\n\n\t/**\n\t * Format and output a log entry\n\t */\n\tprivate log(\n\t\tlevel: LogLevel,\n\t\tmessage: string,\n\t\tcontext?: LogContext,\n\t\terror?: Error,\n\t): void {\n\t\tif (!this.shouldLog(level)) return;\n\n\t\tconst entry: LogEntry = {\n\t\t\tlevel,\n\t\t\tmessage,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tcontext,\n\t\t\terror: error\n\t\t\t\t? {\n\t\t\t\t\t\tname: error.name,\n\t\t\t\t\t\tmessage: error.message,\n\t\t\t\t\t\tstack: error.stack,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t};\n\n\t\tif (this.config.output) {\n\t\t\tthis.config.output(entry);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.config.jsonFormat) {\n\t\t\tthis.outputJson(entry);\n\t\t} else {\n\t\t\tthis.outputPretty(entry);\n\t\t}\n\t}\n\n\t/**\n\t * Output as JSON (for log aggregation systems)\n\t */\n\tprivate outputJson(entry: LogEntry): void {\n\t\tthis.writeLine(\n\t\t\tentry,\n\t\t\tJSON.stringify({ ...entry, severity: LOG_SEVERITIES[entry.level] }),\n\t\t);\n\t}\n\n\t/**\n\t * Output as human-readable format\n\t */\n\tprivate outputPretty(entry: LogEntry): void {\n\t\tconst parts: string[] = [];\n\n\t\tif (this.config.timestamps) {\n\t\t\tparts.push(`[${entry.timestamp}]`);\n\t\t}\n\n\t\tparts.push(`[${entry.level.toUpperCase()}]`);\n\t\tparts.push(entry.message);\n\n\t\tif (entry.context && Object.keys(entry.context).length > 0) {\n\t\t\tparts.push(JSON.stringify(entry.context));\n\t\t}\n\n\t\tthis.writeLine(entry, parts.join(\" \"));\n\n\t\tif (entry.error?.stack) {\n\t\t\tthis.writeLine(entry, entry.error.stack);\n\t\t}\n\t}\n\n\tprivate writeLine(entry: Pick<LogEntry, \"level\">, line: string): void {\n\t\tconst writeToStdout =\n\t\t\tthis.config.splitStreams && LOG_LEVELS[entry.level] < LOG_LEVELS.warn;\n\t\t(writeToStdout ? console.log : console.error)(line);\n\t}\n\n\t/**\n\t * Log debug message (verbose, typically for development)\n\t */\n\tdebug(message: string, context?: LogContext): void {\n\t\tthis.log(\"debug\", message, context);\n\t}\n\n\t/**\n\t * Log info message (general information)\n\t */\n\tinfo(message: string, context?: LogContext): void {\n\t\tthis.log(\"info\", message, context);\n\t}\n\n\t/**\n\t * Log warning message (potentially problematic situations)\n\t */\n\twarn(message: string, context?: LogContext): void {\n\t\tthis.log(\"warn\", message, context);\n\t}\n\n\t/**\n\t * Log error message (failures and exceptions)\n\t */\n\terror(message: string, error?: Error, context?: LogContext): void {\n\t\tthis.log(\"error\", message, context, error);\n\t}\n\n\t/**\n\t * Create a child logger with additional context\n\t */\n\tchild(additionalContext: LogContext): Logger {\n\t\treturn new ContextualLogger(this, additionalContext);\n\t}\n\n\t/**\n\t * Update logger configuration\n\t */\n\tconfigure(config: Partial<LoggerConfig>): void {\n\t\tthis.config = { ...this.config, ...config };\n\t}\n}\n\n/**\n * Logger that automatically includes context in all log calls\n */\nclass ContextualLogger extends Logger {\n\tconstructor(\n\t\tprivate parent: Logger,\n\t\tprivate contextData: LogContext,\n\t) {\n\t\tsuper();\n\t}\n\n\tprivate mergeContext(context?: LogContext): LogContext {\n\t\treturn { ...this.contextData, ...context };\n\t}\n\n\toverride debug(message: string, context?: LogContext): void {\n\t\tthis.parent.debug(message, this.mergeContext(context));\n\t}\n\n\toverride info(message: string, context?: LogContext): void {\n\t\tthis.parent.info(message, this.mergeContext(context));\n\t}\n\n\toverride warn(message: string, context?: LogContext): void {\n\t\tthis.parent.warn(message, this.mergeContext(context));\n\t}\n\n\toverride error(message: string, error?: Error, context?: LogContext): void {\n\t\tthis.parent.error(message, error, this.mergeContext(context));\n\t}\n}\n\n/**\n * Global logger instance\n */\nexport const logger = new Logger();\n\n/**\n * Create a logger for a specific module/component\n */\nexport function createLogger(moduleName: string): Logger {\n\treturn logger.child({ module: moduleName });\n}\n\n/**\n * Silence the logger (useful for TUI mode where stdout must not be polluted)\n */\nexport function silenceLogger(): void {\n\tlogger.configure({ output: () => {} });\n}\n\n/**\n * Redirect all logs to a file (useful for TUI mode)\n * @param filePath - Path to the log file (defaults to ~/.maestro/logs/maestro.log)\n */\nexport function redirectLoggerToFile(filePath?: string): void {\n\tconst logFile = filePath ?? join(PATHS.MAESTRO_HOME, \"logs\", \"maestro.log\");\n\n\t// Ensure directory exists\n\ttry {\n\t\tmkdirSync(dirname(logFile), { recursive: true });\n\t} catch {\n\t\t// Directory may already exist\n\t}\n\n\tlogger.configure({\n\t\toutput: (entry) => {\n\t\t\tconst parts: string[] = [];\n\t\t\tparts.push(`[${entry.timestamp}]`);\n\t\t\tparts.push(`[${entry.level.toUpperCase()}]`);\n\t\t\tparts.push(entry.message);\n\n\t\t\tif (entry.context && Object.keys(entry.context).length > 0) {\n\t\t\t\tparts.push(JSON.stringify(entry.context));\n\t\t\t}\n\n\t\t\tlet line = `${parts.join(\" \")}\\n`;\n\n\t\t\tif (entry.error?.stack) {\n\t\t\t\tline += `${entry.error.stack}\\n`;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tappendFileSync(logFile, line);\n\t\t\t} catch {\n\t\t\t\t// Silently fail if we can't write to the log file\n\t\t\t}\n\t\t},\n\t});\n}\n\n/**\n * Redirect global console methods to the structured logger.\n *\n * Important: Call this only after redirectLoggerToFile() (or a custom logger\n * output) has been configured; otherwise console.* would route back to the\n * console-backed logger output and recurse.\n */\nexport function redirectConsoleToLogger(options?: {\n\tpreserveErrorStderr?: boolean;\n}): void {\n\tconsole.log = (...args: unknown[]) => {\n\t\tlogger.info(args.map(String).join(\" \"));\n\t};\n\tconsole.info = (...args: unknown[]) => {\n\t\tlogger.info(args.map(String).join(\" \"));\n\t};\n\tconsole.warn = (...args: unknown[]) => {\n\t\tlogger.warn(args.map(String).join(\" \"));\n\t};\n\tconsole.error = (...args: unknown[]) => {\n\t\tif (options?.preserveErrorStderr) {\n\t\t\toriginalConsole.error(...args);\n\t\t\treturn;\n\t\t}\n\t\t// Preserve first Error stack if present\n\t\tconst maybeError = args.find((a) => a instanceof Error) as\n\t\t\t| Error\n\t\t\t| undefined;\n\t\tif (maybeError) {\n\t\t\tlogger.error(maybeError.message, maybeError);\n\t\t} else {\n\t\t\tlogger.error(args.map(String).join(\" \"));\n\t\t}\n\t};\n\tconsole.debug = (...args: unknown[]) => {\n\t\tlogger.debug(args.map(String).join(\" \"));\n\t};\n}\n\n/**\n * Redirect process.stderr writes to the structured logger.\n * Useful in TUI mode to prevent third-party libraries from corrupting the terminal.\n */\nexport function redirectStderrToLogger(): void {\n\tprocess.stderr.write = (chunk: unknown) => {\n\t\tconst text =\n\t\t\ttypeof chunk === \"string\"\n\t\t\t\t? chunk\n\t\t\t\t: chunk instanceof Buffer\n\t\t\t\t\t? chunk.toString()\n\t\t\t\t\t: String(chunk);\n\t\tlogger.error(text.trimEnd());\n\t\treturn true;\n\t};\n}\n\n/**\n * Wire process warning / rejection hooks into the logger so they don't hit stderr.\n */\nexport function pipeProcessEventsToLogger(): void {\n\tprocess.on(\"warning\", (warning) => {\n\t\tlogger.warn(\n\t\t\t`${warning.name}: ${warning.message}${\n\t\t\t\twarning.stack ? `\\n${warning.stack}` : \"\"\n\t\t\t}`,\n\t\t);\n\t});\n\n\tprocess.on(\"unhandledRejection\", (reason, promise) => {\n\t\tlogger.error(\n\t\t\t`UnhandledRejection: ${String(reason)} (promise: ${String(promise)})`,\n\t\t);\n\t});\n\n\tprocess.on(\"uncaughtException\", (error) => {\n\t\tif (error instanceof Error) {\n\t\t\tlogger.error(error.message, error);\n\t\t} else {\n\t\t\tlogger.error(`UncaughtException: ${String(error)}`);\n\t\t}\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Structured logging service for Maestro CLI.\n * Replaces scattered console.log/error calls with centralized, level-based logging.\n */\n\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { PATHS } from \"../config/constants.js\";\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport interface LogContext {\n\t[key: string]: unknown;\n}\n\ninterface LogEntry {\n\tlevel: LogLevel;\n\tmessage: string;\n\ttimestamp: string;\n\tcontext?: LogContext;\n\terror?: {\n\t\tname: string;\n\t\tmessage: string;\n\t\tstack?: string;\n\t};\n}\n\n/**\n * Logger configuration\n */\ninterface LoggerConfig {\n\t/** Minimum log level to output (debug < info < warn < error) */\n\tminLevel: LogLevel;\n\t/** Whether to output JSON format (useful for log aggregation) */\n\tjsonFormat: boolean;\n\t/** Whether to route debug/info logs to stdout while preserving warnings/errors on stderr */\n\tsplitStreams: boolean;\n\t/** Whether to include timestamps */\n\ttimestamps: boolean;\n\t/** Custom output function (defaults to stderr) */\n\toutput?: (entry: LogEntry) => void;\n}\n\nconst originalConsole = {\n\tlog: console.log.bind(console),\n\tinfo: console.info.bind(console),\n\twarn: console.warn.bind(console),\n\terror: console.error.bind(console),\n\tdebug: console.debug.bind(console),\n};\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n\tdebug: 0,\n\tinfo: 1,\n\twarn: 2,\n\terror: 3,\n};\n\nconst LOG_SEVERITIES: Record<LogLevel, string> = {\n\tdebug: \"DEBUG\",\n\tinfo: \"INFO\",\n\twarn: \"WARNING\",\n\terror: \"ERROR\",\n};\n\nclass Logger {\n\tprivate config: LoggerConfig;\n\n\tconstructor(config?: Partial<LoggerConfig>) {\n\t\tthis.config = {\n\t\t\tminLevel: (process.env.MAESTRO_LOG_LEVEL as LogLevel) ?? \"info\",\n\t\t\tjsonFormat: process.env.MAESTRO_LOG_JSON === \"1\",\n\t\t\tsplitStreams: process.env.MAESTRO_LOG_SPLIT_STREAMS === \"1\",\n\t\t\ttimestamps: true,\n\t\t\t...config,\n\t\t};\n\t}\n\n\t/**\n\t * Check if a log level should be output\n\t */\n\tprivate shouldLog(level: LogLevel): boolean {\n\t\treturn LOG_LEVELS[level] >= LOG_LEVELS[this.config.minLevel];\n\t}\n\n\t/**\n\t * Format and output a log entry\n\t */\n\tprivate log(\n\t\tlevel: LogLevel,\n\t\tmessage: string,\n\t\tcontext?: LogContext,\n\t\terror?: Error,\n\t): void {\n\t\tif (!this.shouldLog(level)) return;\n\n\t\tconst entry: LogEntry = {\n\t\t\tlevel,\n\t\t\tmessage,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tcontext,\n\t\t\terror: error\n\t\t\t\t? {\n\t\t\t\t\t\tname: error.name,\n\t\t\t\t\t\tmessage: error.message,\n\t\t\t\t\t\tstack: error.stack,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t};\n\n\t\tif (this.config.output) {\n\t\t\tthis.config.output(entry);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.config.jsonFormat) {\n\t\t\tthis.outputJson(entry);\n\t\t} else {\n\t\t\tthis.outputPretty(entry);\n\t\t}\n\t}\n\n\t/**\n\t * Output as JSON (for log aggregation systems)\n\t */\n\tprivate outputJson(entry: LogEntry): void {\n\t\tthis.writeLine(\n\t\t\tentry,\n\t\t\tJSON.stringify({ ...entry, severity: LOG_SEVERITIES[entry.level] }),\n\t\t);\n\t}\n\n\t/**\n\t * Output as human-readable format\n\t */\n\tprivate outputPretty(entry: LogEntry): void {\n\t\tconst parts: string[] = [];\n\n\t\tif (this.config.timestamps) {\n\t\t\tparts.push(`[${entry.timestamp}]`);\n\t\t}\n\n\t\tparts.push(`[${entry.level.toUpperCase()}]`);\n\t\tparts.push(entry.message);\n\n\t\tif (entry.context && Object.keys(entry.context).length > 0) {\n\t\t\tparts.push(JSON.stringify(entry.context));\n\t\t}\n\n\t\tthis.writeLine(entry, parts.join(\" \"));\n\n\t\tif (entry.error?.stack) {\n\t\t\tthis.writeLine(entry, entry.error.stack);\n\t\t}\n\t}\n\n\tprivate writeLine(entry: Pick<LogEntry, \"level\">, line: string): void {\n\t\tconst writeToStdout =\n\t\t\tthis.config.splitStreams && LOG_LEVELS[entry.level] < LOG_LEVELS.warn;\n\t\t(writeToStdout ? console.log : console.error)(line);\n\t}\n\n\t/**\n\t * Log debug message (verbose, typically for development)\n\t */\n\tdebug(message: string, context?: LogContext): void {\n\t\tthis.log(\"debug\", message, context);\n\t}\n\n\t/**\n\t * Log info message (general information)\n\t */\n\tinfo(message: string, context?: LogContext): void {\n\t\tthis.log(\"info\", message, context);\n\t}\n\n\t/**\n\t * Log warning message (potentially problematic situations)\n\t */\n\twarn(message: string, context?: LogContext): void {\n\t\tthis.log(\"warn\", message, context);\n\t}\n\n\t/**\n\t * Log error message (failures and exceptions)\n\t */\n\terror(message: string, error?: Error, context?: LogContext): void {\n\t\tthis.log(\"error\", message, context, error);\n\t}\n\n\t/**\n\t * Create a child logger with additional context\n\t */\n\tchild(additionalContext: LogContext): Logger {\n\t\treturn new ContextualLogger(this, additionalContext);\n\t}\n\n\t/**\n\t * Update logger configuration\n\t */\n\tconfigure(config: Partial<LoggerConfig>): void {\n\t\tthis.config = { ...this.config, ...config };\n\t}\n}\n\n/**\n * Logger that automatically includes context in all log calls\n */\nclass ContextualLogger extends Logger {\n\tconstructor(\n\t\tprivate parent: Logger,\n\t\tprivate contextData: LogContext,\n\t) {\n\t\tsuper();\n\t}\n\n\tprivate mergeContext(context?: LogContext): LogContext {\n\t\treturn { ...this.contextData, ...context };\n\t}\n\n\toverride debug(message: string, context?: LogContext): void {\n\t\tthis.parent.debug(message, this.mergeContext(context));\n\t}\n\n\toverride info(message: string, context?: LogContext): void {\n\t\tthis.parent.info(message, this.mergeContext(context));\n\t}\n\n\toverride warn(message: string, context?: LogContext): void {\n\t\tthis.parent.warn(message, this.mergeContext(context));\n\t}\n\n\toverride error(message: string, error?: Error, context?: LogContext): void {\n\t\tthis.parent.error(message, error, this.mergeContext(context));\n\t}\n}\n\n/**\n * Global logger instance\n */\nexport const logger = new Logger();\n\n/**\n * Create a logger for a specific module/component\n */\nexport function createLogger(moduleName: string): Logger {\n\treturn logger.child({ module: moduleName });\n}\n\n/**\n * Silence the logger (useful for TUI mode where stdout must not be polluted)\n */\nexport function silenceLogger(): void {\n\tlogger.configure({ output: () => {} });\n}\n\n/**\n * Redirect all logs to a file (useful for TUI mode)\n * @param filePath - Path to the log file (defaults to ~/.maestro/logs/maestro.log)\n */\nexport function redirectLoggerToFile(filePath?: string): void {\n\tconst logFile = filePath ?? join(PATHS.MAESTRO_HOME, \"logs\", \"maestro.log\");\n\n\t// Ensure directory exists\n\ttry {\n\t\tmkdirSync(dirname(logFile), { recursive: true });\n\t} catch {\n\t\t// Directory may already exist\n\t}\n\n\tlogger.configure({\n\t\toutput: (entry) => {\n\t\t\tconst parts: string[] = [];\n\t\t\tparts.push(`[${entry.timestamp}]`);\n\t\t\tparts.push(`[${entry.level.toUpperCase()}]`);\n\t\t\tparts.push(entry.message);\n\n\t\t\tif (entry.context && Object.keys(entry.context).length > 0) {\n\t\t\t\tparts.push(JSON.stringify(entry.context));\n\t\t\t}\n\n\t\t\tlet line = `${parts.join(\" \")}\\n`;\n\n\t\t\tif (entry.error?.stack) {\n\t\t\t\tline += `${entry.error.stack}\\n`;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tappendFileSync(logFile, line);\n\t\t\t} catch {\n\t\t\t\t// Silently fail if we can't write to the log file\n\t\t\t}\n\t\t},\n\t});\n}\n\n/**\n * Redirect global console methods to the structured logger.\n *\n * Important: Call this only after redirectLoggerToFile() (or a custom logger\n * output) has been configured; otherwise console.* would route back to the\n * console-backed logger output and recurse.\n */\nexport function redirectConsoleToLogger(options?: {\n\tpreserveErrorStderr?: boolean;\n}): void {\n\tconsole.log = (...args: unknown[]) => {\n\t\tlogger.info(args.map(String).join(\" \"));\n\t};\n\tconsole.info = (...args: unknown[]) => {\n\t\tlogger.info(args.map(String).join(\" \"));\n\t};\n\tconsole.warn = (...args: unknown[]) => {\n\t\tlogger.warn(args.map(String).join(\" \"));\n\t};\n\tconsole.error = (...args: unknown[]) => {\n\t\tif (options?.preserveErrorStderr) {\n\t\t\toriginalConsole.error(...args);\n\t\t\treturn;\n\t\t}\n\t\t// Preserve first Error stack if present\n\t\tconst maybeError = args.find((a) => a instanceof Error) as\n\t\t\t| Error\n\t\t\t| undefined;\n\t\tif (maybeError) {\n\t\t\tlogger.error(maybeError.message, maybeError);\n\t\t} else {\n\t\t\tlogger.error(args.map(String).join(\" \"));\n\t\t}\n\t};\n\tconsole.debug = (...args: unknown[]) => {\n\t\tlogger.debug(args.map(String).join(\" \"));\n\t};\n}\n\n/**\n * Redirect process.stderr writes to the structured logger.\n * Useful in TUI mode to prevent third-party libraries from corrupting the terminal.\n */\nexport function redirectStderrToLogger(): void {\n\tprocess.stderr.write = (chunk: unknown) => {\n\t\tconst text =\n\t\t\ttypeof chunk === \"string\"\n\t\t\t\t? chunk\n\t\t\t\t: chunk instanceof Buffer\n\t\t\t\t\t? chunk.toString()\n\t\t\t\t\t: String(chunk);\n\t\tlogger.error(text.trimEnd());\n\t\treturn true;\n\t};\n}\n\n/**\n * Wire process warning / rejection hooks into the logger so they don't hit stderr.\n */\nexport function pipeProcessEventsToLogger(): void {\n\tprocess.on(\"warning\", (warning) => {\n\t\tlogger.warn(\n\t\t\t`${warning.name}: ${warning.message}${\n\t\t\t\twarning.stack ? `\\n${warning.stack}` : \"\"\n\t\t\t}`,\n\t\t);\n\t});\n\n\tprocess.on(\"unhandledRejection\", (reason, promise) => {\n\t\tlogger.error(\n\t\t\t`UnhandledRejection: ${String(reason)} (promise: ${String(promise)})`,\n\t\t);\n\t});\n\n\tprocess.on(\"uncaughtException\", (error) => {\n\t\tif (error instanceof Error) {\n\t\t\tlogger.error(error.message, error);\n\t\t} else {\n\t\t\tlogger.error(`UncaughtException: ${String(error)}`);\n\t\t}\n\t});\n}\n"]}
|
package/dist/version.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.10.
|
|
3
|
-
"notes": "Maestro by EvalOps - Deterministic coding agent with TUI/CLI and Web UI for AI-assisted development v0.10.
|
|
2
|
+
"version": "0.10.24",
|
|
3
|
+
"notes": "Maestro by EvalOps - Deterministic coding agent with TUI/CLI and Web UI for AI-assisted development v0.10.24 is now available."
|
|
4
4
|
}
|
package/dist/web-server.d.ts
CHANGED
package/dist/web-server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-server.d.ts","sourceRoot":"","sources":["../src/web-server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACN,KAAK,eAAe,EACpB,KAAK,cAAc,EAEnB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"web-server.d.ts","sourceRoot":"","sources":["../src/web-server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACN,KAAK,eAAe,EACpB,KAAK,cAAc,EAEnB,MAAM,WAAW,CAAC;AAwCnB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAe5D,OAAO,KAAK,EACX,mBAAmB,EAEnB,MAAM,yBAAyB,CAAC;AAqBjC,UAAU,qBAAqB;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAyFD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAiMrD,eAAO,MAAM,qBAAqB;iBACpB,eAAe;;;kBAbT,MAAM;iBAAW,MAAM;;CAgB1C,CAAC;AAoZF,wBAAsB,cAAc,CACnC,IAAI,SAAO,EACX,OAAO,GAAE,qBAA0B,iFAyRnC"}
|