@primitive.ai/prim 0.1.0-alpha.92 → 0.1.0-alpha.94

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 (42) hide show
  1. package/README.md +84 -10
  2. package/SKILL.md +5 -2
  3. package/dist/{chunk-67VNLLBN.js → chunk-2GP5UFV7.js} +1 -0
  4. package/dist/{chunk-26P57LAR.js → chunk-AXQQMX2U.js} +203 -9
  5. package/dist/{chunk-M6RIJVRE.js → chunk-DSWT6BCC.js} +78 -4
  6. package/dist/{chunk-FBAYCS3X.js → chunk-DXJQR4QI.js} +150 -38
  7. package/dist/chunk-FXF4JWK2.js +162 -0
  8. package/dist/{chunk-PCVGBE5B.js → chunk-G2VMA2QO.js} +2 -1
  9. package/dist/{chunk-NAHHFSLH.js → chunk-ICM2XCXS.js} +2 -2
  10. package/dist/{chunk-5HRR4AOR.js → chunk-IMK4JKTA.js} +1 -1
  11. package/dist/{chunk-OAAP2MY6.js → chunk-K7D2EYBS.js} +2 -2
  12. package/dist/{chunk-ADUTW66W.js → chunk-O7YAW7G6.js} +6 -6
  13. package/dist/{chunk-5AFRMOPX.js → chunk-OH3EZXYX.js} +1 -1
  14. package/dist/{chunk-KFXF2V5G.js → chunk-OTHKG76J.js} +1 -1
  15. package/dist/chunk-OYHYCK4K.js +13 -0
  16. package/dist/{chunk-FKXFUUWJ.js → chunk-TYAHC25F.js} +1 -1
  17. package/dist/{chunk-5GYQ4J3D.js → chunk-UKUAAAXE.js} +2 -2
  18. package/dist/{chunk-LGGMJYY4.js → chunk-WUXFLE7X.js} +720 -369
  19. package/dist/{chunk-WX52U7Z2.js → chunk-ZU563PQI.js} +58 -2
  20. package/dist/daemon/server.js +372 -123
  21. package/dist/hook-runtime/daemon/server.js +372 -123
  22. package/dist/hook-runtime/hooks/post-commit.js +192 -58
  23. package/dist/hook-runtime/hooks/post-rewrite.js +58 -40
  24. package/dist/hook-runtime/hooks/post-tool-use.js +150 -67
  25. package/dist/hook-runtime/hooks/pre-tool-use.js +87 -15
  26. package/dist/hook-runtime/hooks/prim-hook.js +197 -107
  27. package/dist/hook-runtime/hooks/session-end.js +53 -5
  28. package/dist/hook-runtime/hooks/session-start.js +880 -280
  29. package/dist/hook-runtime/index.js +4008 -2438
  30. package/dist/hook-runtime/statusline-main.js +23 -1
  31. package/dist/hooks/post-commit.js +15 -8
  32. package/dist/hooks/post-rewrite.js +11 -8
  33. package/dist/hooks/post-tool-use.js +13 -15
  34. package/dist/hooks/pre-commit.js +4 -4
  35. package/dist/hooks/pre-tool-use.js +10 -12
  36. package/dist/hooks/prim-hook.js +17 -14
  37. package/dist/hooks/session-end.js +4 -4
  38. package/dist/hooks/session-start.js +35 -45
  39. package/dist/index.js +1401 -620
  40. package/dist/statusline-main.js +23 -1
  41. package/package.json +1 -1
  42. package/dist/chunk-BTNNEH2W.js +0 -79
@@ -52,9 +52,9 @@ var require_ucs2length = __commonJS({
52
52
  });
53
53
 
54
54
  // src/hooks/post-commit.ts
55
- import { execFileSync as execFileSync4, spawn } from "child_process";
56
- import { lstatSync as lstatSync3, readFileSync as readFileSync9 } from "fs";
57
- import { basename as basename2, dirname as dirname8, isAbsolute as isAbsolute4, join as join10 } from "path";
55
+ import { execFileSync as execFileSync5, spawn } from "child_process";
56
+ import { lstatSync as lstatSync3, readFileSync as readFileSync11 } from "fs";
57
+ import { basename as basename3, dirname as dirname10, isAbsolute as isAbsolute4, join as join12 } from "path";
58
58
  import { fileURLToPath } from "url";
59
59
 
60
60
  // src/binding.ts
@@ -371,16 +371,16 @@ function resolveOrg(args) {
371
371
  import {
372
372
  appendFileSync,
373
373
  closeSync as closeSync2,
374
- existsSync as existsSync4,
374
+ existsSync as existsSync5,
375
375
  fstatSync,
376
376
  mkdirSync as mkdirSync4,
377
377
  openSync as openSync2,
378
378
  opendirSync,
379
- readFileSync as readFileSync5,
379
+ readFileSync as readFileSync6,
380
380
  readSync,
381
- readdirSync
381
+ readdirSync as readdirSync2
382
382
  } from "fs";
383
- import { dirname as dirname5, join as join6 } from "path";
383
+ import { dirname as dirname6, join as join7 } from "path";
384
384
 
385
385
  // src/client.ts
386
386
  import { createHash as createHash2 } from "crypto";
@@ -401,6 +401,69 @@ import {
401
401
  writeFileSync
402
402
  } from "fs";
403
403
  import { dirname as dirname2 } from "path";
404
+ var DEFAULT_FILE_MODE = 438;
405
+ function syncDirectory(path) {
406
+ const fd = openSync(path, constants.O_RDONLY);
407
+ try {
408
+ fsyncSync(fd);
409
+ } finally {
410
+ closeSync(fd);
411
+ }
412
+ }
413
+ function syncCreatedParentChain(firstCreatedParent, parent) {
414
+ const createdDirectories = [];
415
+ let current = parent;
416
+ while (current !== firstCreatedParent) {
417
+ createdDirectories.push(current);
418
+ const next = dirname2(current);
419
+ if (next === current) {
420
+ throw new Error("recursive mkdir returned a path outside the target parent chain");
421
+ }
422
+ current = next;
423
+ }
424
+ createdDirectories.push(firstCreatedParent);
425
+ syncDirectory(dirname2(firstCreatedParent));
426
+ for (const directory of createdDirectories.reverse().slice(0, -1)) {
427
+ syncDirectory(directory);
428
+ }
429
+ }
430
+ function ensureDurableDirectory(path, mode) {
431
+ const firstCreatedParent = mkdirSync(path, { recursive: true, mode });
432
+ if (firstCreatedParent) {
433
+ syncCreatedParentChain(firstCreatedParent, path);
434
+ }
435
+ }
436
+ function atomicWriteFile(target, content, options = {}) {
437
+ const parent = dirname2(target);
438
+ if (options.ensureParent) {
439
+ ensureDurableDirectory(parent);
440
+ }
441
+ const temporaryPath = `${target}.${randomUUID()}.tmp`;
442
+ let temporaryCreated = false;
443
+ try {
444
+ const flags = constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW;
445
+ const fd = openSync(temporaryPath, flags, options.mode ?? DEFAULT_FILE_MODE);
446
+ temporaryCreated = true;
447
+ try {
448
+ if (options.mode !== void 0) fchmodSync(fd, options.mode);
449
+ writeFileSync(fd, content);
450
+ fsyncSync(fd);
451
+ } finally {
452
+ closeSync(fd);
453
+ }
454
+ options.validate?.(temporaryPath);
455
+ renameSync(temporaryPath, target);
456
+ syncDirectory(parent);
457
+ } catch (error) {
458
+ if (temporaryCreated) {
459
+ try {
460
+ rmSync(temporaryPath, { force: true });
461
+ } catch {
462
+ }
463
+ }
464
+ throw error;
465
+ }
466
+ }
404
467
 
405
468
  // src/lib/file-lock.ts
406
469
  import { randomBytes } from "crypto";
@@ -418,8 +481,19 @@ function getSiteUrlForEnvironment(primApiUrl) {
418
481
  }
419
482
  var CLI_MANAGEMENT_RESPONSE_MAX_BYTES = 2 * 1024 * 1024;
420
483
 
484
+ // src/drain-progress.ts
485
+ import {
486
+ chmodSync as chmodSync2,
487
+ existsSync as existsSync4,
488
+ readFileSync as readFileSync5,
489
+ readdirSync,
490
+ rmSync as rmSync4,
491
+ rmdirSync
492
+ } from "fs";
493
+ import { basename, dirname as dirname5, join as join6 } from "path";
494
+
421
495
  // src/journal.ts
422
- var JOURNAL_DIR = join6(primConfigDirectory(), "moves");
496
+ var JOURNAL_DIR = join7(primConfigDirectory(), "moves");
423
497
  var UNBOUND_BUCKET = "_unbound";
424
498
  var JOURNAL_BASENAME = "journal.ndjson";
425
499
  var JOURNAL_STATS_SAMPLE_BYTES = 64 * 1024;
@@ -431,15 +505,15 @@ function envSlug(apiUrl) {
431
505
  return slug;
432
506
  }
433
507
  function currentEnvDir() {
434
- return join6(JOURNAL_DIR, envSlug(getSiteUrl()));
508
+ return join7(JOURNAL_DIR, envSlug(getSiteUrl()));
435
509
  }
436
510
  var DIR_MODE = 448;
437
511
  var FILE_MODE = 384;
438
512
  var SAFE_BUCKET = /^[A-Za-z0-9_-]+$/;
439
513
  var RESERVED_BUCKETS = /* @__PURE__ */ new Set([UNBOUND_BUCKET, "_legacy"]);
440
514
  function appendMoveToPath(path, move) {
441
- const dir = dirname5(path);
442
- if (!existsSync4(dir)) {
515
+ const dir = dirname6(path);
516
+ if (!existsSync5(dir)) {
443
517
  mkdirSync4(dir, { recursive: true, mode: DIR_MODE });
444
518
  }
445
519
  appendFileSync(path, `${JSON.stringify(move)}
@@ -447,10 +521,10 @@ function appendMoveToPath(path, move) {
447
521
  }
448
522
  function bucketDir(orgId) {
449
523
  const safe = orgId !== void 0 && SAFE_BUCKET.test(orgId) && !RESERVED_BUCKETS.has(orgId);
450
- return join6(currentEnvDir(), safe ? orgId : UNBOUND_BUCKET);
524
+ return join7(currentEnvDir(), safe ? orgId : UNBOUND_BUCKET);
451
525
  }
452
526
  function journalPath(orgId) {
453
- return join6(bucketDir(orgId), JOURNAL_BASENAME);
527
+ return join7(bucketDir(orgId), JOURNAL_BASENAME);
454
528
  }
455
529
  function appendMove(move, orgId) {
456
530
  appendMoveToPath(journalPath(orgId), move);
@@ -459,15 +533,15 @@ var FLUSHING_PREFIX = `${JOURNAL_BASENAME}.flushing.`;
459
533
 
460
534
  // src/lib/activation.ts
461
535
  import { execFileSync as execFileSync2 } from "child_process";
462
- import { existsSync as existsSync5, readFileSync as readFileSync6 } from "fs";
536
+ import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
463
537
  import { homedir as homedir2 } from "os";
464
- import { join as join7 } from "path";
538
+ import { join as join8 } from "path";
465
539
 
466
540
  // src/lib/git.ts
467
541
  import { execFileSync } from "child_process";
468
542
  import { createHash as createHash3 } from "crypto";
469
543
  import { lstatSync, realpathSync } from "fs";
470
- import { basename, dirname as dirname6, isAbsolute as isAbsolute2, relative, resolve as resolve2, sep } from "path";
544
+ import { basename as basename2, dirname as dirname7, isAbsolute as isAbsolute2, relative, resolve as resolve2, sep } from "path";
471
545
  var GIT_TIMEOUT_MS = 1e3;
472
546
  var GITHUB_OWNER_PATTERN = /^(?![A-Za-z0-9-]*--)[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/u;
473
547
  var GITHUB_REPOSITORY_PATTERN = /^[A-Za-z0-9._-]{1,100}$/u;
@@ -615,10 +689,10 @@ function hasProjectPrimInstall(cwd) {
615
689
  const root = gitToplevel(cwd);
616
690
  if (root === null || root === homedir2()) return false;
617
691
  for (const rel of PROJECT_INSTALL_FILES) {
618
- const path = join7(root, rel);
619
- if (existsSync5(path)) {
692
+ const path = join8(root, rel);
693
+ if (existsSync6(path)) {
620
694
  try {
621
- const content = readFileSync6(path, "utf-8");
695
+ const content = readFileSync7(path, "utf-8");
622
696
  if (PRIM_HOOK_BINS.some((bin) => content.includes(bin))) return true;
623
697
  } catch {
624
698
  }
@@ -18704,26 +18778,84 @@ function cachedCollectScopeAdmits(cwd, facts) {
18704
18778
  );
18705
18779
  }
18706
18780
 
18707
- // src/lib/workspace-id.ts
18781
+ // src/lib/commit-heartbeat.ts
18708
18782
  import { execFileSync as execFileSync3 } from "child_process";
18783
+ import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, readdirSync as readdirSync3, unlinkSync } from "fs";
18784
+ import { dirname as dirname8, join as join9, resolve as resolve3 } from "path";
18785
+ var FIRED_DIR = "prim/post-commit-fired";
18786
+ var GIT_TIMEOUT_MS3 = 1e3;
18787
+ var MAX_STAMP_BYTES = 1024;
18788
+ var MAX_FIRED_STAMPS = 256;
18789
+ var PRUNE_SLACK = 64;
18790
+ var FULL_SHA_RE = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/u;
18791
+ function gitPath(cwd, relative2) {
18792
+ const value = execFileSync3("git", ["rev-parse", "--git-path", relative2], {
18793
+ cwd,
18794
+ encoding: "utf8",
18795
+ stdio: ["ignore", "pipe", "ignore"],
18796
+ timeout: GIT_TIMEOUT_MS3
18797
+ }).replace(/\r?\n$/u, "");
18798
+ if (value === "" || /[\0\r\n]/u.test(value)) throw new Error("Git returned an unsafe path");
18799
+ return resolve3(cwd, value);
18800
+ }
18801
+ function ensurePrivateParent(path) {
18802
+ mkdirSync5(dirname8(dirname8(path)), { recursive: true, mode: 448 });
18803
+ mkdirSync5(dirname8(path), { recursive: true, mode: 448 });
18804
+ }
18805
+ function writeStamp(path, at) {
18806
+ ensurePrivateParent(path);
18807
+ atomicWriteFile(path, `${JSON.stringify({ at })}
18808
+ `, { mode: 384 });
18809
+ }
18810
+ function readStampAt(path) {
18811
+ try {
18812
+ const raw = readFileSync8(path, "utf8");
18813
+ if (raw.length > MAX_STAMP_BYTES) return void 0;
18814
+ const parsed = JSON.parse(raw);
18815
+ return typeof parsed.at === "number" && Number.isSafeInteger(parsed.at) && parsed.at > 0 ? parsed.at : void 0;
18816
+ } catch {
18817
+ return void 0;
18818
+ }
18819
+ }
18820
+ function recordPostCommitFired(cwd, sha, now = Date.now()) {
18821
+ if (!sha || !FULL_SHA_RE.test(sha)) return;
18822
+ try {
18823
+ const dir = gitPath(cwd, FIRED_DIR);
18824
+ writeStamp(join9(dir, sha), now);
18825
+ const names = readdirSync3(dir).filter((name) => FULL_SHA_RE.test(name));
18826
+ if (names.length <= MAX_FIRED_STAMPS + PRUNE_SLACK) return;
18827
+ const stale = names.map((name) => ({ name, at: readStampAt(join9(dir, name)) ?? 0 })).sort((left, right) => right.at - left.at || left.name.localeCompare(right.name)).slice(MAX_FIRED_STAMPS);
18828
+ for (const { name } of stale) unlinkSync(join9(dir, name));
18829
+ } catch {
18830
+ }
18831
+ }
18832
+
18833
+ // src/lib/unattended.ts
18834
+ var UNATTENDED_ENV = "PRIM_UNATTENDED";
18835
+ function unattendedEnv(env = process.env) {
18836
+ return { ...env, [UNATTENDED_ENV]: "1" };
18837
+ }
18838
+
18839
+ // src/lib/workspace-id.ts
18840
+ import { execFileSync as execFileSync4 } from "child_process";
18709
18841
  import { randomUUID as randomUUID2 } from "crypto";
18710
18842
  import {
18711
18843
  constants as constants2,
18712
- chmodSync as chmodSync2,
18844
+ chmodSync as chmodSync3,
18713
18845
  closeSync as closeSync3,
18714
18846
  fchmodSync as fchmodSync2,
18715
18847
  fsyncSync as fsyncSync2,
18716
18848
  linkSync,
18717
18849
  lstatSync as lstatSync2,
18718
- mkdirSync as mkdirSync5,
18850
+ mkdirSync as mkdirSync6,
18719
18851
  openSync as openSync3,
18720
- readFileSync as readFileSync7,
18852
+ readFileSync as readFileSync9,
18721
18853
  statSync as statSync2,
18722
- unlinkSync,
18854
+ unlinkSync as unlinkSync2,
18723
18855
  writeFileSync as writeFileSync3
18724
18856
  } from "fs";
18725
- import { dirname as dirname7, isAbsolute as isAbsolute3, join as join8, resolve as resolve3 } from "path";
18726
- var WORKSPACE_ID_RELATIVE_PATH = join8("prim", "workspace-id");
18857
+ import { dirname as dirname9, isAbsolute as isAbsolute3, join as join10, resolve as resolve4 } from "path";
18858
+ var WORKSPACE_ID_RELATIVE_PATH = join10("prim", "workspace-id");
18727
18859
  var MAX_ANCESTORS = 64;
18728
18860
  var MAX_GIT_FILE_BYTES = 4096;
18729
18861
  var MAX_ID_FILE_BYTES = 128;
@@ -18751,7 +18883,7 @@ function resolveWorkspaceIdPath(cwd) {
18751
18883
  if (fromFilesystem) return { status: "resolved", path: fromFilesystem };
18752
18884
  }
18753
18885
  try {
18754
- const output = execFileSync3(
18886
+ const output = execFileSync4(
18755
18887
  "git",
18756
18888
  ["rev-parse", "--is-inside-work-tree", "--git-path", WORKSPACE_ID_RELATIVE_PATH],
18757
18889
  {
@@ -18763,13 +18895,13 @@ function resolveWorkspaceIdPath(cwd) {
18763
18895
  windowsHide: true
18764
18896
  }
18765
18897
  );
18766
- const [insideWorktree, gitPath, ...extra] = output.trim().split(/\r?\n/);
18767
- if (insideWorktree !== "true" || !gitPath || extra.length > 0 || gitPath.includes("\0")) {
18898
+ const [insideWorktree, gitPath2, ...extra] = output.trim().split(/\r?\n/);
18899
+ if (insideWorktree !== "true" || !gitPath2 || extra.length > 0 || gitPath2.includes("\0")) {
18768
18900
  return { status: "not_git" };
18769
18901
  }
18770
18902
  return {
18771
18903
  status: "resolved",
18772
- path: isAbsolute3(gitPath) ? resolve3(gitPath) : resolve3(cwd, gitPath)
18904
+ path: isAbsolute3(gitPath2) ? resolve4(gitPath2) : resolve4(cwd, gitPath2)
18773
18905
  };
18774
18906
  } catch (error) {
18775
18907
  const code = errorCode(error);
@@ -18780,21 +18912,21 @@ function resolveWorkspaceIdPath(cwd) {
18780
18912
  }
18781
18913
  }
18782
18914
  function resolveFromFilesystem(cwd) {
18783
- let current = resolve3(cwd);
18915
+ let current = resolve4(cwd);
18784
18916
  for (let depth = 0; depth < MAX_ANCESTORS; depth += 1) {
18785
- const dotGit = join8(current, ".git");
18917
+ const dotGit = join10(current, ".git");
18786
18918
  try {
18787
18919
  const stat = lstatSync2(dotGit);
18788
18920
  if (stat.isDirectory() && isGitDirectory(dotGit)) {
18789
- return join8(dotGit, WORKSPACE_ID_RELATIVE_PATH);
18921
+ return join10(dotGit, WORKSPACE_ID_RELATIVE_PATH);
18790
18922
  }
18791
18923
  if (stat.isFile() && stat.size <= MAX_GIT_FILE_BYTES) {
18792
- const contents = readFileSync7(dotGit, "utf8");
18924
+ const contents = readFileSync9(dotGit, "utf8");
18793
18925
  const match = /^gitdir: (.+?)(?:\r?\n)?$/.exec(contents);
18794
18926
  if (match?.[1]) {
18795
- const gitDirectory = isAbsolute3(match[1]) ? resolve3(match[1]) : resolve3(current, match[1]);
18927
+ const gitDirectory = isAbsolute3(match[1]) ? resolve4(match[1]) : resolve4(current, match[1]);
18796
18928
  if (isGitDirectory(gitDirectory)) {
18797
- return join8(gitDirectory, WORKSPACE_ID_RELATIVE_PATH);
18929
+ return join10(gitDirectory, WORKSPACE_ID_RELATIVE_PATH);
18798
18930
  }
18799
18931
  }
18800
18932
  }
@@ -18805,7 +18937,7 @@ function resolveFromFilesystem(cwd) {
18805
18937
  return null;
18806
18938
  }
18807
18939
  }
18808
- const parent = dirname7(current);
18940
+ const parent = dirname9(current);
18809
18941
  if (parent === current) break;
18810
18942
  current = parent;
18811
18943
  }
@@ -18813,7 +18945,7 @@ function resolveFromFilesystem(cwd) {
18813
18945
  }
18814
18946
  function isGitDirectory(path) {
18815
18947
  try {
18816
- return statSync2(join8(path, "HEAD")).isFile();
18948
+ return statSync2(join10(path, "HEAD")).isFile();
18817
18949
  } catch {
18818
18950
  return false;
18819
18951
  }
@@ -18832,7 +18964,7 @@ function inspectPath(path) {
18832
18964
  return { status: "corrupt", path, reason: "invalid_content" };
18833
18965
  }
18834
18966
  try {
18835
- const contents = readFileSync7(path, "utf8");
18967
+ const contents = readFileSync9(path, "utf8");
18836
18968
  const workspaceId = contents.endsWith("\n") ? contents.slice(0, -1) : contents;
18837
18969
  if ((contents === workspaceId || contents === `${workspaceId}
18838
18970
  `) && isCanonicalWorkspaceId(workspaceId)) {
@@ -18849,14 +18981,14 @@ function inspectPath(path) {
18849
18981
  }
18850
18982
  }
18851
18983
  function createWorkspaceId(path) {
18852
- const parent = dirname7(path);
18984
+ const parent = dirname9(path);
18853
18985
  const workspaceId = randomUUID2();
18854
- const temporaryPath = join8(parent, `.workspace-id-${process.pid}-${randomUUID2()}.tmp`);
18986
+ const temporaryPath = join10(parent, `.workspace-id-${process.pid}-${randomUUID2()}.tmp`);
18855
18987
  let temporaryCreated = false;
18856
18988
  let publishing = false;
18857
18989
  try {
18858
- mkdirSync5(parent, { recursive: true, mode: 448 });
18859
- chmodSync2(parent, 448);
18990
+ mkdirSync6(parent, { recursive: true, mode: 448 });
18991
+ chmodSync3(parent, 448);
18860
18992
  const fd = openSync3(
18861
18993
  temporaryPath,
18862
18994
  constants2.O_CREAT | constants2.O_EXCL | constants2.O_WRONLY,
@@ -18885,7 +19017,7 @@ function createWorkspaceId(path) {
18885
19017
  } finally {
18886
19018
  if (temporaryCreated) {
18887
19019
  try {
18888
- unlinkSync(temporaryPath);
19020
+ unlinkSync2(temporaryPath);
18889
19021
  } catch {
18890
19022
  }
18891
19023
  }
@@ -18920,8 +19052,8 @@ var AGENT_ENVELOPE_VERSION = 3;
18920
19052
  var ENVELOPE_VERSION = LEGACY_ENVELOPE_VERSION;
18921
19053
 
18922
19054
  // src/hooks/redact.ts
18923
- import { existsSync as existsSync6, readFileSync as readFileSync8, statSync as statSync3 } from "fs";
18924
- import { join as join9 } from "path";
19055
+ import { existsSync as existsSync7, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
19056
+ import { join as join11 } from "path";
18925
19057
  import { Worker } from "worker_threads";
18926
19058
  var USER_HOME_RULES = [
18927
19059
  {
@@ -19097,15 +19229,15 @@ function toCommitMove(commit, cliVersion, cwd, context = {}) {
19097
19229
  }
19098
19230
 
19099
19231
  // src/hooks/post-commit.ts
19100
- var here = dirname8(fileURLToPath(import.meta.url));
19101
- var GIT_TIMEOUT_MS3 = 1e3;
19102
- var FULL_SHA_RE = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/u;
19232
+ var here = dirname10(fileURLToPath(import.meta.url));
19233
+ var GIT_TIMEOUT_MS4 = 1e3;
19234
+ var FULL_SHA_RE2 = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/u;
19103
19235
  var OBSERVATION_MARKER_RE = /^prim-post-commit-observed\.[A-Za-z0-9]+$/u;
19104
19236
  var MAX_OBSERVATION_MARKER_AGE_MS = 10 * 60 * 1e3;
19105
19237
  var MAX_OBSERVATION_MARKER_FUTURE_SKEW_MS = 5e3;
19106
19238
  function capturedAtFromLauncher(env = process.env, now = Date.now()) {
19107
19239
  const path = env.PRIM_COMMIT_OBSERVED_FILE;
19108
- if (!path || !isAbsolute4(path) || !OBSERVATION_MARKER_RE.test(basename2(path))) return;
19240
+ if (!path || !isAbsolute4(path) || !OBSERVATION_MARKER_RE.test(basename3(path))) return;
19109
19241
  try {
19110
19242
  const stat = lstatSync3(path);
19111
19243
  const capturedAt = Math.trunc(stat.mtimeMs);
@@ -19120,10 +19252,10 @@ function capturedAtFromLauncher(env = process.env, now = Date.now()) {
19120
19252
  }
19121
19253
  function gitText(args) {
19122
19254
  try {
19123
- return execFileSync4("git", args, {
19255
+ return execFileSync5("git", args, {
19124
19256
  encoding: "utf-8",
19125
19257
  stdio: ["ignore", "pipe", "ignore"],
19126
- timeout: GIT_TIMEOUT_MS3
19258
+ timeout: GIT_TIMEOUT_MS4
19127
19259
  }).trim();
19128
19260
  } catch {
19129
19261
  return;
@@ -19131,10 +19263,10 @@ function gitText(args) {
19131
19263
  }
19132
19264
  function gitBytes(args) {
19133
19265
  try {
19134
- return execFileSync4("git", args, {
19266
+ return execFileSync5("git", args, {
19135
19267
  encoding: "buffer",
19136
19268
  stdio: ["ignore", "pipe", "ignore"],
19137
- timeout: GIT_TIMEOUT_MS3
19269
+ timeout: GIT_TIMEOUT_MS4
19138
19270
  });
19139
19271
  } catch {
19140
19272
  return;
@@ -19165,7 +19297,7 @@ function parseNulPaths(value) {
19165
19297
  function readCommit() {
19166
19298
  const snapshotProvided = process.env.PRIM_COMMIT_SHA !== void 0;
19167
19299
  const sha = snapshotProvided ? process.env.PRIM_COMMIT_SHA : gitText(["rev-parse", "HEAD"]);
19168
- if (!sha || !FULL_SHA_RE.test(sha)) {
19300
+ if (!sha || !FULL_SHA_RE2.test(sha)) {
19169
19301
  return null;
19170
19302
  }
19171
19303
  const rawBranch = process.env.PRIM_COMMIT_BRANCH !== void 0 ? process.env.PRIM_COMMIT_BRANCH : gitText(["rev-parse", "--abbrev-ref", "HEAD"]);
@@ -19191,21 +19323,23 @@ function readCommit() {
19191
19323
  }
19192
19324
  function resolveCliVersion() {
19193
19325
  try {
19194
- const pkg = JSON.parse(readFileSync9(join10(here, "..", "..", "package.json"), "utf-8"));
19326
+ const pkg = JSON.parse(readFileSync11(join12(here, "..", "..", "package.json"), "utf-8"));
19195
19327
  return pkg.version ?? "unknown";
19196
19328
  } catch {
19197
19329
  return "unknown";
19198
19330
  }
19199
19331
  }
19200
19332
  function spawnBackgroundFlush() {
19201
- const entry = join10(here, "..", "index.js");
19333
+ const entry = join12(here, "..", "index.js");
19202
19334
  spawn(process.execPath, [entry, "moves", "flush"], {
19203
19335
  detached: true,
19204
- stdio: "ignore"
19336
+ stdio: "ignore",
19337
+ env: unattendedEnv()
19205
19338
  }).unref();
19206
19339
  }
19207
19340
  function runPostCommit() {
19208
19341
  const cwd = gitText(["rev-parse", "--show-toplevel"]) ?? process.cwd();
19342
+ recordPostCommitFired(cwd, process.env.PRIM_COMMIT_SHA);
19209
19343
  if (!isRepoActiveForCapture(cwd)) {
19210
19344
  return;
19211
19345
  }