@rubytech/create-maxy-code 0.1.214 → 0.1.216
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 +1 -1
- package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +4 -1
- package/payload/platform/plugins/admin/hooks/__tests__/post-tool-use-agent.test.sh +97 -1
- package/payload/platform/plugins/admin/hooks/__tests__/pre-tool-use-admin-tool-gate.test.sh +53 -12
- package/payload/platform/plugins/admin/hooks/lib/hook-emit.sh +30 -0
- package/payload/platform/plugins/admin/hooks/post-tool-use-agent.sh +81 -29
- package/payload/platform/plugins/admin/hooks/pre-tool-use.sh +34 -17
- package/payload/platform/plugins/admin/mcp/dist/__tests__/capabilities-here.test.d.ts +2 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/capabilities-here.test.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/capabilities-here.test.js +130 -0
- package/payload/platform/plugins/admin/mcp/dist/__tests__/capabilities-here.test.js.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js +63 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/lib/catalogue-census.d.ts +14 -0
- package/payload/platform/plugins/admin/mcp/dist/lib/catalogue-census.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/lib/catalogue-census.js +50 -0
- package/payload/platform/plugins/admin/mcp/dist/lib/catalogue-census.js.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/capabilities-here.d.ts +28 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/capabilities-here.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/capabilities-here.js +68 -0
- package/payload/platform/plugins/admin/mcp/dist/tools/capabilities-here.js.map +1 -0
- package/payload/platform/plugins/admin/skills/capabilities-here/SKILL.md +31 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +30 -14
- package/payload/platform/plugins/docs/references/platform.md +19 -9
- package/payload/platform/plugins/docs/references/plugins-guide.md +2 -0
- package/payload/platform/scripts/check-architecture-skill-no-drift.mjs +89 -42
- package/payload/platform/scripts/check-roles-doc-completeness.mjs +96 -0
- package/payload/platform/scripts/check-specialist-tool-surface.mjs +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- 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 +77 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +30 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-tail.d.ts +18 -0
- package/payload/platform/services/claude-session-manager/dist/jsonl-tail.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/jsonl-tail.js +63 -0
- package/payload/platform/services/claude-session-manager/dist/jsonl-tail.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +5 -0
- 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 +29 -0
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-script-spawn.d.ts +80 -0
- package/payload/platform/services/claude-session-manager/dist/rc-script-spawn.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/rc-script-spawn.js +306 -0
- package/payload/platform/services/claude-session-manager/dist/rc-script-spawn.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts +9 -0
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js +6 -2
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js.map +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +3 -1
- package/payload/platform/templates/specialists/agents/content-producer.md +1 -1
- package/payload/server/public/assets/AdminShell-CPWbJ_I8.js +1 -0
- package/payload/server/public/assets/{admin-DMo5DWKH.js → admin-DjGGOx2K.js} +1 -1
- package/payload/server/public/assets/{data-D6IQdm0R.js → data-WBEvtRV-.js} +1 -1
- package/payload/server/public/assets/{graph-PkZKVkWD.js → graph-DsOLsIPf.js} +1 -1
- package/payload/server/public/data.html +2 -2
- package/payload/server/public/graph.html +2 -2
- package/payload/server/public/index.html +2 -2
- package/payload/server/server.js +6 -0
- package/payload/server/public/assets/AdminShell-BcxEZnpu.js +0 -1
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
// Task 562 — isolated rc-spawn path via `systemdSpawn` + `script(1)`.
|
|
2
|
+
//
|
|
3
|
+
// Mirrors the rc-daemon's spawn mechanism (rc-daemon.ts:312) so the
|
|
4
|
+
// manager holds ZERO file descriptors per spawn: stdio:'ignore' on the
|
|
5
|
+
// outer systemd-run child, real TTY allocated by `script -q -f -c` inside
|
|
6
|
+
// the scope, child's stdout/stderr captured to a retained typescript file
|
|
7
|
+
// at `~/.<brand>/logs/spawn-rc-resume-<unitToken>.log`.
|
|
8
|
+
//
|
|
9
|
+
// Shares no mutable state with the legacy node-pty rc-spawn path:
|
|
10
|
+
// - No `spawnPty`, `registerRcSpawnPty`, or `livePtys` interaction.
|
|
11
|
+
// - No master fd in the manager → no `releasePtyMasterFd` lifecycle.
|
|
12
|
+
// - Own `liveScriptScopeRcSpawns` Map keyed on unitToken for census +
|
|
13
|
+
// liveness observability.
|
|
14
|
+
//
|
|
15
|
+
// Observability follows the cross-arm `[rc-life]` schema (see Task 562
|
|
16
|
+
// brief). Every line carries `source=rc-spawn path=script-scope
|
|
17
|
+
// mode=<new|resume> unitToken=<token>` so a `grep source=rc-spawn`
|
|
18
|
+
// directly compares with `grep source=rc-daemon` lines emitted from
|
|
19
|
+
// rc-daemon.ts under the same schema. The capture file is never
|
|
20
|
+
// unlinked by this module — post-mortem is always possible.
|
|
21
|
+
import { dirname, join } from 'node:path';
|
|
22
|
+
import { existsSync } from 'node:fs';
|
|
23
|
+
import { randomUUID } from 'node:crypto';
|
|
24
|
+
import { findExistingJsonlForSessionId } from './jsonl-path.js';
|
|
25
|
+
import { buildRcChildEnv } from './rc-daemon.js';
|
|
26
|
+
const liveScriptScopeRcSpawns = new Map();
|
|
27
|
+
/** For tests + the census sweep. Read-only iteration. */
|
|
28
|
+
export function forEachLiveScriptScopeRcSpawn(cb) {
|
|
29
|
+
for (const e of liveScriptScopeRcSpawns.values())
|
|
30
|
+
cb(e);
|
|
31
|
+
}
|
|
32
|
+
export function liveScriptScopeRcSpawnCount() {
|
|
33
|
+
return liveScriptScopeRcSpawns.size;
|
|
34
|
+
}
|
|
35
|
+
/** Clear the tracker map. Test-only seam — production never calls. */
|
|
36
|
+
export function __resetScriptScopeRcSpawnsForTests() {
|
|
37
|
+
liveScriptScopeRcSpawns.clear();
|
|
38
|
+
}
|
|
39
|
+
/** Schema-tagged line emitter. Every consumer of the cross-arm `[rc-life]`
|
|
40
|
+
* surface must use this so the field order + null-handling stays
|
|
41
|
+
* identical between rc-spawn and rc-daemon. */
|
|
42
|
+
export function emitRcLife(logger, op, source, path, mode, unitToken, fields = {}) {
|
|
43
|
+
const base = `[rc-life] op=${op} source=${source} path=${path} mode=${mode} unitToken=${unitToken}`;
|
|
44
|
+
const extras = Object.entries(fields)
|
|
45
|
+
.map(([k, v]) => `${k}=${v === null ? 'null' : typeof v === 'string' && v.includes(' ') ? JSON.stringify(v) : v}`)
|
|
46
|
+
.join(' ');
|
|
47
|
+
logger(extras ? `${base} ${extras}` : base);
|
|
48
|
+
}
|
|
49
|
+
/** Run the script-scope rc-spawn. Returns once `systemdSpawn` resolves
|
|
50
|
+
* (scope is active, cgroup pid captured). Liveness polling, pid-file
|
|
51
|
+
* binding, and exit observation run in the background — the route
|
|
52
|
+
* responds immediately with `spawnedPid` like the node-pty arm does. */
|
|
53
|
+
export async function handleRcSpawnScriptScope(deps, req) {
|
|
54
|
+
const now = deps.now ?? (() => Date.now());
|
|
55
|
+
const livenessIntervalMs = deps.livenessPollIntervalMs ?? 15_000;
|
|
56
|
+
const start = now();
|
|
57
|
+
const unitToken = `rc-resume-${randomUUID()}`;
|
|
58
|
+
const existingJsonl = req.sessionId
|
|
59
|
+
? findExistingJsonlForSessionId(deps.claudeConfigDir, req.sessionId)
|
|
60
|
+
: null;
|
|
61
|
+
const mode = existingJsonl ? 'resume' : 'new';
|
|
62
|
+
const argv = ['--remote-control'];
|
|
63
|
+
if (req.name)
|
|
64
|
+
argv.push(req.name);
|
|
65
|
+
if (req.sessionId)
|
|
66
|
+
argv.push(mode === 'resume' ? '--resume' : '--session-id', req.sessionId);
|
|
67
|
+
const env = buildRcChildEnv({
|
|
68
|
+
accountId: deps.accountId,
|
|
69
|
+
uiPort: deps.uiPort,
|
|
70
|
+
platformRoot: deps.platformRoot,
|
|
71
|
+
claudeConfigDir: deps.claudeConfigDir,
|
|
72
|
+
brandedNeo4jUri: deps.brandedNeo4jUri,
|
|
73
|
+
brandedNeo4jPassword: deps.brandedNeo4jPassword,
|
|
74
|
+
});
|
|
75
|
+
const cleanEnv = {};
|
|
76
|
+
for (const [k, v] of Object.entries(env)) {
|
|
77
|
+
if (typeof v === 'string')
|
|
78
|
+
cleanEnv[k] = v;
|
|
79
|
+
}
|
|
80
|
+
// Mirror rc-daemon.ts:323 — capture file under <accountDir>/logs/.
|
|
81
|
+
// dirname(claudeConfigDir) is the accountDir (e.g. /home/<user>/.maxy-code/).
|
|
82
|
+
const captureFilePath = join(dirname(deps.claudeConfigDir), 'logs', `spawn-${unitToken}.log`);
|
|
83
|
+
emitRcLife(deps.logger, 'request', 'rc-spawn', 'script-scope', mode, unitToken, {
|
|
84
|
+
sessionId: req.sessionId ?? 'new',
|
|
85
|
+
name: req.name ?? 'none',
|
|
86
|
+
existingJsonl: existingJsonl ?? 'none',
|
|
87
|
+
});
|
|
88
|
+
emitRcLife(deps.logger, 'argv', 'rc-spawn', 'script-scope', mode, unitToken, {
|
|
89
|
+
cwd: deps.spawnCwd,
|
|
90
|
+
captureFile: captureFilePath,
|
|
91
|
+
argv: JSON.stringify([deps.claudeBin, ...argv]),
|
|
92
|
+
});
|
|
93
|
+
let handle;
|
|
94
|
+
try {
|
|
95
|
+
handle = await deps.systemdSpawn({
|
|
96
|
+
claudeBin: deps.claudeBin,
|
|
97
|
+
claudeArgs: argv,
|
|
98
|
+
env: cleanEnv,
|
|
99
|
+
cwd: deps.spawnCwd,
|
|
100
|
+
unitToken,
|
|
101
|
+
captureFilePath,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
106
|
+
emitRcLife(deps.logger, 'spawn-failed', 'rc-spawn', 'script-scope', mode, unitToken, {
|
|
107
|
+
err: JSON.stringify(msg),
|
|
108
|
+
});
|
|
109
|
+
throw err;
|
|
110
|
+
}
|
|
111
|
+
emitRcLife(deps.logger, 'spawned', 'rc-spawn', 'script-scope', mode, unitToken, {
|
|
112
|
+
pid: handle.pid,
|
|
113
|
+
scopeUnit: `claude-session-${unitToken}.scope`,
|
|
114
|
+
captureFile: captureFilePath,
|
|
115
|
+
// Manager holds no fd for this child — this is the isolation invariant.
|
|
116
|
+
// A rising value across script-scope spawns is the leak signature.
|
|
117
|
+
managerOpenFds: 'unchanged',
|
|
118
|
+
});
|
|
119
|
+
const entry = {
|
|
120
|
+
unitToken,
|
|
121
|
+
pid: handle.pid,
|
|
122
|
+
sessionId: req.sessionId,
|
|
123
|
+
mode,
|
|
124
|
+
spawnedAt: start,
|
|
125
|
+
captureFilePath,
|
|
126
|
+
handle,
|
|
127
|
+
pidFileSeen: false,
|
|
128
|
+
remoteBound: false,
|
|
129
|
+
exited: false,
|
|
130
|
+
};
|
|
131
|
+
liveScriptScopeRcSpawns.set(unitToken, entry);
|
|
132
|
+
// Capture-file head emit — first ≤1 KB of the script(1) typescript,
|
|
133
|
+
// settled by either reaching 1 KB or by a short post-spawn delay. The
|
|
134
|
+
// child's own words are the signal whose absence cost 5 occasions
|
|
135
|
+
// (Task 562 brief). Read once and forget; subsequent failures land in
|
|
136
|
+
// op=early-exit's captureTail.
|
|
137
|
+
void readCaptureHead(handle, 500, 1_024).then((head) => {
|
|
138
|
+
emitRcLife(deps.logger, 'child-output', 'rc-spawn', 'script-scope', mode, unitToken, {
|
|
139
|
+
pid: handle.pid,
|
|
140
|
+
head: JSON.stringify(head),
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
// pid-file binding — claude writes <sessions>/<pid>.json once Remote
|
|
144
|
+
// Control registration finishes. This is the `ready` signal: pid file
|
|
145
|
+
// present means claude is alive and reachable from claude.ai/code.
|
|
146
|
+
void deps.waitForPid(handle.pid, deps.pidFileTimeoutMs)
|
|
147
|
+
.then((row) => {
|
|
148
|
+
entry.pidFileSeen = true;
|
|
149
|
+
entry.remoteBound = Boolean(row.bridgeSessionId);
|
|
150
|
+
emitRcLife(deps.logger, 'alive', 'rc-spawn', 'script-scope', mode, unitToken, {
|
|
151
|
+
pid: handle.pid,
|
|
152
|
+
ranMs: now() - start,
|
|
153
|
+
});
|
|
154
|
+
emitRcLife(deps.logger, 'ready', 'rc-spawn', 'script-scope', mode, unitToken, {
|
|
155
|
+
pid: handle.pid,
|
|
156
|
+
pidFile: row.pidFilePath ?? 'unknown',
|
|
157
|
+
bridgeId: row.bridgeSessionId ?? 'unknown',
|
|
158
|
+
remoteSession: row.bridgeSessionId ?? 'unknown',
|
|
159
|
+
});
|
|
160
|
+
})
|
|
161
|
+
.catch((err) => {
|
|
162
|
+
emitRcLife(deps.logger, 'wait-pid-failed', 'rc-spawn', 'script-scope', mode, unitToken, {
|
|
163
|
+
pid: handle.pid,
|
|
164
|
+
err: JSON.stringify(err instanceof Error ? err.message : String(err)),
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
// Liveness poll — runs for the session's whole intended life. Catches
|
|
168
|
+
// a session that dies quietly between events without a reproduction.
|
|
169
|
+
// Both arms emit this so endurance is directly comparable.
|
|
170
|
+
const livenessTimer = setInterval(() => {
|
|
171
|
+
if (entry.exited) {
|
|
172
|
+
clearInterval(livenessTimer);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const pidAlive = pidIsAlive(entry.pid);
|
|
176
|
+
emitRcLife(deps.logger, 'liveness', 'rc-spawn', 'script-scope', mode, unitToken, {
|
|
177
|
+
ageMs: now() - start,
|
|
178
|
+
pidAlive,
|
|
179
|
+
// scopeActive is captured from handle.waitForExit's terminal — true
|
|
180
|
+
// means we have not yet observed the scope leave the active set.
|
|
181
|
+
// A pidAlive=false here while exited=false is an early death the
|
|
182
|
+
// event flow missed.
|
|
183
|
+
scopeActive: !entry.exited,
|
|
184
|
+
remoteBound: entry.remoteBound,
|
|
185
|
+
});
|
|
186
|
+
}, livenessIntervalMs);
|
|
187
|
+
// Don't block process exit on the liveness timer.
|
|
188
|
+
livenessTimer.unref?.();
|
|
189
|
+
// Exit observation — `handle.waitForExit` polls systemctl. On exit,
|
|
190
|
+
// tag the lifetime, attach captureTail bytes, and remove from the
|
|
191
|
+
// live tracker.
|
|
192
|
+
void handle.waitForExit()
|
|
193
|
+
.then(async (exit) => {
|
|
194
|
+
entry.exited = true;
|
|
195
|
+
clearInterval(livenessTimer);
|
|
196
|
+
const lifetimeMs = now() - start;
|
|
197
|
+
let tail = '';
|
|
198
|
+
try {
|
|
199
|
+
tail = await handle.readCaptureTail(2_048);
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
tail = '';
|
|
203
|
+
}
|
|
204
|
+
if (!entry.pidFileSeen && lifetimeMs < 2_000) {
|
|
205
|
+
emitRcLife(deps.logger, 'early-exit', 'rc-spawn', 'script-scope', mode, unitToken, {
|
|
206
|
+
pid: handle.pid,
|
|
207
|
+
ranMs: lifetimeMs,
|
|
208
|
+
exitCode: exit.exitCode ?? 'null',
|
|
209
|
+
signal: exit.code ?? 'null',
|
|
210
|
+
captureTail: JSON.stringify(tail),
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
const reason = inferExitReason(exit.result, lifetimeMs, entry.pidFileSeen);
|
|
214
|
+
emitRcLife(deps.logger, 'exit', 'rc-spawn', 'script-scope', mode, unitToken, {
|
|
215
|
+
pid: handle.pid,
|
|
216
|
+
lifetimeMs,
|
|
217
|
+
reason,
|
|
218
|
+
result: exit.result,
|
|
219
|
+
captureTail: JSON.stringify(tail.slice(-512)),
|
|
220
|
+
});
|
|
221
|
+
liveScriptScopeRcSpawns.delete(unitToken);
|
|
222
|
+
})
|
|
223
|
+
.catch((err) => {
|
|
224
|
+
entry.exited = true;
|
|
225
|
+
clearInterval(livenessTimer);
|
|
226
|
+
emitRcLife(deps.logger, 'wait-exit-failed', 'rc-spawn', 'script-scope', mode, unitToken, {
|
|
227
|
+
pid: handle.pid,
|
|
228
|
+
err: JSON.stringify(err instanceof Error ? err.message : String(err)),
|
|
229
|
+
});
|
|
230
|
+
liveScriptScopeRcSpawns.delete(unitToken);
|
|
231
|
+
});
|
|
232
|
+
return {
|
|
233
|
+
spawnedPid: handle.pid,
|
|
234
|
+
sessionId: req.sessionId,
|
|
235
|
+
unitToken,
|
|
236
|
+
mode,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function inferExitReason(result, lifetimeMs, pidFileSeen) {
|
|
240
|
+
if (result === 'success' && pidFileSeen && lifetimeMs >= 2_000)
|
|
241
|
+
return 'archive';
|
|
242
|
+
if (result !== 'success')
|
|
243
|
+
return 'crash';
|
|
244
|
+
if (!pidFileSeen && lifetimeMs < 2_000)
|
|
245
|
+
return 'crash';
|
|
246
|
+
return 'unknown';
|
|
247
|
+
}
|
|
248
|
+
function pidIsAlive(pid) {
|
|
249
|
+
try {
|
|
250
|
+
process.kill(pid, 0);
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/** Reads the head of the script(1) typescript. Returns at most `maxBytes`
|
|
258
|
+
* from the start of the file; waits up to `settleMs` for the file to
|
|
259
|
+
* appear, since systemd-run + script open the typescript asynchronously
|
|
260
|
+
* after the scope is active. */
|
|
261
|
+
async function readCaptureHead(handle, settleMs, maxBytes) {
|
|
262
|
+
const deadline = Date.now() + settleMs;
|
|
263
|
+
while (Date.now() < deadline) {
|
|
264
|
+
if (existsSync(handle.captureFilePath))
|
|
265
|
+
break;
|
|
266
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
267
|
+
}
|
|
268
|
+
// readCaptureTail returns the last `maxBytes` bytes; for a small early
|
|
269
|
+
// file (< maxBytes) tail == head. The boot sequence is well under 1 KB.
|
|
270
|
+
try {
|
|
271
|
+
return await handle.readCaptureTail(maxBytes);
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
return '';
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/** Census sweep — reconciles expected (dashboard-initiated sessions) vs
|
|
278
|
+
* actual (live tracked entries). Detects a leaked entry whose pid is
|
|
279
|
+
* gone but the tracker still holds it, or a tracker whose handle's
|
|
280
|
+
* scope vanished without an exit event. Traffic-independent — runs on
|
|
281
|
+
* a timer in index.ts so a quiet failure surfaces within one interval.
|
|
282
|
+
*
|
|
283
|
+
* The daemon's live handle is supplied via `daemonAlive`; the daemon
|
|
284
|
+
* itself owns the canonical accounting (a single handle reference),
|
|
285
|
+
* but exposing it here keeps the schema unified. */
|
|
286
|
+
export function runRcLifeCensus(logger, daemonAlive) {
|
|
287
|
+
let pidAlive = 0;
|
|
288
|
+
let pidDeadButTracked = 0;
|
|
289
|
+
for (const entry of liveScriptScopeRcSpawns.values()) {
|
|
290
|
+
if (pidIsAlive(entry.pid)) {
|
|
291
|
+
pidAlive += 1;
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
pidDeadButTracked += 1;
|
|
295
|
+
// Independent reconciliation defect — entry exists with a dead pid.
|
|
296
|
+
emitRcLife(logger, 'orphan', 'rc-spawn', 'script-scope', entry.mode, entry.unitToken, {
|
|
297
|
+
pid: entry.pid,
|
|
298
|
+
kind: 'pid-dead-but-tracked',
|
|
299
|
+
ageMs: Date.now() - entry.spawnedAt,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
logger(`[rc-census] source-breakdown=rc-spawn:${liveScriptScopeRcSpawns.size},rc-daemon:${daemonAlive}` +
|
|
304
|
+
` rcSpawnPidAlive=${pidAlive} rcSpawnPidDead=${pidDeadButTracked}`);
|
|
305
|
+
}
|
|
306
|
+
//# sourceMappingURL=rc-script-spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rc-script-spawn.js","sourceRoot":"","sources":["../src/rc-script-spawn.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,6 +23,15 @@ export interface SpecialistDriftResult {
|
|
|
23
23
|
* any other defect class refuses boot and the manager never reaches a
|
|
24
24
|
* spawn that would consult this map. */
|
|
25
25
|
stripList: ReadonlyMap<string, ReadonlySet<string>>;
|
|
26
|
+
/** Per-specialist resolved tool surface — keyed by specialist name (the
|
|
27
|
+
* `.md` basename), value is the sorted set of tool names declared on the
|
|
28
|
+
* specialist's `tools:` line (before any strip-list removal). Populated
|
|
29
|
+
* for every specialist with a `tools:` line, regardless of drift outcome.
|
|
30
|
+
* Consumed by the manager-boot `[specialist-surface]` standing log so a
|
|
31
|
+
* payload-twin or bundle drift that drops a tool from a specialist's
|
|
32
|
+
* resolved surface is greppable from server.log without re-running a
|
|
33
|
+
* failing brief (Task 565 observability item 1). */
|
|
34
|
+
surfaces: ReadonlyMap<string, ReadonlySet<string>>;
|
|
26
35
|
}
|
|
27
36
|
/** Extract the value of the `tools:` line from a YAML frontmatter block.
|
|
28
37
|
* Returns the raw value (whitespace-trimmed) or null when no `tools:`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"specialist-drift.d.ts","sourceRoot":"","sources":["../src/specialist-drift.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"specialist-drift.d.ts","sourceRoot":"","sources":["../src/specialist-drift.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAyCpD,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EACF,0BAA0B,GAC1B,wBAAwB,GACxB,gBAAgB,GAChB,uBAAuB,CAAA;CAC5B;AAED,MAAM,WAAW,qBAAqB;IACpC;;;yCAGqC;IACrC,EAAE,EAAE,OAAO,CAAA;IACX;;wCAEoC;IACpC,OAAO,EAAE,qBAAqB,EAAE,CAAA;IAChC,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAA;IACjB;;;;6CAIyC;IACzC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;IACnD;;;;;;;yDAOqD;IACrD,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;CACnD;AAED;;;kEAGkE;AAClE,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI3E;AA+CD;;;;;;;;;wDASwD;AACxD,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,WAAW,EAAE,WAAW,EACxB,eAAe,GAAE,WAAW,CAAC,MAAM,CAAa,GAC/C,qBAAqB,CAmDvB"}
|
|
@@ -35,6 +35,7 @@ const CC_NATIVE_TOOLS = new Set([
|
|
|
35
35
|
'Read',
|
|
36
36
|
'Write',
|
|
37
37
|
'Edit',
|
|
38
|
+
'MultiEdit',
|
|
38
39
|
'Glob',
|
|
39
40
|
'Grep',
|
|
40
41
|
'Bash',
|
|
@@ -129,6 +130,7 @@ function classifyTool(tool, allSet, excludedPlugins) {
|
|
|
129
130
|
export function assertSpecialistDrift(agentDirs, toolSurface, excludedPlugins = new Set()) {
|
|
130
131
|
const defects = [];
|
|
131
132
|
const stripList = new Map();
|
|
133
|
+
const surfaces = new Map();
|
|
132
134
|
let inspected = 0;
|
|
133
135
|
for (const dir of agentDirs) {
|
|
134
136
|
let entries;
|
|
@@ -168,7 +170,9 @@ export function assertSpecialistDrift(agentDirs, toolSurface, excludedPlugins =
|
|
|
168
170
|
continue;
|
|
169
171
|
inspected += 1;
|
|
170
172
|
const specialistName = basename(entry, '.md');
|
|
171
|
-
|
|
173
|
+
const declaredTools = splitToolList(toolsLine);
|
|
174
|
+
surfaces.set(specialistName, new Set([...declaredTools].sort()));
|
|
175
|
+
for (const tool of declaredTools) {
|
|
172
176
|
const verdict = classifyTool(tool, toolSurface.all, excludedPlugins);
|
|
173
177
|
if (verdict === 'ok')
|
|
174
178
|
continue;
|
|
@@ -189,6 +193,6 @@ export function assertSpecialistDrift(agentDirs, toolSurface, excludedPlugins =
|
|
|
189
193
|
// logs each and exits non-zero, matching the prior strict contract for
|
|
190
194
|
// typos / missing plugins / malformed names.
|
|
191
195
|
const ok = defects.every((d) => d.reason === 'brand-excluded-plugin');
|
|
192
|
-
return { ok, defects, inspected, stripList };
|
|
196
|
+
return { ok, defects, inspected, stripList, surfaces };
|
|
193
197
|
}
|
|
194
198
|
//# sourceMappingURL=specialist-drift.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"specialist-drift.js","sourceRoot":"","sources":["../src/specialist-drift.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,wEAAwE;AACxE,qEAAqE;AACrE,wEAAwE;AACxE,yEAAyE;AACzE,wEAAwE;AACxE,uEAAuE;AACvE,wBAAwB;AACxB,EAAE;AACF,6EAA6E;AAC7E,gFAAgF;AAChF,6EAA6E;AAC7E,aAAa;AACb,EAAE;AACF,6DAA6D;AAC7D,4EAA4E;AAC5E,gCAAgC;AAChC,gEAAgE;AAChE,wCAAwC;AACxC,+EAA+E;AAC/E,gFAAgF;AAChF,2EAA2E;AAC3E,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,+EAA+E;AAE/E,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC7D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAA;AAEtE;;sDAEsD;AACtD,MAAM,eAAe,GAAG,IAAI,GAAG,CAAS;IACtC,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,YAAY;IACZ,WAAW;IACX,OAAO;IACP,WAAW;IACX,UAAU;IACV,MAAM;IACN,WAAW;IACX,cAAc;IACd,cAAc;IACd,iBAAiB;CAClB,CAAC,CAAA;AAEF;;;;;;;+BAO+B;AAC/B,MAAM,oBAAoB,GAAG,cAAc,CAAA;AAE3C;;4EAE4E;AAC5E,MAAM,eAAe,GAAG,IAAI,GAAG,CAAS,gBAAgB,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"specialist-drift.js","sourceRoot":"","sources":["../src/specialist-drift.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ 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.
|
|
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. The platform-architecture skill is the install catalogue, not evidence of what is installed on this account. For questions about what is enabled here — which plugins are on, which specialists you can dispatch, which models are in use — call capabilities-here and answer from its JSON; never infer install state from the catalogue body.
|
|
16
16
|
|
|
17
17
|
## Before you act
|
|
18
18
|
|
|
@@ -20,6 +20,8 @@ You may not act on a request until you know what is being asked, what is in scop
|
|
|
20
20
|
|
|
21
21
|
Your roster of installed specialists is loaded alongside this file as part of your first-turn reconnaissance. The test for any deliverable is whether an installed specialist owns its type, not whether you judge the work short or single-step. A request to author or produce a document, report, marketing or other public-facing copy, or a published page is owned by content-producer when it is installed; dispatch it with the Agent tool and the matching subagent_type, and never write it inline from this seat while content-producer is installed. Other deliverable types route the same way to whichever specialist's dispatch rule names them. Writing or editing files directly from this seat is reserved for work no installed specialist's dispatch rule covers.
|
|
22
22
|
|
|
23
|
+
When you dispatch a specialist, the brief states the outcome (what should be true when the specialist returns) plus the binding constraints (account, file scope, deadline, acceptance check). It does not name lines, anchors, or literal text to insert; deriving those is the specialist's job, because they own the tools that will run the change. Wrong shape: telling the specialist which file, which line range, and which CSS declaration to drop in. Right shape: "on the realagent-code site, the footer respects iOS safe-area-inset-bottom on mobile; the site's CSS is the only file in scope."
|
|
24
|
+
|
|
23
25
|
## Working from the graph
|
|
24
26
|
|
|
25
27
|
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.
|
|
@@ -3,7 +3,7 @@ name: content-producer
|
|
|
3
3
|
description: "Author professional business documents (proposal, report, brief, memo, plan, case study, brochure), render PDFs, generate images, and publish static websites. Delegate when the operator asks for a written document, a PDF render, a generated image, or to publish a prepared website."
|
|
4
4
|
summary: "Produces visual output from your graph: generates images, renders pages to PDF, and hosts static websites you upload as a zip."
|
|
5
5
|
model: claude-sonnet-4-6
|
|
6
|
-
tools: Bash, Skill, mcp__plugin_memory_memory__memory-search, mcp__plugin_replicate_replicate__image-generate, mcp__plugin_browser_browser__browser-render, mcp__plugin_browser_browser__browser-navigate, mcp__plugin_browser_browser__browser-evaluate, mcp__plugin_browser_browser__browser-resize, mcp__plugin_browser_browser__browser-screenshot, mcp__plugin_browser_browser__browser-pdf-save, mcp__plugin_admin_admin__plugin-read, mcp__plugin_admin_admin__public-hostname, mcp__plugin_admin_admin__publish-site
|
|
6
|
+
tools: Bash, Read, Edit, Write, MultiEdit, Skill, mcp__plugin_memory_memory__memory-search, mcp__plugin_replicate_replicate__image-generate, mcp__plugin_browser_browser__browser-render, mcp__plugin_browser_browser__browser-navigate, mcp__plugin_browser_browser__browser-evaluate, mcp__plugin_browser_browser__browser-resize, mcp__plugin_browser_browser__browser-screenshot, mcp__plugin_browser_browser__browser-pdf-save, mcp__plugin_admin_admin__plugin-read, mcp__plugin_admin_admin__public-hostname, mcp__plugin_admin_admin__publish-site
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Content Producer
|
|
@@ -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),[Z,he]=(0,E.useState)(`node-pty`),ge=(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 Q=(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||Q()},[r,M,Q]);let _e=()=>{A(`artefacts`),console.info(`[admin-ui] sidebar-nav surface=artefacts count=${M?j.length:0} collapsed=${b}`),M||Q()},$=1.5,ve=()=>{console.info(`[admin-ui] sidebar-refresh surface=artefacts`),Q()},ye=(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]),be=()=>{A(`sessions`),console.info(`[admin-ui] sidebar-nav surface=sessions count=${U?H.length:0} collapsed=${b}`),U||ye()},xe=()=>{console.info(`[admin-ui] sidebar-refresh surface=sessions`),ye()},Se=(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,spawnPath:Z})});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,Z]),Ce=(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({spawnPath:Z})});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,Z]),we=(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)),ye()}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,ye]);return(0,D.jsxs)(`aside`,{className:`side`,children:[(0,D.jsxs)(`div`,{className:`side-new-session-row`,children:[(0,D.jsxs)(`button`,{type:`button`,className:`side-new-session`,onClick:Ce,disabled:X,"aria-busy":X,children:[(0,D.jsx)(S,{size:14}),(0,D.jsx)(`span`,{children:X?`Spawning…`:`New session`})]}),(0,D.jsxs)(`label`,{className:`side-spawn-path-toggle`,title:`Task 562 rc-spawn path (temporary diagnostic)`,style:{display:`flex`,alignItems:`center`,gap:4,fontSize:10,opacity:.7,paddingLeft:8},children:[(0,D.jsx)(`input`,{type:`checkbox`,checked:Z===`script-scope`,onChange:e=>he(e.target.checked?`script-scope`:`node-pty`)}),(0,D.jsx)(`span`,{children:`script-scope`})]})]}),(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:$}),(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:$}),(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:$}),(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:$}),(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:_e,children:[(0,D.jsx)(t,{size:20,strokeWidth:$}),(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:be,children:[(0,D.jsx)(m,{size:20,strokeWidth:$}),(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:ve,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:()=>ge(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:xe,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:()=>{Se(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=>{we(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};
|