@amaster.ai/employee-runtime-connector 0.1.0-beta.40 → 0.1.0-beta.42
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/amaster-runtime-daemon.mjs +957 -459
- package/dist/amaster-runtime.mjs +1 -1
- package/package.json +1 -1
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// MirrorX runtime connector daemon bundle.
|
|
3
3
|
|
|
4
4
|
// src/amaster-runtime-daemon.mjs
|
|
5
|
-
import { createHash as
|
|
6
|
-
import { chmodSync as
|
|
5
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
6
|
+
import { chmodSync as chmodSync6, copyFileSync as copyFileSync3, existsSync as existsSync12, lstatSync as lstatSync7, mkdirSync as mkdirSync8, readFileSync as readFileSync10, readdirSync as readdirSync8, realpathSync as realpathSync3, renameSync as renameSync5, rmSync as rmSync7, statSync as statSync7, symlinkSync as symlinkSync4, unlinkSync, writeFileSync as writeFileSync8 } from "node:fs";
|
|
7
7
|
import { arch as arch3, homedir as homedir3, hostname as hostname2, platform as platform3 } from "node:os";
|
|
8
|
-
import { basename as basename6, delimiter as delimiter2, dirname as
|
|
8
|
+
import { basename as basename6, delimiter as delimiter2, dirname as dirname9, extname as extname2, isAbsolute as isAbsolute8, join as join13, relative as relative8, resolve as resolve11 } from "node:path";
|
|
9
9
|
import { spawn, spawnSync as spawnSync5 } from "node:child_process";
|
|
10
10
|
|
|
11
11
|
// src/amaster-runtime-daemon/common.mjs
|
|
@@ -1785,6 +1785,27 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1785
1785
|
const MINIMUM_MCP_ADAPTER_VERSION = [2, 6, 1];
|
|
1786
1786
|
const MANAGED_BROWSER_USE_PACKAGE = "@amaster.ai/pi-browser-use";
|
|
1787
1787
|
const MANAGED_BROWSER_USE_PLUGIN = "browser-use";
|
|
1788
|
+
const MANAGED_TELEMETRY_PACKAGE = "@amaster.ai/pi-telemetry";
|
|
1789
|
+
const MANAGED_TELEMETRY_ENV_NAMES = [
|
|
1790
|
+
"PI_TELEMETRY_SERVICE_NAME",
|
|
1791
|
+
"PI_TELEMETRY_SERVICE_VERSION",
|
|
1792
|
+
"PI_TELEMETRY_INCLUDE_PAYLOADS",
|
|
1793
|
+
"PI_TELEMETRY_LANGFUSE_ENABLED",
|
|
1794
|
+
"PI_TELEMETRY_LANGFUSE_PUBLIC_KEY",
|
|
1795
|
+
"PI_TELEMETRY_LANGFUSE_SECRET_KEY",
|
|
1796
|
+
"PI_TELEMETRY_LANGFUSE_BASE_URL",
|
|
1797
|
+
"PI_TELEMETRY_LANGFUSE_FLUSH_AT",
|
|
1798
|
+
"PI_TELEMETRY_LANGFUSE_FLUSH_INTERVAL_MS",
|
|
1799
|
+
"PI_TELEMETRY_OTEL_ENABLED",
|
|
1800
|
+
"PI_TELEMETRY_OTEL_ENDPOINT",
|
|
1801
|
+
"PI_TELEMETRY_OTEL_HEADERS",
|
|
1802
|
+
"PI_TELEMETRY_OTEL_FLUSH_AT",
|
|
1803
|
+
"PI_TELEMETRY_OTEL_FLUSH_INTERVAL_MS"
|
|
1804
|
+
];
|
|
1805
|
+
const MANAGED_TELEMETRY_PROTECTED_ENV_NAMES = [
|
|
1806
|
+
"PI_TELEMETRY_LANGFUSE_SECRET_KEY",
|
|
1807
|
+
"PI_TELEMETRY_OTEL_HEADERS"
|
|
1808
|
+
];
|
|
1788
1809
|
const MANAGED_BROWSER_USE_BOOLEAN_SETTINGS = [
|
|
1789
1810
|
"headless",
|
|
1790
1811
|
"categoryNetwork",
|
|
@@ -1836,7 +1857,8 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1836
1857
|
"PAPERCLIP_TASK_ID",
|
|
1837
1858
|
"PAPERCLIP_AGENT_ID",
|
|
1838
1859
|
"PAPERCLIP_COMPANY_ID",
|
|
1839
|
-
"AMASTER_EMPLOYEE_COMPANY_ID"
|
|
1860
|
+
"AMASTER_EMPLOYEE_COMPANY_ID",
|
|
1861
|
+
...MANAGED_TELEMETRY_ENV_NAMES
|
|
1840
1862
|
]);
|
|
1841
1863
|
const FORBIDDEN_ARGV = /* @__PURE__ */ new Set([
|
|
1842
1864
|
"--no-tools",
|
|
@@ -1854,7 +1876,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1854
1876
|
const PROFILE_MARKER2 = ".amaster-managed-pi-profile.json";
|
|
1855
1877
|
const SESSION_ROLLOUT_MARKER2 = ".amaster-pi-session-rollout.json";
|
|
1856
1878
|
const DEFAULT_SESSION_ROLLOUT_TTL_MS2 = 24 * 60 * 60 * 1e3;
|
|
1857
|
-
function
|
|
1879
|
+
function record4(value) {
|
|
1858
1880
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1859
1881
|
}
|
|
1860
1882
|
function npmPackageName(source) {
|
|
@@ -1867,7 +1889,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1867
1889
|
if (typeof value !== "string" || value.trim() === "") throw new Error(`pi_managed_mcp_invalid: ${label} is required`);
|
|
1868
1890
|
return value.trim();
|
|
1869
1891
|
}
|
|
1870
|
-
function
|
|
1892
|
+
function within4(candidate, root) {
|
|
1871
1893
|
const rel = relative2(root, candidate);
|
|
1872
1894
|
return rel === "" || !rel.startsWith("..") && !isAbsolute2(rel);
|
|
1873
1895
|
}
|
|
@@ -1910,7 +1932,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1910
1932
|
return matches[0];
|
|
1911
1933
|
}
|
|
1912
1934
|
function restoreManagedPiSessionRollout(input, sessionsRoot, runDir, executorHome, authority) {
|
|
1913
|
-
const session =
|
|
1935
|
+
const session = record4(input.nativeSession);
|
|
1914
1936
|
if (session.mode !== "governed_action_approval" || session.required !== true) return null;
|
|
1915
1937
|
const sessionId = nonEmpty2(session.sessionId, "nativeSession.sessionId");
|
|
1916
1938
|
const sourceRunId = nonEmpty2(session.sourceRunId, "nativeSession.sourceRunId");
|
|
@@ -1934,11 +1956,11 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1934
1956
|
throw new Error("pi_managed_mcp_session_rollout_authority_mismatch: source rollout does not match the approved continuation");
|
|
1935
1957
|
}
|
|
1936
1958
|
const sourceRollout = resolve2(cacheRoot, nonEmpty2(marker.rolloutRelativePath, "rolloutRelativePath"));
|
|
1937
|
-
if (!
|
|
1959
|
+
if (!within4(sourceRollout, cacheRoot) || lstatSync2(sourceRollout).isSymbolicLink() || !lstatSync2(sourceRollout).isFile()) {
|
|
1938
1960
|
throw new Error("pi_managed_mcp_session_rollout_unsafe: source rollout path is invalid");
|
|
1939
1961
|
}
|
|
1940
1962
|
const targetRollout = resolve2(sessionsRoot, marker.rolloutRelativePath);
|
|
1941
|
-
if (!
|
|
1963
|
+
if (!within4(targetRollout, sessionsRoot)) {
|
|
1942
1964
|
throw new Error("pi_managed_mcp_session_rollout_unsafe: target rollout path is invalid");
|
|
1943
1965
|
}
|
|
1944
1966
|
mkdirSync3(dirname3(targetRollout), { recursive: true, mode: 448 });
|
|
@@ -1960,8 +1982,8 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1960
1982
|
return tuple.join(".");
|
|
1961
1983
|
}
|
|
1962
1984
|
function validateAuthority2(input) {
|
|
1963
|
-
const runtimeAuth =
|
|
1964
|
-
const gateway =
|
|
1985
|
+
const runtimeAuth = record4(input.runtimeAuth);
|
|
1986
|
+
const gateway = record4(runtimeAuth.governedMcp);
|
|
1965
1987
|
const runId = nonEmpty2(input.runId, "runId");
|
|
1966
1988
|
if (runtimeAuth.runId !== runId) throw new Error("pi_managed_mcp_owner_mismatch: command runId does not match runtime authority");
|
|
1967
1989
|
if (gateway.schemaVersion !== SUPPORTED_SCHEMA_VERSION2) throw new Error("pi_managed_mcp_invalid: unsupported schema version");
|
|
@@ -1977,7 +1999,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
1977
1999
|
if (!Number.isFinite(expiresAt) || expiresAt <= Date.now() + 3e4) {
|
|
1978
2000
|
throw new Error("pi_managed_mcp_session_expired: Gateway session must remain valid through spawn preflight");
|
|
1979
2001
|
}
|
|
1980
|
-
const headers =
|
|
2002
|
+
const headers = record4(gateway.headers);
|
|
1981
2003
|
for (const name of REQUIRED_AUTHORITY_HEADERS2) nonEmpty2(headers[name], `headers.${name}`);
|
|
1982
2004
|
const allowedHeaderNames = /* @__PURE__ */ new Set([...REQUIRED_AUTHORITY_HEADERS2, ...runtimeAuth.issueId ? ["x-amaster-issue-id"] : []]);
|
|
1983
2005
|
if (Object.keys(headers).some((name) => !allowedHeaderNames.has(name)) || Object.keys(headers).length !== allowedHeaderNames.size) {
|
|
@@ -2006,7 +2028,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
2006
2028
|
return output;
|
|
2007
2029
|
}
|
|
2008
2030
|
function assertInvocationIsolation2(input) {
|
|
2009
|
-
for (const name of Object.keys(
|
|
2031
|
+
for (const name of Object.keys(record4(input.commandEnv))) {
|
|
2010
2032
|
if (FORBIDDEN_COMMAND_ENV2.has(name)) throw new Error(`pi_managed_mcp_env_override_blocked: ${name}`);
|
|
2011
2033
|
if (!ALLOWED_COMMAND_ENV2.has(name)) throw new Error(`pi_managed_mcp_env_injection_blocked: ${name}`);
|
|
2012
2034
|
}
|
|
@@ -2038,7 +2060,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
2038
2060
|
const value = safeProxyValue2(baseEnv?.[name], name);
|
|
2039
2061
|
if (value) env[name] = value;
|
|
2040
2062
|
}
|
|
2041
|
-
return { ...env, ...
|
|
2063
|
+
return { ...env, ...record4(commandEnv) };
|
|
2042
2064
|
}
|
|
2043
2065
|
function projectMcpConfigHasContent(filePath) {
|
|
2044
2066
|
if (!existsSync3(filePath)) return false;
|
|
@@ -2048,14 +2070,14 @@ var piManagedMcpProfileApi = (() => {
|
|
|
2048
2070
|
} catch {
|
|
2049
2071
|
return true;
|
|
2050
2072
|
}
|
|
2051
|
-
const config =
|
|
2052
|
-
return Object.keys(
|
|
2073
|
+
const config = record4(parsed);
|
|
2074
|
+
return Object.keys(record4(config.mcpServers)).length > 0 || Object.keys(record4(config.servers)).length > 0 || Array.isArray(config.imports) && config.imports.length > 0;
|
|
2053
2075
|
}
|
|
2054
2076
|
function assertNoProjectMcpOverride(cwd, runDir) {
|
|
2055
2077
|
let cursor = resolve2(cwd);
|
|
2056
2078
|
const boundary = resolve2(runDir);
|
|
2057
|
-
if (!
|
|
2058
|
-
while (
|
|
2079
|
+
if (!within4(cursor, boundary)) throw new Error("pi_managed_mcp_owner_mismatch: cwd is outside the managed run");
|
|
2080
|
+
while (within4(cursor, boundary)) {
|
|
2059
2081
|
for (const relativePath of [".mcp.json", join4(".pi", "mcp.json")]) {
|
|
2060
2082
|
const configPath = join4(cursor, relativePath);
|
|
2061
2083
|
if (projectMcpConfigHasContent(configPath)) throw new Error(`pi_managed_mcp_project_override_blocked: ${configPath}`);
|
|
@@ -2065,7 +2087,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
2065
2087
|
}
|
|
2066
2088
|
}
|
|
2067
2089
|
function selectManagedBrowserUse(sourceSettings, npmSource) {
|
|
2068
|
-
const plugin =
|
|
2090
|
+
const plugin = record4(record4(sourceSettings.plugins)[MANAGED_BROWSER_USE_PLUGIN]);
|
|
2069
2091
|
if (plugin.enabled !== true || plugin.package !== MANAGED_BROWSER_USE_PACKAGE) return null;
|
|
2070
2092
|
const packageSpec = Array.isArray(sourceSettings.packages) ? sourceSettings.packages.find((entry) => npmPackageName(entry) === MANAGED_BROWSER_USE_PACKAGE) : null;
|
|
2071
2093
|
if (typeof packageSpec !== "string") return null;
|
|
@@ -2082,7 +2104,7 @@ var piManagedMcpProfileApi = (() => {
|
|
|
2082
2104
|
if (packageMetadata.name !== MANAGED_BROWSER_USE_PACKAGE) {
|
|
2083
2105
|
throw new Error(`pi_managed_mcp_attestation_failed: enabled ${MANAGED_BROWSER_USE_PACKAGE} package identity mismatch`);
|
|
2084
2106
|
}
|
|
2085
|
-
const sourceConfig =
|
|
2107
|
+
const sourceConfig = record4(sourceSettings["pi-browser-use"]);
|
|
2086
2108
|
const config = {};
|
|
2087
2109
|
for (const key of MANAGED_BROWSER_USE_BOOLEAN_SETTINGS) {
|
|
2088
2110
|
if (typeof sourceConfig[key] === "boolean") config[key] = sourceConfig[key];
|
|
@@ -2108,6 +2130,27 @@ var piManagedMcpProfileApi = (() => {
|
|
|
2108
2130
|
}
|
|
2109
2131
|
};
|
|
2110
2132
|
}
|
|
2133
|
+
function selectManagedTelemetry(sourceSettings, npmSource) {
|
|
2134
|
+
const packageSpec = Array.isArray(sourceSettings.packages) ? sourceSettings.packages.find((entry) => npmPackageName(entry) === MANAGED_TELEMETRY_PACKAGE) : null;
|
|
2135
|
+
if (typeof packageSpec !== "string") return null;
|
|
2136
|
+
const packagePath = join4(npmSource, "node_modules", ...MANAGED_TELEMETRY_PACKAGE.split("/"), "package.json");
|
|
2137
|
+
if (!existsSync3(packagePath) || lstatSync2(packagePath).isSymbolicLink() || !lstatSync2(packagePath).isFile()) {
|
|
2138
|
+
throw new Error(`pi_managed_mcp_attestation_failed: configured ${MANAGED_TELEMETRY_PACKAGE} package is unavailable`);
|
|
2139
|
+
}
|
|
2140
|
+
let packageMetadata;
|
|
2141
|
+
try {
|
|
2142
|
+
packageMetadata = JSON.parse(readFileSync3(packagePath, "utf8"));
|
|
2143
|
+
} catch {
|
|
2144
|
+
throw new Error(`pi_managed_mcp_attestation_failed: configured ${MANAGED_TELEMETRY_PACKAGE} package metadata is invalid`);
|
|
2145
|
+
}
|
|
2146
|
+
if (packageMetadata.name !== MANAGED_TELEMETRY_PACKAGE) {
|
|
2147
|
+
throw new Error(`pi_managed_mcp_attestation_failed: configured ${MANAGED_TELEMETRY_PACKAGE} package identity mismatch`);
|
|
2148
|
+
}
|
|
2149
|
+
return {
|
|
2150
|
+
packageSpec,
|
|
2151
|
+
config: record4(sourceSettings["pi-telemetry"])
|
|
2152
|
+
};
|
|
2153
|
+
}
|
|
2111
2154
|
function seedPiRuntime(sourceHome, agentDir) {
|
|
2112
2155
|
const source = resolve2(nonEmpty2(sourceHome, "sourcePiHome"));
|
|
2113
2156
|
const npmSource = join4(source, "npm");
|
|
@@ -2126,16 +2169,22 @@ var piManagedMcpProfileApi = (() => {
|
|
|
2126
2169
|
let sourceSettings = {};
|
|
2127
2170
|
if (existsSync3(settingsSource)) {
|
|
2128
2171
|
try {
|
|
2129
|
-
sourceSettings =
|
|
2172
|
+
sourceSettings = record4(JSON.parse(readFileSync3(settingsSource, "utf8")));
|
|
2130
2173
|
} catch {
|
|
2131
2174
|
throw new Error("pi_managed_mcp_attestation_failed: source Pi settings are invalid");
|
|
2132
2175
|
}
|
|
2133
2176
|
}
|
|
2134
2177
|
const browserUse = selectManagedBrowserUse(sourceSettings, npmSource);
|
|
2178
|
+
const telemetry = selectManagedTelemetry(sourceSettings, npmSource);
|
|
2135
2179
|
const settings = {
|
|
2136
2180
|
...typeof sourceSettings.defaultProvider === "string" ? { defaultProvider: sourceSettings.defaultProvider } : {},
|
|
2137
2181
|
...typeof sourceSettings.defaultModel === "string" ? { defaultModel: sourceSettings.defaultModel } : {},
|
|
2138
|
-
packages: [
|
|
2182
|
+
packages: [
|
|
2183
|
+
"npm:pi-mcp-adapter",
|
|
2184
|
+
...telemetry ? [telemetry.packageSpec] : [],
|
|
2185
|
+
...browserUse ? [browserUse.packageSpec] : []
|
|
2186
|
+
],
|
|
2187
|
+
...telemetry ? { "pi-telemetry": telemetry.config } : {},
|
|
2139
2188
|
...browserUse ? {
|
|
2140
2189
|
plugins: {
|
|
2141
2190
|
[MANAGED_BROWSER_USE_PLUGIN]: browserUse.plugin
|
|
@@ -2189,7 +2238,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2189
2238
|
const { gateway, gatewayUrl, sessionToken, headers, runId } = validateAuthority2(input);
|
|
2190
2239
|
const runDir = resolve2(nonEmpty2(input.runDir, "runDir"));
|
|
2191
2240
|
const executorHome = resolve2(nonEmpty2(input.executorHome, "executorHome"));
|
|
2192
|
-
if (!
|
|
2241
|
+
if (!within4(executorHome, join4(runDir, "executors"))) throw new Error("pi_managed_mcp_owner_mismatch: executorHome is outside the managed run");
|
|
2193
2242
|
assertNoProjectMcpOverride(nonEmpty2(input.cwd, "cwd"), runDir);
|
|
2194
2243
|
const profileRoot = join4(executorHome, "managed-mcp");
|
|
2195
2244
|
if (existsSync3(profileRoot)) throw new Error(`pi_managed_mcp_profile_exists: ${profileRoot}`);
|
|
@@ -2204,7 +2253,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2204
2253
|
const owner = Object.freeze({ commandId: input.commandId, runId });
|
|
2205
2254
|
writePrivateFile2(markerPath, `${JSON.stringify({ version: 1, ...owner, profileRoot })}
|
|
2206
2255
|
`);
|
|
2207
|
-
const runtimeAuth =
|
|
2256
|
+
const runtimeAuth = record4(input.runtimeAuth);
|
|
2208
2257
|
const authority = Object.freeze({
|
|
2209
2258
|
companyId: nonEmpty2(runtimeAuth.companyId, "runtimeAuth.companyId"),
|
|
2210
2259
|
agentId: nonEmpty2(runtimeAuth.agentId, "runtimeAuth.agentId"),
|
|
@@ -2265,6 +2314,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2265
2314
|
protectedValues: [.../* @__PURE__ */ new Set([
|
|
2266
2315
|
sessionToken,
|
|
2267
2316
|
...seededRuntime.protectedValues,
|
|
2317
|
+
...MANAGED_TELEMETRY_PROTECTED_ENV_NAMES.map((name) => input.baseEnv?.[name]).filter((value) => typeof value === "string" && value.length > 0),
|
|
2268
2318
|
...MANAGED_PI_PROVIDER_PROTECTED_ENV_NAMES.map((name) => input.commandEnv?.[name]).filter((value) => typeof value === "string" && value.length > 0)
|
|
2269
2319
|
])],
|
|
2270
2320
|
attestation: {
|
|
@@ -2358,7 +2408,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2358
2408
|
const profileRoot = dirname3(markerPath);
|
|
2359
2409
|
try {
|
|
2360
2410
|
const marker = JSON.parse(readFileSync3(markerPath, "utf8"));
|
|
2361
|
-
if (!
|
|
2411
|
+
if (!within4(profileRoot, root) || marker?.profileRoot !== profileRoot) throw new Error("ownership marker root mismatch");
|
|
2362
2412
|
cleanupManagedPiMcpProfile2({ profileRoot }, { commandId: marker.commandId, runId: marker.runId });
|
|
2363
2413
|
removedProfiles += 1;
|
|
2364
2414
|
} catch (error) {
|
|
@@ -2373,7 +2423,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
2373
2423
|
const markerStat = lstatSync2(markerPath);
|
|
2374
2424
|
const cacheStat = lstatSync2(cacheRoot);
|
|
2375
2425
|
const marker = JSON.parse(readFileSync3(markerPath, "utf8"));
|
|
2376
|
-
if (!
|
|
2426
|
+
if (!within4(cacheRoot, root) || basename2(cacheRoot) !== "session-rollout" || markerStat.isSymbolicLink() || !markerStat.isFile() || cacheStat.isSymbolicLink() || !cacheStat.isDirectory() || marker?.version !== 1 || typeof marker?.companyId !== "string" || typeof marker?.agentId !== "string" || typeof marker?.sourceRunId !== "string" || typeof marker?.sourceCommandId !== "string" || typeof marker?.sessionId !== "string" || marker?.cacheRoot !== cacheRoot) throw new Error("session rollout ownership marker mismatch");
|
|
2377
2427
|
const preservedAtMs = typeof marker.preservedAt === "string" ? Date.parse(marker.preservedAt) : Number.NaN;
|
|
2378
2428
|
const markerAgeMs = nowMs - (Number.isFinite(preservedAtMs) ? preservedAtMs : markerStat.mtimeMs);
|
|
2379
2429
|
if (markerAgeMs < rolloutTtlMs) continue;
|
|
@@ -2461,14 +2511,42 @@ function signalExecutorProcess(child, signal, processGroupId = processGroupIdFor
|
|
|
2461
2511
|
return false;
|
|
2462
2512
|
}
|
|
2463
2513
|
|
|
2514
|
+
// src/amaster-runtime-daemon/executor-spawn.mjs
|
|
2515
|
+
function record2(value) {
|
|
2516
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2517
|
+
}
|
|
2518
|
+
function managedChildSpawnInvocation(command, args, requestedIdentity) {
|
|
2519
|
+
const identity = record2(requestedIdentity);
|
|
2520
|
+
const childUmask = identity.umask;
|
|
2521
|
+
if (childUmask !== void 0 && (!Number.isInteger(childUmask) || childUmask < 0 || childUmask > 511)) {
|
|
2522
|
+
throw new Error("executor_spawn_umask_invalid");
|
|
2523
|
+
}
|
|
2524
|
+
const spawnIdentity = { ...identity };
|
|
2525
|
+
delete spawnIdentity.umask;
|
|
2526
|
+
if (childUmask === void 0) {
|
|
2527
|
+
return { command, args, spawnIdentity };
|
|
2528
|
+
}
|
|
2529
|
+
return {
|
|
2530
|
+
command: "/bin/sh",
|
|
2531
|
+
args: [
|
|
2532
|
+
"-c",
|
|
2533
|
+
`umask ${childUmask.toString(8).padStart(4, "0")}; exec "$@"`,
|
|
2534
|
+
"amaster-managed-child",
|
|
2535
|
+
command,
|
|
2536
|
+
...args
|
|
2537
|
+
],
|
|
2538
|
+
spawnIdentity
|
|
2539
|
+
};
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2464
2542
|
// src/amaster-runtime-daemon/durability.mjs
|
|
2465
2543
|
function resultOutboxFileName(commandId, now = Date.now()) {
|
|
2466
2544
|
const safeCommandId = String(commandId ?? "command").replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
2467
2545
|
return `${now}-${safeCommandId}.json`;
|
|
2468
2546
|
}
|
|
2469
2547
|
function isValidResultOutboxEntry(entry) {
|
|
2470
|
-
const
|
|
2471
|
-
return
|
|
2548
|
+
const record4 = asRecord(entry);
|
|
2549
|
+
return record4.version === 1 && Boolean(readString(record4.path)) && Object.keys(asRecord(record4.payload)).length > 0;
|
|
2472
2550
|
}
|
|
2473
2551
|
function resultOutboxEntryAgeMs(entry, nowMs) {
|
|
2474
2552
|
const createdAt = Date.parse(readString(entry.createdAt) ?? "");
|
|
@@ -2489,6 +2567,15 @@ var RECOVERY_WAKE_REASONS = /* @__PURE__ */ new Set([
|
|
|
2489
2567
|
function isRecoveryWakeReason(wakeReason) {
|
|
2490
2568
|
return RECOVERY_WAKE_REASONS.has(wakeReason);
|
|
2491
2569
|
}
|
|
2570
|
+
function stringifyBoundedJson(value, maxChars = 24e3) {
|
|
2571
|
+
let text = "";
|
|
2572
|
+
try {
|
|
2573
|
+
text = JSON.stringify(value, null, 2);
|
|
2574
|
+
} catch {
|
|
2575
|
+
text = String(value);
|
|
2576
|
+
}
|
|
2577
|
+
return truncateText(text, maxChars);
|
|
2578
|
+
}
|
|
2492
2579
|
function jsonText(value) {
|
|
2493
2580
|
return JSON.stringify(value, null, 2);
|
|
2494
2581
|
}
|
|
@@ -2546,8 +2633,8 @@ function governedReadSection(context) {
|
|
|
2546
2633
|
const reads = Array.isArray(context.governedReadResults) ? context.governedReadResults : [];
|
|
2547
2634
|
if (reads.length === 0) return { content: "", provenance: [] };
|
|
2548
2635
|
const normalized = reads.map((entry, index) => {
|
|
2549
|
-
const
|
|
2550
|
-
const receipt = asRecord(
|
|
2636
|
+
const record4 = asRecord(entry);
|
|
2637
|
+
const receipt = asRecord(record4.receipt);
|
|
2551
2638
|
const provider = readString(receipt.provider) ?? readString(receipt.transport);
|
|
2552
2639
|
const operation = readString(receipt.operation);
|
|
2553
2640
|
const observedAt = readString(receipt.retrievedAt) ?? readString(receipt.observedAt);
|
|
@@ -2557,7 +2644,7 @@ function governedReadSection(context) {
|
|
|
2557
2644
|
throw new Error(`governed_read_context_provenance_invalid: entry ${index} requires provider, operation, observedAt, and source`);
|
|
2558
2645
|
}
|
|
2559
2646
|
return {
|
|
2560
|
-
content:
|
|
2647
|
+
content: record4.content,
|
|
2561
2648
|
receipt: {
|
|
2562
2649
|
provider,
|
|
2563
2650
|
operation,
|
|
@@ -2590,6 +2677,7 @@ function fixedRules(input, includeIssueLine) {
|
|
|
2590
2677
|
`- command id: ${input.commandId}`,
|
|
2591
2678
|
`- run id: ${input.runId ?? "unknown"}`,
|
|
2592
2679
|
`- issue id: ${input.issueId ?? "unknown"}`,
|
|
2680
|
+
input.currentDate ? `- current date: ${input.currentDate}` : "",
|
|
2593
2681
|
includeIssueLine && input.issueLine ? `- issue: ${input.issueLine}` : "",
|
|
2594
2682
|
`- workspace: ${input.cwd}`,
|
|
2595
2683
|
input.managed ? `- source workspace: ${input.sourceWorkspacePath}` : "",
|
|
@@ -2606,6 +2694,17 @@ function approvalContinuationText(input) {
|
|
|
2606
2694
|
"Do not advance to another write action until that exact call returns status succeeded."
|
|
2607
2695
|
].join("\n");
|
|
2608
2696
|
}
|
|
2697
|
+
function interactionResolutionText(context) {
|
|
2698
|
+
const direct = asRecord(context.interactionResolution);
|
|
2699
|
+
const wakeResolution = asRecord(asRecord(context.paperclipWake).interactionResolution);
|
|
2700
|
+
const resolution = Object.keys(direct).length > 0 ? direct : wakeResolution;
|
|
2701
|
+
if (Object.keys(resolution).length === 0) return "";
|
|
2702
|
+
return [
|
|
2703
|
+
"Treat this resolved interaction as the authoritative delta for this run.",
|
|
2704
|
+
readString(resolution.status) === "changes_requested" ? "Apply every requested change before creating a replacement review." : "",
|
|
2705
|
+
stringifyBoundedJson(resolution, 8e3)
|
|
2706
|
+
].filter(Boolean).join("\n");
|
|
2707
|
+
}
|
|
2609
2708
|
function recoveryInstructionText(input) {
|
|
2610
2709
|
const context = asRecord(input.context);
|
|
2611
2710
|
if (input.wakeReason === "finish_successful_run_handoff" && context.handoffRequired === true) {
|
|
@@ -2613,6 +2712,8 @@ function recoveryInstructionText(input) {
|
|
|
2613
2712
|
"The prior successful run did not leave a terminal task disposition.",
|
|
2614
2713
|
"Do not repeat the original source work or create or revise deliverables.",
|
|
2615
2714
|
"Inspect the existing task and run evidence, then choose exactly one explicit disposition: done, in_review, input, blocked, delegated, or queued.",
|
|
2715
|
+
"If more work remains on this issue, call `update_parent` with `status: todo`, preserve the current agent owner, and record the concrete next action.",
|
|
2716
|
+
"Do not keep or write `in_progress`: only the actual `todo` issue update is a recognized resume disposition and lets the control plane queue a normal-model continuation.",
|
|
2616
2717
|
"Record the disposition with its concrete owner or next action and update the task accordingly."
|
|
2617
2718
|
].join("\n");
|
|
2618
2719
|
}
|
|
@@ -2647,6 +2748,28 @@ function runtimeAuthorizationText(context) {
|
|
|
2647
2748
|
"Never use request_confirmation to authorize a runtime action class."
|
|
2648
2749
|
].join("\n");
|
|
2649
2750
|
}
|
|
2751
|
+
function runtimeDecompositionRequirementText(context) {
|
|
2752
|
+
const issue = asRecord(context.paperclipIssue);
|
|
2753
|
+
const requirements = asRecord(issue.taskRequirements);
|
|
2754
|
+
const decomposition = asRecord(requirements.decomposition);
|
|
2755
|
+
if (decomposition.mode !== "required") return "";
|
|
2756
|
+
const children = Array.isArray(context.childIssueSummaries) ? context.childIssueSummaries : [];
|
|
2757
|
+
if (children.length > 0) return "";
|
|
2758
|
+
const source = asRecord(decomposition.source);
|
|
2759
|
+
const sourceType = readString(source.type);
|
|
2760
|
+
const sourceId = readString(source.id);
|
|
2761
|
+
const sourceRevision = readString(source.revision);
|
|
2762
|
+
if (!sourceType || !sourceId || !sourceRevision) {
|
|
2763
|
+
throw new Error("runtime_decomposition_requirement_invalid: required mode needs typed source provenance");
|
|
2764
|
+
}
|
|
2765
|
+
return [
|
|
2766
|
+
"This issue has a server-enforced typed decomposition requirement.",
|
|
2767
|
+
"Create real direct child tasks before continuing substantial source work.",
|
|
2768
|
+
"Each executable child must have an owner, dependencies where needed, and acceptance criteria. Do not create probe or test children.",
|
|
2769
|
+
"Preserve every parent safety and approval boundary in each child title, description, and acceptance criteria. If the parent prohibits registration, payment, booking, or external contact without later explicit authorization, create preparation or approval only children and do not assign the prohibited action.",
|
|
2770
|
+
`Requirement source: ${sourceType}:${sourceId}@${sourceRevision}`
|
|
2771
|
+
].join("\n");
|
|
2772
|
+
}
|
|
2650
2773
|
function sectionText(section) {
|
|
2651
2774
|
if (!section.content) return "";
|
|
2652
2775
|
return section.title ? `## ${section.title}
|
|
@@ -2716,6 +2839,15 @@ function compileCommandPromptWithManifest(input, options = {}) {
|
|
|
2716
2839
|
const wakeBodies = commentBodies(context);
|
|
2717
2840
|
const commentsDuplicatedByTask = hasTask && wakeBodies.length > 0 && wakeBodies.every((body) => taskText.includes(body));
|
|
2718
2841
|
const commentsSelected = mode !== "cold" || !commentsDuplicatedByTask;
|
|
2842
|
+
const interactionResolution = interactionResolutionText(context);
|
|
2843
|
+
const selectedComments = commentsSelected ? readString(input.comments) ?? "" : "";
|
|
2844
|
+
const wakeDeltaContent = [interactionResolution, selectedComments].filter(Boolean).join("\n\n");
|
|
2845
|
+
const wakeDeltaOriginal = [interactionResolution, readString(input.comments) ?? ""].filter(Boolean).join("\n\n");
|
|
2846
|
+
const wakeDeltaTitle = interactionResolution ? selectedComments ? "Wake Delta" : "Resolved Interaction Input" : "Wake Comment Delta";
|
|
2847
|
+
const wakeDeltaSourceRefs = [
|
|
2848
|
+
...readString(context.interactionId) ? [`interaction:${readString(context.interactionId)}`] : [],
|
|
2849
|
+
...commentRefs(context).map((id) => `comment:${id}`)
|
|
2850
|
+
];
|
|
2719
2851
|
const contextScope = {
|
|
2720
2852
|
companyId: readString(asRecord(context.paperclipCompany).id),
|
|
2721
2853
|
issueId: input.issueId ?? null
|
|
@@ -2726,8 +2858,9 @@ function compileCommandPromptWithManifest(input, options = {}) {
|
|
|
2726
2858
|
{ name: "recovery_instruction", title: "Recovery Instruction", priority: 99, sourceRef: `run:${input.runId ?? "unknown"}`, content: recoveryInstructionText(input), truncationReason: isRecoveryWakeReason(input.wakeReason) ? null : "mode_selection" },
|
|
2727
2859
|
{ name: "approval_continuation", title: "Approved Runtime Action Continuation", priority: 99, sourceRef: `run:${input.runId ?? "unknown"}`, content: approvalContinuationText(input), truncationReason: mode === "continuation" ? null : "mode_selection" },
|
|
2728
2860
|
{ name: "runtime_authorization", title: "Runtime Action Authorization", priority: 98, sourceRef: `run:${input.runId ?? "unknown"}`, content: runtimeAuthorizationText(context) },
|
|
2861
|
+
{ name: "runtime_decomposition_requirement", title: "Required Task Decomposition", priority: 98, sourceRef: `issue:${input.issueId ?? "unknown"}`, content: runtimeDecompositionRequirementText(context) },
|
|
2729
2862
|
{ name: "continuation_summary", title: "Continuation Summary", priority: 97, sourceRef: readString(asRecord(context.paperclipContinuationSummary).key) ?? `issue:${input.issueId ?? "unknown"}`, observedAt: readString(asRecord(context.paperclipContinuationSummary).updatedAt), originalContent: continuationSummary, content: mode === "cold" ? "" : continuationSummary, truncationReason: mode === "cold" ? "mode_selection" : null },
|
|
2730
|
-
{ name: "wake_comments", title:
|
|
2863
|
+
{ name: "wake_comments", title: wakeDeltaTitle, priority: interactionResolution ? 99 : 95, sourceRef: wakeDeltaSourceRefs, originalContent: wakeDeltaOriginal, content: wakeDeltaContent, truncationReason: commentsSelected ? null : "duplicate_task_context" },
|
|
2731
2864
|
{ name: "task", title: "Task Context", priority: 90, sourceRef: `issue:${input.issueId ?? "unknown"}`, originalContent: taskText, content: includeTask ? taskText : "", truncationReason: includeTask ? null : "mode_selection" },
|
|
2732
2865
|
{ name: "governed_reads", title: "Governed External Reads", priority: 88, sourceRef: governedReads.provenance.map((entry) => entry.sourceRef), observedAt: governedReads.provenance.map((entry) => entry.observedAt), freshness: governedReads.provenance.map((entry) => entry.freshness), scope: governedReads.provenance.map((entry) => entry.scope), content: governedReads.content },
|
|
2733
2866
|
{ name: "agent_instructions", title: "Agent Instructions", priority: 85, sourceRef: "agent_instructions_bundle", content: readString(input.agentInstructions) ?? "" },
|
|
@@ -3097,10 +3230,10 @@ function compactExecutorJsonlForTranscript(event) {
|
|
|
3097
3230
|
const text = JSON.stringify(compactExecutorJsonValue(event, stringMaxChars));
|
|
3098
3231
|
if (text.length <= 15e3) return text;
|
|
3099
3232
|
}
|
|
3100
|
-
const
|
|
3101
|
-
const item = tcAsRecord(
|
|
3233
|
+
const record4 = tcAsRecord(event);
|
|
3234
|
+
const item = tcAsRecord(record4.item);
|
|
3102
3235
|
return JSON.stringify({
|
|
3103
|
-
type: tcReadString(
|
|
3236
|
+
type: tcReadString(record4.type) ?? "executor.event",
|
|
3104
3237
|
item: item.type ? {
|
|
3105
3238
|
id: tcReadString(item.id),
|
|
3106
3239
|
type: tcReadString(item.type),
|
|
@@ -3113,10 +3246,10 @@ function compactExecutorJsonlForTranscript(event) {
|
|
|
3113
3246
|
});
|
|
3114
3247
|
}
|
|
3115
3248
|
function summarizeTokenUsage(usage) {
|
|
3116
|
-
const
|
|
3117
|
-
const inputTokens = tcReadNumber(
|
|
3118
|
-
const cachedInputTokens = tcReadNumber(
|
|
3119
|
-
const outputTokens = tcReadNumber(
|
|
3249
|
+
const record4 = tcAsRecord(usage);
|
|
3250
|
+
const inputTokens = tcReadNumber(record4.input_tokens ?? record4.inputTokens, 0);
|
|
3251
|
+
const cachedInputTokens = tcReadNumber(record4.cached_input_tokens ?? record4.cachedInputTokens, 0);
|
|
3252
|
+
const outputTokens = tcReadNumber(record4.output_tokens ?? record4.outputTokens, 0);
|
|
3120
3253
|
const parts = [];
|
|
3121
3254
|
if (inputTokens > 0) parts.push(`\u8F93\u5165 ${inputTokens}`);
|
|
3122
3255
|
if (cachedInputTokens > 0) parts.push(`\u7F13\u5B58 ${cachedInputTokens}`);
|
|
@@ -3371,8 +3504,8 @@ function summarizeClaudeEvent(event) {
|
|
|
3371
3504
|
return null;
|
|
3372
3505
|
}
|
|
3373
3506
|
function tcPiMessageText(message) {
|
|
3374
|
-
const
|
|
3375
|
-
const content =
|
|
3507
|
+
const record4 = tcAsRecord(message);
|
|
3508
|
+
const content = record4.content;
|
|
3376
3509
|
if (typeof content === "string" && content.trim().length > 0) return content.trim();
|
|
3377
3510
|
if (!Array.isArray(content)) return "";
|
|
3378
3511
|
return content.map((entry) => {
|
|
@@ -3386,14 +3519,14 @@ function tcPiAssistantMessageEventText(assistantMessageEvent) {
|
|
|
3386
3519
|
return tcReadString(event.content) ?? "";
|
|
3387
3520
|
}
|
|
3388
3521
|
function tcPiMessageStopReason(message) {
|
|
3389
|
-
const
|
|
3390
|
-
return tcReadString(
|
|
3522
|
+
const record4 = tcAsRecord(message);
|
|
3523
|
+
return tcReadString(record4.stopReason ?? record4.stop_reason);
|
|
3391
3524
|
}
|
|
3392
3525
|
function tcPiMessageErrorText(message) {
|
|
3393
|
-
const
|
|
3394
|
-
const explicitError = tcReadString(
|
|
3526
|
+
const record4 = tcAsRecord(message);
|
|
3527
|
+
const explicitError = tcReadString(record4.errorMessage ?? record4.error_message)?.trim();
|
|
3395
3528
|
if (explicitError) return explicitError;
|
|
3396
|
-
const stopReason = tcPiMessageStopReason(
|
|
3529
|
+
const stopReason = tcPiMessageStopReason(record4);
|
|
3397
3530
|
if (stopReason === "error" || stopReason === "failed" || stopReason === "exception") {
|
|
3398
3531
|
return `Pi Agent message ended with stopReason=${stopReason}`;
|
|
3399
3532
|
}
|
|
@@ -3553,6 +3686,10 @@ function shouldPreserveExecutorJsonlForTranscript(executorKind, event) {
|
|
|
3553
3686
|
var CODEX_TRANSIENT_UPSTREAM_RE = /(?:we(?:'|’)re\s+currently\s+experiencing\s+high\s+demand|temporary\s+errors|rate[-\s]?limit(?:ed)?|too\s+many\s+requests|\b429\b|server\s+overloaded|service\s+unavailable|try\s+again\s+later)/i;
|
|
3554
3687
|
var CODEX_REMOTE_COMPACTION_RE = /remote\s+compact\s+task/i;
|
|
3555
3688
|
var CODEX_USAGE_LIMIT_RE = /you(?:'|’)ve hit your usage limit for .+\.\s+switch to another model now,\s+or try again at\s+([^.!\n]+)(?:[.!]|\n|$)/i;
|
|
3689
|
+
var PI_PROVIDER_AUTH_RE = /(?:(?:\b401\b|\b403\b)[^\n]*(?:unauthorized|forbidden|auth(?:entication|orization)?|api[_\s-]?key)|(?:invalid|missing|expired|revoked)\s+(?:provider\s+)?api[_\s-]?key|provider\s+authentication\s+required)/i;
|
|
3690
|
+
var PI_PROVIDER_TRANSIENT_RE = /(?:\b(?:429|5\d{2})\b|rate[-\s]?limit(?:ed)?|too\s+many\s+requests|billing\s+admission\s+failed|service\s+unavailable|upstream[^\n]*(?:unavailable|failed|timeout)|connect(?:ion)?[^\n]*refused|temporar(?:y|ily)[^\n]*(?:unavailable|failed)|try\s+again\s+later)/i;
|
|
3691
|
+
var PI_PROVIDER_RETRY_AFTER_SECONDS_RE = /retry[-\s]?after\s*[:=]?\s*(\d{1,6})\s*(?:seconds?|secs?|s)\b/i;
|
|
3692
|
+
var MAX_PI_PROVIDER_RETRY_AFTER_SECONDS = 7 * 24 * 60 * 60;
|
|
3556
3693
|
function approvedMcpInvocationSucceeded(results, invocationId) {
|
|
3557
3694
|
const approvedInvocationId = readString(invocationId);
|
|
3558
3695
|
return Boolean(approvedInvocationId && (Array.isArray(results) ? results : []).some((rawResult) => {
|
|
@@ -3767,6 +3904,32 @@ function classifyCodexTransientUpstreamError(input, now = /* @__PURE__ */ new Da
|
|
|
3767
3904
|
...retryNotBefore ? { retryNotBefore: retryNotBefore.toISOString() } : {}
|
|
3768
3905
|
};
|
|
3769
3906
|
}
|
|
3907
|
+
function extractPiProviderRetryNotBefore(errorMessage, now) {
|
|
3908
|
+
const retryAfter = errorMessage.match(PI_PROVIDER_RETRY_AFTER_SECONDS_RE);
|
|
3909
|
+
if (!retryAfter) return null;
|
|
3910
|
+
const seconds = Number.parseInt(retryAfter[1] ?? "", 10);
|
|
3911
|
+
if (!Number.isSafeInteger(seconds) || seconds < 0 || seconds > MAX_PI_PROVIDER_RETRY_AFTER_SECONDS) {
|
|
3912
|
+
return null;
|
|
3913
|
+
}
|
|
3914
|
+
return new Date(now.getTime() + seconds * 1e3);
|
|
3915
|
+
}
|
|
3916
|
+
function classifyPiProviderError(input, now = /* @__PURE__ */ new Date()) {
|
|
3917
|
+
const errorMessage = readString(asRecord(input).errorMessage);
|
|
3918
|
+
if (!errorMessage) return null;
|
|
3919
|
+
if (PI_PROVIDER_AUTH_RE.test(errorMessage)) {
|
|
3920
|
+
return {
|
|
3921
|
+
errorCode: "pi_provider_auth_required",
|
|
3922
|
+
errorFamily: "configuration"
|
|
3923
|
+
};
|
|
3924
|
+
}
|
|
3925
|
+
if (!PI_PROVIDER_TRANSIENT_RE.test(errorMessage)) return null;
|
|
3926
|
+
const retryNotBefore = extractPiProviderRetryNotBefore(errorMessage, now);
|
|
3927
|
+
return {
|
|
3928
|
+
errorCode: "pi_transient_upstream",
|
|
3929
|
+
errorFamily: "transient_upstream",
|
|
3930
|
+
...retryNotBefore ? { retryNotBefore: retryNotBefore.toISOString() } : {}
|
|
3931
|
+
};
|
|
3932
|
+
}
|
|
3770
3933
|
function parseClaudeStreamJson(stdout) {
|
|
3771
3934
|
let sessionId = null;
|
|
3772
3935
|
let summary = "";
|
|
@@ -3813,13 +3976,13 @@ function parseClaudeStreamJson(stdout) {
|
|
|
3813
3976
|
}
|
|
3814
3977
|
function openCodeErrorText(value) {
|
|
3815
3978
|
if (typeof value === "string") return value;
|
|
3816
|
-
const
|
|
3817
|
-
const message = readString(
|
|
3979
|
+
const record4 = asRecord(value);
|
|
3980
|
+
const message = readString(record4.message);
|
|
3818
3981
|
if (message) return message;
|
|
3819
|
-
const data = asRecord(
|
|
3982
|
+
const data = asRecord(record4.data);
|
|
3820
3983
|
const nestedMessage = readString(data.message);
|
|
3821
3984
|
if (nestedMessage) return nestedMessage;
|
|
3822
|
-
return readString(
|
|
3985
|
+
return readString(record4.name) ?? readString(record4.code) ?? "";
|
|
3823
3986
|
}
|
|
3824
3987
|
function parseOpenCodeJsonl(stdout) {
|
|
3825
3988
|
let sessionId = null;
|
|
@@ -3857,8 +4020,8 @@ function parseOpenCodeJsonl(stdout) {
|
|
|
3857
4020
|
return { sessionId, summary, usage, errorMessage };
|
|
3858
4021
|
}
|
|
3859
4022
|
function piMessageText(message) {
|
|
3860
|
-
const
|
|
3861
|
-
const content =
|
|
4023
|
+
const record4 = asRecord(message);
|
|
4024
|
+
const content = record4.content;
|
|
3862
4025
|
if (typeof content === "string") return content.trim();
|
|
3863
4026
|
if (!Array.isArray(content)) return "";
|
|
3864
4027
|
return content.map((entry) => {
|
|
@@ -3883,10 +4046,10 @@ function piTextValue(value) {
|
|
|
3883
4046
|
return typeof value === "string" && value.length > 0 ? value : "";
|
|
3884
4047
|
}
|
|
3885
4048
|
function piAssistantEventText(assistantEvent) {
|
|
3886
|
-
const
|
|
3887
|
-
const type = readString(
|
|
3888
|
-
if (type === "text_delta") return piTextValue(
|
|
3889
|
-
if (type === "text_end") return piTextValue(
|
|
4049
|
+
const record4 = asRecord(assistantEvent);
|
|
4050
|
+
const type = readString(record4.type);
|
|
4051
|
+
if (type === "text_delta") return piTextValue(record4.delta);
|
|
4052
|
+
if (type === "text_end") return piTextValue(record4.content);
|
|
3890
4053
|
return "";
|
|
3891
4054
|
}
|
|
3892
4055
|
function piMessageUsage(message) {
|
|
@@ -3907,14 +4070,14 @@ function assignPiUsage(target, source) {
|
|
|
3907
4070
|
if (source.costUsd > 0) target.costUsd = source.costUsd;
|
|
3908
4071
|
}
|
|
3909
4072
|
function piMessageStopReason(message) {
|
|
3910
|
-
const
|
|
3911
|
-
return readString(
|
|
4073
|
+
const record4 = asRecord(message);
|
|
4074
|
+
return readString(record4.stopReason ?? record4.stop_reason);
|
|
3912
4075
|
}
|
|
3913
4076
|
function piMessageErrorText(message) {
|
|
3914
|
-
const
|
|
3915
|
-
const explicitError = readString(
|
|
4077
|
+
const record4 = asRecord(message);
|
|
4078
|
+
const explicitError = readString(record4.errorMessage ?? record4.error_message)?.trim();
|
|
3916
4079
|
if (explicitError) return explicitError;
|
|
3917
|
-
const stopReason = piMessageStopReason(
|
|
4080
|
+
const stopReason = piMessageStopReason(record4);
|
|
3918
4081
|
if (stopReason === "error" || stopReason === "failed" || stopReason === "exception") {
|
|
3919
4082
|
return `Pi Agent message ended with stopReason=${stopReason}`;
|
|
3920
4083
|
}
|
|
@@ -4206,7 +4369,7 @@ async function postRuntimeConnectorJsonWithRetry(config, path, payload, options
|
|
|
4206
4369
|
} catch (error) {
|
|
4207
4370
|
lastError = error;
|
|
4208
4371
|
if (attempt >= maxAttempts || !retryableRuntimeConnectorPost(error)) throw error;
|
|
4209
|
-
if (delayMs > 0) await new Promise((
|
|
4372
|
+
if (delayMs > 0) await new Promise((resolve12) => setTimeout(resolve12, delayMs));
|
|
4210
4373
|
}
|
|
4211
4374
|
}
|
|
4212
4375
|
throw lastError;
|
|
@@ -4290,14 +4453,25 @@ function prepareRuntimeArtifactUploads(cwd, mcpToolResults) {
|
|
|
4290
4453
|
}
|
|
4291
4454
|
|
|
4292
4455
|
// src/amaster-runtime-daemon/runtime-artifact-ingest-queue.mjs
|
|
4456
|
+
function normalizedError(caught) {
|
|
4457
|
+
return caught instanceof Error ? caught : new Error(String(caught));
|
|
4458
|
+
}
|
|
4459
|
+
var RuntimeArtifactIngestAggregateError = class extends AggregateError {
|
|
4460
|
+
constructor(errors, receipts) {
|
|
4461
|
+
super(errors, `${errors.length} Runtime Artifact ingest operation(s) failed`);
|
|
4462
|
+
this.name = "RuntimeArtifactIngestAggregateError";
|
|
4463
|
+
this.code = errors.some((error) => error.code === "runtime_artifact_rejected") ? "runtime_artifact_rejected" : "runtime_artifact_ingest_failed";
|
|
4464
|
+
this.failures = [...errors];
|
|
4465
|
+
this.receipts = [...receipts];
|
|
4466
|
+
}
|
|
4467
|
+
};
|
|
4293
4468
|
function createRuntimeArtifactIngestQueue({ ingest, onError }) {
|
|
4294
4469
|
const handledIntentIds = /* @__PURE__ */ new Set();
|
|
4295
4470
|
const artifacts = [];
|
|
4296
|
-
|
|
4471
|
+
const errors = [];
|
|
4297
4472
|
let queue = Promise.resolve();
|
|
4298
4473
|
return {
|
|
4299
4474
|
enqueue(results) {
|
|
4300
|
-
if (error) return;
|
|
4301
4475
|
const pending = results.filter((result2) => {
|
|
4302
4476
|
const intentId = readString(asRecord(result2).artifactIntent?.intentId);
|
|
4303
4477
|
if (!intentId || handledIntentIds.has(intentId)) return false;
|
|
@@ -4306,8 +4480,12 @@ function createRuntimeArtifactIngestQueue({ ingest, onError }) {
|
|
|
4306
4480
|
});
|
|
4307
4481
|
if (pending.length === 0) return;
|
|
4308
4482
|
queue = queue.then(async () => artifacts.push(...await ingest(pending))).catch((caught) => {
|
|
4309
|
-
|
|
4310
|
-
|
|
4483
|
+
const aggregate = caught instanceof RuntimeArtifactIngestAggregateError ? caught : null;
|
|
4484
|
+
artifacts.push(...aggregate?.receipts ?? []);
|
|
4485
|
+
for (const error of aggregate?.failures ?? [normalizedError(caught)]) {
|
|
4486
|
+
errors.push(error);
|
|
4487
|
+
onError?.(error);
|
|
4488
|
+
}
|
|
4311
4489
|
});
|
|
4312
4490
|
},
|
|
4313
4491
|
hasHandled(intentId) {
|
|
@@ -4315,7 +4493,9 @@ function createRuntimeArtifactIngestQueue({ ingest, onError }) {
|
|
|
4315
4493
|
},
|
|
4316
4494
|
async flush() {
|
|
4317
4495
|
await queue;
|
|
4318
|
-
if (
|
|
4496
|
+
if (errors.length > 0) {
|
|
4497
|
+
throw new RuntimeArtifactIngestAggregateError(errors, artifacts);
|
|
4498
|
+
}
|
|
4319
4499
|
return [...artifacts];
|
|
4320
4500
|
}
|
|
4321
4501
|
};
|
|
@@ -4845,18 +5025,24 @@ function createPiChildIdentityAllocator(input = {}) {
|
|
|
4845
5025
|
const runAssignments = /* @__PURE__ */ new Map();
|
|
4846
5026
|
const uidAssignments = /* @__PURE__ */ new Map();
|
|
4847
5027
|
return {
|
|
4848
|
-
acquire(runId) {
|
|
5028
|
+
acquire(runId, options = {}) {
|
|
4849
5029
|
if (typeof runId !== "string" || runId.trim().length === 0) {
|
|
4850
5030
|
throw new Error("pi_child_isolation_run_id_required");
|
|
4851
5031
|
}
|
|
4852
5032
|
const normalizedRunId = runId.trim();
|
|
4853
5033
|
const existing = runAssignments.get(normalizedRunId);
|
|
4854
|
-
|
|
5034
|
+
const requestedGid = options.gid === void 0 ? null : positiveInteger(options.gid, "gid");
|
|
5035
|
+
if (existing) {
|
|
5036
|
+
if (requestedGid !== null && existing.gid !== requestedGid) {
|
|
5037
|
+
throw new Error("pi_child_isolation_run_gid_mismatch");
|
|
5038
|
+
}
|
|
5039
|
+
return { ...existing };
|
|
5040
|
+
}
|
|
4855
5041
|
const initialOffset = Math.abs(hashRunId(normalizedRunId)) % uidSpan;
|
|
4856
5042
|
for (let attempt = 0; attempt < uidSpan; attempt += 1) {
|
|
4857
5043
|
const uid = uidBase + (initialOffset + attempt) % uidSpan;
|
|
4858
5044
|
if (uidAssignments.has(uid)) continue;
|
|
4859
|
-
const assignment = { uid, gid: uid };
|
|
5045
|
+
const assignment = { uid, gid: requestedGid ?? uid };
|
|
4860
5046
|
runAssignments.set(normalizedRunId, assignment);
|
|
4861
5047
|
uidAssignments.set(uid, normalizedRunId);
|
|
4862
5048
|
return { ...assignment };
|
|
@@ -4895,7 +5081,9 @@ function preparePiChildIsolation(input) {
|
|
|
4895
5081
|
if (!isWithin(input.profileRoot, input.allowedRoot) || !isWithin(input.workspaceRoot, input.allowedRoot)) {
|
|
4896
5082
|
throw new Error("pi_child_isolation_path_outside_run_root");
|
|
4897
5083
|
}
|
|
4898
|
-
const assignment = input.allocator.acquire(input.runId
|
|
5084
|
+
const assignment = input.allocator.acquire(input.runId, {
|
|
5085
|
+
...input.gid === void 0 ? {} : { gid: input.gid }
|
|
5086
|
+
});
|
|
4899
5087
|
const isolatePath = input.isolatePath ?? isolatePiChildPath;
|
|
4900
5088
|
try {
|
|
4901
5089
|
for (const path of [resolve7(input.profileRoot), resolve7(input.workspaceRoot)]) {
|
|
@@ -4906,7 +5094,7 @@ function preparePiChildIsolation(input) {
|
|
|
4906
5094
|
throw error;
|
|
4907
5095
|
}
|
|
4908
5096
|
return {
|
|
4909
|
-
spawn: { uid: assignment.uid, gid: assignment.gid },
|
|
5097
|
+
spawn: { uid: assignment.uid, gid: assignment.gid, umask: 7 },
|
|
4910
5098
|
attestation: {
|
|
4911
5099
|
schemaVersion: "amaster.pi-child-isolation.v1",
|
|
4912
5100
|
commandId: input.commandId,
|
|
@@ -4919,21 +5107,248 @@ function preparePiChildIsolation(input) {
|
|
|
4919
5107
|
};
|
|
4920
5108
|
}
|
|
4921
5109
|
|
|
4922
|
-
// src/amaster-runtime-daemon/pi-
|
|
5110
|
+
// src/amaster-runtime-daemon/pi-company-memory.mjs
|
|
4923
5111
|
import { createHash as createHash6 } from "node:crypto";
|
|
4924
5112
|
import {
|
|
4925
5113
|
chmodSync as chmodSync4,
|
|
4926
|
-
|
|
5114
|
+
chownSync as chownSync2,
|
|
4927
5115
|
existsSync as existsSync9,
|
|
5116
|
+
lchownSync as lchownSync2,
|
|
4928
5117
|
lstatSync as lstatSync5,
|
|
4929
5118
|
mkdirSync as mkdirSync6,
|
|
4930
5119
|
readFileSync as readFileSync7,
|
|
4931
|
-
|
|
5120
|
+
renameSync as renameSync4,
|
|
4932
5121
|
rmSync as rmSync5,
|
|
4933
5122
|
symlinkSync as symlinkSync2,
|
|
4934
5123
|
writeFileSync as writeFileSync6
|
|
4935
5124
|
} from "node:fs";
|
|
4936
5125
|
import { dirname as dirname7, isAbsolute as isAbsolute5, join as join10, relative as relative5, resolve as resolve8 } from "node:path";
|
|
5126
|
+
var REGISTRY_FILENAME = ".amaster-company-memory-groups.json";
|
|
5127
|
+
var COMPANY_MARKER_FILENAME = ".amaster-company-memory.json";
|
|
5128
|
+
var REGISTRY_VERSION = 1;
|
|
5129
|
+
var COMPANY_MARKER_VERSION = 1;
|
|
5130
|
+
var DEFAULT_GID_BASE = 1e5;
|
|
5131
|
+
var DEFAULT_GID_SPAN = 1e6;
|
|
5132
|
+
var defaultFs2 = {
|
|
5133
|
+
chmodSync: chmodSync4,
|
|
5134
|
+
chownSync: chownSync2,
|
|
5135
|
+
existsSync: existsSync9,
|
|
5136
|
+
lchownSync: lchownSync2,
|
|
5137
|
+
lstatSync: lstatSync5,
|
|
5138
|
+
mkdirSync: mkdirSync6,
|
|
5139
|
+
readFileSync: readFileSync7,
|
|
5140
|
+
renameSync: renameSync4,
|
|
5141
|
+
rmSync: rmSync5,
|
|
5142
|
+
symlinkSync: symlinkSync2,
|
|
5143
|
+
writeFileSync: writeFileSync6
|
|
5144
|
+
};
|
|
5145
|
+
function requiredString2(value, label) {
|
|
5146
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
5147
|
+
throw new Error(`pi_company_memory_invalid:${label}`);
|
|
5148
|
+
}
|
|
5149
|
+
return value.trim();
|
|
5150
|
+
}
|
|
5151
|
+
function positiveInteger2(value, label) {
|
|
5152
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
5153
|
+
throw new Error(`pi_company_memory_invalid:${label}`);
|
|
5154
|
+
}
|
|
5155
|
+
return value;
|
|
5156
|
+
}
|
|
5157
|
+
function within2(candidate, root) {
|
|
5158
|
+
const rel = relative5(root, candidate);
|
|
5159
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute5(rel);
|
|
5160
|
+
}
|
|
5161
|
+
function assertDirectory(path, label, fs) {
|
|
5162
|
+
const stat = fs.lstatSync(path);
|
|
5163
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
5164
|
+
throw new Error(`pi_company_memory_unsafe:${label}`);
|
|
5165
|
+
}
|
|
5166
|
+
}
|
|
5167
|
+
function readJson(path, label, fs) {
|
|
5168
|
+
try {
|
|
5169
|
+
const value = JSON.parse(fs.readFileSync(path, "utf8"));
|
|
5170
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5171
|
+
throw new Error("not an object");
|
|
5172
|
+
}
|
|
5173
|
+
return value;
|
|
5174
|
+
} catch {
|
|
5175
|
+
throw new Error(`pi_company_memory_invalid:${label}`);
|
|
5176
|
+
}
|
|
5177
|
+
}
|
|
5178
|
+
function writeJsonAtomic(path, value, mode, fs) {
|
|
5179
|
+
const tempPath = `${path}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
5180
|
+
try {
|
|
5181
|
+
fs.writeFileSync(tempPath, `${JSON.stringify(value, null, 2)}
|
|
5182
|
+
`, {
|
|
5183
|
+
mode,
|
|
5184
|
+
flag: "wx"
|
|
5185
|
+
});
|
|
5186
|
+
fs.chmodSync(tempPath, mode);
|
|
5187
|
+
fs.renameSync(tempPath, path);
|
|
5188
|
+
} catch (error) {
|
|
5189
|
+
fs.rmSync(tempPath, { force: true });
|
|
5190
|
+
throw error;
|
|
5191
|
+
}
|
|
5192
|
+
}
|
|
5193
|
+
function safeCompanyPiHomeSegment(companyId) {
|
|
5194
|
+
const raw = requiredString2(companyId, "companyId");
|
|
5195
|
+
if (/^[A-Za-z0-9][A-Za-z0-9._-]{0,119}$/.test(raw)) return raw;
|
|
5196
|
+
const normalized = raw.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^[._-]+|[._-]+$/g, "").slice(0, 80);
|
|
5197
|
+
const hash = createHash6("sha256").update(raw).digest("hex").slice(0, 12);
|
|
5198
|
+
return normalized ? `${normalized}-${hash}` : `company-${hash}`;
|
|
5199
|
+
}
|
|
5200
|
+
function ensureMemoryRoot(root, fs) {
|
|
5201
|
+
if (!fs.existsSync(root)) fs.mkdirSync(root, { recursive: true, mode: 457 });
|
|
5202
|
+
assertDirectory(root, "root", fs);
|
|
5203
|
+
fs.chownSync(root, 0, 0);
|
|
5204
|
+
fs.chmodSync(root, 457);
|
|
5205
|
+
}
|
|
5206
|
+
function readGroupRegistry(root, fs) {
|
|
5207
|
+
const path = join10(root, REGISTRY_FILENAME);
|
|
5208
|
+
if (!fs.existsSync(path)) {
|
|
5209
|
+
return { path, groups: {} };
|
|
5210
|
+
}
|
|
5211
|
+
const registryStat = fs.lstatSync(path);
|
|
5212
|
+
if (!registryStat.isFile() || registryStat.isSymbolicLink()) {
|
|
5213
|
+
throw new Error("pi_company_memory_unsafe:group_registry");
|
|
5214
|
+
}
|
|
5215
|
+
const registry = readJson(path, "group_registry", fs);
|
|
5216
|
+
if (registry.version !== REGISTRY_VERSION || !registry.groups || typeof registry.groups !== "object" || Array.isArray(registry.groups)) {
|
|
5217
|
+
throw new Error("pi_company_memory_invalid:group_registry");
|
|
5218
|
+
}
|
|
5219
|
+
const groups = {};
|
|
5220
|
+
const used = /* @__PURE__ */ new Set();
|
|
5221
|
+
for (const [companyId, rawGid] of Object.entries(registry.groups)) {
|
|
5222
|
+
const gid = positiveInteger2(rawGid, "registeredGid");
|
|
5223
|
+
if (used.has(gid)) throw new Error("pi_company_memory_invalid:duplicate_registered_gid");
|
|
5224
|
+
groups[requiredString2(companyId, "registeredCompanyId")] = gid;
|
|
5225
|
+
used.add(gid);
|
|
5226
|
+
}
|
|
5227
|
+
return { path, groups };
|
|
5228
|
+
}
|
|
5229
|
+
function allocateCompanyGid(root, companyId, input, fs) {
|
|
5230
|
+
const gidBase = positiveInteger2(input.gidBase ?? DEFAULT_GID_BASE, "gidBase");
|
|
5231
|
+
const gidSpan = positiveInteger2(input.gidSpan ?? DEFAULT_GID_SPAN, "gidSpan");
|
|
5232
|
+
const { path, groups } = readGroupRegistry(root, fs);
|
|
5233
|
+
if (groups[companyId]) return groups[companyId];
|
|
5234
|
+
const used = new Set(Object.values(groups));
|
|
5235
|
+
const initialOffset = Number.parseInt(
|
|
5236
|
+
createHash6("sha256").update(companyId).digest("hex").slice(0, 12),
|
|
5237
|
+
16
|
|
5238
|
+
) % gidSpan;
|
|
5239
|
+
let gid = null;
|
|
5240
|
+
for (let attempt = 0; attempt < gidSpan; attempt += 1) {
|
|
5241
|
+
const candidate = gidBase + (initialOffset + attempt) % gidSpan;
|
|
5242
|
+
if (!used.has(candidate)) {
|
|
5243
|
+
gid = candidate;
|
|
5244
|
+
break;
|
|
5245
|
+
}
|
|
5246
|
+
}
|
|
5247
|
+
if (!gid) throw new Error("pi_company_memory_gid_pool_exhausted");
|
|
5248
|
+
writeJsonAtomic(path, {
|
|
5249
|
+
version: REGISTRY_VERSION,
|
|
5250
|
+
groups: {
|
|
5251
|
+
...groups,
|
|
5252
|
+
[companyId]: gid
|
|
5253
|
+
}
|
|
5254
|
+
}, 384, fs);
|
|
5255
|
+
return gid;
|
|
5256
|
+
}
|
|
5257
|
+
function resolveCompanyPiMemoryGroup(input, fs = defaultFs2) {
|
|
5258
|
+
const root = resolve8(requiredString2(input.root, "root"));
|
|
5259
|
+
const companyId = requiredString2(input.companyId, "companyId");
|
|
5260
|
+
ensureMemoryRoot(root, fs);
|
|
5261
|
+
return {
|
|
5262
|
+
root,
|
|
5263
|
+
companyId,
|
|
5264
|
+
gid: allocateCompanyGid(root, companyId, input, fs)
|
|
5265
|
+
};
|
|
5266
|
+
}
|
|
5267
|
+
function ensurePrivateDirectory(path, mode, uid, gid, fs) {
|
|
5268
|
+
if (!fs.existsSync(path)) fs.mkdirSync(path, { recursive: false, mode });
|
|
5269
|
+
assertDirectory(path, "directory", fs);
|
|
5270
|
+
fs.chownSync(path, uid, gid);
|
|
5271
|
+
fs.chmodSync(path, mode);
|
|
5272
|
+
}
|
|
5273
|
+
function prepareCompanyPiMemory(input, fs = defaultFs2) {
|
|
5274
|
+
const root = resolve8(requiredString2(input.root, "root"));
|
|
5275
|
+
const profileRoot = resolve8(requiredString2(input.profileRoot, "profileRoot"));
|
|
5276
|
+
const profileHome = resolve8(requiredString2(input.profileHome, "profileHome"));
|
|
5277
|
+
const companyId = requiredString2(input.companyId, "companyId");
|
|
5278
|
+
const childUid = positiveInteger2(input.childUid, "childUid");
|
|
5279
|
+
if (!within2(profileHome, profileRoot)) {
|
|
5280
|
+
throw new Error("pi_company_memory_profile_path_escape");
|
|
5281
|
+
}
|
|
5282
|
+
assertDirectory(profileRoot, "profile_root", fs);
|
|
5283
|
+
assertDirectory(profileHome, "profile_home", fs);
|
|
5284
|
+
const group = resolveCompanyPiMemoryGroup({ ...input, root, companyId }, fs);
|
|
5285
|
+
const gid = group.gid;
|
|
5286
|
+
if (input.gid !== void 0 && positiveInteger2(input.gid, "gid") !== gid) {
|
|
5287
|
+
throw new Error("pi_company_memory_gid_mismatch");
|
|
5288
|
+
}
|
|
5289
|
+
const companyDir = join10(root, safeCompanyPiHomeSegment(companyId));
|
|
5290
|
+
const companyPiHome = join10(companyDir, ".pi");
|
|
5291
|
+
const memoryDir = join10(companyPiHome, "memories");
|
|
5292
|
+
ensurePrivateDirectory(companyDir, 456, 0, gid, fs);
|
|
5293
|
+
const markerPath = join10(companyDir, COMPANY_MARKER_FILENAME);
|
|
5294
|
+
if (fs.existsSync(markerPath)) {
|
|
5295
|
+
const markerStat = fs.lstatSync(markerPath);
|
|
5296
|
+
if (!markerStat.isFile() || markerStat.isSymbolicLink()) {
|
|
5297
|
+
throw new Error("pi_company_memory_unsafe:company_marker");
|
|
5298
|
+
}
|
|
5299
|
+
const marker = readJson(markerPath, "company_marker", fs);
|
|
5300
|
+
if (marker.version !== COMPANY_MARKER_VERSION || marker.companyId !== companyId || marker.gid !== gid) {
|
|
5301
|
+
throw new Error("pi_company_memory_authority_mismatch");
|
|
5302
|
+
}
|
|
5303
|
+
} else {
|
|
5304
|
+
writeJsonAtomic(markerPath, {
|
|
5305
|
+
version: COMPANY_MARKER_VERSION,
|
|
5306
|
+
companyId,
|
|
5307
|
+
gid,
|
|
5308
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5309
|
+
}, 384, fs);
|
|
5310
|
+
}
|
|
5311
|
+
fs.chownSync(markerPath, 0, 0);
|
|
5312
|
+
fs.chmodSync(markerPath, 384);
|
|
5313
|
+
ensurePrivateDirectory(companyPiHome, 456, 0, gid, fs);
|
|
5314
|
+
if (!fs.existsSync(memoryDir)) fs.mkdirSync(memoryDir, { recursive: false, mode: 1528 });
|
|
5315
|
+
assertDirectory(memoryDir, "memories", fs);
|
|
5316
|
+
fs.chownSync(memoryDir, 0, gid);
|
|
5317
|
+
fs.chmodSync(memoryDir, 1528);
|
|
5318
|
+
const memoryLink = join10(profileHome, "memories");
|
|
5319
|
+
if (fs.existsSync(memoryLink)) {
|
|
5320
|
+
throw new Error("pi_company_memory_profile_link_exists");
|
|
5321
|
+
}
|
|
5322
|
+
fs.symlinkSync(memoryDir, memoryLink, "dir");
|
|
5323
|
+
fs.lchownSync(memoryLink, childUid, gid);
|
|
5324
|
+
return {
|
|
5325
|
+
gid,
|
|
5326
|
+
memoryDir,
|
|
5327
|
+
memoryLink,
|
|
5328
|
+
attestation: {
|
|
5329
|
+
schemaVersion: "amaster.company-pi-memory.v1",
|
|
5330
|
+
companyId,
|
|
5331
|
+
gid,
|
|
5332
|
+
mode: "run_scoped_home_company_memory"
|
|
5333
|
+
}
|
|
5334
|
+
};
|
|
5335
|
+
}
|
|
5336
|
+
|
|
5337
|
+
// src/amaster-runtime-daemon/pi-trusted-runtime-profile.mjs
|
|
5338
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
5339
|
+
import {
|
|
5340
|
+
chmodSync as chmodSync5,
|
|
5341
|
+
copyFileSync as copyFileSync2,
|
|
5342
|
+
existsSync as existsSync10,
|
|
5343
|
+
lstatSync as lstatSync6,
|
|
5344
|
+
mkdirSync as mkdirSync7,
|
|
5345
|
+
readFileSync as readFileSync8,
|
|
5346
|
+
readdirSync as readdirSync6,
|
|
5347
|
+
rmSync as rmSync6,
|
|
5348
|
+
symlinkSync as symlinkSync3,
|
|
5349
|
+
writeFileSync as writeFileSync7
|
|
5350
|
+
} from "node:fs";
|
|
5351
|
+
import { dirname as dirname8, isAbsolute as isAbsolute6, join as join11, relative as relative6, resolve as resolve9 } from "node:path";
|
|
4937
5352
|
var ASSERTION_VERSION = "2026-07-25.v1";
|
|
4938
5353
|
var SHA256 = /^[a-f0-9]{64}$/;
|
|
4939
5354
|
var COPY_ENTRIES = ["SYSTEM.md", "policy", "skills", "agents", "bundles", "extensions"];
|
|
@@ -4942,23 +5357,23 @@ var SECRET_KEY = /(authorization|cookie|api[_-]?key|password|secret|token)$/i;
|
|
|
4942
5357
|
var SECRET_VALUE = /(?:authorization|cookie|api[_-]?key|password|secret|token)\s*[:=]\s*(?:bearer\s+)?[^\s"',;]+|bearer\s+[^\s"',;]+/i;
|
|
4943
5358
|
var MAX_AUDIT_BYTES = 1024 * 1024;
|
|
4944
5359
|
var MAX_AUDIT_EVENTS = 2e3;
|
|
4945
|
-
function
|
|
5360
|
+
function requiredString3(value, field) {
|
|
4946
5361
|
if (typeof value !== "string" || value.trim() === "") {
|
|
4947
5362
|
throw new Error(`pi_trusted_runtime_assertion_invalid:${field}`);
|
|
4948
5363
|
}
|
|
4949
5364
|
return value.trim();
|
|
4950
5365
|
}
|
|
4951
5366
|
function requiredDigest(value, field) {
|
|
4952
|
-
const digest =
|
|
5367
|
+
const digest = requiredString3(value, field);
|
|
4953
5368
|
if (!SHA256.test(digest)) throw new Error(`pi_trusted_runtime_assertion_invalid:${field}`);
|
|
4954
5369
|
return digest;
|
|
4955
5370
|
}
|
|
4956
5371
|
function sha256File(path, label) {
|
|
4957
|
-
const stat =
|
|
5372
|
+
const stat = lstatSync6(path);
|
|
4958
5373
|
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
4959
5374
|
throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
|
|
4960
5375
|
}
|
|
4961
|
-
return
|
|
5376
|
+
return createHash7("sha256").update(readFileSync8(path)).digest("hex");
|
|
4962
5377
|
}
|
|
4963
5378
|
function verifyDeclaredFiles(manifest, root, label, ignoredPaths = [], enforceComplete = true) {
|
|
4964
5379
|
if (!Array.isArray(manifest.files) || manifest.files.length === 0) {
|
|
@@ -4966,10 +5381,10 @@ function verifyDeclaredFiles(manifest, root, label, ignoredPaths = [], enforceCo
|
|
|
4966
5381
|
}
|
|
4967
5382
|
const seen = /* @__PURE__ */ new Set();
|
|
4968
5383
|
for (const entry of manifest.files) {
|
|
4969
|
-
const relativePath =
|
|
5384
|
+
const relativePath = requiredString3(entry?.path, `${label}.files.path`);
|
|
4970
5385
|
const expectedDigest = requiredDigest(entry?.sha256, `${label}.files.sha256`);
|
|
4971
|
-
const filePath =
|
|
4972
|
-
if (!
|
|
5386
|
+
const filePath = resolve9(root, relativePath);
|
|
5387
|
+
if (!within3(filePath, root) || seen.has(relativePath)) {
|
|
4973
5388
|
throw new Error(`pi_trusted_runtime_source_invalid:${label}_files`);
|
|
4974
5389
|
}
|
|
4975
5390
|
seen.add(relativePath);
|
|
@@ -4981,9 +5396,9 @@ function verifyDeclaredFiles(manifest, root, label, ignoredPaths = [], enforceCo
|
|
|
4981
5396
|
const ignored = ignoredPaths.map((path) => path.split("\\").join("/"));
|
|
4982
5397
|
const visit = (directory) => {
|
|
4983
5398
|
for (const entry of readdirSync6(directory)) {
|
|
4984
|
-
const filePath =
|
|
4985
|
-
const relativePath =
|
|
4986
|
-
const stat =
|
|
5399
|
+
const filePath = join11(directory, entry);
|
|
5400
|
+
const relativePath = relative6(root, filePath).split("\\").join("/");
|
|
5401
|
+
const stat = lstatSync6(filePath);
|
|
4987
5402
|
if (stat.isSymbolicLink()) {
|
|
4988
5403
|
throw new Error(`pi_trusted_runtime_source_unsafe:${label}_file`);
|
|
4989
5404
|
}
|
|
@@ -4999,21 +5414,21 @@ function verifyDeclaredFiles(manifest, root, label, ignoredPaths = [], enforceCo
|
|
|
4999
5414
|
};
|
|
5000
5415
|
visit(root);
|
|
5001
5416
|
}
|
|
5002
|
-
function
|
|
5417
|
+
function record3(value) {
|
|
5003
5418
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
5004
5419
|
}
|
|
5005
|
-
function
|
|
5006
|
-
const rel =
|
|
5007
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
5420
|
+
function within3(candidate, root) {
|
|
5421
|
+
const rel = relative6(root, candidate);
|
|
5422
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute6(rel);
|
|
5008
5423
|
}
|
|
5009
5424
|
function readJsonFile2(path, label, fallback = {}) {
|
|
5010
|
-
if (!
|
|
5011
|
-
const stat =
|
|
5425
|
+
if (!existsSync10(path)) return fallback;
|
|
5426
|
+
const stat = lstatSync6(path);
|
|
5012
5427
|
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
5013
5428
|
throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
|
|
5014
5429
|
}
|
|
5015
5430
|
try {
|
|
5016
|
-
return JSON.parse(
|
|
5431
|
+
return JSON.parse(readFileSync8(path, "utf8"));
|
|
5017
5432
|
} catch {
|
|
5018
5433
|
throw new Error(`pi_trusted_runtime_source_invalid:${label}`);
|
|
5019
5434
|
}
|
|
@@ -5041,32 +5456,32 @@ function assertNoPersistentSecrets(value, path = []) {
|
|
|
5041
5456
|
}
|
|
5042
5457
|
}
|
|
5043
5458
|
function copyTreeNoLinks(source, target) {
|
|
5044
|
-
const stat =
|
|
5459
|
+
const stat = lstatSync6(source);
|
|
5045
5460
|
if (stat.isSymbolicLink()) throw new Error("pi_trusted_runtime_source_symlink_blocked");
|
|
5046
5461
|
if (stat.isDirectory()) {
|
|
5047
|
-
|
|
5048
|
-
|
|
5462
|
+
mkdirSync7(target, { recursive: true, mode: 448 });
|
|
5463
|
+
chmodSync5(target, 448);
|
|
5049
5464
|
for (const entry of readdirSync6(source)) {
|
|
5050
|
-
copyTreeNoLinks(
|
|
5465
|
+
copyTreeNoLinks(join11(source, entry), join11(target, entry));
|
|
5051
5466
|
}
|
|
5052
5467
|
return;
|
|
5053
5468
|
}
|
|
5054
5469
|
if (!stat.isFile()) throw new Error("pi_trusted_runtime_source_type_blocked");
|
|
5055
|
-
|
|
5470
|
+
mkdirSync7(dirname8(target), { recursive: true, mode: 448 });
|
|
5056
5471
|
copyFileSync2(source, target);
|
|
5057
|
-
|
|
5472
|
+
chmodSync5(target, 384 | stat.mode & 73);
|
|
5058
5473
|
}
|
|
5059
5474
|
function mergeMcp(seedRoot, overlayRoot, governedConfig) {
|
|
5060
|
-
const seed =
|
|
5061
|
-
const overlay =
|
|
5475
|
+
const seed = record3(readJsonFile2(join11(seedRoot, "mcp.json"), "seed_mcp", { mcpServers: {} }));
|
|
5476
|
+
const overlay = record3(readJsonFile2(join11(overlayRoot, "mcp.json"), "overlay_mcp", { mcpServers: {} }));
|
|
5062
5477
|
assertNoPersistentSecrets(seed, ["seed", "mcp.json"]);
|
|
5063
5478
|
assertNoPersistentSecrets(overlay, ["overlay", "mcp.json"]);
|
|
5064
|
-
const seedServers =
|
|
5065
|
-
const overlayServers =
|
|
5479
|
+
const seedServers = record3(seed.mcpServers);
|
|
5480
|
+
const overlayServers = record3(overlay.mcpServers);
|
|
5066
5481
|
if ("amaster" in seedServers || "amaster" in overlayServers) {
|
|
5067
5482
|
throw new Error("pi_trusted_runtime_reserved_mcp_override:amaster");
|
|
5068
5483
|
}
|
|
5069
|
-
const governed =
|
|
5484
|
+
const governed = record3(record3(governedConfig).mcpServers).amaster;
|
|
5070
5485
|
if (!governed) throw new Error("pi_trusted_runtime_governed_mcp_missing");
|
|
5071
5486
|
return {
|
|
5072
5487
|
...deepMerge(seed, overlay),
|
|
@@ -5086,14 +5501,14 @@ function assertEnabledPackagesAvailable(settings, npmRoot) {
|
|
|
5086
5501
|
const requiredNames = new Set(
|
|
5087
5502
|
(Array.isArray(settings.packages) ? settings.packages : []).map(packageName).filter(Boolean)
|
|
5088
5503
|
);
|
|
5089
|
-
for (const plugin of Object.values(
|
|
5090
|
-
const config =
|
|
5504
|
+
for (const plugin of Object.values(record3(settings.plugins))) {
|
|
5505
|
+
const config = record3(plugin);
|
|
5091
5506
|
if (config.enabled === true && typeof config.package === "string") {
|
|
5092
5507
|
requiredNames.add(config.package);
|
|
5093
5508
|
}
|
|
5094
5509
|
}
|
|
5095
5510
|
for (const name of requiredNames) {
|
|
5096
|
-
const metadataPath =
|
|
5511
|
+
const metadataPath = join11(npmRoot, "node_modules", ...name.split("/"), "package.json");
|
|
5097
5512
|
const metadata = readJsonFile2(metadataPath, `package:${name}`, null);
|
|
5098
5513
|
if (!metadata || metadata.name !== name) {
|
|
5099
5514
|
throw new Error(`pi_trusted_runtime_package_unavailable:${name}`);
|
|
@@ -5101,62 +5516,62 @@ function assertEnabledPackagesAvailable(settings, npmRoot) {
|
|
|
5101
5516
|
}
|
|
5102
5517
|
}
|
|
5103
5518
|
function materializeTrustedPiRuntimeProfile(input) {
|
|
5104
|
-
const seedRoot =
|
|
5105
|
-
const overlayRoot =
|
|
5106
|
-
const profileRoot =
|
|
5107
|
-
const agentDir =
|
|
5108
|
-
if (!
|
|
5519
|
+
const seedRoot = resolve9(requiredString3(input.seedRoot, "seedRoot"));
|
|
5520
|
+
const overlayRoot = resolve9(requiredString3(input.overlayRoot, "overlayRoot"));
|
|
5521
|
+
const profileRoot = resolve9(requiredString3(input.profileRoot, "profileRoot"));
|
|
5522
|
+
const agentDir = resolve9(requiredString3(input.agentDir, "agentDir"));
|
|
5523
|
+
if (!within3(agentDir, profileRoot)) throw new Error("pi_trusted_runtime_profile_path_escape");
|
|
5109
5524
|
for (const [root, label] of [[seedRoot, "seed_root"], [overlayRoot, "overlay_root"]]) {
|
|
5110
|
-
const stat =
|
|
5525
|
+
const stat = lstatSync6(root);
|
|
5111
5526
|
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
5112
5527
|
throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
|
|
5113
5528
|
}
|
|
5114
5529
|
}
|
|
5115
5530
|
for (const entry of COPY_ENTRIES) {
|
|
5116
|
-
const target =
|
|
5117
|
-
|
|
5531
|
+
const target = join11(agentDir, entry);
|
|
5532
|
+
rmSync6(target, { recursive: true, force: true });
|
|
5118
5533
|
for (const sourceRoot of [seedRoot, overlayRoot]) {
|
|
5119
|
-
const source =
|
|
5120
|
-
if (
|
|
5534
|
+
const source = join11(sourceRoot, entry);
|
|
5535
|
+
if (existsSync10(source)) copyTreeNoLinks(source, target);
|
|
5121
5536
|
}
|
|
5122
5537
|
}
|
|
5123
5538
|
const mergedJson = {};
|
|
5124
5539
|
for (const entry of JSON_ENTRIES) {
|
|
5125
|
-
const seed = readJsonFile2(
|
|
5126
|
-
const overlay = readJsonFile2(
|
|
5540
|
+
const seed = readJsonFile2(join11(seedRoot, entry), `seed_${entry}`, {});
|
|
5541
|
+
const overlay = readJsonFile2(join11(overlayRoot, entry), `overlay_${entry}`, {});
|
|
5127
5542
|
const merged = deepMerge(seed, overlay);
|
|
5128
5543
|
if (entry === "settings.json") {
|
|
5129
5544
|
merged["pi-security"] = {
|
|
5130
|
-
...
|
|
5545
|
+
...record3(merged["pi-security"]),
|
|
5131
5546
|
enabled: true,
|
|
5132
5547
|
approvals: {
|
|
5133
|
-
...
|
|
5548
|
+
...record3(record3(merged["pi-security"]).approvals),
|
|
5134
5549
|
allowSessionGrants: false
|
|
5135
5550
|
}
|
|
5136
5551
|
};
|
|
5137
5552
|
}
|
|
5138
5553
|
assertNoPersistentSecrets(merged, [entry]);
|
|
5139
|
-
|
|
5554
|
+
writeFileSync7(join11(agentDir, entry), `${JSON.stringify(merged, null, 2)}
|
|
5140
5555
|
`, {
|
|
5141
5556
|
mode: 384
|
|
5142
5557
|
});
|
|
5143
|
-
|
|
5558
|
+
chmodSync5(join11(agentDir, entry), 384);
|
|
5144
5559
|
mergedJson[entry] = merged;
|
|
5145
5560
|
}
|
|
5146
5561
|
const governedConfig = readJsonFile2(input.governedMcpConfigPath, "governed_mcp");
|
|
5147
5562
|
const mcp = mergeMcp(seedRoot, overlayRoot, governedConfig);
|
|
5148
|
-
|
|
5563
|
+
writeFileSync7(input.governedMcpConfigPath, `${JSON.stringify(mcp, null, 2)}
|
|
5149
5564
|
`, { mode: 384 });
|
|
5150
|
-
|
|
5151
|
-
const npmRoot =
|
|
5565
|
+
chmodSync5(input.governedMcpConfigPath, 384);
|
|
5566
|
+
const npmRoot = join11(seedRoot, "npm");
|
|
5152
5567
|
assertEnabledPackagesAvailable(mergedJson["settings.json"], npmRoot);
|
|
5153
|
-
const npmTarget =
|
|
5154
|
-
|
|
5155
|
-
const npmStat =
|
|
5568
|
+
const npmTarget = join11(agentDir, "npm");
|
|
5569
|
+
rmSync6(npmTarget, { recursive: true, force: true });
|
|
5570
|
+
const npmStat = lstatSync6(npmRoot);
|
|
5156
5571
|
if (!npmStat.isDirectory() || npmStat.isSymbolicLink()) {
|
|
5157
5572
|
throw new Error("pi_trusted_runtime_source_unsafe:seed_npm");
|
|
5158
5573
|
}
|
|
5159
|
-
|
|
5574
|
+
symlinkSync3(npmRoot, npmTarget, "dir");
|
|
5160
5575
|
const facts = {
|
|
5161
5576
|
schemaVersion: "amaster.trusted-pi-profile.v1",
|
|
5162
5577
|
seedManifestDigest: input.verifiedAssertion.digests.seedManifestDigest,
|
|
@@ -5169,7 +5584,7 @@ function materializeTrustedPiRuntimeProfile(input) {
|
|
|
5169
5584
|
};
|
|
5170
5585
|
return {
|
|
5171
5586
|
facts,
|
|
5172
|
-
attestationId:
|
|
5587
|
+
attestationId: createHash7("sha256").update(JSON.stringify(facts)).digest("hex")
|
|
5173
5588
|
};
|
|
5174
5589
|
}
|
|
5175
5590
|
function assertAuditArgsRedacted(value) {
|
|
@@ -5192,16 +5607,16 @@ function assertAuditArgsRedacted(value) {
|
|
|
5192
5607
|
}
|
|
5193
5608
|
}
|
|
5194
5609
|
function readTrustedPiRuntimeAudit(input) {
|
|
5195
|
-
const profileRoot =
|
|
5196
|
-
const auditFile =
|
|
5197
|
-
if (!
|
|
5198
|
-
if (!
|
|
5199
|
-
const stat =
|
|
5610
|
+
const profileRoot = resolve9(requiredString3(input.profileRoot, "profileRoot"));
|
|
5611
|
+
const auditFile = resolve9(requiredString3(input.auditFile, "auditFile"));
|
|
5612
|
+
if (!within3(auditFile, profileRoot)) throw new Error("pi_trusted_runtime_audit_path_escape");
|
|
5613
|
+
if (!existsSync10(auditFile)) throw new Error("pi_trusted_runtime_audit_startup_missing");
|
|
5614
|
+
const stat = lstatSync6(auditFile);
|
|
5200
5615
|
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
5201
5616
|
throw new Error("pi_trusted_runtime_audit_unsafe");
|
|
5202
5617
|
}
|
|
5203
5618
|
if (stat.size > MAX_AUDIT_BYTES) throw new Error("pi_trusted_runtime_audit_too_large");
|
|
5204
|
-
const lines =
|
|
5619
|
+
const lines = readFileSync8(auditFile, "utf8").split("\n").filter(Boolean);
|
|
5205
5620
|
if (lines.length === 0 || lines.length > MAX_AUDIT_EVENTS) {
|
|
5206
5621
|
throw new Error("pi_trusted_runtime_audit_event_count_invalid");
|
|
5207
5622
|
}
|
|
@@ -5249,20 +5664,20 @@ function readTrustedPiRuntimeAudit(input) {
|
|
|
5249
5664
|
};
|
|
5250
5665
|
}
|
|
5251
5666
|
function readTrustedPiRuntimeLocalDigests(input) {
|
|
5252
|
-
const seedRoot =
|
|
5253
|
-
const overlayRoot =
|
|
5254
|
-
const policyFile =
|
|
5667
|
+
const seedRoot = resolve9(requiredString3(input.seedRoot, "seedRoot"));
|
|
5668
|
+
const overlayRoot = resolve9(requiredString3(input.overlayRoot, "overlayRoot"));
|
|
5669
|
+
const policyFile = resolve9(requiredString3(input.policyFile, "policyFile"));
|
|
5255
5670
|
for (const [path, label] of [[seedRoot, "seed_root"], [overlayRoot, "overlay_root"]]) {
|
|
5256
|
-
const stat =
|
|
5671
|
+
const stat = lstatSync6(path);
|
|
5257
5672
|
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
5258
5673
|
throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
|
|
5259
5674
|
}
|
|
5260
5675
|
}
|
|
5261
|
-
const seedManifestFile =
|
|
5262
|
-
const overlayManifestFile =
|
|
5263
|
-
const seedManifest = JSON.parse(
|
|
5264
|
-
const overlayManifest = JSON.parse(
|
|
5265
|
-
const policyManifest = JSON.parse(
|
|
5676
|
+
const seedManifestFile = join11(seedRoot, "seed-manifest.json");
|
|
5677
|
+
const overlayManifestFile = join11(overlayRoot, "runtime-overlay-manifest.json");
|
|
5678
|
+
const seedManifest = JSON.parse(readFileSync8(seedManifestFile, "utf8"));
|
|
5679
|
+
const overlayManifest = JSON.parse(readFileSync8(overlayManifestFile, "utf8"));
|
|
5680
|
+
const policyManifest = JSON.parse(readFileSync8(policyFile, "utf8"));
|
|
5266
5681
|
verifyDeclaredFiles(seedManifest, seedRoot, "seed", [
|
|
5267
5682
|
"seed-manifest.json",
|
|
5268
5683
|
"npm/package-lock.json",
|
|
@@ -5271,9 +5686,9 @@ function readTrustedPiRuntimeLocalDigests(input) {
|
|
|
5271
5686
|
verifyDeclaredFiles(overlayManifest, overlayRoot, "overlay", ["runtime-overlay-manifest.json"]);
|
|
5272
5687
|
verifyDeclaredFiles(
|
|
5273
5688
|
policyManifest,
|
|
5274
|
-
|
|
5689
|
+
dirname8(policyFile),
|
|
5275
5690
|
"policy",
|
|
5276
|
-
[
|
|
5691
|
+
[relative6(dirname8(policyFile), policyFile)],
|
|
5277
5692
|
false
|
|
5278
5693
|
);
|
|
5279
5694
|
return {
|
|
@@ -5319,16 +5734,16 @@ function verifyTrustedPiRuntimeAssertion(input) {
|
|
|
5319
5734
|
leaseId: input.leaseId,
|
|
5320
5735
|
executorKind: input.executorKind
|
|
5321
5736
|
};
|
|
5322
|
-
|
|
5737
|
+
requiredString3(assertion.attestationId, "attestationId");
|
|
5323
5738
|
for (const [field, expected] of Object.entries(bindings)) {
|
|
5324
|
-
if (
|
|
5739
|
+
if (requiredString3(assertion[field], field) !== expected) {
|
|
5325
5740
|
throw new Error(`pi_trusted_runtime_assertion_binding_mismatch:${field}`);
|
|
5326
5741
|
}
|
|
5327
5742
|
}
|
|
5328
5743
|
if (assertion.executorKind !== "pi") {
|
|
5329
5744
|
throw new Error("pi_trusted_runtime_assertion_binding_mismatch:executorKind");
|
|
5330
5745
|
}
|
|
5331
|
-
const expiresAt = Date.parse(
|
|
5746
|
+
const expiresAt = Date.parse(requiredString3(assertion.expiresAt, "expiresAt"));
|
|
5332
5747
|
const now = input.now instanceof Date ? input.now : new Date(input.now ?? Date.now());
|
|
5333
5748
|
if (!Number.isFinite(expiresAt) || input.verifyExpiry !== false && expiresAt <= now.getTime()) {
|
|
5334
5749
|
throw new Error("pi_trusted_runtime_assertion_expired");
|
|
@@ -5365,9 +5780,9 @@ function verifyTrustedPiRuntimeAssertion(input) {
|
|
|
5365
5780
|
|
|
5366
5781
|
// src/amaster-runtime-daemon/workspace-status.mjs
|
|
5367
5782
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
5368
|
-
import { createHash as
|
|
5369
|
-
import { existsSync as
|
|
5370
|
-
import { basename as basename5, extname, isAbsolute as
|
|
5783
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
5784
|
+
import { existsSync as existsSync11, readdirSync as readdirSync7, readFileSync as readFileSync9, statSync as statSync6 } from "node:fs";
|
|
5785
|
+
import { basename as basename5, extname, isAbsolute as isAbsolute7, join as join12, relative as relative7, resolve as resolve10 } from "node:path";
|
|
5371
5786
|
var WORKSPACE_RUNTIME_SERVICES_FILENAME = ".amaster-runtime-services.json";
|
|
5372
5787
|
var ARTIFACT_EXTENSIONS = /* @__PURE__ */ new Map([
|
|
5373
5788
|
[".md", "markdown"],
|
|
@@ -5412,11 +5827,11 @@ var SAFE_RUNTIME_SERVICE_STATUSES = /* @__PURE__ */ new Set(["starting", "runnin
|
|
|
5412
5827
|
var SAFE_RUNTIME_SERVICE_HEALTH_STATUSES = /* @__PURE__ */ new Set(["unknown", "healthy", "unhealthy"]);
|
|
5413
5828
|
var SAFE_RUNTIME_SERVICE_LIFECYCLES = /* @__PURE__ */ new Set(["shared", "ephemeral"]);
|
|
5414
5829
|
function statusPathWithin(candidate, root) {
|
|
5415
|
-
const rel =
|
|
5416
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
5830
|
+
const rel = relative7(root, candidate);
|
|
5831
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute7(rel);
|
|
5417
5832
|
}
|
|
5418
5833
|
function normalizeRelativePath(root, filePath) {
|
|
5419
|
-
return
|
|
5834
|
+
return relative7(root, filePath).split(/[\\/]+/).join("/");
|
|
5420
5835
|
}
|
|
5421
5836
|
function isSafeRelativePath(value) {
|
|
5422
5837
|
const text = String(value ?? "").trim().split(/[\\/]+/).join("/");
|
|
@@ -5436,7 +5851,7 @@ function sanitizeTrackedChange(line) {
|
|
|
5436
5851
|
return isSafeRelativePath(path) ? line : null;
|
|
5437
5852
|
}
|
|
5438
5853
|
function sha256File2(filePath) {
|
|
5439
|
-
return
|
|
5854
|
+
return createHash8("sha256").update(readFileSync9(filePath)).digest("hex");
|
|
5440
5855
|
}
|
|
5441
5856
|
function artifactHashCacheKey(relativePath, stat) {
|
|
5442
5857
|
return `${relativePath}\0${stat.size}\0${stat.mtimeMs}`;
|
|
@@ -5464,7 +5879,7 @@ function artifactSha256(filePath, relativePath, stat, opts = {}) {
|
|
|
5464
5879
|
return hash;
|
|
5465
5880
|
}
|
|
5466
5881
|
function scanArtifactCandidates(cwd, opts = {}) {
|
|
5467
|
-
const root =
|
|
5882
|
+
const root = resolve10(cwd);
|
|
5468
5883
|
const maxCandidates = opts.maxCandidates ?? MAX_CANDIDATES;
|
|
5469
5884
|
const maxEntries = opts.maxEntries ?? MAX_SCAN_ENTRIES;
|
|
5470
5885
|
const candidates = [];
|
|
@@ -5485,7 +5900,7 @@ function scanArtifactCandidates(cwd, opts = {}) {
|
|
|
5485
5900
|
if (entry.name.startsWith(".") && entry.name !== ".amaster-runtime.json") {
|
|
5486
5901
|
if (entry.name === ".git") continue;
|
|
5487
5902
|
}
|
|
5488
|
-
const fullPath =
|
|
5903
|
+
const fullPath = join12(current, entry.name);
|
|
5489
5904
|
const relativePath = normalizeRelativePath(root, fullPath);
|
|
5490
5905
|
if (!isSafeRelativePath(relativePath)) continue;
|
|
5491
5906
|
if (basename5(relativePath) === ".amaster-runtime.json") continue;
|
|
@@ -5504,7 +5919,7 @@ function scanArtifactCandidates(cwd, opts = {}) {
|
|
|
5504
5919
|
} catch {
|
|
5505
5920
|
continue;
|
|
5506
5921
|
}
|
|
5507
|
-
if (!statusPathWithin(
|
|
5922
|
+
if (!statusPathWithin(resolve10(fullPath), root) || stat.size > MAX_HASH_BYTES) continue;
|
|
5508
5923
|
candidates.push({
|
|
5509
5924
|
relativePath,
|
|
5510
5925
|
name: basename5(fullPath),
|
|
@@ -5564,10 +5979,10 @@ function sanitizeRuntimeService(entry) {
|
|
|
5564
5979
|
};
|
|
5565
5980
|
}
|
|
5566
5981
|
function readRuntimeServicesSnapshot(cwd) {
|
|
5567
|
-
const snapshotPath =
|
|
5568
|
-
if (!
|
|
5982
|
+
const snapshotPath = join12(resolve10(cwd), WORKSPACE_RUNTIME_SERVICES_FILENAME);
|
|
5983
|
+
if (!existsSync11(snapshotPath)) return [];
|
|
5569
5984
|
try {
|
|
5570
|
-
const parsed = JSON.parse(
|
|
5985
|
+
const parsed = JSON.parse(readFileSync9(snapshotPath, "utf8"));
|
|
5571
5986
|
const rawServices = Array.isArray(parsed) ? parsed : Array.isArray(parsed?.services) ? parsed.services : [];
|
|
5572
5987
|
return rawServices.map((entry) => sanitizeRuntimeService(entry)).filter((entry) => entry !== null).slice(0, 50);
|
|
5573
5988
|
} catch {
|
|
@@ -5638,7 +6053,7 @@ function readWorkspaceStatus(cwd, opts = {}) {
|
|
|
5638
6053
|
}
|
|
5639
6054
|
|
|
5640
6055
|
// src/amaster-runtime-daemon.mjs
|
|
5641
|
-
var CONNECTOR_VERSION = "0.1.0-beta.
|
|
6056
|
+
var CONNECTOR_VERSION = "0.1.0-beta.42";
|
|
5642
6057
|
var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
|
|
5643
6058
|
var MAX_CHECKPOINT_BYTES = 20 * 1024 * 1024;
|
|
5644
6059
|
var CHECKPOINT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -5686,11 +6101,11 @@ function updateActiveRunWorkspaceManifest(commandId, manifestPath, patch = {}) {
|
|
|
5686
6101
|
}
|
|
5687
6102
|
function resultOutboxPendingCount(config) {
|
|
5688
6103
|
const dir = resultOutboxDir(config);
|
|
5689
|
-
if (!
|
|
6104
|
+
if (!existsSync12(dir)) return 0;
|
|
5690
6105
|
try {
|
|
5691
6106
|
let pending = 0;
|
|
5692
6107
|
for (const file of readdirSync8(dir).filter((name) => name.endsWith(".json"))) {
|
|
5693
|
-
if (readValidResultOutboxEntryOrQuarantine(config, file,
|
|
6108
|
+
if (readValidResultOutboxEntryOrQuarantine(config, file, join13(dir, file))) {
|
|
5694
6109
|
pending += 1;
|
|
5695
6110
|
}
|
|
5696
6111
|
}
|
|
@@ -5706,11 +6121,11 @@ function piCompletionOutputType(event) {
|
|
|
5706
6121
|
}
|
|
5707
6122
|
function resultOutboxActiveRunCommands(config) {
|
|
5708
6123
|
const dir = resultOutboxDir(config);
|
|
5709
|
-
if (!
|
|
6124
|
+
if (!existsSync12(dir)) return [];
|
|
5710
6125
|
const outboxPending = resultOutboxPendingCount(config);
|
|
5711
6126
|
const entries = [];
|
|
5712
6127
|
for (const file of readdirSync8(dir).filter((name) => name.endsWith(".json")).sort()) {
|
|
5713
|
-
const entry = readValidResultOutboxEntryOrQuarantine(config, file,
|
|
6128
|
+
const entry = readValidResultOutboxEntryOrQuarantine(config, file, join13(dir, file));
|
|
5714
6129
|
if (!entry) continue;
|
|
5715
6130
|
const activeRun = asRecord(entry.activeRun);
|
|
5716
6131
|
const commandId = readString(activeRun.commandId) ?? readString(entry.commandId);
|
|
@@ -5740,12 +6155,12 @@ function resultOutboxActiveRunCommands(config) {
|
|
|
5740
6155
|
}
|
|
5741
6156
|
function resultOutboxFailedRunCommands(config) {
|
|
5742
6157
|
const dir = resultOutboxInvalidDir(config);
|
|
5743
|
-
if (!
|
|
6158
|
+
if (!existsSync12(dir)) return [];
|
|
5744
6159
|
const entries = [];
|
|
5745
6160
|
for (const file of readdirSync8(dir).filter((name) => name.endsWith(".json")).sort().slice(-100)) {
|
|
5746
6161
|
let entry;
|
|
5747
6162
|
try {
|
|
5748
|
-
entry = asRecord(JSON.parse(
|
|
6163
|
+
entry = asRecord(JSON.parse(readFileSync10(join13(dir, file), "utf8")));
|
|
5749
6164
|
} catch {
|
|
5750
6165
|
continue;
|
|
5751
6166
|
}
|
|
@@ -5805,11 +6220,11 @@ function piExtraArgsDiagnostics(value) {
|
|
|
5805
6220
|
}
|
|
5806
6221
|
function safeExpandPath(value) {
|
|
5807
6222
|
const text = readString(value);
|
|
5808
|
-
return text ?
|
|
6223
|
+
return text ? resolve11(expandHomePath(text)) : null;
|
|
5809
6224
|
}
|
|
5810
6225
|
function safeJsonObjectFromFile(filePath) {
|
|
5811
6226
|
try {
|
|
5812
|
-
const parsed = JSON.parse(
|
|
6227
|
+
const parsed = JSON.parse(readFileSync10(filePath, "utf8"));
|
|
5813
6228
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
5814
6229
|
} catch {
|
|
5815
6230
|
return null;
|
|
@@ -5852,10 +6267,10 @@ function safeSkillRootSummary(kind, source, pathValue) {
|
|
|
5852
6267
|
try {
|
|
5853
6268
|
for (const name of readdirSync8(pathValue)) {
|
|
5854
6269
|
if (name.startsWith(".")) continue;
|
|
5855
|
-
const skillDir =
|
|
6270
|
+
const skillDir = join13(pathValue, name);
|
|
5856
6271
|
try {
|
|
5857
6272
|
if (!statSync7(skillDir).isDirectory()) continue;
|
|
5858
|
-
if (!
|
|
6273
|
+
if (!existsSync12(join13(skillDir, "SKILL.md"))) continue;
|
|
5859
6274
|
skillCount += 1;
|
|
5860
6275
|
if (skillCount >= MAX_PI_CAPABILITY_SOURCE_ENTRIES) {
|
|
5861
6276
|
truncated = true;
|
|
@@ -5906,7 +6321,7 @@ function objectKeyCount(value) {
|
|
|
5906
6321
|
return value && typeof value === "object" && !Array.isArray(value) ? Object.keys(value).length : 0;
|
|
5907
6322
|
}
|
|
5908
6323
|
function defaultPiCodingAgentDir() {
|
|
5909
|
-
return
|
|
6324
|
+
return join13(homedir3(), ".pi", "agent");
|
|
5910
6325
|
}
|
|
5911
6326
|
function piCapabilitySourcesDiagnostics() {
|
|
5912
6327
|
const configuredPiCodingAgentDir = safeExpandPath(process.env.PI_CODING_AGENT_DIR);
|
|
@@ -5915,11 +6330,11 @@ function piCapabilitySourcesDiagnostics() {
|
|
|
5915
6330
|
const configuredPiAgentHome = safeExpandPath(process.env.PI_AGENT_HOME);
|
|
5916
6331
|
const piAgentHome = configuredPiAgentHome ?? piCodingAgentDir;
|
|
5917
6332
|
const piAgentHomeSource = configuredPiAgentHome ? "PI_AGENT_HOME" : piCodingAgentDirSource;
|
|
5918
|
-
const userSkillsPath = piAgentHome ?
|
|
5919
|
-
const marketplaceSkillsPath = safeExpandPath(process.env.PI_AGENT_MARKETPLACE_SKILLS_DIR) ?? (piAgentHome ?
|
|
6333
|
+
const userSkillsPath = piAgentHome ? join13(piAgentHome, "skills") : null;
|
|
6334
|
+
const marketplaceSkillsPath = safeExpandPath(process.env.PI_AGENT_MARKETPLACE_SKILLS_DIR) ?? (piAgentHome ? join13(piAgentHome, "marketplace", "skills") : null);
|
|
5920
6335
|
const builtinSkillsPath = safeExpandPath(process.env.PI_AGENT_BUILTIN_SKILLS_DIR) ?? safeExpandPath(process.env.AMASTER_BUILTIN_SKILLS);
|
|
5921
|
-
const mcpConfigPath = safeExpandPath(process.env.PI_AGENT_MCP_SERVERS_FILE) ?? (piAgentHome ?
|
|
5922
|
-
const settingsConfigPath = piCodingAgentDir ?
|
|
6336
|
+
const mcpConfigPath = safeExpandPath(process.env.PI_AGENT_MCP_SERVERS_FILE) ?? (piAgentHome ? join13(piAgentHome, "mcp.json") : null);
|
|
6337
|
+
const settingsConfigPath = piCodingAgentDir ? join13(piCodingAgentDir, "settings.json") : null;
|
|
5923
6338
|
const skillRoots = [
|
|
5924
6339
|
safeSkillRootSummary("user", `${piAgentHomeSource}/skills`, userSkillsPath),
|
|
5925
6340
|
safeSkillRootSummary(
|
|
@@ -6150,13 +6565,13 @@ function piAgentLocalPlatformRunnerEnabled(config) {
|
|
|
6150
6565
|
}
|
|
6151
6566
|
function piAgentSystemDataDir(config) {
|
|
6152
6567
|
const configured = readString(config.AMASTER_PI_AGENT_SYSTEM_DATA_DIR ?? process.env.AMASTER_PI_AGENT_SYSTEM_DATA_DIR);
|
|
6153
|
-
return configured ?
|
|
6568
|
+
return configured ? resolve11(expandHomePath(configured)) : null;
|
|
6154
6569
|
}
|
|
6155
6570
|
function readPiAgentLocalPlatformCredential(credentialsDir) {
|
|
6156
|
-
const pointer = readJsonFile3(
|
|
6571
|
+
const pointer = readJsonFile3(join13(credentialsDir, "latest.json"));
|
|
6157
6572
|
const credentialRef = readString(pointer.credentialRef);
|
|
6158
6573
|
if (!credentialRef || !/^[a-f0-9]{64}$/i.test(credentialRef)) return null;
|
|
6159
|
-
const credential = readJsonFile3(
|
|
6574
|
+
const credential = readJsonFile3(join13(credentialsDir, `${credentialRef}.json`));
|
|
6160
6575
|
const organizationId = readString(credential.organizationId);
|
|
6161
6576
|
const apiKey = readString(credential.apiKey);
|
|
6162
6577
|
if (credential.version !== 1 || !organizationId || !apiKey) return null;
|
|
@@ -6172,7 +6587,7 @@ function piAgentLocalPlatformCredentials(config) {
|
|
|
6172
6587
|
if (!piAgentLocalPlatformRunnerEnabled(config)) return [];
|
|
6173
6588
|
const systemDataDir = piAgentSystemDataDir(config);
|
|
6174
6589
|
if (!systemDataDir) return [];
|
|
6175
|
-
const companiesDir =
|
|
6590
|
+
const companiesDir = join13(systemDataDir, "companies");
|
|
6176
6591
|
let entries = [];
|
|
6177
6592
|
try {
|
|
6178
6593
|
entries = readdirSync8(companiesDir, { withFileTypes: true });
|
|
@@ -6182,7 +6597,7 @@ function piAgentLocalPlatformCredentials(config) {
|
|
|
6182
6597
|
const credentialsByOrganizationId = /* @__PURE__ */ new Map();
|
|
6183
6598
|
for (const entry of entries) {
|
|
6184
6599
|
if (!entry.isDirectory()) continue;
|
|
6185
|
-
const credential = readPiAgentLocalPlatformCredential(
|
|
6600
|
+
const credential = readPiAgentLocalPlatformCredential(join13(companiesDir, entry.name, "model-credentials"));
|
|
6186
6601
|
if (credential) credentialsByOrganizationId.set(credential.organizationId, credential);
|
|
6187
6602
|
}
|
|
6188
6603
|
return [...credentialsByOrganizationId.values()];
|
|
@@ -6356,7 +6771,7 @@ AMASTER_WORKSPACE_ALLOWLIST=${quoteShell(config.workspaceBindings.join(","))}
|
|
|
6356
6771
|
AMASTER_EXECUTORS=${quoteShell(executorEnv)}
|
|
6357
6772
|
AMASTER_CAPABILITIES=${quoteShell(config.capabilities.join(","))}
|
|
6358
6773
|
AMASTER_NETWORK_DOMAINS=${quoteShell(config.networkDomains.join(","))}
|
|
6359
|
-
AMASTER_DAEMON_STATE_FILE=${quoteShell(
|
|
6774
|
+
AMASTER_DAEMON_STATE_FILE=${quoteShell(join13(homedir3(), ".amaster-employee", "runtime-connector-state.json"))}
|
|
6360
6775
|
EOF
|
|
6361
6776
|
|
|
6362
6777
|
set -a
|
|
@@ -6544,10 +6959,10 @@ function buildActiveRunCommandStatus(config, entry) {
|
|
|
6544
6959
|
const base = {
|
|
6545
6960
|
...entry,
|
|
6546
6961
|
phase: readString(entry.phase) ?? "executing",
|
|
6547
|
-
managedWorkdirPresent: entry.workspacePath ?
|
|
6962
|
+
managedWorkdirPresent: entry.workspacePath ? existsSync12(entry.workspacePath) : false,
|
|
6548
6963
|
outboxPending: resultOutboxPendingCount(config)
|
|
6549
6964
|
};
|
|
6550
|
-
if (!entry.workspacePath || !
|
|
6965
|
+
if (!entry.workspacePath || !existsSync12(entry.workspacePath)) return base;
|
|
6551
6966
|
const manifestPath = entry.manifestPath ?? workspaceManifestPath(entry.workspacePath);
|
|
6552
6967
|
const status = readWorkspaceStatus(entry.workspacePath, { hashCache: workspaceStatusHashCache });
|
|
6553
6968
|
const artifactCandidates = status.artifacts.slice(0, 20);
|
|
@@ -6728,7 +7143,7 @@ function trustedPiRuntimeSources(config) {
|
|
|
6728
7143
|
}
|
|
6729
7144
|
function readJsonFile3(filePath) {
|
|
6730
7145
|
try {
|
|
6731
|
-
const parsed = JSON.parse(
|
|
7146
|
+
const parsed = JSON.parse(readFileSync10(filePath, "utf8"));
|
|
6732
7147
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
6733
7148
|
} catch {
|
|
6734
7149
|
return {};
|
|
@@ -6797,11 +7212,11 @@ function safeAgentInstructionMaterializationTarget(workspace, filePath) {
|
|
|
6797
7212
|
const raw = readString(filePath);
|
|
6798
7213
|
if (!raw || raw.includes("\0")) return null;
|
|
6799
7214
|
const normalized = raw.replace(/\\/g, "/");
|
|
6800
|
-
if (
|
|
7215
|
+
if (isAbsolute8(normalized)) return null;
|
|
6801
7216
|
const segments = normalized.split("/").filter(Boolean);
|
|
6802
7217
|
if (segments.length === 0 || segments.some((segment) => segment === "." || segment === "..")) return null;
|
|
6803
7218
|
const relativePath = segments.join("/");
|
|
6804
|
-
const targetPath =
|
|
7219
|
+
const targetPath = resolve11(workspace.cwd, relativePath);
|
|
6805
7220
|
if (!pathWithin2(targetPath, workspace.cwd)) return null;
|
|
6806
7221
|
return { relativePath, targetPath };
|
|
6807
7222
|
}
|
|
@@ -6815,8 +7230,8 @@ async function materializeAgentInstructionsBundle(config, command, workspace) {
|
|
|
6815
7230
|
if (!content) continue;
|
|
6816
7231
|
const target = safeAgentInstructionMaterializationTarget(workspace, filePath);
|
|
6817
7232
|
if (!target) continue;
|
|
6818
|
-
|
|
6819
|
-
|
|
7233
|
+
mkdirSync8(dirname9(target.targetPath), { recursive: true });
|
|
7234
|
+
writeFileSync8(target.targetPath, content, "utf8");
|
|
6820
7235
|
materialized.push({
|
|
6821
7236
|
path: target.relativePath,
|
|
6822
7237
|
byteSize: Buffer.byteLength(content, "utf8")
|
|
@@ -6866,6 +7281,7 @@ function buildCommandPrompt(command, workspace, materializedAttachments = [], op
|
|
|
6866
7281
|
commandId: command.commandId,
|
|
6867
7282
|
runId: commandRunId(command),
|
|
6868
7283
|
issueId: commandIssueId(command),
|
|
7284
|
+
currentDate: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
6869
7285
|
issueLine,
|
|
6870
7286
|
cwd,
|
|
6871
7287
|
managed: workspaceContext.managed,
|
|
@@ -6880,25 +7296,18 @@ function buildCommandPrompt(command, workspace, materializedAttachments = [], op
|
|
|
6880
7296
|
nativeSession: asRecord(payload.nativeSession)
|
|
6881
7297
|
});
|
|
6882
7298
|
}
|
|
6883
|
-
function safeCompanyPiHomeSegment(companyId) {
|
|
6884
|
-
const raw = readString(companyId)?.trim();
|
|
6885
|
-
if (!raw) return null;
|
|
6886
|
-
if (/^[A-Za-z0-9][A-Za-z0-9._-]{0,119}$/.test(raw)) return raw;
|
|
6887
|
-
const normalized = raw.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^[._-]+|[._-]+$/g, "").slice(0, 80);
|
|
6888
|
-
const hash = createHash8("sha256").update(raw).digest("hex").slice(0, 12);
|
|
6889
|
-
return normalized ? `${normalized}-${hash}` : `company-${hash}`;
|
|
6890
|
-
}
|
|
6891
7299
|
function companyPiHomeRoot(baseEnv) {
|
|
6892
7300
|
const explicitRoot = readString(baseEnv.AMASTER_COMPANY_PI_HOME_ROOT);
|
|
6893
|
-
if (explicitRoot) return
|
|
7301
|
+
if (explicitRoot) return resolve11(expandHomePath(explicitRoot));
|
|
6894
7302
|
const configuredPiHome = readString(baseEnv.PI_AGENT_HOME) ?? readString(baseEnv.PI_CODING_AGENT_DIR);
|
|
6895
|
-
if (configuredPiHome) return
|
|
6896
|
-
return
|
|
7303
|
+
if (configuredPiHome) return join13(dirname9(resolve11(expandHomePath(configuredPiHome))), "companies");
|
|
7304
|
+
return join13(homedir3(), ".amaster-employee", "companies");
|
|
6897
7305
|
}
|
|
6898
7306
|
function companyPiAgentHome(baseEnv, companyId) {
|
|
6899
|
-
const
|
|
6900
|
-
if (!
|
|
6901
|
-
|
|
7307
|
+
const rawCompanyId = readString(companyId);
|
|
7308
|
+
if (!rawCompanyId) return null;
|
|
7309
|
+
const segment = safeCompanyPiHomeSegment(rawCompanyId);
|
|
7310
|
+
return join13(companyPiHomeRoot(baseEnv), segment, ".pi");
|
|
6902
7311
|
}
|
|
6903
7312
|
function commandUsesPiExecutor(command) {
|
|
6904
7313
|
return readString(asRecord(command.payload).executorKind) === "pi";
|
|
@@ -6967,7 +7376,7 @@ function resolveNativeSessionRequest(command, workspace) {
|
|
|
6967
7376
|
try {
|
|
6968
7377
|
cwdMatched = realpathSync3(requestedCwd) === realpathSync3(sourceWorkspacePath);
|
|
6969
7378
|
} catch {
|
|
6970
|
-
cwdMatched =
|
|
7379
|
+
cwdMatched = resolve11(requestedCwd) === resolve11(sourceWorkspacePath);
|
|
6971
7380
|
}
|
|
6972
7381
|
}
|
|
6973
7382
|
const used = Boolean(enabled && requested && sessionId && requestedCwd && cwdMatched);
|
|
@@ -7166,6 +7575,7 @@ function createLiveOutputLogger(config, command, executorKind, protectedValues =
|
|
|
7166
7575
|
let nonProgressEventCount = 0;
|
|
7167
7576
|
let unparsedLineCount = 0;
|
|
7168
7577
|
let lastPiAgentMessage = null;
|
|
7578
|
+
let piTerminalOutput = null;
|
|
7169
7579
|
let executorSessionId = null;
|
|
7170
7580
|
const liveMcpToolResults = [];
|
|
7171
7581
|
let queue = Promise.resolve();
|
|
@@ -7249,9 +7659,20 @@ function createLiveOutputLogger(config, command, executorKind, protectedValues =
|
|
|
7249
7659
|
const text = redactProtectedText(line, protectedValues).trim();
|
|
7250
7660
|
if (!text) return;
|
|
7251
7661
|
const event = stream === "stdout" ? parseJsonLine(text) : null;
|
|
7252
|
-
|
|
7662
|
+
const eventType = readString(asRecord(event).type);
|
|
7663
|
+
if (executorKind === "pi" && eventType === "session") {
|
|
7253
7664
|
executorSessionId = readString(asRecord(event).sessionId ?? asRecord(event).id) ?? executorSessionId;
|
|
7254
7665
|
}
|
|
7666
|
+
if (executorKind === "pi" && (["message_end", "turn_end", "agent_end"].includes(eventType ?? "") || eventType === "message_update" && readString(asRecord(asRecord(event).assistantMessageEvent).type) === "text_end")) {
|
|
7667
|
+
const parsedTerminalOutput = parsePiJsonl(text);
|
|
7668
|
+
if (parsedTerminalOutput.hasAssistantOutput && readString(parsedTerminalOutput.summary)) {
|
|
7669
|
+
piTerminalOutput = {
|
|
7670
|
+
summary: parsedTerminalOutput.summary,
|
|
7671
|
+
usage: parsedTerminalOutput.usage,
|
|
7672
|
+
hasAssistantOutput: true
|
|
7673
|
+
};
|
|
7674
|
+
}
|
|
7675
|
+
}
|
|
7255
7676
|
if (["codex", "pi"].includes(executorKind) && event) {
|
|
7256
7677
|
const results = executorKind === "codex" ? codexMcpToolResults(event) : piMcpToolResults(event);
|
|
7257
7678
|
liveMcpToolResults.push(...results);
|
|
@@ -7290,6 +7711,12 @@ function createLiveOutputLogger(config, command, executorKind, protectedValues =
|
|
|
7290
7711
|
mcpToolResults() {
|
|
7291
7712
|
return [...liveMcpToolResults];
|
|
7292
7713
|
},
|
|
7714
|
+
terminalOutput() {
|
|
7715
|
+
return piTerminalOutput ? {
|
|
7716
|
+
...piTerminalOutput,
|
|
7717
|
+
usage: { ...piTerminalOutput.usage }
|
|
7718
|
+
} : null;
|
|
7719
|
+
},
|
|
7293
7720
|
write(stream, chunk) {
|
|
7294
7721
|
const key = stream === "stderr" ? "stderr" : "stdout";
|
|
7295
7722
|
sourceCounts[key] += 1;
|
|
@@ -7394,10 +7821,10 @@ function realOrResolvedPath(value) {
|
|
|
7394
7821
|
try {
|
|
7395
7822
|
return realpathSync3(value);
|
|
7396
7823
|
} catch {
|
|
7397
|
-
return
|
|
7824
|
+
return resolve11(value);
|
|
7398
7825
|
}
|
|
7399
7826
|
}
|
|
7400
|
-
var LSOF_COMMAND = process.platform === "darwin" &&
|
|
7827
|
+
var LSOF_COMMAND = process.platform === "darwin" && existsSync12("/usr/sbin/lsof") ? "/usr/sbin/lsof" : "lsof";
|
|
7401
7828
|
function processCwdForPid(pid) {
|
|
7402
7829
|
if (process.platform === "linux") {
|
|
7403
7830
|
try {
|
|
@@ -7519,7 +7946,7 @@ function killWorkspaceResidentProcesses(cwd, processGroupId, options = {}) {
|
|
|
7519
7946
|
}
|
|
7520
7947
|
function walkManagedWorkdirs(root) {
|
|
7521
7948
|
const workdirs = [];
|
|
7522
|
-
if (!root || !
|
|
7949
|
+
if (!root || !existsSync12(root)) return workdirs;
|
|
7523
7950
|
const stack = [root];
|
|
7524
7951
|
while (stack.length > 0) {
|
|
7525
7952
|
const current = stack.pop();
|
|
@@ -7532,8 +7959,8 @@ function walkManagedWorkdirs(root) {
|
|
|
7532
7959
|
}
|
|
7533
7960
|
for (const entry of entries) {
|
|
7534
7961
|
if (!entry.isDirectory()) continue;
|
|
7535
|
-
const fullPath =
|
|
7536
|
-
if (entry.name === "workdir" &&
|
|
7962
|
+
const fullPath = join13(current, entry.name);
|
|
7963
|
+
if (entry.name === "workdir" && existsSync12(workspaceManifestPath(fullPath))) {
|
|
7537
7964
|
workdirs.push(fullPath);
|
|
7538
7965
|
continue;
|
|
7539
7966
|
}
|
|
@@ -7571,8 +7998,8 @@ function manifestMatchesActiveRuntimeRef(manifest, refs, workdir = null) {
|
|
|
7571
7998
|
}
|
|
7572
7999
|
function buildOrphanReaperSample(root, workdir, manifest, residents) {
|
|
7573
8000
|
const relativeWorkdir = (() => {
|
|
7574
|
-
const value =
|
|
7575
|
-
return value && !value.startsWith("..") && !
|
|
8001
|
+
const value = relative8(root, workdir);
|
|
8002
|
+
return value && !value.startsWith("..") && !isAbsolute8(value) ? value : basename6(workdir);
|
|
7576
8003
|
})();
|
|
7577
8004
|
return {
|
|
7578
8005
|
workdir: relativeWorkdir,
|
|
@@ -7675,12 +8102,13 @@ function runExecutor(command, args, options) {
|
|
|
7675
8102
|
const maxOutputBytes = parsePositiveInteger(options.maxOutputBytes, 50 * 1024 * 1024);
|
|
7676
8103
|
const maxRssMb = parsePositiveInteger(options.maxRssMb, 0);
|
|
7677
8104
|
const maxRssBytes = maxRssMb * 1024 * 1024;
|
|
7678
|
-
const
|
|
8105
|
+
const spawnInvocation = managedChildSpawnInvocation(command, args, options.spawnIdentity);
|
|
8106
|
+
const child = spawn(spawnInvocation.command, spawnInvocation.args, {
|
|
7679
8107
|
cwd: options.cwd,
|
|
7680
8108
|
env: options.env,
|
|
7681
8109
|
detached: process.platform !== "win32",
|
|
7682
8110
|
stdio: options.managedInput ? ["pipe", "pipe", "pipe", "pipe"] : ["pipe", "pipe", "pipe"],
|
|
7683
|
-
...
|
|
8111
|
+
...spawnInvocation.spawnIdentity
|
|
7684
8112
|
});
|
|
7685
8113
|
const processGroupId = processGroupIdForChild(child);
|
|
7686
8114
|
const finish = (result2) => {
|
|
@@ -7962,6 +8390,7 @@ async function ingestRuntimeArtifacts(config, command, cwd, mcpToolResults) {
|
|
|
7962
8390
|
if (!runId) throw new Error("Runtime Artifact ingest requires a correlated runId");
|
|
7963
8391
|
const uploads = prepareRuntimeArtifactUploads(cwd, mcpToolResults);
|
|
7964
8392
|
const receipts = [];
|
|
8393
|
+
const failures = [];
|
|
7965
8394
|
for (const upload of uploads) {
|
|
7966
8395
|
const path = `/api/amaster/runtime-connectors/${connectorId}/artifact-intents/${encodeURIComponent(upload.intentId)}/ingest`;
|
|
7967
8396
|
const sourcePathHeaders = /^[\x20-\x7e]+$/.test(upload.sourceRelativePath) ? { "x-amaster-artifact-source-path": upload.sourceRelativePath } : {
|
|
@@ -7975,8 +8404,13 @@ async function ingestRuntimeArtifacts(config, command, cwd, mcpToolResults) {
|
|
|
7975
8404
|
"x-amaster-artifact-manifest-id": upload.manifestId,
|
|
7976
8405
|
...sourcePathHeaders
|
|
7977
8406
|
}));
|
|
7978
|
-
|
|
7979
|
-
|
|
8407
|
+
const receiptStatus = readString(receipt.status);
|
|
8408
|
+
if (readString(receipt.intentId) !== upload.intentId || receiptStatus !== "finalized") {
|
|
8409
|
+
const error = new Error(`Runtime Artifact ${upload.intentId} was not finalized: ${JSON.stringify(receipt)}`);
|
|
8410
|
+
if (receiptStatus === "rejected") {
|
|
8411
|
+
error.code = "runtime_artifact_rejected";
|
|
8412
|
+
}
|
|
8413
|
+
throw error;
|
|
7980
8414
|
}
|
|
7981
8415
|
receipts.push(receipt);
|
|
7982
8416
|
await ingestLog(config, command, "system", "info", `Finalized Runtime Artifact ${upload.sourceRelativePath}`, {
|
|
@@ -7992,7 +8426,12 @@ async function ingestRuntimeArtifacts(config, command, cwd, mcpToolResults) {
|
|
|
7992
8426
|
});
|
|
7993
8427
|
} catch (err) {
|
|
7994
8428
|
const message = `Runtime Artifact ${upload.intentId} ingest failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
8429
|
+
const failure = new Error(message, err instanceof Error ? { cause: err } : void 0);
|
|
8430
|
+
if (err instanceof Error && err.code === "runtime_artifact_rejected") {
|
|
8431
|
+
failure.code = "runtime_artifact_rejected";
|
|
8432
|
+
}
|
|
7995
8433
|
await ingestLog(config, command, "system", "error", message, {
|
|
8434
|
+
event: "runtime_artifact_ingest_failed",
|
|
7996
8435
|
presentationKind: "runtime_artifact_ingest",
|
|
7997
8436
|
intentId: upload.intentId,
|
|
7998
8437
|
manifestId: upload.manifestId,
|
|
@@ -8001,9 +8440,12 @@ async function ingestRuntimeArtifacts(config, command, cwd, mcpToolResults) {
|
|
|
8001
8440
|
byteSize: upload.byteSize,
|
|
8002
8441
|
status: "failed"
|
|
8003
8442
|
});
|
|
8004
|
-
|
|
8443
|
+
failures.push(failure);
|
|
8005
8444
|
}
|
|
8006
8445
|
}
|
|
8446
|
+
if (failures.length > 0) {
|
|
8447
|
+
throw new RuntimeArtifactIngestAggregateError(failures, receipts);
|
|
8448
|
+
}
|
|
8007
8449
|
return receipts;
|
|
8008
8450
|
}
|
|
8009
8451
|
function resultOutboxActiveRunSnapshot(command) {
|
|
@@ -8056,15 +8498,15 @@ async function completeCommand(config, command, status, result2, error) {
|
|
|
8056
8498
|
}
|
|
8057
8499
|
function resultOutboxDir(config) {
|
|
8058
8500
|
const explicit = readString(process.env.AMASTER_RESULT_OUTBOX_DIR);
|
|
8059
|
-
if (explicit) return
|
|
8060
|
-
return
|
|
8501
|
+
if (explicit) return resolve11(expandHomePath(explicit));
|
|
8502
|
+
return join13(dirname9(stateFilePath(process.env)), "result-outbox");
|
|
8061
8503
|
}
|
|
8062
8504
|
function resultOutboxInvalidDir(config) {
|
|
8063
|
-
return
|
|
8505
|
+
return join13(resultOutboxDir(config), "invalid");
|
|
8064
8506
|
}
|
|
8065
8507
|
function writeResultOutboxEntry(config, entry) {
|
|
8066
8508
|
const dir = resultOutboxDir(config);
|
|
8067
|
-
|
|
8509
|
+
mkdirSync8(dir, { recursive: true });
|
|
8068
8510
|
const body = {
|
|
8069
8511
|
version: 1,
|
|
8070
8512
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -8072,16 +8514,16 @@ function writeResultOutboxEntry(config, entry) {
|
|
|
8072
8514
|
lastAttemptAt: null,
|
|
8073
8515
|
...entry
|
|
8074
8516
|
};
|
|
8075
|
-
|
|
8517
|
+
writeFileSync8(join13(dir, resultOutboxFileName(entry.commandId)), `${JSON.stringify(body, null, 2)}
|
|
8076
8518
|
`, { mode: 384 });
|
|
8077
8519
|
}
|
|
8078
8520
|
function moveResultOutboxEntryToInvalid(config, file, fullPath, reason, detail, original) {
|
|
8079
8521
|
const invalidDir = resultOutboxInvalidDir(config);
|
|
8080
|
-
|
|
8081
|
-
const invalidPath =
|
|
8522
|
+
mkdirSync8(invalidDir, { recursive: true });
|
|
8523
|
+
const invalidPath = join13(invalidDir, file);
|
|
8082
8524
|
if (original === void 0) {
|
|
8083
8525
|
try {
|
|
8084
|
-
|
|
8526
|
+
renameSync5(fullPath, invalidPath);
|
|
8085
8527
|
} catch {
|
|
8086
8528
|
copyFileSync3(fullPath, invalidPath);
|
|
8087
8529
|
unlinkSync(fullPath);
|
|
@@ -8094,14 +8536,14 @@ function moveResultOutboxEntryToInvalid(config, file, fullPath, reason, detail,
|
|
|
8094
8536
|
...detail ? { detail: truncateText(detail, 1e3) } : {},
|
|
8095
8537
|
original
|
|
8096
8538
|
};
|
|
8097
|
-
|
|
8539
|
+
writeFileSync8(invalidPath, `${JSON.stringify(evidence, null, 2)}
|
|
8098
8540
|
`, { mode: 384 });
|
|
8099
8541
|
unlinkSync(fullPath);
|
|
8100
8542
|
}
|
|
8101
8543
|
function readValidResultOutboxEntryOrQuarantine(config, file, fullPath) {
|
|
8102
8544
|
let entry;
|
|
8103
8545
|
try {
|
|
8104
|
-
entry = JSON.parse(
|
|
8546
|
+
entry = JSON.parse(readFileSync10(fullPath, "utf8"));
|
|
8105
8547
|
} catch (err) {
|
|
8106
8548
|
const message = err instanceof Error ? err.message : String(err);
|
|
8107
8549
|
moveResultOutboxEntryToInvalid(config, file, fullPath, "malformed_result_outbox_json", message);
|
|
@@ -8131,13 +8573,13 @@ function updateResultOutboxAttempt(fullPath, entry, err) {
|
|
|
8131
8573
|
...typeof err?.httpStatus === "number" ? { httpStatus: err.httpStatus } : {},
|
|
8132
8574
|
lastError: truncateText(err instanceof Error ? err.message : String(err), 1e3)
|
|
8133
8575
|
};
|
|
8134
|
-
|
|
8576
|
+
writeFileSync8(fullPath, `${JSON.stringify(next, null, 2)}
|
|
8135
8577
|
`, { mode: 384 });
|
|
8136
8578
|
return next;
|
|
8137
8579
|
}
|
|
8138
8580
|
function quarantineResultOutboxEntry(config, fullPath, file, entry, reason, err) {
|
|
8139
8581
|
const invalidDir = resultOutboxInvalidDir(config);
|
|
8140
|
-
|
|
8582
|
+
mkdirSync8(invalidDir, { recursive: true });
|
|
8141
8583
|
const body = {
|
|
8142
8584
|
...entry,
|
|
8143
8585
|
invalidReason: reason,
|
|
@@ -8145,8 +8587,8 @@ function quarantineResultOutboxEntry(config, fullPath, file, entry, reason, err)
|
|
|
8145
8587
|
...typeof err?.httpStatus === "number" ? { httpStatus: err.httpStatus } : {},
|
|
8146
8588
|
lastError: truncateText(err instanceof Error ? err.message : String(err), 1e3)
|
|
8147
8589
|
};
|
|
8148
|
-
const invalidPath =
|
|
8149
|
-
|
|
8590
|
+
const invalidPath = join13(invalidDir, file);
|
|
8591
|
+
writeFileSync8(invalidPath, `${JSON.stringify(body, null, 2)}
|
|
8150
8592
|
`, { mode: 384 });
|
|
8151
8593
|
try {
|
|
8152
8594
|
unlinkSync(fullPath);
|
|
@@ -8159,11 +8601,11 @@ function quarantineResultOutboxEntry(config, fullPath, file, entry, reason, err)
|
|
|
8159
8601
|
}
|
|
8160
8602
|
async function flushResultOutbox(config) {
|
|
8161
8603
|
const dir = resultOutboxDir(config);
|
|
8162
|
-
if (!
|
|
8604
|
+
if (!existsSync12(dir)) return { attempted: 0, completed: 0 };
|
|
8163
8605
|
const files = readdirSync8(dir).filter((name) => name.endsWith(".json")).sort();
|
|
8164
8606
|
let completed = 0;
|
|
8165
8607
|
for (const file of files) {
|
|
8166
|
-
const fullPath =
|
|
8608
|
+
const fullPath = join13(dir, file);
|
|
8167
8609
|
const entry = readValidResultOutboxEntryOrQuarantine(config, file, fullPath);
|
|
8168
8610
|
if (!entry) continue;
|
|
8169
8611
|
try {
|
|
@@ -8360,8 +8802,8 @@ async function materializeIssueAttachments(config, command, workspace) {
|
|
|
8360
8802
|
runtimeAuth,
|
|
8361
8803
|
issueId
|
|
8362
8804
|
);
|
|
8363
|
-
const targetDir =
|
|
8364
|
-
|
|
8805
|
+
const targetDir = join13(workspace.cwd, "input-attachments");
|
|
8806
|
+
mkdirSync8(targetDir, { recursive: true });
|
|
8365
8807
|
const usedFilenames = /* @__PURE__ */ new Set();
|
|
8366
8808
|
const materialized = [];
|
|
8367
8809
|
for (const [index, rawAttachment] of attachments.entries()) {
|
|
@@ -8375,11 +8817,11 @@ async function materializeIssueAttachments(config, command, workspace) {
|
|
|
8375
8817
|
filename = `${stem}-${index + 1}${ext}`;
|
|
8376
8818
|
}
|
|
8377
8819
|
usedFilenames.add(filename);
|
|
8378
|
-
const targetPath =
|
|
8820
|
+
const targetPath = join13(targetDir, filename);
|
|
8379
8821
|
const body = await runtimeApiBuffer(runtimeAuth, contentPath);
|
|
8380
|
-
|
|
8822
|
+
writeFileSync8(targetPath, body);
|
|
8381
8823
|
const attachmentId = readString(attachment.id);
|
|
8382
|
-
const actualSha256 =
|
|
8824
|
+
const actualSha256 = createHash9("sha256").update(body).digest("hex");
|
|
8383
8825
|
const lineageCandidates = lineageCandidatesByAttachmentId.get(attachmentId) ?? [];
|
|
8384
8826
|
const lineage = selectAttachmentLineage(lineageCandidates, actualSha256);
|
|
8385
8827
|
if (lineageCandidates.length > 0 && !lineage) {
|
|
@@ -8402,7 +8844,7 @@ async function materializeIssueAttachments(config, command, workspace) {
|
|
|
8402
8844
|
id: attachmentId,
|
|
8403
8845
|
name: readString(attachment.originalFilename) ?? filename,
|
|
8404
8846
|
path: targetPath,
|
|
8405
|
-
relativePath:
|
|
8847
|
+
relativePath: relative8(workspace.cwd, targetPath),
|
|
8406
8848
|
contentType: readString(attachment.contentType),
|
|
8407
8849
|
byteSize: body.byteLength,
|
|
8408
8850
|
contentPath,
|
|
@@ -8451,9 +8893,9 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
8451
8893
|
if (manifest.version !== 1 || !Array.isArray(manifest.entries)) {
|
|
8452
8894
|
throw new Error("artifact_input_manifest_invalid: expected version 1 entries array");
|
|
8453
8895
|
}
|
|
8454
|
-
const targetRoot =
|
|
8455
|
-
|
|
8456
|
-
|
|
8896
|
+
const targetRoot = join13(workspace.cwd, "input-artifacts");
|
|
8897
|
+
rmSync7(targetRoot, { recursive: true, force: true });
|
|
8898
|
+
mkdirSync8(targetRoot, { recursive: true });
|
|
8457
8899
|
const usedPaths = /* @__PURE__ */ new Set();
|
|
8458
8900
|
const materialized = [];
|
|
8459
8901
|
for (const [index, rawEntry] of manifest.entries.entries()) {
|
|
@@ -8471,7 +8913,7 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
8471
8913
|
throw new Error(`artifact_input_manifest_invalid: entry ${index} contentPath does not match attachmentId`);
|
|
8472
8914
|
}
|
|
8473
8915
|
const body = await runtimeApiBuffer(runtimeAuth, contentPath);
|
|
8474
|
-
const actualSha256 =
|
|
8916
|
+
const actualSha256 = createHash9("sha256").update(body).digest("hex");
|
|
8475
8917
|
if (body.byteLength !== byteSize || actualSha256 !== sha256) {
|
|
8476
8918
|
throw new Error(
|
|
8477
8919
|
`artifact_input_integrity_mismatch: workProductId=${workProductId} expectedBytes=${byteSize} actualBytes=${body.byteLength} expectedSha256=${sha256} actualSha256=${actualSha256}`
|
|
@@ -8482,18 +8924,18 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
8482
8924
|
id: attachmentId,
|
|
8483
8925
|
originalFilename: readString(entry.originalFilename)
|
|
8484
8926
|
}, index);
|
|
8485
|
-
let relativePath =
|
|
8927
|
+
let relativePath = join13("input-artifacts", sourceDir, filename).split(/[\\/]+/).join("/");
|
|
8486
8928
|
if (usedPaths.has(relativePath)) {
|
|
8487
8929
|
const ext = extname2(filename);
|
|
8488
8930
|
const stem = ext ? filename.slice(0, -ext.length) : filename;
|
|
8489
8931
|
filename = `${stem}-${index + 1}${ext}`;
|
|
8490
|
-
relativePath =
|
|
8932
|
+
relativePath = join13("input-artifacts", sourceDir, filename).split(/[\\/]+/).join("/");
|
|
8491
8933
|
}
|
|
8492
8934
|
usedPaths.add(relativePath);
|
|
8493
|
-
const targetPath =
|
|
8494
|
-
|
|
8495
|
-
|
|
8496
|
-
|
|
8935
|
+
const targetPath = join13(workspace.cwd, relativePath);
|
|
8936
|
+
mkdirSync8(dirname9(targetPath), { recursive: true });
|
|
8937
|
+
writeFileSync8(targetPath, body);
|
|
8938
|
+
chmodSync6(targetPath, 292);
|
|
8497
8939
|
materialized.push({
|
|
8498
8940
|
id: attachmentId,
|
|
8499
8941
|
workProductId,
|
|
@@ -8512,9 +8954,9 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
8512
8954
|
version: 1,
|
|
8513
8955
|
entries: materialized.map(({ path: _path, relativePath, ...entry }) => ({ ...entry, path: relativePath }))
|
|
8514
8956
|
};
|
|
8515
|
-
const manifestPath =
|
|
8516
|
-
|
|
8517
|
-
|
|
8957
|
+
const manifestPath = join13(targetRoot, "artifact-input-manifest.json");
|
|
8958
|
+
writeFileSync8(manifestPath, JSON.stringify(localManifest, null, 2) + "\n");
|
|
8959
|
+
chmodSync6(manifestPath, 292);
|
|
8518
8960
|
updateWorkspaceManifest(workspaceManifestPath(workspace), { artifactInputManifest: localManifest });
|
|
8519
8961
|
await ingestLog(config, command, "system", "info", `Materialized ${materialized.length} required artifact input(s) into the execution workspace`, {
|
|
8520
8962
|
artifactInputCount: materialized.length,
|
|
@@ -8523,46 +8965,46 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
|
|
|
8523
8965
|
return materialized;
|
|
8524
8966
|
}
|
|
8525
8967
|
function issueCheckpointDir(workspace) {
|
|
8526
|
-
return
|
|
8968
|
+
return join13(dirname9(workspace.runDir), "checkpoint");
|
|
8527
8969
|
}
|
|
8528
8970
|
async function clearIssueCheckpoint(config, command, workspace, reason) {
|
|
8529
8971
|
const checkpointDir = issueCheckpointDir(workspace);
|
|
8530
|
-
if (!
|
|
8531
|
-
|
|
8972
|
+
if (!existsSync12(checkpointDir)) return false;
|
|
8973
|
+
rmSync7(checkpointDir, { recursive: true, force: true });
|
|
8532
8974
|
await ingestLog(config, command, "system", "info", "Cleared issue continuation checkpoint", { reason });
|
|
8533
8975
|
return true;
|
|
8534
8976
|
}
|
|
8535
8977
|
function safeCheckpointRelativePath(rawPath) {
|
|
8536
8978
|
const raw = String(rawPath ?? "").trim();
|
|
8537
|
-
if (
|
|
8979
|
+
if (isAbsolute8(raw) || /^[A-Za-z]:[\\/]/.test(raw)) return null;
|
|
8538
8980
|
const normalized = raw.split(/[\\/]+/).filter(Boolean).join("/");
|
|
8539
8981
|
if (!normalized || normalized.startsWith("../") || normalized.split("/").some((segment) => segment.startsWith("."))) return null;
|
|
8540
8982
|
if (normalized.startsWith("input-attachments/") || isRuntimeMetadataArtifactPath(normalized)) return null;
|
|
8541
8983
|
return normalized;
|
|
8542
8984
|
}
|
|
8543
8985
|
function hashFileSha256(filePath) {
|
|
8544
|
-
return
|
|
8986
|
+
return createHash9("sha256").update(readFileSync10(filePath)).digest("hex");
|
|
8545
8987
|
}
|
|
8546
8988
|
async function materializeIssueCheckpoint(config, command, workspace) {
|
|
8547
8989
|
const checkpointDir = issueCheckpointDir(workspace);
|
|
8548
|
-
const manifestPath =
|
|
8549
|
-
if (!
|
|
8990
|
+
const manifestPath = join13(checkpointDir, "manifest.json");
|
|
8991
|
+
if (!existsSync12(manifestPath)) return [];
|
|
8550
8992
|
let manifest;
|
|
8551
8993
|
try {
|
|
8552
|
-
manifest = asRecord(JSON.parse(
|
|
8994
|
+
manifest = asRecord(JSON.parse(readFileSync10(manifestPath, "utf8")));
|
|
8553
8995
|
} catch (err) {
|
|
8554
|
-
|
|
8996
|
+
rmSync7(checkpointDir, { recursive: true, force: true });
|
|
8555
8997
|
throw new Error(`invalid issue checkpoint manifest: ${err instanceof Error ? err.message : String(err)}`);
|
|
8556
8998
|
}
|
|
8557
8999
|
const expiresAt = Date.parse(readString(manifest.expiresAt) ?? "");
|
|
8558
9000
|
if (!Number.isFinite(expiresAt) || expiresAt <= Date.now() || readString(manifest.issueId) !== commandIssueId(command)) {
|
|
8559
|
-
|
|
9001
|
+
rmSync7(checkpointDir, { recursive: true, force: true });
|
|
8560
9002
|
return [];
|
|
8561
9003
|
}
|
|
8562
9004
|
try {
|
|
8563
9005
|
const files = Array.isArray(manifest.files) ? manifest.files : [];
|
|
8564
9006
|
if (files.length > 20) throw new Error("issue checkpoint manifest exceeds the limit of 20 files");
|
|
8565
|
-
const filesRoot = realpathSync3(
|
|
9007
|
+
const filesRoot = realpathSync3(join13(checkpointDir, "files"));
|
|
8566
9008
|
const workspaceRoot = realpathSync3(workspace.cwd);
|
|
8567
9009
|
const validated = [];
|
|
8568
9010
|
let totalBytes = 0;
|
|
@@ -8570,12 +9012,12 @@ async function materializeIssueCheckpoint(config, command, workspace) {
|
|
|
8570
9012
|
const file = asRecord(rawFile);
|
|
8571
9013
|
const relativePath = safeCheckpointRelativePath(readString(file.path));
|
|
8572
9014
|
if (!relativePath) throw new Error("issue checkpoint manifest contains an invalid file path");
|
|
8573
|
-
const sourceCandidate =
|
|
8574
|
-
const target =
|
|
9015
|
+
const sourceCandidate = resolve11(filesRoot, relativePath);
|
|
9016
|
+
const target = resolve11(workspaceRoot, relativePath);
|
|
8575
9017
|
if (!pathWithin2(sourceCandidate, filesRoot) || !pathWithin2(target, workspaceRoot)) {
|
|
8576
9018
|
throw new Error(`issue checkpoint path escapes its workspace: ${relativePath}`);
|
|
8577
9019
|
}
|
|
8578
|
-
if (!
|
|
9020
|
+
if (!existsSync12(sourceCandidate)) throw new Error(`issue checkpoint file is missing: ${relativePath}`);
|
|
8579
9021
|
const source = realpathSync3(sourceCandidate);
|
|
8580
9022
|
if (!pathWithin2(source, filesRoot) || !statSync7(source).isFile()) {
|
|
8581
9023
|
throw new Error(`issue checkpoint source escapes its storage root: ${relativePath}`);
|
|
@@ -8595,13 +9037,13 @@ async function materializeIssueCheckpoint(config, command, workspace) {
|
|
|
8595
9037
|
const materialized = [];
|
|
8596
9038
|
for (const { relativePath, source, target } of validated) {
|
|
8597
9039
|
try {
|
|
8598
|
-
|
|
9040
|
+
lstatSync7(target);
|
|
8599
9041
|
continue;
|
|
8600
9042
|
} catch (err) {
|
|
8601
9043
|
if (err?.code !== "ENOENT") throw err;
|
|
8602
9044
|
}
|
|
8603
|
-
|
|
8604
|
-
const targetParent = realpathSync3(
|
|
9045
|
+
mkdirSync8(dirname9(target), { recursive: true });
|
|
9046
|
+
const targetParent = realpathSync3(dirname9(target));
|
|
8605
9047
|
if (!pathWithin2(targetParent, workspaceRoot)) {
|
|
8606
9048
|
throw new Error(`issue checkpoint target escapes its workspace: ${relativePath}`);
|
|
8607
9049
|
}
|
|
@@ -8629,31 +9071,31 @@ async function materializeIssueCheckpoint(config, command, workspace) {
|
|
|
8629
9071
|
}
|
|
8630
9072
|
async function saveIssueCheckpoint(config, command, workspace, candidates) {
|
|
8631
9073
|
const checkpointDir = issueCheckpointDir(workspace);
|
|
8632
|
-
const filesDir =
|
|
8633
|
-
|
|
8634
|
-
|
|
9074
|
+
const filesDir = join13(checkpointDir, "files");
|
|
9075
|
+
rmSync7(checkpointDir, { recursive: true, force: true });
|
|
9076
|
+
mkdirSync8(filesDir, { recursive: true });
|
|
8635
9077
|
const files = [];
|
|
8636
9078
|
let totalBytes = 0;
|
|
8637
9079
|
const workspaceRoot = realpathSync3(workspace.cwd);
|
|
8638
9080
|
for (const candidate of candidates.slice(0, 20)) {
|
|
8639
9081
|
const relativePath = safeCheckpointRelativePath(candidate.rawPath);
|
|
8640
9082
|
const source = readString(candidate.filePath);
|
|
8641
|
-
if (!relativePath || !source || !
|
|
9083
|
+
if (!relativePath || !source || !existsSync12(source) || !statSync7(source).isFile()) continue;
|
|
8642
9084
|
const ownedSource = realpathSync3(source);
|
|
8643
9085
|
if (!pathWithin2(ownedSource, workspaceRoot)) {
|
|
8644
9086
|
throw new Error(`issue checkpoint source escapes its execution workspace: ${relativePath}`);
|
|
8645
9087
|
}
|
|
8646
9088
|
const byteSize = statSync7(ownedSource).size;
|
|
8647
9089
|
if (byteSize <= 0 || totalBytes + byteSize > MAX_CHECKPOINT_BYTES) continue;
|
|
8648
|
-
const target =
|
|
9090
|
+
const target = resolve11(filesDir, relativePath);
|
|
8649
9091
|
if (!pathWithin2(target, filesDir)) continue;
|
|
8650
|
-
|
|
9092
|
+
mkdirSync8(dirname9(target), { recursive: true });
|
|
8651
9093
|
copyFileSync3(ownedSource, target);
|
|
8652
9094
|
totalBytes += byteSize;
|
|
8653
9095
|
files.push({ path: relativePath, byteSize, sha256: hashFileSha256(ownedSource) });
|
|
8654
9096
|
}
|
|
8655
9097
|
if (files.length === 0) {
|
|
8656
|
-
|
|
9098
|
+
rmSync7(checkpointDir, { recursive: true, force: true });
|
|
8657
9099
|
return null;
|
|
8658
9100
|
}
|
|
8659
9101
|
const manifest = {
|
|
@@ -8665,7 +9107,7 @@ async function saveIssueCheckpoint(config, command, workspace, candidates) {
|
|
|
8665
9107
|
totalBytes,
|
|
8666
9108
|
files
|
|
8667
9109
|
};
|
|
8668
|
-
|
|
9110
|
+
writeFileSync8(join13(checkpointDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
|
|
8669
9111
|
`);
|
|
8670
9112
|
await ingestLog(config, command, "system", "warn", `Saved ${files.length} required deliverable(s) for continuation recovery`, manifest);
|
|
8671
9113
|
return manifest;
|
|
@@ -8739,44 +9181,20 @@ async function executeRunCommand(config, command) {
|
|
|
8739
9181
|
let cleanupManagedMcpProfile = null;
|
|
8740
9182
|
const providerProtectedValues = [];
|
|
8741
9183
|
let piChildIsolation = null;
|
|
9184
|
+
let piChildAssignmentAcquired = false;
|
|
9185
|
+
let piCompanyMemory = null;
|
|
8742
9186
|
let trustedPiRuntime = null;
|
|
8743
9187
|
let trustedPiRuntimeSourcePaths = null;
|
|
8744
9188
|
let trustedPiRuntimeProfile = null;
|
|
8745
9189
|
let trustedPiRuntimeAudit = null;
|
|
8746
9190
|
let piResolvedProviderConfig = null;
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
runDir: workspace.runDir,
|
|
8755
|
-
cwd,
|
|
8756
|
-
runtimeAuth: commandRuntimeAuth(command),
|
|
8757
|
-
nativeSession: asRecord(asRecord(command.payload).nativeSession),
|
|
8758
|
-
baseEnv: executorEnv,
|
|
8759
|
-
commandEnv: commandExecutorEnv(command),
|
|
8760
|
-
extraArgs: splitExtraArgs(process.env.AMASTER_CODEX_EXTRA_ARGS)
|
|
8761
|
-
});
|
|
8762
|
-
cleanupManagedMcpProfile = cleanupManagedCodexMcpProfile;
|
|
8763
|
-
}
|
|
8764
|
-
if (executor.kind === "pi") {
|
|
8765
|
-
if (piAgentLocalPlatformRunnerEnabled(config)) {
|
|
8766
|
-
delete executorEnv.AMASTER_API_KEY;
|
|
8767
|
-
delete executorEnv.AMASTER_PROVIDER_BASE_URL;
|
|
8768
|
-
delete executorEnv.AMASTER_PROVIDER_DEFAULT_MODEL;
|
|
8769
|
-
delete executorEnv.AMASTER_PROVIDER_FLASH_MODEL;
|
|
8770
|
-
}
|
|
8771
|
-
piResolvedProviderConfig = resolvePiExecutorProviderConfig(config, command, executorEnv);
|
|
8772
|
-
for (const envName of ["AMASTER_API_KEY", "AMASTER_PLATFORM_OAUTH_TOKEN"]) {
|
|
8773
|
-
const protectedValue = readString(piResolvedProviderConfig.providerConfig[envName]);
|
|
8774
|
-
if (protectedValue && !providerProtectedValues.includes(protectedValue)) {
|
|
8775
|
-
providerProtectedValues.push(protectedValue);
|
|
8776
|
-
}
|
|
8777
|
-
}
|
|
8778
|
-
if (Object.keys(governedMcp).length > 0) {
|
|
8779
|
-
managedMcpProfile = prepareManagedPiMcpProfile({
|
|
9191
|
+
let forgetActiveRunCommand = () => {
|
|
9192
|
+
};
|
|
9193
|
+
let stopActiveRunHeartbeats = () => {
|
|
9194
|
+
};
|
|
9195
|
+
try {
|
|
9196
|
+
if (executor.kind === "codex" && Object.keys(governedMcp).length > 0) {
|
|
9197
|
+
managedMcpProfile = prepareManagedCodexMcpProfile({
|
|
8780
9198
|
commandId: command.commandId,
|
|
8781
9199
|
runId: commandRunId(command),
|
|
8782
9200
|
connectorVersion: CONNECTOR_VERSION,
|
|
@@ -8788,165 +9206,220 @@ async function executeRunCommand(config, command) {
|
|
|
8788
9206
|
nativeSession: asRecord(asRecord(command.payload).nativeSession),
|
|
8789
9207
|
baseEnv: executorEnv,
|
|
8790
9208
|
commandEnv: commandExecutorEnv(command),
|
|
8791
|
-
extraArgs: splitExtraArgs(process.env.
|
|
9209
|
+
extraArgs: splitExtraArgs(process.env.AMASTER_CODEX_EXTRA_ARGS)
|
|
8792
9210
|
});
|
|
8793
|
-
cleanupManagedMcpProfile =
|
|
8794
|
-
for (const protectedValue of providerProtectedValues) {
|
|
8795
|
-
if (!managedMcpProfile.protectedValues.includes(protectedValue)) {
|
|
8796
|
-
managedMcpProfile.protectedValues.push(protectedValue);
|
|
8797
|
-
}
|
|
8798
|
-
}
|
|
9211
|
+
cleanupManagedMcpProfile = cleanupManagedCodexMcpProfile;
|
|
8799
9212
|
}
|
|
8800
|
-
|
|
8801
|
-
|
|
8802
|
-
|
|
8803
|
-
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
});
|
|
8807
|
-
}
|
|
8808
|
-
const piChildAllocator = executor.kind === "pi" ? configuredPiChildIdentityAllocator(config) : null;
|
|
8809
|
-
const trustedPiRuntimeAssertion = commandTrustedPiRuntimeAssertion(command);
|
|
8810
|
-
if (Object.keys(trustedPiRuntimeAssertion).length > 0) {
|
|
8811
|
-
try {
|
|
8812
|
-
if (executor.kind !== "pi") {
|
|
8813
|
-
throw new Error("pi_trusted_runtime_assertion_binding_mismatch:executorKind");
|
|
9213
|
+
if (executor.kind === "pi") {
|
|
9214
|
+
if (piAgentLocalPlatformRunnerEnabled(config)) {
|
|
9215
|
+
delete executorEnv.AMASTER_API_KEY;
|
|
9216
|
+
delete executorEnv.AMASTER_PROVIDER_BASE_URL;
|
|
9217
|
+
delete executorEnv.AMASTER_PROVIDER_DEFAULT_MODEL;
|
|
9218
|
+
delete executorEnv.AMASTER_PROVIDER_FLASH_MODEL;
|
|
8814
9219
|
}
|
|
8815
|
-
|
|
8816
|
-
|
|
8817
|
-
|
|
8818
|
-
|
|
8819
|
-
|
|
8820
|
-
|
|
8821
|
-
leaseId: command.leaseId,
|
|
8822
|
-
executorKind: executor.kind,
|
|
8823
|
-
localDigests: readTrustedPiRuntimeLocalDigests(trustedPiRuntimeSourcePaths)
|
|
8824
|
-
});
|
|
8825
|
-
if (!managedMcpProfile) {
|
|
8826
|
-
throw new Error("pi_trusted_runtime_governed_profile_required");
|
|
9220
|
+
piResolvedProviderConfig = resolvePiExecutorProviderConfig(config, command, executorEnv);
|
|
9221
|
+
for (const envName of ["AMASTER_API_KEY", "AMASTER_PLATFORM_OAUTH_TOKEN"]) {
|
|
9222
|
+
const protectedValue = readString(piResolvedProviderConfig.providerConfig[envName]);
|
|
9223
|
+
if (protectedValue && !providerProtectedValues.includes(protectedValue)) {
|
|
9224
|
+
providerProtectedValues.push(protectedValue);
|
|
9225
|
+
}
|
|
8827
9226
|
}
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
seedRoot: trustedPiRuntimeSourcePaths.seedRoot,
|
|
8831
|
-
overlayRoot: trustedPiRuntimeSourcePaths.overlayRoot,
|
|
8832
|
-
profileRoot: managedMcpProfile.profileRoot,
|
|
8833
|
-
agentDir: managedMcpProfile.env.PI_CODING_AGENT_DIR,
|
|
8834
|
-
governedMcpConfigPath: managedMcpProfile.configPath,
|
|
8835
|
-
verifiedAssertion: trustedPiRuntime
|
|
8836
|
-
});
|
|
8837
|
-
executorEnv = {
|
|
8838
|
-
...executorEnv,
|
|
8839
|
-
AMASTER_MANAGED_RUNTIME_ASSERTION_FD: "3",
|
|
8840
|
-
AMASTER_MANAGED_RUNTIME_AUDIT_FILE: join12(
|
|
8841
|
-
managedMcpProfile.env.HOME,
|
|
8842
|
-
".amaster-managed-runtime-audit.jsonl"
|
|
8843
|
-
),
|
|
8844
|
-
AMASTER_RUNTIME_LEASE_ID: command.leaseId
|
|
8845
|
-
};
|
|
8846
|
-
} catch (error) {
|
|
8847
|
-
if (managedMcpProfile) {
|
|
8848
|
-
cleanupManagedMcpProfile(managedMcpProfile, {
|
|
9227
|
+
if (Object.keys(governedMcp).length > 0) {
|
|
9228
|
+
managedMcpProfile = prepareManagedPiMcpProfile({
|
|
8849
9229
|
commandId: command.commandId,
|
|
8850
|
-
runId: commandRunId(command)
|
|
9230
|
+
runId: commandRunId(command),
|
|
9231
|
+
connectorVersion: CONNECTOR_VERSION,
|
|
9232
|
+
executorCommand: invocation.command,
|
|
9233
|
+
executorHome: workspace.executorHome,
|
|
9234
|
+
runDir: workspace.runDir,
|
|
9235
|
+
cwd,
|
|
9236
|
+
runtimeAuth: commandRuntimeAuth(command),
|
|
9237
|
+
nativeSession: asRecord(asRecord(command.payload).nativeSession),
|
|
9238
|
+
baseEnv: executorEnv,
|
|
9239
|
+
commandEnv: commandExecutorEnv(command),
|
|
9240
|
+
extraArgs: splitExtraArgs(process.env.AMASTER_PI_EXTRA_ARGS)
|
|
8851
9241
|
});
|
|
9242
|
+
cleanupManagedMcpProfile = cleanupManagedPiMcpProfile;
|
|
9243
|
+
for (const protectedValue of providerProtectedValues) {
|
|
9244
|
+
if (!managedMcpProfile.protectedValues.includes(protectedValue)) {
|
|
9245
|
+
managedMcpProfile.protectedValues.push(protectedValue);
|
|
9246
|
+
}
|
|
9247
|
+
}
|
|
8852
9248
|
}
|
|
8853
|
-
throw error;
|
|
8854
9249
|
}
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
|
|
8862
|
-
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
|
|
8866
|
-
|
|
8867
|
-
|
|
8868
|
-
|
|
8869
|
-
config
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
);
|
|
8874
|
-
} catch (error) {
|
|
8875
|
-
if (managedMcpProfile && cleanupManagedMcpProfile) {
|
|
8876
|
-
cleanupManagedMcpProfile(managedMcpProfile, {
|
|
9250
|
+
if (managedMcpProfile) {
|
|
9251
|
+
executorEnv = managedMcpProfile.env;
|
|
9252
|
+
await ingestLog(config, command, "system", "info", `Attested isolated ${executor.kind} managed MCP profile`, {
|
|
9253
|
+
presentationKind: "managed_mcp_attestation",
|
|
9254
|
+
...managedMcpProfile.attestation
|
|
9255
|
+
});
|
|
9256
|
+
}
|
|
9257
|
+
const piChildAllocator2 = executor.kind === "pi" ? configuredPiChildIdentityAllocator(config) : null;
|
|
9258
|
+
const trustedPiRuntimeAssertion = commandTrustedPiRuntimeAssertion(command);
|
|
9259
|
+
if (Object.keys(trustedPiRuntimeAssertion).length > 0) {
|
|
9260
|
+
try {
|
|
9261
|
+
if (executor.kind !== "pi") {
|
|
9262
|
+
throw new Error("pi_trusted_runtime_assertion_binding_mismatch:executorKind");
|
|
9263
|
+
}
|
|
9264
|
+
trustedPiRuntimeSourcePaths = trustedPiRuntimeSources(config);
|
|
9265
|
+
trustedPiRuntime = verifyTrustedPiRuntimeAssertion({
|
|
9266
|
+
assertion: trustedPiRuntimeAssertion,
|
|
9267
|
+
connectorId: requireConnectorId(config),
|
|
8877
9268
|
commandId: command.commandId,
|
|
8878
|
-
runId: commandRunId(command)
|
|
9269
|
+
runId: commandRunId(command),
|
|
9270
|
+
leaseId: command.leaseId,
|
|
9271
|
+
executorKind: executor.kind,
|
|
9272
|
+
localDigests: readTrustedPiRuntimeLocalDigests(trustedPiRuntimeSourcePaths)
|
|
8879
9273
|
});
|
|
8880
|
-
managedMcpProfile
|
|
9274
|
+
if (!managedMcpProfile) {
|
|
9275
|
+
throw new Error("pi_trusted_runtime_governed_profile_required");
|
|
9276
|
+
}
|
|
9277
|
+
requireTrustedPiChildAllocator(piChildAllocator2, true);
|
|
9278
|
+
trustedPiRuntimeProfile = materializeTrustedPiRuntimeProfile({
|
|
9279
|
+
seedRoot: trustedPiRuntimeSourcePaths.seedRoot,
|
|
9280
|
+
overlayRoot: trustedPiRuntimeSourcePaths.overlayRoot,
|
|
9281
|
+
profileRoot: managedMcpProfile.profileRoot,
|
|
9282
|
+
agentDir: managedMcpProfile.env.PI_CODING_AGENT_DIR,
|
|
9283
|
+
governedMcpConfigPath: managedMcpProfile.configPath,
|
|
9284
|
+
verifiedAssertion: trustedPiRuntime
|
|
9285
|
+
});
|
|
9286
|
+
executorEnv = {
|
|
9287
|
+
...executorEnv,
|
|
9288
|
+
AMASTER_MANAGED_RUNTIME_ASSERTION_FD: "3",
|
|
9289
|
+
AMASTER_MANAGED_RUNTIME_AUDIT_FILE: join13(
|
|
9290
|
+
managedMcpProfile.env.HOME,
|
|
9291
|
+
".amaster-managed-runtime-audit.jsonl"
|
|
9292
|
+
),
|
|
9293
|
+
AMASTER_RUNTIME_LEASE_ID: command.leaseId
|
|
9294
|
+
};
|
|
9295
|
+
} catch (error2) {
|
|
9296
|
+
if (managedMcpProfile) {
|
|
9297
|
+
cleanupManagedMcpProfile(managedMcpProfile, {
|
|
9298
|
+
commandId: command.commandId,
|
|
9299
|
+
runId: commandRunId(command)
|
|
9300
|
+
});
|
|
9301
|
+
}
|
|
9302
|
+
throw error2;
|
|
8881
9303
|
}
|
|
8882
|
-
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
|
|
8887
|
-
|
|
8888
|
-
|
|
8889
|
-
|
|
9304
|
+
await ingestLog(config, command, "system", "info", "Verified trusted Pi runtime provenance", {
|
|
9305
|
+
presentationKind: "trusted_pi_runtime_attestation",
|
|
9306
|
+
attestationId: trustedPiRuntime.attestationId,
|
|
9307
|
+
unknownToolMode: trustedPiRuntime.unknownToolMode,
|
|
9308
|
+
directToolBudget: trustedPiRuntime.directToolBudget,
|
|
9309
|
+
digests: trustedPiRuntime.digests,
|
|
9310
|
+
profileAttestationId: trustedPiRuntimeProfile.attestationId,
|
|
9311
|
+
inheritedEntries: trustedPiRuntimeProfile.facts.inheritedEntries
|
|
8890
9312
|
});
|
|
8891
|
-
|
|
8892
|
-
|
|
8893
|
-
|
|
8894
|
-
|
|
8895
|
-
|
|
8896
|
-
|
|
8897
|
-
|
|
8898
|
-
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
|
|
8902
|
-
|
|
9313
|
+
}
|
|
9314
|
+
if (executor.kind === "pi" && piResolvedProviderConfig) {
|
|
9315
|
+
const agentDir = managedMcpProfile ? readString(managedMcpProfile.env.PI_CODING_AGENT_DIR) ?? readString(managedMcpProfile.env.PI_AGENT_HOME) ?? null : piAgentLocalPlatformRunnerEnabled(config) ? readString(executorEnv.PI_AGENT_HOME) ?? readString(executorEnv.PI_CODING_AGENT_DIR) ?? null : readString(executorEnv.PI_CODING_AGENT_DIR) ?? readString(executorEnv.PI_AGENT_HOME) ?? null;
|
|
9316
|
+
try {
|
|
9317
|
+
await syncPiExecutorProviderConfig(
|
|
9318
|
+
config,
|
|
9319
|
+
command,
|
|
9320
|
+
agentDir,
|
|
9321
|
+
piResolvedProviderConfig
|
|
9322
|
+
);
|
|
9323
|
+
} catch (error2) {
|
|
9324
|
+
if (managedMcpProfile && cleanupManagedMcpProfile) {
|
|
9325
|
+
cleanupManagedMcpProfile(managedMcpProfile, {
|
|
9326
|
+
commandId: command.commandId,
|
|
9327
|
+
runId: commandRunId(command)
|
|
9328
|
+
});
|
|
9329
|
+
managedMcpProfile = null;
|
|
9330
|
+
}
|
|
9331
|
+
throw error2;
|
|
9332
|
+
}
|
|
9333
|
+
}
|
|
9334
|
+
if (piChildAllocator2) {
|
|
9335
|
+
try {
|
|
9336
|
+
const companyId = readString(commandRuntimeAuth(command).companyId) ?? readString(asRecord(command.payload).companyId);
|
|
9337
|
+
if (!companyId) throw new Error("pi_company_memory_company_id_required");
|
|
9338
|
+
const companyMemoryGroup = resolveCompanyPiMemoryGroup({
|
|
9339
|
+
root: companyPiHomeRoot(process.env),
|
|
9340
|
+
companyId
|
|
9341
|
+
});
|
|
9342
|
+
const assignment = piChildAllocator2.acquire(commandRunId(command), {
|
|
9343
|
+
gid: companyMemoryGroup.gid
|
|
9344
|
+
});
|
|
9345
|
+
piChildAssignmentAcquired = true;
|
|
9346
|
+
if (managedMcpProfile) {
|
|
9347
|
+
piCompanyMemory = prepareCompanyPiMemory({
|
|
9348
|
+
root: companyMemoryGroup.root,
|
|
9349
|
+
companyId,
|
|
9350
|
+
gid: companyMemoryGroup.gid,
|
|
9351
|
+
profileRoot: managedMcpProfile.profileRoot,
|
|
9352
|
+
profileHome: managedMcpProfile.env.PI_AGENT_HOME,
|
|
9353
|
+
childUid: assignment.uid
|
|
9354
|
+
});
|
|
9355
|
+
}
|
|
9356
|
+
const profileRoot = piChildIsolationProfileRoot({
|
|
9357
|
+
managedMcpProfile,
|
|
9358
|
+
executorHome: workspace.executorHome
|
|
9359
|
+
});
|
|
9360
|
+
piChildIsolation = preparePiChildIsolation({
|
|
9361
|
+
allocator: piChildAllocator2,
|
|
9362
|
+
effectiveUid: typeof process.geteuid === "function" ? process.geteuid() : null,
|
|
8903
9363
|
commandId: command.commandId,
|
|
8904
|
-
runId: commandRunId(command)
|
|
9364
|
+
runId: commandRunId(command),
|
|
9365
|
+
...piCompanyMemory ? { gid: piCompanyMemory.gid } : {},
|
|
9366
|
+
profileRoot,
|
|
9367
|
+
workspaceRoot: cwd,
|
|
9368
|
+
allowedRoot: config.runtimeWorkspacesRoot
|
|
8905
9369
|
});
|
|
9370
|
+
} catch (error2) {
|
|
9371
|
+
if (piChildAssignmentAcquired) {
|
|
9372
|
+
piChildAllocator2.release(commandRunId(command));
|
|
9373
|
+
piChildAssignmentAcquired = false;
|
|
9374
|
+
}
|
|
9375
|
+
if (managedMcpProfile) {
|
|
9376
|
+
cleanupManagedMcpProfile(managedMcpProfile, {
|
|
9377
|
+
commandId: command.commandId,
|
|
9378
|
+
runId: commandRunId(command)
|
|
9379
|
+
});
|
|
9380
|
+
}
|
|
9381
|
+
throw error2;
|
|
8906
9382
|
}
|
|
8907
|
-
|
|
9383
|
+
await ingestLog(config, command, "system", "info", "Prepared isolated Pi child identity", {
|
|
9384
|
+
presentationKind: "pi_child_isolation_attestation",
|
|
9385
|
+
...piChildIsolation.attestation,
|
|
9386
|
+
...piCompanyMemory ? { companyMemory: piCompanyMemory.attestation } : {}
|
|
9387
|
+
});
|
|
8908
9388
|
}
|
|
8909
|
-
await ingestLog(config, command, "system", "info",
|
|
8910
|
-
presentationKind: "
|
|
8911
|
-
|
|
9389
|
+
await ingestLog(config, command, "system", "info", `Compiled ${contextManifest.mode} prompt using ${contextManifest.budget.usedChars}/${contextManifest.budget.totalChars} characters`, {
|
|
9390
|
+
presentationKind: "context_manifest",
|
|
9391
|
+
contextManifest
|
|
8912
9392
|
});
|
|
8913
|
-
|
|
8914
|
-
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
|
|
8919
|
-
|
|
8920
|
-
|
|
8921
|
-
|
|
8922
|
-
|
|
8923
|
-
|
|
8924
|
-
|
|
8925
|
-
|
|
8926
|
-
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
|
-
|
|
8930
|
-
|
|
8931
|
-
|
|
8932
|
-
|
|
8933
|
-
|
|
8934
|
-
|
|
8935
|
-
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
command,
|
|
8944
|
-
executor.kind,
|
|
8945
|
-
protectedExecutorValues,
|
|
8946
|
-
(results) => runtimeArtifactIngest.enqueue(results)
|
|
8947
|
-
);
|
|
8948
|
-
let execution;
|
|
8949
|
-
try {
|
|
9393
|
+
await ackCommand(config, command, "spawned");
|
|
9394
|
+
await ingestLog(config, command, "system", "info", `Starting ${executor.kind} executor`, {
|
|
9395
|
+
executorKind: executor.kind,
|
|
9396
|
+
cwd,
|
|
9397
|
+
args: invocation.args
|
|
9398
|
+
});
|
|
9399
|
+
forgetActiveRunCommand = rememberActiveRunCommand(command, {
|
|
9400
|
+
executorKind: executor.kind,
|
|
9401
|
+
workspacePath: cwd,
|
|
9402
|
+
sourceWorkspacePath: workspace.sourceWorkspacePath,
|
|
9403
|
+
managedWorkdir: workspace.managed,
|
|
9404
|
+
manifestPath: workspaceManifestPath(workspace),
|
|
9405
|
+
outputFloodLimitBytesPerStream: config.executorMaxOutputBytes,
|
|
9406
|
+
...managedMcpProfile ? { managedMcpAttestation: managedMcpProfile.attestation } : {}
|
|
9407
|
+
});
|
|
9408
|
+
const abortController = new AbortController();
|
|
9409
|
+
stopActiveRunHeartbeats = startActiveRunHeartbeats(config, command, abortController);
|
|
9410
|
+
const protectedExecutorValues = managedMcpProfile?.protectedValues ?? providerProtectedValues;
|
|
9411
|
+
const runtimeArtifacts = [];
|
|
9412
|
+
const runtimeArtifactIngest = createRuntimeArtifactIngestQueue({
|
|
9413
|
+
ingest: (results) => ingestRuntimeArtifacts(config, command, cwd, results)
|
|
9414
|
+
});
|
|
9415
|
+
const liveOutputLogger = createLiveOutputLogger(
|
|
9416
|
+
config,
|
|
9417
|
+
command,
|
|
9418
|
+
executor.kind,
|
|
9419
|
+
protectedExecutorValues,
|
|
9420
|
+
(results) => runtimeArtifactIngest.enqueue(results)
|
|
9421
|
+
);
|
|
9422
|
+
let execution;
|
|
8950
9423
|
try {
|
|
8951
9424
|
execution = await runExecutor(invocation.command, invocation.args, {
|
|
8952
9425
|
cwd,
|
|
@@ -9015,6 +9488,19 @@ async function executeRunCommand(config, command) {
|
|
|
9015
9488
|
errorMessage: null
|
|
9016
9489
|
} : executor.kind === "codex" ? parseCodexJsonl(execution.stdout) : executor.kind === "claude" ? parseClaudeStreamJson(execution.stdout) : executor.kind === "opencode" ? parseOpenCodeJsonl(execution.stdout) : executor.kind === "pi" ? parsePiJsonl(execution.stdout) : parseGenericOutput(execution.stdout, execution.stderr);
|
|
9017
9490
|
parsed.sessionId ??= liveOutputLogger.sessionId();
|
|
9491
|
+
const liveTerminalOutput = executor.kind === "pi" && !hasOutputFlood ? liveOutputLogger.terminalOutput() : null;
|
|
9492
|
+
if (liveTerminalOutput) {
|
|
9493
|
+
const parsedUsage = asRecord(parsed.usage);
|
|
9494
|
+
const liveUsage = asRecord(liveTerminalOutput.usage);
|
|
9495
|
+
parsed.summary = liveTerminalOutput.summary;
|
|
9496
|
+
parsed.hasAssistantOutput = true;
|
|
9497
|
+
parsed.usage = {
|
|
9498
|
+
inputTokens: readNumber(liveUsage.inputTokens, 0) || readNumber(parsedUsage.inputTokens, 0),
|
|
9499
|
+
cachedInputTokens: readNumber(liveUsage.cachedInputTokens, 0) || readNumber(parsedUsage.cachedInputTokens, 0),
|
|
9500
|
+
outputTokens: readNumber(liveUsage.outputTokens, 0) || readNumber(parsedUsage.outputTokens, 0),
|
|
9501
|
+
...readNumber(liveUsage.costUsd, 0) > 0 || readNumber(parsedUsage.costUsd, 0) > 0 ? { costUsd: readNumber(liveUsage.costUsd, 0) || readNumber(parsedUsage.costUsd, 0) } : {}
|
|
9502
|
+
};
|
|
9503
|
+
}
|
|
9018
9504
|
const outputTelemetry = liveOutputLogger.snapshot({
|
|
9019
9505
|
outputBytes: execution.outputBytes,
|
|
9020
9506
|
floodLimitBytes: config.executorMaxOutputBytes,
|
|
@@ -9069,7 +9555,7 @@ async function executeRunCommand(config, command) {
|
|
|
9069
9555
|
workspace,
|
|
9070
9556
|
workspaceStatus.artifacts.map((artifact) => ({
|
|
9071
9557
|
rawPath: artifact.relativePath,
|
|
9072
|
-
filePath:
|
|
9558
|
+
filePath: resolve11(cwd, artifact.relativePath)
|
|
9073
9559
|
}))
|
|
9074
9560
|
);
|
|
9075
9561
|
nativeSessionRollout = {
|
|
@@ -9121,6 +9607,7 @@ async function executeRunCommand(config, command) {
|
|
|
9121
9607
|
allowMissingTurnEnd: completionOutputStopped,
|
|
9122
9608
|
allowMissingAssistantOutput: execution.completionOutputType === "approval_required"
|
|
9123
9609
|
}) : null;
|
|
9610
|
+
const piProviderFailure = executor.kind === "pi" && !cancelled && !hasOutputFlood && !hasMemoryLimit && execution.timedOut !== true && !execution.spawnError ? classifyPiProviderError(parsed) : null;
|
|
9124
9611
|
const parsedErrorMessage = outputFloodError ?? memoryLimitError ?? piInvalidOutputError ?? nativeSessionRolloutError ?? nativeSessionRolloutCleanupError ?? parsed.errorMessage;
|
|
9125
9612
|
const codexTransientFailure = executor.kind === "codex" && (execution.exitCode ?? 0) !== 0 ? classifyCodexTransientUpstreamError({
|
|
9126
9613
|
stdout: execution.stdout,
|
|
@@ -9196,10 +9683,11 @@ async function executeRunCommand(config, command) {
|
|
|
9196
9683
|
...Array.isArray(execution.killedWorkspaceResidents) && execution.killedWorkspaceResidents.length > 0 ? {
|
|
9197
9684
|
killedWorkspaceResidents: execution.killedWorkspaceResidents
|
|
9198
9685
|
} : {},
|
|
9199
|
-
...piInvalidOutputError && !hasOutputFlood ? {
|
|
9686
|
+
...piInvalidOutputError && !cancelled && !hasOutputFlood && !hasMemoryLimit && execution.timedOut !== true && !execution.spawnError && !piProviderFailure ? {
|
|
9200
9687
|
errorCode: "pi_executor_invalid_output",
|
|
9201
9688
|
errorFamily: "validation"
|
|
9202
9689
|
} : {},
|
|
9690
|
+
...piProviderFailure ? piProviderFailure : {},
|
|
9203
9691
|
...codexTransientFailure ? codexTransientFailure : {},
|
|
9204
9692
|
...piUsageDiagnostic && !piInvalidOutputError ? {
|
|
9205
9693
|
piDiagnostics: {
|
|
@@ -9217,6 +9705,9 @@ async function executeRunCommand(config, command) {
|
|
|
9217
9705
|
...piChildIsolation ? {
|
|
9218
9706
|
piChildIsolation: piChildIsolation.attestation
|
|
9219
9707
|
} : {},
|
|
9708
|
+
...piCompanyMemory ? {
|
|
9709
|
+
companyMemory: piCompanyMemory.attestation
|
|
9710
|
+
} : {},
|
|
9220
9711
|
...trustedPiRuntimeProfile ? {
|
|
9221
9712
|
trustedPiRuntime: {
|
|
9222
9713
|
attestationId: trustedPiRuntime.attestationId,
|
|
@@ -9247,6 +9738,9 @@ async function executeRunCommand(config, command) {
|
|
|
9247
9738
|
});
|
|
9248
9739
|
}
|
|
9249
9740
|
piChildIsolation?.release();
|
|
9741
|
+
if (!piChildIsolation && piChildAssignmentAcquired) {
|
|
9742
|
+
piChildAllocator?.release(commandRunId(command));
|
|
9743
|
+
}
|
|
9250
9744
|
stopActiveRunHeartbeats();
|
|
9251
9745
|
forgetActiveRunCommand();
|
|
9252
9746
|
}
|
|
@@ -9275,10 +9769,14 @@ async function processCommand(config, command) {
|
|
|
9275
9769
|
});
|
|
9276
9770
|
} catch (err) {
|
|
9277
9771
|
const message = err instanceof Error ? err.message : String(err);
|
|
9772
|
+
const errorCode = readString(asRecord(err).code);
|
|
9773
|
+
const runtimeArtifacts = Array.isArray(asRecord(err).receipts) ? asRecord(err).receipts.map(asRecord) : [];
|
|
9278
9774
|
await ingestLog(config, command, "system", "error", message);
|
|
9279
9775
|
await completeCommand(config, command, "failed", {
|
|
9280
9776
|
summary: message,
|
|
9281
|
-
commandType: command.commandType
|
|
9777
|
+
commandType: command.commandType,
|
|
9778
|
+
...errorCode && /^[a-z][a-z0-9_]{0,127}$/.test(errorCode) ? { errorCode } : {},
|
|
9779
|
+
...runtimeArtifacts.length > 0 ? { runtimeArtifacts } : {}
|
|
9282
9780
|
}, message);
|
|
9283
9781
|
}
|
|
9284
9782
|
}
|
|
@@ -9449,7 +9947,7 @@ async function runLoop(config) {
|
|
|
9449
9947
|
${message}
|
|
9450
9948
|
`);
|
|
9451
9949
|
}
|
|
9452
|
-
await new Promise((
|
|
9950
|
+
await new Promise((resolve12) => setTimeout(resolve12, config.pollIntervalSeconds * 1e3));
|
|
9453
9951
|
}
|
|
9454
9952
|
}
|
|
9455
9953
|
function help() {
|