@hailer/mcp 1.0.29 → 1.1.2

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 (233) hide show
  1. package/.claude/.session-checked +1 -0
  2. package/.claude/agents/agent-ada-skill-builder.md +10 -2
  3. package/.claude/agents/agent-alejandro-function-fields.md +104 -37
  4. package/.claude/agents/agent-bjorn-config-audit.md +41 -21
  5. package/.claude/agents/agent-builder-agent-creator.md +13 -3
  6. package/.claude/agents/agent-code-simplifier.md +53 -0
  7. package/.claude/agents/agent-dmitri-activity-crud.md +126 -11
  8. package/.claude/agents/agent-giuseppe-app-builder.md +212 -22
  9. package/.claude/agents/agent-gunther-mcp-tools.md +7 -36
  10. package/.claude/agents/agent-helga-workflow-config.md +75 -10
  11. package/.claude/agents/agent-igor-activity-mover-automation.md +125 -0
  12. package/.claude/agents/agent-ingrid-doc-templates.md +164 -36
  13. package/.claude/agents/agent-ivan-monolith.md +154 -0
  14. package/.claude/agents/agent-kenji-data-reader.md +15 -8
  15. package/.claude/agents/agent-lars-code-inspector.md +56 -8
  16. package/.claude/agents/agent-marco-mockup-builder.md +110 -0
  17. package/.claude/agents/agent-marcus-api-documenter.md +323 -0
  18. package/.claude/agents/agent-marketplace-publisher.md +232 -72
  19. package/.claude/agents/agent-marketplace-reviewer.md +255 -79
  20. package/.claude/agents/agent-permissions-handler.md +208 -0
  21. package/.claude/agents/agent-simple-writer.md +48 -0
  22. package/.claude/agents/agent-svetlana-code-review.md +127 -14
  23. package/.claude/agents/agent-tanya-test-runner.md +333 -0
  24. package/.claude/agents/agent-ui-designer.md +100 -0
  25. package/.claude/agents/agent-viktor-sql-insights.md +19 -6
  26. package/.claude/agents/agent-web-search.md +55 -0
  27. package/.claude/agents/agent-yevgeni-discussions.md +7 -1
  28. package/.claude/agents/agent-zara-zapier.md +159 -0
  29. package/.claude/commands/app-squad.md +135 -0
  30. package/.claude/commands/audit-squad.md +158 -0
  31. package/.claude/commands/autoplan.md +563 -0
  32. package/.claude/commands/cleanup-squad.md +98 -0
  33. package/.claude/commands/config-squad.md +106 -0
  34. package/.claude/commands/crud-squad.md +87 -0
  35. package/.claude/commands/data-squad.md +97 -0
  36. package/.claude/commands/debug-squad.md +303 -0
  37. package/.claude/commands/doc-squad.md +65 -0
  38. package/.claude/commands/handoff.md +137 -0
  39. package/.claude/commands/health.md +49 -0
  40. package/.claude/commands/help.md +2 -1
  41. package/.claude/commands/help:agents.md +96 -16
  42. package/.claude/commands/help:commands.md +55 -11
  43. package/.claude/commands/help:faq.md +16 -1
  44. package/.claude/commands/help:skills.md +93 -0
  45. package/.claude/commands/hotfix-squad.md +112 -0
  46. package/.claude/commands/integration-squad.md +82 -0
  47. package/.claude/commands/janitor-squad.md +167 -0
  48. package/.claude/commands/learn-auto.md +120 -0
  49. package/.claude/commands/learn.md +120 -0
  50. package/.claude/commands/mcp-list.md +27 -0
  51. package/.claude/commands/onboard-squad.md +140 -0
  52. package/.claude/commands/plan-workspace.md +732 -0
  53. package/.claude/commands/prd.md +131 -0
  54. package/.claude/commands/project-status.md +82 -0
  55. package/.claude/commands/publish.md +138 -0
  56. package/.claude/commands/recap.md +69 -0
  57. package/.claude/commands/restore.md +64 -0
  58. package/.claude/commands/review-squad.md +152 -0
  59. package/.claude/commands/save.md +24 -0
  60. package/.claude/commands/stats.md +19 -0
  61. package/.claude/commands/swarm.md +210 -0
  62. package/.claude/commands/tool-builder.md +3 -1
  63. package/.claude/commands/ws-pull.md +1 -1
  64. package/.claude/commands/yolo-off.md +17 -0
  65. package/.claude/commands/yolo.md +82 -0
  66. package/.claude/hooks/_shared-memory.cjs +305 -0
  67. package/.claude/hooks/_utils.cjs +134 -0
  68. package/.claude/hooks/agent-failure-detector.cjs +164 -79
  69. package/.claude/hooks/agent-usage-logger.cjs +204 -0
  70. package/.claude/hooks/app-edit-guard.cjs +20 -4
  71. package/.claude/hooks/auto-learn.cjs +316 -0
  72. package/.claude/hooks/bash-guard.cjs +282 -0
  73. package/.claude/hooks/builder-mode-manager.cjs +183 -54
  74. package/.claude/hooks/bulk-activity-guard.cjs +283 -0
  75. package/.claude/hooks/context-watchdog.cjs +292 -0
  76. package/.claude/hooks/delegation-reminder.cjs +478 -0
  77. package/.claude/hooks/design-system-lint.cjs +283 -0
  78. package/.claude/hooks/post-scaffold-hook.cjs +16 -3
  79. package/.claude/hooks/prompt-guard.cjs +366 -0
  80. package/.claude/hooks/publish-template-guard.cjs +16 -0
  81. package/.claude/hooks/session-start.cjs +35 -0
  82. package/.claude/hooks/shared-memory-writer.cjs +147 -0
  83. package/.claude/hooks/skill-injector.cjs +140 -0
  84. package/.claude/hooks/skill-usage-logger.cjs +258 -0
  85. package/.claude/hooks/src-edit-guard.cjs +16 -1
  86. package/.claude/hooks/sync-marketplace-agents.cjs +53 -8
  87. package/.claude/scripts/yolo-toggle.cjs +142 -0
  88. package/.claude/settings.json +141 -14
  89. package/.claude/skills/SDK-activity-patterns/SKILL.md +428 -0
  90. package/.claude/skills/SDK-document-templates/SKILL.md +1033 -0
  91. package/.claude/skills/SDK-function-fields/SKILL.md +542 -0
  92. package/.claude/skills/SDK-generate-skill/SKILL.md +92 -0
  93. package/.claude/skills/SDK-init-skill/SKILL.md +127 -0
  94. package/.claude/skills/SDK-insight-queries/SKILL.md +787 -0
  95. package/.claude/skills/SDK-ws-config-skill/SKILL.md +1139 -0
  96. package/.claude/skills/agent-structure/SKILL.md +98 -0
  97. package/.claude/skills/api-documentation-patterns/SKILL.md +474 -0
  98. package/.claude/skills/chrome-mcp-reference/SKILL.md +370 -0
  99. package/.claude/skills/delegation-routing/SKILL.md +202 -0
  100. package/.claude/skills/frontend-design/SKILL.md +254 -0
  101. package/.claude/skills/hailer-activity-mover/SKILL.md +213 -0
  102. package/.claude/skills/hailer-api-client/SKILL.md +518 -0
  103. package/.claude/skills/hailer-app-builder/SKILL.md +939 -11
  104. package/.claude/skills/hailer-apps-pictures/SKILL.md +269 -0
  105. package/.claude/skills/hailer-design-system/SKILL.md +235 -0
  106. package/.claude/skills/hailer-monolith-automations/SKILL.md +686 -0
  107. package/.claude/skills/hailer-permissions-system/SKILL.md +121 -0
  108. package/.claude/skills/hailer-project-protocol/SKILL.md +488 -0
  109. package/.claude/skills/hailer-rest-api/SKILL.md +61 -0
  110. package/.claude/skills/hailer-rest-api/hailer-activities.md +184 -0
  111. package/.claude/skills/hailer-rest-api/hailer-admin.md +473 -0
  112. package/.claude/skills/hailer-rest-api/hailer-calendar.md +256 -0
  113. package/.claude/skills/hailer-rest-api/hailer-feed.md +249 -0
  114. package/.claude/skills/hailer-rest-api/hailer-insights.md +195 -0
  115. package/.claude/skills/hailer-rest-api/hailer-messaging.md +276 -0
  116. package/.claude/skills/hailer-rest-api/hailer-workflows.md +283 -0
  117. package/.claude/skills/insight-join-patterns/SKILL.md +3 -0
  118. package/.claude/skills/integration-patterns/SKILL.md +421 -0
  119. package/.claude/skills/json-only-output/SKILL.md +52 -12
  120. package/.claude/skills/lsp-setup/SKILL.md +160 -0
  121. package/.claude/skills/mcp-direct-tools/SKILL.md +153 -0
  122. package/.claude/skills/optional-parameters/SKILL.md +32 -23
  123. package/.claude/skills/publish-hailer-app/SKILL.md +76 -12
  124. package/.claude/skills/testing-patterns/SKILL.md +630 -0
  125. package/.claude/skills/tool-builder/SKILL.md +250 -0
  126. package/.claude/skills/tool-parameter-usage/SKILL.md +59 -45
  127. package/.claude/skills/tool-response-verification/SKILL.md +82 -48
  128. package/.claude/skills/zapier-hailer-patterns/SKILL.md +581 -0
  129. package/.env.example +26 -7
  130. package/CLAUDE.md +290 -224
  131. package/dist/CLAUDE.md +370 -0
  132. package/dist/app.d.ts +1 -1
  133. package/dist/app.js +101 -101
  134. package/dist/bot/bot-config.d.ts +26 -0
  135. package/dist/bot/bot-config.js +135 -0
  136. package/dist/bot/bot-manager.d.ts +40 -0
  137. package/dist/bot/bot-manager.js +137 -0
  138. package/dist/bot/bot.d.ts +127 -0
  139. package/dist/bot/bot.js +1328 -0
  140. package/dist/bot/operation-logger.d.ts +28 -0
  141. package/dist/bot/operation-logger.js +132 -0
  142. package/dist/bot/services/conversation-manager.d.ts +60 -0
  143. package/dist/bot/services/conversation-manager.js +246 -0
  144. package/dist/bot/services/index.d.ts +9 -0
  145. package/dist/bot/services/index.js +18 -0
  146. package/dist/bot/services/message-classifier.d.ts +42 -0
  147. package/dist/bot/services/message-classifier.js +228 -0
  148. package/dist/bot/services/message-formatter.d.ts +88 -0
  149. package/dist/bot/services/message-formatter.js +411 -0
  150. package/dist/bot/services/session-logger.d.ts +162 -0
  151. package/dist/bot/services/session-logger.js +724 -0
  152. package/dist/bot/services/token-billing.d.ts +78 -0
  153. package/dist/bot/services/token-billing.js +233 -0
  154. package/dist/bot/services/types.d.ts +169 -0
  155. package/dist/bot/services/types.js +12 -0
  156. package/dist/bot/services/typing-indicator.d.ts +23 -0
  157. package/dist/bot/services/typing-indicator.js +60 -0
  158. package/dist/bot/services/workspace-schema-cache.d.ts +122 -0
  159. package/dist/bot/services/workspace-schema-cache.js +506 -0
  160. package/dist/bot/tool-executor.d.ts +28 -0
  161. package/dist/bot/tool-executor.js +48 -0
  162. package/dist/bot/workspace-overview.d.ts +12 -0
  163. package/dist/bot/workspace-overview.js +94 -0
  164. package/dist/cli.d.ts +1 -8
  165. package/dist/cli.js +1 -253
  166. package/dist/config.d.ts +96 -3
  167. package/dist/config.js +148 -37
  168. package/dist/core.d.ts +5 -0
  169. package/dist/core.js +61 -8
  170. package/dist/lib/discussion-lock.d.ts +42 -0
  171. package/dist/lib/discussion-lock.js +110 -0
  172. package/dist/lib/logger.d.ts +0 -1
  173. package/dist/lib/logger.js +39 -23
  174. package/dist/lib/request-logger.d.ts +77 -0
  175. package/dist/lib/request-logger.js +147 -0
  176. package/dist/mcp/UserContextCache.js +16 -13
  177. package/dist/mcp/hailer-clients.js +18 -17
  178. package/dist/mcp/signal-handler.js +29 -13
  179. package/dist/mcp/tool-registry.d.ts +4 -15
  180. package/dist/mcp/tool-registry.js +94 -32
  181. package/dist/mcp/tools/activity.js +28 -69
  182. package/dist/mcp/tools/app-core.js +9 -4
  183. package/dist/mcp/tools/app-marketplace.js +22 -12
  184. package/dist/mcp/tools/app-member.js +5 -2
  185. package/dist/mcp/tools/app-scaffold.js +32 -18
  186. package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
  187. package/dist/mcp/tools/bot-config/constants.js +94 -0
  188. package/dist/mcp/tools/bot-config/core.d.ts +253 -0
  189. package/dist/mcp/tools/bot-config/core.js +2456 -0
  190. package/dist/mcp/tools/bot-config/index.d.ts +10 -0
  191. package/dist/mcp/tools/bot-config/index.js +59 -0
  192. package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
  193. package/dist/mcp/tools/bot-config/tools.js +15 -0
  194. package/dist/mcp/tools/bot-config/types.d.ts +50 -0
  195. package/dist/mcp/tools/bot-config/types.js +6 -0
  196. package/dist/mcp/tools/discussion.js +107 -77
  197. package/dist/mcp/tools/document.d.ts +11 -0
  198. package/dist/mcp/tools/document.js +741 -0
  199. package/dist/mcp/tools/file.js +5 -2
  200. package/dist/mcp/tools/insight.js +36 -12
  201. package/dist/mcp/tools/investigate.d.ts +9 -0
  202. package/dist/mcp/tools/investigate.js +254 -0
  203. package/dist/mcp/tools/user.d.ts +2 -4
  204. package/dist/mcp/tools/user.js +9 -50
  205. package/dist/mcp/tools/workflow.d.ts +1 -0
  206. package/dist/mcp/tools/workflow.js +164 -52
  207. package/dist/mcp/utils/hailer-api-client.js +26 -17
  208. package/dist/mcp/webhook-handler.d.ts +64 -3
  209. package/dist/mcp/webhook-handler.js +219 -9
  210. package/dist/mcp-server.d.ts +4 -0
  211. package/dist/mcp-server.js +237 -25
  212. package/dist/plugins/bug-fixer/index.d.ts +2 -0
  213. package/dist/plugins/bug-fixer/index.js +18 -0
  214. package/dist/plugins/bug-fixer/tools.d.ts +45 -0
  215. package/dist/plugins/bug-fixer/tools.js +1096 -0
  216. package/package.json +10 -10
  217. package/scripts/test-hal-tools.ts +154 -0
  218. package/.claude/agents/agent-nora-name-functions.md +0 -123
  219. package/.claude/assistant-knowledge.md +0 -23
  220. package/.claude/commands/install-plugin.md +0 -261
  221. package/.claude/commands/list-plugins.md +0 -42
  222. package/.claude/commands/marketplace-setup.md +0 -33
  223. package/.claude/commands/publish-plugin.md +0 -55
  224. package/.claude/commands/uninstall-plugin.md +0 -87
  225. package/.claude/hooks/interactive-mode.cjs +0 -87
  226. package/.claude/hooks/mcp-server-guard.cjs +0 -108
  227. package/.claude/skills/marketplace-publishing.md +0 -155
  228. package/dist/bot/chat-bot.d.ts +0 -31
  229. package/dist/bot/chat-bot.js +0 -357
  230. package/dist/mcp/tools/metrics.d.ts +0 -13
  231. package/dist/mcp/tools/metrics.js +0 -546
  232. package/dist/stdio-server.d.ts +0 -14
  233. package/dist/stdio-server.js +0 -114
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hailer/mcp",
3
- "version": "1.0.29",
3
+ "version": "1.1.2",
4
4
  "config": {
5
5
  "docker": {
6
6
  "registry": "registry.gitlab.com/hailer-repos/hailer-mcp"
@@ -10,25 +10,26 @@
10
10
  "dev": "tsx watch src/app.ts",
11
11
  "claude-code-mcp": "DISABLE_CLIENT=true tsx src/app.ts",
12
12
  "start-mcp-only": "DISABLE_CLIENT=true tsx src/app.ts",
13
+ "start-client-only": "DISABLE_MCP_SERVER=true tsx src/app.ts",
13
14
  "build": "tsc",
14
15
  "start": "node dist/app.js",
15
16
  "lint": "eslint src/",
16
- "build-dev-push": "rm -rf build/docker-dev && docker build --target artifacts --output build/docker-dev . -f Dockerfile.build-dev && docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs)-dev -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):dev -f ./Dockerfile.dev .",
17
- "build-debug-push": "docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs)-debug -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):debug -f ./Dockerfile.debug .",
18
- "build-prod-push": "rm -rf build/docker-prod && docker build --target artifacts --output build/docker-prod . -f Dockerfile.build-prod && docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs) -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):prod -f ./Dockerfile.prod .",
19
- "build-k3d": "docker build -f Dockerfile.debug . -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs) && k3d image import $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs) -c hailer",
20
- "build-k3d-dummy": "docker build --target artifacts --output build/docker-dev . -f Dockerfile.build-dev && docker build -f Dockerfile.dev . -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs)-dev && k3d image import $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs):$(npm pkg get version | xargs)-dev -c hailer",
17
+ "build-dev-push": "rm -rf build/docker-dev && docker build --target artifacts --output build/docker-dev . -f Dockerfile.build-dev && docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs)-dev -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):dev -f ./Dockerfile.dev .",
18
+ "build-debug-push": "docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs)-debug -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):debug -f ./Dockerfile.debug .",
19
+ "build-prod-push": "rm -rf build/docker-prod && docker build --target artifacts --output build/docker-prod . -f Dockerfile.build-prod && docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs) -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):prod -f ./Dockerfile.prod .",
20
+ "build-k3d": "docker build -f Dockerfile.debug . -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs) && k3d image import $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs) -c hailer",
21
+ "build-k3d-dummy": "docker build --target artifacts --output build/docker-dev . -f Dockerfile.build-dev && docker build -f Dockerfile.dev . -t $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs)-dev && k3d image import $(npm pkg get config.docker.registry | xargs)/$(npm pkg get name | xargs | sed 's/@hailer\\//hailer-/'):$(npm pkg get version | xargs)-dev -c hailer",
21
22
  "mcp-server": "hailer-mcp",
23
+ "server": "tsx src/client/server.ts",
24
+ "server:prod": "node dist/client/server.js",
22
25
  "release:patch": "npm version patch -m 'chore: release v%s' && git push && git push --tags && npm run build && npm publish --access public",
23
26
  "release:minor": "npm version minor -m 'chore: release v%s' && git push && git push --tags && npm run build && npm publish --access public",
24
27
  "release:major": "npm version major -m 'chore: release v%s' && git push && git push --tags && npm run build && npm publish --access public",
25
- "seed-config": "tsx src/commands/seed-config.ts",
26
- "bot": "tsx src/bot/chat-bot.ts"
28
+ "seed-config": "tsx src/commands/seed-config.ts"
27
29
  },
28
30
  "dependencies": {
29
31
  "@anthropic-ai/sdk": "^0.54.0",
30
32
  "@hailer/cli": "^1.1.10",
31
- "@hailer/mcp": "^1.0.24",
32
33
  "@modelcontextprotocol/sdk": "^1.11.5",
33
34
  "@opentelemetry/api-logs": "^0.57.0",
34
35
  "@opentelemetry/exporter-logs-otlp-proto": "^0.57.0",
@@ -36,7 +37,6 @@
36
37
  "@opentelemetry/sdk-logs": "^0.57.0",
37
38
  "@opentelemetry/sdk-node": "^0.57.0",
38
39
  "@opentelemetry/semantic-conventions": "^1.36.0",
39
- "axios": "^1.13.4",
40
40
  "cors": "^2.8.5",
41
41
  "dotenv": "^16.5.0",
42
42
  "express": "^4.21.2",
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env npx ts-node
2
+ /**
3
+ * HAL Tools Test - Simple version
4
+ * Just calls each tool and shows the result. No magic.
5
+ */
6
+
7
+ import * as dotenv from 'dotenv';
8
+ import * as path from 'path';
9
+
10
+ dotenv.config({ path: path.join(__dirname, '..', '.env.local') });
11
+
12
+ const MCP_URL = process.env.MCP_SERVER_URL || 'http://localhost:3030/api/mcp';
13
+
14
+ async function call(apiKey: string, tool: string, args: Record<string, unknown> = {}) {
15
+ console.log(`\n>>> ${tool}`);
16
+ console.log(` args: ${JSON.stringify(args)}`);
17
+
18
+ const res = await fetch(`${MCP_URL}?apiKey=${apiKey}`, {
19
+ method: 'POST',
20
+ headers: { 'Content-Type': 'application/json' },
21
+ body: JSON.stringify({
22
+ jsonrpc: '2.0',
23
+ id: '1',
24
+ method: 'tools/call',
25
+ params: { name: tool, arguments: args },
26
+ }),
27
+ });
28
+
29
+ const text = await res.text();
30
+ for (const line of text.split('\n')) {
31
+ if (line.startsWith('data: ')) {
32
+ const data = JSON.parse(line.substring(6));
33
+ if (data.error) {
34
+ console.log(`<<< ERROR: ${data.error.message}`);
35
+ return { error: true, data: null };
36
+ }
37
+ const content = data.result?.content?.[0]?.text || '';
38
+ // Show first 500 chars
39
+ console.log(`<<< ${content.substring(0, 500)}${content.length > 500 ? '...' : ''}`);
40
+ return { error: false, content };
41
+ }
42
+ }
43
+ console.log('<<< NO RESPONSE');
44
+ return { error: true, data: null };
45
+ }
46
+
47
+ async function main() {
48
+ const apiKey = process.env.MCP_CLIENT_API_KEY;
49
+ if (!apiKey) {
50
+ console.error('Set MCP_CLIENT_API_KEY in .env.local');
51
+ process.exit(1);
52
+ }
53
+
54
+ console.log('=== HAL TOOLS TEST ===\n');
55
+
56
+ // Get a workflow to work with
57
+ const wf = await call(apiKey, 'list_workflows_minimal', {});
58
+ const wfMatch = wf.content?.match(/`([a-f0-9]{24})`/);
59
+ const workflowId = wfMatch?.[1];
60
+ console.log(`\n[Using workflowId: ${workflowId}]`);
61
+
62
+ if (!workflowId) {
63
+ console.log('No workflow found, stopping');
64
+ process.exit(1);
65
+ }
66
+
67
+ // Get phase
68
+ const ph = await call(apiKey, 'list_workflow_phases', { workflowId });
69
+ const phMatch = ph.content?.match(/`([a-f0-9]{24})`/);
70
+ const phaseId = phMatch?.[1];
71
+ console.log(`\n[Using phaseId: ${phaseId}]`);
72
+
73
+ // Schema
74
+ await call(apiKey, 'get_workflow_schema', { workflowId, phaseId });
75
+
76
+ // List activities
77
+ await call(apiKey, 'list_activities', { workflowId, phaseId, fields: '[]' });
78
+
79
+ // Count
80
+ await call(apiKey, 'count_activities', { workflowId });
81
+
82
+ // Create activity
83
+ const created = await call(apiKey, 'create_activity', {
84
+ workflowId,
85
+ name: `TEST_${Date.now()}`
86
+ });
87
+ const actMatch = created.content?.match(/\*\*ID\*\*:\s*([a-f0-9]{24})/);
88
+ const activityId = actMatch?.[1];
89
+ console.log(`\n[Created activityId: ${activityId}]`);
90
+
91
+ if (activityId) {
92
+ // Show it
93
+ await call(apiKey, 'show_activity_by_id', { activityId });
94
+
95
+ // Update it
96
+ await call(apiKey, 'update_activity', { activityId, name: `UPDATED_${Date.now()}` });
97
+
98
+ // Delete it (this tool doesn't exist yet)
99
+ await call(apiKey, 'delete_activity', { activityId });
100
+ }
101
+
102
+ // Insights
103
+ await call(apiKey, 'list_insights', {});
104
+
105
+ const sources = [{
106
+ name: 'src',
107
+ workflowId,
108
+ fields: [{ meta: 'name', name: 'Name', as: 'name' }]
109
+ }];
110
+
111
+ await call(apiKey, 'preview_insight', { sources, query: 'SELECT * FROM src LIMIT 3' });
112
+
113
+ const ins = await call(apiKey, 'create_insight', {
114
+ name: `TEST_${Date.now()}`,
115
+ sources,
116
+ query: 'SELECT * FROM src LIMIT 3'
117
+ });
118
+ const insMatch = ins.content?.match(/`([a-f0-9]{24})`/);
119
+ const insightId = insMatch?.[1];
120
+
121
+ if (insightId) {
122
+ await call(apiKey, 'get_insight_data', { insightId });
123
+ await call(apiKey, 'remove_insight', { insightId });
124
+ }
125
+
126
+ // Discussions
127
+ await call(apiKey, 'list_my_discussions', {});
128
+
129
+ if (activityId) {
130
+ await call(apiKey, 'join_discussion', { activityId });
131
+ // Get discussion from activity
132
+ const act = await call(apiKey, 'show_activity_by_id', { activityId });
133
+ const discMatch = act.content?.match(/discussion.*?([a-f0-9]{24})/i);
134
+ const discussionId = discMatch?.[1];
135
+
136
+ if (discussionId) {
137
+ await call(apiKey, 'fetch_discussion_messages', { discussionId });
138
+ await call(apiKey, 'add_discussion_message', { discussionId, content: 'TEST' });
139
+ await call(apiKey, 'get_activity_from_discussion', { discussionId });
140
+ await call(apiKey, 'leave_discussion', { discussionId });
141
+ }
142
+ }
143
+
144
+ // Other
145
+ await call(apiKey, 'list_workflows', {});
146
+ await call(apiKey, 'list_apps', {});
147
+ await call(apiKey, 'list_templates', {});
148
+ await call(apiKey, 'get_workspace_balance', {});
149
+ await call(apiKey, 'search_workspace_users', { query: 'test' });
150
+
151
+ console.log('\n=== DONE ===');
152
+ }
153
+
154
+ main().catch(console.error);
@@ -1,123 +0,0 @@
1
- ---
2
- name: agent-nora-name-functions
3
- description: Creates and manages workflow nameFunction configurations via SDK v0.8.4. Designs JavaScript name generation functions with field dependencies for dynamic activity naming.\n\n<example>\nuser: "Add name function to Employees workflow"\nassistant: {"status":"ready_to_push","result":{"name_function_added":true,"variables":1},"commands":["npm run workflows-push"],"summary":"Added name function to Employees"}\n</example>
4
- model: haiku
5
- tools: Bash, Read, Edit, Glob
6
- ---
7
-
8
- <identity>
9
- I am Nora, Finnish name function specialist. Every activity deserves a meaningful name. SDK v0.8.4. Output JSON. Full stop.
10
-
11
- ⚠️ EXCLUSIVE DOMAIN: I am the ONLY agent who handles nameField, nameFunction, and nameFunctionVariables. Alejandro does NOT touch these.
12
- </identity>
13
-
14
- <handles>
15
- - Add nameFunction to workflow main.ts files (inline JavaScript, not separate file)
16
- - Configure nameFunctionVariables with field dependencies (same format as field functions)
17
- - Enable/disable dynamic activity naming
18
- - Test name function syntax before deployment
19
- - EVERYTHING related to nameField and nameFieldFunctions (sole responsibility)
20
- </handles>
21
-
22
- <function-rules>
23
- nameFunction follows SAME rules as Alejandro's field functions:
24
- - Vanilla JS only (no TypeScript syntax, no imports, no async)
25
- - NEVER return null/undefined - always return valid string
26
- - Helper functions MUST be inside main function body
27
- - Stability required - same inputs = same outputs
28
- - Safe handling: var x = dep.field || 'default'
29
- - Division by zero: check denominator > 0
30
- - Arrays: var arr = dep.arr || []
31
- - JSON: try/catch with fallback
32
-
33
- ⚠️ CRITICAL SYNTAX: nameFunction is ONLY the function BODY (what's between {}), NOT the full function declaration!
34
- ❌ WRONG: "function(dep) { return 'value'; }"
35
- ✅ CORRECT: "return 'value'"
36
- </function-rules>
37
-
38
- <rules>
39
- 1. **NEVER FABRICATE** - Must call tools.
40
- 2. **CRITICAL** - Pull OVERWRITES local changes. Workflow: pull → edit → push → verify success.
41
- 3. Edit main.ts in workspace/[Workflow]_[id]/ directory.
42
- 4. **NEVER run workflows-push** - Return command for orchestrator.
43
- 5. nameFunctionVariables uses field functionVariables format: {varName: {data: [FieldId], type: '='}}.
44
- 6. Set nameFunctionEnabled: true when adding nameFunction.
45
- 7. Use enums from enums.ts - Never hardcode field IDs.
46
- 8. **JSON ONLY** - Output closing brace, then STOP. Zero prose after JSON.
47
- </rules>
48
-
49
- <patterns>
50
- Simple field (current activity):
51
- nameFunctionVariables: {
52
- fieldName: { data: [FieldIds.field_name_abc], type: "=" }
53
- }
54
- nameFunction: "return (dep.fieldName || 'Unnamed')"
55
-
56
- Multiple fields:
57
- nameFunctionVariables: {
58
- firstName: { data: [FieldIds.first_name], type: "=" },
59
- lastName: { data: [FieldIds.last_name], type: "=" }
60
- }
61
- nameFunction: "return (dep.firstName || '') + ' ' + (dep.lastName || '')"
62
-
63
- Linked field (forward link ">"):
64
- nameFunctionVariables: {
65
- clientName: { data: [FieldIds.client_link, ClientFieldIds.company_name], type: ">" }
66
- }
67
- nameFunction: "return 'Project for ' + (dep.clientName || 'Unknown')"
68
-
69
- With safe number handling:
70
- nameFunctionVariables: {
71
- invoiceNum: { data: [FieldIds.invoice_number], type: "=" }
72
- }
73
- nameFunction: "var num = Number(dep.invoiceNum) || 0; return 'INV-' + num"
74
-
75
- With helper function inside:
76
- nameFunction: "function safe(val) { return val || 'N/A'; } return safe(dep.name) + ' - ' + safe(dep.code)"
77
- </patterns>
78
-
79
- <dependency-types>
80
- "=" - Current activity field → data: [FieldId]
81
- ">" - Forward link (THIS → other) → data: [LinkFieldId, TargetFieldId]
82
- "<" - Backlink (others → THIS) → data: [WorkflowId, TargetFieldId] (returns array)
83
-
84
- CRITICAL: Forward links use LinkFieldId. Backlinks use WorkflowId.
85
- </dependency-types>
86
-
87
- <common-errors>
88
- ❌ CRITICAL: Writing "function(dep) { ... }" (ONLY write function body!)
89
- ❌ Using array for nameFunctionVariables: [FieldId] (use object)
90
- ❌ Using const/let instead of var in function
91
- ❌ Returning null or undefined
92
- ❌ Using TypeScript type annotations: (dep: Deps)
93
- ❌ Using WorkflowIds for forward links (use LinkFieldId)
94
- ❌ Forgetting nameFunctionEnabled: true
95
- ❌ Running workflows-push directly (return to orchestrator)
96
-
97
- ✅ Write ONLY function body: "return 'value'" not "function(dep) { return 'value'; }"
98
- ✅ Use object for nameFunctionVariables
99
- ✅ Use var for variables
100
- ✅ Always return string with fallback
101
- ✅ Use vanilla JS only
102
- ✅ Define helpers inside function body
103
- ✅ Handle null/undefined inputs
104
- </common-errors>
105
-
106
- <workflow>
107
- 1. npm run pull (run directly)
108
- 2. Read workspace/[Workflow]_[id]/main.ts
109
- 3. Read workspace/[Workflow]_[id]/fields.ts to identify key fields for naming
110
- 4. Add nameFunctionEnabled, nameFunction, nameFunctionVariables to workflowConfig
111
- 5. Return ['npm run workflows-push']
112
- </workflow>
113
-
114
- <protocol>
115
- Input: JSON task spec
116
- Output: JSON only
117
- Schema: {
118
- "status": "ready_to_push|error",
119
- "result": { "name_function_added": true, "variables": 0 },
120
- "commands": ["npm run workflows-push"],
121
- "summary": "max 50 chars"
122
- }
123
- </protocol>
@@ -1,23 +0,0 @@
1
- # MCP Agents
2
-
3
- kenji: Read data/schema from workspace (haiku)
4
- dmitri: Create/update activities (haiku)
5
- yevgeni: Discussions and chat (haiku)
6
- helga: Workflow/field/phase config (sonnet)
7
- viktor: SQL insights over workflows (sonnet)
8
- giuseppe: Build Hailer apps (sonnet)
9
- alejandro: Function/calculated fields (sonnet)
10
-
11
- # What MCP Can Do
12
-
13
- - Manage Hailer workflows, activities, fields
14
- - Create SQL-like reports (insights)
15
- - Build custom apps
16
- - Handle discussions/messaging
17
- - Configure workspace structure
18
-
19
- # Limitations
20
-
21
- - Cannot access external systems
22
- - Limited to configured workspace
23
- - Agents run via Claude Code CLI
@@ -1,261 +0,0 @@
1
- ---
2
- description: Install a plugin from local marketplace clone to .claude/ folder
3
- ---
4
-
5
- # Install Plugin from Local Marketplace
6
-
7
- Copies plugin files from local marketplace repo to project's `.claude/` folder.
8
-
9
- ## Usage
10
-
11
- ```
12
- /install-plugin <plugin-name>
13
- ```
14
-
15
- ## Pre-flight Checks
16
-
17
- ### 1. Marketplace Path
18
- ```bash
19
- PROJECT_ROOT="$(pwd)"
20
- MARKETPLACE_PATH="$PROJECT_ROOT/hailer-marketplace"
21
- if [ ! -d "$MARKETPLACE_PATH" ]; then
22
- echo "ERROR: Marketplace not found at $MARKETPLACE_PATH"
23
- echo "Clone it: git clone git@github.com:Bdolf/Hailer-Marketplace.git $MARKETPLACE_PATH"
24
- exit 1
25
- fi
26
- ```
27
-
28
- ### 2. Plugin Exists
29
- ```bash
30
- PLUGIN_NAME="$1"
31
- if [ ! -d "$MARKETPLACE_PATH/$PLUGIN_NAME" ]; then
32
- echo "ERROR: Plugin '$PLUGIN_NAME' not found in marketplace"
33
- echo "Available plugins:"
34
- ls -1 "$MARKETPLACE_PATH" | grep -v "^\." | grep -v "node_modules"
35
- exit 1
36
- fi
37
- ```
38
-
39
- ## Installation Steps
40
-
41
- For each plugin, copy files to the correct locations:
42
-
43
- | Source | Destination |
44
- |--------|-------------|
45
- | `{plugin}/agents/*.md` | `.claude/agents/` |
46
- | `{plugin}/skills/*/` | `.claude/skills/` |
47
- | `{plugin}/hooks/*.cjs` | `.claude/hooks/` |
48
- | `{plugin}/hooks/hooks.json` | Merge into `.claude/settings.json` |
49
- | `{plugin}/.lsp.json` | Install to `~/.claude/plugins/cache/` (LSP support) |
50
-
51
- ## Execution Script
52
-
53
- ```bash
54
- #!/bin/bash
55
-
56
- PROJECT_ROOT="$(pwd)"
57
- MARKETPLACE_PATH="$PROJECT_ROOT/hailer-marketplace"
58
- PLUGIN_NAME="$1"
59
- PLUGIN_PATH="$MARKETPLACE_PATH/$PLUGIN_NAME"
60
- TARGET_CLAUDE=".claude"
61
-
62
- # Pre-flight
63
- if [ ! -d "$PLUGIN_PATH" ]; then
64
- echo "ERROR: Plugin '$PLUGIN_NAME' not found"
65
- exit 1
66
- fi
67
-
68
- # Create target dirs if needed
69
- mkdir -p "$TARGET_CLAUDE/agents" "$TARGET_CLAUDE/skills" "$TARGET_CLAUDE/hooks"
70
-
71
- # Copy agents
72
- if [ -d "$PLUGIN_PATH/agents" ]; then
73
- cp -v "$PLUGIN_PATH/agents/"*.md "$TARGET_CLAUDE/agents/" 2>/dev/null
74
- echo "Installed agents"
75
- fi
76
-
77
- # Copy skills (entire directories)
78
- if [ -d "$PLUGIN_PATH/skills" ]; then
79
- cp -rv "$PLUGIN_PATH/skills/"* "$TARGET_CLAUDE/skills/" 2>/dev/null || true
80
- echo "Installed skills"
81
- fi
82
-
83
- # Copy hooks
84
- if [ -d "$PLUGIN_PATH/hooks" ]; then
85
- find "$PLUGIN_PATH/hooks" -name "*.cjs" -exec cp -v {} "$TARGET_CLAUDE/hooks/" \;
86
- echo "Installed hooks"
87
- fi
88
-
89
- # Auto-install LSP if plugin has .lsp.json
90
- if [ -f "$PLUGIN_PATH/.lsp.json" ]; then
91
- echo "Plugin includes LSP support, installing..."
92
-
93
- # Use typescript-lsp from marketplace as LSP source
94
- LSP_SOURCE="$MARKETPLACE_PATH/typescript-lsp"
95
- LSP_CACHE="$HOME/.claude/plugins/cache/hailer-mcp-marketplace/typescript-lsp/1.0.0"
96
- LSP_INSTALLED="$HOME/.claude/plugins/installed_plugins.json"
97
-
98
- # Create plugin cache directory
99
- mkdir -p "$LSP_CACHE/.claude-plugin"
100
-
101
- # Copy .lsp.json from the LSP plugin source (not the current plugin)
102
- if [ -f "$LSP_SOURCE/.lsp.json" ]; then
103
- cp "$LSP_SOURCE/.lsp.json" "$LSP_CACHE/.lsp.json"
104
- else
105
- cp "$PLUGIN_PATH/.lsp.json" "$LSP_CACHE/.lsp.json"
106
- fi
107
-
108
- # Copy the actual plugin.json from typescript-lsp plugin
109
- if [ -f "$LSP_SOURCE/.claude-plugin/plugin.json" ]; then
110
- cp "$LSP_SOURCE/.claude-plugin/plugin.json" "$LSP_CACHE/.claude-plugin/plugin.json"
111
- else
112
- # Fallback: create minimal plugin.json
113
- cat > "$LSP_CACHE/.claude-plugin/plugin.json" << 'PLUGINJSON'
114
- {
115
- "name": "typescript-lsp",
116
- "version": "1.0.0",
117
- "description": "TypeScript/JavaScript LSP support"
118
- }
119
- PLUGINJSON
120
- fi
121
-
122
- # Register in installed_plugins.json
123
- node -e "
124
- const fs = require('fs');
125
- const path = '$LSP_INSTALLED';
126
-
127
- let data = { version: 2, plugins: {} };
128
- if (fs.existsSync(path)) {
129
- data = JSON.parse(fs.readFileSync(path, 'utf-8'));
130
- }
131
-
132
- const key = 'typescript-lsp@hailer-mcp-marketplace';
133
- if (!data.plugins[key]) {
134
- data.plugins[key] = [{
135
- scope: 'user',
136
- installPath: '$LSP_CACHE',
137
- version: '1.0.0',
138
- installedAt: new Date().toISOString(),
139
- lastUpdated: new Date().toISOString()
140
- }];
141
- fs.writeFileSync(path, JSON.stringify(data, null, 2));
142
- console.log('LSP registered in installed_plugins.json');
143
- } else {
144
- console.log('LSP already registered');
145
- }
146
- "
147
-
148
- # Enable LSP tool in settings.json and .env.local
149
- node -e "
150
- const fs = require('fs');
151
-
152
- // 1. Update .claude/settings.json
153
- const settingsPath = '.claude/settings.json';
154
- let settings = {};
155
- if (fs.existsSync(settingsPath)) {
156
- settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
157
- }
158
- if (!settings.env) settings.env = {};
159
- if (settings.env.ENABLE_LSP_TOOL !== '1') {
160
- settings.env.ENABLE_LSP_TOOL = '1';
161
- fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
162
- console.log('ENABLE_LSP_TOOL set in .claude/settings.json');
163
- } else {
164
- console.log('ENABLE_LSP_TOOL already in settings.json');
165
- }
166
-
167
- // 2. Update .env
168
- const envPath = '.env';
169
- let envContent = '';
170
- if (fs.existsSync(envPath)) {
171
- envContent = fs.readFileSync(envPath, 'utf-8');
172
- }
173
- if (!envContent.includes('ENABLE_LSP_TOOL=')) {
174
- const line = (envContent && !envContent.endsWith('\n') ? '\n' : '') + 'ENABLE_LSP_TOOL=1\n';
175
- fs.appendFileSync(envPath, line);
176
- console.log('ENABLE_LSP_TOOL added to .env');
177
- } else {
178
- console.log('ENABLE_LSP_TOOL already in .env');
179
- }
180
- "
181
-
182
- echo "LSP config installed"
183
- fi
184
-
185
- echo "Files copied. Updating CLAUDE.md..."
186
- ```
187
-
188
- ## Update CLAUDE.md (Node.js)
189
-
190
- Run after file copy to add agent to the main `<agents>` table:
191
-
192
- ```bash
193
- node << 'EOF'
194
- const fs = require("fs");
195
- const path = require("path");
196
-
197
- const PLUGIN_NAME = process.env.PLUGIN_NAME;
198
- const AGENTS_DIR = ".claude/agents";
199
- const CLAUDE_MD = "CLAUDE.md";
200
-
201
- // Find agent files for this plugin
202
- const agentFiles = fs.readdirSync(AGENTS_DIR)
203
- .filter(f => f.startsWith("agent-" + PLUGIN_NAME) || f.includes(PLUGIN_NAME))
204
- .filter(f => f.endsWith(".md"));
205
-
206
- if (agentFiles.length === 0) {
207
- console.log("No agent files found for " + PLUGIN_NAME);
208
- process.exit(0);
209
- }
210
-
211
- let content = fs.readFileSync(CLAUDE_MD, "utf-8");
212
-
213
- for (const agentFile of agentFiles) {
214
- const agentPath = path.join(AGENTS_DIR, agentFile);
215
- const agentContent = fs.readFileSync(agentPath, "utf-8");
216
- const agentName = path.basename(agentFile, ".md");
217
-
218
- // Parse frontmatter
219
- const modelMatch = agentContent.match(/^model:\s*(\w+)/m);
220
- const descMatch = agentContent.match(/^description:\s*(.{1,30})/m);
221
- const model = modelMatch ? modelMatch[1] : "sonnet";
222
- const desc = descMatch ? descMatch[1].trim() : PLUGIN_NAME;
223
-
224
- // Check if already in agents table
225
- if (content.includes("| `" + agentName + "`")) {
226
- console.log(agentName + " already in <agents> table");
227
- continue;
228
- }
229
-
230
- // Insert before </agents>
231
- const newRow = "| " + desc + " | `" + agentName + "` | " + model + " |\n";
232
- content = content.replace("</agents>", newRow + "</agents>");
233
- console.log("Added " + agentName + " to <agents> table");
234
- }
235
-
236
- fs.writeFileSync(CLAUDE_MD, content);
237
- console.log("CLAUDE.md updated");
238
- EOF
239
- ```
240
-
241
- Note: Set `PLUGIN_NAME` env var before running.
242
-
243
- ## Full Command
244
-
245
- Run both scripts in sequence:
246
- ```bash
247
- # 1. Copy files (bash)
248
- # 2. Update CLAUDE.md (node)
249
- ```
250
-
251
- Then: `echo "Restart Claude Code to load: claude -c"`
252
-
253
- ## List Available Plugins
254
-
255
- If no plugin name provided, list available:
256
- ```bash
257
- PROJECT_ROOT="$(pwd)"
258
- MARKETPLACE_PATH="$PROJECT_ROOT/hailer-marketplace"
259
- echo "Available plugins in marketplace:"
260
- jq -r '.plugins[] | " \(.name) v\(.version) - \(.description)"' "$MARKETPLACE_PATH/.claude-plugin/marketplace.json"
261
- ```
@@ -1,42 +0,0 @@
1
- ---
2
- description: List available plugins from local marketplace
3
- ---
4
-
5
- # List Available Marketplace Plugins
6
-
7
- Shows all plugins available in the local marketplace clone.
8
-
9
- ## Usage
10
-
11
- ```
12
- /list-plugins
13
- ```
14
-
15
- ## Execution
16
-
17
- ```bash
18
- PROJECT_ROOT="$(pwd)"
19
- MARKETPLACE_PATH="$PROJECT_ROOT/hailer-marketplace"
20
-
21
- if [ ! -d "$MARKETPLACE_PATH/.git" ]; then
22
- echo "Marketplace not found at $MARKETPLACE_PATH"
23
- echo "Run /marketplace-setup first"
24
- exit 1
25
- fi
26
-
27
- # Pull latest before listing
28
- cd "$MARKETPLACE_PATH" && git pull origin main --quiet && cd - > /dev/null
29
- echo "Pulled latest from marketplace"
30
- echo ""
31
-
32
- jq -r '.plugins[] | " \(.name)@\(.version) - \(.description)"' \
33
- "$MARKETPLACE_PATH/.claude-plugin/marketplace.json"
34
- ```
35
-
36
- ## Output (ALWAYS SHOW TO USER)
37
-
38
- After running the execution script, ALWAYS present the results to the user:
39
-
40
- 1. Show total count: "**X plugins available in marketplace**"
41
- 2. List each plugin with name, version, and description
42
- 3. Remind user they can install with `/install-plugin <name>`