@brainervirus/workit-core 2.2.1 → 2.3.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-core",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "private": false,
5
5
  "description": "Workit shared core — task, policy, evidence, review, decision, worker, and writer state for agentic coding workflows",
6
6
  "keywords": [
package/src/git/rev.ts CHANGED
@@ -214,6 +214,23 @@ export type WorktreeTree = {
214
214
  skipped: Array<{ path: string; size: number; mtimeMs: number }>;
215
215
  };
216
216
 
217
+ /**
218
+ * Copy the index and keep its mtime. Git trusts an entry's cached stat only
219
+ * when the entry is older than the index file ("racy git"). An entry written
220
+ * in the same timestamp tick as the index is re-hashed instead. A plain copy
221
+ * stamps the index with the current time, so a same-size rewrite in that
222
+ * tick would read as clean. That is common on git builds that compare whole
223
+ * seconds (macOS). The copy's mtime is floored one microsecond below the
224
+ * original: an older index only makes more entries racy, which is the safe
225
+ * direction.
226
+ */
227
+ const seedIndex = (from: string, to: string): void => {
228
+ fs.copyFileSync(from, to);
229
+ const { atimeNs, mtimeNs } = fs.statSync(from, { bigint: true });
230
+ const seconds = (ns: bigint): number => (Number(ns / 1000n) - 1) / 1e6;
231
+ fs.utimesSync(to, seconds(atimeNs), seconds(mtimeNs));
232
+ };
233
+
217
234
  /**
218
235
  * The tree the worktree would commit right now, including unstaged and
219
236
  * untracked (non-ignored) files. Built in a throwaway index
@@ -241,7 +258,7 @@ export function worktreeTree(
241
258
  const tempIndex = path.join(scratch, "index");
242
259
  // Seeding from the real index keeps git's stat cache, so `add -A` only
243
260
  // rehashes files that actually changed.
244
- if (fs.existsSync(indexPath)) fs.copyFileSync(indexPath, tempIndex);
261
+ if (fs.existsSync(indexPath)) seedIndex(indexPath, tempIndex);
245
262
  const env = { ...process.env, GIT_INDEX_FILE: tempIndex };
246
263
  const untracked = git(top, ["ls-files", "--others", "--exclude-standard", "-z"], {
247
264
  env,