@hailer/mcp 1.2.1 → 1.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/agent-hailer-helper.md +118 -0
- package/.claude/commands/debug-squad.md +13 -290
- package/.claude/commands/publish.md +2 -2
- package/.claude/commands/review-squad.md +17 -139
- package/.claude/skills/create-and-publish-app/SKILL.md +133 -143
- package/.claude/skills/hailer-app-builder/SKILL.md +29 -2
- package/.claude/skills/hailer-ui-guide/SKILL.md +265 -0
- package/.env.example +50 -1
- package/CLAUDE.md +141 -10
- package/dist/app-prep.d.ts +27 -0
- package/dist/app-prep.d.ts.map +1 -0
- package/dist/app-prep.js +94 -0
- package/dist/app-prep.js.map +1 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +3 -0
- package/dist/app.js.map +1 -1
- package/dist/bot/bot-manager.d.ts +9 -6
- package/dist/bot/bot-manager.d.ts.map +1 -1
- package/dist/bot/bot-manager.js +142 -31
- package/dist/bot/bot-manager.js.map +1 -1
- package/dist/bot/bot.d.ts +61 -16
- package/dist/bot/bot.d.ts.map +1 -1
- package/dist/bot/bot.js +927 -151
- package/dist/bot/bot.js.map +1 -1
- package/dist/bot/operation-logger.d.ts.map +1 -1
- package/dist/bot/operation-logger.js +24 -12
- package/dist/bot/operation-logger.js.map +1 -1
- package/dist/bot/services/bot-permissions.d.ts +37 -5
- package/dist/bot/services/bot-permissions.d.ts.map +1 -1
- package/dist/bot/services/bot-permissions.js +159 -35
- package/dist/bot/services/bot-permissions.js.map +1 -1
- package/dist/bot/services/conversation-manager.d.ts +23 -23
- package/dist/bot/services/conversation-manager.d.ts.map +1 -1
- package/dist/bot/services/conversation-manager.js +52 -49
- package/dist/bot/services/conversation-manager.js.map +1 -1
- package/dist/bot/services/helper-prompt.d.ts +8 -0
- package/dist/bot/services/helper-prompt.d.ts.map +1 -0
- package/dist/bot/services/helper-prompt.js +177 -0
- package/dist/bot/services/helper-prompt.js.map +1 -0
- package/dist/bot/services/message-classifier.d.ts +16 -16
- package/dist/bot/services/message-classifier.d.ts.map +1 -1
- package/dist/bot/services/message-classifier.js +55 -49
- package/dist/bot/services/message-classifier.js.map +1 -1
- package/dist/bot/services/message-formatter.d.ts +47 -38
- package/dist/bot/services/message-formatter.d.ts.map +1 -1
- package/dist/bot/services/message-formatter.js +99 -80
- package/dist/bot/services/message-formatter.js.map +1 -1
- package/dist/bot/services/permission-guard.d.ts.map +1 -1
- package/dist/bot/services/permission-guard.js +20 -10
- package/dist/bot/services/permission-guard.js.map +1 -1
- package/dist/bot/services/signal-router.d.ts.map +1 -1
- package/dist/bot/services/signal-router.js +11 -6
- package/dist/bot/services/signal-router.js.map +1 -1
- package/dist/bot/services/system-prompt.d.ts +14 -0
- package/dist/bot/services/system-prompt.d.ts.map +1 -1
- package/dist/bot/services/system-prompt.js +181 -4
- package/dist/bot/services/system-prompt.js.map +1 -1
- package/dist/bot/services/token-billing.d.ts +23 -23
- package/dist/bot/services/token-billing.d.ts.map +1 -1
- package/dist/bot/services/token-billing.js +51 -36
- package/dist/bot/services/token-billing.js.map +1 -1
- package/dist/bot/services/types.d.ts +3 -1
- package/dist/bot/services/types.d.ts.map +1 -1
- package/dist/bot/services/typing-indicator.d.ts +8 -8
- package/dist/bot/services/typing-indicator.d.ts.map +1 -1
- package/dist/bot/services/typing-indicator.js +12 -10
- package/dist/bot/services/typing-indicator.js.map +1 -1
- package/dist/bot/services/workspace-refresh.d.ts +3 -3
- package/dist/bot/services/workspace-refresh.d.ts.map +1 -1
- package/dist/bot/services/workspace-refresh.js +23 -13
- package/dist/bot/services/workspace-refresh.js.map +1 -1
- package/dist/bot/tool-executor.d.ts +10 -6
- package/dist/bot/tool-executor.d.ts.map +1 -1
- package/dist/bot/tool-executor.js +12 -6
- package/dist/bot/tool-executor.js.map +1 -1
- package/dist/bot/workspace-overview.d.ts.map +1 -1
- package/dist/bot/workspace-overview.js +6 -3
- package/dist/bot/workspace-overview.js.map +1 -1
- package/dist/bot-config/activity-error.d.ts +47 -0
- package/dist/bot-config/activity-error.d.ts.map +1 -0
- package/dist/bot-config/activity-error.js +67 -0
- package/dist/bot-config/activity-error.js.map +1 -0
- package/dist/bot-config/context.d.ts +4 -4
- package/dist/bot-config/context.d.ts.map +1 -1
- package/dist/bot-config/context.js +18 -14
- package/dist/bot-config/context.js.map +1 -1
- package/dist/bot-config/events.d.ts +45 -0
- package/dist/bot-config/events.d.ts.map +1 -0
- package/dist/bot-config/events.js +51 -0
- package/dist/bot-config/events.js.map +1 -0
- package/dist/bot-config/index.d.ts +3 -0
- package/dist/bot-config/index.d.ts.map +1 -1
- package/dist/bot-config/index.js +8 -1
- package/dist/bot-config/index.js.map +1 -1
- package/dist/bot-config/loader.d.ts +3 -0
- package/dist/bot-config/loader.d.ts.map +1 -1
- package/dist/bot-config/loader.js +45 -20
- package/dist/bot-config/loader.js.map +1 -1
- package/dist/bot-config/persistence.js.map +1 -1
- package/dist/bot-config/reconciler.d.ts +11 -0
- package/dist/bot-config/reconciler.d.ts.map +1 -0
- package/dist/bot-config/reconciler.js +121 -0
- package/dist/bot-config/reconciler.js.map +1 -0
- package/dist/bot-config/state.d.ts.map +1 -1
- package/dist/bot-config/state.js.map +1 -1
- package/dist/bot-config/types.d.ts +32 -0
- package/dist/bot-config/types.d.ts.map +1 -1
- package/dist/bot-config/webhooks.d.ts.map +1 -1
- package/dist/bot-config/webhooks.js.map +1 -1
- package/dist/bot-config/workflow-installer.d.ts +37 -0
- package/dist/bot-config/workflow-installer.d.ts.map +1 -0
- package/dist/bot-config/workflow-installer.js +346 -0
- package/dist/bot-config/workflow-installer.js.map +1 -0
- package/dist/cli.d.ts +4 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +92 -11
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +23 -19
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +65 -27
- package/dist/config.js.map +1 -1
- package/dist/core.d.ts +6 -4
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +11 -16
- package/dist/core.js.map +1 -1
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +7 -4
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/request-logger.d.ts +19 -19
- package/dist/lib/request-logger.d.ts.map +1 -1
- package/dist/lib/request-logger.js +19 -19
- package/dist/lib/request-logger.js.map +1 -1
- package/dist/mcp/UserContextCache.d.ts +28 -22
- package/dist/mcp/UserContextCache.d.ts.map +1 -1
- package/dist/mcp/UserContextCache.js +23 -23
- package/dist/mcp/UserContextCache.js.map +1 -1
- package/dist/mcp/auth.js.map +1 -1
- package/dist/mcp/hailer-clients.d.ts +5 -4
- package/dist/mcp/hailer-clients.d.ts.map +1 -1
- package/dist/mcp/hailer-clients.js +83 -34
- package/dist/mcp/hailer-clients.js.map +1 -1
- package/dist/mcp/hailer-rpc.d.ts +40 -0
- package/dist/mcp/hailer-rpc.d.ts.map +1 -0
- package/dist/mcp/hailer-rpc.js +43 -0
- package/dist/mcp/hailer-rpc.js.map +1 -0
- package/dist/mcp/publish-auth-injector.d.ts +22 -0
- package/dist/mcp/publish-auth-injector.d.ts.map +1 -0
- package/dist/mcp/publish-auth-injector.js +100 -0
- package/dist/mcp/publish-auth-injector.js.map +1 -0
- package/dist/mcp/session-store.d.ts +16 -16
- package/dist/mcp/session-store.d.ts.map +1 -1
- package/dist/mcp/session-store.js +16 -16
- package/dist/mcp/session-store.js.map +1 -1
- package/dist/mcp/tool-profiles.d.ts +69 -0
- package/dist/mcp/tool-profiles.d.ts.map +1 -0
- package/dist/mcp/tool-profiles.js +184 -0
- package/dist/mcp/tool-profiles.js.map +1 -0
- package/dist/mcp/tool-registry.d.ts +16 -0
- package/dist/mcp/tool-registry.d.ts.map +1 -1
- package/dist/mcp/tool-registry.js +91 -39
- package/dist/mcp/tool-registry.js.map +1 -1
- package/dist/mcp/tools/activity.d.ts +2 -0
- package/dist/mcp/tools/activity.d.ts.map +1 -1
- package/dist/mcp/tools/activity.js +575 -218
- package/dist/mcp/tools/activity.js.map +1 -1
- package/dist/mcp/tools/aliases.d.ts +11 -0
- package/dist/mcp/tools/aliases.d.ts.map +1 -0
- package/dist/mcp/tools/aliases.js +182 -0
- package/dist/mcp/tools/aliases.js.map +1 -0
- package/dist/mcp/tools/app-core.d.ts +6 -8
- package/dist/mcp/tools/app-core.d.ts.map +1 -1
- package/dist/mcp/tools/app-core.js +355 -254
- package/dist/mcp/tools/app-core.js.map +1 -1
- package/dist/mcp/tools/app-marketplace.d.ts +12 -16
- package/dist/mcp/tools/app-marketplace.d.ts.map +1 -1
- package/dist/mcp/tools/app-marketplace.js +748 -856
- package/dist/mcp/tools/app-marketplace.js.map +1 -1
- package/dist/mcp/tools/app.d.ts +4 -7
- package/dist/mcp/tools/app.d.ts.map +1 -1
- package/dist/mcp/tools/app.js +4 -7
- package/dist/mcp/tools/app.js.map +1 -1
- package/dist/mcp/tools/bot-self.d.ts +21 -0
- package/dist/mcp/tools/bot-self.d.ts.map +1 -0
- package/dist/mcp/tools/bot-self.js +174 -0
- package/dist/mcp/tools/bot-self.js.map +1 -0
- package/dist/mcp/tools/calendar.d.ts +21 -0
- package/dist/mcp/tools/calendar.d.ts.map +1 -0
- package/dist/mcp/tools/calendar.js +741 -0
- package/dist/mcp/tools/calendar.js.map +1 -0
- package/dist/mcp/tools/company.d.ts.map +1 -1
- package/dist/mcp/tools/company.js +2 -1
- package/dist/mcp/tools/company.js.map +1 -1
- package/dist/mcp/tools/date.js.map +1 -1
- package/dist/mcp/tools/discussion.d.ts +29 -3
- package/dist/mcp/tools/discussion.d.ts.map +1 -1
- package/dist/mcp/tools/discussion.js +419 -534
- package/dist/mcp/tools/discussion.js.map +1 -1
- package/dist/mcp/tools/file.d.ts.map +1 -1
- package/dist/mcp/tools/file.js +18 -16
- package/dist/mcp/tools/file.js.map +1 -1
- package/dist/mcp/tools/index.js +4 -4
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/insight.d.ts +24 -5
- package/dist/mcp/tools/insight.d.ts.map +1 -1
- package/dist/mcp/tools/insight.js +513 -480
- package/dist/mcp/tools/insight.js.map +1 -1
- package/dist/mcp/tools/user.d.ts.map +1 -1
- package/dist/mcp/tools/user.js +15 -13
- package/dist/mcp/tools/user.js.map +1 -1
- package/dist/mcp/tools/workflow-permissions.d.ts +2 -4
- package/dist/mcp/tools/workflow-permissions.d.ts.map +1 -1
- package/dist/mcp/tools/workflow-permissions.js +88 -97
- package/dist/mcp/tools/workflow-permissions.js.map +1 -1
- package/dist/mcp/tools/workflow.d.ts +9 -7
- package/dist/mcp/tools/workflow.d.ts.map +1 -1
- package/dist/mcp/tools/workflow.js +852 -860
- package/dist/mcp/tools/workflow.js.map +1 -1
- package/dist/mcp/utils/api-errors.d.ts.map +1 -1
- package/dist/mcp/utils/api-errors.js +2 -2
- package/dist/mcp/utils/api-errors.js.map +1 -1
- package/dist/mcp/utils/data-transformers.d.ts +0 -3
- package/dist/mcp/utils/data-transformers.d.ts.map +1 -1
- package/dist/mcp/utils/data-transformers.js +32 -5
- package/dist/mcp/utils/data-transformers.js.map +1 -1
- package/dist/mcp/utils/file-upload.d.ts.map +1 -1
- package/dist/mcp/utils/file-upload.js +1 -1
- package/dist/mcp/utils/file-upload.js.map +1 -1
- package/dist/mcp/utils/hailer-api-client.d.ts +81 -81
- package/dist/mcp/utils/hailer-api-client.d.ts.map +1 -1
- package/dist/mcp/utils/hailer-api-client.js +113 -103
- package/dist/mcp/utils/hailer-api-client.js.map +1 -1
- package/dist/mcp/utils/index.d.ts.map +1 -1
- package/dist/mcp/utils/index.js.map +1 -1
- package/dist/mcp/utils/logger.d.ts.map +1 -1
- package/dist/mcp/utils/logger.js.map +1 -1
- package/dist/mcp/utils/response-builder.d.ts.map +1 -1
- package/dist/mcp/utils/response-builder.js +8 -4
- package/dist/mcp/utils/response-builder.js.map +1 -1
- package/dist/mcp/utils/role-utils.d.ts.map +1 -1
- package/dist/mcp/utils/role-utils.js +6 -3
- package/dist/mcp/utils/role-utils.js.map +1 -1
- package/dist/mcp/utils/tool-helpers.d.ts.map +1 -1
- package/dist/mcp/utils/tool-helpers.js +2 -2
- package/dist/mcp/utils/tool-helpers.js.map +1 -1
- package/dist/mcp/utils/types.d.ts +2 -1
- package/dist/mcp/utils/types.d.ts.map +1 -1
- package/dist/mcp/utils/types.js.map +1 -1
- package/dist/mcp/webhook-handler.d.ts +43 -8
- package/dist/mcp/webhook-handler.d.ts.map +1 -1
- package/dist/mcp/webhook-handler.js +861 -116
- package/dist/mcp/webhook-handler.js.map +1 -1
- package/dist/mcp/workspace-admin-store.d.ts +49 -0
- package/dist/mcp/workspace-admin-store.d.ts.map +1 -0
- package/dist/mcp/workspace-admin-store.js +168 -0
- package/dist/mcp/workspace-admin-store.js.map +1 -0
- package/dist/mcp/workspace-cache.d.ts +2 -2
- package/dist/mcp/workspace-cache.d.ts.map +1 -1
- package/dist/mcp/workspace-cache.js +9 -5
- package/dist/mcp/workspace-cache.js.map +1 -1
- package/dist/mcp-server.d.ts +26 -11
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +367 -48
- package/dist/mcp-server.js.map +1 -1
- package/dist/plugins/vipunen/client.d.ts +41 -41
- package/dist/plugins/vipunen/client.d.ts.map +1 -1
- package/dist/plugins/vipunen/client.js +53 -48
- package/dist/plugins/vipunen/client.js.map +1 -1
- package/dist/plugins/vipunen/index.js.map +1 -1
- package/dist/plugins/vipunen/tools.d.ts.map +1 -1
- package/dist/plugins/vipunen/tools.js +6 -3
- package/dist/plugins/vipunen/tools.js.map +1 -1
- package/dist/public-chat/graduate.d.ts +29 -0
- package/dist/public-chat/graduate.d.ts.map +1 -0
- package/dist/public-chat/graduate.js +593 -0
- package/dist/public-chat/graduate.js.map +1 -0
- package/dist/public-chat/handler.d.ts +12 -0
- package/dist/public-chat/handler.d.ts.map +1 -0
- package/dist/public-chat/handler.js +183 -0
- package/dist/public-chat/handler.js.map +1 -0
- package/dist/public-chat/index.d.ts +16 -0
- package/dist/public-chat/index.d.ts.map +1 -0
- package/dist/public-chat/index.js +74 -0
- package/dist/public-chat/index.js.map +1 -0
- package/dist/public-chat/knowledge.d.ts +3 -0
- package/dist/public-chat/knowledge.d.ts.map +1 -0
- package/dist/public-chat/knowledge.js +1340 -0
- package/dist/public-chat/knowledge.js.map +1 -0
- package/dist/public-chat/rate-limit.d.ts +16 -0
- package/dist/public-chat/rate-limit.d.ts.map +1 -0
- package/dist/public-chat/rate-limit.js +51 -0
- package/dist/public-chat/rate-limit.js.map +1 -0
- package/dist/public-chat/session-store.d.ts +41 -0
- package/dist/public-chat/session-store.d.ts.map +1 -0
- package/dist/public-chat/session-store.js +95 -0
- package/dist/public-chat/session-store.js.map +1 -0
- package/dist/public-chat/studio-prewarm.d.ts +61 -0
- package/dist/public-chat/studio-prewarm.d.ts.map +1 -0
- package/dist/public-chat/studio-prewarm.js +162 -0
- package/dist/public-chat/studio-prewarm.js.map +1 -0
- package/dist/public-chat/system-prompt.d.ts +22 -0
- package/dist/public-chat/system-prompt.d.ts.map +1 -0
- package/dist/public-chat/system-prompt.js +435 -0
- package/dist/public-chat/system-prompt.js.map +1 -0
- package/package.json +13 -7
- package/scripts/build-public-chat-knowledge.py +101 -0
- package/scripts/smoke-public-chat-live.ts +148 -0
- package/scripts/smoke-public-chat.ts +110 -0
- package/.claude/CLAUDE.md +0 -126
- package/.claude/commands/app-squad.md +0 -131
- package/.claude/commands/audit-squad.md +0 -158
- package/.claude/commands/cleanup-squad.md +0 -98
- package/.claude/commands/config-squad.md +0 -106
- package/.claude/commands/crud-squad.md +0 -87
- package/.claude/commands/data-squad.md +0 -97
- package/.claude/commands/doc-squad.md +0 -65
- package/.claude/commands/help.md +0 -29
- package/.claude/commands/help:agents.md +0 -182
- package/.claude/commands/help:commands.md +0 -78
- package/.claude/commands/help:faq.md +0 -79
- package/.claude/commands/help:plugins.md +0 -50
- package/.claude/commands/help:skills.md +0 -87
- package/.claude/commands/help:tools.md +0 -75
- package/.claude/commands/hotfix-squad.md +0 -112
- package/.claude/commands/integration-squad.md +0 -82
- package/.claude/commands/janitor-squad.md +0 -167
- package/.claude/commands/onboard-squad.md +0 -130
- package/.claude/commands/swarm.md +0 -210
- package/.claude/commands/tool-builder.md +0 -39
- package/.claude/skills/publish-hailer-app/SKILL.md +0 -280
- package/dist/CLAUDE.md +0 -370
- package/dist/agents/bot-manager.d.ts +0 -48
- package/dist/agents/bot-manager.d.ts.map +0 -1
- package/dist/agents/bot-manager.js +0 -254
- package/dist/agents/bot-manager.js.map +0 -1
- package/dist/agents/bug-fixer/ai.d.ts +0 -80
- package/dist/agents/bug-fixer/ai.d.ts.map +0 -1
- package/dist/agents/bug-fixer/ai.js +0 -466
- package/dist/agents/bug-fixer/ai.js.map +0 -1
- package/dist/agents/bug-fixer/bot.d.ts +0 -92
- package/dist/agents/bug-fixer/bot.d.ts.map +0 -1
- package/dist/agents/bug-fixer/bot.js +0 -687
- package/dist/agents/bug-fixer/bot.js.map +0 -1
- package/dist/agents/bug-fixer/config.d.ts +0 -21
- package/dist/agents/bug-fixer/config.d.ts.map +0 -1
- package/dist/agents/bug-fixer/config.js +0 -218
- package/dist/agents/bug-fixer/config.js.map +0 -1
- package/dist/agents/bug-fixer/files.d.ts +0 -67
- package/dist/agents/bug-fixer/files.d.ts.map +0 -1
- package/dist/agents/bug-fixer/files.js +0 -386
- package/dist/agents/bug-fixer/files.js.map +0 -1
- package/dist/agents/bug-fixer/git.d.ts +0 -48
- package/dist/agents/bug-fixer/git.d.ts.map +0 -1
- package/dist/agents/bug-fixer/git.js +0 -298
- package/dist/agents/bug-fixer/git.js.map +0 -1
- package/dist/agents/bug-fixer/index.d.ts +0 -103
- package/dist/agents/bug-fixer/index.d.ts.map +0 -1
- package/dist/agents/bug-fixer/index.js +0 -262
- package/dist/agents/bug-fixer/index.js.map +0 -1
- package/dist/agents/bug-fixer/lsp.d.ts +0 -113
- package/dist/agents/bug-fixer/lsp.d.ts.map +0 -1
- package/dist/agents/bug-fixer/lsp.js +0 -485
- package/dist/agents/bug-fixer/lsp.js.map +0 -1
- package/dist/agents/bug-fixer/monitor.d.ts +0 -123
- package/dist/agents/bug-fixer/monitor.d.ts.map +0 -1
- package/dist/agents/bug-fixer/monitor.js +0 -629
- package/dist/agents/bug-fixer/monitor.js.map +0 -1
- package/dist/agents/bug-fixer/prompt.d.ts +0 -5
- package/dist/agents/bug-fixer/prompt.d.ts.map +0 -1
- package/dist/agents/bug-fixer/prompt.js +0 -94
- package/dist/agents/bug-fixer/prompt.js.map +0 -1
- package/dist/agents/bug-fixer/registries/pending-classification.d.ts +0 -28
- package/dist/agents/bug-fixer/registries/pending-classification.d.ts.map +0 -1
- package/dist/agents/bug-fixer/registries/pending-classification.js +0 -50
- package/dist/agents/bug-fixer/registries/pending-classification.js.map +0 -1
- package/dist/agents/bug-fixer/registries/pending-fix.d.ts +0 -33
- package/dist/agents/bug-fixer/registries/pending-fix.d.ts.map +0 -1
- package/dist/agents/bug-fixer/registries/pending-fix.js +0 -64
- package/dist/agents/bug-fixer/registries/pending-fix.js.map +0 -1
- package/dist/agents/bug-fixer/registries/pending.d.ts +0 -27
- package/dist/agents/bug-fixer/registries/pending.d.ts.map +0 -1
- package/dist/agents/bug-fixer/registries/pending.js +0 -49
- package/dist/agents/bug-fixer/registries/pending.js.map +0 -1
- package/dist/agents/bug-fixer/specialist-daemon.d.ts +0 -88
- package/dist/agents/bug-fixer/specialist-daemon.d.ts.map +0 -1
- package/dist/agents/bug-fixer/specialist-daemon.js +0 -431
- package/dist/agents/bug-fixer/specialist-daemon.js.map +0 -1
- package/dist/agents/bug-fixer/specialist.d.ts +0 -47
- package/dist/agents/bug-fixer/specialist.d.ts.map +0 -1
- package/dist/agents/bug-fixer/specialist.js +0 -327
- package/dist/agents/bug-fixer/specialist.js.map +0 -1
- package/dist/agents/bug-fixer/types.d.ts +0 -123
- package/dist/agents/bug-fixer/types.d.ts.map +0 -1
- package/dist/agents/bug-fixer/types.js +0 -9
- package/dist/agents/bug-fixer/types.js.map +0 -1
- package/dist/agents/factory.d.ts +0 -172
- package/dist/agents/factory.d.ts.map +0 -1
- package/dist/agents/factory.js +0 -706
- package/dist/agents/factory.js.map +0 -1
- package/dist/agents/hailer-expert/index.d.ts +0 -8
- package/dist/agents/hailer-expert/index.d.ts.map +0 -1
- package/dist/agents/hailer-expert/index.js +0 -14
- package/dist/agents/hailer-expert/index.js.map +0 -1
- package/dist/agents/hal/daemon.d.ts +0 -174
- package/dist/agents/hal/daemon.d.ts.map +0 -1
- package/dist/agents/hal/daemon.js +0 -1385
- package/dist/agents/hal/daemon.js.map +0 -1
- package/dist/agents/hal/definitions.d.ts +0 -42
- package/dist/agents/hal/definitions.d.ts.map +0 -1
- package/dist/agents/hal/definitions.js +0 -300
- package/dist/agents/hal/definitions.js.map +0 -1
- package/dist/agents/hal/index.d.ts +0 -3
- package/dist/agents/hal/index.d.ts.map +0 -1
- package/dist/agents/hal/index.js +0 -8
- package/dist/agents/hal/index.js.map +0 -1
- package/dist/agents/index.d.ts +0 -18
- package/dist/agents/index.d.ts.map +0 -1
- package/dist/agents/index.js +0 -48
- package/dist/agents/index.js.map +0 -1
- package/dist/agents/shared/base.d.ts +0 -253
- package/dist/agents/shared/base.d.ts.map +0 -1
- package/dist/agents/shared/base.js +0 -1122
- package/dist/agents/shared/base.js.map +0 -1
- package/dist/agents/shared/schemas/action-schema.d.ts +0 -62
- package/dist/agents/shared/schemas/action-schema.d.ts.map +0 -1
- package/dist/agents/shared/schemas/action-schema.js +0 -483
- package/dist/agents/shared/schemas/action-schema.js.map +0 -1
- package/dist/agents/shared/services/agent-registry.d.ts +0 -108
- package/dist/agents/shared/services/agent-registry.d.ts.map +0 -1
- package/dist/agents/shared/services/agent-registry.js +0 -469
- package/dist/agents/shared/services/agent-registry.js.map +0 -1
- package/dist/agents/shared/services/conversation-manager.d.ts +0 -57
- package/dist/agents/shared/services/conversation-manager.d.ts.map +0 -1
- package/dist/agents/shared/services/conversation-manager.js +0 -168
- package/dist/agents/shared/services/conversation-manager.js.map +0 -1
- package/dist/agents/shared/services/mcp-client.d.ts +0 -56
- package/dist/agents/shared/services/mcp-client.d.ts.map +0 -1
- package/dist/agents/shared/services/mcp-client.js +0 -124
- package/dist/agents/shared/services/mcp-client.js.map +0 -1
- package/dist/agents/shared/services/message-classifier.d.ts +0 -37
- package/dist/agents/shared/services/message-classifier.d.ts.map +0 -1
- package/dist/agents/shared/services/message-classifier.js +0 -203
- package/dist/agents/shared/services/message-classifier.js.map +0 -1
- package/dist/agents/shared/services/message-formatter.d.ts +0 -89
- package/dist/agents/shared/services/message-formatter.d.ts.map +0 -1
- package/dist/agents/shared/services/message-formatter.js +0 -390
- package/dist/agents/shared/services/message-formatter.js.map +0 -1
- package/dist/agents/shared/services/session-logger.d.ts +0 -162
- package/dist/agents/shared/services/session-logger.d.ts.map +0 -1
- package/dist/agents/shared/services/session-logger.js +0 -724
- package/dist/agents/shared/services/session-logger.js.map +0 -1
- package/dist/agents/shared/services/structured-output-executor.d.ts +0 -88
- package/dist/agents/shared/services/structured-output-executor.d.ts.map +0 -1
- package/dist/agents/shared/services/structured-output-executor.js +0 -296
- package/dist/agents/shared/services/structured-output-executor.js.map +0 -1
- package/dist/agents/shared/services/token-billing.d.ts +0 -72
- package/dist/agents/shared/services/token-billing.d.ts.map +0 -1
- package/dist/agents/shared/services/token-billing.js +0 -198
- package/dist/agents/shared/services/token-billing.js.map +0 -1
- package/dist/agents/shared/services/tool-executor.d.ts +0 -43
- package/dist/agents/shared/services/tool-executor.d.ts.map +0 -1
- package/dist/agents/shared/services/tool-executor.js +0 -175
- package/dist/agents/shared/services/tool-executor.js.map +0 -1
- package/dist/agents/shared/services/typing-indicator.d.ts +0 -24
- package/dist/agents/shared/services/typing-indicator.d.ts.map +0 -1
- package/dist/agents/shared/services/typing-indicator.js +0 -54
- package/dist/agents/shared/services/typing-indicator.js.map +0 -1
- package/dist/agents/shared/services/workspace-schema-cache.d.ts +0 -122
- package/dist/agents/shared/services/workspace-schema-cache.d.ts.map +0 -1
- package/dist/agents/shared/services/workspace-schema-cache.js +0 -507
- package/dist/agents/shared/services/workspace-schema-cache.js.map +0 -1
- package/dist/agents/shared/specialist.d.ts +0 -91
- package/dist/agents/shared/specialist.d.ts.map +0 -1
- package/dist/agents/shared/specialist.js +0 -399
- package/dist/agents/shared/specialist.js.map +0 -1
- package/dist/agents/shared/tool-schema-loader.d.ts +0 -65
- package/dist/agents/shared/tool-schema-loader.d.ts.map +0 -1
- package/dist/agents/shared/tool-schema-loader.js +0 -238
- package/dist/agents/shared/tool-schema-loader.js.map +0 -1
- package/dist/agents/shared/types.d.ts +0 -190
- package/dist/agents/shared/types.d.ts.map +0 -1
- package/dist/agents/shared/types.js +0 -13
- package/dist/agents/shared/types.js.map +0 -1
- package/dist/bot/bot-config.d.ts +0 -37
- package/dist/bot/bot-config.d.ts.map +0 -1
- package/dist/bot/bot-config.js +0 -219
- package/dist/bot/bot-config.js.map +0 -1
- package/dist/bot/services/__tests__/permission-guard.test.d.ts +0 -2
- package/dist/bot/services/__tests__/permission-guard.test.d.ts.map +0 -1
- package/dist/bot/services/__tests__/permission-guard.test.js +0 -357
- package/dist/bot/services/__tests__/permission-guard.test.js.map +0 -1
- package/dist/bot/services/session-logger.d.ts +0 -162
- package/dist/bot/services/session-logger.d.ts.map +0 -1
- package/dist/bot/services/session-logger.js +0 -724
- package/dist/bot/services/session-logger.js.map +0 -1
- package/dist/bot/services/workspace-schema-cache.d.ts +0 -122
- package/dist/bot/services/workspace-schema-cache.d.ts.map +0 -1
- package/dist/bot/services/workspace-schema-cache.js +0 -506
- package/dist/bot/services/workspace-schema-cache.js.map +0 -1
- package/dist/bot-config/tools.d.ts +0 -28
- package/dist/bot-config/tools.d.ts.map +0 -1
- package/dist/bot-config/tools.js +0 -279
- package/dist/bot-config/tools.js.map +0 -1
- package/dist/client/agents/base.d.ts +0 -207
- package/dist/client/agents/base.d.ts.map +0 -1
- package/dist/client/agents/base.js +0 -744
- package/dist/client/agents/base.js.map +0 -1
- package/dist/client/agents/definitions.d.ts +0 -53
- package/dist/client/agents/definitions.d.ts.map +0 -1
- package/dist/client/agents/definitions.js +0 -263
- package/dist/client/agents/definitions.js.map +0 -1
- package/dist/client/agents/orchestrator.d.ts +0 -141
- package/dist/client/agents/orchestrator.d.ts.map +0 -1
- package/dist/client/agents/orchestrator.js +0 -1062
- package/dist/client/agents/orchestrator.js.map +0 -1
- package/dist/client/agents/specialist.d.ts +0 -86
- package/dist/client/agents/specialist.d.ts.map +0 -1
- package/dist/client/agents/specialist.js +0 -340
- package/dist/client/agents/specialist.js.map +0 -1
- package/dist/client/bot-entrypoint.d.ts +0 -7
- package/dist/client/bot-entrypoint.d.ts.map +0 -1
- package/dist/client/bot-entrypoint.js +0 -103
- package/dist/client/bot-entrypoint.js.map +0 -1
- package/dist/client/bot-manager.d.ts +0 -44
- package/dist/client/bot-manager.d.ts.map +0 -1
- package/dist/client/bot-manager.js +0 -173
- package/dist/client/bot-manager.js.map +0 -1
- package/dist/client/bot-runner.d.ts +0 -35
- package/dist/client/bot-runner.d.ts.map +0 -1
- package/dist/client/bot-runner.js +0 -188
- package/dist/client/bot-runner.js.map +0 -1
- package/dist/client/chat-agent-daemon.d.ts +0 -464
- package/dist/client/chat-agent-daemon.d.ts.map +0 -1
- package/dist/client/chat-agent-daemon.js +0 -1774
- package/dist/client/chat-agent-daemon.js.map +0 -1
- package/dist/client/daemon-factory.d.ts +0 -106
- package/dist/client/daemon-factory.d.ts.map +0 -1
- package/dist/client/daemon-factory.js +0 -301
- package/dist/client/daemon-factory.js.map +0 -1
- package/dist/client/factory.d.ts +0 -111
- package/dist/client/factory.d.ts.map +0 -1
- package/dist/client/factory.js +0 -314
- package/dist/client/factory.js.map +0 -1
- package/dist/client/index.d.ts +0 -17
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js +0 -38
- package/dist/client/index.js.map +0 -1
- package/dist/client/multi-bot-manager.d.ts +0 -42
- package/dist/client/multi-bot-manager.d.ts.map +0 -1
- package/dist/client/multi-bot-manager.js +0 -161
- package/dist/client/multi-bot-manager.js.map +0 -1
- package/dist/client/orchestrator-daemon.d.ts +0 -87
- package/dist/client/orchestrator-daemon.d.ts.map +0 -1
- package/dist/client/orchestrator-daemon.js +0 -444
- package/dist/client/orchestrator-daemon.js.map +0 -1
- package/dist/client/server.d.ts +0 -8
- package/dist/client/server.d.ts.map +0 -1
- package/dist/client/server.js +0 -251
- package/dist/client/server.js.map +0 -1
- package/dist/client/services/agent-registry.d.ts +0 -108
- package/dist/client/services/agent-registry.d.ts.map +0 -1
- package/dist/client/services/agent-registry.js +0 -630
- package/dist/client/services/agent-registry.js.map +0 -1
- package/dist/client/services/conversation-manager.d.ts +0 -50
- package/dist/client/services/conversation-manager.d.ts.map +0 -1
- package/dist/client/services/conversation-manager.js +0 -136
- package/dist/client/services/conversation-manager.js.map +0 -1
- package/dist/client/services/mcp-client.d.ts +0 -48
- package/dist/client/services/mcp-client.d.ts.map +0 -1
- package/dist/client/services/mcp-client.js +0 -105
- package/dist/client/services/mcp-client.js.map +0 -1
- package/dist/client/services/message-classifier.d.ts +0 -37
- package/dist/client/services/message-classifier.d.ts.map +0 -1
- package/dist/client/services/message-classifier.js +0 -187
- package/dist/client/services/message-classifier.js.map +0 -1
- package/dist/client/services/message-formatter.d.ts +0 -84
- package/dist/client/services/message-formatter.d.ts.map +0 -1
- package/dist/client/services/message-formatter.js +0 -353
- package/dist/client/services/message-formatter.js.map +0 -1
- package/dist/client/services/session-logger.d.ts +0 -106
- package/dist/client/services/session-logger.d.ts.map +0 -1
- package/dist/client/services/session-logger.js +0 -446
- package/dist/client/services/session-logger.js.map +0 -1
- package/dist/client/services/tool-executor.d.ts +0 -41
- package/dist/client/services/tool-executor.d.ts.map +0 -1
- package/dist/client/services/tool-executor.js +0 -169
- package/dist/client/services/tool-executor.js.map +0 -1
- package/dist/client/services/workspace-schema-cache.d.ts +0 -149
- package/dist/client/services/workspace-schema-cache.d.ts.map +0 -1
- package/dist/client/services/workspace-schema-cache.js +0 -732
- package/dist/client/services/workspace-schema-cache.js.map +0 -1
- package/dist/client/specialist-daemon.d.ts +0 -77
- package/dist/client/specialist-daemon.d.ts.map +0 -1
- package/dist/client/specialist-daemon.js +0 -197
- package/dist/client/specialist-daemon.js.map +0 -1
- package/dist/client/specialists.d.ts +0 -53
- package/dist/client/specialists.d.ts.map +0 -1
- package/dist/client/specialists.js +0 -178
- package/dist/client/specialists.js.map +0 -1
- package/dist/client/tool-schema-loader.d.ts +0 -62
- package/dist/client/tool-schema-loader.d.ts.map +0 -1
- package/dist/client/tool-schema-loader.js +0 -232
- package/dist/client/tool-schema-loader.js.map +0 -1
- package/dist/client/types.d.ts +0 -327
- package/dist/client/types.d.ts.map +0 -1
- package/dist/client/types.js +0 -121
- package/dist/client/types.js.map +0 -1
- package/dist/commands/seed-config.d.ts +0 -9
- package/dist/commands/seed-config.d.ts.map +0 -1
- package/dist/commands/seed-config.js +0 -377
- package/dist/commands/seed-config.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -11
- package/dist/commands/setup.d.ts.map +0 -1
- package/dist/commands/setup.js +0 -320
- package/dist/commands/setup.js.map +0 -1
- package/dist/lib/discussion-lock.d.ts +0 -42
- package/dist/lib/discussion-lock.d.ts.map +0 -1
- package/dist/lib/discussion-lock.js +0 -110
- package/dist/lib/discussion-lock.js.map +0 -1
- package/dist/mcp/signal-handler.d.ts +0 -82
- package/dist/mcp/signal-handler.d.ts.map +0 -1
- package/dist/mcp/signal-handler.js +0 -406
- package/dist/mcp/signal-handler.js.map +0 -1
- package/dist/mcp/tools/__tests__/discussion-forward.test.d.ts +0 -2
- package/dist/mcp/tools/__tests__/discussion-forward.test.d.ts.map +0 -1
- package/dist/mcp/tools/__tests__/discussion-forward.test.js +0 -218
- package/dist/mcp/tools/__tests__/discussion-forward.test.js.map +0 -1
- package/dist/mcp/tools/app-member.d.ts +0 -14
- package/dist/mcp/tools/app-member.d.ts.map +0 -1
- package/dist/mcp/tools/app-member.js +0 -195
- package/dist/mcp/tools/app-member.js.map +0 -1
- package/dist/mcp/tools/app-scaffold.d.ts +0 -14
- package/dist/mcp/tools/app-scaffold.d.ts.map +0 -1
- package/dist/mcp/tools/app-scaffold.js +0 -581
- package/dist/mcp/tools/app-scaffold.js.map +0 -1
- package/dist/mcp/tools/bot-config/constants.d.ts +0 -23
- package/dist/mcp/tools/bot-config/constants.d.ts.map +0 -1
- package/dist/mcp/tools/bot-config/constants.js +0 -94
- package/dist/mcp/tools/bot-config/constants.js.map +0 -1
- package/dist/mcp/tools/bot-config/core.d.ts +0 -253
- package/dist/mcp/tools/bot-config/core.d.ts.map +0 -1
- package/dist/mcp/tools/bot-config/core.js +0 -2456
- package/dist/mcp/tools/bot-config/core.js.map +0 -1
- package/dist/mcp/tools/bot-config/index.d.ts +0 -10
- package/dist/mcp/tools/bot-config/index.d.ts.map +0 -1
- package/dist/mcp/tools/bot-config/index.js +0 -59
- package/dist/mcp/tools/bot-config/index.js.map +0 -1
- package/dist/mcp/tools/bot-config/tools.d.ts +0 -7
- package/dist/mcp/tools/bot-config/tools.d.ts.map +0 -1
- package/dist/mcp/tools/bot-config/tools.js +0 -15
- package/dist/mcp/tools/bot-config/tools.js.map +0 -1
- package/dist/mcp/tools/bot-config/types.d.ts +0 -50
- package/dist/mcp/tools/bot-config/types.d.ts.map +0 -1
- package/dist/mcp/tools/bot-config/types.js +0 -6
- package/dist/mcp/tools/bot-config/types.js.map +0 -1
- package/dist/mcp/tools/bug-fixer-tools.d.ts +0 -45
- package/dist/mcp/tools/bug-fixer-tools.d.ts.map +0 -1
- package/dist/mcp/tools/bug-fixer-tools.js +0 -1096
- package/dist/mcp/tools/bug-fixer-tools.js.map +0 -1
- package/dist/mcp/tools/document.d.ts +0 -11
- package/dist/mcp/tools/document.d.ts.map +0 -1
- package/dist/mcp/tools/document.js +0 -741
- package/dist/mcp/tools/document.js.map +0 -1
- package/dist/mcp/tools/investigate.d.ts +0 -9
- package/dist/mcp/tools/investigate.d.ts.map +0 -1
- package/dist/mcp/tools/investigate.js +0 -254
- package/dist/mcp/tools/investigate.js.map +0 -1
- package/dist/mcp/utils/pagination.d.ts +0 -40
- package/dist/mcp/utils/pagination.d.ts.map +0 -1
- package/dist/mcp/utils/pagination.js +0 -55
- package/dist/mcp/utils/pagination.js.map +0 -1
- package/dist/modules/bug-reports/bug-config.d.ts +0 -25
- package/dist/modules/bug-reports/bug-config.d.ts.map +0 -1
- package/dist/modules/bug-reports/bug-config.js +0 -187
- package/dist/modules/bug-reports/bug-config.js.map +0 -1
- package/dist/modules/bug-reports/bug-monitor.d.ts +0 -108
- package/dist/modules/bug-reports/bug-monitor.d.ts.map +0 -1
- package/dist/modules/bug-reports/bug-monitor.js +0 -510
- package/dist/modules/bug-reports/bug-monitor.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-agent.d.ts +0 -58
- package/dist/modules/bug-reports/giuseppe-agent.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-agent.js +0 -467
- package/dist/modules/bug-reports/giuseppe-agent.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-ai.d.ts +0 -83
- package/dist/modules/bug-reports/giuseppe-ai.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-ai.js +0 -466
- package/dist/modules/bug-reports/giuseppe-ai.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-bot.d.ts +0 -110
- package/dist/modules/bug-reports/giuseppe-bot.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-bot.js +0 -804
- package/dist/modules/bug-reports/giuseppe-bot.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-daemon.d.ts +0 -80
- package/dist/modules/bug-reports/giuseppe-daemon.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-daemon.js +0 -617
- package/dist/modules/bug-reports/giuseppe-daemon.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-files.d.ts +0 -64
- package/dist/modules/bug-reports/giuseppe-files.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-files.js +0 -375
- package/dist/modules/bug-reports/giuseppe-files.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-git.d.ts +0 -48
- package/dist/modules/bug-reports/giuseppe-git.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-git.js +0 -298
- package/dist/modules/bug-reports/giuseppe-git.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-lsp.d.ts +0 -113
- package/dist/modules/bug-reports/giuseppe-lsp.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-lsp.js +0 -485
- package/dist/modules/bug-reports/giuseppe-lsp.js.map +0 -1
- package/dist/modules/bug-reports/giuseppe-prompt.d.ts +0 -5
- package/dist/modules/bug-reports/giuseppe-prompt.d.ts.map +0 -1
- package/dist/modules/bug-reports/giuseppe-prompt.js +0 -94
- package/dist/modules/bug-reports/giuseppe-prompt.js.map +0 -1
- package/dist/modules/bug-reports/index.d.ts +0 -77
- package/dist/modules/bug-reports/index.d.ts.map +0 -1
- package/dist/modules/bug-reports/index.js +0 -215
- package/dist/modules/bug-reports/index.js.map +0 -1
- package/dist/modules/bug-reports/pending-classification-registry.d.ts +0 -28
- package/dist/modules/bug-reports/pending-classification-registry.d.ts.map +0 -1
- package/dist/modules/bug-reports/pending-classification-registry.js +0 -50
- package/dist/modules/bug-reports/pending-classification-registry.js.map +0 -1
- package/dist/modules/bug-reports/pending-fix-registry.d.ts +0 -30
- package/dist/modules/bug-reports/pending-fix-registry.d.ts.map +0 -1
- package/dist/modules/bug-reports/pending-fix-registry.js +0 -42
- package/dist/modules/bug-reports/pending-fix-registry.js.map +0 -1
- package/dist/modules/bug-reports/pending-registry.d.ts +0 -27
- package/dist/modules/bug-reports/pending-registry.d.ts.map +0 -1
- package/dist/modules/bug-reports/pending-registry.js +0 -49
- package/dist/modules/bug-reports/pending-registry.js.map +0 -1
- package/dist/modules/bug-reports/types.d.ts +0 -123
- package/dist/modules/bug-reports/types.d.ts.map +0 -1
- package/dist/modules/bug-reports/types.js +0 -9
- package/dist/modules/bug-reports/types.js.map +0 -1
- package/dist/plugins/bug-fixer/index.d.ts +0 -2
- package/dist/plugins/bug-fixer/index.d.ts.map +0 -1
- package/dist/plugins/bug-fixer/index.js +0 -18
- package/dist/plugins/bug-fixer/index.js.map +0 -1
- package/dist/plugins/bug-fixer/tools.d.ts +0 -45
- package/dist/plugins/bug-fixer/tools.d.ts.map +0 -1
- package/dist/plugins/bug-fixer/tools.js +0 -1096
- package/dist/plugins/bug-fixer/tools.js.map +0 -1
- package/dist/plugins/vipunen/__tests__/tools.test.d.ts +0 -10
- package/dist/plugins/vipunen/__tests__/tools.test.d.ts.map +0 -1
- package/dist/plugins/vipunen/__tests__/tools.test.js +0 -646
- package/dist/plugins/vipunen/__tests__/tools.test.js.map +0 -1
- package/dist/routes/agents.d.ts +0 -44
- package/dist/routes/agents.d.ts.map +0 -1
- package/dist/routes/agents.js +0 -311
- package/dist/routes/agents.js.map +0 -1
- package/dist/services/agent-credential-store.d.ts +0 -73
- package/dist/services/agent-credential-store.d.ts.map +0 -1
- package/dist/services/agent-credential-store.js +0 -212
- package/dist/services/agent-credential-store.js.map +0 -1
- package/dist/stdio-server.d.ts +0 -14
- package/dist/stdio-server.d.ts.map +0 -1
- package/dist/stdio-server.js +0 -101
- package/dist/stdio-server.js.map +0 -1
- package/dist/workspace/context.d.ts +0 -148
- package/dist/workspace/context.d.ts.map +0 -1
- package/dist/workspace/context.js +0 -339
- package/dist/workspace/context.js.map +0 -1
- package/dist/workspace/credentials.d.ts +0 -55
- package/dist/workspace/credentials.d.ts.map +0 -1
- package/dist/workspace/credentials.js +0 -239
- package/dist/workspace/credentials.js.map +0 -1
- package/dist/workspace/index.d.ts +0 -21
- package/dist/workspace/index.d.ts.map +0 -1
- package/dist/workspace/index.js +0 -45
- package/dist/workspace/index.js.map +0 -1
- package/dist/workspace/loader.d.ts +0 -27
- package/dist/workspace/loader.d.ts.map +0 -1
- package/dist/workspace/loader.js +0 -222
- package/dist/workspace/loader.js.map +0 -1
- package/dist/workspace/schema.d.ts +0 -37
- package/dist/workspace/schema.d.ts.map +0 -1
- package/dist/workspace/schema.js +0 -192
- 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.
|
|
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:
|
|
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
|
|
192
|
+
// READ TOOLS - Workflow Discovery (describe_workflows)
|
|
181
193
|
// ============================================================================
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
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
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
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
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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
|
-
|
|
393
|
-
|
|
394
|
-
|
|
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
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
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:
|
|
417
|
-
schema:
|
|
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('
|
|
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
|
-
//
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
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
|
|
436
|
-
|
|
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
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
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
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
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(
|
|
478
|
+
if (!request_logger_1.RequestLogger.getCurrent()) {
|
|
479
|
+
logger.error('Failed to describe workflows', error);
|
|
480
|
+
}
|
|
505
481
|
return {
|
|
506
482
|
content: [{
|
|
507
|
-
type:
|
|
508
|
-
text: `❌
|
|
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(
|
|
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}$/,
|
|
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(
|
|
536
|
-
description: zod_1.z.string().optional().describe(
|
|
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(
|
|
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(
|
|
545
|
-
key: zod_1.z.string().optional().describe(
|
|
546
|
-
required: zod_1.z.boolean().optional().describe(
|
|
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(
|
|
549
|
-
unit: zod_1.z.string().optional().describe(
|
|
550
|
-
description: zod_1.z.string().optional().describe(
|
|
551
|
-
editable: zod_1.z.boolean().optional().describe(
|
|
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:
|
|
555
|
-
.describe(
|
|
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(
|
|
559
|
-
isInitial: zod_1.z.boolean().optional().describe(
|
|
560
|
-
fields: zod_1.z.array(zod_1.z.string()).optional().describe(
|
|
561
|
-
description: zod_1.z.string().optional().describe(
|
|
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:
|
|
565
|
-
.describe(
|
|
566
|
-
fieldsOrder: zod_1.z.array(zod_1.z.string()).optional().describe(
|
|
567
|
-
phasesOrder: zod_1.z.array(zod_1.z.string()).optional().describe(
|
|
568
|
-
enableMessenger: zod_1.z.boolean().optional().describe(
|
|
569
|
-
enableLinkedAnnouncements: zod_1.z.boolean().optional().describe(
|
|
570
|
-
defaultView: zod_1.z.enum(['timeline', 'table', 'kanban', 'calendar', 'map']).optional().describe(
|
|
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,
|
|
573
|
-
.max(100,
|
|
574
|
-
.describe(
|
|
575
|
-
force: zod_1.z.boolean().optional().describe(
|
|
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:
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
796
|
+
}
|
|
797
|
+
for (const [, key] of Object.entries(kr.phases)) {
|
|
755
798
|
responseText += `- Phase: \`${key}\`\n`;
|
|
756
|
-
|
|
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
|
-
|
|
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:
|
|
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(
|
|
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:
|
|
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:
|
|
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,
|
|
816
|
-
.describe(
|
|
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(
|
|
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(
|
|
872
|
+
.describe('First confirmation - must be true to proceed'),
|
|
825
873
|
secondConfirmed: zod_1.z
|
|
826
874
|
.boolean()
|
|
827
875
|
.optional()
|
|
828
|
-
.describe(
|
|
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:
|
|
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 (\`
|
|
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:
|
|
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 \`
|
|
962
|
+
responseText += `💡 Use \`describe_workflows\` to see remaining workflows in the workspace.`;
|
|
912
963
|
return {
|
|
913
964
|
content: [{
|
|
914
|
-
type:
|
|
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(
|
|
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:
|
|
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:
|
|
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 \`
|
|
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:
|
|
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
|
|
1003
|
+
// TOOL 3: UPDATE WORKFLOW STRUCTURE (create/update fields and phases)
|
|
952
1004
|
// ============================================================================
|
|
953
|
-
const
|
|
954
|
-
const
|
|
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,
|
|
958
|
-
.describe(
|
|
959
|
-
|
|
960
|
-
.
|
|
961
|
-
.
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
.describe(
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
.
|
|
972
|
-
.
|
|
973
|
-
.optional()
|
|
974
|
-
.describe(
|
|
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
|
-
.
|
|
980
|
-
|
|
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
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
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
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
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
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
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
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
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:
|
|
1054
|
-
text:
|
|
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
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
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:
|
|
1083
|
-
text: `❌ **
|
|
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,
|
|
1097
|
-
.describe(
|
|
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,
|
|
1101
|
-
.describe(
|
|
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,
|
|
1105
|
-
.describe(
|
|
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(
|
|
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(
|
|
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:
|
|
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:
|
|
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:
|
|
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 \`
|
|
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
|
-
|
|
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 \`
|
|
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:
|
|
1558
|
+
content: [{ type: 'text', text }],
|
|
1232
1559
|
};
|
|
1233
1560
|
}
|
|
1234
1561
|
catch (error) {
|
|
1235
|
-
if (!request_logger_1.RequestLogger.getCurrent())
|
|
1236
|
-
logger.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:
|
|
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:** \`
|
|
1508
|
-
**Step 2 - Get phases:** \`
|
|
1509
|
-
**Step 3 - Get fields:** \`
|
|
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,
|
|
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:
|
|
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(
|
|
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:
|
|
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(
|
|
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:
|
|
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:
|
|
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.
|
|
1720
|
-
exports.listWorkflowPhasesTool,
|
|
1721
|
-
exports.listWorkflowsTool,
|
|
1716
|
+
exports.describeWorkflowsTool,
|
|
1722
1717
|
exports.installWorkflowTool,
|
|
1723
1718
|
exports.removeWorkflowTool,
|
|
1724
|
-
exports.
|
|
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
|
];
|