@oneie/claude 0.6.0 → 0.7.0

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.
Files changed (111) hide show
  1. package/agents/w1-recon.md +9 -4
  2. package/agents/w2-decide.md +51 -28
  3. package/agents/w3-edit.md +70 -78
  4. package/agents/w4-verify.md +164 -69
  5. package/commands/browser.md +98 -35
  6. package/commands/cc-connect.md +6 -0
  7. package/commands/chat.md +13 -1
  8. package/commands/close.md +45 -19
  9. package/commands/create.md +20 -10
  10. package/commands/db-sync.md +5 -1
  11. package/commands/deploy.md +174 -87
  12. package/commands/do-autonomous.md +31 -20
  13. package/commands/do-improve.md +4 -4
  14. package/commands/do-show.md +4 -3
  15. package/commands/do.md +53 -13
  16. package/commands/go.md +75 -0
  17. package/commands/improve.md +4 -2
  18. package/commands/kill.md +6 -8
  19. package/commands/notify.md +15 -2
  20. package/commands/oo-push.md +24 -9
  21. package/commands/rag.md +6 -0
  22. package/commands/release.md +46 -25
  23. package/commands/restart.md +5 -4
  24. package/commands/see.md +45 -35
  25. package/commands/skill-create.md +38 -5
  26. package/commands/sync.md +21 -11
  27. package/hooks/scripts/auto-continue.sh +70 -0
  28. package/hooks/scripts/branch-pin.sh +85 -0
  29. package/hooks/scripts/git-add-guard.sh +16 -5
  30. package/hooks/scripts/post-edit-check.sh +16 -0
  31. package/hooks/scripts/session-start.sh +13 -8
  32. package/hooks/scripts/sync-priority-todo.sh +5 -0
  33. package/package.json +1 -1
  34. package/rules/api.md +9 -0
  35. package/rules/design.md +13 -3
  36. package/rules/documentation.md +30 -71
  37. package/rules/engine.md +8 -1
  38. package/rules/ui.md +5 -1
  39. package/scripts/__pycache__/do-rank.cpython-313.pyc +0 -0
  40. package/scripts/browser-check.mjs +44 -103
  41. package/scripts/cc-events-proof.sh +13 -12
  42. package/scripts/chrome.mjs +381 -0
  43. package/scripts/do-analyze.sh +109 -4
  44. package/scripts/do-auto.sh +350 -43
  45. package/scripts/do-consumer-sweep.sh +72 -0
  46. package/scripts/do-derives-check.sh +88 -0
  47. package/scripts/do-fleet.sh +50 -1
  48. package/scripts/do-killswitch-audit.py +33 -14
  49. package/scripts/do-promise-lint.sh +150 -4
  50. package/scripts/do-promise-settle.sh +131 -9
  51. package/scripts/do-prove.sh +197 -17
  52. package/scripts/do-rank.py +606 -20
  53. package/scripts/do-rubric.py +21 -2
  54. package/scripts/do-signal.sh +157 -17
  55. package/scripts/do-smoke.sh +9 -0
  56. package/scripts/do-substrate-check.sh +49 -0
  57. package/scripts/do-tasks-wire-check.sh +81 -0
  58. package/scripts/do-tier.sh +90 -5
  59. package/scripts/do-ui-gate.sh +332 -0
  60. package/scripts/do-untracked-gate.sh +231 -0
  61. package/scripts/do-walk.sh +344 -0
  62. package/scripts/factory-check.sh +747 -0
  63. package/scripts/factory-repo.sh +1361 -0
  64. package/scripts/factory-tasks-check.sh +85 -0
  65. package/scripts/outcome-pull.ts +279 -0
  66. package/scripts/promise-manifest.mjs +167 -0
  67. package/scripts/reconcile-allow.txt +5 -0
  68. package/scripts/rubric-weights.json +64 -0
  69. package/scripts/spine-canary.sh +20 -0
  70. package/scripts/typedb-cluster-status.sh +128 -0
  71. package/scripts/typedb-env.sh +182 -0
  72. package/scripts/typedb-flap-recorder.sh +85 -0
  73. package/scripts/typedb-probes/containment-probe.py +88 -0
  74. package/scripts/typedb-probes/panic-probe-version.py +92 -0
  75. package/scripts/typedb-probes/panic-probe.py +77 -0
  76. package/scripts/typedb-scratch.sh +73 -0
  77. package/scripts/urls-lint.sh +58 -0
  78. package/scripts/w4-rubric.ts +96 -12
  79. package/scripts/wf-check.mjs +75 -0
  80. package/skills/ai-ui/SKILL.md +1 -1
  81. package/skills/astro/SKILL.md +177 -132
  82. package/skills/astro/add-content-collection.md +29 -13
  83. package/skills/astro/check-build.md +19 -13
  84. package/skills/astro/create-component.md +36 -9
  85. package/skills/astro/create-page.md +39 -10
  86. package/skills/astro/optimize-performance.md +36 -8
  87. package/skills/cli/SKILL.md +254 -220
  88. package/skills/dev/SKILL.md +1 -1
  89. package/skills/directory-autofill/SKILL.md +68 -0
  90. package/skills/docs/SKILL.md +4 -4
  91. package/skills/mcp/SKILL.md +186 -156
  92. package/skills/promise-make/SKILL.md +2 -2
  93. package/skills/puck/SKILL.md +465 -250
  94. package/skills/react19/SKILL.md +196 -296
  95. package/skills/reactflow/SKILL.md +387 -412
  96. package/skills/sdk/SKILL.md +167 -106
  97. package/skills/shadcn/SKILL.md +245 -201
  98. package/skills/signal/SKILL.md +5 -0
  99. package/skills/sui/SKILL.md +6 -1
  100. package/skills/tutorial/SKILL.md +15 -0
  101. package/skills/typedb/SKILL.md +427 -217
  102. package/skills/typedb/examples/python-patterns.py +11 -4
  103. package/skills/typedb/examples/query-patterns.tql +8 -3
  104. package/skills/typedb/examples/schema-patterns.tql +4 -2
  105. package/skills/typedb/reference/migration-2x-3x.md +19 -1
  106. package/skills/typedb/reference/python-driver.md +17 -1
  107. package/skills/voice/SKILL.md +117 -0
  108. package/skills/writer/SKILL.md +29 -12
  109. package/templates/template-feature.md +26 -1
  110. package/templates/template-tests.md +4 -0
  111. package/templates/template-todo.md +65 -10
@@ -1,13 +1,22 @@
1
1
  ---
2
2
  name: shadcn
3
- description: Use shadcn/ui components for the Envelope System UI - Cards, Tabs, Badges, and dark theme patterns
3
+ description: shadcn/ui primitives in `one.ie/web` under the ONE 6-token design system. Covers the `src/components/ui/` inventory, why shadcn's own `-foreground` names survive the `--color-*: initial` palette wipe via the Layout.astro aliases, adding a primitive with the CLI, and Button/Badge/Card/Dialog variants. Use when adding or editing a `src/components/ui/` primitive, when a shadcn component renders transparent or invisible after the wipe, or when picking between a token utility and an alias.
4
4
  user-invocable: true
5
5
  allowed-tools: Read, Write, Edit, Glob, Grep, Bash
6
6
  ---
7
7
 
8
8
  # shadcn/ui Development
9
9
 
10
- Build consistent UI with shadcn/ui components, customized for the Envelope System's dark theme.
10
+ Build UI in `one.ie/web` with shadcn primitives on the ONE 6-token design system.
11
+
12
+ This skill covers the seam that the auto-loaded rules do not: **how shadcn's own
13
+ naming convention (`bg-card`, `text-muted-foreground`, `text-primary-foreground`)
14
+ survives the `--color-*: initial` palette wipe.** For the token list, the allowed
15
+ utilities, and the ban list, read `.claude/rules/design.md` — it auto-loads on the
16
+ same files and is already in context when you edit.
17
+
18
+ Scope: `one.ie/web`. For `template/site` use the `template:shadcn` skill; for
19
+ generic registry/CLI operations outside this repo use the `shadcn` plugin skill.
11
20
 
12
21
  ## Works With
13
22
 
@@ -15,56 +24,102 @@ Build consistent UI with shadcn/ui components, customized for the Envelope Syste
15
24
  |------------|------------------------------------------------------------------------------|
16
25
  | `/react19` | shadcn components ARE React components — ref-as-prop, Actions, transitions apply. |
17
26
  | `/astro` | Placement inside islands + hydration strategy decisions. |
18
- | `/signal` | Buttons, menus, dialogsevery semantic click emits `ui:<surface>:<action>`. |
27
+ | `/puck` | Every Puck block wraps a real component brand tokens reach the editor iframe. |
19
28
  | `/ai-ui` | AI Elements (reasoning cards, tool-call blocks) compose shadcn primitives. |
20
29
 
21
- Auto-loads on `*.tsx`: `rules/react.md` + `rules/ui.md` (per `.claude/settings.json`).
30
+ Auto-loads on these files, via each rule's own `paths:` frontmatter (not
31
+ `settings.json`, which wires hooks only):
32
+
33
+ | Rule | Glob |
34
+ |---|---|
35
+ | `rules/react.md` | `**/*.tsx` |
36
+ | `rules/ui.md` | `one.ie/web/src/components/**/*.tsx` |
37
+ | `rules/design.md` | `one.ie/web/**/*.{tsx,astro,css}` |
22
38
 
23
39
  ## When to Use This Skill
24
40
 
25
- - Use existing shadcn components from `src/components/ui/`
26
- - Customize component variants
27
- - Add new shadcn components
28
- - Apply the dark theme color system
29
- - Build composite components
41
+ - Use existing primitives from `one.ie/web/src/components/ui/`
42
+ - Add a new primitive with the shadcn CLI
43
+ - Customize a variant (`cva` blocks in `button.tsx`, `badge.tsx`)
44
+ - Fix a primitive that renders transparent or invisible after the palette wipe
45
+ - Build composite components on top of the primitives
30
46
 
31
47
  ## Available Components
32
48
 
33
- The project includes these shadcn/ui components in `src/components/ui/`:
34
-
35
- | Component | Import | Use Case |
36
- |-----------|--------|----------|
37
- | `Card` | `@/components/ui/card` | Envelopes, agents, panels |
38
- | `Tabs` | `@/components/ui/tabs` | Agent tabs in top panel |
39
- | `Badge` | `@/components/ui/badge` | Status indicators |
40
- | `Button` | `@/components/ui/button` | Actions, submissions |
41
- | `ScrollArea` | `@/components/ui/scroll-area` | Scrollable lists |
42
- | `Separator` | `@/components/ui/separator` | Visual dividers |
43
- | `Tooltip` | `@/components/ui/tooltip` | Hover information |
44
- | `Dialog` | `@/components/ui/dialog` | Modals |
45
- | `Accordion` | `@/components/ui/accordion` | Collapsible sections |
46
-
47
- ## Color System (Dark Theme)
48
-
49
- ```css
50
- /* Primary colors */
51
- --background: #0a0a0f; /* Near-black */
52
- --foreground: #ffffff; /* White text */
53
-
54
- /* Status colors */
55
- --status-ready: #22c55e; /* Green - ready/resolved */
56
- --status-pending: #eab308; /* Amber - pending/waiting */
57
- --status-idle: #64748b; /* Slate - idle */
58
- --status-error: #ef4444; /* Red - error/rejected */
59
-
60
- /* Borders and accents */
61
- --border: #1e293b; /* Subtle borders */
62
- --accent: #3b82f6; /* Blue accent */
49
+ `one.ie/web/src/components/ui/` holds **57 files**. They are not all shadcn:
50
+
51
+ **shadcn primitives** generated by the CLI, backed by the unified `radix-ui`
52
+ package (`^1.4.3`, imported as `import { Dialog as DialogPrimitive } from "radix-ui"`
53
+ **not** the old `@radix-ui/react-*` scoped packages):
54
+
55
+ `accordion` · `alert` · `aspect-ratio` · `avatar` · `badge` · `breadcrumb` ·
56
+ `button` · `button-group` · `card` · `carousel` · `chart` · `checkbox` ·
57
+ `collapsible` · `command` · `dialog` · `dropdown-menu` · `hover-card` ·
58
+ `input` · `input-group` · `kbd` · `label` · `navigation-menu` · `pagination` ·
59
+ `popover` · `progress` · `radio-group` · `scroll-area` · `select` · `separator` ·
60
+ `sheet` · `skeleton` · `slider` · `spinner` · `switch` · `table` · `tabs` ·
61
+ `textarea` · `toggle` · `toggle-group` · `tooltip`
62
+
63
+ **ONE-local, not shadcn** do not `shadcn add` over these, and do not assume
64
+ upstream props: `Icon.tsx` · `IconBadge.tsx` · `EmptyCard.tsx` · `ImagePicker.tsx` ·
65
+ `Drawer.tsx` · `global-toaster.tsx` · `multi-select.tsx` · `rating.tsx` ·
66
+ `animated-tooltip.tsx` · `bounce-button.tsx` · `magnetic-button.tsx` ·
67
+ `shimmer-button.tsx` · `motion-checkbox.tsx` · `motion-highlight.tsx` ·
68
+ `motion-radio-group.tsx` · `motion-switch.tsx` · `motion-tabs.tsx`
69
+
70
+ `components.json` pins `style: "radix-nova"`, `iconLibrary: "lucide"`,
71
+ `cssVariables: true`, and `css: src/styles/globals.css`.
72
+
73
+ ## Color System how shadcn names survive the wipe
74
+
75
+ `Layout.astro` declares `--color-*: initial` inside `@theme`, which erases
76
+ Tailwind's entire default palette. That is the enforcement layer: `bg-zinc-950`
77
+ emits no CSS at all. It also erases every var a stock shadcn primitive expects.
78
+
79
+ So `Layout.astro` re-declares the ones shadcn needs, aliased onto the 6 tokens.
80
+ This is the mechanism to know — it is why you can write `bg-card` and
81
+ `text-muted-foreground` in a primitive without adding a 7th token:
82
+
83
+ ```
84
+ --color-popover: var(--color-foreground)
85
+ --color-popover-foreground: var(--color-font)
86
+ --color-card: var(--color-foreground)
87
+ --color-card-foreground: var(--color-font)
88
+ --color-muted: var(--color-foreground)
89
+ --color-muted-foreground: color-mix(font 60%, transparent)
90
+ --color-accent: var(--color-foreground)
91
+ --color-accent-foreground: var(--color-font)
92
+ --color-input: var(--color-background)
93
+ --color-primary-foreground: var(--color-on-primary)
94
+ --color-secondary-foreground: var(--color-on-secondary)
63
95
  ```
64
96
 
97
+ Two failure modes this prevents, both of which look like a bug in the component:
98
+
99
+ 1. **Transparent popovers.** Without `--color-card` / `--color-popover`, the
100
+ wiped var makes the `background-color` declaration invalid, so the panel
101
+ inherits nothing and floats see-through over the page.
102
+ 2. **Invisible glyphs on a brand fill.** Stock Button/Badge/Checkbox read
103
+ `text-primary-foreground`. Wiped, the color declaration is dropped and the
104
+ icon inherits an ancestor's `text-muted-foreground` — near-invisible on a
105
+ solid `bg-primary`. The alias points it at the already-WCAG-correct
106
+ `on-primary` label.
107
+
108
+ **The one collision you must resolve by hand:** shadcn uses `foreground` to mean
109
+ "body text on a card". ONE uses `foreground` as the L2 *surface* token (cards,
110
+ sidebar, panels). They are not the same thing and there is no alias that can make
111
+ them so. Any primitive that ships `text-foreground` for body text **must be edited
112
+ to `text-font`** — otherwise the text paints the same color as its own background.
113
+ `src/components/ui/` currently has zero `text-foreground` occurrences; keep it
114
+ that way after every `shadcn add`.
115
+
116
+ Fine as-is, no edit needed: `text-card-foreground`, `text-popover-foreground`,
117
+ `text-muted-foreground`, `text-accent-foreground`, and the
118
+ `text-{primary,secondary,destructive,sidebar}-foreground` contrast labels.
119
+
65
120
  ## Core Components
66
121
 
67
- ### Card (Envelopes, Agents)
122
+ ### Card
68
123
 
69
124
  ```tsx
70
125
  import {
@@ -75,32 +130,33 @@ import {
75
130
  CardTitle,
76
131
  } from "@/components/ui/card";
77
132
 
78
- export function EnvelopeCard({ envelope }: { envelope: Envelope }) {
133
+ interface Signal {
134
+ id: string;
135
+ receiver: string;
136
+ target: string;
137
+ status: string;
138
+ }
139
+
140
+ export function SignalCard({ signal }: { signal: Signal }) {
79
141
  return (
80
- <Card className="bg-[#0f0f14] border-[#1e293b]">
142
+ <Card>
81
143
  <CardHeader className="pb-2">
82
144
  <CardTitle className="flex items-center gap-2 text-sm font-mono">
83
- <span className="text-slate-400">envelope</span>
84
- <span className="text-blue-400">{envelope.id}</span>
145
+ <span className="text-font/60">signal</span>
146
+ <span className="text-primary">{signal.id}</span>
85
147
  </CardTitle>
86
148
  <CardDescription>
87
- {envelope.env.action} → {envelope.metadata?.receiver}
149
+ {signal.receiver} → {signal.target}
88
150
  </CardDescription>
89
151
  </CardHeader>
90
152
  <CardContent className="space-y-2">
91
153
  <div className="font-mono text-xs">
92
- <span className="text-slate-500">action: </span>
93
- <span className="text-green-400">{envelope.env.action}</span>
154
+ <span className="text-font/40">receiver: </span>
155
+ <span className="text-tertiary">{signal.receiver}</span>
94
156
  </div>
95
157
  <div className="font-mono text-xs">
96
- <span className="text-slate-500">inputs: </span>
97
- <span className="text-amber-400">
98
- {JSON.stringify(envelope.env.inputs)}
99
- </span>
100
- </div>
101
- <div className="font-mono text-xs">
102
- <span className="text-slate-500">status: </span>
103
- <StatusBadge status={envelope.payload.status} />
158
+ <span className="text-font/40">status: </span>
159
+ <StatusBadge status={signal.status} />
104
160
  </div>
105
161
  </CardContent>
106
162
  </Card>
@@ -108,30 +164,31 @@ export function EnvelopeCard({ envelope }: { envelope: Envelope }) {
108
164
  }
109
165
  ```
110
166
 
111
- ### Tabs (Agent Selection)
167
+ `Card` already resolves to the `foreground` surface via `--color-card`. Do not
168
+ re-skin it with a background utility.
169
+
170
+ ### Tabs
112
171
 
113
172
  ```tsx
114
173
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
115
174
 
116
- export function AgentTabs({ agents }: { agents: Agent[] }) {
175
+ interface Actor { id: string; name: string; status: string }
176
+
177
+ export function ActorTabs({ actors }: { actors: Actor[] }) {
117
178
  return (
118
- <Tabs defaultValue={agents[0]?.id} className="w-full">
119
- <TabsList className="bg-[#0f0f14] border border-[#1e293b]">
120
- {agents.map(agent => (
121
- <TabsTrigger
122
- key={agent.id}
123
- value={agent.id}
124
- className="data-[state=active]:bg-[#1e293b] data-[state=active]:text-white"
125
- >
126
- <StatusDot status={agent.status} />
127
- <span className="ml-2">{agent.name}</span>
179
+ <Tabs defaultValue={actors[0]?.id} className="w-full">
180
+ <TabsList>
181
+ {actors.map(actor => (
182
+ <TabsTrigger key={actor.id} value={actor.id}>
183
+ <StatusDot status={actor.status} />
184
+ <span className="ml-2">{actor.name}</span>
128
185
  </TabsTrigger>
129
186
  ))}
130
187
  </TabsList>
131
188
 
132
- {agents.map(agent => (
133
- <TabsContent key={agent.id} value={agent.id} className="mt-4">
134
- <AgentContent agent={agent} />
189
+ {actors.map(actor => (
190
+ <TabsContent key={actor.id} value={actor.id} className="mt-4">
191
+ <ActorContent actor={actor} />
135
192
  </TabsContent>
136
193
  ))}
137
194
  </Tabs>
@@ -139,26 +196,26 @@ export function AgentTabs({ agents }: { agents: Agent[] }) {
139
196
  }
140
197
  ```
141
198
 
142
- ### Badge (Status Indicators)
199
+ ### Badge
200
+
201
+ Status color comes from the 5 invariants plus the 3 brand tokens — never from a
202
+ Tailwind palette ramp.
143
203
 
144
204
  ```tsx
145
205
  import { Badge } from "@/components/ui/badge";
146
206
 
147
- const statusColors = {
148
- ready: "bg-green-500/20 text-green-400 border-green-500/30",
149
- resolved: "bg-green-500/20 text-green-400 border-green-500/30",
150
- pending: "bg-amber-500/20 text-amber-400 border-amber-500/30",
151
- waiting: "bg-amber-500/20 text-amber-400 border-amber-500/30",
152
- idle: "bg-slate-500/20 text-slate-400 border-slate-500/30",
153
- error: "bg-red-500/20 text-red-400 border-red-500/30",
154
- rejected: "bg-red-500/20 text-red-400 border-red-500/30",
207
+ const statusClasses = {
208
+ resolved: "bg-success/20 text-success",
209
+ pending: "bg-secondary/20 text-secondary",
210
+ idle: "bg-font/10 text-font/60",
211
+ error: "bg-destructive/20 text-destructive",
155
212
  };
156
213
 
157
214
  export function StatusBadge({ status }: { status: string }) {
158
215
  return (
159
216
  <Badge
160
217
  variant="outline"
161
- className={statusColors[status as keyof typeof statusColors] || statusColors.idle}
218
+ className={statusClasses[status as keyof typeof statusClasses] ?? statusClasses.idle}
162
219
  >
163
220
  {status}
164
221
  </Badge>
@@ -166,43 +223,41 @@ export function StatusBadge({ status }: { status: string }) {
166
223
  }
167
224
  ```
168
225
 
169
- ### Button Variants
226
+ ### Button
227
+
228
+ The repo's `button.tsx` ships **6 variants** — `default` · `outline` ·
229
+ `secondary` · `ghost` · `destructive` · `link` — and **8 sizes** — `default` ·
230
+ `xs` · `sm` · `lg` · `icon` · `icon-xs` · `icon-sm` · `icon-lg`. There is no
231
+ `primary` variant name; `default` already means `bg-primary text-primary-foreground`.
170
232
 
171
233
  ```tsx
172
234
  import { Button } from "@/components/ui/button";
235
+ import { ChevronRight } from "lucide-react";
173
236
 
174
- // Primary action
175
- <Button className="bg-blue-600 hover:bg-blue-700">
176
- Send Envelope
177
- </Button>
178
-
179
- // Secondary action
180
- <Button variant="outline" className="border-[#1e293b] hover:bg-[#1e293b]">
181
- Cancel
182
- </Button>
183
-
184
- // Destructive
185
- <Button variant="destructive">
186
- Reject
187
- </Button>
188
-
189
- // Ghost (icon buttons)
237
+ <Button>Send signal</Button> {/* default = brand fill */}
238
+ <Button variant="outline">Cancel</Button>
239
+ <Button variant="secondary">Save draft</Button>
240
+ <Button variant="destructive">Reject</Button>
190
241
  <Button variant="ghost" size="icon">
191
- <ChevronRight className="h-4 w-4" />
242
+ <ChevronRight />
192
243
  </Button>
193
244
  ```
194
245
 
195
- ### ScrollArea (Lists)
246
+ Do not pass a background class to override the variant — that is how a palette
247
+ class gets reintroduced. Add a variant to the `cva` block instead.
248
+
249
+ ### ScrollArea
196
250
 
197
251
  ```tsx
198
252
  import { ScrollArea } from "@/components/ui/scroll-area";
253
+ import { SignalCard } from "./SignalCard";
199
254
 
200
- export function EnvelopeList({ envelopes }: { envelopes: Envelope[] }) {
255
+ export function SignalList({ signals }: { signals: Signal[] }) {
201
256
  return (
202
257
  <ScrollArea className="h-[400px] pr-4">
203
258
  <div className="space-y-3">
204
- {envelopes.map(env => (
205
- <EnvelopeCard key={env.id} envelope={env} />
259
+ {signals.map(s => (
260
+ <SignalCard key={s.id} signal={s} />
206
261
  ))}
207
262
  </div>
208
263
  </ScrollArea>
@@ -210,7 +265,7 @@ export function EnvelopeList({ envelopes }: { envelopes: Envelope[] }) {
210
265
  }
211
266
  ```
212
267
 
213
- ### Tooltip (Hover Info)
268
+ ### Tooltip
214
269
 
215
270
  ```tsx
216
271
  import {
@@ -220,11 +275,11 @@ import {
220
275
  TooltipTrigger,
221
276
  } from "@/components/ui/tooltip";
222
277
 
223
- export function EnvelopeId({ id, full }: { id: string; full: string }) {
278
+ export function SignalId({ id, full }: { id: string; full: string }) {
224
279
  return (
225
280
  <TooltipProvider>
226
281
  <Tooltip>
227
- <TooltipTrigger className="font-mono text-blue-400 cursor-help">
282
+ <TooltipTrigger className="font-mono text-primary cursor-help">
228
283
  {id}
229
284
  </TooltipTrigger>
230
285
  <TooltipContent>
@@ -236,7 +291,7 @@ export function EnvelopeId({ id, full }: { id: string; full: string }) {
236
291
  }
237
292
  ```
238
293
 
239
- ### Accordion (Collapsible Logic)
294
+ ### Accordion
240
295
 
241
296
  ```tsx
242
297
  import {
@@ -246,16 +301,14 @@ import {
246
301
  AccordionTrigger,
247
302
  } from "@/components/ui/accordion";
248
303
 
249
- export function LogicViewer({ code }: { code: string }) {
304
+ export function ConfigViewer({ code }: { code: string }) {
250
305
  return (
251
- <Accordion type="single" collapsible defaultValue="logic">
252
- <AccordionItem value="logic" className="border-[#1e293b]">
253
- <AccordionTrigger className="text-sm">
254
- Agent Logic
255
- </AccordionTrigger>
306
+ <Accordion type="single" collapsible defaultValue="config">
307
+ <AccordionItem value="config">
308
+ <AccordionTrigger className="text-sm">Step config</AccordionTrigger>
256
309
  <AccordionContent>
257
- <pre className="p-4 bg-[#0a0a0f] rounded font-mono text-xs overflow-x-auto">
258
- <code className="text-slate-300">{code}</code>
310
+ <pre className="p-4 bg-background rounded font-mono text-xs overflow-x-auto">
311
+ <code className="text-font/80">{code}</code>
259
312
  </pre>
260
313
  </AccordionContent>
261
314
  </AccordionItem>
@@ -269,21 +322,18 @@ export function LogicViewer({ code }: { code: string }) {
269
322
  ### Status Dot
270
323
 
271
324
  ```tsx
272
- const dotColors = {
273
- ready: "bg-green-500",
274
- resolved: "bg-green-500",
275
- pending: "bg-amber-500 animate-pulse",
276
- waiting: "bg-amber-500 animate-pulse",
277
- idle: "bg-slate-500",
278
- error: "bg-red-500",
279
- rejected: "bg-red-500",
325
+ const dotClasses = {
326
+ resolved: "bg-success",
327
+ pending: "bg-secondary animate-pulse",
328
+ idle: "bg-font/40",
329
+ error: "bg-destructive",
280
330
  };
281
331
 
282
332
  export function StatusDot({ status }: { status: string }) {
283
333
  return (
284
334
  <span
285
335
  className={`inline-block w-2 h-2 rounded-full ${
286
- dotColors[status as keyof typeof dotColors] || dotColors.idle
336
+ dotClasses[status as keyof typeof dotClasses] ?? dotClasses.idle
287
337
  }`}
288
338
  />
289
339
  );
@@ -293,24 +343,20 @@ export function StatusDot({ status }: { status: string }) {
293
343
  ### Panel Header
294
344
 
295
345
  ```tsx
296
- export function PanelHeader({
297
- title,
298
- count,
299
- children,
300
- }: {
346
+ import { Badge } from "@/components/ui/badge";
347
+
348
+ interface PanelHeaderProps {
301
349
  title: string;
302
350
  count?: number;
303
351
  children?: React.ReactNode;
304
- }) {
352
+ }
353
+
354
+ export function PanelHeader({ title, count, children }: PanelHeaderProps) {
305
355
  return (
306
356
  <div className="flex items-center justify-between mb-4">
307
357
  <div className="flex items-center gap-2">
308
- <h3 className="text-sm font-medium text-slate-300">{title}</h3>
309
- {count !== undefined && (
310
- <Badge variant="secondary" className="bg-[#1e293b]">
311
- {count}
312
- </Badge>
313
- )}
358
+ <h3 className="text-sm font-medium text-font/80">{title}</h3>
359
+ {count !== undefined && <Badge variant="secondary">{count}</Badge>}
314
360
  </div>
315
361
  {children}
316
362
  </div>
@@ -321,18 +367,19 @@ export function PanelHeader({
321
367
  ### Code Block
322
368
 
323
369
  ```tsx
324
- export function CodeBlock({
325
- code,
326
- language = "typescript",
327
- }: {
370
+ import { Card, CardContent } from "@/components/ui/card";
371
+
372
+ interface CodeBlockProps {
328
373
  code: string;
329
374
  language?: string;
330
- }) {
375
+ }
376
+
377
+ export function CodeBlock({ code, language = "typescript" }: CodeBlockProps) {
331
378
  return (
332
- <Card className="bg-[#0a0a0f] border-[#1e293b]">
379
+ <Card data-language={language}>
333
380
  <CardContent className="p-0">
334
381
  <pre className="p-4 overflow-x-auto">
335
- <code className="font-mono text-xs text-slate-300 whitespace-pre">
382
+ <code className="font-mono text-xs text-font/80 whitespace-pre">
336
383
  {code}
337
384
  </code>
338
385
  </pre>
@@ -344,31 +391,39 @@ export function CodeBlock({
344
391
 
345
392
  ## Adding New Components
346
393
 
347
- To add a new shadcn component:
348
-
349
394
  ```bash
350
- # From project root
351
- bunx shadcn@latest add [component-name]
352
-
353
- # Examples
395
+ # from one.ie/web (components.json lives there)
354
396
  bunx shadcn@latest add sheet
355
397
  bunx shadcn@latest add command
356
398
  bunx shadcn@latest add popover
357
399
  ```
358
400
 
401
+ **Always run the token pass immediately after.** The CLI writes upstream defaults
402
+ that assume Tailwind's palette exists:
403
+
404
+ ```bash
405
+ grep -nE 'text-foreground|#[0-9a-fA-F]{3,8}|(bg|text|border)-(zinc|slate|gray|neutral|red|green|blue|amber)-[0-9]' \
406
+ src/components/ui/<new>.tsx
407
+ ```
408
+
409
+ Every hit is a fix: `text-foreground` → `text-font`; a palette class → a token
410
+ utility or an alias from the table above; a hex → a token. The `design-check.sh`
411
+ PostToolUse hook catches these on your next edit of the file, but the CLI writes
412
+ the file without going through the hook — so sweep it yourself.
413
+
359
414
  ## Customization Patterns
360
415
 
361
416
  ### Extending Button
362
417
 
363
418
  ```tsx
364
- // src/components/ui/button.tsx - add variant
419
+ // src/components/ui/button.tsx add to the existing cva variants block
365
420
  const buttonVariants = cva(
366
421
  "...",
367
422
  {
368
423
  variants: {
369
424
  variant: {
370
- // ... existing variants
371
- envelope: "bg-blue-600/20 text-blue-400 border border-blue-600/30 hover:bg-blue-600/30",
425
+ // ... default | outline | secondary | ghost | destructive | link
426
+ brand: "bg-tertiary text-on-tertiary hover:bg-tertiary/80",
372
427
  },
373
428
  },
374
429
  }
@@ -378,20 +433,17 @@ const buttonVariants = cva(
378
433
  ### Custom Card Variant
379
434
 
380
435
  ```tsx
381
- export function EnvelopeCardVariant({
382
- children,
383
- isNested,
384
- }: {
436
+ import { Card } from "@/components/ui/card";
437
+ import { cn } from "@/lib/utils";
438
+
439
+ interface NestedCardProps {
385
440
  children: React.ReactNode;
386
441
  isNested?: boolean;
387
- }) {
442
+ }
443
+
444
+ export function NestedCard({ children, isNested }: NestedCardProps) {
388
445
  return (
389
- <Card
390
- className={cn(
391
- "bg-[#0f0f14] border-[#1e293b]",
392
- isNested && "ml-4 border-l-2 border-l-blue-500/30"
393
- )}
394
- >
446
+ <Card className={cn(isNested && "ml-4 border-l-2 border-l-primary")}>
395
447
  {children}
396
448
  </Card>
397
449
  );
@@ -403,20 +455,24 @@ export function EnvelopeCardVariant({
403
455
  ### Two-Panel Layout
404
456
 
405
457
  ```tsx
406
- export function WorkspaceLayout() {
458
+ import { ScrollArea } from "@/components/ui/scroll-area";
459
+
460
+ export function WorkspaceLayout({ actors, signals }: { actors: Actor[]; signals: Signal[] }) {
407
461
  return (
408
- <div className="h-screen flex flex-col bg-[#0a0a0f]">
409
- {/* Top Panel - Agent Tabs */}
410
- <div className="flex-none h-[40%] border-b border-[#1e293b] p-4">
411
- <AgentTabs />
462
+ <div className="h-screen flex flex-col bg-background">
463
+ <div
464
+ className="flex-none h-[40%] border-b p-4"
465
+ style={{ borderColor: 'var(--color-border)' }}
466
+ >
467
+ <ActorTabs actors={actors} />
412
468
  </div>
413
469
 
414
- {/* Bottom Panel - Envelopes & Logic */}
415
470
  <div className="flex-1 overflow-hidden p-4">
416
471
  <ScrollArea className="h-full">
417
- <EnvelopeList />
472
+ <SignalList signals={signals} />
418
473
  </ScrollArea>
419
474
  </div>
475
+ {/* ActorTabs / SignalList as defined above */}
420
476
  </div>
421
477
  );
422
478
  }
@@ -425,48 +481,36 @@ export function WorkspaceLayout() {
425
481
  ### Grid Layout
426
482
 
427
483
  ```tsx
428
- export function AgentGrid({ agents }: { agents: Agent[] }) {
484
+ import { ActorCard } from "./ActorCard";
485
+
486
+ export function ActorGrid({ actors }: { actors: Actor[] }) {
429
487
  return (
430
488
  <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
431
- {agents.map(agent => (
432
- <AgentCard key={agent.id} agent={agent} />
489
+ {actors.map(actor => (
490
+ <ActorCard key={actor.id} actor={actor} />
433
491
  ))}
434
492
  </div>
435
493
  );
436
494
  }
437
495
  ```
438
496
 
439
- ## Utils
440
-
441
- The project uses `cn()` utility for class merging:
442
-
443
- ```tsx
444
- // src/lib/utils.ts
445
- import { clsx, type ClassValue } from "clsx";
446
- import { twMerge } from "tailwind-merge";
447
-
448
- export function cn(...inputs: ClassValue[]) {
449
- return twMerge(clsx(inputs));
450
- }
451
-
452
- // Usage
453
- <div className={cn(
454
- "base-classes",
455
- isActive && "active-classes",
456
- className
457
- )} />
458
- ```
459
-
460
497
  ## Best Practices
461
498
 
462
- 1. **Use semantic colors**: Status colors for state, not random colors
463
- 2. **Consistent spacing**: Use Tailwind's spacing scale (4, 8, 12, 16...)
464
- 3. **Dark-first**: Design for dark theme, colors should work on `#0a0a0f`
465
- 4. **Monospace for data**: Use `font-mono` for IDs, JSON, code
466
- 5. **Subtle borders**: Use `border-[#1e293b]` for separation
467
- 6. **Animate pending**: Use `animate-pulse` for pending states
499
+ 1. **Let the primitive keep its surface**: `Card` already resolves to `foreground`
500
+ through `--color-card`. Adding `bg-*` on top fights the alias.
501
+ 2. **`text-font`, never `text-foreground`**: the one shadcn name the alias table
502
+ cannot rescue.
503
+ 3. **Contrast labels on brand fills**: `text-on-primary` in ONE code,
504
+ `text-primary-foreground` inside a CLI-generated primitive both resolve to
505
+ the same computed color.
506
+ 4. **Variants over overrides**: extend the `cva` block rather than passing a
507
+ className that re-colors the button.
508
+ 5. **Sweep after `shadcn add`**: the CLI bypasses the design hook.
509
+ 6. **Monospace for data**: `font-mono` for IDs, JSON, code.
510
+ 7. **Icons from lucide only**: via `<Icon>` / `<IconBadge>`, never inline SVG in
511
+ a React component.
468
512
 
469
513
  ---
470
514
 
471
- **Version**: 1.0.0
472
- **Tech**: shadcn/ui, Tailwind CSS 4, Radix UI
515
+ **Tech**: shadcn/ui (`style: radix-nova`) · `radix-ui` ^1.4.3 · Tailwind CSS 4 · React 19
516
+ **Tree**: `one.ie/web` for `template/site` use `template:shadcn`