@astralyn/pi 1.4.9 → 1.4.10

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 (204) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/bundle/chunks/{chunk-3PKXUKTB.js → chunk-6GTUUUCJ.js} +123 -123
  3. package/dist/bundle/chunks/{chunk-BAGHIP5J.js → chunk-MF3T3ETJ.js} +3 -3
  4. package/dist/bundle/chunks/{chunk-F66AY3WR.js → chunk-UCH27AVQ.js} +1 -1
  5. package/dist/bundle/chunks/{execute-P22VMM2H.js → execute-FQKRO4XJ.js} +1 -1
  6. package/dist/bundle/chunks/{virtual-modules-VKMBQTR2.js → virtual-modules-6IJ6V2CG.js} +1 -1
  7. package/dist/bundle/cli.js +1 -1
  8. package/dist/bundle/index.js +1 -1
  9. package/dist/bundle/rpc-entry.js +1 -1
  10. package/dist/core/agent-session.d.ts +34 -0
  11. package/dist/core/agent-session.d.ts.map +1 -1
  12. package/dist/core/agent-session.js +99 -2
  13. package/dist/core/agent-session.js.map +1 -1
  14. package/dist/core/isolated-session.d.ts +7 -2
  15. package/dist/core/isolated-session.d.ts.map +1 -1
  16. package/dist/core/isolated-session.js +7 -3
  17. package/dist/core/isolated-session.js.map +1 -1
  18. package/dist/core/session-manager.d.ts +17 -1
  19. package/dist/core/session-manager.d.ts.map +1 -1
  20. package/dist/core/session-manager.js +29 -0
  21. package/dist/core/session-manager.js.map +1 -1
  22. package/dist/core/tasks/delivery.d.ts +42 -7
  23. package/dist/core/tasks/delivery.d.ts.map +1 -1
  24. package/dist/core/tasks/delivery.js +129 -15
  25. package/dist/core/tasks/delivery.js.map +1 -1
  26. package/dist/core/tasks/execution.d.ts +27 -14
  27. package/dist/core/tasks/execution.d.ts.map +1 -1
  28. package/dist/core/tasks/execution.js +90 -86
  29. package/dist/core/tasks/execution.js.map +1 -1
  30. package/dist/core/tasks/limits.d.ts +13 -1
  31. package/dist/core/tasks/limits.d.ts.map +1 -1
  32. package/dist/core/tasks/limits.js +14 -1
  33. package/dist/core/tasks/limits.js.map +1 -1
  34. package/dist/core/tasks/output.d.ts +9 -1
  35. package/dist/core/tasks/output.d.ts.map +1 -1
  36. package/dist/core/tasks/output.js +23 -10
  37. package/dist/core/tasks/output.js.map +1 -1
  38. package/dist/core/tasks/presentation.d.ts +1 -1
  39. package/dist/core/tasks/presentation.d.ts.map +1 -1
  40. package/dist/core/tasks/presentation.js +6 -4
  41. package/dist/core/tasks/presentation.js.map +1 -1
  42. package/dist/core/tasks/record.d.ts +41 -29
  43. package/dist/core/tasks/record.d.ts.map +1 -1
  44. package/dist/core/tasks/record.js +82 -37
  45. package/dist/core/tasks/record.js.map +1 -1
  46. package/dist/core/tasks/reminder.js +2 -2
  47. package/dist/core/tasks/reminder.js.map +1 -1
  48. package/dist/core/tasks/runtime.d.ts +17 -14
  49. package/dist/core/tasks/runtime.d.ts.map +1 -1
  50. package/dist/core/tasks/runtime.js +68 -116
  51. package/dist/core/tasks/runtime.js.map +1 -1
  52. package/dist/core/tasks/scheduler.d.ts +3 -1
  53. package/dist/core/tasks/scheduler.d.ts.map +1 -1
  54. package/dist/core/tasks/scheduler.js +16 -12
  55. package/dist/core/tasks/scheduler.js.map +1 -1
  56. package/dist/core/tasks/session.d.ts +24 -3
  57. package/dist/core/tasks/session.d.ts.map +1 -1
  58. package/dist/core/tasks/session.js +73 -9
  59. package/dist/core/tasks/session.js.map +1 -1
  60. package/dist/core/tasks/store.d.ts +17 -4
  61. package/dist/core/tasks/store.d.ts.map +1 -1
  62. package/dist/core/tasks/store.js +45 -48
  63. package/dist/core/tasks/store.js.map +1 -1
  64. package/dist/core/tasks/types.d.ts +72 -29
  65. package/dist/core/tasks/types.d.ts.map +1 -1
  66. package/dist/core/tasks/types.js +7 -0
  67. package/dist/core/tasks/types.js.map +1 -1
  68. package/dist/core/tasks/wait.d.ts +19 -0
  69. package/dist/core/tasks/wait.d.ts.map +1 -0
  70. package/dist/core/tasks/wait.js +45 -0
  71. package/dist/core/tasks/wait.js.map +1 -0
  72. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  73. package/dist/core/tools/shell-execution.js +2 -1
  74. package/dist/core/tools/shell-execution.js.map +1 -1
  75. package/dist/core/tools/shell-tool.d.ts.map +1 -1
  76. package/dist/core/tools/shell-tool.js +20 -13
  77. package/dist/core/tools/shell-tool.js.map +1 -1
  78. package/dist/extensions/agent/activity-lines.d.ts +10 -0
  79. package/dist/extensions/agent/activity-lines.d.ts.map +1 -0
  80. package/dist/extensions/agent/activity-lines.js +76 -0
  81. package/dist/extensions/agent/activity-lines.js.map +1 -0
  82. package/dist/extensions/agent/activity.d.ts +25 -4
  83. package/dist/extensions/agent/activity.d.ts.map +1 -1
  84. package/dist/extensions/agent/activity.js +76 -21
  85. package/dist/extensions/agent/activity.js.map +1 -1
  86. package/dist/extensions/agent/artifacts.d.ts +15 -0
  87. package/dist/extensions/agent/artifacts.d.ts.map +1 -0
  88. package/dist/extensions/agent/artifacts.js +44 -0
  89. package/dist/extensions/agent/artifacts.js.map +1 -0
  90. package/dist/extensions/agent/progress.d.ts +30 -4
  91. package/dist/extensions/agent/progress.d.ts.map +1 -1
  92. package/dist/extensions/agent/progress.js +84 -11
  93. package/dist/extensions/agent/progress.js.map +1 -1
  94. package/dist/extensions/agent/render.d.ts.map +1 -1
  95. package/dist/extensions/agent/render.js +8 -24
  96. package/dist/extensions/agent/render.js.map +1 -1
  97. package/dist/extensions/agent/report.d.ts +11 -3
  98. package/dist/extensions/agent/report.d.ts.map +1 -1
  99. package/dist/extensions/agent/report.js +32 -7
  100. package/dist/extensions/agent/report.js.map +1 -1
  101. package/dist/extensions/agent/tool.d.ts.map +1 -1
  102. package/dist/extensions/agent/tool.js +20 -5
  103. package/dist/extensions/agent/tool.js.map +1 -1
  104. package/dist/extensions/agent/types.d.ts +2 -0
  105. package/dist/extensions/agent/types.d.ts.map +1 -1
  106. package/dist/extensions/agent/types.js.map +1 -1
  107. package/dist/extensions/agent/worker.d.ts +7 -0
  108. package/dist/extensions/agent/worker.d.ts.map +1 -1
  109. package/dist/extensions/agent/worker.js +9 -3
  110. package/dist/extensions/agent/worker.js.map +1 -1
  111. package/dist/extensions/search/index.d.ts.map +1 -1
  112. package/dist/extensions/search/index.js +6 -7
  113. package/dist/extensions/search/index.js.map +1 -1
  114. package/dist/extensions/tasks/tool/actions.d.ts.map +1 -1
  115. package/dist/extensions/tasks/tool/actions.js +15 -11
  116. package/dist/extensions/tasks/tool/actions.js.map +1 -1
  117. package/dist/extensions/tasks/tool/schema.d.ts +1 -1
  118. package/dist/extensions/tasks/tool/schema.d.ts.map +1 -1
  119. package/dist/extensions/tasks/tool/schema.js +5 -5
  120. package/dist/extensions/tasks/tool/schema.js.map +1 -1
  121. package/dist/extensions/tasks/tool/types.d.ts +2 -0
  122. package/dist/extensions/tasks/tool/types.d.ts.map +1 -1
  123. package/dist/extensions/tasks/tool/types.js.map +1 -1
  124. package/dist/extensions/tasks/tool.d.ts.map +1 -1
  125. package/dist/extensions/tasks/tool.js +3 -2
  126. package/dist/extensions/tasks/tool.js.map +1 -1
  127. package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
  128. package/dist/extensions/tasks/ui/completion-render.js +2 -2
  129. package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
  130. package/dist/extensions/tasks/ui/footer.d.ts +37 -0
  131. package/dist/extensions/tasks/ui/footer.d.ts.map +1 -0
  132. package/dist/extensions/tasks/ui/footer.js +129 -0
  133. package/dist/extensions/tasks/ui/footer.js.map +1 -0
  134. package/dist/extensions/tasks/ui/frame.d.ts +36 -0
  135. package/dist/extensions/tasks/ui/frame.d.ts.map +1 -0
  136. package/dist/extensions/tasks/ui/frame.js +33 -0
  137. package/dist/extensions/tasks/ui/frame.js.map +1 -0
  138. package/dist/extensions/tasks/ui/help.d.ts +6 -0
  139. package/dist/extensions/tasks/ui/help.d.ts.map +1 -0
  140. package/dist/extensions/tasks/ui/help.js +53 -0
  141. package/dist/extensions/tasks/ui/help.js.map +1 -0
  142. package/dist/extensions/tasks/ui/inspector.d.ts +4 -3
  143. package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
  144. package/dist/extensions/tasks/ui/inspector.js +25 -6
  145. package/dist/extensions/tasks/ui/inspector.js.map +1 -1
  146. package/dist/extensions/tasks/ui/layout.d.ts +15 -18
  147. package/dist/extensions/tasks/ui/layout.d.ts.map +1 -1
  148. package/dist/extensions/tasks/ui/layout.js +162 -255
  149. package/dist/extensions/tasks/ui/layout.js.map +1 -1
  150. package/dist/extensions/tasks/ui/list.d.ts +3 -1
  151. package/dist/extensions/tasks/ui/list.d.ts.map +1 -1
  152. package/dist/extensions/tasks/ui/list.js +19 -14
  153. package/dist/extensions/tasks/ui/list.js.map +1 -1
  154. package/dist/extensions/tasks/ui/manager.d.ts +17 -5
  155. package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
  156. package/dist/extensions/tasks/ui/manager.js +147 -90
  157. package/dist/extensions/tasks/ui/manager.js.map +1 -1
  158. package/dist/extensions/tasks/ui/model.d.ts +32 -5
  159. package/dist/extensions/tasks/ui/model.d.ts.map +1 -1
  160. package/dist/extensions/tasks/ui/model.js +7 -7
  161. package/dist/extensions/tasks/ui/model.js.map +1 -1
  162. package/dist/extensions/tasks/ui/panes.d.ts +40 -0
  163. package/dist/extensions/tasks/ui/panes.d.ts.map +1 -0
  164. package/dist/extensions/tasks/ui/panes.js +144 -0
  165. package/dist/extensions/tasks/ui/panes.js.map +1 -0
  166. package/dist/extensions/tasks/ui/render.d.ts.map +1 -1
  167. package/dist/extensions/tasks/ui/render.js +11 -7
  168. package/dist/extensions/tasks/ui/render.js.map +1 -1
  169. package/dist/extensions/tasks/ui/viewport.d.ts +12 -4
  170. package/dist/extensions/tasks/ui/viewport.d.ts.map +1 -1
  171. package/dist/extensions/tasks/ui/viewport.js +23 -7
  172. package/dist/extensions/tasks/ui/viewport.js.map +1 -1
  173. package/dist/extensions/tasks/ui/views.d.ts +12 -6
  174. package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
  175. package/dist/extensions/tasks/ui/views.js +39 -32
  176. package/dist/extensions/tasks/ui/views.js.map +1 -1
  177. package/dist/modes/interactive/components/session-selector.d.ts +11 -1
  178. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  179. package/dist/modes/interactive/components/session-selector.js +43 -17
  180. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  181. package/dist/modes/print-mode.d.ts.map +1 -1
  182. package/dist/modes/print-mode.js +37 -2
  183. package/dist/modes/print-mode.js.map +1 -1
  184. package/dist/modes/rpc/rpc-client.d.ts +11 -0
  185. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  186. package/dist/modes/rpc/rpc-client.js +48 -0
  187. package/dist/modes/rpc/rpc-client.js.map +1 -1
  188. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  189. package/dist/modes/rpc/rpc-mode.js +1 -0
  190. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  191. package/dist/modes/rpc/rpc-types.d.ts +2 -0
  192. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  193. package/dist/modes/rpc/rpc-types.js.map +1 -1
  194. package/docs/bundled/extensions/agent.md +39 -7
  195. package/docs/bundled/tasks.md +25 -21
  196. package/docs/extensions.md +14 -10
  197. package/docs/json.md +3 -0
  198. package/docs/rpc.md +14 -0
  199. package/docs/sdk.md +11 -1
  200. package/docs/session-format.md +10 -4
  201. package/docs/sessions.md +1 -1
  202. package/docs/usage.md +2 -0
  203. package/npm-shrinkwrap.json +2 -2
  204. package/package.json +1 -1
@@ -1 +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 { isStoppable, type PanelFocus, type PanelMode, type TaskSelection, type TasksTab } from \"./model.ts\";\nimport { modeName, statusName, statusView } from \"./status.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: PanelFocus;\n\tmode: PanelMode;\n\t/** Renders the search input line; shown only in search mode. */\n\tsearchLine: (width: number) => string;\n\tfeedback?: string;\n\t/** Whether the host would move this task to the background now. */\n\tcanDetach: (id: string) => boolean;\n}\nconst pad = (text: string, width: number) => truncateToWidth(text, Math.max(1, width), \"…\", true);\n/** Visible width of \"Output Details\". */\nconst TABS_WIDTH = 15;\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, mode } = 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\t// One row per task, less the group headings.\n\tresult.listPageSize = Math.max(1, bodyHeight - 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 (mode.kind === \"search\") 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\t// One header row in every layout: the selected task's source and status, with the tabs on the right.\n\tconst tabsX = rightWidth - 2 - TABS_WIDTH;\n\tconst summary = task\n\t\t? [\n\t\t\t\ttheme.fg(\"muted\", cleanTaskText(task.label)),\n\t\t\t\ttheme.fg(statusView(task.status).color, statusName(task.status)),\n\t\t\t\ttheme.fg(\"muted\", runtimeLabel(task)),\n\t\t\t].join(theme.fg(\"dim\", \" · \"))\n\t\t: \"\";\n\tconst shownSummary = truncateToWidth(summary, Math.max(0, tabsX - 1), \"…\");\n\tconst right = [\n\t\t`${shownSummary}${\" \".repeat(tabsX - visibleWidth(shownSummary))}${tabLabel(\"output\", \"Output\")} ${tabLabel(\"info\", \"Details\")}`,\n\t];\n\tif (wide || focus === \"inspector\")\n\t\thits.push(\n\t\t\t{ x: rightX + 1 + tabsX, y: 1, width: 6, tab: \"output\" },\n\t\t\t{ x: rightX + 9 + tabsX, y: 1, width: 7, tab: \"info\" },\n\t\t);\n\tconst content: string[] = [];\n\tlet reading = \"\";\n\tif (task) {\n\t\t// Without the list beside it, the inspector names the task it shows.\n\t\tif (!wide) content.push(theme.fg(\"text\", cleanTaskText(firstCommandLine(task.title))));\n\t\tconst position = inspector.position;\n\t\tconst read = position.read;\n\t\tconst terminal = isTaskTerminal(task.status);\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? inspector.details(`${statusName(task.status)} · ${modeName(task.mode)} · ${runtimeLabel(task)}`)\n\t\t\t\t: inspector.output(rightWidth - 2);\n\t\tcontent.push(...position[tab].layout(source, rightWidth - 2, bodyHeight - content.length));\n\t\tif (tab === \"output\") {\n\t\t\t// Only a log holds a browsed snapshot; other output is always the current result.\n\t\t\tconst settled = terminal && task.outputPath === undefined;\n\t\t\treading =\n\t\t\t\tposition.output.follow || settled\n\t\t\t\t\t? terminal\n\t\t\t\t\t\t? \"Finished\"\n\t\t\t\t\t\t: \"Live\"\n\t\t\t\t\t: terminal\n\t\t\t\t\t\t? `Finished · ${hint(\"app.tasks.follow\")} load final output`\n\t\t\t\t\t\t: `Browsing · ${hint(\"app.tasks.follow\")} follow output`;\n\t\t\tif (!position.output.follow && !settled && (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 (task.outputPath !== undefined && 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 (mode.kind === \"help\") {\n\t\thits.length = 0;\n\t\tpanels = pane(helpLines(mode.viewport, hint, theme, width, height), width, false);\n\t\taddHint(\"tui.select.up\", `/ ${hint(\"tui.select.down\")} scroll`);\n\t\taddHint(\"tui.select.cancel\", \"back\", { cancel: true });\n\t} else if (mode.kind === \"confirmStop\") {\n\t\t// The question borrows only the footer row, so the task stays in view while confirming.\n\t\thits.length = 0;\n\t\tconst target = selection.all.find((task) => task.id === mode.taskId);\n\t\tconst source = cleanTaskText(target?.label ?? \"task\");\n\t\tconst confirm = `${hint(\"app.tasks.confirmStop\")} stop`;\n\t\tconst cancel = `${hint(\"tui.select.cancel\")} cancel`;\n\t\tconst actions = `${confirm} · ${cancel}`;\n\t\tconst room = width - visibleWidth(`Stop ${source} \"\"? ${actions}`);\n\t\tconst title = cleanTaskText(firstCommandLine(target?.title ?? mode.taskId));\n\t\tconst question = room >= 4 ? `Stop ${source} \"${truncateToWidth(title, room, \"…\")}\"? ` : `Stop ${source}? `;\n\t\tfooter = question + actions;\n\t\tconst x = visibleWidth(question);\n\t\thits.push(\n\t\t\t{ x, y: height - 1, width: visibleWidth(confirm), key: \"app.tasks.confirmStop\" },\n\t\t\t{ x: x + visibleWidth(confirm) + 3, y: height - 1, width: visibleWidth(cancel), cancel: true },\n\t\t);\n\t} else if (mode.kind === \"search\") {\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\tif (focus === \"list\") addHint(\"tui.select.confirm\", \"open\", { tab });\n\t\telse addHint(\"app.tasks.nextFocus\", \"tasks\", { key: \"app.tasks.nextFocus\" });\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 && isStoppable(task)) addHint(\"app.tasks.kill\", \"stop\", { key: \"app.tasks.kill\" });\n\t\tif (task && options.canDetach(task.id))\n\t\t\taddHint(\"app.tasks.detachSelected\", \"background\", { key: \"app.tasks.detachSelected\" });\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(mode.kind === \"confirmStop\" ? \"warning\" : \"dim\", pad(footer, width))];\n\treturn result;\n}\n\n/** Controls grouped by purpose; actions sharing a key, such as list and inspector paging, share a row. */\nfunction helpLines(\n\thelp: TaskViewport,\n\thint: (key: Keybinding) => string,\n\ttheme: Theme,\n\twidth: number,\n\theight: number,\n): string[] {\n\tconst keys = (...bindings: Keybinding[]) => [...new Set(bindings.map(hint).filter(Boolean))].join(\" / \");\n\tconst listPage = keys(\"tui.select.pageUp\", \"tui.select.pageDown\");\n\tconst inspectorPage = keys(\"tui.editor.pageUp\", \"tui.editor.pageDown\");\n\tconst paging: Array<[string, string]> =\n\t\tlistPage === inspectorPage\n\t\t\t? [[listPage, \"Page the list or inspector\"]]\n\t\t\t: [\n\t\t\t\t\t[listPage, \"Page the list\"],\n\t\t\t\t\t[inspectorPage, \"Page the inspector\"],\n\t\t\t\t];\n\tconst sections: Array<[string, Array<[string, string]>]> = [\n\t\t[\n\t\t\t\"Navigate\",\n\t\t\t[\n\t\t\t\t[keys(\"tui.select.up\", \"tui.select.down\"), \"Select a task, or scroll the inspector\"],\n\t\t\t\t...paging,\n\t\t\t\t[keys(\"app.tasks.top\", \"app.tasks.bottom\"), \"Top or bottom\"],\n\t\t\t\t[hint(\"tui.select.confirm\"), \"Open the selected task\"],\n\t\t\t\t[keys(\"app.tasks.nextFocus\", \"app.tasks.previousFocus\"), \"Switch between list and inspector\"],\n\t\t\t],\n\t\t],\n\t\t[\n\t\t\t\"View\",\n\t\t\t[\n\t\t\t\t[keys(\"app.tasks.previousTab\", \"app.tasks.nextTab\"), \"Output or Details, in the inspector\"],\n\t\t\t\t[hint(\"app.tasks.follow\"), \"Follow the latest output, or load the final output\"],\n\t\t\t\t[hint(\"app.tasks.search\"), \"Find a task; Enter locates it, Esc restores the selection\"],\n\t\t\t],\n\t\t],\n\t\t[\n\t\t\t\"Act\",\n\t\t\t[\n\t\t\t\t[hint(\"app.tasks.kill\"), `Stop the selected task; ${hint(\"app.tasks.confirmStop\")} confirms`],\n\t\t\t\t[hint(\"app.tasks.detachSelected\"), \"Move the selected foreground task to the background\"],\n\t\t\t\t[hint(\"app.tasks.detach\"), \"Move every foreground execution to the background\"],\n\t\t\t\t[hint(\"tui.select.cancel\"), \"Close search, help or confirmation; otherwise the panel\"],\n\t\t\t],\n\t\t],\n\t];\n\tconst keyWidth = Math.max(...sections.flatMap(([, rows]) => rows.map(([key]) => visibleWidth(key)))) + 2;\n\tconst rows = sections.flatMap(([title, entries], index) => [\n\t\t...(index ? [\"\"] : []),\n\t\ttheme.fg(\"accent\", title),\n\t\t...entries.map(([key, label]) => ` ${key}${\" \".repeat(keyWidth - visibleWidth(key))}${label}`),\n\t]);\n\tconst body = [theme.fg(\"text\", \"Task controls\"), ...help.layout(rows, width - 2, height - 5), \"\"];\n\twhile (body.length < height - 3) body.push(\"\");\n\treturn body;\n}\n"]}
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/layout.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Screen layout. This is the only place that knows widths and row positions: it returns the\n * rendered lines together with the clickable cells and the pane regions the manager routes\n * wheel and focus gestures by, so a resize cannot separate geometry from targets.\n */\nimport { visibleWidth, wrapTextWithAnsi } from \"@earendil-works/pi-tui\";\nimport type { Keybinding, KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { keyLabel } from \"../../../modes/interactive/components/keybinding-hints.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport {\n\tbrowseFooter,\n\tconfirmStopFooter,\n\ttype Feedback,\n\ttype Footer,\n\ttype FooterEnv,\n\thelpFooter,\n\tsearchFooter,\n} from \"./footer.ts\";\nimport { fitCell, framePane, type Rect } from \"./frame.ts\";\nimport { helpRows } from \"./help.ts\";\nimport type { TaskInspector } from \"./inspector.ts\";\nimport type { TaskList } from \"./list.ts\";\nimport type { PanelFocus, PanelMode, TaskHit, TaskSelection } from \"./model.ts\";\nimport { isStoppable } from \"./model.ts\";\nimport { type PaneRender, renderInspectorPane, renderListPane } from \"./panes.ts\";\nimport { cleanTaskText, firstCommandLine } from \"./text.ts\";\n\n/** A terminal at least this wide shows the list beside the inspector. */\nconst SPLIT_MIN_WIDTH = 100;\n/** The minimum supported terminal; below it a resize notice covers the screen. */\nconst MIN_WIDTH = 60;\nconst MIN_HEIGHT = 14;\n\n/** A pane the pointer can act on: wheel scrolls it and a click on it focuses it. */\nexport interface PaneRegion extends Rect {\n\tpane: PanelFocus | \"help\";\n}\n\nexport interface TasksLayout {\n\tlines: string[];\n\thits: TaskHit[];\n\tregions: PaneRegion[];\n\t/** Both panes are visible; otherwise one pane at a time fills the width. */\n\tsplit: boolean;\n\tlistPageSize: number;\n\t/** The terminal is below the supported size; only a full-screen resize notice is shown. */\n\ttooSmall?: boolean;\n}\n\nexport interface 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: PanelFocus;\n\tmode: PanelMode;\n\tfeedback?: Feedback;\n\t/** Whether the host would move this task to the background now. */\n\tcanDetach: (id: string) => boolean;\n}\n\n/** The list takes 40% of a split terminal, between 34 and 60 columns. */\nexport function listWidthFor(width: number): number {\n\treturn Math.min(60, Math.max(34, Math.round(width * 0.4)));\n}\n\ninterface PaneRects {\n\tsplit: boolean;\n\tlist: Rect;\n\tinspector: Rect;\n}\n\n/** Pane rectangles above the single footer row; without room for two, both panes share the full width. */\nfunction paneRects(width: number, height: number): PaneRects {\n\tconst rows = height - 1;\n\tif (width < SPLIT_MIN_WIDTH) {\n\t\tconst full = { x: 0, y: 0, width, height: rows };\n\t\treturn { split: false, list: full, inspector: full };\n\t}\n\tconst listWidth = listWidthFor(width);\n\treturn {\n\t\tsplit: true,\n\t\tlist: { x: 0, y: 0, width: listWidth, height: rows },\n\t\tinspector: { x: listWidth + 1, y: 0, width: width - listWidth - 1, height: rows },\n\t};\n}\n\nexport function renderTasksLayout(options: LayoutOptions): TasksLayout {\n\tconst { width, height, theme, mode } = options;\n\tif (width < 1 || height < 1) return { lines: [], hits: [], regions: [], split: false, listPageSize: 1 };\n\tconst hint = (key: Keybinding) => keyLabel(key, { keybindings: options.keybindings });\n\tif (width < MIN_WIDTH || height < MIN_HEIGHT) return renderTooSmall(options, hint);\n\tconst rects = paneRects(width, height);\n\tconst env: FooterEnv = { width, y: height - 1, theme, hint, feedback: options.feedback };\n\tlet body: PaneRender & { regions: PaneRegion[]; pageSize?: number };\n\tlet footer: Footer;\n\tswitch (mode.kind) {\n\t\tcase \"help\": {\n\t\t\tbody = renderHelpPane(options, hint, { x: 0, y: 0, width, height: height - 1 });\n\t\t\tfooter = helpFooter(env);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"search\": {\n\t\t\tbody = renderPanes(options, hint, rects);\n\t\t\tfooter = searchFooter(env);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"confirmStop\": {\n\t\t\tbody = renderPanes(options, hint, rects);\n\t\t\tconst target = options.selection.all.find((task) => task.id === mode.taskId);\n\t\t\tfooter = confirmStopFooter(env, {\n\t\t\t\tsource: cleanTaskText(target?.label ?? \"task\"),\n\t\t\t\ttitle: cleanTaskText(firstCommandLine(target?.title ?? mode.taskId)),\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\t\tcase \"browse\": {\n\t\t\tbody = renderPanes(options, hint, rects);\n\t\t\tconst task = options.inspector.task;\n\t\t\tfooter = browseFooter(env, {\n\t\t\t\tfocus: options.focus,\n\t\t\t\tsplit: rects.split,\n\t\t\t\tstoppable: !!task && isStoppable(task),\n\t\t\t\tdetachable: !!task && options.canDetach(task.id),\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn {\n\t\tlines: [...body.lines, footer.line],\n\t\thits: [...body.hits, ...footer.hits],\n\t\tregions: body.regions,\n\t\tsplit: rects.split,\n\t\tlistPageSize: body.pageSize ?? Math.max(1, rects.list.height - 4),\n\t};\n}\n\n/**\n * Browse, search and confirmation share the two-pane frame; the mode decides which panes\n * answer to the pointer, so each mode exposes only its own targets.\n */\nfunction renderPanes(\n\toptions: LayoutOptions,\n\thint: (key: Keybinding) => string,\n\trects: PaneRects,\n): PaneRender & { regions: PaneRegion[]; pageSize: number } {\n\tconst { theme, selection, inspector, list, focus, mode } = options;\n\tconst showList = rects.split || focus === \"list\";\n\tconst showInspector = rects.split || focus === \"inspector\";\n\tconst browsing = mode.kind === \"browse\";\n\tconst searching = mode.kind === \"search\";\n\tconst listPane = showList\n\t\t? renderListPane({ theme, selection, list }, rects.list, {\n\t\t\t\tactive: rects.split && focus === \"list\",\n\t\t\t\tinteractive: browsing || searching,\n\t\t\t\tsearchRow: mode.kind === \"search\" ? mode.input.render(rects.list.width - 2).join(\"\") : undefined,\n\t\t\t\tstopTargetId: mode.kind === \"confirmStop\" ? mode.taskId : undefined,\n\t\t\t})\n\t\t: undefined;\n\tconst inspectorPane = showInspector\n\t\t? renderInspectorPane({ theme, selection, inspector, hint }, rects.inspector, {\n\t\t\t\tactive: rects.split && focus === \"inspector\",\n\t\t\t\tinteractive: browsing,\n\t\t\t})\n\t\t: undefined;\n\tconst regions: PaneRegion[] = [];\n\tif (listPane && (browsing || searching)) regions.push({ pane: \"list\", ...rects.list });\n\tif (inspectorPane && browsing) regions.push({ pane: \"inspector\", ...rects.inspector });\n\tconst lines =\n\t\tlistPane && inspectorPane\n\t\t\t? listPane.lines.map((line, i) => `${line} ${inspectorPane.lines[i]}`)\n\t\t\t: (listPane ?? inspectorPane)!.lines;\n\treturn {\n\t\tlines,\n\t\thits: [...(listPane?.hits ?? []), ...(inspectorPane?.hits ?? [])],\n\t\tregions,\n\t\tpageSize: listPane?.pageSize ?? Math.max(1, rects.list.height - 4),\n\t};\n}\n\nfunction renderHelpPane(\n\toptions: LayoutOptions,\n\thint: (key: Keybinding) => string,\n\trect: Rect,\n): PaneRender & { regions: PaneRegion[] } {\n\tconst { theme, mode } = options;\n\tif (mode.kind !== \"help\") throw new Error(\"help pane requires help mode\");\n\tconst inner = rect.width - 2;\n\tconst rows = mode.viewport.layout(helpRows(hint, theme), inner, rect.height - 2);\n\tconst frame = framePane({\n\t\twidth: rect.width,\n\t\ttheme,\n\t\taccent: false,\n\t\ttitle: theme.fg(\"text\", \"Task controls\"),\n\t\tstatus: mode.viewport.overflows ? theme.fg(\"muted\", mode.viewport.range) : undefined,\n\t\trows: Array.from({ length: rect.height - 2 }, (_, i) => rows[i] ?? \"\"),\n\t});\n\treturn { lines: frame.lines, hits: [], regions: [{ pane: \"help\", ...rect }] };\n}\n\n/**\n * The panel is modal: a floating notice would leave the transcript visible yet unscrollable,\n * so the notice owns every row as a centered dialog. Only a truly tiny terminal, where even\n * the dialog does not fit, gets bare covering lines.\n */\nfunction renderTooSmall(options: LayoutOptions, hint: (key: Keybinding) => string): TasksLayout {\n\tconst { width, height, theme } = options;\n\tconst result: TasksLayout = { lines: [], hits: [], regions: [], split: false, listPageSize: 1, tooSmall: true };\n\tconst message = \"Terminal too small for /tasks. Enlarge the window to continue.\";\n\tconst close = `${hint(\"tui.select.cancel\")} close`;\n\tconst boxWidth = Math.min(width, 46);\n\tconst inner = boxWidth - 2;\n\tconst wrapped = wrapTextWithAnsi(message, inner).map((line) => theme.fg(\"warning\", line));\n\tconst spacious = [theme.fg(\"text\", \"Tasks\"), \"\", ...wrapped, \"\", theme.fg(\"dim\", close)];\n\tconst tight = [theme.fg(\"text\", \"Tasks\"), ...wrapped, theme.fg(\"dim\", close)];\n\tconst body = height >= spacious.length + 2 ? spacious : tight;\n\tif (inner >= 16 && height >= body.length + 2) {\n\t\tconst box = framePane({ width: boxWidth, theme, accent: false, rows: body }).lines;\n\t\tconst left = Math.floor((width - boxWidth) / 2);\n\t\tconst top = Math.max(0, Math.floor((height - box.length) / 2));\n\t\tconst blank = \" \".repeat(width);\n\t\tresult.lines = [\n\t\t\t...Array.from({ length: top }, () => blank),\n\t\t\t...box.map((line) => \" \".repeat(left) + line + \" \".repeat(width - left - boxWidth)),\n\t\t\t...Array.from({ length: height - top - box.length }, () => blank),\n\t\t];\n\t\tresult.hits.push({ x: left + 1, y: top + body.length, width: visibleWidth(close), action: { kind: \"back\" } });\n\t} else {\n\t\tresult.lines = [\"Tasks\", message, close].slice(0, height).map((line) => fitCell(line, width));\n\t\twhile (result.lines.length < height) result.lines.push(\" \".repeat(width));\n\t}\n\treturn result;\n}\n"]}
@@ -14,7 +14,9 @@ export declare class TaskList {
14
14
  private reveal;
15
15
  showSelection(): void;
16
16
  scroll(delta: number): void;
17
- render(selection: TaskSelection, theme: Theme, width: number, height: number): ListRow[];
17
+ /** `stopTargetId` marks the row a pending stop question is about. */
18
+ render(selection: TaskSelection, theme: Theme, width: number, height: number, stopTargetId?: string): ListRow[];
19
+ /** The visible task span, such as `1-12 of 40`; empty while every row fits. */
18
20
  get range(): string;
19
21
  }
20
22
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/list.ts"],"names":[],"mappings":"AAGA,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;AAgBD,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;IAgExF,IAAI,KAAK,IAAI,MAAM,CAOlB;CACD"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/list.ts"],"names":[],"mappings":"AAGA,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;AAmBD,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,qEAAqE;IACrE,MAAM,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE;IAgE/G,+EAA+E;IAC/E,IAAI,KAAK,IAAI,MAAM,CAOlB;CACD"}
@@ -5,15 +5,18 @@ import { statusName, statusView } from "./status.js";
5
5
  import { cleanTaskText, firstCommandLine } from "./text.js";
6
6
  /** Spinner, ✓ and the error × are unique; every other status also needs its name. */
7
7
  const SELF_EVIDENT = new Set(["running", "completed", "failed"]);
8
- /** Right-aligned row metadata: the status name when the glyph is ambiguous, a disambiguating ID, and runtime. */
9
- function rowMeta(task, duplicate) {
10
- return [
11
- SELF_EVIDENT.has(task.status) ? "" : statusName(task.status),
12
- duplicate ? task.id.slice(-8) : "",
13
- runtimeLabel(task),
14
- ]
15
- .filter(Boolean)
16
- .join(" · ");
8
+ /**
9
+ * Right-aligned row metadata: a pending stop question, the status name when the glyph is
10
+ * ambiguous, a disambiguating ID, and runtime.
11
+ */
12
+ function rowMeta(task, duplicate, stopTarget, theme) {
13
+ const parts = [
14
+ stopTarget ? theme.fg("warning", "stop?") : "",
15
+ SELF_EVIDENT.has(task.status) ? "" : theme.fg("muted", statusName(task.status)),
16
+ duplicate ? theme.fg("muted", task.id.slice(-8)) : "",
17
+ theme.fg("muted", runtimeLabel(task)),
18
+ ];
19
+ return parts.filter(Boolean).join(theme.fg("muted", " · "));
17
20
  }
18
21
  /** Keeps list scrolling independent of selection, with an identity anchor on reordering. */
19
22
  export class TaskList {
@@ -30,7 +33,8 @@ export class TaskList {
30
33
  scroll(delta) {
31
34
  this.start = Math.max(0, Math.min(Math.max(0, this.rows.length - this.height), this.start + delta));
32
35
  }
33
- render(selection, theme, width, height) {
36
+ /** `stopTargetId` marks the row a pending stop question is about. */
37
+ render(selection, theme, width, height, stopTargetId) {
34
38
  const rows = [];
35
39
  const labels = selection.rows.map((task) => cleanTaskText(task.label));
36
40
  const labelWidth = Math.max(0, ...labels.map((label) => visibleWidth(label)));
@@ -48,13 +52,13 @@ export class TaskList {
48
52
  const marker = statusView(task.status, { now: Date.now() });
49
53
  const label = labels[index];
50
54
  const duplicate = titles.some((title, other) => other !== index && title === titles[index]);
51
- const meta = rowMeta(task, duplicate);
55
+ const meta = rowMeta(task, duplicate, task.id === stopTargetId, theme);
52
56
  // Labels form an aligned source column so titles start together.
53
57
  const source = labelWidth ? `${label}${" ".repeat(labelWidth - visibleWidth(label))} ` : "";
54
58
  const head = visibleWidth(marker.glyph) + 1 + visibleWidth(source);
55
59
  const title = truncateToWidth(titles[index], Math.max(1, width - head - visibleWidth(meta) - 1), "…");
56
60
  const gap = Math.max(1, width - head - visibleWidth(title) - visibleWidth(meta));
57
- const text = `${theme.fg(marker.color, marker.glyph)} ${theme.fg("dim", source)}${theme.fg("text", title)}${" ".repeat(gap)}${theme.fg("muted", meta)}`;
61
+ const text = `${theme.fg(marker.color, marker.glyph)} ${theme.fg("dim", source)}${theme.fg("text", title)}${" ".repeat(gap)}${meta}`;
58
62
  const padded = truncateToWidth(text, width, "…", true);
59
63
  // The system theme has no panel backgrounds until the terminal reports its colors.
60
64
  rows.push({
@@ -67,7 +71,7 @@ export class TaskList {
67
71
  });
68
72
  }
69
73
  if (!rows.length)
70
- rows.push({ text: theme.fg("muted", selection.query ? "No matching tasks." : "No retained tasks.") });
74
+ rows.push({ text: theme.fg("muted", selection.all.length ? "No matching tasks." : "No retained tasks.") });
71
75
  const sameSelection = this.selectedId === selection.state.selectedId;
72
76
  const selectedWasVisible = sameSelection &&
73
77
  this.selectedLine >= this.start &&
@@ -97,6 +101,7 @@ export class TaskList {
97
101
  this.reveal = false;
98
102
  return rows.slice(this.start, this.start + height);
99
103
  }
104
+ /** The visible task span, such as `1-12 of 40`; empty while every row fits. */
100
105
  get range() {
101
106
  if (this.rows.length <= this.height)
102
107
  return "";
@@ -104,7 +109,7 @@ export class TaskList {
104
109
  const visible = this.rows
105
110
  .slice(this.start, this.start + this.height)
106
111
  .flatMap((row) => (row.taskId ? [row.taskId] : []));
107
- return `Tasks ${ids.indexOf(visible[0]) + 1}-${ids.indexOf(visible.at(-1)) + 1} of ${ids.length}`;
112
+ return `${ids.indexOf(visible[0]) + 1}-${ids.indexOf(visible.at(-1)) + 1} of ${ids.length}`;
108
113
  }
109
114
  }
110
115
  //# sourceMappingURL=list.js.map
@@ -1 +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, visibleWidth } from \"@earendil-works/pi-tui\";\nimport { runtimeLabel } from \"../../../core/tasks/format.ts\";\nimport { isTaskTerminal, type TaskSnapshot, type TaskStatus } from \"../../../core/tasks/types.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { TaskSelection } from \"./model.ts\";\nimport { statusName, statusView } from \"./status.ts\";\nimport { cleanTaskText, firstCommandLine } from \"./text.ts\";\n\ninterface ListRow {\n\ttext: string;\n\ttaskId?: string;\n}\n\n/** Spinner, ✓ and the error × are unique; every other status also needs its name. */\nconst SELF_EVIDENT = new Set<TaskStatus>([\"running\", \"completed\", \"failed\"]);\n\n/** Right-aligned row metadata: the status name when the glyph is ambiguous, a disambiguating ID, and runtime. */\nfunction rowMeta(task: TaskSnapshot, duplicate: boolean): string {\n\treturn [\n\t\tSELF_EVIDENT.has(task.status) ? \"\" : statusName(task.status),\n\t\tduplicate ? task.id.slice(-8) : \"\",\n\t\truntimeLabel(task),\n\t]\n\t\t.filter(Boolean)\n\t\t.join(\" · \");\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(task.label));\n\t\tconst labelWidth = Math.max(0, ...labels.map((label) => visibleWidth(label)));\n\t\tconst titles = selection.rows.map((task) => cleanTaskText(firstCommandLine(task.title)));\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 = statusView(task.status, { now: Date.now() });\n\t\t\tconst label = labels[index]!;\n\t\t\tconst duplicate = titles.some((title, other) => other !== index && title === titles[index]);\n\t\t\tconst meta = rowMeta(task, duplicate);\n\t\t\t// Labels form an aligned source column so titles start together.\n\t\t\tconst source = labelWidth ? `${label}${\" \".repeat(labelWidth - visibleWidth(label))} ` : \"\";\n\t\t\tconst head = visibleWidth(marker.glyph) + 1 + visibleWidth(source);\n\t\t\tconst title = truncateToWidth(titles[index]!, Math.max(1, width - head - visibleWidth(meta) - 1), \"…\");\n\t\t\tconst gap = Math.max(1, width - head - visibleWidth(title) - visibleWidth(meta));\n\t\t\tconst text = `${theme.fg(marker.color, marker.glyph)} ${theme.fg(\"dim\", source)}${theme.fg(\"text\", title)}${\" \".repeat(gap)}${theme.fg(\"muted\", meta)}`;\n\t\t\tconst padded = truncateToWidth(text, width, \"…\", true);\n\t\t\t// The system theme has no panel backgrounds until the terminal reports its colors.\n\t\t\trows.push({\n\t\t\t\ttext: !selected\n\t\t\t\t\t? padded\n\t\t\t\t\t: theme.getBgAnsi(\"selectedBg\") === \"\\x1b[49m\"\n\t\t\t\t\t\t? theme.style(stripTerminalSequences(padded), { inverse: true })\n\t\t\t\t\t\t: theme.bg(\"selectedBg\", padded),\n\t\t\t\ttaskId: task.id,\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 next = anchor ? rows.findIndex((row) => row.taskId === anchor) : -1;\n\t\t\tif (next >= 0) this.start = next;\n\t\t}\n\t\tif (selectedLine >= 0 && (!sameSelection || this.reveal || selectedWasVisible)) {\n\t\t\t// Revealing the first task of a group keeps its heading in view.\n\t\t\tconst top = rows[selectedLine - 1]?.taskId === undefined ? selectedLine - 1 : selectedLine;\n\t\t\tif (top < this.start) this.start = Math.max(0, top);\n\t\t\telse if (selectedLine >= this.start + height) this.start = selectedLine + 1 - 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 = 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
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/list.ts"],"names":[],"mappings":"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","sourcesContent":["import { stripTerminalSequences, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport { runtimeLabel } from \"../../../core/tasks/format.ts\";\nimport { isTaskTerminal, type TaskSnapshot, type TaskStatus } from \"../../../core/tasks/types.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { TaskSelection } from \"./model.ts\";\nimport { statusName, statusView } from \"./status.ts\";\nimport { cleanTaskText, firstCommandLine } from \"./text.ts\";\n\ninterface ListRow {\n\ttext: string;\n\ttaskId?: string;\n}\n\n/** Spinner, ✓ and the error × are unique; every other status also needs its name. */\nconst SELF_EVIDENT = new Set<TaskStatus>([\"running\", \"completed\", \"failed\"]);\n\n/**\n * Right-aligned row metadata: a pending stop question, the status name when the glyph is\n * ambiguous, a disambiguating ID, and runtime.\n */\nfunction rowMeta(task: TaskSnapshot, duplicate: boolean, stopTarget: boolean, theme: Theme): string {\n\tconst parts = [\n\t\tstopTarget ? theme.fg(\"warning\", \"stop?\") : \"\",\n\t\tSELF_EVIDENT.has(task.status) ? \"\" : theme.fg(\"muted\", statusName(task.status)),\n\t\tduplicate ? theme.fg(\"muted\", task.id.slice(-8)) : \"\",\n\t\ttheme.fg(\"muted\", runtimeLabel(task)),\n\t];\n\treturn parts.filter(Boolean).join(theme.fg(\"muted\", \" · \"));\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\t/** `stopTargetId` marks the row a pending stop question is about. */\n\trender(selection: TaskSelection, theme: Theme, width: number, height: number, stopTargetId?: string): ListRow[] {\n\t\tconst rows: ListRow[] = [];\n\t\tconst labels = selection.rows.map((task) => cleanTaskText(task.label));\n\t\tconst labelWidth = Math.max(0, ...labels.map((label) => visibleWidth(label)));\n\t\tconst titles = selection.rows.map((task) => cleanTaskText(firstCommandLine(task.title)));\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 = statusView(task.status, { now: Date.now() });\n\t\t\tconst label = labels[index]!;\n\t\t\tconst duplicate = titles.some((title, other) => other !== index && title === titles[index]);\n\t\t\tconst meta = rowMeta(task, duplicate, task.id === stopTargetId, theme);\n\t\t\t// Labels form an aligned source column so titles start together.\n\t\t\tconst source = labelWidth ? `${label}${\" \".repeat(labelWidth - visibleWidth(label))} ` : \"\";\n\t\t\tconst head = visibleWidth(marker.glyph) + 1 + visibleWidth(source);\n\t\t\tconst title = truncateToWidth(titles[index]!, Math.max(1, width - head - visibleWidth(meta) - 1), \"…\");\n\t\t\tconst gap = Math.max(1, width - head - visibleWidth(title) - visibleWidth(meta));\n\t\t\tconst text = `${theme.fg(marker.color, marker.glyph)} ${theme.fg(\"dim\", source)}${theme.fg(\"text\", title)}${\" \".repeat(gap)}${meta}`;\n\t\t\tconst padded = truncateToWidth(text, width, \"…\", true);\n\t\t\t// The system theme has no panel backgrounds until the terminal reports its colors.\n\t\t\trows.push({\n\t\t\t\ttext: !selected\n\t\t\t\t\t? padded\n\t\t\t\t\t: theme.getBgAnsi(\"selectedBg\") === \"\\x1b[49m\"\n\t\t\t\t\t\t? theme.style(stripTerminalSequences(padded), { inverse: true })\n\t\t\t\t\t\t: theme.bg(\"selectedBg\", padded),\n\t\t\t\ttaskId: task.id,\n\t\t\t});\n\t\t}\n\t\tif (!rows.length)\n\t\t\trows.push({ text: theme.fg(\"muted\", selection.all.length ? \"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 next = anchor ? rows.findIndex((row) => row.taskId === anchor) : -1;\n\t\t\tif (next >= 0) this.start = next;\n\t\t}\n\t\tif (selectedLine >= 0 && (!sameSelection || this.reveal || selectedWasVisible)) {\n\t\t\t// Revealing the first task of a group keeps its heading in view.\n\t\t\tconst top = rows[selectedLine - 1]?.taskId === undefined ? selectedLine - 1 : selectedLine;\n\t\t\tif (top < this.start) this.start = Math.max(0, top);\n\t\t\telse if (selectedLine >= this.start + height) this.start = selectedLine + 1 - 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\t/** The visible task span, such as `1-12 of 40`; empty while every row fits. */\n\tget range(): string {\n\t\tif (this.rows.length <= this.height) return \"\";\n\t\tconst ids = 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 `${ids.indexOf(visible[0]!) + 1}-${ids.indexOf(visible.at(-1)!) + 1} of ${ids.length}`;\n\t}\n}\n"]}
@@ -5,7 +5,7 @@ import type { KeybindingsManager } from "../../../core/keybindings.ts";
5
5
  import { type TasksContext } from "../../../core/tasks/types.ts";
6
6
  import type { Theme } from "../../../modes/interactive/theme/theme.ts";
7
7
  import { type TasksPanelState } from "./model.ts";
8
- export type TasksManagerHost = Pick<TasksContext, "list" | "read" | "kill" | "subscribe" | "retain" | "canDetach" | "detach">;
8
+ export type TasksManagerHost = Pick<TasksContext, "list" | "read" | "kill" | "subscribe" | "retain" | "canDetach" | "detach" | "presentOutput">;
9
9
  export interface TasksMenuOptions {
10
10
  tui: {
11
11
  requestRender(): void;
@@ -27,10 +27,10 @@ export declare class TasksMenu implements Component, Focusable {
27
27
  private readonly selection;
28
28
  private readonly inspector;
29
29
  private readonly list;
30
- private readonly search;
31
30
  private readonly unsubscribe;
32
31
  private readonly pollTimer;
33
32
  private animationTimer?;
33
+ private feedbackTimer?;
34
34
  private mode;
35
35
  private feedback?;
36
36
  private focus;
@@ -41,20 +41,32 @@ export declare class TasksMenu implements Component, Focusable {
41
41
  private width;
42
42
  private layout?;
43
43
  constructor(options: TasksMenuOptions);
44
+ /** The search text, owned by the search mode: browsing always sees every retained task. */
45
+ private get query();
46
+ private select;
44
47
  private sync;
45
48
  private queueTick;
46
49
  invalidate(): void;
47
- /** The one place the mode changes; the search input is focused exactly while searching. */
48
50
  private setMode;
49
- /** Unwinds exactly one transient layer; from plain browsing it closes the panel. */
50
- private cancel;
51
+ /** Reports an action that did not do what was asked; it clears on the next input or after a few seconds. */
52
+ private notify;
53
+ private clearFeedback;
54
+ /**
55
+ * Unwinds exactly one layer: search, help or a confirmation; then the inspector back to the
56
+ * list when the list is hidden; from plain browsing it closes the panel.
57
+ */
58
+ private escape;
51
59
  private close;
52
60
  private selectedChanged;
53
61
  private requestStop;
54
62
  private confirmStop;
63
+ private detachSelected;
55
64
  private startSearch;
56
65
  private finishSearch;
66
+ private open;
57
67
  private action;
68
+ /** Performs what a click on a rendered target asks for. */
69
+ private perform;
58
70
  private move;
59
71
  handleInput(data: string): void;
60
72
  private helpInput;
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/manager.ts"],"names":[],"mappings":"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"}