@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
package/dist/redact.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { str } from './util.js';
|
|
2
|
+
import { diffHunks } from './text/diff.js';
|
|
3
|
+
import { isRasterDataUri } from './raster-image.js';
|
|
2
4
|
import { snapshotArgs, toolArgs, toolDisplay, toolName } from './sessions/tool-display.js';
|
|
3
|
-
import { messageText } from './sessions/merge.js';
|
|
5
|
+
import { hasNativeImages, messageText, normalizeUserDisplay } from './sessions/merge.js';
|
|
4
6
|
import { stripAttachedFilesMarker } from './sessions/session.js';
|
|
5
7
|
/**
|
|
6
8
|
* Credential redaction and the public session projection (Python
|
|
@@ -258,39 +260,56 @@ const ANSI_PAYLOAD_GAPS_RE = new RegExp([SEQ_CSI, String.raw `${SEQ_ESC}[\]PX^_]
|
|
|
258
260
|
* terminal title can hold a token), and without control characters only (an escape's final byte can be a token's).
|
|
259
261
|
*/
|
|
260
262
|
const SPLIT_VIEWS = [ANSI_GAPS_RE, ANSI_PAYLOAD_GAPS_RE, CONTROL_CHARS_RE];
|
|
263
|
+
/** `ANSI_GAPS_RE` without the whitespace controls, so a view keeps its lines and words apart. */
|
|
264
|
+
const DISPLAY_GAPS_RE = new RegExp(String.raw `(?![\t-\r])(?:${ANSI_GAPS_RE.source})`, 'g');
|
|
261
265
|
const ANSI_GAP_AT_RE = new RegExp(ANSI_GAPS_RE.source, 'y');
|
|
262
266
|
const TOKEN_CHAR_RE = /[A-Za-z0-9_-]/;
|
|
267
|
+
/** A character a credential's prefix or body can hold (`SG.`, `glrt-a.b`, `gAAAA…=`): what a fail-closed run walks. */
|
|
268
|
+
const RUN_CHAR_RE = /[A-Za-z0-9_.=-]/;
|
|
263
269
|
/** A string sequence's opener, with an OSC's command number (`8;`), which is no payload. */
|
|
264
270
|
const STRING_OPENER_RE = new RegExp(String.raw `^(?:(?:${SEQ_ESC}\]|\x9d)(?:\d*;)?|${SEQ_ESC}[PX^_]|[\x90\x98\x9e\x9f])`);
|
|
265
271
|
const PAYLOAD_RUN_CAP = 65_536;
|
|
266
|
-
|
|
272
|
+
/**
|
|
273
|
+
* The token families a split token is joined for, each with its own boundaries: `CRED_RE`'s prefixes, and `JWT_RE`, whose
|
|
274
|
+
* `\b` lets a JWT start after a `-` and which has no right boundary.
|
|
275
|
+
*/
|
|
276
|
+
const TOKEN_TEST_RE = new RegExp(`${CRED_RE.source}|${JWT_RE.source}`);
|
|
267
277
|
/** `CRED_RE`'s prefix and body from a position, without its boundaries (a split token checks the original ones). */
|
|
268
278
|
const CRED_RUN_RE = new RegExp(CRED_RE.source.replace(/^\(\?<!\[A-Za-z0-9_-\]\)/, '').replace(/\(\?!\[A-Za-z0-9_-\]\)$/, ''), 'y');
|
|
279
|
+
const JWT_RUN_SOURCE = JWT_RE.source.replace(/^\\b/, '');
|
|
280
|
+
/** A credential's or JWT's prefix and body from a position, without its boundaries. */
|
|
281
|
+
const TOKEN_RUN_RE = new RegExp(`${CRED_RUN_RE.source}|${JWT_RUN_SOURCE}`, 'y');
|
|
269
282
|
const SPLIT_TOKEN_CAP = 1024;
|
|
270
283
|
/** Where a `CRED_RE` prefix and body start at a boundary, however they end. */
|
|
271
284
|
const CRED_START_RE = new RegExp(CRED_RE.source.replace(/\(\?!\[A-Za-z0-9_-\]\)$/, ''), 'g');
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
const
|
|
285
|
+
const TOKEN_START_RE = new RegExp(`${CRED_START_RE.source}|${JWT_RE.source}`, 'g');
|
|
286
|
+
const TOKEN_WHOLE_RE = new RegExp(`^(?:${CRED_RE.source}|${JWT_RE.source})$`);
|
|
287
|
+
/** `TOKEN_START_RE` and `TOKEN_RUN_RE` without their body: a token's prefix, however little of its body follows. */
|
|
288
|
+
const TOKEN_PREFIX_RE = new RegExp(`${CRED_START_RE.source.replace(/\{\d+,?\}/g, '{0}')}|\\beyJ`, 'g');
|
|
289
|
+
const TOKEN_PREFIX_RUN_RE = new RegExp(`${CRED_RUN_RE.source.replace(/\{\d+,?\}/g, '{0}')}|eyJ`, 'y');
|
|
276
290
|
/** A URL query parameter's value, up to the next `&` or `#`. */
|
|
277
291
|
const QUERY_VALUE_RE = /[^&#]*/y;
|
|
278
|
-
const
|
|
279
|
-
/**
|
|
280
|
-
|
|
292
|
+
const PEM_OPENER = '-----BEGIN';
|
|
293
|
+
/**
|
|
294
|
+
* A private key through its end marker (captured) or, when that is missing (a display cap cut it off), to the end of the
|
|
295
|
+
* text.
|
|
296
|
+
*/
|
|
297
|
+
const PRIVKEY_RE = /-----BEGIN[A-Z ]*PRIVATE KEY-----(?:[\s\S]*?(-----END[A-Z ]*PRIVATE KEY-----)|[\s\S]*$)/g;
|
|
298
|
+
/** `PRIVKEY_RE` after its opener, from a position. */
|
|
299
|
+
const PRIVKEY_REST_RE = new RegExp(PRIVKEY_RE.source.slice(PEM_OPENER.length), 'y');
|
|
281
300
|
const CODE_ENV_KEY_LITERAL_RE = /([A-Z0-9_]{0,50}(?:API_?KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|AUTH)[A-Z0-9_]{0,50}=)(["'][)\]:,]+|[)\]:,]+)/y;
|
|
282
301
|
const ENV_KEY_PREFIX_RE = /([A-Z0-9_]{0,50}(?:API_?KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|AUTH)[A-Z0-9_]{0,50}=)/g;
|
|
283
302
|
const REDACTED_ENV_VALUE_RE = /(?:\*{3,}|[A-Za-z0-9][A-Za-z0-9_.:/+-]{0,32}\.\.\.[A-Za-z0-9_.:/+-]{1,16})/y;
|
|
284
303
|
/**
|
|
285
|
-
* Where a credential split by control or zero-width characters (`ghp_abc\x1bdef`, `ghp_abc\ndef…`) starting at `i` of the
|
|
304
|
+
* Where a credential or JWT split by control or zero-width characters (`ghp_abc\x1bdef`, `ghp_abc\ndef…`) starting at `i` of the
|
|
286
305
|
* stripped text ends there, or -1. The run of its prefix and body is read once (capped), then the longest candidate is
|
|
287
|
-
* taken that ends at a piece boundary of the original, is a whole
|
|
306
|
+
* taken that ends at a piece boundary of the original, is a whole token, is not the name of a `KEY=` that follows,
|
|
288
307
|
* and never reaches a line holding a whole token itself (that line is the prefix pass's and joins nothing).
|
|
289
308
|
*/
|
|
290
309
|
function splitTokenEnd(text, stripped, kept, i) {
|
|
291
|
-
|
|
310
|
+
TOKEN_RUN_RE.lastIndex = 0;
|
|
292
311
|
// ponytail: a split credential longer than SPLIT_TOKEN_CAP is cut at the cap; raise it if longer tokens appear.
|
|
293
|
-
const run =
|
|
312
|
+
const run = TOKEN_RUN_RE.exec(stripped.slice(i, i + SPLIT_TOKEN_CAP))?.[0];
|
|
294
313
|
if (!run)
|
|
295
314
|
return -1;
|
|
296
315
|
const start = kept[i];
|
|
@@ -298,7 +317,7 @@ function splitTokenEnd(text, stripped, kept, i) {
|
|
|
298
317
|
for (let lineStart = start; lineStart < limit;) {
|
|
299
318
|
const lineEnd = text.slice(lineStart, limit).search(/[\r\n]/);
|
|
300
319
|
const end = lineEnd === -1 ? limit : lineStart + lineEnd;
|
|
301
|
-
if (
|
|
320
|
+
if (TOKEN_TEST_RE.test(text.slice(lineStart, end))) {
|
|
302
321
|
limit = lineStart === start ? end : lineStart;
|
|
303
322
|
break;
|
|
304
323
|
}
|
|
@@ -309,23 +328,17 @@ function splitTokenEnd(text, stripped, kept, i) {
|
|
|
309
328
|
for (let e = i + run.length; e > i; e -= 1) {
|
|
310
329
|
const atBoundary = e === stripped.length || kept[e] - kept[e - 1] > 1 || (e === i + run.length && !/[A-Za-z0-9_-]/.test(stripped[e]));
|
|
311
330
|
const originalEnd = kept[e - 1] + 1;
|
|
312
|
-
if (!atBoundary || originalEnd > limit || !
|
|
331
|
+
if (!atBoundary || originalEnd > limit || !TOKEN_WHOLE_RE.test(stripped.slice(i, e)) || /^[ \t]*=/.test(text.slice(originalEnd, originalEnd + 64)))
|
|
313
332
|
continue;
|
|
314
333
|
return e;
|
|
315
334
|
}
|
|
316
335
|
return -1;
|
|
317
336
|
}
|
|
318
|
-
/**
|
|
319
|
-
|
|
320
|
-
* matched on the text without those gaps, plus `payloadRunSpan`'s from each prefix. A token starts at a boundary of the
|
|
321
|
-
* stripped text, or where a stripped gap hid the original one (`note\nghp_…`); one starting inside a token already
|
|
322
|
-
* masked is part of it.
|
|
323
|
-
*/
|
|
324
|
-
function splitTokenSpans(text, gaps) {
|
|
337
|
+
/** The text without the gaps of `gaps`, and the original index of each kept character, or null when it has none. */
|
|
338
|
+
function splitView(text, gaps) {
|
|
325
339
|
const stripped = text.replace(gaps, '');
|
|
326
340
|
if (stripped.length === text.length)
|
|
327
|
-
return
|
|
328
|
-
// The original index of each kept character.
|
|
341
|
+
return null;
|
|
329
342
|
const kept = [];
|
|
330
343
|
let at = 0;
|
|
331
344
|
for (const m of text.matchAll(gaps)) {
|
|
@@ -335,14 +348,27 @@ function splitTokenSpans(text, gaps) {
|
|
|
335
348
|
}
|
|
336
349
|
while (at < text.length)
|
|
337
350
|
kept.push(at++);
|
|
338
|
-
|
|
339
|
-
|
|
351
|
+
return { stripped, kept };
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* The original spans, and the joined text, of prefixed credentials and JWTs whose body a gap of one of `SPLIT_VIEWS` splits,
|
|
355
|
+
* matched on the text without those gaps, plus `payloadRunSpan`'s from each prefix. A token starts at a boundary of the
|
|
356
|
+
* stripped text, or where a stripped gap hid the original one (`note\nghp_…`); one starting inside a token already
|
|
357
|
+
* masked is part of it.
|
|
358
|
+
*/
|
|
359
|
+
function splitTokenSpans(text, gaps) {
|
|
360
|
+
const view = splitView(text, gaps);
|
|
361
|
+
if (!view)
|
|
362
|
+
return [];
|
|
363
|
+
const { stripped, kept } = view;
|
|
364
|
+
const starts = [...stripped.matchAll(TOKEN_START_RE)].map((m) => m.index);
|
|
365
|
+
const prefixStarts = [...stripped.matchAll(TOKEN_PREFIX_RE)].map((m) => m.index);
|
|
340
366
|
for (let i = 1; i < kept.length; i += 1) {
|
|
341
367
|
if (kept[i] - kept[i - 1] <= 1 || !TOKEN_CHAR_RE.test(stripped[i - 1]))
|
|
342
368
|
continue;
|
|
343
369
|
starts.push(i);
|
|
344
|
-
|
|
345
|
-
if (
|
|
370
|
+
TOKEN_PREFIX_RUN_RE.lastIndex = i;
|
|
371
|
+
if (TOKEN_PREFIX_RUN_RE.test(stripped))
|
|
346
372
|
prefixStarts.push(i);
|
|
347
373
|
}
|
|
348
374
|
const spans = [];
|
|
@@ -356,17 +382,103 @@ function splitTokenSpans(text, gaps) {
|
|
|
356
382
|
spans.push([kept[i], kept[e - 1] + 1, stripped.slice(i, e)]);
|
|
357
383
|
scanned = e;
|
|
358
384
|
}
|
|
385
|
+
return [...spans, ...payloadRunSpans(text, prefixStarts.map((i) => kept[i]))];
|
|
386
|
+
}
|
|
387
|
+
/** `payloadRunSpan`'s spans from credential prefixes at these original indices, each run walked once. */
|
|
388
|
+
function payloadRunSpans(text, starts) {
|
|
389
|
+
const spans = [];
|
|
359
390
|
let walked = 0;
|
|
360
|
-
for (const
|
|
361
|
-
if (
|
|
391
|
+
for (const start of starts.sort((a, b) => a - b)) {
|
|
392
|
+
if (start < walked)
|
|
362
393
|
continue;
|
|
363
|
-
const [span, reached] = payloadRunSpan(text,
|
|
394
|
+
const [span, reached] = payloadRunSpan(text, start);
|
|
364
395
|
if (span)
|
|
365
396
|
spans.push(span);
|
|
366
397
|
walked = reached;
|
|
367
398
|
}
|
|
368
399
|
return spans;
|
|
369
400
|
}
|
|
401
|
+
/** A string sequence's terminator: BEL (OSC only), ST, or CAN or SUB cancelling it. */
|
|
402
|
+
const STRING_END_RE = /(?:\x07|\x1b\\|\x9c|[\x18\x1a])$/;
|
|
403
|
+
/** Tags a candidate that can grow only into a JWT prefix: one starting after a `-`, a boundary for `JWT_RE`'s `\b` alone. */
|
|
404
|
+
const JWT_ONLY = '\0';
|
|
405
|
+
/**
|
|
406
|
+
* What a piece after `prev` (undefined after a gap) seeds: any prefix after a non-token character, only a JWT's after a
|
|
407
|
+
* `-`, none after a word character.
|
|
408
|
+
*/
|
|
409
|
+
const seedAfter = (prev) => (prev === undefined || !TOKEN_CHAR_RE.test(prev) ? '' : prev === '-' ? JWT_ONLY : null);
|
|
410
|
+
/**
|
|
411
|
+
* Where a credential or JWT prefix or a private key's opener starts, where it ends, and which marker it is, when its
|
|
412
|
+
* pieces lie apart in a run of token characters and escape sequences, with a string payload between them taken whole or
|
|
413
|
+
* skipped (`g\x1b]0;x\x07h\x1b]0;p_\x07…`), so that no view holds it whole.
|
|
414
|
+
* Display characters are mandatory and each payload's optional. A piece starts on the display after a gap or a non-token
|
|
415
|
+
* character (`.`), or in a payload's trailing run after its start or a non-token character, where `payloadRunSpan` can
|
|
416
|
+
* walk from it; a JWT's also after a `-`.
|
|
417
|
+
* Candidates live only while they can grow into a prefix, which bounds them and keeps the scan linear.
|
|
418
|
+
*/
|
|
419
|
+
function crossPayloadPrefixStarts(text) {
|
|
420
|
+
const starts = [];
|
|
421
|
+
if (!/[\x1b\x90\x98\x9d-\x9f]/.test(text))
|
|
422
|
+
return starts;
|
|
423
|
+
// Each candidate string, with the original index of its earliest start.
|
|
424
|
+
let candidates = new Map();
|
|
425
|
+
// Grows a candidate by the run characters of `chars`, which starts at original index `at`.
|
|
426
|
+
const grow = (into, candidate, start, chars, at) => {
|
|
427
|
+
for (let j = 0; j < chars.length; j += 1) {
|
|
428
|
+
if (!RUN_CHAR_RE.test(chars[j]))
|
|
429
|
+
continue;
|
|
430
|
+
candidate += chars[j];
|
|
431
|
+
if (PAYLOAD_MARKERS.has(candidate))
|
|
432
|
+
return void starts.push([start, at + j + 1, candidate]);
|
|
433
|
+
if (!PAYLOAD_MARKER_STEMS.has(candidate))
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const seen = into.get(candidate);
|
|
437
|
+
if (seen === undefined || start < seen)
|
|
438
|
+
into.set(candidate, start);
|
|
439
|
+
};
|
|
440
|
+
// The last display character, unless a gap came after it: what a piece starting here may seed.
|
|
441
|
+
let prev;
|
|
442
|
+
for (let k = 0; k < text.length;) {
|
|
443
|
+
ANSI_GAP_AT_RE.lastIndex = k;
|
|
444
|
+
const gap = ANSI_GAP_AT_RE.exec(text)?.[0];
|
|
445
|
+
if (gap) {
|
|
446
|
+
const from = STRING_OPENER_RE.exec(gap)?.[0].length ?? gap.length;
|
|
447
|
+
const next = new Map(candidates);
|
|
448
|
+
for (const [candidate, start] of candidates)
|
|
449
|
+
grow(next, candidate, start, gap.slice(from), k + from);
|
|
450
|
+
const end = Math.max(from, gap.length - (STRING_END_RE.exec(gap)?.[0].length ?? 0));
|
|
451
|
+
let tail = end;
|
|
452
|
+
while (tail > from && RUN_CHAR_RE.test(gap[tail - 1]))
|
|
453
|
+
tail -= 1;
|
|
454
|
+
for (let j = tail; j < end; j += 1) {
|
|
455
|
+
const seed = seedAfter(j === tail ? undefined : gap[j - 1]);
|
|
456
|
+
if (seed !== null)
|
|
457
|
+
grow(next, seed, k + j, gap.slice(j, end), k + j);
|
|
458
|
+
}
|
|
459
|
+
candidates = next;
|
|
460
|
+
prev = undefined;
|
|
461
|
+
k += gap.length;
|
|
462
|
+
}
|
|
463
|
+
else if (RUN_CHAR_RE.test(text[k])) {
|
|
464
|
+
const next = new Map();
|
|
465
|
+
for (const [candidate, start] of candidates)
|
|
466
|
+
grow(next, candidate, start, text[k], k);
|
|
467
|
+
const seed = seedAfter(prev);
|
|
468
|
+
if (seed !== null)
|
|
469
|
+
grow(next, seed, k, text[k], k);
|
|
470
|
+
candidates = next;
|
|
471
|
+
prev = text[k];
|
|
472
|
+
k += 1;
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
candidates.clear();
|
|
476
|
+
prev = undefined;
|
|
477
|
+
k += 1;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return starts;
|
|
481
|
+
}
|
|
370
482
|
/**
|
|
371
483
|
* Fail-closed for a token split across string payloads: from a credential prefix at `start`, the span through the run of
|
|
372
484
|
* token characters and whole escape sequences after it, when a string payload in the run holds token characters, and
|
|
@@ -385,7 +497,7 @@ function payloadRunSpan(text, start) {
|
|
|
385
497
|
if (gap) {
|
|
386
498
|
const from = STRING_OPENER_RE.exec(gap)?.[0].length ?? gap.length;
|
|
387
499
|
for (let j = from; j < gap.length; j += 1) {
|
|
388
|
-
if (!
|
|
500
|
+
if (!RUN_CHAR_RE.test(gap[j]))
|
|
389
501
|
continue;
|
|
390
502
|
token += gap[j];
|
|
391
503
|
end = k + j + 1;
|
|
@@ -393,7 +505,7 @@ function payloadRunSpan(text, start) {
|
|
|
393
505
|
}
|
|
394
506
|
k += gap.length;
|
|
395
507
|
}
|
|
396
|
-
else if (
|
|
508
|
+
else if (RUN_CHAR_RE.test(text[k])) {
|
|
397
509
|
token += text[k];
|
|
398
510
|
end = k += 1;
|
|
399
511
|
}
|
|
@@ -402,9 +514,51 @@ function payloadRunSpan(text, start) {
|
|
|
402
514
|
}
|
|
403
515
|
return [hidden ? [start, end, token] : null, k];
|
|
404
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* The original spans of private keys a gap of one of `SPLIT_VIEWS` splits (`-----BE\x1b[1mGIN …`), matched on each view,
|
|
519
|
+
* and of those whose opener lies apart across string payloads (`-----B\x1b]0;x\x07E\x1b]0;GIN\x07 …`), matched on each
|
|
520
|
+
* view from where the opener ends. A whole key is `PRIVKEY_RE`'s on the text itself. A key one view leaves open runs to
|
|
521
|
+
* the end of the text only when no view closes one there (`-----END PRI\x1b[1mVATE KEY-----`).
|
|
522
|
+
*/
|
|
523
|
+
function privateKeySpans(text) {
|
|
524
|
+
const openers = crossPayloadPrefixStarts(text).filter(([, , marker]) => marker === PEM_OPENER).sort((a, b) => a[1] - b[1]);
|
|
525
|
+
const closed = [];
|
|
526
|
+
const open = [];
|
|
527
|
+
for (const gaps of SPLIT_VIEWS) {
|
|
528
|
+
const view = splitView(text, gaps);
|
|
529
|
+
if (!view)
|
|
530
|
+
continue;
|
|
531
|
+
const { stripped, kept } = view;
|
|
532
|
+
// A key running to the end of the view runs to the end of the text, past any trailing gap.
|
|
533
|
+
const end = (e) => (e === stripped.length ? text.length : kept[e - 1] + 1);
|
|
534
|
+
for (const m of stripped.matchAll(PRIVKEY_RE))
|
|
535
|
+
(m[1] ? closed : open).push([kept[m.index], end(m.index + m[0].length), '']);
|
|
536
|
+
let i = 0;
|
|
537
|
+
let scanned = 0;
|
|
538
|
+
for (const [start, opened] of openers) {
|
|
539
|
+
if (opened < scanned)
|
|
540
|
+
continue;
|
|
541
|
+
while (i < kept.length && kept[i] < opened)
|
|
542
|
+
i += 1;
|
|
543
|
+
PRIVKEY_REST_RE.lastIndex = i;
|
|
544
|
+
const m = PRIVKEY_REST_RE.exec(stripped);
|
|
545
|
+
if (!m)
|
|
546
|
+
continue;
|
|
547
|
+
scanned = end(PRIVKEY_REST_RE.lastIndex);
|
|
548
|
+
const spans = m[1] ? closed : open;
|
|
549
|
+
spans.push([start, scanned, '']);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return [...closed, ...open.filter(([start]) => !closed.some(([from, to]) => from <= start && start < to))];
|
|
553
|
+
}
|
|
405
554
|
/** Masks each union of the split-token spans every view finds, so no view masks a piece of a token another one joins. */
|
|
406
555
|
function maskSplitTokens(text) {
|
|
407
|
-
const
|
|
556
|
+
const starts = crossPayloadPrefixStarts(text).flatMap(([start, , marker]) => (marker === PEM_OPENER ? [] : [start]));
|
|
557
|
+
return maskSpans(text, [...SPLIT_VIEWS.flatMap((gaps) => splitTokenSpans(text, gaps)), ...payloadRunSpans(text, starts)], mask);
|
|
558
|
+
}
|
|
559
|
+
/** Replaces each union of overlapping original spans, given the longest of their texts. */
|
|
560
|
+
function maskSpans(text, found, replace) {
|
|
561
|
+
const spans = found.sort((a, b) => a[0] - b[0]);
|
|
408
562
|
let out = '';
|
|
409
563
|
let last = 0;
|
|
410
564
|
for (let k = 0; k < spans.length;) {
|
|
@@ -416,7 +570,7 @@ function maskSplitTokens(text) {
|
|
|
416
570
|
if (nextToken.length > token.length)
|
|
417
571
|
token = nextToken;
|
|
418
572
|
}
|
|
419
|
-
out += text.slice(last, start) +
|
|
573
|
+
out += text.slice(last, start) + replace(token);
|
|
420
574
|
last = end;
|
|
421
575
|
}
|
|
422
576
|
return out + text.slice(last);
|
|
@@ -938,7 +1092,10 @@ const REDIRECT_RE = /[0-9]*(?:&>>?|<<<|<<-?|<>|>>|>&|<&|>\||[<>])/y;
|
|
|
938
1092
|
*/
|
|
939
1093
|
function commandWords(text, from, enclosing, list) {
|
|
940
1094
|
const spans = [];
|
|
941
|
-
const [gap, close
|
|
1095
|
+
const [gap, close] = list ? [/[ \t,<>]/, /[\n;&|()\]}]/] : [/[ \t]/, /[\n;&|()]/];
|
|
1096
|
+
// A word ends only where the scan can step on (a gap, a redirection) or the command ends, so it always advances. Other
|
|
1097
|
+
// whitespace (`\r`, a no-break space) is part of the word, as the shell reads it, so a secret holding one is masked whole.
|
|
1098
|
+
const stop = new RegExp(`${gap.source}|${close.source}|[<>]`);
|
|
942
1099
|
let i = from;
|
|
943
1100
|
let redirect = false;
|
|
944
1101
|
for (;;) {
|
|
@@ -1606,6 +1763,69 @@ function secretTokenCounts(text) {
|
|
|
1606
1763
|
export function redactSensitive(text) {
|
|
1607
1764
|
if (!text)
|
|
1608
1765
|
return text;
|
|
1766
|
+
const redacted = redactShellText(text);
|
|
1767
|
+
// An escape sequence in a key or between a key and its value (`\x1b[1;31mAPI_KEY\x1b[m=…`, `pass\x1b[1mword …`) hides
|
|
1768
|
+
// it from the rules. A unit of the text the view without sequences masks anywhere is masked in the text's redaction,
|
|
1769
|
+
// wherever it still shows, removing a sequence inside one and keeping the rest.
|
|
1770
|
+
const stripped = text.replace(DISPLAY_GAPS_RE, '');
|
|
1771
|
+
if (stripped.length === text.length)
|
|
1772
|
+
return redacted;
|
|
1773
|
+
const shown = redactShellText(stripped);
|
|
1774
|
+
const base = unitCounts(stripped);
|
|
1775
|
+
const shownCounts = unitCounts(shown);
|
|
1776
|
+
const view = splitView(redacted, DISPLAY_GAPS_RE);
|
|
1777
|
+
const plain = view?.stripped ?? redacted;
|
|
1778
|
+
const at = (i) => (view ? view.kept[i] : i);
|
|
1779
|
+
const raw = unitCounts(plain);
|
|
1780
|
+
// Hidden by a redaction showing `counts`: fewer than the text holds, or fewer than another redaction shows (a value
|
|
1781
|
+
// equal to a mask made elsewhere, `ghp_ab...cdef`, fails closed). Only a unit of the text is masked, never a mask.
|
|
1782
|
+
const hides = (counts, other, unit) => {
|
|
1783
|
+
const n = counts.get(unit) ?? 0;
|
|
1784
|
+
return base.has(unit) && (n < base.get(unit) || n < (other.get(unit) ?? 0));
|
|
1785
|
+
};
|
|
1786
|
+
// Masked units only blanks apart are one value (`'correct horse battery'`), masked whole so its word count stays hidden.
|
|
1787
|
+
const spans = [];
|
|
1788
|
+
let last = -1;
|
|
1789
|
+
for (const m of plain.matchAll(MASK_OR_UNIT_RE)) {
|
|
1790
|
+
if (!hides(shownCounts, raw, m[0]))
|
|
1791
|
+
continue;
|
|
1792
|
+
const end = at(m.index + m[0].length - 1) + 1;
|
|
1793
|
+
if (last !== -1 && /^[ \t]+$/.test(plain.slice(last, m.index)))
|
|
1794
|
+
spans.at(-1)[1] = end;
|
|
1795
|
+
else
|
|
1796
|
+
spans.push([at(m.index), end, m[0]]);
|
|
1797
|
+
last = m.index + m[0].length;
|
|
1798
|
+
}
|
|
1799
|
+
const out = spans.length ? maskSpans(redacted, spans, () => '***') : redacted;
|
|
1800
|
+
// A credential of delimiters only (`Bear\x1b[1mer $$$$`) has no unit to mask: when the view shows fewer of a delimiter
|
|
1801
|
+
// than the text's redaction, the view's redaction is returned, without escape sequences, with each unit the text's
|
|
1802
|
+
// redaction hides masked in it too.
|
|
1803
|
+
const plainOut = out.replace(DISPLAY_GAPS_RE, '');
|
|
1804
|
+
const outCounts = delimiterCounts(plainOut);
|
|
1805
|
+
const viewCounts = delimiterCounts(shown);
|
|
1806
|
+
if (![...outCounts].some(([char, count]) => (viewCounts.get(char) ?? 0) < count))
|
|
1807
|
+
return out;
|
|
1808
|
+
const hidden = unitCounts(plainOut);
|
|
1809
|
+
return shown.replace(MASK_OR_UNIT_RE, (unit) => (hides(hidden, shownCounts, unit) ? '***' : unit));
|
|
1810
|
+
}
|
|
1811
|
+
const PRIVATE_KEY_MASK = '[REDACTED PRIVATE KEY]';
|
|
1812
|
+
/** A private key's mask, as one unit (its words are no units of their own), or a `SECRET_UNIT_RE` unit. */
|
|
1813
|
+
const MASK_OR_UNIT_RE = new RegExp(String.raw `\[REDACTED PRIVATE KEY\]|${SECRET_UNIT_RE.source}`, 'gu');
|
|
1814
|
+
/** A text's `MASK_OR_UNIT_RE` units, counted. */
|
|
1815
|
+
function unitCounts(text) {
|
|
1816
|
+
const counts = new Map();
|
|
1817
|
+
for (const [unit] of text.matchAll(MASK_OR_UNIT_RE))
|
|
1818
|
+
counts.set(unit, (counts.get(unit) ?? 0) + 1);
|
|
1819
|
+
return counts;
|
|
1820
|
+
}
|
|
1821
|
+
/** A text's delimiters, `SECRET_UNIT_RE`'s but whitespace, counted outside the masks `***` and a private key's. */
|
|
1822
|
+
function delimiterCounts(text) {
|
|
1823
|
+
const counts = new Map();
|
|
1824
|
+
for (const [char] of text.replaceAll(PRIVATE_KEY_MASK, '').replace(/(?<!\*)\*{3}(?!\*)/g, '').matchAll(/['"`$\\=:@/;&|<>(){}[\],*]/g))
|
|
1825
|
+
counts.set(char, (counts.get(char) ?? 0) + 1);
|
|
1826
|
+
return counts;
|
|
1827
|
+
}
|
|
1828
|
+
function redactShellText(text) {
|
|
1609
1829
|
// Line continuations join their lines as the shell runs them (`--user \⏎ bob:pw`, `--pass\⏎word=x`): that view is
|
|
1610
1830
|
// redacted, and a text with nothing to mask keeps its lines as written.
|
|
1611
1831
|
const joined = text.replace(/\\\r?\n/g, '');
|
|
@@ -1783,7 +2003,7 @@ export function redactSensitive(text) {
|
|
|
1783
2003
|
function redactRules(text) {
|
|
1784
2004
|
if (!text)
|
|
1785
2005
|
return text;
|
|
1786
|
-
let out = maskSplitTokens(text).replace(CRED_RE, (_, t) => mask(t));
|
|
2006
|
+
let out = maskSplitTokens(maskSpans(text, privateKeySpans(text), () => '[REDACTED PRIVATE KEY]')).replace(CRED_RE, (_, t) => mask(t));
|
|
1787
2007
|
out = out.replace(EMBEDDED_AWS_RE, (t) => mask(t));
|
|
1788
2008
|
out = redactHeaderCredentials(out, AUTH_HDR_RE);
|
|
1789
2009
|
out = out.replace(JWT_RE, (t) => mask(t));
|
|
@@ -1813,7 +2033,7 @@ function redactRules(text) {
|
|
|
1813
2033
|
out = redactUserFlags(out);
|
|
1814
2034
|
out = redactCommandFlags(out);
|
|
1815
2035
|
out = out.replace(QUERY_KEY_RE, (whole, head, value) => (/[A-Za-z0-9]/.test(value) ? head + mask(value) : whole));
|
|
1816
|
-
out = out.replace(PRIVKEY_RE, '[REDACTED PRIVATE KEY]')
|
|
2036
|
+
out = out.replace(PRIVKEY_RE, '[REDACTED PRIVATE KEY]');
|
|
1817
2037
|
return restoreCodeEnvKeyLiterals(text, out);
|
|
1818
2038
|
}
|
|
1819
2039
|
const CASE_MARKERS = [
|
|
@@ -1822,6 +2042,11 @@ const CASE_MARKERS = [
|
|
|
1822
2042
|
'gsk_', 'syt_', 'retaindb_', 'hsk-', 'mem0_', 'brv_', 'xapp-', 'xai-', 'ntn_', 'fw-', 'fw_', 'fpk_', 'glpat-', 'gloas-', 'gldt-', 'glrt-', 'glrtr-',
|
|
1823
2043
|
'glcbt-', 'glptt-', 'glft-', 'glimt-', 'glagent-', 'glsoat-', 'glffct-', 'glwt-', 'GR1348941', 'pk-lf-', 'eyJ', '-----BEGIN',
|
|
1824
2044
|
];
|
|
2045
|
+
/** The literal prefixes of `CRED_RE` (`xapp-` stands for `xapp-1-`) and `JWT_RE`, the JWT's also as `JWT_ONLY`'s. */
|
|
2046
|
+
const TOKEN_MARKERS = new Set([...CASE_MARKERS.filter((m) => ((TOKEN_PREFIX_RUN_RE.lastIndex = 0), TOKEN_PREFIX_RUN_RE.test(`${m}0-`))), `${JWT_ONLY}eyJ`]);
|
|
2047
|
+
/** What a cross-payload scan assembles: `TOKEN_MARKERS` and a private key's opener, and their proper prefixes. */
|
|
2048
|
+
const PAYLOAD_MARKERS = new Set([...TOKEN_MARKERS, PEM_OPENER]);
|
|
2049
|
+
const PAYLOAD_MARKER_STEMS = new Set([...PAYLOAD_MARKERS].flatMap((m) => Array.from({ length: m.length - 1 }, (_, n) => m.slice(0, n + 1))));
|
|
1825
2050
|
const LOWER_MARKERS = [
|
|
1826
2051
|
'authorization: bearer ', 'authorization: bot ', 'private key', 'postgres://', 'postgresql://', 'mysql://', 'mongodb://', 'redis://', 'amqp://', '://',
|
|
1827
2052
|
'access_token', 'refresh_token', 'id_token', 'api_key', 'apikey', 'client_secret', 'auth_token', 'raw_secret', 'secret_input', 'key_material',
|
|
@@ -1838,6 +2063,12 @@ export function mightContainSensitiveText(text) {
|
|
|
1838
2063
|
const views = SPLIT_VIEWS.map((gaps) => text.replace(gaps, ''));
|
|
1839
2064
|
if (CASE_MARKERS.some((m) => views.some((view) => view.includes(m))))
|
|
1840
2065
|
return true;
|
|
2066
|
+
if (crossPayloadPrefixStarts(text).length)
|
|
2067
|
+
return true;
|
|
2068
|
+
// So is a key or token an escape sequence splits (`pass\x1b[1mword`, `123456789\x1b[0m:…`).
|
|
2069
|
+
return mightContainKeyword(text) || (views[0] !== text && mightContainKeyword(views[0]));
|
|
2070
|
+
}
|
|
2071
|
+
function mightContainKeyword(text) {
|
|
1841
2072
|
const lower = text.toLowerCase();
|
|
1842
2073
|
if (LOWER_MARKERS.some((m) => lower.includes(m)))
|
|
1843
2074
|
return true;
|
|
@@ -1901,11 +2132,15 @@ export function redactValue(v, enabled) {
|
|
|
1901
2132
|
return redactText(v, enabled);
|
|
1902
2133
|
if (Array.isArray(v))
|
|
1903
2134
|
return v.map((item) => redactValue(item, enabled));
|
|
1904
|
-
if (v
|
|
1905
|
-
return
|
|
1906
|
-
|
|
2135
|
+
if (!v || typeof v !== 'object')
|
|
2136
|
+
return v;
|
|
2137
|
+
const out = Object.fromEntries(Object.entries(v).map(([k, val]) => [k, redactValue(val, enabled)]));
|
|
2138
|
+
// TAL-604: a diff's `hunks` are re-parsed from its redacted text, which masks spans (a private key) that no single line shows.
|
|
2139
|
+
if (enabled && Array.isArray(out.hunks) && typeof out.diff === 'string')
|
|
2140
|
+
out.hunks = diffHunks(out.diff);
|
|
2141
|
+
return out;
|
|
1907
2142
|
}
|
|
1908
|
-
export const PUBLIC_MESSAGE_INTERNAL_FIELDS = new Set(['api_content', '_row_id', '_state_db_row_id', '_state_db_generation', '_db_row_id', 'state_db_row_id', '_active_turn_token', '_active_turn_user', '_fork_child_turn']);
|
|
2143
|
+
export const PUBLIC_MESSAGE_INTERNAL_FIELDS = new Set(['_background_review_terminal', 'api_content', '_absorbed_message_uids', '_row_id', '_state_db_row_id', '_state_db_message_uid', '_state_db_generation', '_state_db_authored_change', '_state_db_source_key', '_db_row_id', 'state_db_row_id', '_active_turn_token', '_active_turn_user', '_fork_child_turn']);
|
|
1909
2144
|
export function copyJson(value) {
|
|
1910
2145
|
if (Array.isArray(value))
|
|
1911
2146
|
return value.map((v) => copyJson(v));
|
|
@@ -2016,25 +2251,68 @@ export function buildActiveTurnToken(streamId, pendingStartedAt) {
|
|
|
2016
2251
|
const COLLAPSIBLE_USER_MESSAGE_LINES = 20;
|
|
2017
2252
|
const COLLAPSIBLE_USER_MESSAGE_CHARS = 2000;
|
|
2018
2253
|
/**
|
|
2019
|
-
* Whether a public (redacted) row is a typed user message (no steer, wakeup or
|
|
2254
|
+
* Whether a public (redacted) row is a typed user message (no steer, wakeup, marker or delivery) longer than either limit, measured
|
|
2020
2255
|
* without the `[Attached files: ...]` line clients hide.
|
|
2021
2256
|
*/
|
|
2022
2257
|
function isCollapsibleUserMessage(item) {
|
|
2023
|
-
if (item.role !== 'user' || item._steer !== undefined || item._background_update !== undefined || item._marker_kind !== undefined)
|
|
2258
|
+
if (item.role !== 'user' || item._steer !== undefined || item._background_update !== undefined || item._marker_kind !== undefined || item._delivery !== undefined)
|
|
2024
2259
|
return false;
|
|
2025
2260
|
const text = stripAttachedFilesMarker(messageText(item.content));
|
|
2026
2261
|
return text.length > COLLAPSIBLE_USER_MESSAGE_CHARS || text.split('\n').length > COLLAPSIBLE_USER_MESSAGE_LINES;
|
|
2027
2262
|
}
|
|
2263
|
+
/**
|
|
2264
|
+
* TAL-600: how clients show a public row. A tool result or consumed steer shows only inside its turn's activity scene
|
|
2265
|
+
* (`in_scene`); a silent background reply, or a row with nothing to show, not at all (`hidden`); every other row on its own.
|
|
2266
|
+
*/
|
|
2267
|
+
function messageDisplay(item) {
|
|
2268
|
+
if (item.role === 'tool' || item._steer)
|
|
2269
|
+
return 'in_scene';
|
|
2270
|
+
if (!item.role || item._background_silent || item.display_kind === 'hidden')
|
|
2271
|
+
return 'hidden';
|
|
2272
|
+
if (item._marker_kind)
|
|
2273
|
+
return 'row';
|
|
2274
|
+
const shown = Boolean(messageText(item.content).trim()) || (Array.isArray(item.attachments) && item.attachments.length > 0) || (item.role === 'user' && hasNativeImages([item]));
|
|
2275
|
+
if (item.role !== 'assistant')
|
|
2276
|
+
return shown ? 'row' : 'hidden';
|
|
2277
|
+
const hasTools = Array.isArray(item.tool_calls) && item.tool_calls.length > 0;
|
|
2278
|
+
return shown || hasTools || Boolean(item.reasoning || item._anchor_activity_scene) ? 'row' : 'hidden';
|
|
2279
|
+
}
|
|
2280
|
+
/**
|
|
2281
|
+
* One user `content[*]` part (Python `_redact_message_content_part`): an `image_url.url` raster data URI passes through
|
|
2282
|
+
* unscanned (TAL-583). The exemption exists only at this schema position; image-shaped values elsewhere are redacted.
|
|
2283
|
+
*/
|
|
2284
|
+
function redactUserContentPart(part, enabled) {
|
|
2285
|
+
if (!enabled || !part || typeof part !== 'object' || Array.isArray(part))
|
|
2286
|
+
return redactValue(part, enabled);
|
|
2287
|
+
const p = part;
|
|
2288
|
+
const image = p.image_url;
|
|
2289
|
+
if (p.type !== 'image_url' || !image || typeof image !== 'object' || Array.isArray(image))
|
|
2290
|
+
return redactValue(part, enabled);
|
|
2291
|
+
const url = image.url;
|
|
2292
|
+
if (!isRasterDataUri(url))
|
|
2293
|
+
return redactValue(part, enabled);
|
|
2294
|
+
const rest = Object.fromEntries(Object.entries(image).filter(([k]) => k !== 'url'));
|
|
2295
|
+
const redacted = redactValue({ ...p, image_url: rest }, enabled);
|
|
2296
|
+
redacted.image_url = { ...redacted.image_url, url };
|
|
2297
|
+
return redacted;
|
|
2298
|
+
}
|
|
2028
2299
|
function publicMessageProjection(message, enabled, activeTurnToken) {
|
|
2029
2300
|
const isActive = Boolean(message && typeof message === 'object' && message.role === 'user' && activeTurnToken !== null && message._active_turn_token === activeTurnToken);
|
|
2030
|
-
|
|
2301
|
+
// Exports and nested public documents bypass scene hydration; project their user content at this boundary too.
|
|
2302
|
+
const scrubbed = normalizeUserDisplay(scrubInternalReplayFields([message], { messageRecords: true })[0]);
|
|
2031
2303
|
if (!scrubbed || typeof scrubbed !== 'object' || Array.isArray(scrubbed))
|
|
2032
2304
|
return redactValue(scrubbed, enabled);
|
|
2033
2305
|
const item = {};
|
|
2034
2306
|
for (const [key, value] of Object.entries(scrubbed)) {
|
|
2035
2307
|
if (PUBLIC_MESSAGE_INTERNAL_FIELDS.has(key))
|
|
2036
2308
|
continue;
|
|
2037
|
-
|
|
2309
|
+
// TAL-909: a tool row's metadata carries the whole edit diff, which ships capped and redacted as its call's `edit_diff`.
|
|
2310
|
+
if (key === 'display_metadata' && scrubbed.role === 'tool')
|
|
2311
|
+
continue;
|
|
2312
|
+
const userParts = key === 'content' && Array.isArray(value) && scrubbed.role === 'user';
|
|
2313
|
+
// Preserve the string/parts/null contract and redact JSON credential fields with their key context intact.
|
|
2314
|
+
const publicValue = key === 'content' && value != null && typeof value !== 'string' && !Array.isArray(value) ? JSON.stringify(value) : value;
|
|
2315
|
+
item[key] = userParts ? value.map((part) => redactUserContentPart(part, enabled)) : redactValue(publicValue, enabled);
|
|
2038
2316
|
}
|
|
2039
2317
|
if (isActive)
|
|
2040
2318
|
item._active_turn_user = true;
|
|
@@ -2043,6 +2321,24 @@ function publicMessageProjection(message, enabled, activeTurnToken) {
|
|
|
2043
2321
|
item._collapsible = true;
|
|
2044
2322
|
else
|
|
2045
2323
|
delete item._collapsible;
|
|
2324
|
+
item._display = messageDisplay(item);
|
|
2325
|
+
// TAL-598: stored and Agent rows may carry these as numeric strings or mixed arrays; ship the contract types or nothing.
|
|
2326
|
+
for (const key of ['_ts', '_turnDuration', '_turnTps']) {
|
|
2327
|
+
if (!(key in item))
|
|
2328
|
+
continue;
|
|
2329
|
+
const n = typeof item[key] === 'string' && item[key] !== '' ? Number(item[key]) : item[key];
|
|
2330
|
+
if (typeof n === 'number' && Number.isFinite(n))
|
|
2331
|
+
item[key] = n;
|
|
2332
|
+
else
|
|
2333
|
+
Reflect.deleteProperty(item, key);
|
|
2334
|
+
}
|
|
2335
|
+
if ('reasoning_titles' in item) {
|
|
2336
|
+
const titles = Array.isArray(item.reasoning_titles) ? item.reasoning_titles.filter((t) => typeof t === 'string' && Boolean(t.trim())) : [];
|
|
2337
|
+
if (titles.length)
|
|
2338
|
+
item.reasoning_titles = titles;
|
|
2339
|
+
else
|
|
2340
|
+
delete item.reasoning_titles;
|
|
2341
|
+
}
|
|
2046
2342
|
return withMessageToolDisplay(scrubbed, item, enabled);
|
|
2047
2343
|
}
|
|
2048
2344
|
/**
|