@deepseek-insight/dsi 0.11.4 → 0.11.5
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/.agents/skills/glass-dsh/SKILL.md +18 -4
- package/.agents/skills/glass-dsh/scripts/_connect.mjs +37 -1
- package/.agents/skills/glass-dsh/scripts/gesture.mjs +117 -45
- package/README.md +7 -1
- package/bin/dsi-chassis.mjs +40 -6
- package/build/client/_app/immutable/assets/0.DtmjX3F5.css +2 -0
- package/build/client/_app/immutable/chunks/B_-jo8TU.js +1 -0
- package/build/client/_app/immutable/chunks/D4hWXjx0.js +1 -0
- package/build/client/_app/immutable/chunks/VN40mceS.js +2 -0
- package/build/client/_app/immutable/chunks/{BQI9wyZo.js → m-9mXueE.js} +1 -1
- package/build/client/_app/immutable/entry/{app.CaHTeMGs.js → app.CMOM1S0-.js} +2 -2
- package/build/client/_app/immutable/entry/start.BSTSdw9I.js +1 -0
- package/build/client/_app/immutable/nodes/{1.AoWxyOCL.js → 1.D89b4952.js} +1 -1
- package/build/client/_app/immutable/nodes/{2.BiOhzV1A.js → 2.BTTHruTq.js} +2 -2
- package/build/client/_app/version.json +1 -1
- package/build/handler.js +4 -4
- package/build/index.js +4 -4
- package/build/server/chunks/chunks/{internal2.js-y5mpUnMs.js → internal2.js-Bu378t5u.js} +2 -2
- package/build/server/chunks/chunks/{registry.js-Cnmd1vW3.js → registry.js-BuEw-96E.js} +2 -2
- package/build/server/chunks/chunks/{state.js-DgYQBCjR.js → state.js-DjKlX2y2.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/activate/{_server.ts.js-DlbbO3RF.js → _server.ts.js-BWbEzlCm.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/close/{_server.ts.js-B85bLw4w.js → _server.ts.js-BRhxONLL.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/closetab/{_server.ts.js-Dt5Bxv2-.js → _server.ts.js-DcafQOUs.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/element/{_server.ts.js-uJ5BnGUA.js → _server.ts.js-BBSIIDAx.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/history/{_server.ts.js-CVCoWk2n.js → _server.ts.js-BDAujEcp.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/input/{_server.ts.js-CmhQ7zGO.js → _server.ts.js-PP6mc-7m.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/mcp/{_server.ts.js-CFtpmSCd.js → _server.ts.js-N1WWoP-W.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/navigate/{_server.ts.js-BH8MNt9W.js → _server.ts.js-7iuI6c8E.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/opentab/{_server.ts.js-uIrK0T8h.js → _server.ts.js-CsF_LSmK.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/page/{_server.ts.js-Bg5yHS9F.js → _server.ts.js-CshBvfm4.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/stream/{_server.ts.js-DG6xvUsm.js → _server.ts.js-CAtPWIGT.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/tabs/{_server.ts.js-RiXP45mV.js → _server.ts.js-Cuqk6xWI.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/viewport/{_server.ts.js-w9MNQddQ.js → _server.ts.js-CstasxV_.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/_id_/zoom/{_server.ts.js-BoXDoshV.js → _server.ts.js-BAe1WUX-.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/browser/{_server.ts.js-pQmJm_Io.js → _server.ts.js-CkzA7KWV.js} +2 -2
- package/build/server/chunks/entries/pages/{_error.svelte.js-BIJ7nQ2M.js → _error.svelte.js-BQo1hDr-.js} +3 -3
- package/build/server/chunks/entries/pages/{_page.svelte.js-u9R9oLkN.js → _page.svelte.js-DKmRrZt2.js} +4 -4
- package/build/server/chunks/{handler-B33Zuq6Y.js → handler-BPITMesY.js} +3 -3
- package/build/server/chunks/{index.js-_yRI545U.js → index.js-DB5oAaYI.js} +2 -2
- package/build/server/chunks/{manifest.js-mKEDDCRk.js → manifest.js-DnTfr66C.js} +20 -20
- package/build/server/chunks/nodes/{0.js-B8ciwPSu.js → 0.js-tNBtSaEq.js} +3 -3
- package/build/server/chunks/nodes/1.js-DCnyPlh8.js +9 -0
- package/build/server/chunks/nodes/{2.js-qAWSZ3SP.js → 2.js-2Lw9Q9N5.js} +3 -3
- package/package.json +1 -1
- package/template/.dsi/prompts.sqlite-shm +0 -0
- package/template/.dsi/prompts.sqlite-wal +0 -0
- package/build/client/_app/immutable/assets/0.Bjw4vcZl.css +0 -2
- package/build/client/_app/immutable/chunks/C-zV0ulT.js +0 -1
- package/build/client/_app/immutable/chunks/C2MzPOYY.js +0 -2
- package/build/client/_app/immutable/chunks/DQy5rtST.js +0 -1
- package/build/client/_app/immutable/entry/start.D9CL1tVI.js +0 -1
- package/build/server/chunks/nodes/1.js-Cw3CxJ6F.js +0 -9
- /package/build/client/_app/immutable/nodes/{0.DopnsZUT.js → 0.IJdZxujs.js} +0 -0
|
@@ -55,10 +55,15 @@ The floor registry (glass sessions) is resolved separately: `DSI_UI` env when
|
|
|
55
55
|
set, else probe `5175` then `5174` (`/api/browser`). A floor stamps its own
|
|
56
56
|
addresses at boot — agents in a floor's conversations drive that floor's glass.
|
|
57
57
|
|
|
58
|
-
## Environment contract (D6)
|
|
59
|
-
|
|
60
|
-
-
|
|
61
|
-
|
|
58
|
+
## Environment contract (D6, amended by D16 2026-11-09)
|
|
59
|
+
|
|
60
|
+
- Plain node ESM, no build step. The driver resolves `playwright-core`
|
|
61
|
+
**itself** (D16): script-relative `node_modules` → the cwd's `package.json`
|
|
62
|
+
tree → `$DSI_REPO_ROOT` → loud death naming the remedy. Running from the DSI
|
|
63
|
+
repo root still works (the cwd fallback), but is no longer required; there is
|
|
64
|
+
NO symlink step. If the skill directory is read-only (harness workspace-write
|
|
65
|
+
mode), copying `scripts/` into the workspace is the sanctioned deployment —
|
|
66
|
+
the copy bootstraps itself.
|
|
62
67
|
- Every verb prints ONE JSON verdict on stdout and exits 0/1; failures print
|
|
63
68
|
`{"error": ...}` via `die()` — a refusal is an answer, quote it.
|
|
64
69
|
- No state files between runs: every run re-derives session and tab from the
|
|
@@ -76,6 +81,15 @@ addresses at boot — agents in a floor's conversations drive that floor's glass
|
|
|
76
81
|
3. **Gestures (Gates 3–4)** — one verb per process, composition in your hands:
|
|
77
82
|
`glass-dsh.mjs eval --b64` for reads, `gesture.mjs click|type|drag|control|persist`
|
|
78
83
|
for real input. Each verb prints `{before, after, moved}` — quote the pair.
|
|
84
|
+
For gesture SEQUENCES prefer the D17 composite (one process, one CDP session,
|
|
85
|
+
one verdict per step):
|
|
86
|
+
`node gesture.mjs run steps.json` where steps.json is an array like
|
|
87
|
+
`[{"verb":"click","selector":"…","label":"open"},{"verb":"drag","selector":"…","dx":-433,"dy":-303},{"verb":"type","selector":"…","text":"…"},{"verb":"control","expr":"…"}]`
|
|
88
|
+
→ `{"verb":"run","steps":4,"executed":N,"failedAt":null,"ok":true,"results":[…per-step verdicts…]}`
|
|
89
|
+
and exit 1 if any step failed. The composite STOPS at the first failed gate
|
|
90
|
+
(control `pass:false`, gesture `moved:false`, any `die`) and reports the
|
|
91
|
+
completed prefix — quote the prefix, do not improvise onward (D11). Single
|
|
92
|
+
verbs stay for one-off reads and re-runs of a single failed step.
|
|
79
93
|
4. **Restore (Gate 5)** — clear seeded state via the page's own store, reload,
|
|
80
94
|
re-probe: launcher present, console clean, store empty.
|
|
81
95
|
5. **Report** — table of before/after numbers, the gesture that produced them,
|
|
@@ -26,7 +26,43 @@
|
|
|
26
26
|
* (never a port substring, never positional). Dies when
|
|
27
27
|
* absent, naming the resolved origin.
|
|
28
28
|
*/
|
|
29
|
-
import {
|
|
29
|
+
import { createRequire } from 'node:module';
|
|
30
|
+
import { join } from 'node:path';
|
|
31
|
+
|
|
32
|
+
// D16 (ADR-0045 Amendment 7) — the driver resolves its own engine; the cwd is
|
|
33
|
+
// never the contract. Resolution order: script-relative node_modules → the
|
|
34
|
+
// cwd's package.json tree (the documented "run from the repo root" case) →
|
|
35
|
+
// the stamped default repo (~/agentic-ai/deepseek-insight) or $DSI_REPO_ROOT →
|
|
36
|
+
// die loudly with the exact remedy. ESM bare imports resolve from the script's
|
|
37
|
+
// own directory, which is why cwd alone was never enough.
|
|
38
|
+
function resolveChromium() {
|
|
39
|
+
const attempts = [];
|
|
40
|
+
const repoCandidates = [];
|
|
41
|
+
if (process.env.DSI_REPO_ROOT) repoCandidates.push(process.env.DSI_REPO_ROOT);
|
|
42
|
+
if (process.env.HOME) repoCandidates.push(join(process.env.HOME, 'agentic-ai', 'deepseek-insight'));
|
|
43
|
+
const tryRequire = (label, anchor) => {
|
|
44
|
+
try {
|
|
45
|
+
return createRequire(anchor)('playwright-core');
|
|
46
|
+
} catch (e) {
|
|
47
|
+
attempts.push(label + ': ' + (e?.code ?? e?.message ?? String(e)));
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
let mod = tryRequire('script-relative', import.meta.url);
|
|
52
|
+
if (!mod) mod = tryRequire('cwd', join(process.cwd(), 'package.json'));
|
|
53
|
+
for (const root of repoCandidates) {
|
|
54
|
+
if (mod) break;
|
|
55
|
+
mod = tryRequire('repo:' + root, join(root, 'package.json'));
|
|
56
|
+
}
|
|
57
|
+
if (!mod?.chromium) {
|
|
58
|
+
die('playwright-core not resolvable — tried: ' + attempts.join(' | ') +
|
|
59
|
+
'. Remedy: run from the DSI repo root (cwd with a package.json), copy these ' +
|
|
60
|
+
'scripts next to a node_modules that has playwright-core, export DSI_REPO_ROOT=<repo path>, ' +
|
|
61
|
+
'or clone the DSI repo to ~/agentic-ai/deepseek-insight.');
|
|
62
|
+
}
|
|
63
|
+
return mod.chromium;
|
|
64
|
+
}
|
|
65
|
+
const chromium = resolveChromium();
|
|
30
66
|
|
|
31
67
|
const DEFAULT_FLOOR_BASES = ['http://127.0.0.1:5175', 'http://127.0.0.1:5174'];
|
|
32
68
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* gesture.mjs — real-gesture verbs for the glass-dsh skill (Gates 3–5, D15).
|
|
4
4
|
* Real mouse/keyboard only: synthetic dispatchEvent is not verification.
|
|
5
5
|
* One verb per process; each prints {before, after, moved|delta} JSON.
|
|
6
|
-
* Run from the
|
|
6
|
+
* Run from any cwd (D16: the driver resolves its own playwright-core).
|
|
7
7
|
*
|
|
8
8
|
* Verbs:
|
|
9
9
|
* click <selector> real click (raises interception as an error, never force-clicks)
|
|
@@ -11,10 +11,17 @@
|
|
|
11
11
|
* drag <selector> <dx> <dy> real mouse down → 10 stepped moves with waits → up, on the element's box
|
|
12
12
|
* control <js-expr> control gate: evaluate an assertion expression → {pass, result}
|
|
13
13
|
* persist <localStorageKey> read a store key from the DSH tab → {raw}
|
|
14
|
+
* run <steps.json> D17 composite: ONE process + ONE CDP session executes a JSON
|
|
15
|
+
* array of steps ({verb, …args, label?}) in order, printing one
|
|
16
|
+
* verdict per step (same shapes as the single verbs) and stopping
|
|
17
|
+
* at the first failed gate — control pass:false, a moved:false on
|
|
18
|
+
* a gesture, or any die() — reporting the completed prefix.
|
|
19
|
+
* Exit 1 when a step failed, 0 otherwise (D11 stop-loss, batched).
|
|
14
20
|
*
|
|
15
21
|
* Flags: --dsh-url|--dsh-port|--owner-session (see _connect.mjs); --substr <s> selects a tab by URL
|
|
16
22
|
* substring for reads (never positional, D10); input verbs always target the DSH-origin tab.
|
|
17
23
|
*/
|
|
24
|
+
import { readFileSync } from 'node:fs';
|
|
18
25
|
import { connect, pickByOrigin, originOf, die } from './_connect.mjs';
|
|
19
26
|
|
|
20
27
|
const argv = process.argv.slice(2);
|
|
@@ -35,64 +42,129 @@ function page() {
|
|
|
35
42
|
return pickByOrigin(ctx, dshOrigin);
|
|
36
43
|
}
|
|
37
44
|
|
|
38
|
-
|
|
45
|
+
async function readHostPos(p, sel) {
|
|
46
|
+
return p.evaluate((s) => {
|
|
47
|
+
const el = document.querySelector(s);
|
|
48
|
+
if (!el) return null;
|
|
49
|
+
const host = el.closest('[style*="left"]') ?? el;
|
|
50
|
+
return { x: host.style.left, y: host.style.top };
|
|
51
|
+
}, sel);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Execute one step; returns { ok, verdict }. Verdict shapes are byte-identical
|
|
56
|
+
* to the single-verb shapes (D17 — additive composition only).
|
|
57
|
+
*/
|
|
58
|
+
async function execStep(p, step) {
|
|
59
|
+
const v = step.verb;
|
|
60
|
+
try {
|
|
61
|
+
if (v === 'click') {
|
|
62
|
+
const sel = step.selector;
|
|
63
|
+
if (!sel) return { ok: false, verdict: { error: 'click needs a selector' } };
|
|
64
|
+
const before = await p.evaluate((s) => !!document.querySelector(s), sel);
|
|
65
|
+
await p.locator(sel).first().click(); // locator.click raises interception loudly (no force)
|
|
66
|
+
return { ok: true, verdict: { verb: 'click', selector: sel, before, after: true, moved: before !== true } };
|
|
67
|
+
}
|
|
68
|
+
if (v === 'type') {
|
|
69
|
+
const sel = step.selector, text = step.text;
|
|
70
|
+
if (!sel || text === undefined) return { ok: false, verdict: { error: 'type needs selector + text' } };
|
|
71
|
+
const loc = p.locator(sel).first();
|
|
72
|
+
await loc.click();
|
|
73
|
+
await p.keyboard.type(text);
|
|
74
|
+
const after = await loc.inputValue().catch(() => undefined);
|
|
75
|
+
return { ok: after === text, verdict: { verb: 'type', selector: sel, before: '', after, moved: after === text } };
|
|
76
|
+
}
|
|
77
|
+
if (v === 'drag') {
|
|
78
|
+
const sel = step.selector, dx = Number(step.dx), dy = Number(step.dy);
|
|
79
|
+
if (!sel || !Number.isFinite(dx) || !Number.isFinite(dy)) {
|
|
80
|
+
return { ok: false, verdict: { error: 'drag needs selector + finite dx/dy' } };
|
|
81
|
+
}
|
|
82
|
+
const posBefore = await readHostPos(p, sel);
|
|
83
|
+
if (!posBefore) return { ok: false, verdict: { error: 'no element for ' + sel } };
|
|
84
|
+
const box = await p.locator(sel).first().boundingBox();
|
|
85
|
+
if (!box) return { ok: false, verdict: { error: 'boundingBox failed for ' + sel } };
|
|
86
|
+
const sx = box.x + box.width / 2, sy = box.y + Math.min(box.height / 2, 8);
|
|
87
|
+
await p.mouse.move(sx, sy);
|
|
88
|
+
await p.mouse.down();
|
|
89
|
+
for (let i = 1; i <= 10; i++) {
|
|
90
|
+
await p.mouse.move(sx + (dx * i) / 10, sy + (dy * i) / 10);
|
|
91
|
+
await new Promise((r) => setTimeout(r, 20));
|
|
92
|
+
}
|
|
93
|
+
await p.mouse.up();
|
|
94
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
95
|
+
const posAfter = await readHostPos(p, sel);
|
|
96
|
+
const moved = JSON.stringify(posBefore) !== JSON.stringify(posAfter);
|
|
97
|
+
return { ok: moved, verdict: { verb: 'drag', selector: sel, before: posBefore, after: posAfter, moved } };
|
|
98
|
+
}
|
|
99
|
+
if (v === 'control') {
|
|
100
|
+
const expr = step.expr;
|
|
101
|
+
if (!expr) return { ok: false, verdict: { error: 'control needs a JS assertion expression' } };
|
|
102
|
+
const result = await p.evaluate('!!(' + expr + ')');
|
|
103
|
+
return { ok: result === true, verdict: { verb: 'control', expr, pass: result === true, result } };
|
|
104
|
+
}
|
|
105
|
+
if (v === 'persist') {
|
|
106
|
+
const key = step.key;
|
|
107
|
+
if (!key) return { ok: false, verdict: { error: 'persist needs a localStorage key' } };
|
|
108
|
+
const raw = await p.evaluate((k) => window.localStorage.getItem(k), key);
|
|
109
|
+
return { ok: true, verdict: { verb: 'persist', key, raw } };
|
|
110
|
+
}
|
|
111
|
+
return { ok: false, verdict: { error: 'unknown step verb ' + JSON.stringify(v) + ' — click | type | drag | control | persist' } };
|
|
112
|
+
} catch (e) {
|
|
113
|
+
return { ok: false, verdict: { error: String(e?.message ?? e) } };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (verb === 'run') {
|
|
118
|
+
const file = argv[1];
|
|
119
|
+
if (!file) die('run needs a steps.json path');
|
|
120
|
+
let steps;
|
|
121
|
+
try {
|
|
122
|
+
steps = JSON.parse(readFileSync(file, 'utf8'));
|
|
123
|
+
} catch (e) {
|
|
124
|
+
die('run cannot read steps: ' + String(e?.message ?? e));
|
|
125
|
+
}
|
|
126
|
+
if (!Array.isArray(steps)) die('run steps must be a JSON array of {verb, …}');
|
|
127
|
+
const p = page();
|
|
128
|
+
const results = [];
|
|
129
|
+
let failedAt = null;
|
|
130
|
+
for (let i = 0; i < steps.length; i++) {
|
|
131
|
+
const step = steps[i];
|
|
132
|
+
const { ok, verdict } = await execStep(p, step);
|
|
133
|
+
results.push({ label: step.label ?? (step.verb + '#' + i), ok, ...verdict });
|
|
134
|
+
if (!ok) { failedAt = i; break; }
|
|
135
|
+
}
|
|
136
|
+
console.log(JSON.stringify({
|
|
137
|
+
verb: 'run', steps: steps.length, executed: results.length,
|
|
138
|
+
failedAt, ok: failedAt === null, results,
|
|
139
|
+
}));
|
|
140
|
+
process.exit(failedAt === null ? 0 : 1);
|
|
141
|
+
} else if (verb === 'click') {
|
|
39
142
|
const sel = argv[1];
|
|
40
143
|
if (!sel) die('click needs a selector');
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
console.log(JSON.stringify({ verb: 'click', selector: sel, before, after: true, moved: before !== true }));
|
|
144
|
+
const { verdict } = await execStep(page(), { verb: 'click', selector: sel });
|
|
145
|
+
if (verdict.error) die(verdict.error);
|
|
146
|
+
console.log(JSON.stringify(verdict));
|
|
45
147
|
} else if (verb === 'type') {
|
|
46
148
|
const sel = argv[1], text = argv[2];
|
|
47
149
|
if (!sel || text === undefined) die('type needs <selector> <text>');
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
await loc.click();
|
|
51
|
-
await p.keyboard.type(text);
|
|
52
|
-
const after = await loc.inputValue().catch(() => undefined);
|
|
53
|
-
console.log(JSON.stringify({ verb: 'type', selector: sel, before: '', after, moved: after === text }));
|
|
150
|
+
const { verdict } = await execStep(page(), { verb: 'type', selector: sel, text });
|
|
151
|
+
console.log(JSON.stringify(verdict));
|
|
54
152
|
} else if (verb === 'drag') {
|
|
55
153
|
const sel = argv[1], dx = Number(argv[2]), dy = Number(argv[3]);
|
|
56
154
|
if (!sel || !Number.isFinite(dx) || !Number.isFinite(dy)) die('drag needs <selector> <dx> <dy>');
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
const el = document.querySelector(s);
|
|
60
|
-
if (!el) return null;
|
|
61
|
-
const host = el.closest('[style*="left"]') ?? el;
|
|
62
|
-
return { x: host.style.left, y: host.style.top };
|
|
63
|
-
}, sel);
|
|
64
|
-
if (!posBefore) die('no element for ' + sel);
|
|
65
|
-
const box = await p.locator(sel).first().boundingBox();
|
|
66
|
-
if (!box) die('boundingBox failed for ' + sel);
|
|
67
|
-
const sx = box.x + box.width / 2, sy = box.y + Math.min(box.height / 2, 8);
|
|
68
|
-
await p.mouse.move(sx, sy);
|
|
69
|
-
await p.mouse.down();
|
|
70
|
-
for (let i = 1; i <= 10; i++) {
|
|
71
|
-
await p.mouse.move(sx + (dx * i) / 10, sy + (dy * i) / 10);
|
|
72
|
-
await new Promise((r) => setTimeout(r, 20));
|
|
73
|
-
}
|
|
74
|
-
await p.mouse.up();
|
|
75
|
-
await new Promise((r) => setTimeout(r, 300));
|
|
76
|
-
const posAfter = await p.evaluate((s) => {
|
|
77
|
-
const el = document.querySelector(s);
|
|
78
|
-
const host = el?.closest('[style*="left"]') ?? el;
|
|
79
|
-
return { x: host.style.left, y: host.style.top };
|
|
80
|
-
}, sel);
|
|
81
|
-
const moved = JSON.stringify(posBefore) !== JSON.stringify(posAfter);
|
|
82
|
-
console.log(JSON.stringify({ verb: 'drag', selector: sel, before: posBefore, after: posAfter, moved }));
|
|
155
|
+
const { verdict } = await execStep(page(), { verb: 'drag', selector: sel, dx, dy });
|
|
156
|
+
console.log(JSON.stringify(verdict));
|
|
83
157
|
} else if (verb === 'control') {
|
|
84
158
|
const expr = argv[1];
|
|
85
159
|
if (!expr) die('control needs a JS assertion expression');
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
console.log(JSON.stringify({ verb: 'control', expr, pass: result === true, result }));
|
|
160
|
+
const { verdict } = await execStep(page(), { verb: 'control', expr });
|
|
161
|
+
console.log(JSON.stringify(verdict));
|
|
89
162
|
} else if (verb === 'persist') {
|
|
90
163
|
const key = argv[1];
|
|
91
164
|
if (!key) die('persist needs a localStorage key');
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
console.log(JSON.stringify({ verb: 'persist', key, raw }));
|
|
165
|
+
const { verdict } = await execStep(page(), { verb: 'persist', key });
|
|
166
|
+
console.log(JSON.stringify(verdict));
|
|
95
167
|
} else {
|
|
96
|
-
die('unknown verb ' + JSON.stringify(verb) + ' — click | type | drag | control | persist');
|
|
168
|
+
die('unknown verb ' + JSON.stringify(verb) + ' — click | type | drag | control | persist | run');
|
|
97
169
|
}
|
|
98
170
|
process.exit(0);
|
package/README.md
CHANGED
|
@@ -84,6 +84,12 @@ When it is up, your browser opens the page by itself (default `http://127.0.0.1:
|
|
|
84
84
|
<img src="https://github.com/mitmplay/dsh-insight/blob/main/docs/images/dsi-insight-5.ws-explorer.png?raw=true"/>
|
|
85
85
|
</details>
|
|
86
86
|
|
|
87
|
+
<details>
|
|
88
|
+
<summary><strong>Glass browser</strong></summary>
|
|
89
|
+
<p>The Glass browser is a real browser living inside DSI. While you work, agents build and change DSI itself — plugins, panels, settings — and instead of telling you "it's done", they can prove it: the work runs right there in the Glass panel, and you watch it live. If a plugin breaks, you see exactly what broke with your own eyes instead of trusting a green test report — the browser is the receipt.</p>
|
|
90
|
+
<img src="https://raw.githubusercontent.com/mitmplay/dsh-insight/refs/heads/main/docs/images/dsi-insight-3.glass-browser.png"/>
|
|
91
|
+
</details>
|
|
92
|
+
|
|
87
93
|
## Included skills for:
|
|
88
94
|
- Coding agents: `/dsi-adr`, `/dsi-spec`, `/dsi-task`
|
|
89
95
|
- Integration helper for [OpenViking](https://openviking.ai/): `/dsi-ov-setup`
|
|
@@ -164,4 +170,4 @@ DSI_PORT=5171 DSH_PORT=3081 GLASS_CHASSIS_URL=http://192.168.1.9:9525 pnpm dsi d
|
|
|
164
170
|
[Apache-2.0](LICENSE) — Copyright © 2026 [Widi Harsojo](https://www.linkedin.com/in/wharsojo/)
|
|
165
171
|
> OPEN TO WORK (SG_PR)
|
|
166
172
|
|
|
167
|
-
**Your language.** The interface speaks English, Chinese, Indonesian & Spanish.
|
|
173
|
+
**Your language.** The interface speaks English, Chinese, Indonesian & Spanish.
|
package/bin/dsi-chassis.mjs
CHANGED
|
@@ -45,6 +45,21 @@ import {
|
|
|
45
45
|
writeOwnerMarker
|
|
46
46
|
} from '../src/lib/server/browser/chassis-shared.ts';
|
|
47
47
|
|
|
48
|
+
/** @typedef {{ ok: false, error: string } | { ok: true, addr: string }} BindVerdict */
|
|
49
|
+
/** @typedef {{ bind: string | undefined, port: number | undefined }} ParsedArgs */
|
|
50
|
+
/** @typedef {{ profileDir: string, args: string[], headless: boolean, width: number, height: number }} LaunchOptions */
|
|
51
|
+
/** @typedef {{ pid: number | null, port: number, close: () => Promise<void> }} LaunchResult */
|
|
52
|
+
/** @typedef {{ id: string, ownerSessionId: string, debugPort: number, pid: number | null, profileDir: string, close: () => Promise<void> }} Glass */
|
|
53
|
+
/** @typedef {{
|
|
54
|
+
* bind?: string,
|
|
55
|
+
* port?: number,
|
|
56
|
+
* debugPort?: number,
|
|
57
|
+
* profileRoot?: string,
|
|
58
|
+
* launch?: (o: LaunchOptions) => Promise<LaunchResult>,
|
|
59
|
+
* portFor?: (preferred?: number) => Promise<number>
|
|
60
|
+
* }} CompanionOptions */
|
|
61
|
+
/** @typedef {{ server: import('node:http').Server, port: number, glasses: Map<string, Glass>, stop: () => Promise<void> }} Companion */
|
|
62
|
+
|
|
48
63
|
/** The companion's disposable root — the same default the floor config
|
|
49
64
|
* ships (insight-config). The companion runs on the host and answers to
|
|
50
65
|
* the Borrowed Chrome posture, so deletes are GUARDED to this root. */
|
|
@@ -53,6 +68,7 @@ const PROFILE_ROOT = join(homedir(), '.dsi', 'browser-profiles');
|
|
|
53
68
|
/** D4 — the bind verdict. Pure: `--bind` is REQUIRED and 0.0.0.0 (and the
|
|
54
69
|
* IPv6 all-interfaces '::') are refused. The stamp already names the
|
|
55
70
|
* exact interface; bind-all buys nothing and invites every device. */
|
|
71
|
+
/** @param {string | undefined} bind @returns {BindVerdict} */
|
|
56
72
|
export function resolveBind(bind) {
|
|
57
73
|
if (bind === undefined || bind === '') {
|
|
58
74
|
return { ok: false, error: 'dsi-chassis: --bind <addr> is required (the private interface from the GLASS_CHASSIS_URL stamp); refusing to guess' };
|
|
@@ -64,7 +80,9 @@ export function resolveBind(bind) {
|
|
|
64
80
|
}
|
|
65
81
|
|
|
66
82
|
/** CLI arg parsing — pure, so the pins drive it directly. */
|
|
83
|
+
/** @param {string[]} argv @returns {ParsedArgs} */
|
|
67
84
|
export function parseArgs(argv) {
|
|
85
|
+
/** @type {ParsedArgs} */
|
|
68
86
|
const out = { bind: undefined, port: undefined };
|
|
69
87
|
for (let i = 0; i < argv.length; i += 1) {
|
|
70
88
|
const a = argv[i];
|
|
@@ -78,8 +96,10 @@ export function parseArgs(argv) {
|
|
|
78
96
|
|
|
79
97
|
/** A free port for Chrome's debugging listener — net probe, no lsof
|
|
80
98
|
* dependency, same behavior on macOS and Linux hosts. */
|
|
99
|
+
/** @param {number} [preferred] @returns {Promise<number>} */
|
|
81
100
|
async function freeChassisPort(preferred) {
|
|
82
101
|
const { createServer: probeServer } = await import('node:net');
|
|
102
|
+
/** @param {number} port @returns {Promise<boolean>} */
|
|
83
103
|
const tryBind = (port) =>
|
|
84
104
|
new Promise((resolve) => {
|
|
85
105
|
const s = probeServer();
|
|
@@ -95,6 +115,7 @@ async function freeChassisPort(preferred) {
|
|
|
95
115
|
/** The REAL launcher: headed Chromium on a disposable profile via the
|
|
96
116
|
* repo's pinned playwright-core, channel 'chrome' with the bundled
|
|
97
117
|
* chromium fallback — the same posture registry.open() births with. */
|
|
118
|
+
/** @param {LaunchOptions} opts @returns {Promise<LaunchResult>} */
|
|
98
119
|
async function defaultLaunch({ profileDir, args, headless, width, height }) {
|
|
99
120
|
const { chromium } = await import('playwright-core');
|
|
100
121
|
const ignoreDefaultArgs = ['--enable-automation', '--mute-audio', '--hide-scrollbars'];
|
|
@@ -136,6 +157,7 @@ async function defaultLaunch({ profileDir, args, headless, width, height }) {
|
|
|
136
157
|
* whole open/close/ownership/bridge contract without a real Chromium.
|
|
137
158
|
* Returns { server, port, glasses, stop }.
|
|
138
159
|
*/
|
|
160
|
+
/** @param {CompanionOptions} [opts] @returns {Promise<Companion>} */
|
|
139
161
|
export async function startChassisCompanion(opts = {}) {
|
|
140
162
|
const bindVerdict = resolveBind(opts.bind);
|
|
141
163
|
if (!bindVerdict.ok) throw new Error(bindVerdict.error);
|
|
@@ -150,7 +172,9 @@ export async function startChassisCompanion(opts = {}) {
|
|
|
150
172
|
// The ownership registry lives IN this process: one conversation = one
|
|
151
173
|
// glass, keyed by the requesting floor's ownerSessionId (karpathy edge
|
|
152
174
|
// case: two floors stamping the same companion each carry their own id).
|
|
175
|
+
/** @type {Map<string, Glass>} */
|
|
153
176
|
const glasses = new Map(); // id -> glass
|
|
177
|
+
/** @type {Map<string, string>} */
|
|
154
178
|
const byOwner = new Map(); // ownerSessionId -> id
|
|
155
179
|
|
|
156
180
|
const server = createServer(async (req, res) => {
|
|
@@ -165,6 +189,7 @@ export async function startChassisCompanion(opts = {}) {
|
|
|
165
189
|
const preq = httpRequest({ host: '127.0.0.1', port: glass.debugPort, path: cdp[2] + url.search, method: req.method, headers }, (pres) => {
|
|
166
190
|
const ctype = String(pres.headers['content-type'] ?? '');
|
|
167
191
|
if (ctype.includes('json')) {
|
|
192
|
+
/** @type {Buffer[]} */
|
|
168
193
|
const chunks = [];
|
|
169
194
|
pres.on('data', (c) => chunks.push(c));
|
|
170
195
|
pres.on('end', () => {
|
|
@@ -172,7 +197,7 @@ export async function startChassisCompanion(opts = {}) {
|
|
|
172
197
|
// through THIS companion — the floor never needs to know
|
|
173
198
|
// Chrome's loopback port (ADR fact 7, the Host hop).
|
|
174
199
|
const body = Buffer.concat(chunks).toString('utf8')
|
|
175
|
-
.split('ws://127.0.0.1:' + glass.debugPort).join('ws://' + (req.headers.host ?? bind + ':' +
|
|
200
|
+
.split('ws://127.0.0.1:' + glass.debugPort).join('ws://' + (req.headers.host ?? bind + ':' + glassPort(server)) + '/cdp/' + glass.id);
|
|
176
201
|
const headers = { ...pres.headers };
|
|
177
202
|
delete headers['transfer-encoding'];
|
|
178
203
|
res.writeHead(pres.statusCode ?? 200, { ...headers, 'content-length': Buffer.byteLength(body) });
|
|
@@ -197,6 +222,7 @@ export async function startChassisCompanion(opts = {}) {
|
|
|
197
222
|
return;
|
|
198
223
|
}
|
|
199
224
|
if (req.method === 'POST' && url.pathname === '/open') {
|
|
225
|
+
/** @type {Buffer[]} */
|
|
200
226
|
const chunks = [];
|
|
201
227
|
for await (const c of req) chunks.push(c);
|
|
202
228
|
let body;
|
|
@@ -232,12 +258,15 @@ export async function startChassisCompanion(opts = {}) {
|
|
|
232
258
|
'--autoplay-policy=no-user-gesture-required',
|
|
233
259
|
'--window-size=' + (width + 6) + ',' + (height + 70)
|
|
234
260
|
];
|
|
235
|
-
|
|
261
|
+
let born;
|
|
262
|
+
try {
|
|
263
|
+
born = await launch({ profileDir, args, headless: body.headless === true, width, height });
|
|
264
|
+
} catch (e) {
|
|
236
265
|
// a failed birth must not leave a profile dir behind (and the
|
|
237
266
|
// error rides the honest 500 to the floor's panel)
|
|
238
267
|
try { if (profileDir.startsWith(profileRoot)) rmSync(profileDir, { recursive: true, force: true }); } catch { /* best-effort */ }
|
|
239
268
|
throw e;
|
|
240
|
-
}
|
|
269
|
+
}
|
|
241
270
|
const glass = {
|
|
242
271
|
id,
|
|
243
272
|
ownerSessionId,
|
|
@@ -262,6 +291,7 @@ export async function startChassisCompanion(opts = {}) {
|
|
|
262
291
|
return;
|
|
263
292
|
}
|
|
264
293
|
if (req.method === 'POST' && url.pathname === '/close') {
|
|
294
|
+
/** @type {Buffer[]} */
|
|
265
295
|
const chunks = [];
|
|
266
296
|
for await (const c of req) chunks.push(c);
|
|
267
297
|
let body;
|
|
@@ -292,6 +322,7 @@ export async function startChassisCompanion(opts = {}) {
|
|
|
292
322
|
}
|
|
293
323
|
});
|
|
294
324
|
|
|
325
|
+
/** @param {Glass} glass @returns {Promise<void>} */
|
|
295
326
|
function releaseGlass(glass) {
|
|
296
327
|
glasses.delete(glass.id);
|
|
297
328
|
if (byOwner.get(glass.ownerSessionId) === glass.id) byOwner.delete(glass.ownerSessionId);
|
|
@@ -303,6 +334,7 @@ export async function startChassisCompanion(opts = {}) {
|
|
|
303
334
|
})();
|
|
304
335
|
}
|
|
305
336
|
|
|
337
|
+
/** @param {import('node:http').IncomingMessage} req @param {import('node:net').Socket} socket @param {Buffer} head */
|
|
306
338
|
const upgrade = (req, socket, head) => {
|
|
307
339
|
const m = (req.url ?? '').match(/^\/cdp\/([^/]+)(\/devtools\/.*)$/);
|
|
308
340
|
if (!m) { socket.destroy(); return; }
|
|
@@ -310,6 +342,7 @@ export async function startChassisCompanion(opts = {}) {
|
|
|
310
342
|
if (!glass) { socket.destroy(); return; }
|
|
311
343
|
// Raw pipe to Chrome's loopback port; the Host header is rewritten —
|
|
312
344
|
// recent Chrome validates it (ADR fact 7) and the companion is the hop.
|
|
345
|
+
/** @type {string[]} */
|
|
313
346
|
const headers = [];
|
|
314
347
|
const raw = req.rawHeaders;
|
|
315
348
|
for (let i = 0; i < raw.length; i += 2) {
|
|
@@ -328,13 +361,13 @@ export async function startChassisCompanion(opts = {}) {
|
|
|
328
361
|
server.on('upgrade', upgrade);
|
|
329
362
|
|
|
330
363
|
const wanted = opts.port ?? 9560;
|
|
331
|
-
const boundPort = await new Promise((res, rej) => {
|
|
364
|
+
const boundPort = await (/** @type {Promise<number>} */ (new Promise((res, rej) => {
|
|
332
365
|
server.once('error', rej);
|
|
333
366
|
server.listen(wanted, bind, () => {
|
|
334
367
|
const a = server.address();
|
|
335
368
|
res(typeof a === 'object' && a ? a.port : wanted);
|
|
336
369
|
});
|
|
337
|
-
});
|
|
370
|
+
})));
|
|
338
371
|
return {
|
|
339
372
|
server,
|
|
340
373
|
port: boundPort,
|
|
@@ -342,11 +375,12 @@ export async function startChassisCompanion(opts = {}) {
|
|
|
342
375
|
stop: async () => {
|
|
343
376
|
server.removeAllListeners('upgrade');
|
|
344
377
|
for (const g of [...glasses.values()]) await releaseGlass(g);
|
|
345
|
-
await new Promise((res) => server.close(() => res()));
|
|
378
|
+
await /** @type {Promise<void>} */ (new Promise((res) => server.close(() => res())));
|
|
346
379
|
}
|
|
347
380
|
};
|
|
348
381
|
}
|
|
349
382
|
|
|
383
|
+
/** @param {import('node:http').Server} server @returns {number} */
|
|
350
384
|
function glassPort(server) {
|
|
351
385
|
const a = server.address();
|
|
352
386
|
return typeof a === 'object' && a ? a.port : 0;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-yellow-200:oklch(94.5% .129 101.54);--color-green-300:oklch(87.1% .15 154.449);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-emerald-500:oklch(69.6% .17 162.48);--color-sky-400:oklch(74.6% .16 232.661);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-900:oklch(37.9% .146 265.522);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--color-slate-950:oklch(12.9% .042 264.695);--color-zinc-100:oklch(96.7% .001 286.375);--color-zinc-200:oklch(92% .004 286.32);--color-zinc-300:oklch(87.1% .006 286.286);--color-zinc-400:oklch(70.5% .015 286.067);--color-zinc-500:oklch(55.2% .016 285.938);--color-zinc-600:oklch(44.2% .017 285.786);--color-zinc-700:oklch(37% .013 285.805);--color-zinc-800:oklch(27.4% .006 286.033);--color-zinc-900:oklch(21% .006 285.885);--color-neutral-100:oklch(97% 0 none);--color-neutral-200:oklch(92.2% 0 none);--color-neutral-400:oklch(70.8% 0 none);--color-neutral-700:oklch(37.1% 0 none);--color-neutral-800:oklch(26.9% 0 none);--color-neutral-900:oklch(20.5% 0 none);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-normal:1.5;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-surface:#f8f9fa;--color-surface-alt:#f1f3f5;--color-surface-hover:#e9ecef;--color-surface-border:#dee2e6;--color-surface-elevated:#fff;--color-subagent-tint-1:beige;--color-subagent-tint-2:#e9e3c9;--color-subagent-tint-3:#ddd3b0;--color-text-primary:#212529;--color-text-secondary:#6c757d;--color-text-muted:#adb5bd;--color-accent-blue:#3b82f6;--color-accent-purple:#8b5cf6;--color-accent-purple-soft:#9f88fb;--color-accent-purple-ink:#2e1065;--color-accent-emerald-deep:#15803d;--color-accent-amber:#f59e0b;--color-accent-rose:#f43f5e;--color-accent-cyan:#06b6d4;--color-status-pass:#10b981;--color-status-fail:#ef4444;--color-status-pending:#f59e0b;--color-status-fail-ink:#fff;--color-tree-repo:#ff4500;--color-tree-child:#d2691e;--color-tree-amber:#f7ad31;--color-accent-deep:#7c3aed;--color-success-ink:#1a7f37;--color-success-soft:#27ae60;--color-green-verify:#16a34a;--color-accent-orange:#e67e22;--color-accent-amber-ink:#d97706;--color-accent-amber-ink-deep:#b45309;--color-danger-madrid:#e74c3c;--color-danger-github:#cf222e;--color-danger-editor-surface:#45161c;--color-danger-editor-ink:#ffb4bb;--color-doc-child:maroon;--color-navy-focus:#1e3a8a;--color-header-wash:#fdf5e6;--color-slate-neutral:#52606d;--color-danger-wash:#fef2f2;--color-danger-wash-border:#fee2e2;--color-danger-wash-ink:#991b1b;--color-ws-violet:#9400d3;--color-ws-green:#00a802;--color-ws-blue:#06c}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root{--si-run:#b91c1c;--color-surface-primary:var(--color-surface-elevated);--color-surface-secondary:var(--color-surface-alt);--color-border:var(--color-surface-border);--color-text:var(--color-text-primary);--color-bg:var(--color-surface)}svg{color:var(--color-accent-purple)}}@layer components;@layer utilities{.\@container{container-type:inline-size}.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.-top-3{top:calc(var(--spacing) * -3)}.top-0{top:0}.top-1{top:var(--spacing)}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-1\/2{top:50%}.top-5{top:calc(var(--spacing) * 5)}.top-8{top:calc(var(--spacing) * 8)}.top-full{top:100%}.-right-3{right:calc(var(--spacing) * -3)}.right-0{right:0}.right-1{right:var(--spacing)}.right-1\.5{right:calc(var(--spacing) * 1.5)}.right-2{right:calc(var(--spacing) * 2)}.right-3{right:calc(var(--spacing) * 3)}.right-5{right:calc(var(--spacing) * 5)}.right-full{right:100%}.bottom-0{bottom:0}.bottom-0\.5{bottom:calc(var(--spacing) * .5)}.bottom-1{bottom:var(--spacing)}.bottom-1\/2{bottom:50%}.bottom-\[50vh\]{bottom:50vh}.bottom-full{bottom:100%}.left-0{left:0}.left-1\/2{left:50%}.left-3{left:calc(var(--spacing) * 3)}.left-7{left:calc(var(--spacing) * 7)}.left-full{left:100%}.isolate{isolation:isolate}.z-10{z-index:10}.z-30{z-index:30}.z-40{z-index:40}.z-41{z-index:41}.z-50{z-index:50}.z-1000,.z-\[1000\]{z-index:1000}.z-auto{z-index:auto}.order-0{order:0}.order-2{order:2}.row-1{grid-row:1}.\!container{width:100%!important}@media (width>=40rem){.\!container{max-width:40rem!important}}@media (width>=48rem){.\!container{max-width:48rem!important}}@media (width>=64rem){.\!container{max-width:64rem!important}}@media (width>=80rem){.\!container{max-width:80rem!important}}@media (width>=96rem){.\!container{max-width:96rem!important}}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-0{margin:0}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-0\.5{margin-inline:calc(var(--spacing) * .5)}.mx-1{margin-inline:var(--spacing)}.mx-auto{margin-inline:auto}.my-0\.5{margin-block:calc(var(--spacing) * .5)}.my-1{margin-block:var(--spacing)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-px{margin-top:1px}.mr-1\.5{margin-right:calc(var(--spacing) * 1.5)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.ml-1{margin-left:var(--spacing)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-\[-2px\]{margin-left:-2px}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.h-1{height:var(--spacing)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-16{height:calc(var(--spacing) * 16)}.h-\[18px\]{height:18px}.h-\[22px\]{height:22px}.h-\[50px\]{height:50px}.h-\[62px\]{height:62px}.h-dvh{height:100dvh}.h-full{height:100%}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-80{max-height:calc(var(--spacing) * 80)}.max-h-\[28rem\]{max-height:28rem}.max-h-\[30rem\]{max-height:30rem}.max-h-\[60vh\]{max-height:60vh}.max-h-\[500px\]{max-height:500px}.max-h-\[calc\(100vh-80px\)\]{max-height:calc(100vh - 80px)}.min-h-0{min-height:0}.min-h-72{min-height:calc(var(--spacing) * 72)}.min-h-80{min-height:calc(var(--spacing) * 80)}.min-h-\[2\.75rem\]{min-height:2.75rem}.w-1{width:var(--spacing)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-14{width:calc(var(--spacing) * 14)}.w-15{width:calc(var(--spacing) * 15)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-36{width:calc(var(--spacing) * 36)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-96{width:calc(var(--spacing) * 96)}.w-\[18px\]{width:18px}.w-\[22px\]{width:22px}.w-\[62px\]{width:62px}.w-\[200px\]{width:200px}.w-fit{width:fit-content}.w-full{width:100%}.w-max{width:max-content}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-56{max-width:calc(var(--spacing) * 56)}.max-w-72{max-width:calc(var(--spacing) * 72)}.max-w-\[16rem\]{max-width:16rem}.max-w-\[80\%\]{max-width:80%}.max-w-\[80vw\]{max-width:80vw}.max-w-\[85\%\]{max-width:85%}.max-w-\[min\(100\%\,1600px\)\]{max-width:min(100%,1600px)}.max-w-full{max-width:100%}.max-w-sm{max-width:var(--container-sm)}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:0}.min-w-5{min-width:calc(var(--spacing) * 5)}.min-w-44{min-width:calc(var(--spacing) * 44)}.min-w-72{min-width:calc(var(--spacing) * 72)}.flex-1{flex:1}.flex-none{flex:none}.flex-shrink,.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.border-collapse{border-collapse:collapse}.origin-top-left{transform-origin:0 0}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.zoom-1{zoom:1%}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-move{cursor:move}.cursor-pointer{cursor:pointer}.cursor-zoom-in{cursor:zoom-in}.resize{resize:both}.resize-none{resize:none}.scrollbar-none{scrollbar-width:none}.list-none{list-style-type:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[auto_1fr\]{grid-template-columns:auto 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-0\.5{column-gap:calc(var(--spacing) * .5)}.gap-x-1{column-gap:var(--spacing)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-0\.5{row-gap:calc(var(--spacing) * .5)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-clip{overflow-x:clip}.overflow-y-auto{overflow-y:auto}.overflow-y-hidden{overflow-y:hidden}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\[2px\]{border-radius:2px}.rounded-\[16px\]{border-radius:16px}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.rounded-t-lg{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.rounded-t-md{border-top-left-radius:var(--radius-md);border-top-right-radius:var(--radius-md)}.rounded-l-sm{border-top-left-radius:var(--radius-sm);border-bottom-left-radius:var(--radius-sm)}.rounded-r-sm{border-top-right-radius:var(--radius-sm);border-bottom-right-radius:var(--radius-sm)}.rounded-br-sm{border-bottom-right-radius:var(--radius-sm)}.rounded-bl-sm{border-bottom-left-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.border-l-0{border-left-style:var(--tw-border-style);border-left-width:0}.border-none{--tw-border-style:none;border-style:none}.border-\[var\(--color-accent-deep\)\]{border-color:var(--color-accent-deep)}.border-\[var\(--color-accent-deep\)\]\/30{border-color:#7c3aed4d}@supports (color:color-mix(in lab, red, red)){.border-\[var\(--color-accent-deep\)\]\/30{border-color:color-mix(in oklab, var(--color-accent-deep) 30%, transparent)}}.border-\[var\(--color-surface-border\)\]{border-color:var(--color-surface-border)}.border-accent-blue{border-color:var(--color-accent-blue)}.border-accent-blue\/20{border-color:#3b82f633}@supports (color:color-mix(in lab, red, red)){.border-accent-blue\/20{border-color:color-mix(in oklab, var(--color-accent-blue) 20%, transparent)}}.border-accent-blue\/30{border-color:#3b82f64d}@supports (color:color-mix(in lab, red, red)){.border-accent-blue\/30{border-color:color-mix(in oklab, var(--color-accent-blue) 30%, transparent)}}.border-accent-purple\/30{border-color:#8b5cf64d}@supports (color:color-mix(in lab, red, red)){.border-accent-purple\/30{border-color:color-mix(in oklab, var(--color-accent-purple) 30%, transparent)}}.border-black\/10{border-color:#0000001a}@supports (color:color-mix(in lab, red, red)){.border-black\/10{border-color:color-mix(in oklab, var(--color-black) 10%, transparent)}}.border-black\/15{border-color:#00000026}@supports (color:color-mix(in lab, red, red)){.border-black\/15{border-color:color-mix(in oklab, var(--color-black) 15%, transparent)}}.border-danger-wash-border{border-color:var(--color-danger-wash-border)}.border-slate-600{border-color:var(--color-slate-600)}.border-slate-700\/50{border-color:#31415880}@supports (color:color-mix(in lab, red, red)){.border-slate-700\/50{border-color:color-mix(in oklab, var(--color-slate-700) 50%, transparent)}}.border-slate-800{border-color:var(--color-slate-800)}.border-status-fail\/30{border-color:#ef44444d}@supports (color:color-mix(in lab, red, red)){.border-status-fail\/30{border-color:color-mix(in oklab, var(--color-status-fail) 30%, transparent)}}.border-status-pass{border-color:var(--color-status-pass)}.border-status-pass\/30{border-color:#10b9814d}@supports (color:color-mix(in lab, red, red)){.border-status-pass\/30{border-color:color-mix(in oklab, var(--color-status-pass) 30%, transparent)}}.border-status-pending\/30{border-color:#f59e0b4d}@supports (color:color-mix(in lab, red, red)){.border-status-pending\/30{border-color:color-mix(in oklab, var(--color-status-pending) 30%, transparent)}}.border-surface-border{border-color:var(--color-surface-border)}.border-surface-border\/30{border-color:#dee2e64d}@supports (color:color-mix(in lab, red, red)){.border-surface-border\/30{border-color:color-mix(in oklab, var(--color-surface-border) 30%, transparent)}}.border-surface-border\/40{border-color:#dee2e666}@supports (color:color-mix(in lab, red, red)){.border-surface-border\/40{border-color:color-mix(in oklab, var(--color-surface-border) 40%, transparent)}}.border-surface-border\/50{border-color:#dee2e680}@supports (color:color-mix(in lab, red, red)){.border-surface-border\/50{border-color:color-mix(in oklab, var(--color-surface-border) 50%, transparent)}}.border-text-muted\/15{border-color:#adb5bd26}@supports (color:color-mix(in lab, red, red)){.border-text-muted\/15{border-color:color-mix(in oklab, var(--color-text-muted) 15%, transparent)}}.border-text-muted\/20{border-color:#adb5bd33}@supports (color:color-mix(in lab, red, red)){.border-text-muted\/20{border-color:color-mix(in oklab, var(--color-text-muted) 20%, transparent)}}.border-transparent{border-color:#0000}.border-zinc-300{border-color:var(--color-zinc-300)}.border-zinc-700{border-color:var(--color-zinc-700)}.bg-\[var\(--color-accent-deep\)\]{background-color:var(--color-accent-deep)}.bg-\[var\(--color-accent-deep\)\]\/10{background-color:#7c3aed1a}@supports (color:color-mix(in lab, red, red)){.bg-\[var\(--color-accent-deep\)\]\/10{background-color:color-mix(in oklab, var(--color-accent-deep) 10%, transparent)}}.bg-\[var\(--color-subagent-tint-1\)\]{background-color:var(--color-subagent-tint-1)}.bg-\[var\(--color-subagent-tint-2\)\]{background-color:var(--color-subagent-tint-2)}.bg-\[var\(--color-subagent-tint-3\)\]{background-color:var(--color-subagent-tint-3)}.bg-\[var\(--color-surface-elevated\)\]{background-color:var(--color-surface-elevated)}.bg-accent-blue{background-color:var(--color-accent-blue)}.bg-accent-blue\/10{background-color:#3b82f61a}@supports (color:color-mix(in lab, red, red)){.bg-accent-blue\/10{background-color:color-mix(in oklab, var(--color-accent-blue) 10%, transparent)}}.bg-accent-blue\/15{background-color:#3b82f626}@supports (color:color-mix(in lab, red, red)){.bg-accent-blue\/15{background-color:color-mix(in oklab, var(--color-accent-blue) 15%, transparent)}}.bg-accent-blue\/20{background-color:#3b82f633}@supports (color:color-mix(in lab, red, red)){.bg-accent-blue\/20{background-color:color-mix(in oklab, var(--color-accent-blue) 20%, transparent)}}.bg-accent-blue\/30{background-color:#3b82f64d}@supports (color:color-mix(in lab, red, red)){.bg-accent-blue\/30{background-color:color-mix(in oklab, var(--color-accent-blue) 30%, transparent)}}.bg-accent-cyan\/10{background-color:#06b6d41a}@supports (color:color-mix(in lab, red, red)){.bg-accent-cyan\/10{background-color:color-mix(in oklab, var(--color-accent-cyan) 10%, transparent)}}.bg-accent-emerald-deep{background-color:var(--color-accent-emerald-deep)}.bg-accent-purple-ink{background-color:var(--color-accent-purple-ink)}.bg-accent-purple-soft{background-color:var(--color-accent-purple-soft)}.bg-accent-purple\/15{background-color:#8b5cf626}@supports (color:color-mix(in lab, red, red)){.bg-accent-purple\/15{background-color:color-mix(in oklab, var(--color-accent-purple) 15%, transparent)}}.bg-accent-purple\/20{background-color:#8b5cf633}@supports (color:color-mix(in lab, red, red)){.bg-accent-purple\/20{background-color:color-mix(in oklab, var(--color-accent-purple) 20%, transparent)}}.bg-amber-400{background-color:var(--color-amber-400)}.bg-black\/5{background-color:#0000000d}@supports (color:color-mix(in lab, red, red)){.bg-black\/5{background-color:color-mix(in oklab, var(--color-black) 5%, transparent)}}.bg-black\/40{background-color:#0006}@supports (color:color-mix(in lab, red, red)){.bg-black\/40{background-color:color-mix(in oklab, var(--color-black) 40%, transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.bg-black\/60{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.bg-blue-100{background-color:var(--color-blue-100)}.bg-danger-wash{background-color:var(--color-danger-wash)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-green-300{background-color:var(--color-green-300)}.bg-green-500{background-color:var(--color-green-500)}.bg-header-wash{background-color:var(--color-header-wash)}.bg-neutral-100{background-color:var(--color-neutral-100)}.bg-neutral-200{background-color:var(--color-neutral-200)}.bg-red-500{background-color:var(--color-red-500)}.bg-sky-400{background-color:var(--color-sky-400)}.bg-slate-700{background-color:var(--color-slate-700)}.bg-slate-800{background-color:var(--color-slate-800)}.bg-slate-800\/60{background-color:#1d293d99}@supports (color:color-mix(in lab, red, red)){.bg-slate-800\/60{background-color:color-mix(in oklab, var(--color-slate-800) 60%, transparent)}}.bg-slate-800\/90{background-color:#1d293de6}@supports (color:color-mix(in lab, red, red)){.bg-slate-800\/90{background-color:color-mix(in oklab, var(--color-slate-800) 90%, transparent)}}.bg-slate-900{background-color:var(--color-slate-900)}.bg-slate-900\/40{background-color:#0f172b66}@supports (color:color-mix(in lab, red, red)){.bg-slate-900\/40{background-color:color-mix(in oklab, var(--color-slate-900) 40%, transparent)}}.bg-slate-950{background-color:var(--color-slate-950)}.bg-status-fail{background-color:var(--color-status-fail)}.bg-status-fail\/10{background-color:#ef44441a}@supports (color:color-mix(in lab, red, red)){.bg-status-fail\/10{background-color:color-mix(in oklab, var(--color-status-fail) 10%, transparent)}}.bg-status-pass{background-color:var(--color-status-pass)}.bg-status-pass\/10{background-color:#10b9811a}@supports (color:color-mix(in lab, red, red)){.bg-status-pass\/10{background-color:color-mix(in oklab, var(--color-status-pass) 10%, transparent)}}.bg-status-pass\/100{background-color:var(--color-status-pass)}.bg-status-pending{background-color:var(--color-status-pending)}.bg-status-pending\/10{background-color:#f59e0b1a}@supports (color:color-mix(in lab, red, red)){.bg-status-pending\/10{background-color:color-mix(in oklab, var(--color-status-pending) 10%, transparent)}}.bg-status-pending\/100{background-color:var(--color-status-pending)}.bg-surface{background-color:var(--color-surface)}.bg-surface-alt{background-color:var(--color-surface-alt)}.bg-surface-border{background-color:var(--color-surface-border)}.bg-surface-elevated{background-color:var(--color-surface-elevated)}.bg-surface\/60{background-color:#f8f9fa99}@supports (color:color-mix(in lab, red, red)){.bg-surface\/60{background-color:color-mix(in oklab, var(--color-surface) 60%, transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/95{background-color:#fffffff2}@supports (color:color-mix(in lab, red, red)){.bg-white\/95{background-color:color-mix(in oklab, var(--color-white) 95%, transparent)}}.bg-yellow-200{background-color:var(--color-yellow-200)}.bg-zinc-400{background-color:var(--color-zinc-400)}.bg-\[linear-gradient\(90deg\,color-mix\(in_srgb\,var\(--color-status-pass\)_18\%\,var\(--color-surface\)\)\,var\(--color-header-wash\)_65\%\,var\(--color-surface\)\)\]{background-image:linear-gradient(90deg,#ceede4,var(--color-header-wash) 65%,var(--color-surface))}@supports (color:color-mix(in lab, red, red)){.bg-\[linear-gradient\(90deg\,color-mix\(in_srgb\,var\(--color-status-pass\)_18\%\,var\(--color-surface\)\)\,var\(--color-header-wash\)_65\%\,var\(--color-surface\)\)\]{background-image:linear-gradient(90deg,color-mix(in srgb,var(--color-status-pass) 18%,var(--color-surface)),var(--color-header-wash) 65%,var(--color-surface))}}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.\[padding\:0_10px\]{padding:0 10px}.p-0{padding:0}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-10{padding:calc(var(--spacing) * 10)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-16{padding-block:calc(var(--spacing) * 16)}.py-\[0\.1rem\]{padding-block:.1rem}.py-px{padding-block:1px}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-4{padding-right:calc(var(--spacing) * 4)}.pr-7{padding-right:calc(var(--spacing) * 7)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-1{padding-bottom:var(--spacing)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-1{padding-left:var(--spacing)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-bottom{vertical-align:bottom}.align-middle{vertical-align:middle}.align-top{vertical-align:top}.font-mono{font-family:var(--font-mono)}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.8rem\]{font-size:.8rem}.text-\[0\.6875rem\]{font-size:.6875rem}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[18px\]{font-size:18px}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-none{--tw-leading:1;line-height:1}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[color\:var\(--color-accent-blue\)\]{color:var(--color-accent-blue)}.text-\[color\:var\(--color-accent-purple\)\]{color:var(--color-accent-purple)}.text-\[color\:var\(--color-text-secondary\,\#6c757d\)\]{color:var(--color-text-secondary,#6c757d)}.text-\[var\(--color-accent-deep\)\]{color:var(--color-accent-deep)}.text-\[var\(--color-accent-purple\)\]{color:var(--color-accent-purple)}.text-\[var\(--color-text-primary\)\]{color:var(--color-text-primary)}.text-\[var\(--color-text-secondary\)\]{color:var(--color-text-secondary)}.text-accent-blue{color:var(--color-accent-blue)}.text-accent-purple{color:var(--color-accent-purple)}.text-accent-purple-ink{color:var(--color-accent-purple-ink)}.text-accent-purple\/80{color:#8b5cf6cc}@supports (color:color-mix(in lab, red, red)){.text-accent-purple\/80{color:color-mix(in oklab, var(--color-accent-purple) 80%, transparent)}}.text-amber-400{color:var(--color-amber-400)}.text-amber-500{color:var(--color-amber-500)}.text-blue-900{color:var(--color-blue-900)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-neutral-400{color:var(--color-neutral-400)}.text-neutral-700{color:var(--color-neutral-700)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-slate-100{color:var(--color-slate-100)}.text-slate-200{color:var(--color-slate-200)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-500{color:var(--color-slate-500)}.text-status-fail{color:var(--color-status-fail)}.text-status-fail-ink{color:var(--color-status-fail-ink)}.text-status-pass{color:var(--color-status-pass)}.text-status-pending{color:var(--color-status-pending)}.text-status-pending\/80{color:#f59e0bcc}@supports (color:color-mix(in lab, red, red)){.text-status-pending\/80{color:color-mix(in oklab, var(--color-status-pending) 80%, transparent)}}.text-surface{color:var(--color-surface)}.text-text-muted{color:var(--color-text-muted)}.text-text-muted\/60{color:#adb5bd99}@supports (color:color-mix(in lab, red, red)){.text-text-muted\/60{color:color-mix(in oklab, var(--color-text-muted) 60%, transparent)}}.text-text-primary{color:var(--color-text-primary)}.text-text-secondary{color:var(--color-text-secondary)}.text-white{color:var(--color-white)}.text-zinc-500{color:var(--color-zinc-500)}.text-zinc-600{color:var(--color-zinc-600)}.text-zinc-800{color:var(--color-zinc-800)}.text-zinc-900{color:var(--color-zinc-900)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.decoration-surface-border{-webkit-text-decoration-color:var(--color-surface-border);-webkit-text-decoration-color:var(--color-surface-border);-webkit-text-decoration-color:var(--color-surface-border);text-decoration-color:var(--color-surface-border)}.underline-offset-2{text-underline-offset:2px}.accent-\[var\(--color-accent-purple\)\]{accent-color:var(--color-accent-purple)}.opacity-0{opacity:0}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-accent-purple-ink\/30{--tw-ring-color:#2e10654d}@supports (color:color-mix(in lab, red, red)){.ring-accent-purple-ink\/30{--tw-ring-color:color-mix(in oklab, var(--color-accent-purple-ink) 30%, transparent)}}.ring-danger-wash-border{--tw-ring-color:var(--color-danger-wash-border)}.ring-status-fail\/30{--tw-ring-color:#ef44444d}@supports (color:color-mix(in lab, red, red)){.ring-status-fail\/30{--tw-ring-color:color-mix(in oklab, var(--color-status-fail) 30%, transparent)}}.ring-status-pending\/30{--tw-ring-color:#f59e0b4d}@supports (color:color-mix(in lab, red, red)){.ring-status-pending\/30{--tw-ring-color:color-mix(in oklab, var(--color-status-pending) 30%, transparent)}}.ring-surface-border{--tw-ring-color:var(--color-surface-border)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.grayscale{--tw-grayscale:grayscale(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[background-color\,transform\]{transition-property:background-color,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-linear{--tw-ease:linear;transition-timing-function:linear}.outline-none{--tw-outline-style:none;outline-style:none}.select-all{-webkit-user-select:all;user-select:all}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\/bubble\:text-\[var\(--color-accent-deep\)\]:is(:where(.group\/bubble):hover *){color:var(--color-accent-deep)}.group-hover\/bubble\:opacity-100:is(:where(.group\/bubble):hover *),.group-hover\/code\:opacity-100:is(:where(.group\/code):hover *),.group-hover\/diagram\:opacity-100:is(:where(.group\/diagram):hover *),.group-hover\/featurespec\:opacity-100:is(:where(.group\/featurespec):hover *),.group-hover\/markdown\:opacity-100:is(:where(.group\/markdown):hover *){opacity:1}.group-hover\/new\:block:is(:where(.group\/new):hover *){display:block}.group-hover\/new\:hidden:is(:where(.group\/new):hover *){display:none}.group-hover\/reasoning\:opacity-100:is(:where(.group\/reasoning):hover *),.group-hover\/tab\:opacity-100:is(:where(.group\/tab):hover *),.group-hover\/table\:opacity-100:is(:where(.group\/table):hover *),.group-hover\/terminal\:opacity-100:is(:where(.group\/terminal):hover *){opacity:1}}.placeholder\:text-text-muted::placeholder{color:var(--color-text-muted)}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media (hover:hover){.hover\:scale-105:hover{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.hover\:border-surface-border:hover{border-color:var(--color-surface-border)}.hover\:bg-\[color-mix\(in_srgb\,var\(--color-accent-emerald-deep\)_85\%\,black\)\]:hover{background-color:#126d34}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\[color-mix\(in_srgb\,var\(--color-accent-emerald-deep\)_85\%\,black\)\]:hover{background-color:color-mix(in srgb,var(--color-accent-emerald-deep) 85%,black)}}.hover\:bg-\[var\(--color-accent-deep\)\]\/20:hover{background-color:#7c3aed33}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\[var\(--color-accent-deep\)\]\/20:hover{background-color:color-mix(in oklab, var(--color-accent-deep) 20%, transparent)}}.hover\:bg-accent-blue:hover{background-color:var(--color-accent-blue)}.hover\:bg-accent-blue\/20:hover{background-color:#3b82f633}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent-blue\/20:hover{background-color:color-mix(in oklab, var(--color-accent-blue) 20%, transparent)}}.hover\:bg-accent-purple\/5:hover{background-color:#8b5cf60d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent-purple\/5:hover{background-color:color-mix(in oklab, var(--color-accent-purple) 5%, transparent)}}.hover\:bg-danger-wash-border:hover{background-color:var(--color-danger-wash-border)}.hover\:bg-red-500:hover{background-color:var(--color-red-500)}.hover\:bg-slate-600:hover{background-color:var(--color-slate-600)}.hover\:bg-slate-700:hover{background-color:var(--color-slate-700)}.hover\:bg-slate-800:hover{background-color:var(--color-slate-800)}.hover\:bg-status-fail:hover{background-color:var(--color-status-fail)}.hover\:bg-status-pass:hover{background-color:var(--color-status-pass)}.hover\:bg-status-pending\/20:hover{background-color:#f59e0b33}@supports (color:color-mix(in lab, red, red)){.hover\:bg-status-pending\/20:hover{background-color:color-mix(in oklab, var(--color-status-pending) 20%, transparent)}}.hover\:bg-surface:hover{background-color:var(--color-surface)}.hover\:bg-surface-alt:hover{background-color:var(--color-surface-alt)}.hover\:bg-surface-border\/20:hover{background-color:#dee2e633}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-border\/20:hover{background-color:color-mix(in oklab, var(--color-surface-border) 20%, transparent)}}.hover\:bg-surface-hover:hover{background-color:var(--color-surface-hover)}.hover\:bg-zinc-100:hover{background-color:var(--color-zinc-100)}.hover\:bg-zinc-200:hover{background-color:var(--color-zinc-200)}.hover\:text-\[color\:var\(--color-text-primary\,\#212529\)\]:hover{color:var(--color-text-primary,#212529)}.hover\:text-accent-purple:hover{color:var(--color-accent-purple)}.hover\:text-slate-200:hover{color:var(--color-slate-200)}.hover\:text-status-pending:hover{color:var(--color-status-pending)}.hover\:text-text-muted:hover{color:var(--color-text-muted)}.hover\:text-text-primary:hover{color:var(--color-text-primary)}.hover\:text-text-secondary:hover{color:var(--color-text-secondary)}.hover\:opacity-80:hover{opacity:.8}.hover\:ring-accent-purple\/40:hover{--tw-ring-color:#8b5cf666}@supports (color:color-mix(in lab, red, red)){.hover\:ring-accent-purple\/40:hover{--tw-ring-color:color-mix(in oklab, var(--color-accent-purple) 40%, transparent)}}@media (hover:hover){.hover\:group-hover\/bubble\:text-\[var\(--color-accent-deep\)\]:hover:is(:where(.group\/bubble):hover *){color:var(--color-accent-deep)}}}.focus\:border-text-muted:focus{border-color:var(--color-text-muted)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-text-muted:focus{--tw-ring-color:var(--color-text-muted)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:opacity-100:focus-visible{opacity:1}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-surface:disabled{background-color:var(--color-surface)}.disabled\:bg-surface-alt:disabled{background-color:var(--color-surface-alt)}.disabled\:text-text-muted:disabled{color:var(--color-text-muted)}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}@media (hover:hover){.disabled\:hover\:bg-surface-alt:disabled:hover{background-color:var(--color-surface-alt)}.disabled\:hover\:bg-transparent:disabled:hover{background-color:#0000}}@media (prefers-color-scheme:dark){.dark\:border-white\/15{border-color:#ffffff26}@supports (color:color-mix(in lab, red, red)){.dark\:border-white\/15{border-color:color-mix(in oklab, var(--color-white) 15%, transparent)}}.dark\:border-white\/20{border-color:#fff3}@supports (color:color-mix(in lab, red, red)){.dark\:border-white\/20{border-color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.dark\:bg-neutral-700{background-color:var(--color-neutral-700)}.dark\:bg-neutral-800{background-color:var(--color-neutral-800)}.dark\:bg-neutral-900\/95{background-color:#171717f2}@supports (color:color-mix(in lab, red, red)){.dark\:bg-neutral-900\/95{background-color:color-mix(in oklab, var(--color-neutral-900) 95%, transparent)}}.dark\:text-neutral-200{color:var(--color-neutral-200)}}@media (pointer:coarse){.pointer-coarse\:opacity-100{opacity:1}}}pre code.hljs{padding:1em;display:block;overflow-x:auto}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}[data-theme=dark]{--color-surface:#16181d;--color-surface-alt:#1d2026;--color-surface-hover:#262a32;--color-surface-border:#333842;--color-surface-elevated:#21252c;--color-text-primary:#e9ecef;--color-text-secondary:#9aa3ad;--color-text-muted:#757e89;--color-accent-blue:#60a5fa;--color-accent-purple:#a78bfa;--color-accent-purple-soft:#4c1d95;--color-accent-purple-ink:#ede9fe;--color-accent-emerald:#34d399;--color-accent-emerald-deep:#15803d;--color-accent-amber:#fbbf24;--color-accent-rose:#fb7185;--color-accent-cyan:#22d3ee;--color-accent-pink:#f48bb4;--color-accent-pink-strong:#f7a8c4;--color-status-pass:#34d399;--color-status-fail:#f87171;--color-status-pending:#fbbf24;--color-status-fail-ink:#450a0a;--color-tree-repo:#ff7a4d;--color-tree-child:#f0a05c;--color-tree-amber:#ffc95c;--color-accent-deep:#a78bfa;--color-success-ink:#4ade80;--color-success-soft:#34d399;--color-green-verify:#4ade80;--color-accent-orange:#fb923c;--color-accent-amber-ink:#fbbf24;--color-accent-amber-ink-deep:#fcd34d;--color-danger-madrid:#ff6b6b;--color-danger-github:#ff8181;--color-danger-editor-surface:#3b1218;--color-danger-editor-ink:#ffb4bb;--color-doc-child:#ff9b9b;--color-navy-focus:#93c5fd;--color-header-wash:#2b2620;--color-slate-neutral:#9aa3ad;--color-danger-wash:#2a1215;--color-danger-wash-border:#45161c;--color-danger-wash-ink:#ffb4bb;--color-ws-violet:#c084fc;--color-ws-green:#4ade80;--color-ws-blue:#6cb8ff;--color-subagent-tint-1:#2e2c25;--color-subagent-tint-2:#35332a;--color-subagent-tint-3:#3c3a2f;--si-run:#f87171}[data-theme=dark] pre code.hljs{padding:1em;display:block;overflow-x:auto}[data-theme=dark] code.hljs{padding:3px 5px}[data-theme=dark] .hljs{color:#c9d1d9;background:#0d1117}[data-theme=dark] .hljs-doctag,[data-theme=dark] .hljs-keyword,[data-theme=dark] .hljs-meta .hljs-keyword,[data-theme=dark] .hljs-template-tag,[data-theme=dark] .hljs-template-variable,[data-theme=dark] .hljs-type,[data-theme=dark] .hljs-variable.language_{color:#ff7b72}[data-theme=dark] .hljs-title,[data-theme=dark] .hljs-title.class_,[data-theme=dark] .hljs-title.class_.inherited__,[data-theme=dark] .hljs-title.function_{color:#d2a8ff}[data-theme=dark] .hljs-attr,[data-theme=dark] .hljs-attribute,[data-theme=dark] .hljs-literal,[data-theme=dark] .hljs-meta,[data-theme=dark] .hljs-number,[data-theme=dark] .hljs-operator,[data-theme=dark] .hljs-variable,[data-theme=dark] .hljs-selector-attr,[data-theme=dark] .hljs-selector-class,[data-theme=dark] .hljs-selector-id{color:#79c0ff}[data-theme=dark] .hljs-regexp,[data-theme=dark] .hljs-string,[data-theme=dark] .hljs-meta .hljs-string{color:#a5d6ff}[data-theme=dark] .hljs-built_in,[data-theme=dark] .hljs-symbol{color:#ffa657}[data-theme=dark] .hljs-comment,[data-theme=dark] .hljs-code,[data-theme=dark] .hljs-formula{color:#8b949e}[data-theme=dark] .hljs-name,[data-theme=dark] .hljs-quote,[data-theme=dark] .hljs-selector-tag,[data-theme=dark] .hljs-selector-pseudo{color:#7ee787}[data-theme=dark] .hljs-subst{color:#c9d1d9}[data-theme=dark] .hljs-section{color:#1f6feb;font-weight:700}[data-theme=dark] .hljs-bullet{color:#f2cc60}[data-theme=dark] .hljs-emphasis{color:#c9d1d9;font-style:italic}[data-theme=dark] .hljs-strong{color:#c9d1d9;font-weight:700}[data-theme=dark] .hljs-addition{color:#aff5b4;background-color:#033a16}[data-theme=dark] .hljs-deletion{color:#ffdcd7;background-color:#67060c}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:var(--color-surface)}::-webkit-scrollbar-thumb{background:var(--color-surface-border);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--color-text-muted)}.scrollbar-none{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-none::-webkit-scrollbar{display:none}body{background-color:var(--color-surface);color:var(--color-text-primary);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.md-content{overflow-wrap:break-word;word-break:break-word;min-width:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.md-content table{border-collapse:collapse;white-space:normal;background:#8b5cf60a;border:1px solid #8b5cf633;border-radius:.5em;width:100%;margin:.5em 0;display:block;overflow:auto hidden}.md-content table th,.md-content table td{white-space:normal;word-break:normal;overflow-wrap:break-word}.md-content p{margin-top:.5em;margin-bottom:.25em}.md-content ul{margin:.2em 0;padding-left:1.5em;list-style-type:disc}.md-content ol{margin:.2em 0;padding-left:1.5em;list-style-type:decimal}.md-content li{display:list-item}.md-content h1,.md-content h2,.md-content h3{color:var(--color-text-primary);margin:.75em 0 .3em;font-weight:800}.md-content h1{font-size:1.25em}.md-content h2{font-size:1.1em}.md-content h3{font-size:1em}.md-content blockquote{color:var(--color-text-secondary);border-left:3px solid #8b5cf666;margin:.5em 0;padding:.3em .75em}.md-content strong{color:var(--color-text-primary);font-weight:600}.md-content em{color:var(--color-accent-deep)}.md-content hr{border:none;border-top:1px solid var(--color-surface-border);margin:.5em 0}.md-content a{color:var(--color-accent-blue);text-underline-offset:2px;text-decoration:underline}.md-content th{color:var(--color-text-primary);background:#8b5cf61f}.md-content th,.md-content td{text-align:left;border:1px solid #8b5cf626;padding:.35em .6em}.md-content tbody tr:nth-child(2n){background:#8b5cf608}.md-content tbody tr:hover{background:#8b5cf614}.md-content code:not(pre code),.md-content :not(pre)>code{color:var(--color-accent-deep);background:#8b5cf614;border-radius:.3em;padding:.15em .35em;font-family:SF Mono,Fira Code,JetBrains Mono,monospace;font-size:.8em}.md-content pre{background:var(--color-surface-alt);border:1px solid var(--color-surface-border);border-radius:.5em;max-width:100%;margin:.5em 0;padding:.5em;font-size:.8em;overflow-x:auto}.md-content pre code{color:var(--color-text-primary);font-family:SF Mono,Fira Code,JetBrains Mono,monospace}[data-testid=assistant-turn] .md-content>:last-child{margin-bottom:.25em}[data-testid=assistant-turn] .md-content>:first-child{margin-top:.5em}.md-content .mermaid-diagram{justify-content:center;margin:.5em 0;padding:.5em;display:flex;overflow-x:auto}.md-content .mermaid-diagram svg{max-width:100%;height:auto}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{U as e}from"../nodes/2.BTTHruTq.js";export{e as startPanelResize};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"../nodes/2.BTTHruTq.js";export{e as stringify};
|