@vinaes/succ 1.3.31 → 1.5.37

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 (759) hide show
  1. package/README.md +65 -11
  2. package/agents/succ-code-reviewer.md +1 -1
  3. package/agents/succ-diff-reviewer.md +1 -1
  4. package/agents/succ-general.md +1 -1
  5. package/dist/cli.js +84 -2
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/agents-md.d.ts.map +1 -1
  8. package/dist/commands/agents-md.js +3 -2
  9. package/dist/commands/agents-md.js.map +1 -1
  10. package/dist/commands/analyze-agents.d.ts.map +1 -1
  11. package/dist/commands/analyze-agents.js +10 -11
  12. package/dist/commands/analyze-agents.js.map +1 -1
  13. package/dist/commands/analyze-profile.d.ts.map +1 -1
  14. package/dist/commands/analyze-profile.js +32 -8
  15. package/dist/commands/analyze-profile.js.map +1 -1
  16. package/dist/commands/analyze-recursive.d.ts.map +1 -1
  17. package/dist/commands/analyze-recursive.js +8 -3
  18. package/dist/commands/analyze-recursive.js.map +1 -1
  19. package/dist/commands/analyze-utils.d.ts.map +1 -1
  20. package/dist/commands/analyze-utils.js +17 -4
  21. package/dist/commands/analyze-utils.js.map +1 -1
  22. package/dist/commands/benchmark-quality.d.ts.map +1 -1
  23. package/dist/commands/benchmark-quality.js +11 -4
  24. package/dist/commands/benchmark-quality.js.map +1 -1
  25. package/dist/commands/benchmark-sqlite-vec.d.ts.map +1 -1
  26. package/dist/commands/benchmark-sqlite-vec.js +4 -0
  27. package/dist/commands/benchmark-sqlite-vec.js.map +1 -1
  28. package/dist/commands/benchmark.d.ts.map +1 -1
  29. package/dist/commands/benchmark.js +5 -1
  30. package/dist/commands/benchmark.js.map +1 -1
  31. package/dist/commands/codex-chat.d.ts +8 -0
  32. package/dist/commands/codex-chat.d.ts.map +1 -0
  33. package/dist/commands/codex-chat.js +161 -0
  34. package/dist/commands/codex-chat.js.map +1 -0
  35. package/dist/commands/config.d.ts.map +1 -1
  36. package/dist/commands/config.js +32 -4
  37. package/dist/commands/config.js.map +1 -1
  38. package/dist/commands/daemon.d.ts.map +1 -1
  39. package/dist/commands/daemon.js +13 -4
  40. package/dist/commands/daemon.js.map +1 -1
  41. package/dist/commands/index-code.d.ts +4 -0
  42. package/dist/commands/index-code.d.ts.map +1 -1
  43. package/dist/commands/index-code.js +1 -1
  44. package/dist/commands/index-code.js.map +1 -1
  45. package/dist/commands/init-templates.js +2 -2
  46. package/dist/commands/init.d.ts.map +1 -1
  47. package/dist/commands/init.js +305 -203
  48. package/dist/commands/init.js.map +1 -1
  49. package/dist/commands/memories.d.ts.map +1 -1
  50. package/dist/commands/memories.js +25 -14
  51. package/dist/commands/memories.js.map +1 -1
  52. package/dist/commands/progress.d.ts.map +1 -1
  53. package/dist/commands/progress.js +3 -2
  54. package/dist/commands/progress.js.map +1 -1
  55. package/dist/commands/reindex.d.ts.map +1 -1
  56. package/dist/commands/reindex.js +54 -36
  57. package/dist/commands/reindex.js.map +1 -1
  58. package/dist/commands/retention.d.ts.map +1 -1
  59. package/dist/commands/retention.js +7 -5
  60. package/dist/commands/retention.js.map +1 -1
  61. package/dist/commands/scan-code.d.ts +76 -0
  62. package/dist/commands/scan-code.d.ts.map +1 -0
  63. package/dist/commands/scan-code.js +385 -0
  64. package/dist/commands/scan-code.js.map +1 -0
  65. package/dist/commands/score.d.ts.map +1 -1
  66. package/dist/commands/score.js +3 -2
  67. package/dist/commands/score.js.map +1 -1
  68. package/dist/commands/session.d.ts +33 -0
  69. package/dist/commands/session.d.ts.map +1 -0
  70. package/dist/commands/session.js +163 -0
  71. package/dist/commands/session.js.map +1 -0
  72. package/dist/commands/setup.d.ts.map +1 -1
  73. package/dist/commands/setup.js +254 -15
  74. package/dist/commands/setup.js.map +1 -1
  75. package/dist/commands/soul.d.ts.map +1 -1
  76. package/dist/commands/soul.js +7 -46
  77. package/dist/commands/soul.js.map +1 -1
  78. package/dist/commands/status.d.ts.map +1 -1
  79. package/dist/commands/status.js +14 -5
  80. package/dist/commands/status.js.map +1 -1
  81. package/dist/commands/watch.d.ts.map +1 -1
  82. package/dist/commands/watch.js +13 -4
  83. package/dist/commands/watch.js.map +1 -1
  84. package/dist/daemon/analyzer.d.ts.map +1 -1
  85. package/dist/daemon/analyzer.js +23 -7
  86. package/dist/daemon/analyzer.js.map +1 -1
  87. package/dist/daemon/client.d.ts.map +1 -1
  88. package/dist/daemon/client.js +32 -8
  89. package/dist/daemon/client.js.map +1 -1
  90. package/dist/daemon/routes/analyzer.d.ts +3 -0
  91. package/dist/daemon/routes/analyzer.d.ts.map +1 -0
  92. package/dist/daemon/routes/analyzer.js +27 -0
  93. package/dist/daemon/routes/analyzer.js.map +1 -0
  94. package/dist/daemon/routes/hooks.d.ts +14 -0
  95. package/dist/daemon/routes/hooks.d.ts.map +1 -0
  96. package/dist/daemon/routes/hooks.js +1212 -0
  97. package/dist/daemon/routes/hooks.js.map +1 -0
  98. package/dist/daemon/routes/memory.d.ts +4 -0
  99. package/dist/daemon/routes/memory.d.ts.map +1 -0
  100. package/dist/daemon/routes/memory.js +71 -0
  101. package/dist/daemon/routes/memory.js.map +1 -0
  102. package/dist/daemon/routes/reflection.d.ts +10 -0
  103. package/dist/daemon/routes/reflection.d.ts.map +1 -0
  104. package/dist/daemon/routes/reflection.js +397 -0
  105. package/dist/daemon/routes/reflection.js.map +1 -0
  106. package/dist/daemon/routes/search.d.ts +5 -0
  107. package/dist/daemon/routes/search.d.ts.map +1 -0
  108. package/dist/daemon/routes/search.js +93 -0
  109. package/dist/daemon/routes/search.js.map +1 -0
  110. package/dist/daemon/routes/sessions.d.ts +3 -0
  111. package/dist/daemon/routes/sessions.d.ts.map +1 -0
  112. package/dist/daemon/routes/sessions.js +160 -0
  113. package/dist/daemon/routes/sessions.js.map +1 -0
  114. package/dist/daemon/routes/skills.d.ts +3 -0
  115. package/dist/daemon/routes/skills.d.ts.map +1 -0
  116. package/dist/daemon/routes/skills.js +36 -0
  117. package/dist/daemon/routes/skills.js.map +1 -0
  118. package/dist/daemon/routes/status.d.ts +3 -0
  119. package/dist/daemon/routes/status.d.ts.map +1 -0
  120. package/dist/daemon/routes/status.js +47 -0
  121. package/dist/daemon/routes/status.js.map +1 -0
  122. package/dist/daemon/routes/types.d.ts +240 -0
  123. package/dist/daemon/routes/types.d.ts.map +1 -0
  124. package/dist/daemon/routes/types.js +97 -0
  125. package/dist/daemon/routes/types.js.map +1 -0
  126. package/dist/daemon/routes/versioning.d.ts +27 -0
  127. package/dist/daemon/routes/versioning.d.ts.map +1 -0
  128. package/dist/daemon/routes/versioning.js +44 -0
  129. package/dist/daemon/routes/versioning.js.map +1 -0
  130. package/dist/daemon/routes/watcher.d.ts +3 -0
  131. package/dist/daemon/routes/watcher.d.ts.map +1 -0
  132. package/dist/daemon/routes/watcher.js +28 -0
  133. package/dist/daemon/routes/watcher.js.map +1 -0
  134. package/dist/daemon/service.d.ts +5 -23
  135. package/dist/daemon/service.d.ts.map +1 -1
  136. package/dist/daemon/service.js +177 -934
  137. package/dist/daemon/service.js.map +1 -1
  138. package/dist/daemon/session-processor.d.ts +4 -8
  139. package/dist/daemon/session-processor.d.ts.map +1 -1
  140. package/dist/daemon/session-processor.js +49 -222
  141. package/dist/daemon/session-processor.js.map +1 -1
  142. package/dist/lib/ai-readiness.d.ts.map +1 -1
  143. package/dist/lib/ai-readiness.js +33 -8
  144. package/dist/lib/ai-readiness.js.map +1 -1
  145. package/dist/lib/analyze-state.d.ts.map +1 -1
  146. package/dist/lib/analyze-state.js +25 -3
  147. package/dist/lib/analyze-state.js.map +1 -1
  148. package/dist/lib/auto-memory/consolidation.d.ts +41 -0
  149. package/dist/lib/auto-memory/consolidation.d.ts.map +1 -0
  150. package/dist/lib/auto-memory/consolidation.js +151 -0
  151. package/dist/lib/auto-memory/consolidation.js.map +1 -0
  152. package/dist/lib/bpe.d.ts.map +1 -1
  153. package/dist/lib/bpe.js +9 -10
  154. package/dist/lib/bpe.js.map +1 -1
  155. package/dist/lib/brain-export.d.ts +65 -0
  156. package/dist/lib/brain-export.d.ts.map +1 -0
  157. package/dist/lib/brain-export.js +413 -0
  158. package/dist/lib/brain-export.js.map +1 -0
  159. package/dist/lib/checkpoint.d.ts.map +1 -1
  160. package/dist/lib/checkpoint.js +22 -6
  161. package/dist/lib/checkpoint.js.map +1 -1
  162. package/dist/lib/chunker.d.ts.map +1 -1
  163. package/dist/lib/chunker.js +6 -1
  164. package/dist/lib/chunker.js.map +1 -1
  165. package/dist/lib/claude-ws-transport.d.ts.map +1 -1
  166. package/dist/lib/claude-ws-transport.js +12 -4
  167. package/dist/lib/claude-ws-transport.js.map +1 -1
  168. package/dist/lib/command-safety.d.ts +64 -0
  169. package/dist/lib/command-safety.d.ts.map +1 -0
  170. package/dist/lib/command-safety.js +625 -0
  171. package/dist/lib/command-safety.js.map +1 -0
  172. package/dist/lib/compact-briefing.d.ts.map +1 -1
  173. package/dist/lib/compact-briefing.js +18 -17
  174. package/dist/lib/compact-briefing.js.map +1 -1
  175. package/dist/lib/config-defaults.d.ts.map +1 -1
  176. package/dist/lib/config-defaults.js +3 -0
  177. package/dist/lib/config-defaults.js.map +1 -1
  178. package/dist/lib/config-display.d.ts +4 -0
  179. package/dist/lib/config-display.d.ts.map +1 -1
  180. package/dist/lib/config-display.js +6 -1
  181. package/dist/lib/config-display.js.map +1 -1
  182. package/dist/lib/config-types.d.ts +157 -0
  183. package/dist/lib/config-types.d.ts.map +1 -1
  184. package/dist/lib/config-validation.d.ts.map +1 -1
  185. package/dist/lib/config-validation.js +6 -0
  186. package/dist/lib/config-validation.js.map +1 -1
  187. package/dist/lib/config.d.ts +8 -0
  188. package/dist/lib/config.d.ts.map +1 -1
  189. package/dist/lib/config.js +108 -9
  190. package/dist/lib/config.js.map +1 -1
  191. package/dist/lib/consolidate.d.ts.map +1 -1
  192. package/dist/lib/consolidate.js +73 -49
  193. package/dist/lib/consolidate.js.map +1 -1
  194. package/dist/lib/content-sanitizer.d.ts +29 -0
  195. package/dist/lib/content-sanitizer.d.ts.map +1 -0
  196. package/dist/lib/content-sanitizer.js +72 -0
  197. package/dist/lib/content-sanitizer.js.map +1 -0
  198. package/dist/lib/cross-repo.d.ts +44 -0
  199. package/dist/lib/cross-repo.d.ts.map +1 -0
  200. package/dist/lib/cross-repo.js +108 -0
  201. package/dist/lib/cross-repo.js.map +1 -0
  202. package/dist/lib/daemon-port.d.ts +12 -0
  203. package/dist/lib/daemon-port.d.ts.map +1 -0
  204. package/dist/lib/daemon-port.js +20 -0
  205. package/dist/lib/daemon-port.js.map +1 -0
  206. package/dist/lib/db/auto-memory.d.ts +40 -0
  207. package/dist/lib/db/auto-memory.d.ts.map +1 -0
  208. package/dist/lib/db/auto-memory.js +74 -0
  209. package/dist/lib/db/auto-memory.js.map +1 -0
  210. package/dist/lib/db/bm25-indexes.d.ts.map +1 -1
  211. package/dist/lib/db/bm25-indexes.js +16 -4
  212. package/dist/lib/db/bm25-indexes.js.map +1 -1
  213. package/dist/lib/db/connection.d.ts.map +1 -1
  214. package/dist/lib/db/connection.js +8 -1
  215. package/dist/lib/db/connection.js.map +1 -1
  216. package/dist/lib/db/documents.d.ts.map +1 -1
  217. package/dist/lib/db/documents.js +4 -1
  218. package/dist/lib/db/documents.js.map +1 -1
  219. package/dist/lib/db/global-memories.d.ts +2 -10
  220. package/dist/lib/db/global-memories.d.ts.map +1 -1
  221. package/dist/lib/db/global-memories.js +13 -6
  222. package/dist/lib/db/global-memories.js.map +1 -1
  223. package/dist/lib/db/graph.d.ts +5 -1
  224. package/dist/lib/db/graph.d.ts.map +1 -1
  225. package/dist/lib/db/graph.js +38 -8
  226. package/dist/lib/db/graph.js.map +1 -1
  227. package/dist/lib/db/hybrid-search.d.ts +4 -2
  228. package/dist/lib/db/hybrid-search.d.ts.map +1 -1
  229. package/dist/lib/db/hybrid-search.js +29 -11
  230. package/dist/lib/db/hybrid-search.js.map +1 -1
  231. package/dist/lib/db/index.d.ts +6 -1
  232. package/dist/lib/db/index.d.ts.map +1 -1
  233. package/dist/lib/db/index.js +5 -1
  234. package/dist/lib/db/index.js.map +1 -1
  235. package/dist/lib/db/memories.d.ts +19 -14
  236. package/dist/lib/db/memories.d.ts.map +1 -1
  237. package/dist/lib/db/memories.js +100 -37
  238. package/dist/lib/db/memories.js.map +1 -1
  239. package/dist/lib/db/parse-helpers.d.ts +14 -0
  240. package/dist/lib/db/parse-helpers.d.ts.map +1 -0
  241. package/dist/lib/db/parse-helpers.js +59 -0
  242. package/dist/lib/db/parse-helpers.js.map +1 -0
  243. package/dist/lib/db/recall-events.d.ts +49 -0
  244. package/dist/lib/db/recall-events.d.ts.map +1 -0
  245. package/dist/lib/db/recall-events.js +196 -0
  246. package/dist/lib/db/recall-events.js.map +1 -0
  247. package/dist/lib/db/retention.d.ts +4 -3
  248. package/dist/lib/db/retention.d.ts.map +1 -1
  249. package/dist/lib/db/retention.js +12 -1
  250. package/dist/lib/db/retention.js.map +1 -1
  251. package/dist/lib/db/schema.d.ts +2 -0
  252. package/dist/lib/db/schema.d.ts.map +1 -1
  253. package/dist/lib/db/schema.js +140 -80
  254. package/dist/lib/db/schema.js.map +1 -1
  255. package/dist/lib/db/skills.d.ts.map +1 -1
  256. package/dist/lib/db/skills.js +10 -6
  257. package/dist/lib/db/skills.js.map +1 -1
  258. package/dist/lib/diff-brain.d.ts +24 -0
  259. package/dist/lib/diff-brain.d.ts.map +1 -0
  260. package/dist/lib/diff-brain.js +114 -0
  261. package/dist/lib/diff-brain.js.map +1 -0
  262. package/dist/lib/diff-parser.d.ts +74 -0
  263. package/dist/lib/diff-parser.d.ts.map +1 -0
  264. package/dist/lib/diff-parser.js +200 -0
  265. package/dist/lib/diff-parser.js.map +1 -0
  266. package/dist/lib/embedding-pool.d.ts.map +1 -1
  267. package/dist/lib/embedding-pool.js +5 -1
  268. package/dist/lib/embedding-pool.js.map +1 -1
  269. package/dist/lib/embeddings.d.ts +12 -0
  270. package/dist/lib/embeddings.d.ts.map +1 -1
  271. package/dist/lib/embeddings.js +77 -19
  272. package/dist/lib/embeddings.js.map +1 -1
  273. package/dist/lib/errors.d.ts +2 -0
  274. package/dist/lib/errors.d.ts.map +1 -1
  275. package/dist/lib/errors.js +4 -0
  276. package/dist/lib/errors.js.map +1 -1
  277. package/dist/lib/fault-logger.d.ts.map +1 -1
  278. package/dist/lib/fault-logger.js +22 -7
  279. package/dist/lib/fault-logger.js.map +1 -1
  280. package/dist/lib/git/co-change.d.ts +39 -0
  281. package/dist/lib/git/co-change.d.ts.map +1 -0
  282. package/dist/lib/git/co-change.js +139 -0
  283. package/dist/lib/git/co-change.js.map +1 -0
  284. package/dist/lib/graph/bridge-edges.d.ts +93 -0
  285. package/dist/lib/graph/bridge-edges.d.ts.map +1 -0
  286. package/dist/lib/graph/bridge-edges.js +276 -0
  287. package/dist/lib/graph/bridge-edges.js.map +1 -0
  288. package/dist/lib/graph/centrality.d.ts +11 -0
  289. package/dist/lib/graph/centrality.d.ts.map +1 -1
  290. package/dist/lib/graph/centrality.js +51 -3
  291. package/dist/lib/graph/centrality.js.map +1 -1
  292. package/dist/lib/graph/cleanup.d.ts.map +1 -1
  293. package/dist/lib/graph/cleanup.js +2 -1
  294. package/dist/lib/graph/cleanup.js.map +1 -1
  295. package/dist/lib/graph/community-detection.d.ts +17 -2
  296. package/dist/lib/graph/community-detection.d.ts.map +1 -1
  297. package/dist/lib/graph/community-detection.js +147 -48
  298. package/dist/lib/graph/community-detection.js.map +1 -1
  299. package/dist/lib/graph/community-summaries.d.ts +26 -0
  300. package/dist/lib/graph/community-summaries.d.ts.map +1 -0
  301. package/dist/lib/graph/community-summaries.js +130 -0
  302. package/dist/lib/graph/community-summaries.js.map +1 -0
  303. package/dist/lib/graph/contextual-proximity.d.ts.map +1 -1
  304. package/dist/lib/graph/contextual-proximity.js +11 -4
  305. package/dist/lib/graph/contextual-proximity.js.map +1 -1
  306. package/dist/lib/graph/graphology-bridge.d.ts +101 -0
  307. package/dist/lib/graph/graphology-bridge.d.ts.map +1 -0
  308. package/dist/lib/graph/graphology-bridge.js +488 -0
  309. package/dist/lib/graph/graphology-bridge.js.map +1 -0
  310. package/dist/lib/graph/llm-relations.d.ts.map +1 -1
  311. package/dist/lib/graph/llm-relations.js +34 -45
  312. package/dist/lib/graph/llm-relations.js.map +1 -1
  313. package/dist/lib/graph-export.d.ts.map +1 -1
  314. package/dist/lib/graph-export.js +2 -2
  315. package/dist/lib/graph-export.js.map +1 -1
  316. package/dist/lib/graph-scheduler.d.ts +0 -5
  317. package/dist/lib/graph-scheduler.d.ts.map +1 -1
  318. package/dist/lib/graph-scheduler.js +5 -1
  319. package/dist/lib/graph-scheduler.js.map +1 -1
  320. package/dist/lib/guardrails.d.ts +50 -0
  321. package/dist/lib/guardrails.d.ts.map +1 -0
  322. package/dist/lib/guardrails.js +502 -0
  323. package/dist/lib/guardrails.js.map +1 -0
  324. package/dist/lib/hook-rules.d.ts +1 -1
  325. package/dist/lib/hook-rules.d.ts.map +1 -1
  326. package/dist/lib/hook-rules.js +8 -2
  327. package/dist/lib/hook-rules.js.map +1 -1
  328. package/dist/lib/ifc/file-labels.d.ts +35 -0
  329. package/dist/lib/ifc/file-labels.d.ts.map +1 -0
  330. package/dist/lib/ifc/file-labels.js +208 -0
  331. package/dist/lib/ifc/file-labels.js.map +1 -0
  332. package/dist/lib/ifc/label.d.ts +38 -0
  333. package/dist/lib/ifc/label.d.ts.map +1 -0
  334. package/dist/lib/ifc/label.js +80 -0
  335. package/dist/lib/ifc/label.js.map +1 -0
  336. package/dist/lib/ifc/session-ifc.d.ts +92 -0
  337. package/dist/lib/ifc/session-ifc.d.ts.map +1 -0
  338. package/dist/lib/ifc/session-ifc.js +222 -0
  339. package/dist/lib/ifc/session-ifc.js.map +1 -0
  340. package/dist/lib/indexer.js +2 -2
  341. package/dist/lib/indexer.js.map +1 -1
  342. package/dist/lib/injection-detector.d.ts +83 -0
  343. package/dist/lib/injection-detector.d.ts.map +1 -0
  344. package/dist/lib/injection-detector.js +586 -0
  345. package/dist/lib/injection-detector.js.map +1 -0
  346. package/dist/lib/injection-semantic.d.ts +31 -0
  347. package/dist/lib/injection-semantic.d.ts.map +1 -0
  348. package/dist/lib/injection-semantic.js +230 -0
  349. package/dist/lib/injection-semantic.js.map +1 -0
  350. package/dist/lib/llm.d.ts +14 -0
  351. package/dist/lib/llm.d.ts.map +1 -1
  352. package/dist/lib/llm.js +44 -8
  353. package/dist/lib/llm.js.map +1 -1
  354. package/dist/lib/lock.d.ts.map +1 -1
  355. package/dist/lib/lock.js +24 -3
  356. package/dist/lib/lock.js.map +1 -1
  357. package/dist/lib/md-fetch.d.ts.map +1 -1
  358. package/dist/lib/md-fetch.js +9 -2
  359. package/dist/lib/md-fetch.js.map +1 -1
  360. package/dist/lib/observability.d.ts +75 -0
  361. package/dist/lib/observability.d.ts.map +1 -0
  362. package/dist/lib/observability.js +201 -0
  363. package/dist/lib/observability.js.map +1 -0
  364. package/dist/lib/ort-session.d.ts +26 -0
  365. package/dist/lib/ort-session.d.ts.map +1 -1
  366. package/dist/lib/ort-session.js +107 -3
  367. package/dist/lib/ort-session.js.map +1 -1
  368. package/dist/lib/prd/codebase-context.d.ts.map +1 -1
  369. package/dist/lib/prd/codebase-context.js +9 -2
  370. package/dist/lib/prd/codebase-context.js.map +1 -1
  371. package/dist/lib/prd/context.d.ts.map +1 -1
  372. package/dist/lib/prd/context.js +11 -3
  373. package/dist/lib/prd/context.js.map +1 -1
  374. package/dist/lib/prd/export.js +1 -1
  375. package/dist/lib/prd/export.js.map +1 -1
  376. package/dist/lib/prd/generate.d.ts.map +1 -1
  377. package/dist/lib/prd/generate.js +19 -5
  378. package/dist/lib/prd/generate.js.map +1 -1
  379. package/dist/lib/prd/parse.d.ts.map +1 -1
  380. package/dist/lib/prd/parse.js +8 -2
  381. package/dist/lib/prd/parse.js.map +1 -1
  382. package/dist/lib/prd/prompt-builder.d.ts +9 -2
  383. package/dist/lib/prd/prompt-builder.d.ts.map +1 -1
  384. package/dist/lib/prd/prompt-builder.js +7 -8
  385. package/dist/lib/prd/prompt-builder.js.map +1 -1
  386. package/dist/lib/prd/runner.d.ts +1 -2
  387. package/dist/lib/prd/runner.d.ts.map +1 -1
  388. package/dist/lib/prd/runner.js +45 -33
  389. package/dist/lib/prd/runner.js.map +1 -1
  390. package/dist/lib/prd/team-runner.js +2 -1
  391. package/dist/lib/prd/team-runner.js.map +1 -1
  392. package/dist/lib/prd/worktree.d.ts +1 -2
  393. package/dist/lib/prd/worktree.d.ts.map +1 -1
  394. package/dist/lib/prd/worktree.js +62 -70
  395. package/dist/lib/prd/worktree.js.map +1 -1
  396. package/dist/lib/precompute-context.d.ts.map +1 -1
  397. package/dist/lib/precompute-context.js +22 -36
  398. package/dist/lib/precompute-context.js.map +1 -1
  399. package/dist/lib/pricing.d.ts.map +1 -1
  400. package/dist/lib/pricing.js +5 -1
  401. package/dist/lib/pricing.js.map +1 -1
  402. package/dist/lib/process-registry.js +3 -3
  403. package/dist/lib/process-registry.js.map +1 -1
  404. package/dist/lib/public-api.d.ts +54 -4
  405. package/dist/lib/public-api.d.ts.map +1 -1
  406. package/dist/lib/public-api.js +52 -2
  407. package/dist/lib/public-api.js.map +1 -1
  408. package/dist/lib/quality.d.ts.map +1 -1
  409. package/dist/lib/quality.js +15 -6
  410. package/dist/lib/quality.js.map +1 -1
  411. package/dist/lib/query-expansion.d.ts +32 -0
  412. package/dist/lib/query-expansion.d.ts.map +1 -1
  413. package/dist/lib/query-expansion.js +64 -13
  414. package/dist/lib/query-expansion.js.map +1 -1
  415. package/dist/lib/reference-embeddings.d.ts.map +1 -1
  416. package/dist/lib/reference-embeddings.js +17 -4
  417. package/dist/lib/reference-embeddings.js.map +1 -1
  418. package/dist/lib/reflection-synthesizer.d.ts.map +1 -1
  419. package/dist/lib/reflection-synthesizer.js +9 -17
  420. package/dist/lib/reflection-synthesizer.js.map +1 -1
  421. package/dist/lib/reranker.d.ts +41 -0
  422. package/dist/lib/reranker.d.ts.map +1 -0
  423. package/dist/lib/reranker.js +294 -0
  424. package/dist/lib/reranker.js.map +1 -0
  425. package/dist/lib/retrieval-feedback.d.ts +100 -0
  426. package/dist/lib/retrieval-feedback.d.ts.map +1 -0
  427. package/dist/lib/retrieval-feedback.js +174 -0
  428. package/dist/lib/retrieval-feedback.js.map +1 -0
  429. package/dist/lib/review/context-pack.d.ts +58 -0
  430. package/dist/lib/review/context-pack.d.ts.map +1 -0
  431. package/dist/lib/review/context-pack.js +300 -0
  432. package/dist/lib/review/context-pack.js.map +1 -0
  433. package/dist/lib/search/hierarchical-summaries.d.ts +65 -0
  434. package/dist/lib/search/hierarchical-summaries.d.ts.map +1 -0
  435. package/dist/lib/search/hierarchical-summaries.js +423 -0
  436. package/dist/lib/search/hierarchical-summaries.js.map +1 -0
  437. package/dist/lib/search/hyde.d.ts +27 -0
  438. package/dist/lib/search/hyde.d.ts.map +1 -0
  439. package/dist/lib/search/hyde.js +141 -0
  440. package/dist/lib/search/hyde.js.map +1 -0
  441. package/dist/lib/search/late-chunking.d.ts +53 -0
  442. package/dist/lib/search/late-chunking.d.ts.map +1 -0
  443. package/dist/lib/search/late-chunking.js +230 -0
  444. package/dist/lib/search/late-chunking.js.map +1 -0
  445. package/dist/lib/search/ppr-retrieval.d.ts +49 -0
  446. package/dist/lib/search/ppr-retrieval.d.ts.map +1 -0
  447. package/dist/lib/search/ppr-retrieval.js +135 -0
  448. package/dist/lib/search/ppr-retrieval.js.map +1 -0
  449. package/dist/lib/search/repo-map.d.ts +43 -0
  450. package/dist/lib/search/repo-map.d.ts.map +1 -0
  451. package/dist/lib/search/repo-map.js +165 -0
  452. package/dist/lib/search/repo-map.js.map +1 -0
  453. package/dist/lib/session-analyzer.d.ts +90 -0
  454. package/dist/lib/session-analyzer.d.ts.map +1 -0
  455. package/dist/lib/session-analyzer.js +467 -0
  456. package/dist/lib/session-analyzer.js.map +1 -0
  457. package/dist/lib/session-observations.d.ts.map +1 -1
  458. package/dist/lib/session-observations.js +13 -3
  459. package/dist/lib/session-observations.js.map +1 -1
  460. package/dist/lib/session-summary.d.ts.map +1 -1
  461. package/dist/lib/session-summary.js +64 -52
  462. package/dist/lib/session-summary.js.map +1 -1
  463. package/dist/lib/session-surgeon.d.ts +53 -0
  464. package/dist/lib/session-surgeon.d.ts.map +1 -0
  465. package/dist/lib/session-surgeon.js +501 -0
  466. package/dist/lib/session-surgeon.js.map +1 -0
  467. package/dist/lib/similarity-utils.d.ts +26 -0
  468. package/dist/lib/similarity-utils.d.ts.map +1 -0
  469. package/dist/lib/similarity-utils.js +66 -0
  470. package/dist/lib/similarity-utils.js.map +1 -0
  471. package/dist/lib/skills.d.ts.map +1 -1
  472. package/dist/lib/skills.js +16 -16
  473. package/dist/lib/skills.js.map +1 -1
  474. package/dist/lib/storage/backends/interface.d.ts +13 -3
  475. package/dist/lib/storage/backends/interface.d.ts.map +1 -1
  476. package/dist/lib/storage/backends/postgresql.d.ts +52 -3
  477. package/dist/lib/storage/backends/postgresql.d.ts.map +1 -1
  478. package/dist/lib/storage/backends/postgresql.js +694 -49
  479. package/dist/lib/storage/backends/postgresql.js.map +1 -1
  480. package/dist/lib/storage/benchmark.js +2 -2
  481. package/dist/lib/storage/benchmark.js.map +1 -1
  482. package/dist/lib/storage/dispatcher/base.d.ts +114 -0
  483. package/dist/lib/storage/dispatcher/base.d.ts.map +1 -0
  484. package/dist/lib/storage/dispatcher/base.js +160 -0
  485. package/dist/lib/storage/dispatcher/base.js.map +1 -0
  486. package/dist/lib/storage/dispatcher/documents.d.ts +25 -0
  487. package/dist/lib/storage/dispatcher/documents.d.ts.map +1 -0
  488. package/dist/lib/storage/dispatcher/documents.js +194 -0
  489. package/dist/lib/storage/dispatcher/documents.js.map +1 -0
  490. package/dist/lib/storage/dispatcher/embeddings.d.ts +34 -0
  491. package/dist/lib/storage/dispatcher/embeddings.d.ts.map +1 -0
  492. package/dist/lib/storage/dispatcher/embeddings.js +144 -0
  493. package/dist/lib/storage/dispatcher/embeddings.js.map +1 -0
  494. package/dist/lib/storage/dispatcher/export-import.d.ts +139 -0
  495. package/dist/lib/storage/dispatcher/export-import.d.ts.map +1 -0
  496. package/dist/lib/storage/dispatcher/export-import.js +191 -0
  497. package/dist/lib/storage/dispatcher/export-import.js.map +1 -0
  498. package/dist/lib/storage/dispatcher/file-hashes.d.ts +13 -0
  499. package/dist/lib/storage/dispatcher/file-hashes.d.ts.map +1 -0
  500. package/dist/lib/storage/dispatcher/file-hashes.js +36 -0
  501. package/dist/lib/storage/dispatcher/file-hashes.js.map +1 -0
  502. package/dist/lib/storage/dispatcher/global-memories.d.ts +28 -0
  503. package/dist/lib/storage/dispatcher/global-memories.d.ts.map +1 -0
  504. package/dist/lib/storage/dispatcher/global-memories.js +151 -0
  505. package/dist/lib/storage/dispatcher/global-memories.js.map +1 -0
  506. package/dist/lib/storage/dispatcher/graph.d.ts +32 -0
  507. package/dist/lib/storage/dispatcher/graph.d.ts.map +1 -0
  508. package/dist/lib/storage/dispatcher/graph.js +146 -0
  509. package/dist/lib/storage/dispatcher/graph.js.map +1 -0
  510. package/dist/lib/storage/dispatcher/index.d.ts +34 -0
  511. package/dist/lib/storage/dispatcher/index.d.ts.map +1 -0
  512. package/dist/lib/storage/dispatcher/index.js +139 -0
  513. package/dist/lib/storage/dispatcher/index.js.map +1 -0
  514. package/dist/lib/storage/dispatcher/memories.d.ts +65 -0
  515. package/dist/lib/storage/dispatcher/memories.d.ts.map +1 -0
  516. package/dist/lib/storage/dispatcher/memories.js +466 -0
  517. package/dist/lib/storage/dispatcher/memories.js.map +1 -0
  518. package/dist/lib/storage/dispatcher/mixin-helper.d.ts +6 -0
  519. package/dist/lib/storage/dispatcher/mixin-helper.d.ts.map +1 -0
  520. package/dist/lib/storage/dispatcher/mixin-helper.js +10 -0
  521. package/dist/lib/storage/dispatcher/mixin-helper.js.map +1 -0
  522. package/dist/lib/storage/dispatcher/retention.d.ts +20 -0
  523. package/dist/lib/storage/dispatcher/retention.d.ts.map +1 -0
  524. package/dist/lib/storage/dispatcher/retention.js +123 -0
  525. package/dist/lib/storage/dispatcher/retention.js.map +1 -0
  526. package/dist/lib/storage/dispatcher/search.d.ts +34 -0
  527. package/dist/lib/storage/dispatcher/search.d.ts.map +1 -0
  528. package/dist/lib/storage/dispatcher/search.js +222 -0
  529. package/dist/lib/storage/dispatcher/search.js.map +1 -0
  530. package/dist/lib/storage/dispatcher/skills.d.ts +53 -0
  531. package/dist/lib/storage/dispatcher/skills.d.ts.map +1 -0
  532. package/dist/lib/storage/dispatcher/skills.js +98 -0
  533. package/dist/lib/storage/dispatcher/skills.js.map +1 -0
  534. package/dist/lib/storage/dispatcher/token-stats.d.ts +23 -0
  535. package/dist/lib/storage/dispatcher/token-stats.d.ts.map +1 -0
  536. package/dist/lib/storage/dispatcher/token-stats.js +92 -0
  537. package/dist/lib/storage/dispatcher/token-stats.js.map +1 -0
  538. package/dist/lib/storage/dispatcher/web-search.d.ts +10 -0
  539. package/dist/lib/storage/dispatcher/web-search.d.ts.map +1 -0
  540. package/dist/lib/storage/dispatcher/web-search.js +39 -0
  541. package/dist/lib/storage/dispatcher/web-search.js.map +1 -0
  542. package/dist/lib/storage/dispatcher-export.d.ts.map +1 -1
  543. package/dist/lib/storage/dispatcher-export.js +48 -39
  544. package/dist/lib/storage/dispatcher-export.js.map +1 -1
  545. package/dist/lib/storage/dispatcher.d.ts +1 -468
  546. package/dist/lib/storage/dispatcher.d.ts.map +1 -1
  547. package/dist/lib/storage/dispatcher.js +1 -1931
  548. package/dist/lib/storage/dispatcher.js.map +1 -1
  549. package/dist/lib/storage/index.d.ts +20 -5
  550. package/dist/lib/storage/index.d.ts.map +1 -1
  551. package/dist/lib/storage/index.js +36 -7
  552. package/dist/lib/storage/index.js.map +1 -1
  553. package/dist/lib/storage/migration/export-import.d.ts.map +1 -1
  554. package/dist/lib/storage/migration/export-import.js +9 -2
  555. package/dist/lib/storage/migration/export-import.js.map +1 -1
  556. package/dist/lib/storage/types.d.ts +152 -10
  557. package/dist/lib/storage/types.d.ts.map +1 -1
  558. package/dist/lib/storage/types.js +13 -0
  559. package/dist/lib/storage/types.js.map +1 -1
  560. package/dist/lib/storage/vector/interface.d.ts +4 -0
  561. package/dist/lib/storage/vector/interface.d.ts.map +1 -1
  562. package/dist/lib/storage/vector/qdrant.d.ts +13 -2
  563. package/dist/lib/storage/vector/qdrant.d.ts.map +1 -1
  564. package/dist/lib/storage/vector/qdrant.js +147 -61
  565. package/dist/lib/storage/vector/qdrant.js.map +1 -1
  566. package/dist/lib/supersession.d.ts.map +1 -1
  567. package/dist/lib/supersession.js +2 -15
  568. package/dist/lib/supersession.js.map +1 -1
  569. package/dist/lib/token-budget.d.ts.map +1 -1
  570. package/dist/lib/token-budget.js +9 -2
  571. package/dist/lib/token-budget.js.map +1 -1
  572. package/dist/lib/transcript-utils.d.ts +60 -0
  573. package/dist/lib/transcript-utils.d.ts.map +1 -0
  574. package/dist/lib/transcript-utils.js +69 -0
  575. package/dist/lib/transcript-utils.js.map +1 -0
  576. package/dist/lib/tree-sitter/extractor.d.ts +1 -1
  577. package/dist/lib/tree-sitter/extractor.d.ts.map +1 -1
  578. package/dist/lib/tree-sitter/extractor.js +34 -9
  579. package/dist/lib/tree-sitter/extractor.js.map +1 -1
  580. package/dist/lib/tree-sitter/parser.d.ts.map +1 -1
  581. package/dist/lib/tree-sitter/parser.js +45 -11
  582. package/dist/lib/tree-sitter/parser.js.map +1 -1
  583. package/dist/lib/tree-sitter/public.d.ts +12 -0
  584. package/dist/lib/tree-sitter/public.d.ts.map +1 -1
  585. package/dist/lib/tree-sitter/public.js +33 -1
  586. package/dist/lib/tree-sitter/public.js.map +1 -1
  587. package/dist/lib/tree-sitter/queries.d.ts.map +1 -1
  588. package/dist/lib/tree-sitter/queries.js +8 -0
  589. package/dist/lib/tree-sitter/queries.js.map +1 -1
  590. package/dist/lib/working-memory-pipeline.d.ts.map +1 -1
  591. package/dist/lib/working-memory-pipeline.js +12 -3
  592. package/dist/lib/working-memory-pipeline.js.map +1 -1
  593. package/dist/lib/worktree-detect.d.ts +43 -0
  594. package/dist/lib/worktree-detect.d.ts.map +1 -0
  595. package/dist/lib/worktree-detect.js +154 -0
  596. package/dist/lib/worktree-detect.js.map +1 -0
  597. package/dist/lsp/client.d.ts +96 -0
  598. package/dist/lsp/client.d.ts.map +1 -0
  599. package/dist/lsp/client.js +435 -0
  600. package/dist/lsp/client.js.map +1 -0
  601. package/dist/lsp/installer.d.ts +39 -0
  602. package/dist/lsp/installer.d.ts.map +1 -0
  603. package/dist/lsp/installer.js +275 -0
  604. package/dist/lsp/installer.js.map +1 -0
  605. package/dist/lsp/manager.d.ts +62 -0
  606. package/dist/lsp/manager.d.ts.map +1 -0
  607. package/dist/lsp/manager.js +234 -0
  608. package/dist/lsp/manager.js.map +1 -0
  609. package/dist/lsp/servers.d.ts +52 -0
  610. package/dist/lsp/servers.d.ts.map +1 -0
  611. package/dist/lsp/servers.js +162 -0
  612. package/dist/lsp/servers.js.map +1 -0
  613. package/dist/mcp/helpers.d.ts +11 -0
  614. package/dist/mcp/helpers.d.ts.map +1 -1
  615. package/dist/mcp/helpers.js +43 -2
  616. package/dist/mcp/helpers.js.map +1 -1
  617. package/dist/mcp/profile.d.ts +16 -0
  618. package/dist/mcp/profile.d.ts.map +1 -0
  619. package/dist/mcp/profile.js +64 -0
  620. package/dist/mcp/profile.js.map +1 -0
  621. package/dist/mcp/server.d.ts +17 -15
  622. package/dist/mcp/server.d.ts.map +1 -1
  623. package/dist/mcp/server.js +135 -22
  624. package/dist/mcp/server.js.map +1 -1
  625. package/dist/mcp/tools/config.d.ts +1 -5
  626. package/dist/mcp/tools/config.d.ts.map +1 -1
  627. package/dist/mcp/tools/config.js +169 -215
  628. package/dist/mcp/tools/config.js.map +1 -1
  629. package/dist/mcp/tools/dead-end.d.ts.map +1 -1
  630. package/dist/mcp/tools/dead-end.js +24 -14
  631. package/dist/mcp/tools/dead-end.js.map +1 -1
  632. package/dist/mcp/tools/debug.d.ts.map +1 -1
  633. package/dist/mcp/tools/debug.js +103 -179
  634. package/dist/mcp/tools/debug.js.map +1 -1
  635. package/dist/mcp/tools/graph.d.ts +0 -1
  636. package/dist/mcp/tools/graph.d.ts.map +1 -1
  637. package/dist/mcp/tools/graph.js +225 -233
  638. package/dist/mcp/tools/graph.js.map +1 -1
  639. package/dist/mcp/tools/indexing.d.ts +1 -7
  640. package/dist/mcp/tools/indexing.d.ts.map +1 -1
  641. package/dist/mcp/tools/indexing.js +180 -268
  642. package/dist/mcp/tools/indexing.js.map +1 -1
  643. package/dist/mcp/tools/memory/forget.d.ts +3 -0
  644. package/dist/mcp/tools/memory/forget.d.ts.map +1 -0
  645. package/dist/mcp/tools/memory/forget.js +175 -0
  646. package/dist/mcp/tools/memory/forget.js.map +1 -0
  647. package/dist/mcp/tools/memory/memory-helpers.d.ts +45 -0
  648. package/dist/mcp/tools/memory/memory-helpers.d.ts.map +1 -0
  649. package/dist/mcp/tools/memory/memory-helpers.js +291 -0
  650. package/dist/mcp/tools/memory/memory-helpers.js.map +1 -0
  651. package/dist/mcp/tools/memory/recall.d.ts +3 -0
  652. package/dist/mcp/tools/memory/recall.d.ts.map +1 -0
  653. package/dist/mcp/tools/memory/recall.js +495 -0
  654. package/dist/mcp/tools/memory/recall.js.map +1 -0
  655. package/dist/mcp/tools/memory/remember.d.ts +3 -0
  656. package/dist/mcp/tools/memory/remember.d.ts.map +1 -0
  657. package/dist/mcp/tools/memory/remember.js +256 -0
  658. package/dist/mcp/tools/memory/remember.js.map +1 -0
  659. package/dist/mcp/tools/memory/temporal-query.d.ts +8 -0
  660. package/dist/mcp/tools/memory/temporal-query.d.ts.map +1 -0
  661. package/dist/mcp/tools/memory/temporal-query.js +68 -0
  662. package/dist/mcp/tools/memory/temporal-query.js.map +1 -0
  663. package/dist/mcp/tools/memory.d.ts +0 -11
  664. package/dist/mcp/tools/memory.d.ts.map +1 -1
  665. package/dist/mcp/tools/memory.js +6 -1184
  666. package/dist/mcp/tools/memory.js.map +1 -1
  667. package/dist/mcp/tools/prd.d.ts +1 -7
  668. package/dist/mcp/tools/prd.d.ts.map +1 -1
  669. package/dist/mcp/tools/prd.js +198 -255
  670. package/dist/mcp/tools/prd.js.map +1 -1
  671. package/dist/mcp/tools/review.d.ts +8 -0
  672. package/dist/mcp/tools/review.d.ts.map +1 -0
  673. package/dist/mcp/tools/review.js +133 -0
  674. package/dist/mcp/tools/review.js.map +1 -0
  675. package/dist/mcp/tools/search.d.ts.map +1 -1
  676. package/dist/mcp/tools/search.js +168 -47
  677. package/dist/mcp/tools/search.js.map +1 -1
  678. package/dist/mcp/tools/status.d.ts +1 -5
  679. package/dist/mcp/tools/status.d.ts.map +1 -1
  680. package/dist/mcp/tools/status.js +270 -273
  681. package/dist/mcp/tools/status.js.map +1 -1
  682. package/dist/mcp/tools/web-fetch.d.ts +2 -1
  683. package/dist/mcp/tools/web-fetch.d.ts.map +1 -1
  684. package/dist/mcp/tools/web-fetch.js +72 -43
  685. package/dist/mcp/tools/web-fetch.js.map +1 -1
  686. package/dist/mcp/tools/web-search.d.ts +1 -6
  687. package/dist/mcp/tools/web-search.d.ts.map +1 -1
  688. package/dist/mcp/tools/web-search.js +199 -276
  689. package/dist/mcp/tools/web-search.js.map +1 -1
  690. package/dist/prompts/briefing.d.ts +10 -4
  691. package/dist/prompts/briefing.d.ts.map +1 -1
  692. package/dist/prompts/briefing.js +33 -35
  693. package/dist/prompts/briefing.js.map +1 -1
  694. package/dist/prompts/daemon.d.ts +5 -10
  695. package/dist/prompts/daemon.d.ts.map +1 -1
  696. package/dist/prompts/daemon.js +9 -18
  697. package/dist/prompts/daemon.js.map +1 -1
  698. package/dist/prompts/extraction.d.ts +19 -3
  699. package/dist/prompts/extraction.d.ts.map +1 -1
  700. package/dist/prompts/extraction.js +33 -46
  701. package/dist/prompts/extraction.js.map +1 -1
  702. package/dist/prompts/graph.d.ts +9 -0
  703. package/dist/prompts/graph.d.ts.map +1 -0
  704. package/dist/prompts/graph.js +27 -0
  705. package/dist/prompts/graph.js.map +1 -0
  706. package/dist/prompts/guardrails.d.ts +14 -0
  707. package/dist/prompts/guardrails.d.ts.map +1 -0
  708. package/dist/prompts/guardrails.js +115 -0
  709. package/dist/prompts/guardrails.js.map +1 -0
  710. package/dist/prompts/index.d.ts +17 -7
  711. package/dist/prompts/index.d.ts.map +1 -1
  712. package/dist/prompts/index.js +23 -7
  713. package/dist/prompts/index.js.map +1 -1
  714. package/dist/prompts/memory.d.ts +6 -3
  715. package/dist/prompts/memory.d.ts.map +1 -1
  716. package/dist/prompts/memory.js +9 -8
  717. package/dist/prompts/memory.js.map +1 -1
  718. package/dist/prompts/onboarding.d.ts +1 -1
  719. package/dist/prompts/onboarding.d.ts.map +1 -1
  720. package/dist/prompts/onboarding.js +2 -3
  721. package/dist/prompts/onboarding.js.map +1 -1
  722. package/dist/prompts/prd.d.ts +13 -6
  723. package/dist/prompts/prd.d.ts.map +1 -1
  724. package/dist/prompts/prd.js +42 -38
  725. package/dist/prompts/prd.js.map +1 -1
  726. package/dist/prompts/query-expansion.d.ts +8 -0
  727. package/dist/prompts/query-expansion.d.ts.map +1 -0
  728. package/dist/prompts/query-expansion.js +17 -0
  729. package/dist/prompts/query-expansion.js.map +1 -0
  730. package/dist/prompts/skills.d.ts +5 -10
  731. package/dist/prompts/skills.d.ts.map +1 -1
  732. package/dist/prompts/skills.js +9 -17
  733. package/dist/prompts/skills.js.map +1 -1
  734. package/dist/prompts/soul.d.ts +9 -0
  735. package/dist/prompts/soul.d.ts.map +1 -0
  736. package/dist/prompts/soul.js +47 -0
  737. package/dist/prompts/soul.js.map +1 -0
  738. package/dist/prompts/supersession.d.ts +9 -0
  739. package/dist/prompts/supersession.d.ts.map +1 -0
  740. package/dist/prompts/supersession.js +21 -0
  741. package/dist/prompts/supersession.js.map +1 -0
  742. package/dist/prompts/synthesis.d.ts +9 -0
  743. package/dist/prompts/synthesis.d.ts.map +1 -0
  744. package/dist/prompts/synthesis.js +22 -0
  745. package/dist/prompts/synthesis.js.map +1 -0
  746. package/hooks/core/__tests__/adapter.test.cjs +340 -0
  747. package/hooks/core/adapter.cjs +463 -0
  748. package/hooks/core/config.cjs +83 -0
  749. package/hooks/core/daemon-boot.cjs +140 -0
  750. package/hooks/core/log.cjs +41 -0
  751. package/hooks/core/worktree.cjs +119 -0
  752. package/hooks/succ-post-tool.cjs +198 -134
  753. package/hooks/succ-pre-compact.cjs +262 -0
  754. package/hooks/succ-pre-tool.cjs +526 -182
  755. package/hooks/succ-session-end.cjs +40 -64
  756. package/hooks/succ-session-start.cjs +504 -450
  757. package/hooks/succ-stop-reflection.cjs +36 -62
  758. package/hooks/succ-user-prompt.cjs +137 -180
  759. package/package.json +18 -7
@@ -22,6 +22,9 @@
22
22
 
23
23
  const fs = require('fs');
24
24
  const path = require('path');
25
+ const adapter = require('./core/adapter.cjs');
26
+ const { getDaemonPort } = require('./core/daemon-boot.cjs');
27
+ const { loadMergedConfig } = require('./core/config.cjs');
25
28
 
26
29
  // ─── Dangerous command patterns ──────────────────────────────────────
27
30
 
@@ -76,6 +79,18 @@ const DANGEROUS_PATTERNS = [
76
79
  pattern: /\bgit\s+reflog\s+expire\s+--expire=now\b/,
77
80
  reason: 'git reflog expire --expire=now permanently removes recovery points.',
78
81
  },
82
+ {
83
+ pattern: /\bgit\s+filter-branch\b/,
84
+ reason: 'git filter-branch rewrites history and can destroy data.',
85
+ },
86
+ {
87
+ pattern: /\bgit\s+.*--no-verify\b/,
88
+ reason: 'git --no-verify skips pre-commit hooks (safety checks bypassed).',
89
+ },
90
+ {
91
+ pattern: /\bgit\s+restore\s+\.\s*($|[;&|])/,
92
+ reason: 'git restore . discards all modifications.',
93
+ },
79
94
 
80
95
  // ── Filesystem — data loss ──
81
96
  {
@@ -93,6 +108,14 @@ const DANGEROUS_PATTERNS = [
93
108
  reason: 'rm -fr can permanently delete files. Verify the target path.',
94
109
  checkPath: true,
95
110
  },
111
+ { pattern: /\brm\s+-r\s+\/\s/, reason: 'rm -r / would destroy the entire filesystem.' },
112
+ {
113
+ pattern: /\brm\s+-r\s+~(?:\s|\/|$)/,
114
+ reason: 'rm -r ~ would destroy the entire home directory.',
115
+ },
116
+ { pattern: /\bshred\b/, reason: 'shred permanently overwrites file data beyond recovery.' },
117
+ { pattern: /\bdd\s+.*\bof=\/dev\//, reason: 'dd writing to /dev/ can destroy disk data.' },
118
+ { pattern: /\bmkfs\b/, reason: 'mkfs formats a filesystem, destroying all data.' },
96
119
 
97
120
  // ── Docker — container/image/volume destruction ──
98
121
  {
@@ -172,13 +195,93 @@ const DANGEROUS_PATTERNS = [
172
195
  pattern: /\bcurl\b.*\b:6334\b.*\bDELETE\b/i,
173
196
  reason: 'DELETE on Qdrant gRPC port can remove data permanently.',
174
197
  },
198
+
199
+ // ── Infrastructure ──
200
+ {
201
+ pattern: /\bterraform\s+destroy\b/,
202
+ reason: 'terraform destroy tears down all managed infrastructure.',
203
+ },
204
+ {
205
+ pattern: /\bkubectl\s+delete\s+(?:ns|namespace)\b/,
206
+ reason: 'kubectl delete namespace removes all resources.',
207
+ },
208
+ {
209
+ pattern: /\bkubectl\s+delete\s+.*--all\b/,
210
+ reason: 'kubectl delete --all removes all resources of type.',
211
+ },
212
+ { pattern: /\bhelm\s+uninstall\b/, reason: 'helm uninstall removes a Helm release.' },
213
+
214
+ // ── Redis ──
215
+ { pattern: /\bredis-cli\b.*\bFLUSHALL\b/i, reason: 'FLUSHALL removes all Redis data.' },
216
+ { pattern: /\bredis-cli\b.*\bFLUSHDB\b/i, reason: 'FLUSHDB removes current Redis DB data.' },
217
+
218
+ // ── MongoDB ──
219
+ {
220
+ pattern: /\bmongo(?:sh)?\b.*\bdropDatabase\b/,
221
+ reason: 'dropDatabase deletes a MongoDB database.',
222
+ },
223
+ { pattern: /\bmongo(?:sh)?\b.*\.drop\s*\(/, reason: '.drop() deletes a MongoDB collection.' },
224
+
225
+ // ── Permissions ──
226
+ { pattern: /\bchmod\s+-R\s+777\b/, reason: 'chmod -R 777 makes everything world-writable.' },
227
+ { pattern: /\bchmod\s+-R\s+666\b/, reason: 'chmod -R 666 makes all files world-writable.' },
228
+ { pattern: /\bchown\s+-R\s+root\b/, reason: 'chown -R root changes ownership recursively.' },
229
+
230
+ // ── Disk ──
231
+ { pattern: /\bfdisk\b/, reason: 'fdisk modifies disk partitions.' },
232
+ { pattern: /\bparted\b/, reason: 'parted modifies disk partitions.' },
233
+ { pattern: /\bwipefs\b/, reason: 'wipefs erases filesystem signatures.' },
234
+
235
+ // ── Process ──
236
+ { pattern: /\bkillall\b/, reason: 'killall terminates all matching processes.' },
237
+ { pattern: /\bkill\s+-9\b/, reason: 'kill -9 forcefully terminates (SIGKILL).' },
238
+ { pattern: /\bkill\s+-(?:KILL|SIGKILL)\b/, reason: 'kill -KILL forcefully terminates.' },
239
+
240
+ // ── Lockfiles ──
241
+ {
242
+ pattern: /\brm\s+.*package-lock\.json\b/,
243
+ reason: 'Deleting package-lock.json causes dep issues.',
244
+ },
245
+ { pattern: /\brm\s+.*yarn\.lock\b/, reason: 'Deleting yarn.lock causes dep issues.' },
246
+ { pattern: /\brm\s+.*pnpm-lock\.yaml\b/, reason: 'Deleting pnpm-lock.yaml causes dep issues.' },
247
+
248
+ // ── Exfiltration ──
249
+ {
250
+ pattern: /\bcurl\b.*(?:-d\b|--data\b|--form\b)/,
251
+ reason: 'curl with data flags can exfiltrate information.',
252
+ exemptLocalhost: true,
253
+ },
254
+ { pattern: /\bwget\s+--post-data\b/, reason: 'wget --post-data can exfiltrate information.' },
255
+ { pattern: /\bnc\s+-[a-zA-Z]*\s/, reason: 'netcat can exfiltrate data or open reverse shells.' },
256
+ {
257
+ pattern: /\bbase64\b.*\|\s*\bcurl\b/,
258
+ reason: 'Piping base64 to curl is exfiltration pattern.',
259
+ },
260
+ { pattern: /\bcat\b.*\|\s*\bcurl\b/, reason: 'Piping file to curl can exfiltrate data.' },
261
+
262
+ // ── Supply chain ──
263
+ {
264
+ pattern: /\bcurl\b.*\|\s*(?:bash|sh|zsh)\b/,
265
+ reason: 'Piping curl to shell runs untrusted code.',
266
+ },
267
+ {
268
+ pattern: /\bwget\b.*\|\s*(?:bash|sh|zsh)\b/,
269
+ reason: 'Piping wget to shell runs untrusted code.',
270
+ },
271
+ {
272
+ pattern: /\bpip\s+install\s+-i\s/,
273
+ reason: 'pip install -i uses custom index (supply chain risk).',
274
+ },
275
+ {
276
+ pattern: /\bnpm\s+install\s+--registry\s/,
277
+ reason: 'npm --registry uses custom registry (supply chain risk).',
278
+ },
175
279
  ];
176
280
 
177
281
  // Paths where rm -rf is considered safe (normalized, lowercase)
178
282
  const SAFE_RM_PATHS = [
179
283
  '/tmp',
180
284
  '/var/tmp',
181
- 'node_modules',
182
285
  'dist',
183
286
  'build',
184
287
  '.cache',
@@ -205,58 +308,285 @@ const DATA_PREFIXES = [
205
308
  /^\s*(?:"|').*(?:"|')\s*$/, // quoted string
206
309
  ];
207
310
 
311
+ // ─── Content Sanitization (inline — no imports in .cjs) ─────────────
312
+
313
+ function escapeXml(text) {
314
+ return text
315
+ .replace(/&/g, '&')
316
+ .replace(/</g, '&lt;')
317
+ .replace(/>/g, '&gt;')
318
+ .replace(/"/g, '&quot;')
319
+ .replace(/'/g, '&apos;');
320
+ }
321
+
322
+ function stripControlChars(text) {
323
+ return text.replace(/[\u200B\u200C\u200D\uFEFF\u00AD\u2060\u202A-\u202E\u2066-\u2069]/g, '');
324
+ }
325
+
326
+ function sanitize(text, maxLen) {
327
+ maxLen = maxLen || 5000;
328
+ let cleaned = stripControlChars(text);
329
+ if (cleaned.length > maxLen) cleaned = cleaned.slice(0, maxLen) + '... [truncated]';
330
+ return escapeXml(cleaned);
331
+ }
332
+
333
+ function sanitizeFileName(name) {
334
+ let cleaned = name.replace(/\0/g, ''); // Strip null bytes
335
+ cleaned = stripControlChars(cleaned);
336
+ cleaned = cleaned.replace(/[/\\]/g, '');
337
+ return escapeXml(cleaned);
338
+ }
339
+
340
+ // ─── Tier 1 Injection Detection (inline — structural patterns) ──────
341
+
342
+ const TIER1_PATTERNS = [
343
+ // Delimiter injection
344
+ { re: /<\|im_start\|>/i, desc: 'ChatML delimiter' },
345
+ { re: /<\|im_end\|>/i, desc: 'ChatML delimiter' },
346
+ { re: /\[INST\]/i, desc: 'Llama delimiter' },
347
+ { re: /\[\/INST\]/i, desc: 'Llama delimiter' },
348
+ { re: /<<SYS>>/i, desc: 'Llama system delimiter' },
349
+ { re: /<\|endoftext\|>/i, desc: 'GPT endoftext token' },
350
+ { re: /<\|system\|>/i, desc: 'System role token' },
351
+ {
352
+ re: /<\/(?:hook-rule|file-context|soul|previous-session|session|compact-fallback|security-warning|commit-format|pre-commit-review|succ-agents)>/i,
353
+ desc: 'Closing succ XML tag',
354
+ },
355
+ { re: /<\/?system>/i, desc: 'XML system tag' },
356
+ { re: /<\/?assistant>/i, desc: 'XML assistant tag' },
357
+ { re: /<\/?user>/i, desc: 'XML user tag' },
358
+ { re: /\[system\]/i, desc: 'Bracketed system role' },
359
+ { re: /\[assistant\]/i, desc: 'Bracketed assistant role' },
360
+ // End-of-sequence token (avoid false positive on HTML <s>text</s>)
361
+ { re: /(?<!<s[^>]*>.*)<\/s>/i, desc: 'End-of-sequence token' },
362
+ // Hidden content / obfuscation
363
+ { re: /[\u200B\u200C\u200D\uFEFF\u00AD\u2060]{3,}/, desc: 'Zero-width char cluster' },
364
+ { re: /[\u202A-\u202E\u2066-\u2069]{2,}/, desc: 'RTL/LTR override abuse' },
365
+ {
366
+ re: /<(?:span|div|p)\s+[^>]*(?:display\s*:\s*none|visibility\s*:\s*hidden|hidden)[^>]*>/i,
367
+ desc: 'Hidden HTML element',
368
+ },
369
+ {
370
+ re: /<!--\s*(?:AI|AGENT|LLM|ASSISTANT|IGNORE|INSTRUCTION|SYSTEM|OVERRIDE)/i,
371
+ desc: 'HTML comment targeting AI',
372
+ },
373
+ // Encoded injection
374
+ {
375
+ re: /&(?:lt|gt|amp|quot);.*(?:system|assistant|ignore|instruction)/i,
376
+ desc: 'HTML-entity encoded injection',
377
+ },
378
+ {
379
+ re: /(?:base64|atob|decode)\s*[:(]\s*['"]?[A-Za-z0-9+/]{20,}={0,2}/i,
380
+ desc: 'Explicitly decoded base64',
381
+ },
382
+ ];
383
+
384
+ function detectTier1(text) {
385
+ for (const { re, desc } of TIER1_PATTERNS) {
386
+ if (re.test(text)) return desc;
387
+ }
388
+ return null;
389
+ }
390
+
391
+ // ─── File Operation Guards (inline) ─────────────────────────────────
392
+
393
+ const SENSITIVE_EXTENSIONS = ['.pem', '.key', '.p12', '.pfx', '.jks', '.keystore'];
394
+
395
+ const PROTECTED_DELETE_PATTERNS = [
396
+ {
397
+ pattern: /\.gitignore$/i,
398
+ reason: '.gitignore controls tracked files — deletion can expose secrets.',
399
+ },
400
+ {
401
+ pattern: /Dockerfile$/i,
402
+ reason: 'Dockerfile is critical infrastructure — verify before deleting.',
403
+ },
404
+ {
405
+ pattern: /\.github\/workflows\//i,
406
+ reason: 'CI/CD workflow — deletion can break deployment pipeline.',
407
+ },
408
+ {
409
+ pattern: /\.gitlab-ci\.yml$/i,
410
+ reason: 'CI/CD config — deletion can break deployment pipeline.',
411
+ },
412
+ {
413
+ pattern: /CODEOWNERS$/i,
414
+ reason: 'CODEOWNERS controls review policy — verify before deleting.',
415
+ },
416
+ {
417
+ pattern: /migrations?\//i,
418
+ reason: 'Migration files are sequential — deletion can corrupt database schema.',
419
+ },
420
+ {
421
+ pattern: /package-lock\.json$/i,
422
+ reason: 'Lockfile ensures reproducible builds — deletion causes dep issues.',
423
+ },
424
+ {
425
+ pattern: /yarn\.lock$/i,
426
+ reason: 'Lockfile ensures reproducible builds — deletion causes dep issues.',
427
+ },
428
+ {
429
+ pattern: /pnpm-lock\.yaml$/i,
430
+ reason: 'Lockfile ensures reproducible builds — deletion causes dep issues.',
431
+ },
432
+ ];
433
+
434
+ function checkFileGuard(operation, filePath) {
435
+ const normalized = filePath.replace(/\\/g, '/').toLowerCase();
436
+ // Extract all extensions for compound extension check (e.g. file.pem.bak → .pem, .bak)
437
+ const basename = normalized.split('/').pop() || '';
438
+ const parts = basename.split('.');
439
+ if (normalized.includes('/node_modules/') || normalized.includes('/.git/')) return null;
440
+ // Sensitive file extensions — deny read/write (check all extensions, not just last)
441
+ if (operation === 'read' || operation === 'write') {
442
+ for (let i = 1; i < parts.length; i++) {
443
+ const ext = '.' + parts[i];
444
+ if (SENSITIVE_EXTENSIONS.includes(ext)) {
445
+ return {
446
+ reason: `${ext} files contain private keys/certificates — ${operation} blocked.`,
447
+ mode: 'deny',
448
+ };
449
+ }
450
+ }
451
+ }
452
+ // Protected files — deny delete (Bash rm commands handled separately, this is for the delete flag)
453
+ if (operation === 'delete') {
454
+ for (const { pattern, reason } of PROTECTED_DELETE_PATTERNS) {
455
+ if (pattern.test(normalized)) {
456
+ return { reason, mode: 'deny' };
457
+ }
458
+ }
459
+ }
460
+ if (operation === 'write' && /\.env(?:\.|$)/i.test(normalized)) {
461
+ return { reason: '.env files may contain secrets — verify content.', mode: 'ask' };
462
+ }
463
+ return null;
464
+ }
465
+
466
+ // ─── Lightweight IFC labels (inline — proactive file label for context) ──
467
+
468
+ const IFC_EXTENSION_LABELS = {
469
+ '.pem': { level: 3, label: 'highly_confidential {credentials}' },
470
+ '.key': { level: 3, label: 'highly_confidential {credentials}' },
471
+ '.p12': { level: 3, label: 'highly_confidential {credentials}' },
472
+ '.pfx': { level: 3, label: 'highly_confidential {credentials}' },
473
+ '.jks': { level: 3, label: 'highly_confidential {credentials}' },
474
+ '.keystore': { level: 3, label: 'highly_confidential {credentials}' },
475
+ };
476
+
477
+ const IFC_PATH_PATTERNS = [
478
+ { re: /[/\\]secrets?[/\\]/i, level: 3, label: 'highly_confidential {secrets}' },
479
+ { re: /[/\\]\.ssh[/\\]/i, level: 3, label: 'highly_confidential {credentials}' },
480
+ { re: /[/\\]deploy[/\\]/i, level: 2, label: 'confidential {internal_infra}' },
481
+ { re: /[/\\]terraform[/\\]/i, level: 2, label: 'confidential {internal_infra}' },
482
+ { re: /[/\\]k8s[/\\]/i, level: 2, label: 'confidential {internal_infra}' },
483
+ ];
484
+
485
+ /**
486
+ * Quick file label for .cjs hook (no state, just classification).
487
+ * Returns { level, label } or null for public files.
488
+ */
489
+ function quickFileLabel(filePath) {
490
+ const lower = filePath.toLowerCase().replace(/\\/g, '/');
491
+ const basename = lower.split('/').pop() || '';
492
+
493
+ // .env files (but not env.sh, env.py, etc.)
494
+ if (basename === '.env' || basename.startsWith('.env.')) {
495
+ return { level: 2, label: 'confidential {secrets, credentials}' };
496
+ }
497
+ if (basename.startsWith('env.')) {
498
+ const afterDot = basename.slice(4);
499
+ if (!/^(?:sh|py|ts|js|rb|go|rs|pl|bat|cmd|ps1|php|java|c|h|cpp)$/i.test(afterDot)) {
500
+ return { level: 2, label: 'confidential {secrets, credentials}' };
501
+ }
502
+ }
503
+
504
+ // Extension check
505
+ const lastDot = basename.lastIndexOf('.');
506
+ if (lastDot >= 0) {
507
+ const ext = basename.slice(lastDot);
508
+ if (IFC_EXTENSION_LABELS[ext]) return IFC_EXTENSION_LABELS[ext];
509
+ }
510
+
511
+ // Path check (take highest)
512
+ let best = null;
513
+ for (const { re, level, label } of IFC_PATH_PATTERNS) {
514
+ if (re.test(lower) && (!best || level > best.level)) {
515
+ best = { level, label };
516
+ }
517
+ }
518
+
519
+ return best;
520
+ }
521
+
208
522
  // ─── Helpers ─────────────────────────────────────────────────────────
209
523
 
210
524
  function loadConfig(projectDir) {
211
- const defaults = {
212
- commandSafetyGuard: { mode: 'deny', allowlist: [], customPatterns: [] },
213
- includeCoAuthoredBy: true,
214
- preCommitReview: false,
525
+ const merged = loadMergedConfig(projectDir);
526
+ const csg = merged.commandSafetyGuard || {};
527
+ return {
528
+ commandSafetyGuard: {
529
+ mode: csg.mode || 'deny',
530
+ allowlist: Array.isArray(csg.allowlist) ? csg.allowlist : [],
531
+ customPatterns: Array.isArray(csg.customPatterns) ? csg.customPatterns : [],
532
+ },
533
+ includeCoAuthoredBy: merged.includeCoAuthoredBy !== false,
534
+ preCommitReview: merged.preCommitReview === true,
215
535
  };
536
+ }
216
537
 
217
- const configPaths = [
218
- path.join(projectDir, '.succ', 'config.json'),
219
- path.join(require('os').homedir(), '.succ', 'config.json'),
220
- ];
221
-
222
- for (const configPath of configPaths) {
223
- if (fs.existsSync(configPath)) {
224
- try {
225
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
226
-
227
- // Command safety guard
228
- if (config.commandSafetyGuard) {
229
- if (config.commandSafetyGuard.mode) {
230
- defaults.commandSafetyGuard.mode = config.commandSafetyGuard.mode;
231
- }
232
- if (Array.isArray(config.commandSafetyGuard.allowlist)) {
233
- defaults.commandSafetyGuard.allowlist = config.commandSafetyGuard.allowlist;
234
- }
235
- if (Array.isArray(config.commandSafetyGuard.customPatterns)) {
236
- defaults.commandSafetyGuard.customPatterns = config.commandSafetyGuard.customPatterns;
237
- }
238
- }
239
-
240
- if (config.includeCoAuthoredBy === false) {
241
- defaults.includeCoAuthoredBy = false;
242
- }
243
- if (config.preCommitReview === true) {
244
- defaults.preCommitReview = true;
245
- }
246
-
247
- break;
248
- } catch {
249
- // Ignore parse errors
538
+ /**
539
+ * Split a shell command line into individual commands separated by ;, &&, ||, |.
540
+ * Respects quoted strings (single and double quotes).
541
+ */
542
+ function splitShellCommands(command) {
543
+ const parts = [];
544
+ let current = '';
545
+ let inSingle = false;
546
+ let inDouble = false;
547
+ let i = 0;
548
+ while (i < command.length) {
549
+ const ch = command[i];
550
+ if (ch === "'" && !inDouble) {
551
+ inSingle = !inSingle;
552
+ current += ch;
553
+ i++;
554
+ } else if (ch === '"' && !inSingle) {
555
+ inDouble = !inDouble;
556
+ current += ch;
557
+ i++;
558
+ } else if (!inSingle && !inDouble) {
559
+ if (command[i] === '&' && command[i + 1] === '&') {
560
+ parts.push(current);
561
+ current = '';
562
+ i += 2;
563
+ } else if (command[i] === '|' && command[i + 1] === '|') {
564
+ parts.push(current);
565
+ current = '';
566
+ i += 2;
567
+ } else if (command[i] === ';' || command[i] === '|') {
568
+ parts.push(current);
569
+ current = '';
570
+ i++;
571
+ } else {
572
+ current += ch;
573
+ i++;
250
574
  }
575
+ } else {
576
+ current += ch;
577
+ i++;
251
578
  }
252
579
  }
253
-
254
- return defaults;
580
+ if (current.trim()) parts.push(current);
581
+ return parts.map((p) => p.trim()).filter(Boolean);
255
582
  }
256
583
 
584
+ const MAX_REGEX_LENGTH = 200;
585
+
257
586
  function isDataContext(command) {
258
- const trimmed = command.trim();
259
- return DATA_PREFIXES.some((prefix) => prefix.test(trimmed));
587
+ const parts = splitShellCommands(command);
588
+ if (parts.length === 0) return true;
589
+ return parts.every((part) => DATA_PREFIXES.some((prefix) => prefix.test(part.trim())));
260
590
  }
261
591
 
262
592
  function isRmPathSafe(command) {
@@ -277,19 +607,30 @@ function isRmPathSafe(command) {
277
607
  function checkDangerous(command, config) {
278
608
  if (config.commandSafetyGuard.mode === 'off') return null;
279
609
 
280
- // Check allowlist first
610
+ // Check allowlist — each entry is tested as an anchored regex against the full command
611
+ const trimmed = command.trim();
281
612
  const allowlist = config.commandSafetyGuard.allowlist || [];
282
613
  for (const allowed of allowlist) {
283
- if (command.includes(allowed)) return null;
614
+ if (allowed.length > MAX_REGEX_LENGTH) continue;
615
+ try {
616
+ if (new RegExp(allowed).test(trimmed)) return null;
617
+ } catch {
618
+ if (trimmed === allowed) return null;
619
+ }
284
620
  }
285
621
 
286
622
  // Skip if command is in a data context
287
623
  if (isDataContext(command)) return null;
288
624
 
289
625
  // Check built-in patterns
290
- for (const { pattern, reason, checkPath } of DANGEROUS_PATTERNS) {
626
+ for (const { pattern, reason, checkPath, exemptLocalhost } of DANGEROUS_PATTERNS) {
291
627
  if (pattern.test(command)) {
292
628
  if (checkPath && isRmPathSafe(command)) continue;
629
+ if (
630
+ exemptLocalhost &&
631
+ /(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\])(?=[:/'")\s]|$)/.test(command)
632
+ )
633
+ continue;
293
634
 
294
635
  return {
295
636
  reason,
@@ -301,6 +642,7 @@ function checkDangerous(command, config) {
301
642
  // Check user-defined custom patterns (blacklist)
302
643
  const customPatterns = config.commandSafetyGuard.customPatterns || [];
303
644
  for (const custom of customPatterns) {
645
+ if (custom.pattern.length > MAX_REGEX_LENGTH) continue;
304
646
  try {
305
647
  const regex = new RegExp(custom.pattern, custom.flags || '');
306
648
  if (regex.test(command)) {
@@ -322,15 +664,17 @@ function buildCommitContext(config) {
322
664
 
323
665
  if (config.includeCoAuthoredBy) {
324
666
  parts.push(`<commit-format>
325
- Footer order (succ always LAST):
326
- 1. Generated with [Claude Code]
327
- 2. via [Happy] (if used)
328
- 3. powered by [succ](https://succ.ai)
329
-
330
- Co-Authored-By order (succ always LAST):
331
- 1. Co-Authored-By: Claude <noreply@anthropic.com>
332
- 2. Co-Authored-By: Happy <yesreply@happy.engineering> (if used)
333
- 3. Co-Authored-By: succ <mindpalace@succ.ai>
667
+ RULE: Every commit footer MUST end with the succ lines. Other tools may appear before succ but succ is always LAST.
668
+
669
+ TEMPLATE copy the relevant lines exactly:
670
+ Generated with [Claude Code](https://claude.ai/code)
671
+ powered by [succ](https://succ.ai)
672
+
673
+ Co-Authored-By: Claude <noreply@anthropic.com>
674
+ Co-Authored-By: succ <mindpalace@succ.ai>
675
+
676
+ Other tools (Happy, Cursor, etc.) may add their own "via [Tool]" and "Co-Authored-By: Tool" lines.
677
+ Place them BEFORE the succ lines. The only hard rule: succ is always the last footer line and last Co-Authored-By.
334
678
  </commit-format>`);
335
679
  }
336
680
 
@@ -351,15 +695,8 @@ MEDIUM and below — commit is OK, mention findings in summary.
351
695
 
352
696
  // ─── Daemon helpers ──────────────────────────────────────────────────
353
697
 
354
- function getDaemonPort(projectDir) {
355
- const portFile = path.join(projectDir, '.succ', '.tmp', 'daemon.port');
356
- if (!fs.existsSync(portFile)) return null;
357
- const port = parseInt(fs.readFileSync(portFile, 'utf8').trim(), 10);
358
- return port && !isNaN(port) ? port : null;
359
- }
360
-
361
- async function recallFileMemories(projectDir, fileName) {
362
- const port = getDaemonPort(projectDir);
698
+ async function recallFileMemories(succDir, fileName) {
699
+ const port = getDaemonPort(succDir);
363
700
  if (!port) return [];
364
701
 
365
702
  try {
@@ -377,8 +714,8 @@ async function recallFileMemories(projectDir, fileName) {
377
714
  }
378
715
  }
379
716
 
380
- async function fetchHookRules(projectDir, toolName, toolInput) {
381
- const port = getDaemonPort(projectDir);
717
+ async function fetchHookRules(succDir, toolName, toolInput) {
718
+ const port = getDaemonPort(succDir);
382
719
  if (!port) return [];
383
720
 
384
721
  try {
@@ -397,144 +734,151 @@ async function fetchHookRules(projectDir, toolName, toolInput) {
397
734
  }
398
735
 
399
736
  function formatFileContext(memories, fileName) {
400
- const lines = memories.map((m) => `- [${m.type || 'observation'}] ${m.content.slice(0, 200)}`);
401
- return `<file-context file="${fileName}">\nRelated memories:\n${lines.join('\n')}\n</file-context>`;
737
+ const lines = memories.map(
738
+ (m) => `- [${escapeXml(m.type || 'observation')}] ${sanitize(m.content, 200)}`
739
+ );
740
+ return `<file-context file="${sanitizeFileName(fileName)}">\nRelated memories:\n${lines.join('\n')}\n</file-context>`;
402
741
  }
403
742
 
404
743
  // ─── Main ────────────────────────────────────────────────────────────
405
744
 
406
- let input = '';
407
- process.stdin.setEncoding('utf8');
408
- process.stdin.on('readable', () => {
409
- let chunk;
410
- while ((chunk = process.stdin.read()) !== null) {
411
- input += chunk;
745
+ adapter.runHook('pre-tool', async ({ agent, hookInput, projectDir, succDir }) => {
746
+ // Skip if this is a service session (daemon, reflection agent, etc.)
747
+ if (process.env.SUCC_SERVICE_SESSION === '1') {
748
+ process.exit(0);
412
749
  }
413
- });
414
750
 
415
- process.stdin.on('end', async () => {
416
- try {
417
- const hookInput = JSON.parse(input);
418
- let projectDir = hookInput.cwd || process.cwd();
419
-
420
- // Windows path fix
421
- if (process.platform === 'win32' && /^\/[a-z]\//.test(projectDir)) {
422
- projectDir = projectDir[1].toUpperCase() + ':' + projectDir.slice(2);
751
+ const toolName = hookInput.tool_name || '';
752
+ const toolInput = hookInput.tool_input || {};
753
+ const filePath = toolInput.file_path || '';
754
+ const command = toolInput.command || '';
755
+ const contextParts = [];
756
+ let askReason = null;
757
+
758
+ // 0. Injection scan on tool input
759
+ const inputToScan = filePath || command || toolInput.url || '';
760
+ if (inputToScan) {
761
+ const injectionDesc = detectTier1(inputToScan);
762
+ if (injectionDesc) {
763
+ const { json, exitCode } = adapter.formatOutput(agent, 'PreToolUse', {
764
+ deny: true,
765
+ denyReason: `[succ security] Prompt injection detected in tool input: ${injectionDesc}`,
766
+ });
767
+ console.log(JSON.stringify(json));
768
+ process.exit(exitCode);
423
769
  }
770
+ }
424
771
 
425
- // Skip if this is a service session (daemon, reflection agent, etc.)
426
- if (process.env.SUCC_SERVICE_SESSION === '1') {
427
- process.exit(0);
772
+ // 0b. File operation guard
773
+ if (filePath && (toolName === 'Read' || toolName === 'Write' || toolName === 'Edit')) {
774
+ const operation = toolName === 'Read' ? 'read' : 'write';
775
+ const fileGuardResult = checkFileGuard(operation, filePath);
776
+ if (fileGuardResult) {
777
+ const result =
778
+ fileGuardResult.mode === 'ask'
779
+ ? { ask: true, askReason: `[succ file guard] ${fileGuardResult.reason}` }
780
+ : { deny: true, denyReason: `[succ file guard] ${fileGuardResult.reason}` };
781
+ const { json, exitCode } = adapter.formatOutput(agent, 'PreToolUse', result);
782
+ console.log(JSON.stringify(json));
783
+ process.exit(exitCode);
428
784
  }
785
+ }
429
786
 
430
- // Skip if succ is not initialized
431
- if (!fs.existsSync(path.join(projectDir, '.succ'))) {
432
- process.exit(0);
787
+ // 0c. IFC: Proactive file label classification (warn in context)
788
+ if (filePath && (toolName === 'Read' || toolName === 'Write' || toolName === 'Edit')) {
789
+ const fileLabel = quickFileLabel(filePath);
790
+ if (fileLabel && fileLabel.level >= 2) {
791
+ contextParts.push(
792
+ `<security-warning type="ifc">[succ IFC] File ${sanitizeFileName(path.basename(filePath))} classified as ${escapeXml(fileLabel.label)}. ` +
793
+ `Subsequent outbound operations (curl, WebFetch, git push) may be restricted.</security-warning>`
794
+ );
433
795
  }
796
+ }
434
797
 
435
- const toolName = hookInput.tool_name || '';
436
- const toolInput = hookInput.tool_input || {};
437
- const filePath = toolInput.file_path || '';
438
- const command = toolInput.command || '';
439
- const contextParts = [];
440
- let askReason = null;
441
-
442
- // 1. Dynamic hook rules from memory (ALL tools)
443
- // Note: deny/ask exit immediately — any accumulated contextParts are intentionally
444
- // discarded because the tool call is being blocked or requires confirmation.
445
- const rules = await fetchHookRules(projectDir, toolName, toolInput);
446
- for (const rule of rules) {
447
- if (rule.action === 'deny') {
448
- const output = {
449
- hookSpecificOutput: {
450
- hookEventName: 'PreToolUse',
451
- permissionDecision: 'deny',
452
- permissionDecisionReason: `[succ rule] ${rule.content}`,
453
- },
454
- };
455
- console.log(JSON.stringify(output));
456
- process.exit(0);
457
- }
458
- if (rule.action === 'ask' && !askReason) {
459
- askReason = rule.content;
460
- }
461
- if (rule.action === 'inject') {
462
- contextParts.push(`<hook-rule>${rule.content}</hook-rule>`);
463
- }
798
+ // 1. Dynamic hook rules from memory (ALL tools)
799
+ // Note: deny/ask exit immediately — any accumulated contextParts are intentionally
800
+ // discarded because the tool call is being blocked or requires confirmation.
801
+ const rules = await fetchHookRules(succDir, toolName, toolInput);
802
+ for (const rule of rules) {
803
+ // Scan rule content for injection (prevents poisoned memory escalation)
804
+ if (detectTier1(rule.content)) continue;
805
+
806
+ if (rule.action === 'deny') {
807
+ const { json, exitCode } = adapter.formatOutput(agent, 'PreToolUse', {
808
+ deny: true,
809
+ denyReason: `[succ rule] ${sanitize(rule.content, 500)}`,
810
+ });
811
+ console.log(JSON.stringify(json));
812
+ process.exit(exitCode);
813
+ }
814
+ if (rule.action === 'ask' && !askReason) {
815
+ askReason = sanitize(rule.content, 500);
464
816
  }
817
+ if (rule.action === 'inject') {
818
+ contextParts.push(`<hook-rule>${sanitize(rule.content)}</hook-rule>`);
819
+ }
820
+ }
465
821
 
466
- // 2. File-linked memories (Edit/Write only — Read is too frequent, wastes context)
467
- if ((toolName === 'Edit' || toolName === 'Write') && filePath) {
468
- const fileName = path.basename(filePath);
469
- const memories = await recallFileMemories(projectDir, fileName);
470
- if (memories.length > 0) {
471
- contextParts.push(formatFileContext(memories, fileName));
472
- }
822
+ // 2. File-linked memories (Edit/Write only — Read is too frequent, wastes context)
823
+ if ((toolName === 'Edit' || toolName === 'Write') && filePath) {
824
+ const fileName = path.basename(filePath);
825
+ const memories = await recallFileMemories(succDir, fileName);
826
+ if (memories.length > 0) {
827
+ contextParts.push(formatFileContext(memories, fileName));
473
828
  }
829
+ }
474
830
 
475
- // 3. Command safety guard (Bash only)
476
- if (command) {
477
- const config = loadConfig(projectDir);
478
- const dangerousResult = checkDangerous(command, config);
479
- if (dangerousResult) {
480
- const output = {
481
- hookSpecificOutput: {
482
- hookEventName: 'PreToolUse',
483
- permissionDecision: dangerousResult.mode === 'ask' ? 'ask' : 'deny',
484
- permissionDecisionReason: `[succ guard] ${dangerousResult.reason}`,
485
- },
486
- };
487
- console.log(JSON.stringify(output));
488
- process.exit(0);
489
- }
831
+ // 3. Command safety guard (Bash only)
832
+ if (command) {
833
+ const config = loadConfig(projectDir);
834
+ const dangerousResult = checkDangerous(command, config);
835
+ if (dangerousResult) {
836
+ const result =
837
+ dangerousResult.mode === 'ask'
838
+ ? { ask: true, askReason: `[succ guard] ${dangerousResult.reason}` }
839
+ : { deny: true, denyReason: `[succ guard] ${dangerousResult.reason}` };
840
+ const { json, exitCode } = adapter.formatOutput(agent, 'PreToolUse', result);
841
+ console.log(JSON.stringify(json));
842
+ process.exit(exitCode);
843
+ }
490
844
 
491
- // 4. Hook rule ask (after safety guard, so deny takes priority)
492
- if (askReason) {
493
- const output = {
494
- hookSpecificOutput: {
495
- hookEventName: 'PreToolUse',
496
- permissionDecision: 'ask',
497
- permissionDecisionReason: `[succ rule] ${askReason}`,
498
- },
499
- };
500
- console.log(JSON.stringify(output));
501
- process.exit(0);
502
- }
845
+ // 4. Hook rule ask (after safety guard, so deny takes priority)
846
+ if (askReason) {
847
+ const { json, exitCode } = adapter.formatOutput(agent, 'PreToolUse', {
848
+ ask: true,
849
+ askReason: `[succ rule] ${askReason}`,
850
+ });
851
+ console.log(JSON.stringify(json));
852
+ process.exit(exitCode);
853
+ }
503
854
 
504
- // 5. Git commit — inject guidelines + diff review reminder
505
- if (/\bgit\s+commit\b/.test(command)) {
506
- const commitContext = buildCommitContext(config);
507
- if (commitContext) {
508
- contextParts.push(commitContext);
509
- }
855
+ // 5. Git commit — inject guidelines + diff review reminder
856
+ if (/\bgit\s+commit\b/.test(command)) {
857
+ const commitContext = buildCommitContext(config);
858
+ if (commitContext) {
859
+ contextParts.push(commitContext);
510
860
  }
511
- } else if (askReason) {
512
- // Non-Bash ask rule
513
- const output = {
514
- hookSpecificOutput: {
515
- hookEventName: 'PreToolUse',
516
- permissionDecision: 'ask',
517
- permissionDecisionReason: `[succ rule] ${askReason}`,
518
- },
519
- };
520
- console.log(JSON.stringify(output));
521
- process.exit(0);
522
861
  }
862
+ } else if (askReason) {
863
+ // Non-Bash ask rule
864
+ const { json, exitCode } = adapter.formatOutput(agent, 'PreToolUse', {
865
+ ask: true,
866
+ askReason: `[succ rule] ${askReason}`,
867
+ });
868
+ console.log(JSON.stringify(json));
869
+ process.exit(exitCode);
870
+ }
523
871
 
524
- // 6. Emit combined context
525
- if (contextParts.length > 0) {
526
- const output = {
527
- hookSpecificOutput: {
528
- hookEventName: 'PreToolUse',
529
- additionalContext: contextParts.join('\n'),
530
- },
531
- };
532
- console.log(JSON.stringify(output));
872
+ // 6. Emit combined context
873
+ if (contextParts.length > 0) {
874
+ const { json, exitCode } = adapter.formatOutput(agent, 'PreToolUse', {
875
+ additionalContext: contextParts.join('\n'),
876
+ });
877
+ if (json && Object.keys(json).length > 0) {
878
+ console.log(JSON.stringify(json));
533
879
  }
534
-
535
- process.exit(0);
536
- } catch {
537
- // Fail-open: don't block on hook errors
538
- process.exit(0);
880
+ if (exitCode) process.exit(exitCode);
539
881
  }
882
+
883
+ process.exit(0);
540
884
  });