@hailer/mcp 0.0.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/commands/tool-builder.md +37 -0
- package/.claude/commands/ws-pull.md +44 -0
- package/.claude/settings.json +8 -0
- package/.claude/settings.local.json +49 -0
- package/.claude/skills/activity-api/SKILL.md +96 -0
- package/.claude/skills/activity-api/references/activity-endpoints.md +845 -0
- package/.claude/skills/add-app-member-skill/SKILL.md +977 -0
- package/.claude/skills/agent-building/SKILL.md +243 -0
- package/.claude/skills/agent-building/references/architecture-patterns.md +446 -0
- package/.claude/skills/agent-building/references/code-examples.md +587 -0
- package/.claude/skills/agent-building/references/implementation-guide.md +619 -0
- package/.claude/skills/app-api/SKILL.md +219 -0
- package/.claude/skills/app-api/references/app-endpoints.md +759 -0
- package/.claude/skills/building-hailer-apps-skill/SKILL.md +548 -0
- package/.claude/skills/create-app-skill/SKILL.md +1101 -0
- package/.claude/skills/create-insight-skill/SKILL.md +1317 -0
- package/.claude/skills/get-insight-data-skill/SKILL.md +1053 -0
- package/.claude/skills/hailer-api/SKILL.md +283 -0
- package/.claude/skills/hailer-api/references/activities.md +620 -0
- package/.claude/skills/hailer-api/references/authentication.md +216 -0
- package/.claude/skills/hailer-api/references/datasets.md +437 -0
- package/.claude/skills/hailer-api/references/files.md +301 -0
- package/.claude/skills/hailer-api/references/insights.md +469 -0
- package/.claude/skills/hailer-api/references/workflows.md +720 -0
- package/.claude/skills/hailer-api/references/workspaces-users.md +445 -0
- package/.claude/skills/insight-api/SKILL.md +185 -0
- package/.claude/skills/insight-api/references/insight-endpoints.md +514 -0
- package/.claude/skills/install-workflow-skill/SKILL.md +1056 -0
- package/.claude/skills/list-apps-skill/SKILL.md +1010 -0
- package/.claude/skills/list-workflows-minimal-skill/SKILL.md +992 -0
- package/.claude/skills/local-first-skill/SKILL.md +570 -0
- package/.claude/skills/mcp-tools/SKILL.md +419 -0
- package/.claude/skills/mcp-tools/references/api-endpoints.md +499 -0
- package/.claude/skills/mcp-tools/references/data-structures.md +554 -0
- package/.claude/skills/mcp-tools/references/implementation-patterns.md +717 -0
- package/.claude/skills/preview-insight-skill/SKILL.md +1290 -0
- package/.claude/skills/publish-hailer-app-skill/SKILL.md +453 -0
- package/.claude/skills/remove-app-member-skill/SKILL.md +671 -0
- package/.claude/skills/remove-app-skill/SKILL.md +985 -0
- package/.claude/skills/remove-insight-skill/SKILL.md +1011 -0
- package/.claude/skills/remove-workflow-skill/SKILL.md +920 -0
- package/.claude/skills/scaffold-hailer-app-skill/SKILL.md +1034 -0
- package/.claude/skills/skill-testing/README.md +137 -0
- package/.claude/skills/skill-testing/SKILL.md +348 -0
- package/.claude/skills/skill-testing/references/test-patterns.md +705 -0
- package/.claude/skills/skill-testing/references/testing-guide.md +603 -0
- package/.claude/skills/skill-testing/references/validation-checklist.md +537 -0
- package/.claude/skills/tool-builder/SKILL.md +328 -0
- package/.claude/skills/update-app-skill/SKILL.md +970 -0
- package/.claude/skills/update-workflow-field-skill/SKILL.md +1098 -0
- package/.env.example +81 -0
- package/.mcp.json +13 -0
- package/README.md +297 -0
- package/dist/app.d.ts +4 -0
- package/dist/app.js +74 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +5 -0
- package/dist/client/adaptive-documentation-bot.d.ts +108 -0
- package/dist/client/adaptive-documentation-bot.js +475 -0
- package/dist/client/adaptive-documentation-types.d.ts +66 -0
- package/dist/client/adaptive-documentation-types.js +9 -0
- package/dist/client/agent-activity-bot.d.ts +51 -0
- package/dist/client/agent-activity-bot.js +166 -0
- package/dist/client/agent-tracker.d.ts +499 -0
- package/dist/client/agent-tracker.js +659 -0
- package/dist/client/description-updater.d.ts +56 -0
- package/dist/client/description-updater.js +259 -0
- package/dist/client/log-parser.d.ts +72 -0
- package/dist/client/log-parser.js +387 -0
- package/dist/client/mcp-client.d.ts +50 -0
- package/dist/client/mcp-client.js +532 -0
- package/dist/client/message-processor.d.ts +35 -0
- package/dist/client/message-processor.js +352 -0
- package/dist/client/multi-bot-manager.d.ts +24 -0
- package/dist/client/multi-bot-manager.js +74 -0
- package/dist/client/providers/anthropic-provider.d.ts +19 -0
- package/dist/client/providers/anthropic-provider.js +631 -0
- package/dist/client/providers/llm-provider.d.ts +47 -0
- package/dist/client/providers/llm-provider.js +367 -0
- package/dist/client/providers/openai-provider.d.ts +23 -0
- package/dist/client/providers/openai-provider.js +621 -0
- package/dist/client/simple-llm-caller.d.ts +19 -0
- package/dist/client/simple-llm-caller.js +100 -0
- package/dist/client/skill-generator.d.ts +81 -0
- package/dist/client/skill-generator.js +386 -0
- package/dist/client/test-adaptive-bot.d.ts +9 -0
- package/dist/client/test-adaptive-bot.js +82 -0
- package/dist/client/token-pricing.d.ts +38 -0
- package/dist/client/token-pricing.js +127 -0
- package/dist/client/token-tracker.d.ts +232 -0
- package/dist/client/token-tracker.js +457 -0
- package/dist/client/token-usage-bot.d.ts +53 -0
- package/dist/client/token-usage-bot.js +153 -0
- package/dist/client/tool-executor.d.ts +69 -0
- package/dist/client/tool-executor.js +159 -0
- package/dist/client/tool-schema-loader.d.ts +60 -0
- package/dist/client/tool-schema-loader.js +178 -0
- package/dist/client/types.d.ts +69 -0
- package/dist/client/types.js +7 -0
- package/dist/config.d.ts +162 -0
- package/dist/config.js +296 -0
- package/dist/core.d.ts +26 -0
- package/dist/core.js +147 -0
- package/dist/lib/context-manager.d.ts +111 -0
- package/dist/lib/context-manager.js +431 -0
- package/dist/lib/logger.d.ts +74 -0
- package/dist/lib/logger.js +277 -0
- package/dist/lib/materialize.d.ts +3 -0
- package/dist/lib/materialize.js +101 -0
- package/dist/lib/normalizedName.d.ts +7 -0
- package/dist/lib/normalizedName.js +48 -0
- package/dist/lib/prompt-length-manager.d.ts +81 -0
- package/dist/lib/prompt-length-manager.js +457 -0
- package/dist/lib/terminal-prompt.d.ts +9 -0
- package/dist/lib/terminal-prompt.js +108 -0
- package/dist/mcp/UserContextCache.d.ts +56 -0
- package/dist/mcp/UserContextCache.js +163 -0
- package/dist/mcp/auth.d.ts +2 -0
- package/dist/mcp/auth.js +29 -0
- package/dist/mcp/hailer-clients.d.ts +42 -0
- package/dist/mcp/hailer-clients.js +246 -0
- package/dist/mcp/signal-handler.d.ts +45 -0
- package/dist/mcp/signal-handler.js +317 -0
- package/dist/mcp/tool-registry.d.ts +100 -0
- package/dist/mcp/tool-registry.js +306 -0
- package/dist/mcp/tools/activity.d.ts +15 -0
- package/dist/mcp/tools/activity.js +955 -0
- package/dist/mcp/tools/app.d.ts +20 -0
- package/dist/mcp/tools/app.js +1488 -0
- package/dist/mcp/tools/discussion.d.ts +19 -0
- package/dist/mcp/tools/discussion.js +950 -0
- package/dist/mcp/tools/file.d.ts +15 -0
- package/dist/mcp/tools/file.js +119 -0
- package/dist/mcp/tools/insight.d.ts +17 -0
- package/dist/mcp/tools/insight.js +806 -0
- package/dist/mcp/tools/skill.d.ts +10 -0
- package/dist/mcp/tools/skill.js +279 -0
- package/dist/mcp/tools/user.d.ts +10 -0
- package/dist/mcp/tools/user.js +108 -0
- package/dist/mcp/tools/workflow-template.d.ts +19 -0
- package/dist/mcp/tools/workflow-template.js +822 -0
- package/dist/mcp/tools/workflow.d.ts +18 -0
- package/dist/mcp/tools/workflow.js +1362 -0
- package/dist/mcp/utils/api-errors.d.ts +45 -0
- package/dist/mcp/utils/api-errors.js +160 -0
- package/dist/mcp/utils/data-transformers.d.ts +102 -0
- package/dist/mcp/utils/data-transformers.js +194 -0
- package/dist/mcp/utils/file-upload.d.ts +33 -0
- package/dist/mcp/utils/file-upload.js +148 -0
- package/dist/mcp/utils/hailer-api-client.d.ts +120 -0
- package/dist/mcp/utils/hailer-api-client.js +323 -0
- package/dist/mcp/utils/index.d.ts +13 -0
- package/dist/mcp/utils/index.js +39 -0
- package/dist/mcp/utils/logger.d.ts +42 -0
- package/dist/mcp/utils/logger.js +103 -0
- package/dist/mcp/utils/types.d.ts +286 -0
- package/dist/mcp/utils/types.js +7 -0
- package/dist/mcp/workspace-cache.d.ts +42 -0
- package/dist/mcp/workspace-cache.js +97 -0
- package/dist/mcp-server.d.ts +42 -0
- package/dist/mcp-server.js +280 -0
- package/package.json +56 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSignalHandler = exports.SignalHandler = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const logger_1 = require("../lib/logger");
|
|
6
|
+
const logger = (0, logger_1.createLogger)({ component: 'signal-handler' });
|
|
7
|
+
class SignalHandler {
|
|
8
|
+
client;
|
|
9
|
+
workspaceCache;
|
|
10
|
+
subscriptions = new Map();
|
|
11
|
+
signalHistory = [];
|
|
12
|
+
maxHistorySize = 100;
|
|
13
|
+
constructor(client, workspaceCache) {
|
|
14
|
+
this.client = client;
|
|
15
|
+
this.workspaceCache = workspaceCache;
|
|
16
|
+
this.initializeSignalHandling();
|
|
17
|
+
}
|
|
18
|
+
initializeSignalHandling() {
|
|
19
|
+
// Register for all signals from the socket client
|
|
20
|
+
this.client.socket.on('signals', (signal) => {
|
|
21
|
+
this.handleIncomingSignal(signal);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
handleIncomingSignal(rawSignal) {
|
|
25
|
+
try {
|
|
26
|
+
const [eventType, eventData] = rawSignal;
|
|
27
|
+
const signal = {
|
|
28
|
+
type: eventType,
|
|
29
|
+
data: eventData,
|
|
30
|
+
timestamp: Date.now(),
|
|
31
|
+
workspaceId: this.workspaceCache?.currentWorkspace._id,
|
|
32
|
+
};
|
|
33
|
+
// Add to history
|
|
34
|
+
this.addToHistory(signal);
|
|
35
|
+
// Dispatch to subscriptions
|
|
36
|
+
this.dispatchSignal(signal);
|
|
37
|
+
// Handle built-in signal processing
|
|
38
|
+
this.processBuiltinSignals(signal);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
logger.error('Failed to handle incoming signal', error);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
addToHistory(signal) {
|
|
45
|
+
this.signalHistory.unshift(signal);
|
|
46
|
+
if (this.signalHistory.length > this.maxHistorySize) {
|
|
47
|
+
this.signalHistory = this.signalHistory.slice(0, this.maxHistorySize);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
dispatchSignal(signal) {
|
|
51
|
+
for (const subscription of this.subscriptions.values()) {
|
|
52
|
+
// Check if signal type matches subscription
|
|
53
|
+
if (!subscription.types.includes(signal.type)) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
// Check workspace filtering
|
|
57
|
+
if (subscription.workspaceId && signal.workspaceId !== subscription.workspaceId) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
subscription.handler(signal);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
logger.error('Signal handler failed', error, { subscriptionId: subscription.id });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
processBuiltinSignals(signal) {
|
|
69
|
+
switch (signal.type) {
|
|
70
|
+
case 'activities.updated':
|
|
71
|
+
this.handleActivityUpdated(signal);
|
|
72
|
+
break;
|
|
73
|
+
case 'activities.created':
|
|
74
|
+
this.handleActivityCreated(signal);
|
|
75
|
+
break;
|
|
76
|
+
case 'discussion.message':
|
|
77
|
+
this.handleDiscussionMessage(signal);
|
|
78
|
+
break;
|
|
79
|
+
case 'workspace.updated':
|
|
80
|
+
this.handleWorkspaceUpdated(signal);
|
|
81
|
+
break;
|
|
82
|
+
case 'messenger.new':
|
|
83
|
+
this.handleMessengerNew(signal);
|
|
84
|
+
break;
|
|
85
|
+
case 'cache.invalidate':
|
|
86
|
+
this.handleCacheInvalidate(signal);
|
|
87
|
+
break;
|
|
88
|
+
default:
|
|
89
|
+
logger.debug('Unhandled signal type received', { signalType: signal.type });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
handleActivityUpdated(signal) {
|
|
93
|
+
logger.debug('Activity updated signal received', {
|
|
94
|
+
activityId: signal.data?._id || signal.data?.id,
|
|
95
|
+
workspaceId: signal.workspaceId
|
|
96
|
+
});
|
|
97
|
+
// TODO: Update workspace cache if we have the activity cached
|
|
98
|
+
// This could invalidate cached activity lists and trigger re-fetching
|
|
99
|
+
// Example: Emit MCP notification for real-time updates
|
|
100
|
+
// this.emitMcpNotification('activity_updated', signal.data);
|
|
101
|
+
}
|
|
102
|
+
handleActivityCreated(signal) {
|
|
103
|
+
logger.debug('Activity created signal received', {
|
|
104
|
+
activityId: signal.data?._id || signal.data?.id,
|
|
105
|
+
workspaceId: signal.workspaceId
|
|
106
|
+
});
|
|
107
|
+
// TODO: Add new activity to workspace cache
|
|
108
|
+
// This could update activity counts and lists
|
|
109
|
+
}
|
|
110
|
+
handleDiscussionMessage(signal) {
|
|
111
|
+
logger.debug('Discussion message signal received', {
|
|
112
|
+
discussionId: signal.data?.discussionId,
|
|
113
|
+
workspaceId: signal.workspaceId
|
|
114
|
+
});
|
|
115
|
+
// TODO: Update message cache if we're tracking discussions
|
|
116
|
+
// This could trigger notifications for AI agents monitoring conversations
|
|
117
|
+
}
|
|
118
|
+
handleWorkspaceUpdated(signal) {
|
|
119
|
+
logger.debug('Workspace updated signal received', {
|
|
120
|
+
workspaceId: signal.workspaceId
|
|
121
|
+
});
|
|
122
|
+
// TODO: Refresh workspace cache
|
|
123
|
+
// This could trigger re-fetching of workspace metadata
|
|
124
|
+
}
|
|
125
|
+
handleMessengerNew(signal) {
|
|
126
|
+
logger.debug('Messenger signal received', {
|
|
127
|
+
workspaceId: signal.workspaceId
|
|
128
|
+
});
|
|
129
|
+
// This is triggered when new messages arrive in discussions
|
|
130
|
+
// The MCP client should be handling this signal for processing user requests
|
|
131
|
+
}
|
|
132
|
+
async handleCacheInvalidate(signal) {
|
|
133
|
+
if (!this.workspaceCache) {
|
|
134
|
+
logger.debug('No workspace cache available, skipping cache invalidation');
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const meta = signal.data || {};
|
|
138
|
+
logger.debug('Cache invalidate signal received', {
|
|
139
|
+
workspaceId: signal.workspaceId,
|
|
140
|
+
meta
|
|
141
|
+
});
|
|
142
|
+
try {
|
|
143
|
+
// Refresh cache by fetching fresh data - pass meta to let backend decide what to return
|
|
144
|
+
const init = await this.client.socket.request('v2.core.init', [meta]);
|
|
145
|
+
// Update workspace cache with fresh data
|
|
146
|
+
if (init.processes) {
|
|
147
|
+
this.workspaceCache.rawInit.processes = init.processes;
|
|
148
|
+
logger.info('Workflows cache refreshed', {
|
|
149
|
+
workflowCount: init.processes.length
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (init.users) {
|
|
153
|
+
this.workspaceCache.users = init.users;
|
|
154
|
+
logger.info('Users cache refreshed', {
|
|
155
|
+
userCount: init.users.length
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
if (init.network) {
|
|
159
|
+
this.workspaceCache.currentWorkspace = init.network;
|
|
160
|
+
logger.info('Current workspace cache refreshed');
|
|
161
|
+
}
|
|
162
|
+
if (init.networks) {
|
|
163
|
+
this.workspaceCache.allWorkspaces = init.networks;
|
|
164
|
+
logger.info('All workspaces cache refreshed', {
|
|
165
|
+
workspaceCount: Object.keys(init.networks).length
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
logger.error('Failed to refresh cache after invalidation signal', error);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Public API for subscription management
|
|
174
|
+
subscribe(id, types, handler, workspaceId) {
|
|
175
|
+
// Check if subscription already exists
|
|
176
|
+
if (this.subscriptions.has(id)) {
|
|
177
|
+
logger.info('Replacing existing signal subscription', { subscriptionId: id });
|
|
178
|
+
}
|
|
179
|
+
const subscription = {
|
|
180
|
+
id,
|
|
181
|
+
types,
|
|
182
|
+
handler,
|
|
183
|
+
workspaceId,
|
|
184
|
+
};
|
|
185
|
+
this.subscriptions.set(id, subscription);
|
|
186
|
+
logger.info('Created signal subscription', {
|
|
187
|
+
subscriptionId: id,
|
|
188
|
+
signalTypes: types,
|
|
189
|
+
workspaceId
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
unsubscribe(id) {
|
|
193
|
+
const removed = this.subscriptions.delete(id);
|
|
194
|
+
if (removed) {
|
|
195
|
+
logger.info('Removed signal subscription', { subscriptionId: id });
|
|
196
|
+
}
|
|
197
|
+
return removed;
|
|
198
|
+
}
|
|
199
|
+
getSignalHistory(types, limit, workspaceId) {
|
|
200
|
+
let filtered = this.signalHistory;
|
|
201
|
+
if (types && types.length > 0) {
|
|
202
|
+
filtered = filtered.filter(signal => types.includes(signal.type));
|
|
203
|
+
}
|
|
204
|
+
if (workspaceId) {
|
|
205
|
+
filtered = filtered.filter(signal => signal.workspaceId === workspaceId);
|
|
206
|
+
}
|
|
207
|
+
if (limit && limit > 0) {
|
|
208
|
+
filtered = filtered.slice(0, limit);
|
|
209
|
+
}
|
|
210
|
+
return filtered;
|
|
211
|
+
}
|
|
212
|
+
getActiveSubscriptions() {
|
|
213
|
+
return Array.from(this.subscriptions.values());
|
|
214
|
+
}
|
|
215
|
+
clearHistory() {
|
|
216
|
+
const previousCount = this.signalHistory.length;
|
|
217
|
+
this.signalHistory = [];
|
|
218
|
+
logger.info('Signal history cleared', { previousHistorySize: previousCount });
|
|
219
|
+
}
|
|
220
|
+
// Utility methods for MCP integration
|
|
221
|
+
createMcpSignalTools(server) {
|
|
222
|
+
// Add MCP tools for signal subscription management
|
|
223
|
+
server.tool("subscribe_to_signals", "š Subscribe to real-time Hailer signals - Get notified of activity updates, new messages, and workspace changes", {
|
|
224
|
+
types: zod_1.z.array(zod_1.z.enum([
|
|
225
|
+
'activities.updated',
|
|
226
|
+
'activities.created',
|
|
227
|
+
'activities.deleted',
|
|
228
|
+
'discussion.message',
|
|
229
|
+
'user.joined',
|
|
230
|
+
'user.left',
|
|
231
|
+
'workspace.updated',
|
|
232
|
+
'process.updated',
|
|
233
|
+
'cache.invalidate'
|
|
234
|
+
])).describe("Signal types to subscribe to"),
|
|
235
|
+
workspaceId: zod_1.z.string().optional().describe("Optional workspace ID to filter signals"),
|
|
236
|
+
}, async (args) => {
|
|
237
|
+
const subscriptionId = `mcp-${Date.now()}`;
|
|
238
|
+
this.subscribe(subscriptionId, args.types, (signal) => {
|
|
239
|
+
// TODO: Send MCP notification to client
|
|
240
|
+
logger.debug('MCP signal notification', {
|
|
241
|
+
subscriptionId,
|
|
242
|
+
signalType: signal.type,
|
|
243
|
+
workspaceId: signal.workspaceId
|
|
244
|
+
});
|
|
245
|
+
}, args.workspaceId);
|
|
246
|
+
return {
|
|
247
|
+
content: [{
|
|
248
|
+
type: "text",
|
|
249
|
+
text: `š Subscribed to real-time signals!\n\n` +
|
|
250
|
+
`š” Subscription ID: ${subscriptionId}\n` +
|
|
251
|
+
`š Signal types: ${args.types.join(", ")}\n` +
|
|
252
|
+
`${args.workspaceId ? `š¢ Workspace filter: ${args.workspaceId}\n` : ''}` +
|
|
253
|
+
`\nš” You'll now receive real-time notifications for these events.\n` +
|
|
254
|
+
`Use get_signal_history to see recent signals.`,
|
|
255
|
+
}],
|
|
256
|
+
};
|
|
257
|
+
});
|
|
258
|
+
server.tool("get_signal_history", "š Get recent real-time signal history - See what's been happening in your workspace", {
|
|
259
|
+
types: zod_1.z.array(zod_1.z.string()).optional().describe("Optional filter for specific signal types"),
|
|
260
|
+
limit: zod_1.z.number().optional().default(20).describe("Maximum number of signals to return"),
|
|
261
|
+
workspaceId: zod_1.z.string().optional().describe("Optional workspace ID to filter signals"),
|
|
262
|
+
}, async (args) => {
|
|
263
|
+
const history = this.getSignalHistory(args.types, args.limit, args.workspaceId);
|
|
264
|
+
const summary = {
|
|
265
|
+
totalSignals: history.length,
|
|
266
|
+
timeRange: history.length > 0 ? {
|
|
267
|
+
newest: new Date(history[0].timestamp).toISOString(),
|
|
268
|
+
oldest: new Date(history[history.length - 1].timestamp).toISOString(),
|
|
269
|
+
} : null,
|
|
270
|
+
typeBreakdown: history.reduce((acc, signal) => {
|
|
271
|
+
acc[signal.type] = (acc[signal.type] || 0) + 1;
|
|
272
|
+
return acc;
|
|
273
|
+
}, {}),
|
|
274
|
+
signals: history.map(signal => ({
|
|
275
|
+
type: signal.type,
|
|
276
|
+
timestamp: new Date(signal.timestamp).toISOString(),
|
|
277
|
+
workspaceId: signal.workspaceId,
|
|
278
|
+
data: signal.data,
|
|
279
|
+
})),
|
|
280
|
+
};
|
|
281
|
+
return {
|
|
282
|
+
content: [{
|
|
283
|
+
type: "text",
|
|
284
|
+
text: `š Signal History (${history.length} signals)\n\n` +
|
|
285
|
+
`š Summary:\n` +
|
|
286
|
+
`${Object.entries(summary.typeBreakdown).map(([type, count]) => `- ${type}: ${count}`).join('\n')}\n\n` +
|
|
287
|
+
`ā° Time range: ${summary.timeRange ? `${summary.timeRange.oldest} ā ${summary.timeRange.newest}` : 'No signals'}\n\n` +
|
|
288
|
+
`š” Real-time signals help you stay updated on workspace activity!\n\n` +
|
|
289
|
+
`${JSON.stringify(summary, null, 2)}`,
|
|
290
|
+
}],
|
|
291
|
+
};
|
|
292
|
+
});
|
|
293
|
+
server.tool("list_signal_subscriptions", "š List active signal subscriptions - See what real-time notifications are configured", {}, async () => {
|
|
294
|
+
const subscriptions = this.getActiveSubscriptions();
|
|
295
|
+
return {
|
|
296
|
+
content: [{
|
|
297
|
+
type: "text",
|
|
298
|
+
text: `š Active Signal Subscriptions (${subscriptions.length})\n\n` +
|
|
299
|
+
(subscriptions.length > 0
|
|
300
|
+
? subscriptions.map((sub, index) => `${index + 1}. **${sub.id}**\n` +
|
|
301
|
+
` - Types: ${sub.types.join(", ")}\n` +
|
|
302
|
+
` - Workspace: ${sub.workspaceId || "All workspaces"}`).join('\n\n')
|
|
303
|
+
: "No active subscriptions") +
|
|
304
|
+
`\n\nš” Use subscribe_to_signals to create new subscriptions.\n` +
|
|
305
|
+
`š” Subscriptions automatically receive real-time updates.`,
|
|
306
|
+
}],
|
|
307
|
+
};
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
exports.SignalHandler = SignalHandler;
|
|
312
|
+
// Factory function for creating signal handler
|
|
313
|
+
const createSignalHandler = (clients, workspaceCache) => {
|
|
314
|
+
return new SignalHandler(clients, workspaceCache);
|
|
315
|
+
};
|
|
316
|
+
exports.createSignalHandler = createSignalHandler;
|
|
317
|
+
//# sourceMappingURL=signal-handler.js.map
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clean Tool Registry with Dependency Injection
|
|
3
|
+
*
|
|
4
|
+
* No singletons, no statics - just clean, explicit tool registration
|
|
5
|
+
* with per-agent access control via dependency injection.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { UserContext } from './UserContextCache';
|
|
9
|
+
/**
|
|
10
|
+
* Tool groups for access control
|
|
11
|
+
* READ: Safe read operations (workflows, activities, schemas)
|
|
12
|
+
* WRITE: Create/update operations (activities, discussions)
|
|
13
|
+
* PLAYGROUND: Admin/dev tools (workflow/app management)
|
|
14
|
+
* NUCLEAR: Destructive operations (remove workflows, apps, insights, templates)
|
|
15
|
+
*/
|
|
16
|
+
export declare enum ToolGroup {
|
|
17
|
+
READ = "read",
|
|
18
|
+
WRITE = "write",
|
|
19
|
+
PLAYGROUND = "playground",
|
|
20
|
+
NUCLEAR = "nuclear"
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Tool definition interface
|
|
24
|
+
*/
|
|
25
|
+
export interface Tool<TSchema extends z.ZodType = z.ZodType> {
|
|
26
|
+
name: string;
|
|
27
|
+
group: ToolGroup;
|
|
28
|
+
description: string;
|
|
29
|
+
schema: TSchema;
|
|
30
|
+
execute: (args: z.infer<TSchema>, context: UserContext) => Promise<any>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Tool definition for MCP protocol (JSON-RPC)
|
|
34
|
+
*/
|
|
35
|
+
export interface ToolDefinition {
|
|
36
|
+
name: string;
|
|
37
|
+
description: string;
|
|
38
|
+
inputSchema: any;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* ToolRegistry - Clean, testable, dependency-injected tool registry
|
|
42
|
+
*
|
|
43
|
+
* NO SINGLETON PATTERN - instantiated explicitly and passed through DI
|
|
44
|
+
*/
|
|
45
|
+
export declare class ToolRegistry {
|
|
46
|
+
private tools;
|
|
47
|
+
private enableNuclearTools;
|
|
48
|
+
constructor(options?: {
|
|
49
|
+
enableNuclearTools?: boolean;
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* Add a tool to the registry
|
|
53
|
+
*/
|
|
54
|
+
addTool(tool: Tool): void;
|
|
55
|
+
/**
|
|
56
|
+
* Get tool definitions with optional filtering
|
|
57
|
+
*
|
|
58
|
+
* @param filter - Optional filter configuration
|
|
59
|
+
* @param filter.allowedGroups - Filter by tool groups
|
|
60
|
+
* @param filter.allowedTools - Explicit whitelist of tool names
|
|
61
|
+
*/
|
|
62
|
+
getToolDefinitions(filter?: {
|
|
63
|
+
allowedGroups?: ToolGroup[];
|
|
64
|
+
allowedTools?: string[];
|
|
65
|
+
}): ToolDefinition[];
|
|
66
|
+
/**
|
|
67
|
+
* Get specific tool schema on-demand
|
|
68
|
+
* Token-efficient: ~200 tokens per tool vs loading all tools upfront
|
|
69
|
+
*/
|
|
70
|
+
getToolSchema(toolName: string): ToolDefinition | null;
|
|
71
|
+
/**
|
|
72
|
+
* Execute tool with validation
|
|
73
|
+
*/
|
|
74
|
+
executeTool(name: string, args: any, context: UserContext): Promise<any>;
|
|
75
|
+
/**
|
|
76
|
+
* Get tool metadata (for access control checks)
|
|
77
|
+
*/
|
|
78
|
+
getTool(name: string): Tool | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Get total tool count
|
|
81
|
+
*/
|
|
82
|
+
getToolCount(): number;
|
|
83
|
+
/**
|
|
84
|
+
* Get statistics for monitoring/debugging
|
|
85
|
+
*/
|
|
86
|
+
getCacheStats(): {
|
|
87
|
+
totalTools: number;
|
|
88
|
+
toolNames: string[];
|
|
89
|
+
byGroup: Record<ToolGroup, number>;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Convert Zod schema to JSON Schema format (required by MCP protocol)
|
|
93
|
+
*/
|
|
94
|
+
private convertZodSchemaToJsonSchema;
|
|
95
|
+
/**
|
|
96
|
+
* Convert a single Zod type to JSON Schema
|
|
97
|
+
*/
|
|
98
|
+
private convertZodTypeToJsonSchema;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=tool-registry.d.ts.map
|