@ashx-j/lunr 0.2.21 → 0.2.22

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 (438) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +20 -4
  3. package/dist/builtin-extensions/index.d.ts.map +1 -1
  4. package/dist/builtin-extensions/index.js +1 -0
  5. package/dist/builtin-extensions/index.js.map +1 -1
  6. package/dist/builtin-extensions/lunr-browser.d.ts +3 -0
  7. package/dist/builtin-extensions/lunr-browser.d.ts.map +1 -0
  8. package/dist/builtin-extensions/lunr-browser.js +56 -0
  9. package/dist/builtin-extensions/lunr-browser.js.map +1 -0
  10. package/dist/builtin-extensions/lunr-todos.d.ts.map +1 -1
  11. package/dist/builtin-extensions/lunr-todos.js +15 -0
  12. package/dist/builtin-extensions/lunr-todos.js.map +1 -1
  13. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  14. package/dist/builtin-extensions/pi-intercom/index.js +3 -0
  15. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  16. package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.d.ts +1 -1
  17. package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.d.ts.map +1 -1
  18. package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.js +5 -1
  19. package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.js.map +1 -1
  20. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +2 -2
  21. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  22. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +18 -5
  23. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  24. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -3
  25. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  26. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +3 -0
  27. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  28. package/dist/builtin-extensions/pi-subagents/src/intercom/communication.d.ts +17 -0
  29. package/dist/builtin-extensions/pi-subagents/src/intercom/communication.d.ts.map +1 -0
  30. package/dist/builtin-extensions/pi-subagents/src/intercom/communication.js +45 -0
  31. package/dist/builtin-extensions/pi-subagents/src/intercom/communication.js.map +1 -0
  32. package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.d.ts.map +1 -1
  33. package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.js +4 -11
  34. package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.js.map +1 -1
  35. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts +4 -1
  36. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts.map +1 -1
  37. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js +160 -51
  38. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js.map +1 -1
  39. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts.map +1 -1
  40. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js +5 -0
  41. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js.map +1 -1
  42. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts +2 -0
  43. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts.map +1 -1
  44. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js +3 -2
  45. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js.map +1 -1
  46. package/dist/builtin-extensions/pi-subagents/src/runs/background/auto-drain.d.ts +1 -0
  47. package/dist/builtin-extensions/pi-subagents/src/runs/background/auto-drain.d.ts.map +1 -1
  48. package/dist/builtin-extensions/pi-subagents/src/runs/background/auto-drain.js +2 -1
  49. package/dist/builtin-extensions/pi-subagents/src/runs/background/auto-drain.js.map +1 -1
  50. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts +1 -0
  51. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts.map +1 -1
  52. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js +2 -0
  53. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js.map +1 -1
  54. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts.map +1 -1
  55. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js +3 -0
  56. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js.map +1 -1
  57. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-control.d.ts +1 -0
  58. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-control.d.ts.map +1 -1
  59. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-control.js +3 -0
  60. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-control.js.map +1 -1
  61. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
  62. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js +1 -1
  63. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
  64. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +1 -0
  65. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
  66. package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
  67. package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts +18 -0
  68. package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -0
  69. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +47 -0
  70. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -0
  71. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  72. package/dist/builtin-extensions/pi-web-access/index.js +11 -7
  73. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  74. package/dist/cli/args.d.ts.map +1 -1
  75. package/dist/cli/args.js +2 -1
  76. package/dist/cli/args.js.map +1 -1
  77. package/dist/cli/install-cli.d.ts.map +1 -1
  78. package/dist/cli/install-cli.js +15 -45
  79. package/dist/cli/install-cli.js.map +1 -1
  80. package/dist/core/agent-session-runtime.d.ts +9 -0
  81. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  82. package/dist/core/agent-session-runtime.js +126 -29
  83. package/dist/core/agent-session-runtime.js.map +1 -1
  84. package/dist/core/agent-session.d.ts +3 -0
  85. package/dist/core/agent-session.d.ts.map +1 -1
  86. package/dist/core/agent-session.js +20 -2
  87. package/dist/core/agent-session.js.map +1 -1
  88. package/dist/core/browser/network.d.ts +9 -0
  89. package/dist/core/browser/network.d.ts.map +1 -0
  90. package/dist/core/browser/network.js +146 -0
  91. package/dist/core/browser/network.js.map +1 -0
  92. package/dist/core/browser/runtime.d.ts +24 -0
  93. package/dist/core/browser/runtime.d.ts.map +1 -0
  94. package/dist/core/browser/runtime.js +289 -0
  95. package/dist/core/browser/runtime.js.map +1 -0
  96. package/dist/core/browser/schema.d.ts +16 -0
  97. package/dist/core/browser/schema.d.ts.map +1 -0
  98. package/dist/core/browser/schema.js +36 -0
  99. package/dist/core/browser/schema.js.map +1 -0
  100. package/dist/core/browser/settings.d.ts +8 -0
  101. package/dist/core/browser/settings.d.ts.map +1 -0
  102. package/dist/core/browser/settings.js +30 -0
  103. package/dist/core/browser/settings.js.map +1 -0
  104. package/dist/core/browser/setup.d.ts +2 -0
  105. package/dist/core/browser/setup.d.ts.map +1 -0
  106. package/dist/core/browser/setup.js +16 -0
  107. package/dist/core/browser/setup.js.map +1 -0
  108. package/dist/core/customize.d.ts.map +1 -1
  109. package/dist/core/customize.js +15 -14
  110. package/dist/core/customize.js.map +1 -1
  111. package/dist/core/export-html/index.d.ts.map +1 -1
  112. package/dist/core/export-html/index.js +1 -1
  113. package/dist/core/export-html/index.js.map +1 -1
  114. package/dist/core/extensions/runner.d.ts +1 -0
  115. package/dist/core/extensions/runner.d.ts.map +1 -1
  116. package/dist/core/extensions/runner.js +1 -1
  117. package/dist/core/extensions/runner.js.map +1 -1
  118. package/dist/core/extensions/types.d.ts +1 -1
  119. package/dist/core/extensions/types.d.ts.map +1 -1
  120. package/dist/core/extensions/types.js.map +1 -1
  121. package/dist/core/install-features.d.ts.map +1 -1
  122. package/dist/core/install-features.js +10 -8
  123. package/dist/core/install-features.js.map +1 -1
  124. package/dist/core/memory-cap.d.ts.map +1 -1
  125. package/dist/core/memory-cap.js +5 -3
  126. package/dist/core/memory-cap.js.map +1 -1
  127. package/dist/core/model-tiers.d.ts.map +1 -1
  128. package/dist/core/model-tiers.js +9 -6
  129. package/dist/core/model-tiers.js.map +1 -1
  130. package/dist/core/permissions.d.ts.map +1 -1
  131. package/dist/core/permissions.js +9 -0
  132. package/dist/core/permissions.js.map +1 -1
  133. package/dist/core/plan-mode.d.ts.map +1 -1
  134. package/dist/core/plan-mode.js +3 -0
  135. package/dist/core/plan-mode.js.map +1 -1
  136. package/dist/core/process-registry.d.ts.map +1 -1
  137. package/dist/core/process-registry.js +6 -4
  138. package/dist/core/process-registry.js.map +1 -1
  139. package/dist/core/runtime-scope.d.ts +11 -0
  140. package/dist/core/runtime-scope.d.ts.map +1 -0
  141. package/dist/core/runtime-scope.js +3 -0
  142. package/dist/core/runtime-scope.js.map +1 -0
  143. package/dist/core/sdk.d.ts.map +1 -1
  144. package/dist/core/sdk.js +13 -0
  145. package/dist/core/sdk.js.map +1 -1
  146. package/dist/core/session-handoff.d.ts +35 -0
  147. package/dist/core/session-handoff.d.ts.map +1 -0
  148. package/dist/core/session-handoff.js +214 -0
  149. package/dist/core/session-handoff.js.map +1 -0
  150. package/dist/core/session-manager.d.ts +20 -0
  151. package/dist/core/session-manager.d.ts.map +1 -1
  152. package/dist/core/session-manager.js +184 -22
  153. package/dist/core/session-manager.js.map +1 -1
  154. package/dist/core/session-ownership.d.ts +28 -0
  155. package/dist/core/session-ownership.d.ts.map +1 -0
  156. package/dist/core/session-ownership.js +138 -0
  157. package/dist/core/session-ownership.js.map +1 -0
  158. package/dist/core/session-retention.d.ts.map +1 -1
  159. package/dist/core/session-retention.js +11 -2
  160. package/dist/core/session-retention.js.map +1 -1
  161. package/dist/core/settings-manager.d.ts +7 -0
  162. package/dist/core/settings-manager.d.ts.map +1 -1
  163. package/dist/core/settings-manager.js +18 -0
  164. package/dist/core/settings-manager.js.map +1 -1
  165. package/dist/core/slash-commands.d.ts.map +1 -1
  166. package/dist/core/slash-commands.js +2 -0
  167. package/dist/core/slash-commands.js.map +1 -1
  168. package/dist/core/system-prompt.d.ts.map +1 -1
  169. package/dist/core/system-prompt.js +5 -2
  170. package/dist/core/system-prompt.js.map +1 -1
  171. package/dist/core/todo-settings.d.ts +5 -0
  172. package/dist/core/todo-settings.d.ts.map +1 -0
  173. package/dist/core/todo-settings.js +7 -0
  174. package/dist/core/todo-settings.js.map +1 -0
  175. package/dist/core/tools/bash.d.ts.map +1 -1
  176. package/dist/core/tools/bash.js +4 -4
  177. package/dist/core/tools/bash.js.map +1 -1
  178. package/dist/core/tools/edit.d.ts.map +1 -1
  179. package/dist/core/tools/edit.js +5 -3
  180. package/dist/core/tools/edit.js.map +1 -1
  181. package/dist/core/tools/find.d.ts.map +1 -1
  182. package/dist/core/tools/find.js +4 -4
  183. package/dist/core/tools/find.js.map +1 -1
  184. package/dist/core/tools/grep.d.ts.map +1 -1
  185. package/dist/core/tools/grep.js +4 -4
  186. package/dist/core/tools/grep.js.map +1 -1
  187. package/dist/core/tools/ls.d.ts.map +1 -1
  188. package/dist/core/tools/ls.js +4 -4
  189. package/dist/core/tools/ls.js.map +1 -1
  190. package/dist/core/tools/read.d.ts.map +1 -1
  191. package/dist/core/tools/read.js +4 -4
  192. package/dist/core/tools/read.js.map +1 -1
  193. package/dist/core/tools/render-utils.d.ts +11 -2
  194. package/dist/core/tools/render-utils.d.ts.map +1 -1
  195. package/dist/core/tools/render-utils.js +31 -4
  196. package/dist/core/tools/render-utils.js.map +1 -1
  197. package/dist/core/tools/write.d.ts.map +1 -1
  198. package/dist/core/tools/write.js +4 -4
  199. package/dist/core/tools/write.js.map +1 -1
  200. package/dist/core/usage-service.d.ts.map +1 -1
  201. package/dist/core/usage-service.js +5 -3
  202. package/dist/core/usage-service.js.map +1 -1
  203. package/dist/gateway/adapters/discord.d.ts +12 -1
  204. package/dist/gateway/adapters/discord.d.ts.map +1 -1
  205. package/dist/gateway/adapters/discord.js +112 -17
  206. package/dist/gateway/adapters/discord.js.map +1 -1
  207. package/dist/gateway/adapters/telegram.d.ts +4 -2
  208. package/dist/gateway/adapters/telegram.d.ts.map +1 -1
  209. package/dist/gateway/adapters/telegram.js +34 -11
  210. package/dist/gateway/adapters/telegram.js.map +1 -1
  211. package/dist/gateway/agent-bridge.d.ts +14 -3
  212. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  213. package/dist/gateway/agent-bridge.js +252 -60
  214. package/dist/gateway/agent-bridge.js.map +1 -1
  215. package/dist/gateway/approval.d.ts +1 -0
  216. package/dist/gateway/approval.d.ts.map +1 -1
  217. package/dist/gateway/approval.js +60 -18
  218. package/dist/gateway/approval.js.map +1 -1
  219. package/dist/gateway/authz.d.ts +2 -0
  220. package/dist/gateway/authz.d.ts.map +1 -1
  221. package/dist/gateway/authz.js +13 -0
  222. package/dist/gateway/authz.js.map +1 -1
  223. package/dist/gateway/buttons.d.ts +3 -1
  224. package/dist/gateway/buttons.d.ts.map +1 -1
  225. package/dist/gateway/buttons.js +18 -3
  226. package/dist/gateway/buttons.js.map +1 -1
  227. package/dist/gateway/command.d.ts.map +1 -1
  228. package/dist/gateway/command.js +49 -4
  229. package/dist/gateway/command.js.map +1 -1
  230. package/dist/gateway/commands.d.ts.map +1 -1
  231. package/dist/gateway/commands.js +18 -3
  232. package/dist/gateway/commands.js.map +1 -1
  233. package/dist/gateway/config.d.ts +5 -0
  234. package/dist/gateway/config.d.ts.map +1 -1
  235. package/dist/gateway/config.js +5 -0
  236. package/dist/gateway/config.js.map +1 -1
  237. package/dist/gateway/conversations.d.ts +14 -0
  238. package/dist/gateway/conversations.d.ts.map +1 -0
  239. package/dist/gateway/conversations.js +30 -0
  240. package/dist/gateway/conversations.js.map +1 -0
  241. package/dist/gateway/download.d.ts +2 -0
  242. package/dist/gateway/download.d.ts.map +1 -0
  243. package/dist/gateway/download.js +36 -0
  244. package/dist/gateway/download.js.map +1 -0
  245. package/dist/gateway/index.d.ts.map +1 -1
  246. package/dist/gateway/index.js +85 -26
  247. package/dist/gateway/index.js.map +1 -1
  248. package/dist/gateway/mobile-commands.d.ts +24 -0
  249. package/dist/gateway/mobile-commands.d.ts.map +1 -0
  250. package/dist/gateway/mobile-commands.js +422 -0
  251. package/dist/gateway/mobile-commands.js.map +1 -0
  252. package/dist/gateway/presenter.d.ts +16 -0
  253. package/dist/gateway/presenter.d.ts.map +1 -0
  254. package/dist/gateway/presenter.js +210 -0
  255. package/dist/gateway/presenter.js.map +1 -0
  256. package/dist/gateway/router.d.ts +1 -0
  257. package/dist/gateway/router.d.ts.map +1 -1
  258. package/dist/gateway/router.js +32 -3
  259. package/dist/gateway/router.js.map +1 -1
  260. package/dist/gateway/service.d.ts +46 -0
  261. package/dist/gateway/service.d.ts.map +1 -0
  262. package/dist/gateway/service.js +395 -0
  263. package/dist/gateway/service.js.map +1 -0
  264. package/dist/gateway/setup.d.ts +4 -0
  265. package/dist/gateway/setup.d.ts.map +1 -0
  266. package/dist/gateway/setup.js +146 -0
  267. package/dist/gateway/setup.js.map +1 -0
  268. package/dist/gateway/types.d.ts +4 -2
  269. package/dist/gateway/types.d.ts.map +1 -1
  270. package/dist/gateway/types.js.map +1 -1
  271. package/dist/index.d.ts +2 -0
  272. package/dist/index.d.ts.map +1 -1
  273. package/dist/index.js +2 -0
  274. package/dist/index.js.map +1 -1
  275. package/dist/main.d.ts.map +1 -1
  276. package/dist/main.js +2 -1
  277. package/dist/main.js.map +1 -1
  278. package/dist/modes/interactive/components/assistant-message.d.ts +11 -2
  279. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  280. package/dist/modes/interactive/components/assistant-message.js +53 -16
  281. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  282. package/dist/modes/interactive/components/copyable-text.d.ts +31 -0
  283. package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -0
  284. package/dist/modes/interactive/components/copyable-text.js +165 -0
  285. package/dist/modes/interactive/components/copyable-text.js.map +1 -0
  286. package/dist/modes/interactive/components/custom-entry.d.ts +1 -0
  287. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  288. package/dist/modes/interactive/components/custom-entry.js +8 -0
  289. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  290. package/dist/modes/interactive/components/custom-message.d.ts +1 -0
  291. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  292. package/dist/modes/interactive/components/custom-message.js +8 -0
  293. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  294. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  295. package/dist/modes/interactive/components/session-selector.js +16 -0
  296. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  297. package/dist/modes/interactive/components/settings-selector.d.ts +5 -0
  298. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  299. package/dist/modes/interactive/components/settings-selector.js +38 -0
  300. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  301. package/dist/modes/interactive/interactive-mode.d.ts +3 -0
  302. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  303. package/dist/modes/interactive/interactive-mode.js +151 -7
  304. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  305. package/dist/node-runtime/agent-session-services-NQ6GKOIK.js +49 -0
  306. package/dist/node-runtime/{builtin-extensions-JCOPAAB5.js → builtin-extensions-GVC6IFDU.js} +6 -5
  307. package/dist/node-runtime/{chunk-LTYWTR3V.js → chunk-2MI5OPMN.js} +17 -2
  308. package/dist/node-runtime/{chunk-W3CVH5RX.js → chunk-2TKODGBZ.js} +11 -6
  309. package/dist/node-runtime/chunk-4EULYYR4.js +62 -0
  310. package/dist/node-runtime/chunk-5BNJ4JUH.js +672 -0
  311. package/dist/node-runtime/{chunk-6N22HULO.js → chunk-5D7LC2ZQ.js} +7 -2
  312. package/dist/node-runtime/{chunk-KBKMCJDU.js → chunk-5ZQXRPMC.js} +19 -4
  313. package/dist/node-runtime/{chunk-6KDIOJL3.js → chunk-6427XAWG.js} +3 -3
  314. package/dist/node-runtime/{chunk-BOHIDQT4.js → chunk-6B2POMK7.js} +1 -1
  315. package/dist/node-runtime/{chunk-RNBHABBA.js → chunk-7QWNYZDI.js} +7 -0
  316. package/dist/node-runtime/chunk-AZJHNQKQ.js +205 -0
  317. package/dist/node-runtime/{chunk-A3KMVBZV.js → chunk-BBUVIEZB.js} +1 -10
  318. package/dist/node-runtime/chunk-BFNXONG3.js +521 -0
  319. package/dist/node-runtime/{chunk-IRPJXI6U.js → chunk-BX2RB477.js} +1 -1
  320. package/dist/node-runtime/chunk-CCCN2UCX.js +14 -0
  321. package/dist/node-runtime/{chunk-25I2BHAA.js → chunk-CSUZVNYE.js} +1 -1
  322. package/dist/node-runtime/{chunk-QZMODZQ2.js → chunk-E24EO34J.js} +2 -1
  323. package/dist/node-runtime/{chunk-2BUAYZ7K.js → chunk-EQ63ANHL.js} +422 -123
  324. package/dist/node-runtime/{chunk-GB2MGFLI.js → chunk-GJSAD4AB.js} +216 -201
  325. package/dist/node-runtime/{chunk-W3SILANP.js → chunk-GMHJCCEN.js} +8 -8
  326. package/dist/node-runtime/{chunk-DDWHZ633.js → chunk-GNN7H3B7.js} +1 -1
  327. package/dist/node-runtime/chunk-GS66LV4M.js +2830 -0
  328. package/dist/node-runtime/{chunk-6BEIBLQ3.js → chunk-H3XF4UVQ.js} +1 -1
  329. package/dist/node-runtime/chunk-H4K3JDRB.js +47 -0
  330. package/dist/node-runtime/{chunk-YMEAYRBE.js → chunk-HTFRRDSF.js} +2 -7
  331. package/dist/node-runtime/chunk-IMLCWLPI.js +9 -0
  332. package/dist/node-runtime/{chunk-Y5KOEMBH.js → chunk-IQIEU7SB.js} +9 -674
  333. package/dist/node-runtime/{chunk-OPEK5RRY.js → chunk-IVXYUAJE.js} +1 -1
  334. package/dist/node-runtime/{chunk-PDNXVXMD.js → chunk-IWOWXRWU.js} +58 -48
  335. package/dist/node-runtime/chunk-KKUTQQV7.js +144 -0
  336. package/dist/node-runtime/{chunk-AWVD5IEY.js → chunk-LMBNLFXQ.js} +23 -12
  337. package/dist/node-runtime/{chunk-7NBZ5P7I.js → chunk-NAY6UUQZ.js} +1 -1
  338. package/dist/node-runtime/chunk-OAR4TYZE.js +146 -0
  339. package/dist/node-runtime/{chunk-STERBGUB.js → chunk-OFKSVRV7.js} +2 -2
  340. package/dist/node-runtime/{chunk-JZQ7F36T.js → chunk-ORH324EP.js} +19 -3
  341. package/dist/node-runtime/{chunk-2SJB2AWP.js → chunk-PC2Z5TKZ.js} +3 -3
  342. package/dist/node-runtime/{chunk-SY2TFMLO.js → chunk-QDGKKKUM.js} +46 -151
  343. package/dist/node-runtime/chunk-R3K2F5GI.js +122 -0
  344. package/dist/node-runtime/chunk-RMQZU2YU.js +117 -0
  345. package/dist/node-runtime/{chunk-XI77KVKA.js → chunk-TDL7UWJ7.js} +283 -2999
  346. package/dist/node-runtime/{chunk-G6LRAP36.js → chunk-TQGPP4SC.js} +1 -1
  347. package/dist/node-runtime/chunk-UAEOTO52.js +119 -0
  348. package/dist/node-runtime/{chunk-VZR3NCM7.js → chunk-UAFLNHSH.js} +18 -14
  349. package/dist/node-runtime/{chunk-AY6CAJSL.js → chunk-UJOCPOMX.js} +6 -3
  350. package/dist/node-runtime/chunk-UP2XBVH5.js +40 -0
  351. package/dist/node-runtime/{chunk-WJVFOIB5.js → chunk-UQUCFAJ3.js} +1 -1
  352. package/dist/node-runtime/chunk-URD2SLIT.js +1019 -0
  353. package/dist/node-runtime/chunk-US544NN6.js +13 -0
  354. package/dist/node-runtime/chunk-UWPJL22I.js +341 -0
  355. package/dist/node-runtime/chunk-V2A7CEXK.js +355 -0
  356. package/dist/node-runtime/chunk-VJPTNWAP.js +708 -0
  357. package/dist/node-runtime/{chunk-WKDK4C5P.js → chunk-VSSXXL36.js} +38 -164
  358. package/dist/node-runtime/{chunk-4I23VTC4.js → chunk-VWCE2HSZ.js} +21 -124
  359. package/dist/node-runtime/{chunk-WLLDXJRT.js → chunk-WADV2VDS.js} +22 -1014
  360. package/dist/node-runtime/{chunk-GKLEQ3I4.js → chunk-XLTL257W.js} +126 -27
  361. package/dist/node-runtime/chunk-YPHAIRZT.js +10 -0
  362. package/dist/node-runtime/cli-runtime.js +2 -2
  363. package/dist/node-runtime/command-3JHHXOPX.js +45 -0
  364. package/dist/node-runtime/commands-2JVNFGMQ.js +36 -0
  365. package/dist/node-runtime/{commands-MV5KOZ64.js → commands-KAMO2T6P.js} +10 -10
  366. package/dist/node-runtime/config-RORQUQFG.js +20 -0
  367. package/dist/node-runtime/{customize-LF5VST47.js → customize-VFJV3U6A.js} +2 -1
  368. package/dist/node-runtime/{direct-tool-executor-BK7CLEBX.js → direct-tool-executor-YAVOLDFY.js} +8 -8
  369. package/dist/node-runtime/{export-html-TEXVV5RP.js → export-html-KBFVV63J.js} +4 -3
  370. package/dist/node-runtime/{extension-input-O4HSAEM4.js → extension-input-K24TVKVW.js} +4 -4
  371. package/dist/node-runtime/{extension-selector-X5FCX43D.js → extension-selector-SPNF7EDR.js} +4 -4
  372. package/dist/node-runtime/{extract-XLQSJN4V.js → extract-EQJE7FZZ.js} +2 -2
  373. package/dist/node-runtime/{gateway-BM6NLOH4.js → gateway-VFO6SFKK.js} +275 -994
  374. package/dist/node-runtime/{gemini-search-U7SUMPQA.js → gemini-search-35OCRFLN.js} +1 -1
  375. package/dist/node-runtime/{gemini-url-context-PXWCBQHK.js → gemini-url-context-UQY3PHHW.js} +2 -2
  376. package/dist/node-runtime/index.js +104 -65
  377. package/dist/node-runtime/{init-3C7Z24OI.js → init-X2LIUB2H.js} +3 -3
  378. package/dist/node-runtime/{install-cli-EXMJQESX.js → install-cli-C3CF7O7N.js} +21 -82
  379. package/dist/node-runtime/interactive-mode-LOM6AIF6.js +72 -0
  380. package/dist/node-runtime/{interactive-view-ILS6TAN5.js → interactive-view-IDSCPPK7.js} +8 -8
  381. package/dist/node-runtime/lunr-browser-YNW7FTYX.js +87 -0
  382. package/dist/node-runtime/{lunr-cron-4VHP4E4B.js → lunr-cron-BKHGNBKT.js} +19 -5
  383. package/dist/node-runtime/main.js +44 -31
  384. package/dist/node-runtime/{memory-cap-3S4XRLNP.js → memory-cap-EL3KL4JJ.js} +2 -1
  385. package/dist/node-runtime/mobile-commands-HMP25WBC.js +32 -0
  386. package/dist/node-runtime/model-runtime-PLQKAG4B.js +16 -0
  387. package/dist/node-runtime/{model-tiers-NJLHUEGK.js → model-tiers-OU3U5CZG.js} +2 -1
  388. package/dist/node-runtime/{package-manager-cli-N37546V5.js → package-manager-cli-VCK4E2RC.js} +22 -15
  389. package/dist/node-runtime/{pi-intercom-NV2LW6X7.js → pi-intercom-HBPK5HSJ.js} +4 -1
  390. package/dist/node-runtime/{pi-mcp-adapter-GUFZWW54.js → pi-mcp-adapter-E6WULBKF.js} +4 -4
  391. package/dist/node-runtime/{pi-subagents-6MUIFNDM.js → pi-subagents-FEUDLJOE.js} +201 -78
  392. package/dist/node-runtime/{pi-web-access-2CQGFLT2.js → pi-web-access-WTGMNZ32.js} +15 -15
  393. package/dist/node-runtime/process-registry-4FAKZQOL.js +31 -0
  394. package/dist/node-runtime/{proxy-modes-V6YVFH3C.js → proxy-modes-OSQCWRBI.js} +9 -9
  395. package/dist/node-runtime/rpc-entry.js +44 -31
  396. package/dist/node-runtime/{rpc-mode-W5ZTLTMZ.js → rpc-mode-P5ODXPEG.js} +2 -2
  397. package/dist/node-runtime/runtime-4VA6JKNF.js +373 -0
  398. package/dist/node-runtime/{runtime-bridges-2VQTLPOZ.js → runtime-bridges-3XUQ46XW.js} +6 -5
  399. package/dist/node-runtime/service-ISSP6VHE.js +36 -0
  400. package/dist/node-runtime/session-handoff-HC7R5E24.js +33 -0
  401. package/dist/node-runtime/{session-manager-E7AREDTV.js → session-manager-CFN4UFM2.js} +2 -1
  402. package/dist/node-runtime/{session-selector-FJ7M2AIX.js → session-selector-LHRMJOKT.js} +5 -4
  403. package/dist/node-runtime/{settings-manager-CUGAZWAB.js → settings-manager-UUZ6NUXI.js} +7 -2
  404. package/dist/node-runtime/setup-JBKOLJ6F.js +18 -0
  405. package/dist/node-runtime/setup-NRXVZBLJ.js +155 -0
  406. package/dist/node-runtime/{subagent-executor-MH4A7CCF.js → subagent-executor-MLUMBWCP.js} +22 -18
  407. package/dist/node-runtime/theme-U7IGOA7O.js +68 -0
  408. package/dist/node-runtime/trust-manager-MMISNCYO.js +17 -0
  409. package/dist/node-runtime/{update-cli-XTZMZGOL.js → update-cli-4TP25CNW.js} +7 -2
  410. package/dist/node-runtime/usage-service-LFB2SWYV.js +37 -0
  411. package/dist/node-runtime/{video-extract-OYT5WKS5.js → video-extract-OOZHR7SU.js} +2 -2
  412. package/dist/node-runtime/{youtube-extract-TQYKGFGS.js → youtube-extract-FNPAUNHU.js} +6 -6
  413. package/docs/browser.md +86 -0
  414. package/docs/extensions.md +2 -0
  415. package/docs/features.md +94 -16
  416. package/docs/interactive-startup.md +2 -1
  417. package/docs/sessions.md +10 -0
  418. package/docs/settings.md +1 -0
  419. package/docs/tui.md +2 -0
  420. package/docs/usage.md +16 -0
  421. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  422. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  423. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  424. package/examples/extensions/gondolin/package-lock.json +2 -2
  425. package/examples/extensions/gondolin/package.json +1 -1
  426. package/examples/extensions/sandbox/package-lock.json +2 -2
  427. package/examples/extensions/sandbox/package.json +1 -1
  428. package/examples/extensions/with-deps/package-lock.json +2 -2
  429. package/examples/extensions/with-deps/package.json +1 -1
  430. package/package.json +7 -4
  431. package/scripts/install-browser.mjs +20 -0
  432. package/dist/node-runtime/agent-session-services-C743TYQE.js +0 -37
  433. package/dist/node-runtime/chunk-VGYZ3APQ.js +0 -59
  434. package/dist/node-runtime/command-P4NYCJ2M.js +0 -13
  435. package/dist/node-runtime/interactive-mode-EVVBA64D.js +0 -59
  436. package/dist/node-runtime/{chunk-UWQYRSYQ.js → chunk-YJMMG7C6.js} +25 -25
  437. package/dist/node-runtime/{mcp-panel-IIGMXQGP.js → mcp-panel-KTTFXJZ4.js} +3 -3
  438. package/dist/node-runtime/{src-BPQFJR76.js → src-IVPNZ2BX.js} +9 -9
@@ -0,0 +1,138 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { existsSync, mkdirSync, readFileSync, realpathSync, renameSync, rmdirSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
3
+ import { hostname } from "node:os";
4
+ import { basename, dirname, join, resolve } from "node:path";
5
+ const instance = randomUUID();
6
+ export class SessionOwnershipError extends Error {
7
+ file;
8
+ constructor(file, message = "Session is owned by another runtime. Request a transfer or close its owner first.") {
9
+ super(`${message} ${file}`);
10
+ this.name = "SessionOwnershipError";
11
+ this.file = file;
12
+ }
13
+ }
14
+ export function canonicalSessionPath(file) {
15
+ const absolute = resolve(file);
16
+ let canonical;
17
+ if (existsSync(absolute))
18
+ canonical = realpathSync.native(absolute);
19
+ else {
20
+ const parent = dirname(absolute);
21
+ canonical = parent === absolute ? absolute : join(canonicalSessionPath(parent), basename(absolute));
22
+ }
23
+ return process.platform === "win32" ? canonical.toLowerCase() : canonical;
24
+ }
25
+ export function sessionOwnershipDirectory(file) {
26
+ return `${canonicalSessionPath(file)}.owner`;
27
+ }
28
+ export function readSessionOwner(file) {
29
+ const directory = sessionOwnershipDirectory(file);
30
+ if (!existsSync(directory))
31
+ return undefined;
32
+ try {
33
+ const value = JSON.parse(readFileSync(join(directory, "owner.json"), "utf8"));
34
+ if (value.version === 1 &&
35
+ value.file === canonicalSessionPath(file) &&
36
+ typeof value.generation === "string" &&
37
+ Number.isSafeInteger(value.pid) &&
38
+ value.pid > 0 &&
39
+ typeof value.host === "string" &&
40
+ typeof value.instance === "string")
41
+ return value;
42
+ }
43
+ catch { }
44
+ throw new SessionOwnershipError(file, "Session owner is incomplete or unknown; automatic takeover is unsafe.");
45
+ }
46
+ export function isSessionOwnerDead(owner) {
47
+ if (owner.host !== hostname())
48
+ return false;
49
+ try {
50
+ process.kill(owner.pid, 0);
51
+ return false;
52
+ }
53
+ catch (error) {
54
+ return error.code === "ESRCH";
55
+ }
56
+ }
57
+ export function writeSessionJson(file, value) {
58
+ const temp = `${file}.${randomUUID()}.tmp`;
59
+ try {
60
+ writeFileSync(temp, JSON.stringify(value), { flag: "wx", mode: 0o600 });
61
+ renameSync(temp, file);
62
+ }
63
+ finally {
64
+ if (existsSync(temp))
65
+ unlinkSync(temp);
66
+ }
67
+ }
68
+ export class SessionOwnership {
69
+ owner;
70
+ released = false;
71
+ directory;
72
+ constructor(file) {
73
+ file = canonicalSessionPath(file);
74
+ if (existsSync(file) && statSync(file).nlink > 1)
75
+ throw new SessionOwnershipError(file, "Hard-linked sessions cannot be owned safely. Use a separate copy.");
76
+ this.directory = sessionOwnershipDirectory(file);
77
+ this.owner = { version: 1, file, generation: randomUUID(), pid: process.pid, host: hostname(), instance };
78
+ mkdirSync(dirname(file), { recursive: true });
79
+ try {
80
+ mkdirSync(this.directory);
81
+ }
82
+ catch (error) {
83
+ if (error.code !== "EEXIST")
84
+ throw error;
85
+ const old = readSessionOwner(file);
86
+ if (!old || !isSessionOwnerDead(old))
87
+ throw new SessionOwnershipError(file);
88
+ // Serialize dead-owner cleanup. Never infer death from elapsed time or a missing heartbeat.
89
+ const recovery = `${this.directory}.recovery`;
90
+ try {
91
+ writeFileSync(recovery, JSON.stringify(this.owner), { flag: "wx", mode: 0o600 });
92
+ }
93
+ catch {
94
+ throw new SessionOwnershipError(file, "Session recovery is already in progress or requires manual inspection.");
95
+ }
96
+ try {
97
+ const current = readSessionOwner(file);
98
+ if (current?.generation !== old.generation || !isSessionOwnerDead(current))
99
+ throw new SessionOwnershipError(file);
100
+ unlinkSync(join(this.directory, "owner.json"));
101
+ rmdirSync(this.directory);
102
+ try {
103
+ mkdirSync(this.directory);
104
+ }
105
+ catch {
106
+ throw new SessionOwnershipError(file);
107
+ }
108
+ }
109
+ finally {
110
+ unlinkSync(recovery);
111
+ }
112
+ }
113
+ writeSessionJson(join(this.directory, "owner.json"), this.owner);
114
+ }
115
+ bindSession(sessionId) {
116
+ this.assert();
117
+ this.owner.sessionId = sessionId;
118
+ writeSessionJson(join(this.directory, "owner.json"), this.owner);
119
+ }
120
+ assert() {
121
+ if (existsSync(this.owner.file) && statSync(this.owner.file).nlink > 1)
122
+ throw new SessionOwnershipError(this.owner.file, "Session acquired a hard-link alias; writes are blocked.");
123
+ if (this.released || readSessionOwner(this.owner.file)?.generation !== this.owner.generation) {
124
+ throw new SessionOwnershipError(this.owner.file, "This runtime no longer owns the session. Reclaim or reopen it before continuing.");
125
+ }
126
+ }
127
+ release() {
128
+ if (this.released)
129
+ return;
130
+ this.assert();
131
+ this.released = true;
132
+ const releasedDirectory = `${this.directory}.released-${this.owner.generation}`;
133
+ renameSync(this.directory, releasedDirectory);
134
+ unlinkSync(join(releasedDirectory, "owner.json"));
135
+ rmdirSync(releasedDirectory);
136
+ }
137
+ }
138
+ //# sourceMappingURL=session-ownership.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-ownership.js","sourceRoot":"","sources":["../../src/core/session-ownership.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport {\n\texistsSync,\n\tmkdirSync,\n\treadFileSync,\n\trealpathSync,\n\trenameSync,\n\trmdirSync,\n\tstatSync,\n\tunlinkSync,\n\twriteFileSync,\n} from \"node:fs\";\nimport { hostname } from \"node:os\";\nimport { basename, dirname, join, resolve } from \"node:path\";\n\nexport interface SessionOwner {\n\tversion: 1;\n\tfile: string;\n\tgeneration: string;\n\tpid: number;\n\thost: string;\n\tinstance: string;\n\tsessionId?: string;\n}\nconst instance = randomUUID();\n\nexport class SessionOwnershipError extends Error {\n\treadonly file: string;\n\tconstructor(\n\t\tfile: string,\n\t\tmessage = \"Session is owned by another runtime. Request a transfer or close its owner first.\",\n\t) {\n\t\tsuper(`${message} ${file}`);\n\t\tthis.name = \"SessionOwnershipError\";\n\t\tthis.file = file;\n\t}\n}\n\nexport function canonicalSessionPath(file: string): string {\n\tconst absolute = resolve(file);\n\tlet canonical: string;\n\tif (existsSync(absolute)) canonical = realpathSync.native(absolute);\n\telse {\n\t\tconst parent = dirname(absolute);\n\t\tcanonical = parent === absolute ? absolute : join(canonicalSessionPath(parent), basename(absolute));\n\t}\n\treturn process.platform === \"win32\" ? canonical.toLowerCase() : canonical;\n}\n\nexport function sessionOwnershipDirectory(file: string): string {\n\treturn `${canonicalSessionPath(file)}.owner`;\n}\n\nexport function readSessionOwner(file: string): SessionOwner | undefined {\n\tconst directory = sessionOwnershipDirectory(file);\n\tif (!existsSync(directory)) return undefined;\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(join(directory, \"owner.json\"), \"utf8\"));\n\t\tif (\n\t\t\tvalue.version === 1 &&\n\t\t\tvalue.file === canonicalSessionPath(file) &&\n\t\t\ttypeof value.generation === \"string\" &&\n\t\t\tNumber.isSafeInteger(value.pid) &&\n\t\t\tvalue.pid > 0 &&\n\t\t\ttypeof value.host === \"string\" &&\n\t\t\ttypeof value.instance === \"string\"\n\t\t)\n\t\t\treturn value;\n\t} catch {}\n\tthrow new SessionOwnershipError(file, \"Session owner is incomplete or unknown; automatic takeover is unsafe.\");\n}\n\nexport function isSessionOwnerDead(owner: SessionOwner): boolean {\n\tif (owner.host !== hostname()) return false;\n\ttry {\n\t\tprocess.kill(owner.pid, 0);\n\t\treturn false;\n\t} catch (error) {\n\t\treturn (error as NodeJS.ErrnoException).code === \"ESRCH\";\n\t}\n}\n\nexport function writeSessionJson(file: string, value: unknown): void {\n\tconst temp = `${file}.${randomUUID()}.tmp`;\n\ttry {\n\t\twriteFileSync(temp, JSON.stringify(value), { flag: \"wx\", mode: 0o600 });\n\t\trenameSync(temp, file);\n\t} finally {\n\t\tif (existsSync(temp)) unlinkSync(temp);\n\t}\n}\n\nexport class SessionOwnership {\n\treadonly owner: SessionOwner;\n\tprivate released = false;\n\tprivate readonly directory: string;\n\tconstructor(file: string) {\n\t\tfile = canonicalSessionPath(file);\n\t\tif (existsSync(file) && statSync(file).nlink > 1)\n\t\t\tthrow new SessionOwnershipError(file, \"Hard-linked sessions cannot be owned safely. Use a separate copy.\");\n\t\tthis.directory = sessionOwnershipDirectory(file);\n\t\tthis.owner = { version: 1, file, generation: randomUUID(), pid: process.pid, host: hostname(), instance };\n\t\tmkdirSync(dirname(file), { recursive: true });\n\t\ttry {\n\t\t\tmkdirSync(this.directory);\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n\t\t\tconst old = readSessionOwner(file);\n\t\t\tif (!old || !isSessionOwnerDead(old)) throw new SessionOwnershipError(file);\n\t\t\t// Serialize dead-owner cleanup. Never infer death from elapsed time or a missing heartbeat.\n\t\t\tconst recovery = `${this.directory}.recovery`;\n\t\t\ttry {\n\t\t\t\twriteFileSync(recovery, JSON.stringify(this.owner), { flag: \"wx\", mode: 0o600 });\n\t\t\t} catch {\n\t\t\t\tthrow new SessionOwnershipError(\n\t\t\t\t\tfile,\n\t\t\t\t\t\"Session recovery is already in progress or requires manual inspection.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst current = readSessionOwner(file);\n\t\t\t\tif (current?.generation !== old.generation || !isSessionOwnerDead(current))\n\t\t\t\t\tthrow new SessionOwnershipError(file);\n\t\t\t\tunlinkSync(join(this.directory, \"owner.json\"));\n\t\t\t\trmdirSync(this.directory);\n\t\t\t\ttry {\n\t\t\t\t\tmkdirSync(this.directory);\n\t\t\t\t} catch {\n\t\t\t\t\tthrow new SessionOwnershipError(file);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tunlinkSync(recovery);\n\t\t\t}\n\t\t}\n\t\twriteSessionJson(join(this.directory, \"owner.json\"), this.owner);\n\t}\n\tbindSession(sessionId: string): void {\n\t\tthis.assert();\n\t\tthis.owner.sessionId = sessionId;\n\t\twriteSessionJson(join(this.directory, \"owner.json\"), this.owner);\n\t}\n\n\tassert(): void {\n\t\tif (existsSync(this.owner.file) && statSync(this.owner.file).nlink > 1)\n\t\t\tthrow new SessionOwnershipError(this.owner.file, \"Session acquired a hard-link alias; writes are blocked.\");\n\t\tif (this.released || readSessionOwner(this.owner.file)?.generation !== this.owner.generation) {\n\t\t\tthrow new SessionOwnershipError(\n\t\t\t\tthis.owner.file,\n\t\t\t\t\"This runtime no longer owns the session. Reclaim or reopen it before continuing.\",\n\t\t\t);\n\t\t}\n\t}\n\trelease(): void {\n\t\tif (this.released) return;\n\t\tthis.assert();\n\t\tthis.released = true;\n\t\tconst releasedDirectory = `${this.directory}.released-${this.owner.generation}`;\n\t\trenameSync(this.directory, releasedDirectory);\n\t\tunlinkSync(join(releasedDirectory, \"owner.json\"));\n\t\trmdirSync(releasedDirectory);\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"session-retention.d.ts","sourceRoot":"","sources":["../../src/core/session-retention.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,uBAAuB;IACvC,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAsB;IACtC,gDAAgD;IAChD,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAuCD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACrC,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,uBAA4B,GACnC,OAAO,CAAC,sBAAsB,CAAC,CAwBjC","sourcesContent":["// lunr: session retention pruning (Phase 5 of lunr-ux plan).\n// Scans the sessions root (~/.lunr/agent/sessions/, layout: <root>/--<cwd>--/*.jsonl,\n// or a flat custom --session-dir) and deletes .jsonl session files older than the\n// configured retention window. The active session file is always excluded.\n\nimport type { Dirent } from \"node:fs\";\nimport { readdir, stat, unlink } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\n\nexport interface PruneOldSessionsOptions {\n\t/** Absolute path of the active session file; never deleted. */\n\texcludeFile?: string;\n\t/** Reference timestamp in ms (defaults to Date.now()); injectable for tests. */\n\tnow?: number;\n}\n\nexport interface PruneOldSessionsResult {\n\t/** Paths of session files that were deleted. */\n\tdeleted: string[];\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nfunction sameFile(a: string, b: string): boolean {\n\tconst ra = resolve(a);\n\tconst rb = resolve(b);\n\t// Windows paths are case-insensitive.\n\treturn process.platform === \"win32\" ? ra.toLowerCase() === rb.toLowerCase() : ra === rb;\n}\n\nasync function pruneDir(\n\tdir: string,\n\tcutoffMs: number,\n\texcludeFile: string | undefined,\n\tdeleted: string[],\n): Promise<void> {\n\tlet entries: Dirent[];\n\ttry {\n\t\tentries = await readdir(dir, { withFileTypes: true });\n\t} catch {\n\t\treturn; // Missing or unreadable directory: nothing to prune.\n\t}\n\tfor (const entry of entries) {\n\t\tif (!entry.isFile() || !entry.name.endsWith(\".jsonl\")) continue;\n\t\tconst filePath = join(dir, entry.name);\n\t\tif (excludeFile && sameFile(filePath, excludeFile)) continue;\n\t\ttry {\n\t\t\tconst info = await stat(filePath);\n\t\t\tif (info.mtimeMs < cutoffMs) {\n\t\t\t\tawait unlink(filePath);\n\t\t\t\tdeleted.push(filePath);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Per-file errors (stat/unlink races, permissions) must never break startup.\n\t\t}\n\t}\n}\n\n/**\n * Delete .jsonl session files older than `retentionDays` under `sessionsRoot`.\n * Covers both layouts: project subdirectories (<root>/--<cwd>--/*.jsonl) and flat\n * custom session dirs (<root>/*.jsonl). `retentionDays <= 0` keeps everything.\n */\nexport async function pruneOldSessions(\n\tsessionsRoot: string,\n\tretentionDays: number,\n\toptions: PruneOldSessionsOptions = {},\n): Promise<PruneOldSessionsResult> {\n\tconst deleted: string[] = [];\n\tif (!Number.isFinite(retentionDays) || retentionDays <= 0) {\n\t\treturn { deleted };\n\t}\n\tconst now = options.now ?? Date.now();\n\tconst cutoffMs = now - retentionDays * DAY_MS;\n\n\t// Flat layout (custom --session-dir).\n\tawait pruneDir(sessionsRoot, cutoffMs, options.excludeFile, deleted);\n\n\t// Project layout (<root>/<dir>/*.jsonl).\n\tlet subdirs: Dirent[];\n\ttry {\n\t\tsubdirs = await readdir(sessionsRoot, { withFileTypes: true });\n\t} catch {\n\t\treturn { deleted };\n\t}\n\tfor (const entry of subdirs) {\n\t\tif (entry.isDirectory()) {\n\t\t\tawait pruneDir(join(sessionsRoot, entry.name), cutoffMs, options.excludeFile, deleted);\n\t\t}\n\t}\n\treturn { deleted };\n}\n"]}
1
+ {"version":3,"file":"session-retention.d.ts","sourceRoot":"","sources":["../../src/core/session-retention.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,uBAAuB;IACvC,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAsB;IACtC,gDAAgD;IAChD,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AA8CD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACrC,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,uBAA4B,GACnC,OAAO,CAAC,sBAAsB,CAAC,CAwBjC","sourcesContent":["// lunr: session retention pruning (Phase 5 of lunr-ux plan).\n// Scans the sessions root (~/.lunr/agent/sessions/, layout: <root>/--<cwd>--/*.jsonl,\n// or a flat custom --session-dir) and deletes .jsonl session files older than the\n// configured retention window. The active session file is always excluded.\n\nimport type { Dirent } from \"node:fs\";\nimport { readdir, stat, unlink } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { SessionOwnership } from \"./session-ownership.ts\";\n\nexport interface PruneOldSessionsOptions {\n\t/** Absolute path of the active session file; never deleted. */\n\texcludeFile?: string;\n\t/** Reference timestamp in ms (defaults to Date.now()); injectable for tests. */\n\tnow?: number;\n}\n\nexport interface PruneOldSessionsResult {\n\t/** Paths of session files that were deleted. */\n\tdeleted: string[];\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nfunction sameFile(a: string, b: string): boolean {\n\tconst ra = resolve(a);\n\tconst rb = resolve(b);\n\t// Windows paths are case-insensitive.\n\treturn process.platform === \"win32\" ? ra.toLowerCase() === rb.toLowerCase() : ra === rb;\n}\n\nasync function pruneDir(\n\tdir: string,\n\tcutoffMs: number,\n\texcludeFile: string | undefined,\n\tdeleted: string[],\n): Promise<void> {\n\tlet entries: Dirent[];\n\ttry {\n\t\tentries = await readdir(dir, { withFileTypes: true });\n\t} catch {\n\t\treturn; // Missing or unreadable directory: nothing to prune.\n\t}\n\tfor (const entry of entries) {\n\t\tif (!entry.isFile() || !entry.name.endsWith(\".jsonl\")) continue;\n\t\tconst filePath = join(dir, entry.name);\n\t\tif (excludeFile && sameFile(filePath, excludeFile)) continue;\n\t\ttry {\n\t\t\tconst info = await stat(filePath);\n\t\t\tif (info.mtimeMs < cutoffMs) {\n\t\t\t\tconst ownership = new SessionOwnership(filePath);\n\t\t\t\ttry {\n\t\t\t\t\tif ((await stat(filePath)).mtimeMs < cutoffMs) {\n\t\t\t\t\t\tawait unlink(filePath);\n\t\t\t\t\t\tdeleted.push(filePath);\n\t\t\t\t\t}\n\t\t\t\t} finally {\n\t\t\t\t\townership.release();\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Per-file errors (stat/unlink races, permissions) must never break startup.\n\t\t}\n\t}\n}\n\n/**\n * Delete .jsonl session files older than `retentionDays` under `sessionsRoot`.\n * Covers both layouts: project subdirectories (<root>/--<cwd>--/*.jsonl) and flat\n * custom session dirs (<root>/*.jsonl). `retentionDays <= 0` keeps everything.\n */\nexport async function pruneOldSessions(\n\tsessionsRoot: string,\n\tretentionDays: number,\n\toptions: PruneOldSessionsOptions = {},\n): Promise<PruneOldSessionsResult> {\n\tconst deleted: string[] = [];\n\tif (!Number.isFinite(retentionDays) || retentionDays <= 0) {\n\t\treturn { deleted };\n\t}\n\tconst now = options.now ?? Date.now();\n\tconst cutoffMs = now - retentionDays * DAY_MS;\n\n\t// Flat layout (custom --session-dir).\n\tawait pruneDir(sessionsRoot, cutoffMs, options.excludeFile, deleted);\n\n\t// Project layout (<root>/<dir>/*.jsonl).\n\tlet subdirs: Dirent[];\n\ttry {\n\t\tsubdirs = await readdir(sessionsRoot, { withFileTypes: true });\n\t} catch {\n\t\treturn { deleted };\n\t}\n\tfor (const entry of subdirs) {\n\t\tif (entry.isDirectory()) {\n\t\t\tawait pruneDir(join(sessionsRoot, entry.name), cutoffMs, options.excludeFile, deleted);\n\t\t}\n\t}\n\treturn { deleted };\n}\n"]}
@@ -4,6 +4,7 @@
4
4
  // configured retention window. The active session file is always excluded.
5
5
  import { readdir, stat, unlink } from "node:fs/promises";
6
6
  import { join, resolve } from "node:path";
7
+ import { SessionOwnership } from "./session-ownership.js";
7
8
  const DAY_MS = 24 * 60 * 60 * 1000;
8
9
  function sameFile(a, b) {
9
10
  const ra = resolve(a);
@@ -28,8 +29,16 @@ async function pruneDir(dir, cutoffMs, excludeFile, deleted) {
28
29
  try {
29
30
  const info = await stat(filePath);
30
31
  if (info.mtimeMs < cutoffMs) {
31
- await unlink(filePath);
32
- deleted.push(filePath);
32
+ const ownership = new SessionOwnership(filePath);
33
+ try {
34
+ if ((await stat(filePath)).mtimeMs < cutoffMs) {
35
+ await unlink(filePath);
36
+ deleted.push(filePath);
37
+ }
38
+ }
39
+ finally {
40
+ ownership.release();
41
+ }
33
42
  }
34
43
  }
35
44
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"session-retention.js","sourceRoot":"","sources":["../../src/core/session-retention.ts"],"names":[],"mappings":"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","sourcesContent":["// lunr: session retention pruning (Phase 5 of lunr-ux plan).\n// Scans the sessions root (~/.lunr/agent/sessions/, layout: <root>/--<cwd>--/*.jsonl,\n// or a flat custom --session-dir) and deletes .jsonl session files older than the\n// configured retention window. The active session file is always excluded.\n\nimport type { Dirent } from \"node:fs\";\nimport { readdir, stat, unlink } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\n\nexport interface PruneOldSessionsOptions {\n\t/** Absolute path of the active session file; never deleted. */\n\texcludeFile?: string;\n\t/** Reference timestamp in ms (defaults to Date.now()); injectable for tests. */\n\tnow?: number;\n}\n\nexport interface PruneOldSessionsResult {\n\t/** Paths of session files that were deleted. */\n\tdeleted: string[];\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nfunction sameFile(a: string, b: string): boolean {\n\tconst ra = resolve(a);\n\tconst rb = resolve(b);\n\t// Windows paths are case-insensitive.\n\treturn process.platform === \"win32\" ? ra.toLowerCase() === rb.toLowerCase() : ra === rb;\n}\n\nasync function pruneDir(\n\tdir: string,\n\tcutoffMs: number,\n\texcludeFile: string | undefined,\n\tdeleted: string[],\n): Promise<void> {\n\tlet entries: Dirent[];\n\ttry {\n\t\tentries = await readdir(dir, { withFileTypes: true });\n\t} catch {\n\t\treturn; // Missing or unreadable directory: nothing to prune.\n\t}\n\tfor (const entry of entries) {\n\t\tif (!entry.isFile() || !entry.name.endsWith(\".jsonl\")) continue;\n\t\tconst filePath = join(dir, entry.name);\n\t\tif (excludeFile && sameFile(filePath, excludeFile)) continue;\n\t\ttry {\n\t\t\tconst info = await stat(filePath);\n\t\t\tif (info.mtimeMs < cutoffMs) {\n\t\t\t\tawait unlink(filePath);\n\t\t\t\tdeleted.push(filePath);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Per-file errors (stat/unlink races, permissions) must never break startup.\n\t\t}\n\t}\n}\n\n/**\n * Delete .jsonl session files older than `retentionDays` under `sessionsRoot`.\n * Covers both layouts: project subdirectories (<root>/--<cwd>--/*.jsonl) and flat\n * custom session dirs (<root>/*.jsonl). `retentionDays <= 0` keeps everything.\n */\nexport async function pruneOldSessions(\n\tsessionsRoot: string,\n\tretentionDays: number,\n\toptions: PruneOldSessionsOptions = {},\n): Promise<PruneOldSessionsResult> {\n\tconst deleted: string[] = [];\n\tif (!Number.isFinite(retentionDays) || retentionDays <= 0) {\n\t\treturn { deleted };\n\t}\n\tconst now = options.now ?? Date.now();\n\tconst cutoffMs = now - retentionDays * DAY_MS;\n\n\t// Flat layout (custom --session-dir).\n\tawait pruneDir(sessionsRoot, cutoffMs, options.excludeFile, deleted);\n\n\t// Project layout (<root>/<dir>/*.jsonl).\n\tlet subdirs: Dirent[];\n\ttry {\n\t\tsubdirs = await readdir(sessionsRoot, { withFileTypes: true });\n\t} catch {\n\t\treturn { deleted };\n\t}\n\tfor (const entry of subdirs) {\n\t\tif (entry.isDirectory()) {\n\t\t\tawait pruneDir(join(sessionsRoot, entry.name), cutoffMs, options.excludeFile, deleted);\n\t\t}\n\t}\n\treturn { deleted };\n}\n"]}
1
+ {"version":3,"file":"session-retention.js","sourceRoot":"","sources":["../../src/core/session-retention.ts"],"names":[],"mappings":"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","sourcesContent":["// lunr: session retention pruning (Phase 5 of lunr-ux plan).\n// Scans the sessions root (~/.lunr/agent/sessions/, layout: <root>/--<cwd>--/*.jsonl,\n// or a flat custom --session-dir) and deletes .jsonl session files older than the\n// configured retention window. The active session file is always excluded.\n\nimport type { Dirent } from \"node:fs\";\nimport { readdir, stat, unlink } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { SessionOwnership } from \"./session-ownership.ts\";\n\nexport interface PruneOldSessionsOptions {\n\t/** Absolute path of the active session file; never deleted. */\n\texcludeFile?: string;\n\t/** Reference timestamp in ms (defaults to Date.now()); injectable for tests. */\n\tnow?: number;\n}\n\nexport interface PruneOldSessionsResult {\n\t/** Paths of session files that were deleted. */\n\tdeleted: string[];\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nfunction sameFile(a: string, b: string): boolean {\n\tconst ra = resolve(a);\n\tconst rb = resolve(b);\n\t// Windows paths are case-insensitive.\n\treturn process.platform === \"win32\" ? ra.toLowerCase() === rb.toLowerCase() : ra === rb;\n}\n\nasync function pruneDir(\n\tdir: string,\n\tcutoffMs: number,\n\texcludeFile: string | undefined,\n\tdeleted: string[],\n): Promise<void> {\n\tlet entries: Dirent[];\n\ttry {\n\t\tentries = await readdir(dir, { withFileTypes: true });\n\t} catch {\n\t\treturn; // Missing or unreadable directory: nothing to prune.\n\t}\n\tfor (const entry of entries) {\n\t\tif (!entry.isFile() || !entry.name.endsWith(\".jsonl\")) continue;\n\t\tconst filePath = join(dir, entry.name);\n\t\tif (excludeFile && sameFile(filePath, excludeFile)) continue;\n\t\ttry {\n\t\t\tconst info = await stat(filePath);\n\t\t\tif (info.mtimeMs < cutoffMs) {\n\t\t\t\tconst ownership = new SessionOwnership(filePath);\n\t\t\t\ttry {\n\t\t\t\t\tif ((await stat(filePath)).mtimeMs < cutoffMs) {\n\t\t\t\t\t\tawait unlink(filePath);\n\t\t\t\t\t\tdeleted.push(filePath);\n\t\t\t\t\t}\n\t\t\t\t} finally {\n\t\t\t\t\townership.release();\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Per-file errors (stat/unlink races, permissions) must never break startup.\n\t\t}\n\t}\n}\n\n/**\n * Delete .jsonl session files older than `retentionDays` under `sessionsRoot`.\n * Covers both layouts: project subdirectories (<root>/--<cwd>--/*.jsonl) and flat\n * custom session dirs (<root>/*.jsonl). `retentionDays <= 0` keeps everything.\n */\nexport async function pruneOldSessions(\n\tsessionsRoot: string,\n\tretentionDays: number,\n\toptions: PruneOldSessionsOptions = {},\n): Promise<PruneOldSessionsResult> {\n\tconst deleted: string[] = [];\n\tif (!Number.isFinite(retentionDays) || retentionDays <= 0) {\n\t\treturn { deleted };\n\t}\n\tconst now = options.now ?? Date.now();\n\tconst cutoffMs = now - retentionDays * DAY_MS;\n\n\t// Flat layout (custom --session-dir).\n\tawait pruneDir(sessionsRoot, cutoffMs, options.excludeFile, deleted);\n\n\t// Project layout (<root>/<dir>/*.jsonl).\n\tlet subdirs: Dirent[];\n\ttry {\n\t\tsubdirs = await readdir(sessionsRoot, { withFileTypes: true });\n\t} catch {\n\t\treturn { deleted };\n\t}\n\tfor (const entry of subdirs) {\n\t\tif (entry.isDirectory()) {\n\t\t\tawait pruneDir(join(sessionsRoot, entry.name), cutoffMs, options.excludeFile, deleted);\n\t\t}\n\t}\n\treturn { deleted };\n}\n"]}
@@ -126,8 +126,11 @@ export interface Settings {
126
126
  modelTiers?: ModelTiersSettings;
127
127
  modelInstructions?: ModelInstructionsSettings;
128
128
  sessionRetentionDays?: number;
129
+ browserEnabled?: boolean;
130
+ browserAllowPrivateNetwork?: boolean;
129
131
  memoryEnabled?: boolean;
130
132
  memoryCharCap?: number;
133
+ todosEnabled?: boolean;
131
134
  footerMcp?: boolean;
132
135
  footerLsp?: boolean;
133
136
  footerContext?: boolean;
@@ -291,8 +294,12 @@ export declare class SettingsManager {
291
294
  getSessionRetentionDays(): number;
292
295
  setSessionRetentionDays(days: number): void;
293
296
  getMemoryCharCap(): number;
297
+ getBrowserEnabled(): boolean;
298
+ setBrowserEnabled(enabled: boolean): void;
294
299
  getMemoryEnabled(): boolean;
295
300
  setMemoryEnabled(enabled: boolean): void;
301
+ getTodosEnabled(): boolean;
302
+ setTodosEnabled(enabled: boolean): void;
296
303
  setMemoryCharCap(cap: number): void;
297
304
  getFooterMcp(): boolean;
298
305
  setFooterMcp(enabled: boolean): void;