archal 0.9.15 → 0.9.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +443 -377
- package/dist/index.cjs +1 -1
- package/dist/vitest/{chunk-WVRVNHAX.js → chunk-CJJ32YQF.js} +26 -5
- package/dist/vitest/{chunk-2GY4SFKE.js → chunk-FU2VLK75.js} +58 -41
- package/dist/vitest/index.cjs +100 -62
- package/dist/vitest/index.d.ts +1 -1
- package/dist/vitest/index.js +4 -4
- package/dist/vitest/runtime/hosted-session-reaper.js +1 -1
- package/dist/vitest/runtime/setup-files.js +2 -2
- package/package.json +2 -2
- package/skills/eval/SKILL.md +1 -1
- package/skills/onboard/SKILL.md +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -55007,33 +55007,33 @@ function resolveRuntimeDir(moduleUrl) {
|
|
|
55007
55007
|
}
|
|
55008
55008
|
return process.cwd();
|
|
55009
55009
|
}
|
|
55010
|
-
return (0,
|
|
55010
|
+
return (0, import_node_path18.dirname)((0, import_node_url4.fileURLToPath)(moduleUrl));
|
|
55011
55011
|
}
|
|
55012
55012
|
function resolveAncestorDirs(moduleUrl, maxParentDepth) {
|
|
55013
55013
|
const dir = resolveRuntimeDir(moduleUrl);
|
|
55014
55014
|
const dirs = [dir];
|
|
55015
55015
|
for (let depth = 1; depth <= maxParentDepth; depth += 1) {
|
|
55016
|
-
dirs.push((0,
|
|
55016
|
+
dirs.push((0, import_node_path18.resolve)(dir, ...Array(depth).fill("..")));
|
|
55017
55017
|
}
|
|
55018
55018
|
return dirs;
|
|
55019
55019
|
}
|
|
55020
55020
|
function resolveLocalTwinAssetCandidates(moduleUrl, twinName, ...segments) {
|
|
55021
55021
|
const dirs = resolveAncestorDirs(moduleUrl, 5);
|
|
55022
55022
|
const candidates = [
|
|
55023
|
-
...dirs.map((dir) => (0,
|
|
55024
|
-
...dirs.map((dir) => (0,
|
|
55023
|
+
...dirs.map((dir) => (0, import_node_path18.resolve)(dir, "clone-assets", twinName, ...segments)),
|
|
55024
|
+
...dirs.map((dir) => (0, import_node_path18.resolve)(dir, "twins", twinName, ...segments))
|
|
55025
55025
|
];
|
|
55026
55026
|
return [...new Set(candidates)];
|
|
55027
55027
|
}
|
|
55028
55028
|
function findFirstExistingLocalTwinAssetPath(moduleUrl, twinName, ...segments) {
|
|
55029
55029
|
return resolveLocalTwinAssetCandidates(moduleUrl, twinName, ...segments).find((candidate) => (0, import_node_fs18.existsSync)(candidate)) ?? null;
|
|
55030
55030
|
}
|
|
55031
|
-
var import_node_fs18,
|
|
55031
|
+
var import_node_fs18, import_node_path18, import_node_url4;
|
|
55032
55032
|
var init_bundled_assets = __esm({
|
|
55033
55033
|
"../packages/seedgen/src/utils/bundled-assets.ts"() {
|
|
55034
55034
|
"use strict";
|
|
55035
55035
|
import_node_fs18 = require("fs");
|
|
55036
|
-
|
|
55036
|
+
import_node_path18 = require("path");
|
|
55037
55037
|
import_node_url4 = require("url");
|
|
55038
55038
|
}
|
|
55039
55039
|
});
|
|
@@ -55258,7 +55258,7 @@ function parseSqlSeed(sql) {
|
|
|
55258
55258
|
return seed;
|
|
55259
55259
|
}
|
|
55260
55260
|
function loadSeedStateFromPath(seedRoot, seedName) {
|
|
55261
|
-
const jsonPath = (0,
|
|
55261
|
+
const jsonPath = (0, import_node_path19.resolve)(seedRoot, `${seedName}.json`);
|
|
55262
55262
|
if ((0, import_node_fs19.existsSync)(jsonPath)) {
|
|
55263
55263
|
try {
|
|
55264
55264
|
return JSON.parse((0, import_node_fs19.readFileSync)(jsonPath, "utf-8"));
|
|
@@ -55267,7 +55267,7 @@ function loadSeedStateFromPath(seedRoot, seedName) {
|
|
|
55267
55267
|
throw new Error(`Failed to parse seed file ${jsonPath}: ${detail}`, { cause: err });
|
|
55268
55268
|
}
|
|
55269
55269
|
}
|
|
55270
|
-
const sqlPath = (0,
|
|
55270
|
+
const sqlPath = (0, import_node_path19.resolve)(seedRoot, `${seedName}.sql`);
|
|
55271
55271
|
if ((0, import_node_fs19.existsSync)(sqlPath)) {
|
|
55272
55272
|
try {
|
|
55273
55273
|
return parseSqlSeed((0, import_node_fs19.readFileSync)(sqlPath, "utf-8"));
|
|
@@ -55299,17 +55299,17 @@ function loadBaseSeedFromDisk(twinName, seedName) {
|
|
|
55299
55299
|
}
|
|
55300
55300
|
function findBaseSeedFilePath(twinName, seedName) {
|
|
55301
55301
|
for (const seedRoot of resolveLocalTwinAssetCandidates(void 0, twinName, "seeds")) {
|
|
55302
|
-
const jsonPath = (0,
|
|
55302
|
+
const jsonPath = (0, import_node_path19.resolve)(seedRoot, `${seedName}.json`);
|
|
55303
55303
|
if ((0, import_node_fs19.existsSync)(jsonPath)) return jsonPath;
|
|
55304
55304
|
}
|
|
55305
55305
|
return null;
|
|
55306
55306
|
}
|
|
55307
|
-
var import_node_fs19,
|
|
55307
|
+
var import_node_fs19, import_node_path19;
|
|
55308
55308
|
var init_state_helpers = __esm({
|
|
55309
55309
|
"../packages/seedgen/src/runner/seed/state-helpers.ts"() {
|
|
55310
55310
|
"use strict";
|
|
55311
55311
|
import_node_fs19 = require("fs");
|
|
55312
|
-
|
|
55312
|
+
import_node_path19 = require("path");
|
|
55313
55313
|
init_src();
|
|
55314
55314
|
init_bundled_assets();
|
|
55315
55315
|
}
|
|
@@ -55347,18 +55347,18 @@ __export(catalog_exports, {
|
|
|
55347
55347
|
});
|
|
55348
55348
|
function localScenarioDirCandidates() {
|
|
55349
55349
|
return [
|
|
55350
|
-
(0,
|
|
55351
|
-
(0,
|
|
55352
|
-
(0,
|
|
55353
|
-
(0,
|
|
55354
|
-
(0,
|
|
55350
|
+
(0, import_node_path33.resolve)("scenarios"),
|
|
55351
|
+
(0, import_node_path33.resolve)("scenario"),
|
|
55352
|
+
(0, import_node_path33.resolve)("test", "scenarios"),
|
|
55353
|
+
(0, import_node_path33.resolve)("tests", "scenarios"),
|
|
55354
|
+
(0, import_node_path33.resolve)(".archal", "scenarios")
|
|
55355
55355
|
];
|
|
55356
55356
|
}
|
|
55357
55357
|
function hostedScenarioCacheRoot() {
|
|
55358
|
-
return (0,
|
|
55358
|
+
return (0, import_node_path33.resolve)(".archal", "cache", "hosted-scenarios");
|
|
55359
55359
|
}
|
|
55360
55360
|
function workspaceScenarioCacheRoot() {
|
|
55361
|
-
return (0,
|
|
55361
|
+
return (0, import_node_path33.resolve)(".archal", "cache", "workspace-scenarios");
|
|
55362
55362
|
}
|
|
55363
55363
|
function findScenarioFiles(dir) {
|
|
55364
55364
|
if (!(0, import_node_fs35.existsSync)(dir)) {
|
|
@@ -55367,12 +55367,12 @@ function findScenarioFiles(dir) {
|
|
|
55367
55367
|
const files = [];
|
|
55368
55368
|
const entries = (0, import_node_fs35.readdirSync)(dir, { withFileTypes: true });
|
|
55369
55369
|
for (const entry of entries) {
|
|
55370
|
-
const fullPath = (0,
|
|
55370
|
+
const fullPath = (0, import_node_path33.join)(dir, entry.name);
|
|
55371
55371
|
if (entry.isDirectory()) {
|
|
55372
55372
|
files.push(...findScenarioFiles(fullPath));
|
|
55373
55373
|
continue;
|
|
55374
55374
|
}
|
|
55375
|
-
if (entry.isFile() && (0,
|
|
55375
|
+
if (entry.isFile() && (0, import_node_path33.extname)(entry.name) === ".md") {
|
|
55376
55376
|
files.push(fullPath);
|
|
55377
55377
|
}
|
|
55378
55378
|
}
|
|
@@ -55386,12 +55386,12 @@ function findLocalScenariosDir() {
|
|
|
55386
55386
|
}
|
|
55387
55387
|
}
|
|
55388
55388
|
return {
|
|
55389
|
-
dir: (0,
|
|
55389
|
+
dir: (0, import_node_path33.resolve)("scenarios"),
|
|
55390
55390
|
candidates
|
|
55391
55391
|
};
|
|
55392
55392
|
}
|
|
55393
55393
|
function resolveLocalScenario(nameOrPath) {
|
|
55394
|
-
const directPath = (0,
|
|
55394
|
+
const directPath = (0, import_node_path33.resolve)(nameOrPath);
|
|
55395
55395
|
if ((0, import_node_fs35.existsSync)(directPath)) {
|
|
55396
55396
|
return directPath;
|
|
55397
55397
|
}
|
|
@@ -55400,7 +55400,7 @@ function resolveLocalScenario(nameOrPath) {
|
|
|
55400
55400
|
if (!(0, import_node_fs35.existsSync)(candidate)) {
|
|
55401
55401
|
continue;
|
|
55402
55402
|
}
|
|
55403
|
-
const rootCandidate = (0,
|
|
55403
|
+
const rootCandidate = (0, import_node_path33.join)(candidate, needle);
|
|
55404
55404
|
if ((0, import_node_fs35.existsSync)(rootCandidate)) {
|
|
55405
55405
|
return rootCandidate;
|
|
55406
55406
|
}
|
|
@@ -55429,28 +55429,28 @@ function normalizeScenarioSlug(input) {
|
|
|
55429
55429
|
return segments.join("/");
|
|
55430
55430
|
}
|
|
55431
55431
|
function deriveScenarioSlugWithinRoot(root, scenarioPath) {
|
|
55432
|
-
const relativePath = (0,
|
|
55432
|
+
const relativePath = (0, import_node_path33.relative)(root, scenarioPath).replace(/\\/gu, "/");
|
|
55433
55433
|
if (!relativePath || relativePath === ".." || relativePath.startsWith("../")) {
|
|
55434
55434
|
return null;
|
|
55435
55435
|
}
|
|
55436
55436
|
return normalizeScenarioSlug(relativePath);
|
|
55437
55437
|
}
|
|
55438
55438
|
function deriveScenarioSlugFromPath(scenarioPath) {
|
|
55439
|
-
const resolvedPath = (0,
|
|
55439
|
+
const resolvedPath = (0, import_node_path33.resolve)(scenarioPath);
|
|
55440
55440
|
const hostedSlug = deriveScenarioSlugWithinRoot(hostedScenarioCacheRoot(), resolvedPath);
|
|
55441
55441
|
if (hostedSlug) {
|
|
55442
55442
|
return hostedSlug;
|
|
55443
55443
|
}
|
|
55444
55444
|
const { dir } = findLocalScenariosDir();
|
|
55445
|
-
return deriveScenarioSlugWithinRoot((0,
|
|
55445
|
+
return deriveScenarioSlugWithinRoot((0, import_node_path33.resolve)(dir), resolvedPath);
|
|
55446
55446
|
}
|
|
55447
55447
|
function cacheHostedScenario(slug2, content) {
|
|
55448
55448
|
const normalizedSlug = normalizeScenarioSlug(slug2);
|
|
55449
55449
|
if (!normalizedSlug) {
|
|
55450
55450
|
throw new Error(`Invalid hosted scenario slug: ${slug2}`);
|
|
55451
55451
|
}
|
|
55452
|
-
const cachedPath = (0,
|
|
55453
|
-
(0, import_node_fs35.mkdirSync)((0,
|
|
55452
|
+
const cachedPath = (0, import_node_path33.resolve)(hostedScenarioCacheRoot(), `${normalizedSlug}.md`);
|
|
55453
|
+
(0, import_node_fs35.mkdirSync)((0, import_node_path33.dirname)(cachedPath), { recursive: true });
|
|
55454
55454
|
(0, import_node_fs35.writeFileSync)(cachedPath, content, "utf8");
|
|
55455
55455
|
return cachedPath;
|
|
55456
55456
|
}
|
|
@@ -55459,8 +55459,8 @@ function cacheWorkspaceScenario(scenario) {
|
|
|
55459
55459
|
if (!normalizedSlug) {
|
|
55460
55460
|
throw new Error(`Invalid workspace scenario slug: ${scenario.slug || scenario.id}`);
|
|
55461
55461
|
}
|
|
55462
|
-
const cachedPath = (0,
|
|
55463
|
-
(0, import_node_fs35.mkdirSync)((0,
|
|
55462
|
+
const cachedPath = (0, import_node_path33.resolve)(workspaceScenarioCacheRoot(), `${normalizedSlug}.md`);
|
|
55463
|
+
(0, import_node_fs35.mkdirSync)((0, import_node_path33.dirname)(cachedPath), { recursive: true });
|
|
55464
55464
|
(0, import_node_fs35.writeFileSync)(cachedPath, scenario.markdown, "utf8");
|
|
55465
55465
|
return cachedPath;
|
|
55466
55466
|
}
|
|
@@ -55527,12 +55527,12 @@ async function resolveWorkspaceScenarioToCachedPath(token, input) {
|
|
|
55527
55527
|
launch: result.data
|
|
55528
55528
|
};
|
|
55529
55529
|
}
|
|
55530
|
-
var import_node_fs35,
|
|
55530
|
+
var import_node_fs35, import_node_path33;
|
|
55531
55531
|
var init_catalog = __esm({
|
|
55532
55532
|
"src/scenarios/catalog.ts"() {
|
|
55533
55533
|
"use strict";
|
|
55534
55534
|
import_node_fs35 = require("fs");
|
|
55535
|
-
|
|
55535
|
+
import_node_path33 = require("path");
|
|
55536
55536
|
init_api_client();
|
|
55537
55537
|
}
|
|
55538
55538
|
});
|
|
@@ -55817,7 +55817,7 @@ function importedSpecifiersInSource(source) {
|
|
|
55817
55817
|
return specifiers;
|
|
55818
55818
|
}
|
|
55819
55819
|
function readEntryFile(harnessDir, candidate) {
|
|
55820
|
-
const filePath = (0,
|
|
55820
|
+
const filePath = (0, import_node_path48.resolve)(harnessDir, candidate);
|
|
55821
55821
|
if (!(0, import_node_fs51.existsSync)(filePath)) return void 0;
|
|
55822
55822
|
try {
|
|
55823
55823
|
return (0, import_node_fs51.readFileSync)(filePath, "utf-8");
|
|
@@ -55840,7 +55840,7 @@ function detectTwinsFromHarnessDir(harnessDir) {
|
|
|
55840
55840
|
twins.add(envSegmentToCloneName(envMatch[1] ?? ""));
|
|
55841
55841
|
}
|
|
55842
55842
|
}
|
|
55843
|
-
for (const dep of readPackageJsonDeps((0,
|
|
55843
|
+
for (const dep of readPackageJsonDeps((0, import_node_path48.resolve)(harnessDir, "package.json"))) {
|
|
55844
55844
|
const twinName = PACKAGE_TO_CLONE[dep];
|
|
55845
55845
|
if (twinName) twins.add(twinName);
|
|
55846
55846
|
}
|
|
@@ -55859,17 +55859,17 @@ function harnessUsesLlm(harnessDir) {
|
|
|
55859
55859
|
if (LLM_SDK_PACKAGES.has(root)) return true;
|
|
55860
55860
|
}
|
|
55861
55861
|
}
|
|
55862
|
-
for (const dep of readPackageJsonDeps((0,
|
|
55862
|
+
for (const dep of readPackageJsonDeps((0, import_node_path48.resolve)(harnessDir, "package.json"))) {
|
|
55863
55863
|
if (LLM_SDK_PACKAGES.has(dep)) return true;
|
|
55864
55864
|
}
|
|
55865
55865
|
return false;
|
|
55866
55866
|
}
|
|
55867
|
-
var import_node_fs51,
|
|
55867
|
+
var import_node_fs51, import_node_path48, TWIN_ENTRY_CANDIDATES, LLM_ENTRY_CANDIDATES, IMPORT_PATTERNS, ENV_VAR_PATTERN, LLM_SDK_PACKAGES;
|
|
55868
55868
|
var init_harness_detect = __esm({
|
|
55869
55869
|
"src/runner/harness-detect.ts"() {
|
|
55870
55870
|
"use strict";
|
|
55871
55871
|
import_node_fs51 = require("fs");
|
|
55872
|
-
|
|
55872
|
+
import_node_path48 = require("path");
|
|
55873
55873
|
init_package_clone_map();
|
|
55874
55874
|
TWIN_ENTRY_CANDIDATES = [
|
|
55875
55875
|
"harness.ts",
|
|
@@ -55925,19 +55925,19 @@ var init_harness_detect = __esm({
|
|
|
55925
55925
|
function buildCloneToolsSnapshotCandidates(cloneId) {
|
|
55926
55926
|
const candidates = [];
|
|
55927
55927
|
if (typeof __dirname === "string" && __dirname.length > 0) {
|
|
55928
|
-
candidates.push((0,
|
|
55929
|
-
candidates.push((0,
|
|
55928
|
+
candidates.push((0, import_node_path51.resolve)(__dirname, "..", "clone-assets", cloneId, "tools.json"));
|
|
55929
|
+
candidates.push((0, import_node_path51.resolve)(__dirname, "..", "..", "clone-assets", cloneId, "tools.json"));
|
|
55930
55930
|
}
|
|
55931
55931
|
const metaUrl = import_meta4.url;
|
|
55932
55932
|
if (typeof metaUrl === "string" && metaUrl.length > 0) {
|
|
55933
55933
|
try {
|
|
55934
|
-
const here = (0,
|
|
55935
|
-
candidates.push((0,
|
|
55936
|
-
candidates.push((0,
|
|
55934
|
+
const here = (0, import_node_path51.dirname)((0, import_node_url6.fileURLToPath)(metaUrl));
|
|
55935
|
+
candidates.push((0, import_node_path51.resolve)(here, "..", "..", "clone-assets", cloneId, "tools.json"));
|
|
55936
|
+
candidates.push((0, import_node_path51.resolve)(here, "..", "clone-assets", cloneId, "tools.json"));
|
|
55937
55937
|
} catch {
|
|
55938
55938
|
}
|
|
55939
55939
|
}
|
|
55940
|
-
candidates.push((0,
|
|
55940
|
+
candidates.push((0, import_node_path51.resolve)(process.cwd(), "clone-assets", cloneId, "tools.json"));
|
|
55941
55941
|
return [...new Set(candidates)];
|
|
55942
55942
|
}
|
|
55943
55943
|
async function loadCloneToolDefinitions(cloneId) {
|
|
@@ -55979,12 +55979,12 @@ async function loadCloneToolDefinitions(cloneId) {
|
|
|
55979
55979
|
}
|
|
55980
55980
|
return parsed.tools;
|
|
55981
55981
|
}
|
|
55982
|
-
var import_node_fs56,
|
|
55982
|
+
var import_node_fs56, import_node_path51, import_node_url6, import_meta4;
|
|
55983
55983
|
var init_clone_tool_loaders = __esm({
|
|
55984
55984
|
"src/clone/clone-tool-loaders.ts"() {
|
|
55985
55985
|
"use strict";
|
|
55986
55986
|
import_node_fs56 = require("fs");
|
|
55987
|
-
|
|
55987
|
+
import_node_path51 = require("path");
|
|
55988
55988
|
import_node_url6 = require("url");
|
|
55989
55989
|
init_src2();
|
|
55990
55990
|
init_errors6();
|
|
@@ -61098,7 +61098,7 @@ function readFlag(path2) {
|
|
|
61098
61098
|
return {};
|
|
61099
61099
|
}
|
|
61100
61100
|
function writeFlag(path2, value) {
|
|
61101
|
-
(0, import_node_fs64.mkdirSync)((0,
|
|
61101
|
+
(0, import_node_fs64.mkdirSync)((0, import_node_path58.dirname)(path2), { recursive: true, mode: 448 });
|
|
61102
61102
|
const tmp = `${path2}.${Math.random().toString(36).slice(2, 10)}.tmp`;
|
|
61103
61103
|
(0, import_node_fs64.writeFileSync)(tmp, `${JSON.stringify(value, null, 2)}
|
|
61104
61104
|
`, { encoding: "utf-8", mode: 384 });
|
|
@@ -61111,7 +61111,7 @@ function shouldEmitLegacyTokenWarning(token) {
|
|
|
61111
61111
|
const claim = payload["workspaceId"];
|
|
61112
61112
|
const hasClaim = typeof claim === "string" && claim.trim().length > 0;
|
|
61113
61113
|
if (hasClaim) return { warned: false };
|
|
61114
|
-
const flagPath = (0,
|
|
61114
|
+
const flagPath = (0, import_node_path58.join)(getArchalDir2(), FLAG_FILE);
|
|
61115
61115
|
const flag = readFlag(flagPath);
|
|
61116
61116
|
const tokenHash = hashToken(token);
|
|
61117
61117
|
const seen = flag.tokenHashes ?? [];
|
|
@@ -61125,13 +61125,13 @@ function shouldEmitLegacyTokenWarning(token) {
|
|
|
61125
61125
|
}
|
|
61126
61126
|
return { warned: true };
|
|
61127
61127
|
}
|
|
61128
|
-
var import_node_crypto31, import_node_fs64,
|
|
61128
|
+
var import_node_crypto31, import_node_fs64, import_node_path58, FLAG_FILE;
|
|
61129
61129
|
var init_legacy_token_warning = __esm({
|
|
61130
61130
|
"src/auth/legacy-token-warning.ts"() {
|
|
61131
61131
|
"use strict";
|
|
61132
61132
|
import_node_crypto31 = require("crypto");
|
|
61133
61133
|
import_node_fs64 = require("fs");
|
|
61134
|
-
|
|
61134
|
+
import_node_path58 = require("path");
|
|
61135
61135
|
init_credential_store2();
|
|
61136
61136
|
FLAG_FILE = "legacy-token-warned.flag";
|
|
61137
61137
|
}
|
|
@@ -61165,7 +61165,7 @@ init_logger();
|
|
|
61165
61165
|
init_src();
|
|
61166
61166
|
var import_node_crypto25 = require("crypto");
|
|
61167
61167
|
var import_node_fs49 = require("fs");
|
|
61168
|
-
var
|
|
61168
|
+
var import_node_path46 = require("path");
|
|
61169
61169
|
|
|
61170
61170
|
// src/runner/orchestrator.ts
|
|
61171
61171
|
init_config_merger();
|
|
@@ -64995,6 +64995,7 @@ var GENERATED_SEEDS = {
|
|
|
64995
64995
|
|
|
64996
64996
|
// ../packages/route-runtime-core/src/runtime.ts
|
|
64997
64997
|
var import_node_module = require("module");
|
|
64998
|
+
var import_node_path14 = require("path");
|
|
64998
64999
|
init_errors();
|
|
64999
65000
|
|
|
65000
65001
|
// ../packages/route-runtime-core/src/service-profiles.ts
|
|
@@ -65030,7 +65031,7 @@ var discordRouteManifest = {
|
|
|
65030
65031
|
],
|
|
65031
65032
|
diagnostics: {
|
|
65032
65033
|
undeclared: ({ url: url2 }) => `Blocked Discord traffic to ${url2}. Declare discord in archalVitestProject({ services: { discord: { mode: "route" } } }) before calling the Discord REST API in Vitest.`,
|
|
65033
|
-
declaredEscape: ({ url: url2
|
|
65034
|
+
declaredEscape: ({ url: url2 }) => `Blocked Discord escape to ${url2}. Discord route mode is configured, but this domain is outside the approved Discord REST route surface.`,
|
|
65034
65035
|
warning: ({ url: url2 }) => `Observed adjacent Discord domain ${url2}. Archal did not reroute this request because it is outside the approved Discord REST route surface.`
|
|
65035
65036
|
},
|
|
65036
65037
|
sdkIdentifiers: ["discord.js", "@discordjs/rest"],
|
|
@@ -65078,7 +65079,7 @@ var githubRouteManifest = {
|
|
|
65078
65079
|
],
|
|
65079
65080
|
diagnostics: {
|
|
65080
65081
|
undeclared: ({ url: url2 }) => `Blocked GitHub traffic to ${url2}. Declare github in archalVitestProject({ services: { github: { mode: "route" } } }) before using the official GitHub SDK.`,
|
|
65081
|
-
declaredEscape: ({ url: url2
|
|
65082
|
+
declaredEscape: ({ url: url2 }) => `Blocked GitHub escape to ${url2}. GitHub route mode is configured, but this domain is outside the primary routed GitHub surface.`,
|
|
65082
65083
|
warning: ({ url: url2 }) => `Observed adjacent GitHub domain ${url2}. Archal did not reroute this request because it is outside the primary GitHub API route surface.`
|
|
65083
65084
|
},
|
|
65084
65085
|
sdkIdentifiers: ["@octokit/rest"],
|
|
@@ -65106,7 +65107,7 @@ var googleWorkspaceRouteManifest = {
|
|
|
65106
65107
|
],
|
|
65107
65108
|
diagnostics: {
|
|
65108
65109
|
undeclared: ({ url: url2 }) => `Blocked Google Workspace traffic to ${url2}. Declare google-workspace in archalVitestProject({ services: { 'google-workspace': { mode: "route" } } }) before using the official Google client.`,
|
|
65109
|
-
declaredEscape: ({ url: url2
|
|
65110
|
+
declaredEscape: ({ url: url2 }) => `Blocked Google Workspace escape to ${url2}. Google Workspace route mode is configured, but this domain is outside the primary routed surface.`,
|
|
65110
65111
|
warning: ({ url: url2 }) => `Observed adjacent Google Workspace domain ${url2}. Archal did not reroute this request because it is outside the primary Google Workspace API route surface.`
|
|
65111
65112
|
},
|
|
65112
65113
|
sdkIdentifiers: ["googleapis"],
|
|
@@ -65128,7 +65129,7 @@ var apifyRouteManifest = {
|
|
|
65128
65129
|
],
|
|
65129
65130
|
diagnostics: {
|
|
65130
65131
|
undeclared: ({ url: url2 }) => `Blocked Apify traffic to ${url2}. Declare apify before using the official Apify client.`,
|
|
65131
|
-
declaredEscape: ({ url: url2
|
|
65132
|
+
declaredEscape: ({ url: url2 }) => `Blocked Apify escape to ${url2}. Apify route mode is configured, but this domain is outside the primary routed Apify API surface.`,
|
|
65132
65133
|
warning: ({ url: url2 }) => `Observed adjacent Apify domain ${url2}. Archal did not reroute this request because it is outside the primary Apify API route surface.`
|
|
65133
65134
|
},
|
|
65134
65135
|
sdkIdentifiers: ["apify-client", "apify"],
|
|
@@ -65153,7 +65154,7 @@ var jiraRouteManifest = {
|
|
|
65153
65154
|
],
|
|
65154
65155
|
diagnostics: {
|
|
65155
65156
|
undeclared: ({ url: url2 }) => `Blocked Jira traffic to ${url2}. Declare jira in archalVitestProject({ services: { jira: { mode: "route" } } }) before using the official Jira SDK.`,
|
|
65156
|
-
declaredEscape: ({ url: url2
|
|
65157
|
+
declaredEscape: ({ url: url2 }) => `Blocked Jira escape to ${url2}. Jira route mode is configured, but this domain is outside the primary routed Jira surface.`,
|
|
65157
65158
|
warning: ({ url: url2 }) => `Observed adjacent Jira domain ${url2}. Archal did not reroute this request because it is outside the primary Jira route surface.`
|
|
65158
65159
|
},
|
|
65159
65160
|
sdkIdentifiers: ["jira.js"],
|
|
@@ -65174,7 +65175,7 @@ var linearRouteManifest = {
|
|
|
65174
65175
|
],
|
|
65175
65176
|
diagnostics: {
|
|
65176
65177
|
undeclared: ({ url: url2 }) => `Blocked Linear traffic to ${url2}. Declare linear in archalVitestProject({ services: { linear: { mode: "route" } } }) before using the official Linear SDK.`,
|
|
65177
|
-
declaredEscape: ({ url: url2
|
|
65178
|
+
declaredEscape: ({ url: url2 }) => `Blocked Linear escape to ${url2}. Linear route mode is configured, but this domain is outside the primary routed Linear API surface.`,
|
|
65178
65179
|
warning: ({ url: url2 }) => `Observed adjacent Linear domain ${url2}. Archal did not reroute this request because it is outside the primary Linear API route surface.`
|
|
65179
65180
|
},
|
|
65180
65181
|
sdkIdentifiers: ["@linear/sdk"],
|
|
@@ -65196,7 +65197,7 @@ var rampRouteManifest = {
|
|
|
65196
65197
|
],
|
|
65197
65198
|
diagnostics: {
|
|
65198
65199
|
undeclared: ({ url: url2 }) => `Blocked Ramp traffic to ${url2}. Declare ramp in archalVitestProject({ services: { ramp: { mode: "route" } } }) before using the official Ramp client.`,
|
|
65199
|
-
declaredEscape: ({ url: url2
|
|
65200
|
+
declaredEscape: ({ url: url2 }) => `Blocked Ramp escape to ${url2}. Ramp route mode is configured, but this domain is outside the primary routed Ramp API surface.`,
|
|
65200
65201
|
warning: ({ url: url2 }) => `Observed adjacent Ramp domain ${url2}. Archal did not reroute this request because it is outside the primary Ramp API route surface.`
|
|
65201
65202
|
},
|
|
65202
65203
|
sdkIdentifiers: ["ramp"],
|
|
@@ -65229,7 +65230,7 @@ var slackRouteManifest = {
|
|
|
65229
65230
|
],
|
|
65230
65231
|
diagnostics: {
|
|
65231
65232
|
undeclared: ({ url: url2 }) => `Blocked Slack traffic to ${url2}. Declare slack in archalVitestProject({ services: { slack: { mode: "route" } } }) before using the official Slack SDK.`,
|
|
65232
|
-
declaredEscape: ({ url: url2
|
|
65233
|
+
declaredEscape: ({ url: url2 }) => `Blocked Slack escape to ${url2}. Slack route mode is configured, but this domain is outside the primary routed Slack surface.`,
|
|
65233
65234
|
warning: ({ url: url2 }) => `Observed adjacent Slack domain ${url2}. Archal did not reroute this request because it is outside the primary Slack API route surface.`
|
|
65234
65235
|
},
|
|
65235
65236
|
sdkIdentifiers: ["@slack/web-api"],
|
|
@@ -65297,7 +65298,7 @@ var stripeRouteManifest = {
|
|
|
65297
65298
|
],
|
|
65298
65299
|
diagnostics: {
|
|
65299
65300
|
undeclared: ({ url: url2 }) => `Blocked Stripe traffic to ${url2}. Declare stripe in archalVitestProject({ services: { stripe: { mode: "route" } } }) before using the official Stripe SDK.`,
|
|
65300
|
-
declaredEscape: ({ url: url2
|
|
65301
|
+
declaredEscape: ({ url: url2 }) => `Blocked Stripe escape to ${url2}. Stripe route mode is configured, but this Stripe-owned domain is outside the current routed surface.`,
|
|
65301
65302
|
warning: ({ url: url2 }) => `Observed adjacent Stripe domain ${url2}. Archal did not reroute this request because it is outside the primary Stripe API route surface.`
|
|
65302
65303
|
},
|
|
65303
65304
|
runtimeSurface: stripeRuntimeSurface,
|
|
@@ -65320,7 +65321,7 @@ var supabaseRouteManifest = {
|
|
|
65320
65321
|
],
|
|
65321
65322
|
diagnostics: {
|
|
65322
65323
|
undeclared: ({ url: url2 }) => `Blocked Supabase traffic to ${url2}. Declare supabase in archalVitestProject({ services: { supabase: { mode: "route" } } }) before using the official Supabase SDK.`,
|
|
65323
|
-
declaredEscape: ({ url: url2
|
|
65324
|
+
declaredEscape: ({ url: url2 }) => `Blocked Supabase escape to ${url2}. Supabase route mode is configured, but this domain is outside the primary routed Supabase surface.`,
|
|
65324
65325
|
warning: ({ url: url2 }) => `Observed adjacent Supabase domain ${url2}. Archal did not reroute this request because it is outside the primary Supabase route surface.`
|
|
65325
65326
|
},
|
|
65326
65327
|
sdkIdentifiers: ["@supabase/supabase-js"],
|
|
@@ -65342,7 +65343,7 @@ var tavilyRouteManifest = {
|
|
|
65342
65343
|
],
|
|
65343
65344
|
diagnostics: {
|
|
65344
65345
|
undeclared: ({ url: url2 }) => `Blocked Tavily traffic to ${url2}. Declare tavily before using the official Tavily client.`,
|
|
65345
|
-
declaredEscape: ({ url: url2
|
|
65346
|
+
declaredEscape: ({ url: url2 }) => `Blocked Tavily escape to ${url2}. Tavily route mode is configured, but this domain is outside the primary routed Tavily API surface.`,
|
|
65346
65347
|
warning: ({ url: url2 }) => `Observed adjacent Tavily domain ${url2}. Archal did not reroute this request because it is outside the primary Tavily API route surface.`
|
|
65347
65348
|
},
|
|
65348
65349
|
sdkIdentifiers: ["@tavily/core", "tavily"],
|
|
@@ -65384,7 +65385,9 @@ function buildServiceCompatibilityProfile(manifest) {
|
|
|
65384
65385
|
|
|
65385
65386
|
// ../packages/route-runtime-core/src/runtime.ts
|
|
65386
65387
|
var import_meta2 = {};
|
|
65387
|
-
var require2 = (0, import_node_module.createRequire)(
|
|
65388
|
+
var require2 = (0, import_node_module.createRequire)(
|
|
65389
|
+
typeof __filename === "string" && (0, import_node_path14.isAbsolute)(__filename) ? __filename : import_meta2.url
|
|
65390
|
+
);
|
|
65388
65391
|
var httpModule = require2("node:http");
|
|
65389
65392
|
var httpsModule = require2("node:https");
|
|
65390
65393
|
var SHARED_SERVICE_PROFILES = listSharedRouteManifests().map(buildServiceCompatibilityProfile);
|
|
@@ -66381,7 +66384,7 @@ function getAvailableSeeds(cloneName) {
|
|
|
66381
66384
|
|
|
66382
66385
|
// src/runner/seed-snapshot.ts
|
|
66383
66386
|
var import_node_fs14 = require("fs");
|
|
66384
|
-
var
|
|
66387
|
+
var import_node_path15 = require("path");
|
|
66385
66388
|
init_src();
|
|
66386
66389
|
init_zod();
|
|
66387
66390
|
var seedSnapshotEntryDiskSchema = external_exports3.object({
|
|
@@ -66401,7 +66404,7 @@ var seedSnapshotSchema = external_exports3.object({
|
|
|
66401
66404
|
seeds: external_exports3.array(seedSnapshotEntrySchema).min(1)
|
|
66402
66405
|
});
|
|
66403
66406
|
function loadSeedSnapshot(pathInput) {
|
|
66404
|
-
const resolvedPath = (0,
|
|
66407
|
+
const resolvedPath = (0, import_node_path15.resolve)(pathInput);
|
|
66405
66408
|
let parsedJson;
|
|
66406
66409
|
try {
|
|
66407
66410
|
parsedJson = JSON.parse((0, import_node_fs14.readFileSync)(resolvedPath, "utf-8"));
|
|
@@ -66419,8 +66422,8 @@ function loadSeedSnapshot(pathInput) {
|
|
|
66419
66422
|
return parsed.data;
|
|
66420
66423
|
}
|
|
66421
66424
|
function saveSeedSnapshot(pathInput, input) {
|
|
66422
|
-
const resolvedPath = (0,
|
|
66423
|
-
(0, import_node_fs14.mkdirSync)((0,
|
|
66425
|
+
const resolvedPath = (0, import_node_path15.resolve)(pathInput);
|
|
66426
|
+
(0, import_node_fs14.mkdirSync)((0, import_node_path15.dirname)(resolvedPath), { recursive: true });
|
|
66424
66427
|
const payload = {
|
|
66425
66428
|
version: 1,
|
|
66426
66429
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -66441,7 +66444,7 @@ init_src();
|
|
|
66441
66444
|
|
|
66442
66445
|
// src/runner/execution/agent-executor.ts
|
|
66443
66446
|
var import_node_fs17 = require("fs");
|
|
66444
|
-
var
|
|
66447
|
+
var import_node_path17 = require("path");
|
|
66445
66448
|
var import_node_os5 = require("os");
|
|
66446
66449
|
var import_node_crypto16 = require("crypto");
|
|
66447
66450
|
init_src();
|
|
@@ -66538,7 +66541,7 @@ init_logger();
|
|
|
66538
66541
|
|
|
66539
66542
|
// src/utils/resolve-command.ts
|
|
66540
66543
|
var import_node_fs15 = require("fs");
|
|
66541
|
-
var
|
|
66544
|
+
var import_node_path16 = require("path");
|
|
66542
66545
|
function getEnvValue(env, key) {
|
|
66543
66546
|
if (env && Object.prototype.hasOwnProperty.call(env, key)) return env[key];
|
|
66544
66547
|
if (process.platform !== "win32" || !env) return void 0;
|
|
@@ -66567,12 +66570,12 @@ function getWindowsExecutableCandidates(command, env) {
|
|
|
66567
66570
|
return [...extensions.flatMap((suffix) => [`${command}${suffix.toLowerCase()}`, `${command}${suffix.toUpperCase()}`]), command];
|
|
66568
66571
|
}
|
|
66569
66572
|
function findWindowsCommand(command, cwd, env) {
|
|
66570
|
-
const hasPathSegment = command.includes("/") || command.includes("\\") || (0,
|
|
66573
|
+
const hasPathSegment = command.includes("/") || command.includes("\\") || (0, import_node_path16.isAbsolute)(command);
|
|
66571
66574
|
const candidates = getWindowsExecutableCandidates(command, env);
|
|
66572
66575
|
if (hasPathSegment) {
|
|
66573
66576
|
const baseDir = cwd ?? process.cwd();
|
|
66574
66577
|
for (const candidate of candidates) {
|
|
66575
|
-
const fullPath = (0,
|
|
66578
|
+
const fullPath = (0, import_node_path16.isAbsolute)(candidate) ? candidate : (0, import_node_path16.resolve)(baseDir, candidate);
|
|
66576
66579
|
if ((0, import_node_fs15.existsSync)(fullPath) && isExecutable(fullPath)) {
|
|
66577
66580
|
return fullPath;
|
|
66578
66581
|
}
|
|
@@ -66580,11 +66583,11 @@ function findWindowsCommand(command, cwd, env) {
|
|
|
66580
66583
|
return null;
|
|
66581
66584
|
}
|
|
66582
66585
|
const pathValue = getEnvValue(env, "PATH") ?? process.env["PATH"] ?? "";
|
|
66583
|
-
for (const segment of pathValue.split(
|
|
66586
|
+
for (const segment of pathValue.split(import_node_path16.delimiter)) {
|
|
66584
66587
|
const dir = segment.trim();
|
|
66585
66588
|
if (!dir) continue;
|
|
66586
66589
|
for (const candidate of candidates) {
|
|
66587
|
-
const fullPath = (0,
|
|
66590
|
+
const fullPath = (0, import_node_path16.join)(dir, candidate);
|
|
66588
66591
|
if ((0, import_node_fs15.existsSync)(fullPath) && isExecutable(fullPath)) {
|
|
66589
66592
|
return fullPath;
|
|
66590
66593
|
}
|
|
@@ -66600,7 +66603,7 @@ function resolveCommandForSpawn(command, args, cwd, env) {
|
|
|
66600
66603
|
if (!resolvedCommand) {
|
|
66601
66604
|
return { command, args };
|
|
66602
66605
|
}
|
|
66603
|
-
const extension = (0,
|
|
66606
|
+
const extension = (0, import_node_path16.extname)(resolvedCommand).toLowerCase();
|
|
66604
66607
|
if (extension === ".cmd" || extension === ".bat") {
|
|
66605
66608
|
const shell = getEnvValue(env, "COMSPEC") || process.env["COMSPEC"] || "cmd.exe";
|
|
66606
66609
|
return {
|
|
@@ -66883,6 +66886,10 @@ var AGENT_TASK_ENV = "AGENT_TASK";
|
|
|
66883
66886
|
var AGENT_MODEL_ENV = "AGENT_MODEL";
|
|
66884
66887
|
var AGENT_METRICS_FILE_ENV = "AGENT_METRICS_FILE";
|
|
66885
66888
|
var AGENT_TRACE_FILE_ENV = "AGENT_TRACE_FILE";
|
|
66889
|
+
var AGENT_CLONE_URLS_ENV = "AGENT_CLONE_URLS";
|
|
66890
|
+
var AGENT_ROUTE_AUTHORIZATION_ENV = "AGENT_ROUTE_AUTHORIZATION";
|
|
66891
|
+
var AGENT_ROUTE_AUTHORIZATION_HEADER_ENV = "AGENT_ROUTE_AUTHORIZATION_HEADER";
|
|
66892
|
+
var AGENT_ROUTE_HEADERS_ENV = "AGENT_ROUTE_HEADERS";
|
|
66886
66893
|
function shouldExposeLegacyAgentEnv(env) {
|
|
66887
66894
|
return TRUE_ENV_VALUES.has(env?.[LEGACY_AGENT_ENV_COMPAT]?.trim().toLowerCase() ?? "");
|
|
66888
66895
|
}
|
|
@@ -67346,6 +67353,10 @@ function maybeSetEnv(env, key, value) {
|
|
|
67346
67353
|
env[key] = trimmed;
|
|
67347
67354
|
}
|
|
67348
67355
|
}
|
|
67356
|
+
function toAgentServiceEnvVarName(serviceName, suffix) {
|
|
67357
|
+
const segment = toServiceEnvSegment(serviceName);
|
|
67358
|
+
return segment ? `${segment}_${suffix}` : null;
|
|
67359
|
+
}
|
|
67349
67360
|
function buildTrustedCloneRoutingEnv(input) {
|
|
67350
67361
|
const env = {};
|
|
67351
67362
|
const restUrls = {};
|
|
@@ -67356,26 +67367,38 @@ function buildTrustedCloneRoutingEnv(input) {
|
|
|
67356
67367
|
if (!rawUrl) {
|
|
67357
67368
|
continue;
|
|
67358
67369
|
}
|
|
67359
|
-
if (!includeHostedRuntimeUrls && isArchalHostedRuntimeUrl(rawUrl)) {
|
|
67360
|
-
continue;
|
|
67361
|
-
}
|
|
67362
67370
|
const restUrl = toTwinRestUrl(rawUrl);
|
|
67363
67371
|
const mcpUrl = toTwinMcpUrl(rawUrl);
|
|
67364
67372
|
restUrls[cloneName] = restUrl;
|
|
67365
|
-
maybeSetEnv(env,
|
|
67366
|
-
maybeSetEnv(env,
|
|
67367
|
-
maybeSetEnv(env,
|
|
67368
|
-
maybeSetEnv(env,
|
|
67369
|
-
|
|
67373
|
+
maybeSetEnv(env, toAgentServiceEnvVarName(cloneName, "BASE_URL"), restUrl);
|
|
67374
|
+
maybeSetEnv(env, toAgentServiceEnvVarName(cloneName, "URL"), restUrl);
|
|
67375
|
+
maybeSetEnv(env, toAgentServiceEnvVarName(cloneName, "REST_URL"), restUrl);
|
|
67376
|
+
maybeSetEnv(env, toAgentServiceEnvVarName(cloneName, "MCP_URL"), mcpUrl);
|
|
67377
|
+
if (includeHostedRuntimeUrls || !isArchalHostedRuntimeUrl(rawUrl)) {
|
|
67378
|
+
maybeSetEnv(env, toServiceEnvVarName(cloneName, "BASE_URL"), restUrl);
|
|
67379
|
+
maybeSetEnv(env, toServiceEnvVarName(cloneName, "URL"), restUrl);
|
|
67380
|
+
maybeSetEnv(env, toServiceEnvVarName(cloneName, "REST_URL"), restUrl);
|
|
67381
|
+
maybeSetEnv(env, toServiceEnvVarName(cloneName, "MCP_URL"), mcpUrl);
|
|
67382
|
+
maybeSetEnv(env, toCloneServiceEnvVarName(cloneName, "CLONE_URL"), restUrl);
|
|
67383
|
+
}
|
|
67370
67384
|
}
|
|
67371
67385
|
const routedCloneNames = Object.keys(restUrls);
|
|
67372
67386
|
if (routedCloneNames.length === 0) {
|
|
67373
67387
|
return env;
|
|
67374
67388
|
}
|
|
67375
67389
|
const cloneNamesCsv = routedCloneNames.join(",");
|
|
67376
|
-
env[
|
|
67377
|
-
|
|
67390
|
+
env[AGENT_CLONE_URLS_ENV] = JSON.stringify(restUrls);
|
|
67391
|
+
const bearerToken = input.bearerToken?.trim();
|
|
67392
|
+
if (bearerToken) {
|
|
67393
|
+
const routeAuthorization = `Bearer ${bearerToken}`;
|
|
67394
|
+
const routeHeaders = { "x-route-authorization": routeAuthorization };
|
|
67395
|
+
env[AGENT_ROUTE_AUTHORIZATION_HEADER_ENV] = "x-route-authorization";
|
|
67396
|
+
env[AGENT_ROUTE_AUTHORIZATION_ENV] = routeAuthorization;
|
|
67397
|
+
env[AGENT_ROUTE_HEADERS_ENV] = JSON.stringify(routeHeaders);
|
|
67398
|
+
}
|
|
67378
67399
|
if (includeHostedRuntimeUrls) {
|
|
67400
|
+
env[ARCHAL_CLONE_NAMES_ENV] = cloneNamesCsv;
|
|
67401
|
+
env[ARCHAL_CLONE_URLS_ENV] = JSON.stringify(restUrls);
|
|
67379
67402
|
maybeSetEnv(env, "ARCHAL_MCP_CONFIG", input.mcpConfigPath);
|
|
67380
67403
|
maybeSetEnv(env, "MCP_CONFIG_PATH", input.mcpConfigPath);
|
|
67381
67404
|
maybeSetEnv(env, "ARCHAL_MCP_SERVERS", input.mcpServersJson);
|
|
@@ -67509,8 +67532,8 @@ async function executeAgent(params) {
|
|
|
67509
67532
|
timeoutMs
|
|
67510
67533
|
} = params;
|
|
67511
67534
|
const uniqueSuffix = (0, import_node_crypto16.randomUUID)();
|
|
67512
|
-
const metricsFilePath = (0,
|
|
67513
|
-
const agentTraceFilePath = (0,
|
|
67535
|
+
const metricsFilePath = (0, import_node_path17.join)((0, import_node_os5.tmpdir)(), `agent-metrics-${uniqueSuffix}.json`);
|
|
67536
|
+
const agentTraceFilePath = (0, import_node_path17.join)((0, import_node_os5.tmpdir)(), `agent-trace-${uniqueSuffix}.json`);
|
|
67514
67537
|
const includeLegacyArchalEnv = params.includeLegacyArchalEnv ?? false;
|
|
67515
67538
|
const trustedCloneRoutingEnv = buildTrustedCloneRoutingEnv({
|
|
67516
67539
|
cloneNames: params.cloneNames,
|
|
@@ -68475,7 +68498,7 @@ function asSeedFamily(value) {
|
|
|
68475
68498
|
}
|
|
68476
68499
|
|
|
68477
68500
|
// src/runner/engine-context.ts
|
|
68478
|
-
var
|
|
68501
|
+
var import_node_path24 = require("path");
|
|
68479
68502
|
init_logger();
|
|
68480
68503
|
|
|
68481
68504
|
// src/runner/execution/agent-command.ts
|
|
@@ -68550,13 +68573,13 @@ function injectDetectedApiKey(env, key) {
|
|
|
68550
68573
|
// src/runner/harness.ts
|
|
68551
68574
|
init_src();
|
|
68552
68575
|
var import_node_fs22 = require("fs");
|
|
68553
|
-
var
|
|
68576
|
+
var import_node_path21 = require("path");
|
|
68554
68577
|
init_zod();
|
|
68555
68578
|
init_logger();
|
|
68556
68579
|
|
|
68557
68580
|
// src/runner/harness-paths.ts
|
|
68558
68581
|
var import_node_fs21 = require("fs");
|
|
68559
|
-
var
|
|
68582
|
+
var import_node_path20 = require("path");
|
|
68560
68583
|
var MANIFEST_FILE = "harness.json";
|
|
68561
68584
|
var HARNESS_ENTRY_CANDIDATES = [
|
|
68562
68585
|
"harness.ts",
|
|
@@ -68576,16 +68599,16 @@ var PROJECT_ROOT_MARKERS = [
|
|
|
68576
68599
|
];
|
|
68577
68600
|
function isProperAncestor(candidate, target) {
|
|
68578
68601
|
if (candidate === target) return false;
|
|
68579
|
-
const withSep = candidate.endsWith(
|
|
68602
|
+
const withSep = candidate.endsWith(import_node_path20.sep) ? candidate : candidate + import_node_path20.sep;
|
|
68580
68603
|
return target.startsWith(withSep);
|
|
68581
68604
|
}
|
|
68582
68605
|
function isProjectArchalHarnessFile(entryPath) {
|
|
68583
|
-
return (0,
|
|
68606
|
+
return (0, import_node_path20.basename)((0, import_node_path20.dirname)(entryPath)) === ".archal" && PROJECT_ARCHAL_HARNESS_FILENAMES.has((0, import_node_path20.basename)(entryPath).toLowerCase());
|
|
68584
68607
|
}
|
|
68585
68608
|
function resolveHarnessExecutionRootFromPath(entryPath) {
|
|
68586
|
-
const entryDir = (0,
|
|
68609
|
+
const entryDir = (0, import_node_path20.dirname)(entryPath);
|
|
68587
68610
|
if (isProjectArchalHarnessFile(entryPath)) {
|
|
68588
|
-
return (0,
|
|
68611
|
+
return (0, import_node_path20.dirname)(entryDir);
|
|
68589
68612
|
}
|
|
68590
68613
|
return entryDir;
|
|
68591
68614
|
}
|
|
@@ -68593,18 +68616,18 @@ function resolveHarnessProjectRoot(startPath, fallback, stopAt) {
|
|
|
68593
68616
|
let current2;
|
|
68594
68617
|
try {
|
|
68595
68618
|
const stats = (0, import_node_fs21.statSync)(startPath);
|
|
68596
|
-
current2 = stats.isDirectory() ? startPath : (0,
|
|
68619
|
+
current2 = stats.isDirectory() ? startPath : (0, import_node_path20.dirname)(startPath);
|
|
68597
68620
|
} catch {
|
|
68598
|
-
current2 = (0,
|
|
68621
|
+
current2 = (0, import_node_path20.dirname)(startPath);
|
|
68599
68622
|
}
|
|
68600
68623
|
const effectiveFallback = fallback ?? current2;
|
|
68601
68624
|
while (true) {
|
|
68602
68625
|
for (const marker of PROJECT_ROOT_MARKERS) {
|
|
68603
|
-
if ((0, import_node_fs21.existsSync)((0,
|
|
68626
|
+
if ((0, import_node_fs21.existsSync)((0, import_node_path20.resolve)(current2, marker))) {
|
|
68604
68627
|
return current2;
|
|
68605
68628
|
}
|
|
68606
68629
|
}
|
|
68607
|
-
const parent = (0,
|
|
68630
|
+
const parent = (0, import_node_path20.dirname)(current2);
|
|
68608
68631
|
if (parent === current2 || stopAt !== void 0 && isProperAncestor(current2, stopAt)) {
|
|
68609
68632
|
return effectiveFallback;
|
|
68610
68633
|
}
|
|
@@ -68616,12 +68639,12 @@ function normalizeHarnessDiscoveryStart(startPath) {
|
|
|
68616
68639
|
if (!trimmed) {
|
|
68617
68640
|
return void 0;
|
|
68618
68641
|
}
|
|
68619
|
-
const resolvedPath = (0,
|
|
68642
|
+
const resolvedPath = (0, import_node_path20.resolve)(trimmed);
|
|
68620
68643
|
try {
|
|
68621
68644
|
const stats = (0, import_node_fs21.statSync)(resolvedPath);
|
|
68622
|
-
return stats.isDirectory() ? resolvedPath : (0,
|
|
68645
|
+
return stats.isDirectory() ? resolvedPath : (0, import_node_path20.dirname)(resolvedPath);
|
|
68623
68646
|
} catch {
|
|
68624
|
-
return (0,
|
|
68647
|
+
return (0, import_node_path20.dirname)(resolvedPath);
|
|
68625
68648
|
}
|
|
68626
68649
|
}
|
|
68627
68650
|
function resolveHarnessReference(input) {
|
|
@@ -68629,7 +68652,7 @@ function resolveHarnessReference(input) {
|
|
|
68629
68652
|
if (!requested) {
|
|
68630
68653
|
throw new Error("Harness must be a non-empty name or path.");
|
|
68631
68654
|
}
|
|
68632
|
-
const localPath = (0,
|
|
68655
|
+
const localPath = (0, import_node_path20.resolve)(requested);
|
|
68633
68656
|
if ((0, import_node_fs21.existsSync)(localPath)) {
|
|
68634
68657
|
const stats = (0, import_node_fs21.statSync)(localPath);
|
|
68635
68658
|
const executionRoot = stats.isDirectory() ? localPath : resolveHarnessExecutionRootFromPath(localPath);
|
|
@@ -68656,12 +68679,12 @@ function discoverRepoLocalHarness(...startPaths) {
|
|
|
68656
68679
|
while (!visited.has(current2)) {
|
|
68657
68680
|
visited.add(current2);
|
|
68658
68681
|
for (const candidate of HARNESS_ENTRY_CANDIDATES) {
|
|
68659
|
-
if ((0, import_node_fs21.existsSync)((0,
|
|
68682
|
+
if ((0, import_node_fs21.existsSync)((0, import_node_path20.resolve)(current2, candidate))) {
|
|
68660
68683
|
return { harnessDir: current2 };
|
|
68661
68684
|
}
|
|
68662
68685
|
}
|
|
68663
|
-
const reachedBoundary = HARNESS_DISCOVERY_BOUNDARY_FILES.some((file2) => (0, import_node_fs21.existsSync)((0,
|
|
68664
|
-
const parent = (0,
|
|
68686
|
+
const reachedBoundary = HARNESS_DISCOVERY_BOUNDARY_FILES.some((file2) => (0, import_node_fs21.existsSync)((0, import_node_path20.resolve)(current2, file2)));
|
|
68687
|
+
const parent = (0, import_node_path20.dirname)(current2);
|
|
68665
68688
|
if (reachedBoundary || parent === current2) {
|
|
68666
68689
|
break;
|
|
68667
68690
|
}
|
|
@@ -68671,7 +68694,7 @@ function discoverRepoLocalHarness(...startPaths) {
|
|
|
68671
68694
|
return void 0;
|
|
68672
68695
|
}
|
|
68673
68696
|
function resolveHarnessLocation(harnessInput, visited = /* @__PURE__ */ new Set()) {
|
|
68674
|
-
const resolvedInput = (0,
|
|
68697
|
+
const resolvedInput = (0, import_node_path20.resolve)(harnessInput);
|
|
68675
68698
|
if (!(0, import_node_fs21.existsSync)(resolvedInput)) {
|
|
68676
68699
|
throw new Error(`Harness path not found: ${resolvedInput}`);
|
|
68677
68700
|
}
|
|
@@ -68684,26 +68707,26 @@ function resolveHarnessLocation(harnessInput, visited = /* @__PURE__ */ new Set(
|
|
|
68684
68707
|
const executionRoot = resolveHarnessExecutionRootFromPath(resolvedInput);
|
|
68685
68708
|
return {
|
|
68686
68709
|
executionRoot,
|
|
68687
|
-
manifestPath: (0,
|
|
68710
|
+
manifestPath: (0, import_node_path20.resolve)(executionRoot, MANIFEST_FILE),
|
|
68688
68711
|
entryPath: resolvedInput,
|
|
68689
68712
|
projectRoot: resolveHarnessProjectRoot(resolvedInput, executionRoot)
|
|
68690
68713
|
};
|
|
68691
68714
|
}
|
|
68692
68715
|
for (const candidate of HARNESS_ENTRY_CANDIDATES) {
|
|
68693
|
-
const candidatePath = (0,
|
|
68716
|
+
const candidatePath = (0, import_node_path20.resolve)(resolvedInput, candidate);
|
|
68694
68717
|
if (!(0, import_node_fs21.existsSync)(candidatePath)) {
|
|
68695
68718
|
continue;
|
|
68696
68719
|
}
|
|
68697
68720
|
return {
|
|
68698
68721
|
executionRoot: resolvedInput,
|
|
68699
|
-
manifestPath: (0,
|
|
68722
|
+
manifestPath: (0, import_node_path20.resolve)(resolvedInput, MANIFEST_FILE),
|
|
68700
68723
|
entryPath: candidatePath,
|
|
68701
68724
|
projectRoot: resolvedInput
|
|
68702
68725
|
};
|
|
68703
68726
|
}
|
|
68704
68727
|
return {
|
|
68705
68728
|
executionRoot: resolvedInput,
|
|
68706
|
-
manifestPath: (0,
|
|
68729
|
+
manifestPath: (0, import_node_path20.resolve)(resolvedInput, MANIFEST_FILE),
|
|
68707
68730
|
projectRoot: resolvedInput
|
|
68708
68731
|
};
|
|
68709
68732
|
}
|
|
@@ -68716,7 +68739,7 @@ var LEGACY_AGENT_ENTRY_CANDIDATES = [
|
|
|
68716
68739
|
{ file: "agent.ts", command: "npx", args: ["tsx", "agent.ts"] }
|
|
68717
68740
|
];
|
|
68718
68741
|
function readPackageJson2(harnessDir) {
|
|
68719
|
-
const packageJsonPath = (0,
|
|
68742
|
+
const packageJsonPath = (0, import_node_path21.resolve)(harnessDir, "package.json");
|
|
68720
68743
|
if (!(0, import_node_fs22.existsSync)(packageJsonPath)) {
|
|
68721
68744
|
return void 0;
|
|
68722
68745
|
}
|
|
@@ -68728,13 +68751,13 @@ function readPackageJson2(harnessDir) {
|
|
|
68728
68751
|
}
|
|
68729
68752
|
function inferPackageRunner(harnessDir, packageManager) {
|
|
68730
68753
|
const packageManagerName = packageManager?.trim().split("@")[0];
|
|
68731
|
-
if (packageManagerName === "pnpm" || (0, import_node_fs22.existsSync)((0,
|
|
68754
|
+
if (packageManagerName === "pnpm" || (0, import_node_fs22.existsSync)((0, import_node_path21.resolve)(harnessDir, "pnpm-lock.yaml"))) {
|
|
68732
68755
|
return "pnpm";
|
|
68733
68756
|
}
|
|
68734
|
-
if (packageManagerName === "yarn" || (0, import_node_fs22.existsSync)((0,
|
|
68757
|
+
if (packageManagerName === "yarn" || (0, import_node_fs22.existsSync)((0, import_node_path21.resolve)(harnessDir, "yarn.lock"))) {
|
|
68735
68758
|
return "yarn";
|
|
68736
68759
|
}
|
|
68737
|
-
if (packageManagerName === "bun" || (0, import_node_fs22.existsSync)((0,
|
|
68760
|
+
if (packageManagerName === "bun" || (0, import_node_fs22.existsSync)((0, import_node_path21.resolve)(harnessDir, "bun.lockb"))) {
|
|
68738
68761
|
return "bun";
|
|
68739
68762
|
}
|
|
68740
68763
|
return "npm";
|
|
@@ -68764,7 +68787,7 @@ function inferLocalCommandFromDirectory(harnessDir) {
|
|
|
68764
68787
|
const packageScript = inferPackageScriptCommand(harnessDir);
|
|
68765
68788
|
if (packageScript) return packageScript;
|
|
68766
68789
|
for (const candidate of LEGACY_AGENT_ENTRY_CANDIDATES) {
|
|
68767
|
-
if (!(0, import_node_fs22.existsSync)((0,
|
|
68790
|
+
if (!(0, import_node_fs22.existsSync)((0, import_node_path21.resolve)(harnessDir, candidate.file))) continue;
|
|
68768
68791
|
return {
|
|
68769
68792
|
localCommand: { command: candidate.command, args: [...candidate.args] },
|
|
68770
68793
|
source: candidate.file
|
|
@@ -68825,12 +68848,12 @@ function loadPromptContext(harnessDir, promptFiles) {
|
|
|
68825
68848
|
if (!relativePath) {
|
|
68826
68849
|
throw new Error("Harness promptFiles entries must be non-empty strings");
|
|
68827
68850
|
}
|
|
68828
|
-
if ((0,
|
|
68851
|
+
if ((0, import_node_path21.isAbsolute)(relativePath)) {
|
|
68829
68852
|
throw new Error(`Harness prompt file must be relative to the harness directory: ${relativePath}`);
|
|
68830
68853
|
}
|
|
68831
|
-
const absolutePath = (0,
|
|
68832
|
-
const relativeToHarness = (0,
|
|
68833
|
-
if (relativeToHarness.startsWith("..") || (0,
|
|
68854
|
+
const absolutePath = (0, import_node_path21.resolve)(harnessDir, relativePath);
|
|
68855
|
+
const relativeToHarness = (0, import_node_path21.relative)(harnessDir, absolutePath);
|
|
68856
|
+
if (relativeToHarness.startsWith("..") || (0, import_node_path21.isAbsolute)(relativeToHarness)) {
|
|
68834
68857
|
throw new Error(`Harness prompt file escapes the harness directory: ${relativePath}`);
|
|
68835
68858
|
}
|
|
68836
68859
|
if (!(0, import_node_fs22.existsSync)(absolutePath)) {
|
|
@@ -68838,8 +68861,8 @@ function loadPromptContext(harnessDir, promptFiles) {
|
|
|
68838
68861
|
}
|
|
68839
68862
|
const realHarnessDir = (0, import_node_fs22.realpathSync)(harnessDir);
|
|
68840
68863
|
const realPromptPath = (0, import_node_fs22.realpathSync)(absolutePath);
|
|
68841
|
-
const realRelativeToHarness = (0,
|
|
68842
|
-
if (realRelativeToHarness.startsWith("..") || (0,
|
|
68864
|
+
const realRelativeToHarness = (0, import_node_path21.relative)(realHarnessDir, realPromptPath);
|
|
68865
|
+
if (realRelativeToHarness.startsWith("..") || (0, import_node_path21.isAbsolute)(realRelativeToHarness)) {
|
|
68843
68866
|
throw new Error(`Harness prompt file resolves outside the harness directory: ${relativePath}`);
|
|
68844
68867
|
}
|
|
68845
68868
|
const content = (0, import_node_fs22.readFileSync)(absolutePath, "utf-8").trim();
|
|
@@ -68856,7 +68879,7 @@ function loadPromptContextFromMarkdownDirectory(harnessDir) {
|
|
|
68856
68879
|
if (markdownFiles.length === 0) return void 0;
|
|
68857
68880
|
const sections = [];
|
|
68858
68881
|
for (const markdownFile of markdownFiles) {
|
|
68859
|
-
const absolutePath = (0,
|
|
68882
|
+
const absolutePath = (0, import_node_path21.resolve)(harnessDir, markdownFile);
|
|
68860
68883
|
const content = (0, import_node_fs22.readFileSync)(absolutePath, "utf-8").trim();
|
|
68861
68884
|
if (!content) {
|
|
68862
68885
|
warn(`Harness markdown prompt file is empty and will be skipped: ${absolutePath}`);
|
|
@@ -68884,13 +68907,13 @@ var DIRECT_FILE_RUNNERS = {
|
|
|
68884
68907
|
".cjs": { command: "node", args: [] }
|
|
68885
68908
|
};
|
|
68886
68909
|
function inferLocalCommandFromEntryPath(spawnCwd, entryPath) {
|
|
68887
|
-
const runner = DIRECT_FILE_RUNNERS[(0,
|
|
68910
|
+
const runner = DIRECT_FILE_RUNNERS[(0, import_node_path21.extname)(entryPath).toLowerCase()];
|
|
68888
68911
|
if (!runner) {
|
|
68889
68912
|
throw new Error(
|
|
68890
68913
|
`Unsupported harness entrypoint extension for ${entryPath}. Use .ts, .js, .mjs, or .cjs.`
|
|
68891
68914
|
);
|
|
68892
68915
|
}
|
|
68893
|
-
const relativeEntryPath = (0,
|
|
68916
|
+
const relativeEntryPath = (0, import_node_path21.relative)(spawnCwd, entryPath) || entryPath;
|
|
68894
68917
|
return {
|
|
68895
68918
|
command: runner.command,
|
|
68896
68919
|
args: [...runner.args, relativeEntryPath]
|
|
@@ -69431,14 +69454,14 @@ function planApiTimeoutSeconds(plan) {
|
|
|
69431
69454
|
|
|
69432
69455
|
// src/runner/config-resolver.ts
|
|
69433
69456
|
var import_node_fs25 = require("fs");
|
|
69434
|
-
var
|
|
69457
|
+
var import_node_path23 = require("path");
|
|
69435
69458
|
init_config_merger();
|
|
69436
69459
|
init_config_loader();
|
|
69437
69460
|
|
|
69438
69461
|
// src/runner/openclaw-shared.ts
|
|
69439
69462
|
var import_node_fs24 = require("fs");
|
|
69440
69463
|
var import_node_os6 = require("os");
|
|
69441
|
-
var
|
|
69464
|
+
var import_node_path22 = require("path");
|
|
69442
69465
|
var OPENCLAW_HARNESS_ALIASES = /* @__PURE__ */ new Set(["openclaw"]);
|
|
69443
69466
|
function isOpenClawHarnessName(name) {
|
|
69444
69467
|
return OPENCLAW_HARNESS_ALIASES.has(name.trim().toLowerCase());
|
|
@@ -69447,7 +69470,7 @@ function resolveDefaultOpenClawHome(opts, homeDir = (0, import_node_os6.homedir)
|
|
|
69447
69470
|
if (opts.openclawHome?.trim() || opts.openclawWorkspace?.trim() || opts.openclawConfig?.trim()) {
|
|
69448
69471
|
return void 0;
|
|
69449
69472
|
}
|
|
69450
|
-
const defaultHome = (0,
|
|
69473
|
+
const defaultHome = (0, import_node_path22.join)(homeDir, ".openclaw");
|
|
69451
69474
|
return (0, import_node_fs24.existsSync)(defaultHome) ? defaultHome : void 0;
|
|
69452
69475
|
}
|
|
69453
69476
|
function resolveOpenClawHomePath(opts, homeDir) {
|
|
@@ -69479,7 +69502,7 @@ function isUserHarnessResolvable(value) {
|
|
|
69479
69502
|
return true;
|
|
69480
69503
|
}
|
|
69481
69504
|
try {
|
|
69482
|
-
const path2 = (0,
|
|
69505
|
+
const path2 = (0, import_node_path23.resolve)(value);
|
|
69483
69506
|
if (!(0, import_node_fs25.existsSync)(path2)) return false;
|
|
69484
69507
|
(0, import_node_fs25.statSync)(path2);
|
|
69485
69508
|
return true;
|
|
@@ -69493,13 +69516,13 @@ var DEFAULT_MODEL = "gemini-2.5-pro";
|
|
|
69493
69516
|
function findNearestProjectRoot(...startPaths) {
|
|
69494
69517
|
for (const start of startPaths) {
|
|
69495
69518
|
if (!start || !start.trim()) continue;
|
|
69496
|
-
let current2 = (0,
|
|
69519
|
+
let current2 = (0, import_node_path23.resolve)(start);
|
|
69497
69520
|
while (true) {
|
|
69498
|
-
const candidate = (0,
|
|
69521
|
+
const candidate = (0, import_node_path23.join)(current2, ".archal.json");
|
|
69499
69522
|
if ((0, import_node_fs25.existsSync)(candidate)) {
|
|
69500
69523
|
return current2;
|
|
69501
69524
|
}
|
|
69502
|
-
const parent = (0,
|
|
69525
|
+
const parent = (0, import_node_path23.dirname)(current2);
|
|
69503
69526
|
if (parent === current2) {
|
|
69504
69527
|
break;
|
|
69505
69528
|
}
|
|
@@ -69509,7 +69532,7 @@ function findNearestProjectRoot(...startPaths) {
|
|
|
69509
69532
|
return null;
|
|
69510
69533
|
}
|
|
69511
69534
|
function loadProjectConfigForScenario(scenarioPath) {
|
|
69512
|
-
const root = findNearestProjectRoot((0,
|
|
69535
|
+
const root = findNearestProjectRoot((0, import_node_path23.dirname)((0, import_node_path23.resolve)(scenarioPath)), process.cwd());
|
|
69513
69536
|
if (!root) {
|
|
69514
69537
|
return {
|
|
69515
69538
|
root: null,
|
|
@@ -69519,7 +69542,7 @@ function loadProjectConfigForScenario(scenarioPath) {
|
|
|
69519
69542
|
}
|
|
69520
69543
|
return {
|
|
69521
69544
|
root,
|
|
69522
|
-
configPath: (0,
|
|
69545
|
+
configPath: (0, import_node_path23.join)(root, ".archal.json"),
|
|
69523
69546
|
config: loadProjectConfig(root)
|
|
69524
69547
|
};
|
|
69525
69548
|
}
|
|
@@ -70240,7 +70263,7 @@ function resolveRunConfigWithSources(scenarioPath, opts, sources, preloaded) {
|
|
|
70240
70263
|
{ value: void 0, source: "unset", detail: "(not set)" }
|
|
70241
70264
|
);
|
|
70242
70265
|
return {
|
|
70243
|
-
scenarioPath: (0,
|
|
70266
|
+
scenarioPath: (0, import_node_path23.resolve)(scenarioPath),
|
|
70244
70267
|
projectRoot: project.root,
|
|
70245
70268
|
projectConfigPath: project.configPath,
|
|
70246
70269
|
invalidExplicitRuns,
|
|
@@ -70607,7 +70630,7 @@ function resolveEngineConfiguration(scenario, options, timeoutSeconds, env = cap
|
|
|
70607
70630
|
validateRemoteApiEngineTopology(apiEngine.url, scenario.config.twins, remoteTwinUrlOverrides);
|
|
70608
70631
|
}
|
|
70609
70632
|
if (localEngine) {
|
|
70610
|
-
info(`Agent harness: ${getHarnessDisplayName((0,
|
|
70633
|
+
info(`Agent harness: ${getHarnessDisplayName((0, import_node_path24.basename)(localEngine.cwd))}`, { path: localEngine.cwd });
|
|
70611
70634
|
}
|
|
70612
70635
|
if (resolvedSandbox && !apiEngine && !localEngine) {
|
|
70613
70636
|
info("OpenClaw sandbox mode enabled");
|
|
@@ -70644,7 +70667,7 @@ init_logger();
|
|
|
70644
70667
|
// ../packages/sandbox-runtime/src/docker-harness/runner.ts
|
|
70645
70668
|
var import_node_fs30 = require("fs");
|
|
70646
70669
|
var import_node_os8 = require("os");
|
|
70647
|
-
var
|
|
70670
|
+
var import_node_path27 = require("path");
|
|
70648
70671
|
init_src();
|
|
70649
70672
|
|
|
70650
70673
|
// ../packages/sandbox-runtime/src/sandbox/route-domains.ts
|
|
@@ -70832,7 +70855,7 @@ var import_node_child_process5 = require("child_process");
|
|
|
70832
70855
|
var import_node_crypto17 = require("crypto");
|
|
70833
70856
|
var import_node_fs27 = require("fs");
|
|
70834
70857
|
var import_node_os7 = require("os");
|
|
70835
|
-
var
|
|
70858
|
+
var import_node_path25 = require("path");
|
|
70836
70859
|
var import_node_url5 = require("url");
|
|
70837
70860
|
|
|
70838
70861
|
// ../packages/sandbox-runtime/src/agent-artifacts.ts
|
|
@@ -70922,27 +70945,27 @@ function formatExecError(err) {
|
|
|
70922
70945
|
return String(err);
|
|
70923
70946
|
}
|
|
70924
70947
|
function resolveLocalSandboxBuildTarget() {
|
|
70925
|
-
const runtimeDir = typeof __dirname !== "undefined" && typeof __dirname === "string" && __dirname.length > 0 ? __dirname : (0,
|
|
70948
|
+
const runtimeDir = typeof __dirname !== "undefined" && typeof __dirname === "string" && __dirname.length > 0 ? __dirname : (0, import_node_path25.dirname)((0, import_node_url5.fileURLToPath)(import_meta3.url));
|
|
70926
70949
|
const candidates = [
|
|
70927
70950
|
{
|
|
70928
|
-
dockerfile: (0,
|
|
70929
|
-
contextDir: (0,
|
|
70951
|
+
dockerfile: (0, import_node_path25.resolve)(process.cwd(), "packages/sandbox-runtime/docker/sandbox/Dockerfile"),
|
|
70952
|
+
contextDir: (0, import_node_path25.resolve)(process.cwd(), "packages/sandbox-runtime")
|
|
70930
70953
|
},
|
|
70931
70954
|
{
|
|
70932
|
-
dockerfile: (0,
|
|
70933
|
-
contextDir: (0,
|
|
70955
|
+
dockerfile: (0, import_node_path25.resolve)(process.cwd(), "cli/docker/sandbox/Dockerfile"),
|
|
70956
|
+
contextDir: (0, import_node_path25.resolve)(process.cwd(), "cli")
|
|
70934
70957
|
},
|
|
70935
70958
|
{
|
|
70936
|
-
dockerfile: (0,
|
|
70959
|
+
dockerfile: (0, import_node_path25.resolve)(process.cwd(), "docker/sandbox/Dockerfile"),
|
|
70937
70960
|
contextDir: process.cwd()
|
|
70938
70961
|
},
|
|
70939
70962
|
{
|
|
70940
|
-
dockerfile: (0,
|
|
70941
|
-
contextDir: (0,
|
|
70963
|
+
dockerfile: (0, import_node_path25.resolve)(runtimeDir, "../docker/sandbox/Dockerfile"),
|
|
70964
|
+
contextDir: (0, import_node_path25.resolve)(runtimeDir, "..")
|
|
70942
70965
|
},
|
|
70943
70966
|
{
|
|
70944
|
-
dockerfile: (0,
|
|
70945
|
-
contextDir: (0,
|
|
70967
|
+
dockerfile: (0, import_node_path25.resolve)(runtimeDir, "../../docker/sandbox/Dockerfile"),
|
|
70968
|
+
contextDir: (0, import_node_path25.resolve)(runtimeDir, "../..")
|
|
70946
70969
|
}
|
|
70947
70970
|
];
|
|
70948
70971
|
return candidates.find((candidate) => (0, import_node_fs27.existsSync)(candidate.dockerfile));
|
|
@@ -70950,23 +70973,23 @@ function resolveLocalSandboxBuildTarget() {
|
|
|
70950
70973
|
function getSandboxRuntimeDependencyPaths(target) {
|
|
70951
70974
|
const twinAuthContractPath = findWorkspaceSiblingPackage("twin-auth-contract", target);
|
|
70952
70975
|
const twinAuthContractDependencies = twinAuthContractPath ? [
|
|
70953
|
-
(0,
|
|
70954
|
-
(0,
|
|
70955
|
-
(0,
|
|
70976
|
+
(0, import_node_path25.resolve)(twinAuthContractPath, "package.json"),
|
|
70977
|
+
(0, import_node_path25.resolve)(twinAuthContractPath, "src/index.ts"),
|
|
70978
|
+
(0, import_node_path25.resolve)(twinAuthContractPath, "src/bootstrap-tokens.ts")
|
|
70956
70979
|
] : [];
|
|
70957
70980
|
return [
|
|
70958
70981
|
target.dockerfile,
|
|
70959
|
-
(0,
|
|
70960
|
-
(0,
|
|
70961
|
-
(0,
|
|
70962
|
-
(0,
|
|
70963
|
-
(0,
|
|
70964
|
-
(0,
|
|
70965
|
-
(0,
|
|
70966
|
-
(0,
|
|
70967
|
-
(0,
|
|
70968
|
-
(0,
|
|
70969
|
-
(0,
|
|
70982
|
+
(0, import_node_path25.resolve)(target.contextDir, "docker/sandbox/entrypoint.sh"),
|
|
70983
|
+
(0, import_node_path25.resolve)(target.contextDir, "docker/sandbox/package.json"),
|
|
70984
|
+
(0, import_node_path25.resolve)(target.contextDir, "docker/sandbox/route-domains.sh"),
|
|
70985
|
+
(0, import_node_path25.resolve)(target.contextDir, "docker/sandbox/AGENTS.md"),
|
|
70986
|
+
(0, import_node_path25.resolve)(target.contextDir, "docker/sandbox/TOOLS.md"),
|
|
70987
|
+
(0, import_node_path25.resolve)(target.contextDir, "src/sandbox/proxy-entry.ts"),
|
|
70988
|
+
(0, import_node_path25.resolve)(target.contextDir, "src/sandbox/llm-config.ts"),
|
|
70989
|
+
(0, import_node_path25.resolve)(target.contextDir, "src/sandbox/proxy.ts"),
|
|
70990
|
+
(0, import_node_path25.resolve)(target.contextDir, "src/sandbox/twins.ts"),
|
|
70991
|
+
(0, import_node_path25.resolve)(target.contextDir, "src/sandbox/route-domains.ts"),
|
|
70992
|
+
(0, import_node_path25.resolve)(target.contextDir, "src/sandbox/certs.ts"),
|
|
70970
70993
|
...twinAuthContractDependencies
|
|
70971
70994
|
].filter((path2) => (0, import_node_fs27.existsSync)(path2));
|
|
70972
70995
|
}
|
|
@@ -71042,14 +71065,14 @@ function shouldRebuildManagedSandboxImage(image, target) {
|
|
|
71042
71065
|
return getNewestSandboxRuntimeMtimeMs(target) > imageCreatedAtMs;
|
|
71043
71066
|
}
|
|
71044
71067
|
function findWorkspaceSiblingPackage(packageName, target) {
|
|
71045
|
-
const dockerfileDir = (0,
|
|
71068
|
+
const dockerfileDir = (0, import_node_path25.resolve)(target.dockerfile, "..");
|
|
71046
71069
|
const candidates = [
|
|
71047
|
-
(0,
|
|
71048
|
-
(0,
|
|
71049
|
-
(0,
|
|
71050
|
-
(0,
|
|
71070
|
+
(0, import_node_path25.resolve)(dockerfileDir, "..", "..", "..", packageName),
|
|
71071
|
+
(0, import_node_path25.resolve)(target.contextDir, "..", packageName),
|
|
71072
|
+
(0, import_node_path25.resolve)(target.contextDir, "packages", packageName),
|
|
71073
|
+
(0, import_node_path25.resolve)(target.contextDir, packageName)
|
|
71051
71074
|
];
|
|
71052
|
-
return candidates.find((c) => (0, import_node_fs27.existsSync)(c) && (0, import_node_fs27.existsSync)((0,
|
|
71075
|
+
return candidates.find((c) => (0, import_node_fs27.existsSync)(c) && (0, import_node_fs27.existsSync)((0, import_node_path25.resolve)(c, "package.json")));
|
|
71053
71076
|
}
|
|
71054
71077
|
function buildSandboxImage(image, target, openclawVersion) {
|
|
71055
71078
|
try {
|
|
@@ -71129,12 +71152,12 @@ async function ensureSandboxImage(image, openclawVersion) {
|
|
|
71129
71152
|
}
|
|
71130
71153
|
function launchSandbox(config2) {
|
|
71131
71154
|
const image = config2.image ?? DEFAULT_SANDBOX_IMAGE;
|
|
71132
|
-
const artifactsDir = (0, import_node_fs27.mkdtempSync)((0,
|
|
71133
|
-
const proxyEventsHostPath = (0,
|
|
71134
|
-
const twinUrlsHostPath = (0,
|
|
71135
|
-
const metricsHostPath = (0,
|
|
71136
|
-
const agentTraceHostPath = (0,
|
|
71137
|
-
const workspaceFilesHostPath = (0,
|
|
71155
|
+
const artifactsDir = (0, import_node_fs27.mkdtempSync)((0, import_node_path25.join)((0, import_node_os7.tmpdir)(), "archal-sandbox-"));
|
|
71156
|
+
const proxyEventsHostPath = (0, import_node_path25.join)(artifactsDir, "proxy-events.ndjson");
|
|
71157
|
+
const twinUrlsHostPath = (0, import_node_path25.join)(artifactsDir, "twin-urls.json");
|
|
71158
|
+
const metricsHostPath = (0, import_node_path25.join)(artifactsDir, "metrics.json");
|
|
71159
|
+
const agentTraceHostPath = (0, import_node_path25.join)(artifactsDir, "agent-trace.json");
|
|
71160
|
+
const workspaceFilesHostPath = (0, import_node_path25.join)(artifactsDir, "workspace-files.json");
|
|
71138
71161
|
const proxyEventsContainerPath = "/archal-artifacts/proxy-events.ndjson";
|
|
71139
71162
|
const twinUrlsContainerPath = "/archal-artifacts/twin-urls.json";
|
|
71140
71163
|
const metricsContainerPath = "/archal-artifacts/metrics.json";
|
|
@@ -71425,7 +71448,7 @@ var BOOTSTRAP_SERVICE_CREDENTIALS2 = buildBootstrapServiceCredentialsEnv();
|
|
|
71425
71448
|
|
|
71426
71449
|
// ../packages/sandbox-runtime/src/docker-harness/dockerfile.ts
|
|
71427
71450
|
var import_node_fs29 = require("fs");
|
|
71428
|
-
var
|
|
71451
|
+
var import_node_path26 = require("path");
|
|
71429
71452
|
var DockerfileError = class extends Error {
|
|
71430
71453
|
kind;
|
|
71431
71454
|
suggestion;
|
|
@@ -71467,7 +71490,7 @@ function readPackageJson3(path2) {
|
|
|
71467
71490
|
};
|
|
71468
71491
|
}
|
|
71469
71492
|
function hasFile(repoPath, relativePath) {
|
|
71470
|
-
return (0, import_node_fs29.existsSync)((0,
|
|
71493
|
+
return (0, import_node_fs29.existsSync)((0, import_node_path26.join)(repoPath, relativePath));
|
|
71471
71494
|
}
|
|
71472
71495
|
function quoteJsonCommand(parts) {
|
|
71473
71496
|
return `[${parts.map((part) => JSON.stringify(part)).join(", ")}]`;
|
|
@@ -71523,7 +71546,7 @@ function resolveNodeLaunchCommand(repoPath, pkg, packageManager) {
|
|
|
71523
71546
|
return void 0;
|
|
71524
71547
|
}
|
|
71525
71548
|
function maybeGenerateNodeDockerfile(repoPath) {
|
|
71526
|
-
const packageJsonPath = (0,
|
|
71549
|
+
const packageJsonPath = (0, import_node_path26.join)(repoPath, "package.json");
|
|
71527
71550
|
const pkg = readPackageJson3(packageJsonPath);
|
|
71528
71551
|
if (!pkg) return void 0;
|
|
71529
71552
|
const packageManager = detectPackageManager(pkg, repoPath);
|
|
@@ -71551,12 +71574,12 @@ function maybeGenerateNodeDockerfile(repoPath) {
|
|
|
71551
71574
|
};
|
|
71552
71575
|
}
|
|
71553
71576
|
function maybeGenerateSharedLibNodeDockerfile(repoPath) {
|
|
71554
|
-
const packageJsonPath = (0,
|
|
71577
|
+
const packageJsonPath = (0, import_node_path26.join)(repoPath, "package.json");
|
|
71555
71578
|
const pkg = readPackageJson3(packageJsonPath);
|
|
71556
71579
|
if (!pkg) return void 0;
|
|
71557
|
-
const harnessDirName = (0,
|
|
71558
|
-
const parentDir = (0,
|
|
71559
|
-
const sharedLibDir = (0,
|
|
71580
|
+
const harnessDirName = (0, import_node_path26.basename)(repoPath);
|
|
71581
|
+
const parentDir = (0, import_node_path26.dirname)(repoPath);
|
|
71582
|
+
const sharedLibDir = (0, import_node_path26.join)(parentDir, "_lib");
|
|
71560
71583
|
if (!(0, import_node_fs29.existsSync)(sharedLibDir)) return void 0;
|
|
71561
71584
|
let hasSharedLibFiles;
|
|
71562
71585
|
try {
|
|
@@ -71671,7 +71694,7 @@ function generateDockerfile(repoPath) {
|
|
|
71671
71694
|
}
|
|
71672
71695
|
function resolveExplicitDockerfile(repoPath, rawPath) {
|
|
71673
71696
|
const trimmed = rawPath.trim();
|
|
71674
|
-
const dockerfilePath = (0,
|
|
71697
|
+
const dockerfilePath = (0, import_node_path26.resolve)(repoPath, trimmed);
|
|
71675
71698
|
if (!(0, import_node_fs29.existsSync)(dockerfilePath) || !(0, import_node_fs29.statSync)(dockerfilePath).isFile()) {
|
|
71676
71699
|
throw new DockerfileError(
|
|
71677
71700
|
"invalid_path",
|
|
@@ -71682,7 +71705,7 @@ function resolveExplicitDockerfile(repoPath, rawPath) {
|
|
|
71682
71705
|
return dockerfilePath;
|
|
71683
71706
|
}
|
|
71684
71707
|
function resolveDockerfile(repoPathInput, options) {
|
|
71685
|
-
const repoPath = (0,
|
|
71708
|
+
const repoPath = (0, import_node_path26.resolve)(repoPathInput);
|
|
71686
71709
|
if (options?.explicitDockerfile?.trim()) {
|
|
71687
71710
|
const dockerfilePath = resolveExplicitDockerfile(repoPath, options.explicitDockerfile);
|
|
71688
71711
|
return {
|
|
@@ -71692,7 +71715,7 @@ function resolveDockerfile(repoPathInput, options) {
|
|
|
71692
71715
|
summary: `using explicit Dockerfile ${dockerfilePath}`
|
|
71693
71716
|
};
|
|
71694
71717
|
}
|
|
71695
|
-
const rootDockerfile = (0,
|
|
71718
|
+
const rootDockerfile = (0, import_node_path26.join)(repoPath, "Dockerfile");
|
|
71696
71719
|
if ((0, import_node_fs29.existsSync)(rootDockerfile) && (0, import_node_fs29.statSync)(rootDockerfile).isFile()) {
|
|
71697
71720
|
return {
|
|
71698
71721
|
source: "existing",
|
|
@@ -71716,7 +71739,7 @@ function resolveDockerfile(repoPathInput, options) {
|
|
|
71716
71739
|
"Pass a generatedDockerfilePath to resolveDockerfile."
|
|
71717
71740
|
);
|
|
71718
71741
|
}
|
|
71719
|
-
const generatedPath = (0,
|
|
71742
|
+
const generatedPath = (0, import_node_path26.resolve)(options.generatedDockerfilePath);
|
|
71720
71743
|
(0, import_node_fs29.writeFileSync)(generatedPath, generated.contents, "utf-8");
|
|
71721
71744
|
return {
|
|
71722
71745
|
source: "generated",
|
|
@@ -71728,36 +71751,36 @@ function resolveDockerfile(repoPathInput, options) {
|
|
|
71728
71751
|
}
|
|
71729
71752
|
|
|
71730
71753
|
// ../packages/sandbox-runtime/src/sandbox/llm-config.ts
|
|
71731
|
-
var
|
|
71732
|
-
var
|
|
71733
|
-
var
|
|
71734
|
-
var
|
|
71754
|
+
var SANDBOX_OPENAI_PLACEHOLDER_API_KEY = "sk-proj-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
71755
|
+
var SANDBOX_ANTHROPIC_PLACEHOLDER_API_KEY = "sk-ant-api03-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
71756
|
+
var SANDBOX_GOOGLE_PLACEHOLDER_API_KEY = "AIzaSyAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
71757
|
+
var SANDBOX_OPENROUTER_PLACEHOLDER_API_KEY = "sk-or-v1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
71735
71758
|
var PROVIDER_SPECS = {
|
|
71736
71759
|
anthropic: {
|
|
71737
71760
|
archalEnv: "ARCHAL_LLM_ANTHROPIC_KEY",
|
|
71738
|
-
fallbacks: [{ env: "ANTHROPIC_API_KEY", placeholder:
|
|
71761
|
+
fallbacks: [{ env: "ANTHROPIC_API_KEY", placeholder: SANDBOX_ANTHROPIC_PLACEHOLDER_API_KEY }],
|
|
71739
71762
|
defaultModel: "anthropic/claude-sonnet-4-6",
|
|
71740
|
-
authPlaceholder:
|
|
71763
|
+
authPlaceholder: SANDBOX_ANTHROPIC_PLACEHOLDER_API_KEY
|
|
71741
71764
|
},
|
|
71742
71765
|
openai: {
|
|
71743
71766
|
archalEnv: "ARCHAL_LLM_OPENAI_KEY",
|
|
71744
|
-
fallbacks: [{ env: "OPENAI_API_KEY", placeholder:
|
|
71767
|
+
fallbacks: [{ env: "OPENAI_API_KEY", placeholder: SANDBOX_OPENAI_PLACEHOLDER_API_KEY }],
|
|
71745
71768
|
defaultModel: "openai/gpt-4.1",
|
|
71746
|
-
authPlaceholder:
|
|
71769
|
+
authPlaceholder: SANDBOX_OPENAI_PLACEHOLDER_API_KEY
|
|
71747
71770
|
},
|
|
71748
71771
|
google: {
|
|
71749
71772
|
archalEnv: "ARCHAL_LLM_GOOGLE_KEY",
|
|
71750
71773
|
fallbacks: [
|
|
71751
|
-
{ env: "GOOGLE_API_KEY", placeholder:
|
|
71752
|
-
{ env: "GEMINI_API_KEY", placeholder:
|
|
71774
|
+
{ env: "GOOGLE_API_KEY", placeholder: SANDBOX_GOOGLE_PLACEHOLDER_API_KEY },
|
|
71775
|
+
{ env: "GEMINI_API_KEY", placeholder: SANDBOX_GOOGLE_PLACEHOLDER_API_KEY }
|
|
71753
71776
|
],
|
|
71754
71777
|
defaultModel: "google/gemini-2.5-flash",
|
|
71755
|
-
authPlaceholder:
|
|
71778
|
+
authPlaceholder: SANDBOX_GOOGLE_PLACEHOLDER_API_KEY
|
|
71756
71779
|
},
|
|
71757
71780
|
openrouter: {
|
|
71758
71781
|
archalEnv: "ARCHAL_LLM_OPENROUTER_KEY",
|
|
71759
|
-
fallbacks: [{ env: "OPENROUTER_API_KEY", placeholder:
|
|
71760
|
-
authPlaceholder:
|
|
71782
|
+
fallbacks: [{ env: "OPENROUTER_API_KEY", placeholder: SANDBOX_OPENROUTER_PLACEHOLDER_API_KEY }],
|
|
71783
|
+
authPlaceholder: SANDBOX_OPENROUTER_PLACEHOLDER_API_KEY
|
|
71761
71784
|
}
|
|
71762
71785
|
};
|
|
71763
71786
|
function readConfiguredKey(env, archalEnv, fallbacks) {
|
|
@@ -72002,12 +72025,12 @@ async function cleanupDockerImage(imageName) {
|
|
|
72002
72025
|
await runDockerCommand(["image", "rm", "-f", imageName], 1e4);
|
|
72003
72026
|
}
|
|
72004
72027
|
async function buildDockerHarnessImage(repoPath, dockerfilePath, timeoutMs) {
|
|
72005
|
-
const resolvedRepoPath = (0,
|
|
72028
|
+
const resolvedRepoPath = (0, import_node_path27.resolve)(repoPath);
|
|
72006
72029
|
const dockerIdSuffix = `${Date.now().toString(36)}-${process.pid}`;
|
|
72007
72030
|
const imageName = `archal/harness-${dockerIdSuffix}`;
|
|
72008
|
-
const buildDir = (0, import_node_fs30.mkdtempSync)((0,
|
|
72031
|
+
const buildDir = (0, import_node_fs30.mkdtempSync)((0, import_node_path27.join)((0, import_node_os8.tmpdir)(), "archal-harness-build-"));
|
|
72009
72032
|
try {
|
|
72010
|
-
const generatedDockerfilePath = (0,
|
|
72033
|
+
const generatedDockerfilePath = (0, import_node_path27.join)(buildDir, "Dockerfile.generated");
|
|
72011
72034
|
let dockerfile;
|
|
72012
72035
|
try {
|
|
72013
72036
|
dockerfile = resolveDockerfile(resolvedRepoPath, {
|
|
@@ -72052,24 +72075,24 @@ async function runDockerHarness(config2) {
|
|
|
72052
72075
|
"Install Docker Desktop or Docker Engine before using the Docker harness."
|
|
72053
72076
|
));
|
|
72054
72077
|
}
|
|
72055
|
-
const repoPath = (0,
|
|
72056
|
-
const runDir = (0, import_node_fs30.mkdtempSync)((0,
|
|
72057
|
-
const generatedDockerfilePath = (0,
|
|
72078
|
+
const repoPath = (0, import_node_path27.resolve)(config2.repoPath);
|
|
72079
|
+
const runDir = (0, import_node_fs30.mkdtempSync)((0, import_node_path27.join)((0, import_node_os8.tmpdir)(), "archal-harness-"));
|
|
72080
|
+
const generatedDockerfilePath = (0, import_node_path27.join)(runDir, "Dockerfile.generated");
|
|
72058
72081
|
const dockerIdSuffix = `${Date.now().toString(36)}-${process.pid}`;
|
|
72059
72082
|
const imageName = config2.prebuiltImage ?? `archal/harness-${dockerIdSuffix}`;
|
|
72060
72083
|
const containerName = `archal-harness-${dockerIdSuffix}`;
|
|
72061
72084
|
const proxyContainerName = `archal-harness-proxy-${dockerIdSuffix}`;
|
|
72062
72085
|
const networkName = `archal-harness-net-${dockerIdSuffix}`;
|
|
72063
72086
|
const proxyEgressNetworkName = `archal-harness-egress-${dockerIdSuffix}`;
|
|
72064
|
-
const mountedConfigDir = (0,
|
|
72065
|
-
const envFilePath = (0,
|
|
72066
|
-
const proxyEnvFilePath = (0,
|
|
72067
|
-
const cloneUrlsHostPath = (0,
|
|
72087
|
+
const mountedConfigDir = (0, import_node_path27.join)(runDir, "out");
|
|
72088
|
+
const envFilePath = (0, import_node_path27.join)(runDir, ".env");
|
|
72089
|
+
const proxyEnvFilePath = (0, import_node_path27.join)(runDir, ".proxy.env");
|
|
72090
|
+
const cloneUrlsHostPath = (0, import_node_path27.join)(mountedConfigDir, "clone-urls.json");
|
|
72068
72091
|
const cloneUrlsContainerPath = `${OUTPUT_DIR_IN_CONTAINER}/clone-urls.json`;
|
|
72069
|
-
const proxyCaPath = (0,
|
|
72070
|
-
const proxyEventsPath = (0,
|
|
72071
|
-
const metricsPath = (0,
|
|
72072
|
-
const agentTracePath = (0,
|
|
72092
|
+
const proxyCaPath = (0, import_node_path27.join)(mountedConfigDir, "ca.crt");
|
|
72093
|
+
const proxyEventsPath = (0, import_node_path27.join)(mountedConfigDir, "proxy-events.ndjson");
|
|
72094
|
+
const metricsPath = (0, import_node_path27.join)(mountedConfigDir, "metrics.json");
|
|
72095
|
+
const agentTracePath = (0, import_node_path27.join)(mountedConfigDir, "agent-trace.json");
|
|
72073
72096
|
const ownImage = !config2.prebuiltImage;
|
|
72074
72097
|
let cleanupDocker = false;
|
|
72075
72098
|
const cleanupHandlers = registerDockerCleanupHandlers(containerName, imageName, ownImage, {
|
|
@@ -72367,7 +72390,7 @@ function buildSupervisorMcpConfig(twinUrls, authToken) {
|
|
|
72367
72390
|
if (authToken) {
|
|
72368
72391
|
entry.headers = { Authorization: `Bearer ${authToken}` };
|
|
72369
72392
|
}
|
|
72370
|
-
mcpServers[
|
|
72393
|
+
mcpServers[twinName] = entry;
|
|
72371
72394
|
}
|
|
72372
72395
|
return mcpServers;
|
|
72373
72396
|
}
|
|
@@ -72599,18 +72622,18 @@ ${buildModelBackendHint()}` : `OpenClaw error: ${parsed.error.message}`,
|
|
|
72599
72622
|
|
|
72600
72623
|
// ../packages/sandbox-runtime/src/sandbox/sandbox-proxy.ts
|
|
72601
72624
|
var import_node_fs33 = require("fs");
|
|
72602
|
-
var
|
|
72625
|
+
var import_node_path31 = require("path");
|
|
72603
72626
|
|
|
72604
72627
|
// ../packages/sandbox-runtime/src/sandbox/local-proxy-runner.ts
|
|
72605
72628
|
var import_node_child_process7 = require("child_process");
|
|
72606
72629
|
var import_node_crypto19 = require("crypto");
|
|
72607
72630
|
var import_node_fs32 = require("fs");
|
|
72608
|
-
var
|
|
72631
|
+
var import_node_path29 = require("path");
|
|
72609
72632
|
|
|
72610
72633
|
// ../packages/sandbox-runtime/src/sandbox/certs.ts
|
|
72611
72634
|
var import_node_crypto18 = require("crypto");
|
|
72612
72635
|
var import_node_fs31 = require("fs");
|
|
72613
|
-
var
|
|
72636
|
+
var import_node_path28 = require("path");
|
|
72614
72637
|
var import_node_os9 = require("os");
|
|
72615
72638
|
var CA_COMMON_NAME = "GlobalSign Atlas R3 DV TLS CA 2025 Q4";
|
|
72616
72639
|
var CERT_VALIDITY_DAYS = 90;
|
|
@@ -72620,9 +72643,9 @@ function generateCertAuthority() {
|
|
|
72620
72643
|
});
|
|
72621
72644
|
const certPem = generateSelfSignedCert(publicKey, privateKey, CA_COMMON_NAME, true);
|
|
72622
72645
|
const keyPem = privateKey.export({ type: "pkcs8", format: "pem" });
|
|
72623
|
-
const dir = (0, import_node_fs31.mkdtempSync)((0,
|
|
72624
|
-
const certPath = (0,
|
|
72625
|
-
const keyPath = (0,
|
|
72646
|
+
const dir = (0, import_node_fs31.mkdtempSync)((0, import_node_path28.join)((0, import_node_os9.tmpdir)(), "tls-trust-store-"));
|
|
72647
|
+
const certPath = (0, import_node_path28.join)(dir, "ca.crt");
|
|
72648
|
+
const keyPath = (0, import_node_path28.join)(dir, "ca.key");
|
|
72626
72649
|
(0, import_node_fs31.writeFileSync)(certPath, certPem);
|
|
72627
72650
|
(0, import_node_fs31.writeFileSync)(keyPath, keyPem);
|
|
72628
72651
|
return { certPem, keyPem, certPath, keyPath, dir };
|
|
@@ -73043,6 +73066,7 @@ function writeEgressBlockedResponse(res) {
|
|
|
73043
73066
|
function endSocketWithEgressBlockedResponse(socket) {
|
|
73044
73067
|
endSocketWithPlainTextResponse(socket, 403, "Forbidden", EGRESS_BLOCKED_MESSAGE);
|
|
73045
73068
|
}
|
|
73069
|
+
var GITHUB_API_REQUEST_FAILED_MESSAGE = "GitHub API request failed";
|
|
73046
73070
|
function forwardToSandboxProxyProvider(clientReq, clientRes, provider, path2, keys, onIntercept, captureBodyPreview) {
|
|
73047
73071
|
const config2 = LLM_PROVIDER_DOMAINS2[provider];
|
|
73048
73072
|
const authHeaders = buildLlmAuthHeaders(provider, keys);
|
|
@@ -73469,7 +73493,7 @@ async function handleIssueList(targetUrl, owner, name, authHeaders) {
|
|
|
73469
73493
|
if (!response.ok) {
|
|
73470
73494
|
const text = await response.text().catch(() => "");
|
|
73471
73495
|
logGraphQL(`REST error: status=${response.status} body=${text.slice(0, 500)}`);
|
|
73472
|
-
return { data: {}, errors: [{ message:
|
|
73496
|
+
return { data: {}, errors: [{ message: `${GITHUB_API_REQUEST_FAILED_MESSAGE}: ${response.status}` }] };
|
|
73473
73497
|
}
|
|
73474
73498
|
const rawBody = await response.json();
|
|
73475
73499
|
const issues = Array.isArray(rawBody) ? rawBody : [];
|
|
@@ -73517,7 +73541,7 @@ async function handleIssueList(targetUrl, owner, name, authHeaders) {
|
|
|
73517
73541
|
} catch (err) {
|
|
73518
73542
|
const msg = err instanceof Error ? err.message : String(err);
|
|
73519
73543
|
logGraphQL(`Issue list fetch failed: ${msg}`);
|
|
73520
|
-
return { data: {}, errors: [{ message:
|
|
73544
|
+
return { data: {}, errors: [{ message: GITHUB_API_REQUEST_FAILED_MESSAGE }] };
|
|
73521
73545
|
}
|
|
73522
73546
|
}
|
|
73523
73547
|
async function handleIssueView(targetUrl, owner, name, number4, authHeaders) {
|
|
@@ -73528,7 +73552,7 @@ async function handleIssueView(targetUrl, owner, name, number4, authHeaders) {
|
|
|
73528
73552
|
if (!response.ok) {
|
|
73529
73553
|
const text = await response.text().catch(() => "");
|
|
73530
73554
|
logGraphQL(`REST error: status=${response.status} body=${text.slice(0, 500)}`);
|
|
73531
|
-
return { data: {}, errors: [{ message:
|
|
73555
|
+
return { data: {}, errors: [{ message: `${GITHUB_API_REQUEST_FAILED_MESSAGE}: ${response.status}` }] };
|
|
73532
73556
|
}
|
|
73533
73557
|
const issue2 = await response.json();
|
|
73534
73558
|
const formatted = formatGraphQLIssue(issue2, owner, name);
|
|
@@ -73549,7 +73573,7 @@ async function handleIssueView(targetUrl, owner, name, number4, authHeaders) {
|
|
|
73549
73573
|
} catch (err) {
|
|
73550
73574
|
const msg = err instanceof Error ? err.message : String(err);
|
|
73551
73575
|
logGraphQL(`Issue view fetch failed: ${msg}`);
|
|
73552
|
-
return { data: {}, errors: [{ message:
|
|
73576
|
+
return { data: {}, errors: [{ message: GITHUB_API_REQUEST_FAILED_MESSAGE }] };
|
|
73553
73577
|
}
|
|
73554
73578
|
}
|
|
73555
73579
|
async function handlePrList(targetUrl, owner, name, authHeaders) {
|
|
@@ -73560,7 +73584,7 @@ async function handlePrList(targetUrl, owner, name, authHeaders) {
|
|
|
73560
73584
|
if (!response.ok) {
|
|
73561
73585
|
const text = await response.text().catch(() => "");
|
|
73562
73586
|
logGraphQL(`REST error: status=${response.status} body=${text.slice(0, 500)}`);
|
|
73563
|
-
return { data: {}, errors: [{ message:
|
|
73587
|
+
return { data: {}, errors: [{ message: `${GITHUB_API_REQUEST_FAILED_MESSAGE}: ${response.status}` }] };
|
|
73564
73588
|
}
|
|
73565
73589
|
const rawBody = await response.json();
|
|
73566
73590
|
const prs = Array.isArray(rawBody) ? rawBody : [];
|
|
@@ -73623,7 +73647,7 @@ async function handlePrList(targetUrl, owner, name, authHeaders) {
|
|
|
73623
73647
|
} catch (err) {
|
|
73624
73648
|
const msg = err instanceof Error ? err.message : String(err);
|
|
73625
73649
|
logGraphQL(`PR list fetch failed: ${msg}`);
|
|
73626
|
-
return { data: {}, errors: [{ message:
|
|
73650
|
+
return { data: {}, errors: [{ message: GITHUB_API_REQUEST_FAILED_MESSAGE }] };
|
|
73627
73651
|
}
|
|
73628
73652
|
}
|
|
73629
73653
|
async function handleRepoView(targetUrl, owner, name, authHeaders) {
|
|
@@ -73634,7 +73658,7 @@ async function handleRepoView(targetUrl, owner, name, authHeaders) {
|
|
|
73634
73658
|
if (!response.ok) {
|
|
73635
73659
|
const text = await response.text().catch(() => "");
|
|
73636
73660
|
logGraphQL(`REST error: status=${response.status} body=${text.slice(0, 500)}`);
|
|
73637
|
-
return { data: {}, errors: [{ message:
|
|
73661
|
+
return { data: {}, errors: [{ message: `${GITHUB_API_REQUEST_FAILED_MESSAGE}: ${response.status}` }] };
|
|
73638
73662
|
}
|
|
73639
73663
|
const repo = await response.json();
|
|
73640
73664
|
const defaultBranch = typeof repo["default_branch"] === "string" ? repo["default_branch"] : "main";
|
|
@@ -73690,7 +73714,7 @@ async function handleRepoView(targetUrl, owner, name, authHeaders) {
|
|
|
73690
73714
|
} catch (err) {
|
|
73691
73715
|
const msg = err instanceof Error ? err.message : String(err);
|
|
73692
73716
|
logGraphQL(`Repo view fetch failed: ${msg}`);
|
|
73693
|
-
return { data: {}, errors: [{ message:
|
|
73717
|
+
return { data: {}, errors: [{ message: GITHUB_API_REQUEST_FAILED_MESSAGE }] };
|
|
73694
73718
|
}
|
|
73695
73719
|
}
|
|
73696
73720
|
function extractInlineArg(query, name) {
|
|
@@ -73823,7 +73847,7 @@ function forwardToCloudTwin(clientReq, clientRes, targetBaseUrl, path2, authHead
|
|
|
73823
73847
|
proxyReq.on("error", () => {
|
|
73824
73848
|
if (!clientRes.headersSent) {
|
|
73825
73849
|
clientRes.writeHead(502);
|
|
73826
|
-
clientRes.end(
|
|
73850
|
+
clientRes.end(SERVICE_UNAVAILABLE_MESSAGE);
|
|
73827
73851
|
}
|
|
73828
73852
|
});
|
|
73829
73853
|
clientReq.pipe(proxyReq);
|
|
@@ -74075,7 +74099,7 @@ async function runLocalProxy(config2, task, canaryFiles) {
|
|
|
74075
74099
|
if (hostsEntries) {
|
|
74076
74100
|
status("NOTE: For full interception in local mode, add these to /etc/hosts:\n" + hostsEntries);
|
|
74077
74101
|
}
|
|
74078
|
-
const workspace = config2.workspacePath ?? (0,
|
|
74102
|
+
const workspace = config2.workspacePath ?? (0, import_node_path29.join)(process.env["HOME"] ?? "/root", ".openclaw");
|
|
74079
74103
|
const noProxyHosts = "127.0.0.1,localhost,.archal.ai";
|
|
74080
74104
|
const openclawAgentName = process.env["ARCHAL_OPENCLAW_AGENT"]?.trim() || "main";
|
|
74081
74105
|
const INFRA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
@@ -74164,14 +74188,17 @@ async function runLocalProxy(config2, task, canaryFiles) {
|
|
|
74164
74188
|
SSL_CERT_FILE: ca.certPath,
|
|
74165
74189
|
REQUESTS_CA_BUNDLE: ca.certPath,
|
|
74166
74190
|
CURL_CA_BUNDLE: ca.certPath,
|
|
74167
|
-
|
|
74191
|
+
...config2.engineModel ? { AGENT_MODEL: config2.engineModel } : {},
|
|
74192
|
+
...config2.openclawEvalMode ? { AGENT_EVAL_MODE: config2.openclawEvalMode } : {},
|
|
74193
|
+
...config2.openclawEvalMode === "isolated" ? { AGENT_DISABLE_PLUGINS: "1" } : {},
|
|
74194
|
+
// Provider-shaped placeholders + routed base URLs so SDKs don't complain about missing keys.
|
|
74168
74195
|
// The proxy intercepts these requests and injects the real key.
|
|
74169
|
-
OPENAI_API_KEY:
|
|
74196
|
+
OPENAI_API_KEY: SANDBOX_OPENAI_PLACEHOLDER_API_KEY,
|
|
74170
74197
|
OPENAI_BASE_URL: `${proxyBase}/openai`,
|
|
74171
|
-
ANTHROPIC_API_KEY:
|
|
74198
|
+
ANTHROPIC_API_KEY: SANDBOX_ANTHROPIC_PLACEHOLDER_API_KEY,
|
|
74172
74199
|
ANTHROPIC_BASE_URL: `${proxyBase}/anthropic`,
|
|
74173
|
-
GOOGLE_API_KEY:
|
|
74174
|
-
OPENROUTER_API_KEY:
|
|
74200
|
+
GOOGLE_API_KEY: SANDBOX_GOOGLE_PLACEHOLDER_API_KEY,
|
|
74201
|
+
OPENROUTER_API_KEY: SANDBOX_OPENROUTER_PLACEHOLDER_API_KEY,
|
|
74175
74202
|
OPENCLAW_AGENT_SESSION_ID: `session-${(0, import_node_crypto19.randomUUID)()}`,
|
|
74176
74203
|
OPENCLAW_DISABLE_BONJOUR: "1"
|
|
74177
74204
|
};
|
|
@@ -74190,13 +74217,13 @@ async function runLocalProxy(config2, task, canaryFiles) {
|
|
|
74190
74217
|
}
|
|
74191
74218
|
}
|
|
74192
74219
|
function writeCanaryFiles(workspace, canaryFiles) {
|
|
74193
|
-
const resolvedWorkspace = (0,
|
|
74220
|
+
const resolvedWorkspace = (0, import_node_path29.resolve)(workspace);
|
|
74194
74221
|
for (const [relativePath, content] of Object.entries(canaryFiles)) {
|
|
74195
|
-
const filePath = (0,
|
|
74196
|
-
if (filePath !== resolvedWorkspace && !filePath.startsWith(resolvedWorkspace +
|
|
74222
|
+
const filePath = (0, import_node_path29.resolve)(workspace, relativePath);
|
|
74223
|
+
if (filePath !== resolvedWorkspace && !filePath.startsWith(resolvedWorkspace + import_node_path29.sep)) {
|
|
74197
74224
|
throw new Error(`Canary path escapes sandbox root: ${relativePath}`);
|
|
74198
74225
|
}
|
|
74199
|
-
(0, import_node_fs32.mkdirSync)((0,
|
|
74226
|
+
(0, import_node_fs32.mkdirSync)((0, import_node_path29.dirname)(filePath), { recursive: true });
|
|
74200
74227
|
(0, import_node_fs32.writeFileSync)(filePath, content);
|
|
74201
74228
|
}
|
|
74202
74229
|
}
|
|
@@ -74286,16 +74313,16 @@ function spawnAgent(workspace, task, env, timeoutMs, agentName) {
|
|
|
74286
74313
|
}
|
|
74287
74314
|
|
|
74288
74315
|
// ../packages/sandbox-runtime/src/sandbox/red-team-alpha.ts
|
|
74289
|
-
var
|
|
74316
|
+
var import_node_path30 = require("path");
|
|
74290
74317
|
var SANDBOX_CANARY_TAG = "openclaw-secret-exfil-alpha";
|
|
74291
74318
|
var CANARY_LEAK_ERROR_CODE = "CANARY_LEAK_DETECTED";
|
|
74292
74319
|
var CANARY_VALUE_PATTERN = /\barchal_canary_[a-z0-9._:-]+\b/gi;
|
|
74293
74320
|
var SANDBOX_FILES_BLOCK_PATTERN = /```archal-sandbox-files\s*\n([\s\S]*?)```/i;
|
|
74294
74321
|
var SNIPPET_RADIUS = 80;
|
|
74295
74322
|
function confinePath(root, relativePath) {
|
|
74296
|
-
const resolvedRoot = (0,
|
|
74297
|
-
const resolved = (0,
|
|
74298
|
-
if (resolved !== resolvedRoot && !resolved.startsWith(resolvedRoot +
|
|
74323
|
+
const resolvedRoot = (0, import_node_path30.resolve)(root);
|
|
74324
|
+
const resolved = (0, import_node_path30.resolve)(root, relativePath);
|
|
74325
|
+
if (resolved !== resolvedRoot && !resolved.startsWith(resolvedRoot + import_node_path30.sep)) {
|
|
74299
74326
|
throw new Error(`Canary path escapes sandbox root: ${relativePath}`);
|
|
74300
74327
|
}
|
|
74301
74328
|
return resolved;
|
|
@@ -74474,7 +74501,7 @@ function readOpenClawProviderKeys(homePath) {
|
|
|
74474
74501
|
if (!homePath?.trim()) {
|
|
74475
74502
|
return {};
|
|
74476
74503
|
}
|
|
74477
|
-
const authPath = (0,
|
|
74504
|
+
const authPath = (0, import_node_path31.join)(homePath, "agents", "main", "agent", "auth-profiles.json");
|
|
74478
74505
|
if (!(0, import_node_fs33.existsSync)(authPath)) {
|
|
74479
74506
|
return {};
|
|
74480
74507
|
}
|
|
@@ -74601,14 +74628,14 @@ async function runDockerSandbox(config2) {
|
|
|
74601
74628
|
...process.env["ANTHROPIC_API_KEY"] ?? mountedOpenClawProviderKeys.anthropic ? { ARCHAL_LLM_ANTHROPIC_KEY: process.env["ANTHROPIC_API_KEY"] ?? mountedOpenClawProviderKeys.anthropic } : {},
|
|
74602
74629
|
...process.env["GOOGLE_API_KEY"] ?? process.env["GEMINI_API_KEY"] ?? mountedOpenClawProviderKeys.google ? { ARCHAL_LLM_GOOGLE_KEY: process.env["GOOGLE_API_KEY"] ?? process.env["GEMINI_API_KEY"] ?? mountedOpenClawProviderKeys.google } : {},
|
|
74603
74630
|
...process.env["OPENROUTER_API_KEY"] ?? mountedOpenClawProviderKeys.openrouter ? { ARCHAL_LLM_OPENROUTER_KEY: process.env["OPENROUTER_API_KEY"] ?? mountedOpenClawProviderKeys.openrouter } : {},
|
|
74604
|
-
//
|
|
74631
|
+
// Provider-shaped placeholders so SDK/auth-profiles don't complain about missing values.
|
|
74605
74632
|
// These never reach the real provider — the proxy strips and replaces them.
|
|
74606
|
-
OPENAI_API_KEY:
|
|
74633
|
+
OPENAI_API_KEY: SANDBOX_OPENAI_PLACEHOLDER_API_KEY,
|
|
74607
74634
|
OPENAI_BASE_URL: "http://host.docker.internal:9100/openai",
|
|
74608
|
-
ANTHROPIC_API_KEY:
|
|
74635
|
+
ANTHROPIC_API_KEY: SANDBOX_ANTHROPIC_PLACEHOLDER_API_KEY,
|
|
74609
74636
|
ANTHROPIC_BASE_URL: "http://host.docker.internal:9100/anthropic",
|
|
74610
|
-
GOOGLE_API_KEY:
|
|
74611
|
-
OPENROUTER_API_KEY:
|
|
74637
|
+
GOOGLE_API_KEY: SANDBOX_GOOGLE_PLACEHOLDER_API_KEY,
|
|
74638
|
+
OPENROUTER_API_KEY: SANDBOX_OPENROUTER_PLACEHOLDER_API_KEY,
|
|
74612
74639
|
ARCHAL_BLOCK_EGRESS: "1",
|
|
74613
74640
|
...process.env["ARCHAL_ENGINE_API_KEY"] ? { ARCHAL_ENGINE_API_KEY: process.env["ARCHAL_ENGINE_API_KEY"] } : {},
|
|
74614
74641
|
...process.env["OPENCLAW_AGENT_ID"] ? { AGENT_ID: process.env["OPENCLAW_AGENT_ID"] } : {}
|
|
@@ -79031,7 +79058,7 @@ function formatCloneRoutingDiagnostic(message) {
|
|
|
79031
79058
|
const snippet = trimSnippet(redactEvidenceString(message));
|
|
79032
79059
|
const observed = snippet ? `
|
|
79033
79060
|
Observed output/log signal: ${snippet}` : "";
|
|
79034
|
-
return "Your local harness did not talk to the clone. It appears to have reached a real service endpoint and failed authentication." + observed + "\nFix: use sandbox or Docker routing when your SDK calls normal service URLs, or
|
|
79061
|
+
return "Your local harness did not talk to the clone. It appears to have reached a real service endpoint and failed authentication." + observed + "\nFix: use sandbox or Docker routing when your SDK calls normal service URLs, or read AGENT_CLONE_URLS for clone REST URLs and add AGENT_ROUTE_HEADERS to clone requests in local harness runs.";
|
|
79035
79062
|
}
|
|
79036
79063
|
function classifyLocalHarnessFailure(message) {
|
|
79037
79064
|
if (/Cannot determine intended module format|ERR_AMBIGUOUS_MODULE_SYNTAX|require is not defined|require\.resolve|top-level await are present/i.test(message)) {
|
|
@@ -79579,7 +79606,7 @@ function logProxyTraffic(count) {
|
|
|
79579
79606
|
|
|
79580
79607
|
// src/runner/lifecycle/agent-lifecycle.ts
|
|
79581
79608
|
var import_node_fs34 = require("fs");
|
|
79582
|
-
var
|
|
79609
|
+
var import_node_path32 = require("path");
|
|
79583
79610
|
var import_node_os10 = require("os");
|
|
79584
79611
|
init_src();
|
|
79585
79612
|
|
|
@@ -79746,7 +79773,7 @@ function writeAgentConfigs(runId, cloudCloneUrls, _authToken) {
|
|
|
79746
79773
|
}
|
|
79747
79774
|
}
|
|
79748
79775
|
};
|
|
79749
|
-
const mcpConfigPath = (0,
|
|
79776
|
+
const mcpConfigPath = (0, import_node_path32.join)((0, import_node_os10.tmpdir)(), `${runId}-mcp-config.json`);
|
|
79750
79777
|
const mcpTmpPath = `${mcpConfigPath}.tmp`;
|
|
79751
79778
|
(0, import_node_fs34.writeFileSync)(mcpTmpPath, JSON.stringify({ mcpServers: aggregateServer }, null, 2), { mode: 384 });
|
|
79752
79779
|
(0, import_node_fs34.chmodSync)(mcpTmpPath, 384);
|
|
@@ -81747,11 +81774,11 @@ init_logger();
|
|
|
81747
81774
|
|
|
81748
81775
|
// src/runner/file-seed-loader.ts
|
|
81749
81776
|
var import_node_fs40 = require("fs");
|
|
81750
|
-
var
|
|
81777
|
+
var import_node_path37 = require("path");
|
|
81751
81778
|
|
|
81752
81779
|
// ../packages/runtime/src/auth-lease.ts
|
|
81753
81780
|
var import_node_fs37 = require("fs");
|
|
81754
|
-
var
|
|
81781
|
+
var import_node_path34 = require("path");
|
|
81755
81782
|
init_src4();
|
|
81756
81783
|
|
|
81757
81784
|
// ../packages/runtime/src/session-provider.ts
|
|
@@ -81805,16 +81832,37 @@ var SESSION_POLL_INTERVAL_MS = 2e3;
|
|
|
81805
81832
|
var ARCHAL_WORKSPACE_HEADER2 = "x-archal-workspace";
|
|
81806
81833
|
var SESSION_RESPONSE_SCOPE_HEADER2 = "x-archal-session-response";
|
|
81807
81834
|
var CLI_SESSION_TRANSPORT_SCOPE2 = "cli-transport";
|
|
81835
|
+
var INFRASTRUCTURE_DETAIL_PATTERN = /(?:archal[-_\s]?(?:proxy|runtime|control[-_\s]?plane|service[-_\s]?gateway|openclaw[-_\s]?gateway)|control[-_\s]?plane|CLI_JWT_SECRET|CONTROL_PLANE|JWT_SECRET|ARCHAL_|runtime provider|runtime\/session|worker[-_\s]?endpoint|x[-_]?archal|service[-_\s]?gateway|service[-_\s]?runtime|provider[-_\s]?gateway|graphql[-_\s]?gateway|workflow[-_\s]?(?:runtime|harness|session)|harness[-_\s]?bootstrap|service_mcp_servers|\/service-gateway|tls intercept|sidecar|openclaw[-_\s]?gateway|credential_issuance_seed|hosted\s+clone|cloud(?:Clone|Twin)Urls|(?:clone|twin)[-_]access[-_]denied|twin[-_]not[-_]in[-_]catalog|pre[-_\s]?migration|stale[-_\s]?data)/i;
|
|
81836
|
+
function publicHostedSessionDetail(detail) {
|
|
81837
|
+
if (!detail?.trim()) {
|
|
81838
|
+
return "";
|
|
81839
|
+
}
|
|
81840
|
+
return INFRASTRUCTURE_DETAIL_PATTERN.test(detail) ? "service routing failed to prepare the requested services." : detail;
|
|
81841
|
+
}
|
|
81842
|
+
function hostedSessionRequestErrorMessage(method, path2, status, detail) {
|
|
81843
|
+
const publicDetail = publicHostedSessionDetail(detail);
|
|
81844
|
+
return `Hosted session request failed (${method} ${path2}, HTTP ${status}${publicDetail ? `: ${publicDetail}` : ""}).`;
|
|
81845
|
+
}
|
|
81808
81846
|
var HostedSessionRequestError = class extends Error {
|
|
81809
81847
|
constructor(method, path2, status, detail) {
|
|
81810
|
-
super(
|
|
81811
|
-
`Hosted session request failed (${method} ${path2}, HTTP ${status}${detail ? `: ${detail}` : ""}).`
|
|
81812
|
-
);
|
|
81848
|
+
super(hostedSessionRequestErrorMessage(method, path2, status, detail));
|
|
81813
81849
|
this.method = method;
|
|
81814
81850
|
this.path = path2;
|
|
81815
81851
|
this.status = status;
|
|
81816
|
-
this.detail = detail;
|
|
81817
81852
|
this.name = "HostedSessionRequestError";
|
|
81853
|
+
this.detail = publicHostedSessionDetail(detail);
|
|
81854
|
+
Object.defineProperty(this, "internalDetail", {
|
|
81855
|
+
value: detail,
|
|
81856
|
+
enumerable: false,
|
|
81857
|
+
configurable: false,
|
|
81858
|
+
writable: false
|
|
81859
|
+
});
|
|
81860
|
+
}
|
|
81861
|
+
detail;
|
|
81862
|
+
internalDetail;
|
|
81863
|
+
/** @internal */
|
|
81864
|
+
getInternalDetailForRetry() {
|
|
81865
|
+
return this.internalDetail;
|
|
81818
81866
|
}
|
|
81819
81867
|
};
|
|
81820
81868
|
function trimEnv(name) {
|
|
@@ -81918,7 +81966,7 @@ function isTransientHostedSessionStartError(error49) {
|
|
|
81918
81966
|
if (error49.status === 401 || error49.status === 429 || error49.status === 500 || error49.status === 502 || error49.status === 503 || error49.status === 504) {
|
|
81919
81967
|
return true;
|
|
81920
81968
|
}
|
|
81921
|
-
return detailLooksTransient(error49.
|
|
81969
|
+
return detailLooksTransient(error49.getInternalDetailForRetry());
|
|
81922
81970
|
}
|
|
81923
81971
|
if (error49 instanceof Error) {
|
|
81924
81972
|
if (error49.message.startsWith("Hosted session timed out waiting for readiness")) {
|
|
@@ -82148,7 +82196,7 @@ function adoptLatestStoredCredentials(credentials) {
|
|
|
82148
82196
|
}
|
|
82149
82197
|
async function withStoredCredentialsLock(action) {
|
|
82150
82198
|
const archalDir = getArchalDir2();
|
|
82151
|
-
const lockDirectory = (0,
|
|
82199
|
+
const lockDirectory = (0, import_node_path34.join)(archalDir, "archal-auth-validation.lock");
|
|
82152
82200
|
const deadline = Date.now() + STORED_CREDENTIALS_LOCK_TIMEOUT_MS;
|
|
82153
82201
|
await import_node_fs37.promises.mkdir(archalDir, { recursive: true });
|
|
82154
82202
|
while (true) {
|
|
@@ -82273,21 +82321,21 @@ async function createHostedAuthLease(options = {}) {
|
|
|
82273
82321
|
|
|
82274
82322
|
// ../packages/runtime/src/seed-loader.ts
|
|
82275
82323
|
var import_node_fs38 = require("fs");
|
|
82276
|
-
var
|
|
82324
|
+
var import_node_path36 = require("path");
|
|
82277
82325
|
init_src6();
|
|
82278
82326
|
|
|
82279
82327
|
// ../packages/runtime/src/temp-artifacts.ts
|
|
82280
|
-
var
|
|
82328
|
+
var import_node_path35 = require("path");
|
|
82281
82329
|
var import_node_os11 = require("os");
|
|
82282
82330
|
function normalizeSessionKey(sessionKey) {
|
|
82283
82331
|
const value = sessionKey?.trim() || "default";
|
|
82284
82332
|
return value.replace(/[^A-Za-z0-9._-]+/g, "_");
|
|
82285
82333
|
}
|
|
82286
82334
|
function getSeedLoadingMarkerPath(sessionKey) {
|
|
82287
|
-
return (0,
|
|
82335
|
+
return (0, import_node_path35.join)((0, import_node_os11.tmpdir)(), "archal-runtime-seed-markers", `${normalizeSessionKey(sessionKey)}.loading`);
|
|
82288
82336
|
}
|
|
82289
82337
|
function getSeedLoadedMarkerPath(sessionKey) {
|
|
82290
|
-
return (0,
|
|
82338
|
+
return (0, import_node_path35.join)((0, import_node_os11.tmpdir)(), "archal-runtime-seed-markers", `${normalizeSessionKey(sessionKey)}.seeded`);
|
|
82291
82339
|
}
|
|
82292
82340
|
|
|
82293
82341
|
// ../packages/runtime/src/seed-loader.ts
|
|
@@ -82300,7 +82348,7 @@ async function loadFileSeedsIntoTwins(config2, fetchTwin2, options = {}) {
|
|
|
82300
82348
|
const sessionKey = config2.sessionKey;
|
|
82301
82349
|
const loadingMarkerPath = getSeedLoadingMarkerPath(sessionKey);
|
|
82302
82350
|
const loadedMarkerPath = getSeedLoadedMarkerPath(sessionKey);
|
|
82303
|
-
const markerDir = (0,
|
|
82351
|
+
const markerDir = (0, import_node_path36.dirname)(loadedMarkerPath);
|
|
82304
82352
|
(0, import_node_fs38.mkdirSync)(markerDir, { recursive: true, mode: 448 });
|
|
82305
82353
|
while (true) {
|
|
82306
82354
|
if ((0, import_node_fs38.existsSync)(loadedMarkerPath)) {
|
|
@@ -82424,7 +82472,7 @@ var HOSTED_SEED_WARMUP_BACKOFF_MS = [1500, 2500, 3500, 5e3, 6e3, 7e3];
|
|
|
82424
82472
|
var HOSTED_SEED_WARMUP_RETRIES = 6;
|
|
82425
82473
|
var DEFAULT_WARMUP_BACKOFF_MS2 = 5e3;
|
|
82426
82474
|
function toSeedFormat(seedPath) {
|
|
82427
|
-
const extension = (0,
|
|
82475
|
+
const extension = (0, import_node_path37.extname)(seedPath).toLowerCase();
|
|
82428
82476
|
if (extension === ".json") return "json";
|
|
82429
82477
|
if (extension === ".md") return "markdown";
|
|
82430
82478
|
throw new Error(`Unsupported seed file extension for ${seedPath}. Expected .json or .md.`);
|
|
@@ -82502,7 +82550,7 @@ async function loadFileSeedsIntoHostedTwins(fileSeedPaths, cloudCloneUrls, beare
|
|
|
82502
82550
|
// src/runner/runtime-prereqs.ts
|
|
82503
82551
|
var import_node_fs41 = require("fs");
|
|
82504
82552
|
var import_node_os12 = require("os");
|
|
82505
|
-
var
|
|
82553
|
+
var import_node_path38 = require("path");
|
|
82506
82554
|
var MIN_SANDBOX_TMP_BYTES = 8 * 1024 * 1024 * 1024;
|
|
82507
82555
|
function listCommandCandidates(command) {
|
|
82508
82556
|
if (process.platform !== "win32") {
|
|
@@ -82533,11 +82581,11 @@ function isCommandAvailable(command) {
|
|
|
82533
82581
|
return false;
|
|
82534
82582
|
}
|
|
82535
82583
|
const candidates = listCommandCandidates(command);
|
|
82536
|
-
for (const segment of pathValue.split(
|
|
82584
|
+
for (const segment of pathValue.split(import_node_path38.delimiter)) {
|
|
82537
82585
|
const dir = segment.trim();
|
|
82538
82586
|
if (!dir) continue;
|
|
82539
82587
|
for (const candidate of candidates) {
|
|
82540
|
-
const fullPath = (0,
|
|
82588
|
+
const fullPath = (0, import_node_path38.join)(dir, candidate);
|
|
82541
82589
|
if (!(0, import_node_fs41.existsSync)(fullPath)) continue;
|
|
82542
82590
|
if (isExecutable2(fullPath)) {
|
|
82543
82591
|
return true;
|
|
@@ -82621,7 +82669,7 @@ init_config_loader();
|
|
|
82621
82669
|
|
|
82622
82670
|
// src/runner/auth-seeds.ts
|
|
82623
82671
|
var import_node_fs42 = require("fs");
|
|
82624
|
-
var
|
|
82672
|
+
var import_node_path39 = require("path");
|
|
82625
82673
|
init_src4();
|
|
82626
82674
|
init_auth();
|
|
82627
82675
|
init_request_metadata2();
|
|
@@ -82659,7 +82707,7 @@ async function resolveHostedScenarioPath(scenarioArg) {
|
|
|
82659
82707
|
return result.path;
|
|
82660
82708
|
}
|
|
82661
82709
|
async function resolveScenarioPath(scenarioArg) {
|
|
82662
|
-
const unresolvedPath = (0,
|
|
82710
|
+
const unresolvedPath = (0, import_node_path39.resolve)(scenarioArg);
|
|
82663
82711
|
let scenarioPath = resolveLocalScenario(scenarioArg);
|
|
82664
82712
|
if (!scenarioPath) {
|
|
82665
82713
|
const hostedScenario = await resolveHostedScenarioPath(scenarioArg);
|
|
@@ -82711,7 +82759,7 @@ async function resolveCredentialsAndEntitlements(scenarioArg, scenario, opts, _e
|
|
|
82711
82759
|
}
|
|
82712
82760
|
|
|
82713
82761
|
// src/runner/engine-plan.ts
|
|
82714
|
-
var
|
|
82762
|
+
var import_node_path40 = require("path");
|
|
82715
82763
|
init_src();
|
|
82716
82764
|
init_logger();
|
|
82717
82765
|
function selectEnvFallback(hasResolved, reader, key) {
|
|
@@ -82887,7 +82935,7 @@ function resolveHarnessAndEngine(opts, timeout, resolved, env = captureEnvSnapsh
|
|
|
82887
82935
|
}
|
|
82888
82936
|
} else {
|
|
82889
82937
|
const inferredHarness = discoverRepoLocalHarness(
|
|
82890
|
-
(0,
|
|
82938
|
+
(0, import_node_path40.dirname)(resolved?.scenarioPath ?? process.cwd()),
|
|
82891
82939
|
resolved?.projectRoot ?? "",
|
|
82892
82940
|
process.cwd()
|
|
82893
82941
|
);
|
|
@@ -83148,7 +83196,7 @@ Docs: https://archal.ai/docs/cli/config#config-file-format` : 'Set GEMINI_API_KE
|
|
|
83148
83196
|
|
|
83149
83197
|
// src/runner/managed-run-state.ts
|
|
83150
83198
|
var import_node_fs43 = require("fs");
|
|
83151
|
-
var
|
|
83199
|
+
var import_node_path41 = require("path");
|
|
83152
83200
|
function getManagedRunStatusPath(reader) {
|
|
83153
83201
|
return reader.get("ARCHAL_WEB_RUN_STATUS_PATH");
|
|
83154
83202
|
}
|
|
@@ -83168,7 +83216,7 @@ function writeManagedRunStatusAt(statusPath, patch) {
|
|
|
83168
83216
|
} catch {
|
|
83169
83217
|
}
|
|
83170
83218
|
}
|
|
83171
|
-
(0, import_node_fs43.mkdirSync)((0,
|
|
83219
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path41.dirname)(statusPath), { recursive: true });
|
|
83172
83220
|
const next = { ...existing, ...patch };
|
|
83173
83221
|
const stage = typeof next["stage"] === "string" ? next["stage"] : null;
|
|
83174
83222
|
if (stage && stage !== "failed") {
|
|
@@ -83193,7 +83241,7 @@ function createManagedRunStatusWriter(reader, statusPath = getManagedRunStatusPa
|
|
|
83193
83241
|
}
|
|
83194
83242
|
|
|
83195
83243
|
// src/runner/hosted-session-provisioning.ts
|
|
83196
|
-
var
|
|
83244
|
+
var import_node_path45 = require("path");
|
|
83197
83245
|
init_auth();
|
|
83198
83246
|
init_api_client();
|
|
83199
83247
|
|
|
@@ -83222,7 +83270,7 @@ init_logger();
|
|
|
83222
83270
|
|
|
83223
83271
|
// src/telemetry/posthog.ts
|
|
83224
83272
|
var import_node_fs45 = require("fs");
|
|
83225
|
-
var
|
|
83273
|
+
var import_node_path42 = require("path");
|
|
83226
83274
|
var import_node_crypto23 = require("crypto");
|
|
83227
83275
|
|
|
83228
83276
|
// ../node_modules/.pnpm/posthog-node@5.26.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
@@ -87143,8 +87191,8 @@ var userPlan = null;
|
|
|
87143
87191
|
var anonymousId = null;
|
|
87144
87192
|
function getAnonymousId() {
|
|
87145
87193
|
if (anonymousId) return anonymousId;
|
|
87146
|
-
const archalDir = (0,
|
|
87147
|
-
const idPath = (0,
|
|
87194
|
+
const archalDir = (0, import_node_path42.join)(process.env["HOME"] ?? process.env["USERPROFILE"] ?? ".", ".archal");
|
|
87195
|
+
const idPath = (0, import_node_path42.join)(archalDir, "anonymous-id");
|
|
87148
87196
|
try {
|
|
87149
87197
|
anonymousId = (0, import_node_fs45.readFileSync)(idPath, "utf-8").trim();
|
|
87150
87198
|
if (anonymousId) return anonymousId;
|
|
@@ -87349,15 +87397,15 @@ init_errors6();
|
|
|
87349
87397
|
// src/clone/session-store.ts
|
|
87350
87398
|
var import_node_fs46 = require("fs");
|
|
87351
87399
|
var import_node_os13 = require("os");
|
|
87352
|
-
var
|
|
87400
|
+
var import_node_path43 = require("path");
|
|
87353
87401
|
init_auth();
|
|
87354
87402
|
init_config_loader();
|
|
87355
87403
|
var SESSION_FILE_NAME = "twin-session.json";
|
|
87356
87404
|
function getSessionFilePath() {
|
|
87357
|
-
return (0,
|
|
87405
|
+
return (0, import_node_path43.join)(getArchalDir(), SESSION_FILE_NAME);
|
|
87358
87406
|
}
|
|
87359
87407
|
function getLegacySessionFilePath() {
|
|
87360
|
-
return (0,
|
|
87408
|
+
return (0, import_node_path43.join)((0, import_node_os13.homedir)(), ".archal", SESSION_FILE_NAME);
|
|
87361
87409
|
}
|
|
87362
87410
|
function toTrimmedRecord(value) {
|
|
87363
87411
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -87933,6 +87981,13 @@ Run 'archal usage' to inspect the workspace pool, or open https://www.archal.ai/
|
|
|
87933
87981
|
}
|
|
87934
87982
|
|
|
87935
87983
|
// src/runner/hosted-session/readiness.ts
|
|
87984
|
+
function isHostedSessionRequestError(error49) {
|
|
87985
|
+
return error49 instanceof HostedSessionRequestError || error49 instanceof Error && typeof error49.method === "string" && typeof error49.path === "string" && typeof error49.status === "number" && typeof error49.detail === "string";
|
|
87986
|
+
}
|
|
87987
|
+
function getHostedSessionErrorDetail(error49) {
|
|
87988
|
+
const internalDetail = typeof error49.getInternalDetailForRetry === "function" ? error49.getInternalDetailForRetry() : void 0;
|
|
87989
|
+
return internalDetail ?? error49.detail;
|
|
87990
|
+
}
|
|
87936
87991
|
async function waitForSessionReady(opts) {
|
|
87937
87992
|
if (!opts.quiet) process.stderr.write("Starting cloud session...\n");
|
|
87938
87993
|
const startedAt = Date.now();
|
|
@@ -87950,11 +88005,11 @@ async function waitForSessionReady(opts) {
|
|
|
87950
88005
|
environment.auth.stop();
|
|
87951
88006
|
}
|
|
87952
88007
|
} catch (error49) {
|
|
87953
|
-
if (error49
|
|
88008
|
+
if (isHostedSessionRequestError(error49)) {
|
|
87954
88009
|
let details;
|
|
87955
88010
|
let code;
|
|
87956
88011
|
try {
|
|
87957
|
-
const parsed = JSON.parse(error49
|
|
88012
|
+
const parsed = JSON.parse(getHostedSessionErrorDetail(error49));
|
|
87958
88013
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
87959
88014
|
details = parsed;
|
|
87960
88015
|
if (typeof parsed["code"] === "string") code = parsed["code"];
|
|
@@ -87989,7 +88044,7 @@ async function waitForSessionReady(opts) {
|
|
|
87989
88044
|
|
|
87990
88045
|
// src/runner/hosted-session/cleanup.ts
|
|
87991
88046
|
var import_node_fs48 = require("fs");
|
|
87992
|
-
var
|
|
88047
|
+
var import_node_path44 = require("path");
|
|
87993
88048
|
init_src();
|
|
87994
88049
|
init_api_client();
|
|
87995
88050
|
init_auth();
|
|
@@ -88344,7 +88399,7 @@ async function writeEvidenceFilePhase(ctx, sessionId, credentials, requestOption
|
|
|
88344
88399
|
warnCleanup("failed to build trace payload", traceErr);
|
|
88345
88400
|
}
|
|
88346
88401
|
}
|
|
88347
|
-
(0, import_node_fs48.mkdirSync)((0,
|
|
88402
|
+
(0, import_node_fs48.mkdirSync)((0, import_node_path44.dirname)(ctx.evidenceOutputPath), { recursive: true });
|
|
88348
88403
|
(0, import_node_fs48.writeFileSync)(
|
|
88349
88404
|
ctx.evidenceOutputPath,
|
|
88350
88405
|
JSON.stringify(
|
|
@@ -88692,7 +88747,7 @@ async function provisionHostedRunSession(input) {
|
|
|
88692
88747
|
}
|
|
88693
88748
|
const enginePlan = engine.plan;
|
|
88694
88749
|
if (!ctx.runFailureMessage && enginePlan.kind === "api" && !enginePlan.twinUrlsPath) {
|
|
88695
|
-
ctx.generatedTwinUrlMapPath = (0,
|
|
88750
|
+
ctx.generatedTwinUrlMapPath = (0, import_node_path45.resolve)(
|
|
88696
88751
|
`.archal-session-${ctx.backendSessionId}-engine-twin-urls.json`
|
|
88697
88752
|
);
|
|
88698
88753
|
const result = writeTempJsonMap(
|
|
@@ -88910,9 +88965,9 @@ function emitExplicitSaveTip(input) {
|
|
|
88910
88965
|
// src/runner/execute-scenario.ts
|
|
88911
88966
|
function resolveCliFileSeedPaths(seed, scenario) {
|
|
88912
88967
|
if (!seed) return void 0;
|
|
88913
|
-
const extension = (0,
|
|
88968
|
+
const extension = (0, import_node_path46.extname)(seed).toLowerCase();
|
|
88914
88969
|
if (extension !== ".json" && extension !== ".md") return void 0;
|
|
88915
|
-
const seedPath = (0,
|
|
88970
|
+
const seedPath = (0, import_node_path46.resolve)(seed);
|
|
88916
88971
|
if (!(0, import_node_fs49.existsSync)(seedPath)) return void 0;
|
|
88917
88972
|
if (scenario.config.twins.length !== 1) {
|
|
88918
88973
|
validationError(
|
|
@@ -89038,7 +89093,7 @@ async function executeRunForScenario(scenarioArg, opts, command, configDefaults,
|
|
|
89038
89093
|
userConfig: configDefaults,
|
|
89039
89094
|
projectConfig: archalFile ? {
|
|
89040
89095
|
root: archalFile.configDir,
|
|
89041
|
-
configPath: (0,
|
|
89096
|
+
configPath: (0, import_node_path46.resolve)(archalFile.configDir, ".archal.json"),
|
|
89042
89097
|
config: loadProjectConfig(archalFile.configDir)
|
|
89043
89098
|
} : void 0,
|
|
89044
89099
|
env: envSnapshot
|
|
@@ -89089,6 +89144,15 @@ async function executeRunForScenario(scenarioArg, opts, command, configDefaults,
|
|
|
89089
89144
|
if (runOpts.dockerfile && isNoDockerRequested(runOpts)) {
|
|
89090
89145
|
validationError("--dockerfile and --no-docker are mutually exclusive");
|
|
89091
89146
|
}
|
|
89147
|
+
const engine = resolveHarnessAndEngine(runOpts, timeout, resolved, envSnapshot);
|
|
89148
|
+
const enginePlan = engine.plan;
|
|
89149
|
+
emitExplicitSaveTip({ enginePlan, runOpts });
|
|
89150
|
+
const dockerHarness = isDockerHarnessPlan(enginePlan);
|
|
89151
|
+
const sandbox = isSandboxPlan(enginePlan);
|
|
89152
|
+
const agentModel = planAgentModel(enginePlan);
|
|
89153
|
+
const harnessName = planHarnessName(enginePlan);
|
|
89154
|
+
const openclawHomePath = planOpenclawHomePath(enginePlan);
|
|
89155
|
+
const openclawEvalMode = planOpenclawEvalMode(enginePlan);
|
|
89092
89156
|
let credentials = await resolveCredentialsAndEntitlements(
|
|
89093
89157
|
scenarioArg,
|
|
89094
89158
|
scenario,
|
|
@@ -89123,15 +89187,6 @@ async function executeRunForScenario(scenarioArg, opts, command, configDefaults,
|
|
|
89123
89187
|
env: envSnapshot,
|
|
89124
89188
|
requiresManagedJudge
|
|
89125
89189
|
});
|
|
89126
|
-
const engine = resolveHarnessAndEngine(runOpts, timeout, resolved, envSnapshot);
|
|
89127
|
-
const enginePlan = engine.plan;
|
|
89128
|
-
emitExplicitSaveTip({ enginePlan, runOpts });
|
|
89129
|
-
const dockerHarness = isDockerHarnessPlan(enginePlan);
|
|
89130
|
-
const sandbox = isSandboxPlan(enginePlan);
|
|
89131
|
-
const agentModel = planAgentModel(enginePlan);
|
|
89132
|
-
const harnessName = planHarnessName(enginePlan);
|
|
89133
|
-
const openclawHomePath = planOpenclawHomePath(enginePlan);
|
|
89134
|
-
const openclawEvalMode = planOpenclawEvalMode(enginePlan);
|
|
89135
89190
|
try {
|
|
89136
89191
|
const prereqOutcome = await validateLocalRuntimePrereqs({
|
|
89137
89192
|
sandbox,
|
|
@@ -89358,11 +89413,11 @@ async function executeRunForScenario(scenarioArg, opts, command, configDefaults,
|
|
|
89358
89413
|
|
|
89359
89414
|
// src/runner/command-scenarios.ts
|
|
89360
89415
|
var import_node_fs52 = require("fs");
|
|
89361
|
-
var
|
|
89416
|
+
var import_node_path49 = require("path");
|
|
89362
89417
|
|
|
89363
89418
|
// src/commands/task-scenario.ts
|
|
89364
89419
|
var import_node_fs50 = require("fs");
|
|
89365
|
-
var
|
|
89420
|
+
var import_node_path47 = require("path");
|
|
89366
89421
|
var import_node_os14 = require("os");
|
|
89367
89422
|
var import_node_crypto26 = require("crypto");
|
|
89368
89423
|
function deriveTitle(task) {
|
|
@@ -89544,10 +89599,10 @@ function generateTaskScenario(options) {
|
|
|
89544
89599
|
"tags: inline",
|
|
89545
89600
|
""
|
|
89546
89601
|
].join("\n");
|
|
89547
|
-
const dir = (0,
|
|
89602
|
+
const dir = (0, import_node_path47.join)((0, import_node_os14.tmpdir)(), "archal-task-scenarios");
|
|
89548
89603
|
(0, import_node_fs50.mkdirSync)(dir, { recursive: true });
|
|
89549
89604
|
const filename = `task-${(0, import_node_crypto26.randomUUID)()}.md`;
|
|
89550
|
-
const filepath = (0,
|
|
89605
|
+
const filepath = (0, import_node_path47.join)(dir, filename);
|
|
89551
89606
|
(0, import_node_fs50.writeFileSync)(filepath, markdown, "utf-8");
|
|
89552
89607
|
return filepath;
|
|
89553
89608
|
}
|
|
@@ -89568,15 +89623,15 @@ function resolveConfigOwnedFilePath(configDir, rawPath, label) {
|
|
|
89568
89623
|
if (!trimmed) {
|
|
89569
89624
|
validationError(`Invalid .archal.json ${label} path.`, "Use a non-empty relative path.");
|
|
89570
89625
|
}
|
|
89571
|
-
if ((0,
|
|
89626
|
+
if ((0, import_node_path49.isAbsolute)(trimmed)) {
|
|
89572
89627
|
validationError(
|
|
89573
89628
|
`Invalid .archal.json ${label} path "${rawPath}".`,
|
|
89574
89629
|
`${label} file paths in .archal.json must be relative to the config directory.`
|
|
89575
89630
|
);
|
|
89576
89631
|
}
|
|
89577
|
-
const resolvedPath = (0,
|
|
89578
|
-
const relativeToConfig = (0,
|
|
89579
|
-
if (relativeToConfig.startsWith("..") || (0,
|
|
89632
|
+
const resolvedPath = (0, import_node_path49.resolve)(configDir, trimmed);
|
|
89633
|
+
const relativeToConfig = (0, import_node_path49.relative)(configDir, resolvedPath);
|
|
89634
|
+
if (relativeToConfig.startsWith("..") || (0, import_node_path49.isAbsolute)(relativeToConfig)) {
|
|
89580
89635
|
validationError(
|
|
89581
89636
|
`Invalid .archal.json ${label} path "${rawPath}".`,
|
|
89582
89637
|
`${label} file paths in .archal.json must stay inside the config directory.`
|
|
@@ -89598,8 +89653,8 @@ function resolveConfigOwnedFilePath(configDir, rawPath, label) {
|
|
|
89598
89653
|
}
|
|
89599
89654
|
const realConfigDir = (0, import_node_fs52.realpathSync)(configDir);
|
|
89600
89655
|
const realFilePath = (0, import_node_fs52.realpathSync)(resolvedPath);
|
|
89601
|
-
const realRelativeToConfig = (0,
|
|
89602
|
-
if (realRelativeToConfig.startsWith("..") || (0,
|
|
89656
|
+
const realRelativeToConfig = (0, import_node_path49.relative)(realConfigDir, realFilePath);
|
|
89657
|
+
if (realRelativeToConfig.startsWith("..") || (0, import_node_path49.isAbsolute)(realRelativeToConfig)) {
|
|
89603
89658
|
validationError(
|
|
89604
89659
|
`Invalid .archal.json ${label} path "${rawPath}".`,
|
|
89605
89660
|
`${label} file paths in .archal.json must resolve inside the config directory.`
|
|
@@ -89650,7 +89705,7 @@ async function resolveRunCommandScenarios(scenarioArg, opts, command) {
|
|
|
89650
89705
|
generatedConfig["_comment"] = 'agentModel "none" disables the agent-side LLM check. Set this when the harness does not call an LLM (bash + curl, urllib, plain fetch). Remove or change to a model name (e.g. "claude-sonnet-4-6") if your harness calls an LLM directly.';
|
|
89651
89706
|
generatedConfig["agentModel"] = "none";
|
|
89652
89707
|
}
|
|
89653
|
-
const configPath = (0,
|
|
89708
|
+
const configPath = (0, import_node_path49.resolve)(process.cwd(), ".archal.json");
|
|
89654
89709
|
const tmpPath = `${configPath}.tmp`;
|
|
89655
89710
|
writeFileSync30(tmpPath, JSON.stringify(generatedConfig, null, 2) + "\n", "utf-8");
|
|
89656
89711
|
renameSync7(tmpPath, configPath);
|
|
@@ -89715,7 +89770,7 @@ async function resolveRunCommandScenarios(scenarioArg, opts, command) {
|
|
|
89715
89770
|
const { config: archalConfig, configDir } = archalFile;
|
|
89716
89771
|
if (scenariosToRun.length === 0 && archalConfig.scenarios && archalConfig.scenarios.length > 0) {
|
|
89717
89772
|
scenariosToRun.push(
|
|
89718
|
-
...archalConfig.scenarios.map((scenarioPath) => (0,
|
|
89773
|
+
...archalConfig.scenarios.map((scenarioPath) => (0, import_node_path49.resolve)(configDir, scenarioPath))
|
|
89719
89774
|
);
|
|
89720
89775
|
if (archalConfig.scenarios.length === 1) {
|
|
89721
89776
|
info(`Using scenario from .archal: ${archalConfig.scenarios[0]}`);
|
|
@@ -89744,7 +89799,7 @@ async function resolveRunCommandScenarios(scenarioArg, opts, command) {
|
|
|
89744
89799
|
const seedOverrides = {};
|
|
89745
89800
|
for (const [twinName, seedPath] of Object.entries(archalConfig.seeds)) {
|
|
89746
89801
|
const resolvedSeedPath = resolveConfigOwnedFilePath(configDir, seedPath, "seed");
|
|
89747
|
-
const seedExt = (0,
|
|
89802
|
+
const seedExt = (0, import_node_path49.extname)(resolvedSeedPath).toLowerCase();
|
|
89748
89803
|
if (seedExt === ".json" || seedExt === ".md") {
|
|
89749
89804
|
fileSeedPaths[twinName] = resolvedSeedPath;
|
|
89750
89805
|
} else {
|
|
@@ -89846,7 +89901,7 @@ function resolveStarterHarnessStubPath(agentConfig, cwd) {
|
|
|
89846
89901
|
return null;
|
|
89847
89902
|
}
|
|
89848
89903
|
try {
|
|
89849
|
-
const harnessPath = (0,
|
|
89904
|
+
const harnessPath = (0, import_node_path49.resolve)(agentConfig.cwd ?? cwd, harnessArg);
|
|
89850
89905
|
return isStarterHarnessStubFile(harnessPath) ? harnessPath : null;
|
|
89851
89906
|
} catch {
|
|
89852
89907
|
return null;
|
|
@@ -89858,7 +89913,7 @@ function resolveExplicitStarterHarnessStubPath(harnessPathInput, cwd) {
|
|
|
89858
89913
|
return null;
|
|
89859
89914
|
}
|
|
89860
89915
|
try {
|
|
89861
|
-
const harnessPath = (0,
|
|
89916
|
+
const harnessPath = (0, import_node_path49.resolve)(cwd, trimmed);
|
|
89862
89917
|
return isStarterHarnessStubFile(harnessPath) ? harnessPath : null;
|
|
89863
89918
|
} catch {
|
|
89864
89919
|
return null;
|
|
@@ -91088,7 +91143,7 @@ ${CYAN}${BOLD}Archal CLI${RESET} ${DIM}v${CLI_VERSION}${RESET}
|
|
|
91088
91143
|
}
|
|
91089
91144
|
|
|
91090
91145
|
// src/commands/scenario.ts
|
|
91091
|
-
var
|
|
91146
|
+
var import_node_path50 = require("path");
|
|
91092
91147
|
var import_node_fs53 = require("fs");
|
|
91093
91148
|
init_errors6();
|
|
91094
91149
|
init_auth();
|
|
@@ -91159,7 +91214,7 @@ function toLocalScenarioRows(opts) {
|
|
|
91159
91214
|
}
|
|
91160
91215
|
rows.push({
|
|
91161
91216
|
scenario: scenario.title,
|
|
91162
|
-
slug: (0,
|
|
91217
|
+
slug: (0, import_node_path50.relative)(localDir, file2).replace(/\\/gu, "/").replace(/\.md$/u, "") || (0, import_node_path50.basename)(file2, ".md"),
|
|
91163
91218
|
clones: scenario.config.twins,
|
|
91164
91219
|
description: describeLocalScenario(
|
|
91165
91220
|
scenario.prompt,
|
|
@@ -91251,7 +91306,7 @@ function parsePositiveCommandInt(value, label) {
|
|
|
91251
91306
|
return parsed;
|
|
91252
91307
|
}
|
|
91253
91308
|
function readScenarioUpload(path2, titleOverride) {
|
|
91254
|
-
const scenarioPath = (0,
|
|
91309
|
+
const scenarioPath = (0, import_node_path50.resolve)(path2);
|
|
91255
91310
|
if (!(0, import_node_fs53.existsSync)(scenarioPath)) {
|
|
91256
91311
|
throw new CliRuntimeError(`Scenario file not found: ${path2}`);
|
|
91257
91312
|
}
|
|
@@ -91278,15 +91333,15 @@ function scenarioOutputName(scenario) {
|
|
|
91278
91333
|
return `${candidate || "workspace-scenario"}.md`;
|
|
91279
91334
|
}
|
|
91280
91335
|
function writePulledScenario(scenario, opts) {
|
|
91281
|
-
const destination = (0,
|
|
91282
|
-
opts.output?.trim() || (0,
|
|
91336
|
+
const destination = (0, import_node_path50.resolve)(
|
|
91337
|
+
opts.output?.trim() || (0, import_node_path50.resolve)(DEFAULT_SCENARIOS_DIR, scenarioOutputName(scenario))
|
|
91283
91338
|
);
|
|
91284
91339
|
if ((0, import_node_fs53.existsSync)(destination) && !opts.force) {
|
|
91285
91340
|
throw new CliRuntimeError(
|
|
91286
|
-
`Scenario already exists: ${(0,
|
|
91341
|
+
`Scenario already exists: ${(0, import_node_path50.relative)(process.cwd(), destination) || destination}. Use --force to overwrite it.`
|
|
91287
91342
|
);
|
|
91288
91343
|
}
|
|
91289
|
-
(0, import_node_fs53.mkdirSync)((0,
|
|
91344
|
+
(0, import_node_fs53.mkdirSync)((0, import_node_path50.dirname)(destination), { recursive: true });
|
|
91290
91345
|
(0, import_node_fs53.writeFileSync)(destination, scenario.markdown, "utf8");
|
|
91291
91346
|
return destination;
|
|
91292
91347
|
}
|
|
@@ -91316,12 +91371,12 @@ function titleFromName(name) {
|
|
|
91316
91371
|
}
|
|
91317
91372
|
function resolveScenarioNewPath(name, outputPath) {
|
|
91318
91373
|
if (outputPath?.trim()) {
|
|
91319
|
-
return (0,
|
|
91374
|
+
return (0, import_node_path50.resolve)(outputPath.trim());
|
|
91320
91375
|
}
|
|
91321
91376
|
const archalFile = loadArchalFile();
|
|
91322
91377
|
const configured = archalFile?.config.scenarios?.find((entry) => entry.trim().length > 0);
|
|
91323
|
-
const baseDir = archalFile && configured ? (0,
|
|
91324
|
-
return (0,
|
|
91378
|
+
const baseDir = archalFile && configured ? (0, import_node_path50.resolve)(archalFile.configDir, (0, import_node_path50.dirname)(configured)) : (0, import_node_path50.resolve)(process.cwd(), DEFAULT_SCENARIOS_DIR);
|
|
91379
|
+
return (0, import_node_path50.resolve)(baseDir, `${slugifyScenarioName(name)}.md`);
|
|
91325
91380
|
}
|
|
91326
91381
|
function renderScenarioTemplate(name, clone2, seed) {
|
|
91327
91382
|
const configLines = [
|
|
@@ -91354,10 +91409,10 @@ function createScenarioFile(name, opts) {
|
|
|
91354
91409
|
const destination = resolveScenarioNewPath(name, opts.output);
|
|
91355
91410
|
if ((0, import_node_fs53.existsSync)(destination) && !opts.force) {
|
|
91356
91411
|
throw new CliRuntimeError(
|
|
91357
|
-
`Scenario already exists: ${(0,
|
|
91412
|
+
`Scenario already exists: ${(0, import_node_path50.relative)(process.cwd(), destination) || destination}. Use --force to overwrite it.`
|
|
91358
91413
|
);
|
|
91359
91414
|
}
|
|
91360
|
-
(0, import_node_fs53.mkdirSync)((0,
|
|
91415
|
+
(0, import_node_fs53.mkdirSync)((0, import_node_path50.dirname)(destination), { recursive: true });
|
|
91361
91416
|
(0, import_node_fs53.writeFileSync)(destination, renderScenarioTemplate(name, opts.clone, opts.seed), "utf8");
|
|
91362
91417
|
return destination;
|
|
91363
91418
|
}
|
|
@@ -91421,7 +91476,7 @@ async function pullWorkspaceScenario(scenarioRef, opts) {
|
|
|
91421
91476
|
const destination = writePulledScenario(scenario, opts);
|
|
91422
91477
|
emitJsonOrInfo(
|
|
91423
91478
|
{ path: destination, scenario },
|
|
91424
|
-
`Pulled ${scenario.title} to ${(0,
|
|
91479
|
+
`Pulled ${scenario.title} to ${(0, import_node_path50.relative)(process.cwd(), destination) || destination}.`,
|
|
91425
91480
|
opts.json
|
|
91426
91481
|
);
|
|
91427
91482
|
return destination;
|
|
@@ -91646,7 +91701,7 @@ function createScenarioCommand() {
|
|
|
91646
91701
|
scenario.command("new").description("Create a runnable markdown scenario scaffold").argument("<name>", "Scenario name").option("--clone <name>", "Clone to include in ## Config (default 'github')").option("--seed <name>", "Named seed to include in ## Config").option("--output <path>", "Write to a specific markdown path").option("--force", "Overwrite an existing scenario file").action(
|
|
91647
91702
|
(name, opts) => {
|
|
91648
91703
|
const destination = createScenarioFile(name, opts);
|
|
91649
|
-
const relativePath = (0,
|
|
91704
|
+
const relativePath = (0, import_node_path50.relative)(process.cwd(), destination) || destination;
|
|
91650
91705
|
info(`Created ${relativePath}`);
|
|
91651
91706
|
info(`Next: edit ${relativePath}, then run \`archal run ${relativePath}\`.`);
|
|
91652
91707
|
}
|
|
@@ -92078,13 +92133,17 @@ function toPositiveInteger2(raw, label) {
|
|
|
92078
92133
|
}
|
|
92079
92134
|
return parsed;
|
|
92080
92135
|
}
|
|
92081
|
-
function parseSeeds(raw) {
|
|
92136
|
+
function parseSeeds(raw, requestedClones = []) {
|
|
92082
92137
|
if (!raw || raw.length === 0) {
|
|
92083
92138
|
return {};
|
|
92084
92139
|
}
|
|
92085
92140
|
const seeds = {};
|
|
92086
92141
|
for (const entry of raw) {
|
|
92087
92142
|
const [twin, seedName, ...rest] = entry.split(":");
|
|
92143
|
+
if (twin && !seedName && rest.length === 0 && requestedClones.length === 1) {
|
|
92144
|
+
seeds[requestedClones[0]] = twin;
|
|
92145
|
+
continue;
|
|
92146
|
+
}
|
|
92088
92147
|
if (!twin || !seedName || rest.length > 0) {
|
|
92089
92148
|
throw new CliUsageError(`Invalid --seed value "${entry}". Use clone:seed-name.`);
|
|
92090
92149
|
}
|
|
@@ -92461,7 +92520,6 @@ init_errors6();
|
|
|
92461
92520
|
init_ansi();
|
|
92462
92521
|
function registerResetSubcommand(parent) {
|
|
92463
92522
|
parent.command("reset").argument("[clone]", "Clone to reset, or all session clones if omitted").option("--json", "Output result as JSON").description("Reset clone state to clean").action(async (clone2, opts) => {
|
|
92464
|
-
const token = requireToken();
|
|
92465
92523
|
const saved = loadSession();
|
|
92466
92524
|
if (!saved) {
|
|
92467
92525
|
if (opts.json) {
|
|
@@ -92472,15 +92530,17 @@ function registerResetSubcommand(parent) {
|
|
|
92472
92530
|
2
|
|
92473
92531
|
) + "\n"
|
|
92474
92532
|
);
|
|
92533
|
+
process.exitCode = 1;
|
|
92475
92534
|
return;
|
|
92476
92535
|
}
|
|
92477
92536
|
throw new CliRuntimeError("No active clone session.");
|
|
92478
92537
|
}
|
|
92538
|
+
const token = requireToken();
|
|
92479
92539
|
const targets = clone2 ? [clone2] : saved.twins;
|
|
92480
92540
|
const failures = [];
|
|
92481
92541
|
const successes = [];
|
|
92482
92542
|
for (const target of targets) {
|
|
92483
|
-
const cloneUrl = saved
|
|
92543
|
+
const cloneUrl = resolveTwinSeedTargetUrl(saved, target);
|
|
92484
92544
|
if (!cloneUrl) {
|
|
92485
92545
|
const msg = `no endpoint for '${target}'`;
|
|
92486
92546
|
if (!opts.json) {
|
|
@@ -92495,7 +92555,7 @@ function registerResetSubcommand(parent) {
|
|
|
92495
92555
|
`);
|
|
92496
92556
|
}
|
|
92497
92557
|
try {
|
|
92498
|
-
const { status } = await twinWorkerCall("POST", `${
|
|
92558
|
+
const { status } = await twinWorkerCall("POST", `${cloneUrl}/state/reset`, void 0, token);
|
|
92499
92559
|
if (status < 400) {
|
|
92500
92560
|
successes.push(target);
|
|
92501
92561
|
if (!opts.json) {
|
|
@@ -92528,6 +92588,7 @@ function registerResetSubcommand(parent) {
|
|
|
92528
92588
|
2
|
|
92529
92589
|
) + "\n"
|
|
92530
92590
|
);
|
|
92591
|
+
process.exitCode = 1;
|
|
92531
92592
|
} else {
|
|
92532
92593
|
process.stdout.write(
|
|
92533
92594
|
JSON.stringify(
|
|
@@ -92747,7 +92808,6 @@ async function loadSeedDescription(session, clone2, description, token) {
|
|
|
92747
92808
|
}
|
|
92748
92809
|
function registerSeedSubcommand(parent) {
|
|
92749
92810
|
parent.command("seed").argument("<clone>", "Clone to seed").argument("[seed-name]", "Named seed to apply").option("--file <path>", "Load a JSON seed file").option("--setup <description>", "Describe desired state in natural language and seed the clone from it").option("--json", "Output result as JSON").description("Load a seed into a running clone").action(async (clone2, seedName, opts) => {
|
|
92750
|
-
const token = requireToken();
|
|
92751
92811
|
const saved = loadSession();
|
|
92752
92812
|
if (!saved) {
|
|
92753
92813
|
if (opts.json) {
|
|
@@ -92758,10 +92818,12 @@ function registerSeedSubcommand(parent) {
|
|
|
92758
92818
|
2
|
|
92759
92819
|
) + "\n"
|
|
92760
92820
|
);
|
|
92821
|
+
process.exitCode = 1;
|
|
92761
92822
|
return;
|
|
92762
92823
|
}
|
|
92763
92824
|
throw new CliRuntimeError("No active clone session.");
|
|
92764
92825
|
}
|
|
92826
|
+
const token = requireToken();
|
|
92765
92827
|
if (opts.file) {
|
|
92766
92828
|
if (opts.json) {
|
|
92767
92829
|
try {
|
|
@@ -92774,6 +92836,7 @@ function registerSeedSubcommand(parent) {
|
|
|
92774
92836
|
2
|
|
92775
92837
|
) + "\n"
|
|
92776
92838
|
);
|
|
92839
|
+
process.exitCode = 1;
|
|
92777
92840
|
return;
|
|
92778
92841
|
}
|
|
92779
92842
|
process.stdout.write(
|
|
@@ -92800,6 +92863,7 @@ function registerSeedSubcommand(parent) {
|
|
|
92800
92863
|
2
|
|
92801
92864
|
) + "\n"
|
|
92802
92865
|
);
|
|
92866
|
+
process.exitCode = 1;
|
|
92803
92867
|
return;
|
|
92804
92868
|
}
|
|
92805
92869
|
process.stdout.write(
|
|
@@ -92814,7 +92878,7 @@ function registerSeedSubcommand(parent) {
|
|
|
92814
92878
|
}
|
|
92815
92879
|
return;
|
|
92816
92880
|
}
|
|
92817
|
-
const cloneUrl = saved
|
|
92881
|
+
const cloneUrl = resolveTwinSeedTargetUrl(saved, clone2);
|
|
92818
92882
|
if (!cloneUrl) {
|
|
92819
92883
|
if (opts.json) {
|
|
92820
92884
|
process.stdout.write(
|
|
@@ -92824,6 +92888,7 @@ function registerSeedSubcommand(parent) {
|
|
|
92824
92888
|
2
|
|
92825
92889
|
) + "\n"
|
|
92826
92890
|
);
|
|
92891
|
+
process.exitCode = 1;
|
|
92827
92892
|
return;
|
|
92828
92893
|
}
|
|
92829
92894
|
throw new CliRuntimeError(`No endpoint found for clone '${clone2}'.`);
|
|
@@ -92845,6 +92910,7 @@ function registerSeedSubcommand(parent) {
|
|
|
92845
92910
|
2
|
|
92846
92911
|
) + "\n"
|
|
92847
92912
|
);
|
|
92913
|
+
process.exitCode = 1;
|
|
92848
92914
|
return;
|
|
92849
92915
|
}
|
|
92850
92916
|
throw new CliRuntimeError(`Seed load failed: HTTP ${status}${detail ? ` - ${detail}` : ""}`);
|
|
@@ -93413,7 +93479,7 @@ Run 'archal clone' to see available clones.`
|
|
|
93413
93479
|
quiet
|
|
93414
93480
|
);
|
|
93415
93481
|
}
|
|
93416
|
-
const seeds = parseSeeds(opts.seed);
|
|
93482
|
+
const seeds = parseSeeds(opts.seed, requestedClones);
|
|
93417
93483
|
const ttlSeconds = opts.ttlSeconds ? toPositiveInteger2(opts.ttlSeconds, "--ttl-seconds") : void 0;
|
|
93418
93484
|
writeProgress(
|
|
93419
93485
|
`${DIM}Starting ${requestedClones.join(", ")} clones...${RESET}
|
|
@@ -96123,20 +96189,20 @@ ${BOLD}Archal Doctor${RESET} ${DIM}session ${saved.sessionId}${RESET}
|
|
|
96123
96189
|
// src/commands/init.ts
|
|
96124
96190
|
var import_node_child_process10 = require("child_process");
|
|
96125
96191
|
var import_node_fs60 = require("fs");
|
|
96126
|
-
var
|
|
96192
|
+
var import_node_path55 = require("path");
|
|
96127
96193
|
|
|
96128
96194
|
// src/skills/installer.ts
|
|
96129
96195
|
var import_node_fs58 = require("fs");
|
|
96130
|
-
var
|
|
96196
|
+
var import_node_path53 = require("path");
|
|
96131
96197
|
var import_prompts3 = __toESM(require_prompts3(), 1);
|
|
96132
96198
|
|
|
96133
96199
|
// src/skills/manifest.ts
|
|
96134
96200
|
var import_node_crypto30 = require("crypto");
|
|
96135
96201
|
var import_node_fs57 = require("fs");
|
|
96136
|
-
var
|
|
96202
|
+
var import_node_path52 = require("path");
|
|
96137
96203
|
var MANIFEST_FILE2 = ".archal-manifest.json";
|
|
96138
96204
|
function readManifest2(skillsPath) {
|
|
96139
|
-
const path2 = (0,
|
|
96205
|
+
const path2 = (0, import_node_path52.join)(skillsPath, MANIFEST_FILE2);
|
|
96140
96206
|
if (!(0, import_node_fs57.existsSync)(path2)) return null;
|
|
96141
96207
|
try {
|
|
96142
96208
|
return JSON.parse((0, import_node_fs57.readFileSync)(path2, "utf8"));
|
|
@@ -96145,7 +96211,7 @@ function readManifest2(skillsPath) {
|
|
|
96145
96211
|
}
|
|
96146
96212
|
}
|
|
96147
96213
|
function writeManifest(skillsPath, data2) {
|
|
96148
|
-
const path2 = (0,
|
|
96214
|
+
const path2 = (0, import_node_path52.join)(skillsPath, MANIFEST_FILE2);
|
|
96149
96215
|
(0, import_node_fs57.writeFileSync)(path2, `${JSON.stringify(data2, null, 2)}
|
|
96150
96216
|
`);
|
|
96151
96217
|
}
|
|
@@ -96157,7 +96223,7 @@ function checksumDir(dir) {
|
|
|
96157
96223
|
);
|
|
96158
96224
|
for (const entry of entries) {
|
|
96159
96225
|
if (entry.name === MANIFEST_FILE2) continue;
|
|
96160
|
-
const p = (0,
|
|
96226
|
+
const p = (0, import_node_path52.join)(dir, entry.name);
|
|
96161
96227
|
const nameBytes = Buffer.from(entry.name, "utf8");
|
|
96162
96228
|
if (entry.isDirectory()) {
|
|
96163
96229
|
const sub = checksumDir(p) ?? "";
|
|
@@ -96258,7 +96324,7 @@ async function runInstaller({
|
|
|
96258
96324
|
const skipped = [];
|
|
96259
96325
|
const sourceDestNames = new Set(skillDirs.map((s) => `${ARCHAL_SKILL_PREFIX}${s}`));
|
|
96260
96326
|
for (const target of selected) {
|
|
96261
|
-
const platformDir = (0,
|
|
96327
|
+
const platformDir = (0, import_node_path53.join)(cwd, target.skillsPath);
|
|
96262
96328
|
(0, import_node_fs58.mkdirSync)(platformDir, { recursive: true });
|
|
96263
96329
|
const manifest = readManifest2(platformDir);
|
|
96264
96330
|
const nextManifest = {
|
|
@@ -96267,9 +96333,9 @@ async function runInstaller({
|
|
|
96267
96333
|
skills: {}
|
|
96268
96334
|
};
|
|
96269
96335
|
for (const skill of skillDirs) {
|
|
96270
|
-
const src = (0,
|
|
96336
|
+
const src = (0, import_node_path53.join)(skillsDir, skill);
|
|
96271
96337
|
const destName = `${ARCHAL_SKILL_PREFIX}${skill}`;
|
|
96272
|
-
const dest = (0,
|
|
96338
|
+
const dest = (0, import_node_path53.join)(platformDir, destName);
|
|
96273
96339
|
const sourceChecksum = checksumDir(src);
|
|
96274
96340
|
const existingChecksum = checksumDir(dest);
|
|
96275
96341
|
const manifestEntry = manifest?.skills?.[destName];
|
|
@@ -96329,7 +96395,7 @@ async function runInstaller({
|
|
|
96329
96395
|
}
|
|
96330
96396
|
const entry = rawEntry;
|
|
96331
96397
|
if (sourceDestNames.has(destName)) continue;
|
|
96332
|
-
const dest = (0,
|
|
96398
|
+
const dest = (0, import_node_path53.join)(platformDir, destName);
|
|
96333
96399
|
if (!(0, import_node_fs58.existsSync)(dest)) continue;
|
|
96334
96400
|
const existingChecksum = checksumDir(dest);
|
|
96335
96401
|
const userEdited = existingChecksum !== entry.checksum;
|
|
@@ -96404,7 +96470,7 @@ async function resolveTargets({
|
|
|
96404
96470
|
if (requested && requested.length > 0) {
|
|
96405
96471
|
return requested.map((id) => findTarget(id)).filter((t) => Boolean(t));
|
|
96406
96472
|
}
|
|
96407
|
-
const detected = TARGETS.filter((t) => (0, import_node_fs58.existsSync)((0,
|
|
96473
|
+
const detected = TARGETS.filter((t) => (0, import_node_fs58.existsSync)((0, import_node_path53.join)(cwd, t.dir)));
|
|
96408
96474
|
if (nonInteractive || !process.stdin.isTTY) {
|
|
96409
96475
|
if (detected.length > 0) return [...detected];
|
|
96410
96476
|
const claude = findTarget("claude");
|
|
@@ -96444,7 +96510,7 @@ ${BOLD}Install Archal skills${RESET} ${DIM}(v${version4})${RESET}
|
|
|
96444
96510
|
|
|
96445
96511
|
// src/skills/vitest-wire.ts
|
|
96446
96512
|
var import_node_fs59 = require("fs");
|
|
96447
|
-
var
|
|
96513
|
+
var import_node_path54 = require("path");
|
|
96448
96514
|
function wireVitestConfig(cwd) {
|
|
96449
96515
|
const detected = detectVitestPresence(cwd);
|
|
96450
96516
|
if (!detected.hasVitest) {
|
|
@@ -96454,7 +96520,7 @@ function wireVitestConfig(cwd) {
|
|
|
96454
96520
|
if (!configPath) {
|
|
96455
96521
|
const usesTypeScript = projectUsesTypeScript(cwd);
|
|
96456
96522
|
const targetName = usesTypeScript ? "vitest.config.ts" : "vitest.config.js";
|
|
96457
|
-
const targetPath = (0,
|
|
96523
|
+
const targetPath = (0, import_node_path54.join)(cwd, targetName);
|
|
96458
96524
|
(0, import_node_fs59.writeFileSync)(targetPath, buildStarterConfig(usesTypeScript), { mode: 420 });
|
|
96459
96525
|
return { kind: "created", path: targetPath };
|
|
96460
96526
|
}
|
|
@@ -96472,7 +96538,7 @@ function wireVitestConfig(cwd) {
|
|
|
96472
96538
|
return { kind: "skipped-unsafe", path: configPath, reason: wrapped.reason };
|
|
96473
96539
|
}
|
|
96474
96540
|
function detectVitestPresence(cwd) {
|
|
96475
|
-
const pkgPath = (0,
|
|
96541
|
+
const pkgPath = (0, import_node_path54.join)(cwd, "package.json");
|
|
96476
96542
|
if (!(0, import_node_fs59.existsSync)(pkgPath)) return { hasVitest: false };
|
|
96477
96543
|
try {
|
|
96478
96544
|
const pkg = JSON.parse((0, import_node_fs59.readFileSync)(pkgPath, "utf-8"));
|
|
@@ -96492,19 +96558,19 @@ var VITEST_CONFIG_NAMES = [
|
|
|
96492
96558
|
"vitest.config.cjs"
|
|
96493
96559
|
];
|
|
96494
96560
|
function inferVitestConfigModuleFormat(configPath) {
|
|
96495
|
-
return (0,
|
|
96561
|
+
return (0, import_node_path54.basename)(configPath).endsWith(".cjs") ? "cjs" : "esm";
|
|
96496
96562
|
}
|
|
96497
96563
|
function findVitestConfig(cwd) {
|
|
96498
96564
|
for (const name of VITEST_CONFIG_NAMES) {
|
|
96499
|
-
const candidate = (0,
|
|
96565
|
+
const candidate = (0, import_node_path54.join)(cwd, name);
|
|
96500
96566
|
if ((0, import_node_fs59.existsSync)(candidate)) return candidate;
|
|
96501
96567
|
}
|
|
96502
96568
|
return null;
|
|
96503
96569
|
}
|
|
96504
96570
|
function projectUsesTypeScript(cwd) {
|
|
96505
|
-
if ((0, import_node_fs59.existsSync)((0,
|
|
96571
|
+
if ((0, import_node_fs59.existsSync)((0, import_node_path54.join)(cwd, "tsconfig.json"))) return true;
|
|
96506
96572
|
try {
|
|
96507
|
-
const pkg = JSON.parse((0, import_node_fs59.readFileSync)((0,
|
|
96573
|
+
const pkg = JSON.parse((0, import_node_fs59.readFileSync)((0, import_node_path54.join)(cwd, "package.json"), "utf-8"));
|
|
96508
96574
|
return Boolean(
|
|
96509
96575
|
pkg.dependencies?.["typescript"] || pkg.devDependencies?.["typescript"]
|
|
96510
96576
|
);
|
|
@@ -96803,14 +96869,14 @@ init_errors6();
|
|
|
96803
96869
|
function detectPackageManager2(cwd) {
|
|
96804
96870
|
const fromPackageManager = readPackageManagerField(cwd);
|
|
96805
96871
|
if (fromPackageManager) return fromPackageManager;
|
|
96806
|
-
if ((0, import_node_fs60.existsSync)((0,
|
|
96807
|
-
if ((0, import_node_fs60.existsSync)((0,
|
|
96808
|
-
if ((0, import_node_fs60.existsSync)((0,
|
|
96872
|
+
if ((0, import_node_fs60.existsSync)((0, import_node_path55.join)(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
96873
|
+
if ((0, import_node_fs60.existsSync)((0, import_node_path55.join)(cwd, "bun.lockb")) || (0, import_node_fs60.existsSync)((0, import_node_path55.join)(cwd, "bun.lock"))) return "bun";
|
|
96874
|
+
if ((0, import_node_fs60.existsSync)((0, import_node_path55.join)(cwd, "yarn.lock"))) return "yarn";
|
|
96809
96875
|
return "npm";
|
|
96810
96876
|
}
|
|
96811
96877
|
function readPackageManagerField(cwd) {
|
|
96812
96878
|
try {
|
|
96813
|
-
const pkg = JSON.parse((0, import_node_fs60.readFileSync)((0,
|
|
96879
|
+
const pkg = JSON.parse((0, import_node_fs60.readFileSync)((0, import_node_path55.join)(cwd, "package.json"), "utf8"));
|
|
96814
96880
|
const raw = typeof pkg.packageManager === "string" ? pkg.packageManager : "";
|
|
96815
96881
|
const name = raw.split("@")[0];
|
|
96816
96882
|
if (name === "pnpm" || name === "yarn" || name === "bun" || name === "npm") {
|
|
@@ -96870,9 +96936,9 @@ const ARCHAL_INIT_STUB_HARNESS = true;
|
|
|
96870
96936
|
// - If your agent uses normal SDK URLs like https://api.github.com, run it
|
|
96871
96937
|
// with Archal sandbox/Docker routing so those calls are captured by the
|
|
96872
96938
|
// clone.
|
|
96873
|
-
// - For an uncontainerized local harness,
|
|
96874
|
-
//
|
|
96875
|
-
//
|
|
96939
|
+
// - For an uncontainerized local harness, read AGENT_CLONE_URLS for clone
|
|
96940
|
+
// REST URLs and AGENT_ROUTE_HEADERS for the route auth headers to include
|
|
96941
|
+
// on those clone requests.
|
|
96876
96942
|
// See https://docs.archal.ai/guides/first-harness for the full guide.
|
|
96877
96943
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
96878
96944
|
import { dirname } from 'node:path';
|
|
@@ -96942,18 +97008,18 @@ function telemetryErrorType(error49) {
|
|
|
96942
97008
|
return message.replace(/https?:\/\/\S+/g, "[url]").replace(/\/[\w./-]+/g, "[path]").slice(0, 120);
|
|
96943
97009
|
}
|
|
96944
97010
|
function hasPackageJson(cwd) {
|
|
96945
|
-
return (0, import_node_fs60.existsSync)((0,
|
|
97011
|
+
return (0, import_node_fs60.existsSync)((0, import_node_path55.join)(cwd, "package.json"));
|
|
96946
97012
|
}
|
|
96947
97013
|
function alreadyHasArchalDep(cwd) {
|
|
96948
97014
|
try {
|
|
96949
|
-
const pkg = JSON.parse((0, import_node_fs60.readFileSync)((0,
|
|
97015
|
+
const pkg = JSON.parse((0, import_node_fs60.readFileSync)((0, import_node_path55.join)(cwd, "package.json"), "utf8"));
|
|
96950
97016
|
return Boolean(pkg.dependencies?.archal) || Boolean(pkg.devDependencies?.archal);
|
|
96951
97017
|
} catch {
|
|
96952
97018
|
return false;
|
|
96953
97019
|
}
|
|
96954
97020
|
}
|
|
96955
97021
|
function writeStarterConfigIfMissing(cwd) {
|
|
96956
|
-
const configPath = (0,
|
|
97022
|
+
const configPath = (0, import_node_path55.join)(cwd, ARCHAL_CONFIG_FILENAME);
|
|
96957
97023
|
if ((0, import_node_fs60.existsSync)(configPath)) {
|
|
96958
97024
|
process.stdout.write(`(${ARCHAL_CONFIG_FILENAME} already present, leaving it alone)
|
|
96959
97025
|
`);
|
|
@@ -96963,8 +97029,8 @@ function writeStarterConfigIfMissing(cwd) {
|
|
|
96963
97029
|
return "created";
|
|
96964
97030
|
}
|
|
96965
97031
|
function writeStarterHarnessIfMissing(cwd) {
|
|
96966
|
-
const archalDir = (0,
|
|
96967
|
-
const harnessPath = (0,
|
|
97032
|
+
const archalDir = (0, import_node_path55.join)(cwd, ARCHAL_DIR);
|
|
97033
|
+
const harnessPath = (0, import_node_path55.join)(archalDir, HARNESS_FILENAME);
|
|
96968
97034
|
if ((0, import_node_fs60.existsSync)(harnessPath)) {
|
|
96969
97035
|
process.stdout.write(
|
|
96970
97036
|
`(${ARCHAL_DIR}/${HARNESS_FILENAME} already present, leaving it alone)
|
|
@@ -96977,8 +97043,8 @@ function writeStarterHarnessIfMissing(cwd) {
|
|
|
96977
97043
|
return "created";
|
|
96978
97044
|
}
|
|
96979
97045
|
function writeStarterScenarioIfMissing(cwd) {
|
|
96980
|
-
const scenariosDir = (0,
|
|
96981
|
-
const scenarioPath = (0,
|
|
97046
|
+
const scenariosDir = (0, import_node_path55.join)(cwd, SCENARIOS_DIR);
|
|
97047
|
+
const scenarioPath = (0, import_node_path55.join)(scenariosDir, STARTER_SCENARIO_FILENAME);
|
|
96982
97048
|
if ((0, import_node_fs60.existsSync)(scenarioPath)) {
|
|
96983
97049
|
process.stdout.write(
|
|
96984
97050
|
`(${SCENARIOS_DIR}/${STARTER_SCENARIO_FILENAME} already present, leaving it alone)
|
|
@@ -96999,10 +97065,10 @@ function looksLikeSkillsDir(candidate) {
|
|
|
96999
97065
|
return false;
|
|
97000
97066
|
}
|
|
97001
97067
|
for (const name of entries) {
|
|
97002
|
-
const child = (0,
|
|
97068
|
+
const child = (0, import_node_path55.join)(candidate, name);
|
|
97003
97069
|
try {
|
|
97004
97070
|
if (!(0, import_node_fs60.statSync)(child).isDirectory()) continue;
|
|
97005
|
-
if ((0, import_node_fs60.existsSync)((0,
|
|
97071
|
+
if ((0, import_node_fs60.existsSync)((0, import_node_path55.join)(child, "SKILL.md"))) return true;
|
|
97006
97072
|
} catch {
|
|
97007
97073
|
}
|
|
97008
97074
|
}
|
|
@@ -97011,8 +97077,8 @@ function looksLikeSkillsDir(candidate) {
|
|
|
97011
97077
|
function findPnpmWorkspaceRoot(start) {
|
|
97012
97078
|
let dir = start;
|
|
97013
97079
|
for (let i = 0; i < 10; i++) {
|
|
97014
|
-
if ((0, import_node_fs60.existsSync)((0,
|
|
97015
|
-
const parent = (0,
|
|
97080
|
+
if ((0, import_node_fs60.existsSync)((0, import_node_path55.join)(dir, "pnpm-workspace.yaml"))) return dir;
|
|
97081
|
+
const parent = (0, import_node_path55.dirname)(dir);
|
|
97016
97082
|
if (parent === dir) return null;
|
|
97017
97083
|
dir = parent;
|
|
97018
97084
|
}
|
|
@@ -97021,8 +97087,8 @@ function findPnpmWorkspaceRoot(start) {
|
|
|
97021
97087
|
function findRepoRoot(start) {
|
|
97022
97088
|
let dir = start;
|
|
97023
97089
|
for (let i = 0; i < 10; i++) {
|
|
97024
|
-
if ((0, import_node_fs60.existsSync)((0,
|
|
97025
|
-
const parent = (0,
|
|
97090
|
+
if ((0, import_node_fs60.existsSync)((0, import_node_path55.join)(dir, "pnpm-workspace.yaml"))) return dir;
|
|
97091
|
+
const parent = (0, import_node_path55.dirname)(dir);
|
|
97026
97092
|
if (parent === dir) return null;
|
|
97027
97093
|
dir = parent;
|
|
97028
97094
|
}
|
|
@@ -97032,10 +97098,10 @@ function resolveSkillsDir() {
|
|
|
97032
97098
|
const here = typeof __dirname === "string" ? __dirname : process.cwd();
|
|
97033
97099
|
const repoRoot = findRepoRoot(here) ?? findRepoRoot(process.cwd());
|
|
97034
97100
|
const candidates = [
|
|
97035
|
-
(0,
|
|
97036
|
-
...repoRoot ? [(0,
|
|
97037
|
-
(0,
|
|
97038
|
-
(0,
|
|
97101
|
+
(0, import_node_path55.resolve)(here, "..", "skills"),
|
|
97102
|
+
...repoRoot ? [(0, import_node_path55.resolve)(repoRoot, "packages", "archal", "skills")] : [],
|
|
97103
|
+
(0, import_node_path55.resolve)(process.cwd(), "packages", "archal", "skills"),
|
|
97104
|
+
(0, import_node_path55.resolve)(process.cwd(), "skills")
|
|
97039
97105
|
];
|
|
97040
97106
|
for (const candidate of candidates) {
|
|
97041
97107
|
if (looksLikeSkillsDir(candidate)) return candidate;
|
|
@@ -97299,7 +97365,7 @@ init_version();
|
|
|
97299
97365
|
|
|
97300
97366
|
// src/utils/update-check.ts
|
|
97301
97367
|
var import_node_fs62 = require("fs");
|
|
97302
|
-
var
|
|
97368
|
+
var import_node_path56 = require("path");
|
|
97303
97369
|
init_config_loader();
|
|
97304
97370
|
init_version();
|
|
97305
97371
|
init_ansi();
|
|
@@ -97308,7 +97374,7 @@ var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
|
97308
97374
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
97309
97375
|
var MIN_PLAUSIBLE_CHECKED_AT_MS = 1e12;
|
|
97310
97376
|
function getCachePath() {
|
|
97311
|
-
return (0,
|
|
97377
|
+
return (0, import_node_path56.join)(ensureArchalDir(), UPDATE_CHECK_FILE);
|
|
97312
97378
|
}
|
|
97313
97379
|
function readCache() {
|
|
97314
97380
|
try {
|
|
@@ -97401,7 +97467,7 @@ async function fetchLatestVersionWithDeadline() {
|
|
|
97401
97467
|
|
|
97402
97468
|
// src/utils/skill-drift-check.ts
|
|
97403
97469
|
var import_node_fs63 = require("fs");
|
|
97404
|
-
var
|
|
97470
|
+
var import_node_path57 = require("path");
|
|
97405
97471
|
init_version();
|
|
97406
97472
|
init_ansi();
|
|
97407
97473
|
function readManifestAt(path2) {
|
|
@@ -97429,7 +97495,7 @@ function maybePrintSkillDriftBanner(cwd = process.cwd()) {
|
|
|
97429
97495
|
try {
|
|
97430
97496
|
const stale = [];
|
|
97431
97497
|
for (const target of TARGETS) {
|
|
97432
|
-
const manifestPath = (0,
|
|
97498
|
+
const manifestPath = (0, import_node_path57.join)(cwd, target.skillsPath, MANIFEST_FILE2);
|
|
97433
97499
|
if (!(0, import_node_fs63.existsSync)(manifestPath)) continue;
|
|
97434
97500
|
const manifest = readManifestAt(manifestPath);
|
|
97435
97501
|
if (!manifest?.version) continue;
|