@superglue/cli 1.1.21 → 1.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +1 -7
  3. package/dist/cli.js +307 -77
  4. package/dist/skills/superglue/SKILL.md +315 -631
  5. package/dist/skills/superglue/references/file-handling.md +180 -96
  6. package/dist/skills/superglue/references/graphql.md +131 -0
  7. package/dist/skills/superglue/references/http.md +251 -0
  8. package/dist/skills/superglue/references/integration.md +4 -2
  9. package/dist/skills/superglue/references/mssql.md +207 -0
  10. package/dist/skills/superglue/references/odbc.md +162 -0
  11. package/dist/skills/superglue/references/postgres.md +154 -0
  12. package/dist/skills/superglue/references/redis.md +68 -118
  13. package/dist/skills/superglue/references/sftp-smb.md +161 -0
  14. package/dist/skills/superglue/references/superglue-info.md +91 -0
  15. package/package.json +1 -1
  16. package/skills/superglue/SKILL.md +315 -631
  17. package/skills/superglue/references/file-handling.md +180 -96
  18. package/skills/superglue/references/graphql.md +131 -0
  19. package/skills/superglue/references/http.md +251 -0
  20. package/skills/superglue/references/integration.md +4 -2
  21. package/skills/superglue/references/mssql.md +207 -0
  22. package/skills/superglue/references/odbc.md +162 -0
  23. package/skills/superglue/references/postgres.md +154 -0
  24. package/skills/superglue/references/redis.md +68 -118
  25. package/skills/superglue/references/sftp-smb.md +161 -0
  26. package/skills/superglue/references/superglue-info.md +91 -0
  27. package/dist/skills/superglue/references/data-handling.md +0 -303
  28. package/dist/skills/superglue/references/databases.md +0 -253
  29. package/dist/skills/superglue/references/file-servers.md +0 -112
  30. package/dist/skills/superglue/references/http-apis.md +0 -248
  31. package/skills/superglue/references/data-handling.md +0 -303
  32. package/skills/superglue/references/databases.md +0 -253
  33. package/skills/superglue/references/file-servers.md +0 -112
  34. package/skills/superglue/references/http-apis.md +0 -248
@@ -1,43 +1,63 @@
1
1
  ---
2
2
  name: superglue
3
- description: "Build, test, deploy and integrate superglue tools via the sg CLI and superglue SDKs. IMPORTANT — you MUST invoke this skill and read the full reference BEFORE running ANY sg command or writing ANY superglue SDK/REST/webhook integration code. Before using the sg CLI, first check that it is installed (run sg --version; if not found, install with npm install -g @superglue/cli), then verify it is configured (check that sg init has been run or that SUPERGLUE_API_KEY and SUPERGLUE_API_ENDPOINT environment variables are set). If not, guide the user through setup first. After reading the SKILL.md file, also read the relevant references/ files for the specific topic (databases, file servers, transforms, integration/SDK)."
3
+ description: "Build, test, deploy and integrate superglue tools via the sg CLI and superglue SDKs. IMPORTANT — you MUST invoke this skill and read the full reference BEFORE running ANY sg command or writing ANY superglue SDK/REST/webhook integration code. Before using the sg CLI, first check that it is installed (run sg --version; if not found, install with npm install -g @superglue/cli), then verify it is configured (check that sg init has been run or that SUPERGLUE_API_KEY and SUPERGLUE_API_ENDPOINT environment variables are set). If not, guide the user through setup first. After reading SKILL.md, also run `sg skill <topic>` for the specific protocols and topics involved."
4
4
  ---
5
5
 
6
6
  # superglue CLI (`sg`) — Agent Reference
7
7
 
8
+ This file is the entry point for operating superglue via the `sg` CLI. It covers setup, tool building, tool editing, system management, running tools, and deployment via SDK/REST/webhooks.
9
+
10
+ For protocol-specific details (HTTP, databases, Redis, file servers, GraphQL), file handling, access rules, SDK integration, and general superglue information, run `sg skill <topic>` (linked throughout and listed at the bottom).
11
+
12
+ ## Reference Files
13
+
14
+ Read these on demand — they are authoritative for their topic and kept in sync with the web agent's skill references.
15
+
16
+ | `sg skill` command | When to read |
17
+ | ------------------------- | ---------------------------------------------------------------------------------------------------- |
18
+ | `sg skill superglue-info` | Company info, interfaces (SDK, REST API, MCP, Web), web UI layout, execution pipeline, internals |
19
+ | `sg skill integration` | Deploying tools — SDK (TS/Python) usage, REST API calls, webhook triggers, retry patterns |
20
+ | `sg skill http` | HTTP step configuration, auth patterns, file uploads, response handling, pagination, error detection |
21
+ | `sg skill graphql` | GraphQL step config, schema introspection, error recovery |
22
+ | `sg skill postgres` | PostgreSQL connection URLs, SSL/TLS handling, schema introspection, parameterized queries |
23
+ | `sg skill mssql` | MSSQL / Azure SQL connection URLs, schema introspection, parameterized queries |
24
+ | `sg skill odbc` | ODBC connections (SAP ASE / Sybase via FreeTDS), driver config, positional `?` params |
25
+ | `sg skill redis` | Redis command syntax, connection URLs, key type handling |
26
+ | `sg skill sftp-smb` | SFTP, FTP, and SMB operations, file upload/download semantics, path handling |
27
+ | `sg skill file-handling` | File detection, parsing, `file::` reference syntax, lazy base64 access, transform-produced files |
28
+ | `sg skill access-rules` | RBAC roles, tool/system permissions, mutation detection, custom rules (enterprise only) |
29
+
8
30
  ## CRITICAL RULES — READ FIRST
9
31
 
10
32
  **Pre-requisites for using the CLI**
11
33
 
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).
34
+ 1. **Check CLI exists**: Run `sg --version`. If it fails with `command not found`, install: `npm install -g @superglue/cli`.
35
+ 2. **Keep CLI and SDK up to date**: Always use the latest versions. Run `sg update` to update the CLI. For the SDK, run `npm install @superglue/client@latest` (JS) or `pip install --upgrade superglue-client` (Python).
36
+ 3. **Verify configuration**: Run `sg system list`. If it fails with `fetch failed` or auth errors, the CLI needs configuration via `sg init` (see Setup below).
14
37
 
15
38
  **Calling systems and running tools**
16
39
 
17
- 1. ALWAYS make sure you pull the relevant system context using `sg system find` before calling system endpoints and running inline JSON tools or building new tools.
18
- 2. Use `sg system search-docs` to do a targeted keyword search of system docs if you're unsure about how a system works.
40
+ 1. ALWAYS pull the relevant system context using `sg system find` before calling system endpoints and before building tools.
41
+ 2. Use `sg system search-docs` for a targeted keyword search of system docs when unsure how a system works.
19
42
 
20
- **Authentication & Credentials:**
43
+ **Authentication & Credentials**
21
44
 
22
- - **Authentication must always be explicitly configured** — nothing is injected automatically in any protocol
23
- - For HTTP: include auth headers using `<<systemId_credentialKey>>` syntax (e.g., `"Authorization": "Bearer <<systemId_access_token>>"`)
24
- - For databases/Redis/file servers: embed credential placeholders in the connection URL (e.g., `postgres://<<sys_user>>:<<sys_pass>>@host/db`)
25
- - OAuth systems also require explicit headers — only token refresh is automatic
45
+ - Authentication must ALWAYS be explicitly configured — nothing is injected automatically in any protocol.
46
+ - HTTP: include auth headers using `<<systemId_credentialKey>>` (e.g. `"Authorization": "Bearer <<my_api_access_token>>"`).
47
+ - Databases/Redis/file servers: embed credential placeholders in the connection URL (e.g. `postgres://<<sys_user>>:<<sys_pass>>@host/db`).
48
+ - OAuth: token refresh is automatic, but the header must still be explicit.
26
49
 
27
- **Saving Tools:**
50
+ **Saving tools**
28
51
 
29
- - **Don't save a tool without explicit user confirmation** — always ask "Should I save this tool?" first
30
- - After `sg tool build` + `sg tool run`, present results to the user and wait for approval
31
- - Only run `sg tool save --draft <id>` after the user explicitly confirms
52
+ - Never save a tool without explicit user confirmation. Build + run, present results, then save with `sg tool save --draft <id>` only after the user approves.
32
53
 
33
- **Credentials in Non-Interactive Environments (AI Agents, CI):**
54
+ **Non-interactive environments (AI agents, CI)**
34
55
 
35
- - **Pass ALL credentials (including secrets) directly via `--credentials` JSON**
36
- - Ask the user to provide secret values, then pass them in `--credentials '{"api_key":"sk-xxx"}'`
56
+ - Pass ALL credentials (including secrets) directly via `--credentials '{"api_key":"sk-xxx"}'`. Ask the user for secret values, then include them in the JSON.
37
57
 
38
58
  ---
39
59
 
40
- ## Installation & Setup
60
+ ## Setup
41
61
 
42
62
  ### Installing the CLI
43
63
 
@@ -45,80 +65,53 @@ description: "Build, test, deploy and integrate superglue tools via the sg CLI a
45
65
  npm install -g @superglue/cli
46
66
  ```
47
67
 
48
- After installation, the `sg` command is available globally.
68
+ After installation the `sg` command is available globally.
49
69
 
50
- ### Initialization (REQUIRED before first use)
70
+ ### Initialization
51
71
 
52
- The CLI **will not work** until configured with an API key. The endpoint defaults to `https://api.superglue.cloud` if not specified.
72
+ The CLI will not work until configured with an API key. The endpoint defaults to `https://api.superglue.cloud`.
53
73
 
54
- **Option A: Interactive setup (recommended for humans)**
74
+ **Interactive (humans):**
55
75
 
56
76
  ```bash
57
77
  sg init
58
78
  ```
59
79
 
60
- This prompts for:
61
-
62
- 1. **API Key** (required) — get one at https://app.superglue.cloud/admin?view=api-keys
63
- 2. **API Endpoint** — defaults to `https://api.superglue.cloud`
64
- 3. **Web Endpoint** — for OAuth callbacks, auto-derived from API endpoint
65
- 4. **Output mode** — `stdout` (default) or `stdout+file`
66
- 5. **Config location** — project-local (`.superglue/config.json`) or global (`~/.superglue/config.json`)
67
-
68
- It verifies the connection before saving. On success it creates the config file, a `drafts/` directory, and updates `.gitignore` if using local config.
69
-
70
- **Option B: Non-interactive init (recommended for CI and AI agents)**
80
+ Prompts for: API key (required — get one at https://app.superglue.cloud/admin?view=api-keys), API endpoint, web endpoint (for OAuth callbacks), output mode (`stdout` or `stdout+file`), and config location (project-local `.superglue/config.json` vs global `~/.superglue/config.json`). Verifies the connection before saving.
71
81
 
72
- Pass the global `--api-key` flag to skip interactive prompts and save a config file:
82
+ **Non-interactive (CI, agents):**
73
83
 
74
84
  ```bash
75
85
  sg init --api-key "your-api-key" --global
76
86
  sg init --api-key "your-api-key" --endpoint "https://custom.endpoint.com" --global
77
87
  ```
78
88
 
79
- > **Note:** `--api-key` and `--endpoint` are global flags (not shown in `sg init --help`). They work on all subcommands including `init`.
89
+ `--api-key` and `--endpoint` are global flags and work on all subcommands.
80
90
 
81
- **Option C: Environment variables (no config file)**
82
-
83
- If you don't need a persistent config file, set these env vars instead:
91
+ **Environment variables (no config file):**
84
92
 
85
93
  ```bash
86
94
  export SUPERGLUE_API_KEY="your-api-key"
87
- export SUPERGLUE_API_ENDPOINT="https://api.superglue.cloud" # optional, this is the default
95
+ export SUPERGLUE_API_ENDPOINT="https://api.superglue.cloud" # optional, this is the default
88
96
  ```
89
97
 
90
- With these set, all `sg` commands work without a config file.
91
-
92
- **Option C: CLI flags (per-command override)**
93
-
94
- ```bash
95
- sg system list --api-key "your-key" --endpoint "https://api.superglue.cloud"
96
- ```
97
-
98
- ### Config Resolution Order
99
-
100
- CLI flags > environment variables > config file (local `.superglue/config.json` > global `~/.superglue/config.json`).
98
+ **Config resolution order:** CLI flags > environment variables > local `.superglue/config.json` > global `~/.superglue/config.json`.
101
99
 
102
- ### Verifying Setup
100
+ Verify with `sg system list` — should return a list (possibly empty) without errors.
103
101
 
104
- After configuring, verify the connection works:
102
+ ### Capability Presets
105
103
 
106
- ```bash
107
- sg system list # should return a list (possibly empty) without errors
108
- ```
109
-
110
- ---
104
+ Set during `sg init` or via `SUPERGLUE_CLI_PRESET` env var. Stored in `config.json` as `"preset"`.
111
105
 
112
- ## Quick Start
106
+ | Preset | Description |
107
+ | --------- | ------------------------------------------------------------------ |
108
+ | `runner` | Run saved tools by ID only. Read-only lookups. No building/editing |
109
+ | `builder` | Runner + build/edit/save tools, call systems. No system CRUD |
110
+ | `admin` | Full access (default) |
113
111
 
114
- ```bash
115
- sg system list
116
- sg tool build --config '{"id":"...","instruction":"...","steps":[...]}'
117
- sg tool run --draft <draftId>
118
- sg tool save --draft <draftId>
119
- ```
112
+ Blocked commands print a clear error showing the current preset and how to change it.
120
113
 
121
- ## Global Flags
114
+ ### Global Flags
122
115
 
123
116
  | Flag | Description |
124
117
  | ------------------ | ------------------------------------------- |
@@ -127,243 +120,144 @@ sg tool save --draft <draftId>
127
120
  | `--api-key <key>` | Override API key |
128
121
  | `--endpoint <url>` | Override API endpoint |
129
122
 
130
- ## Capability Presets
123
+ ---
131
124
 
132
- The CLI supports three capability presets that control which commands are available. Set during `sg init` or via `SUPERGLUE_CLI_PRESET` env var. Stored in `config.json` as `"preset"`.
125
+ ## Workflow
133
126
 
134
- | Preset | Description |
135
- | --------- | ------------------------------------------------------------------ |
136
- | `runner` | Run saved tools by ID only. Read-only lookups. No building/editing |
137
- | `builder` | Runner + build/edit/save tools, call systems. No system CRUD |
138
- | `admin` | Full access (default) |
127
+ ### Building a Tool
139
128
 
140
- ### Preset-to-Command Matrix
129
+ 1. **Load relevant protocol references** via `sg skill <topic>` based on the systems involved (http, postgres, graphql, etc.)
130
+ 2. Use `sg system find` for every involved system — note `storedCredentials` and the system URL
131
+ 3. Use `sg system search-docs` for each system — look up endpoints, auth patterns, pagination, response structure
132
+ 4. Use `sg system call` to test 1-2 primary endpoints — verify response structure and field names before building
133
+ 5. Call `sg tool build --config '{...}'` with the full tool config (see Reference → Tool Config Schema)
134
+ 6. Test with `sg tool run --draft <draftId>`. Use `--include-step-results` to inspect raw step data
135
+ 7. Iterate using `sg tool edit --draft <draftId> --patches '[...]'` (see Reference → Tool Editing)
136
+ 8. Present results to the user and ask for approval. Only then run `sg tool save --draft <draftId>`
141
137
 
142
- ```
143
- Command runner builder admin
144
- ─────────────────────────────────────────────────
145
- sg init x x x
146
- sg update x x x
147
- sg skill x x x
148
- sg tool build - x x
149
- sg tool run --tool x x x
150
- sg tool run --config/etc - x x
151
- sg tool edit - x x
152
- sg tool save - x x
153
- sg tool find / list x x x
154
- sg system create - - x
155
- sg system edit - - x
156
- sg system oauth - - x
157
- sg system call - x x
158
- sg system search-docs - x x
159
- sg system find / list x x x
160
- sg run list x x x
161
- sg run get x x x
162
- ```
138
+ ### Editing a Tool
163
139
 
164
- ### Setting the Preset
140
+ 1. Use `sg tool find --id <toolId>` or `sg tool find <query>` to locate the tool and inspect its current config
141
+ 2. Determine whether upstream steps use object or array selectors so you reference `.data` correctly in downstream code
142
+ 3. Plan the JSON Patch operations (RFC 6902)
143
+ 4. Apply with `sg tool edit --tool <toolId> --patches '[...]'` (or `--draft <draftId>` for drafts)
144
+ 5. Re-run to verify behavior
165
145
 
166
- ```bash
167
- # During init (interactive or non-interactive)
168
- sg init --preset runner --api-key "..." --global
146
+ ### Creating/Editing a System
147
+
148
+ 1. Search for an existing system first: `sg system find <query>`
149
+ 2. If creating: `sg system create --name "..." --url "..." --credentials '{...}'`. Prefer `--template <id>` when one exists — it auto-fills URL and OAuth config
150
+ 3. For OAuth: `sg system oauth --system-id <id> --scopes "..."` opens a browser flow. User approves → tokens saved automatically
151
+ 4. Verify connectivity with `sg system call`
152
+ 5. For updates: `sg system edit --id <id>` with the fields to change
169
153
 
170
- # Via environment variable (overrides config.json)
171
- export SUPERGLUE_CLI_PRESET=builder
154
+ ### Running a Tool (Ad-hoc)
172
155
 
173
- # Manually edit .superglue/config.json
174
- { "preset": "runner", "apiKey": "...", ... }
156
+ ```bash
157
+ sg tool run --tool <toolId> --payload '{"userId":"123"}'
158
+ sg tool run --draft <draftId> --payload-file payload.json
175
159
  ```
176
160
 
177
- Blocked commands print a clear error with the current preset name and how to change it.
161
+ Streams live execution logs to the terminal. Use `--include-step-results` for raw per-step responses and `--include-config` for the full config dump.
178
162
 
179
- ## Command Reference
163
+ ---
180
164
 
181
- ### `sg init`
165
+ ## Reference
182
166
 
183
- Interactive setup — API key, endpoint, output mode, capability preset. Creates `.superglue/`.
167
+ ### Tool Translation (web agent tool → CLI command)
184
168
 
185
- Non-interactive: `sg init --api-key "..." --preset runner --global`
169
+ Agents familiar with the web tool names can map them directly to CLI commands:
186
170
 
187
- ### Tool Commands
171
+ | Web agent tool | CLI command | Notes |
172
+ | ---------------------------- | --------------------------------------------- | ------------------------------------------------------------------ |
173
+ | `build_tool` | `sg tool build --config '{...}'` | CLI is not AI-powered — you provide the full JSON config |
174
+ | `edit_tool` | `sg tool edit --tool <id> --patches '[...]'` | JSON Patch (RFC 6902). Use `--draft <id>` for drafts |
175
+ | `run_tool` | `sg tool run --tool <id>` / `--draft <id>` | Add `--include-step-results` to inspect per-step data |
176
+ | `save_tool` | `sg tool save --draft <draftId>` | Persists a draft to the database |
177
+ | `inspect_tool` / `find_tool` | `sg tool find --id <id>` / `sg tool find <q>` | Full config with `--id`, compact search with a query string |
178
+ | `create_system` | `sg system create --name "..." --url "..."` | Use `--template <id>` when available |
179
+ | `edit_system` | `sg system edit --id <id> ...` | Supports `--env dev\|prod` |
180
+ | `find_system` | `sg system find <query>` / `--id <id>` | Returns `storedCredentials` and system URL |
181
+ | `call_system` | `sg system call --url "..." --system-id <id>` | Authenticated ad-hoc calls for testing / schema introspection |
182
+ | `search_documentation` | `sg system search-docs --system-id <id> -k` | Targeted keyword search over ingested system docs |
183
+ | `authenticate_oauth` | `sg system oauth --system-id <id> --scopes` | Opens browser flow. Supports `--grant-type client_credentials` too |
184
+ | `get_runs` | `sg run list` / `sg run get <runId>` | Filter `list` by `--tool`, `--status`, `--source`, `--limit` |
185
+ | (no direct equivalent) | `sg init`, `sg update`, `sg skill` | CLI-specific setup, updater, and this reference system |
188
186
 
189
- **`sg tool build`** — Register a tool config. Returns a `draftId`. Not AI-powered — you provide the full config.
187
+ Web-agent-only concepts with no CLI equivalent: `load_skill` (references are accessed via `sg skill <topic>` instead), `create_schedule`/`edit_schedule`/`find_schedule` (manage schedules via web app or REST API), `authenticate_oauth`'s dedicated MCP `authenticate` tool (CLI uses `sg system oauth`).
190
188
 
191
- ```bash
192
- sg tool build --config '{"id":"...","steps":[...]}' # inline JSON
193
- sg tool build --id my-tool --instruction "..." --steps steps.json --payload '{"key":"val"}'
194
- sg tool build --config tool.json # from file
195
- ```
189
+ ### Command Reference
196
190
 
197
- | `--config <file-or-json>` | Full JSON config (file path or inline JSON string) |
198
- | `--id <id>` | Tool ID (kebab-case) |
199
- | `--instruction <text>` | Human-readable description |
200
- | `--steps <file>` | JSON file with steps array |
201
- | `--payload <json>` | Sample payload |
202
- | `--file <key=path>` | Attach file reference |
191
+ **`sg init`** — Interactive or non-interactive setup. Creates `.superglue/` config. Flags: `--api-key`, `--endpoint`, `--preset`, `--global`.
203
192
 
204
- **`sg tool run`** — Execute a draft or saved tool. Streams live execution logs to the terminal.
193
+ **Tool commands:**
205
194
 
206
195
  ```bash
196
+ sg tool build --config '{"id":"...","steps":[...]}' # inline JSON
197
+ sg tool build --config tool.json # from file
198
+ sg tool build --id my-tool --instruction "..." --steps steps.json --payload '{...}'
207
199
  sg tool run --draft <draftId> --payload '{"userId":"123"}'
208
- sg tool run --tool my-tool --payload-file payload.json
209
- ```
210
-
211
- | `--draft <id>` / `--tool <id>` | Draft ID or saved tool ID |
212
- | `--payload <json>` / `--payload-file <path>` | Payload |
213
- | `--include-step-results` | Include raw step results |
214
- | `--include-config` | Include full tool config |
215
-
216
- **`sg tool edit`** — Apply JSON Patch (RFC 6902) operations.
217
-
218
- ```bash
200
+ sg tool run --tool my-tool --payload-file payload.json --include-step-results
219
201
  sg tool edit --draft <draftId> --patches '[{"op":"replace","path":"/steps/0/config/url","value":"..."}]'
220
202
  sg tool edit --tool my-tool --patches patches.json
221
- ```
222
-
223
- | `--patches <json-or-file>` | JSON Patch array (inline or file) |
224
-
225
- **`sg tool save`** — Persist draft to database. Deletes draft file on success.
226
-
227
- ```bash
228
203
  sg tool save --draft <draftId>
204
+ sg tool list
205
+ sg tool find "shopify orders" # keyword search (compact results)
206
+ sg tool find --id my-tool # exact lookup (full config)
229
207
  ```
230
208
 
231
- **`sg tool list` / `sg tool find`**
232
-
233
- ```bash
234
- sg tool list # all non-archived tools
235
- sg tool find "shopify orders" # search (compact results)
236
- sg tool find --id my-tool # exact ID lookup (full config)
237
- ```
238
-
239
- ### System Commands
240
-
241
- **`sg system create`**
242
-
243
- **Required flags:**
244
-
245
- - `--name <name>` — Human-readable display name
246
- - `--url <url>` — API base URL (auto-filled when using `--template`)
247
-
248
- **Optional:**
249
-
250
- - `--id <id>` — System ID (lowercase, underscores only, no hyphens). Derived from `--name` if omitted.
251
- - `--template <id>` — Pre-configured template (auto-fills name and url if not provided)
252
-
253
- **Example with credentials (non-interactive — use this in AI agent / CI contexts):**
254
-
255
- ```bash
256
- sg system create --name "My API" --url https://api.example.com \
257
- --credentials '{"api_key":"sk-xxx"}'
258
- ```
259
-
260
- **With template:**
209
+ **System commands:**
261
210
 
262
211
  ```bash
212
+ sg system create --name "My API" --url https://api.example.com --credentials '{"api_key":"sk-xxx"}'
263
213
  sg system create --name "Slack" --template slack
214
+ sg system edit --id my_api --credentials '{...}'
215
+ sg system list
216
+ sg system find slack
217
+ sg system find --id my_api --env dev
218
+ sg system call --url https://api.example.com/users --system-id my_api --method GET \
219
+ --headers '{"Authorization":"Bearer <<my_api_access_token>>"}'
220
+ sg system search-docs --system-id slack -k "send message channels"
221
+ sg system oauth --system-id gmail --scopes "https://www.googleapis.com/auth/gmail.readonly"
222
+ sg system oauth --system-id my_api --grant-type client_credentials --scopes "read write"
264
223
  ```
265
224
 
266
- **Full flag reference:**
267
-
268
- | Flag | Description |
269
- | ---------------------- | ---------------------------------------------------------------------- |
270
- | `--name <name>` | Human-readable name — **REQUIRED** |
271
- | `--id <id>` | System ID (lowercase, underscores only) — derived from name if omitted |
272
- | `--url <url>` | API base URL — **REQUIRED** (auto-filled by `--template`) |
273
- | `--template <id>` | Template ID (stripe, shopify, slack, etc.) |
274
- | `--credentials <json>` | Credentials JSON (all fields including secrets) |
275
- | `--docs-url <url>` | Documentation URL to scrape |
276
- | `--openapi-url <url>` | OpenAPI spec URL |
277
- | `--env <environment>` | Environment: `dev` or `prod` (default: prod) |
278
-
279
- **`sg system edit`** — Update system config or credentials. Supports `--env dev|prod`.
280
- **`sg system list` / `sg system find`** — List or search systems. `find` supports `--env dev|prod`.
281
-
282
- **`sg system call`** — **CRITICAL for tool building.** Make authenticated calls to APIs, databases, and file servers. Use this to:
283
-
284
- - Explore API endpoints and response structures
285
- - Verify field names and data shapes BEFORE building tools
286
-
287
- ```bash
288
-
289
- # POST request with auth and body
290
- sg system call --url https://api.example.com/users \
291
- --system-id my_api \
292
- --method POST \
293
- --headers '{"Authorization":"Bearer <<my_api_access_token>>"}' \
294
- --body '{"name":"test"}'
295
-
296
- # Database query (Postgres)
297
- sg system call --url "postgres://<<my_db_host>>:5432/mydb" \
298
- --system-id my_db \
299
- --body '{"query":"SELECT * FROM users LIMIT 5"}'
300
-
301
- # Redis command
302
- sg system call --url "redis://<<my_redis_host>>:6379/0" \
303
- --system-id my_redis \
304
- --body '{"command":"HGETALL","args":["user:123"]}'
305
-
306
- # File server (SFTP)
307
- sg system call --url "sftp://<<my_sftp_host>>:22/data" \
308
- --system-id my_sftp \
309
- --body '{"operation":"list","path":"/"}'
310
- ```
311
-
312
- | Flag | Description |
313
- | ------------------- | ------------------------------------------------------------------------------------------------- |
314
- | `--url <url>` | Full URL with protocol (http/https/postgres/postgresql/mssql/sqlserver/redis/rediss/sftp/ftp/smb) |
315
- | `--system-id <id>` | System ID for credential injection |
316
- | `--method <method>` | HTTP method (GET, POST, PUT, DELETE, PATCH) |
317
- | `--headers <json>` | HTTP headers JSON with credential placeholders |
318
- | `--body <string>` | Request body (JSON string) |
319
- | `--env <env>` | Environment: `dev` or `prod` |
320
- | `--file <key=path>` | File references (repeatable) |
321
-
322
- **`sg system search-docs`** — Search system documentation.
225
+ **Run commands:**
323
226
 
324
227
  ```bash
325
- sg system search-docs --system-id slack -k "send message channels"
228
+ sg run list --tool my-tool --status failed --limit 20
229
+ sg run get <runId> --fetch-results
326
230
  ```
327
231
 
328
- **`sg system oauth`** — Authenticate via OAuth.
232
+ **File attachments:**
329
233
 
330
234
  ```bash
331
- sg system oauth --system-id gmail --scopes "https://www.googleapis.com/auth/gmail.readonly"
332
- sg system oauth --system-id my_api --grant-type client_credentials --scopes "read write"
235
+ sg tool run --draft <id> --payload '{"data":"file::mysheet"}' --file mysheet=data.xlsx
333
236
  ```
334
237
 
335
- | `--system-id <id>` | Required |
336
- | `--scopes <scopes>` | Space-separated OAuth scopes (required) |
337
- | `--grant-type <type>` | `authorization_code` (default) or `client_credentials` |
338
-
339
- ### Run Commands
340
-
341
- **`sg run list`** — List execution runs. Filter by `--tool`, `--status`, `--source`, `--limit`.
342
- **`sg run get <runId>`** — Get run details. `--fetch-results` to include data.
343
-
344
- ---
238
+ Attach files with repeatable `--file key=path`. Reference in payloads with `file::<key>`. Auto-parsed to JSON where applicable. See `sg skill file-handling` for the full reference syntax including `.raw`, `.base64`, and `.extracted` suffixes.
345
239
 
346
- ## Tool Configuration — Full Schema
240
+ ### Tool Config Schema
347
241
 
348
242
  ```json
349
243
  {
350
244
  "id": "kebab-case-tool-name",
351
- "instruction": "Brief human-readable description of what this tool does",
245
+ "instruction": "Brief 1-2 sentence description of what this tool does and returns",
352
246
  "steps": [
353
247
  {
354
248
  "id": "unique-step-id",
355
249
  "config": {
250
+ "type": "request",
356
251
  "systemId": "example_system",
357
- "url": "https://api.example.com/endpoint?param=<<payload_field>>",
252
+ "url": "<<example_system_url>>/endpoint?param=<<payload_field>>",
358
253
  "method": "GET",
359
- "headers": {
360
- "Authorization": "Bearer <<example_system_access_token>>"
361
- },
254
+ "headers": { "Authorization": "Bearer <<example_system_access_token>>" },
362
255
  "queryParams": { "limit": "10" },
363
256
  "body": "{ \"key\": \"<<payload_field>>\" }"
364
257
  },
365
258
  "dataSelector": "(sourceData) => sourceData.previousStep.data.items",
366
- "failureBehavior": "fail"
259
+ "failureBehavior": "fail",
260
+ "modify": false
367
261
  }
368
262
  ],
369
263
  "outputTransform": "(sourceData) => sourceData.stepId.data",
@@ -372,91 +266,66 @@ sg system oauth --system-id my_api --grant-type client_credentials --scopes "rea
372
266
  }
373
267
  ```
374
268
 
375
- ### Step Config Fields (Request Steps)
269
+ **Request step fields** (HTTP, Postgres, MSSQL, Redis, FTP/SFTP, SMB) — see protocol-specific references for full details:
376
270
 
377
- | Field | Type | Description |
378
- | ------------- | ------ | -------------------------------------------- |
379
- | `type` | string | `"request"` (default, can be omitted) |
380
- | `systemId` | string | System whose credentials to use |
381
- | `url` | string | Full URL with `<<variable>>` placeholders |
382
- | `method` | string | HTTP method |
383
- | `headers` | object | HTTP headers with credential placeholders |
384
- | `queryParams` | object | URL query parameters |
385
- | `body` | string | Request body (JSON string with placeholders) |
386
- | `pagination` | object | Auto-pagination config (see below) |
271
+ | Field | Type | Description |
272
+ | ------------- | ------ | ------------------------------------------------------------------------ |
273
+ | `type` | string | `"request"` (default, can be omitted) |
274
+ | `systemId` | string | Optional. Links system credentials for `<<systemId_credKey>>` resolution |
275
+ | `url` | string | Full URL with `<<variable>>` placeholders. Required. |
276
+ | `method` | string | HTTP method (HTTP only) |
277
+ | `headers` | object | HTTP headers with credential placeholders (HTTP only) |
278
+ | `queryParams` | object | URL query parameters (HTTP only) |
279
+ | `body` | string | Request body / DB query / Redis command / file operation |
280
+ | `pagination` | object | Auto-pagination config (HTTP only, see `sg skill http`) |
387
281
 
388
- ### Step Config Fields (Transform Steps)
282
+ **Transform step fields:**
389
283
 
390
- | Field | Type | Description |
391
- | --------------- | ------ | ------------------------------------------------ |
392
- | `type` | string | `"transform"` — **REQUIRED** for transform steps |
393
- | `transformCode` | string | JS function: `(sourceData) => transformedData` |
284
+ | Field | Type | Description |
285
+ | --------------- | ------ | -------------------------------------------------- |
286
+ | `type` | string | `"transform"` — required for transform steps |
287
+ | `transformCode` | string | `(sourceData) => transformedData` — single-line JS |
394
288
 
395
- ### Step Behavior Fields
289
+ Transform steps do NOT have `systemId`, `url`, `method`, `headers`, `body`, `queryParams`, or `pagination`.
396
290
 
397
- | Field | Type | Description |
398
- | ----------------- | ------ | ------------------------------------------------ |
399
- | `dataSelector` | string | JS function controlling step input and loop mode |
400
- | `failureBehavior` | string | `fail` (default) or `continue` |
291
+ **Step behavior fields:**
401
292
 
402
- ---
293
+ | Field | Type | Description |
294
+ | ----------------- | ------- | ---------------------------------------------------- |
295
+ | `dataSelector` | string | JS function controlling step input and loop mode |
296
+ | `failureBehavior` | string | `fail` (default) or `continue` |
297
+ | `modify` | boolean | Set `true` only when the step writes/updates/deletes |
403
298
 
404
- ## Credential Placeholders
299
+ ### Expression Syntax (`<<>>`)
405
300
 
406
- System credentials are namespaced as `<<systemId_credentialKey>>` and resolved server-side at execution time. **You MUST explicitly reference them in headers.**
301
+ All step config fields (url, headers, body, queryParams) support `<<expression>>` placeholders.
407
302
 
408
- ### Auth Header Patterns
303
+ **Simple top-level keys** — only these work without arrow functions:
409
304
 
410
- ```json
411
- {"Authorization": "Bearer <<stripe_api_key>>"}
412
- {"Authorization": "Bearer <<gmail_access_token>>"}
413
- {"X-API-Key": "<<my_api_api_key>>"}
414
- {"Authorization": "Basic <<my_api_username>>:<<my_api_password>>"}
305
+ ```
306
+ <<userId>> payload inputs
307
+ <<currentItem>> whole current loop item
308
+ <<page>> <<offset>> <<cursor>> <<limit>> <<pageSize>> pagination variables
309
+ <<systemId_api_key>> system credentials (namespaced: systemId_credKey)
310
+ <<systemId_url>> system base URLs (namespaced: systemId_url)
311
+ <<sg_auth_email>> email of the authenticated user (NOT available in scheduled runs)
415
312
  ```
416
313
 
417
- Basic auth is auto-encoded: if the value after `Basic ` isn't already base64, the engine encodes it automatically.
418
-
419
- ### Credential Lifecycle
420
-
421
- - Non-sensitive creds (`client_id`, `auth_url`, etc.) are stored via `--credentials`
422
- - Sensitive creds (`api_key`, `client_secret`) — pass via `--credentials` JSON: `--credentials '{"client_secret":"..."}'`
423
- - OAuth tokens (`access_token`, `refresh_token`) are auto-refreshed before each step execution
424
-
425
- ---
426
-
427
- ## Variables and Data Flow
428
-
429
- ### Variable Syntax
430
-
431
- All step config fields support `<<variable>>` placeholders:
432
-
433
- | Syntax | Resolves to |
434
- | -------------------------- | --------------------------- |
435
- | `<<fieldName>>` | Payload field or credential |
436
- | `<<systemId_credKey>>` | System credential |
437
- | `<<sg_auth_email>>` | Email of authenticated user |
438
- | `<<(sourceData) => expr>>` | JavaScript expression |
439
-
440
- **CRITICAL**: Simple `<<varName>>` only works for **top-level keys**. No dots, no nesting.
441
-
442
- - VALID: `<<userId>>`, `<<currentItem>>`, `<<stripe_api_key>>`, `<<sg_auth_email>>`
443
- - INVALID: `<<currentItem.id>>`, `<<sourceData.userId>>` — these FAIL at runtime
444
-
445
- For nested access, use arrow functions: `<<(sourceData) => sourceData.currentItem.id>>`
446
-
447
- ### Context Variables
448
-
449
- Context variables provide information about the execution environment:
314
+ Simple `<<varName>>` only works for top-level keys. No dots, no nesting. `<<currentItem.id>>`, `<<sourceData.userId>>`, `<<user.name>>` all FAIL at runtime.
450
315
 
451
- - `<<sg_auth_email>>` — Email of the authenticated user who triggered the tool
316
+ **Arrow function expressions** — for everything else:
452
317
 
453
- **Use case**: Personalize tool outputs based on who runs the tool (e.g., user-specific permissions, account lookups, audit logging).
318
+ ```
319
+ <<(sourceData) => sourceData.currentItem.player_id>>
320
+ <<(sourceData) => sourceData.getUsers.data.map(u => u.id)>>
321
+ <<(sourceData) => JSON.stringify({ ids: sourceData.fetchUsers.data.map(u => u.id) })>>
322
+ ```
454
323
 
455
- **Important**: `sg_auth_email` is NOT available in scheduled executions. Tools using `<<sg_auth_email>>` will fail if run via scheduler.
324
+ Object/array return values are `JSON.stringify`'d automatically when spliced into strings.
456
325
 
457
326
  ### sourceData Object
458
327
 
459
- `sourceData` is the cumulative state available to all JS expressions (data selectors, transforms, variable expressions):
328
+ `sourceData` is the cumulative state available to every JS expression, data selector, and transform:
460
329
 
461
330
  ```javascript
462
331
  sourceData = {
@@ -465,45 +334,30 @@ sourceData = {
465
334
  date: "2024-01-15",
466
335
 
467
336
  // Previous step results, keyed by step ID
468
- // Object-selector step:
469
- getUsers: { currentItem: {}, data: { users: [...] }, success: true },
470
- // Array-selector (loop) step:
471
- fetchDetails: [
337
+ getUsers: { currentItem: {}, data: { users: [...] }, success: true }, // object selector
338
+ fetchDetails: [ // array selector
472
339
  { currentItem: "id1", data: { name: "Alice" }, success: true },
473
- { currentItem: "id2", data: { name: "Bob" }, success: true },
340
+ { currentItem: "id2", data: { name: "Bob" }, success: true }
474
341
  ],
475
342
 
476
343
  // Current loop item (only set inside a looping step's config)
477
344
  currentItem: { id: 1 },
478
345
 
479
346
  // Credentials (flattened, namespaced)
480
- systemId_access_token: "...",
481
- systemId_api_key: "..."
347
+ my_api_access_token: "...",
348
+ my_api_api_key: "..."
482
349
  }
483
350
  ```
484
351
 
485
- ### Step Result Envelope
486
-
487
- **Every** step result is wrapped in an envelope — you MUST account for this.
488
-
489
- **Object selector (or no selector)** — step runs once:
352
+ ### Step Result Envelopes
490
353
 
491
- ```javascript
492
- sourceData.stepId = { currentItem: <selectorOutput>, data: <apiResponse>, success: true }
493
- // Access the API response:
494
- sourceData.stepId.data
495
- sourceData.stepId.data.users
496
- ```
354
+ **Every** step result is wrapped in `{ currentItem, data, success }`. You MUST account for this when writing data selectors or transforms.
497
355
 
498
- **Array selector** — step loops, result is an array of envelopes:
356
+ - **Object selector (or none)** — access via `sourceData.stepId.data`
357
+ - **Array selector (loop)** — array of envelopes: `sourceData.stepId.map(i => i.data)`
358
+ - **Paginated step** — all pages merged into a single `.data` field: access via `sourceData.stepId.data`. Do NOT `.map()` over it — returns a single object if one result, array if multiple (unwrapped from single-element array).
499
359
 
500
- ```javascript
501
- sourceData.stepId = [
502
- { currentItem: <item1>, data: <response1>, success: true },
503
- { currentItem: <item2>, data: <response2>, success: true },
504
- ...
505
- ]
506
- ```
360
+ NEVER access step results without `.data`. `sourceData.stepId.results` hits the envelope, not the API response.
507
361
 
508
362
  ### Data Selectors
509
363
 
@@ -515,49 +369,30 @@ Control what a step receives as input and whether it loops:
515
369
  | Array | Step runs once per item (loop mode) |
516
370
  | `undefined`/`null` | Step receives full sourceData |
517
371
 
518
- In loop mode, `sourceData.currentItem` is set to the current array element.
372
+ In loop mode, `sourceData.currentItem` is set to the current array element. Empty arrays are valid — the step skips execution.
519
373
 
520
- Empty arrays are valid — the step simply skips execution.
374
+ ### Transform Steps vs outputTransform
521
375
 
522
- ### Two Step Types
376
+ | Need | Use |
377
+ | ------------------------------------------- | ---------------------------------------------------------------------- |
378
+ | Reshape data for a SUBSEQUENT request step | Transform step (`config.type: "transform"`) |
379
+ | Shape the final tool output | `outputTransform` (runs after all steps; slightly different signature) |
380
+ | Control input / looping for a step | `dataSelector` on the step |
381
+ | Inline data computation in URL/body/headers | `<<(sourceData) => ...>>` expressions |
523
382
 
524
- **Request step** (HTTP, PostgreSQL, MSSQL, Redis, FTP/SFTP/SMB) — makes an API call:
383
+ `outputTransform` must be a single-line JS string (no literal newlines or tabs).
525
384
 
526
- ```json
527
- {
528
- "id": "get-users",
529
- "config": {
530
- "type": "request",
531
- "systemId": "my_api",
532
- "url": "https://api.example.com/users",
533
- "method": "GET",
534
- "headers": { "Authorization": "Bearer <<my_api_access_token>>" }
535
- }
536
- }
537
- ```
385
+ **File output:** To make files downloadable from the tool's API response, set `outputFile: true` on the step that produces the file. The `outputTransform` is for shaping JSON data only — it does not handle files. Libraries `Papa` (CSV), `XLSX` (Excel), and `yaml` (YAML) are available in all transforms. See `sg skill file-handling` for details. Use `sg run download <runId>` to download artifacts.
538
386
 
539
- **Transform step** — pure JavaScript, no API call. Use when a subsequent request step needs reshaped data:
387
+ **Complex request bodies** — when a body needs data from multiple steps or aggregation, use a preceding transform step:
540
388
 
541
- ```json
542
- {
543
- "id": "format-data",
544
- "config": {
545
- "type": "transform",
546
- "transformCode": "(sourceData) => sourceData.getUsers.data.map(u => ({ id: u.id, name: u.fullName }))"
547
- }
548
- }
549
- ```
550
-
551
- 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.
552
-
553
- **When to use each:**
389
+ ```javascript
390
+ // Step: prepareBody (transform)
391
+ transformCode: "(sourceData) => { var items = sourceData.step1.data.results; return { data: items.filter(function(i) { return i.active; }), count: items.length }; }";
554
392
 
555
- | Need | Use |
556
- | ------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
557
- | Filter/reshape data for a SUBSEQUENT request step | Transform step (`config.type: "transform"`) |
558
- | Shape the final tool output | `outputTransform` (runs after all steps, has a slightly different schema than transform only steps) |
559
- | Select input / control looping for a step | `dataSelector` on the step |
560
- | Inline data computation in URL/body/headers | `<<(sourceData) => ...>>` expressions |
393
+ // Step: submitData (request)
394
+ body: "<<(sourceData) => JSON.stringify(sourceData.prepareBody.data)>>";
395
+ ```
561
396
 
562
397
  ### Execution Pipeline
563
398
 
@@ -566,187 +401,77 @@ For each step in order:
566
401
  1. Build `sourceData`: `{ ...originalPayload, ...previousStepResults, ...credentials }`
567
402
  2. Run `dataSelector(sourceData)` → determines single vs loop execution
568
403
  3. For each item: merge `currentItem` into `sourceData`, resolve `<<>>` variables, execute step
569
- - **Request step**: makes the HTTP/DB/FTP call, raw response becomes `.data`
404
+ - **Request step**: makes the HTTP/DB/FTP/Redis call, raw response becomes `.data`
570
405
  - **Transform step**: runs `transformCode(sourceData)`, return value becomes `.data`
571
406
  4. Wrap result: `{ currentItem, data, success }` and store in `sourceData[stepId]`
572
407
  5. After all steps: run `outputTransform(sourceData)` to shape final output
573
408
 
574
- ---
409
+ All user-provided JS runs in an isolated Deno sandbox.
575
410
 
576
- ## HTTP API Patterns
411
+ ### Credentials and Systems
577
412
 
578
- ### Pagination
413
+ Credentials are namespaced as `<<systemId_credentialKey>>` and resolved server-side at execution time. You MUST explicitly reference them:
579
414
 
580
- ```json
581
- {
582
- "pagination": {
583
- "type": "offset|cursor|page",
584
- "pageSize": 100,
585
- "cursorPath": "$.nextPageToken",
586
- "stopCondition": "(response) => !response.hasMore"
587
- }
588
- }
415
+ ```
416
+ System id="stripe", storedCredentials: api_key → "sk_proj****"
417
+ → Available as: <<stripe_api_key>>
589
418
  ```
590
419
 
591
- | Type | How it works |
592
- | -------- | ------------------------------------------------------------ |
593
- | `offset` | Increments `offset` param by `pageSize` each page |
594
- | `cursor` | Extracts next cursor from `cursorPath`, sends as query param |
595
- | `page` | Increments `page` query param |
596
-
597
- All types stop when `stopCondition` returns true, response is empty, or max pages reached.
598
-
599
- ## Systems
600
-
601
- ### Credential Model
602
-
603
- - `credentials` — all credentials passed as JSON via `--credentials`
604
- - **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.
605
- - OAuth tokens (`access_token`, `refresh_token`) are auto-refreshed before each step execution
420
+ **Auth header patterns:**
606
421
 
607
- ### Templates
422
+ ```json
423
+ {"Authorization": "Bearer <<stripe_api_key>>"}
424
+ {"Authorization": "Bearer <<gmail_access_token>>"}
425
+ {"X-API-Key": "<<my_api_api_key>>"}
426
+ {"Authorization": "Basic <<my_api_username>>:<<my_api_password>>"}
427
+ ```
608
428
 
609
- Templates auto-populate endpoints and OAuth config. Use `sg system find` to discover available templates.
429
+ Basic auth auto-encodes: if the value after `Basic ` isn't already base64, the engine encodes it.
610
430
 
611
- **Preconfigured OAuth** (no user client_id/secret needed): slack, salesforce, asana, notion, airtable, jira, confluence
431
+ **System URL variables** — use these instead of hardcoding base URLs. They switch automatically between dev/prod environments:
612
432
 
613
- ### OAuth Flow
433
+ ```json
434
+ { "url": "<<salesforce_url>>/services/data/v58.0/sobjects/Account" }
435
+ ```
614
436
 
615
- **IMPORTANT:** For OAuth systems, prefer `--template` when available because it auto-configures OAuth URLs and defaults. OAuth also works without a template if you provide required credentials (for example `client_id`, `auth_url`, and `token_url`) manually.
437
+ **Credential lifecycle:**
616
438
 
617
- If you don't know the template ID, the CLI auto-detects it from the URL — but using `--template` explicitly is more reliable.
439
+ - Pass ALL credentials (including secrets) via `--credentials '{"api_key":"...","client_secret":"..."}'` on create/edit
440
+ - OAuth tokens (`access_token`, `refresh_token`) auto-refresh before each step execution
441
+ - Non-sensitive fields (`client_id`, `auth_url`, `token_url`) are stored alongside secrets in the same `--credentials` JSON
618
442
 
619
- **Step 1: Create the system with template and credentials**
443
+ **System IDs:** lowercase letters, numbers, underscores only — no hyphens. Used for credential namespacing.
620
444
 
621
- ```bash
622
- # Best: explicit template (auto-fills URL and OAuth config)
623
- sg system create --name "Gmail" --template gmail \
624
- --credentials '{"client_id":"...","client_secret":"..."}'
445
+ **Templates:** auto-populate endpoints and OAuth config. `sg system find` lists available templates.
625
446
 
626
- # Also works: URL-based auto-detection (template inferred from googleapis.com)
627
- sg system create --name "Gmail" --url https://gmail.googleapis.com \
628
- --credentials '{"client_id":"...","client_secret":"..."}'
629
- ```
447
+ - **Preconfigured OAuth** (no user `client_id`/`client_secret` needed): slack, salesforce, asana, notion, airtable, jira, confluence
448
+ - **Common OAuth templates:** gmail, googleDrive, googleCalendar, googleSheets, slack, salesforce, github, jira, confluence, notion, airtable, hubspot, shopify, dropbox, zoom, microsoft
630
449
 
631
- **For custom OAuth systems without a template**, you must include `client_id`, `client_secret`, `auth_url`, and `token_url` in the credentials at create time — or add them later with `sg system edit` before running `sg system oauth`:
450
+ **Custom OAuth (no template):** must include `client_id`, `client_secret`, `auth_url`, `token_url` in credentials at create time — or add later with `sg system edit`:
632
451
 
633
452
  ```bash
634
453
  sg system create --name "My API" --url https://api.example.com \
635
454
  --credentials '{"client_id":"...","client_secret":"...","auth_url":"https://example.com/oauth/authorize","token_url":"https://example.com/oauth/token"}'
636
-
637
- # Or add credentials to an existing system:
638
- sg system edit --id my_api \
639
- --credentials '{"client_id":"...","client_secret":"...","auth_url":"https://...","token_url":"https://..."}'
640
- ```
641
-
642
- **Step 2: Authenticate via OAuth**
643
-
644
- ```bash
645
- sg system oauth --system-id gmail --scopes "https://www.googleapis.com/auth/gmail.readonly"
646
- ```
647
-
648
- **Step 3:** User authenticates in browser → tokens saved automatically
649
-
650
- **Common OAuth templates:** gmail, googleDrive, googleCalendar, googleSheets, slack, salesforce, github, jira, confluence, notion, airtable, hubspot, shopify, dropbox, zoom, microsoft
651
-
652
- ### System IDs
653
-
654
- - Lowercase letters, numbers, underscores only — **no hyphens**
655
- - Used for credential namespacing: `<<systemId_credKey>>`
656
-
657
- ---
658
-
659
- ## Tool Building Guide
660
-
661
- ### Build Recipe
662
-
663
- Before producing a tool config:
664
-
665
- 1. Load relevant skills: data-handling and protocol skill(s) for the involved systems
666
- 2. Use `sg system find` for every involved system — note `storedCredentials` and URL
667
- 3. Use `sg system search-docs` for each system — look up endpoints, auth patterns, pagination, response structure
668
- 4. Use `sg system call` to test 1-2 primary endpoints — verify response structure and field names before building
669
- 5. Only then call `sg tool build --config '...'` with the full tool config
670
-
671
- ### Planning Steps
672
-
673
- - Fetch prerequisites: available projects, entity types, categories, etc.
674
- - Each step = one API call, one DB query, one file operation, or a transform step (no compound ops)
675
- - Final aggregation/filtering/sorting should happen in the `outputTransform`, not in a step
676
- - Step instructions: 2-3 sentences describing the goal and expected data
677
- - `instruction`: Write a 1-2 sentence summary of the tool's purpose. Never leave empty.
678
-
679
- ### Step Result Envelopes
680
-
681
- Every step result is wrapped — you MUST account for this in dataSelectors and outputTransform.
682
-
683
- - **Object selector (or none)** — access via `sourceData.stepId.data`
684
- - **Array selector** — access via `sourceData.stepId.map(i => i.data)`
685
- - **Paginated step** — access via `sourceData.stepId.data` (pages are merged server-side into a single envelope — do NOT `.map()` over it)
686
-
687
- NEVER access step results without `.data` — `sourceData.stepId.results` will fail because you're hitting the envelope, not the API response.
688
-
689
- ### modify Flag
690
-
691
- Set `modify: true` only when the step writes, updates, or deletes live data. Don't rely on HTTP method alone — a POST that only reads (e.g., GraphQL query) should be `modify: false`. Default is false.
692
-
693
- ### Validation Rules
694
-
695
- - Tool must have a valid `id` string
696
- - Tool must have a `steps` array
697
- - `systemId` is optional on request steps. Setting it makes that system's credentials available as `<<systemId_credKey>>` template variables, and enables `<<systemId_url>>` for the base URL. Omit for public APIs.
698
- - Every request step must have a non-empty `url`
699
- - Transform steps must have `transformCode`
700
-
701
- ### Key Pitfalls
702
-
703
- - NEVER guess API endpoints — always verify with `sg system search-docs` or `sg system call` first
704
- - NEVER put `systemId` on the step object — it belongs inside `step.config.systemId`
705
- - NEVER use `<<(sourceData) => sourceData.payload.X>>` — payload fields are at root level of sourceData
706
- - NEVER use `<<currentItem.id>>` — use arrow function syntax: `<<(sourceData) => sourceData.currentItem.id>>`
707
- - NEVER hardcode pagination params — use `<<page>>`, `<<offset>>`, `<<cursor>>`, `<<limit>>`
708
- - NEVER add an `outputSchema` unless the user explicitly requested a specific response structure
709
- - NEVER leave instructions empty
710
- - ALWAYS explicitly configure authentication in every step — credentials are never automatically included in any protocol
711
- - PREFER system URL variables (`<<systemId_url>>`) over hardcoded base URLs
712
- - Check `sg system find` output for `storedCredentials` to know the exact variable names available
713
- - `outputTransform` must be a single-line JS string (no literal newlines or tabs)
714
- - NEVER use regex literals with `/` or complex escapes in transforms — they corrupt during serialization. Use `new URL()`, `.split()`, or `new RegExp()` instead. See data-handling reference "Serialization Safety".
715
- - For complex request bodies, use a preceding transform step — don't put multi-statement logic inside `<<>>` expressions
716
- - When the body contains nested/stringified JSON (e.g. LLM APIs): have `<<>>` expressions return a string via `JSON.stringify(...)`, and use a single expression for the whole body rather than mixing `<<>>` expressions with static JSON
717
-
718
- ### Complex Body Construction
719
-
720
- When a request body needs data from multiple steps or requires aggregation, use a preceding transform step:
721
-
722
- ```javascript
723
- // Step: prepareBody (transform)
724
- transformCode: "(sourceData) => { var items = sourceData.step1.data.results; return { data: items.filter(function(i) { return i.active; }), count: items.length }; }";
725
-
726
- // Step: submitData (request)
727
- body: "<<(sourceData) => JSON.stringify(sourceData.prepareBody.data)>>";
728
455
  ```
729
456
 
730
- ---
731
-
732
- ## Tool Editing Guide
457
+ **Dev/Prod environments:** `--env dev|prod` at creation (immutable afterward). Two systems with the same ID but different environments are automatically linked. Dev systems inherit documentation from their linked prod system. When creating a dev system, always ask for new credentials — never copy from prod.
733
458
 
734
- Edit tools using RFC 6902 JSON Patch operations via `sg tool edit`.
459
+ **System-specific instructions:** systems may include `specificInstructions` from the user (visible in `sg system find` output). Follow them when present — they override general patterns.
735
460
 
736
- ### Patch Format
461
+ ### Tool Editing (JSON Patch)
737
462
 
738
- Each operation:
463
+ `sg tool edit` applies RFC 6902 JSON Patch operations. Each operation:
739
464
 
740
465
  ```typescript
741
466
  {
742
467
  op: "add" | "remove" | "replace" | "move" | "copy" | "test",
743
- path: string, // JSON Pointer (e.g., "/steps/0/config/url")
744
- value?: any, // required for add, replace, test
745
- from?: string // required for move, copy
468
+ path: string, // JSON Pointer, e.g. "/steps/0/config/url"
469
+ value?: any, // required for add, replace, test
470
+ from?: string // required for move, copy
746
471
  }
747
472
  ```
748
473
 
749
- ### Key Paths
474
+ **Key paths:**
750
475
 
751
476
  - `/instruction` — tool description
752
477
  - `/steps/N` — step at index N
@@ -755,148 +480,107 @@ Each operation:
755
480
  - `/outputTransform` — final output shaping function
756
481
  - `/outputSchema` — optional JSON schema for output
757
482
 
758
- ### Operations
759
-
760
- - **`replace`** — Change an existing value. **Path must exist** — if the field is `null` or absent, `replace` fails. Use `add` instead for optional fields.
761
- - **`add`** — Creates the field if missing, overwrites if it exists. **Prefer `add` over `replace`** when the field might be null or absent. Append to array with `/steps/-`.
762
- - **`remove`** — Delete field or array element.
763
- - **`move`** — Reorder or relocate.
764
-
765
- ### Validation Rules
766
-
767
- - Never patch `id` — tool IDs and draft IDs are immutable when editing
768
- - `op` and `path` are required on every patch; `path` must start with `/`
769
- - Patches are applied **sequentially** — later patches see effects of earlier ones
770
- - After patches, same validation rules as building apply (valid id, steps array, URLs present)
771
-
772
- ### Principles
773
-
774
- - **Check result wrapping** — before writing any dataSelector or outputTransform patch, determine whether the upstream step used an object or array selector, and access `.data` accordingly
775
- - **Don't forget downstream** — if you change a step's output shape, check if later dataSelectors and outputTransform need updating
776
- - **Index shifts** — when removing array elements, subsequent indices shift down. Account for this in multi-patch operations.
777
-
778
- ---
779
-
780
- ## Systems Handling Guide
781
-
782
- Systems are reusable building blocks that store configuration details and credentials.
483
+ **Operations:**
783
484
 
784
- ### Credential Use in Tool Configurations
485
+ - `replace` — Change an existing value. **Path must exist** — if the field is `null` or absent, `replace` fails. Prefer `add` when the field might be absent.
486
+ - `add` — Creates if missing, overwrites if present. Append to array with `/steps/-`.
487
+ - `remove` — Delete field or array element.
488
+ - `move` — Reorder or relocate.
785
489
 
786
- For every `systemId` referenced in a tool, credentials are namespaced as `<<systemId_credentialKey>>` and must be explicitly placed in the step config. For HTTP: in headers. For databases/Redis/file servers: in the connection URL. Nothing is injected automatically.
490
+ **Validation:**
787
491
 
788
- ```
789
- System id="stripe", storedCredentials: api_key → "sk_proj****"
790
- → Available as: <<stripe_api_key>>
791
- ```
792
-
793
- OAuth tokens (`access_token`, `refresh_token`) are auto-refreshed before each step execution. Access tokens must also be explicitly referenced in step headers.
794
-
795
- ### System URL Variables
796
-
797
- System URLs are available as `<<systemId_url>>` and should be used instead of hardcoding base URLs:
798
-
799
- ```
800
- System id="salesforce", url="https://mycompany.salesforce.com"
801
- → Available as: <<salesforce_url>>
802
-
803
- Step config: { "url": "<<salesforce_url>>/services/data/v58.0/sobjects/Account" }
804
- ```
805
-
806
- ### Dev/Prod Environments
807
-
808
- `environment` is `"dev"` or `"prod"` (or unset for legacy systems). Set at creation only — immutable afterward. Two systems with the same ID but different environments are automatically linked. Dev systems inherit documentation from their linked prod system. When creating a dev system, always ask for new credentials — never copy from prod.
809
-
810
- Tools reference systems by ID only. Execution mode determines which environment is used (dev mode falls back to prod if no dev system exists).
811
-
812
- ### System-Specific Instructions
492
+ - Never patch `id` — tool IDs and draft IDs are immutable
493
+ - `op` and `path` required; `path` must start with `/`
494
+ - Patches applied **sequentially** — later patches see effects of earlier ones
495
+ - After patches, same validation as building (valid id, steps array, URLs on request steps, transformCode on transform steps)
813
496
 
814
- Systems may include `specificInstructions` from the user (visible in `sg system find` output). Follow them when present. These capture API constraints, rate limits, special endpoints, auth requirements, or usage patterns.
497
+ **Downstream shape changes:** if you change a step's output shape, check if later dataSelectors and `outputTransform` need updating. When removing array elements, subsequent indices shift down.
815
498
 
816
- ---
817
-
818
- ## Debugging Failed Tools
499
+ ### Draft Management
819
500
 
820
- ### Debug Workflow
501
+ Drafts live in `.superglue/drafts/<draftId>.json`. Created by `sg tool build`, updated by `sg tool edit`, deleted by `sg tool save`. Ephemeral — not persisted across sessions.
821
502
 
822
- 1. Run with `--include-step-results` to see raw step responses
823
- 2. Check each step's `data` field — is the API returning what you expect?
824
- 3. Verify credential placeholders match `sg system find --id <systemId>` placeholder list
825
- 4. **Test API calls directly with `sg system call`** — isolate whether the issue is auth, endpoint, or transform
826
-
827
- ---
503
+ ### Deployment
828
504
 
829
- ## Deploying Tools to Production
505
+ After building and saving, tools can be invoked from code via REST API, SDK, or webhook. See `sg skill integration` for complete SDK (TypeScript/Python), REST API, and webhook examples including retry patterns.
830
506
 
831
- After building and saving a tool, integrate it into your application:
507
+ **IP whitelisting:** if a customer's system requires IP whitelisting (firewall rules, security groups, etc.), superglue's outbound IPs are `34.234.12.178` and `18.198.191.215`.
832
508
 
833
- ### REST API (Any Language)
509
+ Quick reference:
834
510
 
835
511
  ```bash
836
- # Run a tool
512
+ # REST (sync)
837
513
  curl -X POST "https://api.superglue.cloud/v1/tools/{toolId}/run" \
838
514
  -H "Authorization: Bearer $SUPERGLUE_API_KEY" \
839
515
  -H "Content-Type: application/json" \
840
- -d '{"inputs": {"userId": "123"}}'
516
+ -d '{"inputs":{"userId":"123"}}'
841
517
 
842
518
  # Webhook trigger (async, fire-and-forget)
843
519
  curl -X POST "https://api.superglue.cloud/v1/hooks/{toolId}?token=$SUPERGLUE_API_KEY" \
844
520
  -H "Content-Type: application/json" \
845
- -d '{"userId": "123"}'
521
+ -d '{"userId":"123"}'
846
522
  ```
847
523
 
848
- ### TypeScript SDK
524
+ ---
849
525
 
850
- ```typescript
851
- import { configure, runTool } from "@superglue/client";
852
- configure({ apiKey: process.env.SUPERGLUE_API_KEY!, baseUrl: "https://api.superglue.cloud/v1" });
853
- const response = await runTool("my-tool-id", { inputs: { userId: "123" } });
854
- // response.data is a Run object: { runId, toolId, status, data, error, metadata }
855
- ```
526
+ ## Common Pitfalls
527
+
528
+ - **Guessing API endpoints** — always verify with `sg system search-docs` or `sg system call` first
529
+ - **`systemId` in the wrong place** — it belongs inside `step.config.systemId`, not on the step object
530
+ - **`<<(sourceData) => sourceData.payload.X>>`** — payload fields are at root level of `sourceData`, not under `.payload`
531
+ - **`<<currentItem.id>>`** — must use arrow function syntax: `<<(sourceData) => sourceData.currentItem.id>>`
532
+ - **Hardcoded pagination params** — use `<<page>>`, `<<offset>>`, `<<cursor>>`, `<<limit>>`
533
+ - **Missing auth headers** — credentials are never automatically included in any protocol, including for OAuth systems (only token refresh is automatic)
534
+ - **Hardcoded base URLs** — prefer system URL variables (`<<systemId_url>>`) for environment portability
535
+ - **Empty `instruction`** — never leave the tool-level `instruction` blank
536
+ - **Adding `outputSchema` unsolicited** — only add when the user explicitly requests a specific response structure
537
+ - **Multi-line `outputTransform`** — must be a single-line JS string (no literal newlines or tabs)
538
+ - **Regex literals in transforms** — `/.../ ` literals and complex escapes corrupt during serialization. Use `new RegExp()`, `.split()`, or `new URL()` instead
539
+ - **Complex bodies inline** — for bodies built from multiple steps, use a preceding transform step rather than stuffing multi-statement logic into `<<>>` expressions
540
+ - **Double-encoded JSON** — when the body contains nested/stringified JSON (e.g. LLM APIs), have `<<>>` expressions return a string via `JSON.stringify(...)`, and use a single expression for the whole body rather than mixing `<<>>` with static JSON
541
+ - **POST for read-only ops** — GraphQL queries via POST should have `modify: false`. Don't rely on HTTP method alone
542
+ - **Saving without approval** — always present `sg tool run` results and ask before `sg tool save`
543
+ - **`sg_auth_email` in scheduled runs** — not available in scheduler-triggered executions. Tools using `<<sg_auth_email>>` will fail
856
544
 
857
- ### Python SDK
545
+ ---
858
546
 
859
- ```python
860
- import os
861
- from superglue_client import AuthenticatedClient
862
- from superglue_client.api.tools import run_tool
863
- from superglue_client.models.run_request import RunRequest
864
- from superglue_client.models.run_request_inputs import RunRequestInputs
547
+ ## Error Recovery
865
548
 
866
- client = AuthenticatedClient(base_url="https://api.superglue.cloud/v1", token=os.environ["SUPERGLUE_API_KEY"])
867
- with client as c:
868
- result = run_tool.sync("my-tool-id", client=c, body=RunRequest(inputs=RunRequestInputs.from_dict({"userId": "123"})))
869
- ```
549
+ For protocol-specific error recovery (HTTP, Postgres, MSSQL, Redis, GraphQL, SFTP/SMB), run `sg skill <protocol>`. General strategies below.
870
550
 
871
- ---
551
+ ### Tool build fails validation
872
552
 
873
- ## Reference Files
553
+ `sg tool build` returns a validation error. Read the message, fix the config, and re-run. Common causes: missing `id`, empty `steps`, missing `url` on request steps, missing `transformCode` on transform steps, `systemId` on the step object instead of `step.config.systemId`.
874
554
 
875
- For detailed documentation on specific topics, read these files in the `references/` directory:
555
+ ### Tool runs but a step fails
876
556
 
877
- | File | When to read |
878
- | ----------------------------- | ------------------------------------------------------------------------------------------------ |
879
- | `references/integration.md` | **READ THIS** when deploying tools to production - SDK usage, REST API, webhooks, error handling |
880
- | `references/databases.md` | Building tools that query PostgreSQL or Microsoft SQL Server (Azure SQL) databases |
881
- | `references/redis.md` | Building tools that interact with Redis (commands, pipelines, data types) |
882
- | `references/file-servers.md` | Building tools that interact with FTP/SFTP/SMB file servers |
883
- | `references/data-handling.md` | Variables, selectors, result envelopes, transforms, JS sandbox constraints |
884
- | `references/file-handling.md` | File detection, parsing, producedFiles, file references, aliasing rules |
885
- | `references/http-apis.md` | HTTP step config — auth patterns, pagination, retries, error detection |
886
- | `references/access-rules.md` | RBAC roles, tool/system permissions, custom rules, mutation detection (enterprise only) |
557
+ 1. Re-run with `--include-step-results` to see raw per-step responses and `data` fields
558
+ 2. Use `sg system call` to test the failing endpoint directly — isolates step config vs system/auth issues
559
+ 3. Use `sg system find --id <systemId>` to verify `storedCredentials` keys match what the step references
560
+ 4. For HTTP: run `sg skill http` and follow the error recovery section (endpoint vs system isolation, credential scopes, rate limiting)
561
+ 5. For databases: run `sg skill postgres` or `sg skill mssql` — SSL/TLS and schema issues are common causes
562
+ 6. Use `sg system search-docs` and web search to verify the current API shape. APIs change across versions
887
563
 
888
- **Important:** When the user asks about integrating superglue into their codebase, deploying tools, using the SDK, or calling tools from code, you MUST read `references/integration.md` for complete examples.
564
+ ### Authentication failures
889
565
 
890
- ---
566
+ 1. Run `sg system find --id <systemId>` → check `storedCredentials` for masked but present values
567
+ 2. For OAuth: re-run `sg system oauth` if tokens are missing or expired
568
+ 3. For custom OAuth: verify `client_id`, `client_secret`, `auth_url`, `token_url` are all present. Confirm the redirect URI is registered on the provider's OAuth app
569
+ 4. Check scopes — 403 / empty responses often mean the token lacks required scopes
891
570
 
892
- ## Draft Management
571
+ ### System creation fails
893
572
 
894
- Drafts live in `.superglue/drafts/<draftId>.json`. Created by `build`, updated by `edit`, deleted by `save`. Ephemeral — not persisted across sessions.
573
+ 1. Check for an existing system with the same ID — use `sg system edit` to update instead
574
+ 2. Ensure `id` uses only lowercase letters, numbers, and underscores (no hyphens)
575
+ 3. For templated systems, verify the template ID is correct (`sg system find` lists available templates)
895
576
 
896
- ## File References
577
+ ### Data selector / transform returns wrong data
897
578
 
898
- Attach files with `--file key=path`. Reference in payloads with `file::<key>`. Auto-parsed to JSON.
579
+ 1. Confirm whether the upstream step used an object selector (access `.data` directly) or an array selector (access via `.map(i => i.data)`)
580
+ 2. Re-run with `--include-step-results` to see the exact envelope shape
581
+ 3. Paginated steps merge into a single `.data` field — do not `.map()` over them
582
+ 4. Verify `sourceData.currentItem` is only referenced inside looping steps (set by the step's own `dataSelector`, not upstream)
899
583
 
900
- ```bash
901
- sg tool run --draft <id> --payload '{"data": "file::mysheet"}' --file mysheet=data.xlsx
902
- ```
584
+ ### Persistent failures
585
+
586
+ After 3-5 unsuccessful iterations on the same step, stop and ask the user for clarification or additional context (credentials, docs, expected payload shape). Don't keep guessing — gather evidence first.