@aigne/aos 0.2.0-beta
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 +49 -0
- package/LICENSE.md +26 -0
- package/dist/agent-dsl.cjs +116 -0
- package/dist/agent-dsl.d.cts +31 -0
- package/dist/agent-dsl.d.cts.map +1 -0
- package/dist/agent-dsl.d.mts +31 -0
- package/dist/agent-dsl.d.mts.map +1 -0
- package/dist/agent-dsl.mjs +115 -0
- package/dist/agent-dsl.mjs.map +1 -0
- package/dist/arc-compat.cjs +125 -0
- package/dist/arc-compat.d.cts +17 -0
- package/dist/arc-compat.d.cts.map +1 -0
- package/dist/arc-compat.d.mts +17 -0
- package/dist/arc-compat.d.mts.map +1 -0
- package/dist/arc-compat.mjs +123 -0
- package/dist/arc-compat.mjs.map +1 -0
- package/dist/auto-surface/compiler.cjs +36 -0
- package/dist/auto-surface/compiler.d.cts +7 -0
- package/dist/auto-surface/compiler.d.cts.map +1 -0
- package/dist/auto-surface/compiler.d.mts +7 -0
- package/dist/auto-surface/compiler.d.mts.map +1 -0
- package/dist/auto-surface/compiler.mjs +37 -0
- package/dist/auto-surface/compiler.mjs.map +1 -0
- package/dist/auto-surface/definition-dsl.cjs +333 -0
- package/dist/auto-surface/definition-dsl.d.cts +41 -0
- package/dist/auto-surface/definition-dsl.d.cts.map +1 -0
- package/dist/auto-surface/definition-dsl.d.mts +41 -0
- package/dist/auto-surface/definition-dsl.d.mts.map +1 -0
- package/dist/auto-surface/definition-dsl.mjs +332 -0
- package/dist/auto-surface/definition-dsl.mjs.map +1 -0
- package/dist/auto-surface/fragments.cjs +177 -0
- package/dist/auto-surface/fragments.d.cts +23 -0
- package/dist/auto-surface/fragments.d.cts.map +1 -0
- package/dist/auto-surface/fragments.d.mts +23 -0
- package/dist/auto-surface/fragments.d.mts.map +1 -0
- package/dist/auto-surface/fragments.mjs +175 -0
- package/dist/auto-surface/fragments.mjs.map +1 -0
- package/dist/auto-surface/index.d.mts +9 -0
- package/dist/auto-surface/layering.cjs +43 -0
- package/dist/auto-surface/layering.d.cts +7 -0
- package/dist/auto-surface/layering.d.cts.map +1 -0
- package/dist/auto-surface/layering.d.mts +7 -0
- package/dist/auto-surface/layering.d.mts.map +1 -0
- package/dist/auto-surface/layering.mjs +43 -0
- package/dist/auto-surface/layering.mjs.map +1 -0
- package/dist/auto-surface/projection.cjs +11 -0
- package/dist/auto-surface/projection.d.cts +11 -0
- package/dist/auto-surface/projection.d.cts.map +1 -0
- package/dist/auto-surface/projection.d.mts +11 -0
- package/dist/auto-surface/projection.d.mts.map +1 -0
- package/dist/auto-surface/projection.mjs +12 -0
- package/dist/auto-surface/projection.mjs.map +1 -0
- package/dist/auto-surface/projectors/settings-shell.cjs +114 -0
- package/dist/auto-surface/projectors/settings-shell.d.cts +10 -0
- package/dist/auto-surface/projectors/settings-shell.d.cts.map +1 -0
- package/dist/auto-surface/projectors/settings-shell.d.mts +10 -0
- package/dist/auto-surface/projectors/settings-shell.d.mts.map +1 -0
- package/dist/auto-surface/projectors/settings-shell.mjs +114 -0
- package/dist/auto-surface/projectors/settings-shell.mjs.map +1 -0
- package/dist/auto-surface/scenario.cjs +38 -0
- package/dist/auto-surface/scenario.d.cts +31 -0
- package/dist/auto-surface/scenario.d.cts.map +1 -0
- package/dist/auto-surface/scenario.d.mts +31 -0
- package/dist/auto-surface/scenario.d.mts.map +1 -0
- package/dist/auto-surface/scenario.mjs +37 -0
- package/dist/auto-surface/scenario.mjs.map +1 -0
- package/dist/auto-surface/types.cjs +9 -0
- package/dist/auto-surface/types.d.cts +153 -0
- package/dist/auto-surface/types.d.cts.map +1 -0
- package/dist/auto-surface/types.d.mts +153 -0
- package/dist/auto-surface/types.d.mts.map +1 -0
- package/dist/auto-surface/types.mjs +9 -0
- package/dist/auto-surface/types.mjs.map +1 -0
- package/dist/auto-surface/value-dsl.cjs +80 -0
- package/dist/auto-surface/value-dsl.d.cts +24 -0
- package/dist/auto-surface/value-dsl.d.cts.map +1 -0
- package/dist/auto-surface/value-dsl.d.mts +24 -0
- package/dist/auto-surface/value-dsl.d.mts.map +1 -0
- package/dist/auto-surface/value-dsl.mjs +79 -0
- package/dist/auto-surface/value-dsl.mjs.map +1 -0
- package/dist/blocklet/activation.cjs +94 -0
- package/dist/blocklet/activation.d.cts +30 -0
- package/dist/blocklet/activation.d.cts.map +1 -0
- package/dist/blocklet/activation.d.mts +30 -0
- package/dist/blocklet/activation.d.mts.map +1 -0
- package/dist/blocklet/activation.mjs +94 -0
- package/dist/blocklet/activation.mjs.map +1 -0
- package/dist/blocklet/did-space-registry.cjs +282 -0
- package/dist/blocklet/did-space-registry.d.cts +82 -0
- package/dist/blocklet/did-space-registry.d.cts.map +1 -0
- package/dist/blocklet/did-space-registry.d.mts +82 -0
- package/dist/blocklet/did-space-registry.d.mts.map +1 -0
- package/dist/blocklet/did-space-registry.mjs +281 -0
- package/dist/blocklet/did-space-registry.mjs.map +1 -0
- package/dist/blocklet/handlers.cjs +66 -0
- package/dist/blocklet/handlers.d.cts +16 -0
- package/dist/blocklet/handlers.d.cts.map +1 -0
- package/dist/blocklet/handlers.d.mts +16 -0
- package/dist/blocklet/handlers.d.mts.map +1 -0
- package/dist/blocklet/handlers.mjs +65 -0
- package/dist/blocklet/handlers.mjs.map +1 -0
- package/dist/blocklet/index.d.mts +7 -0
- package/dist/blocklet/manifest.d.cts +2 -0
- package/dist/blocklet/manifest.d.mts +2 -0
- package/dist/blocklet/manifest.mjs +3 -0
- package/dist/blocklet/registry.cjs +447 -0
- package/dist/blocklet/registry.d.cts +197 -0
- package/dist/blocklet/registry.d.cts.map +1 -0
- package/dist/blocklet/registry.d.mts +197 -0
- package/dist/blocklet/registry.d.mts.map +1 -0
- package/dist/blocklet/registry.mjs +441 -0
- package/dist/blocklet/registry.mjs.map +1 -0
- package/dist/blocklet/static-render.cjs +183 -0
- package/dist/blocklet/static-render.d.cts +55 -0
- package/dist/blocklet/static-render.d.cts.map +1 -0
- package/dist/blocklet/static-render.d.mts +55 -0
- package/dist/blocklet/static-render.d.mts.map +1 -0
- package/dist/blocklet/static-render.mjs +181 -0
- package/dist/blocklet/static-render.mjs.map +1 -0
- package/dist/blocklet/types.d.cts +70 -0
- package/dist/blocklet/types.d.cts.map +1 -0
- package/dist/blocklet/types.d.mts +70 -0
- package/dist/blocklet/types.d.mts.map +1 -0
- package/dist/devices/chain.cjs +127 -0
- package/dist/devices/chain.d.cts +48 -0
- package/dist/devices/chain.d.cts.map +1 -0
- package/dist/devices/chain.d.mts +48 -0
- package/dist/devices/chain.d.mts.map +1 -0
- package/dist/devices/chain.mjs +125 -0
- package/dist/devices/chain.mjs.map +1 -0
- package/dist/dsl-shared.cjs +290 -0
- package/dist/dsl-shared.d.cts +54 -0
- package/dist/dsl-shared.d.cts.map +1 -0
- package/dist/dsl-shared.d.mts +54 -0
- package/dist/dsl-shared.d.mts.map +1 -0
- package/dist/dsl-shared.mjs +287 -0
- package/dist/dsl-shared.mjs.map +1 -0
- package/dist/http/afs-mcp.cjs +85 -0
- package/dist/http/afs-mcp.d.cts +14 -0
- package/dist/http/afs-mcp.d.cts.map +1 -0
- package/dist/http/afs-mcp.d.mts +14 -0
- package/dist/http/afs-mcp.d.mts.map +1 -0
- package/dist/http/afs-mcp.mjs +86 -0
- package/dist/http/afs-mcp.mjs.map +1 -0
- package/dist/http/afs-raw.cjs +264 -0
- package/dist/http/afs-raw.d.cts +31 -0
- package/dist/http/afs-raw.d.cts.map +1 -0
- package/dist/http/afs-raw.d.mts +31 -0
- package/dist/http/afs-raw.d.mts.map +1 -0
- package/dist/http/afs-raw.mjs +264 -0
- package/dist/http/afs-raw.mjs.map +1 -0
- package/dist/http/afs-rest.cjs +30 -0
- package/dist/http/afs-rest.d.cts +21 -0
- package/dist/http/afs-rest.d.cts.map +1 -0
- package/dist/http/afs-rest.d.mts +21 -0
- package/dist/http/afs-rest.d.mts.map +1 -0
- package/dist/http/afs-rest.mjs +31 -0
- package/dist/http/afs-rest.mjs.map +1 -0
- package/dist/http/afs-rpc-wire.cjs +271 -0
- package/dist/http/afs-rpc-wire.d.cts +195 -0
- package/dist/http/afs-rpc-wire.d.cts.map +1 -0
- package/dist/http/afs-rpc-wire.d.mts +195 -0
- package/dist/http/afs-rpc-wire.d.mts.map +1 -0
- package/dist/http/afs-rpc-wire.mjs +262 -0
- package/dist/http/afs-rpc-wire.mjs.map +1 -0
- package/dist/http/afs-rpc.cjs +729 -0
- package/dist/http/afs-rpc.d.cts +103 -0
- package/dist/http/afs-rpc.d.cts.map +1 -0
- package/dist/http/afs-rpc.d.mts +103 -0
- package/dist/http/afs-rpc.d.mts.map +1 -0
- package/dist/http/afs-rpc.mjs +729 -0
- package/dist/http/afs-rpc.mjs.map +1 -0
- package/dist/http/afs-upload.cjs +116 -0
- package/dist/http/afs-upload.d.cts +40 -0
- package/dist/http/afs-upload.d.cts.map +1 -0
- package/dist/http/afs-upload.d.mts +40 -0
- package/dist/http/afs-upload.d.mts.map +1 -0
- package/dist/http/afs-upload.mjs +116 -0
- package/dist/http/afs-upload.mjs.map +1 -0
- package/dist/http/aup-client.cjs +60 -0
- package/dist/http/aup-client.d.cts +22 -0
- package/dist/http/aup-client.d.cts.map +1 -0
- package/dist/http/aup-client.d.mts +22 -0
- package/dist/http/aup-client.d.mts.map +1 -0
- package/dist/http/aup-client.mjs +59 -0
- package/dist/http/aup-client.mjs.map +1 -0
- package/dist/http/aup-event.cjs +100 -0
- package/dist/http/aup-event.d.cts +38 -0
- package/dist/http/aup-event.d.cts.map +1 -0
- package/dist/http/aup-event.d.mts +38 -0
- package/dist/http/aup-event.d.mts.map +1 -0
- package/dist/http/aup-event.mjs +101 -0
- package/dist/http/aup-event.mjs.map +1 -0
- package/dist/http/auth-context.cjs +66 -0
- package/dist/http/auth-context.d.cts +64 -0
- package/dist/http/auth-context.d.cts.map +1 -0
- package/dist/http/auth-context.d.mts +64 -0
- package/dist/http/auth-context.d.mts.map +1 -0
- package/dist/http/auth-context.mjs +66 -0
- package/dist/http/auth-context.mjs.map +1 -0
- package/dist/http/csrf.cjs +50 -0
- package/dist/http/csrf.d.cts +8 -0
- package/dist/http/csrf.d.cts.map +1 -0
- package/dist/http/csrf.d.mts +8 -0
- package/dist/http/csrf.d.mts.map +1 -0
- package/dist/http/csrf.mjs +49 -0
- package/dist/http/csrf.mjs.map +1 -0
- package/dist/http/handlers.cjs +106 -0
- package/dist/http/handlers.d.cts +39 -0
- package/dist/http/handlers.d.cts.map +1 -0
- package/dist/http/handlers.d.mts +39 -0
- package/dist/http/handlers.d.mts.map +1 -0
- package/dist/http/handlers.mjs +104 -0
- package/dist/http/handlers.mjs.map +1 -0
- package/dist/http/index.d.mts +1 -0
- package/dist/http/ingest-facade.cjs +315 -0
- package/dist/http/ingest-facade.mjs +314 -0
- package/dist/http/ingest-facade.mjs.map +1 -0
- package/dist/http/raw-url.cjs +136 -0
- package/dist/http/raw-url.d.cts +54 -0
- package/dist/http/raw-url.d.cts.map +1 -0
- package/dist/http/raw-url.d.mts +54 -0
- package/dist/http/raw-url.d.mts.map +1 -0
- package/dist/http/raw-url.mjs +136 -0
- package/dist/http/raw-url.mjs.map +1 -0
- package/dist/http/request-context.cjs +178 -0
- package/dist/http/request-context.d.cts +76 -0
- package/dist/http/request-context.d.cts.map +1 -0
- package/dist/http/request-context.d.mts +76 -0
- package/dist/http/request-context.d.mts.map +1 -0
- package/dist/http/request-context.mjs +179 -0
- package/dist/http/request-context.mjs.map +1 -0
- package/dist/index.cjs +197 -0
- package/dist/index.d.cts +63 -0
- package/dist/index.d.mts +68 -0
- package/dist/index.mjs +61 -0
- package/dist/mcp/index.cjs +9 -0
- package/dist/mcp/index.d.cts +5 -0
- package/dist/mcp/index.d.mts +5 -0
- package/dist/mcp/index.mjs +6 -0
- package/dist/mcp/prompts.cjs +17 -0
- package/dist/mcp/prompts.d.cts +8 -0
- package/dist/mcp/prompts.d.cts.map +1 -0
- package/dist/mcp/prompts.d.mts +8 -0
- package/dist/mcp/prompts.d.mts.map +1 -0
- package/dist/mcp/prompts.mjs +17 -0
- package/dist/mcp/prompts.mjs.map +1 -0
- package/dist/mcp/resources.cjs +22 -0
- package/dist/mcp/resources.d.cts +8 -0
- package/dist/mcp/resources.d.cts.map +1 -0
- package/dist/mcp/resources.d.mts +8 -0
- package/dist/mcp/resources.d.mts.map +1 -0
- package/dist/mcp/resources.mjs +22 -0
- package/dist/mcp/resources.mjs.map +1 -0
- package/dist/mcp/server.cjs +51 -0
- package/dist/mcp/server.d.cts +20 -0
- package/dist/mcp/server.d.cts.map +1 -0
- package/dist/mcp/server.d.mts +20 -0
- package/dist/mcp/server.d.mts.map +1 -0
- package/dist/mcp/server.mjs +52 -0
- package/dist/mcp/server.mjs.map +1 -0
- package/dist/mcp/tools.cjs +218 -0
- package/dist/mcp/tools.d.cts +8 -0
- package/dist/mcp/tools.d.cts.map +1 -0
- package/dist/mcp/tools.d.mts +8 -0
- package/dist/mcp/tools.d.mts.map +1 -0
- package/dist/mcp/tools.mjs +219 -0
- package/dist/mcp/tools.mjs.map +1 -0
- package/dist/mcp/utils.cjs +75 -0
- package/dist/mcp/utils.mjs +69 -0
- package/dist/mcp/utils.mjs.map +1 -0
- package/dist/mount/index.cjs +4 -0
- package/dist/mount/index.d.cts +3 -0
- package/dist/mount/index.d.mts +3 -0
- package/dist/mount/index.mjs +3 -0
- package/dist/mount/materializer.cjs +167 -0
- package/dist/mount/materializer.d.cts +97 -0
- package/dist/mount/materializer.d.cts.map +1 -0
- package/dist/mount/materializer.d.mts +97 -0
- package/dist/mount/materializer.d.mts.map +1 -0
- package/dist/mount/materializer.mjs +167 -0
- package/dist/mount/materializer.mjs.map +1 -0
- package/dist/mount/types.d.cts +90 -0
- package/dist/mount/types.d.cts.map +1 -0
- package/dist/mount/types.d.mts +90 -0
- package/dist/mount/types.d.mts.map +1 -0
- package/dist/mount-config.cjs +61 -0
- package/dist/mount-config.d.cts +19 -0
- package/dist/mount-config.d.cts.map +1 -0
- package/dist/mount-config.d.mts +19 -0
- package/dist/mount-config.d.mts.map +1 -0
- package/dist/mount-config.mjs +61 -0
- package/dist/mount-config.mjs.map +1 -0
- package/dist/projectors/aup-projector.cjs +190 -0
- package/dist/projectors/aup-projector.d.cts +59 -0
- package/dist/projectors/aup-projector.d.cts.map +1 -0
- package/dist/projectors/aup-projector.d.mts +59 -0
- package/dist/projectors/aup-projector.d.mts.map +1 -0
- package/dist/projectors/aup-projector.mjs +188 -0
- package/dist/projectors/aup-projector.mjs.map +1 -0
- package/dist/projectors/index.cjs +6 -0
- package/dist/projectors/index.d.cts +2 -0
- package/dist/projectors/index.d.mts +2 -0
- package/dist/projectors/index.mjs +3 -0
- package/dist/scaffold/afs.cjs +195 -0
- package/dist/scaffold/afs.d.cts +16 -0
- package/dist/scaffold/afs.d.cts.map +1 -0
- package/dist/scaffold/afs.d.mts +16 -0
- package/dist/scaffold/afs.d.mts.map +1 -0
- package/dist/scaffold/afs.mjs +195 -0
- package/dist/scaffold/afs.mjs.map +1 -0
- package/dist/scaffold/composition.cjs +92 -0
- package/dist/scaffold/composition.d.cts +10 -0
- package/dist/scaffold/composition.d.cts.map +1 -0
- package/dist/scaffold/composition.d.mts +10 -0
- package/dist/scaffold/composition.d.mts.map +1 -0
- package/dist/scaffold/composition.mjs +92 -0
- package/dist/scaffold/composition.mjs.map +1 -0
- package/dist/scaffold/dsl-error.cjs +21 -0
- package/dist/scaffold/dsl-error.d.cts +11 -0
- package/dist/scaffold/dsl-error.d.cts.map +1 -0
- package/dist/scaffold/dsl-error.d.mts +11 -0
- package/dist/scaffold/dsl-error.d.mts.map +1 -0
- package/dist/scaffold/dsl-error.mjs +20 -0
- package/dist/scaffold/dsl-error.mjs.map +1 -0
- package/dist/scaffold/index.d.mts +12 -0
- package/dist/scaffold/manifest-dsl.cjs +188 -0
- package/dist/scaffold/manifest-dsl.d.cts +8 -0
- package/dist/scaffold/manifest-dsl.d.cts.map +1 -0
- package/dist/scaffold/manifest-dsl.d.mts +8 -0
- package/dist/scaffold/manifest-dsl.d.mts.map +1 -0
- package/dist/scaffold/manifest-dsl.mjs +188 -0
- package/dist/scaffold/manifest-dsl.mjs.map +1 -0
- package/dist/scaffold/module-dsl.cjs +284 -0
- package/dist/scaffold/module-dsl.d.cts +8 -0
- package/dist/scaffold/module-dsl.d.cts.map +1 -0
- package/dist/scaffold/module-dsl.d.mts +8 -0
- package/dist/scaffold/module-dsl.d.mts.map +1 -0
- package/dist/scaffold/module-dsl.mjs +284 -0
- package/dist/scaffold/module-dsl.mjs.map +1 -0
- package/dist/scaffold/resolver.cjs +156 -0
- package/dist/scaffold/resolver.d.cts +7 -0
- package/dist/scaffold/resolver.d.cts.map +1 -0
- package/dist/scaffold/resolver.d.mts +7 -0
- package/dist/scaffold/resolver.d.mts.map +1 -0
- package/dist/scaffold/resolver.mjs +156 -0
- package/dist/scaffold/resolver.mjs.map +1 -0
- package/dist/scaffold/runtime.cjs +24 -0
- package/dist/scaffold/runtime.d.cts +19 -0
- package/dist/scaffold/runtime.d.cts.map +1 -0
- package/dist/scaffold/runtime.d.mts +19 -0
- package/dist/scaffold/runtime.d.mts.map +1 -0
- package/dist/scaffold/runtime.mjs +25 -0
- package/dist/scaffold/runtime.mjs.map +1 -0
- package/dist/scaffold/shell-dsl.cjs +279 -0
- package/dist/scaffold/shell-dsl.d.cts +8 -0
- package/dist/scaffold/shell-dsl.d.cts.map +1 -0
- package/dist/scaffold/shell-dsl.d.mts +8 -0
- package/dist/scaffold/shell-dsl.d.mts.map +1 -0
- package/dist/scaffold/shell-dsl.mjs +279 -0
- package/dist/scaffold/shell-dsl.mjs.map +1 -0
- package/dist/scaffold/surface-dsl.cjs +182 -0
- package/dist/scaffold/surface-dsl.d.cts +8 -0
- package/dist/scaffold/surface-dsl.d.cts.map +1 -0
- package/dist/scaffold/surface-dsl.d.mts +8 -0
- package/dist/scaffold/surface-dsl.d.mts.map +1 -0
- package/dist/scaffold/surface-dsl.mjs +182 -0
- package/dist/scaffold/surface-dsl.mjs.map +1 -0
- package/dist/scaffold/surfaces.cjs +84 -0
- package/dist/scaffold/surfaces.d.cts +23 -0
- package/dist/scaffold/surfaces.d.cts.map +1 -0
- package/dist/scaffold/surfaces.d.mts +24 -0
- package/dist/scaffold/surfaces.d.mts.map +1 -0
- package/dist/scaffold/surfaces.mjs +84 -0
- package/dist/scaffold/surfaces.mjs.map +1 -0
- package/dist/scaffold/types.d.cts +264 -0
- package/dist/scaffold/types.d.cts.map +1 -0
- package/dist/scaffold/types.d.mts +265 -0
- package/dist/scaffold/types.d.mts.map +1 -0
- package/dist/scaffold/workspace-dsl.cjs +339 -0
- package/dist/scaffold/workspace-dsl.d.cts +49 -0
- package/dist/scaffold/workspace-dsl.d.cts.map +1 -0
- package/dist/scaffold/workspace-dsl.d.mts +49 -0
- package/dist/scaffold/workspace-dsl.d.mts.map +1 -0
- package/dist/scaffold/workspace-dsl.mjs +337 -0
- package/dist/scaffold/workspace-dsl.mjs.map +1 -0
- package/dist/scope/index.d.mts +3 -0
- package/dist/scope/read-blocklet-scope.cjs +29 -0
- package/dist/scope/read-blocklet-scope.d.cts +8 -0
- package/dist/scope/read-blocklet-scope.d.cts.map +1 -0
- package/dist/scope/read-blocklet-scope.d.mts +8 -0
- package/dist/scope/read-blocklet-scope.d.mts.map +1 -0
- package/dist/scope/read-blocklet-scope.mjs +30 -0
- package/dist/scope/read-blocklet-scope.mjs.map +1 -0
- package/dist/scope/resolve-scoped-afs.cjs +87 -0
- package/dist/scope/resolve-scoped-afs.d.cts +7 -0
- package/dist/scope/resolve-scoped-afs.d.cts.map +1 -0
- package/dist/scope/resolve-scoped-afs.d.mts +7 -0
- package/dist/scope/resolve-scoped-afs.d.mts.map +1 -0
- package/dist/scope/resolve-scoped-afs.mjs +88 -0
- package/dist/scope/resolve-scoped-afs.mjs.map +1 -0
- package/dist/scope/types.d.cts +25 -0
- package/dist/scope/types.d.cts.map +1 -0
- package/dist/scope/types.d.mts +25 -0
- package/dist/scope/types.d.mts.map +1 -0
- package/dist/session/backends.cjs +90 -0
- package/dist/session/backends.d.cts +35 -0
- package/dist/session/backends.d.cts.map +1 -0
- package/dist/session/backends.d.mts +35 -0
- package/dist/session/backends.d.mts.map +1 -0
- package/dist/session/backends.mjs +89 -0
- package/dist/session/backends.mjs.map +1 -0
- package/dist/session/replication-resolver.cjs +323 -0
- package/dist/session/replication-resolver.d.cts +71 -0
- package/dist/session/replication-resolver.d.cts.map +1 -0
- package/dist/session/replication-resolver.d.mts +71 -0
- package/dist/session/replication-resolver.d.mts.map +1 -0
- package/dist/session/replication-resolver.mjs +323 -0
- package/dist/session/replication-resolver.mjs.map +1 -0
- package/dist/session/role-level.cjs +36 -0
- package/dist/session/role-level.d.cts +24 -0
- package/dist/session/role-level.d.cts.map +1 -0
- package/dist/session/role-level.d.mts +24 -0
- package/dist/session/role-level.d.mts.map +1 -0
- package/dist/session/role-level.mjs +35 -0
- package/dist/session/role-level.mjs.map +1 -0
- package/dist/session/session-dir-providers.cjs +254 -0
- package/dist/session/session-dir-providers.d.cts +32 -0
- package/dist/session/session-dir-providers.d.cts.map +1 -0
- package/dist/session/session-dir-providers.d.mts +32 -0
- package/dist/session/session-dir-providers.d.mts.map +1 -0
- package/dist/session/session-dir-providers.mjs +252 -0
- package/dist/session/session-dir-providers.mjs.map +1 -0
- package/dist/session/session-id.cjs +20 -0
- package/dist/session/session-id.d.cts +15 -0
- package/dist/session/session-id.d.cts.map +1 -0
- package/dist/session/session-id.d.mts +15 -0
- package/dist/session/session-id.d.mts.map +1 -0
- package/dist/session/session-id.mjs +20 -0
- package/dist/session/session-id.mjs.map +1 -0
- package/dist/session/session-user-afs.cjs +899 -0
- package/dist/session/session-user-afs.d.cts +296 -0
- package/dist/session/session-user-afs.d.cts.map +1 -0
- package/dist/session/session-user-afs.d.mts +296 -0
- package/dist/session/session-user-afs.d.mts.map +1 -0
- package/dist/session/session-user-afs.mjs +896 -0
- package/dist/session/session-user-afs.mjs.map +1 -0
- package/dist/session/settings-cascade.cjs +69 -0
- package/dist/session/settings-cascade.d.cts +81 -0
- package/dist/session/settings-cascade.d.cts.map +1 -0
- package/dist/session/settings-cascade.d.mts +81 -0
- package/dist/session/settings-cascade.d.mts.map +1 -0
- package/dist/session/settings-cascade.mjs +69 -0
- package/dist/session/settings-cascade.mjs.map +1 -0
- package/dist/session/settings-resolver.cjs +770 -0
- package/dist/session/settings-resolver.d.cts +177 -0
- package/dist/session/settings-resolver.d.cts.map +1 -0
- package/dist/session/settings-resolver.d.mts +177 -0
- package/dist/session/settings-resolver.d.mts.map +1 -0
- package/dist/session/settings-resolver.mjs +771 -0
- package/dist/session/settings-resolver.mjs.map +1 -0
- package/dist/session/settings-schema-store.cjs +0 -0
- package/dist/session/settings-schema-store.d.cts +72 -0
- package/dist/session/settings-schema-store.d.cts.map +1 -0
- package/dist/session/settings-schema-store.d.mts +72 -0
- package/dist/session/settings-schema-store.d.mts.map +1 -0
- package/dist/session/settings-schema-store.mjs +0 -0
- package/dist/session/settings-schema-store.mjs.map +1 -0
- package/dist/system-mounts/index.cjs +14 -0
- package/dist/system-mounts/index.d.cts +6 -0
- package/dist/system-mounts/index.d.mts +6 -0
- package/dist/system-mounts/index.mjs +6 -0
- package/dist/system-mounts/install.cjs +101 -0
- package/dist/system-mounts/install.d.cts +36 -0
- package/dist/system-mounts/install.d.cts.map +1 -0
- package/dist/system-mounts/install.d.mts +37 -0
- package/dist/system-mounts/install.d.mts.map +1 -0
- package/dist/system-mounts/install.mjs +102 -0
- package/dist/system-mounts/install.mjs.map +1 -0
- package/dist/system-mounts/installers.cjs +247 -0
- package/dist/system-mounts/installers.d.cts +13 -0
- package/dist/system-mounts/installers.d.cts.map +1 -0
- package/dist/system-mounts/installers.d.mts +14 -0
- package/dist/system-mounts/installers.d.mts.map +1 -0
- package/dist/system-mounts/installers.mjs +244 -0
- package/dist/system-mounts/installers.mjs.map +1 -0
- package/dist/system-mounts/lists.cjs +122 -0
- package/dist/system-mounts/lists.d.cts +34 -0
- package/dist/system-mounts/lists.d.cts.map +1 -0
- package/dist/system-mounts/lists.d.mts +34 -0
- package/dist/system-mounts/lists.d.mts.map +1 -0
- package/dist/system-mounts/lists.mjs +122 -0
- package/dist/system-mounts/lists.mjs.map +1 -0
- package/dist/system-mounts/types.d.cts +124 -0
- package/dist/system-mounts/types.d.cts.map +1 -0
- package/dist/system-mounts/types.d.mts +125 -0
- package/dist/system-mounts/types.d.mts.map +1 -0
- package/dist/system-mounts/validate.cjs +56 -0
- package/dist/system-mounts/validate.d.cts +34 -0
- package/dist/system-mounts/validate.d.cts.map +1 -0
- package/dist/system-mounts/validate.d.mts +34 -0
- package/dist/system-mounts/validate.d.mts.map +1 -0
- package/dist/system-mounts/validate.mjs +56 -0
- package/dist/system-mounts/validate.mjs.map +1 -0
- package/dist/terminal-llm.cjs +90 -0
- package/dist/terminal-llm.d.cts +50 -0
- package/dist/terminal-llm.d.cts.map +1 -0
- package/dist/terminal-llm.d.mts +50 -0
- package/dist/terminal-llm.d.mts.map +1 -0
- package/dist/terminal-llm.mjs +90 -0
- package/dist/terminal-llm.mjs.map +1 -0
- package/dist/terminal-repl.cjs +371 -0
- package/dist/terminal-repl.d.cts +69 -0
- package/dist/terminal-repl.d.cts.map +1 -0
- package/dist/terminal-repl.d.mts +69 -0
- package/dist/terminal-repl.d.mts.map +1 -0
- package/dist/terminal-repl.mjs +370 -0
- package/dist/terminal-repl.mjs.map +1 -0
- package/dist/transport/idle-timer.cjs +136 -0
- package/dist/transport/idle-timer.d.cts +92 -0
- package/dist/transport/idle-timer.d.cts.map +1 -0
- package/dist/transport/idle-timer.d.mts +92 -0
- package/dist/transport/idle-timer.d.mts.map +1 -0
- package/dist/transport/idle-timer.mjs +132 -0
- package/dist/transport/idle-timer.mjs.map +1 -0
- package/dist/web-component-dsl.cjs +153 -0
- package/dist/web-component-dsl.d.cts +27 -0
- package/dist/web-component-dsl.d.cts.map +1 -0
- package/dist/web-component-dsl.d.mts +27 -0
- package/dist/web-component-dsl.d.mts.map +1 -0
- package/dist/web-component-dsl.mjs +152 -0
- package/dist/web-component-dsl.mjs.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dsl-shared.mjs","names":["start","startColumn"],"sources":["../src/dsl-shared.ts"],"sourcesContent":["export type DslTokenType = \"word\" | \"string\" | \"brace\";\n\nexport interface DslToken {\n type: DslTokenType;\n value: string;\n line: number;\n column: number;\n}\n\nexport interface DslField {\n children?: DslField[];\n name: DslToken;\n values: DslToken[];\n}\n\nexport interface DslDeclaration {\n headValues?: DslToken[];\n kind: string;\n id: string;\n idToken: DslToken;\n shorthand?: DslToken;\n title?: string;\n titleToken?: DslToken;\n fields: DslField[];\n}\n\nexport type DslErrorFactory = (message: string, line: number, column?: number) => Error;\n\nexport interface ParseDslDeclarationOptions {\n allowHeadValues?: boolean;\n allowMissingId?: boolean;\n allowQuotedId?: boolean;\n allowQuotedTitle?: boolean;\n allowShorthandString?: boolean;\n error: DslErrorFactory;\n expected?: string;\n fieldContinuationPreceders?: string[];\n fieldContinuationPairs?: Record<string, string[]>;\n fieldInlineContinuationKeywords?: Record<string, string[]>;\n fieldKeywords: string[];\n kind: string;\n nestedFieldKeywords?: string[];\n wildcardNestedFieldKeywords?: string[];\n}\n\nexport interface DslDeclarationSchema extends ParseDslDeclarationOptions {\n /**\n * Declarative head-shape alias for new DSL parsers. Legacy callers may still\n * pass the lower-level allow* flags directly through ParseDslDeclarationOptions.\n */\n idShape?: \"bare\" | \"quoted\" | \"bare-or-quoted\" | \"none\";\n takesInlineTitle?: boolean;\n}\n\nexport function parseDeclaration(source: string, schema: DslDeclarationSchema): DslDeclaration {\n const { idShape, takesInlineTitle, ...options } = schema;\n return parseDslDeclaration(source, {\n ...options,\n ...(idShape === \"none\" ? { allowMissingId: true } : {}),\n ...(idShape === \"quoted\" || idShape === \"bare-or-quoted\" ? { allowQuotedId: true } : {}),\n ...(takesInlineTitle ? { allowQuotedTitle: true } : {}),\n });\n}\n\nexport function parseDslDeclaration(\n source: string,\n options: ParseDslDeclarationOptions,\n): DslDeclaration {\n const tokens = tokenizeDsl(source, options.error);\n const expected = options.expected ?? `Expected ${options.kind} <id> {`;\n let index = 0;\n\n const kindToken = tokens[index];\n if (kindToken?.type !== \"word\" || kindToken.value !== options.kind) {\n throw options.error(expected, kindToken?.line ?? 1, kindToken?.column ?? 1);\n }\n index += 1;\n\n let idToken = tokens[index];\n if (options.allowMissingId && idToken?.type === \"brace\" && idToken.value === \"{\") {\n idToken = kindToken;\n } else if (\n !idToken ||\n (idToken.type !== \"word\" && (!options.allowQuotedId || idToken.type !== \"string\"))\n ) {\n throw options.error(\n expected,\n idToken?.line ?? kindToken.line,\n idToken?.column ?? kindToken.column,\n );\n } else {\n index += 1;\n }\n const id =\n idToken === kindToken && options.allowMissingId\n ? \"\"\n : idToken.type === \"string\"\n ? parseDslStringToken(idToken, options.error)\n : idToken.value;\n\n let next = tokens[index];\n let title: string | undefined;\n let titleToken: DslToken | undefined;\n if (options.allowQuotedTitle && next?.type === \"string\" && tokens[index + 1]?.value === \"{\") {\n title = parseDslStringToken(next, options.error);\n titleToken = next;\n index += 1;\n next = tokens[index];\n }\n\n if (options.allowShorthandString && next?.type === \"string\") {\n index += 1;\n if (index < tokens.length) {\n const trailing = tokens[index]!;\n throw options.error(\n `Unexpected content after ${options.kind} shorthand`,\n trailing.line,\n trailing.column,\n );\n }\n return { kind: options.kind, id, idToken, shorthand: next, fields: [] };\n }\n\n const headValues: DslToken[] = [];\n if (options.allowHeadValues) {\n while (next && (next.type !== \"brace\" || next.value !== \"{\")) {\n if (next.type === \"brace\") {\n throw options.error(expected, next.line, next.column);\n }\n headValues.push(next);\n index += 1;\n next = tokens[index];\n }\n }\n\n if (next?.type !== \"brace\" || next.value !== \"{\") {\n throw options.error(expected, next?.line ?? idToken.line, next?.column ?? idToken.column);\n }\n index += 1;\n\n const fieldKeywords = new Set(options.fieldKeywords);\n const fieldContinuationPreceders = new Set(options.fieldContinuationPreceders ?? []);\n const fieldContinuationPairs = new Map(\n Object.entries(options.fieldContinuationPairs ?? {}).map(([key, values]) => [\n key,\n new Set(values),\n ]),\n );\n const fieldInlineContinuationKeywords = new Map(\n Object.entries(options.fieldInlineContinuationKeywords ?? {}).map(([key, values]) => [\n key,\n new Set(values),\n ]),\n );\n const nestedFieldKeywords = new Set(options.nestedFieldKeywords ?? []);\n const wildcardNestedFieldKeywords = new Set(options.wildcardNestedFieldKeywords ?? []);\n const parsed = parseDslFields(tokens, index, {\n allowAnyFieldNames: false,\n error: options.error,\n fieldInlineContinuationKeywords,\n fieldContinuationPairs,\n fieldContinuationPreceders,\n fieldKeywords,\n kind: options.kind,\n nestedFieldKeywords,\n wildcardNestedFieldKeywords,\n });\n index = parsed.next;\n const close = tokens[index];\n if (close?.type === \"brace\" && close.value === \"}\") {\n index += 1;\n if (index < tokens.length) {\n const trailing = tokens[index]!;\n throw options.error(\n `Unexpected content after ${options.kind} block`,\n trailing.line,\n trailing.column,\n );\n }\n return {\n kind: options.kind,\n id,\n idToken,\n ...(title ? { title, titleToken } : {}),\n ...(headValues.length > 0 ? { headValues } : {}),\n fields: parsed.fields,\n };\n }\n\n const last = tokens[tokens.length - 1];\n throw options.error(`Unclosed ${options.kind} block`, last?.line ?? 1, last?.column ?? 1);\n}\n\ninterface ParseDslFieldsOptions {\n allowAnyFieldNames: boolean;\n error: DslErrorFactory;\n fieldContinuationPairs: Map<string, Set<string>>;\n fieldContinuationPreceders: Set<string>;\n fieldInlineContinuationKeywords: Map<string, Set<string>>;\n fieldKeywords: Set<string>;\n kind: string;\n nestedFieldKeywords: Set<string>;\n wildcardNestedFieldKeywords: Set<string>;\n}\n\nfunction parseDslFields(\n tokens: DslToken[],\n start: number,\n options: ParseDslFieldsOptions,\n): { fields: DslField[]; next: number } {\n const fields: DslField[] = [];\n let index = start;\n\n while (index < tokens.length) {\n const token = tokens[index]!;\n if (token.type === \"brace\" && token.value === \"}\") {\n return { fields, next: index };\n }\n if (\n token.type !== \"word\" ||\n (!options.allowAnyFieldNames && !options.fieldKeywords.has(token.value))\n ) {\n throw options.error(\n `Unknown ${options.kind} DSL statement: ${token.value}${formatSuggestion(\n didYouMean(token.value, options.fieldKeywords),\n )}`,\n token.line,\n token.column,\n );\n }\n\n const name = token;\n index += 1;\n const values: DslToken[] = [];\n let children: DslField[] | undefined;\n let braceDepth = 0;\n while (index < tokens.length) {\n const value = tokens[index]!;\n const previous = values.at(-1);\n if (value.type === \"brace\") {\n if (\n value.value === \"{\" &&\n braceDepth === 0 &&\n options.nestedFieldKeywords.has(name.value) &&\n !previous?.value.endsWith(\"=\") &&\n tokens[index + 1]?.type === \"word\"\n ) {\n const parsed = parseDslFields(tokens, index + 1, {\n ...options,\n allowAnyFieldNames: options.wildcardNestedFieldKeywords.has(name.value),\n });\n children = parsed.fields;\n index = parsed.next;\n const close = tokens[index];\n if (close?.type !== \"brace\" || close.value !== \"}\") {\n throw options.error(`Unclosed ${name.value} block`, value.line, value.column);\n }\n index += 1;\n break;\n }\n if (value.value === \"}\" && braceDepth === 0) break;\n if (value.value === \"{\") braceDepth += 1;\n if (value.value === \"}\") braceDepth -= 1;\n values.push(value);\n index += 1;\n continue;\n }\n const continuesField =\n previous?.type === \"word\" &&\n (options.fieldContinuationPreceders.has(previous.value) ||\n (value.type === \"word\" &&\n (options.fieldContinuationPairs.get(previous.value)?.has(value.value) ?? false)));\n const continuesInlineFieldKeyword =\n previous !== undefined &&\n value.type === \"word\" &&\n previous.line === value.line &&\n (options.fieldInlineContinuationKeywords.get(name.value)?.has(value.value) ?? false);\n const startsWildcardSibling =\n options.allowAnyFieldNames &&\n value.type === \"word\" &&\n value.line > name.line &&\n braceDepth === 0;\n if (startsWildcardSibling) break;\n if (\n value.type === \"word\" &&\n options.fieldKeywords.has(value.value) &&\n !continuesField &&\n !continuesInlineFieldKeyword &&\n braceDepth === 0\n ) {\n break;\n }\n values.push(value);\n index += 1;\n }\n fields.push({ name, values, ...(children ? { children } : {}) });\n }\n\n return { fields, next: index };\n}\n\nexport function tokenizeDsl(source: string, error: DslErrorFactory): DslToken[] {\n const tokens: DslToken[] = [];\n let line = 1;\n let column = 1;\n let index = 0;\n\n while (index < source.length) {\n const char = source[index];\n if (char === \"\\n\") {\n line += 1;\n column = 1;\n index += 1;\n continue;\n }\n if (/\\s/.test(char ?? \"\")) {\n column += 1;\n index += 1;\n continue;\n }\n if (char === \"#\") {\n while (index < source.length && source[index] !== \"\\n\") {\n index += 1;\n column += 1;\n }\n continue;\n }\n if (char === \"/\" && source[index + 1] === \"/\") {\n while (index < source.length && source[index] !== \"\\n\") {\n index += 1;\n column += 1;\n }\n continue;\n }\n if (char === \"{\" || char === \"}\") {\n tokens.push({ type: \"brace\", value: char, line, column });\n index += 1;\n column += 1;\n continue;\n }\n if (char === '\"') {\n const start = index;\n const startColumn = column;\n index += 1;\n column += 1;\n let escaped = false;\n while (index < source.length) {\n const current = source[index];\n if (current === \"\\n\") throw error(\"Unclosed string literal\", line, startColumn);\n index += 1;\n column += 1;\n if (escaped) {\n escaped = false;\n } else if (current === \"\\\\\") {\n escaped = true;\n } else if (current === '\"') {\n break;\n }\n }\n tokens.push({ type: \"string\", value: source.slice(start, index), line, column: startColumn });\n continue;\n }\n\n const start = index;\n const startColumn = column;\n while (\n index < source.length &&\n !/\\s/.test(source[index] ?? \"\") &&\n source[index] !== \"{\" &&\n source[index] !== \"}\" &&\n // Break on `\"` so the next iteration enters string mode. Without this,\n // `value=\"...\"` would consume the `\"` as part of the word, leaving `{`\n // and `}` inside the user's JSON string to be mis-parsed as braces.\n source[index] !== '\"'\n ) {\n index += 1;\n column += 1;\n }\n tokens.push({ type: \"word\", value: source.slice(start, index), line, column: startColumn });\n }\n\n return tokens;\n}\n\nexport function parseDslStringToken(token: DslToken, error: DslErrorFactory): string {\n if (token.type !== \"string\") throw error(\"Expected string\", token.line, token.column);\n try {\n const value = JSON.parse(token.value);\n if (typeof value !== \"string\") throw new Error(\"expected string\");\n return value;\n } catch (err) {\n throw error(\n `Invalid string literal: ${err instanceof Error ? err.message : String(err)}`,\n token.line,\n token.column,\n );\n }\n}\n\nexport function parseDslScalarToken(token: DslToken, error: DslErrorFactory): unknown {\n if (token.type === \"string\") return parseDslStringToken(token, error);\n if (token.type !== \"word\") throw error(\"Expected value\", token.line, token.column);\n if (token.value === \"true\") return true;\n if (token.value === \"false\") return false;\n const number = Number(token.value);\n if (Number.isFinite(number) && String(number) === token.value) return number;\n return token.value;\n}\n\nfunction formatSuggestion(suggestion?: string): string {\n return suggestion ? `. Did you mean \"${suggestion}\"?` : \"\";\n}\n\nfunction didYouMean(value: string, candidates: Iterable<string>): string | undefined {\n const normalized = value.toLowerCase();\n let best: { distance: number; value: string } | undefined;\n for (const candidate of candidates) {\n const distance = levenshtein(normalized, candidate.toLowerCase());\n if (!best || distance < best.distance) best = { distance, value: candidate };\n }\n if (!best) return undefined;\n const threshold = Math.max(2, Math.floor(Math.max(value.length, best.value.length) / 3));\n return best.distance <= threshold ? best.value : undefined;\n}\n\nfunction levenshtein(a: string, b: string): number {\n if (a === b) return 0;\n if (a.length === 0) return b.length;\n if (b.length === 0) return a.length;\n\n const previous = Array.from({ length: b.length + 1 }, (_, index) => index);\n const current = Array.from({ length: b.length + 1 }, () => 0);\n\n for (let i = 1; i <= a.length; i += 1) {\n current[0] = i;\n for (let j = 1; j <= b.length; j += 1) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n current[j] = Math.min(current[j - 1]! + 1, previous[j]! + 1, previous[j - 1]! + cost);\n }\n for (let j = 0; j <= b.length; j += 1) previous[j] = current[j]!;\n }\n\n return previous[b.length]!;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const require_server = require('../mcp/server.cjs');
|
|
2
|
+
const require_auth_context = require('./auth-context.cjs');
|
|
3
|
+
const require_request_context = require('./request-context.cjs');
|
|
4
|
+
let _modelcontextprotocol_sdk_inMemory_js = require("@modelcontextprotocol/sdk/inMemory.js");
|
|
5
|
+
|
|
6
|
+
//#region src/http/afs-mcp.ts
|
|
7
|
+
const JSON_HEADERS = { "Content-Type": "application/json; charset=utf-8" };
|
|
8
|
+
function jsonResponse(status, body) {
|
|
9
|
+
return new Response(JSON.stringify(body), {
|
|
10
|
+
status,
|
|
11
|
+
headers: { ...JSON_HEADERS }
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A JSON-RPC message is a *notification* (or a response) when it carries no
|
|
16
|
+
* `id`; such messages produce no reply. Per the MCP Streamable HTTP spec, a POST
|
|
17
|
+
* whose payload is solely notifications/responses MUST be answered with 202
|
|
18
|
+
* Accepted and no body. A single message or a batch (array) is accepted.
|
|
19
|
+
*
|
|
20
|
+
* This matters because the standard handshake sends `notifications/initialized`
|
|
21
|
+
* immediately after `initialize`. Without this guard the stateless round-trip
|
|
22
|
+
* below `await`s a response message that never arrives, so the request hangs
|
|
23
|
+
* until the runtime kills it (on CF: ~11s → a 1101 exception) and the client
|
|
24
|
+
* reports "failed to connect".
|
|
25
|
+
*/
|
|
26
|
+
function isNotificationOnly(body) {
|
|
27
|
+
const isNotif = (m) => typeof m === "object" && m !== null && m.id === void 0;
|
|
28
|
+
return Array.isArray(body) ? body.length > 0 && body.every(isNotif) : isNotif(body);
|
|
29
|
+
}
|
|
30
|
+
function createAfsMcpHandler(options) {
|
|
31
|
+
const { globalAFS, name, version } = options;
|
|
32
|
+
const ctx = require_request_context.createAfsRequestContext(options);
|
|
33
|
+
return async (request) => {
|
|
34
|
+
if (request.method !== "POST") return jsonResponse(405, { error: "Method Not Allowed" });
|
|
35
|
+
let scopedAFS = globalAFS;
|
|
36
|
+
let opContext;
|
|
37
|
+
if (options.resolveCaller) {
|
|
38
|
+
const caller = await ctx.resolveCaller(request);
|
|
39
|
+
if (!caller) return jsonResponse(401, { error: "Unauthorized" });
|
|
40
|
+
const blocklet = await ctx.resolveBlocklet(request);
|
|
41
|
+
if (blocklet) try {
|
|
42
|
+
const scoped = await ctx.resolveScoped(request, {
|
|
43
|
+
blocklet,
|
|
44
|
+
sessionId: null,
|
|
45
|
+
caller
|
|
46
|
+
});
|
|
47
|
+
scopedAFS = scoped.afs;
|
|
48
|
+
opContext = scoped.context;
|
|
49
|
+
} catch {
|
|
50
|
+
return jsonResponse(500, { error: "Internal Server Error" });
|
|
51
|
+
}
|
|
52
|
+
else opContext = require_auth_context.mergeCallerContext({}, caller, { callerOrigin: "network" });
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const body = await request.json();
|
|
56
|
+
if (isNotificationOnly(body)) return new Response(null, { status: 202 });
|
|
57
|
+
const mcpServer = require_server.createArcMcpServer(scopedAFS, {
|
|
58
|
+
name,
|
|
59
|
+
version,
|
|
60
|
+
context: opContext
|
|
61
|
+
});
|
|
62
|
+
const [clientTransport, serverTransport] = _modelcontextprotocol_sdk_inMemory_js.InMemoryTransport.createLinkedPair();
|
|
63
|
+
const responsePromise = new Promise((resolve) => {
|
|
64
|
+
clientTransport.onmessage = (msg) => resolve(msg);
|
|
65
|
+
});
|
|
66
|
+
await mcpServer.connect(serverTransport);
|
|
67
|
+
await clientTransport.send(body);
|
|
68
|
+
const response = await responsePromise;
|
|
69
|
+
await Promise.all([clientTransport.close(), serverTransport.close()]);
|
|
70
|
+
return jsonResponse(200, response);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
return jsonResponse(200, {
|
|
73
|
+
jsonrpc: "2.0",
|
|
74
|
+
error: {
|
|
75
|
+
code: -32603,
|
|
76
|
+
message: error instanceof Error ? error.message : "Internal error"
|
|
77
|
+
},
|
|
78
|
+
id: null
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
exports.createAfsMcpHandler = createAfsMcpHandler;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AfsRequestContextOptions } from "./request-context.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/http/afs-mcp.d.ts
|
|
4
|
+
interface AfsMcpHandlerOptions extends AfsRequestContextOptions {
|
|
5
|
+
/** MCP server name forwarded to createArcMcpServer. */
|
|
6
|
+
name: string;
|
|
7
|
+
/** MCP server version forwarded to createArcMcpServer. */
|
|
8
|
+
version: string;
|
|
9
|
+
}
|
|
10
|
+
type AfsMcpHandler = (request: Request) => Promise<Response>;
|
|
11
|
+
declare function createAfsMcpHandler(options: AfsMcpHandlerOptions): AfsMcpHandler;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { AfsMcpHandler, AfsMcpHandlerOptions, createAfsMcpHandler };
|
|
14
|
+
//# sourceMappingURL=afs-mcp.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"afs-mcp.d.cts","names":[],"sources":["../../src/http/afs-mcp.ts"],"mappings":";;;UAgDiB,oBAAA,SAA6B,wBAAA;EAOW;EALvD,IAAA;EAKoC;EAHpC,OAAA;AAAA;AAAA,KAGU,aAAA,IAAiB,OAAA,EAAS,OAAA,KAAY,OAAA,CAAQ,QAAA;AAAA,iBAE1C,mBAAA,CAAoB,OAAA,EAAS,oBAAA,GAAuB,aAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AfsRequestContextOptions } from "./request-context.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/http/afs-mcp.d.ts
|
|
4
|
+
interface AfsMcpHandlerOptions extends AfsRequestContextOptions {
|
|
5
|
+
/** MCP server name forwarded to createArcMcpServer. */
|
|
6
|
+
name: string;
|
|
7
|
+
/** MCP server version forwarded to createArcMcpServer. */
|
|
8
|
+
version: string;
|
|
9
|
+
}
|
|
10
|
+
type AfsMcpHandler = (request: Request) => Promise<Response>;
|
|
11
|
+
declare function createAfsMcpHandler(options: AfsMcpHandlerOptions): AfsMcpHandler;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { AfsMcpHandler, AfsMcpHandlerOptions, createAfsMcpHandler };
|
|
14
|
+
//# sourceMappingURL=afs-mcp.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"afs-mcp.d.mts","names":[],"sources":["../../src/http/afs-mcp.ts"],"mappings":";;;UAgDiB,oBAAA,SAA6B,wBAAA;EAOW;EALvD,IAAA;EAKoC;EAHpC,OAAA;AAAA;AAAA,KAGU,aAAA,IAAiB,OAAA,EAAS,OAAA,KAAY,OAAA,CAAQ,QAAA;AAAA,iBAE1C,mBAAA,CAAoB,OAAA,EAAS,oBAAA,GAAuB,aAAA"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { createArcMcpServer } from "../mcp/server.mjs";
|
|
2
|
+
import { mergeCallerContext } from "./auth-context.mjs";
|
|
3
|
+
import { createAfsRequestContext } from "./request-context.mjs";
|
|
4
|
+
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
5
|
+
|
|
6
|
+
//#region src/http/afs-mcp.ts
|
|
7
|
+
const JSON_HEADERS = { "Content-Type": "application/json; charset=utf-8" };
|
|
8
|
+
function jsonResponse(status, body) {
|
|
9
|
+
return new Response(JSON.stringify(body), {
|
|
10
|
+
status,
|
|
11
|
+
headers: { ...JSON_HEADERS }
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A JSON-RPC message is a *notification* (or a response) when it carries no
|
|
16
|
+
* `id`; such messages produce no reply. Per the MCP Streamable HTTP spec, a POST
|
|
17
|
+
* whose payload is solely notifications/responses MUST be answered with 202
|
|
18
|
+
* Accepted and no body. A single message or a batch (array) is accepted.
|
|
19
|
+
*
|
|
20
|
+
* This matters because the standard handshake sends `notifications/initialized`
|
|
21
|
+
* immediately after `initialize`. Without this guard the stateless round-trip
|
|
22
|
+
* below `await`s a response message that never arrives, so the request hangs
|
|
23
|
+
* until the runtime kills it (on CF: ~11s → a 1101 exception) and the client
|
|
24
|
+
* reports "failed to connect".
|
|
25
|
+
*/
|
|
26
|
+
function isNotificationOnly(body) {
|
|
27
|
+
const isNotif = (m) => typeof m === "object" && m !== null && m.id === void 0;
|
|
28
|
+
return Array.isArray(body) ? body.length > 0 && body.every(isNotif) : isNotif(body);
|
|
29
|
+
}
|
|
30
|
+
function createAfsMcpHandler(options) {
|
|
31
|
+
const { globalAFS, name, version } = options;
|
|
32
|
+
const ctx = createAfsRequestContext(options);
|
|
33
|
+
return async (request) => {
|
|
34
|
+
if (request.method !== "POST") return jsonResponse(405, { error: "Method Not Allowed" });
|
|
35
|
+
let scopedAFS = globalAFS;
|
|
36
|
+
let opContext;
|
|
37
|
+
if (options.resolveCaller) {
|
|
38
|
+
const caller = await ctx.resolveCaller(request);
|
|
39
|
+
if (!caller) return jsonResponse(401, { error: "Unauthorized" });
|
|
40
|
+
const blocklet = await ctx.resolveBlocklet(request);
|
|
41
|
+
if (blocklet) try {
|
|
42
|
+
const scoped = await ctx.resolveScoped(request, {
|
|
43
|
+
blocklet,
|
|
44
|
+
sessionId: null,
|
|
45
|
+
caller
|
|
46
|
+
});
|
|
47
|
+
scopedAFS = scoped.afs;
|
|
48
|
+
opContext = scoped.context;
|
|
49
|
+
} catch {
|
|
50
|
+
return jsonResponse(500, { error: "Internal Server Error" });
|
|
51
|
+
}
|
|
52
|
+
else opContext = mergeCallerContext({}, caller, { callerOrigin: "network" });
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const body = await request.json();
|
|
56
|
+
if (isNotificationOnly(body)) return new Response(null, { status: 202 });
|
|
57
|
+
const mcpServer = createArcMcpServer(scopedAFS, {
|
|
58
|
+
name,
|
|
59
|
+
version,
|
|
60
|
+
context: opContext
|
|
61
|
+
});
|
|
62
|
+
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
63
|
+
const responsePromise = new Promise((resolve) => {
|
|
64
|
+
clientTransport.onmessage = (msg) => resolve(msg);
|
|
65
|
+
});
|
|
66
|
+
await mcpServer.connect(serverTransport);
|
|
67
|
+
await clientTransport.send(body);
|
|
68
|
+
const response = await responsePromise;
|
|
69
|
+
await Promise.all([clientTransport.close(), serverTransport.close()]);
|
|
70
|
+
return jsonResponse(200, response);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
return jsonResponse(200, {
|
|
73
|
+
jsonrpc: "2.0",
|
|
74
|
+
error: {
|
|
75
|
+
code: -32603,
|
|
76
|
+
message: error instanceof Error ? error.message : "Internal error"
|
|
77
|
+
},
|
|
78
|
+
id: null
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
export { createAfsMcpHandler };
|
|
86
|
+
//# sourceMappingURL=afs-mcp.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"afs-mcp.mjs","names":[],"sources":["../../src/http/afs-mcp.ts"],"sourcesContent":["/**\n * Stateless MCP-over-HTTP handler for AFS (InMemoryTransport, CF-style).\n *\n * Companion to afs-rpc.ts: instead of AFS CRUD ops, this endpoint exposes an\n * MCP (Model Context Protocol) server so AI agents can call AFS tools over a\n * plain POST request — no WebSocket or SSE stream required.\n *\n * Key differences from afs-rpc:\n * - Auth is required: null caller → 401. Unlike afs-rpc where null = anonymous,\n * MCP always rejects unauthenticated callers when resolveCaller is configured.\n * - Null blocklet → globalAFS (unlike afs-rpc → 400). MCP is a host-level API;\n * if no blocklet context is resolvable, the global AFS topology is served.\n * - Stateless: InMemoryTransport, one POST = one JSON-RPC exchange. No sessions.\n * - Per-request McpServer: required because createArcMcpServer binds AFS at\n * construction time; different callers need different scoped instances.\n */\n\nimport type { AFS, AFSContext, AFSRoot } from \"@aigne/afs\";\nimport { InMemoryTransport } from \"@modelcontextprotocol/sdk/inMemory.js\";\nimport { createArcMcpServer } from \"../mcp/server.js\";\nimport { mergeCallerContext } from \"./auth-context.js\";\nimport type { AfsRequestContextOptions } from \"./request-context.js\";\nimport { createAfsRequestContext } from \"./request-context.js\";\n\nconst JSON_HEADERS = { \"Content-Type\": \"application/json; charset=utf-8\" } as const;\n\nfunction jsonResponse(status: number, body: unknown): Response {\n return new Response(JSON.stringify(body), { status, headers: { ...JSON_HEADERS } });\n}\n\n/**\n * A JSON-RPC message is a *notification* (or a response) when it carries no\n * `id`; such messages produce no reply. Per the MCP Streamable HTTP spec, a POST\n * whose payload is solely notifications/responses MUST be answered with 202\n * Accepted and no body. A single message or a batch (array) is accepted.\n *\n * This matters because the standard handshake sends `notifications/initialized`\n * immediately after `initialize`. Without this guard the stateless round-trip\n * below `await`s a response message that never arrives, so the request hangs\n * until the runtime kills it (on CF: ~11s → a 1101 exception) and the client\n * reports \"failed to connect\".\n */\nfunction isNotificationOnly(body: unknown): boolean {\n const isNotif = (m: unknown): boolean =>\n typeof m === \"object\" && m !== null && (m as { id?: unknown }).id === undefined;\n return Array.isArray(body) ? body.length > 0 && body.every(isNotif) : isNotif(body);\n}\n\nexport interface AfsMcpHandlerOptions extends AfsRequestContextOptions {\n /** MCP server name forwarded to createArcMcpServer. */\n name: string;\n /** MCP server version forwarded to createArcMcpServer. */\n version: string;\n}\n\nexport type AfsMcpHandler = (request: Request) => Promise<Response>;\n\nexport function createAfsMcpHandler(options: AfsMcpHandlerOptions): AfsMcpHandler {\n const { globalAFS, name, version } = options;\n const ctx = createAfsRequestContext(options);\n\n return async (request: Request): Promise<Response> => {\n if (request.method !== \"POST\") {\n return jsonResponse(405, { error: \"Method Not Allowed\" });\n }\n\n let scopedAFS: AFSRoot = globalAFS;\n // Per-request op context threaded into every MCP tool call so the exec-effect\n // and SessionUserAFS base-write gates engage (both key on\n // callerOrigin === \"network\"). Undefined in local/open mode (no resolveCaller)\n // — tools then run as trusted-internal, matching the pre-auth behaviour.\n let opContext: AFSContext | undefined;\n\n if (options.resolveCaller) {\n // Auth gate: when resolveCaller is configured, null → 401.\n // This is the deliberate contrast with afs-rpc where null = anonymous.\n const caller = await ctx.resolveCaller(request);\n if (!caller) {\n return jsonResponse(401, { error: \"Unauthorized\" });\n }\n\n // Blocklet resolution: null → globalAFS (unlike afs-rpc → 400).\n const blocklet = await ctx.resolveBlocklet(request);\n if (blocklet) {\n // Fail-closed: if scoped AFS construction fails (blocklet not found,\n // resolver error, etc.), return 500 rather than silently degrading to\n // globalAFS — degradation would expose a wider view than intended.\n try {\n const scoped = await ctx.resolveScoped(request, {\n blocklet,\n sessionId: null,\n caller,\n });\n scopedAFS = scoped.afs;\n opContext = scoped.context as AFSContext;\n } catch {\n return jsonResponse(500, { error: \"Internal Server Error\" });\n }\n } else {\n // Root mode (no blocklet resolvable): still stamp a verified network\n // caller context so mutations against the global AFS pass through the\n // same gates a scoped call does (authenticated write allowed; anonymous\n // / forbidden base writes rejected) instead of running trusted-internal.\n opContext = mergeCallerContext({}, caller, { callerOrigin: \"network\" }) as AFSContext;\n }\n }\n\n // Per-request McpServer + InMemoryTransport (one POST = one JSON-RPC round-trip).\n try {\n const body = await request.json();\n // Notifications / responses (no `id`) produce no reply → 202, no body.\n // Otherwise the `await responsePromise` below never resolves and the POST\n // hangs — this is what broke the `notifications/initialized` handshake step.\n if (isNotificationOnly(body)) {\n return new Response(null, { status: 202 });\n }\n // Cast: AFSRoot is the interface; AFS is the implementing class that\n // createArcMcpServer requires for getMounts(). All runtime instances are AFS.\n const mcpServer = createArcMcpServer(scopedAFS as AFS, { name, version, context: opContext });\n const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();\n const responsePromise = new Promise<unknown>((resolve) => {\n clientTransport.onmessage = (msg) => resolve(msg);\n });\n await mcpServer.connect(serverTransport);\n await clientTransport.send(body as Parameters<typeof clientTransport.send>[0]);\n const response = await responsePromise;\n await Promise.all([clientTransport.close(), serverTransport.close()]);\n return jsonResponse(200, response);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Internal error\";\n return jsonResponse(200, { jsonrpc: \"2.0\", error: { code: -32603, message }, id: null });\n }\n };\n}\n"],"mappings":";;;;;;AAwBA,MAAM,eAAe,EAAE,gBAAgB,mCAAmC;AAE1E,SAAS,aAAa,QAAgB,MAAyB;AAC7D,QAAO,IAAI,SAAS,KAAK,UAAU,KAAK,EAAE;EAAE;EAAQ,SAAS,EAAE,GAAG,cAAc;EAAE,CAAC;;;;;;;;;;;;;;AAerF,SAAS,mBAAmB,MAAwB;CAClD,MAAM,WAAW,MACf,OAAO,MAAM,YAAY,MAAM,QAAS,EAAuB,OAAO;AACxE,QAAO,MAAM,QAAQ,KAAK,GAAG,KAAK,SAAS,KAAK,KAAK,MAAM,QAAQ,GAAG,QAAQ,KAAK;;AAYrF,SAAgB,oBAAoB,SAA8C;CAChF,MAAM,EAAE,WAAW,MAAM,YAAY;CACrC,MAAM,MAAM,wBAAwB,QAAQ;AAE5C,QAAO,OAAO,YAAwC;AACpD,MAAI,QAAQ,WAAW,OACrB,QAAO,aAAa,KAAK,EAAE,OAAO,sBAAsB,CAAC;EAG3D,IAAI,YAAqB;EAKzB,IAAI;AAEJ,MAAI,QAAQ,eAAe;GAGzB,MAAM,SAAS,MAAM,IAAI,cAAc,QAAQ;AAC/C,OAAI,CAAC,OACH,QAAO,aAAa,KAAK,EAAE,OAAO,gBAAgB,CAAC;GAIrD,MAAM,WAAW,MAAM,IAAI,gBAAgB,QAAQ;AACnD,OAAI,SAIF,KAAI;IACF,MAAM,SAAS,MAAM,IAAI,cAAc,SAAS;KAC9C;KACA,WAAW;KACX;KACD,CAAC;AACF,gBAAY,OAAO;AACnB,gBAAY,OAAO;WACb;AACN,WAAO,aAAa,KAAK,EAAE,OAAO,yBAAyB,CAAC;;OAO9D,aAAY,mBAAmB,EAAE,EAAE,QAAQ,EAAE,cAAc,WAAW,CAAC;;AAK3E,MAAI;GACF,MAAM,OAAO,MAAM,QAAQ,MAAM;AAIjC,OAAI,mBAAmB,KAAK,CAC1B,QAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,KAAK,CAAC;GAI5C,MAAM,YAAY,mBAAmB,WAAkB;IAAE;IAAM;IAAS,SAAS;IAAW,CAAC;GAC7F,MAAM,CAAC,iBAAiB,mBAAmB,kBAAkB,kBAAkB;GAC/E,MAAM,kBAAkB,IAAI,SAAkB,YAAY;AACxD,oBAAgB,aAAa,QAAQ,QAAQ,IAAI;KACjD;AACF,SAAM,UAAU,QAAQ,gBAAgB;AACxC,SAAM,gBAAgB,KAAK,KAAmD;GAC9E,MAAM,WAAW,MAAM;AACvB,SAAM,QAAQ,IAAI,CAAC,gBAAgB,OAAO,EAAE,gBAAgB,OAAO,CAAC,CAAC;AACrE,UAAO,aAAa,KAAK,SAAS;WAC3B,OAAO;AAEd,UAAO,aAAa,KAAK;IAAE,SAAS;IAAO,OAAO;KAAE,MAAM;KAAQ,SADlD,iBAAiB,QAAQ,MAAM,UAAU;KACkB;IAAE,IAAI;IAAM,CAAC"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
const require_request_context = require('./request-context.cjs');
|
|
2
|
+
const require_afs_rpc = require('./afs-rpc.cjs');
|
|
3
|
+
const require_raw_url = require('./raw-url.cjs');
|
|
4
|
+
let _aigne_afs = require("@aigne/afs");
|
|
5
|
+
let _aigne_afs_provider_utils = require("@aigne/afs-provider-utils");
|
|
6
|
+
|
|
7
|
+
//#region src/http/afs-raw.ts
|
|
8
|
+
/**
|
|
9
|
+
* `GET /api/afs/raw` — raw-bytes endpoint (afs-preview T2.1, design §3).
|
|
10
|
+
*
|
|
11
|
+
* Lets `<img>` / `<iframe>` / `<video>` reference AFS content that is too
|
|
12
|
+
* large to inline as a data URL. AFS-Only I/O: the handler speaks ONLY the
|
|
13
|
+
* scoped AFS API (`stat` + `read`) — never CAS/R2/disk.
|
|
14
|
+
*
|
|
15
|
+
* TWO auth modes (afs-raw cookie mode):
|
|
16
|
+
* - SIGNED (sig query present): a bearer URL whose HMAC binds
|
|
17
|
+
* path+sid+caller+blocklet (raw-url.ts). The ONLY mode that can serve an
|
|
18
|
+
* anonymous caller or a cookie-less context — sandboxed PDF iframe (no
|
|
19
|
+
* `allow-same-origin` ⇒ null origin ⇒ no cookie), cross-origin embeds,
|
|
20
|
+
* public share links. Issued server-side because signing needs the secret.
|
|
21
|
+
* - COOKIE (no sig): a same-origin AUTHENTICATED GET — feed/list `<img>`
|
|
22
|
+
* cards. Identity is the verified session cookie (resolveCaller); the
|
|
23
|
+
* scoped `/user` overlay grants the SAME read authz as afs-rpc, so no
|
|
24
|
+
* bearer URL is minted. `SameSite=Lax` on the session cookie means a
|
|
25
|
+
* cross-site subresource (`<img>` from another origin) carries NO cookie ⇒
|
|
26
|
+
* 401/403, so this can't be hotlinked/CSRF'd; and the only cross-site case
|
|
27
|
+
* Lax DOES allow (top-level nav) only ever exposes the caller's OWN `/user`
|
|
28
|
+
* space to themselves. Anonymous (no cookie) is refused here — an
|
|
29
|
+
* unauthenticated reader must use a signed URL. No per-render server
|
|
30
|
+
* pre-signing, no `exp` churn ⇒ the URL is stable (cacheable later).
|
|
31
|
+
*
|
|
32
|
+
* Processing order (the contract — every step fail-closed):
|
|
33
|
+
* 1. method gate (GET) → 405
|
|
34
|
+
* 2. signing secret present? → else 503 (no signing = no endpoint)
|
|
35
|
+
* 3. cookie caller resolution (anonymous OK in SIGNED mode — symmetry is
|
|
36
|
+
* enforced by the signature, see raw-url.ts)
|
|
37
|
+
* 4. auth: SIGNED → `verifyRawUrl` (sig/exp/caller-binding/anonymous-
|
|
38
|
+
* private-path) any failure → 403; COOKIE → require non-anonymous caller
|
|
39
|
+
* (else 403) + `?path=` (else 400)
|
|
40
|
+
* 5. `sanitizeAfsPath` (single shared entry — no local normalize/reorder)
|
|
41
|
+
* → 400
|
|
42
|
+
* 6. blocklet resolution (query/host alias/first-label) → 400
|
|
43
|
+
* 7. scoped AFS via the shared request-context helper. SIGNED passes the
|
|
44
|
+
* EXPLICIT signature-verified sessionId (never a `rpc-<blocklet>`-style
|
|
45
|
+
* fallback); COOKIE passes null (the `/user` overlay keys on caller.did)
|
|
46
|
+
* 8a. media-302 (preview-r2-direct): MEDIA (image/video/audio) over
|
|
47
|
+
* `RAW_REDIRECT_MIN_BYTES` with a presign-capable scoped AFS → 302 to a
|
|
48
|
+
* presigned R2 GET. Runs AFTER the size-validity check but BEFORE the
|
|
49
|
+
* `maxBytes` cap (cap-exempt — R2's ceiling is the object size); the
|
|
50
|
+
* worker never buffers these bytes. Falls through to 8b on null.
|
|
51
|
+
* 8b. `afs.stat` size cap — over `maxBytes` → 413 BEFORE any read; size
|
|
52
|
+
* missing → conservative 413 (read-after-judge would defeat the memory
|
|
53
|
+
* guardrail)
|
|
54
|
+
* 9. `afs.read` → bytes → response with `Content-Type` (meta.mimeType,
|
|
55
|
+
* fallback shared detectMimeType), `X-Content-Type-Options: nosniff`
|
|
56
|
+
* (mandatory — binary serving endpoint), `Cache-Control: private,
|
|
57
|
+
* no-store`. #818: a CLIENT-DECLARED browser-scriptable type
|
|
58
|
+
* (`isScriptableMimeType`: text/html, image/svg+xml, xml, JS variants) is
|
|
59
|
+
* NEVER served inline — forced to `application/octet-stream` +
|
|
60
|
+
* `Content-Disposition: attachment` + CSP sandbox + `X-Frame-Options: DENY`
|
|
61
|
+
* (nosniff alone can't stop a genuinely-declared scriptable type executing).
|
|
62
|
+
*
|
|
63
|
+
* Cache semantics: this handler owns its OWN request-context instance —
|
|
64
|
+
* code shared with afs-rpc, runtime state (projection cache) NOT shared.
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* Default max served size — 100 MiB (413 above; streaming/Range is a separate
|
|
68
|
+
* project). upload-limits Phase 6 (D4 interim): raised 50→100 MiB to ALIGN with
|
|
69
|
+
* the grant upload cap (`AFS_DID_SPACE_UPLOAD_MAX_BYTES`, 100 MiB) so a file the
|
|
70
|
+
* upload plane accepts can be raw-served, closing the G4 upload/serve asymmetry
|
|
71
|
+
* for the worker-serve path. This is the NODE/default ceiling (Node can buffer
|
|
72
|
+
* 100 MiB once). It is NOT runtime-uniform: the CF Worker passes a much smaller
|
|
73
|
+
* `maxBytes` (~4 MiB, preview-r2-direct's runtime-aware clean-413) because a
|
|
74
|
+
* one-shot read of ≳8 MiB OOMs the worker (Error 1102 → 503); CF non-media over
|
|
75
|
+
* that gets a CLEAN 413 (never a crash), and CF MEDIA over the gate is exempt via
|
|
76
|
+
* the 302→R2-direct path above. The 50→100 doubling of one-shot read memory on
|
|
77
|
+
* Node is the known interim cost; true large serve needs streaming/Range.
|
|
78
|
+
*/
|
|
79
|
+
const RAW_MAX_BYTES_DEFAULT = 100 * 1024 * 1024;
|
|
80
|
+
/**
|
|
81
|
+
* Media over this size redirect (302) to a presigned object-store GET instead of
|
|
82
|
+
* being served by the worker (preview-r2-direct §4 / Review-B). v1 = 32 KB, locked
|
|
83
|
+
* equal to `PREVIEW_IMAGE_INLINE_MAX` (the user-locked "> 32 KB → R2-direct"
|
|
84
|
+
* decision; maximizes worker-offload). The correctness floor is the worker cliff
|
|
85
|
+
* (~4–8 MiB); anything below is a worker-offload-vs-first-byte-latency CHOICE, and
|
|
86
|
+
* a future raise is a measurement-gated, OPTIONAL post-ship activity — NOT a gate.
|
|
87
|
+
*/
|
|
88
|
+
const RAW_REDIRECT_MIN_BYTES = 32 * 1024;
|
|
89
|
+
/**
|
|
90
|
+
* The 302 path is MEDIA-ONLY (preview-r2-direct §5 / Review-1): only `image/*`,
|
|
91
|
+
* `video/*`, `audio/*` are script-safe to redirect cross-origin to R2 (the
|
|
92
|
+
* presigned URL drops `nosniff`; a media element never executes mislabeled
|
|
93
|
+
* bytes). SVG (`image/svg+xml`) matches `image/*` here but is EXCLUDED from the
|
|
94
|
+
* redirect at the call site via `isScriptableMimeType` (#818 supersedes the old
|
|
95
|
+
* Review-A "SVG rides image/*" behavior): a scripted SVG is browser-scriptable,
|
|
96
|
+
* so it falls through to worker-serve, which forces a safe attachment. PDF/HTML/
|
|
97
|
+
* text MUST stay on the worker (iframe `noSandbox`/`_isSameOriginUrl` depends on
|
|
98
|
+
* same-origin + nosniff; text is client-rendered → `fetch` → CORS-gated).
|
|
99
|
+
*/
|
|
100
|
+
function isRedirectableMediaType(mime) {
|
|
101
|
+
const m = mime.toLowerCase();
|
|
102
|
+
return m.startsWith("image/") || m.startsWith("video/") || m.startsWith("audio/");
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Browser-scriptable MIME types (#818). `meta.mimeType` is CLIENT-CONTROLLED —
|
|
106
|
+
* any writer can declare it, there is no write-side allowlist, and this endpoint
|
|
107
|
+
* serves anonymous bearer URLs (public share links). If we echo a declared
|
|
108
|
+
* scriptable type as an inline `Content-Type`, the bytes execute in the serving
|
|
109
|
+
* origin → stored XSS. `X-Content-Type-Options: nosniff` does NOT help here: it
|
|
110
|
+
* only stops sniffing of MIS-labeled bytes; a GENUINELY-declared `text/html`
|
|
111
|
+
* (or scripted `image/svg+xml`) still runs. So at the serve boundary — the
|
|
112
|
+
* provider-agnostic place — these are forced to a non-executing disposition
|
|
113
|
+
* (octet-stream + `Content-Disposition: attachment`) and can never render inline.
|
|
114
|
+
*
|
|
115
|
+
* SVG is included: rendered inline (top-level nav / `<embed>`/`<object>`) a
|
|
116
|
+
* scripted SVG executes same-origin. It is ALSO excluded from the 302→R2 media
|
|
117
|
+
* redirect below (falls through to worker-serve, which forces attachment).
|
|
118
|
+
*/
|
|
119
|
+
const SCRIPTABLE_MIME_TYPES = new Set([
|
|
120
|
+
"text/html",
|
|
121
|
+
"application/xhtml+xml",
|
|
122
|
+
"image/svg+xml",
|
|
123
|
+
"text/xml",
|
|
124
|
+
"application/xml",
|
|
125
|
+
"text/javascript",
|
|
126
|
+
"application/javascript",
|
|
127
|
+
"application/x-javascript",
|
|
128
|
+
"text/ecmascript",
|
|
129
|
+
"application/ecmascript",
|
|
130
|
+
"application/x-ecmascript"
|
|
131
|
+
]);
|
|
132
|
+
/** True when a MIME type can execute script if rendered inline (#818). */
|
|
133
|
+
function isScriptableMimeType(mime) {
|
|
134
|
+
const base = mime.toLowerCase().split(";", 1)[0]?.trim() ?? "";
|
|
135
|
+
return SCRIPTABLE_MIME_TYPES.has(base);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* A header-safe `filename` for `Content-Disposition: attachment` (#818). The
|
|
139
|
+
* path is already `sanitizeAfsPath`-clean (no traversal), but strip quotes /
|
|
140
|
+
* backslashes / CR-LF defensively so the value can never break out of the
|
|
141
|
+
* header or inject a second directive.
|
|
142
|
+
*/
|
|
143
|
+
function attachmentFilename(path) {
|
|
144
|
+
return (path.split("/").pop() || "download").replace(/["\\\r\n]/g, "_") || "download";
|
|
145
|
+
}
|
|
146
|
+
const RAW_HEADERS_BASE = {
|
|
147
|
+
"X-Content-Type-Options": "nosniff",
|
|
148
|
+
"Cache-Control": "private, no-store"
|
|
149
|
+
};
|
|
150
|
+
function deny(status, text) {
|
|
151
|
+
return new Response(text, {
|
|
152
|
+
status,
|
|
153
|
+
headers: {
|
|
154
|
+
...RAW_HEADERS_BASE,
|
|
155
|
+
"Content-Type": "text/plain; charset=utf-8"
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/** Normalize an AFS read result's content to raw bytes. Null = no bytes. */
|
|
160
|
+
function contentToBytes(content, encoding) {
|
|
161
|
+
if (content instanceof Uint8Array) return content;
|
|
162
|
+
if (content instanceof ArrayBuffer) return new Uint8Array(content);
|
|
163
|
+
if (typeof content === "string") {
|
|
164
|
+
if (encoding === "base64") try {
|
|
165
|
+
return Uint8Array.from(atob(content), (c) => c.charCodeAt(0));
|
|
166
|
+
} catch {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
return new TextEncoder().encode(content);
|
|
170
|
+
}
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
function createAfsRawHandler(options) {
|
|
174
|
+
const reqCtx = require_request_context.createAfsRequestContext(options);
|
|
175
|
+
const maxBytes = options.maxBytes ?? RAW_MAX_BYTES_DEFAULT;
|
|
176
|
+
return async function handleRaw(request) {
|
|
177
|
+
try {
|
|
178
|
+
return await handleInner(request);
|
|
179
|
+
} catch (err) {
|
|
180
|
+
return deny(require_afs_rpc.statusForError(err), "Internal error");
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
async function handleInner(request) {
|
|
184
|
+
if (request.method !== "GET") return deny(405, "Method Not Allowed (use GET)");
|
|
185
|
+
const secret = options.rawUrlSecret;
|
|
186
|
+
if (!secret || typeof secret === "string" && secret.length === 0) return deny(503, "raw endpoint unavailable (signing key not configured)");
|
|
187
|
+
const caller = await reqCtx.resolveCaller(request);
|
|
188
|
+
const callerDid = caller?.did ?? null;
|
|
189
|
+
const url = new URL(request.url);
|
|
190
|
+
const hasSignature = url.searchParams.has("sig");
|
|
191
|
+
let rawPath;
|
|
192
|
+
let sessionId;
|
|
193
|
+
let signedBlocklet;
|
|
194
|
+
if (hasSignature) {
|
|
195
|
+
const verdict = await require_raw_url.verifyRawUrl(request, callerDid, { secret });
|
|
196
|
+
if (!verdict.ok) return deny(403, "Forbidden");
|
|
197
|
+
rawPath = verdict.path;
|
|
198
|
+
sessionId = verdict.sessionId;
|
|
199
|
+
signedBlocklet = verdict.blocklet;
|
|
200
|
+
} else {
|
|
201
|
+
if (!callerDid) return deny(403, "Forbidden");
|
|
202
|
+
const qPath = url.searchParams.get("path");
|
|
203
|
+
if (!qPath) return deny(400, "Invalid path");
|
|
204
|
+
rawPath = qPath;
|
|
205
|
+
sessionId = null;
|
|
206
|
+
signedBlocklet = url.searchParams.get("blocklet");
|
|
207
|
+
}
|
|
208
|
+
const safePath = (0, _aigne_afs.sanitizeAfsPath)(rawPath);
|
|
209
|
+
if (safePath === null) return deny(400, "Invalid path");
|
|
210
|
+
const blocklet = await reqCtx.resolveBlocklet(request, signedBlocklet);
|
|
211
|
+
if (!blocklet) return deny(400, "Could not resolve blocklet");
|
|
212
|
+
const scoped = await reqCtx.resolveScoped(request, {
|
|
213
|
+
blocklet,
|
|
214
|
+
sessionId,
|
|
215
|
+
caller
|
|
216
|
+
});
|
|
217
|
+
if (!scoped.afs.stat || !scoped.afs.read) return deny(501, "stat/read not supported");
|
|
218
|
+
const statData = (await scoped.afs.stat(safePath, { context: scoped.context }))?.data ?? {};
|
|
219
|
+
const meta = statData.meta ?? {};
|
|
220
|
+
const size = typeof statData.size === "number" ? statData.size : typeof meta.size === "number" ? meta.size : void 0;
|
|
221
|
+
if (typeof size !== "number" || !Number.isFinite(size) || size < 0) return deny(413, "Content size unknown");
|
|
222
|
+
const statMimeType = typeof meta.mimeType === "string" && meta.mimeType || (0, _aigne_afs_provider_utils.detectMimeType)(safePath) || "application/octet-stream";
|
|
223
|
+
if (size > RAW_REDIRECT_MIN_BYTES && isRedirectableMediaType(statMimeType) && !isScriptableMimeType(statMimeType) && typeof scoped.afs.presignRead === "function") {
|
|
224
|
+
let grant = null;
|
|
225
|
+
try {
|
|
226
|
+
grant = await scoped.afs.presignRead(safePath, { responseContentType: statMimeType });
|
|
227
|
+
} catch {
|
|
228
|
+
grant = null;
|
|
229
|
+
}
|
|
230
|
+
if (grant) return new Response(null, {
|
|
231
|
+
status: 302,
|
|
232
|
+
headers: {
|
|
233
|
+
Location: grant.url,
|
|
234
|
+
"Cache-Control": "private, no-store",
|
|
235
|
+
"Referrer-Policy": "no-referrer"
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
if (size > maxBytes) return deny(413, "Content too large");
|
|
240
|
+
const data = (await scoped.afs.read(safePath, { context: scoped.context }))?.data ?? {};
|
|
241
|
+
const encoding = data.encoding ?? (data.meta?.contentType === "base64" || data.meta?.encoding === "base64" ? "base64" : void 0);
|
|
242
|
+
const bytes = contentToBytes(data.content, encoding);
|
|
243
|
+
if (!bytes) return deny(404, "No content");
|
|
244
|
+
const mimeType = typeof meta.mimeType === "string" && meta.mimeType || typeof data.meta?.mimeType === "string" && data.meta.mimeType || (0, _aigne_afs_provider_utils.detectMimeType)(safePath) || "application/octet-stream";
|
|
245
|
+
const headers = {
|
|
246
|
+
...RAW_HEADERS_BASE,
|
|
247
|
+
"Content-Length": String(bytes.length)
|
|
248
|
+
};
|
|
249
|
+
if (isScriptableMimeType(mimeType)) {
|
|
250
|
+
headers["Content-Type"] = "application/octet-stream";
|
|
251
|
+
headers["Content-Disposition"] = `attachment; filename="${attachmentFilename(safePath)}"`;
|
|
252
|
+
headers["Content-Security-Policy"] = "default-src 'none'; sandbox";
|
|
253
|
+
headers["X-Frame-Options"] = "DENY";
|
|
254
|
+
} else headers["Content-Type"] = mimeType;
|
|
255
|
+
return new Response(bytes, {
|
|
256
|
+
status: 200,
|
|
257
|
+
headers
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
//#endregion
|
|
263
|
+
exports.RAW_MAX_BYTES_DEFAULT = RAW_MAX_BYTES_DEFAULT;
|
|
264
|
+
exports.createAfsRawHandler = createAfsRawHandler;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { AfsRequestContextOptions } from "./request-context.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/http/afs-raw.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Default max served size — 100 MiB (413 above; streaming/Range is a separate
|
|
6
|
+
* project). upload-limits Phase 6 (D4 interim): raised 50→100 MiB to ALIGN with
|
|
7
|
+
* the grant upload cap (`AFS_DID_SPACE_UPLOAD_MAX_BYTES`, 100 MiB) so a file the
|
|
8
|
+
* upload plane accepts can be raw-served, closing the G4 upload/serve asymmetry
|
|
9
|
+
* for the worker-serve path. This is the NODE/default ceiling (Node can buffer
|
|
10
|
+
* 100 MiB once). It is NOT runtime-uniform: the CF Worker passes a much smaller
|
|
11
|
+
* `maxBytes` (~4 MiB, preview-r2-direct's runtime-aware clean-413) because a
|
|
12
|
+
* one-shot read of ≳8 MiB OOMs the worker (Error 1102 → 503); CF non-media over
|
|
13
|
+
* that gets a CLEAN 413 (never a crash), and CF MEDIA over the gate is exempt via
|
|
14
|
+
* the 302→R2-direct path above. The 50→100 doubling of one-shot read memory on
|
|
15
|
+
* Node is the known interim cost; true large serve needs streaming/Range.
|
|
16
|
+
*/
|
|
17
|
+
declare const RAW_MAX_BYTES_DEFAULT: number;
|
|
18
|
+
interface AfsRawHandlerOptions extends AfsRequestContextOptions {
|
|
19
|
+
/**
|
|
20
|
+
* HMAC secret for signed raw URLs (Node: vault-derived; CF: env secret).
|
|
21
|
+
* ABSENT → every request answers 503 (fail-closed: no key, no endpoint —
|
|
22
|
+
* never an unsigned/degraded mode).
|
|
23
|
+
*/
|
|
24
|
+
rawUrlSecret?: string | Uint8Array;
|
|
25
|
+
/** Size cap in bytes (default 50MB). */
|
|
26
|
+
maxBytes?: number;
|
|
27
|
+
}
|
|
28
|
+
declare function createAfsRawHandler(options: AfsRawHandlerOptions): (request: Request) => Promise<Response>;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { AfsRawHandlerOptions, RAW_MAX_BYTES_DEFAULT, createAfsRawHandler };
|
|
31
|
+
//# sourceMappingURL=afs-raw.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"afs-raw.d.cts","names":[],"sources":["../../src/http/afs-raw.ts"],"mappings":";;;;;;;;;;;;;;;;cA8Ea,qBAAA;AAAA,UA2EI,oBAAA,SAA6B,wBAAA;;;;;;EAM5C,YAAA,YAAwB,UAAA;;EAExB,QAAA;AAAA;AAAA,iBAkCc,mBAAA,CACd,OAAA,EAAS,oBAAA,IACP,OAAA,EAAS,OAAA,KAAY,OAAA,CAAQ,QAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { AfsRequestContextOptions } from "./request-context.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/http/afs-raw.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Default max served size — 100 MiB (413 above; streaming/Range is a separate
|
|
6
|
+
* project). upload-limits Phase 6 (D4 interim): raised 50→100 MiB to ALIGN with
|
|
7
|
+
* the grant upload cap (`AFS_DID_SPACE_UPLOAD_MAX_BYTES`, 100 MiB) so a file the
|
|
8
|
+
* upload plane accepts can be raw-served, closing the G4 upload/serve asymmetry
|
|
9
|
+
* for the worker-serve path. This is the NODE/default ceiling (Node can buffer
|
|
10
|
+
* 100 MiB once). It is NOT runtime-uniform: the CF Worker passes a much smaller
|
|
11
|
+
* `maxBytes` (~4 MiB, preview-r2-direct's runtime-aware clean-413) because a
|
|
12
|
+
* one-shot read of ≳8 MiB OOMs the worker (Error 1102 → 503); CF non-media over
|
|
13
|
+
* that gets a CLEAN 413 (never a crash), and CF MEDIA over the gate is exempt via
|
|
14
|
+
* the 302→R2-direct path above. The 50→100 doubling of one-shot read memory on
|
|
15
|
+
* Node is the known interim cost; true large serve needs streaming/Range.
|
|
16
|
+
*/
|
|
17
|
+
declare const RAW_MAX_BYTES_DEFAULT: number;
|
|
18
|
+
interface AfsRawHandlerOptions extends AfsRequestContextOptions {
|
|
19
|
+
/**
|
|
20
|
+
* HMAC secret for signed raw URLs (Node: vault-derived; CF: env secret).
|
|
21
|
+
* ABSENT → every request answers 503 (fail-closed: no key, no endpoint —
|
|
22
|
+
* never an unsigned/degraded mode).
|
|
23
|
+
*/
|
|
24
|
+
rawUrlSecret?: string | Uint8Array;
|
|
25
|
+
/** Size cap in bytes (default 50MB). */
|
|
26
|
+
maxBytes?: number;
|
|
27
|
+
}
|
|
28
|
+
declare function createAfsRawHandler(options: AfsRawHandlerOptions): (request: Request) => Promise<Response>;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { AfsRawHandlerOptions, RAW_MAX_BYTES_DEFAULT, createAfsRawHandler };
|
|
31
|
+
//# sourceMappingURL=afs-raw.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"afs-raw.d.mts","names":[],"sources":["../../src/http/afs-raw.ts"],"mappings":";;;;;;;;;;;;;;;;cA8Ea,qBAAA;AAAA,UA2EI,oBAAA,SAA6B,wBAAA;;;;;;EAM5C,YAAA,YAAwB,UAAA;;EAExB,QAAA;AAAA;AAAA,iBAkCc,mBAAA,CACd,OAAA,EAAS,oBAAA,IACP,OAAA,EAAS,OAAA,KAAY,OAAA,CAAQ,QAAA"}
|