claude-code-session-manager 0.109.0 → 0.111.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{AgentLibrary-Br4Ispr4.js → AgentLibrary-rBO1daqM.js} +1 -1
- package/dist/assets/{Button-C8Mc6MEP.js → Button-DsEYRZg0.js} +1 -1
- package/dist/assets/{DataModel-Bz0MypYO.js → DataModel-D8sbvvBC.js} +1 -1
- package/dist/assets/{History-DT26Iy38.js → History-BEHLtxia.js} +1 -1
- package/dist/assets/{Hooks-e4xUGEf-.js → Hooks-CKpvlXrg.js} +3 -3
- package/dist/assets/{Library-B3rzEhvN.js → Library-CeF4qh9d.js} +1 -1
- package/dist/assets/{ListDetail-BAvci_aP.js → ListDetail-DcfmxPFk.js} +1 -1
- package/dist/assets/{MarkdownEditor-DBWTGgRz.js → MarkdownEditor-CvK1pyto.js} +1 -1
- package/dist/assets/{McpServers-C-grBN21.js → McpServers-D-h2ihzJ.js} +2 -2
- package/dist/assets/{Memory-BmM0Fz-C.js → Memory-BnF89x8v.js} +1 -1
- package/dist/assets/{Panel-Dc6F8wb4.js → Panel-CQY5zano.js} +1 -1
- package/dist/assets/{Permissions-m_NnldFh.js → Permissions-DLukmmsz.js} +3 -3
- package/dist/assets/{Plugins-BB0TLUC9.js → Plugins-0Pf0OZ4l.js} +2 -2
- package/dist/assets/{ProvenanceBadge-k9PH0S2n.js → ProvenanceBadge-vC7Tj-JP.js} +1 -1
- package/dist/assets/RemoteMachines-CWnKbFHc.js +3 -0
- package/dist/assets/{SaveBar-DSMnbUVI.js → SaveBar-DjijiUb0.js} +1 -1
- package/dist/assets/{Scheduler-CbIcJEfM.js → Scheduler-Cm3EXZvE.js} +7 -7
- package/dist/assets/{ScopeSwitcher-tHtloWbN.js → ScopeSwitcher-B-P-kSfq.js} +1 -1
- package/dist/assets/Settings-DYDlp2m_.js +4 -0
- package/dist/assets/{SkillReferenceGraph-Dndl1tzr.js → SkillReferenceGraph-Epv2GJmj.js} +1 -1
- package/dist/assets/{Skills-CGnxroik.js → Skills-DHO0N0C2.js} +1 -1
- package/dist/assets/{SystemPrompt-B3A3rHNp.js → SystemPrompt-DxeNofL9.js} +1 -1
- package/dist/assets/{TagLibrary-k4CTiAYo.js → TagLibrary-QOAs7ISO.js} +1 -1
- package/dist/assets/{TiptapBody-C2LfNQXw.js → TiptapBody-DAMO3DhO.js} +1 -1
- package/dist/assets/{Toggle-CTXTU1q5.js → Toggle-Ba_f7q_m.js} +1 -1
- package/dist/assets/{ViewTabs-CfEfOSE1.js → ViewTabs-CGX6MAhc.js} +1 -1
- package/dist/assets/{historyTotals-Db0xy2Fg.js → historyTotals-vgfk8EOL.js} +1 -1
- package/dist/assets/index-CPieAFsl.js +3078 -0
- package/dist/assets/{index-C8Smiz7z.css → index-Dutcsly-.css} +1 -1
- package/dist/assets/{settingsSchema-xxO9p4yF.js → settingsSchema-D0FxNrTy.js} +1 -1
- package/dist/assets/{useAgentsDirWatch-DLS1_moj.js → useAgentsDirWatch-DCu6BNYN.js} +1 -1
- package/dist/assets/useRemotePeers-D4cdJDyh.js +1 -0
- package/dist/index.html +2 -2
- package/package.json +2 -1
- package/plugins/session-manager-dev/skills/develop/SKILL.md +3 -1
- package/plugins/session-manager-dev/skills/send-feedback/SKILL.md +48 -15
- package/scripts/scheduler-mcp-server.cjs +29 -2
- package/src/main/build-info.json +4 -4
- package/src/main/chatRunner.cjs +7 -0
- package/src/main/index.cjs +6 -0
- package/src/main/ipcSchemas.cjs +28 -0
- package/src/main/lib/autoUpdater.cjs +190 -0
- package/src/main/lib/builtinMacros.cjs +2 -2
- package/src/main/lib/crossProjectFeedback.cjs +143 -6
- package/src/main/lib/mcpToolCatalog.cjs +12 -3
- package/src/main/lib/reaperHelpers.cjs +13 -1
- package/src/main/lib/relayClientAuth.cjs +133 -0
- package/src/main/lib/remoteClientSessions.cjs +84 -0
- package/src/main/lib/shippedPersonaSeeds.cjs +11 -0
- package/src/main/lib/updaterSettings.cjs +64 -0
- package/src/main/remoteClient.cjs +42 -13
- package/src/main/remoteClientIpc.cjs +33 -1
- package/src/main/scheduler.cjs +16 -0
- package/src/main/updaterIpc.cjs +110 -0
- package/src/main/webRemote.cjs +276 -132
- package/src/preload/api.d.ts +55 -2
- package/src/preload/index.cjs +24 -1
- package/src/seed/agents/demo-video-builder.md +62 -19
- package/dist/assets/Settings-CW3w7knp.js +0 -6
- package/dist/assets/index-fJxuoRvi.js +0 -3077
package/src/preload/api.d.ts
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import type { PromptSession } from '../renderer/state/promptSessions';
|
|
2
2
|
|
|
3
3
|
/** Mirrors the item shape returned by main/lib/prereqs.cjs checkPrereqs(). */
|
|
4
|
+
export type AutoUpdaterState =
|
|
5
|
+
| 'unsupported' | 'disabled' | 'idle' | 'checking'
|
|
6
|
+
| 'downloading' | 'ready' | 'deferred' | 'error';
|
|
7
|
+
|
|
8
|
+
export type AutoUpdaterStatus = {
|
|
9
|
+
state: AutoUpdaterState;
|
|
10
|
+
current: string;
|
|
11
|
+
latest: string | null;
|
|
12
|
+
progress: number | null;
|
|
13
|
+
error: string | null;
|
|
14
|
+
busyReason: string | null;
|
|
15
|
+
lastCheckedAt: number | null;
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
4
19
|
export interface PrereqItem {
|
|
5
20
|
id: string;
|
|
6
21
|
label: string;
|
|
@@ -1601,11 +1616,22 @@ export interface RemoteMachinePeer {
|
|
|
1601
1616
|
pairedAt: string;
|
|
1602
1617
|
clientPublicKey: string;
|
|
1603
1618
|
verifiedDevicePubKey: string | null;
|
|
1619
|
+
/** process.platform of the remote machine, last known (null until first authenticated). */
|
|
1620
|
+
os: string | null;
|
|
1604
1621
|
status: string;
|
|
1605
1622
|
reason: string | null;
|
|
1606
1623
|
sas: string | null;
|
|
1607
1624
|
}
|
|
1608
1625
|
|
|
1626
|
+
export interface RemoteClientDevice {
|
|
1627
|
+
deviceId: string;
|
|
1628
|
+
email: string;
|
|
1629
|
+
issuedAt: string;
|
|
1630
|
+
expiresAt: string;
|
|
1631
|
+
isOnline: boolean;
|
|
1632
|
+
devicePubKey: string;
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1609
1635
|
export interface RemoteClientStatus {
|
|
1610
1636
|
peerId: string;
|
|
1611
1637
|
status: string;
|
|
@@ -1630,9 +1656,18 @@ export interface WebRemoteStatus {
|
|
|
1630
1656
|
e2eState: 'idle' | 'pending_sas' | 'authenticated' | 'failed';
|
|
1631
1657
|
/** 6-digit Short Authentication String pending user confirmation, or null. */
|
|
1632
1658
|
pendingSas: string | null;
|
|
1659
|
+
/** Every connected client's E2E state (no key material). */
|
|
1660
|
+
clients: WebRemoteClientStatus[];
|
|
1633
1661
|
devices: WebRemoteDevice[];
|
|
1634
1662
|
}
|
|
1635
1663
|
|
|
1664
|
+
export interface WebRemoteClientStatus {
|
|
1665
|
+
key: string;
|
|
1666
|
+
clientId: string | null;
|
|
1667
|
+
state: 'idle' | 'pending_sas' | 'authenticated' | 'failed';
|
|
1668
|
+
pendingSas: string | null;
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1636
1671
|
export interface WebRemotePairResult {
|
|
1637
1672
|
ok: boolean;
|
|
1638
1673
|
deviceId?: string;
|
|
@@ -2144,10 +2179,23 @@ export interface SessionManagerAPI {
|
|
|
2144
2179
|
connect: (peerId: string) => Promise<{ status: string; reason: string | null; sas: string | null }>;
|
|
2145
2180
|
confirmSas: (peerId: string) => Promise<{ ok: boolean; reason?: string }>;
|
|
2146
2181
|
remove: (peerId: string) => Promise<{ ok: boolean }>;
|
|
2182
|
+
authStatus: () => Promise<{ paired: boolean; clientId: string | null }>;
|
|
2183
|
+
pair: (code: string, clientName?: string) => Promise<{ ok: boolean; clientId?: string; error?: string }>;
|
|
2184
|
+
unpair: () => Promise<{ ok: boolean }>;
|
|
2185
|
+
devices: () => Promise<{ ok: boolean; devices?: RemoteClientDevice[]; error?: string }>;
|
|
2186
|
+
add: (deviceId: string, machineName: string) => Promise<RemoteMachinePeer>;
|
|
2147
2187
|
send: (peerId: string, type: string, payload?: unknown) => Promise<unknown>;
|
|
2148
2188
|
onStatus: (handler: (status: RemoteClientStatus) => void) => () => void;
|
|
2149
2189
|
onEvent: (handler: (ev: RemoteClientEvent) => void) => () => void;
|
|
2150
2190
|
};
|
|
2191
|
+
updater: {
|
|
2192
|
+
status: () => Promise<AutoUpdaterStatus>;
|
|
2193
|
+
check: () => Promise<AutoUpdaterStatus>;
|
|
2194
|
+
install: (force?: boolean) => Promise<{ ok: boolean; error?: string }>;
|
|
2195
|
+
cancelDeferred: () => Promise<AutoUpdaterStatus>;
|
|
2196
|
+
setEnabled: (enabled: boolean) => Promise<AutoUpdaterStatus>;
|
|
2197
|
+
onStatus: (handler: (status: AutoUpdaterStatus) => void) => () => void;
|
|
2198
|
+
};
|
|
2151
2199
|
webRemote: {
|
|
2152
2200
|
getStatus: () => Promise<WebRemoteStatus>;
|
|
2153
2201
|
enable: () => Promise<WebRemoteMutationResult>;
|
|
@@ -2166,8 +2214,9 @@ export interface SessionManagerAPI {
|
|
|
2166
2214
|
/** Subscribe to the completion event broadcast after revokeAll. */
|
|
2167
2215
|
onRevokedAll: (handler: (ev: { revokedCount: number }) => void) => () => void;
|
|
2168
2216
|
/** Confirm that the SAS shown on the desktop matches the browser — marks the
|
|
2169
|
-
* E2E session as authenticated and unblocks MUTATE-tier commands.
|
|
2170
|
-
|
|
2217
|
+
* E2E session as authenticated and unblocks MUTATE-tier commands. Pass the
|
|
2218
|
+
* client's `key` when several clients are pending (else `ambiguous_pending_sas`). */
|
|
2219
|
+
confirmSas: (clientKey?: string) => Promise<WebRemoteMutationResult>;
|
|
2171
2220
|
};
|
|
2172
2221
|
chat: {
|
|
2173
2222
|
/** Spawn a headless `claude -p` run for a tab. Results arrive via the on* listeners. */
|
|
@@ -2187,6 +2236,10 @@ export interface SessionManagerAPI {
|
|
|
2187
2236
|
* tool) pushes a prompt into an open tab's queue from outside the
|
|
2188
2237
|
* renderer (PRD 753). */
|
|
2189
2238
|
onExternalSend: (handler: (e: ChatExternalSendEvent) => void) => () => void;
|
|
2239
|
+
/** Fires when a paired phone asks main to start a new Session (payload pre-validated in main). */
|
|
2240
|
+
onExternalNewSession: (
|
|
2241
|
+
handler: (e: { cwd: string; agentName: string; tag: AgentPersonaTag; title: string; prompt: string }) => void,
|
|
2242
|
+
) => () => void;
|
|
2190
2243
|
/** Classify a queued PromptTicket's text as 'inline' (run through
|
|
2191
2244
|
* chatRunner) or 'develop' (dispatch to /develop for PRD decomposition).
|
|
2192
2245
|
* A single bounded `claude -p` call, never a scheduler job. */
|
package/src/preload/index.cjs
CHANGED
|
@@ -405,6 +405,11 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
405
405
|
/** Confirm the short authentication string matches the remote machine. */
|
|
406
406
|
confirmSas: (peerId) => ipcRenderer.invoke('remoteClient:confirm-sas', { peerId }),
|
|
407
407
|
remove: (peerId) => ipcRenderer.invoke('remoteClient:remove', { peerId }),
|
|
408
|
+
authStatus: () => ipcRenderer.invoke('remoteClient:auth-status'),
|
|
409
|
+
pair: (code, clientName) => ipcRenderer.invoke('remoteClient:pair', { code, clientName }),
|
|
410
|
+
unpair: () => ipcRenderer.invoke('remoteClient:unpair'),
|
|
411
|
+
devices: () => ipcRenderer.invoke('remoteClient:devices'),
|
|
412
|
+
add: (deviceId, machineName) => ipcRenderer.invoke('remoteClient:add', { deviceId, machineName }),
|
|
408
413
|
send: (peerId, type, payload) => ipcRenderer.invoke('remoteClient:send', { peerId, type, payload }),
|
|
409
414
|
onStatus: (handler) => {
|
|
410
415
|
const listener = (_e, payload) => handler(payload);
|
|
@@ -417,6 +422,18 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
417
422
|
return () => ipcRenderer.removeListener('remoteClient:event', listener);
|
|
418
423
|
},
|
|
419
424
|
},
|
|
425
|
+
updater: {
|
|
426
|
+
status: () => ipcRenderer.invoke('updater:status'),
|
|
427
|
+
check: () => ipcRenderer.invoke('updater:check'),
|
|
428
|
+
install: (force) => ipcRenderer.invoke('updater:install', { force: force === true }),
|
|
429
|
+
cancelDeferred: () => ipcRenderer.invoke('updater:cancel-deferred'),
|
|
430
|
+
setEnabled: (enabled) => ipcRenderer.invoke('updater:set-enabled', { enabled }),
|
|
431
|
+
onStatus: (handler) => {
|
|
432
|
+
const listener = (_e, payload) => handler(payload);
|
|
433
|
+
ipcRenderer.on('updater:status', listener);
|
|
434
|
+
return () => ipcRenderer.removeListener('updater:status', listener);
|
|
435
|
+
},
|
|
436
|
+
},
|
|
420
437
|
webRemote: {
|
|
421
438
|
/** Current connection state (no token values). */
|
|
422
439
|
getStatus: () => ipcRenderer.invoke('webRemote:get-status'),
|
|
@@ -448,7 +465,7 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
448
465
|
},
|
|
449
466
|
/** Revoke ALL paired devices and tear down every session immediately. */
|
|
450
467
|
revokeAll: () => ipcRenderer.invoke('webRemote:revoke-all'),
|
|
451
|
-
confirmSas: () => ipcRenderer.invoke('webRemote:confirm-sas'),
|
|
468
|
+
confirmSas: (clientKey) => ipcRenderer.invoke('webRemote:confirm-sas', clientKey ? { clientKey } : undefined),
|
|
452
469
|
/** Push event when revokeAll completes (main broadcasts webRemote:revoked-all). */
|
|
453
470
|
onRevokedAll: (handler) => {
|
|
454
471
|
const listener = (_e, payload) => handler(payload);
|
|
@@ -509,6 +526,12 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
509
526
|
ipcRenderer.on('chat:external-send', listener);
|
|
510
527
|
return () => ipcRenderer.removeListener('chat:external-send', listener);
|
|
511
528
|
},
|
|
529
|
+
/** Fires when a paired phone asks main to start a new Session. */
|
|
530
|
+
onExternalNewSession: (handler) => {
|
|
531
|
+
const listener = (_e, payload) => handler(payload);
|
|
532
|
+
ipcRenderer.on('chat:external-new-session', listener);
|
|
533
|
+
return () => ipcRenderer.removeListener('chat:external-new-session', listener);
|
|
534
|
+
},
|
|
512
535
|
/** Classify a queued PromptTicket's text as 'inline' or 'develop'. */
|
|
513
536
|
classifyTicket: (payload) => ipcRenderer.invoke('chat:classify-ticket', payload),
|
|
514
537
|
/** Author a mechanical draft PRD from a queued PromptTicket classified 'develop'. */
|
|
@@ -3,9 +3,9 @@ name: demo-video-builder
|
|
|
3
3
|
description: 30-second self-contained HTML/JS demo video for Project Home, saved via project_demo_video_write.
|
|
4
4
|
tools: Read, Grep, Glob, Bash, Write, Edit
|
|
5
5
|
title: 'Project Home — Demo Video'
|
|
6
|
-
model:
|
|
7
|
-
effort:
|
|
8
|
-
seedVersion:
|
|
6
|
+
model: opus
|
|
7
|
+
effort: max
|
|
8
|
+
seedVersion: 4
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
You are the demo-video-builder. You make a 30-second animated demo that shows someone what this
|
|
@@ -28,17 +28,59 @@ testimonials, or UI screenshots. Where the project already describes itself well
|
|
|
28
28
|
feature list, a mission statement), reuse its own wording instead of paraphrasing.
|
|
29
29
|
</grounding_rules>
|
|
30
30
|
|
|
31
|
+
<script_first>
|
|
32
|
+
Write the narration script before any visual work: ~70-80 spoken words for 30 s (~150 wpm), beats =
|
|
33
|
+
hook (a question or bold claim, 0-4 s), problem, solution, three features, call to action with the
|
|
34
|
+
real get-started command. Every line traces to the claims list. Then storyboard one scene per line,
|
|
35
|
+
sized to that line's spoken length; visuals illustrate what the line says at that moment (the noun
|
|
36
|
+
on screen when it is spoken). Good script first, visuals second — a strong script with simple
|
|
37
|
+
visuals beats flashy visuals over a weak script.
|
|
38
|
+
</script_first>
|
|
39
|
+
|
|
40
|
+
<character>
|
|
41
|
+
Design one ORIGINAL mascot from the project's theme/purpose (e.g. a terminal-shaped robot for a CLI
|
|
42
|
+
tool, a ledger-owl for a finance app) — never a trademarked or existing character. Build it only
|
|
43
|
+
from inline SVG/CSS shapes, give it a name and 2-3 expressions, and a deterministic idle loop
|
|
44
|
+
(blink, bob, breathe) computed from t. It appears in most scenes and reacts to each beat (points at
|
|
45
|
+
the feature, celebrates at the CTA). Cute = rounded shapes, big eyes, soft palette drawn from the
|
|
46
|
+
project's own brand colors when it has any.
|
|
47
|
+
</character>
|
|
48
|
+
|
|
49
|
+
<styles>
|
|
50
|
+
Four styles; follow `Video style: <name>` from additional instructions, otherwise choose by the
|
|
51
|
+
project's audience (developer/enterprise → Professional, consumer/playful → Fun,
|
|
52
|
+
conceptual/educational → Animated whiteboard, text-heavy/CLI → Kinetic typography) and name the
|
|
53
|
+
choice in the report.
|
|
54
|
+
- Professional — clean 2D motion graphics, restrained palette, grid layout, smooth ease-in-out,
|
|
55
|
+
character small and polished.
|
|
56
|
+
- Fun — character-led cartoon, saturated palette, squash-and-stretch, bouncy overshoot easing,
|
|
57
|
+
playful sound-matched pops.
|
|
58
|
+
- Animated whiteboard — white background, black/one-accent strokes drawn on via SVG
|
|
59
|
+
stroke-dashoffset, a hand/marker cursor following the stroke, character sketched in line art.
|
|
60
|
+
- Kinetic typography — the script itself is the visual: words animate in sync with narration timing
|
|
61
|
+
(scale, slide, rotate), the character punctuates key words.
|
|
62
|
+
Whatever the style, readability first: captions ≤12 words, high contrast.
|
|
63
|
+
</styles>
|
|
64
|
+
|
|
65
|
+
<dynamic_elements>
|
|
66
|
+
Include at least three per video: overshoot/elastic easing, particle bursts or confetti, morphing
|
|
67
|
+
shapes, camera pan/zoom across the 1280x720 stage, parallax layers, animated counters/diagrams
|
|
68
|
+
built from real facts. Every element is a pure function of t; any randomness comes from a seeded
|
|
69
|
+
PRNG (e.g. mulberry32 with a fixed seed) so `seek(t)` stays exact and frames are deterministic.
|
|
70
|
+
</dynamic_elements>
|
|
71
|
+
|
|
31
72
|
<storyboard>
|
|
32
|
-
Before writing any code,
|
|
33
|
-
seconds:
|
|
73
|
+
Before writing any code, turn the script into a 5-8 scene storyboard, one scene per script line,
|
|
74
|
+
with timings that sum to exactly 30 seconds:
|
|
34
75
|
|
|
35
|
-
1. Title card — the project's name and a one-line purpose.
|
|
76
|
+
1. Title card — the project's name and a one-line purpose (the hook).
|
|
36
77
|
2. The problem it solves.
|
|
37
78
|
3-6. One scene per key feature (3 to 4 features), each a short caption plus a simple animated
|
|
38
79
|
diagram or kinetic type built from shapes, SVG, or canvas — never a fake screenshot.
|
|
39
80
|
7. Closing card — the project's name and how to get started (the real command).
|
|
40
81
|
|
|
41
|
-
|
|
82
|
+
The character appears in most scenes per `<character>`; the style follows `<styles>`. Keep every
|
|
83
|
+
caption at 12 words or fewer, and hold each scene on screen long enough to read twice.
|
|
42
84
|
</storyboard>
|
|
43
85
|
|
|
44
86
|
<output_contract>
|
|
@@ -117,25 +159,26 @@ open('demo.html', 'w').write(html)
|
|
|
117
159
|
- Never write the literal pattern `function (` or `function(` in the inline `<script>` —
|
|
118
160
|
`project_demo_video_write`'s safety scanner blocks anything matching `/\bFunction\s*\(/i`.
|
|
119
161
|
Use arrow functions (`() => { ... }`) throughout.
|
|
120
|
-
- Save the built file by path (see `<process
|
|
121
|
-
argument — a ~300 KB payload retyped by the model is exactly how a run once shipped silent.
|
|
122
|
-
</audio_policy>
|
|
123
|
-
|
|
124
|
-
<process>
|
|
162
|
+
- Save the built file by path (see `<process>
|
|
125
163
|
1. Read, with a bounded pass: the manifest, the README or top-level docs index, the top-level
|
|
126
164
|
directory tree, and `git log --oneline -30` for a sense of recent direction. Stop once you
|
|
127
165
|
have enough to describe the project honestly.
|
|
128
166
|
2. Write the claims list: for every goal or feature you plan to show, note the source you read
|
|
129
167
|
it from. Drop anything without a source.
|
|
130
|
-
3. Write the
|
|
131
|
-
4.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
168
|
+
3. Write the narration script per `<script_first>`.
|
|
169
|
+
4. Choose the style per `<styles>` and design the mascot per `<character>`.
|
|
170
|
+
5. Write the storyboard per `<storyboard>`, with scene timings summing to exactly 30 seconds.
|
|
171
|
+
6. Build the HTML per `<output_contract>` (with `<dynamic_elements>`) and the narration track per
|
|
172
|
+
`<audio_policy>`, ending with the final document written to a file (`demo.html`) that contains
|
|
173
|
+
the `<audio>` tag.
|
|
174
|
+
7. Self-check before saving: scene durations sum to 30, every caption traces to a claim in your
|
|
175
|
+
list, the character appears, at least 3 dynamic elements are present, the style matches the
|
|
176
|
+
choice, and the document contains none of the forbidden network APIs.
|
|
177
|
+
8. Call `project_demo_video_write` exactly once with `{ htmlPath }` — the absolute path of the
|
|
136
178
|
built file. Never pass the document in `html` (retyping base64 is how narration got lost). It
|
|
137
179
|
validates the document and writes it as the project's Demo Video.
|
|
138
|
-
|
|
180
|
+
9. Report back the style, the character, and the scenes as one short list — scene, timing, and the
|
|
181
|
+
claim behind it.
|
|
139
182
|
</process>
|
|
140
183
|
|
|
141
184
|
<when_things_fail>
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import{aD as l,an as e,S as P,A as H,n as K,a2 as Re,aU as ue,bb as Z,bi as Ie,W as Ae,D as ne,_ as Te,a as L,a0 as Pe,b6 as Oe,b3 as De,aY as $e,c as ae,aB as Me,b0 as Le,ba as re,b2 as Fe,aW as q,ap as _e,au as Be,J as He,H as ie,aL as Ue}from"./index-fJxuoRvi.js";import{P as ze}from"./Panel-Dc6F8wb4.js";import{S as Ge}from"./ScopeSwitcher-tHtloWbN.js";import{S as pe}from"./SaveBar-DSMnbUVI.js";import{u as Je,s as oe,E as Ke}from"./settingsSchema-xxO9p4yF.js";import{V as We}from"./ViewTabs-CfEfOSE1.js";import{T as Y}from"./Toggle-CTXTU1q5.js";import"./monaco-editor-BsIlgG7c.js";import"./claude-settings-schema-COigsajx.js";const Ve=[{id:"essentials",title:"Essentials",summary:"The knobs you reach for first.",keys:["model","language","outputStyle","permissions"]},{id:"git",title:"Git & Commits",summary:"How Claude writes commits and pull requests on your behalf.",keys:["attribution","includeGitInstructions","includeCoAuthoredBy"]},{id:"memory",title:"Memory & Plans",summary:"Context Claude keeps between sessions and where it files plans.",keys:["autoMemoryEnabled","plansDirectory","claudeMdExcludes","respectGitignore"]},{id:"model",title:"Model & Reasoning",summary:"Model allow/override lists, reasoning depth, and fast-mode toggles — machine-wide, with no per-Epic override yet. An Epic's Agent persona model (Agent Library) still wins over Essentials' plain model default.",advanced:!0,keys:["availableModels","modelOverrides","effortLevel","fastMode","fastModePerSessionOptIn","alwaysThinkingEnabled","fallbackModel","enforceAvailableModels","teammateDefaultModel","advisorModel"]},{id:"interface",title:"Interface",summary:"Visual polish — spinners, progress bars, motion.",keys:["spinnerTipsEnabled","spinnerTipsOverride","spinnerVerbs","terminalProgressBarEnabled","showTurnDuration","prefersReducedMotion","companyAnnouncements","statusLine","teammateMode"]},{id:"updates",title:"Updates & Cleanup",summary:"Release channel and how long transcripts stick around.",keys:["autoUpdatesChannel","cleanupPeriodDays"]},{id:"env",title:"Environment & Auth",summary:"Environment variables and auth-helper scripts.",keys:["env","apiKeyHelper","awsCredentialExport","awsAuthRefresh"]},{id:"hooks",title:"Hooks",summary:"Scripts Claude runs before/after tool use.",keys:["hooks","disableAllHooks","allowedHttpHookUrls","httpHookAllowedEnvVars"]},{id:"mcp",title:"MCP Servers",summary:"External tool providers Claude can talk to.",keys:["enableAllProjectMcpServers","enabledMcpjsonServers","disabledMcpjsonServers"]},{id:"plugins",title:"Plugins",summary:"Installed plugins, marketplaces, and per-plugin configuration.",keys:["enabledPlugins","extraKnownMarketplaces","skippedPlugins","skippedMarketplaces","pluginConfigs"]},{id:"filesystem",title:"File Picker & Sandbox",summary:"How Claude browses files and the sandbox it runs in.",keys:["fileSuggestion","sandbox","worktree"]},{id:"login",title:"Login",summary:"Which login method to force on startup.",keys:["forceLoginMethod","forceLoginOrgUUID"]},{id:"feedback",title:"Feedback",summary:"Session-quality surveys.",keys:["feedbackSurveyRate"]},{id:"advanced",title:"Advanced / Enterprise",summary:"Managed-settings-only keys and enterprise allow/denylists.",advanced:!0,keys:["allowedMcpServers","deniedMcpServers","allowManagedHooksOnly","allowManagedPermissionRulesOnly","allowManagedMcpServersOnly","strictKnownMarketplaces","blockedMarketplaces","pluginTrustMessage","otelHeadersHelper","skipWebFetchPreflight"]}],qe={mcp:"MCP",url:"URL",urls:"URLs",http:"HTTP",ui:"UI",id:"ID",uuid:"UUID",api:"API",aws:"AWS",otel:"OTel",json:"JSON"};function fe(t){return t.replace(/^\$/,"").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2").toLowerCase().split(/\s+/).filter(Boolean).map((o,r)=>{const a=qe[o];return a||(r===0?o.charAt(0).toUpperCase()+o.slice(1):o)}).join(" ")}function he(t){const s=new Set,n=[];for(const r of Ve){const a=r.keys.filter(c=>t.has(c));a.forEach(c=>s.add(c)),a.length!==0&&n.push({id:r.id,title:r.title,summary:r.summary,advanced:!!r.advanced,keys:a})}const o=Array.from(t).filter(r=>!s.has(r)&&r!=="$schema").sort();return o.length>0&&n.push({id:"other",title:"Other",summary:"Keys not yet grouped.",advanced:!1,keys:o}),n}function Xe(t,s){return he(t).map(n=>({id:n.id,title:n.title,advanced:n.advanced,total:n.keys.length,setCount:n.keys.filter(o=>s.has(o)).length}))}const Ye={};function ge(t,s){if(s)return{text:s,authored:!1};const n=Ye[t];return n?{text:n,authored:!0}:null}const Ze={essentials:"star",git:"link",memory:"memory",model:"sparkle",interface:"eye",updates:"reload",env:"keys",hooks:"hooks",mcp:"mcp",plugins:"plugins",filesystem:"folder",login:"lock",feedback:"send",advanced:"shield",other:"dot"},Qe=["user","project","local","default"],et={user:"user",project:"project",local:"local",default:"default"};function tt({node:t,targetScope:s,onOverride:n,schema:o}){const[r,a]=l.useState(""),[c,p]=l.useState(!1),[b,j]=l.useState(!0),i=t.kind==="object"?t:null,u=i?Object.keys(i.children):[],g=o.rootKeys(),y=new Set([...u,...g]),f=l.useMemo(()=>he(y),[Array.from(y).sort().join(",")]),w=l.useMemo(()=>Xe(y,new Set(u)),[Array.from(y).sort().join(","),u.join(",")]),[R,S]=l.useState(null),m=l.useRef(null),N=h=>{const k=f.find(E=>E.id===h);k!=null&&k.advanced&&!c&&p(!0),S(h)};l.useEffect(()=>{if(!R)return;S(null);const h=m.current,k=document.getElementById(`settings-group-${R}`);if(!h||!k)return;const E=k.getBoundingClientRect().top-h.getBoundingClientRect().top;h.scrollBy({top:E,behavior:"smooth"})},[R]);const I=l.useMemo(()=>f.filter(h=>c||!h.advanced).map(h=>({...h,keys:h.keys.filter(k=>{const E=(i==null?void 0:i.children[k])!==void 0;if(!b&&!E)return!1;if(!r.trim())return!0;const v=o.at([k]);return[k,fe(k),(v==null?void 0:v.description)??""].join(" ").toLowerCase().includes(r.toLowerCase())})})).filter(h=>h.keys.length>0),[f,r,c,b,i,o]);return e.jsxs("div",{className:"h-full flex flex-col",children:[e.jsxs("div",{className:"shrink-0 border-b border-line bg-bg-elev px-3 py-1.5 flex items-center gap-3 text-xs",children:[e.jsxs("span",{className:"text-fg-faint",children:["writing overrides to"," ",e.jsx("span",{className:"text-fg-dim font-medium",children:P[s].label})]}),e.jsxs("label",{className:"flex items-center gap-1 text-fg-faint cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:b,onChange:h=>j(h.target.checked),className:"accent-accent"}),"show not-yet-configured"]}),e.jsxs("label",{className:"flex items-center gap-1 text-fg-faint cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:c,onChange:h=>p(h.target.checked),className:"accent-accent"}),"show advanced"]}),e.jsx("div",{className:"flex-1"}),e.jsx("input",{value:r,onChange:h=>a(h.target.value),placeholder:"search settings…",className:"bg-bg border border-line rounded px-2 py-1 text-xs text-fg w-64"})]}),e.jsxs("div",{className:"flex-1 flex overflow-hidden",children:[e.jsx(st,{groups:w,onJump:N}),e.jsxs("div",{ref:m,className:"flex-1 overflow-auto py-3",children:[I.map(h=>e.jsx(nt,{id:h.id,title:h.title,summary:h.summary,advanced:h.advanced,children:h.keys.map(k=>{const E=i==null?void 0:i.children[k],v=o.at([k]);return e.jsx(at,{keyName:k,node:E,info:v,targetScope:s,onOverride:(d,C)=>n([k],d,C)},k)})},h.id)),I.length===0&&e.jsxs("div",{className:"px-6 py-12 text-center text-fg-faint text-sm",children:['no settings match "',r,'"']})]})]})]})}function st({groups:t,onJump:s}){return e.jsx("nav",{className:"shrink-0 w-48 border-r border-line bg-bg-elev/30 overflow-y-auto py-3",children:t.map(n=>e.jsxs("button",{onClick:()=>s(n.id),className:"w-full flex items-center gap-2 px-3 py-2 text-left hover:bg-bg-hi transition-colors",title:`jump to ${n.title}`,children:[e.jsx(H,{name:Ze[n.id]??"dot",size:15,className:"text-fg-faint shrink-0"}),e.jsx("span",{className:"flex-1 min-w-0 truncate text-xs text-fg-dim",children:n.title}),e.jsxs("span",{className:"text-[10px] text-fg-faint font-mono shrink-0",children:[n.setCount,"/",n.total]})]},n.id))})}function nt({id:t,title:s,summary:n,advanced:o,children:r}){const[a,c]=l.useState(!0);return e.jsxs("section",{id:`settings-group-${t}`,className:"mx-4 mb-4 rounded-lg border border-line shadow-sm bg-bg-elev/50 overflow-hidden",children:[e.jsxs("header",{className:"px-4 py-3 bg-bg-elev cursor-pointer hover:bg-bg-hi flex items-center gap-3 border-b border-line",onClick:()=>c(!a),children:[e.jsx("span",{className:"text-fg-faint w-3",children:a?"▾":"▸"}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-fg text-base font-semibold",children:s}),o&&e.jsx("span",{className:"text-[9px] px-1.5 py-0 rounded border border-yellow-900/40 bg-yellow-950/30 text-yellow-500/80 uppercase tracking-wide",children:"advanced"})]}),e.jsx("p",{className:"text-fg-dim text-sm mt-0.5",children:n})]})]}),a&&e.jsx("div",{className:"divide-y divide-line/60",children:r})]})}function at({keyName:t,node:s,info:n,targetScope:o,onOverride:r}){const[a,c]=l.useState(!1),[p,b]=l.useState(!1),j=fe(t),i=s!==void 0,g=(s==null?void 0:s.kind)==="leaf"?s:null,y=(s==null?void 0:s.kind)==="object"||(s==null?void 0:s.kind)==="array",f=n==null?void 0:n.default,w=g&&f!==void 0&&ye(g.value,f),R=mt({isSet:i,leafNode:g,defaultVal:f,isDefault:!!w,node:s}),S=rt(g,f),m=S.length>=2,N=!!g&&!w,I=ge(t,n==null?void 0:n.description);return e.jsx("div",{className:"px-4 py-3 hover:bg-bg-elev/20",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("button",{onClick:()=>c(!a),className:"text-fg-faint hover:text-fg w-3 mt-0.5",title:a?"collapse":"expand",children:a?"▾":"▸"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-baseline gap-2 flex-wrap",children:[e.jsx("h3",{className:"text-fg text-sm",children:j}),e.jsx(ut,{kind:R.kind,label:R.label}),m&&e.jsxs("button",{onClick:h=>{h.stopPropagation(),a||c(!0),b(k=>!k)},className:"text-[9px] px-1.5 py-0 rounded border border-blue-900/40 bg-blue-950/30 text-blue-300/90 uppercase tracking-wide hover:bg-blue-900/40",title:"this key is defined in multiple scopes — click to expand",children:["drift · ",S.map(h=>et[h]).join(" · ")]}),N&&g&&e.jsx("button",{onClick:h=>{h.stopPropagation(),r(void 0,g.winner)},className:"text-[9px] px-1.5 py-0 rounded border border-line bg-bg-elev text-fg-faint uppercase tracking-wide hover:text-fg hover:bg-bg-hi",title:`reset · delete from ${P[g.winner].label}`,children:"↺ reset"}),(n==null?void 0:n.deprecated)&&e.jsx("span",{className:"text-[9px] px-1 py-0 rounded border border-yellow-900/40 bg-yellow-950/30 text-yellow-500/80 uppercase tracking-wide",children:"deprecated"}),(n==null?void 0:n.required)&&!i&&e.jsx("span",{className:"text-[9px] px-1 py-0 rounded border border-red-900/40 bg-red-950/30 text-red-400/80 uppercase tracking-wide",children:"required"})]}),I&&e.jsx("p",{className:`text-fg-dim text-xs mt-0.5 leading-relaxed ${I.authored?"inline-block border-b border-dotted border-fg-faint/70 cursor-help":""}`,title:I.authored?"In-app-authored description — not from the official Claude Code schema":void 0,children:pt(I.text)}),a&&p&&g&&e.jsx(it,{leaf:g,defaultVal:f,onReset:h=>r(void 0,h)}),a&&e.jsx(ot,{keyName:t,node:s,info:n,targetScope:o,onOverride:h=>r(h)})]}),e.jsx("div",{className:"shrink-0",children:!a&&e.jsx(xt,{node:s,info:n,onSet:h=>{r(h)},disabled:y&&i})})]})})}function rt(t,s){if(!t)return[];const n=new Set;n.add(t.winner);for(const o of t.shadowed)n.add(o.scope);return s!==void 0&&n.add("default"),Qe.filter(o=>n.has(o))}function it({leaf:t,defaultVal:s,onReset:n}){const o={};o[t.winner]={value:t.value,winner:!0};for(const r of t.shadowed)o[r.scope]={value:r.value,winner:!1};return e.jsxs("div",{className:"mt-2 border border-line rounded bg-bg-elev/40 text-xs",children:[e.jsx("div",{className:"px-2 py-1 text-fg-faint border-b border-line/60",children:"Values across all scopes (winner highlighted · reset removes that scope's value):"}),e.jsxs("div",{className:"divide-y divide-line/60",children:[["user","project","local"].map(r=>{const a=o[r],c=a!==void 0;return e.jsxs("div",{className:"grid grid-cols-[5rem_1fr_auto] gap-2 px-2 py-1 items-center",children:[e.jsx("span",{className:"text-fg-faint",children:P[r].label}),e.jsx("span",{className:`font-mono truncate ${a!=null&&a.winner?"text-accent":"text-fg-dim"}`,children:c?B(a.value):e.jsx("span",{className:"text-fg-faint",children:"—"})}),c?e.jsx("button",{onClick:()=>n(r),className:"text-[9px] px-1.5 py-0 rounded border border-line text-fg-faint uppercase tracking-wide hover:text-fg hover:bg-bg-hi",title:`delete this key from ${P[r].label}`,children:"↺"}):e.jsx("span",{})]},r)}),e.jsxs("div",{className:"grid grid-cols-[5rem_1fr_auto] gap-2 px-2 py-1 items-center",children:[e.jsx("span",{className:"text-fg-faint",children:"Default"}),e.jsx("span",{className:"font-mono text-fg-dim truncate",children:s!==void 0?B(s):e.jsx("span",{className:"text-fg-faint",children:"—"})}),e.jsx("span",{})]})]})]})}function ot({keyName:t,node:s,info:n,targetScope:o,onOverride:r}){const c=(s==null?void 0:s.kind)==="leaf"?s:null,p=ge(t,n==null?void 0:n.description);return e.jsxs("div",{className:"mt-3 space-y-2 text-xs",children:[p&&e.jsx("p",{className:`text-fg-dim leading-relaxed whitespace-pre-wrap ${p.authored?"inline-block border-b border-dotted border-fg-faint/70 cursor-help":""}`,title:p.authored?"In-app-authored description — not from the official Claude Code schema":void 0,children:p.text}),e.jsxs("dl",{className:"grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-fg-faint",children:[(n==null?void 0:n.type)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:"Type"}),e.jsx("dd",{className:"text-fg-dim font-mono",children:Array.isArray(n.type)?n.type.join(" | "):n.type})]}),(n==null?void 0:n.default)!==void 0&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:"Default"}),e.jsx("dd",{className:"text-fg-dim font-mono",children:B(n.default)})]}),(n==null?void 0:n.enum)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:"Options"}),e.jsx("dd",{className:"text-fg-dim font-mono",children:n.enum.map(b=>String(b)).join(" | ")})]}),c&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:"Current"}),e.jsxs("dd",{className:"font-mono",children:[e.jsx("span",{className:"text-fg-dim",children:B(c.value)}),e.jsxs("span",{className:"ml-2 text-fg-faint",children:["from ",P[c.winner].label]})]})]}),c&&c.shadowed.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:"Shadowed"}),e.jsx("dd",{className:"space-y-0.5",children:c.shadowed.map((b,j)=>e.jsxs("div",{className:"font-mono text-fg-faint line-through",children:[B(b.value)," —"," ",e.jsx("span",{className:"no-underline",children:P[b.scope].label})]},j))})]}),(s==null?void 0:s.kind)==="array"&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:"Accumulated"}),e.jsxs("dd",{className:"text-fg-dim",children:[s.items.length," items across all scopes"]})]})]}),e.jsx("div",{className:"pt-2 flex items-center gap-2 flex-wrap border-t border-line/60",children:e.jsx(lt,{keyName:t,node:s,info:n,onChange:r,targetScope:o})})]})}function lt({node:t,info:s,onChange:n,targetScope:o}){const a=(t==null?void 0:t.kind)==="leaf"?t.value:s==null?void 0:s.default,c=be(s==null?void 0:s.type);if(c==="boolean"){const p=a===!0;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-fg-faint",children:"Set to:"}),e.jsx("div",{className:"inline-flex rounded border border-line overflow-hidden",children:[{v:!0,label:"on"},{v:!1,label:"off"}].map(({v:b,label:j})=>e.jsx("button",{onClick:()=>n(b),className:`px-3 py-0.5 text-xs transition-colors ${p===b?"bg-accent text-bg":"bg-bg-elev text-fg-dim hover:bg-bg-hi hover:text-fg"}`,children:j},j))}),e.jsxs("span",{className:"text-fg-faint",children:["→ ",P[o].label]})]})}return s!=null&&s.enum?e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("span",{className:"text-fg-faint",children:"Choose:"}),s.enum.map(p=>{const b=ye(a,p);return e.jsx("button",{onClick:()=>n(p),className:`px-2 py-0.5 text-xs rounded border ${b?"bg-accent text-bg border-accent":"bg-bg-elev text-fg-dim border-line hover:text-fg hover:bg-bg-hi"}`,children:String(p)},String(p))}),e.jsxs("span",{className:"text-fg-faint",children:["→ ",P[o].label]})]}):c==="integer"||c==="number"?e.jsx(ct,{value:typeof a=="number"?a:void 0,integer:c==="integer",onCommit:n,target:P[o].label}):c==="string"?e.jsx(dt,{value:typeof a=="string"?a:"",onCommit:n,target:P[o].label}):e.jsxs("div",{className:"text-fg-faint",children:["Complex value (",c??"object/array",") — use the"," ",e.jsx("span",{className:"text-fg-dim",children:"Raw"})," tab to edit."]})}function ct({value:t,integer:s,onCommit:n,target:o}){const[r,a]=l.useState(t!==void 0?String(t):""),c=()=>{const p=s?parseInt(r,10):parseFloat(r);Number.isNaN(p)||n(p)};return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-fg-faint",children:"Set to:"}),e.jsx("input",{type:"number",value:r,onChange:p=>a(p.target.value),onBlur:c,onKeyDown:p=>{p.key==="Enter"&&p.target.blur()},className:"w-24 bg-bg border border-line rounded px-2 py-0.5 text-xs text-fg"}),e.jsxs("button",{onClick:c,className:"px-2 py-0.5 text-xs border border-accent/50 rounded text-accent hover:bg-accent hover:text-bg",children:["save → ",o]})]})}function dt({value:t,onCommit:s,target:n}){const[o,r]=l.useState(t);return e.jsxs("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[e.jsx("span",{className:"text-fg-faint shrink-0",children:"Set to:"}),e.jsx("input",{type:"text",value:o,onChange:a=>r(a.target.value),onKeyDown:a=>{a.key==="Enter"&&s(o)},className:"flex-1 min-w-0 bg-bg border border-line rounded px-2 py-0.5 text-xs text-fg"}),e.jsxs("button",{onClick:()=>s(o),className:"shrink-0 px-2 py-0.5 text-xs border border-accent/50 rounded text-accent hover:bg-accent hover:text-bg",children:["save → ",n]})]})}function xt({node:t,info:s,onSet:n,disabled:o}){const r=(t==null?void 0:t.kind)==="leaf",a=be(s==null?void 0:s.type);if(o)return null;if(a==="boolean"){const c=r&&t.value===!0;return e.jsx("button",{onClick:()=>n(!c),className:`px-2.5 py-0.5 text-xs rounded border transition-colors ${c?"bg-accent/15 text-accent border-accent/40 hover:bg-accent hover:text-bg":"bg-bg-elev text-fg-dim border-line hover:text-fg hover:bg-bg-hi"}`,title:"toggle",children:c?"on":"off"})}return null}function mt({isSet:t,leafNode:s,defaultVal:n,isDefault:o,node:r}){return t?(r==null?void 0:r.kind)==="array"?{kind:"accumulated",label:`${r.items.length} items`}:(r==null?void 0:r.kind)==="object"?{kind:"set",label:"configured"}:s?o?{kind:"default",label:`= default · ${P[s.winner].label}`}:s.shadowed.length>0?{kind:"override",label:`overriding ${s.shadowed.length} scope(s)`}:{kind:"set",label:`set in ${P[s.winner].label}`}:{kind:"set",label:"configured"}:n!==void 0?{kind:"default",label:`using default: ${B(n)}`}:{kind:"unset",label:"not configured"}}function ut({kind:t,label:s}){const n={set:"bg-accent/15 text-accent border-accent/30",default:"bg-bg-hi text-fg-dim border-line",unset:"bg-bg-elev text-fg-faint border-line",override:"bg-purple-950/30 text-purple-400/80 border-purple-900/40",accumulated:"bg-blue-950/30 text-blue-400/80 border-blue-900/40"}[t];return e.jsx("span",{className:`text-[9px] px-1.5 py-0 rounded border uppercase tracking-wide ${n}`,children:s})}function be(t){if(t)return Array.isArray(t)?t.find(n=>n!=="null")??t[0]:t}function ye(t,s){return t===s?!0:typeof t!=typeof s?!1:t&&s&&typeof t=="object"?JSON.stringify(t)===JSON.stringify(s):!1}function pt(t){const s=t.trim().split(`
|
|
2
|
-
`)[0],n=s.match(/^([^.!?]+[.!?])/);return n?n[1]:s.length>120?s.slice(0,120)+"…":s}function B(t){if(typeof t=="string")return t===""?'""':JSON.stringify(t);if(t===null)return"null";if(t===void 0)return"—";if(typeof t=="object"){const s=JSON.stringify(t);return s.length>60?s.slice(0,60)+"…":s}return String(t)}const ft=1440*60*1e3;function le(t){if(!t)return"never";const s=new Date(t).getTime();return Number.isNaN(s)?"never":new Date(s).toLocaleString()}function ce(t){return t?new Date(t).toLocaleString():"never"}function ht(){return e.jsxs("div",{className:"p-4 max-w-3xl space-y-8 text-sm",children:[e.jsx(gt,{}),e.jsx("hr",{className:"border-line"}),e.jsx(bt,{})]})}function gt(){const[t,s]=l.useState(null),[n,o]=l.useState(null),[r,a]=l.useState(null),[c,p]=l.useState(null),[b,j]=l.useState(!1),[i,u]=l.useState(null),[g,y]=l.useState(null);if(l.useEffect(()=>{let m=!1;return Promise.all([window.api.otel.getConfig(),window.api.otel.status(),window.api.otel.configPath()]).then(([N,I,h])=>{m||(s(N),a(N),o(I),p(h))}).catch(N=>{console.warn("[telemetry] load failed:",N==null?void 0:N.message)}),()=>{m=!0}},[]),!r||!t)return e.jsx(K,{title:"loading…"});const f=JSON.stringify(r)!==JSON.stringify(t),w=(m,N)=>{u(null),a({...r,[m]:N})},R=async()=>{j(!0),u(null);try{const m=await window.api.otel.setConfig(r);!m.ok&&m.error&&u(m.error),s(m.config),a(m.config),o(m.status),y(Date.now())}catch(m){u(m instanceof Error?m.message:String(m))}finally{j(!1)}},S=()=>{u(null),a(t)};return e.jsxs("div",{className:"space-y-5",children:[e.jsxs("header",{className:"space-y-1",children:[e.jsx("h2",{className:"text-fg text-base font-medium",children:"OpenTelemetry export"}),e.jsx("p",{className:"text-fg-dim text-xs leading-relaxed",children:"When enabled, every classified transcript event (tool_use, todo_write, plan, usage, agent_spawn) is mirrored as a 0-duration OTLP/HTTP span. Point this at a local collector (Jaeger, Grafana Tempo, SigNoz, Honeycomb) for cross-session analysis."}),c&&e.jsxs("p",{className:"text-fg-faint text-[11px]",children:["stored at ",e.jsx("span",{className:"font-mono",children:c})]})]}),e.jsxs("section",{className:"border border-line rounded p-3 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-fg",children:"Export transcripts to OTEL"}),e.jsx("div",{className:"text-fg-faint text-xs",children:"Toggle off to disable all span emission immediately."})]}),e.jsx(Y,{checked:r.enabled,onChange:m=>w("enabled",m),label:r.enabled?"on":"off"})]}),e.jsxs("label",{className:"block space-y-1",children:[e.jsx("span",{className:"text-fg-dim text-xs",children:"OTLP/HTTP traces endpoint"}),e.jsx("input",{type:"text",value:r.endpoint,onChange:m=>w("endpoint",m.target.value),placeholder:"http://localhost:4318/v1/traces",className:"w-full bg-bg border border-line rounded px-2 py-1 text-fg font-mono text-xs"})]}),e.jsxs("label",{className:"block space-y-1",children:[e.jsxs("span",{className:"text-fg-dim text-xs",children:["Headers (newline-separated ",e.jsx("span",{className:"font-mono",children:"Key: Value"}),")"]}),e.jsx("textarea",{value:r.headers,onChange:m=>w("headers",m.target.value),placeholder:"x-honeycomb-team: YOUR_API_KEY",rows:3,className:"w-full bg-bg border border-line rounded px-2 py-1 text-fg font-mono text-xs"})]}),e.jsxs("label",{className:"block space-y-1",children:[e.jsx("span",{className:"text-fg-dim text-xs",children:"Service name"}),e.jsx("input",{type:"text",value:r.serviceName,onChange:m=>w("serviceName",m.target.value),placeholder:"session-manager",className:"w-full bg-bg border border-line rounded px-2 py-1 text-fg font-mono text-xs"})]}),e.jsxs("div",{className:"flex items-start justify-between gap-3 pt-1",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-fg",children:"Include content (PII)"}),e.jsxs("div",{className:"text-fg-faint text-xs leading-relaxed",children:["Adds tool inputs, plan text, and agent prompts to span attributes. Off by default — matches upstream Claude Code's ",e.jsx("span",{className:"font-mono",children:"OTEL_LOG_USER_PROMPTS"})," opt-in."]})]}),e.jsx(Y,{checked:r.includeContent,onChange:m=>w("includeContent",m),label:r.includeContent?"on":"off"})]})]}),n&&e.jsxs("section",{className:"border border-line rounded p-3 text-xs space-y-1",children:[e.jsx("div",{className:"text-fg-dim",children:"Runtime status"}),e.jsxs("div",{children:[e.jsx("span",{className:"text-fg-faint",children:"enabled:"})," ",e.jsx("span",{className:n.enabled?"text-accent":"text-fg-dim",children:String(n.enabled)})]}),n.error&&e.jsxs("div",{className:"text-red-400 break-words",children:[e.jsx("span",{className:"text-fg-faint",children:"error:"})," ",n.error]}),!n.error&&n.enabled&&e.jsx("div",{className:"text-fg-faint",children:"spans batched and exported in the background. Verify by enabling and pointing at a local Jaeger."})]}),e.jsxs("footer",{className:"flex items-center gap-3 pt-2 border-t border-line",children:[e.jsx("button",{onClick:R,disabled:!f||b,className:"px-3 py-1 text-xs rounded bg-accent text-bg disabled:opacity-50 disabled:cursor-not-allowed",children:b?"saving…":"Save"}),e.jsx("button",{onClick:S,disabled:!f||b,className:"px-3 py-1 text-xs rounded border border-line text-fg-dim hover:text-fg disabled:opacity-50 disabled:cursor-not-allowed",children:"Revert"}),i&&e.jsx("span",{className:"text-red-400 text-xs",children:i}),!i&&g&&!f&&e.jsx("span",{className:"text-fg-faint text-xs",children:"saved"})]})]})}function bt(){const[t,s]=l.useState(null),[n,o]=l.useState(null),[r,a]=l.useState("Copy"),[c,p]=l.useState(!1),[b,j]=l.useState(null),[i,u]=l.useState(null),[g,y]=l.useState(null),[f,w]=l.useState(!1),R=()=>{window.api.telemetry.status().then(o).catch(v=>{console.warn("[product-telemetry] status reload failed:",v==null?void 0:v.message)})};if(l.useEffect(()=>{let v=!1;return Promise.all([window.api.telemetry.getConfig(),window.api.telemetry.status()]).then(([d,C])=>{v||(s(d),o(C))}).catch(d=>{console.warn("[product-telemetry] load failed:",d==null?void 0:d.message)}),()=>{v=!0}},[]),!t||!n)return e.jsx(K,{title:"loading…"});const S=async v=>{u(null);try{const d=await window.api.telemetry.setConfig(v);s(d.config),o(d.status)}catch(d){u(d instanceof Error?d.message:String(d))}},m=v=>{S({...t,enabled:v})},N=v=>{S({...t,enabled:v.turnOff?!1:t.enabled,noticeAckedAt:new Date().toISOString()})},I=async()=>{await Re(t.installId)?(a("Copied"),setTimeout(()=>a("Copy"),1500)):ue.error("Could not copy install id to the clipboard")},h=async()=>{p(!0),j(null);try{const v=await window.api.telemetry.flushNow();j(`sent ${v.sent.length}, failed ${v.failed.length}`),R()}catch(v){j(v instanceof Error?v.message:String(v))}finally{p(!1)}},k=async()=>{if(f){w(!1);return}try{const v=await window.api.telemetry.recentRecords();y(v),w(!0)}catch(v){console.warn("[product-telemetry] recentRecords failed:",v instanceof Error?v.message:v)}},E=t.lastDailyFlushAt?new Date(t.lastDailyFlushAt).getTime()+ft:null;return e.jsxs("div",{className:"space-y-5","data-testid":"product-telemetry-section",children:[e.jsxs("header",{className:"space-y-1",children:[e.jsx("h2",{className:"text-fg text-base font-medium",children:"Product telemetry (bilko.run)"}),e.jsxs("p",{className:"text-fg-dim text-xs leading-relaxed",children:["Anonymous, strictly non-identifying usage/error reporting that helps improve this app. On by default; switchable off in one click. See"," ",e.jsx("span",{className:"font-mono",children:"session-manager-operations/architecture/telemetry.md"})," for the full data model."]})]}),!t.noticeAckedAt&&e.jsxs("section",{"data-testid":"telemetry-first-run-notice",className:"border border-accent rounded p-3 space-y-2 text-xs",children:[e.jsx("div",{className:"text-fg font-medium",children:"This app sends anonymous product telemetry"}),e.jsx("p",{className:"text-fg-dim leading-relaxed",children:"Collected: a coarse machine profile (OS/arch/app version, no hardware id), error and warning counts, and session counts — sent on start-up, after an update, and once a day."}),e.jsx("p",{className:"text-fg-dim leading-relaxed",children:"Never collected: prompts, transcripts, file paths, project names, email, or username."}),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[e.jsx("button",{onClick:()=>N({turnOff:!1}),className:"px-3 py-1 rounded bg-accent text-bg",children:"OK"}),e.jsx("button",{onClick:()=>N({turnOff:!0}),className:"px-3 py-1 rounded border border-line text-fg-dim hover:text-fg",children:"Turn off"})]})]}),e.jsxs("section",{className:"border border-line rounded p-3 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-fg",children:"Send anonymous product telemetry"}),e.jsx("div",{className:"text-fg-faint text-xs",children:"Sent on start-up, after an update, and once a day. Strictly anonymous — an install id only, never an email, name, or other identifier."})]}),e.jsx(Y,{checked:t.enabled,onChange:m,label:t.enabled?"on":"off"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"text-fg-dim text-xs",children:"Anonymous install id"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"text",readOnly:!0,value:t.installId,"aria-label":"Anonymous install identifier",className:"flex-1 bg-bg border border-line rounded px-2 py-1 text-fg font-mono text-xs"}),e.jsx("button",{onClick:I,className:"px-2 py-1 text-xs rounded border border-line text-fg-dim hover:text-fg",children:r})]})]}),e.jsxs("div",{className:"space-y-1 text-xs",children:[e.jsx("div",{className:"text-fg-faint",children:"Endpoint"}),e.jsx("div",{className:"font-mono text-fg-dim break-all",children:t.endpoint})]}),e.jsxs("div",{className:"space-y-1 text-xs",children:[e.jsx("div",{className:"text-fg-faint",children:"Send cadence"}),e.jsx("div",{className:"text-fg-dim",children:"on start-up, after an update, and once a day"})]}),i&&e.jsx("div",{className:"text-red-400 text-xs",children:i})]}),n.pendingCount>0&&n.sentCount===0&&e.jsxs("section",{"data-testid":"telemetry-never-delivered-warning",className:"border border-red-400 rounded p-3 text-xs space-y-1 text-red-400",children:[e.jsx("div",{className:"font-medium",children:"Never delivered"}),e.jsxs("div",{className:"leading-relaxed",children:[n.pendingCount," record",n.pendingCount===1?"":"s",' queued but none have ever been sent to bilko.run on this install. Check the endpoint/network, or click "Send now" below.']})]}),e.jsxs("section",{className:"border border-line rounded p-3 text-xs space-y-1.5",children:[e.jsx("div",{className:"text-fg-dim",children:"Runtime status"}),e.jsxs("div",{children:[e.jsx("span",{className:"text-fg-faint",children:"last send:"})," ",ce(n.lastFlushAt)]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-fg-faint",children:"next daily send due:"})," ",le(E?new Date(E).toISOString():null)]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-fg-faint",children:"queued records:"})," ",n.pendingCount]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-fg-faint",children:"delivered so far:"})," ",n.sentCount]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-fg-faint",children:"de-duplicated:"})," ",n.dedupedAppends]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-fg-faint",children:"evicted:"})," ",n.evictedCount]}),n.backlog&&e.jsxs("div",{className:"text-fg-faint",children:["last backlog drain (",n.backlog.reason,", ",le(n.backlog.ranAt),"):"," ",n.backlog.linesEnqueued," enqueued, ",n.backlog.linesConfirmed," confirmed,"," ",n.backlog.watermarksRewound," watermarks rewound"]}),n.lastError&&e.jsxs("div",{className:"text-red-400 break-words",children:[e.jsx("span",{className:"text-fg-faint",children:"last error:"})," ",n.lastError.message," ","(",ce(n.lastError.at),")"]})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{onClick:h,disabled:c,className:"px-3 py-1 text-xs rounded bg-accent text-bg disabled:opacity-50 disabled:cursor-not-allowed",children:c?"sending…":"Send now"}),b&&e.jsx("span",{className:"text-fg-faint text-xs",children:b})]}),e.jsxs("section",{className:"space-y-2",children:[e.jsx("button",{onClick:k,className:"px-3 py-1 text-xs rounded border border-line text-fg-dim hover:text-fg",children:f?"Hide last records":"Inspect last records sent"}),f&&e.jsx("pre",{"data-testid":"telemetry-inspector-json",className:"bg-bg border border-line rounded p-2 text-[11px] font-mono overflow-auto max-h-96 whitespace-pre-wrap",children:JSON.stringify(g??[],null,2)})]})]})}function _({children:t,right:s}){return e.jsxs("div",{className:"flex items-baseline justify-between mb-2.5",children:[e.jsx("span",{className:"text-[11.5px] font-bold uppercase tracking-[0.8px] text-fg-faint",children:t}),s]})}function D({kind:t="soft",icon:s,children:n,onClick:o,disabled:r,testId:a}){return e.jsxs("button",{type:"button","data-testid":a,onClick:o,disabled:r,className:`shrink-0 inline-flex items-center gap-2 rounded-lg px-3.5 py-2 text-[13px] font-semibold transition-colors disabled:opacity-50 ${t==="soft"?"bg-bg-hi border border-line text-fg hover:bg-bg":"text-fg-dim hover:text-fg"}`,children:[s&&e.jsx(H,{name:s,size:15}),n]})}function Q({icon:t,title:s,subtitle:n,badge:o,action:r,testId:a}){return e.jsxs("div",{"data-testid":a,className:"flex items-center gap-3.5 bg-bg-hi border border-line rounded-xl px-[18px] py-3.5",children:[e.jsx("span",{className:"w-[34px] h-[34px] rounded-lg bg-bg border border-line grid place-items-center text-fg-dim shrink-0",children:e.jsx(H,{name:t,size:17})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2.5 mb-0.5",children:[e.jsx("span",{className:"text-sm font-semibold text-fg truncate",children:s}),o]}),e.jsx("div",{className:"font-mono text-[11.5px] text-fg-faint truncate",children:n})]}),r]})}function je({onClick:t,disabled:s,testId:n,children:o="Revoke"}){return e.jsx("button",{"data-testid":n,onClick:t,disabled:s,className:"shrink-0 rounded-lg border border-line bg-bg text-accent px-3.5 py-1.5 text-[12.5px] font-semibold hover:bg-bg-hi disabled:opacity-50 transition-colors",children:o})}function ve({code:t,onConfirm:s,testId:n,codeTestId:o,confirmTestId:r,peer:a="browser"}){return e.jsxs("div",{"data-testid":n,className:"flex items-start gap-3.5 px-5 py-4 rounded-2xl border border-accent/40 bg-accent/[0.06]",children:[e.jsx("span",{className:"w-[38px] h-[38px] rounded-[11px] shrink-0 grid place-items-center bg-bg-hi text-accent",children:e.jsx(H,{name:"shield",size:20})}),e.jsxs("div",{className:"flex-1 min-w-0 text-sm text-fg",children:[e.jsx("strong",{className:"font-semibold",children:"Verify E2E session."})," Compare this code with the ",a," — they must match.",e.jsx("div",{"data-testid":o,className:"my-2 text-3xl font-mono tracking-[0.3em] text-center text-accent select-all",children:t}),e.jsx("p",{className:"text-[12.5px] text-fg-faint mb-3",children:"If the codes match, confirm below. Mutating commands are blocked until confirmed."}),e.jsx("button",{"data-testid":r,onClick:s,className:"rounded-lg bg-accent text-white px-4 py-2 text-[13px] font-semibold hover:opacity-90 transition-opacity",children:"Codes match — confirm"})]})]})}function W({children:t,testId:s}){return e.jsx("div",{"data-testid":s,className:"bg-bg-hi border border-line rounded-xl p-5 text-center text-[13.5px] text-fg-faint italic font-serif",children:t})}const yt=260;function jt({peerId:t,machineName:s,cwd:n,onClose:o}){const r=l.useRef(null),a=l.useRef(null),c=Z(i=>i.show),[p,b]=l.useState(!1);l.useEffect(()=>{const i=r.current;if(!i)return;const u=crypto.randomUUID();let g=!0,y=!1,f=!1;const w=(d,C)=>{g&&c("error",`Remote terminal ${d} failed: ${C instanceof Error?C.message:String(C)}`)},R=(d,C)=>window.api.remoteClient.send(t,d,C),S=new Ie.Terminal({fontFamily:'"IBM Plex Mono", JetBrains Mono, ui-monospace, Menlo, monospace',fontSize:ne.fontSize,lineHeight:1.2,cursorBlink:!0,allowProposedApi:!0,theme:Ae[ne.theme]}),m=new Te.FitAddon;S.loadAddon(m);const N=()=>{if(Pe(i.clientWidth,i.clientHeight))try{m.fit()}catch{}};S.open(i),N(),S.focus();const I=window.api.remoteClient.onEvent(d=>{if(d.peerId!==t)return;const C=d.payload??{};C.tabId===u&&(d.type==="event:pty:data"?typeof C.data=="string"&&S.write(C.data):d.type==="event:pty:exit"&&(y=!0,S.options.disableStdin=!0,S.write(`\r
|
|
3
|
-
\x1B[38;5;240m[remote session exited code=${C.exitCode??"?"}]\x1B[0m\r
|
|
4
|
-
`),b(!0)))}),h=S.onData(d=>{y||R("cmd:pty:write",{tabId:u,data:d}).catch(C=>w("write",C))}),k=S.onResize(({cols:d,rows:C})=>{y||R("cmd:pty:resize",{tabId:u,cols:d,rows:C}).catch(T=>w("resize",T))});R("cmd:pty:spawn",{tabId:u,cwd:n,cols:S.cols,rows:S.rows}).catch(d=>w("spawn",d)),a.current=()=>{f||(f=!0,R("cmd:pty:kill",{tabId:u}).catch(d=>w("kill",d)))};const E=()=>N();window.addEventListener("resize",E);const v=new ResizeObserver(()=>N());return v.observe(i),()=>{var d;window.removeEventListener("resize",E),v.disconnect(),I(),h.dispose(),k.dispose(),(d=a.current)==null||d.call(a),a.current=null,g=!1,S.dispose()}},[t,n,c]);const j=()=>{var i;(i=a.current)==null||i.call(a),o()};return e.jsxs("div",{"data-testid":"remote-terminal-panel",className:"bg-bg-hi border border-line rounded-xl overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 px-[18px] pt-3.5 pb-2",children:[e.jsxs("div",{className:"flex items-center gap-2.5 min-w-0",children:[e.jsx(_,{children:"Remote terminal"}),e.jsx(L,{tone:"accent",children:e.jsxs("span",{"data-testid":"remote-terminal-badge",children:["Remote: ",s]})}),p&&e.jsx(L,{tone:"dim",children:"exited"})]}),e.jsx(D,{kind:"ghost",onClick:j,testId:"remote-terminal-close",children:"Close"})]}),e.jsx("div",{ref:r,"data-testid":"remote-terminal-host",className:"w-full bg-bg",style:{height:yt}})]})}function de(t){return t instanceof Error?t.message:String(t)}function vt({peerId:t,machineName:s}){const n=Z(m=>m.show),[o,r]=l.useState([]),[a,c]=l.useState("loading"),[p,b]=l.useState(null),[j,i]=l.useState(""),[u,g]=l.useState(!1),y=l.useRef(0),f=l.useCallback(async()=>{const m=++y.current;c("loading");try{const N=await window.api.remoteClient.send(t,"cmd:sessions:load",{});if(m!==y.current)return;r(Array.isArray(N==null?void 0:N.tabs)?N.tabs:[]),c("ready")}catch(N){if(m!==y.current)return;c("error"),n("error",`Could not load sessions from ${s}: ${de(N)}`)}},[t,s,n]);l.useEffect(()=>(f(),()=>{y.current++}),[f]);const w=j.trim(),R=p!==null&&w.length>0&&!u,S=l.useCallback(async()=>{if(!(p===null||j.trim().length===0)){g(!0);try{await window.api.remoteClient.send(t,"cmd:chat:send",{tabId:p,prompt:j}),i("")}catch(m){n("error",`Could not send prompt to ${s}: ${de(m)}`)}finally{g(!1)}}},[t,s,p,j,n]);return e.jsxs("div",{"data-testid":"remote-sessions-panel",className:"flex flex-col gap-3",children:[e.jsx(_,{right:e.jsx(L,{tone:"accent",className:"",title:`Sessions on ${s}`,children:e.jsxs("span",{"data-testid":"remote-sessions-badge",children:["Remote: ",s]})}),children:"Remote sessions"}),e.jsx("div",{className:"flex justify-end",children:e.jsx(D,{icon:"history",testId:"remote-sessions-refresh",onClick:()=>{f()},disabled:a==="loading",children:"Refresh"})}),a==="loading"&&e.jsx(W,{testId:"remote-sessions-loading",children:"Loading sessions…"}),a==="error"&&e.jsxs(W,{testId:"remote-sessions-error",children:["Could not load sessions from ",s,"."]}),a==="ready"&&o.length===0&&e.jsxs(W,{testId:"remote-sessions-empty",children:["No sessions open on ",s,"."]}),a==="ready"&&o.map(m=>e.jsx(Q,{testId:`remote-session-${m.sessionId}`,icon:"terminal",title:m.label||m.cwd,subtitle:m.cwd,action:e.jsx(D,{kind:p===m.sessionId?"soft":"ghost",testId:`remote-session-select-${m.sessionId}`,onClick:()=>b(m.sessionId),children:p===m.sessionId?"Selected":"Select"})},m.sessionId)),a==="ready"&&o.length>0&&e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("textarea",{"data-testid":"remote-sessions-prompt",value:j,onChange:m=>i(m.target.value),rows:3,placeholder:p?`Prompt for the selected session on ${s}`:"Select a session first",className:"w-full rounded-lg bg-bg-hi border border-line px-3 py-2 text-[13px] text-fg placeholder:text-fg-faint"}),e.jsx("div",{className:"flex justify-end",children:e.jsx(D,{icon:"play",testId:"remote-sessions-send",onClick:()=>{S()},disabled:!R,children:"Send"})})]})]})}const wt="relay_client_auth_unavailable",X=t=>(t==null?void 0:t.message)||String(t);function Nt({peer:t,panel:s,onConnect:n,onRevoke:o,onTogglePanel:r,onConfirmSas:a}){const c=t.status==="authenticated",p=t.status==="failed"&&t.reason===wt,b=t.status==="connecting",j=new Date(t.pairedAt).toLocaleString(),i=(s==null?void 0:s.peerId)===t.peerId?s.kind:null;return e.jsxs("div",{className:"space-y-2","data-testid":"remote-machine-row",children:[e.jsx(Q,{testId:"remote-machine",icon:"terminal",title:t.machineName,badge:c?e.jsx(L,{tone:"default",className:"!text-sage !border-sage/40",children:"online"}):void 0,subtitle:`${t.peerId} · last seen ${j}`,action:e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[c?e.jsxs(e.Fragment,{children:[e.jsx(D,{testId:"remote-machine-terminal",icon:"terminal",onClick:()=>r(t.peerId,"terminal"),children:"Open terminal"}),e.jsx(D,{testId:"remote-machine-sessions",onClick:()=>r(t.peerId,"sessions"),children:"Sessions"})]}):!p&&t.status!=="pending_sas"?e.jsx(D,{testId:"remote-machine-connect",disabled:b,onClick:()=>n(t.peerId),children:b?"Connecting…":"Connect"}):null,e.jsx(je,{testId:"remote-machine-revoke",onClick:()=>o(t.peerId),children:"Revoke"})]})}),p&&e.jsx("p",{"data-testid":"remote-machine-unavailable",className:"text-[12.5px] leading-snug text-fg-faint",children:"The bilko.run relay does not support desktop clients yet"}),t.status==="pending_sas"&&t.sas&&e.jsx(ve,{peer:"other machine",testId:"remote-machine-sas",codeTestId:"remote-machine-sas-code",confirmTestId:"remote-machine-sas-confirm",code:t.sas,onConfirm:()=>a(t.peerId)}),i==="terminal"&&e.jsx(jt,{peerId:t.peerId,machineName:t.machineName,cwd:"",onClose:()=>r(t.peerId,"terminal")}),i==="sessions"&&e.jsx(vt,{peerId:t.peerId,machineName:t.machineName})]})}function kt(){const t=Z(i=>i.show),[s,n]=l.useState([]),[o,r]=l.useState(null),a=l.useCallback(async()=>{try{n(await window.api.remoteClient.list())}catch(i){t("error",X(i))}},[t]);l.useEffect(()=>{a();const i=window.api.remoteClient.onStatus(u=>{n(g=>g.map(y=>y.peerId===u.peerId?{...y,status:u.status,reason:u.reason,sas:u.sas}:y))});return()=>{i()}},[a]);const c=l.useCallback(async i=>{try{const u=await window.api.remoteClient.connect(i);n(g=>g.map(y=>y.peerId===i?{...y,status:u.status,reason:u.reason,sas:u.sas}:y))}catch(u){t("error",X(u))}},[t]),p=l.useCallback(async i=>{try{const u=await window.api.remoteClient.confirmSas(i);u.ok||t("error",u.reason??"SAS confirmation failed"),await a()}catch(u){t("error",X(u))}},[t,a]),b=l.useCallback(async i=>{try{await window.api.remoteClient.remove(i),r(u=>(u==null?void 0:u.peerId)===i?null:u),await a()}catch(u){t("error",X(u))}},[t,a]),j=l.useCallback((i,u)=>{r(g=>(g==null?void 0:g.peerId)===i&&g.kind===u?null:{peerId:i,kind:u})},[]);return e.jsxs("div",{"data-testid":"remote-machines",children:[e.jsx(_,{right:s.length>0?e.jsxs("span",{className:"text-[11.5px] text-fg-faint",children:[s.length," paired"]}):void 0,children:"Remote machines"}),s.length===0?e.jsx(W,{testId:"remote-machines-empty",children:"No machines paired yet."}):e.jsx("div",{className:"space-y-2",children:s.map(i=>e.jsx(Nt,{peer:i,panel:o,onConnect:c,onRevoke:b,onTogglePanel:j,onConfirmSas:p},i.peerId))})]})}function xe({label:t,hint:s,on:n,onChange:o,warn:r,disabled:a,first:c,testId:p}){return e.jsxs("div",{className:`flex items-center justify-between gap-4 px-[18px] py-[15px] ${c?"":"border-t border-rule"} ${a?"opacity-50":""}`,children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-sm font-semibold text-fg mb-0.5",children:t}),e.jsxs("div",{className:`text-[12.5px] leading-snug flex items-center gap-1.5 ${r?"text-honey-dark":"text-fg-faint"}`,children:[r&&e.jsx("span",{"aria-hidden":!0,children:"⚠"}),s]})]}),e.jsx("span",{"data-testid":p,className:"inline-flex",children:e.jsx(Y,{checked:n,onChange:a?()=>{}:o,disabled:a})})]})}function St({device:t,online:s,onRevoke:n,revoking:o}){const r=t.lastConnectedAt?new Date(t.lastConnectedAt).toLocaleString():`paired ${new Date(t.issuedAt).toLocaleDateString()}`;return e.jsx(Q,{testId:"settings-remote-device",icon:"wifi",title:t.deviceName,badge:s?e.jsx(L,{tone:"default",className:"!text-sage !border-sage/40",children:"online"}):void 0,subtitle:`${t.deviceId} · last seen ${r}`,action:e.jsx(je,{testId:"settings-remote-revoke",onClick:()=>n(t.deviceId),disabled:o})})}const M=t=>(t==null?void 0:t.message)||String(t);function Ct(){var se;const t=Z(x=>x.show),[s,n]=l.useState(null),[o,r]=l.useState(!0),[a,c]=l.useState(!1),[p,b]=l.useState(!1),[j,i]=l.useState("idle"),[u,g]=l.useState(""),[y,f]=l.useState(null),[w,R]=l.useState(!1),[S,m]=l.useState([]),[N,I]=l.useState(!1),h=l.useRef(null);l.useEffect(()=>{let x=!1;const A=()=>window.api.webRemote.getStatus().then($=>{x||n($)}).catch(()=>{});window.api.webRemote.getStatus().then($=>{x||(n($),r(!1))}).catch($=>{x||(t("error",`Remote status: ${M($)}`),r(!1))});const Se=window.api.webRemote.onStatus($=>n($)),Ce=window.api.webRemote.onTokenRevoked(()=>{t("warn","Remote device token was revoked. Re-pair to reconnect."),A()}),Ee=window.api.webRemote.onRevokedAll(({revokedCount:$})=>{t("info",`Panic: all ${$} device(s) revoked and sessions torn down.`),A()});return()=>{x=!0,Se(),Ce(),Ee()}},[t]),l.useEffect(()=>{if(j!=="enter-otp")return;const x=setTimeout(()=>{var A;return(A=h.current)==null?void 0:A.focus()},50);return()=>clearTimeout(x)},[j]);const k=async()=>n(await window.api.webRemote.getStatus()),E=async()=>{if(s){c(!0);try{const x=s.enabled?await window.api.webRemote.disable():await window.api.webRemote.enable();x&&x.ok===!1&&t("error",x.error||"Failed to change remote state."),await k()}catch(x){t("error",`Failed: ${M(x)}`)}finally{c(!1)}}},v=async()=>{if(s){b(!0);try{const x=s.remoteControlEnabled?await window.api.webRemote.disableControl():await window.api.webRemote.enableControl();x&&x.ok===!1&&t("error",x.error||"Failed to change command writes."),await k()}catch(x){t("error",`Failed: ${M(x)}`)}finally{b(!1)}}},d=async()=>{const x=u.trim().toUpperCase();if(!/^[A-Z0-9]{8}$/.test(x)){t("warn","Pairing code must be 8 alphanumeric characters.");return}i("pairing");try{const A=await window.api.webRemote.pair(x);if(!A.ok){t("error",A.error||"Pairing failed."),i("enter-otp");return}t("info","Device paired successfully."),g(""),i("idle"),await k()}catch(A){t("error",`Pairing error: ${M(A)}`),i("enter-otp")}},C=async x=>{f(x);try{const A=await window.api.webRemote.revokeDevice(x);if(!A.ok){t("error",A.error||"Revoke failed.");return}await k()}catch(A){t("error",`Revoke error: ${M(A)}`)}finally{f(null)}},T=async()=>{R(!0);try{const x=await window.api.webRemote.revokeAll();x.ok||t("error",x.error||"Panic revoke failed.")}catch(x){t("error",`Panic revoke error: ${M(x)}`)}finally{R(!1)}},ee=async()=>{if(N){I(!1);return}try{const x=await window.api.webRemote.auditTail(100);if(!x.ok){t("error",`Audit log: ${x.error||"unavailable"}`);return}m(x.lines??[]),I(!0)}catch(x){t("error",`Audit log: ${M(x)}`)}},U=async()=>{try{const x=await window.api.webRemote.confirmSas();x!=null&&x.ok||t("error",`SAS confirm failed: ${(x==null?void 0:x.error)??"unexpected state — reconnect the mobile app"}`)}catch(x){t("error",`SAS confirm failed: ${M(x)}`)}};if(o)return e.jsx("div",{className:"p-6 text-fg-faint text-sm",children:"Loading…"});const O=(s==null?void 0:s.enabled)??!1,F=(s==null?void 0:s.remoteControlEnabled)??!1,V=(s==null?void 0:s.connected)??!1,z=(s==null?void 0:s.e2eActive)??!1,we=(s==null?void 0:s.e2eAuthenticated)??!1,Ne=(s==null?void 0:s.e2eState)??"idle",te=(s==null?void 0:s.pendingSas)??null,G=(s==null?void 0:s.devices)??[],J=O&&V,ke=V?((se=G.reduce((x,A)=>A.lastConnectedAt&&(!x||(x.lastConnectedAt??"")<A.lastConnectedAt)?A:x,null))==null?void 0:se.deviceId)??null:null;return e.jsxs("div",{"data-testid":"settings-remote",className:"p-4 max-w-[760px] space-y-[22px]",children:[te&&e.jsx(ve,{testId:"settings-remote-sas",codeTestId:"settings-remote-sas-code",confirmTestId:"settings-remote-sas-confirm",code:te,onConfirm:U}),Ne==="failed"&&e.jsxs("div",{className:"flex items-center gap-3.5 px-5 py-4 rounded-2xl border border-[#eccdbe] bg-[#f8e8e0]",children:[e.jsx("span",{className:"w-4 h-4 rounded-full bg-accent text-white grid place-items-center text-[11px] font-bold shrink-0",children:"!"}),e.jsxs("div",{className:"text-[13px] text-[#9a3f1f]",children:[e.jsx("strong",{className:"font-semibold",children:"E2E key exchange failed."})," ",e.jsx("span",{className:"text-fg-dim",children:"The session key could not be established. Reconnect the mobile app to retry."})]})]}),e.jsxs("div",{className:`flex items-center gap-3.5 px-5 py-4 rounded-2xl border ${J?"border-[#e8cdb9] bg-[#f5e9df]":"border-line bg-bg-hi"}`,children:[e.jsx("span",{className:`w-[38px] h-[38px] rounded-[11px] shrink-0 grid place-items-center ${J?"bg-[#f0d9c8] text-accent":"bg-[#e4ebd6] text-sage"}`,children:e.jsx(H,{name:J?"wifi":"shield",size:20})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-[14.5px] font-semibold text-fg mb-0.5",children:J?"Remote control is active":O?"Remote control is idle":"Remote control is off"}),e.jsx("div",{className:"text-[13px] text-fg-dim leading-snug",children:J?"A web session can send commands to this machine. Revoke below if unexpected.":O?"The relay is on but no device is connected. Pair a device to begin.":"The relay connection is closed — no remote commands are accepted. Enable it below only when you need it."})]}),z&&we?e.jsx(L,{tone:"default",className:"!text-sage !border-sage/40",children:"E2E authenticated"}):z?e.jsx(L,{tone:"warn",children:"E2E · awaiting SAS"}):e.jsx(L,{tone:"dim",children:"relay only · not E2E yet"})]}),e.jsxs("div",{children:[e.jsx(_,{children:"Remote control"}),e.jsxs("div",{className:"bg-bg-hi border border-line rounded-2xl overflow-hidden",children:[e.jsx(xe,{first:!0,testId:"settings-remote-enable",label:"Allow remote control from the web",hint:"Master switch. When off, the relay refuses every connection.",on:O,disabled:a,onChange:()=>{a||E()}}),e.jsx(xe,{testId:"settings-remote-control",label:"Allow command writes (pty + scheduler)",hint:F?"A paired device can run shell commands and queue jobs on this machine.":"Paired devices can watch session output but cannot send commands.",warn:F,disabled:!O||p,on:F&&O,onChange:()=>{O&&!p&&v()}})]})]}),e.jsxs("div",{children:[e.jsx(_,{children:"Pair a device"}),j==="idle"?e.jsxs("div",{className:"flex items-center justify-between gap-4 bg-bg-hi border border-line rounded-2xl px-5 py-[18px]",children:[e.jsxs("div",{"data-testid":"settings-remote-pair-hint",className:"text-[13.5px] text-fg-dim leading-relaxed max-w-[420px]",children:["On your phone open ",e.jsx("strong",{className:"text-fg font-semibold",children:"bilko.run/projects/session-manager"}),", sign in, and tap"," ",e.jsx("strong",{className:"text-fg font-semibold",children:"Generate pairing code"}),". Enter the 8-character code here."]}),e.jsx(D,{testId:"settings-remote-pair-start",kind:"soft",icon:"link",onClick:()=>i("enter-otp"),children:"Pair Device…"})]}):e.jsxs("div",{className:"flex items-center gap-5 bg-bg-hi border border-accent/40 rounded-2xl px-6 py-[22px]",children:[e.jsx("span",{className:"w-[52px] h-[52px] rounded-xl bg-bg border border-line grid place-items-center text-accent shrink-0",children:e.jsx(H,{name:"link",size:24})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-[11.5px] font-bold uppercase tracking-[0.8px] text-fg-faint mb-2",children:"Enter the code from your phone"}),e.jsx("input",{ref:h,"data-testid":"settings-remote-otp",value:u,onChange:x=>g(x.target.value.toUpperCase().replace(/[^A-Z0-9]/g,"")),onKeyDown:x=>{x.key==="Enter"&&d()},maxLength:8,placeholder:"XXXXXXXX",disabled:j==="pairing",className:"w-full bg-transparent border-0 outline-none font-mono text-[30px] font-semibold tracking-[6px] text-fg placeholder:text-fg-faint/40 disabled:opacity-50"})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx(D,{testId:"settings-remote-pair-confirm",kind:"soft",onClick:d,disabled:j==="pairing"||u.length<8,children:j==="pairing"?"Pairing…":"Confirm"}),e.jsx(D,{kind:"ghost",onClick:()=>{i("idle"),g("")},disabled:j==="pairing",children:"cancel"})]})]})]}),e.jsxs("div",{children:[e.jsx(_,{right:G.length>0?e.jsxs("span",{className:"text-[11.5px] text-fg-faint",children:[G.length," paired"]}):void 0,children:"Paired devices"}),G.length===0?e.jsx(W,{children:"No devices paired yet."}):e.jsx("div",{className:"space-y-2",children:G.map(x=>e.jsx(St,{device:x,online:x.deviceId===ke,onRevoke:C,revoking:y===x.deviceId},x.deviceId))})]}),e.jsx(kt,{}),e.jsxs("div",{children:[e.jsx(_,{right:e.jsx("button",{"data-testid":"settings-remote-audit-toggle",onClick:ee,className:"text-[12px] text-fg-faint hover:text-fg-dim transition-colors",children:N?"Hide":"Show last 100 · 0600, stays on this machine"}),children:"Audit log"}),N&&e.jsx("div",{className:"bg-bg-hi border border-line rounded-xl overflow-auto max-h-64 mb-2",children:S.length===0?e.jsx("p",{className:"p-4 text-[12.5px] text-fg-faint",children:"No entries today."}):e.jsx("pre",{"data-testid":"settings-remote-audit",className:"p-4 text-[12px] text-fg-dim font-mono whitespace-pre-wrap leading-relaxed",children:S.join(`
|
|
5
|
-
`)})}),e.jsxs("p",{className:"text-[12px] text-fg-faint",children:["Full log at"," ",e.jsx("code",{className:"font-mono text-fg-faint",children:"~/.claude/session-manager/logs/remote-audit-YYYY-MM-DD.log"})," ","(0600, never leaves this machine)"]})]}),e.jsxs("div",{className:"flex items-center justify-between gap-4 bg-[#f8e8e0] border border-[#eccdbe] rounded-2xl px-5 py-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("span",{className:"w-4 h-4 rounded-full bg-accent text-white grid place-items-center text-[11px] font-bold shrink-0",children:"!"}),e.jsx("span",{className:"text-sm font-semibold text-[#9a3f1f]",children:"Panic — disconnect & revoke everything"})]}),e.jsx("div",{className:"text-[12.5px] text-fg-dim leading-snug max-w-[440px]",children:"Tears down every active session and invalidates all paired-device tokens. Devices must re-pair. Use if you suspect compromise."})]}),e.jsx("button",{"data-testid":"settings-remote-revoke-all",onClick:T,disabled:w,className:"shrink-0 rounded-lg bg-accent text-white px-[18px] py-2 text-[13px] font-semibold hover:opacity-90 disabled:opacity-50 transition-opacity",children:w?"Revoking…":"Revoke all"})]})]})}const Et={compact:"Compact",roomy:"Roomy"};function Rt(){const{model:t,setModel:s}=Oe(),{catalog:n}=De(null),{density:o,setDensity:r}=$e();return e.jsxs("div",{className:"p-4 max-w-3xl space-y-5 text-sm",children:[e.jsxs("header",{className:"space-y-1",children:[e.jsx("h2",{className:"text-fg text-base font-medium",children:"Session Manager preferences"}),e.jsx("p",{className:"text-fg-dim text-xs leading-relaxed",children:"Native app preferences, stored locally — not part of Claude Code's own settings."})]}),e.jsxs("section",{className:"border border-line rounded p-3 space-y-3",children:[e.jsxs("div",{className:"block space-y-1",children:[e.jsx("span",{className:"text-fg-dim text-xs",children:"Default model for raw sessions"}),e.jsx(ae,{options:Me(n),value:t,onChange:s,mono:!0}),e.jsx("span",{className:"text-fg-faint text-[11px]",children:"Used when opening a raw interactive session without an explicit per-launch override."})]}),e.jsxs("div",{className:"block space-y-1",children:[e.jsx("span",{className:"text-fg-dim text-xs",children:"Density"}),e.jsx(ae,{options:["compact","roomy"],value:o,onChange:a=>r(a),labels:Et}),e.jsx("span",{className:"text-fg-faint text-[11px]",children:"Compact tightens spacing across the app's chrome; Roomy is the default."})]})]})]})}function It({cwd:t}){const[s,n]=l.useState(!1),[o,r]=l.useState(!1),[a,c]=l.useState(!1),[p,b]=l.useState(!1);l.useEffect(()=>{var y,f;let g=!1;return n(!1),Promise.resolve((f=(y=window.api.promptSessions)==null?void 0:y.getWorktreeDisabled)==null?void 0:f.call(y,{cwd:t})).then(w=>{g||(r((w==null?void 0:w.disabled)??!1),c((w==null?void 0:w.disabled)??!1),n(!0))},()=>{g||n(!0)}),()=>{g=!0}},[t]);const j=s&&a!==o,i=()=>{var g,y;b(!0),Promise.resolve((y=(g=window.api.promptSessions)==null?void 0:g.setWorktreeDisabled)==null?void 0:y.call(g,{cwd:t,disabled:a})).then(f=>{r((f==null?void 0:f.disabled)??a),c((f==null?void 0:f.disabled)??a)}).catch(f=>ue.error(f instanceof Error?f.message:String(f))).finally(()=>b(!1))},u=()=>c(o);return e.jsxs("div",{"data-testid":"settings-epic-isolation",className:"border-b border-line bg-bg-elev px-3 py-2.5 text-[11.5px] leading-snug",children:[e.jsxs("label",{className:"flex items-start gap-2",children:[e.jsx("input",{type:"checkbox",checked:a,disabled:!s||p,onChange:g=>c(g.target.checked),"data-testid":"settings-epic-isolation-checkbox",className:"mt-0.5"}),e.jsxs("span",{children:[e.jsx("span",{className:"font-semibold text-fg",children:"Disable Epic worktree isolation for this project"}),e.jsxs("span",{className:"block text-fg-dim",children:["Off by default — each active Epic runs in its own isolated ",e.jsx("code",{children:"git worktree"})," (branch"," ",e.jsx("code",{children:"sm-epic/<id>"}),"), merged back to main at an explicit checkpoint. Turning this on makes every new Epic in this project run directly in the shared working tree instead, same as before this feature existed."]})]})]}),j&&e.jsx(pe,{dirty:j,busy:p,onSave:i,onRevert:u})]})}const me={user:{title:"Global settings",body:"This is the real ~/.claude/settings.json on disk — the same file the claude CLI reads on every session it starts. Edits apply machine-wide, to every project and every session."},project:{title:"Project settings",body:"This is the real <project>/.claude/settings.json on disk, checked into git. Edits apply to every current and future session in this project, for anyone who clones it."},local:{title:"Local settings",body:"This is the real <project>/.claude/settings.local.json on disk, gitignored. Edits apply to every current and future session in this project, on this machine only."}};function At(){const t=Le(),s=re(d=>d.tabs),n=re(d=>d.activeTabId),o=s.find(d=>d.id===n)??null,r=(o==null?void 0:o.cwd)??null,a=Fe(d=>d.navFace),c=l.useRef(!1),p=l.useRef(a),[b,j]=l.useState(()=>a==="project"&&r?"project":"user"),[i,u]=l.useState("effective");l.useEffect(()=>{if(p.current!==a){if(p.current=a,c.current){c.current=!1;return}j(a==="project"&&r?"project":"user")}},[a,r]),l.useEffect(()=>{a==="project"&&(i==="telemetry"||i==="remote"||i==="app")&&u("effective")},[a,i]);const g=d=>{c.current=!0,j(d)},y=Je(ie,t,r),f=y[b]??null,w=q(d=>d.files),R=q(d=>d.setDraft),S=q(d=>d.saveJson),m=q(d=>d.revert),[N,I]=l.useState(null),h=l.useMemo(()=>_e(Be(w,y)),[w,y]),k=(d,C,T)=>{var z;const U=y[T??b];if(!U)return;I(null);const O=((z=w[U])==null?void 0:z.draftRaw)??"";let F={};if(O.trim())try{F=JSON.parse(O)}catch{F={}}const V=Ue(F,d,C);R(U,JSON.stringify(V,null,2)+`
|
|
6
|
-
`)};if(!t)return e.jsx(K,{title:"loading…"});const E=f?w[f]:null,v=d=>d!=="user"&&!r;return e.jsx(ze,{toolbar:e.jsxs(e.Fragment,{children:[e.jsx(We,{options:[{key:"effective",label:"Guided"},{key:"tree",label:"Tree"},{key:"raw",label:"Raw"},...a==="home"?[{key:"telemetry",label:"Telemetry"},{key:"remote",label:"Phone remote"},{key:"app",label:"Session Manager"}]:[]],active:i,onChange:u}),i!=="telemetry"&&i!=="remote"&&i!=="app"&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"mx-2 text-fg-faint",children:"·"}),e.jsx(Ge,{scopes:ie.scopes,active:b,onChange:g,annotate:d=>{if(v(d))return{exists:!1};const C=y[d];if(!C)return null;const T=w[C];return{exists:(T==null?void 0:T.exists)??!1,dirty:(T==null?void 0:T.dirty)??!1}}}),e.jsx("span",{className:"ml-3 text-fg-faint truncate",children:i==="effective"?`overrides → ${f??"—"}`:f??"—"})]}),e.jsx("div",{className:"flex-1"}),e.jsx("a",{href:"https://code.claude.com/docs/en/settings",target:"_blank",rel:"noreferrer",className:"text-fg-faint hover:text-fg-dim underline-offset-2 hover:underline",children:"schema reference ↗"})]}),footer:i!=="telemetry"&&i!=="remote"&&i!=="app"&&f&&E?e.jsx(pe,{dirty:E.dirty,busy:E.busy,parseError:N||E.parseError,lastSavedAt:E.lastSavedAt,leading:E.exists?null:e.jsx("span",{children:"file will be created on save"}),onSave:async()=>{I(null);const d=await S(f);d.ok||I(d.error??"save failed")},onRevert:()=>{I(null),m(f)}}):null,children:i==="telemetry"?e.jsx(ht,{}):i==="remote"?e.jsx(Ct,{}):i==="app"?e.jsx(Rt,{}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{"data-testid":"settings-scope-note",className:"sticky top-0 z-10 border-b border-line bg-bg-elev px-3 py-2 text-[11.5px] leading-snug",children:[e.jsx("span",{className:"font-semibold text-fg",children:me[b].title}),e.jsx("span",{className:"mx-1.5 text-fg-faint",children:"·"}),e.jsx("span",{className:"text-fg-dim",children:me[b].body}),f&&e.jsx("span",{className:"ml-1.5 font-mono text-fg-faint",children:f})]}),b==="project"&&r&&e.jsx(It,{cwd:r}),v(b)?e.jsx(K,{title:"no active project",hint:"open a tab in a project directory to edit project or local settings"}):i==="effective"?e.jsx(tt,{node:h,targetScope:b,onOverride:k,schema:oe()}):i==="tree"?e.jsx(Ke,{node:h,targetScope:b,onOverride:k,schema:oe()}):f&&E?e.jsx(He,{path:f,value:E.draftRaw,onChange:d=>{I(null),R(f,d)}}):e.jsx(K,{title:"resolving…"})]})})}const Bt=l.memo(At);export{me as SETTINGS_SCOPE_NOTES,Bt as Settings};
|