@drewpayment/mink 0.1.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 (72) hide show
  1. package/README.md +347 -0
  2. package/package.json +32 -0
  3. package/src/cli.ts +176 -0
  4. package/src/commands/bug-search.ts +32 -0
  5. package/src/commands/config.ts +109 -0
  6. package/src/commands/cron.ts +295 -0
  7. package/src/commands/daemon.ts +46 -0
  8. package/src/commands/dashboard.ts +21 -0
  9. package/src/commands/designqc.ts +160 -0
  10. package/src/commands/detect-waste.ts +81 -0
  11. package/src/commands/framework-advisor.ts +52 -0
  12. package/src/commands/init.ts +159 -0
  13. package/src/commands/post-read.ts +123 -0
  14. package/src/commands/post-write.ts +157 -0
  15. package/src/commands/pre-read.ts +109 -0
  16. package/src/commands/pre-write.ts +136 -0
  17. package/src/commands/reflect.ts +39 -0
  18. package/src/commands/restore.ts +31 -0
  19. package/src/commands/scan.ts +101 -0
  20. package/src/commands/session-start.ts +21 -0
  21. package/src/commands/session-stop.ts +115 -0
  22. package/src/commands/status.ts +152 -0
  23. package/src/commands/update.ts +121 -0
  24. package/src/core/action-log.ts +341 -0
  25. package/src/core/backup.ts +122 -0
  26. package/src/core/bug-memory.ts +223 -0
  27. package/src/core/cron-parser.ts +94 -0
  28. package/src/core/daemon.ts +152 -0
  29. package/src/core/dashboard-api.ts +280 -0
  30. package/src/core/dashboard-server.ts +580 -0
  31. package/src/core/description.ts +232 -0
  32. package/src/core/design-eval/capture.ts +269 -0
  33. package/src/core/design-eval/route-detect.ts +165 -0
  34. package/src/core/design-eval/server-detect.ts +91 -0
  35. package/src/core/framework-advisor/catalog.ts +360 -0
  36. package/src/core/framework-advisor/decision-tree.ts +287 -0
  37. package/src/core/framework-advisor/generate.ts +132 -0
  38. package/src/core/framework-advisor/migration-prompts.ts +502 -0
  39. package/src/core/framework-advisor/validate.ts +137 -0
  40. package/src/core/fs-utils.ts +30 -0
  41. package/src/core/global-config.ts +74 -0
  42. package/src/core/index-store.ts +72 -0
  43. package/src/core/learning-memory.ts +120 -0
  44. package/src/core/paths.ts +86 -0
  45. package/src/core/pattern-engine.ts +108 -0
  46. package/src/core/project-id.ts +19 -0
  47. package/src/core/project-registry.ts +64 -0
  48. package/src/core/reflection.ts +256 -0
  49. package/src/core/scanner.ts +99 -0
  50. package/src/core/scheduler.ts +352 -0
  51. package/src/core/seed.ts +239 -0
  52. package/src/core/session.ts +128 -0
  53. package/src/core/stdin.ts +13 -0
  54. package/src/core/task-registry.ts +202 -0
  55. package/src/core/token-estimate.ts +36 -0
  56. package/src/core/token-ledger.ts +185 -0
  57. package/src/core/waste-detection.ts +214 -0
  58. package/src/core/write-exclusions.ts +24 -0
  59. package/src/types/action-log.ts +20 -0
  60. package/src/types/backup.ts +6 -0
  61. package/src/types/bug-memory.ts +24 -0
  62. package/src/types/config.ts +59 -0
  63. package/src/types/dashboard.ts +104 -0
  64. package/src/types/design-eval.ts +64 -0
  65. package/src/types/file-index.ts +38 -0
  66. package/src/types/framework-advisor.ts +97 -0
  67. package/src/types/hook-input.ts +27 -0
  68. package/src/types/learning-memory.ts +36 -0
  69. package/src/types/scheduler.ts +82 -0
  70. package/src/types/session.ts +50 -0
  71. package/src/types/token-ledger.ts +43 -0
  72. package/src/types/waste-detection.ts +21 -0
@@ -0,0 +1,91 @@
1
+ import { readFileSync } from "fs";
2
+ import { join } from "path";
3
+ import type { Subprocess } from "bun";
4
+ import { DEFAULT_PROBE_PORTS } from "../../types/design-eval";
5
+
6
+ /**
7
+ * Check if a port is responding to HTTP requests.
8
+ */
9
+ export async function probePort(port: number): Promise<boolean> {
10
+ try {
11
+ const controller = new AbortController();
12
+ const timeout = setTimeout(() => controller.abort(), 2000);
13
+ await fetch(`http://localhost:${port}`, { signal: controller.signal });
14
+ clearTimeout(timeout);
15
+ return true;
16
+ } catch {
17
+ return false;
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Probe common dev server ports and return the first responding URL.
23
+ */
24
+ export async function findRunningServer(
25
+ ports: number[] = DEFAULT_PROBE_PORTS
26
+ ): Promise<string | null> {
27
+ for (const port of ports) {
28
+ if (await probePort(port)) {
29
+ return `http://localhost:${port}`;
30
+ }
31
+ }
32
+ return null;
33
+ }
34
+
35
+ /**
36
+ * Read package.json scripts to find a likely dev server command.
37
+ * Checks for "dev", "start", "serve" in that priority order.
38
+ */
39
+ export function detectDevCommand(cwd: string): string | null {
40
+ try {
41
+ const raw = readFileSync(join(cwd, "package.json"), "utf-8");
42
+ const pkg = JSON.parse(raw);
43
+ const scripts = pkg.scripts;
44
+ if (!scripts || typeof scripts !== "object") return null;
45
+
46
+ for (const key of ["dev", "start", "serve"]) {
47
+ if (typeof scripts[key] === "string") {
48
+ // Return the npm/bun run command, not the raw script value
49
+ return `npm run ${key}`;
50
+ }
51
+ }
52
+ return null;
53
+ } catch {
54
+ return null;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Start a dev server and wait for it to become responsive.
60
+ * Returns the server URL and the spawned process.
61
+ */
62
+ export async function startAndWaitForServer(
63
+ cwd: string,
64
+ command: string,
65
+ timeoutMs: number = 30000
66
+ ): Promise<{ url: string; proc: Subprocess }> {
67
+ const parts = command.split(/\s+/);
68
+ const proc = Bun.spawn(parts, {
69
+ cwd,
70
+ stdout: "ignore",
71
+ stderr: "ignore",
72
+ stdin: "ignore",
73
+ });
74
+
75
+ const start = Date.now();
76
+ const ports = DEFAULT_PROBE_PORTS;
77
+
78
+ while (Date.now() - start < timeoutMs) {
79
+ for (const port of ports) {
80
+ if (await probePort(port)) {
81
+ return { url: `http://localhost:${port}`, proc };
82
+ }
83
+ }
84
+ await new Promise((r) => setTimeout(r, 500));
85
+ }
86
+
87
+ proc.kill();
88
+ throw new Error(
89
+ `[mink] Dev server did not respond within ${Math.round(timeoutMs / 1000)}s. Start it manually and retry.`
90
+ );
91
+ }
@@ -0,0 +1,360 @@
1
+ // ── Framework Catalog (Spec 14) ───────────────────────────────────────────
2
+
3
+ import type { FrameworkEntry } from "../../types/framework-advisor";
4
+
5
+ export const FRAMEWORK_CATALOG: FrameworkEntry[] = [
6
+ {
7
+ id: "tailwind-headlessui",
8
+ name: "Tailwind CSS + Headless UI",
9
+ description:
10
+ "Utility-first CSS framework paired with unstyled, accessible UI primitives for full design control.",
11
+ cssApproach: "utility-first",
12
+ darkModeSupport: true,
13
+ accessibilityRating: "excellent",
14
+ bundleSize: "small",
15
+ learningCurve: "low",
16
+ typescriptSupport: "native",
17
+ designTokens: false,
18
+ ecosystem: "React and Vue with first-party support from the Tailwind Labs team",
19
+ bestFor: [
20
+ "Custom designs that need full visual control",
21
+ "Accessible interactive components without opinionated styling",
22
+ "Projects already using Tailwind CSS",
23
+ ],
24
+ limitations: [
25
+ "Headless UI has a limited component set compared to full libraries",
26
+ "Requires building your own design system on top",
27
+ "No built-in theme or design token system",
28
+ ],
29
+ officialUrl: "https://headlessui.com",
30
+ },
31
+ {
32
+ id: "shadcn-ui",
33
+ name: "shadcn/ui",
34
+ description:
35
+ "Copy-paste component collection built on Radix primitives and Tailwind CSS that lives in your codebase.",
36
+ cssApproach: "utility-first",
37
+ darkModeSupport: true,
38
+ accessibilityRating: "excellent",
39
+ bundleSize: "small",
40
+ learningCurve: "low",
41
+ typescriptSupport: "native",
42
+ designTokens: false,
43
+ ecosystem: "React with Next.js-optimized CLI and growing community registry",
44
+ bestFor: [
45
+ "Rapid prototyping with production-quality components",
46
+ "Teams that want full ownership of component code",
47
+ "Next.js applications",
48
+ ],
49
+ limitations: [
50
+ "React-only with no official Vue or Svelte port",
51
+ "Components must be manually updated since they are copied into the project",
52
+ "Relies on Radix under the hood so inherits its constraints",
53
+ ],
54
+ officialUrl: "https://ui.shadcn.com",
55
+ },
56
+ {
57
+ id: "mui",
58
+ name: "Material UI (MUI)",
59
+ description:
60
+ "The most popular React component library, implementing Google's Material Design with deep customization.",
61
+ cssApproach: "css-in-js",
62
+ darkModeSupport: true,
63
+ accessibilityRating: "good",
64
+ bundleSize: "large",
65
+ learningCurve: "moderate",
66
+ typescriptSupport: "native",
67
+ designTokens: true,
68
+ ecosystem: "React with a mature ecosystem including MUI X for advanced data grids, date pickers, and charts",
69
+ bestFor: [
70
+ "Enterprise dashboards and admin panels",
71
+ "Teams that want a comprehensive component set out of the box",
72
+ "Material Design implementations",
73
+ ],
74
+ limitations: [
75
+ "Large bundle size even with tree-shaking",
76
+ "Emotion-based styling adds runtime overhead",
77
+ "Overriding deeply nested styles can be cumbersome",
78
+ ],
79
+ officialUrl: "https://mui.com",
80
+ },
81
+ {
82
+ id: "chakra-ui",
83
+ name: "Chakra UI",
84
+ description:
85
+ "Accessible React component library with a simple, composable API and built-in style props.",
86
+ cssApproach: "css-in-js",
87
+ darkModeSupport: true,
88
+ accessibilityRating: "good",
89
+ bundleSize: "medium",
90
+ learningCurve: "low",
91
+ typescriptSupport: "native",
92
+ designTokens: true,
93
+ ecosystem: "React with companion libraries for icons, transitions, and layout utilities",
94
+ bestFor: [
95
+ "Rapid application development with accessible defaults",
96
+ "Teams prioritizing developer experience and composability",
97
+ "Projects needing easy dark mode and theming",
98
+ ],
99
+ limitations: [
100
+ "Runtime CSS-in-JS can impact performance in large apps",
101
+ "Smaller component set than MUI or Ant Design",
102
+ "React-only with no multi-framework support",
103
+ ],
104
+ officialUrl: "https://chakra-ui.com",
105
+ },
106
+ {
107
+ id: "ant-design",
108
+ name: "Ant Design",
109
+ description:
110
+ "Enterprise-grade React component library with 60+ polished components and a complete design system.",
111
+ cssApproach: "css-in-js",
112
+ darkModeSupport: true,
113
+ accessibilityRating: "good",
114
+ bundleSize: "large",
115
+ learningCurve: "moderate",
116
+ typescriptSupport: "native",
117
+ designTokens: true,
118
+ ecosystem: "React with Ant Design Pro for admin templates, charts, and data visualization",
119
+ bestFor: [
120
+ "Enterprise applications and internal tools",
121
+ "Data-heavy dashboards with complex table requirements",
122
+ "Teams familiar with Ant Design's opinionated patterns",
123
+ ],
124
+ limitations: [
125
+ "Very large bundle with aggressive tree-shaking needed",
126
+ "Opinionated design language can be hard to customize away from",
127
+ "Documentation has inconsistencies between Chinese and English versions",
128
+ ],
129
+ officialUrl: "https://ant.design",
130
+ },
131
+ {
132
+ id: "radix-ui",
133
+ name: "Radix UI",
134
+ description:
135
+ "Unstyled, accessible component primitives designed for building high-quality design systems with Tailwind.",
136
+ cssApproach: "utility-first",
137
+ darkModeSupport: true,
138
+ accessibilityRating: "excellent",
139
+ bundleSize: "small",
140
+ learningCurve: "moderate",
141
+ typescriptSupport: "native",
142
+ designTokens: false,
143
+ ecosystem: "React with Radix Themes for pre-styled components and broad community adoption",
144
+ bestFor: [
145
+ "Building custom design systems with rigorous accessibility",
146
+ "Headless component architecture with full style control",
147
+ "Projects that combine Radix primitives with Tailwind CSS",
148
+ ],
149
+ limitations: [
150
+ "Headless primitives require significant styling effort",
151
+ "React-only with no Vue or Svelte support",
152
+ "Some components have complex API surfaces",
153
+ ],
154
+ officialUrl: "https://www.radix-ui.com",
155
+ },
156
+ {
157
+ id: "mantine",
158
+ name: "Mantine",
159
+ description:
160
+ "Hook-driven React component library with 100+ components, native CSS modules, and excellent DX.",
161
+ cssApproach: "css-modules",
162
+ darkModeSupport: true,
163
+ accessibilityRating: "good",
164
+ bundleSize: "medium",
165
+ learningCurve: "low",
166
+ typescriptSupport: "native",
167
+ designTokens: true,
168
+ ecosystem: "React with companion packages for hooks, forms, notifications, and rich text editing",
169
+ bestFor: [
170
+ "Full-featured applications needing a wide component selection",
171
+ "Teams that prefer CSS modules over CSS-in-JS runtime",
172
+ "Projects leveraging React hooks heavily",
173
+ ],
174
+ limitations: [
175
+ "React-only with no multi-framework support",
176
+ "Upgrading between major versions can require significant migration",
177
+ "Some advanced components have a large API surface",
178
+ ],
179
+ officialUrl: "https://mantine.dev",
180
+ },
181
+ {
182
+ id: "daisyui",
183
+ name: "DaisyUI",
184
+ description:
185
+ "Tailwind CSS plugin that adds semantic class names for common UI components with zero JavaScript.",
186
+ cssApproach: "utility-first",
187
+ darkModeSupport: true,
188
+ accessibilityRating: "basic",
189
+ bundleSize: "tiny",
190
+ learningCurve: "low",
191
+ typescriptSupport: "supported",
192
+ designTokens: false,
193
+ ecosystem: "Framework-agnostic as a pure CSS Tailwind plugin, usable with React, Vue, Svelte, or plain HTML",
194
+ bestFor: [
195
+ "Quick prototypes and landing pages",
196
+ "Projects that want styled components without JavaScript overhead",
197
+ "Tailwind users who prefer semantic class names",
198
+ ],
199
+ limitations: [
200
+ "No built-in interactive behavior — JavaScript must be added separately",
201
+ "Accessibility support is minimal and left to the developer",
202
+ "Limited customization depth compared to headless approaches",
203
+ ],
204
+ officialUrl: "https://daisyui.com",
205
+ },
206
+ {
207
+ id: "vuetify",
208
+ name: "Vuetify",
209
+ description:
210
+ "Comprehensive Material Design component framework for Vue with a vast component library and theming engine.",
211
+ cssApproach: "traditional",
212
+ darkModeSupport: true,
213
+ accessibilityRating: "good",
214
+ bundleSize: "large",
215
+ learningCurve: "moderate",
216
+ typescriptSupport: "native",
217
+ designTokens: true,
218
+ ecosystem: "Vue with built-in SASS variables, icon support, and an active community of plugins",
219
+ bestFor: [
220
+ "Vue applications following Material Design guidelines",
221
+ "Enterprise dashboards with complex data tables",
222
+ "Teams wanting an all-in-one Vue component solution",
223
+ ],
224
+ limitations: [
225
+ "Large bundle size even with tree-shaking via Vuetify loader",
226
+ "Tightly coupled to Material Design aesthetic",
227
+ "Major version upgrades have historically required significant migration",
228
+ ],
229
+ officialUrl: "https://vuetifyjs.com",
230
+ },
231
+ {
232
+ id: "primevue",
233
+ name: "PrimeVue",
234
+ description:
235
+ "Feature-rich Vue component suite with 90+ components, multiple themes, and an unstyled mode.",
236
+ cssApproach: "traditional",
237
+ darkModeSupport: true,
238
+ accessibilityRating: "good",
239
+ bundleSize: "medium",
240
+ learningCurve: "moderate",
241
+ typescriptSupport: "native",
242
+ designTokens: true,
243
+ ecosystem: "Vue with PrimeIcons, PrimeFlex utility CSS, and shared design across PrimeReact and PrimeNG",
244
+ bestFor: [
245
+ "Vue applications needing a large selection of pre-built components",
246
+ "Enterprise forms and data management interfaces",
247
+ "Teams that want theme flexibility including unstyled headless mode",
248
+ ],
249
+ limitations: [
250
+ "Documentation can lag behind latest releases",
251
+ "Some components feel less polished than competitors",
252
+ "Theming system has a learning curve for deep customization",
253
+ ],
254
+ officialUrl: "https://primevue.org",
255
+ },
256
+ {
257
+ id: "skeleton-svelte",
258
+ name: "Skeleton",
259
+ description:
260
+ "Tailwind-powered UI toolkit for Svelte and SvelteKit with adaptive theming and clean defaults.",
261
+ cssApproach: "utility-first",
262
+ darkModeSupport: true,
263
+ accessibilityRating: "good",
264
+ bundleSize: "small",
265
+ learningCurve: "low",
266
+ typescriptSupport: "native",
267
+ designTokens: false,
268
+ ecosystem: "Svelte and SvelteKit with Tailwind integration and community theme generator",
269
+ bestFor: [
270
+ "SvelteKit applications needing a polished component set",
271
+ "Tailwind-based projects in the Svelte ecosystem",
272
+ "Developers who want lightweight, themeable components",
273
+ ],
274
+ limitations: [
275
+ "Svelte-only with no React or Vue support",
276
+ "Smaller component set compared to mature libraries",
277
+ "Ecosystem and community are still growing",
278
+ ],
279
+ officialUrl: "https://www.skeleton.dev",
280
+ },
281
+ {
282
+ id: "angular-material",
283
+ name: "Angular Material",
284
+ description:
285
+ "Official Material Design component library for Angular with strong accessibility and CDK primitives.",
286
+ cssApproach: "scoped",
287
+ darkModeSupport: true,
288
+ accessibilityRating: "excellent",
289
+ bundleSize: "medium",
290
+ learningCurve: "steep",
291
+ typescriptSupport: "native",
292
+ designTokens: true,
293
+ ecosystem: "Angular with the Component Dev Kit (CDK) for building custom components",
294
+ bestFor: [
295
+ "Angular enterprise applications",
296
+ "Teams requiring WAI-ARIA compliant components",
297
+ "Projects that align with Material Design standards",
298
+ ],
299
+ limitations: [
300
+ "Angular-only with tight framework coupling",
301
+ "Steep learning curve tied to Angular's own complexity",
302
+ "Customizing beyond Material Design's aesthetic requires significant effort",
303
+ ],
304
+ officialUrl: "https://material.angular.io",
305
+ },
306
+ {
307
+ id: "flowbite",
308
+ name: "Flowbite",
309
+ description:
310
+ "Tailwind CSS component library with vanilla JS and adapters for React, Vue, Svelte, and Angular.",
311
+ cssApproach: "utility-first",
312
+ darkModeSupport: true,
313
+ accessibilityRating: "basic",
314
+ bundleSize: "tiny",
315
+ learningCurve: "low",
316
+ typescriptSupport: "supported",
317
+ designTokens: false,
318
+ ecosystem: "Multi-framework with Flowbite React, Vue, Svelte, and Angular adapters plus a Figma design kit",
319
+ bestFor: [
320
+ "Multi-framework teams sharing a consistent design",
321
+ "Marketing sites and landing pages",
322
+ "Tailwind users who want ready-made components across stacks",
323
+ ],
324
+ limitations: [
325
+ "Accessibility coverage is basic and needs manual enhancement",
326
+ "Framework adapters vary in completeness and maturity",
327
+ "Interactive components depend on Flowbite's own JavaScript",
328
+ ],
329
+ officialUrl: "https://flowbite.com",
330
+ },
331
+ {
332
+ id: "park-ui",
333
+ name: "Park UI",
334
+ description:
335
+ "Beautifully designed components built on Ark UI primitives with support for React, Vue, and Solid.",
336
+ cssApproach: "utility-first",
337
+ darkModeSupport: true,
338
+ accessibilityRating: "good",
339
+ bundleSize: "small",
340
+ learningCurve: "moderate",
341
+ typescriptSupport: "native",
342
+ designTokens: true,
343
+ ecosystem: "Multi-framework via Ark UI with Panda CSS or Tailwind styling and a growing component set",
344
+ bestFor: [
345
+ "Multi-framework projects wanting shared accessible primitives",
346
+ "Teams adopting Panda CSS or modern styling approaches",
347
+ "Design-conscious applications requiring polished defaults",
348
+ ],
349
+ limitations: [
350
+ "Relatively new with a smaller community than established libraries",
351
+ "Component count is still growing",
352
+ "Ark UI dependency adds an additional abstraction layer",
353
+ ],
354
+ officialUrl: "https://park-ui.com",
355
+ },
356
+ ];
357
+
358
+ export function getFrameworkById(id: string): FrameworkEntry | undefined {
359
+ return FRAMEWORK_CATALOG.find((f) => f.id === id);
360
+ }