archal 0.9.18 → 0.9.19

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.
@@ -133,11 +133,10 @@ function trimEnv(name) {
133
133
  }
134
134
  function parsePositiveInteger(rawValue, fallback, minimum = 1) {
135
135
  if (!rawValue) return fallback;
136
- const parsed = Number.parseInt(rawValue, 10);
137
- if (Number.isNaN(parsed) || parsed < minimum) {
138
- return fallback;
139
- }
140
- return parsed;
136
+ const normalized = rawValue.trim();
137
+ if (!/^[1-9]\d*$/.test(normalized)) return fallback;
138
+ const parsed = Number(normalized);
139
+ return Number.isSafeInteger(parsed) && parsed >= minimum ? parsed : fallback;
141
140
  }
142
141
  function normalizeApiBaseUrl(value) {
143
142
  if (!value) return null;
@@ -1115,8 +1114,9 @@ var GENERATED_TWIN_CATALOG = [
1115
1114
  icon: "AP",
1116
1115
  name: "Apify",
1117
1116
  description: "Actors, runs, datasets, key-value stores, and request queues.",
1118
- toolCount: 45,
1119
- transport: "rest"
1117
+ toolCount: 43,
1118
+ transport: "rest",
1119
+ opsCoverage: null
1120
1120
  },
1121
1121
  {
1122
1122
  id: "discord",
@@ -1124,7 +1124,17 @@ var GENERATED_TWIN_CATALOG = [
1124
1124
  name: "Discord",
1125
1125
  description: "Guilds, channels, messages, webhooks, threads, commands, and interaction responses.",
1126
1126
  toolCount: 67,
1127
- transport: "both"
1127
+ transport: "both",
1128
+ opsCoverage: 14
1129
+ },
1130
+ {
1131
+ id: "firecrawl",
1132
+ icon: "FC",
1133
+ name: "Firecrawl",
1134
+ description: "Scraping, crawling, mapping, search, and extraction.",
1135
+ toolCount: 6,
1136
+ transport: "rest",
1137
+ opsCoverage: 77
1128
1138
  },
1129
1139
  {
1130
1140
  id: "github",
@@ -1132,7 +1142,8 @@ var GENERATED_TWIN_CATALOG = [
1132
1142
  name: "GitHub",
1133
1143
  description: "Repos, issues, pull requests, branches, and commits.",
1134
1144
  toolCount: 26,
1135
- transport: "both"
1145
+ transport: "both",
1146
+ opsCoverage: 96
1136
1147
  },
1137
1148
  {
1138
1149
  id: "google-workspace",
@@ -1140,7 +1151,17 @@ var GENERATED_TWIN_CATALOG = [
1140
1151
  name: "Google Workspace",
1141
1152
  description: "Gmail, Calendar, Drive, Sheets, and Contacts.",
1142
1153
  toolCount: 249,
1143
- transport: "both"
1154
+ transport: "both",
1155
+ opsCoverage: 64
1156
+ },
1157
+ {
1158
+ id: "hubspot",
1159
+ icon: "HS",
1160
+ name: "HubSpot",
1161
+ description: "CRM contacts, companies, deals, tickets, and engagements.",
1162
+ toolCount: 45,
1163
+ transport: "rest",
1164
+ opsCoverage: 10
1144
1165
  },
1145
1166
  {
1146
1167
  id: "jira",
@@ -1148,7 +1169,8 @@ var GENERATED_TWIN_CATALOG = [
1148
1169
  name: "Jira",
1149
1170
  description: "Issues, projects, boards, sprints, and versions.",
1150
1171
  toolCount: 49,
1151
- transport: "both"
1172
+ transport: "both",
1173
+ opsCoverage: 80
1152
1174
  },
1153
1175
  {
1154
1176
  id: "linear",
@@ -1156,7 +1178,8 @@ var GENERATED_TWIN_CATALOG = [
1156
1178
  name: "Linear",
1157
1179
  description: "Issues, projects, teams, cycles, and workflows.",
1158
1180
  toolCount: 42,
1159
- transport: "both"
1181
+ transport: "both",
1182
+ opsCoverage: 98
1160
1183
  },
1161
1184
  {
1162
1185
  id: "ramp",
@@ -1164,7 +1187,17 @@ var GENERATED_TWIN_CATALOG = [
1164
1187
  name: "Ramp",
1165
1188
  description: "Cards, funds, expenses, reimbursements, bills, and travel.",
1166
1189
  toolCount: 46,
1167
- transport: "mcp"
1190
+ transport: "mcp",
1191
+ opsCoverage: null
1192
+ },
1193
+ {
1194
+ id: "sendgrid",
1195
+ icon: "SG",
1196
+ name: "SendGrid",
1197
+ description: "Mail send, contacts, lists, templates, and stats.",
1198
+ toolCount: 28,
1199
+ transport: "rest",
1200
+ opsCoverage: 100
1168
1201
  },
1169
1202
  {
1170
1203
  id: "slack",
@@ -1172,7 +1205,8 @@ var GENERATED_TWIN_CATALOG = [
1172
1205
  name: "Slack",
1173
1206
  description: "Channels, messages, threads, users, and reactions.",
1174
1207
  toolCount: 8,
1175
- transport: "both"
1208
+ transport: "both",
1209
+ opsCoverage: 100
1176
1210
  },
1177
1211
  {
1178
1212
  id: "stripe",
@@ -1180,7 +1214,8 @@ var GENERATED_TWIN_CATALOG = [
1180
1214
  name: "Stripe",
1181
1215
  description: "Customers, payments, subscriptions, invoices, and refunds.",
1182
1216
  toolCount: 28,
1183
- transport: "both"
1217
+ transport: "both",
1218
+ opsCoverage: null
1184
1219
  },
1185
1220
  {
1186
1221
  id: "supabase",
@@ -1188,7 +1223,8 @@ var GENERATED_TWIN_CATALOG = [
1188
1223
  name: "Supabase",
1189
1224
  description: "SQL, migrations, logs, branches, and project metadata.",
1190
1225
  toolCount: 29,
1191
- transport: "both"
1226
+ transport: "both",
1227
+ opsCoverage: 100
1192
1228
  },
1193
1229
  {
1194
1230
  id: "tavily",
@@ -1196,7 +1232,35 @@ var GENERATED_TWIN_CATALOG = [
1196
1232
  name: "Tavily",
1197
1233
  description: "Search, extract, crawl, map, research, usage, and API key operations.",
1198
1234
  toolCount: 11,
1199
- transport: "rest"
1235
+ transport: "rest",
1236
+ opsCoverage: 100
1237
+ },
1238
+ {
1239
+ id: "telegram",
1240
+ icon: "TG",
1241
+ name: "Telegram",
1242
+ description: "Bot messages, chats, updates, and webhooks.",
1243
+ toolCount: 32,
1244
+ transport: "both",
1245
+ opsCoverage: null
1246
+ },
1247
+ {
1248
+ id: "twilio",
1249
+ icon: "TW",
1250
+ name: "Twilio",
1251
+ description: "Messages, calls, phone numbers, and verifications.",
1252
+ toolCount: 35,
1253
+ transport: "rest",
1254
+ opsCoverage: 92
1255
+ },
1256
+ {
1257
+ id: "unipile",
1258
+ icon: "UP",
1259
+ name: "Unipile",
1260
+ description: "LinkedIn and email messaging, accounts, and chats.",
1261
+ toolCount: 24,
1262
+ transport: "rest",
1263
+ opsCoverage: 100
1200
1264
  }
1201
1265
  ];
1202
1266
  var GENERATED_STARTABLE_TWIN_IDS = [
@@ -1919,7 +1983,7 @@ function decodeConfig(encoded) {
1919
1983
 
1920
1984
  // ../runtime/src/seed-loader.ts
1921
1985
  import { existsSync as existsSync4, mkdirSync as mkdirSync4, rmSync, writeFileSync as writeFileSync4 } from "fs";
1922
- import { dirname as dirname4 } from "path";
1986
+ import { dirname as dirname5 } from "path";
1923
1987
 
1924
1988
  // ../seedgen/dist/chunk-5G7HFPWB.js
1925
1989
  var seedCodegenTestOverrides = null;
@@ -1964,12 +2028,14 @@ var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__
1964
2028
  mod
1965
2029
  ));
1966
2030
 
1967
- // ../seedgen/dist/chunk-E7QP3UBL.js
2031
+ // ../seedgen/dist/chunk-OUL4HJ5I.js
1968
2032
  import { Readable } from "stream";
1969
2033
  import crypto2 from "crypto";
1970
2034
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
1971
2035
  import { homedir as homedir2 } from "os";
1972
- import { dirname as dirname3, resolve as resolve4 } from "path";
2036
+ import { dirname as dirname3, relative as relative2, resolve as resolve3 } from "path";
2037
+ import { homedir as homedir3 } from "os";
2038
+ import { dirname as dirname2, resolve as resolve2 } from "path";
1973
2039
  var require_code = __commonJS2({
1974
2040
  "../../node_modules/.pnpm/ajv@8.18.0/node_modules/ajv/dist/compile/codegen/code.js"(exports) {
1975
2041
  "use strict";
@@ -4880,7 +4946,7 @@ var require_compile = __commonJS2({
4880
4946
  const schOrFunc = root.refs[ref2];
4881
4947
  if (schOrFunc)
4882
4948
  return schOrFunc;
4883
- let _sch = resolve5.call(this, root, ref2);
4949
+ let _sch = resolve6.call(this, root, ref2);
4884
4950
  if (_sch === void 0) {
4885
4951
  const schema = (_a2 = root.localRefs) === null || _a2 === void 0 ? void 0 : _a2[ref2];
4886
4952
  const { schemaId } = this.opts;
@@ -4907,7 +4973,7 @@ var require_compile = __commonJS2({
4907
4973
  function sameSchemaEnv(s1, s2) {
4908
4974
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
4909
4975
  }
4910
- function resolve5(root, ref2) {
4976
+ function resolve6(root, ref2) {
4911
4977
  let sch;
4912
4978
  while (typeof (sch = this.refs[ref2]) == "string")
4913
4979
  ref2 = sch;
@@ -5474,55 +5540,55 @@ var require_fast_uri = __commonJS2({
5474
5540
  }
5475
5541
  return uri;
5476
5542
  }
5477
- function resolve5(baseURI, relativeURI, options) {
5543
+ function resolve6(baseURI, relativeURI, options) {
5478
5544
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
5479
5545
  const resolved = resolveComponent(parse32(baseURI, schemelessOptions), parse32(relativeURI, schemelessOptions), schemelessOptions, true);
5480
5546
  schemelessOptions.skipEscape = true;
5481
5547
  return serialize(resolved, schemelessOptions);
5482
5548
  }
5483
- function resolveComponent(base, relative2, options, skipNormalization) {
5549
+ function resolveComponent(base, relative3, options, skipNormalization) {
5484
5550
  const target = {};
5485
5551
  if (!skipNormalization) {
5486
5552
  base = parse32(serialize(base, options), options);
5487
- relative2 = parse32(serialize(relative2, options), options);
5553
+ relative3 = parse32(serialize(relative3, options), options);
5488
5554
  }
5489
5555
  options = options || {};
5490
- if (!options.tolerant && relative2.scheme) {
5491
- target.scheme = relative2.scheme;
5492
- target.userinfo = relative2.userinfo;
5493
- target.host = relative2.host;
5494
- target.port = relative2.port;
5495
- target.path = removeDotSegments(relative2.path || "");
5496
- target.query = relative2.query;
5556
+ if (!options.tolerant && relative3.scheme) {
5557
+ target.scheme = relative3.scheme;
5558
+ target.userinfo = relative3.userinfo;
5559
+ target.host = relative3.host;
5560
+ target.port = relative3.port;
5561
+ target.path = removeDotSegments(relative3.path || "");
5562
+ target.query = relative3.query;
5497
5563
  } else {
5498
- if (relative2.userinfo !== void 0 || relative2.host !== void 0 || relative2.port !== void 0) {
5499
- target.userinfo = relative2.userinfo;
5500
- target.host = relative2.host;
5501
- target.port = relative2.port;
5502
- target.path = removeDotSegments(relative2.path || "");
5503
- target.query = relative2.query;
5564
+ if (relative3.userinfo !== void 0 || relative3.host !== void 0 || relative3.port !== void 0) {
5565
+ target.userinfo = relative3.userinfo;
5566
+ target.host = relative3.host;
5567
+ target.port = relative3.port;
5568
+ target.path = removeDotSegments(relative3.path || "");
5569
+ target.query = relative3.query;
5504
5570
  } else {
5505
- if (!relative2.path) {
5571
+ if (!relative3.path) {
5506
5572
  target.path = base.path;
5507
- if (relative2.query !== void 0) {
5508
- target.query = relative2.query;
5573
+ if (relative3.query !== void 0) {
5574
+ target.query = relative3.query;
5509
5575
  } else {
5510
5576
  target.query = base.query;
5511
5577
  }
5512
5578
  } else {
5513
- if (relative2.path[0] === "/") {
5514
- target.path = removeDotSegments(relative2.path);
5579
+ if (relative3.path[0] === "/") {
5580
+ target.path = removeDotSegments(relative3.path);
5515
5581
  } else {
5516
5582
  if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
5517
- target.path = "/" + relative2.path;
5583
+ target.path = "/" + relative3.path;
5518
5584
  } else if (!base.path) {
5519
- target.path = relative2.path;
5585
+ target.path = relative3.path;
5520
5586
  } else {
5521
- target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative2.path;
5587
+ target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative3.path;
5522
5588
  }
5523
5589
  target.path = removeDotSegments(target.path);
5524
5590
  }
5525
- target.query = relative2.query;
5591
+ target.query = relative3.query;
5526
5592
  }
5527
5593
  target.userinfo = base.userinfo;
5528
5594
  target.host = base.host;
@@ -5530,7 +5596,7 @@ var require_fast_uri = __commonJS2({
5530
5596
  }
5531
5597
  target.scheme = base.scheme;
5532
5598
  }
5533
- target.fragment = relative2.fragment;
5599
+ target.fragment = relative3.fragment;
5534
5600
  return target;
5535
5601
  }
5536
5602
  function equal(uriA, uriB, options) {
@@ -5701,7 +5767,7 @@ var require_fast_uri = __commonJS2({
5701
5767
  var fastUri = {
5702
5768
  SCHEMES,
5703
5769
  normalize,
5704
- resolve: resolve5,
5770
+ resolve: resolve6,
5705
5771
  resolveComponent,
5706
5772
  equal,
5707
5773
  serialize,
@@ -27780,6 +27846,62 @@ var toolSearchInputSchema = external_exports3.object({
27780
27846
  /** Max results. Defaults to 10; capped at 100. */
27781
27847
  limit: external_exports3.number().int().positive().max(TOOL_SEARCH_MAX_LIMIT).optional()
27782
27848
  });
27849
+ var RecordingManifestEntrySchema = external_exports3.object({
27850
+ filename: external_exports3.string(),
27851
+ sha256: external_exports3.string().regex(/^[0-9a-f]{64}$/, "sha256 must be 64 lowercase hex chars"),
27852
+ size: external_exports3.number().optional(),
27853
+ sizeBytes: external_exports3.number().optional(),
27854
+ uploadedAt: external_exports3.string().optional(),
27855
+ // Optional symbolic tags that map fixture-oracle / replay lookups onto this
27856
+ // recording. Lets twins keep tag→file resolution inside the manifest itself
27857
+ // rather than depending on a separate provenance.json (which is excluded
27858
+ // from the in-tree fixture allowlist for graduated twins). Codex P2 on
27859
+ // tavily #3603 — fixture-oracle previously required provenance.json to
27860
+ // resolve `rest-profile:tavily:tavily_search_basic` → filename.
27861
+ tags: external_exports3.array(external_exports3.string()).optional()
27862
+ }).loose();
27863
+ var RecordingManifestSchema = external_exports3.object({
27864
+ service: external_exports3.string().min(1),
27865
+ version: external_exports3.number().int(),
27866
+ container: external_exports3.string().min(1),
27867
+ baseUrl: external_exports3.string().optional(),
27868
+ entries: external_exports3.array(RecordingManifestEntrySchema)
27869
+ }).loose();
27870
+ var DEFAULT_BASE_URL = process.env["ARCHAL_FIXTURE_BASE_URL"] ?? "https://archalforge8f96908966.blob.core.windows.net/archal-fixture-artifacts?sv=2023-11-03&spr=https&se=2031-05-10T00%3A00%3A00Z&sr=c&sp=rl&sig=r3%2FC3EwzilSHls8z3Pn5ZR%2BkinwQw1C6%2BDKObIZSIu0%3D";
27871
+ var DEFAULT_CACHE_ROOT = process.env["ARCHAL_FIXTURE_CACHE_ROOT"] ?? resolve2(homedir3(), ".archal", "forge", "recordings-cache");
27872
+ function warnIfSasExpiresSoon(baseUrl) {
27873
+ if (process.env["ARCHAL_FIXTURE_SAS_WARN"] === "0") return;
27874
+ const queryIdx = baseUrl.indexOf("?");
27875
+ if (queryIdx < 0) return;
27876
+ const query = baseUrl.slice(queryIdx + 1);
27877
+ const seParam = query.split("&").find((p) => p.startsWith("se="));
27878
+ if (!seParam) return;
27879
+ const seValue = decodeURIComponent(seParam.slice(3));
27880
+ const expiresAt = Date.parse(seValue);
27881
+ if (Number.isNaN(expiresAt)) return;
27882
+ const now = Date.now();
27883
+ const daysRemaining = Math.floor((expiresAt - now) / (1e3 * 60 * 60 * 24));
27884
+ if (daysRemaining < 365) {
27885
+ console.warn(
27886
+ `[recording-fetcher] SAS token in ARCHAL_FIXTURE_BASE_URL expires in ${daysRemaining}d (${seValue}). Rotate via scripts/rotate-fixture-sas.mjs before expiry.`
27887
+ );
27888
+ }
27889
+ }
27890
+ warnIfSasExpiresSoon(DEFAULT_BASE_URL);
27891
+ var DEFAULT_CACHE_ROOT2 = process.env["ARCHAL_LEGACY_ASSET_CACHE_ROOT"] ?? resolve3(homedir2(), ".archal", "forge", "legacy-assets-cache");
27892
+ var LegacyAssetEntrySchema = external_exports3.object({
27893
+ relativePath: external_exports3.string().min(1),
27894
+ sha256: external_exports3.string().regex(/^[0-9a-f]{64}$/, "sha256 must be 64 lowercase hex chars"),
27895
+ sizeBytes: external_exports3.number().optional(),
27896
+ uploadedAt: external_exports3.string().optional()
27897
+ }).loose();
27898
+ var LegacyAssetManifestSchema = external_exports3.object({
27899
+ service: external_exports3.string().min(1),
27900
+ version: external_exports3.number().int(),
27901
+ container: external_exports3.string().min(1),
27902
+ layout: external_exports3.string().optional(),
27903
+ entries: external_exports3.array(LegacyAssetEntrySchema)
27904
+ }).loose();
27783
27905
  var manifest_default = [
27784
27906
  {
27785
27907
  name: "apify",
@@ -27828,6 +27950,12 @@ var manifest_default = [
27828
27950
  package: "@archal/twin-firecrawl",
27829
27951
  path: "twins/firecrawl",
27830
27952
  stage: "internal",
27953
+ display: {
27954
+ icon: "FC",
27955
+ name: "Firecrawl",
27956
+ description: "Scraping, crawling, mapping, search, and extraction.",
27957
+ toolCount: 6
27958
+ },
27831
27959
  transport: "rest",
27832
27960
  hostedRuntime: { enabled: true, requiresDist: true, requiresEmptySeed: true },
27833
27961
  cli: { bundleAssets: false, bundleToolSnapshot: false },
@@ -27895,6 +28023,12 @@ var manifest_default = [
27895
28023
  package: "@archal/twin-hubspot",
27896
28024
  path: "twins/hubspot",
27897
28025
  stage: "internal",
28026
+ display: {
28027
+ icon: "HS",
28028
+ name: "HubSpot",
28029
+ description: "CRM contacts, companies, deals, tickets, and engagements.",
28030
+ toolCount: 45
28031
+ },
27898
28032
  transport: "rest",
27899
28033
  hostedRuntime: { enabled: true, requiresDist: true, requiresEmptySeed: true },
27900
28034
  cli: { bundleAssets: false, bundleToolSnapshot: false },
@@ -27971,6 +28105,12 @@ var manifest_default = [
27971
28105
  package: "@archal/twin-sendgrid",
27972
28106
  path: "twins/sendgrid",
27973
28107
  stage: "internal",
28108
+ display: {
28109
+ icon: "SG",
28110
+ name: "SendGrid",
28111
+ description: "Mail send, contacts, lists, templates, and stats.",
28112
+ toolCount: 28
28113
+ },
27974
28114
  transport: "rest",
27975
28115
  hostedRuntime: { enabled: true, requiresDist: true, requiresEmptySeed: true },
27976
28116
  cli: { bundleAssets: false, bundleToolSnapshot: false },
@@ -28067,6 +28207,12 @@ var manifest_default = [
28067
28207
  package: "@archal/twin-telegram",
28068
28208
  path: "twins/telegram",
28069
28209
  stage: "internal",
28210
+ display: {
28211
+ icon: "TG",
28212
+ name: "Telegram",
28213
+ description: "Bot messages, chats, updates, and webhooks.",
28214
+ toolCount: 32
28215
+ },
28070
28216
  transport: "both",
28071
28217
  hostedRuntime: { enabled: true, requiresDist: true, requiresEmptySeed: true },
28072
28218
  cli: { bundleAssets: false, bundleToolSnapshot: false },
@@ -28079,6 +28225,12 @@ var manifest_default = [
28079
28225
  package: "@archal/twin-twilio",
28080
28226
  path: "twins/twilio",
28081
28227
  stage: "internal",
28228
+ display: {
28229
+ icon: "TW",
28230
+ name: "Twilio",
28231
+ description: "Messages, calls, phone numbers, and verifications.",
28232
+ toolCount: 35
28233
+ },
28082
28234
  transport: "rest",
28083
28235
  hostedRuntime: { enabled: true, requiresDist: true, requiresEmptySeed: true },
28084
28236
  cli: { bundleAssets: false, bundleToolSnapshot: false },
@@ -28091,6 +28243,12 @@ var manifest_default = [
28091
28243
  package: "@archal/twin-unipile",
28092
28244
  path: "twins/unipile",
28093
28245
  stage: "internal",
28246
+ display: {
28247
+ icon: "UP",
28248
+ name: "Unipile",
28249
+ description: "LinkedIn and email messaging, accounts, and chats.",
28250
+ toolCount: 24
28251
+ },
28094
28252
  transport: "rest",
28095
28253
  hostedRuntime: { enabled: true, requiresDist: true, requiresEmptySeed: true },
28096
28254
  cli: { bundleAssets: false, bundleToolSnapshot: false },
@@ -28235,48 +28393,6 @@ var SCENARIO_RISK_RULES = [
28235
28393
  var SCENARIO_RISK_TAXONOMY = SCENARIO_RISK_RULES.map(
28236
28394
  ({ id, label, description }) => ({ id, label, description })
28237
28395
  );
28238
- var RecordingManifestEntrySchema = external_exports3.object({
28239
- filename: external_exports3.string(),
28240
- sha256: external_exports3.string().regex(/^[0-9a-f]{64}$/, "sha256 must be 64 lowercase hex chars"),
28241
- size: external_exports3.number().optional(),
28242
- sizeBytes: external_exports3.number().optional(),
28243
- uploadedAt: external_exports3.string().optional(),
28244
- // Optional symbolic tags that map fixture-oracle / replay lookups onto this
28245
- // recording. Lets twins keep tag→file resolution inside the manifest itself
28246
- // rather than depending on a separate provenance.json (which is excluded
28247
- // from the in-tree fixture allowlist for graduated twins). Codex P2 on
28248
- // tavily #3603 — fixture-oracle previously required provenance.json to
28249
- // resolve `rest-profile:tavily:tavily_search_basic` → filename.
28250
- tags: external_exports3.array(external_exports3.string()).optional()
28251
- }).loose();
28252
- var RecordingManifestSchema = external_exports3.object({
28253
- service: external_exports3.string().min(1),
28254
- version: external_exports3.number().int(),
28255
- container: external_exports3.string().min(1),
28256
- baseUrl: external_exports3.string().optional(),
28257
- entries: external_exports3.array(RecordingManifestEntrySchema)
28258
- }).loose();
28259
- var DEFAULT_BASE_URL = process.env["ARCHAL_FIXTURE_BASE_URL"] ?? "https://archalforge8f96908966.blob.core.windows.net/archal-fixture-artifacts?sv=2023-11-03&spr=https&se=2031-05-10T00%3A00%3A00Z&sr=c&sp=rl&sig=r3%2FC3EwzilSHls8z3Pn5ZR%2BkinwQw1C6%2BDKObIZSIu0%3D";
28260
- var DEFAULT_CACHE_ROOT = process.env["ARCHAL_FIXTURE_CACHE_ROOT"] ?? resolve4(homedir2(), ".archal", "forge", "recordings-cache");
28261
- function warnIfSasExpiresSoon(baseUrl) {
28262
- if (process.env["ARCHAL_FIXTURE_SAS_WARN"] === "0") return;
28263
- const queryIdx = baseUrl.indexOf("?");
28264
- if (queryIdx < 0) return;
28265
- const query = baseUrl.slice(queryIdx + 1);
28266
- const seParam = query.split("&").find((p) => p.startsWith("se="));
28267
- if (!seParam) return;
28268
- const seValue = decodeURIComponent(seParam.slice(3));
28269
- const expiresAt = Date.parse(seValue);
28270
- if (Number.isNaN(expiresAt)) return;
28271
- const now = Date.now();
28272
- const daysRemaining = Math.floor((expiresAt - now) / (1e3 * 60 * 60 * 24));
28273
- if (daysRemaining < 365) {
28274
- console.warn(
28275
- `[recording-fetcher] SAS token in ARCHAL_FIXTURE_BASE_URL expires in ${daysRemaining}d (${seValue}). Rotate via scripts/rotate-fixture-sas.mjs before expiry.`
28276
- );
28277
- }
28278
- }
28279
- warnIfSasExpiresSoon(DEFAULT_BASE_URL);
28280
28396
 
28281
28397
  // ../../node_modules/.pnpm/acorn@8.16.0/node_modules/acorn/dist/acorn.mjs
28282
28398
  var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 7, 9, 32, 4, 318, 1, 78, 5, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 68, 8, 2, 0, 3, 0, 2, 3, 2, 4, 2, 0, 15, 1, 83, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 7, 19, 58, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 199, 7, 137, 9, 54, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 55, 9, 266, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 10, 5350, 0, 7, 14, 11465, 27, 2343, 9, 87, 9, 39, 4, 60, 6, 26, 9, 535, 9, 470, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4178, 9, 519, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 245, 1, 2, 9, 233, 0, 3, 0, 8, 1, 6, 0, 475, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];
@@ -35197,12 +35313,12 @@ function checkStaticSafety(code) {
35197
35313
  return { safe: true, reason: "" };
35198
35314
  }
35199
35315
 
35200
- // ../seedgen/dist/chunk-XI7HKUUF.js
35316
+ // ../seedgen/dist/chunk-CIYCQV32.js
35201
35317
  import { spawnSync as spawnSync2 } from "child_process";
35202
35318
  import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, createHash as createHash2, randomBytes as randomBytes2 } from "crypto";
35203
35319
  import { chmodSync as chmodSync2, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "fs";
35204
- import { homedir as homedir3, tmpdir as tmpdir2 } from "os";
35205
- import { dirname as dirname2, join as join3 } from "path";
35320
+ import { homedir as homedir4, tmpdir as tmpdir2 } from "os";
35321
+ import { dirname as dirname4, join as join3 } from "path";
35206
35322
  import { isIP as isIP2 } from "net";
35207
35323
  import { fork } from "child_process";
35208
35324
  import { existsSync as existsSync22 } from "fs";
@@ -35252,7 +35368,7 @@ function isRunningUnderTests2() {
35252
35368
  return process.env["VITEST"] === "true" || process.env["VITEST_WORKER_ID"] !== void 0 || process.env["JEST_WORKER_ID"] !== void 0 || process.env["NODE_TEST_CONTEXT"] !== void 0;
35253
35369
  }
35254
35370
  function getRealArchalDir2() {
35255
- return join3(homedir3(), ARCHAL_DIR_NAME2);
35371
+ return join3(homedir4(), ARCHAL_DIR_NAME2);
35256
35372
  }
35257
35373
  function normalizeSandboxId2(raw) {
35258
35374
  const trimmed = raw.trim();
@@ -35498,7 +35614,7 @@ function resolveStoredRefreshToken2(parsed, dir = getArchalDir2()) {
35498
35614
  return { refreshToken: "", source: "none" };
35499
35615
  }
35500
35616
  function buildStoredCredentials2(parsed, path2, warn22, options) {
35501
- const dir = dirname2(path2);
35617
+ const dir = dirname4(path2);
35502
35618
  const { token, source: tokenSource } = resolveStoredToken2(parsed, dir);
35503
35619
  const { refreshToken, source: refreshTokenSource } = resolveStoredRefreshToken2(parsed, dir);
35504
35620
  if (token === null || refreshToken === null || parsed.refreshToken !== void 0 && typeof parsed.refreshToken !== "string" || parsed.refreshTokenEncrypted !== void 0 && typeof parsed.refreshTokenEncrypted !== "string" || !hasValidSelectedTwins2(parsed.selectedTwins)) {
@@ -35634,7 +35750,7 @@ function getStoredCredentials2(options) {
35634
35750
  return isExpired2(creds.expiresAt) ? null : creds;
35635
35751
  }
35636
35752
  function writeCredentialsAtPath2(path2, creds) {
35637
- const dir = dirname2(path2);
35753
+ const dir = dirname4(path2);
35638
35754
  ensureDir2(dir);
35639
35755
  const payload = {
35640
35756
  email: creds.email,
@@ -35760,8 +35876,9 @@ var GENERATED_TWIN_CATALOG2 = [
35760
35876
  icon: "AP",
35761
35877
  name: "Apify",
35762
35878
  description: "Actors, runs, datasets, key-value stores, and request queues.",
35763
- toolCount: 45,
35764
- transport: "rest"
35879
+ toolCount: 43,
35880
+ transport: "rest",
35881
+ opsCoverage: null
35765
35882
  },
35766
35883
  {
35767
35884
  id: "discord",
@@ -35769,7 +35886,17 @@ var GENERATED_TWIN_CATALOG2 = [
35769
35886
  name: "Discord",
35770
35887
  description: "Guilds, channels, messages, webhooks, threads, commands, and interaction responses.",
35771
35888
  toolCount: 67,
35772
- transport: "both"
35889
+ transport: "both",
35890
+ opsCoverage: 14
35891
+ },
35892
+ {
35893
+ id: "firecrawl",
35894
+ icon: "FC",
35895
+ name: "Firecrawl",
35896
+ description: "Scraping, crawling, mapping, search, and extraction.",
35897
+ toolCount: 6,
35898
+ transport: "rest",
35899
+ opsCoverage: 77
35773
35900
  },
35774
35901
  {
35775
35902
  id: "github",
@@ -35777,7 +35904,8 @@ var GENERATED_TWIN_CATALOG2 = [
35777
35904
  name: "GitHub",
35778
35905
  description: "Repos, issues, pull requests, branches, and commits.",
35779
35906
  toolCount: 26,
35780
- transport: "both"
35907
+ transport: "both",
35908
+ opsCoverage: 96
35781
35909
  },
35782
35910
  {
35783
35911
  id: "google-workspace",
@@ -35785,7 +35913,17 @@ var GENERATED_TWIN_CATALOG2 = [
35785
35913
  name: "Google Workspace",
35786
35914
  description: "Gmail, Calendar, Drive, Sheets, and Contacts.",
35787
35915
  toolCount: 249,
35788
- transport: "both"
35916
+ transport: "both",
35917
+ opsCoverage: 64
35918
+ },
35919
+ {
35920
+ id: "hubspot",
35921
+ icon: "HS",
35922
+ name: "HubSpot",
35923
+ description: "CRM contacts, companies, deals, tickets, and engagements.",
35924
+ toolCount: 45,
35925
+ transport: "rest",
35926
+ opsCoverage: 10
35789
35927
  },
35790
35928
  {
35791
35929
  id: "jira",
@@ -35793,7 +35931,8 @@ var GENERATED_TWIN_CATALOG2 = [
35793
35931
  name: "Jira",
35794
35932
  description: "Issues, projects, boards, sprints, and versions.",
35795
35933
  toolCount: 49,
35796
- transport: "both"
35934
+ transport: "both",
35935
+ opsCoverage: 80
35797
35936
  },
35798
35937
  {
35799
35938
  id: "linear",
@@ -35801,7 +35940,8 @@ var GENERATED_TWIN_CATALOG2 = [
35801
35940
  name: "Linear",
35802
35941
  description: "Issues, projects, teams, cycles, and workflows.",
35803
35942
  toolCount: 42,
35804
- transport: "both"
35943
+ transport: "both",
35944
+ opsCoverage: 98
35805
35945
  },
35806
35946
  {
35807
35947
  id: "ramp",
@@ -35809,7 +35949,17 @@ var GENERATED_TWIN_CATALOG2 = [
35809
35949
  name: "Ramp",
35810
35950
  description: "Cards, funds, expenses, reimbursements, bills, and travel.",
35811
35951
  toolCount: 46,
35812
- transport: "mcp"
35952
+ transport: "mcp",
35953
+ opsCoverage: null
35954
+ },
35955
+ {
35956
+ id: "sendgrid",
35957
+ icon: "SG",
35958
+ name: "SendGrid",
35959
+ description: "Mail send, contacts, lists, templates, and stats.",
35960
+ toolCount: 28,
35961
+ transport: "rest",
35962
+ opsCoverage: 100
35813
35963
  },
35814
35964
  {
35815
35965
  id: "slack",
@@ -35817,7 +35967,8 @@ var GENERATED_TWIN_CATALOG2 = [
35817
35967
  name: "Slack",
35818
35968
  description: "Channels, messages, threads, users, and reactions.",
35819
35969
  toolCount: 8,
35820
- transport: "both"
35970
+ transport: "both",
35971
+ opsCoverage: 100
35821
35972
  },
35822
35973
  {
35823
35974
  id: "stripe",
@@ -35825,7 +35976,8 @@ var GENERATED_TWIN_CATALOG2 = [
35825
35976
  name: "Stripe",
35826
35977
  description: "Customers, payments, subscriptions, invoices, and refunds.",
35827
35978
  toolCount: 28,
35828
- transport: "both"
35979
+ transport: "both",
35980
+ opsCoverage: null
35829
35981
  },
35830
35982
  {
35831
35983
  id: "supabase",
@@ -35833,7 +35985,8 @@ var GENERATED_TWIN_CATALOG2 = [
35833
35985
  name: "Supabase",
35834
35986
  description: "SQL, migrations, logs, branches, and project metadata.",
35835
35987
  toolCount: 29,
35836
- transport: "both"
35988
+ transport: "both",
35989
+ opsCoverage: 100
35837
35990
  },
35838
35991
  {
35839
35992
  id: "tavily",
@@ -35841,7 +35994,35 @@ var GENERATED_TWIN_CATALOG2 = [
35841
35994
  name: "Tavily",
35842
35995
  description: "Search, extract, crawl, map, research, usage, and API key operations.",
35843
35996
  toolCount: 11,
35844
- transport: "rest"
35997
+ transport: "rest",
35998
+ opsCoverage: 100
35999
+ },
36000
+ {
36001
+ id: "telegram",
36002
+ icon: "TG",
36003
+ name: "Telegram",
36004
+ description: "Bot messages, chats, updates, and webhooks.",
36005
+ toolCount: 32,
36006
+ transport: "both",
36007
+ opsCoverage: null
36008
+ },
36009
+ {
36010
+ id: "twilio",
36011
+ icon: "TW",
36012
+ name: "Twilio",
36013
+ description: "Messages, calls, phone numbers, and verifications.",
36014
+ toolCount: 35,
36015
+ transport: "rest",
36016
+ opsCoverage: 92
36017
+ },
36018
+ {
36019
+ id: "unipile",
36020
+ icon: "UP",
36021
+ name: "Unipile",
36022
+ description: "LinkedIn and email messaging, accounts, and chats.",
36023
+ toolCount: 24,
36024
+ transport: "rest",
36025
+ opsCoverage: 100
35845
36026
  }
35846
36027
  ];
35847
36028
  var GENERATED_STARTABLE_TWIN_IDS2 = [
@@ -38963,7 +39144,7 @@ function getRunSessionContext() {
38963
39144
  return runSessionContext.getStore();
38964
39145
  }
38965
39146
 
38966
- // ../seedgen/dist/chunk-P6IA2T7T.js
39147
+ // ../seedgen/dist/chunk-JD4OJDYX.js
38967
39148
  async function retryWithCircuitBreaker(fn, opts) {
38968
39149
  let lastError;
38969
39150
  for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {
@@ -39113,7 +39294,7 @@ async function callCodegenLlm(options, cooldownKey = "__global__", directUsage)
39113
39294
  );
39114
39295
  }
39115
39296
 
39116
- // ../seedgen/dist/chunk-FCZCUWWZ.js
39297
+ // ../seedgen/dist/chunk-GBWN7KZ5.js
39117
39298
  var ENRICH_SYSTEM_PROMPT = `You enrich seed data with scenario-specific values. Given a setup description and a seed with generic placeholder titles/names, replace them with realistic values that match the scenario.
39118
39299
 
39119
39300
  Output ONLY valid JSON:
@@ -44406,7 +44587,7 @@ var FILL_TEMPLATES = {
44406
44587
  }
44407
44588
  };
44408
44589
 
44409
- // ../seedgen/dist/chunk-QYH3SE7W.js
44590
+ // ../seedgen/dist/chunk-52VGGT45.js
44410
44591
  var MAX_ENTITY_TYPES = 50;
44411
44592
  function parseDetails(details) {
44412
44593
  const map2 = /* @__PURE__ */ new Map();
@@ -46317,13 +46498,13 @@ function extractSeedIntent(twinName, setupDescription) {
46317
46498
  }
46318
46499
  }
46319
46500
 
46320
- // ../seedgen/dist/chunk-HL4OTBZD.js
46501
+ // ../seedgen/dist/chunk-KEUOYX5N.js
46321
46502
  import { createHash as createHash3 } from "crypto";
46322
46503
  import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3, readdirSync, unlinkSync as unlinkSync3, lstatSync, renameSync as renameSync3 } from "fs";
46323
46504
  import { join as join4 } from "path";
46324
- import { homedir as homedir4 } from "os";
46505
+ import { homedir as homedir5 } from "os";
46325
46506
  var SEED_CACHE_VERSION = 6;
46326
- var CACHE_DIR = join4(homedir4(), ".archal", "seed-cache");
46507
+ var CACHE_DIR = join4(homedir5(), ".archal", "seed-cache");
46327
46508
  var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
46328
46509
  function normalizeSetupText(setupText) {
46329
46510
  return setupText.toLowerCase().replace(/[^a-z0-9\s_/-]/g, " ").replace(/\s+/g, " ").trim();
@@ -46479,7 +46660,7 @@ function cacheSeed(twinName, baseSeedName, setupText, seed, patch, scope, genera
46479
46660
  }
46480
46661
  }
46481
46662
 
46482
- // ../seedgen/dist/chunk-A25DCP64.js
46663
+ // ../seedgen/dist/chunk-KAB6MOBH.js
46483
46664
  import { createHash as createHash4 } from "crypto";
46484
46665
  var SEED_CODEGEN_MAX_TOKENS = 4096;
46485
46666
  var MAX_CODEGEN_ATTEMPTS = 3;
@@ -47044,7 +47225,7 @@ async function loadFileSeedsIntoTwins(config2, fetchTwin2, options = {}) {
47044
47225
  const sessionKey = config2.sessionKey;
47045
47226
  const loadingMarkerPath = getSeedLoadingMarkerPath(sessionKey);
47046
47227
  const loadedMarkerPath = getSeedLoadedMarkerPath(sessionKey);
47047
- const markerDir = dirname4(loadedMarkerPath);
47228
+ const markerDir = dirname5(loadedMarkerPath);
47048
47229
  const forceReload = options.forceReload === true;
47049
47230
  mkdirSync4(markerDir, { recursive: true, mode: 448 });
47050
47231
  if (forceReload) {