total-recall-brain 3.35.0 → 3.37.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.
- package/bin/total-recall.mjs +17 -4
- package/frontend/dist/assets/index-CpvEw3iA.js +5786 -0
- package/frontend/dist/brand/plugins/phone.svg +20 -0
- package/frontend/dist/index.html +1 -1
- package/frontend/src/App.tsx +3 -30
- package/frontend/src/api/plugins.ts +18 -0
- package/frontend/src/components/plugins/previews/CodeQualityPreview.tsx +78 -86
- package/frontend/src/components/plugins/previews/ComposableCliPreview.tsx +74 -84
- package/frontend/src/components/plugins/previews/DecisionPreview.tsx +158 -106
- package/frontend/src/components/plugins/previews/DesignPreview.tsx +109 -75
- package/frontend/src/components/plugins/previews/DomainsPreview.tsx +69 -88
- package/frontend/src/components/plugins/previews/ImageGeneratorPreview.tsx +286 -0
- package/frontend/src/components/plugins/previews/PhonePreview.tsx +490 -76
- package/frontend/src/components/plugins/previews/SigningPreview.tsx +164 -50
- package/frontend/src/components/plugins/previews/TextPreview.tsx +85 -86
- package/frontend/src/components/plugins/previews/UserAutomationsPreview.tsx +30 -0
- package/frontend/src/components/plugins/previews/index.tsx +6 -1
- package/frontend/src/pages/PluginsPage.tsx +603 -136
- package/package.json +2 -5
- package/scaffold/.agent/skills/plugins/SKILL.md +200 -6
- package/src/cli/agent.mjs +59 -18
- package/src/cli/plugin/create.mjs +266 -13
- package/src/cli/plugin/index.mjs +5 -0
- package/src/cli/secret.mjs +28 -1
- package/src/core/agent-manager.mjs +47 -6
- package/src/core/cache-prune.mjs +60 -2
- package/src/core/embeddings.mjs +2 -0
- package/src/core/meta-harness.mjs +93 -6
- package/src/core/plugin-loader.mjs +20 -4
- package/src/core/plugin-store.mjs +122 -11
- package/src/core/surface.mjs +29 -1
- package/src/core/vault.mjs +6 -2
- package/src/server/route-manifest.json +22 -2
- package/src/server/routes/plugins-mesh.mjs +9 -1
- package/src/server/routes/plugins.mjs +65 -1
- package/frontend/dist/assets/index-BPrkIYkZ.js +0 -5786
- package/frontend/src/pages/AutomationsPage.spec.tsx +0 -61
- package/frontend/src/pages/AutomationsPage.tsx +0 -354
- package/plugins/creative-search/README.md +0 -33
- package/plugins/creative-search/cli.mjs +0 -415
- package/plugins/creative-search/config.mjs +0 -129
- package/plugins/creative-search/generator.mjs +0 -13
- package/plugins/creative-search/plugin.json +0 -61
- package/plugins/creative-search/ui/DESIGN.md +0 -50
- package/plugins/creative-search/ui/csearch-main.js +0 -314
- package/plugins/creative-search/ui/csearch-settings.js +0 -392
- package/plugins/creative-search/ui/index.js +0 -2
- package/plugins/creative-search/ui/tokens.css +0 -34
- package/plugins/dsh/README.md +0 -20
- package/plugins/dsh/cli.mjs +0 -232
- package/plugins/dsh/generator.mjs +0 -65
- package/plugins/dsh/plugin.json +0 -57
- package/plugins/dsh/ui/DESIGN.md +0 -48
- package/plugins/dsh/ui/dsh-main.js +0 -226
- package/plugins/dsh/ui/dsh-status.js +0 -265
- package/plugins/dsh/ui/index.js +0 -2
- package/plugins/dsh/ui/tokens.css +0 -32
- package/plugins/git-sentinel/README.md +0 -29
- package/plugins/git-sentinel/cli.mjs +0 -89
- package/plugins/git-sentinel/plugin.json +0 -18
- package/plugins/operator-alerts/README.md +0 -32
- package/plugins/operator-alerts/cli.mjs +0 -57
- package/plugins/operator-alerts/notify-core.mjs +0 -216
- package/plugins/operator-alerts/plugin.json +0 -20
- package/plugins/skill-manager/README.md +0 -57
- package/plugins/skill-manager/cli.mjs +0 -123
- package/plugins/skill-manager/plugin.json +0 -25
- package/plugins/skill-manager/route.mjs +0 -106
- package/plugins/system-monitor/README.md +0 -28
- package/plugins/system-monitor/cli.mjs +0 -80
- package/plugins/system-monitor/generator.mjs +0 -19
- package/plugins/system-monitor/plugin.json +0 -29
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { useState, type CSSProperties } from "react"
|
|
2
|
+
import { runPluginCommand } from "../../../api"
|
|
2
3
|
|
|
3
4
|
const styles: Record<string, CSSProperties> = {
|
|
4
5
|
container: {
|
|
5
|
-
background: "linear-gradient(135deg, #
|
|
6
|
+
background: "linear-gradient(135deg, #0a1628, #1a1a2e)",
|
|
6
7
|
borderRadius: "12px",
|
|
7
8
|
padding: "24px",
|
|
8
|
-
fontFamily: "var(--font-
|
|
9
|
+
fontFamily: "var(--font-mono, 'SF Mono', monospace)",
|
|
9
10
|
color: "#e0e0e0",
|
|
10
|
-
maxWidth: "
|
|
11
|
+
maxWidth: "580px",
|
|
11
12
|
},
|
|
12
13
|
header: {
|
|
13
14
|
display: "flex",
|
|
14
15
|
justifyContent: "space-between",
|
|
16
|
+
alignItems: "center",
|
|
15
17
|
marginBottom: "16px",
|
|
16
18
|
},
|
|
17
19
|
label: {
|
|
@@ -21,136 +23,186 @@ const styles: Record<string, CSSProperties> = {
|
|
|
21
23
|
letterSpacing: "1px",
|
|
22
24
|
},
|
|
23
25
|
badge: {
|
|
24
|
-
background: "#
|
|
25
|
-
color: "#
|
|
26
|
+
background: "#2a1a3a",
|
|
27
|
+
color: "#ce93d8",
|
|
26
28
|
padding: "4px 10px",
|
|
27
29
|
borderRadius: "20px",
|
|
28
30
|
fontSize: "11px",
|
|
31
|
+
fontWeight: 600,
|
|
29
32
|
},
|
|
30
|
-
|
|
33
|
+
table: {
|
|
34
|
+
width: "100%",
|
|
35
|
+
borderCollapse: "collapse" as const,
|
|
31
36
|
marginBottom: "16px",
|
|
32
37
|
},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
th: {
|
|
39
|
+
color: "#888",
|
|
40
|
+
fontSize: "11px",
|
|
41
|
+
textTransform: "uppercase" as const,
|
|
42
|
+
padding: "8px",
|
|
43
|
+
textAlign: "left" as const,
|
|
44
|
+
borderBottom: "1px solid #2a2a4a",
|
|
38
45
|
},
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
borderRadius: "3px",
|
|
44
|
-
background: "#2a2a4a",
|
|
45
|
-
outline: "none",
|
|
46
|
+
td: {
|
|
47
|
+
padding: "8px",
|
|
48
|
+
fontSize: "12px",
|
|
49
|
+
borderBottom: "1px solid #1a1a2e",
|
|
46
50
|
},
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
color: "#7c4dff",
|
|
51
|
-
minWidth: "36px",
|
|
52
|
-
textAlign: "center" as const,
|
|
51
|
+
slider: {
|
|
52
|
+
width: "100%",
|
|
53
|
+
accentColor: "#ab47bc",
|
|
53
54
|
},
|
|
54
|
-
|
|
55
|
+
winnerBox: {
|
|
55
56
|
background: "#0d1117",
|
|
56
|
-
border: "1px solid #
|
|
57
|
+
border: "1px solid #4a148c",
|
|
57
58
|
borderRadius: "8px",
|
|
58
|
-
padding: "
|
|
59
|
-
marginBottom: "8px",
|
|
60
|
-
},
|
|
61
|
-
stageHeader: {
|
|
59
|
+
padding: "14px",
|
|
62
60
|
display: "flex",
|
|
63
61
|
justifyContent: "space-between",
|
|
64
|
-
|
|
65
|
-
},
|
|
66
|
-
stageName: {
|
|
67
|
-
fontSize: "13px",
|
|
68
|
-
fontWeight: 600,
|
|
69
|
-
},
|
|
70
|
-
stageStatus: {
|
|
71
|
-
fontSize: "12px",
|
|
72
|
-
},
|
|
73
|
-
stageBar: {
|
|
74
|
-
height: "4px",
|
|
75
|
-
borderRadius: "2px",
|
|
76
|
-
background: "#2a2a4a",
|
|
77
|
-
overflow: "hidden" as const,
|
|
78
|
-
},
|
|
79
|
-
barFill: {
|
|
80
|
-
height: "100%",
|
|
81
|
-
borderRadius: "2px",
|
|
82
|
-
transition: "width 0.3s ease",
|
|
62
|
+
alignItems: "center",
|
|
83
63
|
},
|
|
84
|
-
|
|
85
|
-
fontSize: "
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
padding: "8px",
|
|
89
|
-
border: "1px dashed #2a2a4a",
|
|
90
|
-
borderRadius: "6px",
|
|
91
|
-
textAlign: "center" as const,
|
|
64
|
+
score: {
|
|
65
|
+
fontSize: "18px",
|
|
66
|
+
fontWeight: 700,
|
|
67
|
+
color: "#e1bee7",
|
|
92
68
|
},
|
|
93
69
|
}
|
|
94
70
|
|
|
95
|
-
interface DecisionStage {
|
|
96
|
-
name: string
|
|
97
|
-
score: number
|
|
98
|
-
passes: boolean
|
|
99
|
-
}
|
|
100
|
-
|
|
101
71
|
export function DecisionPreview() {
|
|
102
|
-
const [
|
|
72
|
+
const [weights, setWeights] = useState<Record<string, number>>({
|
|
73
|
+
Performance: 8,
|
|
74
|
+
Maintainability: 7,
|
|
75
|
+
Security: 9,
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
const [optAScores, setOptAScores] = useState<Record<string, number>>({
|
|
79
|
+
Performance: 9,
|
|
80
|
+
Maintainability: 7,
|
|
81
|
+
Security: 8,
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const [optBScores, setOptBScores] = useState<Record<string, number>>({
|
|
85
|
+
Performance: 7,
|
|
86
|
+
Maintainability: 9,
|
|
87
|
+
Security: 9,
|
|
88
|
+
})
|
|
103
89
|
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
{ name: "Semantic Coherence", score: 78, passes: 78 >= threshold },
|
|
107
|
-
{ name: "Mesh Consensus", score: 45, passes: 45 >= threshold },
|
|
108
|
-
]
|
|
90
|
+
const [evaluating, setEvaluating] = useState(false)
|
|
91
|
+
const [output, setOutput] = useState<string | null>(null)
|
|
109
92
|
|
|
110
|
-
const
|
|
93
|
+
const calcWeightedScore = (scores: Record<string, number>) => {
|
|
94
|
+
let sum = 0
|
|
95
|
+
let totalWeight = 0
|
|
96
|
+
for (const [k, w] of Object.entries(weights)) {
|
|
97
|
+
sum += (scores[k] || 0) * w
|
|
98
|
+
totalWeight += w
|
|
99
|
+
}
|
|
100
|
+
return totalWeight > 0 ? (sum / totalWeight).toFixed(2) : "0.00"
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const scoreA = parseFloat(calcWeightedScore(optAScores))
|
|
104
|
+
const scoreB = parseFloat(calcWeightedScore(optBScores))
|
|
105
|
+
const winner = scoreA >= scoreB ? "Option A" : "Option B"
|
|
106
|
+
|
|
107
|
+
const handleRunEvaluation = async () => {
|
|
108
|
+
setEvaluating(true)
|
|
109
|
+
try {
|
|
110
|
+
const res = await runPluginCommand("decision", "eval", [
|
|
111
|
+
`OptionA=${scoreA}`,
|
|
112
|
+
`OptionB=${scoreB}`,
|
|
113
|
+
])
|
|
114
|
+
setOutput(res.output || res.error || `Decision logged: Winner is ${winner}`)
|
|
115
|
+
} catch (err: any) {
|
|
116
|
+
setOutput(`Evaluation error: ${err?.message || "Check decision plugin"}`)
|
|
117
|
+
} finally {
|
|
118
|
+
setEvaluating(false)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
111
121
|
|
|
112
122
|
return (
|
|
113
123
|
<div style={styles.container}>
|
|
114
124
|
<div style={styles.header}>
|
|
115
|
-
<span style={styles.label}>Decision
|
|
116
|
-
<span style={
|
|
117
|
-
{allPass ? "Passed" : "Blocked"}
|
|
118
|
-
</span>
|
|
125
|
+
<span style={styles.label}>Typed Decision Matrix</span>
|
|
126
|
+
<span style={styles.badge}>Jev Evaluation</span>
|
|
119
127
|
</div>
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
<
|
|
123
|
-
<
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
<
|
|
145
|
-
|
|
128
|
+
|
|
129
|
+
<table style={styles.table}>
|
|
130
|
+
<thead>
|
|
131
|
+
<tr>
|
|
132
|
+
<th style={styles.th}>Criterion</th>
|
|
133
|
+
<th style={styles.th}>Weight</th>
|
|
134
|
+
<th style={styles.th}>Option A</th>
|
|
135
|
+
<th style={styles.th}>Option B</th>
|
|
136
|
+
</tr>
|
|
137
|
+
</thead>
|
|
138
|
+
<tbody>
|
|
139
|
+
{Object.keys(weights).map((c) => (
|
|
140
|
+
<tr key={c}>
|
|
141
|
+
<td style={styles.td}>{c}</td>
|
|
142
|
+
<td style={styles.td}>
|
|
143
|
+
<input
|
|
144
|
+
type="range"
|
|
145
|
+
min="1"
|
|
146
|
+
max="10"
|
|
147
|
+
value={weights[c]}
|
|
148
|
+
style={styles.slider}
|
|
149
|
+
onChange={(e) => setWeights({ ...weights, [c]: parseInt(e.target.value, 10) })}
|
|
150
|
+
/>
|
|
151
|
+
</td>
|
|
152
|
+
<td style={styles.td}>
|
|
153
|
+
<input
|
|
154
|
+
type="range"
|
|
155
|
+
min="1"
|
|
156
|
+
max="10"
|
|
157
|
+
value={optAScores[c]}
|
|
158
|
+
style={styles.slider}
|
|
159
|
+
onChange={(e) => setOptAScores({ ...optAScores, [c]: parseInt(e.target.value, 10) })}
|
|
160
|
+
/>
|
|
161
|
+
</td>
|
|
162
|
+
<td style={styles.td}>
|
|
163
|
+
<input
|
|
164
|
+
type="range"
|
|
165
|
+
min="1"
|
|
166
|
+
max="10"
|
|
167
|
+
value={optBScores[c]}
|
|
168
|
+
style={styles.slider}
|
|
169
|
+
onChange={(e) => setOptBScores({ ...optBScores, [c]: parseInt(e.target.value, 10) })}
|
|
170
|
+
/>
|
|
171
|
+
</td>
|
|
172
|
+
</tr>
|
|
173
|
+
))}
|
|
174
|
+
</tbody>
|
|
175
|
+
</table>
|
|
176
|
+
|
|
177
|
+
<div style={styles.winnerBox}>
|
|
178
|
+
<div>
|
|
179
|
+
<div style={{ fontSize: "11px", color: "#888" }}>RANKED OUTCOME</div>
|
|
180
|
+
<div style={{ fontSize: "16px", fontWeight: 700, color: "#fff" }}>
|
|
181
|
+
{winner} (Score: {Math.max(scoreA, scoreB)})
|
|
146
182
|
</div>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
183
|
+
</div>
|
|
184
|
+
<button
|
|
185
|
+
style={{
|
|
186
|
+
background: "linear-gradient(135deg, #7b1fa2, #4a148c)",
|
|
187
|
+
border: "none",
|
|
188
|
+
borderRadius: "6px",
|
|
189
|
+
padding: "8px 16px",
|
|
190
|
+
color: "#fff",
|
|
191
|
+
fontSize: "12px",
|
|
192
|
+
cursor: "pointer",
|
|
193
|
+
}}
|
|
194
|
+
onClick={handleRunEvaluation}
|
|
195
|
+
disabled={evaluating}
|
|
196
|
+
>
|
|
197
|
+
{evaluating ? "Evaluating…" : "Evaluate Decision"}
|
|
198
|
+
</button>
|
|
153
199
|
</div>
|
|
200
|
+
|
|
201
|
+
{output && (
|
|
202
|
+
<div style={{ marginTop: "12px", fontSize: "11px", color: "#ce93d8" }}>
|
|
203
|
+
{output}
|
|
204
|
+
</div>
|
|
205
|
+
)}
|
|
154
206
|
</div>
|
|
155
207
|
)
|
|
156
208
|
}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { type CSSProperties } from "react"
|
|
1
|
+
import { useState, type CSSProperties } from "react"
|
|
2
2
|
|
|
3
3
|
const styles: Record<string, CSSProperties> = {
|
|
4
4
|
container: {
|
|
5
|
-
background: "linear-gradient(135deg, #
|
|
5
|
+
background: "linear-gradient(135deg, #0a1628, #1a1a2e)",
|
|
6
6
|
borderRadius: "12px",
|
|
7
7
|
padding: "24px",
|
|
8
8
|
fontFamily: "var(--font-sans, system-ui, sans-serif)",
|
|
9
9
|
color: "#e0e0e0",
|
|
10
|
-
maxWidth: "
|
|
10
|
+
maxWidth: "540px",
|
|
11
11
|
},
|
|
12
12
|
header: {
|
|
13
13
|
display: "flex",
|
|
14
14
|
justifyContent: "space-between",
|
|
15
|
-
|
|
15
|
+
alignItems: "center",
|
|
16
|
+
marginBottom: "16px",
|
|
16
17
|
},
|
|
17
18
|
label: {
|
|
18
19
|
color: "#888",
|
|
@@ -21,97 +22,130 @@ const styles: Record<string, CSSProperties> = {
|
|
|
21
22
|
letterSpacing: "1px",
|
|
22
23
|
},
|
|
23
24
|
badge: {
|
|
24
|
-
background: "#
|
|
25
|
-
color: "#
|
|
25
|
+
background: "#3a2a1a",
|
|
26
|
+
color: "#ffb74d",
|
|
26
27
|
padding: "4px 10px",
|
|
27
28
|
borderRadius: "20px",
|
|
28
29
|
fontSize: "11px",
|
|
30
|
+
fontWeight: 600,
|
|
29
31
|
},
|
|
30
|
-
|
|
31
|
-
display: "
|
|
32
|
+
controlsGrid: {
|
|
33
|
+
display: "grid",
|
|
34
|
+
gridTemplateColumns: "1fr 1fr",
|
|
32
35
|
gap: "12px",
|
|
33
|
-
marginBottom: "20px",
|
|
34
|
-
flexWrap: "wrap" as const,
|
|
35
|
-
},
|
|
36
|
-
swatch: {
|
|
37
|
-
width: "44px",
|
|
38
|
-
height: "44px",
|
|
39
|
-
borderRadius: "10px",
|
|
40
|
-
border: "2px solid #2a2a4a",
|
|
41
|
-
},
|
|
42
|
-
typography: {
|
|
43
36
|
marginBottom: "16px",
|
|
44
37
|
},
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
marginBottom: "4px",
|
|
50
|
-
},
|
|
51
|
-
h2: {
|
|
52
|
-
fontSize: "18px",
|
|
53
|
-
fontWeight: 600,
|
|
54
|
-
color: "#d0d0ff",
|
|
55
|
-
marginBottom: "4px",
|
|
38
|
+
control: {
|
|
39
|
+
display: "flex",
|
|
40
|
+
flexDirection: "column",
|
|
41
|
+
gap: "4px",
|
|
56
42
|
},
|
|
57
|
-
|
|
58
|
-
fontSize: "
|
|
43
|
+
ctlLabel: {
|
|
44
|
+
fontSize: "11px",
|
|
59
45
|
color: "#aaa",
|
|
60
|
-
lineHeight: 1.6,
|
|
61
46
|
},
|
|
62
|
-
|
|
63
|
-
background: "
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
fontSize: "
|
|
69
|
-
|
|
70
|
-
},
|
|
71
|
-
labelSm: {
|
|
72
|
-
fontSize: "10px",
|
|
73
|
-
color: "#666",
|
|
74
|
-
textTransform: "uppercase" as const,
|
|
75
|
-
letterSpacing: "1px",
|
|
76
|
-
marginBottom: "8px",
|
|
47
|
+
input: {
|
|
48
|
+
background: "#0d1117",
|
|
49
|
+
border: "1px solid #2a2a4a",
|
|
50
|
+
borderRadius: "6px",
|
|
51
|
+
padding: "6px 10px",
|
|
52
|
+
color: "#fff",
|
|
53
|
+
fontSize: "12px",
|
|
54
|
+
fontFamily: "var(--font-mono, monospace)",
|
|
77
55
|
},
|
|
78
56
|
}
|
|
79
57
|
|
|
80
|
-
const swatches = [
|
|
81
|
-
{ name: "Primary", color: "#7c4dff" },
|
|
82
|
-
{ name: "Secondary", color: "#00bfa5" },
|
|
83
|
-
{ name: "Accent", color: "#ff6d00" },
|
|
84
|
-
{ name: "Surface", color: "#1a1a2e" },
|
|
85
|
-
{ name: "Error", color: "#ff1744" },
|
|
86
|
-
]
|
|
87
|
-
|
|
88
58
|
export function DesignPreview() {
|
|
59
|
+
const [primaryColor, setPrimaryColor] = useState("#ec4899")
|
|
60
|
+
const [borderRadius, setBorderRadius] = useState("10px")
|
|
61
|
+
const [surfaceBg, setSurfaceBg] = useState("#1e1e38")
|
|
62
|
+
const [accentText, setAccentText] = useState("Generative UI Active")
|
|
63
|
+
|
|
89
64
|
return (
|
|
90
65
|
<div style={styles.container}>
|
|
91
66
|
<div style={styles.header}>
|
|
92
|
-
<span style={styles.label}>Design
|
|
93
|
-
<span style={styles.badge}>
|
|
67
|
+
<span style={styles.label}>Design System & Token Playground</span>
|
|
68
|
+
<span style={styles.badge}>Live Tokens</span>
|
|
94
69
|
</div>
|
|
95
|
-
|
|
96
|
-
<div style={styles.
|
|
97
|
-
{
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
<div style={styles.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
70
|
+
|
|
71
|
+
<div style={styles.controlsGrid}>
|
|
72
|
+
<div style={styles.control}>
|
|
73
|
+
<label style={styles.ctlLabel}>--color-primary</label>
|
|
74
|
+
<input
|
|
75
|
+
type="color"
|
|
76
|
+
value={primaryColor}
|
|
77
|
+
onChange={(e) => setPrimaryColor(e.target.value)}
|
|
78
|
+
style={{ ...styles.input, height: "34px", padding: "2px", cursor: "pointer" }}
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
<div style={styles.control}>
|
|
82
|
+
<label style={styles.ctlLabel}>--border-radius</label>
|
|
83
|
+
<select
|
|
84
|
+
style={styles.input}
|
|
85
|
+
value={borderRadius}
|
|
86
|
+
onChange={(e) => setBorderRadius(e.target.value)}
|
|
87
|
+
>
|
|
88
|
+
<option value="4px">4px (Subtle)</option>
|
|
89
|
+
<option value="10px">10px (Default)</option>
|
|
90
|
+
<option value="18px">18px (Smooth)</option>
|
|
91
|
+
<option value="28px">28px (Pill)</option>
|
|
92
|
+
</select>
|
|
93
|
+
</div>
|
|
94
|
+
<div style={styles.control}>
|
|
95
|
+
<label style={styles.ctlLabel}>--surface-bg</label>
|
|
96
|
+
<input
|
|
97
|
+
type="color"
|
|
98
|
+
value={surfaceBg}
|
|
99
|
+
onChange={(e) => setSurfaceBg(e.target.value)}
|
|
100
|
+
style={{ ...styles.input, height: "34px", padding: "2px", cursor: "pointer" }}
|
|
101
|
+
/>
|
|
110
102
|
</div>
|
|
111
103
|
</div>
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
104
|
+
|
|
105
|
+
{/* Live Component styled solely by the active token values */}
|
|
106
|
+
<div
|
|
107
|
+
style={{
|
|
108
|
+
background: surfaceBg,
|
|
109
|
+
borderRadius: borderRadius,
|
|
110
|
+
border: `1px solid ${primaryColor}40`,
|
|
111
|
+
padding: "20px",
|
|
112
|
+
transition: "all 0.2s ease",
|
|
113
|
+
boxShadow: `0 4px 20px ${primaryColor}20`,
|
|
114
|
+
}}
|
|
115
|
+
>
|
|
116
|
+
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "10px" }}>
|
|
117
|
+
<span style={{ fontSize: "14px", fontWeight: 700, color: "#fff" }}>Dynamic Token Card</span>
|
|
118
|
+
<span
|
|
119
|
+
style={{
|
|
120
|
+
background: `${primaryColor}25`,
|
|
121
|
+
color: primaryColor,
|
|
122
|
+
borderRadius: borderRadius,
|
|
123
|
+
padding: "4px 8px",
|
|
124
|
+
fontSize: "11px",
|
|
125
|
+
fontWeight: 600,
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
Active
|
|
129
|
+
</span>
|
|
130
|
+
</div>
|
|
131
|
+
<div style={{ fontSize: "12px", color: "#bbb", marginBottom: "14px" }}>
|
|
132
|
+
Custom elements consume DESIGN.md tokens without modifying plugin source code.
|
|
133
|
+
</div>
|
|
134
|
+
<button
|
|
135
|
+
style={{
|
|
136
|
+
background: primaryColor,
|
|
137
|
+
color: "#fff",
|
|
138
|
+
border: "none",
|
|
139
|
+
borderRadius: borderRadius,
|
|
140
|
+
padding: "8px 16px",
|
|
141
|
+
fontSize: "12px",
|
|
142
|
+
fontWeight: 600,
|
|
143
|
+
cursor: "pointer",
|
|
144
|
+
}}
|
|
145
|
+
onClick={() => setAccentText(`Updated ${new Date().toLocaleTimeString()}`)}
|
|
146
|
+
>
|
|
147
|
+
{accentText}
|
|
148
|
+
</button>
|
|
115
149
|
</div>
|
|
116
150
|
</div>
|
|
117
151
|
)
|