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
|
@@ -136,26 +136,6 @@ function parsePositiveInteger(rawValue, fallback, minimum = 1) {
|
|
|
136
136
|
const parsed = Number(normalized);
|
|
137
137
|
return Number.isSafeInteger(parsed) && parsed >= minimum ? parsed : fallback;
|
|
138
138
|
}
|
|
139
|
-
function normalizeApiBaseUrl(value) {
|
|
140
|
-
if (!value) return null;
|
|
141
|
-
const normalized = value.trim().replace(/\/+$/, "");
|
|
142
|
-
if (!normalized) return null;
|
|
143
|
-
let parsed;
|
|
144
|
-
try {
|
|
145
|
-
parsed = new URL(normalized);
|
|
146
|
-
} catch {
|
|
147
|
-
throw new Error(`Invalid ARCHAL_API_URL: "${normalized}" is not a valid URL`);
|
|
148
|
-
}
|
|
149
|
-
const isLocalhostHttp = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1");
|
|
150
|
-
if (parsed.protocol !== "https:" && !isLocalhostHttp) {
|
|
151
|
-
throw new Error(`Hosted API URL must use HTTPS (or localhost HTTP). Received ${normalized}.`);
|
|
152
|
-
}
|
|
153
|
-
const pathname = parsed.pathname.replace(/\/+$/, "");
|
|
154
|
-
parsed.pathname = pathname.endsWith("/api") ? pathname.slice(0, -4) || "/" : pathname || "/";
|
|
155
|
-
parsed.search = "";
|
|
156
|
-
parsed.hash = "";
|
|
157
|
-
return parsed.toString().replace(/\/$/, "");
|
|
158
|
-
}
|
|
159
139
|
function resolveHostedWorkspaceHeader() {
|
|
160
140
|
return trimEnv("ARCHAL_WORKSPACE_ID");
|
|
161
141
|
}
|
|
@@ -652,6 +632,8 @@ var CREDENTIALS_MASTER_KEY_ENV_VAR = "ARCHAL_CREDENTIALS_MASTER_KEY";
|
|
|
652
632
|
var KEYCHAIN_SERVICE = "archal-cli";
|
|
653
633
|
var KEYCHAIN_ACCOUNT = "credentials-master-key";
|
|
654
634
|
var HOSTED_DEFAULT_AUTH_BASE_URL = "https://www.archal.ai";
|
|
635
|
+
var HOSTED_DEFAULT_API_BASE_URL = "https://api.archal.ai";
|
|
636
|
+
var WORKSPACE_API_KEY_PREFIX = "archal_ws_";
|
|
655
637
|
var STRICT_ENDPOINTS_ENV_VAR = "ARCHAL_STRICT_ENDPOINTS";
|
|
656
638
|
var REQUEST_TIMEOUT_MS = 8e3;
|
|
657
639
|
var ENV_TOKEN_FALLBACK_TTL_SECONDS = 24 * 60 * 60;
|
|
@@ -661,11 +643,6 @@ function isPlan(value) {
|
|
|
661
643
|
return value === "free" || value === "pro" || value === "enterprise";
|
|
662
644
|
}
|
|
663
645
|
|
|
664
|
-
// ../node-auth/src/errors.ts
|
|
665
|
-
function errorMessage2(error) {
|
|
666
|
-
return error instanceof Error ? error.message : String(error);
|
|
667
|
-
}
|
|
668
|
-
|
|
669
646
|
// ../node-auth/src/credential-store.ts
|
|
670
647
|
import { spawnSync } from "child_process";
|
|
671
648
|
import { createCipheriv, createDecipheriv, createHash, randomBytes } from "crypto";
|
|
@@ -698,7 +675,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
698
675
|
name: "Cal.com",
|
|
699
676
|
description: "Event types, schedules, availability slots, bookings, calendars, and webhooks.",
|
|
700
677
|
stage: "preview",
|
|
701
|
-
toolCount:
|
|
678
|
+
toolCount: 35,
|
|
702
679
|
transport: "both",
|
|
703
680
|
architectureClass: "domain-simulator",
|
|
704
681
|
domainPrimitives: [
|
|
@@ -716,7 +693,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
716
693
|
name: "ClickUp",
|
|
717
694
|
description: "Teams, spaces, folders, lists, tasks, comments, tags, time tracking, and checklists.",
|
|
718
695
|
stage: "preview",
|
|
719
|
-
toolCount:
|
|
696
|
+
toolCount: 123,
|
|
720
697
|
transport: "both",
|
|
721
698
|
architectureClass: "standard-core",
|
|
722
699
|
domainPrimitives: [],
|
|
@@ -729,7 +706,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
729
706
|
name: "Customer.io",
|
|
730
707
|
description: "Messaging automation across campaigns, broadcasts, transactional email, segments, customers, and message delivery.",
|
|
731
708
|
stage: "preview",
|
|
732
|
-
toolCount:
|
|
709
|
+
toolCount: 129,
|
|
733
710
|
transport: "rest",
|
|
734
711
|
architectureClass: "standard-core",
|
|
735
712
|
domainPrimitives: [],
|
|
@@ -794,7 +771,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
794
771
|
name: "GitLab",
|
|
795
772
|
description: "Projects, branches, commits, issues, merge requests, pipelines, labels, milestones, releases, and webhooks.",
|
|
796
773
|
stage: "preview",
|
|
797
|
-
toolCount:
|
|
774
|
+
toolCount: 559,
|
|
798
775
|
transport: "both",
|
|
799
776
|
architectureClass: "domain-simulator",
|
|
800
777
|
domainPrimitives: [
|
|
@@ -829,7 +806,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
829
806
|
name: "HubSpot",
|
|
830
807
|
description: "CRM contacts, companies, deals, tickets, and engagements.",
|
|
831
808
|
stage: "preview",
|
|
832
|
-
toolCount:
|
|
809
|
+
toolCount: 44,
|
|
833
810
|
transport: "rest",
|
|
834
811
|
architectureClass: "replay-shell",
|
|
835
812
|
domainPrimitives: [
|
|
@@ -864,7 +841,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
864
841
|
name: "Linear",
|
|
865
842
|
description: "Issues, projects, teams, cycles, and workflows.",
|
|
866
843
|
stage: "public",
|
|
867
|
-
toolCount:
|
|
844
|
+
toolCount: 53,
|
|
868
845
|
transport: "both",
|
|
869
846
|
architectureClass: "domain-simulator",
|
|
870
847
|
domainPrimitives: [
|
|
@@ -933,7 +910,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
933
910
|
name: "Sentry",
|
|
934
911
|
description: "Error monitoring across organizations, projects, teams, issues, events, releases, and DSN keys.",
|
|
935
912
|
stage: "preview",
|
|
936
|
-
toolCount:
|
|
913
|
+
toolCount: 34,
|
|
937
914
|
transport: "rest",
|
|
938
915
|
architectureClass: "domain-simulator",
|
|
939
916
|
domainPrimitives: [
|
|
@@ -1035,14 +1012,10 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
1035
1012
|
name: "Webflow",
|
|
1036
1013
|
description: "Sites, pages, CMS collections, items, assets, forms, and webhooks.",
|
|
1037
1014
|
stage: "preview",
|
|
1038
|
-
toolCount:
|
|
1039
|
-
transport: "
|
|
1040
|
-
architectureClass: "
|
|
1041
|
-
domainPrimitives: [
|
|
1042
|
-
"recording replay cursor",
|
|
1043
|
-
"CMS collection/item overlays",
|
|
1044
|
-
"publish lifecycle captures"
|
|
1045
|
-
],
|
|
1015
|
+
toolCount: 104,
|
|
1016
|
+
transport: "both",
|
|
1017
|
+
architectureClass: "standard-core",
|
|
1018
|
+
domainPrimitives: [],
|
|
1046
1019
|
behaviorOwner: null,
|
|
1047
1020
|
opsCoverage: 100
|
|
1048
1021
|
}
|
|
@@ -1138,142 +1111,11 @@ var STARTABLE_CLONE_CATALOG = CLONE_CATALOG.filter(
|
|
|
1138
1111
|
(entry) => STARTABLE_CLONE_ID_SET.has(entry.id)
|
|
1139
1112
|
);
|
|
1140
1113
|
|
|
1141
|
-
// ../
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
);
|
|
1146
|
-
|
|
1147
|
-
// ../billing-constants/src/index.ts
|
|
1148
|
-
var PLAN_MONTHLY_TWIN_MINUTE_LIMITS = {
|
|
1149
|
-
free: 500,
|
|
1150
|
-
pro: 5e3,
|
|
1151
|
-
enterprise: null
|
|
1152
|
-
};
|
|
1153
|
-
var PLAN_CONCURRENT_SESSION_LIMITS = {
|
|
1154
|
-
free: 3,
|
|
1155
|
-
pro: 10,
|
|
1156
|
-
enterprise: 50
|
|
1157
|
-
};
|
|
1158
|
-
var FREE_WORKSPACE_MEMBER_LIMIT = 2;
|
|
1159
|
-
var PRO_PLAN_PRICE_USD = 199;
|
|
1160
|
-
function formatMinutesLabel(minutes) {
|
|
1161
|
-
return minutes.toLocaleString("en-US");
|
|
1162
|
-
}
|
|
1163
|
-
var FREE_MINUTES = PLAN_MONTHLY_TWIN_MINUTE_LIMITS.free;
|
|
1164
|
-
var PRO_MINUTES = PLAN_MONTHLY_TWIN_MINUTE_LIMITS.pro;
|
|
1165
|
-
if (FREE_MINUTES == null || PRO_MINUTES == null) {
|
|
1166
|
-
throw new Error("PLAN_MONTHLY_TWIN_MINUTE_LIMITS: free and pro must be non-null");
|
|
1167
|
-
}
|
|
1168
|
-
var PRO_EVALS_PER_SEAT = 500;
|
|
1169
|
-
var PRO_SESSION_MINUTES_PER_SEAT = 5e3;
|
|
1170
|
-
var PRO_MAX_SEATS = 5;
|
|
1171
|
-
var FREE_EVALS_PER_MONTH = 100;
|
|
1172
|
-
var PLAN_DISPLAY = {
|
|
1173
|
-
free: {
|
|
1174
|
-
tag: "Free",
|
|
1175
|
-
priceLabel: "$0",
|
|
1176
|
-
periodLabel: "",
|
|
1177
|
-
included: [
|
|
1178
|
-
`${formatMinutesLabel(FREE_MINUTES)} session-minutes / account`,
|
|
1179
|
-
`${FREE_EVALS_PER_MONTH} evals / account`,
|
|
1180
|
-
`1 workspace (${FREE_WORKSPACE_MEMBER_LIMIT} users max)`,
|
|
1181
|
-
`${PLAN_CONCURRENT_SESSION_LIMITS.free} concurrent sessions / workspace`,
|
|
1182
|
-
"All clones included"
|
|
1183
|
-
]
|
|
1184
|
-
},
|
|
1185
|
-
pro: {
|
|
1186
|
-
tag: "Pro",
|
|
1187
|
-
priceLabel: `$${PRO_PLAN_PRICE_USD}`,
|
|
1188
|
-
periodLabel: "/mo per seat",
|
|
1189
|
-
included: [
|
|
1190
|
-
`${formatMinutesLabel(PRO_SESSION_MINUTES_PER_SEAT)} session-minutes / seat / month`,
|
|
1191
|
-
`${PRO_EVALS_PER_SEAT} evals / seat / month`,
|
|
1192
|
-
"All clones included",
|
|
1193
|
-
`${PLAN_CONCURRENT_SESSION_LIMITS.pro} concurrent sessions / workspace`,
|
|
1194
|
-
`1 workspace, up to ${PRO_MAX_SEATS} seats with pooled usage`
|
|
1195
|
-
]
|
|
1196
|
-
},
|
|
1197
|
-
enterprise: {
|
|
1198
|
-
tag: "Enterprise",
|
|
1199
|
-
priceLabel: "Contact us",
|
|
1200
|
-
periodLabel: "",
|
|
1201
|
-
included: [
|
|
1202
|
-
"Unlimited session-minutes",
|
|
1203
|
-
"Unlimited seats per workspace",
|
|
1204
|
-
"Unlimited workspaces",
|
|
1205
|
-
`${PLAN_CONCURRENT_SESSION_LIMITS.enterprise} concurrent sessions / workspace`,
|
|
1206
|
-
"SSO / SAML",
|
|
1207
|
-
"SOC 2 (in progress)",
|
|
1208
|
-
"Custom clones & eval support",
|
|
1209
|
-
"Dedicated onboarding & support"
|
|
1210
|
-
]
|
|
1211
|
-
}
|
|
1212
|
-
};
|
|
1213
|
-
var PLAN_MAX_SESSION_TTL_SECONDS = {
|
|
1214
|
-
free: 30 * 60,
|
|
1215
|
-
// 30 minutes
|
|
1216
|
-
pro: 60 * 60,
|
|
1217
|
-
// 60 minutes
|
|
1218
|
-
enterprise: 90 * 60
|
|
1219
|
-
// 90 minutes
|
|
1220
|
-
};
|
|
1221
|
-
var MAX_ABSOLUTE_SESSION_LIFETIME_SECONDS = 4 * 60 * 60;
|
|
1222
|
-
var LIFETIME_PERIOD_RESETS_AT = new Date(Date.UTC(9999, 11, 31));
|
|
1223
|
-
var ALL_ENTITLED_CLONES = ALL_STARTABLE_CLONE_IDS;
|
|
1224
|
-
var SCENARIO_USAGE_WINDOW_DAYS = 7;
|
|
1225
|
-
var SCENARIO_USAGE_WINDOW_MS = SCENARIO_USAGE_WINDOW_DAYS * 24 * 60 * 60 * 1e3;
|
|
1226
|
-
var SCENARIO_USAGE_WINDOW_SECONDS = SCENARIO_USAGE_WINDOW_DAYS * 24 * 60 * 60;
|
|
1227
|
-
var LLM_PRICING_USD_PER_M_TOKENS = {
|
|
1228
|
-
// Google Gemini (verified 2026-05-05, standard tier <=200K input tokens)
|
|
1229
|
-
"gemini-2.5-pro": { input: 1.25, output: 10 },
|
|
1230
|
-
"gemini-2.5-flash": { input: 0.3, output: 2.5 },
|
|
1231
|
-
// OpenAI flagship text models (verified 2026-05-21, standard short-context tier)
|
|
1232
|
-
"gpt-5.5": { input: 5, output: 30 },
|
|
1233
|
-
"gpt-5.5-pro": { input: 30, output: 180 },
|
|
1234
|
-
"gpt-5.4": { input: 2.5, output: 15 },
|
|
1235
|
-
"gpt-5.4-mini": { input: 0.75, output: 4.5 },
|
|
1236
|
-
"gpt-5.4-nano": { input: 0.2, output: 1.25 },
|
|
1237
|
-
"gpt-5.4-pro": { input: 30, output: 180 },
|
|
1238
|
-
"gpt-4o-mini": { input: 0.15, output: 0.6 },
|
|
1239
|
-
"gpt-4o": { input: 2.5, output: 10 },
|
|
1240
|
-
"gpt-4.1-mini": { input: 0.4, output: 1.6 },
|
|
1241
|
-
"gpt-4.1-nano": { input: 0.1, output: 0.4 },
|
|
1242
|
-
"gpt-4.1": { input: 2, output: 8 },
|
|
1243
|
-
// DeepSeek (verified 2026-05-05; legacy names map to v4-flash per vendor)
|
|
1244
|
-
"deepseek-chat": { input: 0.14, output: 0.28 },
|
|
1245
|
-
"deepseek-reasoner": { input: 0.14, output: 0.28 },
|
|
1246
|
-
"deepseek-v4-flash": { input: 0.14, output: 0.28 }
|
|
1247
|
-
};
|
|
1248
|
-
var LLM_PRICING_FAMILY_RATES = [
|
|
1249
|
-
{ match: /^gemini-2\.5-pro/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gemini-2.5-pro"] },
|
|
1250
|
-
{ match: /^gemini-2\.5-flash/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gemini-2.5-flash"] },
|
|
1251
|
-
{ match: /^gpt-5\.5-pro/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.5-pro"] },
|
|
1252
|
-
{ match: /^gpt-5\.5/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.5"] },
|
|
1253
|
-
{ match: /^gpt-5\.4-pro/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4-pro"] },
|
|
1254
|
-
{ match: /^gpt-5\.4-mini/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4-mini"] },
|
|
1255
|
-
{ match: /^gpt-5\.4-nano/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4-nano"] },
|
|
1256
|
-
{ match: /^gpt-5\.4/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4"] },
|
|
1257
|
-
{ match: /^gpt-4o-mini/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4o-mini"] },
|
|
1258
|
-
{ match: /^gpt-4o(?!-mini)/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4o"] },
|
|
1259
|
-
{ match: /^gpt-4\.1-mini/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4.1-mini"] },
|
|
1260
|
-
{ match: /^gpt-4\.1-nano/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4.1-nano"] },
|
|
1261
|
-
{ match: /^gpt-4\.1(?!-mini|-nano)/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4.1"] },
|
|
1262
|
-
// Anthropic Claude 4.x list prices (verified 2026): Opus $5/$25, Sonnet
|
|
1263
|
-
// $3/$15, Haiku 4.5 $1/$5 per 1M tokens (input/output).
|
|
1264
|
-
{ match: /^claude-opus-/i, rate: { input: 5, output: 25 } },
|
|
1265
|
-
{ match: /^claude-haiku-/i, rate: { input: 1, output: 5 } },
|
|
1266
|
-
{ match: /^claude-sonnet-/i, rate: { input: 3, output: 15 } },
|
|
1267
|
-
{ match: /^opus-/i, rate: { input: 5, output: 25 } },
|
|
1268
|
-
{ match: /^haiku-/i, rate: { input: 1, output: 5 } },
|
|
1269
|
-
{ match: /^sonnet-/i, rate: { input: 3, output: 15 } },
|
|
1270
|
-
{ match: /^deepseek-chat/i, rate: LLM_PRICING_USD_PER_M_TOKENS["deepseek-chat"] },
|
|
1271
|
-
{ match: /^deepseek-reasoner/i, rate: LLM_PRICING_USD_PER_M_TOKENS["deepseek-reasoner"] },
|
|
1272
|
-
{ match: /^deepseek-v4-flash/i, rate: LLM_PRICING_USD_PER_M_TOKENS["deepseek-v4-flash"] }
|
|
1273
|
-
];
|
|
1274
|
-
|
|
1275
|
-
// ../node-auth/src/clone-entitlements.ts
|
|
1276
|
-
var ENTITLED_CLONE_SET = new Set(ALL_ENTITLED_CLONES);
|
|
1114
|
+
// ../node-auth/src/credential-store.ts
|
|
1115
|
+
function errorMessage2(error) {
|
|
1116
|
+
return error instanceof Error ? error.message : String(error);
|
|
1117
|
+
}
|
|
1118
|
+
var ENTITLED_CLONE_SET = new Set(ALL_STARTABLE_CLONE_IDS);
|
|
1277
1119
|
function normalizeEntitledCloneIds(cloneIds) {
|
|
1278
1120
|
if (!cloneIds) {
|
|
1279
1121
|
return [];
|
|
@@ -1290,8 +1132,6 @@ function normalizeEntitledCloneIds(cloneIds) {
|
|
|
1290
1132
|
}
|
|
1291
1133
|
return [...normalized];
|
|
1292
1134
|
}
|
|
1293
|
-
|
|
1294
|
-
// ../node-auth/src/credential-store.ts
|
|
1295
1135
|
var KEYCHAIN_COMMAND_TIMEOUT_MS = 1500;
|
|
1296
1136
|
var ARCHAL_DIR_NAME = ".archal";
|
|
1297
1137
|
var TEST_SANDBOX_ID_ENV_VAR = "ARCHAL_TEST_SANDBOX_ID";
|
|
@@ -1363,7 +1203,7 @@ function seedSandboxFromRealHomeOnce(sandboxDir) {
|
|
|
1363
1203
|
}
|
|
1364
1204
|
}
|
|
1365
1205
|
function getArchalDir() {
|
|
1366
|
-
const explicit = process.env["ARCHAL_HOME"];
|
|
1206
|
+
const explicit = process.env["ARCHAL_HOME"]?.trim();
|
|
1367
1207
|
if (explicit) {
|
|
1368
1208
|
return explicit;
|
|
1369
1209
|
}
|
|
@@ -1647,7 +1487,66 @@ function readCredentialsFile(options) {
|
|
|
1647
1487
|
return readCredentialsFileAtPath(getCredentialsPath(), options);
|
|
1648
1488
|
}
|
|
1649
1489
|
function isWorkspaceApiKey(token) {
|
|
1650
|
-
return token.startsWith(
|
|
1490
|
+
return token.startsWith(WORKSPACE_API_KEY_PREFIX) || token.startsWith("archal_") && !token.includes(".");
|
|
1491
|
+
}
|
|
1492
|
+
var WORKSPACE_API_KEY_EXPIRES_SECONDS = 365 * 24 * 60 * 60;
|
|
1493
|
+
function parseEnvToken(token, envName = AUTH_TOKEN_ENV_VAR, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
1494
|
+
const trimmed = token.trim();
|
|
1495
|
+
if (!trimmed) {
|
|
1496
|
+
return { status: "invalid", message: `${envName} is empty.` };
|
|
1497
|
+
}
|
|
1498
|
+
if (isWorkspaceApiKey(trimmed)) {
|
|
1499
|
+
return {
|
|
1500
|
+
status: "ok",
|
|
1501
|
+
credentials: {
|
|
1502
|
+
token: trimmed,
|
|
1503
|
+
refreshToken: "",
|
|
1504
|
+
email: "(workspace-api-key)",
|
|
1505
|
+
plan: "pro",
|
|
1506
|
+
selectedCloneIds: [],
|
|
1507
|
+
expiresAt: nowSeconds + WORKSPACE_API_KEY_EXPIRES_SECONDS
|
|
1508
|
+
}
|
|
1509
|
+
};
|
|
1510
|
+
}
|
|
1511
|
+
const claims = decodeJwtPayload(trimmed);
|
|
1512
|
+
if (claims === null) {
|
|
1513
|
+
return {
|
|
1514
|
+
status: "invalid",
|
|
1515
|
+
message: `${envName} must be a JWT with valid plan and exp claims or a workspace API key (archal_ws_...).`
|
|
1516
|
+
};
|
|
1517
|
+
}
|
|
1518
|
+
const email = typeof claims["email"] === "string" ? claims["email"] : `(from ${envName})`;
|
|
1519
|
+
if (!isPlan(claims["plan"])) {
|
|
1520
|
+
return {
|
|
1521
|
+
status: "invalid",
|
|
1522
|
+
message: `${envName} JWT does not contain a valid plan claim.`
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
const plan = claims["plan"];
|
|
1526
|
+
if (typeof claims["exp"] !== "number" || !Number.isFinite(claims["exp"])) {
|
|
1527
|
+
return {
|
|
1528
|
+
status: "invalid",
|
|
1529
|
+
message: `${envName} JWT does not contain a valid exp claim.`
|
|
1530
|
+
};
|
|
1531
|
+
}
|
|
1532
|
+
const expiresAt = claims["exp"];
|
|
1533
|
+
if (expiresAt <= nowSeconds) {
|
|
1534
|
+
return {
|
|
1535
|
+
status: "expired",
|
|
1536
|
+
message: `${envName} is expired. Remove it or replace it with a valid token.`
|
|
1537
|
+
};
|
|
1538
|
+
}
|
|
1539
|
+
return {
|
|
1540
|
+
status: "ok",
|
|
1541
|
+
credentials: {
|
|
1542
|
+
token: trimmed,
|
|
1543
|
+
refreshToken: "",
|
|
1544
|
+
email,
|
|
1545
|
+
plan,
|
|
1546
|
+
selectedCloneIds: [],
|
|
1547
|
+
expiresAt
|
|
1548
|
+
}
|
|
1549
|
+
};
|
|
1651
1550
|
}
|
|
1652
1551
|
function getStoredCredentials(options) {
|
|
1653
1552
|
const creds = readCredentialsFile(options);
|
|
@@ -1804,8 +1703,37 @@ function getConfiguredAuthBaseUrl(options) {
|
|
|
1804
1703
|
}
|
|
1805
1704
|
return isStrictEndpointModeEnabled() ? null : HOSTED_DEFAULT_AUTH_BASE_URL;
|
|
1806
1705
|
}
|
|
1706
|
+
function readConfiguredUrlFromEnvChain(envVarNames, options) {
|
|
1707
|
+
const uniqueEnvVars = [...new Set(envVarNames)];
|
|
1708
|
+
return readConfiguredUrl(options, ...uniqueEnvVars);
|
|
1709
|
+
}
|
|
1710
|
+
function getConfiguredAuthValidationBaseUrl(options = {}) {
|
|
1711
|
+
const apiUrlEnvVar = options.apiUrlEnvVar ?? "ARCHAL_API_URL";
|
|
1712
|
+
const authUrlEnvVar = options.authUrlEnvVar ?? "ARCHAL_AUTH_URL";
|
|
1713
|
+
const resolved = readConfiguredUrlFromEnvChain([
|
|
1714
|
+
apiUrlEnvVar,
|
|
1715
|
+
authUrlEnvVar,
|
|
1716
|
+
"ARCHAL_AUTH_URL",
|
|
1717
|
+
"ARCHAL_AUTH_BASE_URL",
|
|
1718
|
+
"ARCHAL_API_URL",
|
|
1719
|
+
"ARCHAL_API_BASE_URL"
|
|
1720
|
+
], options);
|
|
1721
|
+
if (resolved) {
|
|
1722
|
+
return resolved;
|
|
1723
|
+
}
|
|
1724
|
+
return isStrictEndpointModeEnabled() ? null : HOSTED_DEFAULT_AUTH_BASE_URL;
|
|
1725
|
+
}
|
|
1726
|
+
function getConfiguredVitestApiBaseUrl(fallback = HOSTED_DEFAULT_API_BASE_URL, options) {
|
|
1727
|
+
return readConfiguredUrlFromEnvChain([
|
|
1728
|
+
"ARCHAL_VITEST_API_URL",
|
|
1729
|
+
"ARCHAL_API_URL",
|
|
1730
|
+
"ARCHAL_API_BASE_URL",
|
|
1731
|
+
"ARCHAL_AUTH_URL",
|
|
1732
|
+
"ARCHAL_AUTH_BASE_URL"
|
|
1733
|
+
], options) ?? fallback;
|
|
1734
|
+
}
|
|
1807
1735
|
|
|
1808
|
-
// ../node-auth/src/
|
|
1736
|
+
// ../node-auth/src/token-exchange.ts
|
|
1809
1737
|
function buildAuthRequestHeaders(metadata, includeContentType = false) {
|
|
1810
1738
|
const headers = {};
|
|
1811
1739
|
if (includeContentType) {
|
|
@@ -1933,34 +1861,6 @@ import { createHash as createHash2, timingSafeEqual } from "crypto";
|
|
|
1933
1861
|
var STORED_CREDENTIALS_LOCK_TIMEOUT_MS = 3e4;
|
|
1934
1862
|
var STORED_CREDENTIALS_STALE_LOCK_MS = STORED_CREDENTIALS_LOCK_TIMEOUT_MS;
|
|
1935
1863
|
var STORED_CREDENTIALS_LOCK_POLL_INTERVAL_MS = 50;
|
|
1936
|
-
var DEFAULT_AUTH_BASE_URL = "https://www.archal.ai";
|
|
1937
|
-
var WORKSPACE_API_KEY_EXPIRES_SECONDS = 365 * 24 * 60 * 60;
|
|
1938
|
-
function readFirstConfiguredBaseUrl(envVars) {
|
|
1939
|
-
for (const envVar of envVars) {
|
|
1940
|
-
const configured = trimEnv(envVar);
|
|
1941
|
-
if (!configured) {
|
|
1942
|
-
continue;
|
|
1943
|
-
}
|
|
1944
|
-
const normalized = normalizeApiBaseUrl(configured);
|
|
1945
|
-
if (normalized) {
|
|
1946
|
-
return normalized;
|
|
1947
|
-
}
|
|
1948
|
-
}
|
|
1949
|
-
return null;
|
|
1950
|
-
}
|
|
1951
|
-
function resolveHostedAuthBaseUrl(options) {
|
|
1952
|
-
const authUrlEnvVar = options.authUrlEnvVar ?? "ARCHAL_AUTH_URL";
|
|
1953
|
-
const apiUrlEnvVar = options.apiUrlEnvVar ?? "ARCHAL_API_URL";
|
|
1954
|
-
const envVars = [.../* @__PURE__ */ new Set([
|
|
1955
|
-
apiUrlEnvVar,
|
|
1956
|
-
authUrlEnvVar,
|
|
1957
|
-
"ARCHAL_AUTH_URL",
|
|
1958
|
-
"ARCHAL_AUTH_BASE_URL",
|
|
1959
|
-
"ARCHAL_API_URL",
|
|
1960
|
-
"ARCHAL_API_BASE_URL"
|
|
1961
|
-
])];
|
|
1962
|
-
return readFirstConfiguredBaseUrl(envVars) ?? DEFAULT_AUTH_BASE_URL;
|
|
1963
|
-
}
|
|
1964
1864
|
function isImplicitTestSandboxFlow() {
|
|
1965
1865
|
if (trimEnv("ARCHAL_HOME")) {
|
|
1966
1866
|
return false;
|
|
@@ -1977,59 +1877,11 @@ function readExplicitEnvCredentials(envName) {
|
|
|
1977
1877
|
if (!token) {
|
|
1978
1878
|
return { kind: "missing" };
|
|
1979
1879
|
}
|
|
1980
|
-
const
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
if (isWorkspaceApiKey(token)) {
|
|
1984
|
-
return {
|
|
1985
|
-
kind: "valid",
|
|
1986
|
-
credentials: {
|
|
1987
|
-
token,
|
|
1988
|
-
refreshToken: "",
|
|
1989
|
-
email: "(workspace-api-key)",
|
|
1990
|
-
plan: "pro",
|
|
1991
|
-
selectedCloneIds: [],
|
|
1992
|
-
expiresAt: nowSeconds + WORKSPACE_API_KEY_EXPIRES_SECONDS
|
|
1993
|
-
}
|
|
1994
|
-
};
|
|
1995
|
-
}
|
|
1996
|
-
return {
|
|
1997
|
-
kind: "invalid",
|
|
1998
|
-
message: `${envName} must be a JWT with valid plan and exp claims or a workspace API key (archal_ws_...).`
|
|
1999
|
-
};
|
|
2000
|
-
}
|
|
2001
|
-
const email = typeof claims["email"] === "string" ? claims["email"] : `(from ${envName})`;
|
|
2002
|
-
if (!isPlan(claims["plan"])) {
|
|
2003
|
-
return {
|
|
2004
|
-
kind: "invalid",
|
|
2005
|
-
message: `${envName} JWT does not contain a valid plan claim.`
|
|
2006
|
-
};
|
|
2007
|
-
}
|
|
2008
|
-
const plan = claims["plan"];
|
|
2009
|
-
if (typeof claims["exp"] !== "number" || !Number.isFinite(claims["exp"])) {
|
|
2010
|
-
return {
|
|
2011
|
-
kind: "invalid",
|
|
2012
|
-
message: `${envName} JWT does not contain a valid exp claim.`
|
|
2013
|
-
};
|
|
2014
|
-
}
|
|
2015
|
-
const expiresAt = claims["exp"];
|
|
2016
|
-
if (expiresAt <= nowSeconds) {
|
|
2017
|
-
return {
|
|
2018
|
-
kind: "invalid",
|
|
2019
|
-
message: `${envName} is expired. Remove it or replace it with a valid token.`
|
|
2020
|
-
};
|
|
1880
|
+
const parsed = parseEnvToken(token, envName);
|
|
1881
|
+
if (parsed.status !== "ok") {
|
|
1882
|
+
return { kind: "invalid", message: parsed.message };
|
|
2021
1883
|
}
|
|
2022
|
-
return {
|
|
2023
|
-
kind: "valid",
|
|
2024
|
-
credentials: {
|
|
2025
|
-
token,
|
|
2026
|
-
refreshToken: "",
|
|
2027
|
-
email,
|
|
2028
|
-
plan,
|
|
2029
|
-
selectedCloneIds: [],
|
|
2030
|
-
expiresAt
|
|
2031
|
-
}
|
|
2032
|
-
};
|
|
1884
|
+
return { kind: "valid", credentials: parsed.credentials };
|
|
2033
1885
|
}
|
|
2034
1886
|
function readStoredCredentials(includeExpired = false) {
|
|
2035
1887
|
prepareStoredCredentialSources();
|
|
@@ -2061,16 +1913,6 @@ function resolveCredentialsWithSource(tokenEnvVar, includeExpiredStored = false)
|
|
|
2061
1913
|
}
|
|
2062
1914
|
return { credentials: storedCredentials, source: "stored" };
|
|
2063
1915
|
}
|
|
2064
|
-
function resolveHostedCredentials(tokenEnvVar = "ARCHAL_TOKEN") {
|
|
2065
|
-
return resolveCredentialsWithSource(tokenEnvVar)?.credentials ?? null;
|
|
2066
|
-
}
|
|
2067
|
-
function getCredentials2(tokenEnvVar = "ARCHAL_TOKEN") {
|
|
2068
|
-
const credentials = resolveHostedCredentials(tokenEnvVar);
|
|
2069
|
-
if (!credentials) {
|
|
2070
|
-
return null;
|
|
2071
|
-
}
|
|
2072
|
-
return credentials.expiresAt > Math.floor(Date.now() / 1e3) ? credentials : null;
|
|
2073
|
-
}
|
|
2074
1916
|
function prepareStoredCredentialSources() {
|
|
2075
1917
|
if (isImplicitTestSandboxFlow()) {
|
|
2076
1918
|
seedTestSandboxCredentialsFromRealHome();
|
|
@@ -2156,7 +1998,15 @@ async function resolveCurrentCredentials(credentials, source, forceValidation, a
|
|
|
2156
1998
|
}
|
|
2157
1999
|
async function createHostedAuthLease(options = {}) {
|
|
2158
2000
|
const tokenEnvVar = options.tokenEnvVar ?? "ARCHAL_TOKEN";
|
|
2159
|
-
const authBaseUrl =
|
|
2001
|
+
const authBaseUrl = getConfiguredAuthValidationBaseUrl({
|
|
2002
|
+
apiUrlEnvVar: options.apiUrlEnvVar,
|
|
2003
|
+
authUrlEnvVar: options.authUrlEnvVar
|
|
2004
|
+
});
|
|
2005
|
+
if (!authBaseUrl) {
|
|
2006
|
+
throw new Error(
|
|
2007
|
+
"Hosted auth validation requires ARCHAL_AUTH_URL or ARCHAL_API_URL when ARCHAL_STRICT_ENDPOINTS=1."
|
|
2008
|
+
);
|
|
2009
|
+
}
|
|
2160
2010
|
const resolved = resolveCredentialsWithSource(tokenEnvVar, true);
|
|
2161
2011
|
if (!resolved) {
|
|
2162
2012
|
const tokenSources = Array.from(/* @__PURE__ */ new Set([tokenEnvVar, "ARCHAL_TOKEN"])).join(", ");
|
|
@@ -2739,6 +2589,7 @@ function positiveIntegerFromEnv(name, fallback) {
|
|
|
2739
2589
|
}
|
|
2740
2590
|
|
|
2741
2591
|
export {
|
|
2592
|
+
getConfiguredVitestApiBaseUrl,
|
|
2742
2593
|
sleep,
|
|
2743
2594
|
DEFAULT_HOSTED_API_BASE_URL,
|
|
2744
2595
|
DEFAULT_SESSION_TTL_SECONDS,
|
|
@@ -2748,11 +2599,9 @@ export {
|
|
|
2748
2599
|
MIN_READY_TIMEOUT_MS,
|
|
2749
2600
|
trimEnv,
|
|
2750
2601
|
parsePositiveInteger,
|
|
2751
|
-
normalizeApiBaseUrl,
|
|
2752
2602
|
fileExists,
|
|
2753
2603
|
requestedSeedsMatchSession,
|
|
2754
2604
|
HostedSessionClient,
|
|
2755
|
-
getCredentials2 as getCredentials,
|
|
2756
2605
|
createHostedAuthLease,
|
|
2757
2606
|
getSessionIdFilePath,
|
|
2758
2607
|
loadFileSeedsIntoClones,
|