@hailer/mcp 1.2.1 → 2.0.0-beta.10

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 (768) hide show
  1. package/.claude/agents/agent-hailer-helper.md +118 -0
  2. package/.claude/commands/debug-squad.md +13 -290
  3. package/.claude/commands/publish.md +2 -2
  4. package/.claude/commands/review-squad.md +17 -139
  5. package/.claude/skills/create-and-publish-app/SKILL.md +119 -148
  6. package/.claude/skills/hailer-app-builder/SKILL.md +24 -2
  7. package/.claude/skills/hailer-ui-guide/SKILL.md +265 -0
  8. package/.env.example +50 -1
  9. package/CLAUDE.md +141 -10
  10. package/dist/app.d.ts.map +1 -1
  11. package/dist/app.js +3 -0
  12. package/dist/app.js.map +1 -1
  13. package/dist/bot/bot-manager.d.ts +9 -6
  14. package/dist/bot/bot-manager.d.ts.map +1 -1
  15. package/dist/bot/bot-manager.js +142 -31
  16. package/dist/bot/bot-manager.js.map +1 -1
  17. package/dist/bot/bot.d.ts +59 -16
  18. package/dist/bot/bot.d.ts.map +1 -1
  19. package/dist/bot/bot.js +889 -142
  20. package/dist/bot/bot.js.map +1 -1
  21. package/dist/bot/operation-logger.d.ts.map +1 -1
  22. package/dist/bot/operation-logger.js +24 -12
  23. package/dist/bot/operation-logger.js.map +1 -1
  24. package/dist/bot/services/bot-permissions.d.ts +2 -2
  25. package/dist/bot/services/bot-permissions.d.ts.map +1 -1
  26. package/dist/bot/services/bot-permissions.js +28 -9
  27. package/dist/bot/services/bot-permissions.js.map +1 -1
  28. package/dist/bot/services/conversation-manager.d.ts +23 -23
  29. package/dist/bot/services/conversation-manager.d.ts.map +1 -1
  30. package/dist/bot/services/conversation-manager.js +52 -49
  31. package/dist/bot/services/conversation-manager.js.map +1 -1
  32. package/dist/bot/services/helper-prompt.d.ts +8 -0
  33. package/dist/bot/services/helper-prompt.d.ts.map +1 -0
  34. package/dist/bot/services/helper-prompt.js +177 -0
  35. package/dist/bot/services/helper-prompt.js.map +1 -0
  36. package/dist/bot/services/message-classifier.d.ts +16 -16
  37. package/dist/bot/services/message-classifier.d.ts.map +1 -1
  38. package/dist/bot/services/message-classifier.js +55 -49
  39. package/dist/bot/services/message-classifier.js.map +1 -1
  40. package/dist/bot/services/message-formatter.d.ts +38 -38
  41. package/dist/bot/services/message-formatter.d.ts.map +1 -1
  42. package/dist/bot/services/message-formatter.js +81 -74
  43. package/dist/bot/services/message-formatter.js.map +1 -1
  44. package/dist/bot/services/permission-guard.d.ts.map +1 -1
  45. package/dist/bot/services/permission-guard.js +20 -10
  46. package/dist/bot/services/permission-guard.js.map +1 -1
  47. package/dist/bot/services/signal-router.d.ts.map +1 -1
  48. package/dist/bot/services/signal-router.js +11 -6
  49. package/dist/bot/services/signal-router.js.map +1 -1
  50. package/dist/bot/services/system-prompt.d.ts +14 -0
  51. package/dist/bot/services/system-prompt.d.ts.map +1 -1
  52. package/dist/bot/services/system-prompt.js +179 -4
  53. package/dist/bot/services/system-prompt.js.map +1 -1
  54. package/dist/bot/services/token-billing.d.ts +23 -23
  55. package/dist/bot/services/token-billing.d.ts.map +1 -1
  56. package/dist/bot/services/token-billing.js +51 -36
  57. package/dist/bot/services/token-billing.js.map +1 -1
  58. package/dist/bot/services/types.d.ts +3 -1
  59. package/dist/bot/services/types.d.ts.map +1 -1
  60. package/dist/bot/services/typing-indicator.d.ts +8 -8
  61. package/dist/bot/services/typing-indicator.d.ts.map +1 -1
  62. package/dist/bot/services/typing-indicator.js +12 -10
  63. package/dist/bot/services/typing-indicator.js.map +1 -1
  64. package/dist/bot/services/workspace-refresh.d.ts +3 -3
  65. package/dist/bot/services/workspace-refresh.d.ts.map +1 -1
  66. package/dist/bot/services/workspace-refresh.js +23 -13
  67. package/dist/bot/services/workspace-refresh.js.map +1 -1
  68. package/dist/bot/tool-executor.d.ts +10 -6
  69. package/dist/bot/tool-executor.d.ts.map +1 -1
  70. package/dist/bot/tool-executor.js +12 -6
  71. package/dist/bot/tool-executor.js.map +1 -1
  72. package/dist/bot/workspace-overview.d.ts.map +1 -1
  73. package/dist/bot/workspace-overview.js +6 -3
  74. package/dist/bot/workspace-overview.js.map +1 -1
  75. package/dist/bot-config/activity-error.d.ts +47 -0
  76. package/dist/bot-config/activity-error.d.ts.map +1 -0
  77. package/dist/bot-config/activity-error.js +67 -0
  78. package/dist/bot-config/activity-error.js.map +1 -0
  79. package/dist/bot-config/context.d.ts +4 -4
  80. package/dist/bot-config/context.d.ts.map +1 -1
  81. package/dist/bot-config/context.js +18 -14
  82. package/dist/bot-config/context.js.map +1 -1
  83. package/dist/bot-config/events.d.ts +45 -0
  84. package/dist/bot-config/events.d.ts.map +1 -0
  85. package/dist/bot-config/events.js +51 -0
  86. package/dist/bot-config/events.js.map +1 -0
  87. package/dist/bot-config/index.d.ts +3 -0
  88. package/dist/bot-config/index.d.ts.map +1 -1
  89. package/dist/bot-config/index.js +8 -1
  90. package/dist/bot-config/index.js.map +1 -1
  91. package/dist/bot-config/loader.d.ts +3 -0
  92. package/dist/bot-config/loader.d.ts.map +1 -1
  93. package/dist/bot-config/loader.js +45 -20
  94. package/dist/bot-config/loader.js.map +1 -1
  95. package/dist/bot-config/persistence.js.map +1 -1
  96. package/dist/bot-config/reconciler.d.ts +11 -0
  97. package/dist/bot-config/reconciler.d.ts.map +1 -0
  98. package/dist/bot-config/reconciler.js +121 -0
  99. package/dist/bot-config/reconciler.js.map +1 -0
  100. package/dist/bot-config/state.d.ts.map +1 -1
  101. package/dist/bot-config/state.js.map +1 -1
  102. package/dist/bot-config/types.d.ts +32 -0
  103. package/dist/bot-config/types.d.ts.map +1 -1
  104. package/dist/bot-config/webhooks.d.ts.map +1 -1
  105. package/dist/bot-config/webhooks.js.map +1 -1
  106. package/dist/bot-config/workflow-installer.d.ts +37 -0
  107. package/dist/bot-config/workflow-installer.d.ts.map +1 -0
  108. package/dist/bot-config/workflow-installer.js +346 -0
  109. package/dist/bot-config/workflow-installer.js.map +1 -0
  110. package/dist/cli.d.ts.map +1 -1
  111. package/dist/cli.js +54 -0
  112. package/dist/cli.js.map +1 -1
  113. package/dist/config.d.ts +23 -19
  114. package/dist/config.d.ts.map +1 -1
  115. package/dist/config.js +65 -27
  116. package/dist/config.js.map +1 -1
  117. package/dist/core.d.ts +6 -4
  118. package/dist/core.d.ts.map +1 -1
  119. package/dist/core.js +11 -16
  120. package/dist/core.js.map +1 -1
  121. package/dist/lib/logger.d.ts.map +1 -1
  122. package/dist/lib/logger.js +7 -4
  123. package/dist/lib/logger.js.map +1 -1
  124. package/dist/lib/request-logger.d.ts +19 -19
  125. package/dist/lib/request-logger.d.ts.map +1 -1
  126. package/dist/lib/request-logger.js +19 -19
  127. package/dist/lib/request-logger.js.map +1 -1
  128. package/dist/mcp/UserContextCache.d.ts +28 -22
  129. package/dist/mcp/UserContextCache.d.ts.map +1 -1
  130. package/dist/mcp/UserContextCache.js +23 -23
  131. package/dist/mcp/UserContextCache.js.map +1 -1
  132. package/dist/mcp/auth.js.map +1 -1
  133. package/dist/mcp/hailer-clients.d.ts +5 -4
  134. package/dist/mcp/hailer-clients.d.ts.map +1 -1
  135. package/dist/mcp/hailer-clients.js +61 -27
  136. package/dist/mcp/hailer-clients.js.map +1 -1
  137. package/dist/mcp/hailer-rpc.d.ts +40 -0
  138. package/dist/mcp/hailer-rpc.d.ts.map +1 -0
  139. package/dist/mcp/hailer-rpc.js +43 -0
  140. package/dist/mcp/hailer-rpc.js.map +1 -0
  141. package/dist/mcp/publish-auth-injector.d.ts +22 -0
  142. package/dist/mcp/publish-auth-injector.d.ts.map +1 -0
  143. package/dist/mcp/publish-auth-injector.js +100 -0
  144. package/dist/mcp/publish-auth-injector.js.map +1 -0
  145. package/dist/mcp/session-store.d.ts +16 -16
  146. package/dist/mcp/session-store.d.ts.map +1 -1
  147. package/dist/mcp/session-store.js +16 -16
  148. package/dist/mcp/session-store.js.map +1 -1
  149. package/dist/mcp/tool-profiles.d.ts +69 -0
  150. package/dist/mcp/tool-profiles.d.ts.map +1 -0
  151. package/dist/mcp/tool-profiles.js +176 -0
  152. package/dist/mcp/tool-profiles.js.map +1 -0
  153. package/dist/mcp/tool-registry.d.ts +16 -0
  154. package/dist/mcp/tool-registry.d.ts.map +1 -1
  155. package/dist/mcp/tool-registry.js +91 -39
  156. package/dist/mcp/tool-registry.js.map +1 -1
  157. package/dist/mcp/tools/activity.d.ts.map +1 -1
  158. package/dist/mcp/tools/activity.js +398 -198
  159. package/dist/mcp/tools/activity.js.map +1 -1
  160. package/dist/mcp/tools/aliases.d.ts +11 -0
  161. package/dist/mcp/tools/aliases.d.ts.map +1 -0
  162. package/dist/mcp/tools/aliases.js +176 -0
  163. package/dist/mcp/tools/aliases.js.map +1 -0
  164. package/dist/mcp/tools/app-core.d.ts +6 -8
  165. package/dist/mcp/tools/app-core.d.ts.map +1 -1
  166. package/dist/mcp/tools/app-core.js +355 -254
  167. package/dist/mcp/tools/app-core.js.map +1 -1
  168. package/dist/mcp/tools/app-marketplace.d.ts +8 -16
  169. package/dist/mcp/tools/app-marketplace.d.ts.map +1 -1
  170. package/dist/mcp/tools/app-marketplace.js +604 -930
  171. package/dist/mcp/tools/app-marketplace.js.map +1 -1
  172. package/dist/mcp/tools/app.d.ts +4 -7
  173. package/dist/mcp/tools/app.d.ts.map +1 -1
  174. package/dist/mcp/tools/app.js +4 -7
  175. package/dist/mcp/tools/app.js.map +1 -1
  176. package/dist/mcp/tools/bot-self.d.ts +21 -0
  177. package/dist/mcp/tools/bot-self.d.ts.map +1 -0
  178. package/dist/mcp/tools/bot-self.js +174 -0
  179. package/dist/mcp/tools/bot-self.js.map +1 -0
  180. package/dist/mcp/tools/calendar.d.ts +21 -0
  181. package/dist/mcp/tools/calendar.d.ts.map +1 -0
  182. package/dist/mcp/tools/calendar.js +741 -0
  183. package/dist/mcp/tools/calendar.js.map +1 -0
  184. package/dist/mcp/tools/company.d.ts.map +1 -1
  185. package/dist/mcp/tools/company.js +2 -1
  186. package/dist/mcp/tools/company.js.map +1 -1
  187. package/dist/mcp/tools/date.js.map +1 -1
  188. package/dist/mcp/tools/discussion.d.ts +23 -3
  189. package/dist/mcp/tools/discussion.d.ts.map +1 -1
  190. package/dist/mcp/tools/discussion.js +417 -534
  191. package/dist/mcp/tools/discussion.js.map +1 -1
  192. package/dist/mcp/tools/file.d.ts.map +1 -1
  193. package/dist/mcp/tools/file.js +18 -16
  194. package/dist/mcp/tools/file.js.map +1 -1
  195. package/dist/mcp/tools/index.js +4 -4
  196. package/dist/mcp/tools/index.js.map +1 -1
  197. package/dist/mcp/tools/insight.d.ts +7 -5
  198. package/dist/mcp/tools/insight.d.ts.map +1 -1
  199. package/dist/mcp/tools/insight.js +419 -477
  200. package/dist/mcp/tools/insight.js.map +1 -1
  201. package/dist/mcp/tools/user.d.ts.map +1 -1
  202. package/dist/mcp/tools/user.js +15 -13
  203. package/dist/mcp/tools/user.js.map +1 -1
  204. package/dist/mcp/tools/workflow-permissions.d.ts +2 -4
  205. package/dist/mcp/tools/workflow-permissions.d.ts.map +1 -1
  206. package/dist/mcp/tools/workflow-permissions.js +88 -97
  207. package/dist/mcp/tools/workflow-permissions.js.map +1 -1
  208. package/dist/mcp/tools/workflow.d.ts +2 -7
  209. package/dist/mcp/tools/workflow.d.ts.map +1 -1
  210. package/dist/mcp/tools/workflow.js +817 -850
  211. package/dist/mcp/tools/workflow.js.map +1 -1
  212. package/dist/mcp/utils/api-errors.d.ts.map +1 -1
  213. package/dist/mcp/utils/api-errors.js +2 -2
  214. package/dist/mcp/utils/api-errors.js.map +1 -1
  215. package/dist/mcp/utils/data-transformers.d.ts.map +1 -1
  216. package/dist/mcp/utils/data-transformers.js +8 -4
  217. package/dist/mcp/utils/data-transformers.js.map +1 -1
  218. package/dist/mcp/utils/file-upload.d.ts.map +1 -1
  219. package/dist/mcp/utils/file-upload.js +1 -1
  220. package/dist/mcp/utils/file-upload.js.map +1 -1
  221. package/dist/mcp/utils/hailer-api-client.d.ts +81 -81
  222. package/dist/mcp/utils/hailer-api-client.d.ts.map +1 -1
  223. package/dist/mcp/utils/hailer-api-client.js +103 -101
  224. package/dist/mcp/utils/hailer-api-client.js.map +1 -1
  225. package/dist/mcp/utils/index.d.ts.map +1 -1
  226. package/dist/mcp/utils/index.js.map +1 -1
  227. package/dist/mcp/utils/logger.d.ts.map +1 -1
  228. package/dist/mcp/utils/logger.js.map +1 -1
  229. package/dist/mcp/utils/response-builder.d.ts.map +1 -1
  230. package/dist/mcp/utils/response-builder.js +8 -4
  231. package/dist/mcp/utils/response-builder.js.map +1 -1
  232. package/dist/mcp/utils/role-utils.d.ts.map +1 -1
  233. package/dist/mcp/utils/role-utils.js +6 -3
  234. package/dist/mcp/utils/role-utils.js.map +1 -1
  235. package/dist/mcp/utils/tool-helpers.d.ts.map +1 -1
  236. package/dist/mcp/utils/tool-helpers.js +2 -2
  237. package/dist/mcp/utils/tool-helpers.js.map +1 -1
  238. package/dist/mcp/utils/types.d.ts +1 -1
  239. package/dist/mcp/utils/types.d.ts.map +1 -1
  240. package/dist/mcp/utils/types.js.map +1 -1
  241. package/dist/mcp/webhook-handler.d.ts +43 -8
  242. package/dist/mcp/webhook-handler.d.ts.map +1 -1
  243. package/dist/mcp/webhook-handler.js +861 -116
  244. package/dist/mcp/webhook-handler.js.map +1 -1
  245. package/dist/mcp/workspace-admin-store.d.ts +49 -0
  246. package/dist/mcp/workspace-admin-store.d.ts.map +1 -0
  247. package/dist/mcp/workspace-admin-store.js +168 -0
  248. package/dist/mcp/workspace-admin-store.js.map +1 -0
  249. package/dist/mcp/workspace-cache.d.ts +2 -2
  250. package/dist/mcp/workspace-cache.d.ts.map +1 -1
  251. package/dist/mcp/workspace-cache.js +9 -5
  252. package/dist/mcp/workspace-cache.js.map +1 -1
  253. package/dist/mcp-server.d.ts +26 -11
  254. package/dist/mcp-server.d.ts.map +1 -1
  255. package/dist/mcp-server.js +360 -36
  256. package/dist/mcp-server.js.map +1 -1
  257. package/dist/plugins/vipunen/client.d.ts +41 -41
  258. package/dist/plugins/vipunen/client.d.ts.map +1 -1
  259. package/dist/plugins/vipunen/client.js +53 -48
  260. package/dist/plugins/vipunen/client.js.map +1 -1
  261. package/dist/plugins/vipunen/index.js.map +1 -1
  262. package/dist/plugins/vipunen/tools.d.ts.map +1 -1
  263. package/dist/plugins/vipunen/tools.js +6 -3
  264. package/dist/plugins/vipunen/tools.js.map +1 -1
  265. package/dist/public-chat/graduate.d.ts +29 -0
  266. package/dist/public-chat/graduate.d.ts.map +1 -0
  267. package/dist/public-chat/graduate.js +593 -0
  268. package/dist/public-chat/graduate.js.map +1 -0
  269. package/dist/public-chat/handler.d.ts +12 -0
  270. package/dist/public-chat/handler.d.ts.map +1 -0
  271. package/dist/public-chat/handler.js +179 -0
  272. package/dist/public-chat/handler.js.map +1 -0
  273. package/dist/public-chat/index.d.ts +16 -0
  274. package/dist/public-chat/index.d.ts.map +1 -0
  275. package/dist/public-chat/index.js +74 -0
  276. package/dist/public-chat/index.js.map +1 -0
  277. package/dist/public-chat/knowledge.d.ts +3 -0
  278. package/dist/public-chat/knowledge.d.ts.map +1 -0
  279. package/dist/public-chat/knowledge.js +1341 -0
  280. package/dist/public-chat/knowledge.js.map +1 -0
  281. package/dist/public-chat/rate-limit.d.ts +16 -0
  282. package/dist/public-chat/rate-limit.d.ts.map +1 -0
  283. package/dist/public-chat/rate-limit.js +51 -0
  284. package/dist/public-chat/rate-limit.js.map +1 -0
  285. package/dist/public-chat/session-store.d.ts +41 -0
  286. package/dist/public-chat/session-store.d.ts.map +1 -0
  287. package/dist/public-chat/session-store.js +95 -0
  288. package/dist/public-chat/session-store.js.map +1 -0
  289. package/dist/public-chat/studio-prewarm.d.ts +61 -0
  290. package/dist/public-chat/studio-prewarm.d.ts.map +1 -0
  291. package/dist/public-chat/studio-prewarm.js +162 -0
  292. package/dist/public-chat/studio-prewarm.js.map +1 -0
  293. package/dist/public-chat/system-prompt.d.ts +22 -0
  294. package/dist/public-chat/system-prompt.d.ts.map +1 -0
  295. package/dist/public-chat/system-prompt.js +428 -0
  296. package/dist/public-chat/system-prompt.js.map +1 -0
  297. package/package.json +14 -7
  298. package/scripts/build-public-chat-knowledge.py +101 -0
  299. package/scripts/probe-mcp-pricing.ts +52 -0
  300. package/scripts/smoke-public-chat-live.ts +148 -0
  301. package/scripts/smoke-public-chat.ts +110 -0
  302. package/.claude/CLAUDE.md +0 -126
  303. package/.claude/commands/app-squad.md +0 -131
  304. package/.claude/commands/audit-squad.md +0 -158
  305. package/.claude/commands/cleanup-squad.md +0 -98
  306. package/.claude/commands/config-squad.md +0 -106
  307. package/.claude/commands/crud-squad.md +0 -87
  308. package/.claude/commands/data-squad.md +0 -97
  309. package/.claude/commands/doc-squad.md +0 -65
  310. package/.claude/commands/help.md +0 -29
  311. package/.claude/commands/help:agents.md +0 -182
  312. package/.claude/commands/help:commands.md +0 -78
  313. package/.claude/commands/help:faq.md +0 -79
  314. package/.claude/commands/help:plugins.md +0 -50
  315. package/.claude/commands/help:skills.md +0 -87
  316. package/.claude/commands/help:tools.md +0 -75
  317. package/.claude/commands/hotfix-squad.md +0 -112
  318. package/.claude/commands/integration-squad.md +0 -82
  319. package/.claude/commands/janitor-squad.md +0 -167
  320. package/.claude/commands/onboard-squad.md +0 -130
  321. package/.claude/commands/swarm.md +0 -210
  322. package/.claude/commands/tool-builder.md +0 -39
  323. package/.claude/skills/publish-hailer-app/SKILL.md +0 -280
  324. package/dist/CLAUDE.md +0 -370
  325. package/dist/agents/bot-manager.d.ts +0 -48
  326. package/dist/agents/bot-manager.d.ts.map +0 -1
  327. package/dist/agents/bot-manager.js +0 -254
  328. package/dist/agents/bot-manager.js.map +0 -1
  329. package/dist/agents/bug-fixer/ai.d.ts +0 -80
  330. package/dist/agents/bug-fixer/ai.d.ts.map +0 -1
  331. package/dist/agents/bug-fixer/ai.js +0 -466
  332. package/dist/agents/bug-fixer/ai.js.map +0 -1
  333. package/dist/agents/bug-fixer/bot.d.ts +0 -92
  334. package/dist/agents/bug-fixer/bot.d.ts.map +0 -1
  335. package/dist/agents/bug-fixer/bot.js +0 -687
  336. package/dist/agents/bug-fixer/bot.js.map +0 -1
  337. package/dist/agents/bug-fixer/config.d.ts +0 -21
  338. package/dist/agents/bug-fixer/config.d.ts.map +0 -1
  339. package/dist/agents/bug-fixer/config.js +0 -218
  340. package/dist/agents/bug-fixer/config.js.map +0 -1
  341. package/dist/agents/bug-fixer/files.d.ts +0 -67
  342. package/dist/agents/bug-fixer/files.d.ts.map +0 -1
  343. package/dist/agents/bug-fixer/files.js +0 -386
  344. package/dist/agents/bug-fixer/files.js.map +0 -1
  345. package/dist/agents/bug-fixer/git.d.ts +0 -48
  346. package/dist/agents/bug-fixer/git.d.ts.map +0 -1
  347. package/dist/agents/bug-fixer/git.js +0 -298
  348. package/dist/agents/bug-fixer/git.js.map +0 -1
  349. package/dist/agents/bug-fixer/index.d.ts +0 -103
  350. package/dist/agents/bug-fixer/index.d.ts.map +0 -1
  351. package/dist/agents/bug-fixer/index.js +0 -262
  352. package/dist/agents/bug-fixer/index.js.map +0 -1
  353. package/dist/agents/bug-fixer/lsp.d.ts +0 -113
  354. package/dist/agents/bug-fixer/lsp.d.ts.map +0 -1
  355. package/dist/agents/bug-fixer/lsp.js +0 -485
  356. package/dist/agents/bug-fixer/lsp.js.map +0 -1
  357. package/dist/agents/bug-fixer/monitor.d.ts +0 -123
  358. package/dist/agents/bug-fixer/monitor.d.ts.map +0 -1
  359. package/dist/agents/bug-fixer/monitor.js +0 -629
  360. package/dist/agents/bug-fixer/monitor.js.map +0 -1
  361. package/dist/agents/bug-fixer/prompt.d.ts +0 -5
  362. package/dist/agents/bug-fixer/prompt.d.ts.map +0 -1
  363. package/dist/agents/bug-fixer/prompt.js +0 -94
  364. package/dist/agents/bug-fixer/prompt.js.map +0 -1
  365. package/dist/agents/bug-fixer/registries/pending-classification.d.ts +0 -28
  366. package/dist/agents/bug-fixer/registries/pending-classification.d.ts.map +0 -1
  367. package/dist/agents/bug-fixer/registries/pending-classification.js +0 -50
  368. package/dist/agents/bug-fixer/registries/pending-classification.js.map +0 -1
  369. package/dist/agents/bug-fixer/registries/pending-fix.d.ts +0 -33
  370. package/dist/agents/bug-fixer/registries/pending-fix.d.ts.map +0 -1
  371. package/dist/agents/bug-fixer/registries/pending-fix.js +0 -64
  372. package/dist/agents/bug-fixer/registries/pending-fix.js.map +0 -1
  373. package/dist/agents/bug-fixer/registries/pending.d.ts +0 -27
  374. package/dist/agents/bug-fixer/registries/pending.d.ts.map +0 -1
  375. package/dist/agents/bug-fixer/registries/pending.js +0 -49
  376. package/dist/agents/bug-fixer/registries/pending.js.map +0 -1
  377. package/dist/agents/bug-fixer/specialist-daemon.d.ts +0 -88
  378. package/dist/agents/bug-fixer/specialist-daemon.d.ts.map +0 -1
  379. package/dist/agents/bug-fixer/specialist-daemon.js +0 -431
  380. package/dist/agents/bug-fixer/specialist-daemon.js.map +0 -1
  381. package/dist/agents/bug-fixer/specialist.d.ts +0 -47
  382. package/dist/agents/bug-fixer/specialist.d.ts.map +0 -1
  383. package/dist/agents/bug-fixer/specialist.js +0 -327
  384. package/dist/agents/bug-fixer/specialist.js.map +0 -1
  385. package/dist/agents/bug-fixer/types.d.ts +0 -123
  386. package/dist/agents/bug-fixer/types.d.ts.map +0 -1
  387. package/dist/agents/bug-fixer/types.js +0 -9
  388. package/dist/agents/bug-fixer/types.js.map +0 -1
  389. package/dist/agents/factory.d.ts +0 -172
  390. package/dist/agents/factory.d.ts.map +0 -1
  391. package/dist/agents/factory.js +0 -706
  392. package/dist/agents/factory.js.map +0 -1
  393. package/dist/agents/hailer-expert/index.d.ts +0 -8
  394. package/dist/agents/hailer-expert/index.d.ts.map +0 -1
  395. package/dist/agents/hailer-expert/index.js +0 -14
  396. package/dist/agents/hailer-expert/index.js.map +0 -1
  397. package/dist/agents/hal/daemon.d.ts +0 -174
  398. package/dist/agents/hal/daemon.d.ts.map +0 -1
  399. package/dist/agents/hal/daemon.js +0 -1385
  400. package/dist/agents/hal/daemon.js.map +0 -1
  401. package/dist/agents/hal/definitions.d.ts +0 -42
  402. package/dist/agents/hal/definitions.d.ts.map +0 -1
  403. package/dist/agents/hal/definitions.js +0 -300
  404. package/dist/agents/hal/definitions.js.map +0 -1
  405. package/dist/agents/hal/index.d.ts +0 -3
  406. package/dist/agents/hal/index.d.ts.map +0 -1
  407. package/dist/agents/hal/index.js +0 -8
  408. package/dist/agents/hal/index.js.map +0 -1
  409. package/dist/agents/index.d.ts +0 -18
  410. package/dist/agents/index.d.ts.map +0 -1
  411. package/dist/agents/index.js +0 -48
  412. package/dist/agents/index.js.map +0 -1
  413. package/dist/agents/shared/base.d.ts +0 -253
  414. package/dist/agents/shared/base.d.ts.map +0 -1
  415. package/dist/agents/shared/base.js +0 -1122
  416. package/dist/agents/shared/base.js.map +0 -1
  417. package/dist/agents/shared/schemas/action-schema.d.ts +0 -62
  418. package/dist/agents/shared/schemas/action-schema.d.ts.map +0 -1
  419. package/dist/agents/shared/schemas/action-schema.js +0 -483
  420. package/dist/agents/shared/schemas/action-schema.js.map +0 -1
  421. package/dist/agents/shared/services/agent-registry.d.ts +0 -108
  422. package/dist/agents/shared/services/agent-registry.d.ts.map +0 -1
  423. package/dist/agents/shared/services/agent-registry.js +0 -469
  424. package/dist/agents/shared/services/agent-registry.js.map +0 -1
  425. package/dist/agents/shared/services/conversation-manager.d.ts +0 -57
  426. package/dist/agents/shared/services/conversation-manager.d.ts.map +0 -1
  427. package/dist/agents/shared/services/conversation-manager.js +0 -168
  428. package/dist/agents/shared/services/conversation-manager.js.map +0 -1
  429. package/dist/agents/shared/services/mcp-client.d.ts +0 -56
  430. package/dist/agents/shared/services/mcp-client.d.ts.map +0 -1
  431. package/dist/agents/shared/services/mcp-client.js +0 -124
  432. package/dist/agents/shared/services/mcp-client.js.map +0 -1
  433. package/dist/agents/shared/services/message-classifier.d.ts +0 -37
  434. package/dist/agents/shared/services/message-classifier.d.ts.map +0 -1
  435. package/dist/agents/shared/services/message-classifier.js +0 -203
  436. package/dist/agents/shared/services/message-classifier.js.map +0 -1
  437. package/dist/agents/shared/services/message-formatter.d.ts +0 -89
  438. package/dist/agents/shared/services/message-formatter.d.ts.map +0 -1
  439. package/dist/agents/shared/services/message-formatter.js +0 -390
  440. package/dist/agents/shared/services/message-formatter.js.map +0 -1
  441. package/dist/agents/shared/services/session-logger.d.ts +0 -162
  442. package/dist/agents/shared/services/session-logger.d.ts.map +0 -1
  443. package/dist/agents/shared/services/session-logger.js +0 -724
  444. package/dist/agents/shared/services/session-logger.js.map +0 -1
  445. package/dist/agents/shared/services/structured-output-executor.d.ts +0 -88
  446. package/dist/agents/shared/services/structured-output-executor.d.ts.map +0 -1
  447. package/dist/agents/shared/services/structured-output-executor.js +0 -296
  448. package/dist/agents/shared/services/structured-output-executor.js.map +0 -1
  449. package/dist/agents/shared/services/token-billing.d.ts +0 -72
  450. package/dist/agents/shared/services/token-billing.d.ts.map +0 -1
  451. package/dist/agents/shared/services/token-billing.js +0 -198
  452. package/dist/agents/shared/services/token-billing.js.map +0 -1
  453. package/dist/agents/shared/services/tool-executor.d.ts +0 -43
  454. package/dist/agents/shared/services/tool-executor.d.ts.map +0 -1
  455. package/dist/agents/shared/services/tool-executor.js +0 -175
  456. package/dist/agents/shared/services/tool-executor.js.map +0 -1
  457. package/dist/agents/shared/services/typing-indicator.d.ts +0 -24
  458. package/dist/agents/shared/services/typing-indicator.d.ts.map +0 -1
  459. package/dist/agents/shared/services/typing-indicator.js +0 -54
  460. package/dist/agents/shared/services/typing-indicator.js.map +0 -1
  461. package/dist/agents/shared/services/workspace-schema-cache.d.ts +0 -122
  462. package/dist/agents/shared/services/workspace-schema-cache.d.ts.map +0 -1
  463. package/dist/agents/shared/services/workspace-schema-cache.js +0 -507
  464. package/dist/agents/shared/services/workspace-schema-cache.js.map +0 -1
  465. package/dist/agents/shared/specialist.d.ts +0 -91
  466. package/dist/agents/shared/specialist.d.ts.map +0 -1
  467. package/dist/agents/shared/specialist.js +0 -399
  468. package/dist/agents/shared/specialist.js.map +0 -1
  469. package/dist/agents/shared/tool-schema-loader.d.ts +0 -65
  470. package/dist/agents/shared/tool-schema-loader.d.ts.map +0 -1
  471. package/dist/agents/shared/tool-schema-loader.js +0 -238
  472. package/dist/agents/shared/tool-schema-loader.js.map +0 -1
  473. package/dist/agents/shared/types.d.ts +0 -190
  474. package/dist/agents/shared/types.d.ts.map +0 -1
  475. package/dist/agents/shared/types.js +0 -13
  476. package/dist/agents/shared/types.js.map +0 -1
  477. package/dist/bot/bot-config.d.ts +0 -37
  478. package/dist/bot/bot-config.d.ts.map +0 -1
  479. package/dist/bot/bot-config.js +0 -219
  480. package/dist/bot/bot-config.js.map +0 -1
  481. package/dist/bot/services/__tests__/permission-guard.test.d.ts +0 -2
  482. package/dist/bot/services/__tests__/permission-guard.test.d.ts.map +0 -1
  483. package/dist/bot/services/__tests__/permission-guard.test.js +0 -357
  484. package/dist/bot/services/__tests__/permission-guard.test.js.map +0 -1
  485. package/dist/bot/services/session-logger.d.ts +0 -162
  486. package/dist/bot/services/session-logger.d.ts.map +0 -1
  487. package/dist/bot/services/session-logger.js +0 -724
  488. package/dist/bot/services/session-logger.js.map +0 -1
  489. package/dist/bot/services/workspace-schema-cache.d.ts +0 -122
  490. package/dist/bot/services/workspace-schema-cache.d.ts.map +0 -1
  491. package/dist/bot/services/workspace-schema-cache.js +0 -506
  492. package/dist/bot/services/workspace-schema-cache.js.map +0 -1
  493. package/dist/bot-config/tools.d.ts +0 -28
  494. package/dist/bot-config/tools.d.ts.map +0 -1
  495. package/dist/bot-config/tools.js +0 -279
  496. package/dist/bot-config/tools.js.map +0 -1
  497. package/dist/client/agents/base.d.ts +0 -207
  498. package/dist/client/agents/base.d.ts.map +0 -1
  499. package/dist/client/agents/base.js +0 -744
  500. package/dist/client/agents/base.js.map +0 -1
  501. package/dist/client/agents/definitions.d.ts +0 -53
  502. package/dist/client/agents/definitions.d.ts.map +0 -1
  503. package/dist/client/agents/definitions.js +0 -263
  504. package/dist/client/agents/definitions.js.map +0 -1
  505. package/dist/client/agents/orchestrator.d.ts +0 -141
  506. package/dist/client/agents/orchestrator.d.ts.map +0 -1
  507. package/dist/client/agents/orchestrator.js +0 -1062
  508. package/dist/client/agents/orchestrator.js.map +0 -1
  509. package/dist/client/agents/specialist.d.ts +0 -86
  510. package/dist/client/agents/specialist.d.ts.map +0 -1
  511. package/dist/client/agents/specialist.js +0 -340
  512. package/dist/client/agents/specialist.js.map +0 -1
  513. package/dist/client/bot-entrypoint.d.ts +0 -7
  514. package/dist/client/bot-entrypoint.d.ts.map +0 -1
  515. package/dist/client/bot-entrypoint.js +0 -103
  516. package/dist/client/bot-entrypoint.js.map +0 -1
  517. package/dist/client/bot-manager.d.ts +0 -44
  518. package/dist/client/bot-manager.d.ts.map +0 -1
  519. package/dist/client/bot-manager.js +0 -173
  520. package/dist/client/bot-manager.js.map +0 -1
  521. package/dist/client/bot-runner.d.ts +0 -35
  522. package/dist/client/bot-runner.d.ts.map +0 -1
  523. package/dist/client/bot-runner.js +0 -188
  524. package/dist/client/bot-runner.js.map +0 -1
  525. package/dist/client/chat-agent-daemon.d.ts +0 -464
  526. package/dist/client/chat-agent-daemon.d.ts.map +0 -1
  527. package/dist/client/chat-agent-daemon.js +0 -1774
  528. package/dist/client/chat-agent-daemon.js.map +0 -1
  529. package/dist/client/daemon-factory.d.ts +0 -106
  530. package/dist/client/daemon-factory.d.ts.map +0 -1
  531. package/dist/client/daemon-factory.js +0 -301
  532. package/dist/client/daemon-factory.js.map +0 -1
  533. package/dist/client/factory.d.ts +0 -111
  534. package/dist/client/factory.d.ts.map +0 -1
  535. package/dist/client/factory.js +0 -314
  536. package/dist/client/factory.js.map +0 -1
  537. package/dist/client/index.d.ts +0 -17
  538. package/dist/client/index.d.ts.map +0 -1
  539. package/dist/client/index.js +0 -38
  540. package/dist/client/index.js.map +0 -1
  541. package/dist/client/multi-bot-manager.d.ts +0 -42
  542. package/dist/client/multi-bot-manager.d.ts.map +0 -1
  543. package/dist/client/multi-bot-manager.js +0 -161
  544. package/dist/client/multi-bot-manager.js.map +0 -1
  545. package/dist/client/orchestrator-daemon.d.ts +0 -87
  546. package/dist/client/orchestrator-daemon.d.ts.map +0 -1
  547. package/dist/client/orchestrator-daemon.js +0 -444
  548. package/dist/client/orchestrator-daemon.js.map +0 -1
  549. package/dist/client/server.d.ts +0 -8
  550. package/dist/client/server.d.ts.map +0 -1
  551. package/dist/client/server.js +0 -251
  552. package/dist/client/server.js.map +0 -1
  553. package/dist/client/services/agent-registry.d.ts +0 -108
  554. package/dist/client/services/agent-registry.d.ts.map +0 -1
  555. package/dist/client/services/agent-registry.js +0 -630
  556. package/dist/client/services/agent-registry.js.map +0 -1
  557. package/dist/client/services/conversation-manager.d.ts +0 -50
  558. package/dist/client/services/conversation-manager.d.ts.map +0 -1
  559. package/dist/client/services/conversation-manager.js +0 -136
  560. package/dist/client/services/conversation-manager.js.map +0 -1
  561. package/dist/client/services/mcp-client.d.ts +0 -48
  562. package/dist/client/services/mcp-client.d.ts.map +0 -1
  563. package/dist/client/services/mcp-client.js +0 -105
  564. package/dist/client/services/mcp-client.js.map +0 -1
  565. package/dist/client/services/message-classifier.d.ts +0 -37
  566. package/dist/client/services/message-classifier.d.ts.map +0 -1
  567. package/dist/client/services/message-classifier.js +0 -187
  568. package/dist/client/services/message-classifier.js.map +0 -1
  569. package/dist/client/services/message-formatter.d.ts +0 -84
  570. package/dist/client/services/message-formatter.d.ts.map +0 -1
  571. package/dist/client/services/message-formatter.js +0 -353
  572. package/dist/client/services/message-formatter.js.map +0 -1
  573. package/dist/client/services/session-logger.d.ts +0 -106
  574. package/dist/client/services/session-logger.d.ts.map +0 -1
  575. package/dist/client/services/session-logger.js +0 -446
  576. package/dist/client/services/session-logger.js.map +0 -1
  577. package/dist/client/services/tool-executor.d.ts +0 -41
  578. package/dist/client/services/tool-executor.d.ts.map +0 -1
  579. package/dist/client/services/tool-executor.js +0 -169
  580. package/dist/client/services/tool-executor.js.map +0 -1
  581. package/dist/client/services/workspace-schema-cache.d.ts +0 -149
  582. package/dist/client/services/workspace-schema-cache.d.ts.map +0 -1
  583. package/dist/client/services/workspace-schema-cache.js +0 -732
  584. package/dist/client/services/workspace-schema-cache.js.map +0 -1
  585. package/dist/client/specialist-daemon.d.ts +0 -77
  586. package/dist/client/specialist-daemon.d.ts.map +0 -1
  587. package/dist/client/specialist-daemon.js +0 -197
  588. package/dist/client/specialist-daemon.js.map +0 -1
  589. package/dist/client/specialists.d.ts +0 -53
  590. package/dist/client/specialists.d.ts.map +0 -1
  591. package/dist/client/specialists.js +0 -178
  592. package/dist/client/specialists.js.map +0 -1
  593. package/dist/client/tool-schema-loader.d.ts +0 -62
  594. package/dist/client/tool-schema-loader.d.ts.map +0 -1
  595. package/dist/client/tool-schema-loader.js +0 -232
  596. package/dist/client/tool-schema-loader.js.map +0 -1
  597. package/dist/client/types.d.ts +0 -327
  598. package/dist/client/types.d.ts.map +0 -1
  599. package/dist/client/types.js +0 -121
  600. package/dist/client/types.js.map +0 -1
  601. package/dist/commands/seed-config.d.ts +0 -9
  602. package/dist/commands/seed-config.d.ts.map +0 -1
  603. package/dist/commands/seed-config.js +0 -377
  604. package/dist/commands/seed-config.js.map +0 -1
  605. package/dist/commands/setup.d.ts +0 -11
  606. package/dist/commands/setup.d.ts.map +0 -1
  607. package/dist/commands/setup.js +0 -320
  608. package/dist/commands/setup.js.map +0 -1
  609. package/dist/lib/discussion-lock.d.ts +0 -42
  610. package/dist/lib/discussion-lock.d.ts.map +0 -1
  611. package/dist/lib/discussion-lock.js +0 -110
  612. package/dist/lib/discussion-lock.js.map +0 -1
  613. package/dist/mcp/signal-handler.d.ts +0 -82
  614. package/dist/mcp/signal-handler.d.ts.map +0 -1
  615. package/dist/mcp/signal-handler.js +0 -406
  616. package/dist/mcp/signal-handler.js.map +0 -1
  617. package/dist/mcp/tools/__tests__/discussion-forward.test.d.ts +0 -2
  618. package/dist/mcp/tools/__tests__/discussion-forward.test.d.ts.map +0 -1
  619. package/dist/mcp/tools/__tests__/discussion-forward.test.js +0 -218
  620. package/dist/mcp/tools/__tests__/discussion-forward.test.js.map +0 -1
  621. package/dist/mcp/tools/app-member.d.ts +0 -14
  622. package/dist/mcp/tools/app-member.d.ts.map +0 -1
  623. package/dist/mcp/tools/app-member.js +0 -195
  624. package/dist/mcp/tools/app-member.js.map +0 -1
  625. package/dist/mcp/tools/app-scaffold.d.ts +0 -14
  626. package/dist/mcp/tools/app-scaffold.d.ts.map +0 -1
  627. package/dist/mcp/tools/app-scaffold.js +0 -581
  628. package/dist/mcp/tools/app-scaffold.js.map +0 -1
  629. package/dist/mcp/tools/bot-config/constants.d.ts +0 -23
  630. package/dist/mcp/tools/bot-config/constants.d.ts.map +0 -1
  631. package/dist/mcp/tools/bot-config/constants.js +0 -94
  632. package/dist/mcp/tools/bot-config/constants.js.map +0 -1
  633. package/dist/mcp/tools/bot-config/core.d.ts +0 -253
  634. package/dist/mcp/tools/bot-config/core.d.ts.map +0 -1
  635. package/dist/mcp/tools/bot-config/core.js +0 -2456
  636. package/dist/mcp/tools/bot-config/core.js.map +0 -1
  637. package/dist/mcp/tools/bot-config/index.d.ts +0 -10
  638. package/dist/mcp/tools/bot-config/index.d.ts.map +0 -1
  639. package/dist/mcp/tools/bot-config/index.js +0 -59
  640. package/dist/mcp/tools/bot-config/index.js.map +0 -1
  641. package/dist/mcp/tools/bot-config/tools.d.ts +0 -7
  642. package/dist/mcp/tools/bot-config/tools.d.ts.map +0 -1
  643. package/dist/mcp/tools/bot-config/tools.js +0 -15
  644. package/dist/mcp/tools/bot-config/tools.js.map +0 -1
  645. package/dist/mcp/tools/bot-config/types.d.ts +0 -50
  646. package/dist/mcp/tools/bot-config/types.d.ts.map +0 -1
  647. package/dist/mcp/tools/bot-config/types.js +0 -6
  648. package/dist/mcp/tools/bot-config/types.js.map +0 -1
  649. package/dist/mcp/tools/bug-fixer-tools.d.ts +0 -45
  650. package/dist/mcp/tools/bug-fixer-tools.d.ts.map +0 -1
  651. package/dist/mcp/tools/bug-fixer-tools.js +0 -1096
  652. package/dist/mcp/tools/bug-fixer-tools.js.map +0 -1
  653. package/dist/mcp/tools/document.d.ts +0 -11
  654. package/dist/mcp/tools/document.d.ts.map +0 -1
  655. package/dist/mcp/tools/document.js +0 -741
  656. package/dist/mcp/tools/document.js.map +0 -1
  657. package/dist/mcp/tools/investigate.d.ts +0 -9
  658. package/dist/mcp/tools/investigate.d.ts.map +0 -1
  659. package/dist/mcp/tools/investigate.js +0 -254
  660. package/dist/mcp/tools/investigate.js.map +0 -1
  661. package/dist/mcp/utils/pagination.d.ts +0 -40
  662. package/dist/mcp/utils/pagination.d.ts.map +0 -1
  663. package/dist/mcp/utils/pagination.js +0 -55
  664. package/dist/mcp/utils/pagination.js.map +0 -1
  665. package/dist/modules/bug-reports/bug-config.d.ts +0 -25
  666. package/dist/modules/bug-reports/bug-config.d.ts.map +0 -1
  667. package/dist/modules/bug-reports/bug-config.js +0 -187
  668. package/dist/modules/bug-reports/bug-config.js.map +0 -1
  669. package/dist/modules/bug-reports/bug-monitor.d.ts +0 -108
  670. package/dist/modules/bug-reports/bug-monitor.d.ts.map +0 -1
  671. package/dist/modules/bug-reports/bug-monitor.js +0 -510
  672. package/dist/modules/bug-reports/bug-monitor.js.map +0 -1
  673. package/dist/modules/bug-reports/giuseppe-agent.d.ts +0 -58
  674. package/dist/modules/bug-reports/giuseppe-agent.d.ts.map +0 -1
  675. package/dist/modules/bug-reports/giuseppe-agent.js +0 -467
  676. package/dist/modules/bug-reports/giuseppe-agent.js.map +0 -1
  677. package/dist/modules/bug-reports/giuseppe-ai.d.ts +0 -83
  678. package/dist/modules/bug-reports/giuseppe-ai.d.ts.map +0 -1
  679. package/dist/modules/bug-reports/giuseppe-ai.js +0 -466
  680. package/dist/modules/bug-reports/giuseppe-ai.js.map +0 -1
  681. package/dist/modules/bug-reports/giuseppe-bot.d.ts +0 -110
  682. package/dist/modules/bug-reports/giuseppe-bot.d.ts.map +0 -1
  683. package/dist/modules/bug-reports/giuseppe-bot.js +0 -804
  684. package/dist/modules/bug-reports/giuseppe-bot.js.map +0 -1
  685. package/dist/modules/bug-reports/giuseppe-daemon.d.ts +0 -80
  686. package/dist/modules/bug-reports/giuseppe-daemon.d.ts.map +0 -1
  687. package/dist/modules/bug-reports/giuseppe-daemon.js +0 -617
  688. package/dist/modules/bug-reports/giuseppe-daemon.js.map +0 -1
  689. package/dist/modules/bug-reports/giuseppe-files.d.ts +0 -64
  690. package/dist/modules/bug-reports/giuseppe-files.d.ts.map +0 -1
  691. package/dist/modules/bug-reports/giuseppe-files.js +0 -375
  692. package/dist/modules/bug-reports/giuseppe-files.js.map +0 -1
  693. package/dist/modules/bug-reports/giuseppe-git.d.ts +0 -48
  694. package/dist/modules/bug-reports/giuseppe-git.d.ts.map +0 -1
  695. package/dist/modules/bug-reports/giuseppe-git.js +0 -298
  696. package/dist/modules/bug-reports/giuseppe-git.js.map +0 -1
  697. package/dist/modules/bug-reports/giuseppe-lsp.d.ts +0 -113
  698. package/dist/modules/bug-reports/giuseppe-lsp.d.ts.map +0 -1
  699. package/dist/modules/bug-reports/giuseppe-lsp.js +0 -485
  700. package/dist/modules/bug-reports/giuseppe-lsp.js.map +0 -1
  701. package/dist/modules/bug-reports/giuseppe-prompt.d.ts +0 -5
  702. package/dist/modules/bug-reports/giuseppe-prompt.d.ts.map +0 -1
  703. package/dist/modules/bug-reports/giuseppe-prompt.js +0 -94
  704. package/dist/modules/bug-reports/giuseppe-prompt.js.map +0 -1
  705. package/dist/modules/bug-reports/index.d.ts +0 -77
  706. package/dist/modules/bug-reports/index.d.ts.map +0 -1
  707. package/dist/modules/bug-reports/index.js +0 -215
  708. package/dist/modules/bug-reports/index.js.map +0 -1
  709. package/dist/modules/bug-reports/pending-classification-registry.d.ts +0 -28
  710. package/dist/modules/bug-reports/pending-classification-registry.d.ts.map +0 -1
  711. package/dist/modules/bug-reports/pending-classification-registry.js +0 -50
  712. package/dist/modules/bug-reports/pending-classification-registry.js.map +0 -1
  713. package/dist/modules/bug-reports/pending-fix-registry.d.ts +0 -30
  714. package/dist/modules/bug-reports/pending-fix-registry.d.ts.map +0 -1
  715. package/dist/modules/bug-reports/pending-fix-registry.js +0 -42
  716. package/dist/modules/bug-reports/pending-fix-registry.js.map +0 -1
  717. package/dist/modules/bug-reports/pending-registry.d.ts +0 -27
  718. package/dist/modules/bug-reports/pending-registry.d.ts.map +0 -1
  719. package/dist/modules/bug-reports/pending-registry.js +0 -49
  720. package/dist/modules/bug-reports/pending-registry.js.map +0 -1
  721. package/dist/modules/bug-reports/types.d.ts +0 -123
  722. package/dist/modules/bug-reports/types.d.ts.map +0 -1
  723. package/dist/modules/bug-reports/types.js +0 -9
  724. package/dist/modules/bug-reports/types.js.map +0 -1
  725. package/dist/plugins/bug-fixer/index.d.ts +0 -2
  726. package/dist/plugins/bug-fixer/index.d.ts.map +0 -1
  727. package/dist/plugins/bug-fixer/index.js +0 -18
  728. package/dist/plugins/bug-fixer/index.js.map +0 -1
  729. package/dist/plugins/bug-fixer/tools.d.ts +0 -45
  730. package/dist/plugins/bug-fixer/tools.d.ts.map +0 -1
  731. package/dist/plugins/bug-fixer/tools.js +0 -1096
  732. package/dist/plugins/bug-fixer/tools.js.map +0 -1
  733. package/dist/plugins/vipunen/__tests__/tools.test.d.ts +0 -10
  734. package/dist/plugins/vipunen/__tests__/tools.test.d.ts.map +0 -1
  735. package/dist/plugins/vipunen/__tests__/tools.test.js +0 -646
  736. package/dist/plugins/vipunen/__tests__/tools.test.js.map +0 -1
  737. package/dist/routes/agents.d.ts +0 -44
  738. package/dist/routes/agents.d.ts.map +0 -1
  739. package/dist/routes/agents.js +0 -311
  740. package/dist/routes/agents.js.map +0 -1
  741. package/dist/services/agent-credential-store.d.ts +0 -73
  742. package/dist/services/agent-credential-store.d.ts.map +0 -1
  743. package/dist/services/agent-credential-store.js +0 -212
  744. package/dist/services/agent-credential-store.js.map +0 -1
  745. package/dist/stdio-server.d.ts +0 -14
  746. package/dist/stdio-server.d.ts.map +0 -1
  747. package/dist/stdio-server.js +0 -101
  748. package/dist/stdio-server.js.map +0 -1
  749. package/dist/workspace/context.d.ts +0 -148
  750. package/dist/workspace/context.d.ts.map +0 -1
  751. package/dist/workspace/context.js +0 -339
  752. package/dist/workspace/context.js.map +0 -1
  753. package/dist/workspace/credentials.d.ts +0 -55
  754. package/dist/workspace/credentials.d.ts.map +0 -1
  755. package/dist/workspace/credentials.js +0 -239
  756. package/dist/workspace/credentials.js.map +0 -1
  757. package/dist/workspace/index.d.ts +0 -21
  758. package/dist/workspace/index.d.ts.map +0 -1
  759. package/dist/workspace/index.js +0 -45
  760. package/dist/workspace/index.js.map +0 -1
  761. package/dist/workspace/loader.d.ts +0 -27
  762. package/dist/workspace/loader.d.ts.map +0 -1
  763. package/dist/workspace/loader.js +0 -222
  764. package/dist/workspace/loader.js.map +0 -1
  765. package/dist/workspace/schema.d.ts +0 -37
  766. package/dist/workspace/schema.d.ts.map +0 -1
  767. package/dist/workspace/schema.js +0 -192
  768. package/dist/workspace/schema.js.map +0 -1
@@ -6,7 +6,7 @@
6
6
  * These are PLAYGROUND tools requiring workspace administrator permissions.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.workflowTools = exports.autoSetKeysTool = exports.updateWorkflowPhaseTool = exports.coreInitTool = exports.countActivitiesTool = exports.listWorkflowsMinimalTool = exports.testFunctionFieldTool = exports.updateWorkflowFieldTool = exports.removeWorkflowTool = exports.installWorkflowTool = exports.listWorkflowsTool = exports.listWorkflowPhasesTool = exports.getWorkflowSchemaTool = void 0;
9
+ exports.workflowTools = exports.autoSetKeysTool = exports.coreInitTool = exports.testFunctionFieldTool = exports.updateWorkflowStructureTool = exports.removeWorkflowTool = exports.installWorkflowTool = exports.describeWorkflowsTool = void 0;
10
10
  const zod_1 = require("zod");
11
11
  const tool_registry_1 = require("../tool-registry");
12
12
  const logger_1 = require("../../lib/logger");
@@ -34,7 +34,7 @@ function isSdkProject() {
34
34
  function sdkRedirect(tool, sdkCommand, sdkFile) {
35
35
  return {
36
36
  content: [{
37
- type: "text",
37
+ type: 'text',
38
38
  text: `⚠️ **SDK project detected — use the SDK instead of \`${tool}\`**\n\n` +
39
39
  `This project has a \`workspace/\` directory, which means workflow configuration should be managed through SDK files.\n\n` +
40
40
  `**Instead, do this:**\n` +
@@ -96,17 +96,20 @@ function generateKey(name, existingKeys) {
96
96
  .replace(/[^a-zA-Z0-9\s-_]/g, '')
97
97
  .split(/[\s\-_]+/)
98
98
  .filter(w => w.length > 0);
99
- if (words.length === 0)
99
+ if (words.length === 0) {
100
100
  return 'unnamed';
101
+ }
101
102
  const base = words[0].toLowerCase() + words.slice(1).map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join('');
102
103
  const key = base.slice(0, 64);
103
- if (!existingKeys || !existingKeys.has(key))
104
+ if (!existingKeys || !existingKeys.has(key)) {
104
105
  return key;
106
+ }
105
107
  // Dedup: append incrementing suffix
106
108
  for (let i = 2; i <= 99; i++) {
107
109
  const candidate = `${key}${i}`.slice(0, 64);
108
- if (!existingKeys.has(candidate))
110
+ if (!existingKeys.has(candidate)) {
109
111
  return candidate;
112
+ }
110
113
  }
111
114
  return `${key}${Date.now()}`.slice(0, 64);
112
115
  }
@@ -125,13 +128,15 @@ async function autoSetKeys(workflowId, context) {
125
128
  // Collect existing keys to avoid duplicates
126
129
  const existingPhaseKeys = new Set();
127
130
  for (const phase of Object.values(workflow.phases || {})) {
128
- if (phase.key)
131
+ if (phase.key) {
129
132
  existingPhaseKeys.add(phase.key);
133
+ }
130
134
  }
131
135
  const existingFieldKeys = new Set();
132
136
  for (const field of Object.values(workflow.fields || {})) {
133
- if (field.key)
137
+ if (field.key) {
134
138
  existingFieldKeys.add(field.key);
139
+ }
135
140
  }
136
141
  // Set workflow key (unique per workspace — no local dedup needed, API rejects duplicates)
137
142
  if (!workflow.key && workflow.name) {
@@ -177,335 +182,299 @@ async function autoSetKeys(workflowId, context) {
177
182
  return result;
178
183
  }
179
184
  // ============================================================================
180
- // READ TOOLS - Workflow Schema and Information
185
+ // READ TOOLS - Workflow Discovery (describe_workflows)
181
186
  // ============================================================================
182
- const getWorkflowSchemaDescription = `Get workflow field structure - CALL THIS BEFORE create_activity or update_activity.
183
-
184
- **SDK project?** If workspace/ exists, read field definitions from workspace/<WorkflowName>_<id>/fields.ts instead of calling this tool.
185
-
186
- **Hailer Concept:** Shows all fields (columns) in a workflow with their IDs, types, and options. You MUST know field IDs to create or update activities.
187
-
188
- **Returns:** Field IDs, labels, types (text, numeric, date, dropdown, user, activitylink), required status, dropdown options.
189
-
190
- **Critical:** Never guess field IDs - always get them from this tool first.`;
191
- exports.getWorkflowSchemaTool = {
192
- name: 'get_workflow_schema',
193
- group: tool_registry_1.ToolGroup.READ,
194
- description: getWorkflowSchemaDescription,
195
- schema: zod_1.z.object({
196
- workflowId: zod_1.z.string().describe("Workflow ID or key to get schema from"),
197
- phaseId: zod_1.z.string().describe("Phase ID or key to get schema from (use list_workflow_phases to get available phases)"),
198
- compact: zod_1.z.boolean().optional().describe("Return compact summary instead of full field details (default: false)"),
199
- force: zod_1.z.boolean().optional().describe("Override SDK redirect — use API even when workspace/ exists"),
200
- }),
201
- async execute(args, context) {
202
- if (isSdkProject() && !args.force) {
203
- return sdkRedirect('get_workflow_schema', 'cat workspace/<WorkflowName>_<id>/fields.ts', 'workspace/<WorkflowName>_<id>/fields.ts');
204
- }
205
- try {
206
- // Use cached workflow data from context.init (already fetched during initialization)
207
- const workflow = resolveWorkflow(context.init.processes || [], args.workflowId);
208
- if (!workflow) {
209
- return {
210
- content: [{
211
- type: "text",
212
- text: `❌ Workflow "${args.workflowId}" not found`,
213
- }],
214
- };
215
- }
216
- // Get schema for field validation/requirements (optional, mainly for name field info)
217
- const schemaData = await context.hailer.getWorkflowSchema(args.workflowId, args.phaseId);
218
- // Get complete field definitions from workflow (includes keys and all metadata)
219
- const workflowFields = workflow.fields || {};
220
- const fieldsOrder = workflow.fieldsOrder || Object.keys(workflowFields);
221
- // Compact mode: brief summary for chat agents WITH field IDs (required for insights)
222
- if (args.compact) {
223
- const fieldLines = fieldsOrder.map((fieldId) => {
224
- const field = workflowFields[fieldId];
225
- if (!field)
226
- return null;
227
- return `- ${field.label || 'Unnamed'} (${field.type}): fieldId="${fieldId}"`;
228
- }).filter(Boolean);
229
- return {
230
- content: [{
231
- type: "text",
232
- text: `📋 **${workflow.name}** (workflowId: ${args.workflowId})\n\n**Fields:**\n${fieldLines.join('\n')}`,
233
- }],
234
- };
235
- }
236
- let responseText = (isSdkProject() ? SDK_DISCOVERY_HINT : '') + `📋 **WORKFLOW SCHEMA** for "${workflow.name}":\n\n`;
237
- if (schemaData.name) {
238
- responseText += `**Name Field:**\n`;
239
- responseText += `- Type: ${schemaData.name.type}\n`;
240
- responseText += `- Required: ${schemaData.name.required || false}\n`;
241
- if (schemaData.name.placeholder) {
242
- responseText += `- Placeholder: "${schemaData.name.placeholder}"\n`;
243
- }
244
- responseText += `\n`;
245
- }
246
- // Use fieldsOrder to display fields in correct order
247
- if (fieldsOrder.length > 0) {
248
- responseText += `**Available Fields (${fieldsOrder.length} total):**\n\n`;
249
- fieldsOrder.forEach((fieldId, index) => {
250
- const field = workflowFields[fieldId];
251
- if (!field)
252
- return;
253
- responseText += `${index + 1}. **${field.label || 'Unnamed Field'}**\n`;
254
- responseText += ` - Field ID: \`${fieldId}\`\n`;
255
- if (field.key)
256
- responseText += ` - Key: \`${field.key}\`\n`;
257
- responseText += ` - Type: ${field.type}`;
258
- if (field.subtype)
259
- responseText += ` (${field.subtype})`;
260
- responseText += `\n`;
261
- if (field.required)
262
- responseText += ` - Required: Yes\n`;
263
- if (field.description)
264
- responseText += ` - Description: ${field.description}\n`;
265
- if (field.placeholder)
266
- responseText += ` - Placeholder: "${field.placeholder}"\n`;
267
- if (field.data && field.data.length > 0) {
268
- responseText += ` - Options: ${field.data.slice(0, 3).join(', ')}`;
269
- if (field.data.length > 3)
270
- responseText += ` (and ${field.data.length - 3} more)`;
271
- responseText += `\n`;
272
- }
273
- responseText += `\n`;
187
+ /** Render the minimal workflow list former list_workflows_minimal output */
188
+ function renderWorkflowListMinimal(context) {
189
+ const workflows = context.init.processes || [];
190
+ let responseText = (isSdkProject() ? SDK_DISCOVERY_HINT : '') + `📋 **Workflows Found**\n\n`;
191
+ responseText += `Total: ${workflows.length}\n\n`;
192
+ workflows.forEach((wf) => {
193
+ const star = wf.isStarred ? '⭐ ' : '';
194
+ responseText += `${star}**${wf.name}**\n`;
195
+ responseText += ` ID: \`${wf._id}\`\n`;
196
+ responseText += ` Activities: ${wf.createdActivities || 0}\n\n`;
197
+ });
198
+ responseText += `\n💡 **Next Steps:**\n`;
199
+ responseText += `- Use \`describe_workflows\` with a workflowId and include: ['schema'] to see fields\n`;
200
+ responseText += `- Use \`describe_workflows\` with a workflowId and include: ['phases'] to see phases\n`;
201
+ return responseText;
202
+ }
203
+ /** Render the full workflow list with ActivityLink relationships former list_workflows output */
204
+ function renderWorkflowListFull(context) {
205
+ const workflows = context.init.processes || [];
206
+ const workflowSummary = workflows.map((workflow) => {
207
+ const activityLinkFields = Object.entries(workflow.fields ?? {})
208
+ .filter(([, field]) => field.type === 'activitylink');
209
+ const initialPhases = Object.values(workflow.phases || {})
210
+ .filter(phase => phase.isInitial)
211
+ .map(phase => ({
212
+ id: phase._id,
213
+ name: phase.name
214
+ }));
215
+ // Calculate linksTo from activitylink fields
216
+ const linksTo = activityLinkFields.flatMap(([, field]) => field.data || []);
217
+ return {
218
+ id: workflow._id,
219
+ name: workflow.name,
220
+ workspaceId: workflow.cid,
221
+ activityCount: workflow.createdActivities || 0,
222
+ isStarred: workflow.isStarred || false,
223
+ hasActivityLinks: activityLinkFields.length > 0,
224
+ linksTo,
225
+ linkedFrom: [], // Would need to scan all workflows - skip for now
226
+ initialPhases: initialPhases,
227
+ };
228
+ });
229
+ let responseText = `📋 **${workflows.length} Workflows Found**\n\n`;
230
+ responseText += JSON.stringify(workflowSummary, null, 2);
231
+ const relationships = [];
232
+ for (const workflow of workflows) {
233
+ const activityLinkFields = Object.entries(workflow.fields ?? {})
234
+ .filter(([, field]) => field.type === 'activitylink')
235
+ .map(([fieldId, field]) => ({
236
+ id: fieldId,
237
+ label: field.label,
238
+ key: field.key,
239
+ targetWorkflowIds: field.data || [],
240
+ required: field.required || false,
241
+ }));
242
+ for (const field of activityLinkFields) {
243
+ for (const targetWorkflowId of field.targetWorkflowIds) {
244
+ const targetWorkflow = workflows.find((wf) => wf._id === targetWorkflowId);
245
+ relationships.push({
246
+ sourceWorkflowId: workflow._id,
247
+ sourceWorkflowName: workflow.name,
248
+ targetWorkflowId,
249
+ targetWorkflowName: targetWorkflow?.name || 'Unknown',
250
+ fieldLabel: field.label,
251
+ fieldKey: field.key,
252
+ required: field.required,
274
253
  });
275
254
  }
276
- responseText += `💡 **USAGE:**\n`;
277
- responseText += `- Use field IDs (or keys if available) in the 'fields' parameter of list_activities\n`;
278
- responseText += `- **Select ONLY 2-3 essential fields** to minimize token costs\n`;
279
- const firstFieldId = fieldsOrder[0];
280
- const secondFieldId = fieldsOrder[1];
281
- const firstFieldKey = firstFieldId && workflowFields[firstFieldId]?.key;
282
- const secondFieldKey = secondFieldId && workflowFields[secondFieldId]?.key;
283
- if (firstFieldId && secondFieldId) {
284
- responseText += `- Example with IDs: fields: ["${firstFieldId}", "${secondFieldId}"] (just 2 fields)\n`;
285
- if (firstFieldKey && secondFieldKey) {
286
- responseText += `- Example with keys: fields: ["${firstFieldKey}", "${secondFieldKey}"] (more readable)\n`;
287
- }
288
- }
289
- responseText += `- For listings: name + key metric (price/status) is usually sufficient\n`;
290
- responseText += `- Only add description/detail fields when user explicitly needs them`;
291
- return {
292
- content: [{
293
- type: "text",
294
- text: responseText,
295
- }],
296
- };
297
255
  }
298
- catch (error) {
299
- if (!request_logger_1.RequestLogger.getCurrent())
300
- logger.error("Failed to get workflow schema", error);
301
- return {
302
- content: [{
303
- type: "text",
304
- text: `❌ Failed to get workflow schema: ${error instanceof Error ? error.message : String(error)}`,
305
- }],
306
- };
256
+ }
257
+ if (relationships.length > 0) {
258
+ responseText += `\n\n🔗 **Workflow Relationships:**\n`;
259
+ relationships.forEach(rel => {
260
+ responseText += `• ${rel.sourceWorkflowName} → ${rel.targetWorkflowName} (${rel.fieldLabel})\n`;
261
+ });
262
+ }
263
+ responseText += `\n\n💡 Use describe_workflows with a specific workflowId for detailed information.`;
264
+ return responseText;
265
+ }
266
+ /** Render a single-workflow summary — describe_workflows with workflowId and no includes */
267
+ function renderWorkflowSummary(workflow) {
268
+ const fieldCount = Object.keys(workflow.fields || {}).length;
269
+ const phaseCount = Object.keys(workflow.phases || {}).length;
270
+ let responseText = `📋 **${workflow.name}**\n\n`;
271
+ responseText += `- ID: \`${workflow._id}\`\n`;
272
+ if (workflow.key) {
273
+ responseText += `- Key: \`${workflow.key}\`\n`;
274
+ }
275
+ responseText += `- Workspace: \`${workflow.cid}\`\n`;
276
+ responseText += `- Activities: ${workflow.createdActivities || 0}\n`;
277
+ responseText += `- Fields: ${fieldCount}\n`;
278
+ responseText += `- Phases: ${phaseCount}\n`;
279
+ if (workflow.description) {
280
+ responseText += `- Description: ${workflow.description}\n`;
281
+ }
282
+ responseText += `\n💡 Add include: ['schema'] for field IDs, include: ['phases'] for phase IDs.`;
283
+ return responseText;
284
+ }
285
+ /** Render compact field list — former get_workflow_schema compact mode (default) */
286
+ function renderSchemaCompact(workflow) {
287
+ const workflowFields = workflow.fields || {};
288
+ const fieldsOrder = workflow.fieldsOrder || Object.keys(workflowFields);
289
+ const fieldLines = fieldsOrder.map((fieldId) => {
290
+ const field = workflowFields[fieldId];
291
+ if (!field) {
292
+ return null;
307
293
  }
308
- },
309
- };
310
- const listWorkflowPhasesDescription = `List phases (stages/statuses) in a workflow - REQUIRED to get phase IDs.
311
-
312
- **SDK project?** If workspace/ exists, read phases from workspace/<WorkflowName>_<id>/phases.ts instead of calling this tool.
313
-
314
- **Hailer Concept:** Phases are stages like "New" "In Progress" "Done". Activities move through phases as work progresses.
315
-
316
- **When to use:** Before list_activities (need phaseId), before create_activity (need initial phase), before update_activity (to move to new phase).
317
-
318
- **Returns:** Phase names, IDs, which phase is initial (for new items), which is endpoint (completed).`;
319
- exports.listWorkflowPhasesTool = {
320
- name: 'list_workflow_phases',
321
- group: tool_registry_1.ToolGroup.READ,
322
- description: listWorkflowPhasesDescription,
323
- schema: zod_1.z.object({
324
- workflowId: zod_1.z.string().describe("Workflow ID or key to get phases from"),
325
- force: zod_1.z.boolean().optional().describe("Override SDK redirect — use API even when workspace/ exists"),
326
- }),
327
- async execute(args, context) {
328
- if (isSdkProject() && !args.force) {
329
- return sdkRedirect('list_workflow_phases', 'cat workspace/<WorkflowName>_<id>/phases.ts', 'workspace/<WorkflowName>_<id>/phases.ts');
294
+ return `- ${field.label || 'Unnamed'} (${field.type}): fieldId="${fieldId}"`;
295
+ }).filter(Boolean);
296
+ return `📋 **${workflow.name}** (workflowId: ${workflow._id})\n\n**Fields:**\n${fieldLines.join('\n')}`;
297
+ }
298
+ /** Render full field details former get_workflow_schema full mode (detail: 'full') */
299
+ async function renderSchemaFull(workflow, context) {
300
+ // The per-phase schema endpoint supplies name-field metadata; default to the initial phase
301
+ const phaseList = Object.values(workflow.phases || {});
302
+ const schemaPhase = phaseList.find(ph => ph.isInitial) || phaseList[0];
303
+ const schemaData = schemaPhase ? await context.hailer.getWorkflowSchema(workflow._id, schemaPhase._id) : {};
304
+ // Get complete field definitions from workflow (includes keys and all metadata)
305
+ const workflowFields = workflow.fields || {};
306
+ const fieldsOrder = workflow.fieldsOrder || Object.keys(workflowFields);
307
+ let responseText = `📋 **WORKFLOW SCHEMA** for "${workflow.name}":\n\n`;
308
+ if (schemaData.name) {
309
+ responseText += `**Name Field:**\n`;
310
+ responseText += `- Type: ${schemaData.name.type}\n`;
311
+ responseText += `- Required: ${schemaData.name.required || false}\n`;
312
+ responseText += schemaData.name.placeholder ? `- Placeholder: "${schemaData.name.placeholder}"\n` : '';
313
+ responseText += `\n`;
314
+ }
315
+ // Use fieldsOrder to display fields in correct order
316
+ if (fieldsOrder.length > 0) {
317
+ responseText += `**Available Fields (${fieldsOrder.length} total):**\n\n`;
318
+ }
319
+ fieldsOrder.forEach((fieldId, index) => {
320
+ const field = workflowFields[fieldId];
321
+ if (!field) {
322
+ return;
330
323
  }
331
- try {
332
- // Use cached workflow data from context.init (already fetched during initialization)
333
- const workflowData = resolveWorkflow(context.init.processes || [], args.workflowId);
334
- if (!workflowData) {
335
- return {
336
- content: [{
337
- type: "text",
338
- text: `❌ Workflow "${args.workflowId}" not found`,
339
- }],
340
- };
341
- }
342
- const phases = workflowData.phases || {};
343
- const phasesOrder = workflowData.phasesOrder || [];
344
- let responseText = (isSdkProject() ? SDK_DISCOVERY_HINT : '') + `📊 **WORKFLOW PHASES** for "${workflowData.name}":\n\n`;
345
- if (Object.keys(phases).length === 0) {
346
- responseText += `❌ No phases found in workflow "${workflowData.name}".`;
347
- return {
348
- content: [{ type: "text", text: responseText }],
349
- };
350
- }
351
- responseText += `Found ${Object.keys(phases).length} phases:\n\n`;
352
- const orderedPhaseIds = phasesOrder.length > 0 ? phasesOrder : Object.keys(phases);
353
- orderedPhaseIds.forEach((phaseId, index) => {
354
- const phase = phases[phaseId];
355
- if (phase) {
356
- responseText += `${index + 1}. **${phase.name}**\n`;
357
- responseText += ` - Phase ID: \`${phase._id}\`\n`;
358
- if (phase.key) {
359
- responseText += ` - Key: \`${phase.key}\`\n`;
360
- }
361
- if (phase.description) {
362
- responseText += ` - Description: ${phase.description}\n`;
363
- }
364
- if (phase.color) {
365
- responseText += ` - Color: ${phase.color}\n`;
366
- }
367
- if (phase.isInitial) {
368
- responseText += ` - Initial Phase: Yes\n`;
369
- }
370
- if (phase.isEndpoint) {
371
- responseText += ` - Endpoint Phase: Yes\n`;
372
- }
373
- responseText += `\n`;
374
- }
375
- });
376
- responseText += `💡 **USAGE:** Use any of these Phase IDs with the \`list_activities\` tool to get activities in that phase.\n\n`;
377
- responseText += `🔍 **FOR COMPREHENSIVE WORKFLOW VIEW:**\n`;
378
- responseText += `- To see ALL activities across the entire workflow, call \`list_activities\` for each phase ID above\n`;
379
- responseText += `- Each phase contains different activities at different stages of the workflow\n`;
380
- responseText += `- Combine results from all phases to get the complete picture of the workflow\n`;
381
- responseText += `\n**Example workflow:**\n`;
382
- responseText += `1. First call: \`list_activities\` with first phase ID to see new/pending activities\n`;
383
- responseText += `2. Second call: \`list_activities\` with second phase ID to see completed activities\n`;
384
- responseText += `3. Continue for all phases to see the full workflow status`;
385
- return {
386
- content: [{
387
- type: "text",
388
- text: responseText,
389
- }],
390
- };
324
+ responseText += `${index + 1}. **${field.label || 'Unnamed Field'}**\n`;
325
+ responseText += ` - Field ID: \`${fieldId}\`\n`;
326
+ if (field.key) {
327
+ responseText += ` - Key: \`${field.key}\`\n`;
391
328
  }
392
- catch (error) {
393
- if (!request_logger_1.RequestLogger.getCurrent())
394
- logger.error("Failed to list workflow phases", error);
395
- return {
396
- content: [{
397
- type: "text",
398
- text: `❌ Failed to list workflow phases: ${error instanceof Error ? error.message : String(error)}`,
399
- }],
400
- };
329
+ responseText += ` - Type: ${field.type}`;
330
+ if (field.subtype) {
331
+ responseText += ` (${field.subtype})`;
401
332
  }
402
- },
403
- };
404
- const listWorkflowsDescription = `List workflows (processes/pipelines) in the Hailer workspace.
405
-
406
- **Hailer Concept:** A Workflow is like a database table or Kanban board - it defines a process with fields (columns) and phases (stages). Examples: "Sales Pipeline", "Customer Database", "Project Tasks".
407
-
408
- **When to use:** To see all available workflows, find workflow IDs, or understand the workspace structure.
409
-
410
- **Returns:** Workflow names, IDs, activity counts, and relationships between workflows.
411
-
412
- **Next steps:** Use \`list_workflow_phases\` to see stages, then \`get_workflow_schema\` for field structure.`;
413
- exports.listWorkflowsTool = {
414
- name: 'list_workflows',
333
+ responseText += `\n`;
334
+ if (field.required) {
335
+ responseText += ` - Required: Yes\n`;
336
+ }
337
+ if (field.description) {
338
+ responseText += ` - Description: ${field.description}\n`;
339
+ }
340
+ if (field.placeholder) {
341
+ responseText += ` - Placeholder: "${field.placeholder}"\n`;
342
+ }
343
+ if (field.data && field.data.length > 0) {
344
+ const extraOptions = field.data.length > 3 ? ` (and ${field.data.length - 3} more)` : '';
345
+ responseText += ` - Options: ${field.data.slice(0, 3).join(', ')}${extraOptions}\n`;
346
+ }
347
+ responseText += `\n`;
348
+ });
349
+ responseText += `💡 **USAGE:**\n`;
350
+ responseText += `- Use field IDs (or keys if available) in the 'fields' parameter of list_activities\n`;
351
+ responseText += `- **Select ONLY 2-3 essential fields** to minimize token costs\n`;
352
+ const firstFieldId = fieldsOrder[0];
353
+ const secondFieldId = fieldsOrder[1];
354
+ const firstFieldKey = firstFieldId && workflowFields[firstFieldId]?.key;
355
+ const secondFieldKey = secondFieldId && workflowFields[secondFieldId]?.key;
356
+ if (firstFieldId && secondFieldId) {
357
+ responseText += `- Example with IDs: fields: ["${firstFieldId}", "${secondFieldId}"] (just 2 fields)\n`;
358
+ }
359
+ if (firstFieldId && secondFieldId && firstFieldKey && secondFieldKey) {
360
+ responseText += `- Example with keys: fields: ["${firstFieldKey}", "${secondFieldKey}"] (more readable)\n`;
361
+ }
362
+ responseText += `- For listings: name + key metric (price/status) is usually sufficient\n`;
363
+ responseText += `- Only add description/detail fields when user explicitly needs them`;
364
+ return responseText;
365
+ }
366
+ /** Render the phase list — former list_workflow_phases output */
367
+ function renderPhasesSection(workflow) {
368
+ const phases = workflow.phases || {};
369
+ const phasesOrder = workflow.phasesOrder || [];
370
+ let responseText = `📊 **WORKFLOW PHASES** for "${workflow.name}":\n\n`;
371
+ if (Object.keys(phases).length === 0) {
372
+ responseText += `❌ No phases found in workflow "${workflow.name}".`;
373
+ return responseText;
374
+ }
375
+ responseText += `Found ${Object.keys(phases).length} phases:\n\n`;
376
+ const orderedPhaseIds = phasesOrder.length > 0 ? phasesOrder : Object.keys(phases);
377
+ orderedPhaseIds.forEach((phaseId, index) => {
378
+ const phase = phases[phaseId];
379
+ if (!phase) {
380
+ return;
381
+ }
382
+ responseText += `${index + 1}. **${phase.name}**\n`;
383
+ responseText += ` - Phase ID: \`${phase._id}\`\n`;
384
+ if (phase.key) {
385
+ responseText += ` - Key: \`${phase.key}\`\n`;
386
+ }
387
+ if (phase.description) {
388
+ responseText += ` - Description: ${phase.description}\n`;
389
+ }
390
+ if (phase.color) {
391
+ responseText += ` - Color: ${phase.color}\n`;
392
+ }
393
+ if (phase.isInitial) {
394
+ responseText += ` - Initial Phase: Yes\n`;
395
+ }
396
+ if (phase.isEndpoint) {
397
+ responseText += ` - Endpoint Phase: Yes\n`;
398
+ }
399
+ responseText += `\n`;
400
+ });
401
+ responseText += `💡 **USAGE:** Use any of these Phase IDs with the \`list_activities\` tool to get activities in that phase.\n\n`;
402
+ responseText += `🔍 **FOR COMPREHENSIVE WORKFLOW VIEW:**\n`;
403
+ responseText += `- To see ALL activities across the entire workflow, call \`list_activities\` for each phase ID above\n`;
404
+ responseText += `- Each phase contains different activities at different stages of the workflow\n`;
405
+ responseText += `- Combine results from all phases to get the complete picture of the workflow`;
406
+ return responseText;
407
+ }
408
+ const describeWorkflowsDescription = `Discover workflows. Modes: (1) no args → list all workflows (IDs, names, activity counts); detail:'full' adds ActivityLink relationships. (2) workflowId → that workflow's summary. (3) workflowId + include:['schema','phases'] → field IDs/types/options and/or phase IDs/flags; detail:'full' expands schema to full field details. Never guess IDs — call this before create_activity, update_activity, or list_activities.`;
409
+ const describeWorkflowsSchema = zod_1.z.object({
410
+ workflowId: zod_1.z.string().optional().describe('Workflow ID (24-char) or key. Omit to list all workflows'),
411
+ include: zod_1.z
412
+ .array(zod_1.z.enum(['schema', 'phases']))
413
+ .optional()
414
+ .describe("Sections to include when workflowId is given: 'schema' = fields, 'phases' = phases. Both can be combined"),
415
+ detail: zod_1.z
416
+ .enum(['minimal', 'full'])
417
+ .optional()
418
+ .default('minimal')
419
+ .describe("'full' adds relationships to the workflow list and complete field details to the schema (default: 'minimal')"),
420
+ force: zod_1.z.boolean().optional().describe('Override SDK redirect — use API even when workspace/ exists'),
421
+ });
422
+ exports.describeWorkflowsTool = {
423
+ name: 'describe_workflows',
415
424
  group: tool_registry_1.ToolGroup.READ,
416
- description: listWorkflowsDescription,
417
- schema: zod_1.z.object({
418
- workspace: zod_1.z.string().optional().describe("Optional workspace ID or name"),
419
- includeRelationships: zod_1.z.coerce.boolean().optional().default(true).describe("Show ActivityLink relationships between workflows"),
420
- }),
425
+ description: describeWorkflowsDescription,
426
+ schema: describeWorkflowsSchema,
421
427
  async execute(args, context) {
422
- logger.debug('Listing workflows', {
428
+ logger.debug('Describing workflows', {
429
+ workflowId: args.workflowId,
430
+ include: args.include,
431
+ detail: args.detail,
423
432
  apiKey: context.apiKey.substring(0, 8) + '...'
424
433
  });
425
434
  try {
426
- // Use cached workflows from context.init (already fetched during initialization)
427
- let workflows = context.init.processes || [];
428
- if (args.workspace) {
429
- // Filter by workspace ID or name
430
- const workspaceFilter = args.workspace;
431
- workflows = workflows.filter(w => w.cid === workspaceFilter ||
432
- w.cid === workspaceFilter // Could add name-based lookup here if needed
433
- );
435
+ // Mode 1: no workflowId list all workflows
436
+ if (!args.workflowId) {
437
+ const text = args.detail === 'full' ? renderWorkflowListFull(context) : renderWorkflowListMinimal(context);
438
+ return { content: [{ type: 'text', text }] };
434
439
  }
435
- const workflowSummary = workflows.map((workflow) => {
436
- const activityLinkFields = Object.entries(workflow.fields ?? {})
437
- .filter(([_, field]) => field.type === 'activitylink');
438
- const initialPhases = Object.values(workflow.phases || {})
439
- .filter(phase => phase.isInitial)
440
- .map(phase => ({
441
- id: phase._id,
442
- name: phase.name
443
- }));
444
- // Calculate linksTo from activitylink fields
445
- const linksTo = activityLinkFields.flatMap(([_, field]) => field.data || []);
440
+ const workflow = resolveWorkflow(context.init.processes || [], args.workflowId);
441
+ if (!workflow) {
446
442
  return {
447
- id: workflow._id,
448
- name: workflow.name,
449
- workspaceId: workflow.cid,
450
- activityCount: workflow.createdActivities || 0,
451
- isStarred: workflow.isStarred || false,
452
- hasActivityLinks: activityLinkFields.length > 0,
453
- linksTo,
454
- linkedFrom: [], // Would need to scan all workflows - skip for now
455
- initialPhases: initialPhases,
443
+ content: [{
444
+ type: 'text',
445
+ text: `❌ Workflow "${args.workflowId}" not found`,
446
+ }],
456
447
  };
457
- });
458
- let responseText = `📋 **${workflows.length} Workflows Found**\n\n`;
459
- responseText += JSON.stringify(workflowSummary, null, 2);
460
- if (args.includeRelationships) {
461
- const relationships = [];
462
- for (const workflow of workflows) {
463
- const activityLinkFields = Object.entries(workflow.fields ?? {})
464
- .filter(([_, field]) => field.type === 'activitylink')
465
- .map(([fieldId, field]) => ({
466
- id: fieldId,
467
- label: field.label,
468
- key: field.key,
469
- targetWorkflowIds: field.data || [],
470
- required: field.required || false,
471
- }));
472
- for (const field of activityLinkFields) {
473
- for (const targetWorkflowId of field.targetWorkflowIds) {
474
- const targetWorkflow = workflows.find(w => w._id === targetWorkflowId);
475
- relationships.push({
476
- sourceWorkflowId: workflow._id,
477
- sourceWorkflowName: workflow.name,
478
- targetWorkflowId,
479
- targetWorkflowName: targetWorkflow?.name || 'Unknown',
480
- fieldLabel: field.label,
481
- fieldKey: field.key,
482
- required: field.required,
483
- });
484
- }
485
- }
486
- }
487
- if (relationships.length > 0) {
488
- responseText += `\n\n🔗 **Workflow Relationships:**\n`;
489
- relationships.forEach(rel => {
490
- responseText += `• ${rel.sourceWorkflowName} → ${rel.targetWorkflowName} (${rel.fieldLabel})\n`;
491
- });
492
- }
493
448
  }
494
- responseText += `\n\n💡 Use get_workflow_info with specific workflow ID for detailed information.`;
495
- return {
496
- content: [{
497
- type: "text",
498
- text: responseText,
499
- }],
500
- };
449
+ const include = args.include || [];
450
+ // Mode 2: workflowId without includes → summary
451
+ if (include.length === 0) {
452
+ const prefix = isSdkProject() ? SDK_DISCOVERY_HINT : '';
453
+ return { content: [{ type: 'text', text: prefix + renderWorkflowSummary(workflow) }] };
454
+ }
455
+ // Mode 3: workflowId + includes → schema and/or phases deep dive
456
+ if (isSdkProject() && !args.force) {
457
+ return sdkRedirect('describe_workflows', 'cat workspace/<WorkflowName>_<id>/fields.ts workspace/<WorkflowName>_<id>/phases.ts', 'workspace/<WorkflowName>_<id>/');
458
+ }
459
+ const sections = [];
460
+ if (include.includes('schema')) {
461
+ const schemaText = args.detail === 'full' ? await renderSchemaFull(workflow, context) : renderSchemaCompact(workflow);
462
+ sections.push(schemaText);
463
+ }
464
+ if (include.includes('phases')) {
465
+ sections.push(renderPhasesSection(workflow));
466
+ }
467
+ const prefix = isSdkProject() ? SDK_DISCOVERY_HINT : '';
468
+ return { content: [{ type: 'text', text: prefix + sections.join('\n\n') }] };
501
469
  }
502
470
  catch (error) {
503
- if (!request_logger_1.RequestLogger.getCurrent())
504
- logger.error("Error listing workflows", error);
471
+ if (!request_logger_1.RequestLogger.getCurrent()) {
472
+ logger.error('Failed to describe workflows', error);
473
+ }
505
474
  return {
506
475
  content: [{
507
- type: "text",
508
- text: `❌ Error listing workflows: ${error instanceof Error ? error.message : String(error)}`,
476
+ type: 'text',
477
+ text: `❌ Failed to describe workflows: ${error instanceof Error ? error.message : String(error)}`,
509
478
  }],
510
479
  };
511
480
  }
@@ -519,60 +488,67 @@ exports.listWorkflowsTool = {
519
488
  // ============================================================================
520
489
  const installWorkflowDescription = `Install workflow from template
521
490
 
522
- **Field types:** text, textarea, numeric, numericunit, date, datetime, textpredefinedoptions (for dropdowns - NOT 'select'!), activitylink, users, teams, country, subheader`;
491
+ **Field types:** text, textarea, numeric, numericunit, date, datetime, textpredefinedoptions (for dropdowns - NOT 'select'!), activitylink, users, teams, country, subheader
492
+
493
+ **Workflow vs dataset — pick the right shape:**
494
+ - A WORKFLOW is for things with a lifecycle (sales pipeline, project tracker, support tickets) — model with multiple phases the activity moves through.
495
+ - A DATASET is for reference data (customer list, product catalog, equipment register, vendor list) — items don't move through stages, they sit in categories. Model with a SINGLE phase (\`isInitial: true\`), or at most two (e.g. Active/Archived). Don't create rich multi-phase workflows for reference data — the user will end up with a kanban they never use.
496
+ - When the user's request is ambiguous ('customer list', 'projects'), ask them once whether they want stages or just a list before committing.
497
+
498
+ **IMPORTANT — do NOT include real Mongo ObjectId-shaped \`_id\` values anywhere in the template (workflow, fields, or phases).** The server assigns those itself. The only \`_id\` values allowed are template-local references like \`_0001\` (workflow), \`_1000\` (fields), \`_2000\` (phases). Including a 24-hex-char ObjectId can crash Hailer's bulk insert with a duplicate-key error; any such values are stripped before send as a safety net.`;
523
499
  const installWorkflowSchema = zod_1.z.object({
524
500
  workspaceId: zod_1.z
525
501
  .string()
526
502
  .optional()
527
- .describe("Optional workspace ID or name - defaults to current workspace"),
503
+ .describe('Optional workspace ID or name - defaults to current workspace'),
528
504
  workflowTemplates: zod_1.z
529
505
  .array(zod_1.z.object({
530
506
  _id: zod_1.z
531
507
  .string()
532
- .regex(/^_\d{4}$/, "Workflow _id must match pattern _0001, _0002, etc. (underscore + 4 digits)")
508
+ .regex(/^_\d{4}$/, 'Workflow _id must match pattern _0001, _0002, etc. (underscore + 4 digits)')
533
509
  .optional()
534
510
  .describe("Workflow _id for cross-references in activitylink fields (e.g., '_0001', '_0002')"),
535
- name: zod_1.z.string().min(1).describe("Workflow name"),
536
- description: zod_1.z.string().optional().describe("Workflow description"),
511
+ name: zod_1.z.string().min(1).describe('Workflow name'),
512
+ description: zod_1.z.string().optional().describe('Workflow description'),
537
513
  fields: zod_1.z
538
514
  .record(zod_1.z.object({
539
- label: zod_1.z.string().describe("Field label shown in UI"),
515
+ label: zod_1.z.string().describe('Field label shown in UI'),
540
516
  type: zod_1.z.enum([
541
517
  'activitylink', 'country', 'teams', 'text', 'textarea', 'textunit',
542
518
  'textpredefinedoptions', 'users', 'numeric', 'numericunit', 'date',
543
519
  'time', 'datetime', 'daterange', 'timerange', 'datetimerange', 'subheader'
544
- ]).describe("Field type"),
545
- key: zod_1.z.string().optional().describe("Readable field name (like SQL column name) - RECOMMENDED"),
546
- required: zod_1.z.boolean().optional().describe("Whether field is required"),
520
+ ]).describe('Field type'),
521
+ key: zod_1.z.string().optional().describe('Readable field name (like SQL column name) - RECOMMENDED'),
522
+ required: zod_1.z.boolean().optional().describe('Whether field is required'),
547
523
  data: zod_1.z.array(zod_1.z.string()).optional().describe("For textpredefinedoptions: string array like [\"Low\", \"Medium\", \"High\"]. For activitylink: target workflow IDs. NOTE: 'options' also accepted, will be converted to 'data'"),
548
- placeholder: zod_1.z.string().optional().describe("Placeholder text"),
549
- unit: zod_1.z.string().optional().describe("Unit for numeric/textunit fields"),
550
- description: zod_1.z.string().optional().describe("Field description"),
551
- editable: zod_1.z.boolean().optional().describe("Whether field is editable"),
524
+ placeholder: zod_1.z.string().optional().describe('Placeholder text'),
525
+ unit: zod_1.z.string().optional().describe('Unit for numeric/textunit fields'),
526
+ description: zod_1.z.string().optional().describe('Field description'),
527
+ editable: zod_1.z.boolean().optional().describe('Whether field is editable'),
552
528
  }).passthrough())
553
529
  .optional()
554
- .refine((fields) => !fields || Object.keys(fields).every(id => /^_\d{4}$/.test(id)), { message: "Field IDs must match pattern _1000, _1001, etc. (underscore + 4 digits)" })
555
- .describe("Field definitions keyed by field ID (_1000, _1001, etc.)"),
530
+ .refine((fields) => !fields || Object.keys(fields).every(id => /^_\d{4}$/.test(id)), { message: 'Field IDs must match pattern _1000, _1001, etc. (underscore + 4 digits)' })
531
+ .describe('Field definitions keyed by field ID (_1000, _1001, etc.)'),
556
532
  phases: zod_1.z
557
533
  .record(zod_1.z.object({
558
- name: zod_1.z.string().describe("Phase name"),
559
- isInitial: zod_1.z.boolean().optional().describe("Whether activities can be created in this phase"),
560
- fields: zod_1.z.array(zod_1.z.string()).optional().describe("Field IDs visible in this phase (defaults to all)"),
561
- description: zod_1.z.string().optional().describe("Phase description"),
534
+ name: zod_1.z.string().describe('Phase name'),
535
+ isInitial: zod_1.z.boolean().optional().describe('Whether activities can be created in this phase'),
536
+ fields: zod_1.z.array(zod_1.z.string()).optional().describe('Field IDs visible in this phase (defaults to all)'),
537
+ description: zod_1.z.string().optional().describe('Phase description'),
562
538
  }).passthrough())
563
539
  .optional()
564
- .refine((phases) => !phases || Object.keys(phases).every(id => /^_\d{4}$/.test(id)), { message: "Phase IDs must match pattern _2000, _2001, etc. (underscore + 4 digits)" })
565
- .describe("Phase definitions keyed by phase ID (_2000, _2001, etc.)"),
566
- fieldsOrder: zod_1.z.array(zod_1.z.string()).optional().describe("Order of field IDs (auto-generated if omitted)"),
567
- phasesOrder: zod_1.z.array(zod_1.z.string()).optional().describe("Order of phase IDs (auto-generated if omitted)"),
568
- enableMessenger: zod_1.z.boolean().optional().describe("Enable discussion features (defaults to true)"),
569
- enableLinkedAnnouncements: zod_1.z.boolean().optional().describe("Enable announcements (defaults to true)"),
570
- defaultView: zod_1.z.enum(['timeline', 'table', 'kanban', 'calendar', 'map']).optional().describe("Default view type"),
540
+ .refine((phases) => !phases || Object.keys(phases).every(id => /^_\d{4}$/.test(id)), { message: 'Phase IDs must match pattern _2000, _2001, etc. (underscore + 4 digits)' })
541
+ .describe('Phase definitions keyed by phase ID (_2000, _2001, etc.)'),
542
+ fieldsOrder: zod_1.z.array(zod_1.z.string()).optional().describe('Order of field IDs (auto-generated if omitted)'),
543
+ phasesOrder: zod_1.z.array(zod_1.z.string()).optional().describe('Order of phase IDs (auto-generated if omitted)'),
544
+ enableMessenger: zod_1.z.boolean().optional().describe('Enable discussion features (defaults to true)'),
545
+ enableLinkedAnnouncements: zod_1.z.boolean().optional().describe('Enable announcements (defaults to true)'),
546
+ defaultView: zod_1.z.enum(['timeline', 'table', 'kanban', 'calendar', 'map']).optional().describe('Default view type'),
571
547
  }).passthrough())
572
- .min(1, "At least one workflow template is required")
573
- .max(100, "Maximum 100 workflow templates per installation")
574
- .describe("Array of workflow template objects to install"),
575
- force: zod_1.z.boolean().optional().describe("Override SDK redirect — use API directly even when workspace/ exists"),
548
+ .min(1, 'At least one workflow template is required')
549
+ .max(100, 'Maximum 100 workflow templates per installation')
550
+ .describe('Array of workflow template objects to install'),
551
+ force: zod_1.z.boolean().optional().describe('Override SDK redirect — use API directly even when workspace/ exists'),
576
552
  });
577
553
  exports.installWorkflowTool = {
578
554
  name: 'install_workflow',
@@ -597,14 +573,70 @@ exports.installWorkflowTool = {
597
573
  if (!workspaceId) {
598
574
  return {
599
575
  content: [{
600
- type: "text",
576
+ type: 'text',
601
577
  text: `❌ Could not resolve workspace`,
602
578
  }],
603
579
  };
604
580
  }
581
+ // LLMs occasionally invent 24-hex-char ObjectIds that look real
582
+ // and stuff them into `_id` slots. Hailer's server-side install
583
+ // path inserts these verbatim via bulkWrite, and a colliding
584
+ // value crashes the API with `MongoBulkWriteError: E11000
585
+ // duplicate key error`. Strip any `_id` that isn't a
586
+ // template-local reference (`_NNNN`) here as a safety net.
587
+ const TEMPLATE_LOCAL_ID_RE = /^_\d{4}$/;
588
+ const stripBadId = (obj, kind) => {
589
+ if (obj && typeof obj === 'object' && '_id' in obj) {
590
+ const id = obj._id;
591
+ if (typeof id !== 'string' || !TEMPLATE_LOCAL_ID_RE.test(id)) {
592
+ logger.warn(`install_workflow: stripped non-template ${kind} _id from payload`, { strippedId: id });
593
+ delete obj._id;
594
+ }
595
+ }
596
+ };
597
+ // Track template-local workflow `_id`s used in this call so we can
598
+ // hand out a unique one to every workflow that doesn't already have
599
+ // a usable id. Why this exists:
600
+ //
601
+ // hailer-api's `WorkflowV3.prepareProcessTemplate` hardcodes any
602
+ // missing workflow `_id` to the sentinel `'_9999'`, then
603
+ // `Company.instanceFromTemplate` rewrites `_NNNN` value-strings to
604
+ // freshly-generated ObjectIds via an `idsMap` that's SHARED across
605
+ // all processes in one call. Two workflows without an `_id` both
606
+ // get `'_9999'`, both map to the same ObjectId, and the bulk
607
+ // insert crashes with `E11000 duplicate key error` on process._id.
608
+ //
609
+ // Assigning a unique `_0NNN` template-local here side-steps the
610
+ // upstream collision entirely — each workflow ends up with a
611
+ // distinct ObjectId. The result map still returns `_0NNN → real id`
612
+ // so the caller (and the workflow-id extraction below) keep working.
613
+ const usedWorkflowIds = new Set();
614
+ let workflowIdCounter = 0;
615
+ const nextWorkflowId = () => {
616
+ let id;
617
+ do {
618
+ id = '_' + String(workflowIdCounter++).padStart(4, '0');
619
+ } while (usedWorkflowIds.has(id));
620
+ usedWorkflowIds.add(id);
621
+ return id;
622
+ };
605
623
  // Transform templates: fix common LLM mistakes
606
624
  const transformedTemplates = args.workflowTemplates.map((template) => {
607
- let result = { ...template };
625
+ const result = { ...template };
626
+ stripBadId(result, 'workflow');
627
+ // Ensure each workflow has a unique template-local `_id` in
628
+ // this call. See block comment above for the hailer-api bug
629
+ // this works around.
630
+ const existingId = result._id;
631
+ if (typeof existingId === 'string' && TEMPLATE_LOCAL_ID_RE.test(existingId) && !usedWorkflowIds.has(existingId)) {
632
+ usedWorkflowIds.add(existingId);
633
+ }
634
+ else {
635
+ if (existingId !== undefined) {
636
+ logger.warn('install_workflow: duplicate or invalid workflow template _id — reassigning', { existingId });
637
+ }
638
+ result._id = nextWorkflowId();
639
+ }
608
640
  // Transform fields
609
641
  if (template.fields) {
610
642
  const transformedFields = {};
@@ -632,6 +664,7 @@ exports.installWorkflowTool = {
632
664
  delete f.name; // Only 'label' is allowed
633
665
  delete f.sequence; // Not supported
634
666
  delete f.order; // Not supported
667
+ stripBadId(f, 'field');
635
668
  transformedFields[fieldId] = f;
636
669
  }
637
670
  result.fields = transformedFields;
@@ -643,6 +676,7 @@ exports.installWorkflowTool = {
643
676
  const p = { ...phase };
644
677
  delete p.sequence;
645
678
  delete p.order;
679
+ stripBadId(p, 'phase');
646
680
  transformedPhases[phaseId] = p;
647
681
  }
648
682
  result.phases = transformedPhases;
@@ -682,8 +716,9 @@ exports.installWorkflowTool = {
682
716
  // Fallback: if no _0xxx pattern, take all values that look like workflow IDs
683
717
  if (newWorkflowIds.length === 0) {
684
718
  for (const [, id] of Object.entries(result)) {
685
- if (id.length === 24)
719
+ if (id.length === 24) {
686
720
  newWorkflowIds.push(id);
721
+ }
687
722
  break; // Just take the first one
688
723
  }
689
724
  }
@@ -749,12 +784,15 @@ exports.installWorkflowTool = {
749
784
  if (keyResults.length > 0) {
750
785
  const kr = keyResults[0].keys;
751
786
  responseText += `**🔑 Auto-generated keys:**\n`;
752
- if (kr.workflow)
787
+ if (kr.workflow) {
753
788
  responseText += `- Workflow: \`${kr.workflow}\`\n`;
754
- for (const [, key] of Object.entries(kr.phases))
789
+ }
790
+ for (const [, key] of Object.entries(kr.phases)) {
755
791
  responseText += `- Phase: \`${key}\`\n`;
756
- for (const [, key] of Object.entries(kr.fields))
792
+ }
793
+ for (const [, key] of Object.entries(kr.fields)) {
757
794
  responseText += `- Field: \`${key}\`\n`;
795
+ }
758
796
  if (kr.errors.length > 0) {
759
797
  responseText += `- ⚠️ ${kr.errors.length} key(s) failed\n`;
760
798
  }
@@ -770,35 +808,38 @@ exports.installWorkflowTool = {
770
808
  responseText += `{\n`;
771
809
  responseText += ` "workflowId": "${exampleWorkflow}",\n`;
772
810
  responseText += ` "name": "New Activity",\n`;
773
- if (examplePhase)
811
+ if (examplePhase) {
774
812
  responseText += ` "phaseId": "${examplePhase}",\n`;
775
- if (exampleField)
813
+ }
814
+ if (exampleField) {
776
815
  responseText += ` "fields": { "${exampleField}": "value" }\n`;
816
+ }
777
817
  responseText += `}\n`;
778
818
  responseText += `\`\`\``;
779
819
  return {
780
820
  content: [{
781
- type: "text",
821
+ type: 'text',
782
822
  text: responseText,
783
823
  }],
784
824
  };
785
825
  }
786
826
  catch (error) {
787
827
  const errorMessage = error instanceof Error ? error.message : String(error);
788
- if (!request_logger_1.RequestLogger.getCurrent())
789
- logger.error("Error installing workflow", new Error(errorMessage));
828
+ if (!request_logger_1.RequestLogger.getCurrent()) {
829
+ logger.error('Error installing workflow', new Error(errorMessage));
830
+ }
790
831
  // Handle permission errors
791
832
  if (errorMessage.includes('network admin') || errorMessage.includes('PermissionDenied')) {
792
833
  return {
793
834
  content: [{
794
- type: "text",
835
+ type: 'text',
795
836
  text: `❌ **Permission Denied**\n\nYou must be a workspace administrator to install workflows.\n\n**Error:** ${errorMessage}`,
796
837
  }],
797
838
  };
798
839
  }
799
840
  return {
800
841
  content: [{
801
- type: "text",
842
+ type: 'text',
802
843
  text: `❌ **Error installing workflow**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workspace administrator\n- Templates must have valid structure (name, fields, phases)\n- Field/Phase IDs must match pattern _0001, _1000, _2000 (underscore + 4 digits)\n- Workspace ID must be valid`,
803
844
  }],
804
845
  };
@@ -812,20 +853,20 @@ const removeWorkflowDescription = `Delete workflow permanently`;
812
853
  const removeWorkflowSchema = zod_1.z.object({
813
854
  workflowId: zod_1.z
814
855
  .string()
815
- .min(1, "Workflow ID is required")
816
- .describe("The workflow ID or key to remove (get from list_workflows)"),
856
+ .min(1, 'Workflow ID is required')
857
+ .describe('The workflow ID or key to remove (get from list_workflows)'),
817
858
  workspaceId: zod_1.z
818
859
  .string()
819
860
  .optional()
820
- .describe("Optional workspace ID or name - defaults to current workspace"),
861
+ .describe('Optional workspace ID or name - defaults to current workspace'),
821
862
  confirmed: zod_1.z
822
863
  .boolean()
823
864
  .optional()
824
- .describe("First confirmation - must be true to proceed"),
865
+ .describe('First confirmation - must be true to proceed'),
825
866
  secondConfirmed: zod_1.z
826
867
  .boolean()
827
868
  .optional()
828
- .describe("Second confirmation - must be true to proceed (required for double-check safety)"),
869
+ .describe('Second confirmation - must be true to proceed (required for double-check safety)'),
829
870
  });
830
871
  exports.removeWorkflowTool = {
831
872
  name: 'remove_workflow',
@@ -845,7 +886,7 @@ exports.removeWorkflowTool = {
845
886
  if (!workflow) {
846
887
  return {
847
888
  content: [{
848
- type: "text",
889
+ type: 'text',
849
890
  text: `❌ Workflow "${args.workflowId}" not found`,
850
891
  }],
851
892
  };
@@ -883,7 +924,7 @@ exports.removeWorkflowTool = {
883
924
  warningText += `- Verify with user that this is intentional`;
884
925
  return {
885
926
  content: [{
886
- type: "text",
927
+ type: 'text',
887
928
  text: warningText,
888
929
  }],
889
930
  };
@@ -911,20 +952,21 @@ exports.removeWorkflowTool = {
911
952
  responseText += `💡 Use \`list_workflows\` to see remaining workflows in the workspace.`;
912
953
  return {
913
954
  content: [{
914
- type: "text",
955
+ type: 'text',
915
956
  text: responseText,
916
957
  }],
917
958
  };
918
959
  }
919
960
  catch (error) {
920
- if (!request_logger_1.RequestLogger.getCurrent())
921
- logger.error("Error removing workflow", error);
961
+ if (!request_logger_1.RequestLogger.getCurrent()) {
962
+ logger.error('Error removing workflow', error);
963
+ }
922
964
  const errorMessage = error instanceof Error ? error.message : String(error);
923
965
  // Handle permission errors
924
966
  if (errorMessage.includes('network admin') || errorMessage.includes('PermissionDenied') || errorMessage.includes('permission')) {
925
967
  return {
926
968
  content: [{
927
- type: "text",
969
+ type: 'text',
928
970
  text: `❌ **Permission Denied**\n\nYou must be a workspace administrator to remove workflows.\n\n**Error:** ${errorMessage}`,
929
971
  }],
930
972
  };
@@ -933,14 +975,14 @@ exports.removeWorkflowTool = {
933
975
  if (errorMessage.includes('not found') || errorMessage.includes('NotFound')) {
934
976
  return {
935
977
  content: [{
936
- type: "text",
978
+ type: 'text',
937
979
  text: `❌ **Workflow Not Found**\n\nThe specified workflow does not exist or you don't have access to it.\n\n**Workflow ID:** \`${args.workflowId}\`\n\n**Error:** ${errorMessage}\n\n💡 Use \`list_workflows\` to see available workflows.`,
938
980
  }],
939
981
  };
940
982
  }
941
983
  return {
942
984
  content: [{
943
- type: "text",
985
+ type: 'text',
944
986
  text: `❌ **Error removing workflow**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workspace administrator\n- Workflow ID must be valid and exist in the workspace\n- Workflow must not be referenced by other workflows (check ActivityLinks)`,
945
987
  }],
946
988
  };
@@ -948,142 +990,400 @@ exports.removeWorkflowTool = {
948
990
  }
949
991
  };
950
992
  // ============================================================================
951
- // TOOL 3: UPDATE WORKFLOW FIELD
993
+ // TOOL 3: UPDATE WORKFLOW STRUCTURE (create/update fields and phases)
952
994
  // ============================================================================
953
- const updateWorkflowFieldDescription = `Update workflow field properties. Field type cannot be changed after creation. Load \`sdk-ws-config-skill\` for field type reference and updatable properties.`;
954
- const updateWorkflowFieldSchema = zod_1.z.object({
995
+ const updateWorkflowStructureDescription = `Modify workflow structure. Actions: create_field (field.label + field.type required; type is permanent), update_field (fieldId + field required), create_phase (adds a phase named "New Phase" — rename it via update_phase), update_phase (phaseId + phase required; name/description/color). update_field auto-generates a camelCase key from field.label when no key is given — set autoGenerateKey:false when changing only the label. Field types: text, textarea, numeric, numericunit, date, datetime, textpredefinedoptions (dropdown), activitylink, users, teams.`;
996
+ const updateWorkflowStructureSchema = zod_1.z.object({
955
997
  workflowId: zod_1.z
956
998
  .string()
957
- .min(1, "Workflow ID is required")
958
- .describe("The workflow ID or key containing the field (get from list_workflows)"),
959
- fieldId: zod_1.z
960
- .string()
961
- .min(1, "Field ID is required")
962
- .describe("The field ID to update (get from workflow schema)"),
963
- fieldData: zod_1.z
964
- .record(zod_1.z.unknown())
965
- .describe("Field properties to update (label, key, type, data, required, etc.)"),
966
- workspaceId: zod_1.z
967
- .string()
968
- .optional()
969
- .describe("Optional workspace ID or name - defaults to current workspace"),
970
- language: zod_1.z
971
- .string()
972
- .default("en")
973
- .optional()
974
- .describe("Language code for the update (default: 'en')"),
999
+ .min(1, 'Workflow ID is required')
1000
+ .describe('The workflow ID (24-char) or key to modify'),
1001
+ action: zod_1.z
1002
+ .enum(['create_field', 'update_field', 'create_phase', 'update_phase'])
1003
+ .describe('Structure operation to perform'),
1004
+ fieldId: zod_1.z.string().optional().describe('Field ID to update (required for update_field)'),
1005
+ phaseId: zod_1.z.string().optional().describe('Phase ID or key to update (required for update_phase)'),
1006
+ field: zod_1.z.object({
1007
+ label: zod_1.z.string().optional().describe('Field display label (required for create_field)'),
1008
+ type: zod_1.z.enum([
1009
+ 'text', 'textarea', 'numeric', 'numericunit',
1010
+ 'date', 'datetime', 'daterange', 'datetimerange', 'time', 'timerange',
1011
+ 'textpredefinedoptions', 'activitylink', 'users', 'teams',
1012
+ 'country', 'linkedfrom', 'subheader'
1013
+ ]).optional().describe('Field type (required for create_field; cannot be changed after creation)'),
1014
+ key: zod_1.z.string().optional().describe('Unique field key (for programmatic access)'),
1015
+ unit: zod_1.z.string().optional().describe("Unit for numericunit fields (e.g. '€', 'kg')"),
1016
+ data: zod_1.z.array(zod_1.z.string()).optional().describe('For textpredefinedoptions: option values. For activitylink: target workflow IDs'),
1017
+ required: zod_1.z.boolean().optional().describe('Whether field is required'),
1018
+ description: zod_1.z.string().optional().describe('Field description/help text'),
1019
+ placeholder: zod_1.z.string().optional().describe('Placeholder text'),
1020
+ defaultTo: zod_1.z.boolean().optional().describe('Enable default value'),
1021
+ defaultValue: zod_1.z.string().optional().describe('Default value if defaultTo is enabled'),
1022
+ }).passthrough().optional().describe('Field definition (create_field) or properties to change (update_field)'),
1023
+ phase: zod_1.z.object({
1024
+ name: zod_1.z.string().optional().describe('New phase name'),
1025
+ description: zod_1.z.string().optional().describe('New phase description'),
1026
+ color: zod_1.z.string().optional().describe('Phase color code'),
1027
+ }).passthrough().optional().describe('Phase properties to update (update_phase)'),
975
1028
  autoGenerateKey: zod_1.z
976
1029
  .boolean()
977
- .default(true)
978
1030
  .optional()
979
- .describe("Auto-generate camelCase key from label if key not provided (default: true). IMPORTANT: Set to false when updating ONLY the label to prevent key regeneration errors."),
980
- force: zod_1.z.boolean().optional().describe("Override SDK redirect use API directly even when workspace/ exists"),
1031
+ .default(true)
1032
+ .describe('update_field only: auto-generate camelCase key from field.label if key not provided (default: true). Set to false when updating ONLY the label to prevent key regeneration errors.'),
1033
+ force: zod_1.z.boolean().optional().describe('Override SDK redirect — use API directly even when workspace/ exists'),
981
1034
  });
982
- exports.updateWorkflowFieldTool = {
983
- name: 'update_workflow_field',
984
- group: tool_registry_1.ToolGroup.PLAYGROUND,
985
- description: updateWorkflowFieldDescription,
986
- schema: updateWorkflowFieldSchema,
987
- async execute(args, context) {
988
- if (isSdkProject() && !args.force) {
989
- return sdkRedirect('update_workflow_field', 'npm run fields-push:force', 'workspace/<WorkflowName>_<id>/fields.ts');
1035
+ /** Build a validation error response for update_workflow_structure */
1036
+ function structureValidationError(message) {
1037
+ return {
1038
+ content: [{
1039
+ type: 'text',
1040
+ text: `❌ **Invalid update_workflow_structure call**\n\n${message}`,
1041
+ }],
1042
+ };
1043
+ }
1044
+ /** create_field action — former create_workflow_field body */
1045
+ async function executeCreateField(workflowId, field, context) {
1046
+ logger.debug('Creating workflow field', {
1047
+ workflowId,
1048
+ fieldLabel: field.label,
1049
+ fieldType: field.type,
1050
+ });
1051
+ try {
1052
+ if (workflowId.length !== 24) {
1053
+ return {
1054
+ content: [{
1055
+ type: 'text',
1056
+ text: `Invalid workflowId "${workflowId}" - must be a 24-character ID.\n\n**How to get valid workflow IDs:**\n\`\`\`\ndescribe_workflows()\n\`\`\``,
1057
+ }],
1058
+ };
990
1059
  }
991
- logger.debug('Updating workflow field', {
992
- workflowId: args.workflowId,
993
- fieldId: args.fieldId,
994
- apiKey: context.apiKey.substring(0, 8) + '...'
1060
+ // Call RPC endpoint process.create_field
1061
+ const newField = await context.hailer.request('process.create_field', [
1062
+ workflowId,
1063
+ field
1064
+ ]);
1065
+ logger.debug('Workflow field created', {
1066
+ workflowId,
1067
+ fieldId: newField?._id,
1068
+ fieldLabel: newField?.label,
995
1069
  });
996
- try {
997
- // Get current workspace from cached init data
998
- let workspaceId = args.workspaceId;
999
- if (!workspaceId) {
1000
- workspaceId = context.init.network?._id;
1001
- }
1002
- // Process field data - auto-generate key from label if requested
1003
- const fieldData = { ...args.fieldData };
1004
- const autoGenerateKey = args.autoGenerateKey !== false; // Default to true
1005
- if (autoGenerateKey && fieldData.label && !fieldData.key) {
1006
- const generatedKey = labelToCamelCase(fieldData.label);
1007
- fieldData.key = generatedKey;
1008
- logger.debug('Auto-generated key from label', {
1009
- label: fieldData.label,
1010
- key: generatedKey
1011
- });
1012
- }
1013
- const language = args.language || 'en';
1014
- logger.debug('Calling process.update_field', {
1015
- workflowId: args.workflowId,
1016
- fieldId: args.fieldId,
1017
- language,
1018
- fieldData
1019
- });
1020
- // Call process.update_field endpoint
1021
- await context.hailer.request('process.update_field', [
1022
- args.workflowId,
1023
- args.fieldId,
1024
- fieldData,
1025
- language
1026
- ]);
1027
- logger.debug('Workflow field update successful', {
1028
- workflowId: args.workflowId,
1029
- fieldId: args.fieldId
1030
- });
1031
- // Build success response
1032
- let responseText = `✅ **Workflow Field Updated Successfully**\n\n`;
1033
- responseText += `**Workflow ID:** \`${args.workflowId}\`\n`;
1034
- responseText += `**Field ID:** \`${args.fieldId}\`\n`;
1035
- responseText += `**Workspace:** ${workspaceId}\n\n`;
1036
- responseText += `**Updated Properties:**\n`;
1037
- Object.entries(fieldData).forEach(([key, value]) => {
1038
- const valueStr = typeof value === 'object' ? JSON.stringify(value) : String(value);
1039
- responseText += `- ${key}: \`${valueStr}\`\n`;
1070
+ let responseText = `✅ **Field Created Successfully**\n\n`;
1071
+ responseText += `**Workflow ID:** \`${workflowId}\`\n`;
1072
+ responseText += `**Field ID:** \`${newField._id}\`\n`;
1073
+ responseText += `**Label:** ${newField.label}\n`;
1074
+ responseText += `**Type:** ${newField.type}\n`;
1075
+ if (newField.key) {
1076
+ responseText += `**Key:** ${newField.key}\n`;
1077
+ }
1078
+ if (newField.unit) {
1079
+ responseText += `**Unit:** ${newField.unit}\n`;
1080
+ }
1081
+ if (newField.data?.length) {
1082
+ responseText += `**Options/Links:** ${newField.data.join(', ')}\n`;
1083
+ }
1084
+ responseText += `\n💡 **Next Steps:**\n`;
1085
+ responseText += `- Use this field ID in \`create_activity\` or \`update_activity\` to set values\n`;
1086
+ responseText += `- Use \`describe_workflows\` with include: ['schema'] to verify the field was added\n`;
1087
+ return {
1088
+ content: [{
1089
+ type: 'text',
1090
+ text: responseText,
1091
+ }],
1092
+ };
1093
+ }
1094
+ catch (error) {
1095
+ if (!request_logger_1.RequestLogger.getCurrent()) {
1096
+ logger.error('Error creating workflow field', error);
1097
+ }
1098
+ const errorMessage = error instanceof Error ? error.message : String(error);
1099
+ if (errorMessage.includes('Permission') || errorMessage.includes('permission')) {
1100
+ return {
1101
+ content: [{
1102
+ type: 'text',
1103
+ text: `❌ **Permission Denied**\n\nYou must be a workflow administrator to create fields.\n\n**Error:** ${errorMessage}`,
1104
+ }],
1105
+ };
1106
+ }
1107
+ if (errorMessage.includes('key')) {
1108
+ return {
1109
+ content: [{
1110
+ type: 'text',
1111
+ text: `❌ **Duplicate Key**\n\n${errorMessage}\n\nUse a different \`key\` value or omit it to auto-generate.`,
1112
+ }],
1113
+ };
1114
+ }
1115
+ return {
1116
+ content: [{
1117
+ type: 'text',
1118
+ text: `❌ **Error creating field**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workflow administrator\n- Workflow ID must be valid (24 characters)\n- Field type must be valid\n- Field key must be unique within workflow`,
1119
+ }],
1120
+ };
1121
+ }
1122
+ }
1123
+ /** update_field action — former update_workflow_field body */
1124
+ async function executeUpdateField(workflowId, fieldId, field, autoGenerateKey, context) {
1125
+ logger.debug('Updating workflow field', {
1126
+ workflowId,
1127
+ fieldId,
1128
+ apiKey: context.apiKey.substring(0, 8) + '...'
1129
+ });
1130
+ try {
1131
+ const workspaceId = context.init.network?._id;
1132
+ // Process field data - auto-generate key from label if requested
1133
+ const fieldData = { ...field };
1134
+ if (autoGenerateKey && fieldData.label && !fieldData.key) {
1135
+ const generatedKey = labelToCamelCase(fieldData.label);
1136
+ fieldData.key = generatedKey;
1137
+ logger.debug('Auto-generated key from label', {
1138
+ label: fieldData.label,
1139
+ key: generatedKey
1040
1140
  });
1041
- responseText += `\n💡 **Next Steps:**\n`;
1042
- responseText += `- Use \`get_workflow_schema\` to verify the field changes\n`;
1043
- responseText += `- Use \`list_activities\` with \`returnFlat: true\` to see the key in action\n`;
1044
- if (fieldData.key) {
1045
- responseText += `\n**Using the new key:**\n`;
1046
- responseText += `When creating/updating activities with \`returnFlat: true\`, use:\n`;
1047
- responseText += `\`\`\`javascript\n`;
1048
- responseText += `fields: { "${fieldData.key}": "value" }\n`;
1049
- responseText += `\`\`\``;
1050
- }
1141
+ }
1142
+ const language = 'en';
1143
+ logger.debug('Calling process.update_field', {
1144
+ workflowId,
1145
+ fieldId,
1146
+ language,
1147
+ fieldData
1148
+ });
1149
+ // Call process.update_field endpoint
1150
+ await context.hailer.request('process.update_field', [
1151
+ workflowId,
1152
+ fieldId,
1153
+ fieldData,
1154
+ language
1155
+ ]);
1156
+ logger.debug('Workflow field update successful', {
1157
+ workflowId,
1158
+ fieldId
1159
+ });
1160
+ // Build success response
1161
+ let responseText = `✅ **Workflow Field Updated Successfully**\n\n`;
1162
+ responseText += `**Workflow ID:** \`${workflowId}\`\n`;
1163
+ responseText += `**Field ID:** \`${fieldId}\`\n`;
1164
+ responseText += `**Workspace:** ${workspaceId}\n\n`;
1165
+ responseText += `**Updated Properties:**\n`;
1166
+ Object.entries(fieldData).forEach(([key, value]) => {
1167
+ const valueStr = typeof value === 'object' ? JSON.stringify(value) : String(value);
1168
+ responseText += `- ${key}: \`${valueStr}\`\n`;
1169
+ });
1170
+ responseText += `\n💡 **Next Steps:**\n`;
1171
+ responseText += `- Use \`describe_workflows\` with include: ['schema'] to verify the field changes\n`;
1172
+ responseText += `- Use \`list_activities\` with \`returnFlat: true\` to see the key in action\n`;
1173
+ if (fieldData.key) {
1174
+ responseText += `\n**Using the new key:**\n`;
1175
+ responseText += `When creating/updating activities with \`returnFlat: true\`, use:\n`;
1176
+ responseText += `\`\`\`javascript\n`;
1177
+ responseText += `fields: { "${fieldData.key}": "value" }\n`;
1178
+ responseText += `\`\`\``;
1179
+ }
1180
+ return {
1181
+ content: [{
1182
+ type: 'text',
1183
+ text: responseText,
1184
+ }],
1185
+ };
1186
+ }
1187
+ catch (error) {
1188
+ if (!request_logger_1.RequestLogger.getCurrent()) {
1189
+ logger.error('Error updating workflow field', error);
1190
+ }
1191
+ const errorMessage = error instanceof Error ? error.message : String(error);
1192
+ // Handle permission errors
1193
+ if (errorMessage.includes('network admin') || errorMessage.includes('PermissionDenied') || errorMessage.includes('permission')) {
1051
1194
  return {
1052
1195
  content: [{
1053
- type: "text",
1054
- text: responseText,
1196
+ type: 'text',
1197
+ text: `❌ **Permission Denied**\n\nYou must be a workspace administrator to update workflow fields.\n\n**Error:** ${errorMessage}`,
1055
1198
  }],
1056
1199
  };
1057
1200
  }
1058
- catch (error) {
1059
- if (!request_logger_1.RequestLogger.getCurrent())
1060
- logger.error("Error updating workflow field", error);
1061
- const errorMessage = error instanceof Error ? error.message : String(error);
1062
- // Handle permission errors
1063
- if (errorMessage.includes('network admin') || errorMessage.includes('PermissionDenied') || errorMessage.includes('permission')) {
1064
- return {
1065
- content: [{
1066
- type: "text",
1067
- text: `❌ **Permission Denied**\n\nYou must be a workspace administrator to update workflow fields.\n\n**Error:** ${errorMessage}`,
1068
- }],
1069
- };
1070
- }
1071
- // Handle not found errors
1072
- if (errorMessage.includes('not found') || errorMessage.includes('NotFound')) {
1073
- return {
1074
- content: [{
1075
- type: "text",
1076
- text: `❌ **Workflow or Field Not Found**\n\nThe specified workflow or field does not exist.\n\n**Workflow ID:** \`${args.workflowId}\`\n**Field ID:** \`${args.fieldId}\`\n\n**Error:** ${errorMessage}\n\n💡 Use \`list_workflows\` and \`get_workflow_schema\` to see available workflows and fields.`,
1077
- }],
1078
- };
1079
- }
1201
+ // Handle not found errors
1202
+ if (errorMessage.includes('not found') || errorMessage.includes('NotFound')) {
1203
+ return {
1204
+ content: [{
1205
+ type: 'text',
1206
+ text: `❌ **Workflow or Field Not Found**\n\nThe specified workflow or field does not exist.\n\n**Workflow ID:** \`${workflowId}\`\n**Field ID:** \`${fieldId}\`\n\n**Error:** ${errorMessage}\n\n💡 Use \`describe_workflows\` to see available workflows and fields.`,
1207
+ }],
1208
+ };
1209
+ }
1210
+ return {
1211
+ content: [{
1212
+ type: 'text',
1213
+ text: `❌ **Error updating workflow field**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workspace administrator\n- Workflow ID and Field ID must be valid\n- Field data must match field type requirements\n- Some field types may have restrictions on updates`,
1214
+ }],
1215
+ };
1216
+ }
1217
+ }
1218
+ /** create_phase action — former create_workflow_phase body */
1219
+ async function executeCreatePhase(workflowId, context) {
1220
+ logger.debug('Creating workflow phase', {
1221
+ workflowId,
1222
+ apiKey: context.apiKey.substring(0, 8) + '...'
1223
+ });
1224
+ try {
1225
+ // Validate workflowId format
1226
+ if (workflowId.length !== 24) {
1227
+ return {
1228
+ content: [{
1229
+ type: 'text',
1230
+ text: `Invalid workflowId "${workflowId}" - must be a 24-character ID.\n\n**How to get valid workflow IDs:**\n\`\`\`\ndescribe_workflows()\n\`\`\``,
1231
+ }],
1232
+ };
1233
+ }
1234
+ // Call RPC endpoint phase.create
1235
+ const newPhase = await context.hailer.request('phase.create', [workflowId]);
1236
+ logger.debug('Workflow phase created', {
1237
+ workflowId,
1238
+ phaseId: newPhase?._id
1239
+ });
1240
+ let responseText = `✅ **Phase Created Successfully**\n\n`;
1241
+ responseText += `**Workflow ID:** \`${workflowId}\`\n`;
1242
+ responseText += `**New Phase ID:** \`${newPhase._id}\`\n`;
1243
+ responseText += `**Name:** ${newPhase.name}\n\n`;
1244
+ responseText += `💡 **Next Steps:**\n`;
1245
+ responseText += `- Rename: \`update_workflow_structure({ workflowId: "${workflowId}", action: "update_phase", ` +
1246
+ `phaseId: "${newPhase._id}", phase: { name: "Your Phase Name" } })\`\n`;
1247
+ responseText += `- Verify: \`describe_workflows({ workflowId: "${workflowId}", include: ["phases"] })\`\n`;
1248
+ return {
1249
+ content: [{
1250
+ type: 'text',
1251
+ text: responseText,
1252
+ }],
1253
+ };
1254
+ }
1255
+ catch (error) {
1256
+ if (!request_logger_1.RequestLogger.getCurrent()) {
1257
+ logger.error('Error creating workflow phase', error);
1258
+ }
1259
+ const errorMessage = error instanceof Error ? error.message : String(error);
1260
+ if (errorMessage.includes('Permission') || errorMessage.includes('permission')) {
1261
+ return {
1262
+ content: [{
1263
+ type: 'text',
1264
+ text: `❌ **Permission Denied**\n\nYou must be a workflow administrator to create phases.\n\n**Error:** ${errorMessage}`,
1265
+ }],
1266
+ };
1267
+ }
1268
+ return {
1269
+ content: [{
1270
+ type: 'text',
1271
+ text: `❌ **Error creating phase**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workflow administrator\n- Workflow ID must be valid (24 characters)\n- Use \`describe_workflows\` to find workflow IDs`,
1272
+ }],
1273
+ };
1274
+ }
1275
+ }
1276
+ /** update_phase action — former update_workflow_phase body */
1277
+ async function executeUpdatePhase(workflowId, phaseId, phase, context) {
1278
+ logger.debug('Updating workflow phase', {
1279
+ workflowId,
1280
+ phaseId,
1281
+ apiKey: context.apiKey.substring(0, 8) + '...'
1282
+ });
1283
+ try {
1284
+ const workspaceId = context.init.network?._id;
1285
+ const phaseData = phase;
1286
+ const language = 'en'; // Default language
1287
+ logger.debug('Calling RPC phase.update', {
1288
+ workflowId,
1289
+ phaseId,
1290
+ phaseData
1291
+ });
1292
+ // Call RPC endpoint phase.update
1293
+ // Args: [processId, phaseId, phaseSettings, language]
1294
+ await context.hailer.request('phase.update', [
1295
+ workflowId,
1296
+ phaseId,
1297
+ phaseData,
1298
+ language
1299
+ ]);
1300
+ logger.debug('Workflow phase update successful', {
1301
+ workflowId,
1302
+ phaseId
1303
+ });
1304
+ // Build success response
1305
+ let responseText = `✅ **Workflow Phase Updated Successfully**\n\n`;
1306
+ responseText += `**Workflow ID:** \`${workflowId}\`\n`;
1307
+ responseText += `**Phase ID:** \`${phaseId}\`\n`;
1308
+ responseText += `**Workspace:** ${workspaceId}\n\n`;
1309
+ responseText += `**Updated Properties:**\n`;
1310
+ Object.entries(phaseData).forEach(([key, value]) => {
1311
+ const valueStr = typeof value === 'object' ? JSON.stringify(value) : String(value);
1312
+ responseText += `- ${key}: \`${valueStr}\`\n`;
1313
+ });
1314
+ responseText += `\n💡 **Next Steps:**\n`;
1315
+ responseText += `- Use \`describe_workflows\` with include: ['phases'] to verify the phase changes\n`;
1316
+ responseText += `- Phase changes will be immediately visible in the workflow\n`;
1317
+ return {
1318
+ content: [{
1319
+ type: 'text',
1320
+ text: responseText,
1321
+ }],
1322
+ };
1323
+ }
1324
+ catch (error) {
1325
+ if (!request_logger_1.RequestLogger.getCurrent()) {
1326
+ logger.error('Error updating workflow phase', error);
1327
+ }
1328
+ const errorMessage = error instanceof Error ? error.message : String(error);
1329
+ // Handle permission errors
1330
+ if (errorMessage.includes('network admin') || errorMessage.includes('PermissionDenied') || errorMessage.includes('permission')) {
1331
+ return {
1332
+ content: [{
1333
+ type: 'text',
1334
+ text: `❌ **Permission Denied**\n\nYou must be a workspace administrator to update workflow phases.\n\n**Error:** ${errorMessage}`,
1335
+ }],
1336
+ };
1337
+ }
1338
+ // Handle method not found errors
1339
+ if (errorMessage.includes('Method not found')) {
1080
1340
  return {
1081
1341
  content: [{
1082
- type: "text",
1083
- text: `❌ **Error updating workflow field**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workspace administrator\n- Workflow ID and Field ID must be valid\n- Field data must match field type requirements\n- Some field types may have restrictions on updates`,
1342
+ type: 'text',
1343
+ text: `❌ **API Method Not Available**\n\nThe \`process.update_phase\` API method may not be available in this Hailer version.\n\n**Alternative:** Use the Hailer web interface to update phase names manually.\n\n**Error:** ${errorMessage}`,
1084
1344
  }],
1085
1345
  };
1086
1346
  }
1347
+ return {
1348
+ content: [{
1349
+ type: 'text',
1350
+ text: `❌ **Error updating workflow phase**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workspace administrator\n- Workflow ID must be valid (24 characters)\n- Phase ID must exist in the workflow\n- Use \`describe_workflows\` with include: ['phases'] to find phase IDs`,
1351
+ }],
1352
+ };
1353
+ }
1354
+ }
1355
+ exports.updateWorkflowStructureTool = {
1356
+ name: 'update_workflow_structure',
1357
+ group: tool_registry_1.ToolGroup.PLAYGROUND,
1358
+ description: updateWorkflowStructureDescription,
1359
+ schema: updateWorkflowStructureSchema,
1360
+ async execute(args, context) {
1361
+ // SDK redirect applies to update actions only (create actions never redirected)
1362
+ if (args.action === 'update_field' && isSdkProject() && !args.force) {
1363
+ return sdkRedirect('update_workflow_structure', 'npm run fields-push:force', 'workspace/<WorkflowName>_<id>/fields.ts');
1364
+ }
1365
+ if (args.action === 'update_phase' && isSdkProject() && !args.force) {
1366
+ return sdkRedirect('update_workflow_structure', 'npm run phases-push:force', 'workspace/<WorkflowName>_<id>/phases.ts');
1367
+ }
1368
+ if (args.action === 'create_field' && (!args.field?.label || !args.field?.type)) {
1369
+ return structureValidationError("action 'create_field' requires a `field` object with at least `label` and `type`.");
1370
+ }
1371
+ if (args.action === 'create_field') {
1372
+ return executeCreateField(args.workflowId, args.field, context);
1373
+ }
1374
+ if (args.action === 'update_field' && (!args.fieldId || !args.field)) {
1375
+ return structureValidationError("action 'update_field' requires `fieldId` and a `field` object with the properties to change.");
1376
+ }
1377
+ if (args.action === 'update_field') {
1378
+ return executeUpdateField(args.workflowId, args.fieldId, args.field, args.autoGenerateKey ?? true, context);
1379
+ }
1380
+ if (args.action === 'create_phase') {
1381
+ return executeCreatePhase(args.workflowId, context);
1382
+ }
1383
+ if (!args.phaseId || !args.phase) {
1384
+ return structureValidationError("action 'update_phase' requires `phaseId` and a `phase` object (name/description/color).");
1385
+ }
1386
+ return executeUpdatePhase(args.workflowId, args.phaseId, args.phase, context);
1087
1387
  }
1088
1388
  };
1089
1389
  // ============================================================================
@@ -1093,23 +1393,23 @@ const testFunctionFieldDescription = `Test function field code against an activi
1093
1393
  const testFunctionFieldSchema = zod_1.z.object({
1094
1394
  activityId: zod_1.z
1095
1395
  .string()
1096
- .min(1, "Activity ID is required")
1097
- .describe("Activity ID to test the function against (must have dependency field values)"),
1396
+ .min(1, 'Activity ID is required')
1397
+ .describe('Activity ID to test the function against (must have dependency field values)'),
1098
1398
  fieldId: zod_1.z
1099
1399
  .string()
1100
- .min(1, "Field ID is required")
1101
- .describe("Field ID for context and to get field configuration (label, type, etc.)"),
1400
+ .min(1, 'Field ID is required')
1401
+ .describe('Field ID for context and to get field configuration (label, type, etc.)'),
1102
1402
  function: zod_1.z
1103
1403
  .string()
1104
- .min(1, "Function code is required")
1105
- .describe("JavaScript function code to test - access dependencies via dep.variableName"),
1404
+ .min(1, 'Function code is required')
1405
+ .describe('JavaScript function code to test - access dependencies via dep.variableName'),
1106
1406
  functionVariables: zod_1.z
1107
1407
  .record(zod_1.z.object({
1108
1408
  type: zod_1.z.string().describe("Dependency type - use '=' for same-activity field"),
1109
- data: zod_1.z.array(zod_1.z.string()).describe("Array with field ID to depend on")
1409
+ data: zod_1.z.array(zod_1.z.string()).describe('Array with field ID to depend on')
1110
1410
  }))
1111
1411
  .optional()
1112
- .describe("Optional function dependencies - if not provided, reads from field definition"),
1412
+ .describe('Optional function dependencies - if not provided, reads from field definition'),
1113
1413
  });
1114
1414
  exports.testFunctionFieldTool = {
1115
1415
  name: 'test_function_field',
@@ -1127,7 +1427,7 @@ exports.testFunctionFieldTool = {
1127
1427
  if (!activity?.process) {
1128
1428
  return {
1129
1429
  content: [{
1130
- type: "text",
1430
+ type: 'text',
1131
1431
  text: `❌ Could not find activity or workflow for activity ID: ${args.activityId}`
1132
1432
  }],
1133
1433
  };
@@ -1143,7 +1443,7 @@ exports.testFunctionFieldTool = {
1143
1443
  : `Field "${field.label || args.fieldId}" has no function dependencies configured.`;
1144
1444
  return {
1145
1445
  content: [{
1146
- type: "text",
1446
+ type: 'text',
1147
1447
  text: `❌ No function dependencies available.
1148
1448
 
1149
1449
  ${reason}
@@ -1171,7 +1471,7 @@ functionVariables: {
1171
1471
  const cleanMessage = errorMessage.replace(/^(SyntaxError|ReferenceError|TypeError):\s*/, '');
1172
1472
  return {
1173
1473
  content: [{
1174
- type: "text",
1474
+ type: 'text',
1175
1475
  text: `❌ **Function Field Test Failed**
1176
1476
 
1177
1477
  **Error Type:** ${errorType}
@@ -1216,10 +1516,12 @@ functionVariables: {
1216
1516
  const iterations = stats['Iterations Used'];
1217
1517
  if (executionTime !== undefined || iterations !== undefined) {
1218
1518
  text += '\n**⏱️ Execution Statistics:**\n';
1219
- if (executionTime !== undefined)
1519
+ if (executionTime !== undefined) {
1220
1520
  text += `- Execution Time: ${executionTime}ms\n`;
1221
- if (iterations !== undefined)
1521
+ }
1522
+ if (iterations !== undefined) {
1222
1523
  text += `- Iterations: ${iterations}\n`;
1524
+ }
1223
1525
  }
1224
1526
  text += `
1225
1527
  **✅ Next Steps:**
@@ -1228,18 +1530,19 @@ functionVariables: {
1228
1530
  - If you need to modify the function, use \`update_workflow_field\` to save changes
1229
1531
  - Function is working correctly and ready for production use!`;
1230
1532
  return {
1231
- content: [{ type: "text", text }],
1533
+ content: [{ type: 'text', text }],
1232
1534
  };
1233
1535
  }
1234
1536
  catch (error) {
1235
- if (!request_logger_1.RequestLogger.getCurrent())
1236
- logger.error("Error testing function field", error);
1537
+ if (!request_logger_1.RequestLogger.getCurrent()) {
1538
+ logger.error('Error testing function field', error);
1539
+ }
1237
1540
  const errorMessage = error instanceof Error
1238
1541
  ? error.message
1239
1542
  : JSON.stringify(error, null, 2);
1240
1543
  return {
1241
1544
  content: [{
1242
- type: "text",
1545
+ type: 'text',
1243
1546
  text: `❌ **Error Testing Function Field**
1244
1547
 
1245
1548
  ${errorMessage}
@@ -1254,243 +1557,6 @@ ${errorMessage}
1254
1557
  }
1255
1558
  };
1256
1559
  // ============================================================================
1257
- // TOOL 5: LIST WORKFLOWS MINIMAL
1258
- // ============================================================================
1259
- const listWorkflowsMinimalDescription = `Quick list of all workflows - START HERE to find workflow IDs.
1260
-
1261
- **Hailer Concept:** Returns all workflows (processes/boards) with their IDs and names. This is usually your FIRST CALL to discover what's available.
1262
-
1263
- **When to use:** User asks "show my tasks", "what workflows do I have", "find customers" - use this to locate the right workflow ID.
1264
-
1265
- **Returns:** Workflow name, ID, activity count. Use the ID in subsequent calls.
1266
-
1267
- **Typical flow:** list_workflows_minimal → list_workflow_phases → get_workflow_schema → list_activities`;
1268
- const listWorkflowsMinimalSchema = zod_1.z.object({
1269
- workspace: zod_1.z.string().optional().describe("Optional workspace ID or name"),
1270
- limit: zod_1.z.coerce.number().optional().describe("Maximum number of workflows to return"),
1271
- offset: zod_1.z.coerce.number().optional().default(0).describe("Number of workflows to skip (for pagination)"),
1272
- search: zod_1.z.string().optional().describe("Filter workflows by name (case-insensitive partial match)"),
1273
- starredOnly: zod_1.z.coerce.boolean().optional().default(false).describe("Only return starred workflows"),
1274
- });
1275
- exports.listWorkflowsMinimalTool = {
1276
- name: 'list_workflows_minimal',
1277
- group: tool_registry_1.ToolGroup.READ,
1278
- description: listWorkflowsMinimalDescription,
1279
- schema: listWorkflowsMinimalSchema,
1280
- async execute(args, context) {
1281
- logger.debug('Listing workflows (minimal)', {
1282
- apiKey: context.apiKey.substring(0, 8) + '...'
1283
- });
1284
- try {
1285
- // Use cached workflows from context.init (already fetched during initialization)
1286
- let workflows = context.init.processes || [];
1287
- // Filter by workspace if specified
1288
- if (args.workspace) {
1289
- workflows = workflows.filter(w => w.cid === args.workspace);
1290
- }
1291
- // Filter by starred if requested
1292
- if (args.starredOnly) {
1293
- workflows = workflows.filter(w => w.isStarred);
1294
- }
1295
- // Search by name if provided
1296
- if (args.search) {
1297
- const searchLower = args.search.toLowerCase();
1298
- workflows = workflows.filter(w => w.name.toLowerCase().includes(searchLower));
1299
- }
1300
- // Apply pagination
1301
- const offset = args.offset || 0;
1302
- const limit = args.limit;
1303
- const totalCount = workflows.length;
1304
- if (limit) {
1305
- workflows = workflows.slice(offset, offset + limit);
1306
- }
1307
- else if (offset > 0) {
1308
- workflows = workflows.slice(offset);
1309
- }
1310
- // Build minimal response - only id and name
1311
- const minimalWorkflows = workflows.map(w => ({
1312
- id: w._id,
1313
- name: w.name,
1314
- workspaceId: w.cid,
1315
- activityCount: w.createdActivities || 0,
1316
- isStarred: w.isStarred || false
1317
- }));
1318
- let responseText = (isSdkProject() ? SDK_DISCOVERY_HINT : '') + `📋 **Workflows Found**\n\n`;
1319
- responseText += `Total: ${totalCount}\n`;
1320
- responseText += `Showing: ${workflows.length}\n`;
1321
- if (offset > 0)
1322
- responseText += `Offset: ${offset}\n`;
1323
- responseText += `\n`;
1324
- minimalWorkflows.forEach(w => {
1325
- const star = w.isStarred ? '⭐ ' : '';
1326
- responseText += `${star}**${w.name}**\n`;
1327
- responseText += ` ID: \`${w.id}\`\n`;
1328
- responseText += ` Activities: ${w.activityCount}\n\n`;
1329
- });
1330
- responseText += `\n💡 **Next Steps:**\n`;
1331
- responseText += `- Use \`get_workflow_schema\` with workflow ID to see fields\n`;
1332
- responseText += `- Use \`list_workflow_phases\` to see available phases\n`;
1333
- if (limit && (offset + limit) < totalCount) {
1334
- responseText += `- Use \`offset: ${offset + limit}\` to see next page\n`;
1335
- }
1336
- return {
1337
- content: [{
1338
- type: "text",
1339
- text: responseText,
1340
- }],
1341
- };
1342
- }
1343
- catch (error) {
1344
- if (!request_logger_1.RequestLogger.getCurrent())
1345
- logger.error("Error listing workflows (minimal)", error);
1346
- return {
1347
- content: [{
1348
- type: "text",
1349
- text: `❌ Error listing workflows: ${error instanceof Error ? error.message : String(error)}`,
1350
- }],
1351
- };
1352
- }
1353
- }
1354
- };
1355
- // ============================================================================
1356
- // COUNT ACTIVITIES TOOL
1357
- // ============================================================================
1358
- const countActivitiesDescription = `🔢 Count Activities - Get total count of activities in a workflow
1359
-
1360
- **Purpose**: Returns the total number of activities in a specific workflow. Useful for analytics, reporting, and understanding workflow size.
1361
-
1362
- **⚠️ PERFORMANCE NOTICE:**
1363
- - This makes a separate API call per workflow (v3.activity.count)
1364
- - Use \`list_workflows_minimal\` instead for bulk workflow counts (uses cached data from init, zero extra API calls)
1365
- - Only use \`count_activities\` when you need phase-level breakdown or real-time count
1366
-
1367
- **Example**:
1368
- \`\`\`javascript
1369
- count_activities({
1370
- workflowId: "691b136906e6923eac972902"
1371
- })
1372
- \`\`\`
1373
-
1374
- **Response**: Returns count in details object
1375
-
1376
- **Use Cases**:
1377
- - Single workflow activity count
1378
- - Phase-by-phase breakdown (returned data shows counts per phase)
1379
- - Real-time activity count (bypasses cache)
1380
-
1381
- **Tips**:
1382
- - For bulk counts of ALL workflows, use \`list_workflows_minimal\` (free, no API calls)
1383
- - This tool makes 1 API call per workflow
1384
- - Use list_workflows to get workflow IDs`;
1385
- const countActivitiesSchema = zod_1.z.object({
1386
- workflowId: zod_1.z.string().describe("Workflow ID or key"),
1387
- });
1388
- exports.countActivitiesTool = {
1389
- name: 'count_activities',
1390
- group: tool_registry_1.ToolGroup.READ,
1391
- description: countActivitiesDescription,
1392
- schema: countActivitiesSchema,
1393
- async execute(args, context) {
1394
- logger.debug('Counting activities', {
1395
- workflowId: args.workflowId,
1396
- apiKey: context.apiKey.substring(0, 8) + '...'
1397
- });
1398
- try {
1399
- // Get workflow name from cached data
1400
- const workflow = resolveWorkflow(context.init.processes || [], args.workflowId);
1401
- if (!workflow) {
1402
- return {
1403
- content: [{
1404
- type: "text",
1405
- text: `❌ Workflow "${args.workflowId}" not found`,
1406
- }],
1407
- };
1408
- }
1409
- logger.debug('Calling v3.activity.count', {
1410
- workflowId: args.workflowId,
1411
- workflowName: workflow.name
1412
- });
1413
- // Call v3.activity.count endpoint
1414
- // Returns object with phase IDs as keys and counts as values
1415
- const result = await context.hailer.request('v3.activity.count', [args.workflowId]);
1416
- logger.debug('Activity count retrieved', {
1417
- result: JSON.stringify(result)
1418
- });
1419
- // Sum all counts across phases
1420
- const count = Object.values(result).reduce((sum, phaseCount) => sum + phaseCount, 0);
1421
- // Build success response
1422
- let responseText = `🔢 **Activity Count for "${workflow.name}"**\n\n`;
1423
- responseText += `**Workflow ID:** \`${args.workflowId}\`\n`;
1424
- responseText += `**Total Activities:** ${count}\n\n`;
1425
- if (count === 0) {
1426
- responseText += `💡 This workflow has no activities yet. Use \`create_activity\` to add one.\n`;
1427
- }
1428
- else {
1429
- responseText += `💡 **Next Steps:**\n`;
1430
- responseText += `- Use \`list_activities\` to see the activities\n`;
1431
- responseText += `- Use \`get_workflow_schema\` to see workflow structure\n`;
1432
- }
1433
- return {
1434
- content: [{
1435
- type: "text",
1436
- text: responseText,
1437
- }],
1438
- };
1439
- }
1440
- catch (error) {
1441
- if (!request_logger_1.RequestLogger.getCurrent())
1442
- logger.error("Error counting activities", error);
1443
- return {
1444
- content: [{
1445
- type: "text",
1446
- text: `❌ Error counting activities: ${error instanceof Error ? error.message : String(error)}\n\n**Tips:**\n- Check that workflow ID is valid (24 characters)\n- Use \`list_workflows\` to find workflow IDs`,
1447
- }],
1448
- };
1449
- }
1450
- }
1451
- };
1452
- // ============================================================================
1453
- // UPDATE WORKFLOW PHASE
1454
- // ============================================================================
1455
- const updateWorkflowPhaseDescription = `🏷️ Update Workflow Phase - Modify phase name and properties
1456
-
1457
- **What does this do?**
1458
- Updates an existing workflow phase's properties like name, description, and settings.
1459
-
1460
- **Required Parameters**:
1461
- - workflowId: Workflow ID containing the phase
1462
- - phaseId: Phase ID to update
1463
- - phaseData: Properties to update (name, description, etc.)
1464
-
1465
- **Example - Rename phase**:
1466
- \`\`\`javascript
1467
- update_workflow_phase({
1468
- workflowId: "68446dc05b30685f67c6fcd4",
1469
- phaseId: "181",
1470
- phaseData: { name: "Injured" }
1471
- })
1472
- \`\`\`
1473
-
1474
- **Updatable Properties**:
1475
- - name - Phase display name
1476
- - description - Phase description
1477
- - color - Phase color code
1478
-
1479
- **Requirements**:
1480
- - User must be workspace administrator
1481
- `;
1482
- const updateWorkflowPhaseSchema = zod_1.z.object({
1483
- workflowId: zod_1.z.string().describe("The workflow ID or key containing the phase"),
1484
- phaseId: zod_1.z.string().describe("The phase ID or key to update"),
1485
- phaseData: zod_1.z.object({
1486
- name: zod_1.z.string().optional().describe("New phase name"),
1487
- description: zod_1.z.string().optional().describe("New phase description"),
1488
- color: zod_1.z.string().optional().describe("Phase color code"),
1489
- }).passthrough().describe("Phase properties to update"),
1490
- workspaceId: zod_1.z.string().optional().describe("Optional workspace ID - defaults to current workspace"),
1491
- force: zod_1.z.boolean().optional().describe("Override SDK redirect — use API directly even when workspace/ exists"),
1492
- });
1493
- // ============================================================================
1494
1560
  // CORE INIT TOOL - Workspace overview for terminal Claude Code sessions
1495
1561
  // ============================================================================
1496
1562
  const coreInitDescription = `🚀 START HERE - Load workspace context and learn how to use Hailer tools.
@@ -1542,118 +1608,24 @@ exports.coreInitTool = {
1542
1608
  }
1543
1609
  return {
1544
1610
  content: [{
1545
- type: "text",
1611
+ type: 'text',
1546
1612
  text: prefix + overview,
1547
1613
  }],
1548
1614
  };
1549
1615
  }
1550
1616
  catch (error) {
1551
- if (!request_logger_1.RequestLogger.getCurrent())
1552
- logger.error("Failed to generate workspace overview", error);
1617
+ if (!request_logger_1.RequestLogger.getCurrent()) {
1618
+ logger.error('Failed to generate workspace overview', error);
1619
+ }
1553
1620
  return {
1554
1621
  content: [{
1555
- type: "text",
1622
+ type: 'text',
1556
1623
  text: `❌ Failed to load workspace context: ${error instanceof Error ? error.message : String(error)}`,
1557
1624
  }],
1558
1625
  };
1559
1626
  }
1560
1627
  },
1561
1628
  };
1562
- exports.updateWorkflowPhaseTool = {
1563
- name: 'update_workflow_phase',
1564
- group: tool_registry_1.ToolGroup.PLAYGROUND,
1565
- description: updateWorkflowPhaseDescription,
1566
- schema: updateWorkflowPhaseSchema,
1567
- async execute(args, context) {
1568
- if (isSdkProject() && !args.force) {
1569
- return sdkRedirect('update_workflow_phase', 'npm run phases-push:force', 'workspace/<WorkflowName>_<id>/phases.ts');
1570
- }
1571
- logger.debug('Updating workflow phase', {
1572
- workflowId: args.workflowId,
1573
- phaseId: args.phaseId,
1574
- apiKey: context.apiKey.substring(0, 8) + '...'
1575
- });
1576
- try {
1577
- // Get current workspace from cached init data
1578
- let workspaceId = args.workspaceId;
1579
- if (!workspaceId) {
1580
- workspaceId = context.init.network?._id;
1581
- }
1582
- const phaseData = args.phaseData;
1583
- const language = 'en'; // Default language
1584
- logger.debug('Calling REST /phase/update', {
1585
- workflowId: args.workflowId,
1586
- phaseId: args.phaseId,
1587
- phaseData
1588
- });
1589
- // Call REST endpoint /api/phase/update
1590
- // API format: {"0": workflowId, "1": phaseId, "2": phaseSettings, "3": language}
1591
- await context.hailer.callRest({
1592
- operation: 'update_workflow_phase',
1593
- endpoint: '/api/phase/update',
1594
- method: 'POST',
1595
- body: {
1596
- "0": args.workflowId,
1597
- "1": args.phaseId,
1598
- "2": phaseData,
1599
- "3": language
1600
- }
1601
- });
1602
- logger.debug('Workflow phase update successful', {
1603
- workflowId: args.workflowId,
1604
- phaseId: args.phaseId
1605
- });
1606
- // Build success response
1607
- let responseText = `✅ **Workflow Phase Updated Successfully**\n\n`;
1608
- responseText += `**Workflow ID:** \`${args.workflowId}\`\n`;
1609
- responseText += `**Phase ID:** \`${args.phaseId}\`\n`;
1610
- responseText += `**Workspace:** ${workspaceId}\n\n`;
1611
- responseText += `**Updated Properties:**\n`;
1612
- Object.entries(phaseData).forEach(([key, value]) => {
1613
- const valueStr = typeof value === 'object' ? JSON.stringify(value) : String(value);
1614
- responseText += `- ${key}: \`${valueStr}\`\n`;
1615
- });
1616
- responseText += `\n💡 **Next Steps:**\n`;
1617
- responseText += `- Use \`list_workflow_phases\` to verify the phase changes\n`;
1618
- responseText += `- Phase changes will be immediately visible in the workflow\n`;
1619
- return {
1620
- content: [{
1621
- type: "text",
1622
- text: responseText,
1623
- }],
1624
- };
1625
- }
1626
- catch (error) {
1627
- if (!request_logger_1.RequestLogger.getCurrent())
1628
- logger.error("Error updating workflow phase", error);
1629
- const errorMessage = error instanceof Error ? error.message : String(error);
1630
- // Handle permission errors
1631
- if (errorMessage.includes('network admin') || errorMessage.includes('PermissionDenied') || errorMessage.includes('permission')) {
1632
- return {
1633
- content: [{
1634
- type: "text",
1635
- text: `❌ **Permission Denied**\n\nYou must be a workspace administrator to update workflow phases.\n\n**Error:** ${errorMessage}`,
1636
- }],
1637
- };
1638
- }
1639
- // Handle method not found errors
1640
- if (errorMessage.includes('Method not found')) {
1641
- return {
1642
- content: [{
1643
- type: "text",
1644
- text: `❌ **API Method Not Available**\n\nThe \`process.update_phase\` API method may not be available in this Hailer version.\n\n**Alternative:** Use the Hailer web interface to update phase names manually.\n\n**Error:** ${errorMessage}`,
1645
- }],
1646
- };
1647
- }
1648
- return {
1649
- content: [{
1650
- type: "text",
1651
- text: `❌ **Error updating workflow phase**\n\n**Error:** ${errorMessage}\n\n**Common Issues:**\n- User must be workspace administrator\n- Workflow ID must be valid (24 characters)\n- Phase ID must exist in the workflow\n- Use \`list_workflow_phases\` to find phase IDs`,
1652
- }],
1653
- };
1654
- }
1655
- }
1656
- };
1657
1629
  // ============================================================================
1658
1630
  // AUTO SET KEYS TOOL
1659
1631
  // ============================================================================
@@ -1663,7 +1635,7 @@ exports.autoSetKeysTool = {
1663
1635
  group: tool_registry_1.ToolGroup.PLAYGROUND,
1664
1636
  description: autoSetKeysDescription,
1665
1637
  schema: zod_1.z.object({
1666
- workflowId: zod_1.z.string().describe("Workflow ID or key to set keys on"),
1638
+ workflowId: zod_1.z.string().describe('Workflow ID or key to set keys on'),
1667
1639
  }),
1668
1640
  async execute(args, context) {
1669
1641
  try {
@@ -1704,28 +1676,23 @@ exports.autoSetKeysTool = {
1704
1676
  }
1705
1677
  }
1706
1678
  responseText += `\n💡 You can now use these keys instead of hex IDs in all tools.`;
1707
- return { content: [{ type: "text", text: responseText }] };
1679
+ return { content: [{ type: 'text', text: responseText }] };
1708
1680
  }
1709
1681
  catch (error) {
1710
1682
  const errorMessage = error instanceof Error ? error.message : String(error);
1711
1683
  return {
1712
- content: [{ type: "text", text: `❌ **Error setting keys:** ${errorMessage}` }],
1684
+ content: [{ type: 'text', text: `❌ **Error setting keys:** ${errorMessage}` }],
1713
1685
  };
1714
1686
  }
1715
1687
  }
1716
1688
  };
1717
1689
  /** All workflow tools */
1718
1690
  exports.workflowTools = [
1719
- exports.getWorkflowSchemaTool,
1720
- exports.listWorkflowPhasesTool,
1721
- exports.listWorkflowsTool,
1691
+ exports.describeWorkflowsTool,
1722
1692
  exports.installWorkflowTool,
1723
1693
  exports.removeWorkflowTool,
1724
- exports.updateWorkflowFieldTool,
1725
- exports.updateWorkflowPhaseTool,
1694
+ exports.updateWorkflowStructureTool,
1726
1695
  exports.testFunctionFieldTool,
1727
- exports.listWorkflowsMinimalTool,
1728
- exports.countActivitiesTool,
1729
1696
  exports.coreInitTool,
1730
1697
  exports.autoSetKeysTool,
1731
1698
  ];