gsd-pi 2.34.0 → 2.35.0-dev.39eee32

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 (505) hide show
  1. package/dist/cli.js +7 -2
  2. package/dist/resource-loader.d.ts +1 -1
  3. package/dist/resource-loader.js +13 -1
  4. package/dist/resources/extensions/async-jobs/await-tool.js +0 -2
  5. package/dist/resources/extensions/async-jobs/job-manager.js +0 -6
  6. package/dist/resources/extensions/bg-shell/output-formatter.js +1 -19
  7. package/dist/resources/extensions/bg-shell/process-manager.js +0 -4
  8. package/dist/resources/extensions/bg-shell/types.js +0 -2
  9. package/dist/resources/extensions/context7/index.js +5 -0
  10. package/dist/resources/extensions/get-secrets-from-user.js +2 -30
  11. package/dist/resources/extensions/google-search/index.js +5 -0
  12. package/dist/resources/extensions/gsd/auto-dispatch.js +43 -1
  13. package/dist/resources/extensions/gsd/auto-loop.js +10 -1
  14. package/dist/resources/extensions/gsd/auto-recovery.js +35 -0
  15. package/dist/resources/extensions/gsd/auto-start.js +35 -2
  16. package/dist/resources/extensions/gsd/auto.js +59 -4
  17. package/dist/resources/extensions/gsd/changelog.js +162 -0
  18. package/dist/resources/extensions/gsd/commands-bootstrap.js +1 -0
  19. package/dist/resources/extensions/gsd/commands-handlers.js +2 -2
  20. package/dist/resources/extensions/gsd/commands-inspect.js +10 -3
  21. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +5 -1
  22. package/dist/resources/extensions/gsd/commands.js +8 -1
  23. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  24. package/dist/resources/extensions/gsd/doctor-checks.js +113 -5
  25. package/dist/resources/extensions/gsd/doctor-environment.js +26 -17
  26. package/dist/resources/extensions/gsd/doctor-proactive.js +22 -0
  27. package/dist/resources/extensions/gsd/doctor.js +36 -0
  28. package/dist/resources/extensions/gsd/files.js +11 -2
  29. package/dist/resources/extensions/gsd/gitignore.js +54 -7
  30. package/dist/resources/extensions/gsd/guided-flow.js +5 -3
  31. package/dist/resources/extensions/gsd/health-widget-core.js +96 -0
  32. package/dist/resources/extensions/gsd/health-widget.js +97 -46
  33. package/dist/resources/extensions/gsd/index.js +10 -1
  34. package/dist/resources/extensions/gsd/migrate-external.js +55 -2
  35. package/dist/resources/extensions/gsd/milestone-ids.js +3 -2
  36. package/dist/resources/extensions/gsd/paths.js +74 -7
  37. package/dist/resources/extensions/gsd/post-unit-hooks.js +4 -1
  38. package/dist/resources/extensions/gsd/preferences-validation.js +54 -1
  39. package/dist/resources/extensions/gsd/preferences.js +2 -0
  40. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  41. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  42. package/dist/resources/extensions/gsd/roadmap-mutations.js +55 -0
  43. package/dist/resources/extensions/gsd/session-lock.js +26 -2
  44. package/dist/resources/extensions/gsd/state.js +2 -1
  45. package/dist/resources/extensions/gsd/templates/plan.md +8 -0
  46. package/dist/resources/extensions/gsd/worktree-resolver.js +12 -0
  47. package/dist/resources/extensions/mcp-client/index.js +2 -1
  48. package/dist/resources/extensions/remote-questions/remote-command.js +2 -22
  49. package/dist/resources/extensions/shared/mod.js +1 -1
  50. package/dist/resources/extensions/shared/sanitize.js +30 -0
  51. package/dist/resources/extensions/subagent/index.js +6 -14
  52. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  53. package/package.json +2 -1
  54. package/packages/native/dist/native.d.ts +0 -2
  55. package/packages/native/dist/native.js +0 -2
  56. package/packages/native/src/native.ts +0 -3
  57. package/packages/pi-agent-core/dist/agent-loop.d.ts +14 -0
  58. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  59. package/packages/pi-agent-core/dist/agent-loop.js +24 -27
  60. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  61. package/packages/pi-agent-core/dist/agent.d.ts +1 -0
  62. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  63. package/packages/pi-agent-core/dist/agent.js +11 -22
  64. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  65. package/packages/pi-agent-core/dist/proxy.d.ts +1 -25
  66. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  67. package/packages/pi-agent-core/dist/proxy.js +3 -9
  68. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  69. package/packages/pi-agent-core/src/agent-loop.ts +30 -27
  70. package/packages/pi-agent-core/src/agent.ts +12 -23
  71. package/packages/pi-agent-core/src/proxy.ts +3 -9
  72. package/packages/pi-ai/dist/api-registry.d.ts +0 -2
  73. package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
  74. package/packages/pi-ai/dist/api-registry.js +0 -10
  75. package/packages/pi-ai/dist/api-registry.js.map +1 -1
  76. package/packages/pi-ai/dist/providers/anthropic.d.ts +0 -8
  77. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  78. package/packages/pi-ai/dist/providers/anthropic.js +1 -1
  79. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  80. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  81. package/packages/pi-ai/dist/providers/azure-openai-responses.js +5 -41
  82. package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  83. package/packages/pi-ai/dist/providers/github-copilot-headers.d.ts +0 -1
  84. package/packages/pi-ai/dist/providers/github-copilot-headers.d.ts.map +1 -1
  85. package/packages/pi-ai/dist/providers/github-copilot-headers.js +1 -1
  86. package/packages/pi-ai/dist/providers/github-copilot-headers.js.map +1 -1
  87. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts +1 -43
  88. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  89. package/packages/pi-ai/dist/providers/google-gemini-cli.js +2 -2
  90. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  91. package/packages/pi-ai/dist/providers/google-shared.d.ts +0 -4
  92. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  93. package/packages/pi-ai/dist/providers/google-shared.js +1 -1
  94. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  95. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  96. package/packages/pi-ai/dist/providers/openai-completions.js +10 -73
  97. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  98. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  99. package/packages/pi-ai/dist/providers/openai-responses.js +9 -80
  100. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  101. package/packages/pi-ai/dist/providers/openai-shared.d.ts +65 -0
  102. package/packages/pi-ai/dist/providers/openai-shared.d.ts.map +1 -0
  103. package/packages/pi-ai/dist/providers/openai-shared.js +146 -0
  104. package/packages/pi-ai/dist/providers/openai-shared.js.map +1 -0
  105. package/packages/pi-ai/dist/providers/register-builtins.d.ts +0 -1
  106. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  107. package/packages/pi-ai/dist/providers/register-builtins.js +1 -1
  108. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  109. package/packages/pi-ai/dist/utils/event-stream.d.ts +0 -2
  110. package/packages/pi-ai/dist/utils/event-stream.d.ts.map +1 -1
  111. package/packages/pi-ai/dist/utils/event-stream.js +0 -4
  112. package/packages/pi-ai/dist/utils/event-stream.js.map +1 -1
  113. package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
  114. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +7 -135
  115. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
  116. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
  117. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +7 -135
  118. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
  119. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts +46 -0
  120. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts.map +1 -0
  121. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js +160 -0
  122. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js.map +1 -0
  123. package/packages/pi-ai/dist/utils/overflow.d.ts +0 -4
  124. package/packages/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  125. package/packages/pi-ai/dist/utils/overflow.js +0 -6
  126. package/packages/pi-ai/dist/utils/overflow.js.map +1 -1
  127. package/packages/pi-ai/dist/utils/validation.d.ts +0 -8
  128. package/packages/pi-ai/dist/utils/validation.d.ts.map +1 -1
  129. package/packages/pi-ai/dist/utils/validation.js +0 -14
  130. package/packages/pi-ai/dist/utils/validation.js.map +1 -1
  131. package/packages/pi-ai/src/api-registry.ts +0 -12
  132. package/packages/pi-ai/src/providers/anthropic.ts +1 -1
  133. package/packages/pi-ai/src/providers/azure-openai-responses.ts +11 -45
  134. package/packages/pi-ai/src/providers/github-copilot-headers.ts +1 -1
  135. package/packages/pi-ai/src/providers/google-gemini-cli.ts +2 -2
  136. package/packages/pi-ai/src/providers/google-shared.ts +1 -1
  137. package/packages/pi-ai/src/providers/openai-completions.ts +16 -86
  138. package/packages/pi-ai/src/providers/openai-responses.ts +16 -96
  139. package/packages/pi-ai/src/providers/openai-shared.ts +193 -0
  140. package/packages/pi-ai/src/providers/register-builtins.ts +1 -1
  141. package/packages/pi-ai/src/utils/event-stream.ts +0 -5
  142. package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +14 -162
  143. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +13 -161
  144. package/packages/pi-ai/src/utils/oauth/google-oauth-utils.ts +201 -0
  145. package/packages/pi-ai/src/utils/overflow.ts +1 -8
  146. package/packages/pi-ai/src/utils/validation.ts +0 -15
  147. package/packages/pi-coding-agent/dist/config.d.ts +0 -9
  148. package/packages/pi-coding-agent/dist/config.d.ts.map +1 -1
  149. package/packages/pi-coding-agent/dist/config.js +4 -8
  150. package/packages/pi-coding-agent/dist/config.js.map +1 -1
  151. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +16 -63
  152. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  153. package/packages/pi-coding-agent/dist/core/agent-session.js +104 -641
  154. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  155. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +0 -1
  156. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  157. package/packages/pi-coding-agent/dist/core/auth-storage.js +4 -35
  158. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  159. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  160. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js +5 -43
  161. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  162. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  163. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +11 -69
  164. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  165. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +40 -0
  166. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
  167. package/packages/pi-coding-agent/dist/core/compaction/utils.js +78 -0
  168. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  169. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +77 -0
  170. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -0
  171. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +331 -0
  172. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -0
  173. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.d.ts +0 -4
  174. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  175. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.js +1 -1
  176. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.js.map +1 -1
  177. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +2 -2
  178. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  179. package/packages/pi-coding-agent/dist/core/extensions/index.js +1 -1
  180. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  181. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +15 -5
  182. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/extensions/runner.js +129 -256
  184. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +49 -42
  186. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  187. package/packages/pi-coding-agent/dist/core/extensions/types.js +2 -21
  188. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/keybindings.d.ts +0 -8
  190. package/packages/pi-coding-agent/dist/core/keybindings.d.ts.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/keybindings.js +2 -2
  192. package/packages/pi-coding-agent/dist/core/keybindings.js.map +1 -1
  193. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts +39 -0
  194. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts.map +1 -0
  195. package/packages/pi-coding-agent/dist/core/lock-utils.js +89 -0
  196. package/packages/pi-coding-agent/dist/core/lock-utils.js.map +1 -0
  197. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts +0 -17
  198. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  199. package/packages/pi-coding-agent/dist/core/lsp/client.js +3 -62
  200. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  201. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts +1 -1
  202. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
  203. package/packages/pi-coding-agent/dist/core/lsp/config.js +2 -6
  204. package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
  205. package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts +0 -5
  206. package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts.map +1 -1
  207. package/packages/pi-coding-agent/dist/core/lsp/edits.js +1 -1
  208. package/packages/pi-coding-agent/dist/core/lsp/edits.js.map +1 -1
  209. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  210. package/packages/pi-coding-agent/dist/core/lsp/index.js +52 -107
  211. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  212. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts +0 -1
  213. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  214. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -22
  215. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  216. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts +0 -1
  217. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -1
  218. package/packages/pi-coding-agent/dist/core/lsp/types.js +0 -28
  219. package/packages/pi-coding-agent/dist/core/lsp/types.js.map +1 -1
  220. package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts +1 -6
  221. package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts.map +1 -1
  222. package/packages/pi-coding-agent/dist/core/lsp/utils.js +1 -28
  223. package/packages/pi-coding-agent/dist/core/lsp/utils.js.map +1 -1
  224. package/packages/pi-coding-agent/dist/core/messages.d.ts +0 -8
  225. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  226. package/packages/pi-coding-agent/dist/core/messages.js +5 -5
  227. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  228. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +0 -3
  229. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/model-registry.js +1 -3
  231. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts +1 -26
  233. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/model-resolver.js +3 -59
  235. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  236. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  237. package/packages/pi-coding-agent/dist/core/package-manager.js +2 -4
  238. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/prompt-templates.d.ts +0 -17
  240. package/packages/pi-coding-agent/dist/core/prompt-templates.d.ts.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/prompt-templates.js +2 -2
  242. package/packages/pi-coding-agent/dist/core/prompt-templates.js.map +1 -1
  243. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +2 -4
  244. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  245. package/packages/pi-coding-agent/dist/core/resource-loader.js +46 -60
  246. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +87 -0
  248. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -0
  249. package/packages/pi-coding-agent/dist/core/retry-handler.js +295 -0
  250. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -0
  251. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +0 -5
  252. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  253. package/packages/pi-coding-agent/dist/core/session-manager.js +5 -32
  254. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  255. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +8 -12
  256. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  257. package/packages/pi-coding-agent/dist/core/settings-manager.js +78 -168
  258. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  260. package/packages/pi-coding-agent/dist/core/skills.js +1 -3
  261. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  263. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  264. package/packages/pi-coding-agent/dist/index.js +1 -1
  265. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  266. package/packages/pi-coding-agent/dist/migrations.d.ts +0 -16
  267. package/packages/pi-coding-agent/dist/migrations.d.ts.map +1 -1
  268. package/packages/pi-coding-agent/dist/migrations.js +2 -2
  269. package/packages/pi-coding-agent/dist/migrations.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.d.ts +0 -2
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.js +2 -2
  273. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  274. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts +1 -1
  275. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +9 -26
  277. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
  278. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -13
  280. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts +44 -0
  282. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts.map +1 -0
  283. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js +61 -0
  284. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js.map +1 -0
  285. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  286. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js +6 -9
  287. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js.map +1 -1
  288. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -24
  289. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  290. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +50 -512
  291. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  292. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts +71 -0
  293. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +514 -0
  295. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -0
  296. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +65 -4
  297. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  298. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +6 -23
  299. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  300. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +12 -0
  301. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  302. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +175 -0
  303. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -0
  304. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts +6 -0
  305. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts.map +1 -0
  306. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js +15 -0
  307. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js.map +1 -0
  308. package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  309. package/packages/pi-coding-agent/dist/modes/print-mode.js +2 -30
  310. package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  311. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  312. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +2 -28
  313. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  314. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts +19 -0
  315. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts.map +1 -0
  316. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js +45 -0
  317. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js.map +1 -0
  318. package/packages/pi-coding-agent/dist/utils/changelog.d.ts +0 -4
  319. package/packages/pi-coding-agent/dist/utils/changelog.d.ts.map +1 -1
  320. package/packages/pi-coding-agent/dist/utils/changelog.js +1 -1
  321. package/packages/pi-coding-agent/dist/utils/changelog.js.map +1 -1
  322. package/packages/pi-coding-agent/dist/utils/clipboard-image.d.ts +0 -1
  323. package/packages/pi-coding-agent/dist/utils/clipboard-image.d.ts.map +1 -1
  324. package/packages/pi-coding-agent/dist/utils/clipboard-image.js +1 -1
  325. package/packages/pi-coding-agent/dist/utils/clipboard-image.js.map +1 -1
  326. package/packages/pi-coding-agent/dist/utils/error.d.ts +5 -0
  327. package/packages/pi-coding-agent/dist/utils/error.d.ts.map +1 -0
  328. package/packages/pi-coding-agent/dist/utils/error.js +7 -0
  329. package/packages/pi-coding-agent/dist/utils/error.js.map +1 -0
  330. package/packages/pi-coding-agent/dist/utils/photon.d.ts +0 -19
  331. package/packages/pi-coding-agent/dist/utils/photon.d.ts.map +1 -1
  332. package/packages/pi-coding-agent/dist/utils/photon.js +1 -120
  333. package/packages/pi-coding-agent/dist/utils/photon.js.map +1 -1
  334. package/packages/pi-coding-agent/dist/utils/tools-manager.d.ts +0 -1
  335. package/packages/pi-coding-agent/dist/utils/tools-manager.d.ts.map +1 -1
  336. package/packages/pi-coding-agent/dist/utils/tools-manager.js +1 -1
  337. package/packages/pi-coding-agent/dist/utils/tools-manager.js.map +1 -1
  338. package/packages/pi-coding-agent/package.json +1 -1
  339. package/packages/pi-coding-agent/src/config.ts +5 -10
  340. package/packages/pi-coding-agent/src/core/agent-session.ts +117 -745
  341. package/packages/pi-coding-agent/src/core/auth-storage.ts +4 -38
  342. package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +7 -53
  343. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +14 -74
  344. package/packages/pi-coding-agent/src/core/compaction/utils.ts +100 -0
  345. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +424 -0
  346. package/packages/pi-coding-agent/src/core/export-html/ansi-to-html.ts +1 -1
  347. package/packages/pi-coding-agent/src/core/extensions/index.ts +1 -21
  348. package/packages/pi-coding-agent/src/core/extensions/runner.ts +119 -256
  349. package/packages/pi-coding-agent/src/core/extensions/types.ts +50 -69
  350. package/packages/pi-coding-agent/src/core/keybindings.ts +2 -2
  351. package/packages/pi-coding-agent/src/core/lock-utils.ts +113 -0
  352. package/packages/pi-coding-agent/src/core/lsp/client.ts +3 -73
  353. package/packages/pi-coding-agent/src/core/lsp/config.ts +2 -10
  354. package/packages/pi-coding-agent/src/core/lsp/edits.ts +1 -1
  355. package/packages/pi-coding-agent/src/core/lsp/index.ts +83 -152
  356. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -23
  357. package/packages/pi-coding-agent/src/core/lsp/types.ts +0 -29
  358. package/packages/pi-coding-agent/src/core/lsp/utils.ts +1 -33
  359. package/packages/pi-coding-agent/src/core/messages.ts +5 -5
  360. package/packages/pi-coding-agent/src/core/model-registry.ts +0 -2
  361. package/packages/pi-coding-agent/src/core/model-resolver.ts +3 -77
  362. package/packages/pi-coding-agent/src/core/package-manager.ts +1 -4
  363. package/packages/pi-coding-agent/src/core/prompt-templates.ts +2 -2
  364. package/packages/pi-coding-agent/src/core/resource-loader.ts +56 -69
  365. package/packages/pi-coding-agent/src/core/retry-handler.ts +359 -0
  366. package/packages/pi-coding-agent/src/core/session-manager.ts +5 -34
  367. package/packages/pi-coding-agent/src/core/settings-manager.ts +87 -166
  368. package/packages/pi-coding-agent/src/core/skills.ts +1 -4
  369. package/packages/pi-coding-agent/src/index.ts +1 -7
  370. package/packages/pi-coding-agent/src/migrations.ts +2 -2
  371. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector-search.ts +2 -2
  372. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +17 -29
  373. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -13
  374. package/packages/pi-coding-agent/src/modes/interactive/components/tree-render-utils.ts +81 -0
  375. package/packages/pi-coding-agent/src/modes/interactive/components/tree-selector.ts +14 -19
  376. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +50 -561
  377. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +653 -0
  378. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +7 -26
  379. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +196 -0
  380. package/packages/pi-coding-agent/src/modes/interactive/utils/shorten-path.ts +14 -0
  381. package/packages/pi-coding-agent/src/modes/print-mode.ts +2 -30
  382. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -28
  383. package/packages/pi-coding-agent/src/modes/shared/command-context-actions.ts +53 -0
  384. package/packages/pi-coding-agent/src/utils/changelog.ts +1 -1
  385. package/packages/pi-coding-agent/src/utils/clipboard-image.ts +1 -1
  386. package/packages/pi-coding-agent/src/utils/error.ts +6 -0
  387. package/packages/pi-coding-agent/src/utils/photon.ts +0 -137
  388. package/packages/pi-coding-agent/src/utils/tools-manager.ts +1 -1
  389. package/packages/pi-tui/dist/components/editor.d.ts +0 -10
  390. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  391. package/packages/pi-tui/dist/components/editor.js +1 -1
  392. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  393. package/packages/pi-tui/dist/components/markdown.d.ts +5 -0
  394. package/packages/pi-tui/dist/components/markdown.d.ts.map +1 -1
  395. package/packages/pi-tui/dist/components/markdown.js +25 -31
  396. package/packages/pi-tui/dist/components/markdown.js.map +1 -1
  397. package/packages/pi-tui/dist/keys.d.ts +0 -4
  398. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  399. package/packages/pi-tui/dist/keys.js +94 -162
  400. package/packages/pi-tui/dist/keys.js.map +1 -1
  401. package/packages/pi-tui/dist/overlay-layout.d.ts +55 -0
  402. package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -0
  403. package/packages/pi-tui/dist/overlay-layout.js +288 -0
  404. package/packages/pi-tui/dist/overlay-layout.js.map +1 -0
  405. package/packages/pi-tui/dist/tui.d.ts +0 -22
  406. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  407. package/packages/pi-tui/dist/tui.js +6 -272
  408. package/packages/pi-tui/dist/tui.js.map +1 -1
  409. package/packages/pi-tui/dist/utils.d.ts +0 -7
  410. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  411. package/packages/pi-tui/dist/utils.js +0 -44
  412. package/packages/pi-tui/dist/utils.js.map +1 -1
  413. package/packages/pi-tui/src/components/editor.ts +1 -1
  414. package/packages/pi-tui/src/components/markdown.ts +25 -29
  415. package/packages/pi-tui/src/keys.ts +94 -173
  416. package/packages/pi-tui/src/overlay-layout.ts +372 -0
  417. package/packages/pi-tui/src/tui.ts +11 -312
  418. package/packages/pi-tui/src/utils.ts +0 -43
  419. package/pkg/dist/core/export-html/ansi-to-html.d.ts +0 -4
  420. package/pkg/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  421. package/pkg/dist/core/export-html/ansi-to-html.js +1 -1
  422. package/pkg/dist/core/export-html/ansi-to-html.js.map +1 -1
  423. package/pkg/dist/modes/interactive/theme/theme.d.ts +65 -4
  424. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  425. package/pkg/dist/modes/interactive/theme/theme.js +6 -23
  426. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  427. package/pkg/dist/modes/interactive/theme/themes.d.ts +12 -0
  428. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  429. package/pkg/dist/modes/interactive/theme/themes.js +175 -0
  430. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -0
  431. package/pkg/package.json +1 -1
  432. package/src/resources/extensions/async-jobs/await-tool.ts +0 -2
  433. package/src/resources/extensions/async-jobs/job-manager.ts +0 -7
  434. package/src/resources/extensions/bg-shell/output-formatter.ts +0 -17
  435. package/src/resources/extensions/bg-shell/process-manager.ts +0 -4
  436. package/src/resources/extensions/bg-shell/types.ts +0 -12
  437. package/src/resources/extensions/context7/index.ts +7 -0
  438. package/src/resources/extensions/get-secrets-from-user.ts +2 -35
  439. package/src/resources/extensions/google-search/index.ts +7 -0
  440. package/src/resources/extensions/gsd/auto-dispatch.ts +49 -1
  441. package/src/resources/extensions/gsd/auto-loop.ts +11 -1
  442. package/src/resources/extensions/gsd/auto-recovery.ts +39 -0
  443. package/src/resources/extensions/gsd/auto-start.ts +42 -2
  444. package/src/resources/extensions/gsd/auto.ts +61 -3
  445. package/src/resources/extensions/gsd/changelog.ts +213 -0
  446. package/src/resources/extensions/gsd/commands-bootstrap.ts +1 -0
  447. package/src/resources/extensions/gsd/commands-handlers.ts +2 -2
  448. package/src/resources/extensions/gsd/commands-inspect.ts +10 -3
  449. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +5 -1
  450. package/src/resources/extensions/gsd/commands.ts +9 -1
  451. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  452. package/src/resources/extensions/gsd/doctor-checks.ts +107 -5
  453. package/src/resources/extensions/gsd/doctor-environment.ts +26 -16
  454. package/src/resources/extensions/gsd/doctor-proactive.ts +24 -0
  455. package/src/resources/extensions/gsd/doctor-types.ts +9 -1
  456. package/src/resources/extensions/gsd/doctor.ts +35 -0
  457. package/src/resources/extensions/gsd/files.ts +12 -2
  458. package/src/resources/extensions/gsd/gitignore.ts +54 -7
  459. package/src/resources/extensions/gsd/guided-flow.ts +5 -3
  460. package/src/resources/extensions/gsd/health-widget-core.ts +129 -0
  461. package/src/resources/extensions/gsd/health-widget.ts +103 -59
  462. package/src/resources/extensions/gsd/index.ts +10 -1
  463. package/src/resources/extensions/gsd/migrate-external.ts +47 -2
  464. package/src/resources/extensions/gsd/milestone-ids.ts +3 -2
  465. package/src/resources/extensions/gsd/paths.ts +73 -7
  466. package/src/resources/extensions/gsd/post-unit-hooks.ts +5 -1
  467. package/src/resources/extensions/gsd/preferences-validation.ts +54 -1
  468. package/src/resources/extensions/gsd/preferences.ts +2 -0
  469. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  470. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  471. package/src/resources/extensions/gsd/roadmap-mutations.ts +66 -0
  472. package/src/resources/extensions/gsd/session-lock.ts +29 -2
  473. package/src/resources/extensions/gsd/state.ts +2 -1
  474. package/src/resources/extensions/gsd/templates/plan.md +8 -0
  475. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +46 -0
  476. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +98 -2
  477. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +59 -3
  478. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +20 -0
  479. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +214 -0
  480. package/src/resources/extensions/gsd/tests/health-widget.test.ts +158 -0
  481. package/src/resources/extensions/gsd/tests/paths.test.ts +113 -0
  482. package/src/resources/extensions/gsd/tests/preferences.test.ts +40 -2
  483. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +26 -0
  484. package/src/resources/extensions/gsd/tests/test-utils.ts +165 -0
  485. package/src/resources/extensions/gsd/tests/validate-directory.test.ts +15 -0
  486. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +7 -0
  487. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +32 -0
  488. package/src/resources/extensions/gsd/worktree-resolver.ts +11 -0
  489. package/src/resources/extensions/mcp-client/index.ts +2 -1
  490. package/src/resources/extensions/remote-questions/remote-command.ts +2 -23
  491. package/src/resources/extensions/shared/mod.ts +1 -1
  492. package/src/resources/extensions/shared/sanitize.ts +36 -0
  493. package/src/resources/extensions/subagent/index.ts +6 -12
  494. package/src/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  495. package/dist/resources/extensions/shared/wizard-ui.js +0 -478
  496. package/packages/pi-coding-agent/dist/modes/interactive/theme/dark.json +0 -85
  497. package/packages/pi-coding-agent/dist/modes/interactive/theme/light.json +0 -84
  498. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.json +0 -335
  499. package/packages/pi-coding-agent/src/modes/interactive/theme/dark.json +0 -85
  500. package/packages/pi-coding-agent/src/modes/interactive/theme/light.json +0 -84
  501. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.json +0 -335
  502. package/pkg/dist/modes/interactive/theme/dark.json +0 -85
  503. package/pkg/dist/modes/interactive/theme/light.json +0 -84
  504. package/pkg/dist/modes/interactive/theme/theme-schema.json +0 -335
  505. package/src/resources/extensions/shared/wizard-ui.ts +0 -551
@@ -0,0 +1,372 @@
1
+ /**
2
+ * Overlay layout resolution, compositing, and rendering utilities.
3
+ *
4
+ * Extracted from tui.ts — these are pure functions that compute overlay
5
+ * positions and composite overlay content onto base terminal lines.
6
+ */
7
+
8
+ import type { OverlayAnchor, OverlayOptions, SizeValue } from "./tui.js";
9
+ import { extractSegments, sliceByColumn, sliceWithWidth, truncateToWidth, visibleWidth } from "./utils.js";
10
+ import { isImageLine } from "./terminal-image.js";
11
+ import { CURSOR_MARKER } from "./tui.js";
12
+
13
+ // ─── Size parsing ───────────────────────────────────────────────────────────
14
+
15
+ /** Parse a SizeValue into absolute value given a reference size */
16
+ export function parseSizeValue(value: SizeValue | undefined, referenceSize: number): number | undefined {
17
+ if (value === undefined) return undefined;
18
+ if (typeof value === "number") return value;
19
+ // Parse percentage string like "50%"
20
+ const match = value.match(/^(\d+(?:\.\d+)?)%$/);
21
+ if (match) {
22
+ return Math.floor((referenceSize * parseFloat(match[1])) / 100);
23
+ }
24
+ return undefined;
25
+ }
26
+
27
+ // ─── Anchor resolution ──────────────────────────────────────────────────────
28
+
29
+ export function resolveAnchorRow(
30
+ anchor: OverlayAnchor,
31
+ height: number,
32
+ availHeight: number,
33
+ marginTop: number,
34
+ ): number {
35
+ switch (anchor) {
36
+ case "top-left":
37
+ case "top-center":
38
+ case "top-right":
39
+ return marginTop;
40
+ case "bottom-left":
41
+ case "bottom-center":
42
+ case "bottom-right":
43
+ return marginTop + availHeight - height;
44
+ case "left-center":
45
+ case "center":
46
+ case "right-center":
47
+ return marginTop + Math.floor((availHeight - height) / 2);
48
+ }
49
+ }
50
+
51
+ export function resolveAnchorCol(
52
+ anchor: OverlayAnchor,
53
+ width: number,
54
+ availWidth: number,
55
+ marginLeft: number,
56
+ ): number {
57
+ switch (anchor) {
58
+ case "top-left":
59
+ case "left-center":
60
+ case "bottom-left":
61
+ return marginLeft;
62
+ case "top-right":
63
+ case "right-center":
64
+ case "bottom-right":
65
+ return marginLeft + availWidth - width;
66
+ case "top-center":
67
+ case "center":
68
+ case "bottom-center":
69
+ return marginLeft + Math.floor((availWidth - width) / 2);
70
+ }
71
+ }
72
+
73
+ // ─── Overlay layout resolution ──────────────────────────────────────────────
74
+
75
+ export interface OverlayLayout {
76
+ width: number;
77
+ row: number;
78
+ col: number;
79
+ maxHeight: number | undefined;
80
+ }
81
+
82
+ /**
83
+ * Resolve overlay layout from options.
84
+ * Returns { width, row, col, maxHeight } for rendering.
85
+ */
86
+ export function resolveOverlayLayout(
87
+ options: OverlayOptions | undefined,
88
+ overlayHeight: number,
89
+ termWidth: number,
90
+ termHeight: number,
91
+ ): OverlayLayout {
92
+ const opt = options ?? {};
93
+
94
+ // Parse margin (clamp to non-negative)
95
+ const margin =
96
+ typeof opt.margin === "number"
97
+ ? { top: opt.margin, right: opt.margin, bottom: opt.margin, left: opt.margin }
98
+ : (opt.margin ?? {});
99
+ const marginTop = Math.max(0, margin.top ?? 0);
100
+ const marginRight = Math.max(0, margin.right ?? 0);
101
+ const marginBottom = Math.max(0, margin.bottom ?? 0);
102
+ const marginLeft = Math.max(0, margin.left ?? 0);
103
+
104
+ // Available space after margins
105
+ const availWidth = Math.max(1, termWidth - marginLeft - marginRight);
106
+ const availHeight = Math.max(1, termHeight - marginTop - marginBottom);
107
+
108
+ // === Resolve width ===
109
+ let width = parseSizeValue(opt.width, termWidth) ?? Math.min(80, availWidth);
110
+ // Apply minWidth
111
+ if (opt.minWidth !== undefined) {
112
+ width = Math.max(width, opt.minWidth);
113
+ }
114
+ // Clamp to available space
115
+ width = Math.max(1, Math.min(width, availWidth));
116
+
117
+ // === Resolve maxHeight ===
118
+ let maxHeight = parseSizeValue(opt.maxHeight, termHeight);
119
+ // Clamp to available space
120
+ if (maxHeight !== undefined) {
121
+ maxHeight = Math.max(1, Math.min(maxHeight, availHeight));
122
+ }
123
+
124
+ // Effective overlay height (may be clamped by maxHeight)
125
+ const effectiveHeight = maxHeight !== undefined ? Math.min(overlayHeight, maxHeight) : overlayHeight;
126
+
127
+ // === Resolve position ===
128
+ let row: number;
129
+ let col: number;
130
+
131
+ if (opt.row !== undefined) {
132
+ if (typeof opt.row === "string") {
133
+ // Percentage: 0% = top, 100% = bottom (overlay stays within bounds)
134
+ const match = opt.row.match(/^(\d+(?:\.\d+)?)%$/);
135
+ if (match) {
136
+ const maxRow = Math.max(0, availHeight - effectiveHeight);
137
+ const percent = parseFloat(match[1]) / 100;
138
+ row = marginTop + Math.floor(maxRow * percent);
139
+ } else {
140
+ // Invalid format, fall back to center
141
+ row = resolveAnchorRow("center", effectiveHeight, availHeight, marginTop);
142
+ }
143
+ } else {
144
+ // Absolute row position
145
+ row = opt.row;
146
+ }
147
+ } else {
148
+ // Anchor-based (default: center)
149
+ const anchor = opt.anchor ?? "center";
150
+ row = resolveAnchorRow(anchor, effectiveHeight, availHeight, marginTop);
151
+ }
152
+
153
+ if (opt.col !== undefined) {
154
+ if (typeof opt.col === "string") {
155
+ // Percentage: 0% = left, 100% = right (overlay stays within bounds)
156
+ const match = opt.col.match(/^(\d+(?:\.\d+)?)%$/);
157
+ if (match) {
158
+ const maxCol = Math.max(0, availWidth - width);
159
+ const percent = parseFloat(match[1]) / 100;
160
+ col = marginLeft + Math.floor(maxCol * percent);
161
+ } else {
162
+ // Invalid format, fall back to center
163
+ col = resolveAnchorCol("center", width, availWidth, marginLeft);
164
+ }
165
+ } else {
166
+ // Absolute column position
167
+ col = opt.col;
168
+ }
169
+ } else {
170
+ // Anchor-based (default: center)
171
+ const anchor = opt.anchor ?? "center";
172
+ col = resolveAnchorCol(anchor, width, availWidth, marginLeft);
173
+ }
174
+
175
+ // Apply offsets
176
+ if (opt.offsetY !== undefined) row += opt.offsetY;
177
+ if (opt.offsetX !== undefined) col += opt.offsetX;
178
+
179
+ // Clamp to terminal bounds (respecting margins)
180
+ row = Math.max(marginTop, Math.min(row, termHeight - marginBottom - effectiveHeight));
181
+ col = Math.max(marginLeft, Math.min(col, termWidth - marginRight - width));
182
+
183
+ return { width, row, col, maxHeight };
184
+ }
185
+
186
+ // ─── Line compositing ───────────────────────────────────────────────────────
187
+
188
+ const SEGMENT_RESET = "\x1b[0m\x1b]8;;\x07";
189
+
190
+ /** Append reset sequences to each non-image line. */
191
+ export function applyLineResets(lines: string[]): string[] {
192
+ for (let i = 0; i < lines.length; i++) {
193
+ const line = lines[i];
194
+ if (!isImageLine(line)) {
195
+ lines[i] = line + SEGMENT_RESET;
196
+ }
197
+ }
198
+ return lines;
199
+ }
200
+
201
+ /** Splice overlay content into a base line at a specific column. Single-pass optimized. */
202
+ export function compositeLineAt(
203
+ baseLine: string,
204
+ overlayLine: string,
205
+ startCol: number,
206
+ overlayWidth: number,
207
+ totalWidth: number,
208
+ ): string {
209
+ if (isImageLine(baseLine)) return baseLine;
210
+
211
+ // Single pass through baseLine extracts both before and after segments
212
+ const afterStart = startCol + overlayWidth;
213
+ const base = extractSegments(baseLine, startCol, afterStart, totalWidth - afterStart, true);
214
+
215
+ // Extract overlay with width tracking (strict=true to exclude wide chars at boundary)
216
+ const overlay = sliceWithWidth(overlayLine, 0, overlayWidth, true);
217
+
218
+ // Pad segments to target widths
219
+ const beforePad = Math.max(0, startCol - base.beforeWidth);
220
+ const overlayPad = Math.max(0, overlayWidth - overlay.width);
221
+ const actualBeforeWidth = Math.max(startCol, base.beforeWidth);
222
+ const actualOverlayWidth = Math.max(overlayWidth, overlay.width);
223
+ const afterTarget = Math.max(0, totalWidth - actualBeforeWidth - actualOverlayWidth);
224
+ const afterPad = Math.max(0, afterTarget - base.afterWidth);
225
+
226
+ // Compose result
227
+ const r = SEGMENT_RESET;
228
+ const result =
229
+ base.before +
230
+ " ".repeat(beforePad) +
231
+ r +
232
+ overlay.text +
233
+ " ".repeat(overlayPad) +
234
+ r +
235
+ base.after +
236
+ " ".repeat(afterPad);
237
+
238
+ // CRITICAL: Always verify and truncate to terminal width.
239
+ // This is the final safeguard against width overflow which would crash the TUI.
240
+ // Width tracking can drift from actual visible width due to:
241
+ // - Complex ANSI/OSC sequences (hyperlinks, colors)
242
+ // - Wide characters at segment boundaries
243
+ // - Edge cases in segment extraction
244
+ const resultWidth = visibleWidth(result);
245
+ if (resultWidth <= totalWidth) {
246
+ return result;
247
+ }
248
+ // Truncate with strict=true to ensure we don't exceed totalWidth
249
+ return sliceByColumn(result, 0, totalWidth, true);
250
+ }
251
+
252
+ // ─── Overlay compositing ────────────────────────────────────────────────────
253
+
254
+ export interface OverlayEntry {
255
+ component: { render(width: number): string[]; invalidate?(): void };
256
+ options?: OverlayOptions;
257
+ hidden: boolean;
258
+ focusOrder: number;
259
+ }
260
+
261
+ /** Check if an overlay entry is currently visible */
262
+ export function isOverlayVisible(
263
+ entry: OverlayEntry,
264
+ termWidth: number,
265
+ termHeight: number,
266
+ ): boolean {
267
+ if (entry.hidden) return false;
268
+ if (entry.options?.visible) {
269
+ return entry.options.visible(termWidth, termHeight);
270
+ }
271
+ return true;
272
+ }
273
+
274
+ /**
275
+ * Composite all visible overlays into content lines.
276
+ * Sorted by focusOrder (higher = on top).
277
+ */
278
+ export function compositeOverlays(
279
+ lines: string[],
280
+ overlayStack: OverlayEntry[],
281
+ termWidth: number,
282
+ termHeight: number,
283
+ maxLinesRendered: number,
284
+ ): string[] {
285
+ if (overlayStack.length === 0) return lines;
286
+ const result = [...lines];
287
+
288
+ // Pre-render all visible overlays and calculate positions
289
+ const rendered: { overlayLines: string[]; row: number; col: number; w: number }[] = [];
290
+ let minLinesNeeded = result.length;
291
+
292
+ const visibleEntries = overlayStack.filter((e) => isOverlayVisible(e, termWidth, termHeight));
293
+ visibleEntries.sort((a, b) => a.focusOrder - b.focusOrder);
294
+ for (const entry of visibleEntries) {
295
+ const { component, options } = entry;
296
+
297
+ // Get layout with height=0 first to determine width and maxHeight
298
+ // (width and maxHeight don't depend on overlay height)
299
+ const { width, maxHeight } = resolveOverlayLayout(options, 0, termWidth, termHeight);
300
+
301
+ // Render component at calculated width
302
+ let overlayLines = component.render(width);
303
+
304
+ // Apply maxHeight if specified
305
+ if (maxHeight !== undefined && overlayLines.length > maxHeight) {
306
+ overlayLines = overlayLines.slice(0, maxHeight);
307
+ }
308
+
309
+ // Get final row/col with actual overlay height
310
+ const { row, col } = resolveOverlayLayout(options, overlayLines.length, termWidth, termHeight);
311
+
312
+ rendered.push({ overlayLines, row, col, w: width });
313
+ minLinesNeeded = Math.max(minLinesNeeded, row + overlayLines.length);
314
+ }
315
+
316
+ // Ensure result covers the terminal working area to keep overlay positioning stable across resizes.
317
+ // maxLinesRendered can exceed current content length after a shrink; pad to keep viewportStart consistent.
318
+ const workingHeight = Math.max(maxLinesRendered, minLinesNeeded);
319
+
320
+ // Extend result with empty lines if content is too short for overlay placement or working area
321
+ while (result.length < workingHeight) {
322
+ result.push("");
323
+ }
324
+
325
+ const viewportStart = Math.max(0, workingHeight - termHeight);
326
+
327
+ // Composite each overlay
328
+ for (const { overlayLines, row, col, w } of rendered) {
329
+ for (let i = 0; i < overlayLines.length; i++) {
330
+ const idx = viewportStart + row + i;
331
+ if (idx >= 0 && idx < result.length) {
332
+ // Defensive: truncate overlay line to declared width before compositing
333
+ // (components should already respect width, but this ensures it)
334
+ const truncatedOverlayLine =
335
+ visibleWidth(overlayLines[i]) > w ? sliceByColumn(overlayLines[i], 0, w, true) : overlayLines[i];
336
+ result[idx] = compositeLineAt(result[idx], truncatedOverlayLine, col, w, termWidth);
337
+ }
338
+ }
339
+ }
340
+
341
+ return result;
342
+ }
343
+
344
+ // ─── Cursor extraction ──────────────────────────────────────────────────────
345
+
346
+ /**
347
+ * Find and extract cursor position from rendered lines.
348
+ * Searches for CURSOR_MARKER, calculates its position, and strips it from the output.
349
+ * Only scans the bottom terminal height lines (visible viewport).
350
+ * @param lines - Rendered lines to search (mutated to strip marker)
351
+ * @param height - Terminal height (visible viewport size)
352
+ * @returns Cursor position { row, col } or null if no marker found
353
+ */
354
+ export function extractCursorPosition(lines: string[], height: number): { row: number; col: number } | null {
355
+ // Only scan the bottom `height` lines (visible viewport)
356
+ const viewportTop = Math.max(0, lines.length - height);
357
+ for (let row = lines.length - 1; row >= viewportTop; row--) {
358
+ const line = lines[row];
359
+ const markerIndex = line.indexOf(CURSOR_MARKER);
360
+ if (markerIndex !== -1) {
361
+ // Calculate visual column (width of text before marker)
362
+ const beforeMarker = line.slice(0, markerIndex);
363
+ const col = visibleWidth(beforeMarker);
364
+
365
+ // Strip marker from the line
366
+ lines[row] = line.slice(0, markerIndex) + line.slice(markerIndex + CURSOR_MARKER.length);
367
+
368
+ return { row, col };
369
+ }
370
+ }
371
+ return null;
372
+ }