@hearsay-tools/squawk 0.17.0-dev.5723 → 0.17.0-dev.5728

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.
@@ -0,0 +1,2 @@
1
+ /** Whether a directory entry exists at `path`, without following a final symlink. Any error but ENOENT throws. */
2
+ export declare function entryExists(path: string): Promise<boolean>;
@@ -0,0 +1,10 @@
1
+ import { lstat } from 'node:fs/promises';
2
+ /** Whether a directory entry exists at `path`, without following a final symlink. Any error but ENOENT throws. */
3
+ export async function entryExists(path) {
4
+ return lstat(path).then(() => true, (error) => {
5
+ if (error.code === 'ENOENT')
6
+ return false;
7
+ throw error;
8
+ });
9
+ }
10
+ //# sourceMappingURL=entry-exists.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-exists.js","sourceRoot":"","sources":["../../src/delegation/entry-exists.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,kHAAkH;AAClH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,KAA4B,EAAE,EAAE;QACnE,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC1C,MAAM,KAAK,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Where the ownership policy in `workspace.ts` keeps its identity files: the receipt directory,
3
+ * receipts, cleanup checkpoints and Git administration markers. The store owns the platform's
4
+ * safety rules; the policy owns what the files prove (ADR 0032).
5
+ *
6
+ * A process entry installs the store for its host. Only entries import the Windows store, so the
7
+ * policy and its many importers never load it (hearsay-tools/cezarion#3244).
8
+ */
9
+ export interface IdentityFileStore {
10
+ /** Create the private receipt directory when `create` is set, and refuse an existing unsafe one. */
11
+ directory(path: string, create: boolean): Promise<void>;
12
+ /** Read an identity file of at most `cap` bytes. `privateParent` is false for a marker in Git's admin directory. */
13
+ read(path: string, cap: number, privateParent: boolean): Promise<string>;
14
+ /** Create a new private identity file; fail when one exists. */
15
+ write(path: string, content: string, privateParent: boolean): Promise<void>;
16
+ /** Replace a private identity file atomically. `assertCurrent` throws when the caller lost ownership. */
17
+ replace(path: string, content: string, cap: number, assertCurrent?: () => void): Promise<void>;
18
+ }
19
+ /** Install the store for this process; `undefined` restores the host default. */
20
+ export declare function installIdentityFileStore(store: IdentityFileStore | undefined): void;
21
+ /** The installed store, else the POSIX store on a non-Windows host. Windows has no default. */
22
+ export declare function identityFileStore(): IdentityFileStore;
@@ -0,0 +1,16 @@
1
+ import { posixIdentityFileStore } from './posix-workspace-identity.js';
2
+ let installed;
3
+ /** Install the store for this process; `undefined` restores the host default. */
4
+ export function installIdentityFileStore(store) {
5
+ installed = store;
6
+ }
7
+ /** The installed store, else the POSIX store on a non-Windows host. Windows has no default. */
8
+ export function identityFileStore() {
9
+ if (installed)
10
+ return installed;
11
+ if (process.platform === 'win32') {
12
+ throw new Error('No workspace identity store is installed: a Windows process entry must call installWindowsIdentityStore');
13
+ }
14
+ return posixIdentityFileStore;
15
+ }
16
+ //# sourceMappingURL=identity-file-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-file-store.js","sourceRoot":"","sources":["../../src/delegation/identity-file-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAqBvE,IAAI,SAAwC,CAAC;AAE7C,iFAAiF;AACjF,MAAM,UAAU,wBAAwB,CAAC,KAAoC;IAC3E,SAAS,GAAG,KAAK,CAAC;AACpB,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,iBAAiB;IAC/B,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAChC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,yGAAyG,CAAC,CAAC;IAC7H,CAAC;IACD,OAAO,sBAAsB,CAAC;AAChC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { IdentityFileStore } from './identity-file-store.ts';
2
+ /** Mode bits and no-follow opens: the directory is 0700, each file 0600, and a replace renames a temporary file. */
3
+ export declare const posixIdentityFileStore: IdentityFileStore;
@@ -0,0 +1,68 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { constants } from 'node:fs';
3
+ import { lstat, mkdir, open, realpath, rename, rm } from 'node:fs/promises';
4
+ import { entryExists as exists } from './entry-exists.js';
5
+ async function directory(dir, create) {
6
+ if (create)
7
+ await mkdir(dir, { mode: 0o700 }).catch((error) => {
8
+ if (error.code !== 'EEXIST')
9
+ throw error;
10
+ });
11
+ if (await exists(dir)) {
12
+ const info = await lstat(dir);
13
+ if (!info.isDirectory() || info.isSymbolicLink() || await realpath(dir) !== dir || (info.mode & 0o077) !== 0) {
14
+ throw new Error('Unsafe owned workspace receipt directory');
15
+ }
16
+ }
17
+ }
18
+ async function read(path, cap) {
19
+ const info = await lstat(path);
20
+ if (!info.isFile() || info.isSymbolicLink())
21
+ throw new Error('Unsafe owned workspace identity file');
22
+ const file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
23
+ try {
24
+ const opened = await file.stat();
25
+ if (!opened.isFile() || opened.size > cap || (opened.mode & 0o077) !== 0)
26
+ throw new Error('Unsafe owned workspace identity file');
27
+ const buffer = Buffer.alloc(cap + 1);
28
+ const { bytesRead } = await file.read(buffer, 0, buffer.length, 0);
29
+ if (bytesRead > cap)
30
+ throw new Error('Oversized owned workspace identity file');
31
+ return buffer.subarray(0, bytesRead).toString('utf8');
32
+ }
33
+ finally {
34
+ await file.close();
35
+ }
36
+ }
37
+ async function write(path, content) {
38
+ const file = await open(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
39
+ try {
40
+ await file.writeFile(content);
41
+ await file.sync();
42
+ }
43
+ finally {
44
+ await file.close();
45
+ }
46
+ }
47
+ async function replace(path, content, cap, assertCurrent) {
48
+ if (await exists(path))
49
+ await read(path, cap);
50
+ assertCurrent?.();
51
+ const temporary = `${path}.${randomUUID()}.tmp`;
52
+ await write(temporary, content);
53
+ try {
54
+ assertCurrent?.();
55
+ await rename(temporary, path);
56
+ }
57
+ finally {
58
+ await rm(temporary, { force: true });
59
+ }
60
+ }
61
+ /** Mode bits and no-follow opens: the directory is 0700, each file 0600, and a replace renames a temporary file. */
62
+ export const posixIdentityFileStore = {
63
+ directory,
64
+ read: (path, cap) => read(path, cap),
65
+ write: (path, content) => write(path, content),
66
+ replace,
67
+ };
68
+ //# sourceMappingURL=posix-workspace-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posix-workspace-identity.js","sourceRoot":"","sources":["../../src/delegation/posix-workspace-identity.ts"],"names":[],"mappings":"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"}
@@ -27,6 +27,18 @@ export declare function delegationFailure(error: unknown): {
27
27
  export declare function createDelegationRoutes(service: DelegationService, credentials: CredentialRegistry): import("hono/hono-base").HonoBase<Env, {
28
28
  "/list": {
29
29
  $get: {
30
+ output: {
31
+ error: string;
32
+ code?: "invalid_input" | undefined;
33
+ };
34
+ outputFormat: "json";
35
+ status: 400;
36
+ input: {
37
+ query: {
38
+ offset?: string | undefined;
39
+ };
40
+ };
41
+ } | {
30
42
  output: {
31
43
  workers: {
32
44
  workerId: string;
@@ -64,24 +76,21 @@ export declare function createDelegationRoutes(service: DelegationService, crede
64
76
  offset?: string | undefined;
65
77
  };
66
78
  };
67
- } | {
68
- output: {
69
- error: string;
70
- code?: "invalid_input" | undefined;
71
- };
72
- outputFormat: "json";
73
- status: 400;
74
- input: {
75
- query: {
76
- offset?: string | undefined;
77
- };
78
- };
79
79
  };
80
80
  };
81
81
  } & {
82
82
  "/discover": {
83
83
  $post: {
84
84
  output: {
85
+ scope: "host-default-account";
86
+ runners: {
87
+ status: "connected" | "disconnected" | "not-installed" | "unknown";
88
+ enabled?: boolean | undefined;
89
+ hint?: string | undefined;
90
+ authFailureId?: string | undefined;
91
+ runner: "claude" | "codex" | "cursor" | "omp" | "opencode" | "pi";
92
+ }[];
93
+ } | {
85
94
  tasks: {
86
95
  id: string;
87
96
  title: string;
@@ -93,15 +102,6 @@ export declare function createDelegationRoutes(service: DelegationService, crede
93
102
  reason?: string | undefined;
94
103
  }[];
95
104
  nextOffset?: number | undefined;
96
- } | {
97
- scope: "host-default-account";
98
- runners: {
99
- status: "connected" | "disconnected" | "not-installed" | "unknown";
100
- enabled?: boolean | undefined;
101
- hint?: string | undefined;
102
- authFailureId?: string | undefined;
103
- runner: "claude" | "codex" | "cursor" | "omp" | "opencode" | "pi";
104
- }[];
105
105
  } | {
106
106
  runner: "claude" | "codex" | "cursor" | "omp" | "opencode" | "pi";
107
107
  models: {
@@ -221,13 +221,13 @@ export declare function createDelegationRoutes(service: DelegationService, crede
221
221
  status: 200;
222
222
  input: {
223
223
  json: {
224
- requestIds: string[];
225
- mode?: "all" | "any" | "one" | undefined;
226
- timeoutSeconds?: number | undefined;
227
- } | {
228
224
  workerIds: string[];
229
225
  timeoutSeconds?: number | undefined;
230
226
  mode?: "all" | "any" | "one" | undefined;
227
+ } | {
228
+ requestIds: string[];
229
+ mode?: "all" | "any" | "one" | undefined;
230
+ timeoutSeconds?: number | undefined;
231
231
  } | {
232
232
  peerIds: string[];
233
233
  timeoutSeconds?: number | undefined;
@@ -613,6 +613,18 @@ export declare function createDelegationRoutes(service: DelegationService, crede
613
613
  } & {
614
614
  "/:workerId": {
615
615
  $get: {
616
+ output: {
617
+ error: string;
618
+ code?: "invalid_input" | undefined;
619
+ };
620
+ outputFormat: "json";
621
+ status: 400;
622
+ input: {
623
+ param: {
624
+ workerId: string;
625
+ };
626
+ };
627
+ } | {
616
628
  output: {
617
629
  workerId: string;
618
630
  parentRunId: string;
@@ -716,7 +728,11 @@ export declare function createDelegationRoutes(service: DelegationService, crede
716
728
  workerId: string;
717
729
  };
718
730
  };
719
- } | {
731
+ };
732
+ };
733
+ } & {
734
+ "/:workerId/collect": {
735
+ $post: {
720
736
  output: {
721
737
  error: string;
722
738
  code?: "invalid_input" | undefined;
@@ -727,12 +743,10 @@ export declare function createDelegationRoutes(service: DelegationService, crede
727
743
  param: {
728
744
  workerId: string;
729
745
  };
746
+ } & {
747
+ json: Record<string, never>;
730
748
  };
731
- };
732
- };
733
- } & {
734
- "/:workerId/collect": {
735
- $post: {
749
+ } | {
736
750
  output: {
737
751
  workerId: string;
738
752
  parentRunId: string;
@@ -834,7 +848,11 @@ export declare function createDelegationRoutes(service: DelegationService, crede
834
848
  } & {
835
849
  json: Record<string, never>;
836
850
  };
837
- } | {
851
+ };
852
+ };
853
+ } & {
854
+ "/:workerId/steer": {
855
+ $post: {
838
856
  output: {
839
857
  error: string;
840
858
  code?: "invalid_input" | undefined;
@@ -846,13 +864,11 @@ export declare function createDelegationRoutes(service: DelegationService, crede
846
864
  workerId: string;
847
865
  };
848
866
  } & {
849
- json: Record<string, never>;
867
+ json: {
868
+ text: string;
869
+ };
850
870
  };
851
- };
852
- };
853
- } & {
854
- "/:workerId/steer": {
855
- $post: {
871
+ } | {
856
872
  output: {
857
873
  workerId: string;
858
874
  state: "delivered" | "queued";
@@ -868,7 +884,11 @@ export declare function createDelegationRoutes(service: DelegationService, crede
868
884
  text: string;
869
885
  };
870
886
  };
871
- } | {
887
+ };
888
+ };
889
+ } & {
890
+ "/:workerId/stop": {
891
+ $post: {
872
892
  output: {
873
893
  error: string;
874
894
  code?: "invalid_input" | undefined;
@@ -880,15 +900,9 @@ export declare function createDelegationRoutes(service: DelegationService, crede
880
900
  workerId: string;
881
901
  };
882
902
  } & {
883
- json: {
884
- text: string;
885
- };
903
+ json: Record<string, never>;
886
904
  };
887
- };
888
- };
889
- } & {
890
- "/:workerId/stop": {
891
- $post: {
905
+ } | {
892
906
  output: {
893
907
  workerId: string;
894
908
  state: "stopping" | "terminated";
@@ -902,7 +916,11 @@ export declare function createDelegationRoutes(service: DelegationService, crede
902
916
  } & {
903
917
  json: Record<string, never>;
904
918
  };
905
- } | {
919
+ };
920
+ };
921
+ } & {
922
+ "/:workerId/destroy": {
923
+ $post: {
906
924
  output: {
907
925
  error: string;
908
926
  code?: "invalid_input" | undefined;
@@ -916,11 +934,7 @@ export declare function createDelegationRoutes(service: DelegationService, crede
916
934
  } & {
917
935
  json: Record<string, never>;
918
936
  };
919
- };
920
- };
921
- } & {
922
- "/:workerId/destroy": {
923
- $post: {
937
+ } | {
924
938
  output: {
925
939
  workerId: string;
926
940
  state: "complete" | "incomplete";
@@ -943,20 +957,6 @@ export declare function createDelegationRoutes(service: DelegationService, crede
943
957
  } & {
944
958
  json: Record<string, never>;
945
959
  };
946
- } | {
947
- output: {
948
- error: string;
949
- code?: "invalid_input" | undefined;
950
- };
951
- outputFormat: "json";
952
- status: 400;
953
- input: {
954
- param: {
955
- workerId: string;
956
- };
957
- } & {
958
- json: Record<string, never>;
959
- };
960
960
  } | {
961
961
  output: {
962
962
  workerId: string;
@@ -986,13 +986,11 @@ export declare function createDelegationRoutes(service: DelegationService, crede
986
986
  "/:workerId/diff": {
987
987
  $get: {
988
988
  output: {
989
- workerId: string;
990
- baselineSha: string;
991
- diff: string;
992
- truncated: boolean;
989
+ error: string;
990
+ code?: "invalid_input" | undefined;
993
991
  };
994
992
  outputFormat: "json";
995
- status: 200;
993
+ status: 400;
996
994
  input: {
997
995
  param: {
998
996
  workerId: string;
@@ -1000,11 +998,13 @@ export declare function createDelegationRoutes(service: DelegationService, crede
1000
998
  };
1001
999
  } | {
1002
1000
  output: {
1003
- error: string;
1004
- code?: "invalid_input" | undefined;
1001
+ workerId: string;
1002
+ baselineSha: string;
1003
+ diff: string;
1004
+ truncated: boolean;
1005
1005
  };
1006
1006
  outputFormat: "json";
1007
- status: 400;
1007
+ status: 200;
1008
1008
  input: {
1009
1009
  param: {
1010
1010
  workerId: string;
@@ -57,6 +57,15 @@ export declare function createDelegationApp(routes: DelegationRoutes): import("h
57
57
  "/discover": {
58
58
  $post: {
59
59
  output: {
60
+ scope: "host-default-account";
61
+ runners: {
62
+ status: "connected" | "disconnected" | "not-installed" | "unknown";
63
+ enabled?: boolean | undefined;
64
+ hint?: string | undefined;
65
+ authFailureId?: string | undefined;
66
+ runner: "claude" | "codex" | "cursor" | "omp" | "opencode" | "pi";
67
+ }[];
68
+ } | {
60
69
  runner: "claude" | "codex" | "cursor" | "omp" | "opencode" | "pi";
61
70
  models: {
62
71
  id: string;
@@ -67,15 +76,6 @@ export declare function createDelegationApp(routes: DelegationRoutes): import("h
67
76
  source: "cache" | "live" | "unavailable";
68
77
  stale: boolean;
69
78
  reason?: string | undefined;
70
- } | {
71
- scope: "host-default-account";
72
- runners: {
73
- status: "connected" | "disconnected" | "not-installed" | "unknown";
74
- enabled?: boolean | undefined;
75
- hint?: string | undefined;
76
- authFailureId?: string | undefined;
77
- runner: "claude" | "codex" | "cursor" | "omp" | "opencode" | "pi";
78
- }[];
79
79
  } | {
80
80
  tasks: {
81
81
  id: string;
@@ -196,13 +196,13 @@ export declare function createDelegationApp(routes: DelegationRoutes): import("h
196
196
  status: 200;
197
197
  input: {
198
198
  json: {
199
- workerIds: string[];
200
- timeoutSeconds?: number | undefined;
201
- mode?: "all" | "any" | "one" | undefined;
202
- } | {
203
199
  requestIds: string[];
204
200
  mode?: "all" | "any" | "one" | undefined;
205
201
  timeoutSeconds?: number | undefined;
202
+ } | {
203
+ workerIds: string[];
204
+ timeoutSeconds?: number | undefined;
205
+ mode?: "all" | "any" | "one" | undefined;
206
206
  } | {
207
207
  peerIds: string[];
208
208
  timeoutSeconds?: number | undefined;
@@ -0,0 +1,5 @@
1
+ import { type IdentityFileStore } from './identity-file-store.ts';
2
+ /** Protected ACLs through the native helper (ADR 0032); a replace overwrites in place, atomically. */
3
+ export declare const windowsIdentityFileStore: IdentityFileStore;
4
+ /** Called by each process entry that reaches `workspace.ts`; installs the Windows store on a Windows host only. */
5
+ export declare function installWindowsIdentityStore(platform?: NodeJS.Platform): void;
@@ -0,0 +1,15 @@
1
+ import { installIdentityFileStore } from './identity-file-store.js';
2
+ import { windowsIdentityDirectory, windowsReadIdentity, windowsWriteIdentity } from './windows-workspace-identity.js';
3
+ /** Protected ACLs through the native helper (ADR 0032); a replace overwrites in place, atomically. */
4
+ export const windowsIdentityFileStore = {
5
+ directory: async (path, create) => { windowsIdentityDirectory(path, create); },
6
+ read: async (path, cap, privateParent) => windowsReadIdentity(path, cap, privateParent),
7
+ write: async (path, content, privateParent) => { windowsWriteIdentity(path, content, false, privateParent); },
8
+ replace: async (path, content) => { windowsWriteIdentity(path, content, true); },
9
+ };
10
+ /** Called by each process entry that reaches `workspace.ts`; installs the Windows store on a Windows host only. */
11
+ export function installWindowsIdentityStore(platform = process.platform) {
12
+ if (platform === 'win32')
13
+ installIdentityFileStore(windowsIdentityFileStore);
14
+ }
15
+ //# sourceMappingURL=windows-identity-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windows-identity-store.js","sourceRoot":"","sources":["../../src/delegation/windows-identity-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAA0B,MAAM,0BAA0B,CAAC;AAC5F,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEtH,sGAAsG;AACtG,MAAM,CAAC,MAAM,wBAAwB,GAAsB;IACzD,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,wBAAwB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9E,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,GAAG,EAAE,aAAa,CAAC;IACvF,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE,GAAG,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAC7G,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;CACjF,CAAC;AAEF,mHAAmH;AACnH,MAAM,UAAU,2BAA2B,CAAC,QAAQ,GAAoB,OAAO,CAAC,QAAQ;IACtF,IAAI,QAAQ,KAAK,OAAO;QAAE,wBAAwB,CAAC,wBAAwB,CAAC,CAAC;AAC/E,CAAC"}
@@ -1,11 +1,12 @@
1
1
  import { projectPaths, fallbackProjectWriteError } from '../project-paths.js';
2
2
  import { inspectGeneration } from './process-liveness.js';
3
3
  import { waitForTestAppWatcher, withIdleTestApp } from './idle-test-app.js';
4
- import { windowsIdentityDirectory, windowsReadIdentity, windowsWriteIdentity } from './windows-workspace-identity.js';
4
+ import { identityFileStore } from './identity-file-store.js';
5
+ import { entryExists as exists } from './entry-exists.js';
5
6
  import { execFile } from 'node:child_process';
6
7
  import { createHash, randomUUID } from 'node:crypto';
7
8
  import { constants } from 'node:fs';
8
- import { lstat, mkdir, mkdtemp, open, readdir, realpath, rename, rm } from 'node:fs/promises';
9
+ import { mkdtemp, open, readdir, realpath, rm } from 'node:fs/promises';
9
10
  import { tmpdir } from 'node:os';
10
11
  import { dirname, join, normalize } from 'node:path';
11
12
  import { z } from 'zod';
@@ -17,8 +18,6 @@ import { resolveTaskDiffBase } from '../git-diff-base.js';
17
18
  import { isSafeGitRef } from '../git-refs.js';
18
19
  import { DelegationPolicyError } from './policy.js';
19
20
  const RECEIPT_CAP = 16_384;
20
- // Filesystem primitives belong to the host that loaded this module.
21
- const windowsIdentities = process.platform === 'win32';
22
21
  // Identify owned branches by tip and reflog contents, not inode identity.
23
22
  // Keep file/logFile fields for older strict checkpoint readers.
24
23
  const fileIdentitySchema = z.object({ dev: z.number(), ino: z.number(), birthtimeMs: z.number() }).strict();
@@ -67,22 +66,7 @@ async function writeCleanup(path, value, assertCurrent) {
67
66
  }
68
67
  async function replaceIdentityFile(path, content, assertCurrent) {
69
68
  assertCurrent?.();
70
- if (windowsIdentities) {
71
- windowsWriteIdentity(path, content, true);
72
- return;
73
- }
74
- if (await exists(path))
75
- await readIdentityFile(path, RECEIPT_CAP);
76
- assertCurrent?.();
77
- const temporary = `${path}.${randomUUID()}.tmp`;
78
- await writeIdentityFile(temporary, content);
79
- try {
80
- assertCurrent?.();
81
- await rename(temporary, path);
82
- }
83
- finally {
84
- await rm(temporary, { force: true });
85
- }
69
+ await identityFileStore().replace(path, content, RECEIPT_CAP, assertCurrent);
86
70
  }
87
71
  function git(cwd, args, index, maxBuffer = 32 * 1024 * 1024) {
88
72
  return new Promise((done) => {
@@ -104,13 +88,6 @@ async function checkedGit(cwd, args, index) {
104
88
  export async function gitCommonDir(cwd) {
105
89
  return realpath(await checkedGit(cwd, ['rev-parse', '--path-format=absolute', '--git-common-dir']));
106
90
  }
107
- async function exists(path) {
108
- return lstat(path).then(() => true, (error) => {
109
- if (error.code === 'ENOENT')
110
- return false;
111
- throw error;
112
- });
113
- }
114
91
  /** Reads only committed state in the server-known parent cwd; never flushes its edits. */
115
92
  export async function resolveWorkerBaseline(repoRoot, parentCwd, baseline) {
116
93
  try {
@@ -164,21 +141,7 @@ async function receiptLocation(repoRoot, workspace, create = false) {
164
141
  }
165
142
  async function receiptDirectory(repoRoot, create) {
166
143
  const dir = join(await gitCommonDir(repoRoot), 'cezar-owned-workspaces');
167
- if (windowsIdentities) {
168
- windowsIdentityDirectory(dir, create);
169
- return dir;
170
- }
171
- if (create)
172
- await mkdir(dir, { mode: 0o700 }).catch((error) => {
173
- if (error.code !== 'EEXIST')
174
- throw error;
175
- });
176
- if (await exists(dir)) {
177
- const info = await lstat(dir);
178
- if (!info.isDirectory() || info.isSymbolicLink() || await realpath(dir) !== dir || (info.mode & 0o077) !== 0) {
179
- throw new Error('Unsafe owned workspace receipt directory');
180
- }
181
- }
144
+ await identityFileStore().directory(dir, create);
182
145
  return dir;
183
146
  }
184
147
  /** The receipt and cleanup checkpoint files in the repository's shared receipt directory, checked
@@ -197,40 +160,11 @@ export function readOwnedWorkspaceRecord(path) {
197
160
  export function replaceOwnedWorkspaceRecord(path, content) {
198
161
  return replaceIdentityFile(path, content);
199
162
  }
200
- async function readIdentityFile(path, cap, privateParent = true) {
201
- if (windowsIdentities)
202
- return windowsReadIdentity(path, cap, privateParent);
203
- const info = await lstat(path);
204
- if (!info.isFile() || info.isSymbolicLink())
205
- throw new Error('Unsafe owned workspace identity file');
206
- const file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
207
- try {
208
- const opened = await file.stat();
209
- if (!opened.isFile() || opened.size > cap || (opened.mode & 0o077) !== 0)
210
- throw new Error('Unsafe owned workspace identity file');
211
- const buffer = Buffer.alloc(cap + 1);
212
- const { bytesRead } = await file.read(buffer, 0, buffer.length, 0);
213
- if (bytesRead > cap)
214
- throw new Error('Oversized owned workspace identity file');
215
- return buffer.subarray(0, bytesRead).toString('utf8');
216
- }
217
- finally {
218
- await file.close();
219
- }
163
+ function readIdentityFile(path, cap, privateParent = true) {
164
+ return identityFileStore().read(path, cap, privateParent);
220
165
  }
221
- async function writeIdentityFile(path, content, privateParent = true) {
222
- if (windowsIdentities) {
223
- windowsWriteIdentity(path, content, false, privateParent);
224
- return;
225
- }
226
- const file = await open(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
227
- try {
228
- await file.writeFile(content);
229
- await file.sync();
230
- }
231
- finally {
232
- await file.close();
233
- }
166
+ function writeIdentityFile(path, content, privateParent = true) {
167
+ return identityFileStore().write(path, content, privateParent);
234
168
  }
235
169
  async function readReceipt(path) {
236
170
  if (!await exists(path))