gsd-pi 2.80.0-dev.c5f2443b3 → 2.80.0-dev.f55d16d13

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 (303) hide show
  1. package/dist/resources/.managed-resources-content-hash +1 -1
  2. package/dist/resources/GSD-WORKFLOW.md +2 -2
  3. package/dist/resources/extensions/github-sync/templates.js +39 -8
  4. package/dist/resources/extensions/gsd/auto/loop.js +16 -9
  5. package/dist/resources/extensions/gsd/auto/phases.js +37 -30
  6. package/dist/resources/extensions/gsd/auto/run-unit.js +19 -15
  7. package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
  8. package/dist/resources/extensions/gsd/auto-dispatch.js +10 -0
  9. package/dist/resources/extensions/gsd/auto-post-unit.js +10 -10
  10. package/dist/resources/extensions/gsd/auto-prompts.js +111 -1
  11. package/dist/resources/extensions/gsd/auto-recovery.js +154 -8
  12. package/dist/resources/extensions/gsd/auto-start.js +2 -3
  13. package/dist/resources/extensions/gsd/auto.js +9 -1
  14. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +15 -1
  15. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +11 -1
  16. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
  17. package/dist/resources/extensions/gsd/clean-root-preflight.js +42 -4
  18. package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
  19. package/dist/resources/extensions/gsd/custom-workflow-engine.js +22 -2
  20. package/dist/resources/extensions/gsd/db-base-schema.js +14 -0
  21. package/dist/resources/extensions/gsd/db-migration-steps.js +16 -0
  22. package/dist/resources/extensions/gsd/detection.js +106 -0
  23. package/dist/resources/extensions/gsd/graph.js +9 -3
  24. package/dist/resources/extensions/gsd/gsd-db.js +102 -2
  25. package/dist/resources/extensions/gsd/guided-flow.js +2 -2
  26. package/dist/resources/extensions/gsd/pr-evidence.js +57 -16
  27. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +7 -8
  28. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  29. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  30. package/dist/resources/extensions/gsd/working-output-messages.js +64 -0
  31. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  32. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  33. package/dist/web/standalone/.next/BUILD_ID +1 -1
  34. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  35. package/dist/web/standalone/.next/build-manifest.json +3 -3
  36. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  37. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  38. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  39. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  40. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  41. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  43. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  44. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  45. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  46. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  47. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  49. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  55. package/dist/web/standalone/.next/server/app/index.html +1 -1
  56. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  63. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  64. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  65. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  66. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  67. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  68. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  69. package/dist/web/standalone/.next/static/chunks/{8336.6f6f30e410419aff.js → 8336.631939fb583761fa.js} +1 -1
  70. package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-0481f1221120a7c6.js} +1 -1
  71. package/package.json +10 -6
  72. package/packages/contracts/package.json +1 -1
  73. package/packages/pi-ai/dist/models/fake-model.d.ts +12 -0
  74. package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
  75. package/packages/pi-ai/dist/models/fake-model.js +27 -0
  76. package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
  77. package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
  78. package/packages/pi-ai/dist/models/index.js +8 -0
  79. package/packages/pi-ai/dist/models/index.js.map +1 -1
  80. package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
  81. package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
  82. package/packages/pi-ai/dist/providers/fake.js +319 -0
  83. package/packages/pi-ai/dist/providers/fake.js.map +1 -0
  84. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  85. package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
  86. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  87. package/packages/pi-ai/src/models/fake-model.ts +30 -0
  88. package/packages/pi-ai/src/models/index.ts +9 -0
  89. package/packages/pi-ai/src/providers/fake.ts +376 -0
  90. package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
  91. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  92. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +74 -0
  93. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  94. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -0
  95. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  96. package/packages/pi-coding-agent/dist/core/extensions/runner.js +14 -1
  97. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  98. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +97 -0
  99. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  100. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  101. package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
  102. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  103. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +4 -0
  104. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  105. package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
  106. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  107. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  108. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  109. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  110. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  111. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  112. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +54 -15
  113. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  114. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +26 -0
  115. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
  116. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +112 -0
  117. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
  118. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
  119. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
  120. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +51 -0
  121. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
  122. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  123. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  124. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  125. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
  126. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  127. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
  128. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  129. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
  130. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  131. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
  132. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  133. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +16 -0
  134. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  135. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +106 -17
  136. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  137. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  138. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +60 -1
  139. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  140. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +40 -1
  141. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  142. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -0
  143. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  144. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
  145. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  146. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  147. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
  148. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  149. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +23 -0
  150. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  151. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  152. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +20 -0
  153. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  154. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
  155. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
  156. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
  157. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
  158. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  159. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  160. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
  161. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  162. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  163. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  164. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +18 -1
  165. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  166. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  167. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
  168. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  169. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
  170. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
  171. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
  172. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
  173. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
  174. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
  175. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +48 -0
  176. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
  177. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +87 -0
  178. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +108 -0
  179. package/packages/pi-coding-agent/src/core/extensions/runner.ts +16 -1
  180. package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
  181. package/packages/pi-coding-agent/src/core/settings-manager.ts +12 -0
  182. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  183. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  184. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +78 -15
  185. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +59 -0
  186. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +160 -0
  187. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
  188. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
  189. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  190. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
  191. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +118 -17
  192. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +43 -1
  193. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -1
  194. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
  195. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
  196. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +25 -0
  197. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
  198. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
  199. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
  200. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +32 -2
  201. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
  202. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +65 -0
  203. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
  204. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  205. package/packages/pi-tui/dist/__tests__/style.test.d.ts +2 -0
  206. package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
  207. package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
  208. package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
  209. package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
  210. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  211. package/packages/pi-tui/dist/index.d.ts +1 -0
  212. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  213. package/packages/pi-tui/dist/index.js +2 -0
  214. package/packages/pi-tui/dist/index.js.map +1 -1
  215. package/packages/pi-tui/dist/style.d.ts +41 -0
  216. package/packages/pi-tui/dist/style.d.ts.map +1 -0
  217. package/packages/pi-tui/dist/style.js +158 -0
  218. package/packages/pi-tui/dist/style.js.map +1 -0
  219. package/packages/pi-tui/dist/tui.d.ts +0 -1
  220. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  221. package/packages/pi-tui/dist/tui.js +3 -8
  222. package/packages/pi-tui/dist/tui.js.map +1 -1
  223. package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
  224. package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
  225. package/packages/pi-tui/src/index.ts +9 -0
  226. package/packages/pi-tui/src/style.ts +225 -0
  227. package/packages/pi-tui/src/tui.ts +3 -8
  228. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  229. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  230. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  231. package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
  232. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  233. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
  234. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  235. package/pkg/dist/modes/interactive/theme/theme.js +18 -1
  236. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  237. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  238. package/pkg/dist/modes/interactive/theme/themes.js +36 -27
  239. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  240. package/src/resources/GSD-WORKFLOW.md +2 -2
  241. package/src/resources/extensions/github-sync/templates.ts +38 -8
  242. package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
  243. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  244. package/src/resources/extensions/gsd/auto/loop.ts +17 -10
  245. package/src/resources/extensions/gsd/auto/phases.ts +42 -28
  246. package/src/resources/extensions/gsd/auto/run-unit.ts +24 -14
  247. package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
  248. package/src/resources/extensions/gsd/auto-dispatch.ts +17 -0
  249. package/src/resources/extensions/gsd/auto-post-unit.ts +10 -10
  250. package/src/resources/extensions/gsd/auto-prompts.ts +116 -1
  251. package/src/resources/extensions/gsd/auto-recovery.ts +153 -7
  252. package/src/resources/extensions/gsd/auto-start.ts +7 -6
  253. package/src/resources/extensions/gsd/auto.ts +12 -1
  254. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +16 -1
  255. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +17 -1
  256. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
  257. package/src/resources/extensions/gsd/clean-root-preflight.ts +41 -3
  258. package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
  259. package/src/resources/extensions/gsd/custom-workflow-engine.ts +24 -1
  260. package/src/resources/extensions/gsd/db-base-schema.ts +15 -0
  261. package/src/resources/extensions/gsd/db-migration-steps.ts +17 -0
  262. package/src/resources/extensions/gsd/detection.ts +128 -0
  263. package/src/resources/extensions/gsd/graph.ts +12 -5
  264. package/src/resources/extensions/gsd/gsd-db.ts +119 -1
  265. package/src/resources/extensions/gsd/guided-flow.ts +2 -2
  266. package/src/resources/extensions/gsd/pr-evidence.ts +63 -5
  267. package/src/resources/extensions/gsd/prompts/complete-milestone.md +7 -8
  268. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  269. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  270. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +7 -1
  271. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +33 -0
  272. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +84 -5
  273. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +170 -1
  274. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +88 -2
  275. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
  276. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +112 -6
  277. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +40 -2
  278. package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
  279. package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
  280. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  281. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-basic.md +52 -0
  282. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
  283. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
  284. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
  285. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
  286. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
  287. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  288. package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
  289. package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
  290. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  291. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  292. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +46 -2
  293. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  294. package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
  295. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +37 -6
  296. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  297. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  298. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
  299. package/src/resources/extensions/gsd/working-output-messages.ts +120 -0
  300. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  301. package/packages/contracts/tsconfig.tsbuildinfo +0 -1
  302. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → mPZbi5BH9dwokaPZlrYuQ}/_buildManifest.js +0 -0
  303. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → mPZbi5BH9dwokaPZlrYuQ}/_ssgManifest.js +0 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=style.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/style.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,63 @@
1
+ // GSD2 - Tests for terminal style primitives
2
+ import assert from "node:assert/strict";
3
+ import { describe, test } from "node:test";
4
+ import stripAnsi from "strip-ansi";
5
+ import { style, visibleWidth } from "../index.js";
6
+ describe("style", () => {
7
+ test("renders rule frames with title, right title, and body gutter", () => {
8
+ const lines = style()
9
+ .border("rule")
10
+ .title("• Tool Bash")
11
+ .titleRight("Running")
12
+ .render(["$ npm test"], 40);
13
+ const plain = lines.map((line) => stripAnsi(line));
14
+ assert.match(plain[0], /^─+$/);
15
+ assert.equal(visibleWidth(plain[0]), 40);
16
+ assert.ok(plain[1].includes("• Tool Bash"));
17
+ assert.ok(plain[1].includes("Running"));
18
+ assert.equal(visibleWidth(plain[1]), 40);
19
+ assert.ok(plain[2].startsWith("│ "));
20
+ assert.ok(plain[2].includes("$ npm test"));
21
+ });
22
+ test("renders boxed rounded borders with padded content", () => {
23
+ const lines = style()
24
+ .border("rounded")
25
+ .paddingX(1)
26
+ .render(["Done"], 12)
27
+ .map((line) => stripAnsi(line));
28
+ assert.equal(lines[0], "╭──────────╮");
29
+ assert.equal(lines[1], "│ Done │");
30
+ assert.equal(lines[2], "╰──────────╯");
31
+ });
32
+ test("truncates content to the available visible width", () => {
33
+ const plain = style().border("rule").render(["abcdefghij"], 7).map((line) => stripAnsi(line));
34
+ assert.equal(plain[1], "│ abcde");
35
+ assert.equal(visibleWidth(plain[1]), 7);
36
+ });
37
+ test("renders minimal left-rule surfaces", () => {
38
+ const plain = style().border("minimal").title("note").render(["No full card"], 20).map((line) => stripAnsi(line));
39
+ assert.equal(plain[0], "│ note ");
40
+ assert.equal(plain[1], "│ No full card ");
41
+ });
42
+ test("applies dashboard density and body gutters", () => {
43
+ const plain = style()
44
+ .border("single")
45
+ .density("dashboard")
46
+ .bodyGutter("· ")
47
+ .render(["body"], 14)
48
+ .map((line) => stripAnsi(line));
49
+ assert.equal(plain[0], "┌────────────┐");
50
+ assert.equal(plain[1], "│ │");
51
+ assert.equal(plain[2], "│· body │");
52
+ assert.equal(plain[3], "│ │");
53
+ assert.equal(plain[4], "└────────────┘");
54
+ });
55
+ test("passes tone to toneColor when no explicit border color is set", () => {
56
+ const lines = style()
57
+ .border("minimal")
58
+ .tone("success", (tone, text) => `[${tone}]${text}`)
59
+ .render(["ok"], 8);
60
+ assert.equal(lines[0], "[success]│ ok ");
61
+ });
62
+ });
63
+ //# sourceMappingURL=style.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.test.js","sourceRoot":"","sources":["../../src/__tests__/style.test.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAE7C,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAElD,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACtB,IAAI,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACzE,MAAM,KAAK,GAAG,KAAK,EAAE;aACnB,MAAM,CAAC,MAAM,CAAC;aACd,KAAK,CAAC,aAAa,CAAC;aACpB,UAAU,CAAC,SAAS,CAAC;aACrB,MAAM,CAAC,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;QAE7B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC9D,MAAM,KAAK,GAAG,KAAK,EAAE;aACnB,MAAM,CAAC,SAAS,CAAC;aACjB,QAAQ,CAAC,CAAC,CAAC;aACX,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;aACpB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAEjC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC7D,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAE9F,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC/C,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAElH,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACvD,MAAM,KAAK,GAAG,KAAK,EAAE;aACnB,MAAM,CAAC,QAAQ,CAAC;aAChB,OAAO,CAAC,WAAW,CAAC;aACpB,UAAU,CAAC,IAAI,CAAC;aAChB,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;aACpB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAEjC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,+DAA+D,EAAE,GAAG,EAAE;QAC1E,MAAM,KAAK,GAAG,KAAK,EAAE;aACnB,MAAM,CAAC,SAAS,CAAC;aACjB,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;aACnD,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAEpB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["// GSD2 - Tests for terminal style primitives\n\nimport assert from \"node:assert/strict\";\nimport { describe, test } from \"node:test\";\nimport stripAnsi from \"strip-ansi\";\n\nimport { style, visibleWidth } from \"../index.js\";\n\ndescribe(\"style\", () => {\n\ttest(\"renders rule frames with title, right title, and body gutter\", () => {\n\t\tconst lines = style()\n\t\t\t.border(\"rule\")\n\t\t\t.title(\"• Tool Bash\")\n\t\t\t.titleRight(\"Running\")\n\t\t\t.render([\"$ npm test\"], 40);\n\n\t\tconst plain = lines.map((line) => stripAnsi(line));\n\t\tassert.match(plain[0], /^─+$/);\n\t\tassert.equal(visibleWidth(plain[0]), 40);\n\t\tassert.ok(plain[1].includes(\"• Tool Bash\"));\n\t\tassert.ok(plain[1].includes(\"Running\"));\n\t\tassert.equal(visibleWidth(plain[1]), 40);\n\t\tassert.ok(plain[2].startsWith(\"│ \"));\n\t\tassert.ok(plain[2].includes(\"$ npm test\"));\n\t});\n\n\ttest(\"renders boxed rounded borders with padded content\", () => {\n\t\tconst lines = style()\n\t\t\t.border(\"rounded\")\n\t\t\t.paddingX(1)\n\t\t\t.render([\"Done\"], 12)\n\t\t\t.map((line) => stripAnsi(line));\n\n\t\tassert.equal(lines[0], \"╭──────────╮\");\n\t\tassert.equal(lines[1], \"│ Done │\");\n\t\tassert.equal(lines[2], \"╰──────────╯\");\n\t});\n\n\ttest(\"truncates content to the available visible width\", () => {\n\t\tconst plain = style().border(\"rule\").render([\"abcdefghij\"], 7).map((line) => stripAnsi(line));\n\n\t\tassert.equal(plain[1], \"│ abcde\");\n\t\tassert.equal(visibleWidth(plain[1]), 7);\n\t});\n\n\ttest(\"renders minimal left-rule surfaces\", () => {\n\t\tconst plain = style().border(\"minimal\").title(\"note\").render([\"No full card\"], 20).map((line) => stripAnsi(line));\n\n\t\tassert.equal(plain[0], \"│ note \");\n\t\tassert.equal(plain[1], \"│ No full card \");\n\t});\n\n\ttest(\"applies dashboard density and body gutters\", () => {\n\t\tconst plain = style()\n\t\t\t.border(\"single\")\n\t\t\t.density(\"dashboard\")\n\t\t\t.bodyGutter(\"· \")\n\t\t\t.render([\"body\"], 14)\n\t\t\t.map((line) => stripAnsi(line));\n\n\t\tassert.equal(plain[0], \"┌────────────┐\");\n\t\tassert.equal(plain[1], \"│ │\");\n\t\tassert.equal(plain[2], \"│· body │\");\n\t\tassert.equal(plain[3], \"│ │\");\n\t\tassert.equal(plain[4], \"└────────────┘\");\n\t});\n\n\ttest(\"passes tone to toneColor when no explicit border color is set\", () => {\n\t\tconst lines = style()\n\t\t\t.border(\"minimal\")\n\t\t\t.tone(\"success\", (tone, text) => `[${tone}]${text}`)\n\t\t\t.render([\"ok\"], 8);\n\n\t\tassert.equal(lines[0], \"[success]│ ok \");\n\t});\n});\n"]}
@@ -1,7 +1,8 @@
1
+ // GSD-2 + packages/pi-tui/src/__tests__/tui.test.ts - Regression coverage for the TUI renderer and container lifecycle.
1
2
  import assert from "node:assert/strict";
2
3
  import { describe, it } from "node:test";
3
- import { Container, TUI } from "../tui.js";
4
- function makeTerminal() {
4
+ import { Container, CURSOR_MARKER, TUI } from "../tui.js";
5
+ function makeTerminal(writes) {
5
6
  return {
6
7
  isTTY: true,
7
8
  columns: 80,
@@ -10,7 +11,9 @@ function makeTerminal() {
10
11
  start() { },
11
12
  stop() { },
12
13
  drainInput: async () => { },
13
- write() { },
14
+ write(data) {
15
+ writes?.push(data);
16
+ },
14
17
  moveBy() { },
15
18
  hideCursor() { },
16
19
  showCursor() { },
@@ -39,6 +42,24 @@ function makeTerminal() {
39
42
  // extracting the debounce decision into a pure helper) — deferred to a
40
43
  // separate refactor PR rather than shipping a tautology. See #4794.
41
44
  describe("TUI", () => {
45
+ it("updates an editor line from the real hardware cursor row", () => {
46
+ const writes = [];
47
+ const terminal = makeTerminal(writes);
48
+ let value = "input";
49
+ const tui = new TUI(terminal);
50
+ tui.addChild({
51
+ render: () => ["top", `${value}${CURSOR_MARKER}`, " GSD No project loaded - run /gsd to start"],
52
+ invalidate() { },
53
+ });
54
+ const anyTui = tui;
55
+ anyTui.doRender();
56
+ const writeCountAfterFirstRender = writes.length;
57
+ value = "input x";
58
+ anyTui.doRender();
59
+ const renderWrite = writes[writeCountAfterFirstRender];
60
+ assert.ok(renderWrite.startsWith("\x1b[?2026h\r"), "editor diff should start at the current cursor row");
61
+ assert.ok(!renderWrite.startsWith("\x1b[?2026h\x1b[1A\r"), "editor diff must not move above the cursor row");
62
+ });
42
63
  it("does not swallow a bare Escape keypress while waiting for the cell-size response", () => {
43
64
  const tui = new TUI(makeTerminal());
44
65
  const received = [];
@@ -1 +1 @@
1
- {"version":3,"file":"tui.test.js","sourceRoot":"","sources":["../../src/__tests__/tui.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAI3C,SAAS,YAAY;IACpB,OAAO;QACN,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,EAAE;QACX,IAAI,EAAE,EAAE;QACR,mBAAmB,EAAE,KAAK;QAC1B,KAAK,KAAI,CAAC;QACV,IAAI,KAAI,CAAC;QACT,UAAU,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC1B,KAAK,KAAI,CAAC;QACV,MAAM,KAAI,CAAC;QACX,UAAU,KAAI,CAAC;QACf,UAAU,KAAI,CAAC;QACf,SAAS,KAAI,CAAC;QACd,eAAe,KAAI,CAAC;QACpB,WAAW,KAAI,CAAC;QAChB,QAAQ,KAAI,CAAC;KACb,CAAC;AACH,CAAC;AAED,mEAAmE;AACnE,EAAE;AACF,sEAAsE;AACtE,qEAAqE;AACrE,kEAAkE;AAClE,iEAAiE;AACjE,0DAA0D;AAC1D,wDAAwD;AACxD,EAAE;AACF,sEAAsE;AACtE,sEAAsE;AACtE,mEAAmE;AACnE,uEAAuE;AACvE,wBAAwB;AACxB,EAAE;AACF,kEAAkE;AAClE,uEAAuE;AACvE,oEAAoE;AAEpE,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;IACpB,EAAE,CAAC,kFAAkF,EAAE,GAAG,EAAE;QAC3F,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;QACpC,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,GAAG,CAAC,QAAQ,CAAC;YACZ,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE;YAChB,WAAW,EAAE,CAAC,IAAY,EAAE,EAAE;gBAC7B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;YACD,UAAU,KAAI,CAAC;SACf,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,GAAU,CAAC;QAC1B,MAAM,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACnC,MAAM,CAAC,WAAW,GAAG,EAAE,CAAC;QAExB,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE3B,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IAC1B,SAAS,mBAAmB,CAAC,OAA6B;QACzD,OAAO;YACN,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE;YAChB,UAAU,KAAI,CAAC;YACf,OAAO;gBACN,OAAO,CAAC,QAAQ,EAAE,CAAC;YACpB,CAAC;SACD,CAAC;IACH,CAAC;IAED,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QACnE,MAAM,CAAC,GAAG,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QAChC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;QAEzC,CAAC,CAAC,cAAc,EAAE,CAAC;QAEnB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACtF,MAAM,CAAC,GAAG,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QAChC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;QAEzC,CAAC,CAAC,KAAK,EAAE,CAAC;QAEV,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\n\nimport { Container, TUI } from \"../tui.js\";\nimport type { Component } from \"../tui.js\";\nimport type { Terminal } from \"../terminal.js\";\n\nfunction makeTerminal(): Terminal {\n\treturn {\n\t\tisTTY: true,\n\t\tcolumns: 80,\n\t\trows: 24,\n\t\tkittyProtocolActive: false,\n\t\tstart() {},\n\t\tstop() {},\n\t\tdrainInput: async () => {},\n\t\twrite() {},\n\t\tmoveBy() {},\n\t\thideCursor() {},\n\t\tshowCursor() {},\n\t\tclearLine() {},\n\t\tclearFromCursor() {},\n\t\tclearScreen() {},\n\t\tsetTitle() {},\n\t};\n}\n\n// TUI clearOnShrink debounce — tests removed in #4794 (ref #4784).\n//\n// The previous tests mutated private fields (`_shrinkDebounceActive`,\n// `maxLinesRendered`) and then asserted the values they just wrote —\n// pure tautologies that never exercised the real debounce path in\n// `renderNow()` (tui.ts:734-754). A regression that narrowed the\n// condition, reversed the flag flip, or dropped the \"keep\n// maxLinesRendered\" rule would have passed all of them.\n//\n// A proper test would (a) render a component that produces N lines to\n// establish `maxLinesRendered`, (b) swap in a component that produces\n// N-k lines to trigger the shrink branch, and (c) observe terminal\n// writes to confirm the debounce defers/commits the full redraw on the\n// expected render call.\n//\n// That test setup requires exposing enough of the render path (or\n// extracting the debounce decision into a pure helper) — deferred to a\n// separate refactor PR rather than shipping a tautology. See #4794.\n\ndescribe(\"TUI\", () => {\n\tit(\"does not swallow a bare Escape keypress while waiting for the cell-size response\", () => {\n\t\tconst tui = new TUI(makeTerminal());\n\t\tconst received: string[] = [];\n\n\t\ttui.setFocus({\n\t\t\trender: () => [],\n\t\t\thandleInput: (data: string) => {\n\t\t\t\treceived.push(data);\n\t\t\t},\n\t\t\tinvalidate() {},\n\t\t});\n\n\t\tconst anyTui = tui as any;\n\t\tanyTui.cellSizeQueryPending = true;\n\t\tanyTui.inputBuffer = \"\";\n\n\t\tanyTui.handleInput(\"\\x1b\");\n\n\t\tassert.deepEqual(received, [\"\\x1b\"]);\n\t\tassert.equal(anyTui.cellSizeQueryPending, false);\n\t\tassert.equal(anyTui.inputBuffer, \"\");\n\t});\n});\n\ndescribe(\"Container\", () => {\n\tfunction makeDisposableChild(counter: { disposed: number }): Component & { dispose(): void } {\n\t\treturn {\n\t\t\trender: () => [],\n\t\t\tinvalidate() {},\n\t\t\tdispose() {\n\t\t\t\tcounter.disposed++;\n\t\t\t},\n\t\t};\n\t}\n\n\tit(\"detachChildren() removes children without disposing them\", () => {\n\t\tconst c = new Container();\n\t\tconst counter = { disposed: 0 };\n\t\tc.addChild(makeDisposableChild(counter));\n\t\tc.addChild(makeDisposableChild(counter));\n\n\t\tc.detachChildren();\n\n\t\tassert.equal(c.children.length, 0);\n\t\tassert.equal(counter.disposed, 0);\n\t});\n\n\tit(\"clear() still disposes children (regression guard for detach/dispose split)\", () => {\n\t\tconst c = new Container();\n\t\tconst counter = { disposed: 0 };\n\t\tc.addChild(makeDisposableChild(counter));\n\t\tc.addChild(makeDisposableChild(counter));\n\n\t\tc.clear();\n\n\t\tassert.equal(c.children.length, 0);\n\t\tassert.equal(counter.disposed, 2);\n\t});\n});\n"]}
1
+ {"version":3,"file":"tui.test.js","sourceRoot":"","sources":["../../src/__tests__/tui.test.ts"],"names":[],"mappings":"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","sourcesContent":["// GSD-2 + packages/pi-tui/src/__tests__/tui.test.ts - Regression coverage for the TUI renderer and container lifecycle.\n\nimport assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\n\nimport { Container, CURSOR_MARKER, TUI } from \"../tui.js\";\nimport type { Component } from \"../tui.js\";\nimport type { Terminal } from \"../terminal.js\";\n\nfunction makeTerminal(writes?: string[]): Terminal {\n\treturn {\n\t\tisTTY: true,\n\t\tcolumns: 80,\n\t\trows: 24,\n\t\tkittyProtocolActive: false,\n\t\tstart() {},\n\t\tstop() {},\n\t\tdrainInput: async () => {},\n\t\twrite(data: string) {\n\t\t\twrites?.push(data);\n\t\t},\n\t\tmoveBy() {},\n\t\thideCursor() {},\n\t\tshowCursor() {},\n\t\tclearLine() {},\n\t\tclearFromCursor() {},\n\t\tclearScreen() {},\n\t\tsetTitle() {},\n\t};\n}\n\n// TUI clearOnShrink debounce — tests removed in #4794 (ref #4784).\n//\n// The previous tests mutated private fields (`_shrinkDebounceActive`,\n// `maxLinesRendered`) and then asserted the values they just wrote —\n// pure tautologies that never exercised the real debounce path in\n// `renderNow()` (tui.ts:734-754). A regression that narrowed the\n// condition, reversed the flag flip, or dropped the \"keep\n// maxLinesRendered\" rule would have passed all of them.\n//\n// A proper test would (a) render a component that produces N lines to\n// establish `maxLinesRendered`, (b) swap in a component that produces\n// N-k lines to trigger the shrink branch, and (c) observe terminal\n// writes to confirm the debounce defers/commits the full redraw on the\n// expected render call.\n//\n// That test setup requires exposing enough of the render path (or\n// extracting the debounce decision into a pure helper) — deferred to a\n// separate refactor PR rather than shipping a tautology. See #4794.\n\ndescribe(\"TUI\", () => {\n\tit(\"updates an editor line from the real hardware cursor row\", () => {\n\t\tconst writes: string[] = [];\n\t\tconst terminal = makeTerminal(writes);\n\t\tlet value = \"input\";\n\t\tconst tui = new TUI(terminal);\n\t\ttui.addChild({\n\t\t\trender: () => [\"top\", `${value}${CURSOR_MARKER}`, \" GSD No project loaded - run /gsd to start\"],\n\t\t\tinvalidate() {},\n\t\t});\n\t\tconst anyTui = tui as any;\n\n\t\tanyTui.doRender();\n\t\tconst writeCountAfterFirstRender = writes.length;\n\n\t\tvalue = \"input x\";\n\t\tanyTui.doRender();\n\n\t\tconst renderWrite = writes[writeCountAfterFirstRender];\n\t\tassert.ok(renderWrite.startsWith(\"\\x1b[?2026h\\r\"), \"editor diff should start at the current cursor row\");\n\t\tassert.ok(!renderWrite.startsWith(\"\\x1b[?2026h\\x1b[1A\\r\"), \"editor diff must not move above the cursor row\");\n\t});\n\n\tit(\"does not swallow a bare Escape keypress while waiting for the cell-size response\", () => {\n\t\tconst tui = new TUI(makeTerminal());\n\t\tconst received: string[] = [];\n\n\t\ttui.setFocus({\n\t\t\trender: () => [],\n\t\t\thandleInput: (data: string) => {\n\t\t\t\treceived.push(data);\n\t\t\t},\n\t\t\tinvalidate() {},\n\t\t});\n\n\t\tconst anyTui = tui as any;\n\t\tanyTui.cellSizeQueryPending = true;\n\t\tanyTui.inputBuffer = \"\";\n\n\t\tanyTui.handleInput(\"\\x1b\");\n\n\t\tassert.deepEqual(received, [\"\\x1b\"]);\n\t\tassert.equal(anyTui.cellSizeQueryPending, false);\n\t\tassert.equal(anyTui.inputBuffer, \"\");\n\t});\n});\n\ndescribe(\"Container\", () => {\n\tfunction makeDisposableChild(counter: { disposed: number }): Component & { dispose(): void } {\n\t\treturn {\n\t\t\trender: () => [],\n\t\t\tinvalidate() {},\n\t\t\tdispose() {\n\t\t\t\tcounter.disposed++;\n\t\t\t},\n\t\t};\n\t}\n\n\tit(\"detachChildren() removes children without disposing them\", () => {\n\t\tconst c = new Container();\n\t\tconst counter = { disposed: 0 };\n\t\tc.addChild(makeDisposableChild(counter));\n\t\tc.addChild(makeDisposableChild(counter));\n\n\t\tc.detachChildren();\n\n\t\tassert.equal(c.children.length, 0);\n\t\tassert.equal(counter.disposed, 0);\n\t});\n\n\tit(\"clear() still disposes children (regression guard for detach/dispose split)\", () => {\n\t\tconst c = new Container();\n\t\tconst counter = { disposed: 0 };\n\t\tc.addChild(makeDisposableChild(counter));\n\t\tc.addChild(makeDisposableChild(counter));\n\n\t\tc.clear();\n\n\t\tassert.equal(c.children.length, 0);\n\t\tassert.equal(counter.disposed, 2);\n\t});\n});\n"]}
@@ -1,3 +1,4 @@
1
+ export { style, TerminalStyle, type TerminalBorderStyle, type TerminalDensity, type TerminalStyleSpec, type TerminalTone, } from "./style.js";
1
2
  export { type AutocompleteItem, type AutocompleteProvider, CombinedAutocompleteProvider, type SlashCommand, } from "./autocomplete.js";
2
3
  export { Box } from "./components/box.js";
3
4
  export { CancellableLoader } from "./components/cancellable-loader.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,4BAA4B,EAC5B,KAAK,YAAY,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,KAAK,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,gBAAgB,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAChG,OAAO,EAAE,KAAK,WAAW,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,EAAE,KAAK,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,EACN,0BAA0B,EAC1B,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EACH,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEnG,OAAO,EAAE,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE/D,OAAO,EACN,eAAe,EACf,KAAK,cAAc,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,aAAa,EACb,WAAW,EACX,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,oBAAoB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EACT,aAAa,EACb,KAAK,SAAS,EACd,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,GAAG,GACH,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,KAAK,EACL,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,YAAY,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,4BAA4B,EAC5B,KAAK,YAAY,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,KAAK,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,gBAAgB,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAChG,OAAO,EAAE,KAAK,WAAW,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,EAAE,KAAK,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,EACN,0BAA0B,EAC1B,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EACH,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEnG,OAAO,EAAE,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE/D,OAAO,EACN,eAAe,EACf,KAAK,cAAc,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,aAAa,EACb,WAAW,EACX,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,oBAAoB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EACT,aAAa,EACb,KAAK,SAAS,EACd,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,GAAG,GACH,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
@@ -1,4 +1,6 @@
1
1
  // Core TUI interfaces and classes
2
+ // Style primitives
3
+ export { style, TerminalStyle, } from "./style.js";
2
4
  // Autocomplete support
3
5
  export { CombinedAutocompleteProvider, } from "./autocomplete.js";
4
6
  // Components
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,uBAAuB;AACvB,OAAO,EAGN,4BAA4B,GAE5B,MAAM,mBAAmB,CAAC;AAC3B,aAAa;AACb,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,MAAM,EAAwC,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,KAAK,EAAsC,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAyB,QAAQ,EAAsB,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAmB,UAAU,EAAwB,MAAM,6BAA6B,CAAC;AAChG,OAAO,EAAoB,YAAY,EAA0B,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAG/D,iBAAiB;AACjB,OAAO,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,cAAc;AACd,OAAO,EACN,0BAA0B,EAG1B,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,0BAA0B;AAC1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EAGH,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AACnB,sCAAsC;AACtC,OAAO,EAAE,WAAW,EAAqD,MAAM,mBAAmB,CAAC;AACnG,yCAAyC;AACzC,OAAO,EAAE,eAAe,EAAiB,MAAM,eAAe,CAAC;AAC/D,yBAAyB;AACzB,OAAO,EACN,eAAe,EAEf,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAIlB,aAAa,EACb,WAAW,EACX,sBAAsB,EACtB,iBAAiB,GAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEN,SAAS,EACT,aAAa,EAEb,WAAW,EAMX,GAAG,GACH,MAAM,UAAU,CAAC;AAClB,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC","sourcesContent":["// Core TUI interfaces and classes\n\n// Autocomplete support\nexport {\n\ttype AutocompleteItem,\n\ttype AutocompleteProvider,\n\tCombinedAutocompleteProvider,\n\ttype SlashCommand,\n} from \"./autocomplete.js\";\n// Components\nexport { Box } from \"./components/box.js\";\nexport { CancellableLoader } from \"./components/cancellable-loader.js\";\nexport { Editor, type EditorOptions, type EditorTheme } from \"./components/editor.js\";\nexport { Image, type ImageOptions, type ImageTheme } from \"./components/image.js\";\nexport { Input } from \"./components/input.js\";\nexport { Loader } from \"./components/loader.js\";\nexport { type DefaultTextStyle, Markdown, type MarkdownTheme } from \"./components/markdown.js\";\nexport { type SelectItem, SelectList, type SelectListTheme } from \"./components/select-list.js\";\nexport { type SettingItem, SettingsList, type SettingsListTheme } from \"./components/settings-list.js\";\nexport { Spacer } from \"./components/spacer.js\";\nexport { Text } from \"./components/text.js\";\nexport { TruncatedText } from \"./components/truncated-text.js\";\n// Editor component interface (for custom editors)\nexport type { EditorComponent } from \"./editor-component.js\";\n// Fuzzy matching\nexport { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from \"./fuzzy.js\";\n// Keybindings\nexport {\n\tDEFAULT_EDITOR_KEYBINDINGS,\n\ttype EditorAction,\n\ttype EditorKeybindingsConfig,\n\tEditorKeybindingsManager,\n\tgetEditorKeybindings,\n\tsetEditorKeybindings,\n} from \"./keybindings.js\";\n// Keyboard input handling\nexport {\n\tdecodeKittyPrintable,\n\tisKeyRelease,\n\tisKeyRepeat,\n\tisKittyProtocolActive,\n\tKey,\n\ttype KeyEventType,\n\ttype KeyId,\n\tmatchesKey,\n\tparseKey,\n\tsetKittyProtocolActive,\n} from \"./keys.js\";\n// Input buffering for batch splitting\nexport { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from \"./stdin-buffer.js\";\n// Terminal interface and implementations\nexport { ProcessTerminal, type Terminal } from \"./terminal.js\";\n// Terminal image support\nexport {\n\tallocateImageId,\n\ttype CellDimensions,\n\tcalculateImageRows,\n\tdeleteAllKittyImages,\n\tdeleteKittyImage,\n\tdetectCapabilities,\n\tencodeITerm2,\n\tencodeKitty,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetImageDimensions,\n\ttype ImageDimensions,\n\ttype ImageProtocol,\n\ttype ImageRenderOptions,\n\timageFallback,\n\trenderImage,\n\tresetCapabilitiesCache,\n\tsetCellDimensions,\n\ttype TerminalCapabilities,\n} from \"./terminal-image.js\";\nexport {\n\ttype Component,\n\tContainer,\n\tCURSOR_MARKER,\n\ttype Focusable,\n\tisFocusable,\n\ttype OverlayAnchor,\n\ttype OverlayHandle,\n\ttype OverlayMargin,\n\ttype OverlayOptions,\n\ttype SizeValue,\n\tTUI,\n} from \"./tui.js\";\n// Utilities\nexport { truncateToWidth, visibleWidth, wrapTextWithAnsi } from \"./utils.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,mBAAmB;AACnB,OAAO,EACN,KAAK,EACL,aAAa,GAKb,MAAM,YAAY,CAAC;AACpB,uBAAuB;AACvB,OAAO,EAGN,4BAA4B,GAE5B,MAAM,mBAAmB,CAAC;AAC3B,aAAa;AACb,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,MAAM,EAAwC,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,KAAK,EAAsC,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAyB,QAAQ,EAAsB,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAmB,UAAU,EAAwB,MAAM,6BAA6B,CAAC;AAChG,OAAO,EAAoB,YAAY,EAA0B,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAG/D,iBAAiB;AACjB,OAAO,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,cAAc;AACd,OAAO,EACN,0BAA0B,EAG1B,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,0BAA0B;AAC1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EAGH,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AACnB,sCAAsC;AACtC,OAAO,EAAE,WAAW,EAAqD,MAAM,mBAAmB,CAAC;AACnG,yCAAyC;AACzC,OAAO,EAAE,eAAe,EAAiB,MAAM,eAAe,CAAC;AAC/D,yBAAyB;AACzB,OAAO,EACN,eAAe,EAEf,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAIlB,aAAa,EACb,WAAW,EACX,sBAAsB,EACtB,iBAAiB,GAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEN,SAAS,EACT,aAAa,EAEb,WAAW,EAMX,GAAG,GACH,MAAM,UAAU,CAAC;AAClB,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC","sourcesContent":["// Core TUI interfaces and classes\n\n// Style primitives\nexport {\n\tstyle,\n\tTerminalStyle,\n\ttype TerminalBorderStyle,\n\ttype TerminalDensity,\n\ttype TerminalStyleSpec,\n\ttype TerminalTone,\n} from \"./style.js\";\n// Autocomplete support\nexport {\n\ttype AutocompleteItem,\n\ttype AutocompleteProvider,\n\tCombinedAutocompleteProvider,\n\ttype SlashCommand,\n} from \"./autocomplete.js\";\n// Components\nexport { Box } from \"./components/box.js\";\nexport { CancellableLoader } from \"./components/cancellable-loader.js\";\nexport { Editor, type EditorOptions, type EditorTheme } from \"./components/editor.js\";\nexport { Image, type ImageOptions, type ImageTheme } from \"./components/image.js\";\nexport { Input } from \"./components/input.js\";\nexport { Loader } from \"./components/loader.js\";\nexport { type DefaultTextStyle, Markdown, type MarkdownTheme } from \"./components/markdown.js\";\nexport { type SelectItem, SelectList, type SelectListTheme } from \"./components/select-list.js\";\nexport { type SettingItem, SettingsList, type SettingsListTheme } from \"./components/settings-list.js\";\nexport { Spacer } from \"./components/spacer.js\";\nexport { Text } from \"./components/text.js\";\nexport { TruncatedText } from \"./components/truncated-text.js\";\n// Editor component interface (for custom editors)\nexport type { EditorComponent } from \"./editor-component.js\";\n// Fuzzy matching\nexport { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from \"./fuzzy.js\";\n// Keybindings\nexport {\n\tDEFAULT_EDITOR_KEYBINDINGS,\n\ttype EditorAction,\n\ttype EditorKeybindingsConfig,\n\tEditorKeybindingsManager,\n\tgetEditorKeybindings,\n\tsetEditorKeybindings,\n} from \"./keybindings.js\";\n// Keyboard input handling\nexport {\n\tdecodeKittyPrintable,\n\tisKeyRelease,\n\tisKeyRepeat,\n\tisKittyProtocolActive,\n\tKey,\n\ttype KeyEventType,\n\ttype KeyId,\n\tmatchesKey,\n\tparseKey,\n\tsetKittyProtocolActive,\n} from \"./keys.js\";\n// Input buffering for batch splitting\nexport { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from \"./stdin-buffer.js\";\n// Terminal interface and implementations\nexport { ProcessTerminal, type Terminal } from \"./terminal.js\";\n// Terminal image support\nexport {\n\tallocateImageId,\n\ttype CellDimensions,\n\tcalculateImageRows,\n\tdeleteAllKittyImages,\n\tdeleteKittyImage,\n\tdetectCapabilities,\n\tencodeITerm2,\n\tencodeKitty,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetImageDimensions,\n\ttype ImageDimensions,\n\ttype ImageProtocol,\n\ttype ImageRenderOptions,\n\timageFallback,\n\trenderImage,\n\tresetCapabilitiesCache,\n\tsetCellDimensions,\n\ttype TerminalCapabilities,\n} from \"./terminal-image.js\";\nexport {\n\ttype Component,\n\tContainer,\n\tCURSOR_MARKER,\n\ttype Focusable,\n\tisFocusable,\n\ttype OverlayAnchor,\n\ttype OverlayHandle,\n\ttype OverlayMargin,\n\ttype OverlayOptions,\n\ttype SizeValue,\n\tTUI,\n} from \"./tui.js\";\n// Utilities\nexport { truncateToWidth, visibleWidth, wrapTextWithAnsi } from \"./utils.js\";\n"]}
@@ -0,0 +1,41 @@
1
+ export type TerminalBorderStyle = "none" | "rule" | "single" | "rounded" | "heavy" | "minimal";
2
+ export type TerminalDensity = "compact" | "comfortable" | "dashboard";
3
+ export type TerminalTone = "default" | "muted" | "running" | "success" | "error" | "current";
4
+ export interface TerminalStyleSpec {
5
+ width?: number;
6
+ paddingX?: number;
7
+ paddingY?: number;
8
+ border?: TerminalBorderStyle;
9
+ density?: TerminalDensity;
10
+ tone?: TerminalTone;
11
+ borderColor?: (text: string) => string;
12
+ foreground?: (text: string) => string;
13
+ toneColor?: (tone: TerminalTone, text: string) => string;
14
+ title?: string;
15
+ titleRight?: string;
16
+ titleColor?: (text: string) => string;
17
+ titleRightColor?: (text: string) => string;
18
+ bodyGutter?: string;
19
+ }
20
+ export declare class TerminalStyle {
21
+ private readonly spec;
22
+ constructor(spec?: TerminalStyleSpec);
23
+ width(width: number): TerminalStyle;
24
+ padding(x: number, y?: number): TerminalStyle;
25
+ paddingX(paddingX: number): TerminalStyle;
26
+ paddingY(paddingY: number): TerminalStyle;
27
+ border(border: TerminalBorderStyle): TerminalStyle;
28
+ density(density: TerminalDensity): TerminalStyle;
29
+ tone(tone: TerminalTone, toneColor?: (tone: TerminalTone, text: string) => string): TerminalStyle;
30
+ borderColor(borderColor: (text: string) => string): TerminalStyle;
31
+ foreground(foreground: (text: string) => string): TerminalStyle;
32
+ toneColor(toneColor: (tone: TerminalTone, text: string) => string): TerminalStyle;
33
+ title(title: string, titleColor?: (text: string) => string): TerminalStyle;
34
+ titleRight(titleRight: string, titleRightColor?: (text: string) => string): TerminalStyle;
35
+ rightTitle(titleRight: string, titleRightColor?: (text: string) => string): TerminalStyle;
36
+ bodyGutter(bodyGutter: string): TerminalStyle;
37
+ render(contentLines: string[], width?: number): string[];
38
+ private renderTitleRows;
39
+ }
40
+ export declare function style(spec?: TerminalStyleSpec): TerminalStyle;
41
+ //# sourceMappingURL=style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../src/style.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAC/F,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;AACtE,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7F,MAAM,WAAW,iBAAiB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACvC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAwDD,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoB;gBAE7B,IAAI,GAAE,iBAAsB;IAIxC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa;IAInC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,SAAI,GAAG,aAAa;IAIxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IAIzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IAIzC,MAAM,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa;IAIlD,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,aAAa;IAIhD,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAIjG,WAAW,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAIjE,UAAU,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAI/D,SAAS,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAIjF,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAI1E,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAIzF,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAIzF,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa;IAI7C,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAiExD,OAAO,CAAC,eAAe;CAavB;AAED,wBAAgB,KAAK,CAAC,IAAI,GAAE,iBAAsB,GAAG,aAAa,CAEjE"}
@@ -0,0 +1,158 @@
1
+ // GSD2 - Terminal style primitives for framed TUI surfaces
2
+ import { truncateToWidth, visibleWidth } from "./utils.js";
3
+ const BORDER_CHARS = {
4
+ single: {
5
+ topLeft: "┌",
6
+ topRight: "┐",
7
+ bottomLeft: "└",
8
+ bottomRight: "┘",
9
+ horizontal: "─",
10
+ vertical: "│",
11
+ },
12
+ rounded: {
13
+ topLeft: "╭",
14
+ topRight: "╮",
15
+ bottomLeft: "╰",
16
+ bottomRight: "╯",
17
+ horizontal: "─",
18
+ vertical: "│",
19
+ },
20
+ heavy: {
21
+ topLeft: "┏",
22
+ topRight: "┓",
23
+ bottomLeft: "┗",
24
+ bottomRight: "┛",
25
+ horizontal: "━",
26
+ vertical: "┃",
27
+ },
28
+ };
29
+ const DENSITY_PADDING = {
30
+ compact: { x: 0, y: 0 },
31
+ comfortable: { x: 1, y: 0 },
32
+ dashboard: { x: 1, y: 1 },
33
+ };
34
+ function padVisible(line, width) {
35
+ return line + " ".repeat(Math.max(0, width - visibleWidth(line)));
36
+ }
37
+ function color(fn, text) {
38
+ return fn ? fn(text) : text;
39
+ }
40
+ function normalizeWidth(spec, width) {
41
+ return Math.max(1, Math.floor(width ?? spec.width ?? 80));
42
+ }
43
+ export class TerminalStyle {
44
+ constructor(spec = {}) {
45
+ this.spec = { ...spec };
46
+ }
47
+ width(width) {
48
+ return new TerminalStyle({ ...this.spec, width });
49
+ }
50
+ padding(x, y = x) {
51
+ return new TerminalStyle({ ...this.spec, paddingX: x, paddingY: y });
52
+ }
53
+ paddingX(paddingX) {
54
+ return new TerminalStyle({ ...this.spec, paddingX });
55
+ }
56
+ paddingY(paddingY) {
57
+ return new TerminalStyle({ ...this.spec, paddingY });
58
+ }
59
+ border(border) {
60
+ return new TerminalStyle({ ...this.spec, border });
61
+ }
62
+ density(density) {
63
+ return new TerminalStyle({ ...this.spec, density });
64
+ }
65
+ tone(tone, toneColor) {
66
+ return new TerminalStyle({ ...this.spec, tone, toneColor });
67
+ }
68
+ borderColor(borderColor) {
69
+ return new TerminalStyle({ ...this.spec, borderColor });
70
+ }
71
+ foreground(foreground) {
72
+ return new TerminalStyle({ ...this.spec, foreground });
73
+ }
74
+ toneColor(toneColor) {
75
+ return new TerminalStyle({ ...this.spec, toneColor });
76
+ }
77
+ title(title, titleColor) {
78
+ return new TerminalStyle({ ...this.spec, title, titleColor });
79
+ }
80
+ titleRight(titleRight, titleRightColor) {
81
+ return new TerminalStyle({ ...this.spec, titleRight, titleRightColor });
82
+ }
83
+ rightTitle(titleRight, titleRightColor) {
84
+ return this.titleRight(titleRight, titleRightColor);
85
+ }
86
+ bodyGutter(bodyGutter) {
87
+ return new TerminalStyle({ ...this.spec, bodyGutter });
88
+ }
89
+ render(contentLines, width) {
90
+ const outerWidth = normalizeWidth(this.spec, width);
91
+ const border = this.spec.border ?? "none";
92
+ const densityPadding = DENSITY_PADDING[this.spec.density ?? "compact"];
93
+ const paddingX = Math.max(0, Math.floor(this.spec.paddingX ?? densityPadding.x));
94
+ const paddingY = Math.max(0, Math.floor(this.spec.paddingY ?? densityPadding.y));
95
+ const gutter = this.spec.bodyGutter ?? "";
96
+ const gutterWidth = visibleWidth(gutter);
97
+ const borderColumns = border === "none" ? 0 : 2;
98
+ const innerWidth = Math.max(1, outerWidth - borderColumns - paddingX * 2 - gutterWidth);
99
+ const emptyPaddedLine = " ".repeat(paddingX * 2 + innerWidth);
100
+ const sourceLines = contentLines.length > 0 ? contentLines : [""];
101
+ const paddedBody = [
102
+ ...Array.from({ length: paddingY }, () => emptyPaddedLine),
103
+ ...sourceLines.map((line) => {
104
+ const clipped = truncateToWidth(line, innerWidth, "");
105
+ const styled = color(this.spec.foreground, clipped);
106
+ return `${gutter}${" ".repeat(paddingX)}${padVisible(styled, innerWidth)}${" ".repeat(paddingX)}`;
107
+ }),
108
+ ...Array.from({ length: paddingY }, () => emptyPaddedLine),
109
+ ];
110
+ const borderColorFn = this.spec.borderColor ?? (this.spec.toneColor ? (value) => this.spec.toneColor?.(this.spec.tone ?? "default", value) ?? value : undefined);
111
+ const borderColor = (text) => color(borderColorFn, text);
112
+ if (border === "none") {
113
+ return paddedBody.map((line) => padVisible(line, outerWidth));
114
+ }
115
+ if (border === "rule") {
116
+ return [
117
+ borderColor("─".repeat(outerWidth)),
118
+ ...this.renderTitleRows(outerWidth),
119
+ ...paddedBody.map((line) => `${borderColor("│ ")}${truncateToWidth(line, Math.max(1, outerWidth - 2), "")}`),
120
+ ];
121
+ }
122
+ if (border === "minimal") {
123
+ const contentWidth = Math.max(1, outerWidth - 2);
124
+ return [
125
+ ...this.renderTitleRows(contentWidth).map((line) => `${borderColor("│ ")}${padVisible(line, contentWidth)}`),
126
+ ...paddedBody.map((line) => `${borderColor("│ ")}${padVisible(line, contentWidth)}`),
127
+ ];
128
+ }
129
+ const chars = BORDER_CHARS[border];
130
+ const horizontalWidth = Math.max(0, outerWidth - 2);
131
+ const top = borderColor(`${chars.topLeft}${chars.horizontal.repeat(horizontalWidth)}${chars.topRight}`);
132
+ const bottom = borderColor(`${chars.bottomLeft}${chars.horizontal.repeat(horizontalWidth)}${chars.bottomRight}`);
133
+ const contentWidth = Math.max(1, outerWidth - 2);
134
+ return [
135
+ top,
136
+ ...this.renderTitleRows(contentWidth).map((line) => `${borderColor(chars.vertical)}${padVisible(line, contentWidth)}${borderColor(chars.vertical)}`),
137
+ ...paddedBody.map((line) => `${borderColor(chars.vertical)}${padVisible(line, contentWidth)}${borderColor(chars.vertical)}`),
138
+ bottom,
139
+ ];
140
+ }
141
+ renderTitleRows(width) {
142
+ const leftRaw = this.spec.title ?? "";
143
+ const rightRaw = this.spec.titleRight ?? "";
144
+ if (!leftRaw && !rightRaw)
145
+ return [];
146
+ const leftBudget = rightRaw ? Math.max(1, width - visibleWidth(rightRaw) - 1) : width;
147
+ const left = color(this.spec.titleColor, truncateToWidth(leftRaw, leftBudget, ""));
148
+ const right = color(this.spec.titleRightColor, rightRaw);
149
+ const gap = rightRaw
150
+ ? Math.max(1, width - visibleWidth(left) - visibleWidth(right))
151
+ : Math.max(0, width - visibleWidth(left));
152
+ return [`${left}${" ".repeat(gap)}${right}`];
153
+ }
154
+ }
155
+ export function style(spec = {}) {
156
+ return new TerminalStyle(spec);
157
+ }
158
+ //# sourceMappingURL=style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.js","sourceRoot":"","sources":["../src/style.ts"],"names":[],"mappings":"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","sourcesContent":["// GSD2 - Terminal style primitives for framed TUI surfaces\n\nimport { truncateToWidth, visibleWidth } from \"./utils.js\";\n\nexport type TerminalBorderStyle = \"none\" | \"rule\" | \"single\" | \"rounded\" | \"heavy\" | \"minimal\";\nexport type TerminalDensity = \"compact\" | \"comfortable\" | \"dashboard\";\nexport type TerminalTone = \"default\" | \"muted\" | \"running\" | \"success\" | \"error\" | \"current\";\n\nexport interface TerminalStyleSpec {\n\twidth?: number;\n\tpaddingX?: number;\n\tpaddingY?: number;\n\tborder?: TerminalBorderStyle;\n\tdensity?: TerminalDensity;\n\ttone?: TerminalTone;\n\tborderColor?: (text: string) => string;\n\tforeground?: (text: string) => string;\n\ttoneColor?: (tone: TerminalTone, text: string) => string;\n\ttitle?: string;\n\ttitleRight?: string;\n\ttitleColor?: (text: string) => string;\n\ttitleRightColor?: (text: string) => string;\n\tbodyGutter?: string;\n}\n\ntype BorderChars = {\n\ttopLeft: string;\n\ttopRight: string;\n\tbottomLeft: string;\n\tbottomRight: string;\n\thorizontal: string;\n\tvertical: string;\n};\n\nconst BORDER_CHARS: Record<Exclude<TerminalBorderStyle, \"none\" | \"rule\" | \"minimal\">, BorderChars> = {\n\tsingle: {\n\t\ttopLeft: \"┌\",\n\t\ttopRight: \"┐\",\n\t\tbottomLeft: \"└\",\n\t\tbottomRight: \"┘\",\n\t\thorizontal: \"─\",\n\t\tvertical: \"│\",\n\t},\n\trounded: {\n\t\ttopLeft: \"╭\",\n\t\ttopRight: \"╮\",\n\t\tbottomLeft: \"╰\",\n\t\tbottomRight: \"╯\",\n\t\thorizontal: \"─\",\n\t\tvertical: \"│\",\n\t},\n\theavy: {\n\t\ttopLeft: \"┏\",\n\t\ttopRight: \"┓\",\n\t\tbottomLeft: \"┗\",\n\t\tbottomRight: \"┛\",\n\t\thorizontal: \"━\",\n\t\tvertical: \"┃\",\n\t},\n};\n\nconst DENSITY_PADDING: Record<TerminalDensity, { x: number; y: number }> = {\n\tcompact: { x: 0, y: 0 },\n\tcomfortable: { x: 1, y: 0 },\n\tdashboard: { x: 1, y: 1 },\n};\n\nfunction padVisible(line: string, width: number): string {\n\treturn line + \" \".repeat(Math.max(0, width - visibleWidth(line)));\n}\n\nfunction color(fn: ((text: string) => string) | undefined, text: string): string {\n\treturn fn ? fn(text) : text;\n}\n\nfunction normalizeWidth(spec: TerminalStyleSpec, width?: number): number {\n\treturn Math.max(1, Math.floor(width ?? spec.width ?? 80));\n}\n\nexport class TerminalStyle {\n\tprivate readonly spec: TerminalStyleSpec;\n\n\tconstructor(spec: TerminalStyleSpec = {}) {\n\t\tthis.spec = { ...spec };\n\t}\n\n\twidth(width: number): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, width });\n\t}\n\n\tpadding(x: number, y = x): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, paddingX: x, paddingY: y });\n\t}\n\n\tpaddingX(paddingX: number): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, paddingX });\n\t}\n\n\tpaddingY(paddingY: number): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, paddingY });\n\t}\n\n\tborder(border: TerminalBorderStyle): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, border });\n\t}\n\n\tdensity(density: TerminalDensity): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, density });\n\t}\n\n\ttone(tone: TerminalTone, toneColor?: (tone: TerminalTone, text: string) => string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, tone, toneColor });\n\t}\n\n\tborderColor(borderColor: (text: string) => string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, borderColor });\n\t}\n\n\tforeground(foreground: (text: string) => string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, foreground });\n\t}\n\n\ttoneColor(toneColor: (tone: TerminalTone, text: string) => string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, toneColor });\n\t}\n\n\ttitle(title: string, titleColor?: (text: string) => string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, title, titleColor });\n\t}\n\n\ttitleRight(titleRight: string, titleRightColor?: (text: string) => string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, titleRight, titleRightColor });\n\t}\n\n\trightTitle(titleRight: string, titleRightColor?: (text: string) => string): TerminalStyle {\n\t\treturn this.titleRight(titleRight, titleRightColor);\n\t}\n\n\tbodyGutter(bodyGutter: string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, bodyGutter });\n\t}\n\n\trender(contentLines: string[], width?: number): string[] {\n\t\tconst outerWidth = normalizeWidth(this.spec, width);\n\t\tconst border = this.spec.border ?? \"none\";\n\t\tconst densityPadding = DENSITY_PADDING[this.spec.density ?? \"compact\"];\n\t\tconst paddingX = Math.max(0, Math.floor(this.spec.paddingX ?? densityPadding.x));\n\t\tconst paddingY = Math.max(0, Math.floor(this.spec.paddingY ?? densityPadding.y));\n\t\tconst gutter = this.spec.bodyGutter ?? \"\";\n\t\tconst gutterWidth = visibleWidth(gutter);\n\t\tconst borderColumns = border === \"none\" ? 0 : 2;\n\t\tconst innerWidth = Math.max(1, outerWidth - borderColumns - paddingX * 2 - gutterWidth);\n\t\tconst emptyPaddedLine = \" \".repeat(paddingX * 2 + innerWidth);\n\t\tconst sourceLines = contentLines.length > 0 ? contentLines : [\"\"];\n\t\tconst paddedBody = [\n\t\t\t...Array.from({ length: paddingY }, () => emptyPaddedLine),\n\t\t\t...sourceLines.map((line) => {\n\t\t\t\tconst clipped = truncateToWidth(line, innerWidth, \"\");\n\t\t\t\tconst styled = color(this.spec.foreground, clipped);\n\t\t\t\treturn `${gutter}${\" \".repeat(paddingX)}${padVisible(styled, innerWidth)}${\" \".repeat(paddingX)}`;\n\t\t\t}),\n\t\t\t...Array.from({ length: paddingY }, () => emptyPaddedLine),\n\t\t];\n\t\tconst borderColorFn = this.spec.borderColor ?? (this.spec.toneColor ? (value: string) => this.spec.toneColor?.(this.spec.tone ?? \"default\", value) ?? value : undefined);\n\t\tconst borderColor = (text: string) => color(borderColorFn, text);\n\n\t\tif (border === \"none\") {\n\t\t\treturn paddedBody.map((line) => padVisible(line, outerWidth));\n\t\t}\n\n\t\tif (border === \"rule\") {\n\t\t\treturn [\n\t\t\t\tborderColor(\"─\".repeat(outerWidth)),\n\t\t\t\t...this.renderTitleRows(outerWidth),\n\t\t\t\t...paddedBody.map((line) => `${borderColor(\"│ \")}${truncateToWidth(line, Math.max(1, outerWidth - 2), \"\")}`),\n\t\t\t];\n\t\t}\n\n\t\tif (border === \"minimal\") {\n\t\t\tconst contentWidth = Math.max(1, outerWidth - 2);\n\t\t\treturn [\n\t\t\t\t...this.renderTitleRows(contentWidth).map((line) => `${borderColor(\"│ \")}${padVisible(line, contentWidth)}`),\n\t\t\t\t...paddedBody.map((line) => `${borderColor(\"│ \")}${padVisible(line, contentWidth)}`),\n\t\t\t];\n\t\t}\n\n\t\tconst chars = BORDER_CHARS[border];\n\t\tconst horizontalWidth = Math.max(0, outerWidth - 2);\n\t\tconst top = borderColor(\n\t\t\t`${chars.topLeft}${chars.horizontal.repeat(horizontalWidth)}${chars.topRight}`,\n\t\t);\n\t\tconst bottom = borderColor(\n\t\t\t`${chars.bottomLeft}${chars.horizontal.repeat(horizontalWidth)}${chars.bottomRight}`,\n\t\t);\n\t\tconst contentWidth = Math.max(1, outerWidth - 2);\n\t\treturn [\n\t\t\ttop,\n\t\t\t...this.renderTitleRows(contentWidth).map((line) =>\n\t\t\t\t`${borderColor(chars.vertical)}${padVisible(line, contentWidth)}${borderColor(chars.vertical)}`,\n\t\t\t),\n\t\t\t...paddedBody.map((line) =>\n\t\t\t\t`${borderColor(chars.vertical)}${padVisible(line, contentWidth)}${borderColor(chars.vertical)}`,\n\t\t\t),\n\t\t\tbottom,\n\t\t];\n\t}\n\n\tprivate renderTitleRows(width: number): string[] {\n\t\tconst leftRaw = this.spec.title ?? \"\";\n\t\tconst rightRaw = this.spec.titleRight ?? \"\";\n\t\tif (!leftRaw && !rightRaw) return [];\n\n\t\tconst leftBudget = rightRaw ? Math.max(1, width - visibleWidth(rightRaw) - 1) : width;\n\t\tconst left = color(this.spec.titleColor, truncateToWidth(leftRaw, leftBudget, \"\"));\n\t\tconst right = color(this.spec.titleRightColor, rightRaw);\n\t\tconst gap = rightRaw\n\t\t\t? Math.max(1, width - visibleWidth(left) - visibleWidth(right))\n\t\t\t: Math.max(0, width - visibleWidth(left));\n\t\treturn [`${left}${\" \".repeat(gap)}${right}`];\n\t}\n}\n\nexport function style(spec: TerminalStyleSpec = {}): TerminalStyle {\n\treturn new TerminalStyle(spec);\n}\n"]}
@@ -153,7 +153,6 @@ export declare class TUI extends Container {
153
153
  private renderRequested;
154
154
  private cursorRow;
155
155
  private hardwareCursorRow;
156
- private contentCursorRow;
157
156
  private inputBuffer;
158
157
  private cellSizeQueryPending;
159
158
  private showHardwareCursor;
@@ -1 +1 @@
1
- {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ // GSD-2 + packages/pi-tui/src/tui.ts - Terminal UI renderer with differential rendering.
1
2
  /**
2
3
  * Minimal TUI implementation with differential rendering
3
4
  */
@@ -106,7 +107,6 @@ export class TUI extends Container {
106
107
  this.renderRequested = false;
107
108
  this.cursorRow = 0; // Logical cursor row (end of rendered content)
108
109
  this.hardwareCursorRow = 0; // Actual terminal cursor row (may differ due to IME positioning)
109
- this.contentCursorRow = 0; // Stable baseline row at end of rendered content (before IME cursor reposition)
110
110
  this.inputBuffer = ""; // Buffer for parsing terminal responses
111
111
  this.cellSizeQueryPending = false;
112
112
  this.showHardwareCursor = process.env.PI_HARDWARE_CURSOR === "1" || process.env.TERM_PROGRAM === "WarpTerminal";
@@ -342,7 +342,6 @@ export class TUI extends Container {
342
342
  this.previousHeight = -1; // -1 triggers heightChanged, forcing a full clear
343
343
  this.cursorRow = 0;
344
344
  this.hardwareCursorRow = 0;
345
- this.contentCursorRow = 0;
346
345
  this.maxLinesRendered = 0;
347
346
  this.previousViewportTop = 0;
348
347
  }
@@ -460,7 +459,7 @@ export class TUI extends Container {
460
459
  const height = this.terminal.rows;
461
460
  let viewportTop = Math.max(0, this.maxLinesRendered - height);
462
461
  let prevViewportTop = this.previousViewportTop;
463
- let hardwareCursorRow = this.contentCursorRow;
462
+ let hardwareCursorRow = this.hardwareCursorRow;
464
463
  const computeLineDiff = (targetRow) => {
465
464
  const currentScreenRow = hardwareCursorRow - prevViewportTop;
466
465
  const targetScreenRow = targetRow - viewportTop;
@@ -510,7 +509,6 @@ export class TUI extends Container {
510
509
  this.terminal.write(buffer);
511
510
  this.cursorRow = Math.max(0, newLines.length - 1);
512
511
  this.hardwareCursorRow = this.cursorRow;
513
- this.contentCursorRow = this.cursorRow;
514
512
  // Reset max lines when clearing, otherwise track growth
515
513
  if (clear) {
516
514
  this.maxLinesRendered = newLines.length;
@@ -633,7 +631,6 @@ export class TUI extends Container {
633
631
  this.terminal.write(buffer);
634
632
  this.cursorRow = targetRow;
635
633
  this.hardwareCursorRow = targetRow;
636
- this.contentCursorRow = targetRow;
637
634
  }
638
635
  this.positionHardwareCursor(cursorPos, newLines.length);
639
636
  this.previousLines = newLines;
@@ -742,10 +739,8 @@ export class TUI extends Container {
742
739
  // Track cursor position for next render
743
740
  // cursorRow tracks end of content (for viewport calculation)
744
741
  // hardwareCursorRow tracks actual terminal cursor position (for movement)
745
- const contentBottomRow = Math.max(0, newLines.length - 1);
746
- this.cursorRow = contentBottomRow;
742
+ this.cursorRow = Math.max(0, newLines.length - 1);
747
743
  this.hardwareCursorRow = finalCursorRow;
748
- this.contentCursorRow = contentBottomRow;
749
744
  // Track terminal's working area (grows but doesn't shrink unless cleared)
750
745
  this.maxLinesRendered = Math.max(this.maxLinesRendered, newLines.length);
751
746
  this.previousViewportTop = Math.max(0, this.maxLinesRendered - height);