@dsiloed/silo-link 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +350 -0
  3. package/dist/api/dsiloed-client.d.ts +32 -0
  4. package/dist/api/dsiloed-client.d.ts.map +1 -0
  5. package/dist/api/dsiloed-client.js +240 -0
  6. package/dist/api/dsiloed-client.js.map +1 -0
  7. package/dist/cable/action-cable-client.d.ts +28 -0
  8. package/dist/cable/action-cable-client.d.ts.map +1 -0
  9. package/dist/cable/action-cable-client.js +194 -0
  10. package/dist/cable/action-cable-client.js.map +1 -0
  11. package/dist/cable/subscription-manager.d.ts +29 -0
  12. package/dist/cable/subscription-manager.d.ts.map +1 -0
  13. package/dist/cable/subscription-manager.js +125 -0
  14. package/dist/cable/subscription-manager.js.map +1 -0
  15. package/dist/cli/commands.d.ts +4 -0
  16. package/dist/cli/commands.d.ts.map +1 -0
  17. package/dist/cli/commands.js +144 -0
  18. package/dist/cli/commands.js.map +1 -0
  19. package/dist/cli/daemon.d.ts +5 -0
  20. package/dist/cli/daemon.d.ts.map +1 -0
  21. package/dist/cli/daemon.js +35 -0
  22. package/dist/cli/daemon.js.map +1 -0
  23. package/dist/config/config-manager.d.ts +7 -0
  24. package/dist/config/config-manager.d.ts.map +1 -0
  25. package/dist/config/config-manager.js +76 -0
  26. package/dist/config/config-manager.js.map +1 -0
  27. package/dist/config/jwt-generator.d.ts +15 -0
  28. package/dist/config/jwt-generator.d.ts.map +1 -0
  29. package/dist/config/jwt-generator.js +54 -0
  30. package/dist/config/jwt-generator.js.map +1 -0
  31. package/dist/core/bridge.d.ts +37 -0
  32. package/dist/core/bridge.d.ts.map +1 -0
  33. package/dist/core/bridge.js +247 -0
  34. package/dist/core/bridge.js.map +1 -0
  35. package/dist/core/claude-launcher.d.ts +78 -0
  36. package/dist/core/claude-launcher.d.ts.map +1 -0
  37. package/dist/core/claude-launcher.js +352 -0
  38. package/dist/core/claude-launcher.js.map +1 -0
  39. package/dist/core/message-queue.d.ts +47 -0
  40. package/dist/core/message-queue.d.ts.map +1 -0
  41. package/dist/core/message-queue.js +139 -0
  42. package/dist/core/message-queue.js.map +1 -0
  43. package/dist/core/session-manager.d.ts +24 -0
  44. package/dist/core/session-manager.d.ts.map +1 -0
  45. package/dist/core/session-manager.js +111 -0
  46. package/dist/core/session-manager.js.map +1 -0
  47. package/dist/index.d.ts +3 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +4 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/mcp/server.d.ts +27 -0
  52. package/dist/mcp/server.d.ts.map +1 -0
  53. package/dist/mcp/server.js +109 -0
  54. package/dist/mcp/server.js.map +1 -0
  55. package/dist/mcp/tools/register-tools.d.ts +19 -0
  56. package/dist/mcp/tools/register-tools.d.ts.map +1 -0
  57. package/dist/mcp/tools/register-tools.js +385 -0
  58. package/dist/mcp/tools/register-tools.js.map +1 -0
  59. package/dist/types/index.d.ts +74 -0
  60. package/dist/types/index.d.ts.map +1 -0
  61. package/dist/types/index.js +2 -0
  62. package/dist/types/index.js.map +1 -0
  63. package/package.json +57 -0
@@ -0,0 +1,385 @@
1
+ import { z } from 'zod';
2
+ import { randomUUID } from 'node:crypto';
3
+ function getSessionForTransport(transport, sessionManager) {
4
+ const mcpSessionId = transport.sessionId;
5
+ if (!mcpSessionId)
6
+ return undefined;
7
+ return sessionManager.getByMcpSessionId(mcpSessionId);
8
+ }
9
+ /**
10
+ * Update agent session status only if it has actually changed.
11
+ * Avoids redundant API calls (e.g. poll loop firing every 3s).
12
+ */
13
+ function setAgentStatus(session, status, dsiloedClient) {
14
+ if (!session.agentSessionId || session.lastAgentStatus === status)
15
+ return;
16
+ session.lastAgentStatus = status;
17
+ dsiloedClient.updateAgentSessionStatus(session.agentSessionId, status).catch(() => { });
18
+ }
19
+ export function registerTools(server, transport, deps) {
20
+ const { config, sessionManager, messageQueue, dsiloedClient, subscriptionManager, cableClient } = deps;
21
+ // remote_register
22
+ server.tool('remote_register', 'Register this Claude Code session with DSiloed. Creates a conversation and subscribes to real-time messages.', {
23
+ session_name: z.string().optional().describe('Human-readable name for this session'),
24
+ conversation_id: z.number().optional().describe('Existing conversation ID to attach to (skips conversation creation)'),
25
+ }, async ({ session_name, conversation_id }) => {
26
+ const mcpSessionId = transport.sessionId;
27
+ if (!mcpSessionId) {
28
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, reason: 'No MCP session' }) }] };
29
+ }
30
+ // Check if already registered
31
+ const existing = sessionManager.getByMcpSessionId(mcpSessionId);
32
+ if (existing) {
33
+ return {
34
+ content: [{
35
+ type: 'text',
36
+ text: JSON.stringify({
37
+ success: true,
38
+ session_id: existing.sessionId,
39
+ conversation_id: existing.conversationId,
40
+ conversation_url: existing.conversationUrl,
41
+ message: 'Already registered',
42
+ }),
43
+ }],
44
+ };
45
+ }
46
+ try {
47
+ const effectiveConvId = conversation_id;
48
+ const fallbackName = session_name || `Claude Code ${new Date().toLocaleString()}`;
49
+ const conversation = effectiveConvId
50
+ ? await dsiloedClient.getConversation(effectiveConvId)
51
+ : await dsiloedClient.findOrCreateConversation(fallbackName, `Remote Claude Code session started at ${new Date().toISOString()}`);
52
+ // Clear pre-assigned ID after use
53
+ // Use conversation name for the session (not the generic session_name param)
54
+ const name = conversation.name || fallbackName;
55
+ const sessionId = randomUUID();
56
+ const conversationUrl = `${config.host}/conversations/${conversation.id}`;
57
+ const session = {
58
+ sessionId,
59
+ sessionName: name,
60
+ conversationId: conversation.id,
61
+ conversationUrl,
62
+ mcpSessionId,
63
+ createdAt: new Date(),
64
+ lastActivity: new Date(),
65
+ };
66
+ sessionManager.register(session);
67
+ subscriptionManager.subscribe(conversation.id);
68
+ // Drain any messages that arrived before this session registered
69
+ subscriptionManager.drainPendingMessages(conversation.id, sessionId);
70
+ // Create agent session for Mission Control dashboard
71
+ const agentSession = await dsiloedClient.createAgentSession({
72
+ session_type: 'silolink',
73
+ session_name: name,
74
+ llm_conversation_id: conversation.id,
75
+ });
76
+ if (agentSession) {
77
+ session.agentSessionId = agentSession.id;
78
+ setAgentStatus(session, 'agent_session_idle', dsiloedClient);
79
+ }
80
+ return {
81
+ content: [{
82
+ type: 'text',
83
+ text: JSON.stringify({
84
+ success: true,
85
+ session_id: sessionId,
86
+ conversation_id: conversation.id,
87
+ conversation_url: conversationUrl,
88
+ }),
89
+ }],
90
+ };
91
+ }
92
+ catch (err) {
93
+ const message = err instanceof Error ? err.message : String(err);
94
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, reason: message }) }] };
95
+ }
96
+ });
97
+ // remote_load_context — fetch conversation history and resume info for session continuity
98
+ server.tool('remote_load_context', 'Load prior conversation context for session continuity. Returns conversation history and last Claude resume ID (if available). Call this after remote_register when attaching to an existing conversation.', {
99
+ conversation_id: z.number().optional().describe('Conversation ID to load context for (defaults to current session conversation)'),
100
+ limit: z.number().optional().describe('Max number of messages to fetch (default: 50, max: 200)'),
101
+ }, async ({ conversation_id, limit }) => {
102
+ const session = getSessionForTransport(transport, sessionManager);
103
+ const effectiveConvId = conversation_id ?? session?.conversationId;
104
+ if (!effectiveConvId) {
105
+ return {
106
+ content: [{
107
+ type: 'text',
108
+ text: JSON.stringify({ success: false, reason: 'No conversation ID. Either pass conversation_id or call remote_register first.' }),
109
+ }],
110
+ };
111
+ }
112
+ if (session) {
113
+ sessionManager.touchActivity(session.sessionId);
114
+ }
115
+ const effectiveLimit = Math.min(limit ?? 50, 200);
116
+ try {
117
+ // Fetch conversation history and agent sessions in parallel
118
+ const [messages, agentSessions] = await Promise.all([
119
+ dsiloedClient.getMessages(effectiveConvId, effectiveLimit),
120
+ dsiloedClient.getAgentSessionsForConversation(effectiveConvId),
121
+ ]);
122
+ // Find the most recent claude_resume_id from agent session metadata
123
+ let resumeId = null;
124
+ for (const agentSession of agentSessions) {
125
+ const rid = agentSession.metadata?.claude_resume_id;
126
+ if (typeof rid === 'string' && rid.length > 0) {
127
+ resumeId = rid;
128
+ break; // Agent sessions are ordered most-recent-first
129
+ }
130
+ }
131
+ // Format messages for Claude to ingest as context
132
+ const history = messages.map((m) => ({
133
+ id: m.id,
134
+ sender: m.sender_name || (m.message?.role === 'assistant' ? 'Claude' : 'User'),
135
+ role: m.message?.role || 'unknown',
136
+ content: m.message?.content || '',
137
+ timestamp: m.created_at,
138
+ }));
139
+ return {
140
+ content: [{
141
+ type: 'text',
142
+ text: JSON.stringify({
143
+ success: true,
144
+ conversation_id: effectiveConvId,
145
+ resume_id: resumeId,
146
+ message_count: history.length,
147
+ history,
148
+ }),
149
+ }],
150
+ };
151
+ }
152
+ catch (err) {
153
+ const message = err instanceof Error ? err.message : String(err);
154
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, reason: message }) }] };
155
+ }
156
+ });
157
+ // remote_notify
158
+ server.tool('remote_notify', 'Send a notification message to the linked DSiloed conversation. Fire-and-forget.', {
159
+ message: z.string().describe('Message to send'),
160
+ }, async ({ message }) => {
161
+ const session = getSessionForTransport(transport, sessionManager);
162
+ if (!session) {
163
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, reason: 'Not registered. Call remote_register first.' }) }] };
164
+ }
165
+ sessionManager.touchActivity(session.sessionId);
166
+ if (cableClient.getState() !== 'connected') {
167
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, reason: 'WebSocket disconnected' }) }] };
168
+ }
169
+ try {
170
+ const prefixed = `**[Claude Code]** ${message}`;
171
+ const result = await dsiloedClient.postMessage(session.conversationId, prefixed);
172
+ if (result.id) {
173
+ subscriptionManager.trackOutboundMessageId(result.id);
174
+ }
175
+ // Update agent session status and heartbeat on activity
176
+ if (session.agentSessionId) {
177
+ setAgentStatus(session, 'agent_session_working', dsiloedClient);
178
+ dsiloedClient.heartbeatAgentSession(session.agentSessionId).catch(() => { });
179
+ }
180
+ return { content: [{ type: 'text', text: JSON.stringify({ success: true, message_id: result.id }) }] };
181
+ }
182
+ catch (err) {
183
+ const msg = err instanceof Error ? err.message : String(err);
184
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, reason: msg }) }] };
185
+ }
186
+ });
187
+ // remote_ask
188
+ server.tool('remote_ask', 'Post a question to the DSiloed conversation and wait for a reply. Blocks until a response is received or timeout.', {
189
+ question: z.string().describe('Question to ask'),
190
+ timeout: z.number().optional().describe('Timeout in seconds (default: 300)'),
191
+ }, async ({ question, timeout }) => {
192
+ const session = getSessionForTransport(transport, sessionManager);
193
+ if (!session) {
194
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, reason: 'Not registered. Call remote_register first.' }) }] };
195
+ }
196
+ sessionManager.touchActivity(session.sessionId);
197
+ const timeoutMs = (timeout ?? 300) * 1000;
198
+ try {
199
+ const prefixed = `**[Claude Code]** ${question}`;
200
+ const result = await dsiloedClient.postMessage(session.conversationId, prefixed);
201
+ if (result.id) {
202
+ subscriptionManager.trackOutboundMessageId(result.id);
203
+ }
204
+ const reply = await messageQueue.waitForMessage(session.sessionId, timeoutMs);
205
+ return {
206
+ content: [{
207
+ type: 'text',
208
+ text: JSON.stringify({
209
+ success: true,
210
+ response: reply.content,
211
+ sender_name: reply.senderName,
212
+ }),
213
+ }],
214
+ };
215
+ }
216
+ catch (err) {
217
+ const msg = err instanceof Error ? err.message : String(err);
218
+ if (msg.includes('Timeout')) {
219
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, timeout: true }) }] };
220
+ }
221
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, reason: msg }) }] };
222
+ }
223
+ });
224
+ // remote_check_messages
225
+ server.tool('remote_check_messages', 'Non-blocking check for pending inbound messages from DSiloed. Returns all queued messages.', {}, async () => {
226
+ const session = getSessionForTransport(transport, sessionManager);
227
+ if (!session) {
228
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, reason: 'Not registered. Call remote_register first.' }) }] };
229
+ }
230
+ sessionManager.touchActivity(session.sessionId);
231
+ const messages = messageQueue.dequeueAll(session.sessionId);
232
+ return {
233
+ content: [{
234
+ type: 'text',
235
+ text: JSON.stringify({
236
+ success: true,
237
+ messages: messages.map((m) => ({
238
+ id: m.id,
239
+ content: m.content,
240
+ sender_name: m.senderName,
241
+ received_at: m.receivedAt.toISOString(),
242
+ })),
243
+ count: messages.length,
244
+ }),
245
+ }],
246
+ };
247
+ });
248
+ // remote_wait_for_command
249
+ server.tool('remote_wait_for_command', 'Block and wait for the next inbound message from DSiloed. Does not post a question first.', {
250
+ timeout: z.number().optional().describe('Timeout in seconds (default: 600)'),
251
+ }, async ({ timeout }) => {
252
+ const session = getSessionForTransport(transport, sessionManager);
253
+ if (!session) {
254
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, reason: 'Not registered. Call remote_register first.' }) }] };
255
+ }
256
+ sessionManager.touchActivity(session.sessionId);
257
+ const totalTimeoutMs = (timeout ?? 600) * 1000;
258
+ const pollIntervalMs = 5000; // Poll every 5 seconds for bulletproof delivery
259
+ const deadline = Date.now() + totalTimeoutMs;
260
+ // Set status to waiting_for_human while blocking
261
+ if (session.agentSessionId) {
262
+ setAgentStatus(session, 'agent_session_waiting_for_human', dsiloedClient);
263
+ }
264
+ // Short-poll loop: wait in small intervals to minimize cancellation window
265
+ while (Date.now() < deadline) {
266
+ const remainingMs = Math.min(pollIntervalMs, deadline - Date.now());
267
+ if (remainingMs <= 0)
268
+ break;
269
+ try {
270
+ const msg = await messageQueue.waitForMessage(session.sessionId, remainingMs);
271
+ // Set status to working when message received
272
+ if (session.agentSessionId) {
273
+ setAgentStatus(session, 'agent_session_working', dsiloedClient);
274
+ dsiloedClient.heartbeatAgentSession(session.agentSessionId).catch(() => { });
275
+ }
276
+ return {
277
+ content: [{
278
+ type: 'text',
279
+ text: JSON.stringify({
280
+ success: true,
281
+ message: msg.content,
282
+ sender_name: msg.senderName,
283
+ }),
284
+ }],
285
+ };
286
+ }
287
+ catch (err) {
288
+ const errMsg = err instanceof Error ? err.message : String(err);
289
+ if (errMsg.includes('Timeout')) {
290
+ // Short poll timeout — loop and try again
291
+ sessionManager.touchActivity(session.sessionId);
292
+ continue;
293
+ }
294
+ // Non-timeout error — return it
295
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, reason: errMsg }) }] };
296
+ }
297
+ }
298
+ // Overall timeout reached
299
+ if (session.agentSessionId) {
300
+ setAgentStatus(session, 'agent_session_idle', dsiloedClient);
301
+ }
302
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, timeout: true }) }] };
303
+ });
304
+ // remote_poll — non-blocking message check (bulletproof alternative to remote_wait_for_command)
305
+ server.tool('remote_poll', 'Non-blocking check for the next inbound message. Returns immediately with either a message or {pending: true}. Use this in a loop with short sleeps for bulletproof message delivery.', {}, async () => {
306
+ const session = getSessionForTransport(transport, sessionManager);
307
+ if (!session) {
308
+ return { content: [{ type: 'text', text: JSON.stringify({ success: false, reason: 'Not registered. Call remote_register first.' }) }] };
309
+ }
310
+ sessionManager.touchActivity(session.sessionId);
311
+ const msg = messageQueue.poll(session.sessionId);
312
+ if (msg) {
313
+ // Set status to working when message received
314
+ if (session.agentSessionId) {
315
+ setAgentStatus(session, 'agent_session_working', dsiloedClient);
316
+ dsiloedClient.heartbeatAgentSession(session.agentSessionId).catch(() => { });
317
+ }
318
+ return {
319
+ content: [{
320
+ type: 'text',
321
+ text: JSON.stringify({
322
+ success: true,
323
+ message: msg.content,
324
+ sender_name: msg.senderName,
325
+ }),
326
+ }],
327
+ };
328
+ }
329
+ // No message — session is idle, waiting for user input
330
+ if (session.agentSessionId) {
331
+ setAgentStatus(session, 'agent_session_waiting_for_human', dsiloedClient);
332
+ }
333
+ return {
334
+ content: [{
335
+ type: 'text',
336
+ text: JSON.stringify({ success: true, pending: true }),
337
+ }],
338
+ };
339
+ });
340
+ // remote_sessions
341
+ server.tool('remote_sessions', 'List all active Claude Code sessions registered with SiloLink.', {}, async () => {
342
+ const sessions = sessionManager.getAll();
343
+ return {
344
+ content: [{
345
+ type: 'text',
346
+ text: JSON.stringify({
347
+ success: true,
348
+ sessions: sessions.map((s) => ({
349
+ session_id: s.sessionId,
350
+ session_name: s.sessionName,
351
+ conversation_id: s.conversationId,
352
+ conversation_url: s.conversationUrl,
353
+ created_at: s.createdAt.toISOString(),
354
+ last_activity: s.lastActivity.toISOString(),
355
+ })),
356
+ count: sessions.length,
357
+ }),
358
+ }],
359
+ };
360
+ });
361
+ // remote_unregister
362
+ server.tool('remote_unregister', 'Unregister this Claude Code session. Unsubscribes from the conversation channel.', {}, async () => {
363
+ const session = getSessionForTransport(transport, sessionManager);
364
+ if (!session) {
365
+ return { content: [{ type: 'text', text: JSON.stringify({ success: true, message: 'No active session' }) }] };
366
+ }
367
+ // Complete agent session on Mission Control dashboard
368
+ if (session.agentSessionId) {
369
+ await dsiloedClient.completeAgentSession(session.agentSessionId);
370
+ }
371
+ subscriptionManager.unsubscribe(session.conversationId);
372
+ messageQueue.clearSession(session.sessionId);
373
+ sessionManager.unregister(session.sessionId);
374
+ return {
375
+ content: [{
376
+ type: 'text',
377
+ text: JSON.stringify({
378
+ success: true,
379
+ message: `Unregistered session ${session.sessionId}`,
380
+ }),
381
+ }],
382
+ };
383
+ });
384
+ }
385
+ //# sourceMappingURL=register-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/register-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ export interface SiloLinkConfig {
2
+ host: string;
3
+ tenant_id: string;
4
+ shared_key: string;
5
+ user_sub: string;
6
+ mcp_port: number;
7
+ reconnect_interval_ms: number;
8
+ max_reconnect_attempts: number;
9
+ claude_command?: string;
10
+ claude_working_directory?: string;
11
+ claude_auto_respawn?: boolean;
12
+ claude_idle_timeout_ms?: number;
13
+ claude_session_prompt?: string;
14
+ }
15
+ export interface Session {
16
+ sessionId: string;
17
+ sessionName: string;
18
+ conversationId: number;
19
+ conversationUrl: string;
20
+ mcpSessionId: string;
21
+ createdAt: Date;
22
+ lastActivity: Date;
23
+ agentSessionId?: number;
24
+ lastAgentStatus?: string;
25
+ claudeResumeId?: string;
26
+ }
27
+ export interface InboundMessage {
28
+ id: number;
29
+ role: string;
30
+ content: string;
31
+ senderName: string;
32
+ receivedAt: Date;
33
+ }
34
+ export interface CableMessage {
35
+ type: string;
36
+ message?: {
37
+ id: number;
38
+ message: {
39
+ role: string;
40
+ content: string;
41
+ };
42
+ sender_name: string;
43
+ };
44
+ }
45
+ export interface ConversationResponse {
46
+ id: number;
47
+ name: string;
48
+ description?: string;
49
+ }
50
+ export interface MessageResponse {
51
+ id: number;
52
+ message: {
53
+ role: string;
54
+ content: string;
55
+ };
56
+ sender_name?: string;
57
+ created_at: string;
58
+ }
59
+ export interface AgentSessionResponse {
60
+ id: number;
61
+ session_type: string;
62
+ session_name: string | null;
63
+ llm_conversation_id: number | null;
64
+ started_at: string;
65
+ ended_at: string | null;
66
+ last_activity_at: string;
67
+ metadata: Record<string, unknown>;
68
+ current_status: {
69
+ status_iid: string;
70
+ status_description: string;
71
+ } | null;
72
+ }
73
+ export type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
74
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,sBAAsB,EAAE,MAAM,CAAC;IAE/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE;YACP,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,cAAc,EAAE;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,kBAAkB,EAAE,MAAM,CAAC;KAC5B,GAAG,IAAI,CAAC;CACV;AAED,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@dsiloed/silo-link",
3
+ "version": "1.0.0",
4
+ "description": "Claude Code Remote Bridge — connects Claude Code sessions to DSiloed via MCP + ActionCable",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "DSiloed <support@dsiloed.com>",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://gitlab.com/model-api/silo_link.git"
11
+ },
12
+ "homepage": "https://www.dsiloed.com",
13
+ "keywords": [
14
+ "claude",
15
+ "claude-code",
16
+ "mcp",
17
+ "model-context-protocol",
18
+ "remote",
19
+ "bridge",
20
+ "dsiloed",
21
+ "actioncable",
22
+ "ai-agent"
23
+ ],
24
+ "bin": {
25
+ "silolink": "./dist/index.js"
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "scripts": {
33
+ "build": "tsc",
34
+ "dev": "tsx src/index.ts",
35
+ "start": "node dist/index.js",
36
+ "prepublishOnly": "npm run build",
37
+ "test": "vitest run",
38
+ "test:watch": "vitest"
39
+ },
40
+ "dependencies": {
41
+ "@modelcontextprotocol/sdk": "^1.12.1",
42
+ "commander": "^13.1.0",
43
+ "express": "^4.21.2",
44
+ "jsonwebtoken": "^9.0.2",
45
+ "ws": "^8.18.1",
46
+ "zod": "^4.3.6"
47
+ },
48
+ "devDependencies": {
49
+ "@types/express": "^5.0.0",
50
+ "@types/jsonwebtoken": "^9.0.9",
51
+ "@types/node": "^22.15.3",
52
+ "@types/ws": "^8.18.1",
53
+ "tsx": "^4.19.4",
54
+ "typescript": "^5.8.3",
55
+ "vitest": "^3.1.1"
56
+ }
57
+ }