@rubytech/create-maxy-code 0.1.198 → 0.1.203
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/package.json +2 -2
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +3736 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +3 -1
- package/payload/platform/scripts/check-architecture-skill-no-drift.mjs +67 -0
- package/payload/platform/scripts/check-no-esm-require.mjs +3 -0
- package/payload/platform/scripts/check-specialist-tool-surface.mjs +323 -0
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.js +7 -7
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +13 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +126 -7
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +9 -1
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.d.ts +2 -12
- package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.js +14 -67
- package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-path.d.ts +6 -0
- package/payload/platform/services/claude-session-manager/dist/jsonl-path.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-path.js +30 -0
- package/payload/platform/services/claude-session-manager/dist/jsonl-path.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +4 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +33 -3
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +88 -57
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts +19 -0
- package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-sidecar.js +42 -0
- package/payload/platform/services/claude-session-manager/dist/session-sidecar.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/systemd-spawn.d.ts +62 -0
- package/payload/platform/services/claude-session-manager/dist/systemd-spawn.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/systemd-spawn.js +173 -0
- package/payload/platform/services/claude-session-manager/dist/systemd-spawn.js.map +1 -0
- package/payload/platform/templates/agents/admin/IDENTITY.md +4 -0
- package/payload/platform/templates/agents/public/IDENTITY.md +1 -1
- package/payload/platform/templates/specialists/agents/coding-assistant.md +73 -0
- package/payload/server/public/assets/AdminShell-BcxEZnpu.js +1 -0
- package/payload/server/public/assets/{Checkbox-Bh3kwzxP.js → Checkbox-DL-HdT29.js} +1 -1
- package/payload/server/public/assets/{admin-BWzKAudL.js → admin-DMo5DWKH.js} +1 -1
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-Boys2mT1.js → architectureDiagram-Q4EWVU46-BoUw4oYz.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-CvHqp46r.js → blockDiagram-DXYQGD6D-DOscnO3m.js} +1 -1
- package/payload/server/public/assets/{brand-VQtREmts.css → brand-SZW-27T7.css} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-DiNQ95F6.js → c4Diagram-AHTNJAMY-aZ1IuZ_F.js} +1 -1
- package/payload/server/public/assets/channel-CzcSNxDm.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-9nS9-05M.js → chunk-336JU56O-DS3ksXBG.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-B2__9lRY.js → chunk-426QAEUC-BLRn2STO.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-R5F8rS0Z.js → chunk-4TB4RGXK-BrhOvJ01.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-B8HhJce-.js → chunk-5FUZZQ4R-BZZwZX5Q.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-Bjb08lbL.js → chunk-5PVQY5BW-YXZKnPCz.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-he0qCF3s.js → chunk-EDXVE4YY-DAMCJHKQ.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-BTArFW5l.js → chunk-ENJZ2VHE-DsD95Bqn.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-CoyIL4q_.js → chunk-ICPOFSXX-DxtrRClx.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-DjLEhNFe.js → chunk-OYMX7WX6-CN4kLK-H.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-tac2uvW1.js → chunk-U2HBQHQK-BPTv3Oj1.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-DIWD9i88.js → chunk-X2U36JSP-DxBry33v.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-Ac7ogADz.js → chunk-YZCP3GAM-BZ4N75oy.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-QgqDaY9-.js → chunk-ZZ45TVLE-Dqr161Q1.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DFOM3vCn.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-HplDfaL1.js +1 -0
- package/payload/server/public/assets/clone-G-2rqnSR.js +1 -0
- package/payload/server/public/assets/{dagre-D6qN4nkK.js → dagre-DtZ0wKkH.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-C6TRKOg0.js → dagre-KV5264BT-BPKhT-ZX.js} +1 -1
- package/payload/server/public/assets/{data-CaZbNF-j.js → data-D6IQdm0R.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-BVk_J8Pt.js → diagram-5BDNPKRD-CATnafi7.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-BdV1IgwS.js → diagram-G4DWMVQ6-ChZYQfji.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-OsvBkN6u.js → diagram-MMDJMWI5-DHW6kYd3.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-BQmKPyrb.js → diagram-TYMM5635-CnS4Zci8.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-ChEx5_3C.js → erDiagram-SMLLAGMA-DKYv2YWp.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-B7sf6AG3.js → flowDiagram-DWJPFMVM-BWvoZWlh.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-DbpSraax.js → ganttDiagram-T4ZO3ILL-CpCb-xKy.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-BnxDElDh.js → gitGraphDiagram-UUTBAWPF-CvHrDKQ-.js} +1 -1
- package/payload/server/public/assets/{graph-CBP5yppq.js → graph-PkZKVkWD.js} +1 -1
- package/payload/server/public/assets/{graph-labels-BsZNScfa.js → graph-labels-CWJy0O4w.js} +1 -1
- package/payload/server/public/assets/{graphlib-Dux06enE.js → graphlib-DjnyHqGy.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-BLWb6oKx.js → infoDiagram-42DDH7IO-D_MywcVn.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-AFiRuE6G.js → ishikawaDiagram-UXIWVN3A-N9m-f-Eb.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CxHBRGGu.js → journeyDiagram-VCZTEJTY-DE0q7uSM.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-CGugF0N8.js → kanban-definition-6JOO6SKY-Dj5hb9Bq.js} +1 -1
- package/payload/server/public/assets/{line-COFloj-X.js → line-C6ph0i4M.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-CxXuCDQf.js → mermaid-parser.core-BrfmEvCA.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-BRBNvNup.js → mermaid.core-DYnHKfDv.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-DarW5Wwq.js → mindmap-definition-QFDTVHPH-DaSaZfhR.js} +1 -1
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-CTokFAkN.js → pieDiagram-DEJITSTG-BAu9Ezbv.js} +1 -1
- package/payload/server/public/assets/{public-Bq-eOUu9.js → public-UKgkJxKv.js} +3 -3
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-BNawkg3I.js → quadrantDiagram-34T5L4WZ-DRsbL1Xd.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-CWnO56oR.js → requirementDiagram-MS252O5E-B9QcsXV6.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-D9c-EZfV.js → sankeyDiagram-XADWPNL6-DsZbvIlD.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-In5lxCT5.js → sequenceDiagram-FGHM5R23-BlT4O2N8.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-CYb5js-u.js → stateDiagram-FHFEXIEX-JFgk1K3Y.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-NXz27DaV.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Cje-BY9v.js → timeline-definition-GMOUNBTQ-DOsHw1ip.js} +1 -1
- package/payload/server/public/assets/{useSelectionMode-B_2EQ2CC.js → useSelectionMode-JDGvwvIk.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-BqeuoPr1.js → vennDiagram-DHZGUBPP-CQWIhqZY.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-DE7xAnoq.js → wardleyDiagram-NUSXRM2D-D5Fh7YVL.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-JE4x8YEZ.js → xychartDiagram-5P7HB3ND-C-tINQEs.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +6 -6
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +566 -256
- package/payload/server/public/assets/AdminShell-DPk5UgEJ.js +0 -1
- package/payload/server/public/assets/channel-BgwH_qhE.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CwdV1-c8.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CS_jtevB.js +0 -1
- package/payload/server/public/assets/clone-BTishuSs.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-z-TVJfRt.js +0 -1
- /package/payload/server/public/assets/{brand-CzeO4m4J.js → brand-SzZmKKjz.js} +0 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// Task 552 — non-PTY spawn primitive for claude scope units.
|
|
2
|
+
//
|
|
3
|
+
// Wraps `child_process.spawn` around `systemd-run --user --scope ...` so
|
|
4
|
+
// the manager allocates ZERO file descriptors per spawn (stdio: 'ignore',
|
|
5
|
+
// detached + unref). The previous `spawnPty` adapter wrapped node-pty
|
|
6
|
+
// around the same systemd-run argv, which opened a master pty fd in the
|
|
7
|
+
// manager process — one fd leaked per /rc-spawn click and one per
|
|
8
|
+
// rc-daemon respawn until V8 GC fired.
|
|
9
|
+
//
|
|
10
|
+
// This primitive is for spawns the manager never talks to: `/rc-spawn`
|
|
11
|
+
// (fire-and-forget, the route never writes back to the child) and the
|
|
12
|
+
// rc-daemon supervisor (stdout via journal, exit detection via
|
|
13
|
+
// systemctl). Channel-bridge spawns (`/spawn`, `:sessionId/input`,
|
|
14
|
+
// WhatsApp / public-agent / channel-pty-bridge) keep node-pty because
|
|
15
|
+
// they genuinely need bidirectional IO with the manager.
|
|
16
|
+
//
|
|
17
|
+
// Argv composition reuses `buildSystemdRunArgv` from systemd-scope.ts so
|
|
18
|
+
// the SIGHUP wrap, per-spawn unit token, slice membership, and
|
|
19
|
+
// `--setenv=KEY=VAL` env block are byte-identical with the PTY spawn
|
|
20
|
+
// path. The pid is read back via `systemctl --user show -p MainPID`
|
|
21
|
+
// once the scope activates — authoritative even if a future systemd
|
|
22
|
+
// version forks before execve.
|
|
23
|
+
import { spawn } from 'node:child_process';
|
|
24
|
+
import { buildSystemdRunArgv, defaultSystemctlRunner, scopeUnitName, stopScopeUnit, } from './systemd-scope.js';
|
|
25
|
+
const ACTIVE_STATES = new Set(['active', 'activating', 'reloading']);
|
|
26
|
+
/** Spawn `systemd-run --user --scope ... <claudeBin> <claudeArgs>` so the
|
|
27
|
+
* manager holds no file descriptors for the resulting claude process.
|
|
28
|
+
* Returns once MainPID is available; on activation timeout, rejects with
|
|
29
|
+
* a deterministic Error so the caller can log / restart. */
|
|
30
|
+
export async function systemdSpawn(p) {
|
|
31
|
+
const run = p.runSystemctl ?? defaultSystemctlRunner;
|
|
32
|
+
const spawnChild = p.spawnChild ?? defaultSpawnChild;
|
|
33
|
+
const activationTimeoutMs = p.activationTimeoutMs ?? 5_000;
|
|
34
|
+
const pollIntervalMs = p.activationPollIntervalMs ?? 50;
|
|
35
|
+
const wrapped = buildSystemdRunArgv({
|
|
36
|
+
unitToken: p.unitToken,
|
|
37
|
+
claudeBin: p.claudeBin,
|
|
38
|
+
claudeArgs: p.claudeArgs,
|
|
39
|
+
env: p.env,
|
|
40
|
+
cwd: p.cwd,
|
|
41
|
+
});
|
|
42
|
+
// Spawn systemd-run as a detached child with stdio:'ignore'. The manager
|
|
43
|
+
// process holds zero fds to it; user systemd owns the scope cgroup's
|
|
44
|
+
// lifetime. `detached: true` puts the child in its own process group so
|
|
45
|
+
// it survives manager exit (systemd already owns it once registered, but
|
|
46
|
+
// the detach is belt-and-braces against PG signal forwarding).
|
|
47
|
+
let child;
|
|
48
|
+
const errorBox = { err: null };
|
|
49
|
+
try {
|
|
50
|
+
child = spawnChild(wrapped.cmd, wrapped.args, {
|
|
51
|
+
cwd: p.cwd,
|
|
52
|
+
env: process.env,
|
|
53
|
+
stdio: 'ignore',
|
|
54
|
+
detached: true,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
throw new Error(`[systemd-spawn] spawn-failed unitToken=${p.unitToken} err=${err instanceof Error ? err.message : String(err)}`);
|
|
59
|
+
}
|
|
60
|
+
child.on('error', (err) => {
|
|
61
|
+
errorBox.err = err;
|
|
62
|
+
});
|
|
63
|
+
child.unref();
|
|
64
|
+
// Poll `systemctl show -p MainPID --value <unit>` until non-zero or
|
|
65
|
+
// timeout. systemd-run --scope registers with PID1 before execve'ing
|
|
66
|
+
// into the wrapped command; MainPID is the canonical pid of the
|
|
67
|
+
// scope's runner (claude), authoritative across any fork the
|
|
68
|
+
// systemd-run binary may introduce.
|
|
69
|
+
const unit = scopeUnitName(p.unitToken);
|
|
70
|
+
const deadline = Date.now() + activationTimeoutMs;
|
|
71
|
+
while (Date.now() < deadline) {
|
|
72
|
+
if (errorBox.err) {
|
|
73
|
+
throw new Error(`[systemd-spawn] child-error unitToken=${p.unitToken} err=${errorBox.err.message}`);
|
|
74
|
+
}
|
|
75
|
+
const r = run(['--user', 'show', '-p', 'MainPID', '--value', unit]);
|
|
76
|
+
if (r.exitCode === 0) {
|
|
77
|
+
const raw = r.stdout.trim();
|
|
78
|
+
if (raw && raw !== '0') {
|
|
79
|
+
const n = Number.parseInt(raw, 10);
|
|
80
|
+
if (Number.isFinite(n) && n > 0) {
|
|
81
|
+
return buildHandle(n, p.unitToken, run);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
await sleep(pollIntervalMs);
|
|
86
|
+
}
|
|
87
|
+
throw new Error(`[systemd-spawn] activation-timeout unitToken=${p.unitToken} timeoutMs=${activationTimeoutMs}`);
|
|
88
|
+
}
|
|
89
|
+
function buildHandle(pid, unitToken, run) {
|
|
90
|
+
const unit = scopeUnitName(unitToken);
|
|
91
|
+
return {
|
|
92
|
+
pid,
|
|
93
|
+
unitToken,
|
|
94
|
+
async waitForExit(opts) {
|
|
95
|
+
const interval = opts?.pollIntervalMs ?? 250;
|
|
96
|
+
while (true) {
|
|
97
|
+
const r = run(['--user', 'show', '-p', 'ActiveState', '--value', unit]);
|
|
98
|
+
const state = r.exitCode === 0 ? r.stdout.trim() : '';
|
|
99
|
+
// Empty state OR exit code 4 (unit not loaded) means the transient
|
|
100
|
+
// unit has been collected — treat as exited.
|
|
101
|
+
if (!state || !ACTIVE_STATES.has(state)) {
|
|
102
|
+
return readScopeExit(run, unit);
|
|
103
|
+
}
|
|
104
|
+
await sleep(interval);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
async readJournalTail(maxBytes) {
|
|
108
|
+
return readJournal(unit, maxBytes);
|
|
109
|
+
},
|
|
110
|
+
async stop() {
|
|
111
|
+
await stopScopeUnit(run, unitToken, { pid });
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function readScopeExit(run, unit) {
|
|
116
|
+
const r = run([
|
|
117
|
+
'--user',
|
|
118
|
+
'show',
|
|
119
|
+
'-p', 'Result',
|
|
120
|
+
'-p', 'ExecMainStatus',
|
|
121
|
+
'-p', 'ExecMainCode',
|
|
122
|
+
unit,
|
|
123
|
+
]);
|
|
124
|
+
if (r.exitCode !== 0) {
|
|
125
|
+
return { result: 'unknown', exitCode: null, code: null };
|
|
126
|
+
}
|
|
127
|
+
const fields = {};
|
|
128
|
+
for (const line of r.stdout.split('\n')) {
|
|
129
|
+
const eq = line.indexOf('=');
|
|
130
|
+
if (eq < 0)
|
|
131
|
+
continue;
|
|
132
|
+
fields[line.slice(0, eq)] = line.slice(eq + 1);
|
|
133
|
+
}
|
|
134
|
+
const statusRaw = fields.ExecMainStatus ?? '';
|
|
135
|
+
const status = statusRaw === '' ? null : Number.parseInt(statusRaw, 10);
|
|
136
|
+
return {
|
|
137
|
+
result: fields.Result || 'unknown',
|
|
138
|
+
exitCode: Number.isFinite(status) ? status : null,
|
|
139
|
+
code: fields.ExecMainCode || null,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
async function readJournal(unit, maxBytes) {
|
|
143
|
+
return new Promise((resolve) => {
|
|
144
|
+
let buf = '';
|
|
145
|
+
try {
|
|
146
|
+
const child = spawn('journalctl', ['--user', '-u', unit, '-n', '200', '--no-pager', '--output=cat'], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
147
|
+
child.stdout?.on('data', (chunk) => {
|
|
148
|
+
buf += chunk.toString('utf8');
|
|
149
|
+
if (buf.length > maxBytes * 2)
|
|
150
|
+
buf = buf.slice(buf.length - maxBytes);
|
|
151
|
+
});
|
|
152
|
+
child.on('error', () => resolve(''));
|
|
153
|
+
child.on('close', () => {
|
|
154
|
+
resolve(buf.length > maxBytes ? buf.slice(buf.length - maxBytes) : buf);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
resolve('');
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
function defaultSpawnChild(cmd, args, opts) {
|
|
163
|
+
const child = spawn(cmd, [...args], opts);
|
|
164
|
+
return {
|
|
165
|
+
pid: child.pid,
|
|
166
|
+
unref: () => child.unref(),
|
|
167
|
+
on: (event, cb) => { child.on(event, cb); },
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function sleep(ms) {
|
|
171
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=systemd-spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemd-spawn.js","sourceRoot":"","sources":["../src/systemd-spawn.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,8 @@ Your job is to do useful work for the operator. How useful you can be depends on
|
|
|
12
12
|
|
|
13
13
|
Before your first message, do reconnaissance: read what is known about the operator and their business, today's calendar, active projects, open work, recent conversations. Infer the domain from the plugins and skills available. Then lead with what you found, and follow with a proposal suited to where the operator is in their day. Ask only the questions you could not answer through investigation. You are expected to drive the day, not solicit instructions for it.
|
|
14
14
|
|
|
15
|
+
When a turn needs you to ground a claim about what the product is, how the platform is built, how plugins or skills or specialists work, how install or deploy runs, or any other product-architecture fact, load the platform-architecture skill and answer from its body. Cite the source URL printed above the block you drew from.
|
|
16
|
+
|
|
15
17
|
## Before you act
|
|
16
18
|
|
|
17
19
|
You may not act on a request until you know what is being asked, what is in scope and what is out, and what rules apply. When the operator's words are precise, all three are obvious and you act. When any is imprecise, stop and ask. Insist on the operator being precise and concise.
|
|
@@ -22,6 +24,8 @@ Your roster of installed specialists is loaded alongside this file as part of yo
|
|
|
22
24
|
|
|
23
25
|
The graph is your brain. The first read of any turn that needs to know something is against the graph; outside lookups happen only after the graph has confirmed it does not hold the answer, and anything new an outside lookup produces is written back the same turn. Greetings and pure interaction turns do not need this loop. When something worth remembering comes out of a conversation, hand the write off to the specialist who owns graph writes; direct writes from this seat are reserved for one-line updates against a node already in context whose classification is unambiguous.
|
|
24
26
|
|
|
27
|
+
Every factual claim you make in any turn, about the operator, their business, the product, the platform, the day, or the world, has a source you can name. The permissible sources are four: a graph read this session, a tool output returned this session, content the operator pasted into this conversation, and the body of the platform-architecture skill when it is loaded. Pretraining recall is not a source. If a claim does not trace to one of the four, you do not have it yet; read the graph, run the tool, load the skill, or ask the operator. This rule binds every factual sentence you emit, not only the ones about the graph.
|
|
28
|
+
|
|
25
29
|
When the operator asks for a previous workflow output by name, fetch the latest matching report directly rather than searching. Searching is for questions about the contents of reports, not for the reports themselves. When the operator asks how your understanding of a person, organisation, or concept has changed over time, walk the revision history of that entity and surface the deltas yourself.
|
|
26
30
|
|
|
27
31
|
## When the session ends
|
|
@@ -14,7 +14,7 @@ Three rules govern every turn. They are load-bearing — when they conflict with
|
|
|
14
14
|
|
|
15
15
|
*Failure symptoms:* unrequested summary, three-paragraph answer to a one-line question, pasting a raw tool result verbatim into chat.
|
|
16
16
|
|
|
17
|
-
**EVIDENCE-BASED.**
|
|
17
|
+
**EVIDENCE-BASED.** Every factual claim you make has a source you can name. The permissible sources are three: a graph read this session via `memory-search`, a tool output returned this session, and content the visitor pasted into this conversation. Pretraining recall is not a source — not for facts about the business, not for facts about the product, not for facts about the world that the graph or a tool could ground. The graph is the canonical store about this account; consult it before answering factual questions or embarking on activity. When the graph has no answer, say so plainly and offer to take a message — never fill the gap from training memory. You are read-only by design (see Boundaries); corrections to the graph are not your job — surface the gap so the operator can address it. *Failure symptoms:* factual claim without a prior graph read or tool output this turn, training-data fallback when the graph has the canonical version, invented fact dressed as a graph result.
|
|
18
18
|
|
|
19
19
|
The 4-step brain-first loop, every turn that needs information:
|
|
20
20
|
1. **Classify the question** — known entity, temporal fact, event, general knowledge, or none. The inbound gateway provides this as `retrievalClass` when available.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coding-assistant
|
|
3
|
+
description: "Shell commands, git operations, code repositories, file reads and edits, running tests and builds, and developer tooling. Delegate when the work needs a shell, touches a git repository, reads or edits source files on disk, runs tests or builds, or otherwise belongs in a developer terminal."
|
|
4
|
+
summary: "Runs shell commands, drives git repositories, and reads or edits code on your behalf — the specialist you reach for when the work belongs in a developer terminal."
|
|
5
|
+
model: claude-opus-4-8[1m]
|
|
6
|
+
tools: Bash, Read, Edit, Write, Skill, Grep, Glob, mcp__plugin_memory_memory__memory-search
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Coding Assistant
|
|
10
|
+
|
|
11
|
+
You execute shell, git, and code-editing work on the operator's device. Admin delegates each task to you with a concrete brief; you run the commands, return the results, and stop.
|
|
12
|
+
|
|
13
|
+
## Three rules
|
|
14
|
+
|
|
15
|
+
These three rules win when anything else in this prompt conflicts with them.
|
|
16
|
+
|
|
17
|
+
1. **Be precise.** Every claim has a source: a tool result, a log line, a file you read. No "likely", no "appears to".
|
|
18
|
+
2. **Be concise.** Three sentences or fewer. If you cannot answer in three, ask in five words.
|
|
19
|
+
3. **Show your evidence.** Gather evidence before forming a hypothesis. One measurement beats three guesses.
|
|
20
|
+
|
|
21
|
+
## Scope
|
|
22
|
+
|
|
23
|
+
You handle work that belongs in a developer terminal: shell commands, git operations (clone, pull, fetch, status, log, diff, branch, checkout, commit, push when admin explicitly asks), reading and editing source files on disk, running tests and builds, grepping codebases, and inspecting developer tooling output. Admin routes shell and code work here because the admin seat blocks `Bash`, `Write`, `Edit`, and `MultiEdit` directly.
|
|
24
|
+
|
|
25
|
+
The operator's machine is the surface — paths admin gives you resolve against the filesystem you are running on. If a brief names a path that does not exist, report the absence with the path admin gave you; do not search for a "close match".
|
|
26
|
+
|
|
27
|
+
## Out of scope
|
|
28
|
+
|
|
29
|
+
- Document authoring, PDF rendering, image generation, website publishing — those route to `content-producer`.
|
|
30
|
+
- Graph writes (memory-write, contact-create, work-create, schedule-event) — those route to `database-operator` or `personal-assistant`.
|
|
31
|
+
- Ingestion of documents, transcripts, or archives into the graph — that routes to `database-operator` or `archive-ingest-operator`.
|
|
32
|
+
- Web research and external lookups — those route to `research-assistant`.
|
|
33
|
+
- Messaging, scheduling, browser automation, tunnel and domain setup — those route to `personal-assistant`.
|
|
34
|
+
|
|
35
|
+
When a brief mixes coding work with one of the above (for example, "clone the repo and write a brochure from its README"), do the coding portion and hand the rest back to admin so it can dispatch the right specialist.
|
|
36
|
+
|
|
37
|
+
## Brain-first read before action
|
|
38
|
+
|
|
39
|
+
Before running a destructive or state-changing command (anything that writes to disk, mutates a git ref, installs packages, or removes files), confirm the target with one read — `git status`, `ls`, `Read`, or `Grep`. The admin's brief names the outcome; the read confirms you are acting on the right tree.
|
|
40
|
+
|
|
41
|
+
For lookups admin may have already saved (a repo path, a service name, a frequently-used directory), `memory-search` is available — search the graph before assuming the brief's path is the only one. The graph is the canonical store; the filesystem is the execution surface.
|
|
42
|
+
|
|
43
|
+
## Git operations
|
|
44
|
+
|
|
45
|
+
- Read-only commands (`status`, `log`, `diff`, `branch`, `show`, `ls-files`) are safe; run them without further confirmation.
|
|
46
|
+
- State-changing commands (`pull`, `fetch`, `merge`, `rebase`, `checkout`, `commit`, `reset`, `stash`) require the brief to name the repository and the desired outcome. Run them from inside the repository directory; never with `cd <repo> && git <cmd>` chained, since the chain forces a permission prompt.
|
|
47
|
+
- `push` is run only when admin explicitly asks. Never `push --force` unless admin's brief names that flag with reason.
|
|
48
|
+
- Never amend a commit unless admin asks. New commits are the default.
|
|
49
|
+
- Never run `git config` to mutate user identity or repo config.
|
|
50
|
+
|
|
51
|
+
## Editing files
|
|
52
|
+
|
|
53
|
+
`Read` the file before `Edit`. Edits target the file the operator names; do not refactor surrounding code, do not delete comments you did not author, do not add error handling or fallbacks the brief did not request. The doctrine is in this repo's `CLAUDE.md` files at every level above the file you are editing — read them when an edit touches a file you have not edited before in this session.
|
|
54
|
+
|
|
55
|
+
## Running commands
|
|
56
|
+
|
|
57
|
+
Use `Bash` for one command at a time when possible. Long pipelines and chained commands are fine when the chain expresses one logical operation; do not chain unrelated commands to "save a turn". When a command is long-running (a build, a test suite, a `git clone` of a large repo), run it in the foreground and report the result when it completes; the admin agent waits.
|
|
58
|
+
|
|
59
|
+
When a command exits non-zero, return the exit code and the relevant stderr verbatim. Do not retry the same command unless admin asks. Do not present a fallback as if the original request succeeded.
|
|
60
|
+
|
|
61
|
+
## Output contract
|
|
62
|
+
|
|
63
|
+
Return to the admin agent: what you ran (the commands, in order), the outcome (success or failure with the exit code), the relevant output (trimmed to what answers the brief), and any blockers. When the brief was "git pull", the outcome line is the `git pull` summary (`Already up to date.` or the fast-forward range). When the brief was a test run, the outcome line names how many tests passed, failed, and skipped.
|
|
64
|
+
|
|
65
|
+
Never include credentials, tokens, or `.env` contents in the response. If a command would print them, run a variant that does not.
|
|
66
|
+
|
|
67
|
+
## When a tool returns an error
|
|
68
|
+
|
|
69
|
+
Name the tool, what you tried, and what the error said. Do not retry the same tool on the same target inside one turn. If switching to another tool is the right move, say why the alternative should succeed where the first did not.
|
|
70
|
+
|
|
71
|
+
## Plain English
|
|
72
|
+
|
|
73
|
+
**The first tool call MUST be `Skill plainly`. Any prose tool call before the skill content is loaded into context is a contract violation.** Load `skill-load skillName=plainly` on the first turn and apply it to the prose payload returned to admin (the "what you did" line, the summary, the blocker description). It does not apply to command output you are quoting verbatim — those are byte-faithful relays, not prose.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{o as e}from"./chunk-DD-I1_y5.js";import{c as t,d as n,i as r,l as i,o as a,s as o,t as s}from"./brand-SzZmKKjz.js";var c=i(`bot`,[[`path`,{d:`M12 8V4H8`,key:`hb8ula`}],[`rect`,{width:`16`,height:`12`,x:`4`,y:`8`,rx:`2`,key:`enze0r`}],[`path`,{d:`M2 14h2`,key:`vft8re`}],[`path`,{d:`M20 14h2`,key:`4cs60a`}],[`path`,{d:`M15 13v2`,key:`1xurst`}],[`path`,{d:`M9 13v2`,key:`rq6x2g`}]]),l=i(`box`,[[`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`,key:`hh9hay`}],[`path`,{d:`m3.3 7 8.7 5 8.7-5`,key:`g66t2b`}],[`path`,{d:`M12 22V12`,key:`d0xqtd`}]]),u=i(`check`,[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]),d=i(`database`,[[`ellipse`,{cx:`12`,cy:`5`,rx:`9`,ry:`3`,key:`msslwz`}],[`path`,{d:`M3 5V19A9 3 0 0 0 21 19V5`,key:`1wlel7`}],[`path`,{d:`M3 12A9 3 0 0 0 21 12`,key:`mv7ke4`}]]),f=i(`download`,[[`path`,{d:`M12 15V3`,key:`m9g1x1`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}],[`path`,{d:`m7 10 5 5 5-5`,key:`brsn70`}]]),p=i(`external-link`,[[`path`,{d:`M15 3h6v6`,key:`1q9fwt`}],[`path`,{d:`M10 14 21 3`,key:`gplh6r`}],[`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`,key:`a6xqqp`}]]),m=i(`history`,[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}],[`path`,{d:`M12 7v5l4 2`,key:`1fdv2h`}]]),h=i(`info`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 16v-4`,key:`1dtifu`}],[`path`,{d:`M12 8h.01`,key:`e9boi3`}]]),g=i(`list-todo`,[[`path`,{d:`M13 5h8`,key:`a7qcls`}],[`path`,{d:`M13 12h8`,key:`h98zly`}],[`path`,{d:`M13 19h8`,key:`c3s6r1`}],[`path`,{d:`m3 17 2 2 4-4`,key:`1jhpwq`}],[`rect`,{x:`3`,y:`4`,width:`6`,height:`6`,rx:`1`,key:`cif1o7`}]]),_=i(`loader-circle`,[[`path`,{d:`M21 12a9 9 0 1 1-6.219-8.56`,key:`13zald`}]]),v=i(`log-out`,[[`path`,{d:`m16 17 5-5-5-5`,key:`1bji2h`}],[`path`,{d:`M21 12H9`,key:`dn1m92`}],[`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`,key:`1uf3rs`}]]),y=i(`menu`,[[`path`,{d:`M4 5h16`,key:`1tepv9`}],[`path`,{d:`M4 12h16`,key:`1lakjw`}],[`path`,{d:`M4 19h16`,key:`1djgab`}]]),b=i(`panel-right-open`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M15 3v18`,key:`14nvp0`}],[`path`,{d:`m10 15-3-3 3-3`,key:`1pgupc`}]]),x=i(`panel-right`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M15 3v18`,key:`14nvp0`}]]),S=i(`plus`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`M12 5v14`,key:`s699le`}]]),C=i(`refresh-cw`,[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]),ee=i(`share-2`,[[`circle`,{cx:`18`,cy:`5`,r:`3`,key:`gq8acd`}],[`circle`,{cx:`6`,cy:`12`,r:`3`,key:`w7nqdw`}],[`circle`,{cx:`18`,cy:`19`,r:`3`,key:`1xt0gg`}],[`line`,{x1:`8.59`,x2:`15.42`,y1:`13.51`,y2:`17.49`,key:`47mynk`}],[`line`,{x1:`15.41`,x2:`8.59`,y1:`6.51`,y2:`10.49`,key:`1n3mei`}]]),w=i(`users`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`path`,{d:`M16 3.128a4 4 0 0 1 0 7.744`,key:`16gr8j`}],[`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`,key:`kshegd`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}]]),T=i(`x`,[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]),E=e(n(),1),D=a(),O=`maxy-shell-side-px`;function k(){if(typeof window>`u`)return 0;let e=document.querySelector(`.platform > .artefact`)?.getBoundingClientRect();return e&&e.width>0?Math.round(e.width):0}function A(e){if(typeof window>`u`)return e;let t=window.innerWidth,n=Math.max(248,t-480-k());return Math.min(Math.max(e,248),n)}function j(){if(typeof window>`u`)return 264;try{let e=window.localStorage.getItem(O);if(!e)return 264;let t=parseInt(e,10);if(Number.isFinite(t)&&t>=248)return A(t)}catch{}return 264}function te({targetSelector:e=`.platform`}){let t=(0,E.useRef)(null),[n,r]=(0,E.useState)(()=>j()),i=(0,E.useRef)(n);(0,E.useEffect)(()=>{let t=document.querySelector(e);!t||!(t instanceof HTMLElement)||(t.style.setProperty(`--side-px`,`${n}px`),i.current=n)},[n,e]);let a=(0,E.useCallback)(()=>{r(e=>{let t=A(e);return t===e?e:t})},[]);(0,E.useEffect)(()=>{a(),window.addEventListener(`resize`,a);let t=document.querySelector(e),n=null;return t instanceof HTMLElement&&(n=new MutationObserver(a),n.observe(t,{attributes:!0,attributeFilter:[`data-artefact`,`class`]})),()=>{window.removeEventListener(`resize`,a),n?.disconnect()}},[a,e]);let o=e=>{e.preventDefault();let n=t.current;if(!n)return;n.setPointerCapture(e.pointerId),n.classList.add(`dragging`);let a=!1,o=e=>{a=!0,r(A(Math.round(e.clientX)))},s=()=>{if(n.releasePointerCapture(e.pointerId),n.classList.remove(`dragging`),window.removeEventListener(`pointermove`,o),window.removeEventListener(`pointerup`,s),!a)return;let t=i.current;try{window.localStorage.setItem(O,String(t))}catch{}console.info(`[admin-ui] sidebar-resize px=${t}`)};window.addEventListener(`pointermove`,o),window.addEventListener(`pointerup`,s)},s=()=>{let e=A(264);r(e);try{window.localStorage.removeItem(O)}catch{}console.info(`[admin-ui] sidebar-resize px=${e}`)};return(0,D.jsx)(`div`,{ref:t,className:`side-resize-handle`,role:`separator`,"aria-orientation":`vertical`,"aria-label":`Resize sidebar`,onPointerDown:o,onDoubleClick:s})}var M=`maxy-admin-session`,N=typeof BroadcastChannel<`u`;function P(e){if(typeof e!=`object`||!e)return!1;let t=e;return t.type===`rotation`&&typeof t.newKey==`string`&&t.newKey.length>0&&(t.surface===`chat`||t.surface===`graph`||t.surface===`data`||t.surface===`sessions`)&&typeof t.ts==`number`}function F(e){if(!N)return()=>{};let t=new BroadcastChannel(M),n=t=>{if(!P(t.data)){console.warn(`[admin-session-broadcast] outcome=received-malformed payload=${JSON.stringify(t.data)}`);return}e(t.data)};return t.addEventListener(`message`,n),()=>{t.removeEventListener(`message`,n),t.close()}}var I=`maxy-admin-session-key`;function L(e,t){return`${e}${e.includes(`?`)?`&`:`?`}session_key=${encodeURIComponent(t)}`}async function R(e){let t;try{t=await e.clone().json()}catch{return`parse-failed`}if(typeof t!=`object`||!t)return`unknown-401`;let n=t.code;return n===`session-missing`||n===`session-not-registered`||n===`session-expired-age`||n===`grant-expired`?n:`unknown-401`}function z(){try{return sessionStorage.getItem(I)}catch{return null}}function B(e){let{initialCacheKey:t,surface:n}=e,[r,i]=(0,E.useState)(t),a=(0,E.useRef)(t);(0,E.useEffect)(()=>{a.current=r},[r]),(0,E.useEffect)(()=>{t!==a.current&&(i(t),a.current=t,s(e=>e+1))},[t]);let[o,s]=(0,E.useState)(0),[c,l]=(0,E.useState)(null);(0,E.useEffect)(()=>F(e=>{let t=a.current.slice(0,8),r=e.newKey.slice(0,8);e.newKey!==a.current&&(console.log(`[admin-session-broadcast] outcome=received oldKey=${t} newKey=${r} surface=${n} senderSurface=${e.surface}`),i(e.newKey),s(e=>e+1),l(null))}),[n]);let u=(0,E.useCallback)(()=>{try{sessionStorage.removeItem(I)}catch{}window.location.href=`/`},[]);return{adminFetch:(0,E.useCallback)(async(e,t)=>{let r=a.current,o=L(e,r),c=await fetch(o,t);if(c.status!==401)return c;let d=await R(c);if(d===`session-missing`)return console.warn(`[useAdminFetch] outcome=redirect-to-login reason=${d} surface=${n} path=${e}`),u(),c;if(d!==`session-not-registered`)return console.warn(`[useAdminFetch] outcome=redirect-to-login reason=${d} surface=${n} path=${e}`),l({message:`Your admin session has expired. Click to reload and sign in.`,reason:d}),c;let f=z();if(!f||f===r)return console.warn(`[useAdminFetch] outcome=redirect-to-login reason=session-not-registered-no-fresh-key surface=${n} path=${e}`),l({message:`Your admin session was renewed in another tab. Click to reload.`,reason:`session-not-registered`}),c;i(f),a.current=f,s(e=>e+1),console.log(`[useAdminFetch] outcome=retry-after-rotation oldKey=${r.slice(0,8)} newKey=${f.slice(0,8)} surface=${n} path=${e}`);let p=L(e,f),m=await fetch(p,t);return m.status===401&&(console.warn(`[useAdminFetch] outcome=redirect-to-login reason=second-401-after-retry surface=${n} path=${e}`),l({message:`Your admin session has expired. Click to reload and sign in.`,reason:`session-not-registered`})),m},[u,n]),cacheKey:r,sessionRefetchNonce:o,banner:c,reloadToLogin:u}}var V=(0,E.createContext)(null);function H({cacheKey:e,onSessionExpired:t,surface:n,children:r}){let i=(0,E.useCallback)(async(r,i)=>{if(!e)return fetch(r,i);let a=L(r,e),o=await fetch(a,i);if(o.status!==401)return o;let s=await R(o),c=e.slice(-8);if(s===`session-not-registered`){let a=z();if(a&&a!==e){let e=L(r,a),o=await fetch(e,i);return o.status===401?(console.warn(`[admin-auth] outcome=session-expired-redirect code=second-401-after-retry path=${r} cacheKey=${c} surface=${n}`),t({code:`second-401-after-retry`,path:r}),o):o}}return console.warn(`[admin-auth] outcome=session-expired-redirect code=${s} path=${r} cacheKey=${c} surface=${n}`),t({code:s,path:r}),o},[e,t,n]);return(0,D.jsx)(V.Provider,{value:i,children:r})}function ne(){return(0,E.useContext)(V)}function re(e){let t=ne();return(0,E.useMemo)(()=>t||(async(t,n)=>fetch(e?L(t,e):t,n)),[t,e])}function U(e){let{businessName:t,onNavigate:n,onToggleSidebar:i,sidebarOpen:a,onLogout:c}=e,[l,f]=(0,E.useState)(!1),m=(0,E.useRef)(null),g=(0,E.useRef)(null),S=re(null),[C,w]=(0,E.useState)(null),[O,k]=(0,E.useState)(!1),[A,j]=(0,E.useState)(null),[te,M]=(0,E.useState)(null),[N,P]=(0,E.useState)(null),[F,I]=(0,E.useState)(``);(0,E.useEffect)(()=>{I(window.location.hostname.startsWith(`admin.`)?window.location.origin.replace(`admin.`,`public.`):window.location.origin)},[]),(0,E.useEffect)(()=>{if(!l)return;let e=e=>{m.current&&!m.current.contains(e.target)&&f(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[l]),(0,E.useEffect)(()=>{if(!l)return;let e=e=>{e.key===`Escape`&&f(!1)};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[l]),(0,E.useEffect)(()=>{l&&g.current?.focus()},[l]),(0,E.useEffect)(()=>{if(!l)return;let e=!1;return S(`/api/admin/version`).then(e=>e.json()).then(t=>{e||P(t)}).catch(e=>{console.error(`[admin/version] menu-open client fetch failed:`,e)}),()=>{e=!0}},[l,S]);let L=(0,E.useCallback)(()=>{f(e=>{let t=!e;return t&&console.info(`[admin-ui] header-menu-open`),t})},[]),R=(0,E.useCallback)(e=>{f(!1),n(e)},[n]),z=(0,E.useCallback)(async()=>{if(C!==null){w(null),M(null);return}k(!0),j(null);try{let e=await S(`/api/admin/agents`);if(!e.ok)throw Error(`Failed to load agents`);w((await e.json()).agents??[])}catch(e){console.error(`[admin/agents] list failed:`,e),j(e instanceof Error?e.message:String(e)),w([])}finally{k(!1)}},[C,S]),B=(0,E.useCallback)(e=>{M(null),w(t=>t?.filter(t=>t.slug!==e)??null),S(`/api/admin/agents/${encodeURIComponent(e)}`,{method:`DELETE`}).catch(e=>console.error(`[admin/agents] delete failed:`,e))},[S]),V=(0,E.useCallback)(()=>{f(!1),c()},[c]),H=t||s.productName;return(0,D.jsxs)(`header`,{className:`admin-header`,children:[(0,D.jsx)(`button`,{type:`button`,className:`admin-sidebar-toggle`,"aria-label":a?`Hide sidebar`:`Show sidebar`,title:a?`Hide sidebar`:`Show sidebar`,"aria-expanded":a,onClick:i,children:a?(0,D.jsx)(b,{size:20,strokeWidth:1.5}):(0,D.jsx)(x,{size:20,strokeWidth:1.5})}),(0,D.jsxs)(`div`,{className:`chat-header-label`,children:[(0,D.jsx)(`span`,{className:`chat-logo-btn`,"aria-hidden":`true`,children:(0,D.jsx)(`img`,{src:r,alt:``,className:`chat-logo`})}),(0,D.jsx)(`h1`,{className:`chat-tagline`,children:H})]}),(0,D.jsxs)(`div`,{className:`chat-burger-wrap`,ref:m,children:[(0,D.jsx)(`button`,{type:`button`,className:`admin-burger`,onClick:L,"aria-label":`Menu`,"aria-haspopup":`true`,"aria-expanded":l,children:(0,D.jsx)(y,{size:20})}),l&&(0,D.jsxs)(`div`,{className:`admin-menu`,role:`menu`,children:[(0,D.jsxs)(`button`,{ref:g,type:`button`,className:`chat-menu-item`,role:`menuitem`,onClick:()=>R(`data`),children:[(0,D.jsx)(d,{size:14}),` Data`]}),(0,D.jsxs)(`button`,{type:`button`,className:`chat-menu-item`,role:`menuitem`,onClick:()=>R(`graph`),children:[(0,D.jsx)(ee,{size:14}),` Graph`]}),(0,D.jsx)(`div`,{className:`chat-menu-divider`}),(0,D.jsxs)(`button`,{type:`button`,className:`chat-menu-item`,role:`menuitem`,onClick:z,children:[(0,D.jsx)(p,{size:14}),` Public`,O&&(0,D.jsx)(_,{size:12,className:`spin`})]}),C!==null&&(0,D.jsxs)(`div`,{className:`chat-menu-agents`,children:[A&&(0,D.jsx)(`span`,{className:`chat-menu-agent-error`,children:A}),C.length===0&&!A&&(0,D.jsx)(`span`,{className:`chat-menu-agent-empty`,children:`No public agents configured`}),C.map(e=>(0,D.jsxs)(`div`,{className:`chat-menu-item chat-menu-agent-item`,children:[(0,D.jsx)(`span`,{className:`agent-status-dot ${e.status}`}),(0,D.jsxs)(`span`,{className:`agent-text`,children:[(0,D.jsx)(`span`,{className:`agent-display-name`,children:e.displayName}),(0,D.jsxs)(`span`,{className:`agent-slug`,children:[`/`,e.slug]})]}),te===e.slug?(0,D.jsxs)(`span`,{className:`agent-actions agent-confirm`,children:[(0,D.jsx)(`button`,{type:`button`,className:`agent-action-btn agent-confirm-yes`,title:`Confirm delete`,onClick:()=>B(e.slug),children:(0,D.jsx)(u,{size:12})}),(0,D.jsx)(`button`,{type:`button`,className:`agent-action-btn agent-confirm-no`,title:`Cancel`,onClick:()=>M(null),children:(0,D.jsx)(T,{size:12})})]}):(0,D.jsxs)(`span`,{className:`agent-actions`,children:[(0,D.jsx)(`a`,{href:`${F}/${e.slug}`,target:`_blank`,rel:`noopener noreferrer`,className:`agent-action-btn`,title:`Open agent`,onClick:()=>f(!1),children:(0,D.jsx)(p,{size:12})}),(0,D.jsx)(`button`,{type:`button`,className:`agent-action-btn agent-delete-btn`,title:`Delete agent`,onClick:()=>M(e.slug),children:(0,D.jsx)(o,{size:12})})]})]},e.slug))]}),(0,D.jsx)(`div`,{className:`chat-menu-divider`}),(0,D.jsxs)(`div`,{className:`chat-menu-version chat-menu-version-passive`,children:[(0,D.jsx)(h,{size:14}),(0,D.jsxs)(`span`,{className:`version-installed`,children:[N?`v${N.installed}`:`…`,N&&!N.updateAvailable&&(0,D.jsx)(`span`,{className:`version-uptodate-dot`}),N?.updateAvailable&&(0,D.jsx)(`span`,{className:`version-update-dot`})]})]}),(0,D.jsxs)(`button`,{type:`button`,className:`chat-menu-item`,role:`menuitem`,onClick:V,children:[(0,D.jsx)(v,{size:14}),` Log out`]})]})]})]})}function ie(e,t,n=`data`){let r=`/api/admin/files/download?session_key=${encodeURIComponent(e)}&path=${encodeURIComponent(t)}`+(n===`data`?``:`&root=${encodeURIComponent(n)}`),i=document.createElement(`a`);i.href=r,i.rel=`noopener noreferrer`,document.body.appendChild(i),i.click(),i.remove()}var ae=`https://claude.ai/code`;function oe(e){let{businessName:n,cacheKey:r,role:i,userName:a,userAvatar:u,onSelectProjects:d,onSelectPeople:h,onSelectTasks:_,onSelectAgents:v,onCloseMobileDrawer:y,collapsed:b}=e,x=re(r),ee=s.productName,T=typeof a==`string`?a:a===null?`name unavailable`:n||ee,O=(T.trim().charAt(0)||`?`).toUpperCase(),[k,A]=(0,E.useState)(`artefacts`),[j,te]=(0,E.useState)([]),[M,N]=(0,E.useState)(!1),[P,F]=(0,E.useState)(null),[I,L]=(0,E.useState)(!1),[R,z]=(0,E.useState)(`all`),[B,V]=(0,E.useState)(null),[H,ne]=(0,E.useState)([]),[U,oe]=(0,E.useState)(!1),[W,G]=(0,E.useState)(null),[K,ce]=(0,E.useState)(!1),[q,le]=(0,E.useState)(!1),[ue,J]=(0,E.useState)(null),[Y,de]=(0,E.useState)(new Set),[fe,pe]=(0,E.useState)(new Set),[X,me]=(0,E.useState)(!1),he=(0,E.useCallback)(e=>{if(y(),!r){console.error(`[admin-ui] artefact-download-blocked id=${e.id} reason=no-cache-key`),V({message:`Session not ready — try again`,failed:!0});return}if(!e.downloadPath){console.error(`[admin-ui] artefact-download-blocked id=${e.id} reason=not-downloadable`),V({message:`${e.name} can’t be downloaded`,failed:!0});return}console.info(`[admin-ui] artefact-download id=${e.id} root=${e.downloadRoot??`data`} path=${e.downloadPath}`),ie(r,e.downloadPath,e.downloadRoot??`data`),V({message:`Downloading ${e.name}`,failed:!1})},[r,y]);(0,E.useEffect)(()=>{if(!B)return;let e=setTimeout(()=>V(null),2500);return()=>clearTimeout(e)},[B]);let Z=(0,E.useCallback)(async()=>{if(r){L(!0),F(null);try{let e=await x(`/api/admin/sidebar-artefacts`);if(!e.ok)throw Error(`status ${e.status}`);te((await e.json()).artefacts??[]),N(!0)}catch(e){let t=e instanceof Error?e.message:String(e);F(`Failed to load artefacts: ${t}`),console.error(`[admin-ui] sidebar-artefacts fetch failed: ${t}`)}finally{L(!1)}}},[r,x]);(0,E.useEffect)(()=>{!r||M||Z()},[r,M,Z]);let ge=()=>{A(`artefacts`),console.info(`[admin-ui] sidebar-nav surface=artefacts count=${M?j.length:0} collapsed=${b}`),M||Z()},Q=1.5,_e=()=>{console.info(`[admin-ui] sidebar-refresh surface=artefacts`),Z()},$=(0,E.useCallback)(async()=>{if(r){ce(!0),G(null);try{let e=await x(`/api/admin/sidebar-sessions`);if(!e.ok)throw Error(`status ${e.status}`);let t=await e.json();ne(t.sessions??[]),J(t.accountId??null),oe(!0)}catch(e){let t=e instanceof Error?e.message:String(e);G(`Failed to load sessions: ${t}`),console.error(`[admin-ui] sidebar-sessions fetch failed: ${t}`)}finally{ce(!1)}}},[r,x]),ve=()=>{A(`sessions`),console.info(`[admin-ui] sidebar-nav surface=sessions count=${U?H.length:0} collapsed=${b}`),U||$()},ye=()=>{console.info(`[admin-ui] sidebar-refresh surface=sessions`),$()},be=(0,E.useCallback)(async e=>{if(!fe.has(e.sessionId)){pe(t=>{let n=new Set(t);return n.add(e.sessionId),n});try{let t=await x(`/api/admin/session-rc-spawn`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sessionId:e.sessionId,name:e.title||e.sessionId})});if(!t.ok){let n=await t.json().catch(()=>({}));console.error(`[admin-ui] sidebar-session-resume-failed sessionId=${e.sessionId} status=${t.status} error=${n.error??`unknown`}`),V({message:`Resume failed: ${n.error??`status ${t.status}`}`,failed:!0});return}let n=await t.json();console.info(`[admin-ui] sidebar-session-resume sessionId=${e.sessionId} spawnedPid=${n.spawnedPid??`?`}`),y(),window.open(ae,`_blank`,`noopener,noreferrer`)}catch(t){let n=t instanceof Error?t.message:String(t);console.error(`[admin-ui] sidebar-session-resume-failed sessionId=${e.sessionId} error=${n}`),V({message:`Resume failed: ${n}`,failed:!0})}finally{pe(t=>{let n=new Set(t);return n.delete(e.sessionId),n})}}},[x,y,fe]),xe=(0,E.useCallback)(async()=>{if(!X){me(!0);try{let e=await x(`/api/admin/session-rc-spawn`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({})});if(!e.ok){let t=await e.json().catch(()=>({}));console.error(`[admin-ui] sidebar-new-session-failed status=${e.status} error=${t.error??`unknown`}`),V({message:`New session failed: ${t.error??`status ${e.status}`}`,failed:!0});return}let t=await e.json();console.info(`[admin-ui] sidebar-new-session-spawned spawnedPid=${t.spawnedPid??`?`}`),window.open(ae,`_blank`,`noopener,noreferrer`)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`[admin-ui] sidebar-new-session-failed error=${t}`),V({message:`New session failed: ${t}`,failed:!0})}finally{me(!1)}}},[x,X]),Se=(0,E.useCallback)(async(e,t)=>{if(e.stopPropagation(),!Y.has(t.sessionId)){de(e=>{let n=new Set(e);return n.add(t.sessionId),n});try{let e=await x(`/api/admin/session-delete`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sessionId:t.sessionId,projectDir:t.projectDir})});if(!e.ok){let n=await e.json().catch(()=>({}));console.error(`[admin-ui] sidebar-session-delete-failed sessionId=${t.sessionId} status=${e.status} error=${n.error??`unknown`}`),V({message:`Delete failed: ${n.error??`status ${e.status}`}`,failed:!0});return}let n=await e.json();console.info(`[admin-ui] sidebar-session-delete sessionId=${t.sessionId} pidKilled=${n.pidKilled??`?`} deleted=${n.deleted??`?`}`),ne(e=>e.filter(e=>e.sessionId!==t.sessionId)),$()}catch(e){let n=e instanceof Error?e.message:String(e);console.error(`[admin-ui] sidebar-session-delete-failed sessionId=${t.sessionId} error=${n}`),V({message:`Delete failed: ${n}`,failed:!0})}finally{de(e=>{let n=new Set(e);return n.delete(t.sessionId),n})}}},[x,Y,$]);return(0,D.jsxs)(`aside`,{className:`side`,children:[(0,D.jsx)(`div`,{className:`side-new-session-row`,children:(0,D.jsxs)(`button`,{type:`button`,className:`side-new-session`,onClick:xe,disabled:X,"aria-busy":X,children:[(0,D.jsx)(S,{size:14}),(0,D.jsx)(`span`,{children:X?`Spawning…`:`New session`})]})}),(0,D.jsxs)(`nav`,{className:`side-nav`,children:[(0,D.jsxs)(`button`,{type:`button`,className:`nav-row`,onClick:()=>{console.info(`[admin-ui] sidebar-nav surface=people`),h(),y()},children:[(0,D.jsx)(w,{size:20,strokeWidth:Q}),(0,D.jsx)(`span`,{className:`label`,children:`People`}),(0,D.jsx)(`span`,{className:`kbd`})]}),(0,D.jsxs)(`button`,{type:`button`,className:`nav-row`,onClick:()=>{console.info(`[admin-ui] sidebar-nav surface=agents`),v(),y()},children:[(0,D.jsx)(c,{size:20,strokeWidth:Q}),(0,D.jsx)(`span`,{className:`label`,children:`Agents`}),(0,D.jsx)(`span`,{className:`kbd`})]}),(0,D.jsxs)(`button`,{type:`button`,className:`nav-row`,onClick:()=>{console.info(`[admin-ui] sidebar-nav surface=projects`),d(),y()},children:[(0,D.jsx)(l,{size:20,strokeWidth:Q}),(0,D.jsx)(`span`,{className:`label`,children:`Projects`}),(0,D.jsx)(`span`,{className:`kbd`})]}),(0,D.jsxs)(`button`,{type:`button`,className:`nav-row`,onClick:()=>{console.info(`[admin-ui] sidebar-nav surface=tasks`),_(),y()},children:[(0,D.jsx)(g,{size:20,strokeWidth:Q}),(0,D.jsx)(`span`,{className:`label`,children:`Tasks`}),(0,D.jsx)(`span`,{className:`kbd`})]}),(0,D.jsxs)(`button`,{type:`button`,className:`nav-row${k===`artefacts`?` active`:``}`,onClick:ge,children:[(0,D.jsx)(t,{size:20,strokeWidth:Q}),(0,D.jsx)(`span`,{className:`label`,children:`Artefacts`}),(0,D.jsx)(`span`,{className:`kbd`})]}),(0,D.jsxs)(`button`,{type:`button`,className:`nav-row${k===`sessions`?` active`:``}`,onClick:ve,children:[(0,D.jsx)(m,{size:20,strokeWidth:Q}),(0,D.jsx)(`span`,{className:`label`,children:`Sessions`}),(0,D.jsx)(`span`,{className:`kbd`})]})]}),k===`artefacts`&&(0,D.jsxs)(`div`,{className:`side-list`,children:[(0,D.jsxs)(`div`,{className:`group-head`,children:[(0,D.jsx)(`span`,{children:`Artefacts`}),(0,D.jsxs)(`span`,{className:`group-head-meta`,children:[(0,D.jsx)(`button`,{type:`button`,className:`group-head-refresh`,title:`Refresh artefacts`,"aria-label":`Refresh artefacts`,onClick:_e,disabled:I,children:(0,D.jsx)(C,{size:12,className:I?`spinning`:void 0})}),(0,D.jsx)(`span`,{children:I?`…`:String(j.length)})]})]}),P&&(0,D.jsx)(`div`,{className:`conv`,style:{color:`var(--text-tertiary)`,cursor:`default`},children:P}),M&&!P&&j.length>0&&(()=>{let e=j.filter(e=>e.kind===`agent-template`).length,t=j.length-e;return(0,D.jsx)(`div`,{className:`artefact-filter-chips`,children:[{key:`all`,label:`All`,count:j.length},{key:`agent`,label:`Agents`,count:e},{key:`file`,label:`Files`,count:t}].map(e=>(0,D.jsxs)(`button`,{type:`button`,className:`artefact-filter-chip${R===e.key?` active`:``}`,onClick:()=>z(e.key),disabled:e.count===0&&e.key!==`all`,children:[e.label,(0,D.jsx)(`span`,{className:`artefact-filter-chip-count`,children:e.count})]},e.key))})})(),M&&!P&&j.length===0&&(0,D.jsx)(`div`,{className:`conv`,style:{color:`var(--text-tertiary)`,cursor:`default`},children:`No artefacts yet`}),j.filter(e=>R===`all`?!0:R===`agent`?e.kind===`agent-template`:e.kind!==`agent-template`).map(e=>{let n=e.kind===`agent-template`,r=n?c:t,i=Date.parse(e.updatedAt),a=Number.isFinite(i)?new Date(i).toLocaleString(void 0,{dateStyle:`medium`,timeStyle:`short`}):``,o=e.downloadPath!==null;return(0,D.jsxs)(`button`,{type:`button`,className:`conv`,onClick:()=>he(e),disabled:!o,style:o?void 0:{cursor:`default`},title:o?`Download ${e.name}`:`${e.name} can’t be downloaded`,children:[(0,D.jsx)(r,{size:14,className:`conv-icon`,"data-kind":n?`agent`:`file`,"aria-label":n?`agent template`:`file`}),(0,D.jsxs)(`span`,{className:`conv-stack`,children:[(0,D.jsx)(`span`,{className:`conv-name-line`,children:(0,D.jsx)(`span`,{className:`conv-name`,children:e.name})}),a&&(0,D.jsx)(`span`,{className:`conv-timestamp`,children:a})]}),o&&(0,D.jsx)(f,{size:12,className:`conv-rc-icon`,"aria-hidden":`true`})]},e.id)})]}),k===`sessions`&&(()=>{let e=q?H:H.filter(e=>!e.isSubagent),t=H.some(e=>e.isSubagent);return(0,D.jsxs)(`div`,{className:`side-list`,children:[(0,D.jsxs)(`div`,{className:`group-head`,children:[(0,D.jsx)(`span`,{children:`Sessions`}),(0,D.jsxs)(`span`,{className:`group-head-meta`,children:[(0,D.jsx)(`button`,{type:`button`,className:`group-head-refresh`,title:`Refresh sessions`,"aria-label":`Refresh sessions`,onClick:ye,disabled:K,children:(0,D.jsx)(C,{size:12,className:K?`spinning`:void 0})}),(0,D.jsx)(`span`,{children:K?`…`:String(e.length)})]})]}),ue&&(0,D.jsx)(`div`,{className:`side-account-id`,title:`This install's accountId. The first 8 characters match the truncated UUID label on the live Remote Control daemon entry in claude.ai/code.`,children:(0,D.jsx)(`code`,{children:ue})}),t&&(0,D.jsx)(`div`,{className:`artefact-filter-chips`,children:(0,D.jsx)(`button`,{type:`button`,className:`artefact-filter-chip${q?` active`:``}`,onClick:()=>le(e=>!e),title:q?`Hide subagent sessions`:`Show subagent sessions`,children:`Subagents`})}),W&&(0,D.jsx)(`div`,{className:`conv`,style:{color:`var(--text-tertiary)`,cursor:`default`},children:W}),U&&!W&&e.length===0&&(0,D.jsx)(`div`,{className:`conv`,style:{color:`var(--text-tertiary)`,cursor:`default`},children:`No sessions yet`}),e.map(e=>{let t=Date.parse(e.startedAt),n=Number.isFinite(t)?new Date(t).toLocaleString(void 0,{dateStyle:`medium`,timeStyle:`short`}):``,r=fe.has(e.sessionId),i=Y.has(e.sessionId);return(0,D.jsxs)(`div`,{className:`conv conv-with-actions`,children:[(0,D.jsxs)(`div`,{className:`conv-main-static`,children:[(0,D.jsx)(`span`,{className:`conv-live-dot`,"data-live":e.live?`1`:`0`,"aria-label":e.live?`live session`:`ended session`}),(0,D.jsxs)(`span`,{className:`conv-stack`,children:[(0,D.jsx)(`span`,{className:`conv-name-line`,children:(0,D.jsx)(`span`,{className:`conv-name`,children:e.title})}),n&&(0,D.jsx)(`span`,{className:`conv-timestamp`,children:n})]})]}),(0,D.jsxs)(`div`,{className:`conv-actions`,children:[(0,D.jsx)(`button`,{type:`button`,className:`conv-action`,onClick:()=>{be(e)},disabled:r||i,"aria-busy":r,"aria-label":`Resume session ${e.title} in claude.ai/code`,title:`Resume in a fresh local Remote Control PTY`,children:(0,D.jsx)(p,{size:12})}),(0,D.jsx)(`button`,{type:`button`,className:`conv-action conv-action-danger`,onClick:t=>{Se(t,e)},disabled:r||i,"aria-busy":i,"aria-label":`Delete session ${e.title}`,title:`Delete session (kills PID if live, removes JSONL)`,children:(0,D.jsx)(o,{size:12})})]})]},e.sessionId)})]})})(),(0,D.jsx)(se,{}),(0,D.jsxs)(`div`,{className:`side-foot`,children:[(0,D.jsx)(`div`,{className:`avatar`,children:u?(0,D.jsx)(`img`,{src:u,alt:T}):O}),(0,D.jsxs)(`div`,{className:`who`,children:[(0,D.jsx)(`span`,{className:`name`,children:T}),(0,D.jsx)(`span`,{className:`role`,children:i??`operator`})]})]}),B&&(0,D.jsx)(`div`,{className:`copy-toast${B.failed?` copy-toast-failed`:``}`,role:`status`,children:B.message})]})}var W=5e3;function se(){let[e,t]=(0,E.useState)(null);if((0,E.useEffect)(()=>{let e=!1,n=null;async function r(){try{let n=await fetch(`/api/admin/system-stats`);if(!n.ok){console.error(`[admin-ui] system-stats-fetch-failed status=${n.status}`);return}let r=await n.json();e||t(r)}catch(e){console.error(`[admin-ui] system-stats-fetch-failed reason=${e instanceof Error?e.message:String(e)}`)}}function i(){n===null&&(r(),n=setInterval(()=>{r()},W))}function a(){n!==null&&(clearInterval(n),n=null)}function o(){document.hidden?a():i()}return document.hidden||i(),document.addEventListener(`visibilitychange`,o),()=>{e=!0,a(),document.removeEventListener(`visibilitychange`,o)}},[]),!e||e.platform===`darwin`)return null;let n=e.cpuPct,r=e.memUsedPct,i=n!==null&&n>=.9,a=n!==null&&n>=.98,o=r!==null&&r>=.9,s=r!==null&&r>=.98,c=i||o,l=a||s,u=e=>e===null?`—`:`${Math.round(e*100)}%`,d=e=>{if(e===null)return{width:`0%`,background:`var(--text-tertiary)`};let t=Math.min(1,Math.max(0,e)),n=Math.round(140*(1-t));return{width:`${Math.round(t*100)}%`,background:`hsl(${n}, 65%, 45%)`}},f=[`system-stats`];return c&&f.push(`system-stats--warn`),l&&f.push(`system-stats--crit`),(0,D.jsxs)(`div`,{className:f.join(` `),role:`status`,"aria-label":`host CPU and RAM`,children:[(0,D.jsxs)(`div`,{className:`system-stats__metric`,children:[(0,D.jsxs)(`span`,{className:i?`system-stats__fig system-stats__fig--warn`:`system-stats__fig`,children:[`CPU `,u(n)]}),(0,D.jsx)(`div`,{className:`system-stats__bar`,children:(0,D.jsx)(`div`,{className:`system-stats__bar-fill`,style:d(n)})})]}),(0,D.jsxs)(`div`,{className:`system-stats__metric`,children:[(0,D.jsxs)(`span`,{className:o?`system-stats__fig system-stats__fig--warn`:`system-stats__fig`,children:[`RAM `,u(r)]}),(0,D.jsx)(`div`,{className:`system-stats__bar`,children:(0,D.jsx)(`div`,{className:`system-stats__bar-fill`,style:d(r)})})]})]})}var G=`admin-sidebar-collapsed`,K=`admin-sidebar-drawer-open`;function ce(){if(typeof window>`u`)return!1;try{return window.sessionStorage.getItem(G)===`1`}catch{return!1}}function q(e){if(!(typeof window>`u`))try{e?window.sessionStorage.setItem(G,`1`):window.sessionStorage.removeItem(G)}catch{}}function le(){if(typeof window>`u`)return!1;try{return window.sessionStorage.getItem(K)===`1`}catch{return!1}}function ue(e){if(!(typeof window>`u`))try{e?window.sessionStorage.setItem(K,`1`):window.sessionStorage.removeItem(K)}catch{}}var J=720;function Y(e){let{cacheKey:t,businessName:n,onLogout:r,userName:i,userAvatar:a,role:o,children:s,footer:c}=e,[l,u]=(0,E.useState)(()=>ce()),[d,f]=(0,E.useState)(()=>le()),[p,m]=(0,E.useState)(()=>typeof window<`u`&&window.matchMedia(`(max-width: ${J}px)`).matches);(0,E.useEffect)(()=>{if(typeof window>`u`)return;let e=window.matchMedia(`(max-width: ${J}px)`),t=e=>m(e.matches);return e.addEventListener(`change`,t),()=>e.removeEventListener(`change`,t)},[]);let h=(0,E.useCallback)(e=>{q(e),u(e)},[]),g=(0,E.useCallback)(e=>{ue(e),f(e)},[]);(0,E.useEffect)(()=>{if(typeof window>`u`)return;let e=window.location?.pathname??``;console.info(`[admin-ui] shell-mount route=${e} collapsed=${l} drawer=${d}`)},[]);let _=p?d:!l,v=(0,E.useCallback)(()=>{if(!(typeof window>`u`))if(window.matchMedia(`(max-width: ${J}px)`).matches){let e=d;console.info(`[admin-ui] header-sidebar-toggle from=${e?`open`:`closed`} mode=drawer`),g(!e)}else{let e=l;console.info(`[admin-ui] header-sidebar-toggle from=${e?`closed`:`open`} mode=collapse`),h(!e)}},[l,d,h,g]),y=(0,E.useCallback)(e=>{console.info(`[admin-ui] header-menu-nav target=${e}`),window.location.href=e===`data`?`/data`:`/graph`},[]),b={collapsed:l,mobileDrawerOpen:d,sidebarOpen:_,onToggleSidebar:v,setMobileDrawerOpen:g};return(0,D.jsxs)(`div`,{className:`admin-shell admin-page admin-shell-root`,children:[(0,D.jsx)(U,{businessName:n,onNavigate:y,onToggleSidebar:v,sidebarOpen:_,onLogout:r}),(0,D.jsxs)(`div`,{className:`platform${d?` menu-open`:``}${l?` sidebar-collapsed`:``}`,"data-artefact":`closed`,children:[(0,D.jsx)(oe,{businessName:n,cacheKey:t,role:o??null,userName:i,userAvatar:a??null,onSelectProjects:()=>{window.location.href=`/graph?label=Project`},onSelectPeople:()=>{window.location.href=`/graph?label=Person`},onSelectTasks:()=>{window.location.href=`/graph?label=Task`},onSelectAgents:()=>{window.location.href=`/graph?label=Agent`},onCloseMobileDrawer:()=>g(!1),collapsed:l,mobileDrawerOpen:d}),typeof s==`function`?s(b):s]}),d&&(0,D.jsx)(`div`,{className:`sidebar-backdrop menu-open`,"aria-hidden":`true`,onClick:()=>g(!1)}),c]})}export{te as a,C as c,f as d,d as f,B as i,S as l,ie as n,T as o,H as r,ee as s,Y as t,_ as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{o as e}from"./brand-
|
|
1
|
+
import{o as e}from"./brand-SzZmKKjz.js";var t=e();function n({checked:e,onChange:n,label:r,disabled:i}){return(0,t.jsxs)(`label`,{className:`maxy-checkbox${i?` maxy-checkbox--disabled`:``}`,children:[(0,t.jsx)(`input`,{type:`checkbox`,checked:e,onChange:e=>n(e.target.checked),disabled:i}),(0,t.jsx)(`span`,{className:`maxy-checkbox__box`,children:`✱`}),r&&(0,t.jsx)(`span`,{className:`maxy-checkbox__label`,children:r})]})}export{n as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{o as e}from"./chunk-DD-I1_y5.js";import{a as t,d as n,o as r,t as i,u as a}from"./brand-CzeO4m4J.js";import{a as o,r as s,t as c,u as l}from"./AdminShell-DPk5UgEJ.js";import{t as u}from"./Checkbox-Bh3kwzxP.js";import{r as d,t as f}from"./useSelectionMode-B_2EQ2CC.js";var p=a(),m=e(n(),1);new Set(`image/jpeg,image/png,image/gif,image/webp,application/pdf,text/plain,text/markdown,text/csv,text/html,text/calendar,application/zip,application/x-zip-compressed,audio/ogg,audio/opus,audio/mp4,audio/mpeg,audio/webm,audio/wav,.opus,.ogg,.m4a,.mp3,.wav,.webm`.split(`,`).filter(e=>!e.startsWith(`.`)));function h(e){switch(e){case`expanded`:return!0;case`collapsed`:return!1;default:return}}var g=`admin-landing-redirected`,_=`/graph`;function v(e){return e.appState===`chat`&&!e.alreadyRedirected}function y(){let[e,t]=(0,m.useState)(`loading`),[n,r]=(0,m.useState)(``),[i,a]=(0,m.useState)(``),[o,s]=(0,m.useState)(``),[c,l]=(0,m.useState)(!1),[u,d]=(0,m.useState)(!1),[f,p]=(0,m.useState)(!1),[y,b]=(0,m.useState)(!1),[x,S]=(0,m.useState)(!1),[C,w]=(0,m.useState)(null),[T,E]=(0,m.useState)(null),[D,O]=(0,m.useState)(void 0),[k,A]=(0,m.useState)(null),[j,M]=(0,m.useState)(void 0),[N,P]=(0,m.useState)(null),[F,I]=(0,m.useState)(null),[L,R]=(0,m.useState)([]),[z,B]=(0,m.useState)(!1),[V,H]=(0,m.useState)(void 0),U=(0,m.useRef)(void 0),[W,G]=(0,m.useState)(!1);(0,m.useEffect)(()=>{typeof window>`u`||window.location.hostname.startsWith(`admin.`)&&fetch(`/api/remote-auth/status`).then(e=>e.ok?e.json():null).then(e=>{e?.configured&&G(!0)}).catch(()=>{})},[]);let K=(0,m.useRef)(null),q=(0,m.useRef)(null);(0,m.useEffect)(()=>{async function e(){let e=null;try{e=sessionStorage.getItem(`maxy-admin-session-key`)}catch{}if(!e)return!1;try{let n=await fetch(`/api/admin/session?session_key=${encodeURIComponent(e)}`);if(n.status===401){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}return!1}if(!n.ok)return!1;let r=await n.json();w(r.session_key),I(r.sessionId??null),O(r.businessName),A(r.role??null),M(r.userName===void 0?null:r.userName),P(r.avatar??null);let i=h(r.thinkingView);return U.current=i,H(i),t(`chat`),!0}catch(e){return console.error(`[admin] session restore failed:`,e),!1}}async function n(r=2){try{let i=await fetch(`/api/health`);if(!i.ok){if(r>0)return await new Promise(e=>setTimeout(e,1500)),n(r-1);console.error(`[admin] health check returned ${i.status} after retries`),t(`set-pin`);return}let a=await i.json();if(!a.pin_configured){t(`set-pin`);return}if(!a.claude_authenticated){t(`connect-claude`);return}if(await e())return;t(`enter-pin`)}catch(e){if(r>0)return await new Promise(e=>setTimeout(e,1500)),n(r-1);console.error(`[admin] health check failed:`,e),t(`set-pin`)}}n()},[]),(0,m.useEffect)(()=>{e===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&E(e)}).catch(()=>{})},[e]),(0,m.useEffect)(()=>{if(typeof window>`u`)return;let t=!1;try{t=sessionStorage.getItem(g)===`1`}catch{}if(v({appState:e,alreadyRedirected:t})){try{sessionStorage.setItem(g,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${_}`),window.location.replace(_)}},[e]);let J=(0,m.useRef)(null);(0,m.useEffect)(()=>{if(e!==`chat`)return;let n=setInterval(async()=>{try{let e=await fetch(`/api/health`);if(e.ok){let n=await e.json();if(n.auth_status===`dead`||n.auth_status===`missing`){t(`connect-claude`);return}}}catch{}if(C)try{let e=await fetch(`/api/admin/session?session_key=${encodeURIComponent(C)}`);if(e.status!==401)return;let t=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${t}`),J.current?.()}catch{}},300*1e3);return()=>clearInterval(n)},[e,C]),(0,m.useEffect)(()=>{e===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&t(`enter-pin`)}).catch(()=>{})},[e]);async function Y(e,n){d(!0);try{let i=await fetch(`/api/admin/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:e,...n?{accountId:n}:{}})});if(!i.ok){s((await i.json().catch(()=>({}))).error||`Invalid PIN`);return}let a=await i.json();if(a.accounts&&!a.session_key){console.log(`[admin] account picker shown: userId=${a.userId} accountCount=${a.accounts.length}`),R(a.accounts),t(`account-picker`);return}w(a.session_key),I(a.sessionId??null),O(a.businessName),A(a.role??null),M(a.userName===void 0?null:a.userName),P(a.avatar??null);let o=h(a.thinkingView);if(U.current=o,H(o),n)try{sessionStorage.setItem(`maxy-account-id`,n)}catch{}try{sessionStorage.setItem(`maxy-admin-session-key`,a.session_key)}catch{}r(``),t(`chat`)}catch(e){console.error(`[admin] connection error:`,e),s(`Could not connect.`)}finally{d(!1),B(!1)}}let X=(0,m.useCallback)(async e=>{if(e.preventDefault(),u)return;s(``);let a=i.trim();if(!a){s(`Please enter your name.`);return}if(n.length<4){s(`PIN must be at least 4 characters.`);return}let o=n;d(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:o,name:a})});if(!e.ok){let n=await e.json().catch(()=>({}));if(e.status===409){console.log(`[admin] PIN already configured — re-checking health`);try{let e=await fetch(`/api/health`);if(e.ok){let r=await e.json();r.pin_configured&&r.claude_authenticated?t(`enter-pin`):r.pin_configured?t(`connect-claude`):s(n.error||`Failed to set PIN.`)}else t(`enter-pin`)}catch{t(`enter-pin`)}return}s(n.error||`Failed to set PIN.`);return}let n=await fetch(`/api/health`);if((n.ok?await n.json():null)?.claude_authenticated){await Y(o);return}r(``),t(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),s(`Could not connect.`)}finally{d(!1)}},[n,u,i]),Z=(0,m.useCallback)(async e=>{e.preventDefault(),s(``),await Y(n)},[n]),Q=(0,m.useCallback)(async()=>{S(!0);try{await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`logout`})}),w(null),A(null),M(void 0),P(null);try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}t(`connect-claude`)}finally{S(!1)}},[]),$=(0,m.useCallback)(()=>{w(null),A(null),M(void 0),P(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(`maxy-account-id`),sessionStorage.removeItem(g)}catch{}r(``),s(``),t(`enter-pin`)},[]);return(0,m.useEffect)(()=>{J.current=$},[$]),{appState:e,setAppState:t,pin:n,setPin:r,operatorName:i,setOperatorName:a,pinError:o,setPinError:s,showPin:c,setShowPin:l,pinLoading:u,authPolling:f,setAuthPolling:p,authLoading:y,setAuthLoading:b,disconnecting:x,cacheKey:C,setCacheKey:w,claudeInfo:T,setClaudeInfo:E,businessName:D,role:k,userName:j,userAvatar:N,sessionId:F,setSessionId:I,accounts:L,accountPickerLoading:z,expandAll:V,setExpandAll:H,expandAllDefaultRef:U,remoteAuthEnabled:W,pinInputRef:K,setPinFormRef:q,handleSetPin:X,handleLogin:Z,handleAccountSelect:(0,m.useCallback)(async e=>{B(!0),s(``),await Y(n,e)},[n]),handleDisconnect:Q,handleLogout:$,handleChangePin:(0,m.useCallback)(async()=>{if(!n){s(`Enter your current PIN first.`);return}d(!0),s(``);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify({currentPin:n})});if(!e.ok){s((await e.json().catch(()=>({error:`Incorrect PIN.`}))).error||`Incorrect PIN.`);return}r(``),s(``),t(`set-pin`)}catch(e){console.error(`[admin-auth] change pin failed:`,e),s(e instanceof Error?e.message:String(e))}finally{d(!1)}},[n])}}var b=r();function x({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,m.useRef)([]);function s(e,r){r.key===`Backspace`?(r.preventDefault(),t[e]?n(t.slice(0,e)+t.slice(e+1)):e>0&&(n(t.slice(0,e-1)+t.slice(e)),o.current[e-1]?.focus())):r.key===`ArrowLeft`&&e>0?o.current[e-1]?.focus():r.key===`ArrowRight`&&e<5?o.current[e+1]?.focus():r.key===`Enter`&&(r.preventDefault(),r.currentTarget.form?.requestSubmit())}function c(e,i){let a=i.nativeEvent.data;if(!a||!/^\d$/.test(a))return;let s=t.split(``);for(s[e]=a;s.length<e;)s.push(``);let c=s.join(``).replace(/\D/g,``).slice(0,6);n(c),c.length===6?r?.(c):e<5&&o.current[e+1]?.focus()}function l(e){e.preventDefault();let t=e.clipboardData.getData(`text`).replace(/\D/g,``).slice(0,6);t&&(n(t),t.length===6?r?.(t):o.current[t.length]?.focus())}return(0,b.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,b.jsx)(`input`,{ref:t=>{o.current[r]=t,r===0&&e&&(e.current=t)},type:`text`,inputMode:`numeric`,className:`pin-box${t[r]?` pin-box-filled`:``}`,value:t[r]?i?t[r]:`•`:``,onKeyDown:e=>s(r,e),onInput:e=>c(r,e),onPaste:l,onFocus:e=>e.target.select(),autoFocus:a&&r===0,autoComplete:`off`,maxLength:1,"aria-label":`PIN digit ${r+1}`},r))})}function S(e){let{pin:n,setPin:r,showPin:a,setShowPin:o,pinLoading:s,pinError:c,pinInputRef:l,setPinFormRef:f,onSubmit:p,operatorName:m,setOperatorName:h}=e;return(0,b.jsx)(`div`,{className:`connect-page`,children:(0,b.jsxs)(`div`,{className:`connect-content`,children:[(0,b.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,b.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,i.productName]}),(0,b.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,i.productName,` who you are, then choose a PIN.`]}),(0,b.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,b.jsxs)(`div`,{className:`pin-input-row`,children:[(0,b.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:m,onChange:e=>h(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,b.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,b.jsxs)(`div`,{className:`pin-input-row`,children:[(0,b.jsx)(x,{inputRef:l,value:n,onChange:r,onComplete:()=>{},showPin:a}),(0,b.jsx)(d,{variant:`send`,type:`submit`,disabled:!n||!m.trim(),loading:s,"aria-label":`Set PIN`,children:(0,b.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,b.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,b.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,b.jsx)(u,{checked:a,onChange:()=>o(e=>!e),label:`Show PIN`})]}),c&&(0,b.jsx)(`p`,{className:`admin-pin-error`,children:c})]})})}function C(e){let{pin:n,setPin:r,showPin:a,setShowPin:o,pinLoading:s,pinError:c,pinInputRef:l,onSubmit:f,onChangePin:p,remoteAuthEnabled:m,onSignOutRemote:h}=e;return(0,b.jsxs)(`div`,{className:`connect-page`,children:[m&&h&&(0,b.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:h,children:`Sign out`}),(0,b.jsxs)(`div`,{className:`connect-content`,children:[(0,b.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,b.jsx)(`h1`,{className:`connect-title`,children:i.productName}),(0,b.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,b.jsxs)(`div`,{className:`pin-input-row`,children:[(0,b.jsx)(x,{inputRef:l,value:n,onChange:r,onComplete:()=>{},showPin:a,autoFocus:!0}),(0,b.jsx)(d,{variant:`send`,type:`submit`,disabled:!n,loading:s,children:(0,b.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,b.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,b.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,b.jsxs)(`div`,{className:`pin-options`,children:[(0,b.jsx)(u,{checked:a,onChange:()=>o(e=>!e),label:`Show PIN`}),(0,b.jsx)(d,{type:`button`,variant:`ghost`,onClick:p,children:`Change PIN`})]})]}),c&&(0,b.jsx)(`p`,{className:`admin-pin-error`,children:c})]})]})}function w(e){let{accounts:n,loading:r,error:a,onSelect:o}=e;return(0,b.jsx)(`div`,{className:`connect-page`,children:(0,b.jsxs)(`div`,{className:`connect-content`,children:[(0,b.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,b.jsx)(`h1`,{className:`connect-title`,children:i.productName}),(0,b.jsx)(`p`,{className:`connect-subtitle`,children:`Select an account`}),(0,b.jsx)(`div`,{className:`account-picker-list`,children:n.map(e=>(0,b.jsxs)(`button`,{className:`account-picker-card`,onClick:()=>o(e.accountId),disabled:r,type:`button`,children:[(0,b.jsx)(`span`,{className:`account-picker-name`,children:e.businessName||e.accountId}),(0,b.jsx)(`span`,{className:`account-picker-role`,children:e.role}),r&&(0,b.jsx)(l,{className:`account-picker-spinner`,size:16})]},e.accountId))}),a&&(0,b.jsx)(`p`,{className:`admin-pin-error`,children:a})]})})}function T(e){let{authPolling:n,setAuthPolling:r,authLoading:a,setAuthLoading:o,pinError:s,setPinError:c,setAppState:l}=e,[u,f]=(0,m.useState)(!1),[p,h]=(0,m.useState)(!1);async function g(){h(!0),c(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`launch-browser`})})).json();e.launched?f(!0):e.error&&c(e.error)}catch(e){console.error(`[admin] browser launch error:`,e),c(`Could not launch browser.`)}h(!1)}async function _(){o(!0),c(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){r(!0),f(!0),o(!1);for(let e=0;e<120;e++)if(await new Promise(e=>setTimeout(e,2e3)),(await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`wait`})})).json()).authenticated){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),l(`enter-pin`);return}c(`Timed out waiting for sign-in. Try again.`),r(!1)}else e.error&&c(e.error)}catch(e){console.error(`[admin] auth flow error:`,e),c(`Could not start auth flow.`)}o(!1)}async function v(){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),r(!1),c(``)}return n||u?(0,b.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,b.jsxs)(`header`,{className:`chat-header`,style:{paddingBottom:`12px`,flexShrink:0,position:`relative`,maxWidth:`680px`,width:`100%`,margin:`0 auto`,padding:`24px 20px 12px`},children:[n?(0,b.jsx)(`button`,{onClick:v,style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Cancel`,children:`✕`}):(0,b.jsx)(`button`,{onClick:()=>f(!1),style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Close browser`,children:`✕`}),(0,b.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,b.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,b.jsx)(`p`,{className:`chat-intro`,children:n?`Sign in and authorize in the browser below.`:`Open your email or prepare your accounts, then sign in.`}),!n&&(0,b.jsx)(`div`,{style:{marginTop:`12px`},children:(0,b.jsx)(d,{variant:`primary`,onClick:_,disabled:a,children:a?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})})]}),(0,b.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:(0,b.jsx)(`iframe`,{src:`/vnc-viewer.html`,style:{flex:1,width:`100%`,minHeight:0,border:`none`,background:`#111`,display:`block`},title:`Claude Sign-in`})}),s&&(0,b.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:s})]}):(0,b.jsx)(`div`,{className:`connect-page`,children:(0,b.jsxs)(`div`,{className:`connect-content`,children:[(0,b.jsxs)(`div`,{className:`connect-logos`,children:[(0,b.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,b.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,b.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,b.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,b.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,b.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,b.jsx)(`span`,{className:`connect-logo-label`,children:i.productName})]})]}),(0,b.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,i.productName]}),(0,b.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,b.jsx)(d,{variant:`primary`,onClick:_,disabled:a,children:a?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,b.jsx)(`p`,{style:{marginTop:`6px`,fontSize:`11px`,color:`#999`,maxWidth:`300px`,textAlign:`center`,lineHeight:`1.4`},children:`First time? You may need to sign into your email and Anthropic account in the browser before connecting.`}),(0,b.jsx)(`button`,{onClick:g,disabled:p,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:p?`Launching…`:`Open browser first`}),s&&(0,b.jsx)(`p`,{className:`admin-pin-error`,children:s})]})})}function E({onOpen:e}){return(0,b.jsx)(`footer`,{className:`admin-footer`,children:(0,b.jsxs)(`div`,{className:`powered-by`,role:`button`,tabIndex:0,onClick:e,onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),e())},"aria-label":`Powered by Claude Code — show details`,children:[(0,b.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`powered-by-icon`}),(0,b.jsx)(`span`,{children:`Powered by Claude Code`})]})})}function D(e){if(e<60)return`${e}s`;let t=Math.floor(e/60),n=e%60;return n>0?`${t}m ${n}s`:`${t}m`}function O(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function k(e){let{show:t,onClose:n,claudeInfo:r,messages:i,sessionElapsed:a,sessionId:o,cacheKey:s}=e,[c,l]=(0,m.useState)(null);if(!t)return null;let u=i.flatMap(e=>e.events?.filter(e=>e.type===`usage`)??[]),d=u.at(-1),p=d?.peak_request_pct==null?d?.context_window?Math.round((d.input_tokens+d.cache_creation_tokens+d.cache_read_tokens)/d.context_window*100):0:Math.round(d.peak_request_pct*100),h=u.reduce((e,t)=>e+t.input_tokens+t.cache_creation_tokens+t.cache_read_tokens+t.output_tokens,0),g=i.flatMap(e=>e.events?.filter(e=>e.type===`rate_limit`)??[]).at(-1),_=u.reduce((e,t)=>e+(t.total_cost_usd??0),0),v=r?.account?.subscriptionType,y=e=>{let t=e*1e3-Date.now();if(t<=0)return`now`;let n=Math.floor(t/36e5),r=Math.floor(t%36e5/6e4);return n>0?`${n}h ${r}m`:`${r}m`};return(0,b.jsx)(`div`,{className:`claude-info-overlay`,onClick:n,children:(0,b.jsxs)(`div`,{className:`claude-info-modal`,onClick:e=>e.stopPropagation(),children:[(0,b.jsxs)(`div`,{className:`claude-info-header`,children:[(0,b.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`claude-info-icon`}),(0,b.jsx)(`span`,{children:`Claude Code`}),(0,b.jsx)(`button`,{className:`claude-info-close`,onClick:n,"aria-label":`Close`,children:`✕`})]}),(0,b.jsxs)(`div`,{className:`claude-info-section`,children:[(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Version`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:r?r.version:`…`})]}),(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Email`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:r?.account?.email??`…`})]})]}),(v||g||_>0)&&(0,b.jsxs)(`div`,{className:`claude-info-section`,children:[v&&(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Plan`}),(0,b.jsx)(`span`,{className:`claude-info-value`,style:{textTransform:`capitalize`},children:v})]}),g&&(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Usage`}),(0,b.jsxs)(`span`,{className:`claude-info-value`,children:[Math.round(g.utilization*100),`%`]})]}),(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Resets in`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:y(g.resetsAt)})]}),g.isUsingOverage&&(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Overage`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:`Active`})]})]}),_>0&&(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Session cost`}),(0,b.jsxs)(`span`,{className:`claude-info-value`,children:[`$`,_<.01?_.toFixed(4):_.toFixed(2)]})]})]}),(0,b.jsxs)(`div`,{className:`claude-info-section`,children:[(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Model`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:r?.model??`…`})]}),(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Context used`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:p>0?`${p}%`:`—`})]}),(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Tokens`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:h>0?O(h):`—`})]}),(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Session`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:D(a)})]}),(o||s)&&(()=>{let e=o??s??``;return(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Session`}),(0,b.jsx)(`button`,{type:`button`,className:`claude-info-value claude-info-id-copy`,title:`${e} (${o?`flushed`:`pre-flush`}) — click to copy`,onClick:async()=>{l(await f(e)?`copied`:`failed`),setTimeout(()=>l(null),1200)},children:c===`copied`?`copied ✓`:c===`failed`?`copy failed ✕`:`${e.slice(0,8)}…`})]})})()]})]})})}function A(){let e=y(),[t,n]=(0,m.useState)(!1);(0,m.useEffect)(()=>{if(!t)return;let e=e=>{e.key===`Escape`&&n(!1)};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[t]);let r=(0,m.useCallback)(async()=>{let t=e.claudeInfo!=null;if(n(!0),t){console.info(`[admin-ui] claude-info-open cached=true ms=0`);return}let r=Date.now();try{let t=await fetch(`/api/admin/claude-info`);if(t.ok){let n=await t.json();e.setClaudeInfo(n)}console.info(`[admin-ui] claude-info-open cached=false ms=${Date.now()-r}`)}catch(e){console.error(`[admin-ui] claude-info-fetch-failed ms=${Date.now()-r} error="${e instanceof Error?e.message:String(e)}"`)}},[e]),i=(0,m.useCallback)(({code:t,path:n})=>{console.warn(`[admin-auth] outcome=chat-tab-logout-on-401 code=${t} path=${n}`),e.handleLogout()},[e]);return e.appState===`loading`?(0,b.jsx)(`div`,{className:`connect-page`}):e.appState===`set-pin`?(0,b.jsx)(S,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,setPinFormRef:e.setPinFormRef,onSubmit:e.handleSetPin,operatorName:e.operatorName,setOperatorName:e.setOperatorName}):e.appState===`connect-claude`?(0,b.jsx)(T,{authPolling:e.authPolling,setAuthPolling:e.setAuthPolling,authLoading:e.authLoading,setAuthLoading:e.setAuthLoading,pinError:e.pinError,setPinError:e.setPinError,setAppState:e.setAppState}):e.appState===`enter-pin`?(0,b.jsx)(C,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,onSubmit:e.handleLogin,onChangePin:e.handleChangePin,remoteAuthEnabled:e.remoteAuthEnabled,onSignOutRemote:e.handleLogout}):e.appState===`account-picker`?(0,b.jsx)(w,{accounts:e.accounts,loading:e.accountPickerLoading,error:e.pinError,onSelect:e.handleAccountSelect}):(0,b.jsx)(s,{cacheKey:e.cacheKey,onSessionExpired:i,surface:`chat`,children:(0,b.jsx)(c,{cacheKey:e.cacheKey,businessName:e.businessName,sessionId:e.sessionId,onLogout:e.handleLogout,userName:e.userName,userAvatar:e.userAvatar,role:e.role,footer:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(E,{onOpen:r}),(0,b.jsx)(k,{show:t,onClose:()=>n(!1),claudeInfo:e.claudeInfo,messages:[],sessionElapsed:0,sessionId:e.sessionId,cacheKey:e.cacheKey})]}),children:()=>(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(o,{}),(0,b.jsx)(`main`,{})]})})})}(0,p.createRoot)(document.getElementById(`root`)).render((0,b.jsx)(A,{}));
|
|
1
|
+
import{o as e}from"./chunk-DD-I1_y5.js";import{a as t,d as n,o as r,t as i,u as a}from"./brand-SzZmKKjz.js";import{a as o,r as s,t as c,u as l}from"./AdminShell-BcxEZnpu.js";import{t as u}from"./Checkbox-DL-HdT29.js";import{r as d,t as f}from"./useSelectionMode-JDGvwvIk.js";var p=a(),m=e(n(),1);new Set(`image/jpeg,image/png,image/gif,image/webp,application/pdf,text/plain,text/markdown,text/csv,text/html,text/calendar,application/zip,application/x-zip-compressed,audio/ogg,audio/opus,audio/mp4,audio/mpeg,audio/webm,audio/wav,.opus,.ogg,.m4a,.mp3,.wav,.webm`.split(`,`).filter(e=>!e.startsWith(`.`)));function h(e){switch(e){case`expanded`:return!0;case`collapsed`:return!1;default:return}}var g=`admin-landing-redirected`,_=`/graph`;function v(e){return e.appState===`chat`&&!e.alreadyRedirected}function y(){let[e,t]=(0,m.useState)(`loading`),[n,r]=(0,m.useState)(``),[i,a]=(0,m.useState)(``),[o,s]=(0,m.useState)(``),[c,l]=(0,m.useState)(!1),[u,d]=(0,m.useState)(!1),[f,p]=(0,m.useState)(!1),[y,b]=(0,m.useState)(!1),[x,S]=(0,m.useState)(!1),[C,w]=(0,m.useState)(null),[T,E]=(0,m.useState)(null),[D,O]=(0,m.useState)(void 0),[k,A]=(0,m.useState)(null),[j,M]=(0,m.useState)(void 0),[N,P]=(0,m.useState)(null),[F,I]=(0,m.useState)(null),[L,R]=(0,m.useState)([]),[z,B]=(0,m.useState)(!1),[V,H]=(0,m.useState)(void 0),U=(0,m.useRef)(void 0),[W,G]=(0,m.useState)(!1);(0,m.useEffect)(()=>{typeof window>`u`||window.location.hostname.startsWith(`admin.`)&&fetch(`/api/remote-auth/status`).then(e=>e.ok?e.json():null).then(e=>{e?.configured&&G(!0)}).catch(()=>{})},[]);let K=(0,m.useRef)(null),q=(0,m.useRef)(null);(0,m.useEffect)(()=>{async function e(){let e=null;try{e=sessionStorage.getItem(`maxy-admin-session-key`)}catch{}if(!e)return!1;try{let n=await fetch(`/api/admin/session?session_key=${encodeURIComponent(e)}`);if(n.status===401){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}return!1}if(!n.ok)return!1;let r=await n.json();w(r.session_key),I(r.sessionId??null),O(r.businessName),A(r.role??null),M(r.userName===void 0?null:r.userName),P(r.avatar??null);let i=h(r.thinkingView);return U.current=i,H(i),t(`chat`),!0}catch(e){return console.error(`[admin] session restore failed:`,e),!1}}async function n(r=2){try{let i=await fetch(`/api/health`);if(!i.ok){if(r>0)return await new Promise(e=>setTimeout(e,1500)),n(r-1);console.error(`[admin] health check returned ${i.status} after retries`),t(`set-pin`);return}let a=await i.json();if(!a.pin_configured){t(`set-pin`);return}if(!a.claude_authenticated){t(`connect-claude`);return}if(await e())return;t(`enter-pin`)}catch(e){if(r>0)return await new Promise(e=>setTimeout(e,1500)),n(r-1);console.error(`[admin] health check failed:`,e),t(`set-pin`)}}n()},[]),(0,m.useEffect)(()=>{e===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&E(e)}).catch(()=>{})},[e]),(0,m.useEffect)(()=>{if(typeof window>`u`)return;let t=!1;try{t=sessionStorage.getItem(g)===`1`}catch{}if(v({appState:e,alreadyRedirected:t})){try{sessionStorage.setItem(g,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${_}`),window.location.replace(_)}},[e]);let J=(0,m.useRef)(null);(0,m.useEffect)(()=>{if(e!==`chat`)return;let n=setInterval(async()=>{try{let e=await fetch(`/api/health`);if(e.ok){let n=await e.json();if(n.auth_status===`dead`||n.auth_status===`missing`){t(`connect-claude`);return}}}catch{}if(C)try{let e=await fetch(`/api/admin/session?session_key=${encodeURIComponent(C)}`);if(e.status!==401)return;let t=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${t}`),J.current?.()}catch{}},300*1e3);return()=>clearInterval(n)},[e,C]),(0,m.useEffect)(()=>{e===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&t(`enter-pin`)}).catch(()=>{})},[e]);async function Y(e,n){d(!0);try{let i=await fetch(`/api/admin/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:e,...n?{accountId:n}:{}})});if(!i.ok){s((await i.json().catch(()=>({}))).error||`Invalid PIN`);return}let a=await i.json();if(a.accounts&&!a.session_key){console.log(`[admin] account picker shown: userId=${a.userId} accountCount=${a.accounts.length}`),R(a.accounts),t(`account-picker`);return}w(a.session_key),I(a.sessionId??null),O(a.businessName),A(a.role??null),M(a.userName===void 0?null:a.userName),P(a.avatar??null);let o=h(a.thinkingView);if(U.current=o,H(o),n)try{sessionStorage.setItem(`maxy-account-id`,n)}catch{}try{sessionStorage.setItem(`maxy-admin-session-key`,a.session_key)}catch{}r(``),t(`chat`)}catch(e){console.error(`[admin] connection error:`,e),s(`Could not connect.`)}finally{d(!1),B(!1)}}let X=(0,m.useCallback)(async e=>{if(e.preventDefault(),u)return;s(``);let a=i.trim();if(!a){s(`Please enter your name.`);return}if(n.length<4){s(`PIN must be at least 4 characters.`);return}let o=n;d(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:o,name:a})});if(!e.ok){let n=await e.json().catch(()=>({}));if(e.status===409){console.log(`[admin] PIN already configured — re-checking health`);try{let e=await fetch(`/api/health`);if(e.ok){let r=await e.json();r.pin_configured&&r.claude_authenticated?t(`enter-pin`):r.pin_configured?t(`connect-claude`):s(n.error||`Failed to set PIN.`)}else t(`enter-pin`)}catch{t(`enter-pin`)}return}s(n.error||`Failed to set PIN.`);return}let n=await fetch(`/api/health`);if((n.ok?await n.json():null)?.claude_authenticated){await Y(o);return}r(``),t(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),s(`Could not connect.`)}finally{d(!1)}},[n,u,i]),Z=(0,m.useCallback)(async e=>{e.preventDefault(),s(``),await Y(n)},[n]),Q=(0,m.useCallback)(async()=>{S(!0);try{await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`logout`})}),w(null),A(null),M(void 0),P(null);try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}t(`connect-claude`)}finally{S(!1)}},[]),$=(0,m.useCallback)(()=>{w(null),A(null),M(void 0),P(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(`maxy-account-id`),sessionStorage.removeItem(g)}catch{}r(``),s(``),t(`enter-pin`)},[]);return(0,m.useEffect)(()=>{J.current=$},[$]),{appState:e,setAppState:t,pin:n,setPin:r,operatorName:i,setOperatorName:a,pinError:o,setPinError:s,showPin:c,setShowPin:l,pinLoading:u,authPolling:f,setAuthPolling:p,authLoading:y,setAuthLoading:b,disconnecting:x,cacheKey:C,setCacheKey:w,claudeInfo:T,setClaudeInfo:E,businessName:D,role:k,userName:j,userAvatar:N,sessionId:F,setSessionId:I,accounts:L,accountPickerLoading:z,expandAll:V,setExpandAll:H,expandAllDefaultRef:U,remoteAuthEnabled:W,pinInputRef:K,setPinFormRef:q,handleSetPin:X,handleLogin:Z,handleAccountSelect:(0,m.useCallback)(async e=>{B(!0),s(``),await Y(n,e)},[n]),handleDisconnect:Q,handleLogout:$,handleChangePin:(0,m.useCallback)(async()=>{if(!n){s(`Enter your current PIN first.`);return}d(!0),s(``);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify({currentPin:n})});if(!e.ok){s((await e.json().catch(()=>({error:`Incorrect PIN.`}))).error||`Incorrect PIN.`);return}r(``),s(``),t(`set-pin`)}catch(e){console.error(`[admin-auth] change pin failed:`,e),s(e instanceof Error?e.message:String(e))}finally{d(!1)}},[n])}}var b=r();function x({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,m.useRef)([]);function s(e,r){r.key===`Backspace`?(r.preventDefault(),t[e]?n(t.slice(0,e)+t.slice(e+1)):e>0&&(n(t.slice(0,e-1)+t.slice(e)),o.current[e-1]?.focus())):r.key===`ArrowLeft`&&e>0?o.current[e-1]?.focus():r.key===`ArrowRight`&&e<5?o.current[e+1]?.focus():r.key===`Enter`&&(r.preventDefault(),r.currentTarget.form?.requestSubmit())}function c(e,i){let a=i.nativeEvent.data;if(!a||!/^\d$/.test(a))return;let s=t.split(``);for(s[e]=a;s.length<e;)s.push(``);let c=s.join(``).replace(/\D/g,``).slice(0,6);n(c),c.length===6?r?.(c):e<5&&o.current[e+1]?.focus()}function l(e){e.preventDefault();let t=e.clipboardData.getData(`text`).replace(/\D/g,``).slice(0,6);t&&(n(t),t.length===6?r?.(t):o.current[t.length]?.focus())}return(0,b.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,b.jsx)(`input`,{ref:t=>{o.current[r]=t,r===0&&e&&(e.current=t)},type:`text`,inputMode:`numeric`,className:`pin-box${t[r]?` pin-box-filled`:``}`,value:t[r]?i?t[r]:`•`:``,onKeyDown:e=>s(r,e),onInput:e=>c(r,e),onPaste:l,onFocus:e=>e.target.select(),autoFocus:a&&r===0,autoComplete:`off`,maxLength:1,"aria-label":`PIN digit ${r+1}`},r))})}function S(e){let{pin:n,setPin:r,showPin:a,setShowPin:o,pinLoading:s,pinError:c,pinInputRef:l,setPinFormRef:f,onSubmit:p,operatorName:m,setOperatorName:h}=e;return(0,b.jsx)(`div`,{className:`connect-page`,children:(0,b.jsxs)(`div`,{className:`connect-content`,children:[(0,b.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,b.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,i.productName]}),(0,b.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,i.productName,` who you are, then choose a PIN.`]}),(0,b.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,b.jsxs)(`div`,{className:`pin-input-row`,children:[(0,b.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:m,onChange:e=>h(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,b.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,b.jsxs)(`div`,{className:`pin-input-row`,children:[(0,b.jsx)(x,{inputRef:l,value:n,onChange:r,onComplete:()=>{},showPin:a}),(0,b.jsx)(d,{variant:`send`,type:`submit`,disabled:!n||!m.trim(),loading:s,"aria-label":`Set PIN`,children:(0,b.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,b.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,b.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,b.jsx)(u,{checked:a,onChange:()=>o(e=>!e),label:`Show PIN`})]}),c&&(0,b.jsx)(`p`,{className:`admin-pin-error`,children:c})]})})}function C(e){let{pin:n,setPin:r,showPin:a,setShowPin:o,pinLoading:s,pinError:c,pinInputRef:l,onSubmit:f,onChangePin:p,remoteAuthEnabled:m,onSignOutRemote:h}=e;return(0,b.jsxs)(`div`,{className:`connect-page`,children:[m&&h&&(0,b.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:h,children:`Sign out`}),(0,b.jsxs)(`div`,{className:`connect-content`,children:[(0,b.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,b.jsx)(`h1`,{className:`connect-title`,children:i.productName}),(0,b.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,b.jsxs)(`div`,{className:`pin-input-row`,children:[(0,b.jsx)(x,{inputRef:l,value:n,onChange:r,onComplete:()=>{},showPin:a,autoFocus:!0}),(0,b.jsx)(d,{variant:`send`,type:`submit`,disabled:!n,loading:s,children:(0,b.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,b.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,b.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,b.jsxs)(`div`,{className:`pin-options`,children:[(0,b.jsx)(u,{checked:a,onChange:()=>o(e=>!e),label:`Show PIN`}),(0,b.jsx)(d,{type:`button`,variant:`ghost`,onClick:p,children:`Change PIN`})]})]}),c&&(0,b.jsx)(`p`,{className:`admin-pin-error`,children:c})]})]})}function w(e){let{accounts:n,loading:r,error:a,onSelect:o}=e;return(0,b.jsx)(`div`,{className:`connect-page`,children:(0,b.jsxs)(`div`,{className:`connect-content`,children:[(0,b.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,b.jsx)(`h1`,{className:`connect-title`,children:i.productName}),(0,b.jsx)(`p`,{className:`connect-subtitle`,children:`Select an account`}),(0,b.jsx)(`div`,{className:`account-picker-list`,children:n.map(e=>(0,b.jsxs)(`button`,{className:`account-picker-card`,onClick:()=>o(e.accountId),disabled:r,type:`button`,children:[(0,b.jsx)(`span`,{className:`account-picker-name`,children:e.businessName||e.accountId}),(0,b.jsx)(`span`,{className:`account-picker-role`,children:e.role}),r&&(0,b.jsx)(l,{className:`account-picker-spinner`,size:16})]},e.accountId))}),a&&(0,b.jsx)(`p`,{className:`admin-pin-error`,children:a})]})})}function T(e){let{authPolling:n,setAuthPolling:r,authLoading:a,setAuthLoading:o,pinError:s,setPinError:c,setAppState:l}=e,[u,f]=(0,m.useState)(!1),[p,h]=(0,m.useState)(!1);async function g(){h(!0),c(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`launch-browser`})})).json();e.launched?f(!0):e.error&&c(e.error)}catch(e){console.error(`[admin] browser launch error:`,e),c(`Could not launch browser.`)}h(!1)}async function _(){o(!0),c(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){r(!0),f(!0),o(!1);for(let e=0;e<120;e++)if(await new Promise(e=>setTimeout(e,2e3)),(await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`wait`})})).json()).authenticated){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),l(`enter-pin`);return}c(`Timed out waiting for sign-in. Try again.`),r(!1)}else e.error&&c(e.error)}catch(e){console.error(`[admin] auth flow error:`,e),c(`Could not start auth flow.`)}o(!1)}async function v(){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),r(!1),c(``)}return n||u?(0,b.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,b.jsxs)(`header`,{className:`chat-header`,style:{paddingBottom:`12px`,flexShrink:0,position:`relative`,maxWidth:`680px`,width:`100%`,margin:`0 auto`,padding:`24px 20px 12px`},children:[n?(0,b.jsx)(`button`,{onClick:v,style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Cancel`,children:`✕`}):(0,b.jsx)(`button`,{onClick:()=>f(!1),style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Close browser`,children:`✕`}),(0,b.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,b.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,b.jsx)(`p`,{className:`chat-intro`,children:n?`Sign in and authorize in the browser below.`:`Open your email or prepare your accounts, then sign in.`}),!n&&(0,b.jsx)(`div`,{style:{marginTop:`12px`},children:(0,b.jsx)(d,{variant:`primary`,onClick:_,disabled:a,children:a?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})})]}),(0,b.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:(0,b.jsx)(`iframe`,{src:`/vnc-viewer.html`,style:{flex:1,width:`100%`,minHeight:0,border:`none`,background:`#111`,display:`block`},title:`Claude Sign-in`})}),s&&(0,b.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:s})]}):(0,b.jsx)(`div`,{className:`connect-page`,children:(0,b.jsxs)(`div`,{className:`connect-content`,children:[(0,b.jsxs)(`div`,{className:`connect-logos`,children:[(0,b.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,b.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,b.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,b.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,b.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,b.jsx)(`img`,{src:t,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,b.jsx)(`span`,{className:`connect-logo-label`,children:i.productName})]})]}),(0,b.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,i.productName]}),(0,b.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,b.jsx)(d,{variant:`primary`,onClick:_,disabled:a,children:a?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,b.jsx)(`p`,{style:{marginTop:`6px`,fontSize:`11px`,color:`#999`,maxWidth:`300px`,textAlign:`center`,lineHeight:`1.4`},children:`First time? You may need to sign into your email and Anthropic account in the browser before connecting.`}),(0,b.jsx)(`button`,{onClick:g,disabled:p,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:p?`Launching…`:`Open browser first`}),s&&(0,b.jsx)(`p`,{className:`admin-pin-error`,children:s})]})})}function E({onOpen:e}){return(0,b.jsx)(`footer`,{className:`admin-footer`,children:(0,b.jsxs)(`div`,{className:`powered-by`,role:`button`,tabIndex:0,onClick:e,onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),e())},"aria-label":`Powered by Claude Code — show details`,children:[(0,b.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`powered-by-icon`}),(0,b.jsx)(`span`,{children:`Powered by Claude Code`})]})})}function D(e){if(e<60)return`${e}s`;let t=Math.floor(e/60),n=e%60;return n>0?`${t}m ${n}s`:`${t}m`}function O(e){return e>=1e3?`${(e/1e3).toFixed(1)}k`:String(e)}function k(e){let{show:t,onClose:n,claudeInfo:r,messages:i,sessionElapsed:a,sessionId:o,cacheKey:s}=e,[c,l]=(0,m.useState)(null);if(!t)return null;let u=i.flatMap(e=>e.events?.filter(e=>e.type===`usage`)??[]),d=u.at(-1),p=d?.peak_request_pct==null?d?.context_window?Math.round((d.input_tokens+d.cache_creation_tokens+d.cache_read_tokens)/d.context_window*100):0:Math.round(d.peak_request_pct*100),h=u.reduce((e,t)=>e+t.input_tokens+t.cache_creation_tokens+t.cache_read_tokens+t.output_tokens,0),g=i.flatMap(e=>e.events?.filter(e=>e.type===`rate_limit`)??[]).at(-1),_=u.reduce((e,t)=>e+(t.total_cost_usd??0),0),v=r?.account?.subscriptionType,y=e=>{let t=e*1e3-Date.now();if(t<=0)return`now`;let n=Math.floor(t/36e5),r=Math.floor(t%36e5/6e4);return n>0?`${n}h ${r}m`:`${r}m`};return(0,b.jsx)(`div`,{className:`claude-info-overlay`,onClick:n,children:(0,b.jsxs)(`div`,{className:`claude-info-modal`,onClick:e=>e.stopPropagation(),children:[(0,b.jsxs)(`div`,{className:`claude-info-header`,children:[(0,b.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`claude-info-icon`}),(0,b.jsx)(`span`,{children:`Claude Code`}),(0,b.jsx)(`button`,{className:`claude-info-close`,onClick:n,"aria-label":`Close`,children:`✕`})]}),(0,b.jsxs)(`div`,{className:`claude-info-section`,children:[(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Version`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:r?r.version:`…`})]}),(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Email`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:r?.account?.email??`…`})]})]}),(v||g||_>0)&&(0,b.jsxs)(`div`,{className:`claude-info-section`,children:[v&&(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Plan`}),(0,b.jsx)(`span`,{className:`claude-info-value`,style:{textTransform:`capitalize`},children:v})]}),g&&(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Usage`}),(0,b.jsxs)(`span`,{className:`claude-info-value`,children:[Math.round(g.utilization*100),`%`]})]}),(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Resets in`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:y(g.resetsAt)})]}),g.isUsingOverage&&(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Overage`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:`Active`})]})]}),_>0&&(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Session cost`}),(0,b.jsxs)(`span`,{className:`claude-info-value`,children:[`$`,_<.01?_.toFixed(4):_.toFixed(2)]})]})]}),(0,b.jsxs)(`div`,{className:`claude-info-section`,children:[(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Model`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:r?.model??`…`})]}),(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Context used`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:p>0?`${p}%`:`—`})]}),(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Tokens`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:h>0?O(h):`—`})]}),(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Session`}),(0,b.jsx)(`span`,{className:`claude-info-value`,children:D(a)})]}),(o||s)&&(()=>{let e=o??s??``;return(0,b.jsxs)(`div`,{className:`claude-info-row`,children:[(0,b.jsx)(`span`,{className:`claude-info-label`,children:`Session`}),(0,b.jsx)(`button`,{type:`button`,className:`claude-info-value claude-info-id-copy`,title:`${e} (${o?`flushed`:`pre-flush`}) — click to copy`,onClick:async()=>{l(await f(e)?`copied`:`failed`),setTimeout(()=>l(null),1200)},children:c===`copied`?`copied ✓`:c===`failed`?`copy failed ✕`:`${e.slice(0,8)}…`})]})})()]})]})})}function A(){let e=y(),[t,n]=(0,m.useState)(!1);(0,m.useEffect)(()=>{if(!t)return;let e=e=>{e.key===`Escape`&&n(!1)};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[t]);let r=(0,m.useCallback)(async()=>{let t=e.claudeInfo!=null;if(n(!0),t){console.info(`[admin-ui] claude-info-open cached=true ms=0`);return}let r=Date.now();try{let t=await fetch(`/api/admin/claude-info`);if(t.ok){let n=await t.json();e.setClaudeInfo(n)}console.info(`[admin-ui] claude-info-open cached=false ms=${Date.now()-r}`)}catch(e){console.error(`[admin-ui] claude-info-fetch-failed ms=${Date.now()-r} error="${e instanceof Error?e.message:String(e)}"`)}},[e]),i=(0,m.useCallback)(({code:t,path:n})=>{console.warn(`[admin-auth] outcome=chat-tab-logout-on-401 code=${t} path=${n}`),e.handleLogout()},[e]);return e.appState===`loading`?(0,b.jsx)(`div`,{className:`connect-page`}):e.appState===`set-pin`?(0,b.jsx)(S,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,setPinFormRef:e.setPinFormRef,onSubmit:e.handleSetPin,operatorName:e.operatorName,setOperatorName:e.setOperatorName}):e.appState===`connect-claude`?(0,b.jsx)(T,{authPolling:e.authPolling,setAuthPolling:e.setAuthPolling,authLoading:e.authLoading,setAuthLoading:e.setAuthLoading,pinError:e.pinError,setPinError:e.setPinError,setAppState:e.setAppState}):e.appState===`enter-pin`?(0,b.jsx)(C,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,onSubmit:e.handleLogin,onChangePin:e.handleChangePin,remoteAuthEnabled:e.remoteAuthEnabled,onSignOutRemote:e.handleLogout}):e.appState===`account-picker`?(0,b.jsx)(w,{accounts:e.accounts,loading:e.accountPickerLoading,error:e.pinError,onSelect:e.handleAccountSelect}):(0,b.jsx)(s,{cacheKey:e.cacheKey,onSessionExpired:i,surface:`chat`,children:(0,b.jsx)(c,{cacheKey:e.cacheKey,businessName:e.businessName,sessionId:e.sessionId,onLogout:e.handleLogout,userName:e.userName,userAvatar:e.userAvatar,role:e.role,footer:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(E,{onOpen:r}),(0,b.jsx)(k,{show:t,onClose:()=>n(!1),claudeInfo:e.claudeInfo,messages:[],sessionElapsed:0,sessionId:e.sessionId,cacheKey:e.cacheKey})]}),children:()=>(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(o,{}),(0,b.jsx)(`main`,{})]})})})}(0,p.createRoot)(document.getElementById(`root`)).render((0,b.jsx)(A,{}));
|