@ashx-j/lunr 0.2.13 → 0.2.15

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 (335) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/README.md +10 -7
  3. package/dist/builtin-extensions/ashxj-tui.d.ts +16 -1
  4. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  5. package/dist/builtin-extensions/ashxj-tui.js +48 -24
  6. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  7. package/dist/builtin-extensions/index.d.ts.map +1 -1
  8. package/dist/builtin-extensions/index.js +2 -0
  9. package/dist/builtin-extensions/index.js.map +1 -1
  10. package/dist/builtin-extensions/lunr-settings-tools.d.ts +4 -0
  11. package/dist/builtin-extensions/lunr-settings-tools.d.ts.map +1 -0
  12. package/dist/builtin-extensions/lunr-settings-tools.js +120 -0
  13. package/dist/builtin-extensions/lunr-settings-tools.js.map +1 -0
  14. package/dist/builtin-extensions/pi-prompt-template-model/subagent-runtime.d.ts +2 -2
  15. package/dist/builtin-extensions/pi-prompt-template-model/subagent-runtime.d.ts.map +1 -1
  16. package/dist/builtin-extensions/pi-prompt-template-model/subagent-runtime.js.map +1 -1
  17. package/dist/builtin-extensions/pi-prompt-template-model/subagent-step.d.ts.map +1 -1
  18. package/dist/builtin-extensions/pi-prompt-template-model/subagent-step.js +3 -3
  19. package/dist/builtin-extensions/pi-prompt-template-model/subagent-step.js.map +1 -1
  20. package/dist/builtin-extensions/pi-subagents/src/api/delegation.d.ts +2 -2
  21. package/dist/builtin-extensions/pi-subagents/src/api/delegation.d.ts.map +1 -1
  22. package/dist/builtin-extensions/pi-subagents/src/api/delegation.js +1 -1
  23. package/dist/builtin-extensions/pi-subagents/src/api/delegation.js.map +1 -1
  24. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +2 -0
  25. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  26. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +29 -23
  27. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  28. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts +5 -11
  29. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  30. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +12 -15
  31. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  32. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +3 -3
  33. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  34. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +14 -27
  35. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  36. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
  37. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +9 -4
  38. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
  39. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.d.ts.map +1 -1
  40. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js +2 -1
  41. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js.map +1 -1
  42. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts.map +1 -1
  43. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js +16 -3
  44. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js.map +1 -1
  45. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.d.ts +1 -0
  46. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.d.ts.map +1 -1
  47. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.js +7 -4
  48. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-status.js.map +1 -1
  49. package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-append.d.ts.map +1 -1
  50. package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-append.js +1 -0
  51. package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-append.js.map +1 -1
  52. package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.d.ts.map +1 -1
  53. package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js +3 -0
  54. package/dist/builtin-extensions/pi-subagents/src/runs/background/chain-root-attachment.js.map +1 -1
  55. package/dist/builtin-extensions/pi-subagents/src/runs/background/fleet-view.d.ts.map +1 -1
  56. package/dist/builtin-extensions/pi-subagents/src/runs/background/fleet-view.js +3 -3
  57. package/dist/builtin-extensions/pi-subagents/src/runs/background/fleet-view.js.map +1 -1
  58. package/dist/builtin-extensions/pi-subagents/src/runs/background/run-status.d.ts.map +1 -1
  59. package/dist/builtin-extensions/pi-subagents/src/runs/background/run-status.js +2 -2
  60. package/dist/builtin-extensions/pi-subagents/src/runs/background/run-status.js.map +1 -1
  61. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  62. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +3 -0
  63. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  64. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-clarify.d.ts.map +1 -1
  65. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-clarify.js +3 -35
  66. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-clarify.js.map +1 -1
  67. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  68. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +7 -8
  69. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  70. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  71. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +2 -0
  72. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  73. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts +1 -0
  74. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  75. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +20 -21
  76. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  77. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +12 -1
  78. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  79. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +42 -17
  80. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  81. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +2 -0
  82. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
  83. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
  84. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts +2 -1
  85. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
  86. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +23 -1
  87. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
  88. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts +3 -1
  89. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts.map +1 -1
  90. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js +15 -4
  91. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js.map +1 -1
  92. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +14 -3
  93. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
  94. package/dist/builtin-extensions/pi-subagents/src/shared/types.js +1 -1
  95. package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
  96. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.d.ts +3 -3
  97. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.d.ts.map +1 -1
  98. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.js +7 -6
  99. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.js.map +1 -1
  100. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-request.d.ts.map +1 -1
  101. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-request.js +3 -3
  102. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-request.js.map +1 -1
  103. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts +1 -1
  104. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  105. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +6 -4
  106. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  107. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +1 -1
  108. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  109. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +15 -10
  110. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  111. package/dist/builtin-extensions/pi-subagents/src/tui/fleet.d.ts.map +1 -1
  112. package/dist/builtin-extensions/pi-subagents/src/tui/fleet.js +5 -4
  113. package/dist/builtin-extensions/pi-subagents/src/tui/fleet.js.map +1 -1
  114. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -2
  115. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  116. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +86 -52
  117. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  118. package/dist/catalog/models.json +1 -1
  119. package/dist/catalog/providers/amazon-bedrock.json +1 -1
  120. package/dist/catalog/providers/anthropic.json +1 -1
  121. package/dist/catalog/providers/azure-openai-responses.json +1 -1
  122. package/dist/catalog/providers/cloudflare-ai-gateway.json +1 -1
  123. package/dist/catalog/providers/fireworks.json +1 -1
  124. package/dist/catalog/providers/github-copilot.json +1 -1
  125. package/dist/catalog/providers/google-vertex.json +1 -1
  126. package/dist/catalog/providers/google.json +1 -1
  127. package/dist/catalog/providers/groq.json +1 -1
  128. package/dist/catalog/providers/huggingface.json +1 -1
  129. package/dist/catalog/providers/nvidia.json +1 -1
  130. package/dist/catalog/providers/openai-codex.json +1 -1
  131. package/dist/catalog/providers/openai.json +1 -1
  132. package/dist/catalog/providers/opencode-go.json +1 -1
  133. package/dist/catalog/providers/opencode.json +1 -1
  134. package/dist/catalog/providers/openrouter.json +1 -1
  135. package/dist/catalog/providers/vercel-ai-gateway.json +1 -1
  136. package/dist/catalog/publication.json +131 -3
  137. package/dist/cli/list-models.d.ts.map +1 -1
  138. package/dist/cli/list-models.js +1 -0
  139. package/dist/cli/list-models.js.map +1 -1
  140. package/dist/cli.d.ts.map +1 -1
  141. package/dist/cli.js +52 -27
  142. package/dist/cli.js.map +1 -1
  143. package/dist/core/agent-session-runtime.d.ts +5 -1
  144. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  145. package/dist/core/agent-session-runtime.js +7 -2
  146. package/dist/core/agent-session-runtime.js.map +1 -1
  147. package/dist/core/agent-session.d.ts +2 -0
  148. package/dist/core/agent-session.d.ts.map +1 -1
  149. package/dist/core/agent-session.js +18 -6
  150. package/dist/core/agent-session.js.map +1 -1
  151. package/dist/core/catalog-cache-scope.d.ts +3 -0
  152. package/dist/core/catalog-cache-scope.d.ts.map +1 -0
  153. package/dist/core/catalog-cache-scope.js +12 -0
  154. package/dist/core/catalog-cache-scope.js.map +1 -0
  155. package/dist/core/catalog-merge.d.ts +2 -0
  156. package/dist/core/catalog-merge.d.ts.map +1 -1
  157. package/dist/core/catalog-merge.js +29 -2
  158. package/dist/core/catalog-merge.js.map +1 -1
  159. package/dist/core/catalog-refresh-polling.d.ts +8 -0
  160. package/dist/core/catalog-refresh-polling.d.ts.map +1 -0
  161. package/dist/core/catalog-refresh-polling.js +30 -0
  162. package/dist/core/catalog-refresh-polling.js.map +1 -0
  163. package/dist/core/codex-catalog.d.ts +3 -0
  164. package/dist/core/codex-catalog.d.ts.map +1 -0
  165. package/dist/core/codex-catalog.js +15 -0
  166. package/dist/core/codex-catalog.js.map +1 -0
  167. package/dist/core/context-breakdown.d.ts +2 -0
  168. package/dist/core/context-breakdown.d.ts.map +1 -1
  169. package/dist/core/context-breakdown.js +6 -2
  170. package/dist/core/context-breakdown.js.map +1 -1
  171. package/dist/core/customize.d.ts +2 -4
  172. package/dist/core/customize.d.ts.map +1 -1
  173. package/dist/core/customize.js +2 -8
  174. package/dist/core/customize.js.map +1 -1
  175. package/dist/core/footer-data-provider.d.ts +3 -4
  176. package/dist/core/footer-data-provider.d.ts.map +1 -1
  177. package/dist/core/footer-data-provider.js +54 -82
  178. package/dist/core/footer-data-provider.js.map +1 -1
  179. package/dist/core/injected-prompt.d.ts +3 -3
  180. package/dist/core/injected-prompt.d.ts.map +1 -1
  181. package/dist/core/injected-prompt.js +2 -7
  182. package/dist/core/injected-prompt.js.map +1 -1
  183. package/dist/core/large-subagent-launch.d.ts +13 -0
  184. package/dist/core/large-subagent-launch.d.ts.map +1 -0
  185. package/dist/core/large-subagent-launch.js +54 -0
  186. package/dist/core/large-subagent-launch.js.map +1 -0
  187. package/dist/core/live-catalog.d.ts +5 -2
  188. package/dist/core/live-catalog.d.ts.map +1 -1
  189. package/dist/core/live-catalog.js +108 -27
  190. package/dist/core/live-catalog.js.map +1 -1
  191. package/dist/core/model-instructions.d.ts +24 -0
  192. package/dist/core/model-instructions.d.ts.map +1 -0
  193. package/dist/core/model-instructions.js +123 -0
  194. package/dist/core/model-instructions.js.map +1 -0
  195. package/dist/core/model-runtime.d.ts +8 -0
  196. package/dist/core/model-runtime.d.ts.map +1 -1
  197. package/dist/core/model-runtime.js +64 -12
  198. package/dist/core/model-runtime.js.map +1 -1
  199. package/dist/core/official-catalog.d.ts +4 -0
  200. package/dist/core/official-catalog.d.ts.map +1 -1
  201. package/dist/core/official-catalog.js +86 -21
  202. package/dist/core/official-catalog.js.map +1 -1
  203. package/dist/core/permissions.d.ts +10 -11
  204. package/dist/core/permissions.d.ts.map +1 -1
  205. package/dist/core/permissions.js +107 -40
  206. package/dist/core/permissions.js.map +1 -1
  207. package/dist/core/plan-mode.d.ts.map +1 -1
  208. package/dist/core/plan-mode.js +10 -1
  209. package/dist/core/plan-mode.js.map +1 -1
  210. package/dist/core/resource-loader.d.ts +3 -0
  211. package/dist/core/resource-loader.d.ts.map +1 -1
  212. package/dist/core/resource-loader.js +13 -4
  213. package/dist/core/resource-loader.js.map +1 -1
  214. package/dist/core/runtime-bridges.d.ts +4 -0
  215. package/dist/core/runtime-bridges.d.ts.map +1 -0
  216. package/dist/core/runtime-bridges.js +16 -0
  217. package/dist/core/runtime-bridges.js.map +1 -0
  218. package/dist/core/sdk.d.ts.map +1 -1
  219. package/dist/core/sdk.js +1 -0
  220. package/dist/core/sdk.js.map +1 -1
  221. package/dist/core/settings-manager.d.ts +13 -6
  222. package/dist/core/settings-manager.d.ts.map +1 -1
  223. package/dist/core/settings-manager.js +32 -17
  224. package/dist/core/settings-manager.js.map +1 -1
  225. package/dist/core/settings-tools-bridge.d.ts +35 -0
  226. package/dist/core/settings-tools-bridge.d.ts.map +1 -0
  227. package/dist/core/settings-tools-bridge.js +56 -0
  228. package/dist/core/settings-tools-bridge.js.map +1 -0
  229. package/dist/core/slash-commands.d.ts.map +1 -1
  230. package/dist/core/slash-commands.js +1 -1
  231. package/dist/core/slash-commands.js.map +1 -1
  232. package/dist/core/system-prompt.d.ts.map +1 -1
  233. package/dist/core/system-prompt.js +1 -1
  234. package/dist/core/system-prompt.js.map +1 -1
  235. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  236. package/dist/gateway/agent-bridge.js +3 -2
  237. package/dist/gateway/agent-bridge.js.map +1 -1
  238. package/dist/gateway/approval.d.ts.map +1 -1
  239. package/dist/gateway/approval.js +4 -3
  240. package/dist/gateway/approval.js.map +1 -1
  241. package/dist/gateway/commands.d.ts +1 -1
  242. package/dist/gateway/commands.d.ts.map +1 -1
  243. package/dist/gateway/commands.js +1 -18
  244. package/dist/gateway/commands.js.map +1 -1
  245. package/dist/gateway/cron.d.ts.map +1 -1
  246. package/dist/gateway/cron.js +3 -2
  247. package/dist/gateway/cron.js.map +1 -1
  248. package/dist/gateway/router.d.ts +1 -1
  249. package/dist/gateway/router.d.ts.map +1 -1
  250. package/dist/gateway/router.js +1 -1
  251. package/dist/gateway/router.js.map +1 -1
  252. package/dist/main.d.ts +2 -0
  253. package/dist/main.d.ts.map +1 -1
  254. package/dist/main.js +108 -58
  255. package/dist/main.js.map +1 -1
  256. package/dist/migrations.d.ts +2 -0
  257. package/dist/migrations.d.ts.map +1 -1
  258. package/dist/migrations.js +18 -4
  259. package/dist/migrations.js.map +1 -1
  260. package/dist/modes/interactive/components/assistant-message.d.ts +1 -3
  261. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  262. package/dist/modes/interactive/components/assistant-message.js +4 -32
  263. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  264. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  265. package/dist/modes/interactive/components/custom-editor.js +2 -1
  266. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  267. package/dist/modes/interactive/components/injected-prompt-message.d.ts +1 -1
  268. package/dist/modes/interactive/components/injected-prompt-message.d.ts.map +1 -1
  269. package/dist/modes/interactive/components/injected-prompt-message.js +1 -1
  270. package/dist/modes/interactive/components/injected-prompt-message.js.map +1 -1
  271. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  272. package/dist/modes/interactive/components/model-selector.js +4 -1
  273. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  274. package/dist/modes/interactive/components/plan-message.d.ts +1 -3
  275. package/dist/modes/interactive/components/plan-message.d.ts.map +1 -1
  276. package/dist/modes/interactive/components/plan-message.js +1 -16
  277. package/dist/modes/interactive/components/plan-message.js.map +1 -1
  278. package/dist/modes/interactive/components/settings-selector.d.ts +8 -5
  279. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  280. package/dist/modes/interactive/components/settings-selector.js +71 -31
  281. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  282. package/dist/modes/interactive/components/user-message.d.ts +1 -3
  283. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  284. package/dist/modes/interactive/components/user-message.js +2 -19
  285. package/dist/modes/interactive/components/user-message.js.map +1 -1
  286. package/dist/modes/interactive/interactive-mode.d.ts +13 -4
  287. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  288. package/dist/modes/interactive/interactive-mode.js +163 -177
  289. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  290. package/dist/modes/interactive/theme/moon.json +0 -1
  291. package/dist/modes/interactive/theme/theme-schema.json +3 -3
  292. package/dist/modes/interactive/theme/theme.d.ts +1 -1
  293. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  294. package/dist/modes/interactive/theme/theme.js +95 -90
  295. package/dist/modes/interactive/theme/theme.js.map +1 -1
  296. package/dist/startup/interactive-view.d.ts +55 -0
  297. package/dist/startup/interactive-view.d.ts.map +1 -0
  298. package/dist/startup/interactive-view.js +332 -0
  299. package/dist/startup/interactive-view.js.map +1 -0
  300. package/dist/startup/launch-routing.d.ts +8 -0
  301. package/dist/startup/launch-routing.d.ts.map +1 -0
  302. package/dist/startup/launch-routing.js +29 -0
  303. package/dist/startup/launch-routing.js.map +1 -0
  304. package/dist/startup/startup-milestones.d.ts +4 -0
  305. package/dist/startup/startup-milestones.d.ts.map +1 -0
  306. package/dist/startup/startup-milestones.js +14 -0
  307. package/dist/startup/startup-milestones.js.map +1 -0
  308. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  309. package/dist/utils/syntax-highlight.js +10 -4
  310. package/dist/utils/syntax-highlight.js.map +1 -1
  311. package/docs/features.md +9 -9
  312. package/docs/interactive-startup.md +58 -0
  313. package/docs/keybindings.md +1 -1
  314. package/docs/model-catalog.md +29 -0
  315. package/docs/quickstart.md +3 -2
  316. package/docs/settings.md +4 -4
  317. package/docs/terminal-setup.md +2 -2
  318. package/docs/termux.md +1 -1
  319. package/docs/usage.md +4 -3
  320. package/docs/windows.md +1 -1
  321. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  322. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  323. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  324. package/examples/extensions/gondolin/package-lock.json +2 -2
  325. package/examples/extensions/gondolin/package.json +1 -1
  326. package/examples/extensions/sandbox/package-lock.json +2 -2
  327. package/examples/extensions/sandbox/package.json +1 -1
  328. package/examples/extensions/subagent/README.md +1 -1
  329. package/examples/extensions/with-deps/package-lock.json +2 -2
  330. package/examples/extensions/with-deps/package.json +1 -1
  331. package/package.json +16 -16
  332. package/dist/core/swarm.d.ts +0 -54
  333. package/dist/core/swarm.d.ts.map +0 -1
  334. package/dist/core/swarm.js +0 -119
  335. package/dist/core/swarm.js.map +0 -1
@@ -15,15 +15,16 @@ import { parseSkillBlock } from "../../core/agent-session.js";
15
15
  import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
16
16
  import { CACHE_TTL_MS, collectCacheMisses, computeCacheWaste, detectCacheMiss, } from "../../core/cache-stats.js";
17
17
  import { formatCatalogRefreshSummary } from "../../core/catalog-merge.js";
18
+ import { startCatalogRefreshPolling } from "../../core/catalog-refresh-polling.js";
18
19
  import { computeContextBreakdown } from "../../core/context-breakdown.js";
19
20
  import { FooterDataProvider } from "../../core/footer-data-provider.js";
20
21
  import { hasGrokCliXaiAuth } from "../../core/grok-cli-auth.js";
21
22
  import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
22
23
  import { detectInjectedPrompt } from "../../core/injected-prompt.js";
23
24
  import { KeybindingsManager } from "../../core/keybindings.js";
24
- import { applyIncompleteAnswers, describeIncomplete, INCOMPLETE_PROMPT_CAP, parsePositiveInt, } from "../../core/live-catalog.js";
25
25
  import { createCompactionSummaryMessage } from "../../core/messages.js";
26
26
  import { isValidProviderBaseUrl, parseModelIds, slugifyProviderId, upsertCustomProvider, } from "../../core/model-config-writer.js";
27
+ import { getGlobalInstructionsPath, getModelInstructionsPath } from "../../core/model-instructions.js";
27
28
  import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScope } from "../../core/model-resolver.js";
28
29
  import { refreshModelCandidatesForInit } from "../../core/model-runtime.js";
29
30
  import { getModelTiersBridge } from "../../core/model-tiers.js";
@@ -37,13 +38,11 @@ import { getSearchCuratorSetting, setSearchCuratorSetting } from "../../core/sea
37
38
  import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
38
39
  import { SessionManager, sessionEntryToContextMessages } from "../../core/session-manager.js";
39
40
  import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
40
- // lunr: moved to core/swarm.ts so the gateway can reuse it.
41
- import { buildSwarmPrompt } from "../../core/swarm.js";
42
41
  import { time } from "../../core/timings.js";
43
42
  import { hasTrustRequiringProjectResources, ProjectTrustStore } from "../../core/trust-manager.js";
44
43
  import { checkForUpdate, markUpdateNotified } from "../../core/update-check.js";
45
44
  import { getAllPlanUsageResults, getUsageServiceBridge } from "../../core/usage-service.js";
46
- import { modelToUserEntry } from "../../core/user-models.js";
45
+ import { markStartupMilestone } from "../../startup/startup-milestones.js";
47
46
  import { copyToClipboard, readClipboardText } from "../../utils/clipboard.js";
48
47
  import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
49
48
  import { parseGitUrl } from "../../utils/git.js";
@@ -199,6 +198,11 @@ function formatLoginProviderCompletionDescription(provider) {
199
198
  const authTypes = provider.authTypes.map(formatAuthSelectorProviderType).join("/");
200
199
  return provider.name === provider.id ? authTypes : `${provider.name} · ${authTypes}`;
201
200
  }
201
+ export async function startInteractiveToolInstalls(currentFdPath, onFdInstalled, installer = ensureTool) {
202
+ const [fdPath] = await Promise.all([installer("fd", true), installer("rg", true)]);
203
+ if (fdPath && fdPath !== currentFdPath)
204
+ onFdInstalled(fdPath);
205
+ }
202
206
  export class InteractiveMode {
203
207
  runtimeHost;
204
208
  ui;
@@ -219,6 +223,7 @@ export class InteractiveMode {
219
223
  keybindings;
220
224
  version;
221
225
  isInitialized = false;
226
+ stopCatalogRefresh;
222
227
  onInputCallback;
223
228
  pendingUserInputs = [];
224
229
  stagedSubmitImages;
@@ -266,8 +271,6 @@ export class InteractiveMode {
266
271
  signalCleanupHandlers = [];
267
272
  // Track if editor is in bash mode (text starts with !)
268
273
  isBashMode = false;
269
- // Track whether a /swarm orchestration turn is in flight (footer status)
270
- swarmMode = false;
271
274
  // lunr: mode in effect before the current plan stretch. Used by approve / `/plan off`
272
275
  // / `/plan <text>` to leave plan. Shift+Tab and `/mode` pick the destination themselves.
273
276
  previousPermissionMode;
@@ -313,6 +316,8 @@ export class InteractiveMode {
313
316
  autoTrustOnReloadCwd;
314
317
  themeController;
315
318
  deferredBuiltinsAttached = false;
319
+ startupReadyPromise;
320
+ startupFeatureError;
316
321
  deferredBuiltinAttachPromise;
317
322
  // Convenience accessors
318
323
  get session() {
@@ -353,7 +358,7 @@ export class InteractiveMode {
353
358
  this.syncPermissionModeEffects(this.settingsManager.getDefaultPermissionMode());
354
359
  });
355
360
  this.version = VERSION;
356
- this.ui = new TUI(new ProcessTerminal(), this.settingsManager.getShowHardwareCursor());
361
+ this.ui = options.startupView?.ui ?? new TUI(new ProcessTerminal(), this.settingsManager.getShowHardwareCursor());
357
362
  this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
358
363
  // lunr: register the permission-mode footer bridge (provider-side: InteractiveMode owns the state).
359
364
  registerPermissionModeBridge(() => getPermissionMode());
@@ -364,21 +369,29 @@ export class InteractiveMode {
364
369
  // lunr: reset permission mode to configured default on startup.
365
370
  resetPermissions(this.settingsManager.getDefaultPermissionMode());
366
371
  this.headerContainer = new Container();
372
+ if (options.startupView) {
373
+ this.headerContainer.addChild(new Spacer(1));
374
+ this.headerContainer.addChild(options.startupView.header);
375
+ this.customFooter = options.startupView.footer;
376
+ }
367
377
  this.loadedResourcesContainer = new Container();
368
378
  this.chatContainer = new Container();
369
379
  this.pendingMessagesContainer = new Container();
370
- this.statusContainer = new Container();
380
+ this.statusContainer = options.startupView?.statusContainer ?? new Container();
371
381
  this.widgetContainerAbove = new Container();
372
382
  this.widgetContainerBelow = new Container();
373
- this.keybindings = KeybindingsManager.create();
383
+ this.keybindings = options.startupView?.keybindings ?? KeybindingsManager.create();
374
384
  setKeybindings(this.keybindings);
375
385
  const editorPaddingX = this.settingsManager.getEditorPaddingX();
376
386
  const autocompleteMaxVisible = this.settingsManager.getAutocompleteMaxVisible();
377
- this.defaultEditor = new CustomEditor(this.ui, getEditorTheme(), this.keybindings, {
378
- paddingX: editorPaddingX,
379
- autocompleteMaxVisible,
380
- });
387
+ this.defaultEditor =
388
+ options.startupView?.editor ??
389
+ new CustomEditor(this.ui, getEditorTheme(), this.keybindings, {
390
+ paddingX: editorPaddingX,
391
+ autocompleteMaxVisible,
392
+ });
381
393
  this.editor = this.defaultEditor;
394
+ options.startupView?.setCurrentEditor(() => this.editor);
382
395
  this.editorContainer = new Container();
383
396
  this.editorContainer.addChild(this.editor);
384
397
  this.footerDataProvider = new FooterDataProvider(this.sessionManager.getCwd());
@@ -540,14 +553,10 @@ export class InteractiveMode {
540
553
  if (this.isInitialized)
541
554
  return;
542
555
  this.registerSignalHandlers();
543
- // Use already-installed fd immediately. Download in the background so a
544
- // missing binary or GitHub outage cannot block first paint.
545
556
  this.fdPath = getToolPath("fd") ?? undefined;
546
- void Promise.all([ensureTool("fd"), ensureTool("rg")]).then(([fdPath]) => {
547
- if (fdPath && fdPath !== this.fdPath) {
548
- this.fdPath = fdPath;
549
- this.setupAutocompleteProvider();
550
- }
557
+ void startInteractiveToolInstalls(this.fdPath, (fdPath) => {
558
+ this.fdPath = fdPath;
559
+ this.setupAutocompleteProvider();
551
560
  });
552
561
  time("ensureTools");
553
562
  if (this.session.scopedModels.length > 0 && (this.options.verbose || !this.settingsManager.getQuietStartup())) {
@@ -563,6 +572,10 @@ export class InteractiveMode {
563
572
  : "";
564
573
  console.log(theme.fg("dim", `Model scope: ${modelList}${cycleHint}`));
565
574
  }
575
+ if (this.options.startupView) {
576
+ this.ui.pinFrom(null);
577
+ this.ui.clear();
578
+ }
566
579
  // Add header container as first child. Populate it after applying theme settings.
567
580
  // Keep loaded resources before chat so restored session messages never precede them.
568
581
  this.ui.addChild(this.headerContainer);
@@ -574,31 +587,24 @@ export class InteractiveMode {
574
587
  this.ui.addChild(this.widgetContainerAbove);
575
588
  this.ui.addChild(this.editorContainer);
576
589
  this.ui.addChild(this.widgetContainerBelow);
577
- this.ui.addChild(this.footer);
590
+ this.ui.addChild(this.customFooter ?? this.footer);
578
591
  this.ui.setFocus(this.editor);
579
- this.setupKeyHandlers();
580
- this.setupEditorSubmitHandler();
581
592
  this.ui.pinFrom(this.widgetContainerAbove);
593
+ this.setupKeyHandlers();
594
+ if (!this.options.startupView)
595
+ this.setupEditorSubmitHandler();
582
596
  this.ui.setAlternateScreen(true);
583
597
  // Start the UI before initializing extensions so session_start handlers can use interactive dialogs
584
- this.ui.start();
598
+ if (!this.options.startupView)
599
+ this.ui.start();
585
600
  this.isInitialized = true;
586
601
  time("ui.start");
587
602
  void this.maybeNotifyCliUpdate();
588
603
  this.startPlanUsagePolling();
589
604
  // lunr: register the permission approval dialog handler so manual mode can prompt.
590
605
  registerApprovalHandler(async (req) => {
591
- // lunr: auto-activated agent swarms get their own dialog; on approval the
592
- // footer shows the swarm status for the rest of the turn (cleared with
593
- // this.swarmMode at turn end, same as an explicit /swarm).
594
- if (req.kind === "swarm") {
595
- const resp = await this.showSwarmApprovalDialog(req);
596
- const decision = typeof resp === "string" ? resp : resp.decision;
597
- if (decision !== "reject") {
598
- this.swarmMode = true;
599
- this.setExtensionStatus("swarm", "swarm");
600
- }
601
- return resp;
606
+ if (req.kind === "large-subagent-launch") {
607
+ return this.showLargeSubagentLaunchApprovalDialog(req);
602
608
  }
603
609
  // lunr: plan approval (present_plan tool). Any approve leaves plan mode —
604
610
  // restore runs BEFORE resolving so the model's next tool call already
@@ -618,6 +624,7 @@ export class InteractiveMode {
618
624
  setRollbackWarningHandler((msg) => this.showStatus(msg));
619
625
  this.syncPermissionModeEffects(this.settingsManager.getDefaultPermissionMode());
620
626
  await this.themeController.applyFromSettings();
627
+ this.headerContainer.clear();
621
628
  // Add boot screen header (unless silenced)
622
629
  if (this.options.verbose || !this.settingsManager.getQuietStartup()) {
623
630
  const header = theme.bold(theme.fg("accent", APP_NAME)) + theme.fg("dim", ` v${this.version}`);
@@ -637,9 +644,32 @@ export class InteractiveMode {
637
644
  await this.rebindCurrentSession();
638
645
  time("rebindCurrentSession");
639
646
  this.renderInitialMessages();
647
+ this.ui.requestRender();
648
+ for (const diagnostic of this.options.startupDiagnostics ?? [])
649
+ this.showStatus(diagnostic.message);
650
+ for (const warning of this.options.deprecationWarnings ?? [])
651
+ this.showWarning(warning);
640
652
  this.deferredBuiltinAttachPromise = this.attachDeferredBuiltinExtensions();
641
- void this.deferredBuiltinAttachPromise.then(() => {
653
+ this.startupReadyPromise = this.deferredBuiltinAttachPromise.then(() => {
654
+ if (!this.isInitialized)
655
+ return;
656
+ if (this.startupFeatureError)
657
+ throw this.startupFeatureError;
658
+ if (this.options.startupView) {
659
+ this.setupEditorSubmitHandler();
660
+ // Extensions can replace the editor. Wire its submit callback after readiness as well.
661
+ this.editor.onSubmit = this.defaultEditor.onSubmit;
662
+ this.options.startupView.activate();
663
+ }
642
664
  time("attachDeferredBuiltins");
665
+ markStartupMilestone("prompt_barrier_open");
666
+ void this.options.deferredMaintenance?.();
667
+ });
668
+ void this.startupReadyPromise.catch((error) => {
669
+ if (this.options.startupView)
670
+ this.options.startupView.showError(error);
671
+ else
672
+ this.showError(String(error));
643
673
  });
644
674
  // Set up theme file watcher
645
675
  onThemeChange(() => {
@@ -655,6 +685,21 @@ export class InteractiveMode {
655
685
  void this.updateAvailableProviderCount().then(() => {
656
686
  time("updateAvailableProviderCount");
657
687
  });
688
+ void this.waitForDeferredBuiltins().then(() => {
689
+ if (!this.isInitialized)
690
+ return;
691
+ this.stopCatalogRefresh = startCatalogRefreshPolling({
692
+ refresh: (signal) => this.session.modelRuntime.refreshIfStale({ signal }),
693
+ isBusy: () => this.session.isStreaming,
694
+ onUpdate: () => {
695
+ this.session.refreshModelFromRegistry();
696
+ this.footer.invalidate();
697
+ },
698
+ });
699
+ });
700
+ }
701
+ async waitForStartupReady() {
702
+ await this.startupReadyPromise;
658
703
  }
659
704
  /** Wait until deferred builtins have attached (or were skipped). */
660
705
  async waitForDeferredBuiltins() {
@@ -715,6 +760,7 @@ export class InteractiveMode {
715
760
  if (!this.isInitialized) {
716
761
  await this.init();
717
762
  }
763
+ await this.waitForStartupReady();
718
764
  // Check tmux keyboard setup asynchronously
719
765
  this.checkTmuxKeyboardSetup().then((warning) => {
720
766
  if (warning) {
@@ -1282,6 +1328,8 @@ export class InteractiveMode {
1282
1328
  catch (error) {
1283
1329
  this.deferredBuiltinsAttached = false;
1284
1330
  const message = error instanceof Error ? error.message : String(error);
1331
+ if (this.options.startupView)
1332
+ this.startupFeatureError = new Error(message);
1285
1333
  this.showError(`Failed to load deferred extensions: ${message}`);
1286
1334
  }
1287
1335
  finally {
@@ -1942,6 +1990,7 @@ export class InteractiveMode {
1942
1990
  this.editorComponentFactory = factory;
1943
1991
  // Save text from current editor before switching
1944
1992
  const currentText = this.editor.getText();
1993
+ const startupImages = this.options.startupView ? this.editor.getPendingImages?.() : undefined;
1945
1994
  this.editorContainer.clear();
1946
1995
  if (factory) {
1947
1996
  // Create the custom editor with tui, theme, and keybindings
@@ -1950,7 +1999,16 @@ export class InteractiveMode {
1950
1999
  newEditor.onSubmit = this.defaultEditor.onSubmit;
1951
2000
  newEditor.onChange = this.defaultEditor.onChange;
1952
2001
  // Copy text from previous editor
1953
- newEditor.setText(currentText);
2002
+ if (newEditor !== this.editor) {
2003
+ newEditor.setText(currentText);
2004
+ if (startupImages?.length) {
2005
+ if (newEditor.restoreImageMarkers)
2006
+ newEditor.restoreImageMarkers(startupImages);
2007
+ else
2008
+ for (const image of startupImages)
2009
+ this.fallbackImageAttachments.set(image.id, image);
2010
+ }
2011
+ }
1954
2012
  // Copy appearance settings if supported
1955
2013
  if (newEditor.borderColor !== undefined) {
1956
2014
  newEditor.borderColor = this.defaultEditor.borderColor;
@@ -1965,16 +2023,15 @@ export class InteractiveMode {
1965
2023
  // If extending CustomEditor, copy app-level handlers
1966
2024
  // Use duck typing since instanceof fails across jiti module boundaries
1967
2025
  const customEditor = newEditor;
1968
- if ("actionHandlers" in customEditor && customEditor.actionHandlers instanceof Map) {
2026
+ if (newEditor !== this.defaultEditor &&
2027
+ "actionHandlers" in customEditor &&
2028
+ customEditor.actionHandlers instanceof Map) {
1969
2029
  if (!customEditor.onEscape) {
1970
2030
  customEditor.onEscape = () => this.defaultEditor.onEscape?.();
1971
2031
  }
1972
2032
  if (!customEditor.onCtrlD) {
1973
2033
  customEditor.onCtrlD = () => this.defaultEditor.onCtrlD?.();
1974
2034
  }
1975
- if (!customEditor.onPasteImage) {
1976
- customEditor.onPasteImage = () => this.defaultEditor.onPasteImage?.();
1977
- }
1978
2035
  if (!customEditor.onExtensionShortcut) {
1979
2036
  customEditor.onExtensionShortcut = (data) => this.defaultEditor.onExtensionShortcut?.(data);
1980
2037
  }
@@ -1987,7 +2044,8 @@ export class InteractiveMode {
1987
2044
  }
1988
2045
  else {
1989
2046
  // Restore default editor with text from custom editor
1990
- this.defaultEditor.setText(currentText);
2047
+ if (this.editor !== this.defaultEditor)
2048
+ this.defaultEditor.setText(currentText);
1991
2049
  this.editor = this.defaultEditor;
1992
2050
  }
1993
2051
  this.editorContainer.addChild(this.editor);
@@ -2149,6 +2207,7 @@ export class InteractiveMode {
2149
2207
  // lunr: tool/thinking expand is per-item click; ctrl+o is not bound (tree filter still uses ctrl+o).
2150
2208
  this.defaultEditor.onAction("app.thinking.toggle", () => this.toggleThinkingBlockVisibility());
2151
2209
  this.defaultEditor.onAction("app.editor.external", () => this.openExternalEditor());
2210
+ this.defaultEditor.onAction("app.clipboard.pasteImage", () => void this.handleClipboardPaste());
2152
2211
  this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand());
2153
2212
  this.defaultEditor.onAction("app.message.followUp", () => this.handleFollowUp());
2154
2213
  this.defaultEditor.onAction("app.message.dequeue", () => this.handleDequeue());
@@ -2163,12 +2222,6 @@ export class InteractiveMode {
2163
2222
  this.updateEditorBorderColor();
2164
2223
  }
2165
2224
  };
2166
- // Handle clipboard paste (keybinding: app.clipboard.pasteImage, Alt+V on Windows —
2167
- // Ctrl+V is owned by the terminal and never reaches us). Images become `[image_n]`
2168
- // chips; otherwise, paste plain text from the system clipboard.
2169
- this.defaultEditor.onPasteImage = () => {
2170
- void this.handleClipboardPaste();
2171
- };
2172
2225
  this.ui.addInputListener((data) => {
2173
2226
  if (!this.ui.isPinned())
2174
2227
  return;
@@ -2290,7 +2343,7 @@ export class InteractiveMode {
2290
2343
  restoreEditorFromTreeResult(result) {
2291
2344
  this.restoreEditorDraft(result.editorText ?? "", result.editorImages);
2292
2345
  }
2293
- async handleClipboardPaste() {
2346
+ async handleClipboardPaste(options = {}) {
2294
2347
  try {
2295
2348
  const image = await readClipboardImage();
2296
2349
  if (image) {
@@ -2300,13 +2353,15 @@ export class InteractiveMode {
2300
2353
  this.showStatus(`Pasted ${formatImageMarker(id)}`);
2301
2354
  return;
2302
2355
  }
2303
- const text = await readClipboardText();
2304
- if (text) {
2305
- this.editor.insertTextAtCursor?.(text);
2306
- this.ui.requestRender();
2307
- return;
2356
+ if (options.textFallback !== false) {
2357
+ const text = await readClipboardText();
2358
+ if (text) {
2359
+ this.editor.insertTextAtCursor?.(text);
2360
+ this.ui.requestRender();
2361
+ return;
2362
+ }
2308
2363
  }
2309
- this.showStatus("Clipboard contains no image or text");
2364
+ this.showStatus(options.textFallback === false ? "Clipboard contains no image" : "Clipboard contains no image or text");
2310
2365
  }
2311
2366
  catch (err) {
2312
2367
  this.showStatus(`Clipboard paste failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -2322,6 +2377,11 @@ export class InteractiveMode {
2322
2377
  const images = this.consumeStagedSubmitImages() ?? (await this.loadImageAttachments(this.takeSubmittedImages(text)));
2323
2378
  this.ui.setChatScroll(0);
2324
2379
  // Handle commands
2380
+ if (text === "/paste-image") {
2381
+ this.editor.setText("");
2382
+ await this.handleClipboardPaste({ textFallback: false });
2383
+ return;
2384
+ }
2325
2385
  if (text === "/settings") {
2326
2386
  void this.showSettingsSelector();
2327
2387
  this.editor.setText("");
@@ -2487,12 +2547,6 @@ export class InteractiveMode {
2487
2547
  await this.handleInitCommand();
2488
2548
  return;
2489
2549
  }
2490
- if (text === "/swarm" || text.startsWith("/swarm ")) {
2491
- const task = text.startsWith("/swarm ") ? text.slice(7).trim() : "";
2492
- this.editor.setText("");
2493
- await this.handleSwarmCommand(task);
2494
- return;
2495
- }
2496
2550
  if (text === "/debug") {
2497
2551
  this.handleDebugCommand();
2498
2552
  this.editor.setText("");
@@ -2741,7 +2795,7 @@ export class InteractiveMode {
2741
2795
  this.ui.requestRender();
2742
2796
  }
2743
2797
  else if (event.message.role === "assistant") {
2744
- this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.settingsManager.getGutterRail(), this.thinkingCollapse);
2798
+ this.streamingComponent = new AssistantMessageComponent(undefined, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.thinkingCollapse);
2745
2799
  // lunr: collapsible reasoning — fresh timing array for this message.
2746
2800
  this.thinkingRunTimings = [];
2747
2801
  this.streamingComponent.setThinkingTimings(this.thinkingRunTimings);
@@ -2878,6 +2932,7 @@ export class InteractiveMode {
2878
2932
  break;
2879
2933
  }
2880
2934
  case "agent_end":
2935
+ this.session.refreshModelFromRegistry();
2881
2936
  if (this.settingsManager.getShowTerminalProgress()) {
2882
2937
  this.ui.terminal.setProgress(false);
2883
2938
  }
@@ -2889,10 +2944,6 @@ export class InteractiveMode {
2889
2944
  this.streamingMessage = undefined;
2890
2945
  }
2891
2946
  this.pendingTools.clear();
2892
- if (this.swarmMode) {
2893
- this.swarmMode = false;
2894
- this.setExtensionStatus("swarm", undefined);
2895
- }
2896
2947
  this.maybeAutoNameSession();
2897
2948
  // lunr: capture tree-scope changes at turn boundary (bash side-effects).
2898
2949
  captureTreeChanges(this.sessionManager.getCwd(), this.sessionManager.getSessionId());
@@ -3073,7 +3124,7 @@ export class InteractiveMode {
3073
3124
  this.chatContainer.addChild(new Spacer(1));
3074
3125
  }
3075
3126
  const skillBlock = parseSkillBlock(textContent);
3076
- // lunr: render injected prompts (/swarm /research /goal) collapsed instead
3127
+ // lunr: render injected prompts (/research /goal) collapsed instead
3077
3128
  // of dumping the full multi-line prompt body verbatim.
3078
3129
  const injected = detectInjectedPrompt(textContent);
3079
3130
  if (injected) {
@@ -3089,12 +3140,12 @@ export class InteractiveMode {
3089
3140
  // Render user message separately if present
3090
3141
  if (skillBlock.userMessage) {
3091
3142
  this.chatContainer.addChild(new Spacer(1));
3092
- const userComponent = new UserMessageComponent(skillBlock.userMessage, this.getMarkdownThemeWithSettings(), this.outputPad, this.settingsManager.getGutterRail());
3143
+ const userComponent = new UserMessageComponent(skillBlock.userMessage, this.getMarkdownThemeWithSettings(), this.outputPad);
3093
3144
  this.chatContainer.addChild(userComponent);
3094
3145
  }
3095
3146
  }
3096
3147
  else {
3097
- const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), this.outputPad, this.settingsManager.getGutterRail());
3148
+ const userComponent = new UserMessageComponent(textContent, this.getMarkdownThemeWithSettings(), this.outputPad);
3098
3149
  this.chatContainer.addChild(userComponent);
3099
3150
  }
3100
3151
  if (options?.populateHistory) {
@@ -3104,7 +3155,7 @@ export class InteractiveMode {
3104
3155
  break;
3105
3156
  }
3106
3157
  case "assistant": {
3107
- const assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.settingsManager.getGutterRail(), this.thinkingCollapse);
3158
+ const assistantComponent = new AssistantMessageComponent(message, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.thinkingCollapse);
3108
3159
  // lunr: collapsible reasoning — re-attach live timings when this
3109
3160
  // message was streamed in this session (undefined = history).
3110
3161
  assistantComponent.setThinkingTimings(this.thinkingTimingsByMessage.get(message));
@@ -3925,12 +3976,14 @@ export class InteractiveMode {
3925
3976
  clearOnShrink: this.settingsManager.getClearOnShrink(),
3926
3977
  showTerminalProgress: this.settingsManager.getShowTerminalProgress(),
3927
3978
  modelTiers: this.settingsManager.getModelTiers(),
3979
+ modelInstructions: this.settingsManager.getModelInstructions(),
3980
+ globalInstructionsPath: getGlobalInstructionsPath(getAgentDir()),
3981
+ modelInstructionsPath: getModelInstructionsPath(getAgentDir(), this.session.model?.id ?? "no-model-selected"),
3982
+ confirmLargeSubagentLaunches: this.settingsManager.getConfirmLargeSubagentLaunches(),
3928
3983
  memoryEnabled: this.settingsManager.getMemoryEnabled(),
3929
3984
  memoryCharCap: this.settingsManager.getMemoryCharCap(),
3930
3985
  searchCurator: getSearchCuratorSetting(),
3931
3986
  // lunr: TUI customize settings
3932
- gutterRail: this.settingsManager.getGutterRail(),
3933
- promptSymbol: this.settingsManager.getPromptSymbol(),
3934
3987
  footerMcp: this.settingsManager.getFooterMcp(),
3935
3988
  footerLsp: this.settingsManager.getFooterLsp(),
3936
3989
  footerContext: this.settingsManager.getFooterContext(),
@@ -4112,6 +4165,17 @@ export class InteractiveMode {
4112
4165
  onModelTierThinkingChange: (tier, level) => {
4113
4166
  this.settingsManager.setTierThinking(tier, level);
4114
4167
  },
4168
+ onModelInstructionsEnabledChange: (enabled) => {
4169
+ this.settingsManager.setModelInstructionsEnabled(enabled);
4170
+ this.session.refreshToolRegistry();
4171
+ },
4172
+ onModelInstructionsModeChange: (mode) => {
4173
+ this.settingsManager.setModelInstructionsMode(mode);
4174
+ this.session.refreshToolRegistry();
4175
+ },
4176
+ onConfirmLargeSubagentLaunchesChange: (enabled) => {
4177
+ this.settingsManager.setConfirmLargeSubagentLaunches(enabled);
4178
+ },
4115
4179
  getTierThinkingLevels: (tier) => {
4116
4180
  const model = this.resolveModelReference(this.settingsManager.getTierModel(tier));
4117
4181
  if (model)
@@ -4132,12 +4196,6 @@ export class InteractiveMode {
4132
4196
  }
4133
4197
  },
4134
4198
  // lunr: TUI customize callbacks
4135
- onGutterRailChange: (enabled) => {
4136
- this.settingsManager.setGutterRail(enabled);
4137
- },
4138
- onPromptSymbolChange: (enabled) => {
4139
- this.settingsManager.setPromptSymbol(enabled);
4140
- },
4141
4199
  onFooterMcpChange: (enabled) => {
4142
4200
  this.settingsManager.setFooterMcp(enabled);
4143
4201
  },
@@ -4257,40 +4315,9 @@ export class InteractiveMode {
4257
4315
  this.footer.invalidate();
4258
4316
  return;
4259
4317
  }
4260
- const incomplete = result.incomplete;
4261
- const toPrompt = incomplete.slice(0, INCOMPLETE_PROMPT_CAP);
4262
- const extraDefaults = Math.max(0, incomplete.length - toPrompt.length);
4263
- const persisted = [];
4318
+ // Discovered metadata stays in its cache, not in user overrides. Enrichment is automatic.
4319
+ const extraDefaults = result.incomplete.length;
4264
4320
  const asked = [];
4265
- let skipRemaining = false;
4266
- for (const item of toPrompt) {
4267
- if (skipRemaining) {
4268
- persisted.push(modelToUserEntry(item.draft));
4269
- continue;
4270
- }
4271
- const choice = await this.showExtensionSelector(describeIncomplete(item), [
4272
- "Enter details",
4273
- "Use defaults",
4274
- "Skip remaining",
4275
- ]);
4276
- asked.push(`${item.provider}/${item.id}`);
4277
- if (choice === "Skip remaining") {
4278
- skipRemaining = true;
4279
- persisted.push(modelToUserEntry(item.draft));
4280
- continue;
4281
- }
4282
- if (choice === "Enter details") {
4283
- const detailed = await this.promptIncompleteModelDetails(item);
4284
- persisted.push(modelToUserEntry(detailed ?? item.draft));
4285
- continue;
4286
- }
4287
- persisted.push(modelToUserEntry(item.draft));
4288
- }
4289
- for (const item of incomplete.slice(toPrompt.length)) {
4290
- persisted.push(modelToUserEntry(item.draft));
4291
- }
4292
- if (persisted.length > 0)
4293
- runtime.persistUserModels(persisted);
4294
4321
  let ollama;
4295
4322
  const runner = this.session.extensionRunner;
4296
4323
  const cloudRefresh = globalThis[Symbol.for("@lunr/ollama-cloud-refresh")];
@@ -4311,53 +4338,26 @@ export class InteractiveMode {
4311
4338
  evictedUserRows: result.official.evictedUserRows,
4312
4339
  }
4313
4340
  : undefined,
4314
- providers: result.live.map((entry) => ({
4315
- id: entry.providerId,
4316
- status: entry.status,
4317
- added: entry.added,
4318
- total: entry.total,
4319
- error: entry.error,
4320
- })),
4341
+ providers: [
4342
+ ...result.live.map((entry) => ({
4343
+ id: entry.providerId,
4344
+ status: entry.status,
4345
+ added: entry.added,
4346
+ total: entry.total,
4347
+ error: entry.error,
4348
+ })),
4349
+ ...Object.entries(result.official?.errors ?? {}).map(([id, error]) => ({
4350
+ id,
4351
+ status: "error",
4352
+ error,
4353
+ })),
4354
+ ],
4321
4355
  asked,
4322
4356
  extraDefaults,
4323
4357
  ollama,
4324
4358
  }));
4325
4359
  this.footer.invalidate();
4326
4360
  }
4327
- async promptIncompleteModelDetails(item) {
4328
- const contextInput = await this.showExtensionInput(`${item.provider}/${item.id} — context window:`, String(item.draft.contextWindow || 128000));
4329
- if (contextInput === undefined)
4330
- return undefined;
4331
- const maxTokensInput = await this.showExtensionInput(`${item.provider}/${item.id} — max output tokens:`, String(item.draft.maxTokens || 8192));
4332
- if (maxTokensInput === undefined)
4333
- return undefined;
4334
- const inputChoice = await this.showExtensionSelector(`${item.provider}/${item.id} — input:`, [
4335
- "text",
4336
- "text + image",
4337
- ]);
4338
- if (inputChoice === undefined)
4339
- return undefined;
4340
- const reasoningChoice = await this.showExtensionSelector(`${item.provider}/${item.id} — reasoning:`, [
4341
- "yes",
4342
- "no",
4343
- ]);
4344
- if (reasoningChoice === undefined)
4345
- return undefined;
4346
- let api = item.draft.api;
4347
- if (item.availableApis.length > 1) {
4348
- const apiChoice = await this.showExtensionSelector(`${item.provider}/${item.id} — API protocol:`, item.availableApis.map(String));
4349
- if (apiChoice === undefined)
4350
- return undefined;
4351
- api = apiChoice;
4352
- }
4353
- return applyIncompleteAnswers(item.draft, {
4354
- contextWindow: parsePositiveInt(contextInput, item.draft.contextWindow),
4355
- maxTokens: parsePositiveInt(maxTokensInput, item.draft.maxTokens),
4356
- input: inputChoice === "text + image" ? ["text", "image"] : ["text"],
4357
- reasoning: reasoningChoice === "yes",
4358
- api,
4359
- });
4360
- }
4361
4361
  async findExactModelMatch(searchTerm) {
4362
4362
  const models = await this.getModelCandidates();
4363
4363
  return findExactModelReferenceMatch(searchTerm, models);
@@ -5578,24 +5578,6 @@ export class InteractiveMode {
5578
5578
  await this.sendUserMessageAfterDeferredBuiltins(prompt);
5579
5579
  this.showStatus("AGENTS.md is being generated — run /reload when it finishes to load it into context.");
5580
5580
  }
5581
- async handleSwarmCommand(task) {
5582
- if (task.length === 0) {
5583
- if (this.swarmMode) {
5584
- this.showStatus("Swarm mode is active — run /subagents-fleet to monitor the fleet.");
5585
- }
5586
- else {
5587
- this.showStatus("Usage: /swarm <task> — decomposes the task across parallel subagents. Monitor with /subagents-fleet.");
5588
- }
5589
- return;
5590
- }
5591
- if (this.session.isStreaming) {
5592
- this.showWarning("Wait for the current response to finish before running /swarm.");
5593
- return;
5594
- }
5595
- this.swarmMode = true;
5596
- this.setExtensionStatus("swarm", "swarm");
5597
- await this.sendUserMessageAfterDeferredBuiltins(buildSwarmPrompt(task));
5598
- }
5599
5581
  // lunr: /undo and /edit rewind the same session via navigateTree (no fork).
5600
5582
  // /undo leaves the editor alone; /edit pastes the undone user text. /redo
5601
5583
  // pops the previous leaf and navigates back.
@@ -6135,7 +6117,8 @@ export class InteractiveMode {
6135
6117
  tools,
6136
6118
  messages: this.session.messages,
6137
6119
  contextWindow,
6138
- globalAgentsPath: path.join(getAgentDir(), "AGENTS.md"),
6120
+ globalAgentsPath: getGlobalInstructionsPath(getAgentDir()),
6121
+ modelAgentsPath: getModelInstructionsPath(getAgentDir(), model.id),
6139
6122
  });
6140
6123
  }
6141
6124
  handleFastCommand(arg) {
@@ -6367,20 +6350,20 @@ export class InteractiveMode {
6367
6350
  });
6368
6351
  });
6369
6352
  }
6370
- // lunr: approval dialog for auto-activated agent swarms (one subagent call
6371
- // launching >2 parallel subagents). "Reject with feedback" collects a one-line
6353
+ // Approval dialog for one subagent call launching more than two children.
6354
+ // "Reject with feedback" collects a one-line
6372
6355
  // reason that becomes the block reason the model sees, so it can adjust the plan.
6373
- async showSwarmApprovalDialog(req) {
6356
+ async showLargeSubagentLaunchApprovalDialog(req) {
6374
6357
  return new Promise((resolve) => {
6375
6358
  this.showSelector((done) => {
6376
- const selector = new ExtensionSelectorComponent("Approve agent swarm?", ["Approve once", "Approve for this session", "Reject", "Reject with feedback"], (option) => {
6359
+ const selector = new ExtensionSelectorComponent("Approve large subagent launch?", ["Approve once", "Approve for this session", "Reject", "Reject with feedback"], (option) => {
6377
6360
  done();
6378
6361
  if (option === "Approve once")
6379
6362
  resolve("once");
6380
6363
  else if (option === "Approve for this session")
6381
6364
  resolve("session");
6382
6365
  else if (option === "Reject with feedback") {
6383
- void this.showExtensionInput("Reject agent swarm", "feedback for the agent (optional)").then((feedback) => {
6366
+ void this.showExtensionInput("Reject large subagent launch", "feedback for the agent (optional)").then((feedback) => {
6384
6367
  const trimmed = feedback?.trim();
6385
6368
  resolve(trimmed ? { decision: "reject", feedback: trimmed } : "reject");
6386
6369
  });
@@ -6400,7 +6383,7 @@ export class InteractiveMode {
6400
6383
  // the result text the model sees. Esc/close counts as Decline.
6401
6384
  showPlanInChat(summary) {
6402
6385
  this.chatContainer.addChild(new Spacer(1));
6403
- this.chatContainer.addChild(new PlanMessageComponent(summary, this.getMarkdownThemeWithSettings(), this.outputPad, this.settingsManager.getGutterRail()));
6386
+ this.chatContainer.addChild(new PlanMessageComponent(summary, this.getMarkdownThemeWithSettings(), this.outputPad));
6404
6387
  this.ui.requestRender();
6405
6388
  }
6406
6389
  async showPlanApprovalDialog(summary) {
@@ -6614,6 +6597,7 @@ ${cycleThinkingLevel ? `| \`${cycleThinkingLevel}\` | Cycle thinking level |\n`
6614
6597
  | \`${followUp}\` | Queue follow-up message |
6615
6598
  | \`${dequeue}\` | Restore queued messages |
6616
6599
  | \`${pasteImage}\` | Paste image or text from clipboard |
6600
+ | \`/paste-image\` | Paste image without a terminal shortcut |
6617
6601
  | \`/\` | Slash commands |
6618
6602
  | \`!\` | Run bash command |
6619
6603
  | \`!!\` | Run bash command (excluded from context) |
@@ -6782,6 +6766,8 @@ ${cycleThinkingLevel ? `| \`${cycleThinkingLevel}\` | Cycle thinking level |\n`
6782
6766
  }
6783
6767
  }
6784
6768
  stop() {
6769
+ this.stopCatalogRefresh?.();
6770
+ this.stopCatalogRefresh = undefined;
6785
6771
  if (this.settingsManager.getShowTerminalProgress()) {
6786
6772
  this.ui.terminal.setProgress(false);
6787
6773
  }