@huseynsnmz/pi-board 0.15.3 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/CHANGELOG.md +13 -4
  2. package/CONTRIBUTING.md +7 -0
  3. package/README.md +53 -419
  4. package/SECURITY.md +19 -0
  5. package/docs/how-it-works.md +31 -0
  6. package/docs/reference.md +276 -0
  7. package/package.json +5 -11
  8. package/src/index.ts +1 -1
  9. package/src/runtime/service.mjs +12 -0
  10. package/src/ui/dashboard.ts +14 -8
  11. package/IMPLEMENTATION_PLAN.md +0 -920
  12. package/PRD.md +0 -484
  13. package/PROGRESS.md +0 -142
  14. package/VERIFY.md +0 -115
  15. package/docs/BATCH_SELECTION_READ_FLOW.md +0 -277
  16. package/docs/EXPLORATION.md +0 -187
  17. package/docs/PTY_ATTACH_IMPLEMENTATION_PLAN.md +0 -581
  18. package/docs/RELEASE.md +0 -148
  19. package/docs/superpowers/plans/2026-08-15-screenlog-gc.md +0 -704
  20. package/docs/superpowers/plans/2026-08-16-attach-double-cursor-jiggle-retry.md +0 -499
  21. package/docs/superpowers/plans/2026-08-21-attach-coldstart-jiggle-rearm.md +0 -797
  22. package/docs/superpowers/plans/2026-08-21-dashboard-keypress-lag.md +0 -366
  23. package/docs/superpowers/plans/2026-08-21-issue-14-needs-input-no-auto-done.md +0 -576
  24. package/docs/superpowers/plans/2026-08-22-jiggle-shrink-and-hold.md +0 -337
  25. package/docs/superpowers/plans/2026-08-22-launch-cwd-favorites.md +0 -916
  26. package/docs/superpowers/plans/2026-08-22-question-tool-grouping.md +0 -211
  27. package/docs/superpowers/plans/2026-08-22-rename-state-labels.md +0 -182
  28. package/docs/superpowers/plans/2026-08-22-stable-list-order.md +0 -51
  29. package/docs/superpowers/plans/2026-08-27-locks-acquirelock-spin.md +0 -614
  30. package/docs/superpowers/plans/2026-08-27-pty-runner-test-flaky.md +0 -32
  31. package/docs/superpowers/plans/2026-08-29-code-refs-badges.md +0 -223
  32. package/docs/superpowers/plans/2026-08-30-circular-navigation.md +0 -308
  33. package/docs/superpowers/plans/2026-08-30-post-exit-timing-fix.md +0 -37
  34. package/docs/superpowers/plans/2026-08-30-pty-attach-quality-debt.md +0 -311
  35. package/docs/superpowers/plans/2026-08-30-readme-v2.md +0 -294
  36. package/docs/superpowers/plans/2026-09-01-attach-detach-gate-cursor-anchor.md +0 -284
  37. package/docs/superpowers/plans/2026-09-02-attach-detach-editor-state.md +0 -722
  38. package/docs/superpowers/plans/2026-09-03-code-refs-pr-backlink-narrow.md +0 -551
  39. package/docs/superpowers/plans/2026-09-03-detach-gate-glyph-fallback.md +0 -146
  40. package/docs/superpowers/plans/2026-09-04-evidence-outputpreview.md +0 -209
  41. package/docs/superpowers/plans/2026-09-04-warm-host-reclaim.md +0 -796
  42. package/docs/superpowers/plans/2026-09-05-issue-13-drainnextfollowup-pty-probe.md +0 -114
  43. package/docs/superpowers/plans/2026-09-05-issue-38-windows-wezterm-ime-cursor.md +0 -73
  44. package/docs/superpowers/plans/2026-09-05-issue-39-truncate-codepoint-boundary.md +0 -143
  45. package/docs/superpowers/plans/2026-09-05-issue-61-mention-fallback-guards.md +0 -226
  46. package/docs/superpowers/plans/2026-09-05-issue-63-flaky-manual-completion.md +0 -87
  47. package/docs/superpowers/plans/2026-09-05-issue-64-changelog-release-helper.md +0 -53
  48. package/docs/superpowers/plans/2026-09-05-pty-host-stacking-sock-race.md +0 -731
  49. package/docs/superpowers/plans/2026-09-08-attach-ctrl-left-detach.md +0 -30
  50. package/docs/superpowers/plans/2026-09-08-dashboard-shrink-repaint.md +0 -68
  51. package/docs/superpowers/plans/2026-09-08-issue-11-attach-runtime-desync-heal.md +0 -917
  52. package/docs/superpowers/plans/2026-09-08-legacy-stale-host-recovery.md +0 -125
  53. package/docs/superpowers/plans/2026-09-08-spawn-async-error-swallow.md +0 -56
  54. package/docs/superpowers/plans/2026-09-08-stale-model-attach-guard.md +0 -96
  55. package/docs/superpowers/plans/2026-09-09-claimpid-blocks-replace.md +0 -267
  56. package/docs/superpowers/plans/2026-09-09-harden-runner-architecture.md +0 -603
  57. package/docs/superpowers/plans/2026-09-09-single-writer-completion.md +0 -252
  58. package/docs/superpowers/plans/2026-09-10-reader-consistency.md +0 -115
  59. package/docs/superpowers/plans/2026-09-14-attach-cursor-dectcem-gate.md +0 -469
  60. package/docs/superpowers/plans/2026-09-14-attach-snapshot.md +0 -92
  61. package/docs/superpowers/plans/2026-09-14-host-meta-orphan-lock.md +0 -771
  62. package/docs/superpowers/plans/2026-09-14-issue-106-terminal-frame-cognition.md +0 -299
  63. package/docs/superpowers/plans/2026-09-14-issue-113-foreground-preview-race.md +0 -609
  64. package/docs/superpowers/plans/2026-09-14-terminal-model.md +0 -145
  65. package/docs/superpowers/plans/2026-09-15-coordinator-pipe-root-normalize.md +0 -224
  66. package/docs/superpowers/plans/2026-09-15-lease-publish-eprem-reclaim.md +0 -341
  67. package/docs/superpowers/plans/2026-09-18-detach-anchor-reporter-endpoint.md +0 -875
  68. package/docs/superpowers/plans/2026-09-20-control-lifecycle.md +0 -116
  69. package/docs/superpowers/plans/2026-09-20-issue-121-perf-gate-out-of-coverage.md +0 -517
  70. package/docs/superpowers/plans/2026-09-23-a5-mid-stream-assertion.md +0 -25
  71. package/docs/superpowers/plans/2026-09-23-cwd-browse-tab-drill.md +0 -393
  72. package/docs/superpowers/plans/2026-09-23-terminal-query-forwarding.md +0 -51
  73. package/docs/superpowers/plans/2026-09-23-unconditional-detach-key.md +0 -58
  74. package/docs/superpowers/plans/2026-09-24-control-reconcile-flake.md +0 -698
  75. package/docs/superpowers/plans/2026-09-24-probe-attached-clients.md +0 -605
  76. package/docs/superpowers/plans/2026-09-29-issue-145-holding-semantic-state.md +0 -1183
  77. package/docs/superpowers/plans/2026-09-29-issue-145-user-verification.md +0 -66
  78. package/docs/superpowers/plans/2026-09-30-board-delete-key-x-y-confirm.md +0 -649
  79. package/docs/superpowers/plans/2026-09-30-issue-153-runner-stop-boot-window.md +0 -618
  80. package/docs/superpowers/plans/2026-09-30-issue-95-test-discipline.md +0 -555
  81. package/docs/superpowers/plans/2026-09-30-publish-dispatch-tag-check.md +0 -259
  82. package/docs/superpowers/plans/2026-10-06-attach-settle-scheme-delivery.md +0 -751
  83. package/docs/superpowers/plans/2026-10-09-issue-167-attach-middle-paste.md +0 -509
  84. package/docs/superpowers/plans/2026-10-09-issue-169-fullscreen-mouse-ownership.md +0 -346
  85. package/docs/superpowers/plans/2026-10-10-attach-delete-in-place.md +0 -832
  86. package/docs/superpowers/plans/2026-10-10-issue-174-selection-mirror-paste-source.md +0 -510
  87. package/docs/superpowers/plans/2026-10-14-issue-170-attach-reply-guard.md +0 -771
  88. package/docs/superpowers/plans/2026-10-14-issue-178-accept-registration-race.md +0 -1257
  89. package/docs/superpowers/plans/2026-10-14-issue-184-snapshot-window-contract.md +0 -657
  90. package/docs/superpowers/plans/2026-10-14-issue-185-attach-wheel-alt-screen.md +0 -47
  91. package/docs/superpowers/plans/2026-10-14-issue-187-motionless-drag.md +0 -931
  92. package/docs/superpowers/plans/2026-10-14-issue-189-mixed-input-segments.md +0 -823
  93. package/docs/superpowers/plans/2026-10-15-issue-188-x10-mouse-release.md +0 -526
  94. package/docs/superpowers/plans/2026-10-16-issue-198-attach-wheel-forward-fallback.md +0 -32
  95. package/docs/superpowers/plans/2026-10-18-attach-wheel-replay-pseudo-scrollback.md +0 -437
  96. package/docs/superpowers/plans/2026-10-19-issue-213-reply-guard-csi-key.md +0 -257
  97. package/docs/superpowers/plans/2026-10-19-issue-214-attach-forward-alt-modifier.md +0 -202
  98. package/docs/superpowers/plans/2026-10-21-issue-221-ask-user-question.md +0 -198
  99. package/docs/superpowers/plans/2026-10-23-issue-222-attach-ready.md +0 -290
  100. package/docs/superpowers/plans/2026-10-23-issue-225-monotonic-foreground-state.md +0 -450
  101. package/docs/superpowers/plans/2026-10-23-issue-229-vim-jkl.md +0 -449
  102. package/docs/superpowers/plans/2026-10-23-issue-232-attach-bg-only-cells.md +0 -153
  103. package/docs/superpowers/plans/2026-10-23-lease-heartbeat-staleness.md +0 -537
  104. package/docs/superpowers/plans/2026-10-23-selected-row-highlight.md +0 -405
  105. package/docs/superpowers/plans/2026-10-24-issue-217-windows-pid-reuse-stopping.md +0 -367
  106. package/docs/superpowers/plans/2026-10-24-issue-230-warm-host-background-runs.md +0 -806
  107. package/docs/superpowers/plans/2026-10-24-issue-238-windows-process-identity-token.md +0 -490
  108. package/docs/superpowers/plans/2026-10-24-issue-241-coordinator-root-exit.md +0 -461
  109. package/docs/superpowers/plans/2026-10-25-issue-239-coordinator-replacement-identity.md +0 -504
  110. package/docs/superpowers/plans/2026-10-26-issue-245-key-hints-doc-sync.md +0 -244
  111. package/docs/superpowers/plans/2026-10-27-issue-172-fullscreen-selection-clear.md +0 -344
  112. package/docs/superpowers/plans/2026-10-27-issue-252-select-key-hints.md +0 -209
  113. package/docs/superpowers/plans/2026-10-28-issue-255-coordinator-endpoint-zombie.md +0 -442
  114. package/docs/superpowers/plans/2026-10-28-issue-257-legacy-pty-runner-endpoint-cleanup.md +0 -256
  115. package/docs/superpowers/plans/2026-11-03-cwd-favorites-full-pool.md +0 -266
  116. package/docs/superpowers/specs/2026-08-15-screenlog-gc-design.md +0 -105
  117. package/docs/superpowers/specs/2026-08-16-attach-double-cursor-jiggle-retry-design.md +0 -142
  118. package/docs/superpowers/specs/2026-08-21-attach-coldstart-jiggle-rearm-design.md +0 -110
  119. package/docs/superpowers/specs/2026-08-21-dashboard-keypress-lag-design.md +0 -59
  120. package/docs/superpowers/specs/2026-08-21-issue-14-needs-input-no-auto-done-design.md +0 -109
  121. package/docs/superpowers/specs/2026-08-22-cwd-favorites-design.md +0 -131
  122. package/docs/superpowers/specs/2026-08-22-jiggle-shrink-and-hold-design.md +0 -111
  123. package/docs/superpowers/specs/2026-08-22-question-tool-grouping-design.md +0 -114
  124. package/docs/superpowers/specs/2026-08-22-rename-state-labels-design.md +0 -80
  125. package/docs/superpowers/specs/2026-08-27-locks-acquirelock-spin-design.md +0 -97
  126. package/docs/superpowers/specs/2026-08-27-pty-runner-test-flaky-design.md +0 -35
  127. package/docs/superpowers/specs/2026-08-29-code-refs-badges-design.md +0 -128
  128. package/docs/superpowers/specs/2026-08-30-circular-navigation-design.md +0 -47
  129. package/docs/superpowers/specs/2026-08-30-eprm-atomicwrite-race-design.md +0 -77
  130. package/docs/superpowers/specs/2026-08-30-post-exit-timing-fix-design.md +0 -80
  131. package/docs/superpowers/specs/2026-08-30-pty-attach-quality-debt-design.md +0 -105
  132. package/docs/superpowers/specs/2026-08-30-readme-v2-design.md +0 -115
  133. package/docs/superpowers/specs/2026-09-01-attach-detach-gate-cursor-anchor-design.md +0 -78
  134. package/docs/superpowers/specs/2026-09-02-attach-detach-editor-state-design.md +0 -120
  135. package/docs/superpowers/specs/2026-09-03-code-refs-pr-backlink-narrow-design.md +0 -92
  136. package/docs/superpowers/specs/2026-09-03-detach-gate-glyph-fallback-design.md +0 -99
  137. package/docs/superpowers/specs/2026-09-04-evidence-outputpreview-design.md +0 -50
  138. package/docs/superpowers/specs/2026-09-04-warm-host-reclaim-design.md +0 -106
  139. package/docs/superpowers/specs/2026-09-05-issue-13-drainnextfollowup-pty-probe-design.md +0 -64
  140. package/docs/superpowers/specs/2026-09-05-issue-38-windows-wezterm-ime-design.md +0 -48
  141. package/docs/superpowers/specs/2026-09-05-issue-39-truncate-codepoint-boundary-design.md +0 -64
  142. package/docs/superpowers/specs/2026-09-05-issue-61-mention-fallback-design.md +0 -71
  143. package/docs/superpowers/specs/2026-09-05-issue-63-flaky-manual-completion-design.md +0 -49
  144. package/docs/superpowers/specs/2026-09-05-issue-64-changelog-helper-design.md +0 -76
  145. package/docs/superpowers/specs/2026-09-05-pty-host-stacking-sock-race-design.md +0 -510
  146. package/docs/superpowers/specs/2026-09-07-issue-11-attach-runtime-desync-heal-design.md +0 -130
  147. package/docs/superpowers/specs/2026-09-08-attach-ctrl-left-detach-design.md +0 -58
  148. package/docs/superpowers/specs/2026-09-08-dashboard-shrink-repaint-design.md +0 -52
  149. package/docs/superpowers/specs/2026-09-08-legacy-stale-host-recovery-design.md +0 -87
  150. package/docs/superpowers/specs/2026-09-08-spawn-async-error-swallow-design.md +0 -56
  151. package/docs/superpowers/specs/2026-09-08-stale-model-attach-guard-design.md +0 -79
  152. package/docs/superpowers/specs/2026-09-09-claimpid-blocks-replace-design.md +0 -147
  153. package/docs/superpowers/specs/2026-09-09-harden-runner-architecture-design.md +0 -304
  154. package/docs/superpowers/specs/2026-09-14-attach-cursor-dectcem-gate-design.md +0 -114
  155. package/docs/superpowers/specs/2026-09-14-host-meta-orphan-lock-design.md +0 -120
  156. package/docs/superpowers/specs/2026-09-14-issue-106-terminal-frame-cognition-design.md +0 -146
  157. package/docs/superpowers/specs/2026-09-14-issue-113-foreground-preview-race-design.md +0 -116
  158. package/docs/superpowers/specs/2026-09-15-coordinator-pipe-root-normalize-design.md +0 -84
  159. package/docs/superpowers/specs/2026-09-15-lease-publish-eprem-reclaim-design.md +0 -92
  160. package/docs/superpowers/specs/2026-09-18-detach-anchor-reporter-endpoint-design.md +0 -123
  161. package/docs/superpowers/specs/2026-09-20-issue-121-perf-gate-out-of-coverage-design.md +0 -204
  162. package/docs/superpowers/specs/2026-09-23-a5-mid-stream-assertion-design.md +0 -43
  163. package/docs/superpowers/specs/2026-09-23-cwd-browse-tab-drill-design.md +0 -95
  164. package/docs/superpowers/specs/2026-09-23-terminal-query-forwarding-design.md +0 -63
  165. package/docs/superpowers/specs/2026-09-23-unconditional-detach-key-design.md +0 -57
  166. package/docs/superpowers/specs/2026-09-24-control-reconcile-flake-design.md +0 -98
  167. package/docs/superpowers/specs/2026-09-24-probe-attached-clients-design.md +0 -190
  168. package/docs/superpowers/specs/2026-09-29-issue-145-holding-semantic-state-design.md +0 -394
  169. package/docs/superpowers/specs/2026-09-30-board-delete-key-x-y-confirm-design.md +0 -86
  170. package/docs/superpowers/specs/2026-09-30-issue-153-runner-stop-boot-window-design.md +0 -75
  171. package/docs/superpowers/specs/2026-09-30-issue-95-test-discipline-design.md +0 -226
  172. package/docs/superpowers/specs/2026-09-30-publish-dispatch-tag-check-design.md +0 -129
  173. package/docs/superpowers/specs/2026-10-06-attach-settle-scheme-delivery-design.md +0 -196
  174. package/docs/superpowers/specs/2026-10-09-issue-167-attach-middle-paste-design.md +0 -125
  175. package/docs/superpowers/specs/2026-10-09-issue-169-fullscreen-mouse-ownership-design.md +0 -130
  176. package/docs/superpowers/specs/2026-10-10-attach-delete-in-place-design.md +0 -224
  177. package/docs/superpowers/specs/2026-10-10-issue-174-selection-mirror-paste-source-design.md +0 -154
  178. package/docs/superpowers/specs/2026-10-14-issue-170-attach-reply-guard-design.md +0 -195
  179. package/docs/superpowers/specs/2026-10-14-issue-178-accept-registration-race-design.md +0 -287
  180. package/docs/superpowers/specs/2026-10-14-issue-184-snapshot-window-contract-design.md +0 -288
  181. package/docs/superpowers/specs/2026-10-14-issue-185-attach-wheel-alt-screen-design.md +0 -126
  182. package/docs/superpowers/specs/2026-10-14-issue-187-motionless-drag-design.md +0 -269
  183. package/docs/superpowers/specs/2026-10-14-issue-189-mixed-input-segments-design.md +0 -369
  184. package/docs/superpowers/specs/2026-10-15-issue-188-x10-mouse-release-design.md +0 -252
  185. package/docs/superpowers/specs/2026-10-16-issue-198-attach-wheel-forward-fallback-design.md +0 -67
  186. package/docs/superpowers/specs/2026-10-18-attach-wheel-replay-pseudo-scrollback-design.md +0 -250
  187. package/docs/superpowers/specs/2026-10-19-issue-213-reply-guard-csi-key-design.md +0 -165
  188. package/docs/superpowers/specs/2026-10-19-issue-214-attach-forward-alt-modifier-design.md +0 -131
  189. package/docs/superpowers/specs/2026-10-20-issue-221-ask-user-question-design.md +0 -270
  190. package/docs/superpowers/specs/2026-10-22-issue-225-monotonic-foreground-state-design.md +0 -225
  191. package/docs/superpowers/specs/2026-10-23-issue-222-attach-ready-design.md +0 -204
  192. package/docs/superpowers/specs/2026-10-23-issue-229-vim-jkl-design.md +0 -90
  193. package/docs/superpowers/specs/2026-10-23-issue-232-attach-bg-only-cells-design.md +0 -146
  194. package/docs/superpowers/specs/2026-10-23-lease-heartbeat-staleness-design.md +0 -271
  195. package/docs/superpowers/specs/2026-10-23-selected-row-highlight-design.md +0 -191
  196. package/docs/superpowers/specs/2026-10-24-issue-217-windows-pid-reuse-stopping-design.md +0 -334
  197. package/docs/superpowers/specs/2026-10-24-issue-230-warm-host-background-runs-design.md +0 -283
  198. package/docs/superpowers/specs/2026-10-24-issue-238-windows-process-identity-token-design.md +0 -286
  199. package/docs/superpowers/specs/2026-10-24-issue-241-coordinator-root-exit-design.md +0 -381
  200. package/docs/superpowers/specs/2026-10-25-issue-239-coordinator-replacement-identity-design.md +0 -331
  201. package/docs/superpowers/specs/2026-10-26-issue-245-key-hints-doc-sync-design.md +0 -72
  202. package/docs/superpowers/specs/2026-10-27-issue-172-fullscreen-selection-clear-design.md +0 -248
  203. package/docs/superpowers/specs/2026-10-27-issue-252-select-key-hints-design.md +0 -95
  204. package/docs/superpowers/specs/2026-10-28-issue-255-coordinator-endpoint-zombie-design.md +0 -380
  205. package/docs/superpowers/specs/2026-10-28-issue-257-legacy-pty-runner-endpoint-cleanup-design.md +0 -197
  206. package/docs/superpowers/specs/2026-11-03-cwd-favorites-full-pool-design.md +0 -106
  207. package/scripts/budget-audit.mjs +0 -135
  208. package/scripts/release.mjs +0 -446
  209. package/scripts/release_helper.mjs +0 -309
  210. package/scripts/run-perf-gate.mjs +0 -40
  211. package/scripts/run-tests.mjs +0 -375
@@ -1,146 +0,0 @@
1
- # Detach-Gate Tier-2 Glyph Fallback Tightening Implementation Plan
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Tighten the attach-surface `←` detach gate's tier-2 glyph fallback so content glyph lines (markdown table rows / quotes / drafts) no longer trap the user when `editor_state` is unavailable (issue #69).
6
-
7
- **Architecture:** One-line condition change in `PtyAttachComponent.childInputLooksEmpty()` (src/ui/pty-attach.ts): the tier-2 loop now only treats an EMPTY prompt-glyph line as proof of an empty editor (`isProbablyPiInputLine(line) && isProbablyEmptyPiInputLine(line)`), skipping content glyph lines; loop-end escape stays authoritative. Tier-1 (inverse fake-cursor anchor), the `editor_state` authoritative path (#71), and all protocol/public API surfaces are untouched. Behavior is pinned by two new detach-gate smoke scenarios (K1/K2) asserted inside the existing `test/pty-attach-detach-gate.test.mjs` case.
8
-
9
- **Tech Stack:** TypeScript (Node `--experimental-transform-types`), node:test, @xterm/headless in-memory smoke harness.
10
-
11
- **Spec:** `docs/superpowers/specs/2026-09-03-detach-gate-glyph-fallback-design.md` (accepted 2026-09-03, Option B).
12
-
13
- **Acceptance traceability:** Task 1 → A1, A2, A3, A4 (automated). Task 2 → U1, U2 (manual, human-executed after push, before merge). No orphan tasks, no orphan acceptance IDs.
14
-
15
- ## Global Constraints
16
-
17
- - Work only inside this worktree: `/home/elling/git-repo/github/pi-agent-board/.pi/worktrees/issue-69-detach-gate-glyph-fallback`. Never edit the main checkout at `/home/elling/git-repo/github/pi-agent-board` (`node_modules` there is only the read-only symlink target).
18
- - Commit messages: English, conventional commits, suffix `(issue #69)`.
19
- - Stage files explicitly (`git add <file> ...`); never `git add -A`.
20
- - Do NOT touch: tier-1 inverse anchor, `editor_state` path (`resolveEditorEmpty`, reporter, runner), README.md, or the pure helpers in `src/core/pty-input.mjs` (spec non-goals).
21
- - Do NOT extract new pure functions — the tightened tier-2 is constant-true by design; the discriminating tests live at smoke level (spec §4).
22
- - Every new online-gate smoke scenario MUST pin `connected=true` explicitly before `handleInput` (B-section convention; otherwise the disconnected-escape semantics fire instead of the online gate).
23
- - `node --test` case count stays 437: the new smoke keys are assertions inside the existing test case in `test/pty-attach-detach-gate.test.mjs`, not new `test()` blocks.
24
- - Verification commands: `npm test` (expect 437 pass, 0 fail) and `npm run typecheck` (expect 0 errors). Faster smoke-only loop: `node --experimental-transform-types test-support/detach-gate-smoke.ts` (prints a JSON of scenario keys).
25
-
26
- ---
27
-
28
- ### Task 1: Tighten tier-2 glyph fallback (TDD) — covers A1, A2, A3, A4
29
-
30
- **Files:**
31
- - Modify: `src/ui/pty-attach.ts` (the tier-2 loop inside `childInputLooksEmpty()`, right after the `// Fallback: Pi variants that render no fake cursor` comment, line 359)
32
- - Test: `test-support/detach-gate-smoke.ts` (insert two scenarios after the J-scenario block, before the `// E2.` comment)
33
- - Test: `test/pty-attach-detach-gate.test.mjs` (two assertions after the `leftHelloNullResetsStaleEditorState` assertion)
34
-
35
- **Interfaces:**
36
- - Consumes: `isProbablyPiInputLine(line)`, `isProbablyEmptyPiInputLine(line)` from `src/core/pty-input.mjs` (both already imported in `pty-attach.ts`); smoke harness helpers `makeAttach()`, `writeToTerm(attach, data)` (already defined in the smoke file).
37
- - Produces: smoke output keys `leftDetachesOnTableRowsWithoutFakeCursor` (A1) and `leftDetachesOnContentGlyphFallback` (A2) in the JSON printed by `test-support/detach-gate-smoke.ts`.
38
-
39
- - [ ] **Step 1: Write the failing smoke scenarios (A1, A2)**
40
-
41
- In `test-support/detach-gate-smoke.ts`, insert these two blocks immediately BEFORE the line starting with `// E2. A terminal at the minimum supported size`:
42
-
43
- ```ts
44
- // K1. Issue #69 real-world shape: zero inverse cells anywhere in the buffer,
45
- // the chat area carries a markdown table row (`│ … │`) and a quote line
46
- // (`> …`) that isProbablyPiInputLine misreads as a draft-bearing input line,
47
- // and editor_state never arrives (editorEmpty stays null — child without the
48
- // reporter). tier-2 must skip content glyph lines and ← must detach: the
49
- // gate philosophy is "never trap the user" (issues #42/#48).
50
- {
51
- const { attach, sent, didDetach } = makeAttach();
52
- await writeToTerm(attach, "chat content\r\n│ Issue #778 │ open │\r\n> quote line\r\n");
53
- (attach as unknown as { connected: boolean }).connected = true;
54
- attach.handleInput("\x1b[D");
55
- out.leftDetachesOnTableRowsWithoutFakeCursor = didDetach() && sent.length === 1 && sent[0].type === "detach";
56
- attach.dispose();
57
- }
58
-
59
- // K2. The deliberate flip side of K1 — pair with scenario B: the SAME draft
60
- // shape (`> draft`) is gated when the fake cursor is present (tier-1, scenario
61
- // B) but detaches when the buffer carries no inverse cells (tier-2 fallback
62
- // cannot tell a real draft from a table row; a spurious detach beats a trapped
63
- // user, and detach never loses the draft — the child session keeps running).
64
- // This pins the intentional loss of fallback draft protection (issue #69);
65
- // restoring it needs the mid-term dock-structure anchor, not a revert.
66
- {
67
- const { attach, sent, didDetach } = makeAttach();
68
- await writeToTerm(attach, "chat content\r\n> draft\r\n");
69
- (attach as unknown as { connected: boolean }).connected = true;
70
- attach.handleInput("\x1b[D");
71
- out.leftDetachesOnContentGlyphFallback = didDetach() && sent.length === 1 && sent[0].type === "detach";
72
- attach.dispose();
73
- }
74
- ```
75
-
76
- In `test/pty-attach-detach-gate.test.mjs`, insert these two assertions immediately AFTER the `assert.equal(parsed.leftHelloNullResetsStaleEditorState, true, ...)` line:
77
-
78
- ```js
79
- assert.equal(parsed.leftDetachesOnTableRowsWithoutFakeCursor, true, "← must detach when a zero-inverse buffer holds only table/quote glyph lines and editor_state is unknown (issue #69)");
80
- assert.equal(parsed.leftDetachesOnContentGlyphFallback, true, "← must detach on a content glyph line in the no-fake-cursor fallback — spurious detach beats trapping (issue #69)");
81
- ```
82
-
83
- - [ ] **Step 2: Run to verify both fail (A1, A2 red)**
84
-
85
- Run: `node --experimental-transform-types test-support/detach-gate-smoke.ts`
86
- Expected: JSON contains `"leftDetachesOnTableRowsWithoutFakeCursor":false` and `"leftDetachesOnContentGlyphFallback":false` (all pre-existing keys stay `true`).
87
-
88
- - [ ] **Step 3: Implement the tier-2 tightening (minimal change)**
89
-
90
- In `src/ui/pty-attach.ts`, inside `childInputLooksEmpty()`, replace this exact block:
91
-
92
- ```ts
93
- // Fallback: Pi variants that render no fake cursor — look for a
94
- // prompt-glyph line.
95
- for (let y = active.baseY + active.length - 1; y >= active.baseY; y--) {
96
- const line = active.getLine(y)?.translateToString(true) ?? "";
97
- if (isProbablyPiInputLine(line)) return isProbablyEmptyPiInputLine(line);
98
- }
99
- ```
100
-
101
- with:
102
-
103
- ```ts
104
- // Fallback: Pi variants that render no fake cursor — look for an EMPTY
105
- // prompt-glyph line. Only an empty glyph line proves an empty editor:
106
- // content glyph lines (markdown table rows `│ … │`, quotes `> …`, or a
107
- // real draft in a no-fake-cursor Pi variant) cannot be told apart, and
108
- // trapping the user is worse than a spurious detach (issue #69) — skip
109
- // them and keep scanning; the loop-end escape below stays authoritative.
110
- for (let y = active.baseY + active.length - 1; y >= active.baseY; y--) {
111
- const line = active.getLine(y)?.translateToString(true) ?? "";
112
- if (isProbablyPiInputLine(line) && isProbablyEmptyPiInputLine(line)) return true;
113
- }
114
- ```
115
-
116
- - [ ] **Step 4: Run smoke to verify the fix (A1, A2 green)**
117
-
118
- Run: `node --experimental-transform-types test-support/detach-gate-smoke.ts`
119
- Expected: EVERY key in the JSON is `true`, including the two new ones.
120
-
121
- - [ ] **Step 5: Full automated acceptance (A3, A4)**
122
-
123
- Run: `npm test`
124
- Expected: `pass 437`, `fail 0` (count unchanged — the new keys are assertions inside the existing test case).
125
-
126
- Run: `npm run typecheck`
127
- Expected: exit 0, no output errors.
128
-
129
- - [ ] **Step 6: Commit**
130
-
131
- ```bash
132
- git add src/ui/pty-attach.ts test-support/detach-gate-smoke.ts test/pty-attach-detach-gate.test.mjs
133
- git commit -m "fix: tighten ← detach tier-2 glyph fallback to empty-only lines (issue #69)"
134
- ```
135
-
136
- ### Task 2: Manual verification U1/U2 (human-executed; after PR branch is pushed, before merge) — covers U1, U2
137
-
138
- > Not a subagent task. The controller surfaces this checklist to the human partner at the pre-merge gate.
139
-
140
- **Environment:** the running extension copy is the git-source clone at `~/.pi/agent/git/github.com/zhuxixi/pi-agent-board` (currently at 0.5.1 / fac9e91). Steps:
141
-
142
- - [ ] **Step 1:** `git -C ~/.pi/agent/git/github.com/zhuxixi/pi-agent-board fetch origin && git -C ~/.pi/agent/git/github.com/zhuxixi/pi-agent-board checkout issue-69-detach-gate-glyph-fallback`
143
- - [ ] **Step 2:** Restart pi IN ANOTHER TERMINAL (restarting kills the session running this agent — do not run inside the controlling session's pi instance).
144
- - [ ] **Step 3 (U1):** Open dashboard → attach a warm session whose chat area contains markdown table output (`│ … │` rows) → with an empty input box press `←`. Pass = returns to dashboard, not trapped.
145
- - [ ] **Step 4 (U2):** In the same or another reporter-active hosted session, type a draft → press `←`. Pass = cursor moves left inside the draft, no detach (same as #67 U3).
146
- - [ ] **Step 5:** `git -C ~/.pi/agent/git/github.com/zhuxixi/pi-agent-board checkout main` and restart pi to restore the running copy.
@@ -1,209 +0,0 @@
1
- # Evidence outputPreview Extraction Implementation Plan
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Fix `evidence.json` `commands[].outputPreview` storing `[object Object]` for bash tool results by extracting text from pi's `AgentToolResult.content` blocks (issue #41).
6
-
7
- **Architecture:** New pure function `toolResultText(result)` in `src/core/heuristics.mjs` (symmetric with existing `assistantText`); `reduceEvidence` bash branch swaps `String(event.result ?? "")` for it. No data-structure changes, no migration.
8
-
9
- **Tech Stack:** Node.js ESM, `node:test`, JSDoc types checked by `tsc --noEmit`.
10
-
11
- **Spec:** `docs/superpowers/specs/2026-09-04-evidence-outputpreview-design.md` (acceptance IDs A1/A2/A3/U1 referenced below).
12
-
13
- ## Global Constraints
14
-
15
- - All edits under worktree `$WT=/home/elling/git-repo/github/pi-agent-board/.pi/worktrees/issue-41-evidence-outputpreview-object`; git via `git -C $WT` — never touch main checkout.
16
- - `toolResultText` must stay a pure function with zero side effects; do NOT inline it into `reduceEvidence` (spec §3 hard constraint).
17
- - Unknown-shaped objects must yield `""`, never `"[object Object]"` (spec D2, #40's 宁可不显示也不错显示 principle).
18
- - Legacy string `result` must keep passing through unchanged (spec D5).
19
- - Do NOT change the 500-char truncate, `EvidenceCommand` shape, other tools' branches, or powershell handling (spec §5 non-goals).
20
- - Stage files individually with `git -C $WT add <file>`; never `git add -A`.
21
- - Full gate per task end: `npm run verify` (typecheck + test + coverage + pack:dry). Never `npm test -- <file>` (glob expands to full suite anyway).
22
-
23
- ---
24
-
25
- ### Task 1: `toolResultText` pure function (acceptance: A1)
26
-
27
- **Files:**
28
- - Modify: `src/core/heuristics.mjs` (after `assistantText`, line ~26)
29
- - Test: `test/heuristics.test.mjs`
30
-
31
- **Interfaces:**
32
- - Produces: `toolResultText(result: any): string` — exported from `src/core/heuristics.mjs`. Task 2 imports it in `src/core/evidence.mjs`.
33
- - Behavior table (spec D2): `null/undefined → ""`; `string → passthrough`; object with `content` array → text blocks `join("\n")` trimmed; object without content/text → `""`; number/bool → `String()`.
34
-
35
- - [ ] **Step 1: Write the failing tests**
36
-
37
- Append to `test/heuristics.test.mjs`, and add `toolResultText` to the existing import block from `../src/core/heuristics.mjs`:
38
-
39
- ```js
40
- test("toolResultText extracts text blocks from AgentToolResult", () => {
41
- const result = {
42
- content: [
43
- { type: "text", text: "line1" },
44
- { type: "image", data: "AAAA", mimeType: "image/png" },
45
- { type: "text", text: "line2" },
46
- ],
47
- details: { fullOutputPath: "/tmp/pi-bash-x.log" },
48
- };
49
- assert.equal(toolResultText(result), "line1\nline2");
50
- });
51
-
52
- test("toolResultText returns empty string for image-only content", () => {
53
- assert.equal(toolResultText({ content: [{ type: "image", data: "AAAA", mimeType: "image/png" }] }), "");
54
- });
55
-
56
- test("toolResultText returns empty string for object without content array", () => {
57
- assert.equal(toolResultText({ details: {} }), "");
58
- assert.equal(toolResultText({}), "");
59
- });
60
-
61
- test("toolResultText passes through plain strings (legacy events)", () => {
62
- assert.equal(toolResultText("ok"), "ok");
63
- });
64
-
65
- test("toolResultText handles nullish and scalar inputs", () => {
66
- assert.equal(toolResultText(null), "");
67
- assert.equal(toolResultText(undefined), "");
68
- assert.equal(toolResultText(42), "42");
69
- assert.equal(toolResultText(true), "true");
70
- });
71
- ```
72
-
73
- - [ ] **Step 2: Run tests to verify they fail**
74
-
75
- Run: `cd $WT && node --test test/heuristics.test.mjs`
76
- Expected: FAIL — `toolResultText is not defined` / import error.
77
-
78
- - [ ] **Step 3: Implement `toolResultText` in `src/core/heuristics.mjs`**
79
-
80
- Insert after the existing `assistantText` function:
81
-
82
- ```js
83
- /**
84
- * Extract text from a pi AgentToolResult object
85
- * ({ content: [{ type: "text", text }, ...], details, ... }), or, defensively,
86
- * a plain string. Unknown-shaped objects yield "" — never "[object Object]"
87
- * (issue #41; mirrors pi's own convertToolResultOutput join("\n") semantics).
88
- * @param {any} result
89
- * @returns {string}
90
- */
91
- export function toolResultText(result) {
92
- if (result == null) return "";
93
- if (typeof result === "string") return result;
94
- if (typeof result !== "object") return String(result);
95
- const content = result.content;
96
- if (!Array.isArray(content)) return "";
97
- return content
98
- .filter((b) => b && b.type === "text" && typeof b.text === "string")
99
- .map((b) => b.text)
100
- .join("\n")
101
- .trim();
102
- }
103
- ```
104
-
105
- - [ ] **Step 4: Run tests to verify they pass**
106
-
107
- Run: `cd $WT && node --test test/heuristics.test.mjs`
108
- Expected: PASS (all 5 new tests + pre-existing suite).
109
-
110
- - [ ] **Step 5: Commit**
111
-
112
- ```bash
113
- git -C $WT add test/heuristics.test.mjs src/core/heuristics.mjs
114
- git -C $WT commit -m "feat: add toolResultText extractor for AgentToolResult content (issue #41)"
115
- ```
116
-
117
- ---
118
-
119
- ### Task 2: `reduceEvidence` bash branch uses `toolResultText` (acceptance: A2, A3)
120
-
121
- **Files:**
122
- - Modify: `src/core/evidence.mjs` (import line 2; bash branch line ~196)
123
- - Test: `test/evidence.test.mjs`
124
-
125
- **Interfaces:**
126
- - Consumes: `toolResultText(result: any): string` from Task 1.
127
- - Produces: unchanged `EvidenceCommand` shape; `outputPreview` now carries extracted text.
128
-
129
- - [ ] **Step 1: Write the failing test (real AgentToolResult shape)**
130
-
131
- In `test/evidence.test.mjs`, inside the existing top-level test that builds `snap` (after the current `b1` end event at line ~24), append:
132
-
133
- ```js
134
- reduceEvidence(snap, { type: "tool_execution_end", toolCallId: "b2", toolName: "bash", isError: false, result: { content: [{ type: "text", text: "https://github.com/zhuxixi/pi-agent-board/pull/45" }] } }, 31);
135
- ```
136
-
137
- and alongside the existing assertions:
138
-
139
- ```js
140
- assert.equal(snap.commands.find((c) => c.id === "b2").outputPreview, "https://github.com/zhuxixi/pi-agent-board/pull/45");
141
- ```
142
-
143
- (The pre-existing `b1` fixture with `result: "ok"` stays untouched — its `outputPreview` passthrough is the D5 regression guard.)
144
-
145
- **Assertion ripple:** the new `b2` command raises the command count. In the same test, update the tail assertion:
146
-
147
- ```js
148
- assert.equal(summary.commandCount, 2);
149
- ```
150
-
151
- (was `assert.equal(summary.commandCount, 1);`)
152
-
153
- - [ ] **Step 2: Run test to verify it fails**
154
-
155
- Run: `cd $WT && node --test test/evidence.test.mjs`
156
- Expected: FAIL — `outputPreview` is `"[object Object]"` instead of the URL.
157
-
158
- - [ ] **Step 3: Modify `src/core/evidence.mjs`**
159
-
160
- Import line (currently):
161
-
162
- ```js
163
- import { assistantText, classifyCommand, toolFileOperation, truncate } from "./heuristics.mjs";
164
- ```
165
-
166
- becomes:
167
-
168
- ```js
169
- import { assistantText, classifyCommand, toolFileOperation, toolResultText, truncate } from "./heuristics.mjs";
170
- ```
171
-
172
- In `reduceEvidence`, `tool_execution_end` → `name === "bash"` branch, replace exactly this line:
173
-
174
- ```js
175
- outputPreview: truncate(String(event.result ?? ""), 500),
176
- ```
177
-
178
- with:
179
-
180
- ```js
181
- outputPreview: truncate(toolResultText(event.result), 500),
182
- ```
183
-
184
- - [ ] **Step 4: Run tests to verify they pass**
185
-
186
- Run: `cd $WT && node --test test/evidence.test.mjs`
187
- Expected: PASS — new assertion green AND legacy `"ok"` fixture still green (D5).
188
-
189
- - [ ] **Step 5: Full verify gate**
190
-
191
- Run: `cd $WT && npm run verify`
192
- Expected: PASS — typecheck, full test suite, coverage, pack:dry all green.
193
-
194
- - [ ] **Step 6: Commit**
195
-
196
- ```bash
197
- git -C $WT add src/core/evidence.mjs test/evidence.test.mjs
198
- git -C $WT commit -m "fix: extract evidence outputPreview from AgentToolResult content (issue #41)"
199
- ```
200
-
201
- ---
202
-
203
- ### Task 3: Post-merge manual verification (acceptance: U1, user-verified)
204
-
205
- **Trigger:** after PR merge + board reloads the new extension on next pi session start.
206
-
207
- - [ ] **Step 1:** In a real pi session, run a few bash commands (e.g. `gh pr create`, `git log`).
208
- - [ ] **Step 2:** Inspect `~/.pi/agent/agent-board/views/<view>/evidence.json`.
209
- - [ ] **Step 3:** Pass criteria: newly recorded bash commands show real output text in `outputPreview` (e.g. the `gh pr create` URL); no new `[object Object]` entries. Record observation result back on issue #41.