@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.
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { randomUUID, createHash, randomBytes, timingSafeEqual, createHmac, createPrivateKey, generateKeyPairSync, sign } from 'crypto';
3
3
  import { readFileSync, promises, linkSync, fstatSync, lstatSync, unlinkSync, constants, readSync, openSync, writeFileSync, fchmodSync, fsyncSync, closeSync, opendirSync, existsSync, realpathSync, mkdirSync, renameSync, chmodSync, statSync, readdirSync } from 'fs';
4
- import path, { isAbsolute, join } from 'path';
5
- import { AGENT_CONTENT_ARTIFACT_READ_CAPABILITY, AGENT_CONTENT_TRANSCRIPT_READ_CAPABILITY, AGENT_CONTENT_WORKSPACE_READ_CAPABILITY, TASK_STATES, AgentEgressPolicySchema, CONFIGURED_TOOLSETS_MAX_ITEMS, ToolsetIdSchema, AgentRefSchema, AgentContentReceiptPayloadSchema, BYOK_PAIR_PATH, PairResponseSchema, BYOK_CHALLENGE_PATH, BYOK_TOKEN_PATH, partitionAgentEvents, TASK_TRANSITIONS, encodeEnvelope, PROTOCOL_VERSION, createEnvelope, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY, byokBlobUrlPath, BYOK_BLOBS_PATH, byokBlobFinalizePath, 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';
4
+ import path2, { isAbsolute, join } from 'path';
5
+ import { AGENT_CONTENT_ARTIFACT_READ_CAPABILITY, AGENT_CONTENT_TRANSCRIPT_READ_CAPABILITY, AGENT_CONTENT_WORKSPACE_READ_CAPABILITY, TASK_STATES, AgentEgressPolicySchema, AgentHomeProjectionPayloadSchema, CONFIGURED_TOOLSETS_MAX_ITEMS, ToolsetIdSchema, AgentRefSchema, AgentContentReceiptPayloadSchema, BYOK_PAIR_PATH, PairResponseSchema, BYOK_CHALLENGE_PATH, BYOK_TOKEN_PATH, partitionAgentEvents, TASK_TRANSITIONS, encodeEnvelope, PROTOCOL_VERSION, createEnvelope, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY, byokBlobUrlPath, BYOK_BLOBS_PATH, byokBlobFinalizePath, 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';
6
6
  import { execFile, spawn } from 'child_process';
7
7
  import os from 'os';
8
8
  import { isTenantId, DEVICE_ASSERTION_AUDIENCE_MAX_BYTES, DEVICE_ASSERTION_DEFAULT_TTL_MS, DEVICE_ASSERTION_MAX_TTL_MS, nonceSigningBytes, CapabilityDeclarationSchema, hasCapability, DeviceAssertionClaimsSchema, deviceAssertionSigningInput, DEVICE_ASSERTION_SCHEMA_ID } from '@byok-sdk/core';
@@ -14,8 +14,79 @@ import { WebSocket } from 'ws';
14
14
  import { createRequire } from 'module';
15
15
  import { createInterface } from 'readline/promises';
16
16
 
17
+ var tmpSeq = 0;
18
+ async function atomicWriteFile(filePath, data, options = {}) {
19
+ const tmpPath = `${filePath}.${process.pid}-${tmpSeq++}.tmp`;
20
+ try {
21
+ const handle = await promises.open(tmpPath, "w", options.mode);
22
+ try {
23
+ await handle.writeFile(data);
24
+ if (options.mode !== void 0) {
25
+ await handle.chmod(options.mode);
26
+ }
27
+ if (options.fsync) {
28
+ await handle.sync();
29
+ }
30
+ } finally {
31
+ await handle.close();
32
+ }
33
+ } catch (err) {
34
+ await promises.rm(tmpPath, { force: true }).catch(() => {
35
+ });
36
+ throw err;
37
+ }
38
+ await renameOnto(tmpPath, filePath);
39
+ if (options.mode !== void 0) {
40
+ await promises.chmod(filePath, options.mode);
41
+ }
42
+ if (options.fsync) {
43
+ const target = await promises.open(filePath, process.platform === "win32" ? "r+" : "r");
44
+ try {
45
+ await target.sync();
46
+ } finally {
47
+ await target.close();
48
+ }
49
+ if (process.platform !== "win32") {
50
+ const directory = await promises.open(path2.dirname(filePath), "r");
51
+ try {
52
+ await directory.sync();
53
+ } finally {
54
+ await directory.close();
55
+ }
56
+ }
57
+ }
58
+ }
59
+ var RENAME_RETRY_ATTEMPTS = 5;
60
+ var RENAME_RETRY_DELAY_MS = 20;
61
+ function delay(ms) {
62
+ return new Promise((resolve) => setTimeout(resolve, ms));
63
+ }
64
+ async function renameOnto(tmpPath, targetPath) {
65
+ for (let attempt = 1; attempt <= RENAME_RETRY_ATTEMPTS; attempt++) {
66
+ try {
67
+ await promises.rename(tmpPath, targetPath);
68
+ return;
69
+ } catch (err) {
70
+ const code = err.code;
71
+ if (code !== "EPERM" && code !== "EEXIST") {
72
+ await promises.rm(tmpPath, { force: true }).catch(() => {
73
+ });
74
+ throw err;
75
+ }
76
+ if (attempt === RENAME_RETRY_ATTEMPTS) {
77
+ await promises.rm(tmpPath, { force: true }).catch(() => {
78
+ });
79
+ throw err;
80
+ }
81
+ await delay(RENAME_RETRY_DELAY_MS * attempt);
82
+ }
83
+ }
84
+ }
85
+
86
+ // src/agent-home.ts
17
87
  var AGENT_HOME_DIRECTORY = "agents";
18
88
  var AGENT_HOME_INTERNAL_DIRECTORY = ".byok";
89
+ var AGENT_HOME_PROJECTION_STATE_FILE = "agent-home-projection.json";
19
90
  var AgentHomeError = class extends Error {
20
91
  constructor(message) {
21
92
  super(message);
@@ -64,11 +135,11 @@ function validateAgentRef(value) {
64
135
  return Object.freeze({ agentId: candidate.agentId, profileRevision: candidate.profileRevision });
65
136
  }
66
137
  function isWithin(root, candidate) {
67
- const relative = path.relative(root, candidate);
68
- return relative === "" || relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
138
+ const relative = path2.relative(root, candidate);
139
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path2.sep}`) && !path2.isAbsolute(relative);
69
140
  }
70
141
  function assertAbsolutePath(value, label) {
71
- if (typeof value !== "string" || value.length === 0 || !path.isAbsolute(value)) {
142
+ if (typeof value !== "string" || value.length === 0 || !path2.isAbsolute(value)) {
72
143
  throw new AgentHomeResolutionError(`${label} must be an absolute path`);
73
144
  }
74
145
  if (/[\u0000\r\n]/u.test(value)) {
@@ -76,7 +147,7 @@ function assertAbsolutePath(value, label) {
76
147
  }
77
148
  }
78
149
  async function resolveExistingAncestor(inputPath) {
79
- let cursor = path.resolve(inputPath);
150
+ let cursor = path2.resolve(inputPath);
80
151
  const tail = [];
81
152
  for (; ; ) {
82
153
  try {
@@ -84,9 +155,9 @@ async function resolveExistingAncestor(inputPath) {
84
155
  } catch (error) {
85
156
  const code = error.code;
86
157
  if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
87
- const parent = path.dirname(cursor);
158
+ const parent = path2.dirname(cursor);
88
159
  if (parent === cursor) throw new AgentHomeResolutionError(`no existing ancestor for ${inputPath}`);
89
- tail.unshift(path.basename(cursor));
160
+ tail.unshift(path2.basename(cursor));
90
161
  cursor = parent;
91
162
  }
92
163
  }
@@ -95,7 +166,7 @@ async function materializeDirectory(inputPath) {
95
166
  const { canonical: canonical2, tail } = await resolveExistingAncestor(inputPath);
96
167
  let cursor = canonical2;
97
168
  for (const component of tail) {
98
- cursor = path.join(cursor, component);
169
+ cursor = path2.join(cursor, component);
99
170
  try {
100
171
  const stat = await promises.lstat(cursor);
101
172
  if (!stat.isDirectory() || stat.isSymbolicLink()) {
@@ -114,11 +185,11 @@ async function materializeDirectory(inputPath) {
114
185
  }
115
186
  async function ensureDirectoryNoSymlink(root, target) {
116
187
  if (!isWithin(root, target)) throw new AgentHomeResolutionError("Agent home is outside hostStorageRoot");
117
- const relative = path.relative(root, target);
118
- const components = relative === "" ? [] : relative.split(path.sep);
188
+ const relative = path2.relative(root, target);
189
+ const components = relative === "" ? [] : relative.split(path2.sep);
119
190
  let cursor = root;
120
191
  for (const component of components) {
121
- cursor = path.join(cursor, component);
192
+ cursor = path2.join(cursor, component);
122
193
  try {
123
194
  const stat = await promises.lstat(cursor);
124
195
  if (!stat.isDirectory() || stat.isSymbolicLink()) {
@@ -154,16 +225,16 @@ var AgentHomeLayout = class {
154
225
  canonicalRoot;
155
226
  constructor(hostStorageRoot) {
156
227
  assertAbsolutePath(hostStorageRoot, "agentHome.hostStorageRoot");
157
- this.hostStorageRootInput = path.resolve(hostStorageRoot);
228
+ this.hostStorageRootInput = path2.resolve(hostStorageRoot);
158
229
  }
159
230
  async resolve(agentRefInput) {
160
231
  const agentRef = validateAgentRef(agentRefInput);
161
232
  const hostStorageRoot = await this.resolveRoot();
162
233
  const agentsRoot = await ensureDirectoryNoSymlink(
163
234
  hostStorageRoot,
164
- path.join(hostStorageRoot, AGENT_HOME_DIRECTORY)
235
+ path2.join(hostStorageRoot, AGENT_HOME_DIRECTORY)
165
236
  );
166
- const lexicalHome = path.join(agentsRoot, agentRef.agentId);
237
+ const lexicalHome = path2.join(agentsRoot, agentRef.agentId);
167
238
  const canonicalHome = await ensureDirectoryNoSymlink(agentsRoot, lexicalHome);
168
239
  const priorAgentId = this.agentIdByCanonicalHome.get(canonicalHome);
169
240
  if (priorAgentId !== void 0 && priorAgentId !== agentRef.agentId) {
@@ -193,9 +264,9 @@ var AgentHomeLayout = class {
193
264
  const hostStorageRoot = await this.resolveRoot();
194
265
  const agentsRoot = await ensureDirectoryNoSymlink(
195
266
  hostStorageRoot,
196
- path.join(hostStorageRoot, AGENT_HOME_DIRECTORY)
267
+ path2.join(hostStorageRoot, AGENT_HOME_DIRECTORY)
197
268
  );
198
- probePath = path.join(agentsRoot, `.byok-agent-home-preflight-${randomUUID()}`);
269
+ probePath = path2.join(agentsRoot, `.byok-agent-home-preflight-${randomUUID()}`);
199
270
  handle = await promises.open(probePath, "wx", 384);
200
271
  created = true;
201
272
  await handle.sync();
@@ -226,7 +297,7 @@ var AgentHomeLayout = class {
226
297
  }
227
298
  };
228
299
  function stableAgentHomeOwnerId(storeDir, productId) {
229
- const identity = `${path.resolve(storeDir)}\0${productId}`;
300
+ const identity = `${path2.resolve(storeDir)}\0${productId}`;
230
301
  return `store-product:${createHash("sha256").update(identity).digest("hex")}`;
231
302
  }
232
303
  function parseLeaseMarker(value, lockPath) {
@@ -236,7 +307,7 @@ function parseLeaseMarker(value, lockPath) {
236
307
  } catch {
237
308
  throw new AgentHomeLeaseCorruptError(`Agent home lease marker ${lockPath} is corrupt`);
238
309
  }
239
- if (typeof parsed !== "object" || parsed === null || parsed.version !== 1 || typeof parsed.ownerId !== "string" || typeof parsed.leaseId !== "string" || typeof parsed.canonicalHome !== "string" || !path.isAbsolute(parsed.canonicalHome)) {
310
+ 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)) {
240
311
  throw new AgentHomeLeaseCorruptError(`Agent home lease marker ${lockPath} has an invalid shape`);
241
312
  }
242
313
  let agentRef;
@@ -246,7 +317,7 @@ function parseLeaseMarker(value, lockPath) {
246
317
  throw new AgentHomeLeaseCorruptError(`Agent home lease marker ${lockPath} has an invalid AgentRef`);
247
318
  }
248
319
  const marker = parsed;
249
- return { ...marker, agentRef, canonicalHome: path.resolve(marker.canonicalHome) };
320
+ return { ...marker, agentRef, canonicalHome: path2.resolve(marker.canonicalHome) };
250
321
  }
251
322
  var AgentHomeLeaseManager = class _AgentHomeLeaseManager {
252
323
  static held = /* @__PURE__ */ new Map();
@@ -268,9 +339,9 @@ var AgentHomeLeaseManager = class _AgentHomeLeaseManager {
268
339
  await ensureDirectoryNoSymlink(resolution.agentsRoot, canonicalHome);
269
340
  const internalDir = await ensureDirectoryNoSymlink(
270
341
  canonicalHome,
271
- path.join(canonicalHome, AGENT_HOME_INTERNAL_DIRECTORY)
342
+ path2.join(canonicalHome, AGENT_HOME_INTERNAL_DIRECTORY)
272
343
  );
273
- lockPath = path.join(internalDir, "agent-home.lease");
344
+ lockPath = path2.join(internalDir, "agent-home.lease");
274
345
  handle = await this.openLeaseMarker(lockPath, canonicalHome, agentRef.agentId);
275
346
  ownsMarker = true;
276
347
  const marker = {
@@ -369,9 +440,73 @@ var AgentHomeLeaseManager = class _AgentHomeLeaseManager {
369
440
  async function initializeAgentHome(resolution) {
370
441
  await ensureDirectoryNoSymlink(
371
442
  resolution.canonicalHome,
372
- path.join(resolution.canonicalHome, "notes")
443
+ path2.join(resolution.canonicalHome, "notes")
373
444
  );
374
- await ensurePreservedFile(path.join(resolution.canonicalHome, "MEMORY.md"));
445
+ await ensurePreservedFile(path2.join(resolution.canonicalHome, "MEMORY.md"));
446
+ }
447
+ function projectionStatePath(resolution) {
448
+ return path2.join(
449
+ resolution.canonicalHome,
450
+ AGENT_HOME_INTERNAL_DIRECTORY,
451
+ AGENT_HOME_PROJECTION_STATE_FILE
452
+ );
453
+ }
454
+ async function readProjectionState(resolution) {
455
+ const filePath = projectionStatePath(resolution);
456
+ try {
457
+ const stat = await promises.lstat(filePath);
458
+ if (!stat.isFile() || stat.isSymbolicLink()) {
459
+ throw new AgentHomeResolutionError(`Agent projection state is not a regular file: ${filePath}`);
460
+ }
461
+ } catch (error) {
462
+ if (error.code === "ENOENT") return void 0;
463
+ throw error;
464
+ }
465
+ let parsed;
466
+ try {
467
+ parsed = JSON.parse(await promises.readFile(filePath, "utf8"));
468
+ } catch (error) {
469
+ throw new AgentHomeResolutionError(
470
+ `Agent projection state is corrupt: ${error instanceof Error ? error.message : String(error)}`
471
+ );
472
+ }
473
+ if (typeof parsed !== "object" || parsed === null || parsed.version !== 1 || typeof parsed.requestId !== "string" || typeof parsed.projectionHash !== "string") {
474
+ throw new AgentHomeResolutionError("Agent projection state has an invalid shape");
475
+ }
476
+ const candidate = parsed;
477
+ const agentRef = validateAgentRef(candidate.agentRef);
478
+ if (agentRef.agentId !== resolution.agentRef.agentId) {
479
+ throw new AgentHomeCollisionError("Agent projection state belongs to a different Agent home");
480
+ }
481
+ return Object.freeze({
482
+ version: 1,
483
+ agentRef,
484
+ requestId: candidate.requestId,
485
+ projectionHash: candidate.projectionHash
486
+ });
487
+ }
488
+ async function writeProjectionState(resolution, payload) {
489
+ const filePath = projectionStatePath(resolution);
490
+ const existing = await promises.lstat(filePath).catch((error) => {
491
+ if (error.code === "ENOENT") return void 0;
492
+ throw error;
493
+ });
494
+ if (existing !== void 0 && (!existing.isFile() || existing.isSymbolicLink())) {
495
+ throw new AgentHomeResolutionError(`Agent projection state is not a regular file: ${filePath}`);
496
+ }
497
+ const state = {
498
+ version: 1,
499
+ agentRef: payload.agentRef,
500
+ requestId: payload.requestId,
501
+ projectionHash: payload.projectionHash
502
+ };
503
+ await atomicWriteFile(filePath, `${JSON.stringify(state)}
504
+ `, { mode: 384, fsync: true });
505
+ }
506
+ function compareProjectionRevision(left, right) {
507
+ const leftRevision = BigInt(left);
508
+ const rightRevision = BigInt(right);
509
+ return leftRevision < rightRevision ? -1 : leftRevision > rightRevision ? 1 : 0;
375
510
  }
376
511
  var AgentHomeManager = class {
377
512
  layout;
@@ -407,12 +542,59 @@ var AgentHomeManager = class {
407
542
  async initialize(binding) {
408
543
  const { resolution, lease } = binding;
409
544
  await initializeAgentHome(resolution);
410
- await this.projection?.prepare({ ...resolution, cwd: lease.cwd });
545
+ const prepare = this.projection?.prepare;
546
+ if (prepare !== void 0) await prepare({ ...resolution, cwd: lease.cwd });
411
547
  if (await promises.realpath(resolution.homeDir) !== resolution.canonicalHome) {
412
548
  throw new AgentHomeResolutionError("Agent projection changed the canonical home path");
413
549
  }
414
550
  await initializeAgentHome(resolution);
415
551
  }
552
+ supportsTaskFreeProjection() {
553
+ return this.projection?.apply !== void 0;
554
+ }
555
+ /**
556
+ * Apply one task-free projection under the same canonical-home writer lease
557
+ * used by Agent execution. Only a successful host hook followed by the
558
+ * SDK-owned fsynced ordering record can return `applied`.
559
+ */
560
+ async project(input) {
561
+ const payload = AgentHomeProjectionPayloadSchema.parse(input);
562
+ const binding = await this.acquire(payload.agentRef);
563
+ try {
564
+ const { resolution, lease } = binding;
565
+ await initializeAgentHome(resolution);
566
+ const current = await readProjectionState(resolution);
567
+ if (current !== void 0) {
568
+ const order = compareProjectionRevision(
569
+ payload.agentRef.profileRevision,
570
+ current.agentRef.profileRevision
571
+ );
572
+ if (order < 0) return "stale";
573
+ if (order === 0) {
574
+ return payload.projectionHash === current.projectionHash ? "idempotent" : "conflict";
575
+ }
576
+ }
577
+ const apply = this.projection?.apply;
578
+ if (apply === void 0) {
579
+ throw new AgentHomeError("task-free Agent-home projection is not configured");
580
+ }
581
+ await apply({
582
+ ...resolution,
583
+ cwd: lease.cwd,
584
+ requestId: payload.requestId,
585
+ projectionHash: payload.projectionHash,
586
+ projection: payload.projection
587
+ });
588
+ if (await promises.realpath(resolution.homeDir) !== resolution.canonicalHome) {
589
+ throw new AgentHomeResolutionError("Agent projection changed the canonical home path");
590
+ }
591
+ await initializeAgentHome(resolution);
592
+ await writeProjectionState(resolution, payload);
593
+ return "applied";
594
+ } finally {
595
+ await binding.lease.release();
596
+ }
597
+ }
416
598
  };
417
599
  var AgentSessionHandoffStoreError = class extends Error {
418
600
  constructor(message) {
@@ -453,7 +635,7 @@ function parseTaskTerminalEntry(value) {
453
635
  assertNonEmptyString(value.terminalReason, "taskTerminal.terminalReason");
454
636
  assertNonEmptyString(value.updatedAt, "taskTerminal.updatedAt");
455
637
  if (value.sessionRef !== void 0) assertNonEmptyString(value.sessionRef, "taskTerminal.sessionRef");
456
- if (typeof value.cwd !== "string" || !path.isAbsolute(value.cwd)) {
638
+ if (typeof value.cwd !== "string" || !path2.isAbsolute(value.cwd)) {
457
639
  throw new AgentSessionHandoffCorruptError("taskTerminal.cwd must be an absolute path");
458
640
  }
459
641
  if (value.terminalCause !== "failed") {
@@ -466,7 +648,7 @@ function parseTaskTerminalEntry(value) {
466
648
  agentRef,
467
649
  taskId: value.taskId,
468
650
  runtimeId: value.runtimeId,
469
- cwd: path.resolve(value.cwd),
651
+ cwd: path2.resolve(value.cwd),
470
652
  leaseId: value.leaseId,
471
653
  ...value.sessionRef === void 0 ? {} : { sessionRef: value.sessionRef },
472
654
  terminalCause: "failed",
@@ -496,7 +678,7 @@ function parseEntry(value) {
496
678
  assertNonEmptyString(value.runtimeId, "handoff.runtimeId");
497
679
  assertNonEmptyString(value.leaseId, "handoff.leaseId");
498
680
  assertNonEmptyString(value.updatedAt, "handoff.updatedAt");
499
- if (typeof value.cwd !== "string" || !path.isAbsolute(value.cwd)) {
681
+ if (typeof value.cwd !== "string" || !path2.isAbsolute(value.cwd)) {
500
682
  throw new AgentSessionHandoffCorruptError("handoff.cwd must be an absolute path");
501
683
  }
502
684
  if (Number.isNaN(Date.parse(value.updatedAt))) {
@@ -513,7 +695,7 @@ function parseEntry(value) {
513
695
  taskId: value.taskId,
514
696
  sessionRef: value.sessionRef,
515
697
  runtimeId: value.runtimeId,
516
- cwd: path.resolve(value.cwd),
698
+ cwd: path2.resolve(value.cwd),
517
699
  leaseId: value.leaseId,
518
700
  ...value.terminalCause === void 0 ? {} : { terminalCause: value.terminalCause },
519
701
  ...value.terminalReason === void 0 ? {} : { terminalReason: value.terminalReason },
@@ -524,10 +706,10 @@ function sameRef(left, right) {
524
706
  return left.agentId === right.agentId && left.profileRevision === right.profileRevision;
525
707
  }
526
708
  function sameMatch(entry, expected) {
527
- return sameRef(entry.agentRef, expected.agentRef) && entry.sessionRef === expected.sessionRef && entry.runtimeId === expected.runtimeId && entry.cwd === path.resolve(expected.cwd);
709
+ return sameRef(entry.agentRef, expected.agentRef) && entry.sessionRef === expected.sessionRef && entry.runtimeId === expected.runtimeId && entry.cwd === path2.resolve(expected.cwd);
528
710
  }
529
711
  function sameTaskTerminalMatch(entry, expected) {
530
- return sameRef(entry.agentRef, expected.agentRef) && entry.taskId === expected.taskId && entry.runtimeId === expected.runtimeId && entry.cwd === path.resolve(expected.cwd);
712
+ return sameRef(entry.agentRef, expected.agentRef) && entry.taskId === expected.taskId && entry.runtimeId === expected.runtimeId && entry.cwd === path2.resolve(expected.cwd);
531
713
  }
532
714
  function sessionFileName(runtimeId, sessionRef) {
533
715
  const digest2 = createHash("sha256").update(sessionRef, "utf8").digest("hex");
@@ -540,13 +722,13 @@ function taskTerminalFileName(runtimeId, taskId) {
540
722
  return `${runtime}-task-${digest2}.jsonl`;
541
723
  }
542
724
  async function evidenceDirectory(cwdInput) {
543
- if (!path.isAbsolute(cwdInput)) {
725
+ if (!path2.isAbsolute(cwdInput)) {
544
726
  throw new AgentSessionHandoffStoreError("Agent session cwd must be absolute");
545
727
  }
546
728
  const cwd = await promises.realpath(cwdInput);
547
729
  let cursor = cwd;
548
730
  for (const component of [".byok", "runtime-sessions"]) {
549
- cursor = path.join(cursor, component);
731
+ cursor = path2.join(cursor, component);
550
732
  try {
551
733
  const stat = await promises.lstat(cursor);
552
734
  if (!stat.isDirectory() || stat.isSymbolicLink()) {
@@ -558,8 +740,8 @@ async function evidenceDirectory(cwdInput) {
558
740
  }
559
741
  }
560
742
  const canonical2 = await promises.realpath(cursor);
561
- const relative = path.relative(cwd, canonical2);
562
- if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
743
+ const relative = path2.relative(cwd, canonical2);
744
+ if (relative === ".." || relative.startsWith(`..${path2.sep}`) || path2.isAbsolute(relative)) {
563
745
  throw new AgentSessionHandoffStoreError("Agent session evidence path escaped the canonical Agent home");
564
746
  }
565
747
  return canonical2;
@@ -605,7 +787,7 @@ var AgentSessionHandoffStore = class {
605
787
  taskId: input.taskId,
606
788
  sessionRef: input.sessionRef,
607
789
  runtimeId: input.runtimeId,
608
- cwd: path.resolve(input.cwd),
790
+ cwd: path2.resolve(input.cwd),
609
791
  leaseId: input.leaseId,
610
792
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
611
793
  });
@@ -648,7 +830,7 @@ var AgentSessionHandoffStore = class {
648
830
  agentRef: validateAgentRef(input.agentRef),
649
831
  taskId: input.taskId,
650
832
  runtimeId: input.runtimeId,
651
- cwd: path.resolve(input.cwd)
833
+ cwd: path2.resolve(input.cwd)
652
834
  };
653
835
  const filePath = await this.taskTerminalFilePath(expected);
654
836
  return this.enqueue(filePath, async () => {
@@ -675,7 +857,7 @@ var AgentSessionHandoffStore = class {
675
857
  agentRef: validateAgentRef(expectedInput.agentRef),
676
858
  taskId: expectedInput.taskId,
677
859
  runtimeId: expectedInput.runtimeId,
678
- cwd: path.resolve(expectedInput.cwd)
860
+ cwd: path2.resolve(expectedInput.cwd)
679
861
  };
680
862
  const filePath = await this.taskTerminalFilePath(expected);
681
863
  return this.enqueue(filePath, async () => {
@@ -693,14 +875,14 @@ var AgentSessionHandoffStore = class {
693
875
  assertNonEmptyString(match.sessionRef, "handoff.sessionRef");
694
876
  assertNonEmptyString(match.runtimeId, "handoff.runtimeId");
695
877
  const directory = await evidenceDirectory(match.cwd);
696
- return path.join(directory, sessionFileName(match.runtimeId, match.sessionRef));
878
+ return path2.join(directory, sessionFileName(match.runtimeId, match.sessionRef));
697
879
  }
698
880
  async taskTerminalFilePath(match) {
699
881
  validateAgentRef(match.agentRef);
700
882
  assertNonEmptyString(match.taskId, "taskTerminal.taskId");
701
883
  assertNonEmptyString(match.runtimeId, "taskTerminal.runtimeId");
702
884
  const directory = await evidenceDirectory(match.cwd);
703
- return path.join(directory, taskTerminalFileName(match.runtimeId, match.taskId));
885
+ return path2.join(directory, taskTerminalFileName(match.runtimeId, match.taskId));
704
886
  }
705
887
  enqueue(key, task) {
706
888
  const previous = this.queues.get(key) ?? Promise.resolve();
@@ -1011,7 +1193,7 @@ function gitEnvironment(readOnly) {
1011
1193
  return env;
1012
1194
  }
1013
1195
  function stableGitWorkspaceOwnerId(storeDir, productId) {
1014
- const identity = `${path.resolve(storeDir)}\\0${productId}`;
1196
+ const identity = `${path2.resolve(storeDir)}\\0${productId}`;
1015
1197
  return `store-product:${createHash("sha256").update(identity).digest("hex")}`;
1016
1198
  }
1017
1199
  var GUIDANCE = [
@@ -1023,11 +1205,11 @@ var GUIDANCE = [
1023
1205
  "Leave incomplete work visible for recovery."
1024
1206
  ].join("\n");
1025
1207
  function canonical(value) {
1026
- return path.resolve(value);
1208
+ return path2.resolve(value);
1027
1209
  }
1028
1210
  function isContained(root, candidate) {
1029
- const relative = path.relative(root, candidate);
1030
- return relative === "" || !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
1211
+ const relative = path2.relative(root, candidate);
1212
+ return relative === "" || !relative.startsWith(`..${path2.sep}`) && !path2.isAbsolute(relative);
1031
1213
  }
1032
1214
  function bounded(value, max) {
1033
1215
  return Buffer.byteLength(value, "utf8") <= max ? value : value.slice(0, max);
@@ -1132,7 +1314,7 @@ var GitWorkspaceManager = class {
1132
1314
  await this.ensureOwnerMarker();
1133
1315
  }
1134
1316
  async ensureOwnerMarker() {
1135
- const markerPath = path.join(this.workspaceRoot, OWNER_MARKER);
1317
+ const markerPath = path2.join(this.workspaceRoot, OWNER_MARKER);
1136
1318
  let existing;
1137
1319
  try {
1138
1320
  existing = JSON.parse(await promises.readFile(markerPath, "utf8"));
@@ -1291,7 +1473,7 @@ ${instruction}`;
1291
1473
  if (error instanceof GitWorkspaceError || code !== "ENOENT" && code !== "ENOTDIR") {
1292
1474
  throw new GitWorkspaceError("workspace-root-invalid", "workspace directory is invalid");
1293
1475
  }
1294
- const parent = path.dirname(current);
1476
+ const parent = path2.dirname(current);
1295
1477
  if (parent === current) {
1296
1478
  throw new GitWorkspaceError("workspace-root-invalid", "workspace directory is invalid");
1297
1479
  }
@@ -1316,74 +1498,6 @@ ${instruction}`;
1316
1498
  function prependGitWorkspaceGuidance(instruction) {
1317
1499
  return GitWorkspaceManager.prependGuidance(instruction);
1318
1500
  }
1319
- var tmpSeq = 0;
1320
- async function atomicWriteFile(filePath, data, options = {}) {
1321
- const tmpPath = `${filePath}.${process.pid}-${tmpSeq++}.tmp`;
1322
- try {
1323
- const handle = await promises.open(tmpPath, "w", options.mode);
1324
- try {
1325
- await handle.writeFile(data);
1326
- if (options.mode !== void 0) {
1327
- await handle.chmod(options.mode);
1328
- }
1329
- if (options.fsync) {
1330
- await handle.sync();
1331
- }
1332
- } finally {
1333
- await handle.close();
1334
- }
1335
- } catch (err) {
1336
- await promises.rm(tmpPath, { force: true }).catch(() => {
1337
- });
1338
- throw err;
1339
- }
1340
- await renameOnto(tmpPath, filePath);
1341
- if (options.mode !== void 0) {
1342
- await promises.chmod(filePath, options.mode);
1343
- }
1344
- if (options.fsync) {
1345
- const target = await promises.open(filePath, process.platform === "win32" ? "r+" : "r");
1346
- try {
1347
- await target.sync();
1348
- } finally {
1349
- await target.close();
1350
- }
1351
- if (process.platform !== "win32") {
1352
- const directory = await promises.open(path.dirname(filePath), "r");
1353
- try {
1354
- await directory.sync();
1355
- } finally {
1356
- await directory.close();
1357
- }
1358
- }
1359
- }
1360
- }
1361
- var RENAME_RETRY_ATTEMPTS = 5;
1362
- var RENAME_RETRY_DELAY_MS = 20;
1363
- function delay(ms) {
1364
- return new Promise((resolve) => setTimeout(resolve, ms));
1365
- }
1366
- async function renameOnto(tmpPath, targetPath) {
1367
- for (let attempt = 1; attempt <= RENAME_RETRY_ATTEMPTS; attempt++) {
1368
- try {
1369
- await promises.rename(tmpPath, targetPath);
1370
- return;
1371
- } catch (err) {
1372
- const code = err.code;
1373
- if (code !== "EPERM" && code !== "EEXIST") {
1374
- await promises.rm(tmpPath, { force: true }).catch(() => {
1375
- });
1376
- throw err;
1377
- }
1378
- if (attempt === RENAME_RETRY_ATTEMPTS) {
1379
- await promises.rm(tmpPath, { force: true }).catch(() => {
1380
- });
1381
- throw err;
1382
- }
1383
- await delay(RENAME_RETRY_DELAY_MS * attempt);
1384
- }
1385
- }
1386
- }
1387
1501
  var defaultRunner = (command, args) => new Promise((resolve, reject) => {
1388
1502
  execFile(command, args, (error, stdout, stderr) => {
1389
1503
  if (error && typeof error.code !== "number") {
@@ -1510,7 +1624,7 @@ function isProtected(record) {
1510
1624
  var GitWorkspaceStore = class {
1511
1625
  constructor(storeDir, options = {}) {
1512
1626
  this.storeDir = storeDir;
1513
- this.filePath = path.join(storeDir, FILE_NAME);
1627
+ this.filePath = path2.join(storeDir, FILE_NAME);
1514
1628
  this.maxRecords = Math.max(1, Math.floor(options.maxRecords ?? MAX_RECORDS));
1515
1629
  }
1516
1630
  storeDir;
@@ -1645,7 +1759,7 @@ var GitWorkspaceStore = class {
1645
1759
  var BYOK_PI_MCP_CONFIG_PATH = "BYOK_PI_MCP_CONFIG_PATH";
1646
1760
  var PI_PACKAGE_NAME = "@earendil-works/pi-coding-agent";
1647
1761
  function readPackageJson(dir) {
1648
- const candidate = path.join(dir, "package.json");
1762
+ const candidate = path2.join(dir, "package.json");
1649
1763
  if (!existsSync(candidate)) return void 0;
1650
1764
  try {
1651
1765
  return JSON.parse(readFileSync(candidate, "utf8"));
@@ -1660,17 +1774,17 @@ function resolvePiBin() {
1660
1774
  }
1661
1775
  try {
1662
1776
  const mainEntryUrl = import.meta.resolve(PI_PACKAGE_NAME);
1663
- let dir = path.dirname(fileURLToPath(mainEntryUrl));
1777
+ let dir = path2.dirname(fileURLToPath(mainEntryUrl));
1664
1778
  for (let depth = 0; depth < 6; depth++) {
1665
1779
  const pkg = readPackageJson(dir);
1666
1780
  if (pkg?.name === PI_PACKAGE_NAME) {
1667
1781
  const binRel = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.pi;
1668
1782
  if (binRel) {
1669
- return { command: path.join(dir, binRel), source: "package" };
1783
+ return { command: path2.join(dir, binRel), source: "package" };
1670
1784
  }
1671
1785
  break;
1672
1786
  }
1673
- const parent = path.dirname(dir);
1787
+ const parent = path2.dirname(dir);
1674
1788
  if (parent === dir) break;
1675
1789
  dir = parent;
1676
1790
  }
@@ -1688,7 +1802,7 @@ function resolvePiExtensions() {
1688
1802
  const clientManifest = fileURLToPath(import.meta.resolve("@byok-sdk/client/package.json"));
1689
1803
  return {
1690
1804
  webAccess: fileURLToPath(import.meta.resolve("pi-web-access/index.ts")),
1691
- mcpAdapter: path.join(path.dirname(clientManifest), "dist", "adapters", "pi", "mcp-extension.js")
1805
+ mcpAdapter: path2.join(path2.dirname(clientManifest), "dist", "adapters", "pi", "mcp-extension.js")
1692
1806
  };
1693
1807
  }
1694
1808
 
@@ -2614,10 +2728,10 @@ var PiAdapter = class {
2614
2728
  const taskMcpServers = startInput.mcpServers ?? {};
2615
2729
  const hasMcpServers = Object.keys(taskMcpServers).length > 0;
2616
2730
  if (hasMcpServers) {
2617
- mcpConfigDir = await promises.mkdtemp(path.join(os.tmpdir(), "byok-pi-mcp-"));
2731
+ mcpConfigDir = await promises.mkdtemp(path2.join(os.tmpdir(), "byok-pi-mcp-"));
2618
2732
  await promises.chmod(mcpConfigDir, 448).catch(() => {
2619
2733
  });
2620
- const mcpConfigPath = path.join(mcpConfigDir, "mcp-config.json");
2734
+ const mcpConfigPath = path2.join(mcpConfigDir, "mcp-config.json");
2621
2735
  await promises.writeFile(mcpConfigPath, JSON.stringify({ mcpServers: taskMcpServers }), { mode: 384 });
2622
2736
  runtimeEnv = { ...runtimeEnv, [BYOK_PI_MCP_CONFIG_PATH]: mcpConfigPath };
2623
2737
  }
@@ -2848,7 +2962,7 @@ function resolveApprovalMcpBin() {
2848
2962
  if (override) {
2849
2963
  return { command: override, args: [], source: "env" };
2850
2964
  }
2851
- const distBin = path.join(path.dirname(fileURLToPath(import.meta.url)), "bin", "byok-approval-mcp.js");
2965
+ const distBin = path2.join(path2.dirname(fileURLToPath(import.meta.url)), "bin", "byok-approval-mcp.js");
2852
2966
  return { command: process.execPath, args: [distBin], source: "dist" };
2853
2967
  }
2854
2968
 
@@ -2939,7 +3053,7 @@ var EXTENSION_CONTENT_TYPES = {
2939
3053
  ".yml": "application/yaml"
2940
3054
  };
2941
3055
  function guessContentType(filePath) {
2942
- const ext = path.extname(filePath).toLowerCase();
3056
+ const ext = path2.extname(filePath).toLowerCase();
2943
3057
  return EXTENSION_CONTENT_TYPES[ext] ?? "application/octet-stream";
2944
3058
  }
2945
3059
  function mapAssistant(msg, correlation) {
@@ -3023,11 +3137,11 @@ function tryBuildArtifactEvent(msg, workspaceDir) {
3023
3137
  const filePath = toolUseResult && typeof toolUseResult.filePath === "string" ? toolUseResult.filePath : void 0;
3024
3138
  if (!filePath) return void 0;
3025
3139
  const realWorkspaceDir = tryRealpath(workspaceDir) ?? workspaceDir;
3026
- const fileDir = path.dirname(filePath);
3140
+ const fileDir = path2.dirname(filePath);
3027
3141
  const realFileDir = tryRealpath(fileDir) ?? fileDir;
3028
- const realFilePath = path.join(realFileDir, path.basename(filePath));
3029
- const relative = path.relative(realWorkspaceDir, realFilePath);
3030
- if (relative === "" || relative.startsWith("..") || path.isAbsolute(relative)) {
3142
+ const realFilePath = path2.join(realFileDir, path2.basename(filePath));
3143
+ const relative = path2.relative(realWorkspaceDir, realFilePath);
3144
+ if (relative === "" || relative.startsWith("..") || path2.isAbsolute(relative)) {
3031
3145
  return void 0;
3032
3146
  }
3033
3147
  return { type: "artifact", name: relative, contentType: guessContentType(filePath) };
@@ -3421,10 +3535,10 @@ var ClaudeAdapter = class {
3421
3535
  });
3422
3536
  }
3423
3537
  if (needsMcpConfig) {
3424
- mcpConfigDir = await promises.mkdtemp(path.join(os.tmpdir(), "byok-mcp-"));
3538
+ mcpConfigDir = await promises.mkdtemp(path2.join(os.tmpdir(), "byok-mcp-"));
3425
3539
  await promises.chmod(mcpConfigDir, 448).catch(() => {
3426
3540
  });
3427
- const mcpConfigPath = path.join(mcpConfigDir, "mcp-config.json");
3541
+ const mcpConfigPath = path2.join(mcpConfigDir, "mcp-config.json");
3428
3542
  const mcpServers = { ...taskMcpServers };
3429
3543
  if (mapping.needsApprovalMcp) {
3430
3544
  const approvalChannel = startInput.approvalChannel;
@@ -3910,8 +4024,8 @@ function extractArtifactEvents(changes, workspaceDir) {
3910
4024
  const absolutePath = typeof change.path === "string" ? change.path : void 0;
3911
4025
  const kind = typeof change.kind === "string" ? change.kind : void 0;
3912
4026
  if (!absolutePath || kind === "delete") continue;
3913
- const relative = path.relative(workspaceDir, absolutePath);
3914
- if (relative.length === 0 || relative.startsWith("..") || path.isAbsolute(relative)) continue;
4027
+ const relative = path2.relative(workspaceDir, absolutePath);
4028
+ if (relative.length === 0 || relative.startsWith("..") || path2.isAbsolute(relative)) continue;
3915
4029
  events.push({ type: "artifact", name: relative, contentType: guessContentType2(relative) });
3916
4030
  }
3917
4031
  return events;
@@ -3932,7 +4046,7 @@ var CONTENT_TYPE_BY_EXTENSION = {
3932
4046
  ".csv": "text/csv"
3933
4047
  };
3934
4048
  function guessContentType2(relativePath) {
3935
- return CONTENT_TYPE_BY_EXTENSION[path.extname(relativePath).toLowerCase()] ?? "application/octet-stream";
4049
+ return CONTENT_TYPE_BY_EXTENSION[path2.extname(relativePath).toLowerCase()] ?? "application/octet-stream";
3936
4050
  }
3937
4051
  function extractErrorMessage(rawError) {
3938
4052
  if (typeof rawError === "string") return rawError;
@@ -4788,12 +4902,12 @@ var DeviceStore = class _DeviceStore {
4788
4902
  */
4789
4903
  constructor(storeDir, secureDirOptions) {
4790
4904
  this.secureDirOptions = secureDirOptions;
4791
- this.filePath = path.join(storeDir, "device.json");
4905
+ this.filePath = path2.join(storeDir, "device.json");
4792
4906
  }
4793
4907
  secureDirOptions;
4794
4908
  filePath;
4795
4909
  static defaultDir(productId) {
4796
- return path.join(os.homedir(), ".byok", productId);
4910
+ return path2.join(os.homedir(), ".byok", productId);
4797
4911
  }
4798
4912
  /**
4799
4913
  * Resolve the one store pathname every daemon/CLI component must share.
@@ -4802,7 +4916,7 @@ var DeviceStore = class _DeviceStore {
4802
4916
  * cwd to pin a quarantine directory inode.
4803
4917
  */
4804
4918
  static resolveDir(productId, configured) {
4805
- return path.resolve(configured ?? _DeviceStore.defaultDir(productId));
4919
+ return path2.resolve(configured ?? _DeviceStore.defaultDir(productId));
4806
4920
  }
4807
4921
  async load() {
4808
4922
  const opened = await this.openBounded();
@@ -4844,7 +4958,7 @@ var DeviceStore = class _DeviceStore {
4844
4958
  }
4845
4959
  async save(record) {
4846
4960
  assertDeviceRecord(record);
4847
- const storeDir = path.dirname(this.filePath);
4961
+ const storeDir = path2.dirname(this.filePath);
4848
4962
  await ensureSecureDir(storeDir, this.secureDirOptions);
4849
4963
  await atomicWriteFile(this.filePath, JSON.stringify(record, null, 2), { mode: 384 });
4850
4964
  }
@@ -5498,19 +5612,19 @@ function shortHash(input) {
5498
5612
  return createHash("sha256").update(input, "utf8").digest("hex").slice(0, 16);
5499
5613
  }
5500
5614
  function controlSocketPath(storeDir) {
5501
- const candidate = path.join(storeDir, "control.sock");
5615
+ const candidate = path2.join(storeDir, "control.sock");
5502
5616
  if (Buffer.byteLength(candidate, "utf8") <= UNIX_SOCKET_PATH_SOFT_LIMIT) return candidate;
5503
- return path.join(CONTROL_SOCKET_FALLBACK_ROOT, `byok-${shortHash(storeDir)}`, "sock");
5617
+ return path2.join(CONTROL_SOCKET_FALLBACK_ROOT, `byok-${shortHash(storeDir)}`, "sock");
5504
5618
  }
5505
5619
  function controlPipeName(productId, storeDir) {
5506
- const id = shortHash(`${productId}|${path.resolve(storeDir)}`);
5620
+ const id = shortHash(`${productId}|${path2.resolve(storeDir)}`);
5507
5621
  return `\\\\.\\pipe\\byok-${id}`;
5508
5622
  }
5509
5623
  function controlEndpointPath(productId, storeDir, platform = process.platform) {
5510
5624
  return platform === "win32" ? controlPipeName(productId, storeDir) : controlSocketPath(storeDir);
5511
5625
  }
5512
5626
  function controlTokenPath(storeDir) {
5513
- return path.join(storeDir, "control.token");
5627
+ return path2.join(storeDir, "control.token");
5514
5628
  }
5515
5629
  var SERVER_PROOF_LABEL = "byok-control-server|";
5516
5630
  var CLIENT_AUTH_LABEL = "byok-control-client|";
@@ -5689,7 +5803,7 @@ async function assertOwnedPrivateDir(dir) {
5689
5803
  }
5690
5804
  async function bindControlEndpoint(server, endpoint) {
5691
5805
  if (process.platform !== "win32") {
5692
- const endpointDir = path.dirname(endpoint);
5806
+ const endpointDir = path2.dirname(endpoint);
5693
5807
  await promises.mkdir(endpointDir, { recursive: true, mode: 448 });
5694
5808
  await promises.chmod(endpointDir, 448).catch(() => {
5695
5809
  });
@@ -6588,7 +6702,7 @@ function toBytes(data, _isBinary) {
6588
6702
 
6589
6703
  // src/daemon/connection-manager.ts
6590
6704
  function isCursorEnvelopeType(type) {
6591
- return type.startsWith("task.") || type === "agent.egress.ack" || type === "agent.content.read";
6705
+ return type.startsWith("task.") || type === "agent.egress.ack" || type === "agent.content.read" || type === "agent.home.projection";
6592
6706
  }
6593
6707
  var ConnectionManager = class {
6594
6708
  constructor(opts) {
@@ -7103,6 +7217,10 @@ var ConnectionManager = class {
7103
7217
  async process(envelope, tracked) {
7104
7218
  const seq = tracked ? envelope.seq : void 0;
7105
7219
  try {
7220
+ if (tracked && this.cursor === void 0) {
7221
+ await this.opts.cursorStore.save(this.opts.serverUrl, this.opts.deviceId, 0);
7222
+ this.cursor = 0;
7223
+ }
7106
7224
  await this.opts.onEnvelope(envelope);
7107
7225
  if (!tracked) return;
7108
7226
  this.processedSeqs.add(seq);
@@ -7332,7 +7450,7 @@ function sameFileState2(left, right) {
7332
7450
  return left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs;
7333
7451
  }
7334
7452
  async function openOperationalHealthFile(storeDir) {
7335
- const filePath = path.join(storeDir, OPERATIONAL_HEALTH_FILENAME);
7453
+ const filePath = path2.join(storeDir, OPERATIONAL_HEALTH_FILENAME);
7336
7454
  let namedBefore;
7337
7455
  try {
7338
7456
  namedBefore = await promises.lstat(filePath, { bigint: true });
@@ -7374,7 +7492,7 @@ var OperationalHealthTracker = class {
7374
7492
  #writeTail = Promise.resolve();
7375
7493
  #started = false;
7376
7494
  constructor(storeDir, options = {}) {
7377
- this.#filePath = path.join(storeDir, OPERATIONAL_HEALTH_FILENAME);
7495
+ this.#filePath = path2.join(storeDir, OPERATIONAL_HEALTH_FILENAME);
7378
7496
  this.#windowMs = options.windowMs ?? 6e4;
7379
7497
  this.#failureThreshold = options.failureThreshold ?? 3;
7380
7498
  this.#maxFailures = options.maxFailures ?? 128;
@@ -7461,7 +7579,7 @@ var OperationalHealthTracker = class {
7461
7579
  async #load() {
7462
7580
  let opened;
7463
7581
  try {
7464
- opened = await openOperationalHealthFile(path.dirname(this.#filePath));
7582
+ opened = await openOperationalHealthFile(path2.dirname(this.#filePath));
7465
7583
  } catch (err) {
7466
7584
  throw new Error("operational health state could not be read");
7467
7585
  }
@@ -7497,7 +7615,7 @@ var OperationalHealthTracker = class {
7497
7615
  if (!this.#state) return;
7498
7616
  const body = JSON.stringify(this.#state, null, 2);
7499
7617
  this.#writeTail = this.#writeTail.then(async () => {
7500
- await ensureSecureDir(path.dirname(this.#filePath));
7618
+ await ensureSecureDir(path2.dirname(this.#filePath));
7501
7619
  await atomicWriteFile(this.#filePath, body, { mode: 384, fsync: true });
7502
7620
  });
7503
7621
  try {
@@ -7625,9 +7743,9 @@ function storeMutexIdentity(canonicalStoreDir) {
7625
7743
  }
7626
7744
  function storeMutexEndpoint(canonicalStoreDir, identity, platform = process.platform) {
7627
7745
  if (platform === "win32") return `\\\\.\\pipe\\byok-store-mutex-${identity.slice(0, 16)}`;
7628
- const candidate = path.join(canonicalStoreDir, STORE_MUTEX_SOCKET_FILENAME);
7746
+ const candidate = path2.join(canonicalStoreDir, STORE_MUTEX_SOCKET_FILENAME);
7629
7747
  if (Buffer.byteLength(candidate, "utf8") <= UNIX_SOCKET_PATH_SOFT_LIMIT2) return candidate;
7630
- return path.join(STORE_MUTEX_FALLBACK_ROOT, `byok-store-mutex-${identity.slice(0, 16)}`, "sock");
7748
+ return path2.join(STORE_MUTEX_FALLBACK_ROOT, `byok-store-mutex-${identity.slice(0, 16)}`, "sock");
7631
7749
  }
7632
7750
  var DaemonOwnerActiveError = class extends Error {
7633
7751
  constructor(role) {
@@ -7799,7 +7917,7 @@ async function acquireStoreMutex(canonicalStoreDir) {
7799
7917
  const endpoint = storeMutexEndpoint(canonicalStoreDir, identity);
7800
7918
  const isPipe = process.platform === "win32";
7801
7919
  if (!isPipe) {
7802
- const endpointDir = path.dirname(endpoint);
7920
+ const endpointDir = path2.dirname(endpoint);
7803
7921
  if (endpointDir !== canonicalStoreDir) {
7804
7922
  await ensureSecureDir(endpointDir);
7805
7923
  await assertOwnedPrivateDir2(endpointDir);
@@ -7879,8 +7997,8 @@ async function acquireDaemonOwner(storeDir, role, clock = () => /* @__PURE__ */
7879
7997
  await mutex.close().catch(() => void 0);
7880
7998
  throw err;
7881
7999
  }
7882
- const ownerPath = path.join(storeDir, DAEMON_OWNER_FILENAME);
7883
- const reclaimPath = path.join(storeDir, RECLAIM_FILENAME);
8000
+ const ownerPath = path2.join(storeDir, DAEMON_OWNER_FILENAME);
8001
+ const reclaimPath = path2.join(storeDir, RECLAIM_FILENAME);
7884
8002
  const record = {
7885
8003
  version: 2,
7886
8004
  pid: process.pid,
@@ -7958,7 +8076,7 @@ var CursorStore = class {
7958
8076
  storeDir;
7959
8077
  fileFor(serverUrl, deviceId) {
7960
8078
  const key = createHash("sha256").update(`${serverUrl}::${deviceId}`).digest("hex").slice(0, 32);
7961
- return path.join(this.storeDir, `cursor-${key}.json`);
8079
+ return path2.join(this.storeDir, `cursor-${key}.json`);
7962
8080
  }
7963
8081
  async load(serverUrl, deviceId) {
7964
8082
  let raw;
@@ -7978,7 +8096,7 @@ var CursorStore = class {
7978
8096
  }
7979
8097
  async save(serverUrl, deviceId, cursor) {
7980
8098
  const file = this.fileFor(serverUrl, deviceId);
7981
- await promises.mkdir(path.dirname(file), { recursive: true, mode: 448 });
8099
+ await promises.mkdir(path2.dirname(file), { recursive: true, mode: 448 });
7982
8100
  await atomicWriteFile(file, JSON.stringify({ cursor }));
7983
8101
  }
7984
8102
  /** 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. */
@@ -8308,7 +8426,7 @@ var SessionWorkspaceStore = class {
8308
8426
  */
8309
8427
  queue = Promise.resolve();
8310
8428
  constructor(storeDir) {
8311
- this.filePath = path.join(storeDir, "session-workspaces.json");
8429
+ this.filePath = path2.join(storeDir, "session-workspaces.json");
8312
8430
  }
8313
8431
  async get(sessionRef) {
8314
8432
  return this.enqueue(async () => {
@@ -8366,7 +8484,7 @@ var SessionWorkspaceStore = class {
8366
8484
  }
8367
8485
  }
8368
8486
  async save(all) {
8369
- const dir = path.dirname(this.filePath);
8487
+ const dir = path2.dirname(this.filePath);
8370
8488
  await promises.mkdir(dir, { recursive: true, mode: 448 });
8371
8489
  const tmpPath = `${this.filePath}.${process.pid}-${tmpSeq2++}.tmp`;
8372
8490
  try {
@@ -9910,6 +10028,11 @@ function offeredAgentRef(payload) {
9910
10028
  if (!Object.prototype.hasOwnProperty.call(payload, "agentRef")) return void 0;
9911
10029
  return validateAgentRef(payload.agentRef);
9912
10030
  }
10031
+ function offeredSessionRef(payload) {
10032
+ if (!Object.prototype.hasOwnProperty.call(payload, "sessionRef")) return void 0;
10033
+ const value = payload.sessionRef;
10034
+ return typeof value === "string" ? value : void 0;
10035
+ }
9913
10036
  function errorMessage4(err) {
9914
10037
  return err instanceof Error ? err.message : String(err);
9915
10038
  }
@@ -9945,8 +10068,8 @@ function estimateEventBytes(event) {
9945
10068
  }
9946
10069
  async function openArtifact(workspaceDir, name) {
9947
10070
  const realWorkspaceDir = await promises.realpath(workspaceDir).catch(() => workspaceDir);
9948
- const candidate = path.resolve(realWorkspaceDir, name);
9949
- const prefix = realWorkspaceDir.endsWith(path.sep) ? realWorkspaceDir : realWorkspaceDir + path.sep;
10071
+ const candidate = path2.resolve(realWorkspaceDir, name);
10072
+ const prefix = realWorkspaceDir.endsWith(path2.sep) ? realWorkspaceDir : realWorkspaceDir + path2.sep;
9950
10073
  if (candidate !== realWorkspaceDir && !candidate.startsWith(prefix)) {
9951
10074
  return { ok: false, reason: `artifact name "${name}" resolves outside the task workspace \u2014 rejected` };
9952
10075
  }
@@ -10278,6 +10401,9 @@ var TaskRunner = class {
10278
10401
  case "task.offer_for_agent_with_egress":
10279
10402
  await this.handleOffer(envelope.task_id, envelope.payload, true);
10280
10403
  return;
10404
+ case "task.offer_for_agent_with_egress_fresh":
10405
+ await this.handleOffer(envelope.task_id, envelope.payload, true);
10406
+ return;
10281
10407
  case "task.cancel":
10282
10408
  await this.handleCancel(envelope.task_id, envelope.payload.reason);
10283
10409
  return;
@@ -10319,6 +10445,7 @@ var TaskRunner = class {
10319
10445
  const decline = (reason, retryable) => {
10320
10446
  this.decline(taskId, reason, retryable, agentRef);
10321
10447
  };
10448
+ const sessionRef = offeredSessionRef(payload);
10322
10449
  if ("egressPolicy" in payload) {
10323
10450
  if (this.deps.agentEgressPolicy === void 0 || !sameEgressPolicy(this.deps.agentEgressPolicy, payload.egressPolicy)) {
10324
10451
  decline("Agent egress offer policy is not exactly enabled by this daemon", false);
@@ -10420,11 +10547,11 @@ var TaskRunner = class {
10420
10547
  let plainWorkspaceNeedsResolve = false;
10421
10548
  if (agentBinding !== void 0) {
10422
10549
  workspaceDir = agentBinding.lease.cwd;
10423
- if (payload.sessionRef !== void 0) {
10550
+ if (sessionRef !== void 0) {
10424
10551
  try {
10425
10552
  await this.deps.agentSessionHandoffs.requireMatch({
10426
10553
  agentRef: agentBinding.resolution.agentRef,
10427
- sessionRef: payload.sessionRef,
10554
+ sessionRef,
10428
10555
  runtimeId: pick.descriptor.id,
10429
10556
  cwd: workspaceDir
10430
10557
  });
@@ -10446,15 +10573,15 @@ var TaskRunner = class {
10446
10573
  return;
10447
10574
  }
10448
10575
  } else if (this.deps.gitWorkspaceManager && this.deps.gitWorkspaceStore) {
10449
- known = payload.sessionRef ? await this.deps.sessionWorkspaces.get(payload.sessionRef) : void 0;
10576
+ known = sessionRef ? await this.deps.sessionWorkspaces.get(sessionRef) : void 0;
10450
10577
  const gitManager = this.deps.gitWorkspaceManager;
10451
10578
  const gitStore = this.deps.gitWorkspaceStore;
10452
- if (payload.sessionRef) {
10453
- const ledger = await gitStore.findBySessionAnyPhase(payload.sessionRef).catch(() => void 0);
10579
+ if (sessionRef) {
10580
+ const ledger = await gitStore.findBySessionAnyPhase(sessionRef).catch(() => void 0);
10454
10581
  const sameProtocolTask = ledger?.taskId === taskId;
10455
10582
  const interruptedOldTask = ledger?.phase === "interrupted" && sameProtocolTask;
10456
10583
  const activeDifferentTask = ledger !== void 0 && ledger.taskId !== taskId && (ledger.phase === "preparing" || ledger.phase === "active");
10457
- if (!known || known.workspaceKind !== "git" || !known.gitWorkspaceId || !ledger || ledger.workspaceId !== known.gitWorkspaceId || ledger.sessionRef !== payload.sessionRef || path.resolve(ledger.workspaceDir) !== path.resolve(known.workspaceDir) || interruptedOldTask || activeDifferentTask) {
10584
+ 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) {
10458
10585
  decline("session is incompatible with Git workspace mode", true);
10459
10586
  return;
10460
10587
  }
@@ -10469,18 +10596,18 @@ var TaskRunner = class {
10469
10596
  return;
10470
10597
  }
10471
10598
  } else {
10472
- workspaceDir = path.join(this.deps.workspaceRoot, taskId);
10599
+ workspaceDir = path2.join(this.deps.workspaceRoot, taskId);
10473
10600
  gitWorkspaceId = randomUUID();
10474
10601
  }
10475
10602
  try {
10476
- gitLease = await gitManager.acquireLease(workspaceDir, payload.sessionRef);
10603
+ gitLease = await gitManager.acquireLease(workspaceDir, sessionRef);
10477
10604
  } catch {
10478
10605
  decline("workspace is busy or unavailable", true);
10479
10606
  return;
10480
10607
  }
10481
10608
  } else if (!this.deps.gitWorkspaceManager && !this.deps.gitWorkspaceStore) {
10482
- known = payload.sessionRef ? await this.deps.sessionWorkspaces.get(payload.sessionRef) : void 0;
10483
- workspaceDir = known?.workspaceDir ?? path.join(this.deps.workspaceRoot, taskId);
10609
+ known = sessionRef ? await this.deps.sessionWorkspaces.get(sessionRef) : void 0;
10610
+ workspaceDir = known?.workspaceDir ?? path2.join(this.deps.workspaceRoot, taskId);
10484
10611
  plainWorkspaceNeedsResolve = true;
10485
10612
  } else {
10486
10613
  decline("workspace mode is unavailable", true);
@@ -10498,7 +10625,7 @@ var TaskRunner = class {
10498
10625
  policy: decision.policy,
10499
10626
  requiredToolsetIds: requiredToolsets ?? [],
10500
10627
  ...offered.dispatchSelection === void 0 ? {} : { dispatchSelection: offered.dispatchSelection },
10501
- ...payload.sessionRef === void 0 || known === void 0 && agentBinding === void 0 ? {} : { sessionRef: payload.sessionRef },
10628
+ ...sessionRef === void 0 || known === void 0 && agentBinding === void 0 ? {} : { sessionRef },
10502
10629
  ...agentBinding === void 0 ? {} : {
10503
10630
  agentRef: agentBinding.resolution.agentRef,
10504
10631
  cwd: agentBinding.lease.cwd,
@@ -10601,7 +10728,7 @@ var TaskRunner = class {
10601
10728
  workspaceId,
10602
10729
  taskId,
10603
10730
  workspaceDir,
10604
- sessionRef: payload.sessionRef,
10731
+ sessionRef,
10605
10732
  phase,
10606
10733
  baseline: gitBaseline ?? observation.head,
10607
10734
  current: observation.head,
@@ -11867,7 +11994,7 @@ var TaskRunner = class {
11867
11994
  }
11868
11995
  /** `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. */
11869
11996
  async resolveWorkspaceDir(taskId, reuseDir) {
11870
- const dir = reuseDir ?? path.join(this.deps.workspaceRoot, taskId);
11997
+ const dir = reuseDir ?? path2.join(this.deps.workspaceRoot, taskId);
11871
11998
  await promises.mkdir(dir, { recursive: true });
11872
11999
  return dir;
11873
12000
  }
@@ -12005,7 +12132,7 @@ var encoder2 = new TextEncoder();
12005
12132
  function eventBytes(event) {
12006
12133
  return encoder2.encode(JSON.stringify(event)).length;
12007
12134
  }
12008
- var AGENT_EGRESS_DIRECTORY = path.join(".byok", "egress");
12135
+ var AGENT_EGRESS_DIRECTORY = path2.join(".byok", "egress");
12009
12136
  var AGENT_RELIABLE_SPOOL_FILENAME = "reliable-v1.jsonl";
12010
12137
  var AgentReliableSpoolError = class extends Error {
12011
12138
  constructor(message) {
@@ -12116,9 +12243,9 @@ var AgentReliableSpool = class _AgentReliableSpool {
12116
12243
  logEntries = 0;
12117
12244
  writeTail = Promise.resolve();
12118
12245
  static async open(homeDir) {
12119
- const directory = path.join(homeDir, AGENT_EGRESS_DIRECTORY);
12246
+ const directory = path2.join(homeDir, AGENT_EGRESS_DIRECTORY);
12120
12247
  await ensureSecureDir(directory);
12121
- const spool = new _AgentReliableSpool(homeDir, path.join(directory, AGENT_RELIABLE_SPOOL_FILENAME));
12248
+ const spool = new _AgentReliableSpool(homeDir, path2.join(directory, AGENT_RELIABLE_SPOOL_FILENAME));
12122
12249
  await spool.load();
12123
12250
  return spool;
12124
12251
  }
@@ -12581,7 +12708,7 @@ var AgentEgressController = class {
12581
12708
  }
12582
12709
  /** Re-open every existing Agent-local spool before retrying stable records after restart. */
12583
12710
  async recover(agentsRoot) {
12584
- if (!path.isAbsolute(agentsRoot)) throw new Error("Agent egress recovery root must be absolute");
12711
+ if (!path2.isAbsolute(agentsRoot)) throw new Error("Agent egress recovery root must be absolute");
12585
12712
  if (!this.active) throw new Error("Agent egress recovery requires an active authenticated enrollment");
12586
12713
  if (this.options.tenantId === void 0) {
12587
12714
  throw new Error("Agent egress recovery requires one authenticated tenant authority");
@@ -12596,14 +12723,14 @@ var AgentEgressController = class {
12596
12723
  }
12597
12724
  for (const entry of entries) {
12598
12725
  if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
12599
- const homeDir = path.join(canonicalAgentsRoot, entry.name);
12726
+ const homeDir = path2.join(canonicalAgentsRoot, entry.name);
12600
12727
  const canonicalHome = await promises.realpath(homeDir);
12601
- const relativeHome = path.relative(canonicalAgentsRoot, canonicalHome);
12602
- if (relativeHome !== entry.name || relativeHome.includes(path.sep) || path.isAbsolute(relativeHome)) {
12728
+ const relativeHome = path2.relative(canonicalAgentsRoot, canonicalHome);
12729
+ if (relativeHome !== entry.name || relativeHome.includes(path2.sep) || path2.isAbsolute(relativeHome)) {
12603
12730
  throw new Error(`Agent egress recovery home escaped the canonical agents root: ${entry.name}`);
12604
12731
  }
12605
12732
  try {
12606
- await promises.lstat(path.join(homeDir, AGENT_EGRESS_DIRECTORY));
12733
+ await promises.lstat(path2.join(homeDir, AGENT_EGRESS_DIRECTORY));
12607
12734
  } catch (error) {
12608
12735
  if (error.code === "ENOENT") continue;
12609
12736
  throw error;
@@ -12690,12 +12817,12 @@ function isAgentRef(value) {
12690
12817
  }
12691
12818
  function isCanonicalRelativeTarget(value) {
12692
12819
  if (value === "[invalid-target]") return true;
12693
- if (path.isAbsolute(value) || value.includes("\\")) return false;
12820
+ if (path2.isAbsolute(value) || value.includes("\\")) return false;
12694
12821
  const segments = value.split("/");
12695
12822
  return value.length > 0 && segments.every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
12696
12823
  }
12697
12824
  function validateIdentity(value, label) {
12698
- if (!isRecord4(value) || !isAgentRef(value.agentRef) || !isNonEmptyString(value.sessionRef) || !isNonEmptyString(value.runtimeId) || !isNonEmptyString(value.cwd) || !path.isAbsolute(value.cwd)) {
12825
+ if (!isRecord4(value) || !isAgentRef(value.agentRef) || !isNonEmptyString(value.sessionRef) || !isNonEmptyString(value.runtimeId) || !isNonEmptyString(value.cwd) || !path2.isAbsolute(value.cwd)) {
12699
12826
  throw new AgentContentAuditStoreError(`${label} has an invalid exact Agent/session identity`);
12700
12827
  }
12701
12828
  return Object.freeze({
@@ -12705,7 +12832,7 @@ function validateIdentity(value, label) {
12705
12832
  }),
12706
12833
  sessionRef: value.sessionRef,
12707
12834
  runtimeId: value.runtimeId,
12708
- cwd: path.resolve(value.cwd)
12835
+ cwd: path2.resolve(value.cwd)
12709
12836
  });
12710
12837
  }
12711
12838
  function validateReceipt(value) {
@@ -12787,16 +12914,16 @@ function assertUniqueRequestIds(entries) {
12787
12914
  }
12788
12915
  }
12789
12916
  function assertAbsoluteFilePath(filePath) {
12790
- if (typeof filePath !== "string" || filePath.length === 0 || !path.isAbsolute(filePath)) {
12917
+ if (typeof filePath !== "string" || filePath.length === 0 || !path2.isAbsolute(filePath)) {
12791
12918
  throw new AgentContentAuditStoreError("content audit path must be absolute");
12792
12919
  }
12793
12920
  if (/[\u0000\r\n]/u.test(filePath)) {
12794
12921
  throw new AgentContentAuditStoreError("content audit path must not contain NUL or line breaks");
12795
12922
  }
12796
- return path.resolve(filePath);
12923
+ return path2.resolve(filePath);
12797
12924
  }
12798
12925
  async function ensureDirectoryNoSymlink2(directory) {
12799
- const absolute = path.resolve(directory);
12926
+ const absolute = path2.resolve(directory);
12800
12927
  await promises.mkdir(absolute, { recursive: true, mode: 448 });
12801
12928
  const stat = await promises.lstat(absolute);
12802
12929
  if (!stat.isDirectory() || stat.isSymbolicLink()) {
@@ -12830,12 +12957,12 @@ var AgentContentAuditStore = class _AgentContentAuditStore {
12830
12957
  /** The daemon may address this ledger only through an AgentHomeLayout resolution. */
12831
12958
  static forCanonicalAgentHome(canonicalHome) {
12832
12959
  const home = assertAbsoluteFilePath(canonicalHome);
12833
- return new _AgentContentAuditStore(path.join(home, AGENT_HOME_INTERNAL_DIRECTORY, AGENT_CONTENT_AUDIT_FILENAME));
12960
+ return new _AgentContentAuditStore(path2.join(home, AGENT_HOME_INTERNAL_DIRECTORY, AGENT_CONTENT_AUDIT_FILENAME));
12834
12961
  }
12835
12962
  async append(receipt) {
12836
12963
  const validated = validateReceipt(receipt);
12837
12964
  return this.enqueue(async () => {
12838
- await ensureDirectoryNoSymlink2(path.dirname(this.filePath));
12965
+ await ensureDirectoryNoSymlink2(path2.dirname(this.filePath));
12839
12966
  await assertAuditFile(this.filePath);
12840
12967
  const entries = await this.readAllUnlocked();
12841
12968
  const prior = entries.find((entry) => entry.requestId === validated.requestId);
@@ -12930,6 +13057,63 @@ var AgentContentAuditStore = class _AgentContentAuditStore {
12930
13057
  return result;
12931
13058
  }
12932
13059
  };
13060
+ var AgentHomeProjectionCompletionError = class extends Error {
13061
+ constructor(message, options) {
13062
+ super(message, options);
13063
+ this.name = "AgentHomeProjectionCompletionError";
13064
+ }
13065
+ };
13066
+ function sameAgentRef2(left, right) {
13067
+ return left.agentId === right.agentId && left.profileRevision === right.profileRevision;
13068
+ }
13069
+ var AgentHomeProjectionCompletionClient = class {
13070
+ constructor(options) {
13071
+ this.options = options;
13072
+ }
13073
+ options;
13074
+ async complete(input) {
13075
+ const completion = AgentHomeProjectionCompletionRequestSchema.parse(input);
13076
+ const url = new URL(
13077
+ byokAgentHomeProjectionCompletionPath(completion.requestId),
13078
+ toHttpBase(this.options.serverUrl)
13079
+ );
13080
+ let response;
13081
+ try {
13082
+ response = await authedFetch(
13083
+ url,
13084
+ {
13085
+ method: "PUT",
13086
+ headers: { "content-type": "application/json" },
13087
+ body: JSON.stringify(completion)
13088
+ },
13089
+ this.options.auth
13090
+ );
13091
+ } catch (error) {
13092
+ throw new AgentHomeProjectionCompletionError("Agent-home projection completion transport failed", {
13093
+ cause: error
13094
+ });
13095
+ }
13096
+ if (!response.ok) {
13097
+ throw new AgentHomeProjectionCompletionError(
13098
+ `Agent-home projection completion was rejected with HTTP ${response.status}`
13099
+ );
13100
+ }
13101
+ let readback;
13102
+ try {
13103
+ readback = AgentHomeProjectionReadbackSchema.parse(await response.json());
13104
+ } catch (error) {
13105
+ throw new AgentHomeProjectionCompletionError("Agent-home projection completion readback is invalid", {
13106
+ cause: error
13107
+ });
13108
+ }
13109
+ 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) {
13110
+ throw new AgentHomeProjectionCompletionError(
13111
+ "Agent-home projection completion readback does not exactly match the authenticated request"
13112
+ );
13113
+ }
13114
+ return readback;
13115
+ }
13116
+ };
12933
13117
  var AGENT_CONTENT_READ_SURFACES = ["workspace", "transcript", "artifact"];
12934
13118
  var AGENT_CONTENT_READ_CAPABILITIES = Object.freeze({
12935
13119
  workspace: AGENT_CONTENT_WORKSPACE_READ_CAPABILITY,
@@ -13033,8 +13217,8 @@ function normalizeIdentity(value, field) {
13033
13217
  const sessionRef = nonEmptyString(value.sessionRef, `${field}.sessionRef`);
13034
13218
  const runtimeId = nonEmptyString(value.runtimeId, `${field}.runtimeId`);
13035
13219
  const cwd = nonEmptyString(value.cwd, `${field}.cwd`);
13036
- if (!path.isAbsolute(cwd)) throw new AgentContentReadPolicyError(`${field}.cwd must be absolute`);
13037
- return Object.freeze({ agentRef, sessionRef, runtimeId, cwd: path.resolve(cwd) });
13220
+ if (!path2.isAbsolute(cwd)) throw new AgentContentReadPolicyError(`${field}.cwd must be absolute`);
13221
+ return Object.freeze({ agentRef, sessionRef, runtimeId, cwd: path2.resolve(cwd) });
13038
13222
  }
13039
13223
  function createAgentContentReadPolicy(input) {
13040
13224
  if (!isRecord5(input) || input.enabled !== true) {
@@ -13062,10 +13246,10 @@ function createAgentContentReadPolicy(input) {
13062
13246
  root = Object.freeze({ kind: "agent-home" });
13063
13247
  } else if (input.root.kind === "runtime-allowlisted") {
13064
13248
  const configuredRoot = nonEmptyString(input.root.root, "contentRead.root.root");
13065
- if (!path.isAbsolute(configuredRoot)) {
13249
+ if (!path2.isAbsolute(configuredRoot)) {
13066
13250
  throw new AgentContentReadPolicyError("contentRead.root.root must be absolute");
13067
13251
  }
13068
- root = Object.freeze({ kind: "runtime-allowlisted", root: path.resolve(configuredRoot) });
13252
+ root = Object.freeze({ kind: "runtime-allowlisted", root: path2.resolve(configuredRoot) });
13069
13253
  } else {
13070
13254
  throw new AgentContentReadPolicyError("contentRead.root.kind is not supported");
13071
13255
  }
@@ -13088,11 +13272,11 @@ function createAgentContentReadPolicy(input) {
13088
13272
  });
13089
13273
  }
13090
13274
  function isWithin2(root, candidate) {
13091
- const relative = path.relative(root, candidate);
13092
- return relative === "" || relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
13275
+ const relative = path2.relative(root, candidate);
13276
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path2.sep}`) && !path2.isAbsolute(relative);
13093
13277
  }
13094
13278
  function isPortableAbsoluteTarget(value) {
13095
- return path.isAbsolute(value) || /^[a-z]:[\\/]/iu.test(value) || /^[/\\]/u.test(value);
13279
+ return path2.isAbsolute(value) || /^[a-z]:[\\/]/iu.test(value) || /^[/\\]/u.test(value);
13096
13280
  }
13097
13281
  function canonicalAuditTarget(value) {
13098
13282
  if (typeof value !== "string" || value.length === 0 || /[\u0000\r\n]/u.test(value) || isPortableAbsoluteTarget(value) || value.includes("\\")) {
@@ -13130,7 +13314,7 @@ function isSensitiveTarget(segments, productNames) {
13130
13314
  return segments.some((segment) => patterns.some((pattern) => nameMatches(pattern, segment)));
13131
13315
  }
13132
13316
  async function resolveExistingAncestor2(inputPath) {
13133
- let cursor = path.resolve(inputPath);
13317
+ let cursor = path2.resolve(inputPath);
13134
13318
  const tail = [];
13135
13319
  for (; ; ) {
13136
13320
  try {
@@ -13138,9 +13322,9 @@ async function resolveExistingAncestor2(inputPath) {
13138
13322
  } catch (error) {
13139
13323
  const code = error.code;
13140
13324
  if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
13141
- const parent = path.dirname(cursor);
13325
+ const parent = path2.dirname(cursor);
13142
13326
  if (parent === cursor) throw new TargetPolicyError("target-missing");
13143
- tail.unshift(path.basename(cursor));
13327
+ tail.unshift(path2.basename(cursor));
13144
13328
  cursor = parent;
13145
13329
  }
13146
13330
  }
@@ -13161,11 +13345,11 @@ var RootPolicyError = class extends Error {
13161
13345
  this.reason = reason;
13162
13346
  }
13163
13347
  };
13164
- function sameAgentRef2(left, right) {
13348
+ function sameAgentRef3(left, right) {
13165
13349
  return left.agentId === right.agentId && left.profileRevision === right.profileRevision;
13166
13350
  }
13167
13351
  function sameSessionIdentity(left, right) {
13168
- return sameAgentRef2(left.agentRef, right.agentRef) && left.sessionRef === right.sessionRef && left.runtimeId === right.runtimeId && left.cwd === right.cwd;
13352
+ return sameAgentRef3(left.agentRef, right.agentRef) && left.sessionRef === right.sessionRef && left.runtimeId === right.runtimeId && left.cwd === right.cwd;
13169
13353
  }
13170
13354
  function validateRequest(request) {
13171
13355
  if (!isRecord5(request)) throw new AgentContentReadRequestError("content read request must be an object");
@@ -13227,18 +13411,18 @@ function normalizeRequestIdentity(value, field) {
13227
13411
  const sessionRef = requestString(value.sessionRef, `${field}.sessionRef`);
13228
13412
  const runtimeId = requestString(value.runtimeId, `${field}.runtimeId`);
13229
13413
  const cwd = requestString(value.cwd, `${field}.cwd`);
13230
- if (!path.isAbsolute(cwd)) throw new AgentContentReadRequestError(`${field}.cwd must be absolute`);
13231
- return Object.freeze({ agentRef, sessionRef, runtimeId, cwd: path.resolve(cwd) });
13414
+ if (!path2.isAbsolute(cwd)) throw new AgentContentReadRequestError(`${field}.cwd must be absolute`);
13415
+ return Object.freeze({ agentRef, sessionRef, runtimeId, cwd: path2.resolve(cwd) });
13232
13416
  }
13233
13417
  async function inspectRegularTarget(root, target) {
13234
13418
  const ancestor = await resolveExistingAncestor2(target);
13235
13419
  if (!isWithin2(root, ancestor.canonical)) {
13236
13420
  throw new TargetPolicyError("path-escape");
13237
13421
  }
13238
- const components = path.relative(root, target).split(path.sep).filter((component) => component.length > 0);
13422
+ const components = path2.relative(root, target).split(path2.sep).filter((component) => component.length > 0);
13239
13423
  let cursor = root;
13240
13424
  for (const [index, component] of components.entries()) {
13241
- cursor = path.join(cursor, component);
13425
+ cursor = path2.join(cursor, component);
13242
13426
  let stat;
13243
13427
  try {
13244
13428
  stat = await promises.lstat(cursor);
@@ -13303,8 +13487,8 @@ var AgentContentReadPolicyEngine = class {
13303
13487
  this.capabilities = new Set(options.capabilities);
13304
13488
  this.runtimeRoots = Object.freeze((options.runtimeAllowlistedRoots ?? []).map((root, index) => {
13305
13489
  const value = nonEmptyString(root, `contentRead.runtimeAllowlistedRoots[${index}]`);
13306
- if (!path.isAbsolute(value)) throw new AgentContentReadPolicyError("runtime allowlisted roots must be absolute");
13307
- return path.resolve(value);
13490
+ if (!path2.isAbsolute(value)) throw new AgentContentReadPolicyError("runtime allowlisted roots must be absolute");
13491
+ return path2.resolve(value);
13308
13492
  }));
13309
13493
  this.resolveSessionIdentity = options.resolveSessionIdentity;
13310
13494
  this.resolveTranscriptIdentity = options.resolveTranscriptIdentity;
@@ -13356,7 +13540,7 @@ var AgentContentReadPolicyEngine = class {
13356
13540
  if (request.decodeAs === "utf8" && !policy.textMimeTypes.includes(request.mimeType)) {
13357
13541
  return this.deny(request, relativeTarget, "text-not-allowlisted");
13358
13542
  }
13359
- const target = path.resolve(root, ...segments);
13543
+ const target = path2.resolve(root, ...segments);
13360
13544
  if (!isWithin2(root, target)) return this.deny(request, relativeTarget, "path-escape");
13361
13545
  try {
13362
13546
  await inspectRegularTarget(root, target);
@@ -13437,7 +13621,7 @@ var AgentContentReadPolicyEngine = class {
13437
13621
  }
13438
13622
  async checkSessionIdentity(request, resolver, requiredCwd) {
13439
13623
  const session = request.session;
13440
- if (session === void 0 || !sameAgentRef2(session.agentRef, request.agentRef) || requiredCwd !== void 0 && session.cwd !== requiredCwd) {
13624
+ if (session === void 0 || !sameAgentRef3(session.agentRef, request.agentRef) || requiredCwd !== void 0 && session.cwd !== requiredCwd) {
13441
13625
  return "identity-mismatch";
13442
13626
  }
13443
13627
  let expected;
@@ -13553,7 +13737,7 @@ async function detectRuntimes(adapters) {
13553
13737
  }
13554
13738
  return runtimes;
13555
13739
  }
13556
- function computeCapabilities(adapters, agentHomeConfigured = false, agentEgressConfigured = false, contentReadPolicies) {
13740
+ function computeCapabilities(adapters, agentHomeConfigured = false, agentHomeProjectionConfigured = false, agentEgressConfigured = false, contentReadPolicies) {
13557
13741
  const flags = [];
13558
13742
  if (adapters.some((adapter) => adapter.descriptor.capabilities.steer)) flags.push("steer");
13559
13743
  flags.push("blob-upload");
@@ -13568,7 +13752,14 @@ function computeCapabilities(adapters, agentHomeConfigured = false, agentEgressC
13568
13752
  flags.push("toolset-selection");
13569
13753
  }
13570
13754
  if (agentHomeConfigured) flags.push("agent-home-contract");
13571
- if (agentEgressConfigured) flags.push(AGENT_EGRESS_POLICY_CAPABILITY, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY);
13755
+ if (agentHomeProjectionConfigured) flags.push(AGENT_HOME_PROJECTION_CAPABILITY);
13756
+ if (agentEgressConfigured) {
13757
+ flags.push(
13758
+ AGENT_EGRESS_POLICY_CAPABILITY,
13759
+ AGENT_EGRESS_RELIABLE_ACK_CAPABILITY,
13760
+ AGENT_EGRESS_FRESH_SESSION_CAPABILITY
13761
+ );
13762
+ }
13572
13763
  if (contentReadPolicies !== void 0) {
13573
13764
  for (const surface of Object.keys(AGENT_CONTENT_READ_CAPABILITIES)) {
13574
13765
  const policy = contentReadPolicies[surface];
@@ -13920,7 +14111,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
13920
14111
  }
13921
14112
  await agentHomeManager?.preflight();
13922
14113
  if (config.agentEgress !== void 0 && config.agentHome !== void 0) {
13923
- await agentEgress.recover(path.join(config.agentHome.hostStorageRoot, "agents"));
14114
+ await agentEgress.recover(path2.join(config.agentHome.hostStorageRoot, "agents"));
13924
14115
  }
13925
14116
  fleetJitter = createFleetJitter(config.productId, record.deviceId);
13926
14117
  if (config.permissionDefaults?.workspaceRoot !== void 0) {
@@ -13975,9 +14166,16 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
13975
14166
  const capabilities = computeCapabilities(
13976
14167
  adapters,
13977
14168
  config.agentHome !== void 0,
14169
+ agentHomeManager?.supportsTaskFreeProjection() === true,
13978
14170
  config.agentEgress !== void 0,
13979
14171
  agentContentReadPolicies
13980
14172
  );
14173
+ const agentHomeProjectionCompletion = agentHomeManager?.supportsTaskFreeProjection() === true ? new AgentHomeProjectionCompletionClient({
14174
+ serverUrl: config.serverUrl,
14175
+ auth,
14176
+ tenantId: record.tenantId,
14177
+ deviceId: record.deviceId
14178
+ }) : void 0;
13981
14179
  const journalIdentity = config.hostedJournal ? { tenantId: record.tenantId, productId: config.productId, deviceId: record.deviceId } : void 0;
13982
14180
  const sendSanitizedEnvelope = activeJournal && journalIdentity ? (envelope) => {
13983
14181
  observer.handleOutboundEnvelope(envelope);
@@ -14114,6 +14312,20 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
14114
14312
  ...activePressureEngine ? { admissionGuard: () => activePressureEngine.admissionGuard() } : {}
14115
14313
  };
14116
14314
  runner = new TaskRunner(deps);
14315
+ const handleAgentHomeProjectionEnvelope = async (envelope) => {
14316
+ if (envelope.type !== "agent.home.projection") return false;
14317
+ if (agentHomeManager === void 0 || agentHomeProjectionCompletion === void 0) {
14318
+ throw new Error("task-free Agent-home projection is not configured on this daemon");
14319
+ }
14320
+ const outcome = await agentHomeManager.project(envelope.payload);
14321
+ await agentHomeProjectionCompletion.complete({
14322
+ requestId: envelope.payload.requestId,
14323
+ agentRef: envelope.payload.agentRef,
14324
+ projectionHash: envelope.payload.projectionHash,
14325
+ outcome
14326
+ });
14327
+ return true;
14328
+ };
14117
14329
  const handleAgentEgressEnvelope = async (envelope) => {
14118
14330
  if (envelope.type !== "agent.egress.ack") return false;
14119
14331
  if (config.agentEgress === void 0) return true;
@@ -14269,6 +14481,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
14269
14481
  throw new Error("tenant enrollment is being re-paired; inbound work is blocked until restart");
14270
14482
  }
14271
14483
  observer.handleInboundEnvelope(envelope);
14484
+ if (await handleAgentHomeProjectionEnvelope(envelope)) return;
14272
14485
  if (await handleAgentEgressEnvelope(envelope)) return;
14273
14486
  if (await handleAgentContentReadEnvelope(envelope)) return;
14274
14487
  activePressureEngine?.assertAckCriticalAllowed();
@@ -14279,6 +14492,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
14279
14492
  return Promise.reject(new Error("tenant enrollment is being re-paired; inbound work is blocked until restart"));
14280
14493
  }
14281
14494
  observer.handleInboundEnvelope(envelope);
14495
+ if (envelope.type === "agent.home.projection") return handleAgentHomeProjectionEnvelope(envelope).then(() => void 0);
14282
14496
  if (envelope.type === "agent.egress.ack") return handleAgentEgressEnvelope(envelope).then(() => void 0);
14283
14497
  if (envelope.type === "agent.content.read") return handleAgentContentReadEnvelope(envelope).then(() => void 0);
14284
14498
  return runner?.handleEnvelope(envelope) ?? Promise.resolve();
@@ -14773,7 +14987,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
14773
14987
  connection.send(sanitized.envelope);
14774
14988
  }
14775
14989
  async function publishReliableAgentEgress(input) {
14776
- if (config.agentEgress === void 0 || agentHomeManager === void 0) {
14990
+ if (config.agentEgress === void 0 || agentHomeManager === void 0 || agentSessionHandoffs === void 0) {
14777
14991
  throw new Error("Agent reliable egress is not configured");
14778
14992
  }
14779
14993
  if (tenantRebinding) {
@@ -14782,12 +14996,21 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
14782
14996
  const binding = await agentHomeManager.acquire(input.agentRef);
14783
14997
  try {
14784
14998
  await agentHomeManager.initialize(binding);
14999
+ const handoff = await agentSessionHandoffs.requireMatch({
15000
+ agentRef: binding.resolution.agentRef,
15001
+ sessionRef: input.sessionRef,
15002
+ runtimeId: input.runtimeId,
15003
+ cwd: binding.resolution.canonicalHome
15004
+ });
15005
+ if (handoff.taskId !== input.taskId) {
15006
+ throw new Error("Agent reliable egress taskId does not match the durable session handoff");
15007
+ }
14785
15008
  const appended = await agentEgress.appendReliable({
14786
15009
  homeDir: binding.resolution.canonicalHome,
14787
15010
  agentRef: binding.resolution.agentRef,
14788
15011
  sessionRef: input.sessionRef,
14789
15012
  payload: input.payload,
14790
- ...input.taskId === void 0 ? {} : { taskId: input.taskId },
15013
+ taskId: input.taskId,
14791
15014
  ...input.eventId === void 0 ? {} : { eventId: input.eventId }
14792
15015
  });
14793
15016
  if (appended.ok) dispatchReliableRecord(appended.record);
@@ -15132,8 +15355,8 @@ function generateLaunchdPlist(def) {
15132
15355
  const { label, program, logDir } = def;
15133
15356
  const args = [program.command, ...program.args];
15134
15357
  const cwd = program.cwd ?? os.homedir();
15135
- const outLog = path.join(logDir, `${label}.out.log`);
15136
- const errLog = path.join(logDir, `${label}.err.log`);
15358
+ const outLog = path2.join(logDir, `${label}.out.log`);
15359
+ const errLog = path2.join(logDir, `${label}.err.log`);
15137
15360
  return `<?xml version="1.0" encoding="UTF-8"?>
15138
15361
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
15139
15362
  <plist version="1.0">
@@ -15174,7 +15397,7 @@ function createLaunchdLifecycle(def, deps = {}) {
15174
15397
  return process.getuid();
15175
15398
  });
15176
15399
  const label = sanitizeServiceName(def.name);
15177
- const plistPath = () => path.join(homedir(), "Library", "LaunchAgents", `${label}.plist`);
15400
+ const plistPath = () => path2.join(homedir(), "Library", "LaunchAgents", `${label}.plist`);
15178
15401
  const domainTarget = () => `gui/${getuid()}`;
15179
15402
  const serviceTarget = () => `${domainTarget()}/${label}`;
15180
15403
  async function fileExists(p) {
@@ -15187,7 +15410,7 @@ function createLaunchdLifecycle(def, deps = {}) {
15187
15410
  }
15188
15411
  async function writePlist(program) {
15189
15412
  const xml = generateLaunchdPlist({ label, program, logDir: def.logDir });
15190
- await fs26.mkdir(path.dirname(plistPath()), { recursive: true });
15413
+ await fs26.mkdir(path2.dirname(plistPath()), { recursive: true });
15191
15414
  await fs26.mkdir(def.logDir, { recursive: true });
15192
15415
  await fs26.writeFile(plistPath(), xml, "utf8");
15193
15416
  }
@@ -15261,8 +15484,8 @@ function generateSystemdUnit(def) {
15261
15484
  assertNoControlChars(displayName, "displayName");
15262
15485
  const cwd = program.cwd ?? os.homedir();
15263
15486
  assertNoControlChars(cwd, "program.cwd");
15264
- const outLog = path.join(logDir, `${name}.out.log`);
15265
- const errLog = path.join(logDir, `${name}.err.log`);
15487
+ const outLog = path2.join(logDir, `${name}.out.log`);
15488
+ const errLog = path2.join(logDir, `${name}.err.log`);
15266
15489
  assertNoControlChars(outLog, "logDir");
15267
15490
  assertNoControlChars(errLog, "logDir");
15268
15491
  const execStart = [program.command, ...program.args].map(quoteSystemdArg).join(" ");
@@ -15288,7 +15511,7 @@ function createSystemdLifecycle(def, deps = {}) {
15288
15511
  const homedir = deps.homedir ?? (() => os.homedir());
15289
15512
  const name = sanitizeServiceName(def.name);
15290
15513
  const unitName = `${name}.service`;
15291
- const unitPath = () => path.join(homedir(), ".config", "systemd", "user", unitName);
15514
+ const unitPath = () => path2.join(homedir(), ".config", "systemd", "user", unitName);
15292
15515
  async function fileExists(p) {
15293
15516
  try {
15294
15517
  await fs26.stat(p);
@@ -15299,7 +15522,7 @@ function createSystemdLifecycle(def, deps = {}) {
15299
15522
  }
15300
15523
  async function writeUnit(program) {
15301
15524
  const unit = generateSystemdUnit({ name, displayName: def.displayName ?? def.name, program, logDir: def.logDir });
15302
- await fs26.mkdir(path.dirname(unitPath()), { recursive: true });
15525
+ await fs26.mkdir(path2.dirname(unitPath()), { recursive: true });
15303
15526
  await fs26.mkdir(def.logDir, { recursive: true });
15304
15527
  await fs26.writeFile(unitPath(), unit, "utf8");
15305
15528
  }
@@ -15381,8 +15604,8 @@ function createWinswLifecycle(def, deps = {}) {
15381
15604
  const winswBin = windows.winswBin;
15382
15605
  const id = sanitizeServiceName(def.name);
15383
15606
  const installDir = windows.installDir ?? def.logDir;
15384
- const exePath = path.join(installDir, `${id}.exe`);
15385
- const xmlPath = path.join(installDir, `${id}.xml`);
15607
+ const exePath = path2.join(installDir, `${id}.exe`);
15608
+ const xmlPath = path2.join(installDir, `${id}.xml`);
15386
15609
  async function fileExists(p) {
15387
15610
  try {
15388
15611
  await fs26.stat(p);
@@ -15452,7 +15675,7 @@ function createServiceLifecycle(def, opts = {}) {
15452
15675
 
15453
15676
  // src/bin/official-release.ts
15454
15677
  var OFFICIAL_LOCAL_AGENT_RELEASE = resolveLocalAgentReleaseIdentity({
15455
- version: "0.7.0"
15678
+ version: "0.8.0"
15456
15679
  });
15457
15680
 
15458
15681
  // src/bin/config.ts
@@ -15937,7 +16160,7 @@ function safeProtocol(serverUrl) {
15937
16160
  }
15938
16161
  }
15939
16162
  async function inspectDevice(storeDir) {
15940
- const filePath = path.join(storeDir, "device.json");
16163
+ const filePath = path2.join(storeDir, "device.json");
15941
16164
  let pathStat;
15942
16165
  try {
15943
16166
  pathStat = await promises.lstat(filePath);
@@ -16017,11 +16240,11 @@ async function copyOpenFileBounded(source, expected, destinationPath) {
16017
16240
  }
16018
16241
  }
16019
16242
  async function inspectJournal(storeDir) {
16020
- const journalPath = path.join(storeDir, JOURNAL_DB_FILENAME);
16243
+ const journalPath = path2.join(storeDir, JOURNAL_DB_FILENAME);
16021
16244
  try {
16022
16245
  const mainIdentity = await regularFileIdentity(journalPath);
16023
16246
  if (mainIdentity === void 0) return { status: "missing" };
16024
- const walIdentity = await regularFileIdentity(path.join(storeDir, `${JOURNAL_DB_FILENAME}-wal`));
16247
+ const walIdentity = await regularFileIdentity(path2.join(storeDir, `${JOURNAL_DB_FILENAME}-wal`));
16025
16248
  let sizeBytes = Number(mainIdentity.size);
16026
16249
  let walBytes = walIdentity === void 0 ? void 0 : Number(walIdentity.size);
16027
16250
  if (!isSqliteAvailable()) {
@@ -16029,7 +16252,7 @@ async function inspectJournal(storeDir) {
16029
16252
  }
16030
16253
  const componentNames = [JOURNAL_DB_FILENAME, `${JOURNAL_DB_FILENAME}-wal`, `${JOURNAL_DB_FILENAME}-shm`];
16031
16254
  const initial = /* @__PURE__ */ new Map();
16032
- for (const name of componentNames) initial.set(name, await regularFileIdentity(path.join(storeDir, name)));
16255
+ for (const name of componentNames) initial.set(name, await regularFileIdentity(path2.join(storeDir, name)));
16033
16256
  const snapshotMain = initial.get(JOURNAL_DB_FILENAME);
16034
16257
  if (!snapshotMain) return { status: "unavailable", reason: "journal changed during diagnostics snapshot" };
16035
16258
  sizeBytes = Number(snapshotMain.size);
@@ -16041,7 +16264,7 @@ async function inspectJournal(storeDir) {
16041
16264
  let handle;
16042
16265
  try {
16043
16266
  handle = await promises.open(
16044
- path.join(storeDir, name),
16267
+ path2.join(storeDir, name),
16045
16268
  constants.O_RDONLY | constants.O_NONBLOCK | (constants.O_NOFOLLOW ?? 0)
16046
16269
  );
16047
16270
  } catch (err) {
@@ -16070,28 +16293,28 @@ async function inspectJournal(storeDir) {
16070
16293
  reason: "journal exceeds the bounded diagnostics copy limit"
16071
16294
  };
16072
16295
  }
16073
- const tempDir = await promises.mkdtemp(path.join(os.tmpdir(), "byok-journal-inspect-"));
16296
+ const tempDir = await promises.mkdtemp(path2.join(os.tmpdir(), "byok-journal-inspect-"));
16074
16297
  const { DatabaseSync } = loadSqliteModule();
16075
16298
  let db;
16076
16299
  try {
16077
16300
  for (const name of componentNames) {
16078
16301
  const component = opened.get(name);
16079
- if (component && !await copyOpenFileBounded(component.handle, component.identity, path.join(tempDir, name))) {
16302
+ if (component && !await copyOpenFileBounded(component.handle, component.identity, path2.join(tempDir, name))) {
16080
16303
  return { status: "unavailable", sizeBytes, ...walBytes === void 0 ? {} : { walBytes }, reason: "journal changed during diagnostics snapshot" };
16081
16304
  }
16082
16305
  }
16083
16306
  for (const [name, component] of opened) {
16084
- if (!sameIdentity(component.identity, identityFromBigIntStat(await component.handle.stat({ bigint: true }))) || !sameIdentity(component.identity, await regularFileIdentity(path.join(storeDir, name)))) {
16307
+ if (!sameIdentity(component.identity, identityFromBigIntStat(await component.handle.stat({ bigint: true }))) || !sameIdentity(component.identity, await regularFileIdentity(path2.join(storeDir, name)))) {
16085
16308
  return { status: "unavailable", sizeBytes, ...walBytes === void 0 ? {} : { walBytes }, reason: "journal changed during diagnostics snapshot" };
16086
16309
  }
16087
16310
  }
16088
16311
  for (const name of componentNames) {
16089
- if (!opened.has(name) && await regularFileIdentity(path.join(storeDir, name)) !== void 0) {
16312
+ if (!opened.has(name) && await regularFileIdentity(path2.join(storeDir, name)) !== void 0) {
16090
16313
  return { status: "unavailable", sizeBytes, ...walBytes === void 0 ? {} : { walBytes }, reason: "journal changed during diagnostics snapshot" };
16091
16314
  }
16092
16315
  }
16093
16316
  const header = Buffer.alloc(16);
16094
- const copiedHandle = await promises.open(path.join(tempDir, JOURNAL_DB_FILENAME), "r");
16317
+ const copiedHandle = await promises.open(path2.join(tempDir, JOURNAL_DB_FILENAME), "r");
16095
16318
  try {
16096
16319
  const { bytesRead } = await copiedHandle.read(header, 0, header.length, 0);
16097
16320
  if (bytesRead !== 16 || header.toString("binary") !== "SQLite format 3\0") {
@@ -16100,7 +16323,7 @@ async function inspectJournal(storeDir) {
16100
16323
  } finally {
16101
16324
  await copiedHandle.close();
16102
16325
  }
16103
- db = new DatabaseSync(path.join(tempDir, JOURNAL_DB_FILENAME), { readOnly: true });
16326
+ db = new DatabaseSync(path2.join(tempDir, JOURNAL_DB_FILENAME), { readOnly: true });
16104
16327
  const result = db.prepare("PRAGMA quick_check(1)").get();
16105
16328
  if (result?.quick_check !== "ok") {
16106
16329
  return { status: "corrupt", sizeBytes, ...walBytes === void 0 ? {} : { walBytes }, reason: "journal quick_check failed" };
@@ -16135,7 +16358,7 @@ async function inspectWorkspace(workspaceRoot) {
16135
16358
  }
16136
16359
  }
16137
16360
  function readPinnedQuarantineFile(name, maxBytes, includeBytes, budget) {
16138
- if (path.basename(name) !== name || name === "." || name === "..") {
16361
+ if (path2.basename(name) !== name || name === "." || name === "..") {
16139
16362
  throw new Error("quarantine manifest contains an invalid evidence name");
16140
16363
  }
16141
16364
  const namedBefore = lstatSync(name, { bigint: true });
@@ -16239,10 +16462,10 @@ function inspectQuarantinePinned(dir, expectedDirectory) {
16239
16462
  if (isJournalQuarantineManifest(parsed)) {
16240
16463
  const manifestBase = manifestName.slice(0, -".manifest.json".length);
16241
16464
  const boundNames = parsed.files.map((file) => {
16242
- if (path.dirname(path.resolve(file)) !== path.resolve(".")) {
16465
+ if (path2.dirname(path2.resolve(file)) !== path2.resolve(".")) {
16243
16466
  throw new Error("journal quarantine manifest points outside quarantine");
16244
16467
  }
16245
- return path.basename(file);
16468
+ return path2.basename(file);
16246
16469
  });
16247
16470
  if (!boundNames.includes(manifestBase)) {
16248
16471
  throw new Error("journal quarantine manifest is not bound to its primary database evidence");
@@ -16282,7 +16505,7 @@ function inspectQuarantinePinned(dir, expectedDirectory) {
16282
16505
  }
16283
16506
  }
16284
16507
  async function inspectQuarantine(storeDir) {
16285
- const dir = path.join(storeDir, JOURNAL_QUARANTINE_DIRNAME);
16508
+ const dir = path2.join(storeDir, JOURNAL_QUARANTINE_DIRNAME);
16286
16509
  let directory;
16287
16510
  try {
16288
16511
  directory = await promises.lstat(dir, { bigint: true });
@@ -16353,7 +16576,7 @@ function checksFor(snapshot) {
16353
16576
  ];
16354
16577
  }
16355
16578
  async function collectDiagnostics(config, storeDir, options = {}) {
16356
- const resolvedStoreDir = path.resolve(storeDir);
16579
+ const resolvedStoreDir = path2.resolve(storeDir);
16357
16580
  const adapters = options.adapters ?? defaultRuntimeAdapters(config.runtimeAllowlist);
16358
16581
  const connectControl = options.connectControl ?? connectControlClient;
16359
16582
  const [device, probedRuntimes, health, journal, workspace, quarantine, controlConnection] = await Promise.all([
@@ -16528,7 +16751,7 @@ function publishQuarantineEvidencePinned(quarantineDir, expectedDirectory, sourc
16528
16751
  unlinkSync(sourcePath);
16529
16752
  sourceRemoved = true;
16530
16753
  if (process.platform !== "win32") {
16531
- const directoryFd = openSync(path.dirname(sourcePath), constants.O_RDONLY);
16754
+ const directoryFd = openSync(path2.dirname(sourcePath), constants.O_RDONLY);
16532
16755
  try {
16533
16756
  fsyncSync(directoryFd);
16534
16757
  } finally {
@@ -16567,10 +16790,10 @@ function publishQuarantineEvidencePinned(quarantineDir, expectedDirectory, sourc
16567
16790
  }
16568
16791
  }
16569
16792
  async function quarantineCorruptOperationalHealth(storeDir, options = {}) {
16570
- const resolvedStoreDir = path.resolve(storeDir);
16793
+ const resolvedStoreDir = path2.resolve(storeDir);
16571
16794
  const owner = await acquireDaemonOwner(resolvedStoreDir, "doctor", options.clock);
16572
16795
  try {
16573
- const sourcePath = path.join(resolvedStoreDir, OPERATIONAL_HEALTH_FILENAME);
16796
+ const sourcePath = path2.join(resolvedStoreDir, OPERATIONAL_HEALTH_FILENAME);
16574
16797
  let opened;
16575
16798
  try {
16576
16799
  opened = await openOperationalHealthFile(resolvedStoreDir);
@@ -16587,7 +16810,7 @@ async function quarantineCorruptOperationalHealth(storeDir, options = {}) {
16587
16810
  }
16588
16811
  const sourceStat = await source.stat({ bigint: true });
16589
16812
  if (!sourceStat.isFile()) throw new Error("operational health state is not a regular file; refusing quarantine");
16590
- const quarantineDir = path.join(resolvedStoreDir, JOURNAL_QUARANTINE_DIRNAME);
16813
+ const quarantineDir = path2.join(resolvedStoreDir, JOURNAL_QUARANTINE_DIRNAME);
16591
16814
  try {
16592
16815
  const existing = await promises.lstat(quarantineDir);
16593
16816
  if (!existing.isDirectory() || existing.isSymbolicLink()) {
@@ -16688,8 +16911,8 @@ function buildServiceDefinition(config, configPath, rest) {
16688
16911
  const name = argValue(rest, "--name") ?? config.productId;
16689
16912
  const agentBin = argValue(rest, "--agent-bin") ?? process.argv[1] ?? "byok-agent";
16690
16913
  const nodeBin = argValue(rest, "--node-bin") ?? process.execPath;
16691
- const absoluteConfigPath = path.resolve(configPath);
16692
- const logDir = path.join(resolveStoreDir(config), "service-logs");
16914
+ const absoluteConfigPath = path2.resolve(configPath);
16915
+ const logDir = path2.join(resolveStoreDir(config), "service-logs");
16693
16916
  const definition = {
16694
16917
  name,
16695
16918
  displayName: config.branding?.displayName ?? config.productName,
@@ -16743,7 +16966,7 @@ async function runServiceStatusCommand(config, configPath, rest, deps = {}) {
16743
16966
  log(`detail: ${status.detail.trim() || "(none)"}`);
16744
16967
  }
16745
16968
  function auditLogPath(storeDir) {
16746
- return path.join(storeDir, "audit.jsonl");
16969
+ return path2.join(storeDir, "audit.jsonl");
16747
16970
  }
16748
16971
  var AUDIT_LOG_MODE = 384;
16749
16972
  var AUDIT_STORE_DIR_MODE = 448;
@@ -17581,11 +17804,11 @@ async function createSupportBundle(config, storeDir, options = {}) {
17581
17804
  };
17582
17805
  }
17583
17806
  async function writeSupportBundle(outputPath, bundle, secureFileOptions = {}) {
17584
- const dir = path.dirname(outputPath);
17807
+ const dir = path2.dirname(outputPath);
17585
17808
  const parentStat = await promises.stat(dir);
17586
17809
  if (!parentStat.isDirectory()) throw new Error("support bundle output parent is not a directory");
17587
- const privateDir = path.join(dir, `.${path.basename(outputPath)}.${process.pid}.${randomUUID()}.private`);
17588
- const tempPath = path.join(privateDir, "bundle.tmp");
17810
+ const privateDir = path2.join(dir, `.${path2.basename(outputPath)}.${process.pid}.${randomUUID()}.private`);
17811
+ const tempPath = path2.join(privateDir, "bundle.tmp");
17589
17812
  try {
17590
17813
  await promises.mkdir(privateDir, { mode: 448 });
17591
17814
  await ensureSecureDir(privateDir, secureFileOptions);
@@ -17615,7 +17838,7 @@ async function writeSupportBundle(outputPath, bundle, secureFileOptions = {}) {
17615
17838
  // src/bin/commands/support-bundle.ts
17616
17839
  async function runSupportBundleCommand(config, options) {
17617
17840
  if (!options.outputPath) throw new Error("support-bundle requires --output <path>");
17618
- const outputPath = path.resolve(options.outputPath);
17841
+ const outputPath = path2.resolve(options.outputPath);
17619
17842
  const bundle = await createSupportBundle(config, resolveStoreDir(config), options);
17620
17843
  await writeSupportBundle(outputPath, bundle);
17621
17844
  const log = options.log ?? ((line) => console.log(line));