@godxjp/ui 13.17.4 → 14.0.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 (61) hide show
  1. package/dist/components/charts/area-chart.d.ts +8 -0
  2. package/dist/components/charts/area-chart.js +8 -0
  3. package/dist/components/charts/bar-chart.d.ts +8 -0
  4. package/dist/components/charts/bar-chart.js +8 -0
  5. package/dist/components/charts/chart-cartesian.d.ts +31 -0
  6. package/dist/components/charts/chart-cartesian.js +178 -0
  7. package/dist/components/charts/chart-frame.d.ts +44 -0
  8. package/dist/components/charts/chart-frame.js +72 -0
  9. package/dist/components/charts/chart-summary.d.ts +21 -0
  10. package/dist/components/charts/chart-summary.js +23 -0
  11. package/dist/components/charts/index.d.ts +16 -0
  12. package/dist/components/charts/index.js +12 -0
  13. package/dist/components/charts/line-chart.d.ts +8 -0
  14. package/dist/components/charts/line-chart.js +8 -0
  15. package/dist/components/charts/pie-chart.d.ts +8 -0
  16. package/dist/components/charts/pie-chart.js +73 -0
  17. package/dist/components/data-display/index.d.ts +2 -0
  18. package/dist/components/data-display/index.js +2 -0
  19. package/dist/components/data-display/list-row.d.ts +24 -0
  20. package/dist/components/data-display/list-row.js +31 -0
  21. package/dist/components/data-entry/command.d.ts +10 -10
  22. package/dist/components/data-entry/transfer.js +1 -1
  23. package/dist/components/general/button.d.ts +1 -0
  24. package/dist/components/general/button.js +3 -0
  25. package/dist/components/general/index.d.ts +2 -0
  26. package/dist/components/general/index.js +4 -1
  27. package/dist/components/general/logo.d.ts +28 -0
  28. package/dist/components/general/logo.js +45 -0
  29. package/dist/components/layout/index.d.ts +1 -1
  30. package/dist/components/layout/sidebar.js +32 -24
  31. package/dist/components/layout/topbar.d.ts +19 -2
  32. package/dist/components/layout/topbar.js +7 -128
  33. package/dist/i18n/messages/en.json +5 -0
  34. package/dist/i18n/messages/ja.json +5 -0
  35. package/dist/i18n/messages/vi.json +5 -0
  36. package/dist/props/components/charts.prop.d.ts +89 -0
  37. package/dist/props/components/charts.prop.js +0 -0
  38. package/dist/props/components/general.prop.d.ts +5 -0
  39. package/dist/props/components/index.d.ts +2 -1
  40. package/dist/props/components/layout.prop.d.ts +16 -33
  41. package/dist/props/registry.d.ts +170 -11
  42. package/dist/props/registry.js +112 -11
  43. package/dist/styles/chart-layout.css +37 -0
  44. package/dist/styles/data-display-layout.css +38 -0
  45. package/dist/styles/density.css +62 -0
  46. package/dist/styles/index.css +1 -0
  47. package/dist/styles/shell-layout.css +39 -0
  48. package/dist/styles/text-layout.css +3 -0
  49. package/dist/tokens/base.css +2 -0
  50. package/dist/tokens/components/list-row.css +9 -0
  51. package/dist/tokens/components/logo.css +11 -0
  52. package/dist/tokens/foundation.css +13 -0
  53. package/package.json +43 -7
  54. package/scripts/_agent-setup.mjs +145 -0
  55. package/scripts/audit-hook.mjs +66 -0
  56. package/scripts/cli.mjs +26 -0
  57. package/scripts/init-agent-kit.mjs +52 -0
  58. package/scripts/postinstall.mjs +31 -0
  59. package/scripts/ui-audit.mjs +165 -3
  60. package/scripts/visual-audit-rules.mjs +119 -0
  61. package/scripts/visual-audit.mjs +261 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@godxjp/ui",
3
- "version": "13.17.4",
3
+ "version": "14.0.1",
4
4
  "type": "module",
5
5
  "packageManager": "pnpm@10.29.1",
6
6
  "sideEffects": false,
@@ -8,7 +8,14 @@
8
8
  "files": [
9
9
  "dist",
10
10
  "scripts/ui-audit.mjs",
11
- "README.md"
11
+ "README.md",
12
+ "scripts/visual-audit.mjs",
13
+ "scripts/visual-audit-rules.mjs",
14
+ "scripts/audit-hook.mjs",
15
+ "scripts/init-agent-kit.mjs",
16
+ "scripts/postinstall.mjs",
17
+ "scripts/_agent-setup.mjs",
18
+ "scripts/cli.mjs"
12
19
  ],
13
20
  "main": "./dist/index.js",
14
21
  "types": "./dist/index.d.ts",
@@ -51,6 +58,10 @@
51
58
  "types": "./dist/components/data-grid/index.d.ts",
52
59
  "import": "./dist/components/data-grid/index.js"
53
60
  },
61
+ "./charts": {
62
+ "types": "./dist/components/charts/index.d.ts",
63
+ "import": "./dist/components/charts/index.js"
64
+ },
54
65
  "./ui": {
55
66
  "types": "./dist/components/ui/index.d.ts",
56
67
  "import": "./dist/components/ui/index.js"
@@ -266,8 +277,8 @@
266
277
  "test:watch": "vitest",
267
278
  "test:coverage": "vitest run --coverage",
268
279
  "check:example-imports": "node scripts/check-example-imports.mjs",
269
- "verify": "pnpm typecheck && pnpm lint && pnpm format && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm test",
270
- "verify:release": "pnpm typecheck && pnpm lint && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:mcp-prop-sync && pnpm test",
280
+ "verify": "pnpm typecheck && pnpm lint && pnpm format && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:audit-sync && pnpm test",
281
+ "verify:release": "pnpm typecheck && pnpm lint && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:audit-sync && pnpm check:mcp-prop-sync && pnpm test",
271
282
  "check:mcp-sync": "node scripts/check-mcp-sync.mjs",
272
283
  "check:mcp-orphans": "node scripts/check-mcp-orphans.mjs",
273
284
  "check:mcp-prop-sync": "node scripts/check-mcp-prop-sync.mjs",
@@ -284,9 +295,14 @@
284
295
  "preview:build": "vite build --config preview/vite.config.ts",
285
296
  "docs:sync-primitives": "node preview/scripts/sync-primitive-docs.mjs && prettier --write \"docs/primitives/**/*.tsx\"",
286
297
  "audit": "node scripts/ui-audit.mjs",
298
+ "audit:examples": "node scripts/ui-audit.mjs docs",
287
299
  "build": "tsup && tsc -p tsconfig.build.json && node scripts/copy-styles.mjs",
288
300
  "dev": "node scripts/dev.mjs",
289
- "prepublishOnly": "pnpm run build"
301
+ "prepublishOnly": "pnpm run build",
302
+ "check:audit-sync": "node scripts/check-audit-sync.mjs",
303
+ "visual-audit": "node scripts/visual-audit.mjs",
304
+ "postinstall": "node scripts/postinstall.mjs",
305
+ "init-agent": "node scripts/init-agent-kit.mjs"
290
306
  },
291
307
  "peerDependencies": {
292
308
  "@hookform/resolvers": "^5.2.0",
@@ -296,12 +312,28 @@
296
312
  "react-dom": ">=19.0.0",
297
313
  "react-hook-form": "^7.76.0",
298
314
  "react-router-dom": ">=7.0.0",
315
+ "recharts": "^2.13.0 || ^3.0.0",
299
316
  "tailwindcss": ">=4.0.0",
300
- "zod": "^4.4.0"
317
+ "zod": "^4.4.0",
318
+ "playwright": "*",
319
+ "@axe-core/playwright": "*",
320
+ "axe-core": "*"
301
321
  },
302
322
  "peerDependenciesMeta": {
303
323
  "@tanstack/react-table": {
304
324
  "optional": true
325
+ },
326
+ "recharts": {
327
+ "optional": true
328
+ },
329
+ "playwright": {
330
+ "optional": true
331
+ },
332
+ "@axe-core/playwright": {
333
+ "optional": true
334
+ },
335
+ "axe-core": {
336
+ "optional": true
305
337
  }
306
338
  },
307
339
  "dependencies": {
@@ -348,6 +380,7 @@
348
380
  "vaul": "^1.1.2"
349
381
  },
350
382
  "devDependencies": {
383
+ "@axe-core/playwright": "^4.12.1",
351
384
  "@eslint/js": "^9.39.4",
352
385
  "@hookform/resolvers": "^5.2.2",
353
386
  "@tailwindcss/vite": "^4.2.4",
@@ -361,17 +394,20 @@
361
394
  "@types/react-dom": "^19.2.3",
362
395
  "@vitejs/plugin-react": "^6.0.1",
363
396
  "@vitest/coverage-v8": "^4.1.5",
397
+ "axe-core": "^4.12.1",
364
398
  "eslint": "^9.39.2",
365
399
  "eslint-plugin-react": "^7.37.5",
366
400
  "eslint-plugin-react-hooks": "^7.1.1",
367
401
  "globals": "^15.15.0",
368
402
  "jsdom": "^29.1.1",
403
+ "playwright": "^1.61.1",
369
404
  "prettier": "^3.6.2",
370
405
  "prettier-plugin-tailwindcss": "^0.6.14",
371
406
  "react": "^19.2.6",
372
407
  "react-dom": "^19.2.6",
373
408
  "react-hook-form": "^7.76.0",
374
409
  "react-router-dom": "^7.15.0",
410
+ "recharts": "^3.8.1",
375
411
  "tailwindcss": "^4.2.4",
376
412
  "tsup": "^8.5.1",
377
413
  "typescript": "^6.0.3",
@@ -382,7 +418,7 @@
382
418
  "zod": "^4.4.3"
383
419
  },
384
420
  "bin": {
385
- "godxjp-ui-audit": "scripts/ui-audit.mjs"
421
+ "godxjp-ui": "scripts/cli.mjs"
386
422
  },
387
423
  "module": "./dist/index.js"
388
424
  }
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Shared agent-setup helpers — used by both postinstall.mjs (auto, on install) and
3
+ * init-agent-kit.mjs (explicit, full kit). Every writer is IDEMPOTENT and
4
+ * NON-DESTRUCTIVE: it only creates a missing file or ADDS a missing key, never
5
+ * overwrites existing config.
6
+ */
7
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
8
+ import { dirname, join } from "node:path";
9
+
10
+ /** The godxjp-ui MCP server — pulled on demand via npx (no extra dependency to ship). */
11
+ export const MCP_SERVER = { command: "npx", args: ["@godxjp/ui-mcp"] };
12
+ export const MCP_KEY = "godx-ui";
13
+
14
+ /** Commands wired into the consumer's .claude/settings.json. */
15
+ export const AUDIT_HOOK_CMD = "node node_modules/@godxjp/ui/scripts/audit-hook.mjs";
16
+ export const PRIMER_CMD = "cat .claude/godxjp-ui-workflow.md";
17
+
18
+ /** The per-session workflow mandate the SessionStart hook injects into the agent. */
19
+ export const WORKFLOW_MD = `# @godxjp/ui — mandatory workflow (read every session)
20
+
21
+ You are building UI in an app that uses @godxjp/ui. Follow this EVERY time you create
22
+ or change a component, page, or form — no exceptions.
23
+
24
+ ## Before writing UI
25
+ 1. **MCP-first.** Consult the godx-ui MCP: \`get_component <Name>\`, \`search_components\`,
26
+ \`list_audit_rules\`, \`list_visual_checks\`. Never guess a prop; never hand-roll what a
27
+ primitive already does.
28
+ 2. **Real primitives only.** No raw \`<input>/<select>/<button>/<textarea>/<table>\`, no
29
+ styled-div fakes. A labelled control ALWAYS goes in \`<FormField label=…>\` (it owns the
30
+ label↔control wiring, error/aria, AND the field rhythm). Never pair a bare \`<Label>\`
31
+ with an \`<Input>\`.
32
+ 3. **Tokens, not literals.** Semantic colour tokens (bg-primary, text-muted-foreground),
33
+ token spacing/size/radius/type — no raw palette (bg-blue-600), no hex, no arbitrary
34
+ \`[13px]\`. No emoji in product UI. Logical CSS (ms-/me-/ps-/pe-) for RTL.
35
+
36
+ ## After writing UI
37
+ 4. **Audit (runs automatically too).** \`node node_modules/@godxjp/ui/scripts/ui-audit.mjs\`
38
+ — fix every finding. A PostToolUse hook also runs it on each edit and feeds findings back.
39
+ 5. **Before a visual review**, run the runtime audit against the running app:
40
+ \`node node_modules/@godxjp/ui/scripts/visual-audit.mjs <url>\` (axe + contrast + layout).
41
+ `;
42
+
43
+ /** Delimited block appended to the consumer's CLAUDE.md — loaded into the agent's context
44
+ * every turn (the most reliable "ensure it reads the rules"). Markers keep it idempotent. */
45
+ export const CLAUDE_MD_BLOCK = `<!-- godxjp-ui:start (managed by @godxjp/ui — edit .claude/godxjp-ui-workflow.md instead) -->
46
+ ## @godxjp/ui — mandatory UI workflow (do NOT skip)
47
+
48
+ This app uses @godxjp/ui. EVERY time you build or change UI:
49
+
50
+ 1. **MCP-first.** Consult the \`godx-ui\` MCP — \`get_component\`, \`search_components\`,
51
+ \`list_audit_rules\`, \`list_visual_checks\`. Never guess a prop; never hand-roll what a
52
+ primitive already does.
53
+ 2. **Real primitives only.** No raw \`<input>/<select>/<button>/<textarea>/<table>\`. A labelled
54
+ control ALWAYS goes in \`<FormField label=…>\` — never a bare \`<Label>\`+\`<Input>\`. Semantic
55
+ tokens, not raw palette/hex/arbitrary values. No emoji in product UI. Logical CSS for RTL.
56
+ 3. **Scan after writing.** \`node node_modules/@godxjp/ui/scripts/ui-audit.mjs <files>\` and fix
57
+ every finding (a PostToolUse hook runs this automatically and feeds findings back). Before a
58
+ visual review: \`node node_modules/@godxjp/ui/scripts/visual-audit.mjs <url>\` (axe + layout).
59
+
60
+ Full guide: \`.claude/godxjp-ui-workflow.md\`.
61
+ <!-- godxjp-ui:end -->
62
+ `;
63
+
64
+ function readJson(path) {
65
+ try {
66
+ return JSON.parse(readFileSync(path, "utf8"));
67
+ } catch {
68
+ return null;
69
+ }
70
+ }
71
+
72
+ /** Ensure `.mcp.json` registers the godx-ui MCP server. Returns 'created' | 'added' | 'present'. */
73
+ export function ensureMcpJson(root) {
74
+ const path = join(root, ".mcp.json");
75
+ const json = readJson(path) ?? {};
76
+ json.mcpServers = json.mcpServers ?? {};
77
+ if (json.mcpServers[MCP_KEY]) return "present";
78
+ const created = !existsSync(path);
79
+ json.mcpServers[MCP_KEY] = MCP_SERVER;
80
+ writeFileSync(path, JSON.stringify(json, null, 2) + "\n");
81
+ return created ? "created" : "added";
82
+ }
83
+
84
+ /** Ensure `.claude/settings.json` has the audit PostToolUse + workflow SessionStart hooks. */
85
+ export function ensureClaudeHooks(root) {
86
+ const path = join(root, ".claude", "settings.json");
87
+ mkdirSync(dirname(path), { recursive: true });
88
+ const json = readJson(path) ?? {};
89
+ json.hooks = json.hooks ?? {};
90
+ const added = [];
91
+
92
+ const has = (arr, cmd) =>
93
+ (arr ?? []).some((g) => (g.hooks ?? []).some((h) => (h.command ?? "").includes(cmd)));
94
+
95
+ json.hooks.PostToolUse = json.hooks.PostToolUse ?? [];
96
+ if (!has(json.hooks.PostToolUse, "audit-hook.mjs")) {
97
+ json.hooks.PostToolUse.push({
98
+ matcher: "Write|Edit|MultiEdit",
99
+ hooks: [{ type: "command", command: AUDIT_HOOK_CMD }],
100
+ });
101
+ added.push("PostToolUse:auto-audit");
102
+ }
103
+
104
+ json.hooks.SessionStart = json.hooks.SessionStart ?? [];
105
+ if (!has(json.hooks.SessionStart, "godxjp-ui-workflow.md")) {
106
+ json.hooks.SessionStart.push({ hooks: [{ type: "command", command: PRIMER_CMD }] });
107
+ added.push("SessionStart:workflow-primer");
108
+ }
109
+
110
+ writeFileSync(path, JSON.stringify(json, null, 2) + "\n");
111
+ return added;
112
+ }
113
+
114
+ /** Write the workflow mandate the SessionStart hook reads (only if absent). */
115
+ export function writeWorkflowMd(root) {
116
+ const path = join(root, ".claude", "godxjp-ui-workflow.md");
117
+ mkdirSync(dirname(path), { recursive: true });
118
+ if (existsSync(path)) return false;
119
+ writeFileSync(path, WORKFLOW_MD);
120
+ return true;
121
+ }
122
+
123
+ /** Append the godxjp-ui mandate to the consumer's CLAUDE.md (created if absent). Idempotent
124
+ * via the markers. Returns 'created' | 'appended' | 'present'. */
125
+ export function ensureClaudeMd(root) {
126
+ const path = join(root, "CLAUDE.md");
127
+ const existing = existsSync(path) ? readFileSync(path, "utf8") : null;
128
+ if (existing?.includes("godxjp-ui:start")) return "present";
129
+ if (existing == null) {
130
+ writeFileSync(path, CLAUDE_MD_BLOCK);
131
+ return "created";
132
+ }
133
+ writeFileSync(path, existing.replace(/\s*$/, "") + "\n\n" + CLAUDE_MD_BLOCK);
134
+ return "appended";
135
+ }
136
+
137
+ /** True when setup should be SKIPPED (CI, opted out, or installing the library itself). */
138
+ export function shouldSkip(root) {
139
+ if (process.env.CI || process.env.GODXJP_UI_SKIP_SETUP) return "ci-or-optout";
140
+ if (!root) return "no-consumer";
141
+ const pkg = readJson(join(root, "package.json"));
142
+ if (!pkg) return "no-package";
143
+ if (pkg.name === "@godxjp/ui" || pkg.name === "@godxjp/ui-mcp") return "self";
144
+ return null;
145
+ }
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Claude Code PostToolUse hook — the FORCING FUNCTION.
4
+ *
5
+ * Wired by `init-agent-kit.mjs` into a consumer's `.claude/settings.json` so that
6
+ * after EVERY Write/Edit/MultiEdit of a .tsx/.ts file, the godxjp-ui static audit
7
+ * runs on that file and its findings are fed straight back to the agent. The agent
8
+ * cannot skip it — the harness runs the hook, not the agent's goodwill — so a
9
+ * hand-rolled <label>+<Input>, a raw <button>, a loud palette colour, or an emoji
10
+ * is surfaced the instant it is written, and the agent self-corrects.
11
+ *
12
+ * Contract: reads the hook JSON on stdin ({ tool_input: { file_path } }). Prints
13
+ * findings to stderr and exits 2 when any are found (Claude Code feeds stderr back
14
+ * to the model); exits 0 (silent) when the file is clean or irrelevant. Non-fatal —
15
+ * it never blocks the edit, it just makes the agent SEE the issue.
16
+ */
17
+ import { execFileSync } from "node:child_process";
18
+ import { readFileSync } from "node:fs";
19
+ import { dirname, join } from "node:path";
20
+ import { fileURLToPath } from "node:url";
21
+
22
+ const HERE = dirname(fileURLToPath(import.meta.url));
23
+ const AUDIT = join(HERE, "ui-audit.mjs");
24
+
25
+ function readStdin() {
26
+ try {
27
+ return JSON.parse(readFileSync(0, "utf8")); // fd 0 = the hook payload piped by Claude Code
28
+ } catch {
29
+ return null;
30
+ }
31
+ }
32
+
33
+ const payload = readStdin();
34
+ const file = payload?.tool_input?.file_path ?? payload?.tool_input?.filePath;
35
+ if (!file || !/\.(tsx|ts)$/.test(file) || /\.(test|stories|d)\.tsx?$/.test(file)) process.exit(0);
36
+
37
+ // ui-audit exits 1 when it finds errors — execFileSync throws, but the JSON is still on
38
+ // e.stdout. Capture it either way; only a truly broken run (no stdout) is ignored.
39
+ let out;
40
+ try {
41
+ out = execFileSync("node", [AUDIT, "--format", "json", file], { encoding: "utf8" });
42
+ } catch (e) {
43
+ out = e.stdout?.toString();
44
+ }
45
+ let result;
46
+ try {
47
+ result = JSON.parse(out);
48
+ } catch {
49
+ process.exit(0); // never let an audit error break the edit flow
50
+ }
51
+
52
+ const findings = result.findings ?? [];
53
+ if (findings.length === 0) process.exit(0);
54
+
55
+ const lines = [
56
+ `godxjp-ui audit flagged ${findings.length} issue(s) in this file — fix before moving on:`,
57
+ ];
58
+ for (const f of findings) {
59
+ lines.push(` [${f.severity}] ${f.rule} (line ${f.line})${f.standard ? ` · ${f.standard}` : ""}`);
60
+ lines.push(` ${f.message}`);
61
+ }
62
+ lines.push(
63
+ "Consult the godxjp-ui MCP (get_component / list_audit_rules) and use the real primitive — do not hand-roll.",
64
+ );
65
+ process.stderr.write(lines.join("\n") + "\n");
66
+ process.exit(2); // exit 2 → Claude Code surfaces stderr to the agent
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @godxjp/ui CLI — `npx @godxjp/ui <command>`.
4
+ * init-agent scaffold the agent forcing-kit (MCP + auto-audit hook + mandate)
5
+ * audit static UI audit (regex over source)
6
+ * visual-audit runtime audit (Playwright + axe-core) against a running app
7
+ */
8
+ import { spawnSync } from "node:child_process";
9
+ import { dirname, join } from "node:path";
10
+ import { fileURLToPath } from "node:url";
11
+
12
+ const HERE = dirname(fileURLToPath(import.meta.url));
13
+ const MAP = {
14
+ "init-agent": "init-agent-kit.mjs",
15
+ audit: "ui-audit.mjs",
16
+ "visual-audit": "visual-audit.mjs",
17
+ };
18
+
19
+ const [cmd, ...rest] = process.argv.slice(2);
20
+ const script = MAP[cmd];
21
+ if (!script) {
22
+ console.error("usage: godxjp-ui <init-agent | audit | visual-audit> [args]");
23
+ process.exit(1);
24
+ }
25
+ const r = spawnSync("node", [join(HERE, script), ...rest], { stdio: "inherit" });
26
+ process.exit(r.status ?? 0);
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * init-agent-kit — the FULL forcing-kit. Run once from a consumer app:
4
+ * npx @godxjp/ui init-agent
5
+ *
6
+ * Scaffolds (idempotent, non-destructive) the harness-enforced workflow so an agent
7
+ * follows the whole godxjp-ui process every time it touches UI:
8
+ * 1. .mcp.json — registers the godx-ui MCP (component + audit guidance)
9
+ * 2. .claude/settings.json — PostToolUse hook auto-runs the audit on every .tsx edit
10
+ * and feeds findings back; SessionStart injects the mandate
11
+ * 3. .claude/godxjp-ui-workflow.md — the per-session mandate the SessionStart hook reads
12
+ *
13
+ * Existing config is preserved (hooks are appended only if absent). It then prints the
14
+ * optional pre-commit / CI snippets.
15
+ */
16
+ import {
17
+ ensureClaudeHooks,
18
+ ensureClaudeMd,
19
+ ensureMcpJson,
20
+ shouldSkip,
21
+ writeWorkflowMd,
22
+ } from "./_agent-setup.mjs";
23
+
24
+ const root = process.env.INIT_CWD || process.cwd();
25
+
26
+ const skip = shouldSkip(root);
27
+ if (skip === "self") {
28
+ console.error("init-agent is for CONSUMER apps, not the @godxjp/ui repo itself.");
29
+ process.exit(1);
30
+ }
31
+
32
+ const mcp = ensureMcpJson(root);
33
+ const hooks = ensureClaudeHooks(root);
34
+ const md = writeWorkflowMd(root);
35
+ const claudeMd = ensureClaudeMd(root);
36
+
37
+ console.log("\n @godxjp/ui agent-kit installed:");
38
+ console.log(` • .mcp.json — godx-ui MCP (${mcp})`);
39
+ console.log(
40
+ ` • .claude/settings.json — ${hooks.length ? hooks.join(", ") : "hooks already present"}`,
41
+ );
42
+ console.log(` • .claude/godxjp-ui-workflow.md — ${md ? "created" : "already present"}`);
43
+ console.log(` • CLAUDE.md — godxjp-ui mandate (${claudeMd})`);
44
+ console.log(`
45
+ The auto-audit hook now runs on every Write/Edit of a .tsx file and feeds findings
46
+ back to the agent — it cannot skip the audit. Restart your agent to load the MCP + hooks.
47
+
48
+ Optional hard gate (block bad UI from landing):
49
+ • pre-commit: node node_modules/@godxjp/ui/scripts/ui-audit.mjs resources/js || exit 1
50
+ • CI step: node node_modules/@godxjp/ui/scripts/ui-audit.mjs --quiet <your-ui-dirs>
51
+ `);
52
+ process.exit(0);
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * postinstall — runs when a consumer installs @godxjp/ui. Auto-registers the godx-ui
4
+ * MCP server in the consumer's `.mcp.json` so the agent gets live access to the
5
+ * component catalog + audit rules WITHOUT any manual step. Non-destructive (only adds
6
+ * a missing server entry) and guarded so it never runs in CI or in the library's own repo.
7
+ *
8
+ * The heavier forcing-kit (the auto-audit PostToolUse hook + the workflow mandate) is
9
+ * left to an EXPLICIT `npx @godxjp/ui init-agent`, since hooks change the dev loop and
10
+ * should be opted into, not forced on install. Set GODXJP_UI_SKIP_SETUP=1 to disable.
11
+ */
12
+ import { ensureMcpJson, shouldSkip } from "./_agent-setup.mjs";
13
+
14
+ const root = process.env.INIT_CWD || process.cwd();
15
+
16
+ const skip = shouldSkip(root);
17
+ if (skip) process.exit(0); // silent: CI / opt-out / self-install / no consumer project
18
+
19
+ try {
20
+ const r = ensureMcpJson(root);
21
+ if (r === "present") process.exit(0); // already configured — stay quiet
22
+ console.log(
23
+ `\n @godxjp/ui → registered the godx-ui MCP in .mcp.json (${r}).\n` +
24
+ " Your agent now has live component + audit guidance. Restart it to pick up the MCP.\n" +
25
+ " For the full forcing-kit (auto-audit on every edit + workflow mandate):\n" +
26
+ " npx @godxjp/ui init-agent\n",
27
+ );
28
+ } catch {
29
+ // Never fail an install over optional setup.
30
+ }
31
+ process.exit(0);