@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
@@ -597,6 +597,27 @@ function decisionIngestionStatus(cwd) {
597
597
  return isRepoActiveForCapture(cwd) ? "enabled" : "disabled";
598
598
  }
599
599
 
600
+ // src/lib/delivery-backlog.ts
601
+ var MS_PER_SECOND = 1e3;
602
+ var MS_PER_MINUTE = 60 * MS_PER_SECOND;
603
+ var MS_PER_HOUR = 60 * MS_PER_MINUTE;
604
+ var MS_PER_DAY = 24 * MS_PER_HOUR;
605
+ function isNonNegativeInteger(value) {
606
+ return typeof value === "number" && Number.isInteger(value) && value >= 0;
607
+ }
608
+ function isPositiveInteger(value) {
609
+ return isNonNegativeInteger(value) && value > 0;
610
+ }
611
+ function deliveryBacklogState(ingestion) {
612
+ if (ingestion?.healthy !== false) return void 0;
613
+ const failures = ingestion.consecutiveFailures;
614
+ const failedWithoutProgress = failures !== 0 && !(isPositiveInteger(failures) && isPositiveInteger(ingestion.lastFailedDrainAcknowledgedCount));
615
+ if (failedWithoutProgress) return "failing";
616
+ const retained = ingestion.lastRetainedBucketCount;
617
+ if (!isNonNegativeInteger(retained)) return "failing";
618
+ return retained > 0 ? "retained" : "draining";
619
+ }
620
+
600
621
  // src/lib/presence.ts
601
622
  var DECISION_ORIGIN = "https://app.getprimitive.ai";
602
623
  function validDecisionUrl(value) {
@@ -671,7 +692,8 @@ function formatStatusline(version, snapshot, resolveIngestionStatus, options = {
671
692
  if (snapshot.ingestion?.healthy === false) {
672
693
  const pending = snapshot.ingestion.pendingCount;
673
694
  const qualifier = snapshot.ingestion.pendingSampled ? "at least " : "";
674
- return `primitive ${version} (daemon: degraded \xB7 delivery: stalled${typeof pending === "number" ? ` \xB7 ${qualifier}${String(pending)} pending` : ""}${repositorySuffix}${ingestionSuffix(ingestionStatus)})`;
695
+ const delivery = deliveryBacklogState(snapshot.ingestion) === "draining" && snapshot.heartbeat?.healthy === true ? "draining" : "stalled";
696
+ return `primitive ${version} (daemon: degraded \xB7 delivery: ${delivery}${typeof pending === "number" ? ` \xB7 ${qualifier}${String(pending)} pending` : ""}${repositorySuffix}${ingestionSuffix(ingestionStatus)})`;
675
697
  }
676
698
  if (snapshot.heartbeat?.healthy === false) {
677
699
  return `primitive ${version} (daemon: degraded \xB7 presence: unavailable${repositorySuffix}${ingestionSuffix(ingestionStatus)})`;
@@ -1,28 +1,33 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ recordPostCommitFired
4
+ } from "../chunk-FXF4JWK2.js";
5
+ import {
6
+ unattendedEnv
7
+ } from "../chunk-OYHYCK4K.js";
2
8
  import {
3
9
  commitAttributionFromEnvironment,
4
10
  toCommitMove
5
- } from "../chunk-NAHHFSLH.js";
11
+ } from "../chunk-ICM2XCXS.js";
6
12
  import {
7
13
  getOrCreateWorkspaceId
8
14
  } from "../chunk-EZXEWFDG.js";
9
15
  import {
10
16
  appendMove,
11
17
  resolveOrg
12
- } from "../chunk-FBAYCS3X.js";
13
- import "../chunk-OAAP2MY6.js";
14
- import "../chunk-BTNNEH2W.js";
18
+ } from "../chunk-DXJQR4QI.js";
19
+ import "../chunk-K7D2EYBS.js";
15
20
  import {
16
21
  cachedCollectScopeAdmits,
17
22
  isRepoActiveForCapture,
18
23
  repoSyncId
19
- } from "../chunk-M6RIJVRE.js";
20
- import "../chunk-PCVGBE5B.js";
24
+ } from "../chunk-DSWT6BCC.js";
25
+ import "../chunk-G2VMA2QO.js";
21
26
  import {
22
27
  githubRepositoryFullName,
23
28
  resolveRepositoryContext
24
29
  } from "../chunk-H4UNYFUC.js";
25
- import "../chunk-67VNLLBN.js";
30
+ import "../chunk-2GP5UFV7.js";
26
31
 
27
32
  // src/hooks/post-commit.ts
28
33
  import { execFileSync, spawn } from "child_process";
@@ -133,11 +138,13 @@ function spawnBackgroundFlush() {
133
138
  const entry = join(here, "..", "index.js");
134
139
  spawn(process.execPath, [entry, "moves", "flush"], {
135
140
  detached: true,
136
- stdio: "ignore"
141
+ stdio: "ignore",
142
+ env: unattendedEnv()
137
143
  }).unref();
138
144
  }
139
145
  function runPostCommit() {
140
146
  const cwd = gitText(["rev-parse", "--show-toplevel"]) ?? process.cwd();
147
+ recordPostCommitFired(cwd, process.env.PRIM_COMMIT_SHA);
141
148
  if (!isRepoActiveForCapture(cwd)) {
142
149
  return;
143
150
  }
@@ -1,28 +1,30 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ unattendedEnv
4
+ } from "../chunk-OYHYCK4K.js";
2
5
  import {
3
6
  canonicalRewritePairs,
4
7
  toRewriteMove
5
- } from "../chunk-NAHHFSLH.js";
8
+ } from "../chunk-ICM2XCXS.js";
6
9
  import {
7
10
  getOrCreateWorkspaceId
8
11
  } from "../chunk-EZXEWFDG.js";
9
12
  import {
10
13
  appendMove,
11
14
  resolveOrg
12
- } from "../chunk-FBAYCS3X.js";
13
- import "../chunk-OAAP2MY6.js";
14
- import "../chunk-BTNNEH2W.js";
15
+ } from "../chunk-DXJQR4QI.js";
16
+ import "../chunk-K7D2EYBS.js";
15
17
  import {
16
18
  cachedCollectScopeAdmits,
17
19
  isRepoActiveForCapture,
18
20
  repoSyncId
19
- } from "../chunk-M6RIJVRE.js";
20
- import "../chunk-PCVGBE5B.js";
21
+ } from "../chunk-DSWT6BCC.js";
22
+ import "../chunk-G2VMA2QO.js";
21
23
  import {
22
24
  githubRepositoryFullName,
23
25
  resolveRepositoryContext
24
26
  } from "../chunk-H4UNYFUC.js";
25
- import "../chunk-67VNLLBN.js";
27
+ import "../chunk-2GP5UFV7.js";
26
28
 
27
29
  // src/hooks/post-rewrite.ts
28
30
  import { execFileSync, spawn } from "child_process";
@@ -143,7 +145,8 @@ function spawnBackgroundFlush() {
143
145
  const entry = join(here, "..", "index.js");
144
146
  spawn(process.execPath, [entry, "moves", "flush"], {
145
147
  detached: true,
146
- stdio: "ignore"
148
+ stdio: "ignore",
149
+ env: unattendedEnv()
147
150
  }).unref();
148
151
  }
149
152
  function runPostRewrite() {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  requireDurableIngestAcknowledgement
4
- } from "../chunk-FKXFUUWJ.js";
4
+ } from "../chunk-TYAHC25F.js";
5
5
  import {
6
6
  enrichHookPayloadWithFileRefs,
7
7
  preserveHookFileMetadata
@@ -10,49 +10,47 @@ import {
10
10
  postToolInvocationId,
11
11
  toMove,
12
12
  toolOutcomeFor
13
- } from "../chunk-NAHHFSLH.js";
13
+ } from "../chunk-ICM2XCXS.js";
14
14
  import {
15
15
  getOrCreateWorkspaceId
16
16
  } from "../chunk-EZXEWFDG.js";
17
17
  import {
18
18
  appendMove,
19
19
  resolveOrg
20
- } from "../chunk-FBAYCS3X.js";
20
+ } from "../chunk-DXJQR4QI.js";
21
21
  import "../chunk-ZB4F75SZ.js";
22
22
  import {
23
23
  appendCodexContext,
24
24
  prepareCodexContext
25
- } from "../chunk-ADUTW66W.js";
26
- import "../chunk-WX52U7Z2.js";
25
+ } from "../chunk-O7YAW7G6.js";
26
+ import "../chunk-ZU563PQI.js";
27
27
  import {
28
28
  scrubFromCwd
29
- } from "../chunk-OAAP2MY6.js";
29
+ } from "../chunk-K7D2EYBS.js";
30
30
  import {
31
31
  bold,
32
- color
33
- } from "../chunk-BTNNEH2W.js";
34
- import {
35
32
  cachedCollectScopeAdmits,
33
+ color,
36
34
  isRepoActiveForCapture,
37
35
  repoSyncId
38
- } from "../chunk-M6RIJVRE.js";
36
+ } from "../chunk-DSWT6BCC.js";
39
37
  import {
40
38
  getClient,
41
39
  terminalSafeLine
42
- } from "../chunk-PCVGBE5B.js";
40
+ } from "../chunk-G2VMA2QO.js";
43
41
  import {
44
42
  normalizeEnvelope,
45
43
  parseAgent,
46
44
  readHookStdin,
47
45
  shouldSuppressImportedCursorHandler
48
- } from "../chunk-5HRR4AOR.js";
49
- import "../chunk-26P57LAR.js";
46
+ } from "../chunk-IMK4JKTA.js";
47
+ import "../chunk-AXQQMX2U.js";
50
48
  import {
51
49
  currentBranch,
52
50
  resolveRepositoryContext
53
51
  } from "../chunk-H4UNYFUC.js";
54
- import "../chunk-KFXF2V5G.js";
55
- import "../chunk-67VNLLBN.js";
52
+ import "../chunk-OTHKG76J.js";
53
+ import "../chunk-2GP5UFV7.js";
56
54
 
57
55
  // src/hooks/post-tool-use.ts
58
56
  import { readFileSync } from "fs";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  checkAffectedDecisions,
4
4
  formatDecisionsWarning
5
- } from "../chunk-5GYQ4J3D.js";
6
- import "../chunk-PCVGBE5B.js";
7
- import "../chunk-KFXF2V5G.js";
8
- import "../chunk-67VNLLBN.js";
5
+ } from "../chunk-UKUAAAXE.js";
6
+ import "../chunk-G2VMA2QO.js";
7
+ import "../chunk-OTHKG76J.js";
8
+ import "../chunk-2GP5UFV7.js";
9
9
 
10
10
  // src/hooks/pre-commit.ts
11
11
  import { execSync } from "child_process";
@@ -17,40 +17,38 @@ import {
17
17
  appendCodexContext,
18
18
  hasVisibleCodexMessage,
19
19
  prepareCodexContext
20
- } from "../chunk-ADUTW66W.js";
21
- import "../chunk-WX52U7Z2.js";
20
+ } from "../chunk-O7YAW7G6.js";
21
+ import "../chunk-ZU563PQI.js";
22
22
  import {
23
23
  DEFAULT_RULES,
24
24
  scrub
25
- } from "../chunk-OAAP2MY6.js";
26
- import {
27
- boundedHealthError
28
- } from "../chunk-BTNNEH2W.js";
25
+ } from "../chunk-K7D2EYBS.js";
29
26
  import {
27
+ boundedHealthError,
30
28
  cachedCollectScopeAdmits,
31
29
  isRepoActive,
32
30
  repoSyncId
33
- } from "../chunk-M6RIJVRE.js";
31
+ } from "../chunk-DSWT6BCC.js";
34
32
  import {
35
33
  getClient
36
- } from "../chunk-PCVGBE5B.js";
34
+ } from "../chunk-G2VMA2QO.js";
37
35
  import {
38
36
  normalizeEnvelope,
39
37
  parseAgent,
40
38
  readHookStdin,
41
39
  shouldSuppressImportedCursorHandler
42
- } from "../chunk-5HRR4AOR.js";
40
+ } from "../chunk-IMK4JKTA.js";
43
41
  import {
44
42
  packageVersion
45
- } from "../chunk-26P57LAR.js";
43
+ } from "../chunk-AXQQMX2U.js";
46
44
  import {
47
45
  canonicalGitRoot,
48
46
  canonicalRepositoryPath,
49
47
  currentBranch,
50
48
  githubRepositoryFullName
51
49
  } from "../chunk-H4UNYFUC.js";
52
- import "../chunk-KFXF2V5G.js";
53
- import "../chunk-67VNLLBN.js";
50
+ import "../chunk-OTHKG76J.js";
51
+ import "../chunk-2GP5UFV7.js";
54
52
 
55
53
  // src/hooks/preflight-v3.ts
56
54
  import { Buffer } from "buffer";
@@ -8,7 +8,10 @@ import {
8
8
  acknowledgeDecisionFeedback,
9
9
  leaseDecisionFeedback,
10
10
  renderFeedback
11
- } from "../chunk-5AFRMOPX.js";
11
+ } from "../chunk-OH3EZXYX.js";
12
+ import {
13
+ unattendedEnv
14
+ } from "../chunk-OYHYCK4K.js";
12
15
  import {
13
16
  enrichHookPayloadWithFileRefs,
14
17
  preserveHookFileMetadata
@@ -17,43 +20,42 @@ import {
17
20
  postToolInvocationId,
18
21
  shouldFlushAfter,
19
22
  toMove
20
- } from "../chunk-NAHHFSLH.js";
23
+ } from "../chunk-ICM2XCXS.js";
21
24
  import {
22
25
  getOrCreateWorkspaceId
23
26
  } from "../chunk-EZXEWFDG.js";
24
27
  import {
25
28
  appendMove,
26
29
  resolveOrg
27
- } from "../chunk-FBAYCS3X.js";
30
+ } from "../chunk-DXJQR4QI.js";
28
31
  import "../chunk-ZB4F75SZ.js";
29
32
  import {
30
33
  prepareCodexContext
31
- } from "../chunk-ADUTW66W.js";
32
- import "../chunk-WX52U7Z2.js";
34
+ } from "../chunk-O7YAW7G6.js";
35
+ import "../chunk-ZU563PQI.js";
33
36
  import {
34
37
  scrubFromCwd,
35
38
  writeHookDebug
36
- } from "../chunk-OAAP2MY6.js";
37
- import "../chunk-BTNNEH2W.js";
39
+ } from "../chunk-K7D2EYBS.js";
38
40
  import {
39
41
  cachedCollectScopeAdmits,
40
42
  isRepoActiveForCapture,
41
43
  repoSyncId
42
- } from "../chunk-M6RIJVRE.js";
43
- import "../chunk-PCVGBE5B.js";
44
+ } from "../chunk-DSWT6BCC.js";
45
+ import "../chunk-G2VMA2QO.js";
44
46
  import {
45
47
  normalizeEnvelope,
46
48
  parseAgent,
47
49
  readHookStdin,
48
50
  shouldSuppressImportedCursorHandler
49
- } from "../chunk-5HRR4AOR.js";
50
- import "../chunk-26P57LAR.js";
51
+ } from "../chunk-IMK4JKTA.js";
52
+ import "../chunk-AXQQMX2U.js";
51
53
  import {
52
54
  currentBranch,
53
55
  resolveRepositoryContext
54
56
  } from "../chunk-H4UNYFUC.js";
55
- import "../chunk-KFXF2V5G.js";
56
- import "../chunk-67VNLLBN.js";
57
+ import "../chunk-OTHKG76J.js";
58
+ import "../chunk-2GP5UFV7.js";
57
59
 
58
60
  // src/hooks/prim-hook.ts
59
61
  import { spawn } from "child_process";
@@ -113,7 +115,8 @@ function spawnBackgroundFlush() {
113
115
  const entry = join(here, "..", "index.js");
114
116
  spawn(process.execPath, [entry, "moves", "flush"], {
115
117
  detached: true,
116
- stdio: "ignore"
118
+ stdio: "ignore",
119
+ env: unattendedEnv()
117
120
  }).unref();
118
121
  }
119
122
  async function main() {
@@ -4,13 +4,13 @@ import {
4
4
  parseAgent,
5
5
  readHookStdin,
6
6
  shouldSuppressImportedCursorHandler
7
- } from "../chunk-5HRR4AOR.js";
8
- import "../chunk-26P57LAR.js";
7
+ } from "../chunk-IMK4JKTA.js";
8
+ import "../chunk-AXQQMX2U.js";
9
9
  import "../chunk-H4UNYFUC.js";
10
10
  import {
11
11
  daemonRequest
12
- } from "../chunk-KFXF2V5G.js";
13
- import "../chunk-67VNLLBN.js";
12
+ } from "../chunk-OTHKG76J.js";
13
+ import "../chunk-2GP5UFV7.js";
14
14
 
15
15
  // src/hooks/session-end.ts
16
16
  var STDIN_TIMEOUT_MS = 1e3;
@@ -1,13 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  bindRepository,
4
- ensureEffectivePostCommitHook,
5
- ensureEffectivePostRewriteHook,
4
+ ensureEffectiveGitHook,
6
5
  hasUsableCodexGuidance,
7
6
  hasUsableCursorSkill,
7
+ kickDaemonEnsure,
8
8
  refreshClaudePlugins,
9
9
  warmBinCache
10
- } from "../chunk-LGGMJYY4.js";
10
+ } from "../chunk-WUXFLE7X.js";
11
+ import {
12
+ clearHooksWired,
13
+ recordHooksWired
14
+ } from "../chunk-FXF4JWK2.js";
11
15
  import {
12
16
  buildHookOutput,
13
17
  handoffHookOutput
@@ -17,64 +21,41 @@ import {
17
21
  acknowledgeDecisionFeedback,
18
22
  leaseDecisionFeedback,
19
23
  renderFeedback
20
- } from "../chunk-5AFRMOPX.js";
24
+ } from "../chunk-OH3EZXYX.js";
25
+ import "../chunk-OYHYCK4K.js";
21
26
  import {
22
27
  getOrCreateWorkspaceId
23
28
  } from "../chunk-EZXEWFDG.js";
24
29
  import {
25
30
  prepareCodexContext
26
- } from "../chunk-ADUTW66W.js";
27
- import "../chunk-WX52U7Z2.js";
31
+ } from "../chunk-O7YAW7G6.js";
32
+ import "../chunk-ZU563PQI.js";
28
33
  import {
29
34
  fetchAndCacheCollectScope,
30
35
  isRepoActiveForCapture,
31
36
  repoActiveFlag,
32
37
  setRepoActive
33
- } from "../chunk-M6RIJVRE.js";
38
+ } from "../chunk-DSWT6BCC.js";
34
39
  import {
35
40
  getSiteUrl,
36
41
  isSessionEnded
37
- } from "../chunk-PCVGBE5B.js";
42
+ } from "../chunk-G2VMA2QO.js";
38
43
  import {
39
44
  normalizeEnvelope,
40
45
  parseAgent,
41
46
  readHookStdin,
42
47
  shouldSuppressImportedCursorHandler
43
- } from "../chunk-5HRR4AOR.js";
48
+ } from "../chunk-IMK4JKTA.js";
44
49
  import {
45
- binFile
46
- } from "../chunk-26P57LAR.js";
50
+ MANAGED_GIT_HOOK_NAMES
51
+ } from "../chunk-AXQQMX2U.js";
47
52
  import {
48
53
  gitToplevel
49
54
  } from "../chunk-H4UNYFUC.js";
50
55
  import {
51
56
  daemonRequest
52
- } from "../chunk-KFXF2V5G.js";
53
- import "../chunk-67VNLLBN.js";
54
-
55
- // src/daemon/self-heal.ts
56
- import { spawn } from "child_process";
57
- function kickDaemonEnsure(options = {}) {
58
- const primEntry = options.primEntry === void 0 ? binFile("prim") : options.primEntry;
59
- if (!primEntry) {
60
- return false;
61
- }
62
- try {
63
- const args = [primEntry, "daemon", "ensure"];
64
- if ((options.platform ?? process.platform) === "darwin") {
65
- args.push("--latest-bootstrap");
66
- }
67
- const child = (options.spawnProcess ?? spawn)(
68
- options.nodeEntry ?? process.execPath,
69
- args,
70
- { detached: true, stdio: "ignore" }
71
- );
72
- child.unref();
73
- return true;
74
- } catch {
75
- return false;
76
- }
77
- }
57
+ } from "../chunk-OTHKG76J.js";
58
+ import "../chunk-2GP5UFV7.js";
78
59
 
79
60
  // src/hooks/reauth-notice.ts
80
61
  var REAUTH_NOTICE = "[prim] authentication ended \u2014 run `prim auth login` to resume decision capture";
@@ -97,7 +78,11 @@ var CODEX_PRIM_REMINDER = primReminder(CODEX_PRIM_ACTION, CODEX_PRIM_ACTION);
97
78
  async function activeProjectRoot(cwd) {
98
79
  try {
99
80
  const root = gitToplevel(cwd);
100
- if (!root || !isRepoActiveForCapture(cwd)) return null;
81
+ if (!root) return null;
82
+ if (!isRepoActiveForCapture(cwd)) {
83
+ if (repoActiveFlag(root) === "false") clearHooksWired(root);
84
+ return null;
85
+ }
101
86
  let shellGateActive = repoActiveFlag(root) === "true";
102
87
  if (!shellGateActive) {
103
88
  try {
@@ -107,13 +92,18 @@ async function activeProjectRoot(cwd) {
107
92
  }
108
93
  }
109
94
  if (shellGateActive) {
110
- try {
111
- ensureEffectivePostCommitHook(root);
112
- } catch {
113
- }
114
- try {
115
- ensureEffectivePostRewriteHook(root);
116
- } catch {
95
+ for (const hookName of MANAGED_GIT_HOOK_NAMES) {
96
+ try {
97
+ const result = ensureEffectiveGitHook(hookName, root, {
98
+ context: "ambient",
99
+ repairOnly: hookName === "pre-commit"
100
+ });
101
+ if (hookName === "post-commit" && // Manual mode: the user's own wiring is expected to reach prim too.
102
+ ["created", "updated", "unchanged", "manual"].includes(result.outcome)) {
103
+ recordHooksWired(root, { onlyIfAbsent: true });
104
+ }
105
+ } catch {
106
+ }
117
107
  }
118
108
  }
119
109
  try {