@ashx-j/lunr 0.2.26 → 0.2.27

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 (639) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/LICENSE +22 -0
  3. package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -1
  4. package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
  5. package/dist/builtin-extensions/ashxj-thinking.js +1 -1
  6. package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
  7. package/dist/builtin-extensions/ashxj-tui.d.ts +11 -1
  8. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  9. package/dist/builtin-extensions/ashxj-tui.js +6 -10
  10. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  11. package/dist/builtin-extensions/lunr-cron.d.ts +4 -5
  12. package/dist/builtin-extensions/lunr-cron.d.ts.map +1 -1
  13. package/dist/builtin-extensions/lunr-cron.js +94 -108
  14. package/dist/builtin-extensions/lunr-cron.js.map +1 -1
  15. package/dist/builtin-extensions/lunr-local-providers/local-servers.d.ts.map +1 -1
  16. package/dist/builtin-extensions/lunr-local-providers/local-servers.js +3 -1
  17. package/dist/builtin-extensions/lunr-local-providers/local-servers.js.map +1 -1
  18. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.d.ts.map +1 -1
  19. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js +2 -2
  20. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js.map +1 -1
  21. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
  22. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +1 -1
  23. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
  24. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.d.ts.map +1 -1
  25. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js +1 -1
  26. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js.map +1 -1
  27. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  28. package/dist/builtin-extensions/pi-intercom/index.js +2 -2
  29. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  30. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts +1 -1
  31. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts.map +1 -1
  32. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js +1 -1
  33. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js.map +1 -1
  34. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
  35. package/dist/builtin-extensions/pi-lsp-extension/src/index.js +1 -15
  36. package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
  37. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts +6 -0
  38. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts.map +1 -1
  39. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js +187 -132
  40. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js.map +1 -1
  41. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts +8 -0
  42. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts.map +1 -1
  43. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js +142 -112
  44. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js.map +1 -1
  45. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts +12 -1
  46. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts.map +1 -1
  47. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js +14 -7
  48. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js.map +1 -1
  49. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts +11 -3
  50. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts.map +1 -1
  51. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js +67 -41
  52. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js.map +1 -1
  53. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts +4 -2
  54. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts.map +1 -1
  55. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js +3 -0
  56. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js.map +1 -1
  57. package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts +2 -1
  58. package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts.map +1 -1
  59. package/dist/builtin-extensions/pi-mcp-adapter/commands.js +6 -6
  60. package/dist/builtin-extensions/pi-mcp-adapter/commands.js.map +1 -1
  61. package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts +1 -1
  62. package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts.map +1 -1
  63. package/dist/builtin-extensions/pi-mcp-adapter/config.js +11 -5
  64. package/dist/builtin-extensions/pi-mcp-adapter/config.js.map +1 -1
  65. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -1
  66. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +2 -2
  67. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -1
  68. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.d.ts.map +1 -1
  69. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js +1 -1
  70. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js.map +1 -1
  71. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  72. package/dist/builtin-extensions/pi-mcp-adapter/index.js +48 -40
  73. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  74. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
  75. package/dist/builtin-extensions/pi-mcp-adapter/init.js +3 -1
  76. package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
  77. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts +12 -40
  78. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts.map +1 -1
  79. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js +166 -235
  80. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js.map +1 -1
  81. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts +5 -0
  82. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts.map +1 -1
  83. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js +43 -13
  84. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js.map +1 -1
  85. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts +14 -3
  86. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts.map +1 -1
  87. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js +73 -21
  88. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js.map +1 -1
  89. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.d.ts.map +1 -1
  90. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js +4 -4
  91. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js.map +1 -1
  92. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
  93. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +2 -2
  94. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
  95. package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts +2 -0
  96. package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts.map +1 -1
  97. package/dist/builtin-extensions/pi-mcp-adapter/state.js.map +1 -1
  98. package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts +1 -1
  99. package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts.map +1 -1
  100. package/dist/builtin-extensions/pi-ollama-cloud/index.js +1 -1
  101. package/dist/builtin-extensions/pi-ollama-cloud/index.js.map +1 -1
  102. package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts +11 -5
  103. package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts.map +1 -1
  104. package/dist/builtin-extensions/pi-ollama-cloud/models.js +12 -32
  105. package/dist/builtin-extensions/pi-ollama-cloud/models.js.map +1 -1
  106. package/dist/builtin-extensions/pi-prompt-template-model/index.d.ts.map +1 -1
  107. package/dist/builtin-extensions/pi-prompt-template-model/index.js +5 -3
  108. package/dist/builtin-extensions/pi-prompt-template-model/index.js.map +1 -1
  109. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts +2 -1
  110. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
  111. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +21 -12
  112. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
  113. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
  114. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +7 -24
  115. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
  116. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  117. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +39 -77
  118. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  119. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +1 -1
  120. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
  121. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +15 -31
  122. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
  123. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
  124. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +7 -2
  125. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
  126. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  127. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +10 -2
  128. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  129. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  130. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +8 -1
  131. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  132. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  133. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +106 -24
  134. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  135. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  136. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +25 -5
  137. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  138. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +1 -1
  139. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  140. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +1 -1
  141. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  142. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +7 -8
  143. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
  144. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js +60 -32
  145. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
  146. package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts +1 -1
  147. package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts.map +1 -1
  148. package/dist/builtin-extensions/pi-subagents/src/shared/utils.js +15 -5
  149. package/dist/builtin-extensions/pi-subagents/src/shared/utils.js.map +1 -1
  150. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  151. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +4 -3
  152. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  153. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +1 -1
  154. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  155. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +17 -8
  156. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  157. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
  158. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +3 -3
  159. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
  160. package/dist/builtin-extensions/pi-tps.d.ts.map +1 -1
  161. package/dist/builtin-extensions/pi-tps.js +20 -17
  162. package/dist/builtin-extensions/pi-tps.js.map +1 -1
  163. package/dist/builtin-extensions/pi-web-access/activity.d.ts +1 -0
  164. package/dist/builtin-extensions/pi-web-access/activity.d.ts.map +1 -1
  165. package/dist/builtin-extensions/pi-web-access/activity.js +27 -5
  166. package/dist/builtin-extensions/pi-web-access/activity.js.map +1 -1
  167. package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts +3 -0
  168. package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts.map +1 -0
  169. package/dist/builtin-extensions/pi-web-access/bounded-body.js +43 -0
  170. package/dist/builtin-extensions/pi-web-access/bounded-body.js.map +1 -0
  171. package/dist/builtin-extensions/pi-web-access/content-page.d.ts +24 -0
  172. package/dist/builtin-extensions/pi-web-access/content-page.d.ts.map +1 -0
  173. package/dist/builtin-extensions/pi-web-access/content-page.js +57 -0
  174. package/dist/builtin-extensions/pi-web-access/content-page.js.map +1 -0
  175. package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
  176. package/dist/builtin-extensions/pi-web-access/extract.js +7 -2
  177. package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
  178. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts +0 -1
  179. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
  180. package/dist/builtin-extensions/pi-web-access/github-extract.js +147 -36
  181. package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
  182. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  183. package/dist/builtin-extensions/pi-web-access/index.js +48 -73
  184. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  185. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +12 -4
  186. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -1
  187. package/dist/builtin-extensions/pi-web-access/session-cleanup.js +35 -12
  188. package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -1
  189. package/dist/builtin-extensions/pi-web-access/storage.d.ts +9 -6
  190. package/dist/builtin-extensions/pi-web-access/storage.d.ts.map +1 -1
  191. package/dist/builtin-extensions/pi-web-access/storage.js +36 -24
  192. package/dist/builtin-extensions/pi-web-access/storage.js.map +1 -1
  193. package/dist/builtin-extensions/simple-pi-memory.d.ts +1 -1
  194. package/dist/builtin-extensions/simple-pi-memory.d.ts.map +1 -1
  195. package/dist/builtin-extensions/simple-pi-memory.js +1 -1
  196. package/dist/builtin-extensions/simple-pi-memory.js.map +1 -1
  197. package/dist/cli/install-cli.d.ts.map +1 -1
  198. package/dist/cli/install-cli.js +38 -30
  199. package/dist/cli/install-cli.js.map +1 -1
  200. package/dist/core/agent-session-runtime.d.ts +13 -0
  201. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  202. package/dist/core/agent-session-runtime.js +75 -11
  203. package/dist/core/agent-session-runtime.js.map +1 -1
  204. package/dist/core/agent-session-services.d.ts +1 -0
  205. package/dist/core/agent-session-services.d.ts.map +1 -1
  206. package/dist/core/agent-session-services.js +1 -0
  207. package/dist/core/agent-session-services.js.map +1 -1
  208. package/dist/core/agent-session.d.ts +40 -6
  209. package/dist/core/agent-session.d.ts.map +1 -1
  210. package/dist/core/agent-session.js +309 -76
  211. package/dist/core/agent-session.js.map +1 -1
  212. package/dist/core/browser/runtime.d.ts +2 -0
  213. package/dist/core/browser/runtime.d.ts.map +1 -1
  214. package/dist/core/browser/runtime.js +80 -45
  215. package/dist/core/browser/runtime.js.map +1 -1
  216. package/dist/core/browser/setup.d.ts.map +1 -1
  217. package/dist/core/browser/setup.js +12 -1
  218. package/dist/core/browser/setup.js.map +1 -1
  219. package/dist/core/computer-use/adapter.d.ts.map +1 -1
  220. package/dist/core/computer-use/adapter.js +7 -2
  221. package/dist/core/computer-use/adapter.js.map +1 -1
  222. package/dist/core/computer-use/image.d.ts.map +1 -1
  223. package/dist/core/computer-use/image.js +17 -5
  224. package/dist/core/computer-use/image.js.map +1 -1
  225. package/dist/core/computer-use/schemas.d.ts.map +1 -1
  226. package/dist/core/computer-use/schemas.js +23 -6
  227. package/dist/core/computer-use/schemas.js.map +1 -1
  228. package/dist/core/computer-use/workflow.d.ts.map +1 -1
  229. package/dist/core/computer-use/workflow.js +459 -119
  230. package/dist/core/computer-use/workflow.js.map +1 -1
  231. package/dist/core/cron/jobs.d.ts +26 -8
  232. package/dist/core/cron/jobs.d.ts.map +1 -1
  233. package/dist/core/cron/jobs.js +357 -232
  234. package/dist/core/cron/jobs.js.map +1 -1
  235. package/dist/core/cron/origin-context.d.ts +1 -0
  236. package/dist/core/cron/origin-context.d.ts.map +1 -1
  237. package/dist/core/cron/origin-context.js.map +1 -1
  238. package/dist/core/cron/scheduler.d.ts +22 -17
  239. package/dist/core/cron/scheduler.d.ts.map +1 -1
  240. package/dist/core/cron/scheduler.js +153 -73
  241. package/dist/core/cron/scheduler.js.map +1 -1
  242. package/dist/core/extensions/index.d.ts +1 -1
  243. package/dist/core/extensions/index.d.ts.map +1 -1
  244. package/dist/core/extensions/index.js.map +1 -1
  245. package/dist/core/extensions/runner.d.ts +1 -0
  246. package/dist/core/extensions/runner.d.ts.map +1 -1
  247. package/dist/core/extensions/runner.js +8 -0
  248. package/dist/core/extensions/runner.js.map +1 -1
  249. package/dist/core/extensions/types.d.ts +8 -0
  250. package/dist/core/extensions/types.d.ts.map +1 -1
  251. package/dist/core/extensions/types.js.map +1 -1
  252. package/dist/core/footer-data-provider.d.ts +4 -0
  253. package/dist/core/footer-data-provider.d.ts.map +1 -1
  254. package/dist/core/footer-data-provider.js +22 -1
  255. package/dist/core/footer-data-provider.js.map +1 -1
  256. package/dist/core/large-subagent-launch.d.ts +1 -1
  257. package/dist/core/large-subagent-launch.d.ts.map +1 -1
  258. package/dist/core/large-subagent-launch.js +7 -7
  259. package/dist/core/large-subagent-launch.js.map +1 -1
  260. package/dist/core/model-registry.d.ts +2 -0
  261. package/dist/core/model-registry.d.ts.map +1 -1
  262. package/dist/core/model-registry.js +5 -0
  263. package/dist/core/model-registry.js.map +1 -1
  264. package/dist/core/model-runtime.d.ts +4 -1
  265. package/dist/core/model-runtime.d.ts.map +1 -1
  266. package/dist/core/model-runtime.js +40 -4
  267. package/dist/core/model-runtime.js.map +1 -1
  268. package/dist/core/package-manager.d.ts.map +1 -1
  269. package/dist/core/package-manager.js.map +1 -1
  270. package/dist/core/permissions.d.ts +3 -3
  271. package/dist/core/permissions.d.ts.map +1 -1
  272. package/dist/core/permissions.js +11 -35
  273. package/dist/core/permissions.js.map +1 -1
  274. package/dist/core/plan-mode.d.ts +5 -13
  275. package/dist/core/plan-mode.d.ts.map +1 -1
  276. package/dist/core/plan-mode.js +126 -116
  277. package/dist/core/plan-mode.js.map +1 -1
  278. package/dist/core/project-trust.d.ts.map +1 -1
  279. package/dist/core/project-trust.js +1 -1
  280. package/dist/core/project-trust.js.map +1 -1
  281. package/dist/core/prompt-resource-bridge.d.ts +12 -0
  282. package/dist/core/prompt-resource-bridge.d.ts.map +1 -0
  283. package/dist/core/prompt-resource-bridge.js +9 -0
  284. package/dist/core/prompt-resource-bridge.js.map +1 -0
  285. package/dist/core/protected-targets.d.ts +6 -0
  286. package/dist/core/protected-targets.d.ts.map +1 -0
  287. package/dist/core/protected-targets.js +45 -0
  288. package/dist/core/protected-targets.js.map +1 -0
  289. package/dist/core/resource-loader.d.ts.map +1 -1
  290. package/dist/core/resource-loader.js +7 -0
  291. package/dist/core/resource-loader.js.map +1 -1
  292. package/dist/core/rollback.d.ts +19 -3
  293. package/dist/core/rollback.d.ts.map +1 -1
  294. package/dist/core/rollback.js +172 -56
  295. package/dist/core/rollback.js.map +1 -1
  296. package/dist/core/runtime-credentials.d.ts +3 -0
  297. package/dist/core/runtime-credentials.d.ts.map +1 -1
  298. package/dist/core/runtime-credentials.js +14 -1
  299. package/dist/core/runtime-credentials.js.map +1 -1
  300. package/dist/core/sdk.d.ts +3 -0
  301. package/dist/core/sdk.d.ts.map +1 -1
  302. package/dist/core/sdk.js +1 -0
  303. package/dist/core/sdk.js.map +1 -1
  304. package/dist/core/session-manager.d.ts +6 -0
  305. package/dist/core/session-manager.d.ts.map +1 -1
  306. package/dist/core/session-manager.js +95 -32
  307. package/dist/core/session-manager.js.map +1 -1
  308. package/dist/core/session-ownership.d.ts.map +1 -1
  309. package/dist/core/session-ownership.js +8 -3
  310. package/dist/core/session-ownership.js.map +1 -1
  311. package/dist/core/session-retention.d.ts.map +1 -1
  312. package/dist/core/session-retention.js +18 -7
  313. package/dist/core/session-retention.js.map +1 -1
  314. package/dist/core/session-startup-settings.d.ts +10 -0
  315. package/dist/core/session-startup-settings.d.ts.map +1 -0
  316. package/dist/core/session-startup-settings.js +70 -0
  317. package/dist/core/session-startup-settings.js.map +1 -0
  318. package/dist/core/subscriptions.d.ts +16 -7
  319. package/dist/core/subscriptions.d.ts.map +1 -1
  320. package/dist/core/subscriptions.js +96 -55
  321. package/dist/core/subscriptions.js.map +1 -1
  322. package/dist/core/trust-manager.d.ts +2 -1
  323. package/dist/core/trust-manager.d.ts.map +1 -1
  324. package/dist/core/trust-manager.js +6 -1
  325. package/dist/core/trust-manager.js.map +1 -1
  326. package/dist/core/update-check.d.ts.map +1 -1
  327. package/dist/core/update-check.js.map +1 -1
  328. package/dist/core/usage-adapters/kimi-coding.d.ts +2 -2
  329. package/dist/core/usage-adapters/kimi-coding.d.ts.map +1 -1
  330. package/dist/core/usage-adapters/kimi-coding.js +2 -2
  331. package/dist/core/usage-adapters/kimi-coding.js.map +1 -1
  332. package/dist/core/usage-adapters/openai-codex.d.ts +3 -2
  333. package/dist/core/usage-adapters/openai-codex.d.ts.map +1 -1
  334. package/dist/core/usage-adapters/openai-codex.js +3 -3
  335. package/dist/core/usage-adapters/openai-codex.js.map +1 -1
  336. package/dist/core/usage-adapters/xai.d.ts +2 -2
  337. package/dist/core/usage-adapters/xai.d.ts.map +1 -1
  338. package/dist/core/usage-adapters/xai.js +3 -3
  339. package/dist/core/usage-adapters/xai.js.map +1 -1
  340. package/dist/core/usage-adapters/zai.d.ts +2 -2
  341. package/dist/core/usage-adapters/zai.d.ts.map +1 -1
  342. package/dist/core/usage-adapters/zai.js +2 -2
  343. package/dist/core/usage-adapters/zai.js.map +1 -1
  344. package/dist/core/usage-service.d.ts +9 -2
  345. package/dist/core/usage-service.d.ts.map +1 -1
  346. package/dist/core/usage-service.js +95 -50
  347. package/dist/core/usage-service.js.map +1 -1
  348. package/dist/gateway/agent-bridge.d.ts +9 -1
  349. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  350. package/dist/gateway/agent-bridge.js +91 -37
  351. package/dist/gateway/agent-bridge.js.map +1 -1
  352. package/dist/gateway/buttons.d.ts +8 -1
  353. package/dist/gateway/buttons.d.ts.map +1 -1
  354. package/dist/gateway/buttons.js +76 -18
  355. package/dist/gateway/buttons.js.map +1 -1
  356. package/dist/gateway/commands.d.ts +1 -0
  357. package/dist/gateway/commands.d.ts.map +1 -1
  358. package/dist/gateway/commands.js +10 -4
  359. package/dist/gateway/commands.js.map +1 -1
  360. package/dist/gateway/cron.d.ts +12 -11
  361. package/dist/gateway/cron.d.ts.map +1 -1
  362. package/dist/gateway/cron.js +65 -56
  363. package/dist/gateway/cron.js.map +1 -1
  364. package/dist/gateway/index.d.ts.map +1 -1
  365. package/dist/gateway/index.js +2 -1
  366. package/dist/gateway/index.js.map +1 -1
  367. package/dist/gateway/mobile-commands.d.ts +1 -0
  368. package/dist/gateway/mobile-commands.d.ts.map +1 -1
  369. package/dist/gateway/mobile-commands.js +56 -14
  370. package/dist/gateway/mobile-commands.js.map +1 -1
  371. package/dist/gateway/presenter.d.ts +12 -2
  372. package/dist/gateway/presenter.d.ts.map +1 -1
  373. package/dist/gateway/presenter.js +73 -38
  374. package/dist/gateway/presenter.js.map +1 -1
  375. package/dist/gateway/router.d.ts +2 -2
  376. package/dist/gateway/router.d.ts.map +1 -1
  377. package/dist/gateway/router.js +17 -2
  378. package/dist/gateway/router.js.map +1 -1
  379. package/dist/gateway/service.d.ts +2 -0
  380. package/dist/gateway/service.d.ts.map +1 -1
  381. package/dist/gateway/service.js +153 -0
  382. package/dist/gateway/service.js.map +1 -1
  383. package/dist/main.d.ts.map +1 -1
  384. package/dist/main.js +86 -33
  385. package/dist/main.js.map +1 -1
  386. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  387. package/dist/modes/interactive/components/assistant-message.js +6 -4
  388. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  389. package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -1
  390. package/dist/modes/interactive/components/copyable-text.js +3 -2
  391. package/dist/modes/interactive/components/copyable-text.js.map +1 -1
  392. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  393. package/dist/modes/interactive/components/extension-editor.js +1 -1
  394. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  395. package/dist/modes/interactive/interactive-mode.d.ts +2 -2
  396. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  397. package/dist/modes/interactive/interactive-mode.js +96 -109
  398. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  399. package/dist/modes/interactive/smooth-streaming.d.ts.map +1 -1
  400. package/dist/modes/interactive/smooth-streaming.js.map +1 -1
  401. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  402. package/dist/modes/rpc/rpc-mode.js +2 -1
  403. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  404. package/dist/node-runtime/{adapter-VFG7WNPX.js → adapter-247RTYLS.js} +4 -5
  405. package/dist/node-runtime/agent-session-services-KDMSPQDY.js +53 -0
  406. package/dist/node-runtime/{brave-UWDA3I22.js → brave-2AFFAXNN.js} +1 -1
  407. package/dist/node-runtime/{builtin-extensions-I2HIFEMY.js → builtin-extensions-OX6KELNX.js} +8 -7
  408. package/dist/node-runtime/{chunk-QH6YL7VK.js → chunk-252ZVPPF.js} +3 -3
  409. package/dist/node-runtime/{chunk-PCEW76PM.js → chunk-2OIPYKLZ.js} +6 -6
  410. package/dist/node-runtime/{chunk-XBWPBZBN.js → chunk-2SWW7KMW.js} +1 -1
  411. package/dist/node-runtime/{chunk-UQUCFAJ3.js → chunk-2VIW3IMF.js} +40 -7
  412. package/dist/node-runtime/{chunk-UOEDI7RP.js → chunk-4KNKQGHM.js} +2 -2
  413. package/dist/node-runtime/{chunk-FQMM2EZ2.js → chunk-64XTQNLA.js} +29 -7
  414. package/dist/node-runtime/{chunk-SPVDBUOS.js → chunk-6O3IW3IA.js} +2 -2
  415. package/dist/node-runtime/{chunk-5ZQXRPMC.js → chunk-6ZZHGUSA.js} +2 -2
  416. package/dist/node-runtime/chunk-A2WO6WIN.js +1197 -0
  417. package/dist/node-runtime/{chunk-WIF24I7G.js → chunk-APVM5NEU.js} +149 -144
  418. package/dist/node-runtime/{chunk-RCR3XAQY.js → chunk-AYHH7YSD.js} +177 -144
  419. package/dist/node-runtime/{chunk-LWYIVUGV.js → chunk-B2IBAXNX.js} +48 -31
  420. package/dist/node-runtime/{chunk-M3LZLQW2.js → chunk-BDRGN3L2.js} +1 -0
  421. package/dist/node-runtime/{chunk-GJ2RDBRL.js → chunk-BYC6RKCN.js} +4 -2
  422. package/dist/node-runtime/{chunk-UVWCDQYF.js → chunk-C3P6Q3B2.js} +455 -278
  423. package/dist/node-runtime/{chunk-SN2KSMPQ.js → chunk-DQSCFU7R.js} +13 -7
  424. package/dist/node-runtime/{chunk-4SBQAI4T.js → chunk-EBLAZVSA.js} +2058 -73
  425. package/dist/node-runtime/{chunk-2KIPT4HJ.js → chunk-EPR2F3GU.js} +68 -20
  426. package/dist/node-runtime/{chunk-CSFI6YXL.js → chunk-ES6PBSIE.js} +1 -1
  427. package/dist/node-runtime/{chunk-IF24A3FH.js → chunk-EVM653DD.js} +4 -4
  428. package/dist/node-runtime/{chunk-HTFRRDSF.js → chunk-F2SMQ6ES.js} +3 -2
  429. package/dist/node-runtime/chunk-F2V2F4ZG.js +114 -0
  430. package/dist/node-runtime/{chunk-IKU6Y7DL.js → chunk-FE3WZI7F.js} +9 -6
  431. package/dist/node-runtime/{chunk-GYIXXQAO.js → chunk-FIRA54AC.js} +2 -5
  432. package/dist/node-runtime/{chunk-6VYZ5UFP.js → chunk-FLGEEH27.js} +1 -1
  433. package/dist/node-runtime/{chunk-5EFIU3OM.js → chunk-FTKEZL27.js} +1 -1
  434. package/dist/node-runtime/{chunk-RGQAEOM5.js → chunk-FYIFPFXE.js} +23 -6
  435. package/dist/node-runtime/{chunk-HMBGROQK.js → chunk-GLDXBBL6.js} +3 -3
  436. package/dist/node-runtime/{chunk-KWA4OC2J.js → chunk-H6YBCWKG.js} +1 -1
  437. package/dist/node-runtime/{chunk-2MI5OPMN.js → chunk-HNNHHJAB.js} +68 -50
  438. package/dist/node-runtime/{chunk-I74LN5JG.js → chunk-HUD2RFJW.js} +2 -2
  439. package/dist/node-runtime/{chunk-I54LGHWM.js → chunk-I2H5QMWW.js} +3 -3
  440. package/dist/node-runtime/{chunk-XHIRAZ26.js → chunk-IAZSK7KK.js} +1 -1
  441. package/dist/node-runtime/{chunk-X3PGBLQ7.js → chunk-IHHTWSXN.js} +9 -9
  442. package/dist/node-runtime/{chunk-DAPBPCBP.js → chunk-IPP5BIV5.js} +25 -3
  443. package/dist/node-runtime/{chunk-QFWG2RVL.js → chunk-IXG6F4NT.js} +11 -0
  444. package/dist/node-runtime/{chunk-RDDAZOMU.js → chunk-JL4HYQXK.js} +1 -1
  445. package/dist/node-runtime/{chunk-CDVHZOOK.js → chunk-JQYNHAKX.js} +1 -1
  446. package/dist/node-runtime/{chunk-L24TPBS4.js → chunk-JWEVT363.js} +37 -29
  447. package/dist/node-runtime/{chunk-2HMIRK7W.js → chunk-LHV3V67B.js} +5 -5
  448. package/dist/node-runtime/{chunk-UAEOTO52.js → chunk-MNQXDFPV.js} +6 -2
  449. package/dist/node-runtime/{chunk-T4DA4XE7.js → chunk-MQPKUHRN.js} +162 -82
  450. package/dist/node-runtime/{chunk-MPKSOJBT.js → chunk-NHATCSOI.js} +4 -7
  451. package/dist/node-runtime/{chunk-RMQZU2YU.js → chunk-NNNR3QIY.js} +1 -1
  452. package/dist/node-runtime/{chunk-RWTKOC3B.js → chunk-QBTJG3UM.js} +1 -1
  453. package/dist/node-runtime/{chunk-P7XBVXGT.js → chunk-QNVMKNNN.js} +18 -14
  454. package/dist/node-runtime/{chunk-GS42T6MX.js → chunk-QW3AAHWN.js} +1 -1
  455. package/dist/node-runtime/{chunk-DVQSHCVP.js → chunk-R4WSB2MQ.js} +5 -5
  456. package/dist/node-runtime/{chunk-B4HP6ZWM.js → chunk-RHCGYWO7.js} +1 -1
  457. package/dist/node-runtime/{chunk-2CFDTH5B.js → chunk-RLGY2QIL.js} +45 -59
  458. package/dist/node-runtime/{chunk-KKUTQQV7.js → chunk-RYRGL7P4.js} +1 -1
  459. package/dist/node-runtime/{chunk-5Q4A37RB.js → chunk-TCT6PCUR.js} +32 -11
  460. package/dist/node-runtime/{chunk-D5UCKPBQ.js → chunk-UBWW2PID.js} +1 -1
  461. package/dist/node-runtime/{chunk-E75WFZ33.js → chunk-UNUZICC4.js} +3 -3
  462. package/dist/node-runtime/{chunk-RAK2QA2B.js → chunk-UYRKUKFE.js} +4 -4
  463. package/dist/node-runtime/{chunk-LWJXTA6Z.js → chunk-VSUEAI7O.js} +1377 -45
  464. package/dist/node-runtime/{chunk-NAY6UUQZ.js → chunk-WDIVLMOH.js} +1 -1
  465. package/dist/node-runtime/{chunk-E24EO34J.js → chunk-WPXUR3HE.js} +1 -1
  466. package/dist/node-runtime/{chunk-SLVOAQOY.js → chunk-WXYNALHD.js} +113 -1
  467. package/dist/node-runtime/{chunk-KJ6DWS3K.js → chunk-XEOCUEUJ.js} +121 -60
  468. package/dist/node-runtime/chunk-YD3IZAZ7.js +47 -0
  469. package/dist/node-runtime/chunk-YSB6URMT.js +41 -0
  470. package/dist/node-runtime/{chunk-LJTIVM7I.js → chunk-ZDJUR45D.js} +427 -126
  471. package/dist/node-runtime/{chunk-YWOJIGFY.js → chunk-ZEVFBFNF.js} +95 -142
  472. package/dist/node-runtime/{chunk-5B6VKFEV.js → chunk-ZIQUS5QO.js} +1 -1
  473. package/dist/node-runtime/cli-runtime.js +4 -4
  474. package/dist/node-runtime/{command-FSBU2EVZ.js → command-3HMSY6W2.js} +5 -5
  475. package/dist/node-runtime/{commands-EMBQQVVT.js → commands-D6A6H4TS.js} +11 -18
  476. package/dist/node-runtime/{commands-NAAL7KNT.js → commands-OCSSEEWJ.js} +16 -16
  477. package/dist/node-runtime/{config-QDD5PUE2.js → config-CU7M7BTK.js} +1 -1
  478. package/dist/node-runtime/{config-D4QUPAHX.js → config-DS7XLMEM.js} +2 -2
  479. package/dist/node-runtime/{direct-tool-executor-4D7UXYU4.js → direct-tool-executor-2QJXVQD2.js} +6 -11
  480. package/dist/node-runtime/{exa-LL64QZR2.js → exa-6VBZNPGE.js} +1 -1
  481. package/dist/node-runtime/{export-html-VM4J2MNR.js → export-html-BRWF5AHI.js} +4 -4
  482. package/dist/node-runtime/{extension-input-E7BJZ35H.js → extension-input-VBBMX7YV.js} +5 -5
  483. package/dist/node-runtime/{extension-selector-WU42XDTU.js → extension-selector-T5AOG5XB.js} +5 -5
  484. package/dist/node-runtime/{extract-EQJE7FZZ.js → extract-BFX2N35A.js} +3 -3
  485. package/dist/node-runtime/{gateway-DQM333YV.js → gateway-6623C2U3.js} +51 -42
  486. package/dist/node-runtime/{gemini-search-35OCRFLN.js → gemini-search-C66QHDT6.js} +2 -2
  487. package/dist/node-runtime/{gemini-url-context-UQY3PHHW.js → gemini-url-context-T7DEK73R.js} +3 -3
  488. package/dist/node-runtime/{github-extract-F64RZOEA.js → github-extract-HOGE3D6F.js} +107 -38
  489. package/dist/node-runtime/{goal-NJEE5CTU.js → goal-AIHEDUYA.js} +5 -5
  490. package/dist/node-runtime/index.js +50 -48
  491. package/dist/node-runtime/{init-P5AUV77I.js → init-JBQJIPYI.js} +3 -6
  492. package/dist/node-runtime/{install-cli-NN4YAU44.js → install-cli-INGHIVBY.js} +30 -25
  493. package/dist/node-runtime/interactive-mode-FM5DNUSW.js +74 -0
  494. package/dist/node-runtime/{interactive-view-NGFAMHPW.js → interactive-view-K33PM4OS.js} +8 -8
  495. package/dist/node-runtime/{lsp-manager-3ASUSO4T.js → lsp-manager-S554V5HR.js} +240 -155
  496. package/dist/node-runtime/{lunr-browser-IR7TL3J7.js → lunr-browser-H4FDOR3C.js} +7 -7
  497. package/dist/node-runtime/{lunr-computer-use-Y23CCDIJ.js → lunr-computer-use-VDP2QNRQ.js} +9 -9
  498. package/dist/node-runtime/{lunr-cron-USHC4LXH.js → lunr-cron-LKVA5CZZ.js} +93 -80
  499. package/dist/node-runtime/main.js +42 -41
  500. package/dist/node-runtime/{mobile-commands-O5LCHL32.js → mobile-commands-XT3NQXLD.js} +12 -12
  501. package/dist/node-runtime/{model-runtime-OO5HFLWE.js → model-runtime-MZ2JMDV4.js} +4 -4
  502. package/dist/node-runtime/{openai-search-B3MSNCQA.js → openai-search-K72LJDYN.js} +1 -1
  503. package/dist/node-runtime/{package-manager-cli-Q7BL6KZO.js → package-manager-cli-CYM262SI.js} +20 -20
  504. package/dist/node-runtime/{parallel-AI2MNSCU.js → parallel-X724NCNU.js} +1 -1
  505. package/dist/node-runtime/{perplexity-QVJW3I35.js → perplexity-RDHQHVMK.js} +2 -2
  506. package/dist/node-runtime/{pi-intercom-QM53RLTS.js → pi-intercom-NHHEPBMI.js} +2 -2
  507. package/dist/node-runtime/{pi-mcp-adapter-3PHF4KZ4.js → pi-mcp-adapter-PP3GQJQ2.js} +98 -94
  508. package/dist/node-runtime/{pi-ollama-cloud-2F3Y2QNM.js → pi-ollama-cloud-4MNWIMFN.js} +11 -24
  509. package/dist/node-runtime/{pi-prompt-template-model-QWTCGLJU.js → pi-prompt-template-model-FTGELLS5.js} +32 -36
  510. package/dist/node-runtime/{pi-subagents-7IBSSGEW.js → pi-subagents-LT3CTO4E.js} +98 -106
  511. package/dist/node-runtime/{pi-web-access-WTGMNZ32.js → pi-web-access-Z3LP246C.js} +144 -108
  512. package/dist/node-runtime/{print-mode-XQ76CYMT.js → print-mode-2XHN5SUA.js} +3 -3
  513. package/dist/node-runtime/{process-registry-4FAKZQOL.js → process-registry-Q4QWIU33.js} +3 -3
  514. package/dist/node-runtime/{proxy-modes-5FAPSZEZ.js → proxy-modes-VEGC6QG5.js} +8 -15
  515. package/dist/node-runtime/rpc-entry.js +42 -41
  516. package/dist/node-runtime/{rpc-mode-O3XV4SID.js → rpc-mode-32DHJPEJ.js} +4 -4
  517. package/dist/node-runtime/{runtime-4VA6JKNF.js → runtime-EDUUGAQD.js} +56 -46
  518. package/dist/node-runtime/{runtime-EFPPD2UW.js → runtime-UGXM4NPQ.js} +2 -2
  519. package/dist/node-runtime/{runtime-bridges-7WVCLI76.js → runtime-bridges-DNKMNJCF.js} +7 -7
  520. package/dist/node-runtime/{service-MDQIPQ26.js → service-IHLGFLBT.js} +6 -4
  521. package/dist/node-runtime/{session-handoff-GWARVEWT.js → session-handoff-LNSPDTKY.js} +4 -4
  522. package/dist/node-runtime/{session-manager-JB5J6XBN.js → session-manager-YIFIAVGC.js} +3 -3
  523. package/dist/node-runtime/{session-selector-GIM4DHQ2.js → session-selector-I73U3EIO.js} +7 -7
  524. package/dist/node-runtime/{settings-manager-DJDM5AHM.js → settings-manager-P2TKGYTR.js} +5 -5
  525. package/dist/node-runtime/{setup-JBKOLJ6F.js → setup-H7CCELIL.js} +15 -1
  526. package/dist/node-runtime/{setup-PFBWRNUI.js → setup-OLQ4GXWS.js} +17 -17
  527. package/dist/node-runtime/{src-IVPNZ2BX.js → src-6RV4PXKJ.js} +64 -36
  528. package/dist/node-runtime/{subagent-executor-LPZ4BHWE.js → subagent-executor-Q5F7DBVM.js} +119 -58
  529. package/dist/node-runtime/{tavily-WEZFVFP7.js → tavily-KZBFYQB6.js} +1 -1
  530. package/dist/node-runtime/{theme-UOO5RVFN.js → theme-YLVZKKZD.js} +2 -2
  531. package/dist/node-runtime/{trust-manager-MMISNCYO.js → trust-manager-ZCU76D23.js} +2 -2
  532. package/dist/node-runtime/{update-cli-HNMOTNGX.js → update-cli-F3XXJANQ.js} +6 -6
  533. package/dist/node-runtime/{usage-service-LFB2SWYV.js → usage-service-CPAGBED5.js} +1 -1
  534. package/dist/node-runtime/{video-extract-OOZHR7SU.js → video-extract-UPKYIBW3.js} +3 -3
  535. package/dist/node-runtime/{workflow-OHPBEFO4.js → workflow-ICDI4N3J.js} +208 -78
  536. package/dist/node-runtime/{youtube-extract-FNPAUNHU.js → youtube-extract-77NT7FWH.js} +4 -4
  537. package/dist/utils/clipboard-image.d.ts.map +1 -1
  538. package/dist/utils/clipboard-image.js.map +1 -1
  539. package/dist/utils/exif-orientation.d.ts.map +1 -1
  540. package/dist/utils/exif-orientation.js +25 -10
  541. package/dist/utils/exif-orientation.js.map +1 -1
  542. package/dist/utils/image-resize-core.d.ts.map +1 -1
  543. package/dist/utils/image-resize-core.js +2 -0
  544. package/dist/utils/image-resize-core.js.map +1 -1
  545. package/dist/utils/paths.d.ts +4 -0
  546. package/dist/utils/paths.d.ts.map +1 -1
  547. package/dist/utils/paths.js +33 -2
  548. package/dist/utils/paths.js.map +1 -1
  549. package/dist/utils/sanitize-terminal-text.d.ts +7 -0
  550. package/dist/utils/sanitize-terminal-text.d.ts.map +1 -0
  551. package/dist/utils/sanitize-terminal-text.js +67 -0
  552. package/dist/utils/sanitize-terminal-text.js.map +1 -0
  553. package/docs/browser.md +1 -1
  554. package/docs/custom-provider.md +3 -3
  555. package/docs/extensions.md +8 -4
  556. package/docs/features.md +15 -7
  557. package/docs/keybindings.md +1 -1
  558. package/docs/models.md +5 -5
  559. package/docs/packages.md +1 -1
  560. package/docs/providers.md +2 -2
  561. package/docs/rpc.md +7 -7
  562. package/docs/security.md +10 -5
  563. package/docs/sessions.md +2 -2
  564. package/docs/skills.md +1 -1
  565. package/docs/terminal-setup.md +7 -7
  566. package/docs/themes.md +1 -1
  567. package/docs/usage.md +1 -1
  568. package/examples/extensions/auto-commit-on-exit.ts +1 -1
  569. package/examples/extensions/bash-spawn-hook.ts +1 -1
  570. package/examples/extensions/built-in-tool-renderer.ts +1 -1
  571. package/examples/extensions/claude-rules.ts +1 -1
  572. package/examples/extensions/commands.ts +1 -1
  573. package/examples/extensions/custom-compaction.ts +1 -1
  574. package/examples/extensions/custom-provider-anthropic/index.ts +3 -3
  575. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  576. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  577. package/examples/extensions/custom-provider-gitlab-duo/index.ts +1 -1
  578. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  579. package/examples/extensions/doom-overlay/index.ts +1 -1
  580. package/examples/extensions/git-merge-and-resolve.ts +2 -2
  581. package/examples/extensions/gondolin/index.ts +1 -1
  582. package/examples/extensions/gondolin/package-lock.json +2 -2
  583. package/examples/extensions/gondolin/package.json +1 -1
  584. package/examples/extensions/hidden-thinking-label.ts +1 -1
  585. package/examples/extensions/inline-bash.ts +2 -2
  586. package/examples/extensions/input-transform-streaming.ts +2 -2
  587. package/examples/extensions/input-transform.ts +2 -2
  588. package/examples/extensions/interactive-shell.ts +1 -1
  589. package/examples/extensions/kimi-deferred-tools.ts +1 -1
  590. package/examples/extensions/mac-system-theme.ts +1 -1
  591. package/examples/extensions/minimal-mode.ts +1 -1
  592. package/examples/extensions/modal-editor.ts +1 -1
  593. package/examples/extensions/model-status.ts +1 -1
  594. package/examples/extensions/notify.ts +3 -3
  595. package/examples/extensions/overlay-qa-tests.ts +1 -1
  596. package/examples/extensions/overlay-test.ts +1 -1
  597. package/examples/extensions/pirate.ts +1 -1
  598. package/examples/extensions/preset.ts +3 -3
  599. package/examples/extensions/project-trust.ts +4 -4
  600. package/examples/extensions/prompt-customizer.ts +1 -1
  601. package/examples/extensions/rainbow-editor.ts +1 -1
  602. package/examples/extensions/rpc-demo.ts +1 -1
  603. package/examples/extensions/sandbox/index.ts +7 -7
  604. package/examples/extensions/sandbox/package-lock.json +2 -2
  605. package/examples/extensions/sandbox/package.json +1 -1
  606. package/examples/extensions/shutdown-command.ts +5 -5
  607. package/examples/extensions/ssh.ts +2 -2
  608. package/examples/extensions/subagent/README.md +3 -3
  609. package/examples/extensions/subagent/index.ts +2 -2
  610. package/examples/extensions/titlebar-spinner.ts +1 -1
  611. package/examples/extensions/tool-override.ts +1 -1
  612. package/examples/extensions/tools.ts +1 -1
  613. package/examples/extensions/with-deps/package-lock.json +2 -2
  614. package/examples/extensions/with-deps/package.json +1 -1
  615. package/examples/extensions/working-indicator.ts +1 -1
  616. package/examples/extensions/working-message-test.ts +1 -1
  617. package/examples/sdk/01-minimal.ts +1 -1
  618. package/examples/sdk/03-custom-prompt.ts +1 -1
  619. package/examples/sdk/04-skills.ts +1 -1
  620. package/examples/sdk/06-extensions.ts +2 -2
  621. package/examples/sdk/08-prompt-templates.ts +1 -1
  622. package/install-lock/package-lock.json +24 -24
  623. package/install-lock/package.json +2 -2
  624. package/npm-shrinkwrap.json +60 -24
  625. package/package.json +9 -9
  626. package/dist/modes/interactive/components/exit-card.d.ts +0 -22
  627. package/dist/modes/interactive/components/exit-card.d.ts.map +0 -1
  628. package/dist/modes/interactive/components/exit-card.js +0 -69
  629. package/dist/modes/interactive/components/exit-card.js.map +0 -1
  630. package/dist/node-runtime/agent-session-services-5YXS2PLF.js +0 -51
  631. package/dist/node-runtime/chunk-2IDTZAG5.js +0 -1415
  632. package/dist/node-runtime/chunk-3MISGG4S.js +0 -769
  633. package/dist/node-runtime/chunk-4HXHDDCF.js +0 -16
  634. package/dist/node-runtime/chunk-5B5QN3ZQ.js +0 -356
  635. package/dist/node-runtime/chunk-7IQGBKBJ.js +0 -2033
  636. package/dist/node-runtime/chunk-AUXVGBO4.js +0 -19
  637. package/dist/node-runtime/chunk-PTFBPO3C.js +0 -50
  638. package/dist/node-runtime/interactive-mode-YOHZVMKX.js +0 -74
  639. package/dist/node-runtime/mcp-auth-flow-QVLFVLEO.js +0 -33
@@ -1,6 +1,14 @@
1
- /** Lightweight session teardown hooks. Heavy modules register on first load. */
2
- type Cleanup = () => void;
3
- export declare function registerSessionCleanup(fn: Cleanup): void;
4
- export declare function runSessionCleanups(): void;
1
+ import { ActivityMonitor } from "./activity.ts";
2
+ type Cleanup = () => void | Promise<void>;
3
+ /** Heavy modules acquire resources inside the calling factory's async scope. */
4
+ export declare function createWebSession(): {
5
+ activity: ActivityMonitor;
6
+ cleanups: Set<Cleanup>;
7
+ closed: boolean;
8
+ };
9
+ export type WebSession = ReturnType<typeof createWebSession>;
10
+ export declare function getWebSession(): WebSession | undefined;
11
+ export declare function runWithWebSession<T>(session: WebSession, fn: () => T): T;
12
+ export declare function runSessionCleanups(session: WebSession): Promise<void>;
5
13
  export {};
6
14
  //# sourceMappingURL=session-cleanup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-cleanup.d.ts","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/session-cleanup.ts"],"names":[],"mappings":"AACA,gFAAgF;AAEhF,KAAK,OAAO,GAAG,MAAM,IAAI,CAAC;AAI1B,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAExD;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAOzC","sourcesContent":["// @ts-nocheck\n/** Lightweight session teardown hooks. Heavy modules register on first load. */\n\ntype Cleanup = () => void;\n\nconst cleanups: Cleanup[] = [];\n\nexport function registerSessionCleanup(fn: Cleanup): void {\n\tif (!cleanups.includes(fn)) cleanups.push(fn);\n}\n\nexport function runSessionCleanups(): void {\n\tfor (const fn of cleanups) {\n\t\ttry {\n\t\t\tfn();\n\t\t} catch {\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"session-cleanup.d.ts","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/session-cleanup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAmB,MAAM,eAAe,CAAC;AAEjE,KAAK,OAAO,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1C,gFAAgF;AAChF,wBAAgB,gBAAgB;;;;EAM/B;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAI7D,wBAAgB,aAAa,IAAI,UAAU,GAAG,SAAS,CAEtD;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAExE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBrE","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { ActivityMonitor, runWithActivity } from \"./activity.ts\";\n\ntype Cleanup = () => void | Promise<void>;\n\n/** Heavy modules acquire resources inside the calling factory's async scope. */\nexport function createWebSession() {\n\treturn {\n\t\tactivity: new ActivityMonitor(),\n\t\tcleanups: new Set<Cleanup>(),\n\t\tclosed: false,\n\t};\n}\n\nexport type WebSession = ReturnType<typeof createWebSession>;\nconst sessionScope = new AsyncLocalStorage<WebSession>();\nconst pendingCleanups = new WeakMap<WebSession, Promise<void>>();\n\nexport function getWebSession(): WebSession | undefined {\n\treturn sessionScope.getStore();\n}\n\nexport function runWithWebSession<T>(session: WebSession, fn: () => T): T {\n\treturn sessionScope.run(session, () => runWithActivity(session.activity, fn));\n}\n\nexport function runSessionCleanups(session: WebSession): Promise<void> {\n\tconst existing = pendingCleanups.get(session);\n\tif (existing) return existing;\n\tsession.closed = true;\n\tconst pending = [...session.cleanups].map(async (cleanup) => cleanup());\n\tsession.cleanups.clear();\n\tconst cleanup = Promise.allSettled(pending).then((results) => {\n\t\tconst errors: unknown[] = [];\n\t\tfor (const result of results) {\n\t\t\tif (result.status === \"rejected\") errors.push(result.reason);\n\t\t}\n\t\tif (errors.length > 0) {\n\t\t\tconst details = errors.map((error) => error instanceof Error ? error.message : String(error)).join(\"; \");\n\t\t\tthrow new AggregateError(errors, `Web session cleanup failed: ${details}`);\n\t\t}\n\t});\n\tpendingCleanups.set(session, cleanup);\n\treturn cleanup;\n}\n"]}
@@ -1,17 +1,40 @@
1
- // @ts-nocheck
2
- /** Lightweight session teardown hooks. Heavy modules register on first load. */
3
- const cleanups = [];
4
- export function registerSessionCleanup(fn) {
5
- if (!cleanups.includes(fn))
6
- cleanups.push(fn);
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { ActivityMonitor, runWithActivity } from "./activity.js";
3
+ /** Heavy modules acquire resources inside the calling factory's async scope. */
4
+ export function createWebSession() {
5
+ return {
6
+ activity: new ActivityMonitor(),
7
+ cleanups: new Set(),
8
+ closed: false,
9
+ };
7
10
  }
8
- export function runSessionCleanups() {
9
- for (const fn of cleanups) {
10
- try {
11
- fn();
11
+ const sessionScope = new AsyncLocalStorage();
12
+ const pendingCleanups = new WeakMap();
13
+ export function getWebSession() {
14
+ return sessionScope.getStore();
15
+ }
16
+ export function runWithWebSession(session, fn) {
17
+ return sessionScope.run(session, () => runWithActivity(session.activity, fn));
18
+ }
19
+ export function runSessionCleanups(session) {
20
+ const existing = pendingCleanups.get(session);
21
+ if (existing)
22
+ return existing;
23
+ session.closed = true;
24
+ const pending = [...session.cleanups].map(async (cleanup) => cleanup());
25
+ session.cleanups.clear();
26
+ const cleanup = Promise.allSettled(pending).then((results) => {
27
+ const errors = [];
28
+ for (const result of results) {
29
+ if (result.status === "rejected")
30
+ errors.push(result.reason);
12
31
  }
13
- catch {
32
+ if (errors.length > 0) {
33
+ const details = errors.map((error) => error instanceof Error ? error.message : String(error)).join("; ");
34
+ throw new AggregateError(errors, `Web session cleanup failed: ${details}`);
14
35
  }
15
- }
36
+ });
37
+ pendingCleanups.set(session, cleanup);
38
+ return cleanup;
16
39
  }
17
40
  //# sourceMappingURL=session-cleanup.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-cleanup.js","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/session-cleanup.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,gFAAgF;AAIhF,MAAM,QAAQ,GAAc,EAAE,CAAC;AAE/B,MAAM,UAAU,sBAAsB,CAAC,EAAW,EAAQ;IACzD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAAA,CAC9C;AAED,MAAM,UAAU,kBAAkB,GAAS;IAC1C,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,CAAC;YACJ,EAAE,EAAE,CAAC;QACN,CAAC;QAAC,MAAM,CAAC;QACT,CAAC;IACF,CAAC;AAAA,CACD","sourcesContent":["// @ts-nocheck\n/** Lightweight session teardown hooks. Heavy modules register on first load. */\n\ntype Cleanup = () => void;\n\nconst cleanups: Cleanup[] = [];\n\nexport function registerSessionCleanup(fn: Cleanup): void {\n\tif (!cleanups.includes(fn)) cleanups.push(fn);\n}\n\nexport function runSessionCleanups(): void {\n\tfor (const fn of cleanups) {\n\t\ttry {\n\t\t\tfn();\n\t\t} catch {\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"session-cleanup.js","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/session-cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAIjE,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,GAAG;IAClC,OAAO;QACN,QAAQ,EAAE,IAAI,eAAe,EAAE;QAC/B,QAAQ,EAAE,IAAI,GAAG,EAAW;QAC5B,MAAM,EAAE,KAAK;KACb,CAAC;AAAA,CACF;AAGD,MAAM,YAAY,GAAG,IAAI,iBAAiB,EAAc,CAAC;AACzD,MAAM,eAAe,GAAG,IAAI,OAAO,EAA6B,CAAC;AAEjE,MAAM,UAAU,aAAa,GAA2B;IACvD,OAAO,YAAY,CAAC,QAAQ,EAAE,CAAC;AAAA,CAC/B;AAED,MAAM,UAAU,iBAAiB,CAAI,OAAmB,EAAE,EAAW,EAAK;IACzE,OAAO,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;AAAA,CAC9E;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAmB,EAAiB;IACtE,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACzB,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC7D,MAAM,MAAM,GAAc,EAAE,CAAC;QAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC9B,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU;gBAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzG,MAAM,IAAI,cAAc,CAAC,MAAM,EAAE,+BAA+B,OAAO,EAAE,CAAC,CAAC;QAC5E,CAAC;IAAA,CACD,CAAC,CAAC;IACH,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACtC,OAAO,OAAO,CAAC;AAAA,CACf","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { ActivityMonitor, runWithActivity } from \"./activity.ts\";\n\ntype Cleanup = () => void | Promise<void>;\n\n/** Heavy modules acquire resources inside the calling factory's async scope. */\nexport function createWebSession() {\n\treturn {\n\t\tactivity: new ActivityMonitor(),\n\t\tcleanups: new Set<Cleanup>(),\n\t\tclosed: false,\n\t};\n}\n\nexport type WebSession = ReturnType<typeof createWebSession>;\nconst sessionScope = new AsyncLocalStorage<WebSession>();\nconst pendingCleanups = new WeakMap<WebSession, Promise<void>>();\n\nexport function getWebSession(): WebSession | undefined {\n\treturn sessionScope.getStore();\n}\n\nexport function runWithWebSession<T>(session: WebSession, fn: () => T): T {\n\treturn sessionScope.run(session, () => runWithActivity(session.activity, fn));\n}\n\nexport function runSessionCleanups(session: WebSession): Promise<void> {\n\tconst existing = pendingCleanups.get(session);\n\tif (existing) return existing;\n\tsession.closed = true;\n\tconst pending = [...session.cleanups].map(async (cleanup) => cleanup());\n\tsession.cleanups.clear();\n\tconst cleanup = Promise.allSettled(pending).then((results) => {\n\t\tconst errors: unknown[] = [];\n\t\tfor (const result of results) {\n\t\t\tif (result.status === \"rejected\") errors.push(result.reason);\n\t\t}\n\t\tif (errors.length > 0) {\n\t\t\tconst details = errors.map((error) => error instanceof Error ? error.message : String(error)).join(\"; \");\n\t\t\tthrow new AggregateError(errors, `Web session cleanup failed: ${details}`);\n\t\t}\n\t});\n\tpendingCleanups.set(session, cleanup);\n\treturn cleanup;\n}\n"]}
@@ -16,10 +16,13 @@ export interface StoredSearchData {
16
16
  urls?: ExtractedContent[];
17
17
  }
18
18
  export declare function generateId(): string;
19
- export declare function storeResult(id: string, data: StoredSearchData): void;
20
- export declare function getResult(id: string): StoredSearchData | null;
21
- export declare function getAllResults(): StoredSearchData[];
22
- export declare function deleteResult(id: string): boolean;
23
- export declare function clearResults(): void;
24
- export declare function restoreFromSession(ctx: ExtensionContext): void;
19
+ /** One factory owns its in-memory results; persisted record formats and TTL stay shared. */
20
+ export declare function createResultStore(): {
21
+ storeResult: (id: string, data: StoredSearchData) => void;
22
+ getResult: (id: string) => StoredSearchData | null;
23
+ getAllResults: () => StoredSearchData[];
24
+ deleteResult: (id: string) => boolean;
25
+ clearResults: () => void;
26
+ restoreFromSession: (ctx: ExtensionContext) => void;
27
+ };
25
28
  //# sourceMappingURL=storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAIpD,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC1B;AAID,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAEpE;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAE7D;AAED,wBAAgB,aAAa,IAAI,gBAAgB,EAAE,CAElD;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AAaD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAY9D","sourcesContent":["// @ts-nocheck\nimport type { ExtensionContext } from \"@ashx-j/lunr\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport type { SearchResult } from \"./perplexity.ts\";\n\nconst CACHE_TTL_MS = 60 * 60 * 1000;\n\nexport interface QueryResultData {\n\tquery: string;\n\tanswer: string;\n\tresults: SearchResult[];\n\terror: string | null;\n\tprovider?: string;\n}\n\nexport interface StoredSearchData {\n\tid: string;\n\ttype: \"search\" | \"fetch\";\n\ttimestamp: number;\n\tqueries?: QueryResultData[];\n\turls?: ExtractedContent[];\n}\n\nconst storedResults = new Map<string, StoredSearchData>();\n\nexport function generateId(): string {\n\treturn Date.now().toString(36) + Math.random().toString(36).slice(2, 8);\n}\n\nexport function storeResult(id: string, data: StoredSearchData): void {\n\tstoredResults.set(id, data);\n}\n\nexport function getResult(id: string): StoredSearchData | null {\n\treturn storedResults.get(id) ?? null;\n}\n\nexport function getAllResults(): StoredSearchData[] {\n\treturn Array.from(storedResults.values());\n}\n\nexport function deleteResult(id: string): boolean {\n\treturn storedResults.delete(id);\n}\n\nexport function clearResults(): void {\n\tstoredResults.clear();\n}\n\nfunction isValidStoredData(data: unknown): data is StoredSearchData {\n\tif (!data || typeof data !== \"object\") return false;\n\tconst d = data as Record<string, unknown>;\n\tif (typeof d.id !== \"string\" || !d.id) return false;\n\tif (d.type !== \"search\" && d.type !== \"fetch\") return false;\n\tif (typeof d.timestamp !== \"number\") return false;\n\tif (d.type === \"search\" && !Array.isArray(d.queries)) return false;\n\tif (d.type === \"fetch\" && !Array.isArray(d.urls)) return false;\n\treturn true;\n}\n\nexport function restoreFromSession(ctx: ExtensionContext): void {\n\tstoredResults.clear();\n\tconst now = Date.now();\n\n\tfor (const entry of ctx.sessionManager.getBranch()) {\n\t\tif (entry.type === \"custom\" && entry.customType === \"web-search-results\") {\n\t\t\tconst data = entry.data;\n\t\t\tif (isValidStoredData(data) && now - data.timestamp < CACHE_TTL_MS) {\n\t\t\t\tstoredResults.set(data.id, data);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAIpD,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC1B;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAaD,4FAA4F;AAC5F,wBAAgB,iBAAiB;;;;;;;EA+ChC","sourcesContent":["import type { ExtensionContext } from \"@ashx-j/lunr\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport type { SearchResult } from \"./perplexity.ts\";\n\nconst CACHE_TTL_MS = 60 * 60 * 1000;\n\nexport interface QueryResultData {\n\tquery: string;\n\tanswer: string;\n\tresults: SearchResult[];\n\terror: string | null;\n\tprovider?: string;\n}\n\nexport interface StoredSearchData {\n\tid: string;\n\ttype: \"search\" | \"fetch\";\n\ttimestamp: number;\n\tqueries?: QueryResultData[];\n\turls?: ExtractedContent[];\n}\n\nexport function generateId(): string {\n\treturn Date.now().toString(36) + Math.random().toString(36).slice(2, 8);\n}\n\nfunction isValidStoredData(data: unknown): data is StoredSearchData {\n\tif (!data || typeof data !== \"object\") return false;\n\tconst d = data as Record<string, unknown>;\n\tif (typeof d.id !== \"string\" || !d.id) return false;\n\tif (d.type !== \"search\" && d.type !== \"fetch\") return false;\n\tif (typeof d.timestamp !== \"number\") return false;\n\tif (d.type === \"search\" && !Array.isArray(d.queries)) return false;\n\tif (d.type === \"fetch\" && !Array.isArray(d.urls)) return false;\n\treturn true;\n}\n\n/** One factory owns its in-memory results; persisted record formats and TTL stay shared. */\nexport function createResultStore() {\n\tconst storedResults = new Map<string, StoredSearchData>();\n\tfunction storeResult(id: string, data: StoredSearchData): void {\n\t\tstoredResults.set(id, data);\n\t}\n\n\tfunction getResult(id: string): StoredSearchData | null {\n\t\treturn storedResults.get(id) ?? null;\n\t}\n\n\tfunction getAllResults(): StoredSearchData[] {\n\t\treturn Array.from(storedResults.values());\n\t}\n\n\tfunction deleteResult(id: string): boolean {\n\t\treturn storedResults.delete(id);\n\t}\n\n\tfunction clearResults(): void {\n\t\tstoredResults.clear();\n\t}\n\n\tfunction restoreFromSession(ctx: ExtensionContext): void {\n\t\tstoredResults.clear();\n\t\tconst now = Date.now();\n\n\t\tfor (const entry of ctx.sessionManager.getBranch()) {\n\t\t\tif (\n\t\t\t\tentry.type === \"custom\" &&\n\t\t\t\tentry.customType === \"web-search-results\"\n\t\t\t) {\n\t\t\t\tconst data = entry.data;\n\t\t\t\tif (isValidStoredData(data) && now - data.timestamp < CACHE_TTL_MS) {\n\t\t\t\t\tstoredResults.set(data.id, data);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tstoreResult,\n\t\tgetResult,\n\t\tgetAllResults,\n\t\tdeleteResult,\n\t\tclearResults,\n\t\trestoreFromSession,\n\t};\n}\n"]}
@@ -1,23 +1,7 @@
1
1
  const CACHE_TTL_MS = 60 * 60 * 1000;
2
- const storedResults = new Map();
3
2
  export function generateId() {
4
3
  return Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
5
4
  }
6
- export function storeResult(id, data) {
7
- storedResults.set(id, data);
8
- }
9
- export function getResult(id) {
10
- return storedResults.get(id) ?? null;
11
- }
12
- export function getAllResults() {
13
- return Array.from(storedResults.values());
14
- }
15
- export function deleteResult(id) {
16
- return storedResults.delete(id);
17
- }
18
- export function clearResults() {
19
- storedResults.clear();
20
- }
21
5
  function isValidStoredData(data) {
22
6
  if (!data || typeof data !== "object")
23
7
  return false;
@@ -34,16 +18,44 @@ function isValidStoredData(data) {
34
18
  return false;
35
19
  return true;
36
20
  }
37
- export function restoreFromSession(ctx) {
38
- storedResults.clear();
39
- const now = Date.now();
40
- for (const entry of ctx.sessionManager.getBranch()) {
41
- if (entry.type === "custom" && entry.customType === "web-search-results") {
42
- const data = entry.data;
43
- if (isValidStoredData(data) && now - data.timestamp < CACHE_TTL_MS) {
44
- storedResults.set(data.id, data);
21
+ /** One factory owns its in-memory results; persisted record formats and TTL stay shared. */
22
+ export function createResultStore() {
23
+ const storedResults = new Map();
24
+ function storeResult(id, data) {
25
+ storedResults.set(id, data);
26
+ }
27
+ function getResult(id) {
28
+ return storedResults.get(id) ?? null;
29
+ }
30
+ function getAllResults() {
31
+ return Array.from(storedResults.values());
32
+ }
33
+ function deleteResult(id) {
34
+ return storedResults.delete(id);
35
+ }
36
+ function clearResults() {
37
+ storedResults.clear();
38
+ }
39
+ function restoreFromSession(ctx) {
40
+ storedResults.clear();
41
+ const now = Date.now();
42
+ for (const entry of ctx.sessionManager.getBranch()) {
43
+ if (entry.type === "custom" &&
44
+ entry.customType === "web-search-results") {
45
+ const data = entry.data;
46
+ if (isValidStoredData(data) && now - data.timestamp < CACHE_TTL_MS) {
47
+ storedResults.set(data.id, data);
48
+ }
45
49
  }
46
50
  }
47
51
  }
52
+ return {
53
+ storeResult,
54
+ getResult,
55
+ getAllResults,
56
+ deleteResult,
57
+ clearResults,
58
+ restoreFromSession,
59
+ };
48
60
  }
49
61
  //# sourceMappingURL=storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/storage.ts"],"names":[],"mappings":"AAKA,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAkBpC,MAAM,aAAa,GAAG,IAAI,GAAG,EAA4B,CAAC;AAE1D,MAAM,UAAU,UAAU,GAAW;IACpC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAAA,CACxE;AAED,MAAM,UAAU,WAAW,CAAC,EAAU,EAAE,IAAsB,EAAQ;IACrE,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;AAAA,CAC5B;AAED,MAAM,UAAU,SAAS,CAAC,EAAU,EAA2B;IAC9D,OAAO,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;AAAA,CACrC;AAED,MAAM,UAAU,aAAa,GAAuB;IACnD,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;AAAA,CAC1C;AAED,MAAM,UAAU,YAAY,CAAC,EAAU,EAAW;IACjD,OAAO,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAAA,CAChC;AAED,MAAM,UAAU,YAAY,GAAS;IACpC,aAAa,CAAC,KAAK,EAAE,CAAC;AAAA,CACtB;AAED,SAAS,iBAAiB,CAAC,IAAa,EAA4B;IACnE,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACpD,MAAM,CAAC,GAAG,IAA+B,CAAC;IAC1C,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAC5D,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAClD,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACnE,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/D,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAqB,EAAQ;IAC/D,aAAa,CAAC,KAAK,EAAE,CAAC;IACtB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,CAAC;QACpD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,oBAAoB,EAAE,CAAC;YAC1E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;YACxB,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,GAAG,YAAY,EAAE,CAAC;gBACpE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAClC,CAAC;QACF,CAAC;IACF,CAAC;AAAA,CACD","sourcesContent":["// @ts-nocheck\nimport type { ExtensionContext } from \"@ashx-j/lunr\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport type { SearchResult } from \"./perplexity.ts\";\n\nconst CACHE_TTL_MS = 60 * 60 * 1000;\n\nexport interface QueryResultData {\n\tquery: string;\n\tanswer: string;\n\tresults: SearchResult[];\n\terror: string | null;\n\tprovider?: string;\n}\n\nexport interface StoredSearchData {\n\tid: string;\n\ttype: \"search\" | \"fetch\";\n\ttimestamp: number;\n\tqueries?: QueryResultData[];\n\turls?: ExtractedContent[];\n}\n\nconst storedResults = new Map<string, StoredSearchData>();\n\nexport function generateId(): string {\n\treturn Date.now().toString(36) + Math.random().toString(36).slice(2, 8);\n}\n\nexport function storeResult(id: string, data: StoredSearchData): void {\n\tstoredResults.set(id, data);\n}\n\nexport function getResult(id: string): StoredSearchData | null {\n\treturn storedResults.get(id) ?? null;\n}\n\nexport function getAllResults(): StoredSearchData[] {\n\treturn Array.from(storedResults.values());\n}\n\nexport function deleteResult(id: string): boolean {\n\treturn storedResults.delete(id);\n}\n\nexport function clearResults(): void {\n\tstoredResults.clear();\n}\n\nfunction isValidStoredData(data: unknown): data is StoredSearchData {\n\tif (!data || typeof data !== \"object\") return false;\n\tconst d = data as Record<string, unknown>;\n\tif (typeof d.id !== \"string\" || !d.id) return false;\n\tif (d.type !== \"search\" && d.type !== \"fetch\") return false;\n\tif (typeof d.timestamp !== \"number\") return false;\n\tif (d.type === \"search\" && !Array.isArray(d.queries)) return false;\n\tif (d.type === \"fetch\" && !Array.isArray(d.urls)) return false;\n\treturn true;\n}\n\nexport function restoreFromSession(ctx: ExtensionContext): void {\n\tstoredResults.clear();\n\tconst now = Date.now();\n\n\tfor (const entry of ctx.sessionManager.getBranch()) {\n\t\tif (entry.type === \"custom\" && entry.customType === \"web-search-results\") {\n\t\t\tconst data = entry.data;\n\t\t\tif (isValidStoredData(data) && now - data.timestamp < CACHE_TTL_MS) {\n\t\t\t\tstoredResults.set(data.id, data);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-web-access/storage.ts"],"names":[],"mappings":"AAIA,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAkBpC,MAAM,UAAU,UAAU,GAAW;IACpC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAAA,CACxE;AAED,SAAS,iBAAiB,CAAC,IAAa,EAA4B;IACnE,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACpD,MAAM,CAAC,GAAG,IAA+B,CAAC;IAC1C,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAC5D,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAClD,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACnE,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/D,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,4FAA4F;AAC5F,MAAM,UAAU,iBAAiB,GAAG;IACnC,MAAM,aAAa,GAAG,IAAI,GAAG,EAA4B,CAAC;IAC1D,SAAS,WAAW,CAAC,EAAU,EAAE,IAAsB,EAAQ;QAC9D,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAAA,CAC5B;IAED,SAAS,SAAS,CAAC,EAAU,EAA2B;QACvD,OAAO,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;IAAA,CACrC;IAED,SAAS,aAAa,GAAuB;QAC5C,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;IAAA,CAC1C;IAED,SAAS,YAAY,CAAC,EAAU,EAAW;QAC1C,OAAO,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAAA,CAChC;IAED,SAAS,YAAY,GAAS;QAC7B,aAAa,CAAC,KAAK,EAAE,CAAC;IAAA,CACtB;IAED,SAAS,kBAAkB,CAAC,GAAqB,EAAQ;QACxD,aAAa,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,CAAC;YACpD,IACC,KAAK,CAAC,IAAI,KAAK,QAAQ;gBACvB,KAAK,CAAC,UAAU,KAAK,oBAAoB,EACxC,CAAC;gBACF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;gBACxB,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,GAAG,YAAY,EAAE,CAAC;oBACpE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBAClC,CAAC;YACF,CAAC;QACF,CAAC;IAAA,CACD;IAED,OAAO;QACN,WAAW;QACX,SAAS;QACT,aAAa;QACb,YAAY;QACZ,YAAY;QACZ,kBAAkB;KAClB,CAAC;AAAA,CACF","sourcesContent":["import type { ExtensionContext } from \"@ashx-j/lunr\";\nimport type { ExtractedContent } from \"./extract.ts\";\nimport type { SearchResult } from \"./perplexity.ts\";\n\nconst CACHE_TTL_MS = 60 * 60 * 1000;\n\nexport interface QueryResultData {\n\tquery: string;\n\tanswer: string;\n\tresults: SearchResult[];\n\terror: string | null;\n\tprovider?: string;\n}\n\nexport interface StoredSearchData {\n\tid: string;\n\ttype: \"search\" | \"fetch\";\n\ttimestamp: number;\n\tqueries?: QueryResultData[];\n\turls?: ExtractedContent[];\n}\n\nexport function generateId(): string {\n\treturn Date.now().toString(36) + Math.random().toString(36).slice(2, 8);\n}\n\nfunction isValidStoredData(data: unknown): data is StoredSearchData {\n\tif (!data || typeof data !== \"object\") return false;\n\tconst d = data as Record<string, unknown>;\n\tif (typeof d.id !== \"string\" || !d.id) return false;\n\tif (d.type !== \"search\" && d.type !== \"fetch\") return false;\n\tif (typeof d.timestamp !== \"number\") return false;\n\tif (d.type === \"search\" && !Array.isArray(d.queries)) return false;\n\tif (d.type === \"fetch\" && !Array.isArray(d.urls)) return false;\n\treturn true;\n}\n\n/** One factory owns its in-memory results; persisted record formats and TTL stay shared. */\nexport function createResultStore() {\n\tconst storedResults = new Map<string, StoredSearchData>();\n\tfunction storeResult(id: string, data: StoredSearchData): void {\n\t\tstoredResults.set(id, data);\n\t}\n\n\tfunction getResult(id: string): StoredSearchData | null {\n\t\treturn storedResults.get(id) ?? null;\n\t}\n\n\tfunction getAllResults(): StoredSearchData[] {\n\t\treturn Array.from(storedResults.values());\n\t}\n\n\tfunction deleteResult(id: string): boolean {\n\t\treturn storedResults.delete(id);\n\t}\n\n\tfunction clearResults(): void {\n\t\tstoredResults.clear();\n\t}\n\n\tfunction restoreFromSession(ctx: ExtensionContext): void {\n\t\tstoredResults.clear();\n\t\tconst now = Date.now();\n\n\t\tfor (const entry of ctx.sessionManager.getBranch()) {\n\t\t\tif (\n\t\t\t\tentry.type === \"custom\" &&\n\t\t\t\tentry.customType === \"web-search-results\"\n\t\t\t) {\n\t\t\t\tconst data = entry.data;\n\t\t\t\tif (isValidStoredData(data) && now - data.timestamp < CACHE_TTL_MS) {\n\t\t\t\t\tstoredResults.set(data.id, data);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tstoreResult,\n\t\tgetResult,\n\t\tgetAllResults,\n\t\tdeleteResult,\n\t\tclearResults,\n\t\trestoreFromSession,\n\t};\n}\n"]}
@@ -6,7 +6,7 @@
6
6
  * Tools: memory_add, memory_remove, memory_load.
7
7
  * Command: /memory-char-cap [n] — view or set the character cap (1..30000, default 5000).
8
8
  *
9
- * Loaded by pi via jiti — no build step, plain TypeScript.
9
+ * Registered as a built-in lunR extension and compiled with the coding-agent package.
10
10
  *
11
11
  * Types are declared inline (see the batxj-thinking extension for why:
12
12
  * pi-coding-agent's index.d.ts re-exports from internal .d.ts files with
@@ -1 +1 @@
1
- {"version":3,"file":"simple-pi-memory.d.ts","sourceRoot":"","sources":["../../src/builtin-extensions/simple-pi-memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAuDH,UAAU,UAAU;IACnB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,UAAU,YAAY;IACrB,YAAY,CAAC,IAAI,EAAE;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,OAAO,CAAC;QACpB,OAAO,CACN,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,OAAO,EACjB,GAAG,EAAE,OAAO,GACV,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC;KACpC,GAAG,IAAI,CAAC;IACT,eAAe,CACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QACR,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;KACjE,GACC,IAAI,CAAC;IACR,EAAE,CACD,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,CACR,KAAK,EAAE,qBAAqB,EAC5B,GAAG,EAAE,OAAO,KAEV,OAAO,CAAC;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,GACzC;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GACzB,IAAI,GACL,IAAI,CAAC;CACR;AAED,UAAU,qBAAqB;IAC9B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,cAAc;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE;QACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CAAC;KACpE,CAAC;CACF;AA4ED,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,GAAG,IAAI,CAgJ/C","sourcesContent":["/**\n * simple-memory — a minimal one-file memory extension for pi.\n *\n * One memory file (~/.lunr/simple-memory/memory.md), one durable fact per line.\n * Loaded into the system prompt every turn while agent memory is enabled.\n * Tools: memory_add, memory_remove, memory_load.\n * Command: /memory-char-cap [n] — view or set the character cap (1..30000, default 5000).\n *\n * Loaded by pi via jiti — no build step, plain TypeScript.\n *\n * Types are declared inline (see the batxj-thinking extension for why:\n * pi-coding-agent's index.d.ts re-exports from internal .d.ts files with\n * subpath imports that fail under `tsc --noEmit index.ts`). `Type` is a\n * runtime value imported from @sinclair/typebox (a peer dependency) for tool\n * parameter schemas.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { Type } from \"@sinclair/typebox\";\n// lunr: concrete core-module import (never the package barrel) — resolves the\n// memory dir next to the lunr agent dir instead of the hardcoded ~/.pi below.\nimport { getAgentDir } from \"../config.js\";\n\n// ---------------------------------------------------------------------------\n// Paths and config\n// ---------------------------------------------------------------------------\n// lunr: was join(homedir(), \".pi\", \"simple-memory\") — leaked lunr memory into a\n// real pi install's ~/.pi. Now a sibling of the lunr agent dir (~/.lunr/simple-memory).\n// Old files are copied over by the core startup migration (migrations.ts).\nfunction baseDir(): string {\n\treturn join(dirname(getAgentDir()), \"simple-memory\");\n}\n\nfunction memoryFile(): string {\n\treturn join(baseDir(), \"memory.md\");\n}\n\nfunction configFile(): string {\n\treturn join(baseDir(), \"config.json\");\n}\n\nconst DEFAULT_CHAR_CAP = 5000;\nconst MIN_CHAR_CAP = 1;\nconst MAX_CHAR_CAP = 30000;\n\n// lunr: inside lunR the cap lives in lunR settings, exposed by core on\n// globalThis under Symbol.for(\"@lunr/memory-cap\") (registered from main.ts).\n// The config.json fallback below only matters when no bridge exists.\ninterface MemoryCapBridge {\n\tisEnabled(): boolean;\n\tgetCharCap(): number;\n\tsetCharCap(cap: number): void;\n}\n\nfunction getCapBridge(): MemoryCapBridge | undefined {\n\treturn (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/memory-cap\")] as MemoryCapBridge | undefined;\n}\n\nfunction isMemoryEnabled(): boolean {\n\treturn getCapBridge()?.isEnabled() ?? true;\n}\n\nfunction disabledResult(): ToolResult {\n\treturn { content: [{ type: \"text\", text: \"Agent memory is disabled in /settings.\" }] };\n}\n\n// ---------------------------------------------------------------------------\n// Inline structural types (self-contained for `tsc --noEmit index.ts`)\n// ---------------------------------------------------------------------------\ninterface ToolResult {\n\tcontent: { type: \"text\"; text: string }[];\n\tdetails?: Record<string, unknown>;\n}\n\ninterface ExtensionAPI {\n\tregisterTool(tool: {\n\t\tname: string;\n\t\tlabel?: string;\n\t\tdescription: string;\n\t\tparameters: unknown;\n\t\texecute(\n\t\t\ttoolCallId: string,\n\t\t\tparams: Record<string, unknown>,\n\t\t\tsignal: AbortSignal,\n\t\t\tonUpdate: unknown,\n\t\t\tctx: unknown,\n\t\t): Promise<ToolResult> | ToolResult;\n\t}): void;\n\tregisterCommand(\n\t\tname: string,\n\t\toptions: {\n\t\t\tdescription?: string;\n\t\t\thandler(args: string, ctx: CommandContext): Promise<void> | void;\n\t\t},\n\t): void;\n\ton(\n\t\tevent: \"before_agent_start\",\n\t\thandler: (\n\t\t\tevent: BeforeAgentStartEvent,\n\t\t\tctx: unknown,\n\t\t) =>\n\t\t\t| Promise<{ systemPrompt?: string } | void>\n\t\t\t| { systemPrompt?: string }\n\t\t\t| void,\n\t): void;\n}\n\ninterface BeforeAgentStartEvent {\n\ttype: \"before_agent_start\";\n\tprompt?: string;\n\tsystemPrompt: string;\n}\n\ninterface CommandContext {\n\tmode: string;\n\tui: {\n\t\tnotify(message: string, level?: \"info\" | \"warning\" | \"error\"): void;\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\nfunction ensureDir(): void {\n\tconst dir = baseDir();\n\tif (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n}\n\nfunction readMemory(): string {\n\tconst file = memoryFile();\n\tif (!existsSync(file)) return \"\";\n\treturn readFileSync(file, \"utf-8\");\n}\n\nfunction writeMemoryRaw(text: string): void {\n\tensureDir();\n\twriteFileSync(memoryFile(), text, \"utf-8\");\n}\n\n// Non-empty lines, in order. Normalizes the file (drops blank lines).\nfunction memoryLines(): string[] {\n\tconst text = readMemory();\n\tif (!text.trim()) return [];\n\treturn text.split(\"\\n\").filter((l) => l.trim().length > 0);\n}\n\nfunction clampCap(n: number): number {\n\tif (!Number.isFinite(n)) return DEFAULT_CHAR_CAP;\n\tn = Math.trunc(n);\n\tif (n < MIN_CHAR_CAP) return MIN_CHAR_CAP;\n\tif (n > MAX_CHAR_CAP) return MAX_CHAR_CAP;\n\treturn n;\n}\n\nfunction readCap(): number {\n\tconst bridge = getCapBridge();\n\tif (bridge) return clampCap(bridge.getCharCap());\n\tconst file = configFile();\n\tif (!existsSync(file)) return DEFAULT_CHAR_CAP;\n\ttry {\n\t\tconst cfg = JSON.parse(readFileSync(file, \"utf-8\"));\n\t\tif (typeof cfg.charCap === \"number\" && Number.isFinite(cfg.charCap)) {\n\t\t\treturn clampCap(cfg.charCap);\n\t\t}\n\t} catch {\n\t\t// corrupt config — fall back to default\n\t}\n\treturn DEFAULT_CHAR_CAP;\n}\n\nfunction writeCap(cap: number): void {\n\tconst bridge = getCapBridge();\n\tif (bridge) {\n\t\tbridge.setCharCap(clampCap(cap));\n\t\treturn;\n\t}\n\tensureDir();\n\twriteFileSync(configFile(), JSON.stringify({ charCap: cap }, null, 2), \"utf-8\");\n}\n\nfunction todayStamp(): string {\n\tconst d = new Date();\n\tconst p = (x: number) => String(x).padStart(2, \"0\");\n\treturn `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;\n}\n\n// Strip a leading \"[YYYY-MM-DD] \" date prefix so dedup compares bare content.\nfunction stripDate(line: string): string {\n\treturn line.replace(/^\\[\\d{4}-\\d{2}-\\d{2}\\]\\s*/, \"\");\n}\n\n// ---------------------------------------------------------------------------\n// Extension\n// ---------------------------------------------------------------------------\nexport default function (pi: ExtensionAPI): void {\n\t// --- Inject memory into the system prompt every turn ---\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\tif (!isMemoryEnabled()) return;\n\t\tconst mem = readMemory();\n\t\tif (!mem.trim()) return; // inject nothing when empty\n\t\tconst block =\n\t\t\t\"\\n\\n## Memory (durable facts; apply these; change them only with the memory tools)\\n\" +\n\t\t\tmem.trimEnd();\n\t\treturn { systemPrompt: event.systemPrompt + block };\n\t});\n\n\t// --- memory_add ---\n\tpi.registerTool({\n\t\tname: \"memory_add\",\n\t\tlabel: \"Memory Add\",\n\t\tdescription: [\n\t\t\t\"Add one durable fact about the user or their environment.\",\n\t\t\t\"Store only established facts and stable preferences, never behavior instructions, task state, transcripts, guesses, or secrets.\",\n\t\t\t\"Each memory is a single line; a [YYYY-MM-DD] date prefix is added automatically.\",\n\t\t\t\"An optional #tag improves readability (e.g. #preference).\",\n\t\t\t\"Refuses if the content already exists (exact match) or if the file is at the character cap.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\tcontent: Type.String({\n\t\t\t\tdescription: \"The memory text (one line). You may include a #tag.\",\n\t\t\t}),\n\t\t}),\n\t\tasync execute(_id, params) {\n\t\t\tif (!isMemoryEnabled()) return disabledResult();\n\t\t\tconst content = String(params.content ?? \"\").replace(/[\\r\\n]+/g, \" \").trim();\n\t\t\tif (!content) {\n\t\t\t\treturn { content: [{ type: \"text\", text: \"memory_add: content is empty.\" }] };\n\t\t\t}\n\t\t\tconst lines = memoryLines();\n\t\t\t// exact-content dedup (compare bare content, ignoring the date prefix)\n\t\t\tif (lines.some((l) => stripDate(l) === content)) {\n\t\t\t\treturn { content: [{ type: \"text\", text: \"Already in memory (not added).\" }] };\n\t\t\t}\n\t\t\tconst cap = readCap();\n\t\t\tconst newLine = `[${todayStamp()}] ${content}`;\n\t\t\tconst sep = lines.length > 0 ? \"\\n\" : \"\";\n\t\t\tconst prospective = lines.join(\"\\n\") + sep + newLine + \"\\n\";\n\t\t\tif (prospective.length > cap) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Memory full: ${readMemory().length}/${cap} chars. Remove a memory first (memory_remove).`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t}\n\t\t\twriteMemoryRaw(prospective);\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{ type: \"text\", text: `Added memory (${prospective.length}/${cap} chars): ${newLine}` },\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t});\n\n\t// --- memory_remove ---\n\tpi.registerTool({\n\t\tname: \"memory_remove\",\n\t\tlabel: \"Memory Remove\",\n\t\tdescription: [\n\t\t\t\"Remove one memory by its exact line text, as shown by memory_load.\",\n\t\t\t\"Deletes only an exact, full-line match (including the date prefix).\",\n\t\t\t\"Returns 'not found' if no line matches exactly.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\tline: Type.String({\n\t\t\t\tdescription: \"The exact memory line to remove (verbatim, including the date prefix).\",\n\t\t\t}),\n\t\t}),\n\t\tasync execute(_id, params) {\n\t\t\tif (!isMemoryEnabled()) return disabledResult();\n\t\t\tconst target = String(params.line ?? \"\").trim();\n\t\t\tif (!target) {\n\t\t\t\treturn { content: [{ type: \"text\", text: \"memory_remove: line is empty.\" }] };\n\t\t\t}\n\t\t\tconst lines = memoryLines();\n\t\t\tconst remaining = lines.filter((l) => l !== target);\n\t\t\tif (remaining.length === lines.length) {\n\t\t\t\treturn { content: [{ type: \"text\", text: `Not found (no exact match): ${target}` }] };\n\t\t\t}\n\t\t\twriteMemoryRaw(remaining.length > 0 ? remaining.join(\"\\n\") + \"\\n\" : \"\");\n\t\t\treturn { content: [{ type: \"text\", text: `Removed memory: ${target}` }] };\n\t\t},\n\t});\n\n\t// --- memory_load ---\n\tpi.registerTool({\n\t\tname: \"memory_load\",\n\t\tlabel: \"Memory Load\",\n\t\tdescription: [\n\t\t\t\"Read the current memory file and show all memories with the size/cap.\",\n\t\t\t\"Use this to inspect durable facts before adding, correcting, or removing one.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({}),\n\t\tasync execute() {\n\t\t\tif (!isMemoryEnabled()) return disabledResult();\n\t\t\tconst raw = readMemory();\n\t\t\tconst cap = readCap();\n\t\t\tif (!raw.trim()) {\n\t\t\t\treturn { content: [{ type: \"text\", text: `Memory is empty (0/${cap} chars).` }] };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{ type: \"text\", text: `Memory (${raw.length}/${cap} chars):\\n${raw.trimEnd()}` },\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t});\n\n\t// --- /memory-char-cap command ---\n\tpi.registerCommand(\"memory-char-cap\", {\n\t\tdescription: \"View or set the memory character cap (1..30000). Default 5000.\",\n\t\thandler(args, ctx) {\n\t\t\tconst trimmed = args.trim();\n\t\t\tif (!trimmed) {\n\t\t\t\tctx.ui.notify(`Memory character cap: ${readCap()}`, \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst n = Number(trimmed);\n\t\t\tif (!Number.isFinite(n) || !Number.isInteger(n) || n < MIN_CHAR_CAP || n > MAX_CHAR_CAP) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Invalid cap. Must be an integer between ${MIN_CHAR_CAP} and ${MAX_CHAR_CAP}.`,\n\t\t\t\t\t\"error\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (n < readMemory().length) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Your memory file already exceeds this character cap: ${memoryFile()}`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\twriteCap(n);\n\t\t\tctx.ui.notify(`Memory character cap set to ${n}.`, \"info\");\n\t\t},\n\t});\n}\n"]}
1
+ {"version":3,"file":"simple-pi-memory.d.ts","sourceRoot":"","sources":["../../src/builtin-extensions/simple-pi-memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAuDH,UAAU,UAAU;IACnB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,UAAU,YAAY;IACrB,YAAY,CAAC,IAAI,EAAE;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,OAAO,CAAC;QACpB,OAAO,CACN,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,OAAO,EACjB,GAAG,EAAE,OAAO,GACV,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC;KACpC,GAAG,IAAI,CAAC;IACT,eAAe,CACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QACR,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;KACjE,GACC,IAAI,CAAC;IACR,EAAE,CACD,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,CACR,KAAK,EAAE,qBAAqB,EAC5B,GAAG,EAAE,OAAO,KAEV,OAAO,CAAC;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,GACzC;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GACzB,IAAI,GACL,IAAI,CAAC;CACR;AAED,UAAU,qBAAqB;IAC9B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,cAAc;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE;QACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CAAC;KACpE,CAAC;CACF;AA4ED,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,GAAG,IAAI,CAgJ/C","sourcesContent":["/**\n * simple-memory — a minimal one-file memory extension for pi.\n *\n * One memory file (~/.lunr/simple-memory/memory.md), one durable fact per line.\n * Loaded into the system prompt every turn while agent memory is enabled.\n * Tools: memory_add, memory_remove, memory_load.\n * Command: /memory-char-cap [n] — view or set the character cap (1..30000, default 5000).\n *\n * Registered as a built-in lunR extension and compiled with the coding-agent package.\n *\n * Types are declared inline (see the batxj-thinking extension for why:\n * pi-coding-agent's index.d.ts re-exports from internal .d.ts files with\n * subpath imports that fail under `tsc --noEmit index.ts`). `Type` is a\n * runtime value imported from @sinclair/typebox (a peer dependency) for tool\n * parameter schemas.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { Type } from \"@sinclair/typebox\";\n// lunr: concrete core-module import (never the package barrel) — resolves the\n// memory dir next to the lunr agent dir instead of the hardcoded ~/.pi below.\nimport { getAgentDir } from \"../config.js\";\n\n// ---------------------------------------------------------------------------\n// Paths and config\n// ---------------------------------------------------------------------------\n// lunr: was join(homedir(), \".pi\", \"simple-memory\") — leaked lunr memory into a\n// real pi install's ~/.pi. Now a sibling of the lunr agent dir (~/.lunr/simple-memory).\n// Old files are copied over by the core startup migration (migrations.ts).\nfunction baseDir(): string {\n\treturn join(dirname(getAgentDir()), \"simple-memory\");\n}\n\nfunction memoryFile(): string {\n\treturn join(baseDir(), \"memory.md\");\n}\n\nfunction configFile(): string {\n\treturn join(baseDir(), \"config.json\");\n}\n\nconst DEFAULT_CHAR_CAP = 5000;\nconst MIN_CHAR_CAP = 1;\nconst MAX_CHAR_CAP = 30000;\n\n// lunr: inside lunR the cap lives in lunR settings, exposed by core on\n// globalThis under Symbol.for(\"@lunr/memory-cap\") (registered from main.ts).\n// The config.json fallback below only matters when no bridge exists.\ninterface MemoryCapBridge {\n\tisEnabled(): boolean;\n\tgetCharCap(): number;\n\tsetCharCap(cap: number): void;\n}\n\nfunction getCapBridge(): MemoryCapBridge | undefined {\n\treturn (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/memory-cap\")] as MemoryCapBridge | undefined;\n}\n\nfunction isMemoryEnabled(): boolean {\n\treturn getCapBridge()?.isEnabled() ?? true;\n}\n\nfunction disabledResult(): ToolResult {\n\treturn { content: [{ type: \"text\", text: \"Agent memory is disabled in /settings.\" }] };\n}\n\n// ---------------------------------------------------------------------------\n// Inline structural types (self-contained for `tsc --noEmit index.ts`)\n// ---------------------------------------------------------------------------\ninterface ToolResult {\n\tcontent: { type: \"text\"; text: string }[];\n\tdetails?: Record<string, unknown>;\n}\n\ninterface ExtensionAPI {\n\tregisterTool(tool: {\n\t\tname: string;\n\t\tlabel?: string;\n\t\tdescription: string;\n\t\tparameters: unknown;\n\t\texecute(\n\t\t\ttoolCallId: string,\n\t\t\tparams: Record<string, unknown>,\n\t\t\tsignal: AbortSignal,\n\t\t\tonUpdate: unknown,\n\t\t\tctx: unknown,\n\t\t): Promise<ToolResult> | ToolResult;\n\t}): void;\n\tregisterCommand(\n\t\tname: string,\n\t\toptions: {\n\t\t\tdescription?: string;\n\t\t\thandler(args: string, ctx: CommandContext): Promise<void> | void;\n\t\t},\n\t): void;\n\ton(\n\t\tevent: \"before_agent_start\",\n\t\thandler: (\n\t\t\tevent: BeforeAgentStartEvent,\n\t\t\tctx: unknown,\n\t\t) =>\n\t\t\t| Promise<{ systemPrompt?: string } | void>\n\t\t\t| { systemPrompt?: string }\n\t\t\t| void,\n\t): void;\n}\n\ninterface BeforeAgentStartEvent {\n\ttype: \"before_agent_start\";\n\tprompt?: string;\n\tsystemPrompt: string;\n}\n\ninterface CommandContext {\n\tmode: string;\n\tui: {\n\t\tnotify(message: string, level?: \"info\" | \"warning\" | \"error\"): void;\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\nfunction ensureDir(): void {\n\tconst dir = baseDir();\n\tif (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n}\n\nfunction readMemory(): string {\n\tconst file = memoryFile();\n\tif (!existsSync(file)) return \"\";\n\treturn readFileSync(file, \"utf-8\");\n}\n\nfunction writeMemoryRaw(text: string): void {\n\tensureDir();\n\twriteFileSync(memoryFile(), text, \"utf-8\");\n}\n\n// Non-empty lines, in order. Normalizes the file (drops blank lines).\nfunction memoryLines(): string[] {\n\tconst text = readMemory();\n\tif (!text.trim()) return [];\n\treturn text.split(\"\\n\").filter((l) => l.trim().length > 0);\n}\n\nfunction clampCap(n: number): number {\n\tif (!Number.isFinite(n)) return DEFAULT_CHAR_CAP;\n\tn = Math.trunc(n);\n\tif (n < MIN_CHAR_CAP) return MIN_CHAR_CAP;\n\tif (n > MAX_CHAR_CAP) return MAX_CHAR_CAP;\n\treturn n;\n}\n\nfunction readCap(): number {\n\tconst bridge = getCapBridge();\n\tif (bridge) return clampCap(bridge.getCharCap());\n\tconst file = configFile();\n\tif (!existsSync(file)) return DEFAULT_CHAR_CAP;\n\ttry {\n\t\tconst cfg = JSON.parse(readFileSync(file, \"utf-8\"));\n\t\tif (typeof cfg.charCap === \"number\" && Number.isFinite(cfg.charCap)) {\n\t\t\treturn clampCap(cfg.charCap);\n\t\t}\n\t} catch {\n\t\t// corrupt config — fall back to default\n\t}\n\treturn DEFAULT_CHAR_CAP;\n}\n\nfunction writeCap(cap: number): void {\n\tconst bridge = getCapBridge();\n\tif (bridge) {\n\t\tbridge.setCharCap(clampCap(cap));\n\t\treturn;\n\t}\n\tensureDir();\n\twriteFileSync(configFile(), JSON.stringify({ charCap: cap }, null, 2), \"utf-8\");\n}\n\nfunction todayStamp(): string {\n\tconst d = new Date();\n\tconst p = (x: number) => String(x).padStart(2, \"0\");\n\treturn `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;\n}\n\n// Strip a leading \"[YYYY-MM-DD] \" date prefix so dedup compares bare content.\nfunction stripDate(line: string): string {\n\treturn line.replace(/^\\[\\d{4}-\\d{2}-\\d{2}\\]\\s*/, \"\");\n}\n\n// ---------------------------------------------------------------------------\n// Extension\n// ---------------------------------------------------------------------------\nexport default function (pi: ExtensionAPI): void {\n\t// --- Inject memory into the system prompt every turn ---\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\tif (!isMemoryEnabled()) return;\n\t\tconst mem = readMemory();\n\t\tif (!mem.trim()) return; // inject nothing when empty\n\t\tconst block =\n\t\t\t\"\\n\\n## Memory (durable facts; apply these; change them only with the memory tools)\\n\" +\n\t\t\tmem.trimEnd();\n\t\treturn { systemPrompt: event.systemPrompt + block };\n\t});\n\n\t// --- memory_add ---\n\tpi.registerTool({\n\t\tname: \"memory_add\",\n\t\tlabel: \"Memory Add\",\n\t\tdescription: [\n\t\t\t\"Add one durable fact about the user or their environment.\",\n\t\t\t\"Store only established facts and stable preferences, never behavior instructions, task state, transcripts, guesses, or secrets.\",\n\t\t\t\"Each memory is a single line; a [YYYY-MM-DD] date prefix is added automatically.\",\n\t\t\t\"An optional #tag improves readability (e.g. #preference).\",\n\t\t\t\"Refuses if the content already exists (exact match) or if the file is at the character cap.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\tcontent: Type.String({\n\t\t\t\tdescription: \"The memory text (one line). You may include a #tag.\",\n\t\t\t}),\n\t\t}),\n\t\tasync execute(_id, params) {\n\t\t\tif (!isMemoryEnabled()) return disabledResult();\n\t\t\tconst content = String(params.content ?? \"\").replace(/[\\r\\n]+/g, \" \").trim();\n\t\t\tif (!content) {\n\t\t\t\treturn { content: [{ type: \"text\", text: \"memory_add: content is empty.\" }] };\n\t\t\t}\n\t\t\tconst lines = memoryLines();\n\t\t\t// exact-content dedup (compare bare content, ignoring the date prefix)\n\t\t\tif (lines.some((l) => stripDate(l) === content)) {\n\t\t\t\treturn { content: [{ type: \"text\", text: \"Already in memory (not added).\" }] };\n\t\t\t}\n\t\t\tconst cap = readCap();\n\t\t\tconst newLine = `[${todayStamp()}] ${content}`;\n\t\t\tconst sep = lines.length > 0 ? \"\\n\" : \"\";\n\t\t\tconst prospective = lines.join(\"\\n\") + sep + newLine + \"\\n\";\n\t\t\tif (prospective.length > cap) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Memory full: ${readMemory().length}/${cap} chars. Remove a memory first (memory_remove).`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t}\n\t\t\twriteMemoryRaw(prospective);\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{ type: \"text\", text: `Added memory (${prospective.length}/${cap} chars): ${newLine}` },\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t});\n\n\t// --- memory_remove ---\n\tpi.registerTool({\n\t\tname: \"memory_remove\",\n\t\tlabel: \"Memory Remove\",\n\t\tdescription: [\n\t\t\t\"Remove one memory by its exact line text, as shown by memory_load.\",\n\t\t\t\"Deletes only an exact, full-line match (including the date prefix).\",\n\t\t\t\"Returns 'not found' if no line matches exactly.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\tline: Type.String({\n\t\t\t\tdescription: \"The exact memory line to remove (verbatim, including the date prefix).\",\n\t\t\t}),\n\t\t}),\n\t\tasync execute(_id, params) {\n\t\t\tif (!isMemoryEnabled()) return disabledResult();\n\t\t\tconst target = String(params.line ?? \"\").trim();\n\t\t\tif (!target) {\n\t\t\t\treturn { content: [{ type: \"text\", text: \"memory_remove: line is empty.\" }] };\n\t\t\t}\n\t\t\tconst lines = memoryLines();\n\t\t\tconst remaining = lines.filter((l) => l !== target);\n\t\t\tif (remaining.length === lines.length) {\n\t\t\t\treturn { content: [{ type: \"text\", text: `Not found (no exact match): ${target}` }] };\n\t\t\t}\n\t\t\twriteMemoryRaw(remaining.length > 0 ? remaining.join(\"\\n\") + \"\\n\" : \"\");\n\t\t\treturn { content: [{ type: \"text\", text: `Removed memory: ${target}` }] };\n\t\t},\n\t});\n\n\t// --- memory_load ---\n\tpi.registerTool({\n\t\tname: \"memory_load\",\n\t\tlabel: \"Memory Load\",\n\t\tdescription: [\n\t\t\t\"Read the current memory file and show all memories with the size/cap.\",\n\t\t\t\"Use this to inspect durable facts before adding, correcting, or removing one.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({}),\n\t\tasync execute() {\n\t\t\tif (!isMemoryEnabled()) return disabledResult();\n\t\t\tconst raw = readMemory();\n\t\t\tconst cap = readCap();\n\t\t\tif (!raw.trim()) {\n\t\t\t\treturn { content: [{ type: \"text\", text: `Memory is empty (0/${cap} chars).` }] };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{ type: \"text\", text: `Memory (${raw.length}/${cap} chars):\\n${raw.trimEnd()}` },\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t});\n\n\t// --- /memory-char-cap command ---\n\tpi.registerCommand(\"memory-char-cap\", {\n\t\tdescription: \"View or set the memory character cap (1..30000). Default 5000.\",\n\t\thandler(args, ctx) {\n\t\t\tconst trimmed = args.trim();\n\t\t\tif (!trimmed) {\n\t\t\t\tctx.ui.notify(`Memory character cap: ${readCap()}`, \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst n = Number(trimmed);\n\t\t\tif (!Number.isFinite(n) || !Number.isInteger(n) || n < MIN_CHAR_CAP || n > MAX_CHAR_CAP) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Invalid cap. Must be an integer between ${MIN_CHAR_CAP} and ${MAX_CHAR_CAP}.`,\n\t\t\t\t\t\"error\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (n < readMemory().length) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Your memory file already exceeds this character cap: ${memoryFile()}`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\twriteCap(n);\n\t\t\tctx.ui.notify(`Memory character cap set to ${n}.`, \"info\");\n\t\t},\n\t});\n}\n"]}
@@ -6,7 +6,7 @@
6
6
  * Tools: memory_add, memory_remove, memory_load.
7
7
  * Command: /memory-char-cap [n] — view or set the character cap (1..30000, default 5000).
8
8
  *
9
- * Loaded by pi via jiti — no build step, plain TypeScript.
9
+ * Registered as a built-in lunR extension and compiled with the coding-agent package.
10
10
  *
11
11
  * Types are declared inline (see the batxj-thinking extension for why:
12
12
  * pi-coding-agent's index.d.ts re-exports from internal .d.ts files with
@@ -1 +1 @@
1
- {"version":3,"file":"simple-pi-memory.js","sourceRoot":"","sources":["../../src/builtin-extensions/simple-pi-memory.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * simple-memory — a minimal one-file memory extension for pi.\n *\n * One memory file (~/.lunr/simple-memory/memory.md), one durable fact per line.\n * Loaded into the system prompt every turn while agent memory is enabled.\n * Tools: memory_add, memory_remove, memory_load.\n * Command: /memory-char-cap [n] — view or set the character cap (1..30000, default 5000).\n *\n * Loaded by pi via jiti — no build step, plain TypeScript.\n *\n * Types are declared inline (see the batxj-thinking extension for why:\n * pi-coding-agent's index.d.ts re-exports from internal .d.ts files with\n * subpath imports that fail under `tsc --noEmit index.ts`). `Type` is a\n * runtime value imported from @sinclair/typebox (a peer dependency) for tool\n * parameter schemas.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { Type } from \"@sinclair/typebox\";\n// lunr: concrete core-module import (never the package barrel) — resolves the\n// memory dir next to the lunr agent dir instead of the hardcoded ~/.pi below.\nimport { getAgentDir } from \"../config.js\";\n\n// ---------------------------------------------------------------------------\n// Paths and config\n// ---------------------------------------------------------------------------\n// lunr: was join(homedir(), \".pi\", \"simple-memory\") — leaked lunr memory into a\n// real pi install's ~/.pi. Now a sibling of the lunr agent dir (~/.lunr/simple-memory).\n// Old files are copied over by the core startup migration (migrations.ts).\nfunction baseDir(): string {\n\treturn join(dirname(getAgentDir()), \"simple-memory\");\n}\n\nfunction memoryFile(): string {\n\treturn join(baseDir(), \"memory.md\");\n}\n\nfunction configFile(): string {\n\treturn join(baseDir(), \"config.json\");\n}\n\nconst DEFAULT_CHAR_CAP = 5000;\nconst MIN_CHAR_CAP = 1;\nconst MAX_CHAR_CAP = 30000;\n\n// lunr: inside lunR the cap lives in lunR settings, exposed by core on\n// globalThis under Symbol.for(\"@lunr/memory-cap\") (registered from main.ts).\n// The config.json fallback below only matters when no bridge exists.\ninterface MemoryCapBridge {\n\tisEnabled(): boolean;\n\tgetCharCap(): number;\n\tsetCharCap(cap: number): void;\n}\n\nfunction getCapBridge(): MemoryCapBridge | undefined {\n\treturn (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/memory-cap\")] as MemoryCapBridge | undefined;\n}\n\nfunction isMemoryEnabled(): boolean {\n\treturn getCapBridge()?.isEnabled() ?? true;\n}\n\nfunction disabledResult(): ToolResult {\n\treturn { content: [{ type: \"text\", text: \"Agent memory is disabled in /settings.\" }] };\n}\n\n// ---------------------------------------------------------------------------\n// Inline structural types (self-contained for `tsc --noEmit index.ts`)\n// ---------------------------------------------------------------------------\ninterface ToolResult {\n\tcontent: { type: \"text\"; text: string }[];\n\tdetails?: Record<string, unknown>;\n}\n\ninterface ExtensionAPI {\n\tregisterTool(tool: {\n\t\tname: string;\n\t\tlabel?: string;\n\t\tdescription: string;\n\t\tparameters: unknown;\n\t\texecute(\n\t\t\ttoolCallId: string,\n\t\t\tparams: Record<string, unknown>,\n\t\t\tsignal: AbortSignal,\n\t\t\tonUpdate: unknown,\n\t\t\tctx: unknown,\n\t\t): Promise<ToolResult> | ToolResult;\n\t}): void;\n\tregisterCommand(\n\t\tname: string,\n\t\toptions: {\n\t\t\tdescription?: string;\n\t\t\thandler(args: string, ctx: CommandContext): Promise<void> | void;\n\t\t},\n\t): void;\n\ton(\n\t\tevent: \"before_agent_start\",\n\t\thandler: (\n\t\t\tevent: BeforeAgentStartEvent,\n\t\t\tctx: unknown,\n\t\t) =>\n\t\t\t| Promise<{ systemPrompt?: string } | void>\n\t\t\t| { systemPrompt?: string }\n\t\t\t| void,\n\t): void;\n}\n\ninterface BeforeAgentStartEvent {\n\ttype: \"before_agent_start\";\n\tprompt?: string;\n\tsystemPrompt: string;\n}\n\ninterface CommandContext {\n\tmode: string;\n\tui: {\n\t\tnotify(message: string, level?: \"info\" | \"warning\" | \"error\"): void;\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\nfunction ensureDir(): void {\n\tconst dir = baseDir();\n\tif (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n}\n\nfunction readMemory(): string {\n\tconst file = memoryFile();\n\tif (!existsSync(file)) return \"\";\n\treturn readFileSync(file, \"utf-8\");\n}\n\nfunction writeMemoryRaw(text: string): void {\n\tensureDir();\n\twriteFileSync(memoryFile(), text, \"utf-8\");\n}\n\n// Non-empty lines, in order. Normalizes the file (drops blank lines).\nfunction memoryLines(): string[] {\n\tconst text = readMemory();\n\tif (!text.trim()) return [];\n\treturn text.split(\"\\n\").filter((l) => l.trim().length > 0);\n}\n\nfunction clampCap(n: number): number {\n\tif (!Number.isFinite(n)) return DEFAULT_CHAR_CAP;\n\tn = Math.trunc(n);\n\tif (n < MIN_CHAR_CAP) return MIN_CHAR_CAP;\n\tif (n > MAX_CHAR_CAP) return MAX_CHAR_CAP;\n\treturn n;\n}\n\nfunction readCap(): number {\n\tconst bridge = getCapBridge();\n\tif (bridge) return clampCap(bridge.getCharCap());\n\tconst file = configFile();\n\tif (!existsSync(file)) return DEFAULT_CHAR_CAP;\n\ttry {\n\t\tconst cfg = JSON.parse(readFileSync(file, \"utf-8\"));\n\t\tif (typeof cfg.charCap === \"number\" && Number.isFinite(cfg.charCap)) {\n\t\t\treturn clampCap(cfg.charCap);\n\t\t}\n\t} catch {\n\t\t// corrupt config — fall back to default\n\t}\n\treturn DEFAULT_CHAR_CAP;\n}\n\nfunction writeCap(cap: number): void {\n\tconst bridge = getCapBridge();\n\tif (bridge) {\n\t\tbridge.setCharCap(clampCap(cap));\n\t\treturn;\n\t}\n\tensureDir();\n\twriteFileSync(configFile(), JSON.stringify({ charCap: cap }, null, 2), \"utf-8\");\n}\n\nfunction todayStamp(): string {\n\tconst d = new Date();\n\tconst p = (x: number) => String(x).padStart(2, \"0\");\n\treturn `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;\n}\n\n// Strip a leading \"[YYYY-MM-DD] \" date prefix so dedup compares bare content.\nfunction stripDate(line: string): string {\n\treturn line.replace(/^\\[\\d{4}-\\d{2}-\\d{2}\\]\\s*/, \"\");\n}\n\n// ---------------------------------------------------------------------------\n// Extension\n// ---------------------------------------------------------------------------\nexport default function (pi: ExtensionAPI): void {\n\t// --- Inject memory into the system prompt every turn ---\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\tif (!isMemoryEnabled()) return;\n\t\tconst mem = readMemory();\n\t\tif (!mem.trim()) return; // inject nothing when empty\n\t\tconst block =\n\t\t\t\"\\n\\n## Memory (durable facts; apply these; change them only with the memory tools)\\n\" +\n\t\t\tmem.trimEnd();\n\t\treturn { systemPrompt: event.systemPrompt + block };\n\t});\n\n\t// --- memory_add ---\n\tpi.registerTool({\n\t\tname: \"memory_add\",\n\t\tlabel: \"Memory Add\",\n\t\tdescription: [\n\t\t\t\"Add one durable fact about the user or their environment.\",\n\t\t\t\"Store only established facts and stable preferences, never behavior instructions, task state, transcripts, guesses, or secrets.\",\n\t\t\t\"Each memory is a single line; a [YYYY-MM-DD] date prefix is added automatically.\",\n\t\t\t\"An optional #tag improves readability (e.g. #preference).\",\n\t\t\t\"Refuses if the content already exists (exact match) or if the file is at the character cap.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\tcontent: Type.String({\n\t\t\t\tdescription: \"The memory text (one line). You may include a #tag.\",\n\t\t\t}),\n\t\t}),\n\t\tasync execute(_id, params) {\n\t\t\tif (!isMemoryEnabled()) return disabledResult();\n\t\t\tconst content = String(params.content ?? \"\").replace(/[\\r\\n]+/g, \" \").trim();\n\t\t\tif (!content) {\n\t\t\t\treturn { content: [{ type: \"text\", text: \"memory_add: content is empty.\" }] };\n\t\t\t}\n\t\t\tconst lines = memoryLines();\n\t\t\t// exact-content dedup (compare bare content, ignoring the date prefix)\n\t\t\tif (lines.some((l) => stripDate(l) === content)) {\n\t\t\t\treturn { content: [{ type: \"text\", text: \"Already in memory (not added).\" }] };\n\t\t\t}\n\t\t\tconst cap = readCap();\n\t\t\tconst newLine = `[${todayStamp()}] ${content}`;\n\t\t\tconst sep = lines.length > 0 ? \"\\n\" : \"\";\n\t\t\tconst prospective = lines.join(\"\\n\") + sep + newLine + \"\\n\";\n\t\t\tif (prospective.length > cap) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Memory full: ${readMemory().length}/${cap} chars. Remove a memory first (memory_remove).`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t}\n\t\t\twriteMemoryRaw(prospective);\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{ type: \"text\", text: `Added memory (${prospective.length}/${cap} chars): ${newLine}` },\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t});\n\n\t// --- memory_remove ---\n\tpi.registerTool({\n\t\tname: \"memory_remove\",\n\t\tlabel: \"Memory Remove\",\n\t\tdescription: [\n\t\t\t\"Remove one memory by its exact line text, as shown by memory_load.\",\n\t\t\t\"Deletes only an exact, full-line match (including the date prefix).\",\n\t\t\t\"Returns 'not found' if no line matches exactly.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\tline: Type.String({\n\t\t\t\tdescription: \"The exact memory line to remove (verbatim, including the date prefix).\",\n\t\t\t}),\n\t\t}),\n\t\tasync execute(_id, params) {\n\t\t\tif (!isMemoryEnabled()) return disabledResult();\n\t\t\tconst target = String(params.line ?? \"\").trim();\n\t\t\tif (!target) {\n\t\t\t\treturn { content: [{ type: \"text\", text: \"memory_remove: line is empty.\" }] };\n\t\t\t}\n\t\t\tconst lines = memoryLines();\n\t\t\tconst remaining = lines.filter((l) => l !== target);\n\t\t\tif (remaining.length === lines.length) {\n\t\t\t\treturn { content: [{ type: \"text\", text: `Not found (no exact match): ${target}` }] };\n\t\t\t}\n\t\t\twriteMemoryRaw(remaining.length > 0 ? remaining.join(\"\\n\") + \"\\n\" : \"\");\n\t\t\treturn { content: [{ type: \"text\", text: `Removed memory: ${target}` }] };\n\t\t},\n\t});\n\n\t// --- memory_load ---\n\tpi.registerTool({\n\t\tname: \"memory_load\",\n\t\tlabel: \"Memory Load\",\n\t\tdescription: [\n\t\t\t\"Read the current memory file and show all memories with the size/cap.\",\n\t\t\t\"Use this to inspect durable facts before adding, correcting, or removing one.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({}),\n\t\tasync execute() {\n\t\t\tif (!isMemoryEnabled()) return disabledResult();\n\t\t\tconst raw = readMemory();\n\t\t\tconst cap = readCap();\n\t\t\tif (!raw.trim()) {\n\t\t\t\treturn { content: [{ type: \"text\", text: `Memory is empty (0/${cap} chars).` }] };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{ type: \"text\", text: `Memory (${raw.length}/${cap} chars):\\n${raw.trimEnd()}` },\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t});\n\n\t// --- /memory-char-cap command ---\n\tpi.registerCommand(\"memory-char-cap\", {\n\t\tdescription: \"View or set the memory character cap (1..30000). Default 5000.\",\n\t\thandler(args, ctx) {\n\t\t\tconst trimmed = args.trim();\n\t\t\tif (!trimmed) {\n\t\t\t\tctx.ui.notify(`Memory character cap: ${readCap()}`, \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst n = Number(trimmed);\n\t\t\tif (!Number.isFinite(n) || !Number.isInteger(n) || n < MIN_CHAR_CAP || n > MAX_CHAR_CAP) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Invalid cap. Must be an integer between ${MIN_CHAR_CAP} and ${MAX_CHAR_CAP}.`,\n\t\t\t\t\t\"error\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (n < readMemory().length) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Your memory file already exceeds this character cap: ${memoryFile()}`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\twriteCap(n);\n\t\t\tctx.ui.notify(`Memory character cap set to ${n}.`, \"info\");\n\t\t},\n\t});\n}\n"]}
1
+ {"version":3,"file":"simple-pi-memory.js","sourceRoot":"","sources":["../../src/builtin-extensions/simple-pi-memory.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * simple-memory — a minimal one-file memory extension for pi.\n *\n * One memory file (~/.lunr/simple-memory/memory.md), one durable fact per line.\n * Loaded into the system prompt every turn while agent memory is enabled.\n * Tools: memory_add, memory_remove, memory_load.\n * Command: /memory-char-cap [n] — view or set the character cap (1..30000, default 5000).\n *\n * Registered as a built-in lunR extension and compiled with the coding-agent package.\n *\n * Types are declared inline (see the batxj-thinking extension for why:\n * pi-coding-agent's index.d.ts re-exports from internal .d.ts files with\n * subpath imports that fail under `tsc --noEmit index.ts`). `Type` is a\n * runtime value imported from @sinclair/typebox (a peer dependency) for tool\n * parameter schemas.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { Type } from \"@sinclair/typebox\";\n// lunr: concrete core-module import (never the package barrel) — resolves the\n// memory dir next to the lunr agent dir instead of the hardcoded ~/.pi below.\nimport { getAgentDir } from \"../config.js\";\n\n// ---------------------------------------------------------------------------\n// Paths and config\n// ---------------------------------------------------------------------------\n// lunr: was join(homedir(), \".pi\", \"simple-memory\") — leaked lunr memory into a\n// real pi install's ~/.pi. Now a sibling of the lunr agent dir (~/.lunr/simple-memory).\n// Old files are copied over by the core startup migration (migrations.ts).\nfunction baseDir(): string {\n\treturn join(dirname(getAgentDir()), \"simple-memory\");\n}\n\nfunction memoryFile(): string {\n\treturn join(baseDir(), \"memory.md\");\n}\n\nfunction configFile(): string {\n\treturn join(baseDir(), \"config.json\");\n}\n\nconst DEFAULT_CHAR_CAP = 5000;\nconst MIN_CHAR_CAP = 1;\nconst MAX_CHAR_CAP = 30000;\n\n// lunr: inside lunR the cap lives in lunR settings, exposed by core on\n// globalThis under Symbol.for(\"@lunr/memory-cap\") (registered from main.ts).\n// The config.json fallback below only matters when no bridge exists.\ninterface MemoryCapBridge {\n\tisEnabled(): boolean;\n\tgetCharCap(): number;\n\tsetCharCap(cap: number): void;\n}\n\nfunction getCapBridge(): MemoryCapBridge | undefined {\n\treturn (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/memory-cap\")] as MemoryCapBridge | undefined;\n}\n\nfunction isMemoryEnabled(): boolean {\n\treturn getCapBridge()?.isEnabled() ?? true;\n}\n\nfunction disabledResult(): ToolResult {\n\treturn { content: [{ type: \"text\", text: \"Agent memory is disabled in /settings.\" }] };\n}\n\n// ---------------------------------------------------------------------------\n// Inline structural types (self-contained for `tsc --noEmit index.ts`)\n// ---------------------------------------------------------------------------\ninterface ToolResult {\n\tcontent: { type: \"text\"; text: string }[];\n\tdetails?: Record<string, unknown>;\n}\n\ninterface ExtensionAPI {\n\tregisterTool(tool: {\n\t\tname: string;\n\t\tlabel?: string;\n\t\tdescription: string;\n\t\tparameters: unknown;\n\t\texecute(\n\t\t\ttoolCallId: string,\n\t\t\tparams: Record<string, unknown>,\n\t\t\tsignal: AbortSignal,\n\t\t\tonUpdate: unknown,\n\t\t\tctx: unknown,\n\t\t): Promise<ToolResult> | ToolResult;\n\t}): void;\n\tregisterCommand(\n\t\tname: string,\n\t\toptions: {\n\t\t\tdescription?: string;\n\t\t\thandler(args: string, ctx: CommandContext): Promise<void> | void;\n\t\t},\n\t): void;\n\ton(\n\t\tevent: \"before_agent_start\",\n\t\thandler: (\n\t\t\tevent: BeforeAgentStartEvent,\n\t\t\tctx: unknown,\n\t\t) =>\n\t\t\t| Promise<{ systemPrompt?: string } | void>\n\t\t\t| { systemPrompt?: string }\n\t\t\t| void,\n\t): void;\n}\n\ninterface BeforeAgentStartEvent {\n\ttype: \"before_agent_start\";\n\tprompt?: string;\n\tsystemPrompt: string;\n}\n\ninterface CommandContext {\n\tmode: string;\n\tui: {\n\t\tnotify(message: string, level?: \"info\" | \"warning\" | \"error\"): void;\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\nfunction ensureDir(): void {\n\tconst dir = baseDir();\n\tif (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n}\n\nfunction readMemory(): string {\n\tconst file = memoryFile();\n\tif (!existsSync(file)) return \"\";\n\treturn readFileSync(file, \"utf-8\");\n}\n\nfunction writeMemoryRaw(text: string): void {\n\tensureDir();\n\twriteFileSync(memoryFile(), text, \"utf-8\");\n}\n\n// Non-empty lines, in order. Normalizes the file (drops blank lines).\nfunction memoryLines(): string[] {\n\tconst text = readMemory();\n\tif (!text.trim()) return [];\n\treturn text.split(\"\\n\").filter((l) => l.trim().length > 0);\n}\n\nfunction clampCap(n: number): number {\n\tif (!Number.isFinite(n)) return DEFAULT_CHAR_CAP;\n\tn = Math.trunc(n);\n\tif (n < MIN_CHAR_CAP) return MIN_CHAR_CAP;\n\tif (n > MAX_CHAR_CAP) return MAX_CHAR_CAP;\n\treturn n;\n}\n\nfunction readCap(): number {\n\tconst bridge = getCapBridge();\n\tif (bridge) return clampCap(bridge.getCharCap());\n\tconst file = configFile();\n\tif (!existsSync(file)) return DEFAULT_CHAR_CAP;\n\ttry {\n\t\tconst cfg = JSON.parse(readFileSync(file, \"utf-8\"));\n\t\tif (typeof cfg.charCap === \"number\" && Number.isFinite(cfg.charCap)) {\n\t\t\treturn clampCap(cfg.charCap);\n\t\t}\n\t} catch {\n\t\t// corrupt config — fall back to default\n\t}\n\treturn DEFAULT_CHAR_CAP;\n}\n\nfunction writeCap(cap: number): void {\n\tconst bridge = getCapBridge();\n\tif (bridge) {\n\t\tbridge.setCharCap(clampCap(cap));\n\t\treturn;\n\t}\n\tensureDir();\n\twriteFileSync(configFile(), JSON.stringify({ charCap: cap }, null, 2), \"utf-8\");\n}\n\nfunction todayStamp(): string {\n\tconst d = new Date();\n\tconst p = (x: number) => String(x).padStart(2, \"0\");\n\treturn `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;\n}\n\n// Strip a leading \"[YYYY-MM-DD] \" date prefix so dedup compares bare content.\nfunction stripDate(line: string): string {\n\treturn line.replace(/^\\[\\d{4}-\\d{2}-\\d{2}\\]\\s*/, \"\");\n}\n\n// ---------------------------------------------------------------------------\n// Extension\n// ---------------------------------------------------------------------------\nexport default function (pi: ExtensionAPI): void {\n\t// --- Inject memory into the system prompt every turn ---\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\tif (!isMemoryEnabled()) return;\n\t\tconst mem = readMemory();\n\t\tif (!mem.trim()) return; // inject nothing when empty\n\t\tconst block =\n\t\t\t\"\\n\\n## Memory (durable facts; apply these; change them only with the memory tools)\\n\" +\n\t\t\tmem.trimEnd();\n\t\treturn { systemPrompt: event.systemPrompt + block };\n\t});\n\n\t// --- memory_add ---\n\tpi.registerTool({\n\t\tname: \"memory_add\",\n\t\tlabel: \"Memory Add\",\n\t\tdescription: [\n\t\t\t\"Add one durable fact about the user or their environment.\",\n\t\t\t\"Store only established facts and stable preferences, never behavior instructions, task state, transcripts, guesses, or secrets.\",\n\t\t\t\"Each memory is a single line; a [YYYY-MM-DD] date prefix is added automatically.\",\n\t\t\t\"An optional #tag improves readability (e.g. #preference).\",\n\t\t\t\"Refuses if the content already exists (exact match) or if the file is at the character cap.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\tcontent: Type.String({\n\t\t\t\tdescription: \"The memory text (one line). You may include a #tag.\",\n\t\t\t}),\n\t\t}),\n\t\tasync execute(_id, params) {\n\t\t\tif (!isMemoryEnabled()) return disabledResult();\n\t\t\tconst content = String(params.content ?? \"\").replace(/[\\r\\n]+/g, \" \").trim();\n\t\t\tif (!content) {\n\t\t\t\treturn { content: [{ type: \"text\", text: \"memory_add: content is empty.\" }] };\n\t\t\t}\n\t\t\tconst lines = memoryLines();\n\t\t\t// exact-content dedup (compare bare content, ignoring the date prefix)\n\t\t\tif (lines.some((l) => stripDate(l) === content)) {\n\t\t\t\treturn { content: [{ type: \"text\", text: \"Already in memory (not added).\" }] };\n\t\t\t}\n\t\t\tconst cap = readCap();\n\t\t\tconst newLine = `[${todayStamp()}] ${content}`;\n\t\t\tconst sep = lines.length > 0 ? \"\\n\" : \"\";\n\t\t\tconst prospective = lines.join(\"\\n\") + sep + newLine + \"\\n\";\n\t\t\tif (prospective.length > cap) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Memory full: ${readMemory().length}/${cap} chars. Remove a memory first (memory_remove).`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t}\n\t\t\twriteMemoryRaw(prospective);\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{ type: \"text\", text: `Added memory (${prospective.length}/${cap} chars): ${newLine}` },\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t});\n\n\t// --- memory_remove ---\n\tpi.registerTool({\n\t\tname: \"memory_remove\",\n\t\tlabel: \"Memory Remove\",\n\t\tdescription: [\n\t\t\t\"Remove one memory by its exact line text, as shown by memory_load.\",\n\t\t\t\"Deletes only an exact, full-line match (including the date prefix).\",\n\t\t\t\"Returns 'not found' if no line matches exactly.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\tline: Type.String({\n\t\t\t\tdescription: \"The exact memory line to remove (verbatim, including the date prefix).\",\n\t\t\t}),\n\t\t}),\n\t\tasync execute(_id, params) {\n\t\t\tif (!isMemoryEnabled()) return disabledResult();\n\t\t\tconst target = String(params.line ?? \"\").trim();\n\t\t\tif (!target) {\n\t\t\t\treturn { content: [{ type: \"text\", text: \"memory_remove: line is empty.\" }] };\n\t\t\t}\n\t\t\tconst lines = memoryLines();\n\t\t\tconst remaining = lines.filter((l) => l !== target);\n\t\t\tif (remaining.length === lines.length) {\n\t\t\t\treturn { content: [{ type: \"text\", text: `Not found (no exact match): ${target}` }] };\n\t\t\t}\n\t\t\twriteMemoryRaw(remaining.length > 0 ? remaining.join(\"\\n\") + \"\\n\" : \"\");\n\t\t\treturn { content: [{ type: \"text\", text: `Removed memory: ${target}` }] };\n\t\t},\n\t});\n\n\t// --- memory_load ---\n\tpi.registerTool({\n\t\tname: \"memory_load\",\n\t\tlabel: \"Memory Load\",\n\t\tdescription: [\n\t\t\t\"Read the current memory file and show all memories with the size/cap.\",\n\t\t\t\"Use this to inspect durable facts before adding, correcting, or removing one.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({}),\n\t\tasync execute() {\n\t\t\tif (!isMemoryEnabled()) return disabledResult();\n\t\t\tconst raw = readMemory();\n\t\t\tconst cap = readCap();\n\t\t\tif (!raw.trim()) {\n\t\t\t\treturn { content: [{ type: \"text\", text: `Memory is empty (0/${cap} chars).` }] };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{ type: \"text\", text: `Memory (${raw.length}/${cap} chars):\\n${raw.trimEnd()}` },\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t});\n\n\t// --- /memory-char-cap command ---\n\tpi.registerCommand(\"memory-char-cap\", {\n\t\tdescription: \"View or set the memory character cap (1..30000). Default 5000.\",\n\t\thandler(args, ctx) {\n\t\t\tconst trimmed = args.trim();\n\t\t\tif (!trimmed) {\n\t\t\t\tctx.ui.notify(`Memory character cap: ${readCap()}`, \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst n = Number(trimmed);\n\t\t\tif (!Number.isFinite(n) || !Number.isInteger(n) || n < MIN_CHAR_CAP || n > MAX_CHAR_CAP) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Invalid cap. Must be an integer between ${MIN_CHAR_CAP} and ${MAX_CHAR_CAP}.`,\n\t\t\t\t\t\"error\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (n < readMemory().length) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Your memory file already exceeds this character cap: ${memoryFile()}`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\twriteCap(n);\n\t\t\tctx.ui.notify(`Memory character cap set to ${n}.`, \"info\");\n\t\t},\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"install-cli.d.ts","sourceRoot":"","sources":["../../src/cli/install-cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAON,KAAK,mBAAmB,EAKxB,MAAM,6BAA6B,CAAC;AA4RrC;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAyBvE;AAED,YAAY,EAAE,mBAAmB,EAAE,CAAC","sourcesContent":["/**\n * Product install CLI: setup / features / uninstall (no source).\n * Intercepted before handlePackageCommand so `lunr uninstall` (no source)\n * is product uninstall and `lunr uninstall <source>` stays package-remove.\n */\n\nimport { existsSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { createInterface } from \"node:readline\";\nimport { APP_NAME, getAgentDir, NPM_CLI_PACKAGE, VERSION } from \"../config.ts\";\nimport {\n\tappendInstallLog,\n\tapplyFeatureFlags,\n\tFEATURE_CATALOG,\n\tFEATURE_HANDLERS,\n\ttype FeatureId,\n\tgetFeatureSpec,\n\ttype InstallFeaturesFile,\n\tisProductUninstallArgv,\n\tloadInstallFeatures,\n\tparseFeatureFlags,\n\tsaveInstallFeatures,\n} from \"../core/install-features.ts\";\nimport { loadInstallLayout, resolveInstallPrefix } from \"../core/install-layout.ts\";\nimport { loadGatewayConfig } from \"../gateway/config.ts\";\nimport { readSecret } from \"./read-secret.ts\";\n\nfunction printSetupHelp(): void {\n\tconsole.log(`${APP_NAME} setup [--yes] [--feature <id>] [--no-feature <id>] [--set <id.option>=<value>] [--reconfigure]\n\nFirst-run / reconfigure optional features.\n\n${APP_NAME} features list\n${APP_NAME} features enable <id> [--set <id.option>=<value>]...\n${APP_NAME} features disable <id> [--purge-secrets]\n${APP_NAME} uninstall [--purge] [--yes] Remove this ${APP_NAME} install (keeps agent dir unless --purge)\n${APP_NAME} uninstall <source> [-l] Remove an extension package (alias for remove)\n`);\n}\n\nfunction printFeaturesHelp(): void {\n\tconsole.log(`${APP_NAME} features list\n${APP_NAME} features enable <id> [--set <id.option>=<value>]...\n${APP_NAME} features disable <id> [--purge-secrets]\n`);\n}\n\nasync function askYesNo(prompt: string, defaultYes: boolean): Promise<boolean> {\n\tif (!process.stdin.isTTY) return defaultYes;\n\tconst rl = createInterface({ input: process.stdin, output: process.stdout });\n\tconst suffix = defaultYes ? \"[Y/n]\" : \"[y/N]\";\n\tconst answer = await new Promise<string>((resolve) => {\n\t\trl.question(`${prompt} ${suffix} `, resolve);\n\t});\n\trl.close();\n\tconst trimmed = answer.trim().toLowerCase();\n\tif (trimmed === \"\") return defaultYes;\n\treturn trimmed === \"y\" || trimmed === \"yes\";\n}\n\nfunction fileTokenAlreadySet(optionId: string): boolean {\n\tconst cfg = loadGatewayConfig();\n\tif (optionId === \"telegram-token\") return Boolean(cfg.telegram.token);\n\tif (optionId === \"discord-token\") return Boolean(cfg.discord.token);\n\treturn false;\n}\n\nasync function collectSecretsForFeature(id: FeatureId, secrets: Record<string, string>): Promise<void> {\n\tconst spec = getFeatureSpec(id);\n\tif (!spec) return;\n\tfor (const option of spec.options) {\n\t\tif (option.type !== \"secret\") continue;\n\t\tif (fileTokenAlreadySet(option.id)) {\n\t\t\tconsole.log(` ${option.id}: token already set`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst value = await readSecret(option.prompt);\n\t\tif (value) secrets[option.id] = value;\n\t}\n}\n\nasync function runSetup(argv: string[]): Promise<number> {\n\tconst parsed = parseFeatureFlags(argv);\n\tif (!parsed.ok) {\n\t\tconsole.error(parsed.error);\n\t\tprintSetupHelp();\n\t\treturn 2;\n\t}\n\tif (!parsed.yes && !process.stdin.isTTY) {\n\t\tconsole.error(\"non-interactive setup requires --yes\");\n\t\tprintSetupHelp();\n\t\treturn 2;\n\t}\n\n\tconst current = loadInstallFeatures();\n\tlet next = current;\n\n\tif (parsed.yes) {\n\t\tconst applied = applyFeatureFlags(current, parsed);\n\t\tif (!applied.ok) {\n\t\t\tconsole.error(applied.error);\n\t\t\treturn applied.exitCode;\n\t\t}\n\t\tnext = applied.next;\n\t\tfor (const id of applied.enabledIds) {\n\t\t\tconst prev = current.features[id];\n\t\t\tconst state = next.features[id];\n\t\t\tif (state) {\n\t\t\t\tawait FEATURE_HANDLERS[id].apply({\n\t\t\t\t\tprevious: prev,\n\t\t\t\t\tnext: state,\n\t\t\t\t\tsecrets: applied.secrets,\n\t\t\t\t\tnonInteractive: true,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tfor (const id of applied.disabledIds) {\n\t\t\tawait FEATURE_HANDLERS[id].disable({ purgeSecrets: false });\n\t\t}\n\t} else {\n\t\tawait (await import(\"../gateway/setup.ts\")).setupGateway();\n\t\treturn 0;\n\t}\n\n\tconst { installBrowser } = await import(\"../core/browser/setup.ts\");\n\tawait installBrowser(false);\n\tsaveInstallFeatures(next);\n\tappendInstallLog(`setup installerVersion=${VERSION}`);\n\tconsole.log(`Writing ${getAgentDir()}/install-features.json`);\n\tconsole.log(\"\\nNext:\");\n\tconsole.log(` 1. Restart this shell (or add ${resolveInstallPrefix()}/bin to PATH)`);\n\tconsole.log(` 2. Run: ${APP_NAME}`);\n\tconsole.log(\" 3. In the TUI: /login\");\n\treturn 0;\n}\n\nasync function runFeatures(argv: string[]): Promise<number> {\n\tconst [sub, ...rest] = argv;\n\tif (!sub || sub === \"list\") {\n\t\tconst file = loadInstallFeatures();\n\t\tfor (const spec of FEATURE_CATALOG) {\n\t\t\tconst enabled = file.features[spec.id]?.enabled ?? spec.defaultEnabled;\n\t\t\tconsole.log(`${spec.id}: ${enabled ? \"enabled\" : \"disabled\"} — ${spec.summary}`);\n\t\t}\n\t\treturn 0;\n\t}\n\tif (sub === \"enable\") {\n\t\tconst id = rest[0];\n\t\tif (!id || !getFeatureSpec(id)) {\n\t\t\tconsole.error(id ? `unknown feature ${id}` : \"features enable requires an id\");\n\t\t\tprintFeaturesHelp();\n\t\t\treturn 2;\n\t\t}\n\t\tconst flagArgv = [\"--feature\", id, ...rest.slice(1)];\n\t\tconst parsed = parseFeatureFlags(flagArgv);\n\t\tif (!parsed.ok) {\n\t\t\tconsole.error(parsed.error);\n\t\t\treturn 2;\n\t\t}\n\t\tif (!parsed.yes && !process.stdin.isTTY && rest.slice(1).length === 0) {\n\t\t\t// --yes not required: enable with catalog defaults when non-interactive\n\t\t}\n\t\tconst current = loadInstallFeatures();\n\t\tconst applied = applyFeatureFlags(current, parsed);\n\t\tif (!applied.ok) {\n\t\t\tconsole.error(applied.error);\n\t\t\treturn applied.exitCode;\n\t\t}\n\t\tconst secrets: Record<string, string> = { ...applied.secrets };\n\t\tif (process.stdin.isTTY && !parsed.yes) {\n\t\t\tconst spec = getFeatureSpec(id);\n\t\t\tif (spec) {\n\t\t\t\tfor (const option of spec.options) {\n\t\t\t\t\tif (option.type !== \"boolean\") continue;\n\t\t\t\t\tif (applied.next.features[id]?.options[option.id] !== undefined) continue;\n\t\t\t\t\tconst currentBool =\n\t\t\t\t\t\ttypeof current.features[id]?.options[option.id] === \"boolean\"\n\t\t\t\t\t\t\t? (current.features[id].options[option.id] as boolean)\n\t\t\t\t\t\t\t: (option.default ?? false);\n\t\t\t\t\tconst value = await askYesNo(` ${option.prompt}`, currentBool);\n\t\t\t\t\tconst state = applied.next.features[id] ?? { enabled: true, options: {} };\n\t\t\t\t\tstate.options[option.id] = value;\n\t\t\t\t\tapplied.next.features[id] = state;\n\t\t\t\t}\n\t\t\t\tawait collectSecretsForFeature(id as FeatureId, secrets);\n\t\t\t}\n\t\t}\n\t\tconst state = applied.next.features[id];\n\t\tif (state) {\n\t\t\tawait FEATURE_HANDLERS[id as FeatureId].apply({\n\t\t\t\tprevious: current.features[id],\n\t\t\t\tnext: state,\n\t\t\t\tsecrets,\n\t\t\t\tnonInteractive: parsed.yes || !process.stdin.isTTY,\n\t\t\t});\n\t\t}\n\t\tsaveInstallFeatures(applied.next);\n\t\tappendInstallLog(`features enable ${id}`);\n\t\tconsole.log(`enabled ${id}`);\n\t\treturn 0;\n\t}\n\tif (sub === \"disable\") {\n\t\tconst id = rest[0];\n\t\tif (!id || !getFeatureSpec(id)) {\n\t\t\tconsole.error(id ? `unknown feature ${id}` : \"features disable requires an id\");\n\t\t\tprintFeaturesHelp();\n\t\t\treturn 2;\n\t\t}\n\t\tconst purgeSecrets = rest.includes(\"--purge-secrets\");\n\t\tconst current = loadInstallFeatures();\n\t\tconst prev = current.features[id];\n\t\tcurrent.features[id] = { enabled: false, options: { ...prev?.options } };\n\t\tcurrent.updatedAt = new Date().toISOString();\n\t\tawait FEATURE_HANDLERS[id as FeatureId].disable({ purgeSecrets });\n\t\tsaveInstallFeatures(current);\n\t\tappendInstallLog(`features disable ${id}`);\n\t\tconsole.log(`disabled ${id}`);\n\t\treturn 0;\n\t}\n\tif (sub === \"--help\" || sub === \"-h\") {\n\t\tprintFeaturesHelp();\n\t\treturn 0;\n\t}\n\tconsole.error(`unknown features subcommand ${sub}`);\n\tprintFeaturesHelp();\n\treturn 2;\n}\n\nfunction parseUninstallFlags(argv: string[]): { purge: boolean; yes: boolean } {\n\treturn {\n\t\tpurge: argv.includes(\"--purge\"),\n\t\tyes: argv.includes(\"--yes\") || argv.includes(\"-y\"),\n\t};\n}\n\nfunction isBinaryLayoutInstall(): boolean {\n\treturn loadInstallLayout() !== undefined;\n}\n\nasync function runProductUninstall(argv: string[]): Promise<number> {\n\tconst { purge, yes } = parseUninstallFlags(argv);\n\tconst agentDir = getAgentDir();\n\n\tif (!isBinaryLayoutInstall()) {\n\t\tconsole.log(`This looks like an npm install. Remove the CLI with:`);\n\t\tconsole.log(` npm rm -g ${NPM_CLI_PACKAGE}`);\n\t\tif (purge) {\n\t\t\tif (!yes && !process.stdin.isTTY) {\n\t\t\t\tconsole.error(\"non-interactive --purge requires --yes\");\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\tif (!yes) {\n\t\t\t\tconst ok = await askYesNo(`Also delete ${agentDir}? This cannot be undone.`, false);\n\t\t\t\tif (!ok) {\n\t\t\t\t\tconsole.log(\"aborted\");\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (existsSync(agentDir)) rmSync(agentDir, { recursive: true, force: true });\n\t\t\tconsole.log(`purged ${agentDir}`);\n\t\t} else {\n\t\t\tconsole.log(`sessions, auth, and gateway config kept in ${agentDir}`);\n\t\t\tconsole.log(`Add --purge to delete that directory.`);\n\t\t}\n\t\tappendInstallLog(`uninstall npm purge=${purge}`);\n\t\treturn 0;\n\t}\n\n\tconst prefix = resolveInstallPrefix();\n\n\tif (purge && !yes) {\n\t\tif (!process.stdin.isTTY) {\n\t\t\tconsole.error(\"non-interactive --purge requires --yes\");\n\t\t\treturn 2;\n\t\t}\n\t\tconst ok = await askYesNo(`Delete ${prefix} and ${agentDir}? This cannot be undone.`, false);\n\t\tif (!ok) {\n\t\t\tconsole.log(\"aborted\");\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\tconst versions = join(prefix, \"versions\");\n\tconst bin = join(prefix, \"bin\");\n\tif (existsSync(versions)) rmSync(versions, { recursive: true, force: true });\n\tif (existsSync(bin)) rmSync(bin, { recursive: true, force: true });\n\tconsole.log(`removed ${versions} and ${bin}`);\n\n\tif (purge) {\n\t\tif (existsSync(agentDir)) rmSync(agentDir, { recursive: true, force: true });\n\t\tif (existsSync(prefix)) {\n\t\t\ttry {\n\t\t\t\trmSync(prefix, { recursive: true, force: true });\n\t\t\t} catch {\n\t\t\t\t// prefix may still hold unrelated files\n\t\t\t}\n\t\t}\n\t\tconsole.log(`purged ${agentDir}`);\n\t} else {\n\t\tconsole.log(`sessions, auth, and gateway config kept in ${agentDir}`);\n\t}\n\tconsole.log(\"Remove the PATH line from your shell profile if you added one.\");\n\tappendInstallLog(`uninstall purge=${purge}`);\n\treturn 0;\n}\n\n/**\n * Returns true when this argv was an install-cli verb that we handled.\n * `uninstall <source>` and package-manager flags are not claimed.\n */\nexport async function handleInstallCli(args: string[]): Promise<boolean> {\n\tconst [verb, ...rest] = args;\n\tif (verb === \"browser\") {\n\t\tif (rest.length !== 1 || rest[0] !== \"install\") {\n\t\t\tconsole.error(\"Usage: lunr browser install. Browser on/off is in /settings.\");\n\t\t\tprocess.exitCode = 2;\n\t\t} else {\n\t\t\tconst { installBrowser } = await import(\"../core/browser/setup.ts\");\n\t\t\tawait installBrowser();\n\t\t}\n\t\treturn true;\n\t}\n\tif (verb === \"setup\") {\n\t\tprocess.exitCode = await runSetup(rest);\n\t\treturn true;\n\t}\n\tif (verb === \"features\") {\n\t\tprocess.exitCode = await runFeatures(rest);\n\t\treturn true;\n\t}\n\tif (verb === \"uninstall\" && isProductUninstallArgv(rest)) {\n\t\tprocess.exitCode = await runProductUninstall(rest);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nexport type { InstallFeaturesFile };\n"]}
1
+ {"version":3,"file":"install-cli.d.ts","sourceRoot":"","sources":["../../src/cli/install-cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAON,KAAK,mBAAmB,EAKxB,MAAM,6BAA6B,CAAC;AA6RrC;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAyBvE;AAED,YAAY,EAAE,mBAAmB,EAAE,CAAC","sourcesContent":["/**\n * Product install CLI: setup / features / uninstall (no source).\n * Intercepted before handlePackageCommand so `lunr uninstall` (no source)\n * is product uninstall and `lunr uninstall <source>` stays package-remove.\n */\n\nimport { existsSync, rmdirSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { createInterface } from \"node:readline\";\nimport { APP_NAME, getAgentDir, NPM_CLI_PACKAGE, VERSION } from \"../config.ts\";\nimport {\n\tappendInstallLog,\n\tapplyFeatureFlags,\n\tFEATURE_CATALOG,\n\tFEATURE_HANDLERS,\n\ttype FeatureId,\n\tgetFeatureSpec,\n\ttype InstallFeaturesFile,\n\tisProductUninstallArgv,\n\tloadInstallFeatures,\n\tparseFeatureFlags,\n\tsaveInstallFeatures,\n} from \"../core/install-features.ts\";\nimport { loadInstallLayout, resolveInstallPrefix } from \"../core/install-layout.ts\";\nimport { loadGatewayConfig } from \"../gateway/config.ts\";\nimport { readSecret } from \"./read-secret.ts\";\n\nfunction printSetupHelp(): void {\n\tconsole.log(`${APP_NAME} setup [--yes] [--feature <id>] [--no-feature <id>] [--set <id.option>=<value>] [--reconfigure]\n\nFirst-run / reconfigure optional features.\n\n${APP_NAME} features list\n${APP_NAME} features enable <id> [--set <id.option>=<value>]...\n${APP_NAME} features disable <id> [--purge-secrets]\n${APP_NAME} uninstall [--purge] [--yes] Remove this ${APP_NAME} install (keeps agent dir unless --purge)\n${APP_NAME} uninstall <source> [-l] Remove an extension package (alias for remove)\n`);\n}\n\nfunction printFeaturesHelp(): void {\n\tconsole.log(`${APP_NAME} features list\n${APP_NAME} features enable <id> [--set <id.option>=<value>]...\n${APP_NAME} features disable <id> [--purge-secrets]\n`);\n}\n\nasync function askYesNo(prompt: string, defaultYes: boolean): Promise<boolean> {\n\tif (!process.stdin.isTTY) return defaultYes;\n\tconst rl = createInterface({ input: process.stdin, output: process.stdout });\n\tconst suffix = defaultYes ? \"[Y/n]\" : \"[y/N]\";\n\tconst answer = await new Promise<string>((resolve) => {\n\t\trl.question(`${prompt} ${suffix} `, resolve);\n\t});\n\trl.close();\n\tconst trimmed = answer.trim().toLowerCase();\n\tif (trimmed === \"\") return defaultYes;\n\treturn trimmed === \"y\" || trimmed === \"yes\";\n}\n\nfunction fileTokenAlreadySet(optionId: string): boolean {\n\tconst cfg = loadGatewayConfig();\n\tif (optionId === \"telegram-token\") return Boolean(cfg.telegram.token);\n\tif (optionId === \"discord-token\") return Boolean(cfg.discord.token);\n\treturn false;\n}\n\nasync function collectSecretsForFeature(id: FeatureId, secrets: Record<string, string>): Promise<void> {\n\tconst spec = getFeatureSpec(id);\n\tif (!spec) return;\n\tfor (const option of spec.options) {\n\t\tif (option.type !== \"secret\") continue;\n\t\tif (fileTokenAlreadySet(option.id)) {\n\t\t\tconsole.log(` ${option.id}: token already set`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst value = await readSecret(option.prompt);\n\t\tif (value) secrets[option.id] = value;\n\t}\n}\n\nasync function runSetup(argv: string[]): Promise<number> {\n\tconst parsed = parseFeatureFlags(argv);\n\tif (!parsed.ok) {\n\t\tconsole.error(parsed.error);\n\t\tprintSetupHelp();\n\t\treturn 2;\n\t}\n\tif (!parsed.yes && !process.stdin.isTTY) {\n\t\tconsole.error(\"non-interactive setup requires --yes\");\n\t\tprintSetupHelp();\n\t\treturn 2;\n\t}\n\n\tconst current = loadInstallFeatures();\n\tconst applied = applyFeatureFlags(current, parsed);\n\tif (!applied.ok) {\n\t\tconsole.error(applied.error);\n\t\treturn applied.exitCode;\n\t}\n\tconst explicitFeatures = parsed.features.length > 0 || parsed.noFeatures.length > 0 || parsed.sets.length > 0;\n\tconst { installBrowser } = await import(\"../core/browser/setup.ts\");\n\tawait installBrowser(false);\n\tlet next = applied.next;\n\tif (!parsed.yes && !explicitFeatures) {\n\t\tawait (await import(\"../gateway/setup.ts\")).setupGateway();\n\t\t// Gateway setup persists its own feature choices. Do not overwrite them.\n\t\tnext = loadInstallFeatures();\n\t} else {\n\t\tconst enabled = new Set([...applied.enabledIds, ...parsed.sets.map((set) => getFeatureSpec(set.id)?.id)]);\n\t\tfor (const id of enabled) {\n\t\t\tif (!id) continue;\n\t\t\tconst state = next.features[id];\n\t\t\tif (!state) continue;\n\t\t\tif (!parsed.yes) await collectSecretsForFeature(id, applied.secrets);\n\t\t\tawait FEATURE_HANDLERS[id].apply({\n\t\t\t\tprevious: current.features[id],\n\t\t\t\tnext: state,\n\t\t\t\tsecrets: applied.secrets,\n\t\t\t\tnonInteractive: parsed.yes,\n\t\t\t});\n\t\t}\n\t\tfor (const id of applied.disabledIds) await FEATURE_HANDLERS[id].disable({ purgeSecrets: false });\n\t}\n\n\tsaveInstallFeatures(next);\n\tappendInstallLog(`setup installerVersion=${VERSION}`);\n\tconsole.log(`Writing ${getAgentDir()}/install-features.json`);\n\tconsole.log(\"\\nNext:\");\n\tconsole.log(` 1. Restart this shell (or add ${resolveInstallPrefix()}/bin to PATH)`);\n\tconsole.log(` 2. Run: ${APP_NAME}`);\n\tconsole.log(\" 3. In the TUI: /login\");\n\treturn 0;\n}\n\nasync function runFeatures(argv: string[]): Promise<number> {\n\tconst [sub, ...rest] = argv;\n\tif (!sub || sub === \"list\") {\n\t\tconst file = loadInstallFeatures();\n\t\tfor (const spec of FEATURE_CATALOG) {\n\t\t\tconst enabled = file.features[spec.id]?.enabled ?? spec.defaultEnabled;\n\t\t\tconsole.log(`${spec.id}: ${enabled ? \"enabled\" : \"disabled\"} — ${spec.summary}`);\n\t\t}\n\t\treturn 0;\n\t}\n\tif (sub === \"enable\") {\n\t\tconst id = rest[0];\n\t\tif (!id || !getFeatureSpec(id)) {\n\t\t\tconsole.error(id ? `unknown feature ${id}` : \"features enable requires an id\");\n\t\t\tprintFeaturesHelp();\n\t\t\treturn 2;\n\t\t}\n\t\tconst flagArgv = [\"--feature\", id, ...rest.slice(1)];\n\t\tconst parsed = parseFeatureFlags(flagArgv);\n\t\tif (!parsed.ok) {\n\t\t\tconsole.error(parsed.error);\n\t\t\treturn 2;\n\t\t}\n\t\tif (!parsed.yes && !process.stdin.isTTY && rest.slice(1).length === 0) {\n\t\t\t// --yes not required: enable with catalog defaults when non-interactive\n\t\t}\n\t\tconst current = loadInstallFeatures();\n\t\tconst applied = applyFeatureFlags(current, parsed);\n\t\tif (!applied.ok) {\n\t\t\tconsole.error(applied.error);\n\t\t\treturn applied.exitCode;\n\t\t}\n\t\tconst secrets: Record<string, string> = { ...applied.secrets };\n\t\tif (process.stdin.isTTY && !parsed.yes) {\n\t\t\tconst spec = getFeatureSpec(id);\n\t\t\tif (spec) {\n\t\t\t\tfor (const option of spec.options) {\n\t\t\t\t\tif (option.type !== \"boolean\") continue;\n\t\t\t\t\tif (applied.next.features[id]?.options[option.id] !== undefined) continue;\n\t\t\t\t\tconst currentBool =\n\t\t\t\t\t\ttypeof current.features[id]?.options[option.id] === \"boolean\"\n\t\t\t\t\t\t\t? (current.features[id].options[option.id] as boolean)\n\t\t\t\t\t\t\t: (option.default ?? false);\n\t\t\t\t\tconst value = await askYesNo(` ${option.prompt}`, currentBool);\n\t\t\t\t\tconst state = applied.next.features[id] ?? { enabled: true, options: {} };\n\t\t\t\t\tstate.options[option.id] = value;\n\t\t\t\t\tapplied.next.features[id] = state;\n\t\t\t\t}\n\t\t\t\tawait collectSecretsForFeature(id as FeatureId, secrets);\n\t\t\t}\n\t\t}\n\t\tconst state = applied.next.features[id];\n\t\tif (state) {\n\t\t\tawait FEATURE_HANDLERS[id as FeatureId].apply({\n\t\t\t\tprevious: current.features[id],\n\t\t\t\tnext: state,\n\t\t\t\tsecrets,\n\t\t\t\tnonInteractive: parsed.yes || !process.stdin.isTTY,\n\t\t\t});\n\t\t}\n\t\tsaveInstallFeatures(applied.next);\n\t\tappendInstallLog(`features enable ${id}`);\n\t\tconsole.log(`enabled ${id}`);\n\t\treturn 0;\n\t}\n\tif (sub === \"disable\") {\n\t\tconst id = rest[0];\n\t\tif (!id || !getFeatureSpec(id)) {\n\t\t\tconsole.error(id ? `unknown feature ${id}` : \"features disable requires an id\");\n\t\t\tprintFeaturesHelp();\n\t\t\treturn 2;\n\t\t}\n\t\tconst purgeSecrets = rest.includes(\"--purge-secrets\");\n\t\tconst current = loadInstallFeatures();\n\t\tconst prev = current.features[id];\n\t\tcurrent.features[id] = { enabled: false, options: { ...prev?.options } };\n\t\tcurrent.updatedAt = new Date().toISOString();\n\t\tawait FEATURE_HANDLERS[id as FeatureId].disable({ purgeSecrets });\n\t\tsaveInstallFeatures(current);\n\t\tappendInstallLog(`features disable ${id}`);\n\t\tconsole.log(`disabled ${id}`);\n\t\treturn 0;\n\t}\n\tif (sub === \"--help\" || sub === \"-h\") {\n\t\tprintFeaturesHelp();\n\t\treturn 0;\n\t}\n\tconsole.error(`unknown features subcommand ${sub}`);\n\tprintFeaturesHelp();\n\treturn 2;\n}\n\nfunction parseUninstallFlags(argv: string[]): { purge: boolean; yes: boolean } {\n\treturn {\n\t\tpurge: argv.includes(\"--purge\"),\n\t\tyes: argv.includes(\"--yes\") || argv.includes(\"-y\"),\n\t};\n}\n\nfunction isBinaryLayoutInstall(): boolean {\n\treturn loadInstallLayout() !== undefined;\n}\n\nasync function runProductUninstall(argv: string[]): Promise<number> {\n\tconst { purge, yes } = parseUninstallFlags(argv);\n\tconst agentDir = getAgentDir();\n\n\tif (!isBinaryLayoutInstall()) {\n\t\tconsole.log(`This looks like an npm install. Remove the CLI with:`);\n\t\tconsole.log(` npm rm -g ${NPM_CLI_PACKAGE}`);\n\t\tif (purge) {\n\t\t\tif (!yes && !process.stdin.isTTY) {\n\t\t\t\tconsole.error(\"non-interactive --purge requires --yes\");\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\tif (!yes) {\n\t\t\t\tconst ok = await askYesNo(`Also delete ${agentDir}? This cannot be undone.`, false);\n\t\t\t\tif (!ok) {\n\t\t\t\t\tconsole.log(\"aborted\");\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait (await import(\"../gateway/service.ts\")).teardownGatewayService();\n\t\t\tif (existsSync(agentDir)) rmSync(agentDir, { recursive: true, force: true });\n\t\t\tconsole.log(`purged ${agentDir}`);\n\t\t} else {\n\t\t\tconsole.log(`sessions, auth, and gateway config kept in ${agentDir}`);\n\t\t\tconsole.log(`Add --purge to delete that directory.`);\n\t\t}\n\t\tif (!purge) appendInstallLog(\"uninstall npm purge=false\");\n\t\treturn 0;\n\t}\n\n\tconst prefix = resolveInstallPrefix();\n\n\tif (purge && !yes) {\n\t\tif (!process.stdin.isTTY) {\n\t\t\tconsole.error(\"non-interactive --purge requires --yes\");\n\t\t\treturn 2;\n\t\t}\n\t\tconst ok = await askYesNo(`Delete ${prefix} and ${agentDir}? This cannot be undone.`, false);\n\t\tif (!ok) {\n\t\t\tconsole.log(\"aborted\");\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\tawait (await import(\"../gateway/service.ts\")).teardownGatewayService();\n\tconst versions = join(prefix, \"versions\");\n\tconst bin = join(prefix, \"bin\");\n\tif (existsSync(versions)) rmSync(versions, { recursive: true, force: true });\n\tif (existsSync(bin)) rmSync(bin, { recursive: true, force: true });\n\tconsole.log(`removed ${versions} and ${bin}`);\n\n\tif (purge) {\n\t\tif (existsSync(agentDir)) rmSync(agentDir, { recursive: true, force: true });\n\t\tif (existsSync(prefix)) {\n\t\t\ttry {\n\t\t\t\trmdirSync(prefix);\n\t\t\t} catch {\n\t\t\t\t// prefix may still hold unrelated files\n\t\t\t}\n\t\t}\n\t\tconsole.log(`purged ${agentDir}`);\n\t} else {\n\t\tconsole.log(`sessions, auth, and gateway config kept in ${agentDir}`);\n\t}\n\tconsole.log(\"Remove the PATH line from your shell profile if you added one.\");\n\tif (!purge) appendInstallLog(\"uninstall purge=false\");\n\treturn 0;\n}\n\n/**\n * Returns true when this argv was an install-cli verb that we handled.\n * `uninstall <source>` and package-manager flags are not claimed.\n */\nexport async function handleInstallCli(args: string[]): Promise<boolean> {\n\tconst [verb, ...rest] = args;\n\tif (verb === \"browser\") {\n\t\tif (rest.length !== 1 || rest[0] !== \"install\") {\n\t\t\tconsole.error(\"Usage: lunr browser install. Browser on/off is in /settings.\");\n\t\t\tprocess.exitCode = 2;\n\t\t} else {\n\t\t\tconst { installBrowser } = await import(\"../core/browser/setup.ts\");\n\t\t\tawait installBrowser();\n\t\t}\n\t\treturn true;\n\t}\n\tif (verb === \"setup\") {\n\t\tprocess.exitCode = await runSetup(rest);\n\t\treturn true;\n\t}\n\tif (verb === \"features\") {\n\t\tprocess.exitCode = await runFeatures(rest);\n\t\treturn true;\n\t}\n\tif (verb === \"uninstall\" && isProductUninstallArgv(rest)) {\n\t\tprocess.exitCode = await runProductUninstall(rest);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nexport type { InstallFeaturesFile };\n"]}