@archal/cli 0.9.7 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +665 -473
- package/package.json +11 -12
package/dist/index.cjs
CHANGED
|
@@ -1202,7 +1202,7 @@ var require_command = __commonJS({
|
|
|
1202
1202
|
"use strict";
|
|
1203
1203
|
var EventEmitter = require("events").EventEmitter;
|
|
1204
1204
|
var childProcess = require("child_process");
|
|
1205
|
-
var
|
|
1205
|
+
var path2 = require("path");
|
|
1206
1206
|
var fs = require("fs");
|
|
1207
1207
|
var process3 = require("process");
|
|
1208
1208
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
@@ -2215,9 +2215,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2215
2215
|
let launchWithNode = false;
|
|
2216
2216
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
2217
2217
|
function findFile(baseDir, baseName) {
|
|
2218
|
-
const localBin =
|
|
2218
|
+
const localBin = path2.resolve(baseDir, baseName);
|
|
2219
2219
|
if (fs.existsSync(localBin)) return localBin;
|
|
2220
|
-
if (sourceExt.includes(
|
|
2220
|
+
if (sourceExt.includes(path2.extname(baseName))) return void 0;
|
|
2221
2221
|
const foundExt = sourceExt.find(
|
|
2222
2222
|
(ext) => fs.existsSync(`${localBin}${ext}`)
|
|
2223
2223
|
);
|
|
@@ -2235,17 +2235,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2235
2235
|
} catch {
|
|
2236
2236
|
resolvedScriptPath = this._scriptPath;
|
|
2237
2237
|
}
|
|
2238
|
-
executableDir =
|
|
2239
|
-
|
|
2238
|
+
executableDir = path2.resolve(
|
|
2239
|
+
path2.dirname(resolvedScriptPath),
|
|
2240
2240
|
executableDir
|
|
2241
2241
|
);
|
|
2242
2242
|
}
|
|
2243
2243
|
if (executableDir) {
|
|
2244
2244
|
let localFile = findFile(executableDir, executableFile);
|
|
2245
2245
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
2246
|
-
const legacyName =
|
|
2246
|
+
const legacyName = path2.basename(
|
|
2247
2247
|
this._scriptPath,
|
|
2248
|
-
|
|
2248
|
+
path2.extname(this._scriptPath)
|
|
2249
2249
|
);
|
|
2250
2250
|
if (legacyName !== this._name) {
|
|
2251
2251
|
localFile = findFile(
|
|
@@ -2256,7 +2256,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2256
2256
|
}
|
|
2257
2257
|
executableFile = localFile || executableFile;
|
|
2258
2258
|
}
|
|
2259
|
-
launchWithNode = sourceExt.includes(
|
|
2259
|
+
launchWithNode = sourceExt.includes(path2.extname(executableFile));
|
|
2260
2260
|
let proc;
|
|
2261
2261
|
if (process3.platform !== "win32") {
|
|
2262
2262
|
if (launchWithNode) {
|
|
@@ -3171,7 +3171,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3171
3171
|
* @return {Command}
|
|
3172
3172
|
*/
|
|
3173
3173
|
nameFromFilename(filename) {
|
|
3174
|
-
this._name =
|
|
3174
|
+
this._name = path2.basename(filename, path2.extname(filename));
|
|
3175
3175
|
return this;
|
|
3176
3176
|
}
|
|
3177
3177
|
/**
|
|
@@ -3185,9 +3185,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3185
3185
|
* @param {string} [path]
|
|
3186
3186
|
* @return {(string|null|Command)}
|
|
3187
3187
|
*/
|
|
3188
|
-
executableDir(
|
|
3189
|
-
if (
|
|
3190
|
-
this._executableDir =
|
|
3188
|
+
executableDir(path3) {
|
|
3189
|
+
if (path3 === void 0) return this._executableDir;
|
|
3190
|
+
this._executableDir = path3;
|
|
3191
3191
|
return this;
|
|
3192
3192
|
}
|
|
3193
3193
|
/**
|
|
@@ -4079,8 +4079,8 @@ var init_parseUtil = __esm({
|
|
|
4079
4079
|
init_errors();
|
|
4080
4080
|
init_en();
|
|
4081
4081
|
makeIssue = (params) => {
|
|
4082
|
-
const { data, path, errorMaps, issueData } = params;
|
|
4083
|
-
const fullPath = [...
|
|
4082
|
+
const { data, path: path2, errorMaps, issueData } = params;
|
|
4083
|
+
const fullPath = [...path2, ...issueData.path || []];
|
|
4084
4084
|
const fullIssue = {
|
|
4085
4085
|
...issueData,
|
|
4086
4086
|
path: fullPath
|
|
@@ -4363,11 +4363,11 @@ var init_types = __esm({
|
|
|
4363
4363
|
init_parseUtil();
|
|
4364
4364
|
init_util();
|
|
4365
4365
|
ParseInputLazyPath = class {
|
|
4366
|
-
constructor(parent, value,
|
|
4366
|
+
constructor(parent, value, path2, key) {
|
|
4367
4367
|
this._cachedPath = [];
|
|
4368
4368
|
this.parent = parent;
|
|
4369
4369
|
this.data = value;
|
|
4370
|
-
this._path =
|
|
4370
|
+
this._path = path2;
|
|
4371
4371
|
this._key = key;
|
|
4372
4372
|
}
|
|
4373
4373
|
get path() {
|
|
@@ -7875,10 +7875,10 @@ function mergeDefs(...defs) {
|
|
|
7875
7875
|
function cloneDef(schema) {
|
|
7876
7876
|
return mergeDefs(schema._zod.def);
|
|
7877
7877
|
}
|
|
7878
|
-
function getElementAtPath(obj,
|
|
7879
|
-
if (!
|
|
7878
|
+
function getElementAtPath(obj, path2) {
|
|
7879
|
+
if (!path2)
|
|
7880
7880
|
return obj;
|
|
7881
|
-
return
|
|
7881
|
+
return path2.reduce((acc, key) => acc?.[key], obj);
|
|
7882
7882
|
}
|
|
7883
7883
|
function promiseAllObject(promisesObj) {
|
|
7884
7884
|
const keys = Object.keys(promisesObj);
|
|
@@ -8190,11 +8190,11 @@ function aborted(x, startIndex = 0) {
|
|
|
8190
8190
|
}
|
|
8191
8191
|
return false;
|
|
8192
8192
|
}
|
|
8193
|
-
function prefixIssues(
|
|
8193
|
+
function prefixIssues(path2, issues) {
|
|
8194
8194
|
return issues.map((iss) => {
|
|
8195
8195
|
var _a2;
|
|
8196
8196
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
8197
|
-
iss.path.unshift(
|
|
8197
|
+
iss.path.unshift(path2);
|
|
8198
8198
|
return iss;
|
|
8199
8199
|
});
|
|
8200
8200
|
}
|
|
@@ -8437,7 +8437,7 @@ function formatError(error49, mapper = (issue2) => issue2.message) {
|
|
|
8437
8437
|
}
|
|
8438
8438
|
function treeifyError(error49, mapper = (issue2) => issue2.message) {
|
|
8439
8439
|
const result = { errors: [] };
|
|
8440
|
-
const processError = (error50,
|
|
8440
|
+
const processError = (error50, path2 = []) => {
|
|
8441
8441
|
var _a2, _b;
|
|
8442
8442
|
for (const issue2 of error50.issues) {
|
|
8443
8443
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -8447,7 +8447,7 @@ function treeifyError(error49, mapper = (issue2) => issue2.message) {
|
|
|
8447
8447
|
} else if (issue2.code === "invalid_element") {
|
|
8448
8448
|
processError({ issues: issue2.issues }, issue2.path);
|
|
8449
8449
|
} else {
|
|
8450
|
-
const fullpath = [...
|
|
8450
|
+
const fullpath = [...path2, ...issue2.path];
|
|
8451
8451
|
if (fullpath.length === 0) {
|
|
8452
8452
|
result.errors.push(mapper(issue2));
|
|
8453
8453
|
continue;
|
|
@@ -8479,8 +8479,8 @@ function treeifyError(error49, mapper = (issue2) => issue2.message) {
|
|
|
8479
8479
|
}
|
|
8480
8480
|
function toDotPath(_path) {
|
|
8481
8481
|
const segs = [];
|
|
8482
|
-
const
|
|
8483
|
-
for (const seg of
|
|
8482
|
+
const path2 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
8483
|
+
for (const seg of path2) {
|
|
8484
8484
|
if (typeof seg === "number")
|
|
8485
8485
|
segs.push(`[${seg}]`);
|
|
8486
8486
|
else if (typeof seg === "symbol")
|
|
@@ -21323,13 +21323,13 @@ function resolveRef(ref, ctx) {
|
|
|
21323
21323
|
if (!ref.startsWith("#")) {
|
|
21324
21324
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
21325
21325
|
}
|
|
21326
|
-
const
|
|
21327
|
-
if (
|
|
21326
|
+
const path2 = ref.slice(1).split("/").filter(Boolean);
|
|
21327
|
+
if (path2.length === 0) {
|
|
21328
21328
|
return ctx.rootSchema;
|
|
21329
21329
|
}
|
|
21330
21330
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
21331
|
-
if (
|
|
21332
|
-
const key =
|
|
21331
|
+
if (path2[0] === defsKey) {
|
|
21332
|
+
const key = path2[1];
|
|
21333
21333
|
if (!key || !ctx.defs[key]) {
|
|
21334
21334
|
throw new Error(`Reference not found: ${ref}`);
|
|
21335
21335
|
}
|
|
@@ -27200,8 +27200,8 @@ var require_utils = __commonJS({
|
|
|
27200
27200
|
}
|
|
27201
27201
|
return ind;
|
|
27202
27202
|
}
|
|
27203
|
-
function removeDotSegments(
|
|
27204
|
-
let input =
|
|
27203
|
+
function removeDotSegments(path2) {
|
|
27204
|
+
let input = path2;
|
|
27205
27205
|
const output = [];
|
|
27206
27206
|
let nextSlash = -1;
|
|
27207
27207
|
let len = 0;
|
|
@@ -27400,8 +27400,8 @@ var require_schemes = __commonJS({
|
|
|
27400
27400
|
wsComponent.secure = void 0;
|
|
27401
27401
|
}
|
|
27402
27402
|
if (wsComponent.resourceName) {
|
|
27403
|
-
const [
|
|
27404
|
-
wsComponent.path =
|
|
27403
|
+
const [path2, query] = wsComponent.resourceName.split("?");
|
|
27404
|
+
wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
|
|
27405
27405
|
wsComponent.query = query;
|
|
27406
27406
|
wsComponent.resourceName = void 0;
|
|
27407
27407
|
}
|
|
@@ -31594,19 +31594,19 @@ function resolveStoredRefreshToken(parsed) {
|
|
|
31594
31594
|
}
|
|
31595
31595
|
return { refreshToken: "", source: "none" };
|
|
31596
31596
|
}
|
|
31597
|
-
function buildStoredCredentials(parsed,
|
|
31597
|
+
function buildStoredCredentials(parsed, path2, warn3) {
|
|
31598
31598
|
const { token, source: tokenSource } = resolveStoredToken(parsed);
|
|
31599
31599
|
const { refreshToken, source: refreshTokenSource } = resolveStoredRefreshToken(parsed);
|
|
31600
31600
|
if (token === null || refreshToken === null || parsed.refreshToken !== void 0 && typeof parsed.refreshToken !== "string" || parsed.refreshTokenEncrypted !== void 0 && typeof parsed.refreshTokenEncrypted !== "string" || !hasValidSelectedTwins(parsed.selectedTwins)) {
|
|
31601
31601
|
warn3(
|
|
31602
|
-
`Credentials file at ${
|
|
31602
|
+
`Credentials file at ${path2} has missing or invalid fields. Run \`archal login\` to re-authenticate.`
|
|
31603
31603
|
);
|
|
31604
31604
|
return null;
|
|
31605
31605
|
}
|
|
31606
31606
|
const { email: email3, plan, expiresAt } = parsed;
|
|
31607
31607
|
if (typeof email3 !== "string" || !isPlan(plan) || typeof expiresAt !== "number") {
|
|
31608
31608
|
warn3(
|
|
31609
|
-
`Credentials file at ${
|
|
31609
|
+
`Credentials file at ${path2} has missing or invalid fields. Run \`archal login\` to re-authenticate.`
|
|
31610
31610
|
);
|
|
31611
31611
|
return null;
|
|
31612
31612
|
}
|
|
@@ -31628,18 +31628,18 @@ function buildStoredCredentials(parsed, path, warn3) {
|
|
|
31628
31628
|
return creds;
|
|
31629
31629
|
}
|
|
31630
31630
|
function readCredentialsFile(options) {
|
|
31631
|
-
const
|
|
31632
|
-
if (!(0, import_fs.existsSync)(
|
|
31631
|
+
const path2 = getCredentialsPath();
|
|
31632
|
+
if (!(0, import_fs.existsSync)(path2)) {
|
|
31633
31633
|
return null;
|
|
31634
31634
|
}
|
|
31635
31635
|
try {
|
|
31636
31636
|
const warn3 = getWarn(options);
|
|
31637
|
-
const parsed = JSON.parse((0, import_fs.readFileSync)(
|
|
31638
|
-
return buildStoredCredentials(parsed,
|
|
31637
|
+
const parsed = JSON.parse((0, import_fs.readFileSync)(path2, "utf-8"));
|
|
31638
|
+
return buildStoredCredentials(parsed, path2, warn3);
|
|
31639
31639
|
} catch {
|
|
31640
31640
|
const warn3 = getWarn(options);
|
|
31641
31641
|
warn3(
|
|
31642
|
-
`Credentials file at ${
|
|
31642
|
+
`Credentials file at ${path2} exists but could not be parsed. Delete it and run \`archal login\` to re-authenticate.`
|
|
31643
31643
|
);
|
|
31644
31644
|
return null;
|
|
31645
31645
|
}
|
|
@@ -31716,11 +31716,11 @@ function saveCredentials(creds) {
|
|
|
31716
31716
|
(0, import_fs.renameSync)(tmpPath, credPath);
|
|
31717
31717
|
}
|
|
31718
31718
|
function deleteCredentials() {
|
|
31719
|
-
const
|
|
31720
|
-
if (!(0, import_fs.existsSync)(
|
|
31719
|
+
const path2 = getCredentialsPath();
|
|
31720
|
+
if (!(0, import_fs.existsSync)(path2)) {
|
|
31721
31721
|
return false;
|
|
31722
31722
|
}
|
|
31723
|
-
(0, import_fs.unlinkSync)(
|
|
31723
|
+
(0, import_fs.unlinkSync)(path2);
|
|
31724
31724
|
return true;
|
|
31725
31725
|
}
|
|
31726
31726
|
function getWarn2(options) {
|
|
@@ -31807,6 +31807,13 @@ function getConfiguredApiBaseUrl(options) {
|
|
|
31807
31807
|
}
|
|
31808
31808
|
return isStrictEndpointModeEnabled() ? null : HOSTED_DEFAULT_API_BASE_URL;
|
|
31809
31809
|
}
|
|
31810
|
+
function getConfiguredRuntimeBaseUrl(options) {
|
|
31811
|
+
const explicit = readConfiguredUrl(options, "ARCHAL_RUNTIME_URL");
|
|
31812
|
+
if (explicit) {
|
|
31813
|
+
return explicit;
|
|
31814
|
+
}
|
|
31815
|
+
return isStrictEndpointModeEnabled() ? null : HOSTED_DEFAULT_RUNTIME_BASE_URL;
|
|
31816
|
+
}
|
|
31810
31817
|
function buildAuthRequestHeaders(metadata, includeContentType = false) {
|
|
31811
31818
|
const headers = {};
|
|
31812
31819
|
if (includeContentType) {
|
|
@@ -32150,7 +32157,7 @@ async function revokeCliSession(refreshToken, metadata) {
|
|
|
32150
32157
|
debug2(`Session revoke failed (best-effort): ${errorMessage2(error49)}`);
|
|
32151
32158
|
}
|
|
32152
32159
|
}
|
|
32153
|
-
var import_child_process, import_crypto2, import_fs, import_os, import_path, CREDENTIALS_FILE, CREDENTIALS_KEY_FILE, AUTH_TOKEN_ENV_VAR, TOKEN_ENCRYPTION_PREFIX, CREDENTIALS_MASTER_KEY_ENV_VAR, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, HOSTED_DEFAULT_AUTH_BASE_URL, HOSTED_DEFAULT_API_BASE_URL, STRICT_ENDPOINTS_ENV_VAR, REQUEST_TIMEOUT_MS, ENV_TOKEN_FALLBACK_TTL_SECONDS, AUTH_RETRY_OPTIONS, ExpiredEnvTokenError, KEYCHAIN_COMMAND_TIMEOUT_MS, ARCHAL_DIR_NAME, seededSandboxes;
|
|
32160
|
+
var import_child_process, import_crypto2, import_fs, import_os, import_path, CREDENTIALS_FILE, CREDENTIALS_KEY_FILE, AUTH_TOKEN_ENV_VAR, TOKEN_ENCRYPTION_PREFIX, CREDENTIALS_MASTER_KEY_ENV_VAR, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, HOSTED_DEFAULT_AUTH_BASE_URL, HOSTED_DEFAULT_API_BASE_URL, HOSTED_DEFAULT_RUNTIME_BASE_URL, STRICT_ENDPOINTS_ENV_VAR, REQUEST_TIMEOUT_MS, ENV_TOKEN_FALLBACK_TTL_SECONDS, AUTH_RETRY_OPTIONS, ExpiredEnvTokenError, KEYCHAIN_COMMAND_TIMEOUT_MS, ARCHAL_DIR_NAME, seededSandboxes;
|
|
32154
32161
|
var init_dist3 = __esm({
|
|
32155
32162
|
"../packages/node-auth/dist/index.js"() {
|
|
32156
32163
|
"use strict";
|
|
@@ -32167,7 +32174,8 @@ var init_dist3 = __esm({
|
|
|
32167
32174
|
KEYCHAIN_SERVICE = "archal-cli";
|
|
32168
32175
|
KEYCHAIN_ACCOUNT = "credentials-master-key";
|
|
32169
32176
|
HOSTED_DEFAULT_AUTH_BASE_URL = "https://www.archal.ai";
|
|
32170
|
-
HOSTED_DEFAULT_API_BASE_URL = "https://
|
|
32177
|
+
HOSTED_DEFAULT_API_BASE_URL = "https://api.archal.ai";
|
|
32178
|
+
HOSTED_DEFAULT_RUNTIME_BASE_URL = "https://api.archal.ai";
|
|
32171
32179
|
STRICT_ENDPOINTS_ENV_VAR = "ARCHAL_STRICT_ENDPOINTS";
|
|
32172
32180
|
REQUEST_TIMEOUT_MS = 8e3;
|
|
32173
32181
|
ENV_TOKEN_FALLBACK_TTL_SECONDS = 24 * 60 * 60;
|
|
@@ -32377,6 +32385,9 @@ function getConfiguredAuthBaseUrl2() {
|
|
|
32377
32385
|
function getConfiguredApiBaseUrl2() {
|
|
32378
32386
|
return getConfiguredApiBaseUrl(READ_OPTIONS);
|
|
32379
32387
|
}
|
|
32388
|
+
function getConfiguredRuntimeBaseUrl2() {
|
|
32389
|
+
return getConfiguredRuntimeBaseUrl(READ_OPTIONS);
|
|
32390
|
+
}
|
|
32380
32391
|
var READ_OPTIONS;
|
|
32381
32392
|
var init_url_resolver = __esm({
|
|
32382
32393
|
"src/auth/url-resolver.ts"() {
|
|
@@ -32598,6 +32609,7 @@ __export(auth_exports, {
|
|
|
32598
32609
|
getArchalDir: () => getArchalDir,
|
|
32599
32610
|
getConfiguredApiBaseUrl: () => getConfiguredApiBaseUrl2,
|
|
32600
32611
|
getConfiguredAuthBaseUrl: () => getConfiguredAuthBaseUrl2,
|
|
32612
|
+
getConfiguredRuntimeBaseUrl: () => getConfiguredRuntimeBaseUrl2,
|
|
32601
32613
|
getCredentials: () => getCredentials2,
|
|
32602
32614
|
getJwtExpiry: () => getJwtExpiry,
|
|
32603
32615
|
getStoredCredentials: () => getStoredCredentials2,
|
|
@@ -32933,13 +32945,13 @@ function resolveBaseUrl(_path) {
|
|
|
32933
32945
|
error: "ARCHAL_API_URL is required for API requests when ARCHAL_STRICT_ENDPOINTS=1. Set ARCHAL_API_URL to your API endpoint, or unset ARCHAL_STRICT_ENDPOINTS."
|
|
32934
32946
|
};
|
|
32935
32947
|
}
|
|
32936
|
-
function isFinalizeEvidencePath(
|
|
32937
|
-
const [pathname] =
|
|
32948
|
+
function isFinalizeEvidencePath(path2) {
|
|
32949
|
+
const [pathname] = path2.split("?", 1);
|
|
32938
32950
|
if (!pathname) return false;
|
|
32939
32951
|
return /^\/api\/sessions\/[^/]+\/evidence\/finalize$/.test(pathname);
|
|
32940
32952
|
}
|
|
32941
|
-
function isCreateSessionPath(
|
|
32942
|
-
const [pathname] =
|
|
32953
|
+
function isCreateSessionPath(path2) {
|
|
32954
|
+
const [pathname] = path2.split("?", 1);
|
|
32943
32955
|
if (!pathname) return false;
|
|
32944
32956
|
return pathname === "/api/sessions";
|
|
32945
32957
|
}
|
|
@@ -32988,9 +33000,9 @@ async function tryRefreshToken() {
|
|
|
32988
33000
|
return null;
|
|
32989
33001
|
}
|
|
32990
33002
|
}
|
|
32991
|
-
async function request(method,
|
|
33003
|
+
async function request(method, path2, token, body, timeoutOrOptions) {
|
|
32992
33004
|
const options = typeof timeoutOrOptions === "number" ? { timeoutMs: timeoutOrOptions } : timeoutOrOptions ?? {};
|
|
32993
|
-
const baseUrl = resolveBaseUrl(
|
|
33005
|
+
const baseUrl = resolveBaseUrl(path2);
|
|
32994
33006
|
if (!baseUrl.ok) {
|
|
32995
33007
|
return {
|
|
32996
33008
|
ok: false,
|
|
@@ -32999,7 +33011,7 @@ async function request(method, path, token, body, timeoutOrOptions) {
|
|
|
32999
33011
|
code: baseUrl.code
|
|
33000
33012
|
};
|
|
33001
33013
|
}
|
|
33002
|
-
const url2 = `${baseUrl.baseUrl}${
|
|
33014
|
+
const url2 = `${baseUrl.baseUrl}${path2}`;
|
|
33003
33015
|
const headers = {
|
|
33004
33016
|
"content-type": "application/json",
|
|
33005
33017
|
"user-agent": CLI_USER_AGENT,
|
|
@@ -33016,8 +33028,8 @@ async function request(method, path, token, body, timeoutOrOptions) {
|
|
|
33016
33028
|
if (options.idempotencyKey) {
|
|
33017
33029
|
headers["x-archal-idempotency-key"] = options.idempotencyKey;
|
|
33018
33030
|
}
|
|
33019
|
-
const isIdempotentFinalize = method === "POST" && isFinalizeEvidencePath(
|
|
33020
|
-
const isIdempotentCreateSession = method === "POST" && isCreateSessionPath(
|
|
33031
|
+
const isIdempotentFinalize = method === "POST" && isFinalizeEvidencePath(path2);
|
|
33032
|
+
const isIdempotentCreateSession = method === "POST" && isCreateSessionPath(path2) && Boolean(options.idempotentPost && options.idempotencyKey);
|
|
33021
33033
|
const retriesAllowed = method !== "POST" || isIdempotentFinalize || isIdempotentCreateSession;
|
|
33022
33034
|
const attempts = retriesAllowed ? getMaxRetries() + 1 : 1;
|
|
33023
33035
|
let lastError = "request failed";
|
|
@@ -33044,7 +33056,7 @@ async function request(method, path, token, body, timeoutOrOptions) {
|
|
|
33044
33056
|
}
|
|
33045
33057
|
if (retriesAllowed && !softAuthRetryAttempted && getMaxRetries() > 0 && token) {
|
|
33046
33058
|
softAuthRetryAttempted = true;
|
|
33047
|
-
debug3(`401 on ${method} ${
|
|
33059
|
+
debug3(`401 on ${method} ${path2}: soft-retrying once after backoff`);
|
|
33048
33060
|
await sleep(retryDelayMs(1, response.headers.get("retry-after")));
|
|
33049
33061
|
attempt -= 1;
|
|
33050
33062
|
continue;
|
|
@@ -34210,7 +34222,7 @@ var init_dist4 = __esm({
|
|
|
34210
34222
|
}
|
|
34211
34223
|
});
|
|
34212
34224
|
|
|
34213
|
-
// ../packages/seed-codegen-runtime/dist/
|
|
34225
|
+
// ../packages/seed-codegen-runtime/dist/chunk-LOUVSGFM.js
|
|
34214
34226
|
function getMaxId(entities) {
|
|
34215
34227
|
let max = 0;
|
|
34216
34228
|
for (const entity of entities) {
|
|
@@ -35137,13 +35149,13 @@ function buildGitHubSandbox(context, collector) {
|
|
|
35137
35149
|
const repoId = repoRef?._id ?? findFirstRepoId(collector.seed) ?? 1;
|
|
35138
35150
|
const nextId = getMaxId(collector.seed["workflows"]) + 1;
|
|
35139
35151
|
const now = /* @__PURE__ */ new Date();
|
|
35140
|
-
const
|
|
35152
|
+
const path2 = opts?.["path"] ?? `.github/workflows/${name.toLowerCase().replace(/\s+/g, "-")}.yml`;
|
|
35141
35153
|
collector.seed["workflows"].push({
|
|
35142
35154
|
id: nextId,
|
|
35143
35155
|
repoId,
|
|
35144
35156
|
nodeId: generateNodeId("W", nextId),
|
|
35145
35157
|
name,
|
|
35146
|
-
path,
|
|
35158
|
+
path: path2,
|
|
35147
35159
|
state: opts?.["state"] ?? "active",
|
|
35148
35160
|
htmlUrl: "",
|
|
35149
35161
|
badgeUrl: "",
|
|
@@ -36120,7 +36132,7 @@ function buildGitHubSandbox(context, collector) {
|
|
|
36120
36132
|
});
|
|
36121
36133
|
return makeRef("environments", nextId, name);
|
|
36122
36134
|
};
|
|
36123
|
-
context["createFileEntry"] = (repoRef,
|
|
36135
|
+
context["createFileEntry"] = (repoRef, path2, content, opts) => {
|
|
36124
36136
|
if (!collector.seed["files"]) collector.seed["files"] = [];
|
|
36125
36137
|
const repoId = repoRef?._id ?? findFirstRepoId(collector.seed) ?? 1;
|
|
36126
36138
|
const nextId = getMaxId(collector.seed["files"]) + 1;
|
|
@@ -36129,7 +36141,7 @@ function buildGitHubSandbox(context, collector) {
|
|
|
36129
36141
|
id: nextId,
|
|
36130
36142
|
repoId,
|
|
36131
36143
|
branchName: opts?.["branchName"] ?? "main",
|
|
36132
|
-
path,
|
|
36144
|
+
path: path2,
|
|
36133
36145
|
content,
|
|
36134
36146
|
encoding: opts?.["encoding"] ?? "utf-8",
|
|
36135
36147
|
sha: generateSha(),
|
|
@@ -36138,7 +36150,7 @@ function buildGitHubSandbox(context, collector) {
|
|
|
36138
36150
|
createdAt: now.toISOString(),
|
|
36139
36151
|
updatedAt: now.toISOString()
|
|
36140
36152
|
});
|
|
36141
|
-
return makeRef("files", nextId,
|
|
36153
|
+
return makeRef("files", nextId, path2);
|
|
36142
36154
|
};
|
|
36143
36155
|
context["createFollower"] = (userLogin, followerLogin) => {
|
|
36144
36156
|
if (!collector.seed["followers"]) collector.seed["followers"] = [];
|
|
@@ -36726,7 +36738,7 @@ function buildGitHubSandbox(context, collector) {
|
|
|
36726
36738
|
});
|
|
36727
36739
|
return makeRef("projectCards", nextId);
|
|
36728
36740
|
};
|
|
36729
|
-
context["createPullRequestReviewThread"] = (repoRef, pullRequestNumber,
|
|
36741
|
+
context["createPullRequestReviewThread"] = (repoRef, pullRequestNumber, path2, opts) => {
|
|
36730
36742
|
if (!collector.seed["pullRequestReviewThreads"]) collector.seed["pullRequestReviewThreads"] = [];
|
|
36731
36743
|
const repoId = repoRef?._id ?? findFirstRepoId(collector.seed) ?? 1;
|
|
36732
36744
|
const nextId = getMaxId(collector.seed["pullRequestReviewThreads"]) + 1;
|
|
@@ -36745,7 +36757,7 @@ function buildGitHubSandbox(context, collector) {
|
|
|
36745
36757
|
startSide: opts?.["startSide"] ?? "RIGHT",
|
|
36746
36758
|
side: opts?.["side"] ?? "RIGHT",
|
|
36747
36759
|
diffSide: opts?.["diffSide"] ?? "RIGHT",
|
|
36748
|
-
path,
|
|
36760
|
+
path: path2,
|
|
36749
36761
|
createdAt: now.toISOString(),
|
|
36750
36762
|
updatedAt: now.toISOString()
|
|
36751
36763
|
});
|
|
@@ -43637,6 +43649,204 @@ function buildSandboxContext(collector, twinName) {
|
|
|
43637
43649
|
}
|
|
43638
43650
|
return context;
|
|
43639
43651
|
}
|
|
43652
|
+
var MS_PER_DAY, ISSUE_TITLES, ISSUE_BODIES, PR_TITLES, CHANNEL_PURPOSES, MESSAGE_TEXTS, DEFAULT_REACTIONS, MAX_BULK_COUNT, SeedCollector, TWIN_CONTEXT_BUILDERS;
|
|
43653
|
+
var init_chunk_LOUVSGFM = __esm({
|
|
43654
|
+
"../packages/seed-codegen-runtime/dist/chunk-LOUVSGFM.js"() {
|
|
43655
|
+
"use strict";
|
|
43656
|
+
MS_PER_DAY = 864e5;
|
|
43657
|
+
ISSUE_TITLES = [
|
|
43658
|
+
"Fix login redirect loop on Safari",
|
|
43659
|
+
"Add dark mode support to settings page",
|
|
43660
|
+
"Rate limiter returns 500 instead of 429",
|
|
43661
|
+
"Memory leak in WebSocket connection manager",
|
|
43662
|
+
"Dropdown menus do not close on mobile",
|
|
43663
|
+
"Search results do not highlight matching terms",
|
|
43664
|
+
"File upload fails silently for large files",
|
|
43665
|
+
"Add CSV export to analytics dashboard",
|
|
43666
|
+
"Implement bulk actions for notifications",
|
|
43667
|
+
"GraphQL query returns stale cached data",
|
|
43668
|
+
"Table component lacks keyboard navigation",
|
|
43669
|
+
"Create onboarding tutorial for new members",
|
|
43670
|
+
"API response times degrade for large date ranges",
|
|
43671
|
+
"Add two-factor authentication for admin accounts",
|
|
43672
|
+
"Deprecated crypto API warnings in test suite",
|
|
43673
|
+
"Evaluate replacing Moment.js with date-fns",
|
|
43674
|
+
"Broken tooltip positioning on Safari 17",
|
|
43675
|
+
"Login page shows blank screen on slow 3G",
|
|
43676
|
+
"Intermittent 502 errors on reports endpoint",
|
|
43677
|
+
"Tracking: migrate auth from cookies to JWT",
|
|
43678
|
+
"Roadmap: accessibility audit and WCAG compliance",
|
|
43679
|
+
"Upgrade Node.js runtime from 18 to 20 LTS",
|
|
43680
|
+
"Refactor database connection pool configuration",
|
|
43681
|
+
"Add retry logic for third-party API calls",
|
|
43682
|
+
"Improve error messages for form validation",
|
|
43683
|
+
"Pagination breaks when filtering by status",
|
|
43684
|
+
"Email notification templates are not responsive",
|
|
43685
|
+
"CI pipeline takes 45 minutes on large PRs",
|
|
43686
|
+
"Localization support for date and number formats",
|
|
43687
|
+
"Dashboard widgets do not resize on mobile"
|
|
43688
|
+
];
|
|
43689
|
+
ISSUE_BODIES = [
|
|
43690
|
+
"This has been reported multiple times by users. Needs investigation and a fix.",
|
|
43691
|
+
"No one has started working on this yet. Low priority but would improve UX.",
|
|
43692
|
+
"This is affecting production traffic. We need to address this soon.",
|
|
43693
|
+
"Users have requested this feature multiple times. Would be a nice enhancement.",
|
|
43694
|
+
"This is a long-running tracking issue. Should remain open for visibility.",
|
|
43695
|
+
"Repro steps: 1) Open the app 2) Navigate to settings 3) Observe the issue.",
|
|
43696
|
+
"This blocks other work. Please prioritize.",
|
|
43697
|
+
"Nice to have. Not urgent but would reduce tech debt."
|
|
43698
|
+
];
|
|
43699
|
+
PR_TITLES = [
|
|
43700
|
+
"Fix null check in JWT validation",
|
|
43701
|
+
"Add pagination to search results",
|
|
43702
|
+
"Refactor database connection pooling",
|
|
43703
|
+
"Update dependencies to latest versions",
|
|
43704
|
+
"Improve error handling in API middleware",
|
|
43705
|
+
"Add unit tests for auth module",
|
|
43706
|
+
"Fix race condition in WebSocket handler",
|
|
43707
|
+
"Migrate CSS to custom properties for theming"
|
|
43708
|
+
];
|
|
43709
|
+
CHANNEL_PURPOSES = [
|
|
43710
|
+
"General discussion",
|
|
43711
|
+
"Engineering team updates",
|
|
43712
|
+
"Product announcements",
|
|
43713
|
+
"Customer support escalations",
|
|
43714
|
+
"Random fun stuff",
|
|
43715
|
+
"Incident response",
|
|
43716
|
+
"Design feedback",
|
|
43717
|
+
"Deploy notifications"
|
|
43718
|
+
];
|
|
43719
|
+
MESSAGE_TEXTS = [
|
|
43720
|
+
"Hey team, just a heads up about the deploy today.",
|
|
43721
|
+
"Can someone review my PR? It's been open for a while.",
|
|
43722
|
+
"The CI pipeline is green again after the fix.",
|
|
43723
|
+
"Meeting notes from today's standup are in the doc.",
|
|
43724
|
+
"Has anyone seen this error before? Getting a 502 intermittently.",
|
|
43725
|
+
"Thanks for the quick turnaround on that bug fix!",
|
|
43726
|
+
"Reminder: retro is at 3pm today.",
|
|
43727
|
+
"I pushed a hotfix for the login issue. Please verify."
|
|
43728
|
+
];
|
|
43729
|
+
DEFAULT_REACTIONS = {
|
|
43730
|
+
totalCount: 0,
|
|
43731
|
+
plusOne: 0,
|
|
43732
|
+
minusOne: 0,
|
|
43733
|
+
laugh: 0,
|
|
43734
|
+
hooray: 0,
|
|
43735
|
+
confused: 0,
|
|
43736
|
+
heart: 0,
|
|
43737
|
+
rocket: 0,
|
|
43738
|
+
eyes: 0
|
|
43739
|
+
};
|
|
43740
|
+
MAX_BULK_COUNT = 1e3;
|
|
43741
|
+
SeedCollector = class {
|
|
43742
|
+
seed;
|
|
43743
|
+
warnings = [];
|
|
43744
|
+
twinName;
|
|
43745
|
+
now;
|
|
43746
|
+
constructor(twinName, baseSeed) {
|
|
43747
|
+
this.seed = structuredClone(baseSeed);
|
|
43748
|
+
this.twinName = twinName;
|
|
43749
|
+
this.now = /* @__PURE__ */ new Date();
|
|
43750
|
+
}
|
|
43751
|
+
/** Create a single identity entity (user, repo, workspace, etc.). */
|
|
43752
|
+
createIdentity(collection, fields) {
|
|
43753
|
+
if (!this.seed[collection]) this.seed[collection] = [];
|
|
43754
|
+
const existing = this.seed[collection].find((entity2) => {
|
|
43755
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
43756
|
+
if (entity2[key] !== value) return false;
|
|
43757
|
+
}
|
|
43758
|
+
return true;
|
|
43759
|
+
});
|
|
43760
|
+
if (existing) {
|
|
43761
|
+
return makeRef(
|
|
43762
|
+
collection,
|
|
43763
|
+
existing["id"],
|
|
43764
|
+
fields["name"] ?? fields["login"]
|
|
43765
|
+
);
|
|
43766
|
+
}
|
|
43767
|
+
const nextId = getMaxId(this.seed[collection]) + 1;
|
|
43768
|
+
const nowStr = this.now.toISOString();
|
|
43769
|
+
const entity = {
|
|
43770
|
+
id: nextId,
|
|
43771
|
+
...fields,
|
|
43772
|
+
createdAt: nowStr,
|
|
43773
|
+
updatedAt: nowStr
|
|
43774
|
+
};
|
|
43775
|
+
fillDefaults(entity, collection);
|
|
43776
|
+
this.seed[collection].push(entity);
|
|
43777
|
+
return makeRef(collection, nextId, fields["name"] ?? fields["login"]);
|
|
43778
|
+
}
|
|
43779
|
+
/** Create N entities in a collection with shared properties. */
|
|
43780
|
+
createBulk(collection, count, properties) {
|
|
43781
|
+
if (!this.seed[collection]) this.seed[collection] = [];
|
|
43782
|
+
const safeCount = Math.min(count, MAX_BULK_COUNT);
|
|
43783
|
+
if (safeCount < count) {
|
|
43784
|
+
this.warnings.push(
|
|
43785
|
+
`createBulk: count ${count} capped at ${MAX_BULK_COUNT} for "${collection}"`
|
|
43786
|
+
);
|
|
43787
|
+
}
|
|
43788
|
+
for (let i = 0; i < safeCount; i++) {
|
|
43789
|
+
const nextId = getMaxId(this.seed[collection]) + 1;
|
|
43790
|
+
const temporal = resolveTemporalProperties(properties, this.now);
|
|
43791
|
+
const entity = this.buildEntity(collection, nextId, properties, i, temporal);
|
|
43792
|
+
this.seed[collection].push(entity);
|
|
43793
|
+
}
|
|
43794
|
+
}
|
|
43795
|
+
/** Push a single pre-built entity directly into a collection. */
|
|
43796
|
+
pushEntity(collection, entity) {
|
|
43797
|
+
if (!this.seed[collection]) this.seed[collection] = [];
|
|
43798
|
+
const stored = entity["id"] === void 0 ? { id: getMaxId(this.seed[collection]) + 1, ...entity } : entity;
|
|
43799
|
+
this.seed[collection].push(stored);
|
|
43800
|
+
}
|
|
43801
|
+
/** Clear a collection (blueprint-style replacement). */
|
|
43802
|
+
clearCollection(collection) {
|
|
43803
|
+
if (this.seed[collection]) {
|
|
43804
|
+
this.seed[collection] = [];
|
|
43805
|
+
}
|
|
43806
|
+
}
|
|
43807
|
+
buildEntity(collection, id, props, index, temporal) {
|
|
43808
|
+
if (this.twinName === "github")
|
|
43809
|
+
return buildGitHubEntity(collection, id, props, this.seed, index, temporal);
|
|
43810
|
+
if (this.twinName === "slack")
|
|
43811
|
+
return buildSlackEntity(collection, id, props, this.seed, index, temporal);
|
|
43812
|
+
if (this.twinName === "linear")
|
|
43813
|
+
return buildLinearEntity(collection, id, props, this.seed, index, temporal);
|
|
43814
|
+
if (this.twinName === "stripe")
|
|
43815
|
+
return buildStripeEntity(collection, id, props, this.seed, index, temporal);
|
|
43816
|
+
if (this.twinName === "jira")
|
|
43817
|
+
return buildJiraEntity(collection, id, props, this.seed, index, temporal);
|
|
43818
|
+
return { id, ...props, createdAt: temporal.createdAt, updatedAt: temporal.updatedAt };
|
|
43819
|
+
}
|
|
43820
|
+
/** Compute a synthetic patch (add-only) from base → built seed. */
|
|
43821
|
+
computePatch(baseSeed) {
|
|
43822
|
+
const add = {};
|
|
43823
|
+
for (const [collection, entities] of Object.entries(this.seed)) {
|
|
43824
|
+
const baseEntities = baseSeed[collection] ?? [];
|
|
43825
|
+
const baseIds = new Set(baseEntities.map((e) => e["id"]));
|
|
43826
|
+
const newEntities = entities.filter(
|
|
43827
|
+
(e) => !baseIds.has(e["id"])
|
|
43828
|
+
);
|
|
43829
|
+
if (newEntities.length > 0) {
|
|
43830
|
+
add[collection] = newEntities;
|
|
43831
|
+
}
|
|
43832
|
+
}
|
|
43833
|
+
return { add };
|
|
43834
|
+
}
|
|
43835
|
+
};
|
|
43836
|
+
TWIN_CONTEXT_BUILDERS = {
|
|
43837
|
+
github: buildGitHubSandbox,
|
|
43838
|
+
slack: buildSlackSandbox,
|
|
43839
|
+
linear: buildLinearSandbox,
|
|
43840
|
+
stripe: buildStripeSandbox,
|
|
43841
|
+
jira: buildJiraSandbox,
|
|
43842
|
+
supabase: buildSupabaseSandbox,
|
|
43843
|
+
"google-workspace": buildGoogleWorkspaceSandbox,
|
|
43844
|
+
ramp: buildRampSandbox
|
|
43845
|
+
};
|
|
43846
|
+
}
|
|
43847
|
+
});
|
|
43848
|
+
|
|
43849
|
+
// ../packages/seed-codegen-runtime/dist/index.js
|
|
43640
43850
|
function checkStaticSafety(code) {
|
|
43641
43851
|
const match = FORBIDDEN_PATTERN.exec(code);
|
|
43642
43852
|
if (match) {
|
|
@@ -44471,204 +44681,18 @@ function augmentPlanFromDescription(plan, description, twinName) {
|
|
|
44471
44681
|
planTypes.add(rule.type);
|
|
44472
44682
|
}
|
|
44473
44683
|
}
|
|
44474
|
-
var
|
|
44684
|
+
var import_url, import_path2, import_vm, import_meta2, FORBIDDEN_PATTERN, OBFUSCATION_PATTERNS, DEFAULT_TIMEOUT_MS2, workerScriptPath, SDK_DECLARATIONS, SDK_EXAMPLES, CODEGEN_SYSTEM_PROMPT, GEMINI_API_BASE_URL2, ANTHROPIC_API_URL2, OPENAI_API_URL2, ANTHROPIC_API_VERSION2, MANAGED_SEED_TIMEOUT_MS, DIRECT_SEED_TIMEOUT_MS, ERROR_BODY_PREVIEW_LENGTH3, RETRYABLE_STATUS_CODES3, MAX_RETRIES2, INITIAL_BACKOFF_MS2, MAX_JITTER_MS2, SeedLlmApiError, PLAN_SYSTEM_PROMPT, ENTITY_TYPE_TO_COLLECTION;
|
|
44475
44685
|
var init_dist5 = __esm({
|
|
44476
44686
|
"../packages/seed-codegen-runtime/dist/index.js"() {
|
|
44477
44687
|
"use strict";
|
|
44688
|
+
init_chunk_LOUVSGFM();
|
|
44689
|
+
import_url = require("url");
|
|
44690
|
+
import_path2 = __toESM(require("path"), 1);
|
|
44478
44691
|
import_vm = __toESM(require("vm"), 1);
|
|
44479
44692
|
init_dist2();
|
|
44480
44693
|
init_dist2();
|
|
44481
44694
|
init_dist3();
|
|
44482
|
-
|
|
44483
|
-
ISSUE_TITLES = [
|
|
44484
|
-
"Fix login redirect loop on Safari",
|
|
44485
|
-
"Add dark mode support to settings page",
|
|
44486
|
-
"Rate limiter returns 500 instead of 429",
|
|
44487
|
-
"Memory leak in WebSocket connection manager",
|
|
44488
|
-
"Dropdown menus do not close on mobile",
|
|
44489
|
-
"Search results do not highlight matching terms",
|
|
44490
|
-
"File upload fails silently for large files",
|
|
44491
|
-
"Add CSV export to analytics dashboard",
|
|
44492
|
-
"Implement bulk actions for notifications",
|
|
44493
|
-
"GraphQL query returns stale cached data",
|
|
44494
|
-
"Table component lacks keyboard navigation",
|
|
44495
|
-
"Create onboarding tutorial for new members",
|
|
44496
|
-
"API response times degrade for large date ranges",
|
|
44497
|
-
"Add two-factor authentication for admin accounts",
|
|
44498
|
-
"Deprecated crypto API warnings in test suite",
|
|
44499
|
-
"Evaluate replacing Moment.js with date-fns",
|
|
44500
|
-
"Broken tooltip positioning on Safari 17",
|
|
44501
|
-
"Login page shows blank screen on slow 3G",
|
|
44502
|
-
"Intermittent 502 errors on reports endpoint",
|
|
44503
|
-
"Tracking: migrate auth from cookies to JWT",
|
|
44504
|
-
"Roadmap: accessibility audit and WCAG compliance",
|
|
44505
|
-
"Upgrade Node.js runtime from 18 to 20 LTS",
|
|
44506
|
-
"Refactor database connection pool configuration",
|
|
44507
|
-
"Add retry logic for third-party API calls",
|
|
44508
|
-
"Improve error messages for form validation",
|
|
44509
|
-
"Pagination breaks when filtering by status",
|
|
44510
|
-
"Email notification templates are not responsive",
|
|
44511
|
-
"CI pipeline takes 45 minutes on large PRs",
|
|
44512
|
-
"Localization support for date and number formats",
|
|
44513
|
-
"Dashboard widgets do not resize on mobile"
|
|
44514
|
-
];
|
|
44515
|
-
ISSUE_BODIES = [
|
|
44516
|
-
"This has been reported multiple times by users. Needs investigation and a fix.",
|
|
44517
|
-
"No one has started working on this yet. Low priority but would improve UX.",
|
|
44518
|
-
"This is affecting production traffic. We need to address this soon.",
|
|
44519
|
-
"Users have requested this feature multiple times. Would be a nice enhancement.",
|
|
44520
|
-
"This is a long-running tracking issue. Should remain open for visibility.",
|
|
44521
|
-
"Repro steps: 1) Open the app 2) Navigate to settings 3) Observe the issue.",
|
|
44522
|
-
"This blocks other work. Please prioritize.",
|
|
44523
|
-
"Nice to have. Not urgent but would reduce tech debt."
|
|
44524
|
-
];
|
|
44525
|
-
PR_TITLES = [
|
|
44526
|
-
"Fix null check in JWT validation",
|
|
44527
|
-
"Add pagination to search results",
|
|
44528
|
-
"Refactor database connection pooling",
|
|
44529
|
-
"Update dependencies to latest versions",
|
|
44530
|
-
"Improve error handling in API middleware",
|
|
44531
|
-
"Add unit tests for auth module",
|
|
44532
|
-
"Fix race condition in WebSocket handler",
|
|
44533
|
-
"Migrate CSS to custom properties for theming"
|
|
44534
|
-
];
|
|
44535
|
-
CHANNEL_PURPOSES = [
|
|
44536
|
-
"General discussion",
|
|
44537
|
-
"Engineering team updates",
|
|
44538
|
-
"Product announcements",
|
|
44539
|
-
"Customer support escalations",
|
|
44540
|
-
"Random fun stuff",
|
|
44541
|
-
"Incident response",
|
|
44542
|
-
"Design feedback",
|
|
44543
|
-
"Deploy notifications"
|
|
44544
|
-
];
|
|
44545
|
-
MESSAGE_TEXTS = [
|
|
44546
|
-
"Hey team, just a heads up about the deploy today.",
|
|
44547
|
-
"Can someone review my PR? It's been open for a while.",
|
|
44548
|
-
"The CI pipeline is green again after the fix.",
|
|
44549
|
-
"Meeting notes from today's standup are in the doc.",
|
|
44550
|
-
"Has anyone seen this error before? Getting a 502 intermittently.",
|
|
44551
|
-
"Thanks for the quick turnaround on that bug fix!",
|
|
44552
|
-
"Reminder: retro is at 3pm today.",
|
|
44553
|
-
"I pushed a hotfix for the login issue. Please verify."
|
|
44554
|
-
];
|
|
44555
|
-
DEFAULT_REACTIONS = {
|
|
44556
|
-
totalCount: 0,
|
|
44557
|
-
plusOne: 0,
|
|
44558
|
-
minusOne: 0,
|
|
44559
|
-
laugh: 0,
|
|
44560
|
-
hooray: 0,
|
|
44561
|
-
confused: 0,
|
|
44562
|
-
heart: 0,
|
|
44563
|
-
rocket: 0,
|
|
44564
|
-
eyes: 0
|
|
44565
|
-
};
|
|
44566
|
-
MAX_BULK_COUNT = 1e3;
|
|
44567
|
-
SeedCollector = class {
|
|
44568
|
-
seed;
|
|
44569
|
-
warnings = [];
|
|
44570
|
-
twinName;
|
|
44571
|
-
now;
|
|
44572
|
-
constructor(twinName, baseSeed) {
|
|
44573
|
-
this.seed = structuredClone(baseSeed);
|
|
44574
|
-
this.twinName = twinName;
|
|
44575
|
-
this.now = /* @__PURE__ */ new Date();
|
|
44576
|
-
}
|
|
44577
|
-
/** Create a single identity entity (user, repo, workspace, etc.). */
|
|
44578
|
-
createIdentity(collection, fields) {
|
|
44579
|
-
if (!this.seed[collection]) this.seed[collection] = [];
|
|
44580
|
-
const existing = this.seed[collection].find((entity2) => {
|
|
44581
|
-
for (const [key, value] of Object.entries(fields)) {
|
|
44582
|
-
if (entity2[key] !== value) return false;
|
|
44583
|
-
}
|
|
44584
|
-
return true;
|
|
44585
|
-
});
|
|
44586
|
-
if (existing) {
|
|
44587
|
-
return makeRef(
|
|
44588
|
-
collection,
|
|
44589
|
-
existing["id"],
|
|
44590
|
-
fields["name"] ?? fields["login"]
|
|
44591
|
-
);
|
|
44592
|
-
}
|
|
44593
|
-
const nextId = getMaxId(this.seed[collection]) + 1;
|
|
44594
|
-
const nowStr = this.now.toISOString();
|
|
44595
|
-
const entity = {
|
|
44596
|
-
id: nextId,
|
|
44597
|
-
...fields,
|
|
44598
|
-
createdAt: nowStr,
|
|
44599
|
-
updatedAt: nowStr
|
|
44600
|
-
};
|
|
44601
|
-
fillDefaults(entity, collection);
|
|
44602
|
-
this.seed[collection].push(entity);
|
|
44603
|
-
return makeRef(collection, nextId, fields["name"] ?? fields["login"]);
|
|
44604
|
-
}
|
|
44605
|
-
/** Create N entities in a collection with shared properties. */
|
|
44606
|
-
createBulk(collection, count, properties) {
|
|
44607
|
-
if (!this.seed[collection]) this.seed[collection] = [];
|
|
44608
|
-
const safeCount = Math.min(count, MAX_BULK_COUNT);
|
|
44609
|
-
if (safeCount < count) {
|
|
44610
|
-
this.warnings.push(
|
|
44611
|
-
`createBulk: count ${count} capped at ${MAX_BULK_COUNT} for "${collection}"`
|
|
44612
|
-
);
|
|
44613
|
-
}
|
|
44614
|
-
for (let i = 0; i < safeCount; i++) {
|
|
44615
|
-
const nextId = getMaxId(this.seed[collection]) + 1;
|
|
44616
|
-
const temporal = resolveTemporalProperties(properties, this.now);
|
|
44617
|
-
const entity = this.buildEntity(collection, nextId, properties, i, temporal);
|
|
44618
|
-
this.seed[collection].push(entity);
|
|
44619
|
-
}
|
|
44620
|
-
}
|
|
44621
|
-
/** Push a single pre-built entity directly into a collection. */
|
|
44622
|
-
pushEntity(collection, entity) {
|
|
44623
|
-
if (!this.seed[collection]) this.seed[collection] = [];
|
|
44624
|
-
const stored = entity["id"] === void 0 ? { id: getMaxId(this.seed[collection]) + 1, ...entity } : entity;
|
|
44625
|
-
this.seed[collection].push(stored);
|
|
44626
|
-
}
|
|
44627
|
-
/** Clear a collection (blueprint-style replacement). */
|
|
44628
|
-
clearCollection(collection) {
|
|
44629
|
-
if (this.seed[collection]) {
|
|
44630
|
-
this.seed[collection] = [];
|
|
44631
|
-
}
|
|
44632
|
-
}
|
|
44633
|
-
buildEntity(collection, id, props, index, temporal) {
|
|
44634
|
-
if (this.twinName === "github")
|
|
44635
|
-
return buildGitHubEntity(collection, id, props, this.seed, index, temporal);
|
|
44636
|
-
if (this.twinName === "slack")
|
|
44637
|
-
return buildSlackEntity(collection, id, props, this.seed, index, temporal);
|
|
44638
|
-
if (this.twinName === "linear")
|
|
44639
|
-
return buildLinearEntity(collection, id, props, this.seed, index, temporal);
|
|
44640
|
-
if (this.twinName === "stripe")
|
|
44641
|
-
return buildStripeEntity(collection, id, props, this.seed, index, temporal);
|
|
44642
|
-
if (this.twinName === "jira")
|
|
44643
|
-
return buildJiraEntity(collection, id, props, this.seed, index, temporal);
|
|
44644
|
-
return { id, ...props, createdAt: temporal.createdAt, updatedAt: temporal.updatedAt };
|
|
44645
|
-
}
|
|
44646
|
-
/** Compute a synthetic patch (add-only) from base → built seed. */
|
|
44647
|
-
computePatch(baseSeed) {
|
|
44648
|
-
const add = {};
|
|
44649
|
-
for (const [collection, entities] of Object.entries(this.seed)) {
|
|
44650
|
-
const baseEntities = baseSeed[collection] ?? [];
|
|
44651
|
-
const baseIds = new Set(baseEntities.map((e) => e["id"]));
|
|
44652
|
-
const newEntities = entities.filter(
|
|
44653
|
-
(e) => !baseIds.has(e["id"])
|
|
44654
|
-
);
|
|
44655
|
-
if (newEntities.length > 0) {
|
|
44656
|
-
add[collection] = newEntities;
|
|
44657
|
-
}
|
|
44658
|
-
}
|
|
44659
|
-
return { add };
|
|
44660
|
-
}
|
|
44661
|
-
};
|
|
44662
|
-
TWIN_CONTEXT_BUILDERS = {
|
|
44663
|
-
github: buildGitHubSandbox,
|
|
44664
|
-
slack: buildSlackSandbox,
|
|
44665
|
-
linear: buildLinearSandbox,
|
|
44666
|
-
stripe: buildStripeSandbox,
|
|
44667
|
-
jira: buildJiraSandbox,
|
|
44668
|
-
supabase: buildSupabaseSandbox,
|
|
44669
|
-
"google-workspace": buildGoogleWorkspaceSandbox,
|
|
44670
|
-
ramp: buildRampSandbox
|
|
44671
|
-
};
|
|
44695
|
+
import_meta2 = {};
|
|
44672
44696
|
FORBIDDEN_PATTERN = /\b(require|process|globalThis|eval|Function|constructor|__proto__|Reflect|Proxy|import)\s*[([.`]/;
|
|
44673
44697
|
OBFUSCATION_PATTERNS = [
|
|
44674
44698
|
/\[\s*['"`](?:constructor|__proto__|prototype)['"` ]/,
|
|
@@ -44685,6 +44709,12 @@ var init_dist5 = __esm({
|
|
|
44685
44709
|
// Symbol-based property access
|
|
44686
44710
|
];
|
|
44687
44711
|
DEFAULT_TIMEOUT_MS2 = 5e3;
|
|
44712
|
+
try {
|
|
44713
|
+
const thisDir = import_path2.default.dirname((0, import_url.fileURLToPath)(import_meta2.url));
|
|
44714
|
+
workerScriptPath = import_path2.default.join(thisDir, "subprocess-worker.js");
|
|
44715
|
+
} catch {
|
|
44716
|
+
workerScriptPath = void 0;
|
|
44717
|
+
}
|
|
44688
44718
|
SDK_DECLARATIONS = {
|
|
44689
44719
|
github: `// GitHub Seed Builder SDK
|
|
44690
44720
|
// All functions return opaque Ref handles. Use them to link entities.
|
|
@@ -52416,13 +52446,13 @@ function applyEnrichments(seed, response) {
|
|
|
52416
52446
|
function buildFewShotExample(twinName) {
|
|
52417
52447
|
try {
|
|
52418
52448
|
const fs = require("fs");
|
|
52419
|
-
const
|
|
52420
|
-
const seedsDir =
|
|
52449
|
+
const path2 = require("path");
|
|
52450
|
+
const seedsDir = path2.resolve("twins", twinName, "seeds");
|
|
52421
52451
|
if (!fs.existsSync(seedsDir)) return "";
|
|
52422
52452
|
const files = fs.readdirSync(seedsDir).filter((f) => f.endsWith(".json") && f !== "empty.json");
|
|
52423
52453
|
if (files.length === 0) return "";
|
|
52424
52454
|
const firstFile = files[0] ?? "";
|
|
52425
|
-
const seedData = JSON.parse(fs.readFileSync(
|
|
52455
|
+
const seedData = JSON.parse(fs.readFileSync(path2.join(seedsDir, firstFile), "utf-8"));
|
|
52426
52456
|
for (const [col, entities] of Object.entries(seedData)) {
|
|
52427
52457
|
if (Array.isArray(entities) && entities.length > 0 && typeof entities[0] === "object") {
|
|
52428
52458
|
const example = JSON.stringify(entities[0]).slice(0, 500);
|
|
@@ -54395,23 +54425,23 @@ __export(dist_exports, {
|
|
|
54395
54425
|
function isStringRecord(v) {
|
|
54396
54426
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
54397
54427
|
}
|
|
54398
|
-
function readPackageJson(
|
|
54399
|
-
if (!(0, import_fs2.existsSync)(
|
|
54400
|
-
const content = (0, import_fs2.readFileSync)(
|
|
54428
|
+
function readPackageJson(path2) {
|
|
54429
|
+
if (!(0, import_fs2.existsSync)(path2)) return void 0;
|
|
54430
|
+
const content = (0, import_fs2.readFileSync)(path2, "utf-8");
|
|
54401
54431
|
let parsed;
|
|
54402
54432
|
try {
|
|
54403
54433
|
parsed = JSON.parse(content);
|
|
54404
54434
|
} catch {
|
|
54405
54435
|
throw new DockerfileError(
|
|
54406
54436
|
"invalid_path",
|
|
54407
|
-
`Failed to parse ${
|
|
54437
|
+
`Failed to parse ${path2.split("/").pop()}: invalid JSON`,
|
|
54408
54438
|
"Fix the JSON syntax error in the file and try again."
|
|
54409
54439
|
);
|
|
54410
54440
|
}
|
|
54411
54441
|
if (typeof parsed !== "object" || parsed === null) {
|
|
54412
54442
|
throw new DockerfileError(
|
|
54413
54443
|
"invalid_path",
|
|
54414
|
-
`${
|
|
54444
|
+
`${path2.split("/").pop()} is not a JSON object`,
|
|
54415
54445
|
"Fix the JSON syntax error in the file and try again."
|
|
54416
54446
|
);
|
|
54417
54447
|
}
|
|
@@ -54422,7 +54452,7 @@ function readPackageJson(path) {
|
|
|
54422
54452
|
};
|
|
54423
54453
|
}
|
|
54424
54454
|
function hasFile(repoPath, relativePath) {
|
|
54425
|
-
return (0, import_fs2.existsSync)((0,
|
|
54455
|
+
return (0, import_fs2.existsSync)((0, import_path3.join)(repoPath, relativePath));
|
|
54426
54456
|
}
|
|
54427
54457
|
function quoteJsonCommand(parts) {
|
|
54428
54458
|
return `[${parts.map((part) => JSON.stringify(part)).join(", ")}]`;
|
|
@@ -54478,7 +54508,7 @@ function resolveNodeLaunchCommand(repoPath, pkg, packageManager) {
|
|
|
54478
54508
|
return void 0;
|
|
54479
54509
|
}
|
|
54480
54510
|
function maybeGenerateNodeDockerfile(repoPath) {
|
|
54481
|
-
const packageJsonPath = (0,
|
|
54511
|
+
const packageJsonPath = (0, import_path3.join)(repoPath, "package.json");
|
|
54482
54512
|
const pkg = readPackageJson(packageJsonPath);
|
|
54483
54513
|
if (!pkg) return void 0;
|
|
54484
54514
|
const packageManager = detectPackageManager(pkg, repoPath);
|
|
@@ -54506,12 +54536,12 @@ function maybeGenerateNodeDockerfile(repoPath) {
|
|
|
54506
54536
|
};
|
|
54507
54537
|
}
|
|
54508
54538
|
function maybeGenerateSharedLibNodeDockerfile(repoPath) {
|
|
54509
|
-
const packageJsonPath = (0,
|
|
54539
|
+
const packageJsonPath = (0, import_path3.join)(repoPath, "package.json");
|
|
54510
54540
|
const pkg = readPackageJson(packageJsonPath);
|
|
54511
54541
|
if (!pkg) return void 0;
|
|
54512
|
-
const harnessDirName = (0,
|
|
54513
|
-
const parentDir = (0,
|
|
54514
|
-
const sharedLibDir = (0,
|
|
54542
|
+
const harnessDirName = (0, import_path3.basename)(repoPath);
|
|
54543
|
+
const parentDir = (0, import_path3.dirname)(repoPath);
|
|
54544
|
+
const sharedLibDir = (0, import_path3.join)(parentDir, "_lib");
|
|
54515
54545
|
if (!(0, import_fs2.existsSync)(sharedLibDir)) return void 0;
|
|
54516
54546
|
let hasSharedLibFiles;
|
|
54517
54547
|
try {
|
|
@@ -54626,7 +54656,7 @@ function generateDockerfile(repoPath) {
|
|
|
54626
54656
|
}
|
|
54627
54657
|
function resolveExplicitDockerfile(repoPath, rawPath) {
|
|
54628
54658
|
const trimmed = rawPath.trim();
|
|
54629
|
-
const dockerfilePath = (0,
|
|
54659
|
+
const dockerfilePath = (0, import_path3.resolve)(repoPath, trimmed);
|
|
54630
54660
|
if (!(0, import_fs2.existsSync)(dockerfilePath) || !(0, import_fs2.statSync)(dockerfilePath).isFile()) {
|
|
54631
54661
|
throw new DockerfileError(
|
|
54632
54662
|
"invalid_path",
|
|
@@ -54637,7 +54667,7 @@ function resolveExplicitDockerfile(repoPath, rawPath) {
|
|
|
54637
54667
|
return dockerfilePath;
|
|
54638
54668
|
}
|
|
54639
54669
|
function resolveDockerfile(repoPathInput, options) {
|
|
54640
|
-
const repoPath = (0,
|
|
54670
|
+
const repoPath = (0, import_path3.resolve)(repoPathInput);
|
|
54641
54671
|
if (options?.explicitDockerfile?.trim()) {
|
|
54642
54672
|
const dockerfilePath = resolveExplicitDockerfile(repoPath, options.explicitDockerfile);
|
|
54643
54673
|
return {
|
|
@@ -54647,7 +54677,7 @@ function resolveDockerfile(repoPathInput, options) {
|
|
|
54647
54677
|
summary: `using explicit Dockerfile ${dockerfilePath}`
|
|
54648
54678
|
};
|
|
54649
54679
|
}
|
|
54650
|
-
const rootDockerfile = (0,
|
|
54680
|
+
const rootDockerfile = (0, import_path3.join)(repoPath, "Dockerfile");
|
|
54651
54681
|
if ((0, import_fs2.existsSync)(rootDockerfile) && (0, import_fs2.statSync)(rootDockerfile).isFile()) {
|
|
54652
54682
|
return {
|
|
54653
54683
|
source: "existing",
|
|
@@ -54671,7 +54701,7 @@ function resolveDockerfile(repoPathInput, options) {
|
|
|
54671
54701
|
"Pass a generatedDockerfilePath to resolveDockerfile."
|
|
54672
54702
|
);
|
|
54673
54703
|
}
|
|
54674
|
-
const generatedPath = (0,
|
|
54704
|
+
const generatedPath = (0, import_path3.resolve)(options.generatedDockerfilePath);
|
|
54675
54705
|
(0, import_fs2.writeFileSync)(generatedPath, generated.contents, "utf-8");
|
|
54676
54706
|
return {
|
|
54677
54707
|
source: "generated",
|
|
@@ -54687,9 +54717,9 @@ function generateCertAuthority() {
|
|
|
54687
54717
|
});
|
|
54688
54718
|
const certPem = generateSelfSignedCert(publicKey, privateKey, CA_COMMON_NAME, true);
|
|
54689
54719
|
const keyPem = privateKey.export({ type: "pkcs8", format: "pem" });
|
|
54690
|
-
const dir = (0, import_fs4.mkdtempSync)((0,
|
|
54691
|
-
const certPath = (0,
|
|
54692
|
-
const keyPath = (0,
|
|
54720
|
+
const dir = (0, import_fs4.mkdtempSync)((0, import_path5.join)((0, import_os3.tmpdir)(), "archal-sandbox-ca-"));
|
|
54721
|
+
const certPath = (0, import_path5.join)(dir, "ca.crt");
|
|
54722
|
+
const keyPath = (0, import_path5.join)(dir, "ca.key");
|
|
54693
54723
|
(0, import_fs4.writeFileSync)(certPath, certPem);
|
|
54694
54724
|
(0, import_fs4.writeFileSync)(keyPath, keyPem);
|
|
54695
54725
|
return { certPem, keyPem, certPath, keyPath, dir };
|
|
@@ -55402,8 +55432,8 @@ function extractInlineArg(query, name) {
|
|
|
55402
55432
|
const match = query.match(regex);
|
|
55403
55433
|
return match?.[1];
|
|
55404
55434
|
}
|
|
55405
|
-
function forwardToCloudTwin(clientReq, clientRes, targetBaseUrl,
|
|
55406
|
-
const target = resolveForwardTarget(targetBaseUrl,
|
|
55435
|
+
function forwardToCloudTwin(clientReq, clientRes, targetBaseUrl, path2, authHeaders, injectResponseHeaders) {
|
|
55436
|
+
const target = resolveForwardTarget(targetBaseUrl, path2);
|
|
55407
55437
|
const isHttps = target.protocol === "https:";
|
|
55408
55438
|
const requestFn = isHttps ? import_https.request : import_http.request;
|
|
55409
55439
|
const headers = {
|
|
@@ -55633,27 +55663,27 @@ function formatExecError(err) {
|
|
|
55633
55663
|
return String(err);
|
|
55634
55664
|
}
|
|
55635
55665
|
function resolveLocalSandboxBuildTarget() {
|
|
55636
|
-
const moduleDir = typeof
|
|
55666
|
+
const moduleDir = typeof import_meta4?.url === "string" ? (0, import_path6.dirname)((0, import_url2.fileURLToPath)(import_meta4.url)) : typeof __dirname === "string" ? __dirname : process.cwd();
|
|
55637
55667
|
const candidates = [
|
|
55638
55668
|
{
|
|
55639
|
-
dockerfile: (0,
|
|
55640
|
-
contextDir: (0,
|
|
55669
|
+
dockerfile: (0, import_path6.resolve)(process.cwd(), "packages/sandbox-runtime/docker/sandbox/Dockerfile"),
|
|
55670
|
+
contextDir: (0, import_path6.resolve)(process.cwd(), "packages/sandbox-runtime")
|
|
55641
55671
|
},
|
|
55642
55672
|
{
|
|
55643
|
-
dockerfile: (0,
|
|
55644
|
-
contextDir: (0,
|
|
55673
|
+
dockerfile: (0, import_path6.resolve)(process.cwd(), "cli/docker/sandbox/Dockerfile"),
|
|
55674
|
+
contextDir: (0, import_path6.resolve)(process.cwd(), "cli")
|
|
55645
55675
|
},
|
|
55646
55676
|
{
|
|
55647
|
-
dockerfile: (0,
|
|
55677
|
+
dockerfile: (0, import_path6.resolve)(process.cwd(), "docker/sandbox/Dockerfile"),
|
|
55648
55678
|
contextDir: process.cwd()
|
|
55649
55679
|
},
|
|
55650
55680
|
{
|
|
55651
|
-
dockerfile: (0,
|
|
55652
|
-
contextDir: (0,
|
|
55681
|
+
dockerfile: (0, import_path6.resolve)(moduleDir, "../docker/sandbox/Dockerfile"),
|
|
55682
|
+
contextDir: (0, import_path6.resolve)(moduleDir, "..")
|
|
55653
55683
|
},
|
|
55654
55684
|
{
|
|
55655
|
-
dockerfile: (0,
|
|
55656
|
-
contextDir: (0,
|
|
55685
|
+
dockerfile: (0, import_path6.resolve)(moduleDir, "../../docker/sandbox/Dockerfile"),
|
|
55686
|
+
contextDir: (0, import_path6.resolve)(moduleDir, "../..")
|
|
55657
55687
|
}
|
|
55658
55688
|
];
|
|
55659
55689
|
return candidates.find((candidate) => (0, import_fs5.existsSync)(candidate.dockerfile));
|
|
@@ -55661,15 +55691,15 @@ function resolveLocalSandboxBuildTarget() {
|
|
|
55661
55691
|
function getSandboxRuntimeDependencyPaths(target) {
|
|
55662
55692
|
return [
|
|
55663
55693
|
target.dockerfile,
|
|
55664
|
-
(0,
|
|
55665
|
-
(0,
|
|
55666
|
-
(0,
|
|
55667
|
-
(0,
|
|
55668
|
-
(0,
|
|
55669
|
-
].filter((
|
|
55694
|
+
(0, import_path6.resolve)(target.contextDir, "docker/sandbox/entrypoint.sh"),
|
|
55695
|
+
(0, import_path6.resolve)(target.contextDir, "src/sandbox/proxy-entry.ts"),
|
|
55696
|
+
(0, import_path6.resolve)(target.contextDir, "src/sandbox/proxy.ts"),
|
|
55697
|
+
(0, import_path6.resolve)(target.contextDir, "src/sandbox/twins.ts"),
|
|
55698
|
+
(0, import_path6.resolve)(target.contextDir, "src/sandbox/certs.ts")
|
|
55699
|
+
].filter((path2) => (0, import_fs5.existsSync)(path2));
|
|
55670
55700
|
}
|
|
55671
55701
|
function getNewestSandboxRuntimeMtimeMs(target) {
|
|
55672
|
-
return getSandboxRuntimeDependencyPaths(target).map((
|
|
55702
|
+
return getSandboxRuntimeDependencyPaths(target).map((path2) => (0, import_fs5.statSync)(path2).mtimeMs).reduce((max, mtimeMs) => Math.max(max, mtimeMs), 0);
|
|
55673
55703
|
}
|
|
55674
55704
|
function getLocalImageCreatedAtMs(image) {
|
|
55675
55705
|
try {
|
|
@@ -55766,8 +55796,8 @@ async function ensureSandboxImage(image, openclawVersion) {
|
|
|
55766
55796
|
}
|
|
55767
55797
|
function launchSandbox(config2) {
|
|
55768
55798
|
const image = config2.image ?? DEFAULT_SANDBOX_IMAGE;
|
|
55769
|
-
const artifactsDir = (0, import_fs5.mkdtempSync)((0,
|
|
55770
|
-
const proxyEventsHostPath = (0,
|
|
55799
|
+
const artifactsDir = (0, import_fs5.mkdtempSync)((0, import_path6.join)((0, import_os4.tmpdir)(), "archal-sandbox-"));
|
|
55800
|
+
const proxyEventsHostPath = (0, import_path6.join)(artifactsDir, "proxy-events.ndjson");
|
|
55771
55801
|
const proxyEventsContainerPath = "/archal-artifacts/proxy-events.ndjson";
|
|
55772
55802
|
const mounts = [];
|
|
55773
55803
|
mounts.push("-v", `${artifactsDir}:/archal-artifacts`);
|
|
@@ -55868,9 +55898,9 @@ function spawnWithTimeout2(command, args, timeoutMs, artifacts) {
|
|
|
55868
55898
|
});
|
|
55869
55899
|
});
|
|
55870
55900
|
}
|
|
55871
|
-
function readProxyEvents(
|
|
55901
|
+
function readProxyEvents(path2) {
|
|
55872
55902
|
try {
|
|
55873
|
-
const raw = (0, import_fs5.readFileSync)(
|
|
55903
|
+
const raw = (0, import_fs5.readFileSync)(path2, "utf8").trim();
|
|
55874
55904
|
if (!raw) return [];
|
|
55875
55905
|
return raw.split("\n").map((line) => {
|
|
55876
55906
|
try {
|
|
@@ -56072,7 +56102,7 @@ function writeMountedConfigFiles(dir, cloudTwinUrls, authToken, caPath) {
|
|
|
56072
56102
|
example: 'mcp__github__list_issues -> POST github-url/tools/call with { "name": "list_issues", "arguments": {} }'
|
|
56073
56103
|
}
|
|
56074
56104
|
};
|
|
56075
|
-
(0, import_fs3.writeFileSync)((0,
|
|
56105
|
+
(0, import_fs3.writeFileSync)((0, import_path4.join)(dir, "rest-config.json"), JSON.stringify(restConfig, null, 2) + "\n", "utf-8");
|
|
56076
56106
|
const mcpServers = {};
|
|
56077
56107
|
for (const [twinName, baseUrl] of Object.entries(cloudTwinUrls)) {
|
|
56078
56108
|
const trimmed = baseUrl.trim().replace(/\/+$/, "");
|
|
@@ -56082,9 +56112,9 @@ function writeMountedConfigFiles(dir, cloudTwinUrls, authToken, caPath) {
|
|
|
56082
56112
|
headers: { Authorization: `Bearer ${authToken}` }
|
|
56083
56113
|
};
|
|
56084
56114
|
}
|
|
56085
|
-
(0, import_fs3.writeFileSync)((0,
|
|
56086
|
-
(0, import_fs3.writeFileSync)((0,
|
|
56087
|
-
(0, import_fs3.writeFileSync)((0,
|
|
56115
|
+
(0, import_fs3.writeFileSync)((0, import_path4.join)(dir, "mcp-config.json"), JSON.stringify({ mcpServers }, null, 2) + "\n", "utf-8");
|
|
56116
|
+
(0, import_fs3.writeFileSync)((0, import_path4.join)(dir, "mcp-servers.json"), JSON.stringify(mcpServers), "utf-8");
|
|
56117
|
+
(0, import_fs3.writeFileSync)((0, import_path4.join)(dir, "ca.crt"), (0, import_fs3.readFileSync)(caPath, "utf-8"), "utf-8");
|
|
56088
56118
|
}
|
|
56089
56119
|
async function ensurePreparedImage(repoPath, dockerfilePath, image, timeoutMs) {
|
|
56090
56120
|
const buildArgs = ["build", "-f", dockerfilePath, "-t", image, repoPath];
|
|
@@ -56107,12 +56137,12 @@ async function cleanupDockerImage(imageName) {
|
|
|
56107
56137
|
await runDockerCommand(["image", "rm", "-f", imageName], 1e4);
|
|
56108
56138
|
}
|
|
56109
56139
|
async function buildDockerHarnessImage(repoPath, dockerfilePath, timeoutMs) {
|
|
56110
|
-
const resolvedRepoPath = (0,
|
|
56140
|
+
const resolvedRepoPath = (0, import_path4.resolve)(repoPath);
|
|
56111
56141
|
const dockerIdSuffix = `${Date.now().toString(36)}-${process.pid}`;
|
|
56112
56142
|
const imageName = `archal/harness-${dockerIdSuffix}`;
|
|
56113
|
-
const buildDir = (0, import_fs3.mkdtempSync)((0,
|
|
56143
|
+
const buildDir = (0, import_fs3.mkdtempSync)((0, import_path4.join)((0, import_os2.tmpdir)(), "archal-harness-build-"));
|
|
56114
56144
|
try {
|
|
56115
|
-
const generatedDockerfilePath = (0,
|
|
56145
|
+
const generatedDockerfilePath = (0, import_path4.join)(buildDir, "Dockerfile.generated");
|
|
56116
56146
|
let dockerfile;
|
|
56117
56147
|
try {
|
|
56118
56148
|
dockerfile = resolveDockerfile(resolvedRepoPath, {
|
|
@@ -56157,9 +56187,9 @@ async function runDockerHarness(config2) {
|
|
|
56157
56187
|
"Install Docker Desktop or Docker Engine before using the Docker harness."
|
|
56158
56188
|
));
|
|
56159
56189
|
}
|
|
56160
|
-
const repoPath = (0,
|
|
56161
|
-
const runDir = (0, import_fs3.mkdtempSync)((0,
|
|
56162
|
-
const generatedDockerfilePath = (0,
|
|
56190
|
+
const repoPath = (0, import_path4.resolve)(config2.repoPath);
|
|
56191
|
+
const runDir = (0, import_fs3.mkdtempSync)((0, import_path4.join)((0, import_os2.tmpdir)(), "archal-harness-"));
|
|
56192
|
+
const generatedDockerfilePath = (0, import_path4.join)(runDir, "Dockerfile.generated");
|
|
56163
56193
|
const dockerIdSuffix = `${Date.now().toString(36)}-${process.pid}`;
|
|
56164
56194
|
const imageName = config2.prebuiltImage ?? `archal/harness-${dockerIdSuffix}`;
|
|
56165
56195
|
const containerName = `archal-harness-${dockerIdSuffix}`;
|
|
@@ -56208,23 +56238,23 @@ async function runDockerHarness(config2) {
|
|
|
56208
56238
|
return fail(stageError("Docker harness attach failed", reason));
|
|
56209
56239
|
}
|
|
56210
56240
|
try {
|
|
56211
|
-
const mountedConfigDir = (0,
|
|
56241
|
+
const mountedConfigDir = (0, import_path4.join)(runDir, "out");
|
|
56212
56242
|
writeMountedConfigFiles(mountedConfigDir, config2.cloudTwinUrls, config2.authToken, ca.certPath);
|
|
56213
56243
|
const env = buildContainerEnv(config2, proxy.port);
|
|
56214
|
-
env["ARCHAL_MCP_SERVERS"] = (0, import_fs3.readFileSync)((0,
|
|
56244
|
+
env["ARCHAL_MCP_SERVERS"] = (0, import_fs3.readFileSync)((0, import_path4.join)(mountedConfigDir, "mcp-servers.json"), "utf-8");
|
|
56215
56245
|
const envFileLines = [];
|
|
56216
56246
|
let multiLineIdx = 0;
|
|
56217
56247
|
for (const [key, value] of Object.entries(env)) {
|
|
56218
56248
|
if (value.includes("\n")) {
|
|
56219
56249
|
const filename = `_env_${multiLineIdx++}_${key.toLowerCase()}`;
|
|
56220
|
-
(0, import_fs3.writeFileSync)((0,
|
|
56250
|
+
(0, import_fs3.writeFileSync)((0, import_path4.join)(mountedConfigDir, filename), value, { encoding: "utf-8", mode: 384 });
|
|
56221
56251
|
envFileLines.push(`${key}_FILE=${OUTPUT_DIR_IN_CONTAINER}/${filename}`);
|
|
56222
56252
|
envFileLines.push(`${key}=${OUTPUT_DIR_IN_CONTAINER}/${filename}`);
|
|
56223
56253
|
} else {
|
|
56224
56254
|
envFileLines.push(`${key}=${value}`);
|
|
56225
56255
|
}
|
|
56226
56256
|
}
|
|
56227
|
-
const envFilePath = (0,
|
|
56257
|
+
const envFilePath = (0, import_path4.join)(runDir, ".env");
|
|
56228
56258
|
(0, import_fs3.writeFileSync)(envFilePath, envFileLines.join("\n") + "\n", { encoding: "utf-8", mode: 384 });
|
|
56229
56259
|
const args = [
|
|
56230
56260
|
"run",
|
|
@@ -56300,7 +56330,7 @@ async function runDockerHarness(config2) {
|
|
|
56300
56330
|
} catch {
|
|
56301
56331
|
}
|
|
56302
56332
|
}
|
|
56303
|
-
const envPath = (0,
|
|
56333
|
+
const envPath = (0, import_path4.join)(runDir, ".env");
|
|
56304
56334
|
try {
|
|
56305
56335
|
if ((0, import_fs3.existsSync)(envPath)) {
|
|
56306
56336
|
const size = (0, import_fs3.statSync)(envPath).size;
|
|
@@ -56352,7 +56382,7 @@ async function runLocalProxy(config2, task, canaryFiles) {
|
|
|
56352
56382
|
if (hostsEntries) {
|
|
56353
56383
|
status("NOTE: For full interception in local mode, add these to /etc/hosts:\n" + hostsEntries);
|
|
56354
56384
|
}
|
|
56355
|
-
const workspace = config2.workspacePath ?? (0,
|
|
56385
|
+
const workspace = config2.workspacePath ?? (0, import_path7.join)(process.env["HOME"] ?? "/root", ".openclaw");
|
|
56356
56386
|
const noProxyHosts = "127.0.0.1,localhost,.archal.ai";
|
|
56357
56387
|
const env = {
|
|
56358
56388
|
...process.env,
|
|
@@ -56387,13 +56417,13 @@ async function runLocalProxy(config2, task, canaryFiles) {
|
|
|
56387
56417
|
}
|
|
56388
56418
|
}
|
|
56389
56419
|
function writeCanaryFiles(workspace, canaryFiles) {
|
|
56390
|
-
const resolvedWorkspace = (0,
|
|
56420
|
+
const resolvedWorkspace = (0, import_path7.resolve)(workspace);
|
|
56391
56421
|
for (const [relativePath, content] of Object.entries(canaryFiles)) {
|
|
56392
|
-
const filePath = (0,
|
|
56393
|
-
if (filePath !== resolvedWorkspace && !filePath.startsWith(resolvedWorkspace +
|
|
56422
|
+
const filePath = (0, import_path7.resolve)(workspace, relativePath);
|
|
56423
|
+
if (filePath !== resolvedWorkspace && !filePath.startsWith(resolvedWorkspace + import_path7.sep)) {
|
|
56394
56424
|
throw new Error(`Canary path escapes sandbox root: ${relativePath}`);
|
|
56395
56425
|
}
|
|
56396
|
-
(0, import_fs6.mkdirSync)((0,
|
|
56426
|
+
(0, import_fs6.mkdirSync)((0, import_path7.dirname)(filePath), { recursive: true });
|
|
56397
56427
|
(0, import_fs6.writeFileSync)(filePath, content);
|
|
56398
56428
|
}
|
|
56399
56429
|
}
|
|
@@ -56462,9 +56492,9 @@ function spawnAgent(workspace, task, env, timeoutMs) {
|
|
|
56462
56492
|
});
|
|
56463
56493
|
}
|
|
56464
56494
|
function confinePath(root, relativePath) {
|
|
56465
|
-
const resolvedRoot = (0,
|
|
56466
|
-
const resolved = (0,
|
|
56467
|
-
if (resolved !== resolvedRoot && !resolved.startsWith(resolvedRoot +
|
|
56495
|
+
const resolvedRoot = (0, import_path8.resolve)(root);
|
|
56496
|
+
const resolved = (0, import_path8.resolve)(root, relativePath);
|
|
56497
|
+
if (resolved !== resolvedRoot && !resolved.startsWith(resolvedRoot + import_path8.sep)) {
|
|
56468
56498
|
throw new Error(`Canary path escapes sandbox root: ${relativePath}`);
|
|
56469
56499
|
}
|
|
56470
56500
|
return resolved;
|
|
@@ -56727,19 +56757,19 @@ async function runDockerSandbox(config2) {
|
|
|
56727
56757
|
error: result.timedOut ? `Sandbox timed out after ${Math.round(config2.timeoutMs / 1e3)}s` : result.exitCode !== 0 ? `Sandbox exited with code ${result.exitCode}` : void 0
|
|
56728
56758
|
};
|
|
56729
56759
|
}
|
|
56730
|
-
var import_fs2,
|
|
56760
|
+
var import_fs2, import_path3, import_fs3, import_os2, import_path4, import_crypto3, import_fs4, import_path5, import_os3, import_http, import_https, import_tls, import_net, import_child_process2, import_fs5, import_os4, import_path6, import_url2, import_child_process3, import_child_process4, import_fs6, import_path7, import_path8, import_meta4, DockerfileError, NODE_SCRIPT_PRIORITY, CA_COMMON_NAME, CERT_VALIDITY_DAYS, domainCertCache, REQUEST_BODY_PREVIEW_HEAD_LIMIT, REQUEST_BODY_PREVIEW_TAIL_LIMIT, GITHUB_RESPONSE_HEADERS, PASSTHROUGH_CONNECT_TIMEOUT_MS, TWIN_DOMAINS, DEFAULT_SANDBOX_IMAGE, VERSIONED_SANDBOX_TAG_PREFIX, MAX_OUTPUT_BYTES, KILL_GRACE_MS, MAX_OUTPUT_BYTES2, OUTPUT_DIR_IN_CONTAINER, HOST_GATEWAY_NAME, BUILD_TIMEOUT_CAP_MS, SANDBOX_CANARY_TAG, CANARY_LEAK_ERROR_CODE, CANARY_VALUE_PATTERN, SANDBOX_FILES_BLOCK_PATTERN, SNIPPET_RADIUS, DOCKER_IMAGE_NAME;
|
|
56731
56761
|
var init_dist6 = __esm({
|
|
56732
56762
|
"../packages/sandbox-runtime/dist/index.js"() {
|
|
56733
56763
|
"use strict";
|
|
56734
56764
|
import_fs2 = require("fs");
|
|
56735
|
-
|
|
56765
|
+
import_path3 = require("path");
|
|
56736
56766
|
import_fs3 = require("fs");
|
|
56737
56767
|
import_os2 = require("os");
|
|
56738
|
-
|
|
56768
|
+
import_path4 = require("path");
|
|
56739
56769
|
init_dist2();
|
|
56740
56770
|
import_crypto3 = require("crypto");
|
|
56741
56771
|
import_fs4 = require("fs");
|
|
56742
|
-
|
|
56772
|
+
import_path5 = require("path");
|
|
56743
56773
|
import_os3 = require("os");
|
|
56744
56774
|
import_http = require("http");
|
|
56745
56775
|
import_https = require("https");
|
|
@@ -56748,15 +56778,15 @@ var init_dist6 = __esm({
|
|
|
56748
56778
|
import_child_process2 = require("child_process");
|
|
56749
56779
|
import_fs5 = require("fs");
|
|
56750
56780
|
import_os4 = require("os");
|
|
56751
|
-
|
|
56752
|
-
|
|
56781
|
+
import_path6 = require("path");
|
|
56782
|
+
import_url2 = require("url");
|
|
56753
56783
|
import_child_process3 = require("child_process");
|
|
56754
56784
|
import_child_process4 = require("child_process");
|
|
56755
56785
|
import_fs6 = require("fs");
|
|
56756
|
-
import_path6 = require("path");
|
|
56757
56786
|
import_path7 = require("path");
|
|
56787
|
+
import_path8 = require("path");
|
|
56758
56788
|
init_dist4();
|
|
56759
|
-
|
|
56789
|
+
import_meta4 = {};
|
|
56760
56790
|
DockerfileError = class extends Error {
|
|
56761
56791
|
kind;
|
|
56762
56792
|
suggestion;
|
|
@@ -56822,13 +56852,13 @@ __export(archal_file_exports, {
|
|
|
56822
56852
|
function loadArchalFile(explicitPath) {
|
|
56823
56853
|
let filePath;
|
|
56824
56854
|
if (explicitPath) {
|
|
56825
|
-
filePath = (0,
|
|
56826
|
-
if (!(0,
|
|
56855
|
+
filePath = (0, import_node_path22.resolve)(explicitPath);
|
|
56856
|
+
if (!(0, import_node_fs26.existsSync)(filePath)) throw new Error(`Config file not found: ${filePath}`);
|
|
56827
56857
|
} else {
|
|
56828
|
-
filePath = (0,
|
|
56829
|
-
if (!(0,
|
|
56858
|
+
filePath = (0, import_node_path22.resolve)(ARCHAL_FILENAME);
|
|
56859
|
+
if (!(0, import_node_fs26.existsSync)(filePath)) return null;
|
|
56830
56860
|
}
|
|
56831
|
-
const raw = (0,
|
|
56861
|
+
const raw = (0, import_node_fs26.readFileSync)(filePath, "utf-8").trim();
|
|
56832
56862
|
if (!raw) throw new Error(`Config file is empty: ${filePath}`);
|
|
56833
56863
|
let parsed;
|
|
56834
56864
|
try {
|
|
@@ -56860,14 +56890,14 @@ function loadArchalFile(explicitPath) {
|
|
|
56860
56890
|
if (typeof c["model"] === "string") r.model = c["model"].trim() || void 0;
|
|
56861
56891
|
if (typeof c["runs"] === "number" && Number.isInteger(c["runs"]) && c["runs"] > 0) r.runs = c["runs"];
|
|
56862
56892
|
if (typeof c["timeout"] === "number" && c["timeout"] > 0) r.timeout = c["timeout"];
|
|
56863
|
-
return { config: r, configDir: (0,
|
|
56893
|
+
return { config: r, configDir: (0, import_node_path22.dirname)(filePath) };
|
|
56864
56894
|
}
|
|
56865
|
-
var
|
|
56895
|
+
var import_node_fs26, import_node_path22, ARCHAL_FILENAME;
|
|
56866
56896
|
var init_archal_file = __esm({
|
|
56867
56897
|
"src/config/archal-file.ts"() {
|
|
56868
56898
|
"use strict";
|
|
56869
|
-
|
|
56870
|
-
|
|
56899
|
+
import_node_fs26 = require("fs");
|
|
56900
|
+
import_node_path22 = require("path");
|
|
56871
56901
|
ARCHAL_FILENAME = ".archal.json";
|
|
56872
56902
|
}
|
|
56873
56903
|
});
|
|
@@ -56926,7 +56956,7 @@ function detectTwinsFromSource(source) {
|
|
|
56926
56956
|
function detectTwinsFromPackageJson(packageJsonPath) {
|
|
56927
56957
|
const twins = /* @__PURE__ */ new Set();
|
|
56928
56958
|
try {
|
|
56929
|
-
const pkg = JSON.parse((0,
|
|
56959
|
+
const pkg = JSON.parse((0, import_node_fs27.readFileSync)(packageJsonPath, "utf-8"));
|
|
56930
56960
|
for (const depName of Object.keys({ ...pkg.dependencies, ...pkg.devDependencies })) {
|
|
56931
56961
|
const twinName = PACKAGE_TO_TWIN[depName];
|
|
56932
56962
|
if (twinName) twins.add(twinName);
|
|
@@ -56938,26 +56968,26 @@ function detectTwinsFromPackageJson(packageJsonPath) {
|
|
|
56938
56968
|
function detectTwinsFromHarnessDir(harnessDir) {
|
|
56939
56969
|
const twins = /* @__PURE__ */ new Set();
|
|
56940
56970
|
for (const candidate of ENTRY_CANDIDATES) {
|
|
56941
|
-
const filePath = (0,
|
|
56942
|
-
if (!(0,
|
|
56971
|
+
const filePath = (0, import_node_path23.resolve)(harnessDir, candidate);
|
|
56972
|
+
if (!(0, import_node_fs27.existsSync)(filePath)) continue;
|
|
56943
56973
|
try {
|
|
56944
|
-
for (const twin of detectTwinsFromSource((0,
|
|
56974
|
+
for (const twin of detectTwinsFromSource((0, import_node_fs27.readFileSync)(filePath, "utf-8"))) {
|
|
56945
56975
|
twins.add(twin);
|
|
56946
56976
|
}
|
|
56947
56977
|
} catch {
|
|
56948
56978
|
}
|
|
56949
56979
|
}
|
|
56950
|
-
for (const twin of detectTwinsFromPackageJson((0,
|
|
56980
|
+
for (const twin of detectTwinsFromPackageJson((0, import_node_path23.resolve)(harnessDir, "package.json"))) {
|
|
56951
56981
|
twins.add(twin);
|
|
56952
56982
|
}
|
|
56953
56983
|
return [...twins].sort();
|
|
56954
56984
|
}
|
|
56955
|
-
var
|
|
56985
|
+
var import_node_fs27, import_node_path23, ENTRY_CANDIDATES, IMPORT_PATTERNS, ENV_VAR_PATTERN;
|
|
56956
56986
|
var init_harness_import_detector = __esm({
|
|
56957
56987
|
"src/runner/harness-import-detector.ts"() {
|
|
56958
56988
|
"use strict";
|
|
56959
|
-
|
|
56960
|
-
|
|
56989
|
+
import_node_fs27 = require("fs");
|
|
56990
|
+
import_node_path23 = require("path");
|
|
56961
56991
|
init_package_twin_map();
|
|
56962
56992
|
ENTRY_CANDIDATES = [
|
|
56963
56993
|
"harness.ts",
|
|
@@ -56983,7 +57013,7 @@ __export(twins_exports, {
|
|
|
56983
57013
|
listTwinCatalog: () => listTwinCatalog
|
|
56984
57014
|
});
|
|
56985
57015
|
function hasFidelityBaseline(twinName) {
|
|
56986
|
-
return findFirstExistingLocalTwinAssetPath(
|
|
57016
|
+
return findFirstExistingLocalTwinAssetPath(import_meta5.url, twinName, "fidelity.json") !== null;
|
|
56987
57017
|
}
|
|
56988
57018
|
function writeLocalTwinCatalogJson() {
|
|
56989
57019
|
process.stdout.write(JSON.stringify(
|
|
@@ -57051,7 +57081,7 @@ async function listTwinCatalog(json2) {
|
|
|
57051
57081
|
table(["Name", "Tools", "Description", "Status"], rows);
|
|
57052
57082
|
success2(twinCatalogSummary(creds));
|
|
57053
57083
|
}
|
|
57054
|
-
var
|
|
57084
|
+
var import_meta5, KNOWN_TWINS;
|
|
57055
57085
|
var init_twins = __esm({
|
|
57056
57086
|
"src/commands/twins.ts"() {
|
|
57057
57087
|
"use strict";
|
|
@@ -57059,7 +57089,7 @@ var init_twins = __esm({
|
|
|
57059
57089
|
init_auth();
|
|
57060
57090
|
init_api_client();
|
|
57061
57091
|
init_bundled_assets();
|
|
57062
|
-
|
|
57092
|
+
import_meta5 = {};
|
|
57063
57093
|
KNOWN_TWINS = [
|
|
57064
57094
|
{ name: "github", description: "GitHub digital twin" },
|
|
57065
57095
|
{ name: "slack", description: "Slack digital twin" },
|
|
@@ -57096,8 +57126,8 @@ init_dist2();
|
|
|
57096
57126
|
// src/commands/run.ts
|
|
57097
57127
|
init_dist2();
|
|
57098
57128
|
var import_node_crypto7 = require("crypto");
|
|
57099
|
-
var
|
|
57100
|
-
var
|
|
57129
|
+
var import_node_fs28 = require("fs");
|
|
57130
|
+
var import_node_path24 = require("path");
|
|
57101
57131
|
|
|
57102
57132
|
// src/commands/task-scenario.ts
|
|
57103
57133
|
var import_node_fs = require("fs");
|
|
@@ -57456,17 +57486,17 @@ function isLoopbackUrl(rawUrl) {
|
|
|
57456
57486
|
function isNonLocalEndpoint(rawUrl) {
|
|
57457
57487
|
return !isLoopbackUrl(rawUrl);
|
|
57458
57488
|
}
|
|
57459
|
-
function parseUrlOverridesFile(
|
|
57460
|
-
if (!
|
|
57461
|
-
if (!(0, import_node_fs4.existsSync)(
|
|
57462
|
-
throw new Error(`${label.fileNotFound}: ${
|
|
57489
|
+
function parseUrlOverridesFile(path2, label) {
|
|
57490
|
+
if (!path2) return void 0;
|
|
57491
|
+
if (!(0, import_node_fs4.existsSync)(path2)) {
|
|
57492
|
+
throw new Error(`${label.fileNotFound}: ${path2}`);
|
|
57463
57493
|
}
|
|
57464
|
-
const raw = (0, import_node_fs4.readFileSync)(
|
|
57494
|
+
const raw = (0, import_node_fs4.readFileSync)(path2, "utf-8");
|
|
57465
57495
|
const parsed = JSON.parse(raw);
|
|
57466
57496
|
const overrides = {};
|
|
57467
57497
|
for (const [key, value] of Object.entries(parsed)) {
|
|
57468
57498
|
if (typeof value !== "string" || !value.trim()) {
|
|
57469
|
-
throw new Error(`${label.invalidEntry} for "${key}" in ${
|
|
57499
|
+
throw new Error(`${label.invalidEntry} for "${key}" in ${path2}`);
|
|
57470
57500
|
}
|
|
57471
57501
|
const trimmed = value.trim();
|
|
57472
57502
|
try {
|
|
@@ -57475,21 +57505,21 @@ function parseUrlOverridesFile(path, label) {
|
|
|
57475
57505
|
throw new Error("missing protocol");
|
|
57476
57506
|
}
|
|
57477
57507
|
} catch {
|
|
57478
|
-
throw new Error(`${label.invalidUrl} "${key}" in ${
|
|
57508
|
+
throw new Error(`${label.invalidUrl} "${key}" in ${path2}: ${trimmed}`);
|
|
57479
57509
|
}
|
|
57480
57510
|
overrides[key] = trimmed;
|
|
57481
57511
|
}
|
|
57482
57512
|
return overrides;
|
|
57483
57513
|
}
|
|
57484
|
-
function parseRemoteTwinUrlOverrides(
|
|
57485
|
-
return parseUrlOverridesFile(
|
|
57514
|
+
function parseRemoteTwinUrlOverrides(path2) {
|
|
57515
|
+
return parseUrlOverridesFile(path2, {
|
|
57486
57516
|
fileNotFound: "Twin URL overrides file not found",
|
|
57487
57517
|
invalidEntry: "Invalid twin URL override",
|
|
57488
57518
|
invalidUrl: "Invalid URL for twin"
|
|
57489
57519
|
});
|
|
57490
57520
|
}
|
|
57491
|
-
function parseApiBaseUrlOverrides(
|
|
57492
|
-
return parseUrlOverridesFile(
|
|
57521
|
+
function parseApiBaseUrlOverrides(path2) {
|
|
57522
|
+
return parseUrlOverridesFile(path2, {
|
|
57493
57523
|
fileNotFound: "API base URL overrides file not found",
|
|
57494
57524
|
invalidEntry: "Invalid API base URL override",
|
|
57495
57525
|
invalidUrl: "Invalid API base URL for"
|
|
@@ -60201,7 +60231,7 @@ var import_node_fs9 = require("fs");
|
|
|
60201
60231
|
var import_node_path7 = require("path");
|
|
60202
60232
|
init_dist2();
|
|
60203
60233
|
init_bundled_assets();
|
|
60204
|
-
var
|
|
60234
|
+
var import_meta3 = {};
|
|
60205
60235
|
function isIdKeyedCollection(value) {
|
|
60206
60236
|
if (!Array.isArray(value)) return false;
|
|
60207
60237
|
if (value.length === 0) return false;
|
|
@@ -60439,7 +60469,7 @@ function normalizeSeedState(raw) {
|
|
|
60439
60469
|
return Object.keys(normalized).length > 0 ? normalized : null;
|
|
60440
60470
|
}
|
|
60441
60471
|
function loadBaseSeedFromDisk(twinName, seedName) {
|
|
60442
|
-
for (const seedRoot of resolveLocalTwinAssetCandidates(
|
|
60472
|
+
for (const seedRoot of resolveLocalTwinAssetCandidates(import_meta3.url, twinName, "seeds")) {
|
|
60443
60473
|
const seedState = loadSeedStateFromPath(seedRoot, seedName);
|
|
60444
60474
|
if (seedState) {
|
|
60445
60475
|
return seedState;
|
|
@@ -66385,12 +66415,12 @@ function listCommandCandidates(command) {
|
|
|
66385
66415
|
}
|
|
66386
66416
|
return [...variants];
|
|
66387
66417
|
}
|
|
66388
|
-
function isExecutable(
|
|
66418
|
+
function isExecutable(path2) {
|
|
66389
66419
|
try {
|
|
66390
|
-
(0, import_node_fs18.accessSync)(
|
|
66420
|
+
(0, import_node_fs18.accessSync)(path2, import_node_fs18.constants.X_OK);
|
|
66391
66421
|
return true;
|
|
66392
66422
|
} catch {
|
|
66393
|
-
return process.platform === "win32" && (0, import_node_fs18.existsSync)(
|
|
66423
|
+
return process.platform === "win32" && (0, import_node_fs18.existsSync)(path2);
|
|
66394
66424
|
}
|
|
66395
66425
|
}
|
|
66396
66426
|
function isCommandAvailable(command) {
|
|
@@ -66639,6 +66669,83 @@ ${lines.join("\n")}`
|
|
|
66639
66669
|
init_cache();
|
|
66640
66670
|
init_auth();
|
|
66641
66671
|
init_api_client();
|
|
66672
|
+
|
|
66673
|
+
// src/commands/env-session-reuse.ts
|
|
66674
|
+
var import_node_fs20 = require("fs");
|
|
66675
|
+
var import_node_os7 = require("os");
|
|
66676
|
+
var import_node_path16 = require("path");
|
|
66677
|
+
init_auth();
|
|
66678
|
+
var TWIN_SESSION_FILE = (0, import_node_path16.join)((0, import_node_os7.homedir)(), ".archal", "twin-session.json");
|
|
66679
|
+
var LEGACY_SESSION_FILE = (0, import_node_path16.join)((0, import_node_os7.homedir)(), ".archal", "env-session.json");
|
|
66680
|
+
function loadSession() {
|
|
66681
|
+
let filePath = TWIN_SESSION_FILE;
|
|
66682
|
+
if (!(0, import_node_fs20.existsSync)(filePath)) {
|
|
66683
|
+
if ((0, import_node_fs20.existsSync)(LEGACY_SESSION_FILE)) {
|
|
66684
|
+
filePath = LEGACY_SESSION_FILE;
|
|
66685
|
+
} else {
|
|
66686
|
+
return null;
|
|
66687
|
+
}
|
|
66688
|
+
}
|
|
66689
|
+
try {
|
|
66690
|
+
return JSON.parse((0, import_node_fs20.readFileSync)(filePath, "utf8"));
|
|
66691
|
+
} catch {
|
|
66692
|
+
return null;
|
|
66693
|
+
}
|
|
66694
|
+
}
|
|
66695
|
+
function resolveApiBaseUrl() {
|
|
66696
|
+
return getConfiguredApiBaseUrl2() ?? "https://api.archal.ai";
|
|
66697
|
+
}
|
|
66698
|
+
async function tryReuseEnvSession(requiredTwins, credentials) {
|
|
66699
|
+
try {
|
|
66700
|
+
const session = loadSession();
|
|
66701
|
+
if (!session) {
|
|
66702
|
+
return null;
|
|
66703
|
+
}
|
|
66704
|
+
if (!requiredTwins.every((t) => session.twins.includes(t))) {
|
|
66705
|
+
return null;
|
|
66706
|
+
}
|
|
66707
|
+
const missingEndpoints = requiredTwins.filter(
|
|
66708
|
+
(t) => !session.endpoints[t] && !session.apiBaseUrls[t]
|
|
66709
|
+
);
|
|
66710
|
+
if (missingEndpoints.length > 0) {
|
|
66711
|
+
return null;
|
|
66712
|
+
}
|
|
66713
|
+
let apiBase = resolveApiBaseUrl();
|
|
66714
|
+
if (session.apiBaseUrl) {
|
|
66715
|
+
try {
|
|
66716
|
+
const parsed = new URL(session.apiBaseUrl);
|
|
66717
|
+
const isLocalHttp = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1");
|
|
66718
|
+
if (parsed.protocol === "https:" || isLocalHttp) {
|
|
66719
|
+
apiBase = session.apiBaseUrl;
|
|
66720
|
+
}
|
|
66721
|
+
} catch {
|
|
66722
|
+
}
|
|
66723
|
+
}
|
|
66724
|
+
const response = await fetch(`${apiBase}/api/sessions/${session.sessionId}`, {
|
|
66725
|
+
method: "GET",
|
|
66726
|
+
headers: {
|
|
66727
|
+
"Authorization": `Bearer ${credentials.token}`,
|
|
66728
|
+
"Content-Type": "application/json"
|
|
66729
|
+
}
|
|
66730
|
+
});
|
|
66731
|
+
if (!response.ok) {
|
|
66732
|
+
return null;
|
|
66733
|
+
}
|
|
66734
|
+
const data = await response.json();
|
|
66735
|
+
if (data.status !== "ready") {
|
|
66736
|
+
return null;
|
|
66737
|
+
}
|
|
66738
|
+
return {
|
|
66739
|
+
sessionId: session.sessionId,
|
|
66740
|
+
endpoints: session.endpoints,
|
|
66741
|
+
apiBaseUrls: session.apiBaseUrls
|
|
66742
|
+
};
|
|
66743
|
+
} catch {
|
|
66744
|
+
return null;
|
|
66745
|
+
}
|
|
66746
|
+
}
|
|
66747
|
+
|
|
66748
|
+
// src/commands/run.ts
|
|
66642
66749
|
init_errors4();
|
|
66643
66750
|
init_logger();
|
|
66644
66751
|
|
|
@@ -66675,24 +66782,24 @@ async function runShutdownHooks(signal) {
|
|
|
66675
66782
|
init_config();
|
|
66676
66783
|
|
|
66677
66784
|
// src/commands/run-config-resolver.ts
|
|
66678
|
-
var
|
|
66679
|
-
var
|
|
66785
|
+
var import_node_fs22 = require("fs");
|
|
66786
|
+
var import_node_path18 = require("path");
|
|
66680
66787
|
init_config();
|
|
66681
66788
|
|
|
66682
66789
|
// src/commands/openclaw-shared.ts
|
|
66683
|
-
var
|
|
66684
|
-
var
|
|
66685
|
-
var
|
|
66790
|
+
var import_node_fs21 = require("fs");
|
|
66791
|
+
var import_node_os8 = require("os");
|
|
66792
|
+
var import_node_path17 = require("path");
|
|
66686
66793
|
var OPENCLAW_HARNESS_ALIASES = /* @__PURE__ */ new Set(["openclaw", "oc", "nemoclaw", "nemo"]);
|
|
66687
66794
|
function isOpenClawHarnessName(name) {
|
|
66688
66795
|
return OPENCLAW_HARNESS_ALIASES.has(name.trim().toLowerCase());
|
|
66689
66796
|
}
|
|
66690
|
-
function resolveDefaultOpenClawHome(opts, homeDir = (0,
|
|
66797
|
+
function resolveDefaultOpenClawHome(opts, homeDir = (0, import_node_os8.homedir)()) {
|
|
66691
66798
|
if (opts.openclawHome?.trim() || opts.workspace?.trim() || opts.openclawConfig?.trim()) {
|
|
66692
66799
|
return void 0;
|
|
66693
66800
|
}
|
|
66694
|
-
const defaultHome = (0,
|
|
66695
|
-
return (0,
|
|
66801
|
+
const defaultHome = (0, import_node_path17.join)(homeDir, ".openclaw");
|
|
66802
|
+
return (0, import_node_fs21.existsSync)(defaultHome) ? defaultHome : void 0;
|
|
66696
66803
|
}
|
|
66697
66804
|
function detectApiKeyProvider(key) {
|
|
66698
66805
|
if (!key) return "unknown";
|
|
@@ -66772,7 +66879,7 @@ function resolveFromCandidates(candidates, fallback) {
|
|
|
66772
66879
|
return fallback;
|
|
66773
66880
|
}
|
|
66774
66881
|
function loadProjectConfigForScenario(scenarioPath) {
|
|
66775
|
-
const root = findNearestProjectRoot((0,
|
|
66882
|
+
const root = findNearestProjectRoot((0, import_node_path18.dirname)((0, import_node_path18.resolve)(scenarioPath)), process.cwd());
|
|
66776
66883
|
if (!root) {
|
|
66777
66884
|
return {
|
|
66778
66885
|
root: null,
|
|
@@ -66782,7 +66889,7 @@ function loadProjectConfigForScenario(scenarioPath) {
|
|
|
66782
66889
|
}
|
|
66783
66890
|
return {
|
|
66784
66891
|
root,
|
|
66785
|
-
configPath: (0,
|
|
66892
|
+
configPath: (0, import_node_path18.join)(root, ".archal.json"),
|
|
66786
66893
|
config: loadProjectConfig(root)
|
|
66787
66894
|
};
|
|
66788
66895
|
}
|
|
@@ -67203,7 +67310,7 @@ function resolveRunConfigWithSources(scenarioPath, opts, sources, preloaded) {
|
|
|
67203
67310
|
{ value: void 0, source: "unset", detail: "(not set)" }
|
|
67204
67311
|
);
|
|
67205
67312
|
return {
|
|
67206
|
-
scenarioPath: (0,
|
|
67313
|
+
scenarioPath: (0, import_node_path18.resolve)(scenarioPath),
|
|
67207
67314
|
projectRoot: project.root,
|
|
67208
67315
|
projectConfigPath: project.configPath,
|
|
67209
67316
|
invalidExplicitRuns,
|
|
@@ -67240,13 +67347,13 @@ function applyResolvedRunConfigToOptions(opts, resolved) {
|
|
|
67240
67347
|
function findNearestProjectRoot(...startPaths) {
|
|
67241
67348
|
for (const start of startPaths) {
|
|
67242
67349
|
if (!start || !start.trim()) continue;
|
|
67243
|
-
let current = (0,
|
|
67350
|
+
let current = (0, import_node_path18.resolve)(start);
|
|
67244
67351
|
while (true) {
|
|
67245
|
-
const candidate = (0,
|
|
67246
|
-
if ((0,
|
|
67352
|
+
const candidate = (0, import_node_path18.join)(current, ".archal.json");
|
|
67353
|
+
if ((0, import_node_fs22.existsSync)(candidate)) {
|
|
67247
67354
|
return current;
|
|
67248
67355
|
}
|
|
67249
|
-
const parent = (0,
|
|
67356
|
+
const parent = (0, import_node_path18.dirname)(current);
|
|
67250
67357
|
if (parent === current) break;
|
|
67251
67358
|
current = parent;
|
|
67252
67359
|
}
|
|
@@ -67255,8 +67362,8 @@ function findNearestProjectRoot(...startPaths) {
|
|
|
67255
67362
|
}
|
|
67256
67363
|
|
|
67257
67364
|
// src/commands/run-session.ts
|
|
67258
|
-
var
|
|
67259
|
-
var
|
|
67365
|
+
var import_node_fs23 = require("fs");
|
|
67366
|
+
var import_node_path19 = require("path");
|
|
67260
67367
|
init_dist2();
|
|
67261
67368
|
init_api_client();
|
|
67262
67369
|
init_auth();
|
|
@@ -67548,9 +67655,9 @@ function writeManagedRunStatus(patch) {
|
|
|
67548
67655
|
if (!statusPath) return;
|
|
67549
67656
|
try {
|
|
67550
67657
|
let existing = {};
|
|
67551
|
-
if ((0,
|
|
67658
|
+
if ((0, import_node_fs23.existsSync)(statusPath)) {
|
|
67552
67659
|
try {
|
|
67553
|
-
const raw = (0,
|
|
67660
|
+
const raw = (0, import_node_fs23.readFileSync)(statusPath, "utf-8");
|
|
67554
67661
|
const parsed = JSON.parse(raw);
|
|
67555
67662
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
67556
67663
|
existing = parsed;
|
|
@@ -67559,8 +67666,8 @@ function writeManagedRunStatus(patch) {
|
|
|
67559
67666
|
}
|
|
67560
67667
|
}
|
|
67561
67668
|
const merged = { ...existing, ...patch, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
67562
|
-
(0,
|
|
67563
|
-
(0,
|
|
67669
|
+
(0, import_node_fs23.mkdirSync)((0, import_node_path19.dirname)(statusPath), { recursive: true });
|
|
67670
|
+
(0, import_node_fs23.writeFileSync)(statusPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
67564
67671
|
} catch {
|
|
67565
67672
|
}
|
|
67566
67673
|
}
|
|
@@ -67578,9 +67685,21 @@ function resolveManagedRunProjectMetadata(opts) {
|
|
|
67578
67685
|
const description = opts?.runProjectDescription?.trim() || process.env["ARCHAL_WEB_RUN_PROJECT_DESCRIPTION"]?.trim();
|
|
67579
67686
|
return { id, name, description };
|
|
67580
67687
|
}
|
|
67688
|
+
function buildRuntimeTwinUrls(sessionId, twins, runtimeBaseUrl) {
|
|
67689
|
+
const base = runtimeBaseUrl.replace(/\/+$/, "");
|
|
67690
|
+
const sessionPath = encodeURIComponent(sessionId);
|
|
67691
|
+
const endpoints = {};
|
|
67692
|
+
const apiBaseUrls = {};
|
|
67693
|
+
for (const twin of twins) {
|
|
67694
|
+
const root = `${base}/runtime/${sessionPath}/${encodeURIComponent(twin)}`;
|
|
67695
|
+
endpoints[twin] = root;
|
|
67696
|
+
apiBaseUrls[twin] = `${root}/api`;
|
|
67697
|
+
}
|
|
67698
|
+
return { endpoints, apiBaseUrls };
|
|
67699
|
+
}
|
|
67581
67700
|
function writeTempJsonMap(filePath, data, context) {
|
|
67582
67701
|
try {
|
|
67583
|
-
(0,
|
|
67702
|
+
(0, import_node_fs23.writeFileSync)(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
67584
67703
|
return { ok: true };
|
|
67585
67704
|
} catch (err) {
|
|
67586
67705
|
const reason = errorMessage(err);
|
|
@@ -67588,17 +67707,17 @@ function writeTempJsonMap(filePath, data, context) {
|
|
|
67588
67707
|
}
|
|
67589
67708
|
}
|
|
67590
67709
|
function cleanupGeneratedSessionMaps(ctx) {
|
|
67591
|
-
if (ctx.generatedTwinUrlMapPath && (0,
|
|
67710
|
+
if (ctx.generatedTwinUrlMapPath && (0, import_node_fs23.existsSync)(ctx.generatedTwinUrlMapPath)) {
|
|
67592
67711
|
try {
|
|
67593
|
-
(0,
|
|
67712
|
+
(0, import_node_fs23.unlinkSync)(ctx.generatedTwinUrlMapPath);
|
|
67594
67713
|
} catch (error49) {
|
|
67595
67714
|
process.stderr.write(`Warning: failed to remove temp twin URL map: ${errorMessage(error49)}
|
|
67596
67715
|
`);
|
|
67597
67716
|
}
|
|
67598
67717
|
}
|
|
67599
|
-
if (ctx.generatedApiBaseUrlMapPath && (0,
|
|
67718
|
+
if (ctx.generatedApiBaseUrlMapPath && (0, import_node_fs23.existsSync)(ctx.generatedApiBaseUrlMapPath)) {
|
|
67600
67719
|
try {
|
|
67601
|
-
(0,
|
|
67720
|
+
(0, import_node_fs23.unlinkSync)(ctx.generatedApiBaseUrlMapPath);
|
|
67602
67721
|
} catch (error49) {
|
|
67603
67722
|
process.stderr.write(`Warning: failed to remove temp API base URL map: ${errorMessage(error49)}
|
|
67604
67723
|
`);
|
|
@@ -67607,6 +67726,9 @@ function cleanupGeneratedSessionMaps(ctx) {
|
|
|
67607
67726
|
}
|
|
67608
67727
|
async function cleanupHostedSession(ctx) {
|
|
67609
67728
|
cleanupGeneratedSessionMaps(ctx);
|
|
67729
|
+
if (ctx.isReusedEnvSession) {
|
|
67730
|
+
return;
|
|
67731
|
+
}
|
|
67610
67732
|
if (!ctx.backendSessionId && ctx.inFlightSessionStart) {
|
|
67611
67733
|
try {
|
|
67612
67734
|
const startResult = await ctx.inFlightSessionStart;
|
|
@@ -67689,8 +67811,8 @@ async function cleanupHostedSession(ctx) {
|
|
|
67689
67811
|
} catch {
|
|
67690
67812
|
}
|
|
67691
67813
|
}
|
|
67692
|
-
(0,
|
|
67693
|
-
(0,
|
|
67814
|
+
(0, import_node_fs23.mkdirSync)((0, import_node_path19.dirname)(ctx.evidenceOutputPath), { recursive: true });
|
|
67815
|
+
(0, import_node_fs23.writeFileSync)(
|
|
67694
67816
|
ctx.evidenceOutputPath,
|
|
67695
67817
|
JSON.stringify(
|
|
67696
67818
|
{
|
|
@@ -67869,35 +67991,35 @@ function mapSessionStartError(sessionResult) {
|
|
|
67869
67991
|
}
|
|
67870
67992
|
|
|
67871
67993
|
// src/commands/run-validation.ts
|
|
67872
|
-
var
|
|
67873
|
-
var
|
|
67994
|
+
var import_node_fs25 = require("fs");
|
|
67995
|
+
var import_node_path21 = require("path");
|
|
67874
67996
|
init_dist2();
|
|
67875
67997
|
init_errors4();
|
|
67876
67998
|
init_auth();
|
|
67877
67999
|
|
|
67878
68000
|
// src/scenarios/catalog.ts
|
|
67879
|
-
var
|
|
67880
|
-
var
|
|
68001
|
+
var import_node_fs24 = require("fs");
|
|
68002
|
+
var import_node_path20 = require("path");
|
|
67881
68003
|
var SCENARIO_DIR_CANDIDATES = [
|
|
67882
|
-
(0,
|
|
67883
|
-
(0,
|
|
67884
|
-
(0,
|
|
67885
|
-
(0,
|
|
67886
|
-
(0,
|
|
68004
|
+
(0, import_node_path20.resolve)("scenarios"),
|
|
68005
|
+
(0, import_node_path20.resolve)("scenario"),
|
|
68006
|
+
(0, import_node_path20.resolve)("test", "scenarios"),
|
|
68007
|
+
(0, import_node_path20.resolve)("tests", "scenarios"),
|
|
68008
|
+
(0, import_node_path20.resolve)(".archal", "scenarios")
|
|
67887
68009
|
];
|
|
67888
68010
|
function findScenarioFiles(dir) {
|
|
67889
|
-
if (!(0,
|
|
68011
|
+
if (!(0, import_node_fs24.existsSync)(dir)) {
|
|
67890
68012
|
return [];
|
|
67891
68013
|
}
|
|
67892
68014
|
const files = [];
|
|
67893
|
-
const entries = (0,
|
|
68015
|
+
const entries = (0, import_node_fs24.readdirSync)(dir, { withFileTypes: true });
|
|
67894
68016
|
for (const entry of entries) {
|
|
67895
|
-
const fullPath = (0,
|
|
68017
|
+
const fullPath = (0, import_node_path20.join)(dir, entry.name);
|
|
67896
68018
|
if (entry.isDirectory()) {
|
|
67897
68019
|
files.push(...findScenarioFiles(fullPath));
|
|
67898
68020
|
continue;
|
|
67899
68021
|
}
|
|
67900
|
-
if (entry.isFile() && (0,
|
|
68022
|
+
if (entry.isFile() && (0, import_node_path20.extname)(entry.name) === ".md") {
|
|
67901
68023
|
files.push(fullPath);
|
|
67902
68024
|
}
|
|
67903
68025
|
}
|
|
@@ -67905,27 +68027,27 @@ function findScenarioFiles(dir) {
|
|
|
67905
68027
|
}
|
|
67906
68028
|
function findLocalScenariosDir() {
|
|
67907
68029
|
for (const candidate of SCENARIO_DIR_CANDIDATES) {
|
|
67908
|
-
if ((0,
|
|
68030
|
+
if ((0, import_node_fs24.existsSync)(candidate)) {
|
|
67909
68031
|
return { dir: candidate, candidates: SCENARIO_DIR_CANDIDATES };
|
|
67910
68032
|
}
|
|
67911
68033
|
}
|
|
67912
68034
|
return {
|
|
67913
|
-
dir: (0,
|
|
68035
|
+
dir: (0, import_node_path20.resolve)("scenarios"),
|
|
67914
68036
|
candidates: SCENARIO_DIR_CANDIDATES
|
|
67915
68037
|
};
|
|
67916
68038
|
}
|
|
67917
68039
|
function resolveLocalScenario(nameOrPath) {
|
|
67918
|
-
const directPath = (0,
|
|
67919
|
-
if ((0,
|
|
68040
|
+
const directPath = (0, import_node_path20.resolve)(nameOrPath);
|
|
68041
|
+
if ((0, import_node_fs24.existsSync)(directPath)) {
|
|
67920
68042
|
return directPath;
|
|
67921
68043
|
}
|
|
67922
68044
|
const needle = nameOrPath.endsWith(".md") ? nameOrPath : `${nameOrPath}.md`;
|
|
67923
68045
|
for (const candidate of SCENARIO_DIR_CANDIDATES) {
|
|
67924
|
-
if (!(0,
|
|
68046
|
+
if (!(0, import_node_fs24.existsSync)(candidate)) {
|
|
67925
68047
|
continue;
|
|
67926
68048
|
}
|
|
67927
|
-
const rootCandidate = (0,
|
|
67928
|
-
if ((0,
|
|
68049
|
+
const rootCandidate = (0, import_node_path20.join)(candidate, needle);
|
|
68050
|
+
if ((0, import_node_fs24.existsSync)(rootCandidate)) {
|
|
67929
68051
|
return rootCandidate;
|
|
67930
68052
|
}
|
|
67931
68053
|
const nestedMatch = findScenarioFiles(candidate).find(
|
|
@@ -68074,8 +68196,8 @@ function parseOpenClawEvalMode(raw, source) {
|
|
|
68074
68196
|
);
|
|
68075
68197
|
}
|
|
68076
68198
|
function resolveScenarioPath(scenarioArg) {
|
|
68077
|
-
let scenarioPath = (0,
|
|
68078
|
-
if (!(0,
|
|
68199
|
+
let scenarioPath = (0, import_node_path21.resolve)(scenarioArg);
|
|
68200
|
+
if (!(0, import_node_fs25.existsSync)(scenarioPath)) {
|
|
68079
68201
|
const localScenario = resolveLocalScenario(scenarioArg);
|
|
68080
68202
|
if (localScenario) {
|
|
68081
68203
|
scenarioPath = localScenario;
|
|
@@ -68092,7 +68214,7 @@ function resolveScenarioPath(scenarioArg) {
|
|
|
68092
68214
|
"Rename the file to use the .md extension, then retry."
|
|
68093
68215
|
);
|
|
68094
68216
|
}
|
|
68095
|
-
if (!(0,
|
|
68217
|
+
if (!(0, import_node_fs25.readFileSync)(scenarioPath, "utf-8").trim()) {
|
|
68096
68218
|
validationError(
|
|
68097
68219
|
`Scenario file is empty: ${scenarioPath}`,
|
|
68098
68220
|
"Add scenario content (Setup, Prompt, Success Criteria sections), then retry."
|
|
@@ -68253,9 +68375,10 @@ function resolveHarnessAndEngine(opts, timeout, resolved) {
|
|
|
68253
68375
|
opts.explicitHarnessKind = void 0;
|
|
68254
68376
|
let inferredRepoHarness = false;
|
|
68255
68377
|
const dockerExplicitlyRequested = isDockerExplicitlyRequested(opts);
|
|
68378
|
+
const userConfig = loadConfig();
|
|
68256
68379
|
if (!process.env["ANTHROPIC_API_KEY"] && !process.env["OPENAI_API_KEY"] && !process.env["GEMINI_API_KEY"]) {
|
|
68257
68380
|
try {
|
|
68258
|
-
const cfg =
|
|
68381
|
+
const cfg = userConfig;
|
|
68259
68382
|
if (cfg.apiKey) {
|
|
68260
68383
|
if (cfg.apiKey.startsWith("sk-ant-")) {
|
|
68261
68384
|
process.env["ANTHROPIC_API_KEY"] = cfg.apiKey;
|
|
@@ -68312,7 +68435,6 @@ function resolveHarnessAndEngine(opts, timeout, resolved) {
|
|
|
68312
68435
|
}
|
|
68313
68436
|
}
|
|
68314
68437
|
}
|
|
68315
|
-
const userConfig = loadConfig();
|
|
68316
68438
|
const { resolvedHarness, resolvedAgentModel } = applyConfiguredRunDefaults(opts, resolved, userConfig);
|
|
68317
68439
|
if (opts.apiKey?.trim()) {
|
|
68318
68440
|
warnIfKeyLooksInvalid(opts.apiKey.trim(), "--api-key");
|
|
@@ -68350,7 +68472,7 @@ function resolveHarnessAndEngine(opts, timeout, resolved) {
|
|
|
68350
68472
|
}
|
|
68351
68473
|
} else {
|
|
68352
68474
|
const inferredHarness = discoverRepoLocalHarness(
|
|
68353
|
-
(0,
|
|
68475
|
+
(0, import_node_path21.dirname)(resolved?.scenarioPath ?? process.cwd()),
|
|
68354
68476
|
resolved?.projectRoot ?? "",
|
|
68355
68477
|
process.cwd()
|
|
68356
68478
|
);
|
|
@@ -68740,9 +68862,29 @@ async function executeRunForScenario(scenarioArg, opts, command, configDefaults)
|
|
|
68740
68862
|
);
|
|
68741
68863
|
}
|
|
68742
68864
|
writeManagedRunStatus({ stage: shouldProvisionHostedSession ? "provisioning" : "running" });
|
|
68865
|
+
let reusedExistingSession = false;
|
|
68866
|
+
if (shouldProvisionHostedSession && credentials) {
|
|
68867
|
+
const reusedSession = await tryReuseEnvSession(scenario.config.twins, credentials);
|
|
68868
|
+
if (reusedSession) {
|
|
68869
|
+
reusedExistingSession = true;
|
|
68870
|
+
ctx.backendSessionId = reusedSession.sessionId;
|
|
68871
|
+
ctx.isReusedEnvSession = true;
|
|
68872
|
+
cloudTwinUrls = reusedSession.endpoints;
|
|
68873
|
+
if (!opts.apiBaseUrls) {
|
|
68874
|
+
hostedApiBaseUrlOverrides = reusedSession.apiBaseUrls;
|
|
68875
|
+
}
|
|
68876
|
+
if (!opts.quiet) {
|
|
68877
|
+
info(`Reusing active twin session ${reusedSession.sessionId}`);
|
|
68878
|
+
}
|
|
68879
|
+
writeManagedRunStatus({
|
|
68880
|
+
stage: "session_ready",
|
|
68881
|
+
sessionId: ctx.backendSessionId
|
|
68882
|
+
});
|
|
68883
|
+
}
|
|
68884
|
+
}
|
|
68743
68885
|
if (process.env["ARCHAL_LOCAL_TWINS"]) {
|
|
68744
68886
|
ctx.runFailureMessage = "ARCHAL_LOCAL_TWINS has been removed. Twins are always provisioned in hosted cloud sessions.";
|
|
68745
|
-
} else if (shouldProvisionHostedSession) {
|
|
68887
|
+
} else if (!reusedExistingSession && shouldProvisionHostedSession) {
|
|
68746
68888
|
ctx.inFlightSessionStart = startSession(credentials?.token ?? "", {
|
|
68747
68889
|
twins: scenario.config.twins,
|
|
68748
68890
|
scenarioId: scenario.title,
|
|
@@ -68772,12 +68914,27 @@ async function executeRunForScenario(scenarioArg, opts, command, configDefaults)
|
|
|
68772
68914
|
stage: "provisioning",
|
|
68773
68915
|
sessionId: ctx.backendSessionId
|
|
68774
68916
|
});
|
|
68775
|
-
const
|
|
68776
|
-
const
|
|
68917
|
+
const serverEndpoints = sessionResult.data.endpoints;
|
|
68918
|
+
const serverApiBaseUrls = sessionResult.data.apiBaseUrls;
|
|
68777
68919
|
const missingEndpoints = scenario.config.twins.filter((name) => {
|
|
68778
|
-
const endpoint =
|
|
68920
|
+
const endpoint = serverEndpoints[name];
|
|
68779
68921
|
return typeof endpoint !== "string" || endpoint.trim().length === 0;
|
|
68780
68922
|
});
|
|
68923
|
+
const runtimeBase = getConfiguredRuntimeBaseUrl2();
|
|
68924
|
+
let endpointRoots;
|
|
68925
|
+
let apiBaseUrls;
|
|
68926
|
+
if (runtimeBase && missingEndpoints.length === 0) {
|
|
68927
|
+
const runtimeUrls = buildRuntimeTwinUrls(
|
|
68928
|
+
ctx.backendSessionId,
|
|
68929
|
+
scenario.config.twins,
|
|
68930
|
+
runtimeBase
|
|
68931
|
+
);
|
|
68932
|
+
endpointRoots = runtimeUrls.endpoints;
|
|
68933
|
+
apiBaseUrls = runtimeUrls.apiBaseUrls;
|
|
68934
|
+
} else {
|
|
68935
|
+
endpointRoots = serverEndpoints;
|
|
68936
|
+
apiBaseUrls = serverApiBaseUrls;
|
|
68937
|
+
}
|
|
68781
68938
|
if (missingEndpoints.length > 0) {
|
|
68782
68939
|
ctx.runFailureMessage = `Twin provisioning failed for: ${missingEndpoints.join(", ")}. Try again or run: archal doctor`;
|
|
68783
68940
|
}
|
|
@@ -68788,7 +68945,7 @@ async function executeRunForScenario(scenarioArg, opts, command, configDefaults)
|
|
|
68788
68945
|
hostedApiBaseUrlOverrides = apiBaseUrls;
|
|
68789
68946
|
}
|
|
68790
68947
|
if (!ctx.runFailureMessage && engine.mode === "api" && !engine.twinUrlsPath) {
|
|
68791
|
-
ctx.generatedTwinUrlMapPath = (0,
|
|
68948
|
+
ctx.generatedTwinUrlMapPath = (0, import_node_path24.resolve)(
|
|
68792
68949
|
`.archal-session-${ctx.backendSessionId}-engine-twin-urls.json`
|
|
68793
68950
|
);
|
|
68794
68951
|
const result = writeTempJsonMap(ctx.generatedTwinUrlMapPath, endpointRoots, "engine twin URL map");
|
|
@@ -68981,8 +69138,8 @@ async function executeRunForScenario(scenarioArg, opts, command, configDefaults)
|
|
|
68981
69138
|
process.stderr.write(`Warning: failed to build trace payload: ${errorMessage(traceErr)}
|
|
68982
69139
|
`);
|
|
68983
69140
|
}
|
|
68984
|
-
(0,
|
|
68985
|
-
(0,
|
|
69141
|
+
(0, import_node_fs28.mkdirSync)((0, import_node_path24.dirname)(ctx.evidenceOutputPath), { recursive: true });
|
|
69142
|
+
(0, import_node_fs28.writeFileSync)(
|
|
68986
69143
|
ctx.evidenceOutputPath,
|
|
68987
69144
|
JSON.stringify({
|
|
68988
69145
|
sessionId: ctx.backendSessionId ?? null,
|
|
@@ -69036,7 +69193,23 @@ function createRunCommand() {
|
|
|
69036
69193
|
throw new CliUsageError("--twin requires --task.");
|
|
69037
69194
|
}
|
|
69038
69195
|
const { loadArchalFile: loadArchalFile2 } = await Promise.resolve().then(() => (init_archal_file(), archal_file_exports));
|
|
69039
|
-
|
|
69196
|
+
let archalFile = loadArchalFile2(opts["config"]);
|
|
69197
|
+
if (!archalFile && opts.task) {
|
|
69198
|
+
try {
|
|
69199
|
+
const { detectTwinsFromHarnessDir: detectTwinsFromHarnessDir2 } = await Promise.resolve().then(() => (init_harness_import_detector(), harness_import_detector_exports));
|
|
69200
|
+
const detected = detectTwinsFromHarnessDir2(process.cwd());
|
|
69201
|
+
if (detected.length > 0) {
|
|
69202
|
+
const { writeFileSync: writeFileSync_ } = await import("fs");
|
|
69203
|
+
const { resolve: resolvePath } = await import("path");
|
|
69204
|
+
const generatedConfig = { twins: detected };
|
|
69205
|
+
const configPath = resolvePath(process.cwd(), ".archal.json");
|
|
69206
|
+
writeFileSync_(configPath, JSON.stringify(generatedConfig, null, 2) + "\n", "utf-8");
|
|
69207
|
+
info("Created .archal.json with detected twins: " + detected.join(", "));
|
|
69208
|
+
archalFile = loadArchalFile2();
|
|
69209
|
+
}
|
|
69210
|
+
} catch {
|
|
69211
|
+
}
|
|
69212
|
+
}
|
|
69040
69213
|
const scenariosToRun = scenarioArg?.trim() ? [scenarioArg] : [];
|
|
69041
69214
|
if (archalFile) {
|
|
69042
69215
|
const { config: af, configDir } = archalFile;
|
|
@@ -69071,7 +69244,7 @@ function createRunCommand() {
|
|
|
69071
69244
|
const seedOverrides = {};
|
|
69072
69245
|
for (const [twinName, seedPath] of Object.entries(af.seeds)) {
|
|
69073
69246
|
const resolvedSeedPath = resolvePath(configDir, seedPath);
|
|
69074
|
-
const seedExt = (0,
|
|
69247
|
+
const seedExt = (0, import_node_path24.extname)(resolvedSeedPath).toLowerCase();
|
|
69075
69248
|
if (seedExt === ".json" || seedExt === ".md") {
|
|
69076
69249
|
fileSeedPaths[twinName] = resolvedSeedPath;
|
|
69077
69250
|
} else {
|
|
@@ -69129,7 +69302,7 @@ function createRunCommand() {
|
|
|
69129
69302
|
}
|
|
69130
69303
|
if (scenariosToRun.length === 0) {
|
|
69131
69304
|
throw new CliUsageError(
|
|
69132
|
-
'No .archal.json config found and no scenario specified.\n Create .archal.json with your twins:
|
|
69305
|
+
'No .archal.json config found and no scenario specified.\n Create .archal.json with your twins: { "twins": ["github"] }\n Or pass a scenario directly: archal run scenario.md\n Or run an inline task with a twin: archal run --task "Create an issue" --twin github'
|
|
69133
69306
|
);
|
|
69134
69307
|
}
|
|
69135
69308
|
const tempManifestPath = opts["_tempManifestPath"];
|
|
@@ -69593,8 +69766,8 @@ ${CYAN2}${BOLD2}Archal CLI${RESET2} ${DIM2}v${CLI_VERSION}${RESET2}
|
|
|
69593
69766
|
}
|
|
69594
69767
|
|
|
69595
69768
|
// src/commands/scenario.ts
|
|
69596
|
-
var
|
|
69597
|
-
var
|
|
69769
|
+
var import_node_fs29 = require("fs");
|
|
69770
|
+
var import_node_path25 = require("path");
|
|
69598
69771
|
init_logger();
|
|
69599
69772
|
function listScenarios(opts) {
|
|
69600
69773
|
const tagFilter = opts.tag?.toLowerCase();
|
|
@@ -69603,7 +69776,7 @@ function listScenarios(opts) {
|
|
|
69603
69776
|
const rows = [];
|
|
69604
69777
|
const localResolution = findLocalScenariosDir();
|
|
69605
69778
|
const localDir = localResolution.dir;
|
|
69606
|
-
const localDirExists = (0,
|
|
69779
|
+
const localDirExists = (0, import_node_fs29.existsSync)(localDir);
|
|
69607
69780
|
if (localDirExists) {
|
|
69608
69781
|
const localFiles = findScenarioFiles(localDir);
|
|
69609
69782
|
for (const file2 of localFiles) {
|
|
@@ -69614,10 +69787,10 @@ function listScenarios(opts) {
|
|
|
69614
69787
|
if (!scenarioTags.includes(tagFilter)) continue;
|
|
69615
69788
|
}
|
|
69616
69789
|
if (difficultyFilter && (scenario.config.difficulty ?? "") !== difficultyFilter) continue;
|
|
69617
|
-
const slug = (0,
|
|
69790
|
+
const slug = (0, import_node_path25.basename)(file2, ".md");
|
|
69618
69791
|
rows.push([scenario.title, slug, scenario.config.twins.join(", ") || "(auto)"]);
|
|
69619
69792
|
} catch {
|
|
69620
|
-
const slug = (0,
|
|
69793
|
+
const slug = (0, import_node_path25.basename)(file2, ".md");
|
|
69621
69794
|
rows.push(["(parse error)", slug, "-"]);
|
|
69622
69795
|
}
|
|
69623
69796
|
}
|
|
@@ -69658,35 +69831,35 @@ function createScenarioCommand() {
|
|
|
69658
69831
|
}
|
|
69659
69832
|
|
|
69660
69833
|
// src/commands/twin.ts
|
|
69661
|
-
var
|
|
69834
|
+
var import_node_fs31 = require("fs");
|
|
69662
69835
|
init_auth();
|
|
69663
69836
|
init_api_client();
|
|
69664
69837
|
init_errors4();
|
|
69665
69838
|
|
|
69666
69839
|
// src/commands/twin-session-store.ts
|
|
69667
|
-
var
|
|
69668
|
-
var
|
|
69669
|
-
var
|
|
69670
|
-
var
|
|
69671
|
-
var
|
|
69840
|
+
var import_node_fs30 = require("fs");
|
|
69841
|
+
var import_node_os9 = require("os");
|
|
69842
|
+
var import_node_path26 = require("path");
|
|
69843
|
+
var TWIN_SESSION_FILE2 = (0, import_node_path26.join)((0, import_node_os9.homedir)(), ".archal", "twin-session.json");
|
|
69844
|
+
var LEGACY_SESSION_FILE2 = (0, import_node_path26.join)((0, import_node_os9.homedir)(), ".archal", "env-session.json");
|
|
69672
69845
|
function saveSession(session) {
|
|
69673
|
-
(0,
|
|
69674
|
-
(0,
|
|
69846
|
+
(0, import_node_fs30.mkdirSync)((0, import_node_path26.join)((0, import_node_os9.homedir)(), ".archal"), { recursive: true });
|
|
69847
|
+
(0, import_node_fs30.writeFileSync)(TWIN_SESSION_FILE2, JSON.stringify(session, null, 2));
|
|
69675
69848
|
}
|
|
69676
|
-
function
|
|
69677
|
-
let filePath =
|
|
69678
|
-
if (!(0,
|
|
69679
|
-
filePath =
|
|
69849
|
+
function loadSession2() {
|
|
69850
|
+
let filePath = TWIN_SESSION_FILE2;
|
|
69851
|
+
if (!(0, import_node_fs30.existsSync)(filePath) && (0, import_node_fs30.existsSync)(LEGACY_SESSION_FILE2)) {
|
|
69852
|
+
filePath = LEGACY_SESSION_FILE2;
|
|
69680
69853
|
}
|
|
69681
|
-
if (!(0,
|
|
69854
|
+
if (!(0, import_node_fs30.existsSync)(filePath)) {
|
|
69682
69855
|
return null;
|
|
69683
69856
|
}
|
|
69684
69857
|
try {
|
|
69685
|
-
const session = JSON.parse((0,
|
|
69686
|
-
if (filePath ===
|
|
69858
|
+
const session = JSON.parse((0, import_node_fs30.readFileSync)(filePath, "utf8"));
|
|
69859
|
+
if (filePath === LEGACY_SESSION_FILE2) {
|
|
69687
69860
|
saveSession(session);
|
|
69688
69861
|
try {
|
|
69689
|
-
(0,
|
|
69862
|
+
(0, import_node_fs30.rmSync)(LEGACY_SESSION_FILE2);
|
|
69690
69863
|
} catch {
|
|
69691
69864
|
}
|
|
69692
69865
|
}
|
|
@@ -69697,11 +69870,11 @@ function loadSession() {
|
|
|
69697
69870
|
}
|
|
69698
69871
|
function clearSession() {
|
|
69699
69872
|
try {
|
|
69700
|
-
(0,
|
|
69873
|
+
(0, import_node_fs30.rmSync)(TWIN_SESSION_FILE2);
|
|
69701
69874
|
} catch {
|
|
69702
69875
|
}
|
|
69703
69876
|
try {
|
|
69704
|
-
(0,
|
|
69877
|
+
(0, import_node_fs30.rmSync)(LEGACY_SESSION_FILE2);
|
|
69705
69878
|
} catch {
|
|
69706
69879
|
}
|
|
69707
69880
|
}
|
|
@@ -69830,11 +70003,19 @@ async function pollUntilReady(sessionId, twins, token) {
|
|
|
69830
70003
|
}
|
|
69831
70004
|
const status = result.data;
|
|
69832
70005
|
if (status.status === "ready") {
|
|
70006
|
+
const runtimeBase = getConfiguredRuntimeBaseUrl2();
|
|
70007
|
+
let endpoints = status.endpoints ?? {};
|
|
70008
|
+
let apiBaseUrls = status.apiBaseUrls ?? {};
|
|
70009
|
+
if (runtimeBase) {
|
|
70010
|
+
const runtimeUrls = buildRuntimeTwinUrls(sessionId, twins, runtimeBase);
|
|
70011
|
+
endpoints = runtimeUrls.endpoints;
|
|
70012
|
+
apiBaseUrls = runtimeUrls.apiBaseUrls;
|
|
70013
|
+
}
|
|
69833
70014
|
const saved = {
|
|
69834
70015
|
sessionId,
|
|
69835
70016
|
twins,
|
|
69836
|
-
endpoints
|
|
69837
|
-
apiBaseUrls
|
|
70017
|
+
endpoints,
|
|
70018
|
+
apiBaseUrls,
|
|
69838
70019
|
createdAt: status.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
69839
70020
|
};
|
|
69840
70021
|
saveSession(saved);
|
|
@@ -69850,7 +70031,7 @@ async function pollUntilReady(sessionId, twins, token) {
|
|
|
69850
70031
|
throw new CliRuntimeError("Timed out waiting for twins to start.");
|
|
69851
70032
|
}
|
|
69852
70033
|
async function loadSeedFile(session, twin, seedFile, token) {
|
|
69853
|
-
const content = (0,
|
|
70034
|
+
const content = (0, import_node_fs31.readFileSync)(seedFile, "utf8");
|
|
69854
70035
|
if (content.length > MAX_SETUP_FILE_SIZE) {
|
|
69855
70036
|
throw new CliUsageError(
|
|
69856
70037
|
`Seed file too large (${content.length} bytes, max ${MAX_SETUP_FILE_SIZE}). Split the seed or reduce its size.`
|
|
@@ -69885,7 +70066,7 @@ async function loadSeedFile(session, twin, seedFile, token) {
|
|
|
69885
70066
|
}
|
|
69886
70067
|
function readSetupFile(filePath) {
|
|
69887
70068
|
try {
|
|
69888
|
-
const content = (0,
|
|
70069
|
+
const content = (0, import_node_fs31.readFileSync)(filePath, "utf-8").trim();
|
|
69889
70070
|
if (content.length > MAX_SETUP_FILE_SIZE) {
|
|
69890
70071
|
throw new CliUsageError(
|
|
69891
70072
|
`Setup file too large (${content.length} bytes, max ${MAX_SETUP_FILE_SIZE}). Use --seed-file for large seeds.`
|
|
@@ -69944,7 +70125,7 @@ function createTwinCommand() {
|
|
|
69944
70125
|
await listTwinCatalog2();
|
|
69945
70126
|
});
|
|
69946
70127
|
command.command("start").argument("[twins...]", "Twins to start").option("--all", "Start all available twins").option("--seed <seeds...>", "Seeds per twin (for example: stripe:small-business github:rich-org)").option("--setup <description>", "Describe desired state in natural language and seed the first twin after startup").option("--setup-file <path>", "Read setup description from a file and seed the first twin after startup").option("--seed-file <path>", "Load a JSON seed file after the first twin is ready").option("--ttl-seconds <seconds>", "Requested twin lifetime in seconds (capped server-side)").description("Start a persistent hosted twin session with hosted twin APIs").action(async (twins, opts) => {
|
|
69947
|
-
const existing =
|
|
70128
|
+
const existing = loadSession2();
|
|
69948
70129
|
if (existing) {
|
|
69949
70130
|
throw new CliRuntimeError(
|
|
69950
70131
|
`Active session found: ${existing.sessionId}
|
|
@@ -69962,14 +70143,15 @@ Run 'archal twin stop' first, or 'archal twin status' to inspect it.`
|
|
|
69962
70143
|
const createResult = await startSession(token, {
|
|
69963
70144
|
twins: requestedTwins,
|
|
69964
70145
|
seeds,
|
|
69965
|
-
ttlSeconds: opts.ttlSeconds ? toPositiveInteger2(opts.ttlSeconds, "--ttl-seconds") : void 0
|
|
70146
|
+
ttlSeconds: opts.ttlSeconds ? toPositiveInteger2(opts.ttlSeconds, "--ttl-seconds") : void 0,
|
|
70147
|
+
source: "twin-start"
|
|
69966
70148
|
});
|
|
69967
70149
|
const response = unwrapApiResult(createResult, "Failed to create twin session");
|
|
69968
70150
|
process.stderr.write(`${DIM3}Session ${response.sessionId} created. Waiting for twins to start...${RESET3}
|
|
69969
70151
|
`);
|
|
69970
70152
|
const ready = await pollUntilReady(response.sessionId, requestedTwins, token);
|
|
69971
70153
|
if (ready.status === "ready") {
|
|
69972
|
-
const saved =
|
|
70154
|
+
const saved = loadSession2();
|
|
69973
70155
|
if (saved) {
|
|
69974
70156
|
await loadCustomSeedIfRequested(saved, requestedTwins, opts, token);
|
|
69975
70157
|
}
|
|
@@ -69977,7 +70159,7 @@ Run 'archal twin stop' first, or 'archal twin status' to inspect it.`
|
|
|
69977
70159
|
});
|
|
69978
70160
|
command.command("status").option("--json", "Print the raw status payload as JSON").description("Show the active twin session endpoints and status").action(async (opts) => {
|
|
69979
70161
|
const token = requireToken();
|
|
69980
|
-
const saved =
|
|
70162
|
+
const saved = loadSession2();
|
|
69981
70163
|
if (!saved) {
|
|
69982
70164
|
process.stderr.write(`${DIM3}No active twin session. Run 'archal twin start github' to start one.${RESET3}
|
|
69983
70165
|
`);
|
|
@@ -70028,7 +70210,7 @@ ${BOLD3}Twin Session: ${saved.sessionId}${RESET3}
|
|
|
70028
70210
|
process.stderr.write("\n");
|
|
70029
70211
|
});
|
|
70030
70212
|
command.command("list").option("--json", "Print twin sessions as JSON").description("List active twin sessions for the current user").action(async (opts) => {
|
|
70031
|
-
const saved =
|
|
70213
|
+
const saved = loadSession2();
|
|
70032
70214
|
if (!saved) {
|
|
70033
70215
|
if (opts.json) {
|
|
70034
70216
|
process.stdout.write(`${JSON.stringify({ sessions: [] }, null, 2)}
|
|
@@ -70072,11 +70254,20 @@ ${BOLD3}Active Twin Sessions${RESET3}
|
|
|
70072
70254
|
const token = requireToken();
|
|
70073
70255
|
const result = await getSessionStatus(token, sessionId);
|
|
70074
70256
|
const response = unwrapApiResult(result, "Failed to attach twin session");
|
|
70257
|
+
const attachedTwins = response.twinIds ?? [];
|
|
70258
|
+
const runtimeBase = getConfiguredRuntimeBaseUrl2();
|
|
70259
|
+
let attachEndpoints = response.endpoints ?? {};
|
|
70260
|
+
let attachApiBaseUrls = response.apiBaseUrls ?? {};
|
|
70261
|
+
if (runtimeBase && attachedTwins.length > 0) {
|
|
70262
|
+
const runtimeUrls = buildRuntimeTwinUrls(sessionId, attachedTwins, runtimeBase);
|
|
70263
|
+
attachEndpoints = runtimeUrls.endpoints;
|
|
70264
|
+
attachApiBaseUrls = runtimeUrls.apiBaseUrls;
|
|
70265
|
+
}
|
|
70075
70266
|
saveSession({
|
|
70076
70267
|
sessionId,
|
|
70077
|
-
twins:
|
|
70078
|
-
endpoints:
|
|
70079
|
-
apiBaseUrls:
|
|
70268
|
+
twins: attachedTwins,
|
|
70269
|
+
endpoints: attachEndpoints,
|
|
70270
|
+
apiBaseUrls: attachApiBaseUrls,
|
|
70080
70271
|
createdAt: response.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
70081
70272
|
});
|
|
70082
70273
|
process.stderr.write(`${GREEN2}Attached${RESET3} ${sessionId}
|
|
@@ -70084,7 +70275,7 @@ ${BOLD3}Active Twin Sessions${RESET3}
|
|
|
70084
70275
|
});
|
|
70085
70276
|
command.command("renew").argument("[ttl-seconds]", "Requested additional lifetime in seconds").description("Extend the active twin session lifetime").action(async (ttlSeconds) => {
|
|
70086
70277
|
const token = requireToken();
|
|
70087
|
-
const saved =
|
|
70278
|
+
const saved = loadSession2();
|
|
70088
70279
|
if (!saved) {
|
|
70089
70280
|
throw new CliRuntimeError("No active twin session.");
|
|
70090
70281
|
}
|
|
@@ -70098,7 +70289,7 @@ ${BOLD3}Active Twin Sessions${RESET3}
|
|
|
70098
70289
|
});
|
|
70099
70290
|
command.command("stop").description("Tear down the active twin session").action(async () => {
|
|
70100
70291
|
const token = requireToken();
|
|
70101
|
-
const saved =
|
|
70292
|
+
const saved = loadSession2();
|
|
70102
70293
|
if (!saved) {
|
|
70103
70294
|
process.stderr.write(`${DIM3}No active twin session.${RESET3}
|
|
70104
70295
|
`);
|
|
@@ -70130,7 +70321,7 @@ ${BOLD3}Active Twin Sessions${RESET3}
|
|
|
70130
70321
|
});
|
|
70131
70322
|
command.command("reset").argument("[twin]", "Twin to reset, or all session twins if omitted").description("Reset twin state to clean").action(async (twin) => {
|
|
70132
70323
|
const token = requireToken();
|
|
70133
|
-
const saved =
|
|
70324
|
+
const saved = loadSession2();
|
|
70134
70325
|
if (!saved) {
|
|
70135
70326
|
throw new CliRuntimeError("No active twin session.");
|
|
70136
70327
|
}
|
|
@@ -70171,7 +70362,7 @@ ${BOLD3}Active Twin Sessions${RESET3}
|
|
|
70171
70362
|
});
|
|
70172
70363
|
command.command("seed").argument("<twin>", "Twin 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 twin from it").description("Load a seed into a running twin").action(async (twin, seedName, opts) => {
|
|
70173
70364
|
const token = requireToken();
|
|
70174
|
-
const saved =
|
|
70365
|
+
const saved = loadSession2();
|
|
70175
70366
|
if (!saved) {
|
|
70176
70367
|
throw new CliRuntimeError("No active twin session.");
|
|
70177
70368
|
}
|
|
@@ -70205,8 +70396,9 @@ ${BOLD3}Active Twin Sessions${RESET3}
|
|
|
70205
70396
|
// src/commands/trace.ts
|
|
70206
70397
|
init_dist2();
|
|
70207
70398
|
init_require_auth();
|
|
70399
|
+
init_auth();
|
|
70208
70400
|
async function fetchTraces(token, limit = 20) {
|
|
70209
|
-
const baseUrl =
|
|
70401
|
+
const baseUrl = getConfiguredApiBaseUrl2() ?? "https://www.archal.ai";
|
|
70210
70402
|
const res = await fetch(`${baseUrl}/api/traces?limit=${limit}`, {
|
|
70211
70403
|
headers: { authorization: `Bearer ${token}` }
|
|
70212
70404
|
});
|
|
@@ -70217,7 +70409,7 @@ async function fetchTraces(token, limit = 20) {
|
|
|
70217
70409
|
return body.traces ?? [];
|
|
70218
70410
|
}
|
|
70219
70411
|
async function fetchTraceDetail(token, rootTraceId) {
|
|
70220
|
-
const baseUrl =
|
|
70412
|
+
const baseUrl = getConfiguredApiBaseUrl2() ?? "https://www.archal.ai";
|
|
70221
70413
|
const res = await fetch(`${baseUrl}/api/traces/${encodeURIComponent(rootTraceId)}`, {
|
|
70222
70414
|
headers: { authorization: `Bearer ${token}` }
|
|
70223
70415
|
});
|