@ai-agent-forge/agent-forge 0.86.7 → 0.88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (717) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +10 -11
  3. package/dist/artifacts/artifact-store.d.ts.map +1 -1
  4. package/dist/artifacts/artifact-store.js +9 -5
  5. package/dist/artifacts/artifact-store.js.map +1 -1
  6. package/dist/bundle/.build-manifest.json +430 -413
  7. package/dist/bundle/chunks/{chunk-A7GUOX2H.js → chunk-6ZKDNZHA.js} +5 -1
  8. package/dist/bundle/chunks/chunk-HLJEVRWP.js +13 -0
  9. package/dist/bundle/chunks/chunk-YGHQME4V.js +1456 -0
  10. package/dist/bundle/chunks/image-resize-worker.js +12 -1
  11. package/dist/bundle/chunks/{virtual-modules-3IZ4MYSQ.js → virtual-modules-KZ5DRH7Q.js} +1 -1
  12. package/dist/bundle/cli.js +1 -1
  13. package/dist/bundle/client.js +1 -1
  14. package/dist/bundle/index.js +2 -2
  15. package/dist/bundle/rpc-entry.js +1 -1
  16. package/dist/cli/args.d.ts.map +1 -1
  17. package/dist/cli/args.js +231 -185
  18. package/dist/cli/args.js.map +1 -1
  19. package/dist/cli/auth-check.d.ts.map +1 -1
  20. package/dist/cli/auth-check.js +17 -4
  21. package/dist/cli/auth-check.js.map +1 -1
  22. package/dist/cli/auth-command.d.ts.map +1 -1
  23. package/dist/cli/auth-command.js +15 -9
  24. package/dist/cli/auth-command.js.map +1 -1
  25. package/dist/cli/credential-print.d.ts.map +1 -1
  26. package/dist/cli/credential-print.js +14 -7
  27. package/dist/cli/credential-print.js.map +1 -1
  28. package/dist/cli/experimental/command.d.ts.map +1 -1
  29. package/dist/cli/experimental/command.js +6 -5
  30. package/dist/cli/experimental/command.js.map +1 -1
  31. package/dist/cli/list-models.d.ts.map +1 -1
  32. package/dist/cli/list-models.js +9 -8
  33. package/dist/cli/list-models.js.map +1 -1
  34. package/dist/cli/plugin-manager-controller.d.ts.map +1 -1
  35. package/dist/cli/plugin-manager-controller.js +2 -1
  36. package/dist/cli/plugin-manager-controller.js.map +1 -1
  37. package/dist/cli/serve.d.ts.map +1 -1
  38. package/dist/cli/serve.js +8 -5
  39. package/dist/cli/serve.js.map +1 -1
  40. package/dist/client/remote-session.d.ts.map +1 -1
  41. package/dist/client/remote-session.js +16 -9
  42. package/dist/client/remote-session.js.map +1 -1
  43. package/dist/config.d.ts.map +1 -1
  44. package/dist/config.js +5 -3
  45. package/dist/config.js.map +1 -1
  46. package/dist/core/agent-capability-contract.d.ts +0 -7
  47. package/dist/core/agent-capability-contract.d.ts.map +1 -1
  48. package/dist/core/agent-capability-contract.js +72 -68
  49. package/dist/core/agent-capability-contract.js.map +1 -1
  50. package/dist/core/agent-session-bash.d.ts.map +1 -1
  51. package/dist/core/agent-session-bash.js +5 -4
  52. package/dist/core/agent-session-bash.js.map +1 -1
  53. package/dist/core/agent-session-compaction.d.ts +6 -10
  54. package/dist/core/agent-session-compaction.d.ts.map +1 -1
  55. package/dist/core/agent-session-compaction.js +35 -133
  56. package/dist/core/agent-session-compaction.js.map +1 -1
  57. package/dist/core/agent-session-context.d.ts.map +1 -1
  58. package/dist/core/agent-session-context.js +18 -13
  59. package/dist/core/agent-session-context.js.map +1 -1
  60. package/dist/core/agent-session-internal.d.ts +0 -6
  61. package/dist/core/agent-session-internal.d.ts.map +1 -1
  62. package/dist/core/agent-session-internal.js.map +1 -1
  63. package/dist/core/agent-session-model.d.ts.map +1 -1
  64. package/dist/core/agent-session-model.js +2 -1
  65. package/dist/core/agent-session-model.js.map +1 -1
  66. package/dist/core/agent-session-retry.d.ts.map +1 -1
  67. package/dist/core/agent-session-retry.js +3 -3
  68. package/dist/core/agent-session-retry.js.map +1 -1
  69. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  70. package/dist/core/agent-session-runtime.js +7 -6
  71. package/dist/core/agent-session-runtime.js.map +1 -1
  72. package/dist/core/agent-session-services.d.ts +1 -1
  73. package/dist/core/agent-session-services.d.ts.map +1 -1
  74. package/dist/core/agent-session-services.js.map +1 -1
  75. package/dist/core/agent-session-tools.d.ts.map +1 -1
  76. package/dist/core/agent-session-tools.js +3 -2
  77. package/dist/core/agent-session-tools.js.map +1 -1
  78. package/dist/core/agent-session.d.ts +40 -22
  79. package/dist/core/agent-session.d.ts.map +1 -1
  80. package/dist/core/agent-session.js +147 -67
  81. package/dist/core/agent-session.js.map +1 -1
  82. package/dist/core/auth-guidance.d.ts.map +1 -1
  83. package/dist/core/auth-guidance.js +11 -5
  84. package/dist/core/auth-guidance.js.map +1 -1
  85. package/dist/core/auth-storage.d.ts.map +1 -1
  86. package/dist/core/auth-storage.js +9 -6
  87. package/dist/core/auth-storage.js.map +1 -1
  88. package/dist/core/compaction/compaction.d.ts.map +1 -1
  89. package/dist/core/compaction/compaction.js +2 -1
  90. package/dist/core/compaction/compaction.js.map +1 -1
  91. package/dist/core/embedded-sdk.d.ts.map +1 -1
  92. package/dist/core/embedded-sdk.js +10 -6
  93. package/dist/core/embedded-sdk.js.map +1 -1
  94. package/dist/core/export-html/index.d.ts.map +1 -1
  95. package/dist/core/export-html/index.js +9 -4
  96. package/dist/core/export-html/index.js.map +1 -1
  97. package/dist/core/extensions/agent-composition.d.ts.map +1 -1
  98. package/dist/core/extensions/agent-composition.js +26 -19
  99. package/dist/core/extensions/agent-composition.js.map +1 -1
  100. package/dist/core/extensions/bootstrap-agent-loop.d.ts.map +1 -1
  101. package/dist/core/extensions/bootstrap-agent-loop.js +3 -2
  102. package/dist/core/extensions/bootstrap-agent-loop.js.map +1 -1
  103. package/dist/core/extensions/bootstrap-compaction-policy.d.ts.map +1 -1
  104. package/dist/core/extensions/bootstrap-compaction-policy.js +0 -34
  105. package/dist/core/extensions/bootstrap-compaction-policy.js.map +1 -1
  106. package/dist/core/extensions/bootstrap-lifecycle.d.ts.map +1 -1
  107. package/dist/core/extensions/bootstrap-lifecycle.js +20 -17
  108. package/dist/core/extensions/bootstrap-lifecycle.js.map +1 -1
  109. package/dist/core/extensions/bootstrap-overflow-policy.d.ts.map +1 -1
  110. package/dist/core/extensions/bootstrap-overflow-policy.js +2 -1
  111. package/dist/core/extensions/bootstrap-overflow-policy.js.map +1 -1
  112. package/dist/core/extensions/bootstrap-retry-policy.d.ts.map +1 -1
  113. package/dist/core/extensions/bootstrap-retry-policy.js +4 -3
  114. package/dist/core/extensions/bootstrap-retry-policy.js.map +1 -1
  115. package/dist/core/extensions/bootstrap-skills.d.ts.map +1 -1
  116. package/dist/core/extensions/bootstrap-skills.js +7 -6
  117. package/dist/core/extensions/bootstrap-skills.js.map +1 -1
  118. package/dist/core/extensions/bootstrap-tools.d.ts.map +1 -1
  119. package/dist/core/extensions/bootstrap-tools.js +2 -1
  120. package/dist/core/extensions/bootstrap-tools.js.map +1 -1
  121. package/dist/core/extensions/capability-plugin.d.ts.map +1 -1
  122. package/dist/core/extensions/capability-plugin.js +37 -13
  123. package/dist/core/extensions/capability-plugin.js.map +1 -1
  124. package/dist/core/extensions/capability-runtime-events.d.ts.map +1 -1
  125. package/dist/core/extensions/capability-runtime-events.js +17 -13
  126. package/dist/core/extensions/capability-runtime-events.js.map +1 -1
  127. package/dist/core/extensions/capability-runtime-guards.d.ts.map +1 -1
  128. package/dist/core/extensions/capability-runtime-guards.js +16 -15
  129. package/dist/core/extensions/capability-runtime-guards.js.map +1 -1
  130. package/dist/core/extensions/capability-runtime-manifest.d.ts.map +1 -1
  131. package/dist/core/extensions/capability-runtime-manifest.js +52 -30
  132. package/dist/core/extensions/capability-runtime-manifest.js.map +1 -1
  133. package/dist/core/extensions/capability-runtime-validation.d.ts.map +1 -1
  134. package/dist/core/extensions/capability-runtime-validation.js +66 -65
  135. package/dist/core/extensions/capability-runtime-validation.js.map +1 -1
  136. package/dist/core/extensions/capability-runtime.d.ts.map +1 -1
  137. package/dist/core/extensions/capability-runtime.js +147 -127
  138. package/dist/core/extensions/capability-runtime.js.map +1 -1
  139. package/dist/core/extensions/compaction-memory-failure-mode.d.ts.map +1 -1
  140. package/dist/core/extensions/compaction-memory-failure-mode.js +3 -2
  141. package/dist/core/extensions/compaction-memory-failure-mode.js.map +1 -1
  142. package/dist/core/extensions/context-strategy-binding.d.ts.map +1 -1
  143. package/dist/core/extensions/context-strategy-binding.js +7 -4
  144. package/dist/core/extensions/context-strategy-binding.js.map +1 -1
  145. package/dist/core/extensions/lifecycle-catalog.d.ts.map +1 -1
  146. package/dist/core/extensions/lifecycle-catalog.js +290 -279
  147. package/dist/core/extensions/lifecycle-catalog.js.map +1 -1
  148. package/dist/core/extensions/lifecycle-delivery-queue.d.ts.map +1 -1
  149. package/dist/core/extensions/lifecycle-delivery-queue.js +3 -2
  150. package/dist/core/extensions/lifecycle-delivery-queue.js.map +1 -1
  151. package/dist/core/extensions/provider-failover.d.ts +7 -3
  152. package/dist/core/extensions/provider-failover.d.ts.map +1 -1
  153. package/dist/core/extensions/provider-failover.js +9 -8
  154. package/dist/core/extensions/provider-failover.js.map +1 -1
  155. package/dist/core/facade/coding-agent-facade.d.ts +6 -6
  156. package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
  157. package/dist/core/facade/coding-agent-facade.js +2 -3
  158. package/dist/core/facade/coding-agent-facade.js.map +1 -1
  159. package/dist/core/http-dispatcher.d.ts.map +1 -1
  160. package/dist/core/http-dispatcher.js +2 -1
  161. package/dist/core/http-dispatcher.js.map +1 -1
  162. package/dist/core/i18n/index.d.ts +14 -0
  163. package/dist/core/i18n/index.d.ts.map +1 -0
  164. package/dist/core/i18n/index.js +67 -0
  165. package/dist/core/i18n/index.js.map +1 -0
  166. package/dist/core/i18n/locales/en/example.d.ts +7 -0
  167. package/dist/core/i18n/locales/en/example.d.ts.map +1 -0
  168. package/dist/core/i18n/locales/en/example.js +7 -0
  169. package/dist/core/i18n/locales/en/example.js.map +1 -0
  170. package/dist/core/i18n/locales/zh-cn/cli.d.ts +8 -0
  171. package/dist/core/i18n/locales/zh-cn/cli.d.ts.map +1 -0
  172. package/dist/core/i18n/locales/zh-cn/cli.js +229 -0
  173. package/dist/core/i18n/locales/zh-cn/cli.js.map +1 -0
  174. package/dist/core/i18n/locales/zh-cn/common.d.ts +6 -0
  175. package/dist/core/i18n/locales/zh-cn/common.d.ts.map +1 -0
  176. package/dist/core/i18n/locales/zh-cn/common.js +6 -0
  177. package/dist/core/i18n/locales/zh-cn/common.js.map +1 -0
  178. package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts +13 -0
  179. package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts.map +1 -0
  180. package/dist/core/i18n/locales/zh-cn/core-contract-core.js +173 -0
  181. package/dist/core/i18n/locales/zh-cn/core-contract-core.js.map +1 -0
  182. package/dist/core/i18n/locales/zh-cn/core-contract-extensions.d.ts +12 -0
  183. package/dist/core/i18n/locales/zh-cn/core-contract-extensions.d.ts.map +1 -0
  184. package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js +582 -0
  185. package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js.map +1 -0
  186. package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts +9 -0
  187. package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts.map +1 -0
  188. package/dist/core/i18n/locales/zh-cn/core-contract-final.js +55 -0
  189. package/dist/core/i18n/locales/zh-cn/core-contract-final.js.map +1 -0
  190. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts +11 -0
  191. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts.map +1 -0
  192. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js +455 -0
  193. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js.map +1 -0
  194. package/dist/core/i18n/locales/zh-cn/core-errors.d.ts +9 -0
  195. package/dist/core/i18n/locales/zh-cn/core-errors.d.ts.map +1 -0
  196. package/dist/core/i18n/locales/zh-cn/core-errors.js +191 -0
  197. package/dist/core/i18n/locales/zh-cn/core-errors.js.map +1 -0
  198. package/dist/core/i18n/locales/zh-cn/example.d.ts +7 -0
  199. package/dist/core/i18n/locales/zh-cn/example.d.ts.map +1 -0
  200. package/dist/core/i18n/locales/zh-cn/example.js +10 -0
  201. package/dist/core/i18n/locales/zh-cn/example.js.map +1 -0
  202. package/dist/core/i18n/locales/zh-cn/index.d.ts +2 -0
  203. package/dist/core/i18n/locales/zh-cn/index.d.ts.map +1 -0
  204. package/dist/core/i18n/locales/zh-cn/index.js +41 -0
  205. package/dist/core/i18n/locales/zh-cn/index.js.map +1 -0
  206. package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts +10 -0
  207. package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts.map +1 -0
  208. package/dist/core/i18n/locales/zh-cn/interactive-mode.js +267 -0
  209. package/dist/core/i18n/locales/zh-cn/interactive-mode.js.map +1 -0
  210. package/dist/core/i18n/locales/zh-cn/keybindings.d.ts +11 -0
  211. package/dist/core/i18n/locales/zh-cn/keybindings.d.ts.map +1 -0
  212. package/dist/core/i18n/locales/zh-cn/keybindings.js +67 -0
  213. package/dist/core/i18n/locales/zh-cn/keybindings.js.map +1 -0
  214. package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts +7 -0
  215. package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts.map +1 -0
  216. package/dist/core/i18n/locales/zh-cn/slash-commands.js +39 -0
  217. package/dist/core/i18n/locales/zh-cn/slash-commands.js.map +1 -0
  218. package/dist/core/i18n/locales/zh-cn/tui-builtin.d.ts +10 -0
  219. package/dist/core/i18n/locales/zh-cn/tui-builtin.d.ts.map +1 -0
  220. package/dist/core/i18n/locales/zh-cn/tui-builtin.js +15 -0
  221. package/dist/core/i18n/locales/zh-cn/tui-builtin.js.map +1 -0
  222. package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts +13 -0
  223. package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts.map +1 -0
  224. package/dist/core/i18n/locales/zh-cn/tui-components-misc.js +102 -0
  225. package/dist/core/i18n/locales/zh-cn/tui-components-misc.js.map +1 -0
  226. package/dist/core/i18n/locales/zh-cn/tui-components-selectors.d.ts +12 -0
  227. package/dist/core/i18n/locales/zh-cn/tui-components-selectors.d.ts.map +1 -0
  228. package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js +286 -0
  229. package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js.map +1 -0
  230. package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.d.ts +9 -0
  231. package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.d.ts.map +1 -0
  232. package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.js +79 -0
  233. package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.js.map +1 -0
  234. package/dist/core/i18n/locales/zh-cn/tui-self-owned.d.ts +8 -0
  235. package/dist/core/i18n/locales/zh-cn/tui-self-owned.d.ts.map +1 -0
  236. package/dist/core/i18n/locales/zh-cn/tui-self-owned.js +72 -0
  237. package/dist/core/i18n/locales/zh-cn/tui-self-owned.js.map +1 -0
  238. package/dist/core/keybindings.d.ts +15 -0
  239. package/dist/core/keybindings.d.ts.map +1 -1
  240. package/dist/core/keybindings.js +18 -0
  241. package/dist/core/keybindings.js.map +1 -1
  242. package/dist/core/logger.d.ts.map +1 -1
  243. package/dist/core/logger.js +5 -1
  244. package/dist/core/logger.js.map +1 -1
  245. package/dist/core/model-config.d.ts +0 -1
  246. package/dist/core/model-config.d.ts.map +1 -1
  247. package/dist/core/model-config.js +9 -1
  248. package/dist/core/model-config.js.map +1 -1
  249. package/dist/core/model-registry.d.ts.map +1 -1
  250. package/dist/core/model-registry.js +2 -1
  251. package/dist/core/model-registry.js.map +1 -1
  252. package/dist/core/model-runtime.d.ts.map +1 -1
  253. package/dist/core/model-runtime.js +11 -7
  254. package/dist/core/model-runtime.js.map +1 -1
  255. package/dist/core/package-install-host.d.ts.map +1 -1
  256. package/dist/core/package-install-host.js +4 -3
  257. package/dist/core/package-install-host.js.map +1 -1
  258. package/dist/core/package-manager.d.ts.map +1 -1
  259. package/dist/core/package-manager.js +15 -10
  260. package/dist/core/package-manager.js.map +1 -1
  261. package/dist/core/package-resource-collection.d.ts.map +1 -1
  262. package/dist/core/package-resource-collection.js +2 -1
  263. package/dist/core/package-resource-collection.js.map +1 -1
  264. package/dist/core/package-source.d.ts.map +1 -1
  265. package/dist/core/package-source.js +3 -2
  266. package/dist/core/package-source.js.map +1 -1
  267. package/dist/core/provider-composer.d.ts +2 -2
  268. package/dist/core/provider-composer.d.ts.map +1 -1
  269. package/dist/core/provider-composer.js +29 -21
  270. package/dist/core/provider-composer.js.map +1 -1
  271. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  272. package/dist/core/remote-catalog-provider.js +6 -2
  273. package/dist/core/remote-catalog-provider.js.map +1 -1
  274. package/dist/core/resolve-config-value.d.ts.map +1 -1
  275. package/dist/core/resolve-config-value.js +15 -5
  276. package/dist/core/resolve-config-value.js.map +1 -1
  277. package/dist/core/sdk.d.ts +27 -5
  278. package/dist/core/sdk.d.ts.map +1 -1
  279. package/dist/core/sdk.js +80 -55
  280. package/dist/core/sdk.js.map +1 -1
  281. package/dist/core/session-cwd.d.ts.map +1 -1
  282. package/dist/core/session-cwd.js +5 -2
  283. package/dist/core/session-cwd.js.map +1 -1
  284. package/dist/core/session-export.d.ts.map +1 -1
  285. package/dist/core/session-export.js +2 -1
  286. package/dist/core/session-export.js.map +1 -1
  287. package/dist/core/session-manager.d.ts.map +1 -1
  288. package/dist/core/session-manager.js +39 -29
  289. package/dist/core/session-manager.js.map +1 -1
  290. package/dist/core/session-storage.d.ts.map +1 -1
  291. package/dist/core/session-storage.js +3 -3
  292. package/dist/core/session-storage.js.map +1 -1
  293. package/dist/core/settings-manager.d.ts +20 -20
  294. package/dist/core/settings-manager.d.ts.map +1 -1
  295. package/dist/core/settings-manager.js +47 -59
  296. package/dist/core/settings-manager.js.map +1 -1
  297. package/dist/core/slash-commands.d.ts.map +1 -1
  298. package/dist/core/slash-commands.js +53 -32
  299. package/dist/core/slash-commands.js.map +1 -1
  300. package/dist/core/system-prompt.d.ts.map +1 -1
  301. package/dist/core/system-prompt.js +25 -2
  302. package/dist/core/system-prompt.js.map +1 -1
  303. package/dist/core/tools/bash.d.ts.map +1 -1
  304. package/dist/core/tools/bash.js +11 -7
  305. package/dist/core/tools/bash.js.map +1 -1
  306. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  307. package/dist/core/tools/edit-diff.js +9 -4
  308. package/dist/core/tools/edit-diff.js.map +1 -1
  309. package/dist/core/tools/edit.d.ts.map +1 -1
  310. package/dist/core/tools/edit.js +4 -3
  311. package/dist/core/tools/edit.js.map +1 -1
  312. package/dist/core/tools/index.d.ts.map +1 -1
  313. package/dist/core/tools/index.js +3 -2
  314. package/dist/core/tools/index.js.map +1 -1
  315. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  316. package/dist/core/tools/output-accumulator.js +2 -1
  317. package/dist/core/tools/output-accumulator.js.map +1 -1
  318. package/dist/core/tools/read.d.ts.map +1 -1
  319. package/dist/core/tools/read.js +6 -2
  320. package/dist/core/tools/read.js.map +1 -1
  321. package/dist/core/tools/write.d.ts.map +1 -1
  322. package/dist/core/tools/write.js +2 -1
  323. package/dist/core/tools/write.js.map +1 -1
  324. package/dist/durable/durable-service.d.ts.map +1 -1
  325. package/dist/durable/durable-service.js +25 -18
  326. package/dist/durable/durable-service.js.map +1 -1
  327. package/dist/host/checkpoint-commit.d.ts.map +1 -1
  328. package/dist/host/checkpoint-commit.js +2 -1
  329. package/dist/host/checkpoint-commit.js.map +1 -1
  330. package/dist/host/manual-compaction.d.ts.map +1 -1
  331. package/dist/host/manual-compaction.js +2 -1
  332. package/dist/host/manual-compaction.js.map +1 -1
  333. package/dist/host/output-projection.d.ts +0 -13
  334. package/dist/host/output-projection.d.ts.map +1 -1
  335. package/dist/host/output-projection.js +16 -2
  336. package/dist/host/output-projection.js.map +1 -1
  337. package/dist/host/summary-retry.d.ts.map +1 -1
  338. package/dist/host/summary-retry.js +3 -2
  339. package/dist/host/summary-retry.js.map +1 -1
  340. package/dist/main.d.ts.map +1 -1
  341. package/dist/main.js +97 -60
  342. package/dist/main.js.map +1 -1
  343. package/dist/modes/interactive/components/agents-view.d.ts.map +1 -1
  344. package/dist/modes/interactive/components/agents-view.js +18 -15
  345. package/dist/modes/interactive/components/agents-view.js.map +1 -1
  346. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  347. package/dist/modes/interactive/components/assistant-message.js +6 -5
  348. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  349. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  350. package/dist/modes/interactive/components/bash-execution.js +12 -7
  351. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  352. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  353. package/dist/modes/interactive/components/bordered-loader.js +2 -1
  354. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  355. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  356. package/dist/modes/interactive/components/branch-summary-message.js +6 -5
  357. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  358. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  359. package/dist/modes/interactive/components/compaction-summary-message.js +9 -5
  360. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  361. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  362. package/dist/modes/interactive/components/config-selector.js +18 -15
  363. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  364. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  365. package/dist/modes/interactive/components/custom-entry.js +2 -1
  366. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  367. package/dist/modes/interactive/components/dialog-editor.d.ts.map +1 -1
  368. package/dist/modes/interactive/components/dialog-editor.js +5 -4
  369. package/dist/modes/interactive/components/dialog-editor.js.map +1 -1
  370. package/dist/modes/interactive/components/dialog-input.d.ts.map +1 -1
  371. package/dist/modes/interactive/components/dialog-input.js +2 -1
  372. package/dist/modes/interactive/components/dialog-input.js.map +1 -1
  373. package/dist/modes/interactive/components/dialog-selector.d.ts.map +1 -1
  374. package/dist/modes/interactive/components/dialog-selector.js +4 -3
  375. package/dist/modes/interactive/components/dialog-selector.js.map +1 -1
  376. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  377. package/dist/modes/interactive/components/first-time-setup.js +11 -10
  378. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  379. package/dist/modes/interactive/components/footer.d.ts +0 -2
  380. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  381. package/dist/modes/interactive/components/footer.js +8 -10
  382. package/dist/modes/interactive/components/footer.js.map +1 -1
  383. package/dist/modes/interactive/components/index.d.ts +1 -0
  384. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  385. package/dist/modes/interactive/components/index.js +1 -0
  386. package/dist/modes/interactive/components/index.js.map +1 -1
  387. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  388. package/dist/modes/interactive/components/keybinding-hints.js +3 -2
  389. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  390. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  391. package/dist/modes/interactive/components/login-dialog.js +12 -11
  392. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  393. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
  394. package/dist/modes/interactive/components/mermaid.js +6 -2
  395. package/dist/modes/interactive/components/mermaid.js.map +1 -1
  396. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  397. package/dist/modes/interactive/components/model-selector.js +28 -16
  398. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  399. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  400. package/dist/modes/interactive/components/oauth-selector.js +10 -9
  401. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  402. package/dist/modes/interactive/components/plugin-manager-entry.d.ts.map +1 -1
  403. package/dist/modes/interactive/components/plugin-manager-entry.js +22 -13
  404. package/dist/modes/interactive/components/plugin-manager-entry.js.map +1 -1
  405. package/dist/modes/interactive/components/plugin-selection-entry.d.ts.map +1 -1
  406. package/dist/modes/interactive/components/plugin-selection-entry.js +27 -12
  407. package/dist/modes/interactive/components/plugin-selection-entry.js.map +1 -1
  408. package/dist/modes/interactive/components/queue-manager-selector.d.ts +60 -0
  409. package/dist/modes/interactive/components/queue-manager-selector.d.ts.map +1 -0
  410. package/dist/modes/interactive/components/queue-manager-selector.js +166 -0
  411. package/dist/modes/interactive/components/queue-manager-selector.js.map +1 -0
  412. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  413. package/dist/modes/interactive/components/scoped-models-selector.js +16 -14
  414. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  415. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  416. package/dist/modes/interactive/components/session-selector.js +43 -31
  417. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  418. package/dist/modes/interactive/components/settings-selector.d.ts +4 -6
  419. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  420. package/dist/modes/interactive/components/settings-selector.js +115 -120
  421. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  422. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
  423. package/dist/modes/interactive/components/settings-submenu.js +5 -4
  424. package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
  425. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  426. package/dist/modes/interactive/components/show-images-selector.js +3 -2
  427. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  428. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  429. package/dist/modes/interactive/components/skill-invocation-message.js +4 -3
  430. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  431. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  432. package/dist/modes/interactive/components/status-indicator.js +14 -5
  433. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  434. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  435. package/dist/modes/interactive/components/theme-selector.js +2 -1
  436. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  437. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  438. package/dist/modes/interactive/components/thinking-selector.js +11 -4
  439. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  440. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  441. package/dist/modes/interactive/components/tool-execution.js +8 -3
  442. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  443. package/dist/modes/interactive/components/tree-list.d.ts.map +1 -1
  444. package/dist/modes/interactive/components/tree-list.js +7 -6
  445. package/dist/modes/interactive/components/tree-list.js.map +1 -1
  446. package/dist/modes/interactive/components/tree-render.d.ts.map +1 -1
  447. package/dist/modes/interactive/components/tree-render.js +28 -23
  448. package/dist/modes/interactive/components/tree-render.js.map +1 -1
  449. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  450. package/dist/modes/interactive/components/tree-selector.js +9 -7
  451. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  452. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  453. package/dist/modes/interactive/components/user-message-selector.js +5 -4
  454. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  455. package/dist/modes/interactive/components/workflow-view.d.ts.map +1 -1
  456. package/dist/modes/interactive/components/workflow-view.js +36 -21
  457. package/dist/modes/interactive/components/workflow-view.js.map +1 -1
  458. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  459. package/dist/modes/interactive/external-editor.js +2 -1
  460. package/dist/modes/interactive/external-editor.js.map +1 -1
  461. package/dist/modes/interactive/interactive-auth.d.ts.map +1 -1
  462. package/dist/modes/interactive/interactive-auth.js +71 -40
  463. package/dist/modes/interactive/interactive-auth.js.map +1 -1
  464. package/dist/modes/interactive/interactive-commands.d.ts +1 -0
  465. package/dist/modes/interactive/interactive-commands.d.ts.map +1 -1
  466. package/dist/modes/interactive/interactive-commands.js +3 -0
  467. package/dist/modes/interactive/interactive-commands.js.map +1 -1
  468. package/dist/modes/interactive/interactive-dialog-ui.d.ts.map +1 -1
  469. package/dist/modes/interactive/interactive-dialog-ui.js +5 -5
  470. package/dist/modes/interactive/interactive-dialog-ui.js.map +1 -1
  471. package/dist/modes/interactive/interactive-format.d.ts.map +1 -1
  472. package/dist/modes/interactive/interactive-format.js +34 -18
  473. package/dist/modes/interactive/interactive-format.js.map +1 -1
  474. package/dist/modes/interactive/interactive-helpers.d.ts.map +1 -1
  475. package/dist/modes/interactive/interactive-helpers.js +7 -2
  476. package/dist/modes/interactive/interactive-helpers.js.map +1 -1
  477. package/dist/modes/interactive/interactive-mode.d.ts +4 -2
  478. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  479. package/dist/modes/interactive/interactive-mode.js +350 -279
  480. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  481. package/dist/modes/interactive/interactive-selectors.d.ts +9 -0
  482. package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
  483. package/dist/modes/interactive/interactive-selectors.js +79 -25
  484. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  485. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  486. package/dist/modes/interactive/theme/theme-controller.js +5 -1
  487. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  488. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  489. package/dist/modes/interactive/theme/theme.js +26 -23
  490. package/dist/modes/interactive/theme/theme.js.map +1 -1
  491. package/dist/modes/json-event.d.ts.map +1 -1
  492. package/dist/modes/json-event.js +3 -2
  493. package/dist/modes/json-event.js.map +1 -1
  494. package/dist/modes/print-mode.d.ts.map +1 -1
  495. package/dist/modes/print-mode.js +3 -2
  496. package/dist/modes/print-mode.js.map +1 -1
  497. package/dist/modes/rpc/rpc-client.d.ts +0 -8
  498. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  499. package/dist/modes/rpc/rpc-client.js +3 -14
  500. package/dist/modes/rpc/rpc-client.js.map +1 -1
  501. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  502. package/dist/modes/rpc/rpc-mode.js +0 -9
  503. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  504. package/dist/modes/rpc/rpc-types.d.ts +0 -19
  505. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  506. package/dist/modes/rpc/rpc-types.js.map +1 -1
  507. package/dist/package-manager-cli.d.ts.map +1 -1
  508. package/dist/package-manager-cli.js +28 -13
  509. package/dist/package-manager-cli.js.map +1 -1
  510. package/dist/plugins/ecosystem/catalog.d.ts.map +1 -1
  511. package/dist/plugins/ecosystem/catalog.js +3 -2
  512. package/dist/plugins/ecosystem/catalog.js.map +1 -1
  513. package/dist/plugins/ecosystem/cli.d.ts.map +1 -1
  514. package/dist/plugins/ecosystem/cli.js +2 -1
  515. package/dist/plugins/ecosystem/cli.js.map +1 -1
  516. package/dist/plugins/ecosystem/default-plugin-market.d.ts.map +1 -1
  517. package/dist/plugins/ecosystem/default-plugin-market.js +3 -2
  518. package/dist/plugins/ecosystem/default-plugin-market.js.map +1 -1
  519. package/dist/plugins/ecosystem/distribution.d.ts.map +1 -1
  520. package/dist/plugins/ecosystem/distribution.js +2 -1
  521. package/dist/plugins/ecosystem/distribution.js.map +1 -1
  522. package/dist/plugins/ecosystem/installer.d.ts.map +1 -1
  523. package/dist/plugins/ecosystem/installer.js +3 -2
  524. package/dist/plugins/ecosystem/installer.js.map +1 -1
  525. package/dist/plugins/ecosystem/node-disk-registry-source.d.ts.map +1 -1
  526. package/dist/plugins/ecosystem/node-disk-registry-source.js +20 -17
  527. package/dist/plugins/ecosystem/node-disk-registry-source.js.map +1 -1
  528. package/dist/plugins/ecosystem/node-distribution-host.d.ts.map +1 -1
  529. package/dist/plugins/ecosystem/node-distribution-host.js +35 -34
  530. package/dist/plugins/ecosystem/node-distribution-host.js.map +1 -1
  531. package/dist/plugins/ecosystem/node-npm-registry-source.d.ts.map +1 -1
  532. package/dist/plugins/ecosystem/node-npm-registry-source.js +35 -34
  533. package/dist/plugins/ecosystem/node-npm-registry-source.js.map +1 -1
  534. package/dist/plugins/ecosystem/node-package-install-host.d.ts.map +1 -1
  535. package/dist/plugins/ecosystem/node-package-install-host.js +9 -8
  536. package/dist/plugins/ecosystem/node-package-install-host.js.map +1 -1
  537. package/dist/plugins/ecosystem/node-package-install-persistence.d.ts.map +1 -1
  538. package/dist/plugins/ecosystem/node-package-install-persistence.js +4 -3
  539. package/dist/plugins/ecosystem/node-package-install-persistence.js.map +1 -1
  540. package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts +9 -2
  541. package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts.map +1 -1
  542. package/dist/plugins/ecosystem/node-plugin-bootstrap.js +44 -5
  543. package/dist/plugins/ecosystem/node-plugin-bootstrap.js.map +1 -1
  544. package/dist/plugins/ecosystem/node-plugin-trust-root.d.ts.map +1 -1
  545. package/dist/plugins/ecosystem/node-plugin-trust-root.js +10 -9
  546. package/dist/plugins/ecosystem/node-plugin-trust-root.js.map +1 -1
  547. package/dist/plugins/ecosystem/node-registry-source.d.ts.map +1 -1
  548. package/dist/plugins/ecosystem/node-registry-source.js +31 -30
  549. package/dist/plugins/ecosystem/node-registry-source.js.map +1 -1
  550. package/dist/plugins/ecosystem/node-release-package-source.d.ts.map +1 -1
  551. package/dist/plugins/ecosystem/node-release-package-source.js +30 -29
  552. package/dist/plugins/ecosystem/node-release-package-source.js.map +1 -1
  553. package/dist/plugins/ecosystem/node-tar-writer.d.ts.map +1 -1
  554. package/dist/plugins/ecosystem/node-tar-writer.js +11 -10
  555. package/dist/plugins/ecosystem/node-tar-writer.js.map +1 -1
  556. package/dist/plugins/ecosystem/node-url-package-source.d.ts.map +1 -1
  557. package/dist/plugins/ecosystem/node-url-package-source.js +21 -20
  558. package/dist/plugins/ecosystem/node-url-package-source.js.map +1 -1
  559. package/dist/plugins/ecosystem/plugin-acquisition.d.ts.map +1 -1
  560. package/dist/plugins/ecosystem/plugin-acquisition.js +3 -2
  561. package/dist/plugins/ecosystem/plugin-acquisition.js.map +1 -1
  562. package/dist/plugins/ecosystem/plugin-bootstrap.d.ts +9 -1
  563. package/dist/plugins/ecosystem/plugin-bootstrap.d.ts.map +1 -1
  564. package/dist/plugins/ecosystem/plugin-bootstrap.js +5 -0
  565. package/dist/plugins/ecosystem/plugin-bootstrap.js.map +1 -1
  566. package/dist/plugins/ecosystem/registry-cli-adapter.d.ts.map +1 -1
  567. package/dist/plugins/ecosystem/registry-cli-adapter.js +2 -1
  568. package/dist/plugins/ecosystem/registry-cli-adapter.js.map +1 -1
  569. package/dist/plugins/ecosystem/registry.d.ts.map +1 -1
  570. package/dist/plugins/ecosystem/registry.js +35 -32
  571. package/dist/plugins/ecosystem/registry.js.map +1 -1
  572. package/dist/plugins/ecosystem/resolver.d.ts.map +1 -1
  573. package/dist/plugins/ecosystem/resolver.js +3 -2
  574. package/dist/plugins/ecosystem/resolver.js.map +1 -1
  575. package/dist/plugins/ecosystem/selection-store.d.ts.map +1 -1
  576. package/dist/plugins/ecosystem/selection-store.js +11 -10
  577. package/dist/plugins/ecosystem/selection-store.js.map +1 -1
  578. package/dist/plugins/ecosystem/selection.d.ts.map +1 -1
  579. package/dist/plugins/ecosystem/selection.js +8 -7
  580. package/dist/plugins/ecosystem/selection.js.map +1 -1
  581. package/dist/plugins/ecosystem/state.d.ts.map +1 -1
  582. package/dist/plugins/ecosystem/state.js +24 -23
  583. package/dist/plugins/ecosystem/state.js.map +1 -1
  584. package/dist/plugins/ecosystem/updates.d.ts.map +1 -1
  585. package/dist/plugins/ecosystem/updates.js +5 -4
  586. package/dist/plugins/ecosystem/updates.js.map +1 -1
  587. package/dist/plugins/mcp-http.d.ts +0 -17
  588. package/dist/plugins/mcp-http.d.ts.map +1 -1
  589. package/dist/plugins/mcp-http.js +30 -7
  590. package/dist/plugins/mcp-http.js.map +1 -1
  591. package/dist/plugins/plugin-supervisor.d.ts.map +1 -1
  592. package/dist/plugins/plugin-supervisor.js +19 -1
  593. package/dist/plugins/plugin-supervisor.js.map +1 -1
  594. package/dist/profile/first-roles.d.ts.map +1 -1
  595. package/dist/profile/first-roles.js +10 -1
  596. package/dist/profile/first-roles.js.map +1 -1
  597. package/dist/profile/goal-plugin.d.ts.map +1 -1
  598. package/dist/profile/goal-plugin.js +24 -5
  599. package/dist/profile/goal-plugin.js.map +1 -1
  600. package/dist/profile/identity.d.ts.map +1 -1
  601. package/dist/profile/identity.js +7 -6
  602. package/dist/profile/identity.js.map +1 -1
  603. package/dist/profile/lock.d.ts.map +1 -1
  604. package/dist/profile/lock.js +15 -1
  605. package/dist/profile/lock.js.map +1 -1
  606. package/dist/profile/plan-plugin.d.ts.map +1 -1
  607. package/dist/profile/plan-plugin.js +26 -13
  608. package/dist/profile/plan-plugin.js.map +1 -1
  609. package/dist/profile/plugin-profiles.d.ts.map +1 -1
  610. package/dist/profile/plugin-profiles.js +2 -1
  611. package/dist/profile/plugin-profiles.js.map +1 -1
  612. package/dist/profile/policy-manifest.d.ts.map +1 -1
  613. package/dist/profile/policy-manifest.js +5 -4
  614. package/dist/profile/policy-manifest.js.map +1 -1
  615. package/dist/profile/profile-registry.d.ts +0 -12
  616. package/dist/profile/profile-registry.d.ts.map +1 -1
  617. package/dist/profile/profile-registry.js +14 -1
  618. package/dist/profile/profile-registry.js.map +1 -1
  619. package/dist/profile/role-catalog.d.ts +0 -1
  620. package/dist/profile/role-catalog.d.ts.map +1 -1
  621. package/dist/profile/role-catalog.js +17 -15
  622. package/dist/profile/role-catalog.js.map +1 -1
  623. package/dist/profile/role-orchestrator.d.ts.map +1 -1
  624. package/dist/profile/role-orchestrator.js +8 -7
  625. package/dist/profile/role-orchestrator.js.map +1 -1
  626. package/dist/profile/role-runner.d.ts.map +1 -1
  627. package/dist/profile/role-runner.js +3 -2
  628. package/dist/profile/role-runner.js.map +1 -1
  629. package/dist/profile/root-facade.d.ts.map +1 -1
  630. package/dist/profile/root-facade.js +2 -1
  631. package/dist/profile/root-facade.js.map +1 -1
  632. package/dist/profile/skill-discovery-wiring.d.ts.map +1 -1
  633. package/dist/profile/skill-discovery-wiring.js +7 -2
  634. package/dist/profile/skill-discovery-wiring.js.map +1 -1
  635. package/dist/profile/state-store.d.ts.map +1 -1
  636. package/dist/profile/state-store.js +13 -9
  637. package/dist/profile/state-store.js.map +1 -1
  638. package/dist/profile/todo-plugin.d.ts.map +1 -1
  639. package/dist/profile/todo-plugin.js +9 -4
  640. package/dist/profile/todo-plugin.js.map +1 -1
  641. package/dist/profiles/builtin-suites.d.ts +13 -6
  642. package/dist/profiles/builtin-suites.d.ts.map +1 -1
  643. package/dist/profiles/builtin-suites.js +15 -6
  644. package/dist/profiles/builtin-suites.js.map +1 -1
  645. package/dist/profiles/suite-loader.d.ts +25 -1
  646. package/dist/profiles/suite-loader.d.ts.map +1 -1
  647. package/dist/profiles/suite-loader.js +34 -9
  648. package/dist/profiles/suite-loader.js.map +1 -1
  649. package/dist/remote/server-entry.d.ts.map +1 -1
  650. package/dist/remote/server-entry.js +3 -2
  651. package/dist/remote/server-entry.js.map +1 -1
  652. package/dist/remote/session-source.d.ts.map +1 -1
  653. package/dist/remote/session-source.js +8 -4
  654. package/dist/remote/session-source.js.map +1 -1
  655. package/dist/share/session-share.d.ts.map +1 -1
  656. package/dist/share/session-share.js +14 -2
  657. package/dist/share/session-share.js.map +1 -1
  658. package/dist/testing/plugin-testkit.d.ts.map +1 -1
  659. package/dist/testing/plugin-testkit.js +4 -3
  660. package/dist/testing/plugin-testkit.js.map +1 -1
  661. package/dist/testing/runtime-delivery-queue.d.ts.map +1 -1
  662. package/dist/testing/runtime-delivery-queue.js +2 -1
  663. package/dist/testing/runtime-delivery-queue.js.map +1 -1
  664. package/dist/testing/session-plugin-testkit.d.ts.map +1 -1
  665. package/dist/testing/session-plugin-testkit.js +10 -7
  666. package/dist/testing/session-plugin-testkit.js.map +1 -1
  667. package/dist/utils/ansi.d.ts.map +1 -1
  668. package/dist/utils/ansi.js +2 -1
  669. package/dist/utils/ansi.js.map +1 -1
  670. package/dist/utils/clipboard.d.ts.map +1 -1
  671. package/dist/utils/clipboard.js +7 -6
  672. package/dist/utils/clipboard.js.map +1 -1
  673. package/dist/utils/image-resize-worker.d.ts.map +1 -1
  674. package/dist/utils/image-resize-worker.js +3 -2
  675. package/dist/utils/image-resize-worker.js.map +1 -1
  676. package/dist/utils/photon.d.ts +2 -2
  677. package/dist/utils/photon.d.ts.map +1 -1
  678. package/dist/utils/photon.js +2 -2
  679. package/dist/utils/photon.js.map +1 -1
  680. package/dist/utils/shell.d.ts.map +1 -1
  681. package/dist/utils/shell.js +9 -8
  682. package/dist/utils/shell.js.map +1 -1
  683. package/dist/utils/tools-manager.d.ts.map +1 -1
  684. package/dist/utils/tools-manager.js +23 -13
  685. package/dist/utils/tools-manager.js.map +1 -1
  686. package/dist/utils/version-check.d.ts.map +1 -1
  687. package/dist/utils/version-check.js +5 -1
  688. package/dist/utils/version-check.js.map +1 -1
  689. package/docs/compaction.md +1 -3
  690. package/docs/docs.json +4 -0
  691. package/docs/index.md +1 -0
  692. package/docs/keybindings.md +3 -0
  693. package/docs/mcp.md +103 -0
  694. package/docs/models.md +14 -22
  695. package/docs/providers.md +0 -1
  696. package/docs/quickstart.md +1 -1
  697. package/docs/rpc.md +1 -26
  698. package/docs/sdk.md +4 -6
  699. package/docs/settings.md +10 -12
  700. package/docs/skills.md +1 -9
  701. package/docs/terminal-setup.md +2 -3
  702. package/docs/usage.md +7 -6
  703. package/examples/extensions/with-deps/package-lock.json +2 -2
  704. package/examples/extensions/with-deps/package.json +1 -1
  705. package/examples/extensions/with-deps/plugin.json +1 -1
  706. package/examples/sdk/10-settings.ts +2 -4
  707. package/examples/sdk/12-full-control.ts +1 -2
  708. package/package.json +1 -3
  709. package/dist/bundle/chunks/chunk-EALJ5DDX.js +0 -1452
  710. package/dist/core/extensions/microcompact.d.ts +0 -80
  711. package/dist/core/extensions/microcompact.d.ts.map +0 -1
  712. package/dist/core/extensions/microcompact.js +0 -134
  713. package/dist/core/extensions/microcompact.js.map +0 -1
  714. package/dist/server/create-harness.d.ts +0 -26
  715. package/dist/server/create-harness.d.ts.map +0 -1
  716. package/dist/server/create-harness.js +0 -106
  717. package/dist/server/create-harness.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-commands.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-commands.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Slash-command dispatch table for the interactive mode editor submit handler.\n * Extracted from InteractiveMode.setupEditorSubmitHandler; entry order mirrors\n * the original if-chain and each run body mirrors its branch verbatim\n * (await/no-await and editor clearing order included).\n */\n\n/**\n * Narrow facade InteractiveMode exposes to the dispatch table. Entries resolve\n * handlers through this interface at dispatch time, so instance-level\n * overrides keep working.\n */\nexport interface CommandDispatchHost {\n\tsetEditorText(text: string): void;\n\tshowSettingsSelector(): void;\n\tshowModelsSelector(): void;\n\thandleModelCommand(searchTerm?: string): Promise<void>;\n\thandleThinkingCommand(searchTerm?: string): void;\n\thandleSuiteCommand(suiteId?: string): void;\n\thandleExportCommand(text: string): Promise<void>;\n\thandleImportCommand(text: string): Promise<void>;\n\thandleCopyCommand(options?: { flashConfirmation?: boolean; preferSelection?: boolean }): Promise<void>;\n\thandleNameCommand(text: string): void;\n\thandleSessionCommand(): void;\n\t/** Interrupt grading (§4.2): terminate every background subagent; the\n\t * /stop-agents command's single execution face. */\n\thandleStopAgentsCommand(): void;\n\thandleMetricsCommand(turnsArg: string | undefined): void;\n\thandleChangelogCommand(): void;\n\thandleHelpCommand(): void;\n\thandleHotkeysCommand(): void;\n\tshowUserMessageSelector(): void;\n\thandleCloneCommand(): Promise<void>;\n\tshowTreeSelector(initialSelectedId?: string): void;\n\thandleLoginCommand(providerRef?: string): Promise<void>;\n\tshowOAuthSelector(mode: \"login\" | \"logout\"): Promise<void>;\n\thandleClearCommand(): Promise<void>;\n\thandleCompactCommand(customInstructions?: string): Promise<void>;\n\thandleReloadCommand(): Promise<void>;\n\thandleDebugCommand(): void;\n\thandleArminSaysHi(): void;\n\tshowSessionSelector(): void;\n\tshowAgentsView(): void;\n\thandleQueueCommand(text: string | undefined): Promise<void>;\n\thandleDequeueCommand(): void;\n\thandleEditorCommand(): Promise<void>;\n\tshutdown(options?: { fromSignal?: boolean }): Promise<void>;\n\tshowWorkflowView(): void;\n}\n\nexport interface CommandDispatchEntry {\n\t/** Command word including the leading slash, e.g. \"/model\". */\n\tcommand: string;\n\t/**\n\t * Slice offset of the optional argument for prefix commands\n\t * (\"/model claude\" -> text.slice(7).trim()); omit for exact-match commands.\n\t */\n\targOffset?: number;\n\t/** Report a blank (empty after trim) argument as undefined. */\n\tblankArgToUndefined?: boolean;\n\t/** Clear the editor text before running the handler instead of after. */\n\tclearEditorBeforeRun?: boolean;\n\t/** Handler; receives the full submitted text and the extracted argument. */\n\trun: (host: CommandDispatchHost, text: string, arg: string | undefined) => Promise<void> | void;\n}\n\nexport interface CommandDispatchMatch {\n\tentry: CommandDispatchEntry;\n\targ: string | undefined;\n}\n\nexport const COMMAND_DISPATCH_ENTRIES: readonly CommandDispatchEntry[] = [\n\t{\n\t\tcommand: \"/settings\",\n\t\trun: (host) => {\n\t\t\thost.showSettingsSelector();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/scoped-models\",\n\t\tclearEditorBeforeRun: true,\n\t\trun: async (host) => {\n\t\t\tawait host.showModelsSelector();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/model\",\n\t\targOffset: 7,\n\t\tclearEditorBeforeRun: true,\n\t\trun: (host, _text, arg) => host.handleModelCommand(arg),\n\t},\n\t{\n\t\tcommand: \"/thinking\",\n\t\targOffset: 10,\n\t\tclearEditorBeforeRun: true,\n\t\trun: (host, _text, arg) => {\n\t\t\thost.handleThinkingCommand(arg);\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/suite\",\n\t\targOffset: 7,\n\t\tblankArgToUndefined: true,\n\t\tclearEditorBeforeRun: true,\n\t\trun: (host, _text, arg) => {\n\t\t\thost.handleSuiteCommand(arg);\n\t\t},\n\t},\n\t// /export, /import and /name are prefix commands whose handlers parse the\n\t// full text themselves; argOffset only enables prefix matching here.\n\t{ command: \"/export\", argOffset: 8, run: (host, text) => host.handleExportCommand(text) },\n\t{ command: \"/import\", argOffset: 8, run: (host, text) => host.handleImportCommand(text) },\n\t{ command: \"/copy\", run: (host) => host.handleCopyCommand() },\n\t{\n\t\tcommand: \"/name\",\n\t\targOffset: 6,\n\t\trun: (host, text) => {\n\t\t\thost.handleNameCommand(text);\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/session\",\n\t\trun: (host) => {\n\t\t\thost.handleSessionCommand();\n\t\t},\n\t},\n\t// Interrupt grading (设计 子代理运行时 §4.2, 2026-10-02): the only explicit\n\t// face for terminating background subagents — Esc never cancels them.\n\t{\n\t\tcommand: \"/stop-agents\",\n\t\trun: (host) => {\n\t\t\thost.handleStopAgentsCommand();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/metrics\",\n\t\targOffset: 9,\n\t\tblankArgToUndefined: true,\n\t\tclearEditorBeforeRun: true,\n\t\trun: (host, _text, arg) => {\n\t\t\thost.handleMetricsCommand(arg);\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/changelog\",\n\t\trun: (host) => {\n\t\t\thost.handleChangelogCommand();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/help\",\n\t\trun: (host) => {\n\t\t\thost.handleHelpCommand();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/hotkeys\",\n\t\trun: (host) => {\n\t\t\thost.handleHotkeysCommand();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/fork\",\n\t\trun: (host) => {\n\t\t\thost.showUserMessageSelector();\n\t\t},\n\t},\n\t{ command: \"/clone\", clearEditorBeforeRun: true, run: (host) => host.handleCloneCommand() },\n\t{\n\t\tcommand: \"/tree\",\n\t\trun: (host) => {\n\t\t\thost.showTreeSelector();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/login\",\n\t\targOffset: 7,\n\t\tclearEditorBeforeRun: true,\n\t\trun: (host, _text, arg) => host.handleLoginCommand(arg),\n\t},\n\t// Original branch does not await showOAuthSelector; keep it fire-and-forget.\n\t{\n\t\tcommand: \"/logout\",\n\t\trun: (host) => {\n\t\t\tvoid host.showOAuthSelector(\"logout\");\n\t\t},\n\t},\n\t{ command: \"/new\", clearEditorBeforeRun: true, run: (host) => host.handleClearCommand() },\n\t{\n\t\tcommand: \"/compact\",\n\t\targOffset: 9,\n\t\tclearEditorBeforeRun: true,\n\t\trun: (host, _text, arg) => host.handleCompactCommand(arg),\n\t},\n\t{ command: \"/reload\", clearEditorBeforeRun: true, run: (host) => host.handleReloadCommand() },\n\t{\n\t\tcommand: \"/debug\",\n\t\trun: (host) => {\n\t\t\thost.handleDebugCommand();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/arminsayshi\",\n\t\trun: (host) => {\n\t\t\thost.handleArminSaysHi();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/resume\",\n\t\trun: (host) => {\n\t\t\thost.showSessionSelector();\n\t\t},\n\t},\n\t// Read-only subagent session browser (view-family command: sync, no editor\n\t// clearing), grouped with /resume ahead of the /workflow view overlay.\n\t{\n\t\tcommand: \"/agents\",\n\t\trun: (host) => {\n\t\t\thost.showAgentsView();\n\t\t},\n\t},\n\t// Follow-up queue face (single-entry iron law: /queue replaces the shipped\n\t// ctrl+q default). A bare /queue prints usage — the editor buffer is\n\t// cleared on submit before the command runs, so there is no editor\n\t// content to queue (the configurable keybinding keeps that behavior).\n\t{\n\t\tcommand: \"/queue\",\n\t\targOffset: 7,\n\t\tblankArgToUndefined: true,\n\t\trun: (host, _text, arg) => host.handleQueueCommand(arg),\n\t},\n\t{ command: \"/dequeue\", run: (host) => host.handleDequeueCommand() },\n\t{ command: \"/editor\", run: (host) => host.handleEditorCommand() },\n\t{ command: \"/quit\", clearEditorBeforeRun: true, run: (host) => host.shutdown() },\n\t// Exact-match only: every other /workflow subcommand (why/log/...) keeps\n\t// flowing to the plugin's text command path untouched (§9 L2).\n\t{\n\t\tcommand: \"/workflow view\",\n\t\trun: (host) => {\n\t\t\thost.showWorkflowView();\n\t\t},\n\t},\n];\n\n/** Find the entry matching text: exact command, or command prefix plus argument. */\nexport function matchCommandDispatchEntry(\n\tentries: readonly CommandDispatchEntry[],\n\ttext: string,\n): CommandDispatchMatch | undefined {\n\tfor (const entry of entries) {\n\t\tif (text === entry.command) {\n\t\t\treturn { entry, arg: undefined };\n\t\t}\n\t\tif (entry.argOffset === undefined || !text.startsWith(`${entry.command} `)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst arg = text.slice(entry.argOffset).trim();\n\t\treturn { entry, arg: entry.blankArgToUndefined && arg.length === 0 ? undefined : arg };\n\t}\n\treturn undefined;\n}\n\n/** Minimal command shape the completion filter works on (mirrors SlashCommand). */\nexport interface CompletionCommandInput {\n\treadonly name: string;\n\treadonly description: string;\n\treadonly argumentHint?: string;\n}\n\n/**\n * Capability commands that collide with a builtin, prompt-template, or skill\n * command name are rejected by AgentSession at invocation time rather than\n * silently resolving to one source, so the colliding capability command is\n * withheld from the completion list entirely (both sides stay executable via\n * their own paths; neither is offered as an ambiguous completion).\n */\nexport function filterCapabilityCommandsForCompletions(\n\tcapabilityCommands: readonly CompletionCommandInput[],\n\treservedNames: readonly Iterable<string>[],\n): CompletionCommandInput[] {\n\tconst reserved = new Set<string>();\n\tfor (const names of reservedNames) for (const name of names) reserved.add(name);\n\treturn capabilityCommands\n\t\t.filter((command) => !reserved.has(command.name))\n\t\t.map((command) => ({\n\t\t\tname: command.name,\n\t\t\tdescription: command.description,\n\t\t\t...(command.argumentHint !== undefined ? { argumentHint: command.argumentHint } : {}),\n\t\t}));\n}\n"]}
1
+ {"version":3,"file":"interactive-commands.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-commands.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Slash-command dispatch table for the interactive mode editor submit handler.\n * Extracted from InteractiveMode.setupEditorSubmitHandler; entry order mirrors\n * the original if-chain and each run body mirrors its branch verbatim\n * (await/no-await and editor clearing order included).\n */\n\n/**\n * Narrow facade InteractiveMode exposes to the dispatch table. Entries resolve\n * handlers through this interface at dispatch time, so instance-level\n * overrides keep working.\n */\nexport interface CommandDispatchHost {\n\tsetEditorText(text: string): void;\n\tshowSettingsSelector(): void;\n\tshowModelsSelector(): void;\n\thandleModelCommand(searchTerm?: string): Promise<void>;\n\thandleThinkingCommand(searchTerm?: string): void;\n\thandleSuiteCommand(suiteId?: string): void;\n\thandleExportCommand(text: string): Promise<void>;\n\thandleImportCommand(text: string): Promise<void>;\n\thandleCopyCommand(options?: { flashConfirmation?: boolean; preferSelection?: boolean }): Promise<void>;\n\thandleNameCommand(text: string): void;\n\thandleSessionCommand(): void;\n\t/** Interrupt grading (§4.2): terminate every background subagent; the\n\t * /stop-agents command's single execution face. */\n\thandleStopAgentsCommand(): void;\n\thandleMetricsCommand(turnsArg: string | undefined): void;\n\thandleChangelogCommand(): void;\n\thandleHelpCommand(): void;\n\thandleHotkeysCommand(): void;\n\tshowUserMessageSelector(): void;\n\thandleCloneCommand(): Promise<void>;\n\tshowTreeSelector(initialSelectedId?: string): void;\n\thandleLoginCommand(providerRef?: string): Promise<void>;\n\tshowOAuthSelector(mode: \"login\" | \"logout\"): Promise<void>;\n\thandleClearCommand(): Promise<void>;\n\thandleCompactCommand(customInstructions?: string): Promise<void>;\n\thandleReloadCommand(): Promise<void>;\n\thandleDebugCommand(): void;\n\thandleArminSaysHi(): void;\n\tshowSessionSelector(): void;\n\tshowAgentsView(): void;\n\thandleQueueCommand(text: string | undefined): Promise<void>;\n\thandleDequeueCommand(): void;\n\thandleQueueListCommand(): void;\n\thandleEditorCommand(): Promise<void>;\n\tshutdown(options?: { fromSignal?: boolean }): Promise<void>;\n\tshowWorkflowView(): void;\n}\n\nexport interface CommandDispatchEntry {\n\t/** Command word including the leading slash, e.g. \"/model\". */\n\tcommand: string;\n\t/**\n\t * Slice offset of the optional argument for prefix commands\n\t * (\"/model claude\" -> text.slice(7).trim()); omit for exact-match commands.\n\t */\n\targOffset?: number;\n\t/** Report a blank (empty after trim) argument as undefined. */\n\tblankArgToUndefined?: boolean;\n\t/** Clear the editor text before running the handler instead of after. */\n\tclearEditorBeforeRun?: boolean;\n\t/** Handler; receives the full submitted text and the extracted argument. */\n\trun: (host: CommandDispatchHost, text: string, arg: string | undefined) => Promise<void> | void;\n}\n\nexport interface CommandDispatchMatch {\n\tentry: CommandDispatchEntry;\n\targ: string | undefined;\n}\n\nexport const COMMAND_DISPATCH_ENTRIES: readonly CommandDispatchEntry[] = [\n\t{\n\t\tcommand: \"/settings\",\n\t\trun: (host) => {\n\t\t\thost.showSettingsSelector();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/scoped-models\",\n\t\tclearEditorBeforeRun: true,\n\t\trun: async (host) => {\n\t\t\tawait host.showModelsSelector();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/model\",\n\t\targOffset: 7,\n\t\tclearEditorBeforeRun: true,\n\t\trun: (host, _text, arg) => host.handleModelCommand(arg),\n\t},\n\t{\n\t\tcommand: \"/thinking\",\n\t\targOffset: 10,\n\t\tclearEditorBeforeRun: true,\n\t\trun: (host, _text, arg) => {\n\t\t\thost.handleThinkingCommand(arg);\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/suite\",\n\t\targOffset: 7,\n\t\tblankArgToUndefined: true,\n\t\tclearEditorBeforeRun: true,\n\t\trun: (host, _text, arg) => {\n\t\t\thost.handleSuiteCommand(arg);\n\t\t},\n\t},\n\t// /export, /import and /name are prefix commands whose handlers parse the\n\t// full text themselves; argOffset only enables prefix matching here.\n\t{ command: \"/export\", argOffset: 8, run: (host, text) => host.handleExportCommand(text) },\n\t{ command: \"/import\", argOffset: 8, run: (host, text) => host.handleImportCommand(text) },\n\t{ command: \"/copy\", run: (host) => host.handleCopyCommand() },\n\t{\n\t\tcommand: \"/name\",\n\t\targOffset: 6,\n\t\trun: (host, text) => {\n\t\t\thost.handleNameCommand(text);\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/session\",\n\t\trun: (host) => {\n\t\t\thost.handleSessionCommand();\n\t\t},\n\t},\n\t// Interrupt grading (设计 子代理运行时 §4.2, 2026-10-02): the only explicit\n\t// face for terminating background subagents — Esc never cancels them.\n\t{\n\t\tcommand: \"/stop-agents\",\n\t\trun: (host) => {\n\t\t\thost.handleStopAgentsCommand();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/metrics\",\n\t\targOffset: 9,\n\t\tblankArgToUndefined: true,\n\t\tclearEditorBeforeRun: true,\n\t\trun: (host, _text, arg) => {\n\t\t\thost.handleMetricsCommand(arg);\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/changelog\",\n\t\trun: (host) => {\n\t\t\thost.handleChangelogCommand();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/help\",\n\t\trun: (host) => {\n\t\t\thost.handleHelpCommand();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/hotkeys\",\n\t\trun: (host) => {\n\t\t\thost.handleHotkeysCommand();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/fork\",\n\t\trun: (host) => {\n\t\t\thost.showUserMessageSelector();\n\t\t},\n\t},\n\t{ command: \"/clone\", clearEditorBeforeRun: true, run: (host) => host.handleCloneCommand() },\n\t{\n\t\tcommand: \"/tree\",\n\t\trun: (host) => {\n\t\t\thost.showTreeSelector();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/login\",\n\t\targOffset: 7,\n\t\tclearEditorBeforeRun: true,\n\t\trun: (host, _text, arg) => host.handleLoginCommand(arg),\n\t},\n\t// Original branch does not await showOAuthSelector; keep it fire-and-forget.\n\t{\n\t\tcommand: \"/logout\",\n\t\trun: (host) => {\n\t\t\tvoid host.showOAuthSelector(\"logout\");\n\t\t},\n\t},\n\t{ command: \"/new\", clearEditorBeforeRun: true, run: (host) => host.handleClearCommand() },\n\t{\n\t\tcommand: \"/compact\",\n\t\targOffset: 9,\n\t\tclearEditorBeforeRun: true,\n\t\trun: (host, _text, arg) => host.handleCompactCommand(arg),\n\t},\n\t{ command: \"/reload\", clearEditorBeforeRun: true, run: (host) => host.handleReloadCommand() },\n\t{\n\t\tcommand: \"/debug\",\n\t\trun: (host) => {\n\t\t\thost.handleDebugCommand();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/arminsayshi\",\n\t\trun: (host) => {\n\t\t\thost.handleArminSaysHi();\n\t\t},\n\t},\n\t{\n\t\tcommand: \"/resume\",\n\t\trun: (host) => {\n\t\t\thost.showSessionSelector();\n\t\t},\n\t},\n\t// Read-only subagent session browser (view-family command: sync, no editor\n\t// clearing), grouped with /resume ahead of the /workflow view overlay.\n\t{\n\t\tcommand: \"/agents\",\n\t\trun: (host) => {\n\t\t\thost.showAgentsView();\n\t\t},\n\t},\n\t// Follow-up queue face (single-entry iron law: /queue replaces the shipped\n\t// ctrl+q default). A bare /queue prints usage — the editor buffer is\n\t// cleared on submit before the command runs, so there is no editor\n\t// content to queue (the configurable keybinding keeps that behavior).\n\t{\n\t\tcommand: \"/queue\",\n\t\targOffset: 7,\n\t\tblankArgToUndefined: true,\n\t\trun: (host, _text, arg) => host.handleQueueCommand(arg),\n\t},\n\t{ command: \"/dequeue\", run: (host) => host.handleDequeueCommand() },\n\t// Queue manager overlay (single entry point: the /queue-list command;\n\t// reorder/remove/restore are in-component keys of the overlay itself).\n\t{ command: \"/queue-list\", run: (host) => host.handleQueueListCommand() },\n\t{ command: \"/editor\", run: (host) => host.handleEditorCommand() },\n\t{ command: \"/quit\", clearEditorBeforeRun: true, run: (host) => host.shutdown() },\n\t// Exact-match only: every other /workflow subcommand (why/log/...) keeps\n\t// flowing to the plugin's text command path untouched (§9 L2).\n\t{\n\t\tcommand: \"/workflow view\",\n\t\trun: (host) => {\n\t\t\thost.showWorkflowView();\n\t\t},\n\t},\n];\n\n/** Find the entry matching text: exact command, or command prefix plus argument. */\nexport function matchCommandDispatchEntry(\n\tentries: readonly CommandDispatchEntry[],\n\ttext: string,\n): CommandDispatchMatch | undefined {\n\tfor (const entry of entries) {\n\t\tif (text === entry.command) {\n\t\t\treturn { entry, arg: undefined };\n\t\t}\n\t\tif (entry.argOffset === undefined || !text.startsWith(`${entry.command} `)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst arg = text.slice(entry.argOffset).trim();\n\t\treturn { entry, arg: entry.blankArgToUndefined && arg.length === 0 ? undefined : arg };\n\t}\n\treturn undefined;\n}\n\n/** Minimal command shape the completion filter works on (mirrors SlashCommand). */\nexport interface CompletionCommandInput {\n\treadonly name: string;\n\treadonly description: string;\n\treadonly argumentHint?: string;\n}\n\n/**\n * Capability commands that collide with a builtin, prompt-template, or skill\n * command name are rejected by AgentSession at invocation time rather than\n * silently resolving to one source, so the colliding capability command is\n * withheld from the completion list entirely (both sides stay executable via\n * their own paths; neither is offered as an ambiguous completion).\n */\nexport function filterCapabilityCommandsForCompletions(\n\tcapabilityCommands: readonly CompletionCommandInput[],\n\treservedNames: readonly Iterable<string>[],\n): CompletionCommandInput[] {\n\tconst reserved = new Set<string>();\n\tfor (const names of reservedNames) for (const name of names) reserved.add(name);\n\treturn capabilityCommands\n\t\t.filter((command) => !reserved.has(command.name))\n\t\t.map((command) => ({\n\t\t\tname: command.name,\n\t\t\tdescription: command.description,\n\t\t\t...(command.argumentHint !== undefined ? { argumentHint: command.argumentHint } : {}),\n\t\t}));\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-dialog-ui.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-dialog-ui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Dialog UI surface for the interactive mode (extracted from interactive-mode.ts).\n *\n * This module holds the blocking dialog primitives (selector/input/editor),\n * notifications, and the InteractionHostV1 factory backing the interaction\n * capability. InteractiveMode owns the mutable state and receives it through\n * the DialogUiHost interface, mirroring the CommandDispatchHost pattern in\n * ./interactive-commands.ts. Calls go through the host so instance-level\n * overrides keep working.\n */\n\nimport type { Component, Container, TUI } from \"@agent-forge/tui\";\nimport type { InteractionDialogOptions, InteractionHostV1, InteractionOutcomeV1 } from \"../../core/extensions/index.ts\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport { DialogEditorComponent } from \"./components/dialog-editor.ts\";\nimport { DialogInputComponent } from \"./components/dialog-input.ts\";\nimport { DialogSelectorComponent } from \"./components/dialog-selector.ts\";\n\n/** Interface for components that can be expanded/collapsed */\nexport interface Expandable {\n\tsetExpanded(expanded: boolean): void;\n}\n\nexport function isExpandable(obj: unknown): obj is Expandable {\n\treturn typeof obj === \"object\" && obj !== null && \"setExpanded\" in obj && typeof obj.setExpanded === \"function\";\n}\n\n/**\n * Map a legacy TUI dialog result (select/input: string | undefined, confirm:\n * boolean) onto the frozen interaction outcome. A dismissed dialog (undefined)\n * yields \"cancelled\"; every concrete answer — including a confirm \"No\"\n * (false) — yields \"answered\".\n */\nexport function mapLegacyDialogResultToOutcome(result: string | boolean | undefined): InteractionOutcomeV1 {\n\tif (result === undefined) return { status: \"cancelled\" };\n\treturn { status: \"answered\", value: result };\n}\n\n/**\n * Host surface InteractiveMode exposes to this module: the mutable dialog state\n * plus the methods that stay on the mode class. Reads and writes go straight to\n * the instance so behavior matches the pre-extraction methods.\n *\n * Internal collaboration interface (same pattern as CommandDispatchHost): not a\n * plugin API and not exported from the package root. Members are public on\n * InteractiveMode only so this module can reach them; treat them as private to\n * the interactive-mode subsystem.\n */\nexport interface DialogUiHost {\n\tui: TUI;\n\teditor: Component;\n\teditorContainer: Container;\n\tkeybindings: KeybindingsManager;\n\tdialogSelector: DialogSelectorComponent | undefined;\n\tdialogSelectorReplaced: (() => void) | undefined;\n\tdialogInput: DialogInputComponent | undefined;\n\tdialogInputReplaced: (() => void) | undefined;\n\tdialogEditor: DialogEditorComponent | undefined;\n\n\tshowDialogSelector(title: string, options: string[], opts?: InteractionDialogOptions): Promise<string | undefined>;\n\thideDialogSelector(): void;\n\tshowDialogInput(title: string, placeholder?: string, opts?: InteractionDialogOptions): Promise<string | undefined>;\n\thideDialogInput(): void;\n\tshowDialogEditor(title: string, prefill?: string): Promise<string | undefined>;\n\thideDialogEditor(): void;\n\tshowDialogNotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n\tdisposeActiveSelector(): void;\n\ttoggleToolOutputExpansion(): void;\n\tshowError(message: string): void;\n\tshowWarning(message: string): void;\n\tshowStatus(message: string): void;\n\t/** External editor command from settings (keeps settings access on the mode). */\n\tgetExternalEditorCommand(): string;\n}\n\n// ---- createInteractionHostV1 ----\nexport function createInteractionHostV1(host: DialogUiHost): InteractionHostV1 {\n\treturn {\n\t\tnotify: (request) => {\n\t\t\thost.showDialogNotify(request.message, request.level ?? \"info\");\n\t\t},\n\t\tprompt: async (request, context) => {\n\t\t\tconst opts: InteractionDialogOptions = { signal: context.signal };\n\t\t\tswitch (request.kind) {\n\t\t\t\tcase \"notify\":\n\t\t\t\t\thost.showDialogNotify(request.message, request.level ?? \"info\");\n\t\t\t\t\treturn { status: \"delivered\" };\n\t\t\t\tcase \"select\":\n\t\t\t\t\treturn mapLegacyDialogResultToOutcome(\n\t\t\t\t\t\tawait host.showDialogSelector(request.title, [...request.options], opts),\n\t\t\t\t\t);\n\t\t\t\tcase \"confirm\": {\n\t\t\t\t\t// showDialogConfirm folds dismissal (undefined) and \"No\" into\n\t\t\t\t\t// false; the frozen contract requires user dismissal to surface\n\t\t\t\t\t// as \"cancelled\", so the Yes/No selector is driven directly.\n\t\t\t\t\tconst selection = await host.showDialogSelector(\n\t\t\t\t\t\t`${request.title}\\n${request.message}`,\n\t\t\t\t\t\t[\"Yes\", \"No\"],\n\t\t\t\t\t\topts,\n\t\t\t\t\t);\n\t\t\t\t\tif (selection === undefined) return { status: \"cancelled\" };\n\t\t\t\t\treturn { status: \"answered\", value: selection === \"Yes\" };\n\t\t\t\t}\n\t\t\t\tcase \"input\":\n\t\t\t\t\t// DialogInputComponent has no prefill support, so defaultValue is ignored.\n\t\t\t\t\treturn mapLegacyDialogResultToOutcome(\n\t\t\t\t\t\tawait host.showDialogInput(request.title, request.placeholder, opts),\n\t\t\t\t\t);\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport function showDialogSelector(\n\thost: DialogUiHost,\n\ttitle: string,\n\toptions: string[],\n\topts?: InteractionDialogOptions,\n): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\tif (opts?.signal?.aborted) {\n\t\t\tresolve(undefined);\n\t\t\treturn;\n\t\t}\n\n\t\t// A concurrent request taking the slot settles this dialog's\n\t\t// still-pending promise as cancelled instead of leaving it hanging.\n\t\thost.dialogSelectorReplaced?.();\n\t\thost.dialogSelectorReplaced = undefined;\n\n\t\tconst onAbort = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogSelectorReplaced = undefined;\n\t\t\tif (host.dialogSelector === component) host.hideDialogSelector();\n\t\t\tresolve(undefined);\n\t\t};\n\t\tconst done = (value: string | undefined): void => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogSelectorReplaced = undefined;\n\t\t\tif (host.dialogSelector === component) host.hideDialogSelector();\n\t\t\tresolve(value);\n\t\t};\n\n\t\tconst component = new DialogSelectorComponent(\n\t\t\ttitle,\n\t\t\toptions,\n\t\t\t(option) => done(option),\n\t\t\t() => done(undefined),\n\t\t\t{ tui: host.ui, timeout: opts?.timeout, onToggleToolsExpanded: () => host.toggleToolOutputExpansion() },\n\t\t);\n\n\t\thost.dialogSelectorReplaced = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve(undefined);\n\t\t};\n\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\thost.disposeActiveSelector();\n\t\thost.editorContainer.clear();\n\t\thost.editorContainer.addChild(component);\n\t\thost.ui.setFocus(component);\n\t\thost.dialogSelector = component;\n\t\thost.ui.requestRender();\n\t});\n}\n\nexport function hideDialogSelector(host: DialogUiHost): void {\n\thost.dialogSelector?.dispose();\n\thost.editorContainer.clear();\n\thost.editorContainer.addChild(host.editor);\n\thost.dialogSelector = undefined;\n\thost.ui.setFocus(host.editor);\n\thost.ui.requestRender();\n}\n\nexport async function showDialogConfirm(\n\thost: DialogUiHost,\n\ttitle: string,\n\tmessage: string,\n\topts?: InteractionDialogOptions,\n): Promise<boolean> {\n\tconst result = await host.showDialogSelector(\n\t\t`${title}\n${message}`,\n\t\t[\"Yes\", \"No\"],\n\t\topts,\n\t);\n\treturn result === \"Yes\";\n}\n\nexport function showDialogInput(\n\thost: DialogUiHost,\n\ttitle: string,\n\tplaceholder?: string,\n\topts?: InteractionDialogOptions,\n): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\tif (opts?.signal?.aborted) {\n\t\t\tresolve(undefined);\n\t\t\treturn;\n\t\t}\n\n\t\t// A concurrent request taking the slot settles this dialog's\n\t\t// still-pending promise as cancelled instead of leaving it hanging.\n\t\thost.dialogInputReplaced?.();\n\t\thost.dialogInputReplaced = undefined;\n\n\t\tconst onAbort = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogInputReplaced = undefined;\n\t\t\tif (host.dialogInput === component) host.hideDialogInput();\n\t\t\tresolve(undefined);\n\t\t};\n\t\tconst done = (value: string | undefined): void => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogInputReplaced = undefined;\n\t\t\tif (host.dialogInput === component) host.hideDialogInput();\n\t\t\tresolve(value);\n\t\t};\n\n\t\tconst component = new DialogInputComponent(\n\t\t\ttitle,\n\t\t\tplaceholder,\n\t\t\t(value) => done(value),\n\t\t\t() => done(undefined),\n\t\t\t{ tui: host.ui, timeout: opts?.timeout },\n\t\t);\n\n\t\thost.dialogInputReplaced = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve(undefined);\n\t\t};\n\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\thost.disposeActiveSelector();\n\t\thost.editorContainer.clear();\n\t\thost.editorContainer.addChild(component);\n\t\thost.ui.setFocus(component);\n\t\thost.dialogInput = component;\n\t\thost.ui.requestRender();\n\t});\n}\n\nexport function hideDialogInput(host: DialogUiHost): void {\n\thost.dialogInput?.dispose();\n\thost.editorContainer.clear();\n\thost.editorContainer.addChild(host.editor);\n\thost.dialogInput = undefined;\n\thost.ui.setFocus(host.editor);\n\thost.ui.requestRender();\n}\n\nexport function showDialogNotify(host: DialogUiHost, message: string, type?: \"info\" | \"warning\" | \"error\"): void {\n\tif (type === \"error\") {\n\t\thost.showError(message);\n\t} else if (type === \"warning\") {\n\t\thost.showWarning(message);\n\t} else {\n\t\thost.showStatus(message);\n\t}\n}\n\nexport function showDialogEditor(host: DialogUiHost, title: string, prefill?: string): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\thost.dialogEditor = new DialogEditorComponent(\n\t\t\thost.ui,\n\t\t\thost.keybindings,\n\t\t\ttitle,\n\t\t\tprefill,\n\t\t\t(value) => {\n\t\t\t\thost.hideDialogEditor();\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t() => {\n\t\t\t\thost.hideDialogEditor();\n\t\t\t\tresolve(undefined);\n\t\t\t},\n\t\t\tundefined,\n\t\t\thost.getExternalEditorCommand(),\n\t\t);\n\n\t\thost.disposeActiveSelector();\n\t\thost.editorContainer.clear();\n\t\thost.editorContainer.addChild(host.dialogEditor);\n\t\thost.ui.setFocus(host.dialogEditor);\n\t\thost.ui.requestRender();\n\t});\n}\n\nexport function hideDialogEditor(host: DialogUiHost): void {\n\thost.editorContainer.clear();\n\thost.editorContainer.addChild(host.editor);\n\thost.dialogEditor = undefined;\n\thost.ui.setFocus(host.editor);\n\thost.ui.requestRender();\n}\n"]}
1
+ {"version":3,"file":"interactive-dialog-ui.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-dialog-ui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Dialog UI surface for the interactive mode (extracted from interactive-mode.ts).\n *\n * This module holds the blocking dialog primitives (selector/input/editor),\n * notifications, and the InteractionHostV1 factory backing the interaction\n * capability. InteractiveMode owns the mutable state and receives it through\n * the DialogUiHost interface, mirroring the CommandDispatchHost pattern in\n * ./interactive-commands.ts. Calls go through the host so instance-level\n * overrides keep working.\n */\n\nimport type { Component, Container, TUI } from \"@agent-forge/tui\";\nimport type { InteractionDialogOptions, InteractionHostV1, InteractionOutcomeV1 } from \"../../core/extensions/index.ts\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport { DialogEditorComponent } from \"./components/dialog-editor.ts\";\nimport { DialogInputComponent } from \"./components/dialog-input.ts\";\nimport { DialogSelectorComponent } from \"./components/dialog-selector.ts\";\n\n/** Interface for components that can be expanded/collapsed */\nexport interface Expandable {\n\tsetExpanded(expanded: boolean): void;\n}\n\nexport function isExpandable(obj: unknown): obj is Expandable {\n\treturn typeof obj === \"object\" && obj !== null && \"setExpanded\" in obj && typeof obj.setExpanded === \"function\";\n}\n\n/**\n * Map a legacy TUI dialog result (select/input: string | undefined, confirm:\n * boolean) onto the frozen interaction outcome. A dismissed dialog (undefined)\n * yields \"cancelled\"; every concrete answer — including a confirm \"No\"\n * (false) — yields \"answered\".\n */\nexport function mapLegacyDialogResultToOutcome(result: string | boolean | undefined): InteractionOutcomeV1 {\n\tif (result === undefined) return { status: \"cancelled\" };\n\treturn { status: \"answered\", value: result };\n}\n\n/**\n * Host surface InteractiveMode exposes to this module: the mutable dialog state\n * plus the methods that stay on the mode class. Reads and writes go straight to\n * the instance so behavior matches the pre-extraction methods.\n *\n * Internal collaboration interface (same pattern as CommandDispatchHost): not a\n * plugin API and not exported from the package root. Members are public on\n * InteractiveMode only so this module can reach them; treat them as private to\n * the interactive-mode subsystem.\n */\nexport interface DialogUiHost {\n\tui: TUI;\n\teditor: Component;\n\teditorContainer: Container;\n\tkeybindings: KeybindingsManager;\n\tdialogSelector: DialogSelectorComponent | undefined;\n\tdialogSelectorReplaced: (() => void) | undefined;\n\tdialogInput: DialogInputComponent | undefined;\n\tdialogInputReplaced: (() => void) | undefined;\n\tdialogEditor: DialogEditorComponent | undefined;\n\n\tshowDialogSelector(title: string, options: string[], opts?: InteractionDialogOptions): Promise<string | undefined>;\n\thideDialogSelector(): void;\n\tshowDialogInput(title: string, placeholder?: string, opts?: InteractionDialogOptions): Promise<string | undefined>;\n\thideDialogInput(): void;\n\tshowDialogEditor(title: string, prefill?: string): Promise<string | undefined>;\n\thideDialogEditor(): void;\n\tshowDialogNotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n\tdisposeActiveSelector(): void;\n\ttoggleToolOutputExpansion(): void;\n\tshowError(message: string): void;\n\tshowWarning(message: string): void;\n\tshowStatus(message: string): void;\n\t/** External editor command from settings (keeps settings access on the mode). */\n\tgetExternalEditorCommand(): string;\n}\n\n// ---- createInteractionHostV1 ----\nexport function createInteractionHostV1(host: DialogUiHost): InteractionHostV1 {\n\treturn {\n\t\tnotify: (request) => {\n\t\t\thost.showDialogNotify(request.message, request.level ?? \"info\");\n\t\t},\n\t\tprompt: async (request, context) => {\n\t\t\tconst opts: InteractionDialogOptions = { signal: context.signal };\n\t\t\tswitch (request.kind) {\n\t\t\t\tcase \"notify\":\n\t\t\t\t\thost.showDialogNotify(request.message, request.level ?? \"info\");\n\t\t\t\t\treturn { status: \"delivered\" };\n\t\t\t\tcase \"select\":\n\t\t\t\t\treturn mapLegacyDialogResultToOutcome(\n\t\t\t\t\t\tawait host.showDialogSelector(request.title, [...request.options], opts),\n\t\t\t\t\t);\n\t\t\t\tcase \"confirm\": {\n\t\t\t\t\t// showDialogConfirm folds dismissal (undefined) and \"No\" into\n\t\t\t\t\t// false; the frozen contract requires user dismissal to surface\n\t\t\t\t\t// as \"cancelled\", so the Yes/No selector is driven directly.\n\t\t\t\t\tconst selection = await host.showDialogSelector(\n\t\t\t\t\t\tt(\"{title}\\n{message}\", { title: request.title, message: request.message }),\n\t\t\t\t\t\t[t(\"Yes\"), t(\"No\")],\n\t\t\t\t\t\topts,\n\t\t\t\t\t);\n\t\t\t\t\tif (selection === undefined) return { status: \"cancelled\" };\n\t\t\t\t\treturn { status: \"answered\", value: selection === t(\"Yes\") };\n\t\t\t\t}\n\t\t\t\tcase \"input\":\n\t\t\t\t\t// DialogInputComponent has no prefill support, so defaultValue is ignored.\n\t\t\t\t\treturn mapLegacyDialogResultToOutcome(\n\t\t\t\t\t\tawait host.showDialogInput(request.title, request.placeholder, opts),\n\t\t\t\t\t);\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport function showDialogSelector(\n\thost: DialogUiHost,\n\ttitle: string,\n\toptions: string[],\n\topts?: InteractionDialogOptions,\n): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\tif (opts?.signal?.aborted) {\n\t\t\tresolve(undefined);\n\t\t\treturn;\n\t\t}\n\n\t\t// A concurrent request taking the slot settles this dialog's\n\t\t// still-pending promise as cancelled instead of leaving it hanging.\n\t\thost.dialogSelectorReplaced?.();\n\t\thost.dialogSelectorReplaced = undefined;\n\n\t\tconst onAbort = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogSelectorReplaced = undefined;\n\t\t\tif (host.dialogSelector === component) host.hideDialogSelector();\n\t\t\tresolve(undefined);\n\t\t};\n\t\tconst done = (value: string | undefined): void => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogSelectorReplaced = undefined;\n\t\t\tif (host.dialogSelector === component) host.hideDialogSelector();\n\t\t\tresolve(value);\n\t\t};\n\n\t\tconst component = new DialogSelectorComponent(\n\t\t\ttitle,\n\t\t\toptions,\n\t\t\t(option) => done(option),\n\t\t\t() => done(undefined),\n\t\t\t{ tui: host.ui, timeout: opts?.timeout, onToggleToolsExpanded: () => host.toggleToolOutputExpansion() },\n\t\t);\n\n\t\thost.dialogSelectorReplaced = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve(undefined);\n\t\t};\n\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\thost.disposeActiveSelector();\n\t\thost.editorContainer.clear();\n\t\thost.editorContainer.addChild(component);\n\t\thost.ui.setFocus(component);\n\t\thost.dialogSelector = component;\n\t\thost.ui.requestRender();\n\t});\n}\n\nexport function hideDialogSelector(host: DialogUiHost): void {\n\thost.dialogSelector?.dispose();\n\thost.editorContainer.clear();\n\thost.editorContainer.addChild(host.editor);\n\thost.dialogSelector = undefined;\n\thost.ui.setFocus(host.editor);\n\thost.ui.requestRender();\n}\n\nexport async function showDialogConfirm(\n\thost: DialogUiHost,\n\ttitle: string,\n\tmessage: string,\n\topts?: InteractionDialogOptions,\n): Promise<boolean> {\n\tconst result = await host.showDialogSelector(t(\"{title}\\n{message}\", { title, message }), [t(\"Yes\"), t(\"No\")], opts);\n\treturn result === t(\"Yes\");\n}\n\nexport function showDialogInput(\n\thost: DialogUiHost,\n\ttitle: string,\n\tplaceholder?: string,\n\topts?: InteractionDialogOptions,\n): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\tif (opts?.signal?.aborted) {\n\t\t\tresolve(undefined);\n\t\t\treturn;\n\t\t}\n\n\t\t// A concurrent request taking the slot settles this dialog's\n\t\t// still-pending promise as cancelled instead of leaving it hanging.\n\t\thost.dialogInputReplaced?.();\n\t\thost.dialogInputReplaced = undefined;\n\n\t\tconst onAbort = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogInputReplaced = undefined;\n\t\t\tif (host.dialogInput === component) host.hideDialogInput();\n\t\t\tresolve(undefined);\n\t\t};\n\t\tconst done = (value: string | undefined): void => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogInputReplaced = undefined;\n\t\t\tif (host.dialogInput === component) host.hideDialogInput();\n\t\t\tresolve(value);\n\t\t};\n\n\t\tconst component = new DialogInputComponent(\n\t\t\ttitle,\n\t\t\tplaceholder,\n\t\t\t(value) => done(value),\n\t\t\t() => done(undefined),\n\t\t\t{ tui: host.ui, timeout: opts?.timeout },\n\t\t);\n\n\t\thost.dialogInputReplaced = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve(undefined);\n\t\t};\n\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\thost.disposeActiveSelector();\n\t\thost.editorContainer.clear();\n\t\thost.editorContainer.addChild(component);\n\t\thost.ui.setFocus(component);\n\t\thost.dialogInput = component;\n\t\thost.ui.requestRender();\n\t});\n}\n\nexport function hideDialogInput(host: DialogUiHost): void {\n\thost.dialogInput?.dispose();\n\thost.editorContainer.clear();\n\thost.editorContainer.addChild(host.editor);\n\thost.dialogInput = undefined;\n\thost.ui.setFocus(host.editor);\n\thost.ui.requestRender();\n}\n\nexport function showDialogNotify(host: DialogUiHost, message: string, type?: \"info\" | \"warning\" | \"error\"): void {\n\tif (type === \"error\") {\n\t\thost.showError(message);\n\t} else if (type === \"warning\") {\n\t\thost.showWarning(message);\n\t} else {\n\t\thost.showStatus(message);\n\t}\n}\n\nexport function showDialogEditor(host: DialogUiHost, title: string, prefill?: string): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\thost.dialogEditor = new DialogEditorComponent(\n\t\t\thost.ui,\n\t\t\thost.keybindings,\n\t\t\ttitle,\n\t\t\tprefill,\n\t\t\t(value) => {\n\t\t\t\thost.hideDialogEditor();\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t() => {\n\t\t\t\thost.hideDialogEditor();\n\t\t\t\tresolve(undefined);\n\t\t\t},\n\t\t\tundefined,\n\t\t\thost.getExternalEditorCommand(),\n\t\t);\n\n\t\thost.disposeActiveSelector();\n\t\thost.editorContainer.clear();\n\t\thost.editorContainer.addChild(host.dialogEditor);\n\t\thost.ui.setFocus(host.dialogEditor);\n\t\thost.ui.requestRender();\n\t});\n}\n\nexport function hideDialogEditor(host: DialogUiHost): void {\n\thost.editorContainer.clear();\n\thost.editorContainer.addChild(host.editor);\n\thost.dialogEditor = undefined;\n\thost.ui.setFocus(host.editor);\n\thost.ui.requestRender();\n}\n"]}
@@ -8,6 +8,7 @@
8
8
  * ./interactive-commands.ts. Calls go through the host so instance-level
9
9
  * overrides keep working.
10
10
  */
11
+ import { t } from "../../core/i18n/index.js";
11
12
  import { DialogEditorComponent } from "./components/dialog-editor.js";
12
13
  import { DialogInputComponent } from "./components/dialog-input.js";
13
14
  import { DialogSelectorComponent } from "./components/dialog-selector.js";
@@ -43,10 +44,10 @@ export function createInteractionHostV1(host) {
43
44
  // showDialogConfirm folds dismissal (undefined) and "No" into
44
45
  // false; the frozen contract requires user dismissal to surface
45
46
  // as "cancelled", so the Yes/No selector is driven directly.
46
- const selection = await host.showDialogSelector(`${request.title}\n${request.message}`, ["Yes", "No"], opts);
47
+ const selection = await host.showDialogSelector(t("{title}\n{message}", { title: request.title, message: request.message }), [t("Yes"), t("No")], opts);
47
48
  if (selection === undefined)
48
49
  return { status: "cancelled" };
49
- return { status: "answered", value: selection === "Yes" };
50
+ return { status: "answered", value: selection === t("Yes") };
50
51
  }
51
52
  case "input":
52
53
  // DialogInputComponent has no prefill support, so defaultValue is ignored.
@@ -102,9 +103,8 @@ export function hideDialogSelector(host) {
102
103
  host.ui.requestRender();
103
104
  }
104
105
  export async function showDialogConfirm(host, title, message, opts) {
105
- const result = await host.showDialogSelector(`${title}
106
- ${message}`, ["Yes", "No"], opts);
107
- return result === "Yes";
106
+ const result = await host.showDialogSelector(t("{title}\n{message}", { title, message }), [t("Yes"), t("No")], opts);
107
+ return result === t("Yes");
108
108
  }
109
109
  export function showDialogInput(host, title, placeholder, opts) {
110
110
  return new Promise((resolve) => {
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-dialog-ui.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-dialog-ui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Dialog UI surface for the interactive mode (extracted from interactive-mode.ts).\n *\n * This module holds the blocking dialog primitives (selector/input/editor),\n * notifications, and the InteractionHostV1 factory backing the interaction\n * capability. InteractiveMode owns the mutable state and receives it through\n * the DialogUiHost interface, mirroring the CommandDispatchHost pattern in\n * ./interactive-commands.ts. Calls go through the host so instance-level\n * overrides keep working.\n */\n\nimport type { Component, Container, TUI } from \"@agent-forge/tui\";\nimport type { InteractionDialogOptions, InteractionHostV1, InteractionOutcomeV1 } from \"../../core/extensions/index.ts\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport { DialogEditorComponent } from \"./components/dialog-editor.ts\";\nimport { DialogInputComponent } from \"./components/dialog-input.ts\";\nimport { DialogSelectorComponent } from \"./components/dialog-selector.ts\";\n\n/** Interface for components that can be expanded/collapsed */\nexport interface Expandable {\n\tsetExpanded(expanded: boolean): void;\n}\n\nexport function isExpandable(obj: unknown): obj is Expandable {\n\treturn typeof obj === \"object\" && obj !== null && \"setExpanded\" in obj && typeof obj.setExpanded === \"function\";\n}\n\n/**\n * Map a legacy TUI dialog result (select/input: string | undefined, confirm:\n * boolean) onto the frozen interaction outcome. A dismissed dialog (undefined)\n * yields \"cancelled\"; every concrete answer — including a confirm \"No\"\n * (false) — yields \"answered\".\n */\nexport function mapLegacyDialogResultToOutcome(result: string | boolean | undefined): InteractionOutcomeV1 {\n\tif (result === undefined) return { status: \"cancelled\" };\n\treturn { status: \"answered\", value: result };\n}\n\n/**\n * Host surface InteractiveMode exposes to this module: the mutable dialog state\n * plus the methods that stay on the mode class. Reads and writes go straight to\n * the instance so behavior matches the pre-extraction methods.\n *\n * Internal collaboration interface (same pattern as CommandDispatchHost): not a\n * plugin API and not exported from the package root. Members are public on\n * InteractiveMode only so this module can reach them; treat them as private to\n * the interactive-mode subsystem.\n */\nexport interface DialogUiHost {\n\tui: TUI;\n\teditor: Component;\n\teditorContainer: Container;\n\tkeybindings: KeybindingsManager;\n\tdialogSelector: DialogSelectorComponent | undefined;\n\tdialogSelectorReplaced: (() => void) | undefined;\n\tdialogInput: DialogInputComponent | undefined;\n\tdialogInputReplaced: (() => void) | undefined;\n\tdialogEditor: DialogEditorComponent | undefined;\n\n\tshowDialogSelector(title: string, options: string[], opts?: InteractionDialogOptions): Promise<string | undefined>;\n\thideDialogSelector(): void;\n\tshowDialogInput(title: string, placeholder?: string, opts?: InteractionDialogOptions): Promise<string | undefined>;\n\thideDialogInput(): void;\n\tshowDialogEditor(title: string, prefill?: string): Promise<string | undefined>;\n\thideDialogEditor(): void;\n\tshowDialogNotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n\tdisposeActiveSelector(): void;\n\ttoggleToolOutputExpansion(): void;\n\tshowError(message: string): void;\n\tshowWarning(message: string): void;\n\tshowStatus(message: string): void;\n\t/** External editor command from settings (keeps settings access on the mode). */\n\tgetExternalEditorCommand(): string;\n}\n\n// ---- createInteractionHostV1 ----\nexport function createInteractionHostV1(host: DialogUiHost): InteractionHostV1 {\n\treturn {\n\t\tnotify: (request) => {\n\t\t\thost.showDialogNotify(request.message, request.level ?? \"info\");\n\t\t},\n\t\tprompt: async (request, context) => {\n\t\t\tconst opts: InteractionDialogOptions = { signal: context.signal };\n\t\t\tswitch (request.kind) {\n\t\t\t\tcase \"notify\":\n\t\t\t\t\thost.showDialogNotify(request.message, request.level ?? \"info\");\n\t\t\t\t\treturn { status: \"delivered\" };\n\t\t\t\tcase \"select\":\n\t\t\t\t\treturn mapLegacyDialogResultToOutcome(\n\t\t\t\t\t\tawait host.showDialogSelector(request.title, [...request.options], opts),\n\t\t\t\t\t);\n\t\t\t\tcase \"confirm\": {\n\t\t\t\t\t// showDialogConfirm folds dismissal (undefined) and \"No\" into\n\t\t\t\t\t// false; the frozen contract requires user dismissal to surface\n\t\t\t\t\t// as \"cancelled\", so the Yes/No selector is driven directly.\n\t\t\t\t\tconst selection = await host.showDialogSelector(\n\t\t\t\t\t\t`${request.title}\\n${request.message}`,\n\t\t\t\t\t\t[\"Yes\", \"No\"],\n\t\t\t\t\t\topts,\n\t\t\t\t\t);\n\t\t\t\t\tif (selection === undefined) return { status: \"cancelled\" };\n\t\t\t\t\treturn { status: \"answered\", value: selection === \"Yes\" };\n\t\t\t\t}\n\t\t\t\tcase \"input\":\n\t\t\t\t\t// DialogInputComponent has no prefill support, so defaultValue is ignored.\n\t\t\t\t\treturn mapLegacyDialogResultToOutcome(\n\t\t\t\t\t\tawait host.showDialogInput(request.title, request.placeholder, opts),\n\t\t\t\t\t);\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport function showDialogSelector(\n\thost: DialogUiHost,\n\ttitle: string,\n\toptions: string[],\n\topts?: InteractionDialogOptions,\n): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\tif (opts?.signal?.aborted) {\n\t\t\tresolve(undefined);\n\t\t\treturn;\n\t\t}\n\n\t\t// A concurrent request taking the slot settles this dialog's\n\t\t// still-pending promise as cancelled instead of leaving it hanging.\n\t\thost.dialogSelectorReplaced?.();\n\t\thost.dialogSelectorReplaced = undefined;\n\n\t\tconst onAbort = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogSelectorReplaced = undefined;\n\t\t\tif (host.dialogSelector === component) host.hideDialogSelector();\n\t\t\tresolve(undefined);\n\t\t};\n\t\tconst done = (value: string | undefined): void => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogSelectorReplaced = undefined;\n\t\t\tif (host.dialogSelector === component) host.hideDialogSelector();\n\t\t\tresolve(value);\n\t\t};\n\n\t\tconst component = new DialogSelectorComponent(\n\t\t\ttitle,\n\t\t\toptions,\n\t\t\t(option) => done(option),\n\t\t\t() => done(undefined),\n\t\t\t{ tui: host.ui, timeout: opts?.timeout, onToggleToolsExpanded: () => host.toggleToolOutputExpansion() },\n\t\t);\n\n\t\thost.dialogSelectorReplaced = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve(undefined);\n\t\t};\n\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\thost.disposeActiveSelector();\n\t\thost.editorContainer.clear();\n\t\thost.editorContainer.addChild(component);\n\t\thost.ui.setFocus(component);\n\t\thost.dialogSelector = component;\n\t\thost.ui.requestRender();\n\t});\n}\n\nexport function hideDialogSelector(host: DialogUiHost): void {\n\thost.dialogSelector?.dispose();\n\thost.editorContainer.clear();\n\thost.editorContainer.addChild(host.editor);\n\thost.dialogSelector = undefined;\n\thost.ui.setFocus(host.editor);\n\thost.ui.requestRender();\n}\n\nexport async function showDialogConfirm(\n\thost: DialogUiHost,\n\ttitle: string,\n\tmessage: string,\n\topts?: InteractionDialogOptions,\n): Promise<boolean> {\n\tconst result = await host.showDialogSelector(\n\t\t`${title}\n${message}`,\n\t\t[\"Yes\", \"No\"],\n\t\topts,\n\t);\n\treturn result === \"Yes\";\n}\n\nexport function showDialogInput(\n\thost: DialogUiHost,\n\ttitle: string,\n\tplaceholder?: string,\n\topts?: InteractionDialogOptions,\n): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\tif (opts?.signal?.aborted) {\n\t\t\tresolve(undefined);\n\t\t\treturn;\n\t\t}\n\n\t\t// A concurrent request taking the slot settles this dialog's\n\t\t// still-pending promise as cancelled instead of leaving it hanging.\n\t\thost.dialogInputReplaced?.();\n\t\thost.dialogInputReplaced = undefined;\n\n\t\tconst onAbort = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogInputReplaced = undefined;\n\t\t\tif (host.dialogInput === component) host.hideDialogInput();\n\t\t\tresolve(undefined);\n\t\t};\n\t\tconst done = (value: string | undefined): void => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogInputReplaced = undefined;\n\t\t\tif (host.dialogInput === component) host.hideDialogInput();\n\t\t\tresolve(value);\n\t\t};\n\n\t\tconst component = new DialogInputComponent(\n\t\t\ttitle,\n\t\t\tplaceholder,\n\t\t\t(value) => done(value),\n\t\t\t() => done(undefined),\n\t\t\t{ tui: host.ui, timeout: opts?.timeout },\n\t\t);\n\n\t\thost.dialogInputReplaced = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve(undefined);\n\t\t};\n\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\thost.disposeActiveSelector();\n\t\thost.editorContainer.clear();\n\t\thost.editorContainer.addChild(component);\n\t\thost.ui.setFocus(component);\n\t\thost.dialogInput = component;\n\t\thost.ui.requestRender();\n\t});\n}\n\nexport function hideDialogInput(host: DialogUiHost): void {\n\thost.dialogInput?.dispose();\n\thost.editorContainer.clear();\n\thost.editorContainer.addChild(host.editor);\n\thost.dialogInput = undefined;\n\thost.ui.setFocus(host.editor);\n\thost.ui.requestRender();\n}\n\nexport function showDialogNotify(host: DialogUiHost, message: string, type?: \"info\" | \"warning\" | \"error\"): void {\n\tif (type === \"error\") {\n\t\thost.showError(message);\n\t} else if (type === \"warning\") {\n\t\thost.showWarning(message);\n\t} else {\n\t\thost.showStatus(message);\n\t}\n}\n\nexport function showDialogEditor(host: DialogUiHost, title: string, prefill?: string): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\thost.dialogEditor = new DialogEditorComponent(\n\t\t\thost.ui,\n\t\t\thost.keybindings,\n\t\t\ttitle,\n\t\t\tprefill,\n\t\t\t(value) => {\n\t\t\t\thost.hideDialogEditor();\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t() => {\n\t\t\t\thost.hideDialogEditor();\n\t\t\t\tresolve(undefined);\n\t\t\t},\n\t\t\tundefined,\n\t\t\thost.getExternalEditorCommand(),\n\t\t);\n\n\t\thost.disposeActiveSelector();\n\t\thost.editorContainer.clear();\n\t\thost.editorContainer.addChild(host.dialogEditor);\n\t\thost.ui.setFocus(host.dialogEditor);\n\t\thost.ui.requestRender();\n\t});\n}\n\nexport function hideDialogEditor(host: DialogUiHost): void {\n\thost.editorContainer.clear();\n\thost.editorContainer.addChild(host.editor);\n\thost.dialogEditor = undefined;\n\thost.ui.setFocus(host.editor);\n\thost.ui.requestRender();\n}\n"]}
1
+ {"version":3,"file":"interactive-dialog-ui.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-dialog-ui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Dialog UI surface for the interactive mode (extracted from interactive-mode.ts).\n *\n * This module holds the blocking dialog primitives (selector/input/editor),\n * notifications, and the InteractionHostV1 factory backing the interaction\n * capability. InteractiveMode owns the mutable state and receives it through\n * the DialogUiHost interface, mirroring the CommandDispatchHost pattern in\n * ./interactive-commands.ts. Calls go through the host so instance-level\n * overrides keep working.\n */\n\nimport type { Component, Container, TUI } from \"@agent-forge/tui\";\nimport type { InteractionDialogOptions, InteractionHostV1, InteractionOutcomeV1 } from \"../../core/extensions/index.ts\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport { DialogEditorComponent } from \"./components/dialog-editor.ts\";\nimport { DialogInputComponent } from \"./components/dialog-input.ts\";\nimport { DialogSelectorComponent } from \"./components/dialog-selector.ts\";\n\n/** Interface for components that can be expanded/collapsed */\nexport interface Expandable {\n\tsetExpanded(expanded: boolean): void;\n}\n\nexport function isExpandable(obj: unknown): obj is Expandable {\n\treturn typeof obj === \"object\" && obj !== null && \"setExpanded\" in obj && typeof obj.setExpanded === \"function\";\n}\n\n/**\n * Map a legacy TUI dialog result (select/input: string | undefined, confirm:\n * boolean) onto the frozen interaction outcome. A dismissed dialog (undefined)\n * yields \"cancelled\"; every concrete answer — including a confirm \"No\"\n * (false) — yields \"answered\".\n */\nexport function mapLegacyDialogResultToOutcome(result: string | boolean | undefined): InteractionOutcomeV1 {\n\tif (result === undefined) return { status: \"cancelled\" };\n\treturn { status: \"answered\", value: result };\n}\n\n/**\n * Host surface InteractiveMode exposes to this module: the mutable dialog state\n * plus the methods that stay on the mode class. Reads and writes go straight to\n * the instance so behavior matches the pre-extraction methods.\n *\n * Internal collaboration interface (same pattern as CommandDispatchHost): not a\n * plugin API and not exported from the package root. Members are public on\n * InteractiveMode only so this module can reach them; treat them as private to\n * the interactive-mode subsystem.\n */\nexport interface DialogUiHost {\n\tui: TUI;\n\teditor: Component;\n\teditorContainer: Container;\n\tkeybindings: KeybindingsManager;\n\tdialogSelector: DialogSelectorComponent | undefined;\n\tdialogSelectorReplaced: (() => void) | undefined;\n\tdialogInput: DialogInputComponent | undefined;\n\tdialogInputReplaced: (() => void) | undefined;\n\tdialogEditor: DialogEditorComponent | undefined;\n\n\tshowDialogSelector(title: string, options: string[], opts?: InteractionDialogOptions): Promise<string | undefined>;\n\thideDialogSelector(): void;\n\tshowDialogInput(title: string, placeholder?: string, opts?: InteractionDialogOptions): Promise<string | undefined>;\n\thideDialogInput(): void;\n\tshowDialogEditor(title: string, prefill?: string): Promise<string | undefined>;\n\thideDialogEditor(): void;\n\tshowDialogNotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n\tdisposeActiveSelector(): void;\n\ttoggleToolOutputExpansion(): void;\n\tshowError(message: string): void;\n\tshowWarning(message: string): void;\n\tshowStatus(message: string): void;\n\t/** External editor command from settings (keeps settings access on the mode). */\n\tgetExternalEditorCommand(): string;\n}\n\n// ---- createInteractionHostV1 ----\nexport function createInteractionHostV1(host: DialogUiHost): InteractionHostV1 {\n\treturn {\n\t\tnotify: (request) => {\n\t\t\thost.showDialogNotify(request.message, request.level ?? \"info\");\n\t\t},\n\t\tprompt: async (request, context) => {\n\t\t\tconst opts: InteractionDialogOptions = { signal: context.signal };\n\t\t\tswitch (request.kind) {\n\t\t\t\tcase \"notify\":\n\t\t\t\t\thost.showDialogNotify(request.message, request.level ?? \"info\");\n\t\t\t\t\treturn { status: \"delivered\" };\n\t\t\t\tcase \"select\":\n\t\t\t\t\treturn mapLegacyDialogResultToOutcome(\n\t\t\t\t\t\tawait host.showDialogSelector(request.title, [...request.options], opts),\n\t\t\t\t\t);\n\t\t\t\tcase \"confirm\": {\n\t\t\t\t\t// showDialogConfirm folds dismissal (undefined) and \"No\" into\n\t\t\t\t\t// false; the frozen contract requires user dismissal to surface\n\t\t\t\t\t// as \"cancelled\", so the Yes/No selector is driven directly.\n\t\t\t\t\tconst selection = await host.showDialogSelector(\n\t\t\t\t\t\tt(\"{title}\\n{message}\", { title: request.title, message: request.message }),\n\t\t\t\t\t\t[t(\"Yes\"), t(\"No\")],\n\t\t\t\t\t\topts,\n\t\t\t\t\t);\n\t\t\t\t\tif (selection === undefined) return { status: \"cancelled\" };\n\t\t\t\t\treturn { status: \"answered\", value: selection === t(\"Yes\") };\n\t\t\t\t}\n\t\t\t\tcase \"input\":\n\t\t\t\t\t// DialogInputComponent has no prefill support, so defaultValue is ignored.\n\t\t\t\t\treturn mapLegacyDialogResultToOutcome(\n\t\t\t\t\t\tawait host.showDialogInput(request.title, request.placeholder, opts),\n\t\t\t\t\t);\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport function showDialogSelector(\n\thost: DialogUiHost,\n\ttitle: string,\n\toptions: string[],\n\topts?: InteractionDialogOptions,\n): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\tif (opts?.signal?.aborted) {\n\t\t\tresolve(undefined);\n\t\t\treturn;\n\t\t}\n\n\t\t// A concurrent request taking the slot settles this dialog's\n\t\t// still-pending promise as cancelled instead of leaving it hanging.\n\t\thost.dialogSelectorReplaced?.();\n\t\thost.dialogSelectorReplaced = undefined;\n\n\t\tconst onAbort = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogSelectorReplaced = undefined;\n\t\t\tif (host.dialogSelector === component) host.hideDialogSelector();\n\t\t\tresolve(undefined);\n\t\t};\n\t\tconst done = (value: string | undefined): void => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogSelectorReplaced = undefined;\n\t\t\tif (host.dialogSelector === component) host.hideDialogSelector();\n\t\t\tresolve(value);\n\t\t};\n\n\t\tconst component = new DialogSelectorComponent(\n\t\t\ttitle,\n\t\t\toptions,\n\t\t\t(option) => done(option),\n\t\t\t() => done(undefined),\n\t\t\t{ tui: host.ui, timeout: opts?.timeout, onToggleToolsExpanded: () => host.toggleToolOutputExpansion() },\n\t\t);\n\n\t\thost.dialogSelectorReplaced = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve(undefined);\n\t\t};\n\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\thost.disposeActiveSelector();\n\t\thost.editorContainer.clear();\n\t\thost.editorContainer.addChild(component);\n\t\thost.ui.setFocus(component);\n\t\thost.dialogSelector = component;\n\t\thost.ui.requestRender();\n\t});\n}\n\nexport function hideDialogSelector(host: DialogUiHost): void {\n\thost.dialogSelector?.dispose();\n\thost.editorContainer.clear();\n\thost.editorContainer.addChild(host.editor);\n\thost.dialogSelector = undefined;\n\thost.ui.setFocus(host.editor);\n\thost.ui.requestRender();\n}\n\nexport async function showDialogConfirm(\n\thost: DialogUiHost,\n\ttitle: string,\n\tmessage: string,\n\topts?: InteractionDialogOptions,\n): Promise<boolean> {\n\tconst result = await host.showDialogSelector(t(\"{title}\\n{message}\", { title, message }), [t(\"Yes\"), t(\"No\")], opts);\n\treturn result === t(\"Yes\");\n}\n\nexport function showDialogInput(\n\thost: DialogUiHost,\n\ttitle: string,\n\tplaceholder?: string,\n\topts?: InteractionDialogOptions,\n): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\tif (opts?.signal?.aborted) {\n\t\t\tresolve(undefined);\n\t\t\treturn;\n\t\t}\n\n\t\t// A concurrent request taking the slot settles this dialog's\n\t\t// still-pending promise as cancelled instead of leaving it hanging.\n\t\thost.dialogInputReplaced?.();\n\t\thost.dialogInputReplaced = undefined;\n\n\t\tconst onAbort = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogInputReplaced = undefined;\n\t\t\tif (host.dialogInput === component) host.hideDialogInput();\n\t\t\tresolve(undefined);\n\t\t};\n\t\tconst done = (value: string | undefined): void => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\thost.dialogInputReplaced = undefined;\n\t\t\tif (host.dialogInput === component) host.hideDialogInput();\n\t\t\tresolve(value);\n\t\t};\n\n\t\tconst component = new DialogInputComponent(\n\t\t\ttitle,\n\t\t\tplaceholder,\n\t\t\t(value) => done(value),\n\t\t\t() => done(undefined),\n\t\t\t{ tui: host.ui, timeout: opts?.timeout },\n\t\t);\n\n\t\thost.dialogInputReplaced = () => {\n\t\t\topts?.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve(undefined);\n\t\t};\n\t\topts?.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\thost.disposeActiveSelector();\n\t\thost.editorContainer.clear();\n\t\thost.editorContainer.addChild(component);\n\t\thost.ui.setFocus(component);\n\t\thost.dialogInput = component;\n\t\thost.ui.requestRender();\n\t});\n}\n\nexport function hideDialogInput(host: DialogUiHost): void {\n\thost.dialogInput?.dispose();\n\thost.editorContainer.clear();\n\thost.editorContainer.addChild(host.editor);\n\thost.dialogInput = undefined;\n\thost.ui.setFocus(host.editor);\n\thost.ui.requestRender();\n}\n\nexport function showDialogNotify(host: DialogUiHost, message: string, type?: \"info\" | \"warning\" | \"error\"): void {\n\tif (type === \"error\") {\n\t\thost.showError(message);\n\t} else if (type === \"warning\") {\n\t\thost.showWarning(message);\n\t} else {\n\t\thost.showStatus(message);\n\t}\n}\n\nexport function showDialogEditor(host: DialogUiHost, title: string, prefill?: string): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\thost.dialogEditor = new DialogEditorComponent(\n\t\t\thost.ui,\n\t\t\thost.keybindings,\n\t\t\ttitle,\n\t\t\tprefill,\n\t\t\t(value) => {\n\t\t\t\thost.hideDialogEditor();\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t() => {\n\t\t\t\thost.hideDialogEditor();\n\t\t\t\tresolve(undefined);\n\t\t\t},\n\t\t\tundefined,\n\t\t\thost.getExternalEditorCommand(),\n\t\t);\n\n\t\thost.disposeActiveSelector();\n\t\thost.editorContainer.clear();\n\t\thost.editorContainer.addChild(host.dialogEditor);\n\t\thost.ui.setFocus(host.dialogEditor);\n\t\thost.ui.requestRender();\n\t});\n}\n\nexport function hideDialogEditor(host: DialogUiHost): void {\n\thost.editorContainer.clear();\n\thost.editorContainer.addChild(host.editor);\n\thost.dialogEditor = undefined;\n\thost.ui.setFocus(host.editor);\n\thost.ui.requestRender();\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-format.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-format.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure formatting helpers for interactive mode: metrics snapshots and\n * path/source/scope display formatting. Implementations live here;\n * InteractiveMode keeps thin instance delegates for compatibility.\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { ResourceDiagnostic } from \"../../core/resource-loader.ts\";\nimport type { SourceInfo } from \"../../core/source-info.ts\";\nimport type { MetricsSnapshotV1 } from \"../../plugins/observability-types.ts\";\nimport { parseGitUrl } from \"../../utils/git.ts\";\nimport { getCwdRelativePath } from \"../../utils/paths.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\nexport function formatMetricsPercent(ratio: number): string {\n\treturn `${(ratio * 100).toFixed(1)}%`;\n}\n\nexport function formatMetricsDuration(ms: number | null): string {\n\tif (ms === null) return \"n/a\";\n\treturn ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(2)}s`;\n}\n\nexport function formatMetricsSnapshot(snapshot: MetricsSnapshotV1): string {\n\tlet info = `${theme.bold(\"Product Metrics\")}\\n\\n`;\n\tconst bound = snapshot.window.windowTurns === null ? \"whole journal\" : `last ${snapshot.window.windowTurns} turns`;\n\tinfo += `${theme.fg(\"dim\", \"Window:\")} ${bound} (${snapshot.window.sampledTurns} sampled)\\n`;\n\n\tconst successRate =\n\t\tsnapshot.turns.successRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.turns.successRate)})`;\n\tinfo += `${theme.fg(\"dim\", \"Turns:\")} ${snapshot.turns.count} total, ${snapshot.turns.successCount} succeeded${successRate}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Turn duration:\")} p50 ${formatMetricsDuration(snapshot.turns.p50DurationMs)}, p95 ${formatMetricsDuration(snapshot.turns.p95DurationMs)}\\n`;\n\n\tconst errorRate = snapshot.tools.errorRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.tools.errorRate)})`;\n\tinfo += `${theme.fg(\"dim\", \"Tools:\")} ${snapshot.tools.calls} calls, ${snapshot.tools.errors} errors${errorRate}\\n`;\n\tif (snapshot.tools.topErrors.length > 0) {\n\t\tconst top = snapshot.tools.topErrors.map((entry) => `${entry.toolName} (${entry.errors})`).join(\", \");\n\t\tinfo += `${theme.fg(\"dim\", \"Top errors:\")} ${top}\\n`;\n\t}\n\n\tconst memoryRecall =\n\t\tsnapshot.memoryRecall.status === \"sampled\"\n\t\t\t? `${snapshot.memoryRecall.calls} calls, ${snapshot.memoryRecall.hits} hits (${formatMetricsPercent(snapshot.memoryRecall.hitRate)})`\n\t\t\t: `not sampled (${snapshot.memoryRecall.reason})`;\n\tinfo += `${theme.fg(\"dim\", \"Memory recall:\")} ${memoryRecall}\\n`;\n\n\tconst cancelLatency =\n\t\tsnapshot.cancelLatencyMs.status === \"sampled\"\n\t\t\t? `${snapshot.cancelLatencyMs.count} samples, p95 ${formatMetricsDuration(snapshot.cancelLatencyMs.p95Ms)}`\n\t\t\t: `not sampled (${snapshot.cancelLatencyMs.reason})`;\n\tinfo += `${theme.fg(\"dim\", \"Cancel latency:\")} ${cancelLatency}\\n`;\n\n\tconst tokens =\n\t\tsnapshot.tokens.status === \"sampled\"\n\t\t\t? `${snapshot.tokens.totalTokens} tokens`\n\t\t\t: `not sampled (${snapshot.tokens.reason})`;\n\tinfo += `${theme.fg(\"dim\", \"Tokens:\")} ${tokens}\\n`;\n\treturn info;\n}\n\nexport function formatDisplayPath(p: string): string {\n\tconst home = os.homedir();\n\tlet result = p;\n\n\t// Replace home directory with ~. On Windows the path may arrive with\n\t// forward slashes while homedir() uses backslashes, so compare both in\n\t// slash form and keep the output in the path's own form.\n\tif (result.startsWith(home)) {\n\t\tresult = `~${result.slice(home.length)}`;\n\t} else {\n\t\tconst homeSlash = home.replaceAll(\"\\\\\", \"/\");\n\t\tconst resultSlash = result.replaceAll(\"\\\\\", \"/\");\n\t\tif (homeSlash !== home && resultSlash.startsWith(homeSlash)) {\n\t\t\tresult = `~${resultSlash.slice(homeSlash.length)}`;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/** Resolve a path against cwd and prefer a cwd-relative rendering. */\nexport function formatContextPath(p: string, cwd: string): string {\n\tconst resolvedCwd = path.resolve(cwd);\n\tconst absolutePath = path.isAbsolute(p) ? path.resolve(p) : path.resolve(resolvedCwd, p);\n\tconst relativePath = getCwdRelativePath(absolutePath, resolvedCwd);\n\tif (relativePath !== undefined) {\n\t\treturn relativePath;\n\t}\n\n\treturn formatDisplayPath(absolutePath);\n}\n\nexport function isPackageSource(sourceInfo?: SourceInfo): boolean {\n\tconst source = sourceInfo?.source ?? \"\";\n\treturn source.startsWith(\"npm:\") || source.startsWith(\"git:\");\n}\n\n/**\n * Get a short path relative to the package root for display.\n */\nexport function getShortPath(fullPath: string, sourceInfo?: SourceInfo): string {\n\tconst normalizedFullPath = fullPath.replace(/\\\\/g, \"/\");\n\tconst baseDir = sourceInfo?.baseDir;\n\tif (baseDir && isPackageSource(sourceInfo)) {\n\t\tconst normalizedBaseDir = baseDir.replace(/\\\\/g, \"/\");\n\t\tconst npmRootMatch = normalizedBaseDir.match(/^(.*\\/node_modules)\\/(@?[^/]+(?:\\/[^/]+)?)$/);\n\t\t// If fullPath is under the same node_modules root as baseDir, preserve that relative topology.\n\t\tif (npmRootMatch?.[1] && normalizedFullPath.startsWith(`${npmRootMatch[1]}/`)) {\n\t\t\treturn path.posix.relative(normalizedBaseDir, normalizedFullPath);\n\t\t}\n\n\t\tconst relativePath = path.relative(path.resolve(baseDir), path.resolve(fullPath));\n\t\tif (\n\t\t\trelativePath &&\n\t\t\trelativePath !== \".\" &&\n\t\t\t!relativePath.startsWith(\"..\") &&\n\t\t\t!relativePath.startsWith(`..${path.sep}`) &&\n\t\t\t!path.isAbsolute(relativePath)\n\t\t) {\n\t\t\treturn relativePath.replace(/\\\\/g, \"/\");\n\t\t}\n\t}\n\n\tconst source = sourceInfo?.source ?? \"\";\n\tconst npmMatch = normalizedFullPath.match(/node_modules\\/(@?[^/]+(?:\\/[^/]+)?)\\/(.*)/);\n\tif (npmMatch && source.startsWith(\"npm:\")) {\n\t\treturn npmMatch[2];\n\t}\n\n\tconst gitMatch = normalizedFullPath.match(/git\\/[^/]+\\/[^/]+\\/(.*)/);\n\tif (gitMatch && source.startsWith(\"git:\")) {\n\t\treturn gitMatch[1];\n\t}\n\n\treturn formatDisplayPath(fullPath);\n}\n\nexport function getCompactPathLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tconst shortPath = getShortPath(resourcePath, sourceInfo);\n\tconst normalizedPath = shortPath.replace(/\\\\/g, \"/\");\n\tconst segments = normalizedPath.split(\"/\").filter((segment) => segment.length > 0 && segment !== \"~\");\n\tif (segments.length > 0) {\n\t\treturn segments[segments.length - 1]!;\n\t}\n\treturn shortPath;\n}\n\nexport function getCompactPackageSourceLabel(sourceInfo?: SourceInfo): string {\n\tconst source = sourceInfo?.source ?? \"\";\n\tif (source.startsWith(\"npm:\")) {\n\t\treturn source.slice(\"npm:\".length) || source;\n\t}\n\n\tconst gitSource = parseGitUrl(source);\n\tif (gitSource) {\n\t\t// v8 ignore next -- buildGitSource 仅在 path 非空时返回,|| 回退不可达\n\t\treturn gitSource.path || source;\n\t}\n\n\treturn source;\n}\n\nexport function getDisplaySourceInfo(sourceInfo?: SourceInfo): {\n\tlabel: string;\n\tscopeLabel?: string;\n\tcolor: \"accent\" | \"muted\";\n} {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"local\") {\n\t\tif (scope === \"user\") {\n\t\t\treturn { label: \"user\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"project\") {\n\t\t\treturn { label: \"project\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"temporary\") {\n\t\t\treturn { label: \"path\", scopeLabel: \"temp\", color: \"muted\" };\n\t\t}\n\t\treturn { label: \"path\", color: \"muted\" };\n\t}\n\n\tif (source === \"cli\") {\n\t\treturn { label: \"path\", scopeLabel: scope === \"temporary\" ? \"temp\" : undefined, color: \"muted\" };\n\t}\n\n\tconst scopeLabel =\n\t\tscope === \"user\" ? \"user\" : scope === \"project\" ? \"project\" : scope === \"temporary\" ? \"temp\" : undefined;\n\treturn { label: source, scopeLabel, color: \"accent\" };\n}\n\nexport function getScopeGroup(sourceInfo?: SourceInfo): \"user\" | \"project\" | \"path\" {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"cli\" || scope === \"temporary\") return \"path\";\n\tif (scope === \"user\") return \"user\";\n\tif (scope === \"project\") return \"project\";\n\treturn \"path\";\n}\n\nexport function buildScopeGroups(items: Array<{ path: string; sourceInfo?: SourceInfo }>): Array<{\n\tscope: \"user\" | \"project\" | \"path\";\n\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n}> {\n\tconst groups: Record<\n\t\t\"user\" | \"project\" | \"path\",\n\t\t{\n\t\t\tscope: \"user\" | \"project\" | \"path\";\n\t\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t\t}\n\t> = {\n\t\tuser: { scope: \"user\", paths: [], packages: new Map() },\n\t\tproject: { scope: \"project\", paths: [], packages: new Map() },\n\t\tpath: { scope: \"path\", paths: [], packages: new Map() },\n\t};\n\n\tfor (const item of items) {\n\t\tconst groupKey = getScopeGroup(item.sourceInfo);\n\t\tconst group = groups[groupKey];\n\t\tconst source = item.sourceInfo?.source ?? \"local\";\n\n\t\tif (isPackageSource(item.sourceInfo)) {\n\t\t\tconst list = group.packages.get(source) ?? [];\n\t\t\tlist.push(item);\n\t\t\tgroup.packages.set(source, list);\n\t\t} else {\n\t\t\tgroup.paths.push(item);\n\t\t}\n\t}\n\n\treturn [groups.project, groups.user, groups.path].filter(\n\t\t(group) => group.paths.length > 0 || group.packages.size > 0,\n\t);\n}\n\nexport function formatScopeGroups(\n\tgroups: Array<{\n\t\tscope: \"user\" | \"project\" | \"path\";\n\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t}>,\n\toptions: {\n\t\tformatPath: (item: { path: string; sourceInfo?: SourceInfo }) => string;\n\t\tformatPackagePath: (item: { path: string; sourceInfo?: SourceInfo }, source: string) => string;\n\t},\n): string {\n\tconst lines: string[] = [];\n\n\tfor (const group of groups) {\n\t\tlines.push(` ${theme.fg(\"accent\", group.scope)}`);\n\n\t\tconst sortedPaths = [...group.paths].sort((a, b) => a.path.localeCompare(b.path));\n\t\tfor (const item of sortedPaths) {\n\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPath(item)}`));\n\t\t}\n\n\t\tconst sortedPackages = Array.from(group.packages.entries()).sort(([a], [b]) => a.localeCompare(b));\n\t\tfor (const [source, items] of sortedPackages) {\n\t\t\tlines.push(` ${theme.fg(\"mdLink\", source)}`);\n\t\t\tconst sortedPackagePaths = [...items].sort((a, b) => a.path.localeCompare(b.path));\n\t\t\tfor (const item of sortedPackagePaths) {\n\t\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPackagePath(item, source)}`));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nexport function findSourceInfoForPath(p: string, sourceInfos: Map<string, SourceInfo>): SourceInfo | undefined {\n\tconst exact = sourceInfos.get(p);\n\tif (exact) return exact;\n\n\tlet current = p;\n\twhile (current.includes(\"/\")) {\n\t\tcurrent = current.substring(0, current.lastIndexOf(\"/\"));\n\t\tconst parent = sourceInfos.get(current);\n\t\tif (parent) return parent;\n\t}\n\n\treturn undefined;\n}\n\nexport function formatPathWithSource(p: string, sourceInfo?: SourceInfo): string {\n\tif (sourceInfo) {\n\t\tconst shortPath = getShortPath(p, sourceInfo);\n\t\tconst { label, scopeLabel } = getDisplaySourceInfo(sourceInfo);\n\t\tconst labelText = scopeLabel ? `${label} (${scopeLabel})` : label;\n\t\treturn `${labelText} ${shortPath}`;\n\t}\n\treturn formatDisplayPath(p);\n}\n\nexport function formatDiagnostics(\n\tdiagnostics: readonly ResourceDiagnostic[],\n\tsourceInfos: Map<string, SourceInfo>,\n): string {\n\tconst lines: string[] = [];\n\n\t// Group collision diagnostics by name\n\tconst collisions = new Map<string, ResourceDiagnostic[]>();\n\tconst otherDiagnostics: ResourceDiagnostic[] = [];\n\n\tfor (const d of diagnostics) {\n\t\tif (d.type === \"collision\" && d.collision) {\n\t\t\tconst list = collisions.get(d.collision.name) ?? [];\n\t\t\tlist.push(d);\n\t\t\tcollisions.set(d.collision.name, list);\n\t\t} else {\n\t\t\totherDiagnostics.push(d);\n\t\t}\n\t}\n\n\t// Format collision diagnostics grouped by name\n\tfor (const [name, collisionList] of collisions) {\n\t\tconst first = collisionList[0]?.collision;\n\t\t// v8 ignore next -- collision lists only hold diagnostics whose collision payload is set\n\t\tif (!first) continue;\n\t\tlines.push(theme.fg(\"warning\", ` \"${name}\" collision:`));\n\t\tlines.push(\n\t\t\ttheme.fg(\n\t\t\t\t\"dim\",\n\t\t\t\t` ${theme.fg(\"success\", \"✓\")} ${formatPathWithSource(first.winnerPath, findSourceInfoForPath(first.winnerPath, sourceInfos))}`,\n\t\t\t),\n\t\t);\n\t\tfor (const d of collisionList) {\n\t\t\t// v8 ignore next -- collision 列表仅收集带 collision 载荷的诊断\n\t\t\tif (d.collision) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\t` ${theme.fg(\"warning\", \"✗\")} ${formatPathWithSource(d.collision.loserPath, findSourceInfoForPath(d.collision.loserPath, sourceInfos))} (skipped)`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const d of otherDiagnostics) {\n\t\tif (d.path) {\n\t\t\tconst formattedPath = formatPathWithSource(d.path, findSourceInfoForPath(d.path, sourceInfos));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${formattedPath}`));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t} else {\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"interactive-format.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-format.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure formatting helpers for interactive mode: metrics snapshots and\n * path/source/scope display formatting. Implementations live here;\n * InteractiveMode keeps thin instance delegates for compatibility.\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport type { ResourceDiagnostic } from \"../../core/resource-loader.ts\";\nimport type { SourceInfo } from \"../../core/source-info.ts\";\nimport type { MetricsSnapshotV1 } from \"../../plugins/observability-types.ts\";\nimport { parseGitUrl } from \"../../utils/git.ts\";\nimport { getCwdRelativePath } from \"../../utils/paths.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\nexport function formatMetricsPercent(ratio: number): string {\n\treturn `${(ratio * 100).toFixed(1)}%`;\n}\n\nexport function formatMetricsDuration(ms: number | null): string {\n\tif (ms === null) return \"n/a\";\n\treturn ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(2)}s`;\n}\n\nexport function formatMetricsSnapshot(snapshot: MetricsSnapshotV1): string {\n\tlet info = `${theme.bold(t(\"Product Metrics\"))}\\n\\n`;\n\tconst bound =\n\t\tsnapshot.window.windowTurns === null\n\t\t\t? t(\"whole journal\")\n\t\t\t: t(\"last {count} turns\", { count: snapshot.window.windowTurns });\n\tinfo += `${theme.fg(\"dim\", t(\"Window:\"))} ${bound} ${t(\"({count} sampled)\", { count: snapshot.window.sampledTurns })}\\n`;\n\n\tconst successRate =\n\t\tsnapshot.turns.successRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.turns.successRate)})`;\n\tinfo += `${theme.fg(\"dim\", t(\"Turns:\"))} ${t(\"{count} total, {succeeded} succeeded\", {\n\t\tcount: snapshot.turns.count,\n\t\tsucceeded: snapshot.turns.successCount,\n\t})}${successRate}\\n`;\n\tinfo += `${theme.fg(\"dim\", t(\"Turn duration:\"))} p50 ${formatMetricsDuration(snapshot.turns.p50DurationMs)}, p95 ${formatMetricsDuration(snapshot.turns.p95DurationMs)}\\n`;\n\n\tconst errorRate = snapshot.tools.errorRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.tools.errorRate)})`;\n\tinfo += `${theme.fg(\"dim\", t(\"Tools:\"))} ${t(\"{calls} calls, {errors} errors\", {\n\t\tcalls: snapshot.tools.calls,\n\t\terrors: snapshot.tools.errors,\n\t})}${errorRate}\\n`;\n\tif (snapshot.tools.topErrors.length > 0) {\n\t\tconst top = snapshot.tools.topErrors.map((entry) => `${entry.toolName} (${entry.errors})`).join(\", \");\n\t\tinfo += `${theme.fg(\"dim\", t(\"Top errors:\"))} ${top}\\n`;\n\t}\n\n\tconst memoryRecall =\n\t\tsnapshot.memoryRecall.status === \"sampled\"\n\t\t\t? t(\"{calls} calls, {hits} hits ({percent})\", {\n\t\t\t\t\tcalls: snapshot.memoryRecall.calls,\n\t\t\t\t\thits: snapshot.memoryRecall.hits,\n\t\t\t\t\tpercent: formatMetricsPercent(snapshot.memoryRecall.hitRate),\n\t\t\t\t})\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.memoryRecall.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Memory recall:\"))} ${memoryRecall}\\n`;\n\n\tconst cancelLatency =\n\t\tsnapshot.cancelLatencyMs.status === \"sampled\"\n\t\t\t? t(\"{count} samples, p95 {p95}\", {\n\t\t\t\t\tcount: snapshot.cancelLatencyMs.count,\n\t\t\t\t\tp95: formatMetricsDuration(snapshot.cancelLatencyMs.p95Ms),\n\t\t\t\t})\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.cancelLatencyMs.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Cancel latency:\"))} ${cancelLatency}\\n`;\n\n\tconst tokens =\n\t\tsnapshot.tokens.status === \"sampled\"\n\t\t\t? t(\"{count} tokens\", { count: snapshot.tokens.totalTokens })\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.tokens.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Tokens:\"))} ${tokens}\\n`;\n\treturn info;\n}\n\nexport function formatDisplayPath(p: string): string {\n\tconst home = os.homedir();\n\tlet result = p;\n\n\t// Replace home directory with ~. On Windows the path may arrive with\n\t// forward slashes while homedir() uses backslashes, so compare both in\n\t// slash form and keep the output in the path's own form.\n\tif (result.startsWith(home)) {\n\t\tresult = `~${result.slice(home.length)}`;\n\t} else {\n\t\tconst homeSlash = home.replaceAll(\"\\\\\", \"/\");\n\t\tconst resultSlash = result.replaceAll(\"\\\\\", \"/\");\n\t\tif (homeSlash !== home && resultSlash.startsWith(homeSlash)) {\n\t\t\tresult = `~${resultSlash.slice(homeSlash.length)}`;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/** Resolve a path against cwd and prefer a cwd-relative rendering. */\nexport function formatContextPath(p: string, cwd: string): string {\n\tconst resolvedCwd = path.resolve(cwd);\n\tconst absolutePath = path.isAbsolute(p) ? path.resolve(p) : path.resolve(resolvedCwd, p);\n\tconst relativePath = getCwdRelativePath(absolutePath, resolvedCwd);\n\tif (relativePath !== undefined) {\n\t\treturn relativePath;\n\t}\n\n\treturn formatDisplayPath(absolutePath);\n}\n\nexport function isPackageSource(sourceInfo?: SourceInfo): boolean {\n\tconst source = sourceInfo?.source ?? \"\";\n\treturn source.startsWith(\"npm:\") || source.startsWith(\"git:\");\n}\n\n/**\n * Get a short path relative to the package root for display.\n */\nexport function getShortPath(fullPath: string, sourceInfo?: SourceInfo): string {\n\tconst normalizedFullPath = fullPath.replace(/\\\\/g, \"/\");\n\tconst baseDir = sourceInfo?.baseDir;\n\tif (baseDir && isPackageSource(sourceInfo)) {\n\t\tconst normalizedBaseDir = baseDir.replace(/\\\\/g, \"/\");\n\t\tconst npmRootMatch = normalizedBaseDir.match(/^(.*\\/node_modules)\\/(@?[^/]+(?:\\/[^/]+)?)$/);\n\t\t// If fullPath is under the same node_modules root as baseDir, preserve that relative topology.\n\t\tif (npmRootMatch?.[1] && normalizedFullPath.startsWith(`${npmRootMatch[1]}/`)) {\n\t\t\treturn path.posix.relative(normalizedBaseDir, normalizedFullPath);\n\t\t}\n\n\t\tconst relativePath = path.relative(path.resolve(baseDir), path.resolve(fullPath));\n\t\tif (\n\t\t\trelativePath &&\n\t\t\trelativePath !== \".\" &&\n\t\t\t!relativePath.startsWith(\"..\") &&\n\t\t\t!relativePath.startsWith(`..${path.sep}`) &&\n\t\t\t!path.isAbsolute(relativePath)\n\t\t) {\n\t\t\treturn relativePath.replace(/\\\\/g, \"/\");\n\t\t}\n\t}\n\n\tconst source = sourceInfo?.source ?? \"\";\n\tconst npmMatch = normalizedFullPath.match(/node_modules\\/(@?[^/]+(?:\\/[^/]+)?)\\/(.*)/);\n\tif (npmMatch && source.startsWith(\"npm:\")) {\n\t\treturn npmMatch[2];\n\t}\n\n\tconst gitMatch = normalizedFullPath.match(/git\\/[^/]+\\/[^/]+\\/(.*)/);\n\tif (gitMatch && source.startsWith(\"git:\")) {\n\t\treturn gitMatch[1];\n\t}\n\n\treturn formatDisplayPath(fullPath);\n}\n\nexport function getCompactPathLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tconst shortPath = getShortPath(resourcePath, sourceInfo);\n\tconst normalizedPath = shortPath.replace(/\\\\/g, \"/\");\n\tconst segments = normalizedPath.split(\"/\").filter((segment) => segment.length > 0 && segment !== \"~\");\n\tif (segments.length > 0) {\n\t\treturn segments[segments.length - 1]!;\n\t}\n\treturn shortPath;\n}\n\nexport function getCompactPackageSourceLabel(sourceInfo?: SourceInfo): string {\n\tconst source = sourceInfo?.source ?? \"\";\n\tif (source.startsWith(\"npm:\")) {\n\t\treturn source.slice(\"npm:\".length) || source;\n\t}\n\n\tconst gitSource = parseGitUrl(source);\n\tif (gitSource) {\n\t\t// v8 ignore next -- buildGitSource 仅在 path 非空时返回,|| 回退不可达\n\t\treturn gitSource.path || source;\n\t}\n\n\treturn source;\n}\n\nexport function getDisplaySourceInfo(sourceInfo?: SourceInfo): {\n\tlabel: string;\n\tscopeLabel?: string;\n\tcolor: \"accent\" | \"muted\";\n} {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"local\") {\n\t\tif (scope === \"user\") {\n\t\t\treturn { label: \"user\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"project\") {\n\t\t\treturn { label: \"project\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"temporary\") {\n\t\t\treturn { label: \"path\", scopeLabel: \"temp\", color: \"muted\" };\n\t\t}\n\t\treturn { label: \"path\", color: \"muted\" };\n\t}\n\n\tif (source === \"cli\") {\n\t\treturn { label: \"path\", scopeLabel: scope === \"temporary\" ? \"temp\" : undefined, color: \"muted\" };\n\t}\n\n\tconst scopeLabel =\n\t\tscope === \"user\" ? \"user\" : scope === \"project\" ? \"project\" : scope === \"temporary\" ? \"temp\" : undefined;\n\treturn { label: source, scopeLabel, color: \"accent\" };\n}\n\nexport function getScopeGroup(sourceInfo?: SourceInfo): \"user\" | \"project\" | \"path\" {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"cli\" || scope === \"temporary\") return \"path\";\n\tif (scope === \"user\") return \"user\";\n\tif (scope === \"project\") return \"project\";\n\treturn \"path\";\n}\n\nexport function buildScopeGroups(items: Array<{ path: string; sourceInfo?: SourceInfo }>): Array<{\n\tscope: \"user\" | \"project\" | \"path\";\n\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n}> {\n\tconst groups: Record<\n\t\t\"user\" | \"project\" | \"path\",\n\t\t{\n\t\t\tscope: \"user\" | \"project\" | \"path\";\n\t\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t\t}\n\t> = {\n\t\tuser: { scope: \"user\", paths: [], packages: new Map() },\n\t\tproject: { scope: \"project\", paths: [], packages: new Map() },\n\t\tpath: { scope: \"path\", paths: [], packages: new Map() },\n\t};\n\n\tfor (const item of items) {\n\t\tconst groupKey = getScopeGroup(item.sourceInfo);\n\t\tconst group = groups[groupKey];\n\t\tconst source = item.sourceInfo?.source ?? \"local\";\n\n\t\tif (isPackageSource(item.sourceInfo)) {\n\t\t\tconst list = group.packages.get(source) ?? [];\n\t\t\tlist.push(item);\n\t\t\tgroup.packages.set(source, list);\n\t\t} else {\n\t\t\tgroup.paths.push(item);\n\t\t}\n\t}\n\n\treturn [groups.project, groups.user, groups.path].filter(\n\t\t(group) => group.paths.length > 0 || group.packages.size > 0,\n\t);\n}\n\nexport function formatScopeGroups(\n\tgroups: Array<{\n\t\tscope: \"user\" | \"project\" | \"path\";\n\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t}>,\n\toptions: {\n\t\tformatPath: (item: { path: string; sourceInfo?: SourceInfo }) => string;\n\t\tformatPackagePath: (item: { path: string; sourceInfo?: SourceInfo }, source: string) => string;\n\t},\n): string {\n\tconst lines: string[] = [];\n\n\tfor (const group of groups) {\n\t\tlines.push(` ${theme.fg(\"accent\", group.scope)}`);\n\n\t\tconst sortedPaths = [...group.paths].sort((a, b) => a.path.localeCompare(b.path));\n\t\tfor (const item of sortedPaths) {\n\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPath(item)}`));\n\t\t}\n\n\t\tconst sortedPackages = Array.from(group.packages.entries()).sort(([a], [b]) => a.localeCompare(b));\n\t\tfor (const [source, items] of sortedPackages) {\n\t\t\tlines.push(` ${theme.fg(\"mdLink\", source)}`);\n\t\t\tconst sortedPackagePaths = [...items].sort((a, b) => a.path.localeCompare(b.path));\n\t\t\tfor (const item of sortedPackagePaths) {\n\t\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPackagePath(item, source)}`));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nexport function findSourceInfoForPath(p: string, sourceInfos: Map<string, SourceInfo>): SourceInfo | undefined {\n\tconst exact = sourceInfos.get(p);\n\tif (exact) return exact;\n\n\tlet current = p;\n\twhile (current.includes(\"/\")) {\n\t\tcurrent = current.substring(0, current.lastIndexOf(\"/\"));\n\t\tconst parent = sourceInfos.get(current);\n\t\tif (parent) return parent;\n\t}\n\n\treturn undefined;\n}\n\nexport function formatPathWithSource(p: string, sourceInfo?: SourceInfo): string {\n\tif (sourceInfo) {\n\t\tconst shortPath = getShortPath(p, sourceInfo);\n\t\tconst { label, scopeLabel } = getDisplaySourceInfo(sourceInfo);\n\t\tconst labelText = scopeLabel ? `${label} (${scopeLabel})` : label;\n\t\treturn `${labelText} ${shortPath}`;\n\t}\n\treturn formatDisplayPath(p);\n}\n\nexport function formatDiagnostics(\n\tdiagnostics: readonly ResourceDiagnostic[],\n\tsourceInfos: Map<string, SourceInfo>,\n): string {\n\tconst lines: string[] = [];\n\n\t// Group collision diagnostics by name\n\tconst collisions = new Map<string, ResourceDiagnostic[]>();\n\tconst otherDiagnostics: ResourceDiagnostic[] = [];\n\n\tfor (const d of diagnostics) {\n\t\tif (d.type === \"collision\" && d.collision) {\n\t\t\tconst list = collisions.get(d.collision.name) ?? [];\n\t\t\tlist.push(d);\n\t\t\tcollisions.set(d.collision.name, list);\n\t\t} else {\n\t\t\totherDiagnostics.push(d);\n\t\t}\n\t}\n\n\t// Format collision diagnostics grouped by name\n\tfor (const [name, collisionList] of collisions) {\n\t\tconst first = collisionList[0]?.collision;\n\t\t// v8 ignore next -- collision lists only hold diagnostics whose collision payload is set\n\t\tif (!first) continue;\n\t\tlines.push(theme.fg(\"warning\", ` ${t('\"{name}\" collision:', { name })}`));\n\t\tlines.push(\n\t\t\ttheme.fg(\n\t\t\t\t\"dim\",\n\t\t\t\t` ${theme.fg(\"success\", \"✓\")} ${formatPathWithSource(first.winnerPath, findSourceInfoForPath(first.winnerPath, sourceInfos))}`,\n\t\t\t),\n\t\t);\n\t\tfor (const d of collisionList) {\n\t\t\t// v8 ignore next -- collision 列表仅收集带 collision 载荷的诊断\n\t\t\tif (d.collision) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\t` ${theme.fg(\"warning\", \"✗\")} ${formatPathWithSource(d.collision.loserPath, findSourceInfoForPath(d.collision.loserPath, sourceInfos))} ${t(\"(skipped)\")}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const d of otherDiagnostics) {\n\t\tif (d.path) {\n\t\t\tconst formattedPath = formatPathWithSource(d.path, findSourceInfoForPath(d.path, sourceInfos));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${formattedPath}`));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t} else {\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"]}
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import * as os from "node:os";
7
7
  import * as path from "node:path";
8
+ import { t } from "../../core/i18n/index.js";
8
9
  import { parseGitUrl } from "../../utils/git.js";
9
10
  import { getCwdRelativePath } from "../../utils/paths.js";
10
11
  import { theme } from "./theme/theme.js";
@@ -17,30 +18,45 @@ export function formatMetricsDuration(ms) {
17
18
  return ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(2)}s`;
18
19
  }
19
20
  export function formatMetricsSnapshot(snapshot) {
20
- let info = `${theme.bold("Product Metrics")}\n\n`;
21
- const bound = snapshot.window.windowTurns === null ? "whole journal" : `last ${snapshot.window.windowTurns} turns`;
22
- info += `${theme.fg("dim", "Window:")} ${bound} (${snapshot.window.sampledTurns} sampled)\n`;
21
+ let info = `${theme.bold(t("Product Metrics"))}\n\n`;
22
+ const bound = snapshot.window.windowTurns === null
23
+ ? t("whole journal")
24
+ : t("last {count} turns", { count: snapshot.window.windowTurns });
25
+ info += `${theme.fg("dim", t("Window:"))} ${bound} ${t("({count} sampled)", { count: snapshot.window.sampledTurns })}\n`;
23
26
  const successRate = snapshot.turns.successRate === null ? "" : ` (${formatMetricsPercent(snapshot.turns.successRate)})`;
24
- info += `${theme.fg("dim", "Turns:")} ${snapshot.turns.count} total, ${snapshot.turns.successCount} succeeded${successRate}\n`;
25
- info += `${theme.fg("dim", "Turn duration:")} p50 ${formatMetricsDuration(snapshot.turns.p50DurationMs)}, p95 ${formatMetricsDuration(snapshot.turns.p95DurationMs)}\n`;
27
+ info += `${theme.fg("dim", t("Turns:"))} ${t("{count} total, {succeeded} succeeded", {
28
+ count: snapshot.turns.count,
29
+ succeeded: snapshot.turns.successCount,
30
+ })}${successRate}\n`;
31
+ info += `${theme.fg("dim", t("Turn duration:"))} p50 ${formatMetricsDuration(snapshot.turns.p50DurationMs)}, p95 ${formatMetricsDuration(snapshot.turns.p95DurationMs)}\n`;
26
32
  const errorRate = snapshot.tools.errorRate === null ? "" : ` (${formatMetricsPercent(snapshot.tools.errorRate)})`;
27
- info += `${theme.fg("dim", "Tools:")} ${snapshot.tools.calls} calls, ${snapshot.tools.errors} errors${errorRate}\n`;
33
+ info += `${theme.fg("dim", t("Tools:"))} ${t("{calls} calls, {errors} errors", {
34
+ calls: snapshot.tools.calls,
35
+ errors: snapshot.tools.errors,
36
+ })}${errorRate}\n`;
28
37
  if (snapshot.tools.topErrors.length > 0) {
29
38
  const top = snapshot.tools.topErrors.map((entry) => `${entry.toolName} (${entry.errors})`).join(", ");
30
- info += `${theme.fg("dim", "Top errors:")} ${top}\n`;
39
+ info += `${theme.fg("dim", t("Top errors:"))} ${top}\n`;
31
40
  }
32
41
  const memoryRecall = snapshot.memoryRecall.status === "sampled"
33
- ? `${snapshot.memoryRecall.calls} calls, ${snapshot.memoryRecall.hits} hits (${formatMetricsPercent(snapshot.memoryRecall.hitRate)})`
34
- : `not sampled (${snapshot.memoryRecall.reason})`;
35
- info += `${theme.fg("dim", "Memory recall:")} ${memoryRecall}\n`;
42
+ ? t("{calls} calls, {hits} hits ({percent})", {
43
+ calls: snapshot.memoryRecall.calls,
44
+ hits: snapshot.memoryRecall.hits,
45
+ percent: formatMetricsPercent(snapshot.memoryRecall.hitRate),
46
+ })
47
+ : t("not sampled ({reason})", { reason: snapshot.memoryRecall.reason });
48
+ info += `${theme.fg("dim", t("Memory recall:"))} ${memoryRecall}\n`;
36
49
  const cancelLatency = snapshot.cancelLatencyMs.status === "sampled"
37
- ? `${snapshot.cancelLatencyMs.count} samples, p95 ${formatMetricsDuration(snapshot.cancelLatencyMs.p95Ms)}`
38
- : `not sampled (${snapshot.cancelLatencyMs.reason})`;
39
- info += `${theme.fg("dim", "Cancel latency:")} ${cancelLatency}\n`;
50
+ ? t("{count} samples, p95 {p95}", {
51
+ count: snapshot.cancelLatencyMs.count,
52
+ p95: formatMetricsDuration(snapshot.cancelLatencyMs.p95Ms),
53
+ })
54
+ : t("not sampled ({reason})", { reason: snapshot.cancelLatencyMs.reason });
55
+ info += `${theme.fg("dim", t("Cancel latency:"))} ${cancelLatency}\n`;
40
56
  const tokens = snapshot.tokens.status === "sampled"
41
- ? `${snapshot.tokens.totalTokens} tokens`
42
- : `not sampled (${snapshot.tokens.reason})`;
43
- info += `${theme.fg("dim", "Tokens:")} ${tokens}\n`;
57
+ ? t("{count} tokens", { count: snapshot.tokens.totalTokens })
58
+ : t("not sampled ({reason})", { reason: snapshot.tokens.reason });
59
+ info += `${theme.fg("dim", t("Tokens:"))} ${tokens}\n`;
44
60
  return info;
45
61
  }
46
62
  export function formatDisplayPath(p) {
@@ -244,12 +260,12 @@ export function formatDiagnostics(diagnostics, sourceInfos) {
244
260
  // v8 ignore next -- collision lists only hold diagnostics whose collision payload is set
245
261
  if (!first)
246
262
  continue;
247
- lines.push(theme.fg("warning", ` "${name}" collision:`));
263
+ lines.push(theme.fg("warning", ` ${t('"{name}" collision:', { name })}`));
248
264
  lines.push(theme.fg("dim", ` ${theme.fg("success", "✓")} ${formatPathWithSource(first.winnerPath, findSourceInfoForPath(first.winnerPath, sourceInfos))}`));
249
265
  for (const d of collisionList) {
250
266
  // v8 ignore next -- collision 列表仅收集带 collision 载荷的诊断
251
267
  if (d.collision) {
252
- lines.push(theme.fg("dim", ` ${theme.fg("warning", "✗")} ${formatPathWithSource(d.collision.loserPath, findSourceInfoForPath(d.collision.loserPath, sourceInfos))} (skipped)`));
268
+ lines.push(theme.fg("dim", ` ${theme.fg("warning", "✗")} ${formatPathWithSource(d.collision.loserPath, findSourceInfoForPath(d.collision.loserPath, sourceInfos))} ${t("(skipped)")}`));
253
269
  }
254
270
  }
255
271
  }
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-format.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-format.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure formatting helpers for interactive mode: metrics snapshots and\n * path/source/scope display formatting. Implementations live here;\n * InteractiveMode keeps thin instance delegates for compatibility.\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { ResourceDiagnostic } from \"../../core/resource-loader.ts\";\nimport type { SourceInfo } from \"../../core/source-info.ts\";\nimport type { MetricsSnapshotV1 } from \"../../plugins/observability-types.ts\";\nimport { parseGitUrl } from \"../../utils/git.ts\";\nimport { getCwdRelativePath } from \"../../utils/paths.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\nexport function formatMetricsPercent(ratio: number): string {\n\treturn `${(ratio * 100).toFixed(1)}%`;\n}\n\nexport function formatMetricsDuration(ms: number | null): string {\n\tif (ms === null) return \"n/a\";\n\treturn ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(2)}s`;\n}\n\nexport function formatMetricsSnapshot(snapshot: MetricsSnapshotV1): string {\n\tlet info = `${theme.bold(\"Product Metrics\")}\\n\\n`;\n\tconst bound = snapshot.window.windowTurns === null ? \"whole journal\" : `last ${snapshot.window.windowTurns} turns`;\n\tinfo += `${theme.fg(\"dim\", \"Window:\")} ${bound} (${snapshot.window.sampledTurns} sampled)\\n`;\n\n\tconst successRate =\n\t\tsnapshot.turns.successRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.turns.successRate)})`;\n\tinfo += `${theme.fg(\"dim\", \"Turns:\")} ${snapshot.turns.count} total, ${snapshot.turns.successCount} succeeded${successRate}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Turn duration:\")} p50 ${formatMetricsDuration(snapshot.turns.p50DurationMs)}, p95 ${formatMetricsDuration(snapshot.turns.p95DurationMs)}\\n`;\n\n\tconst errorRate = snapshot.tools.errorRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.tools.errorRate)})`;\n\tinfo += `${theme.fg(\"dim\", \"Tools:\")} ${snapshot.tools.calls} calls, ${snapshot.tools.errors} errors${errorRate}\\n`;\n\tif (snapshot.tools.topErrors.length > 0) {\n\t\tconst top = snapshot.tools.topErrors.map((entry) => `${entry.toolName} (${entry.errors})`).join(\", \");\n\t\tinfo += `${theme.fg(\"dim\", \"Top errors:\")} ${top}\\n`;\n\t}\n\n\tconst memoryRecall =\n\t\tsnapshot.memoryRecall.status === \"sampled\"\n\t\t\t? `${snapshot.memoryRecall.calls} calls, ${snapshot.memoryRecall.hits} hits (${formatMetricsPercent(snapshot.memoryRecall.hitRate)})`\n\t\t\t: `not sampled (${snapshot.memoryRecall.reason})`;\n\tinfo += `${theme.fg(\"dim\", \"Memory recall:\")} ${memoryRecall}\\n`;\n\n\tconst cancelLatency =\n\t\tsnapshot.cancelLatencyMs.status === \"sampled\"\n\t\t\t? `${snapshot.cancelLatencyMs.count} samples, p95 ${formatMetricsDuration(snapshot.cancelLatencyMs.p95Ms)}`\n\t\t\t: `not sampled (${snapshot.cancelLatencyMs.reason})`;\n\tinfo += `${theme.fg(\"dim\", \"Cancel latency:\")} ${cancelLatency}\\n`;\n\n\tconst tokens =\n\t\tsnapshot.tokens.status === \"sampled\"\n\t\t\t? `${snapshot.tokens.totalTokens} tokens`\n\t\t\t: `not sampled (${snapshot.tokens.reason})`;\n\tinfo += `${theme.fg(\"dim\", \"Tokens:\")} ${tokens}\\n`;\n\treturn info;\n}\n\nexport function formatDisplayPath(p: string): string {\n\tconst home = os.homedir();\n\tlet result = p;\n\n\t// Replace home directory with ~. On Windows the path may arrive with\n\t// forward slashes while homedir() uses backslashes, so compare both in\n\t// slash form and keep the output in the path's own form.\n\tif (result.startsWith(home)) {\n\t\tresult = `~${result.slice(home.length)}`;\n\t} else {\n\t\tconst homeSlash = home.replaceAll(\"\\\\\", \"/\");\n\t\tconst resultSlash = result.replaceAll(\"\\\\\", \"/\");\n\t\tif (homeSlash !== home && resultSlash.startsWith(homeSlash)) {\n\t\t\tresult = `~${resultSlash.slice(homeSlash.length)}`;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/** Resolve a path against cwd and prefer a cwd-relative rendering. */\nexport function formatContextPath(p: string, cwd: string): string {\n\tconst resolvedCwd = path.resolve(cwd);\n\tconst absolutePath = path.isAbsolute(p) ? path.resolve(p) : path.resolve(resolvedCwd, p);\n\tconst relativePath = getCwdRelativePath(absolutePath, resolvedCwd);\n\tif (relativePath !== undefined) {\n\t\treturn relativePath;\n\t}\n\n\treturn formatDisplayPath(absolutePath);\n}\n\nexport function isPackageSource(sourceInfo?: SourceInfo): boolean {\n\tconst source = sourceInfo?.source ?? \"\";\n\treturn source.startsWith(\"npm:\") || source.startsWith(\"git:\");\n}\n\n/**\n * Get a short path relative to the package root for display.\n */\nexport function getShortPath(fullPath: string, sourceInfo?: SourceInfo): string {\n\tconst normalizedFullPath = fullPath.replace(/\\\\/g, \"/\");\n\tconst baseDir = sourceInfo?.baseDir;\n\tif (baseDir && isPackageSource(sourceInfo)) {\n\t\tconst normalizedBaseDir = baseDir.replace(/\\\\/g, \"/\");\n\t\tconst npmRootMatch = normalizedBaseDir.match(/^(.*\\/node_modules)\\/(@?[^/]+(?:\\/[^/]+)?)$/);\n\t\t// If fullPath is under the same node_modules root as baseDir, preserve that relative topology.\n\t\tif (npmRootMatch?.[1] && normalizedFullPath.startsWith(`${npmRootMatch[1]}/`)) {\n\t\t\treturn path.posix.relative(normalizedBaseDir, normalizedFullPath);\n\t\t}\n\n\t\tconst relativePath = path.relative(path.resolve(baseDir), path.resolve(fullPath));\n\t\tif (\n\t\t\trelativePath &&\n\t\t\trelativePath !== \".\" &&\n\t\t\t!relativePath.startsWith(\"..\") &&\n\t\t\t!relativePath.startsWith(`..${path.sep}`) &&\n\t\t\t!path.isAbsolute(relativePath)\n\t\t) {\n\t\t\treturn relativePath.replace(/\\\\/g, \"/\");\n\t\t}\n\t}\n\n\tconst source = sourceInfo?.source ?? \"\";\n\tconst npmMatch = normalizedFullPath.match(/node_modules\\/(@?[^/]+(?:\\/[^/]+)?)\\/(.*)/);\n\tif (npmMatch && source.startsWith(\"npm:\")) {\n\t\treturn npmMatch[2];\n\t}\n\n\tconst gitMatch = normalizedFullPath.match(/git\\/[^/]+\\/[^/]+\\/(.*)/);\n\tif (gitMatch && source.startsWith(\"git:\")) {\n\t\treturn gitMatch[1];\n\t}\n\n\treturn formatDisplayPath(fullPath);\n}\n\nexport function getCompactPathLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tconst shortPath = getShortPath(resourcePath, sourceInfo);\n\tconst normalizedPath = shortPath.replace(/\\\\/g, \"/\");\n\tconst segments = normalizedPath.split(\"/\").filter((segment) => segment.length > 0 && segment !== \"~\");\n\tif (segments.length > 0) {\n\t\treturn segments[segments.length - 1]!;\n\t}\n\treturn shortPath;\n}\n\nexport function getCompactPackageSourceLabel(sourceInfo?: SourceInfo): string {\n\tconst source = sourceInfo?.source ?? \"\";\n\tif (source.startsWith(\"npm:\")) {\n\t\treturn source.slice(\"npm:\".length) || source;\n\t}\n\n\tconst gitSource = parseGitUrl(source);\n\tif (gitSource) {\n\t\t// v8 ignore next -- buildGitSource 仅在 path 非空时返回,|| 回退不可达\n\t\treturn gitSource.path || source;\n\t}\n\n\treturn source;\n}\n\nexport function getDisplaySourceInfo(sourceInfo?: SourceInfo): {\n\tlabel: string;\n\tscopeLabel?: string;\n\tcolor: \"accent\" | \"muted\";\n} {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"local\") {\n\t\tif (scope === \"user\") {\n\t\t\treturn { label: \"user\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"project\") {\n\t\t\treturn { label: \"project\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"temporary\") {\n\t\t\treturn { label: \"path\", scopeLabel: \"temp\", color: \"muted\" };\n\t\t}\n\t\treturn { label: \"path\", color: \"muted\" };\n\t}\n\n\tif (source === \"cli\") {\n\t\treturn { label: \"path\", scopeLabel: scope === \"temporary\" ? \"temp\" : undefined, color: \"muted\" };\n\t}\n\n\tconst scopeLabel =\n\t\tscope === \"user\" ? \"user\" : scope === \"project\" ? \"project\" : scope === \"temporary\" ? \"temp\" : undefined;\n\treturn { label: source, scopeLabel, color: \"accent\" };\n}\n\nexport function getScopeGroup(sourceInfo?: SourceInfo): \"user\" | \"project\" | \"path\" {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"cli\" || scope === \"temporary\") return \"path\";\n\tif (scope === \"user\") return \"user\";\n\tif (scope === \"project\") return \"project\";\n\treturn \"path\";\n}\n\nexport function buildScopeGroups(items: Array<{ path: string; sourceInfo?: SourceInfo }>): Array<{\n\tscope: \"user\" | \"project\" | \"path\";\n\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n}> {\n\tconst groups: Record<\n\t\t\"user\" | \"project\" | \"path\",\n\t\t{\n\t\t\tscope: \"user\" | \"project\" | \"path\";\n\t\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t\t}\n\t> = {\n\t\tuser: { scope: \"user\", paths: [], packages: new Map() },\n\t\tproject: { scope: \"project\", paths: [], packages: new Map() },\n\t\tpath: { scope: \"path\", paths: [], packages: new Map() },\n\t};\n\n\tfor (const item of items) {\n\t\tconst groupKey = getScopeGroup(item.sourceInfo);\n\t\tconst group = groups[groupKey];\n\t\tconst source = item.sourceInfo?.source ?? \"local\";\n\n\t\tif (isPackageSource(item.sourceInfo)) {\n\t\t\tconst list = group.packages.get(source) ?? [];\n\t\t\tlist.push(item);\n\t\t\tgroup.packages.set(source, list);\n\t\t} else {\n\t\t\tgroup.paths.push(item);\n\t\t}\n\t}\n\n\treturn [groups.project, groups.user, groups.path].filter(\n\t\t(group) => group.paths.length > 0 || group.packages.size > 0,\n\t);\n}\n\nexport function formatScopeGroups(\n\tgroups: Array<{\n\t\tscope: \"user\" | \"project\" | \"path\";\n\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t}>,\n\toptions: {\n\t\tformatPath: (item: { path: string; sourceInfo?: SourceInfo }) => string;\n\t\tformatPackagePath: (item: { path: string; sourceInfo?: SourceInfo }, source: string) => string;\n\t},\n): string {\n\tconst lines: string[] = [];\n\n\tfor (const group of groups) {\n\t\tlines.push(` ${theme.fg(\"accent\", group.scope)}`);\n\n\t\tconst sortedPaths = [...group.paths].sort((a, b) => a.path.localeCompare(b.path));\n\t\tfor (const item of sortedPaths) {\n\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPath(item)}`));\n\t\t}\n\n\t\tconst sortedPackages = Array.from(group.packages.entries()).sort(([a], [b]) => a.localeCompare(b));\n\t\tfor (const [source, items] of sortedPackages) {\n\t\t\tlines.push(` ${theme.fg(\"mdLink\", source)}`);\n\t\t\tconst sortedPackagePaths = [...items].sort((a, b) => a.path.localeCompare(b.path));\n\t\t\tfor (const item of sortedPackagePaths) {\n\t\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPackagePath(item, source)}`));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nexport function findSourceInfoForPath(p: string, sourceInfos: Map<string, SourceInfo>): SourceInfo | undefined {\n\tconst exact = sourceInfos.get(p);\n\tif (exact) return exact;\n\n\tlet current = p;\n\twhile (current.includes(\"/\")) {\n\t\tcurrent = current.substring(0, current.lastIndexOf(\"/\"));\n\t\tconst parent = sourceInfos.get(current);\n\t\tif (parent) return parent;\n\t}\n\n\treturn undefined;\n}\n\nexport function formatPathWithSource(p: string, sourceInfo?: SourceInfo): string {\n\tif (sourceInfo) {\n\t\tconst shortPath = getShortPath(p, sourceInfo);\n\t\tconst { label, scopeLabel } = getDisplaySourceInfo(sourceInfo);\n\t\tconst labelText = scopeLabel ? `${label} (${scopeLabel})` : label;\n\t\treturn `${labelText} ${shortPath}`;\n\t}\n\treturn formatDisplayPath(p);\n}\n\nexport function formatDiagnostics(\n\tdiagnostics: readonly ResourceDiagnostic[],\n\tsourceInfos: Map<string, SourceInfo>,\n): string {\n\tconst lines: string[] = [];\n\n\t// Group collision diagnostics by name\n\tconst collisions = new Map<string, ResourceDiagnostic[]>();\n\tconst otherDiagnostics: ResourceDiagnostic[] = [];\n\n\tfor (const d of diagnostics) {\n\t\tif (d.type === \"collision\" && d.collision) {\n\t\t\tconst list = collisions.get(d.collision.name) ?? [];\n\t\t\tlist.push(d);\n\t\t\tcollisions.set(d.collision.name, list);\n\t\t} else {\n\t\t\totherDiagnostics.push(d);\n\t\t}\n\t}\n\n\t// Format collision diagnostics grouped by name\n\tfor (const [name, collisionList] of collisions) {\n\t\tconst first = collisionList[0]?.collision;\n\t\t// v8 ignore next -- collision lists only hold diagnostics whose collision payload is set\n\t\tif (!first) continue;\n\t\tlines.push(theme.fg(\"warning\", ` \"${name}\" collision:`));\n\t\tlines.push(\n\t\t\ttheme.fg(\n\t\t\t\t\"dim\",\n\t\t\t\t` ${theme.fg(\"success\", \"✓\")} ${formatPathWithSource(first.winnerPath, findSourceInfoForPath(first.winnerPath, sourceInfos))}`,\n\t\t\t),\n\t\t);\n\t\tfor (const d of collisionList) {\n\t\t\t// v8 ignore next -- collision 列表仅收集带 collision 载荷的诊断\n\t\t\tif (d.collision) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\t` ${theme.fg(\"warning\", \"✗\")} ${formatPathWithSource(d.collision.loserPath, findSourceInfoForPath(d.collision.loserPath, sourceInfos))} (skipped)`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const d of otherDiagnostics) {\n\t\tif (d.path) {\n\t\t\tconst formattedPath = formatPathWithSource(d.path, findSourceInfoForPath(d.path, sourceInfos));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${formattedPath}`));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t} else {\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"interactive-format.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-format.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure formatting helpers for interactive mode: metrics snapshots and\n * path/source/scope display formatting. Implementations live here;\n * InteractiveMode keeps thin instance delegates for compatibility.\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport type { ResourceDiagnostic } from \"../../core/resource-loader.ts\";\nimport type { SourceInfo } from \"../../core/source-info.ts\";\nimport type { MetricsSnapshotV1 } from \"../../plugins/observability-types.ts\";\nimport { parseGitUrl } from \"../../utils/git.ts\";\nimport { getCwdRelativePath } from \"../../utils/paths.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\nexport function formatMetricsPercent(ratio: number): string {\n\treturn `${(ratio * 100).toFixed(1)}%`;\n}\n\nexport function formatMetricsDuration(ms: number | null): string {\n\tif (ms === null) return \"n/a\";\n\treturn ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(2)}s`;\n}\n\nexport function formatMetricsSnapshot(snapshot: MetricsSnapshotV1): string {\n\tlet info = `${theme.bold(t(\"Product Metrics\"))}\\n\\n`;\n\tconst bound =\n\t\tsnapshot.window.windowTurns === null\n\t\t\t? t(\"whole journal\")\n\t\t\t: t(\"last {count} turns\", { count: snapshot.window.windowTurns });\n\tinfo += `${theme.fg(\"dim\", t(\"Window:\"))} ${bound} ${t(\"({count} sampled)\", { count: snapshot.window.sampledTurns })}\\n`;\n\n\tconst successRate =\n\t\tsnapshot.turns.successRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.turns.successRate)})`;\n\tinfo += `${theme.fg(\"dim\", t(\"Turns:\"))} ${t(\"{count} total, {succeeded} succeeded\", {\n\t\tcount: snapshot.turns.count,\n\t\tsucceeded: snapshot.turns.successCount,\n\t})}${successRate}\\n`;\n\tinfo += `${theme.fg(\"dim\", t(\"Turn duration:\"))} p50 ${formatMetricsDuration(snapshot.turns.p50DurationMs)}, p95 ${formatMetricsDuration(snapshot.turns.p95DurationMs)}\\n`;\n\n\tconst errorRate = snapshot.tools.errorRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.tools.errorRate)})`;\n\tinfo += `${theme.fg(\"dim\", t(\"Tools:\"))} ${t(\"{calls} calls, {errors} errors\", {\n\t\tcalls: snapshot.tools.calls,\n\t\terrors: snapshot.tools.errors,\n\t})}${errorRate}\\n`;\n\tif (snapshot.tools.topErrors.length > 0) {\n\t\tconst top = snapshot.tools.topErrors.map((entry) => `${entry.toolName} (${entry.errors})`).join(\", \");\n\t\tinfo += `${theme.fg(\"dim\", t(\"Top errors:\"))} ${top}\\n`;\n\t}\n\n\tconst memoryRecall =\n\t\tsnapshot.memoryRecall.status === \"sampled\"\n\t\t\t? t(\"{calls} calls, {hits} hits ({percent})\", {\n\t\t\t\t\tcalls: snapshot.memoryRecall.calls,\n\t\t\t\t\thits: snapshot.memoryRecall.hits,\n\t\t\t\t\tpercent: formatMetricsPercent(snapshot.memoryRecall.hitRate),\n\t\t\t\t})\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.memoryRecall.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Memory recall:\"))} ${memoryRecall}\\n`;\n\n\tconst cancelLatency =\n\t\tsnapshot.cancelLatencyMs.status === \"sampled\"\n\t\t\t? t(\"{count} samples, p95 {p95}\", {\n\t\t\t\t\tcount: snapshot.cancelLatencyMs.count,\n\t\t\t\t\tp95: formatMetricsDuration(snapshot.cancelLatencyMs.p95Ms),\n\t\t\t\t})\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.cancelLatencyMs.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Cancel latency:\"))} ${cancelLatency}\\n`;\n\n\tconst tokens =\n\t\tsnapshot.tokens.status === \"sampled\"\n\t\t\t? t(\"{count} tokens\", { count: snapshot.tokens.totalTokens })\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.tokens.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Tokens:\"))} ${tokens}\\n`;\n\treturn info;\n}\n\nexport function formatDisplayPath(p: string): string {\n\tconst home = os.homedir();\n\tlet result = p;\n\n\t// Replace home directory with ~. On Windows the path may arrive with\n\t// forward slashes while homedir() uses backslashes, so compare both in\n\t// slash form and keep the output in the path's own form.\n\tif (result.startsWith(home)) {\n\t\tresult = `~${result.slice(home.length)}`;\n\t} else {\n\t\tconst homeSlash = home.replaceAll(\"\\\\\", \"/\");\n\t\tconst resultSlash = result.replaceAll(\"\\\\\", \"/\");\n\t\tif (homeSlash !== home && resultSlash.startsWith(homeSlash)) {\n\t\t\tresult = `~${resultSlash.slice(homeSlash.length)}`;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/** Resolve a path against cwd and prefer a cwd-relative rendering. */\nexport function formatContextPath(p: string, cwd: string): string {\n\tconst resolvedCwd = path.resolve(cwd);\n\tconst absolutePath = path.isAbsolute(p) ? path.resolve(p) : path.resolve(resolvedCwd, p);\n\tconst relativePath = getCwdRelativePath(absolutePath, resolvedCwd);\n\tif (relativePath !== undefined) {\n\t\treturn relativePath;\n\t}\n\n\treturn formatDisplayPath(absolutePath);\n}\n\nexport function isPackageSource(sourceInfo?: SourceInfo): boolean {\n\tconst source = sourceInfo?.source ?? \"\";\n\treturn source.startsWith(\"npm:\") || source.startsWith(\"git:\");\n}\n\n/**\n * Get a short path relative to the package root for display.\n */\nexport function getShortPath(fullPath: string, sourceInfo?: SourceInfo): string {\n\tconst normalizedFullPath = fullPath.replace(/\\\\/g, \"/\");\n\tconst baseDir = sourceInfo?.baseDir;\n\tif (baseDir && isPackageSource(sourceInfo)) {\n\t\tconst normalizedBaseDir = baseDir.replace(/\\\\/g, \"/\");\n\t\tconst npmRootMatch = normalizedBaseDir.match(/^(.*\\/node_modules)\\/(@?[^/]+(?:\\/[^/]+)?)$/);\n\t\t// If fullPath is under the same node_modules root as baseDir, preserve that relative topology.\n\t\tif (npmRootMatch?.[1] && normalizedFullPath.startsWith(`${npmRootMatch[1]}/`)) {\n\t\t\treturn path.posix.relative(normalizedBaseDir, normalizedFullPath);\n\t\t}\n\n\t\tconst relativePath = path.relative(path.resolve(baseDir), path.resolve(fullPath));\n\t\tif (\n\t\t\trelativePath &&\n\t\t\trelativePath !== \".\" &&\n\t\t\t!relativePath.startsWith(\"..\") &&\n\t\t\t!relativePath.startsWith(`..${path.sep}`) &&\n\t\t\t!path.isAbsolute(relativePath)\n\t\t) {\n\t\t\treturn relativePath.replace(/\\\\/g, \"/\");\n\t\t}\n\t}\n\n\tconst source = sourceInfo?.source ?? \"\";\n\tconst npmMatch = normalizedFullPath.match(/node_modules\\/(@?[^/]+(?:\\/[^/]+)?)\\/(.*)/);\n\tif (npmMatch && source.startsWith(\"npm:\")) {\n\t\treturn npmMatch[2];\n\t}\n\n\tconst gitMatch = normalizedFullPath.match(/git\\/[^/]+\\/[^/]+\\/(.*)/);\n\tif (gitMatch && source.startsWith(\"git:\")) {\n\t\treturn gitMatch[1];\n\t}\n\n\treturn formatDisplayPath(fullPath);\n}\n\nexport function getCompactPathLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tconst shortPath = getShortPath(resourcePath, sourceInfo);\n\tconst normalizedPath = shortPath.replace(/\\\\/g, \"/\");\n\tconst segments = normalizedPath.split(\"/\").filter((segment) => segment.length > 0 && segment !== \"~\");\n\tif (segments.length > 0) {\n\t\treturn segments[segments.length - 1]!;\n\t}\n\treturn shortPath;\n}\n\nexport function getCompactPackageSourceLabel(sourceInfo?: SourceInfo): string {\n\tconst source = sourceInfo?.source ?? \"\";\n\tif (source.startsWith(\"npm:\")) {\n\t\treturn source.slice(\"npm:\".length) || source;\n\t}\n\n\tconst gitSource = parseGitUrl(source);\n\tif (gitSource) {\n\t\t// v8 ignore next -- buildGitSource 仅在 path 非空时返回,|| 回退不可达\n\t\treturn gitSource.path || source;\n\t}\n\n\treturn source;\n}\n\nexport function getDisplaySourceInfo(sourceInfo?: SourceInfo): {\n\tlabel: string;\n\tscopeLabel?: string;\n\tcolor: \"accent\" | \"muted\";\n} {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"local\") {\n\t\tif (scope === \"user\") {\n\t\t\treturn { label: \"user\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"project\") {\n\t\t\treturn { label: \"project\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"temporary\") {\n\t\t\treturn { label: \"path\", scopeLabel: \"temp\", color: \"muted\" };\n\t\t}\n\t\treturn { label: \"path\", color: \"muted\" };\n\t}\n\n\tif (source === \"cli\") {\n\t\treturn { label: \"path\", scopeLabel: scope === \"temporary\" ? \"temp\" : undefined, color: \"muted\" };\n\t}\n\n\tconst scopeLabel =\n\t\tscope === \"user\" ? \"user\" : scope === \"project\" ? \"project\" : scope === \"temporary\" ? \"temp\" : undefined;\n\treturn { label: source, scopeLabel, color: \"accent\" };\n}\n\nexport function getScopeGroup(sourceInfo?: SourceInfo): \"user\" | \"project\" | \"path\" {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"cli\" || scope === \"temporary\") return \"path\";\n\tif (scope === \"user\") return \"user\";\n\tif (scope === \"project\") return \"project\";\n\treturn \"path\";\n}\n\nexport function buildScopeGroups(items: Array<{ path: string; sourceInfo?: SourceInfo }>): Array<{\n\tscope: \"user\" | \"project\" | \"path\";\n\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n}> {\n\tconst groups: Record<\n\t\t\"user\" | \"project\" | \"path\",\n\t\t{\n\t\t\tscope: \"user\" | \"project\" | \"path\";\n\t\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t\t}\n\t> = {\n\t\tuser: { scope: \"user\", paths: [], packages: new Map() },\n\t\tproject: { scope: \"project\", paths: [], packages: new Map() },\n\t\tpath: { scope: \"path\", paths: [], packages: new Map() },\n\t};\n\n\tfor (const item of items) {\n\t\tconst groupKey = getScopeGroup(item.sourceInfo);\n\t\tconst group = groups[groupKey];\n\t\tconst source = item.sourceInfo?.source ?? \"local\";\n\n\t\tif (isPackageSource(item.sourceInfo)) {\n\t\t\tconst list = group.packages.get(source) ?? [];\n\t\t\tlist.push(item);\n\t\t\tgroup.packages.set(source, list);\n\t\t} else {\n\t\t\tgroup.paths.push(item);\n\t\t}\n\t}\n\n\treturn [groups.project, groups.user, groups.path].filter(\n\t\t(group) => group.paths.length > 0 || group.packages.size > 0,\n\t);\n}\n\nexport function formatScopeGroups(\n\tgroups: Array<{\n\t\tscope: \"user\" | \"project\" | \"path\";\n\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t}>,\n\toptions: {\n\t\tformatPath: (item: { path: string; sourceInfo?: SourceInfo }) => string;\n\t\tformatPackagePath: (item: { path: string; sourceInfo?: SourceInfo }, source: string) => string;\n\t},\n): string {\n\tconst lines: string[] = [];\n\n\tfor (const group of groups) {\n\t\tlines.push(` ${theme.fg(\"accent\", group.scope)}`);\n\n\t\tconst sortedPaths = [...group.paths].sort((a, b) => a.path.localeCompare(b.path));\n\t\tfor (const item of sortedPaths) {\n\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPath(item)}`));\n\t\t}\n\n\t\tconst sortedPackages = Array.from(group.packages.entries()).sort(([a], [b]) => a.localeCompare(b));\n\t\tfor (const [source, items] of sortedPackages) {\n\t\t\tlines.push(` ${theme.fg(\"mdLink\", source)}`);\n\t\t\tconst sortedPackagePaths = [...items].sort((a, b) => a.path.localeCompare(b.path));\n\t\t\tfor (const item of sortedPackagePaths) {\n\t\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPackagePath(item, source)}`));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nexport function findSourceInfoForPath(p: string, sourceInfos: Map<string, SourceInfo>): SourceInfo | undefined {\n\tconst exact = sourceInfos.get(p);\n\tif (exact) return exact;\n\n\tlet current = p;\n\twhile (current.includes(\"/\")) {\n\t\tcurrent = current.substring(0, current.lastIndexOf(\"/\"));\n\t\tconst parent = sourceInfos.get(current);\n\t\tif (parent) return parent;\n\t}\n\n\treturn undefined;\n}\n\nexport function formatPathWithSource(p: string, sourceInfo?: SourceInfo): string {\n\tif (sourceInfo) {\n\t\tconst shortPath = getShortPath(p, sourceInfo);\n\t\tconst { label, scopeLabel } = getDisplaySourceInfo(sourceInfo);\n\t\tconst labelText = scopeLabel ? `${label} (${scopeLabel})` : label;\n\t\treturn `${labelText} ${shortPath}`;\n\t}\n\treturn formatDisplayPath(p);\n}\n\nexport function formatDiagnostics(\n\tdiagnostics: readonly ResourceDiagnostic[],\n\tsourceInfos: Map<string, SourceInfo>,\n): string {\n\tconst lines: string[] = [];\n\n\t// Group collision diagnostics by name\n\tconst collisions = new Map<string, ResourceDiagnostic[]>();\n\tconst otherDiagnostics: ResourceDiagnostic[] = [];\n\n\tfor (const d of diagnostics) {\n\t\tif (d.type === \"collision\" && d.collision) {\n\t\t\tconst list = collisions.get(d.collision.name) ?? [];\n\t\t\tlist.push(d);\n\t\t\tcollisions.set(d.collision.name, list);\n\t\t} else {\n\t\t\totherDiagnostics.push(d);\n\t\t}\n\t}\n\n\t// Format collision diagnostics grouped by name\n\tfor (const [name, collisionList] of collisions) {\n\t\tconst first = collisionList[0]?.collision;\n\t\t// v8 ignore next -- collision lists only hold diagnostics whose collision payload is set\n\t\tif (!first) continue;\n\t\tlines.push(theme.fg(\"warning\", ` ${t('\"{name}\" collision:', { name })}`));\n\t\tlines.push(\n\t\t\ttheme.fg(\n\t\t\t\t\"dim\",\n\t\t\t\t` ${theme.fg(\"success\", \"✓\")} ${formatPathWithSource(first.winnerPath, findSourceInfoForPath(first.winnerPath, sourceInfos))}`,\n\t\t\t),\n\t\t);\n\t\tfor (const d of collisionList) {\n\t\t\t// v8 ignore next -- collision 列表仅收集带 collision 载荷的诊断\n\t\t\tif (d.collision) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\t` ${theme.fg(\"warning\", \"✗\")} ${formatPathWithSource(d.collision.loserPath, findSourceInfoForPath(d.collision.loserPath, sourceInfos))} ${t(\"(skipped)\")}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const d of otherDiagnostics) {\n\t\tif (d.path) {\n\t\t\tconst formattedPath = formatPathWithSource(d.path, findSourceInfoForPath(d.path, sourceInfos));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${formattedPath}`));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t} else {\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"]}