@namzu/sdk 59.0.0 → 60.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (370) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/dist/agents/QueryAgent.d.ts.map +1 -1
  3. package/dist/agents/QueryAgent.js +1 -0
  4. package/dist/agents/QueryAgent.js.map +1 -1
  5. package/dist/bridge/a2a/mapper.d.ts.map +1 -1
  6. package/dist/bridge/a2a/mapper.js +16 -0
  7. package/dist/bridge/a2a/mapper.js.map +1 -1
  8. package/dist/bridge/acp/update.d.ts.map +1 -1
  9. package/dist/bridge/acp/update.js +1 -0
  10. package/dist/bridge/acp/update.js.map +1 -1
  11. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  12. package/dist/bridge/sse/mapper.js +12 -0
  13. package/dist/bridge/sse/mapper.js.map +1 -1
  14. package/dist/compaction/context-window.d.ts +53 -0
  15. package/dist/compaction/context-window.d.ts.map +1 -1
  16. package/dist/compaction/context-window.js +141 -2
  17. package/dist/compaction/context-window.js.map +1 -1
  18. package/dist/constants/continuation.d.ts +9 -0
  19. package/dist/constants/continuation.d.ts.map +1 -1
  20. package/dist/constants/continuation.js +9 -0
  21. package/dist/constants/continuation.js.map +1 -1
  22. package/dist/contracts/session/api.d.ts +7 -1
  23. package/dist/contracts/session/api.d.ts.map +1 -1
  24. package/dist/execution/workflow/index.d.ts +3 -1
  25. package/dist/execution/workflow/index.d.ts.map +1 -1
  26. package/dist/execution/workflow/index.js +2 -1
  27. package/dist/execution/workflow/index.js.map +1 -1
  28. package/dist/execution/workflow/journal.d.ts +24 -4
  29. package/dist/execution/workflow/journal.d.ts.map +1 -1
  30. package/dist/execution/workflow/journal.js +131 -9
  31. package/dist/execution/workflow/journal.js.map +1 -1
  32. package/dist/execution/workflow/prelude.d.ts +2 -0
  33. package/dist/execution/workflow/prelude.d.ts.map +1 -1
  34. package/dist/execution/workflow/prelude.js +49 -8
  35. package/dist/execution/workflow/prelude.js.map +1 -1
  36. package/dist/execution/workflow/resume.d.ts +59 -0
  37. package/dist/execution/workflow/resume.d.ts.map +1 -0
  38. package/dist/execution/workflow/resume.js +273 -0
  39. package/dist/execution/workflow/resume.js.map +1 -0
  40. package/dist/execution/workflow/runtime.d.ts.map +1 -1
  41. package/dist/execution/workflow/runtime.js +112 -8
  42. package/dist/execution/workflow/runtime.js.map +1 -1
  43. package/dist/execution/workflow/types.d.ts +105 -1
  44. package/dist/execution/workflow/types.d.ts.map +1 -1
  45. package/dist/index.d.ts +3 -0
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +4 -0
  48. package/dist/index.js.map +1 -1
  49. package/dist/manager/session/turn-recorder.d.ts.map +1 -1
  50. package/dist/manager/session/turn-recorder.js +1 -0
  51. package/dist/manager/session/turn-recorder.js.map +1 -1
  52. package/dist/plugin/compat.d.ts +24 -0
  53. package/dist/plugin/compat.d.ts.map +1 -0
  54. package/dist/plugin/compat.js +149 -0
  55. package/dist/plugin/compat.js.map +1 -0
  56. package/dist/plugin/loader.d.ts +2 -1
  57. package/dist/plugin/loader.d.ts.map +1 -1
  58. package/dist/plugin/loader.js +6 -0
  59. package/dist/plugin/loader.js.map +1 -1
  60. package/dist/pricing/index.d.ts.map +1 -1
  61. package/dist/pricing/index.js +2 -1
  62. package/dist/pricing/index.js.map +1 -1
  63. package/dist/process/kill-tree.d.ts +44 -0
  64. package/dist/process/kill-tree.d.ts.map +1 -1
  65. package/dist/process/kill-tree.js +102 -4
  66. package/dist/process/kill-tree.js.map +1 -1
  67. package/dist/prompt/coding-agent-doctrine.d.ts +1 -1
  68. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
  69. package/dist/prompt/coding-agent-doctrine.js +9 -1
  70. package/dist/prompt/coding-agent-doctrine.js.map +1 -1
  71. package/dist/provider/collect-chat-completion.d.ts.map +1 -1
  72. package/dist/provider/collect-chat-completion.js +4 -0
  73. package/dist/provider/collect-chat-completion.js.map +1 -1
  74. package/dist/provider/fallback.d.ts.map +1 -1
  75. package/dist/provider/fallback.js +11 -0
  76. package/dist/provider/fallback.js.map +1 -1
  77. package/dist/provider/idle-timeout.d.ts.map +1 -1
  78. package/dist/provider/idle-timeout.js +5 -0
  79. package/dist/provider/idle-timeout.js.map +1 -1
  80. package/dist/provider/mock.d.ts +2 -0
  81. package/dist/provider/mock.d.ts.map +1 -1
  82. package/dist/provider/mock.js +16 -8
  83. package/dist/provider/mock.js.map +1 -1
  84. package/dist/provider/model-window-suffix.d.ts +18 -0
  85. package/dist/provider/model-window-suffix.d.ts.map +1 -0
  86. package/dist/provider/model-window-suffix.js +78 -0
  87. package/dist/provider/model-window-suffix.js.map +1 -0
  88. package/dist/provider/retry.d.ts.map +1 -1
  89. package/dist/provider/retry.js +5 -0
  90. package/dist/provider/retry.js.map +1 -1
  91. package/dist/public-runtime.d.ts +5 -3
  92. package/dist/public-runtime.d.ts.map +1 -1
  93. package/dist/public-runtime.js +5 -4
  94. package/dist/public-runtime.js.map +1 -1
  95. package/dist/public-types.d.ts +1 -0
  96. package/dist/public-types.d.ts.map +1 -1
  97. package/dist/registry/command/kernel-commands.d.ts +1 -4
  98. package/dist/registry/command/kernel-commands.d.ts.map +1 -1
  99. package/dist/registry/command/kernel-commands.js +0 -28
  100. package/dist/registry/command/kernel-commands.js.map +1 -1
  101. package/dist/runtime/jobs/awaited-jobs.d.ts +6 -0
  102. package/dist/runtime/jobs/awaited-jobs.d.ts.map +1 -1
  103. package/dist/runtime/jobs/awaited-jobs.js +11 -0
  104. package/dist/runtime/jobs/awaited-jobs.js.map +1 -1
  105. package/dist/runtime/jobs/host-exit-finalizer.d.ts +20 -0
  106. package/dist/runtime/jobs/host-exit-finalizer.d.ts.map +1 -0
  107. package/dist/runtime/jobs/host-exit-finalizer.js +57 -0
  108. package/dist/runtime/jobs/host-exit-finalizer.js.map +1 -0
  109. package/dist/runtime/jobs/liveness.d.ts +67 -0
  110. package/dist/runtime/jobs/liveness.d.ts.map +1 -0
  111. package/dist/runtime/jobs/liveness.js +94 -0
  112. package/dist/runtime/jobs/liveness.js.map +1 -0
  113. package/dist/runtime/jobs/registry.d.ts +21 -0
  114. package/dist/runtime/jobs/registry.d.ts.map +1 -1
  115. package/dist/runtime/jobs/registry.js +104 -2
  116. package/dist/runtime/jobs/registry.js.map +1 -1
  117. package/dist/runtime/jobs/wake-budget.d.ts +35 -0
  118. package/dist/runtime/jobs/wake-budget.d.ts.map +1 -0
  119. package/dist/runtime/jobs/wake-budget.js +48 -0
  120. package/dist/runtime/jobs/wake-budget.js.map +1 -0
  121. package/dist/runtime/query/detached-calls.d.ts +65 -0
  122. package/dist/runtime/query/detached-calls.d.ts.map +1 -0
  123. package/dist/runtime/query/detached-calls.js +116 -0
  124. package/dist/runtime/query/detached-calls.js.map +1 -0
  125. package/dist/runtime/query/executor.d.ts +4 -1
  126. package/dist/runtime/query/executor.d.ts.map +1 -1
  127. package/dist/runtime/query/executor.js +90 -6
  128. package/dist/runtime/query/executor.js.map +1 -1
  129. package/dist/runtime/query/index.d.ts +34 -0
  130. package/dist/runtime/query/index.d.ts.map +1 -1
  131. package/dist/runtime/query/index.js +32 -5
  132. package/dist/runtime/query/index.js.map +1 -1
  133. package/dist/runtime/query/iteration/effort-clamp.d.ts +13 -0
  134. package/dist/runtime/query/iteration/effort-clamp.d.ts.map +1 -0
  135. package/dist/runtime/query/iteration/effort-clamp.js +42 -0
  136. package/dist/runtime/query/iteration/effort-clamp.js.map +1 -0
  137. package/dist/runtime/query/iteration/index.d.ts +34 -0
  138. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  139. package/dist/runtime/query/iteration/index.js +199 -6
  140. package/dist/runtime/query/iteration/index.js.map +1 -1
  141. package/dist/runtime/query/iteration/outstanding-work.d.ts.map +1 -1
  142. package/dist/runtime/query/iteration/outstanding-work.js +11 -3
  143. package/dist/runtime/query/iteration/outstanding-work.js.map +1 -1
  144. package/dist/runtime/query/iteration/phases/context.d.ts +9 -0
  145. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  146. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  147. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  148. package/dist/runtime/query/iteration/phases/tool-review.js +63 -1
  149. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  150. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  151. package/dist/runtime/query/iteration/stream-turn.js +6 -0
  152. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  153. package/dist/runtime/query/session-storage.d.ts.map +1 -1
  154. package/dist/runtime/query/session-storage.js +8 -3
  155. package/dist/runtime/query/session-storage.js.map +1 -1
  156. package/dist/runtime/query/steering.d.ts +29 -3
  157. package/dist/runtime/query/steering.d.ts.map +1 -1
  158. package/dist/runtime/query/steering.js +58 -3
  159. package/dist/runtime/query/steering.js.map +1 -1
  160. package/dist/runtime/query/tooling.d.ts +1 -0
  161. package/dist/runtime/query/tooling.d.ts.map +1 -1
  162. package/dist/runtime/query/tooling.js +1 -0
  163. package/dist/runtime/query/tooling.js.map +1 -1
  164. package/dist/runtime/system-events.d.ts +5 -0
  165. package/dist/runtime/system-events.d.ts.map +1 -1
  166. package/dist/runtime/system-events.js +7 -1
  167. package/dist/runtime/system-events.js.map +1 -1
  168. package/dist/sandbox/denial.d.ts +11 -0
  169. package/dist/sandbox/denial.d.ts.map +1 -0
  170. package/dist/sandbox/denial.js +61 -0
  171. package/dist/sandbox/denial.js.map +1 -0
  172. package/dist/sandbox/file-walk-program.d.ts.map +1 -1
  173. package/dist/sandbox/file-walk-program.js +31 -13
  174. package/dist/sandbox/file-walk-program.js.map +1 -1
  175. package/dist/sandbox/file-walk.d.ts +2 -0
  176. package/dist/sandbox/file-walk.d.ts.map +1 -1
  177. package/dist/sandbox/file-walk.js +64 -13
  178. package/dist/sandbox/file-walk.js.map +1 -1
  179. package/dist/sandbox/ignore-matcher.d.ts +30 -0
  180. package/dist/sandbox/ignore-matcher.d.ts.map +1 -0
  181. package/dist/sandbox/ignore-matcher.js +11 -0
  182. package/dist/sandbox/ignore-matcher.js.map +1 -0
  183. package/dist/sandbox/ignore-source.d.ts +26 -0
  184. package/dist/sandbox/ignore-source.d.ts.map +1 -0
  185. package/dist/sandbox/ignore-source.js +221 -0
  186. package/dist/sandbox/ignore-source.js.map +1 -0
  187. package/dist/sandbox/provider/local.d.ts.map +1 -1
  188. package/dist/sandbox/provider/local.js +11 -1
  189. package/dist/sandbox/provider/local.js.map +1 -1
  190. package/dist/scheduler/completion-inbox.d.ts.map +1 -1
  191. package/dist/scheduler/completion-inbox.js +1 -0
  192. package/dist/scheduler/completion-inbox.js.map +1 -1
  193. package/dist/session/log-hash.d.ts.map +1 -1
  194. package/dist/session/log-hash.js +18 -1
  195. package/dist/session/log-hash.js.map +1 -1
  196. package/dist/store/memory/disk.d.ts.map +1 -1
  197. package/dist/store/memory/disk.js +1 -1
  198. package/dist/store/memory/disk.js.map +1 -1
  199. package/dist/store/memory/markdown.d.ts.map +1 -1
  200. package/dist/store/memory/markdown.js +1 -1
  201. package/dist/store/memory/markdown.js.map +1 -1
  202. package/dist/store/memory/operation-lock.d.ts +20 -4
  203. package/dist/store/memory/operation-lock.d.ts.map +1 -1
  204. package/dist/store/memory/operation-lock.js +235 -58
  205. package/dist/store/memory/operation-lock.js.map +1 -1
  206. package/dist/store/session-index/sqlite.d.ts.map +1 -1
  207. package/dist/store/session-index/sqlite.js +169 -16
  208. package/dist/store/session-index/sqlite.js.map +1 -1
  209. package/dist/tools/builtins/bash.d.ts.map +1 -1
  210. package/dist/tools/builtins/bash.js +10 -4
  211. package/dist/tools/builtins/bash.js.map +1 -1
  212. package/dist/tools/builtins/computer-use.d.ts +35 -0
  213. package/dist/tools/builtins/computer-use.d.ts.map +1 -1
  214. package/dist/tools/builtins/computer-use.js +512 -67
  215. package/dist/tools/builtins/computer-use.js.map +1 -1
  216. package/dist/tools/builtins/glob.d.ts +1 -0
  217. package/dist/tools/builtins/glob.d.ts.map +1 -1
  218. package/dist/tools/builtins/glob.js +65 -28
  219. package/dist/tools/builtins/glob.js.map +1 -1
  220. package/dist/tools/builtins/grep.d.ts +2 -0
  221. package/dist/tools/builtins/grep.d.ts.map +1 -1
  222. package/dist/tools/builtins/grep.js +94 -40
  223. package/dist/tools/builtins/grep.js.map +1 -1
  224. package/dist/tools/builtins/job.d.ts +1 -1
  225. package/dist/tools/builtins/job.d.ts.map +1 -1
  226. package/dist/tools/builtins/job.js +34 -7
  227. package/dist/tools/builtins/job.js.map +1 -1
  228. package/dist/tools/builtins/search-support.d.ts +44 -0
  229. package/dist/tools/builtins/search-support.d.ts.map +1 -0
  230. package/dist/tools/builtins/search-support.js +89 -0
  231. package/dist/tools/builtins/search-support.js.map +1 -0
  232. package/dist/tools/builtins/wait-for-job-bounds.d.ts +2 -0
  233. package/dist/tools/builtins/wait-for-job-bounds.d.ts.map +1 -1
  234. package/dist/tools/builtins/wait-for-job-bounds.js +3 -1
  235. package/dist/tools/builtins/wait-for-job-bounds.js.map +1 -1
  236. package/dist/tools/builtins/wait-for-job.d.ts +1 -1
  237. package/dist/tools/builtins/wait-for-job.d.ts.map +1 -1
  238. package/dist/tools/builtins/wait-for-job.js +13 -2
  239. package/dist/tools/builtins/wait-for-job.js.map +1 -1
  240. package/dist/tools/command-shell.d.ts.map +1 -1
  241. package/dist/tools/command-shell.js +14 -5
  242. package/dist/tools/command-shell.js.map +1 -1
  243. package/dist/turn/reporter.d.ts.map +1 -1
  244. package/dist/turn/reporter.js +11 -0
  245. package/dist/turn/reporter.js.map +1 -1
  246. package/dist/types/agent/query.d.ts +2 -0
  247. package/dist/types/agent/query.d.ts.map +1 -1
  248. package/dist/types/computer-use/index.d.ts +129 -13
  249. package/dist/types/computer-use/index.d.ts.map +1 -1
  250. package/dist/types/computer-use/index.js.map +1 -1
  251. package/dist/types/message/index.d.ts +1 -1
  252. package/dist/types/message/index.d.ts.map +1 -1
  253. package/dist/types/message/index.js +1 -0
  254. package/dist/types/message/index.js.map +1 -1
  255. package/dist/types/plugin/index.d.ts +24 -0
  256. package/dist/types/plugin/index.d.ts.map +1 -1
  257. package/dist/types/plugin/index.js +4 -0
  258. package/dist/types/plugin/index.js.map +1 -1
  259. package/dist/types/provider/chat.d.ts +19 -0
  260. package/dist/types/provider/chat.d.ts.map +1 -1
  261. package/dist/types/provider/config.d.ts +7 -0
  262. package/dist/types/provider/config.d.ts.map +1 -1
  263. package/dist/types/provider/index.d.ts +1 -1
  264. package/dist/types/provider/index.d.ts.map +1 -1
  265. package/dist/types/provider/interface.d.ts +15 -0
  266. package/dist/types/provider/interface.d.ts.map +1 -1
  267. package/dist/types/provider/stream.d.ts +6 -0
  268. package/dist/types/provider/stream.d.ts.map +1 -1
  269. package/dist/types/sandbox/index.d.ts +38 -1
  270. package/dist/types/sandbox/index.d.ts.map +1 -1
  271. package/dist/types/sandbox/index.js.map +1 -1
  272. package/dist/types/session/events.d.ts +34 -0
  273. package/dist/types/session/events.d.ts.map +1 -1
  274. package/dist/types/session/events.js.map +1 -1
  275. package/dist/types/session/records.d.ts +298 -34
  276. package/dist/types/session/records.d.ts.map +1 -1
  277. package/dist/types/session/records.js +35 -1
  278. package/dist/types/session/records.js.map +1 -1
  279. package/dist/types/session/stop-reason.d.ts +11 -0
  280. package/dist/types/session/stop-reason.d.ts.map +1 -1
  281. package/dist/types/tool/index.d.ts +30 -0
  282. package/dist/types/tool/index.d.ts.map +1 -1
  283. package/dist/types/tool/index.js.map +1 -1
  284. package/dist/types/tool/presentation.d.ts +8 -0
  285. package/dist/types/tool/presentation.d.ts.map +1 -1
  286. package/package.json +1 -1
  287. package/src/agents/QueryAgent.ts +1 -0
  288. package/src/bridge/a2a/mapper.ts +19 -0
  289. package/src/bridge/acp/update.ts +6 -1
  290. package/src/bridge/sse/mapper.ts +13 -0
  291. package/src/compaction/context-window.ts +163 -2
  292. package/src/constants/continuation.ts +13 -0
  293. package/src/contracts/session/api.ts +6 -0
  294. package/src/execution/workflow/index.ts +14 -1
  295. package/src/execution/workflow/journal.ts +161 -11
  296. package/src/execution/workflow/prelude.ts +51 -8
  297. package/src/execution/workflow/resume.ts +313 -0
  298. package/src/execution/workflow/runtime.ts +127 -9
  299. package/src/execution/workflow/types.ts +109 -1
  300. package/src/index.ts +17 -0
  301. package/src/manager/session/turn-recorder.ts +1 -0
  302. package/src/plugin/compat.ts +173 -0
  303. package/src/plugin/loader.ts +7 -1
  304. package/src/pricing/index.ts +2 -1
  305. package/src/process/kill-tree.ts +106 -4
  306. package/src/prompt/coding-agent-doctrine.ts +9 -1
  307. package/src/provider/collect-chat-completion.ts +3 -0
  308. package/src/provider/fallback.ts +17 -0
  309. package/src/provider/idle-timeout.ts +9 -0
  310. package/src/provider/mock.ts +19 -9
  311. package/src/provider/model-window-suffix.ts +85 -0
  312. package/src/provider/retry.ts +9 -0
  313. package/src/public-runtime.ts +21 -2
  314. package/src/public-types.ts +1 -0
  315. package/src/registry/command/kernel-commands.ts +1 -32
  316. package/src/runtime/jobs/awaited-jobs.ts +11 -0
  317. package/src/runtime/jobs/host-exit-finalizer.ts +67 -0
  318. package/src/runtime/jobs/liveness.ts +144 -0
  319. package/src/runtime/jobs/registry.ts +114 -2
  320. package/src/runtime/jobs/wake-budget.ts +55 -0
  321. package/src/runtime/query/detached-calls.ts +135 -0
  322. package/src/runtime/query/executor.ts +92 -10
  323. package/src/runtime/query/index.ts +65 -7
  324. package/src/runtime/query/iteration/effort-clamp.ts +46 -0
  325. package/src/runtime/query/iteration/index.ts +260 -6
  326. package/src/runtime/query/iteration/outstanding-work.ts +12 -3
  327. package/src/runtime/query/iteration/phases/context.ts +9 -0
  328. package/src/runtime/query/iteration/phases/tool-review.ts +73 -8
  329. package/src/runtime/query/iteration/stream-turn.ts +5 -0
  330. package/src/runtime/query/session-storage.ts +8 -3
  331. package/src/runtime/query/steering.ts +77 -6
  332. package/src/runtime/query/tooling.ts +2 -0
  333. package/src/runtime/system-events.ts +12 -1
  334. package/src/sandbox/denial.ts +79 -0
  335. package/src/sandbox/file-walk-program.ts +32 -13
  336. package/src/sandbox/file-walk.ts +75 -12
  337. package/src/sandbox/ignore-matcher.ts +46 -0
  338. package/src/sandbox/ignore-source.ts +220 -0
  339. package/src/sandbox/provider/local.ts +11 -1
  340. package/src/scheduler/completion-inbox.ts +1 -0
  341. package/src/session/log-hash.ts +21 -0
  342. package/src/store/memory/disk.ts +1 -0
  343. package/src/store/memory/markdown.ts +1 -0
  344. package/src/store/memory/operation-lock.ts +288 -57
  345. package/src/store/session-index/sqlite.ts +171 -16
  346. package/src/tools/builtins/bash.ts +11 -4
  347. package/src/tools/builtins/computer-use.ts +593 -68
  348. package/src/tools/builtins/glob.ts +79 -32
  349. package/src/tools/builtins/grep.ts +107 -43
  350. package/src/tools/builtins/job.ts +42 -12
  351. package/src/tools/builtins/search-support.ts +107 -0
  352. package/src/tools/builtins/wait-for-job-bounds.ts +5 -1
  353. package/src/tools/builtins/wait-for-job.ts +14 -2
  354. package/src/tools/command-shell.ts +13 -5
  355. package/src/turn/reporter.ts +12 -0
  356. package/src/types/agent/query.ts +2 -0
  357. package/src/types/computer-use/index.ts +157 -15
  358. package/src/types/message/index.ts +5 -3
  359. package/src/types/plugin/index.ts +8 -0
  360. package/src/types/provider/chat.ts +20 -0
  361. package/src/types/provider/config.ts +7 -0
  362. package/src/types/provider/index.ts +1 -0
  363. package/src/types/provider/interface.ts +20 -0
  364. package/src/types/provider/stream.ts +6 -0
  365. package/src/types/sandbox/index.ts +40 -1
  366. package/src/types/session/events.ts +65 -5
  367. package/src/types/session/records.ts +39 -2
  368. package/src/types/session/stop-reason.ts +11 -0
  369. package/src/types/tool/index.ts +30 -0
  370. package/src/types/tool/presentation.ts +8 -0
@@ -1,8 +1,9 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { lstat, open, readFile, unlink } from 'node:fs/promises';
3
+ import { hostname as osHostname } from 'node:os';
3
4
  import { setTimeout as delay } from 'node:timers/promises';
4
5
  import { NamzuError } from '../../types/errors/index.js';
5
- /** Wait bound, not a lease: a slow or crashed owner is never silently replaced. */
6
+ /** Wait bound, not a lease: a slow owner that is still running is never replaced. */
6
7
  export const DEFAULT_MEMORY_LOCK_TIMEOUT_MS = 10_000;
7
8
  export function validateMemoryLockTimeout(timeoutMs) {
8
9
  if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0) {
@@ -13,82 +14,258 @@ export function validateMemoryLockTimeout(timeoutMs) {
13
14
  });
14
15
  }
15
16
  }
16
- function lockError(path, reason, timeoutMs) {
17
+ /**
18
+ * An empty or unparsable lock file is only believed abandoned once it is older
19
+ * than this. A live acquirer writes its record immediately after creating the
20
+ * file, so a gap of seconds means the writer died in between (disk full, kill).
21
+ */
22
+ export const MEMORY_LOCK_RECORD_GRACE_MS = 5_000;
23
+ /**
24
+ * Residual risk, deliberately accepted: a pid that is alive is treated as the
25
+ * owner even when it is an unrelated process that reused the number after the
26
+ * real owner died. That cannot be disproved from here, so such a lock stays and
27
+ * the caller gets the plain "another process is using it" error. It is not
28
+ * bounded by `acquiredAt` age: a lock's age is not a lease.
29
+ */
30
+ function defaultIsPidAlive(pid) {
31
+ try {
32
+ process.kill(pid, 0);
33
+ return true;
34
+ }
35
+ catch (error) {
36
+ return error.code !== 'ESRCH';
37
+ }
38
+ }
39
+ function lockError(path, message, timeoutMs) {
17
40
  return new NamzuError({
18
41
  code: 'storage_error',
19
- message: `Memory operation lock ${path}: ${reason}. Stop all processes using this memory store and inspect the lock owner before removing a stale lock; it is never broken automatically.`,
42
+ message,
20
43
  details: { lockPath: path, timeoutMs },
21
44
  retryable: false,
22
45
  });
23
46
  }
47
+ function busyError(path, pid, timeoutMs) {
48
+ const who = pid === undefined ? 'Another Namzu process is' : `Another Namzu process (pid ${pid}) is`;
49
+ return lockError(path, `${who} using the stored memory. Close it, or wait for it to finish.`, timeoutMs);
50
+ }
51
+ function parseOwner(content) {
52
+ try {
53
+ const value = JSON.parse(content);
54
+ if (!value || typeof value !== 'object')
55
+ return undefined;
56
+ const pid = value.pid;
57
+ if (typeof pid !== 'number' || !Number.isSafeInteger(pid) || pid <= 0)
58
+ return undefined;
59
+ const host = value.hostname;
60
+ return {
61
+ pid,
62
+ token: String(value.token ?? ''),
63
+ acquiredAt: Number(value.acquiredAt ?? 0),
64
+ ...(typeof host === 'string' && host.length > 0 ? { hostname: host } : {}),
65
+ };
66
+ }
67
+ catch {
68
+ return undefined;
69
+ }
70
+ }
71
+ /** Reads the file at `path`; undefined when it is gone or was swapped while reading. */
72
+ async function inspect(path, env) {
73
+ const before = await lstat(path).catch((error) => {
74
+ if (error.code === 'ENOENT')
75
+ return undefined;
76
+ throw error;
77
+ });
78
+ if (!before)
79
+ return undefined;
80
+ if (!before.isFile() || before.isSymbolicLink())
81
+ return { stats: before, content: '', pid: undefined, staleReason: undefined };
82
+ const content = await readFile(path, 'utf8').catch((error) => {
83
+ if (error.code === 'ENOENT')
84
+ return undefined;
85
+ throw error;
86
+ });
87
+ if (content === undefined)
88
+ return undefined;
89
+ const after = await lstat(path).catch(() => undefined);
90
+ if (!after || after.dev !== before.dev || after.ino !== before.ino)
91
+ return undefined;
92
+ const owner = parseOwner(content);
93
+ if (owner) {
94
+ // A record from another host on a shared filesystem cannot be checked from
95
+ // here; it is live. A record without a host predates the field: local.
96
+ if (owner.hostname !== undefined && owner.hostname !== env.hostname) {
97
+ return { stats: before, content, pid: owner.pid, staleReason: undefined };
98
+ }
99
+ return {
100
+ stats: before,
101
+ content,
102
+ pid: owner.pid,
103
+ staleReason: env.isPidAlive(owner.pid) ? undefined : `owner process ${owner.pid} is gone`,
104
+ };
105
+ }
106
+ const age = env.now() - before.mtimeMs;
107
+ return {
108
+ stats: before,
109
+ content,
110
+ pid: undefined,
111
+ staleReason: age > MEMORY_LOCK_RECORD_GRACE_MS
112
+ ? `lock holds no readable owner record and is ${Math.round(age / 1000)}s old`
113
+ : undefined,
114
+ };
115
+ }
116
+ /**
117
+ * Creates `path` exclusively and writes this process's owner record. Returns
118
+ * undefined when the path is occupied. A failed write (a full disk) leaves no
119
+ * file behind.
120
+ */
121
+ async function createOwned(path, env) {
122
+ let handle;
123
+ try {
124
+ handle = await open(path, 'wx', 0o600);
125
+ }
126
+ catch (error) {
127
+ if (error.code === 'EEXIST')
128
+ return undefined;
129
+ throw error;
130
+ }
131
+ const owner = `${JSON.stringify({
132
+ pid: process.pid,
133
+ token: randomUUID(),
134
+ acquiredAt: Date.now(),
135
+ hostname: env.hostname,
136
+ })}\n`;
137
+ let identity;
138
+ try {
139
+ identity = await handle.stat();
140
+ await handle.writeFile(owner, 'utf8');
141
+ await handle.sync();
142
+ }
143
+ catch (error) {
144
+ await handle.close().catch(() => undefined);
145
+ // We created this path exclusively a moment ago; drop it so no empty or
146
+ // partial record is left to block the next start.
147
+ const current = await lstat(path).catch(() => undefined);
148
+ if (!identity || (current?.dev === identity.dev && current.ino === identity.ino)) {
149
+ await unlink(path).catch(() => undefined);
150
+ }
151
+ throw error;
152
+ }
153
+ await handle.close();
154
+ return { identity, owner };
155
+ }
156
+ async function releaseOwned(path, identity, owner, timeoutMs) {
157
+ const current = await lstat(path);
158
+ if (!current.isFile() ||
159
+ current.isSymbolicLink() ||
160
+ current.dev !== identity.dev ||
161
+ current.ino !== identity.ino ||
162
+ (await readFile(path, 'utf8')) !== owner) {
163
+ throw lockError(path, `Memory operation lock ${path}: the lock owner changed before release.`, timeoutMs);
164
+ }
165
+ await unlink(path);
166
+ }
167
+ function sameFile(a, b) {
168
+ return a.dev === b.dev && a.ino === b.ino;
169
+ }
170
+ /** Unlinks `path` only if it is still exactly the stale file that was inspected. */
171
+ async function unlinkIfStillStale(path, seen, env) {
172
+ const again = await inspect(path, env);
173
+ if (!again || !sameFile(again.stats, seen.stats) || again.content !== seen.content)
174
+ return false;
175
+ if (again.staleReason === undefined)
176
+ return false;
177
+ // Narrow the window further: the inode must still be the inspected one now.
178
+ const last = await lstat(path).catch(() => undefined);
179
+ if (!last || !sameFile(last, seen.stats))
180
+ return false;
181
+ await unlink(path).catch((error) => {
182
+ if (error.code !== 'ENOENT')
183
+ throw error;
184
+ });
185
+ return true;
186
+ }
187
+ /**
188
+ * Removes a lock whose owner is provably gone. Two processes that see the same
189
+ * stale lock are serialised through `<lock>.break`; the lock is re-inspected
190
+ * under it and only the inspected inode is unlinked. Returns whether the lock
191
+ * was removed.
192
+ */
193
+ async function breakStaleLock(path, seen, timeoutMs, env) {
194
+ const breakPath = `${path}.break`;
195
+ let held;
196
+ for (let attempt = 0; attempt < 2 && !held; attempt++) {
197
+ held = await createOwned(breakPath, env);
198
+ if (held)
199
+ break;
200
+ const breaker = await inspect(breakPath, env);
201
+ if (!breaker)
202
+ continue;
203
+ // A dead breaker's file follows the same rule, once.
204
+ if (breaker.staleReason === undefined || !(await unlinkIfStillStale(breakPath, breaker, env))) {
205
+ return false;
206
+ }
207
+ }
208
+ if (!held)
209
+ return false;
210
+ try {
211
+ const removed = await unlinkIfStillStale(path, seen, env);
212
+ if (removed) {
213
+ env.logger?.info('Broke an abandoned memory operation lock', {
214
+ 'namzu.store.lock_path': path,
215
+ 'namzu.store.lock_reason': seen.staleReason,
216
+ });
217
+ }
218
+ return removed;
219
+ }
220
+ finally {
221
+ await releaseOwned(breakPath, held.identity, held.owner, timeoutMs).catch(() => undefined);
222
+ }
223
+ }
24
224
  /**
25
225
  * Local-filesystem exclusion for cooperating processes. Atomic rename of the
26
226
  * index alone cannot serialize the index/content read-modify-write transaction.
27
- * An abandoned lock fails closed; guessing a lease expired would permit two
28
- * live writers to overwrite each other again.
227
+ * A lock whose owner is provably gone (dead pid on this host, or an owner-less
228
+ * file older than the grace period) is broken; a live or unverifiable owner is
229
+ * waited for until the timeout, never replaced on a guessed lease.
29
230
  */
30
- export async function acquireMemoryOperationLock(path, timeoutMs) {
231
+ export async function acquireMemoryOperationLock(path, timeoutMs, options = {}) {
232
+ const env = {
233
+ logger: options.logger,
234
+ now: options.now ?? Date.now,
235
+ isPidAlive: options.isPidAlive ?? defaultIsPidAlive,
236
+ hostname: options.hostname ?? osHostname(),
237
+ };
31
238
  const deadline = performance.now() + timeoutMs;
32
239
  let attempted = false;
240
+ let lastPid;
241
+ // The wait bound limits waiting for a live owner, not the attempt that
242
+ // follows a successful break: the lock is free then, and breaking it can
243
+ // itself outlast a short bound on a slow disk.
244
+ let justBroke = false;
33
245
  for (;;) {
34
- if (attempted && performance.now() >= deadline) {
35
- throw lockError(path, `acquisition timed out after ${timeoutMs} ms`, timeoutMs);
246
+ if (attempted && !justBroke && performance.now() >= deadline) {
247
+ throw busyError(path, lastPid, timeoutMs);
36
248
  }
249
+ justBroke = false;
37
250
  attempted = true;
38
- let handle;
39
- try {
40
- handle = await open(path, 'wx', 0o600);
251
+ const created = await createOwned(path, env);
252
+ if (created) {
253
+ return () => releaseOwned(path, created.identity, created.owner, timeoutMs);
41
254
  }
42
- catch (error) {
43
- if (error.code !== 'EEXIST')
44
- throw error;
45
- const existing = await lstat(path).catch((statError) => {
46
- if (statError.code === 'ENOENT')
47
- return undefined;
48
- throw statError;
49
- });
50
- if (!existing)
51
- continue;
52
- if (!existing.isFile() || existing.isSymbolicLink()) {
53
- throw lockError(path, 'the occupied lock is not a regular file', timeoutMs);
54
- }
55
- if (performance.now() >= deadline) {
56
- throw lockError(path, `acquisition timed out after ${timeoutMs} ms`, timeoutMs);
57
- }
58
- await delay(Math.min(25, Math.max(1, deadline - performance.now())));
255
+ const seen = await inspect(path, env);
256
+ if (!seen)
59
257
  continue;
258
+ if (!seen.stats.isFile() || seen.stats.isSymbolicLink()) {
259
+ throw lockError(path, `The stored memory lock ${path} is not a regular file, so Namzu will not use it. Move it aside to continue.`, timeoutMs);
60
260
  }
61
- const owner = `${JSON.stringify({ pid: process.pid, token: randomUUID(), acquiredAt: Date.now() })}\n`;
62
- const identity = await handle.stat().catch(async (error) => {
63
- await handle.close();
64
- // Exclusive create happened, but ownership could not be established.
65
- // Leave the path for explicit recovery rather than unlink an unknown inode.
66
- throw error;
67
- });
68
- try {
69
- await handle.writeFile(owner, 'utf8');
70
- await handle.sync();
71
- }
72
- catch (error) {
73
- await handle.close();
74
- const current = await lstat(path).catch(() => undefined);
75
- if (current?.dev === identity.dev && current.ino === identity.ino) {
76
- await unlink(path).catch(() => undefined);
77
- }
78
- throw error;
261
+ lastPid = seen.pid;
262
+ if (seen.staleReason !== undefined && (await breakStaleLock(path, seen, timeoutMs, env))) {
263
+ justBroke = true;
264
+ continue;
79
265
  }
80
- await handle.close();
81
- return async () => {
82
- const current = await lstat(path);
83
- if (!current.isFile() ||
84
- current.isSymbolicLink() ||
85
- current.dev !== identity.dev ||
86
- current.ino !== identity.ino ||
87
- (await readFile(path, 'utf8')) !== owner) {
88
- throw lockError(path, 'the lock owner changed before release', timeoutMs);
89
- }
90
- await unlink(path);
91
- };
266
+ if (performance.now() >= deadline)
267
+ throw busyError(path, lastPid, timeoutMs);
268
+ await delay(Math.min(25, Math.max(1, deadline - performance.now())));
92
269
  }
93
270
  }
94
271
  //# sourceMappingURL=operation-lock.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"operation-lock.js","sourceRoot":"","sources":["../../../src/store/memory/operation-lock.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"operation-lock.js","sourceRoot":"","sources":["../../../src/store/memory/operation-lock.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../src/store/session-index/sqlite.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAa,SAAS,EAAU,MAAM,0BAA0B,CAAA;AAI5E,OAAO,KAAK,EACX,mBAAmB,EACnB,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,sBAAsB,EACtB,cAAc,EAEd,WAAW,EAEX,mBAAmB,EACnB,MAAM,YAAY,CAAA;AACnB,OAAO,EAKN,KAAK,SAAS,EACd,gBAAgB,EAEhB,KAAK,UAAU,EAUf,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAoB,eAAe,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAErF,0GAA0G;AAC1G,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAsBtC,0FAA0F;AAC1F,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAwLD;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,QAAiB,CAAA;AA6ExD,MAAM,WAAW,yBAAyB;IACzC,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,gCAAiC,SAAQ,yBAAyB;IAClF;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACxC,OAAO,EAAE,gCAAgC,GACvC,OAAO,CAAC,OAAO,CAAC,CAElB;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,gBAAgB;;IACvD,QAAQ,CAAC,OAAO,EAAG,QAAQ,CAAS;IAMpC,2FAA2F;IAC3F,OAAO;IA2LP,6CAA6C;WAChC,OAAO,CAAC,OAAO,EAAE,gCAAgC,GAAG,OAAO,CAAC,OAAO,CAAC;IA0BjF;;;;OAIG;WACU,IAAI,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAwBlF,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,CAAC,GAAG,CAAC;IA0BzD,SAAS,CAAC,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS;IAOnE,SAAS,CAAC,iBAAiB,IAAI,SAAS,EAAE;IAIpC,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAe1E,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAOvD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAUlE,oBAAoB,CACzB,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,SAAS,CAAA;KAAO,GACrC,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAW9B,eAAe,CACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,eAAe,EACrB,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAUnC,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAOpE,OAAO,CAAC,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,SAAS,CAAA;KAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAWzE,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA8B5E,KAAK,IAAI,IAAI;CAKb"}
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../src/store/session-index/sqlite.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAa,SAAS,EAAU,MAAM,0BAA0B,CAAA;AAI5E,OAAO,KAAK,EACX,mBAAmB,EACnB,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,sBAAsB,EACtB,cAAc,EAEd,WAAW,EAEX,mBAAmB,EACnB,MAAM,YAAY,CAAA;AACnB,OAAO,EAKN,KAAK,SAAS,EACd,gBAAgB,EAEhB,KAAK,UAAU,EAUf,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAoB,eAAe,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAErF,0GAA0G;AAC1G,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAsBtC,0FAA0F;AAC1F,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAwLD;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,QAAiB,CAAA;AAoLxD,MAAM,WAAW,yBAAyB;IACzC,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,gCAAiC,SAAQ,yBAAyB;IAClF;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACxC,OAAO,EAAE,gCAAgC,GACvC,OAAO,CAAC,OAAO,CAAC,CAElB;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,gBAAgB;;IACvD,QAAQ,CAAC,OAAO,EAAG,QAAQ,CAAS;IAUpC,2FAA2F;IAC3F,OAAO;IA6LP,6CAA6C;WAChC,OAAO,CAAC,OAAO,EAAE,gCAAgC,GAAG,OAAO,CAAC,OAAO,CAAC;IAyBjF;;;;OAIG;WACU,IAAI,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA0DlF,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,CAAC,GAAG,CAAC;IAmCzD,SAAS,CAAC,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS;IAQnE,SAAS,CAAC,iBAAiB,IAAI,SAAS,EAAE;IAIpC,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAe1E,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAOvD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAUlE,oBAAoB,CACzB,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,SAAS,CAAA;KAAO,GACrC,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAW9B,eAAe,CACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,eAAe,EACrB,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAWnC,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAOpE,OAAO,CAAC,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,SAAS,CAAA;KAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAWzE,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA+B5E,KAAK,IAAI,IAAI;CAKb"}
@@ -1,3 +1,4 @@
1
+ import { existsSync, statSync } from 'node:fs';
1
2
  import { mkdir, readdir, rename, rm, stat } from 'node:fs/promises';
2
3
  import { createRequire } from 'node:module';
3
4
  import { basename, dirname, join } from 'node:path';
@@ -253,33 +254,129 @@ async function sweepAbandonedRebuilds(path) {
253
254
  await rm(journal, { force: true });
254
255
  }
255
256
  }
257
+ /** `device:inode` of the file at `path`, or undefined when there is none. */
258
+ function fileIdentity(path) {
259
+ try {
260
+ const { dev, ino } = statSync(path);
261
+ return `${dev}:${ino}`;
262
+ }
263
+ catch {
264
+ return undefined;
265
+ }
266
+ }
256
267
  function userVersion(db) {
257
268
  return Number(db.prepare('PRAGMA user_version').get()?.user_version);
258
269
  }
270
+ /** SQLite primary result codes for "the image is malformed" and "the file is not a database". */
271
+ const SQLITE_CORRUPT = 11;
272
+ const SQLITE_NOTADB = 26;
273
+ /** Whether `error` says the file's content is not a usable SQLite database. */
274
+ function isNotADatabase(error) {
275
+ const code = error?.errcode;
276
+ return typeof code === 'number' && [SQLITE_CORRUPT, SQLITE_NOTADB].includes(code & 0xff);
277
+ }
278
+ const SQLITE_BUSY = 5;
279
+ const SQLITE_READONLY = 8;
280
+ /** `SQLITE_READONLY_DBMOVED`: the file this connection opened was renamed or unlinked. */
281
+ const SQLITE_READONLY_DBMOVED = 1032;
282
+ function errcode(error) {
283
+ const code = error?.errcode;
284
+ return typeof code === 'number' ? code : undefined;
285
+ }
286
+ /** Whether `error` says another process holds the index locked past the busy timeout. */
287
+ function isBusy(error) {
288
+ const code = errcode(error);
289
+ return code !== undefined && (code & 0xff) === SQLITE_BUSY;
290
+ }
291
+ /** Whether `error` says the file under this connection was replaced by another process. */
292
+ function isMoved(error) {
293
+ const code = errcode(error);
294
+ return code === SQLITE_READONLY_DBMOVED && (code & 0xff) === SQLITE_READONLY;
295
+ }
296
+ /** A plain-language error for an index another process keeps locked. */
297
+ function busyError(path, cause) {
298
+ return new SessionIndexError(`The session index at ${path} is in use by another process. Try again in a moment.`, { cause });
299
+ }
259
300
  /**
260
- * The version of the index file at `path`: -1 when there is none, 0 when it
261
- * cannot be read as a SQLite database, otherwise its `user_version`.
301
+ * The version of the index file at `path`: -1 when there is none, 0 when its
302
+ * content is not a SQLite database, otherwise its `user_version`.
303
+ *
304
+ * The file is opened for writing, never read-only. A writer that died inside
305
+ * a transaction leaves a hot journal beside the file, and only a connection
306
+ * that may write can roll it back; a read-only one fails on it, which used to
307
+ * read as "not a database" and sent the caller to replace a healthy index,
308
+ * leaving the dead writer's journal beside the new file for the next
309
+ * connection to play back into it. Only a SQLite "corrupt" or "not a
310
+ * database" answer means 0; being busy, read-only or unable to read is thrown,
311
+ * never a reason to rebuild.
262
312
  */
263
313
  function indexVersion(path) {
264
- const { DatabaseSync } = requireSqlite();
265
- let db;
266
- try {
267
- db = new DatabaseSync(path, { readOnly: true });
268
- }
269
- catch {
314
+ if (!existsSync(path))
270
315
  return -1;
271
- }
316
+ const { DatabaseSync } = requireSqlite();
317
+ const db = new DatabaseSync(path);
272
318
  try {
273
319
  db.exec('PRAGMA busy_timeout = 10000');
274
320
  return userVersion(db);
275
321
  }
276
- catch {
277
- return 0;
322
+ catch (error) {
323
+ if (isNotADatabase(error))
324
+ return 0;
325
+ throw isBusy(error) ? busyError(path, error) : error;
278
326
  }
279
327
  finally {
280
328
  db.close();
281
329
  }
282
330
  }
331
+ /**
332
+ * Put the finished `temporary` file in place of the index at `path`.
333
+ *
334
+ * Takes the old index's exclusive lock first. That waits out a peer that is
335
+ * mid-write and rolls back a hot journal left by one that died, so no journal
336
+ * for the old file survives to be played into the new one. A leftover journal
337
+ * of a file that is not a database is removed too: it can describe nothing
338
+ * but that file.
339
+ */
340
+ async function replaceIndexFile(temporary, path, force) {
341
+ let old;
342
+ if (existsSync(path)) {
343
+ const { DatabaseSync } = requireSqlite();
344
+ old = new DatabaseSync(path);
345
+ try {
346
+ old.exec('PRAGMA busy_timeout = 10000');
347
+ old.exec('BEGIN EXCLUSIVE');
348
+ // A peer may have finished its own rebuild while this one ran. With the
349
+ // lock held, nobody can change the file between this check and the
350
+ // rename, so a current index is left alone rather than replaced under
351
+ // the connections that already adopted it.
352
+ if (!force && userVersion(old) === SESSION_INDEX_VERSION) {
353
+ old.close();
354
+ old = undefined;
355
+ return false;
356
+ }
357
+ }
358
+ catch (error) {
359
+ old?.close();
360
+ old = undefined;
361
+ if (!isNotADatabase(error))
362
+ throw isBusy(error) ? busyError(path, error) : error;
363
+ }
364
+ }
365
+ try {
366
+ // Windows will not rename over a file that is open, so the lock is let go
367
+ // first there; elsewhere it is held until the new file is in place.
368
+ if (process.platform === 'win32') {
369
+ old?.close();
370
+ old = undefined;
371
+ }
372
+ await rm(`${path}-journal`, { force: true });
373
+ await rename(temporary, path);
374
+ return true;
375
+ }
376
+ finally {
377
+ old?.close();
378
+ }
379
+ }
283
380
  /**
284
381
  * Build the index from every log under `home` into a temporary file beside
285
382
  * it (`index.sqlite.tmp-<pid>-<uuidv7>`), then rename that file over the
@@ -303,13 +400,19 @@ export function rebuildSqliteSessionIndex(options) {
303
400
  export class SqliteSessionIndex extends SessionIndexBase {
304
401
  backend = 'sqlite';
305
402
  #db;
403
+ /** Where `#db` was opened, or undefined for a temporary build file that is never watched. */
404
+ #path;
405
+ /** Identity of the file `#db` has open, to notice another process replacing it. */
406
+ #identity;
306
407
  #sink;
307
408
  #statements = new Map();
308
409
  #open = true;
309
410
  /** Wraps an open database whose schema is current. Use {@link SqliteSessionIndex.open}. */
310
- constructor(db) {
411
+ constructor(db, path) {
311
412
  super();
312
413
  this.#db = db;
414
+ this.#path = path;
415
+ this.#identity = path === undefined ? undefined : fileIdentity(path);
313
416
  const run = (sql, ...values) => {
314
417
  this.#statement(sql).run(...values);
315
418
  };
@@ -394,8 +497,7 @@ export class SqliteSessionIndex extends SessionIndexBase {
394
497
  if (indexVersion(options.path) === SESSION_INDEX_VERSION)
395
498
  return false;
396
499
  }
397
- await rename(temporary, options.path);
398
- return true;
500
+ return await replaceIndexFile(temporary, options.path, options.force === true);
399
501
  }
400
502
  finally {
401
503
  await rm(temporary, { force: true });
@@ -428,12 +530,59 @@ export class SqliteSessionIndex extends SessionIndexBase {
428
530
  db.close();
429
531
  throw error;
430
532
  }
431
- const index = new SqliteSessionIndex(db);
533
+ const index = new SqliteSessionIndex(db, options.path);
432
534
  await index.sync(options.home);
433
535
  return index;
434
536
  }
537
+ /**
538
+ * Another process rebuilt the index and renamed a new file over it: this
539
+ * connection still has the old, unlinked file, whose reads go stale and
540
+ * whose writes fail with SQLITE_READONLY_DBMOVED. Reopen the file now at
541
+ * the path. A no-op for a temporary build file, and when the path holds
542
+ * nothing to adopt.
543
+ */
544
+ #reopenIfReplaced(force = false) {
545
+ const path = this.#path;
546
+ if (path === undefined || !this.#open)
547
+ return;
548
+ const identity = fileIdentity(path);
549
+ if (identity === undefined || (!force && identity === this.#identity))
550
+ return;
551
+ const { DatabaseSync } = requireSqlite();
552
+ const db = new DatabaseSync(path);
553
+ try {
554
+ configure(db);
555
+ if (userVersion(db) !== SESSION_INDEX_VERSION) {
556
+ throw new SessionIndexError(`The index at ${path} changed version while in use.`);
557
+ }
558
+ }
559
+ catch (error) {
560
+ db.close();
561
+ throw error;
562
+ }
563
+ const previous = this.#db;
564
+ this.#statements.clear();
565
+ this.#db = db;
566
+ this.#identity = fileIdentity(path);
567
+ try {
568
+ previous.close();
569
+ }
570
+ catch {
571
+ // The old file is already unlinked; nothing is lost if it will not close.
572
+ }
573
+ }
435
574
  transaction(work) {
436
- this.#db.exec('BEGIN IMMEDIATE');
575
+ this.#reopenIfReplaced();
576
+ try {
577
+ this.#db.exec('BEGIN IMMEDIATE');
578
+ }
579
+ catch (error) {
580
+ // Nothing has run yet, so the work can start again on the new file.
581
+ if (!isMoved(error))
582
+ throw error;
583
+ this.#reopenIfReplaced(true);
584
+ this.#db.exec('BEGIN IMMEDIATE');
585
+ }
437
586
  try {
438
587
  const result = work(this.#sink);
439
588
  this.#db.exec('COMMIT');
@@ -454,9 +603,11 @@ export class SqliteSessionIndex extends SessionIndexBase {
454
603
  return statement;
455
604
  }
456
605
  #all(sql, ...values) {
606
+ this.#reopenIfReplaced();
457
607
  return this.#statement(sql).all(...values);
458
608
  }
459
609
  readSession(sessionId) {
610
+ this.#reopenIfReplaced();
460
611
  const row = this.#statement('SELECT * FROM sessions WHERE id = ?').get(sessionId);
461
612
  return row === undefined ? undefined : sessionRow(row);
462
613
  }
@@ -493,6 +644,7 @@ export class SqliteSessionIndex extends SessionIndexBase {
493
644
  return rows.map((row) => decisionView(decisionRow(row)));
494
645
  }
495
646
  async resolveExternal(protocol, kind, externalId) {
647
+ this.#reopenIfReplaced();
496
648
  const row = this.#db
497
649
  .prepare(`SELECT * FROM external_refs WHERE protocol = ? AND kind = ? AND external_id = ?
498
650
  ORDER BY claimed_at, session_id, claimed_seq LIMIT 1`)
@@ -523,6 +675,7 @@ export class SqliteSessionIndex extends SessionIndexBase {
523
675
  values.push(options.sessionId);
524
676
  }
525
677
  const clause = where.length === 0 ? '' : `WHERE ${where.join(' AND ')}`;
678
+ this.#reopenIfReplaced();
526
679
  const statement = this.#db.prepare(`SELECT text, session_id, turn_id, seq, part, source, tool_name, is_error FROM evidence_fts
527
680
  ${clause} ORDER BY session_id, seq, part`);
528
681
  const hits = [];