@kolisachint/hoocode-agent 0.4.106 → 0.4.107

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 (289) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/cli/args.d.ts.map +1 -1
  3. package/dist/cli/args.js +4 -4
  4. package/dist/cli/args.js.map +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +0 -1
  7. package/dist/cli.js.map +1 -1
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +2 -2
  10. package/dist/config.js.map +1 -1
  11. package/dist/core/agent-session.d.ts +1 -3
  12. package/dist/core/agent-session.d.ts.map +1 -1
  13. package/dist/core/agent-session.js +2 -2
  14. package/dist/core/agent-session.js.map +1 -1
  15. package/dist/core/bash-executor.d.ts.map +1 -1
  16. package/dist/core/bash-executor.js +1 -1
  17. package/dist/core/bash-executor.js.map +1 -1
  18. package/dist/core/extension-mcp-servers.d.ts +1 -1
  19. package/dist/core/extension-mcp-servers.d.ts.map +1 -1
  20. package/dist/core/extension-mcp-servers.js +1 -1
  21. package/dist/core/extension-mcp-servers.js.map +1 -1
  22. package/dist/core/extensions/plugins/index.d.ts.map +1 -1
  23. package/dist/core/extensions/plugins/index.js +1 -1
  24. package/dist/core/extensions/plugins/index.js.map +1 -1
  25. package/dist/core/extensions/types.d.ts +1 -3
  26. package/dist/core/extensions/types.d.ts.map +1 -1
  27. package/dist/core/extensions/types.js.map +1 -1
  28. package/dist/core/index.d.ts +1 -1
  29. package/dist/core/index.d.ts.map +1 -1
  30. package/dist/core/index.js.map +1 -1
  31. package/dist/core/mode-prompts.d.ts +1 -1
  32. package/dist/core/mode-prompts.d.ts.map +1 -1
  33. package/dist/core/mode-prompts.js +1 -1
  34. package/dist/core/mode-prompts.js.map +1 -1
  35. package/dist/core/package-manager.d.ts.map +1 -1
  36. package/dist/core/package-manager.js +1 -1
  37. package/dist/core/package-manager.js.map +1 -1
  38. package/dist/core/sdk.d.ts.map +1 -1
  39. package/dist/core/sdk.js +1 -2
  40. package/dist/core/sdk.js.map +1 -1
  41. package/dist/core/session-manager.d.ts +2 -97
  42. package/dist/core/session-manager.d.ts.map +1 -1
  43. package/dist/core/session-manager.js +4 -65
  44. package/dist/core/session-manager.js.map +1 -1
  45. package/dist/core/settings-manager.d.ts.map +1 -1
  46. package/dist/core/settings-manager.js +2 -3
  47. package/dist/core/settings-manager.js.map +1 -1
  48. package/dist/core/telemetry.d.ts.map +1 -1
  49. package/dist/core/telemetry.js +1 -1
  50. package/dist/core/telemetry.js.map +1 -1
  51. package/dist/core/timings.d.ts +1 -1
  52. package/dist/core/timings.d.ts.map +1 -1
  53. package/dist/core/timings.js +2 -2
  54. package/dist/core/timings.js.map +1 -1
  55. package/dist/core/tools/{browser-continue.d.ts → browser/browser-continue.d.ts} +1 -1
  56. package/dist/core/tools/browser/browser-continue.d.ts.map +1 -0
  57. package/dist/core/tools/{browser-continue.js → browser/browser-continue.js} +2 -2
  58. package/dist/core/tools/browser/browser-continue.js.map +1 -0
  59. package/dist/core/tools/{browser-run.d.ts → browser/browser-run.d.ts} +2 -2
  60. package/dist/core/tools/browser/browser-run.d.ts.map +1 -0
  61. package/dist/core/tools/{browser-run.js → browser/browser-run.js} +2 -2
  62. package/dist/core/tools/browser/browser-run.js.map +1 -0
  63. package/dist/core/tools/browser/browsertools-shared.d.ts.map +1 -0
  64. package/dist/core/tools/{browsertools-shared.js → browser/browsertools-shared.js} +1 -1
  65. package/dist/core/tools/browser/browsertools-shared.js.map +1 -0
  66. package/dist/core/tools/browser/index.d.ts +8 -0
  67. package/dist/core/tools/browser/index.d.ts.map +1 -0
  68. package/dist/core/tools/browser/index.js +8 -0
  69. package/dist/core/tools/browser/index.js.map +1 -0
  70. package/dist/core/tools/{docedit.d.ts → doc/docedit.d.ts} +2 -2
  71. package/dist/core/tools/doc/docedit.d.ts.map +1 -0
  72. package/dist/core/tools/{docedit.js → doc/docedit.js} +7 -7
  73. package/dist/core/tools/doc/docedit.js.map +1 -0
  74. package/dist/core/tools/{docgrep.d.ts → doc/docgrep.d.ts} +2 -2
  75. package/dist/core/tools/doc/docgrep.d.ts.map +1 -0
  76. package/dist/core/tools/{docgrep.js → doc/docgrep.js} +6 -6
  77. package/dist/core/tools/doc/docgrep.js.map +1 -0
  78. package/dist/core/tools/{docpeek.d.ts → doc/docpeek.d.ts} +2 -2
  79. package/dist/core/tools/{docpeek.js.map → doc/docpeek.d.ts.map} +1 -1
  80. package/dist/core/tools/{docpeek.js → doc/docpeek.js} +6 -6
  81. package/dist/core/tools/doc/docpeek.js.map +1 -0
  82. package/dist/core/tools/{docread.d.ts → doc/docread.d.ts} +2 -2
  83. package/dist/core/tools/doc/docread.d.ts.map +1 -0
  84. package/dist/core/tools/{docread.js → doc/docread.js} +6 -6
  85. package/dist/core/tools/doc/docread.js.map +1 -0
  86. package/dist/core/tools/{docscan.d.ts → doc/docscan.d.ts} +2 -2
  87. package/dist/core/tools/doc/docscan.d.ts.map +1 -0
  88. package/dist/core/tools/{docscan.js → doc/docscan.js} +6 -6
  89. package/dist/core/tools/doc/docscan.js.map +1 -0
  90. package/dist/core/tools/{docwrite.d.ts → doc/docwrite.d.ts} +1 -1
  91. package/dist/core/tools/doc/docwrite.d.ts.map +1 -0
  92. package/dist/core/tools/{docwrite.js → doc/docwrite.js} +6 -6
  93. package/dist/core/tools/doc/docwrite.js.map +1 -0
  94. package/dist/core/tools/doc/index.d.ts +11 -0
  95. package/dist/core/tools/doc/index.d.ts.map +1 -0
  96. package/dist/core/tools/doc/index.js +11 -0
  97. package/dist/core/tools/doc/index.js.map +1 -0
  98. package/dist/core/tools/grep.d.ts.map +1 -1
  99. package/dist/core/tools/grep.js +1 -1
  100. package/dist/core/tools/grep.js.map +1 -1
  101. package/dist/core/tools/index.d.ts +42 -28
  102. package/dist/core/tools/index.d.ts.map +1 -1
  103. package/dist/core/tools/index.js +61 -199
  104. package/dist/core/tools/index.js.map +1 -1
  105. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  106. package/dist/core/tools/output-accumulator.js +1 -1
  107. package/dist/core/tools/output-accumulator.js.map +1 -1
  108. package/dist/core/tools/read.d.ts.map +1 -1
  109. package/dist/core/tools/read.js +1 -1
  110. package/dist/core/tools/read.js.map +1 -1
  111. package/dist/extensions/core/ask-options.d.ts +10 -0
  112. package/dist/extensions/core/ask-options.d.ts.map +1 -0
  113. package/dist/extensions/core/ask-options.js +83 -0
  114. package/dist/extensions/core/ask-options.js.map +1 -0
  115. package/dist/extensions/core/config.d.ts +80 -0
  116. package/dist/extensions/core/config.d.ts.map +1 -0
  117. package/dist/extensions/core/config.js +110 -0
  118. package/dist/extensions/core/config.js.map +1 -0
  119. package/dist/extensions/core/cost.d.ts +11 -0
  120. package/dist/extensions/core/cost.d.ts.map +1 -0
  121. package/dist/extensions/core/cost.js +64 -0
  122. package/dist/extensions/core/cost.js.map +1 -0
  123. package/dist/extensions/core/hoo-core.d.ts +16 -179
  124. package/dist/extensions/core/hoo-core.d.ts.map +1 -1
  125. package/dist/extensions/core/hoo-core.js +27 -1663
  126. package/dist/extensions/core/hoo-core.js.map +1 -1
  127. package/dist/extensions/core/loop.d.ts +15 -0
  128. package/dist/extensions/core/loop.d.ts.map +1 -0
  129. package/dist/extensions/core/loop.js +235 -0
  130. package/dist/extensions/core/loop.js.map +1 -0
  131. package/dist/extensions/core/marketplace.d.ts +17 -0
  132. package/dist/extensions/core/marketplace.d.ts.map +1 -0
  133. package/dist/extensions/core/marketplace.js +167 -0
  134. package/dist/extensions/core/marketplace.js.map +1 -0
  135. package/dist/extensions/core/mcp-loader.d.ts +26 -0
  136. package/dist/extensions/core/mcp-loader.d.ts.map +1 -0
  137. package/dist/extensions/core/mcp-loader.js +391 -0
  138. package/dist/extensions/core/mcp-loader.js.map +1 -0
  139. package/dist/extensions/core/modes.d.ts +56 -0
  140. package/dist/extensions/core/modes.d.ts.map +1 -0
  141. package/dist/extensions/core/modes.js +268 -0
  142. package/dist/extensions/core/modes.js.map +1 -0
  143. package/dist/extensions/core/permission-gate.d.ts +10 -0
  144. package/dist/extensions/core/permission-gate.d.ts.map +1 -0
  145. package/dist/extensions/core/permission-gate.js +167 -0
  146. package/dist/extensions/core/permission-gate.js.map +1 -0
  147. package/dist/extensions/core/scaffold.d.ts +9 -0
  148. package/dist/extensions/core/scaffold.d.ts.map +1 -0
  149. package/dist/extensions/core/scaffold.js +146 -0
  150. package/dist/extensions/core/scaffold.js.map +1 -0
  151. package/dist/extensions/core/thinking-escalation.d.ts +18 -0
  152. package/dist/extensions/core/thinking-escalation.d.ts.map +1 -0
  153. package/dist/extensions/core/thinking-escalation.js +70 -0
  154. package/dist/extensions/core/thinking-escalation.js.map +1 -0
  155. package/dist/index.d.ts +2 -3
  156. package/dist/index.d.ts.map +1 -1
  157. package/dist/index.js +3 -4
  158. package/dist/index.js.map +1 -1
  159. package/dist/main.d.ts.map +1 -1
  160. package/dist/main.js +2 -2
  161. package/dist/main.js.map +1 -1
  162. package/dist/modes/interactive/command-executor.d.ts +0 -5
  163. package/dist/modes/interactive/command-executor.d.ts.map +1 -1
  164. package/dist/modes/interactive/command-executor.js +0 -7
  165. package/dist/modes/interactive/command-executor.js.map +1 -1
  166. package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
  167. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  168. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  169. package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
  170. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  171. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  172. package/dist/modes/interactive/components/custom-message.d.ts +1 -1
  173. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  174. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  175. package/dist/modes/interactive/components/index.d.ts +0 -2
  176. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  177. package/dist/modes/interactive/components/index.js +0 -2
  178. package/dist/modes/interactive/components/index.js.map +1 -1
  179. package/dist/modes/interactive/extension-chrome.d.ts +56 -0
  180. package/dist/modes/interactive/extension-chrome.d.ts.map +1 -0
  181. package/dist/modes/interactive/extension-chrome.js +172 -0
  182. package/dist/modes/interactive/extension-chrome.js.map +1 -0
  183. package/dist/modes/interactive/extension-dialogs.d.ts +82 -0
  184. package/dist/modes/interactive/extension-dialogs.d.ts.map +1 -0
  185. package/dist/modes/interactive/extension-dialogs.js +259 -0
  186. package/dist/modes/interactive/extension-dialogs.js.map +1 -0
  187. package/dist/modes/interactive/interactive-mode.d.ts +11 -161
  188. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  189. package/dist/modes/interactive/interactive-mode.js +261 -1584
  190. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  191. package/dist/modes/interactive/resource-display.d.ts +59 -0
  192. package/dist/modes/interactive/resource-display.d.ts.map +1 -0
  193. package/dist/modes/interactive/resource-display.js +499 -0
  194. package/dist/modes/interactive/resource-display.js.map +1 -0
  195. package/dist/modes/interactive/startup-checks.d.ts +17 -0
  196. package/dist/modes/interactive/startup-checks.d.ts.map +1 -0
  197. package/dist/modes/interactive/startup-checks.js +102 -0
  198. package/dist/modes/interactive/startup-checks.js.map +1 -0
  199. package/dist/modes/interactive/team-focus.d.ts +56 -0
  200. package/dist/modes/interactive/team-focus.d.ts.map +1 -0
  201. package/dist/modes/interactive/team-focus.js +167 -0
  202. package/dist/modes/interactive/team-focus.js.map +1 -0
  203. package/dist/modes/interactive/voice/voice-controller.d.ts +66 -0
  204. package/dist/modes/interactive/voice/voice-controller.d.ts.map +1 -0
  205. package/dist/modes/interactive/voice/voice-controller.js +312 -0
  206. package/dist/modes/interactive/voice/voice-controller.js.map +1 -0
  207. package/dist/modes/interactive/voice/voice-panel.d.ts.map +1 -0
  208. package/dist/modes/interactive/voice/voice-panel.js.map +1 -0
  209. package/dist/modes/interactive/voice/voice-transcribe.d.ts.map +1 -0
  210. package/dist/modes/interactive/voice/voice-transcribe.js.map +1 -0
  211. package/dist/modes/rpc/rpc-client.d.ts +1 -2
  212. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  213. package/dist/modes/rpc/rpc-client.js.map +1 -1
  214. package/dist/modes/rpc/rpc-types.d.ts +1 -2
  215. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  216. package/dist/modes/rpc/rpc-types.js.map +1 -1
  217. package/dist/resources-cli.d.ts.map +1 -1
  218. package/dist/resources-cli.js +1 -1
  219. package/dist/resources-cli.js.map +1 -1
  220. package/dist/utils/tools-manager.d.ts.map +1 -1
  221. package/dist/utils/tools-manager.js +1 -1
  222. package/dist/utils/tools-manager.js.map +1 -1
  223. package/dist/utils/version-check.d.ts.map +1 -1
  224. package/dist/utils/version-check.js +2 -2
  225. package/dist/utils/version-check.js.map +1 -1
  226. package/docs/project-local-resources.md +1 -1
  227. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  228. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  229. package/examples/extensions/sandbox/package.json +1 -1
  230. package/examples/extensions/with-deps/package.json +1 -1
  231. package/package.json +4 -4
  232. package/dist/core/compaction/branch-summarization.d.ts +0 -88
  233. package/dist/core/compaction/branch-summarization.d.ts.map +0 -1
  234. package/dist/core/compaction/branch-summarization.js +0 -243
  235. package/dist/core/compaction/branch-summarization.js.map +0 -1
  236. package/dist/core/compaction/compaction.d.ts +0 -123
  237. package/dist/core/compaction/compaction.d.ts.map +0 -1
  238. package/dist/core/compaction/compaction.js +0 -635
  239. package/dist/core/compaction/compaction.js.map +0 -1
  240. package/dist/core/compaction/index.d.ts +0 -7
  241. package/dist/core/compaction/index.d.ts.map +0 -1
  242. package/dist/core/compaction/index.js +0 -7
  243. package/dist/core/compaction/index.js.map +0 -1
  244. package/dist/core/compaction/utils.d.ts +0 -38
  245. package/dist/core/compaction/utils.d.ts.map +0 -1
  246. package/dist/core/compaction/utils.js +0 -156
  247. package/dist/core/compaction/utils.js.map +0 -1
  248. package/dist/core/messages.d.ts +0 -124
  249. package/dist/core/messages.d.ts.map +0 -1
  250. package/dist/core/messages.js +0 -221
  251. package/dist/core/messages.js.map +0 -1
  252. package/dist/core/tools/browser-continue.d.ts.map +0 -1
  253. package/dist/core/tools/browser-continue.js.map +0 -1
  254. package/dist/core/tools/browser-run.d.ts.map +0 -1
  255. package/dist/core/tools/browser-run.js.map +0 -1
  256. package/dist/core/tools/browsertools-shared.d.ts.map +0 -1
  257. package/dist/core/tools/browsertools-shared.js.map +0 -1
  258. package/dist/core/tools/docedit.d.ts.map +0 -1
  259. package/dist/core/tools/docedit.js.map +0 -1
  260. package/dist/core/tools/docgrep.d.ts.map +0 -1
  261. package/dist/core/tools/docgrep.js.map +0 -1
  262. package/dist/core/tools/docpeek.d.ts.map +0 -1
  263. package/dist/core/tools/docread.d.ts.map +0 -1
  264. package/dist/core/tools/docread.js.map +0 -1
  265. package/dist/core/tools/docscan.d.ts.map +0 -1
  266. package/dist/core/tools/docscan.js.map +0 -1
  267. package/dist/core/tools/docwrite.d.ts.map +0 -1
  268. package/dist/core/tools/docwrite.js.map +0 -1
  269. package/dist/core/tools/output-compression.d.ts +0 -53
  270. package/dist/core/tools/output-compression.d.ts.map +0 -1
  271. package/dist/core/tools/output-compression.js +0 -392
  272. package/dist/core/tools/output-compression.js.map +0 -1
  273. package/dist/modes/interactive/components/armin.d.ts +0 -34
  274. package/dist/modes/interactive/components/armin.d.ts.map +0 -1
  275. package/dist/modes/interactive/components/armin.js +0 -333
  276. package/dist/modes/interactive/components/armin.js.map +0 -1
  277. package/dist/modes/interactive/components/daxnuts.d.ts +0 -23
  278. package/dist/modes/interactive/components/daxnuts.d.ts.map +0 -1
  279. package/dist/modes/interactive/components/daxnuts.js +0 -140
  280. package/dist/modes/interactive/components/daxnuts.js.map +0 -1
  281. package/dist/modes/interactive/components/voice-panel.d.ts.map +0 -1
  282. package/dist/modes/interactive/components/voice-panel.js.map +0 -1
  283. package/dist/modes/interactive/voice-transcribe.d.ts.map +0 -1
  284. package/dist/modes/interactive/voice-transcribe.js.map +0 -1
  285. /package/dist/core/tools/{browsertools-shared.d.ts → browser/browsertools-shared.d.ts} +0 -0
  286. /package/dist/modes/interactive/{components → voice}/voice-panel.d.ts +0 -0
  287. /package/dist/modes/interactive/{components → voice}/voice-panel.js +0 -0
  288. /package/dist/modes/interactive/{voice-transcribe.d.ts → voice/voice-transcribe.d.ts} +0 -0
  289. /package/dist/modes/interactive/{voice-transcribe.js → voice/voice-transcribe.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-display.js","sourceRoot":"","sources":["../../../src/modes/interactive/resource-display.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Startup/reload resource listing: path and source-label formatting, scope\n * grouping, diagnostics rendering, and the [Resources]/[Skills]/… sections\n * shown in the chat. Extracted from interactive-mode.ts; everything here is\n * either pure formatting or rendering into a container passed via deps.\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { type Container, Spacer, Text } from \"@kolisachint/hoocode-tui\";\nimport type { ExtensionRunner } from \"../../core/extensions/index.js\";\nimport type { PromptTemplate } from \"../../core/prompt-templates.js\";\nimport type { ResourceDiagnostic, ResourceLoader } from \"../../core/resource-loader.js\";\nimport type { SourceInfo } from \"../../core/source-info.js\";\nimport { parseGitUrl } from \"../../utils/git.js\";\nimport { getCwdRelativePath } from \"../../utils/paths.js\";\nimport { type ThemeColor, theme } from \"./theme/theme.js\";\n\n// ============================================================================\n// Expandable sections\n// ============================================================================\n\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;\n}\n\nexport class ExpandableText extends Text implements Expandable {\n\tconstructor(\n\t\tprivate collapsed: () => string,\n\t\tprivate expanded: () => string,\n\t\tinitiallyExpanded: boolean,\n\t\tpaddingX: number,\n\t\tpaddingY: number,\n\t) {\n\t\tsuper(initiallyExpanded ? expanded() : collapsed(), paddingX, paddingY);\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.setText(expanded ? this.expanded() : this.collapsed());\n\t}\n}\n\n// ============================================================================\n// Path and source-label formatting\n// ============================================================================\n\nexport function formatDisplayPath(p: string): string {\n\tconst home = os.homedir();\n\tlet result = p;\n\n\t// Replace home directory with ~\n\tif (result.startsWith(home)) {\n\t\tresult = `~${result.slice(home.length)}`;\n\t}\n\n\treturn result;\n}\n\nexport function formatExtensionDisplayPath(extensionPath: string): string {\n\tlet result = formatDisplayPath(extensionPath);\n\tresult = result.replace(/\\/index\\.ts$/, \"\").replace(/\\/index\\.js$/, \"\");\n\treturn result;\n}\n\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\n/**\n * Get a short path relative to the package root for display.\n */\nexport function getShortPath(fullPath: string, sourceInfo?: SourceInfo): string {\n\tconst baseDir = sourceInfo?.baseDir;\n\tif (baseDir && isPackageSource(sourceInfo)) {\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 = fullPath.match(/node_modules\\/(@?[^/]+(?:\\/[^/]+)?)\\/(.*)/);\n\tif (npmMatch && source.startsWith(\"npm:\")) {\n\t\treturn npmMatch[2];\n\t}\n\n\tconst gitMatch = fullPath.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\nfunction 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\treturn gitSource.path || source;\n\t}\n\n\treturn source;\n}\n\nfunction getCompactExtensionLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tif (!isPackageSource(sourceInfo)) {\n\t\treturn getCompactPathLabel(resourcePath, sourceInfo);\n\t}\n\n\tconst sourceLabel = getCompactPackageSourceLabel(sourceInfo);\n\tif (!sourceLabel) {\n\t\treturn getCompactPathLabel(resourcePath, sourceInfo);\n\t}\n\n\tconst shortPath = getShortPath(resourcePath, sourceInfo).replace(/\\\\/g, \"/\");\n\tconst packagePath = shortPath.startsWith(\"extensions/\") ? shortPath.slice(\"extensions/\".length) : shortPath;\n\tconst parsedPath = path.posix.parse(packagePath);\n\n\tif (parsedPath.name === \"index\") {\n\t\treturn !parsedPath.dir || parsedPath.dir === \".\" ? sourceLabel : `${sourceLabel}:${parsedPath.dir}`;\n\t}\n\n\treturn `${sourceLabel}:${packagePath}`;\n}\n\nfunction getCompactDisplayPathSegments(resourcePath: string): string[] {\n\treturn formatDisplayPath(resourcePath)\n\t\t.replace(/\\\\/g, \"/\")\n\t\t.split(\"/\")\n\t\t.filter((segment) => segment.length > 0 && segment !== \"~\");\n}\n\nfunction getCompactNonPackageExtensionLabel(\n\tresourcePath: string,\n\tindex: number,\n\tallPaths: Array<{ path: string; segments: string[] }>,\n): string {\n\tconst segments = allPaths[index]?.segments;\n\tif (!segments || segments.length === 0) {\n\t\treturn getCompactPathLabel(resourcePath);\n\t}\n\n\tfor (let segmentCount = 1; segmentCount <= segments.length; segmentCount += 1) {\n\t\tconst candidate = segments.slice(-segmentCount).join(\"/\");\n\t\tconst isUnique = allPaths.every((item, itemIndex) => {\n\t\t\tif (itemIndex === index) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn item.segments.slice(-segmentCount).join(\"/\") !== candidate;\n\t\t});\n\n\t\tif (isUnique) {\n\t\t\treturn candidate;\n\t\t}\n\t}\n\n\treturn segments.join(\"/\");\n}\n\nexport function getCompactExtensionLabels(\n\textensions: Array<{ path: string; sourceInfo?: SourceInfo; displayName?: string }>,\n): string[] {\n\tconst nonPackageExtensions = extensions\n\t\t.map((extension) => {\n\t\t\tconst segments = getCompactDisplayPathSegments(extension.path);\n\t\t\tconst lastSegment = segments[segments.length - 1];\n\t\t\tif (segments.length > 1 && (lastSegment === \"index.ts\" || lastSegment === \"index.js\")) {\n\t\t\t\tsegments.pop();\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpath: extension.path,\n\t\t\t\tsourceInfo: extension.sourceInfo,\n\t\t\t\tsegments,\n\t\t\t};\n\t\t})\n\t\t.filter((extension) => !isPackageSource(extension.sourceInfo));\n\n\treturn extensions.map((extension) => {\n\t\tif (extension.displayName) {\n\t\t\treturn extension.displayName;\n\t\t}\n\n\t\tif (isPackageSource(extension.sourceInfo)) {\n\t\t\treturn getCompactExtensionLabel(extension.path, extension.sourceInfo);\n\t\t}\n\n\t\tconst nonPackageIndex = nonPackageExtensions.findIndex((item) => item.path === extension.path);\n\t\tif (nonPackageIndex === -1) {\n\t\t\treturn getCompactPathLabel(extension.path, extension.sourceInfo);\n\t\t}\n\n\t\treturn getCompactNonPackageExtensionLabel(extension.path, nonPackageIndex, nonPackageExtensions);\n\t});\n}\n\nfunction 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\nfunction 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\nfunction isPackageSource(sourceInfo?: SourceInfo): boolean {\n\tconst source = sourceInfo?.source ?? \"\";\n\treturn source.startsWith(\"npm:\") || source.startsWith(\"git:\");\n}\n\n// ============================================================================\n// Scope grouping and diagnostics\n// ============================================================================\n\ninterface ScopedItem {\n\tpath: string;\n\tsourceInfo?: SourceInfo;\n\tdisplayName?: string;\n}\n\ninterface ScopeGroup {\n\tscope: \"user\" | \"project\" | \"path\";\n\tpaths: ScopedItem[];\n\tpackages: Map<string, ScopedItem[]>;\n}\n\nfunction buildScopeGroups(items: ScopedItem[]): ScopeGroup[] {\n\tconst groups: Record<\"user\" | \"project\" | \"path\", ScopeGroup> = {\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\nfunction formatScopeGroups(\n\tgroups: ScopeGroup[],\n\toptions: {\n\t\tformatPath: (item: ScopedItem) => string;\n\t\tformatPackagePath: (item: ScopedItem, 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\nfunction 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\nfunction 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\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\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\n// ============================================================================\n// Loaded-resources listing\n// ============================================================================\n\n/** The slice of the interactive mode the resource listing renders into. */\nexport interface ResourceDisplayDeps {\n\tchatContainer: Container;\n\tgetCwd(): string;\n\tgetResourceLoader(): ResourceLoader;\n\tgetPromptTemplates(): ReadonlyArray<PromptTemplate>;\n\tgetExtensionRunner(): ExtensionRunner;\n\tgetActiveMode(): string;\n\tgetSubagentEnabled(): boolean;\n\tquietStartup(): boolean;\n\tverbose: boolean;\n\t/** Startup expansion state for the collapsible sections. */\n\tisExpanded(): boolean;\n\tgetBuiltInCommandConflictDiagnostics(extensionRunner: ExtensionRunner): ResourceDiagnostic[];\n}\n\nexport function showLoadedResources(\n\tdeps: ResourceDisplayDeps,\n\toptions?: {\n\t\textensions?: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\tforce?: boolean;\n\t\tshowDiagnosticsWhenQuiet?: boolean;\n\t},\n): void {\n\tconst showListing = options?.force || deps.verbose || !deps.quietStartup();\n\tconst showDiagnostics = showListing || options?.showDiagnosticsWhenQuiet === true;\n\tif (!showListing && !showDiagnostics) {\n\t\treturn;\n\t}\n\n\tconst resourceLoader = deps.getResourceLoader();\n\tconst chatContainer = deps.chatContainer;\n\n\tconst sectionHeader = (name: string, color: ThemeColor = \"mdHeading\") => theme.fg(color, `[${name}]`);\n\tconst formatCompactList = (items: string[], listOptions?: { sort?: boolean }): string => {\n\t\tconst labels = items.map((item) => item.trim()).filter((item) => item.length > 0);\n\t\tif (listOptions?.sort !== false) {\n\t\t\tlabels.sort((a, b) => a.localeCompare(b));\n\t\t}\n\t\treturn theme.fg(\"dim\", ` ${labels.join(\", \")}`);\n\t};\n\tconst addLoadedSection = (\n\t\tname: string,\n\t\tcollapsedBody: string,\n\t\texpandedBody = collapsedBody,\n\t\tcolor: ThemeColor = \"mdHeading\",\n\t): void => {\n\t\tconst section = new ExpandableText(\n\t\t\t() => `${sectionHeader(name, color)}\\n${collapsedBody}`,\n\t\t\t() => `${sectionHeader(name, color)}\\n${expandedBody}`,\n\t\t\tdeps.isExpanded(),\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t\tchatContainer.addChild(section);\n\t\tchatContainer.addChild(new Spacer(1));\n\t};\n\n\tconst skillsResult = resourceLoader.getSkills();\n\tconst promptsResult = resourceLoader.getPrompts();\n\tconst themesResult = resourceLoader.getThemes();\n\tconst extensions =\n\t\toptions?.extensions ??\n\t\tresourceLoader\n\t\t\t.getExtensions()\n\t\t\t.extensions.filter((extension) => !extension.internal)\n\t\t\t.map((extension) => ({\n\t\t\t\tpath: extension.path,\n\t\t\t\tsourceInfo: extension.sourceInfo,\n\t\t\t\tdisplayName: extension.displayName,\n\t\t\t}));\n\tconst sourceInfos = new Map<string, SourceInfo>();\n\tfor (const extension of extensions) {\n\t\tif (extension.sourceInfo) {\n\t\t\tsourceInfos.set(extension.path, extension.sourceInfo);\n\t\t}\n\t}\n\tfor (const skill of skillsResult.skills) {\n\t\tif (skill.sourceInfo) {\n\t\t\tsourceInfos.set(skill.filePath, skill.sourceInfo);\n\t\t}\n\t}\n\tfor (const prompt of promptsResult.prompts) {\n\t\tif (prompt.sourceInfo) {\n\t\t\tsourceInfos.set(prompt.filePath, prompt.sourceInfo);\n\t\t}\n\t}\n\tfor (const loadedTheme of themesResult.themes) {\n\t\tif (loadedTheme.sourcePath && loadedTheme.sourceInfo) {\n\t\t\tsourceInfos.set(loadedTheme.sourcePath, loadedTheme.sourceInfo);\n\t\t}\n\t}\n\n\tif (showListing) {\n\t\tchatContainer.addChild(new Spacer(1));\n\n\t\tconst { agentsFiles: contextFiles, warnings: contextWarnings } = resourceLoader.getAgentsFiles();\n\t\tconst skills = skillsResult.skills;\n\t\tconst templates = deps.getPromptTemplates();\n\t\tconst loadedThemes = themesResult.themes;\n\t\tconst customThemes = loadedThemes.filter((t) => t.sourcePath);\n\n\t\tconst totalItems =\n\t\t\tcontextFiles.length + skills.length + templates.length + extensions.length + customThemes.length;\n\n\t\t// Meta items: active mode and subagent system prompt (always shown)\n\t\tconst metaItems: string[] = [];\n\t\tconst rawMode = deps.getActiveMode().replace(\" + subagent\", \"\");\n\t\tmetaItems.push(`mode/${rawMode}`);\n\t\tif (deps.getSubagentEnabled()) {\n\t\t\tmetaItems.push(\"subagent_system_prompt\");\n\t\t}\n\n\t\tif (totalItems > 0 && totalItems <= 5) {\n\t\t\tconst allCompactItems: string[] = [...metaItems];\n\t\t\tif (contextFiles.length > 0) {\n\t\t\t\tallCompactItems.push(\n\t\t\t\t\t...contextFiles.map((contextFile) => formatContextPath(contextFile.path, deps.getCwd())),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (skills.length > 0) {\n\t\t\t\tallCompactItems.push(...skills.map((skill) => skill.name));\n\t\t\t}\n\t\t\tif (templates.length > 0) {\n\t\t\t\tallCompactItems.push(...templates.map((template) => `/${template.name}`));\n\t\t\t}\n\t\t\tif (extensions.length > 0) {\n\t\t\t\tallCompactItems.push(...getCompactExtensionLabels(extensions));\n\t\t\t}\n\t\t\tif (customThemes.length > 0) {\n\t\t\t\tallCompactItems.push(\n\t\t\t\t\t...customThemes.map(\n\t\t\t\t\t\t(loadedTheme) =>\n\t\t\t\t\t\t\tloadedTheme.name ?? getCompactPathLabel(loadedTheme.sourcePath!, loadedTheme.sourceInfo),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tchatContainer.addChild(\n\t\t\t\tnew Text(`${theme.fg(\"mdHeading\", \"[Resources]\")} ${theme.fg(\"dim\", allCompactItems.join(\", \"))}`, 0, 0),\n\t\t\t);\n\t\t} else if (totalItems === 0) {\n\t\t\tchatContainer.addChild(\n\t\t\t\tnew Text(`${theme.fg(\"mdHeading\", \"[Resources]\")} ${theme.fg(\"dim\", metaItems.join(\", \"))}`, 0, 0),\n\t\t\t);\n\t\t} else {\n\t\t\taddLoadedSection(\"Resources\", formatCompactList(metaItems), formatCompactList(metaItems));\n\t\t\tif (contextFiles.length > 0) {\n\t\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t\t\tconst contextList = contextFiles.map((f) => theme.fg(\"dim\", ` ${formatDisplayPath(f.path)}`)).join(\"\\n\");\n\t\t\t\tconst contextCompactList = formatCompactList(\n\t\t\t\t\tcontextFiles.map((contextFile) => formatContextPath(contextFile.path, deps.getCwd())),\n\t\t\t\t\t{ sort: false },\n\t\t\t\t);\n\t\t\t\taddLoadedSection(\"Context\", contextCompactList, contextList);\n\t\t\t}\n\n\t\t\tif (skills.length > 0) {\n\t\t\t\tconst groups = buildScopeGroups(\n\t\t\t\t\tskills.map((skill) => ({ path: skill.filePath, sourceInfo: skill.sourceInfo })),\n\t\t\t\t);\n\t\t\t\tconst skillList = formatScopeGroups(groups, {\n\t\t\t\t\tformatPath: (item) => formatDisplayPath(item.path),\n\t\t\t\t\tformatPackagePath: (item) => getShortPath(item.path, item.sourceInfo),\n\t\t\t\t});\n\t\t\t\tconst skillCompactList = formatCompactList(skills.map((skill) => skill.name));\n\t\t\t\taddLoadedSection(\"Skills\", skillCompactList, skillList);\n\t\t\t}\n\n\t\t\tif (templates.length > 0) {\n\t\t\t\tconst groups = buildScopeGroups(\n\t\t\t\t\ttemplates.map((template) => ({ path: template.filePath, sourceInfo: template.sourceInfo })),\n\t\t\t\t);\n\t\t\t\tconst templateByPath = new Map(templates.map((t) => [t.filePath, t]));\n\t\t\t\tconst templateList = formatScopeGroups(groups, {\n\t\t\t\t\tformatPath: (item) => {\n\t\t\t\t\t\tconst template = templateByPath.get(item.path);\n\t\t\t\t\t\treturn template ? `/${template.name}` : formatDisplayPath(item.path);\n\t\t\t\t\t},\n\t\t\t\t\tformatPackagePath: (item) => {\n\t\t\t\t\t\tconst template = templateByPath.get(item.path);\n\t\t\t\t\t\treturn template ? `/${template.name}` : formatDisplayPath(item.path);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tconst promptCompactList = formatCompactList(templates.map((template) => `/${template.name}`));\n\t\t\t\taddLoadedSection(\"Prompts\", promptCompactList, templateList);\n\t\t\t}\n\n\t\t\tif (extensions.length > 0) {\n\t\t\t\tconst groups = buildScopeGroups(extensions);\n\t\t\t\tconst extList = formatScopeGroups(groups, {\n\t\t\t\t\tformatPath: (item) => item.displayName ?? formatExtensionDisplayPath(item.path),\n\t\t\t\t\tformatPackagePath: (item) =>\n\t\t\t\t\t\titem.displayName ?? formatExtensionDisplayPath(getShortPath(item.path, item.sourceInfo)),\n\t\t\t\t});\n\t\t\t\tconst extensionCompactList = formatCompactList(getCompactExtensionLabels(extensions));\n\t\t\t\taddLoadedSection(\"Extensions\", extensionCompactList, extList, \"mdHeading\");\n\t\t\t}\n\n\t\t\tif (customThemes.length > 0) {\n\t\t\t\tconst groups = buildScopeGroups(\n\t\t\t\t\tcustomThemes.map((loadedTheme) => ({\n\t\t\t\t\t\tpath: loadedTheme.sourcePath!,\n\t\t\t\t\t\tsourceInfo: loadedTheme.sourceInfo,\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tconst themeList = formatScopeGroups(groups, {\n\t\t\t\t\tformatPath: (item) => formatDisplayPath(item.path),\n\t\t\t\t\tformatPackagePath: (item) => getShortPath(item.path, item.sourceInfo),\n\t\t\t\t});\n\t\t\t\tconst themeCompactList = formatCompactList(\n\t\t\t\t\tcustomThemes.map(\n\t\t\t\t\t\t(loadedTheme) =>\n\t\t\t\t\t\t\tloadedTheme.name ?? getCompactPathLabel(loadedTheme.sourcePath!, loadedTheme.sourceInfo),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\taddLoadedSection(\"Themes\", themeCompactList, themeList);\n\t\t\t}\n\t\t}\n\n\t\tif (contextWarnings.length > 0) {\n\t\t\tfor (const warning of contextWarnings) {\n\t\t\t\tchatContainer.addChild(new Text(theme.fg(\"warning\", warning), 0, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\tif (showDiagnostics) {\n\t\tconst skillDiagnostics = skillsResult.diagnostics;\n\t\tif (skillDiagnostics.length > 0) {\n\t\t\tconst warningLines = formatDiagnostics(skillDiagnostics, sourceInfos);\n\t\t\tchatContainer.addChild(new Text(`${theme.fg(\"warning\", \"[Skill conflicts]\")}\\n${warningLines}`, 0, 0));\n\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\tconst promptDiagnostics = promptsResult.diagnostics;\n\t\tif (promptDiagnostics.length > 0) {\n\t\t\tconst warningLines = formatDiagnostics(promptDiagnostics, sourceInfos);\n\t\t\tchatContainer.addChild(new Text(`${theme.fg(\"warning\", \"[Prompt conflicts]\")}\\n${warningLines}`, 0, 0));\n\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\tconst extensionDiagnostics: ResourceDiagnostic[] = [];\n\t\tconst extensionErrors = resourceLoader.getExtensions().errors;\n\t\tif (extensionErrors.length > 0) {\n\t\t\tfor (const error of extensionErrors) {\n\t\t\t\textensionDiagnostics.push({ type: \"error\", message: error.error, path: error.path });\n\t\t\t}\n\t\t}\n\n\t\tconst extensionRunner = deps.getExtensionRunner();\n\t\tconst commandDiagnostics = extensionRunner.getCommandDiagnostics();\n\t\textensionDiagnostics.push(...commandDiagnostics);\n\t\textensionDiagnostics.push(...deps.getBuiltInCommandConflictDiagnostics(extensionRunner));\n\n\t\tconst shortcutDiagnostics = extensionRunner.getShortcutDiagnostics();\n\t\textensionDiagnostics.push(...shortcutDiagnostics);\n\n\t\tif (extensionDiagnostics.length > 0) {\n\t\t\tconst warningLines = formatDiagnostics(extensionDiagnostics, sourceInfos);\n\t\t\tchatContainer.addChild(new Text(`${theme.fg(\"warning\", \"[Extension issues]\")}\\n${warningLines}`, 0, 0));\n\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\tconst themeDiagnostics = themesResult.diagnostics;\n\t\tif (themeDiagnostics.length > 0) {\n\t\t\tconst warningLines = formatDiagnostics(themeDiagnostics, sourceInfos);\n\t\t\tchatContainer.addChild(new Text(`${theme.fg(\"warning\", \"[Theme conflicts]\")}\\n${warningLines}`, 0, 0));\n\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Startup environment probes and the changelog-on-update lookup, shown as
3
+ * notices when the interactive mode starts. Extracted from interactive-mode.ts.
4
+ */
5
+ import type { SettingsManager } from "../../core/settings-manager.js";
6
+ export declare function checkForPackageUpdates(cwd: string, settingsManager: SettingsManager): Promise<string[]>;
7
+ export declare function checkTmuxKeyboardSetup(): Promise<string | undefined>;
8
+ /**
9
+ * Get changelog entries to display on startup.
10
+ * Only shows new entries since last seen version, skips for resumed sessions.
11
+ */
12
+ export declare function getChangelogForDisplay(options: {
13
+ /** True for resumed/continued sessions (which already have messages). */
14
+ hasMessages: boolean;
15
+ settingsManager: SettingsManager;
16
+ }): string | undefined;
17
+ //# sourceMappingURL=startup-checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup-checks.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/startup-checks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgB7G;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA6C1E;AAMD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE;IAC/C,yEAAyE;IACzE,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,eAAe,CAAC;CACjC,GAAG,MAAM,GAAG,SAAS,CA+BrB","sourcesContent":["/**\n * Startup environment probes and the changelog-on-update lookup, shown as\n * notices when the interactive mode starts. Extracted from interactive-mode.ts.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { APP_NAME, getAgentDir, VERSION } from \"../../config.js\";\nimport { DefaultPackageManager } from \"../../core/package-manager.js\";\nimport type { SettingsManager } from \"../../core/settings-manager.js\";\nimport { getChangelogPath, getNewEntries, parseChangelog } from \"../../utils/changelog.js\";\n\nexport async function checkForPackageUpdates(cwd: string, settingsManager: SettingsManager): Promise<string[]> {\n\tif (process.env.HOOCODE_OFFLINE) {\n\t\treturn [];\n\t}\n\n\ttry {\n\t\tconst packageManager = new DefaultPackageManager({\n\t\t\tcwd,\n\t\t\tagentDir: getAgentDir(),\n\t\t\tsettingsManager,\n\t\t});\n\t\tconst updates = await packageManager.checkForAvailableUpdates();\n\t\treturn updates.map((update) => update.displayName);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nexport async function checkTmuxKeyboardSetup(): Promise<string | undefined> {\n\tif (!process.env.TMUX) return undefined;\n\n\tconst runTmuxShow = (option: string): Promise<string | undefined> => {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst proc = spawn(\"tmux\", [\"show\", \"-gv\", option], {\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t});\n\t\t\tlet stdout = \"\";\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tproc.kill();\n\t\t\t\tresolve(undefined);\n\t\t\t}, 2000);\n\n\t\t\tproc.stdout?.on(\"data\", (data) => {\n\t\t\t\tstdout += data.toString();\n\t\t\t});\n\t\t\tproc.on(\"error\", () => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(undefined);\n\t\t\t});\n\t\t\tproc.on(\"close\", (code) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(code === 0 ? stdout.trim() : undefined);\n\t\t\t});\n\t\t});\n\t};\n\n\tconst [extendedKeys, extendedKeysFormat] = await Promise.all([\n\t\trunTmuxShow(\"extended-keys\"),\n\t\trunTmuxShow(\"extended-keys-format\"),\n\t]);\n\n\t// If we couldn't query tmux (timeout, sandbox, etc.), don't warn\n\tif (extendedKeys === undefined) return undefined;\n\n\tif (extendedKeys !== \"on\" && extendedKeys !== \"always\") {\n\t\treturn \"tmux extended-keys is off. Modified Enter keys may not work. Add `set -g extended-keys on` to ~/.tmux.conf and restart tmux.\";\n\t}\n\n\tif (extendedKeysFormat === \"xterm\") {\n\t\treturn `tmux extended-keys-format is xterm. ${APP_NAME} works best with csi-u. Add \\`set -g extended-keys-format csi-u\\` to ~/.tmux.conf and restart tmux.`;\n\t}\n\n\treturn undefined;\n}\n\nfunction reportInstallTelemetry(_version: string): void {\n\t// Disabled in HooCode fork: this is forked from pi (upstream pi.dev install-telemetry endpoint is not run by this fork).\n}\n\n/**\n * Get changelog entries to display on startup.\n * Only shows new entries since last seen version, skips for resumed sessions.\n */\nexport function getChangelogForDisplay(options: {\n\t/** True for resumed/continued sessions (which already have messages). */\n\thasMessages: boolean;\n\tsettingsManager: SettingsManager;\n}): string | undefined {\n\t// Skip changelog for resumed/continued sessions (already have messages)\n\tif (options.hasMessages) {\n\t\treturn undefined;\n\t}\n\n\tconst settingsManager = options.settingsManager;\n\tconst lastVersion = settingsManager.getLastChangelogVersion();\n\tconst changelogPath = getChangelogPath();\n\tconst entries = parseChangelog(changelogPath);\n\n\tif (!lastVersion) {\n\t\t// Fresh install - record the latest entry's version (not VERSION, which may\n\t\t// overshoot the latest entry and silently swallow it once it appears).\n\t\t// Fall back to VERSION only if no entries exist yet.\n\t\tconst seedVersion = entries.length > 0 ? `${entries[0].major}.${entries[0].minor}.${entries[0].patch}` : VERSION;\n\t\tsettingsManager.setLastChangelogVersion(seedVersion);\n\t\treportInstallTelemetry(seedVersion);\n\t\treturn undefined;\n\t}\n\n\tconst newEntries = getNewEntries(entries, lastVersion);\n\tif (newEntries.length > 0) {\n\t\tconst latest = newEntries[0];\n\t\tconst latestVersion = `${latest.major}.${latest.minor}.${latest.patch}`;\n\t\tsettingsManager.setLastChangelogVersion(latestVersion);\n\t\treportInstallTelemetry(latestVersion);\n\t\treturn newEntries.map((e) => e.content).join(\"\\n\\n\");\n\t}\n\n\treturn undefined;\n}\n"]}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Startup environment probes and the changelog-on-update lookup, shown as
3
+ * notices when the interactive mode starts. Extracted from interactive-mode.ts.
4
+ */
5
+ import { spawn } from "node:child_process";
6
+ import { APP_NAME, getAgentDir, VERSION } from "../../config.js";
7
+ import { DefaultPackageManager } from "../../core/package-manager.js";
8
+ import { getChangelogPath, getNewEntries, parseChangelog } from "../../utils/changelog.js";
9
+ export async function checkForPackageUpdates(cwd, settingsManager) {
10
+ if (process.env.HOOCODE_OFFLINE) {
11
+ return [];
12
+ }
13
+ try {
14
+ const packageManager = new DefaultPackageManager({
15
+ cwd,
16
+ agentDir: getAgentDir(),
17
+ settingsManager,
18
+ });
19
+ const updates = await packageManager.checkForAvailableUpdates();
20
+ return updates.map((update) => update.displayName);
21
+ }
22
+ catch {
23
+ return [];
24
+ }
25
+ }
26
+ export async function checkTmuxKeyboardSetup() {
27
+ if (!process.env.TMUX)
28
+ return undefined;
29
+ const runTmuxShow = (option) => {
30
+ return new Promise((resolve) => {
31
+ const proc = spawn("tmux", ["show", "-gv", option], {
32
+ stdio: ["ignore", "pipe", "ignore"],
33
+ });
34
+ let stdout = "";
35
+ const timer = setTimeout(() => {
36
+ proc.kill();
37
+ resolve(undefined);
38
+ }, 2000);
39
+ proc.stdout?.on("data", (data) => {
40
+ stdout += data.toString();
41
+ });
42
+ proc.on("error", () => {
43
+ clearTimeout(timer);
44
+ resolve(undefined);
45
+ });
46
+ proc.on("close", (code) => {
47
+ clearTimeout(timer);
48
+ resolve(code === 0 ? stdout.trim() : undefined);
49
+ });
50
+ });
51
+ };
52
+ const [extendedKeys, extendedKeysFormat] = await Promise.all([
53
+ runTmuxShow("extended-keys"),
54
+ runTmuxShow("extended-keys-format"),
55
+ ]);
56
+ // If we couldn't query tmux (timeout, sandbox, etc.), don't warn
57
+ if (extendedKeys === undefined)
58
+ return undefined;
59
+ if (extendedKeys !== "on" && extendedKeys !== "always") {
60
+ return "tmux extended-keys is off. Modified Enter keys may not work. Add `set -g extended-keys on` to ~/.tmux.conf and restart tmux.";
61
+ }
62
+ if (extendedKeysFormat === "xterm") {
63
+ return `tmux extended-keys-format is xterm. ${APP_NAME} works best with csi-u. Add \`set -g extended-keys-format csi-u\` to ~/.tmux.conf and restart tmux.`;
64
+ }
65
+ return undefined;
66
+ }
67
+ function reportInstallTelemetry(_version) {
68
+ // Disabled in HooCode fork: this is forked from pi (upstream pi.dev install-telemetry endpoint is not run by this fork).
69
+ }
70
+ /**
71
+ * Get changelog entries to display on startup.
72
+ * Only shows new entries since last seen version, skips for resumed sessions.
73
+ */
74
+ export function getChangelogForDisplay(options) {
75
+ // Skip changelog for resumed/continued sessions (already have messages)
76
+ if (options.hasMessages) {
77
+ return undefined;
78
+ }
79
+ const settingsManager = options.settingsManager;
80
+ const lastVersion = settingsManager.getLastChangelogVersion();
81
+ const changelogPath = getChangelogPath();
82
+ const entries = parseChangelog(changelogPath);
83
+ if (!lastVersion) {
84
+ // Fresh install - record the latest entry's version (not VERSION, which may
85
+ // overshoot the latest entry and silently swallow it once it appears).
86
+ // Fall back to VERSION only if no entries exist yet.
87
+ const seedVersion = entries.length > 0 ? `${entries[0].major}.${entries[0].minor}.${entries[0].patch}` : VERSION;
88
+ settingsManager.setLastChangelogVersion(seedVersion);
89
+ reportInstallTelemetry(seedVersion);
90
+ return undefined;
91
+ }
92
+ const newEntries = getNewEntries(entries, lastVersion);
93
+ if (newEntries.length > 0) {
94
+ const latest = newEntries[0];
95
+ const latestVersion = `${latest.major}.${latest.minor}.${latest.patch}`;
96
+ settingsManager.setLastChangelogVersion(latestVersion);
97
+ reportInstallTelemetry(latestVersion);
98
+ return newEntries.map((e) => e.content).join("\n\n");
99
+ }
100
+ return undefined;
101
+ }
102
+ //# sourceMappingURL=startup-checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup-checks.js","sourceRoot":"","sources":["../../../src/modes/interactive/startup-checks.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Startup environment probes and the changelog-on-update lookup, shown as\n * notices when the interactive mode starts. Extracted from interactive-mode.ts.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { APP_NAME, getAgentDir, VERSION } from \"../../config.js\";\nimport { DefaultPackageManager } from \"../../core/package-manager.js\";\nimport type { SettingsManager } from \"../../core/settings-manager.js\";\nimport { getChangelogPath, getNewEntries, parseChangelog } from \"../../utils/changelog.js\";\n\nexport async function checkForPackageUpdates(cwd: string, settingsManager: SettingsManager): Promise<string[]> {\n\tif (process.env.HOOCODE_OFFLINE) {\n\t\treturn [];\n\t}\n\n\ttry {\n\t\tconst packageManager = new DefaultPackageManager({\n\t\t\tcwd,\n\t\t\tagentDir: getAgentDir(),\n\t\t\tsettingsManager,\n\t\t});\n\t\tconst updates = await packageManager.checkForAvailableUpdates();\n\t\treturn updates.map((update) => update.displayName);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nexport async function checkTmuxKeyboardSetup(): Promise<string | undefined> {\n\tif (!process.env.TMUX) return undefined;\n\n\tconst runTmuxShow = (option: string): Promise<string | undefined> => {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst proc = spawn(\"tmux\", [\"show\", \"-gv\", option], {\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t});\n\t\t\tlet stdout = \"\";\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tproc.kill();\n\t\t\t\tresolve(undefined);\n\t\t\t}, 2000);\n\n\t\t\tproc.stdout?.on(\"data\", (data) => {\n\t\t\t\tstdout += data.toString();\n\t\t\t});\n\t\t\tproc.on(\"error\", () => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(undefined);\n\t\t\t});\n\t\t\tproc.on(\"close\", (code) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(code === 0 ? stdout.trim() : undefined);\n\t\t\t});\n\t\t});\n\t};\n\n\tconst [extendedKeys, extendedKeysFormat] = await Promise.all([\n\t\trunTmuxShow(\"extended-keys\"),\n\t\trunTmuxShow(\"extended-keys-format\"),\n\t]);\n\n\t// If we couldn't query tmux (timeout, sandbox, etc.), don't warn\n\tif (extendedKeys === undefined) return undefined;\n\n\tif (extendedKeys !== \"on\" && extendedKeys !== \"always\") {\n\t\treturn \"tmux extended-keys is off. Modified Enter keys may not work. Add `set -g extended-keys on` to ~/.tmux.conf and restart tmux.\";\n\t}\n\n\tif (extendedKeysFormat === \"xterm\") {\n\t\treturn `tmux extended-keys-format is xterm. ${APP_NAME} works best with csi-u. Add \\`set -g extended-keys-format csi-u\\` to ~/.tmux.conf and restart tmux.`;\n\t}\n\n\treturn undefined;\n}\n\nfunction reportInstallTelemetry(_version: string): void {\n\t// Disabled in HooCode fork: this is forked from pi (upstream pi.dev install-telemetry endpoint is not run by this fork).\n}\n\n/**\n * Get changelog entries to display on startup.\n * Only shows new entries since last seen version, skips for resumed sessions.\n */\nexport function getChangelogForDisplay(options: {\n\t/** True for resumed/continued sessions (which already have messages). */\n\thasMessages: boolean;\n\tsettingsManager: SettingsManager;\n}): string | undefined {\n\t// Skip changelog for resumed/continued sessions (already have messages)\n\tif (options.hasMessages) {\n\t\treturn undefined;\n\t}\n\n\tconst settingsManager = options.settingsManager;\n\tconst lastVersion = settingsManager.getLastChangelogVersion();\n\tconst changelogPath = getChangelogPath();\n\tconst entries = parseChangelog(changelogPath);\n\n\tif (!lastVersion) {\n\t\t// Fresh install - record the latest entry's version (not VERSION, which may\n\t\t// overshoot the latest entry and silently swallow it once it appears).\n\t\t// Fall back to VERSION only if no entries exist yet.\n\t\tconst seedVersion = entries.length > 0 ? `${entries[0].major}.${entries[0].minor}.${entries[0].patch}` : VERSION;\n\t\tsettingsManager.setLastChangelogVersion(seedVersion);\n\t\treportInstallTelemetry(seedVersion);\n\t\treturn undefined;\n\t}\n\n\tconst newEntries = getNewEntries(entries, lastVersion);\n\tif (newEntries.length > 0) {\n\t\tconst latest = newEntries[0];\n\t\tconst latestVersion = `${latest.major}.${latest.minor}.${latest.patch}`;\n\t\tsettingsManager.setLastChangelogVersion(latestVersion);\n\t\treportInstallTelemetry(latestVersion);\n\t\treturn newEntries.map((e) => e.content).join(\"\\n\\n\");\n\t}\n\n\treturn undefined;\n}\n"]}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * hoocode team focus (--team): focus role rows, nudge, attach.
3
+ *
4
+ * Wires a hooteams connection into the TUI: team focus (app.team.focus),
5
+ * nudging (n), the attach side panel (a) on the task panel's teams view, and
6
+ * approval gates. task_paused events (and gates already pending on the server)
7
+ * surface inline in the attach panel when it shows the paused role, otherwise
8
+ * in the options pane; the answer goes back over POST /tasks/:id/resume.
9
+ */
10
+ import type { Component, Container, TUI } from "@kolisachint/hoocode-tui";
11
+ import type { AskQuestion, ExtensionUIDialogOptions } from "../../core/extensions/index.js";
12
+ import type { TeamViewConnection } from "../../core/team-view.js";
13
+ import type { TaskPanelComponent } from "./components/task-panel.js";
14
+ /** The slice of the interactive mode the team feature needs. */
15
+ export interface TeamFocusDeps {
16
+ ui: TUI;
17
+ taskPanel: TaskPanelComponent;
18
+ editorContainer: Container;
19
+ /** The prompt editor (read at call time; the editor can be swapped). */
20
+ getEditor(): Component;
21
+ showStatus(message: string): void;
22
+ showWarning(message: string): void;
23
+ showAskOptions(questions: AskQuestion[], opts?: ExtensionUIDialogOptions): Promise<string[] | undefined>;
24
+ /** True while another ask-options pane is on screen. */
25
+ isAskOptionsOpen(): boolean;
26
+ }
27
+ export declare class TeamFocusController {
28
+ private readonly deps;
29
+ private client;
30
+ private attachPanel;
31
+ private attachHandle;
32
+ constructor(deps: TeamFocusDeps);
33
+ /** True once a team client has been attached (--team). */
34
+ get connected(): boolean;
35
+ /**
36
+ * Wire a hooteams connection into the TUI. Called by main.ts when `--team`
37
+ * is set, before run().
38
+ */
39
+ attachClient(client: TeamViewConnection): void;
40
+ private presentApproval;
41
+ /** Move keyboard focus to the task panel's team roster. */
42
+ enterFocus(): void;
43
+ /** Leave team focus: detach any side panel and return focus to the editor. */
44
+ exitFocus(): void;
45
+ /**
46
+ * Inline nudge editor for a role (n in team focus or while attached).
47
+ * Swaps the prompt editor for a one-line input; submit fires POST /steer in
48
+ * the background (the REPL and team focus are never blocked on the network).
49
+ */
50
+ showNudgeInput(role: string): void;
51
+ /** Open the attach side panel for a role (a in team focus). */
52
+ showAttach(role: string): void;
53
+ /** Detach the side panel; the role keeps running. Safe to call when closed. */
54
+ closeAttach(): void;
55
+ }
56
+ //# sourceMappingURL=team-focus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-focus.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/team-focus.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAiB,GAAG,EAAE,MAAM,0BAA0B,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAG5F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGrE,gEAAgE;AAChE,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,GAAG,CAAC;IACR,SAAS,EAAE,kBAAkB,CAAC;IAC9B,eAAe,EAAE,SAAS,CAAC;IAC3B,wEAAwE;IACxE,SAAS,IAAI,SAAS,CAAC;IACvB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,cAAc,CAAC,SAAS,EAAE,WAAW,EAAE,EAAE,IAAI,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACzG,wDAAwD;IACxD,gBAAgB,IAAI,OAAO,CAAC;CAC5B;AAED,qBAAa,mBAAmB;IAKnB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJjC,OAAO,CAAC,MAAM,CAA6C;IAC3D,OAAO,CAAC,WAAW,CAAmD;IACtE,OAAO,CAAC,YAAY,CAAwC;IAE5D,YAA6B,IAAI,EAAE,aAAa,EAAI;IAEpD,0DAA0D;IAC1D,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAkB7C;YAUa,eAAe;IA6B7B,2DAA2D;IAC3D,UAAU,IAAI,IAAI,CAYjB;IAED,8EAA8E;IAC9E,SAAS,IAAI,IAAI,CAIhB;IAED;;;;OAIG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAsCjC;IAED,+DAA+D;IAC/D,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAuB7B;IAED,+EAA+E;IAC/E,WAAW,IAAI,IAAI,CAKlB;CACD","sourcesContent":["/**\n * hoocode team focus (--team): focus role rows, nudge, attach.\n *\n * Wires a hooteams connection into the TUI: team focus (app.team.focus),\n * nudging (n), the attach side panel (a) on the task panel's teams view, and\n * approval gates. task_paused events (and gates already pending on the server)\n * surface inline in the attach panel when it shows the paused role, otherwise\n * in the options pane; the answer goes back over POST /tasks/:id/resume.\n */\n\nimport type { Component, Container, OverlayHandle, TUI } from \"@kolisachint/hoocode-tui\";\nimport type { AskQuestion, ExtensionUIDialogOptions } from \"../../core/extensions/index.js\";\nimport { taskStore } from \"../../core/task-store.js\";\nimport { type TeamApproval, TeamApprovalCoordinator } from \"../../core/team-approvals.js\";\nimport type { TeamViewConnection } from \"../../core/team-view.js\";\nimport { ExtensionInputComponent } from \"./components/extension-input.js\";\nimport type { TaskPanelComponent } from \"./components/task-panel.js\";\nimport { TeamAttachPanelComponent } from \"./components/team-attach-panel.js\";\n\n/** The slice of the interactive mode the team feature needs. */\nexport interface TeamFocusDeps {\n\tui: TUI;\n\ttaskPanel: TaskPanelComponent;\n\teditorContainer: Container;\n\t/** The prompt editor (read at call time; the editor can be swapped). */\n\tgetEditor(): Component;\n\tshowStatus(message: string): void;\n\tshowWarning(message: string): void;\n\tshowAskOptions(questions: AskQuestion[], opts?: ExtensionUIDialogOptions): Promise<string[] | undefined>;\n\t/** True while another ask-options pane is on screen. */\n\tisAskOptionsOpen(): boolean;\n}\n\nexport class TeamFocusController {\n\tprivate client: TeamViewConnection | undefined = undefined;\n\tprivate attachPanel: TeamAttachPanelComponent | undefined = undefined;\n\tprivate attachHandle: OverlayHandle | undefined = undefined;\n\n\tconstructor(private readonly deps: TeamFocusDeps) {}\n\n\t/** True once a team client has been attached (--team). */\n\tget connected(): boolean {\n\t\treturn this.client !== undefined;\n\t}\n\n\t/**\n\t * Wire a hooteams connection into the TUI. Called by main.ts when `--team`\n\t * is set, before run().\n\t */\n\tattachClient(client: TeamViewConnection): void {\n\t\tthis.client = client;\n\t\tconst approvals = new TeamApprovalCoordinator({\n\t\t\tpresent: (approval, signal) => this.presentApproval(approval, signal),\n\t\t\tresume: (taskId, option) => client.resume(taskId, option),\n\t\t\tinfo: (message) => this.deps.showStatus(message),\n\t\t\twarn: (message) => this.deps.showWarning(message),\n\t\t});\n\t\tclient.subscribe((event) => approvals.handleEvent(event));\n\t\t// Gates that opened before we attached don't replay as task_paused.\n\t\tvoid client.pendingApprovals().then(\n\t\t\t(pending) => {\n\t\t\t\tfor (const gate of pending) approvals.enqueuePending(gate);\n\t\t\t},\n\t\t\t() => {\n\t\t\t\t// Best-effort like the rest of the bridge; live gates still arrive via SSE.\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Show one team approval gate and resolve with the chosen (or free-form)\n\t * answer, undefined when skipped. When the attach side panel is open on the\n\t * role that paused, the gate renders inline in the panel — right where its\n\t * stream stopped; otherwise it goes to the options pane, waiting politely\n\t * while another ask is on screen. Either way the signal (gate answered\n\t * elsewhere) dismisses the prompt.\n\t */\n\tprivate async presentApproval(approval: TeamApproval, signal: AbortSignal): Promise<string | undefined> {\n\t\tconst panel = this.attachPanel;\n\t\tif (panel && approval.role === panel.role) {\n\t\t\tthis.attachHandle?.focus();\n\t\t\tconst answer = await panel.presentApproval(approval, signal);\n\t\t\t// Detaching mid-gate settles as skipped — fall through to the options\n\t\t\t// pane so the question isn't silently lost. A skip with the panel\n\t\t\t// still open is a real skip.\n\t\t\tif (answer !== undefined || signal.aborted || this.attachPanel === panel) return answer;\n\t\t}\n\t\twhile (this.deps.isAskOptionsOpen() && !signal.aborted) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 200));\n\t\t}\n\t\tif (signal.aborted) return undefined;\n\t\tconst answers = await this.deps.showAskOptions(\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tquestion: approval.question,\n\t\t\t\t\tshort: approval.taskId,\n\t\t\t\t\tdetail: `team task \"${approval.taskId}\"${approval.role ? ` (${approval.role})` : \"\"} is paused until answered`,\n\t\t\t\t\toptions: approval.options.map((label) => ({ label })),\n\t\t\t\t\tallowCustom: true,\n\t\t\t\t},\n\t\t\t],\n\t\t\t{ signal },\n\t\t);\n\t\treturn answers?.[0];\n\t}\n\n\t/** Move keyboard focus to the task panel's team roster. */\n\tenterFocus(): void {\n\t\tif (!this.client) {\n\t\t\tthis.deps.showStatus(\"No team connected. Start with --team <url> to mirror a hooteams server.\");\n\t\t\treturn;\n\t\t}\n\t\tif (!taskStore.agents().some((a) => a.kind === \"role\")) {\n\t\t\tthis.deps.showStatus(\"Team roster is empty — waiting for roles from the team server.\");\n\t\t\treturn;\n\t\t}\n\t\tthis.deps.taskPanel.setView(\"teams\");\n\t\tthis.deps.ui.setFocus(this.deps.taskPanel);\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\t/** Leave team focus: detach any side panel and return focus to the editor. */\n\texitFocus(): void {\n\t\tthis.closeAttach();\n\t\tthis.deps.ui.setFocus(this.deps.getEditor());\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\t/**\n\t * Inline nudge editor for a role (n in team focus or while attached).\n\t * Swaps the prompt editor for a one-line input; submit fires POST /steer in\n\t * the background (the REPL and team focus are never blocked on the network).\n\t */\n\tshowNudgeInput(role: string): void {\n\t\tconst client = this.client;\n\t\tif (!client) return;\n\n\t\tconst restoreFocus = () => {\n\t\t\tthis.deps.editorContainer.clear();\n\t\t\tthis.deps.editorContainer.addChild(this.deps.getEditor());\n\t\t\t// Return focus where the nudge came from: the attach panel if one is\n\t\t\t// open, otherwise the team roster.\n\t\t\tif (this.attachHandle) this.attachHandle.focus();\n\t\t\telse this.deps.ui.setFocus(this.deps.taskPanel);\n\t\t\tthis.deps.ui.requestRender();\n\t\t};\n\n\t\tconst input = new ExtensionInputComponent(\n\t\t\t`Nudge ${role}`,\n\t\t\tundefined,\n\t\t\t(value) => {\n\t\t\t\tinput.dispose();\n\t\t\t\trestoreFocus();\n\t\t\t\tconst message = value.trim();\n\t\t\t\tif (!message) return;\n\t\t\t\tvoid client.steer(role, message).then(\n\t\t\t\t\t() => this.deps.showStatus(`Nudged ${role}`),\n\t\t\t\t\t(error) => this.deps.showWarning(`Failed to nudge ${role}: ${String(error)}`),\n\t\t\t\t);\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tinput.dispose();\n\t\t\t\trestoreFocus();\n\t\t\t},\n\t\t\t{ tui: this.deps.ui },\n\t\t);\n\n\t\tthis.deps.editorContainer.clear();\n\t\tthis.deps.editorContainer.addChild(input);\n\t\tthis.deps.ui.setFocus(input);\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\t/** Open the attach side panel for a role (a in team focus). */\n\tshowAttach(role: string): void {\n\t\tconst client = this.client;\n\t\tif (!client) return;\n\t\t// One attached role at a time: re-attaching swaps the panel.\n\t\tthis.closeAttach();\n\t\tconst panel = new TeamAttachPanelComponent(\n\t\t\trole,\n\t\t\tclient,\n\t\t\t{\n\t\t\t\tonDetach: () => this.closeAttach(),\n\t\t\t\tonNudge: (attachedRole) => this.showNudgeInput(attachedRole),\n\t\t\t},\n\t\t\tthis.deps.ui,\n\t\t);\n\t\tthis.attachPanel = panel;\n\t\t// preFocus is the task panel (attach is triggered from team focus), so\n\t\t// hiding the overlay drops the user back on the role roster.\n\t\tthis.attachHandle = this.deps.ui.showOverlay(panel, {\n\t\t\tanchor: \"top-right\",\n\t\t\twidth: \"45%\",\n\t\t\tminWidth: 36,\n\t\t\tmargin: { top: 1, right: 1 },\n\t\t});\n\t}\n\n\t/** Detach the side panel; the role keeps running. Safe to call when closed. */\n\tcloseAttach(): void {\n\t\tthis.attachPanel?.dispose();\n\t\tthis.attachHandle?.hide();\n\t\tthis.attachPanel = undefined;\n\t\tthis.attachHandle = undefined;\n\t}\n}\n"]}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * hoocode team focus (--team): focus role rows, nudge, attach.
3
+ *
4
+ * Wires a hooteams connection into the TUI: team focus (app.team.focus),
5
+ * nudging (n), the attach side panel (a) on the task panel's teams view, and
6
+ * approval gates. task_paused events (and gates already pending on the server)
7
+ * surface inline in the attach panel when it shows the paused role, otherwise
8
+ * in the options pane; the answer goes back over POST /tasks/:id/resume.
9
+ */
10
+ import { taskStore } from "../../core/task-store.js";
11
+ import { TeamApprovalCoordinator } from "../../core/team-approvals.js";
12
+ import { ExtensionInputComponent } from "./components/extension-input.js";
13
+ import { TeamAttachPanelComponent } from "./components/team-attach-panel.js";
14
+ export class TeamFocusController {
15
+ deps;
16
+ client = undefined;
17
+ attachPanel = undefined;
18
+ attachHandle = undefined;
19
+ constructor(deps) {
20
+ this.deps = deps;
21
+ }
22
+ /** True once a team client has been attached (--team). */
23
+ get connected() {
24
+ return this.client !== undefined;
25
+ }
26
+ /**
27
+ * Wire a hooteams connection into the TUI. Called by main.ts when `--team`
28
+ * is set, before run().
29
+ */
30
+ attachClient(client) {
31
+ this.client = client;
32
+ const approvals = new TeamApprovalCoordinator({
33
+ present: (approval, signal) => this.presentApproval(approval, signal),
34
+ resume: (taskId, option) => client.resume(taskId, option),
35
+ info: (message) => this.deps.showStatus(message),
36
+ warn: (message) => this.deps.showWarning(message),
37
+ });
38
+ client.subscribe((event) => approvals.handleEvent(event));
39
+ // Gates that opened before we attached don't replay as task_paused.
40
+ void client.pendingApprovals().then((pending) => {
41
+ for (const gate of pending)
42
+ approvals.enqueuePending(gate);
43
+ }, () => {
44
+ // Best-effort like the rest of the bridge; live gates still arrive via SSE.
45
+ });
46
+ }
47
+ /**
48
+ * Show one team approval gate and resolve with the chosen (or free-form)
49
+ * answer, undefined when skipped. When the attach side panel is open on the
50
+ * role that paused, the gate renders inline in the panel — right where its
51
+ * stream stopped; otherwise it goes to the options pane, waiting politely
52
+ * while another ask is on screen. Either way the signal (gate answered
53
+ * elsewhere) dismisses the prompt.
54
+ */
55
+ async presentApproval(approval, signal) {
56
+ const panel = this.attachPanel;
57
+ if (panel && approval.role === panel.role) {
58
+ this.attachHandle?.focus();
59
+ const answer = await panel.presentApproval(approval, signal);
60
+ // Detaching mid-gate settles as skipped — fall through to the options
61
+ // pane so the question isn't silently lost. A skip with the panel
62
+ // still open is a real skip.
63
+ if (answer !== undefined || signal.aborted || this.attachPanel === panel)
64
+ return answer;
65
+ }
66
+ while (this.deps.isAskOptionsOpen() && !signal.aborted) {
67
+ await new Promise((resolve) => setTimeout(resolve, 200));
68
+ }
69
+ if (signal.aborted)
70
+ return undefined;
71
+ const answers = await this.deps.showAskOptions([
72
+ {
73
+ question: approval.question,
74
+ short: approval.taskId,
75
+ detail: `team task "${approval.taskId}"${approval.role ? ` (${approval.role})` : ""} is paused until answered`,
76
+ options: approval.options.map((label) => ({ label })),
77
+ allowCustom: true,
78
+ },
79
+ ], { signal });
80
+ return answers?.[0];
81
+ }
82
+ /** Move keyboard focus to the task panel's team roster. */
83
+ enterFocus() {
84
+ if (!this.client) {
85
+ this.deps.showStatus("No team connected. Start with --team <url> to mirror a hooteams server.");
86
+ return;
87
+ }
88
+ if (!taskStore.agents().some((a) => a.kind === "role")) {
89
+ this.deps.showStatus("Team roster is empty — waiting for roles from the team server.");
90
+ return;
91
+ }
92
+ this.deps.taskPanel.setView("teams");
93
+ this.deps.ui.setFocus(this.deps.taskPanel);
94
+ this.deps.ui.requestRender();
95
+ }
96
+ /** Leave team focus: detach any side panel and return focus to the editor. */
97
+ exitFocus() {
98
+ this.closeAttach();
99
+ this.deps.ui.setFocus(this.deps.getEditor());
100
+ this.deps.ui.requestRender();
101
+ }
102
+ /**
103
+ * Inline nudge editor for a role (n in team focus or while attached).
104
+ * Swaps the prompt editor for a one-line input; submit fires POST /steer in
105
+ * the background (the REPL and team focus are never blocked on the network).
106
+ */
107
+ showNudgeInput(role) {
108
+ const client = this.client;
109
+ if (!client)
110
+ return;
111
+ const restoreFocus = () => {
112
+ this.deps.editorContainer.clear();
113
+ this.deps.editorContainer.addChild(this.deps.getEditor());
114
+ // Return focus where the nudge came from: the attach panel if one is
115
+ // open, otherwise the team roster.
116
+ if (this.attachHandle)
117
+ this.attachHandle.focus();
118
+ else
119
+ this.deps.ui.setFocus(this.deps.taskPanel);
120
+ this.deps.ui.requestRender();
121
+ };
122
+ const input = new ExtensionInputComponent(`Nudge ${role}`, undefined, (value) => {
123
+ input.dispose();
124
+ restoreFocus();
125
+ const message = value.trim();
126
+ if (!message)
127
+ return;
128
+ void client.steer(role, message).then(() => this.deps.showStatus(`Nudged ${role}`), (error) => this.deps.showWarning(`Failed to nudge ${role}: ${String(error)}`));
129
+ }, () => {
130
+ input.dispose();
131
+ restoreFocus();
132
+ }, { tui: this.deps.ui });
133
+ this.deps.editorContainer.clear();
134
+ this.deps.editorContainer.addChild(input);
135
+ this.deps.ui.setFocus(input);
136
+ this.deps.ui.requestRender();
137
+ }
138
+ /** Open the attach side panel for a role (a in team focus). */
139
+ showAttach(role) {
140
+ const client = this.client;
141
+ if (!client)
142
+ return;
143
+ // One attached role at a time: re-attaching swaps the panel.
144
+ this.closeAttach();
145
+ const panel = new TeamAttachPanelComponent(role, client, {
146
+ onDetach: () => this.closeAttach(),
147
+ onNudge: (attachedRole) => this.showNudgeInput(attachedRole),
148
+ }, this.deps.ui);
149
+ this.attachPanel = panel;
150
+ // preFocus is the task panel (attach is triggered from team focus), so
151
+ // hiding the overlay drops the user back on the role roster.
152
+ this.attachHandle = this.deps.ui.showOverlay(panel, {
153
+ anchor: "top-right",
154
+ width: "45%",
155
+ minWidth: 36,
156
+ margin: { top: 1, right: 1 },
157
+ });
158
+ }
159
+ /** Detach the side panel; the role keeps running. Safe to call when closed. */
160
+ closeAttach() {
161
+ this.attachPanel?.dispose();
162
+ this.attachHandle?.hide();
163
+ this.attachPanel = undefined;
164
+ this.attachHandle = undefined;
165
+ }
166
+ }
167
+ //# sourceMappingURL=team-focus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-focus.js","sourceRoot":"","sources":["../../../src/modes/interactive/team-focus.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * hoocode team focus (--team): focus role rows, nudge, attach.\n *\n * Wires a hooteams connection into the TUI: team focus (app.team.focus),\n * nudging (n), the attach side panel (a) on the task panel's teams view, and\n * approval gates. task_paused events (and gates already pending on the server)\n * surface inline in the attach panel when it shows the paused role, otherwise\n * in the options pane; the answer goes back over POST /tasks/:id/resume.\n */\n\nimport type { Component, Container, OverlayHandle, TUI } from \"@kolisachint/hoocode-tui\";\nimport type { AskQuestion, ExtensionUIDialogOptions } from \"../../core/extensions/index.js\";\nimport { taskStore } from \"../../core/task-store.js\";\nimport { type TeamApproval, TeamApprovalCoordinator } from \"../../core/team-approvals.js\";\nimport type { TeamViewConnection } from \"../../core/team-view.js\";\nimport { ExtensionInputComponent } from \"./components/extension-input.js\";\nimport type { TaskPanelComponent } from \"./components/task-panel.js\";\nimport { TeamAttachPanelComponent } from \"./components/team-attach-panel.js\";\n\n/** The slice of the interactive mode the team feature needs. */\nexport interface TeamFocusDeps {\n\tui: TUI;\n\ttaskPanel: TaskPanelComponent;\n\teditorContainer: Container;\n\t/** The prompt editor (read at call time; the editor can be swapped). */\n\tgetEditor(): Component;\n\tshowStatus(message: string): void;\n\tshowWarning(message: string): void;\n\tshowAskOptions(questions: AskQuestion[], opts?: ExtensionUIDialogOptions): Promise<string[] | undefined>;\n\t/** True while another ask-options pane is on screen. */\n\tisAskOptionsOpen(): boolean;\n}\n\nexport class TeamFocusController {\n\tprivate client: TeamViewConnection | undefined = undefined;\n\tprivate attachPanel: TeamAttachPanelComponent | undefined = undefined;\n\tprivate attachHandle: OverlayHandle | undefined = undefined;\n\n\tconstructor(private readonly deps: TeamFocusDeps) {}\n\n\t/** True once a team client has been attached (--team). */\n\tget connected(): boolean {\n\t\treturn this.client !== undefined;\n\t}\n\n\t/**\n\t * Wire a hooteams connection into the TUI. Called by main.ts when `--team`\n\t * is set, before run().\n\t */\n\tattachClient(client: TeamViewConnection): void {\n\t\tthis.client = client;\n\t\tconst approvals = new TeamApprovalCoordinator({\n\t\t\tpresent: (approval, signal) => this.presentApproval(approval, signal),\n\t\t\tresume: (taskId, option) => client.resume(taskId, option),\n\t\t\tinfo: (message) => this.deps.showStatus(message),\n\t\t\twarn: (message) => this.deps.showWarning(message),\n\t\t});\n\t\tclient.subscribe((event) => approvals.handleEvent(event));\n\t\t// Gates that opened before we attached don't replay as task_paused.\n\t\tvoid client.pendingApprovals().then(\n\t\t\t(pending) => {\n\t\t\t\tfor (const gate of pending) approvals.enqueuePending(gate);\n\t\t\t},\n\t\t\t() => {\n\t\t\t\t// Best-effort like the rest of the bridge; live gates still arrive via SSE.\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Show one team approval gate and resolve with the chosen (or free-form)\n\t * answer, undefined when skipped. When the attach side panel is open on the\n\t * role that paused, the gate renders inline in the panel — right where its\n\t * stream stopped; otherwise it goes to the options pane, waiting politely\n\t * while another ask is on screen. Either way the signal (gate answered\n\t * elsewhere) dismisses the prompt.\n\t */\n\tprivate async presentApproval(approval: TeamApproval, signal: AbortSignal): Promise<string | undefined> {\n\t\tconst panel = this.attachPanel;\n\t\tif (panel && approval.role === panel.role) {\n\t\t\tthis.attachHandle?.focus();\n\t\t\tconst answer = await panel.presentApproval(approval, signal);\n\t\t\t// Detaching mid-gate settles as skipped — fall through to the options\n\t\t\t// pane so the question isn't silently lost. A skip with the panel\n\t\t\t// still open is a real skip.\n\t\t\tif (answer !== undefined || signal.aborted || this.attachPanel === panel) return answer;\n\t\t}\n\t\twhile (this.deps.isAskOptionsOpen() && !signal.aborted) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 200));\n\t\t}\n\t\tif (signal.aborted) return undefined;\n\t\tconst answers = await this.deps.showAskOptions(\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\tquestion: approval.question,\n\t\t\t\t\tshort: approval.taskId,\n\t\t\t\t\tdetail: `team task \"${approval.taskId}\"${approval.role ? ` (${approval.role})` : \"\"} is paused until answered`,\n\t\t\t\t\toptions: approval.options.map((label) => ({ label })),\n\t\t\t\t\tallowCustom: true,\n\t\t\t\t},\n\t\t\t],\n\t\t\t{ signal },\n\t\t);\n\t\treturn answers?.[0];\n\t}\n\n\t/** Move keyboard focus to the task panel's team roster. */\n\tenterFocus(): void {\n\t\tif (!this.client) {\n\t\t\tthis.deps.showStatus(\"No team connected. Start with --team <url> to mirror a hooteams server.\");\n\t\t\treturn;\n\t\t}\n\t\tif (!taskStore.agents().some((a) => a.kind === \"role\")) {\n\t\t\tthis.deps.showStatus(\"Team roster is empty — waiting for roles from the team server.\");\n\t\t\treturn;\n\t\t}\n\t\tthis.deps.taskPanel.setView(\"teams\");\n\t\tthis.deps.ui.setFocus(this.deps.taskPanel);\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\t/** Leave team focus: detach any side panel and return focus to the editor. */\n\texitFocus(): void {\n\t\tthis.closeAttach();\n\t\tthis.deps.ui.setFocus(this.deps.getEditor());\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\t/**\n\t * Inline nudge editor for a role (n in team focus or while attached).\n\t * Swaps the prompt editor for a one-line input; submit fires POST /steer in\n\t * the background (the REPL and team focus are never blocked on the network).\n\t */\n\tshowNudgeInput(role: string): void {\n\t\tconst client = this.client;\n\t\tif (!client) return;\n\n\t\tconst restoreFocus = () => {\n\t\t\tthis.deps.editorContainer.clear();\n\t\t\tthis.deps.editorContainer.addChild(this.deps.getEditor());\n\t\t\t// Return focus where the nudge came from: the attach panel if one is\n\t\t\t// open, otherwise the team roster.\n\t\t\tif (this.attachHandle) this.attachHandle.focus();\n\t\t\telse this.deps.ui.setFocus(this.deps.taskPanel);\n\t\t\tthis.deps.ui.requestRender();\n\t\t};\n\n\t\tconst input = new ExtensionInputComponent(\n\t\t\t`Nudge ${role}`,\n\t\t\tundefined,\n\t\t\t(value) => {\n\t\t\t\tinput.dispose();\n\t\t\t\trestoreFocus();\n\t\t\t\tconst message = value.trim();\n\t\t\t\tif (!message) return;\n\t\t\t\tvoid client.steer(role, message).then(\n\t\t\t\t\t() => this.deps.showStatus(`Nudged ${role}`),\n\t\t\t\t\t(error) => this.deps.showWarning(`Failed to nudge ${role}: ${String(error)}`),\n\t\t\t\t);\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tinput.dispose();\n\t\t\t\trestoreFocus();\n\t\t\t},\n\t\t\t{ tui: this.deps.ui },\n\t\t);\n\n\t\tthis.deps.editorContainer.clear();\n\t\tthis.deps.editorContainer.addChild(input);\n\t\tthis.deps.ui.setFocus(input);\n\t\tthis.deps.ui.requestRender();\n\t}\n\n\t/** Open the attach side panel for a role (a in team focus). */\n\tshowAttach(role: string): void {\n\t\tconst client = this.client;\n\t\tif (!client) return;\n\t\t// One attached role at a time: re-attaching swaps the panel.\n\t\tthis.closeAttach();\n\t\tconst panel = new TeamAttachPanelComponent(\n\t\t\trole,\n\t\t\tclient,\n\t\t\t{\n\t\t\t\tonDetach: () => this.closeAttach(),\n\t\t\t\tonNudge: (attachedRole) => this.showNudgeInput(attachedRole),\n\t\t\t},\n\t\t\tthis.deps.ui,\n\t\t);\n\t\tthis.attachPanel = panel;\n\t\t// preFocus is the task panel (attach is triggered from team focus), so\n\t\t// hiding the overlay drops the user back on the role roster.\n\t\tthis.attachHandle = this.deps.ui.showOverlay(panel, {\n\t\t\tanchor: \"top-right\",\n\t\t\twidth: \"45%\",\n\t\t\tminWidth: 36,\n\t\t\tmargin: { top: 1, right: 1 },\n\t\t});\n\t}\n\n\t/** Detach the side panel; the role keeps running. Safe to call when closed. */\n\tcloseAttach(): void {\n\t\tthis.attachPanel?.dispose();\n\t\tthis.attachHandle?.hide();\n\t\tthis.attachPanel = undefined;\n\t\tthis.attachHandle = undefined;\n\t}\n}\n"]}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Voice-to-text capture control (ctrl+r / app.input.voiceTranscribe).
3
+ *
4
+ * Prefers a persistent `voicetools serve` daemon: the first press probes for
5
+ * support and (if found) loads models once, showing a "warming up" spinner;
6
+ * every later press reuses the already-warm daemon and jumps straight to
7
+ * Listening. Binaries without `serve` support fall back to spawning
8
+ * `voicetools transcribe` per press. Pressing the shortcut again while
9
+ * listening (or while still warming up) cancels.
10
+ */
11
+ import type { Container, TUI } from "@kolisachint/hoocode-tui";
12
+ /** The slice of the interactive mode the voice feature needs. */
13
+ export interface VoiceControllerDeps {
14
+ ui: TUI;
15
+ /** The status area below the chat; the voice panel mounts here. */
16
+ statusContainer: Container;
17
+ /** Feed raw input (bracketed paste) to the prompt editor. */
18
+ sendEditorInput(data: string): void;
19
+ showError(message: string): void;
20
+ }
21
+ export declare class VoiceController {
22
+ private readonly deps;
23
+ /** In-flight legacy (`voicetools transcribe`) capture. */
24
+ private session;
25
+ private daemon;
26
+ /** Set when the binary rejected `serve`; future presses use the legacy path. */
27
+ private daemonUnsupported;
28
+ /** True while the voicetools binary is being resolved/downloaded before a session starts. */
29
+ private starting;
30
+ /** True while a capture is active (listening or transcribing). */
31
+ private active;
32
+ /** The status panel while voice input is active. */
33
+ private panel;
34
+ constructor(deps: VoiceControllerDeps);
35
+ /** Toggle voice-to-text capture. */
36
+ toggle(): void;
37
+ /** Stop any capture, shut down the daemon, and drop the panel. */
38
+ dispose(): void;
39
+ /**
40
+ * Build the (stable, reused-across-captures) handlers for the daemon.
41
+ *
42
+ * Every handler bails out once `active` is false: CANCEL is a soft
43
+ * request (unlike the legacy path's `proc.kill()`, it doesn't sever the
44
+ * pipe), so the daemon can still have a trailing PARTIAL/FINAL/DONE for the
45
+ * just-cancelled capture in flight when the user presses cancel. Without
46
+ * this guard that stale text would land in the editor after the panel had
47
+ * already collapsed.
48
+ *
49
+ * v0.1.4 serve streams `PARTIAL <full growing hypothesis>` (live preview,
50
+ * never committed) and ends with a single `FINAL <complete text>` (the one
51
+ * commit to the editor). `SEGMENT` is still handled for the legacy
52
+ * transcribe path and any binary that streams committed chunks directly.
53
+ */
54
+ private buildDaemonHandlers;
55
+ /** Inject decoded text into the editor via bracketed paste (with a trailing space). */
56
+ private commitText;
57
+ private beginDaemonCapture;
58
+ private beginLegacyCapture;
59
+ private resolveBin;
60
+ /** Create (or reuse) the voice panel and mount it in the status container. */
61
+ private showPanel;
62
+ private showWarming;
63
+ /** Collapse the voice panel back to nothing (idle) and stop its animation. */
64
+ private resetUI;
65
+ }
66
+ //# sourceMappingURL=voice-controller.d.ts.map