@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/workspace/git.js
CHANGED
|
@@ -7,12 +7,13 @@
|
|
|
7
7
|
* against repo-local config, and bounded by a timeout.
|
|
8
8
|
*/
|
|
9
9
|
import { execFile } from 'node:child_process';
|
|
10
|
-
import { closeSync, existsSync, fstatSync, lstatSync, mkdtempSync, mkdirSync, readFileSync, realpathSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
11
|
-
import { tmpdir } from 'node:os';
|
|
10
|
+
import { closeSync, constants as fsConstants, existsSync, fstatSync, futimesSync, lstatSync, mkdtempSync, mkdirSync, openSync, readdirSync, readFileSync, readSync, realpathSync, rmSync, rmdirSync, statSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
11
|
+
import { homedir, tmpdir } from 'node:os';
|
|
12
12
|
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
13
|
-
import { isWithin, resolvePathLikePython } from './paths.js';
|
|
13
|
+
import { expandHome, isWithin, resolvePathLikePython } from './paths.js';
|
|
14
14
|
import { openAnchoredFd, rmtreeAnchored, safeResolveWs, unlinkAnchored } from './fs.js';
|
|
15
15
|
import { str } from '../util.js';
|
|
16
|
+
import { diffHunks, hunkTotals } from '../text/diff.js';
|
|
16
17
|
export const GIT_TIMEOUT_MS = 5_000;
|
|
17
18
|
export const GIT_REMOTE_TIMEOUT_MS = 60_000;
|
|
18
19
|
export const STATUS_FILE_LIMIT = 500;
|
|
@@ -22,8 +23,9 @@ export const DIFF_SIZE_LIMIT = 512 * 1024;
|
|
|
22
23
|
export const COMMIT_MESSAGE_DIFF_LIMIT = 64 * 1024;
|
|
23
24
|
export const WORKSPACE_GIT_DESTRUCTIVE_ENV = 'HERMES_WEBUI_WORKSPACE_GIT_DESTRUCTIVE';
|
|
24
25
|
export const WORKSPACE_BUSY_MESSAGE = 'A Git operation is running in this workspace.';
|
|
26
|
+
const ACTIVE_RUN_MESSAGE = 'A session run is active. Wait for it to finish before running this Git operation.';
|
|
25
27
|
export const WORKSPACE_WRITE_BUSY_MESSAGE = 'A file operation is running in this workspace.';
|
|
26
|
-
const GIT_ENV_SCRUB_KEYS = ['GIT_DIR', 'GIT_WORK_TREE', 'GIT_CONFIG_GLOBAL', 'GIT_CONFIG_SYSTEM', 'GIT_CONFIG_COUNT', 'GIT_CONFIG_PARAMETERS', 'GIT_ASKPASS', 'SSH_ASKPASS', 'GIT_SSH', 'GIT_SSH_COMMAND'];
|
|
28
|
+
const GIT_ENV_SCRUB_KEYS = ['GIT_DIR', 'GIT_WORK_TREE', 'GIT_COMMON_DIR', 'GIT_CONFIG', 'GIT_CONFIG_GLOBAL', 'GIT_CONFIG_SYSTEM', 'GIT_CONFIG_COUNT', 'GIT_CONFIG_PARAMETERS', 'GIT_ASKPASS', 'SSH_ASKPASS', 'GIT_SSH', 'GIT_SSH_COMMAND', 'GIT_GLOB_PATHSPECS', 'GIT_NOGLOB_PATHSPECS', 'GIT_ICASE_PATHSPECS'];
|
|
27
29
|
const GIT_ENV_SCRUB_PREFIXES = ['GIT_CONFIG_KEY_', 'GIT_CONFIG_VALUE_'];
|
|
28
30
|
const BRANCH_SWITCH_STASH_PREFIX = 'hermes-webui branch switch';
|
|
29
31
|
const GIT_HARDENED_CONFIG = [
|
|
@@ -45,14 +47,43 @@ const GIT_DESTRUCTIVE_HARDENED_CONFIG = [
|
|
|
45
47
|
['core.alternateRefsCommand', ''],
|
|
46
48
|
];
|
|
47
49
|
const CONFLICT_CODES = new Set(['DD', 'AU', 'UD', 'UA', 'DU', 'AA', 'UU']);
|
|
50
|
+
const STATUS_CONFIG_KEYS = /^(core\.(autocrlf|eol|filemode|ignorecase|symlinks|ignorestat|checkstat|trustctime|protecthfs|protectntfs|precomposeunicode|excludesfile|attributesfile|quotepath)|(?:diff|status)\.(renames|renamelimit))$/;
|
|
48
51
|
export class GitWorkspaceError extends Error {
|
|
49
52
|
code;
|
|
50
|
-
constructor(message, code = 'git_failed') {
|
|
51
|
-
super(message);
|
|
53
|
+
constructor(message, code = 'git_failed', options) {
|
|
54
|
+
super(message, options);
|
|
52
55
|
this.code = code;
|
|
53
56
|
this.name = 'GitWorkspaceError';
|
|
54
57
|
}
|
|
55
58
|
}
|
|
59
|
+
function gitDeadline(timeoutMs) {
|
|
60
|
+
const deadline = Date.now() + timeoutMs;
|
|
61
|
+
return () => {
|
|
62
|
+
const ms = deadline - Date.now();
|
|
63
|
+
if (ms <= 0)
|
|
64
|
+
throw new GitWorkspaceError('Git command timed out', 'timeout', { cause: Object.assign(new Error('git timed out'), { code: 'ETIMEDOUT' }) });
|
|
65
|
+
return ms;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** Python `git_info_for_workspace`: the branch badge for a status, null outside a repo. */
|
|
69
|
+
export function gitBadge(status) {
|
|
70
|
+
if (!status.is_git)
|
|
71
|
+
return null;
|
|
72
|
+
const totals = status.totals ?? { changed: 0, staged: 0, unstaged: 0, untracked: 0, conflicts: 0 };
|
|
73
|
+
return { branch: status.branch ?? 'HEAD', dirty: totals.changed, modified: totals.staged + totals.unstaged, untracked: totals.untracked, ahead: status.ahead ?? 0, behind: status.behind ?? 0, is_git: true };
|
|
74
|
+
}
|
|
75
|
+
/** Porcelain v1 records retain their second NUL field for a rename/copy's source path. */
|
|
76
|
+
export function porcelainStatusEntries(output) {
|
|
77
|
+
const fields = output.split('\0');
|
|
78
|
+
const entries = [];
|
|
79
|
+
for (let i = 0; i < fields.length; i++) {
|
|
80
|
+
const record = fields[i];
|
|
81
|
+
if (!record)
|
|
82
|
+
continue;
|
|
83
|
+
entries.push(/[RC]/.test(record.slice(0, 2)) ? [record, fields[++i] ?? ''] : [record]);
|
|
84
|
+
}
|
|
85
|
+
return entries;
|
|
86
|
+
}
|
|
56
87
|
/**
|
|
57
88
|
* Run `git` without blocking the event loop, resolving like `spawnSync`: the exit status (null when a signal ended it),
|
|
58
89
|
* plus the `error` that prevented a normal run (`ETIMEDOUT` when the timeout killed it). Without `env` the child
|
|
@@ -121,7 +152,7 @@ export function classifyGitError(message, args = []) {
|
|
|
121
152
|
return 'timeout';
|
|
122
153
|
if (text.includes('not installed') || text.includes("no such file or directory: 'git'"))
|
|
123
154
|
return 'missing_git';
|
|
124
|
-
if (text.includes('not a git repository'))
|
|
155
|
+
if (text.includes('not a git repository') || text.includes('can only be used inside a git repository'))
|
|
125
156
|
return 'not_a_repo';
|
|
126
157
|
if (text.includes('outside the workspace') || text.includes('outside the git repository'))
|
|
127
158
|
return 'path_outside_workspace';
|
|
@@ -150,18 +181,11 @@ function unifiedDiffFromEmpty(lines, toFile) {
|
|
|
150
181
|
// `difflib` writes `+1` for a single-line range and `+1,N` otherwise.
|
|
151
182
|
return [`--- /dev/null`, `+++ ${toFile}`, `@@ -0,0 +${lines.length === 1 ? '1' : `1,${String(lines.length)}`} @@`, ...lines.map((l) => `+${l}`)];
|
|
152
183
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
continue;
|
|
159
|
-
if (line.startsWith('+'))
|
|
160
|
-
additions += 1;
|
|
161
|
-
else if (line.startsWith('-'))
|
|
162
|
-
deletions += 1;
|
|
163
|
-
}
|
|
164
|
-
return [additions, deletions];
|
|
184
|
+
/** A diff's counts and its parsed hunks (TAL-604): a too-large diff's cut text still counts, but ships no hunks. */
|
|
185
|
+
function diffFields(diff, shown) {
|
|
186
|
+
const hunks = diffHunks(diff);
|
|
187
|
+
const [additions, deletions] = hunkTotals(hunks);
|
|
188
|
+
return { additions, deletions, hunks: shown ? hunks : [] };
|
|
165
189
|
}
|
|
166
190
|
function splitLines(text) {
|
|
167
191
|
// Python `str.splitlines()`: no trailing empty element for a final newline.
|
|
@@ -193,6 +217,17 @@ export class GitRunner {
|
|
|
193
217
|
workspaceBusy(path) {
|
|
194
218
|
return overlapsAny(this.busy, path);
|
|
195
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* A checkpoint diff or restore at `path` (TAL-913): refused while Git holds it or a run is active there, since the
|
|
222
|
+
* Agent's per-turn checkpoint capture stages into the same store index, and held busy so no run starts meanwhile.
|
|
223
|
+
*/
|
|
224
|
+
holdCheckpoint(path, fn) {
|
|
225
|
+
if (this.workspaceBusy(path))
|
|
226
|
+
throw new GitWorkspaceError(WORKSPACE_BUSY_MESSAGE, 'operation_in_progress');
|
|
227
|
+
if (this.deps.activeRunIn?.(path))
|
|
228
|
+
throw new GitWorkspaceError(ACTIVE_RUN_MESSAGE, 'active_stream');
|
|
229
|
+
return this.holdWorkspace(path, fn);
|
|
230
|
+
}
|
|
196
231
|
/** Run an asynchronous workspace writer at `path`: refused while Git holds it, and Git mutations refuse meanwhile. */
|
|
197
232
|
holdWrite(path, fn) {
|
|
198
233
|
if (this.workspaceBusy(path))
|
|
@@ -222,6 +257,8 @@ export class GitRunner {
|
|
|
222
257
|
if (GIT_ENV_SCRUB_PREFIXES.some((p) => key.startsWith(p)))
|
|
223
258
|
Reflect.deleteProperty(env, key);
|
|
224
259
|
env.GIT_TERMINAL_PROMPT = '0';
|
|
260
|
+
// Every pathspec here is a resolved file path; a glob reading would let `a\b.txt` also match `ab.txt`.
|
|
261
|
+
env.GIT_LITERAL_PATHSPECS = '1';
|
|
225
262
|
return env;
|
|
226
263
|
}
|
|
227
264
|
now() {
|
|
@@ -235,7 +272,7 @@ export class GitRunner {
|
|
|
235
272
|
if (ignoreUnsupported)
|
|
236
273
|
return names;
|
|
237
274
|
const message = (result.stderr || result.stdout || 'Git command failed').trim();
|
|
238
|
-
throw new GitWorkspaceError(message, classifyGitError(message, ['config']));
|
|
275
|
+
throw new GitWorkspaceError(message, classifyGitError(message, ['config']), { cause: result.error });
|
|
239
276
|
}
|
|
240
277
|
for (const line of (result.stdout || '').split('\n')) {
|
|
241
278
|
const m = nameRe.exec(line.trim());
|
|
@@ -265,9 +302,267 @@ export class GitRunner {
|
|
|
265
302
|
async hasRepoLocalFilters(cwd) {
|
|
266
303
|
return (await this.filterNames(cwd, this.cleanEnv())).size > 0;
|
|
267
304
|
}
|
|
305
|
+
/** Hold the opened inode and reject devices/FIFOs before reading repository-controlled metadata. */
|
|
306
|
+
static withStatusFile(path, read) {
|
|
307
|
+
let fd;
|
|
308
|
+
try {
|
|
309
|
+
fd = openSync(path, fsConstants.O_RDONLY | (fsConstants.O_NONBLOCK ?? 0));
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
if (error.code === 'ENOENT')
|
|
313
|
+
return null;
|
|
314
|
+
throw error;
|
|
315
|
+
}
|
|
316
|
+
try {
|
|
317
|
+
const stat = fstatSync(fd, { bigint: true });
|
|
318
|
+
if (!stat.isFile())
|
|
319
|
+
throw new GitWorkspaceError('Git status metadata must be a regular file', 'git_failed');
|
|
320
|
+
return read(fd, Number(stat.size), stat.mtimeNs);
|
|
321
|
+
}
|
|
322
|
+
finally {
|
|
323
|
+
closeSync(fd);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
/** A private metadata view never loads executable repository/global configuration, even if the originals change. */
|
|
327
|
+
async withStatusRepository(cwd, remaining, read) {
|
|
328
|
+
const location = await this.run(cwd, ['rev-parse', '--absolute-git-dir', '--verify', 'HEAD'], { timeoutMs: remaining() });
|
|
329
|
+
const output = location.stdout.replace(/\r?\n$/, '');
|
|
330
|
+
const split = output.lastIndexOf('\n');
|
|
331
|
+
const gitDir = location.status === 0 ? output.slice(0, split).replace(/\r$/, '') : output;
|
|
332
|
+
const head = location.status === 0 ? output.slice(split + 1) : 'ref: refs/heads/status-probe';
|
|
333
|
+
if (!gitDir || (location.status !== 0 && location.status !== 128) || (location.status === 0 && !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(head))) {
|
|
334
|
+
const message = (location.stderr || 'Git repository metadata could not be read').trim();
|
|
335
|
+
throw new GitWorkspaceError(message, classifyGitError(message, ['rev-parse']));
|
|
336
|
+
}
|
|
337
|
+
let common = gitDir;
|
|
338
|
+
const commonPath = GitRunner.withStatusFile(join(gitDir, 'commondir'), (fd, size) => {
|
|
339
|
+
if (size > DIFF_SIZE_LIMIT)
|
|
340
|
+
throw new GitWorkspaceError('Git common directory path is too large', 'git_failed');
|
|
341
|
+
const bytes = Buffer.alloc(DIFF_SIZE_LIMIT + 1);
|
|
342
|
+
let offset = 0;
|
|
343
|
+
while (offset < bytes.length) {
|
|
344
|
+
remaining();
|
|
345
|
+
const count = readSync(fd, bytes, offset, bytes.length - offset, null);
|
|
346
|
+
if (!count)
|
|
347
|
+
break;
|
|
348
|
+
offset += count;
|
|
349
|
+
}
|
|
350
|
+
if (offset > DIFF_SIZE_LIMIT)
|
|
351
|
+
throw new GitWorkspaceError('Git common directory path is too large', 'git_failed');
|
|
352
|
+
return bytes.subarray(0, offset).toString('utf8');
|
|
353
|
+
});
|
|
354
|
+
if (commonPath !== null)
|
|
355
|
+
common = resolve(gitDir, commonPath.replace(/\r?\n$/, ''));
|
|
356
|
+
const config = await this.run(cwd, ['-c', `include.path=${join(cwd, '.gitmodules')}`, 'config', '--includes', '--null', '--list', '--show-scope'], { check: true, timeoutMs: remaining() });
|
|
357
|
+
const values = new Map();
|
|
358
|
+
const modules = new Map();
|
|
359
|
+
const entries = config.stdout.split('\0');
|
|
360
|
+
for (let i = 0; i + 1 < entries.length; i += 2) {
|
|
361
|
+
const scope = entries[i];
|
|
362
|
+
const entry = entries[i + 1] ?? '';
|
|
363
|
+
const split = entry.indexOf('\n');
|
|
364
|
+
if (split < 0)
|
|
365
|
+
continue;
|
|
366
|
+
const key = entry.slice(0, split);
|
|
367
|
+
if (scope === 'command') {
|
|
368
|
+
if (/^submodule\..+\.(path|ignore)$/.test(key))
|
|
369
|
+
modules.set(key, entry.slice(split + 1));
|
|
370
|
+
}
|
|
371
|
+
else
|
|
372
|
+
values.set(key, entry.slice(split + 1));
|
|
373
|
+
}
|
|
374
|
+
const ignores = new Map();
|
|
375
|
+
for (const [key, path] of modules) {
|
|
376
|
+
if (!key.endsWith('.path'))
|
|
377
|
+
continue;
|
|
378
|
+
const ignore = values.get(`${key.slice(0, -5)}.ignore`) ?? modules.get(`${key.slice(0, -5)}.ignore`) ?? values.get('diff.ignoresubmodules') ?? 'none';
|
|
379
|
+
if (!['none', 'untracked', 'dirty', 'all'].includes(ignore))
|
|
380
|
+
throw new GitWorkspaceError('Invalid submodule ignore setting', 'git_failed');
|
|
381
|
+
ignores.set(path, ignore);
|
|
382
|
+
}
|
|
383
|
+
const root = mkdtempSync(join(tmpdir(), 'talaria-git-status-'));
|
|
384
|
+
try {
|
|
385
|
+
const objectFormat = values.get('extensions.objectformat') ?? 'sha1';
|
|
386
|
+
if (!['sha1', 'sha256'].includes(objectFormat))
|
|
387
|
+
throw new GitWorkspaceError('Unsupported Git repository format', 'git_failed');
|
|
388
|
+
mkdirSync(join(root, 'info'));
|
|
389
|
+
mkdirSync(join(root, 'refs'));
|
|
390
|
+
writeFileSync(join(root, 'config'), `[core]\nrepositoryFormatVersion = ${objectFormat === 'sha256' ? '1' : '0'}\nbare = false\n${objectFormat === 'sha256' ? '[extensions]\nobjectFormat = sha256\n' : ''}`);
|
|
391
|
+
writeFileSync(join(root, 'HEAD'), `${head}\n`);
|
|
392
|
+
const copy = (directory, file) => {
|
|
393
|
+
GitRunner.withStatusFile(join(directory, file), (source, _size, mtimeNs) => {
|
|
394
|
+
const target = openSync(join(root, file), 'wx', 0o600);
|
|
395
|
+
try {
|
|
396
|
+
const chunk = Buffer.allocUnsafe(64 * 1024);
|
|
397
|
+
for (;;) {
|
|
398
|
+
remaining();
|
|
399
|
+
const bytes = readSync(source, chunk, 0, chunk.length, null);
|
|
400
|
+
if (!bytes)
|
|
401
|
+
break;
|
|
402
|
+
writeFileSync(target, chunk.subarray(0, bytes));
|
|
403
|
+
}
|
|
404
|
+
if (file === 'index' || file.startsWith('sharedindex.')) {
|
|
405
|
+
// A newer index timestamp would suppress Git's racy-stat content check; round conservatively earlier.
|
|
406
|
+
let margin = 1;
|
|
407
|
+
do {
|
|
408
|
+
remaining();
|
|
409
|
+
const stamp = new Date(Number(mtimeNs / 1000000n) - margin);
|
|
410
|
+
futimesSync(target, stamp, stamp);
|
|
411
|
+
margin *= 2;
|
|
412
|
+
} while (fstatSync(target, { bigint: true }).mtimeNs > mtimeNs);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
finally {
|
|
416
|
+
closeSync(target);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
};
|
|
420
|
+
for (const file of ['index', ...readdirSync(gitDir).filter((name) => /^sharedindex\.[a-f0-9]+$/.test(name))]) {
|
|
421
|
+
copy(gitDir, file);
|
|
422
|
+
}
|
|
423
|
+
for (const file of ['packed-refs', 'shallow', 'info/attributes', 'info/exclude', 'info/sparse-checkout']) {
|
|
424
|
+
copy(common, file);
|
|
425
|
+
}
|
|
426
|
+
symlinkSync(join(common, 'objects'), join(root, 'objects'), process.platform === 'win32' ? 'junction' : 'dir');
|
|
427
|
+
const originalEnv = this.cleanEnv();
|
|
428
|
+
const home = originalEnv.HOME || homedir();
|
|
429
|
+
const xdg = originalEnv.XDG_CONFIG_HOME || join(home, '.config');
|
|
430
|
+
if (!values.has('core.attributesfile'))
|
|
431
|
+
values.set('core.attributesfile', join(xdg, 'git', 'attributes'));
|
|
432
|
+
if (!values.has('core.excludesfile'))
|
|
433
|
+
values.set('core.excludesfile', join(xdg, 'git', 'ignore'));
|
|
434
|
+
const prefix = [`--git-dir=${root}`, `--work-tree=${cwd}`];
|
|
435
|
+
for (const [key, raw] of values) {
|
|
436
|
+
if (!STATUS_CONFIG_KEYS.test(key))
|
|
437
|
+
continue;
|
|
438
|
+
const value = key === 'core.attributesfile' || key === 'core.excludesfile' ? resolve(cwd, expandHome(raw, home)) : raw;
|
|
439
|
+
prefix.push('-c', `${key}=${value}`);
|
|
440
|
+
}
|
|
441
|
+
return await read(prefix, { HOME: root, XDG_CONFIG_HOME: root, GIT_CONFIG_NOSYSTEM: '1', GIT_OPTIONAL_LOCKS: '0', GIT_INDEX_FILE: join(root, 'index'), GIT_OBJECT_DIRECTORY: join(root, 'objects'), GIT_ALTERNATE_OBJECT_DIRECTORIES: '' }, ignores, { gitDir, commonDir: common, privateDir: root, refStorage: values.get('extensions.refstorage') ?? 'files' });
|
|
442
|
+
}
|
|
443
|
+
finally {
|
|
444
|
+
rmSync(root, { recursive: true, force: true });
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
/** Worktree lifecycle probes need only porcelain v1; child worktrees are inspected through the same private view. */
|
|
448
|
+
async worktreeStatus(cwd, timeoutMs = GIT_TIMEOUT_MS) {
|
|
449
|
+
const remaining = gitDeadline(timeoutMs);
|
|
450
|
+
const visited = new Set();
|
|
451
|
+
const inspect = async (path) => {
|
|
452
|
+
visited.add(resolvePathLikePython(path));
|
|
453
|
+
return this.withStatusRepository(path, remaining, async (prefix, env, ignores) => {
|
|
454
|
+
const run = (args) => this.run(path, [...prefix, ...args], { check: true, timeoutMs: remaining(), env });
|
|
455
|
+
// Commit differences remain visible; Git must not run a child status against live submodule configuration.
|
|
456
|
+
const result = await run(['status', '--porcelain', '-z', '--untracked-files=normal', '--ignore-submodules=dirty']);
|
|
457
|
+
const index = await run(['ls-files', '--stage', '-z']);
|
|
458
|
+
const gitlinks = index.stdout.split('\0').filter((entry) => entry.startsWith('160000 '));
|
|
459
|
+
const records = porcelainStatusEntries(result.stdout);
|
|
460
|
+
for (let i = records.length - 1; i >= 0; i--) {
|
|
461
|
+
const record = records[i]?.[0] ?? '';
|
|
462
|
+
if (ignores.get(record.slice(3)) !== 'all' || record.startsWith('??'))
|
|
463
|
+
continue;
|
|
464
|
+
if (record.startsWith(' '))
|
|
465
|
+
records.splice(i, 1);
|
|
466
|
+
else {
|
|
467
|
+
const fields = records[i];
|
|
468
|
+
if (fields)
|
|
469
|
+
fields[0] = `${record[0]} ${record.slice(2)}`;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
result.stdout = records.length ? `${records.flat().join('\0')}\0` : '';
|
|
473
|
+
let trackedDirty = records.some(([record]) => !record?.startsWith('??'));
|
|
474
|
+
let untrackedDirty = records.some(([record]) => record?.startsWith('??'));
|
|
475
|
+
for (const entry of gitlinks) {
|
|
476
|
+
const match = /^160000 [a-f0-9]+ [0-3]\t(.+)$/s.exec(entry);
|
|
477
|
+
if (!match?.[1])
|
|
478
|
+
continue;
|
|
479
|
+
const ignore = ignores.get(match[1]) ?? 'none';
|
|
480
|
+
if (ignore === 'all' || ignore === 'dirty')
|
|
481
|
+
continue;
|
|
482
|
+
const child = safeResolveWs(path, match[1]);
|
|
483
|
+
if (visited.has(child) || !existsSync(join(child, '.git')))
|
|
484
|
+
continue;
|
|
485
|
+
const childStatus = await inspect(child);
|
|
486
|
+
const untracked = ignore !== 'untracked' && childStatus.untrackedDirty;
|
|
487
|
+
if (childStatus.trackedDirty || untracked)
|
|
488
|
+
result.stdout += ` M ${match[1]}\0`;
|
|
489
|
+
trackedDirty ||= childStatus.trackedDirty;
|
|
490
|
+
untrackedDirty ||= untracked;
|
|
491
|
+
}
|
|
492
|
+
return { ...result, hasGitlinks: gitlinks.length > 0, trackedDirty, untrackedDirty };
|
|
493
|
+
});
|
|
494
|
+
};
|
|
495
|
+
const { status, stdout, stderr, hasGitlinks } = await inspect(cwd);
|
|
496
|
+
return { status, stdout, stderr, hasGitlinks };
|
|
497
|
+
}
|
|
498
|
+
/** Keep Git's own final clean check, but make its inherited configuration private and non-executable. */
|
|
499
|
+
async removeWorktree(repoRoot, worktree, timeoutMs = GIT_TIMEOUT_MS) {
|
|
500
|
+
const remaining = gitDeadline(timeoutMs);
|
|
501
|
+
const target = resolvePathLikePython(worktree);
|
|
502
|
+
const listed = await this.run(repoRoot, ['worktree', 'list', '--porcelain', '-z'], { check: true, timeoutMs: remaining() });
|
|
503
|
+
const paths = listed.stdout.split('\0').filter((field) => field.startsWith('worktree ')).map((field) => resolvePathLikePython(field.slice(9)));
|
|
504
|
+
if (paths[0] === target || !paths.slice(1).includes(target))
|
|
505
|
+
throw new GitWorkspaceError('Not a registered linked worktree', 'git_failed');
|
|
506
|
+
const callerCommon = (await this.run(repoRoot, ['rev-parse', '--path-format=absolute', '--git-common-dir'], { check: true, timeoutMs: remaining() })).stdout.replace(/\r?\n$/, '');
|
|
507
|
+
const gitDir = (await this.run(target, ['rev-parse', '--absolute-git-dir'], { check: true, timeoutMs: remaining() })).stdout.replace(/\r?\n$/, '');
|
|
508
|
+
const registryRoot = join(callerCommon, 'worktrees');
|
|
509
|
+
if (dirname(resolvePathLikePython(gitDir)) !== resolvePathLikePython(registryRoot))
|
|
510
|
+
throw new GitWorkspaceError('Worktree Git directory does not belong to the repository', 'git_failed');
|
|
511
|
+
const lockPath = join(gitDir, 'index.lock');
|
|
512
|
+
let lock;
|
|
513
|
+
try {
|
|
514
|
+
lock = openSync(lockPath, 'wx', 0o600);
|
|
515
|
+
}
|
|
516
|
+
catch (error) {
|
|
517
|
+
if (error.code === 'EEXIST')
|
|
518
|
+
throw new GitWorkspaceError('The worktree index is locked by another Git operation', 'operation_in_progress');
|
|
519
|
+
throw error;
|
|
520
|
+
}
|
|
521
|
+
let identity;
|
|
522
|
+
try {
|
|
523
|
+
identity = fstatSync(lock);
|
|
524
|
+
return await this.withStatusRepository(target, remaining, async (prefix, env, _ignores, metadata) => {
|
|
525
|
+
if (metadata.gitDir !== gitDir || resolvePathLikePython(metadata.commonDir) !== resolvePathLikePython(callerCommon))
|
|
526
|
+
throw new GitWorkspaceError('Worktree metadata changed during removal', 'operation_in_progress');
|
|
527
|
+
const entries = await this.run(worktree, [...prefix, 'ls-files', '--stage', '-z'], { check: true, timeoutMs: remaining(), env });
|
|
528
|
+
// An uninitialized gitlink could become populated between Git's submodule guard and its internal status.
|
|
529
|
+
if (entries.stdout.split('\0').some((entry) => entry.startsWith('160000 ')))
|
|
530
|
+
return { status: 128, stdout: '', stderr: 'Worktrees containing submodules require force=true to remove' };
|
|
531
|
+
const linkType = process.platform === 'win32' ? 'junction' : 'dir';
|
|
532
|
+
rmdirSync(join(metadata.privateDir, 'refs'));
|
|
533
|
+
if (existsSync(join(metadata.commonDir, 'refs')))
|
|
534
|
+
symlinkSync(join(metadata.commonDir, 'refs'), join(metadata.privateDir, 'refs'), linkType);
|
|
535
|
+
else
|
|
536
|
+
mkdirSync(join(metadata.privateDir, 'refs'));
|
|
537
|
+
if (metadata.refStorage === 'reftable') {
|
|
538
|
+
writeFileSync(join(metadata.privateDir, 'config'), '\n[core]\nrepositoryFormatVersion = 1\n[extensions]\nrefStorage = reftable\n', { flag: 'a' });
|
|
539
|
+
symlinkSync(join(metadata.commonDir, 'reftable'), join(metadata.privateDir, 'reftable'), linkType);
|
|
540
|
+
}
|
|
541
|
+
else if (metadata.refStorage !== 'files')
|
|
542
|
+
throw new GitWorkspaceError('Unsupported Git reference format', 'git_failed');
|
|
543
|
+
const registry = join(metadata.privateDir, 'worktrees');
|
|
544
|
+
mkdirSync(registry);
|
|
545
|
+
symlinkSync(gitDir, join(registry, 'target'), linkType);
|
|
546
|
+
return this.run(repoRoot, [...prefix, 'worktree', 'remove', worktree], { timeoutMs: remaining(), env, commonDir: metadata.privateDir });
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
finally {
|
|
550
|
+
try {
|
|
551
|
+
const current = lstatSync(lockPath);
|
|
552
|
+
if (current.dev === identity?.dev && current.ino === identity.ino)
|
|
553
|
+
unlinkSync(lockPath);
|
|
554
|
+
}
|
|
555
|
+
catch { /* Git may already have removed its administrative directory */ }
|
|
556
|
+
finally {
|
|
557
|
+
closeSync(lock);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
268
561
|
async run(ctxOrCwd, args, opts = {}) {
|
|
269
562
|
const cwd = typeof ctxOrCwd === 'string' ? ctxOrCwd : ctxOrCwd.repoRoot;
|
|
270
563
|
const runEnv = this.cleanEnv(opts.env);
|
|
564
|
+
if (opts.commonDir)
|
|
565
|
+
runEnv.GIT_COMMON_DIR = opts.commonDir;
|
|
271
566
|
const effectiveDestructive = Boolean(opts.destructive) && this.destructiveEnabled();
|
|
272
567
|
const hardenedDestructive = effectiveDestructive || Boolean(opts.forceDestructiveHardening);
|
|
273
568
|
let attributesFile = null;
|
|
@@ -333,10 +628,10 @@ export class GitRunner {
|
|
|
333
628
|
if (result.error) {
|
|
334
629
|
const err = result.error;
|
|
335
630
|
if (err.code === 'ETIMEDOUT')
|
|
336
|
-
throw new GitWorkspaceError('Git command timed out', 'timeout');
|
|
631
|
+
throw new GitWorkspaceError('Git command timed out', 'timeout', { cause: err });
|
|
337
632
|
if (err.code === 'ENOENT')
|
|
338
|
-
throw new GitWorkspaceError('Git is not installed or not available on PATH', 'missing_git');
|
|
339
|
-
throw new GitWorkspaceError(err.message, classifyGitError(err.message, args));
|
|
633
|
+
throw new GitWorkspaceError('Git is not installed or not available on PATH', 'missing_git', { cause: err });
|
|
634
|
+
throw new GitWorkspaceError(err.message, classifyGitError(err.message, args), { cause: err });
|
|
340
635
|
}
|
|
341
636
|
const out = { status: result.status ?? 1, stdout: result.stdout, stderr: result.stderr };
|
|
342
637
|
if (opts.check && out.status !== 0) {
|
|
@@ -394,15 +689,15 @@ export class GitRunner {
|
|
|
394
689
|
const rel = relative(ctx.repoRoot, target).split(sep).join('/');
|
|
395
690
|
return rel || '.';
|
|
396
691
|
}
|
|
692
|
+
/** Git and `repoRel` both separate with `/`; a backslash is a literal POSIX filename character, never a separator. */
|
|
397
693
|
static workspaceRel(ctx, repoRel) {
|
|
398
|
-
const normalized = repoRel.replace(/\\/g, '/');
|
|
399
694
|
if (!ctx.workspacePrefix)
|
|
400
|
-
return
|
|
695
|
+
return repoRel;
|
|
401
696
|
const prefix = `${ctx.workspacePrefix.replace(/\/+$/, '')}/`;
|
|
402
|
-
if (
|
|
697
|
+
if (repoRel === ctx.workspacePrefix)
|
|
403
698
|
return '.';
|
|
404
|
-
if (
|
|
405
|
-
return
|
|
699
|
+
if (repoRel.startsWith(prefix))
|
|
700
|
+
return repoRel.slice(prefix.length);
|
|
406
701
|
return null;
|
|
407
702
|
}
|
|
408
703
|
// ── mutation lock ────────────────────────────────────────────────────────
|
|
@@ -420,7 +715,7 @@ export class GitRunner {
|
|
|
420
715
|
}
|
|
421
716
|
assertRepoFree(repoRoot) {
|
|
422
717
|
if (this.deps.activeRunIn?.(repoRoot))
|
|
423
|
-
throw new GitWorkspaceError(
|
|
718
|
+
throw new GitWorkspaceError(ACTIVE_RUN_MESSAGE, 'active_stream');
|
|
424
719
|
if (overlapsAny(this.writing, repoRoot))
|
|
425
720
|
throw new GitWorkspaceError(WORKSPACE_WRITE_BUSY_MESSAGE, 'operation_in_progress');
|
|
426
721
|
}
|
|
@@ -1021,18 +1316,17 @@ export class GitRunner {
|
|
|
1021
1316
|
if (!read)
|
|
1022
1317
|
throw new GitWorkspaceError('Path is not a file');
|
|
1023
1318
|
if ('tooLarge' in read)
|
|
1024
|
-
return { binary: false, too_large: true, diff: '', additions: 0, deletions: 0 };
|
|
1319
|
+
return { binary: false, too_large: true, diff: '', additions: 0, deletions: 0, hunks: [] };
|
|
1025
1320
|
const data = read.data;
|
|
1026
1321
|
const text = data.toString('utf8');
|
|
1027
1322
|
if (data.includes(0) || (text.includes('�') && !data.equals(Buffer.from(text, 'utf8'))))
|
|
1028
|
-
return { binary: true, too_large: false, diff: '', additions: 0, deletions: 0 };
|
|
1323
|
+
return { binary: true, too_large: false, diff: '', additions: 0, deletions: 0, hunks: [] };
|
|
1029
1324
|
const diffLines = unifiedDiffFromEmpty(splitLines(text), `b/${label}`);
|
|
1030
1325
|
let diff = diffLines.join('\n') + (diffLines.length ? '\n' : '');
|
|
1031
1326
|
const tooLarge = Buffer.byteLength(diff, 'utf8') > DIFF_SIZE_LIMIT;
|
|
1032
1327
|
if (tooLarge)
|
|
1033
1328
|
diff = diff.slice(0, DIFF_SIZE_LIMIT);
|
|
1034
|
-
|
|
1035
|
-
return { binary: false, too_large: tooLarge, diff, additions, deletions };
|
|
1329
|
+
return { binary: false, too_large: tooLarge, diff, ...diffFields(diff, !tooLarge) };
|
|
1036
1330
|
}
|
|
1037
1331
|
async diff(workspace, path, kind = 'unstaged') {
|
|
1038
1332
|
const ctx = await this.resolveContext(workspace);
|
|
@@ -1055,8 +1349,7 @@ export class GitRunner {
|
|
|
1055
1349
|
const tooLarge = Buffer.byteLength(diff, 'utf8') > DIFF_SIZE_LIMIT;
|
|
1056
1350
|
if (tooLarge)
|
|
1057
1351
|
diff = diff.slice(0, DIFF_SIZE_LIMIT);
|
|
1058
|
-
|
|
1059
|
-
return { path: workspaceRel, kind, binary, too_large: tooLarge, additions, deletions, diff: binary ? '' : diff };
|
|
1352
|
+
return { path: workspaceRel, kind, binary, too_large: tooLarge, ...diffFields(diff, !(binary || tooLarge)), diff: binary ? '' : diff };
|
|
1060
1353
|
}
|
|
1061
1354
|
// ── stage / unstage / discard ────────────────────────────────────────────
|
|
1062
1355
|
static cleanPaths(paths) {
|