@squidcloud/cli 1.0.445 → 1.0.447

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.
@@ -0,0 +1,87 @@
1
+ # REST API Reference
2
+
3
+ Most Squid SDK functionality is also available via REST APIs.
4
+
5
+ ## API Documentation
6
+
7
+ Full API reference: https://docs.getsquid.ai/reference-docs/api/
8
+
9
+ ## Authentication
10
+
11
+ All API endpoints require an API key. Include it in the request headers:
12
+ ```
13
+ Authorization: Bearer YOUR_API_KEY
14
+ ```
15
+
16
+ ## API Categories
17
+
18
+ ### [Agent API](https://docs.getsquid.ai/reference-docs/api/#tag/Agent)
19
+ Manage AI agents. SDK: [ai.md](ai.md)
20
+ - `GET /agent/get/{agentId}` - Get agent details
21
+ - `POST /agent/upsert` - Create or update agent
22
+ - `POST /agent/delete` - Delete agent
23
+ - `POST /agent/updateInstructions` - Update agent instructions
24
+ - `POST /agent/updateModel` - Change LLM model
25
+ - `POST /agent/updateConnectedAgents` - Manage connected agents
26
+ - `POST /agent/updateGuardrails` - Configure guardrails
27
+ - `POST /agent/updateCustomGuardrails` - Set custom guardrails
28
+ - `POST /agent/deleteCustomGuardrails` - Remove custom guardrails
29
+ - `POST /agent/ask` - Send prompt, get response
30
+ - `POST /agent/askWithAnnotations` - Get response with annotations
31
+ - `GET /agent/revisions/{agentId}` - List revisions
32
+ - `POST /agent/restoreRevision` - Restore revision
33
+ - `POST /agent/deleteRevision` - Delete revision
34
+
35
+ ### [AI Audio API](https://docs.getsquid.ai/reference-docs/api/#tag/AI-Audio)
36
+ Transcribe audio, text-to-speech. SDK: [ai.md](ai.md)
37
+ - `POST /audio/transcribe` - Transcribe audio to text
38
+ - `POST /audio/createSpeech` - Text to speech
39
+
40
+ ### [AI Image API](https://docs.getsquid.ai/reference-docs/api/#tag/AI-Image)
41
+ Generate images, remove backgrounds. SDK: [ai.md](ai.md)
42
+ - `POST /image/generate` - Generate image from prompt
43
+ - `POST /image/removeBackground` - Remove image background
44
+
45
+ ### [KnowledgeBase API](https://docs.getsquid.ai/reference-docs/api/#tag/KnowledgeBase)
46
+ Manage knowledge bases for RAG. SDK: [ai.md](ai.md)
47
+ - `GET /knowledge-base/get/{knowledgeBaseId}` - Get knowledge base
48
+ - `POST /knowledge-base/upsert` - Create or update knowledge base
49
+ - `POST /knowledge-base/delete` - Delete knowledge base
50
+ - `POST /knowledge-base/upsertContexts` - Add or update contexts
51
+ - `POST /knowledge-base/deleteContexts` - Delete contexts
52
+ - `GET /knowledge-base/getContext/{knowledgeBaseId}/{contextId}` - Get context
53
+ - `GET /knowledge-base/listContexts/{knowledgeBaseId}` - List contexts
54
+ - `POST /knowledge-base/search` - Semantic search
55
+
56
+ ### [Matchmaking API](https://docs.getsquid.ai/reference-docs/api/#tag/Matchmaking) *(deprecated)*
57
+ Use `knowledgeBase().searchContextsWith*()` instead.
58
+
59
+ ### [Web Utilities API](https://docs.getsquid.ai/reference-docs/api/#tag/Web-Utilities)
60
+ Web search, URL content, short URLs. SDK: [client.md](client.md)
61
+ - `POST /web/aiSearch` - AI-powered web search
62
+ - `POST /web/getUrlContent` - Fetch URL as markdown
63
+ - `POST /web/createShortUrl` - Create short URL
64
+ - `POST /web/createShortUrls` - Create multiple short URLs
65
+ - `POST /web/deleteShortUrl` - Delete short URL
66
+ - `POST /web/deleteShortUrls` - Delete multiple short URLs
67
+
68
+ ### [Database API](https://docs.getsquid.ai/reference-docs/api/#tag/Database)
69
+ AI queries against databases. SDK: [ai.md](ai.md)
70
+ - `POST /db/executeAiQuery` - Execute AI query
71
+
72
+ ### [Extraction Utilities API](https://docs.getsquid.ai/reference-docs/api/#tag/Extraction-Utilities)
73
+ Create PDFs, extract data from documents. SDK: [client.md](client.md)
74
+ - `POST /extraction/createPdf` - Create PDF from HTML/markdown
75
+ - `POST /extraction/extractDataFromUrl` - Extract data from URL
76
+ - `POST /extraction/extractDataFromFile` - Extract data from file
77
+
78
+ ## SDK vs REST API
79
+
80
+ | Feature | SDK | REST API |
81
+ |---------|-----|----------|
82
+ | AI Agents | `squid.ai().agent()` | Agent API |
83
+ | Audio | `squid.ai().audio()` | AI Audio API |
84
+ | Image | `squid.ai().image()` | AI Image API |
85
+ | Knowledge Bases | `squid.ai().knowledgeBase()` | KnowledgeBase API |
86
+ | Web Utilities | `squid.web()` | Web Utilities API |
87
+ | Extraction | `squid.extraction()` | Extraction Utilities API |
@@ -0,0 +1,462 @@
1
+ # Backend SDK
2
+
3
+ The Squid Backend SDK (`@squidcloud/backend`) provides TypeScript decorators and base classes for building server-side logic that runs on Squid's infrastructure.
4
+
5
+ Docs: https://docs.getsquid.ai/reference-docs/backend/
6
+
7
+ ## Contents
8
+ - CLI Commands
9
+ - Project Structure
10
+ - How Backend Runs
11
+ - SquidService Base Class
12
+ - Backend Functions (@executable)
13
+ - Webhooks (@webhook)
14
+ - Triggers (@trigger)
15
+ - Schedulers (@scheduler)
16
+ - Rate Limiting (@limits)
17
+ - Client Connection State (@clientConnectionStateHandler)
18
+ - Using Squid Client in Backend
19
+ - File Handling
20
+
21
+ ## CLI Commands
22
+
23
+ Install the CLI globally:
24
+ ```bash
25
+ npm install -g @squidcloud/cli
26
+ ```
27
+
28
+ **`squid init <project-name>`** - Creates a new backend project with `.env` and example service. Also populates `.claude/skills/` with Squid development skills for Claude.
29
+ ```bash
30
+ squid init backend --appId YOUR_APP_ID --apiKey YOUR_API_KEY --environmentId dev --squidDeveloperId YOUR_DEV_ID --region us-east-1.aws
31
+ ```
32
+
33
+ **`squid start`** - Runs backend locally with hot-reload. Connects to Squid Cloud via reverse proxy.
34
+ ```bash
35
+ cd backend && squid start
36
+ ```
37
+
38
+ **`squid deploy`** - Builds and deploys to Squid Cloud.
39
+ ```bash
40
+ squid deploy [--apiKey KEY] [--environmentId prod] [--skipBuild]
41
+ ```
42
+
43
+ **`squid build`** - Builds backend project without deploying.
44
+ ```bash
45
+ squid build [--dev] [--skip-version-check]
46
+ ```
47
+
48
+ **Extended logging** - Add to `.env`:
49
+ ```env
50
+ SQUID_LOG_TYPES=QUERY,MUTATION,AI,API,ERROR
51
+ ```
52
+
53
+ ## Project Structure
54
+
55
+ After running `squid init`, your backend project has this structure:
56
+
57
+ ```
58
+ backend/
59
+ ├── .env # Environment config: SQUID_APP_ID, SQUID_API_KEY, SQUID_ENVIRONMENT_ID, SQUID_REGION
60
+ ├── package.json # Dependencies: @squidcloud/backend, devDeps: @squidcloud/cli
61
+ ├── tsconfig.json # TypeScript configuration
62
+ ├── src/
63
+ │ ├── index.ts # Entry point - exports SquidProject and all services
64
+ │ ├── service/ # All SquidService classes go here
65
+ │ │ ├── index.ts # Re-exports all services (e.g., export * from './example-service')
66
+ │ │ └── *.ts # Your SquidService classes with decorators
67
+ │ └── public/ # Static assets (accessible via this.assetsDirectory)
68
+ └── dist/ # Build output
69
+ ```
70
+
71
+ **Key files:**
72
+ - `src/index.ts` - Must export a `SquidProject` instance and all services
73
+ - `src/service/index.ts` - Re-exports all service files so they're included in the bundle
74
+ - `.env` - Contains credentials from Squid Console (never commit to git)
75
+
76
+ ## How Backend Runs
77
+
78
+ **Local development (`squid start`):**
79
+ - Runs your backend code on your machine
80
+ - Hot-reload on file changes
81
+ - Connects to Squid Cloud via reverse proxy
82
+ - Your code can access integrations configured in Console
83
+
84
+ **Production (`squid deploy`):**
85
+ - Builds and uploads your code to Squid Cloud
86
+ - Squid Cloud runs your backend in a managed environment
87
+ - Multiple backend instances can be configured for scaling
88
+
89
+ ## SquidService Base Class
90
+
91
+ All backend services extend `SquidService`:
92
+
93
+ ```typescript
94
+ import { SquidService } from '@squidcloud/backend';
95
+
96
+ export class MyService extends SquidService {
97
+ // Decorated methods
98
+ }
99
+ ```
100
+
101
+ **Important:** In backend code running on Squid's infrastructure, the Squid client is **already initialized and available** via `this.squid`. You don't need to manually create a new instance or provide configuration parameters.
102
+
103
+ ### Available Properties
104
+
105
+ ```typescript
106
+ this.region // 'local' during dev, region in production
107
+ this.backendBaseUrl
108
+ this.secrets // From Squid Console
109
+ this.apiKeys
110
+ this.context // RunContext (appId, clientId, sourceIp, headers, openApiContext)
111
+ this.squid // Pre-initialized Squid client (initialized with admin API key, full permissions)
112
+ this.assetsDirectory // Path to public/ folder
113
+ ```
114
+
115
+ ### Auth Methods
116
+
117
+ ```typescript
118
+ // Get user authentication (JWT token)
119
+ this.getUserAuth() // AuthWithBearer | undefined
120
+ // Returns: { type: 'Bearer', userId: string, expiration: number, attributes: Record<string, any>, jwt?: string }
121
+
122
+ // Get API key authentication
123
+ this.getApiKeyAuth() // AuthWithApiKey | undefined
124
+ // Returns: { type: 'ApiKey', apiKey: string }
125
+
126
+ this.isAuthenticated() // boolean - true if user token OR API key
127
+ this.assertIsAuthenticated() // throws if not authenticated
128
+ this.assertApiKeyCall() // throws if not API key auth
129
+ ```
130
+
131
+ **Example: Getting User Info**
132
+ ```typescript
133
+ @executable()
134
+ async getUserData(): Promise<UserData> {
135
+ this.assertIsAuthenticated();
136
+ const userId = this.getUserAuth()?.userId;
137
+ if (!userId) throw new Error('User not authenticated');
138
+ return await fetchUserData(userId);
139
+ }
140
+ ```
141
+
142
+ ### Helper Methods
143
+
144
+ ```typescript
145
+ // Create webhook response (for @webhook decorated functions)
146
+ this.createWebhookResponse(body?, statusCode?, headers?)
147
+ // Throws webhook response immediately (interrupts execution)
148
+ this.throwWebhookResponse({ body?, statusCode?, headers? })
149
+
150
+ // Create OpenAPI response (for OpenAPI/tsoa decorated functions)
151
+ this.createOpenApiResponse(body?, statusCode?, headers?)
152
+ // Throws OpenAPI response immediately (interrupts execution)
153
+ this.throwOpenApiResponse({ body?, statusCode?, headers? })
154
+
155
+ // Convert browser File to SquidFile for OpenAPI file returns
156
+ await this.convertToSquidFile(file: File): Promise<SquidFile>
157
+
158
+ // Publish AI status update to specific client (used in @aiFunction)
159
+ await this.publishAiStatusUpdate(update: AiStatusMessage, clientId: ClientId)
160
+ ```
161
+
162
+ ## Backend Functions (@executable)
163
+
164
+ Backend functions allow you to write custom server-side logic that can be called from the client.
165
+
166
+ ### Backend Definition
167
+
168
+ ```typescript
169
+ import { SquidService, executable, SquidFile } from '@squidcloud/backend';
170
+
171
+ export class MyService extends SquidService {
172
+ @executable()
173
+ async greetUser(name: string): Promise<string> {
174
+ return `Hello, ${name}`;
175
+ }
176
+
177
+ @executable()
178
+ async uploadFile(file: SquidFile): Promise<Result> {
179
+ console.log(file.originalName, file.size, file.data);
180
+ return { success: true };
181
+ }
182
+ }
183
+ ```
184
+
185
+ ### Client Invocation
186
+
187
+ ```typescript
188
+ // Execute @executable() decorated function
189
+ const result = await squid.executeFunction('greetUser', 'John');
190
+ const typedResult = await squid.executeFunction<string>('greetUser', 'John');
191
+
192
+ // With headers
193
+ const result = await squid.executeFunctionWithHeaders(
194
+ 'processPayment',
195
+ { 'X-Custom-Header': 'value' },
196
+ paymentData
197
+ );
198
+ ```
199
+
200
+ ## Webhooks (@webhook)
201
+
202
+ Webhooks allow you to create publicly accessible HTTP endpoints that can receive data from external services.
203
+
204
+ ### Backend Definition
205
+
206
+ ```typescript
207
+ import { SquidService, webhook, WebhookRequest } from '@squidcloud/backend';
208
+
209
+ export class MyService extends SquidService {
210
+ @webhook('github-events')
211
+ async handleGithub(request: WebhookRequest): Promise<any> {
212
+ console.log(request.body);
213
+ console.log(request.headers);
214
+ console.log(request.queryParams);
215
+ console.log(request.httpMethod); // 'post' | 'get' | 'put' | 'delete'
216
+ console.log(request.files);
217
+
218
+ return this.createWebhookResponse({ received: true }, 200);
219
+ }
220
+ }
221
+ ```
222
+
223
+ **Webhook URL:** `https://<appId>.<region>.squid.cloud/webhooks/<webhook-id>`
224
+
225
+ ### Client Usage
226
+
227
+ ```typescript
228
+ // Get URL for a specific webhook
229
+ const webhookUrl = squid.getWebhookUrl('github-events');
230
+ // Returns: https://<appId>.<region>.squid.cloud/webhooks/github-events
231
+
232
+ // Get base webhooks URL (no webhook ID)
233
+ const baseUrl = squid.getWebhookUrl();
234
+ // Returns: https://<appId>.<region>.squid.cloud/webhooks
235
+
236
+ // Call webhook programmatically (optional)
237
+ // Usually webhooks are called by external services
238
+ const result = await squid.executeWebhook<Response>('github-events', {
239
+ headers: { 'X-GitHub-Event': 'push' },
240
+ queryParams: { ref: 'main' },
241
+ body: { commits: [...] },
242
+ files: [file1, file2]
243
+ });
244
+ ```
245
+
246
+ ## Triggers (@trigger)
247
+
248
+ Triggers respond to database document changes (insert, update, delete).
249
+
250
+ ```typescript
251
+ import { SquidService, trigger, TriggerRequest } from '@squidcloud/backend';
252
+
253
+ export class MyService extends SquidService {
254
+ // Using options object (recommended)
255
+ @trigger({ collection: 'users', mutationTypes: ['insert'] })
256
+ async onUserCreated(request: TriggerRequest<User>): Promise<void> {
257
+ console.log(request.mutationType); // 'insert' | 'update' | 'delete'
258
+ console.log(request.docId); // Document ID
259
+ console.log(request.collectionName);
260
+ console.log(request.integrationId);
261
+ console.log(request.docBefore); // undefined for insert
262
+ console.log(request.docAfter); // undefined for delete
263
+ }
264
+
265
+ // Custom ID and specific integration
266
+ @trigger({ id: 'order-update', collection: 'orders', integrationId: 'my-postgres' })
267
+ async onOrderChange(request: TriggerRequest<Order>): Promise<void> {
268
+ if (request.mutationType === 'update') {
269
+ const before = request.docBefore;
270
+ const after = request.docAfter;
271
+ // Handle order update
272
+ }
273
+ }
274
+
275
+ // Positional arguments (legacy)
276
+ @trigger('user-deleted', 'users')
277
+ async onUserDeleted(request: TriggerRequest<User>): Promise<void> {
278
+ // Called for all mutation types on 'users' collection
279
+ }
280
+ }
281
+ ```
282
+
283
+ **TriggerOptions:**
284
+ - `id?: string` - Trigger ID (defaults to `ClassName.FunctionName`)
285
+ - `collection: string` - Collection name to watch
286
+ - `integrationId?: string` - Database integration (defaults to `built_in_db`)
287
+ - `mutationTypes?: ('insert' | 'update' | 'delete')[]` - Filter by mutation types
288
+
289
+ **TriggerRequest<T>:**
290
+ - `mutationType` - The type of mutation ('insert' | 'update' | 'delete')
291
+ - `docId` - Document ID
292
+ - `collectionName` - Collection name
293
+ - `integrationId` - Integration ID
294
+ - `docBefore?: T` - Document state before mutation (undefined for insert)
295
+ - `docAfter?: T` - Document state after mutation (undefined for delete)
296
+
297
+ ## Schedulers (@scheduler)
298
+
299
+ Schedules periodic execution using cron expressions.
300
+
301
+ ```typescript
302
+ import { SquidService, scheduler, CronExpression } from '@squidcloud/backend';
303
+
304
+ export class MyService extends SquidService {
305
+ // Using cron string directly
306
+ @scheduler({ id: 'daily-cleanup', cron: '0 0 * * *' }) // Daily at midnight UTC
307
+ async cleanup(): Promise<void> {
308
+ console.log('Running cleanup');
309
+ }
310
+
311
+ // Using predefined CronExpression enum
312
+ @scheduler({ id: 'hourly-sync', cron: CronExpression.EVERY_HOUR })
313
+ async hourlySync(): Promise<void> {
314
+ console.log('Running hourly sync');
315
+ }
316
+
317
+ @scheduler({ id: 'weekday-morning', cron: CronExpression.MONDAY_TO_FRIDAY_AT_9AM })
318
+ async weekdayTask(): Promise<void> {
319
+ console.log('Running weekday morning task');
320
+ }
321
+
322
+ @scheduler({ id: 'frequent', cron: CronExpression.EVERY_5_MINUTES, exclusive: false })
323
+ async frequentTask(): Promise<void> {
324
+ // exclusive: false allows concurrent runs
325
+ }
326
+ }
327
+ ```
328
+
329
+ **Common CronExpression values:**
330
+ - `EVERY_SECOND`, `EVERY_5_SECONDS`, `EVERY_10_SECONDS`, `EVERY_30_SECONDS`
331
+ - `EVERY_MINUTE`, `EVERY_5_MINUTES`, `EVERY_10_MINUTES`, `EVERY_30_MINUTES`
332
+ - `EVERY_HOUR`, `EVERY_2_HOURS`, `EVERY_3_HOURS`, etc.
333
+ - `EVERY_DAY_AT_MIDNIGHT`, `EVERY_DAY_AT_NOON`, `EVERY_DAY_AT_1AM`, etc.
334
+ - `EVERY_WEEKDAY`, `EVERY_WEEKEND`, `EVERY_WEEK`
335
+ - `MONDAY_TO_FRIDAY_AT_9AM`, `MONDAY_TO_FRIDAY_AT_5PM`, etc.
336
+ - `EVERY_1ST_DAY_OF_MONTH_AT_MIDNIGHT`, `EVERY_QUARTER`, `EVERY_YEAR`
337
+
338
+ ### Client Management
339
+
340
+ ```typescript
341
+ const schedulers = squid.schedulers;
342
+
343
+ // List all
344
+ const all = await schedulers.list();
345
+
346
+ // Enable/disable
347
+ await schedulers.enable('daily-cleanup');
348
+ await schedulers.enable(['scheduler-1', 'scheduler-2']);
349
+
350
+ await schedulers.disable('hourly-sync');
351
+ await schedulers.disable(['scheduler-1', 'scheduler-2']);
352
+ ```
353
+
354
+ ## Rate Limiting (@limits)
355
+
356
+ Apply rate limits and quotas to functions.
357
+
358
+ ```typescript
359
+ import { SquidService, executable, limits } from '@squidcloud/backend';
360
+
361
+ export class MyService extends SquidService {
362
+ // Simple rate limit (5 QPS globally)
363
+ @limits({ rateLimit: 5 })
364
+ @executable()
365
+ async limited(): Promise<void> {}
366
+
367
+ // Quota (100 calls/month per user)
368
+ @limits({ quotaLimit: { value: 100, scope: 'user', renewPeriod: 'monthly' } })
369
+ @executable()
370
+ async quotaLimited(): Promise<void> {}
371
+
372
+ // Multiple limits
373
+ @limits({
374
+ rateLimit: [
375
+ { value: 100, scope: 'global' },
376
+ { value: 10, scope: 'user' }
377
+ ],
378
+ quotaLimit: [
379
+ { value: 10000, scope: 'global', renewPeriod: 'monthly' },
380
+ { value: 500, scope: 'user', renewPeriod: 'weekly' }
381
+ ]
382
+ })
383
+ @executable()
384
+ async multiLimited(): Promise<void> {}
385
+ }
386
+ ```
387
+
388
+ **Scopes:** `'global'`, `'user'`, `'ip'`
389
+ **Periods:** `'hourly'`, `'daily'`, `'weekly'`, `'monthly'`, `'quarterly'`, `'annually'`
390
+
391
+ ## Client Connection State (@clientConnectionStateHandler)
392
+
393
+ Handle client connection and disconnection events.
394
+
395
+ ```typescript
396
+ import { SquidService, clientConnectionStateHandler, ClientConnectionState } from '@squidcloud/backend';
397
+ import { ClientId } from '@squidcloud/client';
398
+
399
+ export class MyService extends SquidService {
400
+ @clientConnectionStateHandler()
401
+ async handleConnectionState(
402
+ clientId: ClientId,
403
+ state: ClientConnectionState
404
+ ): Promise<void> {
405
+ if (state === 'CONNECTED') {
406
+ console.log('Client connected:', clientId);
407
+ } else if (state === 'DISCONNECTED') {
408
+ console.log('Client disconnected:', clientId);
409
+ } else if (state === 'REMOVED') {
410
+ console.log('Client removed:', clientId);
411
+ }
412
+ }
413
+ }
414
+ ```
415
+
416
+ **ClientConnectionState values:**
417
+ - `'CONNECTED'` - Client just connected
418
+ - `'DISCONNECTED'` - Client disconnected but ID still retained
419
+ - `'REMOVED'` - Client disconnected and ID removed
420
+
421
+ ## Using Squid Client in Backend
422
+
423
+ The pre-initialized `this.squid` client has full permissions:
424
+
425
+ ```typescript
426
+ export class MyService extends SquidService {
427
+ @executable()
428
+ async aggregateStats(userId: string): Promise<Stats> {
429
+ // this.squid has API key permissions - full access
430
+ const orders = await this.squid.collection('orders')
431
+ .query()
432
+ .eq('userId', userId)
433
+ .snapshot();
434
+
435
+ return { totalOrders: orders.data.length };
436
+ }
437
+ }
438
+ ```
439
+
440
+ ## File Handling
441
+
442
+ ```typescript
443
+ // Receiving files in backend functions
444
+ @executable()
445
+ async processFile(file: SquidFile): Promise<Result> {
446
+ console.log(file.originalName); // Original filename
447
+ console.log(file.size); // File size in bytes
448
+ console.log(file.mimetype); // MIME type
449
+ const content = new TextDecoder().decode(file.data); // Read as text
450
+ return { processed: true };
451
+ }
452
+ ```
453
+
454
+ For AI-related decorators (`@aiFunction`, `@secureAiAgent`, etc.), see [ai.md](ai.md).
455
+ For security decorators (`@secureDatabase`, `@secureCollection`, etc.), see [security.md](security.md).
456
+
457
+ ## Best Practices
458
+
459
+ 1. **Don't store state in class properties** - Use collections instead (instances may restart or scale)
460
+ 2. **Validate input in executables** - Always check auth and validate parameters before processing
461
+ 3. **Never commit `.env` to git** - Contains credentials from Squid Console
462
+ 4. **Use options object for decorators** - Prefer `@trigger({ collection: 'users' })` over positional args (legacy)