@selesai/code 0.8.2 → 0.8.4

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 (528) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +4 -2
  3. package/dist/cli/args.d.ts +2 -0
  4. package/dist/cli/args.js +18 -0
  5. package/dist/cli/config-selector.js +2 -2
  6. package/dist/cli/startup-ui.d.ts +1 -1
  7. package/dist/cli/startup-ui.js +2 -2
  8. package/dist/core/keybindings.d.ts +44 -4
  9. package/dist/core/llama/provider.js +22 -7
  10. package/dist/core/model-resolver.js +2 -0
  11. package/dist/core/model-runtime.d.ts +4 -2
  12. package/dist/core/model-runtime.js +23 -2
  13. package/dist/core/remote-catalog-provider.js +72 -67
  14. package/dist/core/settings-manager.d.ts +8 -0
  15. package/dist/core/settings-manager.js +18 -0
  16. package/dist/extensions/handoff-new.ts +1 -1
  17. package/dist/extensions/inline-skills.test.ts +1 -0
  18. package/dist/extensions/inline-skills.ts +1 -1
  19. package/dist/extensions/pi-intercom/CHANGELOG.md +25 -3
  20. package/dist/extensions/pi-intercom/README.md +34 -15
  21. package/dist/extensions/pi-intercom/broker/broker.ts +38 -141
  22. package/dist/extensions/pi-intercom/broker/client-liveness.test.ts +173 -0
  23. package/dist/extensions/pi-intercom/broker/client.ts +78 -150
  24. package/dist/extensions/pi-intercom/broker/extension-state.ts +18 -7
  25. package/dist/extensions/pi-intercom/broker/framing.ts +1 -1
  26. package/dist/extensions/pi-intercom/broker/protocol.ts +182 -0
  27. package/dist/extensions/pi-intercom/broker/spawn.test.ts +106 -7
  28. package/dist/extensions/pi-intercom/broker/spawn.ts +37 -11
  29. package/dist/extensions/pi-intercom/config.test.ts +8 -10
  30. package/dist/extensions/pi-intercom/config.ts +3 -3
  31. package/dist/extensions/pi-intercom/index.ts +218 -147
  32. package/dist/extensions/pi-intercom/intercom.integration.test.ts +891 -103
  33. package/dist/extensions/pi-intercom/package.json +3 -2
  34. package/dist/extensions/pi-intercom/project-agent.test.ts +145 -0
  35. package/dist/extensions/pi-intercom/project-agent.ts +324 -0
  36. package/dist/extensions/pi-intercom/reply-tracker.test.ts +86 -1
  37. package/dist/extensions/pi-intercom/reply-tracker.ts +41 -9
  38. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +49 -9
  39. package/dist/extensions/pi-intercom/test/inline-message.test.ts +9 -9
  40. package/dist/extensions/pi-intercom/types.ts +3 -1
  41. package/dist/extensions/pi-intercom/ui/inline-message.ts +7 -7
  42. package/dist/extensions/pi-powerline-footer/.github/workflows/test.yml +2 -2
  43. package/dist/extensions/pi-powerline-footer/CHANGELOG.md +15 -1
  44. package/dist/extensions/pi-powerline-footer/README.md +20 -37
  45. package/dist/extensions/pi-powerline-footer/bash-mode/completion.ts +40 -25
  46. package/dist/extensions/pi-powerline-footer/bash-mode/editor.ts +149 -18
  47. package/dist/extensions/pi-powerline-footer/bash-mode/types.ts +1 -0
  48. package/dist/extensions/pi-powerline-footer/editor-performance.ts +99 -0
  49. package/dist/extensions/pi-powerline-footer/git-status.ts +15 -0
  50. package/dist/extensions/pi-powerline-footer/index.ts +394 -586
  51. package/dist/extensions/pi-powerline-footer/package.json +5 -6
  52. package/dist/extensions/pi-powerline-footer/powerline-config.ts +0 -18
  53. package/dist/extensions/pi-powerline-footer/queue/store.ts +8 -56
  54. package/dist/extensions/pi-powerline-footer/queue/types.ts +1 -2
  55. package/dist/extensions/pi-powerline-footer/segments.ts +0 -3
  56. package/dist/extensions/pi-powerline-footer/tests/bash-mode.test.ts +231 -1
  57. package/dist/extensions/pi-powerline-footer/tests/custom-items.test.ts +5 -19
  58. package/dist/extensions/pi-powerline-footer/tests/editor-performance.test.ts +43 -0
  59. package/dist/extensions/pi-powerline-footer/tests/fixed-editor-border.test.ts +2 -2
  60. package/dist/extensions/pi-powerline-footer/tests/git-optional-locks.test.ts +64 -0
  61. package/dist/extensions/pi-powerline-footer/tests/guide.test.ts +1 -1
  62. package/dist/extensions/pi-powerline-footer/tests/jump-shortcuts.test.ts +86 -19
  63. package/dist/extensions/pi-powerline-footer/tests/queue-store.test.ts +19 -149
  64. package/dist/extensions/pi-powerline-footer/tests/remaining-regressions.test.ts +6 -0
  65. package/dist/extensions/pi-powerline-footer/tests/usage-display.test.ts +5 -5
  66. package/dist/extensions/pi-powerline-footer/tsconfig.json +1 -1
  67. package/dist/extensions/pi-powerline-footer/types.ts +1 -2
  68. package/dist/extensions/pi-subagents/CHANGELOG.md +202 -14
  69. package/dist/extensions/pi-subagents/README.md +65 -1614
  70. package/dist/extensions/pi-subagents/agents/builder.md +0 -1
  71. package/dist/extensions/pi-subagents/agents/delegate.md +14 -0
  72. package/dist/extensions/pi-subagents/agents/oracle.md +74 -0
  73. package/dist/extensions/pi-subagents/agents/reviewer.md +78 -0
  74. package/dist/extensions/pi-subagents/agents/scout.md +50 -0
  75. package/dist/extensions/pi-subagents/agents/worker.md +58 -0
  76. package/dist/extensions/pi-subagents/docs/configuration.md +328 -0
  77. package/dist/extensions/pi-subagents/docs/extension-api.md +308 -0
  78. package/dist/extensions/pi-subagents/docs/missions.md +119 -0
  79. package/dist/extensions/pi-subagents/docs/models.md +192 -0
  80. package/dist/extensions/pi-subagents/docs/observability.md +174 -0
  81. package/dist/extensions/pi-subagents/docs/tool-reference.md +343 -0
  82. package/dist/extensions/pi-subagents/docs/watchdog.md +176 -0
  83. package/dist/extensions/pi-subagents/docs/workflows.md +163 -0
  84. package/dist/extensions/pi-subagents/inspector-runner.mjs +11 -0
  85. package/dist/extensions/pi-subagents/package-lock.json +152 -194
  86. package/dist/extensions/pi-subagents/package.json +9 -10
  87. package/dist/extensions/pi-subagents/prompts/gather-context-and-clarify.md +1 -1
  88. package/dist/extensions/pi-subagents/prompts/parallel-cleanup.md +9 -9
  89. package/dist/extensions/pi-subagents/prompts/parallel-research.md +6 -6
  90. package/dist/extensions/pi-subagents/prompts/parallel-review.md +8 -8
  91. package/dist/extensions/pi-subagents/prompts/review-loop.md +12 -12
  92. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +22 -17
  93. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +77 -72
  94. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +177 -69
  95. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +28 -8
  96. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +88 -66
  97. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +3 -3
  98. package/dist/extensions/pi-subagents/src/agents/agent-refinements.ts +624 -0
  99. package/dist/extensions/pi-subagents/src/agents/agents.ts +29 -16
  100. package/dist/extensions/pi-subagents/src/agents/frontmatter.ts +7 -3
  101. package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +2 -2
  102. package/dist/extensions/pi-subagents/src/agents/skills.ts +2 -9
  103. package/dist/extensions/pi-subagents/src/api/delegation.ts +1 -2
  104. package/dist/extensions/pi-subagents/src/api/project-panes.ts +30 -0
  105. package/dist/extensions/pi-subagents/src/extension/config.ts +56 -8
  106. package/dist/extensions/pi-subagents/src/extension/control-notices.ts +2 -2
  107. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +51 -26
  108. package/dist/extensions/pi-subagents/src/extension/index.ts +119 -50
  109. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +72 -0
  110. package/dist/extensions/pi-subagents/src/extension/rpc.ts +15 -15
  111. package/dist/extensions/pi-subagents/src/extension/schemas.ts +58 -21
  112. package/dist/extensions/pi-subagents/src/extension/subagent-guide.ts +39 -0
  113. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +47 -25
  114. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +3 -3
  115. package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +460 -64
  116. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +102 -4
  117. package/dist/extensions/pi-subagents/src/missions/actions.ts +77 -16
  118. package/dist/extensions/pi-subagents/src/missions/goal-driver.ts +162 -0
  119. package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +65 -14
  120. package/dist/extensions/pi-subagents/src/missions/store.ts +147 -5
  121. package/dist/extensions/pi-subagents/src/missions/types.ts +58 -3
  122. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +256 -0
  123. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +8 -8
  124. package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +42 -0
  125. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +41 -7
  126. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +294 -134
  127. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +19 -3
  128. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +39 -6
  129. package/dist/extensions/pi-subagents/src/runs/background/completion-replay.ts +267 -0
  130. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +145 -60
  131. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +114 -6
  132. package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +33 -0
  133. package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +68 -0
  134. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +71 -0
  135. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +21 -2
  136. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +42 -14
  137. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +12 -24
  138. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +7 -5
  139. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +152 -68
  140. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +17 -4
  141. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +146 -0
  142. package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +21 -5
  143. package/dist/extensions/pi-subagents/src/runs/foreground/async-dismiss-action.ts +85 -0
  144. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +43 -18
  145. package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +20 -19
  146. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +3 -0
  147. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +55 -26
  148. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +137 -0
  149. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +798 -112
  150. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +187 -0
  151. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +165 -22
  152. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
  153. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +2 -0
  154. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +9 -5
  155. package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +12 -2
  156. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +1 -0
  157. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +465 -116
  158. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +10 -10
  159. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +189 -32
  160. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +2 -2
  161. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +3 -3
  162. package/dist/extensions/pi-subagents/src/shared/artifacts.ts +128 -3
  163. package/dist/extensions/pi-subagents/src/shared/display-text.ts +100 -0
  164. package/dist/extensions/pi-subagents/src/shared/file-coalescer.ts +9 -0
  165. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +13 -0
  166. package/dist/extensions/pi-subagents/src/shared/formatters.ts +4 -6
  167. package/dist/extensions/pi-subagents/src/shared/prompt-resources.ts +51 -0
  168. package/dist/extensions/pi-subagents/src/shared/settings.ts +41 -11
  169. package/dist/extensions/pi-subagents/src/shared/types.ts +100 -3
  170. package/dist/extensions/pi-subagents/src/shared/utf8.ts +11 -0
  171. package/dist/extensions/pi-subagents/src/shared/utils.ts +43 -33
  172. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +1 -14
  173. package/dist/extensions/pi-subagents/src/slash/inline-subagents.ts +1 -1
  174. package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +14 -12
  175. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +176 -21
  176. package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +12 -6
  177. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +52 -18
  178. package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +36 -5
  179. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +30 -16
  180. package/dist/extensions/pi-subagents/src/tui/fleet.ts +151 -31
  181. package/dist/extensions/pi-subagents/src/tui/render.ts +201 -68
  182. package/dist/extensions/pi-subagents/src/types/pi-runtime-compat.d.ts +0 -6
  183. package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +5 -4
  184. package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +0 -1
  185. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +313 -25
  186. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +15 -15
  187. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +3 -0
  188. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +2 -0
  189. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +17 -0
  190. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +57 -0
  191. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +16 -0
  192. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +15 -0
  193. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +18 -0
  194. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +9 -0
  195. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +10 -0
  196. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +10 -0
  197. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +20 -0
  198. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +3 -0
  199. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +96 -0
  200. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +119 -0
  201. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +85 -0
  202. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +620 -0
  203. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +5 -0
  204. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +56 -0
  205. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +32 -0
  206. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +49 -0
  207. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +93 -0
  208. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +128 -0
  209. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +7 -0
  210. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +38 -0
  211. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +3 -0
  212. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +15 -0
  213. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +9 -0
  214. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +29 -0
  215. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +2 -0
  216. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +22 -0
  217. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +37 -0
  218. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +34 -0
  219. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +12 -0
  220. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +23 -0
  221. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +171 -0
  222. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +1261 -0
  223. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +20 -0
  224. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +54 -0
  225. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +22 -0
  226. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +13 -0
  227. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +358 -0
  228. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +77 -0
  229. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +512 -0
  230. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +43 -0
  231. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +121 -0
  232. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +82 -0
  233. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +17 -0
  234. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +7 -0
  235. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +210 -0
  236. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +15 -0
  237. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +54 -0
  238. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +4 -0
  239. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +55 -0
  240. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +2 -0
  241. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +5 -0
  242. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +30 -0
  243. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +206 -0
  244. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +15 -0
  245. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +106 -0
  246. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +19 -0
  247. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +356 -0
  248. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +297 -0
  249. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +60 -0
  250. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +15 -0
  251. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +18 -0
  252. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +28 -0
  253. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +3 -0
  254. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +10 -0
  255. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +68 -0
  256. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +106 -0
  257. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +51 -0
  258. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +6 -0
  259. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +35 -0
  260. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +37 -0
  261. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +40 -0
  262. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +37 -0
  263. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +52 -0
  264. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +10 -0
  265. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +35 -0
  266. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +24 -0
  267. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  268. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +70 -0
  269. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +26 -0
  270. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +36 -0
  271. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +19 -0
  272. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts +3 -0
  273. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +61 -0
  274. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +23 -0
  275. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +3 -0
  276. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +10 -0
  277. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +42 -0
  278. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +35 -0
  279. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +12 -0
  280. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +33 -0
  281. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +9 -0
  282. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +34 -0
  283. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +22 -0
  284. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  285. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  286. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  287. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  288. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +102 -0
  289. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  290. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  291. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +19 -0
  292. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +20 -0
  293. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  294. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +12 -0
  295. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  296. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  297. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +22 -0
  298. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +23 -0
  299. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  300. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  301. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +32 -0
  302. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +34 -0
  303. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  304. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +52 -0
  305. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +54 -0
  306. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
  307. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  308. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  309. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +95 -0
  310. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +77 -0
  311. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  312. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  313. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +28 -0
  314. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  315. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  316. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  317. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +94 -0
  318. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  319. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  320. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +14 -0
  321. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  322. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +394 -0
  323. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +12 -0
  324. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +29 -0
  325. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +120 -0
  326. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +28 -0
  327. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +17 -0
  328. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +246 -0
  329. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +20 -0
  330. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +457 -0
  331. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +8 -0
  332. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +3 -0
  333. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +2 -0
  334. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +22 -0
  335. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +18 -0
  336. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +11 -0
  337. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +11 -0
  338. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +4 -0
  339. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +4 -0
  340. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +5 -0
  341. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +8 -0
  342. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +5 -0
  343. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +26 -0
  344. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +7 -0
  345. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +10 -0
  346. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +18 -0
  347. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +30 -0
  348. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +2 -0
  349. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +16 -0
  350. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +3 -0
  351. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +3 -0
  352. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +9 -0
  353. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +31 -0
  354. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +21 -0
  355. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +2 -0
  356. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +31 -0
  357. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +5 -0
  358. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +12 -0
  359. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +3 -0
  360. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +15 -0
  361. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +3 -0
  362. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/index.mjs +84 -0
  363. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/package.json +14 -0
  364. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +15 -15
  365. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +411 -300
  366. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +309 -123
  367. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +99 -56
  368. package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +62 -16
  369. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +159 -108
  370. package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +1 -1
  371. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +4 -2
  372. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +56 -56
  373. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +114 -45
  374. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +57 -19
  375. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +106 -106
  376. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +416 -106
  377. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +287 -17
  378. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +809 -87
  379. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +107 -20
  380. package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +9 -9
  381. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +26 -6
  382. package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +2 -2
  383. package/dist/extensions/pi-subagents/test/support/helpers.ts +2 -0
  384. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +1 -1
  385. package/dist/extensions/pi-subagents/test/support/ts-loader.mjs +0 -8
  386. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +163 -58
  387. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +15 -15
  388. package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +66 -66
  389. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +334 -248
  390. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +52 -52
  391. package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +26 -26
  392. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +99 -99
  393. package/dist/extensions/pi-subagents/test/unit/agent-refinements.test.ts +160 -0
  394. package/dist/extensions/pi-subagents/test/unit/agent-selection.test.ts +9 -9
  395. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +43 -1
  396. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +36 -10
  397. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +387 -30
  398. package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +9 -9
  399. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +2 -2
  400. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +94 -40
  401. package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +5 -3
  402. package/dist/extensions/pi-subagents/test/unit/builtin-agent-documentation.test.ts +7 -7
  403. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +19 -19
  404. package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +19 -19
  405. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +9 -9
  406. package/dist/extensions/pi-subagents/test/unit/chain-serializer.test.ts +20 -20
  407. package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +9 -9
  408. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +35 -5
  409. package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +2 -2
  410. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +52 -52
  411. package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +187 -0
  412. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +125 -71
  413. package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +18 -3
  414. package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +12 -12
  415. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +17 -23
  416. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +1 -1
  417. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +25 -25
  418. package/dist/extensions/pi-subagents/test/unit/extra-agent-dirs.test.ts +3 -3
  419. package/dist/extensions/pi-subagents/test/unit/file-coalescer.test.ts +15 -0
  420. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +62 -44
  421. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +329 -37
  422. package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +4 -4
  423. package/dist/extensions/pi-subagents/test/unit/foreground-tool-call-compaction.test.ts +37 -0
  424. package/dist/extensions/pi-subagents/test/unit/herdr-inspector-bootstrap.test.ts +69 -0
  425. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +79 -2
  426. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +102 -49
  427. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +98 -32
  428. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +5 -5
  429. package/dist/extensions/pi-subagents/test/unit/mission-goal-driver.test.ts +116 -0
  430. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +55 -7
  431. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +289 -13
  432. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +28 -1
  433. package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +2 -2
  434. package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +11 -2
  435. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +84 -10
  436. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +122 -8
  437. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +8 -8
  438. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +24 -24
  439. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +16 -2
  440. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +7 -7
  441. package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +10 -10
  442. package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +3 -3
  443. package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +26 -17
  444. package/dist/extensions/pi-subagents/test/unit/pi-args-permission-system.test.ts +405 -0
  445. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +357 -92
  446. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +22 -6
  447. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +6 -6
  448. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +43 -43
  449. package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +13 -13
  450. package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +4 -4
  451. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +19 -19
  452. package/dist/extensions/pi-subagents/test/unit/project-panes-public-api.test.ts +243 -0
  453. package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +68 -168
  454. package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +58 -15
  455. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +40 -0
  456. package/dist/extensions/pi-subagents/test/unit/reads-resolution.test.ts +66 -0
  457. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +47 -28
  458. package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +12 -12
  459. package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +57 -0
  460. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +107 -27
  461. package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +1 -1
  462. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +56 -50
  463. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +69 -28
  464. package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +67 -0
  465. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +59 -44
  466. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +424 -49
  467. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +23 -1
  468. package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +32 -5
  469. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +13 -13
  470. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +120 -91
  471. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +2 -2
  472. package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +85 -0
  473. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +35 -35
  474. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +24 -0
  475. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +312 -22
  476. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +150 -15
  477. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +26 -26
  478. package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +73 -0
  479. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +76 -25
  480. package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +5 -5
  481. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +55 -6
  482. package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +13 -13
  483. package/dist/extensions/pi-subagents/test/unit/watchdog-lsp-diagnostics.test.ts +1 -1
  484. package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +1 -1
  485. package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +8 -8
  486. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +6 -6
  487. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +138 -11
  488. package/dist/extensions/pi-subagents/test/unit/workflow-graph.test.ts +8 -8
  489. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +113 -0
  490. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +7 -7
  491. package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +6 -6
  492. package/dist/extensions/workflow/extension.ts +21 -19
  493. package/dist/extensions/workflow/modes.ts +65 -0
  494. package/dist/index.d.ts +1 -1
  495. package/dist/main.js +1 -0
  496. package/dist/modes/interactive/components/settings-selector.d.ts +6 -2
  497. package/dist/modes/interactive/components/settings-selector.js +20 -0
  498. package/dist/modes/interactive/interactive-mode.d.ts +28 -0
  499. package/dist/modes/interactive/interactive-mode.js +214 -28
  500. package/dist/modes/interactive/theme/dark.json +1 -0
  501. package/dist/modes/interactive/theme/light.json +1 -0
  502. package/dist/modes/interactive/theme/theme-controller.d.ts +3 -0
  503. package/dist/modes/interactive/theme/theme-controller.js +10 -1
  504. package/dist/modes/interactive/theme/theme.d.ts +2 -2
  505. package/dist/modes/interactive/theme/theme.js +24 -6
  506. package/dist/skills/pi-subagents/SKILL.md +20 -15
  507. package/dist/skills/pi-subagents/references/constraints-and-recipes.md +77 -83
  508. package/dist/skills/pi-subagents/references/execution-controls.md +215 -106
  509. package/dist/skills/pi-subagents/references/management-authoring-rpc.md +29 -9
  510. package/dist/skills/pi-subagents/references/prompting-and-roles.md +58 -43
  511. package/docs/keybindings.md +35 -7
  512. package/docs/plans/workflow-autoloop-reference.md +192 -0
  513. package/docs/plans/workflow-subagent-consolidation-planb.md +374 -0
  514. package/docs/plans/workflow-subagent-scripted-merge.md +406 -0
  515. package/docs/settings.md +16 -14
  516. package/docs/usage.md +5 -0
  517. package/package.json +5 -5
  518. package/dist/extensions/pi-powerline-footer/fixed-editor/cluster.ts +0 -113
  519. package/dist/extensions/pi-powerline-footer/fixed-editor/terminal-split.ts +0 -1080
  520. package/dist/extensions/pi-powerline-footer/tests/fixed-editor.test.ts +0 -1452
  521. package/dist/extensions/workflow/adapter.ts +0 -949
  522. package/dist/extensions/workflow/modes/loop.ts +0 -74
  523. package/dist/extensions/workflow/modes/prototype.ts +0 -170
  524. package/dist/extensions/workflow/modes/quicktype.ts +0 -150
  525. package/dist/extensions/workflow/modes/task.ts +0 -105
  526. package/dist/extensions/workflow/run-state.ts +0 -124
  527. package/dist/extensions/workflow/state-machine.ts +0 -484
  528. package/dist/extensions/workflow/validators.ts +0 -42
@@ -9,7 +9,7 @@ import {
9
9
  type Theme,
10
10
  } from "@selesai/code";
11
11
  import type { AssistantMessage } from "@earendil-works/pi-ai";
12
- import { isKeyRelease, type AutocompleteProvider, type SelectItem, SelectList, truncateToWidth, TUI_KEYBINDINGS, visibleWidth } from "@earendil-works/pi-tui";
12
+ import { CURSOR_MARKER, isKeyRelease, type AutocompleteProvider, type SelectItem, SelectList, truncateToWidth, TUI_KEYBINDINGS, visibleWidth } from "@earendil-works/pi-tui";
13
13
  import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from "node:fs";
14
14
  import { join, dirname } from "node:path";
15
15
 
@@ -23,7 +23,7 @@ import {
23
23
  ModeAwareAutocompleteProvider,
24
24
  OneOffBashAutocompleteProvider,
25
25
  } from "./bash-mode/completion.ts";
26
- import { BashModeEditor } from "./bash-mode/editor.ts";
26
+ import { BashModeEditor, isPrintableInput } from "./bash-mode/editor.ts";
27
27
  import { ManagedShellSession } from "./bash-mode/shell-session.ts";
28
28
  import { matchHistoryEntries, readGlobalShellHistory, readProjectHistory, appendProjectHistory } from "./bash-mode/history.ts";
29
29
  import type { BashModeSettings } from "./bash-mode/types.ts";
@@ -40,6 +40,7 @@ import { getGuidePreferences, getNewGuideFeatures, markGuideVersionSeen, resolve
40
40
  import { createRenderScheduler } from "./render-scheduler.ts";
41
41
  import { createWelcomeDismissScheduler } from "./welcome-dismiss.ts";
42
42
  import { getEditorAutocompleteProvider, passAutocompleteProviderThroughPreviousEditor } from "./editor-composition.ts";
43
+ import { EditorPerfProfiler, readEditorPerfOptions } from "./editor-performance.ts";
43
44
  import { CoreContextUsageCache, estimateInitialContextTokens, estimateUnknownContextUsage, resolveDisplayContextUsage, type CoreContextUsage } from "./context-usage.ts";
44
45
  import { isStaleExtensionContextError, shouldShowStartupWelcome } from "./lifecycle.ts";
45
46
  import { getDefaultColors } from "./theme.ts";
@@ -70,10 +71,8 @@ import {
70
71
  } from "./working-vibes.ts";
71
72
  import { setupTpsTracker } from "./tps.ts";
72
73
  import { readAsyncSubagentUsage } from "./session-usage.ts";
73
- import { renderFixedEditorCluster } from "./fixed-editor/cluster.ts";
74
- import { emergencyTerminalModeReset, TerminalSplitCompositor } from "./fixed-editor/terminal-split.ts";
75
- import { PowerlineQueueStore, currentQueueContext, formatIdeaIssuePrompt, formatQueueDeliveryText, parseCompactQueuedPrompt, parseSigilIdeaCapture, parseTargetPrefix, targetForIdea } from "./queue/store.ts";
76
- import type { PowerlineQueueItem, QueueContext, QueueIntent, QueueTarget } from "./queue/types.ts";
74
+ import { PowerlineQueueStore, currentQueueContext, formatQueueDeliveryText, parseCompactQueuedPrompt } from "./queue/store.ts";
75
+ import type { PowerlineQueueItem, QueueContext, QueueIntent, QueueSummary, QueueTarget } from "./queue/types.ts";
77
76
 
78
77
  // ═══════════════════════════════════════════════════════════════════════════
79
78
  // Configuration
@@ -82,8 +81,6 @@ import type { PowerlineQueueItem, QueueContext, QueueIntent, QueueTarget } from
82
81
  let config: PowerlineConfig = {
83
82
  preset: "default",
84
83
  customItems: [],
85
- mouseScroll: true,
86
- fixedEditor: true,
87
84
  fixedEditorPromptGlyph: "",
88
85
  disabledSegments: [],
89
86
  invalidDisabledSegments: [],
@@ -95,7 +92,6 @@ let config: PowerlineConfig = {
95
92
  invalidPlacement: null,
96
93
  welcome: true,
97
94
  stashSharpSShortcut: false,
98
- queue: { captureSigil: "#" },
99
95
  };
100
96
 
101
97
  const CUSTOM_COMPACTION_STATUS_KEY = "compact-policy";
@@ -107,40 +103,18 @@ export interface PowerlineShortcuts {
107
103
  stashHistory: ShortcutBinding;
108
104
  copyEditor: ShortcutBinding;
109
105
  cutEditor: ShortcutBinding;
110
- ideaCapture: ShortcutBinding;
111
106
  queueOpen: ShortcutBinding;
112
- jumpPreviousUserMessage: ShortcutBinding;
113
- jumpNextUserMessage: ShortcutBinding;
114
- jumpPreviousLlmMessage: ShortcutBinding;
115
- jumpNextLlmMessage: ShortcutBinding;
116
- jumpChatBottom: ShortcutBinding;
117
- scrollChatUp: ShortcutBinding;
118
- scrollChatDown: ShortcutBinding;
119
107
  editorStart: ShortcutBinding;
120
108
  editorEnd: ShortcutBinding;
121
109
  }
122
110
 
123
111
  type PowerlineShortcutKey = keyof PowerlineShortcuts;
124
- type ChatJumpShortcutKey = Extract<PowerlineShortcutKey,
125
- | "jumpPreviousUserMessage"
126
- | "jumpNextUserMessage"
127
- | "jumpPreviousLlmMessage"
128
- | "jumpNextLlmMessage"
129
- | "jumpChatBottom"
130
- >;
131
- type ChatJumpRole = "user" | "assistant";
132
- type ChatJumpDirection = "previous" | "next";
133
- type ChatJumpShortcutAction =
134
- | { kind: "message"; role: ChatJumpRole; direction: ChatJumpDirection }
135
- | { kind: "bottom" };
136
112
  type PowerlineShortcutAction =
137
113
  | { kind: "stashHistory" }
138
114
  | { kind: "copyEditor" }
139
115
  | { kind: "cutEditor" }
140
- | { kind: "ideaCapture" }
141
116
  | { kind: "queueOpen" }
142
- | { kind: "bashMode" }
143
- | { kind: "chat"; action: ChatJumpShortcutAction };
117
+ | { kind: "bashMode" };
144
118
  const STASH_HISTORY_LIMIT = 12;
145
119
  const PROJECT_PROMPT_HISTORY_LIMIT = 50;
146
120
  const STASH_PREVIEW_WIDTH = 72;
@@ -148,55 +122,17 @@ const DEFAULT_SHORTCUTS: PowerlineShortcuts = {
148
122
  stashHistory: "ctrl+alt+h",
149
123
  copyEditor: "ctrl+alt+c",
150
124
  cutEditor: "ctrl+alt+x",
151
- ideaCapture: null,
152
125
  queueOpen: "ctrl+alt+q",
153
- jumpPreviousUserMessage: "ctrl+shift+u",
154
- jumpNextUserMessage: "ctrl+shift+i",
155
- jumpPreviousLlmMessage: "ctrl+alt+,",
156
- jumpNextLlmMessage: "ctrl+alt+.",
157
- jumpChatBottom: "ctrl+shift+g",
158
- scrollChatUp: "super+up",
159
- scrollChatDown: "super+down",
160
126
  editorStart: "super+shift+up",
161
127
  editorEnd: "super+shift+down",
162
128
  };
163
129
  const DEFAULT_BASH_MODE_SETTINGS = {
164
130
  toggleShortcut: "ctrl+shift+b",
131
+ completions: false,
165
132
  transcriptMaxLines: 2000,
166
133
  transcriptMaxBytes: 512 * 1024,
167
134
  } as const satisfies BashModeSettings;
168
- const SHORTCUT_KEYS: PowerlineShortcutKey[] = ["stashHistory", "copyEditor", "cutEditor", "ideaCapture", "queueOpen", "jumpPreviousUserMessage", "jumpNextUserMessage", "jumpPreviousLlmMessage", "jumpNextLlmMessage", "jumpChatBottom", "scrollChatUp", "scrollChatDown", "editorStart", "editorEnd"];
169
- const CHAT_JUMP_SHORTCUTS: Array<{
170
- shortcutKey: ChatJumpShortcutKey;
171
- description: string;
172
- action: ChatJumpShortcutAction;
173
- }> = [
174
- {
175
- shortcutKey: "jumpPreviousUserMessage",
176
- description: "Jump to previous user message",
177
- action: { kind: "message", role: "user", direction: "previous" },
178
- },
179
- {
180
- shortcutKey: "jumpNextUserMessage",
181
- description: "Jump to next user message",
182
- action: { kind: "message", role: "user", direction: "next" },
183
- },
184
- {
185
- shortcutKey: "jumpPreviousLlmMessage",
186
- description: "Jump to previous LLM message",
187
- action: { kind: "message", role: "assistant", direction: "previous" },
188
- },
189
- {
190
- shortcutKey: "jumpNextLlmMessage",
191
- description: "Jump to next LLM message",
192
- action: { kind: "message", role: "assistant", direction: "next" },
193
- },
194
- {
195
- shortcutKey: "jumpChatBottom",
196
- description: "Jump chat to bottom",
197
- action: { kind: "bottom" },
198
- },
199
- ];
135
+ const SHORTCUT_KEYS: PowerlineShortcutKey[] = ["stashHistory", "copyEditor", "cutEditor", "queueOpen", "editorStart", "editorEnd"];
200
136
  const APP_RESERVED_SHORTCUTS = [
201
137
  "escape",
202
138
  "ctrl+c",
@@ -242,6 +178,7 @@ const STREAMING_LAYOUT_CACHE_TTL_MS = 1000;
242
178
  const STATUS_RENDER_DEBOUNCE_MS = 33;
243
179
  const CONTEXT_STATUS_RENDER_MS = 250;
244
180
  const EDITOR_STATUS_DEFER_MS = 150;
181
+ const QUEUE_SUMMARY_CACHE_TTL_MS = 250;
245
182
  const PROMPT_HISTORY_TRACKED = Symbol.for("powerlinePromptHistoryTracked");
246
183
  const PROMPT_HISTORY_STATE_KEY = Symbol.for("powerlinePromptHistoryState");
247
184
 
@@ -892,6 +829,9 @@ export function parseBashModeSettings(settings: Record<string, unknown>, powerli
892
829
  `[powerline-footer] Bash mode shortcut conflict: "${configuredToggleShortcut}" replaced with "${toggleShortcut ?? "disabled"}"`,
893
830
  );
894
831
  }
832
+ const completions = typeof raw.completions === "boolean"
833
+ ? raw.completions
834
+ : DEFAULT_BASH_MODE_SETTINGS.completions;
895
835
  const transcriptMaxLines = typeof raw.transcriptMaxLines === "number" && Number.isFinite(raw.transcriptMaxLines)
896
836
  ? Math.max(100, Math.floor(raw.transcriptMaxLines))
897
837
  : DEFAULT_BASH_MODE_SETTINGS.transcriptMaxLines;
@@ -901,11 +841,174 @@ export function parseBashModeSettings(settings: Record<string, unknown>, powerli
901
841
 
902
842
  return {
903
843
  toggleShortcut,
844
+ completions,
904
845
  transcriptMaxLines,
905
846
  transcriptMaxBytes,
906
847
  };
907
848
  }
908
849
 
850
+ const FAST_EDITOR_RENDER_LINE_THRESHOLD = 80;
851
+ const FAST_EDITOR_RENDER_COLUMN_THRESHOLD = 1200;
852
+
853
+ interface FastEditorState {
854
+ lines: string[];
855
+ cursorLine: number;
856
+ cursorCol: number;
857
+ }
858
+
859
+ interface FastEditorVisualLine {
860
+ text: string;
861
+ cursorCol?: number;
862
+ }
863
+
864
+ function readFastEditorState(editor: unknown): FastEditorState | null {
865
+ const state = Reflect.get(editor as object, "state");
866
+ if (!isRecord(state) || !Array.isArray(state.lines)) return null;
867
+ if (typeof state.cursorLine !== "number" || typeof state.cursorCol !== "number") return null;
868
+
869
+ const lines = state.lines as string[];
870
+ const cursorLine = Math.max(0, Math.min(lines.length - 1, Math.floor(state.cursorLine)));
871
+ const cursorText = lines[cursorLine] ?? "";
872
+ if (typeof cursorText !== "string") return null;
873
+ const cursorCol = Math.max(0, Math.min(cursorText.length, Math.floor(state.cursorCol)));
874
+ return { lines, cursorLine, cursorCol };
875
+ }
876
+
877
+ function fastChunkCount(line: string, width: number): number {
878
+ return Math.max(1, Math.ceil(Math.max(1, line.length) / width));
879
+ }
880
+
881
+ function fastChunk(line: string, width: number, chunkIndex: number): { text: string; startCol: number } {
882
+ const startCol = chunkIndex * width;
883
+ return { text: line.slice(startCol, startCol + width), startCol };
884
+ }
885
+
886
+ function isFastRenderableText(text: string): boolean {
887
+ return /^[\x20-\x7E]*$/.test(text);
888
+ }
889
+
890
+ function pushTrailingChunks(target: FastEditorVisualLine[], line: string, width: number, maxCount: number): void {
891
+ const count = fastChunkCount(line, width);
892
+ const start = Math.max(0, count - maxCount);
893
+ for (let index = start; index < count; index++) {
894
+ target.push({ text: fastChunk(line, width, index).text });
895
+ }
896
+ }
897
+
898
+ function collectFastEditorVisualLines(state: FastEditorState, layoutWidth: number, maxVisibleLines: number): {
899
+ lines: FastEditorVisualLine[];
900
+ hasBefore: boolean;
901
+ hasAfter: boolean;
902
+ } {
903
+ const cursorText = state.lines[state.cursorLine] ?? "";
904
+ const cursorChunkIndex = Math.floor(state.cursorCol / layoutWidth);
905
+ const cursorChunkCount = Math.max(fastChunkCount(cursorText, layoutWidth), cursorChunkIndex + 1);
906
+ const firstCursorChunk = Math.max(0, cursorChunkIndex - maxVisibleLines + 1);
907
+
908
+ const visualLines: FastEditorVisualLine[] = [];
909
+ for (let lineIndex = state.cursorLine - 1; lineIndex >= 0 && visualLines.length < maxVisibleLines - 1; lineIndex--) {
910
+ const chunks: FastEditorVisualLine[] = [];
911
+ pushTrailingChunks(chunks, state.lines[lineIndex] ?? "", layoutWidth, maxVisibleLines - 1 - visualLines.length);
912
+ visualLines.unshift(...chunks);
913
+ }
914
+
915
+ for (let chunkIndex = firstCursorChunk; chunkIndex < cursorChunkIndex && visualLines.length < maxVisibleLines - 1; chunkIndex++) {
916
+ visualLines.push({ text: fastChunk(cursorText, layoutWidth, chunkIndex).text });
917
+ }
918
+
919
+ const cursorChunk = fastChunk(cursorText, layoutWidth, cursorChunkIndex);
920
+ visualLines.push({
921
+ text: cursorChunk.text,
922
+ cursorCol: state.cursorCol - cursorChunk.startCol,
923
+ });
924
+
925
+ for (let chunkIndex = cursorChunkIndex + 1; chunkIndex < cursorChunkCount && visualLines.length < maxVisibleLines; chunkIndex++) {
926
+ visualLines.push({ text: fastChunk(cursorText, layoutWidth, chunkIndex).text });
927
+ }
928
+
929
+ for (let lineIndex = state.cursorLine + 1; lineIndex < state.lines.length && visualLines.length < maxVisibleLines; lineIndex++) {
930
+ const line = state.lines[lineIndex] ?? "";
931
+ const count = fastChunkCount(line, layoutWidth);
932
+ for (let chunkIndex = 0; chunkIndex < count && visualLines.length < maxVisibleLines; chunkIndex++) {
933
+ visualLines.push({ text: fastChunk(line, layoutWidth, chunkIndex).text });
934
+ }
935
+ }
936
+
937
+ return {
938
+ lines: visualLines.slice(-maxVisibleLines),
939
+ hasBefore: state.cursorLine > 0 || firstCursorChunk > 0,
940
+ hasAfter: state.cursorLine < state.lines.length - 1 || cursorChunkIndex < cursorChunkCount - 1,
941
+ };
942
+ }
943
+
944
+ function renderFastCursorLine(line: string, cursorCol: number, focused: boolean): string {
945
+ const before = line.slice(0, cursorCol);
946
+ const target = line[cursorCol];
947
+ const marker = focused ? CURSOR_MARKER : "";
948
+ if (target) {
949
+ return `${before}${marker}\x1b[7m${target}\x1b[0m${line.slice(cursorCol + target.length)}`;
950
+ }
951
+ return `${before}${marker}\x1b[7m \x1b[0m`;
952
+ }
953
+
954
+ function padToWidth(line: string, width: number): string {
955
+ return `${line}${" ".repeat(Math.max(0, width - visibleWidth(line)))}`;
956
+ }
957
+
958
+ export function renderFastPowerlineEditor(
959
+ editor: unknown,
960
+ width: number,
961
+ options: { bashModeActive: boolean; completionsEnabled: boolean },
962
+ ): string[] | null {
963
+ if (width < 10 || options.completionsEnabled) return null;
964
+ if (Reflect.get(editor as object, "isInPaste") === true || Reflect.get(editor as object, "jumpMode") != null) return null;
965
+ if (Reflect.get(editor as object, "autocompleteState") != null) return null;
966
+
967
+ const isShowingAutocomplete = Reflect.get(editor as object, "isShowingAutocomplete");
968
+ if (typeof isShowingAutocomplete === "function" && isShowingAutocomplete.call(editor)) return null;
969
+
970
+ const state = readFastEditorState(editor);
971
+ if (!state) return null;
972
+
973
+ const cursorText = state.lines[state.cursorLine] ?? "";
974
+ if (state.lines.length < FAST_EDITOR_RENDER_LINE_THRESHOLD && cursorText.length < FAST_EDITOR_RENDER_COLUMN_THRESHOLD) {
975
+ return null;
976
+ }
977
+
978
+ const terminalRows = Reflect.get(Reflect.get(editor as object, "tui") ?? {}, "terminal")?.rows;
979
+ const maxVisibleLines = Math.max(5, Math.floor((typeof terminalRows === "number" ? terminalRows : 24) * 0.3));
980
+ const innerWidth = Math.max(1, width - 3);
981
+ const layoutWidth = Math.max(1, innerWidth - 1);
982
+ const viewport = collectFastEditorVisualLines(state, layoutWidth, maxVisibleLines);
983
+ if (viewport.lines.some((line) => !isFastRenderableText(line.text))) return null;
984
+
985
+ Reflect.set(editor as object, "lastWidth", layoutWidth);
986
+
987
+ const bc = (s: string) =>
988
+ typeof (editor as { borderColor?: unknown }).borderColor === "function"
989
+ ? (editor as { borderColor: (s: string) => string }).borderColor(s)
990
+ : `${getFgAnsiCode("sep")}${s}${ansi.reset}`;
991
+ const border = (marker: "↑" | "↓" | "─") => {
992
+ const text = marker === "─" ? "─".repeat(width - 2) : `${marker}${"─".repeat(Math.max(0, width - 3))}`;
993
+ return ` ${bc(text)}`;
994
+ };
995
+ const promptGlyph = options.bashModeActive ? "$" : config.fixedEditorPromptGlyph;
996
+ const prompt = promptGlyph ? `${ansi.getFgAnsi(200, 200, 200)}${promptGlyph}${ansi.reset}` : "";
997
+ const promptPrefix = prompt ? ` ${prompt} ` : " ";
998
+ const contPrefix = " ";
999
+
1000
+ const lines = [border(viewport.hasBefore ? "↑" : "─")];
1001
+ for (let index = 0; index < viewport.lines.length; index++) {
1002
+ const visual = viewport.lines[index]!;
1003
+ const content = visual.cursorCol === undefined
1004
+ ? visual.text
1005
+ : renderFastCursorLine(visual.text, visual.cursorCol, Reflect.get(editor as object, "focused") === true);
1006
+ lines.push(`${index === 0 ? promptPrefix : contPrefix}${padToWidth(content, innerWidth)}`);
1007
+ }
1008
+ lines.push(border(viewport.hasAfter ? "↓" : "─"));
1009
+ return lines;
1010
+ }
1011
+
909
1012
  // ═══════════════════════════════════════════════════════════════════════════
910
1013
  // Status Line Builder
911
1014
  // ═══════════════════════════════════════════════════════════════════════════
@@ -1038,6 +1141,7 @@ function warnInvalidSegmentSettings(ctx: any): void {
1038
1141
  }
1039
1142
 
1040
1143
  export default function powerlineFooter(pi: ExtensionAPI) {
1144
+ const editorPerf = new EditorPerfProfiler(readEditorPerfOptions());
1041
1145
  const startupSettings = readSettings();
1042
1146
  config = parsePowerlineConfig(startupSettings.powerline, PRESET_NAMES);
1043
1147
  let resolvedShortcuts = resolveShortcutConfig(startupSettings);
@@ -1063,6 +1167,13 @@ export default function powerlineFooter(pi: ExtensionAPI) {
1063
1167
  let welcomeOverlayShouldDismiss = false;
1064
1168
  let lastUserPrompt = "";
1065
1169
  let showLastPrompt = true;
1170
+ let lastPromptRenderCache: {
1171
+ source: string;
1172
+ compact: string;
1173
+ width: number;
1174
+ color: string;
1175
+ lines: string[];
1176
+ } | null = null;
1066
1177
  let stashedEditorText: string | null = null;
1067
1178
  let stashedPromptHistory: string[] = readPersistedStashHistory();
1068
1179
  let currentEditor: any = null;
@@ -1070,12 +1181,14 @@ export default function powerlineFooter(pi: ExtensionAPI) {
1070
1181
  let bashTranscript = new BashTranscriptStore(bashModeSettings);
1071
1182
  let bashCompletionEngine = new BashCompletionEngine();
1072
1183
  let shellSession: ManagedShellSession | null = null;
1073
- let fixedEditorCompositor: TerminalSplitCompositor | null = null;
1074
- let fixedStatusContainer: any = null;
1075
- let fixedEditorContainer: any = null;
1076
- let fixedWidgetContainerAbove: any = null;
1077
- let fixedWidgetContainerBelow: any = null;
1078
1184
  const queueStore = new PowerlineQueueStore();
1185
+ let queueSummaryCache: {
1186
+ cwd: string;
1187
+ sessionId?: string;
1188
+ compacting: boolean;
1189
+ expiresAt: number;
1190
+ summary: QueueSummary;
1191
+ } | null = null;
1079
1192
  let powerlineCompacting = false;
1080
1193
  let deliverAfterRetrySettles = false;
1081
1194
  let queueDeliveryTimer: ReturnType<typeof setTimeout> | null = null;
@@ -1318,7 +1431,32 @@ export default function powerlineFooter(pi: ExtensionAPI) {
1318
1431
  return currentQueueContext(ctx.cwd ?? process.cwd(), getQueueSessionId(ctx));
1319
1432
  }
1320
1433
 
1434
+ function getQueueSummary(ctx: any): QueueSummary {
1435
+ const context = getQueueContext(ctx);
1436
+ const now = Date.now();
1437
+ if (
1438
+ queueSummaryCache
1439
+ && queueSummaryCache.cwd === context.cwd
1440
+ && queueSummaryCache.sessionId === context.sessionId
1441
+ && queueSummaryCache.compacting === powerlineCompacting
1442
+ && now < queueSummaryCache.expiresAt
1443
+ ) {
1444
+ return queueSummaryCache.summary;
1445
+ }
1446
+
1447
+ const summary = queueStore.summarize(context, powerlineCompacting);
1448
+ queueSummaryCache = {
1449
+ cwd: context.cwd,
1450
+ ...(context.sessionId ? { sessionId: context.sessionId } : {}),
1451
+ compacting: powerlineCompacting,
1452
+ expiresAt: now + QUEUE_SUMMARY_CACHE_TTL_MS,
1453
+ summary,
1454
+ };
1455
+ return summary;
1456
+ }
1457
+
1321
1458
  function requestQueueRender(): void {
1459
+ queueSummaryCache = null;
1322
1460
  requestImmediateStatusRender({ deferDuringTyping: false });
1323
1461
  }
1324
1462
 
@@ -1344,49 +1482,6 @@ export default function powerlineFooter(pi: ExtensionAPI) {
1344
1482
  return item;
1345
1483
  }
1346
1484
 
1347
- function captureIdeaFromParsedInput(ctx: any, parsed: { target: string | null; text: string }): PowerlineQueueItem | null {
1348
- const trimmed = parsed.text.trim();
1349
- if (!trimmed) {
1350
- ctx.ui.notify("Nothing to capture", "info");
1351
- return null;
1352
- }
1353
-
1354
- const target = targetForIdea(parsed.target, queueStore, ctx.cwd ?? process.cwd());
1355
- const item = captureQueueItem(ctx, trimmed, "idea", target);
1356
- ctx.ui.notify(`Idea saved (${item.id}) — /ideas to review`, "info");
1357
- return item;
1358
- }
1359
-
1360
- function captureIdeaFromText(ctx: any, text: string): PowerlineQueueItem | null {
1361
- return captureIdeaFromParsedInput(ctx, parseTargetPrefix(text));
1362
- }
1363
-
1364
- function captureCurrentProjectIdea(ctx: any, text: string): PowerlineQueueItem | null {
1365
- const trimmed = text.trim();
1366
- if (!trimmed) {
1367
- ctx.ui.notify("Nothing to capture", "info");
1368
- return null;
1369
- }
1370
-
1371
- const item = captureQueueItem(ctx, trimmed, "idea", { kind: "project", cwd: ctx.cwd ?? process.cwd() });
1372
- ctx.ui.notify(`Idea saved (${item.id}) — /ideas to review`, "info");
1373
- return item;
1374
- }
1375
-
1376
- function isSigilIdeaDraft(text: string): boolean {
1377
- const sigil = config.queue.captureSigil;
1378
- if (sigil === false) return false;
1379
- const normalizedSigil = sigil.trim();
1380
- if (!normalizedSigil) return false;
1381
- const trimmed = text.trimStart();
1382
- return trimmed.startsWith(normalizedSigil) && /^\s/.test(trimmed.slice(normalizedSigil.length));
1383
- }
1384
-
1385
- function captureSigilGlyph(): string {
1386
- const sigil = config.queue.captureSigil === false ? "#" : config.queue.captureSigil;
1387
- return Array.from(sigil)[0] ?? "#";
1388
- }
1389
-
1390
1485
  function capturePostCompactPrompt(ctx: any, text: string): PowerlineQueueItem | null {
1391
1486
  const trimmed = text.trim();
1392
1487
  if (!trimmed) return null;
@@ -1516,12 +1611,10 @@ export default function powerlineFooter(pi: ExtensionAPI) {
1516
1611
  }
1517
1612
  }
1518
1613
 
1519
- async function openQueuePicker(ctx: any, mode: "ideas" | "queue"): Promise<void> {
1520
- const active = queueStore.activeItems(getQueueContext(ctx)).filter((item) => (
1521
- mode === "ideas" ? item.intent === "idea" : item.intent !== "idea"
1522
- ));
1614
+ async function openQueuePicker(ctx: any): Promise<void> {
1615
+ const active = queueStore.activeItems(getQueueContext(ctx));
1523
1616
  if (active.length === 0) {
1524
- ctx.ui.notify(mode === "ideas" ? "No ideas captured" : "No queued items", "info");
1617
+ ctx.ui.notify("No queued items", "info");
1525
1618
  return;
1526
1619
  }
1527
1620
 
@@ -1532,7 +1625,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
1532
1625
  }));
1533
1626
  const selected = await showSelectOverlay(
1534
1627
  ctx,
1535
- mode === "ideas" ? "Powerline ideas" : "Powerline queue",
1628
+ "Powerline queue",
1536
1629
  "↑↓ navigate • enter manage • esc cancel",
1537
1630
  items,
1538
1631
  Math.min(active.length, 12),
@@ -1545,7 +1638,12 @@ export default function powerlineFooter(pi: ExtensionAPI) {
1545
1638
 
1546
1639
  function resolveCommandTarget(ctx: any, spec: string): QueueTarget {
1547
1640
  const normalized = spec.trim().replace(/^@/, "");
1548
- return targetForIdea(normalized || null, queueStore, ctx.cwd ?? process.cwd());
1641
+ if (normalized === "current") return { kind: "current-session" };
1642
+ if (normalized === "global") return { kind: "global" };
1643
+
1644
+ const cwd = queueStore.resolveAlias(normalized);
1645
+ if (!cwd) throw new Error(`Unknown project alias @${normalized}. Use /queue alias ${normalized} <path> first.`);
1646
+ return { kind: "project", cwd, alias: normalized };
1549
1647
  }
1550
1648
 
1551
1649
  function sendOrRetryQueueItem(ctx: any, idPrefix: string): void {
@@ -1558,42 +1656,6 @@ export default function powerlineFooter(pi: ExtensionAPI) {
1558
1656
  if (updated) deliverQueueItem(ctx, updated);
1559
1657
  }
1560
1658
 
1561
- function findNextIdea(ctx: any): PowerlineQueueItem | null {
1562
- return queueStore.activeItems(getQueueContext(ctx)).find((candidate) => candidate.intent === "idea") ?? null;
1563
- }
1564
-
1565
- function sendIdeaIssueHandoff(ctx: any, item: PowerlineQueueItem): void {
1566
- queueStore.update(item.id, { status: "delivering", error: undefined });
1567
- requestQueueRender();
1568
-
1569
- try {
1570
- const deliverAs = deliveryModeForItem(ctx, item);
1571
- const issuePrompt = formatIdeaIssuePrompt(item);
1572
- if (deliverAs) {
1573
- pi.sendUserMessage(issuePrompt, { deliverAs });
1574
- } else {
1575
- pi.sendUserMessage(issuePrompt);
1576
- }
1577
- queueStore.update(item.id, { status: "sent", error: undefined });
1578
- ctx.ui.notify(`Sent idea ${item.id} for issue triage`, "info");
1579
- requestQueueRender();
1580
- } catch (error) {
1581
- const message = error instanceof Error ? error.message : String(error);
1582
- queueStore.update(item.id, { status: "failed", error: message });
1583
- ctx.ui.notify(`Failed to send ${item.id}: ${message}`, "error");
1584
- requestQueueRender();
1585
- }
1586
- }
1587
-
1588
- function sendIdeaIssueHandoffById(ctx: any, id: string | undefined): void {
1589
- const item = id ? queueStore.get(id) : findNextIdea(ctx);
1590
- if (!item || item.intent !== "idea") {
1591
- ctx.ui.notify(id ? `No unique idea matches ${id}` : "No ideas captured", id ? "warning" : "info");
1592
- return;
1593
- }
1594
- sendIdeaIssueHandoff(ctx, item);
1595
- }
1596
-
1597
1659
  // Track session start
1598
1660
  setupTpsTracker(pi);
1599
1661
 
@@ -1636,10 +1698,6 @@ export default function powerlineFooter(pi: ExtensionAPI) {
1636
1698
 
1637
1699
  if (ctx.hasUI) {
1638
1700
  ctx.ui.setStatus("stash", undefined);
1639
- const pendingIdeas = queueStore.activeItems(getQueueContext(ctx)).filter((item) => item.intent === "idea").length;
1640
- if (pendingIdeas > 0) {
1641
- ctx.ui.notify(`${pendingIdeas} idea${pendingIdeas === 1 ? "" : "s"} waiting — /ideas`, "info");
1642
- }
1643
1701
  }
1644
1702
 
1645
1703
  // Initialize vibe manager (needs modelRegistry from ctx)
@@ -2049,20 +2107,8 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2049
2107
  }
2050
2108
 
2051
2109
  async function handleSelectedStashHistoryEntry(ctx: any, selected: string): Promise<void> {
2052
- const action = await ctx.ui.select("Stashed prompt", ["Insert", "Promote to idea", "Cancel"]);
2053
-
2054
- if (action === "Insert") {
2055
- await insertSelectedPromptHistoryEntry(ctx, selected);
2056
- return;
2057
- }
2058
-
2059
- if (action === "Promote to idea") {
2060
- try {
2061
- captureIdeaFromText(ctx, selected);
2062
- } catch (error) {
2063
- ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
2064
- }
2065
- }
2110
+ const action = await ctx.ui.select("Stashed prompt", ["Insert", "Cancel"]);
2111
+ if (action === "Insert") await insertSelectedPromptHistoryEntry(ctx, selected);
2066
2112
  }
2067
2113
 
2068
2114
  function isStashShortcutInput(data: string): boolean {
@@ -2090,9 +2136,6 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2090
2136
  if (matchesConfiguredShortcut(data, resolvedShortcuts.cutEditor)) {
2091
2137
  return { kind: "cutEditor" };
2092
2138
  }
2093
- if (matchesConfiguredShortcut(data, resolvedShortcuts.ideaCapture)) {
2094
- return { kind: "ideaCapture" };
2095
- }
2096
2139
  if (matchesConfiguredShortcut(data, resolvedShortcuts.queueOpen)) {
2097
2140
  return { kind: "queueOpen" };
2098
2141
  }
@@ -2100,12 +2143,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2100
2143
  return { kind: "bashMode" };
2101
2144
  }
2102
2145
 
2103
- const chatJumpAction = getChatJumpShortcutAction(data);
2104
- return chatJumpAction ? { kind: "chat", action: chatJumpAction } : null;
2105
- }
2106
-
2107
- function getChatJumpShortcutAction(data: string): ChatJumpShortcutAction | null {
2108
- return CHAT_JUMP_SHORTCUTS.find(({ shortcutKey }) => matchesConfiguredShortcut(data, resolvedShortcuts[shortcutKey]))?.action ?? null;
2146
+ return null;
2109
2147
  }
2110
2148
 
2111
2149
  function runPowerlineShortcut(ctx: any, action: PowerlineShortcutAction): void {
@@ -2126,19 +2164,8 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2126
2164
  return;
2127
2165
  }
2128
2166
 
2129
- if (action.kind === "ideaCapture") {
2130
- const text = getEditorTextForClipboard(ctx);
2131
- if (!text) return;
2132
-
2133
- const item = captureCurrentProjectIdea(ctx, text);
2134
- if (item) {
2135
- ctx.ui.setEditorText("");
2136
- }
2137
- return;
2138
- }
2139
-
2140
2167
  if (action.kind === "queueOpen") {
2141
- void openQueuePicker(ctx, "queue");
2168
+ void openQueuePicker(ctx);
2142
2169
  return;
2143
2170
  }
2144
2171
 
@@ -2146,13 +2173,6 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2146
2173
  void setBashModeActive(!bashModeActive, ctx);
2147
2174
  return;
2148
2175
  }
2149
-
2150
- if (action.action.kind === "bottom") {
2151
- jumpChatToBottom(ctx);
2152
- return;
2153
- }
2154
-
2155
- jumpToChatMessage(ctx, action.action.role, action.action.direction);
2156
2176
  }
2157
2177
 
2158
2178
  function stashOrRestoreEditorText(ctx: any): void {
@@ -2255,98 +2275,6 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2255
2275
 
2256
2276
  registerCdCommand(pi, () => currentCtx?.cwd ?? process.cwd());
2257
2277
 
2258
- pi.registerCommand("idea", {
2259
- description: "Capture an idea without interrupting the current agent. Usage: /idea [@alias|@global|@current] <text> | /idea issue [id]",
2260
- handler: async (args, ctx) => {
2261
- currentCtx = ctx;
2262
- const trimmedArgs = args.trim();
2263
- const [action, id] = trimmedArgs.split(/\s+/).filter(Boolean);
2264
- if (action === "issue") {
2265
- sendIdeaIssueHandoffById(ctx, id);
2266
- return;
2267
- }
2268
-
2269
- const raw = trimmedArgs || getCurrentEditorText(ctx, currentEditor).trim();
2270
- if (!raw) {
2271
- ctx.ui.notify("Usage: /idea [@alias|@global|@current] <text> | /idea issue [id]", "info");
2272
- return;
2273
- }
2274
-
2275
- try {
2276
- const item = captureIdeaFromText(ctx, raw);
2277
- if (item && !trimmedArgs) {
2278
- ctx.ui.setEditorText("");
2279
- }
2280
- } catch (error) {
2281
- ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
2282
- }
2283
- },
2284
- });
2285
-
2286
- pi.registerCommand("ideas", {
2287
- description: "Review or send captured ideas. Usage: /ideas next | /ideas issue [id] | /ideas [send|retry|clear|edit] <id>",
2288
- handler: async (args, ctx) => {
2289
- currentCtx = ctx;
2290
- const parts = args.trim().split(/\s+/).filter(Boolean);
2291
- const action = parts[0];
2292
- const id = parts[1];
2293
-
2294
- if (!action) {
2295
- await openQueuePicker(ctx, "ideas");
2296
- return;
2297
- }
2298
-
2299
- if (action === "next") {
2300
- const item = findNextIdea(ctx);
2301
- if (!item) {
2302
- ctx.ui.notify("No ideas captured", "info");
2303
- return;
2304
- }
2305
- const updated = queueStore.update(item.id, { status: "queued", target: { kind: "current-session" }, error: undefined });
2306
- if (updated) deliverQueueItem(ctx, updated);
2307
- return;
2308
- }
2309
-
2310
- if (action === "issue") {
2311
- sendIdeaIssueHandoffById(ctx, id);
2312
- return;
2313
- }
2314
-
2315
- if (!id) {
2316
- ctx.ui.notify("Usage: /ideas next | /ideas issue [id] | /ideas [send|retry|clear|edit] <id>", "info");
2317
- return;
2318
- }
2319
-
2320
- const item = queueStore.get(id);
2321
- if (!item || item.intent !== "idea") {
2322
- ctx.ui.notify(`No unique idea matches ${id}`, "warning");
2323
- return;
2324
- }
2325
-
2326
- if (action === "send" || action === "retry") {
2327
- const updated = queueStore.update(item.id, { status: "queued", target: { kind: "current-session" }, error: undefined });
2328
- if (updated) deliverQueueItem(ctx, updated);
2329
- return;
2330
- }
2331
-
2332
- if (action === "edit") {
2333
- ctx.ui.setEditorText(item.text);
2334
- queueStore.clear(item.id);
2335
- requestQueueRender();
2336
- return;
2337
- }
2338
-
2339
- if (action === "clear") {
2340
- queueStore.clear(item.id);
2341
- ctx.ui.notify(`Cleared idea ${item.id}`, "info");
2342
- requestQueueRender();
2343
- return;
2344
- }
2345
-
2346
- ctx.ui.notify("Usage: /ideas next | /ideas issue [id] | /ideas [send|retry|clear|edit] <id>", "info");
2347
- },
2348
- });
2349
-
2350
2278
  pi.registerCommand("queue", {
2351
2279
  description: "Manage Powerline queued prompts and project aliases",
2352
2280
  handler: async (args, ctx) => {
@@ -2355,7 +2283,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2355
2283
  const action = parts[0];
2356
2284
 
2357
2285
  if (!action) {
2358
- await openQueuePicker(ctx, "queue");
2286
+ await openQueuePicker(ctx);
2359
2287
  return;
2360
2288
  }
2361
2289
 
@@ -2393,7 +2321,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2393
2321
  if (action === "clear") {
2394
2322
  const id = parts[1];
2395
2323
  if (id === "all") {
2396
- const active = queueStore.activeItems(getQueueContext(ctx)).filter((item) => item.intent !== "idea");
2324
+ const active = queueStore.activeItems(getQueueContext(ctx));
2397
2325
  for (const item of active) queueStore.clear(item.id);
2398
2326
  ctx.ui.notify(`Cleared ${active.length} queued item${active.length === 1 ? "" : "s"}`, "info");
2399
2327
  requestQueueRender();
@@ -2404,7 +2332,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2404
2332
  return;
2405
2333
  }
2406
2334
  const item = queueStore.get(id);
2407
- if (!item || item.intent === "idea") {
2335
+ if (!item) {
2408
2336
  ctx.ui.notify(`No unique queued item matches ${id}`, "warning");
2409
2337
  return;
2410
2338
  }
@@ -2607,6 +2535,22 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2607
2535
  },
2608
2536
  });
2609
2537
 
2538
+ pi.registerCommand("powerline-perf", {
2539
+ description: "Show or reset opt-in editor performance profiling",
2540
+ handler: async (args, ctx) => {
2541
+ if (!editorPerf.options.enabled) {
2542
+ ctx.ui.notify("Set POWERLINE_DEBUG_PERF=1 and reload to enable editor profiling", "info");
2543
+ return;
2544
+ }
2545
+ if (args.trim().toLowerCase() === "reset") {
2546
+ editorPerf.reset();
2547
+ ctx.ui.notify("Powerline editor performance counters reset", "info");
2548
+ return;
2549
+ }
2550
+ ctx.ui.notify(editorPerf.report(), "info");
2551
+ },
2552
+ });
2553
+
2610
2554
  pi.registerCommand("bash-reset", {
2611
2555
  description: "Reset the managed bash session",
2612
2556
  handler: async (_args, ctx) => {
@@ -2812,7 +2756,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2812
2756
  : false;
2813
2757
 
2814
2758
  const thinkingLevel = currentThinkingLevel ?? thinkingLevelFromSession ?? getThinkingLevelFn?.() ?? "off";
2815
- const queueSummary = queueStore.summarize(getQueueContext(ctx), powerlineCompacting);
2759
+ const queueSummary = getQueueSummary(ctx);
2816
2760
 
2817
2761
  return {
2818
2762
  model: ctx.model,
@@ -2869,7 +2813,9 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2869
2813
  const presetDef = getPreset(config.preset);
2870
2814
  let segmentCtx: SegmentContext;
2871
2815
  try {
2872
- segmentCtx = buildSegmentContext(currentCtx, theme);
2816
+ segmentCtx = editorPerf.options.enabled
2817
+ ? editorPerf.measure("layout.segment-context", () => buildSegmentContext(currentCtx, theme))
2818
+ : buildSegmentContext(currentCtx, theme);
2873
2819
  } catch (error) {
2874
2820
  if (!isStaleExtensionContextError(error)) throw error;
2875
2821
  currentCtx = null;
@@ -2925,16 +2871,14 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2925
2871
 
2926
2872
  function renderPowerlineQueuePreviewLines(width: number, theme: Theme): string[] {
2927
2873
  if (!currentCtx) return [];
2928
- const summary = queueStore.summarize(getQueueContext(currentCtx), powerlineCompacting);
2874
+ const summary = getQueueSummary(currentCtx);
2929
2875
  if (!summary.leadingText) return [];
2930
2876
 
2931
2877
  const prefix = summary.leadingStatus === "blocked" || summary.leadingStatus === "failed"
2932
2878
  ? "blocked: "
2933
2879
  : summary.leadingStatus === "delivering"
2934
2880
  ? "sending: "
2935
- : summary.leadingIntent === "idea"
2936
- ? "idea: "
2937
- : "queued: ";
2881
+ : "queued: ";
2938
2882
  const text = `${prefix}${summary.leadingText.replace(/\s+/g, " ").trim()}`;
2939
2883
  const color = summary.leadingStatus === "blocked" || summary.leadingStatus === "failed" ? "warning" : "dim";
2940
2884
  return [` ${theme.fg(color, truncateToWidth(text, Math.max(1, width - 1), "…"))}`];
@@ -2974,214 +2918,43 @@ export default function powerlineFooter(pi: ExtensionAPI) {
2974
2918
  function renderLastPromptLines(width: number): string[] {
2975
2919
  if (bashModeActive || !showLastPrompt || !lastUserPrompt) return [];
2976
2920
 
2977
- const prefix = ` ${getFgAnsiCode("sep")}↳${ansi.reset} `;
2978
- const availableWidth = width - visibleWidth(prefix);
2979
- if (availableWidth < 10) return [];
2980
-
2981
- let promptText = lastUserPrompt.replace(/\s+/g, " ").trim();
2982
- if (!promptText) return [];
2983
-
2984
- promptText = truncateToWidth(promptText, availableWidth, "…");
2985
-
2986
- const styledPrompt = `${getFgAnsiCode("sep")}${promptText}${ansi.reset}`;
2987
- const line = `${prefix}${styledPrompt}`;
2988
- return [truncateToWidth(line, width, "…")];
2989
- }
2990
-
2991
- function teardownFixedEditorCompositor(options?: { resetExtendedKeyboardModes?: boolean }) {
2992
- const hadCompositor = fixedEditorCompositor !== null;
2993
- fixedEditorCompositor?.dispose(options);
2994
- if (!hadCompositor && options?.resetExtendedKeyboardModes) {
2995
- try {
2996
- process.stdout.write(emergencyTerminalModeReset());
2997
- } catch {
2998
- // Shutdown cleanup cannot surface useful terminal write failures.
2999
- }
3000
- }
3001
- fixedEditorCompositor = null;
3002
- fixedStatusContainer = null;
3003
- fixedEditorContainer = null;
3004
- fixedWidgetContainerAbove = null;
3005
- fixedWidgetContainerBelow = null;
3006
- }
3007
-
3008
- function findContainerWithChild(tui: any, child: any): { container: any; index: number } | null {
3009
- const children = Array.isArray(tui?.children) ? tui.children : [];
3010
- const index = children.findIndex((candidate: any) => Array.isArray(candidate?.children) && candidate.children.includes(child));
3011
- if (index === -1) return null;
3012
-
3013
- return { container: children[index], index };
3014
- }
3015
-
3016
- function installFixedEditorCompositor(ctx: any, tui: any) {
3017
- teardownFixedEditorCompositor();
3018
-
3019
- if (!ctx.hasUI || !config.fixedEditor) return;
3020
- if (!tui?.terminal || typeof tui.terminal.write !== "function") {
3021
- throw new Error("[powerline-footer] Fixed editor compositor could not find tui.terminal.write()");
3022
- }
3023
- if (!currentEditor) {
3024
- throw new Error("[powerline-footer] Fixed editor compositor expected the custom editor to be installed first");
3025
- }
3026
-
3027
- const editorContainerMatch = findContainerWithChild(tui, currentEditor);
3028
- if (!editorContainerMatch) {
3029
- throw new Error("[powerline-footer] Fixed editor compositor could not find the editor container in TUI children");
3030
- }
3031
-
3032
- const tuiChildren = Array.isArray(tui.children) ? tui.children : [];
3033
- fixedEditorContainer = editorContainerMatch.container;
3034
- const statusContainerCandidate = tuiChildren[editorContainerMatch.index - 2] ?? null;
3035
- fixedStatusContainer = statusContainerCandidate && typeof statusContainerCandidate.render === "function"
3036
- ? statusContainerCandidate
3037
- : null;
3038
- fixedWidgetContainerAbove = tuiChildren[editorContainerMatch.index - 1] ?? null;
3039
- fixedWidgetContainerBelow = tuiChildren[editorContainerMatch.index + 1] ?? null;
3040
-
3041
- let compositor: TerminalSplitCompositor;
3042
- compositor = new TerminalSplitCompositor({
3043
- tui,
3044
- terminal: tui.terminal,
3045
- mouseScroll: config.mouseScroll,
3046
- keyboardScrollShortcuts: {
3047
- up: resolvedShortcuts.scrollChatUp ?? "super+up",
3048
- down: resolvedShortcuts.scrollChatDown ?? "super+down",
3049
- },
3050
- shouldCaptureKeyboardScroll: () => Reflect.get(tui, "focusedComponent") === currentEditor,
3051
- onCopySelection: (text) => copyTextToClipboard(ctx, text),
3052
- getShowHardwareCursor: () => typeof tui.getShowHardwareCursor === "function" && tui.getShowHardwareCursor(),
3053
- renderCluster: (width, terminalRows) => {
3054
- const theme = currentCtx?.ui?.theme ?? ctx.ui.theme;
3055
- const statusContainerLines = fixedStatusContainer
3056
- ? compositor.renderHidden(fixedStatusContainer, width).filter((line) => visibleWidth(line) > 0)
3057
- : [];
3058
- const aboveWidgetLines = fixedWidgetContainerAbove ? compositor.renderHidden(fixedWidgetContainerAbove, width) : [];
3059
- const belowWidgetLines = fixedWidgetContainerBelow ? compositor.renderHidden(fixedWidgetContainerBelow, width) : [];
3060
- return renderFixedEditorCluster({
3061
- width,
3062
- terminalRows,
3063
- statusLines: [...aboveWidgetLines, ...renderPowerlineStatusLines(width), ...statusContainerLines],
3064
- topLines: renderPowerlinePrimaryLines(width, theme),
3065
- editorLines: fixedEditorContainer ? compositor.renderHidden(fixedEditorContainer, width) : [],
3066
- secondaryLines: [...renderPowerlineSecondaryLines(width, theme), ...belowWidgetLines],
3067
- transcriptLines: renderBashTranscriptLines(width, theme),
3068
- lastPromptLines: renderLastPromptLines(width),
3069
- });
3070
- },
3071
- });
3072
-
3073
- fixedEditorCompositor = compositor;
3074
- if (fixedStatusContainer?.render) compositor.hideRenderable(fixedStatusContainer);
3075
- if (fixedWidgetContainerAbove?.render) compositor.hideRenderable(fixedWidgetContainerAbove);
3076
- compositor.hideRenderable(fixedEditorContainer);
3077
- if (fixedWidgetContainerBelow?.render) compositor.hideRenderable(fixedWidgetContainerBelow);
3078
- compositor.install();
3079
- tui.requestRender(true);
3080
- }
3081
-
3082
- function isChatMessageComponentForRole(component: unknown, role: ChatJumpRole): boolean {
3083
- const componentName = typeof component === "object" && component !== null ? component.constructor?.name : undefined;
3084
- if (role === "assistant") {
3085
- return componentName === "AssistantMessageComponent";
3086
- }
3087
-
3088
- return componentName === "UserMessageComponent" || componentName === "SkillInvocationMessageComponent";
3089
- }
3090
-
3091
- function renderLineCount(component: unknown, width: number): number {
3092
- if (typeof component !== "object" || component === null) return 0;
3093
-
3094
- const render = Reflect.get(component, "render");
3095
- if (typeof render !== "function") return 0;
3096
-
3097
- const lines = render.call(component, width);
3098
- return Array.isArray(lines) ? lines.length : 0;
3099
- }
3100
-
3101
- function collectMessageStartLines(component: unknown, width: number, role: ChatJumpRole, offset: number): {
3102
- targets: number[];
3103
- lineCount: number;
3104
- } {
3105
- const lineCount = renderLineCount(component, width);
3106
- if (isChatMessageComponentForRole(component, role)) {
3107
- return { targets: [offset], lineCount };
2921
+ const color = getFgAnsiCode("sep");
2922
+ if (
2923
+ lastPromptRenderCache
2924
+ && lastPromptRenderCache.source === lastUserPrompt
2925
+ && lastPromptRenderCache.width === width
2926
+ && lastPromptRenderCache.color === color
2927
+ ) {
2928
+ return lastPromptRenderCache.lines;
3108
2929
  }
3109
2930
 
3110
- const children = typeof component === "object" && component !== null ? Reflect.get(component, "children") : null;
3111
- if (!Array.isArray(children) || children.length === 0) {
3112
- return { targets: [], lineCount };
3113
- }
3114
-
3115
- const targets: number[] = [];
3116
- let childOffset = offset;
3117
- let childrenLineCount = 0;
3118
- for (const child of children) {
3119
- const result = collectMessageStartLines(child, width, role, childOffset);
3120
- targets.push(...result.targets);
3121
- childOffset += result.lineCount;
3122
- childrenLineCount += result.lineCount;
3123
- }
3124
-
3125
- return { targets, lineCount: Math.max(lineCount, childrenLineCount) };
3126
- }
3127
-
3128
- function collectChatMessageStartLines(role: ChatJumpRole): number[] {
3129
- const children = Array.isArray(tuiRef?.children) ? tuiRef.children : [];
3130
- const width = Math.max(1, tuiRef?.terminal?.columns ?? 80);
3131
- const targets: number[] = [];
3132
- let offset = 0;
3133
-
3134
- for (const child of children) {
3135
- const result = collectMessageStartLines(child, width, role, offset);
3136
- targets.push(...result.targets);
3137
- offset += result.lineCount;
3138
- }
3139
-
3140
- return [...new Set(targets)].sort((a, b) => a - b);
3141
- }
3142
-
3143
- function jumpToChatMessage(ctx: any, role: ChatJumpRole, direction: ChatJumpDirection): void {
3144
- if (!fixedEditorCompositor) {
3145
- ctx.ui.notify("Chat message jumps require /powerline fixed-editor on", "warning");
3146
- return;
3147
- }
3148
-
3149
- const targets = collectChatMessageStartLines(role);
3150
- const label = role === "assistant" ? "LLM" : "user";
3151
- if (targets.length === 0) {
3152
- ctx.ui.notify(`No ${label} messages found`, "info");
3153
- return;
3154
- }
2931
+ const compact = lastPromptRenderCache?.source === lastUserPrompt
2932
+ ? lastPromptRenderCache.compact
2933
+ : lastUserPrompt.replace(/\s+/g, " ").trim();
2934
+ const prefix = ` ${color}↳${ansi.reset} `;
2935
+ const availableWidth = width - visibleWidth(prefix);
2936
+ const lines = compact && availableWidth >= 10
2937
+ ? [truncateToWidth(`${prefix}${color}${truncateToWidth(compact, availableWidth, "…")}${ansi.reset}`, width, "…")]
2938
+ : [];
3155
2939
 
3156
- const jumped = direction === "previous"
3157
- ? fixedEditorCompositor.jumpToPreviousRootTarget(targets)
3158
- : fixedEditorCompositor.jumpToNextRootTarget(targets);
3159
- if (!jumped) {
3160
- ctx.ui.notify(`No ${direction} ${label} message`, "info");
3161
- }
2940
+ lastPromptRenderCache = { source: lastUserPrompt, compact, width, color, lines };
2941
+ return lines;
3162
2942
  }
3163
2943
 
3164
- function jumpChatToBottom(ctx: any): void {
3165
- if (!fixedEditorCompositor) {
3166
- ctx.ui.notify("Chat bottom jump requires /powerline fixed-editor on", "warning");
3167
- return;
3168
- }
3169
-
3170
- fixedEditorCompositor.jumpToRootBottom();
3171
- }
2944
+ function installPowerlineWidgets(ctx: any) {
2945
+ if (!editorPerf.options.widgets) return;
3172
2946
 
3173
- function followSubmittedEditorToBottom(): void {
3174
- fixedEditorCompositor?.jumpToRootBottom();
3175
- }
2947
+ const measureWidget = (name: string, render: () => string[]): string[] => {
2948
+ return editorPerf.options.enabled ? editorPerf.measure(`widget.${name}`, render) : render();
2949
+ };
3176
2950
 
3177
- function installPowerlineWidgets(ctx: any) {
3178
2951
  ctx.ui.setWidget("powerline-status", () => ({
3179
2952
  dispose() {},
3180
2953
  invalidate() {
3181
2954
  requestStatusRender();
3182
2955
  },
3183
2956
  render(width: number): string[] {
3184
- return renderPowerlineStatusLines(width);
2957
+ return measureWidget("status", () => renderPowerlineStatusLines(width));
3185
2958
  },
3186
2959
  }), { placement: "aboveEditor" });
3187
2960
 
@@ -3191,7 +2964,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
3191
2964
  resetLayoutCache();
3192
2965
  },
3193
2966
  render(width: number): string[] {
3194
- return renderPowerlinePrimaryLines(width, theme);
2967
+ return measureWidget("primary", () => renderPowerlinePrimaryLines(width, theme));
3195
2968
  },
3196
2969
  }), { placement: config.placement === "below" ? "belowEditor" : "aboveEditor" });
3197
2970
 
@@ -3201,33 +2974,37 @@ export default function powerlineFooter(pi: ExtensionAPI) {
3201
2974
  resetLayoutCache();
3202
2975
  },
3203
2976
  render(width: number): string[] {
3204
- return renderPowerlineSecondaryLines(width, theme);
2977
+ return measureWidget("secondary", () => renderPowerlineSecondaryLines(width, theme));
3205
2978
  },
3206
2979
  }), { placement: "belowEditor" });
3207
2980
 
3208
- ctx.ui.setWidget("powerline-bash-transcript", (_tui: any, theme: Theme) => ({
3209
- dispose() {},
3210
- invalidate() {},
3211
- render(width: number): string[] {
3212
- return renderBashTranscriptLines(width, theme);
3213
- },
3214
- }), { placement: "belowEditor" });
2981
+ if (editorPerf.options.bashWidgets) {
2982
+ ctx.ui.setWidget("powerline-bash-transcript", (_tui: any, theme: Theme) => ({
2983
+ dispose() {},
2984
+ invalidate() {},
2985
+ render(width: number): string[] {
2986
+ return measureWidget("bash-transcript", () => renderBashTranscriptLines(width, theme));
2987
+ },
2988
+ }), { placement: "belowEditor" });
2989
+ }
3215
2990
 
3216
2991
  ctx.ui.setWidget("powerline-queue-preview", (_tui: any, theme: Theme) => ({
3217
2992
  dispose() {},
3218
2993
  invalidate() {},
3219
2994
  render(width: number): string[] {
3220
- return renderPowerlineQueuePreviewLines(width, theme);
2995
+ return measureWidget("queue-preview", () => renderPowerlineQueuePreviewLines(width, theme));
3221
2996
  },
3222
2997
  }), { placement: "belowEditor" });
3223
2998
 
3224
- ctx.ui.setWidget("powerline-last-prompt", () => ({
3225
- dispose() {},
3226
- invalidate() {},
3227
- render(width: number): string[] {
3228
- return renderLastPromptLines(width);
3229
- },
3230
- }), { placement: "belowEditor" });
2999
+ if (editorPerf.options.lastPrompt) {
3000
+ ctx.ui.setWidget("powerline-last-prompt", () => ({
3001
+ dispose() {},
3002
+ invalidate() {},
3003
+ render(width: number): string[] {
3004
+ return measureWidget("last-prompt", () => renderLastPromptLines(width));
3005
+ },
3006
+ }), { placement: "belowEditor" });
3007
+ }
3231
3008
  }
3232
3009
 
3233
3010
  function setupCustomEditor(ctx: any) {
@@ -3266,7 +3043,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
3266
3043
  ctx.ui.setWidget("powerline-queue-preview", undefined);
3267
3044
  ctx.ui.setWidget("powerline-last-prompt", undefined);
3268
3045
 
3269
- let autocompleteFixed = false;
3046
+ let autocompleteFixed = !bashModeSettings.completions;
3270
3047
  const previousEditorFactory = typeof ctx.ui.getEditorComponent === "function" ? ctx.ui.getEditorComponent() : undefined;
3271
3048
 
3272
3049
  const editorFactory = (tui: any, editorTheme: any, keybindings: any) => {
@@ -3289,6 +3066,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
3289
3066
  },
3290
3067
  onNotify: (message, level = "info") => ctx.ui.notify(message, level),
3291
3068
  getHistoryEntries: (prefix) => getShellHistoryEntries(prefix),
3069
+ areCompletionsEnabled: () => bashModeSettings.completions,
3292
3070
  resolveGhostSuggestion: async (text, signal) => {
3293
3071
  const oneOffBash = getOneOffBashCommandContext(text);
3294
3072
  if (oneOffBash) {
@@ -3322,6 +3100,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
3322
3100
  };
3323
3101
 
3324
3102
  const attachAutocompleteProvider = (): boolean => {
3103
+ if (!bashModeSettings.completions) return false;
3325
3104
  if (editor.hasWrappedProvider()) return true;
3326
3105
  const defaultProvider = getInstalledAutocompleteProvider();
3327
3106
  if (!defaultProvider) return false;
@@ -3344,29 +3123,21 @@ export default function powerlineFooter(pi: ExtensionAPI) {
3344
3123
  restorePromptHistory(editor);
3345
3124
  attachAutocompleteProvider();
3346
3125
 
3347
- const originalHandleInput = editor.handleInput.bind(editor);
3348
- editor.handleInput = (data: string) => {
3126
+ const baseHandleInput = editor.handleInput.bind(editor);
3127
+ const originalHandleInput = editorPerf.options.enabled
3128
+ ? (data: string) => editorPerf.measure("input.base-editor", () => baseHandleInput(data))
3129
+ : baseHandleInput;
3130
+ const handlePowerlineEditorInput = (data: string) => {
3349
3131
  lastEditorInputAt = Date.now();
3350
3132
 
3351
- const isSubmit = keybindings.matches(data, "tui.input.submit") && !keybindings.matches(data, "tui.input.newLine");
3352
- const isFollowUpSubmit = keybindings.matches(data, "app.message.followUp");
3353
- if (!bashModeActive && (isSubmit || isFollowUpSubmit)) {
3354
- const sigilCapture = parseSigilIdeaCapture(editor.getExpandedText(), config.queue.captureSigil);
3355
- if (sigilCapture) {
3356
- try {
3357
- const item = captureIdeaFromParsedInput(ctx, sigilCapture);
3358
- if (item) {
3359
- editor.addToHistory?.(editor.getExpandedText().trim());
3360
- editor.setText("");
3361
- }
3362
- } catch (error) {
3363
- ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
3364
- }
3365
- scheduleDismissWelcome(ctx);
3366
- return;
3367
- }
3133
+ if (isPrintableInput(data)) {
3134
+ scheduleDismissWelcome(ctx);
3135
+ originalHandleInput(data);
3136
+ return;
3368
3137
  }
3369
3138
 
3139
+ const isSubmit = keybindings.matches(data, "tui.input.submit") && !keybindings.matches(data, "tui.input.newLine");
3140
+ const isFollowUpSubmit = keybindings.matches(data, "app.message.followUp");
3370
3141
  if (!powerlineCompacting && !bashModeActive && isSubmit && typeof ctx.compact === "function") {
3371
3142
  const editorText = editor.getExpandedText().trim();
3372
3143
  const compactQueuedPrompt = parseCompactQueuedPrompt(editorText);
@@ -3423,64 +3194,101 @@ export default function powerlineFooter(pi: ExtensionAPI) {
3423
3194
  return;
3424
3195
  }
3425
3196
 
3426
- attachAutocompleteProvider();
3427
- const followUpText = keybindings.matches(data, "app.message.followUp") ? getCurrentEditorText(ctx, editor) : "";
3197
+ if (bashModeSettings.completions) {
3198
+ attachAutocompleteProvider();
3199
+ }
3428
3200
  scheduleDismissWelcome(ctx);
3429
3201
  originalHandleInput(data);
3430
- if (hasNonWhitespaceText(followUpText) && !hasNonWhitespaceText(getCurrentEditorText(ctx, editor))) {
3431
- followSubmittedEditorToBottom();
3432
- }
3433
3202
  };
3203
+ editor.handleInput = editorPerf.options.enabled
3204
+ ? (data: string) => {
3205
+ editorPerf.measure("input.total", () => handlePowerlineEditorInput(data));
3206
+ const state = Reflect.get(editor, "state");
3207
+ const lines = state && typeof state === "object" ? Reflect.get(state, "lines") : null;
3208
+ if (Array.isArray(lines)) editorPerf.observeDraft(lines);
3209
+ }
3210
+ : handlePowerlineEditorInput;
3434
3211
 
3435
3212
  const originalRender = editor.render.bind(editor);
3436
3213
  editor.render = (width: number): string[] => {
3437
- if (width < 10) {
3438
- return originalRender(width);
3439
- }
3214
+ const renderPowerlineEditor = (): string[] => {
3215
+ if (!editorPerf.options.editorChrome) {
3216
+ return editorPerf.options.enabled
3217
+ ? editorPerf.measure("editor.render.base", () => originalRender(width))
3218
+ : originalRender(width);
3219
+ }
3440
3220
 
3441
- const bc = (s: string) =>
3442
- typeof editor.borderColor === "function"
3443
- ? editor.borderColor(s)
3444
- : `${getFgAnsiCode("sep")}${s}${ansi.reset}`;
3445
- const captureDraft = !bashModeActive && isSigilIdeaDraft(editor.getExpandedText());
3446
- const promptGlyph = bashModeActive ? "$" : captureDraft ? captureSigilGlyph() : config.fixedEditorPromptGlyph;
3447
- const promptColor = captureDraft ? getFgAnsiCode("queue") : ansi.getFgAnsi(200, 200, 200);
3448
- const prompt = promptGlyph ? `${promptColor}${promptGlyph}${ansi.reset}` : "";
3449
- const promptPrefix = prompt ? ` ${prompt} ` : " ";
3450
- const contPrefix = " ";
3451
- const contentWidth = Math.max(1, width - 1);
3452
- const lines = originalRender(contentWidth);
3453
-
3454
- if (lines.length === 0) return lines;
3455
-
3456
- let bottomBorderIndex = lines.length - 1;
3457
- for (let i = lines.length - 1; i >= 1; i--) {
3458
- const stripped = lines[i]?.replace(/\x1b\[[0-9;]*m/g, "") || "";
3459
- if (stripped.length > 0 && /^─{3,}/.test(stripped)) {
3460
- bottomBorderIndex = i;
3461
- break;
3221
+ if (editorPerf.options.fastRender) {
3222
+ const fastLines = editorPerf.options.enabled
3223
+ ? editorPerf.measure("editor.render.fast-probe", () => renderFastPowerlineEditor(editor, width, {
3224
+ bashModeActive,
3225
+ completionsEnabled: bashModeSettings.completions,
3226
+ }))
3227
+ : renderFastPowerlineEditor(editor, width, {
3228
+ bashModeActive,
3229
+ completionsEnabled: bashModeSettings.completions,
3230
+ });
3231
+ if (fastLines) {
3232
+ if (editorPerf.options.enabled) editorPerf.count("editor.render.fast-hit");
3233
+ return fastLines;
3234
+ }
3462
3235
  }
3463
- }
3464
3236
 
3465
- const result: string[] = [];
3466
- result.push(" " + bc("─".repeat(width - 2)));
3237
+ if (width < 10) {
3238
+ return editorPerf.options.enabled
3239
+ ? editorPerf.measure("editor.render.base", () => originalRender(width))
3240
+ : originalRender(width);
3241
+ }
3467
3242
 
3468
- for (let i = 1; i < bottomBorderIndex; i++) {
3469
- const prefix = i === 1 ? promptPrefix : contPrefix;
3470
- result.push(`${prefix}${lines[i] || ""}`);
3471
- }
3243
+ const bc = (s: string) =>
3244
+ typeof editor.borderColor === "function"
3245
+ ? editor.borderColor(s)
3246
+ : `${getFgAnsiCode("sep")}${s}${ansi.reset}`;
3247
+ const promptGlyph = bashModeActive ? "$" : config.fixedEditorPromptGlyph;
3248
+ const promptColor = ansi.getFgAnsi(200, 200, 200);
3249
+ const prompt = promptGlyph ? `${promptColor}${promptGlyph}${ansi.reset}` : "";
3250
+ const promptPrefix = prompt ? ` ${prompt} ` : " ";
3251
+ const contPrefix = " ";
3252
+ const contentWidth = Math.max(1, width - 1);
3253
+ const lines = editorPerf.options.enabled
3254
+ ? editorPerf.measure("editor.render.base", () => originalRender(contentWidth))
3255
+ : originalRender(contentWidth);
3256
+
3257
+ if (lines.length === 0) return lines;
3258
+
3259
+ let bottomBorderIndex = lines.length - 1;
3260
+ for (let i = lines.length - 1; i >= 1; i--) {
3261
+ const stripped = lines[i]?.replace(/\x1b\[[0-9;]*m/g, "") || "";
3262
+ if (stripped.length > 0 && /^─{3,}/.test(stripped)) {
3263
+ bottomBorderIndex = i;
3264
+ break;
3265
+ }
3266
+ }
3472
3267
 
3473
- if (bottomBorderIndex === 1) {
3474
- result.push(`${promptPrefix}${" ".repeat(contentWidth)}`);
3475
- }
3268
+ const result: string[] = [];
3269
+ result.push(" " + bc("─".repeat(width - 2)));
3476
3270
 
3477
- result.push(" " + bc("─".repeat(width - 2)));
3271
+ for (let i = 1; i < bottomBorderIndex; i++) {
3272
+ const prefix = i === 1 ? promptPrefix : contPrefix;
3273
+ result.push(`${prefix}${lines[i] || ""}`);
3274
+ }
3478
3275
 
3479
- for (let i = bottomBorderIndex + 1; i < lines.length; i++) {
3480
- result.push(lines[i] || "");
3481
- }
3276
+ if (bottomBorderIndex === 1) {
3277
+ result.push(`${promptPrefix}${" ".repeat(contentWidth)}`);
3278
+ }
3279
+
3280
+ result.push(" " + bc("─".repeat(width - 2)));
3281
+
3282
+ for (let i = bottomBorderIndex + 1; i < lines.length; i++) {
3283
+ result.push(lines[i] || "");
3284
+ }
3285
+
3286
+ return result;
3287
+ };
3482
3288
 
3483
- return result;
3289
+ return editorPerf.options.enabled
3290
+ ? editorPerf.measure("editor.render.total", renderPowerlineEditor)
3291
+ : renderPowerlineEditor();
3484
3292
  };
3485
3293
 
3486
3294
  return editor;