Skip to content

D-11: Lifecycle integration — TerminalSession ownership for Dialogue #261

@kirich1409

Description

@kirich1409

Description

Integrate the ClaudeCodeJSONLSession adapter's lifecycle with the underlying TerminalSession — ensure the PTY / gRPC session is owned, started, reconnected, and terminated as a pair with the Dialogue session.

Spec: Epic #250 §4.3 (data flow).

Scope

Ownership model

ClaudeCodeJSONLSession owns a TerminalSession instance. Ownership implications:

  • Creating a Dialogue session creates the underlying TerminalSession; terminating Dialogue terminates the terminal.
  • TerminalFeature (the existing reducer) is not used for Dialogue sessions — the Dialogue session goes directly through TerminalEngine.makeSession(configuration:) → no reducer indirection.
  • For .agentDialogue surface, the TerminalSession is registered into sharedTerminalRegistry with a distinct tag so UI can differentiate (useful for Stream Inspector).

Reconnect semantics (remote sessions)

  • When RemoteTerminalSession.connectionState emits .reconnected, the VT-snapshot replay happens as usual. ClaudeCodeJSONLSession observes rawStdout — replay bytes flow in naturally and parser dedupes by session_id + event.index + uuid.
  • If reconnect is impossible (runner drop, auth rotation) → status .error(ReconnectFailed) + UI shows retry banner.

Subagent nesting

  • parent_tool_use_id ≠ null events — parser tags them, reducer routes them to the parent ToolCall.subagentTranscript sub-state (forward decision — nested reducer state inside ToolCall).
  • Lifecycle of subagent is tied to parent tool call — subagent can't outlive parent.

Acceptance Criteria

  • ClaudeCodeJSONLSession.start() spawns terminal process + starts parser consumption in one atomic step.
  • .terminate() cleanly closes terminal, cancels consumer tasks, finishes transcript stream.
  • Process exit mid-turn triggers parser close() + emits .error(UnexpectedExit) to transcript before finishing the stream.
  • Remote reconnect: integration test with mocked gRPC drop → session re-attaches → parser dedupes replayed events → transcript state unchanged.
  • Subagent parent_tool_use_id routing — unit test verifies nested events land in the correct ToolCall subagent sub-state.
  • No leaked tasks or continuations after terminate() (verified by memory / task-counter tests).
  • sharedTerminalRegistry contains the underlying session during its lifetime, removed on terminate.

Relationships

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions