@astralyn/pi 1.4.5 → 1.4.7

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 (324) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/bundle/chunks/chunk-FODCTZXW.js +230 -0
  3. package/dist/bundle/chunks/{chunk-I5S7H7GA.js → chunk-FYKNSJG6.js} +1 -1
  4. package/dist/bundle/chunks/{chunk-AXFWZIHH.js → chunk-MG5XDTXV.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-ALHAFUHP.js → chunk-PU2IWWXV.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-5M3YJ54Z.js → chunk-RO2VH6UZ.js} +1 -1
  7. package/dist/bundle/chunks/chunk-YJTSOLP2.js +1499 -0
  8. package/dist/bundle/chunks/{cli-FH77R7JR.js → cli-MEL7SGJD.js} +1 -1
  9. package/dist/bundle/chunks/{execute-GMFGC27P.js → execute-4CWRNHPO.js} +1 -1
  10. package/dist/bundle/chunks/{runtime-R5CMHJ5P.js → runtime-R3X67XMR.js} +1 -1
  11. package/dist/bundle/chunks/{virtual-modules-6FUV7ZDV.js → virtual-modules-PKEOKGYI.js} +1 -1
  12. package/dist/bundle/cli.js +1 -1
  13. package/dist/bundle/index.js +1 -1
  14. package/dist/bundle/rpc-entry.js +1 -1
  15. package/dist/core/agent-session.d.ts +0 -3
  16. package/dist/core/agent-session.d.ts.map +1 -1
  17. package/dist/core/agent-session.js +0 -4
  18. package/dist/core/agent-session.js.map +1 -1
  19. package/dist/core/extensions/index.d.ts +1 -1
  20. package/dist/core/extensions/index.d.ts.map +1 -1
  21. package/dist/core/extensions/index.js.map +1 -1
  22. package/dist/core/isolated-session.d.ts +23 -0
  23. package/dist/core/isolated-session.d.ts.map +1 -0
  24. package/dist/core/isolated-session.js +55 -0
  25. package/dist/core/isolated-session.js.map +1 -0
  26. package/dist/core/package-manager.d.ts +7 -1
  27. package/dist/core/package-manager.d.ts.map +1 -1
  28. package/dist/core/package-manager.js +72 -1
  29. package/dist/core/package-manager.js.map +1 -1
  30. package/dist/core/resource-loader.d.ts +1 -0
  31. package/dist/core/resource-loader.d.ts.map +1 -1
  32. package/dist/core/resource-loader.js +23 -7
  33. package/dist/core/resource-loader.js.map +1 -1
  34. package/dist/core/settings-manager.d.ts +4 -2
  35. package/dist/core/settings-manager.d.ts.map +1 -1
  36. package/dist/core/settings-manager.js +11 -0
  37. package/dist/core/settings-manager.js.map +1 -1
  38. package/dist/core/settings-schema.d.ts +7 -0
  39. package/dist/core/settings-schema.d.ts.map +1 -1
  40. package/dist/core/settings-schema.js +6 -0
  41. package/dist/core/settings-schema.js.map +1 -1
  42. package/dist/core/skills.d.ts +10 -0
  43. package/dist/core/skills.d.ts.map +1 -1
  44. package/dist/core/skills.js +23 -0
  45. package/dist/core/skills.js.map +1 -1
  46. package/dist/core/tasks/codec.d.ts +12 -0
  47. package/dist/core/tasks/codec.d.ts.map +1 -0
  48. package/dist/core/tasks/codec.js +139 -0
  49. package/dist/core/tasks/codec.js.map +1 -0
  50. package/dist/core/tasks/delivery.d.ts +11 -4
  51. package/dist/core/tasks/delivery.d.ts.map +1 -1
  52. package/dist/core/tasks/delivery.js +9 -9
  53. package/dist/core/tasks/delivery.js.map +1 -1
  54. package/dist/core/tasks/execution.d.ts +71 -0
  55. package/dist/core/tasks/execution.d.ts.map +1 -0
  56. package/dist/core/tasks/execution.js +292 -0
  57. package/dist/core/tasks/execution.js.map +1 -0
  58. package/dist/core/tasks/format.d.ts +0 -2
  59. package/dist/core/tasks/format.d.ts.map +1 -1
  60. package/dist/core/tasks/format.js +1 -16
  61. package/dist/core/tasks/format.js.map +1 -1
  62. package/dist/core/tasks/limits.d.ts +12 -1
  63. package/dist/core/tasks/limits.d.ts.map +1 -1
  64. package/dist/core/tasks/limits.js +20 -1
  65. package/dist/core/tasks/limits.js.map +1 -1
  66. package/dist/core/tasks/output.d.ts +17 -17
  67. package/dist/core/tasks/output.d.ts.map +1 -1
  68. package/dist/core/tasks/output.js +72 -69
  69. package/dist/core/tasks/output.js.map +1 -1
  70. package/dist/core/tasks/presentation.d.ts +14 -5
  71. package/dist/core/tasks/presentation.d.ts.map +1 -1
  72. package/dist/core/tasks/presentation.js +56 -185
  73. package/dist/core/tasks/presentation.js.map +1 -1
  74. package/dist/core/tasks/record.d.ts +45 -0
  75. package/dist/core/tasks/record.d.ts.map +1 -0
  76. package/dist/core/tasks/record.js +80 -0
  77. package/dist/core/tasks/record.js.map +1 -0
  78. package/dist/core/tasks/runtime.d.ts +22 -22
  79. package/dist/core/tasks/runtime.d.ts.map +1 -1
  80. package/dist/core/tasks/runtime.js +170 -343
  81. package/dist/core/tasks/runtime.js.map +1 -1
  82. package/dist/core/tasks/scheduler.d.ts +16 -0
  83. package/dist/core/tasks/scheduler.d.ts.map +1 -0
  84. package/dist/core/tasks/scheduler.js +42 -0
  85. package/dist/core/tasks/scheduler.js.map +1 -0
  86. package/dist/core/tasks/session.d.ts +1 -1
  87. package/dist/core/tasks/session.d.ts.map +1 -1
  88. package/dist/core/tasks/session.js +22 -35
  89. package/dist/core/tasks/session.js.map +1 -1
  90. package/dist/core/tasks/store.d.ts +18 -25
  91. package/dist/core/tasks/store.d.ts.map +1 -1
  92. package/dist/core/tasks/store.js +45 -43
  93. package/dist/core/tasks/store.js.map +1 -1
  94. package/dist/core/tasks/types.d.ts +159 -70
  95. package/dist/core/tasks/types.d.ts.map +1 -1
  96. package/dist/core/tasks/types.js +3 -9
  97. package/dist/core/tasks/types.js.map +1 -1
  98. package/dist/core/tools/shell-execution.d.ts +8 -7
  99. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  100. package/dist/core/tools/shell-execution.js +19 -27
  101. package/dist/core/tools/shell-execution.js.map +1 -1
  102. package/dist/core/tools/shell-tool.d.ts.map +1 -1
  103. package/dist/core/tools/shell-tool.js +42 -47
  104. package/dist/core/tools/shell-tool.js.map +1 -1
  105. package/dist/core/usage-totals.d.ts +4 -3
  106. package/dist/core/usage-totals.d.ts.map +1 -1
  107. package/dist/core/usage-totals.js +32 -8
  108. package/dist/core/usage-totals.js.map +1 -1
  109. package/dist/extensions/agent/activity.d.ts +4 -4
  110. package/dist/extensions/agent/activity.d.ts.map +1 -1
  111. package/dist/extensions/agent/activity.js +15 -24
  112. package/dist/extensions/agent/activity.js.map +1 -1
  113. package/dist/extensions/agent/index.d.ts +2 -11
  114. package/dist/extensions/agent/index.d.ts.map +1 -1
  115. package/dist/extensions/agent/index.js +3 -88
  116. package/dist/extensions/agent/index.js.map +1 -1
  117. package/dist/extensions/agent/progress.d.ts +31 -0
  118. package/dist/extensions/agent/progress.d.ts.map +1 -0
  119. package/dist/extensions/agent/progress.js +135 -0
  120. package/dist/extensions/agent/progress.js.map +1 -0
  121. package/dist/extensions/agent/render.d.ts.map +1 -1
  122. package/dist/extensions/agent/render.js +8 -17
  123. package/dist/extensions/agent/render.js.map +1 -1
  124. package/dist/extensions/agent/report.d.ts +9 -0
  125. package/dist/extensions/agent/report.d.ts.map +1 -0
  126. package/dist/extensions/agent/report.js +40 -0
  127. package/dist/extensions/agent/report.js.map +1 -0
  128. package/dist/extensions/agent/settings-panel.d.ts +43 -0
  129. package/dist/extensions/agent/settings-panel.d.ts.map +1 -0
  130. package/dist/extensions/agent/settings-panel.js +125 -0
  131. package/dist/extensions/agent/settings-panel.js.map +1 -0
  132. package/dist/extensions/agent/settings.d.ts +1 -1
  133. package/dist/extensions/agent/settings.d.ts.map +1 -1
  134. package/dist/extensions/agent/settings.js +101 -83
  135. package/dist/extensions/agent/settings.js.map +1 -1
  136. package/dist/extensions/agent/tool.d.ts +13 -0
  137. package/dist/extensions/agent/tool.d.ts.map +1 -0
  138. package/dist/extensions/agent/tool.js +88 -0
  139. package/dist/extensions/agent/tool.js.map +1 -0
  140. package/dist/extensions/agent/types.d.ts +19 -21
  141. package/dist/extensions/agent/types.d.ts.map +1 -1
  142. package/dist/extensions/agent/types.js +2 -10
  143. package/dist/extensions/agent/types.js.map +1 -1
  144. package/dist/extensions/agent/worker.d.ts +16 -0
  145. package/dist/extensions/agent/worker.d.ts.map +1 -0
  146. package/dist/extensions/agent/worker.js +66 -0
  147. package/dist/extensions/agent/worker.js.map +1 -0
  148. package/dist/extensions/btw/agent.d.ts +1 -1
  149. package/dist/extensions/btw/agent.d.ts.map +1 -1
  150. package/dist/extensions/btw/agent.js +3 -20
  151. package/dist/extensions/btw/agent.js.map +1 -1
  152. package/dist/extensions/cached-compaction/index.d.ts.map +1 -1
  153. package/dist/extensions/cached-compaction/index.js +3 -22
  154. package/dist/extensions/cached-compaction/index.js.map +1 -1
  155. package/dist/extensions/cached-compaction/render.d.ts +1 -0
  156. package/dist/extensions/cached-compaction/render.d.ts.map +1 -1
  157. package/dist/extensions/cached-compaction/render.js +42 -14
  158. package/dist/extensions/cached-compaction/render.js.map +1 -1
  159. package/dist/extensions/deepwiki/client.d.ts.map +1 -1
  160. package/dist/extensions/deepwiki/client.js +6 -78
  161. package/dist/extensions/deepwiki/client.js.map +1 -1
  162. package/dist/extensions/deepwiki/transport.d.ts +3 -0
  163. package/dist/extensions/deepwiki/transport.d.ts.map +1 -0
  164. package/dist/extensions/deepwiki/transport.js +96 -0
  165. package/dist/extensions/deepwiki/transport.js.map +1 -0
  166. package/dist/extensions/provider/ui/builtin-data.d.ts +3 -3
  167. package/dist/extensions/provider/ui/builtin-data.d.ts.map +1 -1
  168. package/dist/extensions/provider/ui/builtin-data.js.map +1 -1
  169. package/dist/extensions/provider/ui/compat.d.ts +3 -3
  170. package/dist/extensions/provider/ui/compat.d.ts.map +1 -1
  171. package/dist/extensions/provider/ui/compat.js.map +1 -1
  172. package/dist/extensions/provider/ui/controls.d.ts +2 -2
  173. package/dist/extensions/provider/ui/controls.d.ts.map +1 -1
  174. package/dist/extensions/provider/ui/controls.js.map +1 -1
  175. package/dist/extensions/provider/ui/dialogs.d.ts +3 -3
  176. package/dist/extensions/provider/ui/dialogs.d.ts.map +1 -1
  177. package/dist/extensions/provider/ui/dialogs.js.map +1 -1
  178. package/dist/extensions/provider/ui/dictionary.d.ts +2 -2
  179. package/dist/extensions/provider/ui/dictionary.d.ts.map +1 -1
  180. package/dist/extensions/provider/ui/dictionary.js.map +1 -1
  181. package/dist/extensions/provider/ui/editor.d.ts.map +1 -1
  182. package/dist/extensions/provider/ui/editor.js +1 -3
  183. package/dist/extensions/provider/ui/editor.js.map +1 -1
  184. package/dist/extensions/provider/ui/fetch-models.d.ts +2 -2
  185. package/dist/extensions/provider/ui/fetch-models.d.ts.map +1 -1
  186. package/dist/extensions/provider/ui/fetch-models.js.map +1 -1
  187. package/dist/extensions/provider/ui/model-fields.d.ts +2 -2
  188. package/dist/extensions/provider/ui/model-fields.d.ts.map +1 -1
  189. package/dist/extensions/provider/ui/model-fields.js.map +1 -1
  190. package/dist/extensions/provider/ui/model-options.d.ts +6 -6
  191. package/dist/extensions/provider/ui/model-options.d.ts.map +1 -1
  192. package/dist/extensions/provider/ui/model-options.js.map +1 -1
  193. package/dist/extensions/provider/ui/pane.d.ts +21 -12
  194. package/dist/extensions/provider/ui/pane.d.ts.map +1 -1
  195. package/dist/extensions/provider/ui/pane.js.map +1 -1
  196. package/dist/extensions/provider/ui/provider-fields.d.ts +3 -3
  197. package/dist/extensions/provider/ui/provider-fields.d.ts.map +1 -1
  198. package/dist/extensions/provider/ui/provider-fields.js.map +1 -1
  199. package/dist/extensions/provider/ui/thinking-map.d.ts +2 -2
  200. package/dist/extensions/provider/ui/thinking-map.d.ts.map +1 -1
  201. package/dist/extensions/provider/ui/thinking-map.js.map +1 -1
  202. package/dist/extensions/run-summary/format.js +1 -1
  203. package/dist/extensions/run-summary/format.js.map +1 -1
  204. package/dist/extensions/statusline/usage.d.ts.map +1 -1
  205. package/dist/extensions/statusline/usage.js +2 -6
  206. package/dist/extensions/statusline/usage.js.map +1 -1
  207. package/dist/extensions/tasks/tool/actions.d.ts +1 -1
  208. package/dist/extensions/tasks/tool/actions.d.ts.map +1 -1
  209. package/dist/extensions/tasks/tool/actions.js +50 -115
  210. package/dist/extensions/tasks/tool/actions.js.map +1 -1
  211. package/dist/extensions/tasks/tool/constants.d.ts +1 -6
  212. package/dist/extensions/tasks/tool/constants.d.ts.map +1 -1
  213. package/dist/extensions/tasks/tool/constants.js +1 -6
  214. package/dist/extensions/tasks/tool/constants.js.map +1 -1
  215. package/dist/extensions/tasks/tool/schema.d.ts +0 -3
  216. package/dist/extensions/tasks/tool/schema.d.ts.map +1 -1
  217. package/dist/extensions/tasks/tool/schema.js +5 -14
  218. package/dist/extensions/tasks/tool/schema.js.map +1 -1
  219. package/dist/extensions/tasks/tool/types.d.ts +2 -8
  220. package/dist/extensions/tasks/tool/types.d.ts.map +1 -1
  221. package/dist/extensions/tasks/tool/types.js +0 -2
  222. package/dist/extensions/tasks/tool/types.js.map +1 -1
  223. package/dist/extensions/tasks/tool.d.ts.map +1 -1
  224. package/dist/extensions/tasks/tool.js +2 -2
  225. package/dist/extensions/tasks/tool.js.map +1 -1
  226. package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
  227. package/dist/extensions/tasks/ui/completion-render.js +46 -47
  228. package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
  229. package/dist/extensions/tasks/ui/inspector.d.ts +5 -3
  230. package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
  231. package/dist/extensions/tasks/ui/inspector.js +18 -6
  232. package/dist/extensions/tasks/ui/inspector.js.map +1 -1
  233. package/dist/extensions/tasks/ui/layout.d.ts +7 -7
  234. package/dist/extensions/tasks/ui/layout.d.ts.map +1 -1
  235. package/dist/extensions/tasks/ui/layout.js +118 -84
  236. package/dist/extensions/tasks/ui/layout.js.map +1 -1
  237. package/dist/extensions/tasks/ui/list.d.ts.map +1 -1
  238. package/dist/extensions/tasks/ui/list.js +45 -31
  239. package/dist/extensions/tasks/ui/list.js.map +1 -1
  240. package/dist/extensions/tasks/ui/manager.d.ts +16 -7
  241. package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
  242. package/dist/extensions/tasks/ui/manager.js +167 -129
  243. package/dist/extensions/tasks/ui/manager.js.map +1 -1
  244. package/dist/extensions/tasks/ui/model.d.ts +29 -0
  245. package/dist/extensions/tasks/ui/model.d.ts.map +1 -1
  246. package/dist/extensions/tasks/ui/model.js +16 -1
  247. package/dist/extensions/tasks/ui/model.js.map +1 -1
  248. package/dist/extensions/tasks/ui/render.d.ts +1 -1
  249. package/dist/extensions/tasks/ui/render.d.ts.map +1 -1
  250. package/dist/extensions/tasks/ui/render.js +12 -9
  251. package/dist/extensions/tasks/ui/render.js.map +1 -1
  252. package/dist/extensions/tasks/ui/status.d.ts +15 -0
  253. package/dist/extensions/tasks/ui/status.d.ts.map +1 -0
  254. package/dist/extensions/tasks/ui/status.js +16 -0
  255. package/dist/extensions/tasks/ui/status.js.map +1 -0
  256. package/dist/extensions/tasks/ui/tree.js +1 -1
  257. package/dist/extensions/tasks/ui/tree.js.map +1 -1
  258. package/dist/extensions/tasks/ui/views.d.ts +10 -5
  259. package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
  260. package/dist/extensions/tasks/ui/views.js +61 -36
  261. package/dist/extensions/tasks/ui/views.js.map +1 -1
  262. package/dist/index.d.ts +2 -1
  263. package/dist/index.d.ts.map +1 -1
  264. package/dist/index.js.map +1 -1
  265. package/dist/modes/interactive/components/config-selector.d.ts +14 -1
  266. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  267. package/dist/modes/interactive/components/config-selector.js +258 -7
  268. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  269. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  270. package/dist/modes/interactive/components/keybinding-hints.js +2 -1
  271. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  272. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  273. package/dist/modes/interactive/components/model-selector.js +7 -4
  274. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  275. package/dist/modes/interactive/components/status-marker.d.ts +2 -1
  276. package/dist/modes/interactive/components/status-marker.d.ts.map +1 -1
  277. package/dist/modes/interactive/components/status-marker.js +0 -1
  278. package/dist/modes/interactive/components/status-marker.js.map +1 -1
  279. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  280. package/dist/modes/interactive/components/thinking-selector.js +10 -3
  281. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  282. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  283. package/dist/modes/interactive/interactive-mode.js +7 -1
  284. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  285. package/dist/utils/duration.d.ts +3 -0
  286. package/dist/utils/duration.d.ts.map +1 -0
  287. package/dist/utils/duration.js +17 -0
  288. package/dist/utils/duration.js.map +1 -0
  289. package/dist/utils/number.d.ts +3 -0
  290. package/dist/utils/number.d.ts.map +1 -0
  291. package/dist/utils/number.js +5 -0
  292. package/dist/utils/number.js.map +1 -0
  293. package/docs/bundled/extensions/agent.md +14 -12
  294. package/docs/bundled/extensions/cached-compaction.md +13 -4
  295. package/docs/bundled/extensions/deepwiki.md +3 -1
  296. package/docs/bundled/extensions/statusline.md +1 -1
  297. package/docs/bundled/tasks.md +15 -14
  298. package/docs/extensions.md +26 -10
  299. package/docs/packages.md +5 -3
  300. package/docs/sdk.md +3 -3
  301. package/docs/session-format.md +28 -24
  302. package/docs/settings.md +11 -0
  303. package/docs/skills.md +23 -0
  304. package/npm-shrinkwrap.json +2 -2
  305. package/package.json +1 -1
  306. package/schemas/settings.schema.json +36 -0
  307. package/dist/bundle/chunks/chunk-FSJ45CRP.js +0 -229
  308. package/dist/bundle/chunks/chunk-W3FIUMGM.js +0 -1501
  309. package/dist/core/tasks/history.d.ts +0 -4
  310. package/dist/core/tasks/history.d.ts.map +0 -1
  311. package/dist/core/tasks/history.js +0 -131
  312. package/dist/core/tasks/history.js.map +0 -1
  313. package/dist/extensions/agent/runner.d.ts +0 -24
  314. package/dist/extensions/agent/runner.d.ts.map +0 -1
  315. package/dist/extensions/agent/runner.js +0 -274
  316. package/dist/extensions/agent/runner.js.map +0 -1
  317. package/dist/extensions/deepwiki/http.d.ts +0 -13
  318. package/dist/extensions/deepwiki/http.d.ts.map +0 -1
  319. package/dist/extensions/deepwiki/http.js +0 -88
  320. package/dist/extensions/deepwiki/http.js.map +0 -1
  321. package/dist/extensions/tasks/ui/task-view.d.ts +0 -13
  322. package/dist/extensions/tasks/ui/task-view.d.ts.map +0 -1
  323. package/dist/extensions/tasks/ui/task-view.js +0 -20
  324. package/dist/extensions/tasks/ui/task-view.js.map +0 -1
@@ -5,7 +5,7 @@ import type { KeybindingsManager } from "../../../core/keybindings.ts";
5
5
  import { type TasksContext } from "../../../core/tasks/types.ts";
6
6
  import type { Theme } from "../../../modes/interactive/theme/theme.ts";
7
7
  import { type TasksPanelState } from "./model.ts";
8
- export type TasksManagerHost = Pick<TasksContext, "list" | "read" | "kill" | "subscribe" | "retain"> & Partial<Pick<TasksContext, "detach" | "enabled">>;
8
+ export type TasksManagerHost = Pick<TasksContext, "list" | "read" | "kill" | "subscribe" | "retain" | "canDetach" | "detach">;
9
9
  export interface TasksMenuOptions {
10
10
  tui: {
11
11
  requestRender(): void;
@@ -31,12 +31,9 @@ export declare class TasksMenu implements Component, Focusable {
31
31
  private readonly unsubscribe;
32
32
  private readonly pollTimer;
33
33
  private animationTimer?;
34
- private pendingKill?;
34
+ private mode;
35
35
  private feedback?;
36
36
  private focus;
37
- private searching;
38
- private beforeSearch?;
39
- private help?;
40
37
  private dirty;
41
38
  private tickQueued;
42
39
  private refreshQueued;
@@ -47,15 +44,27 @@ export declare class TasksMenu implements Component, Focusable {
47
44
  private sync;
48
45
  private queueTick;
49
46
  invalidate(): void;
50
- private clearKill;
47
+ /** The one place the mode changes; the search input is focused exactly while searching. */
48
+ private setMode;
49
+ /** Unwinds exactly one transient layer; from plain browsing it closes the panel. */
50
+ private cancel;
51
+ private close;
51
52
  private selectedChanged;
52
- private stop;
53
+ private requestStop;
54
+ private confirmStop;
55
+ private startSearch;
53
56
  private finishSearch;
54
57
  private action;
55
58
  private move;
56
59
  handleInput(data: string): void;
60
+ private helpInput;
61
+ private searchInput;
62
+ private confirmInput;
63
+ private browseInput;
57
64
  handleMouse(event: TuiMouseEvent): TuiMouseEventResult | undefined;
58
65
  render(width: number): string[];
66
+ /** The panel's selection can lag the runtime by a notification; a task that is gone cannot move. */
67
+ private canDetach;
59
68
  dispose(): void;
60
69
  }
61
70
  //# sourceMappingURL=manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/manager.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EACN,KAAK,SAAS,EACd,KAAK,SAAS,EAEd,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAiB,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACtF,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AAIvE,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAIjE,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC,GACnG,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC;AACnD,MAAM,WAAW,gBAAgB;IAChC,GAAG,EAAE;QAAE,aAAa,IAAI,IAAI,CAAC;QAAC,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IAC5E,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,SAAS,CAAC,CAAC;IAC7D,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,OAAO,IAAI,IAAI,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAgBD,qBAAa,SAAU,YAAW,SAAS,EAAE,SAAS;IACrD,OAAO,UAAS;IAChB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAC3D,OAAO,CAAC,cAAc,CAAC,CAAiC;IACxD,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAC,CAA+C;IACpE,OAAO,CAAC,IAAI,CAAC,CAAe;IAC5B,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAC,CAAc;gBACjB,OAAO,EAAE,gBAAgB;IAuBrC,OAAO,CAAC,IAAI;IAqBZ,OAAO,CAAC,SAAS;IAmBjB,UAAU,IAAI,IAAI;IAGlB,OAAO,CAAC,SAAS;IAGjB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,IAAI;IAaZ,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,MAAM;IA8Dd,OAAO,CAAC,IAAI;IAiBZ,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAiE/B,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,mBAAmB,GAAG,SAAS;IA2DlE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAoB/B,OAAO,IAAI,IAAI;CASf"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/manager.ts"],"names":[],"mappings":"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"}
@@ -6,9 +6,10 @@ import { STATUS_SPINNER_INTERVAL_MS } from "../../../modes/interactive/component
6
6
  import { TaskInspector } from "./inspector.js";
7
7
  import { renderTasksLayout } from "./layout.js";
8
8
  import { TaskList } from "./list.js";
9
- import { TaskSelection } from "./model.js";
9
+ import { isStoppable, TaskSelection } from "./model.js";
10
10
  import { cleanTaskText } from "./text.js";
11
11
  import { TaskViewport } from "./viewport.js";
12
+ const BROWSE = { kind: "browse" };
12
13
  const actions = [
13
14
  "app.tasks.search",
14
15
  "app.tasks.kill",
@@ -26,8 +27,8 @@ export class TasksMenu {
26
27
  constructor(options) {
27
28
  this.focused = false;
28
29
  this.list = new TaskList();
30
+ this.mode = BROWSE;
29
31
  this.focus = "list";
30
- this.searching = false;
31
32
  this.dirty = true;
32
33
  this.tickQueued = false;
33
34
  this.refreshQueued = false;
@@ -42,6 +43,9 @@ export class TasksMenu {
42
43
  });
43
44
  this.search = new Input({ prompt: "Find task: ", placeholder: "title, command, kind or ID" });
44
45
  this.sync();
46
+ this.selection.selectStartedSinceClose();
47
+ this.inspector.select(this.selection.selected);
48
+ this.list.showSelection();
45
49
  this.unsubscribe = options.host.subscribe(() => {
46
50
  this.dirty = true;
47
51
  this.queueTick();
@@ -66,8 +70,8 @@ export class TasksMenu {
66
70
  const selected = this.selection.selected;
67
71
  if (selected && isTaskTerminal(selected.status) && previous && !isTaskTerminal(previous.status))
68
72
  this.feedback = undefined;
69
- if (this.pendingKill && (this.pendingKill !== selected?.id || (selected && isTaskTerminal(selected.status))))
70
- this.clearKill();
73
+ if (this.mode.kind === "confirmStop" && (this.mode.taskId !== selected?.id || isTaskTerminal(selected.status)))
74
+ this.setMode(BROWSE);
71
75
  const animates = this.selection.all.some((task) => task.status === "running");
72
76
  if (animates && !this.animationTimer) {
73
77
  this.animationTimer = setInterval(() => this.options.tui.requestRender(), STATUS_SPINNER_INTERVAL_MS);
@@ -103,50 +107,76 @@ export class TasksMenu {
103
107
  invalidate() {
104
108
  this.inspector.invalidate();
105
109
  }
106
- clearKill() {
107
- this.pendingKill = undefined;
110
+ /** The one place the mode changes; the search input is focused exactly while searching. */
111
+ setMode(next) {
112
+ this.mode = next;
113
+ this.search.focused = next.kind === "search";
114
+ }
115
+ /** Unwinds exactly one transient layer; from plain browsing it closes the panel. */
116
+ cancel() {
117
+ switch (this.mode.kind) {
118
+ case "search":
119
+ this.finishSearch(true);
120
+ break;
121
+ case "help":
122
+ case "confirmStop":
123
+ this.setMode(BROWSE);
124
+ break;
125
+ case "browse":
126
+ this.close();
127
+ break;
128
+ }
129
+ }
130
+ close() {
131
+ this.dispose();
132
+ this.options.onClose();
108
133
  }
109
134
  selectedChanged() {
110
- this.clearKill();
135
+ if (this.mode.kind === "confirmStop")
136
+ this.setMode(BROWSE);
111
137
  this.list.showSelection();
112
138
  this.inspector.select(this.selection.selected);
113
139
  this.queueTick(true);
114
140
  }
115
- stop(confirm = false) {
141
+ requestStop() {
116
142
  const task = this.selection.selected;
117
- if (confirm) {
118
- const id = this.pendingKill;
119
- this.clearKill();
120
- if (!id || id !== task?.id || isTaskTerminal(task.status))
121
- return;
122
- this.feedback = this.options.host.kill(id)
123
- ? "Cancellation requested; waiting for cleanup."
124
- : "No new cancellation requested.";
125
- }
126
- else if (task && !isTaskTerminal(task.status) && task.status !== "stopping") {
127
- this.pendingKill = task.id;
128
- }
143
+ if (task && isStoppable(task))
144
+ this.setMode({ kind: "confirmStop", taskId: task.id });
145
+ }
146
+ confirmStop() {
147
+ const mode = this.mode;
148
+ if (mode.kind !== "confirmStop")
149
+ return;
150
+ this.setMode(BROWSE);
151
+ const task = this.selection.selected;
152
+ if (mode.taskId !== task?.id || isTaskTerminal(task.status))
153
+ return;
154
+ this.feedback = this.options.host.kill(mode.taskId)
155
+ ? "Cancellation requested; waiting for cleanup."
156
+ : "No new cancellation requested.";
157
+ }
158
+ startSearch() {
159
+ this.setMode({ kind: "search", restore: { id: this.selection.state.selectedId, focus: this.focus } });
160
+ this.focus = "list";
161
+ this.search.setValue("");
129
162
  }
130
163
  finishSearch(cancel) {
131
- const id = cancel ? this.beforeSearch?.id : this.selection.state.selectedId;
164
+ const mode = this.mode;
165
+ if (mode.kind !== "search")
166
+ return;
167
+ const id = cancel ? mode.restore.id : this.selection.state.selectedId;
132
168
  if (!cancel && !id)
133
169
  return;
134
- this.focus = cancel ? (this.beforeSearch?.focus ?? "list") : "list";
135
- this.searching = false;
136
- this.search.focused = false;
170
+ this.focus = cancel ? mode.restore.focus : "list";
171
+ this.setMode(BROWSE);
137
172
  this.selection.query = "";
138
173
  this.selection.select(id);
139
- this.beforeSearch = undefined;
140
174
  this.selectedChanged();
141
175
  }
142
176
  action(key) {
143
177
  switch (key) {
144
178
  case "app.tasks.search":
145
- this.beforeSearch = { id: this.selection.state.selectedId, focus: this.focus };
146
- this.focus = "list";
147
- this.searching = true;
148
- this.search.focused = true;
149
- this.search.setValue("");
179
+ this.startSearch();
150
180
  break;
151
181
  case "app.tasks.previousTab":
152
182
  case "app.tasks.nextTab":
@@ -173,31 +203,29 @@ export class TasksMenu {
173
203
  this.inspector.position[this.selection.state.tab].jump(key === "app.tasks.bottom", this.selection.state.tab === "output");
174
204
  break;
175
205
  case "app.tasks.kill":
176
- this.stop();
206
+ this.requestStop();
177
207
  break;
178
208
  case "app.tasks.confirmStop":
179
- this.stop(true);
209
+ this.confirmStop();
180
210
  break;
181
211
  case "app.tasks.detachSelected": {
182
212
  const task = this.selection.selected;
183
- if (task?.mode === "foreground" &&
184
- !isTaskTerminal(task.status) &&
185
- task.status !== "stopping" &&
186
- this.options.host.enabled !== false) {
187
- this.feedback = this.options.host.detach?.(task.id)
213
+ // The core decides; a full background lane throws its own explanation, shown as feedback.
214
+ if (task?.mode === "foreground" && isStoppable(task)) {
215
+ this.feedback = this.options.host.detach(task.id)
188
216
  ? "Selected task moved to background; execution continues."
189
217
  : "This task cannot move to background.";
190
218
  }
191
219
  break;
192
220
  }
193
221
  case "app.tasks.help":
194
- this.help = this.help ? undefined : new TaskViewport();
222
+ this.setMode({ kind: "help", viewport: new TaskViewport() });
195
223
  break;
196
224
  }
197
225
  }
198
226
  move(direction, page = false) {
199
- if (this.help) {
200
- this.help.move(direction, page, false);
227
+ if (this.mode.kind === "help") {
228
+ this.mode.viewport.move(direction, page, false);
201
229
  return;
202
230
  }
203
231
  if (this.focus === "list") {
@@ -219,85 +247,95 @@ export class TasksMenu {
219
247
  return;
220
248
  this.sync();
221
249
  this.render(this.width);
222
- const kb = this.options.keybindings;
223
250
  this.feedback = undefined;
224
251
  try {
225
252
  if (this.layout?.tooSmall) {
226
253
  // The resize notice owns the screen; keys must not act on the hidden panel.
227
- // Cancel unwinds one transient state at a time, then closes.
228
- if (kb.matches(data, "tui.select.cancel")) {
229
- if (this.help)
230
- this.help = undefined;
231
- else if (this.searching)
232
- this.finishSearch(true);
233
- else if (this.pendingKill)
234
- this.clearKill();
235
- else {
236
- this.dispose();
237
- this.options.onClose();
238
- return;
239
- }
240
- }
241
- }
242
- else if (this.help) {
243
- if (kb.matches(data, "tui.select.cancel") || kb.matches(data, "app.tasks.help"))
244
- this.help = undefined;
245
- else if (kb.matches(data, "app.tasks.top") || kb.matches(data, "app.tasks.bottom"))
246
- this.help.jump(kb.matches(data, "app.tasks.bottom"), false);
247
- else if (kb.matches(data, "tui.select.up") || kb.matches(data, "tui.editor.pageUp"))
248
- this.help.move(-1, kb.matches(data, "tui.editor.pageUp"), false);
249
- else if (kb.matches(data, "tui.select.down") || kb.matches(data, "tui.editor.pageDown"))
250
- this.help.move(1, kb.matches(data, "tui.editor.pageDown"), false);
251
- }
252
- else if (this.searching) {
253
- if (kb.matches(data, "tui.select.cancel"))
254
- this.finishSearch(true);
255
- else if (kb.matches(data, "tui.select.confirm"))
256
- this.finishSearch(false);
257
- else if (kb.matches(data, "tui.select.up") || kb.matches(data, "tui.select.pageUp"))
258
- this.move(-1, kb.matches(data, "tui.select.pageUp"));
259
- else if (kb.matches(data, "tui.select.down") || kb.matches(data, "tui.select.pageDown"))
260
- this.move(1, kb.matches(data, "tui.select.pageDown"));
261
- else {
262
- this.search.handleInput(data);
263
- this.selection.query = this.search.getValue().slice(0, 512);
264
- this.selection.refresh();
265
- this.selectedChanged();
266
- }
267
- }
268
- else if (this.pendingKill) {
269
- if (kb.matches(data, "app.tasks.confirmStop"))
270
- this.stop(true);
271
- else if (kb.matches(data, "tui.select.cancel"))
272
- this.clearKill();
273
- }
274
- else if (kb.matches(data, "tui.select.cancel")) {
275
- this.dispose();
276
- this.options.onClose();
277
- return;
254
+ if (this.options.keybindings.matches(data, "tui.select.cancel"))
255
+ this.cancel();
278
256
  }
279
257
  else {
280
- const pageUp = kb.matches(data, this.focus === "list" ? "tui.select.pageUp" : "tui.editor.pageUp");
281
- const pageDown = kb.matches(data, this.focus === "list" ? "tui.select.pageDown" : "tui.editor.pageDown");
282
- if (pageUp || kb.matches(data, "tui.select.up"))
283
- this.move(-1, pageUp);
284
- else if (pageDown || kb.matches(data, "tui.select.down"))
285
- this.move(1, pageDown);
286
- else if (kb.matches(data, "tui.select.confirm"))
287
- return;
288
- else {
289
- const key = actions.find((key) => kb.matches(data, key));
290
- if (key)
291
- this.action(key);
258
+ switch (this.mode.kind) {
259
+ case "help":
260
+ this.helpInput(this.mode.viewport, data);
261
+ break;
262
+ case "search":
263
+ this.searchInput(data);
264
+ break;
265
+ case "confirmStop":
266
+ this.confirmInput(data);
267
+ break;
268
+ case "browse":
269
+ this.browseInput(data);
270
+ break;
292
271
  }
293
272
  }
294
273
  }
295
274
  catch (error) {
296
275
  this.feedback = cleanTaskText(error instanceof Error ? error.message : String(error));
297
276
  }
277
+ if (this.disposed)
278
+ return;
298
279
  this.queueTick(true);
299
280
  this.options.tui.requestRender();
300
281
  }
282
+ helpInput(viewport, data) {
283
+ const kb = this.options.keybindings;
284
+ if (kb.matches(data, "tui.select.cancel") || kb.matches(data, "app.tasks.help"))
285
+ this.setMode(BROWSE);
286
+ else if (kb.matches(data, "app.tasks.top") || kb.matches(data, "app.tasks.bottom"))
287
+ viewport.jump(kb.matches(data, "app.tasks.bottom"), false);
288
+ else if (kb.matches(data, "tui.select.up") || kb.matches(data, "tui.editor.pageUp"))
289
+ viewport.move(-1, kb.matches(data, "tui.editor.pageUp"), false);
290
+ else if (kb.matches(data, "tui.select.down") || kb.matches(data, "tui.editor.pageDown"))
291
+ viewport.move(1, kb.matches(data, "tui.editor.pageDown"), false);
292
+ }
293
+ searchInput(data) {
294
+ const kb = this.options.keybindings;
295
+ if (kb.matches(data, "tui.select.cancel"))
296
+ this.cancel();
297
+ else if (kb.matches(data, "tui.select.confirm"))
298
+ this.finishSearch(false);
299
+ else if (kb.matches(data, "tui.select.up") || kb.matches(data, "tui.select.pageUp"))
300
+ this.move(-1, kb.matches(data, "tui.select.pageUp"));
301
+ else if (kb.matches(data, "tui.select.down") || kb.matches(data, "tui.select.pageDown"))
302
+ this.move(1, kb.matches(data, "tui.select.pageDown"));
303
+ else {
304
+ this.search.handleInput(data);
305
+ this.selection.query = this.search.getValue().slice(0, 512);
306
+ this.selection.refresh();
307
+ this.selectedChanged();
308
+ }
309
+ }
310
+ confirmInput(data) {
311
+ const kb = this.options.keybindings;
312
+ if (kb.matches(data, "app.tasks.confirmStop"))
313
+ this.confirmStop();
314
+ else if (kb.matches(data, "tui.select.cancel"))
315
+ this.cancel();
316
+ }
317
+ browseInput(data) {
318
+ const kb = this.options.keybindings;
319
+ if (kb.matches(data, "tui.select.cancel")) {
320
+ this.cancel();
321
+ return;
322
+ }
323
+ const pageUp = kb.matches(data, this.focus === "list" ? "tui.select.pageUp" : "tui.editor.pageUp");
324
+ const pageDown = kb.matches(data, this.focus === "list" ? "tui.select.pageDown" : "tui.editor.pageDown");
325
+ if (pageUp || kb.matches(data, "tui.select.up"))
326
+ this.move(-1, pageUp);
327
+ else if (pageDown || kb.matches(data, "tui.select.down"))
328
+ this.move(1, pageDown);
329
+ else if (kb.matches(data, "tui.select.confirm")) {
330
+ if (this.focus === "list" && this.selection.selected)
331
+ this.focus = "inspector";
332
+ }
333
+ else {
334
+ const key = actions.find((key) => kb.matches(data, key));
335
+ if (key)
336
+ this.action(key);
337
+ }
338
+ }
301
339
  handleMouse(event) {
302
340
  if (this.disposed || event.ctrl || event.alt || event.shift)
303
341
  return;
@@ -305,38 +343,32 @@ export class TasksMenu {
305
343
  this.feedback = undefined;
306
344
  this.render(event.width);
307
345
  const layout = this.layout;
346
+ const mode = this.mode;
308
347
  if (event.type === "wheel" && event.wheelDelta) {
309
- if (!this.pendingKill && !layout.tooSmall && event.y >= 2 && event.y < this.options.tui.terminal.rows - 3) {
348
+ if (mode.kind !== "confirmStop" &&
349
+ !layout.tooSmall &&
350
+ event.y >= 2 &&
351
+ event.y < this.options.tui.terminal.rows - 3) {
310
352
  const delta = Math.sign(event.wheelDelta) * Math.min(20, Math.abs(event.wheelDelta));
311
353
  const region = this.width >= 100 ? (event.x < layout.listWidth ? "list" : "inspector") : this.focus;
312
- if (this.help)
313
- this.help.move(delta, false, false);
354
+ if (mode.kind === "help")
355
+ mode.viewport.move(delta, false, false);
314
356
  else if (region === "list")
315
357
  this.list.scroll(delta);
316
- else if (!this.searching)
358
+ else if (mode.kind !== "search")
317
359
  this.inspector.position[this.selection.state.tab].move(delta, false, this.selection.state.tab === "output");
318
360
  }
319
361
  }
320
362
  else if (event.type === "click" && event.button === "left") {
321
363
  const hit = layout.hits.find((hit) => hit.y === event.y && event.x >= hit.x && event.x < hit.x + hit.width);
322
364
  try {
323
- if (hit?.cancel) {
324
- if (this.searching)
325
- this.finishSearch(true);
326
- else if (this.help)
327
- this.help = undefined;
328
- else if (this.pendingKill)
329
- this.clearKill();
330
- else {
331
- this.dispose();
332
- this.options.onClose();
333
- }
334
- }
365
+ if (hit?.cancel)
366
+ this.cancel();
335
367
  else if (hit?.taskId) {
336
368
  this.selection.select(hit.taskId);
337
369
  this.selectedChanged();
338
370
  this.focus = "list";
339
- if (this.searching)
371
+ if (mode.kind === "search")
340
372
  this.finishSearch(false);
341
373
  }
342
374
  else if (hit?.tab) {
@@ -348,9 +380,7 @@ export class TasksMenu {
348
380
  this.focus = "inspector";
349
381
  this.action(hit.key);
350
382
  }
351
- else if (!this.pendingKill &&
352
- !this.searching &&
353
- !this.help &&
383
+ else if (mode.kind === "browse" &&
354
384
  !layout.tooSmall &&
355
385
  event.y >= 1 &&
356
386
  event.y < this.options.tui.terminal.rows - 2 &&
@@ -379,21 +409,29 @@ export class TasksMenu {
379
409
  inspector: this.inspector,
380
410
  list: this.list,
381
411
  focus: this.focus,
382
- searchLine: this.searching ? (width) => this.search.render(width).join("") : undefined,
383
- pendingKill: this.pendingKill,
412
+ mode: this.mode,
413
+ searchLine: (width) => this.search.render(width).join(""),
384
414
  feedback: this.feedback,
385
- help: this.help,
386
- canDetach: this.options.host.enabled !== false && !!this.options.host.detach,
415
+ canDetach: (id) => this.canDetach(id),
387
416
  });
388
417
  return this.layout.lines;
389
418
  }
419
+ /** The panel's selection can lag the runtime by a notification; a task that is gone cannot move. */
420
+ canDetach(id) {
421
+ try {
422
+ return this.options.host.canDetach(id);
423
+ }
424
+ catch {
425
+ return false;
426
+ }
427
+ }
390
428
  dispose() {
391
429
  if (this.disposed)
392
430
  return;
393
431
  this.disposed = true;
432
+ this.selection.state.closedAt = Date.now();
394
433
  clearInterval(this.pollTimer);
395
434
  clearInterval(this.animationTimer);
396
- this.clearKill();
397
435
  this.unsubscribe();
398
436
  this.inspector.dispose();
399
437
  }