@deepseek-insight/dsi 0.5.17 → 0.5.19
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/dsi-adr/SKILL.md +121 -0
- package/.agents/skills/dsi-i18n-migrate/SKILL.md +87 -0
- package/.agents/skills/dsi-release/SKILL.md +175 -0
- package/.agents/skills/dsi-spcheck/SKILL.md +188 -0
- package/.agents/skills/dsi-spec/SKILL.md +310 -0
- package/.agents/skills/dsi-spec/references/mermaid-pattern.md +160 -0
- package/.agents/skills/dsi-spec/references/tasks-json-template.md +125 -0
- package/.agents/skills/dsi-task/SKILL.md +287 -0
- package/README.md +6 -23
- package/bin/dsi.mjs +67 -15
- package/bin/lib/mirror-skills.mjs +56 -0
- package/build/client/_app/immutable/assets/0.C4pk9RsQ.css +2 -0
- package/build/client/_app/immutable/assets/2.Da1CnqbG.css +1 -0
- package/build/client/_app/immutable/chunks/7MCZCUsX.js +1 -0
- package/build/client/_app/immutable/chunks/BeeAmuEs.js +2 -0
- package/build/client/_app/immutable/chunks/BgF4MPCH.js +1 -0
- package/build/client/_app/immutable/chunks/CLNDb8QN.js +6 -0
- package/build/client/_app/immutable/chunks/{Bl6W6XsZ.js → Dv2f6AVG.js} +1 -1
- package/build/client/_app/immutable/chunks/h_AAZIXW.js +1 -0
- package/build/client/_app/immutable/entry/{app.DhFsVx9Q.js → app.C8CwtYTr.js} +2 -2
- package/build/client/_app/immutable/entry/start.CCr7WSxA.js +1 -0
- package/build/client/_app/immutable/nodes/{0.DSOF-uUw.js → 0.VWq3h0rH.js} +1 -1
- package/build/client/_app/immutable/nodes/{1.wYU7SDRw.js → 1.Dnl1P2aB.js} +1 -1
- package/build/client/_app/immutable/nodes/2.0fqLf_Nw.js +170 -0
- 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/app-config.svelte.js-rN4N5yAI.js +305 -0
- package/build/server/chunks/chunks/{config.js-D2vQdial.js → config.js-iG_1bK3r.js} +16 -2
- package/build/server/chunks/chunks/{db.js-B7zd2qLf.js → db.js-DbbYS9o8.js} +2 -2
- package/build/server/chunks/chunks/{db2.js-CCmqoCC8.js → db2.js-BQWa7bEG.js} +52 -41
- package/build/server/chunks/chunks/{dsh-connection.js-qRBqNOg4.js → dsh-connection.js-CpcCtA42.js} +3 -3
- package/build/server/chunks/chunks/{git-probe.js-Dw7WYQIb.js → git-probe.js-CvkToKO4.js} +2 -2
- package/build/server/chunks/chunks/{insight-config.js-BcJiCZlZ.js → insight-config.js-Dw_Qi0fO.js} +60 -11
- package/build/server/chunks/chunks/{internal.js-Y8BDUVWO.js → internal.js-BDS_h7zE.js} +3 -3
- package/build/server/chunks/chunks/{settings-document.js-BIwLIxnE.js → settings-document.js-BKnRkLVq.js} +2 -2
- package/build/server/chunks/chunks/{state.js-C1kUoUk4.js → state.js-eZmA7eF7.js} +3 -3
- package/build/server/chunks/chunks/{watcher.js-CUAJN9lS.js → watcher.js-C97Xyorx.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/a2a/_id_/{_server.ts.js-DZyjEufw.js → _server.ts.js-Cqh1iqgu.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/a2a/{_server.ts.js-sqxh02Ab.js → _server.ts.js-DNKD4rZu.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/a2a/register/{_server.ts.js-CUnQYezc.js → _server.ts.js-CJ-FwkrZ.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/config/{_server.ts.js-BZhBgOdD.js → _server.ts.js-CMM4kYVx.js} +6 -5
- package/build/server/chunks/entries/endpoints/api/dsh/directory/{_server.ts.js-Dm7aSfmb.js → _server.ts.js-epVplzwB.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/pick-directory/{_server.ts.js-CLZoIW4v.js → _server.ts.js-bXHb97gT.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/presets/{_server.ts.js-DBklPI3F.js → _server.ts.js-BNOHhtzy.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/attachment/{_server.ts.js-Cuq-JEHL.js → _server.ts.js-BBi6jeVj.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/cancel/{_server.ts.js-C2M3e5l-.js → _server.ts.js-N0nKPuqL.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/catalog/{_server.ts.js-J64QhcMH.js → _server.ts.js-VGFCPAbs.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/command/{_server.ts.js-BSAQMYfS.js → _server.ts.js-na_sUb0Z.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/events/{_server.ts.js-BF9MvjDa.js → _server.ts.js-CeNf028P.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/fork/{_server.ts.js-CrJB2-mv.js → _server.ts.js-DfqO-GO4.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/goal/{_server.ts.js-BzvIAbjd.js → _server.ts.js-Dj9GYNl7.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/history/{_server.ts.js-CpID_rFC.js → _server.ts.js-DqShsRl9.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/models/{_server.ts.js-B_uu8lbl.js → _server.ts.js-BQSBUf70.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/path/{_server.ts.js-DjvyuSLb.js → _server.ts.js-CeCKDyKB.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/permission/{_server.ts.js-DX8nvoLd.js → _server.ts.js-CadTCNUJ.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/prompt/{_server.ts.js-BSFv1R4Z.js → _server.ts.js-BXzgi8xX.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/rename/{_server.ts.js-I0dJrnyq.js → _server.ts.js-BfD5FXiL.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/respond/{_server.ts.js-w_eF8BVI.js → _server.ts.js-CiDPC9TY.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/select-model/{_server.ts.js-Bvw_1JCx.js → _server.ts.js-DGcZgN96.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/sessions/{_server.ts.js-DHsKo688.js → _server.ts.js-DnU1CCOw.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-file/{_server.ts.js-BTIrnyBK.js → _server.ts.js-BZ0UV1n2.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-file-bytes/{_server.ts.js-Deb3yET3.js → _server.ts.js-lxLpuPFL.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-tree/{_server.ts.js-DYifOFKl.js → _server.ts.js-Cw3vl704.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/{_server.ts.js-DW12qsWc.js → _server.ts.js-KKnR2UO4.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/delete/{_server.ts.js-BeTfsMv4.js → _server.ts.js-I1eSZn60.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/rename/{_server.ts.js-BOvj8cc1.js → _server.ts.js-B0zqAKnV.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/prompts/_id_/{_server.ts.js-CcewTyD0.js → _server.ts.js-C-QN0enK.js} +10 -8
- package/build/server/chunks/entries/endpoints/api/prompts/{_server.ts.js-CkFYi6-s.js → _server.ts.js-CwTGUPIp.js} +16 -8
- package/build/server/chunks/entries/endpoints/api/prompts/use/_server.ts.js-Bvotxm37.js +45 -0
- package/build/server/chunks/entries/endpoints/api/settings/{_server.ts.js-xkyh8Bsn.js → _server.ts.js-CRRLXk0y.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/workspace/file-write/{_server.ts.js-C8h4skba.js → _server.ts.js-DY_NDlYl.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/workspace/git-events/{_server.ts.js-WGYYK-PJ.js → _server.ts.js-DHEaymrG.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/workspace/git-file-head/{_server.ts.js-CG64CyF8.js → _server.ts.js-AQgNkfCV.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/workspace/git-map/{_server.ts.js-DLf26VXY.js → _server.ts.js-C9vxPbB3.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/workspace/git-status/{_server.ts.js-Db2kgLys.js → _server.ts.js-BlMRR11v.js} +6 -6
- package/build/server/chunks/entries/{hooks.server.js-B7FsvqtT.js → hooks.server.js-B_E1wCwG.js} +3 -3
- package/build/server/chunks/entries/pages/{_error.svelte.js-BRTO_bKK.js → _error.svelte.js-DIRRk8AK.js} +4 -4
- package/build/server/chunks/entries/pages/{_page.server.ts.js-DFo2_s9d.js → _page.server.ts.js-ze2dUhXW.js} +2 -2
- package/build/server/chunks/entries/pages/{_page.svelte.js-T6ftg3_-.js → _page.svelte.js-CYT_NWww.js} +728 -492
- package/build/server/chunks/{handler-Xeib4Xb9.js → handler-jvQdYpdY.js} +3 -3
- package/build/server/chunks/{index.js-DDqgzbFD.js → index.js-BGLJR092.js} +2 -2
- package/build/server/chunks/{manifest.js-CmazPK88.js → manifest.js-CIb6Wm5j.js} +43 -43
- package/build/server/chunks/nodes/{0.js-DDgHSLf5.js → 0.js-CQ3k21rg.js} +3 -3
- package/build/server/chunks/nodes/1.js-NI6SZ6un.js +9 -0
- package/build/server/chunks/nodes/{2.js-BIByS7ug.js → 2.js-BG_HkTrm.js} +9 -9
- package/package.json +2 -1
- package/template/.dsi/prompts.sqlite +0 -0
- package/template/.dsi/prompts.sqlite-shm +0 -0
- package/template/.dsi/prompts.sqlite-wal +0 -0
- package/template/.dsi/settings.yaml +1 -1
- package/build/client/_app/immutable/assets/0.BQjO3ESU.css +0 -2
- package/build/client/_app/immutable/assets/2.DHY7FpOZ.css +0 -1
- package/build/client/_app/immutable/chunks/BuVjHIij.js +0 -1
- package/build/client/_app/immutable/chunks/C88qhAPJ.js +0 -1
- package/build/client/_app/immutable/chunks/Ct7xT-0E.js +0 -1
- package/build/client/_app/immutable/chunks/DFtKrqgo.js +0 -1
- package/build/client/_app/immutable/chunks/DQgaJgp5.js +0 -2
- package/build/client/_app/immutable/entry/start.CyefizPA.js +0 -1
- package/build/client/_app/immutable/nodes/2.Bu226K9e.js +0 -174
- package/build/server/chunks/chunks/app-config.svelte.js-BkhuJ9bF.js +0 -52
- package/build/server/chunks/entries/endpoints/api/prompts/use/_server.ts.js-yxG3ypD4.js +0 -55
- package/build/server/chunks/nodes/1.js-DleiYihI.js +0 -9
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "dsi-task"
|
|
3
|
+
description: "Execute implementation tasks from a Karpathy context file and tasks document. Applies Visible Checklist Pattern, Playwright regression gates, and sub-agent comp"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Task Executor
|
|
7
|
+
|
|
8
|
+
Execute implementation tasks defined in a Karpathy context + tasks document.
|
|
9
|
+
|
|
10
|
+
## SYSTEM PROTOCOL: STRUCTURED IMPLEMENTATION & LAYERING
|
|
11
|
+
|
|
12
|
+
You must treat code generation as a spatial and structural architecture task, not just functional text completion. Your code layout must mirror the logical boundaries defined in the system design/sequence diagrams:
|
|
13
|
+
|
|
14
|
+
### 1. DIRECTORY SANCTITY & ENCAPSULATION
|
|
15
|
+
- Every domain or feature subset must reside within its own completely isolated directory.
|
|
16
|
+
- Cross-module code bleeding is strictly prohibited. All module-specific state and logic must remain local to that module's folder.
|
|
17
|
+
- Before creating any file, verify its target directory exists and aligns with the Module Map from the PRD.
|
|
18
|
+
|
|
19
|
+
### 2. DECOUPLED COMMUNICATION MECHANISM
|
|
20
|
+
- You are forbidden from hardcoding direct dependencies or side-effects between feature modules.
|
|
21
|
+
- Execution orchestration must follow the project's communication pattern (event bus, pub/sub, middleware chain, dependency injection, message passing, etc.). Modules requiring observation or intervention must use the defined communication layer, not direct imports.
|
|
22
|
+
- Document how each module connects to the system: what it receives, what it produces, and through which channel.
|
|
23
|
+
|
|
24
|
+
### 3. ARCHITECTURAL DRY PRINCIPLE
|
|
25
|
+
- Before implementing any utility logic (e.g., file checks, payload validation, format verifiers), check the global Shared Layer.
|
|
26
|
+
- You must import shared utilities from the central shared directory rather than re-creating localized or redundant helper functions inside individual modules.
|
|
27
|
+
|
|
28
|
+
### Enforcement Rules
|
|
29
|
+
- Before writing code for any wave, verify the PRD's Module Map against the physical filesystem (`find | sort`)
|
|
30
|
+
- Every new file must be created in its designated module directory — never in the root or another module's folder
|
|
31
|
+
- Shared utilities must be placed in the designated shared directory and imported via relative paths — never duplicated
|
|
32
|
+
- After each wave, run a "cross-module bleed check": verify no module imports from another module's directory
|
|
33
|
+
- Module wiring (how modules connect to each other) must happen at the defined integration point — not scattered across module internals
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## When to Use
|
|
38
|
+
|
|
39
|
+
- User says `/execute-tasks {project-path}` — execute with project root (auto-discovers docs)
|
|
40
|
+
- User says "execute the WebSocket tasks" or "implement the tasks from the Karpathy-context"
|
|
41
|
+
- User provides a `{*} karpathy-context.md` file and asks to start implementation
|
|
42
|
+
|
|
43
|
+
### Step 0: No Params — Usage Guide
|
|
44
|
+
|
|
45
|
+
When the user sends `/execute-tasks` with no arguments:
|
|
46
|
+
|
|
47
|
+
1. Ask for the two required paths:
|
|
48
|
+
- **Karpathy context** — path to the karpathy-context file (auto-discovered from project path)
|
|
49
|
+
- **Tasks document** — path to the tasks document (local file under project dev/)
|
|
50
|
+
2. Reply with a usage guide — NOT execution
|
|
51
|
+
|
|
52
|
+
**Response format:**
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
📋 **Task Executor** — No paths specified. I need two things:
|
|
56
|
+
|
|
57
|
+
1. **Project path** — the codebase root (where dev/specs/ lives)
|
|
58
|
+
Example: `~/openclaw-insight`
|
|
59
|
+
|
|
60
|
+
2. **Tasks document** — the implementation tasks (auto-resolved from project path)
|
|
61
|
+
Example: `openclaw-insight/dev/specs/WebSocket Real-Time/Tasks.md`
|
|
62
|
+
|
|
63
|
+
Usage: `/execute-tasks {project-path}`
|
|
64
|
+
|
|
65
|
+
Or just paste the project path and I'll find the latest tasks document.
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Rules:**
|
|
69
|
+
- If project path is provided, auto-discover feature folder: `{project-path}/dev/specs/*/`
|
|
70
|
+
- If multiple feature folders exist, ask which one to execute
|
|
71
|
+
- If a karpathy-context file exists in `{project-path}/dev/specs/{feature}/`, load it automatically
|
|
72
|
+
- If no Karpathy context found, ask if the user wants to proceed without it
|
|
73
|
+
- If a path doesn't exist, say so and ask for the correct one
|
|
74
|
+
- Do NOT proceed to Step 1 (Load Context) until paths are confirmed
|
|
75
|
+
|
|
76
|
+
## Core Principle: Context Loading, Not Memorization
|
|
77
|
+
|
|
78
|
+
This skill is intentionally SHORT. It references external documents instead of copying rules inline. This prevents attention degradation — the model loads only what it needs, when it needs it.
|
|
79
|
+
<!-- RCA: AI-Research/YT-Research/2026-06-22 - Why Long Instructions Make AI Dumber - Attention Degradation Science.md -->
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Step 1: Load Context — MANDATORY
|
|
84
|
+
|
|
85
|
+
Before any execution, load exactly these files:
|
|
86
|
+
|
|
87
|
+
1. **Karpathy context** — `{project-path}/dev/specs/{feature}/karpathy-context.md` (auto-discovered)
|
|
88
|
+
2. **Tasks document** — `{project-path}/dev/specs/{feature}/Tasks.md` (auto-discovered)
|
|
89
|
+
3. **Visible Checklist Pattern** — `ai-research/references/visible-checklist-pattern.md` (loaded on demand)
|
|
90
|
+
4. **Sub-Agent Completion Rules** — `TOOLS.md` lines 85-115
|
|
91
|
+
|
|
92
|
+
Read these files at the start. Do NOT carry them from previous conversation context — reload fresh.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Step 1.5: Date Resolution ⛔ MANDATORY
|
|
97
|
+
|
|
98
|
+
Before constructing any date-prefixed filenames during execution, resolve today's date via `date +%Y-%m-%d`. Store as `TODAY`. Do not carry the date from the feature-spec session — it may be a different day.
|
|
99
|
+
<!-- RCA: AI-Research/Troubleshooting/2026-06-18 - Wrong Date Prefix in yt-research Filename - RCA.md -->
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Step 2: Declare Execution Checklist — MANDATORY
|
|
104
|
+
|
|
105
|
+
Output a checklist of ALL tasks for the current wave, INCLUDING the behavioral commitments. The user MUST see every rule I'm committing to follow.
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
📋 Execution: {project-name} — {wave name}
|
|
109
|
+
|
|
110
|
+
[ ] 1.5 ⛔ Resolve today's date via `date +%Y-%m-%d` (store as TODAY)
|
|
111
|
+
[ ] 2.1 {task 1 name}
|
|
112
|
+
[ ] 2.2 {task 2 name}
|
|
113
|
+
[ ] 2.3 {task 3 name}
|
|
114
|
+
|
|
115
|
+
⛔ Behavioral Commitments (user can verify):
|
|
116
|
+
[ ] I will NOT execute multiple waves without your confirmation
|
|
117
|
+
[ ] I will NOT skip Playwright regression gate
|
|
118
|
+
[ ] I will NOT rely on completion events as ground truth
|
|
119
|
+
[ ] I will NOT post NO_REPLY after spawning sub-agents
|
|
120
|
+
[ ] I will NOT self-certify completion without running verify commands
|
|
121
|
+
[ ] I will NOT reload this skill + all referenced docs simultaneously
|
|
122
|
+
[ ] I will NOT bleed code across module boundaries
|
|
123
|
+
[ ] I will NOT duplicate shared utilities in module directories
|
|
124
|
+
[ ] I will run unit tests after EACH code-writing task (not batched at end)
|
|
125
|
+
[ ] I will re-output this checklist after each task completes
|
|
126
|
+
|
|
127
|
+
⛔ Sub-Agent Safety (conditional — ⊘ skip if no sub-agents spawned):
|
|
128
|
+
[⊘] Check ALL children via subagents list — not just one
|
|
129
|
+
[⊘] Disk files = ground truth, events = convenience
|
|
130
|
+
[⊘] Post ACK to user before other work
|
|
131
|
+
|
|
132
|
+
⛔ Completion Gate:
|
|
133
|
+
[ ] All task files exist on disk (verified via find)
|
|
134
|
+
[ ] Directory structure matches PRD Module Map (verified via find | sort)
|
|
135
|
+
[ ] No cross-module import violations (verified via grep)
|
|
136
|
+
[ ] Unit tests pass (npx node --test or npm test) — MANDATORY, not optional
|
|
137
|
+
[ ] Type-check zero new errors: if `npm run check` exits non-zero from pre-existing errors, grep output for this wave's exact new file paths — 0 hits satisfies the gate ONLY when the error count also matches the wave-start check counts. When the wave adds or changes a field on a shared type (interface/type alias), pre-existing object-literal fixtures typed as that interface break in files outside the wave list: the wave-file grep returns 0 hits while the count rises, so adjudicate every count delta by listing diagnostics per file (`--output machine`); errors naming the changed type are this wave's lockstep obligation — extend the fixture in-wave; prove the rest pre-existing via `git log --oneline -- <file>` (last-touch commit predates the wave) plus empty `git diff --stat HEAD -- <file>`. The same git-log proof settles a hit in a different file sharing a name substring; fall back to `git stash` → re-run check → confirm same hit on clean baseline → `git stash pop` only when history is ambiguous. Never judge by raw error-count deltas against a `git stash -u` baseline: `-u` also stashes new untracked test files, and the fix itself may resolve pre-existing errors — current < baseline is normal and proves nothing. A stash baseline only adjudicates files tracked in both states: plain `git stash` leaves this wave's untracked new files in the worktree, so they compile against the reverted tracked code and the baseline sprouts phantom errors in this wave's own files (e.g. missing-export errors the stash itself created) — classify those baseline hits as stash artifacts and settle them by grepping the intact worktree instead
|
|
138
|
+
<!-- RCA: 2026-08-16 openclaw-insight ControlRail Wave 1 — adding required `deleted_at` to the shared Feature interface broke the untouched wave-prompt.test.ts fixture; wave-file grep said 0 hits while 26e→27e. Delta adjudication via machine diagnostics fixed the lockstep fixture in-wave; git-log + empty-diff proved the sibling sessionKey/TaskData errors pre-existing. -->
|
|
139
|
+
[ ] Playwright regression: zero failures vs baseline ⊘ (skip if no Playwright)
|
|
140
|
+
[ ] User acknowledged completion
|
|
141
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Check off each item as it completes: `[✅]` done, `[🔄]` current, `[ ]` remaining.
|
|
145
|
+
|
|
146
|
+
### Check-Off Rules
|
|
147
|
+
|
|
148
|
+
- **After each task completes within a wave**, re-output the full wave checklist with updated statuses
|
|
149
|
+
- **At wave completion**, output the final checklist: ALL `[✅]`, any `[❌]` for failures, any `[⊘]` for skipped conditionals
|
|
150
|
+
- **Do NOT deliver without showing the final checklist**
|
|
151
|
+
<!-- RCA: AI-Research/LLMs Skip Mandatory Steps/001. LLMs Skip Mandatory Steps/002.The Visible checklist Pattern/2026-06-11 - The Visible Checklist Pattern - AI Research v1 - report.md -->
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Step 3: Execute Tasks Sequentially
|
|
156
|
+
|
|
157
|
+
- Execute one task at a time within the current wave
|
|
158
|
+
- Do NOT skip tasks or reorder
|
|
159
|
+
- After each task: verify deliverables exist on disk (`ls`, `find`)
|
|
160
|
+
- **After each code-writing task: run unit tests for the affected module** (`npx node --test dist/{module}/`). Do NOT proceed to the next task if tests fail.
|
|
161
|
+
- If a task spawns a sub-agent: follow Step 4 (Sub-Agent Safety)
|
|
162
|
+
|
|
163
|
+
### Step 3.5: Acceptance Scenarios Are the Contract ⛔
|
|
164
|
+
|
|
165
|
+
When verification disagrees with user-stated acceptance scenarios:
|
|
166
|
+
|
|
167
|
+
1. Treat the scenarios as the contract. Fix the implementation to satisfy them — never rewrite, loop, or weaken the test to match observed behavior.
|
|
168
|
+
2. Follow the promised verification order: fix → headed run of the user's scenarios verbatim (one user action per assertion) → only then unit tests.
|
|
169
|
+
3. When a simulated-DOM unit test (happy-dom/jsdom) fails while the headed real-browser run passes, trust the headed run and fix the harness — poll microtask-driven state with `vi.waitFor` instead of fixed sleeps.
|
|
170
|
+
4. This binds user scenarios only — not edge-case assertions you authored from an assumption. When your own new test fails, verify the assumption against documented platform semantics; a false assumption means correct the assertion, not working code (e.g. Node `basename('dev/specs/')` → `'specs'` — trailing slash stripped, so a "basename empty → fallback" branch never fires for it).
|
|
171
|
+
<!-- RCA: 2026-08-16 openclaw-insight wave-prompt — fallback test expected the feature id for a trailing-slash spec path; basename semantics proved the assertion wrong; test corrected, implementation untouched, 17/17 green -->
|
|
172
|
+
|
|
173
|
+
Criterion: every user scenario is asserted verbatim and passes, with no assertion softened to make a run green.
|
|
174
|
+
<!-- RCA: 2026-08-13 openclaw-insight ghost-Backspace — headed test was softened (BS retry loops) to match buggy native-selection deletion; user rejected; keydown-intercept fix + verbatim-scenario headed run passed -->
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
### Step 3.6: Expected-Fail Sanity Proofs ⛔
|
|
180
|
+
|
|
181
|
+
When a wave plans "old bug-spec must FAIL as proof of fix":
|
|
182
|
+
|
|
183
|
+
1. Run it; if it unexpectedly PASSES, treat that as evidence the spec discriminates nothing — inspect what its assertions measure before drawing any conclusion.
|
|
184
|
+
2. Symptom assertions anchored to the wrong reference (viewport/window instead of the fixed element's own container) pass both pre- and post-fix.
|
|
185
|
+
3. Prove the fix with a reference-relative probe: assert the fixed element's rect against its wrapper rect within ±1px, plus a pixel scan of the artifact region; capture the evidence, then delete the probe spec.
|
|
186
|
+
4. Scrollable wrapper: compare bottom/right edges against `clientHeight`/`clientWidth` — a rendered scrollbar occupies the bounding-rect edge, so a naive rect comparison reports a false gap (scrollbar px = rect height − clientHeight).
|
|
187
|
+
|
|
188
|
+
Criterion: fix proven by reference-relative geometry (e.g. gap 301.3px → 0.01px), independent of the old spec's pass/fail; wrapper gaps measured client-relative (scrollbar not counted as gap).
|
|
189
|
+
<!-- RCA: 2026-08-16 openclaw-insight zoom-artifact Wave 1 — old visual spec passed pre- AND post-fix because it asserted last-panel edge vs viewport; wrapper-relative probe proved the wrapper fix. Wave 2 — wrapperRect.bottom − childRect.bottom reported a false 15px gap: the h-scrollbar occupied the rect bottom while .columns exactly filled clientHeight -->
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### Step 3.7: Deletion-Only Tasks — Zero-Reference Verification
|
|
195
|
+
|
|
196
|
+
When a task deletes a file and its paired verification is "grep returns zero references":
|
|
197
|
+
|
|
198
|
+
1. Confirm the deletion at three levels: absent from worktree (`ls`), untracked (`git ls-files <path>` empty), recorded in history (`git log --oneline --diff-filter=D -- <path>`).
|
|
199
|
+
2. If the deletion already exists in a prior commit, verify and report — do not redo it.
|
|
200
|
+
3. Run the prescribed grep over the full worktree, then classify every hit:
|
|
201
|
+
- code/config references (src, tests, configs, scripts) — the only hits that fail the gate
|
|
202
|
+
- spec-folder and ADR docs recording the retirement decision — intentional audit trail, keep
|
|
203
|
+
- gitignored runtime logs — not repo content
|
|
204
|
+
4. Keep the audit-trail doc hits: the gate is zero code references, not a literal zero; scrubbing the spec's own record falsifies history.
|
|
205
|
+
5. Before concluding, confirm similarly-named sibling files are unrelated, not misnamed leftovers.
|
|
206
|
+
|
|
207
|
+
Criterion: filtered grep (docs + ignored dirs excluded) returns zero hits, with the hit classification stated in the task summary.
|
|
208
|
+
<!-- RCA: 2026-08-16 openclaw-insight zoom-artifact Task 2.2-T — grep for deleted zz-zoom-artifact-headed.spec.ts returned 16 hits: ADR retirement table + spec-folder audit trail + gitignored logs/; zero-code-reference criterion satisfied without touching the retirement record, and zz-backspace-headed.spec.ts confirmed unrelated -->
|
|
209
|
+
|
|
210
|
+
### Step 3.8: New E2E Specs — Assert the Component's Real DOM Contract
|
|
211
|
+
|
|
212
|
+
When a wave adds a Playwright spec against existing UI:
|
|
213
|
+
|
|
214
|
+
1. Read the target component source BEFORE writing selectors. Svelte classnames are hash-suffixed or absent; icon-only badges carry status only in `aria-label`. Select via `role`/`aria-label`/testid found in the source, never guessed classes.
|
|
215
|
+
2. On a red run, read `test-results/<spec>/error-context.md` FIRST — its page snapshot shows the actual rendered tree and reveals state such as a collapsed accordion hiding the badges you assert on; expand each nesting level (feature card, then wave toggle) before asserting inside it.
|
|
216
|
+
3. When a setup step fails on pointer interception and its UI is already covered by a sibling spec, drive the mocked API directly (`page.evaluate(() => fetch(...))`) — the setup is a means, not the subject.
|
|
217
|
+
|
|
218
|
+
Criterion: every selector is verified present in component source, and red runs are diagnosed from the error-context snapshot before the assertion is touched.
|
|
219
|
+
<!-- RCA: 2026-08-16 openclaw-insight wave-dispatch e2e — three red runs, all test-side: guessed `.task-completed` classes (StatusBadge is icon-only; real contract `[role="status"][aria-label="Completed"]`), register-popover click intercepted by panels-viewport (moved to mocked API; popover covered by orchestration-register.spec.ts), collapsed wave accordion hid task badges (added wave-toggle click). No production change, no softened assertions; 3 consecutive green runs after. -->
|
|
220
|
+
|
|
221
|
+
### Step 3.9: Tagged Playwright Invocations — Prove Non-Empty Selection
|
|
222
|
+
|
|
223
|
+
When a gate or spec pins a tag-filtered run (`--grep @tag`):
|
|
224
|
+
|
|
225
|
+
1. Read the active config for a static `grep:` first — Playwright ANDs config grep with CLI `--grep`, and a static entry cannot be overridden from the CLI. An exclusion grep in config plus a tag grep on CLI silently selects ZERO tests: exit 0, green gate, nothing ran.
|
|
226
|
+
2. Before trusting a tagged green run, read the reporter's collected/passed count and confirm it matches the expected suite size. Zero collected = false green.
|
|
227
|
+
3. To diagnose emptiness, race an untagged control file against the tagged file under the same invocation: control collects while the tagged file never collects under `--grep`, `--grep-invert`, or path+grep ⇒ the config grep is the blocker.
|
|
228
|
+
4. Fix additively: a sibling config that spreads the base config and clears ONLY `grep` (default-suite composition stays byte-identical), then invoke with `--config`. Record the working invocation in the completion notes as a documented deviation from the spec-pinned form.
|
|
229
|
+
5. When the fix un-buries suites that have never run, classify every failure stale vs regression before judging the gate: `git log -1 -- <file>` predating the subject plus assertions naming removed UI ⇒ stale; document for owner adjudication and do not rewrite or delete foreign suites in-wave.
|
|
230
|
+
|
|
231
|
+
Criterion: the tagged invocation reports the expected collected count, and every failure in a newly reachable suite is classified with git-log evidence.
|
|
232
|
+
<!-- RCA: 2026-08-17 openclaw-insight Control Room Recovery W5 — the spec-pinned `--grep @orchestration` had selected zero tests ever since the base config gained its exclusion grep; a sibling config (spread base, clear only grep) un-buried the recovery spec (5/5 green) plus a 2026-08-08 suite asserting the removed pre-redesign page — stale, documented, not rewritten. -->
|
|
233
|
+
|
|
234
|
+
## Step 4: Sub-Agent Safety — When Spawning Children
|
|
235
|
+
|
|
236
|
+
Only fires when a task requires spawning a sub-agent. If no sub-agents are spawned, mark `[⊘]` in the checklist and skip this step.
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
📋 Sub-Agent Safety
|
|
240
|
+
|
|
241
|
+
[ ] 4.1 Spawn sub-agent with explicit model + taskName
|
|
242
|
+
[ ] 4.2 Continue independent work on main session
|
|
243
|
+
[ ] 4.3 On completion: verify output file on disk (find | wc -l)
|
|
244
|
+
[ ] 4.4 Post ACK to user before starting next task
|
|
245
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Step 4.5: 2-Minute Ledger Gate ⚠️ MANDATORY
|
|
249
|
+
|
|
250
|
+
If 2 minutes pass after spawning a sub-agent without any completion event or user message, fire `subagents(action="list")` proactively — do not silently wait.
|
|
251
|
+
<!-- RCA: AI-Research/Troubleshooting/Agentic Pipeline/2026-06-22 - Missing Sub-Agent Completion Event for Gemini but Not Perplexity - RCA 1.md -->
|
|
252
|
+
|
|
253
|
+
**The rule:**
|
|
254
|
+
1. After spawning, note the spawn timestamp
|
|
255
|
+
2. If 2 minutes pass without a completion event: fire `subagents(action="list")` immediately
|
|
256
|
+
3. Check ALL expected children — not just one
|
|
257
|
+
4. For any child showing "done": verify output file on disk (find | wc -l)
|
|
258
|
+
5. For any child still "running" past 5 minutes: flag as potentially stuck
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Step 5: Wave Completion Gate — MANDATORY
|
|
263
|
+
|
|
264
|
+
Before declaring a wave complete, output the final checklist with ALL items checked.
|
|
265
|
+
|
|
266
|
+
If any `[ ]` remains: fix it, do NOT proceed to next wave.
|
|
267
|
+
|
|
268
|
+
If Playwright tests are part of the wave: run `npx playwright test --reporter=list` and show results.
|
|
269
|
+
<!-- RCA: AI-Research/Troubleshooting/2026-06-11 - ADDITIONAL_PAGES Three Generations Same Bug - RCA.md -->
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Step 6: Save Completion Artifacts
|
|
274
|
+
|
|
275
|
+
Save completion notes to the same project docs folder. Use the resolved `TODAY` date from Step 1.5.
|
|
276
|
+
|
|
277
|
+
Path: `{project-path}/dev/specs/{feature}/{TODAY} - {Wave Name} - Completion Notes.md`
|
|
278
|
+
|
|
279
|
+
Include: tasks completed, files modified, test results, blockers encountered.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Step 7: Ask Before Next Wave
|
|
284
|
+
|
|
285
|
+
After completing a wave, ask the user before proceeding to the next wave.
|
|
286
|
+
|
|
287
|
+
"✅ {Wave N} complete. Ready to start {Wave N+1}? Tasks: {brief list}"
|
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# DeepSeek Insight
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
- `DSH web` shows you a conversation.
|
|
4
|
+
- [DeepSeek Insight](https://gitlab.com/wharsojo.dev/deepseek-insight) (DSI) shows you the **whole floor**
|
|
5
|
+
|
|
6
|
+
> `DSI` as a `Control room` built on your harness's own records: every session, past and running, side by side on one page; lineage tree of sub-agents pinned under the parent that spawned them; every tool call with its pass/fail receipt; history you can search; prompts worth keeping filed for reuse. It speaks the same wire as the `DSH` you already run — nothing new to configure.
|
|
4
7
|
|
|
5
8
|
## Run
|
|
6
9
|
|
|
@@ -12,10 +15,11 @@ The whole DX loop lives in the home page: pick a preset + workspace, press **+ N
|
|
|
12
15
|
Everything on the page is **real harness activity**, not a mock — every chip, diff, and reply is read straight from the running harness.
|
|
13
16
|
|
|
14
17
|
- **Conversation, with receipts.** Each tool the agent runs shows as a chip that passes or fails, with its duration and its receipt; open it to see exactly what ran. Reasoning folds away until you want it, and long sessions load older turns as you scroll up.
|
|
15
|
-
- **One-click approvals.** When the agent asks permission — run this command, edit that file — an approval card appears in the flow; answer it right there, no tab-switching.
|
|
16
18
|
- **The workspace explorer, with git diff.** A side panel shows the files your agent is touching. Changed files are flagged and pulsing while the agent works; click one and you get a **real git diff** — additions in green, removals in red — rendered from the file's live buffer, so it updates as the agent edits and refreshes if you (or anything else) change the file underneath.
|
|
17
19
|
- **Presets and workspaces.** Start each chat with the right agent for the job — a coder, a researcher, a generalist — pointed at the right folder.
|
|
18
20
|
- **Many conversations, one page.** Conversations live in panels you can open side by side; compare two runs, or keep a scratch chat next to the main one.
|
|
21
|
+
- **A family tree under every chat.** When your agent spawns sub-agents, they appear as their own panels **below the parent that made them** — a ghost-tinted panel that stays put on refresh, so you always know who was working for whom. And when one conversation is worth a second try, **fork it**: one click clones the loaded context into a fresh session that starts exactly where the original stood — same history, new task.
|
|
22
|
+
- **A prompt library that files itself.** Save any bubble into the library and give it short filing words (tags) at save time; filter the prompt manager by tag chips or `+tag` words in the search box, and narrow the suggestion strip with its own tag chips — filters survive a reload. Tune the offered tags in `~/.dsi/settings.yaml` under `prompts.tags`.
|
|
19
23
|
- **Your language.** The interface speaks English, Chinese, and Indonesian.
|
|
20
24
|
|
|
21
25
|
### Run from npm
|
|
@@ -39,27 +43,6 @@ npx @deepseek-insight/dsi@latest dsh --sync
|
|
|
39
43
|
|
|
40
44
|
When it is up, your browser opens the page by itself (default `http://127.0.0.1:5174`). Run it again later and DSI even cleans up after a lost previous run: `dsi dsh --sync-kills`.
|
|
41
45
|
|
|
42
|
-
### Run from source
|
|
43
|
-
|
|
44
|
-
```sh
|
|
45
|
-
git clone git@gitlab.com:wharsojo.dev/deepseek-insight.git
|
|
46
|
-
cd deepseek-insight
|
|
47
|
-
pnpm install
|
|
48
|
-
pnpm run build
|
|
49
|
-
pnpm dsi dsh --sync
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Hacking on DSI itself? `pnpm dsi dsh --sync --dev` serves the Vite dev server (hot reload) instead of the build, and the usual gates apply:
|
|
53
|
-
|
|
54
|
-
```sh
|
|
55
|
-
pnpm check # svelte-check, 0 errors
|
|
56
|
-
pnpm test # unit tests (the live wire spike skips cleanly without DSH_LIVE)
|
|
57
|
-
npx playwright test # e2e on a stubbed DSH wire — no harness needed
|
|
58
|
-
DSH_LIVE=1 pnpm run test:live # only with `dsh web` running on :3080
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
The deeper story — architecture decisions (ADRs), wire-protocol guides, and KB notes — lives in [`dev/`](dev).
|
|
62
|
-
|
|
63
46
|
## License
|
|
64
47
|
|
|
65
48
|
[Apache-2.0](LICENSE) — Copyright © 2026 Widi Harsojo
|
package/bin/dsi.mjs
CHANGED
|
@@ -22,6 +22,8 @@ import { fileURLToPath } from 'node:url';
|
|
|
22
22
|
|
|
23
23
|
import { parse, stringify } from 'yaml';
|
|
24
24
|
|
|
25
|
+
import { mirrorSkills } from './lib/mirror-skills.mjs';
|
|
26
|
+
|
|
25
27
|
// Layman-facing help: wrapped near 76 columns, continuation lines indented,
|
|
26
28
|
// the recommended one-liner first. --zai is optional on purpose — no GLM
|
|
27
29
|
// account, no problem, the flag can simply be dropped.
|
|
@@ -33,38 +35,41 @@ const USAGE = [
|
|
|
33
35
|
' npx @deepseek-insight/dsi@latest dsh --sync --zai',
|
|
34
36
|
'',
|
|
35
37
|
' One command, one window: it starts the DSH host AND the DSI page',
|
|
36
|
-
' together in the foreground — one Ctrl-C stops both.
|
|
37
|
-
'
|
|
38
|
+
' together in the foreground — one Ctrl-C stops both. Every flag, once —',
|
|
39
|
+
' the same flag means the same thing on any command that accepts it:',
|
|
38
40
|
'',
|
|
39
41
|
' --sync sync the one-time launch token into ~/.dsi/settings.yaml,',
|
|
40
42
|
' then serve host + page as one pair',
|
|
41
43
|
' --zai bootstrap the GLM (Z.AI) provider into ~/.dsh/settings.yaml',
|
|
42
|
-
' before
|
|
44
|
+
' before anything boots. No GLM account? Skip it — drop this',
|
|
43
45
|
' flag and keep whatever provider you already configured:',
|
|
44
46
|
'',
|
|
45
47
|
' npx @deepseek-insight/dsi@latest dsh --sync',
|
|
46
48
|
'',
|
|
49
|
+
' --token <token>',
|
|
50
|
+
' store the dsh launch token as dsh.authToken in',
|
|
51
|
+
' ~/.dsi/settings.yaml, then serve',
|
|
52
|
+
' --dev serve the Vite dev server instead of the built page (takes',
|
|
53
|
+
' port 5175; needs a full checkout: pnpm install)',
|
|
54
|
+
' --sync-kills',
|
|
55
|
+
' kill orphaned dsh/dsi processes left by an earlier run',
|
|
56
|
+
'',
|
|
47
57
|
' Ports: `dsi dsh --sync` serves the DSI page on 5174 and opens your',
|
|
48
58
|
' browser there. With --dev the Vite dev server takes 5175 instead',
|
|
49
59
|
' and the browser follows. Override with PORT=<n>.',
|
|
50
60
|
'',
|
|
51
|
-
' All commands:',
|
|
61
|
+
' All commands (flags — see above):',
|
|
52
62
|
'',
|
|
53
|
-
' dsi web',
|
|
54
|
-
' serve the
|
|
63
|
+
' dsi web [--zai] [--dev] [--token <token>]',
|
|
64
|
+
' serve the DSI page alone (PORT env default 5174,',
|
|
55
65
|
' HOST env default 127.0.0.1)',
|
|
56
|
-
' dsi zai',
|
|
57
|
-
' add the ZAI provider + default model to',
|
|
66
|
+
' dsi zai add the ZAI provider + default model to',
|
|
58
67
|
' ~/.dsh/settings.yaml',
|
|
59
68
|
' dsi dsh --token <token>',
|
|
60
|
-
' store the dsh launch token
|
|
61
|
-
' ~/.dsi/settings.yaml',
|
|
69
|
+
' store the dsh launch token in ~/.dsi/settings.yaml',
|
|
62
70
|
' dsi dsh --sync [--zai] [--dev]',
|
|
63
71
|
' run dsh-web-synced.sh (dsh web + token sync) AND serve',
|
|
64
|
-
' dsi — see the recommended command above
|
|
65
|
-
' bootstraps the ZAI provider first; --dev serves the',
|
|
66
|
-
' Vite dev server instead of the build (needs a full',
|
|
67
|
-
' checkout: pnpm install)',
|
|
72
|
+
' dsi — see the recommended command above',
|
|
68
73
|
' dsi dsh --sync-kills',
|
|
69
74
|
' kill orphaned dsh/dsi processes left by an earlier run'
|
|
70
75
|
].join('\n');
|
|
@@ -162,6 +167,7 @@ if (command === 'dsh') {
|
|
|
162
167
|
const withZai = rest.includes('--zai');
|
|
163
168
|
const withDev = rest.includes('--dev');
|
|
164
169
|
if (withZai) addZaiProvider();
|
|
170
|
+
runSkillsMirror();
|
|
165
171
|
runSyncedPair(
|
|
166
172
|
rest.filter((arg) => arg !== '--zai' && arg !== '--dev'),
|
|
167
173
|
withDev
|
|
@@ -381,6 +387,23 @@ function addZaiProvider() {
|
|
|
381
387
|
console.log(`dsi zai: ${settingsPath} updated — set ZAI_API_KEY in the harness env, then restart dsh web`);
|
|
382
388
|
}
|
|
383
389
|
|
|
390
|
+
/** Plant the shipped skills into the operator's skill mirror
|
|
391
|
+
* (~/.agents/skills) — ADR "The Skill Mirror" 2026-09-15, D1–D5:
|
|
392
|
+
* per-skill copy-only-if-absent, every repo skill, failures warn and
|
|
393
|
+
* never block the launch. Silent when nothing was copied or warned. */
|
|
394
|
+
function runSkillsMirror() {
|
|
395
|
+
const report = mirrorSkills(
|
|
396
|
+
path.join(packageRoot, '.agents', 'skills'),
|
|
397
|
+
path.join(homedir(), '.agents', 'skills')
|
|
398
|
+
);
|
|
399
|
+
for (const name of report.warned) {
|
|
400
|
+
console.error(`dsi: skills mirror — could not copy ${name} (skipping)`);
|
|
401
|
+
}
|
|
402
|
+
if (report.copied.length > 0 || report.warned.length > 0) {
|
|
403
|
+
console.log(`dsi: skills mirror — ${report.copied.length} copied, ${report.skipped.length} skipped, ${report.warned.length} warned`);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
384
407
|
// ── dsi web ────────────────────────────────────────────────────────────────
|
|
385
408
|
|
|
386
409
|
/** Spawn the built server (adapter-node output): the one child `dsi web`
|
|
@@ -440,7 +463,36 @@ function startDsiServer(defaultPort = '5174') {
|
|
|
440
463
|
// EADDRINUSE, the crash child's exit handler killed this launcher, and the
|
|
441
464
|
// fresh pair was orphaned in the background (RCA 2026-09-14).
|
|
442
465
|
if (command === 'web') {
|
|
443
|
-
|
|
466
|
+
// Optional dsi-side flags, the same meanings as `dsi dsh --sync`: --zai
|
|
467
|
+
// bootstraps the ZAI provider BEFORE anything boots (so this run picks it
|
|
468
|
+
// up), --token stores the dsh launch token before the page serves, --dev
|
|
469
|
+
// swaps the built server for the Vite dev server. Everything is done
|
|
470
|
+
// first, then the one child spawns and the script falls off the end.
|
|
471
|
+
const rest = process.argv.slice(3);
|
|
472
|
+
const withZai = rest.includes('--zai');
|
|
473
|
+
const withDev = rest.includes('--dev');
|
|
474
|
+
const tokenIdx = rest.indexOf('--token');
|
|
475
|
+
let token;
|
|
476
|
+
if (tokenIdx !== -1) {
|
|
477
|
+
token = rest[tokenIdx + 1];
|
|
478
|
+
if (token === undefined || token === '' || token.startsWith('--')) {
|
|
479
|
+
console.error('dsi web: --token needs the launch token as its value');
|
|
480
|
+
process.exit(64);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
const unknown = rest.filter((arg, i) =>
|
|
484
|
+
arg !== '--zai' && arg !== '--dev'
|
|
485
|
+
&& arg !== '--token' && !(tokenIdx !== -1 && i === tokenIdx + 1)
|
|
486
|
+
);
|
|
487
|
+
if (unknown.length > 0) {
|
|
488
|
+
console.error(`dsi web: unknown flag "${unknown[0]}"`);
|
|
489
|
+
console.error(USAGE);
|
|
490
|
+
process.exit(64);
|
|
491
|
+
}
|
|
492
|
+
if (withZai) addZaiProvider();
|
|
493
|
+
if (token !== undefined) setDshAuthToken(token);
|
|
494
|
+
runSkillsMirror();
|
|
495
|
+
const child = withDev ? startDsiDevServer() : startDsiServer();
|
|
444
496
|
|
|
445
497
|
for (const signal of ['SIGINT', 'SIGTERM']) {
|
|
446
498
|
process.on(signal, () => {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// skills-mirror — plant DSI's shipped skills into the operator's skill
|
|
2
|
+
// mirror (~/.agents/skills). Per-skill, copy-only-if-absent: an existing
|
|
3
|
+
// target ALWAYS wins (ADR "The Skill Mirror" 2026-09-15, D1), the whole
|
|
4
|
+
// source set is copied (D4), and any per-skill failure is recorded as a
|
|
5
|
+
// warning instead of throwing (D5). Zero dependencies: node built-ins only.
|
|
6
|
+
import { cpSync, existsSync, readdirSync, statSync } from 'node:fs';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Copy every skill directory from sourceDir into mirrorDir whose target is
|
|
11
|
+
* absent. Never throws: failures land in the report's warned list.
|
|
12
|
+
* @param {string} sourceDir - e.g. <packageRoot>/.agents/skills
|
|
13
|
+
* @param {string} mirrorDir - e.g. ~/.agents/skills
|
|
14
|
+
* @returns {{copied: string[], skipped: string[], warned: string[]}}
|
|
15
|
+
*/
|
|
16
|
+
export function mirrorSkills(sourceDir, mirrorDir) {
|
|
17
|
+
const report = { copied: [], skipped: [], warned: [] };
|
|
18
|
+
let sourceIsDir = false;
|
|
19
|
+
try {
|
|
20
|
+
sourceIsDir = existsSync(sourceDir) && statSync(sourceDir).isDirectory();
|
|
21
|
+
} catch {
|
|
22
|
+
return report;
|
|
23
|
+
}
|
|
24
|
+
if (!sourceIsDir) return report;
|
|
25
|
+
|
|
26
|
+
let entries = [];
|
|
27
|
+
try {
|
|
28
|
+
entries = readdirSync(sourceDir);
|
|
29
|
+
} catch {
|
|
30
|
+
return report;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
for (const name of entries) {
|
|
34
|
+
const source = join(sourceDir, name);
|
|
35
|
+
let isDir = false;
|
|
36
|
+
try {
|
|
37
|
+
isDir = statSync(source).isDirectory();
|
|
38
|
+
} catch {
|
|
39
|
+
continue; // unreadable source entry — not this run's problem
|
|
40
|
+
}
|
|
41
|
+
if (!isDir) continue; // stray files are not skills
|
|
42
|
+
|
|
43
|
+
const target = join(mirrorDir, name);
|
|
44
|
+
if (existsSync(target)) {
|
|
45
|
+
report.skipped.push(name); // existing wins — D1
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
cpSync(source, target, { recursive: true });
|
|
50
|
+
report.copied.push(name);
|
|
51
|
+
} catch {
|
|
52
|
+
report.warned.push(name); // D5: warn, continue, never throw
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return report;
|
|
56
|
+
}
|
|
@@ -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-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-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-900:oklch(41.4% .112 45.904);--color-green-50:oklch(98.2% .018 155.826);--color-green-300:oklch(87.1% .15 154.449);--color-green-500:oklch(72.3% .219 149.579);--color-green-700:oklch(52.7% .154 150.069);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-emerald-700:oklch(50.8% .118 165.612);--color-emerald-800:oklch(43.2% .095 166.913);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-slate-50:oklch(98.4% .003 247.858);--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-neutral-400:oklch(70.8% 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;--tracking-wide:.025em;--tracking-wider:.05em;--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-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-rose:#f43f5e;--color-accent-cyan:#06b6d4;--color-status-pass:#10b981;--color-status-fail:#ef4444}}@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}svg{color:var(--color-accent-purple)}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.\!collapse{visibility:collapse!important}.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\.5{bottom:calc(var(--spacing) * .5)}.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)}.isolate{isolation:isolate}.z-10{z-index:10}.z-30{z-index:30}.z-50{z-index:50}.z-1000,.z-\[1000\]{z-index:1000}.z-auto{z-index:auto}.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-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)}.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-2{margin-right:calc(var(--spacing) * 2)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:var(--spacing)}.ml-1{margin-left:var(--spacing)}.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-5{height:calc(var(--spacing) * 5)}.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-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-\[calc\(100vh-80px\)\]{max-height:calc(100vh - 80px)}.min-h-0{min-height:0}.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-5{width:calc(var(--spacing) * 5)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-15{width:calc(var(--spacing) * 15)}.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-\[18px\]{width:18px}.w-\[22px\]{width:22px}.w-\[62px\]{width:62px}.w-\[200px\]{width:200px}.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-44{min-width:calc(var(--spacing) * 44)}.min-w-72{min-width:calc(var(--spacing) * 72)}.flex-1{flex:1}.flex-shrink,.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.border-collapse{border-collapse:collapse}.-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,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.cursor-zoom-in{cursor:zoom-in}.resize{resize:both}.resize-none{resize:none}.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-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-lg{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.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-none{--tw-border-style:none;border-style:none}.border-\[\#7c3aed\]\/30{border-color:oklab(54.1337% .0963843 -.226968/.3)}.border-\[var\(--color-surface-border\)\]{border-color:var(--color-surface-border)}.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-amber-200{border-color:var(--color-amber-200)}.border-amber-300{border-color:var(--color-amber-300)}.border-emerald-200{border-color:var(--color-emerald-200)}.border-emerald-300{border-color:var(--color-emerald-300)}.border-emerald-600{border-color:var(--color-emerald-600)}.border-green-300{border-color:var(--color-green-300)}.border-red-200{border-color:var(--color-red-200)}.border-red-300{border-color:var(--color-red-300)}.border-red-500\/30{border-color:#fb2c364d}@supports (color:color-mix(in lab, red, red)){.border-red-500\/30{border-color:color-mix(in oklab, var(--color-red-500) 30%, transparent)}}.border-slate-200{border-color:var(--color-slate-200)}.border-slate-300{border-color:var(--color-slate-300)}.border-slate-500\/20{border-color:#62748e33}@supports (color:color-mix(in lab, red, red)){.border-slate-500\/20{border-color:color-mix(in oklab, var(--color-slate-500) 20%, 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\/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)}}.bg-\[\#7c3aed\]\/10{background-color:oklab(54.1337% .0963843 -.226968/.1)}.bg-\[\#DDD3B0\]{background-color:#ddd3b0}.bg-\[\#E9E3C9\]{background-color:#e9e3c9}.bg-\[\#F5F5DC\]{background-color:beige}.bg-\[\#FDF5E6\]{background-color:#fdf5e6}.bg-\[var\(--color-surface-elevated\)\]{background-color:var(--color-surface-elevated)}.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-purple-ink{background-color:var(--color-accent-purple-ink)}.bg-accent-purple-soft{background-color:var(--color-accent-purple-soft)}.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-50{background-color:var(--color-amber-50)}.bg-amber-400{background-color:var(--color-amber-400)}.bg-amber-500{background-color:var(--color-amber-500)}.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-600{background-color:var(--color-blue-600)}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-emerald-600{background-color:var(--color-emerald-600)}.bg-green-50{background-color:var(--color-green-50)}.bg-green-500{background-color:var(--color-green-500)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/10{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.bg-red-600{background-color:var(--color-red-600)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-300{background-color:var(--color-slate-300)}.bg-slate-400{background-color:var(--color-slate-400)}.bg-slate-500\/5{background-color:#62748e0d}@supports (color:color-mix(in lab, red, red)){.bg-slate-500\/5{background-color:color-mix(in oklab, var(--color-slate-500) 5%, transparent)}}.bg-slate-500\/10{background-color:#62748e1a}@supports (color:color-mix(in lab, red, red)){.bg-slate-500\/10{background-color:color-mix(in oklab, var(--color-slate-500) 10%, transparent)}}.bg-slate-800{background-color:var(--color-slate-800)}.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-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-\[linear-gradient\(90deg\,\#E6F4D7\,\#FDF5E6_65\%\,\#FEF9EF\)\]{background-image:linear-gradient(90deg,#e6f4d7,#fdf5e6 65%,#fef9ef)}.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-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-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}.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\.6875rem\]{font-size:.6875rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.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-\[\#7c3aed\]{color:#7c3aed}.text-\[color\:var\(--color-text-secondary\,\#6c757d\)\]{color:var(--color-text-secondary,#6c757d)}.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-amber-500{color:var(--color-amber-500)}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-amber-700\/80{color:#b75000cc}@supports (color:color-mix(in lab, red, red)){.text-amber-700\/80{color:color-mix(in oklab, var(--color-amber-700) 80%, transparent)}}.text-amber-800{color:var(--color-amber-800)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-600{color:var(--color-emerald-600)}.text-emerald-700{color:var(--color-emerald-700)}.text-emerald-800{color:var(--color-emerald-800)}.text-green-500{color:var(--color-green-500)}.text-green-700{color:var(--color-green-700)}.text-neutral-400{color:var(--color-neutral-400)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.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-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-800{color:var(--color-slate-800)}.text-slate-900{color:var(--color-slate-900)}.text-status-pass{color:var(--color-status-pass)}.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)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.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-slate-300{-webkit-text-decoration-color:var(--color-slate-300);-webkit-text-decoration-color:var(--color-slate-300);-webkit-text-decoration-color:var(--color-slate-300);text-decoration-color:var(--color-slate-300)}.opacity-0{opacity:0}.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-amber-200{--tw-ring-color:var(--color-amber-200)}.ring-red-200{--tw-ring-color:var(--color-red-200)}.ring-red-300{--tw-ring-color:var(--color-red-300)}.ring-slate-100{--tw-ring-color:var(--color-slate-100)}.ring-slate-200{--tw-ring-color:var(--color-slate-200)}.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,)}.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,)}.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-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)}.outline-none{--tw-outline-style:none;outline-style:none}.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-\[\#7c3aed\]:is(:where(.group\/bubble):hover *){color:#7c3aed}.group-hover\/bubble\:opacity-100:is(:where(.group\/bubble):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 *),.group-hover\/reasoning\:opacity-100:is(:where(.group\/reasoning):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-slate-400::placeholder{color:var(--color-slate-400)}.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-slate-300:hover{border-color:var(--color-slate-300)}.hover\:bg-\[\#7c3aed\]\/20:hover{background-color:oklab(54.1337% .0963843 -.226968/.2)}.hover\:bg-amber-100:hover{background-color:var(--color-amber-100)}.hover\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\:bg-emerald-700:hover{background-color:var(--color-emerald-700)}.hover\:bg-red-100:hover{background-color:var(--color-red-100)}.hover\:bg-red-600:hover{background-color:var(--color-red-600)}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:bg-slate-50:hover{background-color:var(--color-slate-50)}.hover\:bg-slate-100:hover{background-color:var(--color-slate-100)}.hover\:bg-slate-200:hover{background-color:var(--color-slate-200)}.hover\:bg-slate-500\/20:hover{background-color:#62748e33}@supports (color:color-mix(in lab, red, red)){.hover\:bg-slate-500\/20:hover{background-color:color-mix(in oklab, var(--color-slate-500) 20%, transparent)}}.hover\:bg-slate-700:hover{background-color:var(--color-slate-700)}.hover\:bg-surface-hover:hover{background-color:var(--color-surface-hover)}.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-amber-900:hover{color:var(--color-amber-900)}.hover\:text-slate-200:hover{color:var(--color-slate-200)}.hover\:text-slate-600:hover{color:var(--color-slate-600)}.hover\:text-text-muted:hover{color:var(--color-text-muted)}.hover\:text-text-primary:hover{color:var(--color-text-primary)}@media (hover:hover){.hover\:group-hover\/bubble\:text-\[\#7c3aed\]:hover:is(:where(.group\/bubble):hover *){color:#7c3aed}}}.focus\:border-slate-500:focus{border-color:var(--color-slate-500)}.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-slate-400:focus{--tw-ring-color:var(--color-slate-400)}.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-slate-50:disabled{background-color:var(--color-slate-50)}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-50:disabled{opacity:.5}@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}::-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:nowrap;background:#8b5cf60a;border:1px solid #8b5cf633;border-radius:.5em;width:100%;margin:.5em 0;display:block;overflow:auto hidden}.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:#7c3aed}.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:#7c3aed;background:#8b5cf614;border-radius:.3em;padding:.15em .35em;font-family:SF Mono,Fira Code,JetBrains Mono,monospace;font-size:.8em}.md-content pre{border:1px solid var(--color-surface-border);background:#f1f3f5;border-radius:.5em;max-width:100%;margin:.5em 0;padding:.5em;font-size:.8em;overflow-x:auto}.md-content pre code{color:#212529;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-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}}
|