@syrin/cli 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +302 -0
- package/dist/cli/commands/analyse.d.ts +16 -0
- package/dist/cli/commands/analyse.js +61 -0
- package/dist/cli/commands/dev.d.ts +23 -0
- package/dist/cli/commands/dev.js +419 -0
- package/dist/cli/commands/doctor.d.ts +10 -0
- package/dist/cli/commands/doctor.js +195 -0
- package/dist/cli/commands/index.d.ts +12 -0
- package/dist/cli/commands/index.js +12 -0
- package/dist/cli/commands/init.d.ts +16 -0
- package/dist/cli/commands/init.js +90 -0
- package/dist/cli/commands/list.d.ts +15 -0
- package/dist/cli/commands/list.js +50 -0
- package/dist/cli/commands/rollback.d.ts +12 -0
- package/dist/cli/commands/rollback.js +101 -0
- package/dist/cli/commands/test.d.ts +31 -0
- package/dist/cli/commands/test.js +88 -0
- package/dist/cli/commands/update.d.ts +9 -0
- package/dist/cli/commands/update.js +76 -0
- package/dist/cli/index.d.ts +13 -0
- package/dist/cli/index.js +342 -0
- package/dist/cli/prompts/index.d.ts +5 -0
- package/dist/cli/prompts/index.js +5 -0
- package/dist/cli/prompts/init-prompt.d.ts +17 -0
- package/dist/cli/prompts/init-prompt.js +263 -0
- package/dist/cli/utils/command-error-handler.d.ts +14 -0
- package/dist/cli/utils/command-error-handler.js +35 -0
- package/dist/cli/utils/common-types.d.ts +24 -0
- package/dist/cli/utils/common-types.js +6 -0
- package/dist/cli/utils/connection-handler.d.ts +37 -0
- package/dist/cli/utils/connection-handler.js +90 -0
- package/dist/cli/utils/index.d.ts +11 -0
- package/dist/cli/utils/index.js +11 -0
- package/dist/cli/utils/option-parsers.d.ts +41 -0
- package/dist/cli/utils/option-parsers.js +92 -0
- package/dist/cli/utils/output-utils.d.ts +12 -0
- package/dist/cli/utils/output-utils.js +21 -0
- package/dist/cli/utils/transport-resolver.d.ts +33 -0
- package/dist/cli/utils/transport-resolver.js +82 -0
- package/dist/cli/utils/version-banner.d.ts +10 -0
- package/dist/cli/utils/version-banner.js +26 -0
- package/dist/config/env-checker.d.ts +37 -0
- package/dist/config/env-checker.js +136 -0
- package/dist/config/generator.d.ts +19 -0
- package/dist/config/generator.js +196 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.js +9 -0
- package/dist/config/loader.d.ts +19 -0
- package/dist/config/loader.js +57 -0
- package/dist/config/schema.d.ts +42 -0
- package/dist/config/schema.js +181 -0
- package/dist/config/syrin.template.yaml +127 -0
- package/dist/config/types.d.ts +87 -0
- package/dist/config/types.js +6 -0
- package/dist/constants/app.d.ts +9 -0
- package/dist/constants/app.js +9 -0
- package/dist/constants/commands.d.ts +43 -0
- package/dist/constants/commands.js +43 -0
- package/dist/constants/defaults.d.ts +18 -0
- package/dist/constants/defaults.js +18 -0
- package/dist/constants/env-vars.d.ts +11 -0
- package/dist/constants/env-vars.js +11 -0
- package/dist/constants/icons.d.ts +23 -0
- package/dist/constants/icons.js +23 -0
- package/dist/constants/index.d.ts +17 -0
- package/dist/constants/index.js +17 -0
- package/dist/constants/labels.d.ts +38 -0
- package/dist/constants/labels.js +42 -0
- package/dist/constants/links.d.ts +10 -0
- package/dist/constants/links.js +11 -0
- package/dist/constants/list.d.ts +10 -0
- package/dist/constants/list.js +9 -0
- package/dist/constants/llm.d.ts +26 -0
- package/dist/constants/llm.js +25 -0
- package/dist/constants/messages.d.ts +107 -0
- package/dist/constants/messages.js +138 -0
- package/dist/constants/paths.d.ts +29 -0
- package/dist/constants/paths.js +29 -0
- package/dist/constants/transport.d.ts +9 -0
- package/dist/constants/transport.js +8 -0
- package/dist/events/emitter.d.ts +64 -0
- package/dist/events/emitter.js +142 -0
- package/dist/events/event-type.d.ts +66 -0
- package/dist/events/event-type.js +81 -0
- package/dist/events/payloads/diagnostics.d.ts +24 -0
- package/dist/events/payloads/diagnostics.js +5 -0
- package/dist/events/payloads/index.d.ts +15 -0
- package/dist/events/payloads/index.js +6 -0
- package/dist/events/payloads/llm.d.ts +58 -0
- package/dist/events/payloads/llm.js +6 -0
- package/dist/events/payloads/registry.d.ts +28 -0
- package/dist/events/payloads/registry.js +5 -0
- package/dist/events/payloads/session.d.ts +32 -0
- package/dist/events/payloads/session.js +5 -0
- package/dist/events/payloads/testing.d.ts +17 -0
- package/dist/events/payloads/testing.js +5 -0
- package/dist/events/payloads/tool.d.ts +29 -0
- package/dist/events/payloads/tool.js +5 -0
- package/dist/events/payloads/transport.d.ts +30 -0
- package/dist/events/payloads/transport.js +5 -0
- package/dist/events/payloads/validation.d.ts +37 -0
- package/dist/events/payloads/validation.js +5 -0
- package/dist/events/payloads/workflow.d.ts +45 -0
- package/dist/events/payloads/workflow.js +5 -0
- package/dist/events/store/file-store.d.ts +37 -0
- package/dist/events/store/file-store.js +113 -0
- package/dist/events/store/index.d.ts +7 -0
- package/dist/events/store/index.js +6 -0
- package/dist/events/store/memory-store.d.ts +26 -0
- package/dist/events/store/memory-store.js +39 -0
- package/dist/events/store.d.ts +11 -0
- package/dist/events/store.js +2 -0
- package/dist/events/types.d.ts +14 -0
- package/dist/events/types.js +2 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +30 -0
- package/dist/presentation/analysis-ui.d.ts +24 -0
- package/dist/presentation/analysis-ui.js +158 -0
- package/dist/presentation/dev/chat-ui-types.d.ts +68 -0
- package/dist/presentation/dev/chat-ui-types.js +5 -0
- package/dist/presentation/dev/chat-ui.d.ts +61 -0
- package/dist/presentation/dev/chat-ui.js +714 -0
- package/dist/presentation/dev/components/assistant-message.d.ts +19 -0
- package/dist/presentation/dev/components/assistant-message.js +36 -0
- package/dist/presentation/dev/components/header.d.ts +16 -0
- package/dist/presentation/dev/components/header.js +22 -0
- package/dist/presentation/dev/components/index.d.ts +13 -0
- package/dist/presentation/dev/components/index.js +13 -0
- package/dist/presentation/dev/components/input-panel.d.ts +22 -0
- package/dist/presentation/dev/components/input-panel.js +43 -0
- package/dist/presentation/dev/components/message-component.d.ts +16 -0
- package/dist/presentation/dev/components/message-component.js +51 -0
- package/dist/presentation/dev/components/messages-list.d.ts +24 -0
- package/dist/presentation/dev/components/messages-list.js +48 -0
- package/dist/presentation/dev/components/system-message.d.ts +16 -0
- package/dist/presentation/dev/components/system-message.js +26 -0
- package/dist/presentation/dev/components/user-message.d.ts +21 -0
- package/dist/presentation/dev/components/user-message.js +35 -0
- package/dist/presentation/dev/components/welcome-banner.d.ts +24 -0
- package/dist/presentation/dev/components/welcome-banner.js +146 -0
- package/dist/presentation/dev/goodbye-messages.d.ts +31 -0
- package/dist/presentation/dev/goodbye-messages.js +100 -0
- package/dist/presentation/dev/index.d.ts +5 -0
- package/dist/presentation/dev/index.js +5 -0
- package/dist/presentation/dev/text-wrapper.d.ts +30 -0
- package/dist/presentation/dev/text-wrapper.js +74 -0
- package/dist/presentation/dev-ui.d.ts +33 -0
- package/dist/presentation/dev-ui.js +246 -0
- package/dist/presentation/doctor-ui.d.ts +40 -0
- package/dist/presentation/doctor-ui.js +157 -0
- package/dist/presentation/init-ui.d.ts +14 -0
- package/dist/presentation/init-ui.js +41 -0
- package/dist/presentation/list-ui.d.ts +44 -0
- package/dist/presentation/list-ui.js +139 -0
- package/dist/presentation/test-ui.d.ts +49 -0
- package/dist/presentation/test-ui.js +358 -0
- package/dist/runtime/analysis/analyser.d.ts +14 -0
- package/dist/runtime/analysis/analyser.js +88 -0
- package/dist/runtime/analysis/dependencies.d.ts +10 -0
- package/dist/runtime/analysis/dependencies.js +140 -0
- package/dist/runtime/analysis/index.d.ts +10 -0
- package/dist/runtime/analysis/index.js +10 -0
- package/dist/runtime/analysis/indexer.d.ts +10 -0
- package/dist/runtime/analysis/indexer.js +62 -0
- package/dist/runtime/analysis/loader.d.ts +15 -0
- package/dist/runtime/analysis/loader.js +47 -0
- package/dist/runtime/analysis/normalizer.d.ts +14 -0
- package/dist/runtime/analysis/normalizer.js +184 -0
- package/dist/runtime/analysis/rules/__test-helpers__.d.ts +18 -0
- package/dist/runtime/analysis/rules/__test-helpers__.js +40 -0
- package/dist/runtime/analysis/rules/base.d.ts +38 -0
- package/dist/runtime/analysis/rules/base.js +23 -0
- package/dist/runtime/analysis/rules/error-codes.d.ts +64 -0
- package/dist/runtime/analysis/rules/error-codes.js +73 -0
- package/dist/runtime/analysis/rules/errors/e000-tool-not-found.d.ts +35 -0
- package/dist/runtime/analysis/rules/errors/e000-tool-not-found.js +32 -0
- package/dist/runtime/analysis/rules/errors/e001-missing-output-schema.d.ts +22 -0
- package/dist/runtime/analysis/rules/errors/e001-missing-output-schema.js +30 -0
- package/dist/runtime/analysis/rules/errors/e002-underspecified-input.d.ts +24 -0
- package/dist/runtime/analysis/rules/errors/e002-underspecified-input.js +52 -0
- package/dist/runtime/analysis/rules/errors/e003-type-mismatch.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e003-type-mismatch.js +73 -0
- package/dist/runtime/analysis/rules/errors/e004-free-text-propagation.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e004-free-text-propagation.js +47 -0
- package/dist/runtime/analysis/rules/errors/e005-tool-ambiguity.d.ts +25 -0
- package/dist/runtime/analysis/rules/errors/e005-tool-ambiguity.js +73 -0
- package/dist/runtime/analysis/rules/errors/e006-param-not-in-description.d.ts +22 -0
- package/dist/runtime/analysis/rules/errors/e006-param-not-in-description.js +57 -0
- package/dist/runtime/analysis/rules/errors/e007-output-not-guaranteed.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e007-output-not-guaranteed.js +56 -0
- package/dist/runtime/analysis/rules/errors/e008-circular-dependency.d.ts +22 -0
- package/dist/runtime/analysis/rules/errors/e008-circular-dependency.js +84 -0
- package/dist/runtime/analysis/rules/errors/e009-implicit-user-input.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e009-implicit-user-input.js +89 -0
- package/dist/runtime/analysis/rules/errors/e010-non-serializable.d.ts +25 -0
- package/dist/runtime/analysis/rules/errors/e010-non-serializable.js +46 -0
- package/dist/runtime/analysis/rules/errors/e011-missing-tool-description.d.ts +24 -0
- package/dist/runtime/analysis/rules/errors/e011-missing-tool-description.js +33 -0
- package/dist/runtime/analysis/rules/errors/e012-side-effect-detected.d.ts +39 -0
- package/dist/runtime/analysis/rules/errors/e012-side-effect-detected.js +40 -0
- package/dist/runtime/analysis/rules/errors/e013-non-deterministic-output.d.ts +37 -0
- package/dist/runtime/analysis/rules/errors/e013-non-deterministic-output.js +34 -0
- package/dist/runtime/analysis/rules/errors/e013-output-explosion.d.ts +39 -0
- package/dist/runtime/analysis/rules/errors/e013-output-explosion.js +36 -0
- package/dist/runtime/analysis/rules/errors/e014-hidden-dependency.d.ts +42 -0
- package/dist/runtime/analysis/rules/errors/e014-hidden-dependency.js +46 -0
- package/dist/runtime/analysis/rules/errors/e014-output-explosion.d.ts +39 -0
- package/dist/runtime/analysis/rules/errors/e014-output-explosion.js +36 -0
- package/dist/runtime/analysis/rules/errors/e015-hidden-dependency.d.ts +42 -0
- package/dist/runtime/analysis/rules/errors/e015-hidden-dependency.js +46 -0
- package/dist/runtime/analysis/rules/errors/e015-unbounded-execution.d.ts +44 -0
- package/dist/runtime/analysis/rules/errors/e015-unbounded-execution.js +66 -0
- package/dist/runtime/analysis/rules/errors/e016-output-validation-failed.d.ts +43 -0
- package/dist/runtime/analysis/rules/errors/e016-output-validation-failed.js +42 -0
- package/dist/runtime/analysis/rules/errors/e016-unbounded-execution.d.ts +44 -0
- package/dist/runtime/analysis/rules/errors/e016-unbounded-execution.js +66 -0
- package/dist/runtime/analysis/rules/errors/e017-input-validation-failed.d.ts +57 -0
- package/dist/runtime/analysis/rules/errors/e017-input-validation-failed.js +80 -0
- package/dist/runtime/analysis/rules/errors/e017-output-validation-failed.d.ts +43 -0
- package/dist/runtime/analysis/rules/errors/e017-output-validation-failed.js +42 -0
- package/dist/runtime/analysis/rules/errors/e018-input-validation-failed.d.ts +57 -0
- package/dist/runtime/analysis/rules/errors/e018-input-validation-failed.js +80 -0
- package/dist/runtime/analysis/rules/errors/e018-tool-execution-failed.d.ts +38 -0
- package/dist/runtime/analysis/rules/errors/e018-tool-execution-failed.js +37 -0
- package/dist/runtime/analysis/rules/errors/e019-tool-execution-failed.d.ts +38 -0
- package/dist/runtime/analysis/rules/errors/e019-tool-execution-failed.js +37 -0
- package/dist/runtime/analysis/rules/errors/e019-unexpected-test-result.d.ts +65 -0
- package/dist/runtime/analysis/rules/errors/e019-unexpected-test-result.js +109 -0
- package/dist/runtime/analysis/rules/errors/e020-unexpected-test-result.d.ts +65 -0
- package/dist/runtime/analysis/rules/errors/e020-unexpected-test-result.js +109 -0
- package/dist/runtime/analysis/rules/errors/e100-missing-output-schema.d.ts +22 -0
- package/dist/runtime/analysis/rules/errors/e100-missing-output-schema.js +30 -0
- package/dist/runtime/analysis/rules/errors/e101-missing-tool-description.d.ts +24 -0
- package/dist/runtime/analysis/rules/errors/e101-missing-tool-description.js +33 -0
- package/dist/runtime/analysis/rules/errors/e102-underspecified-input.d.ts +24 -0
- package/dist/runtime/analysis/rules/errors/e102-underspecified-input.js +52 -0
- package/dist/runtime/analysis/rules/errors/e103-type-mismatch.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e103-type-mismatch.js +72 -0
- package/dist/runtime/analysis/rules/errors/e104-param-not-in-description.d.ts +22 -0
- package/dist/runtime/analysis/rules/errors/e104-param-not-in-description.js +57 -0
- package/dist/runtime/analysis/rules/errors/e105-free-text-propagation.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e105-free-text-propagation.js +47 -0
- package/dist/runtime/analysis/rules/errors/e106-output-not-guaranteed.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e106-output-not-guaranteed.js +58 -0
- package/dist/runtime/analysis/rules/errors/e107-circular-dependency.d.ts +22 -0
- package/dist/runtime/analysis/rules/errors/e107-circular-dependency.js +84 -0
- package/dist/runtime/analysis/rules/errors/e108-implicit-user-input.d.ts +23 -0
- package/dist/runtime/analysis/rules/errors/e108-implicit-user-input.js +94 -0
- package/dist/runtime/analysis/rules/errors/e109-non-serializable.d.ts +25 -0
- package/dist/runtime/analysis/rules/errors/e109-non-serializable.js +44 -0
- package/dist/runtime/analysis/rules/errors/e110-tool-ambiguity.d.ts +25 -0
- package/dist/runtime/analysis/rules/errors/e110-tool-ambiguity.js +73 -0
- package/dist/runtime/analysis/rules/errors/e200-input-validation-failed.d.ts +57 -0
- package/dist/runtime/analysis/rules/errors/e200-input-validation-failed.js +71 -0
- package/dist/runtime/analysis/rules/errors/e300-output-validation-failed.d.ts +43 -0
- package/dist/runtime/analysis/rules/errors/e300-output-validation-failed.js +44 -0
- package/dist/runtime/analysis/rules/errors/e301-output-explosion.d.ts +39 -0
- package/dist/runtime/analysis/rules/errors/e301-output-explosion.js +36 -0
- package/dist/runtime/analysis/rules/errors/e400-tool-execution-failed.d.ts +38 -0
- package/dist/runtime/analysis/rules/errors/e400-tool-execution-failed.js +37 -0
- package/dist/runtime/analysis/rules/errors/e403-unbounded-execution.d.ts +44 -0
- package/dist/runtime/analysis/rules/errors/e403-unbounded-execution.js +66 -0
- package/dist/runtime/analysis/rules/errors/e500-side-effect-detected.d.ts +39 -0
- package/dist/runtime/analysis/rules/errors/e500-side-effect-detected.js +40 -0
- package/dist/runtime/analysis/rules/errors/e501-hidden-dependency.d.ts +47 -0
- package/dist/runtime/analysis/rules/errors/e501-hidden-dependency.js +46 -0
- package/dist/runtime/analysis/rules/errors/e600-unexpected-test-result.d.ts +65 -0
- package/dist/runtime/analysis/rules/errors/e600-unexpected-test-result.js +109 -0
- package/dist/runtime/analysis/rules/index.d.ts +18 -0
- package/dist/runtime/analysis/rules/index.js +94 -0
- package/dist/runtime/analysis/rules/warnings/w001-implicit-dependency.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w001-implicit-dependency.js +39 -0
- package/dist/runtime/analysis/rules/warnings/w002-free-text-without-normalization.d.ts +24 -0
- package/dist/runtime/analysis/rules/warnings/w002-free-text-without-normalization.js +40 -0
- package/dist/runtime/analysis/rules/warnings/w003-missing-examples.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w003-missing-examples.js +84 -0
- package/dist/runtime/analysis/rules/warnings/w004-overloaded-responsibility.d.ts +23 -0
- package/dist/runtime/analysis/rules/warnings/w004-overloaded-responsibility.js +96 -0
- package/dist/runtime/analysis/rules/warnings/w005-generic-description.d.ts +53 -0
- package/dist/runtime/analysis/rules/warnings/w005-generic-description.js +108 -0
- package/dist/runtime/analysis/rules/warnings/w006-optional-as-required.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w006-optional-as-required.js +44 -0
- package/dist/runtime/analysis/rules/warnings/w007-broad-output-schema.d.ts +23 -0
- package/dist/runtime/analysis/rules/warnings/w007-broad-output-schema.js +37 -0
- package/dist/runtime/analysis/rules/warnings/w008-multiple-entry-points.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w008-multiple-entry-points.js +97 -0
- package/dist/runtime/analysis/rules/warnings/w009-hidden-side-effects.d.ts +23 -0
- package/dist/runtime/analysis/rules/warnings/w009-hidden-side-effects.js +88 -0
- package/dist/runtime/analysis/rules/warnings/w010-output-not-reusable.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w010-output-not-reusable.js +81 -0
- package/dist/runtime/analysis/rules/warnings/w021-weak-schema.d.ts +40 -0
- package/dist/runtime/analysis/rules/warnings/w021-weak-schema.js +32 -0
- package/dist/runtime/analysis/rules/warnings/w022-high-entropy-output.d.ts +39 -0
- package/dist/runtime/analysis/rules/warnings/w022-high-entropy-output.js +36 -0
- package/dist/runtime/analysis/rules/warnings/w023-unstable-defaults.d.ts +38 -0
- package/dist/runtime/analysis/rules/warnings/w023-unstable-defaults.js +36 -0
- package/dist/runtime/analysis/rules/warnings/w100-implicit-dependency.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w100-implicit-dependency.js +89 -0
- package/dist/runtime/analysis/rules/warnings/w101-free-text-without-normalization.d.ts +24 -0
- package/dist/runtime/analysis/rules/warnings/w101-free-text-without-normalization.js +40 -0
- package/dist/runtime/analysis/rules/warnings/w102-missing-examples.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w102-missing-examples.js +76 -0
- package/dist/runtime/analysis/rules/warnings/w103-overloaded-responsibility.d.ts +23 -0
- package/dist/runtime/analysis/rules/warnings/w103-overloaded-responsibility.js +91 -0
- package/dist/runtime/analysis/rules/warnings/w104-generic-description.d.ts +53 -0
- package/dist/runtime/analysis/rules/warnings/w104-generic-description.js +108 -0
- package/dist/runtime/analysis/rules/warnings/w105-optional-as-required.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w105-optional-as-required.js +45 -0
- package/dist/runtime/analysis/rules/warnings/w106-broad-output-schema.d.ts +23 -0
- package/dist/runtime/analysis/rules/warnings/w106-broad-output-schema.js +37 -0
- package/dist/runtime/analysis/rules/warnings/w107-multiple-entry-points.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w107-multiple-entry-points.js +97 -0
- package/dist/runtime/analysis/rules/warnings/w108-hidden-side-effects.d.ts +23 -0
- package/dist/runtime/analysis/rules/warnings/w108-hidden-side-effects.js +94 -0
- package/dist/runtime/analysis/rules/warnings/w109-output-not-reusable.d.ts +22 -0
- package/dist/runtime/analysis/rules/warnings/w109-output-not-reusable.js +63 -0
- package/dist/runtime/analysis/rules/warnings/w110-weak-schema.d.ts +40 -0
- package/dist/runtime/analysis/rules/warnings/w110-weak-schema.js +32 -0
- package/dist/runtime/analysis/rules/warnings/w300-high-entropy-output.d.ts +39 -0
- package/dist/runtime/analysis/rules/warnings/w300-high-entropy-output.js +47 -0
- package/dist/runtime/analysis/rules/warnings/w301-unstable-defaults.d.ts +38 -0
- package/dist/runtime/analysis/rules/warnings/w301-unstable-defaults.js +36 -0
- package/dist/runtime/analysis/strict-mode.d.ts +21 -0
- package/dist/runtime/analysis/strict-mode.js +44 -0
- package/dist/runtime/analysis/types.d.ts +133 -0
- package/dist/runtime/analysis/types.js +6 -0
- package/dist/runtime/analysis/utils.d.ts +19 -0
- package/dist/runtime/analysis/utils.js +21 -0
- package/dist/runtime/dev/data-manager.d.ts +55 -0
- package/dist/runtime/dev/data-manager.js +87 -0
- package/dist/runtime/dev/event-mapper.d.ts +100 -0
- package/dist/runtime/dev/event-mapper.js +400 -0
- package/dist/runtime/dev/formatter.d.ts +94 -0
- package/dist/runtime/dev/formatter.js +236 -0
- package/dist/runtime/dev/index.d.ts +9 -0
- package/dist/runtime/dev/index.js +9 -0
- package/dist/runtime/dev/repl.d.ts +114 -0
- package/dist/runtime/dev/repl.js +310 -0
- package/dist/runtime/dev/session.d.ts +86 -0
- package/dist/runtime/dev/session.js +447 -0
- package/dist/runtime/dev/stack-trace.d.ts +77 -0
- package/dist/runtime/dev/stack-trace.js +286 -0
- package/dist/runtime/dev/types.d.ts +54 -0
- package/dist/runtime/dev/types.js +5 -0
- package/dist/runtime/llm/claude.d.ts +27 -0
- package/dist/runtime/llm/claude.js +150 -0
- package/dist/runtime/llm/factory.d.ts +30 -0
- package/dist/runtime/llm/factory.js +78 -0
- package/dist/runtime/llm/index.d.ts +10 -0
- package/dist/runtime/llm/index.js +10 -0
- package/dist/runtime/llm/ollama.d.ts +45 -0
- package/dist/runtime/llm/ollama.js +449 -0
- package/dist/runtime/llm/openai.d.ts +27 -0
- package/dist/runtime/llm/openai.js +170 -0
- package/dist/runtime/llm/provider.d.ts +32 -0
- package/dist/runtime/llm/provider.js +6 -0
- package/dist/runtime/llm/types.d.ts +55 -0
- package/dist/runtime/llm/types.js +6 -0
- package/dist/runtime/mcp/client/base.d.ts +40 -0
- package/dist/runtime/mcp/client/base.js +157 -0
- package/dist/runtime/mcp/client/manager.d.ts +91 -0
- package/dist/runtime/mcp/client/manager.js +248 -0
- package/dist/runtime/mcp/client/process.d.ts +31 -0
- package/dist/runtime/mcp/client/process.js +82 -0
- package/dist/runtime/mcp/connection.d.ts +63 -0
- package/dist/runtime/mcp/connection.js +449 -0
- package/dist/runtime/mcp/index.d.ts +9 -0
- package/dist/runtime/mcp/index.js +9 -0
- package/dist/runtime/mcp/list.d.ts +50 -0
- package/dist/runtime/mcp/list.js +65 -0
- package/dist/runtime/mcp/stdio-transport.d.ts +23 -0
- package/dist/runtime/mcp/stdio-transport.js +71 -0
- package/dist/runtime/mcp/types.d.ts +85 -0
- package/dist/runtime/mcp/types.js +6 -0
- package/dist/runtime/sandbox/executor.d.ts +102 -0
- package/dist/runtime/sandbox/executor.js +537 -0
- package/dist/runtime/sandbox/index.d.ts +9 -0
- package/dist/runtime/sandbox/index.js +9 -0
- package/dist/runtime/sandbox/io-monitor.d.ts +78 -0
- package/dist/runtime/sandbox/io-monitor.js +98 -0
- package/dist/runtime/sandbox/time-parser.d.ts +19 -0
- package/dist/runtime/sandbox/time-parser.js +67 -0
- package/dist/runtime/sandbox/types.d.ts +58 -0
- package/dist/runtime/sandbox/types.js +23 -0
- package/dist/runtime/test/behavior-observer.d.ts +61 -0
- package/dist/runtime/test/behavior-observer.js +140 -0
- package/dist/runtime/test/contract-loader.d.ts +41 -0
- package/dist/runtime/test/contract-loader.js +158 -0
- package/dist/runtime/test/contract-schema.d.ts +46 -0
- package/dist/runtime/test/contract-schema.js +107 -0
- package/dist/runtime/test/contract-types.d.ts +106 -0
- package/dist/runtime/test/contract-types.js +6 -0
- package/dist/runtime/test/dependency-tracker.d.ts +66 -0
- package/dist/runtime/test/dependency-tracker.js +80 -0
- package/dist/runtime/test/formatters.d.ts +18 -0
- package/dist/runtime/test/formatters.js +172 -0
- package/dist/runtime/test/index.d.ts +12 -0
- package/dist/runtime/test/index.js +13 -0
- package/dist/runtime/test/input-generator.d.ts +33 -0
- package/dist/runtime/test/input-generator.js +498 -0
- package/dist/runtime/test/mcp-root-detector.d.ts +31 -0
- package/dist/runtime/test/mcp-root-detector.js +105 -0
- package/dist/runtime/test/orchestrator.d.ts +131 -0
- package/dist/runtime/test/orchestrator.js +738 -0
- package/dist/runtime/test/output-validator.d.ts +44 -0
- package/dist/runtime/test/output-validator.js +262 -0
- package/dist/runtime/test/retry-tester.d.ts +44 -0
- package/dist/runtime/test/retry-tester.js +103 -0
- package/dist/runtime/test/runner.d.ts +28 -0
- package/dist/runtime/test/runner.js +55 -0
- package/dist/runtime/test/synthetic-input-generator.d.ts +11 -0
- package/dist/runtime/test/synthetic-input-generator.js +154 -0
- package/dist/runtime/test/test-runner.d.ts +28 -0
- package/dist/runtime/test/test-runner.js +55 -0
- package/dist/types/factories.d.ts +16 -0
- package/dist/types/factories.js +43 -0
- package/dist/types/ids.d.ts +16 -0
- package/dist/types/ids.js +2 -0
- package/dist/types/opaque.d.ts +4 -0
- package/dist/types/opaque.js +2 -0
- package/dist/utils/errors.d.ts +92 -0
- package/dist/utils/errors.js +97 -0
- package/dist/utils/gitignore.d.ts +11 -0
- package/dist/utils/gitignore.js +59 -0
- package/dist/utils/json-file-saver.d.ts +17 -0
- package/dist/utils/json-file-saver.js +81 -0
- package/dist/utils/json-formatter.d.ts +63 -0
- package/dist/utils/json-formatter.js +344 -0
- package/dist/utils/logger.d.ts +184 -0
- package/dist/utils/logger.js +330 -0
- package/dist/utils/package-manager.d.ts +30 -0
- package/dist/utils/package-manager.js +157 -0
- package/dist/utils/version-checker.d.ts +47 -0
- package/dist/utils/version-checker.js +167 -0
- package/dist/utils/version-display.d.ts +10 -0
- package/dist/utils/version-display.js +20 -0
- package/package.json +106 -0
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox executor for isolated tool execution.
|
|
3
|
+
* Provides isolated execution environment with process reuse for performance.
|
|
4
|
+
* This module is reusable for any sandboxed execution needs, not just testing.
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
import * as os from 'os';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
10
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
11
|
+
import { parseCommand } from '../../runtime/mcp/client/process.js';
|
|
12
|
+
import { ConfigurationError } from '../../utils/errors.js';
|
|
13
|
+
import { formatTimeString } from './time-parser.js';
|
|
14
|
+
import { ToolExecutionErrorType } from './types.js';
|
|
15
|
+
import { logger } from '../../utils/logger.js';
|
|
16
|
+
// Re-export types for convenience
|
|
17
|
+
export * from './types.js';
|
|
18
|
+
/**
|
|
19
|
+
* Sandbox executor with process reuse.
|
|
20
|
+
* Starts MCP server once, executes multiple tools, then closes.
|
|
21
|
+
*/
|
|
22
|
+
export class SandboxExecutor {
|
|
23
|
+
// Note: serverProcess is managed by StdioClientTransport internally
|
|
24
|
+
client = null;
|
|
25
|
+
transport = null;
|
|
26
|
+
tempDir = null;
|
|
27
|
+
initialized = false;
|
|
28
|
+
options;
|
|
29
|
+
constructor(options) {
|
|
30
|
+
this.options = options;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Initialize the sandbox (start MCP server process).
|
|
34
|
+
* This should be called once before testing multiple tools.
|
|
35
|
+
*/
|
|
36
|
+
async initialize() {
|
|
37
|
+
if (this.initialized) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
// Create isolated temp directory
|
|
42
|
+
this.tempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'syrin-sandbox-'));
|
|
43
|
+
// Parse command
|
|
44
|
+
let { executable, args } = parseCommand(this.options.mcpCommand);
|
|
45
|
+
let isWrapped = false;
|
|
46
|
+
// Apply memory limit enforcement if specified
|
|
47
|
+
if (this.options.memoryLimitMB) {
|
|
48
|
+
const memoryMB = this.options.memoryLimitMB;
|
|
49
|
+
// Check if this is a Node.js command
|
|
50
|
+
const isNodeCommand = executable === 'node' || executable.endsWith('/node');
|
|
51
|
+
if (isNodeCommand) {
|
|
52
|
+
// For Node.js: inject --max-old-space-size flag
|
|
53
|
+
args = ['--max-old-space-size', String(memoryMB), ...args];
|
|
54
|
+
logger.debug(`Memory limit: ${memoryMB}MB enforced via --max-old-space-size for Node.js`);
|
|
55
|
+
}
|
|
56
|
+
else if (process.platform !== 'win32') {
|
|
57
|
+
// For POSIX systems: wrap with ulimit -v (virtual memory limit)
|
|
58
|
+
// Convert MB to KB (ulimit -v uses KB)
|
|
59
|
+
const memoryKB = memoryMB * 1024;
|
|
60
|
+
// Wrap the original command with ulimit
|
|
61
|
+
const originalCommand = [executable, ...args]
|
|
62
|
+
.map(arg => (arg.includes(' ') ? `"${arg}"` : arg))
|
|
63
|
+
.join(' ');
|
|
64
|
+
executable = '/bin/sh';
|
|
65
|
+
args = ['-c', `ulimit -v ${memoryKB} && exec ${originalCommand}`];
|
|
66
|
+
isWrapped = true;
|
|
67
|
+
logger.debug(`Memory limit: ${memoryMB}MB (${memoryKB}KB) enforced via ulimit -v`);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
// Windows: Memory limits require different approach (SetProcessWorkingSetSize, Job Objects)
|
|
71
|
+
// For now, log warning that limit is not enforced on Windows
|
|
72
|
+
logger.warn(`Memory limit ${memoryMB}MB specified but not enforced on Windows platform`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Suppress stderr output if requested (for CI mode)
|
|
76
|
+
if (this.options.suppressStderr) {
|
|
77
|
+
if (process.platform !== 'win32') {
|
|
78
|
+
// POSIX: Add stderr redirection to /dev/null
|
|
79
|
+
if (isWrapped) {
|
|
80
|
+
// Already wrapped - add stderr redirection to the existing wrapper
|
|
81
|
+
args[1] = `${args[1]} 2>/dev/null`;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
// Not wrapped yet - wrap to redirect stderr
|
|
85
|
+
const originalCommand = [executable, ...args]
|
|
86
|
+
.map(arg => (arg.includes(' ') ? `"${arg}"` : arg))
|
|
87
|
+
.join(' ');
|
|
88
|
+
executable = '/bin/sh';
|
|
89
|
+
args = ['-c', `${originalCommand} 2>/dev/null`];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// Windows: Add stderr redirection to NUL
|
|
94
|
+
if (isWrapped) {
|
|
95
|
+
// Already wrapped - add stderr redirection to the existing wrapper
|
|
96
|
+
args[1] = `${args[1]} 2>NUL`;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// Not wrapped yet - wrap to redirect stderr
|
|
100
|
+
const originalCommand = [executable, ...args]
|
|
101
|
+
.map(arg => (arg.includes(' ') ? `"${arg}"` : arg))
|
|
102
|
+
.join(' ');
|
|
103
|
+
executable = 'cmd.exe';
|
|
104
|
+
args = ['/c', `${originalCommand} 2>NUL`];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Prepare environment
|
|
109
|
+
const env = {
|
|
110
|
+
...process.env,
|
|
111
|
+
...this.options.env,
|
|
112
|
+
SYRIN_SANDBOX: 'true',
|
|
113
|
+
SYRIN_TEMP_DIR: this.tempDir,
|
|
114
|
+
};
|
|
115
|
+
// Create MCP client
|
|
116
|
+
this.client = new Client({
|
|
117
|
+
name: 'syrin-test',
|
|
118
|
+
version: '1.3.0',
|
|
119
|
+
}, {
|
|
120
|
+
capabilities: {},
|
|
121
|
+
});
|
|
122
|
+
// Create stdio transport (this will spawn the process automatically)
|
|
123
|
+
// Note: StdioClientTransport handles process spawning internally
|
|
124
|
+
// Use project root as cwd (not temp dir) so the server can find its files
|
|
125
|
+
// Memory limits are enforced via command wrapping (see above)
|
|
126
|
+
this.transport = new StdioClientTransport({
|
|
127
|
+
command: executable,
|
|
128
|
+
args,
|
|
129
|
+
env: env,
|
|
130
|
+
cwd: this.options.projectRoot,
|
|
131
|
+
});
|
|
132
|
+
// Set up error handlers
|
|
133
|
+
this.client.onerror = (event) => {
|
|
134
|
+
// Log connection-level errors for debugging
|
|
135
|
+
const errorMessage = event instanceof Error
|
|
136
|
+
? event.message
|
|
137
|
+
: typeof event === 'object' && event !== null && 'message' in event
|
|
138
|
+
? String(event.message)
|
|
139
|
+
: 'Unknown MCP client error';
|
|
140
|
+
logger.error(`MCP client connection error: ${errorMessage}`, event instanceof Error ? event : new Error(errorMessage));
|
|
141
|
+
// Errors will also be caught in try-catch blocks during tool execution
|
|
142
|
+
};
|
|
143
|
+
// Connect client to server (StdioClientTransport spawns the process here)
|
|
144
|
+
await this.client.connect(this.transport);
|
|
145
|
+
// Poll for server readiness with exponential backoff
|
|
146
|
+
const maxWaitTime = 5000; // Maximum total wait time: 5 seconds
|
|
147
|
+
const initialBackoff = 100; // Start with 100ms
|
|
148
|
+
const maxBackoff = 500; // Cap at 500ms
|
|
149
|
+
const startTime = Date.now();
|
|
150
|
+
let backoff = initialBackoff;
|
|
151
|
+
let lastError;
|
|
152
|
+
while (Date.now() - startTime < maxWaitTime) {
|
|
153
|
+
try {
|
|
154
|
+
// Try to list tools to verify server is ready
|
|
155
|
+
const listToolsPromise = this.client.listTools();
|
|
156
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
157
|
+
setTimeout(() => {
|
|
158
|
+
reject(new Error('listTools timeout'));
|
|
159
|
+
}, Math.min(backoff, 1000)); // Use backoff as timeout, max 1s
|
|
160
|
+
});
|
|
161
|
+
await Promise.race([listToolsPromise, timeoutPromise]);
|
|
162
|
+
// Success - server is ready
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
catch (pollError) {
|
|
166
|
+
lastError =
|
|
167
|
+
pollError instanceof Error
|
|
168
|
+
? pollError
|
|
169
|
+
: new Error(String(pollError));
|
|
170
|
+
// Check if we've exceeded max wait time
|
|
171
|
+
if (Date.now() - startTime >= maxWaitTime) {
|
|
172
|
+
throw new ConfigurationError(`MCP server did not become ready within ${maxWaitTime}ms. Command may not exist or server failed to start.`, { cause: lastError });
|
|
173
|
+
}
|
|
174
|
+
// Wait with exponential backoff before retrying
|
|
175
|
+
await new Promise(resolve => setTimeout(resolve, backoff));
|
|
176
|
+
backoff = Math.min(backoff * 1.5, maxBackoff); // Exponential backoff with cap
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Final verification (in case we exited loop due to timeout)
|
|
180
|
+
if (Date.now() - startTime >= maxWaitTime && lastError) {
|
|
181
|
+
throw new ConfigurationError(`MCP server did not become ready within ${maxWaitTime}ms. Command may not exist or server failed to start.`, { cause: lastError });
|
|
182
|
+
}
|
|
183
|
+
this.initialized = true;
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
await this.cleanup();
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Parse MCP protocol response and extract output or error.
|
|
192
|
+
* Handles various response formats from MCP SDK.
|
|
193
|
+
* @param rawResult - Raw result from MCP SDK
|
|
194
|
+
* @param timedOut - Whether execution timed out
|
|
195
|
+
* @returns Object with output and error (mutually exclusive)
|
|
196
|
+
*/
|
|
197
|
+
parseMcpResponse(rawResult, timedOut) {
|
|
198
|
+
// Handle non-object responses
|
|
199
|
+
if (!rawResult || typeof rawResult !== 'object') {
|
|
200
|
+
return { output: rawResult, error: undefined };
|
|
201
|
+
}
|
|
202
|
+
// Check for error field (MCP protocol error response)
|
|
203
|
+
if ('error' in rawResult && rawResult.error) {
|
|
204
|
+
const errorObj = rawResult.error;
|
|
205
|
+
const mcpError = new Error(errorObj.message ||
|
|
206
|
+
`Tool execution failed with code ${errorObj.code || 'unknown'}`);
|
|
207
|
+
return {
|
|
208
|
+
output: undefined,
|
|
209
|
+
error: this.classifyError(mcpError, rawResult, timedOut),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
// Check for content array (MCP SDK standard response format)
|
|
213
|
+
if ('content' in rawResult) {
|
|
214
|
+
const content = rawResult.content;
|
|
215
|
+
if (!Array.isArray(content) || content.length === 0) {
|
|
216
|
+
return { output: rawResult, error: undefined };
|
|
217
|
+
}
|
|
218
|
+
// Check for error content in MCP protocol
|
|
219
|
+
const errorContent = content.find(item => item.type === 'error' || item.error);
|
|
220
|
+
if (errorContent) {
|
|
221
|
+
const errorMessage = errorContent
|
|
222
|
+
.text ||
|
|
223
|
+
errorContent.error?.message ||
|
|
224
|
+
'Tool execution failed';
|
|
225
|
+
const mcpError = new Error(errorMessage);
|
|
226
|
+
return {
|
|
227
|
+
output: undefined,
|
|
228
|
+
error: this.classifyError(mcpError, rawResult, timedOut),
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
// Extract text content
|
|
232
|
+
const textContent = content
|
|
233
|
+
.filter(item => item.type === 'text' && item.text)
|
|
234
|
+
.map(item => item.text)
|
|
235
|
+
.join('\n');
|
|
236
|
+
if (textContent) {
|
|
237
|
+
// Check if this looks like an error message
|
|
238
|
+
if (this.isErrorText(textContent)) {
|
|
239
|
+
const errorMessage = new Error(textContent);
|
|
240
|
+
return {
|
|
241
|
+
output: undefined,
|
|
242
|
+
error: this.classifyError(errorMessage, rawResult, timedOut),
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
// Try to parse as JSON (for structured outputs like Pydantic models)
|
|
246
|
+
try {
|
|
247
|
+
const parsedOutput = JSON.parse(textContent);
|
|
248
|
+
// Check if parsed output contains error-like structure
|
|
249
|
+
if (parsedOutput && typeof parsedOutput === 'object') {
|
|
250
|
+
if ('error' in parsedOutput ||
|
|
251
|
+
'exception' in parsedOutput ||
|
|
252
|
+
'traceback' in parsedOutput) {
|
|
253
|
+
const errorMsg = parsedOutput.error ||
|
|
254
|
+
parsedOutput.exception ||
|
|
255
|
+
String(parsedOutput);
|
|
256
|
+
return {
|
|
257
|
+
output: undefined,
|
|
258
|
+
error: this.classifyError(new Error(errorMsg), rawResult, timedOut),
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return { output: parsedOutput, error: undefined };
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
// If not JSON, use text as-is
|
|
266
|
+
return { output: textContent, error: undefined };
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Fallback: return raw result as output
|
|
271
|
+
return { output: rawResult, error: undefined };
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Check if text content looks like an error message.
|
|
275
|
+
* This handles cases where MCP servers return errors as text instead of proper error responses.
|
|
276
|
+
*/
|
|
277
|
+
isErrorText(text) {
|
|
278
|
+
// Check for validation error patterns (more specific and robust)
|
|
279
|
+
const validationPatterns = [
|
|
280
|
+
/validation\s+error/i,
|
|
281
|
+
/validationerror/i,
|
|
282
|
+
/input\s+should\s+be\s+a\s+valid/i,
|
|
283
|
+
/invalid\s+parameter/i,
|
|
284
|
+
/invalid\s+params/i,
|
|
285
|
+
/type.*mismatch/i,
|
|
286
|
+
/required\s+field/i,
|
|
287
|
+
];
|
|
288
|
+
// Check for general error patterns
|
|
289
|
+
const errorPatterns = [
|
|
290
|
+
/^error:/i,
|
|
291
|
+
/^exception:/i,
|
|
292
|
+
/traceback/i,
|
|
293
|
+
/failed\s+to/i,
|
|
294
|
+
/cannot\s+.*because/i,
|
|
295
|
+
// FastMCP exception patterns - exceptions are logged but might appear in output
|
|
296
|
+
/^valueerror:/i,
|
|
297
|
+
/^runtimeerror:/i,
|
|
298
|
+
/^typeerror:/i,
|
|
299
|
+
/^keyerror:/i,
|
|
300
|
+
/^attributeerror:/i,
|
|
301
|
+
/execution\s+failed/i,
|
|
302
|
+
/error\s+calling\s+tool/i,
|
|
303
|
+
];
|
|
304
|
+
// Must match at least one pattern and be reasonably short (error messages, not large outputs)
|
|
305
|
+
const isShortEnough = text.length < 2000; // Error messages are typically short
|
|
306
|
+
// Also check if text contains exception-like patterns (common in Python tracebacks)
|
|
307
|
+
const hasExceptionPattern = /^\s*\w+Error\s*:/i.test(text) ||
|
|
308
|
+
/^\s*Traceback\s+\(most\s+recent\s+call\s+last\)/i.test(text);
|
|
309
|
+
return (isShortEnough &&
|
|
310
|
+
(validationPatterns.some(pattern => pattern.test(text)) ||
|
|
311
|
+
errorPatterns.some(pattern => pattern.test(text)) ||
|
|
312
|
+
hasExceptionPattern));
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Classify error type from error message and MCP protocol response.
|
|
316
|
+
*/
|
|
317
|
+
classifyError(error, rawResult, timedOut = false) {
|
|
318
|
+
if (timedOut) {
|
|
319
|
+
return Object.assign(error, {
|
|
320
|
+
errorType: ToolExecutionErrorType.TIMEOUT,
|
|
321
|
+
name: 'ToolExecutionTimeout',
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
// Check MCP protocol error codes
|
|
325
|
+
if (rawResult && typeof rawResult === 'object') {
|
|
326
|
+
// MCP protocol uses error codes: -32700 to -32099
|
|
327
|
+
// -32602: Invalid params (input validation)
|
|
328
|
+
// -32603: Internal error (execution error)
|
|
329
|
+
if ('error' in rawResult && rawResult.error) {
|
|
330
|
+
const errorObj = rawResult.error;
|
|
331
|
+
const errorCode = errorObj.code;
|
|
332
|
+
if (errorCode === -32602) {
|
|
333
|
+
return Object.assign(new Error(errorObj.message || error.message), {
|
|
334
|
+
errorType: ToolExecutionErrorType.INPUT_VALIDATION,
|
|
335
|
+
errorCode,
|
|
336
|
+
name: 'MCPInvalidParams',
|
|
337
|
+
context: { mcpErrorCode: errorCode },
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
if (errorCode) {
|
|
341
|
+
return Object.assign(new Error(errorObj.message || error.message), {
|
|
342
|
+
errorType: ToolExecutionErrorType.EXECUTION_ERROR,
|
|
343
|
+
errorCode,
|
|
344
|
+
name: 'MCPExecutionError',
|
|
345
|
+
context: { mcpErrorCode: errorCode },
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
// Classify based on error message patterns (fallback, but more robust)
|
|
351
|
+
const message = error.message.toLowerCase();
|
|
352
|
+
// Input validation patterns (more specific)
|
|
353
|
+
if (message.includes('invalid params') ||
|
|
354
|
+
message.includes('invalid parameter') ||
|
|
355
|
+
message.includes('validation error') ||
|
|
356
|
+
(message.includes('input should be') && message.includes('type'))) {
|
|
357
|
+
return Object.assign(error, {
|
|
358
|
+
errorType: ToolExecutionErrorType.INPUT_VALIDATION,
|
|
359
|
+
name: 'InputValidationError',
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
// Connection errors (use specific patterns to avoid false positives)
|
|
363
|
+
if (message.includes('connection refused') ||
|
|
364
|
+
message.includes('connection reset') ||
|
|
365
|
+
message.includes('connect failed') ||
|
|
366
|
+
message.includes('unable to connect') ||
|
|
367
|
+
message.includes('econnrefused') ||
|
|
368
|
+
message.includes('network')) {
|
|
369
|
+
return Object.assign(error, {
|
|
370
|
+
errorType: ToolExecutionErrorType.CONNECTION_ERROR,
|
|
371
|
+
name: 'ConnectionError',
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
// Default to execution error
|
|
375
|
+
return Object.assign(error, {
|
|
376
|
+
errorType: ToolExecutionErrorType.EXECUTION_ERROR,
|
|
377
|
+
name: 'ToolExecutionError',
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Execute a tool with the given inputs.
|
|
382
|
+
* @param toolName - Name of the tool to execute
|
|
383
|
+
* @param inputs - Array of input objects to test
|
|
384
|
+
* @param timeoutMs - Optional per-tool timeout in milliseconds (overrides default)
|
|
385
|
+
* @returns Array of execution results (one per input)
|
|
386
|
+
*/
|
|
387
|
+
async executeTool(toolName, inputs, timeoutMs) {
|
|
388
|
+
if (!this.initialized || !this.client) {
|
|
389
|
+
throw new ConfigurationError('Sandbox not initialized. Call initialize() first.');
|
|
390
|
+
}
|
|
391
|
+
const results = [];
|
|
392
|
+
for (const input of inputs) {
|
|
393
|
+
const startTime = Date.now();
|
|
394
|
+
let timedOut = false;
|
|
395
|
+
let output;
|
|
396
|
+
let error;
|
|
397
|
+
let rawResult;
|
|
398
|
+
try {
|
|
399
|
+
// Use per-tool timeout if provided, otherwise use default
|
|
400
|
+
const effectiveTimeout = timeoutMs ?? this.options.timeout;
|
|
401
|
+
// Execute with timeout
|
|
402
|
+
const executionPromise = this.client.callTool({
|
|
403
|
+
name: toolName,
|
|
404
|
+
arguments: input,
|
|
405
|
+
});
|
|
406
|
+
let timeoutId;
|
|
407
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
408
|
+
timeoutId = setTimeout(() => {
|
|
409
|
+
timedOut = true;
|
|
410
|
+
reject(new Error(`Tool execution timeout after ${this.formatTimeout(effectiveTimeout)}`));
|
|
411
|
+
}, effectiveTimeout);
|
|
412
|
+
});
|
|
413
|
+
try {
|
|
414
|
+
rawResult = await Promise.race([executionPromise, timeoutPromise]);
|
|
415
|
+
}
|
|
416
|
+
finally {
|
|
417
|
+
// Clear the timeout timer if execution completed before timeout
|
|
418
|
+
if (timeoutId !== undefined) {
|
|
419
|
+
clearTimeout(timeoutId);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
// Parse MCP response to extract output or error
|
|
423
|
+
const parsed = this.parseMcpResponse(rawResult, timedOut);
|
|
424
|
+
output = parsed.output;
|
|
425
|
+
error = parsed.error;
|
|
426
|
+
}
|
|
427
|
+
catch (err) {
|
|
428
|
+
const baseError = err instanceof Error ? err : new Error(String(err));
|
|
429
|
+
error = this.classifyError(baseError, rawResult, timedOut);
|
|
430
|
+
output = undefined;
|
|
431
|
+
}
|
|
432
|
+
const executionTime = Date.now() - startTime;
|
|
433
|
+
// Get memory usage if available (platform-specific)
|
|
434
|
+
const memoryUsed = this.getProcessMemoryUsage();
|
|
435
|
+
if (error) {
|
|
436
|
+
results.push({
|
|
437
|
+
success: false,
|
|
438
|
+
error,
|
|
439
|
+
executionTime,
|
|
440
|
+
memoryUsed,
|
|
441
|
+
timedOut: timedOut || undefined,
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
results.push({
|
|
446
|
+
success: true,
|
|
447
|
+
output: output ?? null,
|
|
448
|
+
executionTime,
|
|
449
|
+
memoryUsed,
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return results;
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Format timeout in milliseconds to human-readable string.
|
|
457
|
+
*/
|
|
458
|
+
formatTimeout(ms) {
|
|
459
|
+
return formatTimeString(ms);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Get the MCP client instance (for reuse by orchestrator).
|
|
463
|
+
* @returns The MCP client, or null if not initialized
|
|
464
|
+
*/
|
|
465
|
+
getClient() {
|
|
466
|
+
return this.client;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Get current process memory usage (if available).
|
|
470
|
+
* @returns Memory usage in MB, or undefined if not available
|
|
471
|
+
*/
|
|
472
|
+
getProcessMemoryUsage() {
|
|
473
|
+
// Memory usage tracking is platform-specific
|
|
474
|
+
// For now, we'll return undefined and can enhance later
|
|
475
|
+
// On Linux, we could read from /proc/{pid}/status
|
|
476
|
+
// On macOS, we could use ps command
|
|
477
|
+
// On Windows, we could use tasklist or WMI
|
|
478
|
+
// Note: The process is managed by StdioClientTransport internally
|
|
479
|
+
// We would need to access it from the transport to get the PID
|
|
480
|
+
return undefined;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Cleanup sandbox resources.
|
|
484
|
+
* Should be called after all tools are tested.
|
|
485
|
+
*/
|
|
486
|
+
async cleanup() {
|
|
487
|
+
// Close MCP client (this will also close the transport and process)
|
|
488
|
+
if (this.client) {
|
|
489
|
+
try {
|
|
490
|
+
await this.client.close();
|
|
491
|
+
}
|
|
492
|
+
catch (_error) {
|
|
493
|
+
// Ignore cleanup errors
|
|
494
|
+
}
|
|
495
|
+
this.client = null;
|
|
496
|
+
}
|
|
497
|
+
// Close transport explicitly (StdioClientTransport manages the process internally)
|
|
498
|
+
if (this.transport) {
|
|
499
|
+
try {
|
|
500
|
+
// The transport's process is managed internally and will be closed
|
|
501
|
+
// when the client is closed, but we can close it explicitly if needed
|
|
502
|
+
if ('close' in this.transport &&
|
|
503
|
+
typeof this.transport.close === 'function') {
|
|
504
|
+
await this.transport.close();
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
catch (_error) {
|
|
508
|
+
// Ignore cleanup errors
|
|
509
|
+
}
|
|
510
|
+
this.transport = null;
|
|
511
|
+
}
|
|
512
|
+
// Clean up temp directory
|
|
513
|
+
if (this.tempDir) {
|
|
514
|
+
try {
|
|
515
|
+
await fs.promises.rm(this.tempDir, { recursive: true, force: true });
|
|
516
|
+
}
|
|
517
|
+
catch (_error) {
|
|
518
|
+
// Ignore cleanup errors
|
|
519
|
+
}
|
|
520
|
+
this.tempDir = null;
|
|
521
|
+
}
|
|
522
|
+
this.initialized = false;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Check if sandbox is initialized.
|
|
526
|
+
*/
|
|
527
|
+
isInitialized() {
|
|
528
|
+
return this.initialized;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Get the temp directory path.
|
|
532
|
+
*/
|
|
533
|
+
getTempDir() {
|
|
534
|
+
return this.tempDir;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox module exports.
|
|
3
|
+
* Reusable sandbox functionality for isolated tool execution.
|
|
4
|
+
*/
|
|
5
|
+
export * from './executor.js';
|
|
6
|
+
export * from './types.js';
|
|
7
|
+
export * from './io-monitor.js';
|
|
8
|
+
export * from './time-parser.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox module exports.
|
|
3
|
+
* Reusable sandbox functionality for isolated tool execution.
|
|
4
|
+
*/
|
|
5
|
+
export * from './executor.js';
|
|
6
|
+
export * from './types.js';
|
|
7
|
+
export * from './io-monitor.js';
|
|
8
|
+
export * from './time-parser.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* I/O monitor for sandboxed tool execution.
|
|
3
|
+
* Monitors filesystem and network operations (does not block).
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Filesystem operation type.
|
|
7
|
+
*/
|
|
8
|
+
export type FSOperation = 'read' | 'write' | 'delete' | 'mkdir' | 'rmdir';
|
|
9
|
+
/**
|
|
10
|
+
* Filesystem operation record.
|
|
11
|
+
*/
|
|
12
|
+
export interface FSOperationRecord {
|
|
13
|
+
/** Operation type */
|
|
14
|
+
operation: FSOperation;
|
|
15
|
+
/** File or directory path */
|
|
16
|
+
path: string;
|
|
17
|
+
/** Timestamp */
|
|
18
|
+
timestamp: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Network operation record.
|
|
22
|
+
*/
|
|
23
|
+
export interface NetworkOperationRecord {
|
|
24
|
+
/** Request URL or endpoint */
|
|
25
|
+
url: string;
|
|
26
|
+
/** HTTP method (if applicable) */
|
|
27
|
+
method?: string;
|
|
28
|
+
/** Timestamp */
|
|
29
|
+
timestamp: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* I/O monitor for tracking operations during tool execution.
|
|
33
|
+
*/
|
|
34
|
+
export declare class IOMonitor {
|
|
35
|
+
private fsOperations;
|
|
36
|
+
private networkOperations;
|
|
37
|
+
private readonly tempDir;
|
|
38
|
+
private readonly projectRoot;
|
|
39
|
+
constructor(tempDir: string, projectRoot: string);
|
|
40
|
+
/**
|
|
41
|
+
* Record a filesystem operation.
|
|
42
|
+
*/
|
|
43
|
+
recordFSOperation(operation: FSOperation, filePath: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Record a network operation.
|
|
46
|
+
*/
|
|
47
|
+
recordNetworkOperation(url: string, method?: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* Get all filesystem operations.
|
|
50
|
+
*/
|
|
51
|
+
getFSOperations(): readonly FSOperationRecord[];
|
|
52
|
+
/**
|
|
53
|
+
* Get all network operations.
|
|
54
|
+
*/
|
|
55
|
+
getNetworkOperations(): readonly NetworkOperationRecord[];
|
|
56
|
+
/**
|
|
57
|
+
* Get filesystem operations that are side effects (writes to project files).
|
|
58
|
+
* Writes to temp directory are NOT considered side effects.
|
|
59
|
+
*/
|
|
60
|
+
getSideEffects(): FSOperationRecord[];
|
|
61
|
+
/**
|
|
62
|
+
* Get filesystem operations filtered by operation type.
|
|
63
|
+
*/
|
|
64
|
+
getFSOperationsByType(operation: FSOperation): readonly FSOperationRecord[];
|
|
65
|
+
/**
|
|
66
|
+
* Clear all recorded operations.
|
|
67
|
+
*/
|
|
68
|
+
clear(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Get summary of I/O operations.
|
|
71
|
+
*/
|
|
72
|
+
getSummary(): {
|
|
73
|
+
totalFSOperations: number;
|
|
74
|
+
sideEffects: number;
|
|
75
|
+
networkOperations: number;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=io-monitor.d.ts.map
|