@astralyn/pi 1.4.2 → 1.4.3

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 (232) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/bundle/chunks/{chunk-HXKY52DF.js → chunk-ISXCH6TG.js} +1 -1
  3. package/dist/bundle/chunks/{chunk-FGPSYHTQ.js → chunk-Z2YN4E74.js} +111 -111
  4. package/dist/bundle/chunks/{virtual-modules-5NSVVTKO.js → virtual-modules-QX6D3D7X.js} +1 -1
  5. package/dist/bundle/cli.js +1 -1
  6. package/dist/bundle/index.js +1 -1
  7. package/dist/bundle/rpc-entry.js +1 -1
  8. package/dist/core/agent-session.d.ts +15 -1
  9. package/dist/core/agent-session.d.ts.map +1 -1
  10. package/dist/core/agent-session.js +1 -8
  11. package/dist/core/agent-session.js.map +1 -1
  12. package/dist/core/extensions/distribution-api.d.ts +1 -1
  13. package/dist/core/extensions/distribution-api.d.ts.map +1 -1
  14. package/dist/core/extensions/distribution-api.js.map +1 -1
  15. package/dist/core/extensions/index.d.ts +1 -1
  16. package/dist/core/extensions/index.d.ts.map +1 -1
  17. package/dist/core/extensions/index.js.map +1 -1
  18. package/dist/core/extensions/runner.d.ts.map +1 -1
  19. package/dist/core/extensions/runner.js +3 -2
  20. package/dist/core/extensions/runner.js.map +1 -1
  21. package/dist/core/extensions/types.d.ts +4 -1
  22. package/dist/core/extensions/types.d.ts.map +1 -1
  23. package/dist/core/extensions/types.js.map +1 -1
  24. package/dist/core/keybinding-registry.d.ts +16 -1
  25. package/dist/core/keybinding-registry.d.ts.map +1 -1
  26. package/dist/core/keybinding-registry.js +20 -0
  27. package/dist/core/keybinding-registry.js.map +1 -1
  28. package/dist/core/keybindings-schema.d.ts.map +1 -1
  29. package/dist/core/keybindings-schema.js +2 -1
  30. package/dist/core/keybindings-schema.js.map +1 -1
  31. package/dist/core/keybindings.d.ts +4 -106
  32. package/dist/core/keybindings.d.ts.map +1 -1
  33. package/dist/core/keybindings.js +0 -13
  34. package/dist/core/keybindings.js.map +1 -1
  35. package/dist/core/slash-commands.d.ts.map +1 -1
  36. package/dist/core/slash-commands.js +0 -1
  37. package/dist/core/slash-commands.js.map +1 -1
  38. package/dist/core/tasks/format.d.ts.map +1 -1
  39. package/dist/core/tasks/format.js +10 -4
  40. package/dist/core/tasks/format.js.map +1 -1
  41. package/dist/core/tasks/limits.d.ts +5 -0
  42. package/dist/core/tasks/limits.d.ts.map +1 -0
  43. package/dist/core/tasks/limits.js +5 -0
  44. package/dist/core/tasks/limits.js.map +1 -0
  45. package/dist/core/tasks/runtime.d.ts +1 -0
  46. package/dist/core/tasks/runtime.d.ts.map +1 -1
  47. package/dist/core/tasks/runtime.js +7 -3
  48. package/dist/core/tasks/runtime.js.map +1 -1
  49. package/dist/core/tasks/session.d.ts +1 -1
  50. package/dist/core/tasks/session.d.ts.map +1 -1
  51. package/dist/core/tasks/session.js +10 -2
  52. package/dist/core/tasks/session.js.map +1 -1
  53. package/dist/core/tasks/types.d.ts +13 -0
  54. package/dist/core/tasks/types.d.ts.map +1 -1
  55. package/dist/core/tasks/types.js.map +1 -1
  56. package/dist/core/tools/bash.d.ts +98 -9
  57. package/dist/core/tools/bash.d.ts.map +1 -1
  58. package/dist/core/tools/bash.js +308 -11
  59. package/dist/core/tools/bash.js.map +1 -1
  60. package/dist/core/tools/index.d.ts +5 -4
  61. package/dist/core/tools/index.d.ts.map +1 -1
  62. package/dist/core/tools/index.js +3 -11
  63. package/dist/core/tools/index.js.map +1 -1
  64. package/dist/core/tools/powershell.d.ts +2 -1
  65. package/dist/core/tools/powershell.d.ts.map +1 -1
  66. package/dist/core/tools/powershell.js +2 -1
  67. package/dist/core/tools/powershell.js.map +1 -1
  68. package/dist/core/tools/renderers/bash.d.ts +1 -1
  69. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  70. package/dist/core/tools/renderers/bash.js.map +1 -1
  71. package/dist/core/tools/renderers/index.d.ts.map +1 -1
  72. package/dist/core/tools/renderers/index.js +7 -5
  73. package/dist/core/tools/renderers/index.js.map +1 -1
  74. package/dist/core/tools/shell-execution.d.ts +2 -2
  75. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  76. package/dist/core/tools/shell-execution.js +0 -21
  77. package/dist/core/tools/shell-execution.js.map +1 -1
  78. package/dist/core/tools/shell-operations.d.ts +12 -0
  79. package/dist/core/tools/shell-operations.d.ts.map +1 -0
  80. package/dist/core/tools/shell-operations.js +38 -0
  81. package/dist/core/tools/shell-operations.js.map +1 -0
  82. package/dist/core/tools/shell-tool.d.ts +8 -64
  83. package/dist/core/tools/shell-tool.d.ts.map +1 -1
  84. package/dist/core/tools/shell-tool.js +27 -125
  85. package/dist/core/tools/shell-tool.js.map +1 -1
  86. package/dist/extensions/index.d.ts +1 -0
  87. package/dist/extensions/index.d.ts.map +1 -1
  88. package/dist/extensions/index.js +3 -0
  89. package/dist/extensions/index.js.map +1 -1
  90. package/dist/extensions/keybindings.d.ts +6 -0
  91. package/dist/extensions/keybindings.d.ts.map +1 -0
  92. package/dist/extensions/keybindings.js +6 -0
  93. package/dist/extensions/keybindings.js.map +1 -0
  94. package/dist/extensions/tasks/index.d.ts +5 -0
  95. package/dist/extensions/tasks/index.d.ts.map +1 -0
  96. package/dist/extensions/tasks/index.js +42 -0
  97. package/dist/extensions/tasks/index.js.map +1 -0
  98. package/dist/extensions/tasks/keybindings.d.ts +19 -0
  99. package/dist/extensions/tasks/keybindings.d.ts.map +1 -0
  100. package/dist/extensions/tasks/keybindings.js +30 -0
  101. package/dist/extensions/tasks/keybindings.js.map +1 -0
  102. package/dist/{core/tools/tasks → extensions/tasks/tool}/actions.d.ts +2 -2
  103. package/dist/extensions/tasks/tool/actions.d.ts.map +1 -0
  104. package/dist/{core/tools/tasks → extensions/tasks/tool}/actions.js +4 -4
  105. package/dist/extensions/tasks/tool/actions.js.map +1 -0
  106. package/dist/{core/tools/tasks → extensions/tasks/tool}/constants.d.ts +1 -3
  107. package/dist/extensions/tasks/tool/constants.d.ts.map +1 -0
  108. package/dist/{core/tools/tasks → extensions/tasks/tool}/constants.js +1 -3
  109. package/dist/extensions/tasks/tool/constants.js.map +1 -0
  110. package/dist/extensions/tasks/tool/schema.d.ts.map +1 -0
  111. package/dist/{core/tools/tasks → extensions/tasks/tool}/schema.js +5 -4
  112. package/dist/extensions/tasks/tool/schema.js.map +1 -0
  113. package/dist/{core/tools/tasks → extensions/tasks/tool}/types.d.ts +1 -1
  114. package/dist/extensions/tasks/tool/types.d.ts.map +1 -0
  115. package/dist/extensions/tasks/tool/types.js.map +1 -0
  116. package/dist/extensions/tasks/tool.d.ts +6 -0
  117. package/dist/extensions/tasks/tool.d.ts.map +1 -0
  118. package/dist/{core/tools/tasks.js → extensions/tasks/tool.js} +6 -10
  119. package/dist/extensions/tasks/tool.js.map +1 -0
  120. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/completion-render.d.ts +1 -1
  121. package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -0
  122. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/completion-render.js +2 -2
  123. package/dist/extensions/tasks/ui/completion-render.js.map +1 -0
  124. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/index.d.ts +1 -1
  125. package/dist/extensions/tasks/ui/index.d.ts.map +1 -0
  126. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/index.js +4 -4
  127. package/dist/extensions/tasks/ui/index.js.map +1 -0
  128. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/inspector.d.ts +1 -1
  129. package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -0
  130. package/dist/extensions/tasks/ui/inspector.js.map +1 -0
  131. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/layout.d.ts +1 -1
  132. package/dist/extensions/tasks/ui/layout.d.ts.map +1 -0
  133. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/layout.js +1 -1
  134. package/dist/extensions/tasks/ui/layout.js.map +1 -0
  135. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/list.d.ts +1 -1
  136. package/dist/extensions/tasks/ui/list.d.ts.map +1 -0
  137. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/list.js +1 -1
  138. package/dist/extensions/tasks/ui/list.js.map +1 -0
  139. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/manager.d.ts +2 -1
  140. package/dist/extensions/tasks/ui/manager.d.ts.map +1 -0
  141. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/manager.js +2 -1
  142. package/dist/extensions/tasks/ui/manager.js.map +1 -0
  143. package/dist/extensions/tasks/ui/model.d.ts.map +1 -0
  144. package/dist/extensions/tasks/ui/model.js.map +1 -0
  145. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/render.d.ts +3 -3
  146. package/dist/extensions/tasks/ui/render.d.ts.map +1 -0
  147. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/render.js +2 -2
  148. package/dist/extensions/tasks/ui/render.js.map +1 -0
  149. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/task-view.d.ts +1 -1
  150. package/dist/extensions/tasks/ui/task-view.d.ts.map +1 -0
  151. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/task-view.js +1 -1
  152. package/dist/extensions/tasks/ui/task-view.js.map +1 -0
  153. package/dist/extensions/tasks/ui/text.d.ts.map +1 -0
  154. package/dist/extensions/tasks/ui/text.js.map +1 -0
  155. package/dist/extensions/tasks/ui/tree.d.ts +7 -0
  156. package/dist/extensions/tasks/ui/tree.d.ts.map +1 -0
  157. package/dist/{modes/interactive/tasks/host-hooks.js → extensions/tasks/ui/tree.js} +1 -18
  158. package/dist/extensions/tasks/ui/tree.js.map +1 -0
  159. package/dist/extensions/tasks/ui/viewport.d.ts.map +1 -0
  160. package/dist/extensions/tasks/ui/viewport.js.map +1 -0
  161. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/views.d.ts +1 -1
  162. package/dist/extensions/tasks/ui/views.d.ts.map +1 -0
  163. package/dist/{modes/interactive/tasks → extensions/tasks/ui}/views.js +1 -1
  164. package/dist/extensions/tasks/ui/views.js.map +1 -0
  165. package/dist/index.d.ts +1 -1
  166. package/dist/index.d.ts.map +1 -1
  167. package/dist/index.js.map +1 -1
  168. package/dist/modes/interactive/components/assistant-message.d.ts +3 -2
  169. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  170. package/dist/modes/interactive/components/assistant-message.js +65 -18
  171. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  172. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  173. package/dist/modes/interactive/components/custom-message.js +1 -3
  174. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  175. package/dist/modes/interactive/interactive-mode.d.ts +5 -3
  176. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  177. package/dist/modes/interactive/interactive-mode.js +13 -28
  178. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  179. package/docs/bundled/README.md +1 -4
  180. package/docs/bundled/tasks.md +3 -3
  181. package/docs/extensions.md +6 -3
  182. package/docs/settings.md +1 -1
  183. package/npm-shrinkwrap.json +2 -2
  184. package/package.json +1 -1
  185. package/schemas/keybindings.schema.json +84 -52
  186. package/dist/core/tools/tasks/actions.d.ts.map +0 -1
  187. package/dist/core/tools/tasks/actions.js.map +0 -1
  188. package/dist/core/tools/tasks/constants.d.ts.map +0 -1
  189. package/dist/core/tools/tasks/constants.js.map +0 -1
  190. package/dist/core/tools/tasks/schema.d.ts.map +0 -1
  191. package/dist/core/tools/tasks/schema.js.map +0 -1
  192. package/dist/core/tools/tasks/types.d.ts.map +0 -1
  193. package/dist/core/tools/tasks/types.js.map +0 -1
  194. package/dist/core/tools/tasks.d.ts +0 -14
  195. package/dist/core/tools/tasks.d.ts.map +0 -1
  196. package/dist/core/tools/tasks.js.map +0 -1
  197. package/dist/modes/interactive/tasks/completion-render.d.ts.map +0 -1
  198. package/dist/modes/interactive/tasks/completion-render.js.map +0 -1
  199. package/dist/modes/interactive/tasks/host-hooks.d.ts +0 -14
  200. package/dist/modes/interactive/tasks/host-hooks.d.ts.map +0 -1
  201. package/dist/modes/interactive/tasks/host-hooks.js.map +0 -1
  202. package/dist/modes/interactive/tasks/index.d.ts.map +0 -1
  203. package/dist/modes/interactive/tasks/index.js.map +0 -1
  204. package/dist/modes/interactive/tasks/inspector.d.ts.map +0 -1
  205. package/dist/modes/interactive/tasks/inspector.js.map +0 -1
  206. package/dist/modes/interactive/tasks/layout.d.ts.map +0 -1
  207. package/dist/modes/interactive/tasks/layout.js.map +0 -1
  208. package/dist/modes/interactive/tasks/list.d.ts.map +0 -1
  209. package/dist/modes/interactive/tasks/list.js.map +0 -1
  210. package/dist/modes/interactive/tasks/manager.d.ts.map +0 -1
  211. package/dist/modes/interactive/tasks/manager.js.map +0 -1
  212. package/dist/modes/interactive/tasks/model.d.ts.map +0 -1
  213. package/dist/modes/interactive/tasks/model.js.map +0 -1
  214. package/dist/modes/interactive/tasks/render.d.ts.map +0 -1
  215. package/dist/modes/interactive/tasks/render.js.map +0 -1
  216. package/dist/modes/interactive/tasks/task-view.d.ts.map +0 -1
  217. package/dist/modes/interactive/tasks/task-view.js.map +0 -1
  218. package/dist/modes/interactive/tasks/text.d.ts.map +0 -1
  219. package/dist/modes/interactive/tasks/text.js.map +0 -1
  220. package/dist/modes/interactive/tasks/viewport.d.ts.map +0 -1
  221. package/dist/modes/interactive/tasks/viewport.js.map +0 -1
  222. package/dist/modes/interactive/tasks/views.d.ts.map +0 -1
  223. package/dist/modes/interactive/tasks/views.js.map +0 -1
  224. /package/dist/{core/tools/tasks → extensions/tasks/tool}/schema.d.ts +0 -0
  225. /package/dist/{core/tools/tasks → extensions/tasks/tool}/types.js +0 -0
  226. /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/inspector.js +0 -0
  227. /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/model.d.ts +0 -0
  228. /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/model.js +0 -0
  229. /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/text.d.ts +0 -0
  230. /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/text.js +0 -0
  231. /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/viewport.d.ts +0 -0
  232. /package/dist/{modes/interactive/tasks → extensions/tasks/ui}/viewport.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/constants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,yFAAyF;AACzF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,GAAG,IAAI,CAAC;AACjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAExC,wEAAwE;AACxE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC;AAE3C,0DAA0D;AAC1D,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhD,4EAA4E;AAC5E,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAE5G,4FAA4F;AAC5F,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC","sourcesContent":["/**\n * Shared limits of the `tasks` tool.\n *\n * Numbers that more than one module needs live here so a change lands in one\n * place; execution and retention limits belong to the core service.\n */\n\n/** Default and floor for a `read` slice; the ceiling is the core's TASK_RESULT_BYTES. */\nexport const TASKS_LOGS_DEFAULT_BYTES = 8 * 1024;\nexport const TASKS_LOGS_MIN_BYTES = 256;\n\n/** Finished tasks shown by `list` before the rest fold into a count. */\nexport const TASKS_LIST_FINISHED_SHOWN = 5;\n\n/** Bounded output delta returned by a successful wait. */\nexport const TASKS_WAIT_DELTA_BYTES = 32 * 1024;\n\n/** Wait-window bounds shared by execution and the pending-call renderer. */\nexport { TASKS_WAIT_DEFAULT_MS, TASKS_WAIT_MAX_MS, TASKS_WAIT_MIN_MS } from \"../../../core/tasks/limits.ts\";\n\n/** How long a foreground execution runs before the statusline advertises the detach key. */\nexport const TASKS_DETACH_HINT_DELAY_MS = 10_000;\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAY5C,eAAO,MAAM,WAAW;;;;;;;EAiCtB,CAAC;AAEH,uFAAuF;AACvF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAOpD,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMvD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGhE;AAED,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG9D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAElF;AAED,eAAO,MAAM,sBAAsB,QAOmS,CAAC;AACvU,eAAO,MAAM,oBAAoB,0EAA0E,CAAC;AAC5G,eAAO,MAAM,uBAAuB,UAInC,CAAC"}
@@ -8,8 +8,9 @@
8
8
  */
9
9
  import { StringEnum } from "@earendil-works/pi-ai";
10
10
  import { Type } from "typebox";
11
- import { TASK_RESULT_BYTES } from "../../tasks/output.js";
12
- import { formatSize } from "../truncate.js";
11
+ import { formatDuration } from "../../../core/tasks/format.js";
12
+ import { TASK_RESULT_BYTES } from "../../../core/tasks/output.js";
13
+ import { formatSize } from "../../../core/tools/truncate.js";
13
14
  import { TASKS_LOGS_DEFAULT_BYTES, TASKS_LOGS_MIN_BYTES, TASKS_WAIT_DEFAULT_MS, TASKS_WAIT_MAX_MS, TASKS_WAIT_MIN_MS, } from "./constants.js";
14
15
  export const tasksSchema = Type.Object({
15
16
  action: StringEnum(["read", "wait", "kill", "list"], {
@@ -28,7 +29,7 @@ export const tasksSchema = Type.Object({
28
29
  })),
29
30
  // — wait —
30
31
  waitMs: Type.Optional(Type.Number({
31
- description: `Max time to wait in ms, default ${TASKS_WAIT_DEFAULT_MS}, max ${TASKS_WAIT_MAX_MS} (wait)`,
32
+ description: `Maximum wait window in ms (default ${formatDuration(TASKS_WAIT_DEFAULT_MS)}, max ${formatDuration(TASKS_WAIT_MAX_MS)}). Only the wait ends on timeout; execution continues.`,
32
33
  })),
33
34
  sinceBytes: Type.Optional(Type.Number({
34
35
  description: "Only return output written after this byte offset — use the 'next sinceBytes' value from a previous read or wait (wait with taskId only)",
@@ -61,7 +62,7 @@ export const TASKS_TOOL_DESCRIPTION = "Inspect and control background tasks star
61
62
  "Completion is delivered to you automatically as a notification — never poll. " +
62
63
  "list: bounded activity/history listing; find task IDs here. " +
63
64
  "read: bounded output or report slice (head/tail). " +
64
- "wait: block up to waitMs for one task to settle, or omit taskId to wait for any task running at call time; no running tasks returns immediately. New steering input ends only the wait with outcome interrupted; it never stops the task. " +
65
+ "wait: observe one task, or any task running at call time, for up to waitMs; no running tasks returns immediately. New steering input ends only the wait with outcome interrupted; it never stops the task. " +
65
66
  "kill: request cancellation of a whole task. " +
66
67
  "tasks cannot start work; submit background work through its owning tool. A wait ends as settled, interrupted, timed_out, or no_tasks. Timeout or cancellation ends only the wait, never execution. Reads and settled waits report byte ranges; use next sinceBytes only with that task's ID. Output is capped at 50KB per response.";
67
68
  export const TASKS_PROMPT_SNIPPET = "Manage background tasks; wait for a specific task or any running task";
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/schema.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The `tasks` tool's wire contract: one flat schema whose `action`\n * selects which of the remaining fields apply, plus the model-facing copy.\n *\n * The schema stays flat deliberately: a single tool keeps the model's tool list\n * short. Execution creation belongs to the native tools. Narrowing happens\n * inside actions.ts, not here.\n */\n\nimport { StringEnum } from \"@earendil-works/pi-ai\";\nimport { type Static, Type } from \"typebox\";\nimport { formatDuration } from \"../../../core/tasks/format.ts\";\nimport { TASK_RESULT_BYTES } from \"../../../core/tasks/output.ts\";\nimport { formatSize } from \"../../../core/tools/truncate.ts\";\nimport {\n\tTASKS_LOGS_DEFAULT_BYTES,\n\tTASKS_LOGS_MIN_BYTES,\n\tTASKS_WAIT_DEFAULT_MS,\n\tTASKS_WAIT_MAX_MS,\n\tTASKS_WAIT_MIN_MS,\n} from \"./constants.ts\";\n\nexport const tasksSchema = Type.Object({\n\taction: StringEnum([\"read\", \"wait\", \"kill\", \"list\"] as const, {\n\t\tdescription: \"Which task operation to perform\",\n\t}),\n\t// — read / wait / kill —\n\ttaskId: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: \"Task execution id (read/wait/kill). Omit for wait to wait for any task running at call time.\",\n\t\t}),\n\t),\n\t// — read —\n\tmode: Type.Optional(\n\t\tStringEnum([\"tail\", \"head\"] as const, {\n\t\t\tdescription: \"Read from the end (default) or the start of the output (read)\",\n\t\t}),\n\t),\n\tbytes: Type.Optional(\n\t\tType.Number({\n\t\t\tdescription: `Max bytes to return (read, default ${formatSize(TASKS_LOGS_DEFAULT_BYTES)}, max ${formatSize(TASK_RESULT_BYTES)})`,\n\t\t}),\n\t),\n\t// — wait —\n\twaitMs: Type.Optional(\n\t\tType.Number({\n\t\t\tdescription: `Maximum wait window in ms (default ${formatDuration(TASKS_WAIT_DEFAULT_MS)}, max ${formatDuration(TASKS_WAIT_MAX_MS)}). Only the wait ends on timeout; execution continues.`,\n\t\t}),\n\t),\n\tsinceBytes: Type.Optional(\n\t\tType.Number({\n\t\t\tdescription:\n\t\t\t\t\"Only return output written after this byte offset — use the 'next sinceBytes' value from a previous read or wait (wait with taskId only)\",\n\t\t}),\n\t),\n});\n\n/** Raw tool arguments. Every per-action field is optional here; actions.ts narrows. */\nexport type TasksInput = Static<typeof tasksSchema>;\n\n// ── reading the contract ──────────────────────────────────────────────────\n// One place per field: required fields throw a message that names the next\n// step, optional ones clamp to their documented range. Callers get plain\n// values, so no action handler needs a cast.\n\nexport function requireTaskId(input: TasksInput): string {\n\tconst taskId = input.taskId;\n\tif (!taskId || taskId.trim().length === 0) {\n\t\tthrow new Error(`action '${input.action}' requires 'taskId' — use action list to find the execution id.`);\n\t}\n\treturn taskId;\n}\n\nexport function clampReadBytes(bytes: number | undefined): number {\n\tconst value = bytes !== undefined && Number.isFinite(bytes) ? bytes : TASKS_LOGS_DEFAULT_BYTES;\n\treturn Math.min(TASK_RESULT_BYTES, Math.max(TASKS_LOGS_MIN_BYTES, Math.floor(value)));\n}\n\n/** Shared with the pending-call renderer so the window it shows is the one that runs. */\nexport function clampWaitMs(waitMs: number | undefined): number {\n\tconst value = waitMs !== undefined && Number.isFinite(waitMs) ? waitMs : TASKS_WAIT_DEFAULT_MS;\n\treturn Math.min(TASKS_WAIT_MAX_MS, Math.max(TASKS_WAIT_MIN_MS, Math.floor(value)));\n}\n\nexport function clampSinceBytes(sinceBytes: number | undefined): number | undefined {\n\treturn sinceBytes === undefined || !Number.isFinite(sinceBytes) ? undefined : Math.max(0, Math.floor(sinceBytes));\n}\n\nexport const TASKS_TOOL_DESCRIPTION =\n\t\"Inspect and control background tasks started by native tools or extensions. \" +\n\t\"Completion is delivered to you automatically as a notification — never poll. \" +\n\t\"list: bounded activity/history listing; find task IDs here. \" +\n\t\"read: bounded output or report slice (head/tail). \" +\n\t\"wait: observe one task, or any task running at call time, for up to waitMs; no running tasks returns immediately. New steering input ends only the wait with outcome interrupted; it never stops the task. \" +\n\t\"kill: request cancellation of a whole task. \" +\n\t\"tasks cannot start work; submit background work through its owning tool. A wait ends as settled, interrupted, timed_out, or no_tasks. Timeout or cancellation ends only the wait, never execution. Reads and settled waits report byte ranges; use next sinceBytes only with that task's ID. Output is capped at 50KB per response.\";\nexport const TASKS_PROMPT_SNIPPET = \"Manage background tasks; wait for a specific task or any running task\";\nexport const TASKS_PROMPT_GUIDELINES = [\n\t\"Start background work through its owning tool with background: true; continue independent work while it runs.\",\n\t\"A finished background task delivers its result automatically as a notification. Use tasks wait only when your next step is blocked: provide taskId for one task or omit it for any task running at call time; never sleep-poll with repeated reads.\",\n\t\"A new steering message interrupts only an active tasks wait so you can read the new input; it does not cancel execution. A wait timeout is not a task failure.\",\n];\n"]}
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * `exitCode` is three-state: `null` for signal-reaped tasks.
10
10
  */
11
- import type { TaskKind, TaskStatus } from "../../tasks/types.ts";
11
+ import type { TaskKind, TaskStatus } from "../../../core/tasks/types.ts";
12
12
  export interface TasksReadDetails {
13
13
  kind?: TaskKind;
14
14
  status?: TaskStatus;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAChC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAC;AAEpF,MAAM,WAAW,gBAAgB;IAChC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,4FAA4F;IAC5F,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8FAA8F;IAC9F,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAChC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/tool/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG","sourcesContent":["/**\n * The `tasks` tool's structured `details` payloads.\n *\n * Every shape here is JSON-serialized verbatim into the session file and read back\n * by the renderers on `/reload`, `/tree`, and session resume. Adding an optional\n * field is free; renaming or repurposing an existing one degrades historical\n * transcripts.\n *\n * `exitCode` is three-state: `null` for signal-reaped tasks.\n */\n\nimport type { TaskKind, TaskStatus } from \"../../../core/tasks/types.ts\";\n\nexport interface TasksReadDetails {\n\tkind?: TaskKind;\n\tstatus?: TaskStatus;\n\taction: \"read\";\n\ttaskId: string;\n\tmode: \"head\" | \"tail\";\n\tsliceBytes: number;\n\ttotalBytes: number;\n\toutputPath: string;\n}\n\nexport type TasksWaitOutcome = \"settled\" | \"interrupted\" | \"timed_out\" | \"no_tasks\";\n\nexport interface TasksWaitDetails {\n\tkind?: TaskKind;\n\taction: \"wait\";\n\t/** Absent only in historical results; new calls always record the reason the wait ended. */\n\toutcome?: TasksWaitOutcome;\n\t/** Undefined for waitAny with no selected task, or when no tasks were running. */\n\ttaskId?: string;\n\t/** Retained for compatibility with historical details; true only for a wait-window expiry. */\n\ttimedOut: boolean;\n\tstatus?: TaskStatus;\n\texitCode: number | null | undefined;\n\twaitedMs: number;\n\tdeltaBytes: number;\n\ttotalBytes: number;\n\tdeltaTruncated: boolean;\n\toutputPath: string;\n\t/** Initial waitAny cohort members still running when the wait ended. */\n\trunning?: number;\n}\n\nexport interface TasksKillDetails {\n\trequested?: boolean;\n\tstatus?: TaskStatus;\n\taction: \"kill\";\n\ttaskId: string;\n\tcommand: string;\n}\n\nexport interface TasksListDetails {\n\taction: \"list\";\n\trunning: number;\n\tfinished: number;\n\tshown: number;\n\thidden: number;\n\t/** Foreground executions omitted from the listing; they deliver inline in the transcript. */\n\tforegroundOmitted?: number;\n}\n\nexport type TasksDetails = TasksReadDetails | TasksKillDetails | TasksListDetails | TasksWaitDetails;\n"]}
@@ -0,0 +1,6 @@
1
+ import type { ToolDefinition } from "../../core/extensions/types.ts";
2
+ import { tasksSchema } from "./tool/schema.ts";
3
+ import type { TasksDetails } from "./tool/types.ts";
4
+ import { type TasksRenderState } from "./ui/render.ts";
5
+ export declare function createTasksToolDefinition(): ToolDefinition<typeof tasksSchema, TasksDetails, TasksRenderState>;
6
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../src/extensions/tasks/tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,EAAyE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACtH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAsC,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE3F,wBAAgB,yBAAyB,IAAI,cAAc,CAAC,OAAO,WAAW,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAoC9G"}
@@ -1,8 +1,7 @@
1
- import { renderTasksCall, renderTasksResult } from "../../modes/interactive/tasks/render.js";
2
- import { boundedText, runKill, runList, runRead, runWait } from "./tasks/actions.js";
3
- import { TASKS_PROMPT_GUIDELINES, TASKS_PROMPT_SNIPPET, TASKS_TOOL_DESCRIPTION, tasksSchema } from "./tasks/schema.js";
4
- import { wrapToolDefinition } from "./tool-definition-wrapper.js";
5
- export function createTasksToolDefinition(onWaitResult, waitInterruptSignal) {
1
+ import { boundedText, runKill, runList, runRead, runWait } from "./tool/actions.js";
2
+ import { TASKS_PROMPT_GUIDELINES, TASKS_PROMPT_SNIPPET, TASKS_TOOL_DESCRIPTION, tasksSchema } from "./tool/schema.js";
3
+ import { renderTasksCall, renderTasksResult } from "./ui/render.js";
4
+ export function createTasksToolDefinition() {
6
5
  return {
7
6
  name: "tasks",
8
7
  label: "tasks",
@@ -17,7 +16,7 @@ export function createTasksToolDefinition(onWaitResult, waitInterruptSignal) {
17
16
  case "read":
18
17
  return await runRead(ctx.tasks, params);
19
18
  case "wait":
20
- return await runWait(ctx.tasks, params, signal, (taskId) => onWaitResult?.(_id, taskId), waitInterruptSignal?.());
19
+ return await runWait(ctx.tasks, params, signal, (taskId) => ctx.tasks.session?.prepareWait(_id, taskId), ctx.tasks.session?.waitInterruptSignal);
21
20
  case "kill":
22
21
  return runKill(ctx.tasks, params);
23
22
  case "list":
@@ -34,7 +33,4 @@ export function createTasksToolDefinition(onWaitResult, waitInterruptSignal) {
34
33
  renderResult: renderTasksResult,
35
34
  };
36
35
  }
37
- export function createTasksTool() {
38
- return wrapToolDefinition(createTasksToolDefinition());
39
- }
40
- //# sourceMappingURL=tasks.js.map
36
+ //# sourceMappingURL=tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../src/extensions/tasks/tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEtH,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAyB,MAAM,gBAAgB,CAAC;AAE3F,MAAM,UAAU,yBAAyB;IACxC,OAAO;QACN,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,OAAO;QACd,WAAW,EAAE,sBAAsB;QACnC,aAAa,EAAE,oBAAoB;QACnC,gBAAgB,EAAE,uBAAuB;QACzC,UAAU,EAAE,WAAW;QACvB,mBAAmB,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE;QAC9D,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG;YAChD,IAAI,CAAC;gBACJ,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;oBACvB,KAAK,MAAM;wBACV,OAAO,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;oBACzC,KAAK,MAAM;wBACV,OAAO,MAAM,OAAO,CACnB,GAAG,CAAC,KAAK,EACT,MAAM,EACN,MAAM,EACN,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,EACvD,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,mBAAmB,CACtC,CAAC;oBACH,KAAK,MAAM;wBACV,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;oBACnC,KAAK,MAAM;wBACV,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAC5B,CAAC;YACF,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,uEAAuE;gBACvE,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACvE,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;YACvC,CAAC;QACF,CAAC;QACD,UAAU,EAAE,eAAe;QAC3B,YAAY,EAAE,iBAAiB;KAC/B,CAAC;AACH,CAAC","sourcesContent":["import type { ToolDefinition } from \"../../core/extensions/types.ts\";\nimport { boundedText, runKill, runList, runRead, runWait } from \"./tool/actions.ts\";\nimport { TASKS_PROMPT_GUIDELINES, TASKS_PROMPT_SNIPPET, TASKS_TOOL_DESCRIPTION, tasksSchema } from \"./tool/schema.ts\";\nimport type { TasksDetails } from \"./tool/types.ts\";\nimport { renderTasksCall, renderTasksResult, type TasksRenderState } from \"./ui/render.ts\";\n\nexport function createTasksToolDefinition(): ToolDefinition<typeof tasksSchema, TasksDetails, TasksRenderState> {\n\treturn {\n\t\tname: \"tasks\",\n\t\tlabel: \"tasks\",\n\t\tdescription: TASKS_TOOL_DESCRIPTION,\n\t\tpromptSnippet: TASKS_PROMPT_SNIPPET,\n\t\tpromptGuidelines: TASKS_PROMPT_GUIDELINES,\n\t\tparameters: tasksSchema,\n\t\tconstrainedSampling: { type: \"json_schema\", strict: \"prefer\" },\n\t\tasync execute(_id, params, signal, _onUpdate, ctx) {\n\t\t\ttry {\n\t\t\t\tswitch (params.action) {\n\t\t\t\t\tcase \"read\":\n\t\t\t\t\t\treturn await runRead(ctx.tasks, params);\n\t\t\t\t\tcase \"wait\":\n\t\t\t\t\t\treturn await runWait(\n\t\t\t\t\t\t\tctx.tasks,\n\t\t\t\t\t\t\tparams,\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\t(taskId) => ctx.tasks.session?.prepareWait(_id, taskId),\n\t\t\t\t\t\t\tctx.tasks.session?.waitInterruptSignal,\n\t\t\t\t\t\t);\n\t\t\t\t\tcase \"kill\":\n\t\t\t\t\t\treturn runKill(ctx.tasks, params);\n\t\t\t\t\tcase \"list\":\n\t\t\t\t\t\treturn runList(ctx.tasks);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\t// Lookup failures already carry the current task list from actions.ts.\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new Error(boundedText(message));\n\t\t\t}\n\t\t},\n\t\trenderCall: renderTasksCall,\n\t\trenderResult: renderTasksResult,\n\t};\n}\n"]}
@@ -2,7 +2,7 @@
2
2
  import { type Component } from "@earendil-works/pi-tui";
3
3
  import type { MessageRenderOptions } from "../../../core/extensions/types.ts";
4
4
  import type { CustomMessage } from "../../../core/messages.ts";
5
- import type { Theme } from "../theme/theme.ts";
5
+ import type { Theme } from "../../../modes/interactive/theme/theme.ts";
6
6
  /** Always return a compact, replay-safe component, including for unknown historical formats. */
7
7
  export declare function renderTaskCompletion(message: CustomMessage<unknown>, options: MessageRenderOptions, theme: Theme): Component;
8
8
  //# sourceMappingURL=completion-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion-render.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/completion-render.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,OAAO,EAAE,KAAK,SAAS,EAA6D,MAAM,wBAAwB,CAAC;AACnH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAK/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AAmLvE,gGAAgG;AAChG,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,EAC/B,OAAO,EAAE,oBAAoB,EAC7B,KAAK,EAAE,KAAK,GACV,SAAS,CAWX"}
@@ -2,9 +2,9 @@
2
2
  import { stripTerminalSequences, truncateToWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
3
3
  import { runtimeLabel } from "../../../core/tasks/format.js";
4
4
  import { readTaskCompletion } from "../../../core/tasks/presentation.js";
5
+ import { statusMarker } from "../../../modes/interactive/components/status-marker.js";
6
+ import { FramedComponent } from "../../../modes/interactive/tool-view/style.js";
5
7
  import { sanitizeBinaryOutput } from "../../../utils/shell.js";
6
- import { statusMarker } from "../components/status-marker.js";
7
- import { FramedComponent } from "../tool-view/style.js";
8
8
  import { statusName } from "./task-view.js";
9
9
  const SOURCE_LIMIT = 64 * 1024;
10
10
  const CARD_ROWS = 128;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion-render.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/completion-render.ts"],"names":[],"mappings":"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","sourcesContent":["/** Human-facing completion cards. The persisted context message remains untouched. */\nimport { type Component, stripTerminalSequences, truncateToWidth, wrapTextWithAnsi } from \"@earendil-works/pi-tui\";\nimport type { MessageRenderOptions } from \"../../../core/extensions/types.ts\";\nimport type { CustomMessage } from \"../../../core/messages.ts\";\nimport { runtimeLabel } from \"../../../core/tasks/format.ts\";\nimport { readTaskCompletion } from \"../../../core/tasks/presentation.ts\";\nimport type { TaskTerminalStatus } from \"../../../core/tasks/types.ts\";\nimport { type StatusMarkerColor, statusMarker } from \"../../../modes/interactive/components/status-marker.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport { FramedComponent } from \"../../../modes/interactive/tool-view/style.ts\";\nimport { sanitizeBinaryOutput } from \"../../../utils/shell.ts\";\nimport { statusName } from \"./task-view.ts\";\n\nconst SOURCE_LIMIT = 64 * 1024;\nconst CARD_ROWS = 128;\nconst OUTPUT_ROWS = 20;\nconst SHELL_NAMES: Record<string, string> = { bash: \"Bash\", powershell: \"PowerShell\" };\n\ninterface CompletionView {\n\ttitle?: string;\n\tduration?: string;\n\texitCode?: number | null;\n\tkind?: string;\n\tstatus?: TaskTerminalStatus;\n\tid?: string;\n\tcommand?: string;\n\tcwd?: string;\n\tpath?: string;\n\tdiagnostic?: string;\n\t/** Undefined for an unreadable message, whose saved content is shown instead. */\n\toutput?: string;\n\tbody: string;\n\ttruncated: boolean;\n}\n\nfunction clean(text: string): string {\n\treturn sanitizeBinaryOutput(stripTerminalSequences(text)).replace(/\\r\\n?/g, \"\\n\");\n}\n\nfunction savedText(message: CustomMessage<unknown>): { text: string; clipped: boolean } {\n\t// 64K is a UTF-16 code-unit display budget, not a UTF-8 byte promise; the block\n\t// cap bounds iteration itself so many empty/non-text blocks cannot spin here.\n\tconst MAX_SOURCE_BLOCKS = 256;\n\tconst content = message.content;\n\tlet text = \"\";\n\tlet clipped = false;\n\tif (typeof content === \"string\") {\n\t\ttext = content.slice(0, SOURCE_LIMIT);\n\t\tclipped = content.length > SOURCE_LIMIT;\n\t} else if (Array.isArray(content)) {\n\t\tlet visited = 0;\n\t\tfor (const block of content) {\n\t\t\tif (++visited > MAX_SOURCE_BLOCKS) {\n\t\t\t\tclipped = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!block || block.type !== \"text\" || typeof block.text !== \"string\") continue;\n\t\t\tconst next = `${text ? \"\\n\" : \"\"}${block.text.slice(0, SOURCE_LIMIT + 1)}`;\n\t\t\tconst remaining = SOURCE_LIMIT - text.length;\n\t\t\ttext += next.slice(0, remaining);\n\t\t\tif (next.length > remaining || block.text.length > SOURCE_LIMIT) {\n\t\t\t\tclipped = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn { text: clean(text), clipped };\n}\n\nfunction completionView(message: CustomMessage<unknown>): CompletionView {\n\tconst snapshot = readTaskCompletion(message.details);\n\tif (!snapshot) {\n\t\tconst { text, clipped } = savedText(message);\n\t\treturn { body: text, truncated: clipped };\n\t}\n\treturn {\n\t\ttitle: clean(snapshot.title),\n\t\tduration: runtimeLabel(snapshot),\n\t\tkind: snapshot.kind,\n\t\tstatus: snapshot.status,\n\t\tid: clean(snapshot.taskId),\n\t\texitCode: snapshot.exitCode,\n\t\tcommand: snapshot.command === undefined ? undefined : clean(snapshot.command.text),\n\t\tcwd: snapshot.cwd === undefined ? undefined : clean(snapshot.cwd),\n\t\tpath: snapshot.outputPath === undefined ? undefined : clean(snapshot.outputPath),\n\t\tdiagnostic: snapshot.error === undefined ? undefined : clean(snapshot.error),\n\t\toutput: clean(snapshot.output.text),\n\t\tbody: \"\",\n\t\ttruncated: snapshot.output.truncated || snapshot.command?.truncated === true,\n\t};\n}\n\nfunction color(status: string | undefined): StatusMarkerColor {\n\treturn status === undefined ? \"muted\" : statusMarker(status).color;\n}\nfunction shortId(id: string): string {\n\treturn id.replace(/^(.+)-([0-9a-f]{8})-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, \"$1-$2\");\n}\n\nclass CompletionCard implements Component {\n\tprivate readonly view: CompletionView;\n\tprivate readonly options: MessageRenderOptions;\n\tprivate readonly theme: Theme;\n\tconstructor(view: CompletionView, options: MessageRenderOptions, theme: Theme) {\n\t\tthis.view = view;\n\t\tthis.options = options;\n\t\tthis.theme = theme;\n\t}\n\tinvalidate(): void {}\n\trender(width: number): string[] {\n\t\tif (width < 1) return [];\n\t\tconst chrome = new FramedComponent(\n\t\t\t{ render: (contentWidth) => this.renderContent(contentWidth), invalidate() {} },\n\t\t\t\"header\",\n\t\t\t() => color(this.view.status),\n\t\t);\n\t\t// The gutter reserves its own cells; clip defensively for one-cell terminals.\n\t\treturn chrome.render(width).map((line) => truncateToWidth(line, width, \"\"));\n\t}\n\tprivate renderContent(width: number): string[] {\n\t\t// The chrome clamps to ≥1 already; keep the padding arithmetic safe regardless.\n\t\tif (!Number.isFinite(width) || width < 1) return [];\n\t\tconst view = this.view;\n\t\tconst theme = this.theme;\n\t\tconst options = this.options;\n\t\t// The native dot/rail replaces the default one-cell custom-message inset.\n\t\t// Additional configured padding stays inside the chrome, never shifting the dot.\n\t\tconst padding = Math.min(Math.max(0, Math.floor(options.outputPad || 0) - 1), Math.floor((width - 1) / 2));\n\t\tconst inner = width - padding * 2;\n\t\tconst indent = inner >= 3 ? \" \" : \"\";\n\t\tconst bodyWidth = Math.max(1, inner - indent.length);\n\t\tconst lines: string[] = [];\n\t\tconst status = view.status ? statusName(view.status) : \"Result received\";\n\t\tconst kind = view.kind === undefined ? \"Notification\" : (SHELL_NAMES[view.kind] ?? view.kind);\n\t\tlines.push(\n\t\t\t`${theme.fg(\"toolTitle\", theme.bold(kind))}${theme.fg(\"muted\", ` · Background ${status.toLowerCase()}${view.duration ? ` · ${view.duration}` : \"\"}`)}${view.id ? theme.fg(\"dim\", ` · ${shortId(view.id)}`) : \"\"}`,\n\t\t);\n\t\tconst summary = view.command ? `$ ${view.command.split(\"\\n\")[0]}` : view.title;\n\t\tif (!options.expanded) {\n\t\t\tif (summary) lines.push(theme.fg(\"toolOutput\", summary));\n\t\t\tif (view.diagnostic) lines.push(theme.fg(color(view.status), view.diagnostic));\n\t\t} else {\n\t\t\tif (view.truncated) {\n\t\t\t\tlines.push(theme.fg(\"warning\", \"The saved result is truncated; this is not the complete original output.\"));\n\t\t\t}\n\t\t\tconst section = (title: string, text: string, limit: number, tail = false, error = false) => {\n\t\t\t\tlines.push(\"\", theme.fg(\"muted\", theme.bold(title)));\n\t\t\t\tconst rendered = wrapTextWithAnsi(text, bodyWidth).map((line) =>\n\t\t\t\t\ttheme.fg(error ? \"error\" : \"toolOutput\", line),\n\t\t\t\t);\n\t\t\t\tconst omitted = Math.max(0, rendered.length - limit);\n\t\t\t\tconst selected = tail ? rendered.slice(-limit) : rendered.slice(0, limit);\n\t\t\t\tif (tail && omitted) lines.push(theme.fg(\"dim\", `${indent}… ${omitted} earlier display lines omitted`));\n\t\t\t\tfor (const line of selected) lines.push(indent + line);\n\t\t\t\tif (!tail && omitted) lines.push(theme.fg(\"dim\", `${indent}… ${omitted} more display lines omitted`));\n\t\t\t};\n\t\t\tif (view.output === undefined) section(\"Details\", view.body || \"No text result.\", 36);\n\t\t\telse {\n\t\t\t\tif (view.command) section(\"Command\", view.command, 8);\n\t\t\t\telse if (view.title) section(\"Task\", view.title, 4);\n\t\t\t\tif (view.cwd) section(\"Directory\", view.cwd, 2);\n\t\t\t\tsection(\n\t\t\t\t\tview.status === \"failed\" || view.status === \"timeout\" ? \"Error\" : \"Result\",\n\t\t\t\t\t`${view.diagnostic ?? status}${view.exitCode !== undefined ? ` · ${view.exitCode === null ? \"terminated by signal\" : `exit ${view.exitCode}`}` : \"\"}`,\n\t\t\t\t\t4,\n\t\t\t\t\tfalse,\n\t\t\t\t\tview.status === \"failed\",\n\t\t\t\t);\n\t\t\t\tsection(\"Output\", !view.output.trim() ? \"No output.\" : view.output, OUTPUT_ROWS, true);\n\t\t\t\tif (view.path) section(\"Log\", view.path, 4);\n\t\t\t}\n\t\t\tif (view.id) {\n\t\t\t\tlines.push(\"\", ...wrapTextWithAnsi(`Task ID: ${view.id}`, inner).map((line) => theme.fg(\"dim\", line)));\n\t\t\t}\n\t\t\tlines.push(theme.fg(\"dim\", \"Preview of the saved result.\"));\n\t\t}\n\t\tconst bounded =\n\t\t\tlines.length > CARD_ROWS\n\t\t\t\t? [\n\t\t\t\t\t\t...lines.slice(0, CARD_ROWS - 1),\n\t\t\t\t\t\ttheme.fg(\"dim\", \"… card shortened; use tasks read for retained output\"),\n\t\t\t\t\t]\n\t\t\t\t: lines;\n\t\treturn bounded.map((line) => \" \".repeat(padding) + truncateToWidth(line, inner, \"…\") + \" \".repeat(padding));\n\t}\n}\n\n/** Always return a compact, replay-safe component, including for unknown historical formats. */\nexport function renderTaskCompletion(\n\tmessage: CustomMessage<unknown>,\n\toptions: MessageRenderOptions,\n\ttheme: Theme,\n): Component {\n\tlet view: CompletionView;\n\ttry {\n\t\tview = completionView(message);\n\t} catch {\n\t\tview = {\n\t\t\tbody: \"The saved notification could not be interpreted. Its original message remains in session history.\",\n\t\t\ttruncated: false,\n\t\t};\n\t}\n\treturn new CompletionCard(view, options, theme);\n}\n"]}
@@ -4,7 +4,7 @@ export interface TasksUI {
4
4
  open(): Promise<void>;
5
5
  dispose(): void;
6
6
  }
7
- /** Host-owned task UI; it is available without loading an extension. */
7
+ /** Extension-owned task UI, bound to one session context at a time. */
8
8
  export declare function bindTasksUI(ctx: {
9
9
  tasks: TasksContext;
10
10
  ui: ExtensionUIContext;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAOjF,MAAM,WAAW,OAAO;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,GAAG,EAAE;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,kBAAkB,CAAA;CAAE,GAAG,OAAO,CA8FzF"}
@@ -1,10 +1,10 @@
1
1
  import { getKeybindings } from "@earendil-works/pi-tui";
2
2
  import { isTaskTerminal } from "../../../core/tasks/types.js";
3
- import { TASKS_DETACH_HINT_DELAY_MS } from "../../../core/tools/tasks/constants.js";
4
- import { keyLabel } from "../components/keybinding-hints.js";
5
- import { theme } from "../theme/theme.js";
3
+ import { keyLabel } from "../../../modes/interactive/components/keybinding-hints.js";
4
+ import { theme } from "../../../modes/interactive/theme/theme.js";
5
+ import { TASKS_DETACH_HINT_DELAY_MS } from "../tool/constants.js";
6
6
  import { TasksMenu } from "./manager.js";
7
- /** Host-owned task UI; it is available without loading an extension. */
7
+ /** Extension-owned task UI, bound to one session context at a time. */
8
8
  export function bindTasksUI(ctx) {
9
9
  const state = { tab: "output" };
10
10
  let unsubscribe;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,cAAc,EAAqB,MAAM,8BAA8B,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,2DAA2D,CAAC;AACrF,OAAO,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAQzC,uEAAuE;AACvE,MAAM,UAAU,WAAW,CAAC,GAAoD;IAC/E,MAAM,KAAK,GAAoB,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;IACjD,IAAI,WAAqC,CAAC;IAC1C,IAAI,oBAA8C,CAAC;IACnD,IAAI,SAAmC,CAAC;IACxC,IAAI,SAAoD,CAAC;IACzD,MAAM,KAAK,GAAG,GAAG,EAAE;QAClB,WAAW,EAAE,EAAE,CAAC;QAChB,oBAAoB,EAAE,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,GAAG,EAAE;YACnB,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,SAAS,GAAG,SAAS,CAAC;YACtB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAC7B,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;YAC3G,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,IAAI,UAAU,EAAE,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,UAAU,mBAAmB,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAC5F,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;YAC1E,CAAC;YACD,kFAAkF;YAClF,wEAAwE;YACxE,MAAM,SAAS,GAAG,QAAQ,CAAC,kBAAkB,CAAC,CAAC;YAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACnE,MAAM,KAAK,GAAG,OAAO;iBACnB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,GAAG,0BAA0B,GAAG,GAAG,CAAC;iBAChE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;YAC7B,IAAI,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;gBAC7C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC;YACxF,IAAI,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnC,+EAA+E;gBAC/E,mCAAmC;gBACnC,SAAS,GAAG,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;gBACnD,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;YACrB,CAAC;YACD,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC/F,CAAC,CAAC;QACF,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC1C,oBAAoB,GAAG,GAAG,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,EAAE;YACtD,IAAI,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,kBAAkB,CAAC;gBAAE,OAAO,SAAS,CAAC;YAC1E,IAAI,KAAa,CAAC;YAClB,IAAI,CAAC;gBACJ,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;YACtC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,uDAAuD;gBACvD,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;gBACjF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC1B,CAAC;YACD,2EAA2E;YAC3E,mDAAmD;YACnD,IAAI,KAAK,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;YAClC,GAAG,CAAC,EAAE,CAAC,MAAM,CACZ,SAAS,KAAK,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,iDAAiD,CAClG,CAAC;YACF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,MAAM,EAAE,CAAC;IACV,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,GAAG,EAAE;QACpB,WAAW,EAAE,EAAE,CAAC;QAChB,WAAW,GAAG,SAAS,CAAC;QACxB,oBAAoB,EAAE,EAAE,CAAC;QACzB,oBAAoB,GAAG,SAAS,CAAC;QACjC,YAAY,CAAC,SAAS,CAAC,CAAC;QACxB,SAAS,GAAG,SAAS,CAAC;QACtB,SAAS,EAAE,EAAE,CAAC;QACd,SAAS,GAAG,SAAS,CAAC;QACtB,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAC3C,CAAC,CAAC;IACF,KAAK,EAAE,CAAC;IACR,OAAO;QACN,OAAO;QACP,IAAI,EAAE,KAAK,IAAI,EAAE;YAChB,SAAS,EAAE,EAAE,CAAC;YACd,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,CAClB,CAAC,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;gBACjC,MAAM,KAAK,GAAG,GAAG,EAAE;oBAClB,IAAI,SAAS,KAAK,KAAK;wBAAE,SAAS,GAAG,SAAS,CAAC;oBAC/C,IAAI,EAAE,CAAC;gBACR,CAAC,CAAC;gBACF,SAAS,GAAG,KAAK,CAAC;gBAClB,OAAO,IAAI,SAAS,CAAC;oBACpB,KAAK;oBACL,GAAG;oBACH,KAAK;oBACL,WAAW;oBACX,IAAI,EAAE,GAAG,CAAC,KAAK;oBACf,OAAO,EAAE,KAAK;iBACd,CAAC,CAAC;YACJ,CAAC,EACD,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CACzF,CAAC;QACH,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["import { getKeybindings } from \"@earendil-works/pi-tui\";\nimport type { ExtensionUIContext } from \"../../../core/extensions/types.ts\";\nimport { isTaskTerminal, type TasksContext } from \"../../../core/tasks/types.ts\";\nimport { keyLabel } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport { theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport { TASKS_DETACH_HINT_DELAY_MS } from \"../tool/constants.ts\";\nimport { TasksMenu } from \"./manager.ts\";\nimport type { TasksPanelState } from \"./model.ts\";\n\nexport interface TasksUI {\n\topen(): Promise<void>;\n\tdispose(): void;\n}\n\n/** Extension-owned task UI, bound to one session context at a time. */\nexport function bindTasksUI(ctx: { tasks: TasksContext; ui: ExtensionUIContext }): TasksUI {\n\tconst state: TasksPanelState = { tab: \"output\" };\n\tlet unsubscribe: (() => void) | undefined;\n\tlet unsubscribeDetachKey: (() => void) | undefined;\n\tlet closeMenu: (() => void) | undefined;\n\tlet hintTimer: ReturnType<typeof setTimeout> | undefined;\n\tconst start = () => {\n\t\tunsubscribe?.();\n\t\tunsubscribeDetachKey?.();\n\t\tconst update = () => {\n\t\t\tclearTimeout(hintTimer);\n\t\t\thintTimer = undefined;\n\t\t\tconst all = ctx.tasks.list();\n\t\t\tconst background = all.filter((task) => task.mode === \"background\" && !isTaskTerminal(task.status)).length;\n\t\t\tconst parts: string[] = [];\n\t\t\tif (background) {\n\t\t\t\tparts.push(theme.fg(\"text\", `${background} background task${background === 1 ? \"\" : \"s\"}`));\n\t\t\t\tparts.push(theme.fg(\"accent\", \"/tasks\") + theme.fg(\"muted\", \" to view\"));\n\t\t\t}\n\t\t\t// Teach the detach key once something has run long enough to be worth moving, and\n\t\t\t// only while it can move, independently of the background task summary.\n\t\t\tconst detachKey = keyLabel(\"app.tasks.detach\");\n\t\t\tconst now = Date.now();\n\t\t\tconst movable = all.filter((task) => ctx.tasks.canDetach(task.id));\n\t\t\tconst waits = movable\n\t\t\t\t.map((task) => task.startedAt + TASKS_DETACH_HINT_DELAY_MS - now)\n\t\t\t\t.filter((wait) => wait > 0);\n\t\t\tif (detachKey && movable.length > waits.length)\n\t\t\t\tparts.push(theme.fg(\"accent\", detachKey) + theme.fg(\"muted\", \" to run in background\"));\n\t\t\tif (detachKey && waits.length > 0) {\n\t\t\t\t// The service notifies on state changes, not on time, so wake up when the next\n\t\t\t\t// execution crosses the threshold.\n\t\t\t\thintTimer = setTimeout(update, Math.min(...waits));\n\t\t\t\thintTimer.unref?.();\n\t\t\t}\n\t\t\tctx.ui.setStatus(\"background\", parts.length ? parts.join(theme.fg(\"dim\", \" · \")) : undefined);\n\t\t};\n\t\tunsubscribe = ctx.tasks.subscribe(update);\n\t\tunsubscribeDetachKey = ctx.ui.onTerminalInput((data) => {\n\t\t\tif (!getKeybindings().matches(data, \"app.tasks.detach\")) return undefined;\n\t\t\tlet count: number;\n\t\t\ttry {\n\t\t\t\tcount = ctx.tasks.detachForeground();\n\t\t\t} catch (error) {\n\t\t\t\t// Work could move, but every background slot is taken.\n\t\t\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"warning\");\n\t\t\t\treturn { consume: true };\n\t\t\t}\n\t\t\t// Nothing can move: let the key fall through to editor bindings instead of\n\t\t\t// spending it on a \"nothing happened\" status line.\n\t\t\tif (count === 0) return undefined;\n\t\t\tctx.ui.notify(\n\t\t\t\t`Moved ${count} execution${count === 1 ? \"\" : \"s\"} to the background. Use /tasks to manage tasks.`,\n\t\t\t);\n\t\t\treturn { consume: true };\n\t\t});\n\t\tupdate();\n\t};\n\tconst dispose = () => {\n\t\tunsubscribe?.();\n\t\tunsubscribe = undefined;\n\t\tunsubscribeDetachKey?.();\n\t\tunsubscribeDetachKey = undefined;\n\t\tclearTimeout(hintTimer);\n\t\thintTimer = undefined;\n\t\tcloseMenu?.();\n\t\tcloseMenu = undefined;\n\t\tctx.ui.setStatus(\"background\", undefined);\n\t};\n\tstart();\n\treturn {\n\t\tdispose,\n\t\topen: async () => {\n\t\t\tcloseMenu?.();\n\t\t\tawait ctx.ui.custom<void>(\n\t\t\t\t(tui, theme, keybindings, done) => {\n\t\t\t\t\tconst close = () => {\n\t\t\t\t\t\tif (closeMenu === close) closeMenu = undefined;\n\t\t\t\t\t\tdone();\n\t\t\t\t\t};\n\t\t\t\t\tcloseMenu = close;\n\t\t\t\t\treturn new TasksMenu({\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\ttui,\n\t\t\t\t\t\ttheme,\n\t\t\t\t\t\tkeybindings,\n\t\t\t\t\t\thost: ctx.tasks,\n\t\t\t\t\t\tonClose: close,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t{ overlay: true, overlayOptions: { anchor: \"center\", width: \"100%\", maxHeight: \"100%\" } },\n\t\t\t);\n\t\t},\n\t};\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { TaskRead, TaskSnapshot, TasksContext } from "../../../core/tasks/types.ts";
2
- import type { Theme } from "../theme/theme.ts";
2
+ import type { Theme } from "../../../modes/interactive/theme/theme.ts";
3
3
  import type { TasksTab } from "./model.ts";
4
4
  import { TaskViewport } from "./viewport.ts";
5
5
  interface ReadingPosition {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspector.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/inspector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEzF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AACvE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG7C,UAAU,eAAe;IACxB,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,QAAQ,CAAC;CAChB;AACD,UAAU,gBAAgB;IACzB,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC;IAC5C,KAAK,EAAE,KAAK,CAAC;IACb,aAAa,IAAI,IAAI,CAAC;CACtB;AAED,8FAA8F;AAC9F,qBAAa,aAAa;IACzB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;IAChE,OAAO,CAAC,OAAO,CAAC,CAAa;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,iFAAiF;IACjF,OAAO,CAAC,KAAK,CAAC,CAA4D;gBAC9D,OAAO,EAAE,gBAAgB;IAGrC,IAAI,QAAQ,IAAI,eAAe,CAQ9B;IACD,MAAM,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI;IAU5C,KAAK,CAAC,GAAG,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI;IAGrC,UAAU,IAAI,IAAI;IAGZ,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B9B,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,EAAE;IAQ9B,OAAO,IAAI,IAAI;CAOf"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspector.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/inspector.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TaskRead, TaskSnapshot, TasksContext } from \"../../../core/tasks/types.ts\";\nimport { isTaskTerminal } from \"../../../core/tasks/types.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { TasksTab } from \"./model.ts\";\nimport { cleanTaskText } from \"./text.ts\";\nimport { TaskViewport } from \"./viewport.ts\";\nimport { type TaskLines, taskLines } from \"./views.ts\";\n\ninterface ReadingPosition {\n\tinfo: TaskViewport;\n\toutput: TaskViewport;\n\tread?: TaskRead;\n}\ninterface InspectorOptions {\n\thost: Pick<TasksContext, \"read\" | \"retain\">;\n\ttheme: Theme;\n\trequestRender(): void;\n}\n\n/** Owns the selected task's bounded reads. Reading never acknowledges completion delivery. */\nexport class TaskInspector {\n\ttask?: TaskSnapshot;\n\tprivate readonly options: InspectorOptions;\n\tprivate readonly positions = new Map<string, ReadingPosition>();\n\tprivate release?: () => void;\n\tprivate reading = false;\n\tprivate disposed = false;\n\t/** Snapshots are immutable, so identity tells when the lines must be rebuilt. */\n\tprivate cache?: { task: TaskSnapshot; read?: TaskRead; lines: TaskLines };\n\tconstructor(options: InspectorOptions) {\n\t\tthis.options = options;\n\t}\n\tget position(): ReadingPosition {\n\t\tconst id = this.task?.id;\n\t\tlet position = id ? this.positions.get(id) : undefined;\n\t\tif (!position) {\n\t\t\tposition = { info: new TaskViewport(), output: new TaskViewport(true) };\n\t\t\tif (id) this.positions.set(id, position);\n\t\t}\n\t\treturn position;\n\t}\n\tselect(task: TaskSnapshot | undefined): void {\n\t\tif (this.disposed) return;\n\t\tif (this.task?.id !== task?.id) {\n\t\t\tconst release = task ? this.options.host.retain(task.id) : undefined;\n\t\t\tconst previous = this.release;\n\t\t\tthis.release = release;\n\t\t\tprevious?.();\n\t\t}\n\t\tthis.task = task;\n\t}\n\tprune(ids: ReadonlySet<string>): void {\n\t\tfor (const id of this.positions.keys()) if (!ids.has(id)) this.positions.delete(id);\n\t}\n\tinvalidate(): void {\n\t\tthis.cache = undefined;\n\t}\n\tasync refresh(): Promise<void> {\n\t\tconst task = this.task;\n\t\tif (this.disposed || !task || this.reading) return;\n\t\tconst position = this.position;\n\t\tif (position.read && (!position.output.follow || isTaskTerminal(position.read.task.status))) return;\n\t\tthis.reading = true;\n\t\ttry {\n\t\t\tconst read = await this.options.host.read(task.id, { mode: \"tail\", bytes: 48 * 1024 });\n\t\t\tif (this.disposed || this.task?.id !== task.id || (!position.output.follow && position.read)) return;\n\t\t\tposition.read = read;\n\t\t} catch (error) {\n\t\t\tif (!this.disposed && this.task?.id === task.id && (position.output.follow || !position.read)) {\n\t\t\t\tposition.read = {\n\t\t\t\t\ttask,\n\t\t\t\t\ttext: \"\",\n\t\t\t\t\treadError: `Cannot read output: ${cleanTaskText(String(error))}`,\n\t\t\t\t\ttotalBytes: 0,\n\t\t\t\t\ttruncated: false,\n\t\t\t\t};\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.reading = false;\n\t\t\tif (!this.disposed) this.options.requestRender();\n\t\t\tif (!this.disposed && this.task?.id !== task.id) await this.refresh();\n\t\t}\n\t}\n\tlines(tab: TasksTab): string[] {\n\t\tconst task = this.task;\n\t\tif (!task) return [];\n\t\tconst read = this.position.read;\n\t\tif (this.cache?.task !== task || this.cache.read !== read)\n\t\t\tthis.cache = { task, read, lines: taskLines(task, read, this.options.theme) };\n\t\treturn this.cache.lines[tab];\n\t}\n\tdispose(): void {\n\t\tif (this.disposed) return;\n\t\tthis.disposed = true;\n\t\tthis.release?.();\n\t\tthis.release = undefined;\n\t\tthis.positions.clear();\n\t}\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { AppKeybinding, KeybindingsManager } from "../../../core/keybindings.ts";
2
- import type { Theme } from "../theme/theme.ts";
2
+ import type { Theme } from "../../../modes/interactive/theme/theme.ts";
3
3
  import type { TaskInspector } from "./inspector.ts";
4
4
  import type { TaskList } from "./list.ts";
5
5
  import type { TaskSelection, TasksTab } from "./model.ts";
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/layout.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAc,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAKlG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,WAAW,OAAO;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AACD,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AACD,UAAU,aAAa;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC,CAAC;IACjD,SAAS,EAAE,aAAa,CAAC;IACzB,SAAS,EAAE,aAAa,CAAC;IACzB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACnB;AAGD,6FAA6F;AAC7F,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,WAAW,CA0NrE"}
@@ -2,7 +2,7 @@ import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works
2
2
  import { runtimeLabel } from "../../../core/tasks/format.js";
3
3
  import { isTaskTerminal } from "../../../core/tasks/types.js";
4
4
  import { formatSize } from "../../../core/tools/truncate.js";
5
- import { keyLabel } from "../components/keybinding-hints.js";
5
+ import { keyLabel } from "../../../modes/interactive/components/keybinding-hints.js";
6
6
  import { statusName } from "./task-view.js";
7
7
  import { cleanTaskText, firstCommandLine } from "./text.js";
8
8
  const pad = (text, width) => truncateToWidth(text, Math.max(1, width), "…", true);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/layout.ts"],"names":[],"mappings":"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","sourcesContent":["import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from \"@earendil-works/pi-tui\";\nimport type { AppKeybinding, Keybinding, KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { runtimeLabel } from \"../../../core/tasks/format.ts\";\nimport { isTaskTerminal } from \"../../../core/tasks/types.ts\";\nimport { formatSize } from \"../../../core/tools/truncate.ts\";\nimport { keyLabel } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { TaskInspector } from \"./inspector.ts\";\nimport type { TaskList } from \"./list.ts\";\nimport type { TaskSelection, TasksTab } from \"./model.ts\";\nimport { statusName } from \"./task-view.ts\";\nimport { cleanTaskText, firstCommandLine } from \"./text.ts\";\nimport type { TaskViewport } from \"./viewport.ts\";\n\nexport interface TaskHit {\n\tx: number;\n\ty: number;\n\twidth: number;\n\tkey?: AppKeybinding;\n\ttaskId?: string;\n\ttab?: TasksTab;\n\tcancel?: boolean;\n}\nexport interface TasksLayout {\n\thits: TaskHit[];\n\tlistWidth: number;\n\tlistPageSize: number;\n\tlines: string[];\n\t/** The terminal is below the supported size; only a full-screen resize notice is shown. */\n\ttooSmall?: boolean;\n}\ninterface LayoutOptions {\n\twidth: number;\n\theight: number;\n\ttheme: Theme;\n\tkeybindings: Pick<KeybindingsManager, \"getKeys\">;\n\tselection: TaskSelection;\n\tinspector: TaskInspector;\n\tlist: TaskList;\n\tfocus: \"list\" | \"inspector\";\n\tsearchLine?: (width: number) => string;\n\tpendingKill?: string;\n\tfeedback?: string;\n\thelp?: TaskViewport;\n\tcanDetach: boolean;\n}\nconst pad = (text: string, width: number) => truncateToWidth(text, Math.max(1, width), \"…\", true);\n\n/** Cell geometry and mouse targets are produced together, so resize cannot separate them. */\nexport function renderTasksLayout(options: LayoutOptions): TasksLayout {\n\tconst { width, height, theme, selection, inspector, list, focus, keybindings } = options;\n\tconst hint = (key: Keybinding) => keyLabel(key, { keybindings });\n\tconst result: TasksLayout = { hits: [], listWidth: 0, listPageSize: 1, lines: [] };\n\tif (width < 1 || height < 1) return result;\n\tconst wide = width >= 100;\n\tconst listWidth = wide ? Math.min(42, Math.max(32, Math.floor(width * 0.32))) : width;\n\tconst rightWidth = wide ? width - listWidth - 1 : width;\n\tconst rightX = wide ? listWidth + 1 : 0;\n\tconst bodyHeight = height - 5;\n\tconst hits = result.hits;\n\tresult.listWidth = listWidth;\n\tresult.listPageSize = Math.max(1, Math.floor((bodyHeight - 1) / 2));\n\tconst pane = (lines: string[], size: number, active: boolean): string[] => {\n\t\tconst border = (text: string) => theme.fg(wide && active ? \"borderAccent\" : \"borderMuted\", text);\n\t\treturn [\n\t\t\tborder(`┌${\"─\".repeat(size - 2)}┐`),\n\t\t\t...lines.map((line) => border(\"│\") + pad(line, size - 2) + border(\"│\")),\n\t\t\tborder(`└${\"─\".repeat(size - 2)}┘`),\n\t\t];\n\t};\n\tif (width < 60 || height < 14) {\n\t\t// The panel is modal: a floating notice would leave the transcript visible yet\n\t\t// unscrollable, so the notice owns every row as a centered dialog. Only a truly\n\t\t// tiny terminal, where even the dialog does not fit, gets bare covering lines.\n\t\tresult.tooSmall = true;\n\t\tconst message = \"Terminal too small for /tasks. Enlarge the window to continue.\";\n\t\tconst close = `${hint(\"tui.select.cancel\")} close`;\n\t\tconst boxWidth = Math.min(width, 46);\n\t\tconst inner = boxWidth - 2;\n\t\tconst wrapped = wrapTextWithAnsi(message, inner).map((line) => theme.fg(\"warning\", line));\n\t\tconst spacious = [theme.fg(\"text\", \"Tasks\"), \"\", ...wrapped, \"\", theme.fg(\"dim\", close)];\n\t\tconst tight = [theme.fg(\"text\", \"Tasks\"), ...wrapped, theme.fg(\"dim\", close)];\n\t\tconst body = height >= spacious.length + 2 ? spacious : tight;\n\t\tif (inner >= 16 && height >= body.length + 2) {\n\t\t\tconst box = pane(body, boxWidth, false);\n\t\t\tconst left = Math.floor((width - boxWidth) / 2);\n\t\t\tconst top = Math.max(0, Math.floor((height - box.length) / 2));\n\t\t\tconst blank = \" \".repeat(width);\n\t\t\tresult.lines = [\n\t\t\t\t...Array.from({ length: top }, () => blank),\n\t\t\t\t...box.map((line) => \" \".repeat(left) + line + \" \".repeat(width - left - boxWidth)),\n\t\t\t\t...Array.from({ length: height - top - box.length }, () => blank),\n\t\t\t];\n\t\t\thits.push({ x: left + 1, y: top + body.length, width: visibleWidth(close), cancel: true });\n\t\t} else {\n\t\t\tresult.lines = [\"Tasks\", message, close].slice(0, height).map((line) => pad(line, width));\n\t\t\twhile (result.lines.length < height) result.lines.push(\" \".repeat(width));\n\t\t}\n\t\treturn result;\n\t}\n\tconst visible = list.render(selection, theme, listWidth - 2, bodyHeight);\n\tlet listHeader = theme.fg(\"text\", \"Tasks\");\n\tconst searchLabel = `${hint(\"app.tasks.search\")} find`;\n\tif (options.searchLine) listHeader = options.searchLine(listWidth - 2);\n\telse {\n\t\tconst x = Math.max(6, listWidth - 2 - visibleWidth(searchLabel));\n\t\tlistHeader += \" \".repeat(x - 5) + theme.fg(\"dim\", searchLabel);\n\t\tif (wide || focus === \"list\")\n\t\t\thits.push({ x: x + 1, y: 1, width: visibleWidth(searchLabel), key: \"app.tasks.search\" });\n\t}\n\tif (wide || focus === \"list\")\n\t\tvisible.forEach((row, index) => {\n\t\t\tif (row.taskId) hits.push({ x: 1, y: 2 + index, width: listWidth - 2, taskId: row.taskId });\n\t\t});\n\tconst left = [\n\t\tlistHeader,\n\t\t...Array.from({ length: bodyHeight }, (_, i) => visible[i]?.text ?? \"\"),\n\t\ttheme.fg(\"dim\", list.range),\n\t];\n\tconst task = inspector.task;\n\tconst tab = selection.state.tab;\n\tconst tabLabel = (id: TasksTab, label: string) => theme.style(label, { fg: \"text\", underline: tab === id });\n\tconst right = [`${tabLabel(\"output\", \"Output\")} ${tabLabel(\"info\", \"Details\")}`];\n\tif (wide || focus === \"inspector\")\n\t\thits.push({ x: rightX + 1, y: 1, width: 6, tab: \"output\" }, { x: rightX + 9, y: 1, width: 7, tab: \"info\" });\n\tconst content: string[] = [];\n\tlet reading = \"\";\n\tif (task) {\n\t\tif (!wide)\n\t\t\tcontent.push(\n\t\t\t\ttheme.fg(\"text\", cleanTaskText(firstCommandLine(task.command ?? task.title))),\n\t\t\t\ttheme.fg(\"muted\", `${statusName(task.status)} · ${runtimeLabel(task)}`),\n\t\t\t);\n\t\tconst lines = inspector.lines(tab);\n\t\tconst position = inspector.position;\n\t\tconst read = position.read;\n\t\tconst diagnostics = [task.error, read?.readError].filter((text): text is string => !!text).map(cleanTaskText);\n\t\tif (tab === \"output\" && diagnostics.length)\n\t\t\tcontent.push(theme.fg(\"warning\", diagnostics.join(\" · \").replace(/\\n/g, \" \")));\n\t\tconst source =\n\t\t\ttab === \"info\"\n\t\t\t\t? [\n\t\t\t\t\t\t`Task ID ${task.id}`,\n\t\t\t\t\t\t`Status ${statusName(task.status)} · ${statusName(task.mode)} · ${runtimeLabel(task)}`,\n\t\t\t\t\t\t...diagnostics,\n\t\t\t\t\t\t...lines,\n\t\t\t\t\t]\n\t\t\t\t: lines;\n\t\tcontent.push(...position[tab].layout(source, rightWidth - 2, bodyHeight - content.length));\n\t\tif (tab === \"output\") {\n\t\t\treading = position.output.follow\n\t\t\t\t? isTaskTerminal(task.status)\n\t\t\t\t\t? \"Finished\"\n\t\t\t\t\t: \"Live\"\n\t\t\t\t: isTaskTerminal(task.status)\n\t\t\t\t\t? `Finished · ${hint(\"app.tasks.follow\")} load final output`\n\t\t\t\t\t: `Browsing · ${hint(\"app.tasks.follow\")} follow output`;\n\t\t\tif (!position.output.follow && (wide || focus === \"inspector\"))\n\t\t\t\thits.push({\n\t\t\t\t\tx: rightX + 1,\n\t\t\t\t\ty: height - 3,\n\t\t\t\t\twidth: Math.min(rightWidth - 2, visibleWidth(reading)),\n\t\t\t\t\tkey: \"app.tasks.follow\",\n\t\t\t\t});\n\t\t\tif (read?.truncated)\n\t\t\t\treading += ` · Tail preview: ${formatSize(Buffer.byteLength(read.text))} of ${formatSize(read.totalBytes)}`;\n\t\t} else if (tab === \"info\") reading = `Details ${position.info.range}`;\n\t} else content.push(theme.fg(\"muted\", \"Select a task to inspect its result.\"));\n\tright.push(...Array.from({ length: bodyHeight }, (_, i) => content[i] ?? \"\"), theme.fg(\"dim\", reading));\n\tconst rightPane = pane(right, rightWidth, focus === \"inspector\");\n\tlet panels = wide\n\t\t? pane(left, listWidth, focus === \"list\").map((line, i) => `${line} ${rightPane[i]}`)\n\t\t: pane(focus === \"list\" ? left : right, width, false);\n\n\tlet footer = \"\";\n\tconst addHint = (key: Keybinding, label: string, target?: Omit<TaskHit, \"x\" | \"y\" | \"width\">) => {\n\t\tconst text = `${hint(key)} ${label}`;\n\t\tconst x = visibleWidth(footer) + (footer ? 3 : 0);\n\t\tif (x + visibleWidth(text) > width) return;\n\t\tfooter += (footer ? \" · \" : \"\") + text;\n\t\tif (target) hits.push({ x, y: height - 1, width: visibleWidth(text), ...target });\n\t};\n\tif (options.help || options.pendingKill) {\n\t\thits.length = 0;\n\t\tlet body: string[];\n\t\tif (options.help) {\n\t\t\tconst controls: [Keybinding, string][] = [\n\t\t\t\t[\"app.tasks.nextFocus\", \"Switch task list / inspector\"],\n\t\t\t\t[\"app.tasks.previousFocus\", \"Switch inspector / task list\"],\n\t\t\t\t[\"app.tasks.previousTab\", \"Output (inspector only)\"],\n\t\t\t\t[\"app.tasks.nextTab\", \"Details (inspector only)\"],\n\t\t\t\t[\"tui.select.up\", \"Previous task / scroll up\"],\n\t\t\t\t[\"tui.select.down\", \"Next task / scroll down\"],\n\t\t\t\t[\"tui.select.pageUp\", \"Page up in task list\"],\n\t\t\t\t[\"tui.select.pageDown\", \"Page down in task list\"],\n\t\t\t\t[\"tui.editor.pageUp\", \"Page up in inspector\"],\n\t\t\t\t[\"tui.editor.pageDown\", \"Page down in inspector\"],\n\t\t\t\t[\"app.tasks.top\", \"Top of list / content\"],\n\t\t\t\t[\"app.tasks.bottom\", \"Bottom of list / content\"],\n\t\t\t\t[\"app.tasks.search\", \"Locate a retained task; Enter chooses, Escape restores selection\"],\n\t\t\t\t[\"app.tasks.follow\", \"Follow latest / final output (Output only)\"],\n\t\t\t\t[\"app.tasks.detach\", \"Move every eligible foreground execution to the background\"],\n\t\t\t\t[\"app.tasks.detachSelected\", \"Move selected foreground task to background\"],\n\t\t\t\t[\"app.tasks.kill\", \"Request stop of selected whole task\"],\n\t\t\t\t[\"app.tasks.confirmStop\", \"Confirm stop\"],\n\t\t\t\t[\"tui.select.cancel\", \"Close current search, help or confirmation; otherwise close panel\"],\n\t\t\t];\n\t\t\tbody = [\n\t\t\t\ttheme.fg(\"text\", \"Task controls\"),\n\t\t\t\t...options.help.layout(\n\t\t\t\t\tcontrols.map(([key, label]) => hint(key).padEnd(14) + label),\n\t\t\t\t\twidth - 2,\n\t\t\t\t\theight - 5,\n\t\t\t\t),\n\t\t\t\t\"\",\n\t\t\t];\n\t\t\taddHint(\"tui.select.up\", `/ ${hint(\"tui.select.down\")} scroll`);\n\t\t\taddHint(\"tui.select.cancel\", \"back\", { cancel: true });\n\t\t} else {\n\t\t\tconst target = selection.all.find((task) => task.id === options.pendingKill);\n\t\t\tconst command = wrapTextWithAnsi(\n\t\t\t\tcleanTaskText(target?.command ?? target?.title ?? options.pendingKill!),\n\t\t\t\twidth - 2,\n\t\t\t);\n\t\t\tconst preview = command.slice(0, height - 8);\n\t\t\tif (preview.length < command.length) preview[preview.length - 1] = \"… Full command in Details.\";\n\t\t\tbody = [\n\t\t\t\ttheme.fg(\"text\", \"Stop task?\"),\n\t\t\t\t\"Stops the whole task, including its active work.\",\n\t\t\t\t`Task ID: ${options.pendingKill}`,\n\t\t\t\t\"\",\n\t\t\t\t...preview,\n\t\t\t];\n\t\t\taddHint(\"app.tasks.confirmStop\", \"confirm\", { key: \"app.tasks.confirmStop\" });\n\t\t\taddHint(\"tui.select.cancel\", \"cancel\", { cancel: true });\n\t\t}\n\t\twhile (body.length < height - 3) body.push(\"\");\n\t\tpanels = pane(body, width, false);\n\t} else if (options.searchLine) {\n\t\t// Only search candidates and cancellation are clickable while locating a task.\n\t\tfor (let i = hits.length - 1; i >= 0; i--) if (!hits[i]!.taskId) hits.splice(i, 1);\n\t\taddHint(\"tui.select.up\", `/ ${hint(\"tui.select.down\")} choose`);\n\t\taddHint(\"tui.select.confirm\", \"locate\");\n\t\taddHint(\"tui.select.cancel\", \"cancel\", { cancel: true });\n\t} else {\n\t\taddHint(\"tui.select.up\", `/ ${hint(\"tui.select.down\")}${focus === \"list\" ? \" tasks\" : \" scroll\"}`);\n\t\taddHint(\"app.tasks.nextFocus\", focus === \"list\" ? (tab === \"output\" ? \"output\" : \"details\") : \"tasks\", {\n\t\t\tkey: \"app.tasks.nextFocus\",\n\t\t});\n\t\taddHint(\"tui.select.cancel\", \"close\", { cancel: true });\n\t\tif (focus === \"list\") addHint(\"app.tasks.search\", \"find\", { key: \"app.tasks.search\" });\n\t\telse {\n\t\t\taddHint(\"app.tasks.previousTab\", \"output\", { tab: \"output\" });\n\t\t\taddHint(\"app.tasks.nextTab\", \"details\", { tab: \"info\" });\n\t\t}\n\t\tif (task && !isTaskTerminal(task.status) && task.status !== \"stopping\") {\n\t\t\taddHint(\"app.tasks.kill\", \"stop\", { key: \"app.tasks.kill\" });\n\t\t\tif (task.mode === \"foreground\" && options.canDetach)\n\t\t\t\taddHint(\"app.tasks.detachSelected\", \"background\", { key: \"app.tasks.detachSelected\" });\n\t\t}\n\t\taddHint(\"app.tasks.help\", \"keys\", { key: \"app.tasks.help\" });\n\t\t// Feedback borrows the hint row, so the hint hit targets stay live and the click that\n\t\t// dismisses it can act in the same gesture.\n\t\tif (options.feedback) footer = options.feedback;\n\t}\n\tresult.lines = [...panels, theme.fg(options.pendingKill ? \"warning\" : \"dim\", pad(footer, width))];\n\treturn result;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { Theme } from "../theme/theme.ts";
1
+ import type { Theme } from "../../../modes/interactive/theme/theme.ts";
2
2
  import type { TaskSelection } from "./model.ts";
3
3
  interface ListRow {
4
4
  text: string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/list.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD,UAAU,OAAO;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,4FAA4F;AAC5F,qBAAa,QAAQ;IACpB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,MAAM,CAAS;IACvB,aAAa,IAAI,IAAI;IAGrB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAG3B,MAAM,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE;IA6DxF,IAAI,KAAK,IAAI,MAAM,CAOlB;CACD"}
@@ -1,7 +1,7 @@
1
1
  import { stripTerminalSequences, truncateToWidth } from "@earendil-works/pi-tui";
2
2
  import { runtimeLabel } from "../../../core/tasks/format.js";
3
3
  import { isTaskTerminal } from "../../../core/tasks/types.js";
4
- import { statusMarker } from "../components/status-marker.js";
4
+ import { statusMarker } from "../../../modes/interactive/components/status-marker.js";
5
5
  import { statusName } from "./task-view.js";
6
6
  import { cleanTaskText, firstCommandLine } from "./text.js";
7
7
  /** Keeps list scrolling independent of selection, with an identity anchor on reordering. */
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/list.ts"],"names":[],"mappings":"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","sourcesContent":["import { stripTerminalSequences, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport { runtimeLabel } from \"../../../core/tasks/format.ts\";\nimport { isTaskTerminal } from \"../../../core/tasks/types.ts\";\nimport { statusMarker } from \"../../../modes/interactive/components/status-marker.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { TaskSelection } from \"./model.ts\";\nimport { statusName } from \"./task-view.ts\";\nimport { cleanTaskText, firstCommandLine } from \"./text.ts\";\n\ninterface ListRow {\n\ttext: string;\n\ttaskId?: string;\n}\n\n/** Keeps list scrolling independent of selection, with an identity anchor on reordering. */\nexport class TaskList {\n\tprivate start = 0;\n\tprivate height = 1;\n\tprivate rows: ListRow[] = [];\n\tprivate selectedId?: string;\n\tprivate selectedLine = -1;\n\tprivate reveal = false;\n\tshowSelection(): void {\n\t\tthis.reveal = true;\n\t}\n\tscroll(delta: number): void {\n\t\tthis.start = Math.max(0, Math.min(Math.max(0, this.rows.length - this.height), this.start + delta));\n\t}\n\trender(selection: TaskSelection, theme: Theme, width: number, height: number): ListRow[] {\n\t\tconst rows: ListRow[] = [];\n\t\tconst labels = selection.rows.map((task) => cleanTaskText(firstCommandLine(task.command ?? task.title)));\n\t\tconst fitted = labels.map((label) => truncateToWidth(label, Math.max(1, width - 3), \"…\"));\n\t\tlet group = \"\",\n\t\t\tselectedLine = -1;\n\t\tfor (const [index, task] of selection.rows.entries()) {\n\t\t\tconst nextGroup = isTaskTerminal(task.status) ? \"Finished\" : \"Active\";\n\t\t\tif (nextGroup !== group) {\n\t\t\t\trows.push({ text: theme.fg(\"dim\", nextGroup) });\n\t\t\t\tgroup = nextGroup;\n\t\t\t}\n\t\t\tconst selected = task.id === selection.state.selectedId;\n\t\t\tif (selected) selectedLine = rows.length;\n\t\t\tconst marker = statusMarker(task.status, { now: Date.now() });\n\t\t\tconst duplicate = fitted.some((label, other) => other !== index && label === fitted[index]);\n\t\t\tconst meta = `${runtimeLabel(task)}${duplicate ? ` · ${task.id.slice(-8)}` : \"\"}`;\n\t\t\tconst texts = [\n\t\t\t\t`${theme.fg(marker.color, marker.glyph)} ${theme.fg(\"text\", labels[index]!)}`,\n\t\t\t\t` ${theme.fg(marker.color, statusName(task.status))}${theme.fg(\"muted\", ` · ${meta}`)}`,\n\t\t\t];\n\t\t\tfor (const text of texts) {\n\t\t\t\tconst padded = truncateToWidth(text, width, \"…\", true);\n\t\t\t\t// The system theme has no panel backgrounds until the terminal reports its colors.\n\t\t\t\trows.push({\n\t\t\t\t\ttext: !selected\n\t\t\t\t\t\t? padded\n\t\t\t\t\t\t: theme.getBgAnsi(\"selectedBg\") === \"\\x1b[49m\"\n\t\t\t\t\t\t\t? theme.style(stripTerminalSequences(padded), { inverse: true })\n\t\t\t\t\t\t\t: theme.bg(\"selectedBg\", padded),\n\t\t\t\t\ttaskId: task.id,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tif (!rows.length)\n\t\t\trows.push({ text: theme.fg(\"muted\", selection.query ? \"No matching tasks.\" : \"No retained tasks.\") });\n\t\tconst sameSelection = this.selectedId === selection.state.selectedId;\n\t\tconst selectedWasVisible =\n\t\t\tsameSelection &&\n\t\t\tthis.selectedLine >= this.start &&\n\t\t\tthis.selectedLine < this.start + this.height &&\n\t\t\tselectedLine >= 0;\n\t\tif (selectedWasVisible) this.start += selectedLine - this.selectedLine;\n\t\telse {\n\t\t\tconst anchor = this.rows[this.start]?.taskId;\n\t\t\tconst offset = anchor && this.rows[this.start - 1]?.taskId === anchor ? 1 : 0;\n\t\t\tconst next = anchor ? rows.findIndex((row) => row.taskId === anchor) : -1;\n\t\t\tif (next >= 0) this.start = next + offset;\n\t\t}\n\t\tif (selectedLine >= 0 && (!sameSelection || this.reveal || selectedWasVisible)) {\n\t\t\tif (selectedLine < this.start) this.start = selectedLine;\n\t\t\telse if (selectedLine + 1 >= this.start + height) this.start = selectedLine + 2 - height;\n\t\t}\n\t\tthis.start = Math.max(0, Math.min(Math.max(0, rows.length - height), this.start));\n\t\tthis.rows = rows;\n\t\tthis.height = height;\n\t\tthis.selectedId = selection.state.selectedId;\n\t\tthis.selectedLine = selectedLine;\n\t\tthis.reveal = false;\n\t\treturn rows.slice(this.start, this.start + height);\n\t}\n\tget range(): string {\n\t\tif (this.rows.length <= this.height) return \"\";\n\t\tconst ids = [...new Set(this.rows.flatMap((row) => (row.taskId ? [row.taskId] : [])))];\n\t\tconst visible = this.rows\n\t\t\t.slice(this.start, this.start + this.height)\n\t\t\t.flatMap((row) => (row.taskId ? [row.taskId] : []));\n\t\treturn `Tasks ${ids.indexOf(visible[0]!) + 1}-${ids.indexOf(visible.at(-1)!) + 1} of ${ids.length}`;\n\t}\n}\n"]}
@@ -1,8 +1,9 @@
1
1
  /** Panel lifecycle and input routing; selection, output ownership and layout have separate owners. */
2
+ import "../keybindings.ts";
2
3
  import { type Component, type Focusable, type TuiMouseEvent, type TuiMouseEventResult } from "@earendil-works/pi-tui";
3
4
  import type { KeybindingsManager } from "../../../core/keybindings.ts";
4
5
  import { type TasksContext } from "../../../core/tasks/types.ts";
5
- import type { Theme } from "../theme/theme.ts";
6
+ import type { Theme } from "../../../modes/interactive/theme/theme.ts";
6
7
  import { type TasksPanelState } from "./model.ts";
7
8
  export type TasksManagerHost = Pick<TasksContext, "list" | "read" | "kill" | "subscribe" | "retain"> & Partial<Pick<TasksContext, "detach" | "enabled">>;
8
9
  export interface TasksMenuOptions {
@@ -0,0 +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,7 +1,8 @@
1
1
  /** Panel lifecycle and input routing; selection, output ownership and layout have separate owners. */
2
+ import "../keybindings.js";
2
3
  import { Input, } from "@earendil-works/pi-tui";
3
4
  import { isTaskTerminal } from "../../../core/tasks/types.js";
4
- import { STATUS_SPINNER_INTERVAL_MS } from "../components/status-marker.js";
5
+ import { STATUS_SPINNER_INTERVAL_MS } from "../../../modes/interactive/components/status-marker.js";
5
6
  import { TaskInspector } from "./inspector.js";
6
7
  import { renderTasksLayout } from "./layout.js";
7
8
  import { TaskList } from "./list.js";
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/manager.ts"],"names":[],"mappings":"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","sourcesContent":["/** Panel lifecycle and input routing; selection, output ownership and layout have separate owners. */\nimport \"../keybindings.ts\";\nimport {\n\ttype Component,\n\ttype Focusable,\n\tInput,\n\ttype TuiMouseEvent,\n\ttype TuiMouseEventResult,\n} from \"@earendil-works/pi-tui\";\nimport type { AppKeybinding, KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { isTaskTerminal, type TasksContext } from \"../../../core/tasks/types.ts\";\nimport { STATUS_SPINNER_INTERVAL_MS } from \"../../../modes/interactive/components/status-marker.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport { TaskInspector } from \"./inspector.ts\";\nimport { renderTasksLayout, type TasksLayout } from \"./layout.ts\";\nimport { TaskList } from \"./list.ts\";\nimport { TaskSelection, type TasksPanelState } from \"./model.ts\";\nimport { cleanTaskText } from \"./text.ts\";\nimport { TaskViewport } from \"./viewport.ts\";\n\nexport type TasksManagerHost = Pick<TasksContext, \"list\" | \"read\" | \"kill\" | \"subscribe\" | \"retain\"> &\n\tPartial<Pick<TasksContext, \"detach\" | \"enabled\">>;\nexport interface TasksMenuOptions {\n\ttui: { requestRender(): void; terminal: { rows: number; columns: number } };\n\ttheme: Theme;\n\tkeybindings: Pick<KeybindingsManager, \"matches\" | \"getKeys\">;\n\thost: TasksManagerHost;\n\tstate?: TasksPanelState;\n\tonClose(): void;\n\tpollIntervalMs?: number;\n}\n\nconst actions: AppKeybinding[] = [\n\t\"app.tasks.search\",\n\t\"app.tasks.kill\",\n\t\"app.tasks.detachSelected\",\n\t\"app.tasks.previousTab\",\n\t\"app.tasks.nextTab\",\n\t\"app.tasks.follow\",\n\t\"app.tasks.top\",\n\t\"app.tasks.bottom\",\n\t\"app.tasks.nextFocus\",\n\t\"app.tasks.previousFocus\",\n\t\"app.tasks.help\",\n];\n\nexport class TasksMenu implements Component, Focusable {\n\tfocused = false;\n\tprivate readonly options: TasksMenuOptions;\n\tprivate readonly selection: TaskSelection;\n\tprivate readonly inspector: TaskInspector;\n\tprivate readonly list = new TaskList();\n\tprivate readonly search: Input;\n\tprivate readonly unsubscribe: () => void;\n\tprivate readonly pollTimer: ReturnType<typeof setInterval>;\n\tprivate animationTimer?: ReturnType<typeof setInterval>;\n\tprivate pendingKill?: string;\n\tprivate feedback?: string;\n\tprivate focus: \"list\" | \"inspector\" = \"list\";\n\tprivate searching = false;\n\tprivate beforeSearch?: { id?: string; focus: \"list\" | \"inspector\" };\n\tprivate help?: TaskViewport;\n\tprivate dirty = true;\n\tprivate tickQueued = false;\n\tprivate refreshQueued = false;\n\tprivate disposed = false;\n\tprivate width: number;\n\tprivate layout?: TasksLayout;\n\tconstructor(options: TasksMenuOptions) {\n\t\tthis.options = options;\n\t\tthis.width = options.tui.terminal.columns;\n\t\tthis.selection = new TaskSelection(options.state ?? { tab: \"output\" });\n\t\tthis.inspector = new TaskInspector({\n\t\t\thost: options.host,\n\t\t\ttheme: options.theme,\n\t\t\trequestRender: () => options.tui.requestRender(),\n\t\t});\n\t\tthis.search = new Input({ prompt: \"Find task: \", placeholder: \"title, command, kind or ID\" });\n\t\tthis.sync();\n\t\tthis.unsubscribe = options.host.subscribe(() => {\n\t\t\tthis.dirty = true;\n\t\t\tthis.queueTick();\n\t\t\toptions.tui.requestRender();\n\t\t});\n\t\tthis.pollTimer = setInterval(() => {\n\t\t\tthis.queueTick(true);\n\t\t\tif (this.selection.activeCount) options.tui.requestRender();\n\t\t}, options.pollIntervalMs ?? 1000);\n\t\tthis.pollTimer.unref?.();\n\t\tthis.queueTick(true);\n\t}\n\tprivate sync(): void {\n\t\tif (this.disposed || !this.dirty) return;\n\t\tthis.dirty = false;\n\t\tconst previous = this.selection.selected;\n\t\tthis.selection.sync(this.options.host.list());\n\t\tthis.inspector.select(this.selection.selected);\n\t\tthis.inspector.prune(new Set(this.selection.all.map((task) => task.id)));\n\t\tconst selected = this.selection.selected;\n\t\tif (selected && isTaskTerminal(selected.status) && previous && !isTaskTerminal(previous.status))\n\t\t\tthis.feedback = undefined;\n\t\tif (this.pendingKill && (this.pendingKill !== selected?.id || (selected && isTaskTerminal(selected.status))))\n\t\t\tthis.clearKill();\n\t\tconst animates = this.selection.all.some((task) => task.status === \"running\");\n\t\tif (animates && !this.animationTimer) {\n\t\t\tthis.animationTimer = setInterval(() => this.options.tui.requestRender(), STATUS_SPINNER_INTERVAL_MS);\n\t\t\tthis.animationTimer.unref?.();\n\t\t} else if (!animates) {\n\t\t\tclearInterval(this.animationTimer);\n\t\t\tthis.animationTimer = undefined;\n\t\t}\n\t}\n\tprivate queueTick(refresh = false): void {\n\t\tif (this.disposed) return;\n\t\tthis.refreshQueued ||= refresh;\n\t\tif (this.tickQueued) return;\n\t\tthis.tickQueued = true;\n\t\tvoid Promise.resolve()\n\t\t\t.then(async () => {\n\t\t\t\tthis.tickQueued = false;\n\t\t\t\tif (this.disposed) return;\n\t\t\t\tconst refresh = this.refreshQueued;\n\t\t\t\tthis.refreshQueued = false;\n\t\t\t\tthis.sync();\n\t\t\t\tif (refresh || (this.inspector.task && isTaskTerminal(this.inspector.task.status)))\n\t\t\t\t\tawait this.inspector.refresh();\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\t/* Task observers cannot reject execution. */\n\t\t\t});\n\t}\n\tinvalidate(): void {\n\t\tthis.inspector.invalidate();\n\t}\n\tprivate clearKill(): void {\n\t\tthis.pendingKill = undefined;\n\t}\n\tprivate selectedChanged(): void {\n\t\tthis.clearKill();\n\t\tthis.list.showSelection();\n\t\tthis.inspector.select(this.selection.selected);\n\t\tthis.queueTick(true);\n\t}\n\tprivate stop(confirm = false): void {\n\t\tconst task = this.selection.selected;\n\t\tif (confirm) {\n\t\t\tconst id = this.pendingKill;\n\t\t\tthis.clearKill();\n\t\t\tif (!id || id !== task?.id || isTaskTerminal(task.status)) return;\n\t\t\tthis.feedback = this.options.host.kill(id)\n\t\t\t\t? \"Cancellation requested; waiting for cleanup.\"\n\t\t\t\t: \"No new cancellation requested.\";\n\t\t} else if (task && !isTaskTerminal(task.status) && task.status !== \"stopping\") {\n\t\t\tthis.pendingKill = task.id;\n\t\t}\n\t}\n\tprivate finishSearch(cancel: boolean): void {\n\t\tconst id = cancel ? this.beforeSearch?.id : this.selection.state.selectedId;\n\t\tif (!cancel && !id) return;\n\t\tthis.focus = cancel ? (this.beforeSearch?.focus ?? \"list\") : \"list\";\n\t\tthis.searching = false;\n\t\tthis.search.focused = false;\n\t\tthis.selection.query = \"\";\n\t\tthis.selection.select(id);\n\t\tthis.beforeSearch = undefined;\n\t\tthis.selectedChanged();\n\t}\n\tprivate action(key: AppKeybinding): void {\n\t\tswitch (key) {\n\t\t\tcase \"app.tasks.search\":\n\t\t\t\tthis.beforeSearch = { id: this.selection.state.selectedId, focus: this.focus };\n\t\t\t\tthis.focus = \"list\";\n\t\t\t\tthis.searching = true;\n\t\t\t\tthis.search.focused = true;\n\t\t\t\tthis.search.setValue(\"\");\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.previousTab\":\n\t\t\tcase \"app.tasks.nextTab\":\n\t\t\t\tif (this.focus === \"inspector\")\n\t\t\t\t\tthis.selection.state.tab = key === \"app.tasks.previousTab\" ? \"output\" : \"info\";\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.nextFocus\":\n\t\t\tcase \"app.tasks.previousFocus\":\n\t\t\t\tthis.focus = this.focus === \"list\" ? \"inspector\" : \"list\";\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.follow\":\n\t\t\t\tif (this.focus === \"inspector\" && this.selection.state.tab === \"output\") {\n\t\t\t\t\tthis.inspector.position.output.jump(true, true);\n\t\t\t\t\tthis.queueTick(true);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.top\":\n\t\t\tcase \"app.tasks.bottom\":\n\t\t\t\tif (this.focus === \"list\") {\n\t\t\t\t\tthis.selection.select(\n\t\t\t\t\t\tkey === \"app.tasks.top\" ? this.selection.rows[0]?.id : this.selection.rows.at(-1)?.id,\n\t\t\t\t\t);\n\t\t\t\t\tthis.selectedChanged();\n\t\t\t\t} else\n\t\t\t\t\tthis.inspector.position[this.selection.state.tab].jump(\n\t\t\t\t\t\tkey === \"app.tasks.bottom\",\n\t\t\t\t\t\tthis.selection.state.tab === \"output\",\n\t\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.kill\":\n\t\t\t\tthis.stop();\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.confirmStop\":\n\t\t\t\tthis.stop(true);\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.detachSelected\": {\n\t\t\t\tconst task = this.selection.selected;\n\t\t\t\tif (\n\t\t\t\t\ttask?.mode === \"foreground\" &&\n\t\t\t\t\t!isTaskTerminal(task.status) &&\n\t\t\t\t\ttask.status !== \"stopping\" &&\n\t\t\t\t\tthis.options.host.enabled !== false\n\t\t\t\t) {\n\t\t\t\t\tthis.feedback = this.options.host.detach?.(task.id)\n\t\t\t\t\t\t? \"Selected task moved to background; execution continues.\"\n\t\t\t\t\t\t: \"This task cannot move to background.\";\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"app.tasks.help\":\n\t\t\t\tthis.help = this.help ? undefined : new TaskViewport();\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tprivate move(direction: number, page = false): void {\n\t\tif (this.help) {\n\t\t\tthis.help.move(direction, page, false);\n\t\t\treturn;\n\t\t}\n\t\tif (this.focus === \"list\") {\n\t\t\tconst rows = this.selection.rows;\n\t\t\tif (!rows.length) return;\n\t\t\tconst index = rows.findIndex((task) => task.id === this.selection.state.selectedId);\n\t\t\tconst next = page\n\t\t\t\t? Math.max(0, Math.min(rows.length - 1, index + direction * (this.layout?.listPageSize ?? 1)))\n\t\t\t\t: (index + direction + rows.length) % rows.length;\n\t\t\tthis.selection.select(rows[next]?.id);\n\t\t\tthis.selectedChanged();\n\t\t} else\n\t\t\tthis.inspector.position[this.selection.state.tab].move(direction, page, this.selection.state.tab === \"output\");\n\t}\n\thandleInput(data: string): void {\n\t\tif (this.disposed) return;\n\t\tthis.sync();\n\t\tthis.render(this.width);\n\t\tconst kb = this.options.keybindings;\n\t\tthis.feedback = undefined;\n\t\ttry {\n\t\t\tif (this.layout?.tooSmall) {\n\t\t\t\t// The resize notice owns the screen; keys must not act on the hidden panel.\n\t\t\t\t// Cancel unwinds one transient state at a time, then closes.\n\t\t\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\t\t\tif (this.help) this.help = undefined;\n\t\t\t\t\telse if (this.searching) this.finishSearch(true);\n\t\t\t\t\telse if (this.pendingKill) this.clearKill();\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.dispose();\n\t\t\t\t\t\tthis.options.onClose();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (this.help) {\n\t\t\t\tif (kb.matches(data, \"tui.select.cancel\") || kb.matches(data, \"app.tasks.help\")) this.help = undefined;\n\t\t\t\telse if (kb.matches(data, \"app.tasks.top\") || kb.matches(data, \"app.tasks.bottom\"))\n\t\t\t\t\tthis.help.jump(kb.matches(data, \"app.tasks.bottom\"), false);\n\t\t\t\telse if (kb.matches(data, \"tui.select.up\") || kb.matches(data, \"tui.editor.pageUp\"))\n\t\t\t\t\tthis.help.move(-1, kb.matches(data, \"tui.editor.pageUp\"), false);\n\t\t\t\telse if (kb.matches(data, \"tui.select.down\") || kb.matches(data, \"tui.editor.pageDown\"))\n\t\t\t\t\tthis.help.move(1, kb.matches(data, \"tui.editor.pageDown\"), false);\n\t\t\t} else if (this.searching) {\n\t\t\t\tif (kb.matches(data, \"tui.select.cancel\")) this.finishSearch(true);\n\t\t\t\telse if (kb.matches(data, \"tui.select.confirm\")) this.finishSearch(false);\n\t\t\t\telse if (kb.matches(data, \"tui.select.up\") || kb.matches(data, \"tui.select.pageUp\"))\n\t\t\t\t\tthis.move(-1, kb.matches(data, \"tui.select.pageUp\"));\n\t\t\t\telse if (kb.matches(data, \"tui.select.down\") || kb.matches(data, \"tui.select.pageDown\"))\n\t\t\t\t\tthis.move(1, kb.matches(data, \"tui.select.pageDown\"));\n\t\t\t\telse {\n\t\t\t\t\tthis.search.handleInput(data);\n\t\t\t\t\tthis.selection.query = this.search.getValue().slice(0, 512);\n\t\t\t\t\tthis.selection.refresh();\n\t\t\t\t\tthis.selectedChanged();\n\t\t\t\t}\n\t\t\t} else if (this.pendingKill) {\n\t\t\t\tif (kb.matches(data, \"app.tasks.confirmStop\")) this.stop(true);\n\t\t\t\telse if (kb.matches(data, \"tui.select.cancel\")) this.clearKill();\n\t\t\t} else if (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\t\tthis.dispose();\n\t\t\t\tthis.options.onClose();\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tconst pageUp = kb.matches(data, this.focus === \"list\" ? \"tui.select.pageUp\" : \"tui.editor.pageUp\");\n\t\t\t\tconst pageDown = kb.matches(data, this.focus === \"list\" ? \"tui.select.pageDown\" : \"tui.editor.pageDown\");\n\t\t\t\tif (pageUp || kb.matches(data, \"tui.select.up\")) this.move(-1, pageUp);\n\t\t\t\telse if (pageDown || kb.matches(data, \"tui.select.down\")) this.move(1, pageDown);\n\t\t\t\telse if (kb.matches(data, \"tui.select.confirm\")) return;\n\t\t\t\telse {\n\t\t\t\t\tconst key = actions.find((key) => kb.matches(data, key));\n\t\t\t\t\tif (key) this.action(key);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.feedback = cleanTaskText(error instanceof Error ? error.message : String(error));\n\t\t}\n\t\tthis.queueTick(true);\n\t\tthis.options.tui.requestRender();\n\t}\n\thandleMouse(event: TuiMouseEvent): TuiMouseEventResult | undefined {\n\t\tif (this.disposed || event.ctrl || event.alt || event.shift) return;\n\t\t// Feedback is transient: a click retracts it and acts, exactly like a keypress does.\n\t\tthis.feedback = undefined;\n\t\tthis.render(event.width);\n\t\tconst layout = this.layout!;\n\t\tif (event.type === \"wheel\" && event.wheelDelta) {\n\t\t\tif (!this.pendingKill && !layout.tooSmall && event.y >= 2 && event.y < this.options.tui.terminal.rows - 3) {\n\t\t\t\tconst delta = Math.sign(event.wheelDelta) * Math.min(20, Math.abs(event.wheelDelta));\n\t\t\t\tconst region = this.width >= 100 ? (event.x < layout.listWidth ? \"list\" : \"inspector\") : this.focus;\n\t\t\t\tif (this.help) this.help.move(delta, false, false);\n\t\t\t\telse if (region === \"list\") this.list.scroll(delta);\n\t\t\t\telse if (!this.searching)\n\t\t\t\t\tthis.inspector.position[this.selection.state.tab].move(\n\t\t\t\t\t\tdelta,\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t\tthis.selection.state.tab === \"output\",\n\t\t\t\t\t);\n\t\t\t}\n\t\t} else if (event.type === \"click\" && event.button === \"left\") {\n\t\t\tconst hit = layout.hits.find((hit) => hit.y === event.y && event.x >= hit.x && event.x < hit.x + hit.width);\n\t\t\ttry {\n\t\t\t\tif (hit?.cancel) {\n\t\t\t\t\tif (this.searching) this.finishSearch(true);\n\t\t\t\t\telse if (this.help) this.help = undefined;\n\t\t\t\t\telse if (this.pendingKill) this.clearKill();\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.dispose();\n\t\t\t\t\t\tthis.options.onClose();\n\t\t\t\t\t}\n\t\t\t\t} else if (hit?.taskId) {\n\t\t\t\t\tthis.selection.select(hit.taskId);\n\t\t\t\t\tthis.selectedChanged();\n\t\t\t\t\tthis.focus = \"list\";\n\t\t\t\t\tif (this.searching) this.finishSearch(false);\n\t\t\t\t} else if (hit?.tab) {\n\t\t\t\t\tthis.focus = \"inspector\";\n\t\t\t\t\tthis.selection.state.tab = hit.tab;\n\t\t\t\t} else if (hit?.key) {\n\t\t\t\t\tif (hit.key === \"app.tasks.follow\") this.focus = \"inspector\";\n\t\t\t\t\tthis.action(hit.key);\n\t\t\t\t} else if (\n\t\t\t\t\t!this.pendingKill &&\n\t\t\t\t\t!this.searching &&\n\t\t\t\t\t!this.help &&\n\t\t\t\t\t!layout.tooSmall &&\n\t\t\t\t\tevent.y >= 1 &&\n\t\t\t\t\tevent.y < this.options.tui.terminal.rows - 2 &&\n\t\t\t\t\tthis.width >= 100\n\t\t\t\t)\n\t\t\t\t\tthis.focus = event.x < layout.listWidth ? \"list\" : \"inspector\";\n\t\t\t} catch (error) {\n\t\t\t\tthis.feedback = cleanTaskText(error instanceof Error ? error.message : String(error));\n\t\t\t}\n\t\t} else return;\n\t\tthis.queueTick(true);\n\t\tthis.options.tui.requestRender();\n\t\treturn { handled: true, focus: event.type === \"click\" };\n\t}\n\trender(width: number): string[] {\n\t\tthis.width = width;\n\t\tthis.sync();\n\t\tthis.layout = renderTasksLayout({\n\t\t\twidth,\n\t\t\theight: this.options.tui.terminal.rows,\n\t\t\ttheme: this.options.theme,\n\t\t\tkeybindings: this.options.keybindings,\n\t\t\tselection: this.selection,\n\t\t\tinspector: this.inspector,\n\t\t\tlist: this.list,\n\t\t\tfocus: this.focus,\n\t\t\tsearchLine: this.searching ? (width) => this.search.render(width).join(\"\") : undefined,\n\t\t\tpendingKill: this.pendingKill,\n\t\t\tfeedback: this.feedback,\n\t\t\thelp: this.help,\n\t\t\tcanDetach: this.options.host.enabled !== false && !!this.options.host.detach,\n\t\t});\n\t\treturn this.layout.lines;\n\t}\n\tdispose(): void {\n\t\tif (this.disposed) return;\n\t\tthis.disposed = true;\n\t\tclearInterval(this.pollTimer);\n\t\tclearInterval(this.animationTimer);\n\t\tthis.clearKill();\n\t\tthis.unsubscribe();\n\t\tthis.inspector.dispose();\n\t}\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjF,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEzC,6FAA6F;AAC7F,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,QAAQ,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,8FAA8F;AAC9F,qBAAa,aAAa;IACzB,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,GAAG,EAAE,YAAY,EAAE,CAAM;IACzB,IAAI,EAAE,YAAY,EAAE,CAAM;IAC1B,KAAK,SAAM;gBACC,KAAK,EAAE,eAAe;IAGlC,IAAI,QAAQ,IAAI,YAAY,GAAG,SAAS,CAEvC;IACD,IAAI,WAAW,IAAI,MAAM,CAExB;IACD,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,IAAI;IAI/B,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAIpC,OAAO,IAAI,IAAI;CAiBf"}