@amaster.ai/employee-runtime-connector 0.1.1-beta.103 → 0.1.1-beta.104
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.
|
@@ -3490,7 +3490,7 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
3490
3490
|
const PI_ATTESTATION_RECENT_LIVE_TTL_MS = Number.isFinite(options.recentLiveTtlMs) && options.recentLiveTtlMs > 0 ? options.recentLiveTtlMs : 30 * 60 * 1e3;
|
|
3491
3491
|
const recentLivePiVersionProbes = /* @__PURE__ */ new Map();
|
|
3492
3492
|
const effectiveToolsProbeCircuits = /* @__PURE__ */ new Map();
|
|
3493
|
-
function
|
|
3493
|
+
function record7(value) {
|
|
3494
3494
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
3495
3495
|
}
|
|
3496
3496
|
function readJsonObjectFile(filePath) {
|
|
@@ -3552,7 +3552,7 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
3552
3552
|
return matches[0];
|
|
3553
3553
|
}
|
|
3554
3554
|
function restoreManagedPiSessionRollout(input, sessionsRoot, runDir, executorHome, authority) {
|
|
3555
|
-
const session =
|
|
3555
|
+
const session = record7(input.nativeSession);
|
|
3556
3556
|
if (session.mode !== "governed_action_approval" || session.required !== true) return null;
|
|
3557
3557
|
const sessionId = nonEmpty2(session.sessionId, "nativeSession.sessionId");
|
|
3558
3558
|
const sourceRunId = nonEmpty2(session.sourceRunId, "nativeSession.sourceRunId");
|
|
@@ -3838,11 +3838,11 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
3838
3838
|
return sha2563(stablePiJson(identity2));
|
|
3839
3839
|
}
|
|
3840
3840
|
function validateDirectCatalog(gateway, mcpToolMode) {
|
|
3841
|
-
const catalog =
|
|
3841
|
+
const catalog = record7(gateway.toolCatalog);
|
|
3842
3842
|
if (catalog.schemaVersion !== DIRECT_CATALOG_SCHEMA_VERSION) {
|
|
3843
3843
|
throw new Error("pi_managed_mcp_invalid: direct tool catalog schema mismatch");
|
|
3844
3844
|
}
|
|
3845
|
-
const tools = Array.isArray(catalog.tools) ? catalog.tools.map(
|
|
3845
|
+
const tools = Array.isArray(catalog.tools) ? catalog.tools.map(record7) : [];
|
|
3846
3846
|
const declaredToolNames = new Set(tools.map((tool) => tool.name).filter((name) => typeof name === "string"));
|
|
3847
3847
|
const covers = (set) => [...set].every((name) => declaredToolNames.has(name));
|
|
3848
3848
|
const countIn = (set) => tools.filter((tool) => set.has(tool.name)).length;
|
|
@@ -3873,7 +3873,7 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
3873
3873
|
throw new Error(`pi_managed_mcp_invalid: direct tool exposed name collision for ${exposedName}`);
|
|
3874
3874
|
}
|
|
3875
3875
|
exposedNames.add(exposedName);
|
|
3876
|
-
const inputSchema =
|
|
3876
|
+
const inputSchema = record7(tool.inputSchema);
|
|
3877
3877
|
if (inputSchema.type !== "object" || inputSchema.additionalProperties !== false) {
|
|
3878
3878
|
throw new Error(`pi_managed_mcp_invalid: direct tool schema is not strict for ${name}`);
|
|
3879
3879
|
}
|
|
@@ -3960,8 +3960,8 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
3960
3960
|
}
|
|
3961
3961
|
}
|
|
3962
3962
|
function validateAuthority2(input) {
|
|
3963
|
-
const runtimeAuth =
|
|
3964
|
-
const gateway =
|
|
3963
|
+
const runtimeAuth = record7(input.runtimeAuth);
|
|
3964
|
+
const gateway = record7(runtimeAuth.governedMcp);
|
|
3965
3965
|
const runId = nonEmpty2(input.runId, "runId");
|
|
3966
3966
|
if (runtimeAuth.runId !== runId) throw new Error("pi_managed_mcp_owner_mismatch: command runId does not match runtime authority");
|
|
3967
3967
|
if (gateway.schemaVersion !== SUPPORTED_SCHEMA_VERSION2) throw new Error("pi_managed_mcp_invalid: unsupported schema version");
|
|
@@ -3977,7 +3977,7 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
3977
3977
|
if (!Number.isFinite(expiresAt) || expiresAt <= Date.now() + 3e4) {
|
|
3978
3978
|
throw new Error("pi_managed_mcp_session_expired: Gateway session must remain valid through spawn preflight");
|
|
3979
3979
|
}
|
|
3980
|
-
const headers =
|
|
3980
|
+
const headers = record7(gateway.headers);
|
|
3981
3981
|
for (const name of REQUIRED_AUTHORITY_HEADERS2) nonEmpty2(headers[name], `headers.${name}`);
|
|
3982
3982
|
const allowedHeaderNames = /* @__PURE__ */ new Set([...REQUIRED_AUTHORITY_HEADERS2, ...runtimeAuth.issueId ? ["x-amaster-issue-id"] : []]);
|
|
3983
3983
|
if (Object.keys(headers).some((name) => !allowedHeaderNames.has(name)) || Object.keys(headers).length !== allowedHeaderNames.size) {
|
|
@@ -4039,7 +4039,7 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
4039
4039
|
return env;
|
|
4040
4040
|
}
|
|
4041
4041
|
function assertInvocationIsolation2(input) {
|
|
4042
|
-
for (const name of Object.keys(
|
|
4042
|
+
for (const name of Object.keys(record7(input.commandEnv))) {
|
|
4043
4043
|
if (FORBIDDEN_COMMAND_ENV2.has(name)) throw new Error(`pi_managed_mcp_env_override_blocked: ${name}`);
|
|
4044
4044
|
if (!ALLOWED_COMMAND_ENV2.has(name)) throw new Error(`pi_managed_mcp_env_injection_blocked: ${name}`);
|
|
4045
4045
|
}
|
|
@@ -4071,7 +4071,7 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
4071
4071
|
const value = safeProxyValue2(baseEnv?.[name], name);
|
|
4072
4072
|
if (value) env[name] = value;
|
|
4073
4073
|
}
|
|
4074
|
-
return { ...env, ...
|
|
4074
|
+
return { ...env, ...record7(commandEnv) };
|
|
4075
4075
|
}
|
|
4076
4076
|
function sourceAcquisitionBrowserEnvironment(sourceAcquisition, baseEnv) {
|
|
4077
4077
|
const env = {
|
|
@@ -4116,8 +4116,8 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
4116
4116
|
} catch {
|
|
4117
4117
|
return true;
|
|
4118
4118
|
}
|
|
4119
|
-
const config =
|
|
4120
|
-
return Object.keys(
|
|
4119
|
+
const config = record7(parsed);
|
|
4120
|
+
return Object.keys(record7(config.mcpServers)).length > 0 || Object.keys(record7(config.servers)).length > 0 || Array.isArray(config.imports) && config.imports.length > 0;
|
|
4121
4121
|
}
|
|
4122
4122
|
function walkProjectMcpConfigs(cwd, runDir, visit) {
|
|
4123
4123
|
const start = resolve3(cwd);
|
|
@@ -4191,7 +4191,7 @@ function createManagedPiMcpProfileApi(options = {}) {
|
|
|
4191
4191
|
let settings = {};
|
|
4192
4192
|
if (existsSync4(settingsPath)) {
|
|
4193
4193
|
try {
|
|
4194
|
-
settings =
|
|
4194
|
+
settings = record7(JSON.parse(readFileSync4(settingsPath, "utf8")));
|
|
4195
4195
|
} catch {
|
|
4196
4196
|
throw new Error("pi_managed_mcp_attestation_failed: source Pi settings are invalid");
|
|
4197
4197
|
}
|
|
@@ -4582,7 +4582,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
4582
4582
|
workspaceMcpConfigPath
|
|
4583
4583
|
})}
|
|
4584
4584
|
`);
|
|
4585
|
-
const runtimeAuth =
|
|
4585
|
+
const runtimeAuth = record7(input.runtimeAuth);
|
|
4586
4586
|
const authority = Object.freeze({
|
|
4587
4587
|
companyId: nonEmpty2(runtimeAuth.companyId, "runtimeAuth.companyId"),
|
|
4588
4588
|
agentId: nonEmpty2(runtimeAuth.agentId, "runtimeAuth.agentId"),
|
|
@@ -4924,11 +4924,11 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
4924
4924
|
}
|
|
4925
4925
|
function restoreManagedPiRunExitClosureBaseline2(input, expectedOwner2) {
|
|
4926
4926
|
if (!input) return { status: "not_required" };
|
|
4927
|
-
const baseline =
|
|
4927
|
+
const baseline = record7(input);
|
|
4928
4928
|
if (!["amaster.pi-run-exit-closure-baseline.v1", "amaster.pi-run-exit-closure-baseline.v2"].includes(baseline.schemaVersion)) {
|
|
4929
4929
|
throw new Error("pi_run_exit_closure_baseline_invalid: unsupported schema version");
|
|
4930
4930
|
}
|
|
4931
|
-
const owner =
|
|
4931
|
+
const owner = record7(baseline.owner);
|
|
4932
4932
|
if (owner.commandId !== expectedOwner2?.commandId || owner.runId !== expectedOwner2?.runId) {
|
|
4933
4933
|
throw new Error("pi_run_exit_closure_baseline_owner_mismatch");
|
|
4934
4934
|
}
|
|
@@ -4957,12 +4957,12 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
4957
4957
|
if (sha2563(cacheContents) !== cacheSha256) {
|
|
4958
4958
|
throw new Error("pi_run_exit_closure_baseline_cache_digest_mismatch");
|
|
4959
4959
|
}
|
|
4960
|
-
const baselineCacheOwnership =
|
|
4960
|
+
const baselineCacheOwnership = record7(baseline.cacheOwnership);
|
|
4961
4961
|
const cacheOwnership = Number.isSafeInteger(baselineCacheOwnership.uid) && baselineCacheOwnership.uid >= 0 && Number.isSafeInteger(baselineCacheOwnership.gid) && baselineCacheOwnership.gid >= 0 ? { uid: baselineCacheOwnership.uid, gid: baselineCacheOwnership.gid } : existsSync4(cachePath) ? ownershipStatSyncImpl(cachePath) : null;
|
|
4962
4962
|
if (!cacheOwnership) {
|
|
4963
4963
|
throw new Error("pi_run_exit_closure_baseline_cache_owner_missing");
|
|
4964
4964
|
}
|
|
4965
|
-
const closureProfile = baseline.schemaVersion === "amaster.pi-run-exit-closure-baseline.v2" ?
|
|
4965
|
+
const closureProfile = baseline.schemaVersion === "amaster.pi-run-exit-closure-baseline.v2" ? record7(baseline.closureProfile) : null;
|
|
4966
4966
|
const closureToolAllowlist = closureProfile ? Array.isArray(closureProfile.toolAllowlist) ? closureProfile.toolAllowlist.filter((name) => typeof name === "string") : [] : null;
|
|
4967
4967
|
if (closureToolAllowlist && (closureToolAllowlist.length !== RUN_EXIT_CLOSURE_DIRECT_TYPED_TOOL_NAMES.size || new Set(closureToolAllowlist).size !== RUN_EXIT_CLOSURE_DIRECT_TYPED_TOOL_NAMES.size || closureToolAllowlist.some((name) => !PROVIDER_SAFE_TOOL_NAME.test(name)))) {
|
|
4968
4968
|
throw new Error("pi_run_exit_closure_baseline_tool_allowlist_invalid");
|
|
@@ -4988,7 +4988,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
4988
4988
|
path: configPath,
|
|
4989
4989
|
bytes: Buffer.from(nonEmpty2(closureProfile.configContentsBase64, "closureProfile.configContentsBase64"), "base64"),
|
|
4990
4990
|
expectedSha256: nonEmpty2(closureProfile.configSha256, "closureProfile.configSha256"),
|
|
4991
|
-
ownership:
|
|
4991
|
+
ownership: record7(closureProfile.configOwnership),
|
|
4992
4992
|
label: "config"
|
|
4993
4993
|
},
|
|
4994
4994
|
{
|
|
@@ -5002,7 +5002,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
5002
5002
|
path: manifestPath,
|
|
5003
5003
|
bytes: Buffer.from(nonEmpty2(closureProfile.manifestContentsBase64, "closureProfile.manifestContentsBase64"), "base64"),
|
|
5004
5004
|
expectedSha256: nonEmpty2(closureProfile.manifestSha256, "closureProfile.manifestSha256"),
|
|
5005
|
-
ownership:
|
|
5005
|
+
ownership: record7(closureProfile.manifestOwnership),
|
|
5006
5006
|
label: "manifest"
|
|
5007
5007
|
}
|
|
5008
5008
|
] : [{
|
|
@@ -5039,8 +5039,8 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
5039
5039
|
}
|
|
5040
5040
|
function inspectManagedPiRunExitClosureAttestation2(input, expectedOwner2) {
|
|
5041
5041
|
if (!input) return { status: "not_required" };
|
|
5042
|
-
const baseline =
|
|
5043
|
-
const owner =
|
|
5042
|
+
const baseline = record7(input);
|
|
5043
|
+
const owner = record7(baseline.owner);
|
|
5044
5044
|
if (owner.commandId !== expectedOwner2?.commandId || owner.runId !== expectedOwner2?.runId) {
|
|
5045
5045
|
throw new Error("pi_run_exit_closure_baseline_owner_mismatch");
|
|
5046
5046
|
}
|
|
@@ -5053,7 +5053,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
5053
5053
|
throw new Error(`pi_run_exit_closure_baseline_unsafe: ${receiptPath}`);
|
|
5054
5054
|
}
|
|
5055
5055
|
try {
|
|
5056
|
-
const receipt =
|
|
5056
|
+
const receipt = record7(JSON.parse(readFileSync4(receiptPath, "utf8")));
|
|
5057
5057
|
return {
|
|
5058
5058
|
status: nonEmpty2(receipt.status, "effectiveToolsReceipt.status"),
|
|
5059
5059
|
...typeof receipt.mode === "string" ? { mode: receipt.mode } : {},
|
|
@@ -5087,7 +5087,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
5087
5087
|
const owner = Object.freeze({ commandId: input.commandId, runId });
|
|
5088
5088
|
writePrivateFile2(markerPath, `${JSON.stringify({ version: 1, ...owner, profileRoot, piCodingAgentDir })}
|
|
5089
5089
|
`);
|
|
5090
|
-
const runtimeAuth =
|
|
5090
|
+
const runtimeAuth = record7(input.runtimeAuth);
|
|
5091
5091
|
const authority = Object.freeze({
|
|
5092
5092
|
companyId: nonEmpty2(runtimeAuth.companyId, "runtimeAuth.companyId"),
|
|
5093
5093
|
agentId: nonEmpty2(runtimeAuth.agentId, "runtimeAuth.agentId"),
|
|
@@ -5114,11 +5114,11 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
5114
5114
|
const config = {
|
|
5115
5115
|
...sourceMcp,
|
|
5116
5116
|
settings: {
|
|
5117
|
-
...
|
|
5117
|
+
...record7(sourceMcp.settings),
|
|
5118
5118
|
...mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE ? { disableProxyTool: true } : {}
|
|
5119
5119
|
},
|
|
5120
5120
|
mcpServers: {
|
|
5121
|
-
...
|
|
5121
|
+
...record7(sourceMcp.mcpServers),
|
|
5122
5122
|
[SUPPORTED_SERVER_NAME2]: serverConfig
|
|
5123
5123
|
}
|
|
5124
5124
|
};
|
|
@@ -5141,7 +5141,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
|
|
|
5141
5141
|
}
|
|
5142
5142
|
const env = {
|
|
5143
5143
|
...input.baseEnv,
|
|
5144
|
-
...
|
|
5144
|
+
...record7(input.commandEnv),
|
|
5145
5145
|
PI_AGENT_HOME: sourcePiHome,
|
|
5146
5146
|
PI_CODING_AGENT_DIR: piCodingAgentDir,
|
|
5147
5147
|
"AMASTER-CLI_CODING_AGENT_DIR": piCodingAgentDir,
|
|
@@ -5497,8 +5497,8 @@ function resultOutboxFileName(commandId, now = Date.now()) {
|
|
|
5497
5497
|
return `${now}-${safeCommandId}.json`;
|
|
5498
5498
|
}
|
|
5499
5499
|
function isValidResultOutboxEntry(entry) {
|
|
5500
|
-
const
|
|
5501
|
-
return
|
|
5500
|
+
const record7 = asRecord(entry);
|
|
5501
|
+
return record7.version === 1 && Boolean(readString(record7.path)) && Object.keys(asRecord(record7.payload)).length > 0;
|
|
5502
5502
|
}
|
|
5503
5503
|
function resultOutboxEntryAgeMs(entry, nowMs) {
|
|
5504
5504
|
const createdAt = Date.parse(readString(entry.createdAt) ?? "");
|
|
@@ -5805,6 +5805,60 @@ function retainedSourceExecutorEntry(entry, executorKind) {
|
|
|
5805
5805
|
};
|
|
5806
5806
|
}
|
|
5807
5807
|
|
|
5808
|
+
// src/amaster-runtime-daemon/source-acquisition-profile.mjs
|
|
5809
|
+
var HEADLESS_ADAPTER = "pi_browser_use_headless_v1";
|
|
5810
|
+
var DESKTOP_ADAPTER = "browser_skill_desktop_v1";
|
|
5811
|
+
function invalid() {
|
|
5812
|
+
return Object.assign(new Error("source_acquisition_profile_invalid"), {
|
|
5813
|
+
code: "source_acquisition_profile_invalid"
|
|
5814
|
+
});
|
|
5815
|
+
}
|
|
5816
|
+
function exactSourceLocator(value) {
|
|
5817
|
+
if (typeof value !== "string" || value.length === 0) throw invalid();
|
|
5818
|
+
let url;
|
|
5819
|
+
try {
|
|
5820
|
+
url = new URL(value);
|
|
5821
|
+
} catch {
|
|
5822
|
+
throw invalid();
|
|
5823
|
+
}
|
|
5824
|
+
if (!["http:", "https:"].includes(url.protocol) || url.username || url.password) throw invalid();
|
|
5825
|
+
return url;
|
|
5826
|
+
}
|
|
5827
|
+
function exactAuthenticationOrigin(value) {
|
|
5828
|
+
const url = exactSourceLocator(value);
|
|
5829
|
+
if (url.protocol !== "https:" || value !== url.origin) throw invalid();
|
|
5830
|
+
return url.origin;
|
|
5831
|
+
}
|
|
5832
|
+
function exactSourceOrigin(value) {
|
|
5833
|
+
const url = exactSourceLocator(value);
|
|
5834
|
+
if (value !== url.origin) throw invalid();
|
|
5835
|
+
return url.origin;
|
|
5836
|
+
}
|
|
5837
|
+
function inspectSourceAcquisitionProfile(profile, expectedRunId) {
|
|
5838
|
+
const access = profile?.access;
|
|
5839
|
+
const transport = profile?.transport;
|
|
5840
|
+
const tools = profile?.tools;
|
|
5841
|
+
const connectorAdmission = profile?.connectorAdmission;
|
|
5842
|
+
if (!profile || typeof profile !== "object" || profile.retention !== "source_summary_only_v1" || profile.runId !== expectedRunId || !Array.isArray(tools?.exactAllowlist) || tools.exactAllowlist.length === 0 || !["public", "authenticated"].includes(access?.mode) || !["isolated", "existing"].includes(transport?.browserMode) || ![HEADLESS_ADAPTER, DESKTOP_ADAPTER].includes(transport?.adapter) || connectorAdmission?.adapter !== transport?.adapter) throw invalid();
|
|
5843
|
+
if (access.mode === "public" && (transport.browserMode !== "isolated" || transport.adapter !== HEADLESS_ADAPTER) || access.mode === "authenticated" && (transport.browserMode !== "existing" || transport.adapter !== DESKTOP_ADAPTER)) throw invalid();
|
|
5844
|
+
if (profile.purpose === "source_acquisition_v1") {
|
|
5845
|
+
if (connectorAdmission.capability !== "source_acquisition_v1" || connectorAdmission.profileVersion !== "source_acquisition_v1") throw invalid();
|
|
5846
|
+
const locators = [access.exactLocator, ...Array.isArray(access.declaredPageLocators) ? access.declaredPageLocators : []];
|
|
5847
|
+
const sourceOrigins2 = [...new Set(locators.map((locator) => exactSourceLocator(locator).origin))];
|
|
5848
|
+
return { version: profile.purpose, mode: access.mode, sourceOrigins: sourceOrigins2 };
|
|
5849
|
+
}
|
|
5850
|
+
if (profile.purpose !== "source_acquisition_v2" || connectorAdmission.capability !== "source_authentication_origin_discovery_v1" || connectorAdmission.profileVersion !== "source_acquisition_v2" || !Array.isArray(access.exactSourceLocators) || access.exactSourceLocators.length === 0 || !Array.isArray(access.sourceOrigins) || access.sourceOrigins.length === 0 || !Array.isArray(access.authorizedAuthenticationOrigins) || access.authenticationOriginDiscovery?.enabled !== true) throw invalid();
|
|
5851
|
+
const derivedSourceOrigins = [...new Set(
|
|
5852
|
+
access.exactSourceLocators.map((locator) => exactSourceLocator(locator).origin)
|
|
5853
|
+
)];
|
|
5854
|
+
const sourceOrigins = access.sourceOrigins.map(exactSourceOrigin);
|
|
5855
|
+
const sourceOriginSet = new Set(sourceOrigins);
|
|
5856
|
+
if (sourceOriginSet.size !== sourceOrigins.length || derivedSourceOrigins.length !== sourceOrigins.length || derivedSourceOrigins.some((origin) => !sourceOriginSet.has(origin))) throw invalid();
|
|
5857
|
+
const authenticationOrigins = access.authorizedAuthenticationOrigins.map(exactAuthenticationOrigin);
|
|
5858
|
+
if (authenticationOrigins.some((origin) => sourceOriginSet.has(origin))) throw invalid();
|
|
5859
|
+
return { version: profile.purpose, mode: access.mode, sourceOrigins };
|
|
5860
|
+
}
|
|
5861
|
+
|
|
5808
5862
|
// src/amaster-runtime-daemon/prompt-compiler.mjs
|
|
5809
5863
|
import { createHash as createHash6 } from "node:crypto";
|
|
5810
5864
|
|
|
@@ -6046,7 +6100,18 @@ function sourceAcquisitionPiInvocationArgs(profile) {
|
|
|
6046
6100
|
}
|
|
6047
6101
|
function serializeSourceAcquisitionProfile(profile) {
|
|
6048
6102
|
if (!profile || typeof profile !== "object" || Array.isArray(profile)) return null;
|
|
6049
|
-
const
|
|
6103
|
+
const canonicalize = (value) => {
|
|
6104
|
+
if (value === null || typeof value === "boolean" || typeof value === "string") {
|
|
6105
|
+
return JSON.stringify(value);
|
|
6106
|
+
}
|
|
6107
|
+
if (typeof value === "number" && Number.isFinite(value)) return JSON.stringify(value);
|
|
6108
|
+
if (Array.isArray(value)) return `[${value.map(canonicalize).join(",")}]`;
|
|
6109
|
+
if (value && typeof value === "object") {
|
|
6110
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalize(value[key])}`).join(",")}}`;
|
|
6111
|
+
}
|
|
6112
|
+
throw new Error("source_acquisition_profile_canonicalization_failed");
|
|
6113
|
+
};
|
|
6114
|
+
const input = Buffer.from(canonicalize(profile), "utf8");
|
|
6050
6115
|
return {
|
|
6051
6116
|
input,
|
|
6052
6117
|
sha256: createHash5("sha256").update(input).digest("hex")
|
|
@@ -6137,19 +6202,19 @@ function promptContextMode(input) {
|
|
|
6137
6202
|
}
|
|
6138
6203
|
function filterDuplicatedTaskComments(context, mode) {
|
|
6139
6204
|
if (mode !== "cold") return context;
|
|
6140
|
-
const
|
|
6205
|
+
const record7 = asRecord(context);
|
|
6141
6206
|
const included = new Set(
|
|
6142
|
-
(Array.isArray(
|
|
6207
|
+
(Array.isArray(record7.paperclipTaskMarkdownCommentIds) ? record7.paperclipTaskMarkdownCommentIds : []).map((entry) => readString(entry)).filter(Boolean)
|
|
6143
6208
|
);
|
|
6144
6209
|
if (included.size === 0) return context;
|
|
6145
|
-
const wake = asRecord(
|
|
6210
|
+
const wake = asRecord(record7.paperclipWake);
|
|
6146
6211
|
const comments = Array.isArray(wake.comments) ? wake.comments : [];
|
|
6147
6212
|
const kept = comments.filter((entry) => {
|
|
6148
6213
|
const id = readString(asRecord(entry).id);
|
|
6149
6214
|
return !id || !included.has(id);
|
|
6150
6215
|
});
|
|
6151
6216
|
if (kept.length === comments.length) return context;
|
|
6152
|
-
return { ...
|
|
6217
|
+
return { ...record7, paperclipWake: { ...wake, comments: kept } };
|
|
6153
6218
|
}
|
|
6154
6219
|
function commentRefs(context) {
|
|
6155
6220
|
const comments = Array.isArray(asRecord(context.paperclipWake).comments) ? asRecord(context.paperclipWake).comments : [];
|
|
@@ -6283,8 +6348,8 @@ function governedReadSection(context) {
|
|
|
6283
6348
|
const reads = Array.isArray(context.governedReadResults) ? context.governedReadResults : [];
|
|
6284
6349
|
if (reads.length === 0) return { content: "", provenance: [] };
|
|
6285
6350
|
const normalized = reads.map((entry, index) => {
|
|
6286
|
-
const
|
|
6287
|
-
const receipt = asRecord(
|
|
6351
|
+
const record7 = asRecord(entry);
|
|
6352
|
+
const receipt = asRecord(record7.receipt);
|
|
6288
6353
|
const provider = readString(receipt.provider) ?? readString(receipt.transport);
|
|
6289
6354
|
const operation = readString(receipt.operation);
|
|
6290
6355
|
const observedAt = readString(receipt.retrievedAt) ?? readString(receipt.observedAt);
|
|
@@ -6294,7 +6359,7 @@ function governedReadSection(context) {
|
|
|
6294
6359
|
throw new Error(`governed_read_context_provenance_invalid: entry ${index} requires provider, operation, observedAt, and source`);
|
|
6295
6360
|
}
|
|
6296
6361
|
return {
|
|
6297
|
-
content:
|
|
6362
|
+
content: record7.content,
|
|
6298
6363
|
receipt: {
|
|
6299
6364
|
provider,
|
|
6300
6365
|
operation,
|
|
@@ -6340,11 +6405,11 @@ function governedBusinessDetailRead(input, issueId) {
|
|
|
6340
6405
|
return { mode: "canonical", tool: canonicalTool, arguments: argumentsValue };
|
|
6341
6406
|
}
|
|
6342
6407
|
function governedBusinessDecisionProjection(state, detailRead) {
|
|
6343
|
-
const
|
|
6344
|
-
const snapshot = asRecord(
|
|
6345
|
-
const authoritativeObjectRefs = Array.isArray(
|
|
6346
|
-
const capabilities = Array.isArray(
|
|
6347
|
-
const availability = asRecord(
|
|
6408
|
+
const record7 = asRecord(state);
|
|
6409
|
+
const snapshot = asRecord(record7.governed_state_snapshot);
|
|
6410
|
+
const authoritativeObjectRefs = Array.isArray(record7.authoritative_object_refs) ? record7.authoritative_object_refs : [];
|
|
6411
|
+
const capabilities = Array.isArray(record7.capabilities) ? record7.capabilities : [];
|
|
6412
|
+
const availability = asRecord(record7.availability);
|
|
6348
6413
|
const projection = {
|
|
6349
6414
|
status: readString(availability.status) ?? null,
|
|
6350
6415
|
objects: authoritativeObjectRefs.map((entry) => {
|
|
@@ -6359,7 +6424,7 @@ function governedBusinessDecisionProjection(state, detailRead) {
|
|
|
6359
6424
|
}
|
|
6360
6425
|
return compact;
|
|
6361
6426
|
}),
|
|
6362
|
-
missing: (Array.isArray(
|
|
6427
|
+
missing: (Array.isArray(record7.missing_objects) ? record7.missing_objects : []).map((entry) => {
|
|
6363
6428
|
const missing = asRecord(entry);
|
|
6364
6429
|
return {
|
|
6365
6430
|
kind: readString(missing.object_kind) ?? null,
|
|
@@ -6379,22 +6444,22 @@ function governedBusinessDecisionProjection(state, detailRead) {
|
|
|
6379
6444
|
if (unavailableReads.length > 0) {
|
|
6380
6445
|
projection.unavailable_reads = unavailableReads;
|
|
6381
6446
|
}
|
|
6382
|
-
const continuationId = readString(
|
|
6447
|
+
const continuationId = readString(record7.continuation_id);
|
|
6383
6448
|
if (continuationId) projection.continuation_id = continuationId;
|
|
6384
|
-
if (Number.isInteger(
|
|
6385
|
-
const freeTextReason = readString(
|
|
6449
|
+
if (Number.isInteger(record7.outcome_revision)) projection.outcome_revision = record7.outcome_revision;
|
|
6450
|
+
const freeTextReason = readString(record7.free_text_reason);
|
|
6386
6451
|
if (freeTextReason) projection.free_text_reason = freeTextReason;
|
|
6387
6452
|
return projection;
|
|
6388
6453
|
}
|
|
6389
6454
|
function governedBusinessModelView(state, input) {
|
|
6390
|
-
const
|
|
6391
|
-
const snapshot = asRecord(
|
|
6455
|
+
const record7 = asRecord(state);
|
|
6456
|
+
const snapshot = asRecord(record7.governed_state_snapshot);
|
|
6392
6457
|
const detailRead = governedBusinessDetailRead(
|
|
6393
6458
|
input,
|
|
6394
6459
|
readString(snapshot.issue_id) ?? readString(input.issueId)
|
|
6395
6460
|
);
|
|
6396
6461
|
if (detailRead.mode === "unavailable") {
|
|
6397
|
-
const { task_acceptance_contract: _TaskAcceptanceContract, ...stateWithoutAcceptanceContract } =
|
|
6462
|
+
const { task_acceptance_contract: _TaskAcceptanceContract, ...stateWithoutAcceptanceContract } = record7;
|
|
6398
6463
|
return {
|
|
6399
6464
|
mode: "full_snapshot",
|
|
6400
6465
|
content: stateWithoutAcceptanceContract,
|
|
@@ -6403,7 +6468,7 @@ function governedBusinessModelView(state, input) {
|
|
|
6403
6468
|
}
|
|
6404
6469
|
return {
|
|
6405
6470
|
mode: "decision_projection",
|
|
6406
|
-
content: governedBusinessDecisionProjection(
|
|
6471
|
+
content: governedBusinessDecisionProjection(record7, detailRead),
|
|
6407
6472
|
unavailableReason: null
|
|
6408
6473
|
};
|
|
6409
6474
|
}
|
|
@@ -6469,10 +6534,10 @@ ${bodies}`,
|
|
|
6469
6534
|
}
|
|
6470
6535
|
function canonicalJsonValue(value) {
|
|
6471
6536
|
if (Array.isArray(value)) return value.map(canonicalJsonValue);
|
|
6472
|
-
const
|
|
6473
|
-
if (Object.keys(
|
|
6537
|
+
const record7 = asRecord(value);
|
|
6538
|
+
if (Object.keys(record7).length === 0) return value;
|
|
6474
6539
|
return Object.fromEntries(
|
|
6475
|
-
Object.keys(
|
|
6540
|
+
Object.keys(record7).sort().map((key) => [key, canonicalJsonValue(record7[key])])
|
|
6476
6541
|
);
|
|
6477
6542
|
}
|
|
6478
6543
|
function resolvedDependencySections(context, input, contextScope, snapshotFreshness) {
|
|
@@ -8543,10 +8608,10 @@ function compactExecutorJsonlForTranscript(event) {
|
|
|
8543
8608
|
const text = JSON.stringify(compactExecutorJsonValue(event, stringMaxChars));
|
|
8544
8609
|
if (text.length <= 15e3) return text;
|
|
8545
8610
|
}
|
|
8546
|
-
const
|
|
8547
|
-
const item = tcAsRecord(
|
|
8611
|
+
const record7 = tcAsRecord(event);
|
|
8612
|
+
const item = tcAsRecord(record7.item);
|
|
8548
8613
|
return JSON.stringify({
|
|
8549
|
-
type: tcReadString(
|
|
8614
|
+
type: tcReadString(record7.type) ?? "executor.event",
|
|
8550
8615
|
item: item.type ? {
|
|
8551
8616
|
id: tcReadString(item.id),
|
|
8552
8617
|
type: tcReadString(item.type),
|
|
@@ -8559,10 +8624,10 @@ function compactExecutorJsonlForTranscript(event) {
|
|
|
8559
8624
|
});
|
|
8560
8625
|
}
|
|
8561
8626
|
function summarizeTokenUsage(usage) {
|
|
8562
|
-
const
|
|
8563
|
-
const inputTokens = tcReadNumber(
|
|
8564
|
-
const cachedInputTokens = tcReadNumber(
|
|
8565
|
-
const outputTokens = tcReadNumber(
|
|
8627
|
+
const record7 = tcAsRecord(usage);
|
|
8628
|
+
const inputTokens = tcReadNumber(record7.input_tokens ?? record7.inputTokens, 0);
|
|
8629
|
+
const cachedInputTokens = tcReadNumber(record7.cached_input_tokens ?? record7.cachedInputTokens, 0);
|
|
8630
|
+
const outputTokens = tcReadNumber(record7.output_tokens ?? record7.outputTokens, 0);
|
|
8566
8631
|
const parts = [];
|
|
8567
8632
|
if (inputTokens > 0) parts.push(`\u8F93\u5165 ${inputTokens}`);
|
|
8568
8633
|
if (cachedInputTokens > 0) parts.push(`\u7F13\u5B58 ${cachedInputTokens}`);
|
|
@@ -8817,8 +8882,8 @@ function summarizeClaudeEvent(event) {
|
|
|
8817
8882
|
return null;
|
|
8818
8883
|
}
|
|
8819
8884
|
function tcPiMessageText(message) {
|
|
8820
|
-
const
|
|
8821
|
-
const content =
|
|
8885
|
+
const record7 = tcAsRecord(message);
|
|
8886
|
+
const content = record7.content;
|
|
8822
8887
|
if (typeof content === "string" && content.trim().length > 0) return content.trim();
|
|
8823
8888
|
if (!Array.isArray(content)) return "";
|
|
8824
8889
|
return content.map((entry) => {
|
|
@@ -8832,14 +8897,14 @@ function tcPiAssistantMessageEventText(assistantMessageEvent) {
|
|
|
8832
8897
|
return tcReadString(event.content) ?? "";
|
|
8833
8898
|
}
|
|
8834
8899
|
function tcPiMessageStopReason(message) {
|
|
8835
|
-
const
|
|
8836
|
-
return tcReadString(
|
|
8900
|
+
const record7 = tcAsRecord(message);
|
|
8901
|
+
return tcReadString(record7.stopReason ?? record7.stop_reason);
|
|
8837
8902
|
}
|
|
8838
8903
|
function tcPiMessageErrorText(message) {
|
|
8839
|
-
const
|
|
8840
|
-
const explicitError = tcReadString(
|
|
8904
|
+
const record7 = tcAsRecord(message);
|
|
8905
|
+
const explicitError = tcReadString(record7.errorMessage ?? record7.error_message)?.trim();
|
|
8841
8906
|
if (explicitError) return explicitError;
|
|
8842
|
-
const stopReason = tcPiMessageStopReason(
|
|
8907
|
+
const stopReason = tcPiMessageStopReason(record7);
|
|
8843
8908
|
if (stopReason === "error" || stopReason === "failed" || stopReason === "exception") {
|
|
8844
8909
|
return `Pi Agent message ended with stopReason=${stopReason}`;
|
|
8845
8910
|
}
|
|
@@ -9494,13 +9559,13 @@ function parseClaudeStreamJson(stdout) {
|
|
|
9494
9559
|
}
|
|
9495
9560
|
function openCodeErrorText(value) {
|
|
9496
9561
|
if (typeof value === "string") return value;
|
|
9497
|
-
const
|
|
9498
|
-
const message = readString(
|
|
9562
|
+
const record7 = asRecord(value);
|
|
9563
|
+
const message = readString(record7.message);
|
|
9499
9564
|
if (message) return message;
|
|
9500
|
-
const data = asRecord(
|
|
9565
|
+
const data = asRecord(record7.data);
|
|
9501
9566
|
const nestedMessage = readString(data.message);
|
|
9502
9567
|
if (nestedMessage) return nestedMessage;
|
|
9503
|
-
return readString(
|
|
9568
|
+
return readString(record7.name) ?? readString(record7.code) ?? "";
|
|
9504
9569
|
}
|
|
9505
9570
|
function parseOpenCodeJsonl(stdout) {
|
|
9506
9571
|
let sessionId = null;
|
|
@@ -9538,8 +9603,8 @@ function parseOpenCodeJsonl(stdout) {
|
|
|
9538
9603
|
return { sessionId, summary, usage, errorMessage };
|
|
9539
9604
|
}
|
|
9540
9605
|
function piMessageText(message) {
|
|
9541
|
-
const
|
|
9542
|
-
const content =
|
|
9606
|
+
const record7 = asRecord(message);
|
|
9607
|
+
const content = record7.content;
|
|
9543
9608
|
if (typeof content === "string") return content.trim();
|
|
9544
9609
|
if (!Array.isArray(content)) return "";
|
|
9545
9610
|
return content.map((entry) => {
|
|
@@ -9548,10 +9613,10 @@ function piMessageText(message) {
|
|
|
9548
9613
|
}).filter(Boolean).join("\n").trim();
|
|
9549
9614
|
}
|
|
9550
9615
|
function piAgentEndHasFinalAssistantText(event) {
|
|
9551
|
-
const
|
|
9552
|
-
if (
|
|
9553
|
-
const messages = Array.isArray(
|
|
9554
|
-
if (Object.keys(asRecord(
|
|
9616
|
+
const record7 = asRecord(event);
|
|
9617
|
+
if (record7.type !== "agent_end") return false;
|
|
9618
|
+
const messages = Array.isArray(record7.messages) ? [...record7.messages] : [];
|
|
9619
|
+
if (Object.keys(asRecord(record7.message)).length > 0) messages.push(record7.message);
|
|
9555
9620
|
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
9556
9621
|
const message = asRecord(messages[index]);
|
|
9557
9622
|
if (message.role !== "assistant") continue;
|
|
@@ -9584,10 +9649,10 @@ function piTextValue(value) {
|
|
|
9584
9649
|
return typeof value === "string" && value.length > 0 ? value : "";
|
|
9585
9650
|
}
|
|
9586
9651
|
function piAssistantEventText(assistantEvent) {
|
|
9587
|
-
const
|
|
9588
|
-
const type = readString(
|
|
9589
|
-
if (type === "text_delta") return piTextValue(
|
|
9590
|
-
if (type === "text_end") return piTextValue(
|
|
9652
|
+
const record7 = asRecord(assistantEvent);
|
|
9653
|
+
const type = readString(record7.type);
|
|
9654
|
+
if (type === "text_delta") return piTextValue(record7.delta);
|
|
9655
|
+
if (type === "text_end") return piTextValue(record7.content);
|
|
9591
9656
|
return "";
|
|
9592
9657
|
}
|
|
9593
9658
|
function piMessageUsage(message) {
|
|
@@ -9608,14 +9673,14 @@ function assignPiUsage(target, source) {
|
|
|
9608
9673
|
if (source.costUsd > 0) target.costUsd = source.costUsd;
|
|
9609
9674
|
}
|
|
9610
9675
|
function piMessageStopReason(message) {
|
|
9611
|
-
const
|
|
9612
|
-
return readString(
|
|
9676
|
+
const record7 = asRecord(message);
|
|
9677
|
+
return readString(record7.stopReason ?? record7.stop_reason);
|
|
9613
9678
|
}
|
|
9614
9679
|
function piMessageErrorText(message) {
|
|
9615
|
-
const
|
|
9616
|
-
const explicitError = readString(
|
|
9680
|
+
const record7 = asRecord(message);
|
|
9681
|
+
const explicitError = readString(record7.errorMessage ?? record7.error_message)?.trim();
|
|
9617
9682
|
if (explicitError) return explicitError;
|
|
9618
|
-
const stopReason = piMessageStopReason(
|
|
9683
|
+
const stopReason = piMessageStopReason(record7);
|
|
9619
9684
|
if (stopReason === "error" || stopReason === "failed" || stopReason === "exception") {
|
|
9620
9685
|
return `Pi Agent message ended with stopReason=${stopReason}`;
|
|
9621
9686
|
}
|
|
@@ -9779,6 +9844,79 @@ function piSourceObservationReceipts(event) {
|
|
|
9779
9844
|
}
|
|
9780
9845
|
return receipts;
|
|
9781
9846
|
}
|
|
9847
|
+
function hasExactKeys(value, expected) {
|
|
9848
|
+
const keys = Object.keys(asRecord(value)).sort();
|
|
9849
|
+
return keys.length === expected.length && expected.slice().sort().every((key, index) => key === keys[index]);
|
|
9850
|
+
}
|
|
9851
|
+
function canonicalOrigin(value, protocol) {
|
|
9852
|
+
const raw = readString(value);
|
|
9853
|
+
if (!raw) return null;
|
|
9854
|
+
try {
|
|
9855
|
+
const url = new URL(raw);
|
|
9856
|
+
if ((protocol ? url.protocol !== protocol : !["http:", "https:"].includes(url.protocol)) || url.username || url.password || url.pathname !== "/" || url.search || url.hash || url.origin !== raw || url.hostname === "localhost" || url.hostname.endsWith(".localhost") || /^\[.*\]$|^\d{1,3}(?:\.\d{1,3}){3}$/.test(url.hostname)) return null;
|
|
9857
|
+
return url.origin;
|
|
9858
|
+
} catch {
|
|
9859
|
+
return null;
|
|
9860
|
+
}
|
|
9861
|
+
}
|
|
9862
|
+
function piSourceAuthenticationOriginDiscoveries(event) {
|
|
9863
|
+
if (readString(event?.type) !== "amaster_source_authentication_discovery" || readString(event?.version) !== "authentication_origin_discovery_v1" || !hasExactKeys(event, ["type", "version", "authenticationOriginDiscovery"])) return [];
|
|
9864
|
+
const discovery = asRecord(event.authenticationOriginDiscovery);
|
|
9865
|
+
const context = asRecord(discovery.context);
|
|
9866
|
+
const receipt = asRecord(discovery.receipt);
|
|
9867
|
+
const uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
9868
|
+
if (!hasExactKeys(discovery, ["context", "receipt", "receiptDigest"]) || !hasExactKeys(context, [
|
|
9869
|
+
"companyId",
|
|
9870
|
+
"sourceId",
|
|
9871
|
+
"sourceRevisionId",
|
|
9872
|
+
"attemptId",
|
|
9873
|
+
"epoch",
|
|
9874
|
+
"connectorId",
|
|
9875
|
+
"connectionEpoch"
|
|
9876
|
+
]) || !hasExactKeys(receipt, [
|
|
9877
|
+
"version",
|
|
9878
|
+
"discoveryId",
|
|
9879
|
+
"runId",
|
|
9880
|
+
"sourceOrigin",
|
|
9881
|
+
"targetOrigin",
|
|
9882
|
+
"navigationKind",
|
|
9883
|
+
"redirectStatus",
|
|
9884
|
+
"capturedAt",
|
|
9885
|
+
"profileDigest"
|
|
9886
|
+
]) || ![
|
|
9887
|
+
context.companyId,
|
|
9888
|
+
context.sourceId,
|
|
9889
|
+
context.sourceRevisionId,
|
|
9890
|
+
context.attemptId,
|
|
9891
|
+
context.connectorId,
|
|
9892
|
+
context.connectionEpoch,
|
|
9893
|
+
receipt.discoveryId,
|
|
9894
|
+
receipt.runId
|
|
9895
|
+
].every((value) => uuid.test(readString(value) ?? "")) || !Number.isSafeInteger(context.epoch) || context.epoch < 1 || receipt.version !== "authentication_origin_discovery_v1" || !canonicalOrigin(receipt.sourceOrigin) || !canonicalOrigin(receipt.targetOrigin, "https:") || receipt.sourceOrigin === receipt.targetOrigin || !["http_redirect", "top_frame_navigation"].includes(receipt.navigationKind) || (receipt.navigationKind === "http_redirect" ? !Number.isInteger(receipt.redirectStatus) || receipt.redirectStatus < 300 || receipt.redirectStatus > 399 : receipt.redirectStatus !== null) || !Number.isFinite(Date.parse(readString(receipt.capturedAt) ?? "")) || !/^sha256:[a-f0-9]{64}$/.test(readString(receipt.profileDigest) ?? "") || !/^sha256:[a-f0-9]{64}$/.test(readString(discovery.receiptDigest) ?? "")) return [];
|
|
9896
|
+
return [{
|
|
9897
|
+
context: {
|
|
9898
|
+
companyId: context.companyId,
|
|
9899
|
+
sourceId: context.sourceId,
|
|
9900
|
+
sourceRevisionId: context.sourceRevisionId,
|
|
9901
|
+
attemptId: context.attemptId,
|
|
9902
|
+
epoch: context.epoch,
|
|
9903
|
+
connectorId: context.connectorId,
|
|
9904
|
+
connectionEpoch: context.connectionEpoch
|
|
9905
|
+
},
|
|
9906
|
+
receipt: {
|
|
9907
|
+
version: receipt.version,
|
|
9908
|
+
discoveryId: receipt.discoveryId,
|
|
9909
|
+
runId: receipt.runId,
|
|
9910
|
+
sourceOrigin: receipt.sourceOrigin,
|
|
9911
|
+
targetOrigin: receipt.targetOrigin,
|
|
9912
|
+
navigationKind: receipt.navigationKind,
|
|
9913
|
+
redirectStatus: receipt.redirectStatus,
|
|
9914
|
+
capturedAt: receipt.capturedAt,
|
|
9915
|
+
profileDigest: receipt.profileDigest
|
|
9916
|
+
},
|
|
9917
|
+
receiptDigest: discovery.receiptDigest
|
|
9918
|
+
}];
|
|
9919
|
+
}
|
|
9782
9920
|
function parsePiJsonl(stdout) {
|
|
9783
9921
|
let sessionId = null;
|
|
9784
9922
|
let errorMessage = null;
|
|
@@ -11581,7 +11719,8 @@ async function executeBrowserSessionCommand(command, dependencies = {}) {
|
|
|
11581
11719
|
}
|
|
11582
11720
|
|
|
11583
11721
|
// src/amaster-runtime-daemon/browser-session-broker.mjs
|
|
11584
|
-
import { createHash as createHash13 } from "node:crypto";
|
|
11722
|
+
import { createHash as createHash13, randomUUID } from "node:crypto";
|
|
11723
|
+
import { lookup as dnsLookup } from "node:dns/promises";
|
|
11585
11724
|
import {
|
|
11586
11725
|
chmodSync as chmodSync6,
|
|
11587
11726
|
existsSync as existsSync13,
|
|
@@ -11592,12 +11731,213 @@ import {
|
|
|
11592
11731
|
statSync as statSync8,
|
|
11593
11732
|
writeFileSync as writeFileSync9
|
|
11594
11733
|
} from "node:fs";
|
|
11734
|
+
import { createServer as createHttpServer } from "node:http";
|
|
11735
|
+
import { connect as connectTcp, isIP } from "node:net";
|
|
11595
11736
|
import { dirname as dirname9, join as join14, relative as relative6, resolve as resolve10 } from "node:path";
|
|
11596
11737
|
var MARKER_NAME = ".amaster-browser-session.json";
|
|
11738
|
+
var HUMAN_LEASE_INACTIVITY_MS = 30 * 60 * 1e3;
|
|
11597
11739
|
var HUMAN_LEASE_HARD_CAP_MS = 2 * 60 * 60 * 1e3;
|
|
11740
|
+
var TERMINATED_LEASE_HISTORY_LIMIT = 100;
|
|
11598
11741
|
function brokerError(code) {
|
|
11599
11742
|
return Object.assign(new Error(code), { code });
|
|
11600
11743
|
}
|
|
11744
|
+
function parseIpv4(value) {
|
|
11745
|
+
const parts = value.split(".").map(Number);
|
|
11746
|
+
if (parts.length !== 4 || parts.some((part) => !Number.isInteger(part) || part < 0 || part > 255)) {
|
|
11747
|
+
return null;
|
|
11748
|
+
}
|
|
11749
|
+
return parts;
|
|
11750
|
+
}
|
|
11751
|
+
function parseIpv6(value) {
|
|
11752
|
+
const withoutZone = value.split("%")[0].toLowerCase();
|
|
11753
|
+
const halves = withoutZone.split("::");
|
|
11754
|
+
if (halves.length > 2) return null;
|
|
11755
|
+
const parseSide = (side) => {
|
|
11756
|
+
if (!side) return [];
|
|
11757
|
+
const groups2 = [];
|
|
11758
|
+
for (const part of side.split(":")) {
|
|
11759
|
+
if (part.includes(".")) {
|
|
11760
|
+
const ipv4 = parseIpv4(part);
|
|
11761
|
+
if (!ipv4) return null;
|
|
11762
|
+
groups2.push(ipv4[0] << 8 | ipv4[1], ipv4[2] << 8 | ipv4[3]);
|
|
11763
|
+
} else {
|
|
11764
|
+
if (!/^[a-f0-9]{1,4}$/.test(part)) return null;
|
|
11765
|
+
groups2.push(Number.parseInt(part, 16));
|
|
11766
|
+
}
|
|
11767
|
+
}
|
|
11768
|
+
return groups2;
|
|
11769
|
+
};
|
|
11770
|
+
const left = parseSide(halves[0]);
|
|
11771
|
+
const right = parseSide(halves[1] ?? "");
|
|
11772
|
+
if (!left || !right) return null;
|
|
11773
|
+
const missing = 8 - left.length - right.length;
|
|
11774
|
+
if (halves.length === 1 && missing !== 0 || halves.length === 2 && missing < 1) return null;
|
|
11775
|
+
const groups = [...left, ...Array(Math.max(0, missing)).fill(0), ...right];
|
|
11776
|
+
if (groups.length !== 8) return null;
|
|
11777
|
+
return groups.flatMap((group) => [group >> 8, group & 255]);
|
|
11778
|
+
}
|
|
11779
|
+
function prefixMatches(bytes, prefix, bits) {
|
|
11780
|
+
const whole = Math.floor(bits / 8);
|
|
11781
|
+
const rest = bits % 8;
|
|
11782
|
+
for (let index = 0; index < whole; index += 1) {
|
|
11783
|
+
if (bytes[index] !== prefix[index]) return false;
|
|
11784
|
+
}
|
|
11785
|
+
if (!rest) return true;
|
|
11786
|
+
const mask = 255 << 8 - rest;
|
|
11787
|
+
return (bytes[whole] & mask) === (prefix[whole] & mask);
|
|
11788
|
+
}
|
|
11789
|
+
function ipv4IsPublic(address) {
|
|
11790
|
+
const bytes = parseIpv4(address);
|
|
11791
|
+
if (!bytes) return false;
|
|
11792
|
+
const [a, b, c] = bytes;
|
|
11793
|
+
if (a === 0 || a === 10 || a === 127 || a >= 224) return false;
|
|
11794
|
+
if (a === 100 && b >= 64 && b <= 127) return false;
|
|
11795
|
+
if (a === 169 && b === 254) return false;
|
|
11796
|
+
if (a === 172 && b >= 16 && b <= 31) return false;
|
|
11797
|
+
if (a === 192 && (b === 0 || b === 168)) return false;
|
|
11798
|
+
if (a === 192 && b === 88 && c === 99) return false;
|
|
11799
|
+
if (a === 198 && (b === 18 || b === 19 || b === 51 && c === 100)) return false;
|
|
11800
|
+
if (a === 203 && b === 0 && c === 113) return false;
|
|
11801
|
+
return true;
|
|
11802
|
+
}
|
|
11803
|
+
function ipv6IsPublic(address) {
|
|
11804
|
+
const bytes = parseIpv6(address);
|
|
11805
|
+
if (!bytes) return false;
|
|
11806
|
+
const allZero = bytes.every((byte) => byte === 0);
|
|
11807
|
+
if (allZero || bytes.slice(0, 15).every((byte) => byte === 0) && bytes[15] === 1) return false;
|
|
11808
|
+
if ((bytes[0] & 254) === 252 || bytes[0] === 254 && (bytes[1] & 192) === 128 || bytes[0] === 255) {
|
|
11809
|
+
return false;
|
|
11810
|
+
}
|
|
11811
|
+
if (bytes.slice(0, 12).every((byte) => byte === 0)) return false;
|
|
11812
|
+
if (prefixMatches(bytes, [32, 1, 0, 0], 32)) return false;
|
|
11813
|
+
if (prefixMatches(bytes, [32, 1, 0, 2, 0, 0], 48)) return false;
|
|
11814
|
+
if (prefixMatches(bytes, [32, 1, 13, 184], 32)) return false;
|
|
11815
|
+
if (prefixMatches(bytes, [32, 1, 0, 16], 28)) return false;
|
|
11816
|
+
if (prefixMatches(bytes, [0, 100, 255, 155, 0, 1], 48)) return false;
|
|
11817
|
+
if (prefixMatches(bytes, Array(10).fill(0).concat([255, 255]), 96)) {
|
|
11818
|
+
return ipv4IsPublic(bytes.slice(12).join("."));
|
|
11819
|
+
}
|
|
11820
|
+
if (prefixMatches(bytes, [0, 100, 255, 155].concat(Array(8).fill(0)), 96)) {
|
|
11821
|
+
return ipv4IsPublic(bytes.slice(12).join("."));
|
|
11822
|
+
}
|
|
11823
|
+
if (prefixMatches(bytes, [32, 2], 16)) {
|
|
11824
|
+
return ipv4IsPublic(bytes.slice(2, 6).join("."));
|
|
11825
|
+
}
|
|
11826
|
+
return true;
|
|
11827
|
+
}
|
|
11828
|
+
function isPublicNetworkAddress(address) {
|
|
11829
|
+
const family = isIP(address);
|
|
11830
|
+
return family === 4 ? ipv4IsPublic(address) : family === 6 ? ipv6IsPublic(address) : false;
|
|
11831
|
+
}
|
|
11832
|
+
async function defaultResolveAddresses(hostname3) {
|
|
11833
|
+
const family = isIP(hostname3);
|
|
11834
|
+
if (family) return [{ address: hostname3, family }];
|
|
11835
|
+
return dnsLookup(hostname3, { all: true, verbatim: true });
|
|
11836
|
+
}
|
|
11837
|
+
function parseProxyAuthority(authority) {
|
|
11838
|
+
let target;
|
|
11839
|
+
try {
|
|
11840
|
+
target = new URL(`http://${authority}`);
|
|
11841
|
+
} catch {
|
|
11842
|
+
throw brokerError("browser_session_proxy_target_invalid");
|
|
11843
|
+
}
|
|
11844
|
+
const port = Number(target.port || 443);
|
|
11845
|
+
if (!target.hostname || target.username || target.password || !Number.isInteger(port) || port < 1 || port > 65535) {
|
|
11846
|
+
throw brokerError("browser_session_proxy_target_invalid");
|
|
11847
|
+
}
|
|
11848
|
+
return { hostname: target.hostname, port };
|
|
11849
|
+
}
|
|
11850
|
+
async function resolvePublicAddress(hostname3, resolveAddresses) {
|
|
11851
|
+
if (isIP(hostname3) && !isPublicNetworkAddress(hostname3)) {
|
|
11852
|
+
throw brokerError("browser_session_private_network_request_blocked");
|
|
11853
|
+
}
|
|
11854
|
+
let answers;
|
|
11855
|
+
try {
|
|
11856
|
+
answers = await resolveAddresses(hostname3);
|
|
11857
|
+
} catch {
|
|
11858
|
+
throw brokerError("browser_session_dns_failed");
|
|
11859
|
+
}
|
|
11860
|
+
if (!Array.isArray(answers) || answers.length === 0 || answers.some((answer) => !isPublicNetworkAddress(answer?.address))) {
|
|
11861
|
+
throw brokerError("browser_session_private_network_request_blocked");
|
|
11862
|
+
}
|
|
11863
|
+
return answers[0];
|
|
11864
|
+
}
|
|
11865
|
+
async function startPublicNetworkProxy(resolveAddresses) {
|
|
11866
|
+
const sockets = /* @__PURE__ */ new Set();
|
|
11867
|
+
const trackSocket = (socket) => {
|
|
11868
|
+
sockets.add(socket);
|
|
11869
|
+
socket.once("close", () => sockets.delete(socket));
|
|
11870
|
+
socket.on("error", () => socket.destroy());
|
|
11871
|
+
};
|
|
11872
|
+
const server = createHttpServer((_request, response) => {
|
|
11873
|
+
response.writeHead(403, { "content-type": "text/plain" });
|
|
11874
|
+
response.end("browser_session_non_https_request_blocked");
|
|
11875
|
+
});
|
|
11876
|
+
server.on("connection", trackSocket);
|
|
11877
|
+
server.on("connect", async (request, clientSocket, head) => {
|
|
11878
|
+
try {
|
|
11879
|
+
const target = parseProxyAuthority(request.url ?? "");
|
|
11880
|
+
const resolved = await resolvePublicAddress(target.hostname, resolveAddresses);
|
|
11881
|
+
const upstream = connectTcp({
|
|
11882
|
+
host: resolved.address,
|
|
11883
|
+
family: resolved.family,
|
|
11884
|
+
port: target.port
|
|
11885
|
+
});
|
|
11886
|
+
trackSocket(upstream);
|
|
11887
|
+
upstream.once("connect", () => {
|
|
11888
|
+
clientSocket.write("HTTP/1.1 200 Connection Established\r\n\r\n");
|
|
11889
|
+
if (head.length) upstream.write(head);
|
|
11890
|
+
upstream.pipe(clientSocket);
|
|
11891
|
+
clientSocket.pipe(upstream);
|
|
11892
|
+
});
|
|
11893
|
+
upstream.once("error", () => clientSocket.destroy());
|
|
11894
|
+
} catch {
|
|
11895
|
+
clientSocket.end("HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n");
|
|
11896
|
+
}
|
|
11897
|
+
});
|
|
11898
|
+
await new Promise((resolveListen, reject) => {
|
|
11899
|
+
server.once("error", reject);
|
|
11900
|
+
server.listen(0, "127.0.0.1", () => {
|
|
11901
|
+
server.off("error", reject);
|
|
11902
|
+
resolveListen();
|
|
11903
|
+
});
|
|
11904
|
+
});
|
|
11905
|
+
const address = server.address();
|
|
11906
|
+
if (!address || typeof address === "string") {
|
|
11907
|
+
server.close();
|
|
11908
|
+
throw brokerError("browser_session_proxy_start_failed");
|
|
11909
|
+
}
|
|
11910
|
+
return {
|
|
11911
|
+
url: `http://127.0.0.1:${address.port}`,
|
|
11912
|
+
close: () => new Promise((resolveClose) => {
|
|
11913
|
+
for (const socket of sockets) socket.destroy();
|
|
11914
|
+
server.close(() => resolveClose());
|
|
11915
|
+
})
|
|
11916
|
+
};
|
|
11917
|
+
}
|
|
11918
|
+
async function installPublicHttpsPolicy(context, resolveAddresses) {
|
|
11919
|
+
if (typeof context.route !== "function") {
|
|
11920
|
+
throw brokerError("browser_session_public_https_policy_unavailable");
|
|
11921
|
+
}
|
|
11922
|
+
await context.route("**/*", async (route) => {
|
|
11923
|
+
try {
|
|
11924
|
+
const requestUrl = new URL(route.request().url());
|
|
11925
|
+
if (requestUrl.protocol !== "https:" || requestUrl.username || requestUrl.password) {
|
|
11926
|
+
throw brokerError("browser_session_non_https_request_blocked");
|
|
11927
|
+
}
|
|
11928
|
+
if (isIP(requestUrl.hostname) && !isPublicNetworkAddress(requestUrl.hostname)) {
|
|
11929
|
+
throw brokerError("browser_session_private_network_request_blocked");
|
|
11930
|
+
}
|
|
11931
|
+
const addresses = await resolveAddresses(requestUrl.hostname);
|
|
11932
|
+
if (!Array.isArray(addresses) || addresses.length === 0 || addresses.some((answer) => !isPublicNetworkAddress(answer?.address))) {
|
|
11933
|
+
throw brokerError("browser_session_private_network_request_blocked");
|
|
11934
|
+
}
|
|
11935
|
+
await route.continue();
|
|
11936
|
+
} catch {
|
|
11937
|
+
await route.abort("blockedbyclient");
|
|
11938
|
+
}
|
|
11939
|
+
});
|
|
11940
|
+
}
|
|
11601
11941
|
function pathWithin3(candidate, root) {
|
|
11602
11942
|
const value = relative6(root, candidate);
|
|
11603
11943
|
return value === "" || !value.startsWith("..") && !value.startsWith("/");
|
|
@@ -11739,10 +12079,57 @@ function createBrowserSessionBroker({
|
|
|
11739
12079
|
stateRoot,
|
|
11740
12080
|
browserExecutable,
|
|
11741
12081
|
chromium,
|
|
12082
|
+
resolveAddresses = defaultResolveAddresses,
|
|
12083
|
+
startNetworkProxy = () => startPublicNetworkProxy(resolveAddresses),
|
|
12084
|
+
scheduleTimeout = setTimeout,
|
|
12085
|
+
cancelTimeout = clearTimeout,
|
|
11742
12086
|
now = () => /* @__PURE__ */ new Date()
|
|
11743
12087
|
}) {
|
|
11744
12088
|
const active = /* @__PURE__ */ new Map();
|
|
11745
12089
|
const readers = /* @__PURE__ */ new Map();
|
|
12090
|
+
const terminated = [];
|
|
12091
|
+
function rememberTermination(lease, reason) {
|
|
12092
|
+
terminated.push({
|
|
12093
|
+
companyId: lease.owner.companyId,
|
|
12094
|
+
bindingId: lease.owner.bindingId,
|
|
12095
|
+
leaseId: lease.leaseId,
|
|
12096
|
+
reason,
|
|
12097
|
+
terminatedAt: now().toISOString()
|
|
12098
|
+
});
|
|
12099
|
+
if (terminated.length > TERMINATED_LEASE_HISTORY_LIMIT) terminated.shift();
|
|
12100
|
+
}
|
|
12101
|
+
async function closeHumanLease(localOpaqueRef, lease, reason = null) {
|
|
12102
|
+
if (lease.closePromise) return lease.closePromise;
|
|
12103
|
+
lease.closePromise = (async () => {
|
|
12104
|
+
if (lease.inactivityTimer) cancelTimeout(lease.inactivityTimer);
|
|
12105
|
+
if (lease.hardCapTimer) cancelTimeout(lease.hardCapTimer);
|
|
12106
|
+
if (active.get(localOpaqueRef) === lease) active.delete(localOpaqueRef);
|
|
12107
|
+
if (reason) rememberTermination(lease, reason);
|
|
12108
|
+
await Promise.allSettled([
|
|
12109
|
+
lease.context.close(),
|
|
12110
|
+
lease.networkProxy.close()
|
|
12111
|
+
]);
|
|
12112
|
+
})();
|
|
12113
|
+
return lease.closePromise;
|
|
12114
|
+
}
|
|
12115
|
+
function scheduleLeaseTimer(localOpaqueRef, lease, kind, delay, reason) {
|
|
12116
|
+
if (lease[kind]) cancelTimeout(lease[kind]);
|
|
12117
|
+
lease[kind] = scheduleTimeout(() => {
|
|
12118
|
+
if (active.get(localOpaqueRef) !== lease) return;
|
|
12119
|
+
void closeHumanLease(localOpaqueRef, lease, reason);
|
|
12120
|
+
}, Math.max(0, delay));
|
|
12121
|
+
lease[kind]?.unref?.();
|
|
12122
|
+
}
|
|
12123
|
+
function scheduleInactivity(localOpaqueRef, lease) {
|
|
12124
|
+
const lastActivityMs = Date.parse(lease.lastActivityAt);
|
|
12125
|
+
scheduleLeaseTimer(
|
|
12126
|
+
localOpaqueRef,
|
|
12127
|
+
lease,
|
|
12128
|
+
"inactivityTimer",
|
|
12129
|
+
lastActivityMs + HUMAN_LEASE_INACTIVITY_MS - now().getTime(),
|
|
12130
|
+
"browser_auth_human_lease_inactive"
|
|
12131
|
+
);
|
|
12132
|
+
}
|
|
11746
12133
|
async function open(payload, { replace = false } = {}) {
|
|
11747
12134
|
validateHttpsLocator(payload);
|
|
11748
12135
|
validateHumanLease(payload, now);
|
|
@@ -11762,38 +12149,97 @@ function createBrowserSessionBroker({
|
|
|
11762
12149
|
state: "human_ready"
|
|
11763
12150
|
};
|
|
11764
12151
|
}
|
|
11765
|
-
await existing
|
|
11766
|
-
active.delete(payload.localOpaqueRef);
|
|
12152
|
+
await closeHumanLease(payload.localOpaqueRef, existing);
|
|
11767
12153
|
}
|
|
11768
12154
|
if (!chromium || typeof chromium.launchPersistentContext !== "function") {
|
|
11769
12155
|
throw brokerError("browser_session_runtime_unavailable");
|
|
11770
12156
|
}
|
|
11771
|
-
const
|
|
11772
|
-
|
|
11773
|
-
|
|
11774
|
-
|
|
11775
|
-
|
|
12157
|
+
const networkProxy = await startNetworkProxy();
|
|
12158
|
+
let context;
|
|
12159
|
+
try {
|
|
12160
|
+
context = await chromium.launchPersistentContext(profilePath, {
|
|
12161
|
+
executablePath: browserExecutable,
|
|
12162
|
+
headless: false,
|
|
12163
|
+
acceptDownloads: false,
|
|
12164
|
+
proxy: { server: networkProxy.url }
|
|
12165
|
+
});
|
|
12166
|
+
} catch (error) {
|
|
12167
|
+
await networkProxy.close();
|
|
12168
|
+
throw error;
|
|
12169
|
+
}
|
|
12170
|
+
try {
|
|
12171
|
+
await installPublicHttpsPolicy(context, resolveAddresses);
|
|
12172
|
+
} catch (error) {
|
|
12173
|
+
await context.close();
|
|
12174
|
+
await networkProxy.close();
|
|
12175
|
+
throw error;
|
|
12176
|
+
}
|
|
11776
12177
|
const leaseState = {
|
|
11777
12178
|
context,
|
|
12179
|
+
networkProxy,
|
|
11778
12180
|
leaseId: payload.leaseId,
|
|
11779
12181
|
owner: expectedOwner(payload),
|
|
11780
|
-
|
|
12182
|
+
startedAt: now().toISOString(),
|
|
12183
|
+
lastActivityAt: now().toISOString(),
|
|
12184
|
+
activityToken: randomUUID(),
|
|
12185
|
+
inactivityTimer: null,
|
|
12186
|
+
hardCapTimer: null,
|
|
12187
|
+
closePromise: null
|
|
11781
12188
|
};
|
|
11782
|
-
|
|
11783
|
-
|
|
11784
|
-
|
|
11785
|
-
|
|
11786
|
-
|
|
11787
|
-
|
|
12189
|
+
try {
|
|
12190
|
+
if (typeof context.exposeBinding === "function" && typeof context.addInitScript === "function") {
|
|
12191
|
+
await context.exposeBinding("__mirrorxBrowserAuthActivity", (_source, activityToken) => {
|
|
12192
|
+
if (activityToken !== leaseState.activityToken) return;
|
|
12193
|
+
leaseState.lastActivityAt = now().toISOString();
|
|
12194
|
+
scheduleInactivity(payload.localOpaqueRef, leaseState);
|
|
11788
12195
|
});
|
|
11789
|
-
|
|
11790
|
-
|
|
11791
|
-
|
|
12196
|
+
await context.addInitScript(({ activityToken }) => {
|
|
12197
|
+
const reportActivity = globalThis.__mirrorxBrowserAuthActivity;
|
|
12198
|
+
try {
|
|
12199
|
+
delete globalThis.__mirrorxBrowserAuthActivity;
|
|
12200
|
+
} catch {
|
|
12201
|
+
}
|
|
12202
|
+
const report = (event) => {
|
|
12203
|
+
if (event.isTrusted !== true) return;
|
|
12204
|
+
reportActivity?.(activityToken).catch?.(() => {
|
|
12205
|
+
});
|
|
12206
|
+
};
|
|
12207
|
+
globalThis.addEventListener("pointerdown", report, { capture: true, passive: true });
|
|
12208
|
+
globalThis.addEventListener("keydown", report, { capture: true, passive: true });
|
|
12209
|
+
globalThis.addEventListener("touchstart", report, { capture: true, passive: true });
|
|
12210
|
+
}, { activityToken: leaseState.activityToken });
|
|
12211
|
+
}
|
|
12212
|
+
const page = context.pages()[0] ?? await context.newPage();
|
|
12213
|
+
if (typeof context.on !== "function" || typeof page.on !== "function") {
|
|
12214
|
+
throw brokerError("browser_session_lifecycle_monitor_unavailable");
|
|
12215
|
+
}
|
|
12216
|
+
const terminateFromBrowser = (reason) => {
|
|
12217
|
+
if (active.get(payload.localOpaqueRef) !== leaseState) return;
|
|
12218
|
+
void closeHumanLease(payload.localOpaqueRef, leaseState, reason);
|
|
12219
|
+
};
|
|
12220
|
+
context.on("close", () => terminateFromBrowser("browser_auth_human_session_closed"));
|
|
12221
|
+
context.on("page", (openedPage) => {
|
|
12222
|
+
if (openedPage !== page) void openedPage.close();
|
|
11792
12223
|
});
|
|
12224
|
+
page.on("close", () => terminateFromBrowser("browser_auth_human_session_closed"));
|
|
12225
|
+
page.on("crash", () => terminateFromBrowser("browser_auth_human_session_crashed"));
|
|
12226
|
+
page.on("download", (download) => {
|
|
12227
|
+
void download.cancel();
|
|
12228
|
+
});
|
|
12229
|
+
active.set(payload.localOpaqueRef, leaseState);
|
|
12230
|
+
await page.goto(payload.locator);
|
|
12231
|
+
} catch (error) {
|
|
12232
|
+
await closeHumanLease(payload.localOpaqueRef, leaseState);
|
|
12233
|
+
throw error;
|
|
11793
12234
|
}
|
|
11794
|
-
|
|
11795
|
-
|
|
11796
|
-
|
|
12235
|
+
scheduleInactivity(payload.localOpaqueRef, leaseState);
|
|
12236
|
+
scheduleLeaseTimer(
|
|
12237
|
+
payload.localOpaqueRef,
|
|
12238
|
+
leaseState,
|
|
12239
|
+
"hardCapTimer",
|
|
12240
|
+
Date.parse(leaseState.startedAt) + HUMAN_LEASE_HARD_CAP_MS - now().getTime(),
|
|
12241
|
+
"browser_auth_human_lease_hard_expired"
|
|
12242
|
+
);
|
|
11797
12243
|
return {
|
|
11798
12244
|
bindingId: payload.bindingId,
|
|
11799
12245
|
localOpaqueRef: payload.localOpaqueRef,
|
|
@@ -11809,8 +12255,7 @@ function createBrowserSessionBroker({
|
|
|
11809
12255
|
}
|
|
11810
12256
|
const profilePath = exactProfile(stateRoot, payload);
|
|
11811
12257
|
if (existing) {
|
|
11812
|
-
await existing
|
|
11813
|
-
active.delete(payload.localOpaqueRef);
|
|
12258
|
+
await closeHumanLease(payload.localOpaqueRef, existing);
|
|
11814
12259
|
}
|
|
11815
12260
|
rmSync7(profilePath, { recursive: true, force: false });
|
|
11816
12261
|
return {
|
|
@@ -11854,8 +12299,7 @@ function createBrowserSessionBroker({
|
|
|
11854
12299
|
if (human.owner.companyId !== payload.companyId || human.owner.bindingId !== payload.bindingId) {
|
|
11855
12300
|
throw brokerError("browser_session_profile_owner_mismatch");
|
|
11856
12301
|
}
|
|
11857
|
-
await human
|
|
11858
|
-
active.delete(payload.localOpaqueRef);
|
|
12302
|
+
await closeHumanLease(payload.localOpaqueRef, human);
|
|
11859
12303
|
}
|
|
11860
12304
|
readers.set(payload.localOpaqueRef, payload.leaseId);
|
|
11861
12305
|
return () => {
|
|
@@ -11870,15 +12314,154 @@ function createBrowserSessionBroker({
|
|
|
11870
12314
|
bindingId: entry.owner.bindingId,
|
|
11871
12315
|
leaseId: entry.leaseId,
|
|
11872
12316
|
lastActivityAt: entry.lastActivityAt
|
|
11873
|
-
}))
|
|
12317
|
+
})),
|
|
12318
|
+
terminatedHumanLeases: terminated.map((entry) => ({ ...entry }))
|
|
11874
12319
|
})
|
|
11875
12320
|
};
|
|
11876
12321
|
}
|
|
11877
12322
|
|
|
12323
|
+
// src/amaster-runtime-daemon/source-authentication-origin-discovery-ingest.mjs
|
|
12324
|
+
function asRecord2(value) {
|
|
12325
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
12326
|
+
}
|
|
12327
|
+
function readString2(value) {
|
|
12328
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
12329
|
+
}
|
|
12330
|
+
async function submitSourceAuthenticationOriginDiscovery({
|
|
12331
|
+
config,
|
|
12332
|
+
command,
|
|
12333
|
+
connectorId,
|
|
12334
|
+
profile,
|
|
12335
|
+
discoveries,
|
|
12336
|
+
postJsonWithRetry: postJsonWithRetry2,
|
|
12337
|
+
ingestLog: ingestLog2
|
|
12338
|
+
}) {
|
|
12339
|
+
if (profile.purpose !== "source_acquisition_v2" || discoveries.length !== 1) {
|
|
12340
|
+
throw new Error("source_authentication_origin_discovery_profile_inactive");
|
|
12341
|
+
}
|
|
12342
|
+
const discovery = asRecord2(discoveries[0]);
|
|
12343
|
+
const context = asRecord2(discovery.context);
|
|
12344
|
+
const receipt = asRecord2(discovery.receipt);
|
|
12345
|
+
if (context.companyId !== profile.companyId || context.sourceId !== profile.sourceId || context.sourceRevisionId !== profile.sourceRevisionId || context.attemptId !== profile.attemptId || context.epoch !== profile.epoch || context.connectorId !== connectorId || context.connectionEpoch !== profile.connectorAdmission.connectionEpoch || receipt.runId !== profile.runId) {
|
|
12346
|
+
throw new Error("source_authentication_origin_discovery_authority_invalid");
|
|
12347
|
+
}
|
|
12348
|
+
const accepted = asRecord2(await postJsonWithRetry2(
|
|
12349
|
+
config,
|
|
12350
|
+
`/api/amaster/runtime-connectors/${connectorId}/commands/${command.commandId}/source-acquisition/authentication-origin-discoveries`,
|
|
12351
|
+
{
|
|
12352
|
+
profileVersion: profile.purpose,
|
|
12353
|
+
attemptId: profile.attemptId,
|
|
12354
|
+
epoch: profile.epoch,
|
|
12355
|
+
receipt,
|
|
12356
|
+
receiptDigest: discovery.receiptDigest
|
|
12357
|
+
},
|
|
12358
|
+
{ maxAttempts: 3, timeoutMs: 5e3, delayMs: 100 }
|
|
12359
|
+
));
|
|
12360
|
+
if (accepted.status !== "auth_required" || accepted.attemptId !== profile.attemptId || !readString2(accepted.interactionId)) {
|
|
12361
|
+
throw new Error("source_authentication_origin_discovery_ingest_rejected");
|
|
12362
|
+
}
|
|
12363
|
+
await ingestLog2(
|
|
12364
|
+
config,
|
|
12365
|
+
command,
|
|
12366
|
+
"system",
|
|
12367
|
+
"info",
|
|
12368
|
+
"Source Authentication origin discovery recorded",
|
|
12369
|
+
{
|
|
12370
|
+
presentationKind: "source_authentication_origin_discovery",
|
|
12371
|
+
attemptId: profile.attemptId,
|
|
12372
|
+
interactionId: accepted.interactionId,
|
|
12373
|
+
discoveryId: receipt.discoveryId,
|
|
12374
|
+
sourceOrigin: receipt.sourceOrigin,
|
|
12375
|
+
targetOrigin: receipt.targetOrigin,
|
|
12376
|
+
replayed: accepted.replayed === true
|
|
12377
|
+
}
|
|
12378
|
+
);
|
|
12379
|
+
}
|
|
12380
|
+
|
|
12381
|
+
// src/amaster-runtime-daemon/source-completion-policy.mjs
|
|
12382
|
+
var SOURCE_COMPLETION_REPAIR_HARD_CAP_MS = 12e4;
|
|
12383
|
+
function record6(value) {
|
|
12384
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
12385
|
+
}
|
|
12386
|
+
function sourceCompletionActionAccepted(results) {
|
|
12387
|
+
return (Array.isArray(results) ? results : []).some((value) => {
|
|
12388
|
+
const result3 = record6(value);
|
|
12389
|
+
const runtimeAction = record6(result3.runtimeAction);
|
|
12390
|
+
return result3.status === "succeeded" && result3.providerStatus === "accepted" && runtimeAction.toolName === "runtime_action.submit" && typeof runtimeAction.callId === "string" && runtimeAction.callId.length > 0 && runtimeAction.resultStatus === "succeeded";
|
|
12391
|
+
});
|
|
12392
|
+
}
|
|
12393
|
+
function sourceCompletionTerminalFailure(stderr, profile) {
|
|
12394
|
+
if (!profile || profile.purpose !== "source_acquisition_v2") return null;
|
|
12395
|
+
for (const line of String(stderr ?? "").split(/\r?\n/u)) {
|
|
12396
|
+
const trimmed = line.trim();
|
|
12397
|
+
if (!trimmed.startsWith("{")) continue;
|
|
12398
|
+
try {
|
|
12399
|
+
const event = record6(JSON.parse(trimmed));
|
|
12400
|
+
if (event.type === "amaster_source_acquisition_terminal" && event.code === "source_acquisition_terminal_action_missing" && event.companyId === profile.companyId && event.sourceId === profile.sourceId && event.sourceRevisionId === profile.sourceRevisionId && event.attemptId === profile.attemptId && event.epoch === profile.epoch && event.runId === profile.runId) {
|
|
12401
|
+
return "source_acquisition_terminal_action_missing";
|
|
12402
|
+
}
|
|
12403
|
+
} catch {
|
|
12404
|
+
}
|
|
12405
|
+
}
|
|
12406
|
+
return null;
|
|
12407
|
+
}
|
|
12408
|
+
function createSourceCompletionStopPolicy({
|
|
12409
|
+
enabled,
|
|
12410
|
+
onStop,
|
|
12411
|
+
scheduleTimeout = setTimeout,
|
|
12412
|
+
cancelTimeout = clearTimeout,
|
|
12413
|
+
hardCapMs = SOURCE_COMPLETION_REPAIR_HARD_CAP_MS
|
|
12414
|
+
}) {
|
|
12415
|
+
let timer = null;
|
|
12416
|
+
let hardCapExceeded = false;
|
|
12417
|
+
let settled = false;
|
|
12418
|
+
function clear() {
|
|
12419
|
+
if (timer) cancelTimeout(timer);
|
|
12420
|
+
timer = null;
|
|
12421
|
+
}
|
|
12422
|
+
return {
|
|
12423
|
+
observe(eventType) {
|
|
12424
|
+
if (!enabled || settled) return { handled: false };
|
|
12425
|
+
if (eventType === "agent_end") {
|
|
12426
|
+
if (!timer) {
|
|
12427
|
+
timer = scheduleTimeout(() => {
|
|
12428
|
+
if (settled) return;
|
|
12429
|
+
hardCapExceeded = true;
|
|
12430
|
+
onStop("source_completion_hard_cap");
|
|
12431
|
+
}, hardCapMs);
|
|
12432
|
+
timer?.unref?.();
|
|
12433
|
+
}
|
|
12434
|
+
return { handled: true, completionOutputType: null };
|
|
12435
|
+
}
|
|
12436
|
+
if (eventType === "agent_settled") {
|
|
12437
|
+
settled = true;
|
|
12438
|
+
clear();
|
|
12439
|
+
onStop("completion_output");
|
|
12440
|
+
return { handled: true, completionOutputType: "agent_settled" };
|
|
12441
|
+
}
|
|
12442
|
+
return { handled: false };
|
|
12443
|
+
},
|
|
12444
|
+
close: clear,
|
|
12445
|
+
get hardCapExceeded() {
|
|
12446
|
+
return hardCapExceeded;
|
|
12447
|
+
}
|
|
12448
|
+
};
|
|
12449
|
+
}
|
|
12450
|
+
|
|
11878
12451
|
// ../shared/src/source-acquisition-compatibility.json
|
|
11879
12452
|
var source_acquisition_compatibility_default = {
|
|
11880
12453
|
schemaVersion: "mirrorx.source-acquisition-compatibility.v1",
|
|
11881
12454
|
profileVersion: "source_acquisition_v1",
|
|
12455
|
+
supportedProfileVersions: [
|
|
12456
|
+
"source_acquisition_v1",
|
|
12457
|
+
"source_acquisition_v2"
|
|
12458
|
+
],
|
|
12459
|
+
v2Activation: {
|
|
12460
|
+
profileVersion: "source_acquisition_v2",
|
|
12461
|
+
capability: "source_authentication_origin_discovery_v1",
|
|
12462
|
+
piCodingAgentVersion: "0.80.10",
|
|
12463
|
+
completionGuard: "source_completion_same_session_v1"
|
|
12464
|
+
},
|
|
11882
12465
|
retentionVersion: "source_summary_only_v1",
|
|
11883
12466
|
actionVersion: "complete_source_acquisition_v1",
|
|
11884
12467
|
policyVersion: "browser_read_policy_v1",
|
|
@@ -11891,7 +12474,7 @@ var source_acquisition_compatibility_default = {
|
|
|
11891
12474
|
};
|
|
11892
12475
|
|
|
11893
12476
|
// src/amaster-runtime-daemon.mjs
|
|
11894
|
-
var CONNECTOR_VERSION = "0.1.1-beta.
|
|
12477
|
+
var CONNECTOR_VERSION = "0.1.1-beta.104";
|
|
11895
12478
|
var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
|
|
11896
12479
|
var SOURCE_ACQUISITION_CAPABILITY = source_acquisition_compatibility_default.profileVersion;
|
|
11897
12480
|
var daemonRequire = createRequire(import.meta.url);
|
|
@@ -11901,6 +12484,10 @@ var SOURCE_ACQUISITION_ACTION_VERSION = source_acquisition_compatibility_default
|
|
|
11901
12484
|
var SOURCE_ACQUISITION_BROWSER_POLICY_VERSION = source_acquisition_compatibility_default.policyVersion;
|
|
11902
12485
|
var SOURCE_ACQUISITION_HEADLESS_ADAPTER = source_acquisition_compatibility_default.adapters[0];
|
|
11903
12486
|
var SOURCE_ACQUISITION_DESKTOP_ADAPTER = "browser_skill_desktop_v1";
|
|
12487
|
+
var SOURCE_ACQUISITION_PROFILE_VERSION_V2 = source_acquisition_compatibility_default.v2Activation.profileVersion;
|
|
12488
|
+
var SOURCE_AUTHENTICATION_ORIGIN_DISCOVERY_CAPABILITY = source_acquisition_compatibility_default.v2Activation.capability;
|
|
12489
|
+
var SOURCE_ACQUISITION_V2_PI_VERSION = source_acquisition_compatibility_default.v2Activation.piCodingAgentVersion;
|
|
12490
|
+
var SOURCE_ACQUISITION_V2_COMPLETION_GUARD = source_acquisition_compatibility_default.v2Activation.completionGuard;
|
|
11904
12491
|
var SOURCE_ACQUISITION_PACKAGE_VERSIONS = Object.freeze(
|
|
11905
12492
|
source_acquisition_compatibility_default.requiredPackages
|
|
11906
12493
|
);
|
|
@@ -12370,6 +12957,70 @@ function sourceAcquisitionBrowserExecutableReady() {
|
|
|
12370
12957
|
return false;
|
|
12371
12958
|
}
|
|
12372
12959
|
}
|
|
12960
|
+
function sourceAcquisitionV2Cohort(extensionDigest) {
|
|
12961
|
+
const names = [
|
|
12962
|
+
"AMASTER_SOURCE_ACQUISITION_SUPPORTED_PROFILE_VERSIONS",
|
|
12963
|
+
"AMASTER_SOURCE_ACQUISITION_AUTHENTICATION_ORIGIN_DISCOVERY_CAPABILITY",
|
|
12964
|
+
"AMASTER_SOURCE_ACQUISITION_COMPLETION_GUARD",
|
|
12965
|
+
"AMASTER_SOURCE_ACQUISITION_CAPABILITY_DIGEST",
|
|
12966
|
+
"AMASTER_SOURCE_ACQUISITION_RUNTIME_BUILD_COMMIT",
|
|
12967
|
+
"AMASTER_SOURCE_ACQUISITION_SOURCE_EXTENSION_DIGEST",
|
|
12968
|
+
"AMASTER_SOURCE_ACQUISITION_PI_CODING_AGENT_VERSION",
|
|
12969
|
+
"AMASTER_SOURCE_ACQUISITION_PI_CODING_AGENT_DIGEST"
|
|
12970
|
+
];
|
|
12971
|
+
if (names.every((name) => !readString(process.env[name]))) return null;
|
|
12972
|
+
const incompatible = (reason) => ({ state: "incompatible", reason });
|
|
12973
|
+
const piMetadata = sourceAcquisitionPackageMetadata("@earendil-works/pi-coding-agent");
|
|
12974
|
+
const piVersion = readString(process.env.AMASTER_SOURCE_ACQUISITION_PI_CODING_AGENT_VERSION);
|
|
12975
|
+
const piDigest = readString(process.env.AMASTER_SOURCE_ACQUISITION_PI_CODING_AGENT_DIGEST);
|
|
12976
|
+
const sourceExtensionDigest = readString(process.env.AMASTER_SOURCE_ACQUISITION_SOURCE_EXTENSION_DIGEST);
|
|
12977
|
+
const runtimeBuildCommit = readString(process.env.AMASTER_SOURCE_ACQUISITION_RUNTIME_BUILD_COMMIT);
|
|
12978
|
+
const deploymentImageDigest = readString(process.env.AMASTER_DEPLOYMENT_IMAGE_DIGEST);
|
|
12979
|
+
const capabilityDigest = readString(process.env.AMASTER_SOURCE_ACQUISITION_CAPABILITY_DIGEST);
|
|
12980
|
+
if (readString(process.env.AMASTER_SOURCE_ACQUISITION_SUPPORTED_PROFILE_VERSIONS) !== source_acquisition_compatibility_default.supportedProfileVersions.join(",") || readString(process.env.AMASTER_SOURCE_ACQUISITION_AUTHENTICATION_ORIGIN_DISCOVERY_CAPABILITY) !== SOURCE_AUTHENTICATION_ORIGIN_DISCOVERY_CAPABILITY || readString(process.env.AMASTER_SOURCE_ACQUISITION_COMPLETION_GUARD) !== SOURCE_ACQUISITION_V2_COMPLETION_GUARD) return incompatible("source_acquisition_v2_capability_mismatch");
|
|
12981
|
+
if (piVersion !== SOURCE_ACQUISITION_V2_PI_VERSION || readString(piMetadata?.version) !== piVersion) {
|
|
12982
|
+
return incompatible("source_acquisition_v2_pi_version_mismatch");
|
|
12983
|
+
}
|
|
12984
|
+
if (!piDigest || !/^[a-f0-9]{64}$/u.test(piDigest)) {
|
|
12985
|
+
return incompatible("source_acquisition_v2_pi_digest_invalid");
|
|
12986
|
+
}
|
|
12987
|
+
if (sourceExtensionDigest !== `sha256:${extensionDigest}`) {
|
|
12988
|
+
return incompatible("source_acquisition_v2_extension_digest_mismatch");
|
|
12989
|
+
}
|
|
12990
|
+
if (!runtimeBuildCommit || !/^[a-f0-9]{40}$/u.test(runtimeBuildCommit)) {
|
|
12991
|
+
return incompatible("source_acquisition_v2_build_commit_invalid");
|
|
12992
|
+
}
|
|
12993
|
+
if (!deploymentImageDigest || !/^sha256:[a-f0-9]{64}$/u.test(deploymentImageDigest)) {
|
|
12994
|
+
return incompatible("source_acquisition_v2_image_digest_invalid");
|
|
12995
|
+
}
|
|
12996
|
+
const runtimeIdentity = {
|
|
12997
|
+
sourceProfileVersion: SOURCE_ACQUISITION_PROFILE_VERSION_V2,
|
|
12998
|
+
piCodingAgentVersion: SOURCE_ACQUISITION_V2_PI_VERSION,
|
|
12999
|
+
supportsAgentSettled: true,
|
|
13000
|
+
supportsSameSessionFollowUp: true,
|
|
13001
|
+
completionRepairHardCapSeconds: 120,
|
|
13002
|
+
sourceExtensionDigest,
|
|
13003
|
+
runtimeBuildCommit
|
|
13004
|
+
};
|
|
13005
|
+
const expectedCapabilityDigest = `sha256:${serializeSourceAcquisitionProfile(runtimeIdentity).sha256}`;
|
|
13006
|
+
if (capabilityDigest !== expectedCapabilityDigest) {
|
|
13007
|
+
return incompatible("source_acquisition_v2_capability_digest_mismatch");
|
|
13008
|
+
}
|
|
13009
|
+
return {
|
|
13010
|
+
state: "ready",
|
|
13011
|
+
proof: {
|
|
13012
|
+
supportedProfileVersions: [...source_acquisition_compatibility_default.supportedProfileVersions],
|
|
13013
|
+
profileVersion: SOURCE_ACQUISITION_PROFILE_VERSION_V2,
|
|
13014
|
+
capability: SOURCE_AUTHENTICATION_ORIGIN_DISCOVERY_CAPABILITY,
|
|
13015
|
+
piCodingAgent: { version: piVersion, digest: piDigest },
|
|
13016
|
+
sourceExtensionDigest,
|
|
13017
|
+
runtimeBuildCommit,
|
|
13018
|
+
deploymentImageDigest,
|
|
13019
|
+
completionGuard: SOURCE_ACQUISITION_V2_COMPLETION_GUARD,
|
|
13020
|
+
capabilityDigest
|
|
13021
|
+
}
|
|
13022
|
+
};
|
|
13023
|
+
}
|
|
12373
13024
|
function sourceAcquisitionRuntimeReadiness(config) {
|
|
12374
13025
|
const unavailable = (reason) => ({ ready: false, reason });
|
|
12375
13026
|
const piExecutor = config.executors.find((executor) => executor.kind === "pi");
|
|
@@ -12392,13 +13043,22 @@ function sourceAcquisitionRuntimeReadiness(config) {
|
|
|
12392
13043
|
}
|
|
12393
13044
|
let browserSkill;
|
|
12394
13045
|
if (adapters.includes(SOURCE_ACQUISITION_DESKTOP_ADAPTER)) {
|
|
13046
|
+
const authenticationOriginDiscoveryCapability = readString(
|
|
13047
|
+
process.env.AMASTER_SOURCE_ACQUISITION_BROWSER_SKILL_AUTHENTICATION_ORIGIN_DISCOVERY_CAPABILITY
|
|
13048
|
+
);
|
|
13049
|
+
if (authenticationOriginDiscoveryCapability && authenticationOriginDiscoveryCapability !== SOURCE_AUTHENTICATION_ORIGIN_DISCOVERY_CAPABILITY) {
|
|
13050
|
+
return unavailable("source_acquisition_browser_skill_discovery_attestation_invalid");
|
|
13051
|
+
}
|
|
12395
13052
|
browserSkill = {
|
|
12396
13053
|
runtimeVersion: readString(process.env.AMASTER_SOURCE_ACQUISITION_BROWSER_SKILL_RUNTIME_VERSION),
|
|
12397
13054
|
runtimeDigest: readString(process.env.AMASTER_SOURCE_ACQUISITION_BROWSER_SKILL_RUNTIME_DIGEST),
|
|
12398
13055
|
assetVersion: readString(process.env.AMASTER_SOURCE_ACQUISITION_BROWSER_SKILL_ASSET_VERSION),
|
|
12399
13056
|
assetDigest: readString(process.env.AMASTER_SOURCE_ACQUISITION_BROWSER_SKILL_ASSET_DIGEST),
|
|
12400
13057
|
policyVersion: SOURCE_ACQUISITION_BROWSER_POLICY_VERSION,
|
|
12401
|
-
policyDigest: readString(process.env.AMASTER_SOURCE_ACQUISITION_BROWSER_SKILL_POLICY_DIGEST)
|
|
13058
|
+
policyDigest: readString(process.env.AMASTER_SOURCE_ACQUISITION_BROWSER_SKILL_POLICY_DIGEST),
|
|
13059
|
+
...authenticationOriginDiscoveryCapability ? {
|
|
13060
|
+
authenticationOriginDiscoveryCapability
|
|
13061
|
+
} : {}
|
|
12402
13062
|
};
|
|
12403
13063
|
if (!browserSkill.runtimeVersion || !browserSkill.assetVersion || !/^[a-f0-9]{64}$/u.test(browserSkill.runtimeDigest ?? "") || !/^[a-f0-9]{64}$/u.test(browserSkill.assetDigest ?? "") || !/^[a-f0-9]{64}$/u.test(browserSkill.policyDigest ?? "")) {
|
|
12404
13064
|
return unavailable("source_acquisition_browser_skill_attestation_invalid");
|
|
@@ -12423,6 +13083,7 @@ function sourceAcquisitionRuntimeReadiness(config) {
|
|
|
12423
13083
|
}
|
|
12424
13084
|
packages.push({ name, version, digest });
|
|
12425
13085
|
}
|
|
13086
|
+
const v2Cohort = sourceAcquisitionV2Cohort(extensionDigest);
|
|
12426
13087
|
return {
|
|
12427
13088
|
ready: true,
|
|
12428
13089
|
profileVersion: SOURCE_ACQUISITION_PROFILE_VERSION,
|
|
@@ -12435,7 +13096,8 @@ function sourceAcquisitionRuntimeReadiness(config) {
|
|
|
12435
13096
|
version: CONNECTOR_VERSION,
|
|
12436
13097
|
digest: connectorDigest
|
|
12437
13098
|
},
|
|
12438
|
-
packages
|
|
13099
|
+
packages,
|
|
13100
|
+
...v2Cohort ? { v2Cohort } : {}
|
|
12439
13101
|
};
|
|
12440
13102
|
}
|
|
12441
13103
|
function browserSessionRuntimeReadiness(config) {
|
|
@@ -13142,41 +13804,14 @@ function commandTrustedPiRuntimeAssertion(command) {
|
|
|
13142
13804
|
function commandSourceAcquisitionProfile(command) {
|
|
13143
13805
|
return asRecord(asRecord(asRecord(command.payload).sourceAcquisition).profile);
|
|
13144
13806
|
}
|
|
13145
|
-
function sourceAcquisitionExactOrigin(value) {
|
|
13146
|
-
const locator = readString(value);
|
|
13147
|
-
let url;
|
|
13148
|
-
try {
|
|
13149
|
-
url = new URL(locator ?? "");
|
|
13150
|
-
} catch {
|
|
13151
|
-
throw Object.assign(new Error("source_acquisition_profile_invalid"), {
|
|
13152
|
-
code: "source_acquisition_profile_invalid"
|
|
13153
|
-
});
|
|
13154
|
-
}
|
|
13155
|
-
if (url.protocol !== "https:" || url.username || url.password) {
|
|
13156
|
-
throw Object.assign(new Error("source_acquisition_profile_invalid"), {
|
|
13157
|
-
code: "source_acquisition_profile_invalid"
|
|
13158
|
-
});
|
|
13159
|
-
}
|
|
13160
|
-
return url.origin;
|
|
13161
|
-
}
|
|
13162
13807
|
async function sourceAcquisitionRuntimeProfile(config, command) {
|
|
13163
13808
|
const profile = commandSourceAcquisitionProfile(command);
|
|
13164
13809
|
if (Object.keys(profile).length === 0) return null;
|
|
13165
13810
|
const access = asRecord(profile.access);
|
|
13166
|
-
const
|
|
13167
|
-
const tools = asRecord(profile.tools);
|
|
13168
|
-
if (profile.purpose !== "source_acquisition_v1" || profile.retention !== "source_summary_only_v1" || readString(profile.runId) !== commandRunId(command) || !Array.isArray(tools.exactAllowlist) || tools.exactAllowlist.length === 0 || !["public", "authenticated"].includes(access.mode) || !["isolated", "existing"].includes(transport.browserMode) || ![SOURCE_ACQUISITION_HEADLESS_ADAPTER, SOURCE_ACQUISITION_DESKTOP_ADAPTER].includes(transport.adapter)) {
|
|
13169
|
-
throw new Error("source_acquisition_profile_invalid");
|
|
13170
|
-
}
|
|
13811
|
+
const inspection = inspectSourceAcquisitionProfile(profile, commandRunId(command));
|
|
13171
13812
|
if (access.mode === "public") {
|
|
13172
|
-
if (transport.browserMode !== "isolated" || transport.adapter !== SOURCE_ACQUISITION_HEADLESS_ADAPTER) {
|
|
13173
|
-
throw new Error("source_acquisition_profile_invalid");
|
|
13174
|
-
}
|
|
13175
13813
|
return { profile };
|
|
13176
13814
|
}
|
|
13177
|
-
if (transport.browserMode !== "existing" || transport.adapter !== SOURCE_ACQUISITION_DESKTOP_ADAPTER) {
|
|
13178
|
-
throw new Error("source_acquisition_profile_invalid");
|
|
13179
|
-
}
|
|
13180
13815
|
const companyId = readString(profile.companyId);
|
|
13181
13816
|
const bindingId = readString(access.browserBindingId);
|
|
13182
13817
|
const localOpaqueRef = readString(access.localOpaqueRef);
|
|
@@ -13185,7 +13820,6 @@ async function sourceAcquisitionRuntimeProfile(config, command) {
|
|
|
13185
13820
|
if (!companyId || !bindingId || !/^profile_[a-z0-9]{16,64}$/i.test(localOpaqueRef ?? "") || !browserLeaseId || !browserLeaseExpiresAt || Date.parse(browserLeaseExpiresAt) <= Date.now()) {
|
|
13186
13821
|
throw new Error("source_acquisition_profile_invalid");
|
|
13187
13822
|
}
|
|
13188
|
-
const exactOrigin = sourceAcquisitionExactOrigin(access.exactLocator);
|
|
13189
13823
|
const profileName2 = createHash14("sha256").update(`${companyId}\0${bindingId}\0${localOpaqueRef}`).digest("hex");
|
|
13190
13824
|
const stateRoot = resolve11(config.browserSessionStateRoot);
|
|
13191
13825
|
const userDataDir = resolve11(stateRoot, profileName2);
|
|
@@ -13193,7 +13827,7 @@ async function sourceAcquisitionRuntimeProfile(config, command) {
|
|
|
13193
13827
|
const markerPath = join15(userDataDir, ".amaster-browser-session.json");
|
|
13194
13828
|
if (!existsSync14(userDataDir) || lstatSync7(userDataDir).isSymbolicLink() || !lstatSync7(userDataDir).isDirectory() || !existsSync14(markerPath) || lstatSync7(markerPath).isSymbolicLink()) throw new Error("source_acquisition_browser_profile_invalid");
|
|
13195
13829
|
const marker = readJsonFile2(markerPath);
|
|
13196
|
-
if (marker.version !== 1 || marker.companyId !== companyId || marker.bindingId !== bindingId || marker.localOpaqueRef !== localOpaqueRef || !readString(marker.provider) || marker.origin
|
|
13830
|
+
if (marker.version !== 1 || marker.companyId !== companyId || marker.bindingId !== bindingId || marker.localOpaqueRef !== localOpaqueRef || !readString(marker.provider) || !inspection.sourceOrigins.includes(marker.origin) || Object.keys(marker).length !== 6) {
|
|
13197
13831
|
throw new Error("source_acquisition_browser_profile_invalid");
|
|
13198
13832
|
}
|
|
13199
13833
|
const releaseBrowserLease = await browserSessionBrokerFor(config).acquireAgentRead({
|
|
@@ -13822,9 +14456,11 @@ function createLiveOutputLogger(config, command, executorKind, protectedValues =
|
|
|
13822
14456
|
const liveMcpToolResults = [];
|
|
13823
14457
|
const sourceRetention = options.sourceRetention === true;
|
|
13824
14458
|
const onSourceObservations = typeof options.onSourceObservations === "function" ? options.onSourceObservations : null;
|
|
14459
|
+
const onSourceAuthenticationOriginDiscoveries = typeof options.onSourceAuthenticationOriginDiscoveries === "function" ? options.onSourceAuthenticationOriginDiscoveries : null;
|
|
13825
14460
|
let queue = Promise.resolve();
|
|
13826
14461
|
let observationQueue = Promise.resolve();
|
|
13827
14462
|
let observationError = null;
|
|
14463
|
+
let authenticationDiscoverySeen = false;
|
|
13828
14464
|
const piToolArgumentTracker = executorKind === "pi" ? createPiToolArgumentAmplificationTracker(options.piToolArgumentGuard) : null;
|
|
13829
14465
|
const maxEntriesPerStream = parsePositiveInteger(process.env.AMASTER_RUNTIME_LIVE_LOG_MAX_ENTRIES_PER_STREAM, 200);
|
|
13830
14466
|
const countEventType = (event) => {
|
|
@@ -13906,6 +14542,7 @@ function createLiveOutputLogger(config, command, executorKind, protectedValues =
|
|
|
13906
14542
|
const text = redactProtectedText(line, protectedValues).trim();
|
|
13907
14543
|
if (!text) return;
|
|
13908
14544
|
const event = stream === "stdout" ? parseJsonLine(text) : null;
|
|
14545
|
+
const sourceControlEvent = parseJsonLine(text);
|
|
13909
14546
|
const argumentAmplificationStop = stream === "stdout" ? piToolArgumentTracker?.record(event) ?? null : null;
|
|
13910
14547
|
const eventType = readString(asRecord(event).type);
|
|
13911
14548
|
if (executorKind === "pi" && eventType === "session") {
|
|
@@ -13939,6 +14576,24 @@ function createLiveOutputLogger(config, command, executorKind, protectedValues =
|
|
|
13939
14576
|
});
|
|
13940
14577
|
}
|
|
13941
14578
|
}
|
|
14579
|
+
if (sourceRetention && executorKind === "pi" && sourceControlEvent && onSourceAuthenticationOriginDiscoveries) {
|
|
14580
|
+
const discoveries = piSourceAuthenticationOriginDiscoveries(sourceControlEvent);
|
|
14581
|
+
if (discoveries.length > 0) {
|
|
14582
|
+
if (authenticationDiscoverySeen) {
|
|
14583
|
+
observationError ??= new Error("source_authentication_origin_discovery_duplicate");
|
|
14584
|
+
} else {
|
|
14585
|
+
authenticationDiscoverySeen = true;
|
|
14586
|
+
observationQueue = observationQueue.then(async () => {
|
|
14587
|
+
if (observationError) return;
|
|
14588
|
+
try {
|
|
14589
|
+
await onSourceAuthenticationOriginDiscoveries(discoveries);
|
|
14590
|
+
} catch (error) {
|
|
14591
|
+
observationError = error;
|
|
14592
|
+
}
|
|
14593
|
+
});
|
|
14594
|
+
}
|
|
14595
|
+
}
|
|
14596
|
+
}
|
|
13942
14597
|
let entry = null;
|
|
13943
14598
|
if (event && shouldPreserveExecutorJsonlForTranscript(executorKind, event)) {
|
|
13944
14599
|
entry = {
|
|
@@ -14414,6 +15069,7 @@ function runExecutor(command, args, options) {
|
|
|
14414
15069
|
if (quiescenceTimer) clearTimeout(quiescenceTimer);
|
|
14415
15070
|
if (stoppedResidentTimer) clearTimeout(stoppedResidentTimer);
|
|
14416
15071
|
if (completionOutputDrainTimer) clearTimeout(completionOutputDrainTimer);
|
|
15072
|
+
sourceCompletionStopPolicy.close();
|
|
14417
15073
|
options.signal?.removeEventListener?.("abort", abort);
|
|
14418
15074
|
resolveRun({
|
|
14419
15075
|
stdout,
|
|
@@ -14426,6 +15082,7 @@ function runExecutor(command, args, options) {
|
|
|
14426
15082
|
memoryLimit,
|
|
14427
15083
|
completionOutputType,
|
|
14428
15084
|
completionOutputHasFinalAssistantText,
|
|
15085
|
+
sourceCompletionHardCapExceeded: sourceCompletionStopPolicy.hardCapExceeded,
|
|
14429
15086
|
killedWorkspaceResidents,
|
|
14430
15087
|
...outputDrainForcedClosed ? { outputDrainForcedClosed: true } : {},
|
|
14431
15088
|
...result3
|
|
@@ -14441,6 +15098,10 @@ function runExecutor(command, args, options) {
|
|
|
14441
15098
|
signalExecutorProcess(child, "SIGTERM", processGroupId);
|
|
14442
15099
|
scheduleStopKill();
|
|
14443
15100
|
};
|
|
15101
|
+
const sourceCompletionStopPolicy = createSourceCompletionStopPolicy({
|
|
15102
|
+
enabled: options.sourceCompletionGuard === true,
|
|
15103
|
+
onStop: requestStop
|
|
15104
|
+
});
|
|
14444
15105
|
deliverSourceAcquisitionManagedInputs(child, managedInputs, (code, error) => {
|
|
14445
15106
|
spawnError = `${code}_delivery_failed: ${error.message}`;
|
|
14446
15107
|
requestStop(`${code}_delivery_failed`);
|
|
@@ -14522,6 +15183,15 @@ function runExecutor(command, args, options) {
|
|
|
14522
15183
|
if (!trimmed.startsWith("{")) continue;
|
|
14523
15184
|
try {
|
|
14524
15185
|
const event = JSON.parse(trimmed);
|
|
15186
|
+
const eventType = readString(asRecord(event).type);
|
|
15187
|
+
const sourceStop = sourceCompletionStopPolicy.observe(eventType);
|
|
15188
|
+
if (sourceStop.handled) {
|
|
15189
|
+
if (sourceStop.completionOutputType) {
|
|
15190
|
+
completionOutputType = sourceStop.completionOutputType;
|
|
15191
|
+
return;
|
|
15192
|
+
}
|
|
15193
|
+
continue;
|
|
15194
|
+
}
|
|
14525
15195
|
const stopType = piCompletionOutputType(event);
|
|
14526
15196
|
if (stopType) {
|
|
14527
15197
|
completionOutputType = stopType;
|
|
@@ -14705,6 +15375,17 @@ async function ingestSourceAcquisitionObservations(config, command, profile, rec
|
|
|
14705
15375
|
);
|
|
14706
15376
|
}
|
|
14707
15377
|
}
|
|
15378
|
+
async function ingestSourceAuthenticationOriginDiscoveries(config, command, profile, discoveries) {
|
|
15379
|
+
await submitSourceAuthenticationOriginDiscovery({
|
|
15380
|
+
config,
|
|
15381
|
+
command,
|
|
15382
|
+
connectorId: requireConnectorId(config),
|
|
15383
|
+
profile,
|
|
15384
|
+
discoveries,
|
|
15385
|
+
postJsonWithRetry,
|
|
15386
|
+
ingestLog
|
|
15387
|
+
});
|
|
15388
|
+
}
|
|
14708
15389
|
function parsedUsageCostCents(usage) {
|
|
14709
15390
|
const costUsd = readNumber(asRecord(usage).costUsd, 0);
|
|
14710
15391
|
if (!Number.isFinite(costUsd) || costUsd <= 0) return 0;
|
|
@@ -16836,6 +17517,7 @@ async function executeRunCommand(config, command) {
|
|
|
16836
17517
|
const protectedExecutorValues = managedMcpProfile?.protectedValues ?? providerProtectedValues;
|
|
16837
17518
|
const runtimeArtifacts = [];
|
|
16838
17519
|
const runtimeDocuments = [];
|
|
17520
|
+
let sourceAuthenticationDiscoveryAccepted = false;
|
|
16839
17521
|
const runtimeArtifactIngest = createRuntimeArtifactIngestQueue({
|
|
16840
17522
|
ingest: (results) => ingestRuntimeArtifacts(config, command, cwd, results)
|
|
16841
17523
|
});
|
|
@@ -16860,7 +17542,15 @@ async function executeRunCommand(config, command) {
|
|
|
16860
17542
|
command,
|
|
16861
17543
|
sourceAcquisition.profile,
|
|
16862
17544
|
receipts
|
|
16863
|
-
)
|
|
17545
|
+
),
|
|
17546
|
+
onSourceAuthenticationOriginDiscoveries: (discoveries) => ingestSourceAuthenticationOriginDiscoveries(
|
|
17547
|
+
config,
|
|
17548
|
+
command,
|
|
17549
|
+
sourceAcquisition.profile,
|
|
17550
|
+
discoveries
|
|
17551
|
+
).then(() => {
|
|
17552
|
+
sourceAuthenticationDiscoveryAccepted = true;
|
|
17553
|
+
})
|
|
16864
17554
|
} : {}
|
|
16865
17555
|
}
|
|
16866
17556
|
);
|
|
@@ -16875,6 +17565,7 @@ async function executeRunCommand(config, command) {
|
|
|
16875
17565
|
maxRssMb: config.executorMaxRssMb,
|
|
16876
17566
|
signal: abortController.signal,
|
|
16877
17567
|
executorKind: executor.kind,
|
|
17568
|
+
sourceCompletionGuard: executor.kind === "pi" && sourceAcquisition?.profile?.purpose === SOURCE_ACQUISITION_PROFILE_VERSION_V2,
|
|
16878
17569
|
...piExecutorIdentity ? { spawnIdentity: piExecutorIdentity } : {},
|
|
16879
17570
|
...sourceProfile ? { sourceProfileInput: sourceProfile.input } : {},
|
|
16880
17571
|
onOutput: (stream, chunk, rawBytes) => {
|
|
@@ -17100,11 +17791,14 @@ async function executeRunCommand(config, command) {
|
|
|
17100
17791
|
}
|
|
17101
17792
|
}
|
|
17102
17793
|
const cancelled = execution.cancelled === true;
|
|
17794
|
+
const sourceCompletionGuard = executor.kind === "pi" && sourceAcquisition?.profile?.purpose === SOURCE_ACQUISITION_PROFILE_VERSION_V2;
|
|
17795
|
+
const sourceCompletionOutputStopped = sourceCompletionGuard && execution.completionOutputType === "agent_settled" && piCompletionCleanupStopped(execution);
|
|
17796
|
+
const sourceCompletionFailure = sourceCompletionGuard && !sourceAuthenticationDiscoveryAccepted && (execution.sourceCompletionHardCapExceeded === true || sourceCompletionTerminalFailure(execution.stderr, sourceAcquisition.profile) || !sourceCompletionActionAccepted(mcpToolResults)) ? "source_acquisition_terminal_action_missing" : null;
|
|
17103
17797
|
const outputFloodError = hasOutputFlood ? `${executor.kind === "pi" ? "Pi Agent" : "Executor"} output flood: ${outputFlood.stream} exceeded ${readNumber(outputFlood.limitBytes, 0)} bytes` : null;
|
|
17104
17798
|
const argumentAmplificationError = hasArgumentAmplification ? `Pi Agent tool argument stream amplification stopped before execution: ${readNumber(argumentAmplification.transportArgumentBytes, 0)} transported byte(s), ${readNumber(argumentAmplification.materializedArgumentBytes, 0)} materialized byte(s)` : null;
|
|
17105
17799
|
const memoryLimitError = hasMemoryLimit ? `${executor.kind === "pi" ? "Pi Agent" : "Executor"} memory limit exceeded: RSS ${readNumber(memoryLimit.rssBytes, 0)} bytes exceeded ${readNumber(memoryLimit.limitBytes, config.executorMaxRssMb * 1024 * 1024)} bytes` : null;
|
|
17106
17800
|
const piUsageDiagnostic = executor.kind === "pi" && !hasOutputFlood && !hasArgumentAmplification && piOutputUsageMetadataMissing(parsed) ? "Pi Agent exited without usage metadata" : null;
|
|
17107
|
-
const completionOutputStopped = executor.kind === "pi" && piCompletionOutputStopped(execution);
|
|
17801
|
+
const completionOutputStopped = executor.kind === "pi" && (piCompletionOutputStopped(execution) || sourceCompletionOutputStopped);
|
|
17108
17802
|
const cleanupDisposition = executor.kind === "pi" && !cancelled && !hasOutputFlood && !hasArgumentAmplification && !hasMemoryLimit && execution.timedOut !== true && !execution.spawnError && execution.signal === null ? classifyPiTerminalCleanupDisposition(
|
|
17109
17803
|
{ ...parsed, mcpToolResults },
|
|
17110
17804
|
runtimeArtifacts
|
|
@@ -17126,13 +17820,13 @@ async function executeRunCommand(config, command) {
|
|
|
17126
17820
|
const piTurnLimitFailure = executor.kind === "pi" && !cancelled && !hasOutputFlood && !hasArgumentAmplification && !hasMemoryLimit && execution.timedOut !== true && !execution.spawnError ? classifyPiTurnLimitResult(parsedForValidation) : null;
|
|
17127
17821
|
const piInvalidOutputError = executor.kind === "pi" ? piOutputValidationError(parsedForValidation, {
|
|
17128
17822
|
allowMissingTurnEnd: completionOutputStopped,
|
|
17129
|
-
allowMissingAssistantOutput: execution.completionOutputType === "approval_required",
|
|
17823
|
+
allowMissingAssistantOutput: execution.completionOutputType === "approval_required" || sourceCompletionGuard,
|
|
17130
17824
|
completionOutputType: execution.completionOutputType,
|
|
17131
17825
|
completionOutputHasFinalAssistantText: terminalTextRepair?.succeeded === true ? true : execution.completionOutputHasFinalAssistantText
|
|
17132
17826
|
}) : null;
|
|
17133
17827
|
const piOutputFailure = executor.kind === "pi" && !cancelled && !hasOutputFlood && !hasArgumentAmplification && !hasMemoryLimit && execution.timedOut !== true && !execution.spawnError ? classifyPiOutputFailure(parsedForValidation, { invalidOutputError: piInvalidOutputError }) : null;
|
|
17134
17828
|
const piProviderFailure = piOutputFailure?.errorCode !== "pi_executor_invalid_output" ? piOutputFailure : null;
|
|
17135
|
-
const parsedErrorMessage = outputFloodError ?? argumentAmplificationError ?? memoryLimitError ?? piTurnLimitFailure?.message ?? piInvalidOutputError ?? nativeSessionRolloutError ?? nativeSessionRolloutCleanupError ?? parsedForValidation.errorMessage;
|
|
17829
|
+
const parsedErrorMessage = outputFloodError ?? argumentAmplificationError ?? memoryLimitError ?? sourceCompletionFailure ?? piTurnLimitFailure?.message ?? piInvalidOutputError ?? nativeSessionRolloutError ?? nativeSessionRolloutCleanupError ?? parsedForValidation.errorMessage;
|
|
17136
17830
|
const codexTransientFailure = executor.kind === "codex" && (execution.exitCode ?? 0) !== 0 ? classifyCodexTransientUpstreamError({
|
|
17137
17831
|
stdout: execution.stdout,
|
|
17138
17832
|
stderr: execution.stderr,
|
|
@@ -17159,15 +17853,15 @@ async function executeRunCommand(config, command) {
|
|
|
17159
17853
|
receipt: sourceExecutionReceiptPath ? readSourceAcquisitionExecutionReceipt(sourceExecutionReceiptPath, sourceExecutionIdentity) : null,
|
|
17160
17854
|
exitCode: execution.exitCode
|
|
17161
17855
|
}) : null;
|
|
17162
|
-
const sourceErrorCode = sourceAcquisition ? execution.timedOut ? "source_acquisition_timeout" : cancelled ? "source_acquisition_cancelled" : hasOutputFlood ? "source_acquisition_output_flood" : hasMemoryLimit ? "source_acquisition_memory_limit" : execution.spawnError ? "source_acquisition_executor_unavailable" : succeeded ? null : sourceExecutionFailure?.failureCode ?? "source_acquisition_executor_failed" : null;
|
|
17856
|
+
const sourceErrorCode = sourceAcquisition ? sourceCompletionFailure ?? (execution.timedOut ? "source_acquisition_timeout" : cancelled ? "source_acquisition_cancelled" : hasOutputFlood ? "source_acquisition_output_flood" : hasMemoryLimit ? "source_acquisition_memory_limit" : execution.spawnError ? "source_acquisition_executor_unavailable" : succeeded ? null : sourceExecutionFailure?.failureCode ?? "source_acquisition_executor_failed") : null;
|
|
17163
17857
|
const error = sourceAcquisition ? sourceErrorCode : unsafeError;
|
|
17164
17858
|
const costUsage = parsedCostUsage(parsed.usage);
|
|
17165
|
-
const cleanPiTerminalOutputStop = succeeded && (completionOutputStopped || repairedPiTerminalOutputStop) && execution.completionOutputType === "agent_end" && parsed.terminalEventType === "agent_end" && Number.isInteger(parsed.terminalEventIndex);
|
|
17859
|
+
const cleanPiTerminalOutputStop = succeeded && (completionOutputStopped || repairedPiTerminalOutputStop) && (sourceCompletionOutputStopped || execution.completionOutputType === "agent_end" && parsed.terminalEventType === "agent_end" && Number.isInteger(parsed.terminalEventIndex));
|
|
17166
17860
|
const executorOutcome = {
|
|
17167
17861
|
status: cancelled ? "cancelled" : execution.timedOut ? "timed_out" : cleanPiTerminalOutputStop || execution.exitCode === 0 && execution.signal === null ? "completed" : "failed",
|
|
17168
17862
|
exitCode: cleanPiTerminalOutputStop ? 0 : execution.exitCode,
|
|
17169
17863
|
signal: cleanPiTerminalOutputStop ? null : execution.signal,
|
|
17170
|
-
terminalEvent: ["agent_end", "turn_end"].includes(readString(parsed.terminalEventType) ?? "") ? readString(parsed.terminalEventType) : null,
|
|
17864
|
+
terminalEvent: sourceCompletionOutputStopped ? "agent_settled" : ["agent_end", "turn_end"].includes(readString(parsed.terminalEventType) ?? "") ? readString(parsed.terminalEventType) : null,
|
|
17171
17865
|
terminalEventIndex: Number.isInteger(parsed.terminalEventIndex) ? parsed.terminalEventIndex : null
|
|
17172
17866
|
};
|
|
17173
17867
|
let result3 = {
|