@hailer/mcp 0.0.6 → 0.1.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 (122) hide show
  1. package/.claude/agents/ada.md +127 -0
  2. package/.claude/agents/agent-builder.md +151 -0
  3. package/.claude/agents/alejandro.md +66 -0
  4. package/.claude/agents/bjorn.md +305 -0
  5. package/.claude/agents/dmitri.md +61 -0
  6. package/.claude/agents/giuseppe.md +66 -0
  7. package/.claude/agents/gunther.md +355 -0
  8. package/.claude/agents/helga.md +68 -0
  9. package/.claude/agents/ingrid.md +108 -0
  10. package/.claude/agents/kenji.md +58 -0
  11. package/.claude/agents/svetlana.md +394 -0
  12. package/.claude/agents/viktor.md +63 -0
  13. package/.claude/agents/yevgeni.md +60 -0
  14. package/.claude/hooks/agent-failure-detector.cjs +286 -0
  15. package/.claude/hooks/app-edit-guard.cjs +462 -0
  16. package/.claude/hooks/interactive-mode.cjs +59 -0
  17. package/.claude/hooks/mcp-server-guard.cjs +92 -0
  18. package/.claude/hooks/post-scaffold-hook.cjs +31 -0
  19. package/.claude/hooks/sdk-delete-guard.cjs +2 -0
  20. package/.claude/hooks/src-edit-guard.cjs +208 -0
  21. package/.claude/settings.json +47 -2
  22. package/.claude/skills/insight-join-patterns/SKILL.md +209 -0
  23. package/.env.example +13 -1
  24. package/CLAUDE.md +135 -0
  25. package/dist/app.js +4 -3
  26. package/dist/cli.js +0 -0
  27. package/dist/client/adaptive-documentation-bot.d.ts +0 -2
  28. package/dist/client/adaptive-documentation-bot.js +5 -16
  29. package/dist/client/message-processor.js +5 -0
  30. package/dist/client/providers/anthropic-provider.js +21 -7
  31. package/dist/mcp/UserContextCache.d.ts +14 -0
  32. package/dist/mcp/UserContextCache.js +49 -24
  33. package/dist/mcp/auth.d.ts +7 -0
  34. package/dist/mcp/auth.js +13 -5
  35. package/dist/mcp/hailer-clients.d.ts +5 -2
  36. package/dist/mcp/signal-handler.d.ts +28 -2
  37. package/dist/mcp/signal-handler.js +4 -2
  38. package/dist/mcp/tool-registry.d.ts +55 -2
  39. package/dist/mcp/tool-registry.js +197 -2
  40. package/dist/mcp/tools/app-core.d.ts +15 -0
  41. package/dist/mcp/tools/app-core.js +609 -0
  42. package/dist/mcp/tools/app-marketplace.d.ts +21 -0
  43. package/dist/mcp/tools/app-marketplace.js +1284 -0
  44. package/dist/mcp/tools/app-member.d.ts +11 -0
  45. package/dist/mcp/tools/app-member.js +258 -0
  46. package/dist/mcp/tools/app-scaffold.d.ts +11 -0
  47. package/dist/mcp/tools/app-scaffold.js +743 -0
  48. package/dist/mcp/tools/app.d.ts +13 -22
  49. package/dist/mcp/tools/app.js +17 -2466
  50. package/dist/mcp/tools/file.js +6 -6
  51. package/dist/mcp/tools/insight.d.ts +1 -0
  52. package/dist/mcp/tools/insight.js +203 -64
  53. package/dist/mcp/tools/user.js +3 -9
  54. package/dist/mcp/tools/workflow.js +49 -38
  55. package/dist/mcp/utils/hailer-api-client.js +4 -13
  56. package/dist/mcp/utils/tool-helpers.d.ts +102 -0
  57. package/dist/mcp/utils/tool-helpers.js +179 -0
  58. package/dist/mcp/utils/types.d.ts +6 -0
  59. package/dist/mcp/workspace-cache.d.ts +5 -5
  60. package/dist/mcp/workspace-cache.js +4 -3
  61. package/package.json +1 -1
  62. package/.claude/hooks/PreToolUse.sh +0 -52
  63. package/.claude/hooks/prompt-skill-loader.cjs +0 -553
  64. package/.claude/hooks/skill-loader.cjs +0 -142
  65. package/.claude/settings.local.json +0 -49
  66. package/.claude/skills/MCP-add-app-member-skill/SKILL.md +0 -977
  67. package/.claude/skills/MCP-build-data-app-skill/SKILL.md +0 -372
  68. package/.claude/skills/MCP-create-app-skill/SKILL.md +0 -1101
  69. package/.claude/skills/MCP-create-insight-skill/SKILL.md +0 -1317
  70. package/.claude/skills/MCP-get-insight-data-skill/SKILL.md +0 -1053
  71. package/.claude/skills/MCP-insight-api/SKILL.md +0 -185
  72. package/.claude/skills/MCP-insight-api/references/insight-endpoints.md +0 -514
  73. package/.claude/skills/MCP-install-workflow-skill/SKILL.md +0 -1056
  74. package/.claude/skills/MCP-list-apps-skill/SKILL.md +0 -1010
  75. package/.claude/skills/MCP-list-workflows-minimal-skill/SKILL.md +0 -992
  76. package/.claude/skills/MCP-local-first-skill/SKILL.md +0 -570
  77. package/.claude/skills/MCP-populate-workflow-data-skill/SKILL.md +0 -395
  78. package/.claude/skills/MCP-preview-insight-skill/SKILL.md +0 -1290
  79. package/.claude/skills/MCP-publish-hailer-app-skill/SKILL.md +0 -453
  80. package/.claude/skills/MCP-publish-template-skill/SKILL.md +0 -278
  81. package/.claude/skills/MCP-remove-app-member-skill/SKILL.md +0 -671
  82. package/.claude/skills/MCP-remove-app-skill/SKILL.md +0 -985
  83. package/.claude/skills/MCP-remove-insight-skill/SKILL.md +0 -1011
  84. package/.claude/skills/MCP-remove-workflow-skill/SKILL.md +0 -920
  85. package/.claude/skills/MCP-scaffold-hailer-app-skill/SKILL.md +0 -1314
  86. package/.claude/skills/MCP-update-app-skill/SKILL.md +0 -970
  87. package/.claude/skills/MCP-update-workflow-field-skill/SKILL.md +0 -1098
  88. package/.claude/skills/SDK-create-function-field-skill/SKILL.md +0 -313
  89. package/.claude/skills/SDK-generate-skill/SKILL.md +0 -223
  90. package/.claude/skills/SDK-init-skill/SKILL.md +0 -177
  91. package/.claude/skills/SDK-workspace-setup-skill/SKILL.md +0 -605
  92. package/.claude/skills/SDK-ws-config-skill/SKILL.md +0 -435
  93. package/.claude/skills/activity-api/SKILL.md +0 -96
  94. package/.claude/skills/activity-api/references/activity-endpoints.md +0 -845
  95. package/.claude/skills/agent-building/SKILL.md +0 -243
  96. package/.claude/skills/agent-building/references/architecture-patterns.md +0 -446
  97. package/.claude/skills/agent-building/references/code-examples.md +0 -587
  98. package/.claude/skills/agent-building/references/implementation-guide.md +0 -619
  99. package/.claude/skills/app-api/SKILL.md +0 -219
  100. package/.claude/skills/app-api/references/app-endpoints.md +0 -759
  101. package/.claude/skills/building-hailer-apps-skill/SKILL.md +0 -813
  102. package/.claude/skills/hailer-api/SKILL.md +0 -283
  103. package/.claude/skills/hailer-api/references/activities.md +0 -620
  104. package/.claude/skills/hailer-api/references/authentication.md +0 -216
  105. package/.claude/skills/hailer-api/references/datasets.md +0 -437
  106. package/.claude/skills/hailer-api/references/files.md +0 -301
  107. package/.claude/skills/hailer-api/references/insights.md +0 -469
  108. package/.claude/skills/hailer-api/references/workflows.md +0 -720
  109. package/.claude/skills/hailer-api/references/workspaces-users.md +0 -445
  110. package/.claude/skills/hailer-app-builder/SKILL.md +0 -340
  111. package/.claude/skills/mcp-tools/SKILL.md +0 -419
  112. package/.claude/skills/mcp-tools/references/api-endpoints.md +0 -499
  113. package/.claude/skills/mcp-tools/references/data-structures.md +0 -554
  114. package/.claude/skills/mcp-tools/references/implementation-patterns.md +0 -717
  115. package/.claude/skills/skill-testing/README.md +0 -137
  116. package/.claude/skills/skill-testing/SKILL.md +0 -348
  117. package/.claude/skills/skill-testing/references/test-patterns.md +0 -705
  118. package/.claude/skills/skill-testing/references/testing-guide.md +0 -603
  119. package/.claude/skills/skill-testing/references/validation-checklist.md +0 -537
  120. package/.claude/skills/spawn-app-builder/SKILL.md +0 -366
  121. package/.claude/skills/tool-builder/SKILL.md +0 -328
  122. package/tsconfig.json +0 -23
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Claude Code PreToolUse Hook - Source Code Edit Guard
4
+ *
5
+ * Blocks direct edits to src/ directory files.
6
+ * Forces the main agent to spawn subagents for code changes.
7
+ * This saves context in the main agent for orchestration.
8
+ *
9
+ * Edits are ONLY allowed when:
10
+ * - Running inside a subagent (builder mode active)
11
+ * - File is outside src/ directory
12
+ */
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+
17
+ // UNIFIED: Use same builder mode file as app-edit-guard.cjs
18
+ const BUILDER_MODE_FILE = '/tmp/.claude-builder-agent-active';
19
+
20
+ // Read hook input from stdin
21
+ let input = '';
22
+ process.stdin.setEncoding('utf8');
23
+ process.stdin.on('data', chunk => input += chunk);
24
+ process.stdin.on('end', () => {
25
+ try {
26
+ const data = JSON.parse(input);
27
+ processHook(data);
28
+ } catch (e) {
29
+ // Invalid JSON - allow to avoid blocking legitimate operations
30
+ outputAllow();
31
+ }
32
+ });
33
+
34
+ function outputAllow() {
35
+ console.log(JSON.stringify({ decision: 'allow' }));
36
+ process.exit(0);
37
+ }
38
+
39
+ function outputBlock(message) {
40
+ console.log(JSON.stringify({
41
+ decision: 'block',
42
+ reason: message
43
+ }));
44
+ process.exit(0);
45
+ }
46
+
47
+ /**
48
+ * Check if builder mode is active (subagent editing)
49
+ */
50
+ function isBuilderModeActive() {
51
+ try {
52
+ return fs.existsSync(BUILDER_MODE_FILE);
53
+ } catch {
54
+ return false;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Enable builder mode
60
+ */
61
+ function enableBuilderMode() {
62
+ fs.writeFileSync(BUILDER_MODE_FILE, JSON.stringify({
63
+ enabledAt: new Date().toISOString(),
64
+ pid: process.pid
65
+ }));
66
+ }
67
+
68
+ /**
69
+ * Disable builder mode
70
+ */
71
+ function disableBuilderMode() {
72
+ if (fs.existsSync(BUILDER_MODE_FILE)) {
73
+ fs.unlinkSync(BUILDER_MODE_FILE);
74
+ return true;
75
+ }
76
+ return false;
77
+ }
78
+
79
+ function processHook(data) {
80
+ const { tool_name, tool_input } = data;
81
+
82
+ // Only guard Write and Edit tools
83
+ if (tool_name !== 'Write' && tool_name !== 'Edit') {
84
+ outputAllow();
85
+ return;
86
+ }
87
+
88
+ const filePath = tool_input?.file_path;
89
+ if (!filePath) {
90
+ outputAllow();
91
+ return;
92
+ }
93
+
94
+ // Normalize and get relative path
95
+ const normalizedPath = path.resolve(filePath);
96
+ const projectRoot = process.env.CLAUDE_PROJECT_DIR || process.cwd();
97
+ const relativePath = path.relative(projectRoot, normalizedPath);
98
+
99
+ // Check if file is in src/ directory
100
+ const isInSrc = relativePath.startsWith('src/') || relativePath.startsWith('src\\');
101
+
102
+ if (!isInSrc) {
103
+ // Not in src/ directory - allow
104
+ outputAllow();
105
+ return;
106
+ }
107
+
108
+ // Check if builder mode is active - ALLOW
109
+ if (isBuilderModeActive()) {
110
+ outputAllow();
111
+ return;
112
+ }
113
+
114
+ // BLOCK with helpful message
115
+ outputBlock(`
116
+ 🚫 BLOCKED: Direct edit to source file
117
+
118
+ File: ${relativePath}
119
+
120
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
121
+ WHY: Use a subagent to save your context for orchestration
122
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
123
+
124
+ TO PROCEED: Spawn a general-purpose agent with detailed instructions:
125
+
126
+ Task({
127
+ subagent_type: "general-purpose",
128
+ description: "Fix issue #XX",
129
+ prompt: \`
130
+ [Detailed instructions for the change]
131
+
132
+ File to modify: ${relativePath}
133
+
134
+ [Explain what to change and why]
135
+ \`
136
+ })
137
+
138
+ The agent will:
139
+ 1. Make the code changes
140
+ 2. Verify the build passes
141
+ 3. Report back results
142
+
143
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
144
+ OR: Enable builder mode temporarily (if you need to edit directly)
145
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
146
+
147
+ Bash: node .claude/hooks/src-edit-guard.cjs --on
148
+ [Make your edits]
149
+ Bash: node .claude/hooks/src-edit-guard.cjs --off
150
+ `);
151
+ }
152
+
153
+ // CLI: Enable builder mode
154
+ if (process.argv[2] === '--on') {
155
+ enableBuilderMode();
156
+ console.log('🔧 Builder mode ENABLED - src/ edits now allowed');
157
+ process.exit(0);
158
+ }
159
+
160
+ // CLI: Disable builder mode
161
+ if (process.argv[2] === '--off') {
162
+ if (disableBuilderMode()) {
163
+ console.log('🔒 Builder mode DISABLED - src/ edits blocked again');
164
+ } else {
165
+ console.log('ℹ️ Builder mode was not active');
166
+ }
167
+ process.exit(0);
168
+ }
169
+
170
+ // CLI: Check status
171
+ if (process.argv[2] === '--status') {
172
+ if (isBuilderModeActive()) {
173
+ const data = JSON.parse(fs.readFileSync(BUILDER_MODE_FILE, 'utf8'));
174
+ console.log(`🔧 Builder mode is ACTIVE (enabled at ${data.enabledAt})`);
175
+ } else {
176
+ console.log('🔒 Builder mode is OFF - src/ edits are blocked');
177
+ }
178
+ process.exit(0);
179
+ }
180
+
181
+ // CLI: Help
182
+ if (process.argv[2] === '--help' || process.argv[2] === '-h') {
183
+ console.log(`
184
+ Source Code Edit Guard - Blocks direct edits to src/ directory
185
+
186
+ Usage:
187
+ node src-edit-guard.cjs --on Enable builder mode (allow edits)
188
+ node src-edit-guard.cjs --off Disable builder mode (block edits)
189
+ node src-edit-guard.cjs --status Check current mode
190
+ node src-edit-guard.cjs --help Show this help
191
+
192
+ UNIFIED SYSTEM: This hook uses the same builder mode file as app-edit-guard.cjs.
193
+ Enabling builder mode here also enables it for Hailer app edits, and vice versa.
194
+
195
+ Preferred commands (via app-edit-guard.cjs):
196
+ node app-edit-guard.cjs --agent-on Enable global builder mode
197
+ node app-edit-guard.cjs --agent-off Disable global builder mode
198
+
199
+ As a hook:
200
+ Reads JSON from stdin with tool_name and tool_input
201
+ Outputs JSON with decision: "allow" or "block"
202
+
203
+ Purpose:
204
+ Forces the main Claude agent to spawn subagents for code changes.
205
+ This saves context in the main agent for orchestration tasks.
206
+ `);
207
+ process.exit(0);
208
+ }
@@ -14,8 +14,8 @@
14
14
  "hooks": [
15
15
  {
16
16
  "type": "command",
17
- "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/prompt-skill-loader.cjs\"",
18
- "timeout": 15
17
+ "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/interactive-mode.cjs\"",
18
+ "timeout": 5
19
19
  }
20
20
  ]
21
21
  }
@@ -28,6 +28,11 @@
28
28
  "type": "command",
29
29
  "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/sdk-delete-guard.cjs\"",
30
30
  "timeout": 5
31
+ },
32
+ {
33
+ "type": "command",
34
+ "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/mcp-server-guard.cjs\"",
35
+ "timeout": 5
31
36
  }
32
37
  ]
33
38
  },
@@ -40,6 +45,36 @@
40
45
  "timeout": 5
41
46
  }
42
47
  ]
48
+ },
49
+ {
50
+ "matcher": "Write",
51
+ "hooks": [
52
+ {
53
+ "type": "command",
54
+ "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/app-edit-guard.cjs\"",
55
+ "timeout": 5
56
+ },
57
+ {
58
+ "type": "command",
59
+ "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/src-edit-guard.cjs\"",
60
+ "timeout": 5
61
+ }
62
+ ]
63
+ },
64
+ {
65
+ "matcher": "Edit",
66
+ "hooks": [
67
+ {
68
+ "type": "command",
69
+ "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/app-edit-guard.cjs\"",
70
+ "timeout": 5
71
+ },
72
+ {
73
+ "type": "command",
74
+ "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/src-edit-guard.cjs\"",
75
+ "timeout": 5
76
+ }
77
+ ]
43
78
  }
44
79
  ],
45
80
  "PostToolUse": [
@@ -52,6 +87,16 @@
52
87
  "timeout": 5
53
88
  }
54
89
  ]
90
+ },
91
+ {
92
+ "matcher": "Task",
93
+ "hooks": [
94
+ {
95
+ "type": "command",
96
+ "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/agent-failure-detector.cjs\"",
97
+ "timeout": 5
98
+ }
99
+ ]
55
100
  }
56
101
  ]
57
102
  }
@@ -0,0 +1,209 @@
1
+ # Insight JOIN Patterns
2
+
3
+ ## Pattern
4
+ When joining workflows with ActivityLink fields in Hailer insights, you must:
5
+ 1. Include `_id` meta field in BOTH source definitions
6
+ 2. Join ON the activitylink field value equals target _id
7
+ 3. Use the activitylink fieldId (NOT the key) for the JOIN condition
8
+
9
+ ## Critical Rules
10
+
11
+ **Always Required:**
12
+ - Both workflows need `{ name: 'id', meta: '_id' }` in their fields array
13
+ - JOIN condition: `source1.activityLinkFieldName = source2.id`
14
+ - Use LEFT JOIN for optional relationships (activitylink can be null)
15
+ - Use INNER JOIN only when relationship must exist
16
+
17
+ ## Correct Examples
18
+
19
+ ### Basic ActivityLink JOIN
20
+ ```javascript
21
+ // Players workflow has "club" field (activitylink to Clubs workflow)
22
+ {
23
+ sources: [
24
+ {
25
+ name: 'p',
26
+ workflowId: '68446dc05b30685f67c6fcd4',
27
+ fields: [
28
+ { name: 'player_name', meta: 'name' },
29
+ { name: 'id', meta: '_id' }, // Required!
30
+ { name: 'club', fieldId: '684d5e45...' } // ActivityLink field
31
+ ]
32
+ },
33
+ {
34
+ name: 'c',
35
+ workflowId: '691ea936ccb6bdeebc0cbf77',
36
+ fields: [
37
+ { name: 'club_name', meta: 'name' },
38
+ { name: 'id', meta: '_id' } // Required!
39
+ ]
40
+ }
41
+ ],
42
+ query: 'SELECT p.player_name, c.club_name FROM p LEFT JOIN c ON p.club = c.id'
43
+ }
44
+ ```
45
+
46
+ ### Three-Way JOIN (Tasks -> Topics -> Projects)
47
+ ```javascript
48
+ {
49
+ sources: [
50
+ {
51
+ name: 't',
52
+ workflowId: 'tasks-workflow-id',
53
+ fields: [
54
+ { name: 'task_name', meta: 'name' },
55
+ { name: 'id', meta: '_id' },
56
+ { name: 'topic', fieldId: 'topic-field-id' } // Links to Topics
57
+ ]
58
+ },
59
+ {
60
+ name: 'top',
61
+ workflowId: 'topics-workflow-id',
62
+ fields: [
63
+ { name: 'topic_name', meta: 'name' },
64
+ { name: 'id', meta: '_id' },
65
+ { name: 'project', fieldId: 'project-field-id' } // Links to Projects
66
+ ]
67
+ },
68
+ {
69
+ name: 'p',
70
+ workflowId: 'projects-workflow-id',
71
+ fields: [
72
+ { name: 'project_name', meta: 'name' },
73
+ { name: 'id', meta: '_id' }
74
+ ]
75
+ }
76
+ ],
77
+ query: `
78
+ SELECT
79
+ t.task_name,
80
+ top.topic_name,
81
+ p.project_name
82
+ FROM t
83
+ LEFT JOIN top ON t.topic = top.id
84
+ LEFT JOIN p ON top.project = p.id
85
+ `
86
+ }
87
+ ```
88
+
89
+ ### Aggregation with JOIN
90
+ ```javascript
91
+ {
92
+ sources: [
93
+ {
94
+ name: 'matches',
95
+ workflowId: 'matches-workflow-id',
96
+ fields: [
97
+ { name: 'match_date', fieldId: 'date-field-id' },
98
+ { name: 'id', meta: '_id' },
99
+ { name: 'home_team', fieldId: 'home-team-field-id' }
100
+ ]
101
+ },
102
+ {
103
+ name: 'teams',
104
+ workflowId: 'teams-workflow-id',
105
+ fields: [
106
+ { name: 'team_name', meta: 'name' },
107
+ { name: 'id', meta: '_id' }
108
+ ]
109
+ }
110
+ ],
111
+ query: `
112
+ SELECT
113
+ teams.team_name,
114
+ COUNT(*) as match_count
115
+ FROM matches
116
+ LEFT JOIN teams ON matches.home_team = teams.id
117
+ GROUP BY teams.team_name
118
+ `
119
+ }
120
+ ```
121
+
122
+ ## Wrong Examples
123
+
124
+ ### Missing _id Field
125
+ ```javascript
126
+ // ❌ WRONG - Missing _id in clubs source
127
+ {
128
+ sources: [
129
+ {
130
+ name: 'p',
131
+ workflowId: 'players-id',
132
+ fields: [
133
+ { name: 'player_name', meta: 'name' },
134
+ { name: 'id', meta: '_id' },
135
+ { name: 'club', fieldId: 'club-field-id' }
136
+ ]
137
+ },
138
+ {
139
+ name: 'c',
140
+ workflowId: 'clubs-id',
141
+ fields: [
142
+ { name: 'club_name', meta: 'name' }
143
+ // Missing: { name: 'id', meta: '_id' }
144
+ ]
145
+ }
146
+ ],
147
+ query: 'SELECT p.player_name, c.club_name FROM p LEFT JOIN c ON p.club = c.id'
148
+ }
149
+ // Error: "no such column: c.id"
150
+ ```
151
+
152
+ ### Using Key Instead of FieldId
153
+ ```javascript
154
+ // ❌ WRONG - Using field key instead of fieldId
155
+ {
156
+ sources: [
157
+ {
158
+ name: 'p',
159
+ workflowId: 'players-id',
160
+ fields: [
161
+ { name: 'player_name', meta: 'name' },
162
+ { name: 'id', meta: '_id' },
163
+ { name: 'club', key: 'club' } // Wrong! Use fieldId
164
+ ]
165
+ }
166
+ ]
167
+ }
168
+ ```
169
+
170
+ ### Wrong JOIN Syntax
171
+ ```javascript
172
+ // ❌ WRONG - Trying to join on name instead of id
173
+ query: 'SELECT p.player_name, c.club_name FROM p LEFT JOIN c ON p.club = c.club_name'
174
+
175
+ // ❌ WRONG - Using field key in JOIN instead of column name
176
+ query: 'SELECT p.player_name, c.club_name FROM p LEFT JOIN c ON p.clubId = c.id'
177
+ // (Should use column name from sources definition: p.club = c.id)
178
+ ```
179
+
180
+ ## Troubleshooting
181
+
182
+ **Error: "no such column: c.id"**
183
+ - Missing `{ name: 'id', meta: '_id' }` in target workflow source
184
+
185
+ **Error: "no such column: p.club"**
186
+ - ActivityLink field not included in source fields array
187
+ - Check you used correct fieldId from `get_workflow_schema`
188
+
189
+ **NULL results for joined data**
190
+ - ActivityLink field is empty/null for some activities (expected with LEFT JOIN)
191
+ - Use INNER JOIN if you only want activities with relationships
192
+
193
+ ## Workflow
194
+
195
+ 1. Get schema: `get_workflow_schema({ workflowId, phaseId })`
196
+ 2. Find ActivityLink field ID and target workflow ID
197
+ 3. Build sources with BOTH _id fields
198
+ 4. Preview query: `preview_insight({ sources, query })`
199
+ 5. Fix errors, re-preview
200
+ 6. Create insight when preview succeeds
201
+
202
+ ## Quick Checklist
203
+
204
+ Before creating an insight with JOINs:
205
+ - [ ] Both workflow sources include `{ name: 'id', meta: '_id' }`
206
+ - [ ] ActivityLink field uses `fieldId` (NOT `key`)
207
+ - [ ] JOIN condition uses column names from sources (e.g., `p.club = c.id`)
208
+ - [ ] Using LEFT JOIN (unless relationship required)
209
+ - [ ] Tested with `preview_insight` first
package/.env.example CHANGED
@@ -1,6 +1,18 @@
1
1
  # Hailer MCP Server Configuration
2
2
  # Copy this file to .env.local and update with your own credentials
3
3
 
4
+ # ==============================================
5
+ # ENVIRONMENT
6
+ # ==============================================
7
+
8
+ # NODE_ENV controls multiple behaviors:
9
+ # - 'development': TLS bypass for local URLs, console logging, file tracking
10
+ # - 'production': Strict TLS, OpenTelemetry logging, no file tracking
11
+ #
12
+ # Set to 'development' when using local Hailer cluster (*.local.gd)
13
+ # Leave unset or 'production' for api.hailer.com
14
+ # NODE_ENV=development
15
+
4
16
  # ==============================================
5
17
  # MCP SERVER CONFIGURATION (for external clients)
6
18
  # ==============================================
@@ -78,4 +90,4 @@ ADAPTIVE_DOCUMENTATION_BOT_ENABLED=false
78
90
  ADAPTIVE_AUTO_UPDATE=false
79
91
  ADAPTIVE_UPDATE_INTERVAL=60000
80
92
  ADAPTIVE_MIN_ERROR_COUNT=3
81
- ADAPTIVE_SKILL_GENERATION=false
93
+ ADAPTIVE_SKILL_GENERATION=false
package/CLAUDE.md ADDED
@@ -0,0 +1,135 @@
1
+ # Hailer SDK
2
+
3
+ MCP tools for Hailer workspaces: workflows, activities, insights, and apps.
4
+
5
+ **Core features:**
6
+ - MCP Tools: Direct Hailer API access
7
+ - Local Config: Synced workspace in `workspace/` directory
8
+ - Type Generation: TypeScript enums for IDs
9
+
10
+ ---
11
+
12
+ # Default Agent System (Customizable)
13
+
14
+ Ships with pre-configured agents. **These are defaults - modify, replace, or remove them.**
15
+
16
+ | Action | How |
17
+ |--------|-----|
18
+ | Create custom | `agent-builder` or add to `.claude/agents/` |
19
+ | Modify defaults | Edit `.claude/agents/*.md` |
20
+ | Disable agents | Move to `docs/agents/`, update this file |
21
+
22
+ ## Orchestrator Role
23
+
24
+ You route requests to agents. Do trivial things directly; delegate everything else.
25
+
26
+ **Do directly:** Answer from context, summarize results, opinions, confirmations
27
+ **Delegate:** Any file read, API call, creation, update, or complex reasoning
28
+
29
+ ## Default Agents
30
+
31
+ > Customize by editing `.claude/agents/` files.
32
+
33
+ | Pattern | Agent | Model |
34
+ |---------|-------|-------|
35
+ | Read data/schema | `kenji` | Haiku |
36
+ | Activity CRUD | `dmitri` | Haiku |
37
+ | Discussions/chat | `yevgeni` | Haiku |
38
+ | Config audit | `bjorn` | Haiku |
39
+ | Workspace config | `helga` | Sonnet |
40
+ | SQL insights | `viktor` | Sonnet |
41
+ | Function fields | `alejandro` | Sonnet |
42
+ | MCP tools | `gunther` | Sonnet |
43
+ | Hailer apps | `giuseppe` | Sonnet |
44
+ | Code review | `svetlana` | Sonnet |
45
+ | New agents | `agent-builder` | Sonnet |
46
+ | Create/update skills, improve agents | `ada` | Sonnet |
47
+ | Document templates | `ingrid` | Sonnet |
48
+
49
+ ## Delegation Protocol
50
+
51
+ ```
52
+ Task(subagent_type="agent-name", prompt="JSON task spec", model="haiku")
53
+ ```
54
+
55
+ **Task spec:**
56
+ ```json
57
+ { "task": "action", "context": { "workflow_id": "...", "field_ids": {} }, "requirements": {}, "output": [] }
58
+ ```
59
+
60
+ **Response (JSON only, no prose):**
61
+ ```json
62
+ { "status": "success", "result": {}, "summary": "max 50 chars" }
63
+ ```
64
+
65
+ **Critical:** Get IDs first (via kenji), then pass to execution agents.
66
+
67
+ ---
68
+
69
+ # Local-First Principle
70
+
71
+ **Check local files BEFORE API calls.**
72
+
73
+ After `npm run pull`:
74
+ ```
75
+ workspace/
76
+ ├── workflows.ts # Workflow IDs, names
77
+ ├── enums.ts # Type-safe ID constants
78
+ ├── teams.ts, groups.ts # Team/group definitions
79
+ └── [Workflow]_[id]/
80
+ ├── fields.ts # Field definitions
81
+ └── phases.ts # Phase definitions
82
+ ```
83
+
84
+ | Use Local | Use API |
85
+ |-----------|---------|
86
+ | Workflow/field/phase IDs | Activity data (live) |
87
+ | Field types, labels, options | Activity counts |
88
+ | Team/group definitions | Discussion messages |
89
+
90
+ **Refresh:** `npm run pull` (after changes, start of session, before building apps)
91
+
92
+ ---
93
+
94
+ # Safety Rules
95
+
96
+ **Protected (hooks confirm):** `npm run push`, `*-push`, `*-sync`
97
+ **Safe:** `npm run pull`, `npm run generate`
98
+
99
+ ---
100
+
101
+ # Directory Structure
102
+
103
+ ```
104
+ workspace/ # Local config (check FIRST)
105
+ .claude/
106
+ agents/ # Agent definitions
107
+ hooks/ # Safety hooks
108
+ skills/ # Documentation
109
+ commands/ # Slash commands
110
+ settings.json # Permissions
111
+ ```
112
+
113
+ ---
114
+
115
+ # Customization
116
+
117
+ ## Create Agent
118
+ ```yaml
119
+ # .claude/agents/your-agent.md
120
+ ---
121
+ name: your-agent
122
+ description: What it does.\n\n<example>...</example>
123
+ model: haiku
124
+ ---
125
+ [Agent body with responsibilities]
126
+ ```
127
+
128
+ ## Modify Agents
129
+ Edit `.claude/agents/*.md` - change personality, responsibilities, model, tools.
130
+
131
+ ## Disable Agents
132
+ Move from `.claude/agents/` to `docs/agents/`, remove from delegation table.
133
+
134
+ ## Without Agents
135
+ Use MCP tools directly: `list_workflows`, `create_activity`, `get_workflow_schema`, etc.
package/dist/app.js CHANGED
@@ -9,7 +9,6 @@ const user_1 = require("./mcp/tools/user");
9
9
  const workflow_1 = require("./mcp/tools/workflow");
10
10
  const insight_1 = require("./mcp/tools/insight");
11
11
  const app_1 = require("./mcp/tools/app");
12
- const skill_1 = require("./mcp/tools/skill");
13
12
  const core = new core_1.Core();
14
13
  console.log('Registering tools...');
15
14
  console.log(`Nuclear tools ${config_1.environment.ENABLE_NUCLEAR_TOOLS ? 'ENABLED' : 'DISABLED'} (set ENABLE_NUCLEAR_TOOLS=true in .env.local to enable)`);
@@ -47,6 +46,7 @@ core.addTool(workflow_1.countActivitiesTool);
47
46
  core.addTool(insight_1.createInsightTool);
48
47
  core.addTool(insight_1.previewInsightTool);
49
48
  core.addTool(insight_1.getInsightDataTool);
49
+ core.addTool(insight_1.updateInsightTool);
50
50
  if (config_1.environment.ENABLE_NUCLEAR_TOOLS) {
51
51
  core.addTool(insight_1.removeInsightTool);
52
52
  }
@@ -69,8 +69,9 @@ core.addTool(app_1.getTemplateTool);
69
69
  core.addTool(app_1.publishTemplateTool);
70
70
  core.addTool(app_1.getProductTool);
71
71
  core.addTool(app_1.getProductManifestTool);
72
- core.addTool(skill_1.listSkillsTool);
73
- core.addTool(skill_1.getSkillTool);
72
+ // Marketplace app tools
73
+ core.addTool(app_1.publishAppTool);
74
+ core.addTool(app_1.installMarketplaceAppTool);
74
75
  console.log('All tools registered successfully!');
75
76
  // Start the application
76
77
  core.start().catch((error) => {
package/dist/cli.js CHANGED
File without changes
@@ -15,7 +15,6 @@ import { ToolCallError, ErrorPattern, AdaptiveBotConfig } from './adaptive-docum
15
15
  export declare class AdaptiveDocumentationBot {
16
16
  private logParser;
17
17
  private descriptionUpdater;
18
- private skillGenerator;
19
18
  private llmCaller;
20
19
  private config;
21
20
  private errorPatterns;
@@ -83,7 +82,6 @@ export declare class AdaptiveDocumentationBot {
83
82
  monitoring: boolean;
84
83
  errorPatterns: number;
85
84
  improvements: any;
86
- skills: any;
87
85
  };
88
86
  /**
89
87
  * Get error patterns for a specific tool