Skip to content

fix: migrate coder-tui remote runtime for Pi v0.65#1351

Merged
rblalock merged 1 commit intomainfrom
fix/pi-v0.65-session-runtime
Apr 7, 2026
Merged

fix: migrate coder-tui remote runtime for Pi v0.65#1351
rblalock merged 1 commit intomainfrom
fix/pi-v0.65-session-runtime

Conversation

@rblalock
Copy link
Copy Markdown
Member

@rblalock rblalock commented Apr 4, 2026

related: https://github.com/agentuity/coder/pull/20

Summary

  • migrate @agentuity/coder-tui remote mode to Pi's AgentSessionRuntime model
  • pass a runtime, not a raw session, into InteractiveMode
  • keep remote controller mode scoped to the current sandbox-backed Hub session only
  • explicitly block controller-side /new, /resume, /fork, and /import with cancelled: true plus a user-facing warning
  • remove reliance on Pi's removed session_switch and session_fork extension events
  • add regression coverage for the remote runtime event hook and the blocked session-management operations
  • bump the Pi dependencies in packages/coder-tui to ^0.65.0

Why

Pi v0.65.0 moved interactive session management onto AgentSessionRuntime, so the old new InteractiveMode(session) path was no longer valid.

This PR keeps the remote TUI aligned with the product model we actually want:

  • one Hub session per sandbox
  • remote attach controls the current sandbox session only
  • remote controller mode is not a Pi session browser

Because of that, the migration intentionally blocks controller-side session replacement operations instead of letting them mutate a local in-memory mirror that would diverge from the sandbox source of truth.

Validation

  • bun run --filter='./packages/coder-tui' typecheck
  • bun run --filter='./packages/coder-tui' build
  • bun test packages/coder-tui/test
  • paired live validation with the Hub change:
    • remote CLI attach to a live sandbox-backed session
    • remote controller reconnect to the same session
    • local agentuity coder start still booting Pi v0.65.0

Notes

  • remote dispatch currently goes through Pi's private AgentSession._handleAgentEvent hook; the new regression test fails loudly if upstream changes that hook again
  • future fork support, if we add it, should be modeled as a new sandbox plus a new Hub session rather than multiple Pi sessions inside one sandbox

Summary by CodeRabbit

Release Notes

  • Dependencies

    • Updated package dependencies to v0.65.0
  • New Features

    • Added remote runtime operation blocking for session controllers
    • Enhanced remote event dispatch mechanism for improved session event handling
  • Changes

    • Modified session lifecycle event forwarding behavior
  • Tests

    • Added comprehensive test coverage for remote runtime functionality

@agentuity-agent
Copy link
Copy Markdown

agentuity-agent bot commented Apr 4, 2026

The latest Agentuity deployment details.

Project Deployment Preview Updated (UTC)
docs 🟢 Ready (deploy_a961150790d3664e10fbd9ca9ef0339b) - 2026-04-04T22:21:30Z

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 4, 2026

📝 Walkthrough

Walkthrough

The changes update dependencies to ^0.65.0, refactor session management from createAgentSession to createAgentSessionRuntime, remove certain event proxies, add remote runtime operation blocking, and introduce utilities for remote session event dispatching with corresponding tests.

Changes

Cohort / File(s) Summary
Dependency Updates
packages/coder-tui/package.json
Bumped @mariozechner/pi-coding-agent, @mariozechner/pi-tui, and @mariozechner/pi-ai from ^0.64.0 to ^0.65.0.
Event Proxy Configuration
packages/coder-tui/src/index.ts
Removed session_switch and session_fork entries from PROXY_EVENTS, retaining only "before" variants for session lifecycle event forwarding.
Remote Runtime Utilities
packages/coder-tui/src/remote-runtime.ts
New module exporting REMOTE_RUNTIME_OPERATION_MESSAGE, dispatchRemoteSessionEvent() for forwarding RpcEvents to sessions, and installRemoteRuntimeOperationGuards() for blocking runtime operations.
Session Management Refactoring
packages/coder-tui/src/remote-tui.ts
Migrated from createAgentSession to createAgentSessionRuntime-backed architecture; replaced direct event emission with dispatchRemoteSessionEvent(); added operation blocking via guards; implemented explicit disposeRuntime() cleanup in signal handlers and finally blocks.
Remote Runtime Tests
packages/coder-tui/test/remote-runtime.test.ts
New test suite validating dispatchRemoteSessionEvent() forwarding and error handling, and installRemoteRuntimeOperationGuards() blocking behavior for session operations.
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@rblalock rblalock requested a review from jhaynie April 4, 2026 22:13
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 4, 2026

📦 Canary Packages Published

version: 2.0.9-9f43c59

Packages
Package Version URL
@agentuity/webhook 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-webhook-2.0.9-9f43c59.tgz
@agentuity/auth 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-auth-2.0.9-9f43c59.tgz
@agentuity/email 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-email-2.0.9-9f43c59.tgz
@agentuity/evals 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-evals-2.0.9-9f43c59.tgz
@agentuity/migrate 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-migrate-2.0.9-9f43c59.tgz
@agentuity/core 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-core-2.0.9-9f43c59.tgz
@agentuity/sandbox 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-sandbox-2.0.9-9f43c59.tgz
@agentuity/server 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-server-2.0.9-9f43c59.tgz
@agentuity/vector 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-vector-2.0.9-9f43c59.tgz
@agentuity/claude-code 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-claude-code-2.0.9-9f43c59.tgz
@agentuity/keyvalue 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-keyvalue-2.0.9-9f43c59.tgz
@agentuity/postgres 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-postgres-2.0.9-9f43c59.tgz
@agentuity/opencode 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-opencode-2.0.9-9f43c59.tgz
@agentuity/runtime 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-runtime-2.0.9-9f43c59.tgz
@agentuity/db 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-db-2.0.9-9f43c59.tgz
@agentuity/task 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-task-2.0.9-9f43c59.tgz
@agentuity/coder-tui 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-coder-tui-2.0.9-9f43c59.tgz
@agentuity/schema 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-schema-2.0.9-9f43c59.tgz
@agentuity/drizzle 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-drizzle-2.0.9-9f43c59.tgz
@agentuity/coder 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-coder-2.0.9-9f43c59.tgz
@agentuity/frontend 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-frontend-2.0.9-9f43c59.tgz
@agentuity/react 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-react-2.0.9-9f43c59.tgz
@agentuity/cli 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-cli-2.0.9-9f43c59.tgz
@agentuity/schedule 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-schedule-2.0.9-9f43c59.tgz
@agentuity/queue 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-queue-2.0.9-9f43c59.tgz
@agentuity/workbench 2.0.9-9f43c59 https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-workbench-2.0.9-9f43c59.tgz
Install

Add to your package.json:

{
  "dependencies": {
    "@agentuity/webhook": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-webhook-2.0.9-9f43c59.tgz",
    "@agentuity/auth": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-auth-2.0.9-9f43c59.tgz",
    "@agentuity/email": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-email-2.0.9-9f43c59.tgz",
    "@agentuity/evals": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-evals-2.0.9-9f43c59.tgz",
    "@agentuity/migrate": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-migrate-2.0.9-9f43c59.tgz",
    "@agentuity/core": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-core-2.0.9-9f43c59.tgz",
    "@agentuity/sandbox": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-sandbox-2.0.9-9f43c59.tgz",
    "@agentuity/server": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-server-2.0.9-9f43c59.tgz",
    "@agentuity/vector": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-vector-2.0.9-9f43c59.tgz",
    "@agentuity/claude-code": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-claude-code-2.0.9-9f43c59.tgz",
    "@agentuity/keyvalue": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-keyvalue-2.0.9-9f43c59.tgz",
    "@agentuity/postgres": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-postgres-2.0.9-9f43c59.tgz",
    "@agentuity/opencode": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-opencode-2.0.9-9f43c59.tgz",
    "@agentuity/runtime": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-runtime-2.0.9-9f43c59.tgz",
    "@agentuity/db": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-db-2.0.9-9f43c59.tgz",
    "@agentuity/task": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-task-2.0.9-9f43c59.tgz",
    "@agentuity/coder-tui": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-coder-tui-2.0.9-9f43c59.tgz",
    "@agentuity/schema": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-schema-2.0.9-9f43c59.tgz",
    "@agentuity/drizzle": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-drizzle-2.0.9-9f43c59.tgz",
    "@agentuity/coder": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-coder-2.0.9-9f43c59.tgz",
    "@agentuity/frontend": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-frontend-2.0.9-9f43c59.tgz",
    "@agentuity/react": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-react-2.0.9-9f43c59.tgz",
    "@agentuity/cli": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-cli-2.0.9-9f43c59.tgz",
    "@agentuity/schedule": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-schedule-2.0.9-9f43c59.tgz",
    "@agentuity/queue": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-queue-2.0.9-9f43c59.tgz",
    "@agentuity/workbench": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-workbench-2.0.9-9f43c59.tgz"
  }
}

Or install directly:

bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-webhook-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-auth-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-email-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-evals-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-migrate-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-core-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-sandbox-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-server-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-vector-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-claude-code-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-keyvalue-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-postgres-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-opencode-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-runtime-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-db-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-task-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-coder-tui-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-schema-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-drizzle-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-coder-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-frontend-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-react-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-cli-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-schedule-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-queue-2.0.9-9f43c59.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/2.0.9-9f43c59/agentuity-workbench-2.0.9-9f43c59.tgz

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/coder-tui/src/remote-tui.ts (1)

902-927: Cleanup is comprehensive but has potential double-execution.

The signal handler (cleanup) and the finally block both call remote.close() and setNativeRemoteExtensionContext(null). When SIGINT fires, interactive.stop() causes run() to exit, triggering the finally block.

This is likely safe since:

  • WebSocket close() is idempotent
  • setNativeRemoteExtensionContext(null) is idempotent
  • disposeRuntime() has the idempotent guard

However, the signal handler doesn't prevent re-registration, so multiple SIGINT signals could race. Consider this optional improvement:

♻️ Optional: Deduplicate cleanup logic
+	let cleanupStarted = false;
 	const cleanup = () => {
+		if (cleanupStarted) return;
+		cleanupStarted = true;
 		remote.close();
 		setNativeRemoteExtensionContext(null);
 		interactive.stop();
 		void disposeRuntime().catch((err) => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/coder-tui/src/remote-tui.ts` around lines 902 - 927, The signal
handler cleanup and the finally block both call remote.close(),
setNativeRemoteExtensionContext(null), and disposeRuntime(), which can run twice
when SIGINT triggers interactive.stop(); make cleanup idempotent and prevent
double-execution by adding a guarded flag (e.g., cleanupCalled) checked/set
inside the cleanup function and by removing the process.on listeners (or calling
process.off) from within cleanup; update references in remote.close,
setNativeRemoteExtensionContext, interactive.stop, and disposeRuntime usages so
the cleanup function is the single point of teardown and the finally block only
awaits the guarded cleanup (or checks the flag) to avoid duplicate calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/coder-tui/src/remote-tui.ts`:
- Around line 902-927: The signal handler cleanup and the finally block both
call remote.close(), setNativeRemoteExtensionContext(null), and
disposeRuntime(), which can run twice when SIGINT triggers interactive.stop();
make cleanup idempotent and prevent double-execution by adding a guarded flag
(e.g., cleanupCalled) checked/set inside the cleanup function and by removing
the process.on listeners (or calling process.off) from within cleanup; update
references in remote.close, setNativeRemoteExtensionContext, interactive.stop,
and disposeRuntime usages so the cleanup function is the single point of
teardown and the finally block only awaits the guarded cleanup (or checks the
flag) to avoid duplicate calls.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0445b259-b244-47ba-8dab-2721f5293e2a

📥 Commits

Reviewing files that changed from the base of the PR and between 95d2860 and 9f43c59.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • packages/coder-tui/package.json
  • packages/coder-tui/src/index.ts
  • packages/coder-tui/src/remote-runtime.ts
  • packages/coder-tui/src/remote-tui.ts
  • packages/coder-tui/test/remote-runtime.test.ts
💤 Files with no reviewable changes (1)
  • packages/coder-tui/src/index.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: SDK Integration Test Suite
  • GitHub Check: Sandbox CLI Tests
  • GitHub Check: Queue CLI Tests
  • GitHub Check: Queue SDK Tests
  • GitHub Check: Cloud Deployment Tests
  • GitHub Check: Standalone Agent Test
  • GitHub Check: Postgres SSL Integration Test
  • GitHub Check: Template Integration Tests
  • GitHub Check: Framework Integration Tests (TanStack & Next.js)
  • GitHub Check: Playwright E2E Smoke Test
  • GitHub Check: Package Installation & Usage Test
  • GitHub Check: Build
  • GitHub Check: Pack & Upload
  • GitHub Check: Agentuity Deployment
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Biome as code formatter with tabs (width 3), single quotes, semicolons, lineWidth 100, and trailingCommas es5

Files:

  • packages/coder-tui/test/remote-runtime.test.ts
  • packages/coder-tui/src/remote-runtime.ts
  • packages/coder-tui/src/remote-tui.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript Strict mode with ESNext target and bundler moduleResolution
Use StructuredError from @agentuity/core for error handling

Files:

  • packages/coder-tui/test/remote-runtime.test.ts
  • packages/coder-tui/src/remote-runtime.ts
  • packages/coder-tui/src/remote-tui.ts
**/test/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/test/**/*.{ts,tsx}: Place tests in test/ folder, never in src/ or __tests__/ directories
Import from ../src/ in test files
Use @agentuity/test-utils for mocks in tests

Files:

  • packages/coder-tui/test/remote-runtime.test.ts
🧠 Learnings (3)
📚 Learning: 2026-03-27T23:18:58.450Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 1292
File: packages/keyvalue/package.json:3-3
Timestamp: 2026-03-27T23:18:58.450Z
Learning: In the agentuity/sdk monorepo, subpackage `package.json` files under `packages/` (e.g., `packages/keyvalue`) are allowed to depend on other workspace packages (such as `agentuity/server`) and are not limited to only `agentuity/core` and `zod`. Also, if a subpackage uses `bunx tsc --build --force` as its build script, treat it as a valid/intentional build command and do not flag it as a dependency/build-script violation.

Applied to files:

  • packages/coder-tui/package.json
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.

Applied to files:

  • packages/coder-tui/test/remote-runtime.test.ts
  • packages/coder-tui/src/remote-runtime.ts
  • packages/coder-tui/src/remote-tui.ts
📚 Learning: 2026-02-21T02:05:57.982Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 1010
File: packages/drizzle/test/proxy.test.ts:594-603
Timestamp: 2026-02-21T02:05:57.982Z
Learning: Do not rely on StructuredError from agentuity/core in test files or simple error handling paths. In tests and straightforward error handling, use plain Error objects to represent failures, reserving StructuredError for more complex error scenarios in application logic.

Applied to files:

  • packages/coder-tui/test/remote-runtime.test.ts
🔇 Additional comments (9)
packages/coder-tui/src/remote-runtime.ts (1)

1-45: LGTM — Clean utility module for remote runtime guards.

The implementation is well-structured:

  • The explicit runtime check for _handleAgentEvent with a descriptive error message provides a clear failure mode if Pi's internal API changes (as noted in PR objectives).
  • The block closure pattern elegantly creates async guards that return { cancelled: true }.

One minor observation: switchSession maps to /resume in the operation callback, which is intentional per the PR description (blocking controller-side /resume commands).

packages/coder-tui/package.json (1)

28-33: LGTM — Consistent Pi ecosystem version bump to ^0.65.0.

All Pi packages (@mariozechner/pi-coding-agent, @mariozechner/pi-tui, @mariozechner/pi-ai) are bumped in lockstep, which is appropriate for a breaking API migration.

packages/coder-tui/test/remote-runtime.test.ts (1)

1-53: LGTM — Comprehensive test coverage for remote runtime helpers.

The tests effectively cover:

  1. Event dispatch routing through _handleAgentEvent (not agent.emit)
  2. Explicit failure when Pi removes/changes the internal hook
  3. All four blocked operations with correct callback invocation

The use of toThrow('_handleAgentEvent') as a substring match is a good regression guard that will fail if Pi changes the hook name.

packages/coder-tui/src/remote-tui.ts (6)

100-135: Well-structured migration to createAgentSessionRuntime.

The factory callback pattern correctly separates service creation from session initialization:

  • noExtensions: true with explicit extensionFactories ensures controlled extension loading
  • tools: [] appropriately delegates tool execution to the sandbox
  • SessionManager.inMemory() is correct since state comes from the remote session

The destructuring on line 132 clearly shows the relationship: runtime.session is the backing session.


137-150: Operation guard notification is well-integrated with the UI context.

The notifyBlockedRuntimeOperation function:

  • Uses the native remote UI context when available for proper user feedback
  • Falls back to logging when UI isn't ready
  • Sets both notification and status for visibility

The as any cast on line 148 is acceptable here since RemoteRuntimeGuards is a minimal interface for the specific methods being guarded, and Pi's runtime type may include additional properties.


152-156: Good idempotent dispose pattern.

The runtimeDisposed flag correctly prevents double-disposal, which could cause issues if both the signal handler and the finally block attempt cleanup.


164-166: Clean abstraction for event dispatch.

The emitSessionEvent helper provides a single point of control for routing events through dispatchRemoteSessionEvent, which:

  • Enables centralized error handling if the Pi hook changes
  • Makes the code more readable than inline casts at each call site

The as any cast is necessary since the session type from Pi doesn't expose _handleAgentEvent in its public interface.


840-844: Core migration: InteractiveMode now receives runtime instead of session.

This is the primary change required by Pi v0.65.0's move to AgentSessionRuntime. The runtime encapsulates the session plus lifecycle management, which InteractiveMode needs for proper initialization.


4-11: Documentation accurately reflects the architectural change.

The header comments correctly describe:

  • Line 4: AgentSessionRuntime + InteractiveMode (updated from prior session-only model)
  • Line 11: Events flow through AgentSession event handling via dispatchRemoteSessionEvent

This provides good context for future maintainers understanding the remote TUI architecture.

@rblalock
Copy link
Copy Markdown
Member Author

rblalock commented Apr 6, 2026

I merged the Coder app PR related to this fyi.

@rblalock rblalock merged commit a1955d4 into main Apr 7, 2026
18 checks passed
@rblalock rblalock deleted the fix/pi-v0.65-session-runtime branch April 7, 2026 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant