@signaliz/sdk 1.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/README.md +98 -0
- package/dist/chunk-R657OZE7.mjs +543 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +599 -0
- package/dist/cli.mjs +62 -0
- package/dist/index.d.mts +311 -0
- package/dist/index.d.ts +311 -0
- package/dist/index.js +570 -0
- package/dist/index.mjs +8 -0
- package/dist/mcp-config.d.mts +1 -0
- package/dist/mcp-config.d.ts +1 -0
- package/dist/mcp-config.js +687 -0
- package/dist/mcp-config.mjs +126 -0
- package/package.json +35 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
// src/errors.ts
|
|
5
|
+
var SignalizError = class extends Error {
|
|
6
|
+
constructor(data) {
|
|
7
|
+
super(data.message);
|
|
8
|
+
this.name = "SignalizError";
|
|
9
|
+
this.code = data.code;
|
|
10
|
+
this.errorType = data.errorType;
|
|
11
|
+
this.retryAfter = data.retryAfter;
|
|
12
|
+
this.details = data.details;
|
|
13
|
+
}
|
|
14
|
+
get isRetryable() {
|
|
15
|
+
return this.errorType === "rate_limited" || this.errorType === "timeout" || this.errorType === "provider_error";
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
function parseError(status, body) {
|
|
19
|
+
if (body?.error && typeof body.error === "object") {
|
|
20
|
+
return new SignalizError({
|
|
21
|
+
code: body.error.code || `HTTP_${status}`,
|
|
22
|
+
message: body.error.message || `Request failed with status ${status}`,
|
|
23
|
+
errorType: mapErrorType(body.error.code, status),
|
|
24
|
+
retryAfter: body.error.retry_after,
|
|
25
|
+
details: body.error.details
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return new SignalizError({
|
|
29
|
+
code: `HTTP_${status}`,
|
|
30
|
+
message: body?.message || body?.error || `Request failed with status ${status}`,
|
|
31
|
+
errorType: mapErrorType(void 0, status)
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function mapErrorType(code, status) {
|
|
35
|
+
if (code === "RATE_LIMITED" || status === 429) return "rate_limited";
|
|
36
|
+
if (code === "VALIDATION_ERROR" || status === 400) return "validation";
|
|
37
|
+
if (code === "NOT_FOUND" || status === 404) return "not_found";
|
|
38
|
+
if (code === "AUTH_EXPIRED" || status === 401) return "auth_expired";
|
|
39
|
+
if (code === "INSUFFICIENT_CREDITS" || status === 402) return "insufficient_credits";
|
|
40
|
+
if (code === "TIMEOUT" || status === 504) return "timeout";
|
|
41
|
+
if (status >= 500) return "provider_error";
|
|
42
|
+
return "unknown";
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/client.ts
|
|
46
|
+
var DEFAULT_BASE_URL = "https://api.signaliz.com/functions/v1";
|
|
47
|
+
var DEFAULT_TIMEOUT = 12e4;
|
|
48
|
+
var DEFAULT_MAX_RETRIES = 3;
|
|
49
|
+
var HttpClient = class {
|
|
50
|
+
constructor(config) {
|
|
51
|
+
this.baseUrl = config.baseUrl?.replace(/\/$/, "") || DEFAULT_BASE_URL;
|
|
52
|
+
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
53
|
+
this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
54
|
+
this.apiKey = config.apiKey;
|
|
55
|
+
this.clientId = config.clientId;
|
|
56
|
+
this.clientSecret = config.clientSecret;
|
|
57
|
+
if (!this.apiKey && !(this.clientId && this.clientSecret)) {
|
|
58
|
+
throw new Error("Signaliz: provide either apiKey or clientId + clientSecret");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async request(functionName, body, method = "POST") {
|
|
62
|
+
let lastError;
|
|
63
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
64
|
+
try {
|
|
65
|
+
const token = await this.getToken();
|
|
66
|
+
const url = `${this.baseUrl}/${functionName}`;
|
|
67
|
+
const controller = new AbortController();
|
|
68
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
69
|
+
const init = {
|
|
70
|
+
method,
|
|
71
|
+
headers: {
|
|
72
|
+
"Content-Type": "application/json",
|
|
73
|
+
Authorization: `Bearer ${token}`
|
|
74
|
+
},
|
|
75
|
+
signal: controller.signal
|
|
76
|
+
};
|
|
77
|
+
if (method === "POST") {
|
|
78
|
+
init.body = JSON.stringify(body);
|
|
79
|
+
}
|
|
80
|
+
const res = await fetch(url, init);
|
|
81
|
+
clearTimeout(timer);
|
|
82
|
+
if (!res.ok) {
|
|
83
|
+
const errBody = await res.json().catch(() => ({}));
|
|
84
|
+
const err = parseError(res.status, errBody);
|
|
85
|
+
if (err.isRetryable && attempt < this.maxRetries) {
|
|
86
|
+
const wait = err.retryAfter ? err.retryAfter * 1e3 : Math.min(1e3 * Math.pow(2, attempt), 1e4);
|
|
87
|
+
await sleep(wait);
|
|
88
|
+
lastError = err;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
throw err;
|
|
92
|
+
}
|
|
93
|
+
return await res.json();
|
|
94
|
+
} catch (e) {
|
|
95
|
+
if (e instanceof SignalizError) throw e;
|
|
96
|
+
if (e.name === "AbortError") {
|
|
97
|
+
const timeout = new SignalizError({
|
|
98
|
+
code: "TIMEOUT",
|
|
99
|
+
message: `Request timed out after ${this.timeout}ms`,
|
|
100
|
+
errorType: "timeout"
|
|
101
|
+
});
|
|
102
|
+
if (attempt < this.maxRetries) {
|
|
103
|
+
lastError = timeout;
|
|
104
|
+
await sleep(1e3 * Math.pow(2, attempt));
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
throw timeout;
|
|
108
|
+
}
|
|
109
|
+
lastError = e;
|
|
110
|
+
if (attempt < this.maxRetries) {
|
|
111
|
+
await sleep(1e3 * Math.pow(2, attempt));
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
throw lastError || new Error("Request failed after retries");
|
|
117
|
+
}
|
|
118
|
+
/** Convenience wrapper for POST-based edge function calls */
|
|
119
|
+
async post(functionName, body) {
|
|
120
|
+
return this.request(functionName, body, "POST");
|
|
121
|
+
}
|
|
122
|
+
/** JSON-RPC call to the MCP server */
|
|
123
|
+
async mcp(method, params = {}) {
|
|
124
|
+
const token = await this.getToken();
|
|
125
|
+
const url = `${this.baseUrl}/signaliz-mcp`;
|
|
126
|
+
const res = await fetch(url, {
|
|
127
|
+
method: "POST",
|
|
128
|
+
headers: {
|
|
129
|
+
"Content-Type": "application/json",
|
|
130
|
+
Authorization: `Bearer ${token}`
|
|
131
|
+
},
|
|
132
|
+
body: JSON.stringify({
|
|
133
|
+
jsonrpc: "2.0",
|
|
134
|
+
id: Date.now(),
|
|
135
|
+
method,
|
|
136
|
+
params
|
|
137
|
+
})
|
|
138
|
+
});
|
|
139
|
+
const data = await res.json();
|
|
140
|
+
if (data.error) {
|
|
141
|
+
throw new SignalizError({
|
|
142
|
+
code: data.error.code?.toString() || "MCP_ERROR",
|
|
143
|
+
message: data.error.message || "MCP request failed",
|
|
144
|
+
errorType: "unknown"
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
if (data.result?.content?.[0]?.text) {
|
|
148
|
+
try {
|
|
149
|
+
return JSON.parse(data.result.content[0].text);
|
|
150
|
+
} catch {
|
|
151
|
+
return data.result.content[0].text;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (data.result?.structuredContent) {
|
|
155
|
+
return data.result.structuredContent;
|
|
156
|
+
}
|
|
157
|
+
return data.result;
|
|
158
|
+
}
|
|
159
|
+
async getToken() {
|
|
160
|
+
if (this.apiKey) return this.apiKey;
|
|
161
|
+
if (this.accessToken) return this.accessToken;
|
|
162
|
+
const res = await fetch("https://api.signaliz.com/token", {
|
|
163
|
+
method: "POST",
|
|
164
|
+
headers: { "Content-Type": "application/json" },
|
|
165
|
+
body: JSON.stringify({
|
|
166
|
+
grant_type: "client_credentials",
|
|
167
|
+
client_id: this.clientId,
|
|
168
|
+
client_secret: this.clientSecret
|
|
169
|
+
})
|
|
170
|
+
});
|
|
171
|
+
if (!res.ok) {
|
|
172
|
+
throw new SignalizError({
|
|
173
|
+
code: "AUTH_FAILED",
|
|
174
|
+
message: "Failed to obtain access token",
|
|
175
|
+
errorType: "auth_expired"
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
const data = await res.json();
|
|
179
|
+
this.accessToken = data.access_token;
|
|
180
|
+
return this.accessToken;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
function sleep(ms) {
|
|
184
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/resources/emails.ts
|
|
188
|
+
var Emails = class {
|
|
189
|
+
constructor(client) {
|
|
190
|
+
this.client = client;
|
|
191
|
+
}
|
|
192
|
+
/** Find and verify an email address for a person at a company */
|
|
193
|
+
async find(params) {
|
|
194
|
+
const body = {
|
|
195
|
+
company_domain: params.companyDomain
|
|
196
|
+
};
|
|
197
|
+
if (params.fullName) body.full_name = params.fullName;
|
|
198
|
+
if (params.firstName) body.first_name = params.firstName;
|
|
199
|
+
if (params.lastName) body.last_name = params.lastName;
|
|
200
|
+
if (params.linkedinUrl) body.linkedin_url = params.linkedinUrl;
|
|
201
|
+
if (params.companyName) body.company_name = params.companyName;
|
|
202
|
+
const data = await this.client.mcp("tools/call", {
|
|
203
|
+
name: "find_emails_with_verification",
|
|
204
|
+
arguments: body
|
|
205
|
+
});
|
|
206
|
+
return {
|
|
207
|
+
email: data.email,
|
|
208
|
+
firstName: data.first_name,
|
|
209
|
+
lastName: data.last_name,
|
|
210
|
+
confidence: data.confidence ?? data.confidence_score ?? 0,
|
|
211
|
+
verificationStatus: data.verification_status ?? "unknown",
|
|
212
|
+
providerUsed: data.provider_used ?? data.source ?? "unknown"
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
/** Verify a single email address */
|
|
216
|
+
async verify(email) {
|
|
217
|
+
const data = await this.client.mcp("tools/call", {
|
|
218
|
+
name: "verify_email",
|
|
219
|
+
arguments: { email }
|
|
220
|
+
});
|
|
221
|
+
return {
|
|
222
|
+
email: data.email ?? email,
|
|
223
|
+
isValid: data.is_valid ?? false,
|
|
224
|
+
isDeliverable: data.is_deliverable ?? false,
|
|
225
|
+
isCatchAll: data.is_catch_all ?? false,
|
|
226
|
+
provider: data.provider,
|
|
227
|
+
confidenceScore: data.confidence_score ?? 0,
|
|
228
|
+
verificationSource: data.verification_source
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// src/resources/signals.ts
|
|
234
|
+
var Signals = class {
|
|
235
|
+
constructor(client) {
|
|
236
|
+
this.client = client;
|
|
237
|
+
}
|
|
238
|
+
/** Enrich a company with actionable signals (V1) */
|
|
239
|
+
async enrich(params) {
|
|
240
|
+
const args = {
|
|
241
|
+
company_name: params.companyName
|
|
242
|
+
};
|
|
243
|
+
if (params.domain) args.domain = params.domain;
|
|
244
|
+
if (params.researchPrompt) args.research_prompt = params.researchPrompt;
|
|
245
|
+
if (params.signalTypes) args.signal_types = params.signalTypes;
|
|
246
|
+
const data = await this.client.mcp("tools/call", {
|
|
247
|
+
name: "enrich_company_signals",
|
|
248
|
+
arguments: args
|
|
249
|
+
});
|
|
250
|
+
return {
|
|
251
|
+
companyName: data.company_name ?? params.companyName,
|
|
252
|
+
signals: (data.signals ?? []).map((s) => ({
|
|
253
|
+
title: s.title,
|
|
254
|
+
signalType: s.signal_type,
|
|
255
|
+
confidenceScore: s.confidence_score ?? 0,
|
|
256
|
+
detectedAt: s.detected_at ?? "",
|
|
257
|
+
url: s.url,
|
|
258
|
+
content: s.content ?? ""
|
|
259
|
+
})),
|
|
260
|
+
totalSignals: data.total_signals ?? data.signals?.length ?? 0,
|
|
261
|
+
fromCache: data.from_cache ?? false
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
/** Enrich a company with actionable signals (V2 — clean response + online mode) */
|
|
265
|
+
async enrichV2(params) {
|
|
266
|
+
const args = {};
|
|
267
|
+
if (params.companyName) args.company_name = params.companyName;
|
|
268
|
+
if (params.domain) args.domain = params.domain;
|
|
269
|
+
if (params.companyDomain) args.company_domain = params.companyDomain;
|
|
270
|
+
if (params.researchPrompt) args.research_prompt = params.researchPrompt;
|
|
271
|
+
if (params.signalTypes) args.signal_types = params.signalTypes;
|
|
272
|
+
if (params.online !== void 0) args.online = params.online;
|
|
273
|
+
if (params.targetSignalCount) args.target_signal_count = params.targetSignalCount;
|
|
274
|
+
if (params.lookbackDays) args.lookback_days = params.lookbackDays;
|
|
275
|
+
if (params.model) args.model = params.model;
|
|
276
|
+
if (params.enableDeepSearch) args.enable_deep_search = params.enableDeepSearch;
|
|
277
|
+
if (params.enableOutreachIntelligence) args.enable_outreach_intelligence = params.enableOutreachIntelligence;
|
|
278
|
+
if (params.enablePredictiveIntelligence) args.enable_predictive_intelligence = params.enablePredictiveIntelligence;
|
|
279
|
+
if (params.icpId) args.icp_id = params.icpId;
|
|
280
|
+
if (params.cacheTtlHours !== void 0) args.cache_ttl_hours = params.cacheTtlHours;
|
|
281
|
+
if (params.skipCache) args.skip_cache = params.skipCache;
|
|
282
|
+
const data = await this.client.post("company-signal-enrichment-v2", args);
|
|
283
|
+
return {
|
|
284
|
+
success: data.success ?? false,
|
|
285
|
+
company: {
|
|
286
|
+
name: data.company?.name ?? null,
|
|
287
|
+
domain: data.company?.domain ?? null
|
|
288
|
+
},
|
|
289
|
+
signals: (data.signals ?? []).map((s) => ({
|
|
290
|
+
id: s.id,
|
|
291
|
+
title: s.title,
|
|
292
|
+
type: s.type,
|
|
293
|
+
content: s.content ?? "",
|
|
294
|
+
date: s.date ?? null,
|
|
295
|
+
sourceUrl: s.source_url ?? null,
|
|
296
|
+
sourceType: s.source_type ?? "unknown",
|
|
297
|
+
confidence: s.confidence ?? null
|
|
298
|
+
})),
|
|
299
|
+
signalCount: data.signal_count ?? 0,
|
|
300
|
+
intelligence: data.intelligence ? {
|
|
301
|
+
executiveSummary: data.intelligence.executive_summary ?? null,
|
|
302
|
+
keyThemes: data.intelligence.key_themes ?? [],
|
|
303
|
+
relevanceScore: data.intelligence.relevance_score ?? null,
|
|
304
|
+
outreach: data.intelligence.outreach ? {
|
|
305
|
+
urgencyScore: data.intelligence.outreach.urgency_score ?? null,
|
|
306
|
+
bestTiming: data.intelligence.outreach.best_timing ?? null,
|
|
307
|
+
primaryAngle: data.intelligence.outreach.primary_angle ?? null,
|
|
308
|
+
ctas: data.intelligence.outreach.ctas ? {
|
|
309
|
+
soft: data.intelligence.outreach.ctas.soft,
|
|
310
|
+
direct: data.intelligence.outreach.ctas.direct,
|
|
311
|
+
valueFirst: data.intelligence.outreach.ctas.value_first
|
|
312
|
+
} : null,
|
|
313
|
+
conversationStarters: data.intelligence.outreach.conversation_starters ?? []
|
|
314
|
+
} : null,
|
|
315
|
+
predictions: (data.intelligence.predictions ?? []).map((p) => ({
|
|
316
|
+
prediction: p.prediction,
|
|
317
|
+
confidence: p.confidence,
|
|
318
|
+
targetPersona: p.target_persona ?? null,
|
|
319
|
+
recommendedAction: p.recommended_action ?? null
|
|
320
|
+
}))
|
|
321
|
+
} : null,
|
|
322
|
+
credits: {
|
|
323
|
+
charged: data.credits?.charged ?? 0,
|
|
324
|
+
billingType: data.credits?.billing_type ?? "unknown",
|
|
325
|
+
breakdown: {
|
|
326
|
+
signalCredits: data.credits?.breakdown?.signal_credits ?? 0,
|
|
327
|
+
modelCostUsd: data.credits?.breakdown?.model_cost_usd ?? 0,
|
|
328
|
+
modelCredits: data.credits?.breakdown?.model_credits ?? 0,
|
|
329
|
+
explanation: data.credits?.breakdown?.explanation ?? ""
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
metadata: {
|
|
333
|
+
version: data.metadata?.version ?? "",
|
|
334
|
+
model: data.metadata?.model ?? "",
|
|
335
|
+
online: data.metadata?.online ?? false,
|
|
336
|
+
processingTimeMs: data.metadata?.processing_time_ms ?? 0
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
// src/resources/systems.ts
|
|
343
|
+
var Systems = class {
|
|
344
|
+
constructor(client) {
|
|
345
|
+
this.client = client;
|
|
346
|
+
}
|
|
347
|
+
/** Create a new pipeline/system */
|
|
348
|
+
async create(params) {
|
|
349
|
+
const data = await this.client.mcp("tools/call", {
|
|
350
|
+
name: "create_system",
|
|
351
|
+
arguments: {
|
|
352
|
+
name: params.name,
|
|
353
|
+
description: params.description,
|
|
354
|
+
capabilities: params.capabilities,
|
|
355
|
+
field_mappings: params.fieldMappings
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
return {
|
|
359
|
+
id: data.system_id ?? data.id,
|
|
360
|
+
name: data.name ?? params.name,
|
|
361
|
+
status: data.status ?? "created",
|
|
362
|
+
nodeCount: data.node_count ?? params.capabilities.length,
|
|
363
|
+
createdAt: data.created_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
/** Run a system with input data */
|
|
367
|
+
async run(systemId, params) {
|
|
368
|
+
const data = await this.client.mcp("tools/call", {
|
|
369
|
+
name: "run_system",
|
|
370
|
+
arguments: {
|
|
371
|
+
system_id: systemId,
|
|
372
|
+
input_data: params.data,
|
|
373
|
+
async: params.async ?? false
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
return {
|
|
377
|
+
runId: data.run_id ?? data.id,
|
|
378
|
+
status: data.status ?? "running",
|
|
379
|
+
totalRows: data.total_rows,
|
|
380
|
+
completedRows: data.completed_rows ?? 0,
|
|
381
|
+
creditsUsed: data.credits_used ?? 0
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
/** Get a system by ID */
|
|
385
|
+
async get(systemId) {
|
|
386
|
+
const data = await this.client.mcp("tools/call", {
|
|
387
|
+
name: "get_system",
|
|
388
|
+
arguments: { system_id: systemId }
|
|
389
|
+
});
|
|
390
|
+
return {
|
|
391
|
+
id: data.id ?? systemId,
|
|
392
|
+
name: data.name,
|
|
393
|
+
status: data.status,
|
|
394
|
+
nodeCount: data.node_count ?? 0,
|
|
395
|
+
createdAt: data.created_at
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
/** List all systems */
|
|
399
|
+
async list() {
|
|
400
|
+
const data = await this.client.mcp("tools/call", {
|
|
401
|
+
name: "list_systems",
|
|
402
|
+
arguments: {}
|
|
403
|
+
});
|
|
404
|
+
return (data.systems ?? data ?? []).map((s) => ({
|
|
405
|
+
id: s.id,
|
|
406
|
+
name: s.name,
|
|
407
|
+
status: s.status,
|
|
408
|
+
nodeCount: s.node_count ?? 0,
|
|
409
|
+
createdAt: s.created_at
|
|
410
|
+
}));
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
// src/resources/runs.ts
|
|
415
|
+
var Runs = class {
|
|
416
|
+
constructor(client) {
|
|
417
|
+
this.client = client;
|
|
418
|
+
}
|
|
419
|
+
/** Get run status */
|
|
420
|
+
async get(runId) {
|
|
421
|
+
const data = await this.client.mcp("tools/call", {
|
|
422
|
+
name: "get_run_results",
|
|
423
|
+
arguments: { run_id: runId }
|
|
424
|
+
});
|
|
425
|
+
return {
|
|
426
|
+
runId: data.run_id ?? runId,
|
|
427
|
+
status: data.status,
|
|
428
|
+
totalRows: data.total_rows,
|
|
429
|
+
completedRows: data.completed_rows ?? 0,
|
|
430
|
+
creditsUsed: data.credits_used ?? 0
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
/** Poll until a run completes. Returns final result. */
|
|
434
|
+
async waitForCompletion(runId, pollIntervalMs = 2e3) {
|
|
435
|
+
while (true) {
|
|
436
|
+
const run = await this.get(runId);
|
|
437
|
+
if (["completed", "failed", "cancelled", "crashed", "timed_out", "interrupted", "system_failure"].includes(run.status)) {
|
|
438
|
+
return run;
|
|
439
|
+
}
|
|
440
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Stream run progress as an async iterator.
|
|
445
|
+
* Usage: for await (const event of signaliz.runs.stream(runId)) { ... }
|
|
446
|
+
*/
|
|
447
|
+
async *stream(runId, pollIntervalMs = 1500) {
|
|
448
|
+
let lastCompleted = -1;
|
|
449
|
+
while (true) {
|
|
450
|
+
const run = await this.get(runId);
|
|
451
|
+
const event = {
|
|
452
|
+
runId,
|
|
453
|
+
status: run.status,
|
|
454
|
+
completedRows: run.completedRows ?? 0,
|
|
455
|
+
totalRows: run.totalRows ?? 0,
|
|
456
|
+
creditsUsed: run.creditsUsed ?? 0
|
|
457
|
+
};
|
|
458
|
+
if (event.completedRows !== lastCompleted) {
|
|
459
|
+
lastCompleted = event.completedRows;
|
|
460
|
+
yield event;
|
|
461
|
+
}
|
|
462
|
+
if (["completed", "failed", "cancelled"].includes(run.status)) {
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
// src/resources/http.ts
|
|
471
|
+
var Http = class {
|
|
472
|
+
constructor(client) {
|
|
473
|
+
this.client = client;
|
|
474
|
+
}
|
|
475
|
+
/** Proxy an HTTP request through Signaliz */
|
|
476
|
+
async request(params) {
|
|
477
|
+
const data = await this.client.mcp("tools/call", {
|
|
478
|
+
name: "http_request",
|
|
479
|
+
arguments: {
|
|
480
|
+
url: params.url,
|
|
481
|
+
method: params.method,
|
|
482
|
+
headers: params.headers,
|
|
483
|
+
body: params.body ? JSON.stringify(params.body) : void 0
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
return {
|
|
487
|
+
statusCode: data.status_code ?? data.statusCode ?? 200,
|
|
488
|
+
headers: data.headers ?? {},
|
|
489
|
+
body: data.body ?? data.response ?? data
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
// src/index.ts
|
|
495
|
+
var Signaliz = class {
|
|
496
|
+
constructor(config) {
|
|
497
|
+
this.client = new HttpClient(config);
|
|
498
|
+
this.emails = new Emails(this.client);
|
|
499
|
+
this.signals = new Signals(this.client);
|
|
500
|
+
this.systems = new Systems(this.client);
|
|
501
|
+
this.runs = new Runs(this.client);
|
|
502
|
+
this.http = new Http(this.client);
|
|
503
|
+
}
|
|
504
|
+
/** Get current workspace info including credits */
|
|
505
|
+
async getWorkspace() {
|
|
506
|
+
const data = await this.client.mcp("tools/call", {
|
|
507
|
+
name: "get_workspace",
|
|
508
|
+
arguments: {}
|
|
509
|
+
});
|
|
510
|
+
return {
|
|
511
|
+
id: data.workspace_id ?? data.id,
|
|
512
|
+
name: data.workspace_name ?? data.name ?? "Unknown",
|
|
513
|
+
creditsRemaining: data.credits_remaining ?? data.credits ?? 0,
|
|
514
|
+
plan: data.plan ?? "unknown"
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
/** List all available MCP tools */
|
|
518
|
+
async listTools() {
|
|
519
|
+
const data = await this.client.mcp("tools/list", {});
|
|
520
|
+
const tools = data?.tools ?? data ?? [];
|
|
521
|
+
return tools.map((t) => ({
|
|
522
|
+
name: t.name,
|
|
523
|
+
description: (t.description ?? "").slice(0, 120),
|
|
524
|
+
category: t.annotations?.category,
|
|
525
|
+
costCredits: t.annotations?.cost_credits
|
|
526
|
+
}));
|
|
527
|
+
}
|
|
528
|
+
/** Discover tools by natural language query */
|
|
529
|
+
async discover(query, category) {
|
|
530
|
+
const data = await this.client.mcp("tools/call", {
|
|
531
|
+
name: "discover_capabilities",
|
|
532
|
+
arguments: { query, category }
|
|
533
|
+
});
|
|
534
|
+
return (data.matches ?? []).map((m) => ({
|
|
535
|
+
name: m.tool,
|
|
536
|
+
description: m.description,
|
|
537
|
+
category: m.category,
|
|
538
|
+
costCredits: m.cost_credits
|
|
539
|
+
}));
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
// src/cli.ts
|
|
544
|
+
var apiKey = process.env.SIGNALIZ_API_KEY;
|
|
545
|
+
async function main() {
|
|
546
|
+
const command = process.argv[2];
|
|
547
|
+
if (!apiKey) {
|
|
548
|
+
console.error("\u274C SIGNALIZ_API_KEY environment variable is required.");
|
|
549
|
+
console.error(" Set it with: export SIGNALIZ_API_KEY=sk_...");
|
|
550
|
+
process.exit(1);
|
|
551
|
+
}
|
|
552
|
+
const signaliz = new Signaliz({ apiKey });
|
|
553
|
+
switch (command) {
|
|
554
|
+
case "test": {
|
|
555
|
+
try {
|
|
556
|
+
const ws = await signaliz.getWorkspace();
|
|
557
|
+
console.log(`\u2705 Connected to workspace: ${ws.name} (${ws.creditsRemaining.toLocaleString()} credits remaining)`);
|
|
558
|
+
} catch (e) {
|
|
559
|
+
console.error(`\u274C Connection failed: ${e.message}`);
|
|
560
|
+
process.exit(1);
|
|
561
|
+
}
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
564
|
+
case "tools": {
|
|
565
|
+
try {
|
|
566
|
+
const tools = await signaliz.listTools();
|
|
567
|
+
console.log(`
|
|
568
|
+
\u{1F4CB} Available tools (${tools.length}):
|
|
569
|
+
`);
|
|
570
|
+
console.log("Name".padEnd(40) + "Category".padEnd(15) + "Credits".padEnd(10) + "Description");
|
|
571
|
+
console.log("\u2500".repeat(100));
|
|
572
|
+
for (const t of tools) {
|
|
573
|
+
console.log(
|
|
574
|
+
(t.name ?? "").padEnd(40) + (t.category ?? "-").padEnd(15) + String(t.costCredits ?? "-").padEnd(10) + (t.description ?? "").slice(0, 60)
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
} catch (e) {
|
|
578
|
+
console.error(`\u274C Failed to list tools: ${e.message}`);
|
|
579
|
+
process.exit(1);
|
|
580
|
+
}
|
|
581
|
+
break;
|
|
582
|
+
}
|
|
583
|
+
default:
|
|
584
|
+
console.log(`
|
|
585
|
+
Signaliz CLI v1.0.0
|
|
586
|
+
|
|
587
|
+
Usage:
|
|
588
|
+
signaliz test Verify API connectivity
|
|
589
|
+
signaliz tools List all available MCP tools
|
|
590
|
+
|
|
591
|
+
Environment:
|
|
592
|
+
SIGNALIZ_API_KEY Your API key (required)
|
|
593
|
+
`);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
main().catch((e) => {
|
|
597
|
+
console.error(e);
|
|
598
|
+
process.exit(1);
|
|
599
|
+
});
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
Signaliz
|
|
4
|
+
} from "./chunk-R657OZE7.mjs";
|
|
5
|
+
|
|
6
|
+
// src/cli.ts
|
|
7
|
+
var apiKey = process.env.SIGNALIZ_API_KEY;
|
|
8
|
+
async function main() {
|
|
9
|
+
const command = process.argv[2];
|
|
10
|
+
if (!apiKey) {
|
|
11
|
+
console.error("\u274C SIGNALIZ_API_KEY environment variable is required.");
|
|
12
|
+
console.error(" Set it with: export SIGNALIZ_API_KEY=sk_...");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
const signaliz = new Signaliz({ apiKey });
|
|
16
|
+
switch (command) {
|
|
17
|
+
case "test": {
|
|
18
|
+
try {
|
|
19
|
+
const ws = await signaliz.getWorkspace();
|
|
20
|
+
console.log(`\u2705 Connected to workspace: ${ws.name} (${ws.creditsRemaining.toLocaleString()} credits remaining)`);
|
|
21
|
+
} catch (e) {
|
|
22
|
+
console.error(`\u274C Connection failed: ${e.message}`);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
case "tools": {
|
|
28
|
+
try {
|
|
29
|
+
const tools = await signaliz.listTools();
|
|
30
|
+
console.log(`
|
|
31
|
+
\u{1F4CB} Available tools (${tools.length}):
|
|
32
|
+
`);
|
|
33
|
+
console.log("Name".padEnd(40) + "Category".padEnd(15) + "Credits".padEnd(10) + "Description");
|
|
34
|
+
console.log("\u2500".repeat(100));
|
|
35
|
+
for (const t of tools) {
|
|
36
|
+
console.log(
|
|
37
|
+
(t.name ?? "").padEnd(40) + (t.category ?? "-").padEnd(15) + String(t.costCredits ?? "-").padEnd(10) + (t.description ?? "").slice(0, 60)
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
} catch (e) {
|
|
41
|
+
console.error(`\u274C Failed to list tools: ${e.message}`);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
default:
|
|
47
|
+
console.log(`
|
|
48
|
+
Signaliz CLI v1.0.0
|
|
49
|
+
|
|
50
|
+
Usage:
|
|
51
|
+
signaliz test Verify API connectivity
|
|
52
|
+
signaliz tools List all available MCP tools
|
|
53
|
+
|
|
54
|
+
Environment:
|
|
55
|
+
SIGNALIZ_API_KEY Your API key (required)
|
|
56
|
+
`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
main().catch((e) => {
|
|
60
|
+
console.error(e);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
});
|