@pennixrv/trellis 0.7.1-beta.8 → 0.7.1-beta.9

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 (56) hide show
  1. package/README.md +10 -7
  2. package/dist/cli/index.d.ts.map +1 -1
  3. package/dist/cli/index.js +2 -0
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/commands/ablate.d.ts.map +1 -1
  6. package/dist/commands/ablate.js +2 -0
  7. package/dist/commands/ablate.js.map +1 -1
  8. package/dist/commands/backup.d.ts +4 -0
  9. package/dist/commands/backup.d.ts.map +1 -0
  10. package/dist/commands/backup.js +75 -0
  11. package/dist/commands/backup.js.map +1 -0
  12. package/dist/commands/init.d.ts.map +1 -1
  13. package/dist/commands/init.js +675 -672
  14. package/dist/commands/init.js.map +1 -1
  15. package/dist/commands/mem.d.ts.map +1 -1
  16. package/dist/commands/mem.js +49 -7
  17. package/dist/commands/mem.js.map +1 -1
  18. package/dist/commands/uninstall.d.ts.map +1 -1
  19. package/dist/commands/uninstall.js +92 -84
  20. package/dist/commands/uninstall.js.map +1 -1
  21. package/dist/commands/update.d.ts.map +1 -1
  22. package/dist/commands/update.js +587 -606
  23. package/dist/commands/update.js.map +1 -1
  24. package/dist/commands/workflow.d.ts.map +1 -1
  25. package/dist/commands/workflow.js +94 -89
  26. package/dist/commands/workflow.js.map +1 -1
  27. package/dist/configurators/shared.js +2 -2
  28. package/dist/configurators/shared.js.map +1 -1
  29. package/dist/migrations/manifests/0.7.1-beta.9.json +191 -0
  30. package/dist/templates/common/bundled-skills/trellis-decision-space-construction-and-merging/workflow.md +2 -0
  31. package/dist/templates/common/bundled-skills/trellis-goal-exploration-and-requirements/workflow.md +2 -0
  32. package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +2 -1
  33. package/dist/templates/common/bundled-skills/trellis-session-insight/references/triggering-patterns.md +2 -2
  34. package/dist/templates/common/bundled-skills/trellis-solution-design-and-convergence/workflow.md +4 -0
  35. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/mcp-setup.md +4 -2
  36. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-task-planning.md +2 -2
  37. package/dist/templates/common/bundled-skills/trellis-teamwork/SKILL.md +1 -1
  38. package/dist/templates/common/commands/start.md +2 -2
  39. package/dist/templates/common/skills/before-dev.md +1 -4
  40. package/dist/templates/common/skills/break-loop.md +7 -18
  41. package/dist/templates/common/skills/check.md +7 -11
  42. package/dist/templates/common/skills/{brainstorm.md → request-intake.md} +5 -3
  43. package/dist/templates/common/skills/update-spec.md +5 -7
  44. package/dist/utils/ablation-store.d.ts +1 -1
  45. package/dist/utils/ablation-store.d.ts.map +1 -1
  46. package/dist/utils/ablation-store.js +58 -24
  47. package/dist/utils/ablation-store.js.map +1 -1
  48. package/dist/utils/asset-backup.d.ts +138 -0
  49. package/dist/utils/asset-backup.d.ts.map +1 -0
  50. package/dist/utils/asset-backup.js +507 -0
  51. package/dist/utils/asset-backup.js.map +1 -0
  52. package/dist/utils/atomic-write.d.ts +1 -1
  53. package/dist/utils/atomic-write.d.ts.map +1 -1
  54. package/dist/utils/atomic-write.js +6 -3
  55. package/dist/utils/atomic-write.js.map +1 -1
  56. package/package.json +2 -2
@@ -0,0 +1,507 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { z } from "zod";
5
+ import { VERSION } from "../constants/version.js";
6
+ import { ALL_MANAGED_DIRS, getConfiguredPlatforms, } from "../configurators/index.js";
7
+ import { getAllMigrations } from "../migrations/index.js";
8
+ import { loadHashes } from "./template-hash.js";
9
+ import { writeFileAtomic } from "./atomic-write.js";
10
+ import { TRELLIS_BLOCK_START, TRELLIS_BLOCK_END } from "./managed-paths.js";
11
+ import { canonicalProjectRoot, projectKey, fingerprintPath, fingerprintsEqual, getTransactionPaths, loadAblationTransaction, withAblationProjectLock, } from "./ablation-store.js";
12
+ import { validateManagedRelativePath } from "./managed-removal.js";
13
+ const fileSchema = z
14
+ .object({
15
+ kind: z.literal("file"),
16
+ sha256: z.string().regex(/^[a-f0-9]{64}$/),
17
+ size: z.number().int().nonnegative(),
18
+ mode: z.number().int().min(0).max(0o7777),
19
+ })
20
+ .strict();
21
+ const fingerprintSchema = z.union([
22
+ fileSchema,
23
+ z.object({ kind: z.literal("absent") }).strict(),
24
+ ]);
25
+ const entrySchema = z
26
+ .object({
27
+ path: z.string(),
28
+ before: fingerprintSchema,
29
+ after: fingerprintSchema.optional(),
30
+ afterBlock: z.string().optional(),
31
+ })
32
+ .strict();
33
+ const manifestSchema = z
34
+ .object({
35
+ schema: z.literal(1),
36
+ contract: z.literal("status-layout-v1/five-phases-v1"),
37
+ id: z.string(),
38
+ projectRoot: z.string(),
39
+ projectKey: z.string(),
40
+ createdAt: z.string().datetime(),
41
+ version: z.string(),
42
+ sourceVersion: z.string(),
43
+ workflow: z.string(),
44
+ platforms: z.array(z.string()),
45
+ runtime: z.record(z.string(), fingerprintSchema),
46
+ reason: z.enum(["manual", "update", "restore-recovery"]),
47
+ update: z.enum(["pending", "succeeded", "restored", "not-applicable"]),
48
+ entries: z.array(entrySchema),
49
+ restore: z
50
+ .object({
51
+ status: z.enum(["restoring", "complete"]),
52
+ review: z.string(),
53
+ recovery: z.string(),
54
+ entries: z.array(z
55
+ .object({
56
+ path: z.string(),
57
+ current: fingerprintSchema,
58
+ desired: fingerprintSchema,
59
+ })
60
+ .strict()),
61
+ })
62
+ .strict()
63
+ .optional(),
64
+ })
65
+ .strict();
66
+ const BACKUP_ID = /^\.backup-\d{4}-\d{2}-\d{2}T[\d-]+Z-[a-f0-9-]{36}$/;
67
+ const LEGACY_ID = /^\.backup-\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}(?:-\d{3}Z)?$/;
68
+ const META = [".trellis/.version", ".trellis/.template-hashes.json"];
69
+ const RUNTIME = [
70
+ ".trellis/scripts/common/task_layout.py",
71
+ ".trellis/scripts/common/task_workflow.py",
72
+ ];
73
+ const PROTECTED = /(?:^|\/)(?:tasks|spec|workspace|backlog|session-handoffs|sessions|history|logs?|cache|node_modules|worktrees?|agent-traces|\.runtime|\.git|credentials?|secrets?)(?:\/|$)|(?:^|\/)\.backup-|(?:^|\/)\.env(?:\.|$)|(?:^|\/)(?:\.developer|\.task-layout-migration\.json)$/i;
74
+ /** Reject all symlink components, including links that happen to stay in-project. */
75
+ function safePath(root, relative) {
76
+ validateManagedRelativePath(relative);
77
+ root = canonicalProjectRoot(root);
78
+ let cursor = root;
79
+ for (const part of relative.split("/")) {
80
+ cursor = path.join(cursor, part);
81
+ try {
82
+ const stat = fs.lstatSync(cursor);
83
+ if (stat.isSymbolicLink())
84
+ throw new Error(`Symlink in asset path: ${relative}`);
85
+ if (cursor !== path.join(root, relative) && !stat.isDirectory())
86
+ throw new Error(`Invalid asset parent: ${relative}`);
87
+ }
88
+ catch (error) {
89
+ if (error.code !== "ENOENT")
90
+ throw error;
91
+ }
92
+ }
93
+ return cursor;
94
+ }
95
+ function assetPath(relative) {
96
+ validateManagedRelativePath(relative);
97
+ return (!PROTECTED.test(relative) &&
98
+ (relative === "AGENTS.md" ||
99
+ ALL_MANAGED_DIRS.some((dir) => relative.startsWith(`${dir}/`))));
100
+ }
101
+ function current(root, relative) {
102
+ const fp = fingerprintPath(safePath(root, relative));
103
+ if (fp.kind !== "file" && fp.kind !== "absent")
104
+ throw new Error(`Asset must be a regular file: ${relative}`);
105
+ return fp;
106
+ }
107
+ function digest(value) {
108
+ return createHash("sha256").update(JSON.stringify(value)).digest("hex");
109
+ }
110
+ function block(content) {
111
+ const start = content.indexOf(TRELLIS_BLOCK_START);
112
+ const end = content.indexOf(TRELLIS_BLOCK_END);
113
+ if (start < 0 ||
114
+ end < start ||
115
+ content.indexOf(TRELLIS_BLOCK_START, start + 1) >= 0 ||
116
+ content.indexOf(TRELLIS_BLOCK_END, end + 1) >= 0)
117
+ return undefined;
118
+ return content.slice(start, end + TRELLIS_BLOCK_END.length);
119
+ }
120
+ function backupDir(root, id) {
121
+ if (!BACKUP_ID.test(id))
122
+ throw new Error(`Invalid asset backup id: ${id}`);
123
+ return safePath(root, `.trellis/${id}`);
124
+ }
125
+ function save(root, backup) {
126
+ const dir = backupDir(root, backup.id);
127
+ const file = safePath(dir, "manifest.json");
128
+ writeFileAtomic(file, `${JSON.stringify(manifestSchema.parse(backup), null, 2)}\n`, 0o600);
129
+ }
130
+ export function loadAssetBackup(root, id) {
131
+ root = canonicalProjectRoot(root);
132
+ const dir = backupDir(root, id);
133
+ const result = manifestSchema.parse(JSON.parse(fs.readFileSync(safePath(dir, "manifest.json"), "utf-8")));
134
+ if (result.id !== id ||
135
+ result.projectRoot !== root ||
136
+ result.projectKey !== projectKey(root))
137
+ throw new Error("Asset backup belongs to a different project.");
138
+ const paths = new Set();
139
+ for (const entry of result.entries) {
140
+ if (!assetPath(entry.path) || paths.has(entry.path))
141
+ throw new Error(`Invalid or duplicate asset scope: ${entry.path}`);
142
+ paths.add(entry.path);
143
+ const stored = current(dir, `files/${entry.path}`);
144
+ if (!fingerprintsEqual(stored, entry.before))
145
+ throw new Error(`Asset backup integrity failure: ${entry.path}`);
146
+ }
147
+ if (result.restore) {
148
+ if (result.restore.entries.length !== result.entries.length)
149
+ throw new Error("Invalid restore scope.");
150
+ for (const entry of result.restore.entries)
151
+ if (!paths.delete(entry.path))
152
+ throw new Error("Invalid restore path.");
153
+ }
154
+ if (treeSize(dir).files !==
155
+ 1 + result.entries.filter((entry) => entry.before.kind === "file").length)
156
+ throw new Error("Unexpected files in asset backup; retained for inspection.");
157
+ return result;
158
+ }
159
+ export function assetBackupScope(root, extra = []) {
160
+ return [...new Set([...Object.keys(loadHashes(root)), ...META, ...extra])]
161
+ .filter(assetPath)
162
+ .sort();
163
+ }
164
+ /** Caller holds the shared maintenance lock through the associated asset writes. */
165
+ export function createAssetBackup(root, reason = "manual", paths = assetBackupScope(root)) {
166
+ root = canonicalProjectRoot(root);
167
+ const id = `.backup-${new Date().toISOString().replace(/[:.]/g, "-")}-${randomUUID()}`;
168
+ const dir = backupDir(root, id);
169
+ const staging = safePath(root, `.trellis/.backup-preparing-${randomUUID()}`);
170
+ const scope = [...new Set(paths)].sort();
171
+ const entries = scope.map((relative) => {
172
+ if (!assetPath(relative))
173
+ throw new Error(`Protected or unmanaged asset: ${relative}`);
174
+ return { path: relative, before: current(root, relative) };
175
+ });
176
+ fs.mkdirSync(staging, { mode: 0o700 });
177
+ for (const entry of entries) {
178
+ if (entry.before.kind === "absent")
179
+ continue;
180
+ const source = safePath(root, entry.path);
181
+ const target = safePath(staging, `files/${entry.path}`);
182
+ fs.mkdirSync(path.dirname(target), { recursive: true, mode: 0o700 });
183
+ fs.copyFileSync(source, target, fs.constants.COPYFILE_EXCL);
184
+ if (process.platform !== "win32")
185
+ fs.chmodSync(target, entry.before.mode);
186
+ if (!fingerprintsEqual(current(staging, `files/${entry.path}`), entry.before) ||
187
+ !fingerprintsEqual(current(root, entry.path), entry.before))
188
+ throw new Error(`Asset changed during backup: ${entry.path}`);
189
+ }
190
+ const versionFile = safePath(root, ".trellis/.version");
191
+ const workflowFile = safePath(root, ".trellis/workflow.md");
192
+ const backup = {
193
+ schema: 1,
194
+ contract: "status-layout-v1/five-phases-v1",
195
+ id,
196
+ projectRoot: root,
197
+ projectKey: projectKey(root),
198
+ createdAt: new Date().toISOString(),
199
+ version: VERSION,
200
+ sourceVersion: fs.existsSync(versionFile)
201
+ ? fs.readFileSync(versionFile, "utf-8").trim()
202
+ : "unknown",
203
+ workflow: fs.existsSync(workflowFile)
204
+ ? digest(fs.readFileSync(workflowFile))
205
+ : "absent",
206
+ runtime: Object.fromEntries(RUNTIME.map((relative) => [relative, current(root, relative)])),
207
+ platforms: [...getConfiguredPlatforms(root)],
208
+ reason,
209
+ update: reason === "update" ? "pending" : "not-applicable",
210
+ entries,
211
+ };
212
+ fs.writeFileSync(path.join(staging, "manifest.json"), `${JSON.stringify(manifestSchema.parse(backup), null, 2)}\n`, { mode: 0o600, flag: "wx" });
213
+ fs.renameSync(staging, dir);
214
+ return loadAssetBackup(root, id);
215
+ }
216
+ export function bindAssetUpdate(root, id) {
217
+ const backup = loadAssetBackup(root, id);
218
+ for (const entry of backup.entries) {
219
+ entry.after = current(root, entry.path);
220
+ if (entry.path === "AGENTS.md" && entry.after.kind === "file") {
221
+ const managed = block(fs.readFileSync(safePath(root, entry.path), "utf-8"));
222
+ if (managed !== undefined)
223
+ entry.afterBlock = digest(managed);
224
+ }
225
+ }
226
+ backup.update = "succeeded";
227
+ save(root, backup);
228
+ }
229
+ function treeSize(root) {
230
+ const stat = fs.lstatSync(root);
231
+ if (stat.isSymbolicLink())
232
+ throw new Error("Symlink in backup storage.");
233
+ if (stat.isFile())
234
+ return { bytes: stat.size, files: 1 };
235
+ if (!stat.isDirectory())
236
+ throw new Error("Unsupported backup storage object.");
237
+ const total = { bytes: 0, files: 0 };
238
+ for (const name of fs.readdirSync(root)) {
239
+ const size = treeSize(path.join(root, name));
240
+ total.bytes += size.bytes;
241
+ total.files += size.files;
242
+ }
243
+ return total;
244
+ }
245
+ export function listAssetBackups(root) {
246
+ const workflow = safePath(root, ".trellis");
247
+ if (!fs.existsSync(workflow))
248
+ return [];
249
+ const result = [];
250
+ const activeRecovery = new Set();
251
+ for (const id of fs
252
+ .readdirSync(workflow)
253
+ .filter((name) => name.startsWith(".backup-"))
254
+ .sort()) {
255
+ const relative = `.trellis/${id}`;
256
+ const item = {
257
+ id,
258
+ path: relative,
259
+ kind: "protected",
260
+ bytes: 0,
261
+ files: 0,
262
+ fingerprint: "",
263
+ };
264
+ try {
265
+ const location = safePath(root, relative);
266
+ Object.assign(item, treeSize(location));
267
+ item.fingerprint = digest(fingerprintPath(location));
268
+ if (BACKUP_ID.test(id)) {
269
+ const backup = loadAssetBackup(root, id);
270
+ if (backup.restore?.status === "restoring")
271
+ activeRecovery.add(backup.restore.recovery);
272
+ if (backup.update === "pending" ||
273
+ backup.restore?.status === "restoring")
274
+ item.problem =
275
+ "Unresolved update or restore; inspect before cleanup.";
276
+ else
277
+ item.kind = "complete";
278
+ }
279
+ else if (LEGACY_ID.test(id)) {
280
+ const names = fs.readdirSync(location);
281
+ if (!names.length ||
282
+ !names.some((name) => name === ".trellis" || name === "AGENTS.md") ||
283
+ names.some((name) => name !== "AGENTS.md" && !ALL_MANAGED_DIRS.includes(name)))
284
+ throw new Error("Unknown legacy backup scope.");
285
+ item.kind = "legacy";
286
+ }
287
+ else
288
+ item.problem = "Unknown or incomplete backup; retained.";
289
+ }
290
+ catch (error) {
291
+ item.problem = error instanceof Error ? error.message : String(error);
292
+ }
293
+ result.push(item);
294
+ }
295
+ for (const item of result) {
296
+ if (activeRecovery.has(item.id)) {
297
+ item.kind = "protected";
298
+ item.problem = "Unresolved restore depends on this recovery snapshot.";
299
+ }
300
+ }
301
+ const owned = new Set([
302
+ ...Object.keys(loadHashes(root)),
303
+ ...getAllMigrations().flatMap((item) => [
304
+ item.from,
305
+ ...(item.to ? [item.to] : []),
306
+ ]),
307
+ ]);
308
+ for (const original of owned) {
309
+ if (!assetPath(original))
310
+ continue;
311
+ const relative = `${original}.backup`;
312
+ try {
313
+ const location = safePath(root, relative);
314
+ if (!fs.existsSync(location))
315
+ continue;
316
+ if (!fs.lstatSync(location).isFile())
317
+ throw new Error("Migration sidecar is not a regular file; retained.");
318
+ const size = treeSize(location);
319
+ result.push({
320
+ id: relative,
321
+ path: relative,
322
+ kind: "sidecar",
323
+ ...size,
324
+ fingerprint: digest(fingerprintPath(location)),
325
+ });
326
+ }
327
+ catch (error) {
328
+ result.push({
329
+ id: relative,
330
+ path: relative,
331
+ kind: "protected",
332
+ bytes: 0,
333
+ files: 0,
334
+ fingerprint: "",
335
+ problem: error instanceof Error ? error.message : String(error),
336
+ });
337
+ }
338
+ }
339
+ return result;
340
+ }
341
+ export function assertNoAssetRecovery(root) {
342
+ const active = listAssetBackups(root).filter((item) => item.problem?.startsWith("Unresolved"));
343
+ if (active.length)
344
+ throw new Error(`Unresolved asset recovery: ${active.map((item) => item.id).join(", ")}. Inspect the backup before changing assets.`);
345
+ }
346
+ export function withAssetMaintenance(root, operation, readOnly = false) {
347
+ if (readOnly)
348
+ return operation();
349
+ return withAblationProjectLock(getTransactionPaths(root), () => {
350
+ if (loadAblationTransaction(root))
351
+ throw new Error("An ablation transaction exists; use trellis restore first.");
352
+ assertNoAssetRecovery(root);
353
+ return operation();
354
+ });
355
+ }
356
+ export function pruneAssetBackups(root, options = {}) {
357
+ const inventory = listAssetBackups(root);
358
+ const keep = options.keep ?? 3;
359
+ if (!Number.isSafeInteger(keep) || keep < 3)
360
+ throw new Error("Daily retention requires at least three complete backups; use explicit --all for full cleanup.");
361
+ if (options.includeLegacy && !options.all)
362
+ throw new Error("Legacy cleanup requires --all --include-legacy.");
363
+ const eligible = inventory.filter((item) => item.kind === "complete");
364
+ const selected = options.all
365
+ ? inventory.filter((item) => item.kind === "complete" ||
366
+ (options.includeLegacy &&
367
+ (item.kind === "legacy" || item.kind === "sidecar")))
368
+ : eligible.slice(0, Math.max(0, eligible.length - keep));
369
+ const report = {
370
+ selected,
371
+ protected: inventory.filter((item) => !selected.includes(item)),
372
+ deleted: [],
373
+ failed: [],
374
+ };
375
+ if (!options.yes)
376
+ return report;
377
+ if (loadAblationTransaction(root))
378
+ throw new Error("An ablation transaction exists; cleanup is blocked.");
379
+ for (const item of selected) {
380
+ try {
381
+ const latest = listAssetBackups(root).find((candidate) => candidate.path === item.path);
382
+ if (latest?.kind !== item.kind || latest.fingerprint !== item.fingerprint)
383
+ throw new Error("Backup changed since cleanup preflight.");
384
+ const location = safePath(root, item.path);
385
+ treeSize(location);
386
+ fs.rmSync(location, { recursive: true });
387
+ report.deleted.push(item.path);
388
+ }
389
+ catch (error) {
390
+ report.failed.push({
391
+ path: item.path,
392
+ error: error instanceof Error ? error.message : String(error),
393
+ });
394
+ }
395
+ }
396
+ return report;
397
+ }
398
+ function desiredContent(root, backup, relative) {
399
+ const entry = backup.entries.find((item) => item.path === relative);
400
+ if (!entry || entry.before.kind === "absent")
401
+ return undefined;
402
+ const stored = fs.readFileSync(safePath(backupDir(root, backup.id), `files/${relative}`));
403
+ if (relative !== "AGENTS.md" || current(root, relative).kind === "absent")
404
+ return stored;
405
+ const previous = block(stored.toString("utf-8"));
406
+ const now = fs.readFileSync(safePath(root, relative), "utf-8");
407
+ const active = block(now);
408
+ return previous && active
409
+ ? Buffer.from(now.replace(active, previous))
410
+ : stored;
411
+ }
412
+ export function planAssetRestore(root, id, replaceModified = false) {
413
+ const backup = loadAssetBackup(root, id);
414
+ // Asset rollback cannot roll back task data; require the exact task runtime.
415
+ if (Object.keys(backup.runtime).length !== RUNTIME.length ||
416
+ RUNTIME.some((relative) => {
417
+ const recorded = backup.runtime[relative];
418
+ return (recorded?.kind !== "file" ||
419
+ !fingerprintsEqual(recorded, current(root, relative)));
420
+ }))
421
+ throw new Error("Task layout/phase runtime compatibility cannot be verified; assets were not changed.");
422
+ const entries = backup.entries.map((entry) => {
423
+ const actual = current(root, entry.path);
424
+ const data = desiredContent(root, backup, entry.path);
425
+ const desired = data === undefined
426
+ ? { kind: "absent" }
427
+ : {
428
+ kind: "file",
429
+ sha256: createHash("sha256").update(data).digest("hex"),
430
+ size: data.length,
431
+ mode: entry.before.kind === "file" ? entry.before.mode : 0o644,
432
+ };
433
+ const resumed = backup.restore?.status === "restoring"
434
+ ? backup.restore.entries.find((item) => item.path === entry.path)
435
+ : undefined;
436
+ const mixedMatch = entry.path === "AGENTS.md" &&
437
+ entry.afterBlock !== undefined &&
438
+ actual.kind === "file" &&
439
+ digest(block(fs.readFileSync(safePath(root, entry.path), "utf-8"))) ===
440
+ entry.afterBlock;
441
+ const safe = resumed
442
+ ? fingerprintsEqual(actual, resumed.current) ||
443
+ fingerprintsEqual(actual, resumed.desired)
444
+ : entry.after !== undefined &&
445
+ (fingerprintsEqual(actual, entry.after) || mixedMatch);
446
+ const same = fingerprintsEqual(actual, desired);
447
+ const action = same
448
+ ? "keep"
449
+ : safe || (replaceModified && !resumed)
450
+ ? desired.kind === "absent"
451
+ ? "delete"
452
+ : "write"
453
+ : "conflict";
454
+ return { path: entry.path, current: actual, desired, action };
455
+ });
456
+ return { id, review: digest({ id, replaceModified, entries }), entries };
457
+ }
458
+ export function restoreAssetBackup(root, id, options = {}) {
459
+ const plan = planAssetRestore(root, id, options.replaceModified);
460
+ if (!options.yes)
461
+ return plan;
462
+ if (options.review !== plan.review)
463
+ throw new Error("Restore requires the current preview --review digest; preview again after any change.");
464
+ if (plan.entries.some((entry) => entry.action === "conflict"))
465
+ throw new Error("Restore conflicts remain; no assets changed.");
466
+ const backup = loadAssetBackup(root, id);
467
+ if (!backup.restore || backup.restore.status === "complete") {
468
+ const recovery = createAssetBackup(root, "restore-recovery", backup.entries.map((entry) => entry.path));
469
+ backup.restore = {
470
+ status: "restoring",
471
+ review: plan.review,
472
+ recovery: recovery.id,
473
+ entries: plan.entries.map(({ path: relative, current: actual, desired }) => ({
474
+ path: relative,
475
+ current: actual,
476
+ desired,
477
+ })),
478
+ };
479
+ save(root, backup);
480
+ }
481
+ for (const entry of plan.entries) {
482
+ if (entry.action === "keep")
483
+ continue;
484
+ const target = safePath(root, entry.path);
485
+ if (!fingerprintsEqual(current(root, entry.path), entry.current))
486
+ throw new Error(`Asset changed during restore: ${entry.path}`);
487
+ if (entry.action === "delete")
488
+ fs.unlinkSync(target);
489
+ else {
490
+ const data = desiredContent(root, backup, entry.path);
491
+ if (data === undefined || entry.desired.kind !== "file")
492
+ throw new Error("Missing restore payload.");
493
+ fs.mkdirSync(path.dirname(target), { recursive: true });
494
+ writeFileAtomic(target, data, entry.desired.mode);
495
+ }
496
+ if (!fingerprintsEqual(current(root, entry.path), entry.desired))
497
+ throw new Error(`Restore verification failed: ${entry.path}`);
498
+ }
499
+ if (!backup.restore)
500
+ throw new Error("Missing restore transaction.");
501
+ backup.restore.status = "complete";
502
+ if (backup.update === "pending")
503
+ backup.update = "restored";
504
+ save(root, backup);
505
+ return plan;
506
+ }
507
+ //# sourceMappingURL=asset-backup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-backup.js","sourceRoot":"","sources":["../../src/utils/asset-backup.ts"],"names":[],"mappings":"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"}
@@ -8,5 +8,5 @@
8
8
  * On failure the temp file is removed on a best-effort basis and the
9
9
  * original error is re-thrown.
10
10
  */
11
- export declare function writeFileAtomic(filePath: string, data: string | Uint8Array): void;
11
+ export declare function writeFileAtomic(filePath: string, data: string | Uint8Array, mode?: number): void;
12
12
  //# sourceMappingURL=atomic-write.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"atomic-write.d.ts","sourceRoot":"","sources":["../../src/utils/atomic-write.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GAAG,UAAU,GACxB,IAAI,CAcN"}
1
+ {"version":3,"file":"atomic-write.d.ts","sourceRoot":"","sources":["../../src/utils/atomic-write.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GAAG,UAAU,EACzB,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CAmBN"}
@@ -1,5 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { randomUUID } from "node:crypto";
3
4
  /**
4
5
  * Write a file atomically: stream into a temp file in the same directory,
5
6
  * then rename it over the target. A crash, Ctrl-C, or ENOSPC mid-write
@@ -10,11 +11,13 @@ import path from "node:path";
10
11
  * On failure the temp file is removed on a best-effort basis and the
11
12
  * original error is re-thrown.
12
13
  */
13
- export function writeFileAtomic(filePath, data) {
14
+ export function writeFileAtomic(filePath, data, mode) {
14
15
  const dir = path.dirname(filePath);
15
- const tmp = path.join(dir, `.${path.basename(filePath)}.${process.pid}.tmp`);
16
+ const tmp = path.join(dir, `.${path.basename(filePath)}.${process.pid}.${randomUUID()}.tmp`);
16
17
  try {
17
- fs.writeFileSync(tmp, data);
18
+ fs.writeFileSync(tmp, data, { flag: "wx", mode });
19
+ if (mode !== undefined && process.platform !== "win32")
20
+ fs.chmodSync(tmp, mode);
18
21
  fs.renameSync(tmp, filePath);
19
22
  }
20
23
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"atomic-write.js","sourceRoot":"","sources":["../../src/utils/atomic-write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,IAAyB;IAEzB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;IAC7E,IAAI,CAAC;QACH,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC;YACH,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,wDAAwD;QAC1D,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"atomic-write.js","sourceRoot":"","sources":["../../src/utils/atomic-write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,IAAyB,EACzB,IAAa;IAEb,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CACnB,GAAG,EACH,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,GAAG,IAAI,UAAU,EAAE,MAAM,CACjE,CAAC;IACF,IAAI,CAAC;QACH,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;YACpD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1B,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC;YACH,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,wDAAwD;QAC1D,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pennixrv/trellis",
3
- "version": "0.7.1-beta.8",
3
+ "version": "0.7.1-beta.9",
4
4
  "description": "AI capabilities grow like ivy — Trellis provides the structure to guide them along a disciplined path",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -34,7 +34,7 @@
34
34
  "inquirer": "^9.3.7",
35
35
  "undici": "^6.21.0",
36
36
  "zod": "^4.4.2",
37
- "@pennixrv/trellis-core": "0.7.1-beta.8"
37
+ "@pennixrv/trellis-core": "0.7.1-beta.9"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@eslint/js": "^9.18.0",