wicked-crew 0.7.24 → 0.7.26

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 (131) hide show
  1. package/dist/api/endpoint-manifest-live.d.ts.map +1 -1
  2. package/dist/api/endpoint-manifest-live.js +5 -0
  3. package/dist/api/endpoint-manifest-live.js.map +1 -1
  4. package/dist/api/eval-compare.d.ts +306 -0
  5. package/dist/api/eval-compare.d.ts.map +1 -0
  6. package/dist/api/eval-compare.js +610 -0
  7. package/dist/api/eval-compare.js.map +1 -0
  8. package/dist/api/eval-sample.d.ts +158 -0
  9. package/dist/api/eval-sample.d.ts.map +1 -0
  10. package/dist/api/eval-sample.js +88 -0
  11. package/dist/api/eval-sample.js.map +1 -0
  12. package/dist/api/routes.d.ts +5 -0
  13. package/dist/api/routes.d.ts.map +1 -1
  14. package/dist/api/routes.js +31 -0
  15. package/dist/api/routes.js.map +1 -1
  16. package/dist/api/run-files.d.ts +12 -2
  17. package/dist/api/run-files.d.ts.map +1 -1
  18. package/dist/api/run-files.js +17 -5
  19. package/dist/api/run-files.js.map +1 -1
  20. package/dist/api/server.d.ts +20 -0
  21. package/dist/api/server.d.ts.map +1 -1
  22. package/dist/api/server.js +62 -9
  23. package/dist/api/server.js.map +1 -1
  24. package/dist/api/skills.d.ts +88 -0
  25. package/dist/api/skills.d.ts.map +1 -0
  26. package/dist/api/skills.js +264 -0
  27. package/dist/api/skills.js.map +1 -0
  28. package/dist/api/testing.d.ts +2 -75
  29. package/dist/api/testing.d.ts.map +1 -1
  30. package/dist/api/testing.js +14 -28
  31. package/dist/api/testing.js.map +1 -1
  32. package/dist/core/adapter.d.ts +42 -0
  33. package/dist/core/adapter.d.ts.map +1 -1
  34. package/dist/core/adapter.js +83 -12
  35. package/dist/core/adapter.js.map +1 -1
  36. package/dist/interactive/bridge-root.d.ts +117 -7
  37. package/dist/interactive/bridge-root.d.ts.map +1 -1
  38. package/dist/interactive/bridge-root.js +229 -9
  39. package/dist/interactive/bridge-root.js.map +1 -1
  40. package/dist/interactive/doc-delete-routes.d.ts +2 -0
  41. package/dist/interactive/doc-delete-routes.d.ts.map +1 -1
  42. package/dist/interactive/doc-delete-routes.js +3 -19
  43. package/dist/interactive/doc-delete-routes.js.map +1 -1
  44. package/dist/interactive/doc-list-routes.d.ts +42 -0
  45. package/dist/interactive/doc-list-routes.d.ts.map +1 -0
  46. package/dist/interactive/doc-list-routes.js +165 -0
  47. package/dist/interactive/doc-list-routes.js.map +1 -0
  48. package/dist/interactive/project-root.d.ts +36 -0
  49. package/dist/interactive/project-root.d.ts.map +1 -0
  50. package/dist/interactive/project-root.js +45 -0
  51. package/dist/interactive/project-root.js.map +1 -0
  52. package/dist/interactive/proxy-routes.d.ts +4 -1
  53. package/dist/interactive/proxy-routes.d.ts.map +1 -1
  54. package/dist/interactive/proxy-routes.js +4 -22
  55. package/dist/interactive/proxy-routes.js.map +1 -1
  56. package/dist/projects/default-project.d.ts +10 -0
  57. package/dist/projects/default-project.d.ts.map +1 -0
  58. package/dist/projects/default-project.js +10 -0
  59. package/dist/projects/default-project.js.map +1 -0
  60. package/dist/projects/routes.d.ts +0 -2
  61. package/dist/projects/routes.d.ts.map +1 -1
  62. package/dist/projects/routes.js +1 -2
  63. package/dist/projects/routes.js.map +1 -1
  64. package/dist/skills/bundle.d.ts +94 -0
  65. package/dist/skills/bundle.d.ts.map +1 -0
  66. package/dist/skills/bundle.js +187 -0
  67. package/dist/skills/bundle.js.map +1 -0
  68. package/dist/skills/contain.d.ts +57 -0
  69. package/dist/skills/contain.d.ts.map +1 -0
  70. package/dist/skills/contain.js +90 -0
  71. package/dist/skills/contain.js.map +1 -0
  72. package/dist/skills/core-closure.d.ts +83 -0
  73. package/dist/skills/core-closure.d.ts.map +1 -0
  74. package/dist/skills/core-closure.js +130 -0
  75. package/dist/skills/core-closure.js.map +1 -0
  76. package/dist/skills/engine-env.d.ts +48 -0
  77. package/dist/skills/engine-env.d.ts.map +1 -0
  78. package/dist/skills/engine-env.js +69 -0
  79. package/dist/skills/engine-env.js.map +1 -0
  80. package/dist/skills/frontmatter.d.ts +77 -0
  81. package/dist/skills/frontmatter.d.ts.map +1 -0
  82. package/dist/skills/frontmatter.js +190 -0
  83. package/dist/skills/frontmatter.js.map +1 -0
  84. package/dist/skills/guards.d.ts +72 -0
  85. package/dist/skills/guards.d.ts.map +1 -0
  86. package/dist/skills/guards.js +147 -0
  87. package/dist/skills/guards.js.map +1 -0
  88. package/dist/skills/live-generations.d.ts +80 -0
  89. package/dist/skills/live-generations.d.ts.map +1 -0
  90. package/dist/skills/live-generations.js +163 -0
  91. package/dist/skills/live-generations.js.map +1 -0
  92. package/dist/skills/plugin-source.d.ts +109 -0
  93. package/dist/skills/plugin-source.d.ts.map +1 -0
  94. package/dist/skills/plugin-source.js +272 -0
  95. package/dist/skills/plugin-source.js.map +1 -0
  96. package/dist/skills/refs.d.ts +58 -0
  97. package/dist/skills/refs.d.ts.map +1 -0
  98. package/dist/skills/refs.js +133 -0
  99. package/dist/skills/refs.js.map +1 -0
  100. package/dist/skills/root-fence.d.ts +53 -0
  101. package/dist/skills/root-fence.d.ts.map +1 -0
  102. package/dist/skills/root-fence.js +109 -0
  103. package/dist/skills/root-fence.js.map +1 -0
  104. package/dist/skills/root-names.d.ts +42 -0
  105. package/dist/skills/root-names.d.ts.map +1 -0
  106. package/dist/skills/root-names.js +44 -0
  107. package/dist/skills/root-names.js.map +1 -0
  108. package/dist/skills/runtime.d.ts +130 -0
  109. package/dist/skills/runtime.d.ts.map +1 -0
  110. package/dist/skills/runtime.js +246 -0
  111. package/dist/skills/runtime.js.map +1 -0
  112. package/dist/skills/store.d.ts +895 -0
  113. package/dist/skills/store.d.ts.map +1 -0
  114. package/dist/skills/store.js +3575 -0
  115. package/dist/skills/store.js.map +1 -0
  116. package/dist/skills/tree.d.ts +292 -0
  117. package/dist/skills/tree.d.ts.map +1 -0
  118. package/dist/skills/tree.js +645 -0
  119. package/dist/skills/tree.js.map +1 -0
  120. package/dist/skills/venv.d.ts +52 -0
  121. package/dist/skills/venv.d.ts.map +1 -0
  122. package/dist/skills/venv.js +80 -0
  123. package/dist/skills/venv.js.map +1 -0
  124. package/dist/studio/assets/index-CK1uJWs2.css +32 -0
  125. package/dist/studio/assets/index-FcZg3WDR.js +539 -0
  126. package/dist/studio/index.html +2 -2
  127. package/dist/studio/testid-inventory.json +611 -7
  128. package/endpoint-manifest.json +183 -1
  129. package/package.json +4 -3
  130. package/dist/studio/assets/index-BmXt63Ij.js +0 -537
  131. package/dist/studio/assets/index-eso7X_3n.css +0 -32
@@ -0,0 +1,645 @@
1
+ /**
2
+ * File-tree primitives for the skills store: walk, hash, copy, remove — POSIX-relative paths,
3
+ * sorted, symlinks never followed.
4
+ *
5
+ * NO-FOLLOW EVERYWHERE (design v3 §API; codex review of #480). A plugin tree is copied INTO the
6
+ * daemon's root and later handed to worker spawns, so a link anywhere on a path the store reads or
7
+ * writes would turn "copy the plugin" into "copy whatever the link reaches" and "write this skill
8
+ * file" into "write wherever the link points". Therefore:
9
+ *
10
+ * - `walkFiles` refuses a symlinked ROOT (the skill dir itself replaced by a link) and skips
11
+ * symlink entries (never followed, never copied, never hashed); `walkTree` is the variant a
12
+ * VERIFICATION uses — it ENUMERATES link entries with their link text (still never followed)
13
+ * so an injected link cannot hide from `current`'s hash (codex round 5); a PRUNED directory
14
+ * (`SKIP_DIR_NAMES`: `.venv`, `node_modules`, `__pycache__`) is descended for CLASSIFICATION
15
+ * only — every entry beneath it is reported with its kind and marked `pruned`, and stays out of
16
+ * every file, hash and copy view (codex round 10: a link under `effective/node_modules/` used
17
+ * to be invisible to the validators because the walk stopped at the directory);
18
+ * - `copyFiles` PREFLIGHTS every destination — each `rel` must be a safe relative path (no `..`,
19
+ * `.`, empty or separator-carrying segment, no absolute/drive prefix, no NUL:
20
+ * `assertSafeRelSegments`) and symlink-free (`assertNoSymlinkComponents`) — BEFORE it creates a
21
+ * parent or writes a byte, independent of where the record came from (codex round 4: a
22
+ * manifest-sourced skill name became a copilot-view path `views/…/<name>/SKILL.md`, and a
23
+ * `../…` name would have joined out of the staging dir). A refused record writes NOTHING —
24
+ * not the records ahead of it either;
25
+ * - `writeFileAtomic` refuses a symlink at the target, opens its temp file with `O_EXCL`
26
+ * (fails on ANY pre-existing entry, a pre-planted symlink included) and `O_NOFOLLOW` under an
27
+ * unpredictable name, and preserves the target's mode bits (an executable support script
28
+ * stays executable across an in-place edit or a replace).
29
+ *
30
+ * # TOCTOU discipline inside the skills root (design v3.5 §3; codex round 8)
31
+ *
32
+ * The lstat walk is necessary, not sufficient: every file open inside the root uses `O_NOFOLLOW`
33
+ * where the platform has it (`readFileNoFollow`, `copyFileNoFollow`, `writeFileAtomic`'s temp
34
+ * file), and the lstat-then-open pattern is closed EVERYWHERE — Windows has no `O_NOFOLLOW` — with a
35
+ * post-open identity check (`fstat` dev/ino against the lstat result: the entry opened IS the entry
36
+ * the walk judged); copies read their SOURCE through such an open, never by path
37
+ * (`copyFileSync(path)` follows a source swapped for a link between enumeration and copy); a staged
38
+ * tree is re-walked (lstat) and re-hashed AFTER the copy and BEFORE the rename into place
39
+ * (store.ts `stagedTreeProblem`, `captureBaseline`, `publishSerialized`). Residual, documented: a
40
+ * directory component swapped between the walk and the rename by another writer with access to the
41
+ * crew-owned state home — mitigated by the single-writer daemon and the post-operation verification,
42
+ * not eliminated.
43
+ */
44
+ import { createHash, randomBytes } from 'node:crypto';
45
+ import { chmodSync, closeSync, constants as fsConstants, fstatSync, lstatSync, mkdirSync, openSync, readdirSync, readFileSync, readlinkSync, renameSync, rmdirSync, rmSync, unlinkSync, writeSync, } from 'node:fs';
46
+ import { dirname, join, relative, sep } from 'node:path';
47
+ import { ATOMIC_TMP_INFIX } from './root-names.js';
48
+ /** `O_NOFOLLOW` where the platform has it (POSIX); `0` on Windows, where the post-open identity check alone closes the gap. */
49
+ const O_NOFOLLOW = fsConstants.O_NOFOLLOW ?? 0;
50
+ /**
51
+ * Directory names PRUNED from every file, hash and copy view (build caches, vendored deps, the
52
+ * per-baseline `uv sync` env): nothing beneath one is bundle content — never copied into a baseline
53
+ * or a generation, never hashed. The walk still DESCENDS them for classification (codex round 10),
54
+ * so a validator sees what such a directory holds (`TreeEntry.pruned`, `TreeListing.pruned`).
55
+ */
56
+ export const SKIP_DIR_NAMES = new Set(['__pycache__', 'node_modules', '.venv']);
57
+ /** File names never copied into the root (Finder noise). */
58
+ export const SKIP_FILE_NAMES = new Set(['.DS_Store']);
59
+ export function toPosix(p) {
60
+ return sep === '/' ? p : p.split(sep).join('/');
61
+ }
62
+ /** A path the store would have to FOLLOW a symlink to reach — refused, never judged lexically. */
63
+ export class SymlinkComponentError extends Error {
64
+ path;
65
+ component;
66
+ constructor(path, component) {
67
+ super(`${path} crosses a symlink at ${component} — the skills root never follows links`);
68
+ this.path = path;
69
+ this.component = component;
70
+ this.name = 'SymlinkComponentError';
71
+ }
72
+ }
73
+ /** A relative path whose SHAPE could join out of its root (`..`, an absolute piece, a separator in a
74
+ * segment, a NUL) — refused before any lstat, whatever produced it. */
75
+ export class UnsafePathSegmentError extends Error {
76
+ path;
77
+ reason;
78
+ constructor(path, reason) {
79
+ super(`unsafe path ${JSON.stringify(path)}: ${reason} — the joined path must stay inside its root`);
80
+ this.path = path;
81
+ this.reason = reason;
82
+ this.name = 'UnsafePathSegmentError';
83
+ }
84
+ }
85
+ /**
86
+ * Why ONE path component is not a safe segment, or `null`. A segment may not be empty, `.` or `..`,
87
+ * may not carry a separator (`/` or `\`), a NUL, or a drive prefix (`C:`). The ONE rule every
88
+ * joined component in the store goes through (contain.ts, `copyFiles`, the view generator).
89
+ */
90
+ export function unsafeSegmentReason(seg) {
91
+ if (seg === '' || seg === '.' || seg === '..')
92
+ return `segment ${JSON.stringify(seg)}`;
93
+ if (seg.includes('/') || seg.includes('\\'))
94
+ return `segment ${JSON.stringify(seg)} carries a separator`;
95
+ if (seg.includes('\0'))
96
+ return 'NUL byte';
97
+ if (/^[A-Za-z]:/.test(seg))
98
+ return `segment ${JSON.stringify(seg)} carries a drive prefix`;
99
+ return null;
100
+ }
101
+ /**
102
+ * Split a POSIX-relative path into segments, refusing anything that could escape: empty, absolute
103
+ * (`/…`), drive-prefixed, backslashes, NUL, and a `.` / `..` / empty segment. Throws
104
+ * `UnsafePathSegmentError`. Lexical only — the caller walks the result for symlinks.
105
+ */
106
+ export function assertSafeRelSegments(rel) {
107
+ if (rel === '')
108
+ throw new UnsafePathSegmentError(rel, 'empty — the root itself is not a file');
109
+ if (rel.includes('\0'))
110
+ throw new UnsafePathSegmentError(rel, 'NUL byte');
111
+ if (rel.includes('\\'))
112
+ throw new UnsafePathSegmentError(rel, 'backslash — paths are POSIX');
113
+ if (rel.startsWith('/'))
114
+ throw new UnsafePathSegmentError(rel, 'absolute');
115
+ if (/^[A-Za-z]:/.test(rel))
116
+ throw new UnsafePathSegmentError(rel, 'drive prefix');
117
+ const segments = rel.split('/');
118
+ for (const seg of segments) {
119
+ const why = unsafeSegmentReason(seg);
120
+ if (why !== null)
121
+ throw new UnsafePathSegmentError(rel, why);
122
+ }
123
+ return segments;
124
+ }
125
+ /**
126
+ * `join(root, ...segments)` after an lstat walk that refuses a symlink at ANY component — the
127
+ * leaf included. A component that does not exist yet ends the walk (a not-yet-written leaf, or
128
+ * its new parent dirs — the write creates them); so does a component whose parent turned out to
129
+ * be a REGULAR FILE (ENOTDIR — nothing below a file exists, and no link can be crossed through
130
+ * one; whether the caller may write there is the caller's preflight, `containedDestinations`).
131
+ * Any other filesystem error propagates: an unreadable component is not judged lexically. `root`
132
+ * itself is not walked — the caller decides what its root is (the store walks from the SKILLS
133
+ * root down, so a skill dir replaced by a link is a component, not a root).
134
+ */
135
+ export function assertNoSymlinkComponents(root, segments) {
136
+ // The walk joins each segment onto its parent, so a `..` (or a separator smuggled inside a
137
+ // segment) would climb out of `root` before any lstat ran — refused lexically first, whatever
138
+ // the caller already checked (codex round 4: `copyFiles` used to trust its records' shape).
139
+ for (const seg of segments) {
140
+ const why = unsafeSegmentReason(seg);
141
+ if (why !== null)
142
+ throw new UnsafePathSegmentError(segments.join('/'), why);
143
+ }
144
+ let cur = root;
145
+ for (const seg of segments) {
146
+ cur = join(cur, seg);
147
+ let st;
148
+ try {
149
+ st = lstatSync(cur);
150
+ }
151
+ catch (err) {
152
+ const code = err.code;
153
+ if (code === 'ENOENT' || code === 'ENOTDIR')
154
+ break;
155
+ throw err;
156
+ }
157
+ if (st.isSymbolicLink())
158
+ throw new SymlinkComponentError(segments.join('/'), seg);
159
+ }
160
+ return join(root, ...segments);
161
+ }
162
+ /**
163
+ * THE walker (design v3 no-follow everywhere; codex round 9 on #480): every entry under `root` —
164
+ * the root itself excluded — classified by lstat as a regular file, a directory, a symlink or
165
+ * something else (a socket, fifo, device …), sorted by `rel`, never following a link and never
166
+ * descending into one. NOTHING is invisible: an empty directory is an entry, a symlink is an entry
167
+ * with its link text, a special node is an entry of kind `other`. A directory named in
168
+ * `SKIP_DIR_NAMES` (`.venv`, `node_modules`, `__pycache__`) is reported AND descended (codex round
169
+ * 10): every entry beneath it is classified like any other and marked `pruned` with that
170
+ * directory's `rel`, so a validator SEES a link or a special node planted there — while the file,
171
+ * hash and copy views (`walkFiles`, `walkTree`'s `files` / `links` / `dirs` / `others`, and
172
+ * therefore `hashTree` and `copyFiles`) exclude the whole subtree exactly as before: nothing under
173
+ * a pruned directory is ever copied or hashed. `skipDir(rel)` is the caller's CLOSURE prune (the
174
+ * bundle walk drops `scripts/` dev tooling with it): content outside the closure is not reported
175
+ * and not descended — it is never reached, so never copied either. Every other view derives from
176
+ * this one. A missing `root` yields `[]` — callers treat optional plugin dirs (`schemas/`) as
177
+ * empty, not as errors; a `root` that IS a symlink is refused (`readdirSync` would follow it, and
178
+ * "list this skill's own files" must never enumerate a tree outside the store).
179
+ */
180
+ export function walkEntries(root, skipDir) {
181
+ const out = [];
182
+ try {
183
+ if (lstatSync(root).isSymbolicLink())
184
+ throw new SymlinkComponentError(root, root);
185
+ }
186
+ catch (err) {
187
+ if (err.code === 'ENOENT')
188
+ return out;
189
+ throw err;
190
+ }
191
+ const visit = (dir, relDir, pruned) => {
192
+ let entries;
193
+ try {
194
+ entries = readdirSync(dir, { withFileTypes: true });
195
+ }
196
+ catch (err) {
197
+ if (err.code === 'ENOENT' && relDir === '')
198
+ return;
199
+ throw err;
200
+ }
201
+ for (const entry of entries) {
202
+ const rel = relDir === '' ? entry.name : `${relDir}/${entry.name}`;
203
+ const abs = join(dir, entry.name);
204
+ if (entry.isSymbolicLink()) {
205
+ out.push({ rel, abs, kind: 'symlink', target: readlinkSync(abs), pruned });
206
+ }
207
+ else if (entry.isDirectory()) {
208
+ out.push({ rel, abs, kind: 'dir', pruned });
209
+ if (skipDir !== undefined && skipDir(rel))
210
+ continue;
211
+ // A pruned-name directory is descended for CLASSIFICATION: its entries carry the outermost
212
+ // pruned directory's rel (a `node_modules` inside a `.venv` is still pruned by the `.venv`).
213
+ visit(abs, rel, pruned ?? (SKIP_DIR_NAMES.has(entry.name) ? rel : null));
214
+ }
215
+ else if (entry.isFile()) {
216
+ out.push({ rel, abs, kind: 'file', pruned });
217
+ }
218
+ else {
219
+ out.push({ rel, abs, kind: 'other', pruned });
220
+ }
221
+ }
222
+ };
223
+ visit(root, '', null);
224
+ out.sort((a, b) => (a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0));
225
+ return out;
226
+ }
227
+ /**
228
+ * Whether a walk entry is a regular file the store CARRIES — copies, hashes, records: a regular
229
+ * file outside every pruned directory that is not Finder noise (`SKIP_FILE_NAMES`).
230
+ */
231
+ export function isCarriedFile(e) {
232
+ return e.kind === 'file' && e.pruned === null && !SKIP_FILE_NAMES.has(e.rel.split('/').pop() ?? '');
233
+ }
234
+ /**
235
+ * Every regular file under `root`, sorted by `rel` — `walkEntries` filtered to the files the store
236
+ * carries (`isCarriedFile`: nothing beneath a pruned directory, no Finder noise). `skipDir(rel)`
237
+ * prunes a subtree; `SKIP_DIR_NAMES` / `SKIP_FILE_NAMES` always apply.
238
+ */
239
+ export function walkFiles(root, skipDir) {
240
+ return walkEntries(root, skipDir)
241
+ .filter(isCarriedFile)
242
+ .map(({ rel, abs }) => ({ rel, abs }));
243
+ }
244
+ /**
245
+ * `walkEntries` split into what a verification consumes: files (Finder noise excluded), links
246
+ * (listed with their text, never followed or descended — codex round 5: a verification that skips
247
+ * links leaves an injected outside-pointing link invisible to the hash), directories and special
248
+ * nodes — each of these OUTSIDE every pruned directory — plus `pruned`: what the pruned
249
+ * directories hold. `SKIP_DIR_NAMES` (`.venv` / `node_modules` / `__pycache__`) keeps the
250
+ * subtree out of `files` / `links` / `dirs` / `others` (so out of every hash and copy) exactly as
251
+ * before, but the subtree is now WALKED and reported under `pruned` (codex round 10); the
252
+ * pruned-name directory entry itself is in `dirs`; a LINK bearing one of those names is listed like
253
+ * any link (the snapshot's `.venv` link is exactly that). `skipDir(rel)` is the caller's closure
254
+ * prune (the bundle walk drops the `scripts/` dev tooling with it — content there is never reached,
255
+ * and never copied either).
256
+ */
257
+ export function walkTree(root, skipDir) {
258
+ const entries = walkEntries(root, skipDir);
259
+ const carried = entries.filter((e) => e.pruned === null);
260
+ return {
261
+ files: carried.filter(isCarriedFile).map(({ rel, abs }) => ({ rel, abs })),
262
+ links: carried.filter((e) => e.kind === 'symlink').map(({ rel, abs, target }) => ({ rel, abs, target: target ?? '' })),
263
+ dirs: carried.filter((e) => e.kind === 'dir').map((e) => e.rel),
264
+ others: carried.filter((e) => e.kind === 'other'),
265
+ pruned: entries.filter((e) => e.pruned !== null),
266
+ };
267
+ }
268
+ /** Every proper ancestor directory a set of POSIX-relative file paths implies (`a/b/c.md` → `a`, `a/b`), sorted. */
269
+ export function impliedDirs(rels) {
270
+ const out = new Set();
271
+ for (const rel of rels) {
272
+ const segments = rel.split('/');
273
+ for (let i = 1; i < segments.length; i += 1)
274
+ out.add(segments.slice(0, i).join('/'));
275
+ }
276
+ return [...out].sort();
277
+ }
278
+ export function sha256Hex(data) {
279
+ return createHash('sha256').update(data).digest('hex');
280
+ }
281
+ /** The leaf changed identity between the lstat and the open (a link swapped in, a file replaced) — refused, never read or copied (v3.5 §3). */
282
+ export class EntrySwappedError extends Error {
283
+ path;
284
+ constructor(path) {
285
+ super(`${path} is not the entry the walk judged — it changed between lstat and open (a symlink swapped in, or the file replaced); refused`);
286
+ this.path = path;
287
+ this.name = 'EntrySwappedError';
288
+ }
289
+ }
290
+ /**
291
+ * Open the REGULAR FILE at `path` for reading without following a symlink at the leaf (`O_NOFOLLOW`
292
+ * where available), and prove the opened descriptor IS the entry lstat saw (dev/ino equal, a regular
293
+ * file) — the Windows close of the lstat-then-open gap, applied everywhere (v3.5 §3). Throws
294
+ * `SymlinkComponentError` for a link at the leaf, `EntrySwappedError` when the identity moved, and
295
+ * the filesystem's own error otherwise (ENOENT propagates). Answers the descriptor and its stats.
296
+ */
297
+ export function openRegularNoFollow(path) {
298
+ const before = lstatSync(path);
299
+ if (before.isSymbolicLink())
300
+ throw new SymlinkComponentError(path, path);
301
+ if (!before.isFile())
302
+ throw new EntrySwappedError(path);
303
+ let fd;
304
+ try {
305
+ fd = openSync(path, fsConstants.O_RDONLY | O_NOFOLLOW);
306
+ }
307
+ catch (err) {
308
+ // ELOOP: a link stood there by the time we opened — the swap this discipline exists for.
309
+ if (err.code === 'ELOOP')
310
+ throw new EntrySwappedError(path);
311
+ throw err;
312
+ }
313
+ let stat;
314
+ try {
315
+ stat = fstatSync(fd);
316
+ }
317
+ catch (err) {
318
+ closeSync(fd);
319
+ throw err;
320
+ }
321
+ if (!stat.isFile() || stat.dev !== before.dev || stat.ino !== before.ino) {
322
+ closeSync(fd);
323
+ throw new EntrySwappedError(path);
324
+ }
325
+ return { fd, stat };
326
+ }
327
+ /** The bytes of the regular file at `path`, read through an `O_NOFOLLOW` open with the identity check (`openRegularNoFollow`). */
328
+ export function readFileNoFollow(path) {
329
+ const { fd } = openRegularNoFollow(path);
330
+ try {
331
+ return readFileSync(fd);
332
+ }
333
+ finally {
334
+ closeSync(fd);
335
+ }
336
+ }
337
+ /**
338
+ * Copy one regular file `src` → `dest`: the source is read through `openRegularNoFollow` (never by
339
+ * path — a source swapped for a link between enumeration and copy is refused), the destination is
340
+ * created `O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW` with the source's mode bits (an executable
341
+ * baseline script lands executable), so a pre-planted destination entry — a link included — fails
342
+ * the open instead of being written through.
343
+ */
344
+ export function copyFileNoFollow(src, dest) {
345
+ const { fd: inFd, stat } = openRegularNoFollow(src);
346
+ let buf;
347
+ try {
348
+ buf = readFileSync(inFd);
349
+ }
350
+ finally {
351
+ closeSync(inFd);
352
+ }
353
+ const outFd = openSync(dest, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | O_NOFOLLOW, stat.mode & 0o777);
354
+ try {
355
+ let off = 0;
356
+ while (off < buf.length)
357
+ off += writeSync(outFd, buf, off, buf.length - off);
358
+ }
359
+ catch (err) {
360
+ closeSync(outFd);
361
+ rmSync(dest, { force: true });
362
+ throw err;
363
+ }
364
+ closeSync(outFd);
365
+ }
366
+ /**
367
+ * One hash over a file set: sorted relative paths + content digests (`rel \0 sha256(content) \n`
368
+ * per file). Two trees with the same relative layout and bytes hash equal wherever they live —
369
+ * which is what lets a baseline snapshot and the effective copy be compared by hash alone.
370
+ */
371
+ export function hashFileSet(files) {
372
+ return hashTree(files, []);
373
+ }
374
+ /**
375
+ * One hash over a file set, its symlink entries AND its directory entries: the files as
376
+ * `hashFileSet` spells them, then every link as `rel \0 -> \0 <link text> \n` (sorted), then every
377
+ * directory as `rel \0 dir \n` (sorted; codex round 9 — an extra EMPTY directory planted in a
378
+ * generation used to leave the hash unchanged). With no links and no directories this IS
379
+ * `hashFileSet`, so a bundle's identity hashes as before; a link added, removed or re-pointed, or a
380
+ * directory added or removed, changes the hash — which is what lets `current` verification refuse
381
+ * an injected link or directory (codex rounds 5, 9). Only `rel`s, digests and link TEXT enter the
382
+ * hash, never what a link reaches: two trees with the same layout, bytes and link texts hash equal
383
+ * wherever they live. Publish hashes the directories its file set IMPLIES (`impliedDirs`); a
384
+ * verification hashes the directories it WALKED — equal iff the generation carries no directory
385
+ * beyond those.
386
+ */
387
+ export function hashTree(files, links, dirs = []) {
388
+ const h = createHash('sha256');
389
+ for (const f of [...files].sort((a, b) => (a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0))) {
390
+ h.update(f.rel);
391
+ h.update('\0');
392
+ h.update(sha256Hex(readFileNoFollow(f.abs)));
393
+ h.update('\n');
394
+ }
395
+ for (const l of [...links].sort((a, b) => (a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0))) {
396
+ h.update(l.rel);
397
+ h.update('\0->\0');
398
+ h.update(l.target);
399
+ h.update('\n');
400
+ }
401
+ for (const d of [...dirs].sort()) {
402
+ h.update(d);
403
+ h.update('\0dir\n');
404
+ }
405
+ return h.digest('hex');
406
+ }
407
+ /**
408
+ * Copy every record to `destRoot/<rel>`, creating parents. EVERY destination is preflighted
409
+ * first — the shape (`assertSafeRelSegments`: a `..`, an absolute or drive-prefixed piece, a
410
+ * separator inside a segment, a NUL is refused, whatever produced the record) and the walk
411
+ * (`assertNoSymlinkComponents`: a pre-planted link under the destination would redirect the
412
+ * copy) — and only then does the first byte move, so a refused record leaves NOTHING written
413
+ * (codex round 4: the per-record check used to run only when the record was reached, after the
414
+ * ones ahead of it had landed). Each file goes through `copyFileNoFollow` (v3.5 §3): the source is
415
+ * read through an `O_NOFOLLOW` open with the identity check — a source swapped for a symlink between
416
+ * enumeration and copy is refused — and the destination is created `O_EXCL | O_NOFOLLOW` with the
417
+ * source's mode bits, so an executable baseline script lands executable.
418
+ */
419
+ export function copyFiles(files, destRoot) {
420
+ const plan = [];
421
+ for (const f of files) {
422
+ const dest = assertNoSymlinkComponents(destRoot, assertSafeRelSegments(f.rel));
423
+ plan.push({ src: f.abs, dest });
424
+ }
425
+ for (const { src, dest } of plan) {
426
+ mkdirSync(dirname(dest), { recursive: true });
427
+ copyFileNoFollow(src, dest);
428
+ }
429
+ }
430
+ /**
431
+ * Atomic write (tmp + rename), creating parents — the settings-store discipline, hardened:
432
+ *
433
+ * - the target is lstat'ed: a symlink there is refused (the rename would replace the link,
434
+ * but the caller's containment already forbids links, and a write "over" one is never what
435
+ * the file manager meant);
436
+ * - the temp file is opened `O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW`: POSIX fails that open on ANY existing
437
+ * entry — a symlink included, regardless of where it points — so a pre-planted temp symlink
438
+ * cannot redirect the bytes; the name carries 64 random bits so it cannot be pre-planted by
439
+ * guessing either;
440
+ * - the target's mode bits survive (an in-place edit of an executable support script keeps
441
+ * it executable); a new file takes `opts.mode` or the platform default.
442
+ */
443
+ export function writeFileAtomic(path, content, opts = {}) {
444
+ mkdirSync(dirname(path), { recursive: true });
445
+ let mode = opts.mode;
446
+ try {
447
+ const st = lstatSync(path);
448
+ if (st.isSymbolicLink())
449
+ throw new SymlinkComponentError(path, path);
450
+ if (st.isFile())
451
+ mode = st.mode & 0o777;
452
+ }
453
+ catch (err) {
454
+ if (err.code !== 'ENOENT')
455
+ throw err;
456
+ }
457
+ const tmp = `${path}${ATOMIC_TMP_INFIX}${randomBytes(8).toString('hex')}`;
458
+ const flags = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | O_NOFOLLOW;
459
+ const fd = mode === undefined ? openSync(tmp, flags) : openSync(tmp, flags, mode);
460
+ try {
461
+ const buf = typeof content === 'string' ? Buffer.from(content, 'utf8') : content;
462
+ let off = 0;
463
+ while (off < buf.length)
464
+ off += writeSync(fd, buf, off, buf.length - off);
465
+ }
466
+ catch (err) {
467
+ closeSync(fd);
468
+ rmSync(tmp, { force: true });
469
+ throw err;
470
+ }
471
+ closeSync(fd);
472
+ try {
473
+ renameSync(tmp, path);
474
+ }
475
+ catch (err) {
476
+ rmSync(tmp, { force: true });
477
+ throw err;
478
+ }
479
+ }
480
+ /**
481
+ * Remove the records, then prune directories left empty between each file and `upTo`
482
+ * (exclusive). Never removes a non-empty directory — a nested skill living under a disabled
483
+ * parent's directory stays exactly where it is.
484
+ */
485
+ export function removeFiles(files, upTo) {
486
+ for (const f of files)
487
+ rmSync(f.abs, { force: true });
488
+ for (const f of files)
489
+ pruneEmptyDirs(dirname(f.abs), upTo);
490
+ }
491
+ /** Remove `dir` and its ancestors while they are empty, stopping at `upTo` (which is kept). */
492
+ export function pruneEmptyDirs(dir, upTo) {
493
+ let cur = dir;
494
+ for (;;) {
495
+ const rel = relative(upTo, cur);
496
+ if (rel === '' || rel.startsWith('..'))
497
+ return;
498
+ try {
499
+ rmdirSync(cur); // ENOTEMPTY / ENOENT both end the climb
500
+ }
501
+ catch {
502
+ return;
503
+ }
504
+ cur = dirname(cur);
505
+ }
506
+ }
507
+ function isEnoent(err) {
508
+ return err.code === 'ENOENT';
509
+ }
510
+ /**
511
+ * Every directory under `root` (root included, deepest first), symlinks never followed. `strict`
512
+ * propagates every error but ENOENT (an entry that vanished mid-walk); the lenient mode (the
513
+ * force-remove's) skips what it cannot list — `rmSync` reports what matters there.
514
+ */
515
+ function directoriesUnder(root, strict) {
516
+ const out = [];
517
+ const visit = (dir) => {
518
+ let entries;
519
+ try {
520
+ entries = readdirSync(dir, { withFileTypes: true });
521
+ }
522
+ catch (err) {
523
+ if (strict && !isEnoent(err))
524
+ throw err;
525
+ return;
526
+ }
527
+ for (const entry of entries) {
528
+ if (entry.isSymbolicLink() || !entry.isDirectory())
529
+ continue;
530
+ visit(join(dir, entry.name));
531
+ }
532
+ out.push(dir);
533
+ };
534
+ try {
535
+ if (!lstatSync(root).isDirectory())
536
+ return out;
537
+ }
538
+ catch (err) {
539
+ if (strict && !isEnoent(err))
540
+ throw err;
541
+ return out;
542
+ }
543
+ visit(root);
544
+ return out;
545
+ }
546
+ const WRITE_BITS = 0o222;
547
+ /**
548
+ * Strip the write bits from every directory and file under `root` — the shared per-baseline
549
+ * `.venv` is read-only by contract (design v3 §4): a worker's `uv run` from a snapshot must not
550
+ * install into, or remove from, an env every other snapshot links; a published snapshot is locked
551
+ * the same way (immutable by contract, verified by hash). Files first, then directories (deepest
552
+ * first), so the walk never has to re-open a directory it already closed. A permission failure
553
+ * PROPAGATES (codex round 2 on #480: "silently swallows permission failures while claiming to
554
+ * lock") — a tree this cannot lock is not locked, and the caller decides what that means (the
555
+ * store treats an unlockable env as a failed provisioning, blocking the publish). Only an entry
556
+ * that vanished mid-walk (ENOENT) is tolerated. A no-op on platforms without POSIX modes.
557
+ */
558
+ export function makeTreeReadOnly(root) {
559
+ if (process.platform === 'win32')
560
+ return;
561
+ for (const dir of directoriesUnder(root, true)) {
562
+ let entries;
563
+ try {
564
+ entries = readdirSync(dir, { withFileTypes: true });
565
+ }
566
+ catch (err) {
567
+ if (isEnoent(err))
568
+ continue;
569
+ throw err;
570
+ }
571
+ for (const entry of entries) {
572
+ if (!entry.isFile())
573
+ continue;
574
+ const p = join(dir, entry.name);
575
+ try {
576
+ chmodSync(p, lstatSync(p).mode & 0o777 & ~WRITE_BITS);
577
+ }
578
+ catch (err) {
579
+ if (!isEnoent(err))
580
+ throw err;
581
+ }
582
+ }
583
+ try {
584
+ chmodSync(dir, lstatSync(dir).mode & 0o777 & ~WRITE_BITS);
585
+ }
586
+ catch (err) {
587
+ if (!isEnoent(err))
588
+ throw err;
589
+ }
590
+ }
591
+ }
592
+ /**
593
+ * `rmSync(root, { recursive: true, force: true })` that also removes a tree `makeTreeReadOnly`
594
+ * locked — OR a partial env whose lock FAILED, which can leave an UNLISTABLE directory (a `uv sync`
595
+ * that produced a `0o000`/`0o111` dir the lock choked on; codex round 3). Each directory has its
596
+ * owner `rwx` restored TOP-DOWN, before it is enumerated, so an unlistable dir becomes traversable
597
+ * and removable (unlinking an entry needs a writable, listable parent, whatever the entry's own
598
+ * mode). A missing root is a no-op.
599
+ */
600
+ export function removeTreeForce(root) {
601
+ restoreDirPermsTopDown(root);
602
+ rmSync(root, { recursive: true, force: true });
603
+ }
604
+ /** Give every directory under `dir` (`dir` included, symlinks never followed) owner `rwx` — restored
605
+ * before the dir is read, so even a `0o000` directory can be enumerated and removed. Best-effort. */
606
+ function restoreDirPermsTopDown(dir) {
607
+ let st;
608
+ try {
609
+ st = lstatSync(dir);
610
+ }
611
+ catch {
612
+ return; // gone already
613
+ }
614
+ if (st.isSymbolicLink() || !st.isDirectory())
615
+ return;
616
+ try {
617
+ chmodSync(dir, (st.mode & 0o777) | 0o700);
618
+ }
619
+ catch {
620
+ /* not ours to chmod — rmSync below reports what matters */
621
+ }
622
+ let entries;
623
+ try {
624
+ entries = readdirSync(dir, { withFileTypes: true });
625
+ }
626
+ catch {
627
+ return; // still unreadable (not ours) — rmSync reports it
628
+ }
629
+ for (const entry of entries) {
630
+ if (entry.isSymbolicLink() || !entry.isDirectory())
631
+ continue;
632
+ restoreDirPermsTopDown(join(dir, entry.name));
633
+ }
634
+ }
635
+ /** Unlink one path without following it (a link is removed, its target untouched). */
636
+ export function unlinkNoFollow(path) {
637
+ try {
638
+ unlinkSync(path);
639
+ }
640
+ catch (err) {
641
+ if (err.code !== 'ENOENT')
642
+ throw err;
643
+ }
644
+ }
645
+ //# sourceMappingURL=tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.js","sourceRoot":"","sources":["../../src/skills/tree.ts"],"names":[],"mappings":"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"}