Conversation
A cross-window move keeps the Session instance and TerminalView reuses the cached surface, so no factory re-runs in the destination and every callback kept resolving the session against the source store: shell exit, overlay teardown and exit status, unseen/status clears, search and font size all silently no-oped, and the source store leaked. Extract the per-surface wiring and re-apply it through a new WindowLibrary.rebindAdoptedSession hook. Also route adoptSession(select:) through selectSession so an adopted session arrives with its unseen badge and completed flash cleared, and reject --select without --to-window in both the CLI and the dispatcher instead of dropping it.
…n-move # Conflicts: # .claude/rules/control-api.md # agtermCore/Tests/agtermCoreTests/WindowLibraryTests.swift
|
I want the capability, so this is about the form rather than the idea. Three design questions I cannot resolve from the current form, then a list of review findings which are secondary to them. 1. Ownership addressing this is the first question I cannot resolve. after a move the window selector still resolves, but to the window the session left. the updated SKILL.md shows the shape of this. Lines 58-59 add a warning that a stale I do not see a safe fix confined to the move itself. Is there one that preserves existing scripts? Nothing can rewrite a live process's environment, so any cross-window move leaves a wrong value in a shell agterm itself spawned. The mitigation here is to demote both variables to spawn-time hints and tell every caller to read what I would want first is ownership addressing that cannot go stale. worth knowing, since it narrows the damage: no cookbook recipe is exposed. 2. Parity with cross-workspace move moving a session between workspaces has three entry points today: drag in that is the one I would not leave out, because the drag transport already crosses windows. the batch half is the real work there rather than the plumbing: a multi-row drop has to preserve the block's order at the hovered index, and 3. Scope this is a 48-file, +3465/-887 change covering the move, the ownership read-back, UI, tests and docs. Two separate things make me want to step back from it. Whole-workspace transfer has the same window-addressing problem across every session in the workspace, so it multiplies the exposure even if it reuses the transfer engine. And this change omits the adjacent drag interaction, which is where most of the remaining work sits. I would rather design one transfer that covers sessions and workspaces, with the addressing sorted first, than take the session-only form now and grow it. I am not asking you to make this smaller by trimming tests or docs, and a safe design may well start out bigger. What I am weighing is the permanent cost. on that: transfer duties are spread across surface rebinding, controller eviction, notification move records and store-membership observers. The major below is one missed observer. Store membership carries no removal reason, so transfer and close look identical to every observer, and every future thing holding a session-to-window relationship inherits that. Review findings, secondary to the above fixing these alone would not answer the design questions above. major. Moving a session whose overlay is the keymap or minor. Three surfaces say the move changes neither window's selection, and the source does reselect: minor. The cross-window batch arm at minor. minor. minor. |
A session is pinned to the window it was created in, so splitting work across windows means closing it and starting the process over. This adds moving a session to another open window with its live shell intact.
The move is a transfer of the same
Sessioninstance between twoAppStores, so the surface and its shell survive untouched —dismantleNSViewwas already a no-op andviewDidMoveToWindowalready re-pushes scale and size, so nothing in the AppKit or libghostty layer needed changing.WindowLibraryowns the operation because it spans two stores, and it evicts the session from the source window's zoom and dashboard registries before detaching, so that window can't keep pointing at a surface now hosted elsewhere. On the wire it issession.move --to-window, taking an optional destination workspace inside that window and--selectto make it active there; the destination must already be open, since a closed window has no mounted deck to host the surface. The sidebar row menu and the command palette get matching entries. Cross-window drag stays out of scope, and the strict one-bundle-one-window model is unchanged.Moving a session invalidates the
AGTERM_WINDOW_IDandAGTERM_WORKSPACE_IDits shell was spawned with, and nothing can rewrite a live process's environment — the workspace id already went stale on any ordinary workspace move, with no way to re-read it. The tree now publisheswindowIdandworkspaceIdon every session node, andtree --all-windowsprojects every open window in one response, so a shell can resolve its own current owners in a single call. The skill docs demote both variables to spawn-time hints and point at that query instead.