@hailer/mcp 1.1.12 → 1.1.13

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 (271) hide show
  1. package/CHANGELOG.md +0 -7
  2. package/{.claude → dist}/CLAUDE.md +2 -2
  3. package/dist/app.js +18 -5
  4. package/dist/bot/bot-config.d.ts +10 -1
  5. package/dist/bot/bot-config.js +64 -3
  6. package/dist/bot/bot-manager.d.ts +2 -0
  7. package/dist/bot/bot-manager.js +9 -2
  8. package/dist/bot/bot.d.ts +33 -0
  9. package/dist/bot/bot.js +461 -160
  10. package/dist/bot/services/message-classifier.js +17 -0
  11. package/dist/bot/services/permission-guard.d.ts +52 -0
  12. package/dist/bot/services/permission-guard.js +149 -0
  13. package/dist/bot/services/types.d.ts +5 -0
  14. package/dist/bot/services/typing-indicator.d.ts +6 -1
  15. package/dist/bot/services/typing-indicator.js +19 -3
  16. package/dist/cli.js +0 -0
  17. package/dist/config.d.ts +6 -1
  18. package/dist/config.js +43 -0
  19. package/dist/core.js +3 -6
  20. package/dist/lib/discussion-lock.d.ts +42 -0
  21. package/dist/lib/discussion-lock.js +110 -0
  22. package/dist/mcp/UserContextCache.d.ts +5 -0
  23. package/dist/mcp/UserContextCache.js +51 -19
  24. package/dist/mcp/hailer-clients.d.ts +19 -1
  25. package/dist/mcp/hailer-clients.js +158 -24
  26. package/dist/mcp/session-store.d.ts +68 -0
  27. package/dist/mcp/session-store.js +169 -0
  28. package/dist/mcp/signal-handler.js +2 -0
  29. package/dist/mcp/tool-registry.d.ts +17 -4
  30. package/dist/mcp/tool-registry.js +37 -7
  31. package/dist/mcp/tools/activity.js +99 -7
  32. package/dist/mcp/tools/app-scaffold.js +304 -336
  33. package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
  34. package/dist/mcp/tools/bot-config/constants.js +94 -0
  35. package/dist/mcp/tools/bot-config/core.d.ts +253 -0
  36. package/dist/mcp/tools/bot-config/core.js +2456 -0
  37. package/dist/mcp/tools/bot-config/index.d.ts +10 -0
  38. package/dist/mcp/tools/bot-config/index.js +59 -0
  39. package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
  40. package/dist/mcp/tools/bot-config/tools.js +15 -0
  41. package/dist/mcp/tools/bot-config/types.d.ts +50 -0
  42. package/dist/mcp/tools/bot-config/types.js +6 -0
  43. package/dist/mcp/tools/bug-fixer-tools.d.ts +45 -0
  44. package/dist/mcp/tools/bug-fixer-tools.js +1096 -0
  45. package/dist/mcp/tools/company.d.ts +9 -0
  46. package/dist/mcp/tools/company.js +88 -0
  47. package/dist/mcp/tools/discussion.js +68 -0
  48. package/dist/mcp/tools/document.d.ts +11 -0
  49. package/dist/mcp/tools/document.js +741 -0
  50. package/dist/mcp/tools/investigate.d.ts +9 -0
  51. package/dist/mcp/tools/investigate.js +254 -0
  52. package/dist/mcp/tools/workflow-permissions.d.ts +15 -0
  53. package/dist/mcp/tools/workflow-permissions.js +204 -0
  54. package/dist/mcp/tools/workflow.js +57 -18
  55. package/dist/mcp/utils/index.d.ts +2 -0
  56. package/dist/mcp/utils/index.js +12 -1
  57. package/dist/mcp/utils/role-utils.d.ts +74 -0
  58. package/dist/mcp/utils/role-utils.js +151 -0
  59. package/dist/mcp/utils/types.d.ts +43 -1
  60. package/dist/mcp/utils/types.js +14 -0
  61. package/dist/mcp/webhook-handler.d.ts +4 -0
  62. package/dist/mcp/webhook-handler.js +8 -0
  63. package/dist/mcp-server.d.ts +23 -2
  64. package/dist/mcp-server.js +639 -127
  65. package/dist/plugins/vipunen/client.d.ts +150 -0
  66. package/dist/plugins/vipunen/client.js +535 -0
  67. package/dist/plugins/vipunen/config/schema-config.json +19 -0
  68. package/dist/plugins/vipunen/config/schema-doc.json +22 -0
  69. package/dist/plugins/vipunen/index.d.ts +41 -0
  70. package/dist/plugins/vipunen/index.js +88 -0
  71. package/dist/plugins/vipunen/tools.d.ts +26 -0
  72. package/dist/plugins/vipunen/tools.js +501 -0
  73. package/dist/stdio-server.d.ts +14 -0
  74. package/dist/stdio-server.js +101 -0
  75. package/package.json +2 -1
  76. package/.claude/agents/agent-ada-skill-builder.md +0 -94
  77. package/.claude/agents/agent-alejandro-function-fields.md +0 -342
  78. package/.claude/agents/agent-bjorn-config-audit.md +0 -103
  79. package/.claude/agents/agent-builder-agent-creator.md +0 -130
  80. package/.claude/agents/agent-code-simplifier.md +0 -53
  81. package/.claude/agents/agent-dmitri-activity-crud.md +0 -159
  82. package/.claude/agents/agent-giuseppe-app-builder.md +0 -247
  83. package/.claude/agents/agent-gunther-mcp-tools.md +0 -39
  84. package/.claude/agents/agent-helga-workflow-config.md +0 -204
  85. package/.claude/agents/agent-igor-activity-mover-automation.md +0 -125
  86. package/.claude/agents/agent-ingrid-doc-templates.md +0 -261
  87. package/.claude/agents/agent-ivan-monolith.md +0 -154
  88. package/.claude/agents/agent-kenji-data-reader.md +0 -86
  89. package/.claude/agents/agent-lars-code-inspector.md +0 -102
  90. package/.claude/agents/agent-marco-mockup-builder.md +0 -110
  91. package/.claude/agents/agent-marcus-api-documenter.md +0 -323
  92. package/.claude/agents/agent-marketplace-publisher.md +0 -280
  93. package/.claude/agents/agent-marketplace-reviewer.md +0 -309
  94. package/.claude/agents/agent-permissions-handler.md +0 -208
  95. package/.claude/agents/agent-simple-writer.md +0 -48
  96. package/.claude/agents/agent-svetlana-code-review.md +0 -171
  97. package/.claude/agents/agent-tanya-test-runner.md +0 -333
  98. package/.claude/agents/agent-ui-designer.md +0 -100
  99. package/.claude/agents/agent-viktor-sql-insights.md +0 -212
  100. package/.claude/agents/agent-web-search.md +0 -55
  101. package/.claude/agents/agent-yevgeni-discussions.md +0 -45
  102. package/.claude/agents/agent-zara-zapier.md +0 -159
  103. package/.claude/commands/app-squad.md +0 -135
  104. package/.claude/commands/audit-squad.md +0 -158
  105. package/.claude/commands/autoplan.md +0 -563
  106. package/.claude/commands/cleanup-squad.md +0 -98
  107. package/.claude/commands/config-squad.md +0 -106
  108. package/.claude/commands/crud-squad.md +0 -87
  109. package/.claude/commands/data-squad.md +0 -97
  110. package/.claude/commands/debug-squad.md +0 -303
  111. package/.claude/commands/doc-squad.md +0 -65
  112. package/.claude/commands/handoff.md +0 -137
  113. package/.claude/commands/health.md +0 -49
  114. package/.claude/commands/help.md +0 -29
  115. package/.claude/commands/help:agents.md +0 -151
  116. package/.claude/commands/help:commands.md +0 -78
  117. package/.claude/commands/help:faq.md +0 -79
  118. package/.claude/commands/help:plugins.md +0 -50
  119. package/.claude/commands/help:skills.md +0 -93
  120. package/.claude/commands/help:tools.md +0 -75
  121. package/.claude/commands/hotfix-squad.md +0 -112
  122. package/.claude/commands/integration-squad.md +0 -82
  123. package/.claude/commands/janitor-squad.md +0 -167
  124. package/.claude/commands/learn-auto.md +0 -120
  125. package/.claude/commands/learn.md +0 -120
  126. package/.claude/commands/mcp-list.md +0 -27
  127. package/.claude/commands/onboard-squad.md +0 -140
  128. package/.claude/commands/plan-workspace.md +0 -732
  129. package/.claude/commands/prd.md +0 -130
  130. package/.claude/commands/project-status.md +0 -82
  131. package/.claude/commands/publish.md +0 -138
  132. package/.claude/commands/recap.md +0 -69
  133. package/.claude/commands/restore.md +0 -64
  134. package/.claude/commands/review-squad.md +0 -152
  135. package/.claude/commands/save.md +0 -24
  136. package/.claude/commands/stats.md +0 -19
  137. package/.claude/commands/swarm.md +0 -210
  138. package/.claude/commands/tool-builder.md +0 -39
  139. package/.claude/commands/ws-pull.md +0 -44
  140. package/.claude/hooks/_shared-memory.cjs +0 -305
  141. package/.claude/hooks/_utils.cjs +0 -108
  142. package/.claude/hooks/agent-failure-detector.cjs +0 -383
  143. package/.claude/hooks/agent-usage-logger.cjs +0 -204
  144. package/.claude/hooks/app-edit-guard.cjs +0 -494
  145. package/.claude/hooks/auto-learn.cjs +0 -304
  146. package/.claude/hooks/bash-guard.cjs +0 -272
  147. package/.claude/hooks/builder-mode-manager.cjs +0 -354
  148. package/.claude/hooks/bulk-activity-guard.cjs +0 -271
  149. package/.claude/hooks/context-watchdog.cjs +0 -230
  150. package/.claude/hooks/delegation-reminder.cjs +0 -465
  151. package/.claude/hooks/design-system-lint.cjs +0 -271
  152. package/.claude/hooks/post-scaffold-hook.cjs +0 -181
  153. package/.claude/hooks/prompt-guard.cjs +0 -354
  154. package/.claude/hooks/publish-template-guard.cjs +0 -147
  155. package/.claude/hooks/session-start.cjs +0 -35
  156. package/.claude/hooks/shared-memory-writer.cjs +0 -147
  157. package/.claude/hooks/skill-injector.cjs +0 -140
  158. package/.claude/hooks/skill-usage-logger.cjs +0 -258
  159. package/.claude/hooks/src-edit-guard.cjs +0 -240
  160. package/.claude/hooks/sync-marketplace-agents.cjs +0 -346
  161. package/.claude/settings.json +0 -257
  162. package/.claude/skills/SDK-activity-patterns/SKILL.md +0 -428
  163. package/.claude/skills/SDK-document-templates/SKILL.md +0 -1033
  164. package/.claude/skills/SDK-function-fields/SKILL.md +0 -542
  165. package/.claude/skills/SDK-generate-skill/SKILL.md +0 -92
  166. package/.claude/skills/SDK-init-skill/SKILL.md +0 -127
  167. package/.claude/skills/SDK-insight-queries/SKILL.md +0 -787
  168. package/.claude/skills/SDK-ws-config-skill/SKILL.md +0 -1139
  169. package/.claude/skills/agent-structure/SKILL.md +0 -98
  170. package/.claude/skills/api-documentation-patterns/SKILL.md +0 -474
  171. package/.claude/skills/chrome-mcp-reference/SKILL.md +0 -370
  172. package/.claude/skills/delegation-routing/SKILL.md +0 -202
  173. package/.claude/skills/frontend-design/SKILL.md +0 -254
  174. package/.claude/skills/hailer-activity-mover/SKILL.md +0 -213
  175. package/.claude/skills/hailer-api-client/SKILL.md +0 -518
  176. package/.claude/skills/hailer-app-builder/SKILL.md +0 -1434
  177. package/.claude/skills/hailer-apps-pictures/SKILL.md +0 -269
  178. package/.claude/skills/hailer-design-system/SKILL.md +0 -235
  179. package/.claude/skills/hailer-monolith-automations/SKILL.md +0 -686
  180. package/.claude/skills/hailer-permissions-system/SKILL.md +0 -121
  181. package/.claude/skills/hailer-project-protocol/SKILL.md +0 -488
  182. package/.claude/skills/hailer-rest-api/SKILL.md +0 -61
  183. package/.claude/skills/hailer-rest-api/hailer-activities.md +0 -184
  184. package/.claude/skills/hailer-rest-api/hailer-admin.md +0 -473
  185. package/.claude/skills/hailer-rest-api/hailer-calendar.md +0 -256
  186. package/.claude/skills/hailer-rest-api/hailer-feed.md +0 -249
  187. package/.claude/skills/hailer-rest-api/hailer-insights.md +0 -195
  188. package/.claude/skills/hailer-rest-api/hailer-messaging.md +0 -276
  189. package/.claude/skills/hailer-rest-api/hailer-workflows.md +0 -283
  190. package/.claude/skills/insight-join-patterns/SKILL.md +0 -174
  191. package/.claude/skills/integration-patterns/SKILL.md +0 -421
  192. package/.claude/skills/json-only-output/SKILL.md +0 -72
  193. package/.claude/skills/lsp-setup/SKILL.md +0 -160
  194. package/.claude/skills/mcp-direct-tools/SKILL.md +0 -153
  195. package/.claude/skills/optional-parameters/SKILL.md +0 -72
  196. package/.claude/skills/publish-hailer-app/SKILL.md +0 -244
  197. package/.claude/skills/testing-patterns/SKILL.md +0 -630
  198. package/.claude/skills/tool-builder/SKILL.md +0 -250
  199. package/.claude/skills/tool-parameter-usage/SKILL.md +0 -126
  200. package/.claude/skills/tool-response-verification/SKILL.md +0 -92
  201. package/.claude/skills/zapier-hailer-patterns/SKILL.md +0 -581
  202. package/.mcp.json +0 -13
  203. package/.opencode/agent/agent-ada-skill-builder.md +0 -35
  204. package/.opencode/agent/agent-alejandro-function-fields.md +0 -39
  205. package/.opencode/agent/agent-bjorn-config-audit.md +0 -36
  206. package/.opencode/agent/agent-builder-agent-creator.md +0 -39
  207. package/.opencode/agent/agent-code-simplifier.md +0 -31
  208. package/.opencode/agent/agent-dmitri-activity-crud.md +0 -40
  209. package/.opencode/agent/agent-giuseppe-app-builder.md +0 -37
  210. package/.opencode/agent/agent-gunther-mcp-tools.md +0 -39
  211. package/.opencode/agent/agent-helga-workflow-config.md +0 -203
  212. package/.opencode/agent/agent-igor-activity-mover-automation.md +0 -46
  213. package/.opencode/agent/agent-ingrid-doc-templates.md +0 -39
  214. package/.opencode/agent/agent-ivan-monolith.md +0 -46
  215. package/.opencode/agent/agent-kenji-data-reader.md +0 -53
  216. package/.opencode/agent/agent-lars-code-inspector.md +0 -28
  217. package/.opencode/agent/agent-marco-mockup-builder.md +0 -42
  218. package/.opencode/agent/agent-marcus-api-documenter.md +0 -53
  219. package/.opencode/agent/agent-marketplace-publisher.md +0 -44
  220. package/.opencode/agent/agent-marketplace-reviewer.md +0 -42
  221. package/.opencode/agent/agent-permissions-handler.md +0 -50
  222. package/.opencode/agent/agent-simple-writer.md +0 -45
  223. package/.opencode/agent/agent-svetlana-code-review.md +0 -39
  224. package/.opencode/agent/agent-tanya-test-runner.md +0 -57
  225. package/.opencode/agent/agent-ui-designer.md +0 -56
  226. package/.opencode/agent/agent-viktor-sql-insights.md +0 -34
  227. package/.opencode/agent/agent-web-search.md +0 -42
  228. package/.opencode/agent/agent-yevgeni-discussions.md +0 -37
  229. package/.opencode/agent/agent-zara-zapier.md +0 -53
  230. package/.opencode/commands/app-squad.md +0 -135
  231. package/.opencode/commands/audit-squad.md +0 -158
  232. package/.opencode/commands/autoplan.md +0 -563
  233. package/.opencode/commands/cleanup-squad.md +0 -98
  234. package/.opencode/commands/config-squad.md +0 -106
  235. package/.opencode/commands/crud-squad.md +0 -87
  236. package/.opencode/commands/data-squad.md +0 -97
  237. package/.opencode/commands/debug-squad.md +0 -303
  238. package/.opencode/commands/doc-squad.md +0 -65
  239. package/.opencode/commands/handoff.md +0 -137
  240. package/.opencode/commands/health.md +0 -49
  241. package/.opencode/commands/help-agents.md +0 -151
  242. package/.opencode/commands/help-commands.md +0 -32
  243. package/.opencode/commands/help-faq.md +0 -29
  244. package/.opencode/commands/help-plugins.md +0 -28
  245. package/.opencode/commands/help-skills.md +0 -7
  246. package/.opencode/commands/help-tools.md +0 -40
  247. package/.opencode/commands/help.md +0 -28
  248. package/.opencode/commands/hotfix-squad.md +0 -112
  249. package/.opencode/commands/integration-squad.md +0 -82
  250. package/.opencode/commands/janitor-squad.md +0 -167
  251. package/.opencode/commands/learn-auto.md +0 -120
  252. package/.opencode/commands/learn.md +0 -120
  253. package/.opencode/commands/mcp-list.md +0 -27
  254. package/.opencode/commands/onboard-squad.md +0 -140
  255. package/.opencode/commands/plan-workspace.md +0 -732
  256. package/.opencode/commands/prd.md +0 -131
  257. package/.opencode/commands/project-status.md +0 -82
  258. package/.opencode/commands/publish.md +0 -138
  259. package/.opencode/commands/recap.md +0 -69
  260. package/.opencode/commands/restore.md +0 -64
  261. package/.opencode/commands/review-squad.md +0 -152
  262. package/.opencode/commands/save.md +0 -24
  263. package/.opencode/commands/stats.md +0 -19
  264. package/.opencode/commands/swarm.md +0 -210
  265. package/.opencode/commands/tool-builder.md +0 -39
  266. package/.opencode/commands/ws-pull.md +0 -44
  267. package/.opencode/opencode.json +0 -28
  268. package/SESSION-HANDOFF.md +0 -68
  269. package/inbox/2026-03-04-bot-config-patterns.md +0 -24
  270. package/scripts/postinstall.cjs +0 -64
  271. package/scripts/test-hal-tools.ts +0 -154
@@ -1,271 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * <hook-name>design-system-lint</hook-name>
4
- *
5
- * <purpose>
6
- * Warns if app code doesn't follow Hailer Design System patterns.
7
- * Runs after Giuseppe writes/edits files in app directories.
8
- * </purpose>
9
- *
10
- * <triggers>
11
- * - PostToolUse on Write and Edit
12
- * - Only for files in apps/ or containing Chakra imports
13
- * </triggers>
14
- *
15
- * <checks>
16
- * - Hardcoded colors (hex, rgb, hsl)
17
- * - External icon libraries (react-icons, heroicons, etc.)
18
- * - Plain HTML table elements instead of Chakra Table
19
- * - Missing theme import when using ChakraProvider
20
- * </checks>
21
- *
22
- * <behavior>
23
- * 1. Check if file is in app directory or has Chakra imports
24
- * 2. Scan content for violations
25
- * 3. Output warnings to stderr (non-blocking)
26
- * </behavior>
27
- */
28
-
29
- const fs = require('fs');
30
- const path = require('path');
31
-
32
- // Read hook input from stdin
33
- let input = '';
34
- process.stdin.setEncoding('utf8');
35
- process.stdin.on('data', chunk => input += chunk);
36
- process.stdin.on('end', () => {
37
- try {
38
- const data = JSON.parse(input);
39
- processHook(data);
40
- } catch (e) {
41
- console.error(`[design-system-lint] Warning: ${e.message}`);
42
- process.exit(0);
43
- }
44
- });
45
-
46
- // Design system violation patterns
47
- const VIOLATIONS = [
48
- {
49
- name: 'hardcoded-hex-color',
50
- pattern: /(?:color|bg|background|border|fill|stroke)[:=]\s*(?:["'`]#[0-9a-fA-F]{3,8}["'`]|\$\{[^}]*#[0-9a-fA-F]{3,8}[^}]*\})/g,
51
- message: 'Hardcoded hex color found',
52
- suggestion: 'Use Chakra color tokens (e.g., "gray.500", "green.400") or semantic tokens ("subtleText", "bodyText")'
53
- },
54
- {
55
- name: 'hardcoded-rgb-color',
56
- pattern: /(?:color|bg|background|border)[:=]\s*(?:["'`]rgba?\([^)]+\)["'`]|\$\{[^}]*rgba?\([^)]+\)[^}]*\})/g,
57
- message: 'Hardcoded RGB/RGBA color found',
58
- suggestion: 'Use Chakra color tokens instead'
59
- },
60
- {
61
- name: 'external-icons',
62
- pattern: /import\s+.*\s+from\s+["'](react-icons|@heroicons|@fortawesome|lucide-react|@tabler\/icons)/g,
63
- message: 'External icon library imported',
64
- suggestion: 'Use Hailer icons from design-system/theme/icons (e.g., HailerPlus, HailerSettings)'
65
- },
66
- {
67
- name: 'plain-html-table',
68
- pattern: /<(table|thead|tbody|tr|th|td)[\s>]/gi,
69
- message: 'Plain HTML table elements found',
70
- suggestion: 'Use Chakra UI Table components: <Table>, <Thead>, <Tbody>, <Tr>, <Th>, <Td>'
71
- },
72
- {
73
- name: 'missing-theme-import',
74
- pattern: /ChakraProvider/,
75
- message: 'ChakraProvider without theme prop',
76
- suggestion: 'Import and pass the Hailer theme: <ChakraProvider theme={theme}>'
77
- },
78
- {
79
- name: 'inline-style',
80
- pattern: /style\s*=\s*\{\s*\{[^}]*(?:color|background|border)[^}]*\}\s*\}/g,
81
- message: 'Inline style with color/background',
82
- suggestion: 'Use Chakra style props instead of inline styles'
83
- },
84
- {
85
- name: 'wrong-stat-pattern',
86
- pattern: /<Box[^>]*>[\s\S]*?<Text[^>]*fontSize=["']sm["'][^>]*>[\s\S]*?<\/Text>[\s\S]*?<(?:Heading|Text)[^>]*fontSize=["'](?:2xl|3xl|xl)["']/g,
87
- message: 'Manual stat card pattern detected',
88
- suggestion: 'Use Chakra Stat components: <Stat>, <StatLabel>, <StatNumber>, <StatHelpText>'
89
- }
90
- ];
91
-
92
- // Files/patterns to skip
93
- const SKIP_PATTERNS = [
94
- /node_modules/,
95
- /\.d\.ts$/,
96
- /\.json$/,
97
- /\.md$/,
98
- /\.css$/,
99
- /theme\.ts$/, // Don't lint the theme file itself
100
- /customColors\.ts$/
101
- ];
102
-
103
- function shouldLintFile(filePath) {
104
- // Skip certain files
105
- for (const pattern of SKIP_PATTERNS) {
106
- if (pattern.test(filePath)) {
107
- return false;
108
- }
109
- }
110
-
111
- // Check if it's in apps/ directory
112
- if (filePath.includes('/apps/') || filePath.includes('\\apps\\')) {
113
- return true;
114
- }
115
-
116
- // Check if it's a TypeScript/JavaScript file that might be an app
117
- if (/\.(tsx?|jsx?)$/.test(filePath)) {
118
- return true;
119
- }
120
-
121
- return false;
122
- }
123
-
124
- function lintContent(content, filePath) {
125
- const warnings = [];
126
-
127
- // Only lint if file has Chakra imports (indicates it's a UI file)
128
- const hasChakraImport = content.includes('@chakra-ui/react') || content.includes('chakra-ui');
129
- const isInApps = filePath.includes('/apps/') || filePath.includes('\\apps\\');
130
-
131
- if (!hasChakraImport && !isInApps) {
132
- return warnings;
133
- }
134
-
135
- // Single-pass scan: loop through violations once, check content for each pattern
136
- // Performance: O(n*m) where n=violations, m=pattern matches. Acceptable for typical files (<50KB)
137
- for (const violation of VIOLATIONS) {
138
- const matches = content.match(violation.pattern);
139
- if (matches) {
140
- // Special handling for missing-theme-import
141
- if (violation.name === 'missing-theme-import') {
142
- // Only warn if ChakraProvider exists but no theme= prop nearby
143
- if (content.includes('ChakraProvider') && !content.includes('theme={') && !content.includes('theme=')) {
144
- warnings.push({
145
- name: violation.name,
146
- message: violation.message,
147
- suggestion: violation.suggestion,
148
- count: 1
149
- });
150
- }
151
- continue;
152
- }
153
-
154
- warnings.push({
155
- name: violation.name,
156
- message: violation.message,
157
- suggestion: violation.suggestion,
158
- count: matches.length,
159
- examples: matches.slice(0, 2).map(m => m.substring(0, 60))
160
- });
161
- }
162
- }
163
-
164
- return warnings;
165
- }
166
-
167
- function processHook(data) {
168
- const { tool_name, tool_input, tool_response } = data;
169
-
170
- // Only check Write and Edit tools on PostToolUse
171
- if (tool_name !== 'Write' && tool_name !== 'Edit') {
172
- process.exit(0);
173
- }
174
-
175
- // Need tool_response to confirm it's PostToolUse
176
- if (tool_response === undefined) {
177
- process.exit(0);
178
- }
179
-
180
- const filePath = tool_input?.file_path;
181
- if (!filePath) {
182
- process.exit(0);
183
- }
184
-
185
- // Check if we should lint this file
186
- if (!shouldLintFile(filePath)) {
187
- process.exit(0);
188
- }
189
-
190
- // Read the file content
191
- let content;
192
- try {
193
- content = fs.readFileSync(filePath, 'utf8');
194
- } catch (e) {
195
- console.error(`[design-system-lint] Warning: ${e.message}`);
196
- process.exit(0);
197
- }
198
-
199
- // Lint the content
200
- const warnings = lintContent(content, filePath);
201
-
202
- if (warnings.length > 0) {
203
- const output = `
204
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
205
- 🎨 DESIGN SYSTEM LINT WARNINGS
206
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
207
-
208
- File: ${path.basename(filePath)}
209
-
210
- ${warnings.map(w => `
211
- ⚠️ ${w.message}${w.count > 1 ? ` (${w.count} occurrences)` : ''}
212
- → ${w.suggestion}
213
- ${w.examples ? w.examples.map(e => ` Example: ${e}...`).join('\n') : ''}`).join('\n')}
214
-
215
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
216
- 📚 Reference: Load \`hailer-design-system\` skill for full guide
217
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
218
- `;
219
- console.error(output);
220
- }
221
-
222
- process.exit(0);
223
- }
224
-
225
- // CLI: Lint a specific file
226
- if (process.argv[2] && !process.argv[2].startsWith('-')) {
227
- const filePath = path.resolve(process.argv[2]);
228
-
229
- if (!fs.existsSync(filePath)) {
230
- console.error(`File not found: ${filePath}`);
231
- process.exit(1);
232
- }
233
-
234
- const content = fs.readFileSync(filePath, 'utf8');
235
- const warnings = lintContent(content, filePath);
236
-
237
- if (warnings.length === 0) {
238
- console.log(`✅ No design system issues found in ${path.basename(filePath)}`);
239
- } else {
240
- console.log(`Found ${warnings.length} issue(s) in ${path.basename(filePath)}:\n`);
241
- for (const w of warnings) {
242
- console.log(`⚠️ ${w.message}${w.count > 1 ? ` (${w.count}x)` : ''}`);
243
- console.log(` → ${w.suggestion}\n`);
244
- }
245
- }
246
- process.exit(0);
247
- }
248
-
249
- // CLI: Help
250
- if (process.argv[2] === '--help' || process.argv[2] === '-h') {
251
- console.log(`
252
- Design System Lint - Checks app code for Hailer Design System compliance
253
-
254
- Usage:
255
- node design-system-lint.cjs <file> Lint a specific file
256
- node design-system-lint.cjs --help Show this help
257
-
258
- Checks for:
259
- - Hardcoded colors (hex, rgb, rgba)
260
- - External icon libraries
261
- - Plain HTML table elements
262
- - Missing theme in ChakraProvider
263
- - Inline styles with colors
264
- - Manual stat card patterns
265
-
266
- As a hook:
267
- PostToolUse on Write/Edit
268
- Outputs warnings to stderr (non-blocking)
269
- `);
270
- process.exit(0);
271
- }
@@ -1,181 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * <hook-name>post-scaffold-hook</hook-name>
4
- *
5
- * <purpose>
6
- * Prompts user to spawn builder agent after scaffold_hailer_app completes.
7
- * Registers new app with app-edit-guard for edit protection.
8
- * </purpose>
9
- *
10
- * <triggers>
11
- * - PostToolUse on mcp__hailer__scaffold_hailer_app
12
- * - Only when output contains "Setup Complete"
13
- * </triggers>
14
- *
15
- * <behavior>
16
- * 1. Detects successful scaffold completion
17
- * 2. Registers app in /tmp/.claude-scaffolded-apps/
18
- * 3. Outputs AskUserQuestion template for builder spawn decision
19
- * 4. Provides instructions for both "spawn builder" and "build manually" paths
20
- * </behavior>
21
- *
22
- * <user-choices>
23
- * - "Yes, spawn builder": Load spawn-app-builder skill, spawn giuseppe
24
- * - "No, build manually": Load building-hailer-apps-skill in current session
25
- * </user-choices>
26
- *
27
- * <tracker-dir>/tmp/.claude-scaffolded-apps/</tracker-dir>
28
- */
29
-
30
- const path = require('path');
31
- const fs = require('fs');
32
- const os = require('os');
33
-
34
- const TEMP_DIR = os.tmpdir();
35
- const TRACKER_DIR = path.join(TEMP_DIR, '.claude-scaffolded-apps');
36
-
37
- // Ensure tracker directory exists
38
- if (!fs.existsSync(TRACKER_DIR)) {
39
- fs.mkdirSync(TRACKER_DIR, { recursive: true });
40
- }
41
-
42
- // Read hook input from stdin
43
- let input = '';
44
- process.stdin.setEncoding('utf8');
45
- process.stdin.on('data', chunk => input += chunk);
46
- process.stdin.on('end', () => {
47
- try {
48
- const data = JSON.parse(input);
49
- processHook(data);
50
- } catch {
51
- // Invalid JSON, exit silently
52
- process.exit(0);
53
- }
54
- });
55
-
56
- function processHook(data) {
57
- const { tool_name, tool_input, tool_output } = data;
58
-
59
- // Only trigger for scaffold_hailer_app
60
- if (tool_name !== 'mcp__hailer__scaffold_hailer_app') {
61
- process.exit(0);
62
- }
63
-
64
- // Check if scaffold was successful (look for "Setup Complete" in output)
65
- if (!tool_output || !tool_output.includes('Setup Complete')) {
66
- process.exit(0);
67
- }
68
-
69
- // Extract project info from tool_input
70
- const projectName = tool_input?.projectName || 'the app';
71
- const description = tool_input?.description || 'Hailer data app';
72
-
73
- // Try to determine project path
74
- const cwd = process.env.CLAUDE_PROJECT_DIR || process.cwd();
75
- const projectPath = tool_input?.targetDirectory
76
- ? path.join(tool_input.targetDirectory, projectName)
77
- : path.join(cwd, projectName);
78
-
79
- // Register app with edit guard to block direct edits
80
- registerScaffoldedApp(projectName, projectPath);
81
-
82
- // Build the AskUserQuestion instruction
83
- const output = `
84
- ============================================================
85
- ✅ App Scaffolded Successfully!
86
- ============================================================
87
-
88
- **Project:** ${projectName}
89
- **Location:** ${projectPath}
90
- **Dev Server:** http://localhost:3000 (running)
91
-
92
- The app structure is ready. Now you need to build the actual components.
93
-
94
- ----------------------------------------
95
- ⚠️ MANDATORY: ASK THE USER
96
- ----------------------------------------
97
-
98
- You MUST use AskUserQuestion with EXACTLY this format:
99
-
100
- \`\`\`json
101
- {
102
- "questions": [
103
- {
104
- "question": "Would you like me to spawn a builder agent to create the app components?",
105
- "header": "Build App",
106
- "options": [
107
- {
108
- "label": "Yes, spawn builder",
109
- "description": "Spawn isolated agent with TypeScript + SDK patterns"
110
- },
111
- {
112
- "label": "No, I'll build manually",
113
- "description": "Continue in current session"
114
- }
115
- ],
116
- "multiSelect": false
117
- }
118
- ]
119
- }
120
- \`\`\`
121
-
122
- ----------------------------------------
123
- IF USER SAYS YES: Follow these steps
124
- ----------------------------------------
125
-
126
- 0. Enable builder mode (required for Giuseppe to edit app files):
127
- \`\`\`bash
128
- node .claude/hooks/app-edit-guard.cjs --agent-on
129
- \`\`\`
130
-
131
- 1. Load the spawn-app-builder skill:
132
- \`\`\`javascript
133
- Skill("spawn-app-builder")
134
- \`\`\`
135
-
136
- 2. Get workflow context:
137
- \`\`\`javascript
138
- list_workflows_minimal()
139
- \`\`\`
140
-
141
- 3. Use the Task tool template from the skill with:
142
- - PROJECT_PATH: ${projectPath}
143
- - TASK_DESCRIPTION: ${description}
144
- - WORKFLOWS_INFO: (from list_workflows_minimal)
145
-
146
- ----------------------------------------
147
- IF USER SAYS NO: Load skills in current session
148
- ----------------------------------------
149
-
150
- \`\`\`javascript
151
- Skill("building-hailer-apps-skill")
152
- Skill("hailer-app-builder")
153
- \`\`\`
154
-
155
- Then continue building in the current conversation.
156
-
157
- ============================================================
158
- ASK THE USER NOW - Do not skip this question!
159
- ============================================================
160
- `;
161
-
162
- console.log(JSON.stringify({ decision: 'allow', message: output }));
163
- process.exit(0);
164
- }
165
-
166
- /**
167
- * Register scaffolded app in tracker so app-edit-guard can block direct edits
168
- */
169
- function registerScaffoldedApp(name, appPath) {
170
- try {
171
- const trackerFile = path.join(TRACKER_DIR, `${name}.json`);
172
- fs.writeFileSync(trackerFile, JSON.stringify({
173
- name,
174
- path: path.resolve(appPath),
175
- scaffoldedAt: new Date().toISOString()
176
- }));
177
- console.error(`📝 Registered app "${name}" for edit protection`);
178
- } catch (err) {
179
- console.error(`Warning: Could not register app for edit protection: ${err.message}`);
180
- }
181
- }