poly-weaver 0.11.3 → 0.11.5

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 (152) hide show
  1. package/dist/agents/reviewers/handler.d.ts.map +1 -1
  2. package/dist/agents/reviewers/handler.js +6 -1
  3. package/dist/agents/reviewers/handler.js.map +1 -1
  4. package/dist/agents/reviewers/sanity-inject.d.ts +7 -0
  5. package/dist/agents/reviewers/sanity-inject.d.ts.map +1 -0
  6. package/dist/agents/reviewers/sanity-inject.js +22 -0
  7. package/dist/agents/reviewers/sanity-inject.js.map +1 -0
  8. package/dist/auto-update/tui.d.ts +1 -1
  9. package/dist/auto-update/tui.d.ts.map +1 -1
  10. package/dist/auto-update/tui.js +3 -2
  11. package/dist/auto-update/tui.js.map +1 -1
  12. package/dist/cli.js +3 -0
  13. package/dist/cli.js.map +1 -1
  14. package/dist/flow/executor.d.ts +2 -2
  15. package/dist/flow/executor.d.ts.map +1 -1
  16. package/dist/flow/executor.js +30 -7
  17. package/dist/flow/executor.js.map +1 -1
  18. package/dist/flow-editor/tui.d.ts +3 -0
  19. package/dist/flow-editor/tui.d.ts.map +1 -1
  20. package/dist/flow-editor/tui.js +90 -12
  21. package/dist/flow-editor/tui.js.map +1 -1
  22. package/dist/markdown.d.ts.map +1 -1
  23. package/dist/markdown.js +386 -30
  24. package/dist/markdown.js.map +1 -1
  25. package/dist/offscreen/artifact-pane.d.ts +20 -0
  26. package/dist/offscreen/artifact-pane.d.ts.map +1 -0
  27. package/dist/offscreen/artifact-pane.js +72 -0
  28. package/dist/offscreen/artifact-pane.js.map +1 -0
  29. package/dist/offscreen/controller.d.ts +16 -3
  30. package/dist/offscreen/controller.d.ts.map +1 -1
  31. package/dist/offscreen/controller.js +84 -75
  32. package/dist/offscreen/controller.js.map +1 -1
  33. package/dist/offscreen/inquiry-pane.d.ts +14 -0
  34. package/dist/offscreen/inquiry-pane.d.ts.map +1 -0
  35. package/dist/offscreen/inquiry-pane.js +101 -0
  36. package/dist/offscreen/inquiry-pane.js.map +1 -0
  37. package/dist/offscreen/panes.d.ts +14 -0
  38. package/dist/offscreen/panes.d.ts.map +1 -0
  39. package/dist/offscreen/panes.js +2 -0
  40. package/dist/offscreen/panes.js.map +1 -0
  41. package/dist/offscreen/split-inquiry.d.ts +28 -0
  42. package/dist/offscreen/split-inquiry.d.ts.map +1 -0
  43. package/dist/offscreen/split-inquiry.js +88 -0
  44. package/dist/offscreen/split-inquiry.js.map +1 -0
  45. package/dist/orchestrator.d.ts +3 -0
  46. package/dist/orchestrator.d.ts.map +1 -1
  47. package/dist/orchestrator.js +18 -2
  48. package/dist/orchestrator.js.map +1 -1
  49. package/dist/paste-image/attachment-manager.d.ts +20 -0
  50. package/dist/paste-image/attachment-manager.d.ts.map +1 -0
  51. package/dist/paste-image/attachment-manager.js +88 -0
  52. package/dist/paste-image/attachment-manager.js.map +1 -0
  53. package/dist/paste-image/bracketed-paste.d.ts +13 -0
  54. package/dist/paste-image/bracketed-paste.d.ts.map +1 -0
  55. package/dist/paste-image/bracketed-paste.js +82 -0
  56. package/dist/paste-image/bracketed-paste.js.map +1 -0
  57. package/dist/paste-image/clipboard-ffi.d.ts +9 -0
  58. package/dist/paste-image/clipboard-ffi.d.ts.map +1 -0
  59. package/dist/paste-image/clipboard-ffi.js +149 -0
  60. package/dist/paste-image/clipboard-ffi.js.map +1 -0
  61. package/dist/paste-image/clipboard.d.ts +38 -0
  62. package/dist/paste-image/clipboard.d.ts.map +1 -0
  63. package/dist/paste-image/clipboard.js +454 -0
  64. package/dist/paste-image/clipboard.js.map +1 -0
  65. package/dist/paste-image/image-format.d.ts +7 -0
  66. package/dist/paste-image/image-format.d.ts.map +1 -0
  67. package/dist/paste-image/image-format.js +61 -0
  68. package/dist/paste-image/image-format.js.map +1 -0
  69. package/dist/paste-image/intents.d.ts +11 -0
  70. package/dist/paste-image/intents.d.ts.map +1 -0
  71. package/dist/paste-image/intents.js +66 -0
  72. package/dist/paste-image/intents.js.map +1 -0
  73. package/dist/paste-image/persistence.d.ts +2 -0
  74. package/dist/paste-image/persistence.d.ts.map +1 -0
  75. package/dist/paste-image/persistence.js +8 -0
  76. package/dist/paste-image/persistence.js.map +1 -0
  77. package/dist/paste-image/staging.d.ts +8 -0
  78. package/dist/paste-image/staging.d.ts.map +1 -0
  79. package/dist/paste-image/staging.js +23 -0
  80. package/dist/paste-image/staging.js.map +1 -0
  81. package/dist/paste-image/token.d.ts +14 -0
  82. package/dist/paste-image/token.d.ts.map +1 -0
  83. package/dist/paste-image/token.js +26 -0
  84. package/dist/paste-image/token.js.map +1 -0
  85. package/dist/providers/claude/completion-plan-mode.d.ts +3 -2
  86. package/dist/providers/claude/completion-plan-mode.d.ts.map +1 -1
  87. package/dist/providers/claude/completion-plan-mode.js +13 -11
  88. package/dist/providers/claude/completion-plan-mode.js.map +1 -1
  89. package/dist/providers/claude/plan-mode-pty-monitor.d.ts +9 -6
  90. package/dist/providers/claude/plan-mode-pty-monitor.d.ts.map +1 -1
  91. package/dist/providers/claude/plan-mode-pty-monitor.js +15 -6
  92. package/dist/providers/claude/plan-mode-pty-monitor.js.map +1 -1
  93. package/dist/providers/option-catalog.d.ts.map +1 -1
  94. package/dist/providers/option-catalog.js +0 -1
  95. package/dist/providers/option-catalog.js.map +1 -1
  96. package/dist/resume-tui.d.ts +1 -1
  97. package/dist/resume-tui.d.ts.map +1 -1
  98. package/dist/resume-tui.js +3 -1
  99. package/dist/resume-tui.js.map +1 -1
  100. package/dist/session/manifest.d.ts +3 -1
  101. package/dist/session/manifest.d.ts.map +1 -1
  102. package/dist/session/restore.d.ts.map +1 -1
  103. package/dist/session/restore.js +2 -1
  104. package/dist/session/restore.js.map +1 -1
  105. package/dist/session/session-store.d.ts +8 -0
  106. package/dist/session/session-store.d.ts.map +1 -1
  107. package/dist/session/session-store.js +18 -1
  108. package/dist/session/session-store.js.map +1 -1
  109. package/dist/startup-tui.d.ts +8 -2
  110. package/dist/startup-tui.d.ts.map +1 -1
  111. package/dist/startup-tui.js +77 -6
  112. package/dist/startup-tui.js.map +1 -1
  113. package/dist/terminal/input-router.d.ts +9 -0
  114. package/dist/terminal/input-router.d.ts.map +1 -1
  115. package/dist/terminal/input-router.js +14 -0
  116. package/dist/terminal/input-router.js.map +1 -1
  117. package/dist/text-editing/emacs-input.d.ts +11 -0
  118. package/dist/text-editing/emacs-input.d.ts.map +1 -1
  119. package/dist/text-editing/emacs-input.js +254 -17
  120. package/dist/text-editing/emacs-input.js.map +1 -1
  121. package/dist/user/curate-handler.d.ts.map +1 -1
  122. package/dist/user/curate-handler.js +4 -1
  123. package/dist/user/curate-handler.js.map +1 -1
  124. package/dist/user/curate-prompt.d.ts +2 -0
  125. package/dist/user/curate-prompt.d.ts.map +1 -1
  126. package/dist/user/curate-prompt.js.map +1 -1
  127. package/dist/user/feedback-editing.d.ts +28 -0
  128. package/dist/user/feedback-editing.d.ts.map +1 -0
  129. package/dist/user/feedback-editing.js +72 -0
  130. package/dist/user/feedback-editing.js.map +1 -0
  131. package/dist/user/handler.d.ts.map +1 -1
  132. package/dist/user/handler.js +5 -2
  133. package/dist/user/handler.js.map +1 -1
  134. package/dist/user/host-curate-prompt.d.ts +5 -6
  135. package/dist/user/host-curate-prompt.d.ts.map +1 -1
  136. package/dist/user/host-curate-prompt.js +149 -81
  137. package/dist/user/host-curate-prompt.js.map +1 -1
  138. package/dist/user/host-prompt.d.ts +4 -13
  139. package/dist/user/host-prompt.d.ts.map +1 -1
  140. package/dist/user/host-prompt.js +444 -264
  141. package/dist/user/host-prompt.js.map +1 -1
  142. package/dist/user/prompt.d.ts +3 -1
  143. package/dist/user/prompt.d.ts.map +1 -1
  144. package/dist/user/shortcut-hints.d.ts +1 -0
  145. package/dist/user/shortcut-hints.d.ts.map +1 -1
  146. package/dist/user/shortcut-hints.js +1 -1
  147. package/dist/user/shortcut-hints.js.map +1 -1
  148. package/dist/user/split-surface.d.ts +5 -1
  149. package/dist/user/split-surface.d.ts.map +1 -1
  150. package/dist/user/split-surface.js +15 -8
  151. package/dist/user/split-surface.js.map +1 -1
  152. package/package.json +1 -2
@@ -0,0 +1,72 @@
1
+ import { visibleLength } from "../ansi.js";
2
+ import { applyTextBufferEvent, splitPasteToEvents, } from "../text-editing/emacs-input.js";
3
+ import { cursorToVisual, renderWrappedLine, softWrapLine } from "../text-editing/soft-wrap.js";
4
+ import { clipToWidth } from "./curate-prompt.js";
5
+ import { ensurePersistentImagesDir } from "../paste-image/persistence.js";
6
+ export function emptyBuffer() {
7
+ return { lines: [""], cursorRow: 0, cursorCol: 0 };
8
+ }
9
+ export function bufferFromText(text) {
10
+ const lines = text.length > 0 ? text.split("\n") : [""];
11
+ const cursorRow = Math.max(0, lines.length - 1);
12
+ return {
13
+ lines,
14
+ cursorRow,
15
+ cursorCol: lines[cursorRow]?.length ?? 0,
16
+ };
17
+ }
18
+ export function normalizeBuffer(buffer) {
19
+ if (buffer.lines.length === 0)
20
+ buffer.lines.push("");
21
+ buffer.cursorRow = Math.max(0, Math.min(buffer.cursorRow, buffer.lines.length - 1));
22
+ buffer.cursorCol = Math.max(0, Math.min(buffer.cursorCol, buffer.lines[buffer.cursorRow].length));
23
+ }
24
+ export function applyEditingBufferEvent(editing, event) {
25
+ normalizeBuffer(editing.buffer);
26
+ const changed = applyTextBufferEvent(editing.buffer, event);
27
+ normalizeBuffer(editing.buffer);
28
+ return changed;
29
+ }
30
+ export function applyEditInsertedText(editing, text) {
31
+ for (const textEvent of splitPasteToEvents(text)) {
32
+ applyEditingBufferEvent(editing, textEvent);
33
+ }
34
+ }
35
+ export async function finalizeEditText(editing, text, persistentDir) {
36
+ const targetDir = persistentDir
37
+ ? await ensurePersistentImagesDir(persistentDir)
38
+ : undefined;
39
+ return editing.attachments.finalize(text, targetDir ? { targetDir } : {});
40
+ }
41
+ export function renderMultilineEditor(buffer, width, firstPrefix, continuationPrefix) {
42
+ normalizeBuffer(buffer);
43
+ const lines = [];
44
+ const firstPrefixWidth = visibleLength(firstPrefix);
45
+ const continuationPrefixWidth = visibleLength(continuationPrefix);
46
+ const bodyWidth = Math.max(1, width - firstPrefixWidth);
47
+ for (let row = 0; row < buffer.lines.length; row++) {
48
+ const raw = buffer.lines[row] ?? "";
49
+ const rendered = renderWrappedLine(raw, bodyWidth, row === buffer.cursorRow ? buffer.cursorCol : null);
50
+ for (let subRow = 0; subRow < rendered.length; subRow++) {
51
+ const prefix = row === 0 && subRow === 0 ? firstPrefix : continuationPrefix;
52
+ lines.push(clipToWidth(`${prefix}${rendered[subRow]}`, width));
53
+ }
54
+ }
55
+ const cursorLine = buffer.lines[buffer.cursorRow] ?? "";
56
+ let cursorRowOffset = 0;
57
+ for (let row = 0; row < buffer.cursorRow; row++) {
58
+ cursorRowOffset += softWrapLine(buffer.lines[row] ?? "", bodyWidth).length;
59
+ }
60
+ const cursorSegments = softWrapLine(cursorLine, bodyWidth);
61
+ const cursor = cursorToVisual(cursorSegments, buffer.cursorCol, cursorLine.length, bodyWidth);
62
+ cursorRowOffset += cursor.subRow;
63
+ const cursorPrefixWidth = buffer.cursorRow === 0 && cursor.subRow === 0
64
+ ? firstPrefixWidth
65
+ : continuationPrefixWidth;
66
+ return {
67
+ lines,
68
+ cursorRowOffset,
69
+ cursorCol: Math.min(Math.max(0, width - 1), cursorPrefixWidth + cursor.visCol),
70
+ };
71
+ }
72
+ //# sourceMappingURL=feedback-editing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-editing.js","sourceRoot":"","sources":["../../src/user/feedback-editing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EACL,oBAAoB,EACpB,kBAAkB,GAEnB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC/F,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAY1E,MAAM,UAAU,WAAW;IACzB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChD,OAAO;QACL,KAAK;QACL,SAAS;QACT,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;KACzC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAkB;IAChD,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrD,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACpF,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CACzB,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAClE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,OAA+B,EAC/B,KAAsB;IAEtB,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC5D,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,OAA+B,EAC/B,IAAY;IAEZ,KAAK,MAAM,SAAS,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAA2C,EAC3C,IAAY,EACZ,aAAiC;IAEjC,MAAM,SAAS,GAAG,aAAa;QAC7B,CAAC,CAAC,MAAM,yBAAyB,CAAC,aAAa,CAAC;QAChD,CAAC,CAAC,SAAS,CAAC;IACd,OAAO,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,MAAkB,EAClB,KAAa,EACb,WAAmB,EACnB,kBAA0B;IAE1B,eAAe,CAAC,MAAM,CAAC,CAAC;IACxB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,gBAAgB,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,uBAAuB,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,gBAAgB,CAAC,CAAC;IAExD,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;QACnD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,iBAAiB,CAChC,GAAG,EACH,SAAS,EACT,GAAG,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CACnD,CAAC;QACF,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;YACxD,MAAM,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,kBAAkB,CAAC;YAC5E,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IACxD,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC;QAChD,eAAe,IAAI,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC;IAC7E,CAAC;IACD,MAAM,cAAc,GAAG,YAAY,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,cAAc,CAC3B,cAAc,EACd,MAAM,CAAC,SAAS,EAChB,UAAU,CAAC,MAAM,EACjB,SAAS,CACV,CAAC;IACF,eAAe,IAAI,MAAM,CAAC,MAAM,CAAC;IACjC,MAAM,iBAAiB,GAAG,MAAM,CAAC,SAAS,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QACrE,CAAC,CAAC,gBAAgB;QAClB,CAAC,CAAC,uBAAuB,CAAC;IAC5B,OAAO;QACL,KAAK;QACL,eAAe;QACf,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC;KAC/E,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/user/handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAEjB,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,QAAQ,EAER,WAAW,EACX,UAAU,EACV,OAAO,EACP,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEnF;;;;;;;GAOG;AACH,qBAAa,eAAgB,YAAW,WAAW;IAE/C,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFhB,SAAS,EAAE,iBAAiB,EACnB,WAAW,GAAE,WAAW,CAAC,aAAa,EAAE,gBAAgB,CAAa,EACrE,OAAO,SAAgB;IAGpC,OAAO,CACX,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,UAAU,CAAC;CAyCvB;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,WAAW,EAChB,WAAW,EAAE,WAAW,CAAC,aAAa,EAAE,gBAAgB,CAAC,EACzD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAE5C;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,WAAW,GACf,cAAc,CAShB"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/user/handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAEjB,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,QAAQ,EAER,WAAW,EACX,UAAU,EACV,OAAO,EACP,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEnF;;;;;;;GAOG;AACH,qBAAa,eAAgB,YAAW,WAAW;IAE/C,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFhB,SAAS,EAAE,iBAAiB,EACnB,WAAW,GAAE,WAAW,CAAC,aAAa,EAAE,gBAAgB,CAAa,EACrE,OAAO,SAAgB;IAGpC,OAAO,CACX,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,UAAU,CAAC;CA2CvB;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,WAAW,EAChB,WAAW,EAAE,WAAW,CAAC,aAAa,EAAE,gBAAgB,CAAC,EACzD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAE5C;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,WAAW,GACf,cAAc,CAShB"}
@@ -26,6 +26,8 @@ export class UserRoleHandler {
26
26
  const promptCtx = { phaseLabel, artifactKind };
27
27
  if (offscreen)
28
28
  promptCtx.offscreen = offscreen;
29
+ if (ctx.persistentDir)
30
+ promptCtx.persistentDir = ctx.persistentDir;
29
31
  const result = await this.userPhase.prompt(displayText, step.id, promptCtx);
30
32
  if (result.accepted) {
31
33
  const verdictKey = step.writes.verdict;
@@ -41,9 +43,10 @@ export class UserRoleHandler {
41
43
  }
42
44
  const verdictKey = step.writes.verdict;
43
45
  if (verdictKey) {
46
+ const items = result.feedback ?? [];
44
47
  ctx.artifacts.set(verdictKey, {
45
- data: { approved: false },
46
- text: result.comments ?? "",
48
+ data: { approved: false, feedbackItems: items },
49
+ text: items.join("\n\n"),
47
50
  meta: { source: "user" },
48
51
  });
49
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/user/handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/user/handler.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,8 @@ import { type CurateDecision, type CuratePromptHandler, type CurateResult } from
3
3
  import type { ReviewVerdict } from "../agents/reviewers/types.js";
4
4
  import type { TerminalHost } from "../terminal/host.js";
5
5
  import type { CuratePromptContext } from "./curate-prompt.js";
6
+ import { AttachmentManager } from "../paste-image/attachment-manager.js";
7
+ import { type FeedbackEditTarget } from "./feedback-editing.js";
6
8
  export declare const KDR_HINT = "\u001B[2mK\u001B[0m[eep]/\u001B[2mD\u001B[0m[rop]/\u001B[2mR\u001B[0m[evise]";
7
9
  /**
8
10
  * Host-backed curate-verdict prompt. The plan is always visible:
@@ -42,6 +44,8 @@ interface CurateState {
42
44
  editing: {
43
45
  target: EditTarget;
44
46
  buffer: TextBuffer;
47
+ attachments: AttachmentManager;
48
+ transientHint: string | null;
45
49
  } | undefined;
46
50
  planScrollTop: number;
47
51
  nextCycle: number[];
@@ -50,11 +54,6 @@ export declare function curateHelpTokens(state: Pick<CurateState, "editing" | "c
50
54
  type EditTarget = {
51
55
  kind: "reviewer-revise";
52
56
  index: number;
53
- } | {
54
- kind: "user-edit";
55
- index: number;
56
- } | {
57
- kind: "user-add";
58
- };
57
+ } | FeedbackEditTarget;
59
58
  export {};
60
59
  //# sourceMappingURL=host-curate-prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"host-curate-prompt.d.ts","sourceRoot":"","sources":["../../src/user/host-curate-prompt.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,EAKL,KAAK,cAAc,EAEnB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAK5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAmC,MAAM,qBAAqB,CAAC;AACzF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAM9D,eAAO,MAAM,QAAQ,iFAC+C,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,sBAAuB,YAAW,mBAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,YAAY;IAEzC,MAAM,CACV,OAAO,EAAE,aAAa,EACtB,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,YAAY,CAAC;CAiUzB;AAED,UAAU,WAAW;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,QAAQ,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IACjC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE;QAAE,MAAM,EAAE,UAAU,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,GAAG,SAAS,CAAC;IAChE,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC,EAC1E,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,OAAO,GACpB,MAAM,EAAE,CAaV;AAED,KAAK,UAAU,GACX;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"host-curate-prompt.d.ts","sourceRoot":"","sources":["../../src/user/host-curate-prompt.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAKL,KAAK,cAAc,EAEnB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAY5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAmC,MAAM,qBAAqB,CAAC;AACzF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAQzE,OAAO,EAOL,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAM/B,eAAO,MAAM,QAAQ,iFAC+C,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,sBAAuB,YAAW,mBAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,YAAY;IAEzC,MAAM,CACV,OAAO,EAAE,aAAa,EACtB,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,YAAY,CAAC;CAqZzB;AAED,UAAU,WAAW;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,QAAQ,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IACjC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE;QACP,MAAM,EAAE,UAAU,CAAC;QACnB,MAAM,EAAE,UAAU,CAAC;QACnB,WAAW,EAAE,iBAAiB,CAAC;QAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;KAC9B,GAAG,SAAS,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC,EAC1E,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,OAAO,GACpB,MAAM,EAAE,CAmBV;AAED,KAAK,UAAU,GACX;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1C,kBAAkB,CAAC"}
@@ -1,17 +1,19 @@
1
- import { bold, cyan, dim, reset, visibleLength, } from "../ansi.js";
1
+ import { bold, cyan, dim, reset, visibleLength, yellow, } from "../ansi.js";
2
2
  import { AgentInterruptedError } from "../agents/runner.js";
3
3
  import { renderMarkdown } from "../markdown.js";
4
4
  import { EmacsInputParser } from "./prompt.js";
5
- import { applyTextBufferEvent, isTextBufferEvent, } from "../text-editing/emacs-input.js";
6
- import { cursorToVisual, renderWrappedLine, softWrapLine } from "../text-editing/soft-wrap.js";
5
+ import { aliasSelectionNavEvent, isTextBufferEvent, } from "../text-editing/emacs-input.js";
7
6
  import { clipToWidth, tagFor, userAddedTag, wrapToWidth, } from "./curate-prompt.js";
8
7
  import { buildPlanPane } from "./plan-pane.js";
9
- import { buildSplitSurface, computeSplitMetrics } from "./split-surface.js";
8
+ import { buildSplitSurface, computeSplitMetrics, SPLIT_COLLAPSE_AT_COLS, } from "./split-surface.js";
10
9
  import { renderShortcutHints } from "./shortcut-hints.js";
11
- import { OffscreenController } from "../offscreen/controller.js";
10
+ import { OffscreenController, } from "../offscreen/controller.js";
11
+ import { AttachmentManager } from "../paste-image/attachment-manager.js";
12
+ import { ALT_V_PASTE_IMAGE_HINT, handleBracketedPaste, handleImagePasteIntent, PASTING_IMAGE_HINT, } from "../paste-image/intents.js";
13
+ import { applyEditingBufferEvent, applyEditInsertedText, bufferFromText, emptyBuffer, finalizeEditText, renderMultilineEditor, } from "./feedback-editing.js";
12
14
  const DECISION_CYCLE = ["keep", "drop", "revise"];
13
15
  const PLAN_PAGE_OVERLAP = 1;
14
- const COLLAPSE_AT_COLS = 100;
16
+ const COLLAPSE_AT_COLS = SPLIT_COLLAPSE_AT_COLS;
15
17
  const CITATION_MARKER = "\x1b[1;95m▶\x1b[0m";
16
18
  export const KDR_HINT = `${dim}K${reset}[eep]/${dim}D${reset}[rop]/${dim}R${reset}[evise]`;
17
19
  /**
@@ -65,7 +67,10 @@ export class HostBackedCuratePrompt {
65
67
  return new Promise((resolve, reject) => {
66
68
  let detach;
67
69
  let offscreenController;
70
+ let active = true;
71
+ let settlingEdit = false;
68
72
  const cleanup = () => {
73
+ active = false;
69
74
  offscreenController?.dispose();
70
75
  offscreenController = undefined;
71
76
  detach?.();
@@ -100,6 +105,8 @@ export class HostBackedCuratePrompt {
100
105
  return result;
101
106
  };
102
107
  const cancelEdit = () => {
108
+ if (settlingEdit)
109
+ return;
103
110
  const editing = state.editing;
104
111
  if (!editing)
105
112
  return;
@@ -110,11 +117,7 @@ export class HostBackedCuratePrompt {
110
117
  }
111
118
  clampCursor(issues.length, state);
112
119
  };
113
- const submitEdit = () => {
114
- const editing = state.editing;
115
- if (!editing)
116
- return;
117
- const text = editing.buffer.lines.join("\n").trim();
120
+ const applySubmittedEdit = (editing, text) => {
118
121
  state.editing = undefined;
119
122
  if (editing.target.kind === "reviewer-revise") {
120
123
  const i = editing.target.index;
@@ -140,22 +143,94 @@ export class HostBackedCuratePrompt {
140
143
  }
141
144
  clampCursor(issues.length, state);
142
145
  };
146
+ const submitEdit = () => {
147
+ const editing = state.editing;
148
+ if (!editing)
149
+ return;
150
+ if (settlingEdit)
151
+ return;
152
+ const text = editing.buffer.lines.join("\n").trim();
153
+ if (editing.attachments.snapshot().length === 0) {
154
+ applySubmittedEdit(editing, text);
155
+ return;
156
+ }
157
+ settlingEdit = true;
158
+ void finalizeEditText(editing, text, context.persistentDir).then((finalText) => {
159
+ if (!active || state.editing !== editing)
160
+ return;
161
+ applySubmittedEdit(editing, finalText);
162
+ settlingEdit = false;
163
+ this.host.scheduleParentUiRender();
164
+ }).catch((err) => {
165
+ settlingEdit = false;
166
+ failWith(err instanceof Error ? err : new Error(String(err)));
167
+ });
168
+ };
143
169
  const openReviewerEditor = (index, text = "") => {
144
170
  state.editing = {
145
171
  target: { kind: "reviewer-revise", index },
146
172
  buffer: bufferFromText(text),
173
+ attachments: new AttachmentManager(),
174
+ transientHint: null,
147
175
  };
148
176
  };
149
177
  const openUserAddEditor = () => {
150
- state.editing = { target: { kind: "user-add" }, buffer: emptyBuffer() };
178
+ state.editing = {
179
+ target: { kind: "user-add" },
180
+ buffer: emptyBuffer(),
181
+ attachments: new AttachmentManager(),
182
+ transientHint: null,
183
+ };
184
+ };
185
+ const applyEditPasteOutcome = (editing, outcome) => {
186
+ if (!active || settlingEdit || state.editing !== editing)
187
+ return;
188
+ editing.transientHint = outcome.hint ?? null;
189
+ if (outcome.inserted !== undefined)
190
+ applyEditInsertedText(editing, outcome.inserted);
191
+ this.host.scheduleParentUiRender();
192
+ };
193
+ const launchEditPasteIntent = (editing, task) => {
194
+ void task.then((outcome) => applyEditPasteOutcome(editing, outcome)).catch((err) => {
195
+ if (!active || settlingEdit || state.editing !== editing)
196
+ return;
197
+ editing.transientHint = err instanceof Error ? err.message : String(err);
198
+ this.host.scheduleParentUiRender();
199
+ });
151
200
  };
152
201
  const processEvents = (events) => {
153
202
  let dirty = false;
154
203
  let finished = false;
155
- for (const event of events) {
204
+ for (const rawEvent of events) {
156
205
  if (finished)
157
206
  break;
207
+ const event = state.editing
208
+ ? rawEvent
209
+ : aliasSelectionNavEvent(rawEvent);
158
210
  if (state.editing) {
211
+ if (settlingEdit) {
212
+ dirty = true;
213
+ continue;
214
+ }
215
+ if (state.editing.transientHint) {
216
+ state.editing.transientHint = null;
217
+ dirty = true;
218
+ }
219
+ if (event.type === "paste") {
220
+ const editing = state.editing;
221
+ launchEditPasteIntent(editing, handleBracketedPaste(event.content, editing.attachments));
222
+ continue;
223
+ }
224
+ if (event.type === "image-paste") {
225
+ const editing = state.editing;
226
+ launchEditPasteIntent(editing, handleImagePasteIntent(editing.attachments, () => {
227
+ if (!active || settlingEdit || state.editing !== editing)
228
+ return;
229
+ editing.transientHint = PASTING_IMAGE_HINT;
230
+ this.host.scheduleParentUiRender();
231
+ }));
232
+ continue;
233
+ }
159
234
  if (event.type === "ctrl-c" || event.type === "escape") {
160
235
  cancelEdit();
161
236
  dirty = true;
@@ -167,20 +242,20 @@ export class HostBackedCuratePrompt {
167
242
  continue;
168
243
  }
169
244
  if (event.type === "ctrl-j") {
170
- dirty = applyCurateTextBufferEvent(state.editing, { type: "newline" }) || dirty;
245
+ dirty = applyEditingBufferEvent(state.editing, { type: "newline" }) || dirty;
171
246
  dirty = true;
172
247
  continue;
173
248
  }
174
249
  if (event.type === "arrow") {
175
250
  if (event.direction === "left" || event.direction === "right") {
176
- dirty = applyCurateTextBufferEvent(state.editing, {
251
+ dirty = applyEditingBufferEvent(state.editing, {
177
252
  type: event.direction === "left" ? "ctrl-b" : "ctrl-f",
178
253
  }) || dirty;
179
254
  }
180
255
  continue;
181
256
  }
182
257
  if (isTextBufferEvent(event)) {
183
- dirty = applyCurateTextBufferEvent(state.editing, event) || dirty;
258
+ dirty = applyEditingBufferEvent(state.editing, event) || dirty;
184
259
  continue;
185
260
  }
186
261
  continue;
@@ -254,6 +329,8 @@ export class HostBackedCuratePrompt {
254
329
  state.editing = {
255
330
  target: { kind: "user-edit", index },
256
331
  buffer: bufferFromText(state.userAdded[index] ?? ""),
332
+ attachments: new AttachmentManager(),
333
+ transientHint: null,
257
334
  };
258
335
  dirty = true;
259
336
  }
@@ -351,15 +428,20 @@ export class HostBackedCuratePrompt {
351
428
  },
352
429
  };
353
430
  const mode = context.offscreen
354
- ? (offscreenController = new OffscreenController(this.host, context.offscreen.workdir, context.offscreen.slots)).wrap(baseMode)
431
+ ? (offscreenController = new OffscreenController(this.host, context.offscreen.workdir, context.offscreen.slots, curateArtifactPaneConfigs(verdict, plan))).wrap(baseMode)
355
432
  : baseMode;
356
433
  detach = this.host.attachParentUi(mode);
357
434
  });
358
435
  }
359
436
  }
360
437
  export function curateHelpTokens(state, issueCount, citationLive) {
361
- if (state.editing)
362
- return ["Ctrl+J Newline", "Enter Submit", "Esc Cancel"];
438
+ if (state.editing) {
439
+ const tokens = ["Ctrl+J Newline", "Enter Submit", "Esc Cancel", ALT_V_PASTE_IMAGE_HINT];
440
+ if (state.editing.transientHint) {
441
+ tokens.push(`${yellow}${state.editing.transientHint}${reset}`);
442
+ }
443
+ return tokens;
444
+ }
363
445
  if (state.cursor < issueCount) {
364
446
  const tokens = [KDR_HINT];
365
447
  if (state.decisions[state.cursor] === "revise")
@@ -374,67 +456,12 @@ export function curateHelpTokens(state, issueCount, citationLive) {
374
456
  }
375
457
  return ["Enter/A Add"];
376
458
  }
377
- function emptyBuffer() {
378
- return { lines: [""], cursorRow: 0, cursorCol: 0 };
379
- }
380
- function bufferFromText(text) {
381
- const lines = text.length > 0 ? text.split("\n") : [""];
382
- const cursorRow = Math.max(0, lines.length - 1);
383
- return {
384
- lines,
385
- cursorRow,
386
- cursorCol: lines[cursorRow]?.length ?? 0,
387
- };
388
- }
389
- function normalizeBuffer(buffer) {
390
- if (buffer.lines.length === 0)
391
- buffer.lines.push("");
392
- buffer.cursorRow = Math.max(0, Math.min(buffer.cursorRow, buffer.lines.length - 1));
393
- buffer.cursorCol = Math.max(0, Math.min(buffer.cursorCol, buffer.lines[buffer.cursorRow].length));
394
- }
395
- function applyCurateTextBufferEvent(editing, event) {
396
- normalizeBuffer(editing.buffer);
397
- const changed = applyTextBufferEvent(editing.buffer, event);
398
- normalizeBuffer(editing.buffer);
399
- return changed;
400
- }
401
459
  function navigableCount(issueCount, state) {
402
460
  return issueCount + state.userAdded.length + 1;
403
461
  }
404
462
  function clampCursor(issueCount, state) {
405
463
  state.cursor = Math.max(0, Math.min(state.cursor, navigableCount(issueCount, state) - 1));
406
464
  }
407
- function renderMultilineEditor(buffer, width, firstPrefix, continuationPrefix) {
408
- normalizeBuffer(buffer);
409
- const lines = [];
410
- const firstPrefixWidth = visibleLength(firstPrefix);
411
- const continuationPrefixWidth = visibleLength(continuationPrefix);
412
- const bodyWidth = Math.max(1, width - firstPrefixWidth);
413
- for (let row = 0; row < buffer.lines.length; row++) {
414
- const raw = buffer.lines[row] ?? "";
415
- const rendered = renderWrappedLine(raw, bodyWidth, row === buffer.cursorRow ? buffer.cursorCol : null);
416
- for (let subRow = 0; subRow < rendered.length; subRow++) {
417
- const prefix = row === 0 && subRow === 0 ? firstPrefix : continuationPrefix;
418
- lines.push(clipToWidth(`${prefix}${rendered[subRow]}`, width));
419
- }
420
- }
421
- const cursorLine = buffer.lines[buffer.cursorRow] ?? "";
422
- let cursorRowOffset = 0;
423
- for (let row = 0; row < buffer.cursorRow; row++) {
424
- cursorRowOffset += softWrapLine(buffer.lines[row] ?? "", bodyWidth).length;
425
- }
426
- const cursorSegments = softWrapLine(cursorLine, bodyWidth);
427
- const cursor = cursorToVisual(cursorSegments, buffer.cursorCol, cursorLine.length, bodyWidth);
428
- cursorRowOffset += cursor.subRow;
429
- const cursorPrefixWidth = buffer.cursorRow === 0 && cursor.subRow === 0
430
- ? firstPrefixWidth
431
- : continuationPrefixWidth;
432
- return {
433
- lines,
434
- cursorRowOffset,
435
- cursorCol: Math.min(Math.max(0, width - 1), cursorPrefixWidth + cursor.visCol),
436
- };
437
- }
438
465
  function buildLeftPane(verdict, state, width, rows, globalHintText, citationLive) {
439
466
  const pinnedHint = clipToWidth(globalHintText, width);
440
467
  const scrollRows = Math.max(0, rows - 1);
@@ -470,16 +497,11 @@ function buildLeftPane(verdict, state, width, rows, globalHintText, citationLive
470
497
  const arrow = isCursor ? `${bold}❯${reset}` : " ";
471
498
  const tag = tagFor(state.decisions[i]);
472
499
  const issue = issues[i];
473
- const meta = [];
474
- if (issue.severity)
475
- meta.push(issue.severity);
476
- if (issue.category)
477
- meta.push(issue.category);
478
500
  const head = `${arrow} ${tag} `;
479
501
  const headWidth = visibleLength(head);
480
502
  const avail = Math.max(1, width - headWidth);
481
- const metaToken = meta.length ? `${dim}[${meta.join("/")}]${reset}` : "";
482
- const metaWidth = meta.length ? visibleLength(metaToken) : 0;
503
+ const metaToken = issueMetaToken(issue);
504
+ const metaWidth = metaToken ? visibleLength(metaToken) : 0;
483
505
  const rendered = renderMarkdown(issue.description, avail);
484
506
  rowStarts[rowIndex] = lines.length;
485
507
  if (rendered.length === 0) {
@@ -712,6 +734,52 @@ function globalHint(context) {
712
734
  tokens.push(slot.hint);
713
735
  return renderShortcutHints(tokens);
714
736
  }
737
+ function curateArtifactPaneConfigs(verdict, plan) {
738
+ return {
739
+ primary: {
740
+ inquirySide: "left",
741
+ renderArtifact: (width) => buildCuratePlanPane(plan, width).lines,
742
+ },
743
+ secondary: {
744
+ inquirySide: "right",
745
+ renderArtifact: (width) => buildIssuesArtifactPane(verdict, width),
746
+ },
747
+ };
748
+ }
749
+ function buildIssuesArtifactPane(verdict, width) {
750
+ const paneWidth = Math.max(1, width);
751
+ const lines = [];
752
+ const issueCount = verdict.issues.length;
753
+ const suffix = issueCount === 1 ? "" : "s";
754
+ lines.push(clipToWidth(`${bold}${cyan}Reviewer Issues${reset} — ${issueCount} issue${suffix}`, paneWidth));
755
+ lines.push(`${dim}${"─".repeat(paneWidth)}${reset}`);
756
+ if (verdict.summary) {
757
+ for (const line of renderMarkdown(verdict.summary, paneWidth)) {
758
+ lines.push(clipToWidth(line, paneWidth));
759
+ }
760
+ lines.push("");
761
+ }
762
+ for (let i = 0; i < verdict.issues.length; i++) {
763
+ if (i > 0)
764
+ lines.push("");
765
+ const issue = verdict.issues[i];
766
+ const title = `${bold}Issue ${i + 1}${reset}`;
767
+ const meta = issueMetaToken(issue);
768
+ lines.push(clipToWidth(meta ? `${title} ${meta}` : title, paneWidth));
769
+ for (const line of renderMarkdown(issue.description, paneWidth)) {
770
+ lines.push(clipToWidth(line, paneWidth));
771
+ }
772
+ }
773
+ return lines;
774
+ }
775
+ function issueMetaToken(issue) {
776
+ const meta = [];
777
+ if (issue.severity)
778
+ meta.push(issue.severity);
779
+ if (issue.category)
780
+ meta.push(issue.category);
781
+ return meta.length ? `${dim}[${meta.join("/")}]${reset}` : "";
782
+ }
715
783
  function planMetrics(plan, host) {
716
784
  const layout = host.getLayout();
717
785
  const cols = Math.max(20, layout.columns);