@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.
- package/CHANGELOG.md +0 -7
- package/{.claude → dist}/CLAUDE.md +2 -2
- package/dist/app.js +18 -5
- package/dist/bot/bot-config.d.ts +10 -1
- package/dist/bot/bot-config.js +64 -3
- package/dist/bot/bot-manager.d.ts +2 -0
- package/dist/bot/bot-manager.js +9 -2
- package/dist/bot/bot.d.ts +33 -0
- package/dist/bot/bot.js +461 -160
- package/dist/bot/services/message-classifier.js +17 -0
- package/dist/bot/services/permission-guard.d.ts +52 -0
- package/dist/bot/services/permission-guard.js +149 -0
- package/dist/bot/services/types.d.ts +5 -0
- package/dist/bot/services/typing-indicator.d.ts +6 -1
- package/dist/bot/services/typing-indicator.js +19 -3
- package/dist/cli.js +0 -0
- package/dist/config.d.ts +6 -1
- package/dist/config.js +43 -0
- package/dist/core.js +3 -6
- package/dist/lib/discussion-lock.d.ts +42 -0
- package/dist/lib/discussion-lock.js +110 -0
- package/dist/mcp/UserContextCache.d.ts +5 -0
- package/dist/mcp/UserContextCache.js +51 -19
- package/dist/mcp/hailer-clients.d.ts +19 -1
- package/dist/mcp/hailer-clients.js +158 -24
- package/dist/mcp/session-store.d.ts +68 -0
- package/dist/mcp/session-store.js +169 -0
- package/dist/mcp/signal-handler.js +2 -0
- package/dist/mcp/tool-registry.d.ts +17 -4
- package/dist/mcp/tool-registry.js +37 -7
- package/dist/mcp/tools/activity.js +99 -7
- package/dist/mcp/tools/app-scaffold.js +304 -336
- package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
- package/dist/mcp/tools/bot-config/constants.js +94 -0
- package/dist/mcp/tools/bot-config/core.d.ts +253 -0
- package/dist/mcp/tools/bot-config/core.js +2456 -0
- package/dist/mcp/tools/bot-config/index.d.ts +10 -0
- package/dist/mcp/tools/bot-config/index.js +59 -0
- package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
- package/dist/mcp/tools/bot-config/tools.js +15 -0
- package/dist/mcp/tools/bot-config/types.d.ts +50 -0
- package/dist/mcp/tools/bot-config/types.js +6 -0
- package/dist/mcp/tools/bug-fixer-tools.d.ts +45 -0
- package/dist/mcp/tools/bug-fixer-tools.js +1096 -0
- package/dist/mcp/tools/company.d.ts +9 -0
- package/dist/mcp/tools/company.js +88 -0
- package/dist/mcp/tools/discussion.js +68 -0
- package/dist/mcp/tools/document.d.ts +11 -0
- package/dist/mcp/tools/document.js +741 -0
- package/dist/mcp/tools/investigate.d.ts +9 -0
- package/dist/mcp/tools/investigate.js +254 -0
- package/dist/mcp/tools/workflow-permissions.d.ts +15 -0
- package/dist/mcp/tools/workflow-permissions.js +204 -0
- package/dist/mcp/tools/workflow.js +57 -18
- package/dist/mcp/utils/index.d.ts +2 -0
- package/dist/mcp/utils/index.js +12 -1
- package/dist/mcp/utils/role-utils.d.ts +74 -0
- package/dist/mcp/utils/role-utils.js +151 -0
- package/dist/mcp/utils/types.d.ts +43 -1
- package/dist/mcp/utils/types.js +14 -0
- package/dist/mcp/webhook-handler.d.ts +4 -0
- package/dist/mcp/webhook-handler.js +8 -0
- package/dist/mcp-server.d.ts +23 -2
- package/dist/mcp-server.js +639 -127
- package/dist/plugins/vipunen/client.d.ts +150 -0
- package/dist/plugins/vipunen/client.js +535 -0
- package/dist/plugins/vipunen/config/schema-config.json +19 -0
- package/dist/plugins/vipunen/config/schema-doc.json +22 -0
- package/dist/plugins/vipunen/index.d.ts +41 -0
- package/dist/plugins/vipunen/index.js +88 -0
- package/dist/plugins/vipunen/tools.d.ts +26 -0
- package/dist/plugins/vipunen/tools.js +501 -0
- package/dist/stdio-server.d.ts +14 -0
- package/dist/stdio-server.js +101 -0
- package/package.json +2 -1
- package/.claude/agents/agent-ada-skill-builder.md +0 -94
- package/.claude/agents/agent-alejandro-function-fields.md +0 -342
- package/.claude/agents/agent-bjorn-config-audit.md +0 -103
- package/.claude/agents/agent-builder-agent-creator.md +0 -130
- package/.claude/agents/agent-code-simplifier.md +0 -53
- package/.claude/agents/agent-dmitri-activity-crud.md +0 -159
- package/.claude/agents/agent-giuseppe-app-builder.md +0 -247
- package/.claude/agents/agent-gunther-mcp-tools.md +0 -39
- package/.claude/agents/agent-helga-workflow-config.md +0 -204
- package/.claude/agents/agent-igor-activity-mover-automation.md +0 -125
- package/.claude/agents/agent-ingrid-doc-templates.md +0 -261
- package/.claude/agents/agent-ivan-monolith.md +0 -154
- package/.claude/agents/agent-kenji-data-reader.md +0 -86
- package/.claude/agents/agent-lars-code-inspector.md +0 -102
- package/.claude/agents/agent-marco-mockup-builder.md +0 -110
- package/.claude/agents/agent-marcus-api-documenter.md +0 -323
- package/.claude/agents/agent-marketplace-publisher.md +0 -280
- package/.claude/agents/agent-marketplace-reviewer.md +0 -309
- package/.claude/agents/agent-permissions-handler.md +0 -208
- package/.claude/agents/agent-simple-writer.md +0 -48
- package/.claude/agents/agent-svetlana-code-review.md +0 -171
- package/.claude/agents/agent-tanya-test-runner.md +0 -333
- package/.claude/agents/agent-ui-designer.md +0 -100
- package/.claude/agents/agent-viktor-sql-insights.md +0 -212
- package/.claude/agents/agent-web-search.md +0 -55
- package/.claude/agents/agent-yevgeni-discussions.md +0 -45
- package/.claude/agents/agent-zara-zapier.md +0 -159
- package/.claude/commands/app-squad.md +0 -135
- package/.claude/commands/audit-squad.md +0 -158
- package/.claude/commands/autoplan.md +0 -563
- package/.claude/commands/cleanup-squad.md +0 -98
- package/.claude/commands/config-squad.md +0 -106
- package/.claude/commands/crud-squad.md +0 -87
- package/.claude/commands/data-squad.md +0 -97
- package/.claude/commands/debug-squad.md +0 -303
- package/.claude/commands/doc-squad.md +0 -65
- package/.claude/commands/handoff.md +0 -137
- package/.claude/commands/health.md +0 -49
- package/.claude/commands/help.md +0 -29
- package/.claude/commands/help:agents.md +0 -151
- package/.claude/commands/help:commands.md +0 -78
- package/.claude/commands/help:faq.md +0 -79
- package/.claude/commands/help:plugins.md +0 -50
- package/.claude/commands/help:skills.md +0 -93
- package/.claude/commands/help:tools.md +0 -75
- package/.claude/commands/hotfix-squad.md +0 -112
- package/.claude/commands/integration-squad.md +0 -82
- package/.claude/commands/janitor-squad.md +0 -167
- package/.claude/commands/learn-auto.md +0 -120
- package/.claude/commands/learn.md +0 -120
- package/.claude/commands/mcp-list.md +0 -27
- package/.claude/commands/onboard-squad.md +0 -140
- package/.claude/commands/plan-workspace.md +0 -732
- package/.claude/commands/prd.md +0 -130
- package/.claude/commands/project-status.md +0 -82
- package/.claude/commands/publish.md +0 -138
- package/.claude/commands/recap.md +0 -69
- package/.claude/commands/restore.md +0 -64
- package/.claude/commands/review-squad.md +0 -152
- package/.claude/commands/save.md +0 -24
- package/.claude/commands/stats.md +0 -19
- package/.claude/commands/swarm.md +0 -210
- package/.claude/commands/tool-builder.md +0 -39
- package/.claude/commands/ws-pull.md +0 -44
- package/.claude/hooks/_shared-memory.cjs +0 -305
- package/.claude/hooks/_utils.cjs +0 -108
- package/.claude/hooks/agent-failure-detector.cjs +0 -383
- package/.claude/hooks/agent-usage-logger.cjs +0 -204
- package/.claude/hooks/app-edit-guard.cjs +0 -494
- package/.claude/hooks/auto-learn.cjs +0 -304
- package/.claude/hooks/bash-guard.cjs +0 -272
- package/.claude/hooks/builder-mode-manager.cjs +0 -354
- package/.claude/hooks/bulk-activity-guard.cjs +0 -271
- package/.claude/hooks/context-watchdog.cjs +0 -230
- package/.claude/hooks/delegation-reminder.cjs +0 -465
- package/.claude/hooks/design-system-lint.cjs +0 -271
- package/.claude/hooks/post-scaffold-hook.cjs +0 -181
- package/.claude/hooks/prompt-guard.cjs +0 -354
- package/.claude/hooks/publish-template-guard.cjs +0 -147
- package/.claude/hooks/session-start.cjs +0 -35
- package/.claude/hooks/shared-memory-writer.cjs +0 -147
- package/.claude/hooks/skill-injector.cjs +0 -140
- package/.claude/hooks/skill-usage-logger.cjs +0 -258
- package/.claude/hooks/src-edit-guard.cjs +0 -240
- package/.claude/hooks/sync-marketplace-agents.cjs +0 -346
- package/.claude/settings.json +0 -257
- package/.claude/skills/SDK-activity-patterns/SKILL.md +0 -428
- package/.claude/skills/SDK-document-templates/SKILL.md +0 -1033
- package/.claude/skills/SDK-function-fields/SKILL.md +0 -542
- package/.claude/skills/SDK-generate-skill/SKILL.md +0 -92
- package/.claude/skills/SDK-init-skill/SKILL.md +0 -127
- package/.claude/skills/SDK-insight-queries/SKILL.md +0 -787
- package/.claude/skills/SDK-ws-config-skill/SKILL.md +0 -1139
- package/.claude/skills/agent-structure/SKILL.md +0 -98
- package/.claude/skills/api-documentation-patterns/SKILL.md +0 -474
- package/.claude/skills/chrome-mcp-reference/SKILL.md +0 -370
- package/.claude/skills/delegation-routing/SKILL.md +0 -202
- package/.claude/skills/frontend-design/SKILL.md +0 -254
- package/.claude/skills/hailer-activity-mover/SKILL.md +0 -213
- package/.claude/skills/hailer-api-client/SKILL.md +0 -518
- package/.claude/skills/hailer-app-builder/SKILL.md +0 -1434
- package/.claude/skills/hailer-apps-pictures/SKILL.md +0 -269
- package/.claude/skills/hailer-design-system/SKILL.md +0 -235
- package/.claude/skills/hailer-monolith-automations/SKILL.md +0 -686
- package/.claude/skills/hailer-permissions-system/SKILL.md +0 -121
- package/.claude/skills/hailer-project-protocol/SKILL.md +0 -488
- package/.claude/skills/hailer-rest-api/SKILL.md +0 -61
- package/.claude/skills/hailer-rest-api/hailer-activities.md +0 -184
- package/.claude/skills/hailer-rest-api/hailer-admin.md +0 -473
- package/.claude/skills/hailer-rest-api/hailer-calendar.md +0 -256
- package/.claude/skills/hailer-rest-api/hailer-feed.md +0 -249
- package/.claude/skills/hailer-rest-api/hailer-insights.md +0 -195
- package/.claude/skills/hailer-rest-api/hailer-messaging.md +0 -276
- package/.claude/skills/hailer-rest-api/hailer-workflows.md +0 -283
- package/.claude/skills/insight-join-patterns/SKILL.md +0 -174
- package/.claude/skills/integration-patterns/SKILL.md +0 -421
- package/.claude/skills/json-only-output/SKILL.md +0 -72
- package/.claude/skills/lsp-setup/SKILL.md +0 -160
- package/.claude/skills/mcp-direct-tools/SKILL.md +0 -153
- package/.claude/skills/optional-parameters/SKILL.md +0 -72
- package/.claude/skills/publish-hailer-app/SKILL.md +0 -244
- package/.claude/skills/testing-patterns/SKILL.md +0 -630
- package/.claude/skills/tool-builder/SKILL.md +0 -250
- package/.claude/skills/tool-parameter-usage/SKILL.md +0 -126
- package/.claude/skills/tool-response-verification/SKILL.md +0 -92
- package/.claude/skills/zapier-hailer-patterns/SKILL.md +0 -581
- package/.mcp.json +0 -13
- package/.opencode/agent/agent-ada-skill-builder.md +0 -35
- package/.opencode/agent/agent-alejandro-function-fields.md +0 -39
- package/.opencode/agent/agent-bjorn-config-audit.md +0 -36
- package/.opencode/agent/agent-builder-agent-creator.md +0 -39
- package/.opencode/agent/agent-code-simplifier.md +0 -31
- package/.opencode/agent/agent-dmitri-activity-crud.md +0 -40
- package/.opencode/agent/agent-giuseppe-app-builder.md +0 -37
- package/.opencode/agent/agent-gunther-mcp-tools.md +0 -39
- package/.opencode/agent/agent-helga-workflow-config.md +0 -203
- package/.opencode/agent/agent-igor-activity-mover-automation.md +0 -46
- package/.opencode/agent/agent-ingrid-doc-templates.md +0 -39
- package/.opencode/agent/agent-ivan-monolith.md +0 -46
- package/.opencode/agent/agent-kenji-data-reader.md +0 -53
- package/.opencode/agent/agent-lars-code-inspector.md +0 -28
- package/.opencode/agent/agent-marco-mockup-builder.md +0 -42
- package/.opencode/agent/agent-marcus-api-documenter.md +0 -53
- package/.opencode/agent/agent-marketplace-publisher.md +0 -44
- package/.opencode/agent/agent-marketplace-reviewer.md +0 -42
- package/.opencode/agent/agent-permissions-handler.md +0 -50
- package/.opencode/agent/agent-simple-writer.md +0 -45
- package/.opencode/agent/agent-svetlana-code-review.md +0 -39
- package/.opencode/agent/agent-tanya-test-runner.md +0 -57
- package/.opencode/agent/agent-ui-designer.md +0 -56
- package/.opencode/agent/agent-viktor-sql-insights.md +0 -34
- package/.opencode/agent/agent-web-search.md +0 -42
- package/.opencode/agent/agent-yevgeni-discussions.md +0 -37
- package/.opencode/agent/agent-zara-zapier.md +0 -53
- package/.opencode/commands/app-squad.md +0 -135
- package/.opencode/commands/audit-squad.md +0 -158
- package/.opencode/commands/autoplan.md +0 -563
- package/.opencode/commands/cleanup-squad.md +0 -98
- package/.opencode/commands/config-squad.md +0 -106
- package/.opencode/commands/crud-squad.md +0 -87
- package/.opencode/commands/data-squad.md +0 -97
- package/.opencode/commands/debug-squad.md +0 -303
- package/.opencode/commands/doc-squad.md +0 -65
- package/.opencode/commands/handoff.md +0 -137
- package/.opencode/commands/health.md +0 -49
- package/.opencode/commands/help-agents.md +0 -151
- package/.opencode/commands/help-commands.md +0 -32
- package/.opencode/commands/help-faq.md +0 -29
- package/.opencode/commands/help-plugins.md +0 -28
- package/.opencode/commands/help-skills.md +0 -7
- package/.opencode/commands/help-tools.md +0 -40
- package/.opencode/commands/help.md +0 -28
- package/.opencode/commands/hotfix-squad.md +0 -112
- package/.opencode/commands/integration-squad.md +0 -82
- package/.opencode/commands/janitor-squad.md +0 -167
- package/.opencode/commands/learn-auto.md +0 -120
- package/.opencode/commands/learn.md +0 -120
- package/.opencode/commands/mcp-list.md +0 -27
- package/.opencode/commands/onboard-squad.md +0 -140
- package/.opencode/commands/plan-workspace.md +0 -732
- package/.opencode/commands/prd.md +0 -131
- package/.opencode/commands/project-status.md +0 -82
- package/.opencode/commands/publish.md +0 -138
- package/.opencode/commands/recap.md +0 -69
- package/.opencode/commands/restore.md +0 -64
- package/.opencode/commands/review-squad.md +0 -152
- package/.opencode/commands/save.md +0 -24
- package/.opencode/commands/stats.md +0 -19
- package/.opencode/commands/swarm.md +0 -210
- package/.opencode/commands/tool-builder.md +0 -39
- package/.opencode/commands/ws-pull.md +0 -44
- package/.opencode/opencode.json +0 -28
- package/SESSION-HANDOFF.md +0 -68
- package/inbox/2026-03-04-bot-config-patterns.md +0 -24
- package/scripts/postinstall.cjs +0 -64
- 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
|
-
}
|