aiwcli 0.15.4 → 0.15.7

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 (299) hide show
  1. package/README.md +6 -3
  2. package/dist/capabilities/branch/adapters.d.ts +2 -0
  3. package/dist/capabilities/branch/adapters.js +21 -0
  4. package/dist/capabilities/branch/contracts.d.ts +57 -0
  5. package/dist/capabilities/branch/contracts.js +1 -0
  6. package/dist/capabilities/branch/control-plane.d.ts +2 -0
  7. package/dist/capabilities/branch/control-plane.js +343 -0
  8. package/dist/capabilities/branch/runtime-core.d.ts +5 -0
  9. package/dist/capabilities/branch/runtime-core.js +36 -0
  10. package/dist/capabilities/installation/control-plane/clean-command.d.ts +41 -0
  11. package/dist/capabilities/installation/control-plane/clean-command.js +196 -0
  12. package/dist/capabilities/installation/control-plane/clear-command.d.ts +160 -0
  13. package/dist/capabilities/installation/control-plane/clear-command.js +1220 -0
  14. package/dist/capabilities/installation/control-plane/init-command.d.ts +81 -0
  15. package/dist/capabilities/installation/control-plane/init-command.js +449 -0
  16. package/dist/capabilities/launch/contracts.d.ts +51 -0
  17. package/dist/capabilities/launch/contracts.js +1 -0
  18. package/dist/capabilities/launch/control-plane/execute-launch.d.ts +2 -0
  19. package/dist/capabilities/launch/control-plane/execute-launch.js +222 -0
  20. package/dist/capabilities/launch/runtime-core/launch-options.d.ts +14 -0
  21. package/dist/capabilities/launch/runtime-core/launch-options.js +69 -0
  22. package/dist/cli/base-command.d.ts +18 -0
  23. package/dist/cli/base-command.js +55 -0
  24. package/dist/commands/branch.d.ts +0 -20
  25. package/dist/commands/branch.js +24 -416
  26. package/dist/commands/clean.d.ts +1 -41
  27. package/dist/commands/clean.js +1 -196
  28. package/dist/commands/clear.d.ts +1 -161
  29. package/dist/commands/clear.js +1 -1121
  30. package/dist/commands/init/index.d.ts +1 -98
  31. package/dist/commands/init/index.js +4 -478
  32. package/dist/commands/launch.d.ts +36 -11
  33. package/dist/commands/launch.js +135 -159
  34. package/dist/lib/base-command.d.ts +1 -114
  35. package/dist/lib/base-command.js +1 -153
  36. package/dist/lib/claude-settings-types.d.ts +31 -19
  37. package/dist/lib/context/context-formatter.d.ts +74 -0
  38. package/dist/lib/context/context-formatter.js +493 -0
  39. package/dist/lib/context/context-selector.d.ts +42 -0
  40. package/dist/lib/context/context-selector.js +451 -0
  41. package/dist/lib/context/context-store.d.ts +100 -0
  42. package/dist/lib/context/context-store.js +618 -0
  43. package/dist/lib/context/plan-manager.d.ts +54 -0
  44. package/dist/lib/context/plan-manager.js +282 -0
  45. package/dist/lib/context/task-tracker.d.ts +44 -0
  46. package/dist/lib/context/task-tracker.js +146 -0
  47. package/dist/lib/core-ide-base.d.ts +4 -0
  48. package/dist/lib/core-ide-base.js +77 -0
  49. package/dist/lib/core-installer.d.ts +5 -0
  50. package/dist/lib/core-installer.js +54 -0
  51. package/dist/lib/git-exclude-manager.d.ts +2 -2
  52. package/dist/lib/git-exclude-manager.js +3 -3
  53. package/dist/lib/hooks/hook-utils.d.ts +143 -0
  54. package/dist/lib/hooks/hook-utils.js +609 -0
  55. package/dist/lib/hooks/session-end-logic.d.ts +5 -0
  56. package/dist/lib/hooks/session-end-logic.js +63 -0
  57. package/dist/lib/hooks-merger.js +25 -19
  58. package/dist/lib/ide-path-resolver.d.ts +19 -7
  59. package/dist/lib/ide-path-resolver.js +25 -9
  60. package/dist/lib/install-state.d.ts +34 -0
  61. package/dist/lib/install-state.js +161 -0
  62. package/dist/lib/launch-options.d.ts +1 -0
  63. package/dist/lib/launch-options.js +1 -0
  64. package/dist/lib/lsp-patch.d.ts +12 -0
  65. package/dist/lib/lsp-patch.js +156 -0
  66. package/dist/lib/multiplexer.d.ts +57 -0
  67. package/dist/lib/multiplexer.js +19 -0
  68. package/dist/lib/multiplexers/psmux.d.ts +75 -0
  69. package/dist/lib/multiplexers/psmux.js +384 -0
  70. package/dist/lib/multiplexers/tmux.d.ts +44 -0
  71. package/dist/lib/multiplexers/tmux.js +262 -0
  72. package/dist/lib/mux-utils.d.ts +5 -0
  73. package/dist/lib/mux-utils.js +42 -0
  74. package/dist/lib/paths.d.ts +2 -2
  75. package/dist/lib/paths.js +2 -2
  76. package/dist/lib/platform-commands.d.ts +27 -0
  77. package/dist/lib/platform-commands.js +49 -0
  78. package/dist/lib/runtime/aiw-cli.d.ts +37 -0
  79. package/dist/lib/runtime/aiw-cli.js +74 -0
  80. package/dist/lib/runtime/atomic-write.d.ts +19 -0
  81. package/dist/lib/runtime/atomic-write.js +121 -0
  82. package/dist/lib/runtime/cli-args.d.ts +55 -0
  83. package/dist/lib/runtime/cli-args.js +185 -0
  84. package/dist/lib/runtime/constants.d.ts +56 -0
  85. package/dist/lib/runtime/constants.js +230 -0
  86. package/dist/lib/runtime/executable-policy.d.ts +16 -0
  87. package/dist/lib/runtime/executable-policy.js +57 -0
  88. package/dist/lib/runtime/git-state.d.ts +9 -0
  89. package/dist/lib/runtime/git-state.js +59 -0
  90. package/dist/lib/runtime/inference.d.ts +37 -0
  91. package/dist/lib/runtime/inference.js +262 -0
  92. package/dist/lib/runtime/lint-dispatch.d.ts +40 -0
  93. package/dist/lib/runtime/lint-dispatch.js +285 -0
  94. package/dist/lib/runtime/logger.d.ts +66 -0
  95. package/dist/lib/runtime/logger.js +201 -0
  96. package/dist/lib/runtime/models.d.ts +14 -0
  97. package/dist/lib/runtime/models.js +14 -0
  98. package/dist/lib/runtime/platform-adapter.d.ts +7 -0
  99. package/dist/lib/runtime/platform-adapter.js +21 -0
  100. package/dist/lib/runtime/preflight.d.ts +24 -0
  101. package/dist/lib/runtime/preflight.js +65 -0
  102. package/dist/lib/runtime/sentinel-ipc.d.ts +14 -0
  103. package/dist/lib/runtime/sentinel-ipc.js +67 -0
  104. package/dist/lib/runtime/state-io.d.ts +30 -0
  105. package/dist/lib/runtime/state-io.js +174 -0
  106. package/dist/lib/runtime/stop-words.d.ts +20 -0
  107. package/dist/lib/runtime/stop-words.js +150 -0
  108. package/dist/lib/runtime/subprocess-utils.d.ts +29 -0
  109. package/dist/lib/runtime/subprocess-utils.js +96 -0
  110. package/dist/lib/runtime/tmux-preflight.d.ts +13 -0
  111. package/dist/lib/runtime/tmux-preflight.js +78 -0
  112. package/dist/lib/runtime/utils.d.ts +54 -0
  113. package/dist/lib/runtime/utils.js +162 -0
  114. package/dist/lib/sentinel-wrapper.d.ts +9 -0
  115. package/dist/lib/sentinel-wrapper.js +20 -0
  116. package/dist/lib/shell-quoting.d.ts +5 -0
  117. package/dist/lib/shell-quoting.js +17 -0
  118. package/dist/lib/spawn-errors.d.ts +6 -0
  119. package/dist/lib/spawn-errors.js +15 -0
  120. package/dist/lib/spawn.js +5 -11
  121. package/dist/lib/template-installer.d.ts +4 -5
  122. package/dist/lib/template-installer.js +36 -34
  123. package/dist/lib/template-resolver.d.ts +6 -7
  124. package/dist/lib/template-resolver.js +26 -21
  125. package/dist/lib/template-settings-reconstructor.d.ts +7 -2
  126. package/dist/lib/template-settings-reconstructor.js +76 -45
  127. package/dist/lib/terminal-strategy.d.ts +11 -0
  128. package/dist/lib/terminal-strategy.js +49 -0
  129. package/dist/lib/terminal.d.ts +28 -0
  130. package/dist/lib/terminal.js +162 -112
  131. package/dist/lib/tmux-pane-placement.d.ts +17 -0
  132. package/dist/lib/tmux-pane-placement.js +58 -0
  133. package/dist/lib/tmux-primitives.d.ts +5 -0
  134. package/dist/lib/tmux-primitives.js +15 -0
  135. package/dist/lib/tmux-session.d.ts +32 -0
  136. package/dist/lib/tmux-session.js +86 -0
  137. package/dist/lib/tty-detection.js +1 -1
  138. package/dist/lib/types.d.ts +168 -0
  139. package/dist/lib/types.js +6 -0
  140. package/dist/lib/version.d.ts +1 -1
  141. package/dist/lib/version.js +1 -1
  142. package/dist/platform/launch.d.ts +10 -0
  143. package/dist/platform/launch.js +10 -0
  144. package/dist/templates/CLAUDE.md +31 -40
  145. package/dist/templates/cc-native/.claude/settings.json +27 -27
  146. package/dist/templates/cc-native/CC-NATIVE-README.md +1 -1
  147. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +10 -9
  148. package/dist/templates/cc-native/_cc-native/CLAUDE.md +18 -18
  149. package/dist/templates/cc-native/_cc-native/artifacts/CLAUDE.md +3 -3
  150. package/dist/templates/cc-native/_cc-native/artifacts/lib/format.ts +14 -14
  151. package/dist/templates/cc-native/_cc-native/artifacts/lib/tracker.ts +1 -1
  152. package/dist/templates/cc-native/_cc-native/artifacts/lib/write.ts +3 -3
  153. package/dist/templates/cc-native/_cc-native/cc-native.config.json +3 -3
  154. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +16 -15
  155. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +3 -3
  156. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +2 -2
  157. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +2 -2
  158. package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +3 -3
  159. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +2 -2
  160. package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +3 -3
  161. package/dist/templates/cc-native/_cc-native/lib-ts/CLAUDE.md +8 -8
  162. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +1 -1
  163. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +4 -4
  164. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +1 -1
  165. package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +1 -1
  166. package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +1 -1
  167. package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +1 -1
  168. package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +2 -2
  169. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +1 -1
  170. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +2 -2
  171. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +1 -1
  172. package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +8 -8
  173. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +3 -3
  174. package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +2 -2
  175. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +3 -3
  176. package/dist/templates/cc-native/_cc-native/plan-review/CLAUDE.md +3 -1
  177. package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/agent-selection.test.ts +345 -0
  178. package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/preflight.test.ts +344 -0
  179. package/dist/templates/cc-native/_cc-native/plan-review/lib/agent-selection.ts +37 -15
  180. package/dist/templates/cc-native/_cc-native/plan-review/lib/corroboration.ts +16 -69
  181. package/dist/templates/cc-native/_cc-native/plan-review/lib/orchestrator.ts +1 -1
  182. package/dist/templates/cc-native/_cc-native/plan-review/lib/output-builder.ts +1 -1
  183. package/dist/templates/cc-native/_cc-native/plan-review/lib/plan-questions.ts +2 -2
  184. package/dist/templates/cc-native/_cc-native/plan-review/lib/preflight.ts +56 -26
  185. package/dist/templates/cc-native/_cc-native/plan-review/lib/review-pipeline.ts +7 -7
  186. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/agent.ts +4 -4
  187. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/base/base-agent.ts +3 -3
  188. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/index.ts +1 -1
  189. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/claude-agent.ts +2 -2
  190. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/codex-agent.ts +4 -4
  191. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/gemini-agent.ts +1 -1
  192. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/orchestrator-claude-agent.ts +5 -6
  193. package/dist/templates/core/.codex/workflows/codex.md +17 -0
  194. package/dist/templates/core/.codex/workflows/handoff.md +5 -0
  195. package/dist/templates/core/.codex/workflows/meta-plan.md +7 -0
  196. package/dist/templates/core/.cognition/AGENTS.md +5 -0
  197. package/dist/templates/core/.cognition/config.json +12 -0
  198. package/dist/templates/{_shared → core}/.windsurf/workflows/handoff.md +1 -1
  199. package/dist/templates/{_shared → core}/.windsurf/workflows/meta-plan.md +1 -1
  200. package/dist/templates/core/hooks-ts/_utils/git-state.ts +2 -0
  201. package/dist/templates/{_shared → core}/hooks-ts/archive_plan.ts +14 -23
  202. package/dist/templates/core/hooks-ts/codex_explorer.ts +160 -0
  203. package/dist/templates/{_shared → core}/hooks-ts/context_monitor.ts +23 -55
  204. package/dist/templates/{_shared → core}/hooks-ts/file-suggestion.ts +4 -3
  205. package/dist/templates/{_shared → core}/hooks-ts/lint_after_edit.ts +7 -9
  206. package/dist/templates/{_shared → core}/hooks-ts/pre_compact.ts +5 -5
  207. package/dist/templates/{_shared → core}/hooks-ts/session_end.ts +38 -78
  208. package/dist/templates/{_shared → core}/hooks-ts/session_start.ts +5 -5
  209. package/dist/templates/core/hooks-ts/task_create_capture.ts +32 -0
  210. package/dist/templates/{_shared → core}/hooks-ts/task_update_capture.ts +9 -24
  211. package/dist/templates/core/hooks-ts/user_prompt_submit.ts +46 -0
  212. package/dist/templates/{_shared → core}/lib-ts/CLAUDE.md +27 -16
  213. package/dist/templates/{_shared → core}/lib-ts/agent-exec/backends/headless.ts +3 -2
  214. package/dist/templates/{_shared → core}/lib-ts/agent-exec/backends/tmux.ts +44 -15
  215. package/dist/templates/{_shared → core}/lib-ts/agent-exec/base-agent.ts +6 -4
  216. package/dist/templates/{_shared → core}/lib-ts/agent-exec/execution-backend.ts +1 -1
  217. package/dist/templates/{_shared → core}/lib-ts/agent-exec/index.ts +2 -2
  218. package/dist/templates/{_shared → core}/lib-ts/agent-exec/structured-output.ts +4 -5
  219. package/dist/templates/{_shared → core}/lib-ts/context/CLAUDE.md +9 -6
  220. package/dist/templates/{_shared → core}/lib-ts/context/context-formatter.ts +16 -21
  221. package/dist/templates/{_shared → core}/lib-ts/context/context-selector.ts +8 -6
  222. package/dist/templates/{_shared → core}/lib-ts/context/context-store.ts +32 -20
  223. package/dist/templates/{_shared → core}/lib-ts/context/plan-manager.ts +19 -15
  224. package/dist/templates/{_shared → core}/lib-ts/context/task-tracker.ts +3 -3
  225. package/dist/templates/core/lib-ts/hooks/context-monitor-logic.ts +32 -0
  226. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/hooks}/hook-utils.ts +168 -41
  227. package/dist/templates/core/lib-ts/hooks/prompt-binding-logic.ts +80 -0
  228. package/dist/templates/core/lib-ts/hooks/session-end-logic.ts +93 -0
  229. package/dist/templates/core/lib-ts/package.json +19 -0
  230. package/dist/templates/core/lib-ts/runtime/agent-launcher.ts +295 -0
  231. package/dist/templates/core/lib-ts/runtime/aiw-cli.ts +106 -0
  232. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/atomic-write.ts +12 -7
  233. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/cli-args.ts +8 -6
  234. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/constants.ts +326 -324
  235. package/dist/templates/core/lib-ts/runtime/executable-policy.ts +89 -0
  236. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/git-state.ts +6 -4
  237. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/inference.ts +59 -10
  238. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/lint-dispatch.ts +25 -23
  239. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/logger.ts +32 -29
  240. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/models.ts +2 -2
  241. package/dist/templates/core/lib-ts/runtime/platform-adapter.ts +33 -0
  242. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/preflight.ts +4 -3
  243. package/dist/templates/core/lib-ts/runtime/sentinel-ipc.ts +91 -0
  244. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/state-io.ts +11 -7
  245. package/dist/templates/core/lib-ts/runtime/stop-words.ts +185 -0
  246. package/dist/templates/core/lib-ts/runtime/subprocess-utils.ts +147 -0
  247. package/dist/templates/core/lib-ts/runtime/tmux-preflight.ts +93 -0
  248. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/utils.ts +4 -3
  249. package/dist/templates/{_shared → core}/lib-ts/templates/formatters.ts +7 -5
  250. package/dist/templates/{_shared → core}/lib-ts/templates/plan-context.ts +2 -1
  251. package/dist/templates/{_shared → core}/lib-ts/tsconfig.json +3 -1
  252. package/dist/templates/{_shared → core}/lib-ts/types.ts +78 -77
  253. package/dist/templates/core/scripts/resolve-run.ts +61 -0
  254. package/dist/templates/{_shared → core}/scripts/resolve_context.ts +3 -3
  255. package/dist/templates/{_shared → core}/scripts/status_line.ts +25 -20
  256. package/dist/templates/core/skills/codex/CLAUDE.md +78 -0
  257. package/dist/templates/{_shared → core}/skills/codex/SKILL.md +21 -18
  258. package/dist/templates/{_shared → core}/skills/codex/lib/codex-watcher.ts +76 -103
  259. package/dist/templates/{_shared → core}/skills/codex/scripts/launch-codex.ts +119 -133
  260. package/dist/templates/{_shared → core}/skills/codex/scripts/watch-codex.ts +6 -4
  261. package/dist/templates/core/skills/devin/CLAUDE.md +65 -0
  262. package/dist/templates/core/skills/devin/SKILL.md +73 -0
  263. package/dist/templates/core/skills/devin/lib/devin-watcher.ts +280 -0
  264. package/dist/templates/core/skills/devin/scripts/launch-devin.ts +257 -0
  265. package/dist/templates/{_shared → core}/skills/handoff-system/CLAUDE.md +436 -433
  266. package/dist/templates/{_shared → core}/skills/handoff-system/lib/document-generator.ts +9 -7
  267. package/dist/templates/{_shared → core}/skills/handoff-system/lib/handoff-reader.ts +6 -4
  268. package/dist/templates/{_shared → core}/skills/handoff-system/scripts/resume_handoff.ts +10 -8
  269. package/dist/templates/{_shared → core}/skills/handoff-system/scripts/save_handoff.ts +12 -10
  270. package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff-resume.md +2 -2
  271. package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff.md +6 -5
  272. package/dist/templates/{_shared → core}/skills/meta-plan/CLAUDE.md +2 -1
  273. package/dist/templates/{_shared → core}/skills/meta-plan/workflows/meta-plan.md +8 -7
  274. package/oclif.manifest.json +89 -13
  275. package/package.json +13 -12
  276. package/dist/templates/_shared/.claude/settings.json +0 -120
  277. package/dist/templates/_shared/.claude/skills/codex/SKILL.md +0 -35
  278. package/dist/templates/_shared/.claude/skills/handoff/SKILL.md +0 -13
  279. package/dist/templates/_shared/.claude/skills/handoff-resume/SKILL.md +0 -13
  280. package/dist/templates/_shared/.claude/skills/meta-plan/SKILL.md +0 -43
  281. package/dist/templates/_shared/.codex/workflows/codex.md +0 -11
  282. package/dist/templates/_shared/.codex/workflows/handoff.md +0 -226
  283. package/dist/templates/_shared/.codex/workflows/meta-plan.md +0 -347
  284. package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +0 -2
  285. package/dist/templates/_shared/hooks-ts/task_create_capture.ts +0 -48
  286. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +0 -93
  287. package/dist/templates/_shared/lib-ts/base/launchers/tmux-launcher.ts +0 -173
  288. package/dist/templates/_shared/lib-ts/base/launchers/window-launcher.ts +0 -93
  289. package/dist/templates/_shared/lib-ts/base/launchers/wt-launcher.ts +0 -64
  290. package/dist/templates/_shared/lib-ts/base/pane-launcher.ts +0 -55
  291. package/dist/templates/_shared/lib-ts/base/sentinel-ipc.ts +0 -87
  292. package/dist/templates/_shared/lib-ts/base/stop-words.ts +0 -184
  293. package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +0 -249
  294. package/dist/templates/_shared/lib-ts/base/tmux-driver.ts +0 -341
  295. package/dist/templates/_shared/lib-ts/base/tmux-pane-placement.ts +0 -78
  296. package/dist/templates/_shared/lib-ts/package.json +0 -20
  297. package/dist/templates/_shared/scripts/resolve-run.ts +0 -62
  298. package/dist/templates/_shared/skills/codex/CLAUDE.md +0 -70
  299. /package/dist/templates/{_shared → core}/lib-ts/agent-exec/backends/index.ts +0 -0
@@ -8,9 +8,9 @@
8
8
  */
9
9
 
10
10
  import * as fs from "node:fs";
11
- import * as path from "node:path";
11
+ import path from "node:path";
12
12
 
13
- import { atomicWrite } from "../base/atomic-write.js";
13
+ import { atomicWrite } from "../runtime/atomic-write.js";
14
14
  import {
15
15
  getContextDir,
16
16
  getContextsDir,
@@ -19,14 +19,17 @@ import {
19
19
  getArchiveContextDir,
20
20
  getArchiveIndexPath,
21
21
  validateContextId,
22
- } from "../base/constants.js";
23
- import { logInfo, logWarn, logError, setContextPath } from "../base/logger.js";
24
- import { readStateJson, writeStateJson } from "../base/state-io.js";
25
- import { nowIso, generateContextId } from "../base/utils.js";
22
+ } from "../runtime/constants.js";
23
+ import { logInfo, logWarn, logError, setContextPath } from "../runtime/logger.js";
24
+ import { readStateJson, writeStateJson } from "../runtime/state-io.js";
25
+ import { nowIso, generateContextId } from "../runtime/utils.js";
26
26
  import type { ContextState, IndexFile, IndexEntry, Mode } from "../types.js";
27
27
 
28
28
  const INDEX_VERSION = "3.0";
29
29
 
30
+ // Module-level index cache — safe because each hook is a separate bun process
31
+ let _indexCache: IndexFile | null = null;
32
+
30
33
  // ---------------------------------------------------------------------------
31
34
  // Public utilities
32
35
  // ---------------------------------------------------------------------------
@@ -73,25 +76,31 @@ export function determineArtifactType(
73
76
  // ---------------------------------------------------------------------------
74
77
 
75
78
  function loadIndex(projectRoot?: string): IndexFile {
79
+ if (_indexCache) return _indexCache;
76
80
  const indexPath = getIndexPath(projectRoot);
77
81
  if (fs.existsSync(indexPath)) {
78
82
  try {
79
- const raw = fs.readFileSync(indexPath, "utf-8");
80
- return JSON.parse(raw) as IndexFile;
81
- } catch (error: any) {
83
+ const raw = fs.readFileSync(indexPath, "utf8");
84
+ _indexCache = JSON.parse(raw) as IndexFile;
85
+ return _indexCache;
86
+ } catch (error: unknown) {
82
87
  logWarn("context_store", `Failed to read index, recreating: ${error}`);
83
88
  }
84
89
  }
85
- return { version: INDEX_VERSION, updated_at: nowIso(), sessions: {}, contexts: {} };
90
+ const fresh: IndexFile = { version: INDEX_VERSION, updated_at: nowIso(), sessions: {}, contexts: {} };
91
+ _indexCache = fresh;
92
+ return fresh;
86
93
  }
87
94
 
88
95
  function saveIndex(index: IndexFile, projectRoot?: string): boolean {
89
96
  index.updated_at = nowIso();
90
97
  const content = JSON.stringify(index, null, 2);
91
- const [success, error] = atomicWrite(getIndexPath(projectRoot), content);
98
+ // fsync: false index.json is reconstructable by scanning _output/contexts/
99
+ const [success, error] = atomicWrite(getIndexPath(projectRoot), content, 2, [500, 1000], false);
92
100
  if (!success) {
93
101
  logWarn("context_store", `Failed to write index: ${error}`);
94
102
  }
103
+ _indexCache = index;
95
104
  return success;
96
105
  }
97
106
 
@@ -111,7 +120,7 @@ function migrateContextJson(contextId: string, projectRoot?: string): ContextSta
111
120
  if (!fs.existsSync(legacyPath)) return null;
112
121
 
113
122
  try {
114
- const data = JSON.parse(fs.readFileSync(legacyPath, "utf-8"));
123
+ const data = JSON.parse(fs.readFileSync(legacyPath, "utf8"));
115
124
  const inFlight = data.in_flight ?? {};
116
125
  const oldMode = inFlight.mode ?? "none";
117
126
  const MODE_MIGRATION: Record<string, string> = {
@@ -149,7 +158,7 @@ function migrateContextJson(contextId: string, projectRoot?: string): ContextSta
149
158
  last_session: null,
150
159
  tasks: [],
151
160
  };
152
- } catch (error: any) {
161
+ } catch (error: unknown) {
153
162
  logWarn("context_store", `Failed to migrate context.json for '${contextId}': ${error}`);
154
163
  return null;
155
164
  }
@@ -493,7 +502,7 @@ export function maybeActivate(
493
502
 
494
503
  if (state.mode === "idle" || state.mode === "has_staged_work") {
495
504
  const oldMode = state.mode;
496
- const opts: Record<string, any> = {};
505
+ const opts: Record<string, unknown> = {};
497
506
  if (oldMode === "has_staged_work") opts.work_consumed = true; // CHANGED: unified flag
498
507
  updateMode(contextId, "active", projectRoot, opts);
499
508
  logInfo(
@@ -560,7 +569,7 @@ export function archiveContext(contextId: string, projectRoot?: string): Context
560
569
 
561
570
  try {
562
571
  fs.renameSync(sourceDir, archiveDest);
563
- } catch (error: any) {
572
+ } catch (error: unknown) {
564
573
  logError("context_store", `Failed to move context to archive: ${error}`);
565
574
  return null;
566
575
  }
@@ -650,8 +659,8 @@ function updateArchiveIndex(state: ContextState, projectRoot?: string): boolean
650
659
 
651
660
  if (fs.existsSync(archiveIndexPath)) {
652
661
  try {
653
- archiveIndex = JSON.parse(fs.readFileSync(archiveIndexPath, "utf-8"));
654
- } catch (error_: any) {
662
+ archiveIndex = JSON.parse(fs.readFileSync(archiveIndexPath, "utf8"));
663
+ } catch (error_: unknown) {
655
664
  logWarn("context_store", `Failed to read archive index, recreating: ${error_}`);
656
665
  }
657
666
  }
@@ -679,7 +688,7 @@ function restoreFromArchive(contextId: string, projectRoot?: string): ContextSta
679
688
 
680
689
  try {
681
690
  fs.renameSync(archiveDir, activeDir);
682
- } catch (error: any) {
691
+ } catch (error: unknown) {
683
692
  logError("context_store", `Failed to restore context from archive: ${error}`);
684
693
  return null;
685
694
  }
@@ -697,7 +706,7 @@ function removeFromArchiveIndex(contextId: string, projectRoot?: string): boolea
697
706
  if (!fs.existsSync(archiveIndexPath)) return true;
698
707
 
699
708
  try {
700
- const archiveIndex = JSON.parse(fs.readFileSync(archiveIndexPath, "utf-8")) as IndexFile;
709
+ const archiveIndex = JSON.parse(fs.readFileSync(archiveIndexPath, "utf8")) as IndexFile;
701
710
  if (archiveIndex.contexts[contextId]) {
702
711
  delete archiveIndex.contexts[contextId];
703
712
  archiveIndex.updated_at = nowIso();
@@ -709,8 +718,11 @@ function removeFromArchiveIndex(contextId: string, projectRoot?: string): boolea
709
718
  }
710
719
  }
711
720
  return true;
712
- } catch (error: any) {
721
+ } catch (error: unknown) {
713
722
  logWarn("context_store", `Failed to read archive index: ${error}`);
714
723
  return false;
715
724
  }
716
725
  }
726
+
727
+
728
+
@@ -10,12 +10,12 @@
10
10
 
11
11
  import * as crypto from "node:crypto";
12
12
  import * as fs from "node:fs";
13
- import * as path from "node:path";
13
+ import path from "node:path";
14
14
 
15
- import { atomicWrite } from "../base/atomic-write.js";
16
- import { getContextPlansDir, sanitizeTitle } from "../base/constants.js";
17
- import { logDebug, logInfo, logWarn, logError } from "../base/logger.js";
18
- import { generateSlug } from "../base/utils.js";
15
+ import { atomicWrite } from "../runtime/atomic-write.js";
16
+ import { getContextPlansDir, sanitizeTitle } from "../runtime/constants.js";
17
+ import { logDebug, logInfo, logWarn, logError } from "../runtime/logger.js";
18
+ import { generateSlug } from "../runtime/utils.js";
19
19
 
20
20
  // ---------------------------------------------------------------------------
21
21
  // Plan archival
@@ -42,14 +42,14 @@ export function archivePlan(
42
42
 
43
43
  let content: string;
44
44
  try {
45
- content = fs.readFileSync(planPath, "utf-8");
46
- } catch (error_: any) {
45
+ content = fs.readFileSync(planPath, "utf8");
46
+ } catch (error_: unknown) {
47
47
  logError("plan_manager", `Failed to read plan: ${error_}`);
48
48
  return [null, null, null];
49
49
  }
50
50
 
51
51
  // Compute hash and signature
52
- const planHash = crypto.createHash("sha256").update(content, "utf-8").digest("hex").slice(0, 12);
52
+ const planHash = crypto.createHash("sha256").update(content, "utf8").digest("hex").slice(0, 12);
53
53
  const planSignature = content.slice(0, 200);
54
54
 
55
55
  // Ensure plans directory exists
@@ -144,12 +144,12 @@ export function findLatestPlan(
144
144
  try {
145
145
  // Dynamic import to avoid circular dependency at module level
146
146
  // eslint-disable-next-line @typescript-eslint/no-require-imports, no-undef -- dynamic require to avoid circular dependency
147
- const stateIo = require("../base/state-io.js");
147
+ const stateIo = require("../runtime/state-io.js");
148
148
  const state = stateIo.readStateJson(contextId, projectRoot);
149
149
  if (state?.plan_path && fs.existsSync(state.plan_path)) {
150
150
  return state.plan_path;
151
151
  }
152
- } catch (error: any) {
152
+ } catch (error: unknown) {
153
153
  logWarn("plan_manager", `Failed to check state.json plan_path: ${error}`);
154
154
  }
155
155
 
@@ -249,8 +249,8 @@ export function findPlanPathInTranscript(transcriptPath: string): string | null
249
249
 
250
250
  let lines: string[];
251
251
  try {
252
- lines = fs.readFileSync(transcriptPath, "utf-8").split(/\r?\n/);
253
- } catch (error: any) {
252
+ lines = fs.readFileSync(transcriptPath, "utf8").split(/\r?\n/);
253
+ } catch (error: unknown) {
254
254
  logWarn("plan_manager", `Failed to read transcript: ${error}`);
255
255
  return null;
256
256
  }
@@ -259,16 +259,17 @@ export function findPlanPathInTranscript(transcriptPath: string): string | null
259
259
  const line = lines[i]!.trim();
260
260
  if (!line) continue;
261
261
 
262
- let data: any;
262
+ let data: unknown;
263
263
  try {
264
264
  data = JSON.parse(line);
265
265
  } catch {
266
266
  continue;
267
267
  }
268
268
 
269
- let contentArr: any;
269
+ let contentArr: unknown;
270
270
  try {
271
- contentArr = data.message?.content;
271
+ const message = (data as { message?: { content?: unknown } }).message;
272
+ contentArr = message?.content;
272
273
  } catch {
273
274
  continue;
274
275
  }
@@ -311,3 +312,6 @@ export function extractPlanPathFromResult(toolResult: string): string | null {
311
312
  const match = toolResult.match(/Your plan has been saved to:\s*(.+\.md)/);
312
313
  return match ? match[1]!.trim() : null;
313
314
  }
315
+
316
+
317
+
@@ -6,9 +6,9 @@
6
6
  * Uses state-io for I/O to avoid circular imports with context-store.
7
7
  */
8
8
 
9
- import { logWarn } from "../base/logger.js";
10
- import { readStateJson, toDict as _toDict, writeStateJson } from "../base/state-io.js";
11
- import { nowIso } from "../base/utils.js";
9
+ import { logWarn } from "../runtime/logger.js";
10
+ import { readStateJson, toDict as _toDict, writeStateJson } from "../runtime/state-io.js";
11
+ import { nowIso } from "../runtime/utils.js";
12
12
  import type { ContextState as _ContextState, Task } from "../types.js";
13
13
 
14
14
  // ---------------------------------------------------------------------------
@@ -0,0 +1,32 @@
1
+ export const CONTEXT_WARNING_30 = "## Context Window: ~30% Remaining\n\n" +
2
+ "This session is approaching its context limit. Consider:\n\n" +
3
+ "- Completing your current task, then pausing for the user to decide next steps\n" +
4
+ "- If significant work remains, mention that `/aiwcli-shared:handoff` can capture progress " +
5
+ "for a fresh session\n\n" +
6
+ "Do not rush or cut corners — finish the current task properly. " +
7
+ "Just be aware that starting large new tasks may not complete before context runs out.";
8
+
9
+ export const CONTEXT_WARNING_15 = "## Context Window: ~15% Remaining — Wrap Up Now\n\n" +
10
+ "Context is critically low. After completing your current step:\n\n" +
11
+ "1. **Stop taking on new work**\n" +
12
+ "2. Summarize what was accomplished and what remains\n" +
13
+ "3. Offer to run `/aiwcli-shared:handoff` so progress transfers to a fresh session\n\n" +
14
+ "Do not start new multi-step tasks. Focus on clean closure.";
15
+
16
+ const WARNING_THRESHOLDS = [
17
+ { pct: 15, msg: CONTEXT_WARNING_15 },
18
+ { pct: 30, msg: CONTEXT_WARNING_30 },
19
+ ];
20
+
21
+ export function selectWarningMessage(
22
+ pctRemaining: number,
23
+ alreadyFired: number[],
24
+ ): { pct: number; msg: string } | null {
25
+ for (const warning of WARNING_THRESHOLDS) {
26
+ if (pctRemaining <= warning.pct && !alreadyFired.includes(warning.pct)) {
27
+ return warning;
28
+ }
29
+ }
30
+
31
+ return null;
32
+ }
@@ -6,10 +6,10 @@
6
6
 
7
7
  import * as fs from "node:fs";
8
8
 
9
- import { getProjectRoot } from "./constants.js";
10
- import { logDebug, logWarn, hookLog, setSessionId, getContextPath as _getContextPath } from "./logger.js";
11
- import { getContextBySessionId } from "../context/context-store.js";
12
- import type { HookInput, HookOutput, PermissionRequestOutput } from "../types.js";
9
+ import { getContextBySessionId, maybeActivate } from "../context/context-store.js";
10
+ import { getProjectRoot } from "../runtime/constants.js";
11
+ import { logDebug, logWarn, hookLog, setSessionId, getContextPath as _getContextPath } from "../runtime/logger.js";
12
+ import type { ContextState, HookInput, HookOutput, PermissionRequestOutput } from "../types.js";
13
13
 
14
14
  // Re-export logger functions for convenience (matches Python hook_utils re-exports)
15
15
 
@@ -24,7 +24,120 @@ let _lastToolName: string | null = null;
24
24
  let _cachedHookName: string | null = null;
25
25
 
26
26
  // Pre-fetched input stash
27
- let _prefetchedInput: Record<string, any> | null = null;
27
+ let _prefetchedInput: Record<string, unknown> | null = null;
28
+
29
+ function readStringField(value: Record<string, unknown>, key: string): null | string {
30
+ const field = value[key];
31
+ return typeof field === "string" ? field : null;
32
+ }
33
+
34
+ export interface BoundSessionContext {
35
+ payload: HookInput;
36
+ projectRoot: string;
37
+ sessionId: string;
38
+ state: ContextState;
39
+ }
40
+
41
+ export interface PersistenceContext extends BoundSessionContext {
42
+ toolInput: Record<string, unknown>;
43
+ }
44
+
45
+ export interface ToolInputContext {
46
+ payload: HookInput;
47
+ toolInput: Record<string, unknown>;
48
+ }
49
+
50
+ /**
51
+ * Load the current payload, resolve its project root, and require an already-bound session.
52
+ * Returns null when the hook should quietly no-op.
53
+ */
54
+ export function requireBoundSession(
55
+ hookName: string,
56
+ prefetchedPayload?: HookInput | null,
57
+ ): BoundSessionContext | null {
58
+ const payload = prefetchedPayload ?? loadHookInput();
59
+ if (!payload) return null;
60
+
61
+ const sessionId = payload.session_id;
62
+ if (!sessionId) {
63
+ logDebug(hookName, "No session_id available");
64
+ return null;
65
+ }
66
+
67
+ const projectRoot = getProjectRoot(payload.cwd);
68
+ const state = getContextBySessionId(sessionId, projectRoot);
69
+ if (!state) {
70
+ logDebug(hookName, `No bound context for session ${sessionId.slice(0, 8)}`);
71
+ return null;
72
+ }
73
+
74
+ return { payload, projectRoot, sessionId, state };
75
+ }
76
+
77
+ /**
78
+ * Require a bound session plus tool_input for PostToolUse task persistence hooks.
79
+ */
80
+ export function requirePersistenceContext(
81
+ expectedTool: string,
82
+ hookName: string,
83
+ ): PersistenceContext | null {
84
+ const bound = requireBoundSession(hookName);
85
+ if (!bound) return null;
86
+
87
+ const { payload } = bound;
88
+ if (payload.hook_event_name !== "PostToolUse") {
89
+ return null;
90
+ }
91
+ if (payload.tool_name !== expectedTool) {
92
+ return null;
93
+ }
94
+ if (checkSkipPersistence(payload, hookName)) {
95
+ return null;
96
+ }
97
+
98
+ const toolInput = getToolInput(payload);
99
+ if (!toolInput) {
100
+ logWarn(hookName, `${expectedTool} missing tool_input payload`);
101
+ return null;
102
+ }
103
+
104
+ return { ...bound, toolInput };
105
+ }
106
+
107
+ /**
108
+ * Require a tool_input payload for tool-oriented hooks without needing a bound session.
109
+ */
110
+ export function requireToolInput(
111
+ hookName: string,
112
+ ): ToolInputContext | null {
113
+ const payload = loadHookInput();
114
+ if (!payload) return null;
115
+
116
+ const toolInput = getToolInput(payload);
117
+ if (!toolInput) {
118
+ logDebug(hookName, "No tool_input payload");
119
+ return null;
120
+ }
121
+
122
+ return { payload, toolInput };
123
+ }
124
+
125
+ /**
126
+ * Best-effort wrapper around maybeActivate. Hooks should never fail closed on activation.
127
+ */
128
+ export function safeMaybeActivate(
129
+ contextId: string,
130
+ permissionMode: string,
131
+ projectRoot?: string,
132
+ hookName = "hook",
133
+ ): boolean {
134
+ try {
135
+ return maybeActivate(contextId, permissionMode, projectRoot, hookName);
136
+ } catch (error) {
137
+ logWarn(hookName, `maybeActivate failed for ${contextId}: ${error}`);
138
+ return false;
139
+ }
140
+ }
28
141
 
29
142
  /**
30
143
  * Load and parse JSON from stdin (or return prefetched input if set).
@@ -36,23 +149,23 @@ export function loadHookInput(): HookInput | null {
36
149
  const result = _prefetchedInput;
37
150
  _prefetchedInput = null; // consume once
38
151
  if (result && typeof result === "object") {
39
- _lastHookEvent = result.hook_event_name ?? null;
40
- _lastToolName = result.tool_name ?? null;
152
+ _lastHookEvent = readStringField(result, "hook_event_name");
153
+ _lastToolName = readStringField(result, "tool_name");
41
154
  }
42
- return result as HookInput;
155
+ return result as unknown as HookInput;
43
156
  }
44
157
 
45
158
  try {
46
159
  // Read entire stdin using fd 0 (cross-platform, works on Windows)
47
- const inputData = fs.readFileSync(0, "utf-8").trim();
160
+ const inputData = fs.readFileSync(0, "utf8").trim();
48
161
  if (!inputData) return null;
49
162
 
50
- const result = JSON.parse(inputData);
163
+ const result = JSON.parse(inputData) as Record<string, unknown>;
51
164
  if (result && typeof result === "object") {
52
- _lastHookEvent = result.hook_event_name ?? null;
53
- _lastToolName = result.tool_name ?? null;
165
+ _lastHookEvent = readStringField(result, "hook_event_name");
166
+ _lastToolName = readStringField(result, "tool_name");
54
167
  }
55
- return result as HookInput;
168
+ return result as unknown as HookInput;
56
169
  } catch {
57
170
  return null;
58
171
  }
@@ -78,7 +191,7 @@ export function validateHookEvent(
78
191
  */
79
192
  export function getToolInput(
80
193
  payload: HookInput,
81
- ): Record<string, any> | null {
194
+ ): Record<string, unknown> | null {
82
195
  const toolInput = payload.tool_input;
83
196
  return toolInput && typeof toolInput === "object" ? toolInput : null;
84
197
  }
@@ -95,7 +208,11 @@ export function checkSkipPersistence(
95
208
  if (!toolInput) return false;
96
209
 
97
210
  const {metadata} = toolInput;
98
- if (metadata && typeof metadata === "object" && metadata.skip_persistence) {
211
+ if (
212
+ metadata &&
213
+ typeof metadata === "object" &&
214
+ Boolean((metadata as Record<string, unknown>).skip_persistence)
215
+ ) {
99
216
  logDebug(hookName, "Skipping persistence (skip_persistence flag set)");
100
217
  return true;
101
218
  }
@@ -167,12 +284,12 @@ export function emitContextAndBlock(
167
284
  }
168
285
 
169
286
  /** Log hook output (context, systemMessage, or block) to hook-log.jsonl for visibility. */
170
- function _logEmit(type: "context" | "systemMessage" | "block", chars: number, payload: Record<string, any>): void {
287
+ function _logEmit(type: "context" | "systemMessage" | "block", chars: number, payload: Record<string, unknown>): void {
171
288
  const hook = _cachedHookName ?? "unknown";
172
289
  const event = payload.event ?? "unknown";
173
290
  const mechanism = payload.mechanism ? ` via ${payload.mechanism}` : "";
174
291
  const msg = type === "block"
175
- ? `HOOK_OUTPUT [${type}] ${event} ${chars} chars${mechanism}, reason="${(payload.blockReason ?? "").slice(0, 80)}"`
292
+ ? `HOOK_OUTPUT [${type}] ${event} ${chars} chars${mechanism}, reason="${String(payload.blockReason ?? "").slice(0, 80)}"`
176
293
  : `HOOK_OUTPUT [${type}] ${event} ${chars} chars`;
177
294
  hookLog("info", hook, msg, { data: payload });
178
295
  }
@@ -316,8 +433,13 @@ export function emitBlock(reason: string, context?: string): void {
316
433
  */
317
434
  function detectTemplate(scriptPath = ""): string {
318
435
  const p = (scriptPath || (process.argv[1] ?? "")).replaceAll('\\', "/");
319
- if (p.includes("/_shared/hooks/") || p.startsWith("_shared/hooks/")) {
320
- return "shared";
436
+ if (
437
+ p.includes("/_core/hooks-ts/") ||
438
+ p.startsWith("_core/hooks-ts/") ||
439
+ p.includes("/core/hooks-ts/") ||
440
+ p.startsWith("core/hooks-ts/")
441
+ ) {
442
+ return "core";
321
443
  }
322
444
  const match = p.match(/_([a-z][a-z0-9-]*)\/hooks\//);
323
445
  if (match?.[1]) return match[1]; // e.g., "cc-native"
@@ -390,32 +512,34 @@ export function getContextPercentRemaining(
390
512
  * Read stdin early and extract session_id + event metadata.
391
513
  * Stashes parsed input for loadHookInput() to consume later.
392
514
  */
393
- function _earlyReadInput(prefetchedInput?: Record<string, any>): void {
515
+ function _earlyReadInput(prefetchedInput?: Record<string, unknown>): void {
394
516
  if (prefetchedInput !== undefined) {
395
517
  _prefetchedInput = prefetchedInput;
396
518
  }
397
519
 
398
520
  // If we already have prefetched input, extract metadata from it
399
521
  if (_prefetchedInput && typeof _prefetchedInput === "object") {
400
- _lastHookEvent = _prefetchedInput.hook_event_name ?? null;
401
- _lastToolName = _prefetchedInput.tool_name ?? null;
402
- if (_prefetchedInput.session_id) {
403
- setSessionId(_prefetchedInput.session_id);
522
+ _lastHookEvent = readStringField(_prefetchedInput, "hook_event_name");
523
+ _lastToolName = readStringField(_prefetchedInput, "tool_name");
524
+ const sessionId = readStringField(_prefetchedInput, "session_id");
525
+ if (sessionId) {
526
+ setSessionId(sessionId);
404
527
  }
405
528
  return;
406
529
  }
407
530
 
408
531
  // Read stdin now so HOOK_START can include sid
409
532
  try {
410
- const inputData = fs.readFileSync(0, "utf-8").trim();
533
+ const inputData = fs.readFileSync(0, "utf8").trim();
411
534
  if (inputData) {
412
- const parsed = JSON.parse(inputData);
535
+ const parsed = JSON.parse(inputData) as Record<string, unknown>;
413
536
  if (parsed && typeof parsed === "object") {
414
537
  _prefetchedInput = parsed;
415
- _lastHookEvent = parsed.hook_event_name ?? null;
416
- _lastToolName = parsed.tool_name ?? null;
417
- if (parsed.session_id) {
418
- setSessionId(parsed.session_id);
538
+ _lastHookEvent = readStringField(parsed, "hook_event_name");
539
+ _lastToolName = readStringField(parsed, "tool_name");
540
+ const sessionId = readStringField(parsed, "session_id");
541
+ if (sessionId) {
542
+ setSessionId(sessionId);
419
543
  }
420
544
  }
421
545
  }
@@ -431,7 +555,7 @@ function _earlyReadInput(prefetchedInput?: Record<string, any>): void {
431
555
  export function runHook(
432
556
  mainFunc: () => number | void,
433
557
  hookName = "unknown",
434
- prefetchedInput?: Record<string, any>,
558
+ prefetchedInput?: Record<string, unknown>,
435
559
  ): never {
436
560
  _earlyReadInput(prefetchedInput);
437
561
  _cachedHookName = hookName;
@@ -439,7 +563,8 @@ export function runHook(
439
563
  // Ensure cwd is project root so relative paths in hooks resolve correctly,
440
564
  // even when cwd has drifted via `cd` in a Bash tool call.
441
565
  try {
442
- const projectRoot = getProjectRoot(_prefetchedInput?.cwd);
566
+ const cwd = _prefetchedInput ? readStringField(_prefetchedInput, "cwd") ?? undefined : undefined;
567
+ const projectRoot = getProjectRoot(cwd);
443
568
  if (process.cwd() !== projectRoot) process.chdir(projectRoot);
444
569
  } catch { /* non-fatal — proceed with current cwd */ }
445
570
 
@@ -448,7 +573,7 @@ export function runHook(
448
573
  const event = _lastHookEvent ?? "unknown";
449
574
  const tool = _lastToolName;
450
575
 
451
- const startData: Record<string, any> = {
576
+ const startData: Record<string, unknown> = {
452
577
  lifecycle: "start",
453
578
  template,
454
579
  event,
@@ -464,7 +589,7 @@ export function runHook(
464
589
  const result = mainFunc();
465
590
  exitCode = typeof result === "number" ? result : 0;
466
591
  status = exitCode !== 0 ? "blocked" : "success";
467
- } catch (error: any) {
592
+ } catch (error: unknown) {
468
593
  if (error instanceof Error && error.message.startsWith("SystemExit:")) {
469
594
  const code = parseInt(error.message.slice(11), 10);
470
595
  exitCode = isNaN(code) ? (error.message.slice(11) ? 1 : 0) : code;
@@ -489,7 +614,7 @@ export function runHook(
489
614
  export function runHookAsync(
490
615
  mainFunc: () => Promise<number | void>,
491
616
  hookName = "unknown",
492
- prefetchedInput?: Record<string, any>,
617
+ prefetchedInput?: Record<string, unknown>,
493
618
  ): void {
494
619
  _earlyReadInput(prefetchedInput);
495
620
  _cachedHookName = hookName;
@@ -497,7 +622,8 @@ export function runHookAsync(
497
622
  // Ensure cwd is project root so relative paths in hooks resolve correctly,
498
623
  // even when cwd has drifted via `cd` in a Bash tool call.
499
624
  try {
500
- const projectRoot = getProjectRoot(_prefetchedInput?.cwd);
625
+ const cwd = _prefetchedInput ? readStringField(_prefetchedInput, "cwd") ?? undefined : undefined;
626
+ const projectRoot = getProjectRoot(cwd);
501
627
  if (process.cwd() !== projectRoot) process.chdir(projectRoot);
502
628
  } catch { /* non-fatal — proceed with current cwd */ }
503
629
 
@@ -506,7 +632,7 @@ export function runHookAsync(
506
632
  const event = _lastHookEvent ?? "unknown";
507
633
  const tool = _lastToolName;
508
634
 
509
- const startData: Record<string, any> = {
635
+ const startData: Record<string, unknown> = {
510
636
  lifecycle: "start",
511
637
  template,
512
638
  event,
@@ -520,7 +646,7 @@ export function runHookAsync(
520
646
  _emitHookEnd(hookName, startTime, exitCode, exitCode !== 0 ? "blocked" : "success", null, startData, event, tool, template);
521
647
  _drainAndExit(exitCode);
522
648
  })
523
- .catch((error: any) => {
649
+ .catch((error: unknown) => {
524
650
  let exitCode = 0;
525
651
  let status = "error";
526
652
  let errorInfo: [Error, string] | null = null;
@@ -547,7 +673,7 @@ function _emitHookEnd(
547
673
  exitCode: number,
548
674
  status: string,
549
675
  errorInfo: [Error, string] | null,
550
- startData: Record<string, any>,
676
+ startData: Record<string, unknown>,
551
677
  event: string,
552
678
  tool: string | null,
553
679
  template: string,
@@ -561,7 +687,7 @@ function _emitHookEnd(
561
687
  const durationMs = Math.round((performance.now() - startTime) * 10) / 10;
562
688
  const endEvent = _lastHookEvent ?? event;
563
689
  const endTool = _lastToolName ?? tool;
564
- const endData: Record<string, any> = {
690
+ const endData: Record<string, unknown> = {
565
691
  lifecycle: "end",
566
692
  status,
567
693
  duration_ms: durationMs,
@@ -602,4 +728,5 @@ function _drainAndExit(code: number): void {
602
728
  });
603
729
  }
604
730
 
605
- export {hookLog, logBlocking, logDebug, logDiagnostic, logError, logHookError, logInfo, logWarn, setContextPath, setSessionId} from "./logger.js";
731
+ export {hookLog, logBlocking, logDebug, logDiagnostic, logError, logHookError, logInfo, logWarn, setContextPath, setSessionId} from "../runtime/logger.js";
732
+