harnery 0.41.0 → 0.43.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.
Files changed (269) hide show
  1. package/dist/commander.d.ts +16 -0
  2. package/dist/commander.d.ts.map +1 -1
  3. package/dist/commander.js +21 -0
  4. package/dist/commands/agents.d.ts.map +1 -1
  5. package/dist/commands/agents.js +63 -5
  6. package/dist/commands/artifacts.d.ts.map +1 -1
  7. package/dist/commands/artifacts.js +113 -12
  8. package/dist/commands/browse.d.ts +164 -0
  9. package/dist/commands/browse.d.ts.map +1 -1
  10. package/dist/commands/browse.js +263 -51
  11. package/dist/commands/claude-desktop.d.ts.map +1 -1
  12. package/dist/commands/claude-desktop.js +52 -0
  13. package/dist/commands/disk.d.ts +6 -0
  14. package/dist/commands/disk.d.ts.map +1 -0
  15. package/dist/commands/disk.js +80 -0
  16. package/dist/commands/doctor.d.ts +8 -0
  17. package/dist/commands/doctor.d.ts.map +1 -1
  18. package/dist/commands/doctor.js +48 -1
  19. package/dist/commands/files.d.ts +16 -0
  20. package/dist/commands/files.d.ts.map +1 -1
  21. package/dist/commands/files.js +54 -2
  22. package/dist/commands/init.d.ts +2 -2
  23. package/dist/commands/init.d.ts.map +1 -1
  24. package/dist/commands/init.js +43 -9
  25. package/dist/commands/rm.d.ts +4 -0
  26. package/dist/commands/rm.d.ts.map +1 -0
  27. package/dist/commands/rm.js +87 -0
  28. package/dist/commands/servers.d.ts +7 -0
  29. package/dist/commands/servers.d.ts.map +1 -0
  30. package/dist/commands/servers.js +394 -0
  31. package/dist/commands/tunnel.d.ts +65 -0
  32. package/dist/commands/tunnel.d.ts.map +1 -1
  33. package/dist/commands/tunnel.js +372 -103
  34. package/dist/commands/web-fetch.d.ts +3 -2
  35. package/dist/commands/web-fetch.d.ts.map +1 -1
  36. package/dist/commands/web-fetch.js +25 -19
  37. package/dist/commands/web.d.ts +7 -1
  38. package/dist/commands/web.d.ts.map +1 -1
  39. package/dist/commands/web.js +9 -3
  40. package/dist/core/adapters/profiles.d.ts +9 -0
  41. package/dist/core/adapters/profiles.d.ts.map +1 -1
  42. package/dist/core/adapters/profiles.js +22 -1
  43. package/dist/core/adapters/types.d.ts +9 -0
  44. package/dist/core/adapters/types.d.ts.map +1 -1
  45. package/dist/core/agents/cli.js +13 -6
  46. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  47. package/dist/core/agents/render/prompt-context.js +11 -5
  48. package/dist/core/agents/render/session-context.d.ts.map +1 -1
  49. package/dist/core/agents/render/session-context.js +59 -13
  50. package/dist/core/agents/state/live-coordination-view.d.ts +20 -0
  51. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  52. package/dist/core/agents/state/live-coordination-view.js +60 -0
  53. package/dist/core/agents/state/names.d.ts +43 -3
  54. package/dist/core/agents/state/names.d.ts.map +1 -1
  55. package/dist/core/agents/state/names.js +87 -3
  56. package/dist/core/artifacts/delivery-card.js +9 -2
  57. package/dist/core/artifacts/index.d.ts +140 -4
  58. package/dist/core/artifacts/index.d.ts.map +1 -1
  59. package/dist/core/artifacts/index.js +522 -49
  60. package/dist/core/config.d.ts +68 -11
  61. package/dist/core/config.d.ts.map +1 -1
  62. package/dist/core/config.js +128 -3
  63. package/dist/core/diagnostics/bundle.d.ts.map +1 -1
  64. package/dist/core/diagnostics/bundle.js +2 -2
  65. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  66. package/dist/core/events/v3/producers/recorder.js +16 -0
  67. package/dist/core/events/v3/projection.js +9 -1
  68. package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
  69. package/dist/core/events/v3/support-storage/pack-reader.js +42 -16
  70. package/dist/core/hooks/adapter/events.d.ts +17 -0
  71. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  72. package/dist/core/hooks/adapter/events.js +5 -0
  73. package/dist/core/hooks/adapter/runtime-telemetry.js +3 -1
  74. package/dist/core/hooks/adapter/wiring.d.ts +37 -7
  75. package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
  76. package/dist/core/hooks/adapter/wiring.js +62 -4
  77. package/dist/core/hooks/cli.js +131 -23
  78. package/dist/core/hooks/fork-lineage.d.ts +40 -0
  79. package/dist/core/hooks/fork-lineage.d.ts.map +1 -0
  80. package/dist/core/hooks/fork-lineage.js +62 -0
  81. package/dist/core/hooks/resolve/transcript.d.ts +16 -0
  82. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  83. package/dist/core/hooks/resolve/transcript.js +84 -0
  84. package/dist/core/hooks/run-markers.d.ts +37 -0
  85. package/dist/core/hooks/run-markers.d.ts.map +1 -0
  86. package/dist/core/hooks/run-markers.js +109 -0
  87. package/dist/core/hooks/shell-rm.d.ts +2 -0
  88. package/dist/core/hooks/shell-rm.d.ts.map +1 -0
  89. package/dist/core/hooks/shell-rm.js +105 -0
  90. package/dist/core/hooks/shell-tokens.d.ts +12 -0
  91. package/dist/core/hooks/shell-tokens.d.ts.map +1 -0
  92. package/dist/core/hooks/shell-tokens.js +97 -0
  93. package/dist/core/hooks/shell-waiter.d.ts.map +1 -1
  94. package/dist/core/hooks/shell-waiter.js +3 -93
  95. package/dist/core/semantic/contract.d.ts +5 -5
  96. package/dist/core/servers/index.d.ts +211 -0
  97. package/dist/core/servers/index.d.ts.map +1 -0
  98. package/dist/core/servers/index.js +560 -0
  99. package/dist/core/servers/net.d.ts +58 -0
  100. package/dist/core/servers/net.d.ts.map +1 -0
  101. package/dist/core/servers/net.js +270 -0
  102. package/dist/core/servers/tunnels.d.ts +14 -0
  103. package/dist/core/servers/tunnels.d.ts.map +1 -0
  104. package/dist/core/servers/tunnels.js +33 -0
  105. package/dist/core/storage/builtins.js +1 -0
  106. package/dist/core/storage/process-log.d.ts +12 -0
  107. package/dist/core/storage/process-log.d.ts.map +1 -1
  108. package/dist/core/storage/process-log.js +10 -2
  109. package/dist/core/workflow/engine.d.ts.map +1 -1
  110. package/dist/core/workflow/engine.js +30 -1
  111. package/dist/core/workflow/sandbox-projection.d.ts +13 -2
  112. package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
  113. package/dist/core/workflow/sandbox-projection.js +23 -0
  114. package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
  115. package/dist/core/workflow/spawn-claude.js +6 -1
  116. package/dist/core/workflow/spawn-codex.d.ts +2 -0
  117. package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
  118. package/dist/core/workflow/spawn-codex.js +20 -1
  119. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  120. package/dist/core/workflow/spawn-cursor.js +6 -1
  121. package/dist/core/workflow/spawn-opencode.d.ts.map +1 -1
  122. package/dist/core/workflow/spawn-opencode.js +4 -1
  123. package/dist/core/workflow/types.d.ts +47 -2
  124. package/dist/core/workflow/types.d.ts.map +1 -1
  125. package/dist/core/workflow/worker-access.d.ts +92 -0
  126. package/dist/core/workflow/worker-access.d.ts.map +1 -0
  127. package/dist/core/workflow/worker-access.js +450 -0
  128. package/dist/lib/browser/batch-steps.d.ts +18 -0
  129. package/dist/lib/browser/batch-steps.d.ts.map +1 -0
  130. package/dist/lib/browser/batch-steps.js +82 -0
  131. package/dist/lib/browser/collect/collector.d.ts +99 -0
  132. package/dist/lib/browser/collect/collector.d.ts.map +1 -0
  133. package/dist/lib/browser/collect/collector.js +202 -0
  134. package/dist/lib/browser/collect/fields.d.ts +31 -0
  135. package/dist/lib/browser/collect/fields.d.ts.map +1 -0
  136. package/dist/lib/browser/collect/fields.js +75 -0
  137. package/dist/lib/browser/collect/index.d.ts +6 -0
  138. package/dist/lib/browser/collect/index.d.ts.map +1 -0
  139. package/dist/lib/browser/collect/index.js +5 -0
  140. package/dist/lib/browser/collect/page-driver.d.ts +14 -0
  141. package/dist/lib/browser/collect/page-driver.d.ts.map +1 -0
  142. package/dist/lib/browser/collect/page-driver.js +306 -0
  143. package/dist/lib/browser/collect/presets.d.ts +52 -0
  144. package/dist/lib/browser/collect/presets.d.ts.map +1 -0
  145. package/dist/lib/browser/collect/presets.js +176 -0
  146. package/dist/lib/browser/collect/scroll-plan.d.ts +85 -0
  147. package/dist/lib/browser/collect/scroll-plan.d.ts.map +1 -0
  148. package/dist/lib/browser/collect/scroll-plan.js +118 -0
  149. package/dist/lib/browser/index.d.ts +1 -1
  150. package/dist/lib/browser/index.d.ts.map +1 -1
  151. package/dist/lib/browser/page-review-judge.d.ts +2 -0
  152. package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
  153. package/dist/lib/browser/page-review-judge.js +13 -0
  154. package/dist/lib/browser/qa-run-contracts.d.ts +10 -0
  155. package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
  156. package/dist/lib/browser/qa-run.d.ts.map +1 -1
  157. package/dist/lib/browser/qa-run.js +1 -0
  158. package/dist/lib/browser/windows-chrome.d.ts +59 -0
  159. package/dist/lib/browser/windows-chrome.d.ts.map +1 -0
  160. package/dist/lib/browser/windows-chrome.js +179 -0
  161. package/dist/lib/claude-desktop-share.d.ts +136 -0
  162. package/dist/lib/claude-desktop-share.d.ts.map +1 -0
  163. package/dist/lib/claude-desktop-share.js +394 -0
  164. package/dist/lib/disk-usage.d.ts +50 -0
  165. package/dist/lib/disk-usage.d.ts.map +1 -0
  166. package/dist/lib/disk-usage.js +303 -0
  167. package/dist/lib/docs-lint.d.ts +6 -0
  168. package/dist/lib/docs-lint.d.ts.map +1 -1
  169. package/dist/lib/docs-lint.js +8 -3
  170. package/dist/lib/guarded-remove.d.ts +34 -0
  171. package/dist/lib/guarded-remove.d.ts.map +1 -0
  172. package/dist/lib/guarded-remove.js +310 -0
  173. package/dist/lib/instructions/templates.js +8 -8
  174. package/dist/lib/tunnel/allowlist.d.ts +44 -0
  175. package/dist/lib/tunnel/allowlist.d.ts.map +1 -0
  176. package/dist/lib/tunnel/allowlist.js +204 -0
  177. package/dist/lib/tunnel/current-address.d.ts +41 -0
  178. package/dist/lib/tunnel/current-address.d.ts.map +1 -0
  179. package/dist/lib/tunnel/current-address.js +123 -0
  180. package/dist/lib/tunnel/error-page.d.ts +1 -1
  181. package/dist/lib/tunnel/error-page.d.ts.map +1 -1
  182. package/dist/lib/tunnel/error-page.js +19 -8
  183. package/dist/lib/tunnel/gate.js +33 -7
  184. package/dist/lib/tunnel/path-scope.d.ts +22 -0
  185. package/dist/lib/tunnel/path-scope.d.ts.map +1 -0
  186. package/dist/lib/tunnel/path-scope.js +62 -0
  187. package/dist/lib/tunnel/processes.d.ts +39 -0
  188. package/dist/lib/tunnel/processes.d.ts.map +1 -0
  189. package/dist/lib/tunnel/processes.js +121 -0
  190. package/dist/lib/tunnel/state.d.ts +33 -3
  191. package/dist/lib/tunnel/state.d.ts.map +1 -1
  192. package/dist/lib/tunnel/state.js +115 -30
  193. package/package.json +7 -1
  194. package/schemas/config.schema.json +91 -0
  195. package/src/commander.ts +51 -0
  196. package/src/commands/agents.ts +111 -11
  197. package/src/commands/artifacts.ts +171 -19
  198. package/src/commands/browse.ts +400 -57
  199. package/src/commands/claude-desktop.ts +61 -0
  200. package/src/commands/disk.ts +114 -0
  201. package/src/commands/doctor.ts +52 -1
  202. package/src/commands/files.ts +93 -2
  203. package/src/commands/init.ts +55 -5
  204. package/src/commands/rm.ts +115 -0
  205. package/src/commands/servers.ts +506 -0
  206. package/src/commands/tunnel.ts +494 -116
  207. package/src/commands/web-fetch.ts +30 -19
  208. package/src/commands/web.ts +9 -3
  209. package/src/core/adapters/profiles.ts +22 -1
  210. package/src/core/adapters/types.ts +10 -0
  211. package/src/core/agents/cli.ts +14 -6
  212. package/src/core/agents/render/prompt-context.ts +25 -8
  213. package/src/core/agents/render/session-context.ts +84 -16
  214. package/src/core/agents/state/live-coordination-view.ts +73 -0
  215. package/src/core/agents/state/names.ts +117 -6
  216. package/src/core/artifacts/delivery-card.ts +10 -2
  217. package/src/core/artifacts/index.ts +697 -44
  218. package/src/core/config.ts +183 -4
  219. package/src/core/diagnostics/bundle.ts +2 -1
  220. package/src/core/events/v3/producers/recorder.ts +16 -0
  221. package/src/core/events/v3/projection.ts +11 -1
  222. package/src/core/events/v3/support-storage/pack-reader.ts +45 -19
  223. package/src/core/hooks/adapter/events.ts +19 -0
  224. package/src/core/hooks/adapter/runtime-telemetry.ts +3 -1
  225. package/src/core/hooks/adapter/wiring.ts +116 -8
  226. package/src/core/hooks/cli.ts +152 -22
  227. package/src/core/hooks/fork-lineage.ts +82 -0
  228. package/src/core/hooks/resolve/transcript.ts +88 -0
  229. package/src/core/hooks/run-markers.ts +132 -0
  230. package/src/core/hooks/shell-rm.ts +103 -0
  231. package/src/core/hooks/shell-tokens.ts +96 -0
  232. package/src/core/hooks/shell-waiter.ts +4 -91
  233. package/src/core/servers/index.ts +712 -0
  234. package/src/core/servers/net.ts +283 -0
  235. package/src/core/servers/tunnels.ts +39 -0
  236. package/src/core/storage/builtins.ts +1 -0
  237. package/src/core/storage/process-log.ts +17 -2
  238. package/src/core/workflow/engine.ts +38 -1
  239. package/src/core/workflow/sandbox-projection.ts +38 -2
  240. package/src/core/workflow/spawn-claude.ts +5 -1
  241. package/src/core/workflow/spawn-codex.ts +18 -1
  242. package/src/core/workflow/spawn-cursor.ts +5 -1
  243. package/src/core/workflow/spawn-opencode.ts +4 -1
  244. package/src/core/workflow/types.ts +62 -2
  245. package/src/core/workflow/worker-access.ts +525 -0
  246. package/src/lib/browser/batch-steps.ts +79 -0
  247. package/src/lib/browser/collect/collector.ts +306 -0
  248. package/src/lib/browser/collect/fields.ts +87 -0
  249. package/src/lib/browser/collect/index.ts +47 -0
  250. package/src/lib/browser/collect/page-driver.ts +327 -0
  251. package/src/lib/browser/collect/presets.ts +237 -0
  252. package/src/lib/browser/collect/scroll-plan.ts +179 -0
  253. package/src/lib/browser/index.ts +1 -0
  254. package/src/lib/browser/page-review-judge.ts +16 -0
  255. package/src/lib/browser/qa-run-contracts.ts +11 -0
  256. package/src/lib/browser/qa-run.ts +1 -0
  257. package/src/lib/browser/windows-chrome.ts +227 -0
  258. package/src/lib/claude-desktop-share.ts +511 -0
  259. package/src/lib/disk-usage.ts +347 -0
  260. package/src/lib/docs-lint.ts +8 -3
  261. package/src/lib/guarded-remove.ts +376 -0
  262. package/src/lib/instructions/templates.ts +8 -8
  263. package/src/lib/tunnel/allowlist.ts +208 -0
  264. package/src/lib/tunnel/current-address.ts +158 -0
  265. package/src/lib/tunnel/error-page.ts +25 -9
  266. package/src/lib/tunnel/gate.ts +38 -9
  267. package/src/lib/tunnel/path-scope.ts +73 -0
  268. package/src/lib/tunnel/processes.ts +149 -0
  269. package/src/lib/tunnel/state.ts +143 -30
@@ -11,13 +11,18 @@
11
11
  * — there's exactly one definition of the `agent-hook <subcommand>` match.
12
12
  */
13
13
  import { type AdapterId, type AdapterSpec, type HookEntryShape, type HookEvent } from "./events.js";
14
- /** Claude Code + Codex entry: `{ hooks: [{ type, command }] }`. */
14
+ /** One Claude Code or Codex command handler. */
15
+ export interface ClaudeHookHandler {
16
+ type: string;
17
+ command: string;
18
+ /** Codex: run instead of `command` on Windows. */
19
+ commandWindows?: string;
20
+ timeout?: number;
21
+ }
22
+ /** Claude Code + Codex entry: `{ hooks: [{ type, command, commandWindows?, timeout? }] }`. */
15
23
  export interface ClaudeHookGroup {
16
24
  matcher?: string;
17
- hooks: {
18
- type: string;
19
- command: string;
20
- }[];
25
+ hooks: ClaudeHookHandler[];
21
26
  }
22
27
  /** Cursor entry: a flat `{ command }`. */
23
28
  export interface CursorHookGroup {
@@ -39,7 +44,32 @@ export interface SettingsFile {
39
44
  /** Build a hook entry in the adapter's shape. */
40
45
  export declare function makeEntry(shape: HookEntryShape, command: string, extras?: {
41
46
  loop_limit?: number;
47
+ timeout?: number;
48
+ commandWindows?: string;
42
49
  }): HookGroup;
50
+ /**
51
+ * Rebuild a handler with Harnery's fields first in a fixed order, dropping
52
+ * undefined ones and keeping any other fields after them.
53
+ */
54
+ export declare function orderHandlerKeys(handler: ClaudeHookHandler): ClaudeHookHandler;
55
+ /**
56
+ * The Windows command for an opted-in project (ADR 0197). It hands the hook to
57
+ * the bridge entry point when that is on PATH and the working directory is a
58
+ * WSL UNC path, and otherwise runs the usual command. `ProviderPath` drops the
59
+ * provider prefix that `Path` carries. The trailing `exit $LASTEXITCODE` is
60
+ * required: without it PowerShell reports any non-zero exit from inside the
61
+ * `if` block as 1, which would turn a hook's blocking exit 2 into a failure.
62
+ */
63
+ export declare function hookCommandWindows(spec: AdapterSpec, agentHookPath: string, subcommand: string, adapter: AdapterId, entryPoint: string): string;
64
+ /** Project-level choices that change what init writes. */
65
+ export interface WiringOptions {
66
+ /** Bridge entry point from `hooks.codexWindowsBridge`, or null when not opted in. */
67
+ windowsBridgeEntryPoint?: string | null;
68
+ }
69
+ /** The `commandWindows` init writes for one event, or undefined for none. */
70
+ export declare function expectedCommandWindows(spec: AdapterSpec, agentHookPath: string, subcommand: string, adapter: AdapterId, options?: WiringOptions): string | undefined;
71
+ /** The `timeout` init writes on one event's Harnery hook, or undefined for none. */
72
+ export declare function hookTimeoutFor(spec: AdapterSpec, subcommand: string): number | undefined;
43
73
  /** Pin Cursor Stop followups to Harnery's loop cap. Returns true when the entry changed. */
44
74
  export declare function applyCursorStopLoopLimit(group: HookGroup, subcommand: string): boolean;
45
75
  /** Pull every command string out of a hook entry, regardless of shape. */
@@ -76,7 +106,7 @@ export interface WiringDiff {
76
106
  duplicates: HookEvent[];
77
107
  /** Spec events wired under an event key other than the canonical one. */
78
108
  misplaced: HookEvent[];
79
- /** Spec events whose correct-key command differs from init's canonical command. */
109
+ /** Spec events whose correct-key command, `commandWindows`, or `timeout` differs from what init writes. */
80
110
  stale: HookEvent[];
81
111
  /** Settings fields rejected by a adapter with a strict top-level schema. */
82
112
  invalidTopLevelKeys: string[];
@@ -90,7 +120,7 @@ export interface WiringDiff {
90
120
  export declare function diffWiring(settings: SettingsFile, spec: AdapterSpec, expected?: {
91
121
  agentHookPath: string;
92
122
  adapter: AdapterId;
93
- }): WiringDiff;
123
+ } & WiringOptions): WiringDiff;
94
124
  export interface AdapterWiringStatus {
95
125
  adapter: AdapterId;
96
126
  /** Settings file path, relative to the project root. */
@@ -1 +1 @@
1
- {"version":3,"file":"wiring.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/adapter/wiring.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wiring.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/adapter/wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,aAAa,CAAC;AAGrB,gDAAgD;AAChD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,8FAA8F;AAC9F,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B;AACD,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AACD,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,eAAe,CAAC;AAE1D,2FAA2F;AAC3F,eAAO,MAAM,+BAA+B,IAAI,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAED,iDAAiD;AACjD,wBAAgB,SAAS,CACvB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1E,SAAS,CAgBX;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,iBAAiB,CAS9E;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,WAAW,EACjB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,SAAS,EAClB,UAAU,EAAE,MAAM,GACjB,MAAM,CAMR;AAED,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,qFAAqF;IACrF,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,6EAA6E;AAC7E,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,WAAW,EACjB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,SAAS,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,GAAG,SAAS,CASpB;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGxF;AAED,4FAA4F;AAC5F,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAMtF;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,EAAE,CAMxD;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAGnF;AAQD,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,6DAA6D;AAC7D,wBAAgB,WAAW,CACzB,IAAI,EAAE,WAAW,EACjB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,SAAS,GACjB,MAAM,CAMR;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAOxF;AAED,MAAM,WAAW,UAAU;IACzB,kDAAkD;IAClD,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,iCAAiC;IACjC,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB;;;;OAIG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,sEAAsE;IACtE,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,yEAAyE;IACzE,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,2GAA2G;IAC3G,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,4EAA4E;IAC5E,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,yEAAyE;IACzE,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,WAAW,EACjB,QAAQ,CAAC,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,CAAA;CAAE,GAAG,aAAa,GACvE,UAAU,CAwFZ;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,SAAS,CAAC;IACnB,wDAAwD;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAsCD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAyD5E;AAED,MAAM,WAAW,oBAAoB;IACnC,mDAAmD;IACnD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB;;;;OAIG;IACH,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,oBAAoB,CA8BhF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAUvC;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAkBlD"}
@@ -13,19 +13,68 @@
13
13
  import { existsSync, readFileSync } from "node:fs";
14
14
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
15
15
  import { fileURLToPath } from "node:url";
16
- import { resolveBinName } from "../../config.js";
16
+ import { codexWindowsBridgeConfig, resolveBinName } from "../../config.js";
17
17
  import { ADAPTER_SPECS, } from "./events.js";
18
18
  import { checkOpenCodePlugin, isOwnedOpenCodePlugin } from "./opencode-plugin.js";
19
19
  /** Bound Cursor Stop `followup_message` retries so a missed ritual cannot loop 5 times. */
20
20
  export const CURSOR_STOP_FOLLOWUP_LOOP_LIMIT = 2;
21
21
  /** Build a hook entry in the adapter's shape. */
22
22
  export function makeEntry(shape, command, extras) {
23
- if (shape !== "cursor")
24
- return { hooks: [{ type: "command", command }] };
23
+ if (shape !== "cursor") {
24
+ return {
25
+ hooks: [
26
+ orderHandlerKeys({
27
+ type: "command",
28
+ command,
29
+ commandWindows: extras?.commandWindows,
30
+ timeout: extras?.timeout,
31
+ }),
32
+ ],
33
+ };
34
+ }
25
35
  return extras?.loop_limit !== undefined
26
36
  ? { command, loop_limit: extras.loop_limit }
27
37
  : { command };
28
38
  }
39
+ /**
40
+ * Rebuild a handler with Harnery's fields first in a fixed order, dropping
41
+ * undefined ones and keeping any other fields after them.
42
+ */
43
+ export function orderHandlerKeys(handler) {
44
+ const { type, command, commandWindows, timeout, ...rest } = handler;
45
+ return {
46
+ type,
47
+ command,
48
+ ...(commandWindows !== undefined ? { commandWindows } : {}),
49
+ ...(timeout !== undefined ? { timeout } : {}),
50
+ ...rest,
51
+ };
52
+ }
53
+ /**
54
+ * The Windows command for an opted-in project (ADR 0197). It hands the hook to
55
+ * the bridge entry point when that is on PATH and the working directory is a
56
+ * WSL UNC path, and otherwise runs the usual command. `ProviderPath` drops the
57
+ * provider prefix that `Path` carries. The trailing `exit $LASTEXITCODE` is
58
+ * required: without it PowerShell reports any non-zero exit from inside the
59
+ * `if` block as 1, which would turn a hook's blocking exit 2 into a failure.
60
+ */
61
+ export function hookCommandWindows(spec, agentHookPath, subcommand, adapter, entryPoint) {
62
+ const direct = hookCommand(spec, agentHookPath, subcommand, adapter);
63
+ return (`if ((Get-Command ${entryPoint} -ErrorAction Ignore) -and $PWD.ProviderPath -like '\\\\wsl*') ` +
64
+ `{ ${entryPoint} ${subcommand} --adapter ${adapter} } else { ${direct} }; exit $LASTEXITCODE`);
65
+ }
66
+ /** The `commandWindows` init writes for one event, or undefined for none. */
67
+ export function expectedCommandWindows(spec, agentHookPath, subcommand, adapter, options) {
68
+ if (!spec.windowsBridgeHooks || !options?.windowsBridgeEntryPoint)
69
+ return undefined;
70
+ return hookCommandWindows(spec, agentHookPath, subcommand, adapter, options.windowsBridgeEntryPoint);
71
+ }
72
+ /** The `timeout` init writes on one event's Harnery hook, or undefined for none. */
73
+ export function hookTimeoutFor(spec, subcommand) {
74
+ if (!spec.hookTimeouts)
75
+ return undefined;
76
+ return spec.hookTimeouts.bySubcommand?.[subcommand] ?? spec.hookTimeouts.default;
77
+ }
29
78
  /** Pin Cursor Stop followups to Harnery's loop cap. Returns true when the entry changed. */
30
79
  export function applyCursorStopLoopLimit(group, subcommand) {
31
80
  if (subcommand !== "stop")
@@ -107,7 +156,15 @@ export function diffWiring(settings, spec, expected) {
107
156
  duplicates.push(event);
108
157
  if (expected && commands.length > 0) {
109
158
  const canonical = hookCommand(spec, expected.agentHookPath, event.subcommand, expected.adapter);
110
- if (commands.some((command) => command !== canonical))
159
+ const timeout = hookTimeoutFor(spec, event.subcommand);
160
+ const commandWindows = expectedCommandWindows(spec, expected.agentHookPath, event.subcommand, expected.adapter, expected);
161
+ const handlerDrift = groups.some((group) => "hooks" in group &&
162
+ Array.isArray(group.hooks) &&
163
+ group.hooks.some((hook) => typeof hook.command === "string" &&
164
+ commandWiresSubcommand(hook.command, event.subcommand) &&
165
+ ((timeout !== undefined && hook.timeout !== timeout) ||
166
+ (spec.windowsBridgeHooks === true && hook.commandWindows !== commandWindows))));
167
+ if (handlerDrift || commands.some((command) => command !== canonical))
111
168
  stale.push(event);
112
169
  }
113
170
  const wrongKey = Object.entries(hooks).some(([key, otherGroups]) => key !== event.settingsKey &&
@@ -222,6 +279,7 @@ export function loadAdapterWiring(projectRoot) {
222
279
  ? {
223
280
  agentHookPath: agentHookPathForProject(projectRoot, packageRoot),
224
281
  adapter: id,
282
+ windowsBridgeEntryPoint: codexWindowsBridgeConfig(projectRoot).entryPoint,
225
283
  }
226
284
  : undefined);
227
285
  if (diff.present.length === 0)
@@ -30,7 +30,7 @@ import { assistantTextStartsWithSessionNameBlock, isSessionNameRemediationComman
30
30
  import { readHeartbeat, setAssignedNameCache, stampSessionNameReminded, stampSessionNameRequested, stampSessionNameSeen, } from "../agents/state/heartbeat-writer.js";
31
31
  import { readLiveCoordinationRow } from "../agents/state/live-coordination-view.js";
32
32
  import { ensureLiveCoordinationHeartbeat } from "../agents/state/live-coordination-writer.js";
33
- import { assignName } from "../agents/state/names.js";
33
+ import { assignName, readForkParent, readForkState, recordForkDetection, resolveName, } from "../agents/state/names.js";
34
34
  import { writePidmapRow } from "../agents/state/pidmap.js";
35
35
  import { agentsRequireGitFinalization, coordFreshnessSeconds, hostPromptContextConfig, resolveBinName, } from "../config.js";
36
36
  import { checkpointContext, completeContextRecovery, extractContextSample, markContextCompactionCompleted, prepareContextRecovery, readContextState, recordContextSample, } from "../context/index.js";
@@ -42,19 +42,25 @@ import { closeProcessLoggers, legacyLogFields, processLogger } from "../storage/
42
42
  import { stableScopeId } from "../workflow/scope-id.js";
43
43
  import { adapterBehavior } from "./adapter/behaviors/index.js";
44
44
  import { detectAdapter, shouldSkipHookAdapter } from "./adapter/detect.js";
45
+ import { ADAPTER_SPECS } from "./adapter/events.js";
45
46
  import { extractBashCommand, extractToolDescription, normalizeEventName, parsePayload, } from "./adapter/parse.js";
47
+ import { hookTimeoutFor } from "./adapter/wiring.js";
46
48
  import { scheduleBackupSnapshot } from "./backup-schedule.js";
47
49
  import { captureImages, detectPresence, imageJanitor, journalArchive, journalJanitor, journalRecoveryCue, playSound, recordImageArtifactsV3, resetSoundCounters, runSessionSyncExtension, soundForEvent, } from "./effects/index.js";
48
50
  import { toolInputHash, toolTargetHash } from "./events/input-hash.js";
51
+ import { detectClaudeCodeFork } from "./fork-lineage.js";
49
52
  import { canonicalize } from "./guard-path.js";
50
53
  import { beginHookHealth, observeHookDebug, observeHookError, writeHookHealthCompletion, } from "./health.js";
51
54
  import { adapterPidFromEnv, parsePsChainLine, selectAnchorPid } from "./resolve/anchor.js";
52
55
  import { extractIntentComment, resolveIntent } from "./resolve/intent.js";
53
56
  import { resolveOwner } from "./resolve/owner.js";
54
57
  import { inspectSessionNameDisplayImmediately, scanAssistantStatusBoxPresent, scanStatusBoxPresent, scanTranscriptRuntime, } from "./resolve/transcript.js";
58
+ import { clearHookRunMarker, writeHookRunMarker } from "./run-markers.js";
55
59
  import { sessionNamePresence } from "./session-name-presence.js";
60
+ import { shellRmReason } from "./shell-rm.js";
56
61
  import { shellWaiterReason } from "./shell-waiter.js";
57
62
  let hookHealthState;
63
+ let hookRunMarkerPath = null;
58
64
  function parseArgv(argv) {
59
65
  const out = { eventName: null, extra: [] };
60
66
  for (let i = 0; i < argv.length; i++) {
@@ -151,11 +157,13 @@ function logError(coordRoot, err, context) {
151
157
  * Mint or recover the hurricane-style name for this owner in-process. Returns
152
158
  * null on any failure so session.started emission never breaks adapter flow.
153
159
  */
154
- function assignNameInProcess(coordRoot, instanceId, kind, forkedFrom) {
160
+ function assignNameInProcess(coordRoot, instanceId, kind, fork) {
155
161
  try {
156
162
  const name = assignName(coordRoot, instanceId, kind, {
157
163
  freshnessSecs: coordFreshnessSeconds(coordRoot),
158
- ...(forkedFrom ? { forkedFrom } : {}),
164
+ ...(fork?.forkedFrom ? { forkedFrom: fork.forkedFrom } : {}),
165
+ ...(fork?.fork ? { fork: true } : {}),
166
+ ...(fork?.forkChecked ? { forkChecked: true } : {}),
159
167
  });
160
168
  return { name, kind };
161
169
  }
@@ -163,9 +171,60 @@ function assignNameInProcess(coordRoot, instanceId, kind, forkedFrom) {
163
171
  return null;
164
172
  }
165
173
  }
174
+ /**
175
+ * Name a main session, recording fork lineage when the instance is new. Every
176
+ * main-session naming path goes through here: whichever hook first sees a new
177
+ * instance writes its history row, and lineage can only ride that first row
178
+ * (later detection appends a `fork.detected` row instead).
179
+ */
180
+ function assignSessionNameInProcess(coordRoot, instanceId, payload, adapter) {
181
+ let fork;
182
+ try {
183
+ if (adapter === "claude-code" &&
184
+ payload?.session_id === instanceId &&
185
+ !resolveName(coordRoot, instanceId)) {
186
+ const detected = detectClaudeCodeFork({
187
+ coordRoot,
188
+ transcriptPath: payload.transcript_path,
189
+ sessionId: instanceId,
190
+ source: payload.source,
191
+ });
192
+ fork = {
193
+ ...(detected.forkedFrom ? { forkedFrom: detected.forkedFrom } : {}),
194
+ fork: detected.fork,
195
+ forkChecked: detected.checked,
196
+ };
197
+ }
198
+ }
199
+ catch {
200
+ fork = undefined;
201
+ }
202
+ return assignNameInProcess(coordRoot, instanceId, "session", fork);
203
+ }
204
+ /**
205
+ * Finish fork detection that session start could not: a CLI fork starts before
206
+ * its transcript exists, and a mid-flight instance may never see SessionStart.
207
+ * Runs once per instance; the appended `fork_checked` row stops later calls.
208
+ */
209
+ function healForkLineage(coordRoot, instanceId, payload) {
210
+ if (!payload?.transcript_path || payload.session_id !== instanceId)
211
+ return;
212
+ const state = readForkState(coordRoot, instanceId);
213
+ if (!state || state.checked)
214
+ return;
215
+ const detected = detectClaudeCodeFork({
216
+ coordRoot,
217
+ transcriptPath: payload.transcript_path,
218
+ sessionId: instanceId,
219
+ knownFork: state.fork,
220
+ });
221
+ if (!detected.checked)
222
+ return;
223
+ recordForkDetection(coordRoot, instanceId, detected);
224
+ }
166
225
  /** Mid-flight sessions can emit tools before SessionStart assigns a pool name.
167
226
  * Stamp the disposable cache so Codec does not render the 8-character id. */
168
- function ensureSessionDisplayName(coordRoot, instanceId, sessionId, adapter) {
227
+ function ensureSessionDisplayName(coordRoot, instanceId, sessionId, adapter, payload) {
169
228
  if (coordEnv("WORKFLOW_CHILD") === "1")
170
229
  return;
171
230
  const row = readLiveCoordinationRow(coordRoot, instanceId) ?? readHeartbeat(coordRoot, instanceId);
@@ -173,7 +232,7 @@ function ensureSessionDisplayName(coordRoot, instanceId, sessionId, adapter) {
173
232
  return;
174
233
  if (row?.name?.trim())
175
234
  return;
176
- const assigned = assignNameInProcess(coordRoot, instanceId, "session");
235
+ const assigned = assignSessionNameInProcess(coordRoot, instanceId, payload, adapter);
177
236
  if (!assigned?.name)
178
237
  return;
179
238
  if (!readHeartbeat(coordRoot, instanceId)) {
@@ -226,17 +285,21 @@ function buildEventData(eventType, ctx) {
226
285
  // The platform label is the adapter id itself; enumerating and defaulting
227
286
  // to codex silently mislabels any adapter not in the list.
228
287
  const adapterPlatform = ctx.adapter;
229
- // Recorded fork lineage is NOT detected here. On claude-code a fork
230
- // never fires its own session.started — SessionStart fires under the
231
- // PARENT's session id (source=resume) before the fork id is minted
232
- // (verified 2026-08-05) — so detection at this point can only mislabel
233
- // the resumed parent. The fork's new instance is caught by the
234
- // tool.requested heal path instead. The forkedFrom plumbing below stays
235
- // for adapters that DO report a parent at session start.
236
- const forkedFrom = undefined;
237
288
  // Assign (or recover) name + kind in-process. Idempotent: resume
238
- // returns the original name; new owner consumes a counter slot.
239
- const assigned = assignNameInProcess(ctx.coordRoot, ctx.instanceId, "session", forkedFrom);
289
+ // returns the original name; new owner consumes a counter slot and,
290
+ // on claude-code, runs fork detection (fork-lineage.ts). Since Claude
291
+ // Code 2.1.283 both fork flows fire SessionStart under the FORK's own
292
+ // id (verified 2026-10-07), superseding the 2026-08-05 finding that a
293
+ // fork never started on its own id. A resumed parent keeps its existing
294
+ // history row, so it is never relabeled here.
295
+ // Workflow children stay unnamed, as on the tool path: a pool name
296
+ // would make them the addressee of mail held for that name.
297
+ const assigned = coordEnv("WORKFLOW_CHILD") === "1"
298
+ ? undefined
299
+ : assignSessionNameInProcess(ctx.coordRoot, ctx.instanceId, p, ctx.adapter);
300
+ const forkedFrom = assigned
301
+ ? readForkParent(ctx.coordRoot, ctx.instanceId)?.instance_id
302
+ : undefined;
240
303
  // Write the adapter pid-map row so `harn agents whoami` ppid-walks find
241
304
  // this owner. Prefer the payload pid (the actual claude binary), then the
242
305
  // anchor walk (the `node` ancestor for Cursor, which has no payload pid),
@@ -299,8 +362,9 @@ function buildEventData(eventType, ctx) {
299
362
  // SessionStart. Mint durable display identity here so a later
300
363
  // SessionStart remains idempotent and Codec is not stuck on the
301
364
  // 8-character native id.
302
- if (!readLiveCoordinationRow(ctx.coordRoot, ctx.instanceId)?.name) {
303
- assignNameInProcess(ctx.coordRoot, ctx.instanceId, "session");
365
+ if (coordEnv("WORKFLOW_CHILD") !== "1" &&
366
+ !readLiveCoordinationRow(ctx.coordRoot, ctx.instanceId)?.name) {
367
+ assignSessionNameInProcess(ctx.coordRoot, ctx.instanceId, p, ctx.adapter);
304
368
  }
305
369
  const prompt = p?.prompt ?? "";
306
370
  const { value, truncated } = clampString(prompt, 4000);
@@ -475,6 +539,23 @@ async function main() {
475
539
  const { eventName, extra } = parseArgv(process.argv.slice(2));
476
540
  const adapter = detectAdapter(process.argv.slice(2));
477
541
  const behavior = adapter ? adapterBehavior(adapter) : null;
542
+ // Adapters that kill a hook at its timeout get a start marker, so a killed
543
+ // run leaves evidence for doctor (ADR 0197). Written before stdin is read.
544
+ const markerSpec = adapter ? ADAPTER_SPECS[adapter] : undefined;
545
+ const markerTimeout = markerSpec && eventName && markerSpec.events.some((e) => e.subcommand === eventName)
546
+ ? hookTimeoutFor(markerSpec, eventName)
547
+ : undefined;
548
+ if (markerTimeout !== undefined && adapter && eventName && coordEnv("AGENT_COORD_OFF") !== "1") {
549
+ const markerRoot = resolveCoordRoot(process.cwd());
550
+ if (markerRoot) {
551
+ hookRunMarkerPath = writeHookRunMarker(markerRoot, {
552
+ event: eventName,
553
+ adapter,
554
+ pid: process.pid,
555
+ timeout_sec: markerTimeout,
556
+ });
557
+ }
558
+ }
478
559
  const raw = await readStdin();
479
560
  hookHealthState = beginHookHealth({
480
561
  started_at_ms: hookStartedAt,
@@ -619,7 +700,7 @@ async function main() {
619
700
  priorCoordination?.kind !== "transient" &&
620
701
  !priorCoordination?.workflow_run_id &&
621
702
  !priorCoordination?.name?.trim()) {
622
- assignNameInProcess(coordRoot, owner.instance_id, "session");
703
+ assignSessionNameInProcess(coordRoot, owner.instance_id, payload, adapter);
623
704
  }
624
705
  const data = buildEventData(norm.event_type, {
625
706
  coordRoot,
@@ -794,12 +875,20 @@ function recordSignal(run) {
794
875
  }
795
876
  if (norm.event_type !== "session.ended") {
796
877
  try {
797
- ensureSessionDisplayName(coordRoot, owner.instance_id, sessionId, adapter);
878
+ ensureSessionDisplayName(coordRoot, owner.instance_id, sessionId, adapter, payload);
798
879
  }
799
880
  catch (error) {
800
881
  logError(coordRoot, error, { phase: "session-display-name" });
801
882
  }
802
883
  }
884
+ if (norm.event_type === "tool.requested" && adapter === "claude-code" && run.topLevelSession) {
885
+ try {
886
+ healForkLineage(coordRoot, owner.instance_id, payload);
887
+ }
888
+ catch (error) {
889
+ logError(coordRoot, error, { phase: "fork-lineage-heal" });
890
+ }
891
+ }
803
892
  const v3EventId = v3Result && "event" in v3Result
804
893
  ? v3Result.event.event_id
805
894
  : v3Result && "event_id" in v3Result
@@ -941,9 +1030,12 @@ async function handleSessionStarted(run) {
941
1030
  const { autoCleanArtifacts } = await import("../artifacts/index.js");
942
1031
  const { autoCleanEventV3Archives } = await import("../events/v3/archive-retention.js");
943
1032
  const { createAutomaticMaintenanceComposition, runAutomaticMaintenancePass } = await import("../storage/maintenance-providers.js");
944
- // Effect: throttled daily sweep of expired artifact workspaces (guarded,
945
- // managed-expired only; see autoCleanArtifacts). Best-effort like every
946
- // janitor here: a failure logs and never blocks session start.
1033
+ // Effect: throttled hourly artifact sweep (see autoCleanArtifacts). It
1034
+ // deletes expired workspaces, plus unheld workspaces over the per-bundle
1035
+ // ceiling or repository budget once they have been idle past
1036
+ // artifacts.idle_grace_hours. Each deletion is rechecked first and recorded
1037
+ // in .harnery/artifact-deletions.jsonl. Best-effort like every janitor
1038
+ // here: a failure logs and never blocks session start.
947
1039
  try {
948
1040
  autoCleanArtifacts(coordRoot);
949
1041
  }
@@ -1252,6 +1344,12 @@ async function handleToolRequested(run) {
1252
1344
  emitDeny(adapter, waiterReason);
1253
1345
  return 0;
1254
1346
  }
1347
+ const rmReason = shellRmReason(payload?.tool_name, payload?.tool_input, resolveBinName(coordRoot));
1348
+ if (rmReason) {
1349
+ const { emitDeny } = await import("./adapter/output.js");
1350
+ emitDeny(adapter, rmReason);
1351
+ return 0;
1352
+ }
1255
1353
  // G-guard for ALL adapters. Claude Code previously ran this via a
1256
1354
  // pre-tool-use bash adapter (which called `agent-coord verdict --rule=claim`);
1257
1355
  // that adapter is now deleted, so agent-hook owns the deny for every adapter.
@@ -1291,7 +1389,8 @@ async function handlePostToolUse(run) {
1291
1389
  // status is the wrong place to ask.
1292
1390
  try {
1293
1391
  const row = readLiveCoordinationRow(coordRoot, owner.instance_id);
1294
- const name = sessionNameDisplayPending(row);
1392
+ // A workflow child has no user-visible title to set.
1393
+ const name = coordEnv("WORKFLOW_CHILD") === "1" ? undefined : sessionNameDisplayPending(row);
1295
1394
  if (name && toolResponseMintedSessionName(payload?.tool_response, name)) {
1296
1395
  // Record the title before asking for it. The suggestion can still
1297
1396
  // change afterwards (an assigned-name rewrite, a lifecycle re-mint, a
@@ -1469,6 +1568,8 @@ function reportSessionNameObservationUnavailable(coordRoot, instanceId, adapter,
1469
1568
  process.stderr.write(`Harnery: session-name observation unavailable (${reason}); allowing this ${eventName} without display enforcement. The name remains pending.\n`);
1470
1569
  }
1471
1570
  async function enforcePendingSessionNameDisplay(coordRoot, instanceId, adapter, payload, coordination) {
1571
+ if (coordEnv("WORKFLOW_CHILD") === "1")
1572
+ return true;
1472
1573
  const name = sessionNameDisplayPending(coordination);
1473
1574
  if (!name)
1474
1575
  return true;
@@ -1830,6 +1931,11 @@ function cleanupSessionEnd(coordRoot, instanceId) {
1830
1931
  }
1831
1932
  }
1832
1933
  async function emitUserPromptSubmitSystemMessage(coordRoot, instanceId, sessionId, adapter, workspaceCwd, recoveryBriefing = "", hostPromptContext = "") {
1934
+ // Workflow children get no prompt-time coordination context, matching
1935
+ // SessionStart. The turn ritual is not enforced for them, the naming nudge
1936
+ // would register them as named peers, and rendering drains peer mail.
1937
+ if (coordEnv("WORKFLOW_CHILD") === "1")
1938
+ return false;
1833
1939
  const behavior = adapterBehavior(adapter);
1834
1940
  const { renderPromptContext } = await import("../agents/render/prompt-context.js");
1835
1941
  let additionalContext = renderPromptContext({
@@ -1943,6 +2049,7 @@ function completeRecoveryInjection(coordRoot, instanceId, sessionId, recovery) {
1943
2049
  }
1944
2050
  main()
1945
2051
  .then(async (code) => {
2052
+ clearHookRunMarker(hookRunMarkerPath);
1946
2053
  writeHookHealthCompletion(hookHealthState, {
1947
2054
  finished_at_ms: performance.now(),
1948
2055
  finished_rss_bytes: process.memoryUsage().rss,
@@ -1957,6 +2064,7 @@ main()
1957
2064
  pid: process.pid,
1958
2065
  phase: "top-level",
1959
2066
  });
2067
+ clearHookRunMarker(hookRunMarkerPath);
1960
2068
  writeHookHealthCompletion(hookHealthState, {
1961
2069
  finished_at_ms: performance.now(),
1962
2070
  finished_rss_bytes: process.memoryUsage().rss,
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Claude Code fork detection: decide whether a new main-session instance is a
3
+ * branch of another session, and which one.
4
+ *
5
+ * Two shapes exist as of Claude Code 2.1.283 (verified 2026-10-07):
6
+ *
7
+ * - CLI `--resume <id> --fork-session` fires SessionStart under the FORK's id
8
+ * with `source: "fork"`, before its transcript exists, and names no parent.
9
+ * The transcript later holds the parent's message uuids with every row's
10
+ * `sessionId` rewritten, so the parent is found by uuid containment
11
+ * (`detectForkParent`) once the transcript is on disk.
12
+ * - The desktop app's "Fork from here" copies the parent's rows into the
13
+ * fork's transcript with their original `sessionId`, so inherited rows
14
+ * name the parent directly (`detectInheritedSessionParent`).
15
+ *
16
+ * Inherited rows alone do not prove a fork: a continuation of a finished
17
+ * session can carry them too. The parent's liveness separates the two. A
18
+ * parent with an unended generation is still running (or resumable) and owns
19
+ * its name, task, and claims, so the new instance is a fork. A finished
20
+ * parent makes it a continuation, which keeps the generic notice.
21
+ *
22
+ * Everything here fails open: an unreadable transcript or an unknown layout
23
+ * yields "not a fork", never an error.
24
+ */
25
+ export interface ForkDetection {
26
+ fork: boolean;
27
+ forkedFrom?: string;
28
+ /** Detection had the evidence it needs; the tool-path heal can skip it. */
29
+ checked: boolean;
30
+ }
31
+ export declare function detectClaudeCodeFork(input: {
32
+ coordRoot: string;
33
+ transcriptPath: string | undefined;
34
+ sessionId: string;
35
+ source?: string;
36
+ /** The instance was already recorded as a fork without a parent. */
37
+ knownFork?: boolean;
38
+ isLive?: (instanceId: string) => boolean;
39
+ }): ForkDetection;
40
+ //# sourceMappingURL=fork-lineage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fork-lineage.d.ts","sourceRoot":"","sources":["../../../src/core/hooks/fork-lineage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,OAAO,EAAE,OAAO,CAAC;CAClB;AAKD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;CAC1C,GAAG,aAAa,CAkChB"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Claude Code fork detection: decide whether a new main-session instance is a
3
+ * branch of another session, and which one.
4
+ *
5
+ * Two shapes exist as of Claude Code 2.1.283 (verified 2026-10-07):
6
+ *
7
+ * - CLI `--resume <id> --fork-session` fires SessionStart under the FORK's id
8
+ * with `source: "fork"`, before its transcript exists, and names no parent.
9
+ * The transcript later holds the parent's message uuids with every row's
10
+ * `sessionId` rewritten, so the parent is found by uuid containment
11
+ * (`detectForkParent`) once the transcript is on disk.
12
+ * - The desktop app's "Fork from here" copies the parent's rows into the
13
+ * fork's transcript with their original `sessionId`, so inherited rows
14
+ * name the parent directly (`detectInheritedSessionParent`).
15
+ *
16
+ * Inherited rows alone do not prove a fork: a continuation of a finished
17
+ * session can carry them too. The parent's liveness separates the two. A
18
+ * parent with an unended generation is still running (or resumable) and owns
19
+ * its name, task, and claims, so the new instance is a fork. A finished
20
+ * parent makes it a continuation, which keeps the generic notice.
21
+ *
22
+ * Everything here fails open: an unreadable transcript or an unknown layout
23
+ * yields "not a fork", never an error.
24
+ */
25
+ import { existsSync } from "node:fs";
26
+ import { readLiveCoordinationRow } from "../agents/state/live-coordination-view.js";
27
+ import { detectForkParent, detectInheritedSessionParent } from "./resolve/transcript.js";
28
+ /** Sources after which a brand-new instance cannot hold inherited history. */
29
+ const FRESH_SOURCES = new Set(["startup", "clear"]);
30
+ export function detectClaudeCodeFork(input) {
31
+ try {
32
+ const declared = input.source === "fork" || input.knownFork === true;
33
+ const transcriptReady = !!input.transcriptPath && existsSync(input.transcriptPath);
34
+ const isLive = input.isLive ?? ((id) => readLiveCoordinationRow(input.coordRoot, id) !== null);
35
+ const inherited = transcriptReady
36
+ ? detectInheritedSessionParent(input.transcriptPath, input.sessionId)
37
+ : undefined;
38
+ if (inherited && inherited !== input.sessionId) {
39
+ if (declared || isLive(inherited)) {
40
+ return { fork: true, forkedFrom: inherited, checked: true };
41
+ }
42
+ return { fork: false, checked: true };
43
+ }
44
+ if (declared) {
45
+ if (!transcriptReady)
46
+ return { fork: true, checked: false };
47
+ const parent = detectForkParent(input.transcriptPath, input.sessionId);
48
+ return {
49
+ fork: true,
50
+ ...(parent && parent !== input.sessionId ? { forkedFrom: parent } : {}),
51
+ checked: true,
52
+ };
53
+ }
54
+ return {
55
+ fork: false,
56
+ checked: transcriptReady || FRESH_SOURCES.has(input.source ?? ""),
57
+ };
58
+ }
59
+ catch {
60
+ return { fork: false, checked: true };
61
+ }
62
+ }
@@ -92,6 +92,22 @@ export interface TranscriptRuntimeScan {
92
92
  * SessionStart).
93
93
  */
94
94
  export declare function scanTranscriptRuntime(transcriptPath: string | undefined): TranscriptRuntimeScan | undefined;
95
+ /**
96
+ * Detect inherited history from row session ids: the session whose rows were
97
+ * copied into this transcript, or undefined when every row is this session's.
98
+ *
99
+ * Empirical basis (verified 2026-10-07, Claude Code 2.1.283): the desktop
100
+ * app's "Fork from here" copies the parent's rows into the fork's transcript
101
+ * WITHOUT rewriting their `sessionId`, so the fork's file opens with thousands
102
+ * of rows stamped with the parent's id. The CLI `--fork-session` path rewrites
103
+ * the ids instead and is covered by {@link detectForkParent}.
104
+ *
105
+ * When the history is itself several generations deep, the LAST foreign row is
106
+ * the nearest ancestor, so the tail is scanned first. Whether the foreign
107
+ * session is a fork parent or a dead predecessor (a continuation) is the
108
+ * caller's call. Fail-soft: never throws, undefined on any read problem.
109
+ */
110
+ export declare function detectInheritedSessionParent(transcriptPath: string | undefined, sessionId: string): string | undefined;
95
111
  /**
96
112
  * Detect the parent session of a forked CC conversation from its transcript.
97
113
  *
@@ -1 +1 @@
1
- {"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/resolve/transcript.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,2BAA2B,wBAAc,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAQhF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACvC,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,MAAM,EAAE,MAAM,GACb,OAAO,CAiCT;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,oBAAoB,EAAE,MAAM,GAAG,SAAS,GACvC,OAAO,CAKT;AAED,kFAAkF;AAClF,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAgB9F;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CACjD,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,GAC/D,OAAO,CAIT;AAED,MAAM,MAAM,4BAA4B,GACpC;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,QAAQ,CAAA;CAAE,GACnB;IACE,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,oBAAoB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;CAClF,CAAC;AAEN;;;;;GAKG;AACH,wBAAgB,oCAAoC,CAClD,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,GAC/D,4BAA4B,CAqD9B;AAgBD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAUrF;AAwDD;4CAC4C;AAC5C,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd;+EAC2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC,qBAAqB,GAAG,SAAS,CA8BnC;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAkDpB"}
1
+ {"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/resolve/transcript.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,2BAA2B,wBAAc,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAQhF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACvC,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,MAAM,EAAE,MAAM,GACb,OAAO,CAiCT;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,oBAAoB,EAAE,MAAM,GAAG,SAAS,GACvC,OAAO,CAKT;AAED,kFAAkF;AAClF,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAgB9F;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CACjD,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,GAC/D,OAAO,CAIT;AAED,MAAM,MAAM,4BAA4B,GACpC;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,QAAQ,CAAA;CAAE,GACnB;IACE,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,oBAAoB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;CAClF,CAAC;AAEN;;;;;GAKG;AACH,wBAAgB,oCAAoC,CAClD,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,GAC/D,4BAA4B,CAqD9B;AAgBD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAUrF;AAwDD;4CAC4C;AAC5C,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd;+EAC2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC,qBAAqB,GAAG,SAAS,CA8BnC;AAgBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,4BAA4B,CAC1C,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAiBpB;AA6CD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAkDpB"}