@godxjp/ui 32.13.1 → 32.15.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 (47) hide show
  1. package/README.md +4 -4
  2. package/agent/START-HERE.md +7 -7
  3. package/agent/components/HeatmapChart.json +97 -0
  4. package/agent/components/ListRow.json +1 -1
  5. package/agent/components/PageContainer.json +2 -2
  6. package/agent/components/Segmented.json +1 -0
  7. package/agent/components/Tabs.json +3 -2
  8. package/agent/components-index.json +5 -0
  9. package/agent/components.json +104 -5
  10. package/agent/index.json +7 -7
  11. package/agent/llms.txt +6 -6
  12. package/agent/patterns/inertia-list-page.json +1 -1
  13. package/agent/patterns.json +1 -1
  14. package/agent/tokens.json +116 -2
  15. package/dist/components/charts/chart-summary.d.ts +32 -1
  16. package/dist/components/charts/chart-summary.js +49 -0
  17. package/dist/components/charts/heatmap-chart.d.ts +19 -0
  18. package/dist/components/charts/heatmap-chart.js +293 -0
  19. package/dist/components/charts/index.d.ts +3 -0
  20. package/dist/components/charts/index.js +2 -0
  21. package/dist/components/feedback/tooltip.d.ts +9 -0
  22. package/dist/components/feedback/tooltip.js +4 -1
  23. package/dist/contracts/measurement.json +1 -1
  24. package/dist/i18n/messages/en.json +8 -1
  25. package/dist/i18n/messages/ja.json +8 -1
  26. package/dist/i18n/messages/vi.json +8 -1
  27. package/dist/props/components/charts.prop.d.ts +58 -0
  28. package/dist/props/registry.d.ts +37 -0
  29. package/dist/props/registry.js +36 -0
  30. package/dist/styles/base.css +19 -19
  31. package/dist/styles/chart-layout.css +161 -0
  32. package/dist/styles/data-display-layout.css +3 -3
  33. package/dist/styles/layers.json +8 -1
  34. package/dist/styles/layout.css +1 -1
  35. package/dist/styles.css +1 -1
  36. package/dist/tokens/components/chart.css +27 -0
  37. package/dist/tokens/foundation.css +12 -0
  38. package/dist/tokens/semantic/layout.css +1 -1
  39. package/package.json +9 -2
  40. package/scripts/_agent-setup.mjs +118 -0
  41. package/scripts/agent-guard.mjs +176 -0
  42. package/scripts/cli.mjs +25 -2
  43. package/scripts/codemod.mjs +313 -42
  44. package/scripts/init-agent-kit.mjs +14 -0
  45. package/scripts/mcp-call.mjs +40 -0
  46. package/scripts/ui-audit.mjs +77 -0
  47. package/scripts/user-guard.mjs +78 -0
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @godxjp/ui user-level guard — the SHIM `npx godxjp-ui init-agent --user` copies to
4
+ * ~/.claude/hooks/godxjp-ui-guard.mjs (gh#1324).
5
+ *
6
+ * A repo's `.mcp.json`, CLAUDE.md and `.claude/settings.json` hooks load only when Claude Code
7
+ * STARTS in that repo. A session started anywhere else writes UI blind: measured in godx-qc,
8
+ * 0 of 25 UI-writing subagents had the godx-ui MCP and no audit fired. User settings always load,
9
+ * so this shim is registered there for PreToolUse and PostToolUse on Write|Edit|MultiEdit.
10
+ *
11
+ * It runs on EVERY write in EVERY repo on the machine, so it does as little as possible: it
12
+ * leaves unless the file is a .tsx/.jsx inside a repo whose `.mcp.json` mounts @godxjp/ui-mcp,
13
+ * and then hands the payload to that repo's own installed `@godxjp/ui/scripts/agent-guard.mjs`,
14
+ * which holds the logic and moves with the package version. Self-contained on purpose: it is a
15
+ * copy that lives outside every package. No network.
16
+ *
17
+ * FAIL OPEN: any error in this shim — unreadable stdin, a malformed .mcp.json, a missing or older
18
+ * package without agent-guard.mjs, a crash — exits 0, and a write is never blocked because the
19
+ * guard itself broke. Only agent-guard.mjs's deliberate exit 2 blocks.
20
+ */
21
+ import { spawnSync } from "node:child_process";
22
+ import { existsSync, readFileSync } from "node:fs";
23
+ import { dirname, join, resolve } from "node:path";
24
+
25
+ process.on("uncaughtException", () => process.exit(0)); // fail open, see above
26
+
27
+ const event = process.argv[2] === "post" ? "post" : "pre";
28
+ let raw;
29
+ try {
30
+ raw = readFileSync(0, "utf8"); // fd 0 = the hook payload piped by Claude Code
31
+ } catch {
32
+ process.exit(0);
33
+ }
34
+ const payload = JSON.parse(raw); // a throw lands in the fail-open handler
35
+ const given = payload?.tool_input?.file_path ?? payload?.tool_input?.filePath;
36
+ if (typeof given !== "string" || !/\.(tsx|jsx)$/.test(given)) process.exit(0);
37
+ const file = resolve(payload?.cwd ?? process.cwd(), given);
38
+
39
+ /** Mirrors runsUiMcp in @godxjp/ui scripts/_agent-setup.mjs: the catalog server, any key. */
40
+ const runsUiMcp = (entry) =>
41
+ [entry?.command, ...(Array.isArray(entry?.args) ? entry.args : [])].some(
42
+ (part) => typeof part === "string" && /(^|\/)@godxjp\/ui-mcp(@|$)/.test(part),
43
+ );
44
+
45
+ // The nearest ancestor `.mcp.json` decides: it mounts the catalog, or this is not our repo.
46
+ let root = null;
47
+ for (let dir = dirname(file); ; dir = dirname(dir)) {
48
+ const cfg = join(dir, ".mcp.json");
49
+ if (existsSync(cfg)) {
50
+ const servers = JSON.parse(readFileSync(cfg, "utf8"))?.mcpServers ?? {};
51
+ if (Object.values(servers).some(runsUiMcp) || servers["godx-ui"]) root = dir;
52
+ break;
53
+ }
54
+ if (dirname(dir) === dir) break;
55
+ }
56
+ if (!root) process.exit(0);
57
+
58
+ // The repo's installed package, up the node_modules chain (a workspace hoists it to the top).
59
+ let guard = null;
60
+ for (let dir = root; ; dir = dirname(dir)) {
61
+ const candidate = join(dir, "node_modules", "@godxjp", "ui", "scripts", "agent-guard.mjs");
62
+ if (existsSync(candidate)) {
63
+ guard = candidate;
64
+ break;
65
+ }
66
+ if (dirname(dir) === dir) break;
67
+ }
68
+ if (!guard) process.exit(0); // not installed, or a release older than the guard: fail open
69
+
70
+ const r = spawnSync(process.execPath, [guard, event, root], {
71
+ input: raw,
72
+ encoding: "utf8",
73
+ timeout: 45_000, // under Claude Code's 60s hook limit, so a slow guard still ends in exit 0
74
+ });
75
+ if (r.error || r.status === null) process.exit(0);
76
+ if (r.stdout) process.stdout.write(r.stdout);
77
+ if (r.stderr) process.stderr.write(r.stderr);
78
+ process.exit(r.status === 2 ? 2 : 0);