@wrongstack/tools 0.313.0 → 0.316.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/dist/_edit-match.d.ts +3 -2
  2. package/dist/_output-spool.d.ts +4 -3
  3. package/dist/_shell-pick.d.ts +2 -1
  4. package/dist/_spawn-stream.d.ts +2 -1
  5. package/dist/_syntax-check.d.ts +2 -1
  6. package/dist/audit.js +10 -4055
  7. package/dist/bash-kill-guard.d.ts +3 -6
  8. package/dist/bash.js +9 -2308
  9. package/dist/batch-tool-use.js +2 -187
  10. package/dist/browser/index.js +25 -1339
  11. package/dist/browser/network-guard-proxy.d.ts +2 -1
  12. package/dist/builtin.js +69 -33949
  13. package/dist/chunk-22B7GE5T.js +260 -0
  14. package/dist/chunk-2VSZC6QM.js +113 -0
  15. package/dist/chunk-3PVYQFRQ.js +472 -0
  16. package/dist/chunk-42BHI7TN.js +337 -0
  17. package/dist/chunk-4BHUSMNL.js +104 -0
  18. package/dist/chunk-4I4LWFOO.js +431 -0
  19. package/dist/chunk-4UESMQDP.js +122 -0
  20. package/dist/chunk-553IQUMO.js +478 -0
  21. package/dist/chunk-5H4GSJAI.js +223 -0
  22. package/dist/chunk-6RNIFLG4.js +305 -0
  23. package/dist/chunk-7EY5DCRO.js +434 -0
  24. package/dist/chunk-A6BRWIXN.js +317 -0
  25. package/dist/chunk-AHHDWNXC.js +200 -0
  26. package/dist/chunk-BSLVR56S.js +199 -0
  27. package/dist/chunk-BTSFTGIL.js +7 -0
  28. package/dist/chunk-D33S4RQG.js +222 -0
  29. package/dist/chunk-DA4KNE2H.js +4412 -0
  30. package/dist/chunk-DR7JOQTC.js +520 -0
  31. package/dist/chunk-EEOFQDT6.js +898 -0
  32. package/dist/chunk-EJWSCQ6D.js +137 -0
  33. package/dist/chunk-EMRGN4KM.js +170 -0
  34. package/dist/chunk-FQZOHLG3.js +89 -0
  35. package/dist/chunk-GOIZNNOA.js +221 -0
  36. package/dist/chunk-HFXSNKCV.js +196 -0
  37. package/dist/chunk-HYX2TZ7O.js +1272 -0
  38. package/dist/chunk-I64BS3VC.js +15 -0
  39. package/dist/chunk-IVWV2UM6.js +955 -0
  40. package/dist/chunk-IXMNTNW5.js +238 -0
  41. package/dist/chunk-IYK7XGDZ.js +892 -0
  42. package/dist/chunk-J5SKD6LN.js +235 -0
  43. package/dist/chunk-JNNVRHMV.js +2111 -0
  44. package/dist/chunk-JOHXDF3D.js +295 -0
  45. package/dist/chunk-JRJJX3L5.js +424 -0
  46. package/dist/chunk-K3WNSHUF.js +1371 -0
  47. package/dist/chunk-L25CVUVR.js +2830 -0
  48. package/dist/chunk-LIJQMYYX.js +59 -0
  49. package/dist/chunk-LWKUTMD5.js +197 -0
  50. package/dist/chunk-MQX2KXVW.js +54 -0
  51. package/dist/chunk-MZZN7VCD.js +359 -0
  52. package/dist/chunk-NBDZMMG2.js +169 -0
  53. package/dist/chunk-NKJW5GFO.js +366 -0
  54. package/dist/chunk-NKNOBUBU.js +522 -0
  55. package/dist/chunk-O4MBV4AX.js +134 -0
  56. package/dist/chunk-OUBDL3WH.js +3515 -0
  57. package/dist/chunk-PQKK5JH7.js +101 -0
  58. package/dist/chunk-PY2IOS7C.js +1000 -0
  59. package/dist/chunk-Q5JPPCZC.js +12 -0
  60. package/dist/chunk-QBV725YG.js +128 -0
  61. package/dist/chunk-QZQSPUBF.js +315 -0
  62. package/dist/chunk-RGISBZBD.js +231 -0
  63. package/dist/chunk-RJZQWEMS.js +84 -0
  64. package/dist/chunk-RXISBFR5.js +315 -0
  65. package/dist/chunk-S5CCLZL3.js +99 -0
  66. package/dist/chunk-SDLVH5RZ.js +178 -0
  67. package/dist/chunk-T2F4S7U4.js +1723 -0
  68. package/dist/chunk-TEBQ4VPZ.js +163 -0
  69. package/dist/chunk-U4D5S3VQ.js +21 -0
  70. package/dist/chunk-U4VAATKP.js +193 -0
  71. package/dist/chunk-UCYQTZ7F.js +113 -0
  72. package/dist/chunk-UKU2ZX4C.js +203 -0
  73. package/dist/chunk-UNSKG6DC.js +159 -0
  74. package/dist/chunk-V43EQ6VR.js +68 -0
  75. package/dist/chunk-VB3MJGCV.js +610 -0
  76. package/dist/chunk-VFKPWSOX.js +154 -0
  77. package/dist/chunk-VJNHFZ7J.js +190 -0
  78. package/dist/chunk-VXECAJJ7.js +1091 -0
  79. package/dist/chunk-WHIIIREL.js +223 -0
  80. package/dist/chunk-Z6DAKQ3U.js +1 -0
  81. package/dist/chunk-ZJQ4IGXK.js +474 -0
  82. package/dist/chunk-ZLTFLC25.js +385 -0
  83. package/dist/circuit-breaker.js +3 -191
  84. package/dist/codebase-index/ast-invariant-engine.d.ts +5 -4
  85. package/dist/codebase-index/binary-frame.d.ts +0 -2
  86. package/dist/codebase-index/bm25.d.ts +1 -1
  87. package/dist/codebase-index/circuit-breaker.d.ts +2 -1
  88. package/dist/codebase-index/codebase-ast-replace-tool.d.ts +3 -2
  89. package/dist/codebase-index/codebase-impact-analysis-tool.d.ts +4 -3
  90. package/dist/codebase-index/codebase-invariant-check-tool.d.ts +3 -2
  91. package/dist/codebase-index/codebase-repo-map-tool.d.ts +3 -2
  92. package/dist/codebase-index/codebase-skeleton-tool.d.ts +3 -2
  93. package/dist/codebase-index/codebase-targeted-test-tool.d.ts +3 -2
  94. package/dist/codebase-index/content-hash.d.ts +0 -2
  95. package/dist/codebase-index/import-extractor.d.ts +0 -13
  96. package/dist/codebase-index/index-service.d.ts +1 -1
  97. package/dist/codebase-index/index.js +84 -13688
  98. package/dist/codebase-index/languages.d.ts +2 -1
  99. package/dist/codebase-index/module-roots.d.ts +3 -2
  100. package/dist/codebase-index/parser-batch.d.ts +0 -5
  101. package/dist/codebase-index/parser-dispatch.d.ts +2 -1
  102. package/dist/codebase-index/parser-output.d.ts +4 -3
  103. package/dist/codebase-index/parser-worker-pool.d.ts +0 -2
  104. package/dist/codebase-index/parser-worker-script.d.ts +1 -16
  105. package/dist/codebase-index/parser-worker-script.js +8 -3995
  106. package/dist/codebase-index/project-server-client-state.d.ts +2 -2
  107. package/dist/codebase-index/project-server-endpoint.d.ts +0 -15
  108. package/dist/codebase-index/project-server.js +60 -8548
  109. package/dist/codebase-index/tree-sitter/visitor.d.ts +2 -1
  110. package/dist/codebase-index/tree-sitter-parser.d.ts +0 -2
  111. package/dist/codebase-index/ts-parser.d.ts +1 -1
  112. package/dist/codebase-index/vector-search.d.ts +2 -1
  113. package/dist/codebase-index/wal-maintenance.d.ts +3 -2
  114. package/dist/codebase-index/worker.js +20 -8416
  115. package/dist/codebase-index/writer-admin.d.ts +0 -1
  116. package/dist/codebase-index/writer-search.d.ts +0 -9
  117. package/dist/design.js +2 -299
  118. package/dist/diff.js +4 -256
  119. package/dist/document.js +4 -222
  120. package/dist/e2e.js +5 -476
  121. package/dist/edit.js +14 -10200
  122. package/dist/exec.js +16 -3131
  123. package/dist/fetch.js +8 -398
  124. package/dist/format.js +10 -3750
  125. package/dist/generic-parser-VUXDIAOZ.js +13 -0
  126. package/dist/git.js +4 -380
  127. package/dist/glob.js +6 -280
  128. package/dist/go-parser-JXYKJHRC.js +469 -0
  129. package/dist/grep.js +7 -604
  130. package/dist/index.js +318 -35387
  131. package/dist/install.js +10 -4091
  132. package/dist/json-parser-IBHZ4BZC.js +213 -0
  133. package/dist/json.js +4 -665
  134. package/dist/kanban-contract-actions.d.ts +1 -1
  135. package/dist/kanban-detail-actions.d.ts +2 -1
  136. package/dist/kanban-presence.d.ts +2 -1
  137. package/dist/kanban-serializer.d.ts +0 -8
  138. package/dist/kanban-split-task-handler.d.ts +2 -2
  139. package/dist/kanban-tool-types.d.ts +2 -1
  140. package/dist/kanban.js +3 -2096
  141. package/dist/languages/diagnostics.d.ts +2 -1
  142. package/dist/languages/index.js +23 -4664
  143. package/dist/languages/legacy-bridge.d.ts +3 -2
  144. package/dist/languages/types.d.ts +2 -1
  145. package/dist/legacy-bridge-7M6QLUQN.js +18 -0
  146. package/dist/lint.js +10 -3706
  147. package/dist/logs.js +4 -287
  148. package/dist/memory.js +6 -215
  149. package/dist/mode.js +3 -99
  150. package/dist/outdated.js +4 -5170
  151. package/dist/pack.js +65 -33897
  152. package/dist/parser-dispatch-QH4XPGG6.js +14 -0
  153. package/dist/patch.js +13 -9935
  154. package/dist/plan.js +5 -3286
  155. package/dist/process-registry.js +8 -651
  156. package/dist/ps-slash.js +12 -1439
  157. package/dist/pwsh.d.ts +0 -1
  158. package/dist/py-parser-IS4HKYMF.js +16 -0
  159. package/dist/read.js +13 -9816
  160. package/dist/replace.js +15 -10014
  161. package/dist/rs-parser-XHUUO2KZ.js +81 -0
  162. package/dist/scaffold.js +4 -253
  163. package/dist/search.js +5 -585
  164. package/dist/session-kanban-sync.d.ts +0 -6
  165. package/dist/session-kanban.js +30 -972
  166. package/dist/skill.js +2 -215
  167. package/dist/spawn-background.d.ts +1 -1
  168. package/dist/task.js +5 -3410
  169. package/dist/test.js +10 -3773
  170. package/dist/todo.js +4 -2891
  171. package/dist/tool-help.js +3 -123
  172. package/dist/tool-search.js +3 -79
  173. package/dist/tool-tier.js +68 -33984
  174. package/dist/tool-use.js +2 -93
  175. package/dist/tree-sitter-parser-AIERW3YI.js +15 -0
  176. package/dist/tree.js +4 -288
  177. package/dist/ts-parser-RCTYKSVI.js +232 -0
  178. package/dist/typecheck.js +10 -3753
  179. package/dist/win32.js +6 -60
  180. package/dist/write.js +14 -9882
  181. package/dist/yaml-parser-4SAXV3PL.js +157 -0
  182. package/package.json +5 -5
@@ -0,0 +1,305 @@
1
+ // src/design.ts
2
+ import * as fs from "node:fs/promises";
3
+ import * as path from "node:path";
4
+ import {
5
+ applyTokenOverrides,
6
+ getDesignKitLoader,
7
+ isDesignStack,
8
+ loadActiveKit,
9
+ materializeTokens,
10
+ recordKitChoice,
11
+ recordOverrides,
12
+ resolveSemanticTune,
13
+ runDesignVerify,
14
+ setActiveKit,
15
+ setDesignOverrides
16
+ } from "@wrongstack/core/design";
17
+ async function resolveReal(p) {
18
+ const resolved = path.resolve(p);
19
+ let probe = resolved;
20
+ const missing = [];
21
+ for (; ; ) {
22
+ try {
23
+ return path.resolve(await fs.realpath(probe), ...missing);
24
+ } catch (err) {
25
+ if (err.code === "ENOENT") {
26
+ const parent = path.dirname(probe);
27
+ if (parent === probe) return resolved;
28
+ missing.unshift(path.basename(probe));
29
+ probe = parent;
30
+ continue;
31
+ }
32
+ return resolved;
33
+ }
34
+ }
35
+ }
36
+ function normalizeOverrides(set) {
37
+ const out = {};
38
+ if (set && typeof set === "object") {
39
+ for (const [k, v] of Object.entries(set)) {
40
+ if (typeof v === "string") out[k] = v;
41
+ }
42
+ }
43
+ return out;
44
+ }
45
+ var designTool = {
46
+ name: "design",
47
+ category: "Design",
48
+ description: 'Browse, load, customize, and enforce curated frontend/mobile UI design kits. Use BEFORE writing UI code to commit to one coherent, modern, responsive, dark/light, accessible design. Actions: "list" (menu), "use" (load+pin a kit for a stack), "foundations" (baseline), "set" (override kit colors/tokens), "materialize" (write the tokens to a real theme file \u2014 CSS @theme/OKLCH or native), "verify" (scan UI files for off-palette colors).',
49
+ usageHint: 'Flow: `design {action:"use", kit:"minimal-clarity", stack:"web"}` \u2192 optionally `design {action:"set", set:{primary:"oklch(62% 0.2 25)"}}` \u2192 `design {action:"materialize"}` to write tokens to disk \u2192 implement against them \u2192 `design {action:"verify"}`.',
50
+ permission: "confirm",
51
+ // WS-046: gives permission decisions something to key on.
52
+ // The action performed; `out` is optional so it cannot be the subject.
53
+ subjectKey: "action",
54
+ mutating: true,
55
+ capabilities: ["fs.write"],
56
+ timeoutMs: 15e3,
57
+ inputSchema: {
58
+ type: "object",
59
+ properties: {
60
+ action: {
61
+ type: "string",
62
+ enum: ["list", "use", "foundations", "set", "tune", "materialize", "verify"],
63
+ description: "list = menu; use = load+pin a kit; foundations = baseline; set = override colors/tokens; tune = high-level knobs (radius/density/font/motion); materialize = write tokens to a theme file; verify = scan UI for token drift. Default: list."
64
+ },
65
+ kit: {
66
+ type: "string",
67
+ description: 'Kit id (required for "use"), e.g. "minimal-clarity", "neo-brutalist".'
68
+ },
69
+ stack: {
70
+ type: "string",
71
+ enum: ["web", "react-native", "flutter", "swiftui", "compose"],
72
+ description: "Target stack \u2014 narrows guidance + materialize format. Default: web."
73
+ },
74
+ set: {
75
+ type: "object",
76
+ description: 'Token overrides for "set"/"use": { "primary": "oklch(\u2026)", "dark.bg": "#111" }. Bare key = both themes; "light."/"dark." prefix = that theme only. Empty value clears an override.',
77
+ additionalProperties: { type: "string" }
78
+ },
79
+ tune: {
80
+ type: "object",
81
+ description: 'High-level knobs for "tune": { "radius": "lg", "density": "compact", "font": "Space Grotesk", "motion": "snappy" }. radius = none|sm|md|lg|xl|full or a base length; density = compact|cozy|comfortable; motion = snappy|smooth|none. Resolved to concrete token overrides.',
82
+ properties: {
83
+ radius: { type: "string" },
84
+ density: { type: "string" },
85
+ font: { type: "string" },
86
+ motion: { type: "string" }
87
+ }
88
+ },
89
+ out: {
90
+ type: "string",
91
+ description: "Materialize output path (project-relative). Defaults to a per-stack convention."
92
+ },
93
+ force: {
94
+ type: "boolean",
95
+ description: "Materialize: overwrite an existing file (default false \u2014 refuses to clobber)."
96
+ },
97
+ files: {
98
+ type: "array",
99
+ items: { type: "string" },
100
+ description: "Verify: explicit project-relative files to scan. Default: a bounded UI-file walk."
101
+ }
102
+ },
103
+ required: []
104
+ },
105
+ async execute(input, ctx) {
106
+ const loader = getDesignKitLoader(ctx.projectRoot);
107
+ const action = input.action ?? "list";
108
+ const stack = input.stack && isDesignStack(input.stack) ? input.stack : void 0;
109
+ if (action === "foundations") {
110
+ const text = await loader.foundationsText(stack);
111
+ return { action, stack, output: text || "No foundations document is installed." };
112
+ }
113
+ if (action === "use") {
114
+ const kitId = input.kit?.trim();
115
+ if (!kitId) {
116
+ const menu2 = await loader.menuText();
117
+ return { action, output: `No kit id provided.
118
+
119
+ ${menu2}` };
120
+ }
121
+ const manifest = await loader.find(kitId);
122
+ if (!manifest) {
123
+ const menu2 = await loader.menuText();
124
+ return { action, kit: kitId, output: `Kit "${kitId}" not found.
125
+
126
+ ${menu2}` };
127
+ }
128
+ const resolvedStack = stack ?? manifest.stacks[0] ?? "web";
129
+ const body = await loader.readBody(manifest.id, resolvedStack);
130
+ const rawTokens = await loader.readTokens(manifest.id);
131
+ const persisted = await loadActiveKit(ctx.projectRoot);
132
+ const keepOverrides = persisted?.kit === manifest.id ? persisted.overrides ?? {} : {};
133
+ const overrides = { ...keepOverrides, ...normalizeOverrides(input.set) };
134
+ const tokens = rawTokens ? applyTokenOverrides(rawTokens, overrides) : rawTokens;
135
+ setActiveKit(ctx, manifest.id, resolvedStack, overrides);
136
+ await recordKitChoice(
137
+ ctx.projectRoot,
138
+ manifest.id,
139
+ resolvedStack,
140
+ "design-tool",
141
+ (/* @__PURE__ */ new Date()).toISOString(),
142
+ Object.keys(overrides).length ? overrides : void 0
143
+ );
144
+ const ovLine = Object.keys(overrides).length ? `
145
+ Active color overrides: ${Object.entries(overrides).map(([k, v]) => `${k}=${v}`).join(", ")}
146
+ ` : "";
147
+ const header = `# Active design kit: ${manifest.name} (${manifest.id}) \u2014 stack: ${resolvedStack}
148
+ ${manifest.aesthetic}
149
+ ${ovLine}
150
+ Implement the UI faithfully to this spec. Keep light/dark, responsive, and WCAG AA.
151
+ `;
152
+ const tokenBlock = tokens ? `
153
+ ## Token snapshot (overrides applied)
154
+ \`\`\`json
155
+ ${JSON.stringify(tokens, null, 2)}
156
+ \`\`\`
157
+ Tip: run \`design {action:"materialize"}\` to write these tokens to a real theme file.
158
+ ` : "";
159
+ return {
160
+ action,
161
+ kit: manifest.id,
162
+ stack: resolvedStack,
163
+ output: `${header}${tokenBlock}
164
+ ${body}`
165
+ };
166
+ }
167
+ if (action === "set") {
168
+ const patch = normalizeOverrides(input.set);
169
+ if (Object.keys(patch).length === 0) {
170
+ return { action, output: 'No overrides given. Pass set:{ "primary": "oklch(\u2026)" }.' };
171
+ }
172
+ const merged = await recordOverrides(ctx.projectRoot, patch, (/* @__PURE__ */ new Date()).toISOString());
173
+ if (!merged) {
174
+ return {
175
+ action,
176
+ output: 'No active kit. Pick one first: `design {action:"use", kit:"<id>"}`.'
177
+ };
178
+ }
179
+ setDesignOverrides(ctx, merged);
180
+ return {
181
+ action,
182
+ output: `Overrides updated. Active overrides: ${Object.entries(merged).map(([k, v]) => `${k}=${v}`).join(", ")}
183
+ These win over kit tokens. Run \`design {action:"materialize"}\` to write them to a theme file.`
184
+ };
185
+ }
186
+ if (action === "tune") {
187
+ const patch = resolveSemanticTune(input.tune ?? {});
188
+ if (Object.keys(patch).length === 0) {
189
+ return {
190
+ action,
191
+ output: 'No recognized knobs. Pass tune:{ radius:"lg", density:"compact", font:"\u2026", motion:"snappy" }.'
192
+ };
193
+ }
194
+ const merged = await recordOverrides(ctx.projectRoot, patch, (/* @__PURE__ */ new Date()).toISOString());
195
+ if (!merged) {
196
+ return {
197
+ action,
198
+ output: 'No active kit. Pick one first: `design {action:"use", kit:"<id>"}`.'
199
+ };
200
+ }
201
+ setDesignOverrides(ctx, merged);
202
+ return {
203
+ action,
204
+ output: `Tuned. Resolved ${Object.keys(patch).length} token override(s): ${Object.entries(patch).map(([k, v]) => `${k}=${v}`).join(", ")}
205
+ Run \`design {action:"materialize"}\` to write the tuned tokens to your theme file.`
206
+ };
207
+ }
208
+ if (action === "materialize") {
209
+ const active = await loadActiveKit(ctx.projectRoot);
210
+ if (!active) {
211
+ return {
212
+ action,
213
+ output: 'No active kit. Pick one first: `design {action:"use", kit:"<id>"}`.'
214
+ };
215
+ }
216
+ const resolvedStack = stack ?? (active.stack && isDesignStack(active.stack) ? active.stack : "web");
217
+ const rawTokens = await loader.readTokens(active.kit);
218
+ if (!rawTokens) {
219
+ return { action, kit: active.kit, output: `Kit "${active.kit}" has no tokens.json.` };
220
+ }
221
+ const tokens = applyTokenOverrides(rawTokens, active.overrides);
222
+ const result = materializeTokens({
223
+ tokens,
224
+ stack: resolvedStack,
225
+ kitId: active.kit,
226
+ outPath: input.out
227
+ });
228
+ const root = await resolveReal(ctx.projectRoot);
229
+ const absResolved = path.isAbsolute(result.path) ? path.resolve(result.path) : path.resolve(path.join(ctx.projectRoot, result.path));
230
+ const absParent = await resolveReal(path.dirname(absResolved));
231
+ const abs = path.join(absParent, path.basename(absResolved));
232
+ const rel = path.relative(root, abs);
233
+ if (rel.startsWith("..") || path.isAbsolute(rel)) {
234
+ throw new Error(`design: materialize path "${result.path}" would escape the project root`);
235
+ }
236
+ let exists = false;
237
+ try {
238
+ await fs.access(abs);
239
+ exists = true;
240
+ } catch {
241
+ }
242
+ if (exists && !input.force) {
243
+ return {
244
+ action,
245
+ kit: active.kit,
246
+ stack: resolvedStack,
247
+ path: result.path,
248
+ output: `${result.path} already exists. Re-run with force:true to overwrite, or write this ${result.format} yourself:
249
+
250
+ \`\`\`
251
+ ${result.content}
252
+ \`\`\``
253
+ };
254
+ }
255
+ await fs.mkdir(path.dirname(abs), { recursive: true });
256
+ await fs.writeFile(abs, result.content);
257
+ return {
258
+ action,
259
+ kit: active.kit,
260
+ stack: resolvedStack,
261
+ path: result.path,
262
+ output: `Wrote ${result.format} to ${result.path}. Import these tokens in your UI so the kit palette is the source of truth. ${exists ? "(overwrote existing file)" : ""}`
263
+ };
264
+ }
265
+ if (action === "verify") {
266
+ const active = await loadActiveKit(ctx.projectRoot);
267
+ if (!active) {
268
+ return {
269
+ action,
270
+ output: 'No active kit to verify against. Pick one: `design {action:"use", kit:"<id>"}`.'
271
+ };
272
+ }
273
+ const rawTokens = await loader.readTokens(active.kit);
274
+ if (!rawTokens) {
275
+ return { action, kit: active.kit, output: `Kit "${active.kit}" has no tokens.json.` };
276
+ }
277
+ const tokens = applyTokenOverrides(rawTokens, active.overrides);
278
+ const report = await runDesignVerify(ctx.projectRoot, tokens, input.files);
279
+ const pct = Math.round(report.score * 100);
280
+ const top = report.violations.slice(0, 25).map((v) => ` ${v.file}:${v.line} \u2014 ${v.reason}: ${v.snippet}`).join("\n");
281
+ const summary = `Adherence: ${pct}% on-palette across ${report.filesScanned} file(s). ${report.violations.length} violation(s).` + (report.violations.length ? `
282
+ ${top}${report.violations.length > 25 ? `
283
+ \u2026and ${report.violations.length - 25} more` : ""}
284
+
285
+ Replace off-palette colors with kit tokens (or the materialized CSS vars / token utilities).` : "\nNo off-palette colors found \u2014 UI adheres to the kit palette.");
286
+ return {
287
+ action,
288
+ kit: active.kit,
289
+ output: summary,
290
+ score: report.score,
291
+ violations: report.violations.length
292
+ };
293
+ }
294
+ const menu = await loader.menuText();
295
+ return {
296
+ action: "list",
297
+ output: (menu || "No design kits are installed.") + '\n\nLoad one with `design {action:"use", kit:"<id>", stack:"<stack>"}`.'
298
+ };
299
+ }
300
+ };
301
+
302
+ export {
303
+ designTool
304
+ };
305
+ //# sourceMappingURL=chunk-6RNIFLG4.js.map