archal 0.9.17 → 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.
- package/clone-assets/apify/tools.json +30 -64
- package/clone-assets/discord/tools.json +1 -1
- package/clone-assets/github/tools.json +6 -0
- package/clone-assets/supabase/tools.json +74 -14
- package/dist/cli.cjs +51832 -38418
- package/dist/index.cjs +1 -1
- package/dist/seed/dynamic-generator.cjs +605 -152
- package/dist/vitest/{chunk-FU2VLK75.js → chunk-L36NXAU6.js} +173 -105
- package/dist/vitest/{chunk-CJJ32YQF.js → chunk-WZ7SA4CK.js} +18255 -17695
- package/dist/vitest/index.cjs +18494 -17872
- package/dist/vitest/index.js +2 -2
- package/dist/vitest/runtime/hosted-session-reaper.cjs +11019 -10746
- package/dist/vitest/runtime/hosted-session-reaper.js +1 -1
- package/dist/vitest/runtime/setup-files.js +2 -2
- package/package.json +9 -9
- package/skills/attach/SKILL.md +402 -0
- package/skills/onboard/SKILL.md +12 -0
|
@@ -2981,7 +2981,7 @@ var require_compile = __commonJS({
|
|
|
2981
2981
|
const schOrFunc = root.refs[ref2];
|
|
2982
2982
|
if (schOrFunc)
|
|
2983
2983
|
return schOrFunc;
|
|
2984
|
-
let _sch =
|
|
2984
|
+
let _sch = resolve6.call(this, root, ref2);
|
|
2985
2985
|
if (_sch === void 0) {
|
|
2986
2986
|
const schema = (_a2 = root.localRefs) === null || _a2 === void 0 ? void 0 : _a2[ref2];
|
|
2987
2987
|
const { schemaId } = this.opts;
|
|
@@ -3008,7 +3008,7 @@ var require_compile = __commonJS({
|
|
|
3008
3008
|
function sameSchemaEnv(s1, s2) {
|
|
3009
3009
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
3010
3010
|
}
|
|
3011
|
-
function
|
|
3011
|
+
function resolve6(root, ref2) {
|
|
3012
3012
|
let sch;
|
|
3013
3013
|
while (typeof (sch = this.refs[ref2]) == "string")
|
|
3014
3014
|
ref2 = sch;
|
|
@@ -3583,55 +3583,55 @@ var require_fast_uri = __commonJS({
|
|
|
3583
3583
|
}
|
|
3584
3584
|
return uri;
|
|
3585
3585
|
}
|
|
3586
|
-
function
|
|
3586
|
+
function resolve6(baseURI, relativeURI, options) {
|
|
3587
3587
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3588
3588
|
const resolved = resolveComponent(parse6(baseURI, schemelessOptions), parse6(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
3589
3589
|
schemelessOptions.skipEscape = true;
|
|
3590
3590
|
return serialize(resolved, schemelessOptions);
|
|
3591
3591
|
}
|
|
3592
|
-
function resolveComponent(base,
|
|
3592
|
+
function resolveComponent(base, relative3, options, skipNormalization) {
|
|
3593
3593
|
const target = {};
|
|
3594
3594
|
if (!skipNormalization) {
|
|
3595
3595
|
base = parse6(serialize(base, options), options);
|
|
3596
|
-
|
|
3596
|
+
relative3 = parse6(serialize(relative3, options), options);
|
|
3597
3597
|
}
|
|
3598
3598
|
options = options || {};
|
|
3599
|
-
if (!options.tolerant &&
|
|
3600
|
-
target.scheme =
|
|
3601
|
-
target.userinfo =
|
|
3602
|
-
target.host =
|
|
3603
|
-
target.port =
|
|
3604
|
-
target.path = removeDotSegments(
|
|
3605
|
-
target.query =
|
|
3599
|
+
if (!options.tolerant && relative3.scheme) {
|
|
3600
|
+
target.scheme = relative3.scheme;
|
|
3601
|
+
target.userinfo = relative3.userinfo;
|
|
3602
|
+
target.host = relative3.host;
|
|
3603
|
+
target.port = relative3.port;
|
|
3604
|
+
target.path = removeDotSegments(relative3.path || "");
|
|
3605
|
+
target.query = relative3.query;
|
|
3606
3606
|
} else {
|
|
3607
|
-
if (
|
|
3608
|
-
target.userinfo =
|
|
3609
|
-
target.host =
|
|
3610
|
-
target.port =
|
|
3611
|
-
target.path = removeDotSegments(
|
|
3612
|
-
target.query =
|
|
3607
|
+
if (relative3.userinfo !== void 0 || relative3.host !== void 0 || relative3.port !== void 0) {
|
|
3608
|
+
target.userinfo = relative3.userinfo;
|
|
3609
|
+
target.host = relative3.host;
|
|
3610
|
+
target.port = relative3.port;
|
|
3611
|
+
target.path = removeDotSegments(relative3.path || "");
|
|
3612
|
+
target.query = relative3.query;
|
|
3613
3613
|
} else {
|
|
3614
|
-
if (!
|
|
3614
|
+
if (!relative3.path) {
|
|
3615
3615
|
target.path = base.path;
|
|
3616
|
-
if (
|
|
3617
|
-
target.query =
|
|
3616
|
+
if (relative3.query !== void 0) {
|
|
3617
|
+
target.query = relative3.query;
|
|
3618
3618
|
} else {
|
|
3619
3619
|
target.query = base.query;
|
|
3620
3620
|
}
|
|
3621
3621
|
} else {
|
|
3622
|
-
if (
|
|
3623
|
-
target.path = removeDotSegments(
|
|
3622
|
+
if (relative3.path[0] === "/") {
|
|
3623
|
+
target.path = removeDotSegments(relative3.path);
|
|
3624
3624
|
} else {
|
|
3625
3625
|
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
|
|
3626
|
-
target.path = "/" +
|
|
3626
|
+
target.path = "/" + relative3.path;
|
|
3627
3627
|
} else if (!base.path) {
|
|
3628
|
-
target.path =
|
|
3628
|
+
target.path = relative3.path;
|
|
3629
3629
|
} else {
|
|
3630
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
3630
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative3.path;
|
|
3631
3631
|
}
|
|
3632
3632
|
target.path = removeDotSegments(target.path);
|
|
3633
3633
|
}
|
|
3634
|
-
target.query =
|
|
3634
|
+
target.query = relative3.query;
|
|
3635
3635
|
}
|
|
3636
3636
|
target.userinfo = base.userinfo;
|
|
3637
3637
|
target.host = base.host;
|
|
@@ -3639,7 +3639,7 @@ var require_fast_uri = __commonJS({
|
|
|
3639
3639
|
}
|
|
3640
3640
|
target.scheme = base.scheme;
|
|
3641
3641
|
}
|
|
3642
|
-
target.fragment =
|
|
3642
|
+
target.fragment = relative3.fragment;
|
|
3643
3643
|
return target;
|
|
3644
3644
|
}
|
|
3645
3645
|
function equal(uriA, uriB, options) {
|
|
@@ -3810,7 +3810,7 @@ var require_fast_uri = __commonJS({
|
|
|
3810
3810
|
var fastUri = {
|
|
3811
3811
|
SCHEMES,
|
|
3812
3812
|
normalize,
|
|
3813
|
-
resolve:
|
|
3813
|
+
resolve: resolve6,
|
|
3814
3814
|
resolveComponent,
|
|
3815
3815
|
equal,
|
|
3816
3816
|
serialize,
|
|
@@ -6809,7 +6809,7 @@ __export(dynamic_generator_exports, {
|
|
|
6809
6809
|
module.exports = __toCommonJS(dynamic_generator_exports);
|
|
6810
6810
|
|
|
6811
6811
|
// ../packages/seedgen/src/runner/seed/dynamic-generator.ts
|
|
6812
|
-
var
|
|
6812
|
+
var import_node_crypto15 = require("crypto");
|
|
6813
6813
|
|
|
6814
6814
|
// ../packages/node-auth/src/constants.ts
|
|
6815
6815
|
var CREDENTIALS_FILE = "credentials.json";
|
|
@@ -7383,15 +7383,26 @@ var GENERATED_TWIN_CATALOG = [
|
|
|
7383
7383
|
name: "Apify",
|
|
7384
7384
|
description: "Actors, runs, datasets, key-value stores, and request queues.",
|
|
7385
7385
|
toolCount: 43,
|
|
7386
|
-
transport: "rest"
|
|
7386
|
+
transport: "rest",
|
|
7387
|
+
opsCoverage: null
|
|
7387
7388
|
},
|
|
7388
7389
|
{
|
|
7389
7390
|
id: "discord",
|
|
7390
7391
|
icon: "DC",
|
|
7391
7392
|
name: "Discord",
|
|
7392
7393
|
description: "Guilds, channels, messages, webhooks, threads, commands, and interaction responses.",
|
|
7393
|
-
toolCount:
|
|
7394
|
-
transport: "both"
|
|
7394
|
+
toolCount: 67,
|
|
7395
|
+
transport: "both",
|
|
7396
|
+
opsCoverage: 14
|
|
7397
|
+
},
|
|
7398
|
+
{
|
|
7399
|
+
id: "firecrawl",
|
|
7400
|
+
icon: "FC",
|
|
7401
|
+
name: "Firecrawl",
|
|
7402
|
+
description: "Scraping, crawling, mapping, search, and extraction.",
|
|
7403
|
+
toolCount: 6,
|
|
7404
|
+
transport: "rest",
|
|
7405
|
+
opsCoverage: 77
|
|
7395
7406
|
},
|
|
7396
7407
|
{
|
|
7397
7408
|
id: "github",
|
|
@@ -7399,15 +7410,26 @@ var GENERATED_TWIN_CATALOG = [
|
|
|
7399
7410
|
name: "GitHub",
|
|
7400
7411
|
description: "Repos, issues, pull requests, branches, and commits.",
|
|
7401
7412
|
toolCount: 26,
|
|
7402
|
-
transport: "both"
|
|
7413
|
+
transport: "both",
|
|
7414
|
+
opsCoverage: 96
|
|
7403
7415
|
},
|
|
7404
7416
|
{
|
|
7405
7417
|
id: "google-workspace",
|
|
7406
7418
|
icon: "GW",
|
|
7407
7419
|
name: "Google Workspace",
|
|
7408
7420
|
description: "Gmail, Calendar, Drive, Sheets, and Contacts.",
|
|
7409
|
-
toolCount:
|
|
7410
|
-
transport: "both"
|
|
7421
|
+
toolCount: 249,
|
|
7422
|
+
transport: "both",
|
|
7423
|
+
opsCoverage: 64
|
|
7424
|
+
},
|
|
7425
|
+
{
|
|
7426
|
+
id: "hubspot",
|
|
7427
|
+
icon: "HS",
|
|
7428
|
+
name: "HubSpot",
|
|
7429
|
+
description: "CRM contacts, companies, deals, tickets, and engagements.",
|
|
7430
|
+
toolCount: 45,
|
|
7431
|
+
transport: "rest",
|
|
7432
|
+
opsCoverage: 10
|
|
7411
7433
|
},
|
|
7412
7434
|
{
|
|
7413
7435
|
id: "jira",
|
|
@@ -7415,7 +7437,8 @@ var GENERATED_TWIN_CATALOG = [
|
|
|
7415
7437
|
name: "Jira",
|
|
7416
7438
|
description: "Issues, projects, boards, sprints, and versions.",
|
|
7417
7439
|
toolCount: 49,
|
|
7418
|
-
transport: "both"
|
|
7440
|
+
transport: "both",
|
|
7441
|
+
opsCoverage: 80
|
|
7419
7442
|
},
|
|
7420
7443
|
{
|
|
7421
7444
|
id: "linear",
|
|
@@ -7423,7 +7446,8 @@ var GENERATED_TWIN_CATALOG = [
|
|
|
7423
7446
|
name: "Linear",
|
|
7424
7447
|
description: "Issues, projects, teams, cycles, and workflows.",
|
|
7425
7448
|
toolCount: 42,
|
|
7426
|
-
transport: "both"
|
|
7449
|
+
transport: "both",
|
|
7450
|
+
opsCoverage: 98
|
|
7427
7451
|
},
|
|
7428
7452
|
{
|
|
7429
7453
|
id: "ramp",
|
|
@@ -7431,7 +7455,17 @@ var GENERATED_TWIN_CATALOG = [
|
|
|
7431
7455
|
name: "Ramp",
|
|
7432
7456
|
description: "Cards, funds, expenses, reimbursements, bills, and travel.",
|
|
7433
7457
|
toolCount: 46,
|
|
7434
|
-
transport: "mcp"
|
|
7458
|
+
transport: "mcp",
|
|
7459
|
+
opsCoverage: null
|
|
7460
|
+
},
|
|
7461
|
+
{
|
|
7462
|
+
id: "sendgrid",
|
|
7463
|
+
icon: "SG",
|
|
7464
|
+
name: "SendGrid",
|
|
7465
|
+
description: "Mail send, contacts, lists, templates, and stats.",
|
|
7466
|
+
toolCount: 28,
|
|
7467
|
+
transport: "rest",
|
|
7468
|
+
opsCoverage: 100
|
|
7435
7469
|
},
|
|
7436
7470
|
{
|
|
7437
7471
|
id: "slack",
|
|
@@ -7439,7 +7473,8 @@ var GENERATED_TWIN_CATALOG = [
|
|
|
7439
7473
|
name: "Slack",
|
|
7440
7474
|
description: "Channels, messages, threads, users, and reactions.",
|
|
7441
7475
|
toolCount: 8,
|
|
7442
|
-
transport: "both"
|
|
7476
|
+
transport: "both",
|
|
7477
|
+
opsCoverage: 100
|
|
7443
7478
|
},
|
|
7444
7479
|
{
|
|
7445
7480
|
id: "stripe",
|
|
@@ -7447,7 +7482,8 @@ var GENERATED_TWIN_CATALOG = [
|
|
|
7447
7482
|
name: "Stripe",
|
|
7448
7483
|
description: "Customers, payments, subscriptions, invoices, and refunds.",
|
|
7449
7484
|
toolCount: 28,
|
|
7450
|
-
transport: "both"
|
|
7485
|
+
transport: "both",
|
|
7486
|
+
opsCoverage: null
|
|
7451
7487
|
},
|
|
7452
7488
|
{
|
|
7453
7489
|
id: "supabase",
|
|
@@ -7455,7 +7491,8 @@ var GENERATED_TWIN_CATALOG = [
|
|
|
7455
7491
|
name: "Supabase",
|
|
7456
7492
|
description: "SQL, migrations, logs, branches, and project metadata.",
|
|
7457
7493
|
toolCount: 29,
|
|
7458
|
-
transport: "both"
|
|
7494
|
+
transport: "both",
|
|
7495
|
+
opsCoverage: 100
|
|
7459
7496
|
},
|
|
7460
7497
|
{
|
|
7461
7498
|
id: "tavily",
|
|
@@ -7463,7 +7500,35 @@ var GENERATED_TWIN_CATALOG = [
|
|
|
7463
7500
|
name: "Tavily",
|
|
7464
7501
|
description: "Search, extract, crawl, map, research, usage, and API key operations.",
|
|
7465
7502
|
toolCount: 11,
|
|
7466
|
-
transport: "rest"
|
|
7503
|
+
transport: "rest",
|
|
7504
|
+
opsCoverage: 100
|
|
7505
|
+
},
|
|
7506
|
+
{
|
|
7507
|
+
id: "telegram",
|
|
7508
|
+
icon: "TG",
|
|
7509
|
+
name: "Telegram",
|
|
7510
|
+
description: "Bot messages, chats, updates, and webhooks.",
|
|
7511
|
+
toolCount: 32,
|
|
7512
|
+
transport: "both",
|
|
7513
|
+
opsCoverage: null
|
|
7514
|
+
},
|
|
7515
|
+
{
|
|
7516
|
+
id: "twilio",
|
|
7517
|
+
icon: "TW",
|
|
7518
|
+
name: "Twilio",
|
|
7519
|
+
description: "Messages, calls, phone numbers, and verifications.",
|
|
7520
|
+
toolCount: 35,
|
|
7521
|
+
transport: "rest",
|
|
7522
|
+
opsCoverage: 92
|
|
7523
|
+
},
|
|
7524
|
+
{
|
|
7525
|
+
id: "unipile",
|
|
7526
|
+
icon: "UP",
|
|
7527
|
+
name: "Unipile",
|
|
7528
|
+
description: "LinkedIn and email messaging, accounts, and chats.",
|
|
7529
|
+
toolCount: 24,
|
|
7530
|
+
transport: "rest",
|
|
7531
|
+
opsCoverage: 100
|
|
7467
7532
|
}
|
|
7468
7533
|
];
|
|
7469
7534
|
var GENERATED_STARTABLE_TWIN_IDS = [
|
|
@@ -7566,6 +7631,51 @@ var LIFETIME_PERIOD_RESETS_AT = new Date(Date.UTC(9999, 11, 31));
|
|
|
7566
7631
|
var SCENARIO_USAGE_WINDOW_DAYS = 7;
|
|
7567
7632
|
var SCENARIO_USAGE_WINDOW_MS = SCENARIO_USAGE_WINDOW_DAYS * 24 * 60 * 60 * 1e3;
|
|
7568
7633
|
var SCENARIO_USAGE_WINDOW_SECONDS = SCENARIO_USAGE_WINDOW_DAYS * 24 * 60 * 60;
|
|
7634
|
+
var LLM_PRICING_USD_PER_M_TOKENS = {
|
|
7635
|
+
// Google Gemini (verified 2026-05-05, standard tier <=200K input tokens)
|
|
7636
|
+
"gemini-2.5-pro": { input: 1.25, output: 10 },
|
|
7637
|
+
"gemini-2.5-flash": { input: 0.3, output: 2.5 },
|
|
7638
|
+
// OpenAI flagship text models (verified 2026-05-21, standard short-context tier)
|
|
7639
|
+
"gpt-5.5": { input: 5, output: 30 },
|
|
7640
|
+
"gpt-5.5-pro": { input: 30, output: 180 },
|
|
7641
|
+
"gpt-5.4": { input: 2.5, output: 15 },
|
|
7642
|
+
"gpt-5.4-mini": { input: 0.75, output: 4.5 },
|
|
7643
|
+
"gpt-5.4-nano": { input: 0.2, output: 1.25 },
|
|
7644
|
+
"gpt-5.4-pro": { input: 30, output: 180 },
|
|
7645
|
+
"gpt-4o-mini": { input: 0.15, output: 0.6 },
|
|
7646
|
+
"gpt-4o": { input: 2.5, output: 10 },
|
|
7647
|
+
"gpt-4.1-mini": { input: 0.4, output: 1.6 },
|
|
7648
|
+
"gpt-4.1-nano": { input: 0.1, output: 0.4 },
|
|
7649
|
+
"gpt-4.1": { input: 2, output: 8 },
|
|
7650
|
+
// DeepSeek (verified 2026-05-05; legacy names map to v4-flash per vendor)
|
|
7651
|
+
"deepseek-chat": { input: 0.14, output: 0.28 },
|
|
7652
|
+
"deepseek-reasoner": { input: 0.14, output: 0.28 },
|
|
7653
|
+
"deepseek-v4-flash": { input: 0.14, output: 0.28 }
|
|
7654
|
+
};
|
|
7655
|
+
var LLM_PRICING_FAMILY_RATES = [
|
|
7656
|
+
{ match: /^gemini-2\.5-pro/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gemini-2.5-pro"] },
|
|
7657
|
+
{ match: /^gemini-2\.5-flash/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gemini-2.5-flash"] },
|
|
7658
|
+
{ match: /^gpt-5\.5-pro/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.5-pro"] },
|
|
7659
|
+
{ match: /^gpt-5\.5/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.5"] },
|
|
7660
|
+
{ match: /^gpt-5\.4-pro/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4-pro"] },
|
|
7661
|
+
{ match: /^gpt-5\.4-mini/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4-mini"] },
|
|
7662
|
+
{ match: /^gpt-5\.4-nano/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4-nano"] },
|
|
7663
|
+
{ match: /^gpt-5\.4/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4"] },
|
|
7664
|
+
{ match: /^gpt-4o-mini/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4o-mini"] },
|
|
7665
|
+
{ match: /^gpt-4o(?!-mini)/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4o"] },
|
|
7666
|
+
{ match: /^gpt-4\.1-mini/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4.1-mini"] },
|
|
7667
|
+
{ match: /^gpt-4\.1-nano/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4.1-nano"] },
|
|
7668
|
+
{ match: /^gpt-4\.1(?!-mini|-nano)/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4.1"] },
|
|
7669
|
+
{ match: /^claude-opus-/i, rate: { input: 15, output: 75 } },
|
|
7670
|
+
{ match: /^claude-haiku-/i, rate: { input: 0.8, output: 4 } },
|
|
7671
|
+
{ match: /^claude-sonnet-/i, rate: { input: 3, output: 15 } },
|
|
7672
|
+
{ match: /^opus-/i, rate: { input: 15, output: 75 } },
|
|
7673
|
+
{ match: /^haiku-/i, rate: { input: 0.8, output: 4 } },
|
|
7674
|
+
{ match: /^sonnet-/i, rate: { input: 3, output: 15 } },
|
|
7675
|
+
{ match: /^deepseek-chat/i, rate: LLM_PRICING_USD_PER_M_TOKENS["deepseek-chat"] },
|
|
7676
|
+
{ match: /^deepseek-reasoner/i, rate: LLM_PRICING_USD_PER_M_TOKENS["deepseek-reasoner"] },
|
|
7677
|
+
{ match: /^deepseek-v4-flash/i, rate: LLM_PRICING_USD_PER_M_TOKENS["deepseek-v4-flash"] }
|
|
7678
|
+
];
|
|
7569
7679
|
|
|
7570
7680
|
// ../twins/core/src/errors.ts
|
|
7571
7681
|
function errorMessage2(error48) {
|
|
@@ -26979,14 +27089,84 @@ var import_node_crypto7 = require("crypto");
|
|
|
26979
27089
|
var import_node_perf_hooks = require("perf_hooks");
|
|
26980
27090
|
|
|
26981
27091
|
// ../twins/core/src/fixture-oracle.ts
|
|
26982
|
-
var
|
|
26983
|
-
var
|
|
27092
|
+
var import_node_fs6 = require("fs");
|
|
27093
|
+
var import_node_path5 = require("path");
|
|
26984
27094
|
var import_node_url2 = require("url");
|
|
26985
27095
|
|
|
26986
|
-
// ../twins/core/src/
|
|
27096
|
+
// ../twins/core/src/legacy-asset-cache.ts
|
|
27097
|
+
var import_node_crypto9 = require("crypto");
|
|
26987
27098
|
var import_node_fs5 = require("fs");
|
|
27099
|
+
var import_node_os3 = require("os");
|
|
26988
27100
|
var import_node_path4 = require("path");
|
|
26989
27101
|
|
|
27102
|
+
// ../twins/core/src/recording-fetcher.ts
|
|
27103
|
+
var import_node_crypto8 = require("crypto");
|
|
27104
|
+
var import_node_fs4 = require("fs");
|
|
27105
|
+
var import_node_os2 = require("os");
|
|
27106
|
+
var import_node_path3 = require("path");
|
|
27107
|
+
var RecordingManifestEntrySchema = external_exports3.object({
|
|
27108
|
+
filename: external_exports3.string(),
|
|
27109
|
+
sha256: external_exports3.string().regex(/^[0-9a-f]{64}$/, "sha256 must be 64 lowercase hex chars"),
|
|
27110
|
+
size: external_exports3.number().optional(),
|
|
27111
|
+
sizeBytes: external_exports3.number().optional(),
|
|
27112
|
+
uploadedAt: external_exports3.string().optional(),
|
|
27113
|
+
// Optional symbolic tags that map fixture-oracle / replay lookups onto this
|
|
27114
|
+
// recording. Lets twins keep tag→file resolution inside the manifest itself
|
|
27115
|
+
// rather than depending on a separate provenance.json (which is excluded
|
|
27116
|
+
// from the in-tree fixture allowlist for graduated twins). Codex P2 on
|
|
27117
|
+
// tavily #3603 — fixture-oracle previously required provenance.json to
|
|
27118
|
+
// resolve `rest-profile:tavily:tavily_search_basic` → filename.
|
|
27119
|
+
tags: external_exports3.array(external_exports3.string()).optional()
|
|
27120
|
+
}).loose();
|
|
27121
|
+
var RecordingManifestSchema = external_exports3.object({
|
|
27122
|
+
service: external_exports3.string().min(1),
|
|
27123
|
+
version: external_exports3.number().int(),
|
|
27124
|
+
container: external_exports3.string().min(1),
|
|
27125
|
+
baseUrl: external_exports3.string().optional(),
|
|
27126
|
+
entries: external_exports3.array(RecordingManifestEntrySchema)
|
|
27127
|
+
}).loose();
|
|
27128
|
+
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";
|
|
27129
|
+
var DEFAULT_CACHE_ROOT = process.env["ARCHAL_FIXTURE_CACHE_ROOT"] ?? (0, import_node_path3.resolve)((0, import_node_os2.homedir)(), ".archal", "forge", "recordings-cache");
|
|
27130
|
+
function warnIfSasExpiresSoon(baseUrl) {
|
|
27131
|
+
if (process.env["ARCHAL_FIXTURE_SAS_WARN"] === "0") return;
|
|
27132
|
+
const queryIdx = baseUrl.indexOf("?");
|
|
27133
|
+
if (queryIdx < 0) return;
|
|
27134
|
+
const query = baseUrl.slice(queryIdx + 1);
|
|
27135
|
+
const seParam = query.split("&").find((p) => p.startsWith("se="));
|
|
27136
|
+
if (!seParam) return;
|
|
27137
|
+
const seValue = decodeURIComponent(seParam.slice(3));
|
|
27138
|
+
const expiresAt = Date.parse(seValue);
|
|
27139
|
+
if (Number.isNaN(expiresAt)) return;
|
|
27140
|
+
const now = Date.now();
|
|
27141
|
+
const daysRemaining = Math.floor((expiresAt - now) / (1e3 * 60 * 60 * 24));
|
|
27142
|
+
if (daysRemaining < 365) {
|
|
27143
|
+
console.warn(
|
|
27144
|
+
`[recording-fetcher] SAS token in ARCHAL_FIXTURE_BASE_URL expires in ${daysRemaining}d (${seValue}). Rotate via scripts/rotate-fixture-sas.mjs before expiry.`
|
|
27145
|
+
);
|
|
27146
|
+
}
|
|
27147
|
+
}
|
|
27148
|
+
warnIfSasExpiresSoon(DEFAULT_BASE_URL);
|
|
27149
|
+
|
|
27150
|
+
// ../twins/core/src/legacy-asset-cache.ts
|
|
27151
|
+
var DEFAULT_CACHE_ROOT2 = process.env["ARCHAL_LEGACY_ASSET_CACHE_ROOT"] ?? (0, import_node_path4.resolve)((0, import_node_os3.homedir)(), ".archal", "forge", "legacy-assets-cache");
|
|
27152
|
+
var LegacyAssetEntrySchema = external_exports3.object({
|
|
27153
|
+
relativePath: external_exports3.string().min(1),
|
|
27154
|
+
sha256: external_exports3.string().regex(/^[0-9a-f]{64}$/, "sha256 must be 64 lowercase hex chars"),
|
|
27155
|
+
sizeBytes: external_exports3.number().optional(),
|
|
27156
|
+
uploadedAt: external_exports3.string().optional()
|
|
27157
|
+
}).loose();
|
|
27158
|
+
var LegacyAssetManifestSchema = external_exports3.object({
|
|
27159
|
+
service: external_exports3.string().min(1),
|
|
27160
|
+
version: external_exports3.number().int(),
|
|
27161
|
+
container: external_exports3.string().min(1),
|
|
27162
|
+
layout: external_exports3.string().optional(),
|
|
27163
|
+
entries: external_exports3.array(LegacyAssetEntrySchema)
|
|
27164
|
+
}).loose();
|
|
27165
|
+
|
|
27166
|
+
// ../twins/core/src/run-twin-cli.ts
|
|
27167
|
+
var import_node_fs7 = require("fs");
|
|
27168
|
+
var import_node_path6 = require("path");
|
|
27169
|
+
|
|
26990
27170
|
// ../twins/manifest.json
|
|
26991
27171
|
var manifest_default = [
|
|
26992
27172
|
{
|
|
@@ -27036,6 +27216,12 @@ var manifest_default = [
|
|
|
27036
27216
|
package: "@archal/twin-firecrawl",
|
|
27037
27217
|
path: "twins/firecrawl",
|
|
27038
27218
|
stage: "internal",
|
|
27219
|
+
display: {
|
|
27220
|
+
icon: "FC",
|
|
27221
|
+
name: "Firecrawl",
|
|
27222
|
+
description: "Scraping, crawling, mapping, search, and extraction.",
|
|
27223
|
+
toolCount: 6
|
|
27224
|
+
},
|
|
27039
27225
|
transport: "rest",
|
|
27040
27226
|
hostedRuntime: { enabled: true, requiresDist: true, requiresEmptySeed: true },
|
|
27041
27227
|
cli: { bundleAssets: false, bundleToolSnapshot: false },
|
|
@@ -27103,6 +27289,12 @@ var manifest_default = [
|
|
|
27103
27289
|
package: "@archal/twin-hubspot",
|
|
27104
27290
|
path: "twins/hubspot",
|
|
27105
27291
|
stage: "internal",
|
|
27292
|
+
display: {
|
|
27293
|
+
icon: "HS",
|
|
27294
|
+
name: "HubSpot",
|
|
27295
|
+
description: "CRM contacts, companies, deals, tickets, and engagements.",
|
|
27296
|
+
toolCount: 45
|
|
27297
|
+
},
|
|
27106
27298
|
transport: "rest",
|
|
27107
27299
|
hostedRuntime: { enabled: true, requiresDist: true, requiresEmptySeed: true },
|
|
27108
27300
|
cli: { bundleAssets: false, bundleToolSnapshot: false },
|
|
@@ -27179,6 +27371,12 @@ var manifest_default = [
|
|
|
27179
27371
|
package: "@archal/twin-sendgrid",
|
|
27180
27372
|
path: "twins/sendgrid",
|
|
27181
27373
|
stage: "internal",
|
|
27374
|
+
display: {
|
|
27375
|
+
icon: "SG",
|
|
27376
|
+
name: "SendGrid",
|
|
27377
|
+
description: "Mail send, contacts, lists, templates, and stats.",
|
|
27378
|
+
toolCount: 28
|
|
27379
|
+
},
|
|
27182
27380
|
transport: "rest",
|
|
27183
27381
|
hostedRuntime: { enabled: true, requiresDist: true, requiresEmptySeed: true },
|
|
27184
27382
|
cli: { bundleAssets: false, bundleToolSnapshot: false },
|
|
@@ -27275,6 +27473,12 @@ var manifest_default = [
|
|
|
27275
27473
|
package: "@archal/twin-telegram",
|
|
27276
27474
|
path: "twins/telegram",
|
|
27277
27475
|
stage: "internal",
|
|
27476
|
+
display: {
|
|
27477
|
+
icon: "TG",
|
|
27478
|
+
name: "Telegram",
|
|
27479
|
+
description: "Bot messages, chats, updates, and webhooks.",
|
|
27480
|
+
toolCount: 32
|
|
27481
|
+
},
|
|
27278
27482
|
transport: "both",
|
|
27279
27483
|
hostedRuntime: { enabled: true, requiresDist: true, requiresEmptySeed: true },
|
|
27280
27484
|
cli: { bundleAssets: false, bundleToolSnapshot: false },
|
|
@@ -27287,6 +27491,12 @@ var manifest_default = [
|
|
|
27287
27491
|
package: "@archal/twin-twilio",
|
|
27288
27492
|
path: "twins/twilio",
|
|
27289
27493
|
stage: "internal",
|
|
27494
|
+
display: {
|
|
27495
|
+
icon: "TW",
|
|
27496
|
+
name: "Twilio",
|
|
27497
|
+
description: "Messages, calls, phone numbers, and verifications.",
|
|
27498
|
+
toolCount: 35
|
|
27499
|
+
},
|
|
27290
27500
|
transport: "rest",
|
|
27291
27501
|
hostedRuntime: { enabled: true, requiresDist: true, requiresEmptySeed: true },
|
|
27292
27502
|
cli: { bundleAssets: false, bundleToolSnapshot: false },
|
|
@@ -27299,6 +27509,12 @@ var manifest_default = [
|
|
|
27299
27509
|
package: "@archal/twin-unipile",
|
|
27300
27510
|
path: "twins/unipile",
|
|
27301
27511
|
stage: "internal",
|
|
27512
|
+
display: {
|
|
27513
|
+
icon: "UP",
|
|
27514
|
+
name: "Unipile",
|
|
27515
|
+
description: "LinkedIn and email messaging, accounts, and chats.",
|
|
27516
|
+
toolCount: 24
|
|
27517
|
+
},
|
|
27302
27518
|
transport: "rest",
|
|
27303
27519
|
hostedRuntime: { enabled: true, requiresDist: true, requiresEmptySeed: true },
|
|
27304
27520
|
cli: { bundleAssets: false, bundleToolSnapshot: false },
|
|
@@ -27317,10 +27533,10 @@ var CLONE_PACKAGES = CLONE_MANIFEST.map((t) => t.package);
|
|
|
27317
27533
|
var TWIN_PREFIX_PATTERN = new RegExp(`^(${CLONE_NAMES.join("|")})_`, "i");
|
|
27318
27534
|
|
|
27319
27535
|
// ../twins/core/src/session-run-id.ts
|
|
27320
|
-
var
|
|
27536
|
+
var import_node_crypto10 = require("crypto");
|
|
27321
27537
|
|
|
27322
27538
|
// ../twins/core/src/webhook-signing.ts
|
|
27323
|
-
var
|
|
27539
|
+
var import_node_crypto11 = require("crypto");
|
|
27324
27540
|
|
|
27325
27541
|
// ../twins/core/src/scenario-schemas.ts
|
|
27326
27542
|
var successCriterionSchema = external_exports3.object({
|
|
@@ -27458,59 +27674,11 @@ var SCENARIO_RISK_TAXONOMY = SCENARIO_RISK_RULES.map(
|
|
|
27458
27674
|
({ id, label, description }) => ({ id, label, description })
|
|
27459
27675
|
);
|
|
27460
27676
|
|
|
27461
|
-
// ../twins/core/src/recording-fetcher.ts
|
|
27462
|
-
var import_node_crypto10 = require("crypto");
|
|
27463
|
-
var import_node_fs6 = require("fs");
|
|
27464
|
-
var import_node_os2 = require("os");
|
|
27465
|
-
var import_node_path5 = require("path");
|
|
27466
|
-
var RecordingManifestEntrySchema = external_exports3.object({
|
|
27467
|
-
filename: external_exports3.string(),
|
|
27468
|
-
sha256: external_exports3.string().regex(/^[0-9a-f]{64}$/, "sha256 must be 64 lowercase hex chars"),
|
|
27469
|
-
size: external_exports3.number().optional(),
|
|
27470
|
-
sizeBytes: external_exports3.number().optional(),
|
|
27471
|
-
uploadedAt: external_exports3.string().optional(),
|
|
27472
|
-
// Optional symbolic tags that map fixture-oracle / replay lookups onto this
|
|
27473
|
-
// recording. Lets twins keep tag→file resolution inside the manifest itself
|
|
27474
|
-
// rather than depending on a separate provenance.json (which is excluded
|
|
27475
|
-
// from the in-tree fixture allowlist for graduated twins). Codex P2 on
|
|
27476
|
-
// tavily #3603 — fixture-oracle previously required provenance.json to
|
|
27477
|
-
// resolve `rest-profile:tavily:tavily_search_basic` → filename.
|
|
27478
|
-
tags: external_exports3.array(external_exports3.string()).optional()
|
|
27479
|
-
}).loose();
|
|
27480
|
-
var RecordingManifestSchema = external_exports3.object({
|
|
27481
|
-
service: external_exports3.string().min(1),
|
|
27482
|
-
version: external_exports3.number().int(),
|
|
27483
|
-
container: external_exports3.string().min(1),
|
|
27484
|
-
baseUrl: external_exports3.string().optional(),
|
|
27485
|
-
entries: external_exports3.array(RecordingManifestEntrySchema)
|
|
27486
|
-
}).loose();
|
|
27487
|
-
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";
|
|
27488
|
-
var DEFAULT_CACHE_ROOT = process.env["ARCHAL_FIXTURE_CACHE_ROOT"] ?? (0, import_node_path5.resolve)((0, import_node_os2.homedir)(), ".archal", "forge", "recordings-cache");
|
|
27489
|
-
function warnIfSasExpiresSoon(baseUrl) {
|
|
27490
|
-
if (process.env["ARCHAL_FIXTURE_SAS_WARN"] === "0") return;
|
|
27491
|
-
const queryIdx = baseUrl.indexOf("?");
|
|
27492
|
-
if (queryIdx < 0) return;
|
|
27493
|
-
const query = baseUrl.slice(queryIdx + 1);
|
|
27494
|
-
const seParam = query.split("&").find((p) => p.startsWith("se="));
|
|
27495
|
-
if (!seParam) return;
|
|
27496
|
-
const seValue = decodeURIComponent(seParam.slice(3));
|
|
27497
|
-
const expiresAt = Date.parse(seValue);
|
|
27498
|
-
if (Number.isNaN(expiresAt)) return;
|
|
27499
|
-
const now = Date.now();
|
|
27500
|
-
const daysRemaining = Math.floor((expiresAt - now) / (1e3 * 60 * 60 * 24));
|
|
27501
|
-
if (daysRemaining < 365) {
|
|
27502
|
-
console.warn(
|
|
27503
|
-
`[recording-fetcher] SAS token in ARCHAL_FIXTURE_BASE_URL expires in ${daysRemaining}d (${seValue}). Rotate via scripts/rotate-fixture-sas.mjs before expiry.`
|
|
27504
|
-
);
|
|
27505
|
-
}
|
|
27506
|
-
}
|
|
27507
|
-
warnIfSasExpiresSoon(DEFAULT_BASE_URL);
|
|
27508
|
-
|
|
27509
27677
|
// ../packages/seedgen/src/codegen/executor.ts
|
|
27510
27678
|
var import_node_child_process2 = require("child_process");
|
|
27511
|
-
var
|
|
27679
|
+
var import_node_fs8 = require("fs");
|
|
27512
27680
|
var import_node_url3 = require("url");
|
|
27513
|
-
var
|
|
27681
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
27514
27682
|
var import_node_vm2 = __toESM(require("vm"), 1);
|
|
27515
27683
|
|
|
27516
27684
|
// ../packages/seedgen/src/codegen/builder-ids.ts
|
|
@@ -34457,15 +34625,15 @@ var import_node_vm = __toESM(require("vm"), 1);
|
|
|
34457
34625
|
var import_meta = {};
|
|
34458
34626
|
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
34459
34627
|
function resolveWorkerScriptPath() {
|
|
34460
|
-
const thisDir =
|
|
34628
|
+
const thisDir = import_node_path7.default.dirname((0, import_node_url3.fileURLToPath)(import_meta.url));
|
|
34461
34629
|
const candidates = [
|
|
34462
34630
|
// Source or unbundled output: executor.js and subprocess-worker.js live together.
|
|
34463
|
-
|
|
34631
|
+
import_node_path7.default.join(thisDir, "subprocess-worker.js"),
|
|
34464
34632
|
// tsup bundles executor into a root chunk while keeping the worker entry
|
|
34465
34633
|
// at dist/codegen/subprocess-worker.js.
|
|
34466
|
-
|
|
34634
|
+
import_node_path7.default.join(thisDir, "codegen", "subprocess-worker.js")
|
|
34467
34635
|
];
|
|
34468
|
-
return candidates.find((candidate) => (0,
|
|
34636
|
+
return candidates.find((candidate) => (0, import_node_fs8.existsSync)(candidate));
|
|
34469
34637
|
}
|
|
34470
34638
|
var workerScriptPath;
|
|
34471
34639
|
try {
|
|
@@ -34482,7 +34650,7 @@ async function executeSeedCodeIsolated(code, twinName, baseSeed, timeoutMs = DEF
|
|
|
34482
34650
|
"seedgen: subprocess worker script is unresolvable. Ensure the package is built before use."
|
|
34483
34651
|
);
|
|
34484
34652
|
}
|
|
34485
|
-
return new Promise((
|
|
34653
|
+
return new Promise((resolve6) => {
|
|
34486
34654
|
const child = (0, import_node_child_process2.fork)(workerScriptPath, {
|
|
34487
34655
|
// Silent: don't inherit parent stdout/stderr so worker crashes
|
|
34488
34656
|
// don't pollute the parent's output.
|
|
@@ -34507,28 +34675,28 @@ async function executeSeedCodeIsolated(code, twinName, baseSeed, timeoutMs = DEF
|
|
|
34507
34675
|
if (!resolved) {
|
|
34508
34676
|
resolved = true;
|
|
34509
34677
|
child.kill("SIGKILL");
|
|
34510
|
-
|
|
34678
|
+
resolve6({ ok: false, type: "timeout", message: `Subprocess timed out after ${timeoutMs}ms` });
|
|
34511
34679
|
}
|
|
34512
34680
|
}, timeoutMs + 2e3);
|
|
34513
34681
|
child.on("message", (msg) => {
|
|
34514
34682
|
if (!resolved) {
|
|
34515
34683
|
resolved = true;
|
|
34516
34684
|
clearTimeout(timer);
|
|
34517
|
-
|
|
34685
|
+
resolve6(msg);
|
|
34518
34686
|
}
|
|
34519
34687
|
});
|
|
34520
34688
|
child.on("error", (err) => {
|
|
34521
34689
|
if (!resolved) {
|
|
34522
34690
|
resolved = true;
|
|
34523
34691
|
clearTimeout(timer);
|
|
34524
|
-
|
|
34692
|
+
resolve6({ ok: false, type: "runtime", message: `Worker error: ${errorMessage2(err)}` });
|
|
34525
34693
|
}
|
|
34526
34694
|
});
|
|
34527
34695
|
child.on("exit", (exitCode) => {
|
|
34528
34696
|
if (!resolved) {
|
|
34529
34697
|
resolved = true;
|
|
34530
34698
|
clearTimeout(timer);
|
|
34531
|
-
|
|
34699
|
+
resolve6({
|
|
34532
34700
|
ok: false,
|
|
34533
34701
|
type: "runtime",
|
|
34534
34702
|
message: exitCode ? `Worker exited with code ${exitCode}` : "Worker exited unexpectedly"
|
|
@@ -35915,7 +36083,7 @@ function buildCodegenUserPrompt(twinName, setupDescription) {
|
|
|
35915
36083
|
const declarations = SDK_DECLARATIONS[twinName];
|
|
35916
36084
|
const example = SDK_EXAMPLES[twinName];
|
|
35917
36085
|
if (!declarations) {
|
|
35918
|
-
return `
|
|
36086
|
+
return `Clone: ${twinName}
|
|
35919
36087
|
|
|
35920
36088
|
Setup:
|
|
35921
36089
|
${setupDescription}
|
|
@@ -35936,7 +36104,7 @@ ${example.code}
|
|
|
35936
36104
|
`;
|
|
35937
36105
|
}
|
|
35938
36106
|
prompt += `## Task
|
|
35939
|
-
|
|
36107
|
+
Clone: ${twinName}
|
|
35940
36108
|
|
|
35941
36109
|
Setup:
|
|
35942
36110
|
${setupDescription}
|
|
@@ -35962,7 +36130,7 @@ ${originalCode}
|
|
|
35962
36130
|
Fix the code and output ONLY the corrected JavaScript. No explanations.`;
|
|
35963
36131
|
}
|
|
35964
36132
|
function buildSimplifiedCodegenPrompt(twinName, setupDescription) {
|
|
35965
|
-
return `Create seed data for the "${twinName}"
|
|
36133
|
+
return `Create seed data for the "${twinName}" clone.
|
|
35966
36134
|
|
|
35967
36135
|
Use ONLY these core functions (they are already defined globally):
|
|
35968
36136
|
createUser(login), createRepo/createProject/createChannel/createCustomer(name),
|
|
@@ -36117,7 +36285,7 @@ var TRANSIENT_AWS_EXCEPTIONS_PATTERN = /ThrottlingException|ServiceUnavailableEx
|
|
|
36117
36285
|
var STATUS_CODE_IN_MESSAGE_PATTERN = /\b(429|500|502|503|529)\b/;
|
|
36118
36286
|
var TRANSIENT_NETWORK_ERRORS_PATTERN = /ECONNRESET|ETIMEDOUT|EAI_AGAIN/i;
|
|
36119
36287
|
function defaultSleep(backoffMs) {
|
|
36120
|
-
return new Promise((
|
|
36288
|
+
return new Promise((resolve6) => setTimeout(resolve6, backoffMs));
|
|
36121
36289
|
}
|
|
36122
36290
|
function getServerHintedDelayMs(error48) {
|
|
36123
36291
|
if (error48 instanceof UpstreamApiError && typeof error48.retryAfterMs === "number" && error48.retryAfterMs >= 0) {
|
|
@@ -36724,7 +36892,7 @@ RULES:
|
|
|
36724
36892
|
- "3 active subscriptions" \u2192 ONE subscription entry with count:3
|
|
36725
36893
|
- Entity type names: user, org, team, repo, branch, issue, pr, label, milestone, release, webhook, workflow, environment, secret, code_scanning_alert, collaborator, project, page, branch_protection, board, sprint, epic, component, version, filter, dashboard, customer, product, price, subscription, invoice, payment_method, coupon, tax_rate, webhook_endpoint, charge, dispute, channel, message`;
|
|
36726
36894
|
function buildPlanPrompt(twinName, setupDescription) {
|
|
36727
|
-
return `
|
|
36895
|
+
return `Clone: ${twinName}
|
|
36728
36896
|
|
|
36729
36897
|
Setup:
|
|
36730
36898
|
${setupDescription}`;
|
|
@@ -37446,7 +37614,7 @@ function progress(message) {
|
|
|
37446
37614
|
}
|
|
37447
37615
|
|
|
37448
37616
|
// ../packages/seedgen/src/runner/seed/fill-templates.ts
|
|
37449
|
-
var
|
|
37617
|
+
var import_node_crypto12 = require("crypto");
|
|
37450
37618
|
function firstOf(seed, key) {
|
|
37451
37619
|
const arr = seed[key];
|
|
37452
37620
|
if (Array.isArray(arr) && arr.length > 0) {
|
|
@@ -38029,7 +38197,7 @@ var stripeWebhookEndpoints = (i, name, _d, _seed, _fk) => ({
|
|
|
38029
38197
|
url: `https://example.com/webhooks/stripe`,
|
|
38030
38198
|
enabledEvents: ["payment_intent.succeeded", "invoice.payment_succeeded"],
|
|
38031
38199
|
status: "enabled",
|
|
38032
|
-
secret: `whsec_${(0,
|
|
38200
|
+
secret: `whsec_${(0, import_node_crypto12.randomBytes)(24).toString("hex")}`,
|
|
38033
38201
|
description: name || null,
|
|
38034
38202
|
apiVersion: "2024-06-20",
|
|
38035
38203
|
livemode: false
|
|
@@ -42334,10 +42502,10 @@ function extractSeedIntent(twinName, setupDescription) {
|
|
|
42334
42502
|
}
|
|
42335
42503
|
|
|
42336
42504
|
// ../packages/seedgen/src/runner/seed/cache.ts
|
|
42337
|
-
var
|
|
42338
|
-
var
|
|
42339
|
-
var
|
|
42340
|
-
var
|
|
42505
|
+
var import_node_crypto13 = require("crypto");
|
|
42506
|
+
var import_node_fs9 = require("fs");
|
|
42507
|
+
var import_node_path8 = require("path");
|
|
42508
|
+
var import_node_os4 = require("os");
|
|
42341
42509
|
|
|
42342
42510
|
// ../packages/seedgen/src/evaluator/deterministic-state.ts
|
|
42343
42511
|
function flattenTwinState(state) {
|
|
@@ -42702,13 +42870,13 @@ function trimSeedToExpectedCounts(seed, mismatches) {
|
|
|
42702
42870
|
|
|
42703
42871
|
// ../packages/seedgen/src/runner/seed/cache.ts
|
|
42704
42872
|
var SEED_CACHE_VERSION = 6;
|
|
42705
|
-
var CACHE_DIR = (0,
|
|
42873
|
+
var CACHE_DIR = (0, import_node_path8.join)((0, import_node_os4.homedir)(), ".archal", "seed-cache");
|
|
42706
42874
|
var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
42707
42875
|
function normalizeSetupText(setupText) {
|
|
42708
42876
|
return setupText.toLowerCase().replace(/[^a-z0-9\s_/-]/g, " ").replace(/\s+/g, " ").trim();
|
|
42709
42877
|
}
|
|
42710
42878
|
function setupHash(normalizedSetup) {
|
|
42711
|
-
return (0,
|
|
42879
|
+
return (0, import_node_crypto13.createHash)("sha256").update(normalizedSetup).digest("hex").slice(0, 32);
|
|
42712
42880
|
}
|
|
42713
42881
|
function canonicalize(value) {
|
|
42714
42882
|
if (Array.isArray(value)) {
|
|
@@ -42725,7 +42893,7 @@ function canonicalize(value) {
|
|
|
42725
42893
|
return value;
|
|
42726
42894
|
}
|
|
42727
42895
|
function hashValue(value) {
|
|
42728
|
-
return (0,
|
|
42896
|
+
return (0, import_node_crypto13.createHash)("sha256").update(JSON.stringify(canonicalize(value))).digest("hex").slice(0, 32);
|
|
42729
42897
|
}
|
|
42730
42898
|
function resolveScopeHashes(scope) {
|
|
42731
42899
|
const contextHash = scope?.cacheContext === void 0 ? "none" : hashValue(scope.cacheContext);
|
|
@@ -42735,10 +42903,10 @@ function resolveScopeHashes(scope) {
|
|
|
42735
42903
|
function cacheFilePathScoped(twinName, baseSeedName, setupText, scope) {
|
|
42736
42904
|
const normalizedSetup = normalizeSetupText(setupText);
|
|
42737
42905
|
const { contextHash, baseSeedHash } = resolveScopeHashes(scope);
|
|
42738
|
-
const key = (0,
|
|
42906
|
+
const key = (0, import_node_crypto13.createHash)("sha256").update(`${twinName}:${baseSeedName}:${normalizedSetup}:${contextHash}:${baseSeedHash}`).digest("hex").slice(0, 32);
|
|
42739
42907
|
const intentHash = setupHash(normalizedSetup);
|
|
42740
42908
|
return {
|
|
42741
|
-
path: (0,
|
|
42909
|
+
path: (0, import_node_path8.join)(CACHE_DIR, `${key}.json`),
|
|
42742
42910
|
key,
|
|
42743
42911
|
normalizedSetup,
|
|
42744
42912
|
intentHash,
|
|
@@ -42747,25 +42915,25 @@ function cacheFilePathScoped(twinName, baseSeedName, setupText, scope) {
|
|
|
42747
42915
|
};
|
|
42748
42916
|
}
|
|
42749
42917
|
function ensureCacheDir() {
|
|
42750
|
-
if (!(0,
|
|
42751
|
-
(0,
|
|
42918
|
+
if (!(0, import_node_fs9.existsSync)(CACHE_DIR)) {
|
|
42919
|
+
(0, import_node_fs9.mkdirSync)(CACHE_DIR, { recursive: true });
|
|
42752
42920
|
}
|
|
42753
42921
|
}
|
|
42754
42922
|
function evictStaleEntries() {
|
|
42755
42923
|
try {
|
|
42756
|
-
if (!(0,
|
|
42924
|
+
if (!(0, import_node_fs9.existsSync)(CACHE_DIR)) return;
|
|
42757
42925
|
const now = Date.now();
|
|
42758
|
-
for (const file2 of (0,
|
|
42926
|
+
for (const file2 of (0, import_node_fs9.readdirSync)(CACHE_DIR)) {
|
|
42759
42927
|
if (!file2.endsWith(".json")) continue;
|
|
42760
|
-
const filePath = (0,
|
|
42761
|
-
const stat = (0,
|
|
42928
|
+
const filePath = (0, import_node_path8.join)(CACHE_DIR, file2);
|
|
42929
|
+
const stat = (0, import_node_fs9.lstatSync)(filePath);
|
|
42762
42930
|
if (stat.isSymbolicLink()) {
|
|
42763
42931
|
debug3("Skipping symlink during cache eviction", { file: file2 });
|
|
42764
42932
|
continue;
|
|
42765
42933
|
}
|
|
42766
42934
|
const age = now - stat.mtimeMs;
|
|
42767
42935
|
if (age > MAX_AGE_MS) {
|
|
42768
|
-
(0,
|
|
42936
|
+
(0, import_node_fs9.unlinkSync)(filePath);
|
|
42769
42937
|
debug3("Evicted stale cache entry", { file: file2 });
|
|
42770
42938
|
}
|
|
42771
42939
|
}
|
|
@@ -42779,7 +42947,7 @@ function getCachedSeed(twinName, baseSeedName, setupText, scope) {
|
|
|
42779
42947
|
const { path: filePath, key } = cacheFilePathScoped(twinName, baseSeedName, setupText, scope);
|
|
42780
42948
|
let raw;
|
|
42781
42949
|
try {
|
|
42782
|
-
raw = (0,
|
|
42950
|
+
raw = (0, import_node_fs9.readFileSync)(filePath, "utf-8");
|
|
42783
42951
|
} catch {
|
|
42784
42952
|
return null;
|
|
42785
42953
|
}
|
|
@@ -42787,7 +42955,7 @@ function getCachedSeed(twinName, baseSeedName, setupText, scope) {
|
|
|
42787
42955
|
if (entry.version !== SEED_CACHE_VERSION) {
|
|
42788
42956
|
warn2(`Seed cache version mismatch (got ${entry.version}, want ${SEED_CACHE_VERSION}), evicting`);
|
|
42789
42957
|
try {
|
|
42790
|
-
(0,
|
|
42958
|
+
(0, import_node_fs9.unlinkSync)(filePath);
|
|
42791
42959
|
} catch {
|
|
42792
42960
|
}
|
|
42793
42961
|
return null;
|
|
@@ -42798,7 +42966,7 @@ function getCachedSeed(twinName, baseSeedName, setupText, scope) {
|
|
|
42798
42966
|
`Cached seed failed count verification, evicting: ${mismatches.map((m) => `${m.subject}: expected ${m.expected}, got ${m.actual}`).join("; ")}`
|
|
42799
42967
|
);
|
|
42800
42968
|
try {
|
|
42801
|
-
(0,
|
|
42969
|
+
(0, import_node_fs9.unlinkSync)(filePath);
|
|
42802
42970
|
} catch {
|
|
42803
42971
|
}
|
|
42804
42972
|
return null;
|
|
@@ -42850,8 +43018,8 @@ function cacheSeed(twinName, baseSeedName, setupText, seed, patch, scope, genera
|
|
|
42850
43018
|
...generatedCode !== void 0 && { generatedCode }
|
|
42851
43019
|
};
|
|
42852
43020
|
const tmpPath = `${filePath}.tmp`;
|
|
42853
|
-
(0,
|
|
42854
|
-
(0,
|
|
43021
|
+
(0, import_node_fs9.writeFileSync)(tmpPath, JSON.stringify(entry));
|
|
43022
|
+
(0, import_node_fs9.renameSync)(tmpPath, filePath);
|
|
42855
43023
|
debug3("Seed cached", { twin: twinName, baseSeed: baseSeedName, key });
|
|
42856
43024
|
} catch (err) {
|
|
42857
43025
|
warn2(`Failed to write seed cache entry: ${errorMessage2(err)}`);
|
|
@@ -42874,6 +43042,8 @@ IMPORTANT CONSTRAINTS:
|
|
|
42874
43042
|
- For RLS policies, use simple expressions like: USING (true) or USING (current_setting('app.user_id')::int = user_id)
|
|
42875
43043
|
- Use serial or bigserial for primary keys, not uuid (unless explicitly asked)
|
|
42876
43044
|
- Use simple types: text, int, boolean, timestamptz
|
|
43045
|
+
- Do NOT use JSON-style array literals like ["a", "b"] in INSERT values.
|
|
43046
|
+
Use ARRAY['a', 'b'] for SQL array columns, or quoted JSON with ::jsonb for jsonb columns.
|
|
42877
43047
|
- Always include INSERT statements with realistic test data
|
|
42878
43048
|
|
|
42879
43049
|
|
|
@@ -42894,6 +43064,222 @@ INSERT INTO users (email, name, role) VALUES
|
|
|
42894
43064
|
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
|
|
42895
43065
|
CREATE POLICY "users_select" ON users FOR SELECT USING (true);
|
|
42896
43066
|
CREATE POLICY "users_update_own" ON users FOR UPDATE USING (id = current_setting('app.user_id', true)::int);`;
|
|
43067
|
+
function sqlLiteral2(value) {
|
|
43068
|
+
if (value === null || value === void 0) return "NULL";
|
|
43069
|
+
if (typeof value === "number") return Number.isFinite(value) ? String(value) : "NULL";
|
|
43070
|
+
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
43071
|
+
return `'${String(value).replace(/'/g, "''")}'`;
|
|
43072
|
+
}
|
|
43073
|
+
function sqlIdent2(value) {
|
|
43074
|
+
if (!value) throw new Error("SQL identifier must not be empty");
|
|
43075
|
+
if (value.includes("\0")) throw new Error("SQL identifier must not contain null bytes");
|
|
43076
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
43077
|
+
}
|
|
43078
|
+
function sqlValueLiteral(value, columnType) {
|
|
43079
|
+
const type = columnType?.toLowerCase() ?? "";
|
|
43080
|
+
if (Array.isArray(value)) {
|
|
43081
|
+
if (type.includes("[]")) {
|
|
43082
|
+
const baseType = type.replace(/\[\].*$/, "") || "text";
|
|
43083
|
+
if (value.length === 0) return `ARRAY[]::${baseType}[]`;
|
|
43084
|
+
return `ARRAY[${value.map(sqlLiteral2).join(", ")}]`;
|
|
43085
|
+
}
|
|
43086
|
+
const json2 = sqlLiteral2(JSON.stringify(value));
|
|
43087
|
+
if (type.includes("jsonb")) return `${json2}::jsonb`;
|
|
43088
|
+
if (type.includes("json")) return `${json2}::json`;
|
|
43089
|
+
return json2;
|
|
43090
|
+
}
|
|
43091
|
+
if (value && typeof value === "object") {
|
|
43092
|
+
const json2 = sqlLiteral2(JSON.stringify(value));
|
|
43093
|
+
if (type.includes("jsonb")) return `${json2}::jsonb`;
|
|
43094
|
+
if (type.includes("json")) return `${json2}::json`;
|
|
43095
|
+
return json2;
|
|
43096
|
+
}
|
|
43097
|
+
return sqlLiteral2(value);
|
|
43098
|
+
}
|
|
43099
|
+
function splitSqlTopLevel(input, separator) {
|
|
43100
|
+
const parts = [];
|
|
43101
|
+
let depth = 0;
|
|
43102
|
+
let bracketDepth = 0;
|
|
43103
|
+
let inQuote = false;
|
|
43104
|
+
let start = 0;
|
|
43105
|
+
for (let i = 0; i < input.length; i++) {
|
|
43106
|
+
const ch = input[i];
|
|
43107
|
+
if (ch === void 0) continue;
|
|
43108
|
+
const next = i + 1 < input.length ? input[i + 1] : void 0;
|
|
43109
|
+
if (ch === "'") {
|
|
43110
|
+
if (inQuote && next === "'") {
|
|
43111
|
+
i += 1;
|
|
43112
|
+
continue;
|
|
43113
|
+
}
|
|
43114
|
+
inQuote = !inQuote;
|
|
43115
|
+
continue;
|
|
43116
|
+
}
|
|
43117
|
+
if (inQuote) continue;
|
|
43118
|
+
if (ch === "(") depth += 1;
|
|
43119
|
+
else if (ch === ")") depth = Math.max(0, depth - 1);
|
|
43120
|
+
else if (ch === "[") bracketDepth += 1;
|
|
43121
|
+
else if (ch === "]") bracketDepth = Math.max(0, bracketDepth - 1);
|
|
43122
|
+
if (depth === 0 && bracketDepth === 0 && ch === separator) {
|
|
43123
|
+
parts.push(input.slice(start, i).trim());
|
|
43124
|
+
start = i + 1;
|
|
43125
|
+
}
|
|
43126
|
+
}
|
|
43127
|
+
const tail = input.slice(start).trim();
|
|
43128
|
+
if (tail) parts.push(tail);
|
|
43129
|
+
return parts;
|
|
43130
|
+
}
|
|
43131
|
+
function splitSqlStatements(sql) {
|
|
43132
|
+
return splitSqlTopLevel(sql, ";").map((statement) => statement.trim()).filter(Boolean);
|
|
43133
|
+
}
|
|
43134
|
+
function normalizeSqlIdentifier(raw) {
|
|
43135
|
+
const parts = raw.split(".").map((part) => part.trim().replace(/^"|"$/g, "").replace(/""/g, '"')).filter(Boolean);
|
|
43136
|
+
return parts[parts.length - 1] ?? raw.trim();
|
|
43137
|
+
}
|
|
43138
|
+
function collectTableSchemas(sql) {
|
|
43139
|
+
const tableSchemas = /* @__PURE__ */ new Map();
|
|
43140
|
+
for (const statement of splitSqlStatements(sql)) {
|
|
43141
|
+
const match = statement.match(
|
|
43142
|
+
/^CREATE\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?\s+([^\s(]+)\s*\(([\s\S]*)\)$/i
|
|
43143
|
+
);
|
|
43144
|
+
if (!match?.[1] || !match[2]) continue;
|
|
43145
|
+
const columnTypes = /* @__PURE__ */ new Map();
|
|
43146
|
+
const columnOrder = [];
|
|
43147
|
+
for (const columnDef of splitSqlTopLevel(match[2], ",")) {
|
|
43148
|
+
const columnMatch = columnDef.trim().match(/^("(?:""|[^"])+"|[a-zA-Z_][a-zA-Z0-9_]*)\s+([a-zA-Z0-9_."[\]]+)/);
|
|
43149
|
+
if (!columnMatch?.[1] || !columnMatch[2]) continue;
|
|
43150
|
+
const columnName = normalizeSqlIdentifier(columnMatch[1]);
|
|
43151
|
+
columnTypes.set(columnName, columnMatch[2].toLowerCase());
|
|
43152
|
+
columnOrder.push(columnName);
|
|
43153
|
+
}
|
|
43154
|
+
tableSchemas.set(normalizeSqlIdentifier(match[1]), { columnTypes, columnOrder });
|
|
43155
|
+
}
|
|
43156
|
+
return tableSchemas;
|
|
43157
|
+
}
|
|
43158
|
+
function normalizeJsonArrayLiteral(value, columnType) {
|
|
43159
|
+
const trimmed = value.trim();
|
|
43160
|
+
if (!trimmed.startsWith("[") || !trimmed.endsWith("]")) return value;
|
|
43161
|
+
let parsed;
|
|
43162
|
+
try {
|
|
43163
|
+
parsed = JSON.parse(trimmed);
|
|
43164
|
+
} catch {
|
|
43165
|
+
return value;
|
|
43166
|
+
}
|
|
43167
|
+
if (!Array.isArray(parsed)) return value;
|
|
43168
|
+
const type = columnType?.toLowerCase() ?? "";
|
|
43169
|
+
if (type.includes("[]")) {
|
|
43170
|
+
const baseType = type.replace(/\[\].*$/, "") || "text";
|
|
43171
|
+
if (parsed.length === 0) return `ARRAY[]::${baseType}[]`;
|
|
43172
|
+
return `ARRAY[${parsed.map(sqlLiteral2).join(", ")}]`;
|
|
43173
|
+
}
|
|
43174
|
+
const json2 = sqlLiteral2(JSON.stringify(parsed));
|
|
43175
|
+
if (type.includes("jsonb")) return `${json2}::jsonb`;
|
|
43176
|
+
if (type.includes("json")) return `${json2}::json`;
|
|
43177
|
+
return json2;
|
|
43178
|
+
}
|
|
43179
|
+
function renderStructuredTableSql(value) {
|
|
43180
|
+
const tables = Array.isArray(value) ? value : value && typeof value === "object" && Array.isArray(value["tables"]) ? value["tables"] : null;
|
|
43181
|
+
if (!Array.isArray(tables)) return null;
|
|
43182
|
+
const statements = [];
|
|
43183
|
+
for (const table of tables) {
|
|
43184
|
+
if (!table || typeof table !== "object") return null;
|
|
43185
|
+
const record2 = table;
|
|
43186
|
+
const tableName = typeof record2["name"] === "string" ? record2["name"] : void 0;
|
|
43187
|
+
const columns = Array.isArray(record2["columns"]) ? record2["columns"] : void 0;
|
|
43188
|
+
if (!tableName || !columns) return null;
|
|
43189
|
+
const columnTypes = /* @__PURE__ */ new Map();
|
|
43190
|
+
const columnDefinitions = columns.map((column) => {
|
|
43191
|
+
if (!column || typeof column !== "object") throw new Error("invalid column");
|
|
43192
|
+
const columnRecord = column;
|
|
43193
|
+
const name = typeof columnRecord["name"] === "string" ? columnRecord["name"] : void 0;
|
|
43194
|
+
const rawType = typeof columnRecord["type"] === "string" ? columnRecord["type"] : "text";
|
|
43195
|
+
if (!name) throw new Error("invalid column name");
|
|
43196
|
+
const isPrimary = columnRecord["is_primary"] === true || columnRecord["primary"] === true;
|
|
43197
|
+
const type = isPrimary && /^(bigint|int|integer|serial|bigserial)$/i.test(rawType) ? "bigserial" : rawType;
|
|
43198
|
+
columnTypes.set(name, type);
|
|
43199
|
+
return `${sqlIdent2(name)} ${type}${isPrimary ? " PRIMARY KEY" : ""}`;
|
|
43200
|
+
});
|
|
43201
|
+
statements.push(`CREATE TABLE IF NOT EXISTS public.${sqlIdent2(tableName)} (${columnDefinitions.join(", ")});`);
|
|
43202
|
+
const rows = Array.isArray(record2["rows"]) ? record2["rows"] : Array.isArray(record2["data"]) ? record2["data"] : [];
|
|
43203
|
+
for (const row of rows) {
|
|
43204
|
+
if (!row || typeof row !== "object") continue;
|
|
43205
|
+
const entries = Object.entries(row).filter(([column]) => columnTypes.has(column));
|
|
43206
|
+
if (entries.length === 0) continue;
|
|
43207
|
+
statements.push(
|
|
43208
|
+
`INSERT INTO public.${sqlIdent2(tableName)} (${entries.map(([column]) => sqlIdent2(column)).join(", ")}) VALUES (${entries.map(([column, rowValue]) => sqlValueLiteral(rowValue, columnTypes.get(column))).join(", ")});`
|
|
43209
|
+
);
|
|
43210
|
+
}
|
|
43211
|
+
}
|
|
43212
|
+
return statements.length > 0 ? statements.join("\n\n") : null;
|
|
43213
|
+
}
|
|
43214
|
+
function normalizeCreateTableStatement(statement) {
|
|
43215
|
+
const match = statement.match(
|
|
43216
|
+
/^(CREATE\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?\s+[^\s(]+\s*)\(([\s\S]*)\)$/i
|
|
43217
|
+
);
|
|
43218
|
+
if (!match?.[1] || !match[2]) return statement;
|
|
43219
|
+
const columnDefs = splitSqlTopLevel(match[2], ",").map((columnDef) => {
|
|
43220
|
+
const columnMatch = columnDef.trim().match(
|
|
43221
|
+
/^("(?:""|[^"])+"|[a-zA-Z_][a-zA-Z0-9_]*)\s+([a-zA-Z0-9_."[\]]+)([\s\S]*)$/i
|
|
43222
|
+
);
|
|
43223
|
+
if (!columnMatch?.[2] || !columnMatch[3]) return columnDef;
|
|
43224
|
+
const columnType = columnMatch[2].toLowerCase();
|
|
43225
|
+
const rest = columnMatch[3].replace(
|
|
43226
|
+
/\bDEFAULT\s+(\[[\s\S]*?\])(?=\s|,|$)/i,
|
|
43227
|
+
(_full, value) => `DEFAULT ${normalizeJsonArrayLiteral(value, columnType)}`
|
|
43228
|
+
);
|
|
43229
|
+
return `${columnMatch[1]} ${columnMatch[2]}${rest}`;
|
|
43230
|
+
});
|
|
43231
|
+
return `${match[1]}(${columnDefs.join(", ")})`;
|
|
43232
|
+
}
|
|
43233
|
+
function normalizeSupabaseSql(sql) {
|
|
43234
|
+
const tableSchemas = collectTableSchemas(sql);
|
|
43235
|
+
return splitSqlStatements(sql).map((statement) => {
|
|
43236
|
+
if (/^CREATE\s+TABLE/i.test(statement)) return normalizeCreateTableStatement(statement);
|
|
43237
|
+
const match = statement.match(/^INSERT\s+INTO\s+([^\s(]+)\s*\(([^)]+)\)\s*VALUES\s*([\s\S]*)$/i) ?? statement.match(/^INSERT\s+INTO\s+([^\s(]+)\s+VALUES\s*([\s\S]*)$/i);
|
|
43238
|
+
if (!match?.[1]) return statement;
|
|
43239
|
+
const tableName = normalizeSqlIdentifier(match[1]);
|
|
43240
|
+
const hasColumnList = match.length === 4;
|
|
43241
|
+
const valuesSql = hasColumnList ? match[3] : match[2];
|
|
43242
|
+
if (!valuesSql) return statement;
|
|
43243
|
+
const schema = tableSchemas.get(tableName);
|
|
43244
|
+
const columns = hasColumnList ? splitSqlTopLevel(match[2] ?? "", ",").map(normalizeSqlIdentifier) : schema?.columnOrder ?? [];
|
|
43245
|
+
const tuples = [];
|
|
43246
|
+
let depth = 0;
|
|
43247
|
+
let bracketDepth = 0;
|
|
43248
|
+
let inQuote = false;
|
|
43249
|
+
let tupleStart = -1;
|
|
43250
|
+
for (let i = 0; i < valuesSql.length; i++) {
|
|
43251
|
+
const ch = valuesSql[i];
|
|
43252
|
+
if (ch === void 0) continue;
|
|
43253
|
+
const next = i + 1 < valuesSql.length ? valuesSql[i + 1] : void 0;
|
|
43254
|
+
if (ch === "'") {
|
|
43255
|
+
if (inQuote && next === "'") {
|
|
43256
|
+
i += 1;
|
|
43257
|
+
continue;
|
|
43258
|
+
}
|
|
43259
|
+
inQuote = !inQuote;
|
|
43260
|
+
}
|
|
43261
|
+
if (inQuote) continue;
|
|
43262
|
+
if (ch === "[") bracketDepth += 1;
|
|
43263
|
+
else if (ch === "]") bracketDepth = Math.max(0, bracketDepth - 1);
|
|
43264
|
+
else if (ch === "(" && bracketDepth === 0) {
|
|
43265
|
+
if (depth === 0) tupleStart = i + 1;
|
|
43266
|
+
depth += 1;
|
|
43267
|
+
} else if (ch === ")" && bracketDepth === 0) {
|
|
43268
|
+
depth -= 1;
|
|
43269
|
+
if (depth === 0 && tupleStart >= 0) {
|
|
43270
|
+
tuples.push(valuesSql.slice(tupleStart, i));
|
|
43271
|
+
tupleStart = -1;
|
|
43272
|
+
}
|
|
43273
|
+
}
|
|
43274
|
+
}
|
|
43275
|
+
if (tuples.length === 0) return statement;
|
|
43276
|
+
const normalizedTuples = tuples.map((tuple2) => {
|
|
43277
|
+
const values = splitSqlTopLevel(tuple2, ",").map((value, index) => normalizeJsonArrayLiteral(value, schema?.columnTypes.get(columns[index] ?? "")));
|
|
43278
|
+
return `(${values.join(", ")})`;
|
|
43279
|
+
});
|
|
43280
|
+
return hasColumnList ? `INSERT INTO ${match[1]} (${match[2]}) VALUES ${normalizedTuples.join(", ")}` : `INSERT INTO ${match[1]} VALUES ${normalizedTuples.join(", ")}`;
|
|
43281
|
+
}).join(";\n") + ";";
|
|
43282
|
+
}
|
|
42897
43283
|
function extractSupabaseSql(response) {
|
|
42898
43284
|
let sql = response.trim();
|
|
42899
43285
|
if (sql.startsWith("```")) {
|
|
@@ -42902,24 +43288,35 @@ function extractSupabaseSql(response) {
|
|
|
42902
43288
|
if (sql.startsWith("{")) {
|
|
42903
43289
|
try {
|
|
42904
43290
|
const parsed = JSON.parse(sql);
|
|
43291
|
+
const structuredSql = renderStructuredTableSql(parsed);
|
|
43292
|
+
if (structuredSql) return normalizeSupabaseSql(structuredSql);
|
|
42905
43293
|
const extracted = parsed["sql"] ?? parsed["query"] ?? parsed["script"] ?? parsed["content"];
|
|
42906
|
-
if (extracted && typeof extracted === "string") return extracted;
|
|
43294
|
+
if (extracted && typeof extracted === "string") return normalizeSupabaseSql(extracted);
|
|
43295
|
+
} catch {
|
|
43296
|
+
}
|
|
43297
|
+
}
|
|
43298
|
+
if (sql.startsWith('"')) {
|
|
43299
|
+
try {
|
|
43300
|
+
const parsed = JSON.parse(sql);
|
|
43301
|
+
if (typeof parsed === "string") return normalizeSupabaseSql(parsed);
|
|
42907
43302
|
} catch {
|
|
42908
43303
|
}
|
|
42909
43304
|
}
|
|
42910
43305
|
if (sql.startsWith("[")) {
|
|
42911
43306
|
try {
|
|
42912
43307
|
const parsed = JSON.parse(sql);
|
|
43308
|
+
const structuredSql = renderStructuredTableSql(parsed);
|
|
43309
|
+
if (structuredSql) return normalizeSupabaseSql(structuredSql);
|
|
42913
43310
|
const parts = [];
|
|
42914
43311
|
for (const item of parsed) {
|
|
42915
43312
|
const s = item["sql"] ?? item["query"] ?? item["script"];
|
|
42916
43313
|
if (s && typeof s === "string") parts.push(s);
|
|
42917
43314
|
}
|
|
42918
|
-
if (parts.length > 0) return parts.join("\n\n");
|
|
43315
|
+
if (parts.length > 0) return normalizeSupabaseSql(parts.join("\n\n"));
|
|
42919
43316
|
} catch {
|
|
42920
43317
|
}
|
|
42921
43318
|
}
|
|
42922
|
-
return sql;
|
|
43319
|
+
return normalizeSupabaseSql(sql);
|
|
42923
43320
|
}
|
|
42924
43321
|
|
|
42925
43322
|
// ../packages/seedgen/src/runtime/session-context.ts
|
|
@@ -43264,7 +43661,7 @@ async function enrichSeedWithLlm(seed, twinName, setupDescription, deadline, coo
|
|
|
43264
43661
|
try {
|
|
43265
43662
|
const response = await callCodegenLlm({
|
|
43266
43663
|
systemPrompt: ENRICH_SYSTEM_PROMPT,
|
|
43267
|
-
userPrompt: `
|
|
43664
|
+
userPrompt: `Clone: ${twinName}
|
|
43268
43665
|
|
|
43269
43666
|
Setup description:
|
|
43270
43667
|
${setupDescription}
|
|
@@ -43285,7 +43682,7 @@ ${snapshot}${buildFewShotExample(twinName)}`,
|
|
|
43285
43682
|
}
|
|
43286
43683
|
|
|
43287
43684
|
// ../packages/seedgen/src/runner/seed/key-fixer.ts
|
|
43288
|
-
var
|
|
43685
|
+
var import_node_crypto14 = require("crypto");
|
|
43289
43686
|
function parseIssueKey(value) {
|
|
43290
43687
|
const match = value.match(/^([A-Z]{2,})-(\d+)$/);
|
|
43291
43688
|
if (!match || !match[1] || !match[2]) return null;
|
|
@@ -43551,7 +43948,7 @@ function fixIssueKeys(seed, intent, twinName, options) {
|
|
|
43551
43948
|
newIssue[issueKeyField] = expectedKey;
|
|
43552
43949
|
newIssue[fkField] = projectId;
|
|
43553
43950
|
if (isLinear) {
|
|
43554
|
-
newIssue["linearId"] = (0,
|
|
43951
|
+
newIssue["linearId"] = (0, import_node_crypto14.randomUUID)();
|
|
43555
43952
|
newIssue["title"] = `Issue ${expectedKey}`;
|
|
43556
43953
|
} else {
|
|
43557
43954
|
newIssue["summary"] = `Issue ${expectedKey}`;
|
|
@@ -44442,6 +44839,10 @@ var GOOGLE_WORKSPACE_BOOTSTRAP_SCOPES = [
|
|
|
44442
44839
|
"https://www.googleapis.com/auth/drive.readonly",
|
|
44443
44840
|
"https://www.googleapis.com/auth/contacts.readonly"
|
|
44444
44841
|
];
|
|
44842
|
+
var GOOGLE_WORKSPACE_SYNTHETIC_EMAIL = "self@local.invalid";
|
|
44843
|
+
function isSyntheticGoogleWorkspaceEmail(email3) {
|
|
44844
|
+
return email3 === GOOGLE_WORKSPACE_SYNTHETIC_EMAIL;
|
|
44845
|
+
}
|
|
44445
44846
|
function googleWorkspaceEmailEntities(intent) {
|
|
44446
44847
|
if (!intent || intent.twinName !== "google-workspace") return [];
|
|
44447
44848
|
return intent.entities.filter((entity) => entity.kind === "email" && entity.key === "address" && typeof entity.value === "string" || entity.kind === "account" && entity.key === "email" && typeof entity.value === "string").map((entity) => normalizedEmail(entity.value)).filter((value) => Boolean(value));
|
|
@@ -44469,6 +44870,32 @@ function googleWorkspaceReferencedEmails(seed) {
|
|
|
44469
44870
|
}
|
|
44470
44871
|
return emails;
|
|
44471
44872
|
}
|
|
44873
|
+
function googleWorkspaceBootstrapEmail(intentEmails, referencedEmails) {
|
|
44874
|
+
return intentEmails.find((email3) => !isSyntheticGoogleWorkspaceEmail(email3)) ?? referencedEmails.find((email3) => !isSyntheticGoogleWorkspaceEmail(email3)) ?? "user@example.com";
|
|
44875
|
+
}
|
|
44876
|
+
function rewriteSyntheticGoogleWorkspaceAccountRefs(seed, email3) {
|
|
44877
|
+
const collections = [
|
|
44878
|
+
"calendars",
|
|
44879
|
+
"calendarEvents",
|
|
44880
|
+
"gmailThreads",
|
|
44881
|
+
"gmailMessages",
|
|
44882
|
+
"gmailDrafts",
|
|
44883
|
+
"gmailAttachments",
|
|
44884
|
+
"gmailHistory",
|
|
44885
|
+
"driveFiles",
|
|
44886
|
+
"contacts",
|
|
44887
|
+
"googleAuthTokens"
|
|
44888
|
+
];
|
|
44889
|
+
for (const collection of collections) {
|
|
44890
|
+
for (const item of seed[collection] ?? []) {
|
|
44891
|
+
const record2 = asRecord(item);
|
|
44892
|
+
if (!record2) continue;
|
|
44893
|
+
if (isSyntheticGoogleWorkspaceEmail(normalizedEmail(record2["accountEmail"]))) {
|
|
44894
|
+
record2["accountEmail"] = email3;
|
|
44895
|
+
}
|
|
44896
|
+
}
|
|
44897
|
+
}
|
|
44898
|
+
}
|
|
44472
44899
|
function googleWorkspaceHasCalendarSurface(intent) {
|
|
44473
44900
|
return intent.extractedSlots["workspace.surface.calendar"] === true || /\b(calendar|event|events|meeting|meetings|invite|invites)\b/i.test(intent.setupSummary);
|
|
44474
44901
|
}
|
|
@@ -44503,6 +44930,15 @@ function ensureGoogleWorkspaceAccount(accounts, email3, primary) {
|
|
|
44503
44930
|
primary
|
|
44504
44931
|
});
|
|
44505
44932
|
}
|
|
44933
|
+
function replaceGoogleWorkspaceAccount(account, email3) {
|
|
44934
|
+
account["accountId"] = "acct_primary";
|
|
44935
|
+
account["email"] = email3;
|
|
44936
|
+
account["displayName"] = "Primary Account";
|
|
44937
|
+
account["givenName"] = "Primary";
|
|
44938
|
+
account["familyName"] = "Account";
|
|
44939
|
+
account["timezone"] = "America/Los_Angeles";
|
|
44940
|
+
account["primary"] = true;
|
|
44941
|
+
}
|
|
44506
44942
|
function ensureGoogleWorkspaceAuthToken(authTokens, email3) {
|
|
44507
44943
|
if (authTokens.some((token) => normalizedEmail(token["accountEmail"]) === email3)) return;
|
|
44508
44944
|
const localPart = email3.split("@")[0] ?? email3;
|
|
@@ -44522,7 +44958,8 @@ function ensureGoogleWorkspaceAuthToken(authTokens, email3) {
|
|
|
44522
44958
|
function ensureGoogleWorkspacePrimaryCalendar(calendars, accountEmail) {
|
|
44523
44959
|
const existingPrimary = calendars.find((calendar) => calendar["calendarId"] === "primary");
|
|
44524
44960
|
if (existingPrimary) {
|
|
44525
|
-
|
|
44961
|
+
const existingEmail = normalizedEmail(existingPrimary["accountEmail"]);
|
|
44962
|
+
existingPrimary["accountEmail"] = !existingEmail || isSyntheticGoogleWorkspaceEmail(existingEmail) ? accountEmail : existingEmail;
|
|
44526
44963
|
existingPrimary["primary"] = true;
|
|
44527
44964
|
return "primary";
|
|
44528
44965
|
}
|
|
@@ -44547,6 +44984,15 @@ function ensureGoogleWorkspaceCalendarRows(mergedSeed) {
|
|
|
44547
44984
|
for (const item of mergedSeed["calendarEvents"] ?? []) {
|
|
44548
44985
|
const event = asRecord(item);
|
|
44549
44986
|
if (!event) continue;
|
|
44987
|
+
if (typeof event["summary"] !== "string") {
|
|
44988
|
+
event["summary"] = "Calendar event";
|
|
44989
|
+
}
|
|
44990
|
+
if (typeof event["description"] !== "string") {
|
|
44991
|
+
event["description"] = "";
|
|
44992
|
+
}
|
|
44993
|
+
if (typeof event["location"] !== "string") {
|
|
44994
|
+
event["location"] = "";
|
|
44995
|
+
}
|
|
44550
44996
|
const calendarId = typeof event["calendarId"] === "string" && event["calendarId"].trim() ? event["calendarId"].trim() : "primary";
|
|
44551
44997
|
const accountEmail = normalizedEmail(event["accountEmail"]) ?? "self@local.invalid";
|
|
44552
44998
|
if (existingCalendarIds.has(calendarId)) continue;
|
|
@@ -44586,21 +45032,28 @@ function ensureGoogleWorkspaceCalendarEvidence(mergedSeed, intent, accountEmail)
|
|
|
44586
45032
|
organizerEmail: accountEmail,
|
|
44587
45033
|
attendeeEmails: [],
|
|
44588
45034
|
conferenceUrl: null,
|
|
44589
|
-
extendedPropertiesShared:
|
|
45035
|
+
extendedPropertiesShared: {}
|
|
44590
45036
|
});
|
|
44591
45037
|
}
|
|
44592
45038
|
function ensureGoogleWorkspaceScenarioAccounts(mergedSeed, intent) {
|
|
44593
45039
|
if (!intent || intent.twinName !== "google-workspace") return mergedSeed;
|
|
44594
45040
|
const accounts = ensureArray(mergedSeed, "accounts");
|
|
44595
45041
|
const authTokens = ensureArray(mergedSeed, "googleAuthTokens");
|
|
45042
|
+
const intentEmails = googleWorkspaceEmailEntities(intent);
|
|
45043
|
+
let referencedEmails = googleWorkspaceReferencedEmails(mergedSeed);
|
|
45044
|
+
const bootstrapEmail = googleWorkspaceBootstrapEmail(intentEmails, referencedEmails);
|
|
44596
45045
|
if (accounts.length === 0) {
|
|
44597
|
-
ensureGoogleWorkspaceAccount(accounts,
|
|
45046
|
+
ensureGoogleWorkspaceAccount(accounts, bootstrapEmail, true);
|
|
45047
|
+
} else if (accounts.length === 1 && isSyntheticGoogleWorkspaceEmail(normalizedEmail(accounts[0]?.["email"]))) {
|
|
45048
|
+
replaceGoogleWorkspaceAccount(accounts[0], bootstrapEmail);
|
|
44598
45049
|
}
|
|
44599
|
-
|
|
45050
|
+
rewriteSyntheticGoogleWorkspaceAccountRefs(mergedSeed, bootstrapEmail);
|
|
45051
|
+
referencedEmails = googleWorkspaceReferencedEmails(mergedSeed);
|
|
45052
|
+
const primaryEmail = normalizedEmail(accounts.find((account) => account["primary"] === true)?.["email"]) ?? normalizedEmail(accounts[0]?.["email"]) ?? GOOGLE_WORKSPACE_SYNTHETIC_EMAIL;
|
|
44600
45053
|
ensureGoogleWorkspaceAuthToken(authTokens, primaryEmail);
|
|
44601
45054
|
const requiredEmails = Array.from(/* @__PURE__ */ new Set([
|
|
44602
|
-
...
|
|
44603
|
-
...
|
|
45055
|
+
...intentEmails,
|
|
45056
|
+
...referencedEmails,
|
|
44604
45057
|
...accounts.map((account) => normalizedEmail(account["email"])).filter((value) => Boolean(value))
|
|
44605
45058
|
]));
|
|
44606
45059
|
for (const email3 of requiredEmails) {
|
|
@@ -44627,7 +45080,7 @@ var DynamicSeedError = class extends Error {
|
|
|
44627
45080
|
const details = validationErrors.length > 0 ? `:
|
|
44628
45081
|
${validationErrors.map((e) => ` - ${e}`).join("\n")}` : ".";
|
|
44629
45082
|
const suffix = hint ?? "\n\nHint: Run `archal login` and retry. For deterministic reruns, use `--replay-seed <path>` with a previously saved managed seed snapshot.";
|
|
44630
|
-
super(`Dynamic seed generation failed for
|
|
45083
|
+
super(`Dynamic seed generation failed for clone "${twinName}"${details}${suffix}`);
|
|
44631
45084
|
this.name = "DynamicSeedError";
|
|
44632
45085
|
this.twinName = twinName;
|
|
44633
45086
|
this.validationErrors = validationErrors;
|
|
@@ -44693,7 +45146,7 @@ ${fkDetails}
|
|
|
44693
45146
|
// ../packages/seedgen/src/runner/seed/dynamic-generator.ts
|
|
44694
45147
|
var SEED_CODEGEN_MAX_TOKENS = 4096;
|
|
44695
45148
|
var MAX_CODEGEN_ATTEMPTS = 3;
|
|
44696
|
-
var SEED_CACHE_PROMPT_TEMPLATE_VERSION =
|
|
45149
|
+
var SEED_CACHE_PROMPT_TEMPLATE_VERSION = 5;
|
|
44697
45150
|
var CODEGEN_TOTAL_BUDGET_MS = 12e4;
|
|
44698
45151
|
function buildSeedCacheContext(twinName, systemPromptHash, intent, context) {
|
|
44699
45152
|
return {
|
|
@@ -45102,7 +45555,7 @@ function buildSeedPromptHashInput() {
|
|
|
45102
45555
|
SUPABASE_SQL_SYSTEM_PROMPT
|
|
45103
45556
|
].join("\n\n---\n\n");
|
|
45104
45557
|
}
|
|
45105
|
-
var SYSTEM_PROMPT_HASH = (0,
|
|
45558
|
+
var SYSTEM_PROMPT_HASH = (0, import_node_crypto15.createHash)("sha256").update(buildSeedPromptHashInput()).digest("hex").slice(0, 12);
|
|
45106
45559
|
async function generateDynamicSeed(twinName, baseSeedName, baseSeedData, setupDescription, config2, intent, context) {
|
|
45107
45560
|
const scopedSetupDescription = config2.skipTwinScoping ? setupDescription : scopeSetupToTwin(twinName, setupDescription);
|
|
45108
45561
|
const seedIntent = resolveSeedIntentForGeneration(twinName, scopedSetupDescription, intent);
|
|
@@ -45222,8 +45675,8 @@ async function generateDynamicSeed(twinName, baseSeedName, baseSeedData, setupDe
|
|
|
45222
45675
|
],
|
|
45223
45676
|
`
|
|
45224
45677
|
|
|
45225
|
-
Hint: Dynamic seed generation failed for the "${twinName}"
|
|
45226
|
-
Use a documented seed name for ${twinName}, or inspect the
|
|
45678
|
+
Hint: Dynamic seed generation failed for the "${twinName}" clone. Try adding a \`seed: <name>\` line to your scenario's Config section to use a pre-built seed instead.
|
|
45679
|
+
Use a documented seed name for ${twinName}, or inspect the bundled clone assets in this repo.`
|
|
45227
45680
|
);
|
|
45228
45681
|
}
|
|
45229
45682
|
// Annotate the CommonJS export names for ESM import in node:
|