@vantran-se/openchamber-web 2.0.3 → 2.0.5
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/README.md +20 -28
- package/bin/cli.js +3 -1
- package/bin/cli.test.js +13 -4
- package/bin/lib/DOCUMENTATION.md +4 -1
- package/bin/lib/commands-serve.js +9 -0
- package/dist/assets/{CodeMirrorCommentWidgets-CWhdh0wf.js → CodeMirrorCommentWidgets-DCAQTLMM.js} +1 -1
- package/dist/assets/DiffView-uzNpHBlV.js +4 -0
- package/dist/assets/FilesView-Bkq0sjNx.js +17 -0
- package/dist/assets/{GitView-DKIjpnu4.js → GitView-BmibZC7n.js} +4 -4
- package/dist/assets/{GuestAttachDialog-BIa9jCfL.js → GuestAttachDialog-D7TJG1rt.js} +1 -1
- package/dist/assets/GuestSurfacePane-PAcYaFzP.js +1 -0
- package/dist/assets/{JsonTreeView-CtI1Mqwo.js → JsonTreeView-BNT2yUVu.js} +1 -1
- package/dist/assets/{LinearIssuesView-BD2zLu-r.js → LinearIssuesView-D3Azksju.js} +1 -1
- package/dist/assets/MarkdownImageGallery-BGY6tuiK.js +1 -0
- package/dist/assets/MarkdownRendererImpl-DJmhQ37f.js +12 -0
- package/dist/assets/{OnboardingScreen-B8TxloXZ.js → OnboardingScreen-D_41H2qC.js} +1 -1
- package/dist/assets/{PatchDiff--Civs1xY.js → PatchDiff-C0RSqa9W.js} +1 -1
- package/dist/assets/{PierreDiffViewer-BlDmw3-A.js → PierreDiffViewer-BBE7tTY2.js} +3 -3
- package/dist/assets/{PlanView-DyH2SyCP.js → PlanView-Bqc-xuDe.js} +4 -4
- package/dist/assets/PluginPane-DQ0k41Q-.js +3 -0
- package/dist/assets/SettingsView-BAiJU5hJ.js +30 -0
- package/dist/assets/{SettingsWindow-y9WpZqK6.js → SettingsWindow-DuC4ecLw.js} +1 -1
- package/dist/assets/{SubmoduleDiffSummary-DeFmhPFZ.js → SubmoduleDiffSummary-0HgmcMXz.js} +1 -1
- package/dist/assets/{ToolOutputDialog-8DmF7_PZ.js → ToolOutputDialog-DdHkQJEE.js} +6 -6
- package/dist/assets/{ToolPartDiffPreview-Ca15DKE1.js → ToolPartDiffPreview-DWdN0r5K.js} +2 -2
- package/dist/assets/{VirtualizedFileDiff-BfEBad09.js → VirtualizedFileDiff-ClDezf2d.js} +1 -1
- package/dist/assets/{WalkthroughView-Cj3K8Xz6.js → WalkthroughView-BJicp0RC.js} +2 -2
- package/dist/assets/{appThemeRegistry-DAdawJZn.js → appThemeRegistry-CiuyzfSW.js} +1 -1
- package/dist/assets/changesTree-CePHbFcj.js +1 -0
- package/dist/assets/commitAndPush-DTKb6IwT.js +1 -0
- package/dist/assets/{computeVirtualFileMetrics-RF-KjfUH.js → computeVirtualFileMetrics-kM_zJNMt.js} +2 -2
- package/dist/assets/de-BMnfXm-G.js +10 -0
- package/dist/assets/es-DKEvCCL6.js +16 -0
- package/dist/assets/fr-D9fgE2xE.js +14 -0
- package/dist/assets/index-DUke1nme.css +1 -0
- package/dist/assets/{index-CL7ZQ94-.js → index-DWB8bR_g.js} +1 -1
- package/dist/assets/index-Di6zUe5h.js +41 -0
- package/dist/assets/{isDiffPlainText-D2yJ9fO6.js → isDiffPlainText-DOoIsGqs.js} +1 -1
- package/dist/assets/{isFilePlainText-BwMEq1Ey.js → isFilePlainText-bt5VHvcd.js} +1 -1
- package/dist/assets/ja-BEXad-KW.js +16 -0
- package/dist/assets/ko-DGrQ0lEe.js +16 -0
- package/dist/assets/{main-quLSA7jc.js → main-BpLQbZC2.js} +2 -2
- package/dist/assets/main-CI9DtHJv.js +896 -0
- package/dist/assets/{markdown-shiki.worker-CahLvHIq.js → markdown-shiki.worker-Bg8SoAJJ.js} +8 -5
- package/dist/assets/markdownCore-DK2KK5RW.js +7 -0
- package/dist/assets/{miniChat-D-lJJibr.js → miniChat-CIWaR8wG.js} +2 -2
- package/dist/assets/{mobile-VTtphbW6.js → mobile-CnWKEYIP.js} +2 -2
- package/dist/assets/patchFileDiff-Cqn0C0az.js +13 -0
- package/dist/assets/pl-BlhkmR5b.js +16 -0
- package/dist/assets/pt-BR-Bs96Ew9I.js +16 -0
- package/dist/assets/{renderElectronMiniChatApp-DF7ch5eM.js → renderElectronMiniChatApp-D9t0-9nV.js} +2 -2
- package/dist/assets/renderMobileApp-CW7fVs_s.js +25 -0
- package/dist/assets/runtimeEndpointReset-D0PcCb3K.js +27 -0
- package/dist/assets/scheduledTasksApi-Dahv3ws0.js +1 -0
- package/dist/assets/{shikiHighlight-_HeCCHx1.js → shikiHighlight-l-MbaNS4.js} +1 -1
- package/dist/assets/{textMateThemeFromAppTheme-C95XdFGj.js → textMateThemeFromAppTheme-C-kGcOpD.js} +1 -1
- package/dist/assets/tr-CehUK1M9.js +7 -0
- package/dist/assets/uk-Bno5WGNz.js +16 -0
- package/dist/assets/{useAppFontEffects-ZM9ij19-.js → useAppFontEffects-DDjuwVqi.js} +160 -156
- package/dist/assets/{useInlineCommentController-CkfxMJPy.js → useInlineCommentController-Clg8EO3A.js} +2 -2
- package/dist/assets/{useRootScrollLock-BtiAC1fj.js → useRootScrollLock-nDcRrgJ1.js} +2 -2
- package/dist/assets/{vendor-codemirror-language-data-U-lXzXNK.js → vendor-codemirror-language-data-oKF0MAwd.js} +2 -2
- package/dist/assets/vendor-opencode-client-DSZl7jSi.js +12 -0
- package/dist/assets/vendor-zod-BSoePkpP.js +39 -0
- package/dist/assets/{web-components-C583Pmfm.js → web-components-Bc1WPd4i.js} +1 -1
- package/dist/assets/zh-CN-DnAweIWo.js +16 -0
- package/dist/assets/zh-TW-BbBBK25p.js +16 -0
- package/dist/index.html +5 -5
- package/dist/mini-chat.html +5 -5
- package/dist/mobile.html +5 -5
- package/package.json +3 -3
- package/server/index.d.ts +2 -0
- package/server/index.js +196 -52
- package/server/lib/agent-tool/DOCUMENTATION.md +5 -0
- package/server/lib/agent-tool/runtime.js +89 -51
- package/server/lib/agent-tool/runtime.test.js +17 -0
- package/server/lib/browser-control/DOCUMENTATION.md +14 -2
- package/server/lib/event-stream/DOCUMENTATION.md +2 -2
- package/server/lib/event-stream/global-hub.js +45 -7
- package/server/lib/event-stream/global-hub.test.js +128 -2
- package/server/lib/event-stream/global-ws-bridge.js +3 -1
- package/server/lib/event-stream/rebind.test.js +1 -0
- package/server/lib/event-stream/runtime.js +1 -2
- package/server/lib/event-stream/upstream-reader.js +3 -2
- package/server/lib/git/DOCUMENTATION.md +1 -1
- package/server/lib/git/service.js +22 -0
- package/server/lib/git/service.test.js +8 -0
- package/server/lib/guests/DOCUMENTATION.md +4 -3
- package/server/lib/guests/catalog.js +19 -1
- package/server/lib/guests/catalog.test.js +22 -0
- package/server/lib/guests/html-styles.js +5 -3
- package/server/lib/guests/html-styles.test.js +3 -1
- package/server/lib/guests/routes.js +11 -3
- package/server/lib/guests/service.js +5 -0
- package/server/lib/guests/surface.js +55 -9
- package/server/lib/guests/surface.test.js +56 -6
- package/server/lib/notifications/DOCUMENTATION.md +10 -0
- package/server/lib/notifications/emit-route.js +118 -0
- package/server/lib/notifications/emit-route.test.js +112 -0
- package/server/lib/openchamber-control/actions.js +16 -2
- package/server/lib/openchamber-control/service.js +23 -0
- package/server/lib/openchamber-control/service.test.js +31 -0
- package/server/lib/openchamber-sessions/fork-inheritance.js +103 -0
- package/server/lib/openchamber-sessions/fork-inheritance.test.js +69 -0
- package/server/lib/openchamber-sessions/routes.js +11 -0
- package/server/lib/openchamber-sessions/routes.test.js +18 -0
- package/server/lib/opencode/DOCUMENTATION.md +23 -23
- package/server/lib/opencode/bootstrap-runtime.js +14 -1
- package/server/lib/opencode/compatibility.js +6 -3
- package/server/lib/opencode/compatibility.test.js +8 -0
- package/server/lib/opencode/config-entity-v2.test.js +27 -0
- package/server/lib/opencode/config-paths.test.js +12 -0
- package/server/lib/opencode/config-v2.d.ts +2 -0
- package/server/lib/opencode/config-v2.js +42 -0
- package/server/lib/opencode/config-v2.test.js +17 -0
- package/server/lib/opencode/core-routes.js +20 -4
- package/server/lib/opencode/core-routes.test.js +41 -0
- package/server/lib/opencode/env-runtime.js +1 -8
- package/server/lib/opencode/feature-routes-runtime.js +2 -1
- package/server/lib/opencode/lifecycle.js +156 -2
- package/server/lib/opencode/lifecycle.test.js +255 -1
- package/server/lib/opencode/managed-config-file.js +18 -6
- package/server/lib/opencode/managed-config-file.test.js +23 -7
- package/server/lib/opencode/mcp.js +7 -2
- package/server/lib/opencode/network-runtime.js +16 -7
- package/server/lib/opencode/network-runtime.test.js +29 -1
- package/server/lib/opencode/npm-registry-config.d.ts +1 -0
- package/server/lib/opencode/npm-registry-config.js +123 -0
- package/server/lib/opencode/npm-registry-config.test.js +167 -0
- package/server/lib/opencode/npm-registry.js +5 -6
- package/server/lib/opencode/npm-registry.test.js +30 -0
- package/server/lib/opencode/openchamber-routes.js +29 -11
- package/server/lib/opencode/openchamber-routes.test.js +18 -0
- package/server/lib/opencode/project-directory-runtime.js +8 -0
- package/server/lib/opencode/project-directory-runtime.test.js +13 -0
- package/server/lib/opencode/provider-source-route.test.js +59 -0
- package/server/lib/opencode/providers.js +3 -0
- package/server/lib/opencode/providers.test.js +62 -0
- package/server/lib/opencode/proxy.js +53 -16
- package/server/lib/opencode/routes-upgrade.test.js +1 -1
- package/server/lib/opencode/routes.js +36 -1
- package/server/lib/opencode/server-startup-runtime.js +25 -0
- package/server/lib/opencode/server-startup-runtime.test.js +67 -1
- package/server/lib/opencode/server-utils-runtime.js +5 -0
- package/server/lib/opencode/settings-helpers.js +10 -0
- package/server/lib/opencode/settings-helpers.test.js +2 -2
- package/server/lib/opencode/settings-registry.json +17 -0
- package/server/lib/opencode/settings-runtime.js +1 -0
- package/server/lib/opencode/shared-service-runtime.js +155 -0
- package/server/lib/opencode/shared-service-runtime.test.js +180 -0
- package/server/lib/opencode/shared.js +49 -4
- package/server/lib/opencode/shared.test.js +78 -1
- package/server/lib/opencode/shutdown-runtime.js +14 -5
- package/server/lib/opencode/shutdown-runtime.test.js +77 -2
- package/server/lib/opencode/skill-routes.js +28 -12
- package/server/lib/opencode/skill-routes.test.js +121 -1
- package/server/lib/opencode/startup-pipeline-runtime.js +5 -4
- package/server/lib/opencode/startup-pipeline-runtime.test.js +18 -7
- package/server/lib/opencode/upgrade-capability.js +0 -14
- package/server/lib/opencode/v1-migration-topup.js +21 -15
- package/server/lib/opencode/v1-migration-topup.test.js +14 -6
- package/server/lib/opencode/v2-install.d.ts +1 -0
- package/server/lib/opencode/v2-install.js +8 -7
- package/server/lib/opencode/v2-install.test.js +13 -4
- package/server/lib/opencode/watcher.js +3 -1
- package/server/lib/opencode/watcher.test.js +54 -0
- package/server/lib/opencode/websearch-config.js +13 -1
- package/server/lib/quota/providers/kimi.js +1 -1
- package/server/lib/realtime-proxy.js +5 -1
- package/server/lib/realtime-proxy.test.js +29 -0
- package/server/lib/relay/tunnel-host.js +4 -1
- package/server/lib/relay/tunnel-host.test.js +11 -0
- package/server/lib/session-assist/DOCUMENTATION.md +17 -5
- package/server/lib/session-assist/runtime.js +19 -2
- package/server/lib/session-assist/runtime.test.js +8 -0
- package/server/lib/session-goal/DOCUMENTATION.md +11 -0
- package/server/lib/small-model/DOCUMENTATION.md +11 -10
- package/server/lib/small-model/index.js +27 -32
- package/server/lib/small-model/index.test.js +28 -16
- package/server/lib/spaces/DOCUMENTATION.md +404 -32
- package/server/lib/spaces/code-in-bait.js +145 -6
- package/server/lib/spaces/code-in.js +10 -150
- package/server/lib/spaces/code-in.test.js +7 -83
- package/server/lib/spaces/code-out.js +1819 -0
- package/server/lib/spaces/code-out.test.js +3945 -0
- package/server/lib/spaces/code-transfer.js +173 -0
- package/server/lib/spaces/command-stream.test.js +181 -0
- package/server/lib/spaces/dispatcher.js +670 -0
- package/server/lib/spaces/dispatcher.test.js +582 -0
- package/server/lib/spaces/gatekeeper-channel.js +61 -7
- package/server/lib/spaces/gatekeeper-channel.test.js +43 -7
- package/server/lib/spaces/gatekeeper-program.cjs +68 -14
- package/server/lib/spaces/gatekeeper-program.test.js +118 -3
- package/server/lib/spaces/hardening.js +20 -4
- package/server/lib/spaces/hardening.test.js +18 -3
- package/server/lib/spaces/host-git.js +7 -4
- package/server/lib/spaces/host-git.test.js +6 -2
- package/server/lib/spaces/host.js +310 -0
- package/server/lib/spaces/host.test.js +273 -0
- package/server/lib/spaces/journey.js +552 -0
- package/server/lib/spaces/journey.test.js +589 -0
- package/server/lib/spaces/layout.js +42 -8
- package/server/lib/spaces/manager.js +4 -3
- package/server/lib/spaces/manager.test.js +6 -0
- package/server/lib/spaces/places/code-out.docker.live.test.js +412 -0
- package/server/lib/spaces/places/contract-suite.js +36 -0
- package/server/lib/spaces/places/dispatcher.docker.live.test.js +296 -0
- package/server/lib/spaces/places/docker-live-support.js +27 -4
- package/server/lib/spaces/places/docker.js +33 -5
- package/server/lib/spaces/places/docker.test.js +42 -3
- package/server/lib/spaces/places/escape-suite.js +118 -14
- package/server/lib/spaces/places/fake-docker.js +3 -1
- package/server/lib/spaces/places/grants.docker.live.test.js +197 -0
- package/server/lib/spaces/places/memory-place.js +24 -1
- package/server/lib/spaces/places/registry.js +1 -1
- package/server/lib/spaces/places/server.docker.live.test.js +69 -33
- package/server/lib/spaces/places/sessions.docker.live.test.js +222 -0
- package/server/lib/spaces/routes.js +216 -0
- package/server/lib/spaces/routes.test.js +213 -0
- package/server/lib/spaces/run-command.js +261 -8
- package/server/lib/spaces/run-command.test.js +193 -3
- package/server/lib/spaces/space-events.js +153 -0
- package/server/lib/spaces/space-events.test.js +160 -0
- package/server/lib/spaces/space-opencode.js +52 -0
- package/server/lib/spaces/space-opencode.test.js +41 -0
- package/server/lib/spaces/space-records.js +150 -0
- package/server/lib/spaces/space-records.test.js +113 -0
- package/server/lib/spaces/space-sessions.js +210 -0
- package/server/lib/spaces/space-sessions.test.js +161 -0
- package/server/lib/spaces/websocket.js +329 -0
- package/server/lib/spaces/websocket.test.js +345 -0
- package/server/lib/ui-auth/ui-auth.js +8 -2
- package/server/lib/ui-auth/ui-auth.test.js +29 -0
- package/server/opencode-proxy.test.js +271 -0
- package/server/proxy-headers.js +8 -2
- package/server/proxy-headers.test.js +20 -0
- package/dist/assets/DiffView-CX3wAX2S.js +0 -4
- package/dist/assets/FilesView-OL3CON3r.js +0 -17
- package/dist/assets/GuestSurfacePane-B_cqX5I5.js +0 -1
- package/dist/assets/MarkdownImageGallery-DFiTFZgj.js +0 -1
- package/dist/assets/MarkdownRendererImpl-DZm5sf1W.js +0 -12
- package/dist/assets/PluginPane-BibJit86.js +0 -3
- package/dist/assets/SettingsView-h-VpVO47.js +0 -29
- package/dist/assets/commitAndPush-BIPfOMXY.js +0 -1
- package/dist/assets/de-BqCNGROu.js +0 -10
- package/dist/assets/es-BTPpTRgN.js +0 -16
- package/dist/assets/fr-hxbzMdAg.js +0 -14
- package/dist/assets/index-CLcM8HKx.css +0 -1
- package/dist/assets/index-CvLgnuNI.js +0 -41
- package/dist/assets/ja-_zLwwYiy.js +0 -16
- package/dist/assets/ko-CFn3Dzhc.js +0 -16
- package/dist/assets/main-BLJaug9I.js +0 -896
- package/dist/assets/markdownCore-DS9FdwrI.js +0 -5
- package/dist/assets/patchFileDiff-D9iBcTEi.js +0 -13
- package/dist/assets/pl-DFHE7xac.js +0 -16
- package/dist/assets/pt-BR-CUjZF179.js +0 -16
- package/dist/assets/renderMobileApp-CNQhdXsi.js +0 -25
- package/dist/assets/runtimeEndpointReset-DeaERc0M.js +0 -27
- package/dist/assets/scheduledTasksApi-BD6Vx9pu.js +0 -1
- package/dist/assets/tr-BB6sA_zH.js +0 -7
- package/dist/assets/uk-CB4o8g-o.js +0 -16
- package/dist/assets/vendor-opencode-client-_BAHQo4R.js +0 -12
- package/dist/assets/vendor-zod-Gea9uBlY.js +0 -39
- package/dist/assets/zh-CN-BRyDuWhc.js +0 -16
- package/dist/assets/zh-TW-BDGbWA1Q.js +0 -16
package/README.md
CHANGED
|
@@ -18,6 +18,17 @@ Or install manually: `bun add -g @openchamber/web` (or npm, pnpm, yarn).
|
|
|
18
18
|
|
|
19
19
|
> **Prerequisites:** [OpenCode CLI](https://opencode.ai) installed, Node.js 22+.
|
|
20
20
|
|
|
21
|
+
Start OpenCode first, then OpenChamber in another terminal:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
opencode
|
|
25
|
+
openchamber
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Both clients use the same local OpenCode service, sessions, and live events. Normal local use does not require `opencode serve`, an OpenCode port, or skip-start configuration. Stopping OpenChamber Web leaves OpenCode, the TUI, and current work running.
|
|
29
|
+
|
|
30
|
+
Shared Web does not install OpenChamber managed tools. Those tools remain available in Electron Desktop's managed OpenCode child.
|
|
31
|
+
|
|
21
32
|
## Usage
|
|
22
33
|
|
|
23
34
|
```bash
|
|
@@ -41,20 +52,14 @@ openchamber connect-url --port 3000 # Add this server to OpenChamber Desktop
|
|
|
41
52
|
openchamber connect-url --server http://host:3000 --qr
|
|
42
53
|
openchamber connect-url --port 3000 --qr
|
|
43
54
|
openchamber logs # Follow latest instance logs
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
openchamber stop # Stop server
|
|
55
|
+
OPENCODE_HOST=https://myhost:4096 openchamber # Connect to an external OpenCode server
|
|
56
|
+
openchamber stop # Stop Web; OpenCode and the TUI keep running
|
|
47
57
|
openchamber update # Update to latest version
|
|
48
58
|
```
|
|
49
59
|
|
|
50
60
|
`startup enable` snapshots your current environment into the native service so startup behaves like you launched `openchamber` from the same shell. This preserves provider tokens, PATH, SSH agent settings, and other CLI auth/config env vars. Use `--no-env-snapshot` for a minimal service env.
|
|
51
61
|
|
|
52
|
-
|
|
53
|
-
`openchamber` agent tool for project, session, and scheduled-task orchestration.
|
|
54
|
-
The tool is not injected when connecting to an external OpenCode server.
|
|
55
|
-
Behavior settings can optionally inject a managed system-prompt optimizer on
|
|
56
|
-
the next OpenCode restart. It is disabled by default and is not available for
|
|
57
|
-
external OpenCode servers.
|
|
62
|
+
Electron Desktop keeps its managed OpenCode child and environment-backed OpenChamber tools. Ordinary Web does not install or advertise those tools. An external endpoint selected with `OPENCODE_HOST` may have user-configured tools, but OpenChamber does not install or guarantee them.
|
|
58
63
|
|
|
59
64
|
### Tunnel behavior notes
|
|
60
65
|
|
|
@@ -101,35 +106,23 @@ Generating a client token does not automatically password-protect the hosted bro
|
|
|
101
106
|
<summary>Connect to external OpenCode server</summary>
|
|
102
107
|
|
|
103
108
|
```bash
|
|
104
|
-
|
|
105
|
-
OPENCODE_HOST=https://myhost:4096 OPENCODE_SKIP_START=true openchamber
|
|
109
|
+
OPENCODE_HOST=https://myhost:4096 openchamber
|
|
106
110
|
```
|
|
107
111
|
|
|
112
|
+
`OPENCODE_HOST` overrides shared local discovery. Web treats that endpoint as externally owned: it connects API and event streams but never starts, stops, or restarts the endpoint. OpenChamber managed tools are not guaranteed there.
|
|
113
|
+
|
|
108
114
|
| Variable | Description |
|
|
109
115
|
|----------|-------------|
|
|
110
|
-
| `OPENCODE_HOST` | Full base URL of
|
|
111
|
-
| `
|
|
112
|
-
| `OPENCODE_SKIP_START` | Skip starting embedded OpenCode server |
|
|
113
|
-
| `OPENCHAMBER_OPENCODE_HOSTNAME` | Bind hostname for managed OpenCode server (default: `127.0.0.1`, use `0.0.0.0` for LAN/remote access — trusted networks only). Invalid values are rejected with an error and fall back to loopback |
|
|
114
|
-
| `OPENCHAMBER_HOST` | Bind hostname for the OpenChamber web server (default: `127.0.0.1`; use `0.0.0.0` for LAN/remote access — trusted networks only) |
|
|
116
|
+
| `OPENCODE_HOST` | Full base URL of an externally owned OpenCode server |
|
|
117
|
+
| `OPENCHAMBER_HOST` | Bind hostname for the OpenChamber web server (default: `127.0.0.1`; use `0.0.0.0` for LAN/remote access on trusted networks) |
|
|
115
118
|
| `OPENCHAMBER_VERBOSE_REQUEST_LOGS` | Set to `true` to log every HTTP request; disabled by default to keep user logs small |
|
|
116
119
|
| `OPENCHAMBER_SKIP_API_COMPRESSION` | Set to `true` to disable gzip compression for `/api/*` responses |
|
|
117
|
-
| `OPENCHAMBER_COMPRESS_API` | Set to `true` to force `/api/*` compression, or `false` to disable it. Desktop
|
|
120
|
+
| `OPENCHAMBER_COMPRESS_API` | Set to `true` to force `/api/*` compression, or `false` to disable it. Desktop disables API compression by default to reduce local sidecar CPU use |
|
|
118
121
|
| `OPENCHAMBER_FS_UPLOAD_MAX_BYTES` | Maximum file upload size in bytes (default: 100 MiB) |
|
|
119
122
|
| `OPENCHAMBER_TERMINAL_SHELL` | Preferred terminal shell executable used by the `Auto` setting before platform defaults |
|
|
120
123
|
|
|
121
124
|
</details>
|
|
122
125
|
|
|
123
|
-
<details>
|
|
124
|
-
<summary>Bind managed OpenCode to LAN / Tailscale</summary>
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
OPENCHAMBER_OPENCODE_HOSTNAME=0.0.0.0 openchamber --port 3000
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
**Security note:** binding to `0.0.0.0` exposes the server on all network interfaces — use only on trusted networks and protect with firewall rules or `--ui-password`.
|
|
131
|
-
|
|
132
|
-
</details>
|
|
133
126
|
|
|
134
127
|
**Optional env vars:**
|
|
135
128
|
```yaml
|
|
@@ -214,7 +207,6 @@ After=opencode.service
|
|
|
214
207
|
Type=simple
|
|
215
208
|
ExecStart=openchamber serve --port 3000 --host 0.0.0.0 --ui-password your-password --foreground
|
|
216
209
|
Environment="OPENCODE_HOST=http://localhost:4095"
|
|
217
|
-
Environment="OPENCODE_SKIP_START=true"
|
|
218
210
|
Restart=on-failure
|
|
219
211
|
RestartSec=5
|
|
220
212
|
|
package/bin/cli.js
CHANGED
|
@@ -414,7 +414,9 @@ if (isCliExecution) {
|
|
|
414
414
|
|
|
415
415
|
main().catch((error) => {
|
|
416
416
|
const message = error instanceof Error ? error.message : String(error);
|
|
417
|
-
if (
|
|
417
|
+
if (error?.cliReported === true) {
|
|
418
|
+
process.exit(EXIT_CODE.GENERAL_ERROR);
|
|
419
|
+
} else if (isJsonMode(activeCommandOptions)) {
|
|
418
420
|
printJson({
|
|
419
421
|
status: 'error',
|
|
420
422
|
error: {
|
package/bin/cli.test.js
CHANGED
|
@@ -70,10 +70,10 @@ function createMockJsonResponse(body, ok = true) {
|
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
async function
|
|
74
|
-
const originalWrite =
|
|
73
|
+
async function captureStream(stream, fn) {
|
|
74
|
+
const originalWrite = stream.write;
|
|
75
75
|
let output = '';
|
|
76
|
-
|
|
76
|
+
stream.write = (chunk, encoding, callback) => {
|
|
77
77
|
output += Buffer.isBuffer(chunk) ? chunk.toString('utf8') : String(chunk);
|
|
78
78
|
if (typeof encoding === 'function') encoding();
|
|
79
79
|
if (typeof callback === 'function') callback();
|
|
@@ -83,10 +83,18 @@ async function captureStdout(fn) {
|
|
|
83
83
|
await fn();
|
|
84
84
|
return output;
|
|
85
85
|
} finally {
|
|
86
|
-
|
|
86
|
+
stream.write = originalWrite;
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
async function captureStdout(fn) {
|
|
91
|
+
return captureStream(process.stdout, fn);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function captureStderr(fn) {
|
|
95
|
+
return captureStream(process.stderr, fn);
|
|
96
|
+
}
|
|
97
|
+
|
|
90
98
|
async function startMockOpenChamberServer(options = {}) {
|
|
91
99
|
const runtime = options.runtime || 'web';
|
|
92
100
|
const pid = Number.isFinite(options.pid) ? options.pid : null;
|
|
@@ -666,6 +674,7 @@ describe('cli API target resolution', () => {
|
|
|
666
674
|
});
|
|
667
675
|
});
|
|
668
676
|
|
|
677
|
+
|
|
669
678
|
describe('network-exposed auth validation', () => {
|
|
670
679
|
it('allows loopback without a UI password', () => {
|
|
671
680
|
expect(() => assertAuthenticatedNetworkExposure({ host: '127.0.0.1' })).not.toThrow();
|
package/bin/lib/DOCUMENTATION.md
CHANGED
|
@@ -15,12 +15,15 @@ Command modules implement user-facing commands and preserve output contracts acr
|
|
|
15
15
|
|
|
16
16
|
- `commands-serve.js`
|
|
17
17
|
- Implements `openchamber serve`.
|
|
18
|
-
- Owns OpenCode CLI checks, port resolution, log rotation, PID
|
|
18
|
+
- Owns OpenCode CLI checks, port resolution, log rotation, PID and instance registry writes, foreground or background server launch, startup summaries, and foreground shutdown behavior.
|
|
19
|
+
- Ordinary Web connects to OpenCode's shared local service. Startup failures use the existing output adapter so JSON remains JSON-only, quiet output stays concise, and non-TTY mode never prompts.
|
|
19
20
|
|
|
20
21
|
- `commands-lifecycle.js`
|
|
21
22
|
- Implements `openchamber stop` and `openchamber restart`.
|
|
22
23
|
- Owns lifecycle stop/restart semantics, desktop-managed port rejection, unmanaged instance shutdown attempts, PID/instance cleanup, and restart reuse of stored instance options.
|
|
23
24
|
|
|
25
|
+
Stopping Web shuts down the selected OpenChamber instance but leaves a `shared-local` or `explicit-external` OpenCode service running. OpenCode process teardown belongs only to the Desktop `managed-owned` runtime.
|
|
26
|
+
|
|
24
27
|
- `commands-status.js`
|
|
25
28
|
- Implements `openchamber status`.
|
|
26
29
|
- Formats discovered instances and tunnel readiness/status for human, quiet, and JSON output.
|
|
@@ -311,6 +311,15 @@ async function serveCommand(options) {
|
|
|
311
311
|
settled = true;
|
|
312
312
|
clearTimeout(timeout);
|
|
313
313
|
resolve(msg.port);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
if (msg && msg.type === 'openchamber:error') {
|
|
317
|
+
settled = true;
|
|
318
|
+
clearTimeout(timeout);
|
|
319
|
+
const error = new Error(msg.message || 'OpenChamber failed to start');
|
|
320
|
+
if (msg.code) error.code = msg.code;
|
|
321
|
+
if (msg.url) error.url = msg.url;
|
|
322
|
+
reject(error);
|
|
314
323
|
}
|
|
315
324
|
});
|
|
316
325
|
|
package/dist/assets/{CodeMirrorCommentWidgets-CWhdh0wf.js → CodeMirrorCommentWidgets-DCAQTLMM.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as a}from"./vendor-react-BUCujlKS.js";import{I as l,a as I}from"./useInlineCommentController-
|
|
1
|
+
import{j as a}from"./vendor-react-BUCujlKS.js";import{I as l,a as I}from"./useInlineCommentController-Clg8EO3A.js";function E(g){const{drafts:x,editingDraftId:d,commentText:o,onTextChange:r,selection:n,isDragging:u,fileLabel:s,newWidgetId:f,mapDraftToRange:p,onSave:m,onCancel:c,onEdit:C,onDelete:h}=g,t=[];for(const e of x){const i=p(e);if(e.id===d){t.push({afterLine:i.end,id:`edit-${e.id}`,content:a.jsx(l,{initialText:o,onTextChange:r,fileLabel:s,lineRange:i,isEditing:!0,onSave:m,onCancel:c},`edit-${e.id}`)});continue}t.push({afterLine:i.end,id:`card-${e.id}`,content:a.jsx(I,{draft:e,onEdit:()=>C(e),onDelete:()=>h(e)},`card-${e.id}`)})}if(n&&!d&&!u){const e={...n,start:Math.min(n.start,n.end),end:Math.max(n.start,n.end)};t.push({afterLine:e.end,id:f,content:a.jsx(l,{initialText:o,onTextChange:r,fileLabel:s,lineRange:e,isEditing:!1,onSave:m,onCancel:c},f)})}return t}export{E as b};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{R as r,f as Qe,j as n}from"./vendor-react-BUCujlKS.js";import{u as Q,P as Fe,C as Zn,a as Re,G as es}from"./index-Di6zUe5h.js";import{c as ts,b as ns,u as ss,a as rs,B as is,C as os,P as on,h as as,e as ls,g as cs,i as us,f as ds}from"./patchFileDiff-Cqn0C0az.js";import{c as fs,b as ms,i as ps,u as hs,a as gs,d as xs,S as ys}from"./SubmoduleDiffSummary-0HgmcMXz.js";import{f as ze,B as je,I as O,h as le,_ as xn,ai as ws,K as ae,aj as bs,bj as vs,J as js,ak as ks,am as Ss,z as an,k as Ns,da as yn,t as Ye,l7 as Cs,az as lt,kY as wn,l8 as Fs,aA as _t,gZ as Rs,ax as at,ay as Ds,c8 as zt,at as As,av as Es,aw as Ts,as as Ls}from"./useAppFontEffects-DDjuwVqi.js";import{j as Vs,f as Ms}from"./runtimeEndpointReset-D0PcCb3K.js";import{P as Bs}from"./PierreDiffViewer-BBE7tTY2.js";import{u as Is,v as Ps,g as _s,W as zs}from"./main-CI9DtHJv.js";import{b as Os,c as Ks}from"./changesTree-CePHbFcj.js";import{p as $s}from"./VirtualizedFileDiff-ClDezf2d.js";import"./vendor-scheduler-7OC5HNn7.js";import"./vendor-zod-BSoePkpP.js";import"./vendor-vite-runtime-DD1OZmLC.js";import"./vendor-zustand-BAGL70zf.js";import"./vendor-opencode-client-DSZl7jSi.js";import"./PluginPane-DQ0k41Q-.js";import"./vendor-sonner-DFyL3AvE.js";import"./vendor-simplewebauthn-browser-VDA66rT_.js";import"./vendor-base-ui-CsXYnR5c.js";import"./vendor-floating-ui-utils-D6FqdtJt.js";import"./vendor-floating-ui-react-dom-DxYCWdHj.js";import"./vendor-floating-ui-dom-BTvzWks8.js";import"./vendor-floating-ui-core-PuGzNPnN.js";import"./vendor-use-sync-external-store-D6wYuSt-.js";import"./vendor-class-variance-authority-5VPnzWs2.js";import"./vendor-clsx-B-dksMZM.js";import"./vendor-dnd-kit-core-BZknOX2w.js";import"./vendor-dnd-kit-utilities-B_MdXhJC.js";import"./vendor-dnd-kit-accessibility-BHxJPORy.js";import"./vendor-dnd-kit-sortable-CsEagZ81.js";import"./vendor-tanstack-react-virtual-ClYN8CzB.js";import"./vendor-tanstack-virtual-core-BewVQryB.js";import"./vendor-framer-motion-Bq3iTZ6r.js";import"./vendor-motion-dom-DcCgeG69.js";import"./vendor-motion-utils-BGh8QBgx.js";import"./contextPanelEmbeddedChat-CirXEPJq.js";import"./vendor-cmdk-DgLInKvT.js";import"./vendor-radix-ui-react-dialog-B94Bt2qq.js";import"./vendor-radix-ui-primitive-Dc_FVRD7.js";import"./vendor-radix-ui-react-compose-refs-DcAh5WdT.js";import"./vendor-radix-ui-react-context-Czxm7Z62.js";import"./vendor-radix-ui-react-id-f5BLKEVw.js";import"./vendor-radix-ui-react-use-layout-effect-D_3IhJdJ.js";import"./vendor-radix-ui-react-use-controllable-state-BFT5YmkA.js";import"./vendor-radix-ui-react-dismissable-layer-D7kXcwgJ.js";import"./vendor-radix-ui-react-primitive-DhVoX9SD.js";import"./vendor-radix-ui-react-slot-BQgQOasS.js";import"./vendor-radix-ui-react-use-callback-ref-BZPnuXAC.js";import"./vendor-radix-ui-react-use-escape-keydown-oph88g-F.js";import"./vendor-radix-ui-react-focus-scope-CiaxW4dD.js";import"./vendor-radix-ui-react-portal-BMJYHWck.js";import"./vendor-radix-ui-react-presence-CNxf-uq4.js";import"./vendor-radix-ui-react-focus-guards-B6qJXYua.js";import"./vendor-react-remove-scroll-DO7dCTnK.js";import"./vendor-tslib-De9GV7Vy.js";import"./vendor-react-remove-scroll-bar-BcFYyj3E.js";import"./vendor-react-style-singleton-q6EMHnwf.js";import"./vendor-get-nonce-C-Z93AgS.js";import"./vendor-use-sidecar-zDC0RhA3.js";import"./vendor-use-callback-ref-D3RC8gqK.js";import"./vendor-aria-hidden-DvXkyWUv.js";import"./vendor-codemirror-language-BgPj_McA.js";import"./vendor-lezer-common-B3-cUCR_.js";import"./vendor-codemirror-state-C9awkmn-.js";import"./vendor-marijn-find-cluster-break-DXwl3gUT.js";import"./vendor-codemirror-view-CiLROUVV.js";import"./vendor-style-mod-NZ5MEPvj.js";import"./vendor-w3c-keyname-Vcq4gwWv.js";import"./vendor-crelt-C8TCjufn.js";import"./vendor-lezer-highlight-CDMHUZ74.js";import"./vendor-codemirror-lang-javascript-Cc2ZYbgX.js";import"./vendor-lezer-javascript-D7Tj24ot.js";import"./vendor-lezer-lr-bhwg1HMg.js";import"./vendor-codemirror-autocomplete-DzPz9Wgq.js";import"./vendor-codemirror-lang-json-CMBS2tG9.js";import"./vendor-lezer-json-Iaex0UN-.js";import"./vendor-codemirror-lang-css-O0cZX78y.js";import"./vendor-lezer-css-C5xB6jxd.js";import"./vendor-codemirror-lang-html-CfgK872x.js";import"./vendor-lezer-html-C0I1p52t.js";import"./vendor-codemirror-lang-markdown-BPGOH9ye.js";import"./vendor-lezer-markdown-C6g-d6P3.js";import"./vendor-codemirror-language-data-oKF0MAwd.js";import"./vendor-codemirror-lang-python-HahnQaAS.js";import"./vendor-lezer-python-CvuFxeZl.js";import"./vendor-codemirror-commands-B7H_j0iU.js";import"./vendor-legendapp-list-BuBPBC3R.js";import"./vendor-tailwind-merge-CPcsbTWB.js";import"./vendor-fuse.js-Dw8P0qyA.js";import"./GuestAttachDialog-D7TJG1rt.js";import"./web-components-Bc1WPd4i.js";import"./computeVirtualFileMetrics-kM_zJNMt.js";import"./vendor-shiki-Bbf2GEcE.js";import"./vendor-shikijs-core-CGM_jqPK.js";import"./vendor-shikijs-types-CPSbSeK6.js";import"./vendor-shikijs-vscode-textmate-BgLrS_2D.js";import"./vendor-hast-util-to-html-BKBhbTDb.js";import"./vendor-html-void-elements-CkdplsNl.js";import"./vendor-property-information-rJCbAzvX.js";import"./vendor-zwitch-C2o2j-tx.js";import"./vendor-stringify-entities-CsH1VEn9.js";import"./vendor-character-entities-legacy-BpoLgcEt.js";import"./vendor-character-entities-html4-D7taRCQ7.js";import"./vendor-ccount-c2V3InAJ.js";import"./vendor-comma-separated-tokens-D8TqSuIK.js";import"./vendor-space-separated-tokens-DD3iYX1K.js";import"./vendor-hast-util-whitespace-D4Wp6AEg.js";import"./vendor-shikijs-engine-oniguruma-DPWuIF1G.js";import"./themeResolver-BmJyTmjJ.js";import"./vendor-pierre-theming-C6Z4M5_u.js";import"./vendor-shikijs-engine-javascript-Cme4830A.js";import"./vendor-oniguruma-to-es-DLBnFDCE.js";import"./vendor-oniguruma-parser-C0D4_9rT.js";import"./vendor-regex-BBWcyTkg.js";import"./vendor-regex-utilities-2BQyy0xI.js";import"./vendor-regex-recursion-JU4mF-dD.js";import"./vendor-shikijs-transformers-CZWsLLKm.js";import"./Virtualizer-D_a8gKmg.js";import"./useInlineCommentController-Clg8EO3A.js";import"./appThemeRegistry-CiuyzfSW.js";import"./textMateThemeFromAppTheme-C-kGcOpD.js";import"./vendor-katex-CHD9BdDO.js";import"./useRootScrollLock-nDcRrgJ1.js";import"./scheduledTasksApi-Dahv3ws0.js";import"./vendor-cron-parser-CjvYVigk.js";import"./vendor-luxon-BZ0puJYg.js";import"./isDiffPlainText-DOoIsGqs.js";import"./vendor-diff-C3JhlQdm.js";const Gs=r.memo(function(e){const s=Qe.c(13),{index:u,staged:g,busyHunk:m,disabled:w,onAction:k}=e,{t:v}=ze();let a;s[0]!==g?(a=g?["unstage"]:["discard","stage"],s[0]=g,s[1]=a):a=s[1];const j=a;let N;s[2]===Symbol.for("react.memo_cache_sentinel")?(N={top:"var(--oc-hunk-action-offset, 0.25rem)"},s[2]=N):N=s[2];let p;s[3]!==j||s[4]!==m||s[5]!==w||s[6]!==u||s[7]!==k||s[8]!==v?(p=n.jsx("div",{className:"pointer-events-auto flex items-center gap-0.5 rounded-full border border-[var(--interactive-border)]/45 bg-[var(--surface-background)]/95 px-1 py-0.5 shadow-sm backdrop-blur-md",children:j.map(b=>{const C=v(b==="stage"?"diffView.hunk.stageTitle":b==="unstage"?"diffView.hunk.unstageTitle":"diffView.hunk.discardTitle",{index:u+1}),V=m?.index===u&&m.action===b;return n.jsx(je,{variant:"ghost",size:"xs",className:le("rounded-full bg-transparent text-muted-foreground hover:bg-transparent hover:text-foreground",b==="discard"&&"text-[var(--status-error)] hover:text-[var(--status-error)]",b==="stage"&&"text-[var(--status-success)] hover:text-[var(--status-success)]"),disabled:w||m!==null,title:C,"aria-label":C,onPointerDown:Ws,onClick:f=>{f.stopPropagation(),k(u,b)},children:n.jsx(O,{name:V?"loader-4":b==="stage"?"add":"arrow-go-back",className:le(b==="stage"?"size-4":"size-3.5",V&&"animate-spin")})},b)})}),s[3]=j,s[4]=m,s[5]=w,s[6]=u,s[7]=k,s[8]=v,s[9]=p):p=s[9];let E;return s[10]!==u||s[11]!==p?(E=n.jsx("div",{className:"pointer-events-none absolute right-3 z-20",style:N,"data-hunk-actions":u,children:p}),s[10]=u,s[11]=p,s[12]=E):E=s[12],E});function Ws(o){return o.stopPropagation()}const ln=(o,e)=>{if(e.length===0)return null;let s=null,u=null;for(const m of e)m.top<=o?(!s||m.top>s.top)&&(s=m):(!u||m.top<u.top)&&(u=m);const g=s??u;return g?{path:g.path,topOffset:g.top-o}:null},Hs=(o,e,s,u)=>Math.min(Math.max(0,u),Math.max(0,o+s-e)),Mt=o=>o.slice(o.lastIndexOf("/")+1),bn=(o,e)=>{const s=[],u=(g,m)=>{const w=Array.from(g.children.values()).sort((v,a)=>v.name.localeCompare(a.name));for(const v of w){const{node:a,label:j}=Ks(v),N=!e.has(a.path);s.push({kind:"directory",key:`dir:${a.path}`,depth:m,path:a.path,label:j,fileCount:a.files.length,expanded:N}),N&&u(a,m+1)}const k=[...g.directFiles].sort((v,a)=>Mt(v.path).localeCompare(Mt(a.path)));for(const v of k)s.push({kind:"file",key:`file:${v.path}`,depth:m,name:Mt(v.path),file:v})};return u(Os(o),0),s},cn=o=>{if(!o)return null;const e=o.split(`
|
|
2
|
+
`);let s=null;for(const u of e){const g=u.match(/^@@\s*-\d+(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s*@@/);if(g){const m=Number.parseInt(g[1]??"",10);s=Number.isFinite(m)&&m>=1?m:null;continue}if(s!==null){if(u.startsWith(" ")){s+=1;continue}if(u.startsWith("+"))return s;if(u.startsWith("-"))return Math.max(1,s)}}return null},qs=1100,Us=15e3,un=500,dn=300,vn=1e6,It=3,Xs=o=>o<=6?o:o<=12?6:o<=25?4:2,fn={status:"loading"},Js=3,Ys=r.memo(()=>{const o=Qe.c(4),{t:e}=ze();let s;o[0]!==e?(s=e("diffView.binary.unavailable"),o[0]=e,o[1]=s):s=o[1];let u;return o[2]!==s?(u=n.jsx("div",{className:"rounded-lg border border-border/60 bg-background px-3 py-2",children:n.jsx("div",{className:"typography-meta text-muted-foreground",children:s})}),o[2]=s,o[3]=u):u=o[3],u}),jn={"?":{code:"?",color:"var(--status-info)",descriptionKey:"diffView.change.untracked"},A:{code:"A",color:"var(--status-success)",descriptionKey:"diffView.change.new"},D:{code:"D",color:"var(--status-error)",descriptionKey:"diffView.change.deleted"},R:{code:"R",color:"var(--status-info)",descriptionKey:"diffView.change.renamed"},C:{code:"C",color:"var(--status-info)",descriptionKey:"diffView.change.copied"},M:{code:"M",color:"var(--status-warning)",descriptionKey:"diffView.change.modified"}},Qs=jn.M,Zs=o=>{const e=o.index?.trim(),s=o.working_dir?.trim();return e&&e!=="?"?e.charAt(0):s?s.charAt(0):e?.charAt(0)||s?.charAt(0)||"M"},Ot=o=>{const e=Zs(o);return jn[e]??Qs},er=o=>{const{index:e,working_dir:s}=o;return e==="A"||s==="A"||e==="?"||s==="?"},mn=o=>{const e=o.index?.trim();return!!(e&&e!=="?")},pn=o=>!!o.working_dir?.trim()||o.index==="?",tr=(o,e)=>Rs(o,e),hn=o=>(o||"").replace(/\\/g,"/").replace(/\/+$/,""),gn=(o,e)=>{const s=o.split(`
|
|
3
|
+
`),u=e.split(`
|
|
4
|
+
`),g=Math.min(s.length,u.length);for(let m=0;m<g;m+=1)if(s[m]!==u[m])return m+1;return u.length>s.length?s.length+1:s.length>u.length?Math.max(1,u.length):1},nr=o=>o==="added"?"A":o==="deleted"?"D":"M",Pt=(o,e,s)=>us(e)?{original:"",modified:"",isBinary:!0,patch:e,contextMode:s}:{original:"",modified:"",patch:e,fileDiff:ds(o,e),contextMode:s},kn=(o,e,s)=>{const u=o??0,g=e??0;return!u&&!g?null:n.jsxs("span",{className:le("typography-meta flex items-center gap-1 text-xs whitespace-nowrap","flex-shrink-0",s?.className),children:[u?n.jsxs("span",{style:{color:"var(--status-success)"},children:["+",u]}):null,g?n.jsxs("span",{style:{color:"var(--status-error)"},children:["-",g]}):null]})},sr=r.memo(o=>{const e=Qe.c(68),{scope:s,workingCount:u,stagedCount:g,turnCount:m,branchCount:w,commitCount:k,prCount:v,showCommitOption:a,showBranchOption:j,onScopeChange:N}=o,{t:p}=ze(),[E,b]=r.useState(!1),C=s==="pr"?v??0:s==="staged"?g:s==="turn"?m:s==="branch"?w??0:s==="commit"?k??0:u;let V;e[0]!==s||e[1]!==p?(V=p(s==="pr"?"session.githubIntegration.tabs.pullRequests":s==="staged"?"diffView.scope.staged":s==="turn"?"diffView.scope.lastTurn":s==="branch"?"diffView.scope.branch":s==="commit"?"commitComparison.mode":"diffView.scope.changed"),e[0]=s,e[1]=p,e[2]=V):V=e[2];const f=V;let S;e[3]!==p?(S=p("diffView.scope.selectorAria"),e[3]=p,e[4]=S):S=e[4];let M;e[5]!==C?(M=n.jsxs("span",{className:"diff-toolbar__scope-count",children:[": ",C]}),e[5]=C,e[6]=M):M=e[6];let I;e[7]!==f||e[8]!==M?(I=n.jsxs("span",{className:"whitespace-nowrap",children:[f,M]}),e[7]=f,e[8]=M,e[9]=I):I=e[9];let ce;e[10]===Symbol.for("react.memo_cache_sentinel")?(ce=n.jsx(O,{name:"arrow-down-s",className:"size-4 flex-shrink-0 opacity-60"}),e[10]=ce):ce=e[10];let U;e[11]!==S||e[12]!==I?(U=n.jsx(As,{asChild:!0,children:n.jsxs("button",{type:"button",className:"flex h-7 flex-shrink-0 items-center gap-1.5 rounded-md px-2 typography-ui-label font-semibold text-foreground outline-none hover:bg-interactive-hover focus-visible:ring-2 focus-visible:ring-ring","aria-label":S,children:[I,ce]})}),e[11]=S,e[12]=I,e[13]=U):U=e[13];let y;e[14]!==N?(y=H=>{(H==="working"||H==="staged"||H==="turn"||H==="branch"||H==="commit"||H==="pr")&&(N?.(H),b(!1))},e[14]=N,e[15]=y):y=e[15];let K;e[16]!==p?(K=p("diffView.scope.changed"),e[16]=p,e[17]=K):K=e[17];let X;e[18]!==K?(X=n.jsx("span",{children:K}),e[18]=K,e[19]=X):X=e[19];let ue;e[20]!==u?(ue=n.jsx("span",{className:"typography-meta text-muted-foreground",children:u}),e[20]=u,e[21]=ue):ue=e[21];let se;e[22]!==ue||e[23]!==X?(se=n.jsx(at,{value:"working",children:n.jsxs("span",{className:"flex min-w-0 flex-1 items-center justify-between gap-3",children:[X,ue]})}),e[22]=ue,e[23]=X,e[24]=se):se=e[24];let xe;e[25]!==p?(xe=p("diffView.scope.staged"),e[25]=p,e[26]=xe):xe=e[26];let re;e[27]!==xe?(re=n.jsx("span",{children:xe}),e[27]=xe,e[28]=re):re=e[28];let ye;e[29]!==g?(ye=n.jsx("span",{className:"typography-meta text-muted-foreground",children:g}),e[29]=g,e[30]=ye):ye=e[30];let ee;e[31]!==re||e[32]!==ye?(ee=n.jsx(at,{value:"staged",children:n.jsxs("span",{className:"flex min-w-0 flex-1 items-center justify-between gap-3",children:[re,ye]})}),e[31]=re,e[32]=ye,e[33]=ee):ee=e[33];let _;e[34]!==p?(_=p("diffView.scope.lastTurn"),e[34]=p,e[35]=_):_=e[35];let te;e[36]!==_?(te=n.jsx("span",{children:_}),e[36]=_,e[37]=te):te=e[37];let ne;e[38]!==m?(ne=n.jsx("span",{className:"typography-meta text-muted-foreground",children:m}),e[38]=m,e[39]=ne):ne=e[39];let $;e[40]!==te||e[41]!==ne?($=n.jsx(at,{value:"turn",children:n.jsxs("span",{className:"flex min-w-0 flex-1 items-center justify-between gap-3",children:[te,ne]})}),e[40]=te,e[41]=ne,e[42]=$):$=e[42];let ke;e[43]!==w||e[44]!==j||e[45]!==p?(ke=j?n.jsx(at,{value:"branch",children:n.jsxs("span",{className:"flex min-w-0 flex-1 items-center justify-between gap-3",children:[n.jsx("span",{children:p("diffView.scope.branch")}),n.jsx("span",{className:"typography-meta text-muted-foreground",children:w??"…"})]})}):null,e[43]=w,e[44]=j,e[45]=p,e[46]=ke):ke=e[46];let T;e[47]!==k||e[48]!==a||e[49]!==p?(T=a&&n.jsx(at,{value:"commit",children:n.jsxs("span",{className:"flex min-w-0 flex-1 items-center justify-between gap-3",children:[n.jsx("span",{children:p("commitComparison.mode")}),n.jsx("span",{className:"typography-meta text-muted-foreground",children:k??"…"})]})}),e[47]=k,e[48]=a,e[49]=p,e[50]=T):T=e[50];let W;e[51]!==v||e[52]!==a||e[53]!==p?(W=a&&n.jsx(at,{value:"pr",children:n.jsxs("span",{className:"flex min-w-0 flex-1 items-center justify-between gap-3",children:[n.jsx("span",{children:p("session.githubIntegration.tabs.pullRequests")}),n.jsx("span",{className:"typography-meta text-muted-foreground",children:v??"…"})]})}),e[51]=v,e[52]=a,e[53]=p,e[54]=W):W=e[54];let A;e[55]!==s||e[56]!==se||e[57]!==ee||e[58]!==$||e[59]!==ke||e[60]!==T||e[61]!==W||e[62]!==y?(A=n.jsx(Es,{align:"start",className:"w-40",children:n.jsxs(Ts,{value:s,onValueChange:y,children:[se,ee,$,ke,T,W]})}),e[55]=s,e[56]=se,e[57]=ee,e[58]=$,e[59]=ke,e[60]=T,e[61]=W,e[62]=y,e[63]=A):A=e[63];let de;return e[64]!==E||e[65]!==A||e[66]!==U?(de=n.jsxs(Ls,{open:E,onOpenChange:b,children:[U,A]}),e[64]=E,e[65]=A,e[66]=U,e[67]=de):de=e[67],de}),rr=r.memo(o=>{const e=Qe.c(11),{changedFiles:s,selectedFile:u,onSelectFile:g}=o,{t:m}=ze();if(s.length===0)return null;let w;if(e[0]!==s||e[1]!==g||e[2]!==u||e[3]!==m){let v;e[5]!==g||e[6]!==u||e[7]!==m?(v=a=>{const j=Ot(a),N=u===a.path;return n.jsx("li",{children:n.jsxs("button",{type:"button",onClick:()=>g(a.path),className:le("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left transition-colors",N?"bg-interactive-selection text-interactive-selection-foreground":"text-muted-foreground hover:bg-interactive-hover hover:text-foreground"),children:[n.jsx(_t,{filePath:a.path,className:"h-3.5 w-3.5 flex-shrink-0"}),n.jsx("span",{className:"typography-micro font-semibold w-4 text-center uppercase",style:{color:j.color},title:m(j.descriptionKey),"aria-label":m(j.descriptionKey),children:j.code}),n.jsx("span",{className:"min-w-0 flex-1 truncate typography-meta",style:{direction:"rtl",textAlign:"left",unicodeBidi:"plaintext"},title:a.path,children:a.path}),kn(a.insertions,a.deletions)]})},a.path)},e[5]=g,e[6]=u,e[7]=m,e[8]=v):v=e[8],w=s.map(v),e[0]=s,e[1]=g,e[2]=u,e[3]=m,e[4]=w}else w=e[4];let k;return e[9]!==w?(k=n.jsx(zt,{outerClassName:"flex-1 min-h-0",className:"px-2 py-2",children:n.jsx("ul",{className:"flex flex-col gap-1",children:w})}),e[9]=w,e[10]=k):k=e[10],k}),Sn=12,Nn=8,Bt=160,ir=.5,or=r.memo(o=>{const e=Qe.c(18),{changedFiles:s,selectedFile:u,onSelectFile:g}=o,{t:m}=ze(),[w,k]=r.useState(ur);let v;e[0]!==s||e[1]!==w?(v=bn(s,w),e[0]=s,e[1]=w,e[2]=v):v=e[2];const a=v;let j,N;e[3]!==u?(j=()=>{u&&k(f=>{const S=Array.from(f).filter(I=>u.startsWith(`${I}/`));if(S.length===0)return f;const M=new Set(f);return S.forEach(I=>M.delete(I)),M})},N=[u],e[3]=u,e[4]=j,e[5]=N):(j=e[4],N=e[5]),r.useEffect(j,N);let p;e[6]===Symbol.for("react.memo_cache_sentinel")?(p=f=>{k(S=>{const M=new Set(S);return M.delete(f)||M.add(f),M})},e[6]=p):p=e[6];const E=p,b=fr;let C;if(e[7]!==g||e[8]!==a||e[9]!==u||e[10]!==m){let f;e[12]!==g||e[13]!==u||e[14]!==m?(f=S=>{const M=`${Nn+S.depth*Sn}px`;if(S.kind==="directory")return n.jsxs("li",{className:"relative",children:[b(S.depth),n.jsxs("button",{type:"button",onClick:()=>E(S.path),"aria-expanded":S.expanded,"aria-label":S.expanded?m("diffView.fileTree.collapseDirectoryAria",{path:S.path}):m("diffView.fileTree.expandDirectoryAria",{path:S.path}),className:"flex w-full items-center gap-1 rounded-md py-1 pr-2 text-left text-muted-foreground transition-colors hover:bg-interactive-hover hover:text-foreground",style:{paddingLeft:M},title:S.path,children:[n.jsx(O,{name:"arrow-right-s",className:le("size-3.5 flex-shrink-0 transition-transform",S.expanded&&"rotate-90")}),n.jsx("span",{className:"min-w-0 flex-1 truncate typography-meta",children:S.label})]})]},S.key);const I=Ot(S.file),ce=u===S.file.path;return n.jsxs("li",{className:"relative",children:[b(S.depth),n.jsxs("button",{type:"button",onClick:()=>g(S.file.path),"aria-current":ce?"true":void 0,className:le("flex w-full items-center gap-1.5 rounded-md py-1 pr-2 text-left transition-colors",ce?"bg-interactive-selection text-interactive-selection-foreground":"text-foreground/90 hover:bg-interactive-hover hover:text-foreground"),style:{paddingLeft:M},title:S.file.path,children:[n.jsx(_t,{filePath:S.file.path,className:"ml-0.5 size-3.5 flex-shrink-0"}),n.jsx("span",{className:"min-w-0 flex-1 truncate typography-meta",children:S.name}),n.jsx("span",{className:"typography-micro font-semibold w-3 text-center uppercase",style:{color:I.color},title:m(I.descriptionKey),"aria-label":m(I.descriptionKey),children:I.code})]})]},S.key)},e[12]=g,e[13]=u,e[14]=m,e[15]=f):f=e[15],C=a.map(f),e[7]=g,e[8]=a,e[9]=u,e[10]=m,e[11]=C}else C=e[11];let V;return e[16]!==C?(V=n.jsx(zt,{outerClassName:"flex-1 min-h-0",className:"px-1.5 py-1.5",children:n.jsx("ul",{className:"flex flex-col",children:C})}),e[16]=C,e[17]=V):V=e[17],V}),ar=r.memo(o=>{const e=Qe.c(20),{filePath:s,diff:u,renderSideBySide:g}=o,{t:m}=ze(),w=u.original.length>0,k=u.modified.length>0,v=g?"flex flex-row gap-6 items-start justify-center":"flex flex-col gap-4 items-center",a=g?"flex flex-col items-center gap-2 flex-1 min-w-0":"flex flex-col items-center gap-2";let j;e[0]===Symbol.for("react.memo_cache_sentinel")?(j={contain:"layout"},e[0]=j):j=e[0];let N;e[1]!==u.original||e[2]!==s||e[3]!==w||e[4]!==a||e[5]!==g||e[6]!==m?(N=w&&n.jsxs("div",{className:a,children:[n.jsx("span",{className:"typography-meta text-muted-foreground font-medium",children:m("diffView.image.original")}),n.jsx("img",{src:u.original,alt:m("diffView.image.originalAlt",{path:s}),className:g?"max-w-full max-h-[70vh] object-contain":"max-w-full object-contain",style:{imageRendering:"auto"}})]}),e[1]=u.original,e[2]=s,e[3]=w,e[4]=a,e[5]=g,e[6]=m,e[7]=N):N=e[7];let p;e[8]!==u.modified||e[9]!==s||e[10]!==k||e[11]!==w||e[12]!==a||e[13]!==g||e[14]!==m?(p=k&&n.jsxs("div",{className:a,children:[n.jsx("span",{className:"typography-meta text-muted-foreground font-medium",children:m(w?"diffView.image.modified":"diffView.image.new")}),n.jsx("img",{src:u.modified,alt:m("diffView.image.modifiedAlt",{path:s}),className:g?"max-w-full max-h-[70vh] object-contain":"max-w-full object-contain",style:{imageRendering:"auto"}})]}),e[8]=u.modified,e[9]=s,e[10]=k,e[11]=w,e[12]=a,e[13]=g,e[14]=m,e[15]=p):p=e[15];let E;return e[16]!==v||e[17]!==N||e[18]!==p?(E=n.jsx("div",{className:"w-full overflow-auto p-4",style:j,children:n.jsxs("div",{className:v,children:[N,p]})}),e[16]=v,e[17]=N,e[18]=p,e[19]=E):E=e[19],E}),lr=r.memo(o=>{const e=Qe.c(23),{filePath:s,diff:u,staged:g,renderSideBySide:m,wrapLines:w,hunkActions:k,onExpandContextRequest:v,pendingContextExpansion:a,contextLoading:j}=o;let N;e[0]!==s?(N=Ds(s)||"text",e[0]=s,e[1]=N):N=e[1];const p=N;if(u.submodule){let C;return e[2]!==u.submodule||e[3]!==g?(C=n.jsx(ys,{state:u.submodule,staged:g}),e[2]=u.submodule,e[3]=g,e[4]=C):C=e[4],C}if(u.isBinary){let C;return e[5]===Symbol.for("react.memo_cache_sentinel")?(C=n.jsx(Ys,{}),e[5]=C):C=e[5],C}if(lt(s)){let C;return e[6]!==u||e[7]!==s||e[8]!==m?(C=n.jsx(ar,{filePath:s,diff:u,renderSideBySide:m}),e[6]=u,e[7]=s,e[8]=m,e[9]=C):C=e[9],C}let E;e[10]===Symbol.for("react.memo_cache_sentinel")?(E={contain:"layout"},e[10]=E):E=e[10];let b;return e[11]!==j||e[12]!==u.fileDiff||e[13]!==u.modified||e[14]!==u.original||e[15]!==s||e[16]!==k||e[17]!==p||e[18]!==v||e[19]!==a||e[20]!==m||e[21]!==w?(b=n.jsx("div",{className:"w-full",style:E,children:n.jsx(Bs,{original:u.original,modified:u.modified,fileDiff:u.fileDiff,language:p,fileName:s,renderSideBySide:m,wrapLines:w,layout:"inline",hunkActions:k,onExpandContextRequest:v,pendingContextExpansion:a,contextLoading:j})}),e[11]=j,e[12]=u.fileDiff,e[13]=u.modified,e[14]=u.original,e[15]=s,e[16]=k,e[17]=p,e[18]=v,e[19]=a,e[20]=m,e[21]=w,e[22]=b):b=e[22],b}),cr=r.memo(({visible:o=!0,directory:e,file:s,layout:u,wrapLines:g,isSelected:m,isExpanded:w,isMounted:k,onSelect:v,onExpandedChange:a,registerSectionRef:j,showOpenInEditorAction:N=!1,isOpeningInEditor:p=!1,onOpenInEditor:E,staged:b=!1,loadFullFiles:C=!1,initialDiffData:V=null,comparisonDiff:f,onRetryComparisonDiff:S,loadFullComparisonDiff:M,readOnlyActions:I=!1,hunkActionsEnabled:ce=!1,contentRevision:U=0})=>{const{t:y}=ze(),{git:K}=xn(),X=ae(r.useCallback(x=>x.directories.get(e)?.diffCache.get(s.path)??null,[e,s.path])),ue=ae(x=>x.setDiff),se=ae(x=>x.fetchStatus),xe=Q(x=>x.setDiffFileLayout),[re,ye]=r.useState(0),[ee,_]=r.useState(null),[te,ne]=r.useState(!1),[$,ke]=r.useState(null),T=$!==null&&$.source===f?$.result:f,W=!!e&&!V&&(!f||!!M),A=r.useMemo(()=>T?T.status==="error"?{kind:"error",message:T.message}:null:ee,[T,ee]),de=T?T.status==="loading":te,[H,xt]=r.useState(null),Oe=r.useRef(!1),[Ke,ct]=r.useState(null),[yt,Ft]=r.useState(!1),[ut,$e]=r.useState(null),[Ze,Ge]=r.useState(null),[c,De]=r.useState(null),ie=C||c!==null;r.useEffect(()=>{if(!c||!M||!f||f.status!=="ready"||$?.source===f)return;let x=!1;return M(s.path).then(z=>{if(!x){if(z.status==="error"){Ye.error(z.message),De(null);return}ke({source:f,result:z})}}),()=>{x=!0}},[c,s.path,$,M,f]);const we=r.useRef(null),Ae=r.useRef(null),We=r.useMemo(()=>Ot(s),[s]),et=u==="side-by-side",He=ie?"full":"patch",Se=`${s.index}:${s.working_dir}:${s.insertions}:${s.deletions}`,fe=ce&&!I&&!V&&!T&&!lt(s.path),tt=JSON.stringify([Re(),e,s.path,b,Se,re,U]),G=Ke?.scope===tt?Ke.patch:null,wt=Ke?.scope===tt?Ke.submodule:null,me=r.useMemo(()=>T?T.status==="ready"?T.data:null:V||(b?Ze:ut||(X?{original:X.original,modified:X.modified,isBinary:X.isBinary,submodule:X.submodule,contextMode:"full"}:null)),[T,X,V,ut,b,Ze]),pe=me?.contextMode===He,dt=r.useCallback(x=>{Ae.current=x,j(s.path,x)},[s.path,j]),nt=r.useCallback(x=>{a(s.path,x)},[s.path,a]),st=r.useCallback(()=>{v(s.path)},[s.path,v]),qe=r.useRef({fileStatusKey:Se,staged:b});r.useEffect(()=>{if(!o)return;const x=qe.current;x.fileStatusKey===Se&&x.staged===b||(qe.current={fileStatusKey:Se,staged:b},b?Ge(null):$e(null),_(null),we.current=null)},[Se,b,o]);const[Ue,Rt]=r.useState(U),rt=Ue===U;r.useEffect(()=>{rt||(_(null),we.current=null)},[rt]),r.useEffect(()=>{if(!o||!w||!k||ee)return;if(!e||T||V||me&&pe&&rt&&(!fe||G!==null)){we.current=null,ne(!1);return}const x=`${e}::${s.path}::${b?"staged":"unstaged"}::${Se}::${He}::${re}::${U}`;if(we.current===x)return;we.current=x,_(null),ne(!0);let z=!1;const he=Re(),Le=ie?vn:It,Z=lt(s.path)?K.getGitFileDiff(e,{path:s.path,staged:b}):!ie&&G!==null?Promise.resolve({diff:G,submodule:wt}):K.getGitDiff(e,{path:s.path,staged:b,contextLines:Le}),Ve=fe&&ie&&G===null?K.getGitDiff(e,{path:s.path,staged:b,contextLines:It}).then(L=>L.diff):Promise.resolve(G),Ne=Promise.all([Z,Ve]),Me=Us;let it;const Dt=new Promise((L,ft)=>{it=setTimeout(()=>ft(new Error(`Timed out after ${Me}ms`)),Me)});return Promise.race([Ne,Dt]).then(([L,ft])=>{if(z||he!==Re())return;const Be="diff"in L&&!ie?L.diff:ft;if(fe&&ie&&Be!==null&&/^@@\s/m.test(Be)&&"diff"in L&&L.diff!==Be&&!as(L.diff,Be))throw ct(null),new Error(y("diffView.hunk.unavailable"));if(fe&&Be!==null&&ct({scope:tt,patch:Be,submodule:L.submodule}),"diff"in L){const Xe={...Pt(s.path,L.diff,He),submodule:L.submodule};b?Ge(Xe):$e(Xe)}else{const Xe={original:L.original??"",modified:L.modified??"",isBinary:L.isBinary,submodule:L.submodule,contextMode:"full"};b?Ge(Xe):ue(e,s.path,Xe,he)}Rt(U),ne(!1)}).catch(L=>{if(!(z||he!==Re())){if(ne(!1),L instanceof es){_({kind:"unavailable",reason:L.reason}),L.reason==="path_not_found"&&se(e,K,{force:!0,silent:!0});return}_({kind:"error",message:L instanceof Error?L.message:String(L)})}}).finally(()=>clearTimeout(it)),()=>{z=!0,clearTimeout(it),we.current===x&&(we.current=null)}},[G,wt,U,fe,rt,tt,T,He,me,pe,re,e,se,s.path,Se,K,V,w,k,ie,ee,ue,b,y,o]);const bt=r.useCallback(()=>{nt(!w),st()},[nt,st,w]),oe=r.useCallback(()=>{_(null),ct(null),$e(null),Ge(null),we.current=null,ye(x=>x+1)},[]),Ee=r.useCallback(async(x,z)=>{if(!e||!fe||de||A||Oe.current||H!==null)return;const he=G?ls(G,x):null;if(!he){Ye.error(y("diffView.hunk.unavailable"));return}if(b&&z!=="unstage"||!b&&z==="unstage")return;Oe.current=!0;const Le=Re();xt({index:x,action:z});try{const Z=z==="stage"?K.stageGitHunk:z==="unstage"?K.unstageGitHunk:K.revertGitHunk;if(!Z){Ye.error(y("diffView.hunk.unsupported"));return}if(await Z(e,s.path,he),Le!==Re())return;oe(),yn.requestGitRefresh({directory:e,paths:[s.path]}),await se(e,K)}catch(Z){if(Le!==Re())return;oe(),Ye.error(Z instanceof Error&&Z.message?Z.message:y("diffView.hunk.unavailable"))}finally{Oe.current=!1,xt(Z=>Z?.index===x&&Z.action===z?null:Z)}},[G,fe,de,A,e,se,s.path,K,H,oe,b,y]),be=r.useMemo(()=>fe&&G!==null?cs(G):[],[G,fe]),q=r.useCallback(x=>n.jsx(Gs,{index:x,staged:b,busyHunk:H,disabled:de||!!A,onAction:Ee}),[A,Ee,H,de,b]),Te=r.useMemo(()=>be.length>0?{anchors:be,render:q}:void 0,[be,q]);return n.jsxs("div",{ref:dt,className:"scroll-mt-9 border-b border-[var(--interactive-border)]/40 last:border-b-0",children:[n.jsx("div",{className:"sticky top-0 z-30 border-b border-[var(--interactive-border)]/35 bg-[var(--surface-elevated)]/90 backdrop-blur-md supports-[backdrop-filter]:bg-[var(--surface-elevated)]/80",children:n.jsxs("div",{role:"button",tabIndex:0,onClick:bt,onKeyDown:x=>{x.target===x.currentTarget&&(x.key==="Enter"||x.key===" ")&&(x.preventDefault(),bt())},className:le("cursor-pointer","group/header relative grid min-h-9 w-full min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-2 overflow-hidden px-3 py-2","bg-transparent","text-muted-foreground hover:text-foreground",m?"bg-[var(--interactive-selection)]/35":null),children:[n.jsx("div",{className:"absolute inset-0 pointer-events-none group-hover/header:bg-[var(--interactive-hover)]/50"}),n.jsxs("div",{className:"relative flex min-w-0 flex-1 items-center gap-2",children:[n.jsx("span",{className:"flex size-5 items-center justify-center opacity-70 group-hover/header:opacity-100",children:w?n.jsx(O,{name:"arrow-down-s",className:"size-4"}):n.jsx(O,{name:"arrow-right-s",className:"size-4"})}),n.jsx("span",{className:"typography-micro font-semibold leading-none w-4 text-center uppercase",style:{color:We.color},title:y(We.descriptionKey),"aria-label":y(We.descriptionKey),children:We.code}),n.jsx("span",{className:"min-w-0 flex-1 overflow-hidden typography-ui-label",title:s.path,children:n.jsxs("span",{className:"flex min-w-0 items-center gap-2",children:[n.jsx(_t,{filePath:s.path,className:"h-3.5 w-3.5 flex-shrink-0 align-middle"}),(()=>{const x=s.path.lastIndexOf("/");if(x===-1)return n.jsx("span",{className:"block min-w-0 truncate typography-ui-label text-foreground",style:{direction:"rtl",textAlign:"left",unicodeBidi:"plaintext"},children:s.path});const z=s.path.slice(0,x),he=s.path.slice(x+1);return n.jsxs("span",{className:"flex min-w-0 items-baseline overflow-hidden",children:[n.jsx("span",{className:"min-w-0 truncate typography-ui-label text-muted-foreground",style:{direction:"rtl",textAlign:"left",unicodeBidi:"plaintext"},children:z}),n.jsxs("span",{className:"flex-shrink-0 typography-ui-label",children:[n.jsx("span",{className:"text-muted-foreground",children:"/"}),n.jsx("span",{className:"text-foreground",children:he})]})]})})()]})})]}),n.jsxs("div",{className:"relative flex shrink-0 items-center justify-self-end gap-2",children:[kn(s.insertions,s.deletions),N&&E?n.jsx(je,{variant:"ghost",size:"sm",className:"h-5 w-5 p-0 opacity-70 hover:opacity-100",title:y("diffView.actions.openFileInEditorAtChange"),onClick:x=>{x.stopPropagation(),E(s.path,me)},disabled:p,children:p?n.jsx(O,{name:"loader-4",className:"size-3.5 animate-spin"}):n.jsx(O,{name:"edit",className:"size-3.5"})}):null,n.jsx(wn,{mode:et?"side-by-side":"unified",onModeChange:x=>{const z=x==="side-by-side"?"side-by-side":"inline";xe(s.path,z)},className:"opacity-70"})]})]})}),w&&n.jsxs("div",{className:"relative bg-background overflow-hidden",children:[!k&&!A?n.jsx("div",{className:"h-40 border border-border/40 bg-background/40"}):null,A?.kind==="unavailable"?n.jsxs("div",{className:"flex flex-col items-center gap-2 px-4 py-8 text-sm text-muted-foreground",children:[n.jsx("div",{className:"typography-ui-label font-semibold text-foreground",children:A.reason==="nested_repository"?y("diffView.unavailable.nestedRepositoryTitle"):A.reason==="untracked_directory"?y("diffView.unavailable.untrackedDirectoryTitle"):y("diffView.unavailable.missingTitle")}),n.jsx("div",{className:"typography-meta text-muted-foreground max-w-[32rem] text-center",children:A.reason==="nested_repository"?y("diffView.unavailable.nestedRepositoryDescription"):A.reason==="untracked_directory"?y("diffView.unavailable.untrackedDirectoryDescription"):y("diffView.unavailable.missingDescription")}),A.reason==="path_not_found"?n.jsx("button",{type:"button",className:"typography-ui-label text-primary hover:underline",onClick:oe,children:y("diffView.actions.retry")}):null]}):null,A?.kind==="error"?n.jsxs("div",{className:"flex flex-col items-center gap-2 px-4 py-8 text-sm text-muted-foreground",children:[n.jsx("div",{className:"typography-ui-label font-semibold text-foreground",children:y("diffView.state.failedToLoadDiff")}),n.jsx("div",{className:"typography-meta text-muted-foreground max-w-[32rem] text-center",children:A.message}),n.jsx("button",{type:"button",className:"typography-ui-label text-primary hover:underline",onClick:()=>T?S?.():oe(),children:y("diffView.actions.retry")})]}):null,k&&de&&!me&&!A?n.jsxs("div",{className:"flex items-center justify-center gap-2 px-4 py-8 text-sm text-muted-foreground",children:[n.jsx(O,{name:"loader-4",className:"size-4 animate-spin"}),y("diffView.state.loadingDiff")]}):null,k&&me&&!yt&&s.insertions+s.deletions>un?n.jsxs("div",{className:"flex flex-col items-center gap-2 px-4 py-8 text-sm text-muted-foreground",children:[n.jsx("div",{className:"typography-ui-label font-semibold text-foreground",children:y("diffView.state.largeDiff",{count:s.insertions+s.deletions})}),n.jsx("div",{className:"typography-meta text-muted-foreground",children:y("diffView.state.largeDiffDescription")}),n.jsx("button",{type:"button",className:"typography-ui-label text-primary hover:underline",onClick:()=>Ft(!0),children:y("diffView.actions.renderAnyway")})]}):null,k&&me&&(yt||s.insertions+s.deletions<=un)?n.jsx(n.Fragment,{children:n.jsx(lr,{filePath:s.path,diff:me,staged:b,renderSideBySide:et,wrapLines:g,hunkActions:Te,onExpandContextRequest:W?De:void 0,pendingContextExpansion:c,contextLoading:c!==null&&me.contextMode!=="full"&&!A})}):null]})]})}),Vo=({visible:o=!0,hideStackedFileSidebar:e=!1,stackedDefaultCollapsedAll:s=!1,pinSelectedFileHeaderToTopOnNavigate:u=!1,showOpenInEditorAction:g=!1,diffScope:m="all",onDiffScopeChange:w,targetFilePath:k=null,flushContent:v=!1})=>{const{t:a}=ze(),{git:j,files:N}=xn(),p=ws(),E=ae(t=>t.runtimeKey),{rootIsGitRepo:b,gitDirectory:C,nestedRepos:V}=bs(p??null,{enabled:o}),f=C??p,S=Q(t=>t.openContextSurface),M=Is(t=>t.requestSource),{screenWidth:I,isMobile:ce}=vs(),U=js(f??null),y=ks(f??null),K=Ss(f??null),X=ae(t=>t.setActiveDirectory),ue=ae(t=>t.ensureStatus),se=ae(t=>t.selectNestedRepo),xe=ae(t=>t.fetchStatus),re=ae(t=>t.fetchBranches),ye=ae(t=>t.clearDiffCache),ee=ae(t=>t.setDiff),[_,te]=r.useState(null),[ne,$]=r.useState(!1),[ke,T]=r.useState(null),[W,A]=r.useState(()=>new Set),[de,H]=r.useState(()=>new Set),[xt,Oe]=r.useState(0),[Ke,ct]=r.useState(()=>new Map),[yt,Ft]=r.useState(0),[ut,$e]=r.useState(!1),[Ze,Ge]=r.useState(!1),[c,De]=r.useState(m);r.useEffect(()=>{De(m)},[m]);const ie=Q(t=>t.pendingDiffFile),we=Q(t=>t.pendingDiffStaged),Ae=Q(t=>t.pendingDiffScope),We=Q(t=>t.setPendingDiffFile),et=Q(t=>t.diffLayoutPreference),He=Q(t=>t.diffFileLayout),Se=Q(t=>t.setDiffFileLayout),fe=Q(t=>t.diffWrapLines),tt=Q(t=>t.setDiffWrapLines),G=Q(t=>t.diffFileListMode),wt=Q(t=>t.setDiffFileListMode),me=Q(t=>t.openContextFileAtLine),pe=an(t=>t.currentSessionId),dt=Ns(c==="turn"?pe??"":"",p??void 0),nt=fe,st=c==="staged"?!0:c==="working"?!1:null,qe=st??ne,Ue=ce||I<=768,Rt=!!pe&&c!=="turn"&&c!=="commit"&&c!=="pr"&&!Ue&&!Fe(),rt=c!=="turn"&&!Ue&&!Fe(),bt=!e&&!Ue&&I>=1024,oe=r.useRef(null),Ee=r.useRef(new Map),be=r.useRef(null),q=r.useRef(null),Te=r.useRef(!1),x=r.useRef(null),z=r.useRef(null),he=r.useRef(null),Le=r.useRef(null),Z=r.useCallback(()=>{const t=oe.current;if(!t)return null;const i=t.getBoundingClientRect().top,l=[];for(const[d,h]of Ee.current)h&&l.push({path:d,top:h.getBoundingClientRect().top});return ln(i,l)},[]),Ve=r.useCallback(()=>{be.current=null,Te.current=!1,T(null),q.current!==null&&(window.cancelAnimationFrame(q.current),q.current=null)},[]),Ne=r.useCallback(t=>{A(i=>{if(i.has(t))return i;const l=new Set(i);return l.add(t),l})},[]),[Me,it]=r.useState([]),Dt=dt.length>0?dt[dt.length-1].id:"";r.useEffect(()=>{if(c!=="turn"||!pe||!o)return;let t=!1;return Zn.getSessionTurnDiff(pe,{directory:p??void 0}).then(i=>{t||it(i.map(l=>({file:l.file,patch:l.patch,status:l.status,additions:l.additions,deletions:l.deletions})))}).catch(i=>{t||(console.warn("[diff-view] turn diff unavailable:",i instanceof Error?i.message:i),it([]))}),()=>{t=!0}},[c,pe,Dt,p,o]);const L=r.useMemo(()=>{const t=new Map;for(const i of Me)if(i.file){if(typeof i.patch=="string"){t.set(i.file,Pt(i.file,i.patch,"patch"));continue}t.set(i.file,{original:i.before??"",modified:i.after??"",contextMode:"full"})}return t},[Me]),ft=r.useMemo(()=>y?.files?y.files.filter(pn).length:0,[y]),Be=r.useMemo(()=>y?.files?y.files.filter(mn).length:0,[y]),Xe=Me.length,J=y?.current??null,Ie=ts(f??null,J,o&&c==="pr"&&!Fe()),Pe=Ie.selectedSource,_e=ns(f??null,J,o&&c==="commit"&&!Fe()),Je=_e.selectedCommit?.hash??null;r.useEffect(()=>{(c==="commit"||c==="pr")&&Fe()&&(De("working"),w?.("working"))},[c,w]);const ot=ae(t=>f?t.directories.get(f)?.branches??null:null),Cn=ae(t=>f?t.directories.get(f)?.isLoadingBranches??!1:!1),Fn=r.useCallback(()=>{f&&re(f,j)},[f,re,j]),Rn=fs(f??null,o&&U!==!1,Cn,!!ot,Fn,Js),Kt=r.useMemo(()=>{const t=y?.tracking?.trim().split("/")[0];return(t&&ot?.defaultBranches?.[t])??ot?.defaultBranches?.origin??null},[ot,y?.tracking]),$t=!Fe()&&ms(J,Kt),Dn=y!==null,Gt=Fe()||Rn||ps(J,Kt,Dn,ot!==null),An=ss(t=>t.setOverride),{base:Ce,resolved:En,revision:Wt}=rs(f??null,J,o&&$t&&c==="branch"),[Tn,Ln]=r.useState(0);r.useEffect(()=>{const t=xs(c,!Gt);t!==c&&(De(t),t==="working"&&w?.("working"))},[c,Gt,w]);const Vn=r.useMemo(()=>c==="pr"?Pe:c==="commit"&&Je?{kind:"commit",hash:Je}:c==="branch"&&Ce&&J?{kind:"branch",baseRef:Ce,headRef:J}:null,[c,Ce,J,Je,Pe]),P=hs(f??null,Vn,o&&!Fe(),c==="branch"?Wt:""),{fetchDiff:Ht,fetchFullFile:qt}=P,Ut=c==="commit"?P.files:null,Xt=c==="commit"?P.error:null,vt=c==="branch"?P.files:null,Jt=c==="branch"?P.error:null,Yt=P.files?c==="pr"?JSON.stringify([P.key,P.revision]):P.key:null,Mn=r.useMemo(()=>c==="branch"||c==="commit"||c==="pr"?Array.from(W).sort().join("\0"):"",[c,W]),At=r.useCallback(async(t,i=!1)=>{try{const l=await Ht(t,i?vn:It);return{status:"ready",data:Pt(t,l.diff,i?"full":"patch")}}catch(l){return{status:"error",message:l instanceof Error?l.message:a("diffView.state.failedToLoadDiff")}}},[Ht,a]),Qt=r.useCallback(async t=>{try{const{original:i,modified:l}=await qt(t),d=$s({name:t,contents:i},{name:t,contents:l});return{status:"ready",data:{original:i,modified:l,fileDiff:d,contextMode:"full"}}}catch(i){return{status:"error",message:i instanceof Error?i.message:a("diffView.state.failedToLoadDiff")}}},[qt,a]),Bn=r.useMemo(()=>c==="branch"||c==="commit"?t=>At(t,!0):c==="pr"?Qt:void 0,[c,At,Qt]),In=gs(Yt,o?Mn:"",Yt?At:null,fn,JSON.stringify([c==="branch"?Wt:"",c==="pr"?P.revision:0,Tn])),Pn=vt?.length??null,D=r.useMemo(()=>{if(c==="commit"||c==="pr")return(P.files??[]).map(d=>({path:d.path,index:"",working_dir:d.status,insertions:d.insertions,deletions:d.deletions,isNew:d.status==="A"}));if(c==="branch")return(vt??[]).map(d=>({path:d.path,index:"",working_dir:d.status,insertions:0,deletions:0,isNew:d.status==="A"})).sort((d,h)=>d.path.localeCompare(h.path));if(c==="turn")return Me.map(d=>({path:d.file??"",index:"",working_dir:nr(d.status),insertions:d.additions??0,deletions:d.deletions??0,isNew:d.status==="added"})).filter(d=>d.path).sort((d,h)=>d.path.localeCompare(h.path));if(!y?.files)return[];const t=y.diffStats,i=c==="staged"?mn:c==="working"?pn:()=>!0,l=d=>{const h=t?.staged?.[d],F=t?.working?.[d];return c==="staged"?{insertions:h?.insertions??0,deletions:h?.deletions??0}:c==="working"?{insertions:F?.insertions??0,deletions:F?.deletions??0}:{insertions:(h?.insertions??0)+(F?.insertions??0),deletions:(h?.deletions??0)+(F?.deletions??0)}};return y.files.filter(i).map(d=>{const h=l(d.path);return{...d,insertions:h.insertions,deletions:h.deletions,isNew:er(d)}}).sort((d,h)=>d.path.localeCompare(h.path))},[c,vt,P.files,Me,y]),Et=r.useMemo(()=>D.map(t=>t.path).join("\0"),[D]);r.useEffect(()=>{const t=Et?Et.split("\0"):[],i=new Set(t),l=`${f??""}:${c}:${s?"collapsed":"default"}`,d=z.current!==l;z.current=l,A(h=>{if(d){const B=s?0:Xs(t.length);return new Set(t.slice(0,B))}let F=!1;const R=new Set;for(const B of h){if(!i.has(B)){F=!0;continue}R.add(B)}return F?R:h}),H(h=>{if(d)return new Set;let F=!1;const R=new Set;for(const B of h){if(!i.has(B)){F=!0;continue}R.add(B)}return F?R:h})},[c,Et,f,s]);const Zt=r.useCallback(()=>{if(x.current=null,!o)return;const t=oe.current;if(!t)return;const i=t.getBoundingClientRect(),l=i.top-dn,d=i.bottom+dn,h={},F=[];for(const[R,B]of Ee.current){if(!B)continue;const Y=B.getBoundingClientRect();F.push({path:R,top:Y.top}),W.has(R)&&(Y.bottom<l||Y.top>d||(h[R]=!0))}he.current=ln(i.top,F),H(R=>{let B=!1;const Y=new Set(R);for(const gt of Object.keys(h))Y.has(gt)||(Y.add(gt),B=!0);return B?Y:R})},[W,o]),ge=r.useCallback(()=>{o&&(typeof window>"u"||x.current===null&&(x.current=window.requestAnimationFrame(Zt)))},[Zt,o]);r.useEffect(()=>{const t=oe.current;if(!(!o||!t))return ge(),t.addEventListener("scroll",ge,{passive:!0}),window.addEventListener("resize",ge),()=>{t.removeEventListener("scroll",ge),window.removeEventListener("resize",ge),x.current!==null&&(window.cancelAnimationFrame(x.current),x.current=null)}},[D,W,ge,o]);const Tt=r.useCallback(t=>{const i=He[t.path];if(i)return i;if(et==="inline")return"inline";if(et==="side-by-side")return"side-by-side";const l=I<qs;return t.isNew||l?"inline":"side-by-side"},[He,et,I]),en=r.useMemo(()=>D.length===0?null:D.every(t=>Tt(t)==="side-by-side")?"side-by-side":"inline",[D,Tt]);r.useEffect(()=>{o&&f&&(X(f),ue(f,j))},[f,X,ue,j,o]);const jt=JSON.stringify([E,f]),Lt=r.useRef({scope:jt,paths:new Set,dirty:!1,unscoped:!1}),tn=r.useRef(o);r.useEffect(()=>{const t=o&&!tn.current;if(tn.current=o,Lt.current.scope!==jt&&(Lt.current={scope:jt,paths:new Set,dirty:!1,unscoped:!1}),!f)return;const i=(d,h)=>{d.length&&(Le.current=Z()??he.current,ye(f,d),ct(F=>{const R=new Map(F);for(const B of d)R.set(B,(R.get(B)??0)+1);return R})),h&&Ft(F=>F+1),xe(f,j,{silent:!0})},l=Lt.current;return o&&(t||l.dirty)&&(i([...l.paths],l.unscoped),l.paths.clear(),l.dirty=!1,l.unscoped=!1),yn.onGitRefreshHint(d=>{if(hn(d.directory)!==hn(f))return;const h=d.paths??[],F=h.length===0;if(!o){l.dirty=!0,l.unscoped||=F;for(const R of h)l.paths.add(R);return}i(h,F)})},[Z,ye,f,xe,j,jt,o]),r.useLayoutEffect(()=>{const t=Le.current;if(!t)return;Le.current=null;const i=oe.current,l=Ee.current.get(t.path);if(!i||!l)return;const d=i.getBoundingClientRect().top,h=l.getBoundingClientRect().top-d;i.scrollTop=Hs(i.scrollTop,t.topOffset,h,i.scrollHeight-i.clientHeight),he.current=t},[Ke]),r.useEffect(()=>{!o||c!=="all"&&!Ae||ie&&(Ae&&De(Ae),te(ie),$(Ae==="staged"||!Ae&&we),We(null),Te.current=!0,be.current=ie,Ne(ie),Oe(t=>t+1))},[c,Ne,ie,Ae,we,We,o]),r.useEffect(()=>{if(c==="all")return;const t=k?.trim();t&&(te(t),$(c==="staged"),Te.current=!0,be.current=t,Ne(t),Oe(i=>i+1))},[c,Ne,k]),r.useEffect(()=>{if(!_)return;D.some(i=>i.path===_)||(te(null),$(!1))},[D,_]);const _n=r.useCallback((t,i)=>{const l=Ee.current;i?l.set(t,i):l.delete(t),ge()},[ge]),zn=r.useCallback((t,i)=>{Ve(),A(l=>{const d=l.has(t);if(i===d)return l;const h=new Set(l);return i?h.add(t):h.delete(t),h}),i||H(l=>{if(!l.has(t))return l;const d=new Set(l);return d.delete(t),d}),ge()},[Ve,ge]),On=r.useCallback(()=>{Ve(),A(t=>t.size>0?new Set:new Set(D.map(i=>i.path))),H(new Set),ge()},[Ve,D,ge]),Kn=r.useCallback(async t=>{if(!pe)return;const i=an.getState().getDirectoryForSession(pe)||p||"";if(!i){Ye.error(a("diffView.reviewDialog.toast.noSessionDirectory"));return}Ge(!0);try{await Cs({originalSessionID:pe,directory:i,providerID:t.providerID,modelID:t.modelID,agent:t.agent||void 0,variant:t.variant||void 0,generateHandoff:t.generateHandoff,returnAfterHandoffRequest:t.generateHandoff,autoReview:t.autoReview}),$e(!1)}catch(l){console.error("[review-flow] failed to start review flow",l),Ye.error(l instanceof Error?l.message:a("diffView.reviewDialog.toast.startFailed"))}finally{Ge(!1)}},[pe,p,a]),kt=r.useCallback(t=>{const i=Ee.current.get(t),l=oe.current;if(!i||!l)return!1;const d=i.getBoundingClientRect().top-l.getBoundingClientRect().top;return l.scrollTo({top:l.scrollTop+d,behavior:"auto"}),!0},[]);r.useEffect(()=>{const t=be.current;if(!o||!t)return;let i=0;const l=20;let d=!1;const h=(R=!0)=>{d||(d=!0,be.current=null,Te.current=!1,R&&T(null),q.current!==null&&(window.cancelAnimationFrame(q.current),q.current=null))},F=()=>{if(d){q.current=null;return}const R=be.current;if(!R){h(),q.current=null;return}if(!kt(R)){i+=1,i<l?q.current=window.requestAnimationFrame(F):(h(),q.current=null);return}if(u&&Te.current){T(R),h(!1);return}h()};return q.current=window.requestAnimationFrame(F),()=>{d=!0,q.current!==null&&(window.cancelAnimationFrame(q.current),q.current=null)}},[u,xt,kt,o]);const $n=r.useCallback(t=>{},[]),ve=G==="tree"&&!Ue,Gn=Q(t=>t.diffFileTreeWidth),St=Q(t=>t.setDiffFileTreeWidth),nn=r.useRef(null),[Wn,sn]=r.useState(!1),mt=Math.max(Gn,Bt),Nt=r.useCallback(t=>{const i=Math.max(Bt,(nn.current?.clientWidth??0)*ir);return Math.min(i,Math.max(Bt,t))},[]),Hn=r.useCallback(t=>{t.preventDefault();const i=t.clientX,l=mt;sn(!0);const d=F=>{St(Nt(l+F.clientX-i))},h=()=>{sn(!1),window.removeEventListener("pointermove",d),window.removeEventListener("pointerup",h),window.removeEventListener("pointercancel",h)};window.addEventListener("pointermove",d),window.addEventListener("pointerup",h),window.addEventListener("pointercancel",h)},[Nt,mt,St]),qn=r.useCallback(t=>{const i=t.shiftKey?40:10,l=t.key==="ArrowLeft"?-i:t.key==="ArrowRight"?i:0;l!==0&&(t.preventDefault(),St(Nt(mt+l)))},[Nt,mt,St]),Vt=r.useMemo(()=>ve?bn(D,new Set).flatMap(t=>t.kind==="file"?[t.file]:[]):[],[D,ve]),pt=ve?Vt:D,ht=ve?Vt.find(t=>t.path===_)??Vt[0]??null:null,Ct=r.useCallback(t=>{if(Ve(),ve){te(t),$(!1),Ne(t),oe.current?.scrollTo({top:0});return}te(t),$(!1),Te.current=!0,be.current=t,Ne(t),Oe(i=>i+1),kt(t)},[Ve,Ne,ve,kt]);r.useEffect(()=>{const t=i=>{if(!o||!i.altKey||i.metaKey||i.ctrlKey||i.shiftKey||i.key!=="ArrowDown"&&i.key!=="ArrowUp")return;const l=i.target;if(l instanceof HTMLElement&&(l.isContentEditable||l.tagName==="INPUT"||l.tagName==="TEXTAREA"||l.closest('[role="dialog"]'))||pt.length===0)return;const d=i.key==="ArrowDown"?1:-1,h=ve?ht?.path:_,F=h?pt.findIndex(Y=>Y.path===h):-1,R=F===-1?d>0?0:pt.length-1:F+d,B=pt[R];B&&(i.preventDefault(),Ct(B.path))};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[_,Ct,ve,pt,ht,o]);const Un=r.useCallback(t=>{const i=t==="side-by-side"?"side-by-side":"inline";D.forEach(l=>{Se(l.path,i)})},[D,Se]),[Xn,rn]=r.useState(null),Jn=r.useCallback(async(t,i)=>{if(!f||!t)return;rn(t);const l=Re();try{let d=null;if(i?.patch&&!i.isBinary&&!lt(t)?d=cn(i.patch):i&&i.contextMode==="full"&&!i.isBinary&&!lt(t)&&(d=gn(i.original,i.modified)),d===null)try{const Y=await j.getGitDiff(f,{path:t,staged:qe,contextLines:3});d=cn(Y.diff)}catch{d=null}let h=i;if(d===null||!h){const Y=await j.getGitFileDiff(f,{path:t,staged:qe}),gt={original:Y.original??"",modified:Y.modified??"",isBinary:Y.isBinary,submodule:Y.submodule};h=gt,qe||ee(f,t,gt,l)}const F=d??(h.isBinary||lt(t)?1:gn(h.original,h.modified)),R=tr(f,t),B=await Ps(N,R,{directory:f});if(!B.ok){Ye.error(_s(B.reason));return}me(f,R,F,1)}finally{rn(d=>d===t?null:d)}},[qe,f,N,j,me,ee]),Yn=()=>{if(!f)return null;const t=(l,d=!1)=>n.jsx(cr,{visible:o,directory:f,file:l,layout:Tt(l),wrapLines:nt,isSelected:!1,isExpanded:d||W.has(l.path),isMounted:d||de.has(l.path)||l.path===ke,onSelect:$n,onExpandedChange:zn,registerSectionRef:_n,showOpenInEditorAction:g&&c!=="turn",isOpeningInEditor:Xn===l.path,onOpenInEditor:(h,F)=>{Jn(h,F)},staged:i(l.path),readOnlyActions:c==="branch"||c==="commit"||c==="pr",hunkActionsEnabled:c==="all"||c==="working"||c==="staged",contentRevision:yt,comparisonDiff:c==="branch"||c==="commit"||c==="pr"?In.get(l.path)??fn:void 0,onRetryComparisonDiff:()=>Ln(h=>h+1),loadFullComparisonDiff:Bn,initialDiffData:c==="turn"?L.get(l.path)??null:null},`${Re()}:${f}:${l.path}:${Ke.get(l.path)??0}`),i=l=>st!==null?st:ne&&l===_;return n.jsxs("div",{ref:nn,className:le("flex min-w-0 flex-1 min-h-0 h-full",v?"gap-0":"gap-3 px-3 pb-3 pt-2"),children:[ve&&n.jsxs(n.Fragment,{children:[n.jsx("section",{className:"flex max-w-[50%] flex-shrink-0 flex-col",style:{width:`${mt}px`},children:n.jsx(or,{changedFiles:D,selectedFile:ht?.path??null,onSelectFile:Ct})}),n.jsx("div",{role:"separator","aria-orientation":"vertical","aria-label":a("diffView.fileTree.resize"),tabIndex:0,onPointerDown:Hn,onKeyDown:qn,className:le("relative w-px shrink-0 cursor-col-resize bg-[var(--interactive-border)]/40","before:absolute before:inset-y-0 before:-left-1 before:-right-1 before:content-['']","hover:bg-interactive-selection focus-visible:bg-interactive-selection focus-visible:outline-none",Wn&&"bg-interactive-selection")})]}),bt&&!ve&&n.jsxs("section",{className:"hidden lg:flex w-72 flex-col rounded-xl border border-border/60 bg-background/70 overflow-hidden",children:[n.jsxs("div",{className:"flex items-center justify-between px-3 py-1.5 border-b border-border/40",children:[n.jsx("span",{className:"typography-ui-header font-semibold text-foreground",children:a("diffView.section.files")}),n.jsx("span",{className:"typography-meta text-muted-foreground",children:D.length})]}),n.jsx(rr,{changedFiles:D,selectedFile:null,onSelectFile:Ct})]}),n.jsx("div",{className:"relative flex-1 min-w-0 min-h-0 h-full",children:n.jsx(zt,{ref:oe,outerClassName:"min-h-0 h-full",className:"[overflow-anchor:none] pb-16",disableHorizontal:!0,observeMutations:!1,preventOverscroll:!0,"data-diff-virtual-root":!0,children:n.jsx("div",{className:"flex flex-col [overflow-anchor:none]","data-diff-virtual-content":!0,children:ve?ht&&t(ht,!0):D.map(l=>t(l))})})})]})},Qn=()=>{if(!f)return n.jsx("div",{className:"flex flex-1 items-center justify-center text-sm text-muted-foreground",children:a("diffView.state.selectSessionDirectory")});if(c!=="turn"&&K&&!y)return n.jsxs("div",{className:"flex flex-1 items-center justify-center gap-2 text-sm text-muted-foreground",children:[n.jsx(O,{name:"loader-4",className:"size-4 animate-spin"}),a("diffView.state.loadingRepositoryStatus")]});if(c!=="turn"&&U===!1)return n.jsx("div",{className:"flex flex-1 items-center justify-center text-sm text-muted-foreground",children:a("diffView.state.notGitRepository")});if(c==="pr"){if(!Pe||P.error)return n.jsxs("div",{className:"flex flex-1 flex-col items-center justify-center gap-3 p-6 text-center",children:[n.jsx("p",{className:"typography-meta text-muted-foreground",children:P.error??Ie.error??(Ie.loading?a("session.githubPrPicker.loading.pullRequests"):a("pullRequestComparison.select"))}),(P.error||Ie.error)&&n.jsx(je,{variant:"outline",size:"sm",onClick:()=>{Pe?P.refresh():Ie.refresh()},children:a("diffView.actions.retry")}),!Pe&&!Ie.loading&&n.jsx(on,{comparison:Ie})]});if(!P.files)return n.jsxs("div",{className:"flex flex-1 items-center justify-center gap-2 typography-meta text-muted-foreground",children:[n.jsx(O,{name:"loader-4",className:"size-4 animate-spin"}),a("diffView.state.loadingDiff")]})}if(c==="commit"){if(Xt)return n.jsxs("div",{className:"flex flex-1 flex-col items-center justify-center gap-3 p-6 text-center",children:[n.jsx("p",{className:"typography-meta text-muted-foreground",children:Xt}),n.jsx(je,{variant:"outline",size:"sm",onClick:()=>{P.refresh()},children:a("diffView.actions.retry")})]});if(!Je&&!_e.loading)return n.jsx("div",{className:"flex flex-1 items-center justify-center text-sm text-muted-foreground",children:_e.error??a("commitComparison.noCommits")});if(!Ut)return n.jsxs("div",{className:"flex flex-1 items-center justify-center gap-2 text-sm text-muted-foreground",children:[n.jsx(O,{name:"loader-4",className:"size-4 animate-spin"}),a("diffView.state.loadingDiff")]})}if(c==="branch"){if(!En)return n.jsxs("div",{className:"flex flex-1 items-center justify-center gap-2 text-sm text-muted-foreground",children:[n.jsx(O,{name:"loader-4",className:"size-4 animate-spin"}),a("diffView.branch.resolvingBase")]});if(!Ce)return n.jsxs("div",{className:"flex flex-1 flex-col items-center justify-center gap-3 px-6 text-center",children:[n.jsx(O,{name:"git-branch",className:"size-6 text-muted-foreground"}),n.jsx("div",{className:"typography-ui-label font-semibold text-foreground",children:a("diffView.branch.noBaseTitle")}),n.jsx("div",{className:"max-w-sm typography-micro text-muted-foreground",children:a("gitView.pr.toast.baseBranchRequired")})]});if(Jt)return n.jsxs("div",{className:"flex flex-1 flex-col items-center justify-center gap-3 px-6 text-center",children:[n.jsx("div",{className:"typography-ui-label font-semibold text-foreground",children:a("diffView.branch.loadError")}),n.jsx("div",{className:"max-w-sm typography-micro text-muted-foreground",children:Jt}),n.jsx(je,{variant:"outline",size:"sm",onClick:()=>{P.refresh()},children:a("diffView.actions.retry")})]});if(vt===null)return n.jsxs("div",{className:"flex flex-1 items-center justify-center gap-2 text-sm text-muted-foreground",children:[n.jsx(O,{name:"loader-4",className:"size-4 animate-spin"}),a("diffView.branch.loadingFiles")]})}return D.length===0?n.jsx("div",{className:"flex flex-1 items-center justify-center text-sm text-muted-foreground",children:c==="turn"?a("diffView.state.noLastTurnChanges"):c==="pr"?a("walkthrough.blocked.emptyDiff.description"):c==="commit"?a("commitComparison.emptyDiff"):c==="branch"&&Ce?a("diffView.branch.empty",{base:Ms(Ce)}):a("diffView.state.cleanWorkingTree")}):Yn()};return n.jsxs("div",{className:"flex h-full flex-col overflow-hidden bg-background",children:[n.jsxs("div",{className:"@container/diff-toolbar flex min-w-0 items-center gap-2 px-3 py-2 bg-background",children:[b===!1&&Array.isArray(V)&&V.length>0?n.jsx(Vs,{repositories:V,selectedRepository:C??null,onSelectRepository:t=>{p&&se(p,t)},repositoryRoot:p??void 0}):null,!ce&&(c!=="all"?n.jsx(sr,{scope:c,workingCount:ft,stagedCount:Be,turnCount:Xe,branchCount:Pn,commitCount:c==="commit"?Ut?.length??null:null,prCount:c==="pr"?P.files?.length??null:null,showCommitOption:!Fe(),showBranchOption:$t,onScopeChange:t=>{De(t),w?.(t)}}):n.jsx("div",{className:"flex items-center gap-1 rounded-md px-2 py-1 text-muted-foreground shrink-0",children:n.jsx("span",{className:"typography-ui-label font-semibold text-foreground",children:K&&!y?a("diffView.state.loadingChanges"):D.length===1?a("diffView.summary.changedFilesSingle",{count:D.length}):a("diffView.summary.changedFilesPlural",{count:D.length})})})),c==="branch"&&n.jsx(is,{branches:ot?.all??[],currentBranch:J,base:Ce,onSelect:t=>{f&&J&&An(f,J,t)}},JSON.stringify([f,J])),c==="commit"&&n.jsx(os,{commits:_e.commits,selectedHash:Je,loading:_e.loading,error:_e.error,onSelect:_e.select,onRefresh:()=>{_e.refresh()}},JSON.stringify([f,J])),c==="pr"&&n.jsxs(n.Fragment,{children:[n.jsx(on,{comparison:Ie},JSON.stringify([E,f,J])),Pe&&n.jsx(je,{variant:"ghost",size:"sm",disabled:P.loading,"aria-label":a("session.githubIssuePicker.actions.refresh"),title:a("session.githubIssuePicker.actions.refresh"),onClick:()=>{P.refresh()},children:n.jsx(O,{name:"refresh",className:"size-4"})})]}),D.length>0&&n.jsxs(je,{variant:"ghost",size:"sm",onClick:On,className:le("diff-toolbar__expand-button h-7 flex-shrink-0 gap-1 px-1.5 text-muted-foreground hover:text-foreground","ml-auto"),title:W.size>0?a("diffView.actions.collapseAll"):a("diffView.actions.expandAll"),children:[n.jsx(O,{name:"expand-up-down",className:"size-4"}),n.jsx("span",{className:"diff-toolbar__expand-label typography-ui-label",children:W.size>0?a("diffView.actions.collapseAll"):a("diffView.actions.expandAll")})]}),D.length>0&&Rt&&n.jsxs(je,{variant:"default",size:"sm",onClick:()=>$e(!0),disabled:Ze,className:"diff-toolbar__review-button h-7 flex-shrink-0 gap-1.5 px-2","aria-label":a("diffView.actions.reviewAria"),children:[Ze?n.jsx(O,{name:"loader-4",className:"size-4 animate-spin"}):n.jsx(O,{name:"search-eye",className:"size-4"}),n.jsx("span",{className:"diff-toolbar__review-label typography-ui-label",children:a("diffView.actions.review")})]}),D.length>0&&rt&&n.jsxs(je,{variant:"outline",size:"sm",onClick:()=>{const t=f??"";M(t,c==="pr"&&Pe?Pe:c==="commit"&&Je?{kind:"commit",hash:Je}:c==="branch"&&Ce&&J?{kind:"branch",baseRef:Ce,headRef:J}:{kind:"working-tree",scope:c==="staged"||c==="working"?c:"all"}),S(p??t,"walkthrough")},className:le("diff-toolbar__walkthrough-button h-7 flex-shrink-0 gap-1.5 px-2",zs),"aria-label":a("walkthrough.action.open"),children:[n.jsx(O,{name:"route",className:"size-4"}),n.jsx("span",{className:"diff-toolbar__walkthrough-label typography-ui-label",children:a("walkthrough.action.open")})]}),D.length>0&&!Ue&&n.jsx(je,{variant:"ghost",size:"sm",onClick:()=>wt(G==="tree"?"flat":"tree"),"aria-pressed":G==="tree",className:le("h-5 w-5 p-0 transition-opacity",G==="tree"?"text-foreground opacity-100":"text-muted-foreground opacity-60 hover:opacity-100"),title:a(G==="tree"?"diffView.fileTree.showAsList":"diffView.fileTree.showAsTree"),children:n.jsx(O,{name:"node-tree",className:"size-4"})}),D.length>0&&n.jsx(je,{variant:"ghost",size:"sm",onClick:()=>tt(!fe),className:le("h-5 w-5 p-0 transition-opacity",nt?"text-foreground opacity-100":"text-muted-foreground opacity-60 hover:opacity-100"),title:a(nt?"diffView.actions.disableLineWrap":"diffView.actions.enableLineWrap"),children:n.jsx(O,{name:"text-wrap",className:"size-4"})}),en&&n.jsx(wn,{mode:en==="side-by-side"?"side-by-side":"unified",onModeChange:Un})]}),n.jsx(Fs,{open:ut,onOpenChange:$e,projectDirectory:f??null,submitting:Ze,onConfirm:Kn}),Qn()]})};function ur(){return new Set}function dr(o,e){return n.jsx("span",{"aria-hidden":!0,className:"pointer-events-none absolute inset-y-0 w-px bg-border/50",style:{left:`${Nn+e*Sn+7}px`}},e)}function fr(o){return Array.from({length:o},dr)}export{Vo as DiffView,cr as MultiFileDiffEntry};
|