yoi/.yoi/tickets/00001KV4YAAVY/thread.md

11 KiB

作成

LocalTicketBackend によって作成されました。


State changed

Ticket を workspace-panel が queued にしました。


Decision

Routing decision: implementation_ready

Reason:

  • Panel Queue により routing が明示的に許可され、Ticket は queued
  • Ticket body / thread / relation / OrchestrationPlan / Orchestrator workspace state を確認した。blocking relation はなく、planning に戻す concrete missing information はない。
  • 対象は single-Pod conversation View の text-like Item selection/copy に限定され、Panel row selection とは scope が分かれている。
  • Tool/non-text Item と copy target は implementation-time decision として許容されており、binding invariants / acceptance criteria / escalation conditions が明確。

Evidence checked:

  • Ticket body/thread: requirements、copy target、tool/non-text handling、acceptance criteria、non-goals、related work を確認。
  • Ticket relations: 00001KV072V8900001KV10SN02 は related のみで blocker ではない。
  • OrchestrationPlan: 既存 record なし。
  • Orchestrator workspace: /home/hare/Projects/yoi/.worktree/orchestration は clean、f0de8413 上。
  • Visible Pods: implementation child Pod なし。Intake peer は routing blocker ではない。
  • Bounded code map: crates/tui/src/single_pod.rs、copy/clipboard abstraction、mouse/selection/key handling tests。

IntentPacket:

Intent:

  • single-Pod TUI conversation View で User/System/Assistant など text-like Item の表示テキストを mouse drag で選択し、y で copy、Esc で clear できるようにする。

Binding decisions / invariants:

  • 対象は single-Pod View Item text。Panel Ticket/Pod row selection は変更しない。
  • terminal-native text selection preservation は non-goal。View drag は Yoi text selection として扱う。
  • selected/copy text、selection state、clipboard diagnostics は Pod history / model context / session log / Ticket records に残さない。
  • composer input、scroll、rewind picker、modal/popup、normal key handling と衝突させない。
  • bare Panel row mouse selection semantics は regress させない。
  • Tool/non-text Item handling と copy target は実装報告または decision comment に明示する。

Requirements / acceptance criteria:

  • UserItem / SystemItem / AssistantItem text を drag selection できる。
  • drag start/update/release 後に selection state が残り、View 上で highlight される。
  • Esc で selection clear。
  • y で selected text を copy し、selection clear。
  • text-like Item を跨いだ selection が deterministic separator で copy される。
  • non-text/tool item handling decision が明示され、test で固定される。
  • copy 成功/失敗が user-visible で、secret-like diagnostics を出さない。
  • tests cover coordinate mapping、selection state、multi-item extraction、Esc、copy+clear、non-text/tool handling。

Implementation latitude:

  • Existing clipboard abstraction があれば利用。なければ testable な最小 copy path を追加してよい。
  • OSC52/system clipboard/internal copy buffer の選択は既存 TUI architecture に合わせる。
  • rendering/highlight 表現、selection model の internal shape、separator は実装側判断。ただし deterministic にする。

Escalate if:

  • terminal/crossterm event stream で必要な drag/release を識別できない。
  • existing rendering model から text coordinate mapping を安全に取れない。
  • copy target を追加すると secrets/history/model-context boundary に影響する。
  • rewind/modal/composer key handling と共存できない大きな model change が必要。

Validation:

  • focused cargo test -p tui ... for single_pod selection/copy。
  • cargo check -p tui --all-targets
  • cargo fmt --check
  • git diff --check
  • Panel row mouse selection regression test if related mouse plumbing is touched。

Critical risks / reviewer focus:

  • selection/copy state の persistence leakage。
  • mouse coordinate -> rendered text mapping correctness。
  • multi-item extraction ordering/separator。
  • composer/scroll/rewind/modal conflict。
  • clipboard path safety and testability。
  • Panel mouse behavior regression absence。

State changed

Routing decision と accepted implementation plan を記録済み。blocking relation / unresolved OrchestrationPlan blocker はなく、single-Pod View work は同時に開始する Panel composer work と主対象が異なるため、implementation side effects の前に queued -> inprogress acceptance を記録する。


Implementation report

Implementation report from Coder Pod yoi-coder-00001KV4YAAVY:

Commit:

  • 09f5e9d5 feat: add single-pod text selection

Changed files:

  • crates/tui/src/text_selection.rs
    • New transient selection state, coordinate mapping, extraction, and focused tests.
  • crates/tui/src/app.rs
    • Local non-persistent selection state on App.
  • crates/tui/src/ui.rs
    • Selectable history row metadata, highlight rendering, snapshot wiring, selectable/non-text tests.
  • crates/tui/src/single_pod.rs
    • Drag mouse handling, Esc clear, y copy+clear, OSC52 copy, tests.
  • crates/tui/src/lib.rs
    • Module registration.
  • crates/tui/Cargo.toml, Cargo.lock
    • Added direct base64 dependency for OSC52 clipboard payloads.

Behavior / implementation decisions:

  • Selectable Items:
    • UserMessage
    • SystemMessage
    • AssistantText
  • Non-text/tool Items:
    • tool calls, thinking, stats, greetings, alerts, turn headers, etc. are not selectable/copyable through this path.
    • extraction skips non-selectable rows.
  • Cross-item selection separator:
    • copied text follows rendered row order and preserves selectable blank spacer rows, giving deterministic \n\n between adjacent text-like Items.
  • Copy target:
    • terminal clipboard via OSC52 (ESC ] 52 ; c ; base64 BEL), not OS clipboard APIs.
    • avoids adding platform clipboard runtime behavior.
  • Copy diagnostics:
    • actionbar-only sanitized messages:
      • success: copied selected text to terminal clipboard
      • failure: terminal clipboard write failed
    • no selected content appears in diagnostics.
  • Selection persistence:
    • selection state/copied text remains TUI-local only.
    • not appended to Pod history, model context, session logs, Ticket records, memory, or durable state.
  • Mouse tracking:
    • single-Pod TUI now enables button-event drag tracking (?1002h) but not all-motion tracking (?1003h).
    • Panel code was not changed.

Validation reported by coder:

  • Passed: cargo fmt --check
  • Passed: cargo check -p tui --all-targets
  • Passed: cargo test -p tui text_selection
  • Passed: cargo test -p tui single_pod::tests
  • Passed: cargo test -p tui ui::tests::history_rows_mark_text_items_selectable_and_non_text_unselectable
  • Passed: git diff --check

Repository status:

  • Child implementation worktree clean after commit.

Residual risks / notes:

  • OSC52 clipboard success means sequence written/flushed; actual clipboard acceptance depends on terminal/multiplexer policy.
  • No real PTY/E2E validation was run; coverage is focused unit-level mouse/key/selection/render extraction behavior.

Review: approve

Review result: approve

Evidence checked:

  • Reviewed child worktree only:
    • /home/hare/Projects/yoi/.worktree/00001KV4YAAVY-single-pod-text-selection
    • diff 368249d6..09f5e9d5
    • Ticket record/thread in the child worktree
  • Read-only validation:
    • Passed: git diff --check 368249d6..09f5e9d5

Implementation review:

  • TUI-local selection state was added in crates/tui/src/text_selection.rs and wired into single-Pod rendering/input.
  • Mouse drag maps terminal coordinates through HistoryViewport into rendered history rows.
  • Drag start/update/release are handled in single_pod.rs; selection remains active after release.
  • Esc clears selection before normal composer handling.
  • bare y copies only when a selection exists; otherwise composer input remains available.
  • Highlighting is applied through range_for_row and highlight_line_selection.
  • Selectable item boundary is explicit:
    • selectable: UserMessage, SystemMessage, AssistantText
    • non-selectable: tool calls, thinking, notices, stats, greetings, etc.
  • Tool/non-text rows are marked unselectable and extraction skips unselectable rows.
  • Cross-item extraction is deterministic, with documented newline/blank-line behavior.
  • Copy uses OSC52; selected text is base64 encoded before writing the OSC52 sequence.
  • Copy diagnostics are generic/actionbar-local and do not include selected content.
  • Selection state lives in TUI-local App.text_selection; no path was found that appends selected/copied text to Pod history, model context, session log, Ticket records, memory, or durable state.
  • Mouse capture changes are limited to single-Pod fullscreen setup and avoid all-motion ?1003h; Panel/multi-pod mouse row selection code was not modified.
  • Composer, scroll, rewind picker, completion/key routing, and normal key handling interactions were inspected and no blocker found.

Coverage reviewed:

  • coordinate mapping
  • drag update/release state
  • multi-row / separator extraction
  • non-selectable row skipping
  • Esc clear
  • copy helper + clear
  • UI selectable/non-selectable marking
  • mouse capture mode avoiding all-motion tracking

Non-blocking notes:

  • No PTY/E2E validation was run; terminal-specific OSC52/mouse behavior still depends on real terminal behavior.
  • OSC52 cannot acknowledge terminal clipboard acceptance; implementation can only report write/flush success/failure.
  • There is no explicit byte-size cap on OSC52 payload, but selection is bounded by visible rendered viewport rather than arbitrary full history traversal. Future hard cap/error notice would be reasonable hardening.
  • A full fixture test constructing an actual Block::ToolCall could strengthen coverage, but the non-text path is explicit and source-inspected.

Validation not rerun by reviewer:

  • Cargo validation was not rerun because review scope was read-only and Cargo writes build artifacts. Coder-reported validation was inspected as evidence.

Conclusion:

  • Approved. No blocker remains.