@hailer/mcp 1.1.16 → 1.1.17-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/CLAUDE.md +117 -320
- package/.claude/commands/app-squad.md +86 -90
- package/.claude/commands/audit-squad.md +19 -19
- package/.claude/commands/autoplan.md +3 -3
- package/.claude/commands/cleanup-squad.md +16 -16
- package/.claude/commands/config-squad.md +30 -30
- package/.claude/commands/crud-squad.md +23 -23
- package/.claude/commands/data-squad.md +21 -21
- package/.claude/commands/debug-squad.md +44 -44
- package/.claude/commands/doc-squad.md +16 -16
- package/.claude/commands/help:agents.md +130 -99
- package/.claude/commands/help:commands.md +15 -15
- package/.claude/commands/help:faq.md +17 -17
- package/.claude/commands/help:plugins.md +1 -1
- package/.claude/commands/help:skills.md +18 -24
- package/.claude/commands/hotfix-squad.md +22 -22
- package/.claude/commands/integration-squad.md +22 -22
- package/.claude/commands/janitor-squad.md +31 -31
- package/.claude/commands/learn-auto.md +5 -5
- package/.claude/commands/learn.md +12 -20
- package/.claude/commands/onboard-squad.md +39 -49
- package/.claude/commands/plan-workspace.md +2 -2
- package/.claude/commands/publish.md +32 -37
- package/.claude/commands/review-squad.md +27 -27
- package/.claude/commands/stats.md +26 -12
- package/.claude/commands/swarm.md +25 -25
- package/.claude/skills/chrome-mcp-reference/SKILL.md +5 -0
- package/.claude/skills/hailer-api-client/SKILL.md +55 -16
- package/.claude/skills/hailer-app-builder/SKILL.md +4 -270
- package/.claude/skills/hailer-apps-pictures/SKILL.md +3 -3
- package/.claude/skills/hailer-design-system/SKILL.md +96 -4
- package/.claude/skills/hailer-monolith-automations/SKILL.md +138 -116
- package/.claude/skills/hailer-permissions-system/SKILL.md +6 -9
- package/.claude/skills/hailer-project-protocol/SKILL.md +20 -110
- package/.claude/skills/integration-patterns/SKILL.md +6 -6
- package/.claude/skills/lsp-setup/SKILL.md +8 -9
- package/.claude/skills/sdk-activity-patterns/SKILL.md +238 -0
- package/.claude/skills/{SDK-document-templates → sdk-document-templates}/SKILL.md +13 -340
- package/.claude/skills/{SDK-function-fields → sdk-function-fields}/SKILL.md +8 -40
- package/.claude/skills/{SDK-insight-queries → sdk-insight-queries}/SKILL.md +114 -392
- package/.claude/skills/{SDK-ws-config-skill → sdk-ws-config-skill}/SKILL.md +79 -310
- package/.claude/skills/zapier-hailer-patterns/SKILL.md +84 -361
- package/.opencode/package-lock.json +117 -0
- package/CLAUDE.md +5 -358
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +10 -127
- package/dist/app.js.map +1 -1
- package/dist/bot/bot-manager.d.ts +3 -14
- package/dist/bot/bot-manager.d.ts.map +1 -1
- package/dist/bot/bot-manager.js +13 -4
- package/dist/bot/bot-manager.js.map +1 -1
- package/dist/bot/bot.d.ts +23 -102
- package/dist/bot/bot.d.ts.map +1 -1
- package/dist/bot/bot.js +356 -1212
- package/dist/bot/bot.js.map +1 -1
- package/dist/bot/services/bot-permissions.d.ts +50 -0
- package/dist/bot/services/bot-permissions.d.ts.map +1 -0
- package/dist/bot/services/bot-permissions.js +198 -0
- package/dist/bot/services/bot-permissions.js.map +1 -0
- package/dist/bot/services/index.d.ts +4 -2
- package/dist/bot/services/index.d.ts.map +1 -1
- package/dist/bot/services/index.js +10 -5
- package/dist/bot/services/index.js.map +1 -1
- package/dist/bot/services/message-classifier.d.ts +1 -1
- package/dist/bot/services/message-classifier.d.ts.map +1 -1
- package/dist/bot/services/message-classifier.js.map +1 -1
- package/dist/bot/services/signal-router.d.ts +32 -0
- package/dist/bot/services/signal-router.d.ts.map +1 -0
- package/dist/bot/services/signal-router.js +132 -0
- package/dist/bot/services/signal-router.js.map +1 -0
- package/dist/bot/services/system-prompt.d.ts +12 -0
- package/dist/bot/services/system-prompt.d.ts.map +1 -0
- package/dist/bot/services/system-prompt.js +93 -0
- package/dist/bot/services/system-prompt.js.map +1 -0
- package/dist/bot/services/types.d.ts +7 -34
- package/dist/bot/services/types.d.ts.map +1 -1
- package/dist/bot/services/types.js +0 -3
- package/dist/bot/services/types.js.map +1 -1
- package/dist/bot/services/workspace-refresh.d.ts +47 -0
- package/dist/bot/services/workspace-refresh.d.ts.map +1 -0
- package/dist/bot/services/workspace-refresh.js +154 -0
- package/dist/bot/services/workspace-refresh.js.map +1 -0
- package/dist/bot-config/constants.d.ts +0 -36
- package/dist/bot-config/constants.d.ts.map +1 -1
- package/dist/bot-config/constants.js +1 -76
- package/dist/bot-config/constants.js.map +1 -1
- package/dist/bot-config/context.d.ts +2 -42
- package/dist/bot-config/context.d.ts.map +1 -1
- package/dist/bot-config/context.js +13 -134
- package/dist/bot-config/context.js.map +1 -1
- package/dist/bot-config/index.d.ts +6 -15
- package/dist/bot-config/index.d.ts.map +1 -1
- package/dist/bot-config/index.js +5 -80
- package/dist/bot-config/index.js.map +1 -1
- package/dist/bot-config/loader.d.ts +16 -4
- package/dist/bot-config/loader.d.ts.map +1 -1
- package/dist/bot-config/loader.js +187 -96
- package/dist/bot-config/loader.js.map +1 -1
- package/dist/bot-config/persistence.d.ts +1 -52
- package/dist/bot-config/persistence.d.ts.map +1 -1
- package/dist/bot-config/persistence.js +3 -213
- package/dist/bot-config/persistence.js.map +1 -1
- package/dist/bot-config/state.d.ts +0 -41
- package/dist/bot-config/state.d.ts.map +1 -1
- package/dist/bot-config/state.js +0 -151
- package/dist/bot-config/state.js.map +1 -1
- package/dist/bot-config/tools.d.ts +1 -1
- package/dist/bot-config/tools.js +27 -27
- package/dist/bot-config/tools.js.map +1 -1
- package/dist/bot-config/types.d.ts +39 -32
- package/dist/bot-config/types.d.ts.map +1 -1
- package/dist/bot-config/types.js +0 -3
- package/dist/bot-config/types.js.map +1 -1
- package/dist/bot-config/webhooks.d.ts +0 -4
- package/dist/bot-config/webhooks.d.ts.map +1 -1
- package/dist/bot-config/webhooks.js +0 -13
- package/dist/bot-config/webhooks.js.map +1 -1
- package/dist/commands/seed-config.js +16 -31
- package/dist/commands/seed-config.js.map +1 -1
- package/dist/config.d.ts +0 -9
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -15
- package/dist/config.js.map +1 -1
- package/dist/mcp/hailer-clients.js +2 -2
- package/dist/mcp/hailer-clients.js.map +1 -1
- package/dist/mcp/tool-registry.d.ts +10 -115
- package/dist/mcp/tool-registry.d.ts.map +1 -1
- package/dist/mcp/tool-registry.js +39 -363
- package/dist/mcp/tool-registry.js.map +1 -1
- package/dist/mcp/tools/activity.d.ts +3 -0
- package/dist/mcp/tools/activity.d.ts.map +1 -1
- package/dist/mcp/tools/activity.js +8 -1
- package/dist/mcp/tools/activity.js.map +1 -1
- package/dist/mcp/tools/app-core.d.ts +3 -0
- package/dist/mcp/tools/app-core.d.ts.map +1 -1
- package/dist/mcp/tools/app-core.js +9 -2
- package/dist/mcp/tools/app-core.js.map +1 -1
- package/dist/mcp/tools/app-marketplace.d.ts +3 -0
- package/dist/mcp/tools/app-marketplace.d.ts.map +1 -1
- package/dist/mcp/tools/app-marketplace.js +13 -1
- package/dist/mcp/tools/app-marketplace.js.map +1 -1
- package/dist/mcp/tools/app-member.d.ts +3 -0
- package/dist/mcp/tools/app-member.d.ts.map +1 -1
- package/dist/mcp/tools/app-member.js +6 -1
- package/dist/mcp/tools/app-member.js.map +1 -1
- package/dist/mcp/tools/app-scaffold.d.ts +3 -0
- package/dist/mcp/tools/app-scaffold.d.ts.map +1 -1
- package/dist/mcp/tools/app-scaffold.js +19 -11
- package/dist/mcp/tools/app-scaffold.js.map +1 -1
- package/dist/mcp/tools/company.d.ts +3 -0
- package/dist/mcp/tools/company.d.ts.map +1 -1
- package/dist/mcp/tools/company.js +5 -1
- package/dist/mcp/tools/company.js.map +1 -1
- package/dist/mcp/tools/discussion.d.ts +3 -0
- package/dist/mcp/tools/discussion.d.ts.map +1 -1
- package/dist/mcp/tools/discussion.js +13 -2
- package/dist/mcp/tools/discussion.js.map +1 -1
- package/dist/mcp/tools/file.d.ts +3 -0
- package/dist/mcp/tools/file.d.ts.map +1 -1
- package/dist/mcp/tools/file.js +6 -1
- package/dist/mcp/tools/file.js.map +1 -1
- package/dist/mcp/tools/index.d.ts +7 -0
- package/dist/mcp/tools/index.d.ts.map +1 -0
- package/dist/mcp/tools/index.js +34 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/insight.d.ts +3 -0
- package/dist/mcp/tools/insight.d.ts.map +1 -1
- package/dist/mcp/tools/insight.js +18 -8
- package/dist/mcp/tools/insight.js.map +1 -1
- package/dist/mcp/tools/user.d.ts +3 -0
- package/dist/mcp/tools/user.d.ts.map +1 -1
- package/dist/mcp/tools/user.js +6 -1
- package/dist/mcp/tools/user.js.map +1 -1
- package/dist/mcp/tools/workflow-permissions.d.ts +3 -0
- package/dist/mcp/tools/workflow-permissions.d.ts.map +1 -1
- package/dist/mcp/tools/workflow-permissions.js +8 -1
- package/dist/mcp/tools/workflow-permissions.js.map +1 -1
- package/dist/mcp/tools/workflow.d.ts +3 -0
- package/dist/mcp/tools/workflow.d.ts.map +1 -1
- package/dist/mcp/tools/workflow.js +29 -28
- package/dist/mcp/tools/workflow.js.map +1 -1
- package/dist/mcp/utils/index.d.ts +4 -11
- package/dist/mcp/utils/index.d.ts.map +1 -1
- package/dist/mcp/utils/index.js +5 -36
- package/dist/mcp/utils/index.js.map +1 -1
- package/dist/mcp/utils/role-utils.d.ts +0 -32
- package/dist/mcp/utils/role-utils.d.ts.map +1 -1
- package/dist/mcp/utils/role-utils.js +0 -73
- package/dist/mcp/utils/role-utils.js.map +1 -1
- package/dist/mcp/utils/tool-helpers.d.ts +0 -25
- package/dist/mcp/utils/tool-helpers.d.ts.map +1 -1
- package/dist/mcp/utils/tool-helpers.js +0 -34
- package/dist/mcp/utils/tool-helpers.js.map +1 -1
- package/dist/mcp/webhook-handler.d.ts +4 -34
- package/dist/mcp/webhook-handler.d.ts.map +1 -1
- package/dist/mcp/webhook-handler.js +57 -74
- package/dist/mcp/webhook-handler.js.map +1 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +3 -78
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -2
- package/.claude/agents/agent-ada-skill-builder.md +0 -94
- package/.claude/agents/agent-alejandro-function-fields.md +0 -342
- package/.claude/agents/agent-bjorn-config-audit.md +0 -103
- package/.claude/agents/agent-builder-agent-creator.md +0 -130
- package/.claude/agents/agent-code-simplifier.md +0 -53
- package/.claude/agents/agent-dmitri-activity-crud.md +0 -159
- package/.claude/agents/agent-giuseppe-app-builder.md +0 -208
- package/.claude/agents/agent-gunther-mcp-tools.md +0 -39
- package/.claude/agents/agent-helga-workflow-config.md +0 -204
- package/.claude/agents/agent-igor-activity-mover-automation.md +0 -125
- package/.claude/agents/agent-ingrid-doc-templates.md +0 -261
- package/.claude/agents/agent-ivan-monolith.md +0 -154
- package/.claude/agents/agent-kenji-data-reader.md +0 -86
- package/.claude/agents/agent-lars-code-inspector.md +0 -102
- package/.claude/agents/agent-marco-mockup-builder.md +0 -110
- package/.claude/agents/agent-marcus-api-documenter.md +0 -323
- package/.claude/agents/agent-marketplace-publisher.md +0 -280
- package/.claude/agents/agent-marketplace-reviewer.md +0 -309
- package/.claude/agents/agent-permissions-handler.md +0 -208
- package/.claude/agents/agent-simple-writer.md +0 -48
- package/.claude/agents/agent-svetlana-code-review.md +0 -171
- package/.claude/agents/agent-tanya-test-runner.md +0 -333
- package/.claude/agents/agent-ui-designer.md +0 -100
- package/.claude/agents/agent-viktor-sql-insights.md +0 -212
- package/.claude/agents/agent-web-search.md +0 -55
- package/.claude/agents/agent-yevgeni-discussions.md +0 -45
- package/.claude/agents/agent-zara-zapier.md +0 -159
- package/.claude/skills/SDK-activity-patterns/SKILL.md +0 -428
- package/.claude/skills/SDK-generate-skill/SKILL.md +0 -92
- package/.claude/skills/SDK-init-skill/SKILL.md +0 -127
- package/.claude/skills/agent-structure/SKILL.md +0 -98
- package/.claude/skills/delegation-routing/SKILL.md +0 -202
- package/.claude/skills/frontend-design/SKILL.md +0 -254
- package/.claude/skills/hailer-activity-mover/SKILL.md +0 -213
- package/.claude/skills/hailer-rest-api/SKILL.md +0 -61
- package/.claude/skills/hailer-rest-api/hailer-activities.md +0 -184
- package/.claude/skills/hailer-rest-api/hailer-admin.md +0 -473
- package/.claude/skills/hailer-rest-api/hailer-calendar.md +0 -256
- package/.claude/skills/hailer-rest-api/hailer-feed.md +0 -249
- package/.claude/skills/hailer-rest-api/hailer-insights.md +0 -195
- package/.claude/skills/hailer-rest-api/hailer-messaging.md +0 -276
- package/.claude/skills/hailer-rest-api/hailer-workflows.md +0 -283
- package/.claude/skills/insight-join-patterns/SKILL.md +0 -174
- package/.claude/skills/json-only-output/SKILL.md +0 -72
- package/.claude/skills/mcp-direct-tools/SKILL.md +0 -153
- package/.claude/skills/optional-parameters/SKILL.md +0 -72
- package/.claude/skills/tool-parameter-usage/SKILL.md +0 -126
- package/.claude/skills/tool-response-verification/SKILL.md +0 -92
- package/.opencode/agent/agent-ada-skill-builder.md +0 -35
- package/.opencode/agent/agent-alejandro-function-fields.md +0 -39
- package/.opencode/agent/agent-bjorn-config-audit.md +0 -36
- package/.opencode/agent/agent-builder-agent-creator.md +0 -39
- package/.opencode/agent/agent-code-simplifier.md +0 -31
- package/.opencode/agent/agent-dmitri-activity-crud.md +0 -40
- package/.opencode/agent/agent-giuseppe-app-builder.md +0 -37
- package/.opencode/agent/agent-gunther-mcp-tools.md +0 -39
- package/.opencode/agent/agent-helga-workflow-config.md +0 -204
- package/.opencode/agent/agent-igor-activity-mover-automation.md +0 -46
- package/.opencode/agent/agent-ingrid-doc-templates.md +0 -39
- package/.opencode/agent/agent-ivan-monolith.md +0 -46
- package/.opencode/agent/agent-kenji-data-reader.md +0 -53
- package/.opencode/agent/agent-lars-code-inspector.md +0 -28
- package/.opencode/agent/agent-marco-mockup-builder.md +0 -42
- package/.opencode/agent/agent-marcus-api-documenter.md +0 -53
- package/.opencode/agent/agent-marketplace-publisher.md +0 -44
- package/.opencode/agent/agent-marketplace-reviewer.md +0 -42
- package/.opencode/agent/agent-permissions-handler.md +0 -50
- package/.opencode/agent/agent-simple-writer.md +0 -45
- package/.opencode/agent/agent-svetlana-code-review.md +0 -39
- package/.opencode/agent/agent-tanya-test-runner.md +0 -57
- package/.opencode/agent/agent-ui-designer.md +0 -56
- package/.opencode/agent/agent-viktor-sql-insights.md +0 -34
- package/.opencode/agent/agent-web-search.md +0 -42
- package/.opencode/agent/agent-yevgeni-discussions.md +0 -37
- package/.opencode/agent/agent-zara-zapier.md +0 -53
- package/.opencode/commands/app-squad.md +0 -135
- package/.opencode/commands/audit-squad.md +0 -158
- package/.opencode/commands/autoplan.md +0 -563
- package/.opencode/commands/cleanup-squad.md +0 -98
- package/.opencode/commands/config-squad.md +0 -106
- package/.opencode/commands/crud-squad.md +0 -87
- package/.opencode/commands/data-squad.md +0 -97
- package/.opencode/commands/debug-squad.md +0 -303
- package/.opencode/commands/doc-squad.md +0 -65
- package/.opencode/commands/handoff.md +0 -137
- package/.opencode/commands/health.md +0 -49
- package/.opencode/commands/help-agents.md +0 -151
- package/.opencode/commands/help-commands.md +0 -32
- package/.opencode/commands/help-faq.md +0 -29
- package/.opencode/commands/help-plugins.md +0 -28
- package/.opencode/commands/help-skills.md +0 -7
- package/.opencode/commands/help-tools.md +0 -40
- package/.opencode/commands/help.md +0 -28
- package/.opencode/commands/hotfix-squad.md +0 -112
- package/.opencode/commands/integration-squad.md +0 -82
- package/.opencode/commands/janitor-squad.md +0 -167
- package/.opencode/commands/learn-auto.md +0 -120
- package/.opencode/commands/learn.md +0 -120
- package/.opencode/commands/mcp-list.md +0 -27
- package/.opencode/commands/onboard-squad.md +0 -140
- package/.opencode/commands/plan-workspace.md +0 -732
- package/.opencode/commands/prd.md +0 -131
- package/.opencode/commands/project-status.md +0 -82
- package/.opencode/commands/publish.md +0 -138
- package/.opencode/commands/recap.md +0 -69
- package/.opencode/commands/restore.md +0 -64
- package/.opencode/commands/review-squad.md +0 -152
- package/.opencode/commands/save.md +0 -24
- package/.opencode/commands/stats.md +0 -19
- package/.opencode/commands/swarm.md +0 -210
- package/.opencode/commands/tool-builder.md +0 -39
- package/.opencode/commands/ws-pull.md +0 -44
|
@@ -1,63 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* No singletons, no statics - just clean, explicit tool registration
|
|
6
|
-
* with per-agent access control via dependency injection.
|
|
7
|
-
*
|
|
8
|
-
* Supports workspace-specific schema overrides for structured outputs:
|
|
9
|
-
* - Load schemas from WORKSPACE_SCHEMAS_PATH environment variable
|
|
10
|
-
* - Schemas contain enum constraints (valid IDs, phase options, etc.)
|
|
11
|
-
* - Enables Claude's strict mode validation with actual workspace values
|
|
3
|
+
* Tool Registry — register, list, validate, execute MCP tools.
|
|
12
4
|
*/
|
|
13
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
-
}
|
|
19
|
-
Object.defineProperty(o, k2, desc);
|
|
20
|
-
}) : (function(o, m, k, k2) {
|
|
21
|
-
if (k2 === undefined) k2 = k;
|
|
22
|
-
o[k2] = m[k];
|
|
23
|
-
}));
|
|
24
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
-
}) : function(o, v) {
|
|
27
|
-
o["default"] = v;
|
|
28
|
-
});
|
|
29
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
-
var ownKeys = function(o) {
|
|
31
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
-
var ar = [];
|
|
33
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
-
return ar;
|
|
35
|
-
};
|
|
36
|
-
return ownKeys(o);
|
|
37
|
-
};
|
|
38
|
-
return function (mod) {
|
|
39
|
-
if (mod && mod.__esModule) return mod;
|
|
40
|
-
var result = {};
|
|
41
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
-
__setModuleDefault(result, mod);
|
|
43
|
-
return result;
|
|
44
|
-
};
|
|
45
|
-
})();
|
|
46
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
6
|
exports.ToolRegistry = exports.ToolGroup = void 0;
|
|
48
7
|
const zod_1 = require("zod");
|
|
49
8
|
const logger_1 = require("../lib/logger");
|
|
50
9
|
const request_logger_1 = require("../lib/request-logger");
|
|
51
|
-
const fs = __importStar(require("fs"));
|
|
52
|
-
const path = __importStar(require("path"));
|
|
53
10
|
const logger = (0, logger_1.createLogger)({ component: 'tool-registry' });
|
|
54
11
|
/**
|
|
55
12
|
* Tool groups for access control
|
|
56
|
-
* READ: Safe read operations (workflows, activities, schemas)
|
|
57
|
-
* WRITE: Create/update operations (activities, discussions)
|
|
58
|
-
* PLAYGROUND: Admin/dev tools (workflow/app management)
|
|
59
|
-
* NUCLEAR: Destructive operations (remove workflows, apps, insights, templates)
|
|
60
|
-
* BOT_INTERNAL: Tools for autonomous bots only (not exposed to MCP clients by default)
|
|
61
13
|
*/
|
|
62
14
|
var ToolGroup;
|
|
63
15
|
(function (ToolGroup) {
|
|
@@ -67,220 +19,63 @@ var ToolGroup;
|
|
|
67
19
|
ToolGroup["NUCLEAR"] = "nuclear";
|
|
68
20
|
ToolGroup["BOT_INTERNAL"] = "bot_internal";
|
|
69
21
|
})(ToolGroup || (exports.ToolGroup = ToolGroup = {}));
|
|
70
|
-
/**
|
|
71
|
-
* ToolRegistry - Clean, testable, dependency-injected tool registry
|
|
72
|
-
*
|
|
73
|
-
* NO SINGLETON PATTERN - instantiated explicitly and passed through DI
|
|
74
|
-
*
|
|
75
|
-
* Workspace Schema Support:
|
|
76
|
-
* Set WORKSPACE_SCHEMAS_PATH env var to load Claude-compatible schemas
|
|
77
|
-
* with enum constraints for workflow IDs, phase IDs, field options, etc.
|
|
78
|
-
*/
|
|
79
22
|
class ToolRegistry {
|
|
80
23
|
tools = new Map();
|
|
24
|
+
jsonSchemas = new Map();
|
|
81
25
|
_lazyGuard;
|
|
82
26
|
enableNuclearTools;
|
|
83
|
-
workspaceSchemas = new Map();
|
|
84
|
-
workspaceSchemasLoaded = false;
|
|
85
27
|
constructor(options = {}) {
|
|
86
28
|
this.enableNuclearTools = options.enableNuclearTools ?? false;
|
|
87
|
-
logger.debug('ToolRegistry instance created', {
|
|
88
|
-
enableNuclearTools: this.enableNuclearTools
|
|
89
|
-
});
|
|
90
|
-
// Load workspace schemas if path is configured
|
|
91
|
-
this.loadWorkspaceSchemas();
|
|
92
29
|
}
|
|
93
|
-
/**
|
|
94
|
-
* Load workspace-specific schemas from configured path
|
|
95
|
-
* Schemas provide enum constraints for Claude's strict mode
|
|
96
|
-
*/
|
|
97
|
-
loadWorkspaceSchemas() {
|
|
98
|
-
const schemasPath = process.env.WORKSPACE_SCHEMAS_PATH;
|
|
99
|
-
if (!schemasPath) {
|
|
100
|
-
logger.debug('WORKSPACE_SCHEMAS_PATH not set, using generic schemas');
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
const claudeSchemasPath = path.join(schemasPath, 'claude');
|
|
104
|
-
if (!fs.existsSync(claudeSchemasPath)) {
|
|
105
|
-
logger.warn('Workspace schemas path not found', { path: claudeSchemasPath });
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
try {
|
|
109
|
-
const files = fs.readdirSync(claudeSchemasPath);
|
|
110
|
-
for (const file of files) {
|
|
111
|
-
if (file.endsWith('.schema.json')) {
|
|
112
|
-
const schemaPath = path.join(claudeSchemasPath, file);
|
|
113
|
-
const schema = JSON.parse(fs.readFileSync(schemaPath, 'utf-8'));
|
|
114
|
-
const name = file.replace('.schema.json', '');
|
|
115
|
-
this.workspaceSchemas.set(name, schema);
|
|
116
|
-
logger.debug('Loaded workspace schema', { name, file });
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
this.workspaceSchemasLoaded = true;
|
|
120
|
-
logger.debug('Workspace schemas loaded for structured outputs', {
|
|
121
|
-
count: this.workspaceSchemas.size,
|
|
122
|
-
schemas: Array.from(this.workspaceSchemas.keys()),
|
|
123
|
-
path: claudeSchemasPath
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
catch (error) {
|
|
127
|
-
logger.error('Failed to load workspace schemas', error);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Get workspace schema for a workflow (if available)
|
|
132
|
-
*/
|
|
133
|
-
getWorkspaceSchema(workflowName) {
|
|
134
|
-
const normalizedName = workflowName.toLowerCase().replace(/ /g, '_');
|
|
135
|
-
return this.workspaceSchemas.get(normalizedName) || null;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Check if workspace schemas are available
|
|
139
|
-
*/
|
|
140
|
-
hasWorkspaceSchemas() {
|
|
141
|
-
return this.workspaceSchemasLoaded && this.workspaceSchemas.size > 0;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Add a tool to the registry
|
|
145
|
-
*/
|
|
146
30
|
addTool(tool) {
|
|
147
|
-
|
|
148
|
-
if (tool.group === ToolGroup.NUCLEAR && !this.enableNuclearTools) {
|
|
149
|
-
logger.debug('Skipping NUCLEAR tool (not enabled)', {
|
|
150
|
-
name: tool.name,
|
|
151
|
-
group: tool.group
|
|
152
|
-
});
|
|
31
|
+
if (tool.group === ToolGroup.NUCLEAR && !this.enableNuclearTools)
|
|
153
32
|
return;
|
|
154
|
-
}
|
|
155
|
-
if (this.tools.has(tool.name)) {
|
|
156
|
-
logger.warn('Tool already registered, replacing', { name: tool.name });
|
|
157
|
-
}
|
|
158
33
|
this.tools.set(tool.name, tool);
|
|
159
|
-
|
|
34
|
+
this.jsonSchemas.set(tool.name, this.convertZodSchemaToJsonSchema(tool.schema));
|
|
160
35
|
}
|
|
161
|
-
/**
|
|
162
|
-
* Get tool definitions filtered by contextType — single-pass, no secondary lookups
|
|
163
|
-
*/
|
|
36
|
+
/** Filter tools by contextType */
|
|
164
37
|
getToolDefinitionsByContextType(contextType) {
|
|
165
38
|
return Array.from(this.tools.values())
|
|
166
39
|
.filter(t => (t.contextType ?? 'hailer') === contextType)
|
|
167
40
|
.map(tool => ({
|
|
168
41
|
name: tool.name,
|
|
169
42
|
description: tool.description,
|
|
170
|
-
inputSchema: this.
|
|
43
|
+
inputSchema: this.jsonSchemas.get(tool.name)
|
|
171
44
|
}));
|
|
172
45
|
}
|
|
173
|
-
/**
|
|
174
|
-
* Get tool definitions with optional filtering
|
|
175
|
-
*
|
|
176
|
-
* @param filter - Optional filter configuration
|
|
177
|
-
* @param filter.allowedGroups - Filter by tool groups
|
|
178
|
-
* @param filter.allowedTools - Explicit whitelist of tool names
|
|
179
|
-
*/
|
|
46
|
+
/** Get tool definitions with optional group/name filtering */
|
|
180
47
|
getToolDefinitions(filter) {
|
|
181
48
|
let toolsToExpose = Array.from(this.tools.values());
|
|
182
49
|
if (filter) {
|
|
183
50
|
if (filter.allowedTools) {
|
|
184
|
-
// Explicit whitelist by tool name (takes precedence)
|
|
185
51
|
toolsToExpose = toolsToExpose.filter(t => filter.allowedTools.includes(t.name));
|
|
186
|
-
logger.debug('Filtered tools by allowedTools', {
|
|
187
|
-
count: toolsToExpose.length,
|
|
188
|
-
allowedTools: filter.allowedTools
|
|
189
|
-
});
|
|
190
52
|
}
|
|
191
53
|
else if (filter.allowedGroups) {
|
|
192
|
-
// Filter by tool groups
|
|
193
54
|
toolsToExpose = toolsToExpose.filter(t => filter.allowedGroups.includes(t.group));
|
|
194
|
-
logger.debug('Filtered tools by allowedGroups', {
|
|
195
|
-
count: toolsToExpose.length,
|
|
196
|
-
allowedGroups: filter.allowedGroups
|
|
197
|
-
});
|
|
198
55
|
}
|
|
199
56
|
}
|
|
200
57
|
return toolsToExpose.map(tool => ({
|
|
201
58
|
name: tool.name,
|
|
202
59
|
description: tool.description,
|
|
203
|
-
inputSchema: this.
|
|
60
|
+
inputSchema: this.jsonSchemas.get(tool.name)
|
|
204
61
|
}));
|
|
205
62
|
}
|
|
206
|
-
/**
|
|
207
|
-
|
|
208
|
-
* Token-efficient: ~200 tokens per tool vs loading all tools upfront
|
|
209
|
-
*
|
|
210
|
-
* For activity tools (create_activity, update_activity), returns the master
|
|
211
|
-
* workspace schema with ALL valid IDs as enums. This enables Claude's strict
|
|
212
|
-
* mode to constrain outputs to valid values without needing them in the prompt.
|
|
213
|
-
*/
|
|
214
|
-
getToolSchema(toolName, workflowName) {
|
|
63
|
+
/** Get specific tool schema on-demand */
|
|
64
|
+
getToolSchema(toolName) {
|
|
215
65
|
const tool = this.tools.get(toolName);
|
|
216
|
-
if (!tool)
|
|
217
|
-
logger.warn('Tool not found', { toolName });
|
|
66
|
+
if (!tool)
|
|
218
67
|
return null;
|
|
219
|
-
}
|
|
220
|
-
// For activity tools, return master schema with ALL enum constraints
|
|
221
|
-
if (this.workspaceSchemasLoaded &&
|
|
222
|
-
(toolName === 'create_activity' || toolName === 'update_activity')) {
|
|
223
|
-
const masterSchema = this.workspaceSchemas.get('_master_activity');
|
|
224
|
-
if (masterSchema) {
|
|
225
|
-
logger.debug('Using master workspace schema with enum constraints', {
|
|
226
|
-
toolName,
|
|
227
|
-
workflowCount: masterSchema.properties?.workflowId?.enum?.length || 0,
|
|
228
|
-
phaseCount: masterSchema.properties?.phaseId?.enum?.length || 0
|
|
229
|
-
});
|
|
230
|
-
return {
|
|
231
|
-
name: tool.name,
|
|
232
|
-
description: `${tool.description} [Enum-constrained to valid workspace IDs]`,
|
|
233
|
-
inputSchema: masterSchema
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
// For workflow-specific request, return that workflow's schema
|
|
238
|
-
if (this.workspaceSchemasLoaded && workflowName) {
|
|
239
|
-
const workspaceSchema = this.getWorkspaceSchema(workflowName);
|
|
240
|
-
if (workspaceSchema) {
|
|
241
|
-
logger.debug('Using workflow-specific schema', { toolName, workflowName });
|
|
242
|
-
return {
|
|
243
|
-
name: tool.name,
|
|
244
|
-
description: `${tool.description} [Schema-constrained to ${workflowName}]`,
|
|
245
|
-
inputSchema: workspaceSchema
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
// Fallback to generic Zod-converted schema
|
|
250
68
|
return {
|
|
251
69
|
name: tool.name,
|
|
252
70
|
description: tool.description,
|
|
253
|
-
inputSchema: this.
|
|
71
|
+
inputSchema: this.jsonSchemas.get(tool.name)
|
|
254
72
|
};
|
|
255
73
|
}
|
|
256
|
-
/**
|
|
257
|
-
* Get all workflow-specific tool schemas
|
|
258
|
-
* Returns schemas with enum constraints for each workflow
|
|
259
|
-
*/
|
|
260
|
-
getAllWorkflowSchemas() {
|
|
261
|
-
const schemas = new Map();
|
|
262
|
-
if (!this.workspaceSchemasLoaded) {
|
|
263
|
-
return schemas;
|
|
264
|
-
}
|
|
265
|
-
for (const [workflowName, schema] of this.workspaceSchemas.entries()) {
|
|
266
|
-
if (workflowName.startsWith('_'))
|
|
267
|
-
continue; // Skip meta schemas
|
|
268
|
-
schemas.set(workflowName, {
|
|
269
|
-
name: `create_${workflowName}`,
|
|
270
|
-
description: `Create activity in ${workflowName}. Enum-constrained to valid IDs.`,
|
|
271
|
-
inputSchema: schema
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
return schemas;
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Execute tool with validation
|
|
278
|
-
*/
|
|
74
|
+
/** Execute tool with Zod validation */
|
|
279
75
|
async executeTool(name, args, context) {
|
|
280
76
|
const tool = this.tools.get(name);
|
|
281
|
-
if (!tool)
|
|
77
|
+
if (!tool)
|
|
282
78
|
throw new Error(`Tool "${name}" not found`);
|
|
283
|
-
}
|
|
284
79
|
logger.debug('Executing tool', {
|
|
285
80
|
name,
|
|
286
81
|
auth: context?.apiKey
|
|
@@ -292,7 +87,6 @@ class ToolRegistry {
|
|
|
292
87
|
if (name === 'install_workflow' && args.workflowTemplates) {
|
|
293
88
|
transformedArgs = this.preTransformInstallWorkflow(args);
|
|
294
89
|
}
|
|
295
|
-
// Zod validation
|
|
296
90
|
try {
|
|
297
91
|
const validated = tool.schema.parse(transformedArgs);
|
|
298
92
|
return await tool.execute(validated, context);
|
|
@@ -300,57 +94,31 @@ class ToolRegistry {
|
|
|
300
94
|
catch (error) {
|
|
301
95
|
if (error instanceof zod_1.z.ZodError) {
|
|
302
96
|
const errorDetails = error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');
|
|
303
|
-
// Track in request logger or log separately
|
|
304
97
|
const reqLogger = request_logger_1.RequestLogger.getCurrent();
|
|
305
98
|
if (reqLogger) {
|
|
306
99
|
reqLogger.toolError(name, errorDetails);
|
|
307
100
|
}
|
|
308
101
|
else {
|
|
309
|
-
logger.warn('Tool validation failed', {
|
|
310
|
-
toolName: name,
|
|
311
|
-
errors: errorDetails,
|
|
312
|
-
receivedArgs: JSON.stringify(args)
|
|
313
|
-
});
|
|
102
|
+
logger.warn('Tool validation failed', { toolName: name, errors: errorDetails, receivedArgs: JSON.stringify(args) });
|
|
314
103
|
}
|
|
315
|
-
// Check if tool has a skill hint
|
|
316
104
|
const hasSkillHint = tool.description.includes('Use Skill');
|
|
317
105
|
const skillName = hasSkillHint ? tool.description.match(/`([^`]+)-skill`/)?.[1] + '-skill' : null;
|
|
318
|
-
const errorMessage = `❌ **Validation Error for \`${name}\`**
|
|
319
|
-
|
|
320
|
-
**Errors:** ${errorDetails}
|
|
321
|
-
|
|
322
|
-
**You provided:**
|
|
323
|
-
\`\`\`json
|
|
324
|
-
${JSON.stringify(args, null, 2)}
|
|
325
|
-
\`\`\`
|
|
326
|
-
|
|
327
|
-
${skillName ? `💡 **Next step:** Load the skill first to see correct format and examples:
|
|
328
|
-
\`\`\`
|
|
329
|
-
get_skill({ skillName: "${skillName}" })
|
|
330
|
-
\`\`\`
|
|
331
|
-
|
|
332
|
-
Then retry \`${name}\` with the correct format from the skill examples.` : `💡 **Next step:** Use \`tools/get_schema\` to see the full schema for \`${name}\`, then retry with correct parameters.`}`;
|
|
333
106
|
return {
|
|
334
107
|
content: [{
|
|
335
108
|
type: "text",
|
|
336
|
-
text:
|
|
109
|
+
text: `❌ **Validation Error for \`${name}\`**\n\n**Errors:** ${errorDetails}\n\n**You provided:**\n\`\`\`json\n${JSON.stringify(args, null, 2)}\n\`\`\`\n\n${skillName ? `💡 **Next step:** Load the skill first:\n\`\`\`\nget_skill({ skillName: "${skillName}" })\n\`\`\`\nThen retry with the correct format.` : `💡 **Next step:** Use \`tools/get_schema\` to see the full schema for \`${name}\`, then retry.`}`
|
|
337
110
|
}]
|
|
338
111
|
};
|
|
339
112
|
}
|
|
340
113
|
throw error;
|
|
341
114
|
}
|
|
342
115
|
}
|
|
343
|
-
/**
|
|
344
|
-
* Pre-transform install_workflow args to fix common LLM mistakes BEFORE validation
|
|
345
|
-
*/
|
|
116
|
+
/** Fix common LLM mistakes in install_workflow before validation */
|
|
346
117
|
preTransformInstallWorkflow(args) {
|
|
347
118
|
let templates = args.workflowTemplates;
|
|
348
|
-
|
|
349
|
-
if (!Array.isArray(templates)) {
|
|
119
|
+
if (!Array.isArray(templates))
|
|
350
120
|
templates = [templates];
|
|
351
|
-
|
|
352
|
-
// Transform each template
|
|
353
|
-
templates = templates.map((template, tIdx) => {
|
|
121
|
+
templates = templates.map((template) => {
|
|
354
122
|
const result = { ...template };
|
|
355
123
|
// Fix: fields as array instead of object
|
|
356
124
|
if (Array.isArray(template.fields)) {
|
|
@@ -363,7 +131,6 @@ Then retry \`${name}\` with the correct format from the skill examples.` : `💡
|
|
|
363
131
|
result.fields = fieldsObj;
|
|
364
132
|
}
|
|
365
133
|
else if (template.fields) {
|
|
366
|
-
// Fix: field IDs not matching pattern
|
|
367
134
|
const fieldsObj = {};
|
|
368
135
|
let idx = 0;
|
|
369
136
|
for (const [key, field] of Object.entries(template.fields)) {
|
|
@@ -379,19 +146,16 @@ Then retry \`${name}\` with the correct format from the skill examples.` : `💡
|
|
|
379
146
|
if (Array.isArray(template.phases)) {
|
|
380
147
|
const phasesObj = {};
|
|
381
148
|
template.phases.forEach((phase, idx) => {
|
|
382
|
-
|
|
383
|
-
phasesObj[phaseId] = { name: phase.name };
|
|
149
|
+
phasesObj[`_${2000 + idx}`] = { name: phase.name };
|
|
384
150
|
});
|
|
385
151
|
result.phases = phasesObj;
|
|
386
152
|
}
|
|
387
153
|
else if (template.phases) {
|
|
388
|
-
// Fix: phase IDs not matching pattern
|
|
389
154
|
const phasesObj = {};
|
|
390
155
|
let idx = 0;
|
|
391
156
|
for (const [key, phase] of Object.entries(template.phases)) {
|
|
392
157
|
const phaseId = /^_\d{4}$/.test(key) ? key : `_${2000 + idx}`;
|
|
393
|
-
|
|
394
|
-
phasesObj[phaseId] = { name: p.name || key };
|
|
158
|
+
phasesObj[phaseId] = { name: phase.name || key };
|
|
395
159
|
idx++;
|
|
396
160
|
}
|
|
397
161
|
result.phases = phasesObj;
|
|
@@ -400,10 +164,8 @@ Then retry \`${name}\` with the correct format from the skill examples.` : `💡
|
|
|
400
164
|
if (result.fields) {
|
|
401
165
|
for (const fieldId of Object.keys(result.fields)) {
|
|
402
166
|
const f = result.fields[fieldId];
|
|
403
|
-
// select → textpredefinedoptions
|
|
404
167
|
if (f.type === 'select')
|
|
405
168
|
f.type = 'textpredefinedoptions';
|
|
406
|
-
// user → users
|
|
407
169
|
if (f.type === 'user')
|
|
408
170
|
f.type = 'users';
|
|
409
171
|
}
|
|
@@ -412,127 +174,55 @@ Then retry \`${name}\` with the correct format from the skill examples.` : `💡
|
|
|
412
174
|
});
|
|
413
175
|
return { ...args, workflowTemplates: templates };
|
|
414
176
|
}
|
|
415
|
-
/**
|
|
416
|
-
* Get tool metadata (for access control checks)
|
|
417
|
-
*/
|
|
418
177
|
getTool(name) {
|
|
419
178
|
return this.tools.get(name);
|
|
420
179
|
}
|
|
421
|
-
/**
|
|
422
|
-
* Get total tool count
|
|
423
|
-
*/
|
|
424
180
|
getToolCount() {
|
|
425
181
|
return this.tools.size;
|
|
426
182
|
}
|
|
427
|
-
/**
|
|
428
|
-
* Get statistics for monitoring/debugging
|
|
429
|
-
*/
|
|
430
183
|
getCacheStats() {
|
|
431
184
|
const byGroup = {
|
|
432
|
-
[ToolGroup.READ]: 0,
|
|
433
|
-
[ToolGroup.
|
|
434
|
-
[ToolGroup.PLAYGROUND]: 0,
|
|
435
|
-
[ToolGroup.NUCLEAR]: 0,
|
|
436
|
-
[ToolGroup.BOT_INTERNAL]: 0
|
|
185
|
+
[ToolGroup.READ]: 0, [ToolGroup.WRITE]: 0,
|
|
186
|
+
[ToolGroup.PLAYGROUND]: 0, [ToolGroup.NUCLEAR]: 0, [ToolGroup.BOT_INTERNAL]: 0
|
|
437
187
|
};
|
|
438
|
-
for (const tool of this.tools.values())
|
|
188
|
+
for (const tool of this.tools.values())
|
|
439
189
|
byGroup[tool.group]++;
|
|
440
|
-
}
|
|
441
|
-
return {
|
|
442
|
-
totalTools: this.tools.size,
|
|
443
|
-
toolNames: Array.from(this.tools.keys()),
|
|
444
|
-
byGroup,
|
|
445
|
-
workspaceSchemas: {
|
|
446
|
-
loaded: this.workspaceSchemasLoaded,
|
|
447
|
-
count: this.workspaceSchemas.size,
|
|
448
|
-
workflows: Array.from(this.workspaceSchemas.keys())
|
|
449
|
-
}
|
|
450
|
-
};
|
|
190
|
+
return { totalTools: this.tools.size, toolNames: Array.from(this.tools.keys()), byGroup };
|
|
451
191
|
}
|
|
452
|
-
|
|
453
|
-
* Get all available workspace schemas (for listing available workflows)
|
|
454
|
-
*/
|
|
455
|
-
getAvailableWorkflowSchemas() {
|
|
456
|
-
const workflows = [];
|
|
457
|
-
for (const [name, schema] of this.workspaceSchemas.entries()) {
|
|
458
|
-
if (name.startsWith('_'))
|
|
459
|
-
continue; // Skip meta schemas like _workspace
|
|
460
|
-
workflows.push({
|
|
461
|
-
name: name.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()),
|
|
462
|
-
workflowId: schema.properties?.workflowId?.const || '',
|
|
463
|
-
description: schema.description || ''
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
|
-
return workflows;
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* Get workflow-specific create tool definition
|
|
470
|
-
* Returns schema with enum constraints for valid phase IDs, field options, etc.
|
|
471
|
-
*/
|
|
472
|
-
getWorkflowCreateToolDefinition(workflowName) {
|
|
473
|
-
const schema = this.getWorkspaceSchema(workflowName);
|
|
474
|
-
if (!schema) {
|
|
475
|
-
return null;
|
|
476
|
-
}
|
|
477
|
-
const normalizedName = workflowName.toLowerCase().replace(/ /g, '_');
|
|
478
|
-
return {
|
|
479
|
-
name: `create_${normalizedName}`,
|
|
480
|
-
description: `Create activity in ${workflowName}. Schema-validated with enum constraints for valid IDs.`,
|
|
481
|
-
inputSchema: schema
|
|
482
|
-
};
|
|
483
|
-
}
|
|
484
|
-
/**
|
|
485
|
-
* Convert Zod schema to JSON Schema format (required by MCP protocol)
|
|
486
|
-
*/
|
|
192
|
+
// ===== ZOD → JSON SCHEMA CONVERSION =====
|
|
487
193
|
convertZodSchemaToJsonSchema(zodSchema) {
|
|
488
|
-
// Handle ZodObject by extracting its shape
|
|
489
194
|
if (zodSchema._def?.typeName === 'ZodObject') {
|
|
490
195
|
zodSchema = zodSchema._def.shape();
|
|
491
196
|
}
|
|
492
197
|
const properties = {};
|
|
493
198
|
const required = [];
|
|
494
|
-
// Handle the schema object
|
|
495
199
|
for (const [key, value] of Object.entries(zodSchema)) {
|
|
496
200
|
if (value && typeof value === "object" && "_def" in value) {
|
|
497
201
|
const zodType = value;
|
|
498
202
|
const property = this.convertZodTypeToJsonSchema(zodType);
|
|
499
|
-
// Handle optional vs required - Check for ZodOptional and ZodDefault wrappers
|
|
500
203
|
const isOptional = zodType._def?.typeName === 'ZodOptional';
|
|
501
204
|
const hasDefault = zodType._def?.typeName === 'ZodDefault';
|
|
502
|
-
if (!isOptional && !hasDefault)
|
|
205
|
+
if (!isOptional && !hasDefault)
|
|
503
206
|
required.push(key);
|
|
504
|
-
}
|
|
505
|
-
// Handle default values - Extract from ZodDefault wrapper
|
|
506
207
|
if (hasDefault && typeof zodType._def?.defaultValue === 'function') {
|
|
507
208
|
property.default = zodType._def.defaultValue();
|
|
508
209
|
}
|
|
509
210
|
properties[key] = property;
|
|
510
211
|
}
|
|
511
212
|
}
|
|
512
|
-
return {
|
|
513
|
-
type: "object",
|
|
514
|
-
properties,
|
|
515
|
-
required,
|
|
516
|
-
};
|
|
213
|
+
return { type: "object", properties, required };
|
|
517
214
|
}
|
|
518
|
-
/**
|
|
519
|
-
* Convert a single Zod type to JSON Schema
|
|
520
|
-
*/
|
|
521
215
|
convertZodTypeToJsonSchema(zodType) {
|
|
522
|
-
// Unwrap ZodOptional and ZodDefault wrappers to get the inner type
|
|
523
216
|
let unwrappedType = zodType;
|
|
524
217
|
while (unwrappedType._def?.typeName === 'ZodOptional' || unwrappedType._def?.typeName === 'ZodDefault') {
|
|
525
218
|
unwrappedType = unwrappedType._def.innerType;
|
|
526
219
|
}
|
|
527
220
|
const typeName = unwrappedType._def?.typeName;
|
|
528
221
|
const property = {};
|
|
529
|
-
|
|
530
|
-
if (zodType._def?.description) {
|
|
222
|
+
if (zodType._def?.description)
|
|
531
223
|
property.description = zodType._def.description;
|
|
532
|
-
|
|
533
|
-
else if (unwrappedType._def?.description) {
|
|
224
|
+
else if (unwrappedType._def?.description)
|
|
534
225
|
property.description = unwrappedType._def.description;
|
|
535
|
-
}
|
|
536
226
|
switch (typeName) {
|
|
537
227
|
case "ZodString":
|
|
538
228
|
property.type = "string";
|
|
@@ -545,23 +235,17 @@ Then retry \`${name}\` with the correct format from the skill examples.` : `💡
|
|
|
545
235
|
break;
|
|
546
236
|
case "ZodArray":
|
|
547
237
|
property.type = "array";
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
}
|
|
552
|
-
else {
|
|
553
|
-
property.items = { type: "string" };
|
|
554
|
-
}
|
|
238
|
+
property.items = unwrappedType._def?.type
|
|
239
|
+
? this.convertZodTypeToJsonSchema(unwrappedType._def.type)
|
|
240
|
+
: { type: "string" };
|
|
555
241
|
break;
|
|
556
242
|
case "ZodObject":
|
|
557
243
|
property.type = "object";
|
|
558
|
-
// Recursively handle object properties if needed
|
|
559
244
|
if (unwrappedType._def?.shape) {
|
|
560
245
|
const nestedSchema = this.convertZodSchemaToJsonSchema(unwrappedType._def.shape);
|
|
561
246
|
property.properties = nestedSchema.properties;
|
|
562
|
-
if (nestedSchema.required?.length > 0)
|
|
247
|
+
if (nestedSchema.required?.length > 0)
|
|
563
248
|
property.required = nestedSchema.required;
|
|
564
|
-
}
|
|
565
249
|
}
|
|
566
250
|
break;
|
|
567
251
|
case "ZodRecord":
|
|
@@ -569,28 +253,21 @@ Then retry \`${name}\` with the correct format from the skill examples.` : `💡
|
|
|
569
253
|
break;
|
|
570
254
|
case "ZodEnum":
|
|
571
255
|
property.type = "string";
|
|
572
|
-
|
|
573
|
-
if (unwrappedType._def?.values) {
|
|
256
|
+
if (unwrappedType._def?.values)
|
|
574
257
|
property.enum = Array.from(unwrappedType._def.values);
|
|
575
|
-
}
|
|
576
258
|
break;
|
|
577
259
|
case "ZodUnion":
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
const firstOption = unwrappedType._def.options[0];
|
|
581
|
-
const firstType = this.convertZodTypeToJsonSchema(firstOption);
|
|
260
|
+
if (unwrappedType._def?.options?.length > 0) {
|
|
261
|
+
const firstType = this.convertZodTypeToJsonSchema(unwrappedType._def.options[0]);
|
|
582
262
|
property.type = firstType.type;
|
|
583
|
-
if (firstType.enum)
|
|
263
|
+
if (firstType.enum)
|
|
584
264
|
property.enum = firstType.enum;
|
|
585
|
-
}
|
|
586
265
|
}
|
|
587
266
|
else {
|
|
588
267
|
property.type = "string";
|
|
589
268
|
}
|
|
590
269
|
break;
|
|
591
270
|
case "ZodLazy":
|
|
592
|
-
// Unwrap lazy schema (used for recursive types like WhereFilter)
|
|
593
|
-
// Guard against infinite recursion from self-referencing schemas
|
|
594
271
|
if (!this._lazyGuard)
|
|
595
272
|
this._lazyGuard = new Set();
|
|
596
273
|
if (this._lazyGuard.has(unwrappedType)) {
|
|
@@ -609,8 +286,7 @@ Then retry \`${name}\` with the correct format from the skill examples.` : `💡
|
|
|
609
286
|
this._lazyGuard.delete(unwrappedType);
|
|
610
287
|
property.type = "object";
|
|
611
288
|
break;
|
|
612
|
-
default:
|
|
613
|
-
property.type = "string";
|
|
289
|
+
default: property.type = "string";
|
|
614
290
|
}
|
|
615
291
|
return property;
|
|
616
292
|
}
|