@dsh-cc/tui 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +144 -0
  3. package/lib/bash-history.d.ts +31 -0
  4. package/lib/bash-history.d.ts.map +1 -0
  5. package/lib/bash-history.js +94 -0
  6. package/lib/bash-history.js.map +1 -0
  7. package/lib/compact-fold.d.ts +35 -0
  8. package/lib/compact-fold.d.ts.map +1 -0
  9. package/lib/compact-fold.js +60 -0
  10. package/lib/compact-fold.js.map +1 -0
  11. package/lib/components/arg-completers.d.ts +22 -0
  12. package/lib/components/arg-completers.d.ts.map +1 -0
  13. package/lib/components/arg-completers.js +75 -0
  14. package/lib/components/arg-completers.js.map +1 -0
  15. package/lib/components/code-theme.d.ts +25 -0
  16. package/lib/components/code-theme.d.ts.map +1 -0
  17. package/lib/components/code-theme.js +137 -0
  18. package/lib/components/code-theme.js.map +1 -0
  19. package/lib/components/completion.d.ts +50 -0
  20. package/lib/components/completion.d.ts.map +1 -0
  21. package/lib/components/completion.js +279 -0
  22. package/lib/components/completion.js.map +1 -0
  23. package/lib/components/diff-card.d.ts +29 -0
  24. package/lib/components/diff-card.d.ts.map +1 -0
  25. package/lib/components/diff-card.js +175 -0
  26. package/lib/components/diff-card.js.map +1 -0
  27. package/lib/components/diff-hunks.d.ts +44 -0
  28. package/lib/components/diff-hunks.d.ts.map +1 -0
  29. package/lib/components/diff-hunks.js +188 -0
  30. package/lib/components/diff-hunks.js.map +1 -0
  31. package/lib/components/editor-history.d.ts +23 -0
  32. package/lib/components/editor-history.d.ts.map +1 -0
  33. package/lib/components/editor-history.js +29 -0
  34. package/lib/components/editor-history.js.map +1 -0
  35. package/lib/components/markdown-theme.d.ts +11 -0
  36. package/lib/components/markdown-theme.d.ts.map +1 -0
  37. package/lib/components/markdown-theme.js +29 -0
  38. package/lib/components/markdown-theme.js.map +1 -0
  39. package/lib/components/masked-input.d.ts +24 -0
  40. package/lib/components/masked-input.d.ts.map +1 -0
  41. package/lib/components/masked-input.js +168 -0
  42. package/lib/components/masked-input.js.map +1 -0
  43. package/lib/components/overlay-host.d.ts +31 -0
  44. package/lib/components/overlay-host.d.ts.map +1 -0
  45. package/lib/components/overlay-host.js +128 -0
  46. package/lib/components/overlay-host.js.map +1 -0
  47. package/lib/components/overlays.d.ts +94 -0
  48. package/lib/components/overlays.d.ts.map +1 -0
  49. package/lib/components/overlays.js +450 -0
  50. package/lib/components/overlays.js.map +1 -0
  51. package/lib/components/provider-box.d.ts +23 -0
  52. package/lib/components/provider-box.d.ts.map +1 -0
  53. package/lib/components/provider-box.js +164 -0
  54. package/lib/components/provider-box.js.map +1 -0
  55. package/lib/components/read-group.d.ts +51 -0
  56. package/lib/components/read-group.d.ts.map +1 -0
  57. package/lib/components/read-group.js +105 -0
  58. package/lib/components/read-group.js.map +1 -0
  59. package/lib/components/root-bash.d.ts +36 -0
  60. package/lib/components/root-bash.d.ts.map +1 -0
  61. package/lib/components/root-bash.js +112 -0
  62. package/lib/components/root-bash.js.map +1 -0
  63. package/lib/components/root-types.d.ts +42 -0
  64. package/lib/components/root-types.d.ts.map +1 -0
  65. package/lib/components/root-types.js +8 -0
  66. package/lib/components/root-types.js.map +1 -0
  67. package/lib/components/root-utils.d.ts +22 -0
  68. package/lib/components/root-utils.d.ts.map +1 -0
  69. package/lib/components/root-utils.js +45 -0
  70. package/lib/components/root-utils.js.map +1 -0
  71. package/lib/components/root.d.ts +25 -0
  72. package/lib/components/root.d.ts.map +1 -0
  73. package/lib/components/root.js +357 -0
  74. package/lib/components/root.js.map +1 -0
  75. package/lib/components/theme.d.ts +61 -0
  76. package/lib/components/theme.d.ts.map +1 -0
  77. package/lib/components/theme.js +99 -0
  78. package/lib/components/theme.js.map +1 -0
  79. package/lib/components/transcript.d.ts +43 -0
  80. package/lib/components/transcript.d.ts.map +1 -0
  81. package/lib/components/transcript.js +203 -0
  82. package/lib/components/transcript.js.map +1 -0
  83. package/lib/components/working-line.d.ts +35 -0
  84. package/lib/components/working-line.d.ts.map +1 -0
  85. package/lib/components/working-line.js +66 -0
  86. package/lib/components/working-line.js.map +1 -0
  87. package/lib/effort-catalog.d.ts +27 -0
  88. package/lib/effort-catalog.d.ts.map +1 -0
  89. package/lib/effort-catalog.js +36 -0
  90. package/lib/effort-catalog.js.map +1 -0
  91. package/lib/export-markdown.d.ts +18 -0
  92. package/lib/export-markdown.d.ts.map +1 -0
  93. package/lib/export-markdown.js +124 -0
  94. package/lib/export-markdown.js.map +1 -0
  95. package/lib/harness/approval-preview.d.ts +33 -0
  96. package/lib/harness/approval-preview.d.ts.map +1 -0
  97. package/lib/harness/approval-preview.js +179 -0
  98. package/lib/harness/approval-preview.js.map +1 -0
  99. package/lib/harness/boot-banner.d.ts +14 -0
  100. package/lib/harness/boot-banner.d.ts.map +1 -0
  101. package/lib/harness/boot-banner.js +89 -0
  102. package/lib/harness/boot-banner.js.map +1 -0
  103. package/lib/harness/driver-agent.d.ts +78 -0
  104. package/lib/harness/driver-agent.d.ts.map +1 -0
  105. package/lib/harness/driver-agent.js +314 -0
  106. package/lib/harness/driver-agent.js.map +1 -0
  107. package/lib/harness/driver-agents.d.ts +20 -0
  108. package/lib/harness/driver-agents.d.ts.map +1 -0
  109. package/lib/harness/driver-agents.js +123 -0
  110. package/lib/harness/driver-agents.js.map +1 -0
  111. package/lib/harness/driver-approvals.d.ts +38 -0
  112. package/lib/harness/driver-approvals.d.ts.map +1 -0
  113. package/lib/harness/driver-approvals.js +277 -0
  114. package/lib/harness/driver-approvals.js.map +1 -0
  115. package/lib/harness/driver-bash.d.ts +15 -0
  116. package/lib/harness/driver-bash.d.ts.map +1 -0
  117. package/lib/harness/driver-bash.js +73 -0
  118. package/lib/harness/driver-bash.js.map +1 -0
  119. package/lib/harness/driver-catalog.d.ts +84 -0
  120. package/lib/harness/driver-catalog.d.ts.map +1 -0
  121. package/lib/harness/driver-catalog.js +256 -0
  122. package/lib/harness/driver-catalog.js.map +1 -0
  123. package/lib/harness/driver-ctx.d.ts +462 -0
  124. package/lib/harness/driver-ctx.d.ts.map +1 -0
  125. package/lib/harness/driver-ctx.js +11 -0
  126. package/lib/harness/driver-ctx.js.map +1 -0
  127. package/lib/harness/driver-hud.d.ts +31 -0
  128. package/lib/harness/driver-hud.d.ts.map +1 -0
  129. package/lib/harness/driver-hud.js +204 -0
  130. package/lib/harness/driver-hud.js.map +1 -0
  131. package/lib/harness/driver-live.d.ts +36 -0
  132. package/lib/harness/driver-live.d.ts.map +1 -0
  133. package/lib/harness/driver-live.js +44 -0
  134. package/lib/harness/driver-live.js.map +1 -0
  135. package/lib/harness/driver-modal.d.ts +52 -0
  136. package/lib/harness/driver-modal.d.ts.map +1 -0
  137. package/lib/harness/driver-modal.js +78 -0
  138. package/lib/harness/driver-modal.js.map +1 -0
  139. package/lib/harness/driver-mode.d.ts +35 -0
  140. package/lib/harness/driver-mode.d.ts.map +1 -0
  141. package/lib/harness/driver-mode.js +84 -0
  142. package/lib/harness/driver-mode.js.map +1 -0
  143. package/lib/harness/driver-pickers.d.ts +48 -0
  144. package/lib/harness/driver-pickers.d.ts.map +1 -0
  145. package/lib/harness/driver-pickers.js +249 -0
  146. package/lib/harness/driver-pickers.js.map +1 -0
  147. package/lib/harness/driver-promote.d.ts +29 -0
  148. package/lib/harness/driver-promote.d.ts.map +1 -0
  149. package/lib/harness/driver-promote.js +36 -0
  150. package/lib/harness/driver-promote.js.map +1 -0
  151. package/lib/harness/driver-queue.d.ts +19 -0
  152. package/lib/harness/driver-queue.d.ts.map +1 -0
  153. package/lib/harness/driver-queue.js +281 -0
  154. package/lib/harness/driver-queue.js.map +1 -0
  155. package/lib/harness/driver-run-local.d.ts +32 -0
  156. package/lib/harness/driver-run-local.d.ts.map +1 -0
  157. package/lib/harness/driver-run-local.js +366 -0
  158. package/lib/harness/driver-run-local.js.map +1 -0
  159. package/lib/harness/driver-sessions.d.ts +28 -0
  160. package/lib/harness/driver-sessions.d.ts.map +1 -0
  161. package/lib/harness/driver-sessions.js +386 -0
  162. package/lib/harness/driver-sessions.js.map +1 -0
  163. package/lib/harness/driver.d.ts +22 -0
  164. package/lib/harness/driver.d.ts.map +1 -0
  165. package/lib/harness/driver.js +459 -0
  166. package/lib/harness/driver.js.map +1 -0
  167. package/lib/harness/preset.d.ts +32 -0
  168. package/lib/harness/preset.d.ts.map +1 -0
  169. package/lib/harness/preset.js +34 -0
  170. package/lib/harness/preset.js.map +1 -0
  171. package/lib/harness/session-list.d.ts +65 -0
  172. package/lib/harness/session-list.d.ts.map +1 -0
  173. package/lib/harness/session-list.js +91 -0
  174. package/lib/harness/session-list.js.map +1 -0
  175. package/lib/harness/shell-output.d.ts +44 -0
  176. package/lib/harness/shell-output.d.ts.map +1 -0
  177. package/lib/harness/shell-output.js +90 -0
  178. package/lib/harness/shell-output.js.map +1 -0
  179. package/lib/harness/statusline-cc-transcript.d.ts +51 -0
  180. package/lib/harness/statusline-cc-transcript.d.ts.map +1 -0
  181. package/lib/harness/statusline-cc-transcript.js +191 -0
  182. package/lib/harness/statusline-cc-transcript.js.map +1 -0
  183. package/lib/harness/statusline-command.d.ts +54 -0
  184. package/lib/harness/statusline-command.d.ts.map +1 -0
  185. package/lib/harness/statusline-command.js +161 -0
  186. package/lib/harness/statusline-command.js.map +1 -0
  187. package/lib/harness/statusline-payload.d.ts +79 -0
  188. package/lib/harness/statusline-payload.d.ts.map +1 -0
  189. package/lib/harness/statusline-payload.js +93 -0
  190. package/lib/harness/statusline-payload.js.map +1 -0
  191. package/lib/harness/statusline-settings.d.ts +47 -0
  192. package/lib/harness/statusline-settings.d.ts.map +1 -0
  193. package/lib/harness/statusline-settings.js +57 -0
  194. package/lib/harness/statusline-settings.js.map +1 -0
  195. package/lib/harness/statusline-wiring.d.ts +45 -0
  196. package/lib/harness/statusline-wiring.d.ts.map +1 -0
  197. package/lib/harness/statusline-wiring.js +247 -0
  198. package/lib/harness/statusline-wiring.js.map +1 -0
  199. package/lib/harness/usage-view.d.ts +84 -0
  200. package/lib/harness/usage-view.d.ts.map +1 -0
  201. package/lib/harness/usage-view.js +199 -0
  202. package/lib/harness/usage-view.js.map +1 -0
  203. package/lib/harness/worktree-exit.d.ts +105 -0
  204. package/lib/harness/worktree-exit.d.ts.map +1 -0
  205. package/lib/harness/worktree-exit.js +168 -0
  206. package/lib/harness/worktree-exit.js.map +1 -0
  207. package/lib/history.d.ts +50 -0
  208. package/lib/history.d.ts.map +1 -0
  209. package/lib/history.js +139 -0
  210. package/lib/history.js.map +1 -0
  211. package/lib/index.d.ts +63 -0
  212. package/lib/index.d.ts.map +1 -0
  213. package/lib/index.js +54 -0
  214. package/lib/index.js.map +1 -0
  215. package/lib/input.d.ts +158 -0
  216. package/lib/input.d.ts.map +1 -0
  217. package/lib/input.js +400 -0
  218. package/lib/input.js.map +1 -0
  219. package/lib/invariant.d.ts +14 -0
  220. package/lib/invariant.d.ts.map +1 -0
  221. package/lib/invariant.js +20 -0
  222. package/lib/invariant.js.map +1 -0
  223. package/lib/mode-cycle.d.ts +22 -0
  224. package/lib/mode-cycle.d.ts.map +1 -0
  225. package/lib/mode-cycle.js +32 -0
  226. package/lib/mode-cycle.js.map +1 -0
  227. package/lib/model-catalog.d.ts +22 -0
  228. package/lib/model-catalog.d.ts.map +1 -0
  229. package/lib/model-catalog.js +45 -0
  230. package/lib/model-catalog.js.map +1 -0
  231. package/lib/packaged-preset.d.ts +32 -0
  232. package/lib/packaged-preset.d.ts.map +1 -0
  233. package/lib/packaged-preset.js +94 -0
  234. package/lib/packaged-preset.js.map +1 -0
  235. package/lib/plugin.d.ts +11 -0
  236. package/lib/plugin.d.ts.map +1 -0
  237. package/lib/plugin.js +88 -0
  238. package/lib/plugin.js.map +1 -0
  239. package/lib/profile.d.ts +4 -0
  240. package/lib/profile.d.ts.map +1 -0
  241. package/lib/profile.js +7 -0
  242. package/lib/profile.js.map +1 -0
  243. package/lib/project-sessions.d.ts +29 -0
  244. package/lib/project-sessions.d.ts.map +1 -0
  245. package/lib/project-sessions.js +60 -0
  246. package/lib/project-sessions.js.map +1 -0
  247. package/lib/project.d.ts +75 -0
  248. package/lib/project.d.ts.map +1 -0
  249. package/lib/project.js +196 -0
  250. package/lib/project.js.map +1 -0
  251. package/lib/provider-actions.d.ts +37 -0
  252. package/lib/provider-actions.d.ts.map +1 -0
  253. package/lib/provider-actions.js +417 -0
  254. package/lib/provider-actions.js.map +1 -0
  255. package/lib/provider-command.d.ts +109 -0
  256. package/lib/provider-command.d.ts.map +1 -0
  257. package/lib/provider-command.js +220 -0
  258. package/lib/provider-command.js.map +1 -0
  259. package/lib/provider-detail.d.ts +15 -0
  260. package/lib/provider-detail.d.ts.map +1 -0
  261. package/lib/provider-detail.js +201 -0
  262. package/lib/provider-detail.js.map +1 -0
  263. package/lib/provider-flow.d.ts +191 -0
  264. package/lib/provider-flow.d.ts.map +1 -0
  265. package/lib/provider-flow.js +192 -0
  266. package/lib/provider-flow.js.map +1 -0
  267. package/lib/provider-presets.d.ts +32 -0
  268. package/lib/provider-presets.d.ts.map +1 -0
  269. package/lib/provider-presets.js +105 -0
  270. package/lib/provider-presets.js.map +1 -0
  271. package/lib/provider-read.d.ts +63 -0
  272. package/lib/provider-read.d.ts.map +1 -0
  273. package/lib/provider-read.js +115 -0
  274. package/lib/provider-read.js.map +1 -0
  275. package/lib/provider-settings.d.ts +30 -0
  276. package/lib/provider-settings.d.ts.map +1 -0
  277. package/lib/provider-settings.js +65 -0
  278. package/lib/provider-settings.js.map +1 -0
  279. package/lib/resume-target.d.ts +59 -0
  280. package/lib/resume-target.d.ts.map +1 -0
  281. package/lib/resume-target.js +143 -0
  282. package/lib/resume-target.js.map +1 -0
  283. package/lib/slash.d.ts +44 -0
  284. package/lib/slash.d.ts.map +1 -0
  285. package/lib/slash.js +81 -0
  286. package/lib/slash.js.map +1 -0
  287. package/lib/state/driver-types.d.ts +505 -0
  288. package/lib/state/driver-types.d.ts.map +1 -0
  289. package/lib/state/driver-types.js +8 -0
  290. package/lib/state/driver-types.js.map +1 -0
  291. package/lib/state/driver-usage-types.d.ts +59 -0
  292. package/lib/state/driver-usage-types.d.ts.map +1 -0
  293. package/lib/state/driver-usage-types.js +8 -0
  294. package/lib/state/driver-usage-types.js.map +1 -0
  295. package/lib/statusline.d.ts +63 -0
  296. package/lib/statusline.d.ts.map +1 -0
  297. package/lib/statusline.js +97 -0
  298. package/lib/statusline.js.map +1 -0
  299. package/lib/store/pickers.d.ts +34 -0
  300. package/lib/store/pickers.d.ts.map +1 -0
  301. package/lib/store/pickers.js +111 -0
  302. package/lib/store/pickers.js.map +1 -0
  303. package/lib/store/provider-panel.d.ts +107 -0
  304. package/lib/store/provider-panel.d.ts.map +1 -0
  305. package/lib/store/provider-panel.js +151 -0
  306. package/lib/store/provider-panel.js.map +1 -0
  307. package/lib/store/question.d.ts +21 -0
  308. package/lib/store/question.d.ts.map +1 -0
  309. package/lib/store/question.js +59 -0
  310. package/lib/store/question.js.map +1 -0
  311. package/lib/store/queue.d.ts +27 -0
  312. package/lib/store/queue.d.ts.map +1 -0
  313. package/lib/store/queue.js +34 -0
  314. package/lib/store/queue.js.map +1 -0
  315. package/lib/store/session.d.ts +73 -0
  316. package/lib/store/session.d.ts.map +1 -0
  317. package/lib/store/session.js +172 -0
  318. package/lib/store/session.js.map +1 -0
  319. package/lib/store/subagents.d.ts +16 -0
  320. package/lib/store/subagents.d.ts.map +1 -0
  321. package/lib/store/subagents.js +44 -0
  322. package/lib/store/subagents.js.map +1 -0
  323. package/lib/store/todos.d.ts +35 -0
  324. package/lib/store/todos.d.ts.map +1 -0
  325. package/lib/store/todos.js +68 -0
  326. package/lib/store/todos.js.map +1 -0
  327. package/lib/store/usage.d.ts +15 -0
  328. package/lib/store/usage.d.ts.map +1 -0
  329. package/lib/store/usage.js +27 -0
  330. package/lib/store/usage.js.map +1 -0
  331. package/lib/store/views.d.ts +419 -0
  332. package/lib/store/views.d.ts.map +1 -0
  333. package/lib/store/views.js +3 -0
  334. package/lib/store/views.js.map +1 -0
  335. package/lib/store.d.ts +19 -0
  336. package/lib/store.d.ts.map +1 -0
  337. package/lib/store.js +10 -0
  338. package/lib/store.js.map +1 -0
  339. package/lib/terminal/lease.d.ts +33 -0
  340. package/lib/terminal/lease.d.ts.map +1 -0
  341. package/lib/terminal/lease.js +99 -0
  342. package/lib/terminal/lease.js.map +1 -0
  343. package/lib/tool-card.d.ts +75 -0
  344. package/lib/tool-card.d.ts.map +1 -0
  345. package/lib/tool-card.js +109 -0
  346. package/lib/tool-card.js.map +1 -0
  347. package/lib/tool-verbs.d.ts +12 -0
  348. package/lib/tool-verbs.d.ts.map +1 -0
  349. package/lib/tool-verbs.js +29 -0
  350. package/lib/tool-verbs.js.map +1 -0
  351. package/lib/transcript.d.ts +40 -0
  352. package/lib/transcript.d.ts.map +1 -0
  353. package/lib/transcript.js +413 -0
  354. package/lib/transcript.js.map +1 -0
  355. package/lib/working-line.d.ts +44 -0
  356. package/lib/working-line.d.ts.map +1 -0
  357. package/lib/working-line.js +56 -0
  358. package/lib/working-line.js.map +1 -0
  359. package/package.json +72 -0
  360. package/presets/cc/.dsh-cc-managed.json +5 -0
  361. package/presets/cc/agent.cordis.yml +524 -0
  362. package/presets/cc/preset.yml +3 -0
  363. package/scripts/stage-preset.mjs +26 -0
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Render structured FileDiff data as ANSI-styled hunk lines for the
3
+ * transcript. Hunks come from {@link computeHunks} (line-level LCS with a
4
+ * size-capped prefix/suffix fallback). Large unchanged runs between hunks
5
+ * collapse to a single dim `… N unchanged lines …` marker; small runs render
6
+ * as dim context so adjacent hunks read as one cluster. Changed lines carry a
7
+ * right-aligned gutter line number (old-side number on `-` lines, new-side on
8
+ * `+` lines). Output is capped so a single tool row never blows the
9
+ * transcript line budget, and truncation respects hunk boundaries: a hunk
10
+ * that fits in the remaining budget is never split in half.
11
+ * @module @dsh-cc/tui/components/diff-card
12
+ */
13
+ import { computeHunks, splitLines } from "./diff-hunks.js";
14
+ import { defaultTheme } from "./theme.js";
15
+ /** Default cap on emitted lines for a single tool row's diffs. */
16
+ export const DEFAULT_DIFF_LINE_CAP = 60;
17
+ /** Context lines shown at the start/end of a file's diff (edge gaps). */
18
+ const DIFF_CONTEXT_LINES = 2;
19
+ /** Hunks separated by at most this many unchanged lines render as one cluster. */
20
+ const HUNK_MERGE_GAP = 2 * DIFF_CONTEXT_LINES;
21
+ /**
22
+ * Hunk computation memo keyed by FileDiff object identity. Store rows are
23
+ * immutable, so the same FileDiff instances recur on every driver emit; the
24
+ * memo keeps repeated renders (including transcript budget counting, which
25
+ * calls renderDiffLines on every pass) from recomputing the LCS.
26
+ */
27
+ const hunkMemo = new WeakMap();
28
+ function hunksFor(diff) {
29
+ let hunks = hunkMemo.get(diff);
30
+ if (hunks === undefined) {
31
+ hunks = computeHunks(diff.oldText ?? '', diff.newText);
32
+ hunkMemo.set(diff, hunks);
33
+ }
34
+ return hunks;
35
+ }
36
+ /** Gutter width covering every line number in either file version. */
37
+ function gutterWidth(oldCount, newCount) {
38
+ return String(Math.max(oldCount, newCount, 1)).length;
39
+ }
40
+ function headerFor(diff, theme) {
41
+ const tag = diff.oldText === null
42
+ ? ' (new file)'
43
+ : diff.newText === ''
44
+ ? ' (deleted)'
45
+ : '';
46
+ return ` ${theme.bold(diff.path)}${tag.length > 0 ? theme.muted(tag) : ''}`;
47
+ }
48
+ function removalLine(num, width, line, theme) {
49
+ return ` ${String(num).padStart(width)} ${theme.error(`- ${line}`)}`;
50
+ }
51
+ function additionLine(num, width, line, theme) {
52
+ return ` ${String(num).padStart(width)} ${theme.success(`+ ${line}`)}`;
53
+ }
54
+ function contextLine(line, theme) {
55
+ return theme.muted(` ${line}`);
56
+ }
57
+ function unchangedMarker(count, theme) {
58
+ return theme.muted(` … ${count} unchanged line${count === 1 ? '' : 's'} …`);
59
+ }
60
+ function contextAtom(line, theme) {
61
+ return { lines: [contextLine(line, theme)], splittable: false };
62
+ }
63
+ /** Atoms for an in-place edit: per-hunk blocks with context and collapse markers. */
64
+ function buildEditAtoms(diff, maxLines, theme) {
65
+ const oldLines = splitLines(diff.oldText ?? '');
66
+ const newLines = splitLines(diff.newText);
67
+ const width = gutterWidth(oldLines.length, newLines.length);
68
+ const hunks = hunksFor(diff);
69
+ const atoms = [{ lines: [headerFor(diff, theme)], splittable: false }];
70
+ if (hunks.length === 0) {
71
+ atoms.push({ lines: [theme.muted(' (no changes)')], splittable: false });
72
+ return atoms;
73
+ }
74
+ // 1-based old-file line consumed by the previous hunk.
75
+ let prevEnd = 0;
76
+ hunks.forEach((hunk, i) => {
77
+ const gap = oldLines.slice(prevEnd, hunk.oldStart - 1);
78
+ if (i === 0) {
79
+ // Leading context: at most DIFF_CONTEXT_LINES lines before the first hunk.
80
+ for (const line of gap.slice(Math.max(0, gap.length - DIFF_CONTEXT_LINES))) {
81
+ atoms.push(contextAtom(line, theme));
82
+ }
83
+ }
84
+ else if (gap.length <= HUNK_MERGE_GAP) {
85
+ // Adjacent hunks: show the small unchanged run so the two changes read
86
+ // as one cluster instead of earning a collapse marker.
87
+ for (const line of gap)
88
+ atoms.push(contextAtom(line, theme));
89
+ }
90
+ else {
91
+ atoms.push({ lines: [unchangedMarker(gap.length, theme)], splittable: false });
92
+ }
93
+ const lines = [];
94
+ hunk.removed.forEach((line, k) => lines.push(removalLine(hunk.oldStart + k, width, line, theme)));
95
+ hunk.added.forEach((line, k) => lines.push(additionLine(hunk.newStart + k, width, line, theme)));
96
+ atoms.push({ lines, splittable: lines.length > maxLines });
97
+ prevEnd = hunk.oldStart - 1 + hunk.removed.length;
98
+ });
99
+ // Trailing context: at most DIFF_CONTEXT_LINES lines after the last hunk.
100
+ for (const line of oldLines.slice(prevEnd, prevEnd + DIFF_CONTEXT_LINES)) {
101
+ atoms.push(contextAtom(line, theme));
102
+ }
103
+ return atoms;
104
+ }
105
+ /** Atoms for a whole-file addition (new file) or removal (deleted file). */
106
+ function buildWholesaleAtoms(diff, maxLines, isAddition, theme) {
107
+ const lines = splitLines(isAddition ? diff.newText : diff.oldText ?? '');
108
+ const width = gutterWidth(isAddition ? 0 : lines.length, isAddition ? lines.length : 0);
109
+ const body = lines.map((line, i) => isAddition ? additionLine(i + 1, width, line, theme) : removalLine(i + 1, width, line, theme));
110
+ return [
111
+ { lines: [headerFor(diff, theme)], splittable: false },
112
+ { lines: body, splittable: body.length > maxLines },
113
+ ];
114
+ }
115
+ /**
116
+ * Flush atoms under the cap. Atoms that fit are emitted whole; when an atom
117
+ * does not fit, emission stops there (dropping it and everything after) so
118
+ * hunks are never cut mid-way — except for oversized atoms, which stream to
119
+ * fill the budget. The trailer reports how many lines were left out.
120
+ */
121
+ function flushAtoms(atoms, maxLines, theme) {
122
+ const total = atoms.reduce((sum, atom) => sum + atom.lines.length, 0);
123
+ if (total <= maxLines) {
124
+ const all = [];
125
+ for (const atom of atoms)
126
+ all.push(...atom.lines);
127
+ return all;
128
+ }
129
+ const out = [];
130
+ for (const atom of atoms) {
131
+ const room = maxLines - out.length;
132
+ if (room <= 0)
133
+ break;
134
+ if (atom.lines.length <= room) {
135
+ out.push(...atom.lines);
136
+ continue;
137
+ }
138
+ if (atom.splittable) {
139
+ for (const line of atom.lines.slice(0, room))
140
+ out.push(line);
141
+ }
142
+ break;
143
+ }
144
+ out.push(theme.muted(` … (${total - out.length} more lines)`));
145
+ return out;
146
+ }
147
+ /**
148
+ * Render FileDiff[] as ANSI-styled lines: a bold per-file header with a tag,
149
+ * then gutter-numbered removals (error role) and additions (success role)
150
+ * grouped into hunks, with muted context and `… N unchanged lines …` collapse
151
+ * markers between them. Capped at `maxLines` (default 60); a muted trailer is
152
+ * appended when content is cut, and the cut lands on a hunk boundary.
153
+ *
154
+ * Indentation (two leading spaces) is applied here so callers can drop the
155
+ * returned lines directly beneath a tool row's head line. Styles come from
156
+ * the injected `theme` (default: the built-in palette).
157
+ */
158
+ export function renderDiffLines(diffs, maxLines = DEFAULT_DIFF_LINE_CAP, theme = defaultTheme) {
159
+ if (diffs.length === 0)
160
+ return [];
161
+ const atoms = [];
162
+ for (const diff of diffs) {
163
+ if (diff.oldText === null) {
164
+ atoms.push(...buildWholesaleAtoms(diff, maxLines, true, theme));
165
+ }
166
+ else if (diff.newText === '') {
167
+ atoms.push(...buildWholesaleAtoms(diff, maxLines, false, theme));
168
+ }
169
+ else {
170
+ atoms.push(...buildEditAtoms(diff, maxLines, theme));
171
+ }
172
+ }
173
+ return flushAtoms(atoms, maxLines, theme);
174
+ }
175
+ //# sourceMappingURL=diff-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-card.js","sourceRoot":"","sources":["../../src/components/diff-card.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Line-level diff computation for file edit cards. Hunks are derived from a
3
+ * true line LCS using Hirschberg's linear-space divide-and-conquer over
4
+ * dynamic-programming rows, so memory stays O(n + m) even for large files.
5
+ * When either side exceeds DIFF_LCS_LINE_CAP lines, computation falls back to
6
+ * the cheaper common prefix/suffix heuristic (a single coarse middle hunk) so
7
+ * pathological inputs stay fast and allocation-light.
8
+ * @module @dsh-cc/tui/components/diff-hunks
9
+ */
10
+ /**
11
+ * One contiguous run of changed lines. Unchanged context is deliberately not
12
+ * stored — the renderer derives context and collapse markers from the
13
+ * surrounding line numbers.
14
+ */
15
+ export interface DiffHunk {
16
+ /** 1-based line number in the old text where this hunk's removals begin. */
17
+ readonly oldStart: number;
18
+ /** 1-based line number in the new text where this hunk's additions begin. */
19
+ readonly newStart: number;
20
+ /** Lines deleted from the old text, in file order. */
21
+ readonly removed: readonly string[];
22
+ /** Lines added to the new text, in file order. */
23
+ readonly added: readonly string[];
24
+ }
25
+ /**
26
+ * Maximum lines per side handled by exact LCS. Beyond this the single-middle
27
+ * prefix/suffix heuristic is used instead (quadratic-time DP is skipped).
28
+ */
29
+ export declare const DIFF_LCS_LINE_CAP = 4000;
30
+ /**
31
+ * Split text into lines, dropping a single trailing empty line produced by a
32
+ * final newline so `a\nb\n` → `['a','b']` (not `['a','b','']`). A bare empty
33
+ * string yields `[]`.
34
+ */
35
+ export declare function splitLines(text: string): string[];
36
+ /**
37
+ * Compute the changed hunks between two versions of a file. Returns hunks in
38
+ * file order; each hunk covers one contiguous run of changed lines (an
39
+ * unchanged line between two changes starts a new hunk). Identical inputs
40
+ * yield `[]`. Inputs larger than DIFF_LCS_LINE_CAP lines per side fall back
41
+ * to a single coarse hunk from the common prefix/suffix trim.
42
+ */
43
+ export declare function computeHunks(oldText: string, newText: string): readonly DiffHunk[];
44
+ //# sourceMappingURL=diff-hunks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-hunks.d.ts","sourceRoot":"","sources":["../../src/components/diff-hunks.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,sDAAsD;IACtD,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAClC;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAErC;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKjD;AAmJD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,QAAQ,EAAE,CAoBlF"}
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Line-level diff computation for file edit cards. Hunks are derived from a
3
+ * true line LCS using Hirschberg's linear-space divide-and-conquer over
4
+ * dynamic-programming rows, so memory stays O(n + m) even for large files.
5
+ * When either side exceeds DIFF_LCS_LINE_CAP lines, computation falls back to
6
+ * the cheaper common prefix/suffix heuristic (a single coarse middle hunk) so
7
+ * pathological inputs stay fast and allocation-light.
8
+ * @module @dsh-cc/tui/components/diff-hunks
9
+ */
10
+ /**
11
+ * Maximum lines per side handled by exact LCS. Beyond this the single-middle
12
+ * prefix/suffix heuristic is used instead (quadratic-time DP is skipped).
13
+ */
14
+ export const DIFF_LCS_LINE_CAP = 4000;
15
+ /**
16
+ * Split text into lines, dropping a single trailing empty line produced by a
17
+ * final newline so `a\nb\n` → `['a','b']` (not `['a','b','']`). A bare empty
18
+ * string yields `[]`.
19
+ */
20
+ export function splitLines(text) {
21
+ if (text.length === 0)
22
+ return [];
23
+ const parts = text.split('\n');
24
+ if (parts.length > 0 && parts[parts.length - 1] === '')
25
+ parts.pop();
26
+ return parts;
27
+ }
28
+ /** Trim the longest common line-exact prefix; return [prefixLength, oldRest, newRest]. */
29
+ function trimCommonPrefix(oldLines, newLines) {
30
+ const min = Math.min(oldLines.length, newLines.length);
31
+ let i = 0;
32
+ while (i < min && oldLines[i] === newLines[i])
33
+ i++;
34
+ return [i, oldLines.slice(i), newLines.slice(i)];
35
+ }
36
+ /** Trim the longest common line-exact suffix; return [oldRest, newRest]. */
37
+ function trimCommonSuffix(oldLines, newLines) {
38
+ const min = Math.min(oldLines.length, newLines.length);
39
+ let i = 0;
40
+ while (i < min && oldLines[oldLines.length - 1 - i] === newLines[newLines.length - 1 - i])
41
+ i++;
42
+ return [oldLines.slice(0, oldLines.length - i), newLines.slice(0, newLines.length - i)];
43
+ }
44
+ /** Edit script ops over the (prefix/suffix-trimmed) middle region. */
45
+ const EQUAL = 0;
46
+ const DELETE = 1;
47
+ const INSERT = 2;
48
+ /** Map lines to dense integer ids so DP comparisons are O(1) instead of string compares. */
49
+ function intern(lines, pool) {
50
+ return lines.map(line => {
51
+ let id = pool.get(line);
52
+ if (id === undefined) {
53
+ id = pool.size;
54
+ pool.set(line, id);
55
+ }
56
+ return id;
57
+ });
58
+ }
59
+ /**
60
+ * Final DP row for LCS(a, b): row[j] is the LCS length of `a` against the
61
+ * first j lines of `b`. Two rolling rows keep memory at O(b.length).
62
+ */
63
+ function lcsRow(a, b) {
64
+ const m = b.length;
65
+ let prev = new Int32Array(m + 1);
66
+ let curr = new Int32Array(m + 1);
67
+ for (let i = 0; i < a.length; i++) {
68
+ const av = a[i];
69
+ curr[0] = 0;
70
+ for (let j = 1; j <= m; j++) {
71
+ curr[j] = av === b[j - 1]
72
+ ? prev[j - 1] + 1
73
+ : prev[j] >= curr[j - 1] ? prev[j] : curr[j - 1];
74
+ }
75
+ const swap = prev;
76
+ prev = curr;
77
+ curr = swap;
78
+ }
79
+ return prev;
80
+ }
81
+ /**
82
+ * Append a minimal edit script for `a` → `b` to `out` via Hirschberg's
83
+ * divide-and-conquer: split `a`, find the `b` split point that maximizes the
84
+ * combined LCS, recurse. Linear space, O(len(a) · len(b)) time.
85
+ */
86
+ function editScript(a, b, out) {
87
+ if (a.length === 0) {
88
+ for (let j = 0; j < b.length; j++)
89
+ out.push(INSERT);
90
+ return;
91
+ }
92
+ if (b.length === 0) {
93
+ for (let i = 0; i < a.length; i++)
94
+ out.push(DELETE);
95
+ return;
96
+ }
97
+ if (a.length === 1) {
98
+ // Base case: align the single line against its first match in b.
99
+ const av = a[0];
100
+ let hit = -1;
101
+ for (let j = 0; j < b.length; j++) {
102
+ if (b[j] === av) {
103
+ hit = j;
104
+ break;
105
+ }
106
+ }
107
+ for (let j = 0; j < b.length; j++)
108
+ out.push(j === hit ? EQUAL : INSERT);
109
+ if (hit === -1)
110
+ out.push(DELETE);
111
+ return;
112
+ }
113
+ const mid = a.length >> 1;
114
+ const l1 = lcsRow(a.slice(0, mid), b);
115
+ const l2 = lcsRow(a.slice(mid).reverse(), b.slice().reverse());
116
+ let bestJ = 0;
117
+ let best = -1;
118
+ for (let j = 0; j <= b.length; j++) {
119
+ const score = l1[j] + l2[b.length - j];
120
+ if (score > best) {
121
+ best = score;
122
+ bestJ = j;
123
+ }
124
+ }
125
+ editScript(a.slice(0, mid), b.slice(0, bestJ), out);
126
+ editScript(a.slice(mid), b.slice(bestJ), out);
127
+ }
128
+ /** Fold an edit script into hunks, tracking 1-based line numbers on both sides. */
129
+ function hunksFromScript(script, oldMiddle, newMiddle, prefixLen) {
130
+ const hunks = [];
131
+ let current = null;
132
+ let oi = 0;
133
+ let ni = 0;
134
+ for (const op of script) {
135
+ if (op === EQUAL) {
136
+ current = null;
137
+ oi++;
138
+ ni++;
139
+ continue;
140
+ }
141
+ if (current === null) {
142
+ current = {
143
+ oldStart: prefixLen + oi + 1,
144
+ newStart: prefixLen + ni + 1,
145
+ removed: [],
146
+ added: [],
147
+ };
148
+ hunks.push(current);
149
+ }
150
+ if (op === DELETE) {
151
+ current.removed.push(oldMiddle[oi]);
152
+ oi++;
153
+ }
154
+ else {
155
+ current.added.push(newMiddle[ni]);
156
+ ni++;
157
+ }
158
+ }
159
+ return hunks;
160
+ }
161
+ /**
162
+ * Compute the changed hunks between two versions of a file. Returns hunks in
163
+ * file order; each hunk covers one contiguous run of changed lines (an
164
+ * unchanged line between two changes starts a new hunk). Identical inputs
165
+ * yield `[]`. Inputs larger than DIFF_LCS_LINE_CAP lines per side fall back
166
+ * to a single coarse hunk from the common prefix/suffix trim.
167
+ */
168
+ export function computeHunks(oldText, newText) {
169
+ if (oldText === newText)
170
+ return [];
171
+ const oldLines = splitLines(oldText);
172
+ const newLines = splitLines(newText);
173
+ const [prefixLen, oldRest, newRest] = trimCommonPrefix(oldLines, newLines);
174
+ const [oldMiddle, newMiddle] = trimCommonSuffix(oldRest, newRest);
175
+ if (oldMiddle.length === 0 && newMiddle.length === 0)
176
+ return [];
177
+ // Guard rail: exact LCS is quadratic in the input sizes. When either side
178
+ // exceeds the cap, fall back to the legacy heuristic: the trimmed middle
179
+ // becomes one coarse hunk (context and markers are the renderer's job).
180
+ if (oldLines.length > DIFF_LCS_LINE_CAP || newLines.length > DIFF_LCS_LINE_CAP) {
181
+ return [{ oldStart: prefixLen + 1, newStart: prefixLen + 1, removed: oldMiddle, added: newMiddle }];
182
+ }
183
+ const pool = new Map();
184
+ const script = [];
185
+ editScript(intern(oldMiddle, pool), intern(newMiddle, pool), script);
186
+ return hunksFromScript(script, oldMiddle, newMiddle, prefixLen);
187
+ }
188
+ //# sourceMappingURL=diff-hunks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-hunks.js","sourceRoot":"","sources":["../../src/components/diff-hunks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Reset a pi-tui Editor's ↑/↓ prompt-recall stack from the dsh-cc TUI layer.
3
+ *
4
+ * pi-tui is vendored byte-pure (packages/ui/pi-tui/PORTING.md: re-vendoring
5
+ * replaces `src/` wholesale, so local edits — like a `setHistory` method —
6
+ * would be destroyed and are not allowed). The reset therefore reaches the
7
+ * editor's private slots (`history`, `historyIndex`, `historyDraft`) through
8
+ * a runtime cast instead; `addToHistory` (public) does the refilling so its
9
+ * trim/dedup/cap rules still apply. These field names are stable across the
10
+ * vendored line — re-vendoring to a new upstream SHA must re-check this
11
+ * seam.
12
+ *
13
+ * @module @dsh-cc/tui/components/editor-history
14
+ */
15
+ import type { Editor } from '@dsh-cc/pi-tui';
16
+ /**
17
+ * Replace the editor's recall stack wholesale (entries oldest-first,
18
+ * matching the persisted order) and cancel any in-progress browsing. Used
19
+ * when a session switch rebinds prompt history onto another project's
20
+ * bucket.
21
+ */
22
+ export declare function resetEditorHistory(editor: Editor, entries: readonly string[]): void;
23
+ //# sourceMappingURL=editor-history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-history.d.ts","sourceRoot":"","sources":["../../src/components/editor-history.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAS5C;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAMnF"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Reset a pi-tui Editor's ↑/↓ prompt-recall stack from the dsh-cc TUI layer.
3
+ *
4
+ * pi-tui is vendored byte-pure (packages/ui/pi-tui/PORTING.md: re-vendoring
5
+ * replaces `src/` wholesale, so local edits — like a `setHistory` method —
6
+ * would be destroyed and are not allowed). The reset therefore reaches the
7
+ * editor's private slots (`history`, `historyIndex`, `historyDraft`) through
8
+ * a runtime cast instead; `addToHistory` (public) does the refilling so its
9
+ * trim/dedup/cap rules still apply. These field names are stable across the
10
+ * vendored line — re-vendoring to a new upstream SHA must re-check this
11
+ * seam.
12
+ *
13
+ * @module @dsh-cc/tui/components/editor-history
14
+ */
15
+ /**
16
+ * Replace the editor's recall stack wholesale (entries oldest-first,
17
+ * matching the persisted order) and cancel any in-progress browsing. Used
18
+ * when a session switch rebinds prompt history onto another project's
19
+ * bucket.
20
+ */
21
+ export function resetEditorHistory(editor, entries) {
22
+ const slots = editor;
23
+ slots.history = [];
24
+ for (const entry of entries)
25
+ editor.addToHistory(entry);
26
+ slots.historyIndex = -1;
27
+ slots.historyDraft = null;
28
+ }
29
+ //# sourceMappingURL=editor-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-history.js","sourceRoot":"","sources":["../../src/components/editor-history.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAWH;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,OAA0B;IAC3E,MAAM,KAAK,GAAG,MAAuC,CAAA;IACrD,KAAK,CAAC,OAAO,GAAG,EAAE,CAAA;IAClB,KAAK,MAAM,KAAK,IAAI,OAAO;QAAE,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;IACvD,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAA;IACvB,KAAK,CAAC,YAAY,GAAG,IAAI,CAAA;AAC3B,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Markdown theme derived from the injected TUI palette. Assistant rows pass
3
+ * through the vendored Markdown component with this theme; fenced code blocks
4
+ * are syntax-highlighted via the `highlightCode` seam (see `code-theme.ts`).
5
+ * @module @dsh-cc/tui/components/markdown-theme
6
+ */
7
+ import type { MarkdownTheme } from '@dsh-cc/pi-tui';
8
+ import { type Theme } from './theme.ts';
9
+ /** Map a theme onto the vendored Markdown component's style hooks. */
10
+ export declare function createMarkdownTheme(theme?: Theme): MarkdownTheme;
11
+ //# sourceMappingURL=markdown-theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-theme.d.ts","sourceRoot":"","sources":["../../src/components/markdown-theme.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,EAAgB,KAAK,KAAK,EAAE,MAAM,YAAY,CAAA;AAErD,sEAAsE;AACtE,wBAAgB,mBAAmB,CAAC,KAAK,GAAE,KAAoB,GAAG,aAAa,CAkB9E"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Markdown theme derived from the injected TUI palette. Assistant rows pass
3
+ * through the vendored Markdown component with this theme; fenced code blocks
4
+ * are syntax-highlighted via the `highlightCode` seam (see `code-theme.ts`).
5
+ * @module @dsh-cc/tui/components/markdown-theme
6
+ */
7
+ import { highlightCodeAnsi } from "./code-theme.js";
8
+ import { defaultTheme } from "./theme.js";
9
+ /** Map a theme onto the vendored Markdown component's style hooks. */
10
+ export function createMarkdownTheme(theme = defaultTheme) {
11
+ return {
12
+ heading: theme.bold,
13
+ link: theme.accent,
14
+ linkUrl: (text) => theme.muted(theme.underline(text)),
15
+ code: theme.warning,
16
+ codeBlock: theme.warning,
17
+ codeBlockBorder: theme.muted,
18
+ quote: theme.italic,
19
+ quoteBorder: theme.muted,
20
+ hr: theme.muted,
21
+ listBullet: theme.accent,
22
+ bold: theme.bold,
23
+ italic: theme.italic,
24
+ strikethrough: theme.strikethrough,
25
+ underline: theme.underline,
26
+ highlightCode: (code, lang) => highlightCodeAnsi(code, lang, theme),
27
+ };
28
+ }
29
+ //# sourceMappingURL=markdown-theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-theme.js","sourceRoot":"","sources":["../../src/components/markdown-theme.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAc,MAAM,YAAY,CAAA;AAErD,sEAAsE;AACtE,MAAM,UAAU,mBAAmB,CAAC,QAAe,YAAY;IAC7D,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,IAAI;QACnB,IAAI,EAAE,KAAK,CAAC,MAAM;QAClB,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,EAAE,KAAK,CAAC,OAAO;QACnB,SAAS,EAAE,KAAK,CAAC,OAAO;QACxB,eAAe,EAAE,KAAK,CAAC,KAAK;QAC5B,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,WAAW,EAAE,KAAK,CAAC,KAAK;QACxB,EAAE,EAAE,KAAK,CAAC,KAAK;QACf,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,aAAa,EAAE,CAAC,IAAY,EAAE,IAAa,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC;KACrF,CAAA;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Masked single-line text input (dsh-cc-side, first-party): a drop-in
3
+ * companion to pi-tui's `Input` for secrets (API keys). Display shows one
4
+ * `•` per grapheme instead of the raw characters; `getValue()` and `onSubmit`
5
+ * still receive the raw value. Key handling mirrors `Input`'s behavior using
6
+ * pi-tui's own public helpers — the vendored package itself is untouched.
7
+ * @module @dsh-cc/tui/components/masked-input
8
+ */
9
+ import { type Component, type Focusable } from '@dsh-cc/pi-tui';
10
+ export declare class MaskedInput implements Component, Focusable {
11
+ private value;
12
+ private cursor;
13
+ private pasteBuffer;
14
+ private isInPaste;
15
+ onSubmit?: (value: string) => void;
16
+ onEscape?: () => void;
17
+ focused: boolean;
18
+ getValue(): string;
19
+ setValue(value: string): void;
20
+ handleInput(data: string): void;
21
+ invalidate(): void;
22
+ render(width: number): string[];
23
+ }
24
+ //# sourceMappingURL=masked-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"masked-input.d.ts","sourceRoot":"","sources":["../../src/components/masked-input.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACN,KAAK,SAAS,EAEd,KAAK,SAAS,EAId,MAAM,gBAAgB,CAAA;AAUvB,qBAAa,WAAY,YAAW,SAAS,EAAE,SAAS;IACvD,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,SAAS,CAAQ;IAClB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IAC5B,OAAO,UAAQ;IAEf,QAAQ,IAAI,MAAM;IAIlB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAoF/B,UAAU,IAAI,IAAI;IAIlB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CA8C/B"}