@byok-sdk/client 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-home.d.ts +21 -2
- package/dist/bin/byok-agent.js +473 -250
- package/dist/bin/byok-agent.js.map +1 -1
- package/dist/daemon/agent-home-projection-client.d.ts +20 -0
- package/dist/daemon/create-daemon.d.ts +4 -1
- package/dist/daemon/task-runner.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +462 -236
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID, createHash, sign, createPrivateKey, generateKeyPairSync, randomBytes, timingSafeEqual, createHmac } from 'crypto';
|
|
2
2
|
import { promises, mkdirSync, existsSync, renameSync, writeFileSync, chmodSync, statSync, readdirSync, linkSync, fstatSync, lstatSync, unlinkSync, constants, readFileSync, realpathSync } from 'fs';
|
|
3
|
-
import
|
|
4
|
-
import { AGENT_CONTENT_ARTIFACT_READ_CAPABILITY, AGENT_CONTENT_TRANSCRIPT_READ_CAPABILITY, AGENT_CONTENT_WORKSPACE_READ_CAPABILITY, AgentRefSchema, BYOK_PAIR_PATH, PairResponseSchema, BYOK_CHALLENGE_PATH, BYOK_TOKEN_PATH, byokBlobUrlPath, BYOK_BLOBS_PATH, byokBlobFinalizePath, partitionAgentEvents, BYOK_SKILL_PACKS_PATH, byokSkillPackFilePath, BYOK_RECORDS_PATH, byokRecordPath, TASK_TRANSITIONS, AgentEgressPolicySchema, CONFIGURED_TOOLSETS_MAX_ITEMS, ToolsetIdSchema, AgentContentReceiptPayloadSchema, encodeEnvelope, PROTOCOL_VERSION, createEnvelope, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY, AGENT_EGRESS_POLICY_CAPABILITY, parseMessage, checkResultDocument, MAX_MESSAGES_PER_BATCH, BYOK_CAPABILITIES_PATH, BYOK_PRESENCE_PATH, RuntimeIdSchema, TERMINAL_INFERENCE_USAGE_MAX_DURATION_MS, TERMINAL_INFERENCE_USAGE_MAX_TOKENS, RESULT_DOCUMENT_MAX_BYTES, decodeEnvelope, BYOK_EVENTS_PATH, BYOK_MESSAGES_PATH, MessagesSendResponseSchema, UnknownMessageTypeError, BYOK_WS_PATH } from '@byok-sdk/protocol';
|
|
3
|
+
import path2, { join, isAbsolute } from 'path';
|
|
4
|
+
import { AGENT_CONTENT_ARTIFACT_READ_CAPABILITY, AGENT_CONTENT_TRANSCRIPT_READ_CAPABILITY, AGENT_CONTENT_WORKSPACE_READ_CAPABILITY, AgentRefSchema, AgentHomeProjectionPayloadSchema, BYOK_PAIR_PATH, PairResponseSchema, BYOK_CHALLENGE_PATH, BYOK_TOKEN_PATH, byokBlobUrlPath, BYOK_BLOBS_PATH, byokBlobFinalizePath, partitionAgentEvents, BYOK_SKILL_PACKS_PATH, byokSkillPackFilePath, BYOK_RECORDS_PATH, byokRecordPath, TASK_TRANSITIONS, AgentEgressPolicySchema, CONFIGURED_TOOLSETS_MAX_ITEMS, ToolsetIdSchema, AgentContentReceiptPayloadSchema, encodeEnvelope, PROTOCOL_VERSION, createEnvelope, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY, AGENT_HOME_PROJECTION_CAPABILITY, AGENT_EGRESS_POLICY_CAPABILITY, AGENT_EGRESS_FRESH_SESSION_CAPABILITY, AgentHomeProjectionCompletionRequestSchema, byokAgentHomeProjectionCompletionPath, AgentHomeProjectionReadbackSchema, parseMessage, checkResultDocument, MAX_MESSAGES_PER_BATCH, BYOK_CAPABILITIES_PATH, BYOK_PRESENCE_PATH, RuntimeIdSchema, TERMINAL_INFERENCE_USAGE_MAX_DURATION_MS, TERMINAL_INFERENCE_USAGE_MAX_TOKENS, RESULT_DOCUMENT_MAX_BYTES, decodeEnvelope, BYOK_EVENTS_PATH, BYOK_MESSAGES_PATH, MessagesSendResponseSchema, UnknownMessageTypeError, BYOK_WS_PATH } from '@byok-sdk/protocol';
|
|
5
5
|
import { execFile, spawn } from 'child_process';
|
|
6
6
|
import os6 from 'os';
|
|
7
7
|
import { parseDeviceAssertionEnvelope, tenantId, DeviceProofProtectedClaimsSchema, deviceProofSigningInput, DEVICE_PROOF_SCHEMA_ID, SKILL_PACK_MAX_BYTES, hasCapability, parseSkillPackManifest, checkSkillPackManifest, skillPackContentHashInput, checkSkillPackFileContent, SKILL_PACK_ENTRY_PATH, checkSkillPackEntry, isSkillPackPathSafe, DEVICE_PROOF_HEADER, contentHash as contentHash$1, TRUTH_RECORD_KINDS, nonceSigningBytes, DEVICE_ASSERTION_AUDIENCE_MAX_BYTES, DEVICE_ASSERTION_DEFAULT_TTL_MS, DEVICE_ASSERTION_MAX_TTL_MS, CONTENT_HASH_PATTERN, isTenantId, CapabilityDeclarationSchema, DeviceAssertionClaimsSchema, deviceAssertionSigningInput, DEVICE_ASSERTION_SCHEMA_ID } from '@byok-sdk/core';
|
|
@@ -12,9 +12,80 @@ import net, { createServer, createConnection } from 'net';
|
|
|
12
12
|
import { WebSocket } from 'ws';
|
|
13
13
|
import { createRequire } from 'module';
|
|
14
14
|
|
|
15
|
+
// src/agent-home.ts
|
|
16
|
+
var tmpSeq = 0;
|
|
17
|
+
async function atomicWriteFile(filePath, data, options = {}) {
|
|
18
|
+
const tmpPath = `${filePath}.${process.pid}-${tmpSeq++}.tmp`;
|
|
19
|
+
try {
|
|
20
|
+
const handle = await promises.open(tmpPath, "w", options.mode);
|
|
21
|
+
try {
|
|
22
|
+
await handle.writeFile(data);
|
|
23
|
+
if (options.mode !== void 0) {
|
|
24
|
+
await handle.chmod(options.mode);
|
|
25
|
+
}
|
|
26
|
+
if (options.fsync) {
|
|
27
|
+
await handle.sync();
|
|
28
|
+
}
|
|
29
|
+
} finally {
|
|
30
|
+
await handle.close();
|
|
31
|
+
}
|
|
32
|
+
} catch (err) {
|
|
33
|
+
await promises.rm(tmpPath, { force: true }).catch(() => {
|
|
34
|
+
});
|
|
35
|
+
throw err;
|
|
36
|
+
}
|
|
37
|
+
await renameOnto(tmpPath, filePath);
|
|
38
|
+
if (options.mode !== void 0) {
|
|
39
|
+
await promises.chmod(filePath, options.mode);
|
|
40
|
+
}
|
|
41
|
+
if (options.fsync) {
|
|
42
|
+
const target = await promises.open(filePath, process.platform === "win32" ? "r+" : "r");
|
|
43
|
+
try {
|
|
44
|
+
await target.sync();
|
|
45
|
+
} finally {
|
|
46
|
+
await target.close();
|
|
47
|
+
}
|
|
48
|
+
if (process.platform !== "win32") {
|
|
49
|
+
const directory = await promises.open(path2.dirname(filePath), "r");
|
|
50
|
+
try {
|
|
51
|
+
await directory.sync();
|
|
52
|
+
} finally {
|
|
53
|
+
await directory.close();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
var RENAME_RETRY_ATTEMPTS = 5;
|
|
59
|
+
var RENAME_RETRY_DELAY_MS = 20;
|
|
60
|
+
function delay(ms) {
|
|
61
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
62
|
+
}
|
|
63
|
+
async function renameOnto(tmpPath, targetPath) {
|
|
64
|
+
for (let attempt = 1; attempt <= RENAME_RETRY_ATTEMPTS; attempt++) {
|
|
65
|
+
try {
|
|
66
|
+
await promises.rename(tmpPath, targetPath);
|
|
67
|
+
return;
|
|
68
|
+
} catch (err) {
|
|
69
|
+
const code = err.code;
|
|
70
|
+
if (code !== "EPERM" && code !== "EEXIST") {
|
|
71
|
+
await promises.rm(tmpPath, { force: true }).catch(() => {
|
|
72
|
+
});
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
if (attempt === RENAME_RETRY_ATTEMPTS) {
|
|
76
|
+
await promises.rm(tmpPath, { force: true }).catch(() => {
|
|
77
|
+
});
|
|
78
|
+
throw err;
|
|
79
|
+
}
|
|
80
|
+
await delay(RENAME_RETRY_DELAY_MS * attempt);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
15
85
|
// src/agent-home.ts
|
|
16
86
|
var AGENT_HOME_DIRECTORY = "agents";
|
|
17
87
|
var AGENT_HOME_INTERNAL_DIRECTORY = ".byok";
|
|
88
|
+
var AGENT_HOME_PROJECTION_STATE_FILE = "agent-home-projection.json";
|
|
18
89
|
var AgentHomeError = class extends Error {
|
|
19
90
|
constructor(message) {
|
|
20
91
|
super(message);
|
|
@@ -63,11 +134,11 @@ function validateAgentRef(value) {
|
|
|
63
134
|
return Object.freeze({ agentId: candidate.agentId, profileRevision: candidate.profileRevision });
|
|
64
135
|
}
|
|
65
136
|
function isWithin(root, candidate) {
|
|
66
|
-
const relative =
|
|
67
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${
|
|
137
|
+
const relative = path2.relative(root, candidate);
|
|
138
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${path2.sep}`) && !path2.isAbsolute(relative);
|
|
68
139
|
}
|
|
69
140
|
function assertAbsolutePath(value, label) {
|
|
70
|
-
if (typeof value !== "string" || value.length === 0 || !
|
|
141
|
+
if (typeof value !== "string" || value.length === 0 || !path2.isAbsolute(value)) {
|
|
71
142
|
throw new AgentHomeResolutionError(`${label} must be an absolute path`);
|
|
72
143
|
}
|
|
73
144
|
if (/[\u0000\r\n]/u.test(value)) {
|
|
@@ -75,7 +146,7 @@ function assertAbsolutePath(value, label) {
|
|
|
75
146
|
}
|
|
76
147
|
}
|
|
77
148
|
async function resolveExistingAncestor(inputPath) {
|
|
78
|
-
let cursor =
|
|
149
|
+
let cursor = path2.resolve(inputPath);
|
|
79
150
|
const tail = [];
|
|
80
151
|
for (; ; ) {
|
|
81
152
|
try {
|
|
@@ -83,9 +154,9 @@ async function resolveExistingAncestor(inputPath) {
|
|
|
83
154
|
} catch (error) {
|
|
84
155
|
const code = error.code;
|
|
85
156
|
if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
|
|
86
|
-
const parent =
|
|
157
|
+
const parent = path2.dirname(cursor);
|
|
87
158
|
if (parent === cursor) throw new AgentHomeResolutionError(`no existing ancestor for ${inputPath}`);
|
|
88
|
-
tail.unshift(
|
|
159
|
+
tail.unshift(path2.basename(cursor));
|
|
89
160
|
cursor = parent;
|
|
90
161
|
}
|
|
91
162
|
}
|
|
@@ -94,7 +165,7 @@ async function materializeDirectory(inputPath) {
|
|
|
94
165
|
const { canonical: canonical2, tail } = await resolveExistingAncestor(inputPath);
|
|
95
166
|
let cursor = canonical2;
|
|
96
167
|
for (const component of tail) {
|
|
97
|
-
cursor =
|
|
168
|
+
cursor = path2.join(cursor, component);
|
|
98
169
|
try {
|
|
99
170
|
const stat = await promises.lstat(cursor);
|
|
100
171
|
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
@@ -113,11 +184,11 @@ async function materializeDirectory(inputPath) {
|
|
|
113
184
|
}
|
|
114
185
|
async function ensureDirectoryNoSymlink(root, target) {
|
|
115
186
|
if (!isWithin(root, target)) throw new AgentHomeResolutionError("Agent home is outside hostStorageRoot");
|
|
116
|
-
const relative =
|
|
117
|
-
const components = relative === "" ? [] : relative.split(
|
|
187
|
+
const relative = path2.relative(root, target);
|
|
188
|
+
const components = relative === "" ? [] : relative.split(path2.sep);
|
|
118
189
|
let cursor = root;
|
|
119
190
|
for (const component of components) {
|
|
120
|
-
cursor =
|
|
191
|
+
cursor = path2.join(cursor, component);
|
|
121
192
|
try {
|
|
122
193
|
const stat = await promises.lstat(cursor);
|
|
123
194
|
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
@@ -153,16 +224,16 @@ var AgentHomeLayout = class {
|
|
|
153
224
|
canonicalRoot;
|
|
154
225
|
constructor(hostStorageRoot) {
|
|
155
226
|
assertAbsolutePath(hostStorageRoot, "agentHome.hostStorageRoot");
|
|
156
|
-
this.hostStorageRootInput =
|
|
227
|
+
this.hostStorageRootInput = path2.resolve(hostStorageRoot);
|
|
157
228
|
}
|
|
158
229
|
async resolve(agentRefInput) {
|
|
159
230
|
const agentRef = validateAgentRef(agentRefInput);
|
|
160
231
|
const hostStorageRoot = await this.resolveRoot();
|
|
161
232
|
const agentsRoot = await ensureDirectoryNoSymlink(
|
|
162
233
|
hostStorageRoot,
|
|
163
|
-
|
|
234
|
+
path2.join(hostStorageRoot, AGENT_HOME_DIRECTORY)
|
|
164
235
|
);
|
|
165
|
-
const lexicalHome =
|
|
236
|
+
const lexicalHome = path2.join(agentsRoot, agentRef.agentId);
|
|
166
237
|
const canonicalHome = await ensureDirectoryNoSymlink(agentsRoot, lexicalHome);
|
|
167
238
|
const priorAgentId = this.agentIdByCanonicalHome.get(canonicalHome);
|
|
168
239
|
if (priorAgentId !== void 0 && priorAgentId !== agentRef.agentId) {
|
|
@@ -192,9 +263,9 @@ var AgentHomeLayout = class {
|
|
|
192
263
|
const hostStorageRoot = await this.resolveRoot();
|
|
193
264
|
const agentsRoot = await ensureDirectoryNoSymlink(
|
|
194
265
|
hostStorageRoot,
|
|
195
|
-
|
|
266
|
+
path2.join(hostStorageRoot, AGENT_HOME_DIRECTORY)
|
|
196
267
|
);
|
|
197
|
-
probePath =
|
|
268
|
+
probePath = path2.join(agentsRoot, `.byok-agent-home-preflight-${randomUUID()}`);
|
|
198
269
|
handle = await promises.open(probePath, "wx", 384);
|
|
199
270
|
created = true;
|
|
200
271
|
await handle.sync();
|
|
@@ -225,7 +296,7 @@ var AgentHomeLayout = class {
|
|
|
225
296
|
}
|
|
226
297
|
};
|
|
227
298
|
function stableAgentHomeOwnerId(storeDir, productId) {
|
|
228
|
-
const identity = `${
|
|
299
|
+
const identity = `${path2.resolve(storeDir)}\0${productId}`;
|
|
229
300
|
return `store-product:${createHash("sha256").update(identity).digest("hex")}`;
|
|
230
301
|
}
|
|
231
302
|
function parseLeaseMarker(value, lockPath) {
|
|
@@ -235,7 +306,7 @@ function parseLeaseMarker(value, lockPath) {
|
|
|
235
306
|
} catch {
|
|
236
307
|
throw new AgentHomeLeaseCorruptError(`Agent home lease marker ${lockPath} is corrupt`);
|
|
237
308
|
}
|
|
238
|
-
if (typeof parsed !== "object" || parsed === null || parsed.version !== 1 || typeof parsed.ownerId !== "string" || typeof parsed.leaseId !== "string" || typeof parsed.canonicalHome !== "string" || !
|
|
309
|
+
if (typeof parsed !== "object" || parsed === null || parsed.version !== 1 || typeof parsed.ownerId !== "string" || typeof parsed.leaseId !== "string" || typeof parsed.canonicalHome !== "string" || !path2.isAbsolute(parsed.canonicalHome)) {
|
|
239
310
|
throw new AgentHomeLeaseCorruptError(`Agent home lease marker ${lockPath} has an invalid shape`);
|
|
240
311
|
}
|
|
241
312
|
let agentRef;
|
|
@@ -245,7 +316,7 @@ function parseLeaseMarker(value, lockPath) {
|
|
|
245
316
|
throw new AgentHomeLeaseCorruptError(`Agent home lease marker ${lockPath} has an invalid AgentRef`);
|
|
246
317
|
}
|
|
247
318
|
const marker = parsed;
|
|
248
|
-
return { ...marker, agentRef, canonicalHome:
|
|
319
|
+
return { ...marker, agentRef, canonicalHome: path2.resolve(marker.canonicalHome) };
|
|
249
320
|
}
|
|
250
321
|
var AgentHomeLeaseManager = class _AgentHomeLeaseManager {
|
|
251
322
|
static held = /* @__PURE__ */ new Map();
|
|
@@ -267,9 +338,9 @@ var AgentHomeLeaseManager = class _AgentHomeLeaseManager {
|
|
|
267
338
|
await ensureDirectoryNoSymlink(resolution.agentsRoot, canonicalHome);
|
|
268
339
|
const internalDir = await ensureDirectoryNoSymlink(
|
|
269
340
|
canonicalHome,
|
|
270
|
-
|
|
341
|
+
path2.join(canonicalHome, AGENT_HOME_INTERNAL_DIRECTORY)
|
|
271
342
|
);
|
|
272
|
-
lockPath =
|
|
343
|
+
lockPath = path2.join(internalDir, "agent-home.lease");
|
|
273
344
|
handle = await this.openLeaseMarker(lockPath, canonicalHome, agentRef.agentId);
|
|
274
345
|
ownsMarker = true;
|
|
275
346
|
const marker = {
|
|
@@ -368,9 +439,73 @@ var AgentHomeLeaseManager = class _AgentHomeLeaseManager {
|
|
|
368
439
|
async function initializeAgentHome(resolution) {
|
|
369
440
|
await ensureDirectoryNoSymlink(
|
|
370
441
|
resolution.canonicalHome,
|
|
371
|
-
|
|
442
|
+
path2.join(resolution.canonicalHome, "notes")
|
|
372
443
|
);
|
|
373
|
-
await ensurePreservedFile(
|
|
444
|
+
await ensurePreservedFile(path2.join(resolution.canonicalHome, "MEMORY.md"));
|
|
445
|
+
}
|
|
446
|
+
function projectionStatePath(resolution) {
|
|
447
|
+
return path2.join(
|
|
448
|
+
resolution.canonicalHome,
|
|
449
|
+
AGENT_HOME_INTERNAL_DIRECTORY,
|
|
450
|
+
AGENT_HOME_PROJECTION_STATE_FILE
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
async function readProjectionState(resolution) {
|
|
454
|
+
const filePath = projectionStatePath(resolution);
|
|
455
|
+
try {
|
|
456
|
+
const stat = await promises.lstat(filePath);
|
|
457
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
458
|
+
throw new AgentHomeResolutionError(`Agent projection state is not a regular file: ${filePath}`);
|
|
459
|
+
}
|
|
460
|
+
} catch (error) {
|
|
461
|
+
if (error.code === "ENOENT") return void 0;
|
|
462
|
+
throw error;
|
|
463
|
+
}
|
|
464
|
+
let parsed;
|
|
465
|
+
try {
|
|
466
|
+
parsed = JSON.parse(await promises.readFile(filePath, "utf8"));
|
|
467
|
+
} catch (error) {
|
|
468
|
+
throw new AgentHomeResolutionError(
|
|
469
|
+
`Agent projection state is corrupt: ${error instanceof Error ? error.message : String(error)}`
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
if (typeof parsed !== "object" || parsed === null || parsed.version !== 1 || typeof parsed.requestId !== "string" || typeof parsed.projectionHash !== "string") {
|
|
473
|
+
throw new AgentHomeResolutionError("Agent projection state has an invalid shape");
|
|
474
|
+
}
|
|
475
|
+
const candidate = parsed;
|
|
476
|
+
const agentRef = validateAgentRef(candidate.agentRef);
|
|
477
|
+
if (agentRef.agentId !== resolution.agentRef.agentId) {
|
|
478
|
+
throw new AgentHomeCollisionError("Agent projection state belongs to a different Agent home");
|
|
479
|
+
}
|
|
480
|
+
return Object.freeze({
|
|
481
|
+
version: 1,
|
|
482
|
+
agentRef,
|
|
483
|
+
requestId: candidate.requestId,
|
|
484
|
+
projectionHash: candidate.projectionHash
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
async function writeProjectionState(resolution, payload) {
|
|
488
|
+
const filePath = projectionStatePath(resolution);
|
|
489
|
+
const existing = await promises.lstat(filePath).catch((error) => {
|
|
490
|
+
if (error.code === "ENOENT") return void 0;
|
|
491
|
+
throw error;
|
|
492
|
+
});
|
|
493
|
+
if (existing !== void 0 && (!existing.isFile() || existing.isSymbolicLink())) {
|
|
494
|
+
throw new AgentHomeResolutionError(`Agent projection state is not a regular file: ${filePath}`);
|
|
495
|
+
}
|
|
496
|
+
const state = {
|
|
497
|
+
version: 1,
|
|
498
|
+
agentRef: payload.agentRef,
|
|
499
|
+
requestId: payload.requestId,
|
|
500
|
+
projectionHash: payload.projectionHash
|
|
501
|
+
};
|
|
502
|
+
await atomicWriteFile(filePath, `${JSON.stringify(state)}
|
|
503
|
+
`, { mode: 384, fsync: true });
|
|
504
|
+
}
|
|
505
|
+
function compareProjectionRevision(left, right) {
|
|
506
|
+
const leftRevision = BigInt(left);
|
|
507
|
+
const rightRevision = BigInt(right);
|
|
508
|
+
return leftRevision < rightRevision ? -1 : leftRevision > rightRevision ? 1 : 0;
|
|
374
509
|
}
|
|
375
510
|
var AgentHomeManager = class {
|
|
376
511
|
layout;
|
|
@@ -406,16 +541,66 @@ var AgentHomeManager = class {
|
|
|
406
541
|
async initialize(binding) {
|
|
407
542
|
const { resolution, lease } = binding;
|
|
408
543
|
await initializeAgentHome(resolution);
|
|
409
|
-
|
|
544
|
+
const prepare = this.projection?.prepare;
|
|
545
|
+
if (prepare !== void 0) await prepare({ ...resolution, cwd: lease.cwd });
|
|
410
546
|
if (await promises.realpath(resolution.homeDir) !== resolution.canonicalHome) {
|
|
411
547
|
throw new AgentHomeResolutionError("Agent projection changed the canonical home path");
|
|
412
548
|
}
|
|
413
549
|
await initializeAgentHome(resolution);
|
|
414
550
|
}
|
|
551
|
+
supportsTaskFreeProjection() {
|
|
552
|
+
return this.projection?.apply !== void 0;
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Apply one task-free projection under the same canonical-home writer lease
|
|
556
|
+
* used by Agent execution. Only a successful host hook followed by the
|
|
557
|
+
* SDK-owned fsynced ordering record can return `applied`.
|
|
558
|
+
*/
|
|
559
|
+
async project(input) {
|
|
560
|
+
const payload = AgentHomeProjectionPayloadSchema.parse(input);
|
|
561
|
+
const binding = await this.acquire(payload.agentRef);
|
|
562
|
+
try {
|
|
563
|
+
const { resolution, lease } = binding;
|
|
564
|
+
await initializeAgentHome(resolution);
|
|
565
|
+
const current = await readProjectionState(resolution);
|
|
566
|
+
if (current !== void 0) {
|
|
567
|
+
const order = compareProjectionRevision(
|
|
568
|
+
payload.agentRef.profileRevision,
|
|
569
|
+
current.agentRef.profileRevision
|
|
570
|
+
);
|
|
571
|
+
if (order < 0) return "stale";
|
|
572
|
+
if (order === 0) {
|
|
573
|
+
return payload.projectionHash === current.projectionHash ? "idempotent" : "conflict";
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
const apply = this.projection?.apply;
|
|
577
|
+
if (apply === void 0) {
|
|
578
|
+
throw new AgentHomeError("task-free Agent-home projection is not configured");
|
|
579
|
+
}
|
|
580
|
+
await apply({
|
|
581
|
+
...resolution,
|
|
582
|
+
cwd: lease.cwd,
|
|
583
|
+
requestId: payload.requestId,
|
|
584
|
+
projectionHash: payload.projectionHash,
|
|
585
|
+
projection: payload.projection
|
|
586
|
+
});
|
|
587
|
+
if (await promises.realpath(resolution.homeDir) !== resolution.canonicalHome) {
|
|
588
|
+
throw new AgentHomeResolutionError("Agent projection changed the canonical home path");
|
|
589
|
+
}
|
|
590
|
+
await initializeAgentHome(resolution);
|
|
591
|
+
await writeProjectionState(resolution, payload);
|
|
592
|
+
return "applied";
|
|
593
|
+
} finally {
|
|
594
|
+
await binding.lease.release();
|
|
595
|
+
}
|
|
596
|
+
}
|
|
415
597
|
};
|
|
416
598
|
function createAgentHomeProjection(prepare) {
|
|
417
599
|
return Object.freeze({ prepare });
|
|
418
600
|
}
|
|
601
|
+
function createAgentHomeProjectionConsumer(apply) {
|
|
602
|
+
return Object.freeze({ apply });
|
|
603
|
+
}
|
|
419
604
|
var AgentSessionHandoffStoreError = class extends Error {
|
|
420
605
|
constructor(message) {
|
|
421
606
|
super(message);
|
|
@@ -455,7 +640,7 @@ function parseTaskTerminalEntry(value) {
|
|
|
455
640
|
assertNonEmptyString(value.terminalReason, "taskTerminal.terminalReason");
|
|
456
641
|
assertNonEmptyString(value.updatedAt, "taskTerminal.updatedAt");
|
|
457
642
|
if (value.sessionRef !== void 0) assertNonEmptyString(value.sessionRef, "taskTerminal.sessionRef");
|
|
458
|
-
if (typeof value.cwd !== "string" || !
|
|
643
|
+
if (typeof value.cwd !== "string" || !path2.isAbsolute(value.cwd)) {
|
|
459
644
|
throw new AgentSessionHandoffCorruptError("taskTerminal.cwd must be an absolute path");
|
|
460
645
|
}
|
|
461
646
|
if (value.terminalCause !== "failed") {
|
|
@@ -468,7 +653,7 @@ function parseTaskTerminalEntry(value) {
|
|
|
468
653
|
agentRef,
|
|
469
654
|
taskId: value.taskId,
|
|
470
655
|
runtimeId: value.runtimeId,
|
|
471
|
-
cwd:
|
|
656
|
+
cwd: path2.resolve(value.cwd),
|
|
472
657
|
leaseId: value.leaseId,
|
|
473
658
|
...value.sessionRef === void 0 ? {} : { sessionRef: value.sessionRef },
|
|
474
659
|
terminalCause: "failed",
|
|
@@ -498,7 +683,7 @@ function parseEntry(value) {
|
|
|
498
683
|
assertNonEmptyString(value.runtimeId, "handoff.runtimeId");
|
|
499
684
|
assertNonEmptyString(value.leaseId, "handoff.leaseId");
|
|
500
685
|
assertNonEmptyString(value.updatedAt, "handoff.updatedAt");
|
|
501
|
-
if (typeof value.cwd !== "string" || !
|
|
686
|
+
if (typeof value.cwd !== "string" || !path2.isAbsolute(value.cwd)) {
|
|
502
687
|
throw new AgentSessionHandoffCorruptError("handoff.cwd must be an absolute path");
|
|
503
688
|
}
|
|
504
689
|
if (Number.isNaN(Date.parse(value.updatedAt))) {
|
|
@@ -515,7 +700,7 @@ function parseEntry(value) {
|
|
|
515
700
|
taskId: value.taskId,
|
|
516
701
|
sessionRef: value.sessionRef,
|
|
517
702
|
runtimeId: value.runtimeId,
|
|
518
|
-
cwd:
|
|
703
|
+
cwd: path2.resolve(value.cwd),
|
|
519
704
|
leaseId: value.leaseId,
|
|
520
705
|
...value.terminalCause === void 0 ? {} : { terminalCause: value.terminalCause },
|
|
521
706
|
...value.terminalReason === void 0 ? {} : { terminalReason: value.terminalReason },
|
|
@@ -526,10 +711,10 @@ function sameRef(left, right) {
|
|
|
526
711
|
return left.agentId === right.agentId && left.profileRevision === right.profileRevision;
|
|
527
712
|
}
|
|
528
713
|
function sameMatch(entry, expected) {
|
|
529
|
-
return sameRef(entry.agentRef, expected.agentRef) && entry.sessionRef === expected.sessionRef && entry.runtimeId === expected.runtimeId && entry.cwd ===
|
|
714
|
+
return sameRef(entry.agentRef, expected.agentRef) && entry.sessionRef === expected.sessionRef && entry.runtimeId === expected.runtimeId && entry.cwd === path2.resolve(expected.cwd);
|
|
530
715
|
}
|
|
531
716
|
function sameTaskTerminalMatch(entry, expected) {
|
|
532
|
-
return sameRef(entry.agentRef, expected.agentRef) && entry.taskId === expected.taskId && entry.runtimeId === expected.runtimeId && entry.cwd ===
|
|
717
|
+
return sameRef(entry.agentRef, expected.agentRef) && entry.taskId === expected.taskId && entry.runtimeId === expected.runtimeId && entry.cwd === path2.resolve(expected.cwd);
|
|
533
718
|
}
|
|
534
719
|
function sessionFileName(runtimeId, sessionRef) {
|
|
535
720
|
const digest2 = createHash("sha256").update(sessionRef, "utf8").digest("hex");
|
|
@@ -542,13 +727,13 @@ function taskTerminalFileName(runtimeId, taskId) {
|
|
|
542
727
|
return `${runtime}-task-${digest2}.jsonl`;
|
|
543
728
|
}
|
|
544
729
|
async function evidenceDirectory(cwdInput) {
|
|
545
|
-
if (!
|
|
730
|
+
if (!path2.isAbsolute(cwdInput)) {
|
|
546
731
|
throw new AgentSessionHandoffStoreError("Agent session cwd must be absolute");
|
|
547
732
|
}
|
|
548
733
|
const cwd = await promises.realpath(cwdInput);
|
|
549
734
|
let cursor = cwd;
|
|
550
735
|
for (const component of [".byok", "runtime-sessions"]) {
|
|
551
|
-
cursor =
|
|
736
|
+
cursor = path2.join(cursor, component);
|
|
552
737
|
try {
|
|
553
738
|
const stat = await promises.lstat(cursor);
|
|
554
739
|
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
@@ -560,8 +745,8 @@ async function evidenceDirectory(cwdInput) {
|
|
|
560
745
|
}
|
|
561
746
|
}
|
|
562
747
|
const canonical2 = await promises.realpath(cursor);
|
|
563
|
-
const relative =
|
|
564
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
748
|
+
const relative = path2.relative(cwd, canonical2);
|
|
749
|
+
if (relative === ".." || relative.startsWith(`..${path2.sep}`) || path2.isAbsolute(relative)) {
|
|
565
750
|
throw new AgentSessionHandoffStoreError("Agent session evidence path escaped the canonical Agent home");
|
|
566
751
|
}
|
|
567
752
|
return canonical2;
|
|
@@ -607,7 +792,7 @@ var AgentSessionHandoffStore = class {
|
|
|
607
792
|
taskId: input.taskId,
|
|
608
793
|
sessionRef: input.sessionRef,
|
|
609
794
|
runtimeId: input.runtimeId,
|
|
610
|
-
cwd:
|
|
795
|
+
cwd: path2.resolve(input.cwd),
|
|
611
796
|
leaseId: input.leaseId,
|
|
612
797
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
613
798
|
});
|
|
@@ -650,7 +835,7 @@ var AgentSessionHandoffStore = class {
|
|
|
650
835
|
agentRef: validateAgentRef(input.agentRef),
|
|
651
836
|
taskId: input.taskId,
|
|
652
837
|
runtimeId: input.runtimeId,
|
|
653
|
-
cwd:
|
|
838
|
+
cwd: path2.resolve(input.cwd)
|
|
654
839
|
};
|
|
655
840
|
const filePath = await this.taskTerminalFilePath(expected);
|
|
656
841
|
return this.enqueue(filePath, async () => {
|
|
@@ -677,7 +862,7 @@ var AgentSessionHandoffStore = class {
|
|
|
677
862
|
agentRef: validateAgentRef(expectedInput.agentRef),
|
|
678
863
|
taskId: expectedInput.taskId,
|
|
679
864
|
runtimeId: expectedInput.runtimeId,
|
|
680
|
-
cwd:
|
|
865
|
+
cwd: path2.resolve(expectedInput.cwd)
|
|
681
866
|
};
|
|
682
867
|
const filePath = await this.taskTerminalFilePath(expected);
|
|
683
868
|
return this.enqueue(filePath, async () => {
|
|
@@ -695,14 +880,14 @@ var AgentSessionHandoffStore = class {
|
|
|
695
880
|
assertNonEmptyString(match.sessionRef, "handoff.sessionRef");
|
|
696
881
|
assertNonEmptyString(match.runtimeId, "handoff.runtimeId");
|
|
697
882
|
const directory = await evidenceDirectory(match.cwd);
|
|
698
|
-
return
|
|
883
|
+
return path2.join(directory, sessionFileName(match.runtimeId, match.sessionRef));
|
|
699
884
|
}
|
|
700
885
|
async taskTerminalFilePath(match) {
|
|
701
886
|
validateAgentRef(match.agentRef);
|
|
702
887
|
assertNonEmptyString(match.taskId, "taskTerminal.taskId");
|
|
703
888
|
assertNonEmptyString(match.runtimeId, "taskTerminal.runtimeId");
|
|
704
889
|
const directory = await evidenceDirectory(match.cwd);
|
|
705
|
-
return
|
|
890
|
+
return path2.join(directory, taskTerminalFileName(match.runtimeId, match.taskId));
|
|
706
891
|
}
|
|
707
892
|
enqueue(key, task) {
|
|
708
893
|
const previous = this.queues.get(key) ?? Promise.resolve();
|
|
@@ -991,7 +1176,7 @@ function gitEnvironment(readOnly) {
|
|
|
991
1176
|
return env;
|
|
992
1177
|
}
|
|
993
1178
|
function stableGitWorkspaceOwnerId(storeDir, productId) {
|
|
994
|
-
const identity = `${
|
|
1179
|
+
const identity = `${path2.resolve(storeDir)}\\0${productId}`;
|
|
995
1180
|
return `store-product:${createHash("sha256").update(identity).digest("hex")}`;
|
|
996
1181
|
}
|
|
997
1182
|
var GUIDANCE = [
|
|
@@ -1003,11 +1188,11 @@ var GUIDANCE = [
|
|
|
1003
1188
|
"Leave incomplete work visible for recovery."
|
|
1004
1189
|
].join("\n");
|
|
1005
1190
|
function canonical(value) {
|
|
1006
|
-
return
|
|
1191
|
+
return path2.resolve(value);
|
|
1007
1192
|
}
|
|
1008
1193
|
function isContained(root, candidate) {
|
|
1009
|
-
const relative =
|
|
1010
|
-
return relative === "" || !relative.startsWith(`..${
|
|
1194
|
+
const relative = path2.relative(root, candidate);
|
|
1195
|
+
return relative === "" || !relative.startsWith(`..${path2.sep}`) && !path2.isAbsolute(relative);
|
|
1011
1196
|
}
|
|
1012
1197
|
function bounded(value, max) {
|
|
1013
1198
|
return Buffer.byteLength(value, "utf8") <= max ? value : value.slice(0, max);
|
|
@@ -1112,7 +1297,7 @@ var GitWorkspaceManager = class {
|
|
|
1112
1297
|
await this.ensureOwnerMarker();
|
|
1113
1298
|
}
|
|
1114
1299
|
async ensureOwnerMarker() {
|
|
1115
|
-
const markerPath =
|
|
1300
|
+
const markerPath = path2.join(this.workspaceRoot, OWNER_MARKER);
|
|
1116
1301
|
let existing;
|
|
1117
1302
|
try {
|
|
1118
1303
|
existing = JSON.parse(await promises.readFile(markerPath, "utf8"));
|
|
@@ -1271,7 +1456,7 @@ ${instruction}`;
|
|
|
1271
1456
|
if (error instanceof GitWorkspaceError || code !== "ENOENT" && code !== "ENOTDIR") {
|
|
1272
1457
|
throw new GitWorkspaceError("workspace-root-invalid", "workspace directory is invalid");
|
|
1273
1458
|
}
|
|
1274
|
-
const parent =
|
|
1459
|
+
const parent = path2.dirname(current);
|
|
1275
1460
|
if (parent === current) {
|
|
1276
1461
|
throw new GitWorkspaceError("workspace-root-invalid", "workspace directory is invalid");
|
|
1277
1462
|
}
|
|
@@ -1303,74 +1488,6 @@ function isGitWorkspaceConfig(value) {
|
|
|
1303
1488
|
return false;
|
|
1304
1489
|
}
|
|
1305
1490
|
}
|
|
1306
|
-
var tmpSeq = 0;
|
|
1307
|
-
async function atomicWriteFile(filePath, data, options = {}) {
|
|
1308
|
-
const tmpPath = `${filePath}.${process.pid}-${tmpSeq++}.tmp`;
|
|
1309
|
-
try {
|
|
1310
|
-
const handle = await promises.open(tmpPath, "w", options.mode);
|
|
1311
|
-
try {
|
|
1312
|
-
await handle.writeFile(data);
|
|
1313
|
-
if (options.mode !== void 0) {
|
|
1314
|
-
await handle.chmod(options.mode);
|
|
1315
|
-
}
|
|
1316
|
-
if (options.fsync) {
|
|
1317
|
-
await handle.sync();
|
|
1318
|
-
}
|
|
1319
|
-
} finally {
|
|
1320
|
-
await handle.close();
|
|
1321
|
-
}
|
|
1322
|
-
} catch (err) {
|
|
1323
|
-
await promises.rm(tmpPath, { force: true }).catch(() => {
|
|
1324
|
-
});
|
|
1325
|
-
throw err;
|
|
1326
|
-
}
|
|
1327
|
-
await renameOnto(tmpPath, filePath);
|
|
1328
|
-
if (options.mode !== void 0) {
|
|
1329
|
-
await promises.chmod(filePath, options.mode);
|
|
1330
|
-
}
|
|
1331
|
-
if (options.fsync) {
|
|
1332
|
-
const target = await promises.open(filePath, process.platform === "win32" ? "r+" : "r");
|
|
1333
|
-
try {
|
|
1334
|
-
await target.sync();
|
|
1335
|
-
} finally {
|
|
1336
|
-
await target.close();
|
|
1337
|
-
}
|
|
1338
|
-
if (process.platform !== "win32") {
|
|
1339
|
-
const directory = await promises.open(path.dirname(filePath), "r");
|
|
1340
|
-
try {
|
|
1341
|
-
await directory.sync();
|
|
1342
|
-
} finally {
|
|
1343
|
-
await directory.close();
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1347
|
-
}
|
|
1348
|
-
var RENAME_RETRY_ATTEMPTS = 5;
|
|
1349
|
-
var RENAME_RETRY_DELAY_MS = 20;
|
|
1350
|
-
function delay(ms) {
|
|
1351
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1352
|
-
}
|
|
1353
|
-
async function renameOnto(tmpPath, targetPath) {
|
|
1354
|
-
for (let attempt = 1; attempt <= RENAME_RETRY_ATTEMPTS; attempt++) {
|
|
1355
|
-
try {
|
|
1356
|
-
await promises.rename(tmpPath, targetPath);
|
|
1357
|
-
return;
|
|
1358
|
-
} catch (err) {
|
|
1359
|
-
const code = err.code;
|
|
1360
|
-
if (code !== "EPERM" && code !== "EEXIST") {
|
|
1361
|
-
await promises.rm(tmpPath, { force: true }).catch(() => {
|
|
1362
|
-
});
|
|
1363
|
-
throw err;
|
|
1364
|
-
}
|
|
1365
|
-
if (attempt === RENAME_RETRY_ATTEMPTS) {
|
|
1366
|
-
await promises.rm(tmpPath, { force: true }).catch(() => {
|
|
1367
|
-
});
|
|
1368
|
-
throw err;
|
|
1369
|
-
}
|
|
1370
|
-
await delay(RENAME_RETRY_DELAY_MS * attempt);
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
1491
|
var defaultRunner = (command, args) => new Promise((resolve, reject) => {
|
|
1375
1492
|
execFile(command, args, (error, stdout, stderr) => {
|
|
1376
1493
|
if (error && typeof error.code !== "number") {
|
|
@@ -1461,7 +1578,7 @@ function isProtected(record) {
|
|
|
1461
1578
|
var GitWorkspaceStore = class {
|
|
1462
1579
|
constructor(storeDir, options = {}) {
|
|
1463
1580
|
this.storeDir = storeDir;
|
|
1464
|
-
this.filePath =
|
|
1581
|
+
this.filePath = path2.join(storeDir, FILE_NAME);
|
|
1465
1582
|
this.maxRecords = Math.max(1, Math.floor(options.maxRecords ?? MAX_RECORDS));
|
|
1466
1583
|
}
|
|
1467
1584
|
storeDir;
|
|
@@ -1596,7 +1713,7 @@ var GitWorkspaceStore = class {
|
|
|
1596
1713
|
var BYOK_PI_MCP_CONFIG_PATH = "BYOK_PI_MCP_CONFIG_PATH";
|
|
1597
1714
|
var PI_PACKAGE_NAME = "@earendil-works/pi-coding-agent";
|
|
1598
1715
|
function readPackageJson(dir) {
|
|
1599
|
-
const candidate =
|
|
1716
|
+
const candidate = path2.join(dir, "package.json");
|
|
1600
1717
|
if (!existsSync(candidate)) return void 0;
|
|
1601
1718
|
try {
|
|
1602
1719
|
return JSON.parse(readFileSync(candidate, "utf8"));
|
|
@@ -1611,17 +1728,17 @@ function resolvePiBin() {
|
|
|
1611
1728
|
}
|
|
1612
1729
|
try {
|
|
1613
1730
|
const mainEntryUrl = import.meta.resolve(PI_PACKAGE_NAME);
|
|
1614
|
-
let dir =
|
|
1731
|
+
let dir = path2.dirname(fileURLToPath(mainEntryUrl));
|
|
1615
1732
|
for (let depth = 0; depth < 6; depth++) {
|
|
1616
1733
|
const pkg = readPackageJson(dir);
|
|
1617
1734
|
if (pkg?.name === PI_PACKAGE_NAME) {
|
|
1618
1735
|
const binRel = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.pi;
|
|
1619
1736
|
if (binRel) {
|
|
1620
|
-
return { command:
|
|
1737
|
+
return { command: path2.join(dir, binRel), source: "package" };
|
|
1621
1738
|
}
|
|
1622
1739
|
break;
|
|
1623
1740
|
}
|
|
1624
|
-
const parent =
|
|
1741
|
+
const parent = path2.dirname(dir);
|
|
1625
1742
|
if (parent === dir) break;
|
|
1626
1743
|
dir = parent;
|
|
1627
1744
|
}
|
|
@@ -1639,7 +1756,7 @@ function resolvePiExtensions() {
|
|
|
1639
1756
|
const clientManifest = fileURLToPath(import.meta.resolve("@byok-sdk/client/package.json"));
|
|
1640
1757
|
return {
|
|
1641
1758
|
webAccess: fileURLToPath(import.meta.resolve("pi-web-access/index.ts")),
|
|
1642
|
-
mcpAdapter:
|
|
1759
|
+
mcpAdapter: path2.join(path2.dirname(clientManifest), "dist", "adapters", "pi", "mcp-extension.js")
|
|
1643
1760
|
};
|
|
1644
1761
|
}
|
|
1645
1762
|
|
|
@@ -2565,10 +2682,10 @@ var PiAdapter = class {
|
|
|
2565
2682
|
const taskMcpServers = startInput.mcpServers ?? {};
|
|
2566
2683
|
const hasMcpServers = Object.keys(taskMcpServers).length > 0;
|
|
2567
2684
|
if (hasMcpServers) {
|
|
2568
|
-
mcpConfigDir = await promises.mkdtemp(
|
|
2685
|
+
mcpConfigDir = await promises.mkdtemp(path2.join(os6.tmpdir(), "byok-pi-mcp-"));
|
|
2569
2686
|
await promises.chmod(mcpConfigDir, 448).catch(() => {
|
|
2570
2687
|
});
|
|
2571
|
-
const mcpConfigPath =
|
|
2688
|
+
const mcpConfigPath = path2.join(mcpConfigDir, "mcp-config.json");
|
|
2572
2689
|
await promises.writeFile(mcpConfigPath, JSON.stringify({ mcpServers: taskMcpServers }), { mode: 384 });
|
|
2573
2690
|
runtimeEnv = { ...runtimeEnv, [BYOK_PI_MCP_CONFIG_PATH]: mcpConfigPath };
|
|
2574
2691
|
}
|
|
@@ -2799,7 +2916,7 @@ function resolveApprovalMcpBin() {
|
|
|
2799
2916
|
if (override) {
|
|
2800
2917
|
return { command: override, args: [], source: "env" };
|
|
2801
2918
|
}
|
|
2802
|
-
const distBin =
|
|
2919
|
+
const distBin = path2.join(path2.dirname(fileURLToPath(import.meta.url)), "bin", "byok-approval-mcp.js");
|
|
2803
2920
|
return { command: process.execPath, args: [distBin], source: "dist" };
|
|
2804
2921
|
}
|
|
2805
2922
|
|
|
@@ -2890,7 +3007,7 @@ var EXTENSION_CONTENT_TYPES = {
|
|
|
2890
3007
|
".yml": "application/yaml"
|
|
2891
3008
|
};
|
|
2892
3009
|
function guessContentType(filePath) {
|
|
2893
|
-
const ext =
|
|
3010
|
+
const ext = path2.extname(filePath).toLowerCase();
|
|
2894
3011
|
return EXTENSION_CONTENT_TYPES[ext] ?? "application/octet-stream";
|
|
2895
3012
|
}
|
|
2896
3013
|
function mapAssistant(msg, correlation) {
|
|
@@ -2974,11 +3091,11 @@ function tryBuildArtifactEvent(msg, workspaceDir) {
|
|
|
2974
3091
|
const filePath = toolUseResult && typeof toolUseResult.filePath === "string" ? toolUseResult.filePath : void 0;
|
|
2975
3092
|
if (!filePath) return void 0;
|
|
2976
3093
|
const realWorkspaceDir = tryRealpath(workspaceDir) ?? workspaceDir;
|
|
2977
|
-
const fileDir =
|
|
3094
|
+
const fileDir = path2.dirname(filePath);
|
|
2978
3095
|
const realFileDir = tryRealpath(fileDir) ?? fileDir;
|
|
2979
|
-
const realFilePath =
|
|
2980
|
-
const relative =
|
|
2981
|
-
if (relative === "" || relative.startsWith("..") ||
|
|
3096
|
+
const realFilePath = path2.join(realFileDir, path2.basename(filePath));
|
|
3097
|
+
const relative = path2.relative(realWorkspaceDir, realFilePath);
|
|
3098
|
+
if (relative === "" || relative.startsWith("..") || path2.isAbsolute(relative)) {
|
|
2982
3099
|
return void 0;
|
|
2983
3100
|
}
|
|
2984
3101
|
return { type: "artifact", name: relative, contentType: guessContentType(filePath) };
|
|
@@ -3372,10 +3489,10 @@ var ClaudeAdapter = class {
|
|
|
3372
3489
|
});
|
|
3373
3490
|
}
|
|
3374
3491
|
if (needsMcpConfig) {
|
|
3375
|
-
mcpConfigDir = await promises.mkdtemp(
|
|
3492
|
+
mcpConfigDir = await promises.mkdtemp(path2.join(os6.tmpdir(), "byok-mcp-"));
|
|
3376
3493
|
await promises.chmod(mcpConfigDir, 448).catch(() => {
|
|
3377
3494
|
});
|
|
3378
|
-
const mcpConfigPath =
|
|
3495
|
+
const mcpConfigPath = path2.join(mcpConfigDir, "mcp-config.json");
|
|
3379
3496
|
const mcpServers = { ...taskMcpServers };
|
|
3380
3497
|
if (mapping.needsApprovalMcp) {
|
|
3381
3498
|
const approvalChannel = startInput.approvalChannel;
|
|
@@ -3861,8 +3978,8 @@ function extractArtifactEvents(changes, workspaceDir) {
|
|
|
3861
3978
|
const absolutePath = typeof change.path === "string" ? change.path : void 0;
|
|
3862
3979
|
const kind = typeof change.kind === "string" ? change.kind : void 0;
|
|
3863
3980
|
if (!absolutePath || kind === "delete") continue;
|
|
3864
|
-
const relative =
|
|
3865
|
-
if (relative.length === 0 || relative.startsWith("..") ||
|
|
3981
|
+
const relative = path2.relative(workspaceDir, absolutePath);
|
|
3982
|
+
if (relative.length === 0 || relative.startsWith("..") || path2.isAbsolute(relative)) continue;
|
|
3866
3983
|
events.push({ type: "artifact", name: relative, contentType: guessContentType2(relative) });
|
|
3867
3984
|
}
|
|
3868
3985
|
return events;
|
|
@@ -3883,7 +4000,7 @@ var CONTENT_TYPE_BY_EXTENSION = {
|
|
|
3883
4000
|
".csv": "text/csv"
|
|
3884
4001
|
};
|
|
3885
4002
|
function guessContentType2(relativePath) {
|
|
3886
|
-
return CONTENT_TYPE_BY_EXTENSION[
|
|
4003
|
+
return CONTENT_TYPE_BY_EXTENSION[path2.extname(relativePath).toLowerCase()] ?? "application/octet-stream";
|
|
3887
4004
|
}
|
|
3888
4005
|
function extractErrorMessage(rawError) {
|
|
3889
4006
|
if (typeof rawError === "string") return rawError;
|
|
@@ -4739,12 +4856,12 @@ var DeviceStore = class _DeviceStore {
|
|
|
4739
4856
|
*/
|
|
4740
4857
|
constructor(storeDir, secureDirOptions) {
|
|
4741
4858
|
this.secureDirOptions = secureDirOptions;
|
|
4742
|
-
this.filePath =
|
|
4859
|
+
this.filePath = path2.join(storeDir, "device.json");
|
|
4743
4860
|
}
|
|
4744
4861
|
secureDirOptions;
|
|
4745
4862
|
filePath;
|
|
4746
4863
|
static defaultDir(productId) {
|
|
4747
|
-
return
|
|
4864
|
+
return path2.join(os6.homedir(), ".byok", productId);
|
|
4748
4865
|
}
|
|
4749
4866
|
/**
|
|
4750
4867
|
* Resolve the one store pathname every daemon/CLI component must share.
|
|
@@ -4753,7 +4870,7 @@ var DeviceStore = class _DeviceStore {
|
|
|
4753
4870
|
* cwd to pin a quarantine directory inode.
|
|
4754
4871
|
*/
|
|
4755
4872
|
static resolveDir(productId, configured) {
|
|
4756
|
-
return
|
|
4873
|
+
return path2.resolve(configured ?? _DeviceStore.defaultDir(productId));
|
|
4757
4874
|
}
|
|
4758
4875
|
async load() {
|
|
4759
4876
|
const opened = await this.openBounded();
|
|
@@ -4795,7 +4912,7 @@ var DeviceStore = class _DeviceStore {
|
|
|
4795
4912
|
}
|
|
4796
4913
|
async save(record) {
|
|
4797
4914
|
assertDeviceRecord(record);
|
|
4798
|
-
const storeDir =
|
|
4915
|
+
const storeDir = path2.dirname(this.filePath);
|
|
4799
4916
|
await ensureSecureDir(storeDir, this.secureDirOptions);
|
|
4800
4917
|
await atomicWriteFile(this.filePath, JSON.stringify(record, null, 2), { mode: 384 });
|
|
4801
4918
|
}
|
|
@@ -5449,19 +5566,19 @@ function shortHash(input) {
|
|
|
5449
5566
|
return createHash("sha256").update(input, "utf8").digest("hex").slice(0, 16);
|
|
5450
5567
|
}
|
|
5451
5568
|
function controlSocketPath(storeDir) {
|
|
5452
|
-
const candidate =
|
|
5569
|
+
const candidate = path2.join(storeDir, "control.sock");
|
|
5453
5570
|
if (Buffer.byteLength(candidate, "utf8") <= UNIX_SOCKET_PATH_SOFT_LIMIT) return candidate;
|
|
5454
|
-
return
|
|
5571
|
+
return path2.join(CONTROL_SOCKET_FALLBACK_ROOT, `byok-${shortHash(storeDir)}`, "sock");
|
|
5455
5572
|
}
|
|
5456
5573
|
function controlPipeName(productId, storeDir) {
|
|
5457
|
-
const id = shortHash(`${productId}|${
|
|
5574
|
+
const id = shortHash(`${productId}|${path2.resolve(storeDir)}`);
|
|
5458
5575
|
return `\\\\.\\pipe\\byok-${id}`;
|
|
5459
5576
|
}
|
|
5460
5577
|
function controlEndpointPath(productId, storeDir, platform = process.platform) {
|
|
5461
5578
|
return platform === "win32" ? controlPipeName(productId, storeDir) : controlSocketPath(storeDir);
|
|
5462
5579
|
}
|
|
5463
5580
|
function controlTokenPath(storeDir) {
|
|
5464
|
-
return
|
|
5581
|
+
return path2.join(storeDir, "control.token");
|
|
5465
5582
|
}
|
|
5466
5583
|
var SERVER_PROOF_LABEL = "byok-control-server|";
|
|
5467
5584
|
var CLIENT_AUTH_LABEL = "byok-control-client|";
|
|
@@ -5640,7 +5757,7 @@ async function assertOwnedPrivateDir(dir) {
|
|
|
5640
5757
|
}
|
|
5641
5758
|
async function bindControlEndpoint(server, endpoint) {
|
|
5642
5759
|
if (process.platform !== "win32") {
|
|
5643
|
-
const endpointDir =
|
|
5760
|
+
const endpointDir = path2.dirname(endpoint);
|
|
5644
5761
|
await promises.mkdir(endpointDir, { recursive: true, mode: 448 });
|
|
5645
5762
|
await promises.chmod(endpointDir, 448).catch(() => {
|
|
5646
5763
|
});
|
|
@@ -6539,7 +6656,7 @@ function toBytes(data, _isBinary) {
|
|
|
6539
6656
|
|
|
6540
6657
|
// src/daemon/connection-manager.ts
|
|
6541
6658
|
function isCursorEnvelopeType(type) {
|
|
6542
|
-
return type.startsWith("task.") || type === "agent.egress.ack" || type === "agent.content.read";
|
|
6659
|
+
return type.startsWith("task.") || type === "agent.egress.ack" || type === "agent.content.read" || type === "agent.home.projection";
|
|
6543
6660
|
}
|
|
6544
6661
|
var ConnectionManager = class {
|
|
6545
6662
|
constructor(opts) {
|
|
@@ -7054,6 +7171,10 @@ var ConnectionManager = class {
|
|
|
7054
7171
|
async process(envelope, tracked) {
|
|
7055
7172
|
const seq = tracked ? envelope.seq : void 0;
|
|
7056
7173
|
try {
|
|
7174
|
+
if (tracked && this.cursor === void 0) {
|
|
7175
|
+
await this.opts.cursorStore.save(this.opts.serverUrl, this.opts.deviceId, 0);
|
|
7176
|
+
this.cursor = 0;
|
|
7177
|
+
}
|
|
7057
7178
|
await this.opts.onEnvelope(envelope);
|
|
7058
7179
|
if (!tracked) return;
|
|
7059
7180
|
this.processedSeqs.add(seq);
|
|
@@ -7283,7 +7404,7 @@ function sameFileState2(left, right) {
|
|
|
7283
7404
|
return left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs;
|
|
7284
7405
|
}
|
|
7285
7406
|
async function openOperationalHealthFile(storeDir) {
|
|
7286
|
-
const filePath =
|
|
7407
|
+
const filePath = path2.join(storeDir, OPERATIONAL_HEALTH_FILENAME);
|
|
7287
7408
|
let namedBefore;
|
|
7288
7409
|
try {
|
|
7289
7410
|
namedBefore = await promises.lstat(filePath, { bigint: true });
|
|
@@ -7325,7 +7446,7 @@ var OperationalHealthTracker = class {
|
|
|
7325
7446
|
#writeTail = Promise.resolve();
|
|
7326
7447
|
#started = false;
|
|
7327
7448
|
constructor(storeDir, options = {}) {
|
|
7328
|
-
this.#filePath =
|
|
7449
|
+
this.#filePath = path2.join(storeDir, OPERATIONAL_HEALTH_FILENAME);
|
|
7329
7450
|
this.#windowMs = options.windowMs ?? 6e4;
|
|
7330
7451
|
this.#failureThreshold = options.failureThreshold ?? 3;
|
|
7331
7452
|
this.#maxFailures = options.maxFailures ?? 128;
|
|
@@ -7412,7 +7533,7 @@ var OperationalHealthTracker = class {
|
|
|
7412
7533
|
async #load() {
|
|
7413
7534
|
let opened;
|
|
7414
7535
|
try {
|
|
7415
|
-
opened = await openOperationalHealthFile(
|
|
7536
|
+
opened = await openOperationalHealthFile(path2.dirname(this.#filePath));
|
|
7416
7537
|
} catch (err) {
|
|
7417
7538
|
throw new Error("operational health state could not be read");
|
|
7418
7539
|
}
|
|
@@ -7448,7 +7569,7 @@ var OperationalHealthTracker = class {
|
|
|
7448
7569
|
if (!this.#state) return;
|
|
7449
7570
|
const body = JSON.stringify(this.#state, null, 2);
|
|
7450
7571
|
this.#writeTail = this.#writeTail.then(async () => {
|
|
7451
|
-
await ensureSecureDir(
|
|
7572
|
+
await ensureSecureDir(path2.dirname(this.#filePath));
|
|
7452
7573
|
await atomicWriteFile(this.#filePath, body, { mode: 384, fsync: true });
|
|
7453
7574
|
});
|
|
7454
7575
|
try {
|
|
@@ -7539,9 +7660,9 @@ function storeMutexIdentity(canonicalStoreDir) {
|
|
|
7539
7660
|
}
|
|
7540
7661
|
function storeMutexEndpoint(canonicalStoreDir, identity, platform = process.platform) {
|
|
7541
7662
|
if (platform === "win32") return `\\\\.\\pipe\\byok-store-mutex-${identity.slice(0, 16)}`;
|
|
7542
|
-
const candidate =
|
|
7663
|
+
const candidate = path2.join(canonicalStoreDir, STORE_MUTEX_SOCKET_FILENAME);
|
|
7543
7664
|
if (Buffer.byteLength(candidate, "utf8") <= UNIX_SOCKET_PATH_SOFT_LIMIT2) return candidate;
|
|
7544
|
-
return
|
|
7665
|
+
return path2.join(STORE_MUTEX_FALLBACK_ROOT, `byok-store-mutex-${identity.slice(0, 16)}`, "sock");
|
|
7545
7666
|
}
|
|
7546
7667
|
var DaemonOwnerActiveError = class extends Error {
|
|
7547
7668
|
constructor(role) {
|
|
@@ -7713,7 +7834,7 @@ async function acquireStoreMutex(canonicalStoreDir) {
|
|
|
7713
7834
|
const endpoint = storeMutexEndpoint(canonicalStoreDir, identity);
|
|
7714
7835
|
const isPipe = process.platform === "win32";
|
|
7715
7836
|
if (!isPipe) {
|
|
7716
|
-
const endpointDir =
|
|
7837
|
+
const endpointDir = path2.dirname(endpoint);
|
|
7717
7838
|
if (endpointDir !== canonicalStoreDir) {
|
|
7718
7839
|
await ensureSecureDir(endpointDir);
|
|
7719
7840
|
await assertOwnedPrivateDir2(endpointDir);
|
|
@@ -7793,8 +7914,8 @@ async function acquireDaemonOwner(storeDir, role, clock = () => /* @__PURE__ */
|
|
|
7793
7914
|
await mutex.close().catch(() => void 0);
|
|
7794
7915
|
throw err;
|
|
7795
7916
|
}
|
|
7796
|
-
const ownerPath =
|
|
7797
|
-
const reclaimPath =
|
|
7917
|
+
const ownerPath = path2.join(storeDir, DAEMON_OWNER_FILENAME);
|
|
7918
|
+
const reclaimPath = path2.join(storeDir, RECLAIM_FILENAME);
|
|
7798
7919
|
const record = {
|
|
7799
7920
|
version: 2,
|
|
7800
7921
|
pid: process.pid,
|
|
@@ -7872,7 +7993,7 @@ var CursorStore = class {
|
|
|
7872
7993
|
storeDir;
|
|
7873
7994
|
fileFor(serverUrl, deviceId) {
|
|
7874
7995
|
const key = createHash("sha256").update(`${serverUrl}::${deviceId}`).digest("hex").slice(0, 32);
|
|
7875
|
-
return
|
|
7996
|
+
return path2.join(this.storeDir, `cursor-${key}.json`);
|
|
7876
7997
|
}
|
|
7877
7998
|
async load(serverUrl, deviceId) {
|
|
7878
7999
|
let raw;
|
|
@@ -7892,7 +8013,7 @@ var CursorStore = class {
|
|
|
7892
8013
|
}
|
|
7893
8014
|
async save(serverUrl, deviceId, cursor) {
|
|
7894
8015
|
const file = this.fileFor(serverUrl, deviceId);
|
|
7895
|
-
await promises.mkdir(
|
|
8016
|
+
await promises.mkdir(path2.dirname(file), { recursive: true, mode: 448 });
|
|
7896
8017
|
await atomicWriteFile(file, JSON.stringify({ cursor }));
|
|
7897
8018
|
}
|
|
7898
8019
|
/** Remove any persisted cursor for (serverUrl, deviceId) — a no-op if none exists. Called from `pair()` (finding F5) so a device that's about to be replaced never leaves a cursor a future, unrelated device could somehow inherit. */
|
|
@@ -8222,7 +8343,7 @@ var SessionWorkspaceStore = class {
|
|
|
8222
8343
|
*/
|
|
8223
8344
|
queue = Promise.resolve();
|
|
8224
8345
|
constructor(storeDir) {
|
|
8225
|
-
this.filePath =
|
|
8346
|
+
this.filePath = path2.join(storeDir, "session-workspaces.json");
|
|
8226
8347
|
}
|
|
8227
8348
|
async get(sessionRef) {
|
|
8228
8349
|
return this.enqueue(async () => {
|
|
@@ -8280,7 +8401,7 @@ var SessionWorkspaceStore = class {
|
|
|
8280
8401
|
}
|
|
8281
8402
|
}
|
|
8282
8403
|
async save(all) {
|
|
8283
|
-
const dir =
|
|
8404
|
+
const dir = path2.dirname(this.filePath);
|
|
8284
8405
|
await promises.mkdir(dir, { recursive: true, mode: 448 });
|
|
8285
8406
|
const tmpPath = `${this.filePath}.${process.pid}-${tmpSeq2++}.tmp`;
|
|
8286
8407
|
try {
|
|
@@ -9827,6 +9948,11 @@ function offeredAgentRef(payload) {
|
|
|
9827
9948
|
if (!Object.prototype.hasOwnProperty.call(payload, "agentRef")) return void 0;
|
|
9828
9949
|
return validateAgentRef(payload.agentRef);
|
|
9829
9950
|
}
|
|
9951
|
+
function offeredSessionRef(payload) {
|
|
9952
|
+
if (!Object.prototype.hasOwnProperty.call(payload, "sessionRef")) return void 0;
|
|
9953
|
+
const value = payload.sessionRef;
|
|
9954
|
+
return typeof value === "string" ? value : void 0;
|
|
9955
|
+
}
|
|
9830
9956
|
function errorMessage4(err) {
|
|
9831
9957
|
return err instanceof Error ? err.message : String(err);
|
|
9832
9958
|
}
|
|
@@ -9862,8 +9988,8 @@ function estimateEventBytes(event) {
|
|
|
9862
9988
|
}
|
|
9863
9989
|
async function openArtifact(workspaceDir, name) {
|
|
9864
9990
|
const realWorkspaceDir = await promises.realpath(workspaceDir).catch(() => workspaceDir);
|
|
9865
|
-
const candidate =
|
|
9866
|
-
const prefix = realWorkspaceDir.endsWith(
|
|
9991
|
+
const candidate = path2.resolve(realWorkspaceDir, name);
|
|
9992
|
+
const prefix = realWorkspaceDir.endsWith(path2.sep) ? realWorkspaceDir : realWorkspaceDir + path2.sep;
|
|
9867
9993
|
if (candidate !== realWorkspaceDir && !candidate.startsWith(prefix)) {
|
|
9868
9994
|
return { ok: false, reason: `artifact name "${name}" resolves outside the task workspace \u2014 rejected` };
|
|
9869
9995
|
}
|
|
@@ -10195,6 +10321,9 @@ var TaskRunner = class {
|
|
|
10195
10321
|
case "task.offer_for_agent_with_egress":
|
|
10196
10322
|
await this.handleOffer(envelope.task_id, envelope.payload, true);
|
|
10197
10323
|
return;
|
|
10324
|
+
case "task.offer_for_agent_with_egress_fresh":
|
|
10325
|
+
await this.handleOffer(envelope.task_id, envelope.payload, true);
|
|
10326
|
+
return;
|
|
10198
10327
|
case "task.cancel":
|
|
10199
10328
|
await this.handleCancel(envelope.task_id, envelope.payload.reason);
|
|
10200
10329
|
return;
|
|
@@ -10236,6 +10365,7 @@ var TaskRunner = class {
|
|
|
10236
10365
|
const decline = (reason, retryable) => {
|
|
10237
10366
|
this.decline(taskId, reason, retryable, agentRef);
|
|
10238
10367
|
};
|
|
10368
|
+
const sessionRef = offeredSessionRef(payload);
|
|
10239
10369
|
if ("egressPolicy" in payload) {
|
|
10240
10370
|
if (this.deps.agentEgressPolicy === void 0 || !sameEgressPolicy(this.deps.agentEgressPolicy, payload.egressPolicy)) {
|
|
10241
10371
|
decline("Agent egress offer policy is not exactly enabled by this daemon", false);
|
|
@@ -10337,11 +10467,11 @@ var TaskRunner = class {
|
|
|
10337
10467
|
let plainWorkspaceNeedsResolve = false;
|
|
10338
10468
|
if (agentBinding !== void 0) {
|
|
10339
10469
|
workspaceDir = agentBinding.lease.cwd;
|
|
10340
|
-
if (
|
|
10470
|
+
if (sessionRef !== void 0) {
|
|
10341
10471
|
try {
|
|
10342
10472
|
await this.deps.agentSessionHandoffs.requireMatch({
|
|
10343
10473
|
agentRef: agentBinding.resolution.agentRef,
|
|
10344
|
-
sessionRef
|
|
10474
|
+
sessionRef,
|
|
10345
10475
|
runtimeId: pick.descriptor.id,
|
|
10346
10476
|
cwd: workspaceDir
|
|
10347
10477
|
});
|
|
@@ -10363,15 +10493,15 @@ var TaskRunner = class {
|
|
|
10363
10493
|
return;
|
|
10364
10494
|
}
|
|
10365
10495
|
} else if (this.deps.gitWorkspaceManager && this.deps.gitWorkspaceStore) {
|
|
10366
|
-
known =
|
|
10496
|
+
known = sessionRef ? await this.deps.sessionWorkspaces.get(sessionRef) : void 0;
|
|
10367
10497
|
const gitManager = this.deps.gitWorkspaceManager;
|
|
10368
10498
|
const gitStore = this.deps.gitWorkspaceStore;
|
|
10369
|
-
if (
|
|
10370
|
-
const ledger = await gitStore.findBySessionAnyPhase(
|
|
10499
|
+
if (sessionRef) {
|
|
10500
|
+
const ledger = await gitStore.findBySessionAnyPhase(sessionRef).catch(() => void 0);
|
|
10371
10501
|
const sameProtocolTask = ledger?.taskId === taskId;
|
|
10372
10502
|
const interruptedOldTask = ledger?.phase === "interrupted" && sameProtocolTask;
|
|
10373
10503
|
const activeDifferentTask = ledger !== void 0 && ledger.taskId !== taskId && (ledger.phase === "preparing" || ledger.phase === "active");
|
|
10374
|
-
if (!known || known.workspaceKind !== "git" || !known.gitWorkspaceId || !ledger || ledger.workspaceId !== known.gitWorkspaceId || ledger.sessionRef !==
|
|
10504
|
+
if (!known || known.workspaceKind !== "git" || !known.gitWorkspaceId || !ledger || ledger.workspaceId !== known.gitWorkspaceId || ledger.sessionRef !== sessionRef || path2.resolve(ledger.workspaceDir) !== path2.resolve(known.workspaceDir) || interruptedOldTask || activeDifferentTask) {
|
|
10375
10505
|
decline("session is incompatible with Git workspace mode", true);
|
|
10376
10506
|
return;
|
|
10377
10507
|
}
|
|
@@ -10386,18 +10516,18 @@ var TaskRunner = class {
|
|
|
10386
10516
|
return;
|
|
10387
10517
|
}
|
|
10388
10518
|
} else {
|
|
10389
|
-
workspaceDir =
|
|
10519
|
+
workspaceDir = path2.join(this.deps.workspaceRoot, taskId);
|
|
10390
10520
|
gitWorkspaceId = randomUUID();
|
|
10391
10521
|
}
|
|
10392
10522
|
try {
|
|
10393
|
-
gitLease = await gitManager.acquireLease(workspaceDir,
|
|
10523
|
+
gitLease = await gitManager.acquireLease(workspaceDir, sessionRef);
|
|
10394
10524
|
} catch {
|
|
10395
10525
|
decline("workspace is busy or unavailable", true);
|
|
10396
10526
|
return;
|
|
10397
10527
|
}
|
|
10398
10528
|
} else if (!this.deps.gitWorkspaceManager && !this.deps.gitWorkspaceStore) {
|
|
10399
|
-
known =
|
|
10400
|
-
workspaceDir = known?.workspaceDir ??
|
|
10529
|
+
known = sessionRef ? await this.deps.sessionWorkspaces.get(sessionRef) : void 0;
|
|
10530
|
+
workspaceDir = known?.workspaceDir ?? path2.join(this.deps.workspaceRoot, taskId);
|
|
10401
10531
|
plainWorkspaceNeedsResolve = true;
|
|
10402
10532
|
} else {
|
|
10403
10533
|
decline("workspace mode is unavailable", true);
|
|
@@ -10415,7 +10545,7 @@ var TaskRunner = class {
|
|
|
10415
10545
|
policy: decision.policy,
|
|
10416
10546
|
requiredToolsetIds: requiredToolsets ?? [],
|
|
10417
10547
|
...offered.dispatchSelection === void 0 ? {} : { dispatchSelection: offered.dispatchSelection },
|
|
10418
|
-
...
|
|
10548
|
+
...sessionRef === void 0 || known === void 0 && agentBinding === void 0 ? {} : { sessionRef },
|
|
10419
10549
|
...agentBinding === void 0 ? {} : {
|
|
10420
10550
|
agentRef: agentBinding.resolution.agentRef,
|
|
10421
10551
|
cwd: agentBinding.lease.cwd,
|
|
@@ -10518,7 +10648,7 @@ var TaskRunner = class {
|
|
|
10518
10648
|
workspaceId,
|
|
10519
10649
|
taskId,
|
|
10520
10650
|
workspaceDir,
|
|
10521
|
-
sessionRef
|
|
10651
|
+
sessionRef,
|
|
10522
10652
|
phase,
|
|
10523
10653
|
baseline: gitBaseline ?? observation.head,
|
|
10524
10654
|
current: observation.head,
|
|
@@ -11784,7 +11914,7 @@ var TaskRunner = class {
|
|
|
11784
11914
|
}
|
|
11785
11915
|
/** `reuseDir`, when set (a known sessionRef's recorded workspace), is used verbatim instead of a fresh `workspaceRoot/<taskId>` directory — `mkdir recursive` is idempotent either way, so ensuring-exists is safe to do unconditionally. */
|
|
11786
11916
|
async resolveWorkspaceDir(taskId, reuseDir) {
|
|
11787
|
-
const dir = reuseDir ??
|
|
11917
|
+
const dir = reuseDir ?? path2.join(this.deps.workspaceRoot, taskId);
|
|
11788
11918
|
await promises.mkdir(dir, { recursive: true });
|
|
11789
11919
|
return dir;
|
|
11790
11920
|
}
|
|
@@ -11922,7 +12052,7 @@ var encoder2 = new TextEncoder();
|
|
|
11922
12052
|
function eventBytes(event) {
|
|
11923
12053
|
return encoder2.encode(JSON.stringify(event)).length;
|
|
11924
12054
|
}
|
|
11925
|
-
var AGENT_EGRESS_DIRECTORY =
|
|
12055
|
+
var AGENT_EGRESS_DIRECTORY = path2.join(".byok", "egress");
|
|
11926
12056
|
var AGENT_RELIABLE_SPOOL_FILENAME = "reliable-v1.jsonl";
|
|
11927
12057
|
var AgentReliableSpoolError = class extends Error {
|
|
11928
12058
|
constructor(message) {
|
|
@@ -12033,9 +12163,9 @@ var AgentReliableSpool = class _AgentReliableSpool {
|
|
|
12033
12163
|
logEntries = 0;
|
|
12034
12164
|
writeTail = Promise.resolve();
|
|
12035
12165
|
static async open(homeDir) {
|
|
12036
|
-
const directory =
|
|
12166
|
+
const directory = path2.join(homeDir, AGENT_EGRESS_DIRECTORY);
|
|
12037
12167
|
await ensureSecureDir(directory);
|
|
12038
|
-
const spool = new _AgentReliableSpool(homeDir,
|
|
12168
|
+
const spool = new _AgentReliableSpool(homeDir, path2.join(directory, AGENT_RELIABLE_SPOOL_FILENAME));
|
|
12039
12169
|
await spool.load();
|
|
12040
12170
|
return spool;
|
|
12041
12171
|
}
|
|
@@ -12498,7 +12628,7 @@ var AgentEgressController = class {
|
|
|
12498
12628
|
}
|
|
12499
12629
|
/** Re-open every existing Agent-local spool before retrying stable records after restart. */
|
|
12500
12630
|
async recover(agentsRoot) {
|
|
12501
|
-
if (!
|
|
12631
|
+
if (!path2.isAbsolute(agentsRoot)) throw new Error("Agent egress recovery root must be absolute");
|
|
12502
12632
|
if (!this.active) throw new Error("Agent egress recovery requires an active authenticated enrollment");
|
|
12503
12633
|
if (this.options.tenantId === void 0) {
|
|
12504
12634
|
throw new Error("Agent egress recovery requires one authenticated tenant authority");
|
|
@@ -12513,14 +12643,14 @@ var AgentEgressController = class {
|
|
|
12513
12643
|
}
|
|
12514
12644
|
for (const entry of entries) {
|
|
12515
12645
|
if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
|
|
12516
|
-
const homeDir =
|
|
12646
|
+
const homeDir = path2.join(canonicalAgentsRoot, entry.name);
|
|
12517
12647
|
const canonicalHome = await promises.realpath(homeDir);
|
|
12518
|
-
const relativeHome =
|
|
12519
|
-
if (relativeHome !== entry.name || relativeHome.includes(
|
|
12648
|
+
const relativeHome = path2.relative(canonicalAgentsRoot, canonicalHome);
|
|
12649
|
+
if (relativeHome !== entry.name || relativeHome.includes(path2.sep) || path2.isAbsolute(relativeHome)) {
|
|
12520
12650
|
throw new Error(`Agent egress recovery home escaped the canonical agents root: ${entry.name}`);
|
|
12521
12651
|
}
|
|
12522
12652
|
try {
|
|
12523
|
-
await promises.lstat(
|
|
12653
|
+
await promises.lstat(path2.join(homeDir, AGENT_EGRESS_DIRECTORY));
|
|
12524
12654
|
} catch (error) {
|
|
12525
12655
|
if (error.code === "ENOENT") continue;
|
|
12526
12656
|
throw error;
|
|
@@ -12607,12 +12737,12 @@ function isAgentRef(value) {
|
|
|
12607
12737
|
}
|
|
12608
12738
|
function isCanonicalRelativeTarget(value) {
|
|
12609
12739
|
if (value === "[invalid-target]") return true;
|
|
12610
|
-
if (
|
|
12740
|
+
if (path2.isAbsolute(value) || value.includes("\\")) return false;
|
|
12611
12741
|
const segments = value.split("/");
|
|
12612
12742
|
return value.length > 0 && segments.every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
|
|
12613
12743
|
}
|
|
12614
12744
|
function validateIdentity(value, label) {
|
|
12615
|
-
if (!isRecord4(value) || !isAgentRef(value.agentRef) || !isNonEmptyString(value.sessionRef) || !isNonEmptyString(value.runtimeId) || !isNonEmptyString(value.cwd) || !
|
|
12745
|
+
if (!isRecord4(value) || !isAgentRef(value.agentRef) || !isNonEmptyString(value.sessionRef) || !isNonEmptyString(value.runtimeId) || !isNonEmptyString(value.cwd) || !path2.isAbsolute(value.cwd)) {
|
|
12616
12746
|
throw new AgentContentAuditStoreError(`${label} has an invalid exact Agent/session identity`);
|
|
12617
12747
|
}
|
|
12618
12748
|
return Object.freeze({
|
|
@@ -12622,7 +12752,7 @@ function validateIdentity(value, label) {
|
|
|
12622
12752
|
}),
|
|
12623
12753
|
sessionRef: value.sessionRef,
|
|
12624
12754
|
runtimeId: value.runtimeId,
|
|
12625
|
-
cwd:
|
|
12755
|
+
cwd: path2.resolve(value.cwd)
|
|
12626
12756
|
});
|
|
12627
12757
|
}
|
|
12628
12758
|
function validateReceipt(value) {
|
|
@@ -12704,16 +12834,16 @@ function assertUniqueRequestIds(entries) {
|
|
|
12704
12834
|
}
|
|
12705
12835
|
}
|
|
12706
12836
|
function assertAbsoluteFilePath(filePath) {
|
|
12707
|
-
if (typeof filePath !== "string" || filePath.length === 0 || !
|
|
12837
|
+
if (typeof filePath !== "string" || filePath.length === 0 || !path2.isAbsolute(filePath)) {
|
|
12708
12838
|
throw new AgentContentAuditStoreError("content audit path must be absolute");
|
|
12709
12839
|
}
|
|
12710
12840
|
if (/[\u0000\r\n]/u.test(filePath)) {
|
|
12711
12841
|
throw new AgentContentAuditStoreError("content audit path must not contain NUL or line breaks");
|
|
12712
12842
|
}
|
|
12713
|
-
return
|
|
12843
|
+
return path2.resolve(filePath);
|
|
12714
12844
|
}
|
|
12715
12845
|
async function ensureDirectoryNoSymlink2(directory) {
|
|
12716
|
-
const absolute =
|
|
12846
|
+
const absolute = path2.resolve(directory);
|
|
12717
12847
|
await promises.mkdir(absolute, { recursive: true, mode: 448 });
|
|
12718
12848
|
const stat = await promises.lstat(absolute);
|
|
12719
12849
|
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
@@ -12747,12 +12877,12 @@ var AgentContentAuditStore = class _AgentContentAuditStore {
|
|
|
12747
12877
|
/** The daemon may address this ledger only through an AgentHomeLayout resolution. */
|
|
12748
12878
|
static forCanonicalAgentHome(canonicalHome) {
|
|
12749
12879
|
const home = assertAbsoluteFilePath(canonicalHome);
|
|
12750
|
-
return new _AgentContentAuditStore(
|
|
12880
|
+
return new _AgentContentAuditStore(path2.join(home, AGENT_HOME_INTERNAL_DIRECTORY, AGENT_CONTENT_AUDIT_FILENAME));
|
|
12751
12881
|
}
|
|
12752
12882
|
async append(receipt) {
|
|
12753
12883
|
const validated = validateReceipt(receipt);
|
|
12754
12884
|
return this.enqueue(async () => {
|
|
12755
|
-
await ensureDirectoryNoSymlink2(
|
|
12885
|
+
await ensureDirectoryNoSymlink2(path2.dirname(this.filePath));
|
|
12756
12886
|
await assertAuditFile(this.filePath);
|
|
12757
12887
|
const entries = await this.readAllUnlocked();
|
|
12758
12888
|
const prior = entries.find((entry) => entry.requestId === validated.requestId);
|
|
@@ -12847,6 +12977,63 @@ var AgentContentAuditStore = class _AgentContentAuditStore {
|
|
|
12847
12977
|
return result;
|
|
12848
12978
|
}
|
|
12849
12979
|
};
|
|
12980
|
+
var AgentHomeProjectionCompletionError = class extends Error {
|
|
12981
|
+
constructor(message, options) {
|
|
12982
|
+
super(message, options);
|
|
12983
|
+
this.name = "AgentHomeProjectionCompletionError";
|
|
12984
|
+
}
|
|
12985
|
+
};
|
|
12986
|
+
function sameAgentRef2(left, right) {
|
|
12987
|
+
return left.agentId === right.agentId && left.profileRevision === right.profileRevision;
|
|
12988
|
+
}
|
|
12989
|
+
var AgentHomeProjectionCompletionClient = class {
|
|
12990
|
+
constructor(options) {
|
|
12991
|
+
this.options = options;
|
|
12992
|
+
}
|
|
12993
|
+
options;
|
|
12994
|
+
async complete(input) {
|
|
12995
|
+
const completion = AgentHomeProjectionCompletionRequestSchema.parse(input);
|
|
12996
|
+
const url = new URL(
|
|
12997
|
+
byokAgentHomeProjectionCompletionPath(completion.requestId),
|
|
12998
|
+
toHttpBase(this.options.serverUrl)
|
|
12999
|
+
);
|
|
13000
|
+
let response;
|
|
13001
|
+
try {
|
|
13002
|
+
response = await authedFetch(
|
|
13003
|
+
url,
|
|
13004
|
+
{
|
|
13005
|
+
method: "PUT",
|
|
13006
|
+
headers: { "content-type": "application/json" },
|
|
13007
|
+
body: JSON.stringify(completion)
|
|
13008
|
+
},
|
|
13009
|
+
this.options.auth
|
|
13010
|
+
);
|
|
13011
|
+
} catch (error) {
|
|
13012
|
+
throw new AgentHomeProjectionCompletionError("Agent-home projection completion transport failed", {
|
|
13013
|
+
cause: error
|
|
13014
|
+
});
|
|
13015
|
+
}
|
|
13016
|
+
if (!response.ok) {
|
|
13017
|
+
throw new AgentHomeProjectionCompletionError(
|
|
13018
|
+
`Agent-home projection completion was rejected with HTTP ${response.status}`
|
|
13019
|
+
);
|
|
13020
|
+
}
|
|
13021
|
+
let readback;
|
|
13022
|
+
try {
|
|
13023
|
+
readback = AgentHomeProjectionReadbackSchema.parse(await response.json());
|
|
13024
|
+
} catch (error) {
|
|
13025
|
+
throw new AgentHomeProjectionCompletionError("Agent-home projection completion readback is invalid", {
|
|
13026
|
+
cause: error
|
|
13027
|
+
});
|
|
13028
|
+
}
|
|
13029
|
+
if (readback.tenantId !== this.options.tenantId || readback.deviceId !== this.options.deviceId || readback.requestId !== completion.requestId || !sameAgentRef2(readback.agentRef, completion.agentRef) || readback.projectionHash !== completion.projectionHash || readback.status !== completion.outcome || readback.completedAt === void 0) {
|
|
13030
|
+
throw new AgentHomeProjectionCompletionError(
|
|
13031
|
+
"Agent-home projection completion readback does not exactly match the authenticated request"
|
|
13032
|
+
);
|
|
13033
|
+
}
|
|
13034
|
+
return readback;
|
|
13035
|
+
}
|
|
13036
|
+
};
|
|
12850
13037
|
var AGENT_CONTENT_READ_SURFACES = ["workspace", "transcript", "artifact"];
|
|
12851
13038
|
var AGENT_CONTENT_READ_CAPABILITIES = Object.freeze({
|
|
12852
13039
|
workspace: AGENT_CONTENT_WORKSPACE_READ_CAPABILITY,
|
|
@@ -12950,8 +13137,8 @@ function normalizeIdentity(value, field) {
|
|
|
12950
13137
|
const sessionRef = nonEmptyString(value.sessionRef, `${field}.sessionRef`);
|
|
12951
13138
|
const runtimeId = nonEmptyString(value.runtimeId, `${field}.runtimeId`);
|
|
12952
13139
|
const cwd = nonEmptyString(value.cwd, `${field}.cwd`);
|
|
12953
|
-
if (!
|
|
12954
|
-
return Object.freeze({ agentRef, sessionRef, runtimeId, cwd:
|
|
13140
|
+
if (!path2.isAbsolute(cwd)) throw new AgentContentReadPolicyError(`${field}.cwd must be absolute`);
|
|
13141
|
+
return Object.freeze({ agentRef, sessionRef, runtimeId, cwd: path2.resolve(cwd) });
|
|
12955
13142
|
}
|
|
12956
13143
|
function createAgentContentReadPolicy(input) {
|
|
12957
13144
|
if (!isRecord5(input) || input.enabled !== true) {
|
|
@@ -12979,10 +13166,10 @@ function createAgentContentReadPolicy(input) {
|
|
|
12979
13166
|
root = Object.freeze({ kind: "agent-home" });
|
|
12980
13167
|
} else if (input.root.kind === "runtime-allowlisted") {
|
|
12981
13168
|
const configuredRoot = nonEmptyString(input.root.root, "contentRead.root.root");
|
|
12982
|
-
if (!
|
|
13169
|
+
if (!path2.isAbsolute(configuredRoot)) {
|
|
12983
13170
|
throw new AgentContentReadPolicyError("contentRead.root.root must be absolute");
|
|
12984
13171
|
}
|
|
12985
|
-
root = Object.freeze({ kind: "runtime-allowlisted", root:
|
|
13172
|
+
root = Object.freeze({ kind: "runtime-allowlisted", root: path2.resolve(configuredRoot) });
|
|
12986
13173
|
} else {
|
|
12987
13174
|
throw new AgentContentReadPolicyError("contentRead.root.kind is not supported");
|
|
12988
13175
|
}
|
|
@@ -13005,11 +13192,11 @@ function createAgentContentReadPolicy(input) {
|
|
|
13005
13192
|
});
|
|
13006
13193
|
}
|
|
13007
13194
|
function isWithin2(root, candidate) {
|
|
13008
|
-
const relative =
|
|
13009
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${
|
|
13195
|
+
const relative = path2.relative(root, candidate);
|
|
13196
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${path2.sep}`) && !path2.isAbsolute(relative);
|
|
13010
13197
|
}
|
|
13011
13198
|
function isPortableAbsoluteTarget(value) {
|
|
13012
|
-
return
|
|
13199
|
+
return path2.isAbsolute(value) || /^[a-z]:[\\/]/iu.test(value) || /^[/\\]/u.test(value);
|
|
13013
13200
|
}
|
|
13014
13201
|
function canonicalAuditTarget(value) {
|
|
13015
13202
|
if (typeof value !== "string" || value.length === 0 || /[\u0000\r\n]/u.test(value) || isPortableAbsoluteTarget(value) || value.includes("\\")) {
|
|
@@ -13047,7 +13234,7 @@ function isSensitiveTarget(segments, productNames) {
|
|
|
13047
13234
|
return segments.some((segment) => patterns.some((pattern) => nameMatches(pattern, segment)));
|
|
13048
13235
|
}
|
|
13049
13236
|
async function resolveExistingAncestor2(inputPath) {
|
|
13050
|
-
let cursor =
|
|
13237
|
+
let cursor = path2.resolve(inputPath);
|
|
13051
13238
|
const tail = [];
|
|
13052
13239
|
for (; ; ) {
|
|
13053
13240
|
try {
|
|
@@ -13055,9 +13242,9 @@ async function resolveExistingAncestor2(inputPath) {
|
|
|
13055
13242
|
} catch (error) {
|
|
13056
13243
|
const code = error.code;
|
|
13057
13244
|
if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
|
|
13058
|
-
const parent =
|
|
13245
|
+
const parent = path2.dirname(cursor);
|
|
13059
13246
|
if (parent === cursor) throw new TargetPolicyError("target-missing");
|
|
13060
|
-
tail.unshift(
|
|
13247
|
+
tail.unshift(path2.basename(cursor));
|
|
13061
13248
|
cursor = parent;
|
|
13062
13249
|
}
|
|
13063
13250
|
}
|
|
@@ -13078,11 +13265,11 @@ var RootPolicyError = class extends Error {
|
|
|
13078
13265
|
this.reason = reason;
|
|
13079
13266
|
}
|
|
13080
13267
|
};
|
|
13081
|
-
function
|
|
13268
|
+
function sameAgentRef3(left, right) {
|
|
13082
13269
|
return left.agentId === right.agentId && left.profileRevision === right.profileRevision;
|
|
13083
13270
|
}
|
|
13084
13271
|
function sameSessionIdentity(left, right) {
|
|
13085
|
-
return
|
|
13272
|
+
return sameAgentRef3(left.agentRef, right.agentRef) && left.sessionRef === right.sessionRef && left.runtimeId === right.runtimeId && left.cwd === right.cwd;
|
|
13086
13273
|
}
|
|
13087
13274
|
function validateRequest(request) {
|
|
13088
13275
|
if (!isRecord5(request)) throw new AgentContentReadRequestError("content read request must be an object");
|
|
@@ -13144,18 +13331,18 @@ function normalizeRequestIdentity(value, field) {
|
|
|
13144
13331
|
const sessionRef = requestString(value.sessionRef, `${field}.sessionRef`);
|
|
13145
13332
|
const runtimeId = requestString(value.runtimeId, `${field}.runtimeId`);
|
|
13146
13333
|
const cwd = requestString(value.cwd, `${field}.cwd`);
|
|
13147
|
-
if (!
|
|
13148
|
-
return Object.freeze({ agentRef, sessionRef, runtimeId, cwd:
|
|
13334
|
+
if (!path2.isAbsolute(cwd)) throw new AgentContentReadRequestError(`${field}.cwd must be absolute`);
|
|
13335
|
+
return Object.freeze({ agentRef, sessionRef, runtimeId, cwd: path2.resolve(cwd) });
|
|
13149
13336
|
}
|
|
13150
13337
|
async function inspectRegularTarget(root, target) {
|
|
13151
13338
|
const ancestor = await resolveExistingAncestor2(target);
|
|
13152
13339
|
if (!isWithin2(root, ancestor.canonical)) {
|
|
13153
13340
|
throw new TargetPolicyError("path-escape");
|
|
13154
13341
|
}
|
|
13155
|
-
const components =
|
|
13342
|
+
const components = path2.relative(root, target).split(path2.sep).filter((component) => component.length > 0);
|
|
13156
13343
|
let cursor = root;
|
|
13157
13344
|
for (const [index, component] of components.entries()) {
|
|
13158
|
-
cursor =
|
|
13345
|
+
cursor = path2.join(cursor, component);
|
|
13159
13346
|
let stat;
|
|
13160
13347
|
try {
|
|
13161
13348
|
stat = await promises.lstat(cursor);
|
|
@@ -13220,8 +13407,8 @@ var AgentContentReadPolicyEngine = class {
|
|
|
13220
13407
|
this.capabilities = new Set(options.capabilities);
|
|
13221
13408
|
this.runtimeRoots = Object.freeze((options.runtimeAllowlistedRoots ?? []).map((root, index) => {
|
|
13222
13409
|
const value = nonEmptyString(root, `contentRead.runtimeAllowlistedRoots[${index}]`);
|
|
13223
|
-
if (!
|
|
13224
|
-
return
|
|
13410
|
+
if (!path2.isAbsolute(value)) throw new AgentContentReadPolicyError("runtime allowlisted roots must be absolute");
|
|
13411
|
+
return path2.resolve(value);
|
|
13225
13412
|
}));
|
|
13226
13413
|
this.resolveSessionIdentity = options.resolveSessionIdentity;
|
|
13227
13414
|
this.resolveTranscriptIdentity = options.resolveTranscriptIdentity;
|
|
@@ -13273,7 +13460,7 @@ var AgentContentReadPolicyEngine = class {
|
|
|
13273
13460
|
if (request.decodeAs === "utf8" && !policy.textMimeTypes.includes(request.mimeType)) {
|
|
13274
13461
|
return this.deny(request, relativeTarget, "text-not-allowlisted");
|
|
13275
13462
|
}
|
|
13276
|
-
const target =
|
|
13463
|
+
const target = path2.resolve(root, ...segments);
|
|
13277
13464
|
if (!isWithin2(root, target)) return this.deny(request, relativeTarget, "path-escape");
|
|
13278
13465
|
try {
|
|
13279
13466
|
await inspectRegularTarget(root, target);
|
|
@@ -13354,7 +13541,7 @@ var AgentContentReadPolicyEngine = class {
|
|
|
13354
13541
|
}
|
|
13355
13542
|
async checkSessionIdentity(request, resolver, requiredCwd) {
|
|
13356
13543
|
const session = request.session;
|
|
13357
|
-
if (session === void 0 || !
|
|
13544
|
+
if (session === void 0 || !sameAgentRef3(session.agentRef, request.agentRef) || requiredCwd !== void 0 && session.cwd !== requiredCwd) {
|
|
13358
13545
|
return "identity-mismatch";
|
|
13359
13546
|
}
|
|
13360
13547
|
let expected;
|
|
@@ -13470,7 +13657,7 @@ async function detectRuntimes(adapters) {
|
|
|
13470
13657
|
}
|
|
13471
13658
|
return runtimes;
|
|
13472
13659
|
}
|
|
13473
|
-
function computeCapabilities(adapters, agentHomeConfigured = false, agentEgressConfigured = false, contentReadPolicies) {
|
|
13660
|
+
function computeCapabilities(adapters, agentHomeConfigured = false, agentHomeProjectionConfigured = false, agentEgressConfigured = false, contentReadPolicies) {
|
|
13474
13661
|
const flags = [];
|
|
13475
13662
|
if (adapters.some((adapter) => adapter.descriptor.capabilities.steer)) flags.push("steer");
|
|
13476
13663
|
flags.push("blob-upload");
|
|
@@ -13485,7 +13672,14 @@ function computeCapabilities(adapters, agentHomeConfigured = false, agentEgressC
|
|
|
13485
13672
|
flags.push("toolset-selection");
|
|
13486
13673
|
}
|
|
13487
13674
|
if (agentHomeConfigured) flags.push("agent-home-contract");
|
|
13488
|
-
if (
|
|
13675
|
+
if (agentHomeProjectionConfigured) flags.push(AGENT_HOME_PROJECTION_CAPABILITY);
|
|
13676
|
+
if (agentEgressConfigured) {
|
|
13677
|
+
flags.push(
|
|
13678
|
+
AGENT_EGRESS_POLICY_CAPABILITY,
|
|
13679
|
+
AGENT_EGRESS_RELIABLE_ACK_CAPABILITY,
|
|
13680
|
+
AGENT_EGRESS_FRESH_SESSION_CAPABILITY
|
|
13681
|
+
);
|
|
13682
|
+
}
|
|
13489
13683
|
if (contentReadPolicies !== void 0) {
|
|
13490
13684
|
for (const surface of Object.keys(AGENT_CONTENT_READ_CAPABILITIES)) {
|
|
13491
13685
|
const policy = contentReadPolicies[surface];
|
|
@@ -13837,7 +14031,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
13837
14031
|
}
|
|
13838
14032
|
await agentHomeManager?.preflight();
|
|
13839
14033
|
if (config.agentEgress !== void 0 && config.agentHome !== void 0) {
|
|
13840
|
-
await agentEgress.recover(
|
|
14034
|
+
await agentEgress.recover(path2.join(config.agentHome.hostStorageRoot, "agents"));
|
|
13841
14035
|
}
|
|
13842
14036
|
fleetJitter = createFleetJitter(config.productId, record.deviceId);
|
|
13843
14037
|
if (config.permissionDefaults?.workspaceRoot !== void 0) {
|
|
@@ -13892,9 +14086,16 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
13892
14086
|
const capabilities = computeCapabilities(
|
|
13893
14087
|
adapters,
|
|
13894
14088
|
config.agentHome !== void 0,
|
|
14089
|
+
agentHomeManager?.supportsTaskFreeProjection() === true,
|
|
13895
14090
|
config.agentEgress !== void 0,
|
|
13896
14091
|
agentContentReadPolicies
|
|
13897
14092
|
);
|
|
14093
|
+
const agentHomeProjectionCompletion = agentHomeManager?.supportsTaskFreeProjection() === true ? new AgentHomeProjectionCompletionClient({
|
|
14094
|
+
serverUrl: config.serverUrl,
|
|
14095
|
+
auth,
|
|
14096
|
+
tenantId: record.tenantId,
|
|
14097
|
+
deviceId: record.deviceId
|
|
14098
|
+
}) : void 0;
|
|
13898
14099
|
const journalIdentity = config.hostedJournal ? { tenantId: record.tenantId, productId: config.productId, deviceId: record.deviceId } : void 0;
|
|
13899
14100
|
const sendSanitizedEnvelope = activeJournal && journalIdentity ? (envelope) => {
|
|
13900
14101
|
observer.handleOutboundEnvelope(envelope);
|
|
@@ -14031,6 +14232,20 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
14031
14232
|
...activePressureEngine ? { admissionGuard: () => activePressureEngine.admissionGuard() } : {}
|
|
14032
14233
|
};
|
|
14033
14234
|
runner = new TaskRunner(deps);
|
|
14235
|
+
const handleAgentHomeProjectionEnvelope = async (envelope) => {
|
|
14236
|
+
if (envelope.type !== "agent.home.projection") return false;
|
|
14237
|
+
if (agentHomeManager === void 0 || agentHomeProjectionCompletion === void 0) {
|
|
14238
|
+
throw new Error("task-free Agent-home projection is not configured on this daemon");
|
|
14239
|
+
}
|
|
14240
|
+
const outcome = await agentHomeManager.project(envelope.payload);
|
|
14241
|
+
await agentHomeProjectionCompletion.complete({
|
|
14242
|
+
requestId: envelope.payload.requestId,
|
|
14243
|
+
agentRef: envelope.payload.agentRef,
|
|
14244
|
+
projectionHash: envelope.payload.projectionHash,
|
|
14245
|
+
outcome
|
|
14246
|
+
});
|
|
14247
|
+
return true;
|
|
14248
|
+
};
|
|
14034
14249
|
const handleAgentEgressEnvelope = async (envelope) => {
|
|
14035
14250
|
if (envelope.type !== "agent.egress.ack") return false;
|
|
14036
14251
|
if (config.agentEgress === void 0) return true;
|
|
@@ -14186,6 +14401,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
14186
14401
|
throw new Error("tenant enrollment is being re-paired; inbound work is blocked until restart");
|
|
14187
14402
|
}
|
|
14188
14403
|
observer.handleInboundEnvelope(envelope);
|
|
14404
|
+
if (await handleAgentHomeProjectionEnvelope(envelope)) return;
|
|
14189
14405
|
if (await handleAgentEgressEnvelope(envelope)) return;
|
|
14190
14406
|
if (await handleAgentContentReadEnvelope(envelope)) return;
|
|
14191
14407
|
activePressureEngine?.assertAckCriticalAllowed();
|
|
@@ -14196,6 +14412,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
14196
14412
|
return Promise.reject(new Error("tenant enrollment is being re-paired; inbound work is blocked until restart"));
|
|
14197
14413
|
}
|
|
14198
14414
|
observer.handleInboundEnvelope(envelope);
|
|
14415
|
+
if (envelope.type === "agent.home.projection") return handleAgentHomeProjectionEnvelope(envelope).then(() => void 0);
|
|
14199
14416
|
if (envelope.type === "agent.egress.ack") return handleAgentEgressEnvelope(envelope).then(() => void 0);
|
|
14200
14417
|
if (envelope.type === "agent.content.read") return handleAgentContentReadEnvelope(envelope).then(() => void 0);
|
|
14201
14418
|
return runner?.handleEnvelope(envelope) ?? Promise.resolve();
|
|
@@ -14690,7 +14907,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
14690
14907
|
connection.send(sanitized.envelope);
|
|
14691
14908
|
}
|
|
14692
14909
|
async function publishReliableAgentEgress(input) {
|
|
14693
|
-
if (config.agentEgress === void 0 || agentHomeManager === void 0) {
|
|
14910
|
+
if (config.agentEgress === void 0 || agentHomeManager === void 0 || agentSessionHandoffs === void 0) {
|
|
14694
14911
|
throw new Error("Agent reliable egress is not configured");
|
|
14695
14912
|
}
|
|
14696
14913
|
if (tenantRebinding) {
|
|
@@ -14699,12 +14916,21 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
14699
14916
|
const binding = await agentHomeManager.acquire(input.agentRef);
|
|
14700
14917
|
try {
|
|
14701
14918
|
await agentHomeManager.initialize(binding);
|
|
14919
|
+
const handoff = await agentSessionHandoffs.requireMatch({
|
|
14920
|
+
agentRef: binding.resolution.agentRef,
|
|
14921
|
+
sessionRef: input.sessionRef,
|
|
14922
|
+
runtimeId: input.runtimeId,
|
|
14923
|
+
cwd: binding.resolution.canonicalHome
|
|
14924
|
+
});
|
|
14925
|
+
if (handoff.taskId !== input.taskId) {
|
|
14926
|
+
throw new Error("Agent reliable egress taskId does not match the durable session handoff");
|
|
14927
|
+
}
|
|
14702
14928
|
const appended = await agentEgress.appendReliable({
|
|
14703
14929
|
homeDir: binding.resolution.canonicalHome,
|
|
14704
14930
|
agentRef: binding.resolution.agentRef,
|
|
14705
14931
|
sessionRef: input.sessionRef,
|
|
14706
14932
|
payload: input.payload,
|
|
14707
|
-
|
|
14933
|
+
taskId: input.taskId,
|
|
14708
14934
|
...input.eventId === void 0 ? {} : { eventId: input.eventId }
|
|
14709
14935
|
});
|
|
14710
14936
|
if (appended.ok) dispatchReliableRecord(appended.record);
|
|
@@ -15149,14 +15375,14 @@ async function getJson(url, auth, signal, what) {
|
|
|
15149
15375
|
return readBoundedJson(response, what);
|
|
15150
15376
|
}
|
|
15151
15377
|
function skillPacksRoot(dataDir) {
|
|
15152
|
-
return
|
|
15378
|
+
return path2.join(dataDir, SKILL_PACKS_DIRNAME);
|
|
15153
15379
|
}
|
|
15154
15380
|
function resolveInside(baseDir, relative) {
|
|
15155
15381
|
if (!isSkillPackPathSafe(relative)) {
|
|
15156
15382
|
throw new SkillPackInstallError("store_unsafe", `${JSON.stringify(relative)} is not a safe pack-relative path.`);
|
|
15157
15383
|
}
|
|
15158
|
-
const resolved =
|
|
15159
|
-
const prefix =
|
|
15384
|
+
const resolved = path2.resolve(baseDir, relative);
|
|
15385
|
+
const prefix = path2.resolve(baseDir) + path2.sep;
|
|
15160
15386
|
if (!resolved.startsWith(prefix)) {
|
|
15161
15387
|
throw new SkillPackInstallError(
|
|
15162
15388
|
"store_unsafe",
|
|
@@ -15182,7 +15408,7 @@ async function appendAuditLine(dataDir, record) {
|
|
|
15182
15408
|
await promises.mkdir(root, { recursive: true, mode: DIR_MODE });
|
|
15183
15409
|
await promises.chmod(root, DIR_MODE).catch(() => {
|
|
15184
15410
|
});
|
|
15185
|
-
const filePath =
|
|
15411
|
+
const filePath = path2.join(root, SKILL_PACK_AUDIT_FILENAME);
|
|
15186
15412
|
const handle = await promises.open(filePath, "a", FILE_MODE);
|
|
15187
15413
|
try {
|
|
15188
15414
|
await handle.chmod(FILE_MODE);
|
|
@@ -15297,12 +15523,12 @@ async function installOne(options, manifest, source, base) {
|
|
|
15297
15523
|
if (!entryCheck.ok) {
|
|
15298
15524
|
await refuse("content_rejected", `skill pack ${JSON.stringify(manifest.name)}: ${entryCheck.reason} \u2014 ${entryCheck.detail}`);
|
|
15299
15525
|
}
|
|
15300
|
-
const packRoot =
|
|
15301
|
-
const revisionDir =
|
|
15526
|
+
const packRoot = path2.join(skillPacksRoot(options.dataDir), manifest.name);
|
|
15527
|
+
const revisionDir = path2.join(packRoot, manifest.contentHash.slice("sha256:".length));
|
|
15302
15528
|
await promises.mkdir(revisionDir, { recursive: true, mode: DIR_MODE });
|
|
15303
15529
|
for (const [relative, content] of bodies) {
|
|
15304
15530
|
const target = resolveInside(revisionDir, relative);
|
|
15305
|
-
await promises.mkdir(
|
|
15531
|
+
await promises.mkdir(path2.dirname(target), { recursive: true, mode: DIR_MODE });
|
|
15306
15532
|
await assertNotSymlink(target);
|
|
15307
15533
|
await atomicWriteFile(target, content, { mode: FILE_MODE });
|
|
15308
15534
|
}
|
|
@@ -15320,7 +15546,7 @@ async function installOne(options, manifest, source, base) {
|
|
|
15320
15546
|
bytes: file.byteSize
|
|
15321
15547
|
}))
|
|
15322
15548
|
};
|
|
15323
|
-
await atomicWriteFile(
|
|
15549
|
+
await atomicWriteFile(path2.join(packRoot, SKILL_PACK_LOCK_FILENAME), `${JSON.stringify(lock, null, 2)}
|
|
15324
15550
|
`, {
|
|
15325
15551
|
mode: FILE_MODE
|
|
15326
15552
|
});
|
|
@@ -15342,10 +15568,10 @@ function isLockShaped(value) {
|
|
|
15342
15568
|
}
|
|
15343
15569
|
async function readLock(dataDir, name) {
|
|
15344
15570
|
if (!isSkillPackPathSafe(name)) return void 0;
|
|
15345
|
-
const packRoot =
|
|
15571
|
+
const packRoot = path2.join(skillPacksRoot(dataDir), name);
|
|
15346
15572
|
let raw;
|
|
15347
15573
|
try {
|
|
15348
|
-
raw = await promises.readFile(
|
|
15574
|
+
raw = await promises.readFile(path2.join(packRoot, SKILL_PACK_LOCK_FILENAME), "utf8");
|
|
15349
15575
|
} catch (err) {
|
|
15350
15576
|
if (err.code === "ENOENT") return void 0;
|
|
15351
15577
|
throw err;
|
|
@@ -15360,7 +15586,7 @@ async function readLock(dataDir, name) {
|
|
|
15360
15586
|
return {
|
|
15361
15587
|
name,
|
|
15362
15588
|
lock: parsed,
|
|
15363
|
-
directory:
|
|
15589
|
+
directory: path2.join(packRoot, parsed.content_hash.slice("sha256:".length))
|
|
15364
15590
|
};
|
|
15365
15591
|
}
|
|
15366
15592
|
async function listInstalledSkillPacks(dataDir) {
|
|
@@ -15409,7 +15635,7 @@ async function projectSkillPack(dataDir, name, targetDir) {
|
|
|
15409
15635
|
);
|
|
15410
15636
|
}
|
|
15411
15637
|
const destination = resolveInside(targetDir, file.path);
|
|
15412
|
-
await promises.mkdir(
|
|
15638
|
+
await promises.mkdir(path2.dirname(destination), { recursive: true, mode: DIR_MODE });
|
|
15413
15639
|
await assertNotSymlink(destination);
|
|
15414
15640
|
await atomicWriteFile(destination, bytes, { mode: FILE_MODE });
|
|
15415
15641
|
copied.push(file.path);
|
|
@@ -15424,7 +15650,7 @@ async function projectSkillPack(dataDir, name, targetDir) {
|
|
|
15424
15650
|
return {
|
|
15425
15651
|
name: installed.name,
|
|
15426
15652
|
contentHash: installed.lock.content_hash,
|
|
15427
|
-
targetDir:
|
|
15653
|
+
targetDir: path2.resolve(targetDir),
|
|
15428
15654
|
files: copied
|
|
15429
15655
|
};
|
|
15430
15656
|
}
|
|
@@ -15933,8 +16159,8 @@ function generateLaunchdPlist(def) {
|
|
|
15933
16159
|
const { label, program, logDir } = def;
|
|
15934
16160
|
const args = [program.command, ...program.args];
|
|
15935
16161
|
const cwd = program.cwd ?? os6.homedir();
|
|
15936
|
-
const outLog =
|
|
15937
|
-
const errLog =
|
|
16162
|
+
const outLog = path2.join(logDir, `${label}.out.log`);
|
|
16163
|
+
const errLog = path2.join(logDir, `${label}.err.log`);
|
|
15938
16164
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
15939
16165
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
15940
16166
|
<plist version="1.0">
|
|
@@ -15975,7 +16201,7 @@ function createLaunchdLifecycle(def, deps = {}) {
|
|
|
15975
16201
|
return process.getuid();
|
|
15976
16202
|
});
|
|
15977
16203
|
const label = sanitizeServiceName(def.name);
|
|
15978
|
-
const plistPath = () =>
|
|
16204
|
+
const plistPath = () => path2.join(homedir(), "Library", "LaunchAgents", `${label}.plist`);
|
|
15979
16205
|
const domainTarget = () => `gui/${getuid()}`;
|
|
15980
16206
|
const serviceTarget = () => `${domainTarget()}/${label}`;
|
|
15981
16207
|
async function fileExists(p) {
|
|
@@ -15988,7 +16214,7 @@ function createLaunchdLifecycle(def, deps = {}) {
|
|
|
15988
16214
|
}
|
|
15989
16215
|
async function writePlist(program) {
|
|
15990
16216
|
const xml = generateLaunchdPlist({ label, program, logDir: def.logDir });
|
|
15991
|
-
await fs24.mkdir(
|
|
16217
|
+
await fs24.mkdir(path2.dirname(plistPath()), { recursive: true });
|
|
15992
16218
|
await fs24.mkdir(def.logDir, { recursive: true });
|
|
15993
16219
|
await fs24.writeFile(plistPath(), xml, "utf8");
|
|
15994
16220
|
}
|
|
@@ -16062,8 +16288,8 @@ function generateSystemdUnit(def) {
|
|
|
16062
16288
|
assertNoControlChars(displayName, "displayName");
|
|
16063
16289
|
const cwd = program.cwd ?? os6.homedir();
|
|
16064
16290
|
assertNoControlChars(cwd, "program.cwd");
|
|
16065
|
-
const outLog =
|
|
16066
|
-
const errLog =
|
|
16291
|
+
const outLog = path2.join(logDir, `${name}.out.log`);
|
|
16292
|
+
const errLog = path2.join(logDir, `${name}.err.log`);
|
|
16067
16293
|
assertNoControlChars(outLog, "logDir");
|
|
16068
16294
|
assertNoControlChars(errLog, "logDir");
|
|
16069
16295
|
const execStart = [program.command, ...program.args].map(quoteSystemdArg).join(" ");
|
|
@@ -16089,7 +16315,7 @@ function createSystemdLifecycle(def, deps = {}) {
|
|
|
16089
16315
|
const homedir = deps.homedir ?? (() => os6.homedir());
|
|
16090
16316
|
const name = sanitizeServiceName(def.name);
|
|
16091
16317
|
const unitName = `${name}.service`;
|
|
16092
|
-
const unitPath = () =>
|
|
16318
|
+
const unitPath = () => path2.join(homedir(), ".config", "systemd", "user", unitName);
|
|
16093
16319
|
async function fileExists(p) {
|
|
16094
16320
|
try {
|
|
16095
16321
|
await fs24.stat(p);
|
|
@@ -16100,7 +16326,7 @@ function createSystemdLifecycle(def, deps = {}) {
|
|
|
16100
16326
|
}
|
|
16101
16327
|
async function writeUnit(program) {
|
|
16102
16328
|
const unit = generateSystemdUnit({ name, displayName: def.displayName ?? def.name, program, logDir: def.logDir });
|
|
16103
|
-
await fs24.mkdir(
|
|
16329
|
+
await fs24.mkdir(path2.dirname(unitPath()), { recursive: true });
|
|
16104
16330
|
await fs24.mkdir(def.logDir, { recursive: true });
|
|
16105
16331
|
await fs24.writeFile(unitPath(), unit, "utf8");
|
|
16106
16332
|
}
|
|
@@ -16182,8 +16408,8 @@ function createWinswLifecycle(def, deps = {}) {
|
|
|
16182
16408
|
const winswBin = windows.winswBin;
|
|
16183
16409
|
const id = sanitizeServiceName(def.name);
|
|
16184
16410
|
const installDir = windows.installDir ?? def.logDir;
|
|
16185
|
-
const exePath =
|
|
16186
|
-
const xmlPath =
|
|
16411
|
+
const exePath = path2.join(installDir, `${id}.exe`);
|
|
16412
|
+
const xmlPath = path2.join(installDir, `${id}.xml`);
|
|
16187
16413
|
async function fileExists(p) {
|
|
16188
16414
|
try {
|
|
16189
16415
|
await fs24.stat(p);
|
|
@@ -16251,6 +16477,6 @@ function createServiceLifecycle(def, opts = {}) {
|
|
|
16251
16477
|
}
|
|
16252
16478
|
}
|
|
16253
16479
|
|
|
16254
|
-
export { AGENT_CONTENT_READ_CAPABILITIES, AGENT_CONTENT_READ_CAPABILITY_ARTIFACT, AGENT_CONTENT_READ_CAPABILITY_TRANSCRIPT, AGENT_CONTENT_READ_CAPABILITY_WORKSPACE, AgentHomeBusyError, AgentHomeCollisionError, AgentHomeError, AgentHomeLayout, AgentHomeLeaseCorruptError, AgentHomeLeaseManager, AgentHomeManager, AgentHomeResolutionError, AgentRefValidationError, AgentSessionHandoffCorruptError, AgentSessionHandoffMismatchError, AgentSessionHandoffStore, AgentSessionHandoffStoreError, AuthManager, BlobClient, ClaudeAdapter, CodexAdapter, DEFAULT_ACK_CRITICAL_RESERVE_BYTES, DEFAULT_CLEANUP_BATCH_LIMIT, DEFAULT_HARD_BUDGET_RATIO, DEFAULT_INCREMENTAL_VACUUM_PAGES, DEFAULT_LOG_ROTATION, DEFAULT_NORMAL_COMPACTION_INTERVAL_MS, DEFAULT_PRESSURE_COMPACTION_INTERVAL_MS, DEFAULT_RETENTION_MS, DEFAULT_SOFT_BUDGET_RATIO, DaemonObserver, DeviceRevokedError, GitWorkspaceError, GitWorkspaceManager, GitWorkspaceStore, JOURNAL_DB_FILENAME, JOURNAL_QUARANTINE_DIRNAME, JOURNAL_TASK_REF_PREFIX, JournalClosedError, JournalCorruptError, JournalRecordTooLargeError, JournalUnavailableError, JournalUnknownTaskError, LocalStorageEmergencyError, LocalStoragePolicyError, LocalStoragePressureEngine, McpToolsetDefinitionRevisionConflictError, McpToolsetRevisionConflictError, PI_PACKAGE_NAME, PiAdapter, PolicyUnsupportedError, RUNTIME_ADAPTER_CONTRACT_VIOLATION_REASON, RuntimeDisposalFailure, RuntimeExecutionFailure, SKILL_PACKS_CAPABILITY, SKILL_PACKS_DIRNAME, SKILL_PACK_AUDIT_FILENAME, SKILL_PACK_INSTALL_ERROR_CODES, SKILL_PACK_LOCK_FILENAME, SKILL_PACK_LOCK_SCHEMA, SKILL_PACK_RESPONSE_MAX_BYTES, SecureDirHardeningError, SkillPackInstallError, SqliteLocalTaskJournal, SteerUnsupportedError, StoredDeviceProofSigner, TruthMemoryClient, TruthMemoryClientError, UnsupportedServicePlatformError, buildIcaclsArgs, cleanupEligibleAt, cleanupOrderFor, computePressureState, createAgentHomeProjection, createDaemon, createDaemonWithAdapters, createFilesystemCleanupExecutor, createServiceLifecycle, createStatfsFreeBytesProvider, ensureSecureDir, freezeRuntimeAdapterDescriptor, generateLaunchdPlist, generateSystemdUnit, generateWinswXml, installSkillPacks, isGitWorkspaceConfig, isRuntimeDisposalFailure, isRuntimeExecutionFailure, journalHash, listInstalledSkillPacks, nodeAgentProgram, prependGitWorkspaceGuidance, projectRuntimeBoundaryFailure, projectRuntimeExecutionFailure, projectSkillPack, requestDeviceAssertion, resolveLocalAgentReleaseIdentity, resolveLocalStoragePolicy, sanitizeServiceName, sealRuntimeOperationManifest, skillPacksRoot, stableAgentHomeOwnerId, validateAgentRef };
|
|
16480
|
+
export { AGENT_CONTENT_READ_CAPABILITIES, AGENT_CONTENT_READ_CAPABILITY_ARTIFACT, AGENT_CONTENT_READ_CAPABILITY_TRANSCRIPT, AGENT_CONTENT_READ_CAPABILITY_WORKSPACE, AGENT_HOME_PROJECTION_STATE_FILE, AgentHomeBusyError, AgentHomeCollisionError, AgentHomeError, AgentHomeLayout, AgentHomeLeaseCorruptError, AgentHomeLeaseManager, AgentHomeManager, AgentHomeResolutionError, AgentRefValidationError, AgentSessionHandoffCorruptError, AgentSessionHandoffMismatchError, AgentSessionHandoffStore, AgentSessionHandoffStoreError, AuthManager, BlobClient, ClaudeAdapter, CodexAdapter, DEFAULT_ACK_CRITICAL_RESERVE_BYTES, DEFAULT_CLEANUP_BATCH_LIMIT, DEFAULT_HARD_BUDGET_RATIO, DEFAULT_INCREMENTAL_VACUUM_PAGES, DEFAULT_LOG_ROTATION, DEFAULT_NORMAL_COMPACTION_INTERVAL_MS, DEFAULT_PRESSURE_COMPACTION_INTERVAL_MS, DEFAULT_RETENTION_MS, DEFAULT_SOFT_BUDGET_RATIO, DaemonObserver, DeviceRevokedError, GitWorkspaceError, GitWorkspaceManager, GitWorkspaceStore, JOURNAL_DB_FILENAME, JOURNAL_QUARANTINE_DIRNAME, JOURNAL_TASK_REF_PREFIX, JournalClosedError, JournalCorruptError, JournalRecordTooLargeError, JournalUnavailableError, JournalUnknownTaskError, LocalStorageEmergencyError, LocalStoragePolicyError, LocalStoragePressureEngine, McpToolsetDefinitionRevisionConflictError, McpToolsetRevisionConflictError, PI_PACKAGE_NAME, PiAdapter, PolicyUnsupportedError, RUNTIME_ADAPTER_CONTRACT_VIOLATION_REASON, RuntimeDisposalFailure, RuntimeExecutionFailure, SKILL_PACKS_CAPABILITY, SKILL_PACKS_DIRNAME, SKILL_PACK_AUDIT_FILENAME, SKILL_PACK_INSTALL_ERROR_CODES, SKILL_PACK_LOCK_FILENAME, SKILL_PACK_LOCK_SCHEMA, SKILL_PACK_RESPONSE_MAX_BYTES, SecureDirHardeningError, SkillPackInstallError, SqliteLocalTaskJournal, SteerUnsupportedError, StoredDeviceProofSigner, TruthMemoryClient, TruthMemoryClientError, UnsupportedServicePlatformError, buildIcaclsArgs, cleanupEligibleAt, cleanupOrderFor, computePressureState, createAgentHomeProjection, createAgentHomeProjectionConsumer, createDaemon, createDaemonWithAdapters, createFilesystemCleanupExecutor, createServiceLifecycle, createStatfsFreeBytesProvider, ensureSecureDir, freezeRuntimeAdapterDescriptor, generateLaunchdPlist, generateSystemdUnit, generateWinswXml, installSkillPacks, isGitWorkspaceConfig, isRuntimeDisposalFailure, isRuntimeExecutionFailure, journalHash, listInstalledSkillPacks, nodeAgentProgram, prependGitWorkspaceGuidance, projectRuntimeBoundaryFailure, projectRuntimeExecutionFailure, projectSkillPack, requestDeviceAssertion, resolveLocalAgentReleaseIdentity, resolveLocalStoragePolicy, sanitizeServiceName, sealRuntimeOperationManifest, skillPacksRoot, stableAgentHomeOwnerId, validateAgentRef };
|
|
16255
16481
|
//# sourceMappingURL=index.js.map
|
|
16256
16482
|
//# sourceMappingURL=index.js.map
|