antechamber 1.0.0 → 1.0.1
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/CHANGELOG.md +15 -0
- package/README.md +21 -0
- package/dist/commands/serve.js +8 -2
- package/dist/commands/setup.js +10 -0
- package/dist/http.d.ts +4 -1
- package/dist/http.js +14 -1
- package/dist/monitor-sessions.d.ts +11 -2
- package/dist/monitor-sessions.js +19 -4
- package/dist/pi-event-translation.d.ts +2 -0
- package/dist/pi-event-translation.js +1 -0
- package/dist/routes-v2.js +5 -3
- package/dist/running-servers.d.ts +2 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +10 -3
- package/dist/sessions.d.ts +2 -0
- package/dist/sessions.js +6 -0
- package/dist/sse.d.ts +7 -1
- package/dist/sse.js +25 -4
- package/dist/todo-bridge.d.ts +11 -0
- package/dist/todo-bridge.js +32 -31
- package/dist/work-status.d.ts +87 -0
- package/dist/work-status.js +308 -0
- package/extensions/omo-compat/package.json +1 -1
- package/extensions/omo-dag/package.json +1 -1
- package/extensions/omo-work/README.md +91 -0
- package/extensions/omo-work/package.json +30 -0
- package/extensions/omo-work/service/main.js +159 -0
- package/extensions/omo-work/status/index.html +78 -0
- package/extensions/omo-work/status/main.js +262 -0
- package/package.json +10 -3
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// extensions/omo-work/src/service.ts
|
|
2
|
+
import { timingSafeEqual } from "node:crypto";
|
|
3
|
+
import http from "node:http";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
|
|
6
|
+
// extensions/omo-work/src/discovery.ts
|
|
7
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
function expandHome(path) {
|
|
11
|
+
if (path === "~") return homedir();
|
|
12
|
+
return path.startsWith("~/") ? join(homedir(), path.slice(2)) : path;
|
|
13
|
+
}
|
|
14
|
+
function defaultStateDirs(home = homedir()) {
|
|
15
|
+
return [join(home, ".config", "antechamber"), join(home, ".config", "openchamber-pi-connector")];
|
|
16
|
+
}
|
|
17
|
+
function alive(pid) {
|
|
18
|
+
try {
|
|
19
|
+
process.kill(pid, 0);
|
|
20
|
+
return true;
|
|
21
|
+
} catch (error) {
|
|
22
|
+
return error instanceof Error && "code" in error && error.code === "EPERM";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function loopbackUrl(url) {
|
|
26
|
+
return url.replace("://0.0.0.0:", "://127.0.0.1:").replace("://[::]:", "://[::1]:");
|
|
27
|
+
}
|
|
28
|
+
function discoverServers(stateDirs, isAlive = alive) {
|
|
29
|
+
const servers = /* @__PURE__ */ new Map();
|
|
30
|
+
for (const dir of stateDirs) {
|
|
31
|
+
let names;
|
|
32
|
+
try {
|
|
33
|
+
names = readdirSync(join(dir, "run"));
|
|
34
|
+
} catch {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
for (const name of names) {
|
|
38
|
+
if (!/^\d+\.json$/.test(name)) continue;
|
|
39
|
+
try {
|
|
40
|
+
const record = JSON.parse(readFileSync(join(dir, "run", name), "utf8"));
|
|
41
|
+
if (record === null || typeof record !== "object") continue;
|
|
42
|
+
const { pid, url, token: token2, started } = record;
|
|
43
|
+
if (typeof pid !== "number" || typeof url !== "string" || typeof token2 !== "string") continue;
|
|
44
|
+
if (typeof started !== "string" || servers.has(pid) || !isAlive(pid)) continue;
|
|
45
|
+
servers.set(pid, { pid, url: loopbackUrl(url), token: token2, started });
|
|
46
|
+
} catch {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return [...servers.values()].sort((a, b) => b.started.localeCompare(a.started));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// extensions/omo-work/src/service.ts
|
|
54
|
+
var SESSION_ID = /^ses_[0-9A-Za-z]+$/;
|
|
55
|
+
var CELL_ID = /^[\w.:-]{1,128}$/;
|
|
56
|
+
var STATUS_TIMEOUT_MS = 5e3;
|
|
57
|
+
var ACTION_TIMEOUT_MS = 15e3;
|
|
58
|
+
async function call(server, method, path, timeoutMs) {
|
|
59
|
+
const response = await fetch(`${server.url}/antechamber/work-status/${path}`, {
|
|
60
|
+
method,
|
|
61
|
+
headers: { Authorization: `Bearer ${server.token}` },
|
|
62
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
63
|
+
});
|
|
64
|
+
return { status: response.status, body: await response.text() };
|
|
65
|
+
}
|
|
66
|
+
function createServer(options) {
|
|
67
|
+
const discover = options.discover ?? ((dirs) => discoverServers(dirs));
|
|
68
|
+
const defaultDirs = options.defaultDirs ?? (() => defaultStateDirs());
|
|
69
|
+
const owners = /* @__PURE__ */ new Map();
|
|
70
|
+
const send = (res, status, body) => {
|
|
71
|
+
res.writeHead(status, { "Content-Type": "application/json", "Cache-Control": "no-store" });
|
|
72
|
+
res.end(body);
|
|
73
|
+
};
|
|
74
|
+
const fail = (res, status, error, detail) => send(res, status, JSON.stringify({ error, ...detail !== void 0 ? { detail } : {} }));
|
|
75
|
+
const ordered = (session, stateDirs) => {
|
|
76
|
+
const servers = discover(stateDirs);
|
|
77
|
+
const owner = owners.get(session);
|
|
78
|
+
return owner === void 0 ? servers : [...servers].sort((a, b) => Number(b.pid === owner) - Number(a.pid === owner));
|
|
79
|
+
};
|
|
80
|
+
const relayStatus = async (res, session, stateDirs) => {
|
|
81
|
+
const servers = ordered(session, stateDirs);
|
|
82
|
+
if (servers.length === 0)
|
|
83
|
+
return fail(
|
|
84
|
+
res,
|
|
85
|
+
503,
|
|
86
|
+
"no-server",
|
|
87
|
+
`No running antechamber server with a work-status token in ${stateDirs.join(", ")}`
|
|
88
|
+
);
|
|
89
|
+
let fallback;
|
|
90
|
+
let lastError;
|
|
91
|
+
for (const server of servers) {
|
|
92
|
+
try {
|
|
93
|
+
const upstream = await call(server, "GET", encodeURIComponent(session), STATUS_TIMEOUT_MS);
|
|
94
|
+
if (upstream.status !== 200) {
|
|
95
|
+
lastError = `${server.url} answered HTTP ${upstream.status}`;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (JSON.parse(upstream.body).live === true) {
|
|
99
|
+
owners.set(session, server.pid);
|
|
100
|
+
return send(res, 200, upstream.body);
|
|
101
|
+
}
|
|
102
|
+
fallback ??= { server, upstream };
|
|
103
|
+
} catch (error) {
|
|
104
|
+
lastError = `${server.url}: ${error instanceof Error ? error.message : String(error)}`;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (fallback) {
|
|
108
|
+
owners.set(session, fallback.server.pid);
|
|
109
|
+
return send(res, 200, fallback.upstream.body);
|
|
110
|
+
}
|
|
111
|
+
return fail(res, 502, "unreachable", lastError);
|
|
112
|
+
};
|
|
113
|
+
const relayAction = async (res, session, stateDirs, method, path) => {
|
|
114
|
+
const server = ordered(session, stateDirs)[0];
|
|
115
|
+
if (server === void 0) return fail(res, 503, "no-server");
|
|
116
|
+
try {
|
|
117
|
+
const upstream = await call(server, method, `${encodeURIComponent(session)}/${path}`, ACTION_TIMEOUT_MS);
|
|
118
|
+
return send(res, upstream.status, upstream.body || "{}");
|
|
119
|
+
} catch (error) {
|
|
120
|
+
return fail(res, 502, "unreachable", error instanceof Error ? error.message : String(error));
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const expected = Buffer.from(`Bearer ${options.token}`);
|
|
124
|
+
return http.createServer((req, res) => {
|
|
125
|
+
const supplied = Buffer.from(req.headers.authorization ?? "");
|
|
126
|
+
if (supplied.length !== expected.length || !timingSafeEqual(supplied, expected))
|
|
127
|
+
return fail(res, 401, "unauthorized");
|
|
128
|
+
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
129
|
+
if (url.pathname === "/health") return send(res, 200, '{"ok":true}');
|
|
130
|
+
const session = url.searchParams.get("session") ?? "";
|
|
131
|
+
if (!SESSION_ID.test(session)) return fail(res, 400, "session query must be an OpenChamber session id");
|
|
132
|
+
const custom = url.searchParams.get("stateDir")?.trim();
|
|
133
|
+
const stateDirs = custom ? [resolve(expandHome(custom))] : defaultDirs();
|
|
134
|
+
const cell = url.searchParams.get("cell") ?? "";
|
|
135
|
+
const method = req.method ?? "GET";
|
|
136
|
+
req.resume();
|
|
137
|
+
if (url.pathname === "/status" && method === "GET") return void relayStatus(res, session, stateDirs);
|
|
138
|
+
if (url.pathname === "/goal/fire" && method === "POST")
|
|
139
|
+
return void relayAction(res, session, stateDirs, "POST", "goal/fire");
|
|
140
|
+
if (url.pathname.startsWith("/eval")) {
|
|
141
|
+
if (!CELL_ID.test(cell)) return fail(res, 400, "cell query must be an eval cell id");
|
|
142
|
+
const tail = Number(url.searchParams.get("tailBytes") ?? 8192);
|
|
143
|
+
if (url.pathname === "/eval" && method === "GET")
|
|
144
|
+
return void relayAction(res, session, stateDirs, "GET", `eval/${encodeURIComponent(cell)}?tailBytes=${tail}`);
|
|
145
|
+
if (url.pathname === "/eval/stop" && method === "POST")
|
|
146
|
+
return void relayAction(res, session, stateDirs, "POST", `eval/${encodeURIComponent(cell)}/stop`);
|
|
147
|
+
}
|
|
148
|
+
return fail(res, 404, "not-found");
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// extensions/omo-work/src/service-main.ts
|
|
153
|
+
var port = Number(process.env.OPENCHAMBER_SERVICE_PORT);
|
|
154
|
+
var token = process.env.OPENCHAMBER_SERVICE_TOKEN ?? "";
|
|
155
|
+
if (!port || !token) {
|
|
156
|
+
console.error("OPENCHAMBER_SERVICE_PORT and OPENCHAMBER_SERVICE_TOKEN are required");
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
createServer({ token }).listen(port, "127.0.0.1");
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>OmO Work</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root {
|
|
9
|
+
--fg: var(--oc-fg, #f2f4f7);
|
|
10
|
+
--muted: var(--oc-muted, #8b93a1);
|
|
11
|
+
--subtle: color-mix(in srgb, var(--muted) 70%, transparent);
|
|
12
|
+
--border: var(--oc-border, #23272f);
|
|
13
|
+
--hover: var(--oc-hover, color-mix(in srgb, var(--fg) 6%, transparent));
|
|
14
|
+
--surface: var(--oc-muted-surface, #171a21);
|
|
15
|
+
--run: var(--oc-info, #22d3ee);
|
|
16
|
+
--run-text: var(--oc-info-text, var(--run));
|
|
17
|
+
--ok: var(--oc-success, #10b981);
|
|
18
|
+
--warn: var(--oc-warning, #f59e0b);
|
|
19
|
+
--bad: var(--oc-error, #f43f5e);
|
|
20
|
+
--bad-text: var(--oc-error-text, var(--bad));
|
|
21
|
+
--focus: var(--oc-focus, var(--run));
|
|
22
|
+
--mono: var(--oc-mono, ui-monospace, "SF Mono", Menlo, monospace);
|
|
23
|
+
--font: var(--oc-font, ui-sans-serif, system-ui, sans-serif);
|
|
24
|
+
color-scheme: dark;
|
|
25
|
+
}
|
|
26
|
+
[data-oc-theme="light"] { color-scheme: light; }
|
|
27
|
+
* { box-sizing: border-box; }
|
|
28
|
+
html, body { margin: 0; background: transparent; color: var(--fg); font: 12px/1.45 var(--font); }
|
|
29
|
+
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
|
|
30
|
+
button:focus-visible, input:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; border-radius: 4px; }
|
|
31
|
+
#root { padding: 2px 4px 6px; display: grid; gap: 8px; }
|
|
32
|
+
.group { display: grid; gap: 1px; }
|
|
33
|
+
.label { display: flex; align-items: baseline; gap: 6px; padding: 0 4px 2px; font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
|
|
34
|
+
.label .count { font-family: var(--mono); letter-spacing: 0; text-transform: none; color: var(--subtle); }
|
|
35
|
+
.row { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto; align-items: center; gap: 6px; min-height: 24px; padding: 2px 4px; border-radius: 5px; text-align: left; width: 100%; }
|
|
36
|
+
button.row:hover, .row.is-open { background: var(--hover); }
|
|
37
|
+
.row .title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
38
|
+
.row .meta { font: 11px var(--mono); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
39
|
+
.row .side { display: flex; align-items: center; gap: 4px; font: 11px var(--mono); color: var(--muted); }
|
|
40
|
+
.stack { display: grid; min-width: 0; text-align: left; }
|
|
41
|
+
button.stack { width: 100%; }
|
|
42
|
+
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--subtle); justify-self: center; }
|
|
43
|
+
.t-run .dot, .dot.t-run { background: var(--run); animation: pulse 1.6s ease-in-out infinite; }
|
|
44
|
+
.t-ok .dot, .dot.t-ok { background: var(--ok); }
|
|
45
|
+
.t-warn .dot, .dot.t-warn { background: var(--warn); }
|
|
46
|
+
.t-bad .dot, .dot.t-bad { background: var(--bad); }
|
|
47
|
+
@keyframes pulse { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--run) 55%, transparent); } 50% { box-shadow: 0 0 0 3px transparent; } }
|
|
48
|
+
.bar { width: 38px; height: 3px; border-radius: 2px; background: color-mix(in srgb, var(--muted) 25%, transparent); overflow: hidden; }
|
|
49
|
+
.bar > i { display: block; height: 100%; background: var(--ok); }
|
|
50
|
+
.t-run .bar > i { background: var(--run); }
|
|
51
|
+
.tasks { display: grid; gap: 0; padding: 1px 0 3px 22px; }
|
|
52
|
+
.task { display: grid; grid-template-columns: 12px minmax(0, 1fr); gap: 6px; align-items: start; padding: 1px 0; color: var(--muted); }
|
|
53
|
+
.task .glyph { font: 10px/17px var(--mono); text-align: center; }
|
|
54
|
+
.task.s-in_progress { color: var(--fg); }
|
|
55
|
+
.task.s-in_progress .glyph { color: var(--run-text); }
|
|
56
|
+
.task.s-completed .glyph { color: var(--ok); }
|
|
57
|
+
.task.s-cancelled { text-decoration: line-through; opacity: .6; }
|
|
58
|
+
.detail { margin: 0 4px 4px 22px; padding: 6px 8px; border-radius: 5px; background: var(--surface); display: grid; gap: 4px; min-width: 0; }
|
|
59
|
+
.detail .kv { font: 11px var(--mono); color: var(--muted); overflow-wrap: anywhere; }
|
|
60
|
+
.detail pre { margin: 0; max-height: 140px; overflow: auto; font: 11px/1.4 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; color: var(--fg); }
|
|
61
|
+
.action { height: 20px; padding: 0 7px; border-radius: 4px; border: 1px solid var(--border); font-size: 11px; color: var(--fg); }
|
|
62
|
+
.action:hover { background: var(--hover); }
|
|
63
|
+
.action.danger { color: var(--bad-text); }
|
|
64
|
+
.action[disabled] { opacity: .5; cursor: default; }
|
|
65
|
+
.note { padding: 2px 4px; color: var(--muted); }
|
|
66
|
+
.note.is-error { color: var(--bad-text); }
|
|
67
|
+
.settings { display: grid; gap: 6px; padding: 6px 8px; border-radius: 5px; background: var(--surface); }
|
|
68
|
+
.settings label { display: grid; gap: 3px; font-size: 11px; color: var(--muted); }
|
|
69
|
+
.settings input { padding: 4px 6px; border: 1px solid var(--border); border-radius: 4px; background: transparent; color: var(--fg); font: 11px var(--mono); }
|
|
70
|
+
.settings .buttons { display: flex; justify-content: flex-end; gap: 6px; }
|
|
71
|
+
@media (prefers-reduced-motion: reduce) { .t-run .dot, .dot.t-run { animation: none; } }
|
|
72
|
+
</style>
|
|
73
|
+
</head>
|
|
74
|
+
<body>
|
|
75
|
+
<div id="root" aria-live="polite"></div>
|
|
76
|
+
<script src="main.js"></script>
|
|
77
|
+
</body>
|
|
78
|
+
</html>
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"use strict";(()=>{var _="openchamber.sdk";var Ce="data-oc-scrolling",tt=`
|
|
2
|
+
:root {
|
|
3
|
+
/* Quiet at rest like the app's own thumbs; hover gives a clear grab target. */
|
|
4
|
+
--oc-scrollbar-thumb: color-mix(in srgb, var(--oc-muted, currentColor) 18%, transparent);
|
|
5
|
+
--oc-scrollbar-thumb-hover: color-mix(in srgb, var(--oc-muted, currentColor) 36%, transparent);
|
|
6
|
+
scrollbar-gutter: stable;
|
|
7
|
+
}
|
|
8
|
+
* {
|
|
9
|
+
scrollbar-width: thin;
|
|
10
|
+
scrollbar-color: transparent transparent;
|
|
11
|
+
}
|
|
12
|
+
:hover, [${Ce}] {
|
|
13
|
+
scrollbar-color: var(--oc-scrollbar-thumb) transparent;
|
|
14
|
+
}
|
|
15
|
+
/* Chromium's standard scrollbar properties otherwise override its pseudo-elements. */
|
|
16
|
+
@supports selector(::-webkit-scrollbar) {
|
|
17
|
+
*, :hover, [${Ce}] { scrollbar-width: auto; scrollbar-color: auto; }
|
|
18
|
+
::-webkit-scrollbar { width: 6px; height: 6px; background: transparent; }
|
|
19
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
20
|
+
::-webkit-scrollbar-thumb {
|
|
21
|
+
background: transparent;
|
|
22
|
+
border-radius: 999px;
|
|
23
|
+
min-width: 24px;
|
|
24
|
+
min-height: 24px;
|
|
25
|
+
}
|
|
26
|
+
:hover::-webkit-scrollbar-thumb, [${Ce}]::-webkit-scrollbar-thumb { background: var(--oc-scrollbar-thumb); }
|
|
27
|
+
::-webkit-scrollbar-thumb:hover { background: var(--oc-scrollbar-thumb-hover); }
|
|
28
|
+
::-webkit-scrollbar-corner { background: transparent; }
|
|
29
|
+
::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
|
|
30
|
+
}
|
|
31
|
+
@media (forced-colors: active) {
|
|
32
|
+
*, :hover, [${Ce}] { scrollbar-color: auto; }
|
|
33
|
+
::-webkit-scrollbar-thumb, ::-webkit-scrollbar-thumb:hover { background: CanvasText; }
|
|
34
|
+
}
|
|
35
|
+
`;function ao(e){let o=e.documentElement;if(o.hasAttribute("data-oc-scrollbar-activity"))return;o.setAttribute("data-oc-scrollbar-activity","");let r=new WeakMap;e.addEventListener("scroll",s=>{let i=s.target===e?o:s.target;if(!(i instanceof Element))return;i.hasAttribute("data-oc-scrolling")||i.setAttribute("data-oc-scrolling","");let d=r.get(i);d!==void 0&&clearTimeout(d),r.set(i,setTimeout(()=>{r.delete(i),i.removeAttribute("data-oc-scrolling")},1e3))},{capture:!0,passive:!0})}var cn=`(${ao.toString()})(document);`;var uo=/^[a-z][a-z0-9-]{0,39}$/;var co=e=>Object(e)===e&&!Array.isArray(e),ot=(e,o)=>Object.keys(e).every(r=>o.includes(r)),lo=e=>String(e)===e&&e.length>=1&&e.length<=60,po=e=>String(e)===e&&e.length>=1&&e.length<=80,fo=e=>{if(!Array.isArray(e)||e.length>4)return!1;let o=new Set;for(let r of e){if(!co(r)||!uo.test(r.id)||!lo(r.label)||r.disabled!==void 0&&r.disabled!==!0&&r.disabled!==!1||o.has(r.id))return!1;if(o.add(r.id),r.kind==="button"){if(!ot(r,["kind","id","label","disabled"]))return!1;continue}if(r.kind!=="select"||!ot(r,["kind","id","label","value","options","disabled"])||!po(r.value)||!Array.isArray(r.options)||r.options.length<1||r.options.length>16)return!1;let s=new Set;for(let i of r.options){if(!co(i)||!ot(i,["value","label"])||!po(i.value)||!lo(i.label)||s.has(i.value))return!1;s.add(i.value)}if(!s.has(r.value))return!1}return!0};var nt=e=>"bytes"in e?e.bytes.byteLength:e.content.length,Eo=(e,o)=>{if(e.path!==o.path||e.readOnly!==o.readOnly)return!1;if(e.encoding==="text"||o.encoding==="text")return e.encoding==="text"&&o.encoding==="text"&&e.content===o.content;if(e.bytes.byteLength!==o.bytes.byteLength)return!1;for(let r=0;r<e.bytes.byteLength;r+=1)if(e.bytes[r]!==o.bytes[r])return!1;return!0};var _o=/^[A-Za-z0-9_-]{1,80}$/;var mo=["left","right","top","bottom"];var So=(e,o=0,r={remaining:16e3})=>{if(--r.remaining<0||o>=32)return!1;if(e===null)return!0;let s=Array.isArray(e)?e:Object(e)===e?Object.values(e):[];for(let i of s)if(!So(i,o+1,r))return!1;return!0},rt=e=>{if(e===null||e===!0||e===!1)return!0;if(Array.isArray(e))return Object.keys(e).every(o=>/^(0|[1-9]\d*)$/.test(o)&&Number(o)<e.length)&&e.every(rt);if(Object(e)===e){let o=Object.getPrototypeOf(e);return(o===null||o===Object.prototype)&&Object.values(e).every(rt)}return String(e)===e||Number.isFinite(e)},st=e=>{try{return String(e.id)!==e.id||!_o.test(e.id)||!Number.isFinite(e.anchor.x)||Math.abs(e.anchor.x)>1e5||!Number.isFinite(e.anchor.y)||Math.abs(e.anchor.y)>1e5||!Number.isFinite(e.anchor.width)||!Number.isFinite(e.anchor.height)||e.anchor.width<=0||e.anchor.height<=0||e.anchor.width>1e5||e.anchor.height>1e5||!Number.isInteger(e.width)||e.width<160||e.width>640||!Number.isInteger(e.height)||e.height<48||e.height>480||e.side!==void 0&&!mo.includes(e.side)||e.focus!==void 0&&e.focus!==!0&&e.focus!==!1||!So(e.data)||!rt(e.data)?!1:JSON.stringify(e.data).length<=16e3}catch{return!1}};var ho=["file","directory","other","missing"],at=e=>!!(e&&"sessionId"in e),ct=e=>!!(e&&"sent"in e&&!("sessionId"in e));var go=/^[0-9a-f]{7,64}$/i,dt=e=>go.test(e),Ie=500,Me=32e3,xo=16e3,bo=128,ko=200,Ao=2e3,yo=16e3,vo=80,Oo=200,Ro=16e3;var wo=2e3;var lt=2e4,Le=1024,Ge=2e6;var Ne=64e3,Pe=8e3,pt=4e3;var ut=96e4,dn=60*6e4;var Uo=999,Co=1e4,xe=500,Io=["HOST_UNAVAILABLE","HOST_TIMEOUT","HOST_REJECTED","DISCONNECTED","DISABLED","BAD_PATH","NO_INTEGRATION","NO_SERVICE","SERVICE_FAILED","REQUEST_FAILED","RESPONSE_TOO_LARGE","NO_SESSION","SESSION_BUSY","NOT_GRANTED","NO_DIRECTORY","NOT_FOUND","FILE_TOO_LARGE","DENIED","NO_MODEL","MODEL_FAILED","UNSUPPORTED"],Mo=["stopped","starting","ready","failed"],ln=new Set(Io),Lo=e=>ln.has(e),Go=e=>e&&Lo(e)?e:"HOST_REJECTED",ie=e=>e===void 0?!1:e===null||e===!0||e===!1||String(e)===e?!0:Number(e)===e?Number.isFinite(e):Array.isArray(e)?e.every(ie):Object(e)===e?Object.values(e).every(ie):!1,No=e=>ie(e)&&JSON.stringify(e).length<=Ro,To=e=>e?.trim().slice(0,Oo)??"",ae=e=>{let o=e.id.trim().slice(0,bo),r=e.title.trim().slice(0,ko),s=e.url.trim().slice(0,Ao),i=e.text?.trim().slice(0,yo),d=e.author?.trim().slice(0,vo),k=e.kind==="pull"?"pull":"issue",S={providerId:e.providerId.trim(),id:o,title:r||o,url:s,kind:k};if(i&&(S.text=i),d&&(S.author=d),k==="pull"){let h=To(e.branches?.head),v=To(e.branches?.base);h&&v&&(S.branches={head:h,base:v})}return No(e.data)&&(S.data=e.data),S},ft=e=>{let o=ae(e);return e.projectId&&(o.projectId=e.projectId),e.navigation&&(o.navigation=e.navigation),e.worktree&&(o.worktree=e.worktree),o},Et=e=>{let o={text:e.text.trim().slice(0,xo)};return e.send&&(o.send=!0),o},_t=e=>e===null||!Number.isFinite(e)?null:Math.min(Uo,Math.max(0,Math.round(e))),mt=e=>Number.isFinite(e)?Math.min(Co,Math.max(0,Math.ceil(e))):0;var ce=e=>e.length>0&&e.length<=Le&&!e.includes("\0")&&!e.includes("\\");var $e=e=>!e.startsWith("/")||e.includes("\0")||e.includes("\\")||e.includes("://")||e.length>wo?!1:!e.split("/").some(r=>r==="."||r===".."),pn=new Set(Mo),St=e=>!!(e&&"status"in e&&pn.has(String(e.status))&&!("body"in e)),He=e=>!!(e&&"status"in e&&"body"in e&&Number.isInteger(e.status)),Tt=e=>!!(e&&"content"in e&&String(e.content)===e.content),ht=e=>!!(e&&"written"in e&&e.written===!0),gt=e=>!!(e&&"entries"in e&&Array.isArray(e.entries)),un=new Set(ho),xt=e=>!!(e&&"kind"in e&&"size"in e&&un.has(String(e.kind))&&Number.isFinite(e.size)),bt=e=>!!(e&&"text"in e&&String(e.text)===e.text&&!("status"in e)),fn=new Set(["workspace","shells","ready","directory","session","connection","settings","session-lifecycle","item","resolve","action","status-control-event","popover-closed","file-open","file-snapshot","file-saved","generate-late"]),En=e=>Object(e)===e?e:null,it=e=>String(e)===e&&e.length>0,_n=e=>{if(!it(e.id))return null;if(e.ok===!0){let o={channel:_,v:1,type:"result",id:e.id,ok:!0};return Object(e.payload)===e.payload&&(o.payload=e.payload),o}return e.ok===!1&&it(e.error)?{channel:_,v:1,type:"result",id:e.id,ok:!1,error:e.error,code:Go(it(e.code)?e.code:void 0)}:null},kt=e=>{let o=En(e);return!o||o.channel!==_||o.v!==1?null:o.type==="result"?_n(o):!fn.has(String(o.type))||Object(o.payload)!==o.payload?null:o};var Po=e=>"key"in e&&"metaKey"in e&&"ctrlKey"in e,mn=e=>(e.metaKey||e.ctrlKey)&&!e.altKey&&!e.shiftKey&&e.key.toLowerCase()==="s",p=class extends Error{code;constructor(o,r){super(r),this.name="HostRequestError",this.code=o}},$o=()=>Promise.reject(new p("BAD_PATH",'Request path must start with "/" and stay on the declared origin.')),De=()=>Promise.reject(new p("BAD_PATH",`File path must be 1 to ${Le} characters without NUL or backslash.`)),Fe=e=>{if(e!==void 0){if(Object(e)!==e||Array.isArray(e)||e.scope!==void 0&&e.scope!=="instance"&&e.scope!=="device")throw new p("HOST_REJECTED",'Storage scope must be "instance" or "device".');return e.scope==="device"?"device":void 0}},E=e=>(e.value+=1,`oc-${e.value}`),Rt=(e={})=>{let o=e.target??("window"in globalThis?window:null);if(!o)throw new p("HOST_UNAVAILABLE","No window. connectHost runs in a browser frame.");let r=e.acceptSource??(t=>t===o.parent),s=e.requestTimeoutMs??lt,i=new Set,d=new Set,k=new Set,S=new Set,h=new Set,v=new Set,G=new Set,oe=new Set,q=new Set,j=new Set,K=[],_e=null,me=null,ve=new Set,Oe=new Set,Se=null,Te=null,qe=!1,ne=new Map,re=new Map,se=new Map,H=!1,f={value:0},u=null,F=null,he=!1,ge=!1,Jt=null,Yt=t=>t?{sessionId:t.id,phase:t.busy?"started":"completed"}:null,N=t=>{o.parent.postMessage(t,"*")},qt=()=>{H||o.parent===o||j.size===0||u?.features?.lateGenerateResults!==!0||N({channel:_,v:1,type:"generate-late-listen"})},A=(t,n)=>{for(let c of t)try{c(n)}catch(l){console.error(l)}},Qt=t=>{if(!(t instanceof MessageEvent)||!r(t.source))return;let n=kt(t.data);if(!n)return;if(n.type==="workspace"){let l=re.get(n.payload.subscriptionId);l&&A([l],n.payload.snapshot);return}if(n.type==="shells"){let l=se.get(n.payload.subscriptionId);l&&A([l],n.payload.snapshot);return}if(n.type==="ready"){u=n.payload,F=Yt(n.payload.session),A(i,n.payload),A(d,n.payload.directory),A(k,n.payload.session),F&&A(S,F),A(h,n.payload.connection),A(v,n.payload.settings),A(G,n.payload.item),qt();return}if(n.type==="generate-late"){j.size===0?K.push(n.payload):A(j,n.payload);return}if(n.type==="directory"){u&&(u={...u,directory:n.payload.directory}),A(d,n.payload.directory);return}if(n.type==="session"){u&&(u={...u,session:n.payload.session}),n.payload.session?F?.sessionId!==n.payload.session.id&&(F=Yt(n.payload.session)):F=null,A(k,n.payload.session);return}if(n.type==="session-lifecycle"){F=n.payload,A(S,n.payload);return}if(n.type==="connection"){u&&(u={...u,connection:n.payload.connection}),A(h,n.payload.connection);return}if(n.type==="settings"){u&&(u={...u,settings:n.payload.settings}),A(v,n.payload.settings);return}if(n.type==="item"){u&&(u={...u,item:n.payload.item}),A(G,n.payload.item);return}if(n.type==="status-control-event"){A(oe,n.payload);return}if(n.type==="popover-closed"){A(q,n.payload);return}if(n.type==="action"){let l=T=>{H||N({channel:_,v:1,type:"action-result",id:n.id,payload:T})},g=me;if(!g){l({ok:!1,error:"This extension does not handle background actions."});return}Promise.resolve().then(()=>g(n.payload)).then(()=>l({ok:!0}),T=>{let w=(T instanceof Error?T.message:String(T)).trim();l({ok:!1,error:(w||"Action failed.").slice(0,xe)})});return}if(n.type==="file-open"){let l=n.payload;if(Te&&Eo(Te,l))return;Te=l,A(ve,n.payload);return}if(n.type==="file-saved"){A(Oe,n.payload.version);return}if(n.type==="file-snapshot"){let l=w=>{H||N({channel:_,v:1,type:"file-snapshot-result",id:n.id,payload:w})},g=w=>l({error:(w.trim()||"Could not read the edited file.").slice(0,xe)}),T=Se;if(!T){g("This extension does not edit files.");return}Promise.resolve().then(()=>T(n.payload.purpose)).then(w=>{if(nt(w)>2e7){g(`The file is over ${2e7} ${"bytes"in w?"bytes":"characters"}.`);return}if(w.version.length>256){g(`The snapshot version is over ${256} characters.`);return}l({snapshot:"bytes"in w?{bytes:w.bytes,version:w.version}:{content:w.content,version:w.version}})},w=>g(w instanceof Error?w.message:String(w)));return}if(n.type==="resolve"){let l=T=>{N({channel:_,v:1,type:"resolve-result",id:n.id,payload:T})},g=_e;if(!g){l({error:"This extension does not resolve commands."});return}Promise.resolve().then(()=>g(n.payload)).then(T=>l({item:T?ae(T):null}),T=>{let w=(T instanceof Error?T.message:String(T)).trim();l({error:(w||"Command failed.").slice(0,xe)})});return}let c=ne.get(n.id);if(c){if(clearTimeout(c.timer),ne.delete(n.id),n.ok){c.resolve(n.payload);return}c.reject(new p(n.code,n.error))}};o.addEventListener("message",Qt),N({channel:_,v:1,type:"hello"});let U=(t,n=s)=>H||o.parent===o?Promise.reject(new p("HOST_UNAVAILABLE","No host frame. This page is not in an iframe.")):new Promise((c,l)=>{let g=setTimeout(()=>{ne.delete(t.id),l(new p("HOST_TIMEOUT","Host did not answer in time."))},n);ne.set(t.id,{resolve:c,reject:l,timer:g}),N(t)}),O=t=>U(t).then(()=>{}),R={channel:_,v:1},Qe=t=>{!H&&o.parent!==o&&N(t)},Zt=()=>Qe({...R,type:"file-save"}),eo=t=>{!Po(t)||!mn(t)||(t.preventDefault(),Zt())},to=t=>{!Po(t)||t.key!=="Escape"||u?.surface!=="popover"||!u.popover||(t.preventDefault(),so(u.popover.id,"escape").catch(()=>{}))},Re=()=>{let t=u?.surface==="popover"?u.popover:void 0;if(!t)return;let n=he||ge;Jt!==n&&(Jt=n,io(t.id,n).catch(()=>{}))},we=()=>{u?.surface!=="popover"||he||(he=!0,Re())},oo=t=>{u?.surface!=="popover"||t.relatedTarget!==null||!he||(he=!1,Re())},no=()=>{u?.surface!=="popover"||ge||(ge=!0,Re())},ro=()=>{u?.surface!=="popover"||!ge||(ge=!1,Re())},$=(t,n=1024)=>{if(!t.trim()||t.length>n)throw new p("HOST_REJECTED",`Identity must contain 1 to ${n} characters.`)},Ze=async t=>{t.kind!=="projects"&&$(t.projectId);let n=await U({...R,type:"workspace-read",id:E(f),payload:t});if(!n||!("kind"in n)||!("state"in n)||n.kind!==t.kind)throw new p("HOST_REJECTED","Host did not return workspace data.");return n},et=async(t,n)=>{t.kind!=="projects"&&$(t.projectId);let c=E(f);re.set(c,n);try{await O({...R,type:"workspace-subscribe",id:E(f),payload:{subscriptionId:c,query:t}})}catch(l){throw re.delete(c),H||N({...R,type:"workspace-unsubscribe",id:E(f),payload:{subscriptionId:c}}),l}return()=>{!re.delete(c)||H||N({...R,type:"workspace-unsubscribe",id:E(f),payload:{subscriptionId:c}})}},an=async(t,n)=>{t.kind==="session"&&$(t.sessionId),t.kind==="project"&&$(t.projectId);let c=E(f);se.set(c,n);try{await O({...R,type:"shells-subscribe",id:E(f),payload:{subscriptionId:c,scope:t}})}catch(l){throw se.delete(c),H||N({...R,type:"shells-unsubscribe",id:E(f),payload:{subscriptionId:c}}),l}return()=>{!se.delete(c)||H||N({...R,type:"shells-unsubscribe",id:E(f),payload:{subscriptionId:c}})}},Ue=async t=>{if("key"in t&&(t.key.length===0||t.key.length>128))throw new p("HOST_REJECTED","Storage key must contain 1 to 128 characters.");if(t.op==="set"&&!ie(t.value))throw new p("HOST_REJECTED","Storage values must be JSON.");if(t.op==="set"&&new TextEncoder().encode(JSON.stringify(t.value)).length>65536)throw new p("HOST_REJECTED","Storage value exceeds 64 KiB.");if(t.scope==="device"&&u?.features?.deviceStorage!==!0)throw new p("UNSUPPORTED","This host does not support device storage.");let n=await U({...R,type:"storage",id:E(f),payload:t});if(!n||!("storage"in n)||n.op!==t.op)throw new p("HOST_REJECTED","Host did not return storage data.");return n},so=(t,n)=>u?.features?.popovers!==!0&&!(u?.surface==="popover"&&u.popover?.id===t)?Promise.reject(new p("UNSUPPORTED","This host does not support popovers.")):O({...R,type:"popover-close",id:E(f),payload:n?{id:t,reason:n}:{id:t}}),io=(t,n)=>u?.features?.popovers!==!0&&!(u?.surface==="popover"&&u.popover?.id===t)?Promise.reject(new p("UNSUPPORTED","This host does not support popovers.")):O({...R,type:"popover-anchor",id:E(f),payload:{id:t,active:n}});return o.addEventListener("keydown",to,!0),o.addEventListener("pointerover",we),o.addEventListener("pointermove",we),o.addEventListener("pointerout",oo),o.addEventListener("focus",no),o.addEventListener("blur",ro),{onAction:t=>(me=t,()=>{me===t&&(me=null)}),listProjects:async()=>{let t=await Ze({kind:"projects"});if(t.kind!=="projects")throw new p("HOST_REJECTED","Expected projects.");return t},listWorktrees:async t=>{let n=await Ze({kind:"worktrees",projectId:t});if(n.kind!=="worktrees")throw new p("HOST_REJECTED","Expected worktrees.");return n},listSessions:async t=>{let n=await Ze({kind:"sessions",projectId:t});if(n.kind!=="sessions")throw new p("HOST_REJECTED","Expected sessions.");return n},onProjects:t=>et({kind:"projects"},n=>{n.kind==="projects"&&t(n)}),onWorktrees:(t,n)=>et({kind:"worktrees",projectId:t},c=>{c.kind==="worktrees"&&n(c)}),onSessions:(t,n)=>et({kind:"sessions",projectId:t},c=>{c.kind==="sessions"&&n(c)}),onRunningShells:(t,n)=>an(t,n),readShellOutput:async(t,n)=>{$(t,128);let c=n?.cursor;if(c!==void 0&&(!Number.isInteger(c)||c<0))throw new p("HOST_REJECTED","Shell output cursor must be a non-negative integer.");let l=n?.tailBytes;if(l!==void 0&&(!Number.isInteger(l)||l<1||l>65536))throw new p("HOST_REJECTED",`Shell output tailBytes must be an integer between 1 and ${65536}.`);let T=await U({...R,type:"shell-output",id:E(f),payload:{shellId:t,cursor:c,tailBytes:l}});if(!T||typeof T.output!="string"||!Number.isFinite(T.cursor))throw new p("HOST_REJECTED","Host did not return shell output.");return T},stopShell:async t=>{if($(t,128),(await U({...R,type:"shell-stop",id:E(f),payload:{shellId:t}}))?.stopped!==!0)throw new p("HOST_REJECTED","Host did not stop the shell.");return{stopped:!0}},openSession:async t=>{$(t),await O({...R,type:"open-session",id:E(f),payload:{sessionId:t}})},storage:{get:async(t,n)=>{let c=Fe(n),l={op:"get",key:t};c&&(l.scope=c);let g=await Ue(l);return g.op==="get"&&g.found?g.value:void 0},set:async(t,n,c)=>{let l=Fe(c),g={op:"set",key:t,value:n};l&&(g.scope=l),await Ue(g)},delete:async(t,n)=>{let c=Fe(n),l={op:"delete",key:t};c&&(l.scope=c),await Ue(l)},keys:async t=>{let n=Fe(t),c={op:"keys"};n&&(c.scope=n);let l=await Ue(c);if(l.op!=="keys")throw new p("HOST_REJECTED","Expected storage keys.");return l.keys}},onReady:t=>(i.add(t),u&&t(u),()=>{i.delete(t)}),onDirectory:t=>(d.add(t),u&&t(u.directory),()=>{d.delete(t)}),onSession:t=>(k.add(t),u&&t(u.session),()=>{k.delete(t)}),onSessionLifecycle:t=>(S.add(t),F&&t(F),()=>{S.delete(t)}),onConnection:t=>(h.add(t),u&&t(u.connection),()=>{h.delete(t)}),onSettings:t=>(v.add(t),u&&t(u.settings),()=>{v.delete(t)}),onItem:t=>(G.add(t),u&&t(u.item),()=>{G.delete(t)}),onStatusControl:t=>(oe.add(t),()=>{oe.delete(t)}),onPopoverClosed:t=>(q.add(t),()=>{q.delete(t)}),setStatusControls:t=>u?.features?.statusControls!==!0?Promise.reject(new p("UNSUPPORTED","This host does not support status controls.")):fo(t)?O({...R,type:"status-controls",id:E(f),payload:{controls:t}}):Promise.reject(new p("HOST_REJECTED","Status controls must have unique bounded ids and valid selected options.")),openPopover:t=>u?.features?.popovers!==!0?Promise.reject(new p("UNSUPPORTED","This host does not support popovers.")):st(t)?O({...R,type:"popover-open",id:E(f),payload:t}):Promise.reject(new p("HOST_REJECTED","Popover requests need bounded geometry and JSON data.")),closePopover:so,setPopoverAnchorActive:io,onResolve:t=>(_e=t,()=>{_e===t&&(_e=null)}),toast:t=>{let n=t.message.trim();return!n||n.length>Ie?Promise.reject(new p("HOST_REJECTED",`Toast message must contain 1 to ${Ie} characters.`)):t.copy&&t.copy!==!0&&(!t.copy.text.length||t.copy.text.length>Me)?Promise.reject(new p("HOST_REJECTED",`Toast copy text must contain 1 to ${Me} characters.`)):O({channel:_,v:1,type:"toast",id:E(f),payload:{...t,message:n}})},openUrl:t=>O({channel:_,v:1,type:"open-url",id:E(f),payload:{url:t}}),openCommit:t=>dt(t)?O({channel:_,v:1,type:"open-commit",id:E(f),payload:{sha:t}}):Promise.reject(new p("HOST_REJECTED","Commit id must be 7 to 64 hex characters.")),openSurface:t=>O({channel:_,v:1,type:"open-surface",id:E(f),payload:{surfaceId:t}}),writeClipboard:t=>O({channel:_,v:1,type:"clipboard-write",id:E(f),payload:{text:t}}),compose:t=>O({channel:_,v:1,type:"compose",id:E(f),payload:t}),attach:t=>O({channel:_,v:1,type:"attach",id:E(f),payload:ae(t)}),startSession:async t=>{t.projectId!==void 0&&$(t.projectId);let n=t.worktree;n&&n!==!0&&(n.kind==="existing"?$(n.directory):(n.name!==void 0&&$(n.name,200),n.baseBranch!==void 0&&$(n.baseBranch,200)));let c=await U({channel:_,v:1,type:"start-session",id:E(f),payload:ft(t)},e.requestTimeoutMs??18e4);if(!at(c))throw new p("HOST_REJECTED","Host did not return a session.");return c},prompt:t=>U({channel:_,v:1,type:"prompt",id:E(f),payload:Et(t)}).then(n=>{if(!ct(n))throw new p("HOST_REJECTED","Host did not return a prompt result.");return n}),sessionLink:t=>O({channel:_,v:1,type:"session-link",id:E(f),payload:ae(t)}),close:()=>O({channel:_,v:1,type:"close",id:E(f)}),oauthStart:()=>O({channel:_,v:1,type:"oauth-start",id:E(f)}),oauthDisconnect:()=>O({channel:_,v:1,type:"oauth-disconnect",id:E(f)}),request:t=>($e(t.path)?U({channel:_,v:1,type:"request",id:E(f),payload:t}):$o()).then(n=>{if(!He(n))throw new p("HOST_REJECTED","Host request result was empty.");return n}),serviceRequest:t=>($e(t.path)?U({channel:_,v:1,type:"service-request",id:E(f),payload:t}):$o()).then(n=>{if(!He(n))throw new p("HOST_REJECTED","Host service request result was empty.");return n}),serviceStatus:()=>U({channel:_,v:1,type:"service-status",id:E(f)}).then(t=>{if(!St(t))throw new p("HOST_REJECTED","Host did not return service status.");return t}),readFile:t=>(ce(t)?U({channel:_,v:1,type:"file-read",id:E(f),payload:{path:t}}):De()).then(n=>{if(!Tt(n))throw new p("HOST_REJECTED","Host did not return file content.");return n}),writeFile:(t,n)=>ce(t)?n.length>Ge?Promise.reject(new p("FILE_TOO_LARGE",`Content is over ${Ge} characters.`)):U({channel:_,v:1,type:"file-write",id:E(f),payload:{path:t,content:n}}).then(c=>{if(!ht(c))throw new p("HOST_REJECTED","Host did not confirm the write.");return c}):De(),listDir:t=>(ce(t)?U({channel:_,v:1,type:"file-list",id:E(f),payload:{path:t}}):De()).then(n=>{if(!gt(n))throw new p("HOST_REJECTED","Host did not return directory entries.");return n}),stat:t=>(ce(t)?U({channel:_,v:1,type:"file-stat",id:E(f),payload:{path:t}}):De()).then(n=>{if(!xt(n))throw new p("HOST_REJECTED","Host did not return file status.");return n}),generate:t=>{let n=t.prompt.trim(),c=t.system?.trim();if(n.length===0||n.length>Ne)return Promise.reject(new p("HOST_REJECTED",`Prompt must be 1 to ${Ne} characters.`));if(c!==void 0&&(c.length===0||c.length>Pe))return Promise.reject(new p("HOST_REJECTED",`System prompt must be 1 to ${Pe} characters.`));let l=t.maxOutputTokens===void 0?void 0:Math.min(pt,Math.max(1,Math.floor(t.maxOutputTokens)));if(l!==void 0&&!Number.isFinite(l))return Promise.reject(new p("HOST_REJECTED","maxOutputTokens must be a number."));let g={prompt:n};return c!==void 0&&(g.system=c),l!==void 0&&(g.maxOutputTokens=l),U({channel:_,v:1,type:"generate",id:E(f),payload:g},e.requestTimeoutMs??ut).then(T=>{if(!bt(T))throw new p("HOST_REJECTED","Host did not return generated text.");return T})},onLateGenerateResult:t=>{j.add(t);for(let n of K.splice(0))A([t],n);return qt(),()=>{j.delete(t)}},setBadge:t=>O({channel:_,v:1,type:"badge",id:E(f),payload:{count:_t(t)}}),setHeight:t=>O({channel:_,v:1,type:"resize",id:E(f),payload:{height:mt(t)}}),onFileOpen:t=>(ve.add(t),qe||(qe=!0,o.addEventListener("keydown",eo,!0)),Te&&t(Te),()=>{ve.delete(t)}),onFileSnapshot:t=>(Se=t,()=>{Se===t&&(Se=null)}),onFileSaved:t=>(Oe.add(t),()=>{Oe.delete(t)}),reportFileChange:t=>Qe({...R,type:"file-change",payload:{dirty:t.dirty,edited:t.edited}}),requestFileSave:Zt,reportFileUnsupported:()=>Qe({...R,type:"file-unsupported"}),dispose:()=>{for(let t of re.keys())N({...R,type:"workspace-unsubscribe",id:E(f),payload:{subscriptionId:t}});re.clear();for(let t of se.keys())N({...R,type:"shells-unsubscribe",id:E(f),payload:{subscriptionId:t}});se.clear(),H=!0,_e=null,me=null,Se=null,ve.clear(),Oe.clear(),qe&&o.removeEventListener("keydown",eo,!0),o.removeEventListener("message",Qt),o.removeEventListener("keydown",to,!0),o.removeEventListener("pointerover",we),o.removeEventListener("pointermove",we),o.removeEventListener("pointerout",oo),o.removeEventListener("focus",no),o.removeEventListener("blur",ro);for(let t of ne.values())clearTimeout(t.timer),t.reject(new p("HOST_UNAVAILABLE","Host client was disposed."));ne.clear(),i.clear(),d.clear(),k.clear(),S.clear(),h.clear(),v.clear(),G.clear(),oe.clear(),q.clear(),j.clear(),K.length=0}}};var Fo=["browser.open","browser.snapshot","browser.click","browser.type","browser.scroll","browser.back","browser.forward","browser.inspect","browser.capture","browser.resize","browser.close"];var dr=new Set(Fo);var Xo=["none","agent","user"];var pr=new Set(Xo);var Sn=[["--oc-bg","background"],["--oc-elevated","elevated"],["--oc-fg","foreground"],["--oc-muted","muted"],["--oc-subtle","subtle"],["--oc-border","border"],["--oc-hover","hover"],["--oc-selection","selection"],["--oc-focus","focus"],["--oc-primary","primary"],["--oc-muted-surface","mutedSurface"],["--oc-elevated-fg","elevatedForeground"],["--oc-active","active"],["--oc-selection-fg","selectionForeground"],["--oc-primary-fg","primaryForeground"],["--oc-primary-text","primaryText"],["--oc-success-text","successText"],["--oc-warning-text","warningText"],["--oc-error-text","errorText"],["--oc-info-text","infoText"],["--oc-success","success"],["--oc-warning","warning"],["--oc-error","error"],["--oc-info","info"],["--oc-font","font"],["--oc-mono","mono"],["--oc-radius","radius"],["--surface-background","background"],["--surface-elevated","elevated"],["--surface-foreground","foreground"],["--surface-muted-foreground","muted"],["--surface-subtle","subtle"],["--interactive-border","border"],["--interactive-hover","hover"],["--interactive-selection","selection"],["--interactive-focus-ring","focus"],["--primary","primary"],["--surface-muted","mutedSurface"],["--surface-elevated-foreground","elevatedForeground"],["--interactive-active","active"],["--interactive-selection-foreground","selectionForeground"],["--primary-foreground","primaryForeground"],["--primary-text","primaryText"],["--success-text","successText"],["--warning-text","warningText"],["--error-text","errorText"],["--info-text","infoText"],["--status-success","success"],["--status-warning","warning"],["--status-error","error"],["--status-info","info"],["--font-sans","font"],["--font-mono","mono"],["--radius","radius"]],Tn=[["--oc-syntax-keyword","--syntax-keyword","syntaxKeyword"],["--oc-syntax-string","--syntax-string","syntaxString"],["--oc-syntax-number","--syntax-number","syntaxNumber"],["--oc-syntax-function","--syntax-function","syntaxFunction"],["--oc-syntax-type","--syntax-type","syntaxType"],["--oc-syntax-comment","--syntax-comment","syntaxComment"],["--oc-syntax-variable","--syntax-variable","syntaxVariable"],["--oc-syntax-operator","--syntax-operator","syntaxOperator"]],Bo=(e,o)=>{o.style.colorScheme=e.mode;for(let[r,s]of Sn)o.style.setProperty(r,e.tokens[s]);for(let[r,s,i]of Tn){let d=e.tokens[i]??"";o.style.setProperty(r,d),o.style.setProperty(s,d)}o.style.setProperty("font-family",e.tokens.font),o.style.setProperty("font-size","0.875rem"),o.style.setProperty("line-height","1.45"),o.style.setProperty("color",e.tokens.foreground)},wt=(e,o)=>{Bo(e.theme,o),o.dataset&&(o.dataset.ocSurface=e.surface,o.dataset.ocTheme=e.theme.mode)};var hn={"surface-background":"bg","surface-elevated":"elevated","surface-elevated-foreground":"elevated-fg","surface-foreground":"fg","surface-muted-foreground":"muted","surface-muted":"muted-surface","surface-subtle":"subtle","interactive-border":"border","interactive-hover":"hover","interactive-active":"active","interactive-selection":"selection","interactive-selection-foreground":"selection-fg","interactive-focus-ring":"focus",primary:"primary","primary-foreground":"primary-fg","primary-text":"primary-text","success-text":"success-text","warning-text":"warning-text","error-text":"error-text","info-text":"info-text","status-success":"success","status-warning":"warning","status-error":"error","status-info":"info","font-sans":"font","font-mono":"mono",radius:"radius"},b=(e,o)=>`var(--${e}, var(--oc-${hn[e]}, ${o}))`,B=b("surface-background","transparent"),Be=b("surface-elevated","transparent"),de=b("surface-elevated-foreground","inherit"),P=b("surface-foreground","inherit"),x=b("surface-muted-foreground","gray"),gn=b("surface-muted","transparent"),W=b("interactive-border","currentColor"),C=b("interactive-hover","transparent"),Q=b("interactive-active","transparent"),Ut=b("interactive-selection","transparent"),Ct=b("interactive-selection-foreground","inherit"),X=b("primary","currentColor"),It=b("primary-text","inherit"),Mt=b("error-text","inherit"),xn=b("font-sans","inherit"),Lt=b("font-mono","monospace"),Wo=b("radius","9px"),Gt=`calc(${Wo} - 2px)`,Vo=`calc(${Wo} - 4px)`,y=(e,o,r="transparent")=>`color-mix(in srgb, ${e} ${o}%, ${r})`,zo=`background-image: linear-gradient(${C}, ${C});`,Nt=e=>`box-shadow: inset 0 0 0 1px ${e}, var(--oc-sdk-field-lift);`,Pt="box-shadow: inset 0 0 0 1px var(--oc-sdk-edge), var(--oc-sdk-raised-lift);",jo="box-shadow: var(--oc-sdk-lit);",Ko=`inset 0 1px 0 0 ${y(P,1.5)}, 0 1px 1px 0 rgb(0 0 0 / 0.28), 0 2px 3px -2px rgb(0 0 0 / 0.2)`,bn=`
|
|
36
|
+
:root {
|
|
37
|
+
--oc-sdk-edge: ${y(P,10)};
|
|
38
|
+
--oc-sdk-field-bg: ${Be};
|
|
39
|
+
--oc-sdk-raised-bg: ${B};
|
|
40
|
+
--oc-sdk-field-lift: inset 0 1px 2px 0 rgb(0 0 0 / 0.04);
|
|
41
|
+
--oc-sdk-raised-lift: 0 1px 2px 0 rgb(0 0 0 / 0.06);
|
|
42
|
+
--oc-sdk-lit: inset 0 1px 0 0 rgb(255 255 255 / 0.45), 0 1px 2px 0 rgb(0 0 0 / 0.08);
|
|
43
|
+
--oc-sdk-float: inset 0 1px 0 0 rgb(255 255 255 / 0.8), inset 0 0 0 1px rgb(0 0 0 / 0.04), 0 0 0 1px rgb(0 0 0 / 0.1), 0 1px 2px -0.5px rgb(0 0 0 / 0.08), 0 4px 8px -2px rgb(0 0 0 / 0.08), 0 12px 20px -4px rgb(0 0 0 / 0.08);
|
|
44
|
+
}
|
|
45
|
+
:root[data-oc-theme="dark"] {
|
|
46
|
+
--oc-sdk-edge: ${y(P,6)};
|
|
47
|
+
--oc-sdk-field-bg: ${y(B,50,Be)};
|
|
48
|
+
--oc-sdk-raised-bg: ${Be};
|
|
49
|
+
--oc-sdk-field-lift: ${Ko};
|
|
50
|
+
--oc-sdk-raised-lift: ${Ko};
|
|
51
|
+
--oc-sdk-lit: inset 0 1px 0 0 ${y(P,1.5)}, 0 1px 1px 0 rgb(0 0 0 / 0.28), 0 2px 3px -2px rgb(0 0 0 / 0.2);
|
|
52
|
+
--oc-sdk-float: inset 0 1px 0 0 rgb(255 255 255 / 0.06), inset 0 0 0 1px rgb(255 255 255 / 0.08), 0 0 0 1px rgb(0 0 0 / 0.36), 0 1px 1px -0.5px rgb(0 0 0 / 0.22), 0 3px 3px -1.5px rgb(0 0 0 / 0.2), 0 6px 6px -3px rgb(0 0 0 / 0.16);
|
|
53
|
+
}`,Xe=e=>{let o=b(`status-${e}`,"currentColor");return`
|
|
54
|
+
.oc-sdk[data-tone="${e}"], .oc-sdk [data-tone="${e}"] { --oc-sdk-tone: ${o}; --oc-sdk-tone-text: ${b(`${e}-text`,"inherit")}; }`},kn=`
|
|
55
|
+
.oc-sdk { box-sizing: border-box; font-size: 0.875rem; line-height: 1.45; }
|
|
56
|
+
.oc-sdk *, .oc-sdk *::before, .oc-sdk *::after { box-sizing: border-box; }
|
|
57
|
+
/* :where() keeps the reset at zero specificity so every primitive class below overrides it. */
|
|
58
|
+
:where(.oc-sdk) :where(button, input, textarea), :where(button.oc-sdk, input.oc-sdk, textarea.oc-sdk) { font: inherit; color: inherit; margin: 0; }
|
|
59
|
+
:where(.oc-sdk) :where(button), :where(button.oc-sdk) { cursor: pointer; background: none; border: 0; padding: 0; }
|
|
60
|
+
.oc-sdk button:disabled, button.oc-sdk:disabled, .oc-sdk[aria-disabled="true"], .oc-sdk [aria-disabled="true"] { opacity: .5; pointer-events: none; }
|
|
61
|
+
|
|
62
|
+
.oc-sdk-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 32px; padding: 0 12px; border: 1px solid transparent; font-size: 0.875rem; font-weight: 500; line-height: 1; white-space: nowrap; }
|
|
63
|
+
.oc-sdk-btn[data-size="sm"] { gap: 6px; height: 28px; padding: 0 10px; font-size: 0.8125rem; }
|
|
64
|
+
.oc-sdk-btn[data-size="xs"] { gap: 4px; height: 24px; padding: 0 8px; font-size: 0.75rem; }
|
|
65
|
+
.oc-sdk-btn[data-loading="true"] { opacity: .5; pointer-events: none; }
|
|
66
|
+
.oc-sdk-btn > .oc-sdk-spinner-ring { width: 14px; height: 14px; }
|
|
67
|
+
|
|
68
|
+
.oc-sdk-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
|
|
69
|
+
.oc-sdk-field-label { font-size: 0.8125rem; font-weight: 500; }
|
|
70
|
+
.oc-sdk-field-note { font-size: 0.75rem; }
|
|
71
|
+
.oc-sdk-input { display: block; width: 100%; min-width: 0; height: 32px; padding: 0 10px; border: 0; font-size: 0.875rem; line-height: 1.45; appearance: none; }
|
|
72
|
+
textarea.oc-sdk-input { height: auto; padding: 8px 10px; resize: vertical; }
|
|
73
|
+
|
|
74
|
+
.oc-sdk-search { position: relative; min-width: 0; }
|
|
75
|
+
.oc-sdk-search .oc-sdk-input { padding-left: 34px; padding-right: 34px; }
|
|
76
|
+
.oc-sdk-search-icon { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); pointer-events: none; }
|
|
77
|
+
.oc-sdk-search-clear { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); display: none; align-items: center; justify-content: center; width: 24px; height: 24px; }
|
|
78
|
+
.oc-sdk-search[data-active="true"] .oc-sdk-search-clear { display: inline-flex; }
|
|
79
|
+
|
|
80
|
+
.oc-sdk-select { position: relative; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
|
|
81
|
+
.oc-sdk-trigger { display: inline-flex; align-items: center; gap: 6px; align-self: flex-start; width: auto; max-width: 100%; min-width: 0; height: 28px; padding: 0 10px; border: 1px solid transparent; font-size: 0.8125rem; text-align: left; }
|
|
82
|
+
.oc-sdk-trigger-value { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
83
|
+
.oc-sdk-trigger-chevron { flex: 0 0 auto; }
|
|
84
|
+
.oc-sdk-popup { position: fixed; z-index: 50; display: flex; flex-direction: column; gap: 2px; min-width: 160px; max-width: calc(100vw - 16px); max-height: min(320px, calc(100vh - 16px)); overflow: auto; padding: 4px; border: 1px solid transparent; }
|
|
85
|
+
.oc-sdk-popup-search { flex: 0 0 auto; padding: 2px 2px 4px; }
|
|
86
|
+
.oc-sdk-popup-search .oc-sdk-input { height: 28px; font-size: 0.8125rem; }
|
|
87
|
+
.oc-sdk-option { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 8px; font-size: 0.8125rem; text-align: left; }
|
|
88
|
+
.oc-sdk-option-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
89
|
+
.oc-sdk-option-hint { flex: 0 0 auto; font-size: 0.75rem; }
|
|
90
|
+
.oc-sdk-option-check { flex: 0 0 auto; display: inline-flex; width: 14px; visibility: hidden; }
|
|
91
|
+
.oc-sdk-option[aria-selected="true"] > .oc-sdk-option-check { visibility: visible; }
|
|
92
|
+
.oc-sdk-popup-empty { padding: 8px; font-size: 0.8125rem; }
|
|
93
|
+
|
|
94
|
+
.oc-sdk-check { display: inline-flex; align-items: flex-start; gap: 8px; width: 100%; text-align: left; }
|
|
95
|
+
.oc-sdk-check-box { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; margin-top: 3px; border: 1px solid transparent; }
|
|
96
|
+
.oc-sdk-check-box > svg { display: none; }
|
|
97
|
+
.oc-sdk-check[aria-checked="true"] .oc-sdk-check-box > svg { display: block; }
|
|
98
|
+
.oc-sdk-check-thumb { flex: 0 0 auto; position: relative; width: 36px; height: 20px; }
|
|
99
|
+
.oc-sdk-check-thumb::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; }
|
|
100
|
+
.oc-sdk-check-text { display: flex; flex-direction: column; min-width: 0; }
|
|
101
|
+
.oc-sdk-check-label { font-size: 0.875rem; }
|
|
102
|
+
.oc-sdk-check-desc { font-size: 0.75rem; }
|
|
103
|
+
|
|
104
|
+
.oc-sdk-tabs { display: inline-flex; gap: 2px; padding: 2px; max-width: 100%; overflow: auto; }
|
|
105
|
+
.oc-sdk-tab { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border: 1px solid transparent; font-size: 0.8125rem; font-weight: 500; white-space: nowrap; }
|
|
106
|
+
.oc-sdk-tab-count { font-size: 0.75rem; font-variant-numeric: tabular-nums; }
|
|
107
|
+
|
|
108
|
+
.oc-sdk-badge { display: inline-flex; align-items: center; padding: 1px 6px; font-size: 11px; font-weight: 500; line-height: 16px; white-space: nowrap; }
|
|
109
|
+
|
|
110
|
+
.oc-sdk-list { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
|
|
111
|
+
.oc-sdk-row { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 8px; text-align: left; }
|
|
112
|
+
.oc-sdk-row-lead { flex: 0 0 auto; width: 64px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.75rem; }
|
|
113
|
+
.oc-sdk-row-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
|
|
114
|
+
.oc-sdk-row-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
115
|
+
.oc-sdk-row-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.75rem; }
|
|
116
|
+
.oc-sdk-row-meta { flex: 0 0 auto; font-size: 0.75rem; font-variant-numeric: tabular-nums; }
|
|
117
|
+
.oc-sdk-list-empty { padding: 16px 8px; text-align: center; font-size: 0.8125rem; }
|
|
118
|
+
|
|
119
|
+
.oc-sdk-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; padding: 40px 16px; text-align: center; }
|
|
120
|
+
.oc-sdk-empty-title { margin: 0; font-size: 0.8125rem; font-weight: 600; }
|
|
121
|
+
.oc-sdk-empty-body { margin: 0; max-width: 32rem; font-size: 0.8125rem; }
|
|
122
|
+
.oc-sdk-empty-action { margin-top: 12px; }
|
|
123
|
+
|
|
124
|
+
@keyframes oc-sdk-spin { to { transform: rotate(360deg); } }
|
|
125
|
+
.oc-sdk-spinner { display: inline-flex; align-items: center; gap: 8px; font-size: 0.8125rem; }
|
|
126
|
+
.oc-sdk-spinner-ring { width: 16px; height: 16px; border: 2px solid transparent; animation: oc-sdk-spin .8s linear infinite; }
|
|
127
|
+
.oc-sdk-spinner[data-size="sm"] .oc-sdk-spinner-ring { width: 12px; height: 12px; }
|
|
128
|
+
|
|
129
|
+
.oc-sdk-banner { display: flex; align-items: flex-start; gap: 12px; padding: 8px 12px; border: 1px solid transparent; }
|
|
130
|
+
.oc-sdk-banner-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
|
|
131
|
+
.oc-sdk-banner-title { font-size: 0.8125rem; font-weight: 500; }
|
|
132
|
+
.oc-sdk-banner-body { font-size: 0.8125rem; }
|
|
133
|
+
.oc-sdk-banner-action { flex: 0 0 auto; }
|
|
134
|
+
|
|
135
|
+
.oc-sdk-separator { display: flex; align-items: center; gap: 8px; width: 100%; margin: 8px 0; font-size: 0.75rem; }
|
|
136
|
+
.oc-sdk-separator::before, .oc-sdk-separator::after { content: ""; flex: 1 1 auto; height: 1px; }
|
|
137
|
+
.oc-sdk-separator[data-labeled="false"]::after { display: none; }
|
|
138
|
+
.oc-sdk-popup > .oc-sdk-separator { margin: 4px 0; }
|
|
139
|
+
|
|
140
|
+
.oc-sdk-progress { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
|
|
141
|
+
.oc-sdk-progress-label { display: flex; justify-content: space-between; font-size: 0.75rem; font-variant-numeric: tabular-nums; }
|
|
142
|
+
.oc-sdk-progress-track { height: 6px; overflow: hidden; }
|
|
143
|
+
.oc-sdk-progress-fill { height: 100%; transform-origin: left; transition: transform 200ms ease-out; }
|
|
144
|
+
|
|
145
|
+
.oc-sdk-menu { position: relative; display: inline-flex; }
|
|
146
|
+
|
|
147
|
+
.oc-sdk-text { white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
148
|
+
.oc-sdk-text img { display: block; max-width: 100%; margin: 8px 0; }
|
|
149
|
+
`,Jo=`${bn}
|
|
150
|
+
.oc-sdk { color: ${P}; font-family: ${xn}; }
|
|
151
|
+
.oc-sdk :focus-visible, .oc-sdk:focus-visible { outline: none; }
|
|
152
|
+
.oc-sdk :where(button, a[href], [role="button"], [role="tab"], [role="option"]):focus-visible, button.oc-sdk:focus-visible { ${zo} }
|
|
153
|
+
.oc-sdk-mono { font-family: ${Lt}; }
|
|
154
|
+
.oc-sdk-muted { color: ${x}; }
|
|
155
|
+
${Xe("success")}${Xe("warning")}${Xe("error")}${Xe("info")}
|
|
156
|
+
.oc-sdk[data-tone="primary"], .oc-sdk [data-tone="primary"] { --oc-sdk-tone: ${X}; --oc-sdk-tone-text: ${It}; }
|
|
157
|
+
|
|
158
|
+
.oc-sdk-btn { border-radius: ${Gt}; transition: background 150ms ease-out, color 150ms ease-out; }
|
|
159
|
+
.oc-sdk-btn[data-size="xs"] { border-radius: ${Vo}; }
|
|
160
|
+
.oc-sdk-btn[data-variant="default"] { color: ${It}; background: ${y(X,10,B)}; border-color: ${y(X,12)}; ${jo} }
|
|
161
|
+
.oc-sdk-btn[data-variant="default"]:hover { background: ${y(X,16,B)}; }
|
|
162
|
+
.oc-sdk-btn[data-variant="default"]:active { background: ${y(X,22,B)}; box-shadow: none; }
|
|
163
|
+
.oc-sdk-btn[data-variant="secondary"] { background: ${gn}; color: var(--oc-fg); }
|
|
164
|
+
.oc-sdk-btn[data-variant="secondary"]:hover { background-image: linear-gradient(${C}, ${C}); }
|
|
165
|
+
.oc-sdk-btn[data-variant="secondary"]:active { background-image: linear-gradient(${Q}, ${Q}); }
|
|
166
|
+
.oc-sdk-btn[data-variant="outline"] { background: var(--oc-sdk-raised-bg); color: ${de}; border-color: transparent; ${Pt} }
|
|
167
|
+
.oc-sdk-btn[data-variant="outline"]:hover { background-image: linear-gradient(${C}, ${C}); }
|
|
168
|
+
.oc-sdk-btn[data-variant="outline"]:active { background-image: linear-gradient(${Q}, ${Q}); box-shadow: inset 0 0 0 1px var(--oc-sdk-edge); }
|
|
169
|
+
.oc-sdk-btn[data-variant="ghost"] { background: transparent; }
|
|
170
|
+
.oc-sdk-btn[data-variant="ghost"]:hover { background: ${C}; }
|
|
171
|
+
.oc-sdk-btn[data-variant="ghost"]:active { background: ${Q}; }
|
|
172
|
+
.oc-sdk-btn[data-variant="destructive"] { --oc-sdk-tone: ${b("status-error","red")}; color: ${Mt}; background: ${y("var(--oc-sdk-tone)",7,B)}; border-color: ${y("var(--oc-sdk-tone)",12)}; ${jo} }
|
|
173
|
+
.oc-sdk-btn[data-variant="destructive"]:hover { background: ${y("var(--oc-sdk-tone)",9,B)}; }
|
|
174
|
+
.oc-sdk-btn[data-variant="destructive"]:active { background: ${y("var(--oc-sdk-tone)",11,B)}; box-shadow: none; }
|
|
175
|
+
|
|
176
|
+
.oc-sdk-field-note { color: ${x}; }
|
|
177
|
+
.oc-sdk-field[data-invalid="true"] .oc-sdk-field-note { color: ${Mt}; }
|
|
178
|
+
.oc-sdk-input { border-radius: ${Gt}; background: var(--oc-sdk-field-bg); color: ${de}; ${Nt("var(--oc-sdk-edge)")} transition: background 150ms ease-out; }
|
|
179
|
+
.oc-sdk-input::placeholder { color: ${x}; }
|
|
180
|
+
.oc-sdk-input:hover:not(:focus) { background-image: linear-gradient(${C}, ${C}); }
|
|
181
|
+
.oc-sdk-input:focus, .oc-sdk-input:focus-visible { ${Nt(y(P,26))} }
|
|
182
|
+
.oc-sdk-field[data-invalid="true"] .oc-sdk-input, .oc-sdk-field[data-invalid="true"] .oc-sdk-input:focus { ${Nt(b("status-error","red"))} }
|
|
183
|
+
.oc-sdk-input[data-mono="true"] { font-family: ${Lt}; }
|
|
184
|
+
|
|
185
|
+
.oc-sdk-search-icon { color: ${x}; }
|
|
186
|
+
.oc-sdk-search[data-active="true"] .oc-sdk-search-icon { color: ${X}; }
|
|
187
|
+
.oc-sdk-search-clear { border-radius: ${Vo}; color: ${x}; }
|
|
188
|
+
.oc-sdk-search-clear:hover { background: ${C}; color: ${P}; }
|
|
189
|
+
|
|
190
|
+
.oc-sdk-trigger { border-color: transparent; border-radius: ${Gt}; background: var(--oc-sdk-raised-bg); color: ${de}; ${Pt} transition: background 150ms ease-out; }
|
|
191
|
+
.oc-sdk-trigger:hover { background-image: linear-gradient(${C}, ${C}); }
|
|
192
|
+
.oc-sdk-trigger[aria-expanded="true"] { background-image: linear-gradient(${Q}, ${Q}); }
|
|
193
|
+
.oc-sdk-trigger-value[data-empty="true"] { color: ${x}; }
|
|
194
|
+
.oc-sdk-trigger-chevron { color: ${x}; }
|
|
195
|
+
/* The app's dropdown light: lit top, hairline rings and a layered shadow, no border. */
|
|
196
|
+
.oc-sdk-popup { --surface-foreground: ${de}; border-color: transparent; border-radius: 12px; background: ${Be}; color: ${de}; box-shadow: var(--oc-sdk-float); }
|
|
197
|
+
.oc-sdk-option { border-radius: 8px; }
|
|
198
|
+
.oc-sdk-option[data-active="true"] { background: ${C}; }
|
|
199
|
+
/* A selected option shows a check mark in the text colour, like the app's own pickers. Options without the mark come
|
|
200
|
+
from bundles built before it existed and keep the selection fill as their only sign of the choice. */
|
|
201
|
+
.oc-sdk-option[aria-selected="true"]:not([data-mark]) { background: ${Ut}; color: ${Ct}; }
|
|
202
|
+
.oc-sdk-option-check { color: ${P}; }
|
|
203
|
+
.oc-sdk-option[data-destructive="true"] { color: ${Mt}; }
|
|
204
|
+
.oc-sdk-option[data-destructive="true"][data-active="true"] { background: ${y(b("status-error","red"),10)}; }
|
|
205
|
+
.oc-sdk-option-hint { color: ${x}; }
|
|
206
|
+
.oc-sdk-popup-empty { color: ${x}; }
|
|
207
|
+
|
|
208
|
+
/* Checked stays neutral: the mark carries the state, and the primary colour stays with primary actions. */
|
|
209
|
+
.oc-sdk-check-box { border-color: ${W}; border-radius: 4px; color: ${P}; transition: border-color 150ms ease-out; }
|
|
210
|
+
.oc-sdk-check[aria-checked="true"] .oc-sdk-check-box { border-color: ${y(P,60,W)}; }
|
|
211
|
+
.oc-sdk-check-thumb { border-radius: 9999px; background: ${W}; transition: background 150ms ease-out; }
|
|
212
|
+
.oc-sdk-check-thumb::after { border-radius: 9999px; background: ${B}; transition: transform 150ms ease-out; }
|
|
213
|
+
.oc-sdk-check[aria-checked="true"] .oc-sdk-check-thumb { background: ${X}; }
|
|
214
|
+
.oc-sdk-check[aria-checked="true"] .oc-sdk-check-thumb::after { transform: translateX(16px); }
|
|
215
|
+
.oc-sdk-check:focus-visible { box-shadow: none; }
|
|
216
|
+
.oc-sdk-check:focus-visible .oc-sdk-check-box, .oc-sdk-check:focus-visible .oc-sdk-check-thumb { ${zo} }
|
|
217
|
+
.oc-sdk-check-desc { color: ${x}; }
|
|
218
|
+
|
|
219
|
+
.oc-sdk-tabs { border-radius: 10px; }
|
|
220
|
+
.oc-sdk-tabs[data-track="true"] { background: ${y(P,4)}; box-shadow: inset 0 1px 2px 0 rgb(0 0 0 / 0.16); }
|
|
221
|
+
.oc-sdk-tab { border-radius: 8px; color: ${x}; transition: color 150ms ease-out, background 150ms ease-out; }
|
|
222
|
+
.oc-sdk-tab:hover { color: ${P}; }
|
|
223
|
+
.oc-sdk-tab[aria-selected="true"] { color: ${Ct}; background: ${Ut}; border-color: ${W}; }
|
|
224
|
+
.oc-sdk-tabs[data-track="true"] .oc-sdk-tab[aria-selected="true"] { color: ${de}; background: var(--oc-sdk-raised-bg); border-color: transparent; ${Pt} }
|
|
225
|
+
.oc-sdk-tab-count { color: ${x}; }
|
|
226
|
+
|
|
227
|
+
.oc-sdk-badge { border-radius: 9999px; background: ${C}; color: ${x}; }
|
|
228
|
+
.oc-sdk-badge[data-tone] { color: var(--oc-sdk-tone-text, var(--oc-sdk-tone)); background: ${y("var(--oc-sdk-tone)",15)}; }
|
|
229
|
+
|
|
230
|
+
.oc-sdk-row { border-radius: 6px; transition: background 120ms ease-out; }
|
|
231
|
+
.oc-sdk-row:hover, .oc-sdk-row[data-active="true"] { background: ${C}; }
|
|
232
|
+
.oc-sdk-row[aria-selected="true"] { background: ${Ut}; color: ${Ct}; }
|
|
233
|
+
.oc-sdk-row-lead { font-family: ${Lt}; color: ${x}; }
|
|
234
|
+
.oc-sdk-row-sub { color: ${x}; }
|
|
235
|
+
.oc-sdk-row-meta { color: ${x}; }
|
|
236
|
+
.oc-sdk-row[aria-selected="true"] .oc-sdk-row-lead, .oc-sdk-row[aria-selected="true"] .oc-sdk-row-sub, .oc-sdk-row[aria-selected="true"] .oc-sdk-row-meta { color: inherit; opacity: .75; }
|
|
237
|
+
.oc-sdk-list-empty { color: ${x}; }
|
|
238
|
+
|
|
239
|
+
.oc-sdk-empty-body { color: ${x}; }
|
|
240
|
+
|
|
241
|
+
.oc-sdk-spinner { color: ${x}; }
|
|
242
|
+
.oc-sdk-spinner-ring { border-color: ${W}; border-top-color: ${X}; border-radius: 9999px; }
|
|
243
|
+
|
|
244
|
+
/* Set apart by its tint alone, like the app's banners. */
|
|
245
|
+
.oc-sdk-banner { border-color: transparent; border-radius: 8px; background: ${y("var(--oc-sdk-tone)",10)}; }
|
|
246
|
+
.oc-sdk-banner-title { color: var(--oc-sdk-tone-text, var(--oc-sdk-tone)); }
|
|
247
|
+
.oc-sdk-banner-body { color: ${x}; }
|
|
248
|
+
|
|
249
|
+
.oc-sdk-separator { color: ${x}; }
|
|
250
|
+
.oc-sdk-separator::before, .oc-sdk-separator::after { background: ${y(W,40)}; }
|
|
251
|
+
|
|
252
|
+
.oc-sdk-progress-label { color: ${x}; }
|
|
253
|
+
.oc-sdk-progress-track { border-radius: 9999px; background: ${W}; }
|
|
254
|
+
.oc-sdk-progress-fill { border-radius: 9999px; background: var(--oc-sdk-tone, ${X}); }
|
|
255
|
+
|
|
256
|
+
.oc-sdk-text a { color: ${It}; text-decoration: underline; text-underline-offset: 2px; }
|
|
257
|
+
.oc-sdk-text img { border-radius: 8px; border: 1px solid ${y(W,60)}; }
|
|
258
|
+
`,I=`
|
|
259
|
+
${tt}
|
|
260
|
+
${kn}
|
|
261
|
+
${Jo}`;var Rn=e=>e!==null&&typeof e=="object"&&!Array.isArray(e);function Yo(e){let o=JSON.parse(e);if(!Rn(o)||o.version!==1||typeof o.sessionID!="string"||typeof o.live!="boolean"||!["todo","monitors","evalCells","background","wakeSources"].every(r=>Array.isArray(o[r])))throw new Error("antechamber answered with an unexpected work-status shape");return o}function qo(e){return e.monitors.some(o=>o.ending===void 0)||e.evalCells.some(o=>o.state==="running"||o.state==="queued")||e.background.length>0||e.goal?.armed===!0||e.todo.some(o=>o.tasks.some(r=>r.status==="in_progress"))}function pe(e){let o=Math.max(0,Math.floor(e/1e3));if(o<60)return`${o}s`;let r=Math.floor(o/60);if(r<60)return`${r}m ${String(o%60).padStart(2,"0")}s`;let s=Math.floor(r/60);return s<24?`${s}h ${String(r%60).padStart(2,"0")}m`:`${Math.floor(s/24)}d ${s%24}h`}function Dt(e){let o=e.tasks.filter(d=>d.status!=="cancelled"),r=o.filter(d=>d.status==="completed").length,s=e.tasks.find(d=>d.status==="in_progress")?.content,i=e.tasks.every(d=>d.status==="completed"||d.status==="cancelled");return{name:e.name,done:r,total:o.length,finished:i,...s!==void 0?{current:s}:{},tone:s!==void 0?"run":i?"ok":"idle"}}function Qo(e){let o=e.findIndex(r=>r.tasks.some(s=>s.status==="in_progress"));return o>=0?o:e.findIndex(r=>!Dt(r).finished)}function Zo(e){return e.ending===void 0?e.monitor.paused?"warn":"run":e.ending.reason==="exit"?e.ending.exitCode===0||e.ending.exitCode===null?"ok":"bad":e.ending.reason==="timeout"||e.ending.reason==="killed"?"idle":"warn"}function en(e,o){let r=`${e.monitor.fireCount} event${e.monitor.fireCount===1?"":"s"}`;return e.ending!==void 0?`${e.ending.label} \xB7 ${r}`:`${e.monitor.paused?"paused":"watching"} ${pe(o-e.monitor.startedAtMs)} \xB7 ${r}`}var wn=new Set(["running","queued"]);function be(e){return wn.has(e.state)}function tn(e){switch(e.state){case"running":return"run";case"queued":return"warn";case"completed":return"ok";case"failed":return"bad";default:return"idle"}}function on(e,o){let r=[e.language,e.state];return e.startedAtMs!==void 0&&be(e)&&r.push(pe(o-e.startedAtMs)),e.queuedBehind!==void 0&&r.push(`behind ${e.queuedBehind.join(", ")}`),r.filter(s=>s!==void 0).join(" \xB7 ")}function Ft(e){switch(e){case"senpi-codemode":return"eval cells";case"terminal-monitors":return"monitors";case"terminal-background-sessions":return"background sessions";case"loop-guard":return"loop guard";default:return e}}function nn(e){return e.todo.length===0&&e.monitors.length===0&&e.evalCells.length===0&&e.background.length===0&&e.goal===null&&e.wakeSources.length===0}var Un=1500,rn=5e3,Cn=1e4,In=4096,Mn={completed:"\u2713",in_progress:"\u25CF",pending:"\u25CB",cancelled:"\u2013"},D=Rt(),Bt=document.getElementById("root"),Ae=null,ee="",J=null,Y=null,Z=0,Vt,Je=!1,zt=new Map,We=new Set,ke=new Set,Ye=new Map,jt=new Map,ue=new Set,Kt=[];function a(e,o={},...r){let s=document.createElement(e);for(let[i,d]of Object.entries(o))typeof d=="function"?s.addEventListener(i,d):i==="class"?s.className=String(d):d===!0?s.setAttribute(i,""):d!==!1&&s.setAttribute(i,d);for(let i of r)i&&s.append(i);return s}function ye(e,o="meta"){let r=a("span",{class:o}),s=i=>{r.textContent=e(i),r.title=r.textContent};return s(Date.now()),Kt.push(s),r}function Ln(e={}){return{session:Ae??"",...ee?{stateDir:ee}:{},...e}}async function Wt(e,o,r={}){let s=await D.serviceRequest({method:e,path:o,query:Ln(r)});if(s.status>=400){let i=`HTTP ${s.status}`;try{let d=JSON.parse(s.body);i=String(d.data?.message??d.detail??d.error??i)}catch{}throw new Error(i)}return s.body}function Xt(e){clearTimeout(Vt),Vt=setTimeout(()=>{te()},e)}async function te(){if(clearTimeout(Vt),Ae===null){J=null,Y=null,z();return}if(document.hidden)return Xt(rn);let e=++Z;try{let o=Yo(await Wt("GET","/status"));if(e!==Z||(J=o,Y=null,await Gn(o,e),e!==Z))return;z(),Xt(qo(o)?Un:rn)}catch(o){if(e!==Z)return;Y=o instanceof Error?o.message:String(o),z(),Xt(Cn)}}async function Gn(e,o){let r=e.evalCells.filter(s=>ke.has(s.cellId)&&(be(s)||jt.get(s.cellId)!==s.state));await Promise.all(r.map(async s=>{try{let i=JSON.parse(await Wt("GET","/eval",{cell:s.cellId,tailBytes:String(In)}));if(o!==Z)return;Ye.set(s.cellId,typeof i.outputTail=="string"?i.outputTail:""),jt.set(s.cellId,s.state)}catch(i){o===Z&&Ye.set(s.cellId,`(output unavailable: ${i.message})`)}}))}async function sn(e,o,r,s,i){if(!ue.has(e)){ue.add(e),z();try{await Wt(o,r,s),D.toast({kind:"success",message:i}).catch(()=>{})}catch(d){D.toast({kind:"error",message:d.message}).catch(()=>{})}finally{ue.delete(e),te()}}}function fe(e,o,...r){return a("section",{class:"group","aria-label":e},a("div",{class:"label"},e,o!==null&&a("span",{class:"count"},o)),...r)}function Ee(e){return a("span",{class:`dot t-${e}`,"aria-hidden":"true"})}function Nn(e){if(e.todo.length===0)return null;let o=Qo(e.todo),r=e.todo.map(Dt),s=r.reduce((k,S)=>k+S.done,0),i=r.reduce((k,S)=>k+S.total,0),d=e.todo.flatMap((k,S)=>{let h=r[S],v=`${S}:${k.name}`,G=zt.get(v)??S===o,oe=h.total===0?100:Math.round(h.done/h.total*100),q=a("button",{class:`row t-${h.tone}${G?" is-open":""}`,type:"button","aria-expanded":String(G),click:()=>{zt.set(v,!G),z()}},Ee(h.tone),a("span",{class:"stack"},a("span",{class:"title"},h.name),!G&&h.current!==void 0&&a("span",{class:"meta"},h.current)),a("span",{class:"side"},`${h.done}/${h.total}`,a("span",{class:"bar","aria-hidden":"true"},a("i",{style:`width:${oe}%`}))));if(!G)return[q];let j=a("div",{class:"tasks"},...k.tasks.map(K=>a("div",{class:`task s-${K.status}`},a("span",{class:"glyph","aria-label":K.status.replace("_"," ")},Mn[K.status]),a("span",{},K.content))));return[q,j]});return fe("Todo",`${s}/${i}`,...d)}function Pn(e){if(e.monitors.length===0)return null;let o=e.monitors.filter(s=>s.ending===void 0).length,r=e.monitors.flatMap(s=>{let i=s.monitor.id,d=We.has(i),k=Zo(s),S=a("button",{class:`row t-${k}${d?" is-open":""}`,type:"button","aria-expanded":String(d),title:s.monitor.command??s.monitor.description,click:()=>{d?We.delete(i):We.add(i),z()}},Ee(k),a("span",{class:"stack"},a("span",{class:"title"},s.monitor.description),ye(v=>en(s,v))),a("span",{class:"side"},i));if(!d)return[S];let h=a("div",{class:"detail"},s.monitor.command!==null&&a("div",{class:"kv"},`$ ${s.monitor.command}`),s.monitor.filter!==null&&a("div",{class:"kv"},`filter ${s.monitor.filter}`),a("div",{class:"kv"},s.monitor.persistent?"persistent":s.monitor.deadlineMs!==null&&s.ending===void 0?ye(v=>`deadline in ${pe((s.monitor.deadlineMs??v)-v)}`,""):""),s.lines.length>0?a("pre",{},s.lines.join(`
|
|
262
|
+
`)):a("div",{class:"kv"},"no matched lines yet"));return[S,h]});return fe("Monitors",o>0?`${o} live`:String(e.monitors.length),...r)}function $n(e){if(e.evalCells.length===0)return null;let o=e.evalCells.filter(be).length,r=e.evalCells.flatMap(i=>{let d=ke.has(i.cellId),k=tn(i),S=`stop:${i.cellId}`,h=a("div",{class:`row t-${k}${d?" is-open":""}`},Ee(k),a("button",{class:"stack",type:"button","aria-expanded":String(d),title:e.live?"Show output":"The agent is not running",click:()=>{d?ke.delete(i.cellId):ke.add(i.cellId),z(),!d&&e.live&&te()}},a("span",{class:"title"},i.summary??i.cellId),ye(G=>on(i,G))),a("span",{class:"side"},be(i)&&e.live&&a("button",{class:"action danger",type:"button",disabled:ue.has(S),"aria-label":`Stop eval cell ${i.summary??i.cellId}`,click:()=>{sn(S,"POST","/eval/stop",{cell:i.cellId},"Eval cell stopped")}},"Stop")));if(!d)return[h];let v=Ye.get(i.cellId);return[h,a("div",{class:"detail"},a("div",{class:"kv"},i.cellId),a("pre",{},v===void 0?"loading\u2026":v===""?"(no output yet)":v))]}),s=!e.evalCellsListed&&e.live&&a("div",{class:"note"},"Cell output needs codemode.");return fe("Eval cells",o>0?`${o} running`:String(e.evalCells.length),...r,s)}function Hn(e){return e.background.length===0?null:fe("Background",String(e.background.length),...e.background.map(o=>a("div",{class:"row t-run",title:o.command},Ee("run"),a("span",{class:"stack"},a("span",{class:"title"},o.command),ye(r=>`${o.id} \xB7 ${pe(r-o.startedAtMs)}`)),a("span",{class:"side"},o.pid!==void 0?`pid ${o.pid}`:""))))}function Dn(e){let o=e.goal;if(o===null)return null;let r=Object.entries(o.wakeSources??{}).filter(([,i])=>i>0).map(([i,d])=>`${d} ${Ft(i)}`).join(", "),s=a("div",{class:`row t-${o.armed?"run":"idle"}`},Ee(o.armed?"run":"idle"),a("span",{class:"stack"},a("span",{class:"title"},o.armed?"Goal continuation armed":"Goal continuation idle"),o.armed&&o.dueAtMs!==void 0?ye(i=>`${o.kind??"next"} ${(o.dueAtMs??i)>i?`in ${pe((o.dueAtMs??i)-i)}`:"due now"}${r?` \xB7 waiting on ${r}`:""}`):r&&a("span",{class:"meta"},`waiting on ${r}`)),a("span",{class:"side"},o.armed&&e.live&&a("button",{class:"action",type:"button",disabled:ue.has("goal"),click:()=>{sn("goal","POST","/goal/fire",{},"Goal continuation fired")}},"Fire now")));return fe("Goal",null,s)}function Fn(e){return e.wakeSources.length===0?null:fe("Other activity",null,...e.wakeSources.map(o=>a("div",{class:"row t-run"},Ee("run"),a("span",{class:"stack"},a("span",{class:"title"},Ft(o.source)),o.items.length>0&&a("span",{class:"meta"},o.items.map(r=>r.description).join(", "))),a("span",{class:"side"},`${o.activeCount} active`))))}function Xn(){let e=a("input",{name:"stateDir",value:ee,placeholder:"~/.config/antechamber (default)",autocomplete:"off",spellcheck:"false"}),o=()=>{ee=e.value.trim(),Je=!1,D.storage.set("stateDir",ee).catch(()=>{}),te()};return a("form",{class:"settings",submit:r=>{r.preventDefault(),o()}},a("label",{},"antechamber state directory",e),a("div",{class:"buttons"},a("button",{class:"action",type:"submit"},"Save")))}function z(){Kt=[];let e=[];if(Je&&e.push(Xn()),Ae===null)e.push(a("div",{class:"note"},"Open a session to see its background work."));else if(J===null&&Y===null)e.push(a("div",{class:"note"},"Loading\u2026"));else if(J===null)e.push(a("div",{class:"note is-error"},Y));else{Y!==null&&e.push(a("div",{class:"note is-error"},Y));let o=[Nn,Pn,$n,Hn,Dn,Fn].map(r=>r(J));e.push(...o),nn(J)&&e.push(a("div",{class:"note"},J.live?"No background work.":"No background work. The agent is not running."))}Bt.replaceChildren(...e.filter(o=>!!o))}setInterval(()=>{let e=Date.now();for(let o of Kt)o(e)},1e3);new ResizeObserver(()=>{D.setHeight(Math.ceil(Bt.getBoundingClientRect().height)).catch(()=>{})}).observe(Bt);document.addEventListener("visibilitychange",()=>{document.hidden||te()});D.onStatusControl(e=>{e.id==="data-path"&&(Je=!Je,z())});D.onReady(e=>{wt(e,document.documentElement),e.features?.statusControls&&D.setStatusControls([{kind:"button",id:"data-path",label:"Data path"}]).catch(()=>{})});D.onSession(e=>{let o=e?.id??null;o!==Ae&&(Ae=o,J=null,Y=null,ke.clear(),We.clear(),Ye.clear(),jt.clear(),ue.clear(),zt.clear(),Z++,te())});D.storage.get("stateDir").then(e=>{typeof e=="string"&&e!==ee&&(ee=e,te())}).catch(()=>{});z();})();
|