@superglue/cli 1.1.13 → 1.1.15

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/dist/cli.js CHANGED
@@ -1925,7 +1925,9 @@ var require_types = __commonJS({
1925
1925
  RemoveScope2["ENTRY"] = "ENTRY";
1926
1926
  })(RemoveScope || (exports2.RemoveScope = RemoveScope = {}));
1927
1927
  function isRequestConfig(config) {
1928
- return config?.type === "request" || !config?.type;
1928
+ if (!config || typeof config !== "object")
1929
+ return false;
1930
+ return config.type === "request" || !("type" in config) || config.type === void 0;
1929
1931
  }
1930
1932
  function isTransformConfig(config) {
1931
1933
  return config?.type === "transform";
@@ -2415,6 +2417,7 @@ Use parameterized queries with $1, $2, etc. placeholders:
2415
2417
  }
2416
2418
  }
2417
2419
  },
2420
+ outputTransform: `(sourceData) => { const quote = sourceData.fetchStock?.data?.["Global Quote"] || {}; return { symbol: quote["01. symbol"] || sourceData.symbol || "AAPL", price: parseFloat(quote["05. price"] || "0").toFixed(2), change: quote["09. change"] || "0", changePercent: quote["10. change percent"] || "0%", volume: parseInt(quote["06. volume"] || "0").toLocaleString(), tradingDay: quote["07. latest trading day"] || "N/A", emailSent: sourceData.sendEmail?.success || false }; }`,
2418
2421
  instruction: "Fetches the current stock quote from Alpha Vantage and sends an email with the stock information to your registered email address."
2419
2422
  }
2420
2423
  ]
@@ -2454,6 +2457,25 @@ var require_templates = __commonJS({
2454
2457
  preferredAuthType: "apikey",
2455
2458
  keywords: ["database", "cache", "redis", "key-value", "nosql", "api key"]
2456
2459
  },
2460
+ azure_sql: {
2461
+ name: "azure_sql",
2462
+ apiUrl: "sqlserver://<<host>>:1433;database=<<database>>",
2463
+ regex: "^.*(azure.*sql|sql.*azure|database\\.windows\\.net).*$",
2464
+ icon: "default",
2465
+ docsUrl: "https://learn.microsoft.com/en-us/azure/azure-sql/",
2466
+ preferredAuthType: "apikey",
2467
+ keywords: [
2468
+ "database",
2469
+ "sql",
2470
+ "azure",
2471
+ "query",
2472
+ "table",
2473
+ "schema",
2474
+ "connection",
2475
+ "mssql",
2476
+ "sqlserver"
2477
+ ]
2478
+ },
2457
2479
  stripe: {
2458
2480
  name: "stripe",
2459
2481
  apiUrl: "https://api.stripe.com",
@@ -2539,6 +2561,30 @@ var require_templates = __commonJS({
2539
2561
  "memberships"
2540
2562
  ]
2541
2563
  },
2564
+ hrworks: {
2565
+ name: "hrworks",
2566
+ apiUrl: "https://api.hrworks.de/v2",
2567
+ regex: "(^|.*\\b)(hr\\s?works|hrworks)(\\b.*|$)",
2568
+ icon: "default",
2569
+ docsUrl: "https://developers.hrworks.de/",
2570
+ preferredAuthType: "apikey",
2571
+ keywords: [
2572
+ "hr",
2573
+ "employee",
2574
+ "absence",
2575
+ "vacation",
2576
+ "payroll",
2577
+ "personnel",
2578
+ "time_tracking",
2579
+ "human_resources",
2580
+ "working_time",
2581
+ "attendance",
2582
+ "onboarding",
2583
+ "applicant_management",
2584
+ "travel_expenses",
2585
+ "sick_leave"
2586
+ ]
2587
+ },
2542
2588
  attio: {
2543
2589
  name: "attio",
2544
2590
  apiUrl: "https://api.attio.com/v2/",
@@ -2805,6 +2851,15 @@ var require_templates = __commonJS({
2805
2851
  "oauth"
2806
2852
  ]
2807
2853
  },
2854
+ granola: {
2855
+ name: "granola",
2856
+ apiUrl: "https://public-api.granola.ai",
2857
+ regex: "^.*granola.*$",
2858
+ icon: "default",
2859
+ docsUrl: "https://docs.granola.ai",
2860
+ preferredAuthType: "apikey",
2861
+ keywords: ["meeting", "notes", "transcript", "summary", "ai", "recording"]
2862
+ },
2808
2863
  googleDrive: {
2809
2864
  name: "googleDrive",
2810
2865
  apiUrl: "https://www.googleapis.com/drive/v3",
@@ -4306,6 +4361,58 @@ HEADERS: { "Authorization": "Bearer <<token>>", "Content-Type": "application/jso
4306
4361
  "api key"
4307
4362
  ]
4308
4363
  },
4364
+ creatio: {
4365
+ name: "creatio",
4366
+ apiUrl: "https://<<instance>>.creatio.com/0/odata",
4367
+ regex: "^(.*\\.)?creatio\\.com(/.*)?$",
4368
+ icon: "default",
4369
+ docsUrl: "https://academy.creatio.com/docs/developer/integrations_and_api/data_services/odata/overview",
4370
+ preferredAuthType: "oauth",
4371
+ oauth: {
4372
+ authUrl: "https://<<instance>>.creatio.com/0/connect/authorize",
4373
+ tokenUrl: "https://<<instance>>.creatio.com/0/connect/token",
4374
+ scopes: "offline_access",
4375
+ grant_type: "authorization_code"
4376
+ },
4377
+ systemSpecificInstructions: `Creatio uses OIDC-compliant OAuth endpoints. The standard /ServiceModel/AuthService.svc/Authorize and /rest/oauth/token endpoints are behind IIS session auth and will NOT work for OAuth flows \u2014 you MUST use the /0/connect/* OIDC endpoints instead.
4378
+
4379
+ To discover the correct endpoints for any Creatio instance, fetch: https://<instance>.creatio.com/0/.well-known/openid-configuration
4380
+
4381
+ This returns authorization_endpoint, token_endpoint, and other OIDC URLs.
4382
+
4383
+ IMPORTANT \u2014 Scopes:
4384
+ - "offline_access" gets you a refresh token but may not grant API access alone.
4385
+ - To get actual API access, the user needs the ApplicationAccess scope: "offline_access ApplicationAccess_<GUID>"
4386
+ - The GUID is found in Creatio: System Designer \u2192 Lookups \u2192 "OAuth resources" \u2192 Name column (strip dashes).
4387
+ - The OAuth app in Creatio must also have this resource added under its permitted resources.
4388
+
4389
+ OAuth App Setup in Creatio:
4390
+ 1. System Designer \u2192 "OAuth 2.0 integrated applications" \u2192 create app with grant type "On behalf of a user (authorization code)"
4391
+ 2. Set redirect URI to the superglue callback URL
4392
+ 3. Under the app's permitted resources, add the ApplicationAccess resource
4393
+ 4. Note the Client ID and Client Secret
4394
+
4395
+ API Base URLs:
4396
+ - OData 4: https://<instance>.creatio.com/0/odata/ (e.g., /0/odata/Contact)
4397
+ - OData 3: https://<instance>.creatio.com/0/ServiceModel/EntityDataService.svc/ (e.g., /EntityDataService.svc/ContactCollection)
4398
+ - Use Bearer token auth: Authorization: Bearer <access_token>`,
4399
+ keywords: [
4400
+ "contacts",
4401
+ "accounts",
4402
+ "leads",
4403
+ "opportunities",
4404
+ "activities",
4405
+ "cases",
4406
+ "orders",
4407
+ "products",
4408
+ "invoices",
4409
+ "campaigns",
4410
+ "crm",
4411
+ "bpm",
4412
+ "odata",
4413
+ "oauth"
4414
+ ]
4415
+ },
4309
4416
  sanity: {
4310
4417
  name: "sanity",
4311
4418
  apiUrl: "https://api.sanity.io",
@@ -5365,7 +5472,7 @@ CUSTOM APIs: Publishers expose custom API pages at /api/{publisher}/{group}/{ver
5365
5472
  },
5366
5473
  googleAds: {
5367
5474
  name: "googleAds",
5368
- apiUrl: "https://googleads.googleapis.com/v20",
5475
+ apiUrl: "https://googleads.googleapis.com/v23",
5369
5476
  regex: "^.*(googleads\\.googleapis|developers\\.google\\.com/google-ads|adwords\\.google).*$",
5370
5477
  icon: "googleads",
5371
5478
  docsUrl: "https://developers.google.com/google-ads/api/docs/concepts/overview",
@@ -5373,11 +5480,24 @@ CUSTOM APIs: Publishers expose custom API pages at /api/{publisher}/{group}/{ver
5373
5480
  oauth: {
5374
5481
  authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
5375
5482
  tokenUrl: "https://oauth2.googleapis.com/token",
5376
- scopes: "https://www.googleapis.com/auth/adwords https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid"
5483
+ scopes: "https://www.googleapis.com/auth/adwords"
5377
5484
  },
5485
+ systemSpecificInstructions: `Google Ads API requires BOTH OAuth AND a developer token on every request.
5486
+
5487
+ REQUIRED HEADERS:
5488
+ - Authorization: Bearer <access_token>
5489
+ - developer-token: <22-char token from https://ads.google.com/aw/apicenter>
5490
+ - login-customer-id: <manager-account-id without hyphens> (only when calling through a manager account)
5491
+
5492
+ SETUP: User needs a Google Ads Manager account, a Google Cloud project with OAuth credentials, and a developer token (applied for via the API Center). New tokens start as test-only; production access requires a follow-up application.
5493
+
5494
+ QUERYING (GAQL): Use Google Ads Query Language via:
5495
+ - POST /v23/customers/{customerId}/googleAds:searchStream (streaming, recommended)
5496
+ - POST /v23/customers/{customerId}/googleAds:search (paginated)
5497
+ Example: SELECT campaign.name, metrics.impressions FROM campaign WHERE segments.date DURING LAST_30_DAYS`,
5378
5498
  keywords: [
5379
5499
  "campaigns",
5380
- "ad groups",
5500
+ "ad_groups",
5381
5501
  "ads",
5382
5502
  "keywords",
5383
5503
  "GAQL",
@@ -5390,6 +5510,9 @@ CUSTOM APIs: Publishers expose custom API pages at /api/{publisher}/{group}/{ver
5390
5510
  "accounts",
5391
5511
  "billing",
5392
5512
  "targeting",
5513
+ "search_terms",
5514
+ "metrics",
5515
+ "segments",
5393
5516
  "oauth"
5394
5517
  ]
5395
5518
  },
@@ -5446,6 +5569,33 @@ CUSTOM APIs: Publishers expose custom API pages at /api/{publisher}/{group}/{ver
5446
5569
  "api key"
5447
5570
  ]
5448
5571
  },
5572
+ circleback: {
5573
+ name: "circleback",
5574
+ apiUrl: "https://app.circleback.ai",
5575
+ regex: "^.*circleback.*$",
5576
+ icon: "default",
5577
+ docsUrl: "https://support.circleback.ai/en/articles/13249081-circleback-mcp",
5578
+ preferredAuthType: "oauth",
5579
+ systemSpecificInstructions: `Circleback has NO traditional REST API. Data access is exclusively via their MCP server.
5580
+
5581
+ MCP ENDPOINT: https://app.circleback.ai/api/mcp
5582
+ PROTOCOL: JSON-RPC 2.0 over Streamable HTTP transport
5583
+ AUTH: OAuth 2.0 with dynamic client registration (no app registration needed).
5584
+
5585
+ AVAILABLE DATA: meetings, transcripts, action items, calendar events, emails, people, companies.`,
5586
+ keywords: [
5587
+ "meetings",
5588
+ "transcripts",
5589
+ "notes",
5590
+ "action_items",
5591
+ "calendar_events",
5592
+ "attendees",
5593
+ "summaries",
5594
+ "people",
5595
+ "companies",
5596
+ "emails"
5597
+ ]
5598
+ },
5449
5599
  firecrawl: {
5450
5600
  name: "firecrawl",
5451
5601
  apiUrl: "https://api.firecrawl.dev/v1",
@@ -5710,6 +5860,8 @@ var require_type_utils = __commonJS({
5710
5860
  exports2.PAGINATION_TYPE_MAP = void 0;
5711
5861
  exports2.mapPaginationType = mapPaginationType;
5712
5862
  exports2.mapFailureBehavior = mapFailureBehavior;
5863
+ exports2.validateToolStructure = validateToolStructure;
5864
+ var types_js_1 = require_types();
5713
5865
  exports2.PAGINATION_TYPE_MAP = {
5714
5866
  OFFSET_BASED: "offsetBased",
5715
5867
  PAGE_BASED: "pageBased",
@@ -5729,6 +5881,50 @@ var require_type_utils = __commonJS({
5729
5881
  return void 0;
5730
5882
  return internal.toLowerCase();
5731
5883
  }
5884
+ function validateToolStructure(tool) {
5885
+ if (!tool || typeof tool !== "object") {
5886
+ return { valid: false, error: "Tool must be an object" };
5887
+ }
5888
+ const candidate = tool;
5889
+ if (!candidate.id || typeof candidate.id !== "string") {
5890
+ return { valid: false, error: "Tool must have a valid 'id' string" };
5891
+ }
5892
+ if (!Array.isArray(candidate.steps)) {
5893
+ return { valid: false, error: "Tool must have a 'steps' array" };
5894
+ }
5895
+ if (candidate.steps.length === 0 && !candidate.outputTransform) {
5896
+ return { valid: false, error: "Tool must have at least one step or an outputTransform" };
5897
+ }
5898
+ for (let i = 0; i < candidate.steps.length; i++) {
5899
+ const step = candidate.steps[i];
5900
+ const stepLabel = step?.id ? `Step ${i + 1} (${step.id})` : `Step ${i + 1}`;
5901
+ if (!step?.id) {
5902
+ return { valid: false, error: `Step ${i + 1}: missing 'id'` };
5903
+ }
5904
+ if (!step.config) {
5905
+ return { valid: false, error: `${stepLabel}: missing 'config'` };
5906
+ }
5907
+ if ((0, types_js_1.isTransformConfig)(step.config)) {
5908
+ if (!step.config.transformCode) {
5909
+ return {
5910
+ valid: false,
5911
+ error: `${stepLabel}: transform step missing 'transformCode'`
5912
+ };
5913
+ }
5914
+ continue;
5915
+ }
5916
+ if (!(0, types_js_1.isRequestConfig)(step.config)) {
5917
+ return {
5918
+ valid: false,
5919
+ error: `${stepLabel}: unknown step config type`
5920
+ };
5921
+ }
5922
+ if (typeof step.config.url !== "string" || step.config.url.trim().length === 0) {
5923
+ return { valid: false, error: `${stepLabel}: request step missing 'url'` };
5924
+ }
5925
+ }
5926
+ return { valid: true };
5927
+ }
5732
5928
  }
5733
5929
  });
5734
5930
 
@@ -9077,8 +9273,8 @@ var require_luxon = __commonJS({
9077
9273
  let current = null, currentFull = "", bracketed = false;
9078
9274
  const splits = [];
9079
9275
  for (let i = 0; i < fmt.length; i++) {
9080
- const c3 = fmt.charAt(i);
9081
- if (c3 === "'") {
9276
+ const c2 = fmt.charAt(i);
9277
+ if (c2 === "'") {
9082
9278
  if (currentFull.length > 0 || bracketed) {
9083
9279
  splits.push({
9084
9280
  literal: bracketed || /^\s+$/.test(currentFull),
@@ -9089,9 +9285,9 @@ var require_luxon = __commonJS({
9089
9285
  currentFull = "";
9090
9286
  bracketed = !bracketed;
9091
9287
  } else if (bracketed) {
9092
- currentFull += c3;
9093
- } else if (c3 === current) {
9094
- currentFull += c3;
9288
+ currentFull += c2;
9289
+ } else if (c2 === current) {
9290
+ currentFull += c2;
9095
9291
  } else {
9096
9292
  if (currentFull.length > 0) {
9097
9293
  splits.push({
@@ -9099,8 +9295,8 @@ var require_luxon = __commonJS({
9099
9295
  val: currentFull
9100
9296
  });
9101
9297
  }
9102
- currentFull = c3;
9103
- current = c3;
9298
+ currentFull = c2;
9299
+ current = c2;
9104
9300
  }
9105
9301
  }
9106
9302
  if (currentFull.length > 0) {
@@ -11782,7 +11978,7 @@ var require_luxon = __commonJS({
11782
11978
  return fixOffset(objToLocalTS(obj), offset2, zone);
11783
11979
  }
11784
11980
  function adjustTime(inst, dur) {
11785
- 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 = {
11981
+ 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 = {
11786
11982
  ...inst.c,
11787
11983
  year,
11788
11984
  month,
@@ -11797,7 +11993,7 @@ var require_luxon = __commonJS({
11797
11993
  minutes: dur.minutes,
11798
11994
  seconds: dur.seconds,
11799
11995
  milliseconds: dur.milliseconds
11800
- }).as("milliseconds"), localTS = objToLocalTS(c3);
11996
+ }).as("milliseconds"), localTS = objToLocalTS(c2);
11801
11997
  let [ts, o] = fixOffset(localTS, oPre, inst.zone);
11802
11998
  if (millisToAdd !== 0) {
11803
11999
  ts += millisToAdd;
@@ -11832,72 +12028,72 @@ var require_luxon = __commonJS({
11832
12028
  }
11833
12029
  function toISODate(o, extended, precision) {
11834
12030
  const longFormat = o.c.year > 9999 || o.c.year < 0;
11835
- let c3 = "";
11836
- if (longFormat && o.c.year >= 0) c3 += "+";
11837
- c3 += padStart(o.c.year, longFormat ? 6 : 4);
11838
- if (precision === "year") return c3;
12031
+ let c2 = "";
12032
+ if (longFormat && o.c.year >= 0) c2 += "+";
12033
+ c2 += padStart(o.c.year, longFormat ? 6 : 4);
12034
+ if (precision === "year") return c2;
11839
12035
  if (extended) {
11840
- c3 += "-";
11841
- c3 += padStart(o.c.month);
11842
- if (precision === "month") return c3;
11843
- c3 += "-";
12036
+ c2 += "-";
12037
+ c2 += padStart(o.c.month);
12038
+ if (precision === "month") return c2;
12039
+ c2 += "-";
11844
12040
  } else {
11845
- c3 += padStart(o.c.month);
11846
- if (precision === "month") return c3;
12041
+ c2 += padStart(o.c.month);
12042
+ if (precision === "month") return c2;
11847
12043
  }
11848
- c3 += padStart(o.c.day);
11849
- return c3;
12044
+ c2 += padStart(o.c.day);
12045
+ return c2;
11850
12046
  }
11851
12047
  function toISOTime(o, extended, suppressSeconds, suppressMilliseconds, includeOffset, extendedZone, precision) {
11852
- let showSeconds = !suppressSeconds || o.c.millisecond !== 0 || o.c.second !== 0, c3 = "";
12048
+ let showSeconds = !suppressSeconds || o.c.millisecond !== 0 || o.c.second !== 0, c2 = "";
11853
12049
  switch (precision) {
11854
12050
  case "day":
11855
12051
  case "month":
11856
12052
  case "year":
11857
12053
  break;
11858
12054
  default:
11859
- c3 += padStart(o.c.hour);
12055
+ c2 += padStart(o.c.hour);
11860
12056
  if (precision === "hour") break;
11861
12057
  if (extended) {
11862
- c3 += ":";
11863
- c3 += padStart(o.c.minute);
12058
+ c2 += ":";
12059
+ c2 += padStart(o.c.minute);
11864
12060
  if (precision === "minute") break;
11865
12061
  if (showSeconds) {
11866
- c3 += ":";
11867
- c3 += padStart(o.c.second);
12062
+ c2 += ":";
12063
+ c2 += padStart(o.c.second);
11868
12064
  }
11869
12065
  } else {
11870
- c3 += padStart(o.c.minute);
12066
+ c2 += padStart(o.c.minute);
11871
12067
  if (precision === "minute") break;
11872
12068
  if (showSeconds) {
11873
- c3 += padStart(o.c.second);
12069
+ c2 += padStart(o.c.second);
11874
12070
  }
11875
12071
  }
11876
12072
  if (precision === "second") break;
11877
12073
  if (showSeconds && (!suppressMilliseconds || o.c.millisecond !== 0)) {
11878
- c3 += ".";
11879
- c3 += padStart(o.c.millisecond, 3);
12074
+ c2 += ".";
12075
+ c2 += padStart(o.c.millisecond, 3);
11880
12076
  }
11881
12077
  }
11882
12078
  if (includeOffset) {
11883
12079
  if (o.isOffsetFixed && o.offset === 0 && !extendedZone) {
11884
- c3 += "Z";
12080
+ c2 += "Z";
11885
12081
  } else if (o.o < 0) {
11886
- c3 += "-";
11887
- c3 += padStart(Math.trunc(-o.o / 60));
11888
- c3 += ":";
11889
- c3 += padStart(Math.trunc(-o.o % 60));
12082
+ c2 += "-";
12083
+ c2 += padStart(Math.trunc(-o.o / 60));
12084
+ c2 += ":";
12085
+ c2 += padStart(Math.trunc(-o.o % 60));
11890
12086
  } else {
11891
- c3 += "+";
11892
- c3 += padStart(Math.trunc(o.o / 60));
11893
- c3 += ":";
11894
- c3 += padStart(Math.trunc(o.o % 60));
12087
+ c2 += "+";
12088
+ c2 += padStart(Math.trunc(o.o / 60));
12089
+ c2 += ":";
12090
+ c2 += padStart(Math.trunc(o.o % 60));
11895
12091
  }
11896
12092
  }
11897
12093
  if (extendedZone) {
11898
- c3 += "[" + o.zone.ianaName + "]";
12094
+ c2 += "[" + o.zone.ianaName + "]";
11899
12095
  }
11900
- return c3;
12096
+ return c2;
11901
12097
  }
11902
12098
  var defaultUnitValues = {
11903
12099
  month: 1,
@@ -12015,10 +12211,10 @@ var require_luxon = __commonJS({
12015
12211
  });
12016
12212
  }
12017
12213
  function diffRelative(start, end, opts) {
12018
- const round = isUndefined(opts.round) ? true : opts.round, rounding = isUndefined(opts.rounding) ? "trunc" : opts.rounding, format = (c3, unit) => {
12019
- c3 = roundTo(c3, round || opts.calendary ? 0 : 2, opts.calendary ? "round" : rounding);
12214
+ const round = isUndefined(opts.round) ? true : opts.round, rounding = isUndefined(opts.rounding) ? "trunc" : opts.rounding, format = (c2, unit) => {
12215
+ c2 = roundTo(c2, round || opts.calendary ? 0 : 2, opts.calendary ? "round" : rounding);
12020
12216
  const formatter = end.loc.clone(opts).relFormatter(opts);
12021
- return formatter.format(c3, unit);
12217
+ return formatter.format(c2, unit);
12022
12218
  }, differ = (unit) => {
12023
12219
  if (opts.calendary) {
12024
12220
  if (!end.hasSame(start, unit)) {
@@ -12059,16 +12255,16 @@ var require_luxon = __commonJS({
12059
12255
  const zone = config.zone || Settings.defaultZone;
12060
12256
  let invalid = config.invalid || (Number.isNaN(config.ts) ? new Invalid("invalid input") : null) || (!zone.isValid ? unsupportedZone(zone) : null);
12061
12257
  this.ts = isUndefined(config.ts) ? Settings.now() : config.ts;
12062
- let c3 = null, o = null;
12258
+ let c2 = null, o = null;
12063
12259
  if (!invalid) {
12064
12260
  const unchanged = config.old && config.old.ts === this.ts && config.old.zone.equals(zone);
12065
12261
  if (unchanged) {
12066
- [c3, o] = [config.old.c, config.old.o];
12262
+ [c2, o] = [config.old.c, config.old.o];
12067
12263
  } else {
12068
12264
  const ot = isNumber(config.o) && !config.old ? config.o : zone.offset(this.ts);
12069
- c3 = tsToObj(this.ts, ot);
12070
- invalid = Number.isNaN(c3.year) ? new Invalid("invalid input") : null;
12071
- c3 = invalid ? null : c3;
12265
+ c2 = tsToObj(this.ts, ot);
12266
+ invalid = Number.isNaN(c2.year) ? new Invalid("invalid input") : null;
12267
+ c2 = invalid ? null : c2;
12072
12268
  o = invalid ? null : ot;
12073
12269
  }
12074
12270
  }
@@ -12077,7 +12273,7 @@ var require_luxon = __commonJS({
12077
12273
  this.invalid = invalid;
12078
12274
  this.weekData = null;
12079
12275
  this.localWeekData = null;
12080
- this.c = c3;
12276
+ this.c = c2;
12081
12277
  this.o = o;
12082
12278
  this.isLuxonDateTime = true;
12083
12279
  }
@@ -12836,8 +13032,8 @@ var require_luxon = __commonJS({
12836
13032
  const ts1 = localTS - o1 * minuteMs;
12837
13033
  const ts2 = localTS - o2 * minuteMs;
12838
13034
  const c1 = tsToObj(ts1, o1);
12839
- const c22 = tsToObj(ts2, o2);
12840
- if (c1.hour === c22.hour && c1.minute === c22.minute && c1.second === c22.second && c1.millisecond === c22.millisecond) {
13035
+ const c2 = tsToObj(ts2, o2);
13036
+ if (c1.hour === c2.hour && c1.minute === c2.minute && c1.second === c2.second && c1.millisecond === c2.millisecond) {
12841
13037
  return [clone2(this, {
12842
13038
  ts: ts1
12843
13039
  }), clone2(this, {
@@ -13235,10 +13431,10 @@ var require_luxon = __commonJS({
13235
13431
  }
13236
13432
  precision = normalizeUnit(precision);
13237
13433
  const ext = format === "extended";
13238
- let c3 = toISODate(this, ext, precision);
13239
- if (orderedUnits.indexOf(precision) >= 3) c3 += "T";
13240
- c3 += toISOTime(this, ext, suppressSeconds, suppressMilliseconds, includeOffset, extendedZone, precision);
13241
- return c3;
13434
+ let c2 = toISODate(this, ext, precision);
13435
+ if (orderedUnits.indexOf(precision) >= 3) c2 += "T";
13436
+ c2 += toISOTime(this, ext, suppressSeconds, suppressMilliseconds, includeOffset, extendedZone, precision);
13437
+ return c2;
13242
13438
  }
13243
13439
  /**
13244
13440
  * Returns an ISO 8601-compliant string representation of this DateTime's date component
@@ -13297,8 +13493,8 @@ var require_luxon = __commonJS({
13297
13493
  return null;
13298
13494
  }
13299
13495
  precision = normalizeUnit(precision);
13300
- let c3 = includePrefix && orderedUnits.indexOf(precision) >= 3 ? "T" : "";
13301
- return c3 + toISOTime(this, format === "extended", suppressSeconds, suppressMilliseconds, includeOffset, extendedZone, precision);
13496
+ let c2 = includePrefix && orderedUnits.indexOf(precision) >= 3 ? "T" : "";
13497
+ return c2 + toISOTime(this, format === "extended", suppressSeconds, suppressMilliseconds, includeOffset, extendedZone, precision);
13302
13498
  }
13303
13499
  /**
13304
13500
  * Returns an RFC 2822-compatible string representation of this DateTime
@@ -17883,7 +18079,7 @@ attempted value: ${formattedValue}
17883
18079
  type: next.type,
17884
18080
  oneOf: next._whitelist.describe(),
17885
18081
  notOneOf: next._blacklist.describe(),
17886
- tests: next.tests.filter((n, idx, list) => list.findIndex((c3) => c3.OPTIONS.name === n.OPTIONS.name) === idx).map((fn) => {
18082
+ tests: next.tests.filter((n, idx, list) => list.findIndex((c2) => c2.OPTIONS.name === n.OPTIONS.name) === idx).map((fn) => {
17887
18083
  const params = fn.OPTIONS.params && options ? resolveParams(Object.assign({}, fn.OPTIONS.params), options) : fn.OPTIONS.params;
17888
18084
  return {
17889
18085
  name: fn.OPTIONS.name,
@@ -20164,6 +20360,8 @@ var require_utils = __commonJS({
20164
20360
  var getConnectionProtocol2 = (url) => {
20165
20361
  if (url.startsWith("postgres://") || url.startsWith("postgresql://"))
20166
20362
  return "postgres";
20363
+ if (url.startsWith("mssql://") || url.startsWith("sqlserver://"))
20364
+ return "mssql";
20167
20365
  if (url.startsWith("redis://") || url.startsWith("rediss://"))
20168
20366
  return "redis";
20169
20367
  if (url.startsWith("ftp://") || url.startsWith("ftps://") || url.startsWith("sftp://"))
@@ -21499,17 +21697,18 @@ var require_superglue_client = __commonJS({
21499
21697
  options: params.options,
21500
21698
  runId: params.runId
21501
21699
  }, params.traceId ? { "X-Trace-Id": params.traceId } : void 0);
21700
+ const success3 = response.status ? response.status === "success" : response.success ?? false;
21502
21701
  return {
21503
- success: response.success,
21702
+ success: success3,
21504
21703
  data: response.data,
21505
21704
  error: response.error,
21506
- tool: response.tool,
21705
+ tool: response.tool || params.tool,
21507
21706
  stepResults: response.stepResults?.map((sr) => ({
21508
21707
  stepId: sr.stepId,
21509
21708
  success: sr.success,
21510
21709
  data: sr.data,
21511
21710
  error: sr.error
21512
- }))
21711
+ })) || []
21513
21712
  };
21514
21713
  }
21515
21714
  async abortToolExecution(runId) {
@@ -21694,12 +21893,18 @@ var require_superglue_client = __commonJS({
21694
21893
  const response = await this.restRequest("GET", `/v1/tools?limit=${limit}&page=${page}${archiveParam}`);
21695
21894
  return { items: response.data, total: response.total };
21696
21895
  }
21896
+ async createWorkflow(id, input) {
21897
+ return this.restRequest("POST", "/v1/tools", { ...input, id });
21898
+ }
21899
+ async updateWorkflow(id, input) {
21900
+ return this.restRequest("PUT", `/v1/tools/${encodeURIComponent(id)}`, input);
21901
+ }
21697
21902
  async upsertWorkflow(id, input) {
21698
21903
  const existing = await this.getWorkflow(id);
21699
21904
  if (existing) {
21700
- return this.restRequest("PUT", `/v1/tools/${encodeURIComponent(id)}`, input);
21905
+ return this.updateWorkflow(id, input);
21701
21906
  } else {
21702
- return this.restRequest("POST", "/v1/tools", { id, ...input });
21907
+ return this.createWorkflow(id, input);
21703
21908
  }
21704
21909
  }
21705
21910
  async deleteWorkflow(id) {
@@ -22014,14 +22219,14 @@ var package_default = {
22014
22219
  "LICENSE"
22015
22220
  ],
22016
22221
  dependencies: {
22017
- commander: "^13.0.0",
22018
- "fast-json-patch": "^3.1.1"
22222
+ commander: "15.0.0-0",
22223
+ "fast-json-patch": "3.1.1"
22019
22224
  },
22020
22225
  devDependencies: {
22021
22226
  "@superglue/shared": "file:../shared",
22022
- "@types/node": "^20.0.0",
22023
- tsup: "^8.0.0",
22024
- typescript: "^5.0.0"
22227
+ "@types/node": "25.5.0",
22228
+ tsup: "8.5.1",
22229
+ typescript: "5.8.3"
22025
22230
  },
22026
22231
  scripts: {
22027
22232
  build: "tsup && (cp -r skills dist/ 2>/dev/null || true)",
@@ -23432,13 +23637,18 @@ function registerFindCommand2(parent, getContext2) {
23432
23637
  const mode = opts.mode === "dev" || opts.mode === "prod" ? opts.mode : "all";
23433
23638
  const { items } = await client.listSystems(100, 1, { mode });
23434
23639
  table(
23435
- items.map((s) => ({
23436
- id: s.id,
23437
- name: s.name || "",
23438
- env: s.environment || "prod",
23439
- url: (s.url || "").slice(0, 50)
23440
- })),
23441
- ["id", "name", "env", "url"]
23640
+ items.map((s) => {
23641
+ const credentialKeys = Object.keys(s.credentials || {});
23642
+ const credPlaceholders = credentialKeys.map((k) => `<<${s.id}_${k}>>`).join(", ");
23643
+ return {
23644
+ id: s.id,
23645
+ name: s.name || "",
23646
+ env: s.environment || "prod",
23647
+ url: (s.url || "").slice(0, 40),
23648
+ credentials: credPlaceholders || "(none)"
23649
+ };
23650
+ }),
23651
+ ["id", "name", "env", "url", "credentials"]
23442
23652
  );
23443
23653
  } catch (err) {
23444
23654
  error(err.message);
@@ -23471,7 +23681,7 @@ function registerFindCommand2(parent, getContext2) {
23471
23681
  if (rawQuery === "*") {
23472
23682
  output({
23473
23683
  success: true,
23474
- systems: items.map((s) => ({ id: s.id, name: s.name, url: s.url }))
23684
+ systems: items.map((s) => filterSystemFields(s))
23475
23685
  });
23476
23686
  return;
23477
23687
  }
@@ -23482,7 +23692,7 @@ function registerFindCommand2(parent, getContext2) {
23482
23692
  });
23483
23693
  output({
23484
23694
  success: true,
23485
- systems: filtered.map((s) => ({ id: s.id, name: s.name, url: s.url }))
23695
+ systems: filtered.map((s) => filterSystemFields(s))
23486
23696
  });
23487
23697
  } catch (err) {
23488
23698
  error(err.message);
@@ -23505,6 +23715,46 @@ function registerCallCommand(parent, getContext2) {
23505
23715
  []
23506
23716
  ).addOption(
23507
23717
  new import_commander5.Option("--env <environment>", "Environment: dev or prod").choices(["dev", "prod"])
23718
+ ).addHelpText(
23719
+ "after",
23720
+ `
23721
+ ${c.bold}Discovering Credential Placeholders:${c.reset}
23722
+ Use 'sg system find <system-id>' to see available credential placeholders:
23723
+
23724
+ ${c.dim}$${c.reset} sg system find my_postgres
23725
+ ${c.green}\u2192 credentialPlaceholders:${c.reset} ["<<my_postgres_username>>", "<<my_postgres_password>>"]
23726
+
23727
+ Or use 'sg system list' to see credentials for all systems at once.
23728
+
23729
+ ${c.bold}Examples:${c.reset}
23730
+ ${c.dim}# HTTP API with API key${c.reset}
23731
+ sg system call --system-id stripe \\
23732
+ --url "https://api.stripe.com/v1/customers" \\
23733
+ --headers '{"Authorization": "Bearer <<stripe_api_key>>"}'
23734
+
23735
+ ${c.dim}# PostgreSQL database query${c.reset}
23736
+ sg system call --system-id my_postgres \\
23737
+ --url "postgres://<<my_postgres_username>>:<<my_postgres_password>>@localhost:5432/mydb" \\
23738
+ --body '{"query": "SELECT * FROM users WHERE id = $1", "params": [123]}'
23739
+
23740
+ ${c.dim}# Microsoft SQL Server with parameterized query${c.reset}
23741
+ sg system call --system-id azure_sql \\
23742
+ --url "mssql://<<azure_sql_username>>:<<azure_sql_password>>@server.database.windows.net:1433/mydb" \\
23743
+ --body '{"query": "SELECT * FROM orders WHERE status = @param1", "params": ["pending"]}'
23744
+
23745
+ ${c.dim}# Redis command${c.reset}
23746
+ sg system call --system-id my_redis \\
23747
+ --url "redis://<<my_redis_password>>@localhost:6379" \\
23748
+ --body '{"command": "GET", "args": ["user:123"]}'
23749
+
23750
+ ${c.dim}# SFTP list files${c.reset}
23751
+ sg system call --system-id sftp_server \\
23752
+ --url "sftp://<<sftp_server_username>>:<<sftp_server_password>>@files.example.com:22" \\
23753
+ --body '{"operation": "list", "path": "/uploads"}'
23754
+
23755
+ ${c.bold}Supported Protocols:${c.reset}
23756
+ HTTP/HTTPS, PostgreSQL, MSSQL/SQL Server, Redis, SFTP/FTP/FTPS, SMB
23757
+ `
23508
23758
  ).action(async (opts) => {
23509
23759
  const { client } = getContext2();
23510
23760
  const method = opts.method || "GET";