@hailer/mcp 1.2.0 → 1.3.9

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