@superglue/cli 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/dist/cli.js +38 -90
- package/dist/dist/cli.js +38 -90
- package/dist/dist/skills/superglue/SKILL.md +123 -239
- package/dist/dist/skills/superglue/references/integration.md +61 -56
- package/dist/skills/superglue/SKILL.md +123 -239
- package/dist/skills/superglue/references/integration.md +61 -56
- package/package.json +1 -1
- package/skills/superglue/SKILL.md +123 -239
- package/skills/superglue/references/integration.md +61 -56
|
@@ -7,58 +7,32 @@ description: "Build, test, deploy and integrate superglue tools via the sg CLI a
|
|
|
7
7
|
|
|
8
8
|
## CRITICAL RULES — READ FIRST
|
|
9
9
|
|
|
10
|
+
**Pre-requisites for using the CLI**
|
|
11
|
+
|
|
12
|
+
1. **Check CLI exists**: Run `sg --version`. If it fails with `command not found`, install it: `npm install -g @superglue/cli`
|
|
13
|
+
2. **Check superglue CLI config exists**: Run `sg system list`. If it fails with `fetch failed` or auth errors, the CLI needs configuration via `sg init` (see below).
|
|
14
|
+
|
|
10
15
|
**Authentication & Credentials:**
|
|
11
16
|
|
|
12
|
-
- **Auth headers MUST be set explicitly** — credentials are NEVER auto-injected into requests
|
|
17
|
+
- **Auth headers MUST be set explicitly** — credentials are NEVER auto-injected into requests or tool steps
|
|
13
18
|
- Every request step (in tools AND `sg system call`) must include the appropriate auth header using `<<systemId_credentialKey>>` syntax
|
|
14
19
|
- OAuth systems also require explicit headers — only token refresh is automatic
|
|
15
20
|
|
|
16
|
-
**
|
|
17
|
-
|
|
18
|
-
- **ALWAYS use `sg system call` to test endpoints BEFORE building tools**
|
|
19
|
-
- Verify authentication works, understand response structure, confirm field names
|
|
20
|
-
- Never guess API responses — test them first
|
|
21
|
-
- This prevents 90% of tool failures
|
|
21
|
+
**Saving Tools:**
|
|
22
22
|
|
|
23
|
-
**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
sg system call --system-id notion --url "https://api.notion.com/v1/search" \
|
|
27
|
-
--method POST \
|
|
28
|
-
--headers '{"Authorization":"Bearer <<notion_access_token>>","Notion-Version":"2022-06-28"}' \
|
|
29
|
-
--body '{"filter":{"property":"object","value":"page"}}'
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
**Example - Tool step with auth:**
|
|
33
|
-
|
|
34
|
-
```json
|
|
35
|
-
{
|
|
36
|
-
"headers": {
|
|
37
|
-
"Authorization": "Bearer <<systemId_access_token>>"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
```
|
|
23
|
+
- **Don't save a tool without explicit user confirmation** — always ask "Should I save this tool?" first
|
|
24
|
+
- After `sg tool build` + `sg tool run`, present results to the user and wait for approval
|
|
25
|
+
- Only run `sg tool save --draft <id>` after the user explicitly confirms
|
|
41
26
|
|
|
42
|
-
**
|
|
27
|
+
**Credentials in Non-Interactive Environments (AI Agents, CI):**
|
|
43
28
|
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
- `id` fields must be kebab-case for tools, snake_case for systems
|
|
47
|
-
- Simple `<<varName>>` only works for **top-level keys** (no dots, no nesting)
|
|
48
|
-
- For nested access use arrow functions: `<<(sourceData) => sourceData.currentItem.id>>`
|
|
49
|
-
- ALWAYS access step results via `.data`: `sourceData.stepId.data` not `.results`
|
|
29
|
+
- **Pass ALL credentials (including secrets) directly via `--credentials` JSON** — do NOT use `--sensitive-credentials` (it requires an interactive TTY which agents don't have)
|
|
30
|
+
- Ask the user to provide secret values, then pass them in `--credentials '{"api_key":"sk-xxx"}'`
|
|
50
31
|
|
|
51
32
|
---
|
|
52
33
|
|
|
53
34
|
## Installation & Setup
|
|
54
35
|
|
|
55
|
-
### Prerequisites Check
|
|
56
|
-
|
|
57
|
-
Before running any `sg` command, verify the CLI is installed and configured:
|
|
58
|
-
|
|
59
|
-
1. **Check CLI exists**: Run `sg --version`. If it fails with `command not found`, install it: `npm install -g @superglue/cli`
|
|
60
|
-
2. **Check config exists**: Run `sg system list`. If it fails with `fetch failed` or auth errors, the CLI needs configuration (see below).
|
|
61
|
-
|
|
62
36
|
### Installing the CLI
|
|
63
37
|
|
|
64
38
|
```bash
|
|
@@ -69,7 +43,7 @@ After installation, the `sg` command is available globally.
|
|
|
69
43
|
|
|
70
44
|
### Initialization (REQUIRED before first use)
|
|
71
45
|
|
|
72
|
-
The CLI **will not work** until configured with an API key
|
|
46
|
+
The CLI **will not work** until configured with an API key. The endpoint defaults to `https://api.superglue.cloud` if not specified.
|
|
73
47
|
|
|
74
48
|
**Option A: Interactive setup (recommended for humans)**
|
|
75
49
|
|
|
@@ -116,14 +90,12 @@ After configuring, verify the connection works:
|
|
|
116
90
|
sg system list # should return a list (possibly empty) without errors
|
|
117
91
|
```
|
|
118
92
|
|
|
119
|
-
If you see `fetch failed`, `ECONNREFUSED`, or authentication errors, double-check your API key and endpoint.
|
|
120
|
-
|
|
121
93
|
---
|
|
122
94
|
|
|
123
95
|
## Quick Start
|
|
124
96
|
|
|
125
97
|
```bash
|
|
126
|
-
sg system list
|
|
98
|
+
sg system list
|
|
127
99
|
sg tool build --config '{"id":"...","instruction":"...","steps":[...]}'
|
|
128
100
|
sg tool run --draft <draftId>
|
|
129
101
|
sg tool save --draft <draftId>
|
|
@@ -137,8 +109,6 @@ sg tool save --draft <draftId>
|
|
|
137
109
|
| `--api-key <key>` | Override API key |
|
|
138
110
|
| `--endpoint <url>` | Override API endpoint |
|
|
139
111
|
|
|
140
|
-
---
|
|
141
|
-
|
|
142
112
|
## Command Reference
|
|
143
113
|
|
|
144
114
|
### `sg init`
|
|
@@ -150,17 +120,17 @@ Interactive setup — API key, endpoint, output mode. Creates `.superglue/`.
|
|
|
150
120
|
**`sg tool build`** — Register a tool config. Returns a `draftId`. Not AI-powered — you provide the full config.
|
|
151
121
|
|
|
152
122
|
```bash
|
|
153
|
-
sg tool build --config tool.json # from file
|
|
154
123
|
sg tool build --config '{"id":"...","steps":[...]}' # inline JSON
|
|
155
124
|
sg tool build --id my-tool --instruction "..." --steps steps.json --payload '{"key":"val"}'
|
|
125
|
+
sg tool build --config tool.json # from file
|
|
156
126
|
```
|
|
157
127
|
|
|
158
128
|
| `--config <file-or-json>` | Full JSON config (file path or inline JSON string) |
|
|
159
129
|
| `--id <id>` | Tool ID (kebab-case) |
|
|
160
130
|
| `--instruction <text>` | Human-readable description |
|
|
161
131
|
| `--steps <file>` | JSON file with steps array |
|
|
162
|
-
| `--payload <json>` | Sample payload
|
|
163
|
-
| `--file <key=path>` | Attach file reference
|
|
132
|
+
| `--payload <json>` | Sample payload |
|
|
133
|
+
| `--file <key=path>` | Attach file reference |
|
|
164
134
|
|
|
165
135
|
**`sg tool run`** — Execute a draft or saved tool. Streams live execution logs to the terminal.
|
|
166
136
|
|
|
@@ -178,11 +148,10 @@ sg tool run --tool my-tool --payload-file payload.json
|
|
|
178
148
|
|
|
179
149
|
```bash
|
|
180
150
|
sg tool edit --draft <draftId> --patches '[{"op":"replace","path":"/steps/0/config/url","value":"..."}]'
|
|
181
|
-
sg tool edit --tool my-tool --patches patches.json
|
|
151
|
+
sg tool edit --tool my-tool --patches patches.json
|
|
182
152
|
```
|
|
183
153
|
|
|
184
154
|
| `--patches <json-or-file>` | JSON Patch array (inline or file) |
|
|
185
|
-
| `--test` | Run patched tool after accepting |
|
|
186
155
|
|
|
187
156
|
**`sg tool save`** — Persist draft to database. Deletes draft file on success.
|
|
188
157
|
|
|
@@ -202,34 +171,53 @@ sg tool find --id my-tool # exact ID lookup (full config)
|
|
|
202
171
|
|
|
203
172
|
**`sg system create`**
|
|
204
173
|
|
|
174
|
+
**Required flags:**
|
|
175
|
+
|
|
176
|
+
- `--id <id>` — System ID (lowercase, underscores only, no hyphens)
|
|
177
|
+
- `--name <name>` — Human-readable display name
|
|
178
|
+
- `--url <url>` — API base URL (auto-filled when using `--template`)
|
|
179
|
+
|
|
180
|
+
**At least one of:**
|
|
181
|
+
|
|
182
|
+
- `--template <id>` — Pre-configured template (auto-fills name and url if not provided)
|
|
183
|
+
- `--url <url>` + `--name <name>` manually
|
|
184
|
+
|
|
185
|
+
**Example with credentials (non-interactive — use this in AI agent / CI contexts):**
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
sg system create --id my_api --name "My API" --url https://api.example.com \
|
|
189
|
+
--credentials '{"api_key":"sk-xxx"}'
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**With template:**
|
|
193
|
+
|
|
205
194
|
```bash
|
|
206
|
-
sg system create --id slack --
|
|
207
|
-
sg system create --id my_api --url https://api.example.com --credentials '{"api_key":"..."}' --sensitive-credentials api_key
|
|
195
|
+
sg system create --id slack --name "Slack" --template slack
|
|
208
196
|
```
|
|
209
197
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
|
213
|
-
|
|
|
214
|
-
| `--
|
|
215
|
-
| `--
|
|
216
|
-
| `--
|
|
198
|
+
**Full flag reference:**
|
|
199
|
+
|
|
200
|
+
| Flag | Description |
|
|
201
|
+
| ---------------------------------- | ---------------------------------------------------------------------------- |
|
|
202
|
+
| `--id <id>` | System ID (lowercase, underscores only) — **REQUIRED** |
|
|
203
|
+
| `--name <name>` | Human-readable name — **REQUIRED** |
|
|
204
|
+
| `--url <url>` | API base URL — **REQUIRED** (auto-filled by `--template`) |
|
|
205
|
+
| `--template <id>` | Template ID (stripe, shopify, slack, etc.) |
|
|
206
|
+
| `--credentials <json>` | Credentials JSON (use for ALL creds in non-interactive mode) |
|
|
207
|
+
| `--sensitive-credentials <fields>` | Comma-separated fields for masked input (TTY only — do NOT use in AI agents) |
|
|
208
|
+
| `--docs-url <url>` | Documentation URL to scrape |
|
|
209
|
+
| `--openapi-url <url>` | OpenAPI spec URL |
|
|
210
|
+
| `--env <environment>` | Environment: `dev` or `prod` (default: prod) |
|
|
217
211
|
|
|
218
212
|
**`sg system edit`** — Update system config or credentials. Supports `--env dev|prod`.
|
|
219
213
|
**`sg system list` / `sg system find`** — List or search systems. `find` supports `--env dev|prod`.
|
|
220
214
|
|
|
221
215
|
**`sg system call`** — **CRITICAL for tool building.** Make authenticated calls to APIs, databases, and file servers. Use this to:
|
|
222
216
|
|
|
223
|
-
- Test system authentication works
|
|
224
217
|
- Explore API endpoints and response structures
|
|
225
218
|
- Verify field names and data shapes BEFORE building tools
|
|
226
|
-
- Debug failing tools by testing individual endpoints
|
|
227
219
|
|
|
228
220
|
```bash
|
|
229
|
-
# Include auth header with credential placeholder
|
|
230
|
-
sg system call --url https://api.example.com/users \
|
|
231
|
-
--system-id my_api \
|
|
232
|
-
--headers '{"Authorization":"Bearer <<my_api_access_token>>"}'
|
|
233
221
|
|
|
234
222
|
# POST request with auth and body
|
|
235
223
|
sg system call --url https://api.example.com/users \
|
|
@@ -303,8 +291,7 @@ sg system oauth --system-id my_api --grant-type client_credentials --scopes "rea
|
|
|
303
291
|
"body": "{ \"key\": \"<<payload_field>>\" }"
|
|
304
292
|
},
|
|
305
293
|
"dataSelector": "(sourceData) => sourceData.previousStep.data.items",
|
|
306
|
-
"
|
|
307
|
-
"failureBehavior": "abort"
|
|
294
|
+
"failureBehavior": "fail"
|
|
308
295
|
}
|
|
309
296
|
],
|
|
310
297
|
"outputTransform": "(sourceData) => sourceData.stepId.data",
|
|
@@ -313,10 +300,11 @@ sg system oauth --system-id my_api --grant-type client_credentials --scopes "rea
|
|
|
313
300
|
}
|
|
314
301
|
```
|
|
315
302
|
|
|
316
|
-
### Step Config Fields
|
|
303
|
+
### Step Config Fields (Request Steps)
|
|
317
304
|
|
|
318
305
|
| Field | Type | Description |
|
|
319
306
|
| ------------- | ------ | -------------------------------------------- |
|
|
307
|
+
| `type` | string | `"request"` (default, can be omitted) |
|
|
320
308
|
| `systemId` | string | System whose credentials to use |
|
|
321
309
|
| `url` | string | Full URL with `<<variable>>` placeholders |
|
|
322
310
|
| `method` | string | HTTP method |
|
|
@@ -325,13 +313,19 @@ sg system oauth --system-id my_api --grant-type client_credentials --scopes "rea
|
|
|
325
313
|
| `body` | string | Request body (JSON string with placeholders) |
|
|
326
314
|
| `pagination` | object | Auto-pagination config (see below) |
|
|
327
315
|
|
|
316
|
+
### Step Config Fields (Transform Steps)
|
|
317
|
+
|
|
318
|
+
| Field | Type | Description |
|
|
319
|
+
| --------------- | ------ | ------------------------------------------------ |
|
|
320
|
+
| `type` | string | `"transform"` — **REQUIRED** for transform steps |
|
|
321
|
+
| `transformCode` | string | JS function: `(sourceData) => transformedData` |
|
|
322
|
+
|
|
328
323
|
### Step Behavior Fields
|
|
329
324
|
|
|
330
325
|
| Field | Type | Description |
|
|
331
326
|
| ----------------- | ------ | ------------------------------------------------ |
|
|
332
327
|
| `dataSelector` | string | JS function controlling step input and loop mode |
|
|
333
|
-
| `
|
|
334
|
-
| `failureBehavior` | string | `abort` (default), `continue`, or `skip` |
|
|
328
|
+
| `failureBehavior` | string | `fail` (default) or `continue` |
|
|
335
329
|
|
|
336
330
|
---
|
|
337
331
|
|
|
@@ -345,15 +339,16 @@ System credentials are namespaced as `<<systemId_credentialKey>>` and resolved s
|
|
|
345
339
|
{"Authorization": "Bearer <<stripe_api_key>>"}
|
|
346
340
|
{"Authorization": "Bearer <<gmail_access_token>>"}
|
|
347
341
|
{"X-API-Key": "<<my_api_api_key>>"}
|
|
348
|
-
{"Authorization": "Basic <<
|
|
342
|
+
{"Authorization": "Basic <<my_api_username>>:<<my_api_password>>"}
|
|
349
343
|
```
|
|
350
344
|
|
|
345
|
+
Basic auth is auto-encoded: if the value after `Basic ` isn't already base64, the engine encodes it automatically.
|
|
346
|
+
|
|
351
347
|
### Credential Lifecycle
|
|
352
348
|
|
|
353
349
|
- Non-sensitive creds (`client_id`, `auth_url`, etc.) are stored via `--credentials`
|
|
354
|
-
- Sensitive creds (`api_key`, `client_secret`) use `--sensitive-credentials` for
|
|
350
|
+
- Sensitive creds (`api_key`, `client_secret`) — in non-interactive mode (AI agents, CI), pass via `--credentials` JSON. In interactive TTY, use `--sensitive-credentials` for masked input, or set `SUPERGLUE_CRED_<FIELD>` env vars.
|
|
355
351
|
- OAuth tokens (`access_token`, `refresh_token`) are auto-refreshed before each step execution
|
|
356
|
-
- Placeholders like `<<gmail_access_token>>` always resolve to the current (refreshed) token
|
|
357
352
|
|
|
358
353
|
---
|
|
359
354
|
|
|
@@ -367,7 +362,6 @@ All step config fields support `<<variable>>` placeholders:
|
|
|
367
362
|
| -------------------------- | --------------------------- |
|
|
368
363
|
| `<<fieldName>>` | Payload field or credential |
|
|
369
364
|
| `<<systemId_credKey>>` | System credential |
|
|
370
|
-
| `<<stepId.data.field>>` | Previous step result |
|
|
371
365
|
| `<<(sourceData) => expr>>` | JavaScript expression |
|
|
372
366
|
|
|
373
367
|
**CRITICAL**: Simple `<<varName>>` only works for **top-level keys**. No dots, no nesting.
|
|
@@ -426,16 +420,8 @@ sourceData.stepId = [
|
|
|
426
420
|
{ currentItem: <item2>, data: <response2>, success: true },
|
|
427
421
|
...
|
|
428
422
|
]
|
|
429
|
-
// Access all responses:
|
|
430
|
-
sourceData.stepId.map(item => item.data)
|
|
431
|
-
// Nested arrays:
|
|
432
|
-
sourceData.stepId.flatMap(item => item.data.results)
|
|
433
|
-
// Only successes:
|
|
434
|
-
sourceData.stepId.filter(item => item.success).map(i => i.data)
|
|
435
423
|
```
|
|
436
424
|
|
|
437
|
-
**NEVER** access step results without `.data` — `sourceData.stepId.results` hits the envelope, not the API response. Use `sourceData.stepId.data.results`.
|
|
438
|
-
|
|
439
425
|
### Data Selectors
|
|
440
426
|
|
|
441
427
|
Control what a step receives as input and whether it loops:
|
|
@@ -450,14 +436,46 @@ In loop mode, `sourceData.currentItem` is set to the current array element.
|
|
|
450
436
|
|
|
451
437
|
Empty arrays are valid — the step simply skips execution.
|
|
452
438
|
|
|
453
|
-
### Step
|
|
439
|
+
### Two Step Types
|
|
440
|
+
|
|
441
|
+
**Request step** (HTTP, Postgres, FTP/SFTP/SMB) — makes an API call:
|
|
454
442
|
|
|
443
|
+
```json
|
|
444
|
+
{
|
|
445
|
+
"id": "get-users",
|
|
446
|
+
"config": {
|
|
447
|
+
"type": "request",
|
|
448
|
+
"systemId": "my_api",
|
|
449
|
+
"url": "https://api.example.com/users",
|
|
450
|
+
"method": "GET",
|
|
451
|
+
"headers": { "Authorization": "Bearer <<my_api_access_token>>" }
|
|
452
|
+
}
|
|
453
|
+
}
|
|
455
454
|
```
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
455
|
+
|
|
456
|
+
**Transform step** — pure JavaScript, no API call. Use when a subsequent request step needs reshaped data:
|
|
457
|
+
|
|
458
|
+
```json
|
|
459
|
+
{
|
|
460
|
+
"id": "format-data",
|
|
461
|
+
"config": {
|
|
462
|
+
"type": "transform",
|
|
463
|
+
"transformCode": "(sourceData) => sourceData.getUsers.data.map(u => ({ id: u.id, name: u.fullName }))"
|
|
464
|
+
}
|
|
465
|
+
}
|
|
459
466
|
```
|
|
460
467
|
|
|
468
|
+
Transform steps do NOT have: `systemId`, `url`, `method`, `headers`, `body`, `queryParams`, or `pagination`. The `transformCode` function receives `sourceData` (same object available everywhere) and its return value becomes `.data` in the step envelope.
|
|
469
|
+
|
|
470
|
+
**When to use each:**
|
|
471
|
+
|
|
472
|
+
| Need | Use |
|
|
473
|
+
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
474
|
+
| Filter/reshape data for a SUBSEQUENT request step | Transform step (`config.type: "transform"`) |
|
|
475
|
+
| Shape the final tool output | `outputTransform` (runs after all steps, has a slightly different schema than transform only steps) |
|
|
476
|
+
| Select input / control looping for a step | `dataSelector` on the step |
|
|
477
|
+
| Inline data computation in URL/body/headers | `<<(sourceData) => ...>>` expressions |
|
|
478
|
+
|
|
461
479
|
### Execution Pipeline
|
|
462
480
|
|
|
463
481
|
For each step in order:
|
|
@@ -465,50 +483,10 @@ For each step in order:
|
|
|
465
483
|
1. Build `sourceData`: `{ ...originalPayload, ...previousStepResults, ...credentials }`
|
|
466
484
|
2. Run `dataSelector(sourceData)` → determines single vs loop execution
|
|
467
485
|
3. For each item: merge `currentItem` into `sourceData`, resolve `<<>>` variables, execute step
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
### Complete Example: List-then-Detail Pattern
|
|
473
|
-
|
|
474
|
-
A tool that lists Gmail message IDs, then fetches details for each:
|
|
475
|
-
|
|
476
|
-
```json
|
|
477
|
-
{
|
|
478
|
-
"id": "get-recent-emails",
|
|
479
|
-
"instruction": "Fetches the 10 most recent Gmail emails with subject, sender, and snippet",
|
|
480
|
-
"steps": [
|
|
481
|
-
{
|
|
482
|
-
"id": "list-messages",
|
|
483
|
-
"config": {
|
|
484
|
-
"systemId": "gmail",
|
|
485
|
-
"url": "https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=10",
|
|
486
|
-
"method": "GET",
|
|
487
|
-
"headers": { "Authorization": "Bearer <<gmail_access_token>>" }
|
|
488
|
-
}
|
|
489
|
-
},
|
|
490
|
-
{
|
|
491
|
-
"id": "get-details",
|
|
492
|
-
"dataSelector": "(sourceData) => sourceData[\"list-messages\"].data.messages.map(m => m.id)",
|
|
493
|
-
"config": {
|
|
494
|
-
"systemId": "gmail",
|
|
495
|
-
"url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/<<currentItem>>?format=metadata&metadataHeaders=Subject&metadataHeaders=From&metadataHeaders=Date",
|
|
496
|
-
"method": "GET",
|
|
497
|
-
"headers": { "Authorization": "Bearer <<gmail_access_token>>" }
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
],
|
|
501
|
-
"outputTransform": "(sourceData) => sourceData[\"get-details\"].map(item => { var h = item.data.payload.headers; var get = function(n) { var f = h.find(function(x) { return x.name === n; }); return f ? f.value : null; }; return { id: item.data.id, subject: get(\"Subject\"), from: get(\"From\"), date: get(\"Date\"), snippet: item.data.snippet }; })"
|
|
502
|
-
}
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
What happens at runtime:
|
|
506
|
-
|
|
507
|
-
1. **list-messages** runs once (no dataSelector) → `sourceData["list-messages"] = { currentItem: {}, data: { messages: [{id: "abc"}, {id: "def"}, ...] }, success: true }`
|
|
508
|
-
2. **get-details** dataSelector returns `["abc", "def", ...]` (an array) → step loops over each ID
|
|
509
|
-
3. Each loop iteration sets `currentItem` to the string ID, which `<<currentItem>>` injects into the URL
|
|
510
|
-
4. Loop results stored as: `sourceData["get-details"] = [{ currentItem: "abc", data: {id, snippet, payload...}, success }, ...]`
|
|
511
|
-
5. **outputTransform** maps over the array of envelopes, extracting `.data` fields from each
|
|
486
|
+
- **Request step**: makes the HTTP/DB/FTP call, raw response becomes `.data`
|
|
487
|
+
- **Transform step**: runs `transformCode(sourceData)`, return value becomes `.data`
|
|
488
|
+
4. Wrap result: `{ currentItem, data, success }` and store in `sourceData[stepId]`
|
|
489
|
+
5. After all steps: run `outputTransform(sourceData)` to shape final output
|
|
512
490
|
|
|
513
491
|
---
|
|
514
492
|
|
|
@@ -535,23 +513,14 @@ What happens at runtime:
|
|
|
535
513
|
|
|
536
514
|
All types stop when `stopCondition` returns true, response is empty, or max pages reached.
|
|
537
515
|
|
|
538
|
-
### Common Auth Patterns by Service Type
|
|
539
|
-
|
|
540
|
-
| Service | Header |
|
|
541
|
-
| ---------------------------- | ----------------------------------------------------- |
|
|
542
|
-
| OAuth (Google, GitHub, etc.) | `"Authorization": "Bearer <<systemId_access_token>>"` |
|
|
543
|
-
| API Key (Stripe, etc.) | `"Authorization": "Bearer <<systemId_api_key>>"` |
|
|
544
|
-
| API Key in header | `"X-API-Key": "<<systemId_api_key>>"` |
|
|
545
|
-
|
|
546
|
-
---
|
|
547
|
-
|
|
548
516
|
## Systems
|
|
549
517
|
|
|
550
518
|
### Credential Model
|
|
551
519
|
|
|
552
|
-
- `credentials` —
|
|
553
|
-
- `sensitiveCredentials` —
|
|
554
|
-
- **
|
|
520
|
+
- `credentials` — all credentials passed as JSON via `--credentials`
|
|
521
|
+
- `sensitiveCredentials` — interactive masked prompt for secrets (TTY only, NOT for AI agents or CI)
|
|
522
|
+
- **For AI agents / non-interactive use:** pass ALL credentials (including secrets like api_key, client_secret) directly via `--credentials '{"api_key":"..."}'`. Ask the user to provide the secret values, then include them in the JSON.
|
|
523
|
+
- **For human interactive use:** use `--sensitive-credentials` for masked input of secrets
|
|
555
524
|
|
|
556
525
|
### Templates
|
|
557
526
|
|
|
@@ -574,85 +543,12 @@ Templates auto-populate endpoints and OAuth config. Use `sg system find` to disc
|
|
|
574
543
|
|
|
575
544
|
## Debugging Failed Tools
|
|
576
545
|
|
|
577
|
-
### Common Errors and Fixes
|
|
578
|
-
|
|
579
|
-
| Error | Cause | Fix |
|
|
580
|
-
| --------------------- | ---------------------------------- | ------------------------------------------------------------------------- |
|
|
581
|
-
| 401 Unauthorized | Missing or invalid auth header | Add `"Authorization": "Bearer <<systemId_access_token>>"` to step headers |
|
|
582
|
-
| 403 Forbidden | Wrong scopes or permissions | Check OAuth scopes, re-authenticate |
|
|
583
|
-
| Empty `data: {}` | No outputTransform or dataSelector | Add `outputTransform` to extract from step results |
|
|
584
|
-
| Variable not resolved | Wrong placeholder syntax | Check `<<systemId_credKey>>` matches actual credential keys |
|
|
585
|
-
| Step references empty | Wrong step ID in reference | Verify `<<stepId.data.field>>` matches actual step IDs |
|
|
586
|
-
|
|
587
546
|
### Debug Workflow
|
|
588
547
|
|
|
589
548
|
1. Run with `--include-step-results` to see raw step responses
|
|
590
549
|
2. Check each step's `data` field — is the API returning what you expect?
|
|
591
550
|
3. Verify credential placeholders match `sg system find --id <systemId>` placeholder list
|
|
592
|
-
4. **Test API calls directly with `sg system call`** — isolate whether the issue is auth, endpoint, or transform
|
|
593
|
-
```bash
|
|
594
|
-
# Test the exact URL from your failing step
|
|
595
|
-
sg system call --url "https://api.example.com/endpoint" \
|
|
596
|
-
--system-id my_api \
|
|
597
|
-
--headers '{"Authorization":"Bearer <<my_api_access_token>>"}'
|
|
598
|
-
```
|
|
599
|
-
5. Compare `sg system call` response to what your tool expects — fix transforms accordingly
|
|
600
|
-
|
|
601
|
-
### Self-Healing Pattern
|
|
602
|
-
|
|
603
|
-
When an outputTransform or dataSelector fails, the executor retries with an LLM-generated fix. To help this:
|
|
604
|
-
|
|
605
|
-
- Throw descriptive errors: `throw new Error("Expected array at data.items, got: " + typeof data.items)`
|
|
606
|
-
- Check for null/undefined with `?.` and defaults
|
|
607
|
-
- Validate arrays with `Array.isArray()` before calling array methods
|
|
608
|
-
|
|
609
|
-
---
|
|
610
|
-
|
|
611
|
-
## Workflow Guide
|
|
612
|
-
|
|
613
|
-
### Pre-Building: Test with `sg system call`
|
|
614
|
-
|
|
615
|
-
**ALWAYS test endpoints with `sg system call` before building tools.** This is the most important step to avoid broken tools.
|
|
616
|
-
|
|
617
|
-
1. **Verify authentication** — Test that credentials work:
|
|
618
|
-
|
|
619
|
-
```bash
|
|
620
|
-
sg system call --url "https://api.example.com/me" \
|
|
621
|
-
--system-id my_api \
|
|
622
|
-
--headers '{"Authorization":"Bearer <<my_api_access_token>>"}'
|
|
623
|
-
```
|
|
624
|
-
|
|
625
|
-
2. **Explore response structure** — Understand what the API returns:
|
|
626
|
-
|
|
627
|
-
```bash
|
|
628
|
-
sg system call --url "https://api.example.com/users?limit=2" \
|
|
629
|
-
--system-id my_api \
|
|
630
|
-
--headers '{"Authorization":"Bearer <<my_api_access_token>>"}'
|
|
631
|
-
```
|
|
632
|
-
|
|
633
|
-
Look at the response to understand:
|
|
634
|
-
- Where is the data array? (`data.users`, `data.items`, `data.results`?)
|
|
635
|
-
- What fields are available? (exact field names matter!)
|
|
636
|
-
- Is there pagination info? (`nextCursor`, `hasMore`, `total`?)
|
|
637
|
-
|
|
638
|
-
3. **Test the exact endpoints your tool will use** — Don't guess:
|
|
639
|
-
```bash
|
|
640
|
-
# If your tool will fetch user details by ID:
|
|
641
|
-
sg system call --url "https://api.example.com/users/123" \
|
|
642
|
-
--system-id my_api \
|
|
643
|
-
--headers '{"Authorization":"Bearer <<my_api_access_token>>"}'
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
### Full Workflow
|
|
647
|
-
|
|
648
|
-
1. **Create system** → `sg system create --id my_api --url ... --sensitive-credentials api_key`
|
|
649
|
-
2. **Authenticate** → `sg system oauth` (if OAuth) or credentials are already set
|
|
650
|
-
3. **Test auth** → `sg system call` to verify credentials work
|
|
651
|
-
4. **Explore API** → `sg system search-docs` + more `sg system call` to test endpoints
|
|
652
|
-
5. **Build tool** → Construct full config JSON, `sg tool build --config '...'`
|
|
653
|
-
6. **Test** → `sg tool run --draft <id> --include-step-results`
|
|
654
|
-
7. **Iterate** → `sg tool edit --draft <id> --patches '[...]' --test`
|
|
655
|
-
8. **Save** → `sg tool save --draft <id>`
|
|
551
|
+
4. **Test API calls directly with `sg system call`** — isolate whether the issue is auth, endpoint, or transform
|
|
656
552
|
|
|
657
553
|
---
|
|
658
554
|
|
|
@@ -679,21 +575,24 @@ curl -X POST "https://api.superglue.cloud/v1/hooks/{toolId}?token=$SUPERGLUE_API
|
|
|
679
575
|
|
|
680
576
|
```typescript
|
|
681
577
|
import { configure, runTool } from "@superglue/client";
|
|
682
|
-
configure({ apiKey: process.env.SUPERGLUE_API_KEY });
|
|
683
|
-
const
|
|
578
|
+
configure({ apiKey: process.env.SUPERGLUE_API_KEY!, baseUrl: "https://api.superglue.cloud/v1" });
|
|
579
|
+
const response = await runTool("my-tool-id", { inputs: { userId: "123" } });
|
|
580
|
+
// response.data is a Run object: { runId, toolId, status, data, error, metadata }
|
|
684
581
|
```
|
|
685
582
|
|
|
686
583
|
### Python SDK
|
|
687
584
|
|
|
688
585
|
```python
|
|
689
586
|
import os
|
|
690
|
-
from superglue_client import
|
|
587
|
+
from superglue_client import AuthenticatedClient
|
|
691
588
|
from superglue_client.api.tools import run_tool
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
```
|
|
589
|
+
from superglue_client.models.run_request import RunRequest
|
|
590
|
+
from superglue_client.models.run_request_inputs import RunRequestInputs
|
|
695
591
|
|
|
696
|
-
|
|
592
|
+
client = AuthenticatedClient(base_url="https://api.superglue.cloud/v1", token=os.environ["SUPERGLUE_API_KEY"])
|
|
593
|
+
with client as c:
|
|
594
|
+
result = run_tool.sync("my-tool-id", client=c, body=RunRequest(inputs=RunRequestInputs.from_dict({"userId": "123"})))
|
|
595
|
+
```
|
|
697
596
|
|
|
698
597
|
---
|
|
699
598
|
|
|
@@ -723,18 +622,3 @@ Attach files with `--file key=path`. Reference in payloads with `file::<key>`. A
|
|
|
723
622
|
```bash
|
|
724
623
|
sg tool run --draft <id> --payload '{"data": "file::mysheet"}' --file mysheet=data.xlsx
|
|
725
624
|
```
|
|
726
|
-
|
|
727
|
-
## Configuration
|
|
728
|
-
|
|
729
|
-
Created by `sg init` at `.superglue/config.json` (project-local) or `~/.superglue/config.json` (global):
|
|
730
|
-
|
|
731
|
-
```json
|
|
732
|
-
{
|
|
733
|
-
"apiKey": "...",
|
|
734
|
-
"endpoint": "https://api.superglue.cloud",
|
|
735
|
-
"webEndpoint": "https://app.superglue.cloud",
|
|
736
|
-
"output": { "mode": "stdout", "directory": ".superglue/output" }
|
|
737
|
-
}
|
|
738
|
-
```
|
|
739
|
-
|
|
740
|
-
Config file is optional if `SUPERGLUE_API_KEY` and `SUPERGLUE_API_ENDPOINT` env vars are set. See **Installation & Setup** above.
|