@mindfoldhq/trellis 0.5.13 → 0.5.15

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 (43) hide show
  1. package/README.md +49 -49
  2. package/dist/commands/init.d.ts.map +1 -1
  3. package/dist/commands/init.js +70 -41
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/commands/uninstall.d.ts.map +1 -1
  6. package/dist/commands/uninstall.js +28 -2
  7. package/dist/commands/uninstall.js.map +1 -1
  8. package/dist/commands/update.d.ts.map +1 -1
  9. package/dist/commands/update.js +21 -1
  10. package/dist/commands/update.js.map +1 -1
  11. package/dist/configurators/claude.d.ts.map +1 -1
  12. package/dist/configurators/claude.js +1 -0
  13. package/dist/configurators/claude.js.map +1 -1
  14. package/dist/migrations/manifests/0.5.14.json +9 -0
  15. package/dist/migrations/manifests/0.5.15.json +9 -0
  16. package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
  17. package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
  18. package/dist/templates/codex/hooks/session-start.py +22 -0
  19. package/dist/templates/codex/hooks.json +1 -1
  20. package/dist/templates/copilot/hooks/session-start.py +24 -0
  21. package/dist/templates/shared-hooks/inject-workflow-state.py +22 -0
  22. package/dist/templates/shared-hooks/session-start.py +19 -6
  23. package/dist/templates/trellis/scripts/common/cli_adapter.py +0 -0
  24. package/dist/templates/trellis/scripts/common/safe_commit.py +49 -19
  25. package/dist/templates/trellis/scripts/common/task_store.py +42 -12
  26. package/dist/templates/trellis/scripts/task.py +0 -0
  27. package/dist/utils/cwd-guard.d.ts +38 -0
  28. package/dist/utils/cwd-guard.d.ts.map +1 -0
  29. package/dist/utils/cwd-guard.js +62 -0
  30. package/dist/utils/cwd-guard.js.map +1 -0
  31. package/dist/utils/file-writer.d.ts +13 -0
  32. package/dist/utils/file-writer.d.ts.map +1 -1
  33. package/dist/utils/file-writer.js +59 -1
  34. package/dist/utils/file-writer.js.map +1 -1
  35. package/dist/utils/manifest-prune.d.ts +61 -0
  36. package/dist/utils/manifest-prune.d.ts.map +1 -0
  37. package/dist/utils/manifest-prune.js +136 -0
  38. package/dist/utils/manifest-prune.js.map +1 -0
  39. package/dist/utils/template-hash.d.ts +32 -6
  40. package/dist/utils/template-hash.d.ts.map +1 -1
  41. package/dist/utils/template-hash.js +53 -31
  42. package/dist/utils/template-hash.js.map +1 -1
  43. package/package.json +27 -26
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Self-heal poisoned `.template-hashes.json` manifests.
3
+ *
4
+ * Versions before this fix walked `.codex/`, `.claude/`, etc. with a blind
5
+ * recursive scan when computing the manifest, so they hashed user-owned
6
+ * runtime data (`.codex/sessions/*`, `.claude/projects/*.jsonl`, pre-existing
7
+ * `AGENTS.md`, user-added `.codex/skills/<custom>/`, …). On uninstall, every
8
+ * manifest entry is unlinked, which silently deletes user data.
9
+ *
10
+ * `pruneOrphanManifestKeys` removes any manifest entry that no current
11
+ * platform configurator owns. The two entry points that consume it are
12
+ * `trellis update` (before migration classification) and `trellis uninstall`
13
+ * (before plan building). Together they ensure existing poisoned manifests
14
+ * self-correct on the next routine command.
15
+ *
16
+ * Rules:
17
+ * - `.trellis/*` entries are ALWAYS kept. `trellis uninstall` removes
18
+ * `.trellis/` wholesale via `fs.rmSync(..., { recursive: true })`, so
19
+ * manifest accuracy there doesn't affect uninstall data-loss. `update`
20
+ * also relies on these entries to detect user-modified workflow files.
21
+ * - Root-level `AGENTS.md` is kept only when it still looks Trellis-managed
22
+ * (contains the managed block markers) or is missing on disk. This
23
+ * self-heals old poisoned manifests for user-owned AGENTS.md files that
24
+ * predated init and were skipped.
25
+ * - Paths referenced by `from`/`to` of any migration manifest entry
26
+ * (rename, rename-dir, delete, safe-file-delete) are preserved. Pruning
27
+ * them would prevent legitimate pending migrations from finding their
28
+ * source/target.
29
+ * - Everything else: if the path is not in the union of
30
+ * `collectPlatformTemplates()` for currently-configured platforms, it is
31
+ * pruned. This matches "files trellis actually wrote during init/update".
32
+ */
33
+ import fs from "node:fs";
34
+ import path from "node:path";
35
+ import { collectPlatformTemplates } from "../configurators/index.js";
36
+ import { FILE_NAMES } from "../constants/paths.js";
37
+ import { getAllMigrations } from "../migrations/index.js";
38
+ import { saveHashes } from "./template-hash.js";
39
+ import { toPosix } from "./posix.js";
40
+ const TRELLIS_BLOCK_START = "<!-- TRELLIS:START -->";
41
+ const TRELLIS_BLOCK_END = "<!-- TRELLIS:END -->";
42
+ /**
43
+ * Compute the union of "what trellis writes" across:
44
+ * - every configured platform's collectTemplates() output
45
+ * - root-level AGENTS.md when it still carries Trellis managed-block markers
46
+ * - every migration manifest's from/to path (preserve so legitimate
47
+ * pending migrations can find their source/target)
48
+ */
49
+ function buildKnownKeys(configuredPlatforms) {
50
+ const known = new Set();
51
+ for (const id of configuredPlatforms) {
52
+ const templates = collectPlatformTemplates(id);
53
+ if (!templates)
54
+ continue;
55
+ for (const key of templates.keys()) {
56
+ known.add(toPosix(key));
57
+ }
58
+ }
59
+ // Preserve any path referenced by a migration: legitimate pending
60
+ // rename/delete operations need to resolve their `from` (and the target's
61
+ // hash record for `to`) even if the current registry doesn't list it.
62
+ for (const migration of getAllMigrations()) {
63
+ if (migration.from)
64
+ known.add(toPosix(migration.from));
65
+ if (migration.to)
66
+ known.add(toPosix(migration.to));
67
+ }
68
+ return known;
69
+ }
70
+ /**
71
+ * Root-level AGENTS.md needs special handling because it has no platform
72
+ * registry owner. New fixed inits record it only when written, but old
73
+ * manifests may contain a user-owned AGENTS.md that init skipped. The
74
+ * managed block markers are the least destructive ownership signal: no
75
+ * markers means preserve the user's file by pruning the stale manifest key.
76
+ */
77
+ function shouldKeepAgentsMd(cwd) {
78
+ const fullPath = path.join(cwd, FILE_NAMES.AGENTS);
79
+ if (!fs.existsSync(fullPath)) {
80
+ return true;
81
+ }
82
+ try {
83
+ const content = fs.readFileSync(fullPath, "utf-8");
84
+ return (content.includes(TRELLIS_BLOCK_START) &&
85
+ content.includes(TRELLIS_BLOCK_END));
86
+ }
87
+ catch {
88
+ return true;
89
+ }
90
+ }
91
+ /**
92
+ * Walk the manifest and split it into kept vs pruned entries.
93
+ *
94
+ * @param cwd Project root — used to save the rewritten manifest.
95
+ * @param configuredPlatforms Output of `getConfiguredPlatforms(cwd)` — caller
96
+ * resolves this so we don't have to re-walk the filesystem.
97
+ * @param hashes Already-loaded manifest contents. Passing it in (vs reading
98
+ * from disk) lets the caller chain `loadHashes` → prune → use the result.
99
+ * @param options.persist When true (default), saves the pruned manifest to
100
+ * disk. Pass `false` for dry-run flows.
101
+ */
102
+ export function pruneOrphanManifestKeys(cwd, configuredPlatforms, hashes, options = {}) {
103
+ const persist = options.persist ?? true;
104
+ const known = buildKnownKeys(configuredPlatforms);
105
+ const pruned = [];
106
+ const kept = {};
107
+ for (const [rawKey, value] of Object.entries(hashes)) {
108
+ const key = toPosix(rawKey);
109
+ // Always preserve .trellis/ entries — they're for the workflow tree
110
+ // which uninstall removes wholesale and which update needs for
111
+ // modified-file detection.
112
+ if (key.startsWith(".trellis/") || key === ".trellis") {
113
+ kept[key] = value;
114
+ continue;
115
+ }
116
+ if (key === FILE_NAMES.AGENTS) {
117
+ if (shouldKeepAgentsMd(cwd)) {
118
+ kept[key] = value;
119
+ }
120
+ else {
121
+ pruned.push(key);
122
+ }
123
+ continue;
124
+ }
125
+ if (known.has(key)) {
126
+ kept[key] = value;
127
+ continue;
128
+ }
129
+ pruned.push(key);
130
+ }
131
+ if (persist && pruned.length > 0) {
132
+ saveHashes(cwd, kept);
133
+ }
134
+ return { pruned, hashes: kept };
135
+ }
136
+ //# sourceMappingURL=manifest-prune.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-prune.js","sourceRoot":"","sources":["../../src/utils/manifest-prune.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAIrC,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AACrD,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;AASjD;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,mBAAsC;IAC5D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,EAAE,IAAI,mBAAmB,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,wBAAwB,CAAC,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,SAAS;YAAE,SAAS;QACzB,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;YACnC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,kEAAkE;IAClE,0EAA0E;IAC1E,sEAAsE;IACtE,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE,EAAE,CAAC;QAC3C,IAAI,SAAS,CAAC,IAAI;YAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QACvD,IAAI,SAAS,CAAC,EAAE;YAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CAAC,GAAW;IACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IACnD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,CACL,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YACrC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CACpC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAWD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CACrC,GAAW,EACX,mBAAsC,EACtC,MAAsB,EACtB,UAAwB,EAAE;IAE1B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;IACxC,MAAM,KAAK,GAAG,cAAc,CAAC,mBAAmB,CAAC,CAAC;IAClD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAmB,EAAE,CAAC;IAEhC,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACrD,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC5B,oEAAoE;QACpE,+DAA+D;QAC/D,2BAA2B;QAC3B,IAAI,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;YACtD,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;YAC9B,IAAI,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAClB,SAAS;QACX,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAED,IAAI,OAAO,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC"}
@@ -83,15 +83,41 @@ export declare function matchesOriginalTemplate(cwd: string, relativePath: strin
83
83
  * @returns Map of path to modification status
84
84
  */
85
85
  export declare function getModificationStatus(cwd: string, relativePaths: string[], hashes: TemplateHashes): Map<string, boolean>;
86
+ /** Options accepted by {@link initializeHashes}. */
87
+ export interface InitializeHashesOptions {
88
+ /**
89
+ * POSIX-style relative paths trellis actually wrote during the init run
90
+ * (captured via `startRecordingWrites` in `file-writer.ts`). Only these
91
+ * paths are hashed for the platform/root-level coverage; anything else
92
+ * under `.codex/` / `.claude/` / etc. is left alone, even if it exists
93
+ * on disk. Setting this to `undefined` or an empty set means "no
94
+ * platform/root coverage this run" — historical hashes from earlier
95
+ * runs are preserved via `merge`.
96
+ */
97
+ trackedPaths?: ReadonlySet<string>;
98
+ /**
99
+ * When true, merge `trackedPaths`-derived hashes into the EXISTING manifest
100
+ * instead of replacing it. Used by `handleReinit` "add platform" flow so
101
+ * previously-tracked platforms aren't wiped from the manifest when only
102
+ * a new platform's writes are recorded. Defaults to false (replace).
103
+ */
104
+ merge?: boolean;
105
+ }
86
106
  /**
87
107
  * Initialize template hashes after init
88
108
  *
89
- * Scans all template directories and computes hashes for files.
90
- * This should be called at the end of `trellis init` to enable
91
- * modification detection on subsequent updates.
109
+ * The platform/root section of the manifest comes from `trackedPaths` —
110
+ * the set of POSIX paths that `writeFile` actually wrote (or owned with
111
+ * byte-identical content) during this init run. Avoids the historical bug
112
+ * where a blind directory walk of `.codex/` / `.claude/` swept up
113
+ * user-owned runtime data (chat history, session JSONLs).
92
114
  *
93
- * @param cwd - Working directory
94
- * @returns Number of files hashed
115
+ * `.trellis/` is still walked recursively (with `EXCLUDE_FROM_HASH`) because
116
+ * uninstall removes `.trellis/` wholesale via `rm -rf` regardless of manifest
117
+ * content — accuracy there doesn't affect data-loss, only `trellis update`
118
+ * 3-way-merge fidelity (preserved by the existing walk).
119
+ *
120
+ * @returns Number of files hashed in the final manifest.
95
121
  */
96
- export declare function initializeHashes(cwd: string): number;
122
+ export declare function initializeHashes(cwd: string, options?: InitializeHashesOptions): number;
97
123
  //# sourceMappingURL=template-hash.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"template-hash.d.ts","sourceRoot":"","sources":["../../src/utils/template-hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAe5D;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGnD;AAoBD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CA6BtD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAOpE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAQ1E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAU1E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAKlE;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,IAAI,CASN;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,cAAc,GACrB,OAAO,CAsBT;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,OAAO,CAST;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EAAE,EACvB,MAAM,EAAE,cAAc,GACrB,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAQtB;AA0ED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAwCpD"}
1
+ {"version":3,"file":"template-hash.d.ts","sourceRoot":"","sources":["../../src/utils/template-hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAe5D;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGnD;AAoBD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CA6BtD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAOpE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAQ1E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAU1E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAKlE;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,IAAI,CASN;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,cAAc,GACrB,OAAO,CAsBT;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,OAAO,CAST;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EAAE,EACvB,MAAM,EAAE,cAAc,GACrB,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAQtB;AA8DD,oDAAoD;AACpD,MAAM,WAAW,uBAAuB;IACtC;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,uBAA4B,GACpC,MAAM,CAyDR"}
@@ -16,7 +16,6 @@ import { createHash } from "node:crypto";
16
16
  import fs from "node:fs";
17
17
  import path from "node:path";
18
18
  import { DIR_NAMES, FILE_NAMES } from "../constants/paths.js";
19
- import { ALL_MANAGED_DIRS } from "../configurators/index.js";
20
19
  import { toPosix } from "./posix.js";
21
20
  /** File name for storing template hashes */
22
21
  const HASHES_FILE = ".template-hashes.json";
@@ -204,13 +203,7 @@ export function getModificationStatus(cwd, relativePaths, hashes) {
204
203
  return result;
205
204
  }
206
205
  /**
207
- * Directories to scan for template files during init (derived from platform registry)
208
- */
209
- const TEMPLATE_DIRS = ALL_MANAGED_DIRS;
210
- /** Root-level template files written by init and managed by update. */
211
- const TEMPLATE_FILES = [FILE_NAMES.AGENTS];
212
- /**
213
- * Patterns to exclude from hash tracking
206
+ * Patterns to exclude from hash tracking (only applied to the .trellis/ walk).
214
207
  */
215
208
  const EXCLUDE_FROM_HASH = [
216
209
  ".template-hashes.json", // Hash file itself
@@ -241,7 +234,7 @@ function shouldExcludeFromHash(relativePath) {
241
234
  * Returned paths are POSIX-normalized so they can be used directly as
242
235
  * hash dictionary keys regardless of host OS.
243
236
  */
244
- function collectFiles(cwd, dir, relativeTo = "") {
237
+ function collectFiles(cwd, dir) {
245
238
  const fullDir = path.join(cwd, dir);
246
239
  if (!fs.existsSync(fullDir)) {
247
240
  return [];
@@ -254,7 +247,7 @@ function collectFiles(cwd, dir, relativeTo = "") {
254
247
  continue;
255
248
  }
256
249
  if (entry.isDirectory()) {
257
- files.push(...collectFiles(cwd, relativePath, relativeTo));
250
+ files.push(...collectFiles(cwd, relativePath));
258
251
  }
259
252
  else if (entry.isFile()) {
260
253
  files.push(toPosix(relativePath));
@@ -265,23 +258,48 @@ function collectFiles(cwd, dir, relativeTo = "") {
265
258
  /**
266
259
  * Initialize template hashes after init
267
260
  *
268
- * Scans all template directories and computes hashes for files.
269
- * This should be called at the end of `trellis init` to enable
270
- * modification detection on subsequent updates.
261
+ * The platform/root section of the manifest comes from `trackedPaths` —
262
+ * the set of POSIX paths that `writeFile` actually wrote (or owned with
263
+ * byte-identical content) during this init run. Avoids the historical bug
264
+ * where a blind directory walk of `.codex/` / `.claude/` swept up
265
+ * user-owned runtime data (chat history, session JSONLs).
271
266
  *
272
- * @param cwd - Working directory
273
- * @returns Number of files hashed
267
+ * `.trellis/` is still walked recursively (with `EXCLUDE_FROM_HASH`) because
268
+ * uninstall removes `.trellis/` wholesale via `rm -rf` regardless of manifest
269
+ * content — accuracy there doesn't affect data-loss, only `trellis update`
270
+ * 3-way-merge fidelity (preserved by the existing walk).
271
+ *
272
+ * @returns Number of files hashed in the final manifest.
274
273
  */
275
- export function initializeHashes(cwd) {
276
- const hashes = {};
277
- for (const relativePath of TEMPLATE_FILES) {
278
- if (shouldExcludeFromHash(relativePath)) {
279
- continue;
274
+ export function initializeHashes(cwd, options = {}) {
275
+ const { trackedPaths, merge = false } = options;
276
+ const hashes = merge ? loadHashes(cwd) : {};
277
+ // Platform + root files: hash only paths actually written this run.
278
+ if (trackedPaths) {
279
+ for (const relativePath of trackedPaths) {
280
+ // `.trellis/` paths are handled by the walk below — don't double-track.
281
+ if (relativePath.startsWith(".trellis/") || relativePath === ".trellis") {
282
+ continue;
283
+ }
284
+ const fullPath = path.join(cwd, ...relativePath.split("/"));
285
+ if (!fs.existsSync(fullPath))
286
+ continue;
287
+ try {
288
+ const content = fs.readFileSync(fullPath, "utf-8");
289
+ hashes[toPosix(relativePath)] = computeHash(content);
290
+ }
291
+ catch {
292
+ // Skip files that can't be read (binary, etc.)
293
+ }
280
294
  }
295
+ }
296
+ // .trellis/ workflow tree: still walked recursively. Accuracy here is for
297
+ // `trellis update`'s 3-way merge of workflow.md / config.yaml / scripts;
298
+ // uninstall removes .trellis/ wholesale so it does not matter for the
299
+ // data-loss bug this contract addresses.
300
+ const files = collectFiles(cwd, ".trellis");
301
+ for (const relativePath of files) {
281
302
  const fullPath = path.join(cwd, relativePath);
282
- if (!fs.existsSync(fullPath)) {
283
- continue;
284
- }
285
303
  try {
286
304
  const content = fs.readFileSync(fullPath, "utf-8");
287
305
  hashes[relativePath] = computeHash(content);
@@ -290,19 +308,23 @@ export function initializeHashes(cwd) {
290
308
  // Skip files that can't be read (binary, etc.)
291
309
  }
292
310
  }
293
- // Collect all template files
294
- for (const dir of TEMPLATE_DIRS) {
295
- const files = collectFiles(cwd, dir);
296
- for (const relativePath of files) {
297
- // `relativePath` is POSIX (collectFiles normalizes); reconstruct an
298
- // OS-native path for the actual fs read.
311
+ // Backwards-compat path: when `trackedPaths` is not supplied (callers that
312
+ // haven't been updated yet), keep tracking root-level files that exist on
313
+ // disk. This preserves the legacy behavior for tests / scripts that don't
314
+ // go through the new recording flow.
315
+ if (!trackedPaths) {
316
+ for (const relativePath of [FILE_NAMES.AGENTS]) {
317
+ if (shouldExcludeFromHash(relativePath))
318
+ continue;
299
319
  const fullPath = path.join(cwd, relativePath);
320
+ if (!fs.existsSync(fullPath))
321
+ continue;
300
322
  try {
301
323
  const content = fs.readFileSync(fullPath, "utf-8");
302
- hashes[relativePath] = computeHash(content);
324
+ hashes[toPosix(relativePath)] = computeHash(content);
303
325
  }
304
326
  catch {
305
- // Skip files that can't be read (binary, etc.)
327
+ // Skip
306
328
  }
307
329
  }
308
330
  }
@@ -1 +1 @@
1
- {"version":3,"file":"template-hash.js","sourceRoot":"","sources":["../../src/utils/template-hash.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"template-hash.js","sourceRoot":"","sources":["../../src/utils/template-hash.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindfoldhq/trellis",
3
- "version": "0.5.13",
3
+ "version": "0.5.15",
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",
@@ -12,6 +12,31 @@
12
12
  "publishConfig": {
13
13
  "access": "public"
14
14
  },
15
+ "scripts": {
16
+ "build": "pnpm run clean && tsc && pnpm run copy-templates",
17
+ "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
18
+ "copy-templates": "node scripts/copy-templates.js",
19
+ "dev": "tsc --watch",
20
+ "start": "node ./dist/cli/index.js",
21
+ "test": "vitest run",
22
+ "test:watch": "vitest",
23
+ "test:coverage": "vitest run --coverage",
24
+ "lint": "eslint src/ test/",
25
+ "lint:fix": "eslint src/ test/ --fix",
26
+ "format": "prettier --write src/",
27
+ "format:check": "prettier --check src/",
28
+ "typecheck": "tsc --noEmit",
29
+ "lint:py": "basedpyright",
30
+ "lint:all": "pnpm lint && pnpm lint:py",
31
+ "prepublishOnly": "pnpm test && pnpm run build && cp ../../README.md ../../LICENSE .",
32
+ "release": "node scripts/check-manifest-continuity.js && pnpm test && git add -A -- ':!docs-site' && (git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates') && pnpm version --no-git-tag-version patch && V=$(node -p \"require('./package.json').version\") && git add package.json && git commit -m \"$V\" && git tag \"v$V\" && git push origin main --tags",
33
+ "release:minor": "node scripts/check-manifest-continuity.js && pnpm test && git add -A -- ':!docs-site' && (git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates') && pnpm version --no-git-tag-version minor && V=$(node -p \"require('./package.json').version\") && git add package.json && git commit -m \"$V\" && git tag \"v$V\" && git push origin main --tags",
34
+ "release:major": "node scripts/check-manifest-continuity.js && pnpm test && git add -A -- ':!docs-site' && (git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates') && pnpm version --no-git-tag-version major && V=$(node -p \"require('./package.json').version\") && git add package.json && git commit -m \"$V\" && git tag \"v$V\" && git push origin main --tags",
35
+ "release:beta": "node scripts/check-manifest-continuity.js && node scripts/check-docs-changelog.js --type beta && pnpm test && git add -A -- ':!docs-site' && (git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates') && pnpm version --no-git-tag-version prerelease --preid beta && V=$(node -p \"require('./package.json').version\") && git add package.json && git commit -m \"$V\" && git tag \"v$V\" && git push origin HEAD --tags",
36
+ "release:rc": "node scripts/check-manifest-continuity.js && node scripts/check-docs-changelog.js --type rc && pnpm test && git add -A -- ':!docs-site' && (git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates') && pnpm version --no-git-tag-version prerelease --preid rc && V=$(node -p \"require('./package.json').version\") && git add package.json && git commit -m \"$V\" && git tag \"v$V\" && git push origin HEAD --tags",
37
+ "release:promote": "node scripts/check-manifest-continuity.js && node scripts/check-docs-changelog.js --type promote && pnpm test && git add -A -- ':!docs-site' && (git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates') && pnpm version --no-git-tag-version \"$(node -p \"require('./package.json').version.replace(/-.*/, '')\")\" && V=$(node -p \"require('./package.json').version\") && git add package.json && git commit -m \"$V\" && git tag \"v$V\" && git push origin main --tags",
38
+ "manifest": "node scripts/create-manifest.js"
39
+ },
15
40
  "keywords": [
16
41
  "ai",
17
42
  "workflow",
@@ -59,29 +84,5 @@
59
84
  "repository": {
60
85
  "type": "git",
61
86
  "url": "https://github.com/mindfold-ai/trellis.git"
62
- },
63
- "scripts": {
64
- "build": "pnpm run clean && tsc && pnpm run copy-templates",
65
- "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
66
- "copy-templates": "node scripts/copy-templates.js",
67
- "dev": "tsc --watch",
68
- "start": "node ./dist/cli/index.js",
69
- "test": "vitest run",
70
- "test:watch": "vitest",
71
- "test:coverage": "vitest run --coverage",
72
- "lint": "eslint src/ test/",
73
- "lint:fix": "eslint src/ test/ --fix",
74
- "format": "prettier --write src/",
75
- "format:check": "prettier --check src/",
76
- "typecheck": "tsc --noEmit",
77
- "lint:py": "basedpyright",
78
- "lint:all": "pnpm lint && pnpm lint:py",
79
- "release": "node scripts/check-manifest-continuity.js && pnpm test && git add -A -- ':!docs-site' && (git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates') && pnpm version --no-git-tag-version patch && V=$(node -p \"require('./package.json').version\") && git add package.json && git commit -m \"$V\" && git tag \"v$V\" && git push origin main --tags",
80
- "release:minor": "node scripts/check-manifest-continuity.js && pnpm test && git add -A -- ':!docs-site' && (git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates') && pnpm version --no-git-tag-version minor && V=$(node -p \"require('./package.json').version\") && git add package.json && git commit -m \"$V\" && git tag \"v$V\" && git push origin main --tags",
81
- "release:major": "node scripts/check-manifest-continuity.js && pnpm test && git add -A -- ':!docs-site' && (git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates') && pnpm version --no-git-tag-version major && V=$(node -p \"require('./package.json').version\") && git add package.json && git commit -m \"$V\" && git tag \"v$V\" && git push origin main --tags",
82
- "release:beta": "node scripts/check-manifest-continuity.js && node scripts/check-docs-changelog.js --type beta && pnpm test && git add -A -- ':!docs-site' && (git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates') && pnpm version --no-git-tag-version prerelease --preid beta && V=$(node -p \"require('./package.json').version\") && git add package.json && git commit -m \"$V\" && git tag \"v$V\" && git push origin HEAD --tags",
83
- "release:rc": "node scripts/check-manifest-continuity.js && node scripts/check-docs-changelog.js --type rc && pnpm test && git add -A -- ':!docs-site' && (git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates') && pnpm version --no-git-tag-version prerelease --preid rc && V=$(node -p \"require('./package.json').version\") && git add package.json && git commit -m \"$V\" && git tag \"v$V\" && git push origin HEAD --tags",
84
- "release:promote": "node scripts/check-manifest-continuity.js && node scripts/check-docs-changelog.js --type promote && pnpm test && git add -A -- ':!docs-site' && (git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates') && pnpm version --no-git-tag-version \"$(node -p \"require('./package.json').version.replace(/-.*/, '')\")\" && V=$(node -p \"require('./package.json').version\") && git add package.json && git commit -m \"$V\" && git tag \"v$V\" && git push origin main --tags",
85
- "manifest": "node scripts/create-manifest.js"
86
87
  }
87
- }
88
+ }