@superglue/cli 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # superglue CLI
2
+
3
+ [![npm](https://img.shields.io/npm/v/@superglue/cli?style=flat-square&logo=npm)](https://www.npmjs.com/package/@superglue/cli)
4
+ [![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](LICENSE)
5
+
6
+ Build, test, and manage superglue API integration tools from the command line.
7
+
8
+ ## What is superglue?
9
+
10
+ - AI-powered tool builder that works with any API, database or file storage server
11
+ - Abstracts away authentication, documentation handling and data mapping between systems
12
+ - Self-heals tools: when steps fail due to upstream API changes, superglue can auto-repair failures
13
+
14
+ ## Installation
15
+
16
+ ### As npm package
17
+
18
+ ```bash
19
+ npm install -g @superglue/cli
20
+ sg --help
21
+ ```
22
+
23
+ ### As Claude Code Plugin
24
+
25
+ ```
26
+ /plugin install github:superglue-ai/cli
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ```bash
32
+ sg init # guided setup
33
+ sg system list # verify connection
34
+ sg tool build --config '...' # build a tool
35
+ sg tool run --draft <id> # test it
36
+ sg tool save --draft <id> # save it
37
+ ```
38
+
39
+ ## Commands
40
+
41
+ ### Tools
42
+
43
+ - `sg tool build` — Build a tool from config
44
+ - `sg tool run` — Run a draft or saved tool
45
+ - `sg tool edit` — Edit via JSON Patch
46
+ - `sg tool save` — Save a draft
47
+ - `sg tool list` — List saved tools
48
+ - `sg tool find` — Search tools
49
+
50
+ ### Systems
51
+
52
+ - `sg system create` — Create a system
53
+ - `sg system edit` — Edit system config
54
+ - `sg system list` — List systems
55
+ - `sg system find` — Search systems
56
+ - `sg system call` — Make authenticated API calls
57
+ - `sg system oauth` — Authenticate via OAuth
58
+ - `sg system docs` — Search system documentation
59
+
60
+ ### Runs
61
+
62
+ - `sg run list` — List execution runs
63
+ - `sg run get` — Get run details
64
+
65
+ ## Documentation
66
+
67
+ - [Full CLI Reference](./skills/superglue/SKILL.md) — Complete command documentation
68
+ - [superglue Docs](https://docs.superglue.cloud) — Platform documentation
69
+ - [API Reference](https://docs.superglue.cloud/api-reference/) — REST API docs
70
+
71
+ ## Related
72
+
73
+ - [superglue Web App](https://app.superglue.cloud) — Visual tool builder
74
+ - [@superglue/client](https://www.npmjs.com/package/@superglue/client) — TypeScript SDK
75
+ - [superglue-client](https://pypi.org/project/superglue-client/) — Python SDK
76
+
77
+ ## License
78
+
79
+ MIT
package/dist/cli.js CHANGED
@@ -21645,7 +21645,9 @@ function resolveConfig(flags) {
21645
21645
  function writeConfig(config, preferLocal) {
21646
21646
  const dir = getConfigDir(preferLocal);
21647
21647
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
21648
- fs.writeFileSync(path.join(dir, "config.json"), JSON.stringify(config, null, 2) + "\n");
21648
+ fs.writeFileSync(path.join(dir, "config.json"), JSON.stringify(config, null, 2) + "\n", {
21649
+ mode: 384
21650
+ });
21649
21651
  }
21650
21652
  function ensureConfigDirs(config, preferLocal) {
21651
21653
  const draftsDir = path.join(getConfigDir(preferLocal), "drafts");
@@ -21677,6 +21679,125 @@ var import_shared2 = __toESM(require_dist2());
21677
21679
 
21678
21680
  // src/output.ts
21679
21681
  var readline = __toESM(require("readline"));
21682
+
21683
+ // src/version.ts
21684
+ var import_node_child_process = require("child_process");
21685
+ var import_node_util = require("util");
21686
+
21687
+ // package.json
21688
+ var package_default = {
21689
+ name: "@superglue/cli",
21690
+ version: "1.1.0",
21691
+ bin: {
21692
+ sg: "./dist/cli.js"
21693
+ },
21694
+ files: [
21695
+ "dist/",
21696
+ "skills/",
21697
+ "skills.md"
21698
+ ],
21699
+ dependencies: {
21700
+ commander: "^13.0.0",
21701
+ "fast-json-patch": "^3.1.1"
21702
+ },
21703
+ devDependencies: {
21704
+ "@superglue/shared": "file:../shared",
21705
+ "@types/node": "^20.0.0",
21706
+ tsup: "^8.0.0",
21707
+ typescript: "^5.0.0"
21708
+ },
21709
+ scripts: {
21710
+ build: "tsup && (cp -r skills dist/ 2>/dev/null || true)",
21711
+ dev: "tsup --watch",
21712
+ "type-check": "tsc --noEmit",
21713
+ prepublishOnly: "npm run build"
21714
+ },
21715
+ publishConfig: {
21716
+ access: "public"
21717
+ }
21718
+ };
21719
+
21720
+ // src/version.ts
21721
+ var execAsync = (0, import_node_util.promisify)(import_node_child_process.exec);
21722
+ var CLI_VERSION = package_default.version;
21723
+ function parseVersionPart(part) {
21724
+ const match = part.match(/^(\d+)(?:-(.+))?$/);
21725
+ if (match) {
21726
+ return { numeric: parseInt(match[1], 10), prerelease: match[2] || null };
21727
+ }
21728
+ return { numeric: 0, prerelease: part };
21729
+ }
21730
+ function compareVersions(a, b) {
21731
+ const partsA = a.split(".");
21732
+ const partsB = b.split(".");
21733
+ const maxLen = Math.max(partsA.length, partsB.length);
21734
+ for (let i = 0; i < maxLen; i++) {
21735
+ const parsedA = parseVersionPart(partsA[i] || "0");
21736
+ const parsedB = parseVersionPart(partsB[i] || "0");
21737
+ if (parsedA.numeric < parsedB.numeric) return -1;
21738
+ if (parsedA.numeric > parsedB.numeric) return 1;
21739
+ if (parsedA.prerelease === null && parsedB.prerelease !== null) return 1;
21740
+ if (parsedA.prerelease !== null && parsedB.prerelease === null) return -1;
21741
+ if (parsedA.prerelease !== null && parsedB.prerelease !== null) {
21742
+ if (parsedA.prerelease < parsedB.prerelease) return -1;
21743
+ if (parsedA.prerelease > parsedB.prerelease) return 1;
21744
+ }
21745
+ }
21746
+ return 0;
21747
+ }
21748
+ async function checkVersionCompatibility(endpoint) {
21749
+ try {
21750
+ const healthUrl = `${endpoint.replace(/\/$/, "")}/v1/health`;
21751
+ const response = await fetch(healthUrl, { signal: AbortSignal.timeout(3e3) });
21752
+ if (!response.ok) return;
21753
+ const health = await response.json();
21754
+ if (!health.minCliVersion) return;
21755
+ if (compareVersions(CLI_VERSION, health.minCliVersion) < 0) {
21756
+ console.error("");
21757
+ console.error(`${c.yellow}${c.bold}\u26A0 CLI version ${CLI_VERSION} is outdated.${c.reset}`);
21758
+ console.error(
21759
+ `${c.yellow} Server requires at least v${health.minCliVersion}. Run: ${c.bold}sg update${c.reset}`
21760
+ );
21761
+ console.error("");
21762
+ }
21763
+ } catch {
21764
+ }
21765
+ }
21766
+ async function getLatestNpmVersion() {
21767
+ try {
21768
+ const response = await fetch("https://registry.npmjs.org/@superglue/cli/latest", {
21769
+ signal: AbortSignal.timeout(5e3)
21770
+ });
21771
+ if (!response.ok) return null;
21772
+ const data = await response.json();
21773
+ return data.version || null;
21774
+ } catch {
21775
+ return null;
21776
+ }
21777
+ }
21778
+ async function updateCli() {
21779
+ const latestVersion = await getLatestNpmVersion();
21780
+ if (!latestVersion) {
21781
+ return { success: false, message: "Could not fetch latest version from npm" };
21782
+ }
21783
+ if (compareVersions(CLI_VERSION, latestVersion) >= 0) {
21784
+ return { success: true, message: `Already on latest version (${CLI_VERSION})` };
21785
+ }
21786
+ try {
21787
+ await execAsync("npm install -g @superglue/cli@latest");
21788
+ return {
21789
+ success: true,
21790
+ message: `Updated from ${CLI_VERSION} to ${latestVersion}`
21791
+ };
21792
+ } catch (err) {
21793
+ return {
21794
+ success: false,
21795
+ message: `Update failed: ${err.message}. Try manually: npm install -g @superglue/cli@latest`
21796
+ };
21797
+ }
21798
+ }
21799
+
21800
+ // src/output.ts
21680
21801
  var isJsonMode = () => process.argv.includes("--json") || !process.stdout.isTTY;
21681
21802
  var c = {
21682
21803
  reset: "\x1B[0m",
@@ -21729,7 +21850,7 @@ function banner() {
21729
21850
  const after = line.slice(last + 1);
21730
21851
  console.log(` ${before}${inv}${inside}${rst}${after}`);
21731
21852
  });
21732
- console.log(` ${d} CLI v0.1.0${rst}`);
21853
+ console.log(` ${d} CLI v${CLI_VERSION}${rst}`);
21733
21854
  console.log("");
21734
21855
  }
21735
21856
  function spinner(message) {
@@ -21782,6 +21903,11 @@ function error(message, details) {
21782
21903
  if (details) prettyPrint(details, 4);
21783
21904
  }
21784
21905
  }
21906
+ function warn(message) {
21907
+ if (!isJsonMode()) {
21908
+ console.log(` ${c.yellow}\u26A0${c.reset} ${message}`);
21909
+ }
21910
+ }
21785
21911
  function info(message) {
21786
21912
  if (!isJsonMode()) {
21787
21913
  console.log(` ${c.dim}${message}${c.reset}`);
@@ -21974,22 +22100,25 @@ async function promptHidden(message) {
21974
22100
  let input = "";
21975
22101
  const onData = (ch) => {
21976
22102
  const s = ch.toString();
21977
- if (s === "\n" || s === "\r") {
21978
- if (process.stdin.isTTY) process.stdin.setRawMode(false);
21979
- process.stdin.removeListener("data", onData);
21980
- process.stdout.write("\n");
21981
- rl.close();
21982
- resolve4(input);
21983
- } else if (s === "") {
21984
- process.exit(0);
21985
- } else if (s === "\x7F" || s === "\b") {
21986
- if (input.length > 0) {
21987
- input = input.slice(0, -1);
21988
- process.stdout.write("\b \b");
22103
+ for (const char of s) {
22104
+ if (char === "\n" || char === "\r") {
22105
+ if (process.stdin.isTTY) process.stdin.setRawMode(false);
22106
+ process.stdin.removeListener("data", onData);
22107
+ process.stdout.write("\n");
22108
+ rl.close();
22109
+ resolve4(input);
22110
+ return;
22111
+ } else if (char === "") {
22112
+ process.exit(130);
22113
+ } else if (char === "\x7F" || char === "\b") {
22114
+ if (input.length > 0) {
22115
+ input = input.slice(0, -1);
22116
+ process.stdout.write("\b \b");
22117
+ }
22118
+ } else {
22119
+ input += char;
22120
+ process.stdout.write(`${c.dim}\u2022${c.reset}`);
21989
22121
  }
21990
- } else {
21991
- input += s;
21992
- process.stdout.write(`${c.dim}\u2022${c.reset}`);
21993
22122
  }
21994
22123
  };
21995
22124
  process.stdin.on("data", onData);
@@ -22151,9 +22280,11 @@ var path3 = __toESM(require("path"));
22151
22280
  function getDraftsDir() {
22152
22281
  return path3.join(getConfigDir(), "drafts");
22153
22282
  }
22283
+ function encodeDraftId(draftId) {
22284
+ return Buffer.from(draftId, "utf-8").toString("base64url");
22285
+ }
22154
22286
  function getDraftPath(draftId) {
22155
- const safeName = draftId.replace(/[^a-zA-Z0-9_-]/g, "_");
22156
- return path3.join(getDraftsDir(), `${safeName}.json`);
22287
+ return path3.join(getDraftsDir(), `${encodeDraftId(draftId)}.json`);
22157
22288
  }
22158
22289
  function writeDraft(draft) {
22159
22290
  const dir = getDraftsDir();
@@ -22471,11 +22602,11 @@ function registerEditCommand(parent, getContext2) {
22471
22602
  draftId: workingDraftId,
22472
22603
  config: {
22473
22604
  ...patchedConfig,
22474
- instruction: originalConfig.instruction || patchedConfig.instruction,
22605
+ instruction: patchedConfig.instruction ?? originalConfig.instruction,
22475
22606
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
22476
22607
  },
22477
22608
  systemIds: patchedConfig.systemIds || [],
22478
- instruction: patchedConfig.instruction || "",
22609
+ instruction: patchedConfig.instruction ?? "",
22479
22610
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
22480
22611
  };
22481
22612
  writeDraft(draft);
@@ -22541,8 +22672,8 @@ function registerSaveCommand(parent, getContext2) {
22541
22672
  process.exit(1);
22542
22673
  }
22543
22674
  const toolId = opts.id || draft.config.id;
22675
+ const spin = spinner(`Saving tool ${c.bold}${toolId}${c.reset}...`);
22544
22676
  try {
22545
- const spin = spinner(`Saving tool ${c.bold}${toolId}${c.reset}...`);
22546
22677
  const saved = await client.upsertWorkflow(toolId, {
22547
22678
  ...draft.config,
22548
22679
  id: toolId,
@@ -22564,6 +22695,7 @@ function registerSaveCommand(parent, getContext2) {
22564
22695
  console.log("");
22565
22696
  }
22566
22697
  } catch (err) {
22698
+ spin.stop();
22567
22699
  error(err.message);
22568
22700
  process.exit(1);
22569
22701
  }
@@ -22602,7 +22734,7 @@ function registerFindCommand(parent, getContext2) {
22602
22734
  output({ success: true, tool });
22603
22735
  return;
22604
22736
  }
22605
- const searchQuery = query || "*";
22737
+ const searchQuery = (query || "").trim() || "*";
22606
22738
  if (searchQuery === "*") {
22607
22739
  const { items } = await client.listWorkflows(100);
22608
22740
  const tools = items.filter((t) => !t.archived).map((t) => ({
@@ -22703,10 +22835,10 @@ function registerCreateCommand(parent, getContext2) {
22703
22835
  if (template.oauth.client_id) oauthCreds.client_id = template.oauth.client_id;
22704
22836
  }
22705
22837
  systemInput = {
22838
+ ...systemInput,
22706
22839
  name: systemInput.name || template.name,
22707
- url: template.apiUrl,
22840
+ url: systemInput.url || template.apiUrl,
22708
22841
  templateName: opts.template,
22709
- ...systemInput,
22710
22842
  credentials: { ...oauthCreds, ...systemInput.credentials }
22711
22843
  };
22712
22844
  }
@@ -22805,7 +22937,9 @@ function registerEditCommand2(parent, getContext2) {
22805
22937
  url: opts.scrapeUrl,
22806
22938
  keywords
22807
22939
  });
22808
- } catch {
22940
+ } catch (scrapeErr) {
22941
+ const errMsg = scrapeErr instanceof Error ? scrapeErr.message : String(scrapeErr || "Unknown error");
22942
+ warn(`Documentation scrape failed for ${opts.scrapeUrl}: ${errMsg}`);
22809
22943
  }
22810
22944
  }
22811
22945
  spin.stop();
@@ -22921,14 +23055,29 @@ function registerCallCommand(parent, getContext2) {
22921
23055
  if (body && Object.keys(filePayloads).length > 0) {
22922
23056
  try {
22923
23057
  let parsed = JSON.parse(body);
22924
- for (const [k, v] of Object.entries(parsed)) {
22925
- if (typeof v === "string" && v.startsWith("file::")) {
22926
- const key = v.slice(6);
22927
- if (key in filePayloads) parsed[k] = filePayloads[key];
23058
+ const resolveFileRefs = (obj) => {
23059
+ if (typeof obj === "string" && obj.startsWith("file::")) {
23060
+ const key = obj.slice(6);
23061
+ if (key in filePayloads) return filePayloads[key];
23062
+ error(
23063
+ `Unresolved file reference: file::${key}. Available: ${Object.keys(filePayloads).join(", ") || "(none)"}`
23064
+ );
23065
+ process.exit(1);
22928
23066
  }
22929
- }
23067
+ if (Array.isArray(obj)) return obj.map(resolveFileRefs);
23068
+ if (obj && typeof obj === "object") {
23069
+ const result = {};
23070
+ for (const [k, v] of Object.entries(obj)) {
23071
+ result[k] = resolveFileRefs(v);
23072
+ }
23073
+ return result;
23074
+ }
23075
+ return obj;
23076
+ };
23077
+ parsed = resolveFileRefs(parsed);
22930
23078
  body = JSON.stringify(parsed);
22931
- } catch {
23079
+ } catch (err) {
23080
+ if (err.message?.startsWith("Unresolved file reference")) throw err;
22932
23081
  }
22933
23082
  }
22934
23083
  const autoExec = process.argv.includes("--yes") || process.argv.includes("-y") || shouldAutoExecute(config.policies.callSystem, method, opts.url);
@@ -23041,13 +23190,13 @@ function registerDocsCommand(parent, getContext2) {
23041
23190
  }
23042
23191
 
23043
23192
  // src/commands/system/oauth.ts
23044
- var import_node_child_process = require("child_process");
23193
+ var import_node_child_process2 = require("child_process");
23045
23194
  var import_shared8 = __toESM(require_dist2());
23046
23195
  function openBrowser(url) {
23047
23196
  const platform = process.platform;
23048
23197
  const cmd = platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
23049
23198
  const args = platform === "win32" ? ["/c", "start", "", url] : [url];
23050
- (0, import_node_child_process.spawn)(cmd, args, { detached: true, stdio: "ignore" }).unref();
23199
+ (0, import_node_child_process2.spawn)(cmd, args, { detached: true, stdio: "ignore" }).unref();
23051
23200
  }
23052
23201
  async function pollForTokens(client, systemId, originalToken, timeoutMs = 3e5, intervalMs = 2e3) {
23053
23202
  const start = Date.now();
@@ -23207,12 +23356,12 @@ function registerSystemCommands(program2, getContext2) {
23207
23356
 
23208
23357
  // src/commands/run/list.ts
23209
23358
  function registerListCommand(parent, getContext2) {
23210
- parent.command("list").description("List recent runs").option("--tool <id>", "Filter by tool ID").option("--status <status>", "Filter by status (running, success, failed, aborted)").option("--source <sources>", "Comma-separated request sources").option("--user <userId>", "Filter by user ID").option("--system-id <id>", "Filter by system ID").option("--limit <n>", "Max results", "10").option("--offset <n>", "Skip first N results", "0").option("--search <text>", "Full-text search").action(async (opts) => {
23359
+ parent.command("list").description("List recent runs").option("--tool <id>", "Filter by tool ID").option("--status <status>", "Filter by status (running, success, failed, aborted)").option("--source <sources>", "Comma-separated request sources").option("--user <userId>", "Filter by user ID").option("--system-id <id>", "Filter by system ID").option("--limit <n>", "Max results", "10").option("--offset <n>", "Skip first N results", "0").action(async (opts) => {
23211
23360
  const { client } = getContext2();
23212
23361
  try {
23213
23362
  const limit = Math.min(parseInt(opts.limit, 10) || 10, 50);
23214
23363
  const offset = parseInt(opts.offset, 10) || 0;
23215
- const page = Math.floor(offset / limit) + 1;
23364
+ const page = Math.ceil((offset + 1) / limit);
23216
23365
  const requestSources = opts.source?.split(",").filter(Boolean);
23217
23366
  const result = await client.listRuns({
23218
23367
  toolId: opts.tool,
@@ -23295,109 +23444,6 @@ function registerRunCommands(program2, getContext2) {
23295
23444
  registerGetCommand(run, getContext2);
23296
23445
  }
23297
23446
 
23298
- // src/version.ts
23299
- var import_node_child_process2 = require("child_process");
23300
- var import_node_util = require("util");
23301
-
23302
- // package.json
23303
- var package_default = {
23304
- name: "@superglue/cli",
23305
- version: "1.0.0",
23306
- bin: {
23307
- sg: "./dist/cli.js"
23308
- },
23309
- files: [
23310
- "dist/",
23311
- "skills/",
23312
- "skills.md"
23313
- ],
23314
- dependencies: {
23315
- commander: "^13.0.0",
23316
- "fast-json-patch": "^3.1.1"
23317
- },
23318
- devDependencies: {
23319
- "@superglue/shared": "file:../shared",
23320
- "@types/node": "^20.0.0",
23321
- tsup: "^8.0.0",
23322
- typescript: "^5.0.0"
23323
- },
23324
- scripts: {
23325
- build: "tsup && cp -r skills dist/ 2>/dev/null || true",
23326
- dev: "tsup --watch",
23327
- "type-check": "tsc --noEmit",
23328
- prepublishOnly: "npm run build"
23329
- },
23330
- publishConfig: {
23331
- access: "public"
23332
- }
23333
- };
23334
-
23335
- // src/version.ts
23336
- var execAsync = (0, import_node_util.promisify)(import_node_child_process2.exec);
23337
- var CLI_VERSION = package_default.version;
23338
- function compareVersions(a, b) {
23339
- const partsA = a.split(".").map(Number);
23340
- const partsB = b.split(".").map(Number);
23341
- for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
23342
- const numA = partsA[i] || 0;
23343
- const numB = partsB[i] || 0;
23344
- if (numA < numB) return -1;
23345
- if (numA > numB) return 1;
23346
- }
23347
- return 0;
23348
- }
23349
- async function checkVersionCompatibility(endpoint) {
23350
- try {
23351
- const healthUrl = `${endpoint.replace(/\/$/, "")}/v1/health`;
23352
- const response = await fetch(healthUrl, { signal: AbortSignal.timeout(3e3) });
23353
- if (!response.ok) return;
23354
- const health = await response.json();
23355
- if (!health.minCliVersion) return;
23356
- if (compareVersions(CLI_VERSION, health.minCliVersion) < 0) {
23357
- console.error("");
23358
- console.error(`${c.yellow}${c.bold}\u26A0 CLI version ${CLI_VERSION} is outdated.${c.reset}`);
23359
- console.error(
23360
- `${c.yellow} Server requires at least v${health.minCliVersion}. Run: ${c.bold}sg update${c.reset}`
23361
- );
23362
- console.error("");
23363
- }
23364
- } catch {
23365
- }
23366
- }
23367
- async function getLatestNpmVersion() {
23368
- try {
23369
- const response = await fetch("https://registry.npmjs.org/@superglue/cli/latest", {
23370
- signal: AbortSignal.timeout(5e3)
23371
- });
23372
- if (!response.ok) return null;
23373
- const data = await response.json();
23374
- return data.version || null;
23375
- } catch {
23376
- return null;
23377
- }
23378
- }
23379
- async function updateCli() {
23380
- const latestVersion = await getLatestNpmVersion();
23381
- if (!latestVersion) {
23382
- return { success: false, message: "Could not fetch latest version from npm" };
23383
- }
23384
- if (compareVersions(CLI_VERSION, latestVersion) >= 0) {
23385
- return { success: true, message: `Already on latest version (${CLI_VERSION})` };
23386
- }
23387
- try {
23388
- await execAsync("npm install -g @superglue/cli@latest");
23389
- return {
23390
- success: true,
23391
- message: `Updated from ${CLI_VERSION} to ${latestVersion}`
23392
- };
23393
- } catch (err) {
23394
- return {
23395
- success: false,
23396
- message: `Update failed: ${err.message}. Try manually: npm install -g @superglue/cli@latest`
23397
- };
23398
- }
23399
- }
23400
-
23401
23447
  // src/commands/update.ts
23402
23448
  function registerUpdateCommand(program2) {
23403
23449
  program2.command("update").description("Update the superglue CLI to the latest version").option("--check", "Only check for updates, don't install").action(async (opts) => {
@@ -23506,12 +23552,22 @@ function findSubcommand(argv) {
23506
23552
  }
23507
23553
  return void 0;
23508
23554
  }
23555
+ function extractFlagValue(argv, flag) {
23556
+ for (let i = 0; i < argv.length; i++) {
23557
+ const arg = argv[i];
23558
+ if (arg.startsWith(`${flag}=`)) {
23559
+ return arg.slice(flag.length + 1);
23560
+ }
23561
+ if (arg === flag && i + 1 < argv.length) {
23562
+ return argv[i + 1];
23563
+ }
23564
+ }
23565
+ return void 0;
23566
+ }
23509
23567
  var subcommand = findSubcommand(process.argv);
23510
23568
  if (subcommand && commandsRequiringServer.includes(subcommand)) {
23511
- const apiKeyIdx = process.argv.indexOf("--api-key");
23512
- const endpointIdx = process.argv.indexOf("--endpoint");
23513
- const cliApiKey = apiKeyIdx !== -1 ? process.argv[apiKeyIdx + 1] : void 0;
23514
- const cliEndpoint = endpointIdx !== -1 ? process.argv[endpointIdx + 1] : void 0;
23569
+ const cliApiKey = extractFlagValue(process.argv, "--api-key");
23570
+ const cliEndpoint = extractFlagValue(process.argv, "--endpoint");
23515
23571
  const config = resolveConfig({ apiKey: cliApiKey, endpoint: cliEndpoint });
23516
23572
  if (config.apiKey) {
23517
23573
  checkVersionCompatibility(config.endpoint).then(() => program.parse());
@@ -227,14 +227,14 @@ sg system oauth --system-id my_api --grant-type client_credentials --scopes "rea
227
227
  {
228
228
  "id": "unique-step-id",
229
229
  "config": {
230
- "systemId": "system-id",
231
- "url": "https://api.example.com/endpoint?param=<<payload.field>>",
230
+ "systemId": "example_system",
231
+ "url": "https://api.example.com/endpoint?param=<<payload_field>>",
232
232
  "method": "GET",
233
233
  "headers": {
234
- "Authorization": "Bearer <<system-id_access_token>>"
234
+ "Authorization": "Bearer <<example_system_access_token>>"
235
235
  },
236
236
  "queryParams": { "limit": "10" },
237
- "body": "{ \"key\": \"<<payload.field>>\" }"
237
+ "body": "{ \"key\": \"<<payload_field>>\" }"
238
238
  },
239
239
  "dataSelector": "(sourceData) => sourceData.previousStep.data.items",
240
240
  "transformCode": "(items) => items.map(i => ({ id: i.id, name: i.name }))",
@@ -75,7 +75,7 @@ Downloaded files are all parsed automatically:
75
75
 
76
76
  - String → written as-is
77
77
  - Buffer → written directly
78
- - Object/Array → JSON.stringified with 2-space indent
78
+ - Object/Array → `JSON.stringify` with 2-space indent
79
79
 
80
80
  ## Connection Details
81
81
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superglue/cli",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "bin": {
5
5
  "sg": "./dist/cli.js"
6
6
  },
@@ -20,7 +20,7 @@
20
20
  "typescript": "^5.0.0"
21
21
  },
22
22
  "scripts": {
23
- "build": "tsup && cp -r skills dist/ 2>/dev/null || true",
23
+ "build": "tsup && (cp -r skills dist/ 2>/dev/null || true)",
24
24
  "dev": "tsup --watch",
25
25
  "type-check": "tsc --noEmit",
26
26
  "prepublishOnly": "npm run build"
@@ -227,14 +227,14 @@ sg system oauth --system-id my_api --grant-type client_credentials --scopes "rea
227
227
  {
228
228
  "id": "unique-step-id",
229
229
  "config": {
230
- "systemId": "system-id",
231
- "url": "https://api.example.com/endpoint?param=<<payload.field>>",
230
+ "systemId": "example_system",
231
+ "url": "https://api.example.com/endpoint?param=<<payload_field>>",
232
232
  "method": "GET",
233
233
  "headers": {
234
- "Authorization": "Bearer <<system-id_access_token>>"
234
+ "Authorization": "Bearer <<example_system_access_token>>"
235
235
  },
236
236
  "queryParams": { "limit": "10" },
237
- "body": "{ \"key\": \"<<payload.field>>\" }"
237
+ "body": "{ \"key\": \"<<payload_field>>\" }"
238
238
  },
239
239
  "dataSelector": "(sourceData) => sourceData.previousStep.data.items",
240
240
  "transformCode": "(items) => items.map(i => ({ id: i.id, name: i.name }))",
@@ -75,7 +75,7 @@ Downloaded files are all parsed automatically:
75
75
 
76
76
  - String → written as-is
77
77
  - Buffer → written directly
78
- - Object/Array → JSON.stringified with 2-space indent
78
+ - Object/Array → `JSON.stringify` with 2-space indent
79
79
 
80
80
  ## Connection Details
81
81