archal 0.9.20 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -159
- package/agents/openclaw/Dockerfile +2 -1
- package/agents/openclaw/README.md +10 -17
- package/agents/openclaw/drive.mjs +21 -31
- package/agents/openclaw/extract-openclaw-response-text.mjs +49 -0
- package/agents/openclaw/scenarios/acceptance/github-escalation-and-cleanup.md +43 -0
- package/agents/openclaw/scenarios/acceptance/jira-linear-release-triage.md +39 -0
- package/agents/openclaw/scenarios/acceptance/multi-clone-customer-risk-review.md +45 -0
- package/agents/openclaw/scenarios/acceptance/slack-incident-handoff.md +42 -0
- package/agents/openclaw/scenarios/acceptance/stripe-dunning-remediation.md +40 -0
- package/agents/openclaw/scenarios/close-stale-issues.md +35 -0
- package/agents/openclaw/workspace/TOOLS.md +19 -0
- package/clone-assets/calcom/tools.json +1705 -153
- package/clone-assets/clickup/tools.json +2528 -541
- package/clone-assets/customerio/tools.json +2108 -144
- package/clone-assets/github/tools.json +1 -2
- package/clone-assets/gitlab/tools.json +10087 -398
- package/clone-assets/hubspot/tools.json +198 -0
- package/clone-assets/linear/tools.json +41 -1
- package/clone-assets/sentry/tools.json +2264 -188
- package/clone-assets/stripe/tools.json +114 -0
- package/clone-assets/webflow/tools.json +1895 -125
- package/dist/{autoloop-worker-types-BEb_E44z.d.cts → autoloop-worker-types-CHaclqtD.d.cts} +23 -59
- package/dist/cli.cjs +107175 -126959
- package/dist/commands/{autoloop-hosted-worker.cjs → autoloop-hosted-control-plane-client.cjs} +25657 -42736
- package/dist/commands/{autoloop-hosted-worker.d.cts → autoloop-hosted-control-plane-client.d.cts} +32 -42
- package/dist/commands/autoloop-pr-verification.cjs +607 -522
- package/dist/commands/autoloop-pr-verification.d.cts +3 -1
- package/dist/commands/autoloop-result-parser.cjs +2474 -2373
- package/dist/commands/autoloop-result-parser.d.cts +159 -2
- package/dist/commands/autoloop-worker.cjs +14565 -12240
- package/dist/commands/autoloop-worker.d.cts +10 -5
- package/dist/eval-shim.mjs +216 -0
- package/dist/index.cjs +15 -2
- package/dist/index.d.cts +3 -1
- package/dist/layer-1-ziaLpfLr.d.cts +62 -0
- package/dist/metafile-cjs.json +1 -0
- package/dist/reporter-entry.js +3 -0
- package/dist/{replay.cjs → sdk/index.cjs} +42979 -40973
- package/dist/sdk/index.d.cts +626 -0
- package/dist/vitest/{chunk-6CBYFCFK.js → chunk-2PDHTPZC.js} +289 -89
- package/dist/vitest/{chunk-ARVS45PP.js → chunk-7L4BBB6M.js} +123 -274
- package/dist/vitest/index.cjs +500 -816
- package/dist/vitest/index.d.ts +16 -81
- package/dist/vitest/index.js +40 -409
- package/dist/vitest/runtime/hosted-session-reaper.cjs +143 -293
- package/dist/vitest/runtime/hosted-session-reaper.js +1 -1
- package/dist/vitest/runtime/setup-files.js +2 -2
- package/manifest.json +9 -0
- package/package.json +14 -13
- package/skills/archal-agent/SKILL.md +0 -1
- package/skills/autoloop/SKILL.md +288 -273
- package/skills/autoloop/references/hosted-sources.md +49 -17
- package/skills/autoloop/references/trace-schema-mapping.md +83 -52
- package/skills/eval/SKILL.md +16 -48
- package/skills/free-account/SKILL.md +103 -0
- package/skills/install-agent/SKILL.md +16 -35
- package/skills/onboard/SKILL.md +13 -70
- package/skills/scenario/SKILL.md +30 -27
- package/skills/seed/SKILL.md +7 -6
- package/skills/vitest/SKILL.md +3 -2
- package/agents/github-octokit/.archal.json +0 -8
- package/agents/github-octokit/Dockerfile +0 -8
- package/agents/github-octokit/README.md +0 -113
- package/agents/github-octokit/agent.mjs +0 -54
- package/agents/github-octokit/package.json +0 -9
- package/agents/github-octokit/scenarios/test-repo-access.md +0 -27
- package/agents/google-workspace-local-tools/Dockerfile +0 -6
- package/agents/google-workspace-local-tools/README.md +0 -58
- package/agents/google-workspace-local-tools/agent.mjs +0 -196
- package/agents/google-workspace-local-tools/archal-harness.json +0 -7
- package/agents/google-workspace-local-tools/run-input.yaml +0 -16
- package/agents/google-workspace-local-tools/scenario.md +0 -29
- package/agents/hermes/.archal.json +0 -8
- package/agents/hermes/Dockerfile +0 -46
- package/agents/hermes/README.md +0 -87
- package/agents/hermes/SOUL.md +0 -27
- package/agents/hermes/config.yaml +0 -34
- package/agents/hermes/drive.mjs +0 -113
- package/agents/hermes/scenarios/stripe-customers-read-only.md +0 -32
- package/agents/pagination-test/README.md +0 -24
- package/agents/pagination-test/scenario.md +0 -24
- package/agents/replay-capsule-harness/README.md +0 -29
- package/agents/replay-capsule-harness/observability-install-offline-e2e.mts +0 -1517
- package/agents/replay-capsule-harness/replay-capsule-e2e.mjs +0 -104
- package/dist/harness.cjs +0 -63
- package/dist/harness.d.cts +0 -20
- package/dist/replay.d.cts +0 -4625
- package/dist/scenarios.cjs +0 -80343
- package/dist/scenarios.d.cts +0 -562
package/dist/vitest/index.cjs
CHANGED
|
@@ -32,7 +32,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
32
32
|
var index_exports = {};
|
|
33
33
|
__export(index_exports, {
|
|
34
34
|
ArchalReporter: () => ArchalReporter,
|
|
35
|
-
archalVitestConfig: () => archalVitestConfig,
|
|
36
35
|
archalVitestProject: () => archalVitestProject,
|
|
37
36
|
archalVitestRootConfig: () => archalVitestRootConfig,
|
|
38
37
|
archalVitestWorkspace: () => archalVitestWorkspace,
|
|
@@ -63,6 +62,8 @@ var CREDENTIALS_MASTER_KEY_ENV_VAR = "ARCHAL_CREDENTIALS_MASTER_KEY";
|
|
|
63
62
|
var KEYCHAIN_SERVICE = "archal-cli";
|
|
64
63
|
var KEYCHAIN_ACCOUNT = "credentials-master-key";
|
|
65
64
|
var HOSTED_DEFAULT_AUTH_BASE_URL = "https://www.archal.ai";
|
|
65
|
+
var HOSTED_DEFAULT_API_BASE_URL = "https://api.archal.ai";
|
|
66
|
+
var WORKSPACE_API_KEY_PREFIX = "archal_ws_";
|
|
66
67
|
var STRICT_ENDPOINTS_ENV_VAR = "ARCHAL_STRICT_ENDPOINTS";
|
|
67
68
|
var REQUEST_TIMEOUT_MS = 8e3;
|
|
68
69
|
var ENV_TOKEN_FALLBACK_TTL_SECONDS = 24 * 60 * 60;
|
|
@@ -72,11 +73,6 @@ function isPlan(value) {
|
|
|
72
73
|
return value === "free" || value === "pro" || value === "enterprise";
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
// ../node-auth/src/errors.ts
|
|
76
|
-
function errorMessage(error) {
|
|
77
|
-
return error instanceof Error ? error.message : String(error);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
76
|
// ../node-auth/src/credential-store.ts
|
|
81
77
|
var import_node_child_process = require("child_process");
|
|
82
78
|
var import_node_crypto = require("crypto");
|
|
@@ -109,7 +105,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
109
105
|
name: "Cal.com",
|
|
110
106
|
description: "Event types, schedules, availability slots, bookings, calendars, and webhooks.",
|
|
111
107
|
stage: "preview",
|
|
112
|
-
toolCount:
|
|
108
|
+
toolCount: 35,
|
|
113
109
|
transport: "both",
|
|
114
110
|
architectureClass: "domain-simulator",
|
|
115
111
|
domainPrimitives: [
|
|
@@ -127,7 +123,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
127
123
|
name: "ClickUp",
|
|
128
124
|
description: "Teams, spaces, folders, lists, tasks, comments, tags, time tracking, and checklists.",
|
|
129
125
|
stage: "preview",
|
|
130
|
-
toolCount:
|
|
126
|
+
toolCount: 123,
|
|
131
127
|
transport: "both",
|
|
132
128
|
architectureClass: "standard-core",
|
|
133
129
|
domainPrimitives: [],
|
|
@@ -140,7 +136,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
140
136
|
name: "Customer.io",
|
|
141
137
|
description: "Messaging automation across campaigns, broadcasts, transactional email, segments, customers, and message delivery.",
|
|
142
138
|
stage: "preview",
|
|
143
|
-
toolCount:
|
|
139
|
+
toolCount: 129,
|
|
144
140
|
transport: "rest",
|
|
145
141
|
architectureClass: "standard-core",
|
|
146
142
|
domainPrimitives: [],
|
|
@@ -205,7 +201,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
205
201
|
name: "GitLab",
|
|
206
202
|
description: "Projects, branches, commits, issues, merge requests, pipelines, labels, milestones, releases, and webhooks.",
|
|
207
203
|
stage: "preview",
|
|
208
|
-
toolCount:
|
|
204
|
+
toolCount: 559,
|
|
209
205
|
transport: "both",
|
|
210
206
|
architectureClass: "domain-simulator",
|
|
211
207
|
domainPrimitives: [
|
|
@@ -240,7 +236,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
240
236
|
name: "HubSpot",
|
|
241
237
|
description: "CRM contacts, companies, deals, tickets, and engagements.",
|
|
242
238
|
stage: "preview",
|
|
243
|
-
toolCount:
|
|
239
|
+
toolCount: 44,
|
|
244
240
|
transport: "rest",
|
|
245
241
|
architectureClass: "replay-shell",
|
|
246
242
|
domainPrimitives: [
|
|
@@ -275,7 +271,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
275
271
|
name: "Linear",
|
|
276
272
|
description: "Issues, projects, teams, cycles, and workflows.",
|
|
277
273
|
stage: "public",
|
|
278
|
-
toolCount:
|
|
274
|
+
toolCount: 53,
|
|
279
275
|
transport: "both",
|
|
280
276
|
architectureClass: "domain-simulator",
|
|
281
277
|
domainPrimitives: [
|
|
@@ -344,7 +340,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
344
340
|
name: "Sentry",
|
|
345
341
|
description: "Error monitoring across organizations, projects, teams, issues, events, releases, and DSN keys.",
|
|
346
342
|
stage: "preview",
|
|
347
|
-
toolCount:
|
|
343
|
+
toolCount: 34,
|
|
348
344
|
transport: "rest",
|
|
349
345
|
architectureClass: "domain-simulator",
|
|
350
346
|
domainPrimitives: [
|
|
@@ -446,14 +442,10 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
446
442
|
name: "Webflow",
|
|
447
443
|
description: "Sites, pages, CMS collections, items, assets, forms, and webhooks.",
|
|
448
444
|
stage: "preview",
|
|
449
|
-
toolCount:
|
|
450
|
-
transport: "
|
|
451
|
-
architectureClass: "
|
|
452
|
-
domainPrimitives: [
|
|
453
|
-
"recording replay cursor",
|
|
454
|
-
"CMS collection/item overlays",
|
|
455
|
-
"publish lifecycle captures"
|
|
456
|
-
],
|
|
445
|
+
toolCount: 104,
|
|
446
|
+
transport: "both",
|
|
447
|
+
architectureClass: "standard-core",
|
|
448
|
+
domainPrimitives: [],
|
|
457
449
|
behaviorOwner: null,
|
|
458
450
|
opsCoverage: 100
|
|
459
451
|
}
|
|
@@ -549,142 +541,11 @@ var STARTABLE_CLONE_CATALOG = CLONE_CATALOG.filter(
|
|
|
549
541
|
(entry) => STARTABLE_CLONE_ID_SET.has(entry.id)
|
|
550
542
|
);
|
|
551
543
|
|
|
552
|
-
// ../
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
);
|
|
557
|
-
|
|
558
|
-
// ../billing-constants/src/index.ts
|
|
559
|
-
var PLAN_MONTHLY_TWIN_MINUTE_LIMITS = {
|
|
560
|
-
free: 500,
|
|
561
|
-
pro: 5e3,
|
|
562
|
-
enterprise: null
|
|
563
|
-
};
|
|
564
|
-
var PLAN_CONCURRENT_SESSION_LIMITS = {
|
|
565
|
-
free: 3,
|
|
566
|
-
pro: 10,
|
|
567
|
-
enterprise: 50
|
|
568
|
-
};
|
|
569
|
-
var FREE_WORKSPACE_MEMBER_LIMIT = 2;
|
|
570
|
-
var PRO_PLAN_PRICE_USD = 199;
|
|
571
|
-
function formatMinutesLabel(minutes) {
|
|
572
|
-
return minutes.toLocaleString("en-US");
|
|
573
|
-
}
|
|
574
|
-
var FREE_MINUTES = PLAN_MONTHLY_TWIN_MINUTE_LIMITS.free;
|
|
575
|
-
var PRO_MINUTES = PLAN_MONTHLY_TWIN_MINUTE_LIMITS.pro;
|
|
576
|
-
if (FREE_MINUTES == null || PRO_MINUTES == null) {
|
|
577
|
-
throw new Error("PLAN_MONTHLY_TWIN_MINUTE_LIMITS: free and pro must be non-null");
|
|
578
|
-
}
|
|
579
|
-
var PRO_EVALS_PER_SEAT = 500;
|
|
580
|
-
var PRO_SESSION_MINUTES_PER_SEAT = 5e3;
|
|
581
|
-
var PRO_MAX_SEATS = 5;
|
|
582
|
-
var FREE_EVALS_PER_MONTH = 100;
|
|
583
|
-
var PLAN_DISPLAY = {
|
|
584
|
-
free: {
|
|
585
|
-
tag: "Free",
|
|
586
|
-
priceLabel: "$0",
|
|
587
|
-
periodLabel: "",
|
|
588
|
-
included: [
|
|
589
|
-
`${formatMinutesLabel(FREE_MINUTES)} session-minutes / account`,
|
|
590
|
-
`${FREE_EVALS_PER_MONTH} evals / account`,
|
|
591
|
-
`1 workspace (${FREE_WORKSPACE_MEMBER_LIMIT} users max)`,
|
|
592
|
-
`${PLAN_CONCURRENT_SESSION_LIMITS.free} concurrent sessions / workspace`,
|
|
593
|
-
"All clones included"
|
|
594
|
-
]
|
|
595
|
-
},
|
|
596
|
-
pro: {
|
|
597
|
-
tag: "Pro",
|
|
598
|
-
priceLabel: `$${PRO_PLAN_PRICE_USD}`,
|
|
599
|
-
periodLabel: "/mo per seat",
|
|
600
|
-
included: [
|
|
601
|
-
`${formatMinutesLabel(PRO_SESSION_MINUTES_PER_SEAT)} session-minutes / seat / month`,
|
|
602
|
-
`${PRO_EVALS_PER_SEAT} evals / seat / month`,
|
|
603
|
-
"All clones included",
|
|
604
|
-
`${PLAN_CONCURRENT_SESSION_LIMITS.pro} concurrent sessions / workspace`,
|
|
605
|
-
`1 workspace, up to ${PRO_MAX_SEATS} seats with pooled usage`
|
|
606
|
-
]
|
|
607
|
-
},
|
|
608
|
-
enterprise: {
|
|
609
|
-
tag: "Enterprise",
|
|
610
|
-
priceLabel: "Contact us",
|
|
611
|
-
periodLabel: "",
|
|
612
|
-
included: [
|
|
613
|
-
"Unlimited session-minutes",
|
|
614
|
-
"Unlimited seats per workspace",
|
|
615
|
-
"Unlimited workspaces",
|
|
616
|
-
`${PLAN_CONCURRENT_SESSION_LIMITS.enterprise} concurrent sessions / workspace`,
|
|
617
|
-
"SSO / SAML",
|
|
618
|
-
"SOC 2 (in progress)",
|
|
619
|
-
"Custom clones & eval support",
|
|
620
|
-
"Dedicated onboarding & support"
|
|
621
|
-
]
|
|
622
|
-
}
|
|
623
|
-
};
|
|
624
|
-
var PLAN_MAX_SESSION_TTL_SECONDS = {
|
|
625
|
-
free: 30 * 60,
|
|
626
|
-
// 30 minutes
|
|
627
|
-
pro: 60 * 60,
|
|
628
|
-
// 60 minutes
|
|
629
|
-
enterprise: 90 * 60
|
|
630
|
-
// 90 minutes
|
|
631
|
-
};
|
|
632
|
-
var MAX_ABSOLUTE_SESSION_LIFETIME_SECONDS = 4 * 60 * 60;
|
|
633
|
-
var LIFETIME_PERIOD_RESETS_AT = new Date(Date.UTC(9999, 11, 31));
|
|
634
|
-
var ALL_ENTITLED_CLONES = ALL_STARTABLE_CLONE_IDS;
|
|
635
|
-
var SCENARIO_USAGE_WINDOW_DAYS = 7;
|
|
636
|
-
var SCENARIO_USAGE_WINDOW_MS = SCENARIO_USAGE_WINDOW_DAYS * 24 * 60 * 60 * 1e3;
|
|
637
|
-
var SCENARIO_USAGE_WINDOW_SECONDS = SCENARIO_USAGE_WINDOW_DAYS * 24 * 60 * 60;
|
|
638
|
-
var LLM_PRICING_USD_PER_M_TOKENS = {
|
|
639
|
-
// Google Gemini (verified 2026-05-05, standard tier <=200K input tokens)
|
|
640
|
-
"gemini-2.5-pro": { input: 1.25, output: 10 },
|
|
641
|
-
"gemini-2.5-flash": { input: 0.3, output: 2.5 },
|
|
642
|
-
// OpenAI flagship text models (verified 2026-05-21, standard short-context tier)
|
|
643
|
-
"gpt-5.5": { input: 5, output: 30 },
|
|
644
|
-
"gpt-5.5-pro": { input: 30, output: 180 },
|
|
645
|
-
"gpt-5.4": { input: 2.5, output: 15 },
|
|
646
|
-
"gpt-5.4-mini": { input: 0.75, output: 4.5 },
|
|
647
|
-
"gpt-5.4-nano": { input: 0.2, output: 1.25 },
|
|
648
|
-
"gpt-5.4-pro": { input: 30, output: 180 },
|
|
649
|
-
"gpt-4o-mini": { input: 0.15, output: 0.6 },
|
|
650
|
-
"gpt-4o": { input: 2.5, output: 10 },
|
|
651
|
-
"gpt-4.1-mini": { input: 0.4, output: 1.6 },
|
|
652
|
-
"gpt-4.1-nano": { input: 0.1, output: 0.4 },
|
|
653
|
-
"gpt-4.1": { input: 2, output: 8 },
|
|
654
|
-
// DeepSeek (verified 2026-05-05; legacy names map to v4-flash per vendor)
|
|
655
|
-
"deepseek-chat": { input: 0.14, output: 0.28 },
|
|
656
|
-
"deepseek-reasoner": { input: 0.14, output: 0.28 },
|
|
657
|
-
"deepseek-v4-flash": { input: 0.14, output: 0.28 }
|
|
658
|
-
};
|
|
659
|
-
var LLM_PRICING_FAMILY_RATES = [
|
|
660
|
-
{ match: /^gemini-2\.5-pro/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gemini-2.5-pro"] },
|
|
661
|
-
{ match: /^gemini-2\.5-flash/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gemini-2.5-flash"] },
|
|
662
|
-
{ match: /^gpt-5\.5-pro/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.5-pro"] },
|
|
663
|
-
{ match: /^gpt-5\.5/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.5"] },
|
|
664
|
-
{ match: /^gpt-5\.4-pro/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4-pro"] },
|
|
665
|
-
{ match: /^gpt-5\.4-mini/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4-mini"] },
|
|
666
|
-
{ match: /^gpt-5\.4-nano/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4-nano"] },
|
|
667
|
-
{ match: /^gpt-5\.4/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4"] },
|
|
668
|
-
{ match: /^gpt-4o-mini/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4o-mini"] },
|
|
669
|
-
{ match: /^gpt-4o(?!-mini)/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4o"] },
|
|
670
|
-
{ match: /^gpt-4\.1-mini/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4.1-mini"] },
|
|
671
|
-
{ match: /^gpt-4\.1-nano/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4.1-nano"] },
|
|
672
|
-
{ match: /^gpt-4\.1(?!-mini|-nano)/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4.1"] },
|
|
673
|
-
// Anthropic Claude 4.x list prices (verified 2026): Opus $5/$25, Sonnet
|
|
674
|
-
// $3/$15, Haiku 4.5 $1/$5 per 1M tokens (input/output).
|
|
675
|
-
{ match: /^claude-opus-/i, rate: { input: 5, output: 25 } },
|
|
676
|
-
{ match: /^claude-haiku-/i, rate: { input: 1, output: 5 } },
|
|
677
|
-
{ match: /^claude-sonnet-/i, rate: { input: 3, output: 15 } },
|
|
678
|
-
{ match: /^opus-/i, rate: { input: 5, output: 25 } },
|
|
679
|
-
{ match: /^haiku-/i, rate: { input: 1, output: 5 } },
|
|
680
|
-
{ match: /^sonnet-/i, rate: { input: 3, output: 15 } },
|
|
681
|
-
{ match: /^deepseek-chat/i, rate: LLM_PRICING_USD_PER_M_TOKENS["deepseek-chat"] },
|
|
682
|
-
{ match: /^deepseek-reasoner/i, rate: LLM_PRICING_USD_PER_M_TOKENS["deepseek-reasoner"] },
|
|
683
|
-
{ match: /^deepseek-v4-flash/i, rate: LLM_PRICING_USD_PER_M_TOKENS["deepseek-v4-flash"] }
|
|
684
|
-
];
|
|
685
|
-
|
|
686
|
-
// ../node-auth/src/clone-entitlements.ts
|
|
687
|
-
var ENTITLED_CLONE_SET = new Set(ALL_ENTITLED_CLONES);
|
|
544
|
+
// ../node-auth/src/credential-store.ts
|
|
545
|
+
function errorMessage(error) {
|
|
546
|
+
return error instanceof Error ? error.message : String(error);
|
|
547
|
+
}
|
|
548
|
+
var ENTITLED_CLONE_SET = new Set(ALL_STARTABLE_CLONE_IDS);
|
|
688
549
|
function normalizeEntitledCloneIds(cloneIds) {
|
|
689
550
|
if (!cloneIds) {
|
|
690
551
|
return [];
|
|
@@ -701,8 +562,6 @@ function normalizeEntitledCloneIds(cloneIds) {
|
|
|
701
562
|
}
|
|
702
563
|
return [...normalized];
|
|
703
564
|
}
|
|
704
|
-
|
|
705
|
-
// ../node-auth/src/credential-store.ts
|
|
706
565
|
var KEYCHAIN_COMMAND_TIMEOUT_MS = 1500;
|
|
707
566
|
var ARCHAL_DIR_NAME = ".archal";
|
|
708
567
|
var TEST_SANDBOX_ID_ENV_VAR = "ARCHAL_TEST_SANDBOX_ID";
|
|
@@ -774,7 +633,7 @@ function seedSandboxFromRealHomeOnce(sandboxDir) {
|
|
|
774
633
|
}
|
|
775
634
|
}
|
|
776
635
|
function getArchalDir() {
|
|
777
|
-
const explicit = process.env["ARCHAL_HOME"];
|
|
636
|
+
const explicit = process.env["ARCHAL_HOME"]?.trim();
|
|
778
637
|
if (explicit) {
|
|
779
638
|
return explicit;
|
|
780
639
|
}
|
|
@@ -1058,7 +917,66 @@ function readCredentialsFile(options) {
|
|
|
1058
917
|
return readCredentialsFileAtPath(getCredentialsPath(), options);
|
|
1059
918
|
}
|
|
1060
919
|
function isWorkspaceApiKey(token) {
|
|
1061
|
-
return token.startsWith(
|
|
920
|
+
return token.startsWith(WORKSPACE_API_KEY_PREFIX) || token.startsWith("archal_") && !token.includes(".");
|
|
921
|
+
}
|
|
922
|
+
var WORKSPACE_API_KEY_EXPIRES_SECONDS = 365 * 24 * 60 * 60;
|
|
923
|
+
function parseEnvToken(token, envName = AUTH_TOKEN_ENV_VAR, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
924
|
+
const trimmed = token.trim();
|
|
925
|
+
if (!trimmed) {
|
|
926
|
+
return { status: "invalid", message: `${envName} is empty.` };
|
|
927
|
+
}
|
|
928
|
+
if (isWorkspaceApiKey(trimmed)) {
|
|
929
|
+
return {
|
|
930
|
+
status: "ok",
|
|
931
|
+
credentials: {
|
|
932
|
+
token: trimmed,
|
|
933
|
+
refreshToken: "",
|
|
934
|
+
email: "(workspace-api-key)",
|
|
935
|
+
plan: "pro",
|
|
936
|
+
selectedCloneIds: [],
|
|
937
|
+
expiresAt: nowSeconds + WORKSPACE_API_KEY_EXPIRES_SECONDS
|
|
938
|
+
}
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
const claims = decodeJwtPayload(trimmed);
|
|
942
|
+
if (claims === null) {
|
|
943
|
+
return {
|
|
944
|
+
status: "invalid",
|
|
945
|
+
message: `${envName} must be a JWT with valid plan and exp claims or a workspace API key (archal_ws_...).`
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
const email = typeof claims["email"] === "string" ? claims["email"] : `(from ${envName})`;
|
|
949
|
+
if (!isPlan(claims["plan"])) {
|
|
950
|
+
return {
|
|
951
|
+
status: "invalid",
|
|
952
|
+
message: `${envName} JWT does not contain a valid plan claim.`
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
const plan = claims["plan"];
|
|
956
|
+
if (typeof claims["exp"] !== "number" || !Number.isFinite(claims["exp"])) {
|
|
957
|
+
return {
|
|
958
|
+
status: "invalid",
|
|
959
|
+
message: `${envName} JWT does not contain a valid exp claim.`
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
const expiresAt = claims["exp"];
|
|
963
|
+
if (expiresAt <= nowSeconds) {
|
|
964
|
+
return {
|
|
965
|
+
status: "expired",
|
|
966
|
+
message: `${envName} is expired. Remove it or replace it with a valid token.`
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
return {
|
|
970
|
+
status: "ok",
|
|
971
|
+
credentials: {
|
|
972
|
+
token: trimmed,
|
|
973
|
+
refreshToken: "",
|
|
974
|
+
email,
|
|
975
|
+
plan,
|
|
976
|
+
selectedCloneIds: [],
|
|
977
|
+
expiresAt
|
|
978
|
+
}
|
|
979
|
+
};
|
|
1062
980
|
}
|
|
1063
981
|
function getStoredCredentials(options) {
|
|
1064
982
|
const creds = readCredentialsFile(options);
|
|
@@ -1215,8 +1133,68 @@ function getConfiguredAuthBaseUrl(options) {
|
|
|
1215
1133
|
}
|
|
1216
1134
|
return isStrictEndpointModeEnabled() ? null : HOSTED_DEFAULT_AUTH_BASE_URL;
|
|
1217
1135
|
}
|
|
1136
|
+
function readConfiguredUrlFromEnvChain(envVarNames, options) {
|
|
1137
|
+
const uniqueEnvVars = [...new Set(envVarNames)];
|
|
1138
|
+
return readConfiguredUrl(options, ...uniqueEnvVars);
|
|
1139
|
+
}
|
|
1140
|
+
function getConfiguredAuthValidationBaseUrl(options = {}) {
|
|
1141
|
+
const apiUrlEnvVar = options.apiUrlEnvVar ?? "ARCHAL_API_URL";
|
|
1142
|
+
const authUrlEnvVar = options.authUrlEnvVar ?? "ARCHAL_AUTH_URL";
|
|
1143
|
+
const resolved = readConfiguredUrlFromEnvChain([
|
|
1144
|
+
apiUrlEnvVar,
|
|
1145
|
+
authUrlEnvVar,
|
|
1146
|
+
"ARCHAL_AUTH_URL",
|
|
1147
|
+
"ARCHAL_AUTH_BASE_URL",
|
|
1148
|
+
"ARCHAL_API_URL",
|
|
1149
|
+
"ARCHAL_API_BASE_URL"
|
|
1150
|
+
], options);
|
|
1151
|
+
if (resolved) {
|
|
1152
|
+
return resolved;
|
|
1153
|
+
}
|
|
1154
|
+
return isStrictEndpointModeEnabled() ? null : HOSTED_DEFAULT_AUTH_BASE_URL;
|
|
1155
|
+
}
|
|
1156
|
+
function getConfiguredVitestApiBaseUrl(fallback = HOSTED_DEFAULT_API_BASE_URL, options) {
|
|
1157
|
+
return readConfiguredUrlFromEnvChain([
|
|
1158
|
+
"ARCHAL_VITEST_API_URL",
|
|
1159
|
+
"ARCHAL_API_URL",
|
|
1160
|
+
"ARCHAL_API_BASE_URL",
|
|
1161
|
+
"ARCHAL_AUTH_URL",
|
|
1162
|
+
"ARCHAL_AUTH_BASE_URL"
|
|
1163
|
+
], options) ?? fallback;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
// ../retry/dist/index.js
|
|
1167
|
+
function abortReason(signal) {
|
|
1168
|
+
return signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted.", "AbortError");
|
|
1169
|
+
}
|
|
1170
|
+
function sleep(ms, options) {
|
|
1171
|
+
const signal = options?.signal;
|
|
1172
|
+
if (signal?.aborted) {
|
|
1173
|
+
return Promise.reject(abortReason(signal));
|
|
1174
|
+
}
|
|
1175
|
+
if (ms <= 0) {
|
|
1176
|
+
return Promise.resolve();
|
|
1177
|
+
}
|
|
1178
|
+
if (!signal) {
|
|
1179
|
+
return new Promise((resolve5) => {
|
|
1180
|
+
setTimeout(resolve5, ms);
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
const abortSignal = signal;
|
|
1184
|
+
return new Promise((resolve5, reject) => {
|
|
1185
|
+
const timeout = setTimeout(() => {
|
|
1186
|
+
abortSignal.removeEventListener("abort", onAbort);
|
|
1187
|
+
resolve5();
|
|
1188
|
+
}, ms);
|
|
1189
|
+
function onAbort() {
|
|
1190
|
+
clearTimeout(timeout);
|
|
1191
|
+
reject(abortReason(abortSignal));
|
|
1192
|
+
}
|
|
1193
|
+
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1218
1196
|
|
|
1219
|
-
// ../node-auth/src/
|
|
1197
|
+
// ../node-auth/src/token-exchange.ts
|
|
1220
1198
|
function buildAuthRequestHeaders(metadata, includeContentType = false) {
|
|
1221
1199
|
const headers = {};
|
|
1222
1200
|
if (includeContentType) {
|
|
@@ -1337,37 +1315,6 @@ async function validateAuthWithServerResult(creds, metadata) {
|
|
|
1337
1315
|
};
|
|
1338
1316
|
}
|
|
1339
1317
|
|
|
1340
|
-
// ../retry/dist/index.js
|
|
1341
|
-
function abortReason(signal) {
|
|
1342
|
-
return signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted.", "AbortError");
|
|
1343
|
-
}
|
|
1344
|
-
function sleep(ms, options) {
|
|
1345
|
-
const signal = options?.signal;
|
|
1346
|
-
if (signal?.aborted) {
|
|
1347
|
-
return Promise.reject(abortReason(signal));
|
|
1348
|
-
}
|
|
1349
|
-
if (ms <= 0) {
|
|
1350
|
-
return Promise.resolve();
|
|
1351
|
-
}
|
|
1352
|
-
if (!signal) {
|
|
1353
|
-
return new Promise((resolve5) => {
|
|
1354
|
-
setTimeout(resolve5, ms);
|
|
1355
|
-
});
|
|
1356
|
-
}
|
|
1357
|
-
const abortSignal = signal;
|
|
1358
|
-
return new Promise((resolve5, reject) => {
|
|
1359
|
-
const timeout = setTimeout(() => {
|
|
1360
|
-
abortSignal.removeEventListener("abort", onAbort);
|
|
1361
|
-
resolve5();
|
|
1362
|
-
}, ms);
|
|
1363
|
-
function onAbort() {
|
|
1364
|
-
clearTimeout(timeout);
|
|
1365
|
-
reject(abortReason(abortSignal));
|
|
1366
|
-
}
|
|
1367
|
-
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
1368
|
-
});
|
|
1369
|
-
}
|
|
1370
|
-
|
|
1371
1318
|
// ../node-auth/src/secure-token.ts
|
|
1372
1319
|
var import_node_crypto2 = require("crypto");
|
|
1373
1320
|
|
|
@@ -1475,26 +1422,6 @@ function parsePositiveInteger(rawValue, fallback, minimum = 1) {
|
|
|
1475
1422
|
const parsed = Number(normalized);
|
|
1476
1423
|
return Number.isSafeInteger(parsed) && parsed >= minimum ? parsed : fallback;
|
|
1477
1424
|
}
|
|
1478
|
-
function normalizeApiBaseUrl(value) {
|
|
1479
|
-
if (!value) return null;
|
|
1480
|
-
const normalized = value.trim().replace(/\/+$/, "");
|
|
1481
|
-
if (!normalized) return null;
|
|
1482
|
-
let parsed;
|
|
1483
|
-
try {
|
|
1484
|
-
parsed = new URL(normalized);
|
|
1485
|
-
} catch {
|
|
1486
|
-
throw new Error(`Invalid ARCHAL_API_URL: "${normalized}" is not a valid URL`);
|
|
1487
|
-
}
|
|
1488
|
-
const isLocalhostHttp = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1");
|
|
1489
|
-
if (parsed.protocol !== "https:" && !isLocalhostHttp) {
|
|
1490
|
-
throw new Error(`Hosted API URL must use HTTPS (or localhost HTTP). Received ${normalized}.`);
|
|
1491
|
-
}
|
|
1492
|
-
const pathname = parsed.pathname.replace(/\/+$/, "");
|
|
1493
|
-
parsed.pathname = pathname.endsWith("/api") ? pathname.slice(0, -4) || "/" : pathname || "/";
|
|
1494
|
-
parsed.search = "";
|
|
1495
|
-
parsed.hash = "";
|
|
1496
|
-
return parsed.toString().replace(/\/$/, "");
|
|
1497
|
-
}
|
|
1498
1425
|
function resolveHostedWorkspaceHeader() {
|
|
1499
1426
|
return trimEnv("ARCHAL_WORKSPACE_ID");
|
|
1500
1427
|
}
|
|
@@ -1982,34 +1909,6 @@ var HostedSessionClient = class {
|
|
|
1982
1909
|
var STORED_CREDENTIALS_LOCK_TIMEOUT_MS = 3e4;
|
|
1983
1910
|
var STORED_CREDENTIALS_STALE_LOCK_MS = STORED_CREDENTIALS_LOCK_TIMEOUT_MS;
|
|
1984
1911
|
var STORED_CREDENTIALS_LOCK_POLL_INTERVAL_MS = 50;
|
|
1985
|
-
var DEFAULT_AUTH_BASE_URL = "https://www.archal.ai";
|
|
1986
|
-
var WORKSPACE_API_KEY_EXPIRES_SECONDS = 365 * 24 * 60 * 60;
|
|
1987
|
-
function readFirstConfiguredBaseUrl(envVars) {
|
|
1988
|
-
for (const envVar of envVars) {
|
|
1989
|
-
const configured = trimEnv(envVar);
|
|
1990
|
-
if (!configured) {
|
|
1991
|
-
continue;
|
|
1992
|
-
}
|
|
1993
|
-
const normalized = normalizeApiBaseUrl(configured);
|
|
1994
|
-
if (normalized) {
|
|
1995
|
-
return normalized;
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
1998
|
-
return null;
|
|
1999
|
-
}
|
|
2000
|
-
function resolveHostedAuthBaseUrl(options) {
|
|
2001
|
-
const authUrlEnvVar = options.authUrlEnvVar ?? "ARCHAL_AUTH_URL";
|
|
2002
|
-
const apiUrlEnvVar = options.apiUrlEnvVar ?? "ARCHAL_API_URL";
|
|
2003
|
-
const envVars = [.../* @__PURE__ */ new Set([
|
|
2004
|
-
apiUrlEnvVar,
|
|
2005
|
-
authUrlEnvVar,
|
|
2006
|
-
"ARCHAL_AUTH_URL",
|
|
2007
|
-
"ARCHAL_AUTH_BASE_URL",
|
|
2008
|
-
"ARCHAL_API_URL",
|
|
2009
|
-
"ARCHAL_API_BASE_URL"
|
|
2010
|
-
])];
|
|
2011
|
-
return readFirstConfiguredBaseUrl(envVars) ?? DEFAULT_AUTH_BASE_URL;
|
|
2012
|
-
}
|
|
2013
1912
|
function isImplicitTestSandboxFlow() {
|
|
2014
1913
|
if (trimEnv("ARCHAL_HOME")) {
|
|
2015
1914
|
return false;
|
|
@@ -2026,59 +1925,11 @@ function readExplicitEnvCredentials(envName) {
|
|
|
2026
1925
|
if (!token) {
|
|
2027
1926
|
return { kind: "missing" };
|
|
2028
1927
|
}
|
|
2029
|
-
const
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
if (isWorkspaceApiKey(token)) {
|
|
2033
|
-
return {
|
|
2034
|
-
kind: "valid",
|
|
2035
|
-
credentials: {
|
|
2036
|
-
token,
|
|
2037
|
-
refreshToken: "",
|
|
2038
|
-
email: "(workspace-api-key)",
|
|
2039
|
-
plan: "pro",
|
|
2040
|
-
selectedCloneIds: [],
|
|
2041
|
-
expiresAt: nowSeconds + WORKSPACE_API_KEY_EXPIRES_SECONDS
|
|
2042
|
-
}
|
|
2043
|
-
};
|
|
2044
|
-
}
|
|
2045
|
-
return {
|
|
2046
|
-
kind: "invalid",
|
|
2047
|
-
message: `${envName} must be a JWT with valid plan and exp claims or a workspace API key (archal_ws_...).`
|
|
2048
|
-
};
|
|
2049
|
-
}
|
|
2050
|
-
const email = typeof claims["email"] === "string" ? claims["email"] : `(from ${envName})`;
|
|
2051
|
-
if (!isPlan(claims["plan"])) {
|
|
2052
|
-
return {
|
|
2053
|
-
kind: "invalid",
|
|
2054
|
-
message: `${envName} JWT does not contain a valid plan claim.`
|
|
2055
|
-
};
|
|
2056
|
-
}
|
|
2057
|
-
const plan = claims["plan"];
|
|
2058
|
-
if (typeof claims["exp"] !== "number" || !Number.isFinite(claims["exp"])) {
|
|
2059
|
-
return {
|
|
2060
|
-
kind: "invalid",
|
|
2061
|
-
message: `${envName} JWT does not contain a valid exp claim.`
|
|
2062
|
-
};
|
|
2063
|
-
}
|
|
2064
|
-
const expiresAt = claims["exp"];
|
|
2065
|
-
if (expiresAt <= nowSeconds) {
|
|
2066
|
-
return {
|
|
2067
|
-
kind: "invalid",
|
|
2068
|
-
message: `${envName} is expired. Remove it or replace it with a valid token.`
|
|
2069
|
-
};
|
|
1928
|
+
const parsed = parseEnvToken(token, envName);
|
|
1929
|
+
if (parsed.status !== "ok") {
|
|
1930
|
+
return { kind: "invalid", message: parsed.message };
|
|
2070
1931
|
}
|
|
2071
|
-
return {
|
|
2072
|
-
kind: "valid",
|
|
2073
|
-
credentials: {
|
|
2074
|
-
token,
|
|
2075
|
-
refreshToken: "",
|
|
2076
|
-
email,
|
|
2077
|
-
plan,
|
|
2078
|
-
selectedCloneIds: [],
|
|
2079
|
-
expiresAt
|
|
2080
|
-
}
|
|
2081
|
-
};
|
|
1932
|
+
return { kind: "valid", credentials: parsed.credentials };
|
|
2082
1933
|
}
|
|
2083
1934
|
function readStoredCredentials(includeExpired = false) {
|
|
2084
1935
|
prepareStoredCredentialSources();
|
|
@@ -2110,16 +1961,6 @@ function resolveCredentialsWithSource(tokenEnvVar, includeExpiredStored = false)
|
|
|
2110
1961
|
}
|
|
2111
1962
|
return { credentials: storedCredentials, source: "stored" };
|
|
2112
1963
|
}
|
|
2113
|
-
function resolveHostedCredentials(tokenEnvVar = "ARCHAL_TOKEN") {
|
|
2114
|
-
return resolveCredentialsWithSource(tokenEnvVar)?.credentials ?? null;
|
|
2115
|
-
}
|
|
2116
|
-
function getCredentials2(tokenEnvVar = "ARCHAL_TOKEN") {
|
|
2117
|
-
const credentials = resolveHostedCredentials(tokenEnvVar);
|
|
2118
|
-
if (!credentials) {
|
|
2119
|
-
return null;
|
|
2120
|
-
}
|
|
2121
|
-
return credentials.expiresAt > Math.floor(Date.now() / 1e3) ? credentials : null;
|
|
2122
|
-
}
|
|
2123
1964
|
function prepareStoredCredentialSources() {
|
|
2124
1965
|
if (isImplicitTestSandboxFlow()) {
|
|
2125
1966
|
seedTestSandboxCredentialsFromRealHome();
|
|
@@ -2205,7 +2046,15 @@ async function resolveCurrentCredentials(credentials, source, forceValidation, a
|
|
|
2205
2046
|
}
|
|
2206
2047
|
async function createHostedAuthLease(options = {}) {
|
|
2207
2048
|
const tokenEnvVar = options.tokenEnvVar ?? "ARCHAL_TOKEN";
|
|
2208
|
-
const authBaseUrl =
|
|
2049
|
+
const authBaseUrl = getConfiguredAuthValidationBaseUrl({
|
|
2050
|
+
apiUrlEnvVar: options.apiUrlEnvVar,
|
|
2051
|
+
authUrlEnvVar: options.authUrlEnvVar
|
|
2052
|
+
});
|
|
2053
|
+
if (!authBaseUrl) {
|
|
2054
|
+
throw new Error(
|
|
2055
|
+
"Hosted auth validation requires ARCHAL_AUTH_URL or ARCHAL_API_URL when ARCHAL_STRICT_ENDPOINTS=1."
|
|
2056
|
+
);
|
|
2057
|
+
}
|
|
2209
2058
|
const resolved = resolveCredentialsWithSource(tokenEnvVar, true);
|
|
2210
2059
|
if (!resolved) {
|
|
2211
2060
|
const tokenSources = Array.from(/* @__PURE__ */ new Set([tokenEnvVar, "ARCHAL_TOKEN"])).join(", ");
|
|
@@ -2783,7 +2632,7 @@ function installReporterLifecycleCheck(projectName) {
|
|
|
2783
2632
|
return;
|
|
2784
2633
|
}
|
|
2785
2634
|
process.stderr.write(
|
|
2786
|
-
'\n\x1B[33m\x1B[1mArchal Vitest
|
|
2635
|
+
'\n\x1B[33m\x1B[1mArchal Vitest reporter did not finish lifecycle diagnostics\n\x1B[0m\x1B[33mThe Archal reporter started, but Vitest did not call its final\nlifecycle step. Benchmark Results are submitted by the scenario runner.\n\nCommon causes:\n - A Vitest upgrade changed per-project reporter lifecycle timing.\n - A consumer config filtered out reporters (look for reporter overrides).\n - The ArchalReporter threw before reaching collectAndReport.\n\nWhat to check:\n 1. Grep stderr for "[archal/reporter]". If any line appears, the\n reporter did run and this warning is a false positive.\n 2. If no [archal/reporter] lines exist at all, the reporter was\n installed but never called. Verify your vitest config wires it\n at the level Vitest actually honors (workspace root vs project).\n'
|
|
2787
2636
|
);
|
|
2788
2637
|
process.stderr.write("\x1B[0m\n");
|
|
2789
2638
|
for (const survivor of survivors) {
|
|
@@ -2831,7 +2680,7 @@ function installWorkspaceReporterCheck(projectNames) {
|
|
|
2831
2680
|
return;
|
|
2832
2681
|
}
|
|
2833
2682
|
process.stderr.write(
|
|
2834
|
-
"\n\x1B[33m\x1B[1mArchal Vitest did not
|
|
2683
|
+
"\n\x1B[33m\x1B[1mArchal Vitest did not run workspace reporter diagnostics\n\x1B[0m\x1B[33marchalVitestWorkspace() configured hosted clone projects, but no\nroot Archal reporter was registered. Requests were routed to the\nhosted clones, but reporter lifecycle diagnostics were skipped.\n\nFix: add a root vitest.config.ts alongside vitest.workspace.ts:\n\n import { defineConfig } from 'vitest/config';\n import { archalVitestRootConfig } from 'archal/vitest';\n\n export default defineConfig(archalVitestRootConfig());\n\nIf you do not need workspace mode, use withArchal() instead.\n\x1B[0m\n"
|
|
2835
2684
|
);
|
|
2836
2685
|
for (const survivor of survivors) {
|
|
2837
2686
|
try {
|
|
@@ -2892,7 +2741,7 @@ function installImportSentinel() {
|
|
|
2892
2741
|
if (process.env[ARCHAL_VITEST_CONFIG_ENV]) return;
|
|
2893
2742
|
warningWritten = true;
|
|
2894
2743
|
process.stderr.write(
|
|
2895
|
-
"\n\x1B[33m\x1B[1mArchal Vitest was imported but not configured\n\x1B[0m\x1B[33mSomething in your test run imported `archal/vitest`, but no\nArchal Vitest helper was called (`withArchal`, `archalVitestProject`,\n`archalVitestRootConfig`).
|
|
2744
|
+
"\n\x1B[33m\x1B[1mArchal Vitest was imported but not configured\n\x1B[0m\x1B[33mSomething in your test run imported `archal/vitest`, but no\nArchal Vitest helper was called (`withArchal`, `archalVitestProject`,\n`archalVitestRootConfig`). Benchmark Results are submitted by the scenario runner.\n\nFix: in your vitest.config.ts, wrap your test block with withArchal():\n\n import { defineConfig } from 'vitest/config';\n import { withArchal } from 'archal/vitest';\n export default defineConfig({\n test: withArchal({}, { services: {} }),\n });\n\nOr run `archal init` from your project root and we will wire it for you.\n\x1B[0m\n"
|
|
2896
2745
|
);
|
|
2897
2746
|
};
|
|
2898
2747
|
const sigintHandler = () => {
|
|
@@ -2911,22 +2760,6 @@ function installImportSentinel() {
|
|
|
2911
2760
|
registeredSigtermListener = sigtermHandler;
|
|
2912
2761
|
}
|
|
2913
2762
|
|
|
2914
|
-
// src/runtime/session-snapshot.ts
|
|
2915
|
-
var ARCHAL_VITEST_CONFIG_ENV2 = "ARCHAL_VITEST_CONFIG";
|
|
2916
|
-
function readArchalVitestConfigFromEnv() {
|
|
2917
|
-
const encoded = process.env[ARCHAL_VITEST_CONFIG_ENV2];
|
|
2918
|
-
if (!encoded) {
|
|
2919
|
-
throw new Error(`Missing ${ARCHAL_VITEST_CONFIG_ENV2}. archalVitestProject() must set worker config before bootstrap.`);
|
|
2920
|
-
}
|
|
2921
|
-
return readArchalVitestConfig(encoded);
|
|
2922
|
-
}
|
|
2923
|
-
function readArchalVitestConfig(encoded) {
|
|
2924
|
-
if (!encoded) {
|
|
2925
|
-
throw new Error(`Missing ${ARCHAL_VITEST_CONFIG_ENV2}. archalVitestProject() must set worker config before bootstrap.`);
|
|
2926
|
-
}
|
|
2927
|
-
return decodeConfig(encoded);
|
|
2928
|
-
}
|
|
2929
|
-
|
|
2930
2763
|
// ../route-runtime-core/src/errors.ts
|
|
2931
2764
|
var RouteRuntimePolicyError = class extends Error {
|
|
2932
2765
|
code;
|
|
@@ -3243,9 +3076,9 @@ var githubRouteManifest = {
|
|
|
3243
3076
|
manifestVersion: "2026-04-02.github.v1",
|
|
3244
3077
|
baselineSeed: "small-project",
|
|
3245
3078
|
routeDomains: [
|
|
3079
|
+
exactDomain("github.com"),
|
|
3246
3080
|
exactDomain("api.github.com"),
|
|
3247
3081
|
exactDomain("uploads.github.com"),
|
|
3248
|
-
exactDomain("github.com"),
|
|
3249
3082
|
exactDomain("raw.githubusercontent.com")
|
|
3250
3083
|
],
|
|
3251
3084
|
// Block adjacent GitHub-owned domains that tests don't need. Keep raw
|
|
@@ -3258,7 +3091,6 @@ var githubRouteManifest = {
|
|
|
3258
3091
|
],
|
|
3259
3092
|
routePathRewrite: rewriteGitHubRawContentPath,
|
|
3260
3093
|
warningDomains: [
|
|
3261
|
-
suffixDomain("github.com"),
|
|
3262
3094
|
suffixDomain("githubusercontent.com")
|
|
3263
3095
|
],
|
|
3264
3096
|
diagnostics: {
|
|
@@ -4593,19 +4425,13 @@ var ROUTE_RUNTIME_DISPATCHING_ROUTE_KINDS = new Set(ROUTE_RUNTIME_PUBLIC_ROUTE_K
|
|
|
4593
4425
|
// ../route-runtime-core/src/service-profiles/stripe.ts
|
|
4594
4426
|
var stripeCompatibilityProfile = buildServiceCompatibilityProfile(stripeRouteManifest);
|
|
4595
4427
|
|
|
4596
|
-
// ../../clones/core/dist/chunk-
|
|
4428
|
+
// ../../clones/core/dist/chunk-457KV5BB.js
|
|
4597
4429
|
var manifest_default = [
|
|
4598
4430
|
{
|
|
4599
|
-
name: "
|
|
4600
|
-
package: "@archal/clone-
|
|
4601
|
-
path: "clones/
|
|
4602
|
-
stage: "
|
|
4603
|
-
display: {
|
|
4604
|
-
icon: "AP",
|
|
4605
|
-
name: "Apify",
|
|
4606
|
-
description: "Actors, runs, datasets, key-value stores, and request queues.",
|
|
4607
|
-
toolCount: 59
|
|
4608
|
-
},
|
|
4431
|
+
name: "agentmail",
|
|
4432
|
+
package: "@archal/clone-agentmail",
|
|
4433
|
+
path: "clones/agentmail",
|
|
4434
|
+
stage: "internal",
|
|
4609
4435
|
transport: "rest",
|
|
4610
4436
|
hostedRuntime: {
|
|
4611
4437
|
enabled: true,
|
|
@@ -4613,15 +4439,62 @@ var manifest_default = [
|
|
|
4613
4439
|
requiresEmptySeed: true
|
|
4614
4440
|
},
|
|
4615
4441
|
cli: {
|
|
4616
|
-
bundleAssets:
|
|
4617
|
-
bundleToolSnapshot:
|
|
4442
|
+
bundleAssets: false,
|
|
4443
|
+
bundleToolSnapshot: false
|
|
4618
4444
|
},
|
|
4619
4445
|
routeProxy: {
|
|
4620
|
-
enabled:
|
|
4621
|
-
domains: [
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4446
|
+
enabled: false,
|
|
4447
|
+
domains: []
|
|
4448
|
+
},
|
|
4449
|
+
seeds: {
|
|
4450
|
+
generatedCatalog: false,
|
|
4451
|
+
default: "empty"
|
|
4452
|
+
},
|
|
4453
|
+
smoke: {
|
|
4454
|
+
production: "none"
|
|
4455
|
+
},
|
|
4456
|
+
architecture: {
|
|
4457
|
+
class: "replay-shell",
|
|
4458
|
+
summary: "AgentMail (api.agentmail.to /v0) replay-shell ported from the forge lineage: REST routes replay the harvested recording corpus with per-operation response shaping; promote only after inbox/thread/draft mutation invariants replace recording-coupled fallbacks.",
|
|
4459
|
+
domainPrimitives: [
|
|
4460
|
+
"inbox lifecycle state",
|
|
4461
|
+
"thread and message state",
|
|
4462
|
+
"draft and webhook lifecycle state"
|
|
4463
|
+
],
|
|
4464
|
+
promotionEvidence: [
|
|
4465
|
+
"clones/agentmail/SPEC.md tracks inbox/thread/draft/webhook handlers mutating StateEngine state",
|
|
4466
|
+
"clones/agentmail/SPEC.md tracks create/update/send/delete sequence invariants and reset determinism",
|
|
4467
|
+
"runtime recording-backed handlers in clones/agentmail/src/rest/handlers.ts and recordings.ts must be replaced by state-derived handlers before promotion"
|
|
4468
|
+
]
|
|
4469
|
+
}
|
|
4470
|
+
},
|
|
4471
|
+
{
|
|
4472
|
+
name: "apify",
|
|
4473
|
+
package: "@archal/clone-apify",
|
|
4474
|
+
path: "clones/apify",
|
|
4475
|
+
stage: "preview",
|
|
4476
|
+
display: {
|
|
4477
|
+
icon: "AP",
|
|
4478
|
+
name: "Apify",
|
|
4479
|
+
description: "Actors, runs, datasets, key-value stores, and request queues.",
|
|
4480
|
+
toolCount: 59
|
|
4481
|
+
},
|
|
4482
|
+
transport: "rest",
|
|
4483
|
+
hostedRuntime: {
|
|
4484
|
+
enabled: true,
|
|
4485
|
+
requiresDist: true,
|
|
4486
|
+
requiresEmptySeed: true
|
|
4487
|
+
},
|
|
4488
|
+
cli: {
|
|
4489
|
+
bundleAssets: true,
|
|
4490
|
+
bundleToolSnapshot: true
|
|
4491
|
+
},
|
|
4492
|
+
routeProxy: {
|
|
4493
|
+
enabled: true,
|
|
4494
|
+
domains: [
|
|
4495
|
+
{
|
|
4496
|
+
domain: "api.apify.com"
|
|
4497
|
+
},
|
|
4625
4498
|
{
|
|
4626
4499
|
domain: "apify.com"
|
|
4627
4500
|
}
|
|
@@ -4643,7 +4516,8 @@ var manifest_default = [
|
|
|
4643
4516
|
"fixture-backed fallback semantics for uncovered REST paths"
|
|
4644
4517
|
],
|
|
4645
4518
|
behaviorOwner: "src/upstream.ts"
|
|
4646
|
-
}
|
|
4519
|
+
},
|
|
4520
|
+
opsCoverage: null
|
|
4647
4521
|
},
|
|
4648
4522
|
{
|
|
4649
4523
|
name: "box",
|
|
@@ -4694,7 +4568,7 @@ var manifest_default = [
|
|
|
4694
4568
|
icon: "CC",
|
|
4695
4569
|
name: "Cal.com",
|
|
4696
4570
|
description: "Event types, schedules, availability slots, bookings, calendars, and webhooks.",
|
|
4697
|
-
toolCount:
|
|
4571
|
+
toolCount: 35
|
|
4698
4572
|
},
|
|
4699
4573
|
transport: "both",
|
|
4700
4574
|
hostedRuntime: {
|
|
@@ -4742,7 +4616,7 @@ var manifest_default = [
|
|
|
4742
4616
|
icon: "CU",
|
|
4743
4617
|
name: "ClickUp",
|
|
4744
4618
|
description: "Teams, spaces, folders, lists, tasks, comments, tags, time tracking, and checklists.",
|
|
4745
|
-
toolCount:
|
|
4619
|
+
toolCount: 123
|
|
4746
4620
|
},
|
|
4747
4621
|
transport: "both",
|
|
4748
4622
|
hostedRuntime: {
|
|
@@ -4783,7 +4657,7 @@ var manifest_default = [
|
|
|
4783
4657
|
icon: "CI",
|
|
4784
4658
|
name: "Customer.io",
|
|
4785
4659
|
description: "Messaging automation across campaigns, broadcasts, transactional email, segments, customers, and message delivery.",
|
|
4786
|
-
toolCount:
|
|
4660
|
+
toolCount: 129
|
|
4787
4661
|
},
|
|
4788
4662
|
transport: "rest",
|
|
4789
4663
|
hostedRuntime: {
|
|
@@ -4892,6 +4766,17 @@ var manifest_default = [
|
|
|
4892
4766
|
{
|
|
4893
4767
|
domain: "discordapp.com"
|
|
4894
4768
|
}
|
|
4769
|
+
],
|
|
4770
|
+
hardFailDomains: [
|
|
4771
|
+
{
|
|
4772
|
+
domain: "cdn.discordapp.com"
|
|
4773
|
+
},
|
|
4774
|
+
{
|
|
4775
|
+
domain: "media.discordapp.net"
|
|
4776
|
+
},
|
|
4777
|
+
{
|
|
4778
|
+
domain: "gateway.discord.gg"
|
|
4779
|
+
}
|
|
4895
4780
|
]
|
|
4896
4781
|
},
|
|
4897
4782
|
seeds: {
|
|
@@ -4918,7 +4803,8 @@ var manifest_default = [
|
|
|
4918
4803
|
"thread",
|
|
4919
4804
|
"webhook",
|
|
4920
4805
|
"slash command"
|
|
4921
|
-
]
|
|
4806
|
+
],
|
|
4807
|
+
opsCoverage: 14
|
|
4922
4808
|
},
|
|
4923
4809
|
{
|
|
4924
4810
|
name: "dropbox",
|
|
@@ -4954,7 +4840,7 @@ var manifest_default = [
|
|
|
4954
4840
|
"sharing permissions",
|
|
4955
4841
|
"delta/list-folder cursors"
|
|
4956
4842
|
],
|
|
4957
|
-
behaviorOwner: "src/
|
|
4843
|
+
behaviorOwner: "src/register-tools.ts"
|
|
4958
4844
|
}
|
|
4959
4845
|
},
|
|
4960
4846
|
{
|
|
@@ -5033,7 +4919,8 @@ var manifest_default = [
|
|
|
5033
4919
|
"clones/firecrawl/SPEC.md tracks runtime recording-backed handlers replaced by state-derived crawl/job responses",
|
|
5034
4920
|
"clones/firecrawl/SPEC.md tracks status/progress/replay determinism invariants"
|
|
5035
4921
|
]
|
|
5036
|
-
}
|
|
4922
|
+
},
|
|
4923
|
+
opsCoverage: 77
|
|
5037
4924
|
},
|
|
5038
4925
|
{
|
|
5039
4926
|
name: "freshdesk",
|
|
@@ -5100,6 +4987,9 @@ var manifest_default = [
|
|
|
5100
4987
|
routeProxy: {
|
|
5101
4988
|
enabled: true,
|
|
5102
4989
|
domains: [
|
|
4990
|
+
{
|
|
4991
|
+
domain: "github.com"
|
|
4992
|
+
},
|
|
5103
4993
|
{
|
|
5104
4994
|
domain: "api.github.com"
|
|
5105
4995
|
},
|
|
@@ -5107,10 +4997,18 @@ var manifest_default = [
|
|
|
5107
4997
|
domain: "uploads.github.com"
|
|
5108
4998
|
},
|
|
5109
4999
|
{
|
|
5110
|
-
domain: "
|
|
5000
|
+
domain: "raw.githubusercontent.com"
|
|
5001
|
+
}
|
|
5002
|
+
],
|
|
5003
|
+
hardFailDomains: [
|
|
5004
|
+
{
|
|
5005
|
+
domain: "gist.github.com"
|
|
5111
5006
|
},
|
|
5112
5007
|
{
|
|
5113
|
-
domain: "
|
|
5008
|
+
domain: "objects.githubusercontent.com"
|
|
5009
|
+
},
|
|
5010
|
+
{
|
|
5011
|
+
domain: "codeload.github.com"
|
|
5114
5012
|
}
|
|
5115
5013
|
]
|
|
5116
5014
|
},
|
|
@@ -5140,7 +5038,8 @@ var manifest_default = [
|
|
|
5140
5038
|
"create_issue",
|
|
5141
5039
|
"create_pull_request",
|
|
5142
5040
|
"merge_pull_request"
|
|
5143
|
-
]
|
|
5041
|
+
],
|
|
5042
|
+
opsCoverage: 96
|
|
5144
5043
|
},
|
|
5145
5044
|
{
|
|
5146
5045
|
name: "gitlab",
|
|
@@ -5151,7 +5050,7 @@ var manifest_default = [
|
|
|
5151
5050
|
icon: "GL",
|
|
5152
5051
|
name: "GitLab",
|
|
5153
5052
|
description: "Projects, branches, commits, issues, merge requests, pipelines, labels, milestones, releases, and webhooks.",
|
|
5154
|
-
toolCount:
|
|
5053
|
+
toolCount: 559
|
|
5155
5054
|
},
|
|
5156
5055
|
transport: "both",
|
|
5157
5056
|
hostedRuntime: {
|
|
@@ -5265,7 +5164,88 @@ var manifest_default = [
|
|
|
5265
5164
|
"google sheet",
|
|
5266
5165
|
"google sheets",
|
|
5267
5166
|
"contacts"
|
|
5268
|
-
]
|
|
5167
|
+
],
|
|
5168
|
+
opsCoverage: 64
|
|
5169
|
+
},
|
|
5170
|
+
{
|
|
5171
|
+
name: "guesty",
|
|
5172
|
+
package: "@archal/clone-guesty",
|
|
5173
|
+
path: "clones/guesty",
|
|
5174
|
+
stage: "internal",
|
|
5175
|
+
transport: "rest",
|
|
5176
|
+
hostedRuntime: {
|
|
5177
|
+
enabled: true,
|
|
5178
|
+
requiresDist: true,
|
|
5179
|
+
requiresEmptySeed: true
|
|
5180
|
+
},
|
|
5181
|
+
cli: {
|
|
5182
|
+
bundleAssets: false,
|
|
5183
|
+
bundleToolSnapshot: false
|
|
5184
|
+
},
|
|
5185
|
+
routeProxy: {
|
|
5186
|
+
enabled: false,
|
|
5187
|
+
domains: []
|
|
5188
|
+
},
|
|
5189
|
+
seeds: {
|
|
5190
|
+
generatedCatalog: false,
|
|
5191
|
+
default: "empty"
|
|
5192
|
+
},
|
|
5193
|
+
smoke: {
|
|
5194
|
+
production: "none"
|
|
5195
|
+
},
|
|
5196
|
+
architecture: {
|
|
5197
|
+
class: "replay-shell",
|
|
5198
|
+
summary: "Current internal Guesty package is a bootstrap scaffold with no registered tools or REST behavior; promote to replay-shell preview only after the Open API listing/reservation/guest surface is harvested and replayed against a Guesty Pro account.",
|
|
5199
|
+
domainPrimitives: [
|
|
5200
|
+
"listing, reservation, and guest read projections",
|
|
5201
|
+
"availability-calendar overlay",
|
|
5202
|
+
"future webhook delivery behavior"
|
|
5203
|
+
],
|
|
5204
|
+
promotionEvidence: [
|
|
5205
|
+
"clones/guesty/SPEC.md tracks listing/reservation/guest handlers mutating StateEngine",
|
|
5206
|
+
"clones/guesty/SPEC.md tracks reservation create/cancel/modify lifecycle and read-after-write invariants"
|
|
5207
|
+
]
|
|
5208
|
+
}
|
|
5209
|
+
},
|
|
5210
|
+
{
|
|
5211
|
+
name: "hostaway",
|
|
5212
|
+
package: "@archal/clone-hostaway",
|
|
5213
|
+
path: "clones/hostaway",
|
|
5214
|
+
stage: "internal",
|
|
5215
|
+
transport: "rest",
|
|
5216
|
+
hostedRuntime: {
|
|
5217
|
+
enabled: true,
|
|
5218
|
+
requiresDist: true,
|
|
5219
|
+
requiresEmptySeed: true
|
|
5220
|
+
},
|
|
5221
|
+
cli: {
|
|
5222
|
+
bundleAssets: false,
|
|
5223
|
+
bundleToolSnapshot: false
|
|
5224
|
+
},
|
|
5225
|
+
routeProxy: {
|
|
5226
|
+
enabled: false,
|
|
5227
|
+
domains: []
|
|
5228
|
+
},
|
|
5229
|
+
seeds: {
|
|
5230
|
+
generatedCatalog: false,
|
|
5231
|
+
default: "empty"
|
|
5232
|
+
},
|
|
5233
|
+
smoke: {
|
|
5234
|
+
production: "none"
|
|
5235
|
+
},
|
|
5236
|
+
architecture: {
|
|
5237
|
+
class: "replay-shell",
|
|
5238
|
+
summary: "Current internal Hostaway package is a bootstrap scaffold with no registered tools or REST behavior; promote to replay-shell preview only after the Public API listing/reservation/calendar surface is harvested and replayed against a Hostaway account.",
|
|
5239
|
+
domainPrimitives: [
|
|
5240
|
+
"listing, reservation, and calendar read projections",
|
|
5241
|
+
"unified-inbox conversation overlay",
|
|
5242
|
+
"future webhook delivery behavior"
|
|
5243
|
+
],
|
|
5244
|
+
promotionEvidence: [
|
|
5245
|
+
"clones/hostaway/SPEC.md tracks listing/reservation/calendar handlers mutating StateEngine",
|
|
5246
|
+
"clones/hostaway/SPEC.md tracks reservation create/cancel/modify lifecycle and read-after-write invariants"
|
|
5247
|
+
]
|
|
5248
|
+
}
|
|
5269
5249
|
},
|
|
5270
5250
|
{
|
|
5271
5251
|
name: "hubspot",
|
|
@@ -5276,7 +5256,7 @@ var manifest_default = [
|
|
|
5276
5256
|
icon: "HS",
|
|
5277
5257
|
name: "HubSpot",
|
|
5278
5258
|
description: "CRM contacts, companies, deals, tickets, and engagements.",
|
|
5279
|
-
toolCount:
|
|
5259
|
+
toolCount: 44
|
|
5280
5260
|
},
|
|
5281
5261
|
transport: "rest",
|
|
5282
5262
|
hostedRuntime: {
|
|
@@ -5315,7 +5295,8 @@ var manifest_default = [
|
|
|
5315
5295
|
"clones/hubspot/SPEC.md tracks runtime recording reads removed from exported handlers",
|
|
5316
5296
|
"clones/hubspot/SPEC.md tracks CRM alias and association sequence invariants"
|
|
5317
5297
|
]
|
|
5318
|
-
}
|
|
5298
|
+
},
|
|
5299
|
+
opsCoverage: 99
|
|
5319
5300
|
},
|
|
5320
5301
|
{
|
|
5321
5302
|
name: "jira",
|
|
@@ -5378,7 +5359,8 @@ var manifest_default = [
|
|
|
5378
5359
|
"jira board",
|
|
5379
5360
|
"sprint",
|
|
5380
5361
|
"epic"
|
|
5381
|
-
]
|
|
5362
|
+
],
|
|
5363
|
+
opsCoverage: 80
|
|
5382
5364
|
},
|
|
5383
5365
|
{
|
|
5384
5366
|
name: "linear",
|
|
@@ -5389,7 +5371,7 @@ var manifest_default = [
|
|
|
5389
5371
|
icon: "LN",
|
|
5390
5372
|
name: "Linear",
|
|
5391
5373
|
description: "Issues, projects, teams, cycles, and workflows.",
|
|
5392
|
-
toolCount:
|
|
5374
|
+
toolCount: 53
|
|
5393
5375
|
},
|
|
5394
5376
|
transport: "both",
|
|
5395
5377
|
hostedRuntime: {
|
|
@@ -5433,7 +5415,8 @@ var manifest_default = [
|
|
|
5433
5415
|
"linear project",
|
|
5434
5416
|
"linear cycle",
|
|
5435
5417
|
"cycle"
|
|
5436
|
-
]
|
|
5418
|
+
],
|
|
5419
|
+
opsCoverage: 98
|
|
5437
5420
|
},
|
|
5438
5421
|
{
|
|
5439
5422
|
name: "mailchimp",
|
|
@@ -5518,6 +5501,47 @@ var manifest_default = [
|
|
|
5518
5501
|
"clones/ownerrez/SPEC.md tracks runtime recording-backed handlers replaced for the promoted reservation/payment slice",
|
|
5519
5502
|
"clones/ownerrez/SPEC.md tracks availability/payment invariants"
|
|
5520
5503
|
]
|
|
5504
|
+
},
|
|
5505
|
+
opsCoverage: 100
|
|
5506
|
+
},
|
|
5507
|
+
{
|
|
5508
|
+
name: "outlook",
|
|
5509
|
+
package: "@archal/clone-outlook",
|
|
5510
|
+
path: "clones/outlook",
|
|
5511
|
+
stage: "internal",
|
|
5512
|
+
transport: "rest",
|
|
5513
|
+
hostedRuntime: {
|
|
5514
|
+
enabled: true,
|
|
5515
|
+
requiresDist: true,
|
|
5516
|
+
requiresEmptySeed: true
|
|
5517
|
+
},
|
|
5518
|
+
cli: {
|
|
5519
|
+
bundleAssets: false,
|
|
5520
|
+
bundleToolSnapshot: false
|
|
5521
|
+
},
|
|
5522
|
+
routeProxy: {
|
|
5523
|
+
enabled: false,
|
|
5524
|
+
domains: []
|
|
5525
|
+
},
|
|
5526
|
+
seeds: {
|
|
5527
|
+
generatedCatalog: false,
|
|
5528
|
+
default: "empty"
|
|
5529
|
+
},
|
|
5530
|
+
smoke: {
|
|
5531
|
+
production: "none"
|
|
5532
|
+
},
|
|
5533
|
+
architecture: {
|
|
5534
|
+
class: "replay-shell",
|
|
5535
|
+
summary: "Outlook mail (Microsoft Graph v1.0, mail-only) replay-shell ported from the forge lineage: REST routes replay harvested Graph recordings over a StateEngine mail model; promote only after folder/message mutation invariants and broader Graph surface land.",
|
|
5536
|
+
domainPrimitives: [
|
|
5537
|
+
"mail folder hierarchy and well-known folder state",
|
|
5538
|
+
"message lifecycle state (draft, send, move, copy, delete)",
|
|
5539
|
+
"attachment state"
|
|
5540
|
+
],
|
|
5541
|
+
promotionEvidence: [
|
|
5542
|
+
"clones/outlook/SPEC.md tracks mail folder/message/attachment handlers mutating StateEngine state",
|
|
5543
|
+
"clones/outlook/SPEC.md tracks draft/send/move/copy/delete sequence invariants and reset determinism"
|
|
5544
|
+
]
|
|
5521
5545
|
}
|
|
5522
5546
|
},
|
|
5523
5547
|
{
|
|
@@ -5549,7 +5573,11 @@ var manifest_default = [
|
|
|
5549
5573
|
architecture: {
|
|
5550
5574
|
class: "redesign-before-expansion",
|
|
5551
5575
|
summary: "PostHog currently models admin resources and frozen insight/dashboard projections; event ingestion, query execution, and feature flag evaluation need a simulator contract before expansion.",
|
|
5552
|
-
domainPrimitives: [
|
|
5576
|
+
domainPrimitives: [
|
|
5577
|
+
"event ingestion",
|
|
5578
|
+
"query execution",
|
|
5579
|
+
"feature flag evaluation"
|
|
5580
|
+
],
|
|
5553
5581
|
redesignContract: "docs/internal/dev/clones/redesign-contracts/posthog.md"
|
|
5554
5582
|
}
|
|
5555
5583
|
},
|
|
@@ -5605,7 +5633,8 @@ var manifest_default = [
|
|
|
5605
5633
|
"clones/pricelabs/SPEC.md tracks runtime recording-backed handlers replaced for the promoted pricing/reservation slice",
|
|
5606
5634
|
"clones/pricelabs/SPEC.md tracks occupancy/rate/replay determinism invariants"
|
|
5607
5635
|
]
|
|
5608
|
-
}
|
|
5636
|
+
},
|
|
5637
|
+
opsCoverage: 100
|
|
5609
5638
|
},
|
|
5610
5639
|
{
|
|
5611
5640
|
name: "quickbooks",
|
|
@@ -5707,7 +5736,8 @@ var manifest_default = [
|
|
|
5707
5736
|
"reimbursement",
|
|
5708
5737
|
"fund",
|
|
5709
5738
|
"card spend"
|
|
5710
|
-
]
|
|
5739
|
+
],
|
|
5740
|
+
opsCoverage: null
|
|
5711
5741
|
},
|
|
5712
5742
|
{
|
|
5713
5743
|
name: "sendgrid",
|
|
@@ -5758,7 +5788,8 @@ var manifest_default = [
|
|
|
5758
5788
|
"clones/sendgrid/SPEC.md tracks runtime recording-backed handlers replaced for send/event/suppression behavior",
|
|
5759
5789
|
"clones/sendgrid/SPEC.md tracks send-to-event and suppression replay invariants"
|
|
5760
5790
|
]
|
|
5761
|
-
}
|
|
5791
|
+
},
|
|
5792
|
+
opsCoverage: 100
|
|
5762
5793
|
},
|
|
5763
5794
|
{
|
|
5764
5795
|
name: "sentry",
|
|
@@ -5769,7 +5800,7 @@ var manifest_default = [
|
|
|
5769
5800
|
icon: "SN",
|
|
5770
5801
|
name: "Sentry",
|
|
5771
5802
|
description: "Error monitoring across organizations, projects, teams, issues, events, releases, and DSN keys.",
|
|
5772
|
-
toolCount:
|
|
5803
|
+
toolCount: 34
|
|
5773
5804
|
},
|
|
5774
5805
|
transport: "rest",
|
|
5775
5806
|
hostedRuntime: {
|
|
@@ -5805,7 +5836,8 @@ var manifest_default = [
|
|
|
5805
5836
|
"release and time-window projections"
|
|
5806
5837
|
],
|
|
5807
5838
|
behaviorOwner: "src/domain/sentry-simulator.ts"
|
|
5808
|
-
}
|
|
5839
|
+
},
|
|
5840
|
+
opsCoverage: null
|
|
5809
5841
|
},
|
|
5810
5842
|
{
|
|
5811
5843
|
name: "slack",
|
|
@@ -5837,6 +5869,23 @@ var manifest_default = [
|
|
|
5837
5869
|
{
|
|
5838
5870
|
domain: "api.slack.com"
|
|
5839
5871
|
}
|
|
5872
|
+
],
|
|
5873
|
+
hardFailDomains: [
|
|
5874
|
+
{
|
|
5875
|
+
domain: "hooks.slack.com"
|
|
5876
|
+
},
|
|
5877
|
+
{
|
|
5878
|
+
domain: "files.slack.com"
|
|
5879
|
+
},
|
|
5880
|
+
{
|
|
5881
|
+
domain: "edgeapi.slack.com"
|
|
5882
|
+
},
|
|
5883
|
+
{
|
|
5884
|
+
domain: "wss-primary.slack.com"
|
|
5885
|
+
},
|
|
5886
|
+
{
|
|
5887
|
+
domain: "wss-backup.slack.com"
|
|
5888
|
+
}
|
|
5840
5889
|
]
|
|
5841
5890
|
},
|
|
5842
5891
|
seeds: {
|
|
@@ -5862,7 +5911,8 @@ var manifest_default = [
|
|
|
5862
5911
|
"send_message",
|
|
5863
5912
|
"slack message",
|
|
5864
5913
|
"direct message"
|
|
5865
|
-
]
|
|
5914
|
+
],
|
|
5915
|
+
opsCoverage: 100
|
|
5866
5916
|
},
|
|
5867
5917
|
{
|
|
5868
5918
|
name: "stripe",
|
|
@@ -5891,6 +5941,14 @@ var manifest_default = [
|
|
|
5891
5941
|
{
|
|
5892
5942
|
domain: "api.stripe.com"
|
|
5893
5943
|
}
|
|
5944
|
+
],
|
|
5945
|
+
hardFailDomains: [
|
|
5946
|
+
{
|
|
5947
|
+
domain: "files.stripe.com"
|
|
5948
|
+
},
|
|
5949
|
+
{
|
|
5950
|
+
domain: "uploads.stripe.com"
|
|
5951
|
+
}
|
|
5894
5952
|
]
|
|
5895
5953
|
},
|
|
5896
5954
|
seeds: {
|
|
@@ -5917,7 +5975,8 @@ var manifest_default = [
|
|
|
5917
5975
|
"subscription",
|
|
5918
5976
|
"invoice",
|
|
5919
5977
|
"charge"
|
|
5920
|
-
]
|
|
5978
|
+
],
|
|
5979
|
+
opsCoverage: null
|
|
5921
5980
|
},
|
|
5922
5981
|
{
|
|
5923
5982
|
name: "woocommerce",
|
|
@@ -6012,7 +6071,8 @@ var manifest_default = [
|
|
|
6012
6071
|
"sql query",
|
|
6013
6072
|
"database table",
|
|
6014
6073
|
"sql"
|
|
6015
|
-
]
|
|
6074
|
+
],
|
|
6075
|
+
opsCoverage: 100
|
|
6016
6076
|
},
|
|
6017
6077
|
{
|
|
6018
6078
|
name: "tavily",
|
|
@@ -6066,7 +6126,8 @@ var manifest_default = [
|
|
|
6066
6126
|
"clones/tavily/SPEC.md tracks runtime recording-backed handlers replaced for the promoted search/extract/research surface",
|
|
6067
6127
|
"clones/tavily/SPEC.md tracks search/extract/research replay determinism invariants"
|
|
6068
6128
|
]
|
|
6069
|
-
}
|
|
6129
|
+
},
|
|
6130
|
+
opsCoverage: 100
|
|
6070
6131
|
},
|
|
6071
6132
|
{
|
|
6072
6133
|
name: "typeform",
|
|
@@ -6152,7 +6213,8 @@ var manifest_default = [
|
|
|
6152
6213
|
"webhook registration state"
|
|
6153
6214
|
],
|
|
6154
6215
|
behaviorOwner: "src/domain/telegram-simulator.ts"
|
|
6155
|
-
}
|
|
6216
|
+
},
|
|
6217
|
+
opsCoverage: null
|
|
6156
6218
|
},
|
|
6157
6219
|
{
|
|
6158
6220
|
name: "twilio",
|
|
@@ -6199,7 +6261,8 @@ var manifest_default = [
|
|
|
6199
6261
|
"clones/twilio/SPEC.md tracks runtime recording-backed handlers replaced for the promoted message/call slice",
|
|
6200
6262
|
"clones/twilio/SPEC.md tracks delivery/status/webhook sequence invariants"
|
|
6201
6263
|
]
|
|
6202
|
-
}
|
|
6264
|
+
},
|
|
6265
|
+
opsCoverage: 92
|
|
6203
6266
|
},
|
|
6204
6267
|
{
|
|
6205
6268
|
name: "unipile",
|
|
@@ -6254,7 +6317,8 @@ var manifest_default = [
|
|
|
6254
6317
|
"clones/unipile/SPEC.md tracks runtime recording-backed handlers replaced for the promoted chat/provider surface",
|
|
6255
6318
|
"clones/unipile/SPEC.md tracks send/delivery/read/webhook sequence invariants"
|
|
6256
6319
|
]
|
|
6257
|
-
}
|
|
6320
|
+
},
|
|
6321
|
+
opsCoverage: 100
|
|
6258
6322
|
},
|
|
6259
6323
|
{
|
|
6260
6324
|
name: "webflow",
|
|
@@ -6265,9 +6329,9 @@ var manifest_default = [
|
|
|
6265
6329
|
icon: "WF",
|
|
6266
6330
|
name: "Webflow",
|
|
6267
6331
|
description: "Sites, pages, CMS collections, items, assets, forms, and webhooks.",
|
|
6268
|
-
toolCount:
|
|
6332
|
+
toolCount: 104
|
|
6269
6333
|
},
|
|
6270
|
-
transport: "
|
|
6334
|
+
transport: "both",
|
|
6271
6335
|
hostedRuntime: {
|
|
6272
6336
|
enabled: true,
|
|
6273
6337
|
requiresDist: true,
|
|
@@ -6296,26 +6360,17 @@ var manifest_default = [
|
|
|
6296
6360
|
production: "clone-surface"
|
|
6297
6361
|
},
|
|
6298
6362
|
architecture: {
|
|
6299
|
-
class: "
|
|
6300
|
-
summary: "Webflow
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
"CMS collection/item overlays",
|
|
6304
|
-
"publish lifecycle captures"
|
|
6305
|
-
],
|
|
6306
|
-
promotionEvidence: [
|
|
6307
|
-
"clones/webflow/SPEC.md tracks staged/live publish projection state model",
|
|
6308
|
-
"clones/webflow/SPEC.md tracks runtime recording-backed handlers replaced for the promoted publish/CMS surface",
|
|
6309
|
-
"clones/webflow/SPEC.md tracks CMS publish/reset sequence invariants"
|
|
6310
|
-
]
|
|
6311
|
-
}
|
|
6363
|
+
class: "standard-core",
|
|
6364
|
+
summary: "Webflow Data API v2 slice models sites, collections, and users as deterministic StateEngine records with state-derived REST routes and a per-boot webhook store; Designer-side surfaces (form components, page DOM editing) and real publish delivery are not claimed."
|
|
6365
|
+
},
|
|
6366
|
+
opsCoverage: 100
|
|
6312
6367
|
}
|
|
6313
6368
|
];
|
|
6314
6369
|
var CLONE_MANIFEST = manifest_default;
|
|
6315
6370
|
var CLONE_NAMES = CLONE_MANIFEST.map((t) => t.name);
|
|
6316
6371
|
var CLONE_PACKAGES = CLONE_MANIFEST.map((t) => t.package);
|
|
6317
6372
|
|
|
6318
|
-
// ../../clones/core/dist/chunk-
|
|
6373
|
+
// ../../clones/core/dist/chunk-UB63UNGS.js
|
|
6319
6374
|
var CLONE_PREFIX_PATTERN = new RegExp(`^(${CLONE_NAMES.join("|")})_`, "i");
|
|
6320
6375
|
|
|
6321
6376
|
// ../../clones/core/dist/chunk-EZKTFYZI.js
|
|
@@ -6384,6 +6439,13 @@ var CLONE_ARCHITECTURE_MANIFEST_FIELDS2 = Object.freeze([
|
|
|
6384
6439
|
]);
|
|
6385
6440
|
var CLONE_ARCHITECTURE_MANIFEST_FIELD_SET2 = new Set(CLONE_ARCHITECTURE_MANIFEST_FIELDS2);
|
|
6386
6441
|
|
|
6442
|
+
// src/runtime/hosted-session-provider.ts
|
|
6443
|
+
var import_node_crypto3 = require("crypto");
|
|
6444
|
+
var import_node_child_process2 = require("child_process");
|
|
6445
|
+
var import_node_fs7 = require("fs");
|
|
6446
|
+
var import_node_path8 = require("path");
|
|
6447
|
+
var import_node_os4 = require("os");
|
|
6448
|
+
|
|
6387
6449
|
// src/runtime/service-profiles.ts
|
|
6388
6450
|
function unsupportedServiceMessage(unsupportedServices) {
|
|
6389
6451
|
const supportedServices = listSharedRouteManifests().map((manifest) => manifest.service).sort();
|
|
@@ -6413,34 +6475,9 @@ function resolveArchalVitestServiceProfiles(services) {
|
|
|
6413
6475
|
}
|
|
6414
6476
|
|
|
6415
6477
|
// src/runtime/hosted-session-provider.ts
|
|
6416
|
-
var import_node_crypto3 = require("crypto");
|
|
6417
|
-
var import_node_child_process2 = require("child_process");
|
|
6418
|
-
var import_node_fs7 = require("fs");
|
|
6419
|
-
var import_node_path8 = require("path");
|
|
6420
|
-
var import_node_os4 = require("os");
|
|
6421
|
-
|
|
6422
|
-
// src/url-resolution.ts
|
|
6423
|
-
function readFirstConfiguredApiBaseUrl(envVars) {
|
|
6424
|
-
for (const envVar of envVars) {
|
|
6425
|
-
const configured = trimEnv(envVar);
|
|
6426
|
-
if (!configured) {
|
|
6427
|
-
continue;
|
|
6428
|
-
}
|
|
6429
|
-
return normalizeApiBaseUrl(configured);
|
|
6430
|
-
}
|
|
6431
|
-
return null;
|
|
6432
|
-
}
|
|
6433
6478
|
function resolveArchalVitestApiBaseUrl(defaultBaseUrl) {
|
|
6434
|
-
return
|
|
6435
|
-
"ARCHAL_VITEST_API_URL",
|
|
6436
|
-
"ARCHAL_API_URL",
|
|
6437
|
-
"ARCHAL_API_BASE_URL",
|
|
6438
|
-
"ARCHAL_AUTH_URL",
|
|
6439
|
-
"ARCHAL_AUTH_BASE_URL"
|
|
6440
|
-
]) ?? defaultBaseUrl;
|
|
6479
|
+
return getConfiguredVitestApiBaseUrl(defaultBaseUrl);
|
|
6441
6480
|
}
|
|
6442
|
-
|
|
6443
|
-
// src/runtime/hosted-session-provider.ts
|
|
6444
6481
|
var COORDINATOR_LOCK_TIMEOUT_MS = 3e4;
|
|
6445
6482
|
var COORDINATOR_STALE_LOCK_MS = COORDINATOR_LOCK_TIMEOUT_MS;
|
|
6446
6483
|
var COORDINATOR_POLL_INTERVAL_MS = 50;
|
|
@@ -7090,6 +7127,20 @@ var VITEST_AUTH_LEASE_OPTIONS = {
|
|
|
7090
7127
|
};
|
|
7091
7128
|
|
|
7092
7129
|
// src/runtime/bootstrap.ts
|
|
7130
|
+
var ARCHAL_VITEST_CONFIG_ENV2 = "ARCHAL_VITEST_CONFIG";
|
|
7131
|
+
function readArchalVitestConfigFromEnv() {
|
|
7132
|
+
const encoded = process.env[ARCHAL_VITEST_CONFIG_ENV2];
|
|
7133
|
+
if (!encoded) {
|
|
7134
|
+
throw new Error(`Missing ${ARCHAL_VITEST_CONFIG_ENV2}. archalVitestProject() must set worker config before bootstrap.`);
|
|
7135
|
+
}
|
|
7136
|
+
return readArchalVitestConfig(encoded);
|
|
7137
|
+
}
|
|
7138
|
+
function readArchalVitestConfig(encoded) {
|
|
7139
|
+
if (!encoded) {
|
|
7140
|
+
throw new Error(`Missing ${ARCHAL_VITEST_CONFIG_ENV2}. archalVitestProject() must set worker config before bootstrap.`);
|
|
7141
|
+
}
|
|
7142
|
+
return decodeConfig(encoded);
|
|
7143
|
+
}
|
|
7093
7144
|
var GLOBAL_RUNTIME_KEY = "__archalVitestRuntime";
|
|
7094
7145
|
var GLOBAL_SESSION_KEY = "__archalVitestSession";
|
|
7095
7146
|
var GLOBAL_CLEANUP_HANDLER_KEY = "__archalVitestRuntimeCleanupHandlerRegistered";
|
|
@@ -7527,14 +7578,8 @@ function getInstalledArchalVitestSession() {
|
|
|
7527
7578
|
}
|
|
7528
7579
|
|
|
7529
7580
|
// src/reporter.ts
|
|
7530
|
-
var import_picomatch = __toESM(require("picomatch"), 1);
|
|
7531
7581
|
var LOG_PREFIX = "[archal/reporter]";
|
|
7532
7582
|
var STRICT_ENV = "ARCHAL_REPORTER_STRICT";
|
|
7533
|
-
var REPORTER_TOKEN_ENV = "ARCHAL_REPORTER_TOKEN";
|
|
7534
|
-
var REPORTER_AUTH_URL_ENV = "ARCHAL_REPORTER_AUTH_URL";
|
|
7535
|
-
var REPORTER_AUTH_BASE_URL_ENV = "ARCHAL_REPORTER_AUTH_BASE_URL";
|
|
7536
|
-
var REPORTER_BYPASS_SECRET_ENV = "ARCHAL_REPORTER_VERCEL_AUTOMATION_BYPASS_SECRET";
|
|
7537
|
-
var REPORTER_WORKSPACE_ENV = "ARCHAL_REPORTER_WORKSPACE_ID";
|
|
7538
7583
|
var WORKSPACE_REPORTER_MARKER_ENV = "ARCHAL_VITEST_WORKSPACE_REPORTER_MARKER";
|
|
7539
7584
|
function isStrict() {
|
|
7540
7585
|
return process.env[STRICT_ENV] === "1";
|
|
@@ -7547,112 +7592,43 @@ function warn(message) {
|
|
|
7547
7592
|
}
|
|
7548
7593
|
process.stderr.write(line);
|
|
7549
7594
|
}
|
|
7550
|
-
function
|
|
7595
|
+
function diagnostic(message) {
|
|
7551
7596
|
process.stderr.write(`${LOG_PREFIX} ${message}
|
|
7552
7597
|
`);
|
|
7553
7598
|
}
|
|
7554
|
-
async function resolveReporterToken() {
|
|
7555
|
-
const explicitReporterToken = process.env[REPORTER_TOKEN_ENV]?.trim();
|
|
7556
|
-
if (explicitReporterToken) {
|
|
7557
|
-
return explicitReporterToken;
|
|
7558
|
-
}
|
|
7559
|
-
try {
|
|
7560
|
-
const creds = getCredentials2();
|
|
7561
|
-
return creds?.token ?? process.env["ARCHAL_TOKEN"]?.trim();
|
|
7562
|
-
} catch (authErr) {
|
|
7563
|
-
warn(`auth resolution failed: ${authErr instanceof Error ? authErr.message : String(authErr)}`);
|
|
7564
|
-
return void 0;
|
|
7565
|
-
}
|
|
7566
|
-
}
|
|
7567
|
-
function resolveReporterBaseUrl() {
|
|
7568
|
-
return (process.env[REPORTER_AUTH_URL_ENV]?.trim() || process.env[REPORTER_AUTH_BASE_URL_ENV]?.trim() || process.env["ARCHAL_AUTH_URL"]?.trim() || process.env["ARCHAL_AUTH_BASE_URL"]?.trim() || "https://www.archal.ai").replace(/\/+$/, "");
|
|
7569
|
-
}
|
|
7570
|
-
function buildReporterHeaders(token) {
|
|
7571
|
-
const headers = new Headers({
|
|
7572
|
-
"content-type": "application/json",
|
|
7573
|
-
authorization: `Bearer ${token}`
|
|
7574
|
-
});
|
|
7575
|
-
const bypassSecret = process.env[REPORTER_BYPASS_SECRET_ENV]?.trim();
|
|
7576
|
-
if (bypassSecret) {
|
|
7577
|
-
headers.set("x-vercel-protection-bypass", bypassSecret);
|
|
7578
|
-
}
|
|
7579
|
-
const workspaceId = resolveReporterWorkspaceId();
|
|
7580
|
-
if (workspaceId) {
|
|
7581
|
-
headers.set("x-archal-workspace", workspaceId);
|
|
7582
|
-
}
|
|
7583
|
-
return headers;
|
|
7584
|
-
}
|
|
7585
|
-
function resolveReporterWorkspaceId() {
|
|
7586
|
-
const reporterWorkspaceId = process.env[REPORTER_WORKSPACE_ENV]?.trim();
|
|
7587
|
-
if (reporterWorkspaceId) {
|
|
7588
|
-
return reporterWorkspaceId;
|
|
7589
|
-
}
|
|
7590
|
-
const cliWorkspaceId = process.env["ARCHAL_WORKSPACE_ID"]?.trim();
|
|
7591
|
-
return cliWorkspaceId || void 0;
|
|
7592
|
-
}
|
|
7593
|
-
function normalizePathForMatch(path) {
|
|
7594
|
-
return path.replaceAll("\\", "/");
|
|
7595
|
-
}
|
|
7596
|
-
function buildIncludeMatcher(pattern) {
|
|
7597
|
-
const normalizedPattern = normalizePathForMatch(pattern).replace(/^\.?\//, "");
|
|
7598
|
-
const patterns = normalizedPattern.startsWith("**/") ? [normalizedPattern] : [normalizedPattern, `**/${normalizedPattern}`];
|
|
7599
|
-
const matchers = patterns.map((candidate) => (0, import_picomatch.default)(candidate, { dot: true }));
|
|
7600
|
-
return (filePath) => {
|
|
7601
|
-
const normalizedFile = normalizePathForMatch(filePath);
|
|
7602
|
-
return matchers.some((matcher) => matcher(normalizedFile));
|
|
7603
|
-
};
|
|
7604
|
-
}
|
|
7605
7599
|
function readEncodedConfigFromTarget(target) {
|
|
7606
7600
|
const env = target?.config?.env;
|
|
7607
7601
|
return env?.[ARCHAL_VITEST_CONFIG_ENV2];
|
|
7608
7602
|
}
|
|
7609
|
-
function readProjectIncludePatterns(project) {
|
|
7610
|
-
const config = project?.config;
|
|
7611
|
-
const include = Array.isArray(config?.include) ? config.include : Array.isArray(config?.test?.include) ? config.test.include : [];
|
|
7612
|
-
return include.filter(
|
|
7613
|
-
(pattern) => typeof pattern === "string" && pattern.length > 0
|
|
7614
|
-
);
|
|
7615
|
-
}
|
|
7616
7603
|
var ArchalReporter = class {
|
|
7617
|
-
startTime = 0;
|
|
7618
7604
|
ctx = null;
|
|
7619
7605
|
lifecycleMarkerPath = "";
|
|
7620
|
-
workspaceReporterMarkerPath = "";
|
|
7621
|
-
projects = [];
|
|
7622
7606
|
/**
|
|
7623
|
-
* In-flight
|
|
7624
|
-
* `onFinished` and `onTestRunEnd` in parallel via `Promise.all
|
|
7625
|
-
*
|
|
7626
|
-
*
|
|
7627
|
-
*
|
|
7628
|
-
* so watch-mode reruns still upload.
|
|
7607
|
+
* In-flight lifecycle promise for the current run. Vitest v3+ fires both
|
|
7608
|
+
* `onFinished` and `onTestRunEnd` in parallel via `Promise.all`, so without
|
|
7609
|
+
* this guard the reporter emits duplicate diagnostics. Reset at the start
|
|
7610
|
+
* of each run (onTestRunStart / onWatcherRerun) so watch-mode reruns still
|
|
7611
|
+
* report.
|
|
7629
7612
|
*/
|
|
7630
|
-
|
|
7613
|
+
activeLifecycle = null;
|
|
7631
7614
|
onInit(ctx) {
|
|
7632
|
-
this.startTime = Date.now();
|
|
7633
7615
|
this.ctx = ctx;
|
|
7634
|
-
|
|
7635
|
-
const projectName = this.projects[0]?.config.projectName ?? "vitest";
|
|
7616
|
+
const projectName = this.resolveProjectName();
|
|
7636
7617
|
this.lifecycleMarkerPath = installReporterLifecycleCheck(projectName);
|
|
7637
|
-
|
|
7638
|
-
markWorkspaceReporterInstalled(
|
|
7639
|
-
this.workspaceReporterMarkerPath = "";
|
|
7618
|
+
const workspaceReporterMarkerPath = process.env[WORKSPACE_REPORTER_MARKER_ENV] ?? "";
|
|
7619
|
+
markWorkspaceReporterInstalled(workspaceReporterMarkerPath);
|
|
7640
7620
|
}
|
|
7641
|
-
/**
|
|
7642
|
-
* v3+ canonical start-of-run hook. Resetting the upload guard here lets
|
|
7643
|
-
* watch-mode reruns upload their own results.
|
|
7644
|
-
*/
|
|
7645
7621
|
onTestRunStart(_specifications) {
|
|
7646
|
-
this.
|
|
7647
|
-
this.startTime = Date.now();
|
|
7622
|
+
this.activeLifecycle = null;
|
|
7648
7623
|
}
|
|
7649
|
-
/**
|
|
7650
|
-
* v2 watch-mode start-of-rerun hook. Same purpose as onTestRunStart for
|
|
7651
|
-
* v3+. Vitest v2 has no onTestRunStart, so we reset here instead.
|
|
7652
|
-
*/
|
|
7653
7624
|
onWatcherRerun(_files, _trigger) {
|
|
7654
|
-
this.
|
|
7655
|
-
|
|
7625
|
+
this.activeLifecycle = null;
|
|
7626
|
+
}
|
|
7627
|
+
async onFinished(files, _errors) {
|
|
7628
|
+
await this.runLifecycleOnce(files?.length ?? 0, "files");
|
|
7629
|
+
}
|
|
7630
|
+
async onTestRunEnd(testModules, _unhandledErrors, _reason) {
|
|
7631
|
+
await this.runLifecycleOnce(testModules?.length ?? 0, "test modules");
|
|
7656
7632
|
}
|
|
7657
7633
|
decodeConfig(encoded) {
|
|
7658
7634
|
try {
|
|
@@ -7661,320 +7637,34 @@ var ArchalReporter = class {
|
|
|
7661
7637
|
return null;
|
|
7662
7638
|
}
|
|
7663
7639
|
}
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
config,
|
|
7667
|
-
includePatterns,
|
|
7668
|
-
includeMatchers: includePatterns.map(buildIncludeMatcher)
|
|
7669
|
-
};
|
|
7670
|
-
}
|
|
7671
|
-
resolveProjects() {
|
|
7672
|
-
const resolvedProjects = (this.ctx?.projects ?? []).map((project) => {
|
|
7640
|
+
resolveProjectName() {
|
|
7641
|
+
for (const project of this.ctx?.projects ?? []) {
|
|
7673
7642
|
const config = this.decodeConfig(readEncodedConfigFromTarget(project));
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
return resolvedProjects;
|
|
7643
|
+
if (config?.projectName) {
|
|
7644
|
+
return config.projectName;
|
|
7645
|
+
}
|
|
7678
7646
|
}
|
|
7679
7647
|
const rootConfig = this.decodeConfig(
|
|
7680
7648
|
readEncodedConfigFromTarget(this.ctx) ?? process.env[ARCHAL_VITEST_CONFIG_ENV2]
|
|
7681
7649
|
);
|
|
7682
|
-
return rootConfig
|
|
7683
|
-
}
|
|
7684
|
-
/**
|
|
7685
|
-
* vitest v2 calls onFinished with an array of File objects (from @vitest/runner).
|
|
7686
|
-
* Each File extends Suite which has `tasks: Task[]`, and each Task has
|
|
7687
|
-
* `.type` ('test' | 'suite'), `.name`, `.result?.state`, `.result?.duration`.
|
|
7688
|
-
*/
|
|
7689
|
-
async onFinished(files, _errors) {
|
|
7690
|
-
await this.runUploadOnce(() => this.collectAndReport(files ?? [], "v2"));
|
|
7650
|
+
return rootConfig?.projectName ?? "vitest";
|
|
7691
7651
|
}
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
* test modules, each with nested children.
|
|
7696
|
-
*/
|
|
7697
|
-
async onTestRunEnd(testModules, _unhandledErrors, _reason) {
|
|
7698
|
-
await this.runUploadOnce(() => this.collectAndReport(testModules ?? [], "v4"));
|
|
7699
|
-
}
|
|
7700
|
-
/**
|
|
7701
|
-
* Dedupe upload work when Vitest fires multiple end-of-run hooks. In
|
|
7702
|
-
* Vitest v3+ both `onFinished` and `onTestRunEnd` fire from the same
|
|
7703
|
-
* `Promise.all` in TestRun.end(); the first hook to enter wins and the
|
|
7704
|
-
* second awaits the same in-flight upload instead of POSTing a duplicate
|
|
7705
|
-
* row to /api/test-results. The resolved promise is kept on the instance
|
|
7706
|
-
* so any late hook still no-ops — the guard is only cleared at the start
|
|
7707
|
-
* of a new run (onTestRunStart / onWatcherRerun).
|
|
7708
|
-
*/
|
|
7709
|
-
async runUploadOnce(work) {
|
|
7710
|
-
if (!this.activeUpload) {
|
|
7711
|
-
this.activeUpload = work();
|
|
7652
|
+
async runLifecycleOnce(itemCount, itemLabel) {
|
|
7653
|
+
if (!this.activeLifecycle) {
|
|
7654
|
+
this.activeLifecycle = this.reportLifecycleComplete(itemCount, itemLabel);
|
|
7712
7655
|
}
|
|
7713
|
-
await this.
|
|
7656
|
+
await this.activeLifecycle;
|
|
7714
7657
|
}
|
|
7715
|
-
async
|
|
7658
|
+
async reportLifecycleComplete(itemCount, itemLabel) {
|
|
7716
7659
|
markReporterFired(this.lifecycleMarkerPath);
|
|
7717
7660
|
this.lifecycleMarkerPath = "";
|
|
7718
|
-
if (
|
|
7719
|
-
|
|
7720
|
-
}
|
|
7721
|
-
if (this.projects.length === 0) {
|
|
7722
|
-
warn(
|
|
7723
|
-
"Archal Vitest config was unreadable. Using the default project name. If this persists, make sure withArchal() or archalVitestProject() wraps your test config."
|
|
7724
|
-
);
|
|
7725
|
-
this.projects = [
|
|
7726
|
-
this.buildProjectContext(
|
|
7727
|
-
{
|
|
7728
|
-
projectName: "vitest",
|
|
7729
|
-
services: {}
|
|
7730
|
-
},
|
|
7731
|
-
[]
|
|
7732
|
-
)
|
|
7733
|
-
];
|
|
7734
|
-
}
|
|
7735
|
-
if (items.length === 0) {
|
|
7736
|
-
warn(`No ${version === "v2" ? "files" : "test modules"} received. Nothing to upload.`);
|
|
7661
|
+
if (itemCount === 0) {
|
|
7662
|
+
warn(`No ${itemLabel} received. Nothing to upload.`);
|
|
7737
7663
|
return;
|
|
7738
7664
|
}
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
return;
|
|
7743
|
-
}
|
|
7744
|
-
const buckets = this.partitionResults(results);
|
|
7745
|
-
if (buckets.length === 0) {
|
|
7746
|
-
warn("collected tests but could not map them to an Archal Vitest project.");
|
|
7747
|
-
return;
|
|
7748
|
-
}
|
|
7749
|
-
try {
|
|
7750
|
-
for (const bucket of buckets) {
|
|
7751
|
-
await this.sendResults(bucket.project, bucket.results);
|
|
7752
|
-
}
|
|
7753
|
-
} catch (err) {
|
|
7754
|
-
warn(`failed to upload test results: ${err instanceof Error ? err.message : String(err)}`);
|
|
7755
|
-
}
|
|
7756
|
-
}
|
|
7757
|
-
/**
|
|
7758
|
-
* vitest v2: File extends Suite { tasks: Task[] }.
|
|
7759
|
-
* Task.type is 'test' | 'suite' | 'custom'. Suite tasks recurse.
|
|
7760
|
-
*/
|
|
7761
|
-
collectV2Files(files) {
|
|
7762
|
-
const results = [];
|
|
7763
|
-
const collectTasks = (tasks, fileName) => {
|
|
7764
|
-
for (const task of tasks) {
|
|
7765
|
-
if (task.type === "test" || task.type === "custom") {
|
|
7766
|
-
const state = task.result?.state;
|
|
7767
|
-
results.push({
|
|
7768
|
-
name: task.name ?? "unnamed",
|
|
7769
|
-
file: fileName,
|
|
7770
|
-
status: state === "pass" ? "passed" : state === "fail" ? "failed" : "skipped",
|
|
7771
|
-
duration: task.result?.duration ?? 0,
|
|
7772
|
-
error: state === "fail" && task.result?.errors?.[0] ? task.result.errors[0].message ?? String(task.result.errors[0]) : void 0
|
|
7773
|
-
});
|
|
7774
|
-
} else if (task.type === "suite" && Array.isArray(task.tasks)) {
|
|
7775
|
-
collectTasks(task.tasks, fileName);
|
|
7776
|
-
}
|
|
7777
|
-
}
|
|
7778
|
-
};
|
|
7779
|
-
for (const file of files) {
|
|
7780
|
-
const f = file;
|
|
7781
|
-
const fileName = f.filepath ?? f.name ?? "unknown";
|
|
7782
|
-
if (Array.isArray(f.tasks)) {
|
|
7783
|
-
collectTasks(f.tasks, fileName);
|
|
7784
|
-
}
|
|
7785
|
-
}
|
|
7786
|
-
return results;
|
|
7787
|
-
}
|
|
7788
|
-
/**
|
|
7789
|
-
* vitest v4: TestModule.children() → TestSuite[].children() → TestCase[]
|
|
7790
|
-
* All accessors are methods (not properties) in v4.
|
|
7791
|
-
*/
|
|
7792
|
-
collectV4Modules(testModules) {
|
|
7793
|
-
const results = [];
|
|
7794
|
-
const collectTests = (node, fileName) => {
|
|
7795
|
-
const children = typeof node.children === "function" ? node.children() : node.children ?? [];
|
|
7796
|
-
for (const child of children) {
|
|
7797
|
-
if (child.type === "test") {
|
|
7798
|
-
const result = typeof child.result === "function" ? child.result() : child.result;
|
|
7799
|
-
const diag = typeof child.diagnostic === "function" ? child.diagnostic() : child.diagnostic;
|
|
7800
|
-
const state = result?.state;
|
|
7801
|
-
results.push({
|
|
7802
|
-
name: child.name ?? "unnamed",
|
|
7803
|
-
file: fileName,
|
|
7804
|
-
status: state === "passed" ? "passed" : state === "failed" ? "failed" : "skipped",
|
|
7805
|
-
duration: diag?.duration ?? result?.duration ?? 0,
|
|
7806
|
-
error: state === "failed" && result?.errors?.[0] ? result.errors[0].message ?? String(result.errors[0]) : void 0
|
|
7807
|
-
});
|
|
7808
|
-
} else {
|
|
7809
|
-
collectTests(child, fileName);
|
|
7810
|
-
}
|
|
7811
|
-
}
|
|
7812
|
-
};
|
|
7813
|
-
for (const mod of testModules) {
|
|
7814
|
-
const m = mod;
|
|
7815
|
-
const fileName = m.moduleId ?? m.id ?? "unknown";
|
|
7816
|
-
collectTests(m, fileName);
|
|
7817
|
-
}
|
|
7818
|
-
return results;
|
|
7819
|
-
}
|
|
7820
|
-
resolveProjectForFile(fileName) {
|
|
7821
|
-
const normalizedFile = normalizePathForMatch(fileName);
|
|
7822
|
-
const onlyProject = this.projects[0] ?? null;
|
|
7823
|
-
if (this.projects.length === 1) {
|
|
7824
|
-
if (!onlyProject) {
|
|
7825
|
-
return null;
|
|
7826
|
-
}
|
|
7827
|
-
if (onlyProject.includeMatchers.length === 0) {
|
|
7828
|
-
return onlyProject;
|
|
7829
|
-
}
|
|
7830
|
-
return onlyProject.includeMatchers.some((matcher) => matcher(normalizedFile)) ? onlyProject : null;
|
|
7831
|
-
}
|
|
7832
|
-
let bestMatch = null;
|
|
7833
|
-
let bestSpecificity = -1;
|
|
7834
|
-
for (const project of this.projects) {
|
|
7835
|
-
for (const [index, matcher] of project.includeMatchers.entries()) {
|
|
7836
|
-
if (!matcher(normalizedFile)) {
|
|
7837
|
-
continue;
|
|
7838
|
-
}
|
|
7839
|
-
const specificity = project.includePatterns[index]?.length ?? 0;
|
|
7840
|
-
if (specificity > bestSpecificity) {
|
|
7841
|
-
bestMatch = project;
|
|
7842
|
-
bestSpecificity = specificity;
|
|
7843
|
-
}
|
|
7844
|
-
}
|
|
7845
|
-
}
|
|
7846
|
-
return bestMatch;
|
|
7847
|
-
}
|
|
7848
|
-
partitionResults(results) {
|
|
7849
|
-
const buckets = /* @__PURE__ */ new Map();
|
|
7850
|
-
for (const result of results) {
|
|
7851
|
-
const project = this.resolveProjectForFile(result.file);
|
|
7852
|
-
if (!project) {
|
|
7853
|
-
warn(
|
|
7854
|
-
`Could not map ${result.file} to a Vitest project config. Skipping reporter upload for that file.`
|
|
7855
|
-
);
|
|
7856
|
-
continue;
|
|
7857
|
-
}
|
|
7858
|
-
const key = project.config.projectName;
|
|
7859
|
-
const bucket = buckets.get(key);
|
|
7860
|
-
if (bucket) {
|
|
7861
|
-
bucket.results.push(result);
|
|
7862
|
-
continue;
|
|
7863
|
-
}
|
|
7864
|
-
buckets.set(key, {
|
|
7865
|
-
project,
|
|
7866
|
-
results: [result]
|
|
7867
|
-
});
|
|
7868
|
-
}
|
|
7869
|
-
return [...buckets.values()];
|
|
7870
|
-
}
|
|
7871
|
-
async sendResults(project, results) {
|
|
7872
|
-
const summary = {
|
|
7873
|
-
total: results.length,
|
|
7874
|
-
passed: results.filter((result) => result.status === "passed").length,
|
|
7875
|
-
failed: results.filter((result) => result.status === "failed").length,
|
|
7876
|
-
skipped: results.filter((result) => result.status === "skipped").length,
|
|
7877
|
-
duration: Date.now() - this.startTime
|
|
7878
|
-
};
|
|
7879
|
-
const token = await resolveReporterToken();
|
|
7880
|
-
if (!token) {
|
|
7881
|
-
warn(
|
|
7882
|
-
`skipped upload (no auth token found). Set ${REPORTER_TOKEN_ENV} or ARCHAL_TOKEN, or run \`archal login\` to populate ~/.archal/credentials.json.`
|
|
7883
|
-
);
|
|
7884
|
-
return;
|
|
7885
|
-
}
|
|
7886
|
-
const baseUrl = resolveReporterBaseUrl();
|
|
7887
|
-
const sessionId = await this.readSessionId(project.config.sessionKey);
|
|
7888
|
-
const payload = {
|
|
7889
|
-
sessionId,
|
|
7890
|
-
projectName: project.config.projectName,
|
|
7891
|
-
services: Object.keys(project.config.services),
|
|
7892
|
-
results,
|
|
7893
|
-
summary,
|
|
7894
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
7895
|
-
};
|
|
7896
|
-
const res = await fetch(`${baseUrl}/api/test-results`, {
|
|
7897
|
-
method: "POST",
|
|
7898
|
-
headers: buildReporterHeaders(token),
|
|
7899
|
-
body: JSON.stringify(payload)
|
|
7900
|
-
});
|
|
7901
|
-
if (res.ok) {
|
|
7902
|
-
info(`Uploaded ${summary.passed}/${summary.total} tests to Archal Tests.`);
|
|
7903
|
-
if (sessionId) {
|
|
7904
|
-
try {
|
|
7905
|
-
const syncRes = await fetch(`${baseUrl}/api/sessions/sync`, {
|
|
7906
|
-
method: "POST",
|
|
7907
|
-
headers: buildReporterHeaders(token),
|
|
7908
|
-
body: JSON.stringify({
|
|
7909
|
-
sessionId,
|
|
7910
|
-
twinIds: Object.keys(project.config.services),
|
|
7911
|
-
status: summary.failed > 0 ? "failed" : "ended",
|
|
7912
|
-
endedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7913
|
-
runtimeStartedAt: new Date(Date.now() - summary.duration).toISOString(),
|
|
7914
|
-
source: "test",
|
|
7915
|
-
evidence: {
|
|
7916
|
-
reportSummary: {
|
|
7917
|
-
scenarioTitle: project.config.projectName,
|
|
7918
|
-
satisfactionScore: summary.total > 0 ? Math.round(summary.passed / summary.total * 100) : null,
|
|
7919
|
-
runCount: 1
|
|
7920
|
-
}
|
|
7921
|
-
}
|
|
7922
|
-
})
|
|
7923
|
-
});
|
|
7924
|
-
if (!syncRes.ok) {
|
|
7925
|
-
const body = await syncRes.text().catch(() => "");
|
|
7926
|
-
warn(`Session sync failed (${syncRes.status}): ${body.slice(0, 200)}`);
|
|
7927
|
-
}
|
|
7928
|
-
} catch (syncErr) {
|
|
7929
|
-
warn(
|
|
7930
|
-
`Session sync failed: ${syncErr instanceof Error ? syncErr.message : String(syncErr)}`
|
|
7931
|
-
);
|
|
7932
|
-
}
|
|
7933
|
-
} else {
|
|
7934
|
-
warn(
|
|
7935
|
-
"Uploaded test results, but could not link them to a session. The run may not appear in Activity."
|
|
7936
|
-
);
|
|
7937
|
-
}
|
|
7938
|
-
} else {
|
|
7939
|
-
const body = await res.text().catch(() => "");
|
|
7940
|
-
warn(`Upload failed (${res.status}): ${body.slice(0, 200)}`);
|
|
7941
|
-
}
|
|
7942
|
-
}
|
|
7943
|
-
async readSessionId(sessionKey) {
|
|
7944
|
-
const { readFileSync: readFileSync4, readdirSync, statSync } = await import("fs");
|
|
7945
|
-
const { dirname: dirname5, join: join6 } = await import("path");
|
|
7946
|
-
if (sessionKey?.trim()) {
|
|
7947
|
-
try {
|
|
7948
|
-
const keyed = readFileSync4(getSessionIdFilePath(sessionKey), "utf-8").trim();
|
|
7949
|
-
if (keyed) return keyed;
|
|
7950
|
-
} catch {
|
|
7951
|
-
}
|
|
7952
|
-
}
|
|
7953
|
-
if (sessionKey?.trim()) {
|
|
7954
|
-
return void 0;
|
|
7955
|
-
}
|
|
7956
|
-
try {
|
|
7957
|
-
const sessionsDir = dirname5(getSessionIdFilePath("any"));
|
|
7958
|
-
const entries = readdirSync(sessionsDir);
|
|
7959
|
-
let newest;
|
|
7960
|
-
for (const name of entries) {
|
|
7961
|
-
if (!name.endsWith(".session-id")) continue;
|
|
7962
|
-
const path = join6(sessionsDir, name);
|
|
7963
|
-
try {
|
|
7964
|
-
const st = statSync(path);
|
|
7965
|
-
if (!newest || st.mtimeMs > newest.mtimeMs) {
|
|
7966
|
-
newest = { path, mtimeMs: st.mtimeMs };
|
|
7967
|
-
}
|
|
7968
|
-
} catch {
|
|
7969
|
-
}
|
|
7970
|
-
}
|
|
7971
|
-
if (newest) {
|
|
7972
|
-
const content = readFileSync4(newest.path, "utf-8").trim();
|
|
7973
|
-
if (content) return content;
|
|
7974
|
-
}
|
|
7975
|
-
} catch {
|
|
7976
|
-
}
|
|
7977
|
-
return void 0;
|
|
7665
|
+
diagnostic(
|
|
7666
|
+
"skipped legacy test-result upload. Benchmark Results ingestion requires a Benchmark Run payload and no longer writes /api/test-results."
|
|
7667
|
+
);
|
|
7978
7668
|
}
|
|
7979
7669
|
};
|
|
7980
7670
|
|
|
@@ -8179,11 +7869,6 @@ function archalVitestProject(options, testOptions = {}) {
|
|
|
8179
7869
|
const test = buildTestConfig(options, testOptions);
|
|
8180
7870
|
return (0, import_config.defineProject)({ test });
|
|
8181
7871
|
}
|
|
8182
|
-
function archalVitestConfig(options, testOptions = {}) {
|
|
8183
|
-
const built = buildTestConfig(options, testOptions);
|
|
8184
|
-
built.reporters = ["default", new ArchalReporter()];
|
|
8185
|
-
return built;
|
|
8186
|
-
}
|
|
8187
7872
|
function archalVitestRootConfig() {
|
|
8188
7873
|
markHelperCalled();
|
|
8189
7874
|
return {
|
|
@@ -8245,7 +7930,6 @@ function archalVitestWorkspace(projects) {
|
|
|
8245
7930
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8246
7931
|
0 && (module.exports = {
|
|
8247
7932
|
ArchalReporter,
|
|
8248
|
-
archalVitestConfig,
|
|
8249
7933
|
archalVitestProject,
|
|
8250
7934
|
archalVitestRootConfig,
|
|
8251
7935
|
archalVitestWorkspace,
|