@sagmans/dsh-tui 0.3.0 → 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 (253) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +407 -53
  3. package/cordis.patch.yml +14 -0
  4. package/lib/agent/present.js +1 -1
  5. package/lib/agent/present.js.map +1 -1
  6. package/lib/agent/projections.d.ts +22 -6
  7. package/lib/agent/projections.d.ts.map +1 -1
  8. package/lib/agent/projections.js +21 -10
  9. package/lib/agent/projections.js.map +1 -1
  10. package/lib/agent/prompt-history.d.ts +89 -0
  11. package/lib/agent/prompt-history.d.ts.map +1 -0
  12. package/lib/agent/prompt-history.js +382 -0
  13. package/lib/agent/prompt-history.js.map +1 -0
  14. package/lib/agent/status.d.ts +6 -0
  15. package/lib/agent/status.d.ts.map +1 -1
  16. package/lib/agent/status.js +1 -0
  17. package/lib/agent/status.js.map +1 -1
  18. package/lib/cards.d.ts +83 -13
  19. package/lib/cards.d.ts.map +1 -1
  20. package/lib/cards.js +96 -28
  21. package/lib/cards.js.map +1 -1
  22. package/lib/export.d.ts +3 -3
  23. package/lib/export.d.ts.map +1 -1
  24. package/lib/export.js +23 -13
  25. package/lib/export.js.map +1 -1
  26. package/lib/fold-cursor.d.ts +12 -5
  27. package/lib/fold-cursor.d.ts.map +1 -1
  28. package/lib/fold-cursor.js +16 -5
  29. package/lib/fold-cursor.js.map +1 -1
  30. package/lib/gates.d.ts.map +1 -1
  31. package/lib/gates.js +42 -9
  32. package/lib/gates.js.map +1 -1
  33. package/lib/herdr/client.d.ts +57 -0
  34. package/lib/herdr/client.d.ts.map +1 -0
  35. package/lib/herdr/client.js +218 -0
  36. package/lib/herdr/client.js.map +1 -0
  37. package/lib/herdr/constants.d.ts +93 -0
  38. package/lib/herdr/constants.d.ts.map +1 -0
  39. package/lib/herdr/constants.js +79 -0
  40. package/lib/herdr/constants.js.map +1 -0
  41. package/lib/herdr/reporter.d.ts +60 -0
  42. package/lib/herdr/reporter.d.ts.map +1 -0
  43. package/lib/herdr/reporter.js +217 -0
  44. package/lib/herdr/reporter.js.map +1 -0
  45. package/lib/herdr/state.d.ts +57 -0
  46. package/lib/herdr/state.d.ts.map +1 -0
  47. package/lib/herdr/state.js +62 -0
  48. package/lib/herdr/state.js.map +1 -0
  49. package/lib/index.d.ts.map +1 -1
  50. package/lib/index.js +700 -81
  51. package/lib/index.js.map +1 -1
  52. package/lib/injection.d.ts +9 -0
  53. package/lib/injection.d.ts.map +1 -0
  54. package/lib/injection.js +128 -0
  55. package/lib/injection.js.map +1 -0
  56. package/lib/input/actions.d.ts +19 -2
  57. package/lib/input/actions.d.ts.map +1 -1
  58. package/lib/input/actions.js +60 -11
  59. package/lib/input/actions.js.map +1 -1
  60. package/lib/input/cancel.d.ts +55 -0
  61. package/lib/input/cancel.d.ts.map +1 -0
  62. package/lib/input/cancel.js +47 -0
  63. package/lib/input/cancel.js.map +1 -0
  64. package/lib/input/completion.d.ts +5 -2
  65. package/lib/input/completion.d.ts.map +1 -1
  66. package/lib/input/completion.js +79 -4
  67. package/lib/input/completion.js.map +1 -1
  68. package/lib/input/file-search.d.ts +105 -0
  69. package/lib/input/file-search.d.ts.map +1 -0
  70. package/lib/input/file-search.js +665 -0
  71. package/lib/input/file-search.js.map +1 -0
  72. package/lib/input/fuzzy.d.ts +42 -0
  73. package/lib/input/fuzzy.d.ts.map +1 -0
  74. package/lib/input/fuzzy.js +289 -0
  75. package/lib/input/fuzzy.js.map +1 -0
  76. package/lib/input/ghost.d.ts +46 -0
  77. package/lib/input/ghost.d.ts.map +1 -0
  78. package/lib/input/ghost.js +58 -0
  79. package/lib/input/ghost.js.map +1 -0
  80. package/lib/input/keymap.d.ts +3 -1
  81. package/lib/input/keymap.d.ts.map +1 -1
  82. package/lib/input/keymap.js +16 -3
  83. package/lib/input/keymap.js.map +1 -1
  84. package/lib/input/match.d.ts +12 -4
  85. package/lib/input/match.d.ts.map +1 -1
  86. package/lib/input/match.js +50 -51
  87. package/lib/input/match.js.map +1 -1
  88. package/lib/input/submission.d.ts +34 -1
  89. package/lib/input/submission.d.ts.map +1 -1
  90. package/lib/input/submission.js +33 -5
  91. package/lib/input/submission.js.map +1 -1
  92. package/lib/keys-command.d.ts +19 -3
  93. package/lib/keys-command.d.ts.map +1 -1
  94. package/lib/keys-command.js +34 -31
  95. package/lib/keys-command.js.map +1 -1
  96. package/lib/settings-notice.d.ts +5 -0
  97. package/lib/settings-notice.d.ts.map +1 -1
  98. package/lib/settings-notice.js +9 -7
  99. package/lib/settings-notice.js.map +1 -1
  100. package/lib/stash/lock.d.ts +72 -0
  101. package/lib/stash/lock.d.ts.map +1 -0
  102. package/lib/stash/lock.js +374 -0
  103. package/lib/stash/lock.js.map +1 -0
  104. package/lib/stash/paths.d.ts +22 -0
  105. package/lib/stash/paths.d.ts.map +1 -0
  106. package/lib/stash/paths.js +84 -0
  107. package/lib/stash/paths.js.map +1 -0
  108. package/lib/stash/private-fs.d.ts +61 -0
  109. package/lib/stash/private-fs.d.ts.map +1 -0
  110. package/lib/stash/private-fs.js +379 -0
  111. package/lib/stash/private-fs.js.map +1 -0
  112. package/lib/stash/schema.d.ts +56 -0
  113. package/lib/stash/schema.d.ts.map +1 -0
  114. package/lib/stash/schema.js +108 -0
  115. package/lib/stash/schema.js.map +1 -0
  116. package/lib/stash/store.d.ts +92 -0
  117. package/lib/stash/store.d.ts.map +1 -0
  118. package/lib/stash/store.js +262 -0
  119. package/lib/stash/store.js.map +1 -0
  120. package/lib/stash.d.ts +122 -0
  121. package/lib/stash.d.ts.map +1 -0
  122. package/lib/stash.js +353 -0
  123. package/lib/stash.js.map +1 -0
  124. package/lib/terminal/external-editor.d.ts +93 -0
  125. package/lib/terminal/external-editor.d.ts.map +1 -0
  126. package/lib/terminal/external-editor.js +263 -0
  127. package/lib/terminal/external-editor.js.map +1 -0
  128. package/lib/terminal/host-writes.d.ts +39 -0
  129. package/lib/terminal/host-writes.d.ts.map +1 -0
  130. package/lib/terminal/host-writes.js +136 -0
  131. package/lib/terminal/host-writes.js.map +1 -0
  132. package/lib/terminal/signals.d.ts +25 -0
  133. package/lib/terminal/signals.d.ts.map +1 -0
  134. package/lib/terminal/signals.js +39 -0
  135. package/lib/terminal/signals.js.map +1 -0
  136. package/lib/terminal/warning-screen.d.ts +19 -1
  137. package/lib/terminal/warning-screen.d.ts.map +1 -1
  138. package/lib/terminal/warning-screen.js +37 -1
  139. package/lib/terminal/warning-screen.js.map +1 -1
  140. package/lib/terminal-text.d.ts +72 -0
  141. package/lib/terminal-text.d.ts.map +1 -0
  142. package/lib/terminal-text.js +603 -0
  143. package/lib/terminal-text.js.map +1 -0
  144. package/lib/text.d.ts +45 -6
  145. package/lib/text.d.ts.map +1 -1
  146. package/lib/text.js +106 -46
  147. package/lib/text.js.map +1 -1
  148. package/lib/theme-command.d.ts +7 -4
  149. package/lib/theme-command.d.ts.map +1 -1
  150. package/lib/theme-command.js +32 -12
  151. package/lib/theme-command.js.map +1 -1
  152. package/lib/theme-files.d.ts +110 -0
  153. package/lib/theme-files.d.ts.map +1 -0
  154. package/lib/theme-files.js +352 -0
  155. package/lib/theme-files.js.map +1 -0
  156. package/lib/theme-schema.d.ts +121 -0
  157. package/lib/theme-schema.d.ts.map +1 -0
  158. package/lib/theme-schema.js +87 -0
  159. package/lib/theme-schema.js.map +1 -0
  160. package/lib/theme-settings.d.ts +72 -10
  161. package/lib/theme-settings.d.ts.map +1 -1
  162. package/lib/theme-settings.js +162 -45
  163. package/lib/theme-settings.js.map +1 -1
  164. package/lib/theme-tokens.d.ts +39 -7
  165. package/lib/theme-tokens.d.ts.map +1 -1
  166. package/lib/theme-tokens.js +104 -13
  167. package/lib/theme-tokens.js.map +1 -1
  168. package/lib/theme.d.ts +24 -2
  169. package/lib/theme.d.ts.map +1 -1
  170. package/lib/theme.js +49 -6
  171. package/lib/theme.js.map +1 -1
  172. package/lib/todo-guard.d.ts +116 -0
  173. package/lib/todo-guard.d.ts.map +1 -0
  174. package/lib/todo-guard.js +259 -0
  175. package/lib/todo-guard.js.map +1 -0
  176. package/lib/tool-display.d.ts +57 -0
  177. package/lib/tool-display.d.ts.map +1 -0
  178. package/lib/tool-display.js +51 -0
  179. package/lib/tool-display.js.map +1 -0
  180. package/lib/transcript.d.ts +28 -0
  181. package/lib/transcript.d.ts.map +1 -1
  182. package/lib/transcript.js +126 -37
  183. package/lib/transcript.js.map +1 -1
  184. package/lib/ui/diff.d.ts +49 -0
  185. package/lib/ui/diff.d.ts.map +1 -0
  186. package/lib/ui/diff.js +208 -0
  187. package/lib/ui/diff.js.map +1 -0
  188. package/lib/ui/dock.d.ts.map +1 -1
  189. package/lib/ui/dock.js +9 -6
  190. package/lib/ui/dock.js.map +1 -1
  191. package/lib/ui/editor.d.ts +41 -1
  192. package/lib/ui/editor.d.ts.map +1 -1
  193. package/lib/ui/editor.js +100 -4
  194. package/lib/ui/editor.js.map +1 -1
  195. package/lib/ui/frame.d.ts +16 -5
  196. package/lib/ui/frame.d.ts.map +1 -1
  197. package/lib/ui/frame.js +32 -13
  198. package/lib/ui/frame.js.map +1 -1
  199. package/lib/ui/history-picker.d.ts +15 -0
  200. package/lib/ui/history-picker.d.ts.map +1 -0
  201. package/lib/ui/history-picker.js +26 -0
  202. package/lib/ui/history-picker.js.map +1 -0
  203. package/lib/ui/keymap-picker.d.ts +16 -0
  204. package/lib/ui/keymap-picker.d.ts.map +1 -0
  205. package/lib/ui/keymap-picker.js +41 -0
  206. package/lib/ui/keymap-picker.js.map +1 -0
  207. package/lib/ui/layout.d.ts +33 -0
  208. package/lib/ui/layout.d.ts.map +1 -0
  209. package/lib/ui/layout.js +33 -0
  210. package/lib/ui/layout.js.map +1 -0
  211. package/lib/ui/markdown.d.ts +25 -3
  212. package/lib/ui/markdown.d.ts.map +1 -1
  213. package/lib/ui/markdown.js +12 -8
  214. package/lib/ui/markdown.js.map +1 -1
  215. package/lib/ui/picker-card.d.ts +42 -0
  216. package/lib/ui/picker-card.d.ts.map +1 -0
  217. package/lib/ui/picker-card.js +148 -0
  218. package/lib/ui/picker-card.js.map +1 -0
  219. package/lib/ui/picker.d.ts +50 -2
  220. package/lib/ui/picker.d.ts.map +1 -1
  221. package/lib/ui/picker.js +66 -7
  222. package/lib/ui/picker.js.map +1 -1
  223. package/lib/ui/prompt.d.ts +12 -2
  224. package/lib/ui/prompt.d.ts.map +1 -1
  225. package/lib/ui/prompt.js +25 -2
  226. package/lib/ui/prompt.js.map +1 -1
  227. package/lib/ui/rows.d.ts +8 -6
  228. package/lib/ui/rows.d.ts.map +1 -1
  229. package/lib/ui/rows.js +10 -18
  230. package/lib/ui/rows.js.map +1 -1
  231. package/lib/ui/stash-picker.d.ts +43 -0
  232. package/lib/ui/stash-picker.d.ts.map +1 -0
  233. package/lib/ui/stash-picker.js +78 -0
  234. package/lib/ui/stash-picker.js.map +1 -0
  235. package/lib/ui/status.d.ts +2 -0
  236. package/lib/ui/status.d.ts.map +1 -1
  237. package/lib/ui/status.js +25 -16
  238. package/lib/ui/status.js.map +1 -1
  239. package/lib/ui/theme-picker.d.ts +18 -0
  240. package/lib/ui/theme-picker.d.ts.map +1 -0
  241. package/lib/ui/theme-picker.js +68 -0
  242. package/lib/ui/theme-picker.js.map +1 -0
  243. package/lib/ui/view.d.ts +146 -22
  244. package/lib/ui/view.d.ts.map +1 -1
  245. package/lib/ui/view.js +461 -154
  246. package/lib/ui/view.js.map +1 -1
  247. package/lib/work.d.ts +3 -1
  248. package/lib/work.d.ts.map +1 -1
  249. package/lib/work.js +9 -1
  250. package/lib/work.js.map +1 -1
  251. package/package.json +7 -1
  252. package/themes/deepseek-blue.yaml +183 -0
  253. package/themes/violet-orbit.yaml +178 -0
package/cordis.patch.yml CHANGED
@@ -97,6 +97,20 @@
97
97
  color: !!js ctx.tuiStartup.color
98
98
  bell: !!js ctx.tuiStartup.bell
99
99
 
100
+ # Advisory todo discipline for every agent this profile runs. The tool and
101
+ # its list already exist per session; this row only notices when a plan has
102
+ # aged and rides the next tool result with a reminder. It is host-plane on
103
+ # purpose: it registers no tool, provides no service, and never gates a
104
+ # call, so it needs no preset and no realm. `staleSteps` and the rest are
105
+ # documented in the README and overridable from a profile patch.
106
+ - id: tui-todo-guard
107
+ name: '@sagmans/dsh-tui/todo-guard'
108
+ config:
109
+ staleSteps: 6
110
+ missingListSteps: 12
111
+ maxRemindersPerTurn: 3
112
+ previewItems: 5
113
+
100
114
  # The roster of agent compositions, and the mode a session starts in when
101
115
  # nobody names one. PTC leads because a flagless run should reach every tool
102
116
  # through one program rather than one shell call at a time. A profile patch
@@ -67,7 +67,7 @@ export function createToolPresenter(ctx, scope) {
67
67
  try {
68
68
  const view = definition(name)?.presentResult?.(parseArguments(input.argumentsJson), { content: toolResultContent(input.content), isError: input.isError, meta: input.meta });
69
69
  return cardOfResult(view, {
70
- fallbackTitle: name,
70
+ name,
71
71
  failed: input.isError,
72
72
  contentLines: contentLines(input.content),
73
73
  });
@@ -1 +1 @@
1
- {"version":3,"file":"present.js","sourceRoot":"","sources":["../../src/agent/present.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,GAGb,MAAM,aAAa,CAAA;AAEpB,SAAS,cAAc,CAAC,aAAqB;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAY,CAAA;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,iBAAiB,CAAC,OAAgB;IACzC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAA;IAC3C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;YAAE,SAAQ;QACzD,MAAM,MAAM,GAAG,KAAgC,CAAA;QAC/C,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;YAAE,OAAO,MAAM,CAAC,OAAO,CAAA;IAC3F,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAY,EAAE,KAA+B;IAC/E,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE;QAClC,IAAI,CAAC;YACH,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC,CAAA;IACD,OAAO;QACL,IAAI,CAAC,IAAI,EAAE,aAAa;YACtB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC,cAAc,CAAC,aAAa,CAAU,CAAC,CAAA;gBACpF,wEAAwE;gBACxE,wEAAwE;gBACxE,sEAAsE;gBACtE,yCAAyC;gBACzC,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YAChE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAA;YAClB,CAAC;QACH,CAAC;QACD,MAAM,CAAC,IAAI,EAAE,KAAsB;YACjC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAC5C,cAAc,CAAC,KAAK,CAAC,aAAa,CAAU,EAC5C,EAAE,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAW,CACjG,CAAA;gBACD,OAAO,YAAY,CAAC,IAAI,EAAE;oBACxB,aAAa,EAAE,IAAI;oBACnB,MAAM,EAAE,KAAK,CAAC,OAAO;oBACrB,YAAY,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC;iBAC1C,CAAC,CAAA;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAA;YAClB,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"present.js","sourceRoot":"","sources":["../../src/agent/present.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,GAGb,MAAM,aAAa,CAAA;AAEpB,SAAS,cAAc,CAAC,aAAqB;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAY,CAAA;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,iBAAiB,CAAC,OAAgB;IACzC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAA;IAC3C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;YAAE,SAAQ;QACzD,MAAM,MAAM,GAAG,KAAgC,CAAA;QAC/C,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;YAAE,OAAO,MAAM,CAAC,OAAO,CAAA;IAC3F,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAY,EAAE,KAA+B;IAC/E,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE;QAClC,IAAI,CAAC;YACH,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC,CAAA;IACD,OAAO;QACL,IAAI,CAAC,IAAI,EAAE,aAAa;YACtB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC,cAAc,CAAC,aAAa,CAAU,CAAC,CAAA;gBACpF,wEAAwE;gBACxE,wEAAwE;gBACxE,sEAAsE;gBACtE,yCAAyC;gBACzC,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YAChE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAA;YAClB,CAAC;QACH,CAAC;QACD,MAAM,CAAC,IAAI,EAAE,KAAsB;YACjC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAC5C,cAAc,CAAC,KAAK,CAAC,aAAa,CAAU,EAC5C,EAAE,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAW,CACjG,CAAA;gBACD,OAAO,YAAY,CAAC,IAAI,EAAE;oBACxB,IAAI;oBACJ,MAAM,EAAE,KAAK,CAAC,OAAO;oBACrB,YAAY,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC;iBAC1C,CAAC,CAAA;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAA;YAClB,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -1,12 +1,28 @@
1
1
  import type { Context } from '@deepseek-ai/cordis';
2
+ /** One projection read that keeps "not registered" apart from "cannot answer". */
3
+ export type ProjectionRead = {
4
+ readonly kind: 'state';
5
+ readonly state: unknown;
6
+ } | {
7
+ readonly kind: 'unregistered';
8
+ } | {
9
+ readonly kind: 'unavailable';
10
+ };
2
11
  /**
3
- * One session projection's state.
12
+ * One session projection's state, with the reason a missing answer is kept.
4
13
  *
5
- * A composition without a projection registry, and a session whose projection
6
- * unit is not registered, both leave the key simply absent — and the surface
7
- * reads projections while rendering, where a missing fact may cost a segment
8
- * but never the session. A registered unit that throws is treated the same way
9
- * for the same reason.
14
+ * `stateOf` answers `undefined` only for a key that is not registered; a
15
+ * composition without a registry, and a registered unit that throws, are the
16
+ * two cases that leave nothing to read at all. A caller that merely decorates a
17
+ * screen may collapse them, but one deciding whether it knows enough to speak
18
+ * must be able to tell them apart.
19
+ */
20
+ export declare function projectionRead(ctx: Context, session: unknown, key: string): ProjectionRead;
21
+ /**
22
+ * One session projection's state, or `undefined` whenever there is none to read.
23
+ *
24
+ * The surface reads projections while rendering, where a missing fact may cost a
25
+ * segment but never the session, so every unreadable case collapses here.
10
26
  */
11
27
  export declare function projectionState(ctx: Context, session: unknown, key: string): unknown;
12
28
  /** One projection's state when it is a record. */
@@ -1 +1 @@
1
- {"version":3,"file":"projections.d.ts","sourceRoot":"","sources":["../../src/agent/projections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAOlD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAQpF;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,GACV,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAGrC;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGhG"}
1
+ {"version":3,"file":"projections.d.ts","sourceRoot":"","sources":["../../src/agent/projections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAOlD,kFAAkF;AAClF,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAAE,GACjC;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE,CAAA;AAEpC;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,CAS1F;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAGpF;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,GACV,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAGrC;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGhG"}
@@ -1,23 +1,34 @@
1
1
  /**
2
- * One session projection's state.
2
+ * One session projection's state, with the reason a missing answer is kept.
3
3
  *
4
- * A composition without a projection registry, and a session whose projection
5
- * unit is not registered, both leave the key simply absent — and the surface
6
- * reads projections while rendering, where a missing fact may cost a segment
7
- * but never the session. A registered unit that throws is treated the same way
8
- * for the same reason.
4
+ * `stateOf` answers `undefined` only for a key that is not registered; a
5
+ * composition without a registry, and a registered unit that throws, are the
6
+ * two cases that leave nothing to read at all. A caller that merely decorates a
7
+ * screen may collapse them, but one deciding whether it knows enough to speak
8
+ * must be able to tell them apart.
9
9
  */
10
- export function projectionState(ctx, session, key) {
10
+ export function projectionRead(ctx, session, key) {
11
11
  const projections = ctx.get('sessionProjections');
12
12
  if (projections?.stateOf === undefined)
13
- return undefined;
13
+ return { kind: 'unavailable' };
14
14
  try {
15
- return projections.stateOf(session, key);
15
+ const state = projections.stateOf(session, key);
16
+ return state === undefined ? { kind: 'unregistered' } : { kind: 'state', state };
16
17
  }
17
18
  catch {
18
- return undefined;
19
+ return { kind: 'unavailable' };
19
20
  }
20
21
  }
22
+ /**
23
+ * One session projection's state, or `undefined` whenever there is none to read.
24
+ *
25
+ * The surface reads projections while rendering, where a missing fact may cost a
26
+ * segment but never the session, so every unreadable case collapses here.
27
+ */
28
+ export function projectionState(ctx, session, key) {
29
+ const read = projectionRead(ctx, session, key);
30
+ return read.kind === 'state' ? read.state : undefined;
31
+ }
21
32
  /** One projection's state when it is a record. */
22
33
  export function projectionRecord(ctx, session, key) {
23
34
  const state = projectionState(ctx, session, key);
@@ -1 +1 @@
1
- {"version":3,"file":"projections.js","sourceRoot":"","sources":["../../src/agent/projections.ts"],"names":[],"mappings":"AAOA;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,GAAY,EAAE,OAAgB,EAAE,GAAW;IACzE,MAAM,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAA4B,CAAA;IAC5E,IAAI,WAAW,EAAE,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACxD,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,gBAAgB,CAC9B,GAAY,EACZ,OAAgB,EAChB,GAAW;IAEX,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,CAAA;IAChD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,CAAC,SAAS,CAAA;AACnG,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB,CAAC,GAAY,EAAE,OAAgB,EAAE,GAAW;IAC1E,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,CAAA;IAChD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACtE,CAAC"}
1
+ {"version":3,"file":"projections.js","sourceRoot":"","sources":["../../src/agent/projections.ts"],"names":[],"mappings":"AAaA;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY,EAAE,OAAgB,EAAE,GAAW;IACxE,MAAM,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAA4B,CAAA;IAC5E,IAAI,WAAW,EAAE,OAAO,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAA;IACtE,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;QAC/C,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;IAClF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAA;IAChC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,GAAY,EAAE,OAAgB,EAAE,GAAW;IACzE,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,CAAA;IAC9C,OAAO,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACvD,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,gBAAgB,CAC9B,GAAY,EACZ,OAAgB,EAChB,GAAW;IAEX,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,CAAA;IAChD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,CAAC,SAAS,CAAA;AACnG,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB,CAAC,GAAY,EAAE,OAAgB,EAAE,GAAW;IAC1E,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,CAAA;IAChD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACtE,CAAC"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Global prompt history for the terminal surface.
3
+ *
4
+ * The file is deliberately project-agnostic: a reader who types the same prompt
5
+ * in two checkouts wants it offered in both, so nothing here records a working
6
+ * directory. It lives beside the reader's other harness preferences rather than
7
+ * inside the profile, because a profile is replaced on install and history is
8
+ * theirs to keep.
9
+ */
10
+ /** Environment variable that overrides the harness home, matching the launcher. */
11
+ export declare const DSH_HOME_ENV = "DSH_HOME";
12
+ /** Directory name of the default harness home under the OS home. */
13
+ export declare const DSH_HOME_DIR_NAME = ".dsh";
14
+ /** File name the history is stored under, inside the harness home. */
15
+ export declare const HISTORY_FILE_NAME = "prompt-history.json";
16
+ /** Schema this build writes; a file that names another positive version is left alone. */
17
+ export declare const HISTORY_SCHEMA_VERSION = 1;
18
+ /** Entries kept when the reader configures nothing. */
19
+ export declare const DEFAULT_MAX_ENTRIES = 2000;
20
+ /** Largest cap a reader may ask for, so a typo cannot grow the file without bound. */
21
+ export declare const MAX_ENTRIES_LIMIT = 20000;
22
+ /** Why the store refuses to write, which is a reason the reader can act on. */
23
+ export type HistoryBlockReason = 'corrupt_history' | 'unsupported_schema' | 'unreadable_history';
24
+ /** One recorded prompt, newest first in the file. */
25
+ export interface PromptEntry {
26
+ readonly text: string;
27
+ readonly updatedAt: string;
28
+ readonly useCount: number;
29
+ }
30
+ /** The persisted document, versioned so a future shape can be recognized. */
31
+ export interface PromptHistoryFile {
32
+ readonly version: number;
33
+ readonly updatedAt: string;
34
+ readonly entries: readonly PromptEntry[];
35
+ }
36
+ /** A file read reduced to what a caller can act on. */
37
+ export type ParsedHistoryFile = {
38
+ readonly kind: 'ready';
39
+ readonly file: PromptHistoryFile;
40
+ } | {
41
+ readonly kind: 'blocked';
42
+ readonly reason: HistoryBlockReason;
43
+ };
44
+ /** The store the surface holds; mutations are fire-and-forget and serialized. */
45
+ export interface PromptHistory {
46
+ /** Current entries, newest first; the array identity is stable per snapshot. */
47
+ entries(): readonly PromptEntry[];
48
+ /** Persist one submitted prompt; blank input is ignored. */
49
+ record(text: string): void;
50
+ /** Remove every entry and report how many went. */
51
+ clear(): Promise<number>;
52
+ /** Resolve once every queued mutation has settled; errors are reported, not thrown. */
53
+ flush(): Promise<void>;
54
+ /** Absolute path of the file, for a status line and diagnostics. */
55
+ path(): string;
56
+ /** Why writes are refused, or undefined while the store is healthy. */
57
+ blockedReason(): HistoryBlockReason | undefined;
58
+ }
59
+ /** Inputs the surface supplies; every one is a seam a test drives. */
60
+ export interface PromptHistoryOptions {
61
+ /** Resolved harness home; defaults to $DSH_HOME or ~/.dsh. */
62
+ readonly home?: string;
63
+ /** Read per mutation so a settings edit takes effect without a restart. */
64
+ readonly cap: () => number;
65
+ readonly now?: () => Date;
66
+ readonly warn?: (message: string) => void;
67
+ /** Lock wait a test can shorten; defaults to LOCK_WAIT_MS. */
68
+ readonly lockWaitMs?: number;
69
+ }
70
+ /**
71
+ * Resolve the harness home.
72
+ *
73
+ * Precedence is the launcher's own: $DSH_HOME, then ~/.dsh. A blank override is
74
+ * treated as unset, because resolving to the working directory would scatter
75
+ * private history into whatever tree the reader happened to start from.
76
+ */
77
+ export declare function resolveDshHome(env?: NodeJS.ProcessEnv): string;
78
+ /** Read one persisted document, refusing anything this build cannot safely rewrite. */
79
+ export declare function parseHistoryFile(text: string): ParsedHistoryFile;
80
+ /**
81
+ * Put one prompt at the front, replacing an exact duplicate.
82
+ *
83
+ * A duplicate is moved rather than copied so a repeated prompt resurfaces as the
84
+ * newest suggestion without ever appearing twice in the list.
85
+ */
86
+ export declare function upsertEntry(entries: readonly PromptEntry[], text: string, now: string, maxEntries: number): PromptEntry[];
87
+ /** Build the store the surface records into and completes from. */
88
+ export declare function createPromptHistory(options: PromptHistoryOptions): PromptHistory;
89
+ //# sourceMappingURL=prompt-history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-history.d.ts","sourceRoot":"","sources":["../../src/agent/prompt-history.ts"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AAEH,mFAAmF;AACnF,eAAO,MAAM,YAAY,aAAa,CAAA;AACtC,oEAAoE;AACpE,eAAO,MAAM,iBAAiB,SAAS,CAAA;AACvC,sEAAsE;AACtE,eAAO,MAAM,iBAAiB,wBAAwB,CAAA;AACtD,0FAA0F;AAC1F,eAAO,MAAM,sBAAsB,IAAI,CAAA;AACvC,uDAAuD;AACvD,eAAO,MAAM,mBAAmB,OAAO,CAAA;AACvC,sFAAsF;AACtF,eAAO,MAAM,iBAAiB,QAAS,CAAA;AAmBvC,+EAA+E;AAC/E,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG,oBAAoB,GAAG,oBAAoB,CAAA;AAShG,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAA;CACzC;AAED,uDAAuD;AACvD,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,CAAA;AAErE,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,OAAO,IAAI,SAAS,WAAW,EAAE,CAAA;IACjC,4DAA4D;IAC5D,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,mDAAmD;IACnD,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACxB,uFAAuF;IACvF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,oEAAoE;IACpE,IAAI,IAAI,MAAM,CAAA;IACd,uEAAuE;IACvE,aAAa,IAAI,kBAAkB,GAAG,SAAS,CAAA;CAChD;AAED,sEAAsE;AACtE,MAAM,WAAW,oBAAoB;IACnC,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAA;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACzC,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAuJD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAM3E;AAED,uFAAuF;AACvF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAiBhE;AAyBD;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GACjB,WAAW,EAAE,CAMf;AAMD,mEAAmE;AACnE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAsGhF"}
@@ -0,0 +1,382 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { chmod, link, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
3
+ import { homedir } from 'node:os';
4
+ import { dirname, join, resolve as resolvePath } from 'node:path';
5
+ import { displayText } from "../text.js";
6
+ /**
7
+ * Global prompt history for the terminal surface.
8
+ *
9
+ * The file is deliberately project-agnostic: a reader who types the same prompt
10
+ * in two checkouts wants it offered in both, so nothing here records a working
11
+ * directory. It lives beside the reader's other harness preferences rather than
12
+ * inside the profile, because a profile is replaced on install and history is
13
+ * theirs to keep.
14
+ */
15
+ /** Environment variable that overrides the harness home, matching the launcher. */
16
+ export const DSH_HOME_ENV = 'DSH_HOME';
17
+ /** Directory name of the default harness home under the OS home. */
18
+ export const DSH_HOME_DIR_NAME = '.dsh';
19
+ /** File name the history is stored under, inside the harness home. */
20
+ export const HISTORY_FILE_NAME = 'prompt-history.json';
21
+ /** Schema this build writes; a file that names another positive version is left alone. */
22
+ export const HISTORY_SCHEMA_VERSION = 1;
23
+ /** Entries kept when the reader configures nothing. */
24
+ export const DEFAULT_MAX_ENTRIES = 2000;
25
+ /** Largest cap a reader may ask for, so a typo cannot grow the file without bound. */
26
+ export const MAX_ENTRIES_LIMIT = 20_000;
27
+ /** Only the reader can read or write the file. */
28
+ const PRIVATE_FILE_MODE = 0o600;
29
+ /** A created home directory stays private; an existing one is never re-moded. */
30
+ const PRIVATE_DIR_MODE = 0o700;
31
+ /** Suffix of the file that serializes mutations across sessions. */
32
+ const LOCK_SUFFIX = '.lock';
33
+ /** Suffix of the lock that guards replacing a lock whose holder stopped. */
34
+ const LOCK_RECLAIM_SUFFIX = '.reclaim';
35
+ /** Suffix of the file a lock is staged in before it is published. */
36
+ const LOCK_TEMP_SUFFIX = '.tmp';
37
+ /** How long a mutation waits for another session's lock before giving up. */
38
+ const LOCK_WAIT_MS = 2_000;
39
+ /** Delay between lock attempts, so a short hold is not a spin. */
40
+ const LOCK_RETRY_MS = 20;
41
+ /** Separates the fields a lock file names its holder with. */
42
+ const LOCK_FIELD_SEPARATOR = ' ';
43
+ /** One phrase per refusal, so a notice reads the same wherever it is raised. */
44
+ const BLOCK_DESCRIPTIONS = {
45
+ corrupt_history: 'corrupt',
46
+ unsupported_schema: 'a newer format',
47
+ unreadable_history: 'unreadable',
48
+ };
49
+ function isRecord(value) {
50
+ return typeof value === 'object' && value !== null;
51
+ }
52
+ function isAlreadyExists(error) {
53
+ return isRecord(error) && error.code === 'EEXIST';
54
+ }
55
+ function delay(ms) {
56
+ return new Promise(resolve => setTimeout(resolve, ms));
57
+ }
58
+ function serializeOwner(owner) {
59
+ return owner.pid + LOCK_FIELD_SEPARATOR + owner.token + '\n';
60
+ }
61
+ function parseOwner(text) {
62
+ const [pid, token] = text.trim().split(LOCK_FIELD_SEPARATOR);
63
+ const value = Number(pid);
64
+ if (!isPositiveInteger(value) || token === undefined || token === '')
65
+ return undefined;
66
+ return { pid: value, token };
67
+ }
68
+ /** Whether the recorded holder can still run; only ESRCH proves that it cannot. */
69
+ function isOwnerAlive(pid) {
70
+ try {
71
+ process.kill(pid, 0);
72
+ return true;
73
+ }
74
+ catch (error) {
75
+ return !isRecord(error) || error.code !== 'ESRCH';
76
+ }
77
+ }
78
+ /**
79
+ * Take the lock that serializes mutations across sessions.
80
+ *
81
+ * A second session that read the same entries before this one wrote would
82
+ * otherwise replace the file with its own view and lose the first session's
83
+ * prompts. The lock names its holder, so a dead session can be displaced while
84
+ * a running one is waited for, and a holder that never lets go costs one
85
+ * mutation rather than the whole file.
86
+ */
87
+ async function acquireLock(lockPath, waitMs) {
88
+ const deadline = Date.now() + waitMs;
89
+ const owner = { pid: process.pid, token: randomUUID() };
90
+ for (;;) {
91
+ const contents = await readFile(lockPath, 'utf8').catch(() => undefined);
92
+ if (contents !== undefined) {
93
+ const holder = parseOwner(contents);
94
+ if (holder !== undefined && isOwnerAlive(holder.pid)) {
95
+ if (Date.now() >= deadline)
96
+ throw new Error('another session is writing the prompt history');
97
+ await delay(LOCK_RETRY_MS);
98
+ continue;
99
+ }
100
+ await reclaimLock(lockPath, contents, Math.max(1, deadline - Date.now()));
101
+ continue;
102
+ }
103
+ if (await publishLock(lockPath, owner))
104
+ return owner;
105
+ }
106
+ }
107
+ /** Publish a lock naming `owner`; false when another holder got there first. */
108
+ async function publishLock(lockPath, owner) {
109
+ // The holder is written before the lock path exists, so a contender can never
110
+ // read a half-published lock and displace a live session.
111
+ const staged = lockPath + '.' + owner.token + LOCK_TEMP_SUFFIX;
112
+ await writeFile(staged, serializeOwner(owner), { encoding: 'utf8', mode: PRIVATE_FILE_MODE });
113
+ try {
114
+ await link(staged, lockPath);
115
+ return true;
116
+ }
117
+ catch (error) {
118
+ if (!isAlreadyExists(error))
119
+ throw error;
120
+ return false;
121
+ }
122
+ finally {
123
+ await rm(staged, { force: true }).catch(() => { });
124
+ }
125
+ }
126
+ /**
127
+ * Replace a lock whose holder cannot run, under a lock of its own.
128
+ *
129
+ * Two sessions that both judge the same lock dead would otherwise each remove
130
+ * it, and one could remove the lock the other had just published, admitting two
131
+ * writers. Displacing a stopped reclaimer would need a third lock, so that case
132
+ * refuses instead: a wrong guess here means concurrent writers.
133
+ */
134
+ async function reclaimLock(lockPath, deadContents, waitMs) {
135
+ const reclaimPath = lockPath + LOCK_RECLAIM_SUFFIX;
136
+ const owner = { pid: process.pid, token: randomUUID() };
137
+ const deadline = Date.now() + waitMs;
138
+ for (;;) {
139
+ const contents = await readFile(reclaimPath, 'utf8').catch(() => undefined);
140
+ if (contents === undefined) {
141
+ if (await publishLock(reclaimPath, owner))
142
+ break;
143
+ continue;
144
+ }
145
+ const holder = parseOwner(contents);
146
+ if (holder !== undefined && isOwnerAlive(holder.pid)) {
147
+ if (Date.now() >= deadline)
148
+ throw new Error('another session is reclaiming the prompt history lock');
149
+ await delay(LOCK_RETRY_MS);
150
+ continue;
151
+ }
152
+ throw new Error('prompt history lock at ' + reclaimPath + ' names a session that stopped; remove it to continue');
153
+ }
154
+ try {
155
+ // No other reclaimer runs now, and a path cannot be published over, so the
156
+ // dead lock is still the one this session judged.
157
+ const current = await readFile(lockPath, 'utf8').catch(() => undefined);
158
+ if (current === deadContents)
159
+ await rm(lockPath, { force: true });
160
+ }
161
+ finally {
162
+ await releaseLock(reclaimPath, owner);
163
+ }
164
+ }
165
+ /** Give the lock back only while it still names this holder, never a successor. */
166
+ async function releaseLock(lockPath, owner) {
167
+ const contents = await readFile(lockPath, 'utf8').catch(() => undefined);
168
+ if (contents !== serializeOwner(owner))
169
+ return;
170
+ await rm(lockPath, { force: true }).catch(() => { });
171
+ }
172
+ /** Run one read-modify-replace under the lock, so nothing lands between them. */
173
+ async function withLock(lockPath, waitMs, operation) {
174
+ await mkdir(dirname(lockPath), { recursive: true, mode: PRIVATE_DIR_MODE });
175
+ const owner = await acquireLock(lockPath, waitMs);
176
+ try {
177
+ return await operation();
178
+ }
179
+ finally {
180
+ await releaseLock(lockPath, owner);
181
+ }
182
+ }
183
+ function isPositiveInteger(value) {
184
+ return typeof value === 'number' && Number.isSafeInteger(value) && value > 0;
185
+ }
186
+ /** Expand a tilde the way the launcher does, so both spell the home the same. */
187
+ function expandHome(path) {
188
+ if (path === '~')
189
+ return homedir();
190
+ if (path.startsWith('~/') || path.startsWith('~\\'))
191
+ return join(homedir(), path.slice(2));
192
+ return path;
193
+ }
194
+ /**
195
+ * Resolve the harness home.
196
+ *
197
+ * Precedence is the launcher's own: $DSH_HOME, then ~/.dsh. A blank override is
198
+ * treated as unset, because resolving to the working directory would scatter
199
+ * private history into whatever tree the reader happened to start from.
200
+ */
201
+ export function resolveDshHome(env = process.env) {
202
+ const configured = env[DSH_HOME_ENV];
203
+ const chosen = configured !== undefined && configured.trim() !== ''
204
+ ? expandHome(configured)
205
+ : join(homedir(), DSH_HOME_DIR_NAME);
206
+ return resolvePath(chosen);
207
+ }
208
+ /** Read one persisted document, refusing anything this build cannot safely rewrite. */
209
+ export function parseHistoryFile(text) {
210
+ let raw;
211
+ try {
212
+ raw = JSON.parse(text);
213
+ }
214
+ catch {
215
+ return { kind: 'blocked', reason: 'corrupt_history' };
216
+ }
217
+ if (!isRecord(raw) || !isPositiveInteger(raw.version))
218
+ return { kind: 'blocked', reason: 'corrupt_history' };
219
+ // Any other positive version may be valid to newer code, so preserve it rather
220
+ // than normalize it away and lose entries this build does not understand.
221
+ if (raw.version !== HISTORY_SCHEMA_VERSION)
222
+ return { kind: 'blocked', reason: 'unsupported_schema' };
223
+ if (typeof raw.updatedAt !== 'string' || !Array.isArray(raw.entries)) {
224
+ return { kind: 'blocked', reason: 'corrupt_history' };
225
+ }
226
+ const entries = normalizeEntries(raw.entries);
227
+ if (entries === undefined)
228
+ return { kind: 'blocked', reason: 'corrupt_history' };
229
+ return { kind: 'ready', file: { version: HISTORY_SCHEMA_VERSION, updatedAt: raw.updatedAt, entries } };
230
+ }
231
+ function normalizeEntries(rawEntries) {
232
+ const entries = [];
233
+ for (const raw of rawEntries) {
234
+ const normalized = normalizeEntry(raw);
235
+ if (normalized === undefined)
236
+ return undefined;
237
+ entries.push(normalized);
238
+ }
239
+ return entries;
240
+ }
241
+ function normalizeEntry(raw) {
242
+ if (!isRecord(raw))
243
+ return undefined;
244
+ if (typeof raw.text !== 'string' || raw.text.trim() === '')
245
+ return undefined;
246
+ if (typeof raw.updatedAt !== 'string')
247
+ return undefined;
248
+ if (!isPositiveInteger(raw.useCount))
249
+ return undefined;
250
+ // A prompt reaches the ghost, the picker, and the bar again, and the terminal
251
+ // executes what it is given: the stored text is the one boundary every later
252
+ // consumer crosses, so a control sequence is spelled out before it is kept. A
253
+ // tab is kept as a tab, because the bar it is restored into has stops of its
254
+ // own and expanding it here would change what the reader typed.
255
+ return { text: displayText(raw.text, { tab: 'keep' }), updatedAt: raw.updatedAt, useCount: raw.useCount };
256
+ }
257
+ /**
258
+ * Put one prompt at the front, replacing an exact duplicate.
259
+ *
260
+ * A duplicate is moved rather than copied so a repeated prompt resurfaces as the
261
+ * newest suggestion without ever appearing twice in the list.
262
+ */
263
+ export function upsertEntry(entries, text, now, maxEntries) {
264
+ const existing = entries.find(entry => entry.text === text);
265
+ const next = existing === undefined
266
+ ? { text, updatedAt: now, useCount: 1 }
267
+ : { text, updatedAt: laterTimestamp(existing.updatedAt, now), useCount: existing.useCount + 1 };
268
+ return [next, ...entries.filter(entry => entry.text !== text)].slice(0, Math.max(0, maxEntries));
269
+ }
270
+ function laterTimestamp(left, right) {
271
+ return left >= right ? left : right;
272
+ }
273
+ /** Build the store the surface records into and completes from. */
274
+ export function createPromptHistory(options) {
275
+ const now = options.now ?? (() => new Date());
276
+ const warn = options.warn ?? (() => { });
277
+ const filePath = join(options.home ?? resolveDshHome(), HISTORY_FILE_NAME);
278
+ const lockPath = filePath + LOCK_SUFFIX;
279
+ let entries = [];
280
+ let blocked;
281
+ const warned = new Set();
282
+ const warnOnce = (key, message) => {
283
+ if (warned.has(key))
284
+ return;
285
+ warned.add(key);
286
+ warn(message);
287
+ };
288
+ // Every mutation rides one chain so a clear can never be overtaken by a record
289
+ // that started earlier; without it a slow initial read could resurrect an
290
+ // entry the reader just removed. Each mutation also re-reads the file, because
291
+ // a second session may have written since this one loaded and its prompts must
292
+ // be folded in rather than overwritten.
293
+ let chain = load();
294
+ async function load() {
295
+ let text;
296
+ try {
297
+ text = await readFile(filePath, 'utf8');
298
+ }
299
+ catch (error) {
300
+ if (isMissingFile(error))
301
+ return;
302
+ blocked = 'unreadable_history';
303
+ warnOnce('load:unreadable', 'prompt history is unreadable; writes are disabled until it can be read');
304
+ return;
305
+ }
306
+ const parsed = parseHistoryFile(text);
307
+ if (parsed.kind === 'blocked') {
308
+ blocked = parsed.reason;
309
+ warnOnce('load:' + parsed.reason, 'prompt history is ' + BLOCK_DESCRIPTIONS[parsed.reason] + '; writes are disabled and the file is left untouched');
310
+ return;
311
+ }
312
+ entries = parsed.file.entries;
313
+ }
314
+ function enqueue(operation) {
315
+ const run = chain.then(operation);
316
+ chain = run.then(() => { }, () => { });
317
+ return run;
318
+ }
319
+ async function write() {
320
+ const file = { version: HISTORY_SCHEMA_VERSION, updatedAt: now().toISOString(), entries };
321
+ const tempPath = filePath + '.' + process.pid + '.' + Date.now() + '.tmp';
322
+ await mkdir(dirname(filePath), { recursive: true, mode: PRIVATE_DIR_MODE });
323
+ try {
324
+ await writeFile(tempPath, JSON.stringify(file, null, 2) + '\n', { encoding: 'utf8', mode: PRIVATE_FILE_MODE });
325
+ await chmod(tempPath, PRIVATE_FILE_MODE);
326
+ await rename(tempPath, filePath);
327
+ }
328
+ catch (error) {
329
+ await rm(tempPath, { force: true });
330
+ throw error;
331
+ }
332
+ }
333
+ return {
334
+ entries: () => entries,
335
+ path: () => filePath,
336
+ blockedReason: () => blocked,
337
+ record(text) {
338
+ if (text.trim() === '')
339
+ return;
340
+ const prompt = displayText(text, { tab: 'keep' });
341
+ void enqueue(() => withLock(lockPath, options.lockWaitMs ?? LOCK_WAIT_MS, async () => {
342
+ await load();
343
+ if (blocked !== undefined)
344
+ return;
345
+ entries = upsertEntry(entries, prompt, now().toISOString(), options.cap());
346
+ await write();
347
+ })).catch((error) => {
348
+ // The reason can name the lock file that must be removed by hand, so it
349
+ // belongs in the notice rather than behind a single opaque sentence.
350
+ const reason = error instanceof Error && error.message !== '' ? ': ' + error.message : '';
351
+ warnOnce('write' + reason, 'prompt history could not be written; this session keeps it in memory only' + reason);
352
+ });
353
+ },
354
+ clear() {
355
+ return enqueue(() => withLock(lockPath, options.lockWaitMs ?? LOCK_WAIT_MS, async () => {
356
+ await load();
357
+ // A file that changed under the reader cannot be cleared safely, and
358
+ // reporting a successful clear of nothing would be worse than refusing.
359
+ if (blocked !== undefined)
360
+ throw new Error('the file is ' + BLOCK_DESCRIPTIONS[blocked]);
361
+ const removed = entries.length;
362
+ const previous = entries;
363
+ entries = [];
364
+ try {
365
+ await write();
366
+ }
367
+ catch (error) {
368
+ // The file still holds the prompts, so memory follows it back rather
369
+ // than reporting a clear the reader would meet again on next start.
370
+ entries = previous;
371
+ throw error;
372
+ }
373
+ return removed;
374
+ }));
375
+ },
376
+ flush: () => chain,
377
+ };
378
+ }
379
+ function isMissingFile(error) {
380
+ return isRecord(error) && error.code === 'ENOENT';
381
+ }
382
+ //# sourceMappingURL=prompt-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-history.js","sourceRoot":"","sources":["../../src/agent/prompt-history.ts"],"names":[],"mappings":"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"}