@spotpatch/shared 1.13.0 → 1.14.1

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.
Files changed (55) hide show
  1. package/dist/{annotation-C0Me9mN2.d.cts → annotation-Cz-NNgR4.d.cts} +2 -2
  2. package/dist/{annotation-C0Me9mN2.d.ts → annotation-Cz-NNgR4.d.ts} +2 -2
  3. package/dist/{chunk-IUTOVI5G.js → chunk-CLQ6MIJB.js} +5 -3
  4. package/dist/chunk-CLQ6MIJB.js.map +1 -0
  5. package/dist/{chunk-DYTWEIES.js → chunk-EWJTKNL4.js} +2 -1
  6. package/dist/chunk-EWJTKNL4.js.map +1 -0
  7. package/dist/{chunk-2LVIH7OA.js → chunk-IX6MSCK6.js} +6 -2
  8. package/dist/chunk-IX6MSCK6.js.map +1 -0
  9. package/dist/{chunk-YQ5GL523.js → chunk-JTZFOTPT.js} +3 -3
  10. package/dist/{chunk-C2PJ4UUU.js → chunk-R6QJFNT2.js} +3 -3
  11. package/dist/chunk-R6QJFNT2.js.map +1 -0
  12. package/dist/{contextual-ask-B0mCFn92.d.cts → contextual-ask-BpbkpFFf.d.cts} +25 -0
  13. package/dist/{contextual-ask-B0mCFn92.d.ts → contextual-ask-BpbkpFFf.d.ts} +25 -0
  14. package/dist/contextual-ask-browser.cjs +1 -0
  15. package/dist/contextual-ask-browser.cjs.map +1 -1
  16. package/dist/contextual-ask-browser.d.cts +1 -1
  17. package/dist/contextual-ask-browser.d.ts +1 -1
  18. package/dist/contextual-ask-browser.js +1 -1
  19. package/dist/contextual-ask-node.cjs +5 -2
  20. package/dist/contextual-ask-node.cjs.map +1 -1
  21. package/dist/contextual-ask-node.d.cts +3 -3
  22. package/dist/contextual-ask-node.d.ts +3 -3
  23. package/dist/contextual-ask-node.js +3 -3
  24. package/dist/{data-flow-runtime-vKeEaJgT.d.ts → data-flow-runtime-DhWpQoik.d.ts} +13 -0
  25. package/dist/{data-flow-runtime-D8HPSb2i.d.cts → data-flow-runtime-w43iwvGA.d.cts} +13 -0
  26. package/dist/data-flow-runtime.d.cts +1 -1
  27. package/dist/data-flow-runtime.d.ts +1 -1
  28. package/dist/{external-agent-control-CRBbjDDk.d.cts → external-agent-control-DKxQACUv.d.cts} +8 -3
  29. package/dist/{external-agent-control-CRBbjDDk.d.ts → external-agent-control-DKxQACUv.d.ts} +8 -3
  30. package/dist/external-agent-node.cjs +178 -20
  31. package/dist/external-agent-node.cjs.map +1 -1
  32. package/dist/external-agent-node.d.cts +18 -3
  33. package/dist/external-agent-node.d.ts +18 -3
  34. package/dist/external-agent-node.js +172 -20
  35. package/dist/external-agent-node.js.map +1 -1
  36. package/dist/{external-handoff-DighrWn8.d.ts → external-handoff-5zHu-fz2.d.ts} +12 -2
  37. package/dist/{external-handoff-DwtFFR6F.d.cts → external-handoff-DeiIvR-2.d.cts} +12 -2
  38. package/dist/external-handoff-browser.cjs +7 -1
  39. package/dist/external-handoff-browser.cjs.map +1 -1
  40. package/dist/external-handoff-browser.d.cts +5 -3
  41. package/dist/external-handoff-browser.d.ts +5 -3
  42. package/dist/external-handoff-browser.js +3 -1
  43. package/dist/external-handoff-browser.js.map +1 -1
  44. package/dist/index.cjs +36 -9
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.cts +19 -7
  47. package/dist/index.d.ts +19 -7
  48. package/dist/index.js +31 -11
  49. package/dist/index.js.map +1 -1
  50. package/package.json +1 -1
  51. package/dist/chunk-2LVIH7OA.js.map +0 -1
  52. package/dist/chunk-C2PJ4UUU.js.map +0 -1
  53. package/dist/chunk-DYTWEIES.js.map +0 -1
  54. package/dist/chunk-IUTOVI5G.js.map +0 -1
  55. /package/dist/{chunk-YQ5GL523.js.map → chunk-JTZFOTPT.js.map} +0 -0
@@ -16,6 +16,8 @@ declare const EXTERNAL_AGENT_ERROR_CODES: readonly ["AGENT_BINARY_NOT_FOUND", "A
16
16
  declare const EXTERNAL_AGENT_ACTIONS: readonly ["install-agent", "use-supported-version", "sign-in", "choose-available-model", "use-inbox", "confirm-managed-access", "review-candidate-diff", "review-workspace-conflict", "retry", "inspect-cleanup-warning"];
17
17
  declare const EXTERNAL_AGENT_MANAGED_PROFILE: "managed-apply-v1";
18
18
  declare const EXTERNAL_AGENT_CONTROL_LIMITS: Readonly<{
19
+ readonly maximumModels: 128;
20
+ readonly maximumModelCharacters: 128;
19
21
  readonly maximumEventSubscribers: 4;
20
22
  readonly eventHeartbeatMs: 15000;
21
23
  readonly eventReconnectMinimumMs: 500;
@@ -47,13 +49,13 @@ declare const externalAgentErrorSchema: z.ZodObject<{
47
49
  MANAGED_CLEANUP_INCOMPLETE: "MANAGED_CLEANUP_INCOMPLETE";
48
50
  }>;
49
51
  stage: z.ZodEnum<{
52
+ model: "model";
50
53
  snapshot: "snapshot";
51
54
  apply: "apply";
52
55
  binary: "binary";
53
56
  integration: "integration";
54
57
  handshake: "handshake";
55
58
  auth: "auth";
56
- model: "model";
57
59
  protocol: "protocol";
58
60
  audit: "audit";
59
61
  validation: "validation";
@@ -201,6 +203,7 @@ declare const externalAgentControlStatusSchema: z.ZodObject<{
201
203
  }>;
202
204
  requestedModel: z.ZodOptional<z.ZodString>;
203
205
  effectiveModel: z.ZodOptional<z.ZodString>;
206
+ models: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
204
207
  task: z.ZodOptional<z.ZodObject<{
205
208
  revision: z.ZodNumber;
206
209
  deliveryStatus: z.ZodEnum<{
@@ -282,13 +285,13 @@ declare const externalAgentControlStatusSchema: z.ZodObject<{
282
285
  MANAGED_CLEANUP_INCOMPLETE: "MANAGED_CLEANUP_INCOMPLETE";
283
286
  }>;
284
287
  stage: z.ZodEnum<{
288
+ model: "model";
285
289
  snapshot: "snapshot";
286
290
  apply: "apply";
287
291
  binary: "binary";
288
292
  integration: "integration";
289
293
  handshake: "handshake";
290
294
  auth: "auth";
291
- model: "model";
292
295
  protocol: "protocol";
293
296
  audit: "audit";
294
297
  validation: "validation";
@@ -320,6 +323,7 @@ declare const externalAgentControlConnectRequestSchema: z.ZodObject<{
320
323
  requestId: z.ZodString;
321
324
  adapterKind: z.ZodLiteral<"codex">;
322
325
  profile: z.ZodLiteral<"managed-apply-v1">;
326
+ model: z.ZodOptional<z.ZodString>;
323
327
  }, z.core.$strict>;
324
328
  declare const externalAgentControlDisconnectRequestSchema: z.ZodObject<{
325
329
  requestId: z.ZodString;
@@ -376,6 +380,7 @@ declare const externalAgentEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
376
380
  }>;
377
381
  requestedModel: z.ZodOptional<z.ZodString>;
378
382
  effectiveModel: z.ZodOptional<z.ZodString>;
383
+ models: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
379
384
  task: z.ZodOptional<z.ZodObject<{
380
385
  revision: z.ZodNumber;
381
386
  deliveryStatus: z.ZodEnum<{
@@ -457,13 +462,13 @@ declare const externalAgentEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
457
462
  MANAGED_CLEANUP_INCOMPLETE: "MANAGED_CLEANUP_INCOMPLETE";
458
463
  }>;
459
464
  stage: z.ZodEnum<{
465
+ model: "model";
460
466
  snapshot: "snapshot";
461
467
  apply: "apply";
462
468
  binary: "binary";
463
469
  integration: "integration";
464
470
  handshake: "handshake";
465
471
  auth: "auth";
466
- model: "model";
467
472
  protocol: "protocol";
468
473
  audit: "audit";
469
474
  validation: "validation";
@@ -33,6 +33,7 @@ __export(external_agent_node_exports, {
33
33
  EXTERNAL_HANDOFF_PROJECT_KEY_SALT: () => EXTERNAL_HANDOFF_PROJECT_KEY_SALT,
34
34
  SPOTPATCH_BRIDGE_PATHS: () => SPOTPATCH_BRIDGE_PATHS,
35
35
  SPOTPATCH_BRIDGE_TOKEN_HEADER: () => SPOTPATCH_BRIDGE_TOKEN_HEADER,
36
+ assertPrivateExternalHandoffPath: () => assertPrivateExternalHandoffPath,
36
37
  bridgeAckRequestSchema: () => bridgeAckRequestSchema,
37
38
  bridgeAckResultSchema: () => bridgeAckResultSchema,
38
39
  bridgeActiveClaimRequestSchema: () => bridgeActiveClaimRequestSchema,
@@ -52,13 +53,16 @@ __export(external_agent_node_exports, {
52
53
  bridgeWaitResultSchema: () => bridgeWaitResultSchema,
53
54
  computeExternalHandoffProjectKey: () => computeExternalHandoffProjectKey,
54
55
  externalHandoffDescriptorSchema: () => externalHandoffDescriptorSchema,
56
+ initializePrivateExternalHandoffFile: () => initializePrivateExternalHandoffFile,
55
57
  resolveExternalHandoffRuntimeDirectory: () => resolveExternalHandoffRuntimeDirectory
56
58
  });
57
59
  module.exports = __toCommonJS(external_agent_node_exports);
58
60
  var import_node_crypto = require("crypto");
61
+ var import_node_child_process = require("child_process");
59
62
  var import_promises = require("fs/promises");
60
63
  var import_node_os = __toESM(require("os"), 1);
61
64
  var import_node_path = __toESM(require("path"), 1);
65
+ var import_node_util = require("util");
62
66
  var import_zod4 = require("zod");
63
67
 
64
68
  // src/protocol/external-handoff.ts
@@ -148,7 +152,7 @@ var sourceRefSchema = import_zod.z.strictObject({
148
152
  relativePath: boundedString(1024).optional(),
149
153
  line: import_zod.z.number().int().positive().optional(),
150
154
  column: import_zod.z.number().int().positive().optional(),
151
- origin: import_zod.z.enum(["jsx-host", "react-fiber", "dom-ancestor", "none"]),
155
+ origin: import_zod.z.enum(["jsx-host", "astro-host", "react-fiber", "dom-ancestor", "none"]),
152
156
  confidence: import_zod.z.enum(["exact", "probable", "approximate", "unknown"])
153
157
  });
154
158
  var matchedStyleRuleSchema = import_zod.z.strictObject({
@@ -159,7 +163,7 @@ var matchedStyleRuleSchema = import_zod.z.strictObject({
159
163
  });
160
164
  var codeContextSchema = import_zod.z.strictObject({
161
165
  relativePath: boundedString(1024),
162
- language: import_zod.z.enum(["tsx", "jsx"]),
166
+ language: import_zod.z.enum(["tsx", "jsx", "astro"]),
163
167
  startLine: import_zod.z.number().int().positive(),
164
168
  endLine: import_zod.z.number().int().positive(),
165
169
  excerpt: boundedString(16e3),
@@ -283,7 +287,11 @@ var EXTERNAL_HANDOFF_STATES = Object.freeze([
283
287
  "expired",
284
288
  "superseded"
285
289
  ]);
286
- var EXTERNAL_HANDOFF_FRAMEWORKS = Object.freeze(["vite", "next"]);
290
+ var EXTERNAL_HANDOFF_FRAMEWORKS = Object.freeze([
291
+ "vite",
292
+ "next",
293
+ "astro"
294
+ ]);
287
295
  var EXTERNAL_HANDOFF_ACTIVE_ADAPTER_KINDS = Object.freeze([
288
296
  "claude-channel",
289
297
  "codex-app-server"
@@ -534,6 +542,75 @@ var SPOTPATCH_BRIDGE_PATHS = Object.freeze({
534
542
  activeRelease: "/bridge/v1/active/release"
535
543
  });
536
544
  var EXTERNAL_HANDOFF_PROJECT_KEY_SALT = "spotpatch-external-agent-project-v1";
545
+ var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
546
+ var WINDOWS_ACL_SCRIPT = String.raw`
547
+ $ErrorActionPreference = 'Stop'
548
+ $target = $env:SPOTPATCH_ACL_TARGET
549
+ $kind = $env:SPOTPATCH_ACL_KIND
550
+ $operation = $env:SPOTPATCH_ACL_OPERATION
551
+ $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent().User
552
+ $allowed = @($identity.Value, 'S-1-5-18', 'S-1-5-32-544')
553
+ if ($kind -eq 'directory') {
554
+ $item = [System.IO.DirectoryInfo]::new($target)
555
+ if ($operation -eq 'initialize') {
556
+ $security = [System.Security.AccessControl.DirectorySecurity]::new()
557
+ $security.SetOwner($identity)
558
+ foreach ($sidValue in $allowed) {
559
+ $sid = [System.Security.Principal.SecurityIdentifier]::new($sidValue)
560
+ $rule = [System.Security.AccessControl.FileSystemAccessRule]::new(
561
+ $sid,
562
+ [System.Security.AccessControl.FileSystemRights]::FullControl,
563
+ [System.Security.AccessControl.InheritanceFlags]'ContainerInherit, ObjectInherit',
564
+ [System.Security.AccessControl.PropagationFlags]::None,
565
+ [System.Security.AccessControl.AccessControlType]::Allow
566
+ )
567
+ [void]$security.AddAccessRule($rule)
568
+ }
569
+ $security.SetAccessRuleProtection($true, $false)
570
+ $item.SetAccessControl($security)
571
+ }
572
+ $acl = $item.GetAccessControl(
573
+ [System.Security.AccessControl.AccessControlSections]'Access, Owner'
574
+ )
575
+ } elseif ($kind -eq 'file') {
576
+ $item = [System.IO.FileInfo]::new($target)
577
+ if ($operation -eq 'initialize') {
578
+ $security = [System.Security.AccessControl.FileSecurity]::new()
579
+ $security.SetOwner($identity)
580
+ foreach ($sidValue in $allowed) {
581
+ $sid = [System.Security.Principal.SecurityIdentifier]::new($sidValue)
582
+ $rule = [System.Security.AccessControl.FileSystemAccessRule]::new(
583
+ $sid,
584
+ [System.Security.AccessControl.FileSystemRights]::FullControl,
585
+ [System.Security.AccessControl.AccessControlType]::Allow
586
+ )
587
+ [void]$security.AddAccessRule($rule)
588
+ }
589
+ $security.SetAccessRuleProtection($true, $false)
590
+ $item.SetAccessControl($security)
591
+ }
592
+ $acl = $item.GetAccessControl(
593
+ [System.Security.AccessControl.AccessControlSections]'Access, Owner'
594
+ )
595
+ } else {
596
+ exit 10
597
+ }
598
+ if ($acl.GetOwner([System.Security.Principal.SecurityIdentifier]).Value -ne $identity.Value) {
599
+ exit 11
600
+ }
601
+ foreach ($rule in $acl.GetAccessRules(
602
+ $true,
603
+ $true,
604
+ [System.Security.Principal.SecurityIdentifier]
605
+ )) {
606
+ if (
607
+ $rule.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow -and
608
+ $allowed -notcontains $rule.IdentityReference.Value
609
+ ) {
610
+ exit 12
611
+ }
612
+ }
613
+ `;
537
614
  var opaqueIdSchema2 = import_zod4.z.string().min(22).max(128).regex(/^[A-Za-z0-9_-]+$/u);
538
615
  var projectKeySchema = import_zod4.z.string().length(64).regex(/^[a-f0-9]+$/u);
539
616
  var loopbackEndpointSchema = import_zod4.z.url().refine((value) => {
@@ -613,46 +690,121 @@ var bridgeActiveStateResultSchema = import_zod4.z.strictObject({
613
690
  var bridgeActiveHeartbeatResultSchema = bridgeActiveStateResultSchema;
614
691
  var bridgeActiveReportResultSchema = bridgeActiveStateResultSchema;
615
692
  var bridgeActiveReleaseResultSchema = bridgeActiveStateResultSchema;
616
- function currentUid() {
617
- const uid = process.getuid?.();
618
- if (uid === void 0) {
693
+ function windowsPowerShellExecutable() {
694
+ const systemRoot = process.env.SystemRoot ?? process.env.SYSTEMROOT;
695
+ if (systemRoot === void 0 || !import_node_path.default.win32.isAbsolute(systemRoot)) {
619
696
  throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);
620
697
  }
621
- return uid;
698
+ return import_node_path.default.win32.join(
699
+ systemRoot,
700
+ "System32",
701
+ "WindowsPowerShell",
702
+ "v1.0",
703
+ "powershell.exe"
704
+ );
622
705
  }
623
- async function assertPrivateDirectory(directory, uid) {
624
- const status = await (0, import_promises.lstat)(directory);
625
- if (!status.isDirectory() || status.isSymbolicLink() || status.uid !== uid || (status.mode & 63) !== 0) {
706
+ async function verifyWindowsAcl(candidate, kind, initialize) {
707
+ try {
708
+ await execFileAsync(
709
+ windowsPowerShellExecutable(),
710
+ ["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", WINDOWS_ACL_SCRIPT],
711
+ {
712
+ encoding: "utf8",
713
+ env: {
714
+ ...process.env,
715
+ SPOTPATCH_ACL_KIND: kind,
716
+ SPOTPATCH_ACL_OPERATION: initialize ? "initialize" : "verify",
717
+ SPOTPATCH_ACL_TARGET: candidate
718
+ },
719
+ timeout: 1e4,
720
+ windowsHide: true
721
+ }
722
+ );
723
+ } catch (error) {
724
+ throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED, void 0, {
725
+ cause: error
726
+ });
727
+ }
728
+ }
729
+ async function assertPrivateExternalHandoffPath(candidate, kind) {
730
+ const status = await (0, import_promises.lstat)(candidate);
731
+ const correctKind = kind === "directory" ? status.isDirectory() : status.isFile();
732
+ if (!correctKind || status.isSymbolicLink()) {
733
+ throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);
734
+ }
735
+ if (process.platform === "win32") {
736
+ await verifyWindowsAcl(candidate, kind, false);
737
+ return status;
738
+ }
739
+ const uid = process.getuid?.();
740
+ if (uid === void 0 || status.uid !== uid || (status.mode & 63) !== 0) {
626
741
  throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);
627
742
  }
743
+ return status;
628
744
  }
629
- async function ensurePrivateSubdirectory(base, uid, create) {
745
+ async function initializePrivateExternalHandoffFile(candidate) {
746
+ if (process.platform === "win32") {
747
+ await verifyWindowsAcl(candidate, "file", true);
748
+ }
749
+ }
750
+ async function initializeWindowsDirectory(directory) {
751
+ if (process.platform === "win32") {
752
+ await verifyWindowsAcl(directory, "directory", true);
753
+ }
754
+ }
755
+ async function ensurePrivateSubdirectory(base, create) {
630
756
  const directory = import_node_path.default.join(base, "spotpatch");
757
+ let created = false;
631
758
  if (create) {
632
759
  try {
633
760
  await (0, import_promises.mkdir)(directory, { mode: 448 });
761
+ created = true;
634
762
  } catch (error) {
635
763
  if (error.code !== "EEXIST") {
636
764
  throw error;
637
765
  }
638
766
  }
639
767
  }
640
- await assertPrivateDirectory(directory, uid);
641
- return directory;
768
+ if (created) await initializeWindowsDirectory(directory);
769
+ await assertPrivateExternalHandoffPath(directory, "directory");
770
+ return (0, import_promises.realpath)(directory);
642
771
  }
643
- async function resolveExternalHandoffRuntimeDirectory(create) {
644
- if (process.platform === "win32") {
772
+ async function resolveWindowsRuntimeDirectory(create) {
773
+ const configuredBase = process.env.LOCALAPPDATA;
774
+ if (configuredBase !== void 0 && !import_node_path.default.isAbsolute(configuredBase)) {
645
775
  throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);
646
776
  }
647
- const uid = currentUid();
777
+ const base = configuredBase ?? import_node_path.default.join(import_node_os.default.homedir(), "AppData", "Local");
778
+ const directory = import_node_path.default.join(base, "SpotPatch", "external-agent-runtime-v1");
779
+ let created = false;
780
+ if (create) {
781
+ created = await (0, import_promises.mkdir)(directory, { mode: 448, recursive: true }) !== void 0;
782
+ }
783
+ if (created) await initializeWindowsDirectory(directory);
784
+ await assertPrivateExternalHandoffPath(directory, "directory");
785
+ return (0, import_promises.realpath)(directory);
786
+ }
787
+ async function resolveExternalHandoffRuntimeDirectory(create) {
648
788
  const xdgRuntimeDirectory = process.env.XDG_RUNTIME_DIR;
649
789
  if (xdgRuntimeDirectory !== void 0 && !import_node_path.default.isAbsolute(xdgRuntimeDirectory)) {
650
790
  throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);
651
791
  }
652
792
  if (xdgRuntimeDirectory !== void 0) {
653
793
  try {
654
- await assertPrivateDirectory(xdgRuntimeDirectory, uid);
655
- return await ensurePrivateSubdirectory(xdgRuntimeDirectory, uid, create);
794
+ if (process.platform !== "win32") {
795
+ await assertPrivateExternalHandoffPath(xdgRuntimeDirectory, "directory");
796
+ }
797
+ return await ensurePrivateSubdirectory(xdgRuntimeDirectory, create);
798
+ } catch (error) {
799
+ if (!create && error.code === "ENOENT") {
800
+ throw new SpotPatchError(ERROR_CODES.SESSION_NOT_FOUND);
801
+ }
802
+ throw error;
803
+ }
804
+ }
805
+ if (process.platform === "win32") {
806
+ try {
807
+ return await resolveWindowsRuntimeDirectory(create);
656
808
  } catch (error) {
657
809
  if (!create && error.code === "ENOENT") {
658
810
  throw new SpotPatchError(ERROR_CODES.SESSION_NOT_FOUND);
@@ -660,6 +812,10 @@ async function resolveExternalHandoffRuntimeDirectory(create) {
660
812
  throw error;
661
813
  }
662
814
  }
815
+ const uid = process.getuid?.();
816
+ if (uid === void 0) {
817
+ throw new SpotPatchError(ERROR_CODES.BRIDGE_UNAUTHORIZED);
818
+ }
663
819
  const fallback = import_node_path.default.join(import_node_os.default.tmpdir(), `spotpatch-${String(uid)}`);
664
820
  if (create) {
665
821
  try {
@@ -671,14 +827,14 @@ async function resolveExternalHandoffRuntimeDirectory(create) {
671
827
  }
672
828
  }
673
829
  try {
674
- await assertPrivateDirectory(fallback, uid);
830
+ await assertPrivateExternalHandoffPath(fallback, "directory");
675
831
  } catch (error) {
676
832
  if (!create && error.code === "ENOENT") {
677
833
  throw new SpotPatchError(ERROR_CODES.SESSION_NOT_FOUND);
678
834
  }
679
835
  throw error;
680
836
  }
681
- return fallback;
837
+ return (0, import_promises.realpath)(fallback);
682
838
  }
683
839
  async function computeExternalHandoffProjectKey(root) {
684
840
  const canonicalRoot = await (0, import_promises.realpath)(root);
@@ -689,6 +845,7 @@ async function computeExternalHandoffProjectKey(root) {
689
845
  EXTERNAL_HANDOFF_PROJECT_KEY_SALT,
690
846
  SPOTPATCH_BRIDGE_PATHS,
691
847
  SPOTPATCH_BRIDGE_TOKEN_HEADER,
848
+ assertPrivateExternalHandoffPath,
692
849
  bridgeAckRequestSchema,
693
850
  bridgeAckResultSchema,
694
851
  bridgeActiveClaimRequestSchema,
@@ -708,6 +865,7 @@ async function computeExternalHandoffProjectKey(root) {
708
865
  bridgeWaitResultSchema,
709
866
  computeExternalHandoffProjectKey,
710
867
  externalHandoffDescriptorSchema,
868
+ initializePrivateExternalHandoffFile,
711
869
  resolveExternalHandoffRuntimeDirectory
712
870
  });
713
871
  //# sourceMappingURL=external-agent-node.cjs.map