@maudecode/talaria-web 1.17.2 → 1.19.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/_release.json +8 -8
- package/dist/api/auth-raw.d.ts +1 -1
- package/dist/api/auth-raw.js +20 -20
- package/dist/api/auth-raw.js.map +1 -1
- package/dist/api/automation-raw.d.ts +7 -1
- package/dist/api/automation-raw.js +74 -27
- package/dist/api/automation-raw.js.map +1 -1
- package/dist/api/automation-router.d.ts +128 -23
- package/dist/api/automation-router.js +29 -13
- package/dist/api/automation-router.js.map +1 -1
- package/dist/api/chat-router.d.ts +1845 -40
- package/dist/api/chat-router.js +196 -114
- package/dist/api/chat-router.js.map +1 -1
- package/dist/api/git-router.d.ts +37 -3
- package/dist/api/git-router.js +47 -48
- package/dist/api/git-router.js.map +1 -1
- package/dist/api/raw-routes.d.ts +9 -1
- package/dist/api/raw-routes.js +286 -73
- package/dist/api/raw-routes.js.map +1 -1
- package/dist/api/router.d.ts +16 -6
- package/dist/api/router.js +28 -26
- package/dist/api/router.js.map +1 -1
- package/dist/api/session-visibility.d.ts +4 -4
- package/dist/api/session-visibility.js +26 -16
- package/dist/api/session-visibility.js.map +1 -1
- package/dist/api/sessions-router.d.ts +3312 -131
- package/dist/api/sessions-router.js +287 -157
- package/dist/api/sessions-router.js.map +1 -1
- package/dist/api/settings-router.d.ts +457 -8
- package/dist/api/settings-router.js +54 -33
- package/dist/api/settings-router.js.map +1 -1
- package/dist/api/sse-routes.d.ts +7 -2
- package/dist/api/sse-routes.js +109 -62
- package/dist/api/sse-routes.js.map +1 -1
- package/dist/api/tools-raw.d.ts +5 -0
- package/dist/api/tools-raw.js +63 -55
- package/dist/api/tools-raw.js.map +1 -1
- package/dist/api/tools-router.d.ts +998 -85
- package/dist/api/tools-router.js +447 -61
- package/dist/api/tools-router.js.map +1 -1
- package/dist/api/transcribe-stream.d.ts +16 -0
- package/dist/api/transcribe-stream.js +172 -0
- package/dist/api/transcribe-stream.js.map +1 -0
- package/dist/app.d.ts +4 -1
- package/dist/app.js +98 -59
- package/dist/app.js.map +1 -1
- package/dist/auth/gate.js +15 -11
- package/dist/auth/gate.js.map +1 -1
- package/dist/auth/oidc.d.ts +5 -2
- package/dist/auth/oidc.js +8 -7
- package/dist/auth/oidc.js.map +1 -1
- package/dist/auth/passkeys.d.ts +15 -14
- package/dist/auth/passkeys.js +89 -91
- package/dist/auth/passkeys.js.map +1 -1
- package/dist/auth/store.d.ts +17 -7
- package/dist/auth/store.js +93 -52
- package/dist/auth/store.js.map +1 -1
- package/dist/bin/talaria-web.js +12 -81
- package/dist/bin/talaria-web.js.map +1 -1
- package/dist/cli/ctl.js +2 -1
- package/dist/cli/ctl.js.map +1 -1
- package/dist/cli/dotenv.d.ts +5 -0
- package/dist/cli/dotenv.js +15 -2
- package/dist/cli/dotenv.js.map +1 -1
- package/dist/cli/launcher.js +5 -5
- package/dist/cli/launcher.js.map +1 -1
- package/dist/cli/main.d.ts +1 -0
- package/dist/cli/main.js +85 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/supervise.d.ts +2 -0
- package/dist/cli/supervise.js +67 -4
- package/dist/cli/supervise.js.map +1 -1
- package/dist/config/agent-config.d.ts +34 -11
- package/dist/config/agent-config.js +116 -60
- package/dist/config/agent-config.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.js +19 -6
- package/dist/config.js.map +1 -1
- package/dist/fs/atomic.d.ts +1 -0
- package/dist/fs/atomic.js +4 -1
- package/dist/fs/atomic.js.map +1 -1
- package/dist/fs/stat.d.ts +1 -0
- package/dist/fs/stat.js +11 -0
- package/dist/fs/stat.js.map +1 -0
- package/dist/http/context.d.ts +31 -12
- package/dist/http/context.js +60 -24
- package/dist/http/context.js.map +1 -1
- package/dist/http/csp.d.ts +2 -1
- package/dist/http/csp.js +3 -2
- package/dist/http/csp.js.map +1 -1
- package/dist/onboarding.d.ts +2 -2
- package/dist/onboarding.js +10 -8
- package/dist/onboarding.js.map +1 -1
- package/dist/profiles/profiles.d.ts +20 -4
- package/dist/profiles/profiles.js +115 -30
- package/dist/profiles/profiles.js.map +1 -1
- package/dist/projects.d.ts +15 -6
- package/dist/projects.js +55 -47
- package/dist/projects.js.map +1 -1
- package/dist/providers/catalog.d.ts +84 -14
- package/dist/providers/catalog.js +474 -151
- package/dist/providers/catalog.js.map +1 -1
- package/dist/providers/env-file.d.ts +10 -3
- package/dist/providers/env-file.js +24 -75
- package/dist/providers/env-file.js.map +1 -1
- package/dist/providers/runtime-env.d.ts +4 -2
- package/dist/providers/runtime-env.js +9 -6
- package/dist/providers/runtime-env.js.map +1 -1
- package/dist/providers/tables.d.ts +3 -1
- package/dist/providers/tables.js +4 -2
- package/dist/providers/tables.js.map +1 -1
- package/dist/raster-image.d.ts +7 -0
- package/dist/raster-image.js +267 -0
- package/dist/raster-image.js.map +1 -0
- package/dist/redact.js +342 -46
- package/dist/redact.js.map +1 -1
- package/dist/release.d.ts +7 -0
- package/dist/release.js +14 -0
- package/dist/release.js.map +1 -1
- package/dist/runtime.d.ts +5 -1
- package/dist/runtime.js +305 -96
- package/dist/runtime.js.map +1 -1
- package/dist/server.js +15 -0
- package/dist/server.js.map +1 -1
- package/dist/sessions/anchor.d.ts +9 -3
- package/dist/sessions/anchor.js +28 -36
- package/dist/sessions/anchor.js.map +1 -1
- package/dist/sessions/background-events.d.ts +2 -0
- package/dist/sessions/background-events.js +10 -0
- package/dist/sessions/background-events.js.map +1 -0
- package/dist/sessions/background-tasks.d.ts +26 -27
- package/dist/sessions/background-tasks.js +89 -97
- package/dist/sessions/background-tasks.js.map +1 -1
- package/dist/sessions/background-updates.d.ts +15 -8
- package/dist/sessions/background-updates.js +101 -25
- package/dist/sessions/background-updates.js.map +1 -1
- package/dist/sessions/cli-sessions.d.ts +27 -6
- package/dist/sessions/cli-sessions.js +152 -42
- package/dist/sessions/cli-sessions.js.map +1 -1
- package/dist/sessions/completions.d.ts +77 -9
- package/dist/sessions/completions.js +482 -45
- package/dist/sessions/completions.js.map +1 -1
- package/dist/sessions/compress.d.ts +8 -0
- package/dist/sessions/compress.js +2 -2
- package/dist/sessions/compress.js.map +1 -1
- package/dist/sessions/drafts.d.ts +14 -10
- package/dist/sessions/drafts.js +38 -43
- package/dist/sessions/drafts.js.map +1 -1
- package/dist/sessions/export.d.ts +5 -0
- package/dist/sessions/export.js +30 -0
- package/dist/sessions/export.js.map +1 -1
- package/dist/sessions/gateway-sessions.d.ts +46 -0
- package/dist/sessions/gateway-sessions.js +378 -0
- package/dist/sessions/gateway-sessions.js.map +1 -0
- package/dist/sessions/gateway-watcher.d.ts +7 -3
- package/dist/sessions/gateway-watcher.js +31 -19
- package/dist/sessions/gateway-watcher.js.map +1 -1
- package/dist/sessions/goals.d.ts +31 -0
- package/dist/sessions/goals.js +75 -0
- package/dist/sessions/goals.js.map +1 -0
- package/dist/sessions/handoff.d.ts +32 -0
- package/dist/sessions/handoff.js +114 -0
- package/dist/sessions/handoff.js.map +1 -0
- package/dist/sessions/journal.d.ts +5 -79
- package/dist/sessions/journal.js +15 -606
- package/dist/sessions/journal.js.map +1 -1
- package/dist/sessions/list.d.ts +31 -16
- package/dist/sessions/list.js +139 -129
- package/dist/sessions/list.js.map +1 -1
- package/dist/sessions/merge.d.ts +69 -13
- package/dist/sessions/merge.js +265 -64
- package/dist/sessions/merge.js.map +1 -1
- package/dist/sessions/notices.d.ts +22 -0
- package/dist/sessions/notices.js +72 -0
- package/dist/sessions/notices.js.map +1 -0
- package/dist/sessions/pending.d.ts +10 -4
- package/dist/sessions/pending.js +83 -7
- package/dist/sessions/pending.js.map +1 -1
- package/dist/sessions/prefix-index.d.ts +82 -0
- package/dist/sessions/prefix-index.js +232 -0
- package/dist/sessions/prefix-index.js.map +1 -0
- package/dist/sessions/recovery.d.ts +19 -0
- package/dist/sessions/recovery.js +322 -0
- package/dist/sessions/recovery.js.map +1 -0
- package/dist/sessions/relay.d.ts +38 -19
- package/dist/sessions/relay.js +302 -79
- package/dist/sessions/relay.js.map +1 -1
- package/dist/sessions/service.d.ts +260 -55
- package/dist/sessions/service.js +1448 -462
- package/dist/sessions/service.js.map +1 -1
- package/dist/sessions/session.d.ts +24 -2
- package/dist/sessions/session.js +69 -7
- package/dist/sessions/session.js.map +1 -1
- package/dist/sessions/shares.d.ts +7 -6
- package/dist/sessions/shares.js +22 -45
- package/dist/sessions/shares.js.map +1 -1
- package/dist/sessions/source-kind.js +1 -0
- package/dist/sessions/source-kind.js.map +1 -1
- package/dist/sessions/state-db-identity.d.ts +18 -0
- package/dist/sessions/state-db-identity.js +67 -0
- package/dist/sessions/state-db-identity.js.map +1 -0
- package/dist/sessions/state-db-worker.d.ts +1 -0
- package/dist/sessions/state-db-worker.js +35 -0
- package/dist/sessions/state-db-worker.js.map +1 -0
- package/dist/sessions/state-db.d.ts +113 -7
- package/dist/sessions/state-db.js +861 -44
- package/dist/sessions/state-db.js.map +1 -1
- package/dist/sessions/storage/backend.d.ts +162 -0
- package/dist/sessions/storage/backend.js +19 -0
- package/dist/sessions/storage/backend.js.map +1 -0
- package/dist/sessions/storage/conformance.d.ts +20 -0
- package/dist/sessions/storage/conformance.js +237 -0
- package/dist/sessions/storage/conformance.js.map +1 -0
- package/dist/sessions/storage/document.d.ts +16 -0
- package/dist/sessions/storage/document.js +44 -0
- package/dist/sessions/storage/document.js.map +1 -0
- package/dist/sessions/storage/json-documents.d.ts +23 -0
- package/dist/sessions/storage/json-documents.js +233 -0
- package/dist/sessions/storage/json-documents.js.map +1 -0
- package/dist/sessions/storage/json-files.d.ts +12 -0
- package/dist/sessions/storage/json-files.js +124 -0
- package/dist/sessions/storage/json-files.js.map +1 -0
- package/dist/sessions/storage/json-installation.d.ts +3 -0
- package/dist/sessions/storage/json-installation.js +31 -0
- package/dist/sessions/storage/json-installation.js.map +1 -0
- package/dist/sessions/storage/json-journal.d.ts +114 -0
- package/dist/sessions/storage/json-journal.js +686 -0
- package/dist/sessions/storage/json-journal.js.map +1 -0
- package/dist/sessions/storage/json-recovery.d.ts +4 -0
- package/dist/sessions/storage/json-recovery.js +195 -0
- package/dist/sessions/storage/json-recovery.js.map +1 -0
- package/dist/sessions/storage/json.d.ts +68 -0
- package/dist/sessions/storage/json.js +258 -0
- package/dist/sessions/storage/json.js.map +1 -0
- package/dist/sessions/storage/row.d.ts +6 -0
- package/dist/sessions/storage/row.js +49 -0
- package/dist/sessions/storage/row.js.map +1 -0
- package/dist/sessions/storage/search-text.d.ts +4 -0
- package/dist/sessions/storage/search-text.js +16 -0
- package/dist/sessions/storage/search-text.js.map +1 -0
- package/dist/sessions/store.d.ts +65 -68
- package/dist/sessions/store.js +305 -602
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/streams.d.ts +4 -0
- package/dist/sessions/streams.js +9 -1
- package/dist/sessions/streams.js.map +1 -1
- package/dist/sessions/titles.d.ts +2 -0
- package/dist/sessions/titles.js +5 -1
- package/dist/sessions/titles.js.map +1 -1
- package/dist/sessions/todo.d.ts +5 -0
- package/dist/sessions/todo.js +28 -21
- package/dist/sessions/todo.js.map +1 -1
- package/dist/sessions/tool-display.d.ts +5 -4
- package/dist/sessions/tool-display.js +30 -50
- package/dist/sessions/tool-display.js.map +1 -1
- package/dist/sessions/turn-context.d.ts +11 -2
- package/dist/sessions/turn-context.js +18 -11
- package/dist/sessions/turn-context.js.map +1 -1
- package/dist/sessions/turn.d.ts +122 -17
- package/dist/sessions/turn.js +939 -358
- package/dist/sessions/turn.js.map +1 -1
- package/dist/sessions/wakeup-pause.d.ts +54 -0
- package/dist/sessions/wakeup-pause.js +163 -0
- package/dist/sessions/wakeup-pause.js.map +1 -0
- package/dist/sessions/window.js +13 -12
- package/dist/sessions/window.js.map +1 -1
- package/dist/settings.d.ts +19 -7
- package/dist/settings.js +178 -184
- package/dist/settings.js.map +1 -1
- package/dist/sidecar/client.d.ts +17 -3
- package/dist/sidecar/client.js +78 -8
- package/dist/sidecar/client.js.map +1 -1
- package/dist/sidecar/discover.d.ts +2 -1
- package/dist/sidecar/discover.js +93 -10
- package/dist/sidecar/discover.js.map +1 -1
- package/dist/sidecar/env.d.ts +4 -0
- package/dist/sidecar/env.js +3 -0
- package/dist/sidecar/env.js.map +1 -0
- package/dist/sidecar/fake.d.ts +2 -2
- package/dist/sidecar/fake.js +19 -2
- package/dist/sidecar/fake.js.map +1 -1
- package/dist/startup.d.ts +13 -5
- package/dist/startup.js +48 -0
- package/dist/startup.js.map +1 -1
- package/dist/test/env-file.d.ts +5 -0
- package/dist/test/env-file.js +88 -0
- package/dist/test/env-file.js.map +1 -0
- package/dist/test/harness.d.ts +1 -0
- package/dist/test/harness.js +1 -1
- package/dist/test/harness.js.map +1 -1
- package/dist/test/passkeys.d.ts +22 -0
- package/dist/test/passkeys.js +62 -0
- package/dist/test/passkeys.js.map +1 -0
- package/dist/test/storage.d.ts +15 -0
- package/dist/test/storage.js +26 -0
- package/dist/test/storage.js.map +1 -0
- package/dist/test/ts-worker-hooks.d.ts +1 -0
- package/dist/test/ts-worker-hooks.js +24 -0
- package/dist/test/ts-worker-hooks.js.map +1 -0
- package/dist/text/diff.d.ts +9 -14
- package/dist/text/diff.js +74 -108
- package/dist/text/diff.js.map +1 -1
- package/dist/tools/commands.d.ts +6 -1
- package/dist/tools/commands.js +8 -2
- package/dist/tools/commands.js.map +1 -1
- package/dist/tools/connectors.d.ts +33 -0
- package/dist/tools/connectors.js +121 -0
- package/dist/tools/connectors.js.map +1 -0
- package/dist/tools/crons.d.ts +38 -1
- package/dist/tools/crons.js +122 -18
- package/dist/tools/crons.js.map +1 -1
- package/dist/tools/dashboard-plugins.d.ts +53 -0
- package/dist/tools/dashboard-plugins.js +188 -0
- package/dist/tools/dashboard-plugins.js.map +1 -0
- package/dist/tools/extensions.d.ts +18 -5
- package/dist/tools/extensions.js +344 -266
- package/dist/tools/extensions.js.map +1 -1
- package/dist/tools/gateway-restart.d.ts +62 -0
- package/dist/tools/gateway-restart.js +142 -0
- package/dist/tools/gateway-restart.js.map +1 -0
- package/dist/tools/health.d.ts +44 -0
- package/dist/tools/health.js +201 -46
- package/dist/tools/health.js.map +1 -1
- package/dist/tools/hygiene.d.ts +4 -3
- package/dist/tools/hygiene.js +23 -9
- package/dist/tools/hygiene.js.map +1 -1
- package/dist/tools/kanban.d.ts +4 -2
- package/dist/tools/kanban.js +28 -19
- package/dist/tools/kanban.js.map +1 -1
- package/dist/tools/mcp.d.ts +13 -0
- package/dist/tools/mcp.js +88 -0
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/memory-masks.d.ts +5 -0
- package/dist/tools/memory-masks.js +256 -0
- package/dist/tools/memory-masks.js.map +1 -0
- package/dist/tools/memory.d.ts +29 -3
- package/dist/tools/memory.js +69 -27
- package/dist/tools/memory.js.map +1 -1
- package/dist/tools/plugin-settings.d.ts +15 -0
- package/dist/tools/plugin-settings.js +90 -0
- package/dist/tools/plugin-settings.js.map +1 -0
- package/dist/tools/project-os.d.ts +11 -0
- package/dist/tools/project-os.js +267 -0
- package/dist/tools/project-os.js.map +1 -0
- package/dist/tools/skills.d.ts +14 -5
- package/dist/tools/skills.js +49 -16
- package/dist/tools/skills.js.map +1 -1
- package/dist/tools/update-notifications.d.ts +34 -15
- package/dist/tools/update-notifications.js +141 -57
- package/dist/tools/update-notifications.js.map +1 -1
- package/dist/tools/update-rollback.d.ts +11 -0
- package/dist/tools/update-rollback.js +28 -0
- package/dist/tools/update-rollback.js.map +1 -0
- package/dist/tools/updates.d.ts +110 -32
- package/dist/tools/updates.js +1112 -294
- package/dist/tools/updates.js.map +1 -1
- package/dist/tools/wiki.d.ts +68 -0
- package/dist/tools/wiki.js +413 -0
- package/dist/tools/wiki.js.map +1 -0
- package/dist/util.d.ts +2 -0
- package/dist/util.js +5 -0
- package/dist/util.js.map +1 -1
- package/dist/workspace/escape.d.ts +61 -0
- package/dist/workspace/escape.js +149 -0
- package/dist/workspace/escape.js.map +1 -0
- package/dist/workspace/extract.d.ts +22 -0
- package/dist/workspace/extract.js +308 -0
- package/dist/workspace/extract.js.map +1 -0
- package/dist/workspace/fs.d.ts +12 -0
- package/dist/workspace/fs.js +92 -23
- package/dist/workspace/fs.js.map +1 -1
- package/dist/workspace/git.d.ts +34 -1
- package/dist/workspace/git.js +328 -35
- package/dist/workspace/git.js.map +1 -1
- package/dist/workspace/media.d.ts +16 -13
- package/dist/workspace/media.js +43 -61
- package/dist/workspace/media.js.map +1 -1
- package/dist/workspace/rollback.d.ts +36 -22
- package/dist/workspace/rollback.js +178 -272
- package/dist/workspace/rollback.js.map +1 -1
- package/dist/workspace/unzip.js +4 -1
- package/dist/workspace/unzip.js.map +1 -1
- package/dist/workspace/upload.d.ts +7 -4
- package/dist/workspace/upload.js +5 -2
- package/dist/workspace/upload.js.map +1 -1
- package/dist/workspace/workspaces.d.ts +15 -19
- package/dist/workspace/workspaces.js +55 -127
- package/dist/workspace/workspaces.js.map +1 -1
- package/dist/workspace/worktrees.d.ts +2 -1
- package/dist/workspace/worktrees.js +179 -42
- package/dist/workspace/worktrees.js.map +1 -1
- package/package.json +7 -3
- package/sidecar/agent_dependency.json +4 -4
- package/sidecar/agent_support.json +26 -0
- package/sidecar/scripts/record-fixtures.py +12 -3
- package/sidecar/scripts/replay_sidecar.py +32 -0
- package/sidecar/scripts/suite_runner.py +302 -0
- package/sidecar/scripts/test.sh +12 -4
- package/sidecar/talaria_sidecar/__init__.py +6 -1
- package/sidecar/talaria_sidecar/__main__.py +4 -2
- package/sidecar/talaria_sidecar/agent_mutation.py +975 -0
- package/sidecar/talaria_sidecar/agent_services.py +1053 -0
- package/sidecar/talaria_sidecar/dependency_sync.py +85 -0
- package/sidecar/talaria_sidecar/home.py +56 -3
- package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
- package/sidecar/talaria_sidecar/methods/aux.py +166 -24
- package/sidecar/talaria_sidecar/methods/chat.py +852 -135
- package/sidecar/talaria_sidecar/methods/checkpoints.py +89 -0
- package/sidecar/talaria_sidecar/methods/commands.py +294 -4
- package/sidecar/talaria_sidecar/methods/config.py +123 -4
- package/sidecar/talaria_sidecar/methods/connectors.py +343 -0
- package/sidecar/talaria_sidecar/methods/cron.py +395 -36
- package/sidecar/talaria_sidecar/methods/cron_execution.py +284 -0
- package/sidecar/talaria_sidecar/methods/gateway.py +212 -55
- package/sidecar/talaria_sidecar/methods/gateway_sessions.py +234 -0
- package/sidecar/talaria_sidecar/methods/goals.py +81 -41
- package/sidecar/talaria_sidecar/methods/kanban.py +108 -34
- package/sidecar/talaria_sidecar/methods/mcp.py +1 -1
- package/sidecar/talaria_sidecar/methods/memory.py +84 -0
- package/sidecar/talaria_sidecar/methods/oauth.py +5 -2
- package/sidecar/talaria_sidecar/methods/process.py +218 -15
- package/sidecar/talaria_sidecar/methods/profiles.py +121 -13
- package/sidecar/talaria_sidecar/methods/providers.py +217 -28
- package/sidecar/talaria_sidecar/methods/runtime.py +69 -1
- package/sidecar/talaria_sidecar/methods/skills.py +67 -4
- package/sidecar/talaria_sidecar/methods/state_db.py +316 -75
- package/sidecar/talaria_sidecar/methods/stt.py +159 -78
- package/sidecar/talaria_sidecar/methods/text.py +14 -1
- package/sidecar/talaria_sidecar/methods/toolsets.py +49 -0
- package/sidecar/talaria_sidecar/methods/usage.py +113 -14
- package/sidecar/talaria_sidecar/methods/worktree.py +26 -19
- package/sidecar/talaria_sidecar/methods/write_approval.py +181 -0
- package/sidecar/talaria_sidecar/rpc.py +45 -4
- package/sidecar/talaria_sidecar/runtime.py +98 -13
- package/sidecar/talaria_sidecar/speed.py +35 -0
- package/static/dist/FILES.txt +126 -126
- package/static/dist/assets/AppShell-cey33v9s.js +8 -0
- package/static/dist/assets/ChatPage-i8wnugr7.js +18 -0
- package/static/dist/assets/ConnectTargets-hg19553x.js +1 -0
- package/static/dist/assets/ExtensionRoute-cly4apm5.js +1 -0
- package/static/dist/assets/Field-j8uqoigz.js +9 -0
- package/static/dist/assets/HubRoute-e4bgz41j.js +2 -0
- package/static/dist/assets/Markdown-lahuichm.js +598 -0
- package/static/dist/assets/RightPanel-lbo4i0fn.js +1 -0
- package/static/dist/assets/Select-gqatm2e0.js +1 -0
- package/static/dist/assets/SessionListPanel-mfqayfjh.js +1 -0
- package/static/dist/assets/SettingsLayout-b8980u7k.js +1 -0
- package/static/dist/assets/States-e7dkgtxf.js +1 -0
- package/static/dist/assets/Toaster-bfqqy786.js +1 -0
- package/static/dist/assets/_app-n1n6pfx1.js +1 -0
- package/static/dist/assets/{_app.ext._extensionId-opyh9y0v.js → _app.ext._extensionId-buxjxav3.js} +1 -1
- package/static/dist/assets/_app.index-jt8zwiu2.js +1 -0
- package/static/dist/assets/_app.insights-cv76ml71.js +1 -0
- package/static/dist/assets/_app.kanban-h6ts53j7.js +1 -0
- package/static/dist/assets/_app.logs-dm873z90.js +1 -0
- package/static/dist/assets/_app.memory-glk5y6m8.js +1 -0
- package/static/dist/assets/_app.profiles-ka6zpstq.js +1 -0
- package/static/dist/assets/{_app.session._sessionId-bfd4h3id.js → _app.session._sessionId-g2vzghvc.js} +1 -1
- package/static/dist/assets/_app.settings-hgjdhzcd.js +1 -0
- package/static/dist/assets/_app.settings._section-jf2kmhae.js +3 -0
- package/static/dist/assets/_app.skills-cii852yq.js +1 -0
- package/static/dist/assets/_app.tasks-fp9q7atm.js +1 -0
- package/static/dist/assets/_app.todos-dw94qzue.js +1 -0
- package/static/dist/assets/_app.workspaces-inyygzze.js +1 -0
- package/static/dist/assets/{abnfDiagram-VCTEODGH-b2x1lqot.js → abnfDiagram-VCTEODGH-gjayq3ra.js} +1 -1
- package/static/dist/assets/architecture-7GRP2DOG-lp56972r.js +1 -0
- package/static/dist/assets/{architectureDiagram-5GKGNRK7-h38o5l7b.js → architectureDiagram-5GKGNRK7-nwb3xovn.js} +1 -1
- package/static/dist/assets/archive-b1j004vn.js +1 -0
- package/static/dist/assets/back-g74gkozu.js +1 -0
- package/static/dist/assets/{blockDiagram-I7D4REHJ-bqquxv2u.js → blockDiagram-I7D4REHJ-joedghi3.js} +1 -1
- package/static/dist/assets/{c4Diagram-7LVT6UL2-f3fb8w6z.js → c4Diagram-7LVT6UL2-hyrjrohe.js} +1 -1
- package/static/dist/assets/channel-es95o4y8.js +1 -0
- package/static/dist/assets/{chunk-4HAMMTFA-bzfyyzp3.js → chunk-4HAMMTFA-koouqbut.js} +1 -1
- package/static/dist/assets/{chunk-75Z2AOVW-ly99rfx5.js → chunk-75Z2AOVW-bl4bhdnt.js} +1 -1
- package/static/dist/assets/{chunk-DU6HZSFF-bg6ecfqf.js → chunk-DU6HZSFF-gpedttsp.js} +3 -3
- package/static/dist/assets/{chunk-F27PBJKO-e8k7mmqw.js → chunk-F27PBJKO-d8xxi0zi.js} +1 -1
- package/static/dist/assets/{chunk-GMAD6QVW-cmalnoaj.js → chunk-GMAD6QVW-jro0hl73.js} +1 -1
- package/static/dist/assets/{chunk-GVQU2GXP-gmif5o01.js → chunk-GVQU2GXP-djn6gbyu.js} +1 -1
- package/static/dist/assets/{chunk-IMKFNOWR-f1nwwh6u.js → chunk-IMKFNOWR-vw4p5p7o.js} +1 -1
- package/static/dist/assets/{chunk-L3NEJ4N5-oktfh5v7.js → chunk-L3NEJ4N5-n1hj77q8.js} +1 -1
- package/static/dist/assets/{chunk-OSK3NFVY-b1sdx96z.js → chunk-OSK3NFVY-oy0gwn2n.js} +1 -1
- package/static/dist/assets/{chunk-P2QGCYS3-fhu4nzxt.js → chunk-P2QGCYS3-onf1hz6c.js} +1 -1
- package/static/dist/assets/{chunk-POPQ4Y6H-em31rnef.js → chunk-POPQ4Y6H-m8sqn7cs.js} +1 -1
- package/static/dist/assets/{chunk-PWAF6VOD-bxhhyftw.js → chunk-PWAF6VOD-ek4smc8x.js} +1 -1
- package/static/dist/assets/{chunk-SHT3W25Y-fmrvwcav.js → chunk-SHT3W25Y-g9gfvefo.js} +3 -3
- package/static/dist/assets/{chunk-SVP7TREG-lymukl2j.js → chunk-SVP7TREG-f9nfv2cu.js} +1 -1
- package/static/dist/assets/{chunk-TICWLB2K-lmza6k23.js → chunk-TICWLB2K-bnk3m1mq.js} +1 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-kmihoqxh.js +1 -0
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-kmihoqxh.js +1 -0
- package/static/dist/assets/copied-bli9tbcx.js +1 -0
- package/static/dist/assets/{copy-fw5b1pc6.js → copy-jamtd1pf.js} +1 -1
- package/static/dist/assets/{cynefin-OW5HDTMX-czlhbyhs.js → cynefin-OW5HDTMX-f8xfdd3f.js} +1 -1
- package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-gq7mvswb.js → cynefinDiagram-5FMLGOSQ-n9lb99h9.js} +1 -1
- package/static/dist/assets/{dagre-GXQ25YYZ-cqdbf7dr.js → dagre-GXQ25YYZ-dgailddi.js} +4 -4
- package/static/dist/assets/{diagram-S7CK7UJ4-o6arxa58.js → diagram-S7CK7UJ4-m6aeoe7c.js} +1 -1
- package/static/dist/assets/{diagram-UQ7AKVKN-nhnd68tz.js → diagram-UQ7AKVKN-jall3j0x.js} +1 -1
- package/static/dist/assets/{diagram-VSXAHHWV-dk2sclzn.js → diagram-VSXAHHWV-hbawi7hn.js} +1 -1
- package/static/dist/assets/{diagram-VX7I27RA-n3k5nyx3.js → diagram-VX7I27RA-hendl2tt.js} +1 -1
- package/static/dist/assets/{diagram-Z3DM3KII-m6q9cwdh.js → diagram-Z3DM3KII-igwc35p3.js} +1 -1
- package/static/dist/assets/{ebnfDiagram-PWID7BFC-lsa5641p.js → ebnfDiagram-PWID7BFC-c64knz08.js} +1 -1
- package/static/dist/assets/{erDiagram-RLTQ6QDP-fo2ckbe6.js → erDiagram-RLTQ6QDP-brdu9lcm.js} +1 -1
- package/static/dist/assets/eventmodeling-NTZA5JFV-njk1j8wl.js +1 -0
- package/static/dist/assets/flowDiagram-HODETNUW-nma6f0ga.js +1 -0
- package/static/dist/assets/folder-plus-lvt9kudb.js +1 -0
- package/static/dist/assets/{ganttDiagram-EL5Y4UJY-nzqz6x9g.js → ganttDiagram-EL5Y4UJY-ma6jxj5i.js} +1 -1
- package/static/dist/assets/{gitGraph-4MIJSDKK-gukvcxe6.js → gitGraph-4MIJSDKK-naa9w6xa.js} +1 -1
- package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-lqhdp8f0.js → gitGraphDiagram-WWUBYQGX-hzltvsod.js} +1 -1
- package/static/dist/assets/{highlighted-body-KPVGNVTW-igw6cp39.js → highlighted-body-KPVGNVTW-ghoavj8d.js} +1 -1
- package/static/dist/assets/host-hzm8n85n.js +1 -0
- package/static/dist/assets/index-drdcaqeq.css +2 -0
- package/static/dist/assets/index-jzm844he.js +11 -0
- package/static/dist/assets/{info-A6RAGUB7-gvu7a93l.js → info-A6RAGUB7-mn2ut5ko.js} +1 -1
- package/static/dist/assets/{infoDiagram-27XIBGKW-m8t8g6w1.js → infoDiagram-27XIBGKW-h6kuqvsb.js} +1 -1
- package/static/dist/assets/{ishikawaDiagram-5VMMS53U-l07vkbgj.js → ishikawaDiagram-5VMMS53U-e7bnwq7h.js} +1 -1
- package/static/dist/assets/{journeyDiagram-3NMN7TZE-hybkgj8l.js → journeyDiagram-3NMN7TZE-etd1bi6p.js} +1 -1
- package/static/dist/assets/{kanban-definition-UXKFOSKX-by13uvtn.js → kanban-definition-UXKFOSKX-emb1g9dz.js} +4 -4
- package/static/dist/assets/lazyRouteComponent-o816ytzl.js +1 -0
- package/static/dist/assets/{line-osxq6fq7.js → line-h0ojzsvs.js} +1 -1
- package/static/dist/assets/link-k01ryaf9.js +1 -0
- package/static/dist/assets/login-bsae49ew.js +1 -0
- package/static/dist/assets/mermaid-HWGCJPDP-ihl34s74.js +1 -0
- package/static/dist/assets/{mermaid-parser.core-i91oxmou.js → mermaid-parser.core-bnre27u8.js} +3 -3
- package/static/dist/assets/{mindmap-definition-YA3MSWOX-m82mx8ww.js → mindmap-definition-YA3MSWOX-o1vathns.js} +1 -1
- package/static/dist/assets/onboarding-c65tysya.js +1 -0
- package/static/dist/assets/onboarding_model_label-gpn28uix.js +1 -0
- package/static/dist/assets/{packet-AYTQ26CC-nbtgge2o.js → packet-AYTQ26CC-hatq7m2e.js} +1 -1
- package/static/dist/assets/pcmTap.worklet-74EKjWAZ.js +1 -0
- package/static/dist/assets/{pegDiagram-XKGWAZYB-f1zxzga1.js → pegDiagram-XKGWAZYB-gwisz8jv.js} +1 -1
- package/static/dist/assets/{pie-WAS4IAKB-of8vuhxs.js → pie-WAS4IAKB-fpftf0mk.js} +1 -1
- package/static/dist/assets/{pieDiagram-E7YTZNPT-o7y8ftio.js → pieDiagram-E7YTZNPT-khm1o9a6.js} +1 -1
- package/static/dist/assets/{quadrantDiagram-AXDQQJYC-iqiwia1t.js → quadrantDiagram-AXDQQJYC-owqc4uqn.js} +1 -1
- package/static/dist/assets/{radar-RG4KPBEZ-delnsy2v.js → radar-RG4KPBEZ-cntfwjpq.js} +1 -1
- package/static/dist/assets/{railroad-74A4TZTK-nspnyq9u.js → railroad-74A4TZTK-a7t5eibp.js} +1 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-ol8cdktf.js +1 -0
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-i8vzd429.js +1 -0
- package/static/dist/assets/railroad-peg-WCYAUIDC-nw3ulewz.js +1 -0
- package/static/dist/assets/{railroadDiagram-O6MQD6OU-z41tqx5z.js → railroadDiagram-O6MQD6OU-etuh0qa0.js} +1 -1
- package/static/dist/assets/{refresh-cw-nt1dtsx4.js → refresh-cw-mqbkv2a3.js} +1 -1
- package/static/dist/assets/refresh-l29ljp76.js +1 -0
- package/static/dist/assets/{requirementDiagram-BXWQKSXE-bdvif194.js → requirementDiagram-BXWQKSXE-oq2ulk22.js} +1 -1
- package/static/dist/assets/{sankeyDiagram-P5KCCOFB-h73e0rol.js → sankeyDiagram-P5KCCOFB-iqc02emv.js} +1 -1
- package/static/dist/assets/saved-ndd4t2xb.js +1 -0
- package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-iv95mb1z.js → sequenceDiagram-WJ2MYXX4-i0v116q0.js} +2 -2
- package/static/dist/assets/settings_section_extensions_title-jhfo6o8z.js +1 -0
- package/static/dist/assets/share._token-c1ri0hy1.js +2 -0
- package/static/dist/assets/sliders-horizontal-j3jjt9tv.js +1 -0
- package/static/dist/assets/{stateDiagram-D77RDMKH-k417ixmf.js → stateDiagram-D77RDMKH-dnpt1ato.js} +1 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-bxjacpk6.js +1 -0
- package/static/dist/assets/{swimlanes-42K2YHIH-esola70w.js → swimlanes-42K2YHIH-loqbdazb.js} +1 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-id62p9hz.js +8 -0
- package/static/dist/assets/{timeline-definition-24CTP7MA-getrz2y8.js → timeline-definition-24CTP7MA-ol2hnvma.js} +1 -1
- package/static/dist/assets/toast-i3h34v6o.js +64 -0
- package/static/dist/assets/{treeView-Q6P3EWNA-hc7ap1q7.js → treeView-Q6P3EWNA-idrj6iox.js} +1 -1
- package/static/dist/assets/{treemap-WGGIJYW6-b7k1syy5.js → treemap-WGGIJYW6-lzr49vv5.js} +1 -1
- package/static/dist/assets/untitled-oaoya4qj.js +1 -0
- package/static/dist/assets/useForm-nfaxgmsk.js +1 -0
- package/static/dist/assets/{useParams-lhg566ew.js → useParams-gjc70qru.js} +1 -1
- package/static/dist/assets/{useSearch-lbrh6ejn.js → useSearch-e6ae539u.js} +1 -1
- package/static/dist/assets/{vennDiagram-4TSXK5OY-n6pcy5qb.js → vennDiagram-4TSXK5OY-bvwr9o2z.js} +1 -1
- package/static/dist/assets/{wardley-WFR3VGLG-lpa18vz1.js → wardley-WFR3VGLG-31ui8tma.js} +1 -1
- package/static/dist/assets/{wardleyDiagram-VM6X3IG4-kpclwwg7.js → wardleyDiagram-VM6X3IG4-k5wqtx4b.js} +1 -1
- package/static/dist/assets/{xychartDiagram-S5SC5T6Z-paa2n8y0.js → xychartDiagram-S5SC5T6Z-aqbgvujg.js} +1 -1
- package/static/dist/index.html +1 -1
- package/static/dist/sw.js +1 -1
- package/static/dist/assets/AppShell-fb2td9zi.js +0 -1
- package/static/dist/assets/ChatPage-cj96kiy9.js +0 -25
- package/static/dist/assets/Dialog-kxcg7ard.js +0 -1
- package/static/dist/assets/ExtensionRoute-jf7h0754.js +0 -1
- package/static/dist/assets/HubRoute-gmanpd5y.js +0 -2
- package/static/dist/assets/Markdown-mdwlvj3w.js +0 -598
- package/static/dist/assets/RightPanel-ftvrjlcp.js +0 -1
- package/static/dist/assets/Select-bilaypej.js +0 -1
- package/static/dist/assets/SessionListPanel-og8n36qs.js +0 -1
- package/static/dist/assets/SettingsLayout-jonjefmj.js +0 -1
- package/static/dist/assets/States-nmejrwrm.js +0 -1
- package/static/dist/assets/Toaster-nnl8zkt9.js +0 -1
- package/static/dist/assets/_app-gdidzd94.js +0 -1
- package/static/dist/assets/_app.index-hbarzbjx.js +0 -1
- package/static/dist/assets/_app.insights-luywlarz.js +0 -1
- package/static/dist/assets/_app.kanban-kincnbr8.js +0 -1
- package/static/dist/assets/_app.logs-oi2gr3gs.js +0 -1
- package/static/dist/assets/_app.memory-b6jfivt6.js +0 -1
- package/static/dist/assets/_app.profiles-lpvixmqp.js +0 -1
- package/static/dist/assets/_app.settings-vowx3iq0.js +0 -1
- package/static/dist/assets/_app.settings._section-cnntg1tu.js +0 -3
- package/static/dist/assets/_app.skills-fb57lpau.js +0 -1
- package/static/dist/assets/_app.tasks-eszpx1q7.js +0 -2
- package/static/dist/assets/_app.todos-nr05ac6w.js +0 -1
- package/static/dist/assets/_app.workspaces-d2luomu6.js +0 -1
- package/static/dist/assets/architecture-7GRP2DOG-hd0o7bde.js +0 -1
- package/static/dist/assets/back-bemaer09.js +0 -1
- package/static/dist/assets/cancel-drd0g6d9.js +0 -1
- package/static/dist/assets/channel-cpdgf867.js +0 -1
- package/static/dist/assets/classDiagram-ZZMXUADV-ko09sguk.js +0 -1
- package/static/dist/assets/classDiagram-v2-VYDZK3BY-ko09sguk.js +0 -1
- package/static/dist/assets/copied-ima3pysb.js +0 -1
- package/static/dist/assets/endpoints-d33siokx.js +0 -64
- package/static/dist/assets/eventmodeling-NTZA5JFV-emctlo64.js +0 -1
- package/static/dist/assets/flowDiagram-HODETNUW-bfi3moqa.js +0 -1
- package/static/dist/assets/index-cxq58xb1.js +0 -11
- package/static/dist/assets/index-hgtx08n5.css +0 -2
- package/static/dist/assets/lazyRouteComponent-af0lvgjx.js +0 -1
- package/static/dist/assets/link-jyxicdhg.js +0 -1
- package/static/dist/assets/login-ec21t39x.js +0 -1
- package/static/dist/assets/mermaid-HWGCJPDP-gfl8z3ep.js +0 -1
- package/static/dist/assets/onboarding-btnltvyz.js +0 -1
- package/static/dist/assets/onboarding_model_label-dp7xffoh.js +0 -1
- package/static/dist/assets/railroad-abnf-HS5TGJTU-nst1qxyn.js +0 -1
- package/static/dist/assets/railroad-ebnf-LZEXJU2U-ci37x8qy.js +0 -1
- package/static/dist/assets/railroad-peg-WCYAUIDC-aimkk07z.js +0 -1
- package/static/dist/assets/refresh-b4uams1i.js +0 -1
- package/static/dist/assets/saved-kg52csy7.js +0 -1
- package/static/dist/assets/settings_section_extensions_title-ej0iapxe.js +0 -1
- package/static/dist/assets/share._token-f97e94r0.js +0 -2
- package/static/dist/assets/sliders-horizontal-fj18it47.js +0 -1
- package/static/dist/assets/sse-fwpqtzbg.js +0 -1
- package/static/dist/assets/stateDiagram-v2-MP3YSRHH-hwn4apct.js +0 -1
- package/static/dist/assets/swimlanesDiagram-VR7AAH4N-d1h97oyg.js +0 -8
- package/static/dist/assets/todoStore-eginf9h4.js +0 -1
- package/static/dist/assets/tts-lxdxnmjd.js +0 -1
- package/static/dist/assets/untitled-ovpfthg4.js +0 -1
- package/static/dist/assets/useForm-bcblv1rx.js +0 -1
- package/static/dist/assets/useLocale-fi5jb8ma.js +0 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only escape grants (Python `workspace.py` `authorize_escape_target` and friends, TAL-263): a workspace symlink
|
|
3
|
+
* whose target sits outside the workspace opens through a short-lived token scoped to that one link. A directory
|
|
4
|
+
* target anchors the grant at the target; a file target anchors it at the parent with the file as the only reachable
|
|
5
|
+
* entry. Every use re-checks the link, and every read stays anchored at the grant root, so nested escaping links stay
|
|
6
|
+
* display-only.
|
|
7
|
+
*/
|
|
8
|
+
import { randomBytes } from 'node:crypto';
|
|
9
|
+
import { lstatSync, statSync } from 'node:fs';
|
|
10
|
+
import { basename, dirname, join, posix, relative } from 'node:path';
|
|
11
|
+
import { stripSurroundingQuotes, isBlockedSystemPath } from './workspaces.js';
|
|
12
|
+
import { isWithin, resolvePathLikePython } from './paths.js';
|
|
13
|
+
import { dirSignature, listDir, NotFoundError, PathTraversalError, safeResolveWs, withPinnedRoot } from './fs.js';
|
|
14
|
+
import { readFilePreview } from './preview.js';
|
|
15
|
+
export const ESCAPE_GRANT_TTL_SECONDS = 300;
|
|
16
|
+
/** Any failed re-check: the client asks for a new grant (403). */
|
|
17
|
+
export class EscapeGrantExpired extends Error {
|
|
18
|
+
constructor() { super('Escape authorization expired'); }
|
|
19
|
+
}
|
|
20
|
+
/** Run `fn` with every anchored open of the grant root held to the inode the grant was minted for. */
|
|
21
|
+
export function anchoredAt(req, fn) {
|
|
22
|
+
return withPinnedRoot(req.externalRoot, req.rootId, fn);
|
|
23
|
+
}
|
|
24
|
+
/** Python `_normalize_workspace_rel_path`: POSIX-normalised and workspace-relative; `..` and absolute paths fail. */
|
|
25
|
+
export function normalizeWorkspaceRelPath(rel) {
|
|
26
|
+
const raw = stripSurroundingQuotes(rel).trim().replaceAll('\\', '/');
|
|
27
|
+
if (!raw || raw === '.')
|
|
28
|
+
return '.';
|
|
29
|
+
const norm = posix.normalize(raw).replace(/(.)\/+$/, '$1');
|
|
30
|
+
if (norm === '.')
|
|
31
|
+
return '.';
|
|
32
|
+
if (norm === '..' || norm.startsWith('../') || norm.startsWith('/'))
|
|
33
|
+
throw new PathTraversalError(`Path traversal blocked: ${rel}`);
|
|
34
|
+
return norm;
|
|
35
|
+
}
|
|
36
|
+
function virtualPath(root, rel) {
|
|
37
|
+
if (root === '.')
|
|
38
|
+
return rel;
|
|
39
|
+
return rel === '.' ? root : `${root}/${rel}`;
|
|
40
|
+
}
|
|
41
|
+
/** Python `_escape_surface_target`: the resolved target of an escaping, reachable, non-system workspace symlink. */
|
|
42
|
+
function surfaceTarget(workspaceRoot, rel) {
|
|
43
|
+
const surfaceRel = normalizeWorkspaceRelPath(rel);
|
|
44
|
+
const parentRel = posix.dirname(surfaceRel);
|
|
45
|
+
const parent = parentRel === '.' ? workspaceRoot : safeResolveWs(workspaceRoot, parentRel);
|
|
46
|
+
const surface = join(parent, posix.basename(surfaceRel));
|
|
47
|
+
let isLink = false;
|
|
48
|
+
try {
|
|
49
|
+
isLink = lstatSync(surface).isSymbolicLink();
|
|
50
|
+
}
|
|
51
|
+
catch { /* missing */ }
|
|
52
|
+
if (!isLink)
|
|
53
|
+
throw new NotFoundError(`Path is not an escape-target symlink: ${rel}`);
|
|
54
|
+
let target;
|
|
55
|
+
try {
|
|
56
|
+
target = resolvePathLikePython(surface);
|
|
57
|
+
statSync(target);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
throw new NotFoundError(`Path is no longer reachable: ${rel}`);
|
|
61
|
+
}
|
|
62
|
+
if (isWithin(target, workspaceRoot))
|
|
63
|
+
throw new NotFoundError(`Path does not escape workspace: ${rel}`);
|
|
64
|
+
if (isBlockedSystemPath(target))
|
|
65
|
+
throw new NotFoundError(`Path points to a system directory: ${target}`);
|
|
66
|
+
return target;
|
|
67
|
+
}
|
|
68
|
+
export class EscapeGrants {
|
|
69
|
+
now;
|
|
70
|
+
grants = new Map();
|
|
71
|
+
constructor(now) {
|
|
72
|
+
this.now = now;
|
|
73
|
+
}
|
|
74
|
+
/** Mint a grant for one surfaced escape-target symlink. */
|
|
75
|
+
authorize(workspace, sessionId, profile, rel) {
|
|
76
|
+
const workspaceRoot = resolvePathLikePython(workspace);
|
|
77
|
+
const target = surfaceTarget(workspaceRoot, rel);
|
|
78
|
+
const isDir = statSync(target).isDirectory();
|
|
79
|
+
const externalRoot = isDir ? target : dirname(target);
|
|
80
|
+
const { dev, ino } = statSync(externalRoot);
|
|
81
|
+
const token = randomBytes(24).toString('base64url');
|
|
82
|
+
const expiresAt = this.now() + ESCAPE_GRANT_TTL_SECONDS;
|
|
83
|
+
const surfacePath = normalizeWorkspaceRelPath(rel);
|
|
84
|
+
this.prune();
|
|
85
|
+
this.grants.set(token, { sessionId, profile, workspaceRoot, surfacePath, externalRoot, rootId: { dev, ino }, externalEntryRel: isDir ? '.' : basename(target), surfaceTarget: target, expiresAt });
|
|
86
|
+
return { token, path: surfacePath, is_dir: isDir, expires_at: expiresAt, expires_in: ESCAPE_GRANT_TTL_SECONDS, read_only: true };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Python `resolve_authorized_escape_request`: re-check the grant, then re-root a request path under the link onto
|
|
90
|
+
* the grant root. A path outside the link answers "Path traversal blocked".
|
|
91
|
+
*/
|
|
92
|
+
resolve(workspace, sessionId, profile, token, rel) {
|
|
93
|
+
const grant = this.check(workspace, sessionId, profile, token);
|
|
94
|
+
const requestPath = normalizeWorkspaceRelPath(rel);
|
|
95
|
+
const under = grant.surfacePath === '.' ? requestPath : requestPath === grant.surfacePath ? '.' : requestPath.startsWith(`${grant.surfacePath}/`) ? requestPath.slice(grant.surfacePath.length + 1) : null;
|
|
96
|
+
if (under === null)
|
|
97
|
+
throw new PathTraversalError(`Path traversal blocked: ${rel}`);
|
|
98
|
+
const externalRel = grant.externalEntryRel === '.' ? under : under === '.' ? grant.externalEntryRel : `${grant.externalEntryRel}/${under}`;
|
|
99
|
+
return { surfacePath: grant.surfacePath, requestPath, externalRoot: grant.externalRoot, rootId: grant.rootId, externalRel };
|
|
100
|
+
}
|
|
101
|
+
/** Python `list_authorized_escape_dir`: entries re-pathed under the link; a target outside the grant root is dropped. */
|
|
102
|
+
list(req) {
|
|
103
|
+
const entries = anchoredAt(req, () => listDir(req.externalRoot, req.externalRel)).map((entry) => {
|
|
104
|
+
const out = { ...entry, path: virtualPath(req.surfacePath, entry.path), escape_read_only: true };
|
|
105
|
+
if (entry.target === undefined)
|
|
106
|
+
return out;
|
|
107
|
+
delete out.target;
|
|
108
|
+
if (isWithin(entry.target, req.externalRoot))
|
|
109
|
+
out.target = virtualPath(req.surfacePath, relative(req.externalRoot, entry.target) || '.');
|
|
110
|
+
return out;
|
|
111
|
+
});
|
|
112
|
+
return { path: req.requestPath, entries, signature: dirSignature(req.externalRoot, req.externalRel, entries), virtual_root: req.surfacePath, read_only: true };
|
|
113
|
+
}
|
|
114
|
+
/** Python `read_authorized_escape_file_content`, with the `/api/file` preview kind. */
|
|
115
|
+
read(req) {
|
|
116
|
+
return { ...anchoredAt(req, () => readFilePreview(req.externalRoot, req.externalRel)), path: req.requestPath, escape_read_only: true };
|
|
117
|
+
}
|
|
118
|
+
/** Python `raw_authorized_escape_target`: the file to serve, anchored at the grant root. */
|
|
119
|
+
rawTarget(req) {
|
|
120
|
+
return safeResolveWs(req.externalRoot, req.externalRel);
|
|
121
|
+
}
|
|
122
|
+
/** Python `_escape_authorization_record`: the link must still escape to the same reachable, non-system target and root inode. */
|
|
123
|
+
check(workspace, sessionId, profile, token) {
|
|
124
|
+
this.prune();
|
|
125
|
+
const grant = this.grants.get(token);
|
|
126
|
+
if (grant?.sessionId !== sessionId || grant.profile !== profile || grant.workspaceRoot !== resolvePathLikePython(workspace))
|
|
127
|
+
throw new EscapeGrantExpired();
|
|
128
|
+
try {
|
|
129
|
+
if (surfaceTarget(grant.workspaceRoot, grant.surfacePath) !== grant.surfaceTarget)
|
|
130
|
+
throw new EscapeGrantExpired();
|
|
131
|
+
const root = statSync(grant.externalRoot);
|
|
132
|
+
if (root.dev !== grant.rootId.dev || root.ino !== grant.rootId.ino)
|
|
133
|
+
throw new EscapeGrantExpired();
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// A retargeted link kills the grant for good, even if it later points back.
|
|
137
|
+
this.grants.delete(token);
|
|
138
|
+
throw new EscapeGrantExpired();
|
|
139
|
+
}
|
|
140
|
+
return grant;
|
|
141
|
+
}
|
|
142
|
+
prune() {
|
|
143
|
+
const now = this.now();
|
|
144
|
+
for (const [token, grant] of this.grants)
|
|
145
|
+
if (grant.expiresAt <= now)
|
|
146
|
+
this.grants.delete(token);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=escape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escape.js","sourceRoot":"","sources":["../../src/workspace/escape.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const ARCHIVE_SUFFIXES: readonly [".zip", ".tar", ".tar.gz", ".tgz", ".tar.bz2", ".tbz2", ".tar.xz", ".txz"];
|
|
2
|
+
/** A tiny archive of millions of empty members slips under the byte cap but exhausts inodes. */
|
|
3
|
+
export declare const MAX_ARCHIVE_MEMBERS = 10000;
|
|
4
|
+
/** Python `ValueError`: the archive was refused (format, slip, size, or member count). */
|
|
5
|
+
export declare class ArchiveRejected extends Error {
|
|
6
|
+
}
|
|
7
|
+
/** Python `BadZipFile` / `TarError`: the archive could not be read. */
|
|
8
|
+
export declare class CorruptArchive extends Error {
|
|
9
|
+
}
|
|
10
|
+
export interface Extraction {
|
|
11
|
+
extracted: number;
|
|
12
|
+
files: string[];
|
|
13
|
+
dest: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function isArchiveName(name: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Extract `bytes` into a new directory named for the archive under `parent`. `root` is the trusted directory (the
|
|
18
|
+
* workspace or the session inbox) that `parent` lives in; every directory and file is created by an anchored walk
|
|
19
|
+
* from it. The member count, total size, and every member path are checked before anything is created, and a failed
|
|
20
|
+
* write removes the partial directory. `files` are relative to `parent`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function extractArchive(bytes: Buffer, filename: string, root: string, parent: string, cap: number): Promise<Extraction>;
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Archive extraction for `/api/upload/extract` and `/api/workspace/upload` (Python `extract_archive`). Zip and tar
|
|
3
|
+
* (plain, gzip, bzip2, xz) members land in a fresh `<parent>/<stem>` directory through the anchored exclusive create,
|
|
4
|
+
* so a slipped name or a symlinked component never writes outside it. Every decompressor stops once its output passes
|
|
5
|
+
* the extracted-bytes cap, and partial output is removed on any failure.
|
|
6
|
+
*/
|
|
7
|
+
import { closeSync, lstatSync } from 'node:fs';
|
|
8
|
+
import { randomInt } from 'node:crypto';
|
|
9
|
+
import { basename, join, relative } from 'node:path';
|
|
10
|
+
import { gunzipSync } from 'node:zlib';
|
|
11
|
+
import Bunzip from 'seek-bzip';
|
|
12
|
+
import xzPkg from 'xz-decompress';
|
|
13
|
+
import { writeFully } from '../fs/atomic.js';
|
|
14
|
+
import { makeAnchoredDir, openAnchoredCreateFd, rmtreeAnchored, safeResolve } from './fs.js';
|
|
15
|
+
import { resolvePathLikePython } from './paths.js';
|
|
16
|
+
import { BadZipError, readZip } from './unzip.js';
|
|
17
|
+
const { XzReadableStream } = xzPkg;
|
|
18
|
+
export const ARCHIVE_SUFFIXES = ['.zip', '.tar', '.tar.gz', '.tgz', '.tar.bz2', '.tbz2', '.tar.xz', '.txz'];
|
|
19
|
+
/** A tiny archive of millions of empty members slips under the byte cap but exhausts inodes. */
|
|
20
|
+
export const MAX_ARCHIVE_MEMBERS = 10_000;
|
|
21
|
+
/**
|
|
22
|
+
* A decompressed tar stream may exceed the file-byte cap only by its framing: each member costs a 512-byte header plus
|
|
23
|
+
* under 512 bytes of padding, and twice the member cap leaves room for directory and extended headers.
|
|
24
|
+
*/
|
|
25
|
+
const TAR_FRAMING_BYTES = 2 * MAX_ARCHIVE_MEMBERS * 1024;
|
|
26
|
+
/** Python `ValueError`: the archive was refused (format, slip, size, or member count). */
|
|
27
|
+
export class ArchiveRejected extends Error {
|
|
28
|
+
}
|
|
29
|
+
/** Python `BadZipFile` / `TarError`: the archive could not be read. */
|
|
30
|
+
export class CorruptArchive extends Error {
|
|
31
|
+
}
|
|
32
|
+
export function isArchiveName(name) {
|
|
33
|
+
const lower = name.toLowerCase();
|
|
34
|
+
return ARCHIVE_SUFFIXES.some((suffix) => lower.endsWith(suffix));
|
|
35
|
+
}
|
|
36
|
+
/** Python `PurePath.stem`: the name without its last suffix (`a.tar.gz` -> `a.tar`, `.zip` -> `.zip`). */
|
|
37
|
+
function pythonStem(name) {
|
|
38
|
+
const dot = name.lastIndexOf('.');
|
|
39
|
+
return dot > 0 && dot < name.length - 1 ? name.slice(0, dot) : name;
|
|
40
|
+
}
|
|
41
|
+
function lexists(path) {
|
|
42
|
+
try {
|
|
43
|
+
lstatSync(path);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function tooLarge(cap) {
|
|
51
|
+
return new ArchiveRejected(`Extraction too large (> ${String(Math.floor(cap / (1024 * 1024)))} MB limit). Possible zip bomb.`);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Extract `bytes` into a new directory named for the archive under `parent`. `root` is the trusted directory (the
|
|
55
|
+
* workspace or the session inbox) that `parent` lives in; every directory and file is created by an anchored walk
|
|
56
|
+
* from it. The member count, total size, and every member path are checked before anything is created, and a failed
|
|
57
|
+
* write removes the partial directory. `files` are relative to `parent`.
|
|
58
|
+
*/
|
|
59
|
+
export async function extractArchive(bytes, filename, root, parent, cap) {
|
|
60
|
+
const name = basename(filename);
|
|
61
|
+
const isZip = name.toLowerCase().endsWith('.zip');
|
|
62
|
+
if (!isZip && !isArchiveName(name))
|
|
63
|
+
throw new ArchiveRejected(`Unsupported archive format: ${filename}`);
|
|
64
|
+
const stem = pythonStem(name);
|
|
65
|
+
if (!stem || stem === '.' || stem === '..')
|
|
66
|
+
throw new ArchiveRejected(`Invalid archive name: ${filename}`);
|
|
67
|
+
const members = isZip ? zipMembers(bytes) : [...tarMembers(await decompressTar(bytes, cap + TAR_FRAMING_BYTES, cap))];
|
|
68
|
+
if (members.length > MAX_ARCHIVE_MEMBERS)
|
|
69
|
+
throw new ArchiveRejected(`Archive has too many files (> ${String(MAX_ARCHIVE_MEMBERS)}). Possible archive bomb.`);
|
|
70
|
+
// Declared sizes are binding: a zip member cannot inflate past its own, and a tar member is a slice of the stream.
|
|
71
|
+
if (members.reduce((sum, m) => sum + m.size, 0) > cap)
|
|
72
|
+
throw tooLarge(cap);
|
|
73
|
+
const parentResolved = resolvePathLikePython(parent);
|
|
74
|
+
let dest = join(parentResolved, stem);
|
|
75
|
+
for (let attempt = 0; lexists(dest); attempt += 1) {
|
|
76
|
+
if (attempt >= 1000)
|
|
77
|
+
throw new ArchiveRejected('Could not allocate a unique extraction directory');
|
|
78
|
+
dest = join(parentResolved, `${stem}_${String(randomInt(1000)).padStart(3, '0')}`);
|
|
79
|
+
}
|
|
80
|
+
const slip = isZip ? 'Zip' : 'Tar';
|
|
81
|
+
const plan = members.map((member) => {
|
|
82
|
+
let target;
|
|
83
|
+
try {
|
|
84
|
+
target = safeResolve(dest, member.name);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
throw new ArchiveRejected(`${slip}-slip blocked: ${member.name}`);
|
|
88
|
+
}
|
|
89
|
+
if (target === dest)
|
|
90
|
+
throw new ArchiveRejected(`${slip}-slip blocked: ${member.name}`);
|
|
91
|
+
return { target, read: member.read };
|
|
92
|
+
});
|
|
93
|
+
makeAnchoredDir(root, dest);
|
|
94
|
+
try {
|
|
95
|
+
for (const { target, read } of plan) {
|
|
96
|
+
let data;
|
|
97
|
+
try {
|
|
98
|
+
data = read();
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
throw error instanceof BadZipError ? new CorruptArchive(error.message) : error;
|
|
102
|
+
}
|
|
103
|
+
const fd = openAnchoredCreateFd(root, target);
|
|
104
|
+
try {
|
|
105
|
+
writeFully(fd, data);
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
closeSync(fd);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
try {
|
|
114
|
+
rmtreeAnchored(root, dest);
|
|
115
|
+
}
|
|
116
|
+
catch { /* the directory is already gone */ }
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
return { extracted: plan.length, files: plan.map(({ target }) => relative(parentResolved, target)), dest };
|
|
120
|
+
}
|
|
121
|
+
function zipMembers(bytes) {
|
|
122
|
+
try {
|
|
123
|
+
return readZip(bytes).filter((entry) => !entry.isDir);
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
throw error instanceof BadZipError ? new CorruptArchive(`File is not a zip file: ${error.message}`) : error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/** The raw tar stream, decompressed by magic number like Python `tarfile.open(mode='r:*')`, never past `limit` bytes. */
|
|
130
|
+
async function decompressTar(bytes, limit, cap) {
|
|
131
|
+
if (bytes[0] === 0x1f && bytes[1] === 0x8b) {
|
|
132
|
+
try {
|
|
133
|
+
return gunzipSync(bytes, { maxOutputLength: limit });
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
if (error.code === 'ERR_BUFFER_TOO_LARGE')
|
|
137
|
+
throw tooLarge(cap);
|
|
138
|
+
throw new CorruptArchive('Invalid gzip data');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (bytes.subarray(0, 3).toString('latin1') === 'BZh') {
|
|
142
|
+
let out = Buffer.allocUnsafe(64 * 1024);
|
|
143
|
+
let pos = 0;
|
|
144
|
+
const sink = {
|
|
145
|
+
writeByte(byte) {
|
|
146
|
+
if (pos >= limit)
|
|
147
|
+
throw tooLarge(cap);
|
|
148
|
+
if (pos === out.length) {
|
|
149
|
+
const grown = Buffer.allocUnsafe(Math.min(out.length * 2, limit));
|
|
150
|
+
out.copy(grown);
|
|
151
|
+
out = grown;
|
|
152
|
+
}
|
|
153
|
+
out[pos++] = byte;
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
try {
|
|
157
|
+
Bunzip.decode(bytes, sink, true);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
if (error instanceof ArchiveRejected)
|
|
161
|
+
throw error;
|
|
162
|
+
throw new CorruptArchive('Invalid bzip2 data');
|
|
163
|
+
}
|
|
164
|
+
return out.subarray(0, pos);
|
|
165
|
+
}
|
|
166
|
+
if (bytes.subarray(0, 6).equals(Buffer.from([0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00]))) {
|
|
167
|
+
const reader = new XzReadableStream(new Blob([bytes]).stream()).getReader();
|
|
168
|
+
const chunks = [];
|
|
169
|
+
let total = 0;
|
|
170
|
+
try {
|
|
171
|
+
for (;;) {
|
|
172
|
+
const { done, value } = await reader.read();
|
|
173
|
+
if (done)
|
|
174
|
+
break;
|
|
175
|
+
total += value.length;
|
|
176
|
+
if (total > limit) {
|
|
177
|
+
await reader.cancel();
|
|
178
|
+
throw tooLarge(cap);
|
|
179
|
+
}
|
|
180
|
+
chunks.push(Buffer.from(value));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
if (error instanceof ArchiveRejected)
|
|
185
|
+
throw error;
|
|
186
|
+
throw new CorruptArchive('Invalid xz data');
|
|
187
|
+
}
|
|
188
|
+
return Buffer.concat(chunks, total);
|
|
189
|
+
}
|
|
190
|
+
return bytes;
|
|
191
|
+
}
|
|
192
|
+
const BLOCK = 512;
|
|
193
|
+
const REGULAR_TYPES = new Set(['0', '\0', '7']);
|
|
194
|
+
/** Python `tarfile`: these member types carry no data blocks even when their size field is set. */
|
|
195
|
+
const DATALESS_TYPES = new Set(['1', '2', '3', '4', '5', '6']);
|
|
196
|
+
function cString(buf, start, length) {
|
|
197
|
+
const field = buf.subarray(start, start + length);
|
|
198
|
+
const nul = field.indexOf(0);
|
|
199
|
+
return (nul < 0 ? field : field.subarray(0, nul)).toString('utf8');
|
|
200
|
+
}
|
|
201
|
+
/** Python `tarfile.nti`: an octal field, or GNU base-256 when the high bit is set. */
|
|
202
|
+
function tarNumber(header, start, length) {
|
|
203
|
+
const first = header[start] ?? 0;
|
|
204
|
+
if (first === 0o200) {
|
|
205
|
+
let n = 0;
|
|
206
|
+
for (let i = start + 1; i < start + length; i += 1)
|
|
207
|
+
n = n * 256 + (header[i] ?? 0);
|
|
208
|
+
return n;
|
|
209
|
+
}
|
|
210
|
+
if (first === 0o377)
|
|
211
|
+
throw new CorruptArchive('Invalid tar header');
|
|
212
|
+
const text = cString(header, start, length).trim();
|
|
213
|
+
if (!text)
|
|
214
|
+
return 0;
|
|
215
|
+
if (!/^[0-7]+$/.test(text))
|
|
216
|
+
throw new CorruptArchive('Invalid tar header');
|
|
217
|
+
return Number.parseInt(text, 8);
|
|
218
|
+
}
|
|
219
|
+
/** Python `tarfile.calc_chksums`: the stored checksum may be the unsigned or the signed byte sum. */
|
|
220
|
+
function checksumOk(header) {
|
|
221
|
+
let unsigned = 256;
|
|
222
|
+
let signed = 256;
|
|
223
|
+
for (let i = 0; i < BLOCK; i += 1) {
|
|
224
|
+
if (i >= 148 && i < 156)
|
|
225
|
+
continue;
|
|
226
|
+
const byte = header[i] ?? 0;
|
|
227
|
+
unsigned += byte;
|
|
228
|
+
signed += byte > 127 ? byte - 256 : byte;
|
|
229
|
+
}
|
|
230
|
+
const stored = tarNumber(header, 148, 8);
|
|
231
|
+
return stored === unsigned || stored === signed;
|
|
232
|
+
}
|
|
233
|
+
function paxRecords(data) {
|
|
234
|
+
const records = new Map();
|
|
235
|
+
let pos = 0;
|
|
236
|
+
while (pos < data.length && data[pos] !== 0) {
|
|
237
|
+
const space = data.indexOf(0x20, pos);
|
|
238
|
+
const length = space < 0 ? Number.NaN : Number(data.subarray(pos, space).toString('latin1'));
|
|
239
|
+
if (!Number.isInteger(length) || length <= space - pos || pos + length > data.length || data[pos + length - 1] !== 0x0a)
|
|
240
|
+
throw new CorruptArchive('Invalid pax header');
|
|
241
|
+
const record = data.subarray(space + 1, pos + length - 1).toString('utf8');
|
|
242
|
+
const eq = record.indexOf('=');
|
|
243
|
+
if (eq < 0)
|
|
244
|
+
throw new CorruptArchive('Invalid pax header');
|
|
245
|
+
records.set(record.slice(0, eq), record.slice(eq + 1));
|
|
246
|
+
pos += length;
|
|
247
|
+
}
|
|
248
|
+
return records;
|
|
249
|
+
}
|
|
250
|
+
/** A small ustar/pax/GNU reader: yields regular-file members only (links, devices, and directories are skipped). */
|
|
251
|
+
function* tarMembers(tar) {
|
|
252
|
+
if (tar.length < BLOCK)
|
|
253
|
+
throw new CorruptArchive('Invalid tar archive');
|
|
254
|
+
let offset = 0;
|
|
255
|
+
let longName = null;
|
|
256
|
+
let pax = new Map();
|
|
257
|
+
while (offset + BLOCK <= tar.length) {
|
|
258
|
+
const header = tar.subarray(offset, offset + BLOCK);
|
|
259
|
+
if (header.every((byte) => byte === 0))
|
|
260
|
+
return;
|
|
261
|
+
if (!checksumOk(header))
|
|
262
|
+
throw new CorruptArchive(offset === 0 ? 'Invalid tar archive' : 'Invalid tar header');
|
|
263
|
+
let name = cString(header, 0, 100);
|
|
264
|
+
if (header.subarray(257, 263).toString('latin1') === 'ustar\0') {
|
|
265
|
+
const prefix = cString(header, 345, 155);
|
|
266
|
+
if (prefix)
|
|
267
|
+
name = `${prefix}/${name}`;
|
|
268
|
+
}
|
|
269
|
+
let size = tarNumber(header, 124, 12);
|
|
270
|
+
let type = String.fromCharCode(header[156] ?? 0);
|
|
271
|
+
const dataStart = offset + BLOCK;
|
|
272
|
+
const padded = (n) => Math.ceil(n / BLOCK) * BLOCK;
|
|
273
|
+
if (type === 'x' || type === 'g' || type === 'L' || type === 'K') {
|
|
274
|
+
if (dataStart + size > tar.length)
|
|
275
|
+
throw new CorruptArchive('Unexpected end of tar data');
|
|
276
|
+
const data = tar.subarray(dataStart, dataStart + size);
|
|
277
|
+
if (type === 'x')
|
|
278
|
+
pax = paxRecords(data);
|
|
279
|
+
else if (type === 'L')
|
|
280
|
+
longName = cString(data, 0, data.length);
|
|
281
|
+
offset = dataStart + padded(size);
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
if (longName !== null)
|
|
285
|
+
name = longName;
|
|
286
|
+
const paxPath = pax.get('path');
|
|
287
|
+
if (paxPath !== undefined)
|
|
288
|
+
name = paxPath;
|
|
289
|
+
const paxSize = pax.get('size');
|
|
290
|
+
if (paxSize !== undefined) {
|
|
291
|
+
if (!/^\d+$/.test(paxSize))
|
|
292
|
+
throw new CorruptArchive('Invalid pax header');
|
|
293
|
+
size = Number(paxSize);
|
|
294
|
+
}
|
|
295
|
+
longName = null;
|
|
296
|
+
pax = new Map();
|
|
297
|
+
if (type === '\0' && name.endsWith('/'))
|
|
298
|
+
type = '5';
|
|
299
|
+
if (REGULAR_TYPES.has(type)) {
|
|
300
|
+
if (dataStart + size > tar.length)
|
|
301
|
+
throw new CorruptArchive('Unexpected end of tar data');
|
|
302
|
+
const data = tar.subarray(dataStart, dataStart + size);
|
|
303
|
+
yield { name, size, read: () => data };
|
|
304
|
+
}
|
|
305
|
+
offset = dataStart + (DATALESS_TYPES.has(type) ? 0 : padded(size));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
//# sourceMappingURL=extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/workspace/extract.ts"],"names":[],"mappings":"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"}
|
package/dist/workspace/fs.d.ts
CHANGED
|
@@ -7,6 +7,11 @@ export declare class NotFoundError extends Error {
|
|
|
7
7
|
export declare function safeResolveWs(root: string, requested: string): string;
|
|
8
8
|
/** Python `helpers.safe_resolve`: same rule, different error text. */
|
|
9
9
|
export declare function safeResolve(root: string, requested: string): string;
|
|
10
|
+
/** Run `fn` with every anchored open of `root` refused unless the root is still the inode `id`. */
|
|
11
|
+
export declare function withPinnedRoot<T>(root: string, id: {
|
|
12
|
+
dev: number;
|
|
13
|
+
ino: number;
|
|
14
|
+
}, fn: () => T): T;
|
|
10
15
|
/** Open `target` for reading with the anchored walk (Python `open_anchored_fd`). Caller closes the fd. */
|
|
11
16
|
export declare function openAnchoredFd(root: string, target: string, opts: {
|
|
12
17
|
wantDir: boolean;
|
|
@@ -20,6 +25,11 @@ export declare function openAnchoredWriteFd(root: string, target: string): numbe
|
|
|
20
25
|
export declare function unlinkAnchored(root: string, target: string): void;
|
|
21
26
|
/** Remove an empty directory through the anchored walk; a non-empty or symlinked target is left alone (throws). */
|
|
22
27
|
export declare function rmdirAnchored(root: string, target: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Remove a directory tree through the anchored walk (Python `shutil.rmtree(dir_fd=...)`): every directory is
|
|
30
|
+
* opened from its parent's descriptor with `O_NOFOLLOW` and emptied through its own, so an entry swapped for a
|
|
31
|
+
* symlink mid-walk is unlinked as a link and never followed.
|
|
32
|
+
*/
|
|
23
33
|
export declare function rmtreeAnchored(root: string, target: string): void;
|
|
24
34
|
export declare function renameAnchored(root: string, source: string, dest: string): void;
|
|
25
35
|
/**
|
|
@@ -59,6 +69,8 @@ export interface FileContent {
|
|
|
59
69
|
}
|
|
60
70
|
export declare class FileTooLargeError extends Error {
|
|
61
71
|
}
|
|
72
|
+
/** `raw` as UTF-8 text, or null for a binary file (a NUL byte, or bytes that do not round-trip). */
|
|
73
|
+
export declare function decodeText(raw: Buffer): string | null;
|
|
62
74
|
/** Python `read_file_content` (office previews were dropped with TAL-245). */
|
|
63
75
|
export declare function readFileContent(workspace: string, rel: string, opts?: {
|
|
64
76
|
statOnly?: boolean;
|