@superglue/cli 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1751,6 +1751,7 @@ var require_types = __commonJS({
1751
1751
  exports2.isRequestConfig = isRequestConfig;
1752
1752
  exports2.isTransformConfig = isTransformConfig;
1753
1753
  exports2.getToolSystemIds = getToolSystemIds;
1754
+ exports2.isProductionSystem = isProductionSystem;
1754
1755
  var UserRole;
1755
1756
  (function(UserRole2) {
1756
1757
  UserRole2["ADMIN"] = "admin";
@@ -1849,15 +1850,16 @@ var require_types = __commonJS({
1849
1850
  RunStatus2["FAILED"] = "FAILED";
1850
1851
  RunStatus2["ABORTED"] = "ABORTED";
1851
1852
  })(RunStatus || (exports2.RunStatus = RunStatus = {}));
1852
- var RequestSource;
1853
- (function(RequestSource2) {
1854
- RequestSource2["API"] = "api";
1855
- RequestSource2["FRONTEND"] = "frontend";
1856
- RequestSource2["SCHEDULER"] = "scheduler";
1857
- RequestSource2["MCP"] = "mcp";
1858
- RequestSource2["TOOL_CHAIN"] = "tool-chain";
1859
- RequestSource2["WEBHOOK"] = "webhook";
1860
- })(RequestSource || (exports2.RequestSource = RequestSource = {}));
1853
+ var RequestSource3;
1854
+ (function(RequestSource4) {
1855
+ RequestSource4["API"] = "api";
1856
+ RequestSource4["FRONTEND"] = "frontend";
1857
+ RequestSource4["SCHEDULER"] = "scheduler";
1858
+ RequestSource4["MCP"] = "mcp";
1859
+ RequestSource4["TOOL_CHAIN"] = "tool-chain";
1860
+ RequestSource4["WEBHOOK"] = "webhook";
1861
+ RequestSource4["CLI"] = "cli";
1862
+ })(RequestSource3 || (exports2.RequestSource = RequestSource3 = {}));
1861
1863
  var FilterTarget;
1862
1864
  (function(FilterTarget2) {
1863
1865
  FilterTarget2["KEYS"] = "KEYS";
@@ -1893,6 +1895,9 @@ var require_types = __commonJS({
1893
1895
  }
1894
1896
  return Array.from(ids);
1895
1897
  }
1898
+ function isProductionSystem(system) {
1899
+ return system.environment !== "dev";
1900
+ }
1896
1901
  var DiscoveryRunStatus;
1897
1902
  (function(DiscoveryRunStatus2) {
1898
1903
  DiscoveryRunStatus2["PENDING"] = "PENDING";
@@ -8813,8 +8818,8 @@ var require_luxon = __commonJS({
8813
8818
  let current = null, currentFull = "", bracketed = false;
8814
8819
  const splits = [];
8815
8820
  for (let i = 0; i < fmt.length; i++) {
8816
- const c2 = fmt.charAt(i);
8817
- if (c2 === "'") {
8821
+ const c3 = fmt.charAt(i);
8822
+ if (c3 === "'") {
8818
8823
  if (currentFull.length > 0 || bracketed) {
8819
8824
  splits.push({
8820
8825
  literal: bracketed || /^\s+$/.test(currentFull),
@@ -8825,9 +8830,9 @@ var require_luxon = __commonJS({
8825
8830
  currentFull = "";
8826
8831
  bracketed = !bracketed;
8827
8832
  } else if (bracketed) {
8828
- currentFull += c2;
8829
- } else if (c2 === current) {
8830
- currentFull += c2;
8833
+ currentFull += c3;
8834
+ } else if (c3 === current) {
8835
+ currentFull += c3;
8831
8836
  } else {
8832
8837
  if (currentFull.length > 0) {
8833
8838
  splits.push({
@@ -8835,8 +8840,8 @@ var require_luxon = __commonJS({
8835
8840
  val: currentFull
8836
8841
  });
8837
8842
  }
8838
- currentFull = c2;
8839
- current = c2;
8843
+ currentFull = c3;
8844
+ current = c3;
8840
8845
  }
8841
8846
  }
8842
8847
  if (currentFull.length > 0) {
@@ -11518,7 +11523,7 @@ var require_luxon = __commonJS({
11518
11523
  return fixOffset(objToLocalTS(obj), offset2, zone);
11519
11524
  }
11520
11525
  function adjustTime(inst, dur) {
11521
- const oPre = inst.o, year = inst.c.year + Math.trunc(dur.years), month = inst.c.month + Math.trunc(dur.months) + Math.trunc(dur.quarters) * 3, c2 = {
11526
+ const oPre = inst.o, year = inst.c.year + Math.trunc(dur.years), month = inst.c.month + Math.trunc(dur.months) + Math.trunc(dur.quarters) * 3, c3 = {
11522
11527
  ...inst.c,
11523
11528
  year,
11524
11529
  month,
@@ -11533,7 +11538,7 @@ var require_luxon = __commonJS({
11533
11538
  minutes: dur.minutes,
11534
11539
  seconds: dur.seconds,
11535
11540
  milliseconds: dur.milliseconds
11536
- }).as("milliseconds"), localTS = objToLocalTS(c2);
11541
+ }).as("milliseconds"), localTS = objToLocalTS(c3);
11537
11542
  let [ts, o] = fixOffset(localTS, oPre, inst.zone);
11538
11543
  if (millisToAdd !== 0) {
11539
11544
  ts += millisToAdd;
@@ -11568,72 +11573,72 @@ var require_luxon = __commonJS({
11568
11573
  }
11569
11574
  function toISODate(o, extended, precision) {
11570
11575
  const longFormat = o.c.year > 9999 || o.c.year < 0;
11571
- let c2 = "";
11572
- if (longFormat && o.c.year >= 0) c2 += "+";
11573
- c2 += padStart(o.c.year, longFormat ? 6 : 4);
11574
- if (precision === "year") return c2;
11576
+ let c3 = "";
11577
+ if (longFormat && o.c.year >= 0) c3 += "+";
11578
+ c3 += padStart(o.c.year, longFormat ? 6 : 4);
11579
+ if (precision === "year") return c3;
11575
11580
  if (extended) {
11576
- c2 += "-";
11577
- c2 += padStart(o.c.month);
11578
- if (precision === "month") return c2;
11579
- c2 += "-";
11581
+ c3 += "-";
11582
+ c3 += padStart(o.c.month);
11583
+ if (precision === "month") return c3;
11584
+ c3 += "-";
11580
11585
  } else {
11581
- c2 += padStart(o.c.month);
11582
- if (precision === "month") return c2;
11586
+ c3 += padStart(o.c.month);
11587
+ if (precision === "month") return c3;
11583
11588
  }
11584
- c2 += padStart(o.c.day);
11585
- return c2;
11589
+ c3 += padStart(o.c.day);
11590
+ return c3;
11586
11591
  }
11587
11592
  function toISOTime(o, extended, suppressSeconds, suppressMilliseconds, includeOffset, extendedZone, precision) {
11588
- let showSeconds = !suppressSeconds || o.c.millisecond !== 0 || o.c.second !== 0, c2 = "";
11593
+ let showSeconds = !suppressSeconds || o.c.millisecond !== 0 || o.c.second !== 0, c3 = "";
11589
11594
  switch (precision) {
11590
11595
  case "day":
11591
11596
  case "month":
11592
11597
  case "year":
11593
11598
  break;
11594
11599
  default:
11595
- c2 += padStart(o.c.hour);
11600
+ c3 += padStart(o.c.hour);
11596
11601
  if (precision === "hour") break;
11597
11602
  if (extended) {
11598
- c2 += ":";
11599
- c2 += padStart(o.c.minute);
11603
+ c3 += ":";
11604
+ c3 += padStart(o.c.minute);
11600
11605
  if (precision === "minute") break;
11601
11606
  if (showSeconds) {
11602
- c2 += ":";
11603
- c2 += padStart(o.c.second);
11607
+ c3 += ":";
11608
+ c3 += padStart(o.c.second);
11604
11609
  }
11605
11610
  } else {
11606
- c2 += padStart(o.c.minute);
11611
+ c3 += padStart(o.c.minute);
11607
11612
  if (precision === "minute") break;
11608
11613
  if (showSeconds) {
11609
- c2 += padStart(o.c.second);
11614
+ c3 += padStart(o.c.second);
11610
11615
  }
11611
11616
  }
11612
11617
  if (precision === "second") break;
11613
11618
  if (showSeconds && (!suppressMilliseconds || o.c.millisecond !== 0)) {
11614
- c2 += ".";
11615
- c2 += padStart(o.c.millisecond, 3);
11619
+ c3 += ".";
11620
+ c3 += padStart(o.c.millisecond, 3);
11616
11621
  }
11617
11622
  }
11618
11623
  if (includeOffset) {
11619
11624
  if (o.isOffsetFixed && o.offset === 0 && !extendedZone) {
11620
- c2 += "Z";
11625
+ c3 += "Z";
11621
11626
  } else if (o.o < 0) {
11622
- c2 += "-";
11623
- c2 += padStart(Math.trunc(-o.o / 60));
11624
- c2 += ":";
11625
- c2 += padStart(Math.trunc(-o.o % 60));
11627
+ c3 += "-";
11628
+ c3 += padStart(Math.trunc(-o.o / 60));
11629
+ c3 += ":";
11630
+ c3 += padStart(Math.trunc(-o.o % 60));
11626
11631
  } else {
11627
- c2 += "+";
11628
- c2 += padStart(Math.trunc(o.o / 60));
11629
- c2 += ":";
11630
- c2 += padStart(Math.trunc(o.o % 60));
11632
+ c3 += "+";
11633
+ c3 += padStart(Math.trunc(o.o / 60));
11634
+ c3 += ":";
11635
+ c3 += padStart(Math.trunc(o.o % 60));
11631
11636
  }
11632
11637
  }
11633
11638
  if (extendedZone) {
11634
- c2 += "[" + o.zone.ianaName + "]";
11639
+ c3 += "[" + o.zone.ianaName + "]";
11635
11640
  }
11636
- return c2;
11641
+ return c3;
11637
11642
  }
11638
11643
  var defaultUnitValues = {
11639
11644
  month: 1,
@@ -11751,10 +11756,10 @@ var require_luxon = __commonJS({
11751
11756
  });
11752
11757
  }
11753
11758
  function diffRelative(start, end, opts) {
11754
- const round = isUndefined(opts.round) ? true : opts.round, rounding = isUndefined(opts.rounding) ? "trunc" : opts.rounding, format = (c2, unit) => {
11755
- c2 = roundTo(c2, round || opts.calendary ? 0 : 2, opts.calendary ? "round" : rounding);
11759
+ const round = isUndefined(opts.round) ? true : opts.round, rounding = isUndefined(opts.rounding) ? "trunc" : opts.rounding, format = (c3, unit) => {
11760
+ c3 = roundTo(c3, round || opts.calendary ? 0 : 2, opts.calendary ? "round" : rounding);
11756
11761
  const formatter = end.loc.clone(opts).relFormatter(opts);
11757
- return formatter.format(c2, unit);
11762
+ return formatter.format(c3, unit);
11758
11763
  }, differ = (unit) => {
11759
11764
  if (opts.calendary) {
11760
11765
  if (!end.hasSame(start, unit)) {
@@ -11795,16 +11800,16 @@ var require_luxon = __commonJS({
11795
11800
  const zone = config.zone || Settings.defaultZone;
11796
11801
  let invalid = config.invalid || (Number.isNaN(config.ts) ? new Invalid("invalid input") : null) || (!zone.isValid ? unsupportedZone(zone) : null);
11797
11802
  this.ts = isUndefined(config.ts) ? Settings.now() : config.ts;
11798
- let c2 = null, o = null;
11803
+ let c3 = null, o = null;
11799
11804
  if (!invalid) {
11800
11805
  const unchanged = config.old && config.old.ts === this.ts && config.old.zone.equals(zone);
11801
11806
  if (unchanged) {
11802
- [c2, o] = [config.old.c, config.old.o];
11807
+ [c3, o] = [config.old.c, config.old.o];
11803
11808
  } else {
11804
11809
  const ot = isNumber(config.o) && !config.old ? config.o : zone.offset(this.ts);
11805
- c2 = tsToObj(this.ts, ot);
11806
- invalid = Number.isNaN(c2.year) ? new Invalid("invalid input") : null;
11807
- c2 = invalid ? null : c2;
11810
+ c3 = tsToObj(this.ts, ot);
11811
+ invalid = Number.isNaN(c3.year) ? new Invalid("invalid input") : null;
11812
+ c3 = invalid ? null : c3;
11808
11813
  o = invalid ? null : ot;
11809
11814
  }
11810
11815
  }
@@ -11813,7 +11818,7 @@ var require_luxon = __commonJS({
11813
11818
  this.invalid = invalid;
11814
11819
  this.weekData = null;
11815
11820
  this.localWeekData = null;
11816
- this.c = c2;
11821
+ this.c = c3;
11817
11822
  this.o = o;
11818
11823
  this.isLuxonDateTime = true;
11819
11824
  }
@@ -12572,8 +12577,8 @@ var require_luxon = __commonJS({
12572
12577
  const ts1 = localTS - o1 * minuteMs;
12573
12578
  const ts2 = localTS - o2 * minuteMs;
12574
12579
  const c1 = tsToObj(ts1, o1);
12575
- const c2 = tsToObj(ts2, o2);
12576
- if (c1.hour === c2.hour && c1.minute === c2.minute && c1.second === c2.second && c1.millisecond === c2.millisecond) {
12580
+ const c22 = tsToObj(ts2, o2);
12581
+ if (c1.hour === c22.hour && c1.minute === c22.minute && c1.second === c22.second && c1.millisecond === c22.millisecond) {
12577
12582
  return [clone2(this, {
12578
12583
  ts: ts1
12579
12584
  }), clone2(this, {
@@ -12971,10 +12976,10 @@ var require_luxon = __commonJS({
12971
12976
  }
12972
12977
  precision = normalizeUnit(precision);
12973
12978
  const ext = format === "extended";
12974
- let c2 = toISODate(this, ext, precision);
12975
- if (orderedUnits.indexOf(precision) >= 3) c2 += "T";
12976
- c2 += toISOTime(this, ext, suppressSeconds, suppressMilliseconds, includeOffset, extendedZone, precision);
12977
- return c2;
12979
+ let c3 = toISODate(this, ext, precision);
12980
+ if (orderedUnits.indexOf(precision) >= 3) c3 += "T";
12981
+ c3 += toISOTime(this, ext, suppressSeconds, suppressMilliseconds, includeOffset, extendedZone, precision);
12982
+ return c3;
12978
12983
  }
12979
12984
  /**
12980
12985
  * Returns an ISO 8601-compliant string representation of this DateTime's date component
@@ -13033,8 +13038,8 @@ var require_luxon = __commonJS({
13033
13038
  return null;
13034
13039
  }
13035
13040
  precision = normalizeUnit(precision);
13036
- let c2 = includePrefix && orderedUnits.indexOf(precision) >= 3 ? "T" : "";
13037
- return c2 + toISOTime(this, format === "extended", suppressSeconds, suppressMilliseconds, includeOffset, extendedZone, precision);
13041
+ let c3 = includePrefix && orderedUnits.indexOf(precision) >= 3 ? "T" : "";
13042
+ return c3 + toISOTime(this, format === "extended", suppressSeconds, suppressMilliseconds, includeOffset, extendedZone, precision);
13038
13043
  }
13039
13044
  /**
13040
13045
  * Returns an RFC 2822-compatible string representation of this DateTime
@@ -17619,7 +17624,7 @@ attempted value: ${formattedValue}
17619
17624
  type: next.type,
17620
17625
  oneOf: next._whitelist.describe(),
17621
17626
  notOneOf: next._blacklist.describe(),
17622
- tests: next.tests.filter((n, idx, list) => list.findIndex((c2) => c2.OPTIONS.name === n.OPTIONS.name) === idx).map((fn) => {
17627
+ tests: next.tests.filter((n, idx, list) => list.findIndex((c3) => c3.OPTIONS.name === n.OPTIONS.name) === idx).map((fn) => {
17623
17628
  const params = fn.OPTIONS.params && options ? resolveParams(Object.assign({}, fn.OPTIONS.params), options) : fn.OPTIONS.params;
17624
17629
  return {
17625
17630
  name: fn.OPTIONS.name,
@@ -19867,6 +19872,7 @@ var require_utils = __commonJS({
19867
19872
  exports2.ALLOWED_PATCH_SYSTEM_FIELDS = exports2.getSystemAuthStatus = exports2.detectSystemAuthType = exports2.maskSystemCredentials = exports2.isSensitiveCredentialKey = exports2.ALLOWED_FILE_EXTENSIONS = exports2.getConnectionProtocol = void 0;
19868
19873
  exports2.validateExternalUrl = validateExternalUrl;
19869
19874
  exports2.flattenAndNamespaceCredentials = flattenAndNamespaceCredentials;
19875
+ exports2.flattenAndNamespaceSystemUrls = flattenAndNamespaceSystemUrls;
19870
19876
  exports2.generateUniqueId = generateUniqueId;
19871
19877
  exports2.waitForSystemProcessing = waitForSystemProcessing;
19872
19878
  exports2.inferJsonSchema = inferJsonSchema;
@@ -20067,6 +20073,14 @@ var require_utils = __commonJS({
20067
20073
  return acc;
20068
20074
  }, {});
20069
20075
  }
20076
+ function flattenAndNamespaceSystemUrls(systems2) {
20077
+ return systems2.reduce((acc, sys) => {
20078
+ if (sys.url) {
20079
+ acc[`${sys.id}_url`] = sys.url;
20080
+ }
20081
+ return acc;
20082
+ }, {});
20083
+ }
20070
20084
  async function generateUniqueId({ baseId, exists }) {
20071
20085
  if (!await exists(baseId)) {
20072
20086
  return baseId;
@@ -20448,6 +20462,7 @@ var require_utils = __commonJS({
20448
20462
  "multiTenancyMode",
20449
20463
  "documentationFiles",
20450
20464
  "tunnel"
20465
+ // Note: "environment" is NOT patchable because it's part of the composite primary key
20451
20466
  ];
20452
20467
  var SAMPLEABLE_KEYS = /* @__PURE__ */ new Set([
20453
20468
  "data",
@@ -21096,9 +21111,9 @@ var require_superglue_client = __commonJS({
21096
21111
  var types_js_1 = require_types();
21097
21112
  var sse_log_subscription_js_1 = require_sse_log_subscription();
21098
21113
  var SuperglueClient3 = class {
21099
- constructor({ endpoint, apiKey, apiEndpoint, onInfrastructureError }) {
21114
+ constructor({ apiKey, apiEndpoint, onInfrastructureError }) {
21100
21115
  this.apiKey = apiKey;
21101
- this.apiEndpoint = apiEndpoint ?? endpoint ?? "https://api.superglue.cloud";
21116
+ this.apiEndpoint = apiEndpoint ?? "https://api.superglue.cloud";
21102
21117
  this.sseManager = new sse_log_subscription_js_1.SSELogSubscriptionManager(this.apiEndpoint, this.apiKey);
21103
21118
  this.onInfrastructureError = onInfrastructureError;
21104
21119
  }
@@ -21218,14 +21233,15 @@ var require_superglue_client = __commonJS({
21218
21233
  * Execute a single step without creating a run in the database.
21219
21234
  * Used for individual step testing in the playground.
21220
21235
  */
21221
- async executeStep({ step, payload, previousResults, credentials, options, runId }) {
21236
+ async executeStep({ step, payload, previousResults, credentials, options, runId, mode }) {
21222
21237
  return this.restRequest("POST", "/v1/tools/step/run", {
21223
21238
  step,
21224
21239
  payload,
21225
21240
  previousResults,
21226
21241
  credentials,
21227
21242
  options,
21228
- runId
21243
+ runId,
21244
+ mode
21229
21245
  });
21230
21246
  }
21231
21247
  /**
@@ -21400,11 +21416,14 @@ var require_superglue_client = __commonJS({
21400
21416
  newId
21401
21417
  });
21402
21418
  }
21403
- async listSystems(limit = 10, page = 1) {
21419
+ async listSystems(limit = 10, page = 1, options) {
21404
21420
  const params = new URLSearchParams({
21405
21421
  limit: String(limit),
21406
21422
  page: String(page)
21407
21423
  });
21424
+ if (options?.mode) {
21425
+ params.set("mode", options.mode);
21426
+ }
21408
21427
  const response = await this.restRequest("GET", `/v1/systems?${params.toString()}`);
21409
21428
  return { items: response.data, total: response.total };
21410
21429
  }
@@ -21413,20 +21432,23 @@ var require_superglue_client = __commonJS({
21413
21432
  const response = await this.restRequest("GET", `/v1/tools/search${params}`);
21414
21433
  return response.data;
21415
21434
  }
21416
- async getSystem(id) {
21417
- const response = await this.restRequest("GET", `/v1/systems/${encodeURIComponent(id)}`);
21435
+ async getSystem(id, options) {
21436
+ const queryParams = options?.environment ? `?env=${options.environment}` : "";
21437
+ const response = await this.restRequest("GET", `/v1/systems/${encodeURIComponent(id)}${queryParams}`);
21418
21438
  return response.data;
21419
21439
  }
21420
21440
  async createSystem(input) {
21421
21441
  const response = await this.restRequest("POST", "/v1/systems", input);
21422
21442
  return response.data;
21423
21443
  }
21424
- async updateSystem(id, input) {
21425
- const response = await this.restRequest("PATCH", `/v1/systems/${encodeURIComponent(id)}`, input);
21444
+ async updateSystem(id, input, options) {
21445
+ const queryParams = options?.environment ? `?env=${options.environment}` : "";
21446
+ const response = await this.restRequest("PATCH", `/v1/systems/${encodeURIComponent(id)}${queryParams}`, input);
21426
21447
  return response.data;
21427
21448
  }
21428
- async deleteSystem(id) {
21429
- await this.restRequest("DELETE", `/v1/systems/${encodeURIComponent(id)}`);
21449
+ async deleteSystem(id, options) {
21450
+ const queryParams = options?.environment ? `?env=${options.environment}` : "";
21451
+ await this.restRequest("DELETE", `/v1/systems/${encodeURIComponent(id)}${queryParams}`);
21430
21452
  return true;
21431
21453
  }
21432
21454
  async cacheOAuthSecret(args) {
@@ -21584,18 +21606,14 @@ var require_dist2 = __commonJS({
21584
21606
  });
21585
21607
 
21586
21608
  // src/cli.ts
21587
- var import_commander = require("commander");
21609
+ var import_commander5 = require("commander");
21588
21610
 
21589
21611
  // src/config.ts
21590
21612
  var fs = __toESM(require("fs"));
21591
21613
  var os = __toESM(require("os"));
21592
21614
  var path = __toESM(require("path"));
21593
21615
  var DEFAULT_CONFIG = {
21594
- output: { mode: "stdout", directory: ".superglue/output" },
21595
- policies: {
21596
- callSystem: "ask_every_time",
21597
- editTool: "confirm"
21598
- }
21616
+ output: { mode: "stdout", directory: ".superglue/output" }
21599
21617
  };
21600
21618
  function getConfigDir(preferLocal) {
21601
21619
  const localDir = path.join(process.cwd(), ".superglue");
@@ -21638,8 +21656,7 @@ function resolveConfig(flags) {
21638
21656
  apiKey,
21639
21657
  endpoint,
21640
21658
  webEndpoint,
21641
- output: { ...DEFAULT_CONFIG.output, ...file.output },
21642
- policies: { ...DEFAULT_CONFIG.policies, ...file.policies }
21659
+ output: { ...DEFAULT_CONFIG.output, ...file.output }
21643
21660
  };
21644
21661
  }
21645
21662
  function writeConfig(config, preferLocal) {
@@ -21692,9 +21709,10 @@ var package_default = {
21692
21709
  sg: "./dist/cli.js"
21693
21710
  },
21694
21711
  files: [
21712
+ ".claude-plugin/",
21695
21713
  "dist/",
21696
21714
  "skills/",
21697
- "skills.md"
21715
+ "LICENSE"
21698
21716
  ],
21699
21717
  dependencies: {
21700
21718
  commander: "^13.0.0",
@@ -21820,6 +21838,10 @@ var c = {
21820
21838
  bgMagenta: "\x1B[45m",
21821
21839
  bgCyan: "\x1B[46m"
21822
21840
  };
21841
+ function link(url, label) {
21842
+ const text = label || url;
21843
+ return `\x1B]8;;${url}\x07${c.underline}${c.cyan}${text}${c.reset}\x1B]8;;\x07`;
21844
+ }
21823
21845
  function banner() {
21824
21846
  if (isJsonMode()) return;
21825
21847
  const rst = c.reset;
@@ -21856,20 +21878,28 @@ function banner() {
21856
21878
  function spinner(message) {
21857
21879
  if (isJsonMode()) return { stop: () => {
21858
21880
  }, update: () => {
21881
+ }, log: () => {
21859
21882
  } };
21860
21883
  const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
21861
21884
  let i = 0;
21862
21885
  let currentMsg = message;
21863
- const interval = setInterval(() => {
21886
+ const clearLine = () => process.stdout.write(`\r\x1B[2K`);
21887
+ const drawSpinner = () => {
21864
21888
  process.stdout.write(`\r ${c.cyan}${frames[i++ % frames.length]}${c.reset} ${currentMsg}`);
21865
- }, 80);
21889
+ };
21890
+ const interval = setInterval(drawSpinner, 80);
21866
21891
  return {
21867
21892
  update: (msg) => {
21868
21893
  currentMsg = msg;
21869
21894
  },
21895
+ log: (line) => {
21896
+ clearLine();
21897
+ console.log(` ${c.dim}\u2502${c.reset} ${line}`);
21898
+ drawSpinner();
21899
+ },
21870
21900
  stop: (finalMsg) => {
21871
21901
  clearInterval(interval);
21872
- process.stdout.write(`\r${"".padEnd(currentMsg.length + 10)}\r`);
21902
+ clearLine();
21873
21903
  if (finalMsg) console.log(` ${finalMsg}`);
21874
21904
  }
21875
21905
  };
@@ -22070,16 +22100,6 @@ function renderDiffs(diffs) {
22070
22100
  return ` ${color}${icon} ${c.bold}[${d.op}]${c.reset} ${c.dim}${d.path}${c.reset}${valueStr}`;
22071
22101
  }).join("\n");
22072
22102
  }
22073
- async function confirm(message) {
22074
- if (process.argv.includes("--yes") || process.argv.includes("-y")) return true;
22075
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
22076
- return new Promise((resolve4) => {
22077
- rl.question(` ${message} ${c.dim}[y/N]${c.reset} `, (answer) => {
22078
- rl.close();
22079
- resolve4(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
22080
- });
22081
- });
22082
- }
22083
22103
  async function prompt(message, defaultValue) {
22084
22104
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
22085
22105
  const suffix = defaultValue ? ` ${c.dim}[${defaultValue}]${c.reset}` : "";
@@ -22092,23 +22112,30 @@ async function prompt(message, defaultValue) {
22092
22112
  }
22093
22113
  async function promptHidden(message) {
22094
22114
  return new Promise((resolve4) => {
22095
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
22096
- process.stdout.write(` ${message}: `);
22097
- if (process.stdin.isTTY) {
22098
- process.stdin.setRawMode(true);
22115
+ process.stdout.write(`${message}: `);
22116
+ if (!process.stdin.isTTY) {
22117
+ const rl = readline.createInterface({ input: process.stdin });
22118
+ rl.once("line", (line) => {
22119
+ rl.close();
22120
+ resolve4(line.trim());
22121
+ });
22122
+ return;
22099
22123
  }
22124
+ process.stdin.setRawMode(true);
22125
+ process.stdin.resume();
22100
22126
  let input = "";
22101
22127
  const onData = (ch) => {
22102
22128
  const s = ch.toString();
22103
22129
  for (const char of s) {
22104
22130
  if (char === "\n" || char === "\r") {
22105
- if (process.stdin.isTTY) process.stdin.setRawMode(false);
22131
+ process.stdin.setRawMode(false);
22106
22132
  process.stdin.removeListener("data", onData);
22133
+ process.stdin.pause();
22107
22134
  process.stdout.write("\n");
22108
- rl.close();
22109
22135
  resolve4(input);
22110
22136
  return;
22111
22137
  } else if (char === "") {
22138
+ process.stdin.setRawMode(false);
22112
22139
  process.exit(130);
22113
22140
  } else if (char === "\x7F" || char === "\b") {
22114
22141
  if (input.length > 0) {
@@ -22122,20 +22149,60 @@ async function promptHidden(message) {
22122
22149
  }
22123
22150
  };
22124
22151
  process.stdin.on("data", onData);
22125
- process.stdin.resume();
22126
22152
  });
22127
22153
  }
22128
22154
  async function choose(message, options, defaultIndex = 0) {
22129
22155
  if (!process.stdout.isTTY) return defaultIndex;
22130
- console.log("");
22131
- for (let i = 0; i < options.length; i++) {
22132
- const marker = i === defaultIndex ? `${c.cyan}\u276F${c.reset}` : " ";
22133
- const label = i === defaultIndex ? `${c.bold}${options[i]}${c.reset}` : `${c.dim}${options[i]}${c.reset}`;
22134
- console.log(` ${marker} ${c.dim}(${i + 1})${c.reset} ${label}`);
22135
- }
22136
- const answer = await prompt(` ${message}`, String(defaultIndex + 1));
22137
- const idx = parseInt(answer, 10) - 1;
22138
- return idx >= 0 && idx < options.length ? idx : defaultIndex;
22156
+ let selected = defaultIndex;
22157
+ const render = () => {
22158
+ for (let i = 0; i < options.length; i++) {
22159
+ const marker = i === selected ? `${c.cyan}\u276F${c.reset}` : " ";
22160
+ const label = i === selected ? `${c.bold}${options[i]}${c.reset}` : `${c.dim}${options[i]}${c.reset}`;
22161
+ console.log(` ${marker} ${label}`);
22162
+ }
22163
+ };
22164
+ const moveUp = () => {
22165
+ process.stdout.write(`\x1B[${options.length}A\r`);
22166
+ for (let i = 0; i < options.length; i++) {
22167
+ process.stdout.write(`\x1B[2K`);
22168
+ if (i < options.length - 1) process.stdout.write(`
22169
+ `);
22170
+ }
22171
+ process.stdout.write(`\x1B[${options.length - 1}A\r`);
22172
+ };
22173
+ console.log(
22174
+ `
22175
+ ${c.bold}${message}${c.reset} ${c.dim}(\u2191/\u2193 to select, enter to confirm)${c.reset}`
22176
+ );
22177
+ render();
22178
+ return new Promise((resolve4) => {
22179
+ process.stdin.setRawMode(true);
22180
+ process.stdin.resume();
22181
+ const onData = (ch) => {
22182
+ const s = ch.toString();
22183
+ if (s === "\r" || s === "\n") {
22184
+ process.stdin.setRawMode(false);
22185
+ process.stdin.removeListener("data", onData);
22186
+ process.stdin.pause();
22187
+ resolve4(selected);
22188
+ return;
22189
+ }
22190
+ if (s === "") {
22191
+ process.stdin.setRawMode(false);
22192
+ process.exit(130);
22193
+ }
22194
+ if (s === "\x1B[A" || s === "k") {
22195
+ selected = (selected - 1 + options.length) % options.length;
22196
+ } else if (s === "\x1B[B" || s === "j") {
22197
+ selected = (selected + 1) % options.length;
22198
+ } else {
22199
+ return;
22200
+ }
22201
+ moveUp();
22202
+ render();
22203
+ };
22204
+ process.stdin.on("data", onData);
22205
+ });
22139
22206
  }
22140
22207
 
22141
22208
  // src/commands/init.ts
@@ -22146,6 +22213,10 @@ function registerInitCommand(program2) {
22146
22213
  console.log(` ${c.dim}Let's get you connected in a few steps.${c.reset}
22147
22214
  `);
22148
22215
  heading("Authentication");
22216
+ console.log(
22217
+ ` ${c.dim}Get your API key at${c.reset} ${link("https://app.superglue.cloud/admin?view=api-keys")}`
22218
+ );
22219
+ console.log("");
22149
22220
  const apiKey = await promptHidden(" API Key");
22150
22221
  if (!apiKey) {
22151
22222
  error("API key is required");
@@ -22178,25 +22249,6 @@ function registerInitCommand(program2) {
22178
22249
  if (outputMode === "stdout+file") {
22179
22250
  outputDir = await prompt(" Output directory", ".superglue/output");
22180
22251
  }
22181
- heading("Execution Policies");
22182
- console.log(` ${c.dim}These control when the CLI asks for confirmation.${c.reset}
22183
- `);
22184
- const callPolicyIdx = await choose(
22185
- "API call confirmation",
22186
- ["Ask every time", "Auto-run GET requests only", "Auto-run everything"],
22187
- 0
22188
- );
22189
- const callPolicies = [
22190
- "ask_every_time",
22191
- "run_gets_only",
22192
- "run_everything"
22193
- ];
22194
- const editPolicyIdx = await choose(
22195
- "Tool edit confirmation",
22196
- ["Show diff and ask to confirm", "Auto-accept all changes"],
22197
- 0
22198
- );
22199
- const editPolicies = ["confirm", "auto_accept"];
22200
22252
  heading("Config Location");
22201
22253
  const homeDir = os2.homedir();
22202
22254
  const localPath = path2.join(process.cwd(), ".superglue");
@@ -22214,11 +22266,7 @@ function registerInitCommand(program2) {
22214
22266
  apiKey,
22215
22267
  endpoint,
22216
22268
  webEndpoint,
22217
- output: { mode: outputMode, directory: outputDir },
22218
- policies: {
22219
- callSystem: callPolicies[callPolicyIdx],
22220
- editTool: editPolicies[editPolicyIdx]
22221
- }
22269
+ output: { mode: outputMode, directory: outputDir }
22222
22270
  };
22223
22271
  writeConfig(config, preferLocal);
22224
22272
  ensureConfigDirs(config, preferLocal);
@@ -22449,8 +22497,10 @@ function registerBuildCommand(parent, getContext2) {
22449
22497
  // src/commands/tool/run.ts
22450
22498
  var fs6 = __toESM(require("fs"));
22451
22499
  var path5 = __toESM(require("path"));
22500
+ var crypto2 = __toESM(require("crypto"));
22501
+ var import_shared4 = __toESM(require_dist2());
22452
22502
  function registerRunCommand(parent, getContext2) {
22453
- parent.command("run").description("Execute a draft or saved tool").option("--draft <id>", "Draft ID from build").option("--tool <id>", "Saved tool ID").option("--payload <json>", "JSON payload").option("--payload-file <path>", "JSON payload file").option(
22503
+ parent.command("run").description("Execute a draft, saved tool, or inline tool config").option("--draft <id>", "Draft ID from build").option("--tool <id>", "Saved tool ID").option("--config <json>", "Inline tool config JSON").option("--config-file <path>", "Tool config JSON file").option("--payload <json>", "JSON payload").option("--payload-file <path>", "JSON payload file").option(
22454
22504
  "--file <key=path...>",
22455
22505
  "File references",
22456
22506
  (v, arr) => {
@@ -22460,8 +22510,13 @@ function registerRunCommand(parent, getContext2) {
22460
22510
  []
22461
22511
  ).option("--include-step-results", "Include raw step results").option("--include-config", "Include full tool config").action(async (opts) => {
22462
22512
  const { config, client } = getContext2();
22463
- if (!opts.draft && !opts.tool) {
22464
- error("Provide --draft or --tool");
22513
+ const selectors = [opts.tool, opts.draft, opts.config, opts.configFile].filter(Boolean);
22514
+ if (selectors.length === 0) {
22515
+ error("Provide one of --tool, --draft, --config, or --config-file");
22516
+ process.exit(1);
22517
+ }
22518
+ if (selectors.length > 1) {
22519
+ error("Only one of --tool, --draft, --config, or --config-file can be used");
22465
22520
  process.exit(1);
22466
22521
  }
22467
22522
  const filePayloads = await parseFileFlags(opts.file, client);
@@ -22475,32 +22530,67 @@ function registerRunCommand(parent, getContext2) {
22475
22530
  payload = fileResult.resolved;
22476
22531
  }
22477
22532
  let result;
22478
- const toolLabel = opts.tool || opts.draft;
22533
+ const toolLabel = opts.tool || opts.draft || "inline-config";
22534
+ const traceId = crypto2.randomUUID();
22479
22535
  const spin = spinner(`Running ${c.bold}${toolLabel}${c.reset}...`);
22480
- if (opts.tool) {
22536
+ const logSub = await client.subscribeToLogsSSE({
22537
+ traceId,
22538
+ onLog: (log) => spin.log(`${c.dim}${log.message}${c.reset}`)
22539
+ }).catch(() => ({ unsubscribe: () => {
22540
+ } }));
22541
+ const runToolConfig = async (toolConfig) => {
22481
22542
  try {
22482
- result = await client.runTool({ toolId: opts.tool, payload });
22543
+ const res = await client.runToolConfig({
22544
+ tool: toolConfig,
22545
+ payload,
22546
+ options: { requestSource: import_shared4.RequestSource.CLI },
22547
+ traceId
22548
+ });
22549
+ logSub.unsubscribe();
22483
22550
  spin.stop();
22551
+ return res;
22484
22552
  } catch (err) {
22553
+ logSub.unsubscribe();
22485
22554
  spin.stop();
22486
22555
  error(err.message);
22487
22556
  process.exit(1);
22488
22557
  }
22489
- } else {
22490
- const draft = readDraft(opts.draft);
22491
- if (!draft) {
22558
+ };
22559
+ if (opts.tool) {
22560
+ try {
22561
+ result = await client.runTool({
22562
+ toolId: opts.tool,
22563
+ payload,
22564
+ options: { requestSource: import_shared4.RequestSource.CLI, traceId }
22565
+ });
22566
+ logSub.unsubscribe();
22492
22567
  spin.stop();
22493
- error(`Draft not found: ${opts.draft}`);
22568
+ } catch (err) {
22569
+ logSub.unsubscribe();
22570
+ spin.stop();
22571
+ error(err.message);
22494
22572
  process.exit(1);
22495
22573
  }
22574
+ } else if (opts.config || opts.configFile) {
22575
+ let toolConfig;
22496
22576
  try {
22497
- result = await client.runToolConfig({ tool: draft.config, payload });
22498
- spin.stop();
22577
+ toolConfig = opts.configFile ? JSON.parse(fs6.readFileSync(opts.configFile, "utf-8")) : JSON.parse(opts.config);
22499
22578
  } catch (err) {
22579
+ logSub.unsubscribe();
22500
22580
  spin.stop();
22501
- error(err.message);
22581
+ error(`Invalid tool config JSON: ${err.message}`);
22582
+ process.exit(1);
22583
+ }
22584
+ result = await runToolConfig(toolConfig);
22585
+ } else {
22586
+ const draft = readDraft(opts.draft);
22587
+ if (!draft) {
22588
+ logSub.unsubscribe();
22589
+ spin.stop();
22590
+ error(`Draft not found: ${opts.draft}`);
22502
22591
  process.exit(1);
22503
22592
  }
22593
+ result = await runToolConfig(draft.config);
22504
22594
  }
22505
22595
  const out = {
22506
22596
  success: result.success,
@@ -22513,7 +22603,7 @@ function registerRunCommand(parent, getContext2) {
22513
22603
  if (config.output.mode === "stdout+file") {
22514
22604
  const outDir = path5.resolve(config.output.directory);
22515
22605
  if (!fs6.existsSync(outDir)) fs6.mkdirSync(outDir, { recursive: true });
22516
- const rawId = opts.tool || opts.draft;
22606
+ const rawId = opts.tool || opts.draft || "inline-config";
22517
22607
  const safeId = path5.basename(rawId).replace(/[^a-zA-Z0-9_-]/g, "_");
22518
22608
  const filename = `${safeId}-${Date.now()}.json`;
22519
22609
  fs6.writeFileSync(path5.join(outDir, filename), JSON.stringify(out, null, 2));
@@ -22524,11 +22614,13 @@ function registerRunCommand(parent, getContext2) {
22524
22614
 
22525
22615
  // src/commands/tool/edit.ts
22526
22616
  var fs7 = __toESM(require("fs"));
22527
- var import_shared4 = __toESM(require_dist2());
22617
+ var crypto3 = __toESM(require("crypto"));
22618
+ var import_shared5 = __toESM(require_dist2());
22619
+ var import_shared6 = __toESM(require_dist2());
22528
22620
  var jsonpatch = __toESM(require("fast-json-patch"));
22529
22621
  function registerEditCommand(parent, getContext2) {
22530
22622
  parent.command("edit").description("Edit a tool using JSON Patch operations").option("--draft <id>", "Draft ID to edit").option("--tool <id>", "Saved tool ID to edit").option("--patches <json-or-file>", "JSON Patch array (inline JSON or file path)").option("--payload <json>", "Test payload JSON").option("--test", "Run the patched tool after accepting").action(async (opts) => {
22531
- const { config, client } = getContext2();
22623
+ const { client } = getContext2();
22532
22624
  if (!opts.draft && !opts.tool) {
22533
22625
  error("Provide --draft or --tool");
22534
22626
  process.exit(1);
@@ -22574,7 +22666,7 @@ function registerEditCommand(parent, getContext2) {
22574
22666
  try {
22575
22667
  const copy = JSON.parse(JSON.stringify(originalConfig));
22576
22668
  const result = jsonpatch.applyPatch(copy, patches, true, true);
22577
- patchedConfig = (0, import_shared4.normalizeToolSchemas)(result.newDocument || copy);
22669
+ patchedConfig = (0, import_shared6.normalizeToolSchemas)(result.newDocument || copy);
22578
22670
  } catch (err) {
22579
22671
  error(`Patch failed: ${err.message}`);
22580
22672
  process.exit(1);
@@ -22590,14 +22682,6 @@ function registerEditCommand(parent, getContext2) {
22590
22682
  console.log(renderDiffs(diffs));
22591
22683
  console.log("");
22592
22684
  }
22593
- const autoAccept = process.argv.includes("--yes") || process.argv.includes("-y") || config.policies.editTool === "auto_accept";
22594
- if (!autoAccept) {
22595
- const accepted = await confirm("Accept changes?");
22596
- if (!accepted) {
22597
- output({ success: false, rejected: true, message: "Changes rejected" });
22598
- process.exit(1);
22599
- }
22600
- }
22601
22685
  const draft = {
22602
22686
  draftId: workingDraftId,
22603
22687
  config: {
@@ -22618,9 +22702,21 @@ function registerEditCommand(parent, getContext2) {
22618
22702
  error(`Invalid --payload JSON: ${err.message}`);
22619
22703
  process.exit(1);
22620
22704
  }
22705
+ const traceId = crypto3.randomUUID();
22621
22706
  const spin = spinner("Running test...");
22707
+ const logSub = await client.subscribeToLogsSSE({
22708
+ traceId,
22709
+ onLog: (log) => spin.log(`${c.dim}${log.message}${c.reset}`)
22710
+ }).catch(() => ({ unsubscribe: () => {
22711
+ } }));
22622
22712
  try {
22623
- const testResult = await client.runToolConfig({ tool: draft.config, payload });
22713
+ const testResult = await client.runToolConfig({
22714
+ tool: draft.config,
22715
+ payload,
22716
+ options: { requestSource: import_shared5.RequestSource.CLI },
22717
+ traceId
22718
+ });
22719
+ logSub.unsubscribe();
22624
22720
  spin.stop();
22625
22721
  if (testResult.success) {
22626
22722
  success("Test passed");
@@ -22642,6 +22738,7 @@ function registerEditCommand(parent, getContext2) {
22642
22738
  output(testResult.data);
22643
22739
  }
22644
22740
  } catch (err) {
22741
+ logSub.unsubscribe();
22645
22742
  spin.stop();
22646
22743
  error(`Test error: ${err.message}`);
22647
22744
  output({
@@ -22773,7 +22870,8 @@ function registerToolCommands(program2, getContext2) {
22773
22870
 
22774
22871
  // src/commands/system/create.ts
22775
22872
  var fs8 = __toESM(require("fs"));
22776
- var import_shared5 = __toESM(require_dist2());
22873
+ var import_commander = require("commander");
22874
+ var import_shared7 = __toESM(require_dist2());
22777
22875
  async function collectSensitiveCredentials(fields) {
22778
22876
  const creds = {};
22779
22877
  for (const field of fields) {
@@ -22791,12 +22889,21 @@ async function collectSensitiveCredentials(fields) {
22791
22889
  return creds;
22792
22890
  }
22793
22891
  function registerCreateCommand(parent, getContext2) {
22794
- parent.command("create").description("Create a new system").option("--config <file>", "JSON config file").option("--id <id>", "System ID").option("--name <name>", "Human-readable name").option("--url <url>", "API URL").option("--template <id>", "Template ID").option("--instructions <text>", "Specific instructions").option("--credentials <json>", "Non-sensitive credentials JSON").option("--sensitive-credentials <fields>", "Comma-separated sensitive credential field names").option("--docs-url <url>", "Documentation URL to scrape").option("--openapi-url <url>", "OpenAPI spec URL").action(async (opts) => {
22892
+ parent.command("create").description("Create a new system").option("--config <file>", "JSON config file").option("--id <id>", "System ID").option("--name <name>", "Human-readable name").option("--url <url>", "API URL").option("--template <id>", "Template ID").option("--instructions <text>", "Specific instructions").option("--credentials <json>", "Non-sensitive credentials JSON").option("--sensitive-credentials <fields>", "Comma-separated sensitive credential field names").option("--docs-url <url>", "Documentation URL to scrape").option("--openapi-url <url>", "OpenAPI spec URL").addOption(
22893
+ new import_commander.Option("--env <environment>", "Environment: dev or prod (default: prod)").choices([
22894
+ "dev",
22895
+ "prod"
22896
+ ])
22897
+ ).action(async (opts) => {
22795
22898
  const { client } = getContext2();
22796
22899
  let systemInput;
22797
22900
  if (opts.config) {
22798
22901
  try {
22799
- systemInput = JSON.parse(fs8.readFileSync(opts.config, "utf-8"));
22902
+ const parsed = JSON.parse(fs8.readFileSync(opts.config, "utf-8"));
22903
+ if (opts.env === "dev" || opts.env === "prod") {
22904
+ parsed.environment = opts.env;
22905
+ }
22906
+ systemInput = parsed;
22800
22907
  } catch (err) {
22801
22908
  error(`Invalid config file: ${err.message}`);
22802
22909
  process.exit(1);
@@ -22816,14 +22923,15 @@ function registerCreateCommand(parent, getContext2) {
22816
22923
  name: opts.name,
22817
22924
  url: opts.url,
22818
22925
  specificInstructions: opts.instructions,
22819
- credentials
22926
+ credentials,
22927
+ environment: opts.env === "dev" || opts.env === "prod" ? opts.env : void 0
22820
22928
  };
22821
22929
  }
22822
22930
  if (opts.template) {
22823
- const template = import_shared5.systems[opts.template];
22931
+ const template = import_shared7.systems[opts.template];
22824
22932
  if (!template) {
22825
22933
  error(
22826
- `Template not found: ${opts.template}. Available: ${Object.keys(import_shared5.systems).join(", ")}`
22934
+ `Template not found: ${opts.template}. Available: ${Object.keys(import_shared7.systems).join(", ")}`
22827
22935
  );
22828
22936
  process.exit(1);
22829
22937
  }
@@ -22886,8 +22994,11 @@ function registerCreateCommand(parent, getContext2) {
22886
22994
  }
22887
22995
 
22888
22996
  // src/commands/system/edit.ts
22997
+ var import_commander2 = require("commander");
22889
22998
  function registerEditCommand2(parent, getContext2) {
22890
- parent.command("edit").description("Edit an existing system").requiredOption("--id <id>", "System ID").option("--name <name>", "New name").option("--url <url>", "New URL").option("--instructions <text>", "New specific instructions").option("--credentials <json>", "Non-sensitive credentials JSON to merge").option("--sensitive-credentials <fields>", "Comma-separated sensitive credential field names").option("--scrape-url <url>", "Documentation URL to scrape").option("--scrape-keywords <keywords>", "Space-separated scrape keywords").action(async (opts) => {
22999
+ parent.command("edit").description("Edit an existing system").requiredOption("--id <id>", "System ID").option("--name <name>", "New name").option("--url <url>", "New URL").option("--instructions <text>", "New specific instructions").option("--credentials <json>", "Non-sensitive credentials JSON to merge").option("--sensitive-credentials <fields>", "Comma-separated sensitive credential field names").option("--scrape-url <url>", "Documentation URL to scrape").option("--scrape-keywords <keywords>", "Space-separated scrape keywords").addOption(
23000
+ new import_commander2.Option("--env <environment>", "Environment: dev or prod").choices(["dev", "prod"])
23001
+ ).action(async (opts) => {
22891
23002
  const { client } = getContext2();
22892
23003
  const patchPayload = { id: opts.id };
22893
23004
  if (opts.name) patchPayload.name = opts.name;
@@ -22919,8 +23030,9 @@ function registerEditCommand2(parent, getContext2) {
22919
23030
  patchPayload.credentials = { ...patchPayload.credentials, ...creds };
22920
23031
  }
22921
23032
  try {
23033
+ const envOption = opts.env === "dev" || opts.env === "prod" ? { environment: opts.env } : void 0;
22922
23034
  const spin = spinner(`Updating system ${c.bold}${opts.id}${c.reset}...`);
22923
- const existing = await client.getSystem(opts.id);
23035
+ const existing = await client.getSystem(opts.id, envOption);
22924
23036
  if (!existing) {
22925
23037
  spin.stop();
22926
23038
  error(`System not found: ${opts.id}`);
@@ -22929,7 +23041,7 @@ function registerEditCommand2(parent, getContext2) {
22929
23041
  if (patchPayload.credentials && existing.credentials) {
22930
23042
  patchPayload.credentials = { ...existing.credentials, ...patchPayload.credentials };
22931
23043
  }
22932
- const result = await client.updateSystem(opts.id, patchPayload);
23044
+ const result = await client.updateSystem(opts.id, patchPayload, envOption);
22933
23045
  if (opts.scrapeUrl) {
22934
23046
  try {
22935
23047
  const keywords = opts.scrapeKeywords?.split(" ").filter(Boolean);
@@ -22956,45 +23068,52 @@ function registerEditCommand2(parent, getContext2) {
22956
23068
  }
22957
23069
 
22958
23070
  // src/commands/system/find.ts
22959
- var import_shared6 = __toESM(require_dist2());
23071
+ var import_commander3 = require("commander");
23072
+ var import_shared8 = __toESM(require_dist2());
22960
23073
  function filterSystemFields(system) {
22961
23074
  const credentialKeys = Object.keys(system.credentials || {});
22962
23075
  return {
22963
23076
  id: system.id,
22964
23077
  name: system.name,
22965
23078
  url: system.url,
23079
+ environment: system.environment,
22966
23080
  specificInstructions: system.specificInstructions,
22967
23081
  credentialPlaceholders: credentialKeys.map((k) => `<<${system.id}_${k}>>`)
22968
23082
  };
22969
23083
  }
22970
23084
  function registerFindCommand2(parent, getContext2) {
22971
- parent.command("list").description("List all systems").action(async () => {
23085
+ parent.command("list").description("List all systems").option("--mode <mode>", "Filter by environment: dev, prod, or all (default: all)").action(async (opts) => {
22972
23086
  const { client } = getContext2();
22973
23087
  try {
22974
- const { items } = await client.listSystems(100);
23088
+ const mode = opts.mode === "dev" || opts.mode === "prod" ? opts.mode : "all";
23089
+ const { items } = await client.listSystems(100, 1, { mode });
22975
23090
  table(
22976
23091
  items.map((s) => ({
22977
23092
  id: s.id,
22978
23093
  name: s.name || "",
23094
+ env: s.environment || "prod",
22979
23095
  url: (s.url || "").slice(0, 50)
22980
23096
  })),
22981
- ["id", "name", "url"]
23097
+ ["id", "name", "env", "url"]
22982
23098
  );
22983
23099
  } catch (err) {
22984
23100
  error(err.message);
22985
23101
  process.exit(1);
22986
23102
  }
22987
23103
  });
22988
- parent.command("find [query]").description("Find systems by query or exact ID").option("--id <exactId>", "Exact system ID lookup").action(async (query, opts) => {
23104
+ parent.command("find [query]").description("Find systems by query or exact ID").option("--id <exactId>", "Exact system ID lookup").addOption(
23105
+ new import_commander3.Option("--env <environment>", "Environment: dev or prod").choices(["dev", "prod"])
23106
+ ).action(async (query, opts) => {
22989
23107
  const { client } = getContext2();
22990
23108
  try {
22991
23109
  if (opts.id) {
22992
- const system = await client.getSystem(opts.id);
23110
+ const envOption = opts.env === "dev" || opts.env === "prod" ? { environment: opts.env } : void 0;
23111
+ const system = await client.getSystem(opts.id, envOption);
22993
23112
  if (!system) {
22994
23113
  error(`System not found: ${opts.id}`);
22995
23114
  process.exit(1);
22996
23115
  }
22997
- const templateMatch = (0, import_shared6.findTemplateForSystem)(system);
23116
+ const templateMatch = (0, import_shared8.findTemplateForSystem)(system);
22998
23117
  output({
22999
23118
  success: true,
23000
23119
  system: filterSystemFields(system),
@@ -23002,8 +23121,9 @@ function registerFindCommand2(parent, getContext2) {
23002
23121
  });
23003
23122
  return;
23004
23123
  }
23124
+ const listMode = opts.env ? { mode: opts.env } : void 0;
23005
23125
  const rawQuery = (query || "*").trim();
23006
- const { items } = await client.listSystems(100);
23126
+ const { items } = await client.listSystems(100, 1, listMode);
23007
23127
  if (rawQuery === "*") {
23008
23128
  output({
23009
23129
  success: true,
@@ -23028,16 +23148,8 @@ function registerFindCommand2(parent, getContext2) {
23028
23148
  }
23029
23149
 
23030
23150
  // src/commands/system/call.ts
23031
- var import_shared7 = __toESM(require_dist2());
23032
- function shouldAutoExecute(policy, method, url) {
23033
- if (policy === "run_everything") return true;
23034
- if (policy === "ask_every_time") return false;
23035
- if (policy === "run_gets_only") {
23036
- const protocol = (0, import_shared7.getConnectionProtocol)(url);
23037
- return protocol === "http" && method.toUpperCase() === "GET";
23038
- }
23039
- return false;
23040
- }
23151
+ var import_commander4 = require("commander");
23152
+ var import_shared9 = __toESM(require_dist2());
23041
23153
  function registerCallCommand(parent, getContext2) {
23042
23154
  parent.command("call").description("Call a system (API, database, file server)").requiredOption("--url <url>", "Full URL including protocol").option("--system-id <id>", "System ID for credential injection").option("--method <method>", "HTTP method", "GET").option("--headers <json>", "HTTP headers JSON").option("--body <string>", "Request body").option(
23043
23155
  "--file <key=path...>",
@@ -23047,8 +23159,10 @@ function registerCallCommand(parent, getContext2) {
23047
23159
  return arr;
23048
23160
  },
23049
23161
  []
23162
+ ).addOption(
23163
+ new import_commander4.Option("--env <environment>", "Environment: dev or prod").choices(["dev", "prod"])
23050
23164
  ).action(async (opts) => {
23051
- const { config, client } = getContext2();
23165
+ const { client } = getContext2();
23052
23166
  const method = opts.method || "GET";
23053
23167
  const filePayloads = await parseFileFlags(opts.file, client);
23054
23168
  let body = opts.body;
@@ -23080,31 +23194,6 @@ function registerCallCommand(parent, getContext2) {
23080
23194
  if (err.message?.startsWith("Unresolved file reference")) throw err;
23081
23195
  }
23082
23196
  }
23083
- const autoExec = process.argv.includes("--yes") || process.argv.includes("-y") || shouldAutoExecute(config.policies.callSystem, method, opts.url);
23084
- if (!autoExec) {
23085
- const methodColors = {
23086
- GET: c.green,
23087
- POST: c.yellow,
23088
- PUT: c.blue,
23089
- PATCH: c.magenta,
23090
- DELETE: c.red
23091
- };
23092
- const mc = methodColors[method.toUpperCase()] || c.white;
23093
- console.log("");
23094
- console.log(` ${mc}${c.bold}${method.toUpperCase()}${c.reset} ${opts.url}`);
23095
- if (opts.systemId) console.log(` ${c.dim}system:${c.reset} ${opts.systemId}`);
23096
- if (opts.headers) console.log(` ${c.dim}headers:${c.reset} ${opts.headers}`);
23097
- if (body) {
23098
- const preview = body.length > 200 ? body.slice(0, 200) + `${c.dim}...${c.reset}` : body;
23099
- console.log(` ${c.dim}body:${c.reset} ${preview}`);
23100
- }
23101
- console.log("");
23102
- const accepted = await confirm("Execute this request?");
23103
- if (!accepted) {
23104
- output({ success: false, cancelled: true, message: "Request cancelled" });
23105
- process.exit(0);
23106
- }
23107
- }
23108
23197
  let headers;
23109
23198
  if (opts.headers) {
23110
23199
  try {
@@ -23126,11 +23215,12 @@ function registerCallCommand(parent, getContext2) {
23126
23215
  }
23127
23216
  };
23128
23217
  try {
23129
- const result = await client.executeStep({ step, payload: {} });
23218
+ const mode = opts.env === "dev" || opts.env === "prod" ? opts.env : void 0;
23219
+ const result = await client.executeStep({ step, payload: {}, mode });
23130
23220
  const responseData = result.data?.data !== void 0 ? result.data.data : result.data;
23131
23221
  output({
23132
23222
  success: result.success,
23133
- protocol: (0, import_shared7.getConnectionProtocol)(opts.url),
23223
+ protocol: (0, import_shared9.getConnectionProtocol)(opts.url),
23134
23224
  data: responseData,
23135
23225
  ...result.error ? { error: result.error } : {}
23136
23226
  });
@@ -23144,7 +23234,7 @@ function registerCallCommand(parent, getContext2) {
23144
23234
 
23145
23235
  // src/commands/system/docs.ts
23146
23236
  function registerDocsCommand(parent, getContext2) {
23147
- parent.command("docs").description("Search system documentation").requiredOption("--system-id <id>", "System ID").requiredOption("--keywords <keywords>", "Search keywords").action(async (opts) => {
23237
+ parent.command("search-docs").description("Search system documentation by keywords").requiredOption("--system-id <id>", "System ID").requiredOption("-k, --keywords <keywords>", "Search keywords").action(async (opts) => {
23148
23238
  const { client } = getContext2();
23149
23239
  try {
23150
23240
  const result = await client.searchSystemDocumentation(opts.systemId, opts.keywords);
@@ -23191,7 +23281,7 @@ function registerDocsCommand(parent, getContext2) {
23191
23281
 
23192
23282
  // src/commands/system/oauth.ts
23193
23283
  var import_node_child_process2 = require("child_process");
23194
- var import_shared8 = __toESM(require_dist2());
23284
+ var import_shared10 = __toESM(require_dist2());
23195
23285
  function openBrowser(url) {
23196
23286
  const platform = process.platform;
23197
23287
  const cmd = platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
@@ -23227,7 +23317,7 @@ function registerOAuthCommand(parent, getContext2) {
23227
23317
  error(err.message);
23228
23318
  process.exit(1);
23229
23319
  }
23230
- const templateMatch = (0, import_shared8.findTemplateForSystem)(system);
23320
+ const templateMatch = (0, import_shared10.findTemplateForSystem)(system);
23231
23321
  const templateOAuth = templateMatch?.template?.oauth;
23232
23322
  const clientId = system.credentials?.client_id ?? templateOAuth?.client_id;
23233
23323
  const authUrl = opts.authUrl ?? system.credentials?.auth_url ?? templateOAuth?.authUrl;
@@ -23305,7 +23395,7 @@ function registerOAuthCommand(parent, getContext2) {
23305
23395
  error(`Failed to get OAuth encryption secret: ${err.message}`);
23306
23396
  process.exit(1);
23307
23397
  }
23308
- const encryptedApiKey = (0, import_shared8.encryptCliApiKey)(config.apiKey, opts.systemId, encryptionSecret);
23398
+ const encryptedApiKey = (0, import_shared10.encryptCliApiKey)(config.apiKey, opts.systemId, encryptionSecret);
23309
23399
  const redirectUri = `${config.webEndpoint.replace(/\/$/, "")}/api/auth/callback`;
23310
23400
  const state = {
23311
23401
  systemId: opts.systemId,
@@ -23481,45 +23571,44 @@ function registerUpdateCommand(program2) {
23481
23571
  }
23482
23572
 
23483
23573
  // src/cli.ts
23484
- var program = new import_commander.Command();
23485
- program.name("sg").description("superglue CLI \u2014 build, run, and manage integration tools").version(CLI_VERSION).option("--api-key <key>", "superglue API key").option("--endpoint <url>", "superglue API endpoint").option("--json", "force JSON output").option("-y, --yes", "auto-accept all confirmations").addHelpText(
23574
+ var program = new import_commander5.Command();
23575
+ program.name("sg").description("superglue CLI \u2014 build, run, and manage integration tools").version(CLI_VERSION).option("--api-key <key>", "superglue API key").option("--endpoint <url>", "superglue API endpoint").option("--json", "force JSON output").addHelpText(
23486
23576
  "after",
23487
23577
  `
23488
23578
  All Commands:
23489
- sg init Set up CLI configuration
23579
+ sg init Set up CLI configuration
23490
23580
 
23491
- sg tool build --config <file> Build a tool from a JSON config file
23492
- sg tool build --id <id> --instruction <t> Build a tool from flags (requires --steps <file>)
23493
- sg tool run --draft <id> [--payload <json>] Run a draft tool
23494
- sg tool run --tool <id> [--payload <json>] Run a saved tool
23495
- sg tool edit --tool <id> --patches <json> Edit a tool via JSON Patch operations
23496
- sg tool edit --draft <id> --patches <json> Edit a draft via JSON Patch operations
23497
- sg tool save <id> Save a draft tool to the server
23498
- sg tool list List all saved tools (IDs + instructions)
23499
- sg tool find [query] Search tools by keyword
23500
- sg tool find --id <id> Get full config of a specific tool
23581
+ sg tool build --config <file> Build a tool from a JSON config
23582
+ sg tool build --id <id> --instruction <text> Build a tool from flags (requires --steps)
23583
+ sg tool run --tool <id> [--payload <json>] Run a saved tool
23584
+ sg tool run --draft <id> [--payload <json>] Run a draft tool
23585
+ sg tool edit --tool <id> --patches <json> Edit a tool via JSON Patch
23586
+ sg tool edit --draft <id> --patches <json> Edit a draft via JSON Patch
23587
+ sg tool save --draft <id> Save a draft to the server
23588
+ sg tool list List all saved tools
23589
+ sg tool find [query] Search tools by keyword
23590
+ sg tool find --id <id> Get full config of a tool
23501
23591
 
23502
- sg system create --config <file> Create a system from a JSON config file
23503
- sg system create --id <id> --url <url> Create a system from flags
23504
- sg system edit <id> Edit a system's configuration
23505
- sg system list List all systems
23506
- sg system find [query] Search systems by keyword
23507
- sg system find --id <id> Get full config of a specific system
23508
- sg system call --url <url> [--method GET] Call an API/DB/file server with credential injection
23509
- sg system docs <id> View system documentation
23510
- sg system oauth <id> Authenticate a system via OAuth
23592
+ sg system create --config <file> Create a system from JSON config
23593
+ sg system create --id <id> --url <url> Create a system from flags
23594
+ sg system edit --id <id> Edit a system's configuration
23595
+ sg system list List all systems
23596
+ sg system find [query] Search systems by keyword
23597
+ sg system find --id <id> Get full config of a system
23598
+ sg system call --url <url> [--method GET] Call an API, database, or file server
23599
+ sg system search-docs --system-id <id> -k <kw> Search system documentation
23600
+ sg system oauth --system-id <id> --scopes <s> Authenticate a system via OAuth
23511
23601
 
23512
- sg run list [toolId] List execution runs, optionally filtered by tool
23513
- sg run get <runId> Get details of a specific run
23602
+ sg run list [toolId] List runs, optionally filtered by tool
23603
+ sg run get <runId> Get details of a specific run
23514
23604
 
23515
- sg update Update CLI to latest version
23516
- sg update --check Check for available updates
23605
+ sg update Update CLI to latest version
23606
+ sg update --check Check for available updates
23517
23607
 
23518
23608
  Global Flags:
23519
- --api-key <key> Override API key from config
23520
- --endpoint <url> Override API endpoint from config
23521
- --json Force JSON output (default in non-TTY)
23522
- -y, --yes Auto-accept all confirmations
23609
+ --api-key <key> Override API key from config
23610
+ --endpoint <url> Override API endpoint from config
23611
+ --json Force JSON output (default in non-TTY)
23523
23612
  `
23524
23613
  );
23525
23614
  var getContext = () => {
@@ -23535,7 +23624,7 @@ registerSystemCommands(program, getContext);
23535
23624
  registerRunCommands(program, getContext);
23536
23625
  var commandsRequiringServer = ["tool", "system", "run"];
23537
23626
  var globalFlagsWithValues = ["--api-key", "--endpoint"];
23538
- var globalFlagsNoValue = ["--json", "-y", "--yes", "-h", "--help", "-V", "--version"];
23627
+ var globalFlagsNoValue = ["--json", "-h", "--help", "-V", "--version"];
23539
23628
  function findSubcommand(argv) {
23540
23629
  let i = 2;
23541
23630
  while (i < argv.length) {