@rainfall-devkit/sdk 0.1.6 → 0.1.8
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/dist/chunk-RA3HDYF4.mjs +778 -0
- package/dist/cli/index.js +75 -12
- package/dist/cli/index.mjs +51 -11
- package/dist/index.js +3 -2
- package/dist/index.mjs +1 -1
- package/dist/mcp.js +3 -2
- package/dist/mcp.mjs +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,778 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var RainfallError = class _RainfallError extends Error {
|
|
3
|
+
constructor(message, code, statusCode, details) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.statusCode = statusCode;
|
|
7
|
+
this.details = details;
|
|
8
|
+
this.name = "RainfallError";
|
|
9
|
+
Object.setPrototypeOf(this, _RainfallError.prototype);
|
|
10
|
+
}
|
|
11
|
+
toJSON() {
|
|
12
|
+
return {
|
|
13
|
+
name: this.name,
|
|
14
|
+
code: this.code,
|
|
15
|
+
message: this.message,
|
|
16
|
+
statusCode: this.statusCode,
|
|
17
|
+
details: this.details
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var AuthenticationError = class _AuthenticationError extends RainfallError {
|
|
22
|
+
constructor(message = "Invalid API key", details) {
|
|
23
|
+
super(message, "AUTHENTICATION_ERROR", 401, details);
|
|
24
|
+
this.name = "AuthenticationError";
|
|
25
|
+
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
var RateLimitError = class _RateLimitError extends RainfallError {
|
|
29
|
+
retryAfter;
|
|
30
|
+
limit;
|
|
31
|
+
remaining;
|
|
32
|
+
resetAt;
|
|
33
|
+
constructor(message = "Rate limit exceeded", retryAfter = 60, limit = 0, remaining = 0, resetAt) {
|
|
34
|
+
super(message, "RATE_LIMIT_ERROR", 429, { retryAfter, limit, remaining });
|
|
35
|
+
this.name = "RateLimitError";
|
|
36
|
+
this.retryAfter = retryAfter;
|
|
37
|
+
this.limit = limit;
|
|
38
|
+
this.remaining = remaining;
|
|
39
|
+
this.resetAt = resetAt || new Date(Date.now() + retryAfter * 1e3);
|
|
40
|
+
Object.setPrototypeOf(this, _RateLimitError.prototype);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var ValidationError = class _ValidationError extends RainfallError {
|
|
44
|
+
constructor(message, details) {
|
|
45
|
+
super(message, "VALIDATION_ERROR", 400, details);
|
|
46
|
+
this.name = "ValidationError";
|
|
47
|
+
Object.setPrototypeOf(this, _ValidationError.prototype);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
var NotFoundError = class _NotFoundError extends RainfallError {
|
|
51
|
+
constructor(resource, identifier) {
|
|
52
|
+
super(
|
|
53
|
+
`${resource}${identifier ? ` '${identifier}'` : ""} not found`,
|
|
54
|
+
"NOT_FOUND_ERROR",
|
|
55
|
+
404,
|
|
56
|
+
{ resource, identifier }
|
|
57
|
+
);
|
|
58
|
+
this.name = "NotFoundError";
|
|
59
|
+
Object.setPrototypeOf(this, _NotFoundError.prototype);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
var ServerError = class _ServerError extends RainfallError {
|
|
63
|
+
constructor(message = "Internal server error", statusCode = 500) {
|
|
64
|
+
super(message, "SERVER_ERROR", statusCode);
|
|
65
|
+
this.name = "ServerError";
|
|
66
|
+
Object.setPrototypeOf(this, _ServerError.prototype);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
var TimeoutError = class _TimeoutError extends RainfallError {
|
|
70
|
+
constructor(timeoutMs) {
|
|
71
|
+
super(`Request timed out after ${timeoutMs}ms`, "TIMEOUT_ERROR", 408);
|
|
72
|
+
this.name = "TimeoutError";
|
|
73
|
+
Object.setPrototypeOf(this, _TimeoutError.prototype);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
var NetworkError = class _NetworkError extends RainfallError {
|
|
77
|
+
constructor(message = "Network error", details) {
|
|
78
|
+
super(message, "NETWORK_ERROR", void 0, details);
|
|
79
|
+
this.name = "NetworkError";
|
|
80
|
+
Object.setPrototypeOf(this, _NetworkError.prototype);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var ToolNotFoundError = class _ToolNotFoundError extends RainfallError {
|
|
84
|
+
constructor(toolId) {
|
|
85
|
+
super(`Tool '${toolId}' not found`, "TOOL_NOT_FOUND", 404, { toolId });
|
|
86
|
+
this.name = "ToolNotFoundError";
|
|
87
|
+
Object.setPrototypeOf(this, _ToolNotFoundError.prototype);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
function parseErrorResponse(response, data) {
|
|
91
|
+
const statusCode = response.status;
|
|
92
|
+
if (statusCode === 429) {
|
|
93
|
+
const retryAfter = parseInt(response.headers.get("retry-after") || "60", 10);
|
|
94
|
+
const limit = parseInt(response.headers.get("x-ratelimit-limit") || "0", 10);
|
|
95
|
+
const remaining = parseInt(response.headers.get("x-ratelimit-remaining") || "0", 10);
|
|
96
|
+
const resetHeader = response.headers.get("x-ratelimit-reset");
|
|
97
|
+
const resetAt = resetHeader ? new Date(parseInt(resetHeader, 10) * 1e3) : void 0;
|
|
98
|
+
return new RateLimitError(
|
|
99
|
+
typeof data === "object" && data && "message" in data ? String(data.message) : "Rate limit exceeded",
|
|
100
|
+
retryAfter,
|
|
101
|
+
limit,
|
|
102
|
+
remaining,
|
|
103
|
+
resetAt
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
switch (statusCode) {
|
|
107
|
+
case 401:
|
|
108
|
+
return new AuthenticationError(
|
|
109
|
+
typeof data === "object" && data && "message" in data ? String(data.message) : "Invalid API key"
|
|
110
|
+
);
|
|
111
|
+
case 404:
|
|
112
|
+
return new NotFoundError(
|
|
113
|
+
typeof data === "object" && data && "resource" in data ? String(data.resource) : "Resource",
|
|
114
|
+
typeof data === "object" && data && "identifier" in data ? String(data.identifier) : void 0
|
|
115
|
+
);
|
|
116
|
+
case 400:
|
|
117
|
+
return new ValidationError(
|
|
118
|
+
typeof data === "object" && data && "message" in data ? String(data.message) : "Invalid request",
|
|
119
|
+
typeof data === "object" && data && "details" in data ? data.details : void 0
|
|
120
|
+
);
|
|
121
|
+
case 500:
|
|
122
|
+
case 502:
|
|
123
|
+
case 503:
|
|
124
|
+
case 504:
|
|
125
|
+
return new ServerError(
|
|
126
|
+
typeof data === "object" && data && "message" in data ? String(data.message) : "Server error",
|
|
127
|
+
statusCode
|
|
128
|
+
);
|
|
129
|
+
default:
|
|
130
|
+
return new RainfallError(
|
|
131
|
+
typeof data === "object" && data && "message" in data ? String(data.message) : `HTTP ${statusCode}`,
|
|
132
|
+
"UNKNOWN_ERROR",
|
|
133
|
+
statusCode,
|
|
134
|
+
typeof data === "object" ? data : void 0
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/client.ts
|
|
140
|
+
var DEFAULT_BASE_URL = "https://olympic-api.pragma-digital.org/v1";
|
|
141
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
142
|
+
var DEFAULT_RETRIES = 3;
|
|
143
|
+
var DEFAULT_RETRY_DELAY = 1e3;
|
|
144
|
+
var RainfallClient = class {
|
|
145
|
+
apiKey;
|
|
146
|
+
baseUrl;
|
|
147
|
+
defaultTimeout;
|
|
148
|
+
defaultRetries;
|
|
149
|
+
defaultRetryDelay;
|
|
150
|
+
lastRateLimitInfo;
|
|
151
|
+
subscriberId;
|
|
152
|
+
constructor(config) {
|
|
153
|
+
this.apiKey = config.apiKey;
|
|
154
|
+
this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
|
|
155
|
+
this.defaultTimeout = config.timeout || DEFAULT_TIMEOUT;
|
|
156
|
+
this.defaultRetries = config.retries ?? DEFAULT_RETRIES;
|
|
157
|
+
this.defaultRetryDelay = config.retryDelay || DEFAULT_RETRY_DELAY;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get the last rate limit info from the API
|
|
161
|
+
*/
|
|
162
|
+
getRateLimitInfo() {
|
|
163
|
+
return this.lastRateLimitInfo;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Make an authenticated request to the Rainfall API
|
|
167
|
+
*/
|
|
168
|
+
async request(path, options = {}, requestOptions) {
|
|
169
|
+
const timeout = requestOptions?.timeout ?? this.defaultTimeout;
|
|
170
|
+
const maxRetries = requestOptions?.retries ?? this.defaultRetries;
|
|
171
|
+
const retryDelay = requestOptions?.retryDelay ?? this.defaultRetryDelay;
|
|
172
|
+
const url = `${this.baseUrl}${path}`;
|
|
173
|
+
const method = options.method || "GET";
|
|
174
|
+
let lastError;
|
|
175
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
176
|
+
try {
|
|
177
|
+
const controller = new AbortController();
|
|
178
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
179
|
+
const response = await fetch(url, {
|
|
180
|
+
method,
|
|
181
|
+
headers: {
|
|
182
|
+
"x-api-key": this.apiKey,
|
|
183
|
+
"Content-Type": "application/json",
|
|
184
|
+
"Accept": "application/json",
|
|
185
|
+
"X-Rainfall-SDK-Version": "0.1.0",
|
|
186
|
+
...options.headers
|
|
187
|
+
},
|
|
188
|
+
body: options.body ? JSON.stringify(options.body) : void 0,
|
|
189
|
+
signal: controller.signal
|
|
190
|
+
});
|
|
191
|
+
clearTimeout(timeoutId);
|
|
192
|
+
const limit = response.headers.get("x-ratelimit-limit");
|
|
193
|
+
const remaining = response.headers.get("x-ratelimit-remaining");
|
|
194
|
+
const reset = response.headers.get("x-ratelimit-reset");
|
|
195
|
+
if (limit && remaining && reset) {
|
|
196
|
+
this.lastRateLimitInfo = {
|
|
197
|
+
limit: parseInt(limit, 10),
|
|
198
|
+
remaining: parseInt(remaining, 10),
|
|
199
|
+
resetAt: new Date(parseInt(reset, 10) * 1e3)
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
let data;
|
|
203
|
+
const contentType = response.headers.get("content-type");
|
|
204
|
+
if (contentType?.includes("application/json")) {
|
|
205
|
+
data = await response.json();
|
|
206
|
+
} else {
|
|
207
|
+
data = await response.text();
|
|
208
|
+
}
|
|
209
|
+
if (!response.ok) {
|
|
210
|
+
throw parseErrorResponse(response, data);
|
|
211
|
+
}
|
|
212
|
+
return data;
|
|
213
|
+
} catch (error) {
|
|
214
|
+
if (error instanceof RainfallError) {
|
|
215
|
+
if (error.statusCode && error.statusCode >= 400 && error.statusCode < 500 && error.statusCode !== 429) {
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
if (error.statusCode === 401) {
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
223
|
+
lastError = new TimeoutError(timeout);
|
|
224
|
+
} else if (error instanceof TypeError) {
|
|
225
|
+
lastError = new NetworkError(error.message);
|
|
226
|
+
} else {
|
|
227
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
228
|
+
}
|
|
229
|
+
if (attempt >= maxRetries) {
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
const delay = retryDelay * Math.pow(2, attempt) + Math.random() * 1e3;
|
|
233
|
+
await this.sleep(delay);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
throw lastError || new RainfallError("Request failed", "REQUEST_FAILED");
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Execute a tool/node by ID
|
|
240
|
+
*/
|
|
241
|
+
async executeTool(toolId, params, options) {
|
|
242
|
+
const subscriberId = await this.ensureSubscriberId();
|
|
243
|
+
const response = await this.request(`/olympic/subscribers/${subscriberId}/nodes/${toolId}`, {
|
|
244
|
+
method: "POST",
|
|
245
|
+
body: params || {}
|
|
246
|
+
}, options);
|
|
247
|
+
return response.result;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* List all available tools
|
|
251
|
+
*/
|
|
252
|
+
async listTools() {
|
|
253
|
+
const subscriberId = await this.ensureSubscriberId();
|
|
254
|
+
const result = await this.request(`/olympic/subscribers/${subscriberId}/nodes/_utils/node-descriptions`);
|
|
255
|
+
if (result.success && result.nodes) {
|
|
256
|
+
return Object.values(result.nodes);
|
|
257
|
+
}
|
|
258
|
+
const legacyResult = await this.request(`/olympic/subscribers/${subscriberId}/nodes/_utils/node-list`);
|
|
259
|
+
if (legacyResult.keys && Array.isArray(legacyResult.keys)) {
|
|
260
|
+
return legacyResult.keys.map((key) => ({
|
|
261
|
+
id: key,
|
|
262
|
+
name: key,
|
|
263
|
+
description: "",
|
|
264
|
+
category: "general"
|
|
265
|
+
}));
|
|
266
|
+
}
|
|
267
|
+
return legacyResult.nodes || [];
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Get tool schema/parameters
|
|
271
|
+
*/
|
|
272
|
+
async getToolSchema(toolId) {
|
|
273
|
+
const subscriberId = await this.ensureSubscriberId();
|
|
274
|
+
const response = await this.request(`/olympic/subscribers/${subscriberId}/nodes/${toolId}/params`);
|
|
275
|
+
return response.params;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Get subscriber info
|
|
279
|
+
*/
|
|
280
|
+
async getMe() {
|
|
281
|
+
const result = await this.request("/olympic/subscribers/me");
|
|
282
|
+
if (result.subscriber?.id) {
|
|
283
|
+
this.subscriberId = result.subscriber.id;
|
|
284
|
+
}
|
|
285
|
+
const subscriber = result.subscriber;
|
|
286
|
+
return {
|
|
287
|
+
id: subscriber.id,
|
|
288
|
+
name: subscriber.name,
|
|
289
|
+
email: subscriber.google_id,
|
|
290
|
+
billingStatus: subscriber.billing_status,
|
|
291
|
+
plan: subscriber.billing_status,
|
|
292
|
+
usage: {
|
|
293
|
+
callsThisMonth: subscriber.metadata?.usage?.callsThisMonth ?? 0,
|
|
294
|
+
callsLimit: subscriber.metadata?.usage?.callsLimit ?? 5e3
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Ensure we have a subscriber ID, fetching it if necessary
|
|
300
|
+
*/
|
|
301
|
+
async ensureSubscriberId() {
|
|
302
|
+
if (this.subscriberId) {
|
|
303
|
+
return this.subscriberId;
|
|
304
|
+
}
|
|
305
|
+
const me = await this.getMe();
|
|
306
|
+
if (!me.id) {
|
|
307
|
+
throw new RainfallError("Failed to get subscriber ID", "NO_SUBSCRIBER_ID");
|
|
308
|
+
}
|
|
309
|
+
return me.id;
|
|
310
|
+
}
|
|
311
|
+
sleep(ms) {
|
|
312
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
// src/namespaces/integrations.ts
|
|
317
|
+
function createIntegrations(client) {
|
|
318
|
+
return new IntegrationsNamespace(client);
|
|
319
|
+
}
|
|
320
|
+
var IntegrationsNamespace = class {
|
|
321
|
+
constructor(client) {
|
|
322
|
+
this.client = client;
|
|
323
|
+
}
|
|
324
|
+
get github() {
|
|
325
|
+
return {
|
|
326
|
+
issues: {
|
|
327
|
+
create: (params) => this.client.executeTool("github-create-issue", params),
|
|
328
|
+
list: (params) => this.client.executeTool("github-list-issues", params),
|
|
329
|
+
get: (params) => this.client.executeTool("github-get-issue", params),
|
|
330
|
+
update: (params) => this.client.executeTool("github-update-issue", params),
|
|
331
|
+
addComment: (params) => this.client.executeTool("github-add-issue-comment", params)
|
|
332
|
+
},
|
|
333
|
+
repos: {
|
|
334
|
+
get: (params) => this.client.executeTool("github-get-repository", params),
|
|
335
|
+
listBranches: (params) => this.client.executeTool("github-list-branches", params)
|
|
336
|
+
},
|
|
337
|
+
pullRequests: {
|
|
338
|
+
list: (params) => this.client.executeTool("github-list-pull-requests", params),
|
|
339
|
+
get: (params) => this.client.executeTool("github-get-pull-request", params)
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
get notion() {
|
|
344
|
+
return {
|
|
345
|
+
pages: {
|
|
346
|
+
create: (params) => this.client.executeTool("notion-pages-create", params),
|
|
347
|
+
retrieve: (params) => this.client.executeTool("notion-pages-retrieve", params),
|
|
348
|
+
update: (params) => this.client.executeTool("notion-pages-update", params)
|
|
349
|
+
},
|
|
350
|
+
databases: {
|
|
351
|
+
query: (params) => this.client.executeTool("notion-databases-query", params),
|
|
352
|
+
retrieve: (params) => this.client.executeTool("notion-databases-retrieve", params)
|
|
353
|
+
},
|
|
354
|
+
blocks: {
|
|
355
|
+
appendChildren: (params) => this.client.executeTool("notion-blocks-append-children", params),
|
|
356
|
+
retrieveChildren: (params) => this.client.executeTool("notion-blocks-retrieve-children", params)
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
get linear() {
|
|
361
|
+
return {
|
|
362
|
+
issues: {
|
|
363
|
+
create: (params) => this.client.executeTool("linear-core-issueCreate", params),
|
|
364
|
+
list: (params) => this.client.executeTool("linear-core-issues", params),
|
|
365
|
+
get: (params) => this.client.executeTool("linear-core-issue", params),
|
|
366
|
+
update: (params) => this.client.executeTool("linear-core-issueUpdate", params),
|
|
367
|
+
archive: (params) => this.client.executeTool("linear-core-issueArchive", params)
|
|
368
|
+
},
|
|
369
|
+
teams: {
|
|
370
|
+
list: () => this.client.executeTool("linear-core-teams", {})
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
get slack() {
|
|
375
|
+
return {
|
|
376
|
+
messages: {
|
|
377
|
+
send: (params) => this.client.executeTool("slack-core-postMessage", params),
|
|
378
|
+
list: (params) => this.client.executeTool("slack-core-listMessages", params)
|
|
379
|
+
},
|
|
380
|
+
channels: {
|
|
381
|
+
list: () => this.client.executeTool("slack-core-listChannels", {})
|
|
382
|
+
},
|
|
383
|
+
users: {
|
|
384
|
+
list: () => this.client.executeTool("slack-core-listUsers", {})
|
|
385
|
+
},
|
|
386
|
+
reactions: {
|
|
387
|
+
add: (params) => this.client.executeTool("slack-core-addReaction", params)
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
get figma() {
|
|
392
|
+
return {
|
|
393
|
+
files: {
|
|
394
|
+
get: (params) => this.client.executeTool("figma-files-getFile", { fileKey: params.fileKey }),
|
|
395
|
+
getNodes: (params) => this.client.executeTool("figma-files-getFileNodes", { fileKey: params.fileKey, nodeIds: params.nodeIds }),
|
|
396
|
+
getImages: (params) => this.client.executeTool("figma-files-getFileImage", { fileKey: params.fileKey, nodeIds: params.nodeIds, format: params.format }),
|
|
397
|
+
getComments: (params) => this.client.executeTool("figma-comments-getFileComments", { fileKey: params.fileKey }),
|
|
398
|
+
postComment: (params) => this.client.executeTool("figma-comments-postComment", { fileKey: params.fileKey, message: params.message, nodeId: params.nodeId })
|
|
399
|
+
},
|
|
400
|
+
projects: {
|
|
401
|
+
list: (params) => this.client.executeTool("figma-projects-getTeamProjects", { teamId: params.teamId }),
|
|
402
|
+
getFiles: (params) => this.client.executeTool("figma-projects-getProjectFiles", { projectId: params.projectId })
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
get stripe() {
|
|
407
|
+
return {
|
|
408
|
+
customers: {
|
|
409
|
+
create: (params) => this.client.executeTool("stripe-customers-create", params),
|
|
410
|
+
retrieve: (params) => this.client.executeTool("stripe-customers-retrieve", { customerId: params.customerId }),
|
|
411
|
+
update: (params) => this.client.executeTool("stripe-customers-update", params),
|
|
412
|
+
listPaymentMethods: (params) => this.client.executeTool("stripe-customers-list-payment-methods", { customerId: params.customerId })
|
|
413
|
+
},
|
|
414
|
+
paymentIntents: {
|
|
415
|
+
create: (params) => this.client.executeTool("stripe-payment-intents-create", params),
|
|
416
|
+
retrieve: (params) => this.client.executeTool("stripe-payment-intents-retrieve", { paymentIntentId: params.paymentIntentId }),
|
|
417
|
+
confirm: (params) => this.client.executeTool("stripe-payment-intents-confirm", { paymentIntentId: params.paymentIntentId })
|
|
418
|
+
},
|
|
419
|
+
subscriptions: {
|
|
420
|
+
create: (params) => this.client.executeTool("stripe-subscriptions-create", params),
|
|
421
|
+
retrieve: (params) => this.client.executeTool("stripe-subscriptions-retrieve", { subscriptionId: params.subscriptionId }),
|
|
422
|
+
cancel: (params) => this.client.executeTool("stripe-subscriptions-cancel", { subscriptionId: params.subscriptionId })
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
// src/namespaces/memory.ts
|
|
429
|
+
function createMemory(client) {
|
|
430
|
+
return {
|
|
431
|
+
create: (params) => client.executeTool("memory-create", params),
|
|
432
|
+
get: (params) => client.executeTool("memory-get", { memoryId: params.memoryId }),
|
|
433
|
+
recall: (params) => client.executeTool("memory-recall", params),
|
|
434
|
+
list: (params) => client.executeTool("memory-list", params ?? {}),
|
|
435
|
+
update: (params) => client.executeTool("memory-update", params),
|
|
436
|
+
delete: (params) => client.executeTool("memory-delete", { memoryId: params.memoryId })
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// src/namespaces/articles.ts
|
|
441
|
+
function createArticles(client) {
|
|
442
|
+
return {
|
|
443
|
+
search: (params) => client.executeTool("article-search", params),
|
|
444
|
+
create: (params) => client.executeTool("article-create", params),
|
|
445
|
+
createFromUrl: (params) => client.executeTool("article-create-from-url", params),
|
|
446
|
+
fetch: (params) => client.executeTool("article-fetch", params),
|
|
447
|
+
recent: (params) => client.executeTool("article-recent", params ?? {}),
|
|
448
|
+
relevant: (params) => client.executeTool("article-relevant-news", params),
|
|
449
|
+
summarize: (params) => client.executeTool("article-summarize", params),
|
|
450
|
+
extractTopics: (params) => client.executeTool("article-topic-extractor", params)
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// src/namespaces/web.ts
|
|
455
|
+
function createWeb(client) {
|
|
456
|
+
return {
|
|
457
|
+
search: {
|
|
458
|
+
exa: (params) => client.executeTool("exa-web-search", params),
|
|
459
|
+
perplexity: (params) => client.executeTool("perplexity-search", params)
|
|
460
|
+
},
|
|
461
|
+
fetch: (params) => client.executeTool("web-fetch", params),
|
|
462
|
+
htmlToMarkdown: (params) => client.executeTool("html-to-markdown-converter", params),
|
|
463
|
+
extractHtml: (params) => client.executeTool("extract-html-selector", params)
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// src/namespaces/ai.ts
|
|
468
|
+
function createAI(client) {
|
|
469
|
+
return {
|
|
470
|
+
embeddings: {
|
|
471
|
+
document: (params) => client.executeTool("jina-document-embedding", params),
|
|
472
|
+
query: (params) => client.executeTool("jina-query-embedding", params),
|
|
473
|
+
image: (params) => client.executeTool("jina-image-embedding", { image: params.imageBase64 })
|
|
474
|
+
},
|
|
475
|
+
image: {
|
|
476
|
+
generate: (params) => client.executeTool("image-generation", params)
|
|
477
|
+
},
|
|
478
|
+
ocr: (params) => client.executeTool("ocr-text-extraction", { image: params.imageBase64 }),
|
|
479
|
+
vision: (params) => client.executeTool("llama-scout-vision", { image: params.imageBase64, prompt: params.prompt }),
|
|
480
|
+
chat: (params) => client.executeTool("xai-chat-completions", params),
|
|
481
|
+
complete: (params) => client.executeTool("fim", params),
|
|
482
|
+
classify: (params) => client.executeTool("jina-document-classifier", params),
|
|
483
|
+
segment: (params) => client.executeTool("jina-text-segmenter", params)
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// src/namespaces/data.ts
|
|
488
|
+
function createData(client) {
|
|
489
|
+
return {
|
|
490
|
+
csv: {
|
|
491
|
+
query: (params) => client.executeTool("query-csv", params),
|
|
492
|
+
convert: (params) => client.executeTool("csv-convert", params)
|
|
493
|
+
},
|
|
494
|
+
scripts: {
|
|
495
|
+
create: (params) => client.executeTool("create-saved-script", params),
|
|
496
|
+
execute: (params) => client.executeTool("execute-saved-script", params),
|
|
497
|
+
list: () => client.executeTool("list-saved-scripts", {}),
|
|
498
|
+
update: (params) => client.executeTool("update-saved-script", params),
|
|
499
|
+
delete: (params) => client.executeTool("delete-saved-script", params)
|
|
500
|
+
},
|
|
501
|
+
similarity: {
|
|
502
|
+
search: (params) => client.executeTool("duck-db-similarity-search", params),
|
|
503
|
+
duckDbSearch: (params) => client.executeTool("duck-db-similarity-search", params)
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// src/namespaces/utils.ts
|
|
509
|
+
function createUtils(client) {
|
|
510
|
+
return {
|
|
511
|
+
mermaid: (params) => client.executeTool("mermaid-diagram-generator", { mermaid: params.diagram }),
|
|
512
|
+
documentConvert: (params) => client.executeTool("document-format-converter", {
|
|
513
|
+
base64: `data:${params.mimeType};base64,${Buffer.from(params.document).toString("base64")}`,
|
|
514
|
+
format: params.format
|
|
515
|
+
}),
|
|
516
|
+
regex: {
|
|
517
|
+
match: (params) => client.executeTool("regex-match", params),
|
|
518
|
+
replace: (params) => client.executeTool("regex-replace", params)
|
|
519
|
+
},
|
|
520
|
+
jsonExtract: (params) => client.executeTool("json-extract", params),
|
|
521
|
+
digest: (params) => client.executeTool("digest-generator", { text: params.data }),
|
|
522
|
+
monteCarlo: (params) => client.executeTool("monte-carlo-simulation", params)
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// src/sdk.ts
|
|
527
|
+
var Rainfall = class {
|
|
528
|
+
client;
|
|
529
|
+
_integrations;
|
|
530
|
+
_memory;
|
|
531
|
+
_articles;
|
|
532
|
+
_web;
|
|
533
|
+
_ai;
|
|
534
|
+
_data;
|
|
535
|
+
_utils;
|
|
536
|
+
constructor(config) {
|
|
537
|
+
this.client = new RainfallClient(config);
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Integrations namespace - GitHub, Notion, Linear, Slack, Figma, Stripe
|
|
541
|
+
*
|
|
542
|
+
* @example
|
|
543
|
+
* ```typescript
|
|
544
|
+
* // GitHub
|
|
545
|
+
* await rainfall.integrations.github.issues.create({
|
|
546
|
+
* owner: 'facebook',
|
|
547
|
+
* repo: 'react',
|
|
548
|
+
* title: 'Bug report'
|
|
549
|
+
* });
|
|
550
|
+
*
|
|
551
|
+
* // Slack
|
|
552
|
+
* await rainfall.integrations.slack.messages.send({
|
|
553
|
+
* channelId: 'C123456',
|
|
554
|
+
* text: 'Hello team!'
|
|
555
|
+
* });
|
|
556
|
+
*
|
|
557
|
+
* // Linear
|
|
558
|
+
* const issues = await rainfall.integrations.linear.issues.list();
|
|
559
|
+
* ```
|
|
560
|
+
*/
|
|
561
|
+
get integrations() {
|
|
562
|
+
if (!this._integrations) {
|
|
563
|
+
this._integrations = createIntegrations(this.client);
|
|
564
|
+
}
|
|
565
|
+
return this._integrations;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Memory namespace - Semantic memory storage and retrieval
|
|
569
|
+
*
|
|
570
|
+
* @example
|
|
571
|
+
* ```typescript
|
|
572
|
+
* // Store a memory
|
|
573
|
+
* await rainfall.memory.create({
|
|
574
|
+
* content: 'User prefers dark mode',
|
|
575
|
+
* keywords: ['preference', 'ui']
|
|
576
|
+
* });
|
|
577
|
+
*
|
|
578
|
+
* // Recall similar memories
|
|
579
|
+
* const memories = await rainfall.memory.recall({
|
|
580
|
+
* query: 'user preferences',
|
|
581
|
+
* topK: 5
|
|
582
|
+
* });
|
|
583
|
+
* ```
|
|
584
|
+
*/
|
|
585
|
+
get memory() {
|
|
586
|
+
if (!this._memory) {
|
|
587
|
+
this._memory = createMemory(this.client);
|
|
588
|
+
}
|
|
589
|
+
return this._memory;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Articles namespace - News aggregation and article management
|
|
593
|
+
*
|
|
594
|
+
* @example
|
|
595
|
+
* ```typescript
|
|
596
|
+
* // Search news
|
|
597
|
+
* const articles = await rainfall.articles.search({
|
|
598
|
+
* query: 'artificial intelligence'
|
|
599
|
+
* });
|
|
600
|
+
*
|
|
601
|
+
* // Create from URL
|
|
602
|
+
* const article = await rainfall.articles.createFromUrl({
|
|
603
|
+
* url: 'https://example.com/article'
|
|
604
|
+
* });
|
|
605
|
+
*
|
|
606
|
+
* // Summarize
|
|
607
|
+
* const summary = await rainfall.articles.summarize({
|
|
608
|
+
* text: article.content
|
|
609
|
+
* });
|
|
610
|
+
* ```
|
|
611
|
+
*/
|
|
612
|
+
get articles() {
|
|
613
|
+
if (!this._articles) {
|
|
614
|
+
this._articles = createArticles(this.client);
|
|
615
|
+
}
|
|
616
|
+
return this._articles;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Web namespace - Web search, scraping, and content extraction
|
|
620
|
+
*
|
|
621
|
+
* @example
|
|
622
|
+
* ```typescript
|
|
623
|
+
* // Search with Exa
|
|
624
|
+
* const results = await rainfall.web.search.exa({
|
|
625
|
+
* query: 'latest AI research'
|
|
626
|
+
* });
|
|
627
|
+
*
|
|
628
|
+
* // Fetch and convert
|
|
629
|
+
* const html = await rainfall.web.fetch({ url: 'https://example.com' });
|
|
630
|
+
* const markdown = await rainfall.web.htmlToMarkdown({ html });
|
|
631
|
+
*
|
|
632
|
+
* // Extract specific elements
|
|
633
|
+
* const links = await rainfall.web.extractHtml({
|
|
634
|
+
* html,
|
|
635
|
+
* selector: 'a[href]'
|
|
636
|
+
* });
|
|
637
|
+
* ```
|
|
638
|
+
*/
|
|
639
|
+
get web() {
|
|
640
|
+
if (!this._web) {
|
|
641
|
+
this._web = createWeb(this.client);
|
|
642
|
+
}
|
|
643
|
+
return this._web;
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* AI namespace - Embeddings, image generation, OCR, vision, chat
|
|
647
|
+
*
|
|
648
|
+
* @example
|
|
649
|
+
* ```typescript
|
|
650
|
+
* // Generate embeddings
|
|
651
|
+
* const embedding = await rainfall.ai.embeddings.document({
|
|
652
|
+
* text: 'Hello world'
|
|
653
|
+
* });
|
|
654
|
+
*
|
|
655
|
+
* // Generate image
|
|
656
|
+
* const image = await rainfall.ai.image.generate({
|
|
657
|
+
* prompt: 'A serene mountain landscape'
|
|
658
|
+
* });
|
|
659
|
+
*
|
|
660
|
+
* // OCR
|
|
661
|
+
* const text = await rainfall.ai.ocr({ imageBase64: '...' });
|
|
662
|
+
*
|
|
663
|
+
* // Chat
|
|
664
|
+
* const response = await rainfall.ai.chat({
|
|
665
|
+
* messages: [{ role: 'user', content: 'Hello!' }]
|
|
666
|
+
* });
|
|
667
|
+
* ```
|
|
668
|
+
*/
|
|
669
|
+
get ai() {
|
|
670
|
+
if (!this._ai) {
|
|
671
|
+
this._ai = createAI(this.client);
|
|
672
|
+
}
|
|
673
|
+
return this._ai;
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Data namespace - CSV processing, scripts, similarity search
|
|
677
|
+
*
|
|
678
|
+
* @example
|
|
679
|
+
* ```typescript
|
|
680
|
+
* // Query CSV with SQL
|
|
681
|
+
* const results = await rainfall.data.csv.query({
|
|
682
|
+
* sql: 'SELECT * FROM data WHERE value > 100'
|
|
683
|
+
* });
|
|
684
|
+
*
|
|
685
|
+
* // Execute saved script
|
|
686
|
+
* const result = await rainfall.data.scripts.execute({
|
|
687
|
+
* name: 'my-script',
|
|
688
|
+
* params: { input: 'data' }
|
|
689
|
+
* });
|
|
690
|
+
* ```
|
|
691
|
+
*/
|
|
692
|
+
get data() {
|
|
693
|
+
if (!this._data) {
|
|
694
|
+
this._data = createData(this.client);
|
|
695
|
+
}
|
|
696
|
+
return this._data;
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Utils namespace - Mermaid diagrams, document conversion, regex, JSON extraction
|
|
700
|
+
*
|
|
701
|
+
* @example
|
|
702
|
+
* ```typescript
|
|
703
|
+
* // Generate diagram
|
|
704
|
+
* const diagram = await rainfall.utils.mermaid({
|
|
705
|
+
* diagram: 'graph TD; A-->B;'
|
|
706
|
+
* });
|
|
707
|
+
*
|
|
708
|
+
* // Convert document
|
|
709
|
+
* const pdf = await rainfall.utils.documentConvert({
|
|
710
|
+
* document: markdownContent,
|
|
711
|
+
* mimeType: 'text/markdown',
|
|
712
|
+
* format: 'pdf'
|
|
713
|
+
* });
|
|
714
|
+
*
|
|
715
|
+
* // Extract JSON from text
|
|
716
|
+
* const json = await rainfall.utils.jsonExtract({
|
|
717
|
+
* text: 'Here is some data: {"key": "value"}'
|
|
718
|
+
* });
|
|
719
|
+
* ```
|
|
720
|
+
*/
|
|
721
|
+
get utils() {
|
|
722
|
+
if (!this._utils) {
|
|
723
|
+
this._utils = createUtils(this.client);
|
|
724
|
+
}
|
|
725
|
+
return this._utils;
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Get the underlying HTTP client for advanced usage
|
|
729
|
+
*/
|
|
730
|
+
getClient() {
|
|
731
|
+
return this.client;
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* List all available tools
|
|
735
|
+
*/
|
|
736
|
+
async listTools() {
|
|
737
|
+
return this.client.listTools();
|
|
738
|
+
}
|
|
739
|
+
/**
|
|
740
|
+
* Get schema for a specific tool
|
|
741
|
+
*/
|
|
742
|
+
async getToolSchema(toolId) {
|
|
743
|
+
return this.client.getToolSchema(toolId);
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* Execute any tool by ID (low-level access)
|
|
747
|
+
*/
|
|
748
|
+
async executeTool(toolId, params) {
|
|
749
|
+
return this.client.executeTool(toolId, params);
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Get current subscriber info and usage
|
|
753
|
+
*/
|
|
754
|
+
async getMe() {
|
|
755
|
+
return this.client.getMe();
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* Get current rate limit info
|
|
759
|
+
*/
|
|
760
|
+
getRateLimitInfo() {
|
|
761
|
+
return this.client.getRateLimitInfo();
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
|
|
765
|
+
export {
|
|
766
|
+
RainfallError,
|
|
767
|
+
AuthenticationError,
|
|
768
|
+
RateLimitError,
|
|
769
|
+
ValidationError,
|
|
770
|
+
NotFoundError,
|
|
771
|
+
ServerError,
|
|
772
|
+
TimeoutError,
|
|
773
|
+
NetworkError,
|
|
774
|
+
ToolNotFoundError,
|
|
775
|
+
parseErrorResponse,
|
|
776
|
+
RainfallClient,
|
|
777
|
+
Rainfall
|
|
778
|
+
};
|
package/dist/cli/index.js
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
3
25
|
|
|
4
26
|
// src/cli/index.ts
|
|
5
27
|
var import_fs = require("fs");
|
|
@@ -241,10 +263,11 @@ var RainfallClient = class {
|
|
|
241
263
|
*/
|
|
242
264
|
async executeTool(toolId, params, options) {
|
|
243
265
|
const subscriberId = await this.ensureSubscriberId();
|
|
244
|
-
|
|
266
|
+
const response = await this.request(`/olympic/subscribers/${subscriberId}/nodes/${toolId}`, {
|
|
245
267
|
method: "POST",
|
|
246
|
-
body: params
|
|
268
|
+
body: params || {}
|
|
247
269
|
}, options);
|
|
270
|
+
return response.result;
|
|
248
271
|
}
|
|
249
272
|
/**
|
|
250
273
|
* List all available tools
|
|
@@ -985,6 +1008,25 @@ async function runTool(args) {
|
|
|
985
1008
|
console.error("\nUsage: rainfall run <tool-id> [options]");
|
|
986
1009
|
process.exit(1);
|
|
987
1010
|
}
|
|
1011
|
+
if (toolId === "--help" || toolId === "-h") {
|
|
1012
|
+
console.log(`
|
|
1013
|
+
Usage: rainfall run <tool-id> [options]
|
|
1014
|
+
|
|
1015
|
+
Execute a tool by ID.
|
|
1016
|
+
|
|
1017
|
+
Options:
|
|
1018
|
+
-p, --params <json> Tool parameters as JSON string
|
|
1019
|
+
-f, --file <path> Read parameters from JSON file
|
|
1020
|
+
--raw Output raw JSON (no formatting)
|
|
1021
|
+
|
|
1022
|
+
Examples:
|
|
1023
|
+
rainfall run figma-users-getMe
|
|
1024
|
+
rainfall run exa-web-search -p '{"query": "AI news"}'
|
|
1025
|
+
rainfall run github-create-issue -f ./issue.json
|
|
1026
|
+
echo '{"query": "hello"}' | rainfall run exa-web-search
|
|
1027
|
+
`);
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
988
1030
|
let params = {};
|
|
989
1031
|
for (let i = 1; i < args.length; i++) {
|
|
990
1032
|
const arg = args[i];
|
|
@@ -1016,16 +1058,37 @@ async function runTool(args) {
|
|
|
1016
1058
|
}
|
|
1017
1059
|
}
|
|
1018
1060
|
if (!process.stdin.isTTY) {
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1061
|
+
process.stdin.pause();
|
|
1062
|
+
const fs = await import("fs");
|
|
1063
|
+
try {
|
|
1064
|
+
const buffer = Buffer.alloc(1024);
|
|
1065
|
+
const bytesRead = await new Promise((resolve) => {
|
|
1066
|
+
const timeout = setTimeout(() => resolve(0), 50);
|
|
1067
|
+
fs.read(process.stdin.fd, buffer, 0, 1024, null, (err, n) => {
|
|
1068
|
+
clearTimeout(timeout);
|
|
1069
|
+
resolve(err ? 0 : n);
|
|
1070
|
+
});
|
|
1071
|
+
});
|
|
1072
|
+
if (bytesRead > 0) {
|
|
1073
|
+
let data = buffer.toString("utf8", 0, bytesRead);
|
|
1074
|
+
while (true) {
|
|
1075
|
+
const more = await new Promise((resolve) => {
|
|
1076
|
+
fs.read(process.stdin.fd, buffer, 0, 1024, null, (err, n) => {
|
|
1077
|
+
resolve(err ? 0 : n);
|
|
1078
|
+
});
|
|
1079
|
+
});
|
|
1080
|
+
if (more === 0) break;
|
|
1081
|
+
data += buffer.toString("utf8", 0, more);
|
|
1082
|
+
}
|
|
1083
|
+
if (data.trim()) {
|
|
1084
|
+
try {
|
|
1085
|
+
const piped = JSON.parse(data);
|
|
1086
|
+
params = { ...params, ...piped };
|
|
1087
|
+
} catch {
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1028
1090
|
}
|
|
1091
|
+
} catch {
|
|
1029
1092
|
}
|
|
1030
1093
|
}
|
|
1031
1094
|
const rainfall = getRainfall();
|
|
@@ -1114,7 +1177,7 @@ async function main() {
|
|
|
1114
1177
|
}
|
|
1115
1178
|
break;
|
|
1116
1179
|
case "run":
|
|
1117
|
-
await runTool(
|
|
1180
|
+
await runTool(args.slice(1));
|
|
1118
1181
|
break;
|
|
1119
1182
|
case "me":
|
|
1120
1183
|
await showMe();
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
Rainfall
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-RA3HDYF4.mjs";
|
|
5
5
|
|
|
6
6
|
// src/cli/index.ts
|
|
7
7
|
import { readFileSync, existsSync, writeFileSync, mkdirSync } from "fs";
|
|
@@ -229,6 +229,25 @@ async function runTool(args) {
|
|
|
229
229
|
console.error("\nUsage: rainfall run <tool-id> [options]");
|
|
230
230
|
process.exit(1);
|
|
231
231
|
}
|
|
232
|
+
if (toolId === "--help" || toolId === "-h") {
|
|
233
|
+
console.log(`
|
|
234
|
+
Usage: rainfall run <tool-id> [options]
|
|
235
|
+
|
|
236
|
+
Execute a tool by ID.
|
|
237
|
+
|
|
238
|
+
Options:
|
|
239
|
+
-p, --params <json> Tool parameters as JSON string
|
|
240
|
+
-f, --file <path> Read parameters from JSON file
|
|
241
|
+
--raw Output raw JSON (no formatting)
|
|
242
|
+
|
|
243
|
+
Examples:
|
|
244
|
+
rainfall run figma-users-getMe
|
|
245
|
+
rainfall run exa-web-search -p '{"query": "AI news"}'
|
|
246
|
+
rainfall run github-create-issue -f ./issue.json
|
|
247
|
+
echo '{"query": "hello"}' | rainfall run exa-web-search
|
|
248
|
+
`);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
232
251
|
let params = {};
|
|
233
252
|
for (let i = 1; i < args.length; i++) {
|
|
234
253
|
const arg = args[i];
|
|
@@ -260,16 +279,37 @@ async function runTool(args) {
|
|
|
260
279
|
}
|
|
261
280
|
}
|
|
262
281
|
if (!process.stdin.isTTY) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
282
|
+
process.stdin.pause();
|
|
283
|
+
const fs = await import("fs");
|
|
284
|
+
try {
|
|
285
|
+
const buffer = Buffer.alloc(1024);
|
|
286
|
+
const bytesRead = await new Promise((resolve) => {
|
|
287
|
+
const timeout = setTimeout(() => resolve(0), 50);
|
|
288
|
+
fs.read(process.stdin.fd, buffer, 0, 1024, null, (err, n) => {
|
|
289
|
+
clearTimeout(timeout);
|
|
290
|
+
resolve(err ? 0 : n);
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
if (bytesRead > 0) {
|
|
294
|
+
let data = buffer.toString("utf8", 0, bytesRead);
|
|
295
|
+
while (true) {
|
|
296
|
+
const more = await new Promise((resolve) => {
|
|
297
|
+
fs.read(process.stdin.fd, buffer, 0, 1024, null, (err, n) => {
|
|
298
|
+
resolve(err ? 0 : n);
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
if (more === 0) break;
|
|
302
|
+
data += buffer.toString("utf8", 0, more);
|
|
303
|
+
}
|
|
304
|
+
if (data.trim()) {
|
|
305
|
+
try {
|
|
306
|
+
const piped = JSON.parse(data);
|
|
307
|
+
params = { ...params, ...piped };
|
|
308
|
+
} catch {
|
|
309
|
+
}
|
|
310
|
+
}
|
|
272
311
|
}
|
|
312
|
+
} catch {
|
|
273
313
|
}
|
|
274
314
|
}
|
|
275
315
|
const rainfall = getRainfall();
|
|
@@ -358,7 +398,7 @@ async function main() {
|
|
|
358
398
|
}
|
|
359
399
|
break;
|
|
360
400
|
case "run":
|
|
361
|
-
await runTool(
|
|
401
|
+
await runTool(args.slice(1));
|
|
362
402
|
break;
|
|
363
403
|
case "me":
|
|
364
404
|
await showMe();
|
package/dist/index.js
CHANGED
|
@@ -277,10 +277,11 @@ var RainfallClient = class {
|
|
|
277
277
|
*/
|
|
278
278
|
async executeTool(toolId, params, options) {
|
|
279
279
|
const subscriberId = await this.ensureSubscriberId();
|
|
280
|
-
|
|
280
|
+
const response = await this.request(`/olympic/subscribers/${subscriberId}/nodes/${toolId}`, {
|
|
281
281
|
method: "POST",
|
|
282
|
-
body: params
|
|
282
|
+
body: params || {}
|
|
283
283
|
}, options);
|
|
284
|
+
return response.result;
|
|
284
285
|
}
|
|
285
286
|
/**
|
|
286
287
|
* List all available tools
|
package/dist/index.mjs
CHANGED
package/dist/mcp.js
CHANGED
|
@@ -277,10 +277,11 @@ var RainfallClient = class {
|
|
|
277
277
|
*/
|
|
278
278
|
async executeTool(toolId, params, options) {
|
|
279
279
|
const subscriberId = await this.ensureSubscriberId();
|
|
280
|
-
|
|
280
|
+
const response = await this.request(`/olympic/subscribers/${subscriberId}/nodes/${toolId}`, {
|
|
281
281
|
method: "POST",
|
|
282
|
-
body: params
|
|
282
|
+
body: params || {}
|
|
283
283
|
}, options);
|
|
284
|
+
return response.result;
|
|
284
285
|
}
|
|
285
286
|
/**
|
|
286
287
|
* List all available tools
|
package/dist/mcp.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rainfall-devkit/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Official SDK for Rainfall API - 200+ tools for building AI-powered applications",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -67,6 +67,6 @@
|
|
|
67
67
|
"node": ">=18"
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@rainfall-devkit/sdk": "^0.1.
|
|
70
|
+
"@rainfall-devkit/sdk": "^0.1.7"
|
|
71
71
|
}
|
|
72
72
|
}
|