mewkit 1.15.0 → 1.16.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/NOTICE +24 -0
- package/README.md +29 -70
- package/dist/commands/visual-plan.d.ts +23 -0
- package/dist/commands/visual-plan.d.ts.map +1 -0
- package/dist/commands/visual-plan.js +26 -0
- package/dist/commands/visual-plan.js.map +1 -0
- package/dist/core/capability.d.ts +81 -81
- package/dist/core/consolidation-ledger.d.ts.map +1 -1
- package/dist/core/consolidation-ledger.js +13 -11
- package/dist/core/consolidation-ledger.js.map +1 -1
- package/dist/core/install-metadata.d.ts +27 -27
- package/dist/core/plugin-manifest.d.ts +16 -16
- package/dist/core/release-metadata.d.ts +2 -2
- package/dist/core/task-record.d.ts +8 -8
- package/dist/index.js +33 -21
- package/dist/index.js.map +1 -1
- package/dist/local-web/atomic-write.d.ts +15 -0
- package/dist/local-web/atomic-write.d.ts.map +1 -0
- package/dist/local-web/atomic-write.js +69 -0
- package/dist/local-web/atomic-write.js.map +1 -0
- package/dist/local-web/constants.d.ts +13 -0
- package/dist/local-web/constants.d.ts.map +1 -0
- package/dist/local-web/constants.js +13 -0
- package/dist/local-web/constants.js.map +1 -0
- package/dist/local-web/etag.d.ts +19 -0
- package/dist/local-web/etag.d.ts.map +1 -0
- package/dist/local-web/etag.js +32 -0
- package/dist/local-web/etag.js.map +1 -0
- package/dist/local-web/host-guard.d.ts +12 -0
- package/dist/local-web/host-guard.d.ts.map +1 -0
- package/dist/local-web/host-guard.js +18 -0
- package/dist/local-web/host-guard.js.map +1 -0
- package/dist/local-web/index.d.ts +23 -0
- package/dist/local-web/index.d.ts.map +1 -0
- package/dist/local-web/index.js +23 -0
- package/dist/local-web/index.js.map +1 -0
- package/dist/local-web/local-server.d.ts +37 -0
- package/dist/local-web/local-server.d.ts.map +1 -0
- package/dist/local-web/local-server.js +85 -0
- package/dist/local-web/local-server.js.map +1 -0
- package/dist/local-web/open-browser.d.ts +12 -0
- package/dist/local-web/open-browser.d.ts.map +1 -0
- package/dist/{orchviz/open-url.js → local-web/open-browser.js} +9 -8
- package/dist/local-web/open-browser.js.map +1 -0
- package/dist/local-web/origin-guard.d.ts +11 -0
- package/dist/local-web/origin-guard.d.ts.map +1 -0
- package/dist/local-web/origin-guard.js +15 -0
- package/dist/local-web/origin-guard.js.map +1 -0
- package/dist/local-web/path-boundary.d.ts +20 -0
- package/dist/local-web/path-boundary.d.ts.map +1 -0
- package/dist/local-web/path-boundary.js +39 -0
- package/dist/local-web/path-boundary.js.map +1 -0
- package/dist/local-web/request-body.d.ts +24 -0
- package/dist/local-web/request-body.d.ts.map +1 -0
- package/dist/local-web/request-body.js +68 -0
- package/dist/local-web/request-body.js.map +1 -0
- package/dist/local-web/static-handler.d.ts +14 -0
- package/dist/local-web/static-handler.d.ts.map +1 -0
- package/dist/{orchviz/server → local-web}/static-handler.js +11 -6
- package/dist/local-web/static-handler.js.map +1 -0
- package/dist/migrate/reconcile/portable-manifest.d.ts +12 -12
- package/dist/migrate/reconcile/portable-registry.d.ts +24 -24
- package/dist/migrate/types.d.ts +10 -10
- package/dist/{orchviz/token-estimator.d.ts → token-estimator/index.d.ts} +6 -1
- package/dist/token-estimator/index.d.ts.map +1 -0
- package/dist/{orchviz/token-estimator.js → token-estimator/index.js} +11 -2
- package/dist/token-estimator/index.js.map +1 -0
- package/dist/visual-plan/__fixtures__/valid-plan.d.ts +15 -0
- package/dist/visual-plan/__fixtures__/valid-plan.d.ts.map +1 -0
- package/dist/visual-plan/__fixtures__/valid-plan.js +79 -0
- package/dist/visual-plan/__fixtures__/valid-plan.js.map +1 -0
- package/dist/visual-plan/application/apply-feedback.d.ts +31 -0
- package/dist/visual-plan/application/apply-feedback.d.ts.map +1 -0
- package/dist/visual-plan/application/apply-feedback.js +85 -0
- package/dist/visual-plan/application/apply-feedback.js.map +1 -0
- package/dist/visual-plan/application/apply-patch-op.d.ts +13 -0
- package/dist/visual-plan/application/apply-patch-op.d.ts.map +1 -0
- package/dist/visual-plan/application/apply-patch-op.js +72 -0
- package/dist/visual-plan/application/apply-patch-op.js.map +1 -0
- package/dist/visual-plan/application/approve.d.ts +24 -0
- package/dist/visual-plan/application/approve.d.ts.map +1 -0
- package/dist/visual-plan/application/approve.js +53 -0
- package/dist/visual-plan/application/approve.js.map +1 -0
- package/dist/visual-plan/application/clock.d.ts +8 -0
- package/dist/visual-plan/application/clock.d.ts.map +1 -0
- package/dist/visual-plan/application/clock.js +10 -0
- package/dist/visual-plan/application/clock.js.map +1 -0
- package/dist/visual-plan/application/export-plan.d.ts +19 -0
- package/dist/visual-plan/application/export-plan.d.ts.map +1 -0
- package/dist/visual-plan/application/export-plan.js +59 -0
- package/dist/visual-plan/application/export-plan.js.map +1 -0
- package/dist/visual-plan/application/patch-plan.d.ts +26 -0
- package/dist/visual-plan/application/patch-plan.d.ts.map +1 -0
- package/dist/visual-plan/application/patch-plan.js +48 -0
- package/dist/visual-plan/application/patch-plan.js.map +1 -0
- package/dist/visual-plan/application/prepare-feedback.d.ts +24 -0
- package/dist/visual-plan/application/prepare-feedback.d.ts.map +1 -0
- package/dist/visual-plan/application/prepare-feedback.js +70 -0
- package/dist/visual-plan/application/prepare-feedback.js.map +1 -0
- package/dist/visual-plan/application/rehash.d.ts +19 -0
- package/dist/visual-plan/application/rehash.d.ts.map +1 -0
- package/dist/visual-plan/application/rehash.js +43 -0
- package/dist/visual-plan/application/rehash.js.map +1 -0
- package/dist/visual-plan/application/status.d.ts +20 -0
- package/dist/visual-plan/application/status.d.ts.map +1 -0
- package/dist/visual-plan/application/status.js +27 -0
- package/dist/visual-plan/application/status.js.map +1 -0
- package/dist/visual-plan/application/validate-plan.d.ts +30 -0
- package/dist/visual-plan/application/validate-plan.d.ts.map +1 -0
- package/dist/visual-plan/application/validate-plan.js +59 -0
- package/dist/visual-plan/application/validate-plan.js.map +1 -0
- package/dist/visual-plan/domain/coverage.d.ts +35 -0
- package/dist/visual-plan/domain/coverage.d.ts.map +1 -0
- package/dist/visual-plan/domain/coverage.js +99 -0
- package/dist/visual-plan/domain/coverage.js.map +1 -0
- package/dist/visual-plan/domain/cross-refs.d.ts +20 -0
- package/dist/visual-plan/domain/cross-refs.d.ts.map +1 -0
- package/dist/visual-plan/domain/cross-refs.js +92 -0
- package/dist/visual-plan/domain/cross-refs.js.map +1 -0
- package/dist/visual-plan/domain/errors.d.ts +43 -0
- package/dist/visual-plan/domain/errors.d.ts.map +1 -0
- package/dist/visual-plan/domain/errors.js +33 -0
- package/dist/visual-plan/domain/errors.js.map +1 -0
- package/dist/visual-plan/domain/feedback-schemas.d.ts +160 -0
- package/dist/visual-plan/domain/feedback-schemas.d.ts.map +1 -0
- package/dist/visual-plan/domain/feedback-schemas.js +71 -0
- package/dist/visual-plan/domain/feedback-schemas.js.map +1 -0
- package/dist/visual-plan/domain/ids.d.ts +21 -0
- package/dist/visual-plan/domain/ids.d.ts.map +1 -0
- package/dist/visual-plan/domain/ids.js +25 -0
- package/dist/visual-plan/domain/ids.js.map +1 -0
- package/dist/visual-plan/domain/patches.d.ts +176 -0
- package/dist/visual-plan/domain/patches.d.ts.map +1 -0
- package/dist/visual-plan/domain/patches.js +41 -0
- package/dist/visual-plan/domain/patches.js.map +1 -0
- package/dist/visual-plan/domain/sanitizer-config.d.ts +61 -0
- package/dist/visual-plan/domain/sanitizer-config.d.ts.map +1 -0
- package/dist/visual-plan/domain/sanitizer-config.js +70 -0
- package/dist/visual-plan/domain/sanitizer-config.js.map +1 -0
- package/dist/visual-plan/domain/schemas.d.ts +1492 -0
- package/dist/visual-plan/domain/schemas.d.ts.map +1 -0
- package/dist/visual-plan/domain/schemas.js +166 -0
- package/dist/visual-plan/domain/schemas.js.map +1 -0
- package/dist/visual-plan/infrastructure/atomic-write.d.ts +11 -0
- package/dist/visual-plan/infrastructure/atomic-write.d.ts.map +1 -0
- package/dist/visual-plan/infrastructure/atomic-write.js +44 -0
- package/dist/visual-plan/infrastructure/atomic-write.js.map +1 -0
- package/dist/visual-plan/infrastructure/feedback-repository.d.ts +18 -0
- package/dist/visual-plan/infrastructure/feedback-repository.d.ts.map +1 -0
- package/dist/visual-plan/infrastructure/feedback-repository.js +59 -0
- package/dist/visual-plan/infrastructure/feedback-repository.js.map +1 -0
- package/dist/visual-plan/infrastructure/hashing.d.ts +37 -0
- package/dist/visual-plan/infrastructure/hashing.d.ts.map +1 -0
- package/dist/visual-plan/infrastructure/hashing.js +81 -0
- package/dist/visual-plan/infrastructure/hashing.js.map +1 -0
- package/dist/visual-plan/infrastructure/plan-state.d.ts +32 -0
- package/dist/visual-plan/infrastructure/plan-state.d.ts.map +1 -0
- package/dist/visual-plan/infrastructure/plan-state.js +58 -0
- package/dist/visual-plan/infrastructure/plan-state.js.map +1 -0
- package/dist/visual-plan/infrastructure/receipt-repository.d.ts +17 -0
- package/dist/visual-plan/infrastructure/receipt-repository.d.ts.map +1 -0
- package/dist/visual-plan/infrastructure/receipt-repository.js +59 -0
- package/dist/visual-plan/infrastructure/receipt-repository.js.map +1 -0
- package/dist/visual-plan/infrastructure/visual-plan-repository.d.ts +38 -0
- package/dist/visual-plan/infrastructure/visual-plan-repository.d.ts.map +1 -0
- package/dist/visual-plan/infrastructure/visual-plan-repository.js +97 -0
- package/dist/visual-plan/infrastructure/visual-plan-repository.js.map +1 -0
- package/dist/visual-plan/infrastructure/wireframe-sanitizer.d.ts +41 -0
- package/dist/visual-plan/infrastructure/wireframe-sanitizer.d.ts.map +1 -0
- package/dist/visual-plan/infrastructure/wireframe-sanitizer.js +72 -0
- package/dist/visual-plan/infrastructure/wireframe-sanitizer.js.map +1 -0
- package/dist/visual-plan/interface/cli.d.ts +29 -0
- package/dist/visual-plan/interface/cli.d.ts.map +1 -0
- package/dist/visual-plan/interface/cli.js +280 -0
- package/dist/visual-plan/interface/cli.js.map +1 -0
- package/dist/visual-plan/interface/studio.d.ts +20 -0
- package/dist/visual-plan/interface/studio.d.ts.map +1 -0
- package/dist/visual-plan/interface/studio.js +74 -0
- package/dist/visual-plan/interface/studio.js.map +1 -0
- package/dist/visual-plan/server/csp.d.ts +13 -0
- package/dist/visual-plan/server/csp.d.ts.map +1 -0
- package/dist/visual-plan/server/csp.js +17 -0
- package/dist/visual-plan/server/csp.js.map +1 -0
- package/dist/visual-plan/server/edit-lock.d.ts +28 -0
- package/dist/visual-plan/server/edit-lock.d.ts.map +1 -0
- package/dist/visual-plan/server/edit-lock.js +71 -0
- package/dist/visual-plan/server/edit-lock.js.map +1 -0
- package/dist/visual-plan/server/routes/feedback.d.ts +12 -0
- package/dist/visual-plan/server/routes/feedback.d.ts.map +1 -0
- package/dist/visual-plan/server/routes/feedback.js +63 -0
- package/dist/visual-plan/server/routes/feedback.js.map +1 -0
- package/dist/visual-plan/server/routes/get-plan.d.ts +14 -0
- package/dist/visual-plan/server/routes/get-plan.d.ts.map +1 -0
- package/dist/visual-plan/server/routes/get-plan.js +38 -0
- package/dist/visual-plan/server/routes/get-plan.js.map +1 -0
- package/dist/visual-plan/server/routes/patch.d.ts +10 -0
- package/dist/visual-plan/server/routes/patch.d.ts.map +1 -0
- package/dist/visual-plan/server/routes/patch.js +66 -0
- package/dist/visual-plan/server/routes/patch.js.map +1 -0
- package/dist/visual-plan/server/visual-plan-server.d.ts +30 -0
- package/dist/visual-plan/server/visual-plan-server.d.ts.map +1 -0
- package/dist/visual-plan/server/visual-plan-server.js +79 -0
- package/dist/visual-plan/server/visual-plan-server.js.map +1 -0
- package/dist/visual-plan-web/architects-daughter-latin-400-normal.woff +0 -0
- package/dist/visual-plan-web/architects-daughter-latin-400-normal.woff2 +0 -0
- package/dist/visual-plan-web/architects-daughter-latin-ext-400-normal.woff +0 -0
- package/dist/visual-plan-web/architects-daughter-latin-ext-400-normal.woff2 +0 -0
- package/dist/visual-plan-web/index.css +1 -0
- package/dist/visual-plan-web/index.html +17 -0
- package/dist/visual-plan-web/index.js +51 -0
- package/package.json +14 -17
- package/dist/commands/orchviz.d.ts +0 -12
- package/dist/commands/orchviz.d.ts.map +0 -1
- package/dist/commands/orchviz.js +0 -157
- package/dist/commands/orchviz.js.map +0 -1
- package/dist/migrate/converters/md-to-codex-rules.d.ts +0 -10
- package/dist/migrate/converters/md-to-codex-rules.d.ts.map +0 -1
- package/dist/migrate/converters/md-to-codex-rules.js +0 -133
- package/dist/migrate/converters/md-to-codex-rules.js.map +0 -1
- package/dist/orchviz/constants.d.ts +0 -72
- package/dist/orchviz/constants.d.ts.map +0 -1
- package/dist/orchviz/constants.js +0 -105
- package/dist/orchviz/constants.js.map +0 -1
- package/dist/orchviz/fs-utils.d.ts +0 -24
- package/dist/orchviz/fs-utils.d.ts.map +0 -1
- package/dist/orchviz/fs-utils.js +0 -49
- package/dist/orchviz/fs-utils.js.map +0 -1
- package/dist/orchviz/index.d.ts +0 -29
- package/dist/orchviz/index.d.ts.map +0 -1
- package/dist/orchviz/index.js +0 -28
- package/dist/orchviz/index.js.map +0 -1
- package/dist/orchviz/log-persister.d.ts +0 -22
- package/dist/orchviz/log-persister.d.ts.map +0 -1
- package/dist/orchviz/log-persister.js +0 -96
- package/dist/orchviz/log-persister.js.map +0 -1
- package/dist/orchviz/logger.d.ts +0 -13
- package/dist/orchviz/logger.d.ts.map +0 -1
- package/dist/orchviz/logger.js +0 -47
- package/dist/orchviz/logger.js.map +0 -1
- package/dist/orchviz/open-url.d.ts +0 -11
- package/dist/orchviz/open-url.d.ts.map +0 -1
- package/dist/orchviz/open-url.js.map +0 -1
- package/dist/orchviz/overlay/collector.d.ts +0 -29
- package/dist/orchviz/overlay/collector.d.ts.map +0 -1
- package/dist/orchviz/overlay/collector.js +0 -38
- package/dist/orchviz/overlay/collector.js.map +0 -1
- package/dist/orchviz/overlay/gate-readers.d.ts +0 -18
- package/dist/orchviz/overlay/gate-readers.d.ts.map +0 -1
- package/dist/orchviz/overlay/gate-readers.js +0 -111
- package/dist/orchviz/overlay/gate-readers.js.map +0 -1
- package/dist/orchviz/overlay/session-state-readers.d.ts +0 -18
- package/dist/orchviz/overlay/session-state-readers.d.ts.map +0 -1
- package/dist/orchviz/overlay/session-state-readers.js +0 -78
- package/dist/orchviz/overlay/session-state-readers.js.map +0 -1
- package/dist/orchviz/parser/handle-progress.d.ts +0 -9
- package/dist/orchviz/parser/handle-progress.d.ts.map +0 -1
- package/dist/orchviz/parser/handle-progress.js +0 -38
- package/dist/orchviz/parser/handle-progress.js.map +0 -1
- package/dist/orchviz/parser/handle-system.d.ts +0 -22
- package/dist/orchviz/parser/handle-system.d.ts.map +0 -1
- package/dist/orchviz/parser/handle-system.js +0 -99
- package/dist/orchviz/parser/handle-system.js.map +0 -1
- package/dist/orchviz/parser/handle-text.d.ts +0 -10
- package/dist/orchviz/parser/handle-text.d.ts.map +0 -1
- package/dist/orchviz/parser/handle-text.js +0 -83
- package/dist/orchviz/parser/handle-text.js.map +0 -1
- package/dist/orchviz/parser/handle-thinking.d.ts +0 -10
- package/dist/orchviz/parser/handle-thinking.d.ts.map +0 -1
- package/dist/orchviz/parser/handle-thinking.js +0 -35
- package/dist/orchviz/parser/handle-thinking.js.map +0 -1
- package/dist/orchviz/parser/handle-tool-result.d.ts +0 -10
- package/dist/orchviz/parser/handle-tool-result.d.ts.map +0 -1
- package/dist/orchviz/parser/handle-tool-result.js +0 -130
- package/dist/orchviz/parser/handle-tool-result.js.map +0 -1
- package/dist/orchviz/parser/handle-tool-use.d.ts +0 -11
- package/dist/orchviz/parser/handle-tool-use.d.ts.map +0 -1
- package/dist/orchviz/parser/handle-tool-use.js +0 -120
- package/dist/orchviz/parser/handle-tool-use.js.map +0 -1
- package/dist/orchviz/parser/index.d.ts +0 -38
- package/dist/orchviz/parser/index.d.ts.map +0 -1
- package/dist/orchviz/parser/index.js +0 -144
- package/dist/orchviz/parser/index.js.map +0 -1
- package/dist/orchviz/parser/label-helpers.d.ts +0 -9
- package/dist/orchviz/parser/label-helpers.d.ts.map +0 -1
- package/dist/orchviz/parser/label-helpers.js +0 -44
- package/dist/orchviz/parser/label-helpers.js.map +0 -1
- package/dist/orchviz/parser/strip-ansi.d.ts +0 -6
- package/dist/orchviz/parser/strip-ansi.d.ts.map +0 -1
- package/dist/orchviz/parser/strip-ansi.js +0 -14
- package/dist/orchviz/parser/strip-ansi.js.map +0 -1
- package/dist/orchviz/parser/utils.d.ts +0 -20
- package/dist/orchviz/parser/utils.d.ts.map +0 -1
- package/dist/orchviz/parser/utils.js +0 -54
- package/dist/orchviz/parser/utils.js.map +0 -1
- package/dist/orchviz/permission-detection.d.ts +0 -32
- package/dist/orchviz/permission-detection.d.ts.map +0 -1
- package/dist/orchviz/permission-detection.js +0 -104
- package/dist/orchviz/permission-detection.js.map +0 -1
- package/dist/orchviz/plan/apply-todo-toggle.d.ts +0 -29
- package/dist/orchviz/plan/apply-todo-toggle.d.ts.map +0 -1
- package/dist/orchviz/plan/apply-todo-toggle.js +0 -129
- package/dist/orchviz/plan/apply-todo-toggle.js.map +0 -1
- package/dist/orchviz/plan/atomic-write.d.ts +0 -25
- package/dist/orchviz/plan/atomic-write.d.ts.map +0 -1
- package/dist/orchviz/plan/atomic-write.js +0 -85
- package/dist/orchviz/plan/atomic-write.js.map +0 -1
- package/dist/orchviz/plan/collector.d.ts +0 -49
- package/dist/orchviz/plan/collector.d.ts.map +0 -1
- package/dist/orchviz/plan/collector.js +0 -169
- package/dist/orchviz/plan/collector.js.map +0 -1
- package/dist/orchviz/plan/etag.d.ts +0 -24
- package/dist/orchviz/plan/etag.d.ts.map +0 -1
- package/dist/orchviz/plan/etag.js +0 -58
- package/dist/orchviz/plan/etag.js.map +0 -1
- package/dist/orchviz/plan/find-active-plan.d.ts +0 -9
- package/dist/orchviz/plan/find-active-plan.d.ts.map +0 -1
- package/dist/orchviz/plan/find-active-plan.js +0 -90
- package/dist/orchviz/plan/find-active-plan.js.map +0 -1
- package/dist/orchviz/plan/index.d.ts +0 -23
- package/dist/orchviz/plan/index.d.ts.map +0 -1
- package/dist/orchviz/plan/index.js +0 -91
- package/dist/orchviz/plan/index.js.map +0 -1
- package/dist/orchviz/plan/list-plans.d.ts +0 -19
- package/dist/orchviz/plan/list-plans.d.ts.map +0 -1
- package/dist/orchviz/plan/list-plans.js +0 -143
- package/dist/orchviz/plan/list-plans.js.map +0 -1
- package/dist/orchviz/plan/parse-phase-file.d.ts +0 -13
- package/dist/orchviz/plan/parse-phase-file.d.ts.map +0 -1
- package/dist/orchviz/plan/parse-phase-file.js +0 -134
- package/dist/orchviz/plan/parse-phase-file.js.map +0 -1
- package/dist/orchviz/plan/parse-plan-file.d.ts +0 -19
- package/dist/orchviz/plan/parse-plan-file.d.ts.map +0 -1
- package/dist/orchviz/plan/parse-plan-file.js +0 -62
- package/dist/orchviz/plan/parse-plan-file.js.map +0 -1
- package/dist/orchviz/plan/plan-constants.d.ts +0 -17
- package/dist/orchviz/plan/plan-constants.d.ts.map +0 -1
- package/dist/orchviz/plan/plan-constants.js +0 -19
- package/dist/orchviz/plan/plan-constants.js.map +0 -1
- package/dist/orchviz/plan/plan-lifecycle.d.ts +0 -17
- package/dist/orchviz/plan/plan-lifecycle.d.ts.map +0 -1
- package/dist/orchviz/plan/plan-lifecycle.js +0 -97
- package/dist/orchviz/plan/plan-lifecycle.js.map +0 -1
- package/dist/orchviz/plan/types.d.ts +0 -46
- package/dist/orchviz/plan/types.d.ts.map +0 -1
- package/dist/orchviz/plan/types.js +0 -6
- package/dist/orchviz/plan/types.js.map +0 -1
- package/dist/orchviz/protocol.d.ts +0 -171
- package/dist/orchviz/protocol.d.ts.map +0 -1
- package/dist/orchviz/protocol.js +0 -23
- package/dist/orchviz/protocol.js.map +0 -1
- package/dist/orchviz/redact.d.ts +0 -10
- package/dist/orchviz/redact.d.ts.map +0 -1
- package/dist/orchviz/redact.js +0 -38
- package/dist/orchviz/redact.js.map +0 -1
- package/dist/orchviz/sanitize.d.ts +0 -11
- package/dist/orchviz/sanitize.d.ts.map +0 -1
- package/dist/orchviz/sanitize.js +0 -38
- package/dist/orchviz/sanitize.js.map +0 -1
- package/dist/orchviz/server/api-handlers.d.ts +0 -55
- package/dist/orchviz/server/api-handlers.d.ts.map +0 -1
- package/dist/orchviz/server/api-handlers.js +0 -112
- package/dist/orchviz/server/api-handlers.js.map +0 -1
- package/dist/orchviz/server/index.d.ts +0 -36
- package/dist/orchviz/server/index.d.ts.map +0 -1
- package/dist/orchviz/server/index.js +0 -144
- package/dist/orchviz/server/index.js.map +0 -1
- package/dist/orchviz/server/sse-handler.d.ts +0 -28
- package/dist/orchviz/server/sse-handler.d.ts.map +0 -1
- package/dist/orchviz/server/sse-handler.js +0 -217
- package/dist/orchviz/server/sse-handler.js.map +0 -1
- package/dist/orchviz/server/static-handler.d.ts +0 -9
- package/dist/orchviz/server/static-handler.d.ts.map +0 -1
- package/dist/orchviz/server/static-handler.js.map +0 -1
- package/dist/orchviz/server/write-handlers.d.ts +0 -20
- package/dist/orchviz/server/write-handlers.d.ts.map +0 -1
- package/dist/orchviz/server/write-handlers.js +0 -184
- package/dist/orchviz/server/write-handlers.js.map +0 -1
- package/dist/orchviz/server/write-utils.d.ts +0 -59
- package/dist/orchviz/server/write-utils.d.ts.map +0 -1
- package/dist/orchviz/server/write-utils.js +0 -161
- package/dist/orchviz/server/write-utils.js.map +0 -1
- package/dist/orchviz/session-discovery.d.ts +0 -19
- package/dist/orchviz/session-discovery.d.ts.map +0 -1
- package/dist/orchviz/session-discovery.js +0 -104
- package/dist/orchviz/session-discovery.js.map +0 -1
- package/dist/orchviz/session-manager.d.ts +0 -17
- package/dist/orchviz/session-manager.d.ts.map +0 -1
- package/dist/orchviz/session-manager.js +0 -63
- package/dist/orchviz/session-manager.js.map +0 -1
- package/dist/orchviz/session-runtime.d.ts +0 -21
- package/dist/orchviz/session-runtime.d.ts.map +0 -1
- package/dist/orchviz/session-runtime.js +0 -135
- package/dist/orchviz/session-runtime.js.map +0 -1
- package/dist/orchviz/session-watcher.d.ts +0 -33
- package/dist/orchviz/session-watcher.d.ts.map +0 -1
- package/dist/orchviz/session-watcher.js +0 -135
- package/dist/orchviz/session-watcher.js.map +0 -1
- package/dist/orchviz/subagent-meta.d.ts +0 -12
- package/dist/orchviz/subagent-meta.d.ts.map +0 -1
- package/dist/orchviz/subagent-meta.js +0 -34
- package/dist/orchviz/subagent-meta.js.map +0 -1
- package/dist/orchviz/subagent-scanner.d.ts +0 -15
- package/dist/orchviz/subagent-scanner.d.ts.map +0 -1
- package/dist/orchviz/subagent-scanner.js +0 -27
- package/dist/orchviz/subagent-scanner.js.map +0 -1
- package/dist/orchviz/subagent-watcher.d.ts +0 -20
- package/dist/orchviz/subagent-watcher.d.ts.map +0 -1
- package/dist/orchviz/subagent-watcher.js +0 -160
- package/dist/orchviz/subagent-watcher.js.map +0 -1
- package/dist/orchviz/token-estimator.d.ts.map +0 -1
- package/dist/orchviz/token-estimator.js.map +0 -1
- package/dist/orchviz/tool-input-data.d.ts +0 -11
- package/dist/orchviz/tool-input-data.d.ts.map +0 -1
- package/dist/orchviz/tool-input-data.js +0 -74
- package/dist/orchviz/tool-input-data.js.map +0 -1
- package/dist/orchviz/tool-summarizer.d.ts +0 -16
- package/dist/orchviz/tool-summarizer.d.ts.map +0 -1
- package/dist/orchviz/tool-summarizer.js +0 -129
- package/dist/orchviz/tool-summarizer.js.map +0 -1
- package/dist/orchviz-web/fira-code-cyrillic-400-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-cyrillic-400-normal.woff2 +0 -0
- package/dist/orchviz-web/fira-code-cyrillic-500-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-cyrillic-500-normal.woff2 +0 -0
- package/dist/orchviz-web/fira-code-cyrillic-ext-400-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/orchviz-web/fira-code-cyrillic-ext-500-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-cyrillic-ext-500-normal.woff2 +0 -0
- package/dist/orchviz-web/fira-code-greek-400-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-greek-400-normal.woff2 +0 -0
- package/dist/orchviz-web/fira-code-greek-500-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-greek-500-normal.woff2 +0 -0
- package/dist/orchviz-web/fira-code-greek-ext-400-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-greek-ext-400-normal.woff2 +0 -0
- package/dist/orchviz-web/fira-code-greek-ext-500-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-greek-ext-500-normal.woff2 +0 -0
- package/dist/orchviz-web/fira-code-latin-400-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-latin-400-normal.woff2 +0 -0
- package/dist/orchviz-web/fira-code-latin-500-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-latin-500-normal.woff2 +0 -0
- package/dist/orchviz-web/fira-code-latin-ext-400-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-latin-ext-400-normal.woff2 +0 -0
- package/dist/orchviz-web/fira-code-latin-ext-500-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-latin-ext-500-normal.woff2 +0 -0
- package/dist/orchviz-web/fira-code-symbols2-400-normal.woff +0 -0
- package/dist/orchviz-web/fira-code-symbols2-500-normal.woff +0 -0
- package/dist/orchviz-web/index.css +0 -1
- package/dist/orchviz-web/index.html +0 -18
- package/dist/orchviz-web/index.js +0 -53
- package/dist/orchviz-web/inter-cyrillic-400-normal.woff +0 -0
- package/dist/orchviz-web/inter-cyrillic-400-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-cyrillic-500-normal.woff +0 -0
- package/dist/orchviz-web/inter-cyrillic-500-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-cyrillic-600-normal.woff +0 -0
- package/dist/orchviz-web/inter-cyrillic-600-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-cyrillic-ext-400-normal.woff +0 -0
- package/dist/orchviz-web/inter-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-cyrillic-ext-500-normal.woff +0 -0
- package/dist/orchviz-web/inter-cyrillic-ext-500-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-cyrillic-ext-600-normal.woff +0 -0
- package/dist/orchviz-web/inter-cyrillic-ext-600-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-greek-400-normal.woff +0 -0
- package/dist/orchviz-web/inter-greek-400-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-greek-500-normal.woff +0 -0
- package/dist/orchviz-web/inter-greek-500-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-greek-600-normal.woff +0 -0
- package/dist/orchviz-web/inter-greek-600-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-greek-ext-400-normal.woff +0 -0
- package/dist/orchviz-web/inter-greek-ext-400-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-greek-ext-500-normal.woff +0 -0
- package/dist/orchviz-web/inter-greek-ext-500-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-greek-ext-600-normal.woff +0 -0
- package/dist/orchviz-web/inter-greek-ext-600-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-latin-400-normal.woff +0 -0
- package/dist/orchviz-web/inter-latin-400-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-latin-500-normal.woff +0 -0
- package/dist/orchviz-web/inter-latin-500-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-latin-600-normal.woff +0 -0
- package/dist/orchviz-web/inter-latin-600-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-latin-ext-400-normal.woff +0 -0
- package/dist/orchviz-web/inter-latin-ext-400-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-latin-ext-500-normal.woff +0 -0
- package/dist/orchviz-web/inter-latin-ext-500-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-latin-ext-600-normal.woff +0 -0
- package/dist/orchviz-web/inter-latin-ext-600-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-vietnamese-400-normal.woff +0 -0
- package/dist/orchviz-web/inter-vietnamese-400-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-vietnamese-500-normal.woff +0 -0
- package/dist/orchviz-web/inter-vietnamese-500-normal.woff2 +0 -0
- package/dist/orchviz-web/inter-vietnamese-600-normal.woff +0 -0
- package/dist/orchviz-web/inter-vietnamese-600-normal.woff2 +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crash-safe same-directory atomic write.
|
|
3
|
+
*
|
|
4
|
+
* Behavior extracted verbatim from the plan writer's atomic-write: write to a
|
|
5
|
+
* same-directory temp file, then `renameSync` (atomic on POSIX because tmp and
|
|
6
|
+
* target share a filesystem). A single Windows EPERM retry covers the case where
|
|
7
|
+
* the target is briefly locked. `try/finally` unlinks the temp on any throw, so
|
|
8
|
+
* a failed write never leaves an orphan. The temp prefix is dotted so orphaned
|
|
9
|
+
* temps never match a caller's content-file glob.
|
|
10
|
+
*/
|
|
11
|
+
import * as crypto from "node:crypto";
|
|
12
|
+
import * as fs from "node:fs";
|
|
13
|
+
import * as path from "node:path";
|
|
14
|
+
const TMP_PREFIX = ".local-web-tmp-";
|
|
15
|
+
const ORPHAN_AGE_MS = 5 * 60 * 1000; // 5 minutes
|
|
16
|
+
/** Write `content` to `targetPath` atomically via a same-directory temp file. */
|
|
17
|
+
export function atomicWriteFileSync(targetPath, content) {
|
|
18
|
+
const dir = path.dirname(targetPath);
|
|
19
|
+
const tmpPath = path.join(dir, `${TMP_PREFIX}${crypto.randomBytes(6).toString("hex")}`);
|
|
20
|
+
fs.writeFileSync(tmpPath, content, "utf-8");
|
|
21
|
+
try {
|
|
22
|
+
try {
|
|
23
|
+
fs.renameSync(tmpPath, targetPath);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
const e = err;
|
|
27
|
+
if (e.code === "EPERM") {
|
|
28
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 50);
|
|
29
|
+
fs.renameSync(tmpPath, targetPath);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
throw err;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
try {
|
|
38
|
+
fs.unlinkSync(tmpPath);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// best-effort cleanup; surface the original error
|
|
42
|
+
}
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Remove `TMP_PREFIX` temps older than the orphan age in `dir` (best-effort). */
|
|
47
|
+
export function cleanOrphanedTmps(dir) {
|
|
48
|
+
let entries;
|
|
49
|
+
try {
|
|
50
|
+
entries = fs.readdirSync(dir);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
for (const name of entries) {
|
|
57
|
+
if (!name.startsWith(TMP_PREFIX))
|
|
58
|
+
continue;
|
|
59
|
+
const full = path.join(dir, name);
|
|
60
|
+
try {
|
|
61
|
+
if (now - fs.statSync(full).mtimeMs > ORPHAN_AGE_MS)
|
|
62
|
+
fs.unlinkSync(full);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// entry may be gone or inaccessible — skip
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=atomic-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-write.js","sourceRoot":"","sources":["../../src/local-web/atomic-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,MAAM,UAAU,GAAG,iBAAiB,CAAC;AACrC,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AAEjD,iFAAiF;AACjF,MAAM,UAAU,mBAAmB,CAAC,UAAkB,EAAE,OAAe;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACxF,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5C,IAAI,CAAC;QACJ,IAAI,CAAC;YACJ,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,CAAC,GAAG,GAA4B,CAAC;YACvC,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACP,MAAM,GAAG,CAAC;YACX,CAAC;QACF,CAAC;IACF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,IAAI,CAAC;YACJ,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;QAAC,MAAM,CAAC;YACR,kDAAkD;QACnD,CAAC;QACD,MAAM,GAAG,CAAC;IACX,CAAC;AACF,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC5C,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACJ,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO;IACR,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,SAAS;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC;YACJ,IAAI,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,aAAa;gBAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1E,CAAC;QAAC,MAAM,CAAC;YACR,2CAA2C;QAC5C,CAAC;IACF,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* local-web shared constants.
|
|
3
|
+
*
|
|
4
|
+
* The loopback bind host is the single security anchor for every primitive in
|
|
5
|
+
* this layer: the server binds it, and the Host/Origin guards build their
|
|
6
|
+
* allowlists from it. Keeping one constant avoids drift between "what we bind"
|
|
7
|
+
* and "what we allow".
|
|
8
|
+
*/
|
|
9
|
+
/** Loopback interface — the server binds here and guards allow only this + localhost. */
|
|
10
|
+
export declare const LOOPBACK_HOST = "127.0.0.1";
|
|
11
|
+
/** Grace period for in-flight connections to drain on server stop. */
|
|
12
|
+
export declare const CLOSE_GRACE_MS = 5000;
|
|
13
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/local-web/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,yFAAyF;AACzF,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC,sEAAsE;AACtE,eAAO,MAAM,cAAc,OAAQ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* local-web shared constants.
|
|
3
|
+
*
|
|
4
|
+
* The loopback bind host is the single security anchor for every primitive in
|
|
5
|
+
* this layer: the server binds it, and the Host/Origin guards build their
|
|
6
|
+
* allowlists from it. Keeping one constant avoids drift between "what we bind"
|
|
7
|
+
* and "what we allow".
|
|
8
|
+
*/
|
|
9
|
+
/** Loopback interface — the server binds here and guards allow only this + localhost. */
|
|
10
|
+
export const LOOPBACK_HOST = "127.0.0.1";
|
|
11
|
+
/** Grace period for in-flight connections to drain on server stop. */
|
|
12
|
+
export const CLOSE_GRACE_MS = 5_000;
|
|
13
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/local-web/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,yFAAyF;AACzF,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AAEzC,sEAAsE;AACtE,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SHA-256 ETag + optimistic-concurrency (409-stale) helper.
|
|
3
|
+
*
|
|
4
|
+
* CONSOLIDATES the two prior sources: the standalone per-file SHA-256 ETag
|
|
5
|
+
* (64-char lowercase hex of the file's bytes) and the write pipeline's 409-stale
|
|
6
|
+
* check (`current !== provided ⇒ stale`). One canonical implementation drives
|
|
7
|
+
* both a caller computing an ETag to hand out and a caller comparing a
|
|
8
|
+
* client-supplied ETag before a write. Missing file ⇒ null (caller decides).
|
|
9
|
+
*/
|
|
10
|
+
/** 64-char lowercase hex SHA-256 of `content`. */
|
|
11
|
+
export declare function computeEtag(content: Buffer | string): string;
|
|
12
|
+
/** SHA-256 ETag of a file's bytes, or null if it cannot be read. */
|
|
13
|
+
export declare function etagFromFile(filePath: string): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* True when a client-supplied ETag no longer matches the current one — the
|
|
16
|
+
* optimistic-concurrency condition a write route answers with HTTP 409.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isStaleEtag(currentEtag: string, providedEtag: string): boolean;
|
|
19
|
+
//# sourceMappingURL=etag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"etag.d.ts","sourceRoot":"","sources":["../../src/local-web/etag.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,kDAAkD;AAClD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE5D;AAED,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM5D;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAE9E"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SHA-256 ETag + optimistic-concurrency (409-stale) helper.
|
|
3
|
+
*
|
|
4
|
+
* CONSOLIDATES the two prior sources: the standalone per-file SHA-256 ETag
|
|
5
|
+
* (64-char lowercase hex of the file's bytes) and the write pipeline's 409-stale
|
|
6
|
+
* check (`current !== provided ⇒ stale`). One canonical implementation drives
|
|
7
|
+
* both a caller computing an ETag to hand out and a caller comparing a
|
|
8
|
+
* client-supplied ETag before a write. Missing file ⇒ null (caller decides).
|
|
9
|
+
*/
|
|
10
|
+
import * as crypto from "node:crypto";
|
|
11
|
+
import * as fs from "node:fs";
|
|
12
|
+
/** 64-char lowercase hex SHA-256 of `content`. */
|
|
13
|
+
export function computeEtag(content) {
|
|
14
|
+
return crypto.createHash("sha256").update(content).digest("hex");
|
|
15
|
+
}
|
|
16
|
+
/** SHA-256 ETag of a file's bytes, or null if it cannot be read. */
|
|
17
|
+
export function etagFromFile(filePath) {
|
|
18
|
+
try {
|
|
19
|
+
return computeEtag(fs.readFileSync(filePath));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* True when a client-supplied ETag no longer matches the current one — the
|
|
27
|
+
* optimistic-concurrency condition a write route answers with HTTP 409.
|
|
28
|
+
*/
|
|
29
|
+
export function isStaleEtag(currentEtag, providedEtag) {
|
|
30
|
+
return currentEtag !== providedEtag;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=etag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"etag.js","sourceRoot":"","sources":["../../src/local-web/etag.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,kDAAkD;AAClD,MAAM,UAAU,WAAW,CAAC,OAAwB;IACnD,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC5C,IAAI,CAAC;QACJ,OAAO,WAAW,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,WAAmB,EAAE,YAAoB;IACpE,OAAO,WAAW,KAAK,YAAY,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host header guard — defense against DNS rebinding.
|
|
3
|
+
*
|
|
4
|
+
* Behavior extracted verbatim from the loopback server's private host check:
|
|
5
|
+
* a request is allowed only when its `Host` header is the loopback/localhost
|
|
6
|
+
* authority (with or without the bound port). The `Host` header may arrive
|
|
7
|
+
* mixed-case from proxies, so this uses a Set of exact expected values plus the
|
|
8
|
+
* bare-host fallback — it does NOT lowercase (that is the Origin guard's job).
|
|
9
|
+
*/
|
|
10
|
+
/** True when `host` is an allowed loopback authority for `port`. Missing host ⇒ false. */
|
|
11
|
+
export declare function isHostAllowed(host: string | undefined, port: number): boolean;
|
|
12
|
+
//# sourceMappingURL=host-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-guard.d.ts","sourceRoot":"","sources":["../../src/local-web/host-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAI7E"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host header guard — defense against DNS rebinding.
|
|
3
|
+
*
|
|
4
|
+
* Behavior extracted verbatim from the loopback server's private host check:
|
|
5
|
+
* a request is allowed only when its `Host` header is the loopback/localhost
|
|
6
|
+
* authority (with or without the bound port). The `Host` header may arrive
|
|
7
|
+
* mixed-case from proxies, so this uses a Set of exact expected values plus the
|
|
8
|
+
* bare-host fallback — it does NOT lowercase (that is the Origin guard's job).
|
|
9
|
+
*/
|
|
10
|
+
import { LOOPBACK_HOST } from "./constants.js";
|
|
11
|
+
/** True when `host` is an allowed loopback authority for `port`. Missing host ⇒ false. */
|
|
12
|
+
export function isHostAllowed(host, port) {
|
|
13
|
+
if (!host)
|
|
14
|
+
return false;
|
|
15
|
+
const expected = new Set([`${LOOPBACK_HOST}:${port}`, `localhost:${port}`]);
|
|
16
|
+
return expected.has(host) || host === LOOPBACK_HOST || host === "localhost";
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=host-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-guard.js","sourceRoot":"","sources":["../../src/local-web/host-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,0FAA0F;AAC1F,MAAM,UAAU,aAAa,CAAC,IAAwB,EAAE,IAAY;IACnE,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,aAAa,IAAI,IAAI,EAAE,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5E,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,WAAW,CAAC;AAC7E,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* local-web — domain-neutral loopback web primitives.
|
|
3
|
+
*
|
|
4
|
+
* Extracted (Phase 2) from the prior local-server implementation so the Visual
|
|
5
|
+
* Plan studio (and any future loopback tool) reuses ONE audited copy of the security- and
|
|
6
|
+
* concurrency-sensitive code: loopback server lifecycle, Host/Origin guards,
|
|
7
|
+
* bounded body reading, realpath containment, atomic writes, SHA-256 ETags,
|
|
8
|
+
* traversal-guarded static serving, and cross-platform browser open.
|
|
9
|
+
*
|
|
10
|
+
* Dependency direction is product-domain → local-web only; this layer imports
|
|
11
|
+
* nothing product-specific.
|
|
12
|
+
*/
|
|
13
|
+
export { LOOPBACK_HOST, CLOSE_GRACE_MS } from "./constants.js";
|
|
14
|
+
export { isHostAllowed } from "./host-guard.js";
|
|
15
|
+
export { isOriginAllowed } from "./origin-guard.js";
|
|
16
|
+
export { bufferBody, BodyError } from "./request-body.js";
|
|
17
|
+
export { safeRealpath, isContainedPath, resolveContained } from "./path-boundary.js";
|
|
18
|
+
export { atomicWriteFileSync, cleanOrphanedTmps } from "./atomic-write.js";
|
|
19
|
+
export { computeEtag, etagFromFile, isStaleEtag } from "./etag.js";
|
|
20
|
+
export { serveStatic } from "./static-handler.js";
|
|
21
|
+
export { openBrowser } from "./open-browser.js";
|
|
22
|
+
export { LocalServer, type LocalServerOptions, type RequestHandler } from "./local-server.js";
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/local-web/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* local-web — domain-neutral loopback web primitives.
|
|
3
|
+
*
|
|
4
|
+
* Extracted (Phase 2) from the prior local-server implementation so the Visual
|
|
5
|
+
* Plan studio (and any future loopback tool) reuses ONE audited copy of the security- and
|
|
6
|
+
* concurrency-sensitive code: loopback server lifecycle, Host/Origin guards,
|
|
7
|
+
* bounded body reading, realpath containment, atomic writes, SHA-256 ETags,
|
|
8
|
+
* traversal-guarded static serving, and cross-platform browser open.
|
|
9
|
+
*
|
|
10
|
+
* Dependency direction is product-domain → local-web only; this layer imports
|
|
11
|
+
* nothing product-specific.
|
|
12
|
+
*/
|
|
13
|
+
export { LOOPBACK_HOST, CLOSE_GRACE_MS } from "./constants.js";
|
|
14
|
+
export { isHostAllowed } from "./host-guard.js";
|
|
15
|
+
export { isOriginAllowed } from "./origin-guard.js";
|
|
16
|
+
export { bufferBody, BodyError } from "./request-body.js";
|
|
17
|
+
export { safeRealpath, isContainedPath, resolveContained } from "./path-boundary.js";
|
|
18
|
+
export { atomicWriteFileSync, cleanOrphanedTmps } from "./atomic-write.js";
|
|
19
|
+
export { computeEtag, etagFromFile, isStaleEtag } from "./etag.js";
|
|
20
|
+
export { serveStatic } from "./static-handler.js";
|
|
21
|
+
export { openBrowser } from "./open-browser.js";
|
|
22
|
+
export { LocalServer } from "./local-server.js";
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/local-web/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAgD,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loopback HTTP server lifecycle — 127.0.0.1 bind + Host guard + port fallback.
|
|
3
|
+
*
|
|
4
|
+
* Server lifecycle ported from patoles/agent-flow @ 59ccf4e (app/src/server.ts).
|
|
5
|
+
* License Apache-2.0 — see the repository NOTICE file.
|
|
6
|
+
*
|
|
7
|
+
* Domain-neutral: it owns ONLY binding, the DNS-rebinding Host guard, port
|
|
8
|
+
* fallback, and graceful shutdown. All routing is delegated to the injected
|
|
9
|
+
* `handler` — this layer has no knowledge of any product's routes or payloads.
|
|
10
|
+
* A request whose `Host` header fails the guard gets 403 before the handler
|
|
11
|
+
* ever sees it.
|
|
12
|
+
*/
|
|
13
|
+
import * as http from "node:http";
|
|
14
|
+
export type RequestHandler = (req: http.IncomingMessage, res: http.ServerResponse) => void;
|
|
15
|
+
export interface LocalServerOptions {
|
|
16
|
+
/** Fixed port, or 0/undefined for a random free port. A busy fixed port falls back to random. */
|
|
17
|
+
port?: number;
|
|
18
|
+
/** Routes every Host-allowed request. */
|
|
19
|
+
handler: RequestHandler;
|
|
20
|
+
/** Emit a one-line note to stderr on port fallback. */
|
|
21
|
+
verbose?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare class LocalServer {
|
|
24
|
+
private server;
|
|
25
|
+
private actualPort;
|
|
26
|
+
private readonly opts;
|
|
27
|
+
constructor(opts: LocalServerOptions);
|
|
28
|
+
get port(): number;
|
|
29
|
+
get url(): string;
|
|
30
|
+
/** Bind the server and return its URL. Falls back to a random port if the fixed one is busy. */
|
|
31
|
+
start(): Promise<string>;
|
|
32
|
+
/** Gracefully close, allowing in-flight connections a bounded grace period. */
|
|
33
|
+
stop(): Promise<void>;
|
|
34
|
+
private listen;
|
|
35
|
+
private route;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=local-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-server.d.ts","sourceRoot":"","sources":["../../src/local-web/local-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC;AAE3F,MAAM,WAAW,kBAAkB;IAClC,iGAAiG;IACjG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,OAAO,EAAE,cAAc,CAAC;IACxB,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,WAAW;IACvB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;gBAE9B,IAAI,EAAE,kBAAkB;IAIpC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,gGAAgG;IAC1F,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAgB9B,+EAA+E;IACzE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,KAAK;CAQb"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loopback HTTP server lifecycle — 127.0.0.1 bind + Host guard + port fallback.
|
|
3
|
+
*
|
|
4
|
+
* Server lifecycle ported from patoles/agent-flow @ 59ccf4e (app/src/server.ts).
|
|
5
|
+
* License Apache-2.0 — see the repository NOTICE file.
|
|
6
|
+
*
|
|
7
|
+
* Domain-neutral: it owns ONLY binding, the DNS-rebinding Host guard, port
|
|
8
|
+
* fallback, and graceful shutdown. All routing is delegated to the injected
|
|
9
|
+
* `handler` — this layer has no knowledge of any product's routes or payloads.
|
|
10
|
+
* A request whose `Host` header fails the guard gets 403 before the handler
|
|
11
|
+
* ever sees it.
|
|
12
|
+
*/
|
|
13
|
+
import * as http from "node:http";
|
|
14
|
+
import { LOOPBACK_HOST, CLOSE_GRACE_MS } from "./constants.js";
|
|
15
|
+
import { isHostAllowed } from "./host-guard.js";
|
|
16
|
+
export class LocalServer {
|
|
17
|
+
server = null;
|
|
18
|
+
actualPort = 0;
|
|
19
|
+
opts;
|
|
20
|
+
constructor(opts) {
|
|
21
|
+
this.opts = opts;
|
|
22
|
+
}
|
|
23
|
+
get port() {
|
|
24
|
+
return this.actualPort;
|
|
25
|
+
}
|
|
26
|
+
get url() {
|
|
27
|
+
return `http://${LOOPBACK_HOST}:${this.actualPort}`;
|
|
28
|
+
}
|
|
29
|
+
/** Bind the server and return its URL. Falls back to a random port if the fixed one is busy. */
|
|
30
|
+
async start() {
|
|
31
|
+
const desiredPort = this.opts.port ?? 0;
|
|
32
|
+
try {
|
|
33
|
+
await this.listen(desiredPort);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
const e = err;
|
|
37
|
+
if (desiredPort !== 0 && (e.code === "EADDRINUSE" || e.code === "EACCES")) {
|
|
38
|
+
if (this.opts.verbose)
|
|
39
|
+
process.stderr.write(`[local-web] port ${desiredPort} unavailable (${e.code}); falling back to random\n`);
|
|
40
|
+
await this.listen(0);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return this.url;
|
|
47
|
+
}
|
|
48
|
+
/** Gracefully close, allowing in-flight connections a bounded grace period. */
|
|
49
|
+
async stop() {
|
|
50
|
+
if (!this.server)
|
|
51
|
+
return;
|
|
52
|
+
const srv = this.server;
|
|
53
|
+
this.server = null;
|
|
54
|
+
await new Promise((resolve) => {
|
|
55
|
+
const timer = setTimeout(() => resolve(), CLOSE_GRACE_MS);
|
|
56
|
+
if (typeof timer.unref === "function")
|
|
57
|
+
timer.unref();
|
|
58
|
+
srv.close(() => {
|
|
59
|
+
clearTimeout(timer);
|
|
60
|
+
resolve();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
listen(port) {
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
const server = http.createServer((req, res) => this.route(req, res));
|
|
67
|
+
server.on("error", reject); // caller distinguishes EADDRINUSE/EACCES for fallback
|
|
68
|
+
server.listen(port, LOOPBACK_HOST, () => {
|
|
69
|
+
this.server = server;
|
|
70
|
+
const addr = server.address();
|
|
71
|
+
this.actualPort = typeof addr === "object" && addr ? addr.port : port;
|
|
72
|
+
resolve();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
route(req, res) {
|
|
77
|
+
if (!isHostAllowed(req.headers.host, this.actualPort)) {
|
|
78
|
+
res.writeHead(403, { "Content-Type": "text/plain" });
|
|
79
|
+
res.end("Forbidden");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
this.opts.handler(req, res);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=local-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-server.js","sourceRoot":"","sources":["../../src/local-web/local-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAahD,MAAM,OAAO,WAAW;IACf,MAAM,GAAuB,IAAI,CAAC;IAClC,UAAU,GAAG,CAAC,CAAC;IACN,IAAI,CAAqB;IAE1C,YAAY,IAAwB;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,IAAI,IAAI;QACP,OAAO,IAAI,CAAC,UAAU,CAAC;IACxB,CAAC;IAED,IAAI,GAAG;QACN,OAAO,UAAU,aAAa,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;IACrD,CAAC;IAED,gGAAgG;IAChG,KAAK,CAAC,KAAK;QACV,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,CAAC,GAAG,GAA4B,CAAC;YACvC,IAAI,WAAW,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;gBAC3E,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO;oBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,WAAW,iBAAiB,CAAC,CAAC,IAAI,6BAA6B,CAAC,CAAC;gBACjI,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACP,MAAM,GAAG,CAAC;YACX,CAAC;QACF,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC;IACjB,CAAC;IAED,+EAA+E;IAC/E,KAAK,CAAC,IAAI;QACT,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACnC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;YAC1D,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU;gBAAE,KAAK,CAAC,KAAK,EAAE,CAAC;YACrD,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE;gBACd,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,OAAO,EAAE,CAAC;YACX,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,IAAY;QAC1B,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YACrE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,sDAAsD;YAClF,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE;gBACvC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;gBACrB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC9B,IAAI,CAAC,UAAU,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBACtE,OAAO,EAAE,CAAC;YACX,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,GAAyB,EAAE,GAAwB;QAChE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACvD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACrB,OAAO;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC7B,CAAC;CACD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform browser launcher with no runtime deps.
|
|
3
|
+
*
|
|
4
|
+
* Ported from patoles/agent-flow @ 59ccf4e (app/src/server.ts).
|
|
5
|
+
* License Apache-2.0 — see the repository NOTICE file.
|
|
6
|
+
*
|
|
7
|
+
* macOS/Linux use execFile (no shell). Windows requires `start` (a shell
|
|
8
|
+
* builtin), so it execs a shell — but ONLY with our own URL, never user input.
|
|
9
|
+
*/
|
|
10
|
+
/** Open `url` in the platform default browser. `onError` receives any launch error. */
|
|
11
|
+
export declare function openBrowser(url: string, onError?: (err: Error) => void): void;
|
|
12
|
+
//# sourceMappingURL=open-browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-browser.d.ts","sourceRoot":"","sources":["../../src/local-web/open-browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAa7E"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Cross-platform browser launcher with no runtime deps.
|
|
3
3
|
*
|
|
4
4
|
* Ported from patoles/agent-flow @ 59ccf4e (app/src/server.ts).
|
|
5
|
-
* License Apache-2.0
|
|
5
|
+
* License Apache-2.0 — see the repository NOTICE file.
|
|
6
6
|
*
|
|
7
|
-
* macOS/Linux use execFile (no shell). Windows requires `start` (shell
|
|
8
|
-
* so
|
|
7
|
+
* macOS/Linux use execFile (no shell). Windows requires `start` (a shell
|
|
8
|
+
* builtin), so it execs a shell — but ONLY with our own URL, never user input.
|
|
9
9
|
*/
|
|
10
10
|
import { exec, execFile } from "node:child_process";
|
|
11
|
-
|
|
11
|
+
/** Open `url` in the platform default browser. `onError` receives any launch error. */
|
|
12
|
+
export function openBrowser(url, onError) {
|
|
12
13
|
const cb = (err) => {
|
|
13
14
|
if (err && onError)
|
|
14
15
|
onError(err);
|
|
@@ -17,12 +18,12 @@ export function openURL(url, onError) {
|
|
|
17
18
|
execFile("open", [url], cb);
|
|
18
19
|
}
|
|
19
20
|
else if (process.platform === "win32") {
|
|
20
|
-
// `start` is a shell builtin; empty title arg
|
|
21
|
-
//
|
|
21
|
+
// `start` is a shell builtin; the empty title arg stops `start "URL"`
|
|
22
|
+
// from being parsed as a window title.
|
|
22
23
|
exec(`start "" "${url}"`, cb);
|
|
23
24
|
}
|
|
24
25
|
else {
|
|
25
26
|
execFile("xdg-open", [url], cb);
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
|
-
//# sourceMappingURL=open-
|
|
29
|
+
//# sourceMappingURL=open-browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-browser.js","sourceRoot":"","sources":["../../src/local-web/open-browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEpD,uFAAuF;AACvF,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,OAA8B;IACtE,MAAM,EAAE,GAAG,CAAC,GAAiB,EAAQ,EAAE;QACtC,IAAI,GAAG,IAAI,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC,CAAC;IACF,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACnC,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7B,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzC,sEAAsE;QACtE,uCAAuC;QACvC,IAAI,CAAC,aAAa,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACP,QAAQ,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACjC,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Origin header guard — exact-match allowlist for cross-origin write requests.
|
|
3
|
+
*
|
|
4
|
+
* Behavior extracted verbatim from the loopback write pipeline: case-insensitive
|
|
5
|
+
* EXACT equality against the two allowed origins. No prefix-match, no contains,
|
|
6
|
+
* no regex. Distinct from the Host guard — the `Origin` header is always
|
|
7
|
+
* lowercase per the browser spec, so this lowercases and compares exact strings.
|
|
8
|
+
*/
|
|
9
|
+
/** True when `origin` is exactly the loopback or localhost origin for `port`. */
|
|
10
|
+
export declare function isOriginAllowed(origin: string, port: number): boolean;
|
|
11
|
+
//# sourceMappingURL=origin-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"origin-guard.d.ts","sourceRoot":"","sources":["../../src/local-web/origin-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGrE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Origin header guard — exact-match allowlist for cross-origin write requests.
|
|
3
|
+
*
|
|
4
|
+
* Behavior extracted verbatim from the loopback write pipeline: case-insensitive
|
|
5
|
+
* EXACT equality against the two allowed origins. No prefix-match, no contains,
|
|
6
|
+
* no regex. Distinct from the Host guard — the `Origin` header is always
|
|
7
|
+
* lowercase per the browser spec, so this lowercases and compares exact strings.
|
|
8
|
+
*/
|
|
9
|
+
import { LOOPBACK_HOST } from "./constants.js";
|
|
10
|
+
/** True when `origin` is exactly the loopback or localhost origin for `port`. */
|
|
11
|
+
export function isOriginAllowed(origin, port) {
|
|
12
|
+
const lower = origin.toLowerCase();
|
|
13
|
+
return lower === `http://${LOOPBACK_HOST}:${port}` || lower === `http://localhost:${port}`;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=origin-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"origin-guard.js","sourceRoot":"","sources":["../../src/local-web/origin-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,iFAAiF;AACjF,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,IAAY;IAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACnC,OAAO,KAAK,KAAK,UAAU,aAAa,IAAI,IAAI,EAAE,IAAI,KAAK,KAAK,oBAAoB,IAAI,EAAE,CAAC;AAC5F,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Realpath-based path containment — fail-closed.
|
|
3
|
+
*
|
|
4
|
+
* Behavior extracted verbatim from the loopback write pipeline's boundary
|
|
5
|
+
* checks: `safeRealpath` resolves symlinks and returns null on ANY error (the
|
|
6
|
+
* caller MUST treat null as denied), and `isContainedPath` verifies a resolved
|
|
7
|
+
* child sits at or strictly inside a resolved parent. Together they stop a
|
|
8
|
+
* symlinked entry from redirecting reads/writes outside an allowed root.
|
|
9
|
+
*/
|
|
10
|
+
/** Resolve `p` to a realpath, or null on any failure (fail-closed). */
|
|
11
|
+
export declare function safeRealpath(p: string): string | null;
|
|
12
|
+
/** True when `childRealpath` is `parentRealpath` itself or strictly inside it. */
|
|
13
|
+
export declare function isContainedPath(childRealpath: string, parentRealpath: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve `child` and verify it is contained within `parent` (already-resolved
|
|
16
|
+
* or resolvable). Returns the child's realpath on success, or null when either
|
|
17
|
+
* realpath fails or containment is violated.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveContained(parent: string, child: string): string | null;
|
|
20
|
+
//# sourceMappingURL=path-boundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-boundary.d.ts","sourceRoot":"","sources":["../../src/local-web/path-boundary.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMrD;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAEtF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM7E"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Realpath-based path containment — fail-closed.
|
|
3
|
+
*
|
|
4
|
+
* Behavior extracted verbatim from the loopback write pipeline's boundary
|
|
5
|
+
* checks: `safeRealpath` resolves symlinks and returns null on ANY error (the
|
|
6
|
+
* caller MUST treat null as denied), and `isContainedPath` verifies a resolved
|
|
7
|
+
* child sits at or strictly inside a resolved parent. Together they stop a
|
|
8
|
+
* symlinked entry from redirecting reads/writes outside an allowed root.
|
|
9
|
+
*/
|
|
10
|
+
import * as fs from "node:fs";
|
|
11
|
+
import * as path from "node:path";
|
|
12
|
+
/** Resolve `p` to a realpath, or null on any failure (fail-closed). */
|
|
13
|
+
export function safeRealpath(p) {
|
|
14
|
+
try {
|
|
15
|
+
return fs.realpathSync(p);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** True when `childRealpath` is `parentRealpath` itself or strictly inside it. */
|
|
22
|
+
export function isContainedPath(childRealpath, parentRealpath) {
|
|
23
|
+
return childRealpath === parentRealpath || childRealpath.startsWith(parentRealpath + path.sep);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolve `child` and verify it is contained within `parent` (already-resolved
|
|
27
|
+
* or resolvable). Returns the child's realpath on success, or null when either
|
|
28
|
+
* realpath fails or containment is violated.
|
|
29
|
+
*/
|
|
30
|
+
export function resolveContained(parent, child) {
|
|
31
|
+
const parentReal = safeRealpath(parent);
|
|
32
|
+
if (!parentReal)
|
|
33
|
+
return null;
|
|
34
|
+
const childReal = safeRealpath(child);
|
|
35
|
+
if (!childReal)
|
|
36
|
+
return null;
|
|
37
|
+
return isContainedPath(childReal, parentReal) ? childReal : null;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=path-boundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-boundary.js","sourceRoot":"","sources":["../../src/local-web/path-boundary.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,CAAS;IACrC,IAAI,CAAC;QACJ,OAAO,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,eAAe,CAAC,aAAqB,EAAE,cAAsB;IAC5E,OAAO,aAAa,KAAK,cAAc,IAAI,aAAa,CAAC,UAAU,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;AAChG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,KAAa;IAC7D,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC7B,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,OAAO,eAAe,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded request-body reader with a socket timeout.
|
|
3
|
+
*
|
|
4
|
+
* Behavior extracted verbatim from the loopback write pipeline: collect the body
|
|
5
|
+
* up to `capBytes`, destroying the socket and rejecting with `BodyError(413)` on
|
|
6
|
+
* overflow or `BodyError(408)` on timeout. The cap + timeout are the DoS guard
|
|
7
|
+
* for any POST/PATCH route; the consumer supplies both (the write pipeline uses
|
|
8
|
+
* a 4096-byte cap).
|
|
9
|
+
*/
|
|
10
|
+
import type { IncomingMessage } from "node:http";
|
|
11
|
+
/** Carries the HTTP status + a short tag for a body-read failure. */
|
|
12
|
+
export declare class BodyError extends Error {
|
|
13
|
+
readonly status: number;
|
|
14
|
+
readonly tag: string;
|
|
15
|
+
constructor(status: number, tag: string);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Collect the full request body up to `capBytes`. Destroys the socket if the
|
|
19
|
+
* body exceeds the cap OR if `timeoutMs` elapses first. Rejects with
|
|
20
|
+
* `BodyError(413,"body-too-large")` on overflow, `BodyError(408,"request-timeout")`
|
|
21
|
+
* on timeout.
|
|
22
|
+
*/
|
|
23
|
+
export declare function bufferBody(req: IncomingMessage, capBytes: number, timeoutMs: number): Promise<Buffer>;
|
|
24
|
+
//# sourceMappingURL=request-body.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-body.d.ts","sourceRoot":"","sources":["../../src/local-web/request-body.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,qEAAqE;AACrE,qBAAa,SAAU,SAAQ,KAAK;aAElB,MAAM,EAAE,MAAM;aACd,GAAG,EAAE,MAAM;gBADX,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM;CAK5B;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwCrG"}
|