reqon-dsl 0.2.0 → 0.4.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/CHANGELOG.md +7 -0
- package/README.md +45 -3
- package/dist/ast/nodes.d.ts +91 -4
- package/dist/ast/nodes.js +14 -0
- package/dist/auth/circuit-breaker.d.ts +11 -0
- package/dist/auth/circuit-breaker.js +90 -18
- package/dist/auth/credentials.d.ts +6 -1
- package/dist/auth/credentials.js +12 -4
- package/dist/auth/oauth2-provider.js +13 -3
- package/dist/auth/rate-limiter.d.ts +12 -1
- package/dist/auth/rate-limiter.js +39 -26
- package/dist/auth/token-store.js +8 -1
- package/dist/cli.d.ts +24 -1
- package/dist/cli.js +149 -10
- package/dist/config/constants.d.ts +152 -0
- package/dist/config/constants.js +139 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.js +4 -0
- package/dist/control/index.d.ts +2 -0
- package/dist/control/index.js +1 -0
- package/dist/control/server.d.ts +105 -0
- package/dist/control/server.js +315 -0
- package/dist/control/types.d.ts +61 -0
- package/dist/control/types.js +7 -0
- package/dist/debug/cli-debugger.d.ts +17 -0
- package/dist/debug/cli-debugger.js +185 -0
- package/dist/debug/controller.d.ts +94 -0
- package/dist/debug/controller.js +45 -0
- package/dist/debug/index.d.ts +6 -0
- package/dist/debug/index.js +5 -0
- package/dist/errors/index.d.ts +67 -0
- package/dist/errors/index.js +89 -1
- package/dist/execution/index.d.ts +1 -1
- package/dist/execution/state.d.ts +24 -0
- package/dist/execution/store.js +2 -2
- package/dist/execution-log/events.d.ts +125 -0
- package/dist/execution-log/events.js +17 -0
- package/dist/execution-log/fold.d.ts +38 -0
- package/dist/execution-log/fold.js +54 -0
- package/dist/execution-log/index.d.ts +18 -0
- package/dist/execution-log/index.js +6 -0
- package/dist/execution-log/postgres-store.d.ts +36 -0
- package/dist/execution-log/postgres-store.js +108 -0
- package/dist/execution-log/resume.d.ts +11 -0
- package/dist/execution-log/resume.js +5 -0
- package/dist/execution-log/sqlite-store.d.ts +16 -0
- package/dist/execution-log/sqlite-store.js +101 -0
- package/dist/execution-log/store.d.ts +72 -0
- package/dist/execution-log/store.js +182 -0
- package/dist/index.d.ts +23 -2
- package/dist/index.js +35 -3
- package/dist/interpreter/context.d.ts +29 -0
- package/dist/interpreter/context.js +18 -0
- package/dist/interpreter/evaluator.d.ts +63 -1
- package/dist/interpreter/evaluator.js +219 -42
- package/dist/interpreter/executor.d.ts +132 -14
- package/dist/interpreter/executor.js +883 -178
- package/dist/interpreter/fetch-handler.d.ts +48 -1
- package/dist/interpreter/fetch-handler.js +216 -38
- package/dist/interpreter/http.d.ts +34 -0
- package/dist/interpreter/http.js +203 -28
- package/dist/interpreter/index.d.ts +5 -3
- package/dist/interpreter/index.js +4 -2
- package/dist/interpreter/pagination.d.ts +12 -3
- package/dist/interpreter/pagination.js +102 -32
- package/dist/interpreter/signals.d.ts +8 -0
- package/dist/interpreter/signals.js +12 -0
- package/dist/interpreter/source-manager.d.ts +75 -0
- package/dist/interpreter/source-manager.js +157 -0
- package/dist/interpreter/step-handlers/apply-handler.d.ts +29 -0
- package/dist/interpreter/step-handlers/apply-handler.js +79 -0
- package/dist/interpreter/step-handlers/for-handler.d.ts +16 -0
- package/dist/interpreter/step-handlers/for-handler.js +89 -7
- package/dist/interpreter/step-handlers/index.d.ts +4 -2
- package/dist/interpreter/step-handlers/index.js +4 -2
- package/dist/interpreter/step-handlers/match-handler.d.ts +9 -0
- package/dist/interpreter/step-handlers/match-handler.js +47 -17
- package/dist/interpreter/step-handlers/pause-handler.d.ts +52 -0
- package/dist/interpreter/step-handlers/pause-handler.js +87 -0
- package/dist/interpreter/step-handlers/store-handler.d.ts +17 -1
- package/dist/interpreter/step-handlers/store-handler.js +61 -20
- package/dist/interpreter/step-handlers/types.d.ts +3 -0
- package/dist/interpreter/step-handlers/validate-handler.d.ts +2 -1
- package/dist/interpreter/step-handlers/validate-handler.js +7 -2
- package/dist/interpreter/step-handlers/webhook-handler.d.ts +4 -0
- package/dist/interpreter/step-handlers/webhook-handler.js +31 -5
- package/dist/interpreter/store-manager.d.ts +46 -0
- package/dist/interpreter/store-manager.js +70 -0
- package/dist/lexer/index.d.ts +11 -4
- package/dist/lexer/index.js +11 -4
- package/dist/lexer/tokens.d.ts +17 -1
- package/dist/lexer/tokens.js +36 -0
- package/dist/loader/index.js +5 -8
- package/dist/mcp/index.d.ts +11 -0
- package/dist/mcp/index.js +11 -0
- package/dist/mcp/sandbox.d.ts +41 -0
- package/dist/mcp/sandbox.js +76 -0
- package/dist/mcp/server.d.ts +17 -0
- package/dist/mcp/server.js +504 -0
- package/dist/oas/index.d.ts +2 -0
- package/dist/oas/index.js +1 -0
- package/dist/oas/loader.d.ts +13 -1
- package/dist/oas/loader.js +25 -3
- package/dist/oas/mock-generator.d.ts +12 -0
- package/dist/oas/mock-generator.js +196 -0
- package/dist/oas/validator.js +45 -5
- package/dist/observability/events.d.ts +248 -0
- package/dist/observability/events.js +85 -0
- package/dist/observability/index.d.ts +15 -0
- package/dist/observability/index.js +12 -0
- package/dist/observability/logger.d.ts +106 -0
- package/dist/observability/logger.js +266 -0
- package/dist/observability/otel.d.ts +143 -0
- package/dist/observability/otel.js +421 -0
- package/dist/parser/action-parser.d.ts +105 -0
- package/dist/parser/action-parser.js +645 -0
- package/dist/parser/base.d.ts +7 -0
- package/dist/parser/base.js +11 -0
- package/dist/parser/expressions.d.ts +14 -0
- package/dist/parser/expressions.js +89 -6
- package/dist/parser/fetch-parser.d.ts +27 -0
- package/dist/parser/fetch-parser.js +280 -0
- package/dist/parser/index.d.ts +17 -0
- package/dist/parser/index.js +17 -0
- package/dist/parser/parser.d.ts +44 -46
- package/dist/parser/parser.js +122 -1070
- package/dist/parser/pipeline-parser.d.ts +12 -0
- package/dist/parser/pipeline-parser.js +52 -0
- package/dist/parser/schedule-parser.d.ts +7 -0
- package/dist/parser/schedule-parser.js +137 -0
- package/dist/parser/source-parser.d.ts +9 -0
- package/dist/parser/source-parser.js +151 -0
- package/dist/pause/index.d.ts +15 -0
- package/dist/pause/index.js +12 -0
- package/dist/pause/log-store.d.ts +33 -0
- package/dist/pause/log-store.js +98 -0
- package/dist/pause/manager.d.ts +130 -0
- package/dist/pause/manager.js +294 -0
- package/dist/pause/state.d.ts +93 -0
- package/dist/pause/state.js +103 -0
- package/dist/pause/store.d.ts +61 -0
- package/dist/pause/store.js +158 -0
- package/dist/plugin.d.ts +9 -12
- package/dist/plugin.js +10 -13
- package/dist/scheduler/cron-parser.d.ts +10 -3
- package/dist/scheduler/cron-parser.js +227 -48
- package/dist/scheduler/scheduler.js +56 -22
- package/dist/stores/factory.d.ts +7 -1
- package/dist/stores/factory.js +14 -3
- package/dist/stores/file.d.ts +26 -0
- package/dist/stores/file.js +67 -21
- package/dist/stores/index.d.ts +16 -1
- package/dist/stores/index.js +16 -1
- package/dist/stores/memory.d.ts +4 -0
- package/dist/stores/memory.js +8 -6
- package/dist/stores/postgrest.d.ts +28 -0
- package/dist/stores/postgrest.js +84 -37
- package/dist/stores/types.d.ts +17 -0
- package/dist/stores/types.js +12 -0
- package/dist/sync/index.d.ts +3 -2
- package/dist/sync/index.js +2 -1
- package/dist/sync/log-store.d.ts +30 -0
- package/dist/sync/log-store.js +45 -0
- package/dist/sync/store.js +1 -1
- package/dist/trace/index.d.ts +18 -0
- package/dist/trace/index.js +13 -0
- package/dist/trace/log-view.d.ts +57 -0
- package/dist/trace/log-view.js +76 -0
- package/dist/trace/recorder.d.ts +75 -0
- package/dist/trace/recorder.js +157 -0
- package/dist/trace/replay.d.ts +132 -0
- package/dist/trace/replay.js +264 -0
- package/dist/trace/state.d.ts +102 -0
- package/dist/trace/state.js +86 -0
- package/dist/trace/store.d.ts +75 -0
- package/dist/trace/store.js +250 -0
- package/dist/utils/deep-merge.d.ts +10 -0
- package/dist/utils/deep-merge.js +23 -0
- package/dist/utils/file.d.ts +13 -4
- package/dist/utils/file.js +70 -12
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +2 -1
- package/dist/utils/long-timeout.d.ts +19 -0
- package/dist/utils/long-timeout.js +33 -0
- package/dist/utils/path.d.ts +22 -1
- package/dist/utils/path.js +46 -1
- package/dist/utils/redact.d.ts +22 -0
- package/dist/utils/redact.js +42 -0
- package/dist/utils/type-guards.d.ts +58 -0
- package/dist/utils/type-guards.js +92 -0
- package/dist/webhook/server.d.ts +9 -0
- package/dist/webhook/server.js +122 -36
- package/dist/webhook/types.d.ts +9 -1
- package/package.json +76 -9
- package/.claude/settings.local.json +0 -31
- package/.claude/skills/api-integration.md +0 -125
- package/.claude/skills/database-schema.md +0 -51
- package/.claude/skills/dsl-design.md +0 -80
- package/.claude/skills/property-testing.md +0 -143
- package/.claude/skills/reqon/SKILL.md +0 -44
- package/.claude/skills/reqon/references/examples.md +0 -206
- package/.claude/skills/reqon/references/syntax.md +0 -263
- package/.claude/skills/vscode-extension.md +0 -113
- package/.github/dependabot.yml +0 -32
- package/.github/pull_request_template.md +0 -21
- package/.github/workflows/ci.yml +0 -174
- package/.github/workflows/release.yml +0 -73
- package/CLAUDE.md +0 -72
- package/CONTRIBUTING.md +0 -161
- package/TODO.md +0 -51
- package/dist/auth/auth.test.d.ts +0 -1
- package/dist/auth/auth.test.js +0 -255
- package/dist/errors/errors.test.d.ts +0 -1
- package/dist/errors/errors.test.js +0 -165
- package/dist/execution/execution.test.d.ts +0 -1
- package/dist/execution/execution.test.js +0 -246
- package/dist/integration.test.d.ts +0 -1
- package/dist/integration.test.js +0 -168
- package/dist/interpreter/evaluator.test.d.ts +0 -1
- package/dist/interpreter/evaluator.test.js +0 -512
- package/dist/interpreter/http.test.d.ts +0 -1
- package/dist/interpreter/http.test.js +0 -299
- package/dist/interpreter/progress.test.d.ts +0 -1
- package/dist/interpreter/progress.test.js +0 -216
- package/dist/interpreter/schema-matcher.test.d.ts +0 -1
- package/dist/interpreter/schema-matcher.test.js +0 -122
- package/dist/lexer/lexer.d.ts +0 -24
- package/dist/lexer/lexer.js +0 -264
- package/dist/lexer/lexer.test.d.ts +0 -1
- package/dist/lexer/lexer.test.js +0 -259
- package/dist/loader/loader.test.d.ts +0 -1
- package/dist/loader/loader.test.js +0 -287
- package/dist/oas/oas.test.d.ts +0 -1
- package/dist/oas/oas.test.js +0 -218
- package/dist/parser/expressions.test.d.ts +0 -1
- package/dist/parser/expressions.test.js +0 -378
- package/dist/parser/match.test.d.ts +0 -1
- package/dist/parser/match.test.js +0 -254
- package/dist/parser/parser.test.d.ts +0 -1
- package/dist/parser/parser.test.js +0 -333
- package/dist/parser/schedule.test.d.ts +0 -1
- package/dist/parser/schedule.test.js +0 -241
- package/dist/scheduler/cron-parser.test.d.ts +0 -1
- package/dist/scheduler/cron-parser.test.js +0 -188
- package/dist/stores/file.test.d.ts +0 -1
- package/dist/stores/file.test.js +0 -165
- package/dist/stores/memory.test.d.ts +0 -1
- package/dist/stores/memory.test.js +0 -157
- package/dist/stores/stores.test.d.ts +0 -1
- package/dist/stores/stores.test.js +0 -158
- package/dist/sync/sync.test.d.ts +0 -1
- package/dist/sync/sync.test.js +0 -221
- package/docusaurus/README.md +0 -41
- package/docusaurus/docs/advanced/execution-state.md +0 -283
- package/docusaurus/docs/advanced/extending-reqon.md +0 -388
- package/docusaurus/docs/advanced/multi-file-missions.md +0 -250
- package/docusaurus/docs/advanced/parallel-execution.md +0 -353
- package/docusaurus/docs/api-reference.md +0 -443
- package/docusaurus/docs/authentication/api-key.md +0 -339
- package/docusaurus/docs/authentication/basic.md +0 -276
- package/docusaurus/docs/authentication/bearer.md +0 -282
- package/docusaurus/docs/authentication/oauth2.md +0 -317
- package/docusaurus/docs/authentication/overview.md +0 -251
- package/docusaurus/docs/cli.md +0 -229
- package/docusaurus/docs/core-concepts/actions.md +0 -286
- package/docusaurus/docs/core-concepts/missions.md +0 -264
- package/docusaurus/docs/core-concepts/schemas.md +0 -353
- package/docusaurus/docs/core-concepts/sources.md +0 -339
- package/docusaurus/docs/core-concepts/stores.md +0 -332
- package/docusaurus/docs/dsl-syntax/expressions.md +0 -361
- package/docusaurus/docs/dsl-syntax/fetch.md +0 -293
- package/docusaurus/docs/dsl-syntax/for-loops.md +0 -324
- package/docusaurus/docs/dsl-syntax/map.md +0 -345
- package/docusaurus/docs/dsl-syntax/match.md +0 -387
- package/docusaurus/docs/dsl-syntax/pipelines.md +0 -397
- package/docusaurus/docs/dsl-syntax/validate.md +0 -401
- package/docusaurus/docs/error-handling/dead-letter-queues.md +0 -399
- package/docusaurus/docs/error-handling/flow-control.md +0 -337
- package/docusaurus/docs/error-handling/retry-strategies.md +0 -368
- package/docusaurus/docs/examples.md +0 -488
- package/docusaurus/docs/getting-started.md +0 -256
- package/docusaurus/docs/http/circuit-breaker.md +0 -401
- package/docusaurus/docs/http/incremental-sync.md +0 -394
- package/docusaurus/docs/http/pagination.md +0 -361
- package/docusaurus/docs/http/rate-limiting.md +0 -383
- package/docusaurus/docs/http/requests.md +0 -328
- package/docusaurus/docs/http/retry.md +0 -402
- package/docusaurus/docs/intro.md +0 -90
- package/docusaurus/docs/openapi/loading-specs.md +0 -305
- package/docusaurus/docs/openapi/operation-calls.md +0 -314
- package/docusaurus/docs/openapi/overview.md +0 -212
- package/docusaurus/docs/openapi/response-validation.md +0 -344
- package/docusaurus/docs/scheduling/cron.md +0 -305
- package/docusaurus/docs/scheduling/daemon-mode.md +0 -317
- package/docusaurus/docs/scheduling/intervals.md +0 -289
- package/docusaurus/docs/scheduling/overview.md +0 -231
- package/docusaurus/docs/stores/custom-adapters.md +0 -376
- package/docusaurus/docs/stores/file.md +0 -236
- package/docusaurus/docs/stores/memory.md +0 -193
- package/docusaurus/docs/stores/overview.md +0 -274
- package/docusaurus/docs/stores/postgrest.md +0 -316
- package/docusaurus/docusaurus.config.ts +0 -148
- package/docusaurus/package-lock.json +0 -18029
- package/docusaurus/package.json +0 -47
- package/docusaurus/sidebars.ts +0 -155
- package/docusaurus/src/components/HomepageFeatures/index.tsx +0 -105
- package/docusaurus/src/components/HomepageFeatures/styles.module.css +0 -12
- package/docusaurus/src/css/custom.css +0 -169
- package/docusaurus/src/pages/index.module.css +0 -48
- package/docusaurus/src/pages/index.tsx +0 -110
- package/docusaurus/src/pages/markdown-page.md +0 -7
- package/docusaurus/static/.nojekyll +0 -0
- package/docusaurus/static/img/docusaurus-social-card.jpg +0 -0
- package/docusaurus/static/img/docusaurus.png +0 -0
- package/docusaurus/static/img/favicon.ico +0 -0
- package/docusaurus/static/img/logo.svg +0 -10
- package/docusaurus/static/img/undraw_docusaurus_mountain.svg +0 -171
- package/docusaurus/static/img/undraw_docusaurus_react.svg +0 -170
- package/docusaurus/static/img/undraw_docusaurus_tree.svg +0 -40
- package/docusaurus/tsconfig.json +0 -8
- package/examples/README.md +0 -112
- package/examples/error-handling/README.md +0 -150
- package/examples/error-handling/payment-processor.vague +0 -287
- package/examples/github-sync/README.md +0 -74
- package/examples/github-sync/fetch-issues.vague +0 -47
- package/examples/github-sync/fetch-prs.vague +0 -40
- package/examples/github-sync/mission.vague +0 -101
- package/examples/github-sync/normalize.vague +0 -70
- package/examples/jsonplaceholder/README.md +0 -28
- package/examples/jsonplaceholder/posts.vague +0 -48
- package/examples/petstore/README.md +0 -35
- package/examples/petstore/openapi.yaml +0 -97
- package/examples/petstore/sync.vague +0 -52
- package/examples/temporal-comparison/README.md +0 -297
- package/examples/temporal-comparison/reconciliation.vague +0 -355
- package/examples/temporal-comparison/temporal/activities/index.ts +0 -8
- package/examples/temporal-comparison/temporal/activities/shipstation.ts +0 -225
- package/examples/temporal-comparison/temporal/activities/shopify.ts +0 -257
- package/examples/temporal-comparison/temporal/activities/storage.ts +0 -198
- package/examples/temporal-comparison/temporal/activities/stripe.ts +0 -169
- package/examples/temporal-comparison/temporal/activities/validation.ts +0 -205
- package/examples/temporal-comparison/temporal/client/schedule.ts +0 -218
- package/examples/temporal-comparison/temporal/config/retry.ts +0 -63
- package/examples/temporal-comparison/temporal/types/index.ts +0 -129
- package/examples/temporal-comparison/temporal/workers/main.ts +0 -130
- package/examples/temporal-comparison/temporal/workflows/orderReconciliation.ts +0 -262
- package/examples/xero/README.md +0 -88
- package/examples/xero/invoices.vague +0 -189
- package/src/api-integration.test.ts +0 -954
- package/src/ast/index.ts +0 -1
- package/src/ast/nodes.ts +0 -310
- package/src/auth/auth.test.ts +0 -326
- package/src/auth/circuit-breaker.test.ts +0 -390
- package/src/auth/circuit-breaker.ts +0 -379
- package/src/auth/credentials.test.ts +0 -273
- package/src/auth/credentials.ts +0 -246
- package/src/auth/index.ts +0 -40
- package/src/auth/oauth2-provider.ts +0 -177
- package/src/auth/rate-limiter.ts +0 -459
- package/src/auth/token-store.ts +0 -177
- package/src/auth/types.ts +0 -159
- package/src/benchmark/e2e.bench.ts +0 -288
- package/src/benchmark/evaluator.bench.ts +0 -331
- package/src/benchmark/fixtures.ts +0 -295
- package/src/benchmark/index.ts +0 -108
- package/src/benchmark/lexer.bench.ts +0 -69
- package/src/benchmark/parser.bench.ts +0 -103
- package/src/benchmark/resilience.bench.ts +0 -193
- package/src/benchmark/store.bench.ts +0 -147
- package/src/benchmark/utils.ts +0 -230
- package/src/cli.ts +0 -313
- package/src/errors/errors.test.ts +0 -234
- package/src/errors/index.ts +0 -223
- package/src/execution/execution.test.ts +0 -307
- package/src/execution/index.ts +0 -21
- package/src/execution/state.ts +0 -207
- package/src/execution/store.ts +0 -188
- package/src/index.ts +0 -169
- package/src/integration.test.ts +0 -192
- package/src/interpreter/context.ts +0 -57
- package/src/interpreter/evaluator.test.ts +0 -796
- package/src/interpreter/evaluator.ts +0 -245
- package/src/interpreter/executor.ts +0 -946
- package/src/interpreter/fetch-handler.ts +0 -302
- package/src/interpreter/http.test.ts +0 -423
- package/src/interpreter/http.ts +0 -308
- package/src/interpreter/index.ts +0 -32
- package/src/interpreter/pagination.ts +0 -207
- package/src/interpreter/progress.test.ts +0 -276
- package/src/interpreter/schema-matcher.test.ts +0 -160
- package/src/interpreter/schema-matcher.ts +0 -168
- package/src/interpreter/signals.ts +0 -73
- package/src/interpreter/step-handlers/for-handler.ts +0 -65
- package/src/interpreter/step-handlers/index.ts +0 -17
- package/src/interpreter/step-handlers/map-handler.ts +0 -24
- package/src/interpreter/step-handlers/match-handler.ts +0 -101
- package/src/interpreter/step-handlers/store-handler.ts +0 -78
- package/src/interpreter/step-handlers/types.ts +0 -17
- package/src/interpreter/step-handlers/validate-handler.ts +0 -30
- package/src/interpreter/step-handlers/webhook-handler.ts +0 -142
- package/src/lexer/index.ts +0 -18
- package/src/lexer/lexer.test.ts +0 -316
- package/src/lexer/tokens.ts +0 -179
- package/src/loader/index.ts +0 -288
- package/src/loader/loader.test.ts +0 -360
- package/src/oas/index.ts +0 -4
- package/src/oas/loader.ts +0 -126
- package/src/oas/oas.test.ts +0 -254
- package/src/oas/validator.ts +0 -299
- package/src/parser/base.ts +0 -124
- package/src/parser/expressions.test.ts +0 -525
- package/src/parser/expressions.ts +0 -314
- package/src/parser/index.ts +0 -3
- package/src/parser/match.test.ts +0 -296
- package/src/parser/parser.test.ts +0 -739
- package/src/parser/parser.ts +0 -1469
- package/src/parser/schedule.test.ts +0 -287
- package/src/parser/webhook.test.ts +0 -248
- package/src/plugin.ts +0 -83
- package/src/scheduler/cron-parser.test.ts +0 -236
- package/src/scheduler/cron-parser.ts +0 -236
- package/src/scheduler/index.ts +0 -10
- package/src/scheduler/scheduler.ts +0 -443
- package/src/scheduler/types.ts +0 -71
- package/src/stores/factory.ts +0 -104
- package/src/stores/file.test.ts +0 -276
- package/src/stores/file.ts +0 -211
- package/src/stores/index.ts +0 -6
- package/src/stores/memory.test.ts +0 -238
- package/src/stores/memory.ts +0 -63
- package/src/stores/postgrest.test.ts +0 -488
- package/src/stores/postgrest.ts +0 -263
- package/src/stores/stores.test.ts +0 -197
- package/src/stores/types.ts +0 -58
- package/src/sync/index.ts +0 -16
- package/src/sync/state.ts +0 -126
- package/src/sync/store.ts +0 -139
- package/src/sync/sync.test.ts +0 -271
- package/src/utils/async.ts +0 -10
- package/src/utils/file.ts +0 -106
- package/src/utils/index.ts +0 -14
- package/src/utils/logger.ts +0 -53
- package/src/utils/path.ts +0 -47
- package/src/webhook/index.ts +0 -15
- package/src/webhook/server.test.ts +0 -253
- package/src/webhook/server.ts +0 -389
- package/src/webhook/store.ts +0 -239
- package/src/webhook/types.ts +0 -93
- package/tsconfig.json +0 -17
- package/vitest.config.ts +0 -39
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized Configuration Constants
|
|
3
|
+
*
|
|
4
|
+
* This module contains all default values and configuration constants used
|
|
5
|
+
* throughout the Reqon framework. Centralizing these values makes it easier
|
|
6
|
+
* to understand, tune, and override defaults.
|
|
7
|
+
*/
|
|
8
|
+
// ============================================
|
|
9
|
+
// HTTP Client Configuration
|
|
10
|
+
// ============================================
|
|
11
|
+
/**
|
|
12
|
+
* Default retry configuration for HTTP requests
|
|
13
|
+
*/
|
|
14
|
+
export const HTTP_RETRY_DEFAULTS = {
|
|
15
|
+
/** Maximum number of retry attempts */
|
|
16
|
+
MAX_ATTEMPTS: 3,
|
|
17
|
+
/** Initial delay between retries in milliseconds */
|
|
18
|
+
INITIAL_DELAY_MS: 1000,
|
|
19
|
+
/** Maximum delay between retries in milliseconds */
|
|
20
|
+
MAX_DELAY_MS: 30000,
|
|
21
|
+
/** Backoff strategy: 'exponential', 'linear', or 'constant' */
|
|
22
|
+
BACKOFF: 'exponential',
|
|
23
|
+
/** Per-attempt request timeout in milliseconds (aborts a hung request) */
|
|
24
|
+
TIMEOUT_MS: 30000,
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Default HTTP headers
|
|
28
|
+
*/
|
|
29
|
+
export const HTTP_DEFAULT_HEADERS = {
|
|
30
|
+
CONTENT_TYPE: 'application/json',
|
|
31
|
+
ACCEPT: 'application/json',
|
|
32
|
+
};
|
|
33
|
+
// ============================================
|
|
34
|
+
// Rate Limiter Configuration
|
|
35
|
+
// ============================================
|
|
36
|
+
/**
|
|
37
|
+
* Default rate limiter configuration
|
|
38
|
+
*/
|
|
39
|
+
export const RATE_LIMIT_DEFAULTS = {
|
|
40
|
+
/** Default strategy when rate limited: 'pause', 'throttle', or 'fail' */
|
|
41
|
+
STRATEGY: 'pause',
|
|
42
|
+
/** Maximum wait time in seconds before timing out */
|
|
43
|
+
MAX_WAIT_SECONDS: 300,
|
|
44
|
+
/** Seconds before starting to notify about ongoing waits */
|
|
45
|
+
NOTIFY_AT_SECONDS: 10,
|
|
46
|
+
/** Fallback requests per minute when no rate limit info available */
|
|
47
|
+
FALLBACK_RPM: 60,
|
|
48
|
+
/** Maximum age for stale rate limit entries (1 hour in ms) */
|
|
49
|
+
MAX_STALE_AGE_MS: 60 * 60 * 1000,
|
|
50
|
+
/** Cleanup interval for stale entries (5 minutes in ms) */
|
|
51
|
+
CLEANUP_INTERVAL_MS: 5 * 60 * 1000,
|
|
52
|
+
/** Number of responses between cleanup checks */
|
|
53
|
+
CLEANUP_CHECK_INTERVAL: 100,
|
|
54
|
+
/** Maximum entries before forced cleanup */
|
|
55
|
+
MAX_ENTRIES_BEFORE_CLEANUP: 1000,
|
|
56
|
+
};
|
|
57
|
+
// ============================================
|
|
58
|
+
// Circuit Breaker Configuration
|
|
59
|
+
// ============================================
|
|
60
|
+
/**
|
|
61
|
+
* Default circuit breaker configuration
|
|
62
|
+
*/
|
|
63
|
+
export const CIRCUIT_BREAKER_DEFAULTS = {
|
|
64
|
+
/** Number of failures before opening circuit */
|
|
65
|
+
FAILURE_THRESHOLD: 5,
|
|
66
|
+
/** Time in milliseconds before attempting recovery */
|
|
67
|
+
RESET_TIMEOUT_MS: 30000,
|
|
68
|
+
/** Number of successful requests in half-open to close circuit */
|
|
69
|
+
SUCCESS_THRESHOLD: 2,
|
|
70
|
+
/** Time window in milliseconds for counting failures */
|
|
71
|
+
FAILURE_WINDOW_MS: 60000,
|
|
72
|
+
/** HTTP status codes to count as failures */
|
|
73
|
+
FAILURE_STATUS_CODES: [500, 501, 502, 503, 504],
|
|
74
|
+
/** Whether to count network errors as failures */
|
|
75
|
+
COUNT_NETWORK_ERRORS: true,
|
|
76
|
+
};
|
|
77
|
+
// ============================================
|
|
78
|
+
// Webhook Server Configuration
|
|
79
|
+
// ============================================
|
|
80
|
+
/**
|
|
81
|
+
* Default webhook server configuration
|
|
82
|
+
*/
|
|
83
|
+
export const WEBHOOK_DEFAULTS = {
|
|
84
|
+
/** Default port for webhook server */
|
|
85
|
+
PORT: 3000,
|
|
86
|
+
/** Default host binding — loopback only; opt into 0.0.0.0 explicitly. */
|
|
87
|
+
HOST: '127.0.0.1',
|
|
88
|
+
/** Default timeout for wait steps (5 minutes in ms) */
|
|
89
|
+
DEFAULT_TIMEOUT_MS: 300000,
|
|
90
|
+
/** Cleanup interval for expired registrations (1 minute in ms) */
|
|
91
|
+
CLEANUP_INTERVAL_MS: 60000,
|
|
92
|
+
/** Maximum accepted request body size in bytes (1 MiB) */
|
|
93
|
+
MAX_BODY_BYTES: 1024 * 1024,
|
|
94
|
+
/** Idle socket timeout in ms; drops slow-drip connections */
|
|
95
|
+
SOCKET_TIMEOUT_MS: 30000,
|
|
96
|
+
};
|
|
97
|
+
// ============================================
|
|
98
|
+
// Store Configuration
|
|
99
|
+
// ============================================
|
|
100
|
+
/**
|
|
101
|
+
* Default store configuration
|
|
102
|
+
*/
|
|
103
|
+
export const STORE_DEFAULTS = {
|
|
104
|
+
/** Default base directory for file stores */
|
|
105
|
+
DATA_DIR: '.reqon-data',
|
|
106
|
+
/** Default subdirectory for executions */
|
|
107
|
+
EXECUTIONS_DIR: 'executions',
|
|
108
|
+
/** Default subdirectory for sync state */
|
|
109
|
+
SYNC_DIR: 'sync',
|
|
110
|
+
};
|
|
111
|
+
// ============================================
|
|
112
|
+
// Scheduler Configuration
|
|
113
|
+
// ============================================
|
|
114
|
+
/**
|
|
115
|
+
* Default scheduler configuration
|
|
116
|
+
*/
|
|
117
|
+
export const SCHEDULER_DEFAULTS = {
|
|
118
|
+
/** Default retry configuration for failed scheduled missions */
|
|
119
|
+
MAX_RETRIES: 3,
|
|
120
|
+
/** Default delay between retries in seconds */
|
|
121
|
+
RETRY_DELAY_SECONDS: 60,
|
|
122
|
+
};
|
|
123
|
+
// ============================================
|
|
124
|
+
// Execution Configuration
|
|
125
|
+
// ============================================
|
|
126
|
+
/**
|
|
127
|
+
* Default execution configuration
|
|
128
|
+
*/
|
|
129
|
+
export const EXECUTION_DEFAULTS = {
|
|
130
|
+
/**
|
|
131
|
+
* Whether development mode is enabled by default. When true, sql/nosql
|
|
132
|
+
* stores fall back to local JSON files; default false so a mission that
|
|
133
|
+
* declares `store sql`/`nosql` errors loudly instead of silently writing
|
|
134
|
+
* to disk.
|
|
135
|
+
*/
|
|
136
|
+
DEVELOPMENT_MODE: false,
|
|
137
|
+
/** Whether to persist execution state by default */
|
|
138
|
+
PERSIST_STATE: false,
|
|
139
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ControlServer } from './server.js';
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Control Server
|
|
3
|
+
*
|
|
4
|
+
* HTTP server for runtime control of mission execution.
|
|
5
|
+
* Provides pause/resume commands and live status queries.
|
|
6
|
+
*/
|
|
7
|
+
import type { ExecutionState, LiveProgress } from '../execution/index.js';
|
|
8
|
+
import type { ControlServerConfig, ControlServerCallbacks } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Control Server
|
|
11
|
+
*
|
|
12
|
+
* Provides HTTP endpoints for controlling mission execution:
|
|
13
|
+
* - POST /pause - Request graceful pause
|
|
14
|
+
* - POST /resume - Clear pause request
|
|
15
|
+
* - GET /status - Get current execution state and progress
|
|
16
|
+
* - GET /health - Health check
|
|
17
|
+
*/
|
|
18
|
+
export declare class ControlServer {
|
|
19
|
+
private config;
|
|
20
|
+
private callbacks;
|
|
21
|
+
private server?;
|
|
22
|
+
private running;
|
|
23
|
+
private startTime;
|
|
24
|
+
private pauseRequested;
|
|
25
|
+
private executionState?;
|
|
26
|
+
private liveProgress?;
|
|
27
|
+
constructor(config?: ControlServerConfig, callbacks?: ControlServerCallbacks);
|
|
28
|
+
/**
|
|
29
|
+
* Start the control server
|
|
30
|
+
*/
|
|
31
|
+
start(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Stop the control server
|
|
34
|
+
*/
|
|
35
|
+
stop(): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Check if pause has been requested
|
|
38
|
+
*/
|
|
39
|
+
isPauseRequested(): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Clear pause request (called after pause is handled)
|
|
42
|
+
*/
|
|
43
|
+
clearPauseRequest(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Update execution state (called by executor)
|
|
46
|
+
*/
|
|
47
|
+
updateState(state: ExecutionState): void;
|
|
48
|
+
/**
|
|
49
|
+
* Update live progress (called by executor)
|
|
50
|
+
*/
|
|
51
|
+
updateProgress(progress: LiveProgress): void;
|
|
52
|
+
/**
|
|
53
|
+
* Check if the server is running
|
|
54
|
+
*/
|
|
55
|
+
isRunning(): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Get the server port
|
|
58
|
+
*/
|
|
59
|
+
getPort(): number;
|
|
60
|
+
/**
|
|
61
|
+
* Handle incoming HTTP request
|
|
62
|
+
*/
|
|
63
|
+
private handleRequest;
|
|
64
|
+
/** True if a host string is a loopback address. */
|
|
65
|
+
private isLoopback;
|
|
66
|
+
/** True if the request carries an Origin header pointing at another origin. */
|
|
67
|
+
private hasCrossOriginHeader;
|
|
68
|
+
/**
|
|
69
|
+
* Enforce the shared-secret token on protected endpoints. When no token is
|
|
70
|
+
* configured, allow (the loopback bind + CSRF check are the baseline) but
|
|
71
|
+
* warn so operators know /status state is exposed locally.
|
|
72
|
+
*/
|
|
73
|
+
private authorized;
|
|
74
|
+
/**
|
|
75
|
+
* Constant-time string comparison. Avoids the timing oracle of `a !== b`,
|
|
76
|
+
* which short-circuits on the first differing byte and can leak the token
|
|
77
|
+
* prefix. Length is compared first (and non-constant-time), which only
|
|
78
|
+
* reveals the token length — not its contents.
|
|
79
|
+
*/
|
|
80
|
+
private safeEqual;
|
|
81
|
+
/**
|
|
82
|
+
* Handle health check
|
|
83
|
+
*/
|
|
84
|
+
private handleHealth;
|
|
85
|
+
/**
|
|
86
|
+
* Handle status query
|
|
87
|
+
*/
|
|
88
|
+
private handleStatus;
|
|
89
|
+
/**
|
|
90
|
+
* Handle pause request
|
|
91
|
+
*/
|
|
92
|
+
private handlePause;
|
|
93
|
+
/**
|
|
94
|
+
* Handle resume request
|
|
95
|
+
*/
|
|
96
|
+
private handleResume;
|
|
97
|
+
/**
|
|
98
|
+
* Send JSON response
|
|
99
|
+
*/
|
|
100
|
+
private sendJson;
|
|
101
|
+
/**
|
|
102
|
+
* Log message if verbose mode enabled
|
|
103
|
+
*/
|
|
104
|
+
private log;
|
|
105
|
+
}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Control Server
|
|
3
|
+
*
|
|
4
|
+
* HTTP server for runtime control of mission execution.
|
|
5
|
+
* Provides pause/resume commands and live status queries.
|
|
6
|
+
*/
|
|
7
|
+
import { createServer } from 'node:http';
|
|
8
|
+
import { parse as parseUrl } from 'node:url';
|
|
9
|
+
import { timingSafeEqual } from 'node:crypto';
|
|
10
|
+
const DEFAULTS = {
|
|
11
|
+
PORT: 3001,
|
|
12
|
+
HOST: 'localhost',
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Control Server
|
|
16
|
+
*
|
|
17
|
+
* Provides HTTP endpoints for controlling mission execution:
|
|
18
|
+
* - POST /pause - Request graceful pause
|
|
19
|
+
* - POST /resume - Clear pause request
|
|
20
|
+
* - GET /status - Get current execution state and progress
|
|
21
|
+
* - GET /health - Health check
|
|
22
|
+
*/
|
|
23
|
+
export class ControlServer {
|
|
24
|
+
config;
|
|
25
|
+
callbacks;
|
|
26
|
+
server;
|
|
27
|
+
running = false;
|
|
28
|
+
startTime = Date.now();
|
|
29
|
+
// State managed by the control server
|
|
30
|
+
pauseRequested = false;
|
|
31
|
+
executionState;
|
|
32
|
+
liveProgress;
|
|
33
|
+
constructor(config = {}, callbacks = {}) {
|
|
34
|
+
this.config = {
|
|
35
|
+
port: config.port ?? DEFAULTS.PORT,
|
|
36
|
+
host: config.host ?? DEFAULTS.HOST,
|
|
37
|
+
verbose: config.verbose ?? false,
|
|
38
|
+
authToken: config.authToken ?? '',
|
|
39
|
+
};
|
|
40
|
+
this.callbacks = callbacks;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Start the control server
|
|
44
|
+
*/
|
|
45
|
+
async start() {
|
|
46
|
+
if (this.running)
|
|
47
|
+
return;
|
|
48
|
+
// Hard-refuse to expose a state-changing server beyond loopback without a
|
|
49
|
+
// shared secret. /pause, /resume, and /status would otherwise be reachable
|
|
50
|
+
// by anyone who can route to this host. Bind to loopback or set authToken.
|
|
51
|
+
if (!this.isLoopback(this.config.host) && !this.config.authToken) {
|
|
52
|
+
throw new Error(`[Control] Refusing to start: binding to non-loopback host "${this.config.host}" ` +
|
|
53
|
+
`with no authToken would expose /pause, /resume, and /status without authentication. ` +
|
|
54
|
+
`Set an authToken or bind to localhost.`);
|
|
55
|
+
}
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
this.server = createServer((req, res) => this.handleRequest(req, res));
|
|
58
|
+
this.server.setTimeout(30000);
|
|
59
|
+
this.server.on('error', (error) => {
|
|
60
|
+
reject(error);
|
|
61
|
+
});
|
|
62
|
+
this.server.listen(this.config.port, this.config.host, () => {
|
|
63
|
+
this.running = true;
|
|
64
|
+
this.startTime = Date.now();
|
|
65
|
+
this.log(`Control server listening on ${this.config.host}:${this.config.port}`);
|
|
66
|
+
resolve();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Stop the control server
|
|
72
|
+
*/
|
|
73
|
+
async stop() {
|
|
74
|
+
if (!this.running)
|
|
75
|
+
return;
|
|
76
|
+
return new Promise((resolve) => {
|
|
77
|
+
if (this.server) {
|
|
78
|
+
this.server.close(() => {
|
|
79
|
+
this.running = false;
|
|
80
|
+
this.log('Control server stopped');
|
|
81
|
+
resolve();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
resolve();
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Check if pause has been requested
|
|
91
|
+
*/
|
|
92
|
+
isPauseRequested() {
|
|
93
|
+
return this.pauseRequested;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Clear pause request (called after pause is handled)
|
|
97
|
+
*/
|
|
98
|
+
clearPauseRequest() {
|
|
99
|
+
this.pauseRequested = false;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Update execution state (called by executor)
|
|
103
|
+
*/
|
|
104
|
+
updateState(state) {
|
|
105
|
+
this.executionState = state;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Update live progress (called by executor)
|
|
109
|
+
*/
|
|
110
|
+
updateProgress(progress) {
|
|
111
|
+
this.liveProgress = progress;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Check if the server is running
|
|
115
|
+
*/
|
|
116
|
+
isRunning() {
|
|
117
|
+
return this.running;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get the server port
|
|
121
|
+
*/
|
|
122
|
+
getPort() {
|
|
123
|
+
return this.config.port;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Handle incoming HTTP request
|
|
127
|
+
*/
|
|
128
|
+
async handleRequest(req, res) {
|
|
129
|
+
const url = parseUrl(req.url ?? '/', true);
|
|
130
|
+
const path = url.pathname ?? '/';
|
|
131
|
+
const method = req.method ?? 'GET';
|
|
132
|
+
// No wildcard CORS. Same-origin reads only; we never reflect ACAO so a
|
|
133
|
+
// browser on another origin can't read /status.
|
|
134
|
+
res.setHeader('Vary', 'Origin');
|
|
135
|
+
// Handle preflight
|
|
136
|
+
if (method === 'OPTIONS') {
|
|
137
|
+
res.writeHead(204);
|
|
138
|
+
res.end();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
// CSRF defense: reject any request that carries a cross-origin Origin
|
|
142
|
+
// header (server-to-server clients and curl send none). Combined with the
|
|
143
|
+
// loopback bind, this stops a web page the operator visits from POSTing
|
|
144
|
+
// /pause or /resume to their local control server.
|
|
145
|
+
if (this.hasCrossOriginHeader(req)) {
|
|
146
|
+
this.sendJson(res, 403, { error: 'Cross-origin request rejected' });
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
// Route requests
|
|
151
|
+
if (path === '/health' || path === '/_health') {
|
|
152
|
+
this.handleHealth(res);
|
|
153
|
+
}
|
|
154
|
+
else if (path === '/status') {
|
|
155
|
+
if (!this.authorized(req, res))
|
|
156
|
+
return;
|
|
157
|
+
this.handleStatus(res);
|
|
158
|
+
}
|
|
159
|
+
else if (path === '/pause' && method === 'POST') {
|
|
160
|
+
if (!this.authorized(req, res))
|
|
161
|
+
return;
|
|
162
|
+
this.handlePause(res);
|
|
163
|
+
}
|
|
164
|
+
else if (path === '/resume' && method === 'POST') {
|
|
165
|
+
if (!this.authorized(req, res))
|
|
166
|
+
return;
|
|
167
|
+
this.handleResume(res);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
this.sendJson(res, 404, { error: 'Not found', path });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
this.sendJson(res, 500, { error: error.message });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/** True if a host string is a loopback address. */
|
|
178
|
+
isLoopback(host) {
|
|
179
|
+
return host === 'localhost' || host === '127.0.0.1' || host === '::1';
|
|
180
|
+
}
|
|
181
|
+
/** True if the request carries an Origin header pointing at another origin. */
|
|
182
|
+
hasCrossOriginHeader(req) {
|
|
183
|
+
const origin = req.headers.origin;
|
|
184
|
+
if (!origin || typeof origin !== 'string')
|
|
185
|
+
return false;
|
|
186
|
+
const host = req.headers.host;
|
|
187
|
+
try {
|
|
188
|
+
const originHost = new URL(origin).host;
|
|
189
|
+
return originHost !== host;
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// Unparseable Origin — treat as cross-origin (reject).
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Enforce the shared-secret token on protected endpoints. When no token is
|
|
198
|
+
* configured, allow (the loopback bind + CSRF check are the baseline) but
|
|
199
|
+
* warn so operators know /status state is exposed locally.
|
|
200
|
+
*/
|
|
201
|
+
authorized(req, res) {
|
|
202
|
+
if (!this.config.authToken) {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
const header = req.headers.authorization;
|
|
206
|
+
const expected = `Bearer ${this.config.authToken}`;
|
|
207
|
+
if (typeof header !== 'string' || !this.safeEqual(header, expected)) {
|
|
208
|
+
this.sendJson(res, 401, { error: 'Unauthorized' });
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Constant-time string comparison. Avoids the timing oracle of `a !== b`,
|
|
215
|
+
* which short-circuits on the first differing byte and can leak the token
|
|
216
|
+
* prefix. Length is compared first (and non-constant-time), which only
|
|
217
|
+
* reveals the token length — not its contents.
|
|
218
|
+
*/
|
|
219
|
+
safeEqual(a, b) {
|
|
220
|
+
const bufA = Buffer.from(a);
|
|
221
|
+
const bufB = Buffer.from(b);
|
|
222
|
+
if (bufA.length !== bufB.length) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
return timingSafeEqual(bufA, bufB);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Handle health check
|
|
229
|
+
*/
|
|
230
|
+
handleHealth(res) {
|
|
231
|
+
this.sendJson(res, 200, {
|
|
232
|
+
status: 'ok',
|
|
233
|
+
timestamp: new Date().toISOString(),
|
|
234
|
+
uptime: Date.now() - this.startTime,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Handle status query
|
|
239
|
+
*/
|
|
240
|
+
handleStatus(res) {
|
|
241
|
+
this.callbacks.onStatusQueried?.();
|
|
242
|
+
const response = {
|
|
243
|
+
execution: this.executionState,
|
|
244
|
+
progress: this.liveProgress,
|
|
245
|
+
pauseRequested: this.pauseRequested,
|
|
246
|
+
uptime: Date.now() - this.startTime,
|
|
247
|
+
timestamp: new Date().toISOString(),
|
|
248
|
+
};
|
|
249
|
+
this.sendJson(res, 200, response);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Handle pause request
|
|
253
|
+
*/
|
|
254
|
+
handlePause(res) {
|
|
255
|
+
if (this.pauseRequested) {
|
|
256
|
+
const response = {
|
|
257
|
+
success: true,
|
|
258
|
+
message: 'Pause already requested',
|
|
259
|
+
pauseRequested: true,
|
|
260
|
+
};
|
|
261
|
+
this.sendJson(res, 200, response);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
this.pauseRequested = true;
|
|
265
|
+
this.callbacks.onPauseRequested?.();
|
|
266
|
+
this.log('Pause requested');
|
|
267
|
+
const response = {
|
|
268
|
+
success: true,
|
|
269
|
+
message: 'Pause requested. Execution will pause at next safe point.',
|
|
270
|
+
pauseRequested: true,
|
|
271
|
+
};
|
|
272
|
+
this.sendJson(res, 200, response);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Handle resume request
|
|
276
|
+
*/
|
|
277
|
+
handleResume(res) {
|
|
278
|
+
if (!this.pauseRequested) {
|
|
279
|
+
const response = {
|
|
280
|
+
success: true,
|
|
281
|
+
message: 'No pause was requested',
|
|
282
|
+
pauseRequested: false,
|
|
283
|
+
};
|
|
284
|
+
this.sendJson(res, 200, response);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
this.pauseRequested = false;
|
|
288
|
+
this.callbacks.onResumeRequested?.();
|
|
289
|
+
this.log('Pause request cleared');
|
|
290
|
+
const response = {
|
|
291
|
+
success: true,
|
|
292
|
+
message: 'Pause request cleared. Use --resume flag to resume execution.',
|
|
293
|
+
pauseRequested: false,
|
|
294
|
+
};
|
|
295
|
+
this.sendJson(res, 200, response);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Send JSON response
|
|
299
|
+
*/
|
|
300
|
+
sendJson(res, status, data) {
|
|
301
|
+
// Close the connection after each response. This localhost admin server has
|
|
302
|
+
// no need for keep-alive, and avoiding pooled sockets removes a client-side
|
|
303
|
+
// socket-reuse race (intermittent ECONNRESET on rapid sequential requests).
|
|
304
|
+
res.writeHead(status, { 'Content-Type': 'application/json', Connection: 'close' });
|
|
305
|
+
res.end(JSON.stringify(data, null, 2));
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Log message if verbose mode enabled
|
|
309
|
+
*/
|
|
310
|
+
log(message) {
|
|
311
|
+
if (this.config.verbose) {
|
|
312
|
+
console.log(`[Control] ${message}`);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Control Server Types
|
|
3
|
+
*
|
|
4
|
+
* Types for the HTTP control server that enables
|
|
5
|
+
* pause/resume and live status queries.
|
|
6
|
+
*/
|
|
7
|
+
import type { ExecutionState, LiveProgress } from '../execution/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for the control server
|
|
10
|
+
*/
|
|
11
|
+
export interface ControlServerConfig {
|
|
12
|
+
/** Port to listen on (default: 3001) */
|
|
13
|
+
port?: number;
|
|
14
|
+
/** Host to bind to (default: localhost) */
|
|
15
|
+
host?: string;
|
|
16
|
+
/** Enable verbose logging */
|
|
17
|
+
verbose?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Shared secret required on state-changing endpoints (/pause, /resume) and
|
|
20
|
+
* /status. When set, requests must present `Authorization: Bearer <secret>`
|
|
21
|
+
* or they are rejected with 401.
|
|
22
|
+
*/
|
|
23
|
+
authToken?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Callbacks for control server events
|
|
27
|
+
*/
|
|
28
|
+
export interface ControlServerCallbacks {
|
|
29
|
+
/** Called when pause is requested */
|
|
30
|
+
onPauseRequested?: () => void;
|
|
31
|
+
/** Called when resume is requested */
|
|
32
|
+
onResumeRequested?: () => void;
|
|
33
|
+
/** Called when status is queried */
|
|
34
|
+
onStatusQueried?: () => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Response for status endpoint
|
|
38
|
+
*/
|
|
39
|
+
export interface StatusResponse {
|
|
40
|
+
/** Execution state (if available) */
|
|
41
|
+
execution?: ExecutionState;
|
|
42
|
+
/** Live progress (if available) */
|
|
43
|
+
progress?: LiveProgress;
|
|
44
|
+
/** Whether pause has been requested */
|
|
45
|
+
pauseRequested: boolean;
|
|
46
|
+
/** Server uptime in milliseconds */
|
|
47
|
+
uptime: number;
|
|
48
|
+
/** Timestamp of this response */
|
|
49
|
+
timestamp: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Response for pause/resume endpoints
|
|
53
|
+
*/
|
|
54
|
+
export interface ControlResponse {
|
|
55
|
+
/** Whether the operation succeeded */
|
|
56
|
+
success: boolean;
|
|
57
|
+
/** Optional message */
|
|
58
|
+
message?: string;
|
|
59
|
+
/** Whether pause is currently requested */
|
|
60
|
+
pauseRequested: boolean;
|
|
61
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Debugger - Interactive readline-based debugger for terminal use
|
|
3
|
+
*/
|
|
4
|
+
import type { DebugCommand, DebugSnapshot } from './controller.js';
|
|
5
|
+
import { BaseDebugController } from './controller.js';
|
|
6
|
+
export declare class CLIDebugger extends BaseDebugController {
|
|
7
|
+
private rl;
|
|
8
|
+
private closed;
|
|
9
|
+
constructor();
|
|
10
|
+
pause(snapshot: DebugSnapshot): Promise<DebugCommand>;
|
|
11
|
+
private printSnapshot;
|
|
12
|
+
private formatValue;
|
|
13
|
+
private promptCommand;
|
|
14
|
+
private parseCommand;
|
|
15
|
+
private printHelp;
|
|
16
|
+
close(): void;
|
|
17
|
+
}
|