cli-jaw 2.17.41 → 2.17.42
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 +3 -3
- package/dist/bin/commands/browser.js +52 -5
- package/dist/bin/commands/browser.js.map +1 -1
- package/dist/src/agent/args.js +69 -19
- package/dist/src/agent/args.js.map +1 -1
- package/dist/src/agent/codex-app-events.js +31 -1
- package/dist/src/agent/codex-app-events.js.map +1 -1
- package/dist/src/agent/cursor-model-inventory.js +140 -0
- package/dist/src/agent/cursor-model-inventory.js.map +1 -0
- package/dist/src/agent/grok-models.js +80 -0
- package/dist/src/agent/grok-models.js.map +1 -0
- package/dist/src/browser/actions.js +383 -20
- package/dist/src/browser/actions.js.map +1 -1
- package/dist/src/browser/grounding-candidate.js +272 -0
- package/dist/src/browser/grounding-candidate.js.map +1 -0
- package/dist/src/browser/grounding-eval.js +247 -0
- package/dist/src/browser/grounding-eval.js.map +1 -0
- package/dist/src/browser/image-size.js +63 -0
- package/dist/src/browser/image-size.js.map +1 -0
- package/dist/src/browser/index.js +1 -0
- package/dist/src/browser/index.js.map +1 -1
- package/dist/src/browser/occlusion.js +148 -0
- package/dist/src/browser/occlusion.js.map +1 -0
- package/dist/src/browser/verify-candidate.js +162 -0
- package/dist/src/browser/verify-candidate.js.map +1 -0
- package/dist/src/browser/vision-input.js +74 -0
- package/dist/src/browser/vision-input.js.map +1 -0
- package/dist/src/browser/vision-provider.js +75 -0
- package/dist/src/browser/vision-provider.js.map +1 -0
- package/dist/src/browser/vision.js +360 -47
- package/dist/src/browser/vision.js.map +1 -1
- package/dist/src/browser/web-ai/candidate-reconcile.js +14 -5
- package/dist/src/browser/web-ai/candidate-reconcile.js.map +1 -1
- package/dist/src/cli/claude-model-discovery.js +175 -0
- package/dist/src/cli/claude-model-discovery.js.map +1 -0
- package/dist/src/cli/claude-models.js +46 -0
- package/dist/src/cli/claude-models.js.map +1 -1
- package/dist/src/cli/registry-live.js +104 -1
- package/dist/src/cli/registry-live.js.map +1 -1
- package/dist/src/cli/registry.js +28 -5
- package/dist/src/cli/registry.js.map +1 -1
- package/dist/src/code-mode/host.js +6 -0
- package/dist/src/code-mode/host.js.map +1 -1
- package/dist/src/code-mode/manager.js +37 -8
- package/dist/src/code-mode/manager.js.map +1 -1
- package/dist/src/code-mode/providers/catalog.js +53 -1
- package/dist/src/code-mode/providers/catalog.js.map +1 -1
- package/dist/src/code-mode/providers/codex-app.js +6 -0
- package/dist/src/code-mode/providers/codex-app.js.map +1 -1
- package/dist/src/code-mode/providers/live-models.js +85 -0
- package/dist/src/code-mode/providers/live-models.js.map +1 -0
- package/dist/src/code-mode/providers/provider-live-models.js +120 -0
- package/dist/src/code-mode/providers/provider-live-models.js.map +1 -0
- package/dist/src/code-mode/session.js +37 -0
- package/dist/src/code-mode/session.js.map +1 -1
- package/dist/src/prompt/templates/a1-system.md +24 -14
- package/dist/src/prompt/templates/control-system.md +6 -11
- package/dist/src/prompt/templates/employee.md +5 -5
- package/dist/src/routes/browser.js +17 -5
- package/dist/src/routes/browser.js.map +1 -1
- package/package.json +1 -1
- package/public/css/activity.css +20 -1
- package/public/css/layout.css +7 -3
- package/public/dist/.vite/manifest.json +104 -105
- package/public/dist/assets/Agent-CQ4EBgY8.js +1 -0
- package/public/dist/assets/CodeCanvas-DWsx6sv5.js +2 -0
- package/public/dist/assets/DashboardMeta-Dh-tasbY.js +1 -0
- package/public/dist/assets/Display-NrqY_IaN.js +1 -0
- package/public/dist/assets/{Permissions-BzbnqenZ.js → Permissions-Bh947tUG.js} +1 -1
- package/public/dist/assets/Permissions-DzNJCt8K.js +1 -0
- package/public/dist/assets/app-BCBnxiGr.css +1 -0
- package/public/dist/assets/{app-x5Kray4W.js → app-Q0prKOFx.js} +4 -4
- package/public/dist/assets/{bgtask-badge-W9djRQVu.js → bgtask-badge-DAcWaUfS.js} +1 -1
- package/public/dist/assets/bgtask-badge-DHA2OQm8.js +1 -0
- package/public/dist/assets/{employees--_dmDw_a.js → employees-CWS3Juca.js} +1 -1
- package/public/dist/assets/{iframe-renderer-D4BmLtAq.js → iframe-renderer-DCDKBMb7.js} +2 -2
- package/public/dist/assets/iframe-renderer-RpvBly2x.js +1 -0
- package/public/dist/assets/manager-Nk7-RYPs.css +1 -0
- package/public/dist/assets/manager-XkR-DRaQ.js +5 -0
- package/public/dist/assets/manager-shortcuts-jsiX-zV6.js +1 -0
- package/public/dist/assets/memory-4YH8sz0L.js +1 -0
- package/public/dist/assets/{memory-DENQWzM8.js → memory-DhNdKZLO.js} +1 -1
- package/public/dist/assets/{message-history-BsrLcGJj.js → message-history-DbRTl1P0.js} +1 -1
- package/public/dist/assets/message-history-lVcLpAw8.js +1 -0
- package/public/dist/assets/{render-CF6Q1oIh.js → render-DP8SJtdZ.js} +1 -1
- package/public/dist/assets/settings--EGy3_B9.js +1 -0
- package/public/dist/assets/settings-85n9NjvX.js +1 -0
- package/public/dist/assets/{settings-B-C_jdZR.js → settings-C9_D-pn0.js} +32 -32
- package/public/dist/assets/settings-core-8wBl1mg-.js +1 -0
- package/public/dist/assets/{settings-core-BzAJLsKN.js → settings-core-BcVD2FgV.js} +1 -1
- package/public/dist/assets/{settings-embedding-dEMyByVi.js → settings-embedding-BSpq785l.js} +1 -1
- package/public/dist/assets/{settings-embedding-BSA42oKM.css → settings-embedding-LIMq5ebM.css} +1 -1
- package/public/dist/assets/{sidebar-fFEOpvJl.js → sidebar-BVhLb5Ft.js} +3 -3
- package/public/dist/assets/skills-6GFkHTlQ.js +1 -0
- package/public/dist/assets/{skills-Da_b06ci.js → skills-X7qxmHka.js} +1 -1
- package/public/dist/assets/{slash-commands-BbPUHHF4.js → slash-commands-BnDH4IU_.js} +1 -1
- package/public/dist/assets/slash-commands-qu8fPAZ3.js +1 -0
- package/public/dist/assets/{trace-drawer-B-QmzUfP.js → trace-drawer-DasaS1z4.js} +1 -1
- package/public/dist/assets/{ui-CkRUrIfp.js → ui-BtiBTXng.js} +1 -1
- package/public/dist/assets/ui-BucJ1zMA.js +1 -0
- package/public/dist/index.html +2 -2
- package/public/dist/manager/index.html +3 -3
- package/public/dist/settings/index.html +2 -2
- package/public/js/features/settings.ts +16 -0
- package/public/manager/src/App.tsx +10 -12
- package/public/manager/src/AppChrome.tsx +2 -3
- package/public/manager/src/InstancePreview.tsx +47 -0
- package/public/manager/src/SidebarRailRouter.tsx +34 -30
- package/public/manager/src/code/CodeComposer.tsx +31 -6
- package/public/manager/src/code/CodeSessionList.tsx +25 -7
- package/public/manager/src/code/CodeToastHost.tsx +49 -0
- package/public/manager/src/code/CodeTranscript.tsx +136 -26
- package/public/manager/src/code/CodeWorkbench.tsx +16 -2
- package/public/manager/src/code/ComposerFooter.tsx +130 -46
- package/public/manager/src/code/ContextUsageMeter.tsx +72 -0
- package/public/manager/src/code/ProviderGlyph.tsx +58 -0
- package/public/manager/src/code/code-composer.css +159 -175
- package/public/manager/src/code/code-controller-runtime.ts +3 -1
- package/public/manager/src/code/code-session-state.ts +7 -1
- package/public/manager/src/code/code-toasts.ts +73 -0
- package/public/manager/src/code/code-workbench.css +42 -1
- package/public/manager/src/code/code.css +130 -15
- package/public/manager/src/code/context-usage.ts +74 -0
- package/public/manager/src/code/pending-user-item.ts +46 -0
- package/public/manager/src/code/session-order.ts +70 -0
- package/public/manager/src/code/tool-summary.ts +101 -0
- package/public/manager/src/code/use-dictation.ts +130 -0
- package/public/manager/src/components/CommandCenter.tsx +4 -8
- package/public/manager/src/components/InstanceDetailPanel.tsx +0 -18
- package/public/manager/src/components/Workbench.tsx +6 -10
- package/public/manager/src/components/WorkbenchHeader.tsx +0 -11
- package/public/manager/src/dashboard-settings/dashboard-settings-ui.ts +3 -1
- package/public/manager/src/hooks/useDashboardView.ts +38 -38
- package/public/manager/src/manager-components.css +0 -8
- package/public/manager/src/manager-shortcut-runner.ts +0 -1
- package/public/manager/src/manager-shortcuts.ts +0 -2
- package/public/manager/src/settings/pages/Agent.tsx +5 -2
- package/public/manager/src/settings/pages/DashboardMeta.tsx +20 -1
- package/public/manager/src/settings/pages/Permissions.tsx +23 -4
- package/public/manager/src/settings/pages/components/agent/PermissionQuickSection.tsx +6 -2
- package/public/manager/src/settings/pages/components/agent/agent-save.ts +24 -1
- package/public/manager/src/settings/settings-icons.ts +3 -1
- package/public/manager/src/settings/settings-registry.ts +3 -3
- package/public/manager/src/settings-controls.css +0 -1
- package/public/manager/src/settings-standalone.tsx +8 -8
- package/public/manager/src/types.ts +0 -1
- package/scripts/check-private-boundary.mjs +101 -0
- package/scripts/grounding-eval.mjs +223 -0
- package/public/dist/assets/Agent-B8ZEWJ6B.js +0 -1
- package/public/dist/assets/CodeCanvas-Bj3lTSu6.js +0 -2
- package/public/dist/assets/DashboardMeta-CmZavI4H.js +0 -1
- package/public/dist/assets/Display-DFkjKcMk.js +0 -1
- package/public/dist/assets/Permissions-CJftCO6p.js +0 -1
- package/public/dist/assets/app-DVbrIl8f.css +0 -1
- package/public/dist/assets/bgtask-badge-CuAc8bAl.js +0 -1
- package/public/dist/assets/iframe-renderer-By2WO5bd.js +0 -1
- package/public/dist/assets/manager-CxLXWCGi.css +0 -1
- package/public/dist/assets/manager-DA3dF3eN.js +0 -5
- package/public/dist/assets/manager-shortcuts-CzGkE0ZG.js +0 -1
- package/public/dist/assets/memory-thjr2apY.js +0 -1
- package/public/dist/assets/message-history-CfU7_P5t.js +0 -1
- package/public/dist/assets/settings-DXA5L4DR.js +0 -1
- package/public/dist/assets/settings-Dy_IaNVH.js +0 -1
- package/public/dist/assets/settings-core-D7sAQqhC.js +0 -1
- package/public/dist/assets/skills-BcIievZp.js +0 -1
- package/public/dist/assets/slash-commands-B-5Shayl.js +0 -1
- package/public/dist/assets/ui-CJLdMfRx.js +0 -1
|
@@ -22,6 +22,107 @@ function rejectPaths(paths, label) {
|
|
|
22
22
|
|
|
23
23
|
export function checkIndex(cwd) {
|
|
24
24
|
rejectPaths(git(cwd, ['ls-files', '-z']).split('\0').filter(Boolean), 'index');
|
|
25
|
+
rejectWorkingTree(cwd);
|
|
26
|
+
reportSubmodules(cwd, { enforce: submoduleEnforcement() });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* An ignored private directory is still a private directory.
|
|
31
|
+
*
|
|
32
|
+
* `ls-files` sees the index, so a `devlog/` that `.gitignore` covers reports
|
|
33
|
+
* OK here while sitting in the checkout — which is exactly how one survived in
|
|
34
|
+
* a working tree until a human noticed. The rule is about where records live,
|
|
35
|
+
* not about whether Git happens to be tracking them: an ignored path is one
|
|
36
|
+
* `git add -f` or one archive away from shipping, and it is already visible to
|
|
37
|
+
* every tool and agent working in the directory.
|
|
38
|
+
*
|
|
39
|
+
* `--directory` reports the containing directory rather than each file inside
|
|
40
|
+
* it, so a large private tree produces one actionable line.
|
|
41
|
+
*/
|
|
42
|
+
function rejectWorkingTree(cwd) {
|
|
43
|
+
const untracked = git(cwd, ['ls-files', '-z', '--others', '--directory', '--no-empty-directory'])
|
|
44
|
+
.split('\0').filter(Boolean)
|
|
45
|
+
.map(entry => entry.replace(/\/$/, ''));
|
|
46
|
+
rejectPaths(untracked, 'working tree');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Submodule contents are enforced.
|
|
51
|
+
*
|
|
52
|
+
* They were warn-only for one reason: the `skills_ref` tip carried 29 private
|
|
53
|
+
* records that predated this check, and failing on them would have broken the
|
|
54
|
+
* build without deleting anything. Those records now live in cli-jaw-internal
|
|
55
|
+
* and are gone from the submodule, so the reason has expired and the default
|
|
56
|
+
* is a failure.
|
|
57
|
+
*
|
|
58
|
+
* Set `JAW_PRIVATE_BOUNDARY_SUBMODULES=warn` to go back to reporting, which
|
|
59
|
+
* exists for the same situation recurring in another submodule — a finding
|
|
60
|
+
* that has to be fixed elsewhere before this repository can demand it. It is
|
|
61
|
+
* a bridge, not a setting to leave on.
|
|
62
|
+
*/
|
|
63
|
+
function submoduleEnforcement() {
|
|
64
|
+
return String(process.env['JAW_PRIVATE_BOUNDARY_SUBMODULES'] || '').toLowerCase() !== 'warn';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function reportSubmodules(cwd, { enforce = false } = {}) {
|
|
68
|
+
const findings = [];
|
|
69
|
+
for (const { path, cwd: subCwd } of submodules(cwd)) {
|
|
70
|
+
if (!subCwd) {
|
|
71
|
+
findings.push({ path, absent: true, files: [] });
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
// Same reasoning as rejectWorkingTree: a submodule's own .gitignore can
|
|
75
|
+
// hide a private tree from its index while it sits in the checkout and
|
|
76
|
+
// ships with any archive of that submodule.
|
|
77
|
+
const tracked = git(subCwd, ['ls-files', '-z']).split('\0').filter(Boolean);
|
|
78
|
+
const untracked = git(subCwd, ['ls-files', '-z', '--others', '--directory', '--no-empty-directory'])
|
|
79
|
+
.split('\0').filter(Boolean).map(entry => entry.replace(/\/$/, ''));
|
|
80
|
+
const files = [...tracked, ...untracked].map(f => path + '/' + f).filter(isPrivatePath);
|
|
81
|
+
if (files.length) findings.push({ path, absent: false, files });
|
|
82
|
+
}
|
|
83
|
+
for (const finding of findings) {
|
|
84
|
+
if (finding.absent) {
|
|
85
|
+
console.warn('[private-boundary] submodule ' + finding.path + ' is not checked out; its contents were NOT scanned');
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const label = 'submodule ' + finding.path + ': ' + finding.files.length + ' private path(s)';
|
|
89
|
+
if (enforce) throw new Error(label + ':\n' + finding.files.join('\n'));
|
|
90
|
+
console.warn('[private-boundary] WARN ' + label + ' — ' + finding.files.slice(0, 3).join(', ') +
|
|
91
|
+
(finding.files.length > 3 ? ', …' : ''));
|
|
92
|
+
}
|
|
93
|
+
return findings;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Submodules are gitlinks: `ls-files` and `ls-tree` stop at the pointer and
|
|
98
|
+
* never enumerate their contents, so a private path committed inside a
|
|
99
|
+
* submodule is invisible to a check that only walks the superproject. Publish
|
|
100
|
+
* the submodule and the record ships with it.
|
|
101
|
+
*
|
|
102
|
+
* Returns each submodule's path plus a working-tree cwd when one is checked
|
|
103
|
+
* out. An absent working tree is reported rather than skipped silently.
|
|
104
|
+
*/
|
|
105
|
+
function submodules(cwd) {
|
|
106
|
+
let raw = '';
|
|
107
|
+
try {
|
|
108
|
+
raw = git(cwd, ['config', '--file', '.gitmodules', '--get-regexp', String.raw`^submodule\..*\.path$`]);
|
|
109
|
+
} catch {
|
|
110
|
+
return []; // no .gitmodules, or no submodule entries in it
|
|
111
|
+
}
|
|
112
|
+
const out = [];
|
|
113
|
+
for (const line of raw.trim().split('\n').filter(Boolean)) {
|
|
114
|
+
const path = line.slice(line.indexOf(' ') + 1).trim();
|
|
115
|
+
if (!path || path.startsWith('/') || path.split('/').includes('..')) continue;
|
|
116
|
+
const subCwd = resolve(cwd, path);
|
|
117
|
+
let usable = false;
|
|
118
|
+
try {
|
|
119
|
+
usable = git(subCwd, ['rev-parse', '--is-inside-work-tree']).trim() === 'true';
|
|
120
|
+
} catch {
|
|
121
|
+
usable = false;
|
|
122
|
+
}
|
|
123
|
+
out.push({ path, cwd: usable ? subCwd : null });
|
|
124
|
+
}
|
|
125
|
+
return out;
|
|
25
126
|
}
|
|
26
127
|
|
|
27
128
|
export function checkRange(cwd, base, head, destination) {
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* scripts/grounding-eval.mjs — run the grounding cases and report the rates.
|
|
4
|
+
*
|
|
5
|
+
* EXECUTION HOME, stated rather than assumed.
|
|
6
|
+
*
|
|
7
|
+
* This is an OPERATOR-RUN tool, not a CI check. It needs a live Chrome and a
|
|
8
|
+
* codex spawn, and `test.yml` has no fixture that provides either. Adding one
|
|
9
|
+
* would mean a model round-trip per case inside CI, which is slow, costs
|
|
10
|
+
* money, and is non-deterministic in a place that must be neither.
|
|
11
|
+
*
|
|
12
|
+
* So the contract is: an operator runs it, and its output is recorded
|
|
13
|
+
* evidence. That is a weaker guarantee than a gate, and saying so is the
|
|
14
|
+
* point — the alternative was a harness that quietly ran nowhere.
|
|
15
|
+
*
|
|
16
|
+
* cli-jaw serve # in another terminal
|
|
17
|
+
* node scripts/grounding-eval.mjs # add --json to capture the report
|
|
18
|
+
*
|
|
19
|
+
* Exit status reflects the run, not a threshold: 0 when every case was
|
|
20
|
+
* scored, 1 when any case errored. There is deliberately no pass/fail bar,
|
|
21
|
+
* because a number invented before the first measurement is not a standard.
|
|
22
|
+
*/
|
|
23
|
+
import fs from 'node:fs';
|
|
24
|
+
import path from 'node:path';
|
|
25
|
+
import { fileURLToPath } from 'node:url';
|
|
26
|
+
|
|
27
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
28
|
+
const root = path.resolve(here, '..');
|
|
29
|
+
const fixtureDir = path.join(root, 'tests/fixtures/grounding');
|
|
30
|
+
|
|
31
|
+
function parseArgs(argv) {
|
|
32
|
+
const opts = { port: null, json: false, only: null, base: 'http://127.0.0.1:3457' };
|
|
33
|
+
for (let i = 0; i < argv.length; i++) {
|
|
34
|
+
const a = argv[i];
|
|
35
|
+
if (a === '--json') opts.json = true;
|
|
36
|
+
else if (a === '--port') opts.port = Number(argv[++i]);
|
|
37
|
+
else if (a === '--only') opts.only = String(argv[++i]);
|
|
38
|
+
else if (a === '--base') opts.base = String(argv[++i]);
|
|
39
|
+
else if (a === '--help' || a === '-h') opts.help = true;
|
|
40
|
+
}
|
|
41
|
+
return opts;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const usage = `grounding-eval — measure grounding on fixed local fixtures
|
|
45
|
+
|
|
46
|
+
node scripts/grounding-eval.mjs [--port 9222] [--base http://127.0.0.1:3457]
|
|
47
|
+
[--only <case-id>] [--json]
|
|
48
|
+
|
|
49
|
+
Requires a running cli-jaw server and a browser session. This is an
|
|
50
|
+
operator-run tool; its output is recorded evidence, not a gate.`;
|
|
51
|
+
|
|
52
|
+
async function api(base, method, route, body, port) {
|
|
53
|
+
// The route resolves the CDP port from the query string, so an operator
|
|
54
|
+
// targeting a specific Chrome needs it forwarded. It used to be parsed and
|
|
55
|
+
// then ignored, which silently ran against whatever port was active.
|
|
56
|
+
const url = base + route + (port ? `?port=${port}` : '');
|
|
57
|
+
const res = await fetch(url, {
|
|
58
|
+
method,
|
|
59
|
+
headers: { 'content-type': 'application/json' },
|
|
60
|
+
...(body ? { body: JSON.stringify(body) } : {}),
|
|
61
|
+
});
|
|
62
|
+
const text = await res.text();
|
|
63
|
+
try { return { status: res.status, body: JSON.parse(text) }; }
|
|
64
|
+
catch { return { status: res.status, body: { raw: text } }; }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Record what the page actually received, so a click can be scored against
|
|
69
|
+
* reality rather than against the response's own claim.
|
|
70
|
+
*
|
|
71
|
+
* The listener walks UP from the event target to the nearest element with an
|
|
72
|
+
* id. A click on a button's inner span reports the span otherwise, and the
|
|
73
|
+
* harness would score a correct click as a misclick - measuring its own
|
|
74
|
+
* instrumentation rather than the pipeline.
|
|
75
|
+
*
|
|
76
|
+
* Reinstalled per case, since navigation discards it.
|
|
77
|
+
*/
|
|
78
|
+
const INSTALL_WITNESS = `(() => {
|
|
79
|
+
window.__jawClickedId = null;
|
|
80
|
+
document.addEventListener('click', (e) => {
|
|
81
|
+
let node = e.target;
|
|
82
|
+
for (let i = 0; node && i < 24; i++) {
|
|
83
|
+
if (node.id) { window.__jawClickedId = node.id; return; }
|
|
84
|
+
node = node.parentElement;
|
|
85
|
+
}
|
|
86
|
+
window.__jawClickedId = null;
|
|
87
|
+
}, true);
|
|
88
|
+
return true;
|
|
89
|
+
})()`;
|
|
90
|
+
|
|
91
|
+
const CLICK_WITNESS = 'window.__jawClickedId';
|
|
92
|
+
|
|
93
|
+
async function main() {
|
|
94
|
+
const opts = parseArgs(process.argv.slice(2));
|
|
95
|
+
if (opts.help) { console.log(usage); return 0; }
|
|
96
|
+
|
|
97
|
+
const { scoreRun, classify, classifyFailure, formatReport } = await import('../src/browser/grounding-eval.ts');
|
|
98
|
+
const spec = JSON.parse(fs.readFileSync(path.join(fixtureDir, 'cases.json'), 'utf8'));
|
|
99
|
+
const fixtureUrl = 'file://' + path.join(fixtureDir, spec.fixture);
|
|
100
|
+
const cases = opts.only ? spec.cases.filter(c => c.id === opts.only) : spec.cases;
|
|
101
|
+
|
|
102
|
+
const results = [];
|
|
103
|
+
for (const c of cases) {
|
|
104
|
+
const started = Date.now();
|
|
105
|
+
try {
|
|
106
|
+
const nav = await api(opts.base, 'POST', '/api/browser/navigate', { url: fixtureUrl }, opts.port);
|
|
107
|
+
// A failed navigation would score the whole case against whatever
|
|
108
|
+
// page happened to be loaded, which is worse than not scoring it.
|
|
109
|
+
if (nav.status >= 400) throw new Error(`navigate failed (${nav.status}): ${nav.body?.error ?? ''}`);
|
|
110
|
+
|
|
111
|
+
// Record what actually receives the click, since "success" alone
|
|
112
|
+
// cannot distinguish a correct click from a wrong one.
|
|
113
|
+
const install = await api(opts.base, 'POST', '/api/browser/evaluate', { expression: INSTALL_WITNESS }, opts.port);
|
|
114
|
+
if (install.status >= 400) throw new Error(`witness install failed (${install.status})`);
|
|
115
|
+
|
|
116
|
+
const res = await api(opts.base, 'POST', '/api/browser/vision-click', { target: c.target }, opts.port);
|
|
117
|
+
const witness = await api(opts.base, 'POST', '/api/browser/evaluate', { expression: CLICK_WITNESS }, opts.port);
|
|
118
|
+
const clicked = witness.body?.result ?? null;
|
|
119
|
+
const ms = Date.now() - started;
|
|
120
|
+
|
|
121
|
+
// A case that declares abstention correct is scored inverted: an
|
|
122
|
+
// abstention is the right answer, and a confident click is not.
|
|
123
|
+
//
|
|
124
|
+
// But a REFUSAL and a FAILURE are not the same thing. Scoring an
|
|
125
|
+
// HTTP error or a crashed call as "correctly declined" would turn
|
|
126
|
+
// harness breakage into a good result — the one direction an
|
|
127
|
+
// evaluation must never fail. Only a real refusal counts.
|
|
128
|
+
//
|
|
129
|
+
// That was the intent; the predicate below did not honour it. It
|
|
130
|
+
// asked whether a code or a reason was PRESENT, so a capture that
|
|
131
|
+
// could not be measured scored as the occlusion guard firing
|
|
132
|
+
// correctly — on the very cases that exist as evidence for those
|
|
133
|
+
// guards. It now asks what the code MEANS, through the same
|
|
134
|
+
// classifier the CLI and the scorer use.
|
|
135
|
+
//
|
|
136
|
+
// `classifyFailure`, not `classify`: this site needs a predicate.
|
|
137
|
+
// `classify` would return `abstained` for a correct refusal, which
|
|
138
|
+
// `scoreRun` files as `refusal.abstained` with `refusal.verified`
|
|
139
|
+
// at zero — reporting "0/3 correctly declined" for perfect work.
|
|
140
|
+
if (c.expectAbstention) {
|
|
141
|
+
if (res.status >= 400) {
|
|
142
|
+
results.push({ id: c.id, expected: 'abstain', outcome: { kind: 'errored', ms, error: `HTTP ${res.status}` } });
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const kind = res.body?.success === false ? classifyFailure(res.body?.code) : null;
|
|
146
|
+
const outcome = res.body?.success === true
|
|
147
|
+
? { kind: 'misclick', ms, got: clicked ?? 'unknown' }
|
|
148
|
+
: kind === 'abstention' || kind === 'not-found'
|
|
149
|
+
// Declining because the target was ambiguous, covered,
|
|
150
|
+
// stale, or simply absent are all correct answers on a
|
|
151
|
+
// case whose right answer is to decline.
|
|
152
|
+
? { kind: 'verified', ms }
|
|
153
|
+
: kind === 'grounding-failure'
|
|
154
|
+
? { kind: 'grounding-failure', ms, reason: res.body?.code }
|
|
155
|
+
: { kind: 'errored', ms, error: res.body?.code ?? res.body?.reason ?? 'declined without a reason' };
|
|
156
|
+
results.push({ id: c.id, expected: 'abstain', outcome });
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// A case with no DOM target expects a coordinate click. It cannot
|
|
161
|
+
// be scored by element identity — the witness reports whatever the
|
|
162
|
+
// coordinate landed on — so it is scored by landing INSIDE the
|
|
163
|
+
// named region instead.
|
|
164
|
+
if (c.expectRegion) {
|
|
165
|
+
// This branch had no status check at all, so a 500 from the
|
|
166
|
+
// route's catch — `{error}`, no `success` field — scored as a
|
|
167
|
+
// decline and exited 0. And its `?? 'declined'` fallback
|
|
168
|
+
// manufactured a reason where `classify` would have said none
|
|
169
|
+
// was given, making it strictly more permissive than the
|
|
170
|
+
// function it stood beside.
|
|
171
|
+
if (res.status >= 400) {
|
|
172
|
+
results.push({ id: c.id, expected: c.expectRegion, outcome: { kind: 'errored', ms, error: `HTTP ${res.status}` } });
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const outcome = res.body?.success !== true
|
|
176
|
+
? classify(res.body ?? {}, c.expectRegion, ms)
|
|
177
|
+
: clicked === c.expectRegion
|
|
178
|
+
? { kind: 'verified', ms }
|
|
179
|
+
: { kind: 'misclick', ms, got: clicked ?? 'unknown' };
|
|
180
|
+
results.push({ id: c.id, expected: c.expectRegion, outcome });
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
results.push({
|
|
185
|
+
id: c.id,
|
|
186
|
+
expected: c.expected ?? 'coordinate',
|
|
187
|
+
outcome: classify(res.body ?? {}, c.expected ?? 'coordinate', ms, clicked ?? undefined),
|
|
188
|
+
});
|
|
189
|
+
} catch (err) {
|
|
190
|
+
results.push({
|
|
191
|
+
id: c.id,
|
|
192
|
+
// A thrown refusal-expected case belongs in the refusal
|
|
193
|
+
// bucket. It files as an error either way today, but the
|
|
194
|
+
// bucket is read from `expected`, so getting it wrong here
|
|
195
|
+
// would put it in the wrong group the moment that changes.
|
|
196
|
+
expected: c.expectAbstention ? 'abstain' : (c.expectRegion ?? c.expected ?? 'coordinate'),
|
|
197
|
+
outcome: { kind: 'errored', ms: Date.now() - started, error: String(err?.message ?? err) },
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const report = scoreRun(results);
|
|
203
|
+
if (opts.json) {
|
|
204
|
+
console.log(JSON.stringify({ report, results }, null, 2));
|
|
205
|
+
} else {
|
|
206
|
+
for (const r of results) {
|
|
207
|
+
const o = r.outcome;
|
|
208
|
+
const detail = o.kind === 'misclick' ? ` (got ${o.got}, wanted ${r.expected})`
|
|
209
|
+
: o.kind === 'abstained' ? ` (${o.reason})`
|
|
210
|
+
: o.kind === 'errored' ? ` (${o.error})`
|
|
211
|
+
: '';
|
|
212
|
+
console.log(`${o.kind.padEnd(10)} ${r.id}${detail}`);
|
|
213
|
+
}
|
|
214
|
+
console.log('');
|
|
215
|
+
console.log(formatReport(report));
|
|
216
|
+
}
|
|
217
|
+
return report.errored > 0 ? 1 : 0;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
main().then(code => process.exit(code)).catch(err => {
|
|
221
|
+
console.error('grounding-eval failed:', err?.message ?? err);
|
|
222
|
+
process.exit(1);
|
|
223
|
+
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./cli-engine-Bw0QTAVX.js";import{n}from"./settings-types-B09BmpYe.js";import{t as r}from"./react-C_pPTFsM.js";import{t as i}from"./jsx-runtime-NZYk81nU.js";import{t as a}from"./settings-client-CmwRsVd1.js";import{t as o}from"./error-normalize-CL69Bl7z.js";import{a as s,i as c,n as l,r as u,t as d}from"./page-shell-BeGD0rRQ.js";import{i as f,s as p}from"./fields-mlGpofqQ.js";import{n as m,o as h,r as ee,s as g}from"./Permissions-CJftCO6p.js";import{a as _,c as v,d as y,i as te,l as b,n as ne,o as x,r as re,s as ie,t as ae,u as S}from"./agent-meta-BWHASq1a.js";import{t as C}from"./path-utils-B6vBr0DD.js";var w=e(r(),1),oe=1e3,se=8e3,ce=9e4;function T(e,t){if(!e||!t)return!1;let n=e[t]?.probeState;return n?n===`checking`||n===`failing`:!1}function le(e){let t=oe*2**Math.min(Number.isFinite(e)&&e>0?Math.floor(e):0,8);return Math.min(Math.max(t,oe),se)}function ue(e){let{snapshot:t,cli:n,attempts:r,now:i,deadline:a}=e;if(!T(t,n))return{kind:`stop`};if(i>=a||r>=24)return{kind:`exhausted`};let o=t?.[n]?.nextRetryAt,s=typeof o==`number`&&o>i?o:i+le(r);return{kind:`wait`,delayMs:Math.max(Math.min(s,a)-i,0)}}var E=i();function de({cli:e,cliOptions:n,provider:r=``,providerOptions:i=[],model:a,modelOptions:o,effort:s,effortOptions:l,workingDir:u,workingDirError:d,cliMeta:m,onCliChange:h,onProviderChange:ee,onModelChange:g,onEffortChange:y,onWorkingDirChange:te}){let b=v(n),x=t(e),re=b.filter(e=>ne.includes(e)).length;return(0,E.jsx)(c,{title:`Agent runtime`,hint:`Active CLI, model, effort, and workspace used by this instance.`,children:(0,E.jsxs)(`div`,{className:`settings-agent-runtime-grid`,children:[(0,E.jsx)(f,{id:`agent-cli`,label:`Active CLI`,value:e,missingValueLabel:x?`JWC (retired)`:void 0,error:x?`This runtime is retired. Select an available runtime to continue.`:null,options:b.map(e=>({value:e,label:_(e,m).label||e})),collapsedAfter:re,onChange:h}),i.length>0?(0,E.jsx)(f,{id:`agent-${e}-provider`,label:`Provider`,value:r,options:i.map(e=>({value:e,label:e})),onChange:e=>ee?.(e)}):null,(0,E.jsx)(f,{id:`agent-model`,label:`Active model`,value:a,disabled:x,options:o.length>0?o:[{value:``,label:`(default)`}],onChange:g}),(0,E.jsx)(f,{id:`agent-effort`,label:`Effort`,value:s,options:[{value:``,label:`(default)`},...l.map(e=>({value:e,label:e}))],disabled:x||l.length===0,onChange:y}),(0,E.jsx)(p,{id:`agent-workingDir`,label:`Working directory`,value:u,error:d,placeholder:`/path/to/project`,onChange:te})]})})}var D=[{value:`auto`,label:`Auto (YOLO)`},{value:`custom`,label:`Custom allowlist`}];function fe({value:e,configuredValue:t,onChange:n}){let r=h(e),i=r.mode===`custom`?`custom`:`auto`,a=r.mode===`custom`?r.tokens:[],o=r.mode===`custom`?`Editor draft: ${a.length} explicit token${a.length===1?``:`s`}`:null;return(0,E.jsxs)(c,{title:`Permissions`,hint:`Selecting a value changes the draft. Save applies it. Auto (YOLO) requests automatic approval or permission bypass. Behavior varies by runtime.`,children:[(0,E.jsx)(f,{id:`agent-permissions-mode`,label:`Change policy to`,value:i,options:D,onChange:e=>{n(e===`auto`?`auto`:a.length>0&&ee(a)?a:g(null))}}),o?(0,E.jsx)(`p`,{className:`settings-agent-note`,children:o}):null,(0,E.jsxs)(`p`,{className:`settings-agent-note`,id:`agent-configured-policy`,children:[`Configured policy: `,m(t)]})]})}function pe({activeCli:e,flushCli:n,flushModel:r,cliOptions:i,modelOptions:a,cliMeta:o,loading:s,error:l,onFlushCliChange:u,onFlushModelChange:d}){let p=n||e,m=p?_(p,o).label||p:`active`;return(0,E.jsx)(c,{title:`Flush Agent`,hint:`Separate summary agent used for context flush and compact work.`,children:(0,E.jsxs)(`details`,{className:`settings-agent-flush`,children:[(0,E.jsxs)(`summary`,{children:[(0,E.jsx)(`span`,{children:`Flush runtime`}),(0,E.jsxs)(`code`,{children:[m,r&&r!=="default"?` / ${r}`:``]})]}),s?(0,E.jsx)(`p`,{className:`settings-agent-note`,children:`Loading flush settings...`}):null,l?(0,E.jsx)(`p`,{className:`settings-field-error`,role:`alert`,children:l}):null,(0,E.jsxs)(`div`,{className:`settings-agent-runtime-grid`,children:[(0,E.jsx)(f,{id:`agent-flush-cli`,label:`Flush CLI`,value:n,missingValueLabel:t(n)?`JWC (retired)`:void 0,error:t(p)?`The saved flush runtime is retired. Choose an available runtime.`:null,options:[{value:``,label:`(active CLI)`},...y(i).map(e=>({value:e,label:_(e,o).label||e}))],onChange:u}),(0,E.jsx)(f,{id:`agent-flush-model`,label:`Flush model`,value:r,disabled:t(p),options:[{value:``,label:`(default)`},...a],onChange:d})]})]})})}function O(e){return e.source===`static`||e.id.startsWith(`static:`)}function me(){return`new:${Date.now().toString(36)}:${Math.random().toString(36).slice(2,8)}`}function he(e,t){let n=y(e)[0]||`claude`,r=t?.[n]?.models?.[0]||`default`;return{id:me(),name:`New Agent`,cli:n,model:r,role:``,status:`idle`,source:`db`}}function ge(e){return Array.isArray(e)?e.map(k).filter(Boolean):e.data.map(k).filter(Boolean)}function k(e){if(!e||typeof e!=`object`)return null;let t=e,n=typeof t.id==`string`?t.id:``,r=typeof t.name==`string`?t.name:``;if(!n||!r)return null;let i=t.source===`static`||n.startsWith(`static:`)?`static`:`db`,a={id:n,name:r,cli:typeof t.cli==`string`&&t.cli?t.cli:`claude`,model:typeof t.model==`string`&&t.model?t.model:`default`,role:typeof t.role==`string`?t.role:``,source:i};return typeof t.status==`string`&&(a.status=t.status),a}function A(e){return e.name.trim()?e.cli.trim()?e.model.trim()?null:`Model is required`:`CLI is required`:`Name is required`}function j(e){return e.some(e=>A(e)!==null)}function _e(e,t){return JSON.stringify(e.map(I))===JSON.stringify(t.map(I))}function M(e,t){let n=new Map(e.map(e=>[e.id,e])),r=new Set(t.map(e=>e.id)),i=[],a=[],o=[];for(let e of t){let t=n.get(e.id);if(!t||e.id.startsWith(`new:`)){i.push(e);continue}let r=P(t,e);Object.keys(r).length>0&&a.push({before:t,after:e,patch:r})}for(let t of e)!r.has(t.id)&&!O(t)&&o.push(t);return{added:i,updated:a,removed:o}}function N(e,t){let n=M(e,t);return{added:n.added.length,updated:n.updated.length,removed:n.removed.length}}async function ve(e,t,n){let r=M(t,n);for(let t of r.removed)await e.delete(`/api/employees/${encodeURIComponent(t.id)}`);for(let t of r.added)await e.post(`/api/employees`,F(t));for(let t of r.updated)await e.put(`/api/employees/${encodeURIComponent(t.after.id)}`,t.patch)}function P(e,t){if(O(t))return e.model===t.model?{}:{model:t.model};let n={};for(let r of[`name`,`cli`,`model`,`role`,`status`])(e[r]||``)!==(t[r]||``)&&(n[r]=t[r]||``);return n}function F(e){return{name:e.name.trim()||`New Agent`,cli:e.cli.trim()||`claude`,model:e.model.trim()||`default`,role:e.role.trim()}}function I(e){let t={id:e.id,name:e.name,cli:e.cli,model:e.model,role:e.role,source:e.source};return e.status!==void 0&&(t.status=e.status),t}function L({employee:e,index:n,cliOptions:r,cliMeta:i,onChange:a,onRemove:o}){let s=O(e),c=_(e.cli,i),l=ie(c.models,e.model),u=A(e),d=t(e.cli),m=y(Array.from(new Set([...r,e.cli,`claude`])).filter(Boolean));return(0,E.jsxs)(`fieldset`,{className:`settings-runtime-employee-row`,children:[(0,E.jsxs)(`legend`,{children:[e.name||`Employee ${n+1}`,s?(0,E.jsx)(`span`,{children:`static`}):null]}),(0,E.jsxs)(`div`,{className:`settings-runtime-employee-grid`,children:[(0,E.jsx)(p,{id:`runtime-employee-${e.id}-name`,label:`Name`,value:e.name,disabled:s,error:u===`Name is required`?u:null,onChange:e=>a({name:e})}),(0,E.jsx)(f,{id:`runtime-employee-${e.id}-cli`,label:`CLI`,value:e.cli,missingValueLabel:d?`JWC (retired)`:void 0,error:d?`This saved runtime cannot execute. Choose an available runtime.`:null,disabled:s,options:m.map(e=>({value:e,label:_(e,i).label||e})),onChange:e=>{a({cli:e,model:_(e,i).models[0]||`default`})}}),(0,E.jsx)(f,{id:`runtime-employee-${e.id}-model`,label:`Model`,value:e.model,disabled:d,options:l.length>0?l:[{value:`default`,label:`default`}],onChange:e=>a({model:e})}),(0,E.jsx)(p,{id:`runtime-employee-${e.id}-role`,label:`Role`,value:e.role,disabled:s,onChange:e=>a({role:e})})]}),(0,E.jsxs)(`div`,{className:`settings-runtime-employee-footer`,children:[(0,E.jsxs)(`span`,{children:[e.source,e.status?` / ${e.status}`:``]}),(0,E.jsx)(`button`,{type:`button`,className:`settings-action settings-action-discard`,disabled:s,onClick:o,"aria-label":`Remove employee ${e.name||n+1}`,children:`Remove`})]})]})}function ye({roster:e,original:t,cliOptions:n,cliMeta:r,loading:i,error:a,onRosterChange:o}){let s=N(t,e),l=j(e);function u(t,n){o(e.map((e,r)=>r===t?{...e,...n}:e))}function d(t){o(e.filter((e,n)=>n!==t))}return(0,E.jsxs)(c,{title:`Employees`,hint:`Runtime dispatch roster. Static employees keep their locked identity; database employees can be edited.`,children:[(0,E.jsxs)(`div`,{className:`settings-runtime-employee-summary`,children:[(0,E.jsxs)(`span`,{children:[`+`,s.added]}),(0,E.jsxs)(`span`,{children:[`~`,s.updated]}),(0,E.jsxs)(`span`,{children:[`-`,s.removed]}),l?(0,E.jsx)(`strong`,{children:`Fix invalid rows before saving.`}):null]}),i?(0,E.jsx)(`p`,{className:`settings-agent-note`,children:`Loading employees...`}):null,a?(0,E.jsx)(`p`,{className:`settings-field-error`,role:`alert`,children:a}):null,e.length===0?(0,E.jsx)(`p`,{className:`settings-empty`,children:`No runtime employees configured.`}):(0,E.jsx)(`div`,{className:`settings-runtime-employee-list`,children:e.map((e,t)=>(0,E.jsx)(L,{employee:e,index:t,cliOptions:n,cliMeta:r??null,onChange:e=>u(t,e),onRemove:()=>d(t)},e.id))}),(0,E.jsx)(`div`,{className:`settings-employee-footer-bar`,children:(0,E.jsx)(`button`,{type:`button`,className:`settings-action settings-action-discard`,onClick:()=>o([...e,he(n,r)]),children:`+ Add employee`})})]})}var R=new Set([`runtimeEmployees`,`flushCli`,`flushModel`]);function z(e){let t={},n=null,r=null;for(let[i,a]of Object.entries(e))i===`runtimeEmployees`?r=a:i===`flushCli`||i===`flushModel`?(n??={},n[i===`flushCli`?`cli`:`model`]=String(a??``)):R.has(i)||(t[i]=a);return{settingsBundle:t,flushPatch:n,runtimeEmployeesNext:r}}async function be(e){let{client:t,bundle:n,employeeDraft:r,employeeOriginal:i}=e;if(j(r))throw Error(`runtime employees: fix invalid rows before saving`);let{settingsBundle:a,flushPatch:o,runtimeEmployeesNext:s}=z(n),c=null;try{if(Object.keys(a).length>0){let e=await t.put(`/api/settings`,C(a));c=e&&typeof e==`object`&&`data`in e?e.data:e}}catch(e){throw Error(`settings save failed: ${e instanceof Error?e.message:String(e)}`)}try{o&&await t.put(`/api/memory-files/settings`,o)}catch(e){throw Error(`flush settings save failed: ${e instanceof Error?e.message:String(e)}`)}try{s&&await ve(t,i,s)}catch(e){throw Error(`runtime employees save failed: ${e instanceof Error?e.message:String(e)}`)}return c}function xe({status:e,exhausted:t=!1}){if(t)return(0,E.jsx)(`div`,{className:`settings-inline-notice`,role:`alert`,children:`상태 확인이 끝나지 않았습니다. 새로고침하거나 잠시 후 다시 확인하세요.`});if(!e)return null;let r=n(e);return r.kind===`checking`?(0,E.jsx)(`div`,{className:`settings-inline-notice`,role:`status`,"aria-live":`polite`,children:`상태 확인 중`}):r.kind===`unknown`?(0,E.jsx)(`div`,{className:`settings-inline-notice`,role:`alert`,children:r.message}):r.kind===`failing`?(0,E.jsxs)(`div`,{className:`settings-inline-notice`,role:`alert`,children:[`상태 확인 실패 (재시도 중)`,e.probeError?`: ${e.probeError}`:``]}):null}function B(e){if(!(e instanceof a)||e.status!==409)return null;try{return JSON.parse(e.detail).settings??null}catch{return null}}function Se({port:e,client:t,dirty:n,registerSave:r}){let{state:i,refresh:a,setData:c}=s(t,`/api/settings`),[f,p]=(0,w.useState)({cli:``,provider:``,model:``,effort:``,workingDir:``,permissions:`auto`}),[m,ee]=(0,w.useState)({}),[g,v]=(0,w.useState)({}),[ne,C]=(0,w.useState)(!0),[oe,se]=(0,w.useState)(null),[T,le]=(0,w.useState)([]),[D,O]=(0,w.useState)([]),[me,he]=(0,w.useState)(!0),[k,A]=(0,w.useState)(null),[M,N]=(0,w.useState)(null),[ve,P]=(0,w.useState)({}),[F,I]=(0,w.useState)(!1),[L,R]=(0,w.useState)(null),[z,Se]=(0,w.useState)(!1),[Ce,we]=(0,w.useState)(null),V=(0,w.useCallback)(async()=>{try{let e=await t.get(`/api/cli-registry`),n=e&&typeof e==`object`&&`data`in e?e.data:e;N(x(n))}catch{N(null)}},[t]),H=(0,w.useRef)(0),Te=(0,w.useRef)({}),[Ee,De]=(0,w.useState)(!1),U=(0,w.useCallback)(async e=>{try{let n=await t.get(`/api/cli-status`);if(e!==void 0&&e!==H.current)return;Te.current=n,P(n)}catch{if(e!==void 0&&e!==H.current)return;Te.current={},P({})}},[t]),W=(0,w.useCallback)(async()=>{C(!0),se(null);try{let e=await t.get(`/api/memory-files`),n={cli:e.cli||``,model:e.model||``};ee(n),v(n)}catch(e){se(e instanceof Error?e.message:String(e))}finally{C(!1)}},[t]),G=(0,w.useCallback)(async()=>{he(!0),A(null);try{let e=ge(await t.get(`/api/employees`));le(e),O(e)}catch(e){A(e instanceof Error?e.message:String(e))}finally{he(!1)}},[t]);(0,w.useEffect)(()=>{V(),U(),W(),G()},[V,U,G,W]),(0,w.useEffect)(()=>{if(!f.cli)return;let e=H.current+1;H.current=e,De(!1);let t=Date.now()+ce,n=0,r,i=()=>{if(e!==H.current)return;let a=ue({snapshot:Te.current,cli:f.cli,attempts:n,now:Date.now(),deadline:t});if(a.kind!==`stop`){if(a.kind===`exhausted`){De(!0);return}r=setTimeout(()=>{e===H.current&&(n+=1,U(e).then(()=>{e===H.current&&i()}))},a.delayMs)}};return i(),()=>{H.current=e+1,r!==void 0&&clearTimeout(r)}},[f.cli,U]),(0,w.useEffect)(()=>{if(i.kind!==`ready`)return;let e=Object.keys(i.data.perCli||{}),t=i.data.cli||e[0]||``,n=h(i.data.permissions),r=_(t,M);p({cli:t,provider:i.data.perCli?.[t]?.provider||r.defaultProvider||``,model:S(t,i.data.perCli,i.data.activeOverrides),effort:b(t,i.data.perCli,i.data.activeOverrides),workingDir:i.data.workingDir||``,permissions:n.mode===`custom`?n.tokens:`auto`})},[M,i]),(0,w.useEffect)(()=>()=>{for(let e of Array.from(n.pending.keys()))(e===`cli`||e===`workingDir`||e===`permissions`||e===`runtimeEmployees`||e===`flushCli`||e===`flushModel`||e.startsWith(`activeOverrides.`))&&n.remove(e)},[n]);let K=(0,w.useCallback)((e,t)=>n.set(e,t),[n]),Oe=(0,w.useCallback)(async()=>{let e=n.saveBundle();if(Object.keys(e).length===0)return;let r=await be({client:t,bundle:e,employeeDraft:D,employeeOriginal:T});n.clear(),r&&c(r),await a(),await V(),await W(),await G()},[t,n,D,T,V,G,W,a,c]);(0,w.useEffect)(()=>{if(r)return r(Oe),()=>r(null)},[r,Oe]);let q=i.kind===`ready`?i.data:{},J=q.perCli||{},Y=q.activeOverrides||{},ke=(0,w.useMemo)(()=>{let e=y(Object.keys(J));return e.length?e:y(Object.keys(M||ae))},[J,M]),X=_(f.cli,M),Z=f.provider||X.defaultProvider||X.providers?.[0]||``,Ae=f.cli===`pi`,Q=!Ae&&(X.providers?.length??0)>0,je=ie(Q&&X.modelsByProvider?.[Z]||X.models,f.model),Me=Q?te(X,f.model,X.effortsByProvider?.[Z]||X.efforts,Z):te(X,f.model),Ne=f.workingDir.trim()?null:`Required`,Pe=(0,w.useCallback)(async e=>{I(!0),R(null);try{let n=await t.post(`/api/settings/runtime-default-migration`,{action:e}),r;r=`settings`in n&&n.settings?n.settings:`data`in n&&n.data?n.data:n,c(r)}catch(e){let t=B(e);if(t){c(t);return}R(o(e))}finally{I(!1)}},[t,c]),Fe=(0,w.useCallback)(async e=>{Se(!0),we(null);try{let n=await t.post(`/api/settings/multi-session-default-migration`,{action:e}),r;r=`settings`in n&&n.settings?n.settings:`data`in n&&n.data?n.data:n,c(r)}catch(e){let t=B(e);if(t){c(t);return}we(o(e))}finally{Se(!1)}},[t,c]);if(i.kind===`loading`)return(0,E.jsx)(l,{});if(i.kind===`offline`)return(0,E.jsx)(u,{port:e});if(i.kind===`error`)return(0,E.jsx)(d,{message:i.message});function Ie(){for(let e of Array.from(n.pending.keys()))e.startsWith(`activeOverrides.`)&&n.remove(e)}function $(e){p(e)}return(0,E.jsxs)(`form`,{className:`settings-page-form`,onSubmit:e=>{e.preventDefault(),Oe()},children:[q.runtimeDefaultMigration?.state===`pending`?(0,E.jsxs)(`div`,{className:`settings-inline-notice`,role:`status`,children:[(0,E.jsx)(`strong`,{children:`기본 런타임 변경 안내`}),(0,E.jsx)(`p`,{children:`기존 선택은 유지됩니다. Codex App으로 전환하거나 현재 런타임을 계속 사용할 수 있습니다.`}),(0,E.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,E.jsx)(`button`,{type:`button`,className:`settings-action settings-action-save`,disabled:F,onClick:()=>void Pe(`accept`),children:`Codex App 사용`}),(0,E.jsx)(`button`,{type:`button`,className:`settings-action settings-action-secondary`,disabled:F,onClick:()=>void Pe(`keep`),children:`현재 런타임 유지`})]}),L?(0,E.jsx)(`span`,{className:`settings-field-error`,role:`alert`,children:L}):null]}):null,q.multiSessionDefaultMigration?.state===`pending`?(0,E.jsxs)(`div`,{className:`settings-inline-notice`,role:`status`,children:[(0,E.jsx)(`strong`,{children:`다중 세션 안내`}),(0,E.jsx)(`p`,{children:`대화 세션을 여러 개 열 수 있습니다. 켜면 동시 실행도 2로 올라가서, 두 번째 세션이 첫 번째가 끝나기를 기다리지 않습니다. 지금 설정은 그대로 유지됩니다.`}),(0,E.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,E.jsx)(`button`,{type:`button`,className:`settings-action settings-action-save`,disabled:z,onClick:()=>void Fe(`accept`),children:`다중 세션 켜기`}),(0,E.jsx)(`button`,{type:`button`,className:`settings-action settings-action-secondary`,disabled:z,onClick:()=>void Fe(`keep`),children:`지금 설정 유지`})]}),Ce?(0,E.jsx)(`span`,{className:`settings-field-error`,role:`alert`,children:Ce}):null]}):null,(0,E.jsxs)(`label`,{className:`settings-field settings-field-select`,htmlFor:`midrun-policy-select`,children:[(0,E.jsx)(`span`,{className:`settings-field-label`,children:`실행 중 메시지 처리 (mid-run policy)`}),(0,E.jsxs)(`select`,{id:`midrun-policy-select`,value:String(q.multiSession?.midRunPolicy||`steer`),onChange:e=>{let t=e.target.value;K(`multiSession.midRunPolicy`,{value:t,original:String(q.multiSession?.midRunPolicy||`steer`),valid:!0})},children:[(0,E.jsx)(`option`,{value:`steer`,children:`steer (기본) — 실행 중 지시 변경`}),(0,E.jsx)(`option`,{value:`followup`,children:`followup — 끝나면 순서대로 실행`}),(0,E.jsx)(`option`,{value:`collect`,children:`collect — 모아서 한 번에 실행`}),(0,E.jsx)(`option`,{value:`interrupt`,children:`interrupt — 현재 실행을 중단하고 즉시 실행`})]}),(0,E.jsx)(`span`,{className:`settings-field-hint`,children:`다중 세션이 켜져 있을 때 적용됩니다. codex-app은 같은 턴에 입력을 전달합니다. Cursor·Grok의 native 모드는 현재 요청의 취소와 정리가 끝난 뒤 같은 세션에 다시 요청합니다(cancel-reprompt). 그 외 런타임은 중단 후 새 실행으로 이어갑니다(kill-steer). 보존되는 맥락은 런타임에 따라 다릅니다. 끝난 뒤 실행하려면 followup을 선택하세요.`})]}),(0,E.jsx)(xe,{status:ve[f.cli],exhausted:Ee}),(0,E.jsx)(de,{cli:f.cli,cliOptions:ke,provider:Z,providerOptions:Ae?[]:X.providers||[],model:f.model,modelOptions:je,effort:f.effort,effortOptions:Me,workingDir:f.workingDir,workingDirError:Ne,cliMeta:M,onCliChange:e=>{let t=_(e,M),n={...f,cli:e,provider:J[e]?.provider||t.defaultProvider||``,model:S(e,J,Y),effort:b(e,J,Y)};Ie(),$(n),K(`cli`,{value:e,original:q.cli||``,valid:!0})},onProviderChange:e=>{let t=X.modelsByProvider?.[e]||[],n=X.effortsByProvider?.[e]||[],r=t.includes(f.model)?f.model:t[0]||``,i=re(X,r,f.effort,n,e);$({...f,provider:e,model:r,effort:i}),K(`perCli.${f.cli}.provider`,{value:e,original:J[f.cli]?.provider||X.defaultProvider||``,valid:!0}),K(`activeOverrides.${f.cli}.model`,{value:r,original:S(f.cli,J,Y),valid:r.trim().length>0}),K(`activeOverrides.${f.cli}.effort`,{value:i,original:b(f.cli,J,Y),valid:!0})},onModelChange:e=>{let t=re(X,e,f.effort,Q?X.effortsByProvider?.[Z]||X.efforts:void 0,Q?Z:void 0);$({...f,model:e,effort:t}),K(`activeOverrides.${f.cli}.model`,{value:e,original:S(f.cli,J,Y),valid:e.trim().length>0}),t!==f.effort&&K(`activeOverrides.${f.cli}.effort`,{value:t,original:b(f.cli,J,Y),valid:!0})},onEffortChange:e=>{$({...f,effort:e}),K(`activeOverrides.${f.cli}.effort`,{value:e,original:b(f.cli,J,Y),valid:!0})},onWorkingDirChange:e=>{$({...f,workingDir:e}),K(`workingDir`,{value:e,original:q.workingDir||``,valid:e.trim().length>0})}}),(0,E.jsx)(fe,{value:f.permissions,configuredValue:q.permissions,onChange:e=>{$({...f,permissions:e}),K(`permissions`,{value:e,original:q.permissions??`auto`,valid:e===`auto`||e.length>0})}}),(0,E.jsx)(pe,{activeCli:f.cli,flushCli:g.cli||``,flushModel:g.model||``,cliOptions:ke,cliMeta:M,modelOptions:ie(_(g.cli||f.cli,M).models,g.model||``),loading:ne,error:oe,onFlushCliChange:e=>{let t=e&&_(e,M).models[0]||``;v({cli:e,model:t}),K(`flushCli`,{value:e,original:m.cli||``,valid:!0}),K(`flushModel`,{value:t,original:m.model||``,valid:!0})},onFlushModelChange:e=>{v({...g,model:e}),K(`flushModel`,{value:e,original:m.model||``,valid:!0})}}),(0,E.jsx)(ye,{roster:D,original:T,cliOptions:ke,cliMeta:M,loading:me,error:k,onRosterChange:e=>{if(O(e),_e(e,T)){n.remove(`runtimeEmployees`);return}n.set(`runtimeEmployees`,{value:e,original:T,valid:!j(e)})}})]})}export{xe as CliProbeNotice,B as conflictSettingsFromError,Se as default,z as splitAgentSaveBundle};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor-render-DSSkXCir.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./preload-helper-CfbQpVni.js";import{a as n,i as r,n as i,r as a,t as o}from"./esm-Q6VOkDbn.js";import{t as s}from"./react-C_pPTFsM.js";import{t as c}from"./react-dom-DyUOYpVL.js";import{t as l}from"./jsx-runtime-NZYk81nU.js";var u=e(s(),1),d=c(),f={session_busy:`This session is busy. Wait for it to finish or stop the current turn.`,request_not_current:`This approval is no longer current. Refreshing its status.`,invalid_option:`This approval option is no longer available. Refreshing its status.`,revision_conflict:`Session settings changed elsewhere. Review the updated values and try again.`,invalid_sequence:`Conversation history needs to be refreshed.`,snapshot_limit:`This conversation exceeds the snapshot limit. Stop and recovery controls remain available.`,transcript_limit:`The conversation has reached its storage limit.`,event_too_large:`A conversation update exceeds the supported size.`,provider_unavailable:`This runtime is unavailable. Check its installation and authentication.`,unsupported_model:`This model is not available for the selected runtime.`,unsupported_effort:`This effort is not supported by the selected runtime.`,unsupported_policy:`This permission mode is not supported by the selected runtime.`,unsupported_capability:`This runtime does not support this action.`,session_not_found:`This session is no longer available. Its local draft is retained.`,unauthorized:`Authentication is required to access this instance.`},p=class extends Error{code;status;session;constructor(e,t,n){super(f[e]??`The request could not be completed. Refresh the session and try again.`),this.code=e,this.status=t,this.session=n,this.name=`CodeClientError`}};function m(e){return typeof window<`u`&&window.location.port===String(e)?window.location.origin:`http://127.0.0.1:${e}`}function h(e){let t=m(e);async function n(e,n,r,i){let a=await fetch(`${t}/api/code${n}`,{method:e,...i===void 0?{}:{signal:i},...r===void 0?{}:{headers:{"Content-Type":`application/json`},body:JSON.stringify(r)}}),o=await a.json();if(!a.ok||o.ok!==!0)throw new p(typeof o.error==`string`?o.error:`code_request_failed`,a.status,o.session);return o}let r=e=>`/sessions/${encodeURIComponent(e)}`,i=async(e,t,r)=>(await n(e,t,r)).session;return{listSessions(e={},t){let r=new URLSearchParams;for(let[t,n]of Object.entries(e))n!==void 0&&r.set(t,String(n));return n(`GET`,`/sessions?${r}`,void 0,t)},listModelOptions:e=>n(`GET`,`/models`,void 0,e),snapshot:(e,t)=>n(`GET`,r(e),void 0,t),events:(e,t,i)=>n(`GET`,`${r(e)}/events?afterSequence=${t}&limit=500`,void 0,i),history:(e,t,i)=>n(`GET`,`${r(e)}/items?beforeSequence=${t}&limit=200`,void 0,i),createSession:e=>i(`POST`,`/sessions`,e),patchSession:(e,t)=>i(`PATCH`,r(e),t),sendPrompt:(e,t)=>n(`POST`,`${r(e)}/prompt`,t),cancelPrompt:(e,t)=>i(`POST`,`${r(e)}/cancel`,t),attachSession:e=>i(`POST`,`${r(e)}/attach`,{}),async answerPermission(e,t){await n(`POST`,`/permissions/${encodeURIComponent(e)}`,t)},getGitInfo:(e,t)=>n(`GET`,`/git-info?cwd=${encodeURIComponent(e)}`,void 0,t),pickWorkspace:()=>n(`POST`,`/workspace/pick`)}}var g=512,_=2097152,v=2e3,y=16777216;function b(e){return{sessionId:e,session:null,items:[],permissions:[],cursor:0,hydrated:!1,hydrating:!1,synced:!1,needsSnapshot:!1,buffered:[],hasOlder:!1,beforeSequence:null,error:null}}function x(e){return!!e&&[`starting`,`streaming`,`stopping`].includes(e.status)}var S=e=>e.sort((e,t)=>(e.firstSequence??0)-(t.firstSequence??0)),C=e=>e.reduce((e,t)=>e+JSON.stringify(t).length,0);function w(e){let t=e.items,n=C(t);if(t.length<=v&&n<=y)return e;for(t=[...t];t.length>v||n>y;){let r=t.findIndex(t=>!e.session?.turnId||t.turnId!==e.session.turnId);if(r<0)return{...e,items:[],synced:!1,needsSnapshot:!0,error:`Conversation exceeds the display capacity.`};n-=JSON.stringify(t[r]).length,t.splice(r,1)}return{...e,items:t,hasOlder:!0,beforeSequence:t[0]?.firstSequence??null}}function ee(e,t){let{items:n,session:r,permissions:i}=e;if(t.event===`code_session`){if(!t.session||t.session.sessionId!==e.sessionId)return{...e,needsSnapshot:!0,synced:!1};r=t.session,i=i.filter(e=>e.epoch===r.epoch&&e.turnId===r.turnId)}else{let a=t.item?.itemId??t.update?.itemId,o=n.find(e=>e.itemId===a),s;if(t.event===`code_item`&&t.item)s={...t.item,firstSequence:o?.firstSequence??t.item.firstSequence??t.sequence};else if(t.event===`code_item_update`&&t.update&&o&&o.turnId===t.update.turnId){let n=t.update;if(n.appendToolOutput!==void 0&&!o.tool)return{...e,needsSnapshot:!0,synced:!1};s={...o,updatedAt:n.updatedAt,...n.appendText===void 0?{}:{text:(o.text??``)+n.appendText},...n.appendToolOutput===void 0?{}:{tool:{...o.tool,output:(o.tool.output??``)+n.appendToolOutput}},...n.status===void 0?{}:{status:n.status},...n.phase===void 0?{}:{phase:n.phase}}}else return{...e,needsSnapshot:!0,synced:!1};n=S([...n.filter(e=>e.itemId!==s.itemId),s]),s.permission&&(i=i.filter(e=>e.permissionId!==s.permission.permissionId),s.status===`pending`&&s.permission.epoch===r?.epoch&&s.permission.turnId===r?.turnId&&(i=[...i,s.permission]))}return w({...e,items:n,session:r,permissions:i,cursor:t.sequence})}function T(e){let t=e;if(!t.hydrated||t.hydrating||t.needsSnapshot)return t;let n=t.buffered.filter(e=>e.sequence>t.cursor);for(;n[0]?.sequence===t.cursor+1;){let e=n[0];if(t=ee(t,e),t.needsSnapshot)break;n.shift()}return{...t,buffered:n,synced:t.synced&&!n.length&&!t.needsSnapshot}}function te(e,t){if(t.sessionId!==e.sessionId||t.sequence<=e.cursor||e.buffered.some(e=>e.sequence===t.sequence))return e;let n=[...e.buffered,t].sort((e,t)=>e.sequence-t.sequence);return n.length>g||JSON.stringify(n).length>_?{...e,buffered:[],synced:!1,needsSnapshot:!0,error:`Live updates exceeded the buffer. Refreshing history.`}:T({...e,buffered:n})}function E(e,t){switch(t.type){case`stale`:return{...e,synced:!1};case`error`:return{...e,hydrating:!1,synced:!1,error:t.error};case`snapshot-start`:return{...e,hydrating:!0,synced:!1,error:null};case`event`:return te(e,t.event);case`snapshot`:{let n=t.snapshot;if(n.session.sessionId!==e.sessionId||n.sequence<e.cursor)return{...e,hydrating:!1,synced:!1,needsSnapshot:!0};let r=S([...n.items]);return T(w({...e,session:n.session,items:r,permissions:n.pendingPermissions,cursor:n.sequence,hydrated:!0,hydrating:!1,synced:!0,needsSnapshot:!1,hasOlder:n.truncated,beforeSequence:r[0]?.firstSequence??null,error:null}))}case`page`:{let n=e;for(let e of t.page.events)n=te(n,e);let r=n.cursor>=t.page.throughSequence&&!n.buffered.length&&!n.needsSnapshot;return{...n,synced:r,error:r?null:n.error}}case`history`:{let n=new Set(e.items.map(e=>e.itemId)),r=S([...e.items,...t.page.items.filter(e=>!n.has(e.itemId))]);return r.length>v||C(r)>y?{...e,error:`Older history exceeds the display capacity. Reload to return to recent items.`}:{...e,items:r,hasOlder:t.page.hasMore,beforeSequence:t.page.beforeSequence}}}}var D=`cli-jaw:code-drafts:v1`,O=`cli-jaw:code-draft-warnings:v1`,k=1,A=4,ne=32,re=262144,j=1048576,ie=2097152,M=`Draft recovery is unavailable in this tab. Your current text remains in memory.`,ae=`Draft recovery is incomplete: some recent text or request state was not saved for reload. Check your draft before sending.`,N=`Draft recovery is incomplete: some text was not saved for reload because this tab reached its recovery limit.`,P=e=>!!e&&typeof e==`object`&&!Array.isArray(e),F=(e,t)=>typeof e==`string`&&e.length<=t,I=e=>typeof e==`number`&&Number.isSafeInteger(e)&&e>=0;function L(e){if(!P(e)||!F(e.input,re)||!I(e.edit)||!I(e.selectionEdit)||typeof e.creating!=`boolean`)return null;let t=e.selection;if(!P(t)||![`codex-app`,`claude`,`cursor`,`grok`].includes(String(t.provider))||!F(t.cwd,4096)||!F(t.model,1024)||!(t.effort===null||F(t.effort,80))||![`ask`,`auto`,`read-only`].includes(String(t.permissionMode)))return null;let n=e.retry,r=e.stop;return n!==null&&(!P(n)||!F(n.text,re)||!F(n.key,240)||!n.key||!I(n.edit)||n.edit>e.edit)||r!==null&&(!P(r)||!F(r.turnId,240)||!r.turnId||!I(r.epoch))?null:{input:e.input,edit:e.edit,selectionEdit:e.selectionEdit,creating:e.creating,selection:{provider:t.provider,cwd:t.cwd,model:t.model,effort:t.effort,permissionMode:t.permissionMode},retry:n===null?null:{text:n.text,key:n.key,edit:n.edit},stop:r===null?null:{turnId:r.turnId,epoch:r.epoch}}}function oe(e){if(e===null)return{version:k,endpoints:[]};if(e.length>ie)return null;let t;try{t=JSON.parse(e)}catch{return null}if(!P(t)||t.version!==k||!Array.isArray(t.endpoints)||t.endpoints.length>A)return null;let n=[];for(let e of t.endpoints){if(!P(e)||!F(e.endpoint,2048)||!(e.selectedId===null||F(e.selectedId,240))||!Array.isArray(e.sessions)||e.sessions.length>ne)return null;let t=L(e.fresh);if(!t||t.retry||t.stop)return null;let r=[];for(let t of e.sessions){if(!P(t)||!F(t.id,240)||!t.id)return null;let e=L(t.draft);if(!e||e.creating||r.some(e=>e.id===t.id))return null;r.push({id:t.id,draft:e})}if(e.selectedId!==null&&!r.some(t=>t.id===e.selectedId)||n.some(t=>t.endpoint===e.endpoint)||JSON.stringify(e).length>j)return null;n.push({endpoint:e.endpoint,selectedId:e.selectedId,fresh:t,sessions:r})}return{version:k,endpoints:n}}function se(e){let t=e.getItem(O);if(!t||t.length>16384)return[];try{let e=JSON.parse(t);return Array.isArray(e)&&e.length<=A&&e.every(e=>F(e,2048))?e:[]}catch{return[]}}function R(e,t,n){try{let r=se(e).filter(e=>e!==t);n&&r.push(t),r.length?e.setItem(O,JSON.stringify(r.slice(-4))):e.removeItem(O)}catch{}}function ce(){if(typeof window>`u`)return{storage:null,warning:null};try{return{storage:window.sessionStorage,warning:null}}catch{return{storage:null,warning:M}}}function le(e,t){try{let n=oe(e.getItem(D));if(!n)return{data:null,warning:`Saved Code drafts could not be read. No saved requests were sent.`};let r=n.endpoints.find(e=>e.endpoint===t)??null,i=se(e);return{data:r,warning:i.includes(t)||!r&&i.length>0?ae:null}}catch{return{data:null,warning:M}}}function z(e){let{provider:t,cwd:n,model:r,effort:i,permissionMode:a}=e.selection;return L({input:e.input,edit:e.edit,selection:{provider:t,cwd:n,model:r,effort:i,permissionMode:a},selectionEdit:e.selectionEdit,creating:e.createUnknown||e.operation.kind===`creating`,retry:e.retry?{text:e.retry.text,key:e.retry.key,edit:e.retry.edit}:null,stop:e.stopTarget?{turnId:e.stopTarget.turnId,epoch:e.stopTarget.epoch}:null})}function ue(e,t,n){try{let r=z(n.fresh);if(!r)return R(e,t,!0),N;let i={endpoint:t,selectedId:null,fresh:r,sessions:[]},a=!1,o=[...n.sessions].sort(([e],[t])=>Number(t===n.selectedId)-Number(e===n.selectedId));for(let[r,s]of o){if(r!==n.selectedId&&!s.input&&!s.retry&&!s.stopTarget)continue;let o=z(s);if(!o)return R(e,t,!0),N;if(i.sessions.length>=ne){a=!0;continue}let c={...i,selectedId:r===n.selectedId?r:i.selectedId,sessions:[...i.sessions,{id:r,draft:o}]};if(JSON.stringify(c).length>j){a=!0;continue}i.sessions=c.sessions,i.selectedId=c.selectedId}if(n.selectedId!==null&&i.selectedId===null||JSON.stringify(i).length>j)return R(e,t,!0),N;let s=e.getItem(D),c=[...(oe(s)??{version:k,endpoints:[]}).endpoints.filter(e=>e.endpoint!==t),i],l=JSON.stringify({version:k,endpoints:c});for(;c.length>A||l.length>ie;){let t=c.shift();t&&R(e,t.endpoint,!0),l=JSON.stringify({version:k,endpoints:c})}return l!==s&&e.setItem(D,l),R(e,t,a||n.recoveryWarning!==null),a?N:null}catch{return R(e,t,!0),M}}var de=new Map,B=new WeakMap;function V(e){return{input:``,edit:0,selection:{...e},selectionEdit:0,operation:{kind:`idle`,error:null},retry:null,createUnknown:!1,requiredSequence:0,stopTarget:null,permissionOperations:{}}}function H(e){let t=V(e.selection);return t.input=e.input,t.edit=e.edit,t.selectionEdit=e.selectionEdit,t.createUnknown=e.creating,t.retry=e.retry,e.creating&&(t.operation={kind:`creating`,error:`Creation was interrupted by reload. The original session may exist; no request has been retried.`}),e.retry&&(t.operation={kind:`unknown-send`,error:`The original message has not been reconciled after reload. It will not be sent automatically.`}),e.stop&&(t.stopTarget={...e.stop,outcome:`unknown`},t.operation={kind:`stopping`,error:`Checking the captured Stop after reload. No cancellation has been resent.`}),t}function fe(e,t){let n=ce(),r=n.storage?B.get(n.storage):de;r||(r=new Map,B.set(n.storage,r));let i=r.get(e);if(!i){let a=n.storage?le(n.storage,e):{data:null,warning:n.warning};i={endpoint:e,storage:n.storage,storageWarning:n.warning,recoveryWarning:a.warning,selectedId:a.data?.selectedId??null,navigation:0,fresh:a.data?H(a.data.fresh):V({provider:`codex-app`,cwd:t,model:``,effort:null,permissionMode:`ask`}),sessions:new Map(a.data?.sessions.map(e=>[e.id,H(e.draft)])??[]),listeners:new Set},r.set(e,i)}return i}function U(e){e.storage&&(e.storageWarning=ue(e.storage,e.endpoint,e))}function W(e){return{provider:e.provider,cwd:e.cwd,model:e.model,effort:e.effort,permissionMode:e.permissionMode}}function G(e,t,n=!1){let r=e.providers.find(e=>e.id===t.provider);if(!r)return t;let i=r.capabilities;return{...t,model:!n&&r.models.includes(t.model)?t.model:r.defaultModel,effort:!n&&t.effort!==null&&i.efforts.includes(t.effort)?t.effort:null,permissionMode:i.permissions?!n&&i.permissionModes.includes(t.permissionMode)?t.permissionMode:i.permissions&&i.permissionModes.includes(`ask`)?`ask`:i.permissionModes.includes(`auto`)?`auto`:`read-only`:`auto`}}function K(e,t){e.retry?.key===t&&(e.edit===e.retry.edit&&(e.input=``,e.edit++),e.retry=null,(e.operation.kind===`sending`||e.operation.kind===`unknown-send`)&&(e.operation={kind:`idle`,error:null}))}var pe=6,q=1e3,me=100,he=32,ge=150,J=e=>e instanceof p?e.message:`Connection lost. Refresh to check the current state.`,Y=e=>e instanceof p&&e.status>=400&&e.status<500,_e=(e,t)=>!t||e.epoch>t.epoch||e.epoch===t.epoch&&(e.sequence>t.sequence||e.sequence===t.sequence&&e.revision>=t.revision),ve=class{client;book;details=new Map;summaries=new Map;rows=[];catalog=null;catalogError=null;transport=`disconnected`;filter={scope:`all`,archived:!1};workingDir;gitInfo=null;gitError=null;gitGeneration=0;pickerGeneration=0;indexGeneration=0;catalogGeneration=0;lifetime=0;active=!1;abort=new AbortController;syncing=new Map;detailReads=new Map;historyLoading=new Set;indexLoading=!1;moreSessions=!1;offset=0;indexError=null;timer;listeners=new Set;model;draftSyncQueued=!1;constructor(e){this.client=h(e.port),this.workingDir=e.workingDir,this.book=fe(m(e.port),e.workingDir),this.model=this.makeModel()}getModel=()=>this.model;subscribe=e=>(this.listeners.add(e),()=>this.listeners.delete(e));changed=()=>{this.model=this.makeModel();for(let e of this.listeners)e();let e=this.book.selectedId,t=e?this.details.get(e):void 0;this.active&&e&&!t?.error&&(!t||this.draft(e).requiredSequence>t.cursor)&&!this.draftSyncQueued&&(this.draftSyncQueued=!0,queueMicrotask(()=>{this.draftSyncQueued=!1,this.active&&this.book.selectedId===e&&!this.syncing.has(e)&&this.sync(e)}))};notify(){U(this.book),this.changed();for(let e of this.book.listeners)e!==this.changed&&e()}mount=()=>(this.active=!0,this.lifetime++,this.abort=new AbortController,this.book.listeners.add(this.changed),this.refresh(),()=>{U(this.book),this.active=!1,this.lifetime++,this.abort.abort(),this.syncing.clear();for(let e of this.detailReads.values())e.abort();this.detailReads.clear(),this.timer!==void 0&&clearTimeout(this.timer),this.timer=void 0,this.book.listeners.delete(this.changed),this.details.clear(),this.summaries.clear(),this.rows=[],this.gitGeneration++,this.pickerGeneration++});setWorkingDir(e){if(e===this.workingDir)return;this.workingDir=e;let t=this.book.fresh;!t.selectionEdit&&!t.input&&t.operation.kind===`idle`&&!t.createUnknown&&(t.selection={...t.selection,cwd:e}),this.filter.scope===`cwd`&&this.readIndex(),this.readGit(),this.notify()}draft(e=this.book.selectedId){if(e===null)return this.book.fresh;let t=this.book.sessions.get(e);if(!t){let n=this.info(e);t=V(n?W(n):this.book.fresh.selection),this.book.sessions.set(e,t)}return t}info(e){if(!e)return null;let t=this.details.get(e)?.session,n=this.summaries.get(e);return n&&_e(n,t)?n:t??n??null}accept(e){if(!this.active||!_e(e,this.info(e.sessionId)))return;if(this.summaries.set(e.sessionId,e),this.summaries.size>1006){let e=[...this.summaries.keys()].find(e=>e!==this.book.selectedId&&!this.details.has(e)&&!this.rows.includes(e));e&&this.summaries.delete(e)}let t=this.book.sessions.get(e.sessionId);t?.stopTarget&&(e.turnId!==t.stopTarget.turnId||e.epoch!==t.stopTarget.epoch||!x(e))&&(t.stopTarget=null,t.operation.kind===`stopping`&&(t.operation=t.retry?{kind:`unknown-send`,error:`The original message still needs reconciliation.`}:{kind:`idle`,error:null}))}state(e){let t=this.details.get(e);return t||(t=b(e),this.details.set(e,t),this.trimDetails()),t}trimDetails(){for(let e of this.details.keys()){if(this.details.size<=pe)break;e!==this.book.selectedId&&(this.details.delete(e),this.detailReads.get(e)?.abort(),this.detailReads.delete(e),this.syncing.delete(e))}}update(e,t){this.details.set(e,t),t.session&&this.accept(t.session);let n=this.book.sessions.get(e);if(n?.retry&&t.items.some(e=>e.kind===`user_message`&&e.clientTurnKey===n.retry.key)&&K(n,n.retry.key),n&&t.synced){let e=new Set(t.permissions.map(e=>e.permissionId));for(let t of Object.keys(n.permissionOperations))!e.has(t)&&!n.permissionOperations[t].pending&&delete n.permissionOperations[t]}this.notify()}makeModel(){let e=this.book.selectedId,t=this.info(e),n=this.draft(e),r=e?this.details.get(e):void 0,i=t&&r?.synced?{...t,pendingPermissionCount:r.permissions.length}:t,a=n.operation,o=this.book.storageWarning??this.book.recoveryWarning,s=[`creating`,`sending`,`stopping`,`resuming`,`patching`].includes(a.kind)&&!a.error,c=e===null?!!this.catalog:!!r?.synced&&(!i||i.sequence<=r.cursor)&&n.requiredSequence<=(r?.cursor??0);return{catalog:this.catalog,sessions:this.rows.map(e=>{let t=this.info(e),n=this.details.get(e);return t&&n?.synced?{...t,pendingPermissionCount:n.permissions.length}:t}).filter(e=>!!e),selectedId:e,session:i,items:r?.items??[],permissions:r?.permissions??[],input:n.input,selection:i?W(i):n.selection,gitInfo:this.gitInfo,loading:this.indexLoading||!!r?.hydrating||!!e&&!r?.hydrated&&!r?.error,pending:s,busy:x(i),synced:c,transport:this.transport,error:[a.error??r?.error??this.indexError??this.catalogError??this.gitError??i?.error?.message,o].filter(Boolean).join(` `)||null,operation:{...a,error:a.error&&o?`${a.error} ${o}`:a.error},retryText:n.retry?.text??null,canRetrySameSend:!!e&&a.kind===`unknown-send`&&!!n.retry&&c&&i?.archivedAt===null,permissionOperations:{...n.permissionOperations},hasMoreSessions:this.moreSessions,hasOlderHistory:r?.hasOlder??!1,filter:this.filter,creationUnknown:e===null&&n.createUnknown,startAnotherSession:this.startAnotherSession,newSession:this.newSession,selectSession:this.selectSession,setInput:this.setInput,setSelection:this.setSelection,pickWorkspace:this.pickWorkspace,send:this.send,retrySameSend:this.retrySameSend,stop:this.stop,resume:this.resume,rename:this.rename,archive:this.archive,answer:this.answer,refresh:this.refresh,loadMoreSessions:this.loadMoreSessions,loadOlderHistory:this.loadOlderHistory,setFilter:this.setFilter,clearError:this.clearError}}async readCatalog(){let e=++this.catalogGeneration,t=this.lifetime;try{let n=await this.client.listModelOptions(this.abort.signal);if(!this.active||t!==this.lifetime||e!==this.catalogGeneration)return;this.catalog=n,this.catalogError=null;let r=this.book.fresh;!r.selection.model&&!r.selectionEdit&&r.operation.kind===`idle`&&(r.selection=G(n,{...r.selection,provider:n.defaultProvider})),this.notify()}catch(n){this.active&&t===this.lifetime&&e===this.catalogGeneration&&(this.catalogError=J(n),this.notify())}}async readIndex(e=!1){let t=++this.indexGeneration,n=this.lifetime,r=e?this.offset:0,i=e?me:Math.min(q,Math.max(me,this.offset));this.indexLoading=!0,this.notify();try{let a=await this.client.listSessions({...this.filter,limit:i,offset:r,...this.filter.scope===`cwd`?{cwd:this.workingDir}:{}},this.abort.signal);if(!this.active||n!==this.lifetime||t!==this.indexGeneration)return;for(let e of a.sessions){this.accept(e);let t=this.details.get(e.sessionId);t?.hydrated&&!t.hydrating&&e.sequence>t.cursor&&(this.details.set(e.sessionId,E(t,{type:`stale`})),this.sync(e.sessionId))}this.rows=[...new Set([...e?this.rows:[],...a.sessions.map(e=>e.sessionId)])].slice(0,q),this.offset=a.offset+a.sessions.length,this.moreSessions=a.hasMore&&this.rows.length<q,this.indexError=null;let o=new Set([...this.rows,...this.details.keys(),...this.book.selectedId?[this.book.selectedId]:[]]);for(let e of this.summaries.keys())o.has(e)||this.summaries.delete(e)}catch(e){this.active&&n===this.lifetime&&t===this.indexGeneration&&(this.indexError=J(e))}finally{this.active&&n===this.lifetime&&t===this.indexGeneration&&(this.indexLoading=!1,this.notify())}}scheduleIndex(){this.active&&this.timer===void 0&&(this.timer=setTimeout(()=>{this.timer=void 0,this.readIndex()},ge))}sync(e,t=!1){let n=this.syncing.get(e);if(n)return n;let r=this.lifetime,i=new AbortController;this.detailReads.set(e,i),this.state(e);let a=()=>this.active&&r===this.lifetime&&this.detailReads.get(e)===i&&this.details.has(e),o=(async()=>{let n=0,r=null;try{for(let o=0;o<he&&a();o++){let o=this.state(e);if(t||!o.hydrated||o.needsSnapshot){if(++n>2)throw Error(`snapshot did not cover live updates`);t=!1,this.update(e,E(o,{type:`snapshot-start`}));let s=this.book.sessions.get(e)?.stopTarget,c=s?.outcome===`unknown`?s:null,l=await this.client.snapshot(e,i.signal);if(!a())return;r=c,this.update(e,E(this.state(e),{type:`snapshot`,snapshot:l}))}if(o=this.state(e),o.needsSnapshot)continue;let s=o.cursor,c=await this.client.events(e,s,i.signal);if(!a())return;let l=E(this.state(e),{type:`page`,page:c});if(this.update(e,l),!l.needsSnapshot){if(l.synced&&l.cursor>=(this.book.sessions.get(e)?.requiredSequence??0)){this.reconcileStop(e,r);return}if(l.cursor<=s){t=!0;continue}}}a()&&this.update(e,E(this.state(e),{type:`error`,error:`History is still catching up. Refresh to continue.`}))}catch(t){if(!a())return;if(t instanceof p&&t.code===`invalid_sequence`&&n<2){let t=await this.client.snapshot(e,i.signal).catch(()=>null);if(!a())return;if(t){this.update(e,E(this.state(e),{type:`snapshot`,snapshot:t}));return}}this.update(e,E(this.state(e),{type:`error`,error:J(t)})),t instanceof p&&t.code===`session_not_found`&&this.scheduleIndex()}})().finally(()=>{this.syncing.get(e)===o&&this.syncing.delete(e),this.detailReads.get(e)===i&&this.detailReads.delete(e),this.trimDetails()});return this.syncing.set(e,o),o}onEvent=e=>{if(!this.active)return;e.session?.sessionId===e.sessionId&&this.accept(e.session),(e.event===`code_session`||e.item?.kind===`permission_request`||e.update?.status)&&this.scheduleIndex();let t=this.book.sessions.get(e.sessionId);e.item?.kind===`user_message`&&e.item.clientTurnKey&&t?.retry?.key===e.item.clientTurnKey&&(t.requiredSequence=Math.max(t.requiredSequence,e.sequence),K(t,e.item.clientTurnKey));let n=this.details.get(e.sessionId);if(!n){this.notify();return}let r=E(n,{type:`event`,event:e});this.update(e.sessionId,r),!r.synced&&!r.hydrating&&this.sync(e.sessionId)};onTransport=e=>{this.transport=e;for(let[e,t]of this.details)this.details.set(e,E(t,{type:`stale`}));if(this.notify(),e===`connected`&&this.active){this.readIndex();for(let e of this.details.keys())this.sync(e,!0)}};refresh=async()=>{let e=this.book.selectedId;await Promise.all([this.readCatalog(),this.readIndex(),e?this.sync(e,!0):Promise.resolve(),this.readGit()])};loadMoreSessions=async()=>{this.moreSessions&&!this.indexLoading&&await this.readIndex(!0)};setFilter=e=>{this.filter={...e},this.offset=0,this.rows=[],this.moreSessions=!1,this.notify(),this.readIndex()};startAnotherSession=()=>{let e=this.book.fresh;if(this.book.selectedId!==null||!e.createUnknown)return;let t=V(e.selection);t.input=e.input,t.edit=e.edit,t.selectionEdit=e.selectionEdit,t.operation.error=`The original session may still exist. Your text is preserved; Send will create another session.`,this.book.fresh=t,this.book.navigation++,this.pickerGeneration++,this.notify()};newSession=()=>{this.book.selectedId=null,this.book.navigation++,this.gitInfo=null,this.notify(),this.readGit()};selectSession=async e=>{this.book.selectedId=e,this.book.navigation++,this.draft(e),this.state(e),this.gitInfo=null,this.notify(),await this.sync(e,!0),this.book.selectedId===e&&await this.readGit()};setInput=e=>{let t=this.draft();t.input=e,t.edit++,this.notify()};clearError=()=>{let e=this.draft();e.operation.kind===`idle`&&(e.operation={kind:`idle`,error:null}),this.indexError=null,this.book.recoveryWarning=null,this.notify()};async readGit(){let e=++this.gitGeneration,t=this.lifetime,n=this.book.selectedId,r=this.info(n)?.cwd??(n===null?this.book.fresh.selection.cwd:``);if(this.gitInfo=null,this.gitError=null,r&&this.active)try{let i=await this.client.getGitInfo(r,this.abort.signal);this.active&&t===this.lifetime&&e===this.gitGeneration&&n===this.book.selectedId&&(this.gitInfo=i,this.notify())}catch(r){this.active&&t===this.lifetime&&e===this.gitGeneration&&n===this.book.selectedId&&(this.gitError=J(r),this.notify())}}pickWorkspace=async()=>{let e=this.book.fresh;if(this.book.selectedId!==null||e.operation.kind!==`idle`||e.createUnknown)return;let t=this.book.navigation,n=e.selectionEdit,r=++this.pickerGeneration;try{let i=await this.client.pickWorkspace();if(!this.active||r!==this.pickerGeneration||t!==this.book.navigation||n!==e.selectionEdit||e!==this.book.fresh||e.operation.kind!==`idle`)return;!i.cancelled&&i.path&&(e.selection={...e.selection,cwd:i.path},e.selectionEdit++,this.notify(),await this.readGit())}catch(i){this.active&&r===this.pickerGeneration&&t===this.book.navigation&&n===e.selectionEdit&&e===this.book.fresh&&e.operation.kind===`idle`&&(e.operation.error=J(i),this.notify())}};setSelection=async e=>{let t=this.book.selectedId,n=this.info(t);if(n&&e.provider&&e.provider!==n.provider){this.newSession(),await this.setSelection({...e,cwd:n.cwd});return}let r=this.draft();if(r.operation.kind!==`idle`||r.createUnknown)return;if(n&&t){if(e.cwd!==void 0&&e.cwd!==n.cwd||e.provider&&e.provider!==n.provider){r.operation.error=`Runtime and workspace are fixed for this session. Create a new session to change them.`,this.notify();return}if(n.status!==`idle`||!this.model.synced||n.archivedAt!==null){r.operation.error=`Wait for this session to be idle and synchronized before changing settings.`,this.notify();return}await this.patch(t,{model:e.model??n.model,effort:e.effort===void 0?n.effort:e.effort,permissionMode:e.permissionMode??n.permissionMode});return}if(t)return;let i=e.provider!==void 0&&e.provider!==r.selection.provider,a={...r.selection,...e};this.catalog&&i&&(a=G(this.catalog,a,!0));let o=this.catalog?.providers.find(e=>e.id===a.provider);a.effort!==null&&o&&!o.capabilities.efforts.includes(a.effort)&&(a.effort=null),r.selection=a,r.selectionEdit++,this.notify(),e.cwd!==void 0&&await this.readGit()};async patch(e,t,n=!1){let r=this.draft(e),i=this.info(e);if(!i||r.operation.kind!==`idle`||x(i)){let e=Error(i?`Wait for the current session action to finish before changing it.`:`Refresh this session before changing it.`);if(r.operation.error=e.message,this.notify(),n)throw e;return}let a=null;r.operation={kind:`patching`,error:null},this.notify();try{this.accept(await this.client.patchSession(e,{...t,expectedRevision:i.revision})),r.operation={kind:`idle`,error:null}}catch(t){t instanceof p&&t.session?.sessionId===e&&this.accept(t.session),a=t instanceof p?t:Error(J(t)),r.operation={kind:`idle`,error:a.message}}if(this.notify(),this.scheduleIndex(),this.active&&await this.sync(e,!0),n&&a)throw a}rename=async(e,t)=>{await this.patch(e,{title:t},!0)};archive=async(e,t)=>{await this.patch(e,{archived:t},!0)};send=async()=>{let e=this.book.selectedId,t=this.draft(e);if(t.operation.kind!==`idle`||t.createUnknown||!t.input.trim())return;let n=this.info(e);if(e&&(!n||n.status!==`idle`||n.archivedAt!==null||!this.model.synced)){t.operation.error=`Wait for the session to be idle and synchronized before sending.`,this.notify();return}let r={text:t.input,edit:t.edit,key:crypto.randomUUID()},i=this.book.navigation;if(!e){let n={...t.selection},r=this.catalog?.providers.find(e=>e.id===n.provider);if(!r?.available||!n.cwd.trim()||!r.models.includes(n.model)||!r.capabilities.permissionModes.includes(n.permissionMode)||n.effort!==null&&!r.capabilities.efforts.includes(n.effort)){t.operation.error=`Choose an available runtime, workspace, model and supported settings before sending.`,this.notify();return}t.operation={kind:`creating`,error:null},this.notify();try{let r=await this.client.createSession(n);e=r.sessionId,this.book.sessions.set(e,t),this.book.fresh===t&&(this.book.fresh=V(n)),this.book.navigation===i&&this.book.selectedId===null&&(this.book.selectedId=e,this.book.navigation++),this.accept(r),this.active&&this.state(e),this.scheduleIndex()}catch(e){t.createUnknown=!Y(e),t.operation={kind:t.createUnknown?`creating`:`idle`,error:t.createUnknown?`Session creation could not be confirmed. The original session may exist. Refresh the list, or choose Start another session to keep this text in a new draft.`:J(e)},this.notify(),this.scheduleIndex();return}}t=this.draft(e),t.retry=r,await this.submit(e,t)};async submit(e,t){let n=t.retry;if(n){t.operation={kind:`sending`,error:null},this.notify();try{let r=await this.client.sendPrompt(e,{text:n.text,clientTurnKey:n.key});if(r.clientTurnKey!==n.key)throw Error(`Mismatched prompt receipt`);t.requiredSequence=Math.max(t.requiredSequence,r.sequence);let i=this.details.get(e);i&&this.details.set(e,E(i,{type:`stale`})),K(t,n.key)}catch(e){t.retry?.key===n.key&&(t.operation={kind:Y(e)?`idle`:`unknown-send`,error:Y(e)?J(e):`Message acceptance is unknown. Refresh, or explicitly retry the original message with the same key.`},Y(e)&&(t.retry=null))}this.notify(),this.scheduleIndex(),this.active&&await this.sync(e,!0)}}retrySameSend=async()=>{let e=this.book.selectedId,t=this.draft(e);e&&this.model.canRetrySameSend&&t.operation.kind===`unknown-send`&&await this.submit(e,t)};reconcileStop(e,t){let n=this.book.sessions.get(e),r=this.details.get(e),i=this.info(e);!t||t.outcome!==`unknown`||n?.stopTarget!==t||!r?.synced||!i||i.sequence>r.cursor||i.turnId!==t.turnId||i.epoch!==t.epoch||(i.status===`starting`||i.status===`streaming`?(t.outcome=`retryable`,n.operation={kind:n.retry?`unknown-send`:`idle`,error:`Stop could not be confirmed. The same turn is still running. Press Stop to retry for this turn.`}):i.status===`stopping`&&(t.outcome=`accepted`,n.operation={kind:`stopping`,error:null}),this.notify())}stop=async()=>{let e=this.book.selectedId,t=this.info(e);if(!e||!t?.turnId||!x(t)||!t.capabilities.interrupt||t.status===`stopping`)return;let n=this.draft(e),r=n.stopTarget;if(r&&(r.outcome!==`retryable`||!this.model.synced||r.turnId!==t.turnId||r.epoch!==t.epoch))return;let i=r??{turnId:t.turnId,epoch:t.epoch,outcome:`pending`};i.outcome=`pending`,n.stopTarget=i,n.operation={kind:`stopping`,error:null},this.notify();try{let t=await this.client.cancelPrompt(e,{turnId:i.turnId,epoch:i.epoch});n.stopTarget===i&&(i.outcome=`accepted`),this.accept(t)}catch(e){n.stopTarget===i&&(i.outcome=`unknown`,n.operation={kind:`stopping`,error:J(e)},Y(e)&&(n.stopTarget=null,n.operation.kind=`idle`))}this.notify(),this.scheduleIndex(),this.active&&(i.outcome===`unknown`&&await this.syncing.get(e),this.active&&await this.sync(e,!0))};resume=async()=>{let e=this.book.selectedId,t=this.info(e),n=this.draft(e);if(e&&t&&this.model.synced&&n.operation.kind===`idle`&&t.archivedAt===null&&[`suspended`,`failed`].includes(t.status)&&t.capabilities.resume&&t.resume.available&&(t.status!==`failed`||t.error?.recoverable)){n.operation={kind:`resuming`,error:null},this.notify();try{this.accept(await this.client.attachSession(e)),n.operation={kind:`idle`,error:null}}catch(e){n.operation={kind:`idle`,error:J(e)}}this.notify(),this.scheduleIndex(),this.active&&await this.sync(e,!0)}};answer=async(e,t)=>{let n=e.sessionId,r=this.details.get(n),i=this.info(n),a=this.draft(n);if(a.permissionOperations[e.permissionId]?.pending)return;let o=r?.permissions.find(t=>t.permissionId===e.permissionId);if(!r?.synced||!i||i.sequence>r.cursor||!o||o.turnId!==e.turnId||o.epoch!==e.epoch||i.turnId!==e.turnId||i.epoch!==e.epoch||!o.options.some(e=>e.optionId===t)){a.permissionOperations[e.permissionId]={pending:!1,error:`This approval is no longer current. Refresh its status.`},this.notify(),this.active&&await this.sync(n,!0);return}a.permissionOperations[e.permissionId]={pending:!0,error:null},this.notify();try{await this.client.answerPermission(e.permissionId,{sessionId:n,turnId:e.turnId,epoch:e.epoch,optionId:t}),a.permissionOperations[e.permissionId]={pending:!0,error:null}}catch(t){a.permissionOperations[e.permissionId]={pending:!0,error:J(t)}}this.notify(),this.scheduleIndex(),this.active&&await this.sync(n,!0);let s=this.details.get(n),c=!s?.synced||s.permissions.some(t=>t.permissionId===e.permissionId),l=a.permissionOperations[e.permissionId];c&&l?a.permissionOperations[e.permissionId]={pending:!1,error:l.error}:delete a.permissionOperations[e.permissionId],this.notify()};loadOlderHistory=async()=>{let e=this.book.selectedId;if(!e||this.historyLoading.has(e))return;let t=this.details.get(e);if(!t?.hydrated||!t.hasOlder||t.beforeSequence===null)return;let n=this.lifetime;this.historyLoading.add(e);try{let r=await this.client.history(e,t.beforeSequence,this.abort.signal);this.active&&n===this.lifetime&&this.details.get(e)?.beforeSequence===t.beforeSequence&&this.update(e,E(this.state(e),{type:`history`,page:r}))}catch(t){this.active&&n===this.lifetime&&(this.draft(e).operation.error=J(t),this.notify())}finally{this.historyLoading.delete(e)}}};function ye({port:e,onEvent:t,onTransport:n}){let r=(0,u.useRef)({onEvent:t,onTransport:n});r.current={onEvent:t,onTransport:n},(0,u.useEffect)(()=>{if(!e)return;let t=!0,n=new EventSource(`${m(e)}/api/events`);return n.onopen=()=>{t&&r.current.onTransport?.(`connected`)},n.onmessage=e=>{if(!t)return;let n;try{n=JSON.parse(e.data)}catch{return}n?.topic!==`code`||typeof n.sessionId!=`string`||!Number.isSafeInteger(n.sequence)||n.sequence<1||!Number.isSafeInteger(n.epoch)||(n.event===`code_item`||n.event===`code_item_update`||n.event===`code_session`)&&r.current.onEvent(n)},n.onerror=()=>{t&&r.current.onTransport?.(n.readyState===EventSource.CLOSED?`disconnected`:`reconnecting`)},()=>{t=!1,n.close()}},[e])}function be({port:e,workingDir:t}){let n=m(e),r=(0,u.useMemo)(()=>new ve({port:e,workingDir:t}),[n,e]);return(0,u.useEffect)(()=>r.mount(),[r]),(0,u.useEffect)(()=>r.setWorkingDir(t),[r,t]),ye({port:e,onEvent:r.onEvent,onTransport:r.onTransport}),(0,u.useSyncExternalStore)(r.subscribe,r.getModel,r.getModel)}var X={"codex-app":`Codex`,claude:`Claude`,cursor:`Cursor`,grok:`Grok`},xe={ask:`Ask first`,auto:`Auto (YOLO)`,"read-only":`Read only`},Se={ask:`Review native permission requests before allowing actions.`,auto:`The native runtime may execute actions without asking for approval.`,"read-only":`The native runtime restricts actions to read-only access.`},Ce={idle:`Ready`,starting:`Starting`,streaming:`Running`,stopping:`Stopping`,suspended:`Suspended`,failed:`Runtime failed`};function we(e){return e.status===`starting`||e.status===`streaming`||e.status===`stopping`}function Te(e){return e.archivedAt===null&&e.capabilities.resume&&e.resume.available&&(e.status===`suspended`||e.status===`failed`&&e.error?.recoverable===!0)}function Ee(e){return e.kind===`turn_cancelled`||e.status===`cancelled`?`Stopped`:e.kind===`turn_failed`||e.status===`error`?`Failed`:e.kind===`turn_completed`?`Completed`:{pending:`Pending`,running:`Running`,done:`Done`,error:`Failed`,cancelled:`Stopped`}[e.status]}var Z=l();function De({session:e,controller:t}){let[n,r]=(0,u.useState)(!1),[i,a]=(0,u.useState)(e.title??``),[o,s]=(0,u.useState)(!1),[c,l]=(0,u.useState)(null),d=(0,u.useRef)(!1),f=(0,u.useRef)(null),p=(0,u.useId)(),m=t.selectedId===e.sessionId,h=we(e),g=m&&t.synced?t.permissions.length:e.pendingPermissionCount;async function _(e,t){if(!d.current){d.current=!0,s(!0),l(null);try{await e(),t?.()}catch(e){l(e instanceof Error?e.message:String(e))}finally{d.current=!1,s(!1)}}}function v(){r(!1),f.current?.focus()}return(0,Z.jsxs)(`li`,{className:`code-session-row`,children:[(0,Z.jsxs)(`button`,{ref:f,type:`button`,className:`code-session-item${m?` active`:``}`,"aria-current":m?`true`:void 0,onClick:()=>void _(()=>t.selectSession(e.sessionId)),children:[(0,Z.jsx)(`span`,{className:`code-session-cwd`,children:e.title||`Untitled session`}),(0,Z.jsxs)(`span`,{className:`code-session-meta`,title:e.cwd,children:[X[e.provider],` · `,e.cwd]}),(0,Z.jsx)(`span`,{className:`code-session-status code-session-status-${e.status}`,children:Ce[e.status]}),(0,Z.jsx)(`span`,{className:`code-session-attention`,children:g===void 0?`Approval status unknown`:g>0?`${g} pending approval${g===1?``:`s`}`:`No pending approvals`})]}),n?(0,Z.jsxs)(`form`,{className:`code-session-rename`,onSubmit:n=>{n.preventDefault(),i.trim()&&_(()=>t.rename(e.sessionId,i.trim()),v)},children:[(0,Z.jsx)(`input`,{autoFocus:!0,"aria-label":`Session title`,"aria-describedby":c?p:void 0,value:i,disabled:o,onChange:e=>a(e.target.value),onKeyDown:t=>{t.key===`Escape`&&!o&&(t.preventDefault(),a(e.title??``),v())}}),(0,Z.jsx)(`button`,{type:`submit`,disabled:o||!i.trim(),children:`Save`}),(0,Z.jsx)(`button`,{type:`button`,disabled:o,onClick:v,children:`Cancel`})]}):(0,Z.jsxs)(`details`,{className:`code-session-actions`,children:[(0,Z.jsx)(`summary`,{"aria-label":`Actions for ${e.title||`Untitled session`}`,children:`Actions`}),(0,Z.jsxs)(`div`,{children:[(0,Z.jsx)(`button`,{type:`button`,disabled:o||h,onClick:()=>{a(e.title??``),r(!0)},children:`Rename`}),(0,Z.jsx)(`button`,{type:`button`,disabled:o||h,title:h?`Stop before archiving`:void 0,onClick:()=>void _(()=>t.archive(e.sessionId,e.archivedAt===null)),children:e.archivedAt===null?`Archive`:`Restore`}),Te(e)&&(0,Z.jsx)(`button`,{type:`button`,disabled:o||!m||!t.synced||t.pending,title:m?`Resume without resending a prompt`:`Select this session to resume it`,onClick:()=>void _(t.resume),children:`Resume`}),h&&(0,Z.jsx)(`small`,{children:`Stop before changing session metadata.`})]})]},`${t.selectedId}:${e.sessionId}`),o&&(0,Z.jsx)(`span`,{className:`code-session-view-hint`,role:`status`,children:`Updating session…`}),c&&(0,Z.jsx)(`div`,{id:p,className:`code-session-list-error`,role:`alert`,children:c})]})}function Oe({controller:e}){let[t,n]=(0,u.useState)(``),[r,i]=(0,u.useState)(!1),[a,o]=(0,u.useState)(null),[s,c]=(0,u.useState)(!1),l=(0,u.useRef)(!1),d=e.sessions.filter(e=>`${e.title??``} ${e.cwd} ${X[e.provider]}`.toLowerCase().includes(t.toLowerCase())),f=new Map;for(let e of d){let t=r?e.cwd:``,n=f.get(t)??[];n.push(e),f.set(t,n)}async function p(){if(!l.current){l.current=!0,c(!0),o(null);try{await e.loadMoreSessions()}catch(e){o(e instanceof Error?e.message:String(e))}finally{l.current=!1,c(!1)}}}return(0,Z.jsxs)(`nav`,{className:`code-session-list`,"aria-label":`Code sessions`,children:[(0,Z.jsxs)(`div`,{className:`code-session-list-header`,children:[(0,Z.jsx)(`span`,{className:`code-session-list-title`,children:`Sessions`}),(0,Z.jsx)(`button`,{type:`button`,className:`code-session-new-btn`,onClick:e.newSession,"aria-label":`New Code session`,children:`+`})]}),(0,Z.jsxs)(`div`,{className:`code-session-view-toggle`,"aria-label":`Session view`,children:[(0,Z.jsx)(`button`,{type:`button`,"aria-pressed":e.filter.scope===`all`,className:`code-session-view-btn${e.filter.scope===`all`?` active`:``}`,onClick:()=>e.setFilter({...e.filter,scope:`all`}),children:`All`}),(0,Z.jsx)(`button`,{type:`button`,"aria-pressed":e.filter.scope===`cwd`,className:`code-session-view-btn${e.filter.scope===`cwd`?` active`:``}`,onClick:()=>e.setFilter({...e.filter,scope:`cwd`}),children:`This cwd`}),(0,Z.jsx)(`button`,{type:`button`,"aria-pressed":r,className:`code-session-view-btn${r?` active`:``}`,onClick:()=>i(!r),children:`Group`})]}),(0,Z.jsxs)(`label`,{className:`code-session-archive-filter`,children:[(0,Z.jsx)(`input`,{type:`checkbox`,checked:e.filter.archived,onChange:t=>e.setFilter({...e.filter,archived:t.target.checked})}),`Archived`]}),(0,Z.jsx)(`input`,{className:`code-session-search`,type:`search`,"aria-label":`Search loaded sessions`,placeholder:`Search loaded sessions…`,value:t,onChange:e=>n(e.target.value)}),(0,Z.jsxs)(`button`,{type:`button`,className:`code-session-item${e.selectedId===null?` active`:``}`,"aria-current":e.selectedId===null?`true`:void 0,onClick:e.newSession,children:[(0,Z.jsx)(`span`,{className:`code-session-cwd`,children:`New session draft`}),(0,Z.jsx)(`span`,{className:`code-session-meta`,children:`Preserved unsent draft`})]}),e.loading&&(0,Z.jsx)(`div`,{className:`code-session-list-loading`,role:`status`,children:`Loading sessions…`}),[...f].map(([t,n])=>(0,Z.jsxs)(`section`,{className:`code-session-group`,children:[r&&(0,Z.jsx)(`h3`,{className:`code-session-group-title`,title:t,children:t}),(0,Z.jsx)(`ul`,{className:`code-session-list-items`,children:n.map(t=>(0,Z.jsx)(De,{session:t,controller:e},t.sessionId))})]},t)),!e.loading&&!d.length&&(0,Z.jsx)(`p`,{className:`code-session-list-empty`,children:t?`No loaded sessions match. Clear search or load more.`:`No sessions here. Start with the new session draft.`}),e.hasMoreSessions&&(0,Z.jsx)(`button`,{type:`button`,className:`code-inline-action`,disabled:s,onClick:()=>void p(),children:s?`Loading…`:`Load more sessions`}),(0,Z.jsx)(`button`,{type:`button`,className:`code-inline-action`,onClick:()=>{o(null),e.refresh().catch(e=>o(e instanceof Error?e.message:String(e)))},children:`Refresh sessions`}),a&&(0,Z.jsx)(`div`,{className:`code-session-list-error`,role:`alert`,children:a})]})}function ke(e){let t=(0,u.useRef)(!1),n=(0,u.useRef)(!1),r=(0,u.useRef)(!1),[i,a]=(0,u.useState)(null);async function o(){if(e.canSend&&e.inputText.trim()&&!n.current){n.current=!0,a(null);try{await e.onSubmit()}catch(e){a(e instanceof Error?e.message:String(e))}finally{n.current=!1}}}async function s(){if(e.canStop&&!r.current){r.current=!0,a(null);try{await e.onStop()}catch(e){a(e instanceof Error?e.message:String(e))}finally{r.current=!1}}}function c(e){e.nativeEvent.isComposing||t.current||e.nativeEvent.keyCode===229||e.key===`Enter`&&!e.shiftKey&&!e.altKey&&!e.ctrlKey&&!e.metaKey&&(e.preventDefault(),o())}return(0,Z.jsxs)(`div`,{className:`code-composer`,children:[(0,Z.jsxs)(`div`,{className:`code-composer-input-shell`,children:[(0,Z.jsx)(`textarea`,{className:`code-composer-input`,"aria-label":`Code prompt`,value:e.inputText,onChange:t=>e.onInputChange(t.target.value),onKeyDown:c,onCompositionStart:()=>{t.current=!0},onCompositionEnd:()=>{t.current=!1},placeholder:e.busy?`Draft a follow-up while this turn runs…`:`Describe a task or ask a question…`,rows:2,readOnly:e.readOnly}),(0,Z.jsx)(`span`,{className:`code-composer-hint`,children:`Enter to send · Shift+Enter for a new line`})]}),e.busy?(0,Z.jsx)(`button`,{type:`button`,className:`code-composer-send code-composer-stop`,"aria-label":`Stop current turn`,disabled:!e.canStop||e.stopping,onClick:()=>void s(),children:e.stopping?`Stopping…`:`Stop`}):(0,Z.jsx)(`button`,{type:`button`,className:`code-composer-send`,"aria-label":`Send prompt`,disabled:!e.canSend||!e.inputText.trim(),onClick:()=>void o(),children:e.pending?`Sending…`:`Send`}),i&&(0,Z.jsx)(`div`,{className:`code-action-error`,role:`alert`,children:i})]})}function Q({label:e,value:t,options:n,disabled:r,onChange:i,displayValue:a}){let o=(0,u.useId)(),s=(0,u.useRef)(null),c=(0,u.useRef)(null),[l,f]=(0,u.useState)(null),p=n.find(e=>e.value===t);function m(e=!0){f(null),e&&s.current?.focus()}function h(){let e=s.current?.getBoundingClientRect();if(!e||r)return;let t=Math.min(340,window.innerWidth-28),n=Math.max(0,e.top-16),i=Math.max(0,window.innerHeight-e.bottom-16),a={left:Math.max(14,Math.min(e.left,window.innerWidth-t-14)),width:t};f(n>=i?{...a,bottom:window.innerHeight-e.top+8,maxHeight:Math.min(280,n)}:{...a,bottom:`auto`,top:e.bottom+8,maxHeight:Math.min(280,i)})}(0,u.useEffect)(()=>{if(!l)return;let e=c.current?.querySelectorAll(`button:not(:disabled)`);([...e??[]].find(e=>e.getAttribute(`aria-selected`)===`true`)??e?.[0])?.focus();let t=e=>{!c.current?.contains(e.target)&&!s.current?.contains(e.target)&&m(!1)},n=()=>m(!1);return document.addEventListener(`pointerdown`,t),window.addEventListener(`resize`,n),()=>{document.removeEventListener(`pointerdown`,t),window.removeEventListener(`resize`,n)}},[l]),(0,u.useEffect)(()=>{r&&f(null)},[r]);function g(e){if(e.key===`Escape`){e.preventDefault(),m();return}if(e.key===`Tab`){e.preventDefault(),m();return}let t=[...c.current?.querySelectorAll(`button:not(:disabled)`)??[]],n=t.findIndex(e=>e===document.activeElement),r;if(e.key===`ArrowDown`)r=(n+1)%t.length;else if(e.key===`ArrowUp`)r=(n-1+t.length)%t.length;else if(e.key===`Home`)r=0;else if(e.key===`End`)r=t.length-1;else return;e.preventDefault(),t[r]?.focus()}return(0,Z.jsxs)(`div`,{className:`code-footer-menu`,children:[(0,Z.jsxs)(`button`,{ref:s,type:`button`,className:`code-footer-menu-trigger`,"aria-label":e,"aria-haspopup":`listbox`,"aria-expanded":!!l,"aria-controls":l?o:void 0,disabled:r,title:p?.detail,onClick:()=>l?m():h(),onKeyDown:e=>{(e.key===`ArrowDown`||e.key===`ArrowUp`)&&(e.preventDefault(),h())},children:[(0,Z.jsx)(`span`,{className:`code-footer-label`,children:e}),(0,Z.jsx)(`strong`,{children:p?.label??a??(t||`Not selected`)})]}),l&&(0,d.createPortal)((0,Z.jsx)(`div`,{ref:c,id:o,role:`listbox`,"aria-label":e,className:`code-footer-dropup code-footer-floating`,style:l,onKeyDown:g,children:n.map(e=>(0,Z.jsx)(`button`,{type:`button`,role:`option`,"aria-selected":e.value===t,disabled:e.disabled,className:`code-footer-dropup-option`,onClick:()=>{i(e.value),m()},children:(0,Z.jsxs)(`span`,{children:[(0,Z.jsx)(`strong`,{children:e.label}),e.detail&&(0,Z.jsx)(`small`,{children:e.detail})]})},e.value))}),document.body)]})}function Ae({controller:e}){let t=e.selection,n=e.catalog?.providers.find(e=>e.id===t.provider),r=e.session?.capabilities??n?.capabilities,i=e.selectedId!==null,a=e.pending||e.busy||e.creationUnknown||e.operation.kind!==`idle`||i&&(!e.synced||e.session?.status!==`idle`||e.session?.archivedAt!==null),[o,s]=(0,u.useState)(t.model),[c,l]=(0,u.useState)(!1),[d,f]=(0,u.useState)(null),p=(0,u.useRef)(!1),m=(0,u.useId)();(0,u.useEffect)(()=>{s(t.model)},[t.model]);async function h(t){if(!(a||p.current)){p.current=!0,l(!0),f(null);try{await e.setSelection(t)}catch(e){f(e instanceof Error?e.message:String(e))}finally{p.current=!1,l(!1)}}}let g=a||c,_=g;return(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`code-composer-footer`,children:[(0,Z.jsx)(Q,{label:`Runtime`,value:t.provider,disabled:i?!e.catalog:g||!e.catalog,options:Object.keys(X).map(n=>{let r=e.catalog?.providers.find(e=>e.id===n);return{value:n,label:i&&n!==t.provider?`New ${X[n]} session`:X[n],disabled:!r?.available||i&&n===t.provider,detail:r?.reason??(r?.available?void 0:`Availability unknown`)}}),onChange:t=>{i?e.setSelection({provider:t}).catch(e=>f(e instanceof Error?e.message:String(e))):h({provider:t})}}),(0,Z.jsxs)(`form`,{className:`code-footer-model-form`,onSubmit:e=>{e.preventDefault(),o.trim()&&!_&&h({model:o.trim()})},children:[(0,Z.jsx)(`label`,{className:`code-footer-label`,htmlFor:`${m}-input`,children:`Model`}),(0,Z.jsx)(`input`,{id:`${m}-input`,"aria-label":`Native model ID`,list:m,value:o,disabled:_,onChange:e=>s(e.target.value),onKeyDown:e=>{e.key===`Escape`&&(s(t.model),e.currentTarget.blur())}}),(0,Z.jsx)(`datalist`,{id:m,children:n?.models.map(e=>(0,Z.jsx)(`option`,{value:e},e))}),o!==t.model&&(0,Z.jsx)(`button`,{type:`submit`,disabled:_||!o.trim(),children:`Apply`})]}),!!r?.efforts.length&&(0,Z.jsx)(Q,{label:`Effort`,value:t.effort??``,options:[{value:``,label:`Native default`},...r.efforts.map(e=>({value:e,label:e}))],disabled:g,onChange:e=>void h({effort:e||null})}),(0,Z.jsx)(Q,{label:`Permission`,value:t.permissionMode,displayValue:xe[t.permissionMode],disabled:g||!r?.permissions,options:(r?.permissionModes??[]).map(e=>({value:e,label:xe[e],detail:Se[e]})),onChange:e=>void h({permissionMode:e})}),i&&(0,Z.jsx)(`button`,{type:`button`,className:`code-inline-action`,onClick:e.newSession,children:`New session`})]}),!n?.available&&(0,Z.jsxs)(`div`,{className:`code-selection-notice`,children:[n?.reason??`Runtime availability has not been confirmed.`,(0,Z.jsx)(`button`,{type:`button`,className:`code-inline-action`,onClick:()=>{e.refresh().catch(e=>f(e instanceof Error?e.message:String(e)))},children:`Refresh availability`})]}),t.permissionMode===`auto`&&(0,Z.jsx)(`p`,{className:`code-policy-note`,children:`Auto (YOLO): actions may run without approval.`}),(c||e.operation.kind===`patching`)&&(0,Z.jsx)(`span`,{role:`status`,children:`Saving settings…`}),d&&(0,Z.jsx)(`div`,{className:`code-action-error`,role:`alert`,children:d})]})}function je({permission:e,operation:t,eligible:n,onAnswer:r}){let i=(0,u.useRef)(!1),[a,o]=(0,u.useState)(!1),[s,c]=(0,u.useState)(null);async function l(a){if(!(!n||i.current||t?.pending)){i.current=!0,o(!0),c(null);try{await r(e,a)}catch(e){c(e instanceof Error?e.message:String(e))}finally{i.current=!1,o(!1)}}}return(0,Z.jsxs)(`section`,{className:`code-permission-card`,"aria-label":e.title,children:[(0,Z.jsxs)(`div`,{className:`code-permission-title`,children:[(0,Z.jsx)(`strong`,{children:e.title}),(0,Z.jsx)(`p`,{children:e.detail}),!n&&(0,Z.jsx)(`small`,{children:`Updating permission availability…`}),(a||t?.pending)&&(0,Z.jsx)(`small`,{role:`status`,children:`Checking decision…`}),(t?.error||s)&&(0,Z.jsx)(`div`,{className:`code-action-error`,role:`alert`,children:t?.error||s})]}),(0,Z.jsxs)(`div`,{className:`code-permission-actions`,children:[e.options.map(e=>(0,Z.jsx)(`button`,{type:`button`,className:`code-permission-btn`,disabled:!n||a||t?.pending,onClick:()=>void l(e.optionId),children:e.label},e.optionId)),e.options.length===0&&(0,Z.jsx)(`span`,{children:`No native actions available. Refresh this session.`})]})]})}function Me({permissions:e,operations:t,session:n,synced:r,onAnswer:i}){return e.length?(0,Z.jsxs)(`aside`,{className:`code-permissions`,"aria-label":`Pending permissions`,tabIndex:-1,id:`code-pending-permissions`,children:[(0,Z.jsxs)(`div`,{className:`code-permissions-heading`,role:`status`,children:[e.length,` pending · `,n?X[n.provider]:`Session updating`]}),e.map(e=>(0,Z.jsx)(je,{permission:e,operation:t[e.permissionId],eligible:r&&n!==null&&n.archivedAt===null&&n.sessionId===e.sessionId&&n.turnId===e.turnId&&n.epoch===e.epoch&&(n.status===`starting`||n.status===`streaming`),onAnswer:i},`${e.sessionId}:${e.permissionId}`))]}):null}var Ne=92,Pe=6;function Fe(e){let[{virtualItems:t,totalSize:s},c]=(0,u.useState)({virtualItems:[],totalSize:0}),l=(0,u.useRef)(null);l.current||=new o({count:e.count,getScrollElement:()=>e.scrollElementRef.current,estimateSize:e.estimateSize||(()=>Ne),overscan:Pe,getItemKey:e.getItemKey,indexAttribute:`data-code-transcript-idx`,useAnimationFrameWithResizeObserver:!0,observeElementRect:n,observeElementOffset:r,scrollToFn:i,measureElement:a,onChange:e=>{c({virtualItems:e.getVirtualItems(),totalSize:e.getTotalSize()})}});let d=l.current;return(0,u.useEffect)(()=>d._didMount(),[d]),(0,u.useEffect)(()=>{d.measure()},[d,e.resetKey]),(0,u.useEffect)(()=>()=>{l.current=null},[]),(0,u.useLayoutEffect)(()=>{d.setOptions({...d.options,count:e.count,getItemKey:e.getItemKey,estimateSize:e.estimateSize||(()=>Ne)}),d._willUpdate(),c({virtualItems:d.getVirtualItems(),totalSize:d.getTotalSize()})},[e.count,e.estimateSize,e.getItemKey,d]),{restoreAnchor:(e,t)=>{let n=d.getOffsetForIndex(e,`start`);n&&d.scrollToOffset(n[0]+t,{behavior:`auto`})},measureElement:e=>{e&&d.measureElement(e)},virtualItems:t,totalSize:s}}var Ie=64,Le=64;function Re({items:e,sessionKey:t,transcriptRef:n,virtual:r}){let i=(0,u.useRef)(new Map),a=(0,u.useRef)(!0),[o,s]=(0,u.useState)(!1),c=(0,u.useRef)({sessionKey:``,firstId:``}),l=(0,u.useRef)({items:e,virtual:r,sessionKey:t});l.current={items:e,virtual:r,sessionKey:t};let d=(0,u.useCallback)(()=>{a.current=!0,s(!1);let e=n.current;e&&(e.scrollTop=e.scrollHeight)},[n]);return(0,u.useLayoutEffect)(()=>{let e=n.current;if(!e)return;let t=()=>{let t=l.current,n=t.virtual.virtualItems.find(t=>t.end>e.scrollTop),r={itemId:n?t.items[n.index]?.itemId??null:null,offset:n?e.scrollTop-n.start:0,following:a.current};if(i.current.delete(t.sessionKey),i.current.set(t.sessionKey,r),i.current.size>Ie){let e=i.current.keys().next().value;e!==void 0&&i.current.delete(e)}},r=()=>{l.current.items.length&&(a.current=e.scrollHeight-e.scrollTop-e.clientHeight<=Le,s(!a.current),t())};return e.addEventListener(`scroll`,r,{passive:!0}),()=>e.removeEventListener(`scroll`,r)},[n]),(0,u.useLayoutEffect)(()=>{let o=n.current;if(!o)return;let l=e[0]?.itemId??``,u=c.current.sessionKey!==t,d=!u&&c.current.firstId!==l;c.current={sessionKey:t,firstId:l};let f=i.current.get(t);if(u&&(a.current=f?.following??!0,s(!a.current)),a.current){o.scrollTop=o.scrollHeight;return}if((u||d)&&f?.itemId){let t=e.findIndex(e=>e.itemId===f.itemId);t>=0&&r.restoreAnchor(t,f.offset)}},[e,t,n,r.totalSize]),{showJump:o,jumpToLatest:d}}var ze=2e3,$=80,Be=400;function Ve(e){return e<=ze?$:Math.min(Be,Math.round($*e/ze))}function He(e,t=!1,n=``){let[r,i]=(0,u.useState)({text:e,identity:n}),a=(0,u.useRef)(0),o=t||r.identity!==n||!e.startsWith(r.text);return(0,u.useEffect)(()=>{if(r.text===e&&r.identity===n)return;let t=()=>{a.current=Date.now(),i({text:e,identity:n})},s=Ve(e.length)-(Date.now()-a.current);if(o||s<=0){t();return}let c=window.setTimeout(t,s);return()=>window.clearTimeout(c)},[e,n,o,r]),o?e:r.text}var Ue=(0,u.lazy)(()=>t(()=>import(`./MarkdownRenderer-DyVx6DxM.js`).then(e=>({default:e.MarkdownRenderer})),__vite__mapDeps([0])));function We({item:e,identity:t,onOpenLocalFile:n}){let r=He(e.text??``,e.status!==`running`&&e.status!==`pending`,t);return r.trim()?(0,Z.jsx)(u.Suspense,{fallback:(0,Z.jsx)(`span`,{className:`code-plain-text`,children:r}),children:(0,Z.jsx)(Ue,{markdown:r,tableMode:`linear`,onLocalFileOpen:n})}):(0,Z.jsx)(`span`,{className:`code-plain-text`,children:r})}function Ge({item:e,provider:t,sessionKey:n,onOpenLocalFile:r}){let i=e.kind===`tool_call`||e.kind===`file_change`,a=e.kind===`reasoning`,o=e.kind===`assistant_message`,s=e.kind===`user_message`,c=Ee(e),l=s?`You`:o?X[t]:a?`Reasoning`:e.kind===`turn_started`?`Turn started`:e.kind===`session_runtime`?`Runtime`:e.kind===`permission_request`?`Permission record`:e.kind===`notice`?`Notice`:c;return(0,Z.jsxs)(`article`,{className:`code-message code-message-${i?`tool`:o?`assistant`:s?`user`:`system`} is-${e.status}`,"data-code-item-id":e.itemId,"aria-label":`${l} · ${c}`,children:[i?(0,Z.jsxs)(`details`,{className:`code-tool-card code-tool-${e.status}`,children:[(0,Z.jsxs)(`summary`,{className:`code-tool-summary`,children:[(0,Z.jsx)(`span`,{className:`code-tool-chevron`,"aria-hidden":`true`,children:`›`}),(0,Z.jsx)(`span`,{className:`code-tool-name`,children:e.tool?.name??(e.kind===`file_change`?`File change`:`Tool`)}),(0,Z.jsx)(`span`,{className:`code-tool-status`,children:c})]}),e.tool?.detail!==void 0&&(0,Z.jsx)(`p`,{className:`code-tool-text`,children:e.tool.detail}),e.tool?.input!==void 0&&(0,Z.jsxs)(`section`,{className:`code-tool-section`,children:[(0,Z.jsx)(`span`,{className:`code-tool-section-label`,children:`Input`}),(0,Z.jsx)(`pre`,{className:`code-tool-args`,children:e.tool.input})]}),e.tool?.output!==void 0&&(0,Z.jsxs)(`section`,{className:`code-tool-section`,children:[(0,Z.jsx)(`span`,{className:`code-tool-section-label`,children:`Output`}),(0,Z.jsx)(`pre`,{className:`code-tool-output`,children:e.tool.output})]}),e.text!==void 0&&(0,Z.jsx)(`pre`,{className:`code-tool-text`,children:e.text})]}):a?(0,Z.jsxs)(`details`,{className:`code-thinking`,children:[(0,Z.jsxs)(`summary`,{className:`code-thinking-summary`,children:[`Reasoning · `,c]}),(0,Z.jsx)(`div`,{className:`code-thinking-text`,children:e.text})]}):(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`span`,{className:`code-message-role`,children:[l,o&&e.phase&&e.phase!==`unknown`?` · ${e.phase===`final`?`Final`:`Commentary`}`:``,(o||s||e.kind===`permission_request`)&&` · ${c}`]}),(0,Z.jsx)(`div`,{className:`code-message-text`,children:o?(0,Z.jsx)(We,{item:e,identity:`${n}:${e.itemId}`,onOpenLocalFile:r}):(0,Z.jsx)(`span`,{className:`code-plain-text`,children:e.text??e.permission?.title??``})}),e.permission?.detail&&(0,Z.jsx)(`p`,{className:`code-plain-text`,children:e.permission.detail})]}),(o||a)&&(e.status===`cancelled`||e.status===`error`)&&(0,Z.jsxs)(`span`,{className:`code-partial-label`,children:[`Partial output · `,c]}),e.truncation&&(0,Z.jsxs)(`p`,{className:`code-truncation`,role:`note`,children:[`Output truncated: `,e.truncation.storedChars.toLocaleString(),` of `,e.truncation.sourceChars.toLocaleString(),` characters retained.`]})]})}function Ke({items:e,provider:t,sessionKey:n,workingDir:r,loading:i,hasOlderHistory:a,loadOlderHistory:o,permissionCount:s,onOpenLocalFile:c}){let l=(0,u.useRef)(null),d=(0,u.useRef)(e);d.current=e;let[f,p]=(0,u.useState)(!1),[m,h]=(0,u.useState)(null),g=(0,u.useRef)(!1),_=e[0]?.itemId,v=(0,u.useCallback)(e=>`${n}:${d.current[e]?.itemId??e}`,[n,_]),y=(0,u.useCallback)(e=>{let t=d.current[e];return t?.kind===`tool_call`||t?.kind===`reasoning`?64:64+Math.min(420,(t?.text?.length??0)/6)},[]),b=Fe({count:e.length,resetKey:n,scrollElementRef:l,getItemKey:v,estimateSize:y}),{showJump:x,jumpToLatest:S}=Re({items:e,sessionKey:n,transcriptRef:l,virtual:b});async function C(){if(!g.current){g.current=!0,p(!0),h(null);try{await o()}catch(e){h({sessionKey:n,message:e instanceof Error?e.message:String(e)})}finally{g.current=!1,p(!1)}}}function w(e){if(e.target!==e.currentTarget||e.altKey||e.ctrlKey||e.metaKey)return;let t=l.current;if(!t)return;let n=Math.max(160,t.clientHeight*.78);[`j`,`d`,`PageDown`].includes(e.key)?(e.preventDefault(),t.scrollBy({top:n,behavior:`auto`})):[`k`,`u`,`PageUp`].includes(e.key)?(e.preventDefault(),t.scrollBy({top:-n,behavior:`auto`})):e.key===`End`?(e.preventDefault(),S()):e.key===`Home`&&(e.preventDefault(),t.scrollTo({top:0,behavior:`auto`}))}return(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`div`,{className:`code-transcript-controls`,children:[a&&(0,Z.jsx)(`button`,{type:`button`,disabled:f||i,onClick:()=>void C(),children:f?`Loading history…`:`Load older history`}),x&&(0,Z.jsx)(`button`,{type:`button`,onClick:S,children:`Jump to latest`}),s>0&&(0,Z.jsxs)(`button`,{type:`button`,onClick:()=>document.getElementById(`code-pending-permissions`)?.focus(),children:[`Jump to permissions (`,s,`)`]}),m?.sessionKey===n&&(0,Z.jsx)(`span`,{className:`code-action-error`,role:`alert`,children:m.message})]}),(0,Z.jsx)(`div`,{ref:l,className:`code-transcript`,role:`log`,"aria-label":`Code transcript`,"aria-live":`off`,tabIndex:0,onKeyDown:w,children:e.length?(0,Z.jsx)(`div`,{className:`code-transcript-virtual-spacer`,style:{height:b.totalSize},children:b.virtualItems.map(r=>{let i=e[r.index];return i?(0,Z.jsx)(`div`,{ref:b.measureElement,className:`code-transcript-virtual-row`,"data-code-transcript-idx":r.index,style:{transform:`translateY(${r.start}px)`},children:(0,Z.jsx)(Ge,{item:i,provider:t,sessionKey:n,onOpenLocalFile:c})},r.key):null})}):(0,Z.jsxs)(`div`,{className:`code-transcript-empty`,children:[(0,Z.jsx)(`p`,{children:i?`Loading conversation…`:`Type a prompt below to start this conversation.`}),(0,Z.jsxs)(`p`,{className:`code-transcript-cwd`,children:[`Workspace: `,r||`not set`]})]})})]})}function qe({controller:e}){let[t,n]=(0,u.useState)(!1),[r,i]=(0,u.useState)(null),a=e.session?.cwd??e.selection.cwd,o=e.selectedId!==null||e.pending||e.creationUnknown||e.operation.kind!==`idle`;async function s(){if(!(o||t)){n(!0),i(null);try{await e.pickWorkspace()}catch(e){i(e instanceof Error?e.message:String(e))}finally{n(!1)}}}return(0,Z.jsxs)(`header`,{className:`code-workspace-header`,children:[(0,Z.jsxs)(`div`,{className:`code-session-header`,children:[(0,Z.jsx)(`span`,{className:`code-session-title`,children:e.session?.title||(e.selectedId?`Untitled session`:`New session draft`)}),(0,Z.jsx)(`span`,{children:X[e.session?.provider??e.selection.provider]}),(0,Z.jsxs)(`span`,{role:`status`,children:[e.session?Ce[e.session.status]:e.creationUnknown?`Creation unconfirmed`:e.operation.kind===`creating`?`Creating session`:`Draft`,e.session?.archivedAt!==null&&e.session?` · Archived`:``]})]}),(0,Z.jsxs)(`div`,{className:`code-workspace-primary`,children:[o?(0,Z.jsx)(`span`,{className:`code-workspace-chip`,title:a,children:a||`Workspace not set`}):(0,Z.jsx)(`button`,{type:`button`,className:`code-workspace-picker`,"aria-label":`Choose Code workspace`,disabled:t,title:a||`Choose a folder`,onClick:()=>void s(),children:(0,Z.jsx)(`span`,{className:`code-workspace-picker-label`,children:t?`Choosing folder…`:a||`Choose workspace`})}),e.gitInfo?.isRepo&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`span`,{className:`code-workspace-pill`,children:[e.gitInfo.branch??`detached`,e.gitInfo.head?` · ${e.gitInfo.head}`:``]}),e.gitInfo.status&&(0,Z.jsx)(`span`,{className:`code-workspace-pill${e.gitInfo.status.dirty?` is-dirty`:``}`,children:e.gitInfo.status.dirty?`${e.gitInfo.status.changed} changed · ${e.gitInfo.status.untracked} untracked`:`clean`})]}),r&&(0,Z.jsx)(`span`,{className:`code-action-error`,role:`alert`,children:r})]})]})}function Je({controller:e,endpointKey:t,onOpenLocalFile:n}){let r=`${t}:${e.selectedId??`new`}`,[i,a]=(0,u.useState)(null),[o,s]=(0,u.useState)(null),c=(0,u.useRef)(new Set),l=e.session?.archivedAt!=null,d=e.session?.status===`stopping`||e.operation.kind===`stopping`,f=e.busy||d||e.session?.status===`starting`||e.session?.status===`streaming`,p=e.catalog?.providers.find(t=>t.id===e.selection.provider),m=e.operation.kind===`unknown-send`,h=!f&&!e.pending&&!e.creationUnknown&&!l&&e.operation.kind===`idle`&&!!p?.available&&!!e.selection.cwd.trim()&&!!e.selection.model.trim()&&(e.selectedId===null||e.synced&&e.session?.status===`idle`),g=!!e.session?.turnId&&e.session.capabilities.interrupt&&f&&!d,_=!!e.session&&Te(e.session)&&e.synced&&!e.pending&&!m,v=e.operation.error||e.error||(i?.key===r?i.message:null),y=[...e.items].reverse().find(e=>e.kind===`turn_cancelled`||e.kind===`turn_failed`||e.kind===`turn_completed`),b=y&&y.kind!==`turn_completed`?e.items.find(e=>e.kind===`user_message`&&e.turnId===y.turnId)?.text:void 0;function x(e){a(null),e().catch(e=>a({key:r,message:e instanceof Error?e.message:String(e)}))}async function S(){if(e.canRetrySameSend&&!c.current.has(r)){c.current.add(r),s(r),a(null);try{await e.retrySameSend()}catch(e){a({key:r,message:e instanceof Error?e.message:String(e)})}finally{c.current.delete(r),s(e=>e===r?null:e)}}}return(0,Z.jsxs)(`div`,{className:`code-canvas-main`,children:[(0,Z.jsx)(qe,{controller:e},r),(e.transport!==`connected`||e.selectedId!==null&&!e.synced)&&(0,Z.jsxs)(`section`,{className:`code-transport-status is-${e.transport}`,role:`status`,children:[e.transport===`reconnecting`?`Live updates reconnecting. History may be out of date.`:e.transport===`disconnected`?`Live updates disconnected. History may be out of date.`:`Updating conversation…`,(0,Z.jsx)(`button`,{type:`button`,onClick:()=>x(e.refresh),children:`Refresh`})]}),v&&(0,Z.jsxs)(`section`,{className:`code-recovery-strip`,role:`alert`,children:[(0,Z.jsx)(`p`,{children:v}),(0,Z.jsx)(`button`,{type:`button`,onClick:()=>x(e.refresh),children:`Refresh session`}),(0,Z.jsx)(`button`,{type:`button`,onClick:()=>{e.clearError(),a(null)},children:`Dismiss`})]}),e.creationUnknown&&(0,Z.jsxs)(`section`,{className:`code-recovery-strip`,"aria-label":`Unconfirmed session creation`,children:[(0,Z.jsx)(`strong`,{children:`Session creation not confirmed`}),(0,Z.jsx)(`p`,{children:`The original session may still exist.`}),(0,Z.jsx)(`p`,{children:`Your draft and choices are kept. Press Send when you are ready to create another session.`}),(0,Z.jsx)(`button`,{type:`button`,onClick:e.startAnotherSession,children:`Start another session`})]}),m&&(0,Z.jsxs)(`section`,{className:`code-recovery-strip`,"aria-label":`Unconfirmed send`,children:[(0,Z.jsx)(`strong`,{children:`Send outcome not confirmed`}),(0,Z.jsx)(`p`,{children:`Retry uses the original request. It may submit it if the server has not already accepted it.`}),(0,Z.jsx)(`pre`,{className:`code-retry-preview`,"aria-label":`Original prompt`,children:e.retryText}),(0,Z.jsx)(`button`,{type:`button`,disabled:!e.canRetrySameSend||o===r,onClick:()=>void S(),children:o===r?`Retrying original send…`:`Retry same send`})]}),l?(0,Z.jsxs)(`section`,{className:`code-recovery-strip`,children:[(0,Z.jsx)(`span`,{children:`Archived · Read-only history`}),(0,Z.jsx)(`button`,{type:`button`,disabled:!e.synced||e.pending,onClick:()=>{let t=e.selectedId;t&&x(()=>e.archive(t,!1))},children:`Restore session`})]}):e.session&&(e.session.status===`failed`||e.session.status===`suspended`)&&(0,Z.jsxs)(`section`,{className:`code-recovery-strip`,role:`status`,children:[(0,Z.jsx)(`p`,{children:e.session.error?.message??`Native session suspended.`}),_?(0,Z.jsx)(`button`,{type:`button`,onClick:()=>x(e.resume),children:`Resume session`}):(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`span`,{children:e.session.resume.reason??`Resume is not currently available.`}),(0,Z.jsx)(`button`,{type:`button`,onClick:e.newSession,children:`New session`})]})]}),(0,Z.jsx)(Ke,{items:e.items,provider:e.session?.provider??e.selection.provider,sessionKey:r,workingDir:e.session?.cwd??e.selection.cwd,loading:e.loading,hasOlderHistory:e.hasOlderHistory,loadOlderHistory:e.loadOlderHistory,permissionCount:e.permissions.length,onOpenLocalFile:n}),(0,Z.jsx)(Me,{permissions:e.permissions,operations:e.permissionOperations,session:e.session,synced:e.synced,onAnswer:e.answer}),(0,Z.jsxs)(`div`,{className:`code-composer-dock`,children:[b!==void 0&&!f&&!l&&(0,Z.jsxs)(`div`,{className:`code-input-recovery`,children:[(0,Z.jsx)(`button`,{type:`button`,disabled:!!e.input||m,title:e.input?`Keep or clear your current draft before restoring the submitted prompt`:void 0,onClick:()=>e.setInput(b),children:`Restore submitted prompt`}),(0,Z.jsx)(`span`,{children:`Restores text for editing without sending.`})]}),(0,Z.jsxs)(`div`,{className:`code-composer-surface`,"aria-label":`Code composer controls`,children:[(0,Z.jsx)(ke,{inputText:e.input,canSend:h,busy:f,canStop:g,stopping:d,pending:e.pending,readOnly:l,onInputChange:e.setInput,onSubmit:e.send,onStop:e.stop},`composer:${r}`),(0,Z.jsx)(Ae,{controller:e},`footer:${r}`)]})]})]})}function Ye({port:e,workingDir:t,onWorkingDirChange:n,onOpenLocalFile:r}){let i=be({port:e,workingDir:t}),[a,o]=(0,u.useState)(null),s=(0,u.useRef)({port:e,id:i.selectedId,cwd:i.selection.cwd});(0,u.useEffect)(()=>{o(document.getElementById(`code-session-sidebar-host`))},[]),(0,u.useEffect)(()=>{let t=s.current,r={port:e,id:i.selectedId,cwd:i.selection.cwd};s.current=r,t.port===e&&t.id===null&&r.id===null&&t.cwd!==r.cwd&&n?.(r.cwd||null)},[e,i.selectedId,i.selection.cwd,n]);let c=(0,Z.jsx)(Oe,{controller:i},e),l=(0,Z.jsx)(Je,{controller:i,endpointKey:String(e),onOpenLocalFile:r},e);return a?(0,Z.jsxs)(Z.Fragment,{children:[(0,d.createPortal)((0,Z.jsx)(`div`,{className:`code-manager-session-navigator-content`,children:c}),a),(0,Z.jsx)(`div`,{className:`code-canvas code-canvas-workbench`,children:l})]}):(0,Z.jsxs)(`div`,{className:`code-canvas`,children:[(0,Z.jsx)(`div`,{className:`code-canvas-sidebar`,children:c}),l]})}export{Ye as CodeCanvas};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-C_pPTFsM.js";import{t as n}from"./jsx-runtime-NZYk81nU.js";import{a as r,i,n as a,t as o}from"./page-shell-BeGD0rRQ.js";import{a as s,s as c}from"./fields-mlGpofqQ.js";var l=e(t(),1),u=n();function d(){return{async get(e){let t=await fetch(e);if(!t.ok)throw Error(`GET ${e} → ${t.status}`);return await t.json()},async patch(e,t){let n=await fetch(e,{method:`PATCH`,headers:{"content-type":`application/json`},body:JSON.stringify(t)});if(!n.ok)throw Error(`PATCH ${e} → ${n.status}`);return await n.json()}}}var f=[`meta.label`,`meta.group`,`meta.favorite`,`meta.hidden`,`meta.notes`];function p(e,t){let n=e?.registry?.instances?.[String(t)];return{label:n?.label??null,favorite:n?.favorite===!0,group:n?.group??null,hidden:n?.hidden===!0,notes:n?.notes??null}}function m(e){return{label:e.label||``,group:e.group||``,favorite:e.favorite,hidden:e.hidden,notes:e.notes||``}}function h({port:e,client:t,dirty:n,registerSave:h,managerClient:g}){let{state:_,refresh:v,setData:y}=r(t,`__dashboard_meta_unused__`,[e]),[b,x]=(0,l.useState)(null),[S,C]=(0,l.useState)(null),[w,T]=(0,l.useState)({label:``,group:``,favorite:!1,hidden:!1,notes:``}),E=g||d();(0,l.useEffect)(()=>{let t=!1;return C(null),E.get(`/api/dashboard/registry`).then(n=>{t||(x(n),T(m(p(n,e))))}).catch(e=>{t||C(e instanceof Error?e.message:String(e))}),()=>{t=!0}},[e]),(0,l.useEffect)(()=>()=>{for(let e of f)n.remove(e)},[n]);let D=p(b,e),O=(0,l.useCallback)((e,t)=>n.set(e,t),[n]),k=(0,l.useCallback)(async()=>{let t=w.label.trim()||null,r=w.group.trim()||null,i=w.notes.trim()||null,a={instances:{[String(e)]:{label:t,group:r,favorite:w.favorite,hidden:w.hidden,notes:i}}},o=await E.patch(`/api/dashboard/registry`,a);x(o),T(m(p(o,e)));for(let e of f)n.remove(e)},[w,E,n,e]);return(0,l.useEffect)(()=>{if(h)return h(k),()=>h(null)},[h,k]),S?(0,u.jsx)(o,{message:S}):b?(0,u.jsx)(`form`,{className:`settings-page-form settings-form`,onSubmit:e=>{e.preventDefault(),k()},children:(0,u.jsxs)(i,{title:`Dashboard meta`,hint:`Manager-side metadata for this instance. Stored in the dashboard registry.`,children:[(0,u.jsx)(c,{id:`dashmeta-label`,label:`Label`,value:w.label,placeholder:`(unset — falls back to home folder name)`,onChange:e=>{T({...w,label:e}),O(`meta.label`,{value:e,original:D.label||``,valid:!0})}}),(0,u.jsx)(c,{id:`dashmeta-group`,label:`Group`,value:w.group,placeholder:`e.g. work, personal`,onChange:e=>{T({...w,group:e}),O(`meta.group`,{value:e,original:D.group||``,valid:!0})}}),(0,u.jsx)(s,{id:`dashmeta-favorite`,label:`Pin favorite`,value:w.favorite,onChange:e=>{T({...w,favorite:e}),O(`meta.favorite`,{value:e,original:D.favorite,valid:!0})}}),(0,u.jsx)(s,{id:`dashmeta-hidden`,label:`Hide by default`,description:`Hide from the default instance list.`,value:w.hidden,onChange:e=>{T({...w,hidden:e}),O(`meta.hidden`,{value:e,original:D.hidden,valid:!0})}}),(0,u.jsxs)(`label`,{className:`settings-field`,htmlFor:`dashmeta-notes`,children:[(0,u.jsx)(`span`,{className:`settings-field-label`,children:`Notes`}),(0,u.jsx)(`textarea`,{id:`dashmeta-notes`,rows:4,value:w.notes,placeholder:`Free-form notes only the dashboard remembers.`,onChange:e=>{let t=e.target.value;T({...w,notes:t}),O(`meta.notes`,{value:t,original:D.notes||``,valid:!0})}})]})]})}):(0,u.jsx)(a,{label:`Loading dashboard registry…`})}var g={readInstance:p,toDraft:m,META_KEYS:f};export{g as __test__,h as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./jsx-runtime-NZYk81nU.js";import{a as t,c as n,i as r,n as i,r as a,s as o,t as s}from"./shared-BI-LEt7g.js";import{i as c,n as l}from"./manager-shortcuts-CzGkE0ZG.js";var u=e();function d({manager:e}){if(!e)return null;let d=e,f=o(d.ui.locale),p=s[f];function m(e,t){d.onUiPatch({dashboardShortcutKeymap:{...d.ui.dashboardShortcutKeymap,[e]:t}})}return(0,u.jsxs)(`section`,{className:`dashboard-settings-section`,children:[(0,u.jsxs)(`header`,{children:[(0,u.jsx)(`h3`,{children:p.displayTitle}),(0,u.jsx)(`p`,{children:p.displayDescription})]}),(0,u.jsxs)(`div`,{className:`dashboard-settings-field-list`,children:[(0,u.jsx)(a,{id:`dashboard-show-activity-title`,label:p.fields.activity.label,scope:p.fields.activity.scope,value:d.ui.showLatestActivityTitles,description:p.fields.activity.description,onChange:e=>d.onUiPatch({showLatestActivityTitles:e})}),(0,u.jsx)(a,{id:`dashboard-show-label-editor`,label:p.fields.rename.label,scope:p.fields.rename.scope,value:d.ui.showInlineLabelEditor,description:p.fields.rename.description,onChange:e=>d.onUiPatch({showInlineLabelEditor:e})}),(0,u.jsx)(a,{id:`dashboard-show-runtime-line`,label:p.fields.runtime.label,scope:p.fields.runtime.scope,value:d.ui.showSidebarRuntimeLine,description:p.fields.runtime.description,onChange:e=>d.onUiPatch({showSidebarRuntimeLine:e})}),(0,u.jsx)(a,{id:`dashboard-show-row-actions`,label:p.fields.actions.label,scope:p.fields.actions.scope,value:d.ui.showSelectedRowActions,description:p.fields.actions.description,onChange:e=>d.onUiPatch({showSelectedRowActions:e})}),(0,u.jsx)(i,{id:`dashboard-locale`,label:p.fields.language.label,scope:p.fields.language.scope,value:f,options:t,description:p.fields.language.description,onChange:e=>d.onUiPatch({locale:e})}),(0,u.jsx)(a,{id:`dashboard-shortcuts-enabled`,label:p.fields.shortcuts.label,scope:p.fields.shortcuts.scope,value:d.ui.dashboardShortcutsEnabled,description:p.fields.shortcuts.description,onChange:e=>d.onUiPatch({dashboardShortcutsEnabled:e})}),l.map(e=>{let t=p.fields[n(e)];return(0,u.jsx)(r,{action:e,label:t.label,scope:t.scope,value:d.ui.dashboardShortcutKeymap[e],description:`${t.description} Current: ${c(d.ui.dashboardShortcutKeymap[e])}`,onChange:m},e)})]})]})}export{d as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-C_pPTFsM.js";import{t as n}from"./jsx-runtime-NZYk81nU.js";import{a as r,i,n as a,r as o,t as s}from"./page-shell-BeGD0rRQ.js";import{i as c,n as l}from"./fields-mlGpofqQ.js";import{t as u}from"./InlineWarn-DIMbcbzk.js";var d=e(t(),1),f=n(),p=/^[a-zA-Z0-9._:*-]+$/,m=[`bash`,`read`,`write`,`edit`,`mcp.*`];function h(e){return e===`auto`?`Auto (YOLO)`:e===`safe`?`Safe`:e==null?`Not provided`:Array.isArray(e)&&e.every(e=>typeof e==`string`)?`Custom (${e.length} ${e.length===1?`entry`:`entries`})`:`Unrecognized`}function g(e){return e===`auto`}function _(e){return g(e)?{mode:`auto`}:Array.isArray(e)?{mode:`custom`,tokens:e.filter(e=>typeof e==`string`).map(e=>e.trim()).filter(e=>e.length>0)}:{mode:`unknown`}}function v(e){return typeof e!=`string`||e.length===0||e.length>64?!1:p.test(e)}function y(e){return Array.isArray(e)&&e.length>0?Array.from(new Set(e.filter(v))):[...m]}function b(e){return e.length!==0&&e.every(v)}var x=[{value:`auto`,label:`Auto (YOLO)`},{value:`custom`,label:`Custom — explicit allowlist below`}];function S({port:e,client:t,dirty:n,registerSave:p}){let{state:m,refresh:g,setData:S}=r(t,`/api/settings`),[C,w]=(0,d.useState)(`auto`),[T,E]=(0,d.useState)([]),D=(0,d.useMemo)(()=>m.kind===`ready`?_(m.data.permissions):null,[m]);(0,d.useEffect)(()=>{if(m.kind!==`ready`)return;let e=_(m.data.permissions);e.mode===`custom`?(w(`custom`),E(e.tokens)):(w(`auto`),E([]))},[m]),(0,d.useEffect)(()=>()=>{n.remove(`permissions`)},[n]);let O=(0,d.useCallback)(e=>n.set(`permissions`,e),[n]),k=(0,d.useMemo)(()=>D&&D.mode===`custom`?D.tokens:`auto`,[D]),A=(0,d.useCallback)(e=>{if(e===`auto`){w(`auto`),E([]),O({value:`auto`,original:k,valid:!0});return}if(e===`custom`){w(`custom`);let e=D&&D.mode===`custom`&&D.tokens.length>0?[...D.tokens]:y(null);E(e),O({value:e,original:k,valid:b(e)})}},[D,k,O]),j=(0,d.useCallback)(e=>{let t=e.map(e=>e.trim()).filter(e=>e.length>0);E(t),O({value:t,original:k,valid:b(t)})},[k,O]),M=(0,d.useCallback)(async()=>{let e=n.saveBundle();if(Object.keys(e).length===0)return;let r=await t.put(`/api/settings`,e),i=r&&typeof r==`object`&&`data`in r?r.data:r;n.clear();let a=_(i.permissions);a.mode===`custom`?(w(`custom`),E(a.tokens)):(w(`auto`),E([])),S(i),await g()},[t,n,g,S]);if((0,d.useEffect)(()=>{if(p)return p(M),()=>p(null)},[p,M]),m.kind===`loading`)return(0,f.jsx)(a,{});if(m.kind===`offline`)return(0,f.jsx)(o,{port:e});if(m.kind===`error`)return(0,f.jsx)(s,{message:m.message});let N=T.filter(e=>!v(e)),P=N.length>0,F=C===`custom`&&T.length===0,I=h(m.data.permissions);return(0,f.jsxs)(`form`,{className:`settings-page-form`,onSubmit:e=>e.preventDefault(),children:[(0,f.jsxs)(i,{title:`Permissions`,hint:`Selecting a value changes the draft. Save applies it. Auto (YOLO) requests automatic approval or permission bypass. Behavior varies by runtime.`,children:[(0,f.jsx)(c,{id:`permissions-mode`,label:`Change policy to`,value:C,options:x,onChange:A}),C===`custom`&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(l,{id:`permissions-allowlist`,label:`Allowlist`,value:T,onChange:j,placeholder:`bash, read, mcp.*`,error:P?`Invalid token${N.length===1?``:`s`}: ${N.join(`, `)}`:F?`Allowlist cannot be empty in Custom mode.`:null}),(0,f.jsxs)(`p`,{className:`settings-section-hint`,children:[`Each chip is a permission token. Examples: `,(0,f.jsx)(`code`,{children:`bash`}),`,`,(0,f.jsx)(`code`,{children:` read`}),`, `,(0,f.jsx)(`code`,{children:` write`}),`, `,(0,f.jsx)(`code`,{children:` mcp.*`}),`.`]}),F&&(0,f.jsx)(u,{role:`alert`,children:`An empty Custom allowlist cannot be saved. Add at least one token or switch back to Auto (YOLO).`})]})]}),(0,f.jsxs)(i,{title:`Saved policy`,hint:`Shows the saved permission policy.`,children:[(0,f.jsxs)(`p`,{className:`settings-readonly-line`,children:[(0,f.jsx)(`span`,{className:`settings-field-label`,children:`Configured policy:`}),` `,(0,f.jsx)(`span`,{children:I})]}),D?.mode===`unknown`?(0,f.jsx)(`p`,{className:`settings-section-hint`,children:`Use Agent to change this configured policy.`}):null]})]})}export{g as a,v as i,h as n,_ as o,b as r,y as s,S as t};
|