@vantran-se/openchamber-web 1.22.1 → 1.22.2
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 +2 -3
- package/bin/cli.js +4 -1
- package/bin/cli.test.js +92 -0
- package/bin/lib/cli-startup.js +49 -0
- package/bin/lib/commands-startup.js +41 -6
- package/dist/assets/{CodeMirrorCommentWidgets-C53Q7pbX.js → CodeMirrorCommentWidgets-CV1HNV5l.js} +1 -1
- package/dist/assets/{DiffView-Dh1ey2x9.js → DiffView-DkkSa30n.js} +3 -3
- package/dist/assets/DirtyBranchSwitchDialog-DW4WaXPc.js +1 -0
- package/dist/assets/FilesView-DDu8zDy5.js +17 -0
- package/dist/assets/GitView-1Ixo8z-M.js +6 -0
- package/dist/assets/{JsonTreeView-Bl0lp9Rs.js → JsonTreeView-DvCLL7dT.js} +1 -1
- package/dist/assets/LinearIssuesView-Bs1rZrF2.js +1 -0
- package/dist/assets/{MarkdownImageGallery-bA0PS-tn.js → MarkdownImageGallery-DyJUc6h9.js} +1 -1
- package/dist/assets/MarkdownRendererImpl-Bdm8vMkS.js +12 -0
- package/dist/assets/{OnboardingScreen-D3kYJIb6.js → OnboardingScreen-Dg66B6oB.js} +1 -1
- package/dist/assets/{PatchDiff-D6NXAfJk.js → PatchDiff-CAduNjfZ.js} +1 -1
- package/dist/assets/{PierreDiffViewer-Ct2A13NO.js → PierreDiffViewer-CTIb1GYD.js} +2 -2
- package/dist/assets/PlanView-trDaszfq.js +5 -0
- package/dist/assets/SettingsView-DStMfBmy.js +28 -0
- package/dist/assets/{SettingsWindow-BiWDBRvb.js → SettingsWindow-DQQFnrSZ.js} +1 -1
- package/dist/assets/{ToolOutputDialog-BQexMQIm.js → ToolOutputDialog-SjY2XZlA.js} +6 -6
- package/dist/assets/ToolPartDiffPreview-DJdzUQPE.js +8 -0
- package/dist/assets/{VirtualizedFileDiff-Dpz2ra8h.js → VirtualizedFileDiff-Iehm4iMH.js} +1 -1
- package/dist/assets/{WalkthroughView-AX-u2pFg.js → WalkthroughView-BALp2d9O.js} +2 -2
- package/dist/assets/{computeVirtualFileMetrics-DtyozJdt.js → computeVirtualFileMetrics-BKZA43vN.js} +2 -2
- package/dist/assets/{contextPanelEmbeddedChat-C9EcRSDF.js → contextPanelEmbeddedChat-D2PM_pEv.js} +1 -1
- package/dist/assets/{de-DqVn5vme.js → de-DlSNLAcy.js} +6 -5
- package/dist/assets/{es-hj43Z53i.js → es-D1GbowZ3.js} +6 -5
- package/dist/assets/{fr-BmkZt2mF.js → fr-BPOLXIAY.js} +6 -5
- package/dist/assets/{index-DmhujXbT.js → index-Ce0LR32V.js} +1 -1
- package/dist/assets/index-D42fPvt4.css +1 -0
- package/dist/assets/index-DlFbCkEy.js +39 -0
- package/dist/assets/{isDiffPlainText-XyulMHxx.js → isDiffPlainText-DaB2u_Kv.js} +1 -1
- package/dist/assets/{isFilePlainText-B19Ddps1.js → isFilePlainText-yJZa2IAC.js} +1 -1
- package/dist/assets/{ja-DioMIEGF.js → ja-Dm2-m9io.js} +7 -6
- package/dist/assets/{ko-BqPgaQJb.js → ko-CIXlzQ5-.js} +7 -6
- package/dist/assets/main-B7qTsd_w.js +930 -0
- package/dist/assets/{main-B2a_JfKZ.js → main-CyQrD9dG.js} +2 -2
- package/dist/assets/{markdownCore-CWRCqSH2.js → markdownCore-CeEwGgEK.js} +2 -2
- package/dist/assets/{miniChat-B3CSU_Ps.js → miniChat-7cPEx4sV.js} +2 -2
- package/dist/assets/{mobile-QNcFIVCW.js → mobile-QtzkPTM8.js} +2 -2
- package/dist/assets/{patchFileDiff-BpMQZnYu.js → patchFileDiff-No55fDiD.js} +1 -1
- package/dist/assets/pl-B2zmkOpw.js +16 -0
- package/dist/assets/{pt-BR-BqH8fuCH.js → pt-BR-C-JE5H6y.js} +6 -5
- package/dist/assets/{renderElectronMiniChatApp-D77bmLqo.js → renderElectronMiniChatApp-ePTkBJNS.js} +2 -2
- package/dist/assets/renderMobileApp-D9RjB9DX.js +25 -0
- package/dist/assets/runtimeEndpointReset-DfJIWwwo.js +17 -0
- package/dist/assets/{scheduledTasksApi-BSRCtP6T.js → scheduledTasksApi-DuhdyYEa.js} +1 -1
- package/dist/assets/{shikiHighlight-DE-OwqGw.js → shikiHighlight-EHEg58-n.js} +1 -1
- package/dist/assets/tr-MJmRIzEY.js +7 -0
- package/dist/assets/{uk-BkkfxbOs.js → uk-BmD7eM8k.js} +6 -5
- package/dist/assets/{useAppFontEffects-COAeIX-D.js → useAppFontEffects-CuJPKtI1.js} +151 -180
- package/dist/assets/useInlineCommentController-DD7_7OP_.js +2 -0
- package/dist/assets/{useRootScrollLock-C0N9mCwz.js → useRootScrollLock-DRGAe8PN.js} +1 -1
- package/dist/assets/{vendor-codemirror-language-data-BG3v1Ghq.js → vendor-codemirror-language-data-9ZzoH0o0.js} +2 -2
- package/dist/assets/vendor-zod-CK21ihK-.js +39 -0
- package/dist/assets/{web-components-BNMwa0qm.js → web-components-PttKBrhi.js} +1 -1
- package/dist/assets/{zh-CN-C6FMdVgv.js → zh-CN-JJHl4ehT.js} +6 -5
- package/dist/assets/{zh-TW-CdcMjDxv.js → zh-TW-DPc4DEEW.js} +6 -5
- package/dist/index.html +5 -5
- package/dist/mini-chat.html +4 -4
- package/dist/mobile.html +4 -4
- package/package.json +8 -4
- package/server/index.js +38 -5
- package/server/lib/agent-tool/runtime.js +2 -19
- package/server/lib/changelog/update-notes.js +82 -0
- package/server/lib/changelog/update-notes.test.js +59 -0
- package/server/lib/dev-tunnel/DOCUMENTATION.md +13 -4
- package/server/lib/dev-tunnel/runtime.js +4 -4
- package/server/lib/dev-tunnel/tunnel.test.js +20 -0
- package/server/lib/fs/DOCUMENTATION.md +2 -0
- package/server/lib/fs/routes.js +32 -21
- package/server/lib/fs/routes.test.js +77 -0
- package/server/lib/git/DOCUMENTATION.md +3 -1
- package/server/lib/git/routes.js +16 -0
- package/server/lib/git/service.js +107 -17
- package/server/lib/git/service.test.js +171 -0
- package/server/lib/mcp-reconnect/DOCUMENTATION.md +55 -0
- package/server/lib/mcp-reconnect/runtime.js +122 -0
- package/server/lib/mcp-reconnect/runtime.test.js +140 -0
- package/server/lib/message-queue/DOCUMENTATION.md +158 -0
- package/server/lib/message-queue/runtime.js +870 -0
- package/server/lib/message-queue/runtime.test.js +482 -0
- package/server/lib/openchamber-sessions/routes.js +102 -0
- package/server/lib/openchamber-sessions/routes.test.js +88 -0
- package/server/lib/opencode/DOCUMENTATION.md +13 -5
- package/server/lib/opencode/config-paths.test.js +116 -0
- package/server/lib/opencode/core-routes.js +1 -0
- package/server/lib/opencode/feature-routes-runtime.js +5 -0
- package/server/lib/opencode/input-history-scope.js +14 -0
- package/server/lib/opencode/managed-plugin-config.js +35 -0
- package/server/lib/opencode/openchamber-routes.test.js +2 -2
- package/server/lib/opencode/plugins.js +2 -2
- package/server/lib/opencode/providers.js +44 -2
- package/server/lib/opencode/providers.test.js +131 -4
- package/server/lib/opencode/routes.js +4 -4
- package/server/lib/opencode/server-startup-runtime.js +1 -1
- package/server/lib/opencode/settings-helpers.js +28 -0
- package/server/lib/opencode/settings-helpers.test.js +177 -0
- package/server/lib/opencode/settings-runtime.js +2 -2
- package/server/lib/opencode/settings-runtime.test.js +29 -0
- package/server/lib/opencode/shared.js +4 -1
- package/server/lib/opencode/shutdown-runtime.js +2 -0
- package/server/lib/opencode/skill-routes.js +2 -1
- package/server/lib/opencode/snippets.js +1 -2
- package/server/lib/package-manager.js +4 -29
- package/server/lib/package-manager.test.js +2 -2
- package/server/lib/quota/DOCUMENTATION.md +2 -1
- package/server/lib/quota/credentials/providers.js +4 -0
- package/server/lib/quota/credentials/store.js +1 -1
- package/server/lib/quota/credentials/store.test.js +4 -4
- package/server/lib/quota/providers/exe-dev.js +75 -0
- package/server/lib/quota/providers/exe-dev.test.js +47 -0
- package/server/lib/quota/providers/index.js +7 -0
- package/server/lib/quota/providers/opencode-go.js +1 -0
- package/server/lib/quota/providers/opencode-go.test.js +5 -1
- package/server/lib/quota/routes.js +2 -0
- package/server/lib/quota/utils/auth.js +1 -1
- package/server/lib/relay/DOCUMENTATION.md +1 -1
- package/server/lib/relay/host-client.test.js +9 -1
- package/server/lib/relay/tunnel-host.js +3 -1
- package/server/lib/relay/tunnel-host.test.js +9 -1
- package/server/lib/security/request-security.js +21 -6
- package/server/lib/security/request-security.test.js +42 -8
- package/server/lib/session-assist/runtime.js +1 -0
- package/server/lib/session-goal/DOCUMENTATION.md +20 -7
- package/server/lib/session-goal/create.js +3 -1
- package/server/lib/session-goal/runtime.js +77 -11
- package/server/lib/session-goal/runtime.test.js +426 -0
- package/server/lib/skills-catalog/DOCUMENTATION.md +1 -1
- package/server/lib/skills-catalog/install.js +3 -2
- package/server/lib/small-model/DOCUMENTATION.md +4 -0
- package/server/lib/small-model/call.js +8 -2
- package/server/lib/small-model/call.test.js +23 -0
- package/server/lib/small-model/index.js +2 -1
- package/server/lib/small-model/routes.js +2 -1
- package/server/lib/system-prompt/runtime.js +2 -21
- package/server/lib/terminal/DOCUMENTATION.md +11 -7
- package/server/lib/terminal/runtime.js +180 -26
- package/server/lib/terminal/runtime.test.js +553 -26
- package/server/lib/terminal/shells.js +17 -0
- package/server/lib/terminal/shells.test.js +32 -1
- package/server/lib/ui-auth/ui-auth.js +4 -1
- package/server/lib/ui-auth/ui-auth.test.js +16 -0
- package/server/lib/walkthrough/index.js +1 -0
- package/server/lib/walkthrough/routes.test.js +26 -5
- package/dist/assets/CommitSection-X-f2RgYr.js +0 -1
- package/dist/assets/FilesView-3ZYP72ki.js +0 -17
- package/dist/assets/GitView-CMuN7z2Z.js +0 -6
- package/dist/assets/LinearIssuesView-CQiUDU8b.js +0 -1
- package/dist/assets/MarkdownRendererImpl-BGQi2PLq.js +0 -12
- package/dist/assets/PlanView-6AUjzNQn.js +0 -5
- package/dist/assets/SettingsView-CHI8fFaK.js +0 -28
- package/dist/assets/ToolPartDiffPreview-DPAATNn6.js +0 -8
- package/dist/assets/index-L_ncV-6H.css +0 -1
- package/dist/assets/index-qES19dlJ.js +0 -7
- package/dist/assets/main-CYgSu6dx.js +0 -928
- package/dist/assets/pl-slULBF4R.js +0 -15
- package/dist/assets/renderMobileApp-BQ3Kdm-d.js +0 -25
- package/dist/assets/runtimeEndpointReset-CRGn1gVj.js +0 -16
- package/dist/assets/tr-CjEbw1Aw.js +0 -6
- package/dist/assets/useInlineCommentController-JsBboQwt.js +0 -2
- package/dist/assets/vendor-zod-BLfBSgBh.js +0 -39
package/README.md
CHANGED
|
@@ -14,14 +14,13 @@ Full project overview, screenshots, and all features: [github.com/openchamber/op
|
|
|
14
14
|
curl -fsSL https://raw.githubusercontent.com/openchamber/openchamber/main/scripts/install.sh | bash
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Install this fork from
|
|
17
|
+
Install this fork from npm:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
npm config set @vantran-se:registry https://npm.pkg.github.com
|
|
21
20
|
npm install -g @vantran-se/openchamber-web
|
|
22
21
|
```
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
The package keeps the `openchamber` command and updates from the same npm package.
|
|
25
24
|
|
|
26
25
|
> **Prerequisites:** [OpenCode CLI](https://opencode.ai) installed, Node.js 22+.
|
|
27
26
|
|
package/bin/cli.js
CHANGED
|
@@ -117,7 +117,10 @@ function getBunBinary() {
|
|
|
117
117
|
return process.env.BUN_BINARY.trim();
|
|
118
118
|
}
|
|
119
119
|
if (typeof process.env.BUN_INSTALL === 'string' && process.env.BUN_INSTALL.trim().length > 0) {
|
|
120
|
-
|
|
120
|
+
// The Windows installer places bun.exe there; spawnSync does not append
|
|
121
|
+
// the extension to an explicit path, so without it the probe fails and
|
|
122
|
+
// the CLI silently falls back to Node.
|
|
123
|
+
return path.join(process.env.BUN_INSTALL.trim(), 'bin', process.platform === 'win32' ? 'bun.exe' : 'bun');
|
|
121
124
|
}
|
|
122
125
|
return 'bun';
|
|
123
126
|
}
|
package/bin/cli.test.js
CHANGED
|
@@ -11,6 +11,7 @@ import { isModuleCliExecution, normalizeCliEntryPath } from './cli-entry.js';
|
|
|
11
11
|
import { requestJson } from './lib/cli-http.js';
|
|
12
12
|
import { requestControlAction } from './lib/cli-control.js';
|
|
13
13
|
import { inspectTunnelAttachability } from './lib/cli-lifecycle.js';
|
|
14
|
+
import { startupCommand } from './lib/commands-startup.js';
|
|
14
15
|
import { formatGoal } from './lib/commands-schedule.js';
|
|
15
16
|
import {
|
|
16
17
|
buildSessionCreatePayload,
|
|
@@ -34,6 +35,7 @@ import {
|
|
|
34
35
|
discoverRunningInstances,
|
|
35
36
|
discoverUnconfirmedRegistryInstanceOnPort,
|
|
36
37
|
ensureTunnelProfilesMigrated,
|
|
38
|
+
EXIT_CODE,
|
|
37
39
|
generateUiPassword,
|
|
38
40
|
getInstanceFilePath,
|
|
39
41
|
getPidFilePath,
|
|
@@ -1456,3 +1458,93 @@ describe('Windows startup task command builder', () => {
|
|
|
1456
1458
|
expect(cmd).not.toContain('-Command ');
|
|
1457
1459
|
});
|
|
1458
1460
|
});
|
|
1461
|
+
|
|
1462
|
+
describe('startup command lingering output', () => {
|
|
1463
|
+
const linuxStatus = (lingerEnabled, lingerUser = 'alice') => ({
|
|
1464
|
+
supported: true,
|
|
1465
|
+
platform: 'linux',
|
|
1466
|
+
enabled: true,
|
|
1467
|
+
active: true,
|
|
1468
|
+
activeState: 'active',
|
|
1469
|
+
servicePath: '/home/alice/.config/systemd/user/openchamber.service',
|
|
1470
|
+
lingerEnabled,
|
|
1471
|
+
lingerUser,
|
|
1472
|
+
});
|
|
1473
|
+
|
|
1474
|
+
const dependenciesFor = (status) => ({
|
|
1475
|
+
getStartupStatus: () => status,
|
|
1476
|
+
enableStartupService: () => status,
|
|
1477
|
+
disableStartupService: () => status,
|
|
1478
|
+
});
|
|
1479
|
+
|
|
1480
|
+
const runCommand = (status, options, action) => startupCommand(options, action, dependenciesFor(status));
|
|
1481
|
+
|
|
1482
|
+
it.each([
|
|
1483
|
+
['enable', true, 'ok', undefined],
|
|
1484
|
+
['enable', false, 'warning', 'LINGER_DISABLED'],
|
|
1485
|
+
['enable', null, 'warning', 'LINGER_UNKNOWN'],
|
|
1486
|
+
['status', true, 'ok', undefined],
|
|
1487
|
+
['status', false, 'warning', 'LINGER_DISABLED'],
|
|
1488
|
+
['status', null, 'warning', 'LINGER_UNKNOWN'],
|
|
1489
|
+
])('reports %s with Linux linger=%s as JSON-only output', async (action, lingerEnabled, expectedStatus, warningCode) => {
|
|
1490
|
+
const output = await captureStdout(() => runCommand(linuxStatus(lingerEnabled), { json: true }, action));
|
|
1491
|
+
const payload = JSON.parse(output);
|
|
1492
|
+
|
|
1493
|
+
expect(payload.status).toBe(expectedStatus);
|
|
1494
|
+
expect(payload.action).toBe(action);
|
|
1495
|
+
expect(payload.lingerEnabled).toBe(lingerEnabled);
|
|
1496
|
+
expect(payload.messages?.[0]?.code).toBe(warningCode);
|
|
1497
|
+
});
|
|
1498
|
+
|
|
1499
|
+
it.each([
|
|
1500
|
+
['enable', true, 'yes'],
|
|
1501
|
+
['enable', false, 'no'],
|
|
1502
|
+
['enable', null, 'unknown'],
|
|
1503
|
+
['status', true, 'yes'],
|
|
1504
|
+
['status', false, 'no'],
|
|
1505
|
+
['status', null, 'unknown'],
|
|
1506
|
+
])('reports %s with Linux linger=%s in one quiet result line', async (action, lingerEnabled, label) => {
|
|
1507
|
+
const output = await captureStdout(() => runCommand(linuxStatus(lingerEnabled), { quiet: true }, action));
|
|
1508
|
+
|
|
1509
|
+
expect(output.split('\n')).toHaveLength(2);
|
|
1510
|
+
expect(output).toContain(` linger:${label}\n`);
|
|
1511
|
+
expect(output).not.toContain('loginctl');
|
|
1512
|
+
});
|
|
1513
|
+
|
|
1514
|
+
it.each([true, false])('warns with an actionable command in human TTY=%s output', async (isTTY) => {
|
|
1515
|
+
const descriptor = Object.getOwnPropertyDescriptor(process.stdout, 'isTTY');
|
|
1516
|
+
Object.defineProperty(process.stdout, 'isTTY', { configurable: true, value: isTTY });
|
|
1517
|
+
try {
|
|
1518
|
+
const output = await captureStdout(() => runCommand(linuxStatus(false), {}, 'enable'));
|
|
1519
|
+
|
|
1520
|
+
expect(output).toContain('[LINGER_DISABLED]');
|
|
1521
|
+
expect(output).toContain('sudo loginctl enable-linger alice');
|
|
1522
|
+
} finally {
|
|
1523
|
+
if (descriptor) Object.defineProperty(process.stdout, 'isTTY', descriptor);
|
|
1524
|
+
else delete process.stdout.isTTY;
|
|
1525
|
+
}
|
|
1526
|
+
});
|
|
1527
|
+
|
|
1528
|
+
it('reports unknown state without inventing a user when detection is unavailable', async () => {
|
|
1529
|
+
const output = await captureStdout(() => runCommand(linuxStatus(null, null), {}, 'status'));
|
|
1530
|
+
|
|
1531
|
+
expect(output).toContain('[LINGER_UNKNOWN]');
|
|
1532
|
+
expect(output).toContain('loginctl show-user "$USER" -p Linger');
|
|
1533
|
+
});
|
|
1534
|
+
|
|
1535
|
+
it('reports disabled-service linger state without warning or remediation', async () => {
|
|
1536
|
+
const output = await captureStdout(() => runCommand({ ...linuxStatus(false), enabled: false }, {}, 'status'));
|
|
1537
|
+
|
|
1538
|
+
expect(output).toContain('user lingering is disabled');
|
|
1539
|
+
expect(output).not.toContain('[LINGER_DISABLED]');
|
|
1540
|
+
expect(output).not.toContain('loginctl enable-linger');
|
|
1541
|
+
});
|
|
1542
|
+
|
|
1543
|
+
it('does not emit linger guidance for unsupported systems', async () => {
|
|
1544
|
+
await expect(runCommand(
|
|
1545
|
+
{ supported: false, platform: 'freebsd', enabled: false, servicePath: null },
|
|
1546
|
+
{ json: true },
|
|
1547
|
+
'status'
|
|
1548
|
+
)).rejects.toMatchObject({ exitCode: EXIT_CODE.USAGE_ERROR });
|
|
1549
|
+
});
|
|
1550
|
+
});
|
package/bin/lib/cli-startup.js
CHANGED
|
@@ -283,6 +283,52 @@ function runStartupCommand(command, args, options = {}) {
|
|
|
283
283
|
return result;
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
+
function parseLingerState(stdout) {
|
|
287
|
+
if (typeof stdout !== 'string') {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
const match = stdout.match(/^Linger=([A-Za-z]+)\s*$/m);
|
|
291
|
+
if (!match) {
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
const value = match[1].toLowerCase();
|
|
295
|
+
if (value === 'yes') return true;
|
|
296
|
+
if (value === 'no') return false;
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function getCurrentUsername() {
|
|
301
|
+
try {
|
|
302
|
+
const name = os.userInfo().username;
|
|
303
|
+
if (typeof name === 'string' && name.length > 0) {
|
|
304
|
+
return name;
|
|
305
|
+
}
|
|
306
|
+
} catch {
|
|
307
|
+
// userInfo() can throw when the uid has no passwd entry; fall back to env.
|
|
308
|
+
}
|
|
309
|
+
return process.env.USER || process.env.LOGNAME || '';
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// A systemd --user service only keeps running without an active login session
|
|
313
|
+
// when the user has lingering enabled. Detect it so `startup enable` can warn
|
|
314
|
+
// that the service may otherwise stop on logout. Returns null when the state
|
|
315
|
+
// cannot be determined (no username, loginctl unavailable, or odd output).
|
|
316
|
+
function getUserLingerEnabled(user) {
|
|
317
|
+
if (!user) {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
let result;
|
|
321
|
+
try {
|
|
322
|
+
result = runStartupCommand('loginctl', ['show-user', user, '-p', 'Linger'], { allowFailure: true });
|
|
323
|
+
} catch {
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
if (result.status !== 0) {
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
return parseLingerState(result.stdout);
|
|
330
|
+
}
|
|
331
|
+
|
|
286
332
|
function getStartupStatus() {
|
|
287
333
|
const paths = getStartupServicePaths();
|
|
288
334
|
if (!paths.servicePath) {
|
|
@@ -296,6 +342,7 @@ function getStartupStatus() {
|
|
|
296
342
|
const enabledResult = runStartupCommand('systemctl', ['--user', 'is-enabled', 'openchamber.service'], { allowFailure: true });
|
|
297
343
|
const activeResult = runStartupCommand('systemctl', ['--user', 'is-active', 'openchamber.service'], { allowFailure: true });
|
|
298
344
|
const activeState = (activeResult.stdout || '').trim() || 'inactive';
|
|
345
|
+
const lingerUser = getCurrentUsername();
|
|
299
346
|
return {
|
|
300
347
|
supported: true,
|
|
301
348
|
platform: paths.platform,
|
|
@@ -303,6 +350,8 @@ function getStartupStatus() {
|
|
|
303
350
|
active: activeState === 'active',
|
|
304
351
|
activeState,
|
|
305
352
|
servicePath: paths.servicePath,
|
|
353
|
+
lingerEnabled: getUserLingerEnabled(lingerUser),
|
|
354
|
+
lingerUser: lingerUser || null,
|
|
306
355
|
};
|
|
307
356
|
}
|
|
308
357
|
return {
|
|
@@ -9,7 +9,10 @@ import {
|
|
|
9
9
|
logStatus,
|
|
10
10
|
} from '../cli-output.js';
|
|
11
11
|
|
|
12
|
-
async function startupCommand(options, action = 'status') {
|
|
12
|
+
async function startupCommand(options, action = 'status', dependencies = {}) {
|
|
13
|
+
const getStatus = dependencies.getStartupStatus || getStartupStatus;
|
|
14
|
+
const enableService = dependencies.enableStartupService || enableStartupService;
|
|
15
|
+
const disableService = dependencies.disableStartupService || disableStartupService;
|
|
13
16
|
const normalized = typeof action === 'string' ? action.trim().toLowerCase() : 'status';
|
|
14
17
|
if (!['status', 'enable', 'disable'].includes(normalized)) {
|
|
15
18
|
throw new TunnelCliError(
|
|
@@ -20,14 +23,14 @@ async function startupCommand(options, action = 'status') {
|
|
|
20
23
|
|
|
21
24
|
let status;
|
|
22
25
|
if (normalized === 'enable') {
|
|
23
|
-
status =
|
|
26
|
+
status = enableService(options);
|
|
24
27
|
} else if (normalized === 'disable') {
|
|
25
|
-
status =
|
|
28
|
+
status = disableService();
|
|
26
29
|
} else {
|
|
27
|
-
status =
|
|
30
|
+
status = getStatus();
|
|
28
31
|
}
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
let result = { action: normalized, ...status };
|
|
31
34
|
if (!result.supported) {
|
|
32
35
|
throw new TunnelCliError(
|
|
33
36
|
`Startup integration is not supported on ${result.platform}.`,
|
|
@@ -40,13 +43,30 @@ async function startupCommand(options, action = 'status') {
|
|
|
40
43
|
EXIT_CODE.GENERAL_ERROR
|
|
41
44
|
);
|
|
42
45
|
}
|
|
46
|
+
if (result.platform === 'linux' && result.enabled && result.lingerEnabled !== true) {
|
|
47
|
+
const user = result.lingerUser || '"$USER"';
|
|
48
|
+
const disabled = result.lingerEnabled === false;
|
|
49
|
+
result = {
|
|
50
|
+
...result,
|
|
51
|
+
messages: [{
|
|
52
|
+
level: 'warning',
|
|
53
|
+
code: disabled ? 'LINGER_DISABLED' : 'LINGER_UNKNOWN',
|
|
54
|
+
message: disabled
|
|
55
|
+
? `User lingering is disabled; the startup service may stop after logout. Run \`sudo loginctl enable-linger ${user}\` to keep it running.`
|
|
56
|
+
: `Could not verify user lingering; the startup service may stop after logout. Check with \`loginctl show-user ${user} -p Linger\`.`,
|
|
57
|
+
}],
|
|
58
|
+
};
|
|
59
|
+
}
|
|
43
60
|
if (isJsonMode(options)) {
|
|
44
61
|
printJson(result);
|
|
45
62
|
return;
|
|
46
63
|
}
|
|
47
64
|
|
|
48
65
|
if (isQuietMode(options)) {
|
|
49
|
-
|
|
66
|
+
const lingerToken = result.platform === 'linux'
|
|
67
|
+
? ` linger:${result.lingerEnabled === true ? 'yes' : result.lingerEnabled === false ? 'no' : 'unknown'}`
|
|
68
|
+
: '';
|
|
69
|
+
process.stdout.write(`startup ${result.enabled ? 'enabled' : 'disabled'} platform:${result.platform} supported:${result.supported ? 'yes' : 'no'}${result.servicePath ? ` path:${result.servicePath}` : ''}${lingerToken}\n`);
|
|
50
70
|
return;
|
|
51
71
|
}
|
|
52
72
|
|
|
@@ -58,6 +78,21 @@ async function startupCommand(options, action = 'status') {
|
|
|
58
78
|
if (normalized === 'enable') {
|
|
59
79
|
logStatus('info', 'service command', 'openchamber serve --foreground');
|
|
60
80
|
}
|
|
81
|
+
if (result.platform === 'linux') {
|
|
82
|
+
if (result.lingerEnabled === true) {
|
|
83
|
+
logStatus('success', 'user lingering enabled');
|
|
84
|
+
} else if (result.lingerEnabled === false) {
|
|
85
|
+
logStatus(result.enabled ? 'warning' : 'info', `${result.enabled ? '[LINGER_DISABLED] ' : ''}user lingering is disabled`, result.enabled ? 'startup service may stop after logout' : undefined);
|
|
86
|
+
if (result.enabled) {
|
|
87
|
+
logStatus('info', '[ENABLE_LINGER]', `sudo loginctl enable-linger ${result.lingerUser || '"$USER"'}`);
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
logStatus(result.enabled ? 'warning' : 'info', result.enabled ? '[LINGER_UNKNOWN] could not verify user lingering' : 'user lingering state is unknown', result.enabled ? 'startup service may stop after logout' : undefined);
|
|
91
|
+
if (result.enabled) {
|
|
92
|
+
logStatus('info', '[CHECK_LINGER]', `loginctl show-user ${result.lingerUser || '"$USER"'} -p Linger`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
61
96
|
clackOutro(normalized === 'status' ? 'status complete' : `${normalized} complete`);
|
|
62
97
|
}
|
|
63
98
|
|
package/dist/assets/{CodeMirrorCommentWidgets-C53Q7pbX.js → CodeMirrorCommentWidgets-CV1HNV5l.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-DD7_7OP_.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};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{R as o,j as n,f as he}from"./vendor-react-BUCujlKS.js";import{
|
|
2
|
-
`);let i=null;for(const a of e){const d=a.match(/^@@\s*-\d+(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s*@@/);if(d){const f=Number.parseInt(d[1]??"",10);i=Number.isFinite(f)&&f>=1?f:null;continue}if(i!==null){if(a.startsWith(" ")){i+=1;continue}if(a.startsWith("+"))return i;if(a.startsWith("-"))return Math.max(1,i)}}return null},as=1100,ls=15e3,Dt=500,At=300,cs=1e6,us=3,fs=s=>s<=6?s:s<=12?6:s<=25?4:2,ds={original:"",modified:"",isBinary:!1,contextMode:"patch"},ps=3,ms=o.memo(()=>{const s=he.c(4),{t:e}=ge();let i;s[0]!==e?(i=e("diffView.binary.unavailable"),s[0]=e,s[1]=i):i=s[1];let a;return s[2]!==i?(a=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:i})}),s[2]=i,s[3]=a):a=s[3],a}),
|
|
1
|
+
import{R as o,j as n,f as he}from"./vendor-react-BUCujlKS.js";import{a0 as wn,a as ct,u as Y,G as Pe}from"./index-DlFbCkEy.js";import{f as ge,W as Tt,ac as yn,ad as vn,b7 as jn,ag as Sn,ae as Nn,ah as Fn,ai as Z,y as Ft,k as kn,hQ as Cn,hR as Rn,hS as Dn,cD as An,t as Ke,hT as En,ap as Ve,B as pe,I as A,h as ue,a7 as Bn,a8 as Vn,a9 as Ln,hD as Mt,hU as Tn,fF as Mn,fK as Ge,a1 as _n,c0 as at,ar as _t,ao as In,b3 as On,b5 as zn,fL as Pn,b6 as Gn}from"./useAppFontEffects-CuJPKtI1.js";import{b as Kn}from"./runtimeEndpointReset-DfJIWwwo.js";import{c as $n,p as Wn}from"./vendor-zustand-BAGL70zf.js";import{P as Hn}from"./PierreDiffViewer-CTIb1GYD.js";import{u as Un,v as qn,g as Xn,W as Jn}from"./main-B7qTsd_w.js";import{f as Qn}from"./patchFileDiff-No55fDiD.js";import"./vendor-scheduler-7OC5HNn7.js";import"./vendor-vite-runtime-DD1OZmLC.js";import"./vendor-zod-CK21ihK-.js";import"./vendor-opencode-sdk-BJ73u-bH.js";import"./vendor-simplewebauthn-browser-VDA66rT_.js";import"./vendor-base-ui-BeMD8X_w.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"./contextPanelEmbeddedChat-D2PM_pEv.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-framer-motion-livSKyyV.js";import"./vendor-motion-dom-D_o3BTI3.js";import"./vendor-motion-utils-BGh8QBgx.js";import"./vendor-tanstack-react-virtual-g05Cx3z9.js";import"./vendor-tanstack-virtual-core-Dubg10g5.js";import"./vendor-sonner-DFyL3AvE.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-9ZzoH0o0.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-gg7YLRW7.js";import"./vendor-tailwind-merge-CPcsbTWB.js";import"./vendor-fuse.js-Dw8P0qyA.js";import"./web-components-PttKBrhi.js";import"./computeVirtualFileMetrics-BKZA43vN.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"./VirtualizedFileDiff-Iehm4iMH.js";import"./isDiffPlainText-DaB2u_Kv.js";import"./vendor-diff-C3JhlQdm.js";import"./Virtualizer-D_a8gKmg.js";import"./useInlineCommentController-DD7_7OP_.js";import"./appThemeRegistry-BK0dHKa6.js";import"./registerCustomTheme-BBXUCRnG.js";import"./useRootScrollLock-DRGAe8PN.js";import"./scheduledTasksApi-DuhdyYEa.js";import"./vendor-cron-parser-CUcP7OfX.js";import"./vendor-luxon-BZ0puJYg.js";const Yn="openchamber.git-base-branch",Zn=100,$e=(s,e)=>JSON.stringify([ct(),s,e]),kt=$n()(Wn((s,e)=>({overrides:{},getOverride:(i,a)=>!i||!a?null:e().overrides[$e(i,a)]??null,setOverride:(i,a,d)=>{!i||!a||!d||s(f=>{const h=$e(i,a),x=Object.entries({...f.overrides,[h]:d});for(;x.length>Zn;)x.shift();return{overrides:Object.fromEntries(x)}})},clearOverride:(i,a)=>{!i||!a||s(d=>{const f=$e(i,a);if(!(f in d.overrides))return d;const h={...d.overrides};return delete h[f],{overrides:h}})}}),{name:Yn,storage:wn(),partialize:s=>({overrides:s.overrides})})),es=(s,e)=>!!s&&e!==null&&s!==e,ts=(s,e,i,a)=>i?s===null||a&&e===null?!0:e!==null&&s===e:!1,ns=(s,e)=>s==="branch"&&!e?"working":s,ss=(s,e,i)=>JSON.stringify([s,e,i]),rs=(s,e,i,a,d,f)=>{const h=o.useRef({directory:"",attempts:0}),[x,u]=o.useState(()=>({directory:"",exhausted:!1})),p=o.useRef(d);p.current=d;const b=!!s&&x.directory===s&&x.exhausted;return o.useEffect(()=>{if(!s||!e||a||i)return;const w=h.current.directory===s?h.current.attempts:0;if(w>=f){x.directory===s&&x.exhausted||u({directory:s,exhausted:!0});return}h.current={directory:s,attempts:w+1},p.current()},[s,x,a,e,i,f]),b},is=(s,e,i,a)=>{const[d,f]=o.useState(()=>new Map),h=o.useRef(d);h.current=d;const x=o.useRef(i);x.current=i;const u=o.useCallback((p,b)=>{const w=new Map(h.current);if(b===null){if(!w.delete(p))return}else w.set(p,b);h.current=w,f(w)},[]);return o.useEffect(()=>{s&&(h.current=new Map,f(h.current))},[s]),o.useEffect(()=>{const p=x.current;if(!s||!p||!e)return;let b=!1;const w=new Set;for(const y of e.split("\0"))h.current.has(y)||(w.add(y),u(y,a),p(y).then(j=>{b||(w.delete(y),u(y,j))}).catch(()=>{b||(w.delete(y),u(y,null))}));return()=>{b=!0;for(const y of w)u(y,null)}},[e,a,s,u]),d},Ct=(s,e)=>{if(e.length===0)return null;let i=null,a=null;for(const f of e)f.top<=s?(!i||f.top>i.top)&&(i=f):(!a||f.top<a.top)&&(a=f);const d=i??a;return d?{path:d.path,topOffset:d.top-s}:null},os=(s,e,i,a)=>Math.min(Math.max(0,a),Math.max(0,s+i-e)),Rt=s=>{if(!s)return null;const e=s.split(`
|
|
2
|
+
`);let i=null;for(const a of e){const d=a.match(/^@@\s*-\d+(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s*@@/);if(d){const f=Number.parseInt(d[1]??"",10);i=Number.isFinite(f)&&f>=1?f:null;continue}if(i!==null){if(a.startsWith(" ")){i+=1;continue}if(a.startsWith("+"))return i;if(a.startsWith("-"))return Math.max(1,i)}}return null},as=1100,ls=15e3,Dt=500,At=300,cs=1e6,us=3,fs=s=>s<=6?s:s<=12?6:s<=25?4:2,ds={original:"",modified:"",isBinary:!1,contextMode:"patch"},ps=3,ms=o.memo(()=>{const s=he.c(4),{t:e}=ge();let i;s[0]!==e?(i=e("diffView.binary.unavailable"),s[0]=e,s[1]=i):i=s[1];let a;return s[2]!==i?(a=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:i})}),s[2]=i,s[3]=a):a=s[3],a}),It={"?":{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"}},hs=It.M,gs=s=>{const e=s.index?.trim(),i=s.working_dir?.trim();return e&&e!=="?"?e.charAt(0):i?i.charAt(0):e?.charAt(0)||i?.charAt(0)||"M"},Ot=s=>{const e=gs(s);return It[e]??hs},xs=s=>{const{index:e,working_dir:i}=s;return e==="A"||i==="A"||e==="?"||i==="?"},Et=s=>{const e=s.index?.trim();return!!(e&&e!=="?")},Bt=s=>!!s.working_dir?.trim()||s.index==="?",bs=(s,e)=>Mn(s,e),Vt=s=>(s||"").replace(/\\/g,"/").replace(/\/+$/,""),Lt=(s,e)=>{const i=s.split(`
|
|
3
3
|
`),a=e.split(`
|
|
4
|
-
`),d=Math.min(i.length,a.length);for(let f=0;f<d;f+=1)if(i[f]!==a[f])return f+1;return a.length>i.length?i.length+1:i.length>a.length?Math.max(1,a.length):1},ws=s=>/^Binary files .+ differ$/m.test(s)||/^GIT binary patch$/m.test(s),ys=s=>Array.isArray(s)?s.filter(e=>!e||typeof e!="object"?!1:typeof e.file=="string"):[],vs=s=>s==="added"?"A":s==="deleted"?"D":"M",lt=(s,e,i)=>ws(e)?{original:"",modified:"",isBinary:!0,patch:e,contextMode:i}:{original:"",modified:"",patch:e,fileDiff:Qn(s,e),contextMode:i},zt=(s,e,i)=>{const a=s??0,d=e??0;return!a&&!d?null:n.jsxs("span",{className:ue("typography-meta flex items-center gap-1 text-xs whitespace-nowrap","flex-shrink-0",i?.className),children:[a?n.jsxs("span",{style:{color:"var(--status-success)"},children:["+",a]}):null,d?n.jsxs("span",{style:{color:"var(--status-error)"},children:["-",d]}):null]})},js=o.memo(s=>{const e=he.c(58),{scope:i,workingCount:a,stagedCount:d,turnCount:f,branchCount:h,showBranchOption:x,onScopeChange:u}=s,{t:p}=ge(),[b,w]=o.useState(!1),y=i==="staged"?d:i==="turn"?f:i==="branch"?h??0:a;let j;e[0]!==i||e[1]!==p?(j=p(i==="staged"?"diffView.scope.staged":i==="turn"?"diffView.scope.lastTurn":i==="branch"?"diffView.scope.branch":"diffView.scope.changed"),e[0]=i,e[1]=p,e[2]=j):j=e[2];const P=j;let m;e[3]!==p?(m=p("diffView.scope.selectorAria"),e[3]=p,e[4]=m):m=e[4];let le;e[5]!==y?(le=n.jsxs("span",{className:"diff-toolbar__scope-count",children:[": ",y]}),e[5]=y,e[6]=le):le=e[6];let k;e[7]!==P||e[8]!==le?(k=n.jsxs("span",{className:"whitespace-nowrap",children:[P,le]}),e[7]=P,e[8]=le,e[9]=k):k=e[9];let E;e[10]===Symbol.for("react.memo_cache_sentinel")?(E=n.jsx(A,{name:"arrow-down-s",className:"size-4 flex-shrink-0 opacity-60"}),e[10]=E):E=e[10];let L;e[11]!==m||e[12]!==k?(L=n.jsx(On,{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":m,children:[k,E]})}),e[11]=m,e[12]=k,e[13]=L):L=e[13];let W;e[14]!==u?(W=B=>{(B==="working"||B==="staged"||B==="turn"||B==="branch")&&(u?.(B),w(!1))},e[14]=u,e[15]=W):W=e[15];let N;e[16]!==p?(N=p("diffView.scope.changed"),e[16]=p,e[17]=N):N=e[17];let ee;e[18]!==N?(ee=n.jsx("span",{children:N}),e[18]=N,e[19]=ee):ee=e[19];let U;e[20]!==a?(U=n.jsx("span",{className:"typography-meta text-muted-foreground",children:a}),e[20]=a,e[21]=U):U=e[21];let q;e[22]!==U||e[23]!==ee?(q=n.jsx(Ge,{value:"working",children:n.jsxs("span",{className:"flex min-w-0 flex-1 items-center justify-between gap-3",children:[ee,U]})}),e[22]=U,e[23]=ee,e[24]=q):q=e[24];let G;e[25]!==p?(G=p("diffView.scope.staged"),e[25]=p,e[26]=G):G=e[26];let K;e[27]!==G?(K=n.jsx("span",{children:G}),e[27]=G,e[28]=K):K=e[28];let te;e[29]!==d?(te=n.jsx("span",{className:"typography-meta text-muted-foreground",children:d}),e[29]=d,e[30]=te):te=e[30];let I;e[31]!==K||e[32]!==te?(I=n.jsx(Ge,{value:"staged",children:n.jsxs("span",{className:"flex min-w-0 flex-1 items-center justify-between gap-3",children:[K,te]})}),e[31]=K,e[32]=te,e[33]=I):I=e[33];let _;e[34]!==p?(_=p("diffView.scope.lastTurn"),e[34]=p,e[35]=_):_=e[35];let V;e[36]!==_?(V=n.jsx("span",{children:_}),e[36]=_,e[37]=V):V=e[37];let O;e[38]!==f?(O=n.jsx("span",{className:"typography-meta text-muted-foreground",children:f}),e[38]=f,e[39]=O):O=e[39];let ne;e[40]!==V||e[41]!==O?(ne=n.jsx(Ge,{value:"turn",children:n.jsxs("span",{className:"flex min-w-0 flex-1 items-center justify-between gap-3",children:[V,O]})}),e[40]=V,e[41]=O,e[42]=ne):ne=e[42];let T;e[43]!==h||e[44]!==x||e[45]!==p?(T=x?n.jsx(Ge,{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:h??"…"})]})}):null,e[43]=h,e[44]=x,e[45]=p,e[46]=T):T=e[46];let se;e[47]!==i||e[48]!==q||e[49]!==I||e[50]!==ne||e[51]!==T||e[52]!==W?(se=n.jsx(zn,{align:"start",className:"w-40",children:n.jsxs(Pn,{value:i,onValueChange:W,children:[q,I,ne,T]})}),e[47]=i,e[48]=q,e[49]=I,e[50]=ne,e[51]=T,e[52]=W,e[53]=se):se=e[53];let re;return e[54]!==b||e[55]!==se||e[56]!==L?(re=n.jsxs(Gn,{open:b,onOpenChange:w,children:[L,se]}),e[54]=b,e[55]=se,e[56]=L,e[57]=re):re=e[57],re}),Ss=o.memo(s=>{const e=he.c(11),{changedFiles:i,selectedFile:a,onSelectFile:d}=s,{t:f}=ge();if(i.length===0)return null;let h;if(e[0]!==i||e[1]!==d||e[2]!==a||e[3]!==f){let u;e[5]!==d||e[6]!==a||e[7]!==f?(u=p=>{const b=Ot(p),w=a===p.path;return n.jsx("li",{children:n.jsxs("button",{type:"button",onClick:()=>d(p.path),className:ue("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left transition-colors",w?"bg-interactive-selection text-interactive-selection-foreground":"text-muted-foreground hover:bg-interactive-hover hover:text-foreground"),children:[n.jsx(It,{filePath:p.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:b.color},title:f(b.descriptionKey),"aria-label":f(b.descriptionKey),children:b.code}),n.jsx("span",{className:"min-w-0 flex-1 truncate typography-meta",style:{direction:"rtl",textAlign:"left",unicodeBidi:"plaintext"},title:p.path,children:p.path}),zt(p.insertions,p.deletions)]})},p.path)},e[5]=d,e[6]=a,e[7]=f,e[8]=u):u=e[8],h=i.map(u),e[0]=i,e[1]=d,e[2]=a,e[3]=f,e[4]=h}else h=e[4];let x;return e[9]!==h?(x=n.jsx(at,{outerClassName:"flex-1 min-h-0",className:"px-2 py-2",children:n.jsx("ul",{className:"flex flex-col gap-1",children:h})}),e[9]=h,e[10]=x):x=e[10],x}),Ns=o.memo(s=>{const e=he.c(20),{filePath:i,diff:a,renderSideBySide:d}=s,{t:f}=ge(),h=a.original.length>0,x=a.modified.length>0,u=d?"flex flex-row gap-6 items-start justify-center":"flex flex-col gap-4 items-center",p=d?"flex flex-col items-center gap-2 flex-1 min-w-0":"flex flex-col items-center gap-2";let b;e[0]===Symbol.for("react.memo_cache_sentinel")?(b={contain:"layout"},e[0]=b):b=e[0];let w;e[1]!==a.original||e[2]!==i||e[3]!==h||e[4]!==p||e[5]!==d||e[6]!==f?(w=h&&n.jsxs("div",{className:p,children:[n.jsx("span",{className:"typography-meta text-muted-foreground font-medium",children:f("diffView.image.original")}),n.jsx("img",{src:a.original,alt:f("diffView.image.originalAlt",{path:i}),className:d?"max-w-full max-h-[70vh] object-contain":"max-w-full object-contain",style:{imageRendering:"auto"}})]}),e[1]=a.original,e[2]=i,e[3]=h,e[4]=p,e[5]=d,e[6]=f,e[7]=w):w=e[7];let y;e[8]!==a.modified||e[9]!==i||e[10]!==x||e[11]!==h||e[12]!==p||e[13]!==d||e[14]!==f?(y=x&&n.jsxs("div",{className:p,children:[n.jsx("span",{className:"typography-meta text-muted-foreground font-medium",children:f(h?"diffView.image.modified":"diffView.image.new")}),n.jsx("img",{src:a.modified,alt:f("diffView.image.modifiedAlt",{path:i}),className:d?"max-w-full max-h-[70vh] object-contain":"max-w-full object-contain",style:{imageRendering:"auto"}})]}),e[8]=a.modified,e[9]=i,e[10]=x,e[11]=h,e[12]=p,e[13]=d,e[14]=f,e[15]=y):y=e[15];let j;return e[16]!==u||e[17]!==w||e[18]!==y?(j=n.jsx("div",{className:"w-full overflow-auto p-4",style:b,children:n.jsxs("div",{className:u,children:[w,y]})}),e[16]=u,e[17]=w,e[18]=y,e[19]=j):j=e[19],j}),Fs=o.memo(s=>{const e=he.c(16),{filePath:i,diff:a,renderSideBySide:d,wrapLines:f}=s;let h;e[0]!==i?(h=_n(i)||"text",e[0]=i,e[1]=h):h=e[1];const x=h;if(a.isBinary){let b;return e[2]===Symbol.for("react.memo_cache_sentinel")?(b=n.jsx(ms,{}),e[2]=b):b=e[2],b}if(Ve(i)){let b;return e[3]!==a||e[4]!==i||e[5]!==d?(b=n.jsx(Ns,{filePath:i,diff:a,renderSideBySide:d}),e[3]=a,e[4]=i,e[5]=d,e[6]=b):b=e[6],b}let u;e[7]===Symbol.for("react.memo_cache_sentinel")?(u={contain:"layout"},e[7]=u):u=e[7];let p;return e[8]!==a.fileDiff||e[9]!==a.modified||e[10]!==a.original||e[11]!==i||e[12]!==x||e[13]!==d||e[14]!==f?(p=n.jsx("div",{className:"w-full",style:u,children:n.jsx(Wn,{original:a.original,modified:a.modified,fileDiff:a.fileDiff,language:x,fileName:i,renderSideBySide:d,wrapLines:f,layout:"inline"})}),e[8]=a.fileDiff,e[9]=a.modified,e[10]=a.original,e[11]=i,e[12]=x,e[13]=d,e[14]=f,e[15]=p):p=e[15],p}),ks=o.memo(s=>{const e=he.c(7),{filePath:i,staged:a,busyAction:d,disabled:f,onAction:h}=s,{t:x}=ge();let u;return e[0]!==d||e[1]!==f||e[2]!==i||e[3]!==h||e[4]!==a||e[5]!==x?(u=n.jsx("div",{className:"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:a?n.jsx(ot,{label:x("gitView.changes.unstageFileAria",{path:i}),icon:"arrow-go-back",loading:d==="unstage",disabled:f,onClick:()=>h("unstage")}):n.jsxs(n.Fragment,{children:[n.jsx(ot,{label:x("gitView.changes.revertFileAria",{path:i}),icon:"arrow-go-back",loading:d==="discard",disabled:f,tone:"failure",onClick:()=>h("discard")}),n.jsx(ot,{label:x("gitView.changes.stageFileAria",{path:i}),icon:"add",loading:d==="stage",disabled:f,tone:"success",onClick:()=>h("stage")})]})}),e[0]=d,e[1]=f,e[2]=i,e[3]=h,e[4]=a,e[5]=x,e[6]=u):u=e[6],u}),ot=s=>{const e=he.c(14),{label:i,icon:a,loading:d,disabled:f,tone:h,onClick:x}=s,u=h==="failure"&&"text-[var(--status-error)] hover:text-[var(--status-error)]",p=h==="success"&&"text-[var(--status-success)] hover:text-[var(--status-success)]";let b;e[0]!==u||e[1]!==p?(b=ue("h-6 w-6 rounded-none bg-transparent p-0 text-muted-foreground opacity-70 hover:bg-transparent hover:text-foreground hover:opacity-100",u,p),e[0]=u,e[1]=p,e[2]=b):b=e[2];let w;e[3]!==x?(w=P=>{P.stopPropagation(),x()},e[3]=x,e[4]=w):w=e[4];let y;e[5]!==a||e[6]!==d?(y=d?n.jsx(A,{name:"loader-4",className:"size-3.5 animate-spin"}):n.jsx(A,{name:a,className:a==="add"?"size-4":"size-3.5"}),e[5]=a,e[6]=d,e[7]=y):y=e[7];let j;return e[8]!==f||e[9]!==i||e[10]!==b||e[11]!==w||e[12]!==y?(j=n.jsx(pe,{variant:"ghost",size:"sm",className:b,disabled:f,title:i,"aria-label":i,onClick:w,children:y}),e[8]=f,e[9]=i,e[10]=b,e[11]=w,e[12]=y,e[13]=j):j=e[13],j},Cs=o.memo(({directory:s,file:e,layout:i,wrapLines:a,isSelected:d,isExpanded:f,isMounted:h,onSelect:x,onExpandedChange:u,registerSectionRef:p,showOpenInEditorAction:b=!1,isOpeningInEditor:w=!1,onOpenInEditor:y,staged:j=!1,loadFullFiles:P=!1,initialDiffData:m=null,readOnlyActions:le=!1})=>{const{t:k}=ge(),{git:E}=Tt(),L=Z(o.useCallback(c=>c.directories.get(s)?.diffCache.get(e.path)??null,[s,e.path])),W=Z(c=>c.setDiff),N=Z(c=>c.fetchStatus),ee=Y(c=>c.setDiffFileLayout),[U,q]=o.useState(0),[G,K]=o.useState(null),[te,I]=o.useState(!1),[_,V]=o.useState(null),[O,ne]=o.useState(!1),[T,se]=o.useState(null),[re,B]=o.useState(null),ie=o.useRef(null),He=o.useRef(null),ce=o.useMemo(()=>Ot(e),[e]),fe=i==="side-by-side",xe=P?"full":"patch",Ce=`${e.index}:${e.working_dir}:${e.insertions}:${e.deletions}`,X=o.useMemo(()=>m||(j?re:T||(L?{original:L.original,modified:L.modified,isBinary:L.isBinary,contextMode:"full"}:null)),[L,m,T,j,re]),Re=X?.contextMode===xe,We=o.useCallback(c=>{He.current=c,p(e.path,c)},[e.path,p]),Le=o.useCallback(c=>{u(e.path,c)},[e.path,u]),be=o.useCallback(()=>{x(e.path)},[e.path,x]);o.useEffect(()=>{j?B(null):se(null),K(null),ie.current=null},[Ce,j]),o.useEffect(()=>{if(!f||!h)return;if(!s||m||X&&Re){ie.current=null,I(!1);return}const c=`${s}::${e.path}::${j?"staged":"unstaged"}::${Ce}::${xe}::${U}`;if(ie.current===c)return;ie.current=c,K(null),I(!0);let C=!1;const oe=ct(),Me=P?cs:us,de=Ve(e.path)?E.getGitFileDiff(s,{path:e.path,staged:j}):E.getGitDiff(s,{path:e.path,staged:j,contextLines:Me}),De=ls,Ae=new Promise(($,J)=>{setTimeout(()=>J(new Error(`Timed out after ${De}ms`)),De)});return Promise.race([de,Ae]).then($=>{if(!C){if("diff"in $){const J=lt(e.path,$.diff,xe);j?B(J):se(J)}else{const J={original:$.original??"",modified:$.modified??"",isBinary:$.isBinary,contextMode:"full"};j?B(J):W(s,e.path,J,oe)}I(!1)}}).catch($=>{if(C)return;const J=$ instanceof Error?$.message:String($);K(J),I(!1)}),()=>{C=!0,ie.current===c&&(ie.current=null)}},[xe,X,Re,U,s,e.path,Ce,E,m,f,h,P,W,j]);const we=o.useCallback(()=>{Le(!f),be()},[Le,be,f]),Te=o.useCallback(async c=>{if(!(!s||_!==null)){V(c);try{c==="stage"?await E.stageGitFile(s,e.path):c==="unstage"?await E.unstageGitFile(s,e.path):await E.revertGitFile(s,e.path,{scope:"working"}),q(C=>C+1),await N(s,E)}catch(C){const oe=c==="unstage"?"gitView.toast.unstageFileFailed":c==="stage"?"gitView.toast.stageFileFailed":"gitView.toast.revertFailed";Ke.error(C instanceof Error?C.message:k(oe))}finally{V(C=>C===c?null:C)}}},[s,N,e.path,_,E,k]);return n.jsxs("div",{ref:We,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:we,onKeyDown:c=>{c.target===c.currentTarget&&(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),we())},className:ue("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",d?"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:f?n.jsx(A,{name:"arrow-down-s",className:"size-4"}):n.jsx(A,{name:"arrow-right-s",className:"size-4"})}),n.jsx("span",{className:"typography-micro font-semibold leading-none w-4 text-center uppercase",style:{color:ce.color},title:k(ce.descriptionKey),"aria-label":k(ce.descriptionKey),children:ce.code}),n.jsx("span",{className:"min-w-0 flex-1 overflow-hidden typography-ui-label",title:e.path,children:n.jsxs("span",{className:"flex min-w-0 items-center gap-2",children:[n.jsx(It,{filePath:e.path,className:"h-3.5 w-3.5 flex-shrink-0 align-middle"}),(()=>{const c=e.path.lastIndexOf("/");if(c===-1)return n.jsx("span",{className:"block min-w-0 truncate typography-ui-label text-foreground",style:{direction:"rtl",textAlign:"left",unicodeBidi:"plaintext"},children:e.path});const C=e.path.slice(0,c),oe=e.path.slice(c+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:C}),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:oe})]})]})})()]})})]}),n.jsxs("div",{className:"relative flex shrink-0 items-center justify-self-end gap-2",children:[zt(e.insertions,e.deletions),b&&y?n.jsx(pe,{variant:"ghost",size:"sm",className:"h-5 w-5 p-0 opacity-70 hover:opacity-100",title:k("diffView.actions.openFileInEditorAtChange"),onClick:c=>{c.stopPropagation(),y(e.path,X)},disabled:w,children:w?n.jsx(A,{name:"loader-4",className:"size-3.5 animate-spin"}):n.jsx(A,{name:"edit",className:"size-3.5"})}):null,n.jsx(Mt,{mode:fe?"side-by-side":"unified",onModeChange:c=>{const C=c==="side-by-side"?"side-by-side":"inline";ee(e.path,C)},className:"opacity-70"})]})]})}),f&&n.jsxs("div",{className:"relative bg-background overflow-hidden",children:[!h&&!G?n.jsx("div",{className:"h-40 border border-border/40 bg-background/40"}):null,G?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:k("diffView.state.failedToLoadDiff")}),n.jsx("div",{className:"typography-meta text-muted-foreground max-w-[32rem] text-center",children:G}),n.jsx("button",{type:"button",className:"typography-ui-label text-primary hover:underline",onClick:()=>q(c=>c+1),children:k("diffView.actions.retry")})]}):null,h&&te&&!X&&!G?n.jsxs("div",{className:"flex items-center justify-center gap-2 px-4 py-8 text-sm text-muted-foreground",children:[n.jsx(A,{name:"loader-4",className:"size-4 animate-spin"}),k("diffView.state.loadingDiff")]}):null,h&&X&&!O&&e.insertions+e.deletions>Dt?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:k("diffView.state.largeDiff",{count:e.insertions+e.deletions})}),n.jsx("div",{className:"typography-meta text-muted-foreground",children:k("diffView.state.largeDiffDescription")}),n.jsx("button",{type:"button",className:"typography-ui-label text-primary hover:underline",onClick:()=>ne(!0),children:k("diffView.actions.renderAnyway")})]}):null,h&&X&&(O||e.insertions+e.deletions<=Dt)?n.jsxs(n.Fragment,{children:[n.jsx(Fs,{filePath:e.path,diff:X,renderSideBySide:fe,wrapLines:a}),n.jsx("div",{className:"pointer-events-none absolute bottom-3 right-3 z-20",children:n.jsx("div",{className:"pointer-events-auto",children:le?null:n.jsx(ks,{filePath:e.path,staged:j,busyAction:_,disabled:_!==null,onAction:Te})})})]}):null]})]})}),Ki=({hideStackedFileSidebar:s=!1,stackedDefaultCollapsedAll:e=!1,pinSelectedFileHeaderToTopOnNavigate:i=!1,showOpenInEditorAction:a=!1,diffScope:d="all",onDiffScopeChange:f,targetFilePath:h=null,flushContent:x=!1})=>{const{t:u}=ge(),{git:p,files:b}=Tt(),w=yn(),{rootIsGitRepo:y,gitDirectory:j,nestedRepos:P}=vn(w??null),m=j??w,le=Y(t=>t.openContextSurface),k=Un(t=>t.requestSource),{screenWidth:E,isMobile:L}=jn(),W=Sn(m??null),N=Nn(m??null),ee=Fn(m??null),U=Z(t=>t.setActiveDirectory),q=Z(t=>t.ensureStatus),G=Z(t=>t.selectNestedRepo),K=Z(t=>t.fetchStatus),te=Z(t=>t.fetchBranches),I=Z(t=>t.clearDiffCache),_=Z(t=>t.setDiff),[V,O]=o.useState(null),[ne,T]=o.useState(!1),[se,re]=o.useState(null),[B,ie]=o.useState(()=>new Set),[He,ce]=o.useState(()=>new Set),[fe,xe]=o.useState(!1),[Ce,X]=o.useState(0),[Re,We]=o.useState(()=>new Map),[Le,be]=o.useState(!1),[we,Te]=o.useState(!1),[c,C]=o.useState(d);o.useEffect(()=>{C(d)},[d]);const oe=Y(t=>t.pendingDiffFile),Me=Y(t=>t.pendingDiffStaged),de=Y(t=>t.pendingDiffScope),De=Y(t=>t.setPendingDiffFile),Ae=Y(t=>t.diffLayoutPreference),$=Y(t=>t.diffFileLayout),J=Y(t=>t.setDiffFileLayout),ut=Y(t=>t.diffWrapLines),Pt=Y(t=>t.setDiffWrapLines),ft=Y(t=>t.openContextFileAtLine),ye=Ft(t=>t.currentSessionId),Ue=kn(ye??"",w??void 0),qe=ut,Xe=c==="staged"?!0:c==="working"?!1:null,Ie=Xe??ne,Je=L||E<=768,Gt=!!ye&&c!=="turn"&&!Je&&!Pe(),Kt=c!=="turn"&&!Je&&!Pe(),$t=!s&&!Je&&E>=1024,ve=o.useRef(null),Ee=o.useRef(new Map),me=o.useRef(null),z=o.useRef(null),je=o.useRef(!1),Se=o.useRef(null),dt=o.useRef(null),Qe=o.useRef(null),Ye=o.useRef(null),pt=o.useCallback(()=>{const t=ve.current;if(!t)return null;const r=t.getBoundingClientRect().top,l=[];for(const[g,v]of Ee.current)v&&l.push({path:g,top:v.getBoundingClientRect().top});return Ct(r,l)},[]),Ne=o.useCallback(()=>{me.current=null,je.current=!1,re(null),z.current!==null&&(window.cancelAnimationFrame(z.current),z.current=null)},[]),Fe=o.useCallback(t=>{ie(r=>{if(r.has(t))return r;const l=new Set(r);return l.add(t),l})},[]),Be=o.useMemo(()=>{for(let t=Ue.length-1;t>=0;t-=1){const r=Ue[t];if(r.role==="user")return ys(r.summary?.diffs)}return[]},[Ue]),Ht=o.useMemo(()=>{const t=new Map;for(const r of Be)if(r.file){if(typeof r.patch=="string"){t.set(r.file,lt(r.file,r.patch,"patch"));continue}t.set(r.file,{original:r.before??"",modified:r.after??"",contextMode:"full"})}return t},[Be]),Wt=o.useMemo(()=>N?.files?N.files.filter(Bt).length:0,[N]),Ut=o.useMemo(()=>N?.files?N.files.filter(Et).length:0,[N]),qt=Be.length,R=N?.current??null,ke=Z(t=>m?t.directories.get(m)?.branches??null:null),Xt=Z(t=>m?t.directories.get(m)?.isLoadingBranches??!1:!1),Jt=o.useCallback(()=>{m&&te(m,p)},[m,te,p]),Qt=rs(m??null,W!==!1,Xt,!!ke,Jt,ps),mt=o.useMemo(()=>{const t=N?.tracking?.trim().split("/")[0];return(t&&ke?.defaultBranches?.[t])??ke?.defaultBranches?.origin??null},[ke,N?.tracking]),Ze=!Pe()&&es(R,mt),Yt=N!==null,ht=Pe()||Qt||ts(R,mt,Yt,ke!==null),Zt=kt(t=>t.setOverride),en=kt(o.useCallback(t=>m&&R?t.overrides[$e(m,R)]??null:null,[R,m])),[tn,et]=o.useState(null),[nn,tt]=o.useState(!1),[gt,sn]=o.useState("");o.useEffect(()=>{const t=ns(c,!ht);t!==c&&(C(t),t==="working"&&f?.("working"))},[c,ht,f]),o.useEffect(()=>{if(!Ze||!m||!R){et(null),tt(!1);return}let t=!1;return tt(!1),Cn(m,R).then(r=>{t||et(r.base)}).catch(()=>{t||et(null)}).finally(()=>{t||tt(!0)}),()=>{t=!0}},[R,m,Ze]);const ae=en??tn,[_e,xt]=o.useState(null),[bt,wt]=o.useState(null),Oe=o.useRef(0),nt=o.useCallback(()=>{if(!m||!R||!ae)return;const t=Oe.current+1;Oe.current=t,xt(null),wt(null),Rn(m,{base:ae,head:R}).then(r=>{Oe.current===t&&xt(r)}).catch(r=>{Oe.current===t&&wt(r instanceof Error?r.message:u("diffView.branch.loadError"))})},[ae,R,m,u]);o.useEffect(()=>{c==="branch"&&nt()},[c,nt]);const yt=c==="branch"&&m&&R&&ae?ss(m,ae,R):null,rn=o.useMemo(()=>c==="branch"?Array.from(B).sort().join("\0"):"",[c,B]),on=o.useCallback(t=>!m||!ae||!R?Promise.reject(new Error("branch range is unavailable")):Dn(m,{base:ae,head:R,path:t}).then(r=>lt(t,r.diff,"patch")),[ae,R,m]),an=is(yt,rn,yt?on:null,ds),ln=_e?.length??null,S=o.useMemo(()=>{if(c==="branch")return(_e??[]).map(l=>({path:l.path,index:"",working_dir:l.status,insertions:0,deletions:0,isNew:l.status==="A"})).sort((l,g)=>l.path.localeCompare(g.path));if(c==="turn")return Be.map(l=>({path:l.file??"",index:"",working_dir:vs(l.status),insertions:l.additions??0,deletions:l.deletions??0,isNew:l.status==="added"})).filter(l=>l.path).sort((l,g)=>l.path.localeCompare(g.path));if(!N?.files)return[];const t=N.diffStats??{},r=c==="staged"?Et:c==="working"?Bt:()=>!0;return N.files.filter(r).map(l=>({...l,insertions:t[l.path]?.insertions??0,deletions:t[l.path]?.deletions??0,isNew:xs(l)})).sort((l,g)=>l.path.localeCompare(g.path))},[c,_e,Be,N]),st=o.useMemo(()=>S.map(t=>t.path).join("\0"),[S]);o.useEffect(()=>{const t=st?st.split("\0"):[],r=new Set(t),l=`${m??""}:${c}:${e?"collapsed":"default"}`,g=dt.current!==l;dt.current=l,ie(v=>{if(g){const D=e?0:fs(t.length);return new Set(t.slice(0,D))}let M=!1;const F=new Set;for(const D of v){if(!r.has(D)){M=!0;continue}F.add(D)}return M?F:v}),ce(v=>{if(g)return new Set;let M=!1;const F=new Set;for(const D of v){if(!r.has(D)){M=!0;continue}F.add(D)}return M?F:v})},[c,st,m,e]);const vt=o.useCallback(()=>{Se.current=null;const t=ve.current;if(!t)return;const r=t.getBoundingClientRect(),l=r.top-At,g=r.bottom+At,v={},M=[];for(const[F,D]of Ee.current){if(!D)continue;const H=D.getBoundingClientRect();M.push({path:F,top:H.top}),B.has(F)&&(H.bottom<l||H.top>g||(v[F]=!0))}Qe.current=Ct(r.top,M),ce(F=>{let D=!1;const H=new Set(F);for(const Nt of Object.keys(v))H.has(Nt)||(H.add(Nt),D=!0);return D?H:F})},[B]),Q=o.useCallback(()=>{typeof window>"u"||Se.current===null&&(Se.current=window.requestAnimationFrame(vt))},[vt]);o.useEffect(()=>{const t=ve.current;if(t)return Q(),t.addEventListener("scroll",Q,{passive:!0}),window.addEventListener("resize",Q),()=>{t.removeEventListener("scroll",Q),window.removeEventListener("resize",Q),Se.current!==null&&(window.cancelAnimationFrame(Se.current),Se.current=null)}},[S,B,Q]);const rt=o.useCallback(t=>{const r=$[t.path];if(r)return r;if(Ae==="inline")return"inline";if(Ae==="side-by-side")return"side-by-side";const l=E<as;return t.isNew||l?"inline":"side-by-side"},[$,Ae,E]),jt=o.useMemo(()=>S.length===0?null:S.every(t=>rt(t)==="side-by-side")?"side-by-side":"inline",[S,rt]);o.useEffect(()=>{m&&(U(m),q(m,p))},[m,U,q,p]),o.useEffect(()=>{if(m)return An.onGitRefreshHint(t=>{Vt(t.directory)===Vt(m)&&(t.paths?.length&&(Ye.current=pt()??Qe.current,I(m,t.paths),We(r=>{const l=new Map(r);for(const g of t.paths??[])l.set(g,(l.get(g)??0)+1);return l})),K(m,p,{silent:!0}))})},[pt,I,m,K,p]),o.useLayoutEffect(()=>{const t=Ye.current;if(!t)return;Ye.current=null;const r=ve.current,l=Ee.current.get(t.path);if(!r||!l)return;const g=r.getBoundingClientRect().top,v=l.getBoundingClientRect().top-g;r.scrollTop=os(r.scrollTop,t.topOffset,v,r.scrollHeight-r.clientHeight),Qe.current=t},[Re]),o.useEffect(()=>{c!=="all"&&!de||oe&&(de&&C(de),O(oe),T(de==="staged"||!de&&Me),De(null),je.current=!0,me.current=oe,Fe(oe),X(t=>t+1))},[c,Fe,oe,de,Me,De]),o.useEffect(()=>{if(c==="all")return;const t=h?.trim();t&&(O(t),T(c==="staged"),je.current=!0,me.current=t,Fe(t),X(r=>r+1))},[c,Fe,h]),o.useEffect(()=>{if(!V)return;S.some(r=>r.path===V)||(O(null),T(!1))},[S,V]);const cn=o.useCallback((t,r)=>{const l=Ee.current;r?l.set(t,r):l.delete(t),Q()},[Q]),un=o.useCallback((t,r)=>{Ne(),ie(l=>{const g=l.has(t);if(r===g)return l;const v=new Set(l);return r?v.add(t):v.delete(t),v}),r||ce(l=>{if(!l.has(t))return l;const g=new Set(l);return g.delete(t),g}),Q()},[Ne,Q]),fn=o.useCallback(()=>{Ne(),ie(t=>t.size>0?new Set:new Set(S.map(r=>r.path))),ce(new Set),Q()},[Ne,S,Q]),dn=o.useCallback(async t=>{if(!ye)return;const r=Ft.getState().getDirectoryForSession(ye)||w||"";if(!r){Ke.error(u("diffView.reviewDialog.toast.noSessionDirectory"));return}Te(!0);try{await En({originalSessionID:ye,directory:r,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}),be(!1)}catch(l){console.error("[review-flow] failed to start review flow",l),Ke.error(l instanceof Error?l.message:u("diffView.reviewDialog.toast.startFailed"))}finally{Te(!1)}},[ye,w,u]),ze=o.useCallback(t=>{const r=Ee.current.get(t),l=ve.current;if(!r||!l)return!1;const g=r.getBoundingClientRect().top-l.getBoundingClientRect().top;return l.scrollTo({top:l.scrollTop+g,behavior:"auto"}),!0},[]);o.useEffect(()=>{if(!me.current)return;let r=0;const l=20;let g=!1;const v=(F=!0)=>{g||(g=!0,me.current=null,je.current=!1,F&&re(null),z.current!==null&&(window.cancelAnimationFrame(z.current),z.current=null))},M=()=>{if(g){z.current=null;return}const F=me.current;if(!F){v(),z.current=null;return}if(!ze(F)){r+=1,r<l?z.current=window.requestAnimationFrame(M):(v(),z.current=null);return}if(i&&je.current){re(F),v(!1);return}v()};return z.current=window.requestAnimationFrame(M),()=>{g=!0,z.current!==null&&(window.cancelAnimationFrame(z.current),z.current=null)}},[i,Ce,ze]);const pn=o.useCallback(t=>{},[]),it=o.useCallback(t=>{Ne(),O(t),T(!1),je.current=!0,me.current=t,Fe(t),X(r=>r+1),ze(t)},[Ne,Fe,ze]);o.useEffect(()=>{const t=r=>{if(!r.altKey||r.metaKey||r.ctrlKey||r.shiftKey||r.key!=="ArrowDown"&&r.key!=="ArrowUp")return;const l=r.target;if(l instanceof HTMLElement&&(l.isContentEditable||l.tagName==="INPUT"||l.tagName==="TEXTAREA"||l.closest('[role="dialog"]'))||S.length===0)return;const g=r.key==="ArrowDown"?1:-1,v=V?S.findIndex(D=>D.path===V):-1,M=v===-1?g>0?0:S.length-1:v+g,F=S[M];F&&(r.preventDefault(),it(F.path))};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[S,V,it]);const mn=o.useCallback(t=>{const r=t==="side-by-side"?"side-by-side":"inline";S.forEach(l=>{J(l.path,r)})},[S,J]),[hn,St]=o.useState(null),gn=o.useCallback(async(t,r)=>{if(!m||!t)return;St(t);const l=ct();try{let g=null;if(r?.patch&&!r.isBinary&&!Ve(t)?g=Rt(r.patch):r&&r.contextMode==="full"&&!r.isBinary&&!Ve(t)&&(g=Lt(r.original,r.modified)),g===null)try{const H=await p.getGitDiff(m,{path:t,staged:Ie,contextLines:3});g=Rt(H.diff)}catch{g=null}let v=r;if(g===null||!v){const H=await p.getGitFileDiff(m,{path:t,staged:Ie});v={original:H.original??"",modified:H.modified??"",isBinary:H.isBinary},Ie||_(m,t,v,l)}const M=g??(v.isBinary||Ve(t)?1:Lt(v.original,v.modified)),F=bs(m,t),D=await qn(b,F,{directory:m});if(!D.ok){Ke.error(Xn(D.reason));return}ft(m,F,M,1)}finally{St(g=>g===t?null:g)}},[Ie,m,b,p,ft,_]),xn=()=>{if(!m)return null;const t=r=>Xe!==null?Xe:ne&&r===V;return n.jsxs("div",{className:ue("flex min-w-0 flex-1 min-h-0 h-full",x?"gap-0":"gap-3 px-3 pb-3 pt-2"),children:[$t&&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:u("diffView.section.files")}),n.jsx("span",{className:"typography-meta text-muted-foreground",children:S.length})]}),n.jsx(Ss,{changedFiles:S,selectedFile:null,onSelectFile:it})]}),n.jsx("div",{className:"relative flex-1 min-w-0 min-h-0 h-full",children:n.jsx(at,{ref:ve,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:S.map(r=>n.jsx(Cs,{directory:m,file:r,layout:rt(r),wrapLines:qe,isSelected:!1,isExpanded:B.has(r.path),isMounted:He.has(r.path)||r.path===se,onSelect:pn,onExpandedChange:un,registerSectionRef:cn,showOpenInEditorAction:a&&c!=="turn",isOpeningInEditor:hn===r.path,onOpenInEditor:(l,g)=>{gn(l,g)},staged:t(r.path),loadFullFiles:fe,readOnlyActions:c==="branch",initialDiffData:c==="turn"?Ht.get(r.path)??null:c==="branch"?an.get(r.path)??null:null},`${r.path}:${Re.get(r.path)??0}`))})})})]})},bn=()=>{if(!m)return n.jsx("div",{className:"flex flex-1 items-center justify-center text-sm text-muted-foreground",children:u("diffView.state.selectSessionDirectory")});if(c!=="turn"&&ee&&!N)return n.jsxs("div",{className:"flex flex-1 items-center justify-center gap-2 text-sm text-muted-foreground",children:[n.jsx(A,{name:"loader-4",className:"size-4 animate-spin"}),u("diffView.state.loadingRepositoryStatus")]});if(c!=="turn"&&W===!1)return n.jsx("div",{className:"flex flex-1 items-center justify-center text-sm text-muted-foreground",children:u("diffView.state.notGitRepository")});if(c==="branch"){if(!nn)return n.jsxs("div",{className:"flex flex-1 items-center justify-center gap-2 text-sm text-muted-foreground",children:[n.jsx(A,{name:"loader-4",className:"size-4 animate-spin"}),u("diffView.branch.resolvingBase")]});if(!ae){const t=(ke?.all??[]).map(l=>l.replace(/^remotes\//,"")).filter(l=>l!==R&&!l.endsWith(`/${R}`)).sort(),r=In(t,gt,l=>[l]);return n.jsxs("div",{className:"flex flex-1 flex-col items-center justify-center gap-3 px-6 text-center",children:[n.jsx(A,{name:"git-branch",className:"size-6 text-muted-foreground"}),n.jsx("div",{className:"typography-ui-label font-semibold text-foreground",children:u("diffView.branch.noBaseTitle")}),n.jsx("div",{className:"max-w-sm typography-micro text-muted-foreground",children:u("diffView.branch.noBaseDescription")}),n.jsx("input",{type:"text",value:gt,onChange:l=>sn(l.target.value),placeholder:u("gitView.branch.searchPlaceholder"),"aria-label":u("gitView.branch.searchPlaceholder"),className:"w-full max-w-sm rounded-md border border-border/60 bg-[var(--surface-elevated)] px-2.5 py-1.5 typography-meta text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-[var(--interactive-focus-ring)]"}),n.jsx(at,{outerClassName:"max-h-48 w-full max-w-sm min-h-0",className:"px-1 py-1",children:r.length===0?n.jsx("div",{className:"px-2 py-3 typography-meta text-muted-foreground",children:u("gitView.branch.empty")}):n.jsx("div",{className:"flex flex-col gap-0.5",children:r.map(l=>n.jsxs("button",{type:"button",onClick:()=>m&&R&&Zt(m,R,l),className:"flex items-center gap-2 rounded-md px-2 py-1.5 text-left hover:bg-interactive-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--interactive-focus-ring)]",children:[n.jsx(A,{name:"git-branch",className:"size-3.5 text-primary"}),n.jsx("span",{className:"truncate typography-ui-label text-foreground",title:l,children:l})]},l))})})]})}if(bt)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:u("diffView.branch.loadError")}),n.jsx("div",{className:"max-w-sm typography-micro text-muted-foreground",children:bt}),n.jsx(pe,{variant:"outline",size:"sm",onClick:()=>nt(),children:u("diffView.actions.retry")})]});if(_e===null)return n.jsxs("div",{className:"flex flex-1 items-center justify-center gap-2 text-sm text-muted-foreground",children:[n.jsx(A,{name:"loader-4",className:"size-4 animate-spin"}),u("diffView.branch.loadingFiles")]})}return S.length===0?n.jsx("div",{className:"flex flex-1 items-center justify-center text-sm text-muted-foreground",children:c==="turn"?u("diffView.state.noLastTurnChanges"):c==="branch"&&ae?u("diffView.branch.empty",{base:ae}):u("diffView.state.cleanWorkingTree")}):xn()};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:[y===!1&&Array.isArray(P)&&P.length>0?n.jsx(Kn,{repositories:P,selectedRepository:j??null,onSelectRepository:t=>{w&&G(w,t)},repositoryRoot:w??void 0}):null,!L&&(c==="working"||c==="staged"||c==="turn"||c==="branch"?n.jsx(js,{scope:c,workingCount:Wt,stagedCount:Ut,turnCount:qt,branchCount:ln,showBranchOption:Ze,onScopeChange:t=>{C(t),f?.(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:ee&&!N?u("diffView.state.loadingChanges"):S.length===1?u("diffView.summary.changedFilesSingle",{count:S.length}):u("diffView.summary.changedFilesPlural",{count:S.length})})})),S.length>0&&n.jsxs(pe,{variant:"ghost",size:"sm",onClick:fn,className:ue("diff-toolbar__expand-button h-7 flex-shrink-0 gap-1 px-1.5 text-muted-foreground hover:text-foreground","ml-auto"),title:B.size>0?u("diffView.actions.collapseAll"):u("diffView.actions.expandAll"),children:[n.jsx(A,{name:"expand-up-down",className:"size-4"}),n.jsx("span",{className:"diff-toolbar__expand-label typography-ui-label",children:B.size>0?u("diffView.actions.collapseAll"):u("diffView.actions.expandAll")})]}),S.length>0&&Gt&&n.jsxs(pe,{variant:"default",size:"sm",onClick:()=>be(!0),disabled:we,className:"diff-toolbar__review-button h-7 flex-shrink-0 gap-1.5 px-2","aria-label":u("diffView.actions.reviewAria"),children:[we?n.jsx(A,{name:"loader-4",className:"size-4 animate-spin"}):n.jsx(A,{name:"search-eye",className:"size-4"}),n.jsx("span",{className:"diff-toolbar__review-label typography-ui-label",children:u("diffView.actions.review")})]}),S.length>0&&Kt&&n.jsxs(pe,{variant:"outline",size:"sm",onClick:()=>{const t=m??"";k(t,{kind:"working-tree",scope:c==="staged"||c==="working"?c:"all"}),le(t,"walkthrough")},className:ue("diff-toolbar__walkthrough-button h-7 flex-shrink-0 gap-1.5 px-2",Jn),"aria-label":u("walkthrough.action.open"),children:[n.jsx(A,{name:"route",className:"size-4"}),n.jsx("span",{className:"diff-toolbar__walkthrough-label typography-ui-label",children:u("walkthrough.action.open")})]}),S.length>0&&n.jsxs(Bn,{children:[n.jsx(Vn,{asChild:!0,children:n.jsx(pe,{variant:"ghost",size:"sm",onClick:()=>xe(t=>!t),"aria-pressed":fe,"aria-label":u(fe?"diffView.actions.disableFullFiles":"diffView.actions.loadFullFiles"),className:ue("h-7 w-7 flex-shrink-0 p-0 text-muted-foreground hover:text-foreground",fe&&"bg-interactive-selection text-interactive-selection-foreground"),children:n.jsx(A,{name:"file-download",className:"size-4"})})}),n.jsx(Ln,{children:n.jsx("p",{children:u(fe?"diffView.actions.disableFullFiles":"diffView.actions.loadFullFiles")})})]}),S.length>0&&n.jsx(pe,{variant:"ghost",size:"sm",onClick:()=>Pt(!ut),className:ue("h-5 w-5 p-0 transition-opacity",qe?"text-foreground opacity-100":"text-muted-foreground opacity-60 hover:opacity-100"),title:u(qe?"diffView.actions.disableLineWrap":"diffView.actions.enableLineWrap"),children:n.jsx(A,{name:"text-wrap",className:"size-4"})}),jt&&n.jsx(Mt,{mode:jt==="side-by-side"?"side-by-side":"unified",onModeChange:mn})]}),n.jsx(Tn,{open:Le,onOpenChange:be,projectDirectory:m??null,submitting:we,onConfirm:dn}),bn()]})};export{Ki as DiffView};
|
|
4
|
+
`),d=Math.min(i.length,a.length);for(let f=0;f<d;f+=1)if(i[f]!==a[f])return f+1;return a.length>i.length?i.length+1:i.length>a.length?Math.max(1,a.length):1},ws=s=>/^Binary files .+ differ$/m.test(s)||/^GIT binary patch$/m.test(s),ys=s=>Array.isArray(s)?s.filter(e=>!e||typeof e!="object"?!1:typeof e.file=="string"):[],vs=s=>s==="added"?"A":s==="deleted"?"D":"M",lt=(s,e,i)=>ws(e)?{original:"",modified:"",isBinary:!0,patch:e,contextMode:i}:{original:"",modified:"",patch:e,fileDiff:Qn(s,e),contextMode:i},zt=(s,e,i)=>{const a=s??0,d=e??0;return!a&&!d?null:n.jsxs("span",{className:ue("typography-meta flex items-center gap-1 text-xs whitespace-nowrap","flex-shrink-0",i?.className),children:[a?n.jsxs("span",{style:{color:"var(--status-success)"},children:["+",a]}):null,d?n.jsxs("span",{style:{color:"var(--status-error)"},children:["-",d]}):null]})},js=o.memo(s=>{const e=he.c(58),{scope:i,workingCount:a,stagedCount:d,turnCount:f,branchCount:h,showBranchOption:x,onScopeChange:u}=s,{t:p}=ge(),[b,w]=o.useState(!1),y=i==="staged"?d:i==="turn"?f:i==="branch"?h??0:a;let j;e[0]!==i||e[1]!==p?(j=p(i==="staged"?"diffView.scope.staged":i==="turn"?"diffView.scope.lastTurn":i==="branch"?"diffView.scope.branch":"diffView.scope.changed"),e[0]=i,e[1]=p,e[2]=j):j=e[2];const P=j;let m;e[3]!==p?(m=p("diffView.scope.selectorAria"),e[3]=p,e[4]=m):m=e[4];let le;e[5]!==y?(le=n.jsxs("span",{className:"diff-toolbar__scope-count",children:[": ",y]}),e[5]=y,e[6]=le):le=e[6];let k;e[7]!==P||e[8]!==le?(k=n.jsxs("span",{className:"whitespace-nowrap",children:[P,le]}),e[7]=P,e[8]=le,e[9]=k):k=e[9];let E;e[10]===Symbol.for("react.memo_cache_sentinel")?(E=n.jsx(A,{name:"arrow-down-s",className:"size-4 flex-shrink-0 opacity-60"}),e[10]=E):E=e[10];let L;e[11]!==m||e[12]!==k?(L=n.jsx(On,{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":m,children:[k,E]})}),e[11]=m,e[12]=k,e[13]=L):L=e[13];let H;e[14]!==u?(H=B=>{(B==="working"||B==="staged"||B==="turn"||B==="branch")&&(u?.(B),w(!1))},e[14]=u,e[15]=H):H=e[15];let N;e[16]!==p?(N=p("diffView.scope.changed"),e[16]=p,e[17]=N):N=e[17];let ee;e[18]!==N?(ee=n.jsx("span",{children:N}),e[18]=N,e[19]=ee):ee=e[19];let U;e[20]!==a?(U=n.jsx("span",{className:"typography-meta text-muted-foreground",children:a}),e[20]=a,e[21]=U):U=e[21];let q;e[22]!==U||e[23]!==ee?(q=n.jsx(Ge,{value:"working",children:n.jsxs("span",{className:"flex min-w-0 flex-1 items-center justify-between gap-3",children:[ee,U]})}),e[22]=U,e[23]=ee,e[24]=q):q=e[24];let G;e[25]!==p?(G=p("diffView.scope.staged"),e[25]=p,e[26]=G):G=e[26];let K;e[27]!==G?(K=n.jsx("span",{children:G}),e[27]=G,e[28]=K):K=e[28];let te;e[29]!==d?(te=n.jsx("span",{className:"typography-meta text-muted-foreground",children:d}),e[29]=d,e[30]=te):te=e[30];let _;e[31]!==K||e[32]!==te?(_=n.jsx(Ge,{value:"staged",children:n.jsxs("span",{className:"flex min-w-0 flex-1 items-center justify-between gap-3",children:[K,te]})}),e[31]=K,e[32]=te,e[33]=_):_=e[33];let I;e[34]!==p?(I=p("diffView.scope.lastTurn"),e[34]=p,e[35]=I):I=e[35];let V;e[36]!==I?(V=n.jsx("span",{children:I}),e[36]=I,e[37]=V):V=e[37];let O;e[38]!==f?(O=n.jsx("span",{className:"typography-meta text-muted-foreground",children:f}),e[38]=f,e[39]=O):O=e[39];let ne;e[40]!==V||e[41]!==O?(ne=n.jsx(Ge,{value:"turn",children:n.jsxs("span",{className:"flex min-w-0 flex-1 items-center justify-between gap-3",children:[V,O]})}),e[40]=V,e[41]=O,e[42]=ne):ne=e[42];let T;e[43]!==h||e[44]!==x||e[45]!==p?(T=x?n.jsx(Ge,{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:h??"…"})]})}):null,e[43]=h,e[44]=x,e[45]=p,e[46]=T):T=e[46];let se;e[47]!==i||e[48]!==q||e[49]!==_||e[50]!==ne||e[51]!==T||e[52]!==H?(se=n.jsx(zn,{align:"start",className:"w-40",children:n.jsxs(Pn,{value:i,onValueChange:H,children:[q,_,ne,T]})}),e[47]=i,e[48]=q,e[49]=_,e[50]=ne,e[51]=T,e[52]=H,e[53]=se):se=e[53];let re;return e[54]!==b||e[55]!==se||e[56]!==L?(re=n.jsxs(Gn,{open:b,onOpenChange:w,children:[L,se]}),e[54]=b,e[55]=se,e[56]=L,e[57]=re):re=e[57],re}),Ss=o.memo(s=>{const e=he.c(11),{changedFiles:i,selectedFile:a,onSelectFile:d}=s,{t:f}=ge();if(i.length===0)return null;let h;if(e[0]!==i||e[1]!==d||e[2]!==a||e[3]!==f){let u;e[5]!==d||e[6]!==a||e[7]!==f?(u=p=>{const b=Ot(p),w=a===p.path;return n.jsx("li",{children:n.jsxs("button",{type:"button",onClick:()=>d(p.path),className:ue("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left transition-colors",w?"bg-interactive-selection text-interactive-selection-foreground":"text-muted-foreground hover:bg-interactive-hover hover:text-foreground"),children:[n.jsx(_t,{filePath:p.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:b.color},title:f(b.descriptionKey),"aria-label":f(b.descriptionKey),children:b.code}),n.jsx("span",{className:"min-w-0 flex-1 truncate typography-meta",style:{direction:"rtl",textAlign:"left",unicodeBidi:"plaintext"},title:p.path,children:p.path}),zt(p.insertions,p.deletions)]})},p.path)},e[5]=d,e[6]=a,e[7]=f,e[8]=u):u=e[8],h=i.map(u),e[0]=i,e[1]=d,e[2]=a,e[3]=f,e[4]=h}else h=e[4];let x;return e[9]!==h?(x=n.jsx(at,{outerClassName:"flex-1 min-h-0",className:"px-2 py-2",children:n.jsx("ul",{className:"flex flex-col gap-1",children:h})}),e[9]=h,e[10]=x):x=e[10],x}),Ns=o.memo(s=>{const e=he.c(20),{filePath:i,diff:a,renderSideBySide:d}=s,{t:f}=ge(),h=a.original.length>0,x=a.modified.length>0,u=d?"flex flex-row gap-6 items-start justify-center":"flex flex-col gap-4 items-center",p=d?"flex flex-col items-center gap-2 flex-1 min-w-0":"flex flex-col items-center gap-2";let b;e[0]===Symbol.for("react.memo_cache_sentinel")?(b={contain:"layout"},e[0]=b):b=e[0];let w;e[1]!==a.original||e[2]!==i||e[3]!==h||e[4]!==p||e[5]!==d||e[6]!==f?(w=h&&n.jsxs("div",{className:p,children:[n.jsx("span",{className:"typography-meta text-muted-foreground font-medium",children:f("diffView.image.original")}),n.jsx("img",{src:a.original,alt:f("diffView.image.originalAlt",{path:i}),className:d?"max-w-full max-h-[70vh] object-contain":"max-w-full object-contain",style:{imageRendering:"auto"}})]}),e[1]=a.original,e[2]=i,e[3]=h,e[4]=p,e[5]=d,e[6]=f,e[7]=w):w=e[7];let y;e[8]!==a.modified||e[9]!==i||e[10]!==x||e[11]!==h||e[12]!==p||e[13]!==d||e[14]!==f?(y=x&&n.jsxs("div",{className:p,children:[n.jsx("span",{className:"typography-meta text-muted-foreground font-medium",children:f(h?"diffView.image.modified":"diffView.image.new")}),n.jsx("img",{src:a.modified,alt:f("diffView.image.modifiedAlt",{path:i}),className:d?"max-w-full max-h-[70vh] object-contain":"max-w-full object-contain",style:{imageRendering:"auto"}})]}),e[8]=a.modified,e[9]=i,e[10]=x,e[11]=h,e[12]=p,e[13]=d,e[14]=f,e[15]=y):y=e[15];let j;return e[16]!==u||e[17]!==w||e[18]!==y?(j=n.jsx("div",{className:"w-full overflow-auto p-4",style:b,children:n.jsxs("div",{className:u,children:[w,y]})}),e[16]=u,e[17]=w,e[18]=y,e[19]=j):j=e[19],j}),Fs=o.memo(s=>{const e=he.c(16),{filePath:i,diff:a,renderSideBySide:d,wrapLines:f}=s;let h;e[0]!==i?(h=In(i)||"text",e[0]=i,e[1]=h):h=e[1];const x=h;if(a.isBinary){let b;return e[2]===Symbol.for("react.memo_cache_sentinel")?(b=n.jsx(ms,{}),e[2]=b):b=e[2],b}if(Ve(i)){let b;return e[3]!==a||e[4]!==i||e[5]!==d?(b=n.jsx(Ns,{filePath:i,diff:a,renderSideBySide:d}),e[3]=a,e[4]=i,e[5]=d,e[6]=b):b=e[6],b}let u;e[7]===Symbol.for("react.memo_cache_sentinel")?(u={contain:"layout"},e[7]=u):u=e[7];let p;return e[8]!==a.fileDiff||e[9]!==a.modified||e[10]!==a.original||e[11]!==i||e[12]!==x||e[13]!==d||e[14]!==f?(p=n.jsx("div",{className:"w-full",style:u,children:n.jsx(Hn,{original:a.original,modified:a.modified,fileDiff:a.fileDiff,language:x,fileName:i,renderSideBySide:d,wrapLines:f,layout:"inline"})}),e[8]=a.fileDiff,e[9]=a.modified,e[10]=a.original,e[11]=i,e[12]=x,e[13]=d,e[14]=f,e[15]=p):p=e[15],p}),ks=o.memo(s=>{const e=he.c(7),{filePath:i,staged:a,busyAction:d,disabled:f,onAction:h}=s,{t:x}=ge();let u;return e[0]!==d||e[1]!==f||e[2]!==i||e[3]!==h||e[4]!==a||e[5]!==x?(u=n.jsx("div",{className:"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:a?n.jsx(ot,{label:x("gitView.changes.unstageFileAria",{path:i}),icon:"arrow-go-back",loading:d==="unstage",disabled:f,onClick:()=>h("unstage")}):n.jsxs(n.Fragment,{children:[n.jsx(ot,{label:x("gitView.changes.revertFileAria",{path:i}),icon:"arrow-go-back",loading:d==="discard",disabled:f,tone:"failure",onClick:()=>h("discard")}),n.jsx(ot,{label:x("gitView.changes.stageFileAria",{path:i}),icon:"add",loading:d==="stage",disabled:f,tone:"success",onClick:()=>h("stage")})]})}),e[0]=d,e[1]=f,e[2]=i,e[3]=h,e[4]=a,e[5]=x,e[6]=u):u=e[6],u}),ot=s=>{const e=he.c(14),{label:i,icon:a,loading:d,disabled:f,tone:h,onClick:x}=s,u=h==="failure"&&"text-[var(--status-error)] hover:text-[var(--status-error)]",p=h==="success"&&"text-[var(--status-success)] hover:text-[var(--status-success)]";let b;e[0]!==u||e[1]!==p?(b=ue("h-6 w-6 rounded-none bg-transparent p-0 text-muted-foreground opacity-70 hover:bg-transparent hover:text-foreground hover:opacity-100",u,p),e[0]=u,e[1]=p,e[2]=b):b=e[2];let w;e[3]!==x?(w=P=>{P.stopPropagation(),x()},e[3]=x,e[4]=w):w=e[4];let y;e[5]!==a||e[6]!==d?(y=d?n.jsx(A,{name:"loader-4",className:"size-3.5 animate-spin"}):n.jsx(A,{name:a,className:a==="add"?"size-4":"size-3.5"}),e[5]=a,e[6]=d,e[7]=y):y=e[7];let j;return e[8]!==f||e[9]!==i||e[10]!==b||e[11]!==w||e[12]!==y?(j=n.jsx(pe,{variant:"ghost",size:"sm",className:b,disabled:f,title:i,"aria-label":i,onClick:w,children:y}),e[8]=f,e[9]=i,e[10]=b,e[11]=w,e[12]=y,e[13]=j):j=e[13],j},Cs=o.memo(({directory:s,file:e,layout:i,wrapLines:a,isSelected:d,isExpanded:f,isMounted:h,onSelect:x,onExpandedChange:u,registerSectionRef:p,showOpenInEditorAction:b=!1,isOpeningInEditor:w=!1,onOpenInEditor:y,staged:j=!1,loadFullFiles:P=!1,initialDiffData:m=null,readOnlyActions:le=!1})=>{const{t:k}=ge(),{git:E}=Tt(),L=Z(o.useCallback(c=>c.directories.get(s)?.diffCache.get(e.path)??null,[s,e.path])),H=Z(c=>c.setDiff),N=Z(c=>c.fetchStatus),ee=Y(c=>c.setDiffFileLayout),[U,q]=o.useState(0),[G,K]=o.useState(null),[te,_]=o.useState(!1),[I,V]=o.useState(null),[O,ne]=o.useState(!1),[T,se]=o.useState(null),[re,B]=o.useState(null),ie=o.useRef(null),We=o.useRef(null),ce=o.useMemo(()=>Ot(e),[e]),fe=i==="side-by-side",xe=P?"full":"patch",Ce=`${e.index}:${e.working_dir}:${e.insertions}:${e.deletions}`,X=o.useMemo(()=>m||(j?re:T||(L?{original:L.original,modified:L.modified,isBinary:L.isBinary,contextMode:"full"}:null)),[L,m,T,j,re]),Re=X?.contextMode===xe,He=o.useCallback(c=>{We.current=c,p(e.path,c)},[e.path,p]),Le=o.useCallback(c=>{u(e.path,c)},[e.path,u]),be=o.useCallback(()=>{x(e.path)},[e.path,x]);o.useEffect(()=>{j?B(null):se(null),K(null),ie.current=null},[Ce,j]),o.useEffect(()=>{if(!f||!h)return;if(!s||m||X&&Re){ie.current=null,_(!1);return}const c=`${s}::${e.path}::${j?"staged":"unstaged"}::${Ce}::${xe}::${U}`;if(ie.current===c)return;ie.current=c,K(null),_(!0);let C=!1;const oe=ct(),Me=P?cs:us,de=Ve(e.path)?E.getGitFileDiff(s,{path:e.path,staged:j}):E.getGitDiff(s,{path:e.path,staged:j,contextLines:Me}),De=ls,Ae=new Promise(($,J)=>{setTimeout(()=>J(new Error(`Timed out after ${De}ms`)),De)});return Promise.race([de,Ae]).then($=>{if(!C){if("diff"in $){const J=lt(e.path,$.diff,xe);j?B(J):se(J)}else{const J={original:$.original??"",modified:$.modified??"",isBinary:$.isBinary,contextMode:"full"};j?B(J):H(s,e.path,J,oe)}_(!1)}}).catch($=>{if(C)return;const J=$ instanceof Error?$.message:String($);K(J),_(!1)}),()=>{C=!0,ie.current===c&&(ie.current=null)}},[xe,X,Re,U,s,e.path,Ce,E,m,f,h,P,H,j]);const we=o.useCallback(()=>{Le(!f),be()},[Le,be,f]),Te=o.useCallback(async c=>{if(!(!s||I!==null)){V(c);try{c==="stage"?await E.stageGitFile(s,e.path):c==="unstage"?await E.unstageGitFile(s,e.path):await E.revertGitFile(s,e.path,{scope:"working"}),q(C=>C+1),await N(s,E)}catch(C){const oe=c==="unstage"?"gitView.toast.unstageFileFailed":c==="stage"?"gitView.toast.stageFileFailed":"gitView.toast.revertFailed";Ke.error(C instanceof Error?C.message:k(oe))}finally{V(C=>C===c?null:C)}}},[s,N,e.path,I,E,k]);return n.jsxs("div",{ref:He,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:we,onKeyDown:c=>{c.target===c.currentTarget&&(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),we())},className:ue("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",d?"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:f?n.jsx(A,{name:"arrow-down-s",className:"size-4"}):n.jsx(A,{name:"arrow-right-s",className:"size-4"})}),n.jsx("span",{className:"typography-micro font-semibold leading-none w-4 text-center uppercase",style:{color:ce.color},title:k(ce.descriptionKey),"aria-label":k(ce.descriptionKey),children:ce.code}),n.jsx("span",{className:"min-w-0 flex-1 overflow-hidden typography-ui-label",title:e.path,children:n.jsxs("span",{className:"flex min-w-0 items-center gap-2",children:[n.jsx(_t,{filePath:e.path,className:"h-3.5 w-3.5 flex-shrink-0 align-middle"}),(()=>{const c=e.path.lastIndexOf("/");if(c===-1)return n.jsx("span",{className:"block min-w-0 truncate typography-ui-label text-foreground",style:{direction:"rtl",textAlign:"left",unicodeBidi:"plaintext"},children:e.path});const C=e.path.slice(0,c),oe=e.path.slice(c+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:C}),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:oe})]})]})})()]})})]}),n.jsxs("div",{className:"relative flex shrink-0 items-center justify-self-end gap-2",children:[zt(e.insertions,e.deletions),b&&y?n.jsx(pe,{variant:"ghost",size:"sm",className:"h-5 w-5 p-0 opacity-70 hover:opacity-100",title:k("diffView.actions.openFileInEditorAtChange"),onClick:c=>{c.stopPropagation(),y(e.path,X)},disabled:w,children:w?n.jsx(A,{name:"loader-4",className:"size-3.5 animate-spin"}):n.jsx(A,{name:"edit",className:"size-3.5"})}):null,n.jsx(Mt,{mode:fe?"side-by-side":"unified",onModeChange:c=>{const C=c==="side-by-side"?"side-by-side":"inline";ee(e.path,C)},className:"opacity-70"})]})]})}),f&&n.jsxs("div",{className:"relative bg-background overflow-hidden",children:[!h&&!G?n.jsx("div",{className:"h-40 border border-border/40 bg-background/40"}):null,G?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:k("diffView.state.failedToLoadDiff")}),n.jsx("div",{className:"typography-meta text-muted-foreground max-w-[32rem] text-center",children:G}),n.jsx("button",{type:"button",className:"typography-ui-label text-primary hover:underline",onClick:()=>q(c=>c+1),children:k("diffView.actions.retry")})]}):null,h&&te&&!X&&!G?n.jsxs("div",{className:"flex items-center justify-center gap-2 px-4 py-8 text-sm text-muted-foreground",children:[n.jsx(A,{name:"loader-4",className:"size-4 animate-spin"}),k("diffView.state.loadingDiff")]}):null,h&&X&&!O&&e.insertions+e.deletions>Dt?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:k("diffView.state.largeDiff",{count:e.insertions+e.deletions})}),n.jsx("div",{className:"typography-meta text-muted-foreground",children:k("diffView.state.largeDiffDescription")}),n.jsx("button",{type:"button",className:"typography-ui-label text-primary hover:underline",onClick:()=>ne(!0),children:k("diffView.actions.renderAnyway")})]}):null,h&&X&&(O||e.insertions+e.deletions<=Dt)?n.jsxs(n.Fragment,{children:[n.jsx(Fs,{filePath:e.path,diff:X,renderSideBySide:fe,wrapLines:a}),n.jsx("div",{className:"pointer-events-none absolute bottom-3 right-3 z-20",children:n.jsx("div",{className:"pointer-events-auto",children:le?null:n.jsx(ks,{filePath:e.path,staged:j,busyAction:I,disabled:I!==null,onAction:Te})})})]}):null]})]})}),Ki=({hideStackedFileSidebar:s=!1,stackedDefaultCollapsedAll:e=!1,pinSelectedFileHeaderToTopOnNavigate:i=!1,showOpenInEditorAction:a=!1,diffScope:d="all",onDiffScopeChange:f,targetFilePath:h=null,flushContent:x=!1})=>{const{t:u}=ge(),{git:p,files:b}=Tt(),w=yn(),{rootIsGitRepo:y,gitDirectory:j,nestedRepos:P}=vn(w??null),m=j??w,le=Y(t=>t.openContextSurface),k=Un(t=>t.requestSource),{screenWidth:E,isMobile:L}=jn(),H=Sn(m??null),N=Nn(m??null),ee=Fn(m??null),U=Z(t=>t.setActiveDirectory),q=Z(t=>t.ensureStatus),G=Z(t=>t.selectNestedRepo),K=Z(t=>t.fetchStatus),te=Z(t=>t.fetchBranches),_=Z(t=>t.clearDiffCache),I=Z(t=>t.setDiff),[V,O]=o.useState(null),[ne,T]=o.useState(!1),[se,re]=o.useState(null),[B,ie]=o.useState(()=>new Set),[We,ce]=o.useState(()=>new Set),[fe,xe]=o.useState(!1),[Ce,X]=o.useState(0),[Re,He]=o.useState(()=>new Map),[Le,be]=o.useState(!1),[we,Te]=o.useState(!1),[c,C]=o.useState(d);o.useEffect(()=>{C(d)},[d]);const oe=Y(t=>t.pendingDiffFile),Me=Y(t=>t.pendingDiffStaged),de=Y(t=>t.pendingDiffScope),De=Y(t=>t.setPendingDiffFile),Ae=Y(t=>t.diffLayoutPreference),$=Y(t=>t.diffFileLayout),J=Y(t=>t.setDiffFileLayout),ut=Y(t=>t.diffWrapLines),Pt=Y(t=>t.setDiffWrapLines),ft=Y(t=>t.openContextFileAtLine),ye=Ft(t=>t.currentSessionId),Ue=kn(ye??"",w??void 0),qe=ut,Xe=c==="staged"?!0:c==="working"?!1:null,_e=Xe??ne,Je=L||E<=768,Gt=!!ye&&c!=="turn"&&!Je&&!Pe(),Kt=c!=="turn"&&!Je&&!Pe(),$t=!s&&!Je&&E>=1024,ve=o.useRef(null),Ee=o.useRef(new Map),me=o.useRef(null),z=o.useRef(null),je=o.useRef(!1),Se=o.useRef(null),dt=o.useRef(null),Qe=o.useRef(null),Ye=o.useRef(null),pt=o.useCallback(()=>{const t=ve.current;if(!t)return null;const r=t.getBoundingClientRect().top,l=[];for(const[g,v]of Ee.current)v&&l.push({path:g,top:v.getBoundingClientRect().top});return Ct(r,l)},[]),Ne=o.useCallback(()=>{me.current=null,je.current=!1,re(null),z.current!==null&&(window.cancelAnimationFrame(z.current),z.current=null)},[]),Fe=o.useCallback(t=>{ie(r=>{if(r.has(t))return r;const l=new Set(r);return l.add(t),l})},[]),Be=o.useMemo(()=>{for(let t=Ue.length-1;t>=0;t-=1){const r=Ue[t];if(r.role==="user")return ys(r.summary?.diffs)}return[]},[Ue]),Wt=o.useMemo(()=>{const t=new Map;for(const r of Be)if(r.file){if(typeof r.patch=="string"){t.set(r.file,lt(r.file,r.patch,"patch"));continue}t.set(r.file,{original:r.before??"",modified:r.after??"",contextMode:"full"})}return t},[Be]),Ht=o.useMemo(()=>N?.files?N.files.filter(Bt).length:0,[N]),Ut=o.useMemo(()=>N?.files?N.files.filter(Et).length:0,[N]),qt=Be.length,R=N?.current??null,ke=Z(t=>m?t.directories.get(m)?.branches??null:null),Xt=Z(t=>m?t.directories.get(m)?.isLoadingBranches??!1:!1),Jt=o.useCallback(()=>{m&&te(m,p)},[m,te,p]),Qt=rs(m??null,H!==!1,Xt,!!ke,Jt,ps),mt=o.useMemo(()=>{const t=N?.tracking?.trim().split("/")[0];return(t&&ke?.defaultBranches?.[t])??ke?.defaultBranches?.origin??null},[ke,N?.tracking]),Ze=!Pe()&&es(R,mt),Yt=N!==null,ht=Pe()||Qt||ts(R,mt,Yt,ke!==null),Zt=kt(t=>t.setOverride),en=kt(o.useCallback(t=>m&&R?t.overrides[$e(m,R)]??null:null,[R,m])),[tn,et]=o.useState(null),[nn,tt]=o.useState(!1),[gt,sn]=o.useState("");o.useEffect(()=>{const t=ns(c,!ht);t!==c&&(C(t),t==="working"&&f?.("working"))},[c,ht,f]),o.useEffect(()=>{if(!Ze||!m||!R){et(null),tt(!1);return}let t=!1;return tt(!1),Cn(m,R).then(r=>{t||et(r.base)}).catch(()=>{t||et(null)}).finally(()=>{t||tt(!0)}),()=>{t=!0}},[R,m,Ze]);const ae=en??tn,[Ie,xt]=o.useState(null),[bt,wt]=o.useState(null),Oe=o.useRef(0),nt=o.useCallback(()=>{if(!m||!R||!ae)return;const t=Oe.current+1;Oe.current=t,xt(null),wt(null),Rn(m,{base:ae,head:R}).then(r=>{Oe.current===t&&xt(r)}).catch(r=>{Oe.current===t&&wt(r instanceof Error?r.message:u("diffView.branch.loadError"))})},[ae,R,m,u]);o.useEffect(()=>{c==="branch"&&nt()},[c,nt]);const yt=c==="branch"&&m&&R&&ae?ss(m,ae,R):null,rn=o.useMemo(()=>c==="branch"?Array.from(B).sort().join("\0"):"",[c,B]),on=o.useCallback(t=>!m||!ae||!R?Promise.reject(new Error("branch range is unavailable")):Dn(m,{base:ae,head:R,path:t}).then(r=>lt(t,r.diff,"patch")),[ae,R,m]),an=is(yt,rn,yt?on:null,ds),ln=Ie?.length??null,S=o.useMemo(()=>{if(c==="branch")return(Ie??[]).map(l=>({path:l.path,index:"",working_dir:l.status,insertions:0,deletions:0,isNew:l.status==="A"})).sort((l,g)=>l.path.localeCompare(g.path));if(c==="turn")return Be.map(l=>({path:l.file??"",index:"",working_dir:vs(l.status),insertions:l.additions??0,deletions:l.deletions??0,isNew:l.status==="added"})).filter(l=>l.path).sort((l,g)=>l.path.localeCompare(g.path));if(!N?.files)return[];const t=N.diffStats??{},r=c==="staged"?Et:c==="working"?Bt:()=>!0;return N.files.filter(r).map(l=>({...l,insertions:t[l.path]?.insertions??0,deletions:t[l.path]?.deletions??0,isNew:xs(l)})).sort((l,g)=>l.path.localeCompare(g.path))},[c,Ie,Be,N]),st=o.useMemo(()=>S.map(t=>t.path).join("\0"),[S]);o.useEffect(()=>{const t=st?st.split("\0"):[],r=new Set(t),l=`${m??""}:${c}:${e?"collapsed":"default"}`,g=dt.current!==l;dt.current=l,ie(v=>{if(g){const D=e?0:fs(t.length);return new Set(t.slice(0,D))}let M=!1;const F=new Set;for(const D of v){if(!r.has(D)){M=!0;continue}F.add(D)}return M?F:v}),ce(v=>{if(g)return new Set;let M=!1;const F=new Set;for(const D of v){if(!r.has(D)){M=!0;continue}F.add(D)}return M?F:v})},[c,st,m,e]);const vt=o.useCallback(()=>{Se.current=null;const t=ve.current;if(!t)return;const r=t.getBoundingClientRect(),l=r.top-At,g=r.bottom+At,v={},M=[];for(const[F,D]of Ee.current){if(!D)continue;const W=D.getBoundingClientRect();M.push({path:F,top:W.top}),B.has(F)&&(W.bottom<l||W.top>g||(v[F]=!0))}Qe.current=Ct(r.top,M),ce(F=>{let D=!1;const W=new Set(F);for(const Nt of Object.keys(v))W.has(Nt)||(W.add(Nt),D=!0);return D?W:F})},[B]),Q=o.useCallback(()=>{typeof window>"u"||Se.current===null&&(Se.current=window.requestAnimationFrame(vt))},[vt]);o.useEffect(()=>{const t=ve.current;if(t)return Q(),t.addEventListener("scroll",Q,{passive:!0}),window.addEventListener("resize",Q),()=>{t.removeEventListener("scroll",Q),window.removeEventListener("resize",Q),Se.current!==null&&(window.cancelAnimationFrame(Se.current),Se.current=null)}},[S,B,Q]);const rt=o.useCallback(t=>{const r=$[t.path];if(r)return r;if(Ae==="inline")return"inline";if(Ae==="side-by-side")return"side-by-side";const l=E<as;return t.isNew||l?"inline":"side-by-side"},[$,Ae,E]),jt=o.useMemo(()=>S.length===0?null:S.every(t=>rt(t)==="side-by-side")?"side-by-side":"inline",[S,rt]);o.useEffect(()=>{m&&(U(m),q(m,p))},[m,U,q,p]),o.useEffect(()=>{if(m)return An.onGitRefreshHint(t=>{Vt(t.directory)===Vt(m)&&(t.paths?.length&&(Ye.current=pt()??Qe.current,_(m,t.paths),He(r=>{const l=new Map(r);for(const g of t.paths??[])l.set(g,(l.get(g)??0)+1);return l})),K(m,p,{silent:!0}))})},[pt,_,m,K,p]),o.useLayoutEffect(()=>{const t=Ye.current;if(!t)return;Ye.current=null;const r=ve.current,l=Ee.current.get(t.path);if(!r||!l)return;const g=r.getBoundingClientRect().top,v=l.getBoundingClientRect().top-g;r.scrollTop=os(r.scrollTop,t.topOffset,v,r.scrollHeight-r.clientHeight),Qe.current=t},[Re]),o.useEffect(()=>{c!=="all"&&!de||oe&&(de&&C(de),O(oe),T(de==="staged"||!de&&Me),De(null),je.current=!0,me.current=oe,Fe(oe),X(t=>t+1))},[c,Fe,oe,de,Me,De]),o.useEffect(()=>{if(c==="all")return;const t=h?.trim();t&&(O(t),T(c==="staged"),je.current=!0,me.current=t,Fe(t),X(r=>r+1))},[c,Fe,h]),o.useEffect(()=>{if(!V)return;S.some(r=>r.path===V)||(O(null),T(!1))},[S,V]);const cn=o.useCallback((t,r)=>{const l=Ee.current;r?l.set(t,r):l.delete(t),Q()},[Q]),un=o.useCallback((t,r)=>{Ne(),ie(l=>{const g=l.has(t);if(r===g)return l;const v=new Set(l);return r?v.add(t):v.delete(t),v}),r||ce(l=>{if(!l.has(t))return l;const g=new Set(l);return g.delete(t),g}),Q()},[Ne,Q]),fn=o.useCallback(()=>{Ne(),ie(t=>t.size>0?new Set:new Set(S.map(r=>r.path))),ce(new Set),Q()},[Ne,S,Q]),dn=o.useCallback(async t=>{if(!ye)return;const r=Ft.getState().getDirectoryForSession(ye)||w||"";if(!r){Ke.error(u("diffView.reviewDialog.toast.noSessionDirectory"));return}Te(!0);try{await En({originalSessionID:ye,directory:r,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}),be(!1)}catch(l){console.error("[review-flow] failed to start review flow",l),Ke.error(l instanceof Error?l.message:u("diffView.reviewDialog.toast.startFailed"))}finally{Te(!1)}},[ye,w,u]),ze=o.useCallback(t=>{const r=Ee.current.get(t),l=ve.current;if(!r||!l)return!1;const g=r.getBoundingClientRect().top-l.getBoundingClientRect().top;return l.scrollTo({top:l.scrollTop+g,behavior:"auto"}),!0},[]);o.useEffect(()=>{if(!me.current)return;let r=0;const l=20;let g=!1;const v=(F=!0)=>{g||(g=!0,me.current=null,je.current=!1,F&&re(null),z.current!==null&&(window.cancelAnimationFrame(z.current),z.current=null))},M=()=>{if(g){z.current=null;return}const F=me.current;if(!F){v(),z.current=null;return}if(!ze(F)){r+=1,r<l?z.current=window.requestAnimationFrame(M):(v(),z.current=null);return}if(i&&je.current){re(F),v(!1);return}v()};return z.current=window.requestAnimationFrame(M),()=>{g=!0,z.current!==null&&(window.cancelAnimationFrame(z.current),z.current=null)}},[i,Ce,ze]);const pn=o.useCallback(t=>{},[]),it=o.useCallback(t=>{Ne(),O(t),T(!1),je.current=!0,me.current=t,Fe(t),X(r=>r+1),ze(t)},[Ne,Fe,ze]);o.useEffect(()=>{const t=r=>{if(!r.altKey||r.metaKey||r.ctrlKey||r.shiftKey||r.key!=="ArrowDown"&&r.key!=="ArrowUp")return;const l=r.target;if(l instanceof HTMLElement&&(l.isContentEditable||l.tagName==="INPUT"||l.tagName==="TEXTAREA"||l.closest('[role="dialog"]'))||S.length===0)return;const g=r.key==="ArrowDown"?1:-1,v=V?S.findIndex(D=>D.path===V):-1,M=v===-1?g>0?0:S.length-1:v+g,F=S[M];F&&(r.preventDefault(),it(F.path))};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[S,V,it]);const mn=o.useCallback(t=>{const r=t==="side-by-side"?"side-by-side":"inline";S.forEach(l=>{J(l.path,r)})},[S,J]),[hn,St]=o.useState(null),gn=o.useCallback(async(t,r)=>{if(!m||!t)return;St(t);const l=ct();try{let g=null;if(r?.patch&&!r.isBinary&&!Ve(t)?g=Rt(r.patch):r&&r.contextMode==="full"&&!r.isBinary&&!Ve(t)&&(g=Lt(r.original,r.modified)),g===null)try{const W=await p.getGitDiff(m,{path:t,staged:_e,contextLines:3});g=Rt(W.diff)}catch{g=null}let v=r;if(g===null||!v){const W=await p.getGitFileDiff(m,{path:t,staged:_e});v={original:W.original??"",modified:W.modified??"",isBinary:W.isBinary},_e||I(m,t,v,l)}const M=g??(v.isBinary||Ve(t)?1:Lt(v.original,v.modified)),F=bs(m,t),D=await qn(b,F,{directory:m});if(!D.ok){Ke.error(Xn(D.reason));return}ft(m,F,M,1)}finally{St(g=>g===t?null:g)}},[_e,m,b,p,ft,I]),xn=()=>{if(!m)return null;const t=r=>Xe!==null?Xe:ne&&r===V;return n.jsxs("div",{className:ue("flex min-w-0 flex-1 min-h-0 h-full",x?"gap-0":"gap-3 px-3 pb-3 pt-2"),children:[$t&&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:u("diffView.section.files")}),n.jsx("span",{className:"typography-meta text-muted-foreground",children:S.length})]}),n.jsx(Ss,{changedFiles:S,selectedFile:null,onSelectFile:it})]}),n.jsx("div",{className:"relative flex-1 min-w-0 min-h-0 h-full",children:n.jsx(at,{ref:ve,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:S.map(r=>n.jsx(Cs,{directory:m,file:r,layout:rt(r),wrapLines:qe,isSelected:!1,isExpanded:B.has(r.path),isMounted:We.has(r.path)||r.path===se,onSelect:pn,onExpandedChange:un,registerSectionRef:cn,showOpenInEditorAction:a&&c!=="turn",isOpeningInEditor:hn===r.path,onOpenInEditor:(l,g)=>{gn(l,g)},staged:t(r.path),loadFullFiles:fe,readOnlyActions:c==="branch",initialDiffData:c==="turn"?Wt.get(r.path)??null:c==="branch"?an.get(r.path)??null:null},`${r.path}:${Re.get(r.path)??0}`))})})})]})},bn=()=>{if(!m)return n.jsx("div",{className:"flex flex-1 items-center justify-center text-sm text-muted-foreground",children:u("diffView.state.selectSessionDirectory")});if(c!=="turn"&&ee&&!N)return n.jsxs("div",{className:"flex flex-1 items-center justify-center gap-2 text-sm text-muted-foreground",children:[n.jsx(A,{name:"loader-4",className:"size-4 animate-spin"}),u("diffView.state.loadingRepositoryStatus")]});if(c!=="turn"&&H===!1)return n.jsx("div",{className:"flex flex-1 items-center justify-center text-sm text-muted-foreground",children:u("diffView.state.notGitRepository")});if(c==="branch"){if(!nn)return n.jsxs("div",{className:"flex flex-1 items-center justify-center gap-2 text-sm text-muted-foreground",children:[n.jsx(A,{name:"loader-4",className:"size-4 animate-spin"}),u("diffView.branch.resolvingBase")]});if(!ae){const t=(ke?.all??[]).map(l=>l.replace(/^remotes\//,"")).filter(l=>l!==R&&!l.endsWith(`/${R}`)).sort(),r=_n(t,gt,l=>[l]);return n.jsxs("div",{className:"flex flex-1 flex-col items-center justify-center gap-3 px-6 text-center",children:[n.jsx(A,{name:"git-branch",className:"size-6 text-muted-foreground"}),n.jsx("div",{className:"typography-ui-label font-semibold text-foreground",children:u("diffView.branch.noBaseTitle")}),n.jsx("div",{className:"max-w-sm typography-micro text-muted-foreground",children:u("diffView.branch.noBaseDescription")}),n.jsx("input",{type:"text",value:gt,onChange:l=>sn(l.target.value),placeholder:u("gitView.branch.searchPlaceholder"),"aria-label":u("gitView.branch.searchPlaceholder"),className:"w-full max-w-sm rounded-md border border-border/60 bg-[var(--surface-elevated)] px-2.5 py-1.5 typography-meta text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-[var(--interactive-focus-ring)]"}),n.jsx(at,{outerClassName:"max-h-48 w-full max-w-sm min-h-0",className:"px-1 py-1",children:r.length===0?n.jsx("div",{className:"px-2 py-3 typography-meta text-muted-foreground",children:u("gitView.branch.empty")}):n.jsx("div",{className:"flex flex-col gap-0.5",children:r.map(l=>n.jsxs("button",{type:"button",onClick:()=>m&&R&&Zt(m,R,l),className:"flex items-center gap-2 rounded-md px-2 py-1.5 text-left hover:bg-interactive-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--interactive-focus-ring)]",children:[n.jsx(A,{name:"git-branch",className:"size-3.5 text-primary"}),n.jsx("span",{className:"truncate typography-ui-label text-foreground",title:l,children:l})]},l))})})]})}if(bt)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:u("diffView.branch.loadError")}),n.jsx("div",{className:"max-w-sm typography-micro text-muted-foreground",children:bt}),n.jsx(pe,{variant:"outline",size:"sm",onClick:()=>nt(),children:u("diffView.actions.retry")})]});if(Ie===null)return n.jsxs("div",{className:"flex flex-1 items-center justify-center gap-2 text-sm text-muted-foreground",children:[n.jsx(A,{name:"loader-4",className:"size-4 animate-spin"}),u("diffView.branch.loadingFiles")]})}return S.length===0?n.jsx("div",{className:"flex flex-1 items-center justify-center text-sm text-muted-foreground",children:c==="turn"?u("diffView.state.noLastTurnChanges"):c==="branch"&&ae?u("diffView.branch.empty",{base:ae}):u("diffView.state.cleanWorkingTree")}):xn()};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:[y===!1&&Array.isArray(P)&&P.length>0?n.jsx(Kn,{repositories:P,selectedRepository:j??null,onSelectRepository:t=>{w&&G(w,t)},repositoryRoot:w??void 0}):null,!L&&(c==="working"||c==="staged"||c==="turn"||c==="branch"?n.jsx(js,{scope:c,workingCount:Ht,stagedCount:Ut,turnCount:qt,branchCount:ln,showBranchOption:Ze,onScopeChange:t=>{C(t),f?.(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:ee&&!N?u("diffView.state.loadingChanges"):S.length===1?u("diffView.summary.changedFilesSingle",{count:S.length}):u("diffView.summary.changedFilesPlural",{count:S.length})})})),S.length>0&&n.jsxs(pe,{variant:"ghost",size:"sm",onClick:fn,className:ue("diff-toolbar__expand-button h-7 flex-shrink-0 gap-1 px-1.5 text-muted-foreground hover:text-foreground","ml-auto"),title:B.size>0?u("diffView.actions.collapseAll"):u("diffView.actions.expandAll"),children:[n.jsx(A,{name:"expand-up-down",className:"size-4"}),n.jsx("span",{className:"diff-toolbar__expand-label typography-ui-label",children:B.size>0?u("diffView.actions.collapseAll"):u("diffView.actions.expandAll")})]}),S.length>0&&Gt&&n.jsxs(pe,{variant:"default",size:"sm",onClick:()=>be(!0),disabled:we,className:"diff-toolbar__review-button h-7 flex-shrink-0 gap-1.5 px-2","aria-label":u("diffView.actions.reviewAria"),children:[we?n.jsx(A,{name:"loader-4",className:"size-4 animate-spin"}):n.jsx(A,{name:"search-eye",className:"size-4"}),n.jsx("span",{className:"diff-toolbar__review-label typography-ui-label",children:u("diffView.actions.review")})]}),S.length>0&&Kt&&n.jsxs(pe,{variant:"outline",size:"sm",onClick:()=>{const t=m??"";k(t,{kind:"working-tree",scope:c==="staged"||c==="working"?c:"all"}),le(t,"walkthrough")},className:ue("diff-toolbar__walkthrough-button h-7 flex-shrink-0 gap-1.5 px-2",Jn),"aria-label":u("walkthrough.action.open"),children:[n.jsx(A,{name:"route",className:"size-4"}),n.jsx("span",{className:"diff-toolbar__walkthrough-label typography-ui-label",children:u("walkthrough.action.open")})]}),S.length>0&&n.jsxs(Bn,{children:[n.jsx(Vn,{asChild:!0,children:n.jsx(pe,{variant:"ghost",size:"sm",onClick:()=>xe(t=>!t),"aria-pressed":fe,"aria-label":u(fe?"diffView.actions.disableFullFiles":"diffView.actions.loadFullFiles"),className:ue("h-7 w-7 flex-shrink-0 p-0 text-muted-foreground hover:text-foreground",fe&&"bg-interactive-selection text-interactive-selection-foreground"),children:n.jsx(A,{name:"file-download",className:"size-4"})})}),n.jsx(Ln,{children:n.jsx("p",{children:u(fe?"diffView.actions.disableFullFiles":"diffView.actions.loadFullFiles")})})]}),S.length>0&&n.jsx(pe,{variant:"ghost",size:"sm",onClick:()=>Pt(!ut),className:ue("h-5 w-5 p-0 transition-opacity",qe?"text-foreground opacity-100":"text-muted-foreground opacity-60 hover:opacity-100"),title:u(qe?"diffView.actions.disableLineWrap":"diffView.actions.enableLineWrap"),children:n.jsx(A,{name:"text-wrap",className:"size-4"})}),jt&&n.jsx(Mt,{mode:jt==="side-by-side"?"side-by-side":"unified",onModeChange:mn})]}),n.jsx(Tn,{open:Le,onOpenChange:be,projectDirectory:m??null,submitting:we,onConfirm:dn}),bn()]})};export{Ki as DiffView};
|