Skip to content

refactor: migrate CLI off the v1 socket protocol#74

Merged
arzafran merged 1 commit into
mainfrom
refactor/cli-v2-migration
Jul 8, 2026
Merged

refactor: migrate CLI off the v1 socket protocol#74
arzafran merged 1 commit into
mainfrom
refactor/cli-v2-migration

Conversation

@arzafran

@arzafran arzafran commented Jul 8, 2026

Copy link
Copy Markdown
Member

What this does

The CLI (programa command) was still talking v1 (a plain-text line protocol) for about 20 commands, while the rest of it already speaks v2 (JSON-RPC). This finishes that migration: every remaining CLI dispatch case, plus the internal Claude/Codex hook helpers, now goes through v2. Nothing changes for users — same flags, same printed output, same exit codes — only the wire protocol underneath. This is step 2 of the v1-deletion sequence (v1 handlers themselves are untouched and still serve tests/ and shell integration until they migrate too).

Summary

  • Deleted sendV1Command/forwardSidebarMetadataCommand in CLI/programa.swift. Every call site now builds a client.sendV2(method:params:) request and reconstructs the old plain-text output from the v2 JSON result, so CLI output stays byte-identical.
  • Added the small number of v2 methods that were still missing in Sources/TerminalController.swift (additive only — v1 handlers untouched):
    • workspace.set_agent_pid
    • workspace.report_meta_block / workspace.clear_meta_block / workspace.list_meta_blocks
    • workspace.reset_sidebar
    • notification.clear gained an optional workspace_id param (previously global-only) so clear-notifications --workspace X and the Claude/Codex hook cleanup paths can scope to one workspace instead of wiping every workspace's notifications.
  • report_meta/clear_meta/list_meta needed no new v2 method — their v1 handlers are themselves aliases of set_status/clear_status/list_status. read_screen needed no new method — surface.read_text (added in an earlier PR) already covers its scrollback/lines semantics.
  • Updated docs/v2-api-migration.md's parity checklist and status log.

CLI command → v2 method

CLI command v2 method(s)
ping system.ping
list-windows window.list
current-window window.current
new-window window.create
focus-window window.focus
close-window window.close
drag-surface-to-split surface.drag_to_split
refresh-surfaces surface.refresh
reload-config app.reload_config
notify notification.create_for_target
list-notifications notification.list
clear-notifications notification.clear
set-app-focus app.focus_override.set
simulate-app-active app.simulate_active
set-status workspace.set_status
clear-status workspace.clear_status
list-status workspace.list_status
set-progress workspace.set_progress
clear-progress workspace.clear_progress
log workspace.log
clear-log workspace.clear_log
list-log workspace.list_log
sidebar-state workspace.sidebar_state
claude-hook/codex-hook internals (status/pid/notify helpers) workspace.set_status/clear_status, workspace.set_agent_pid/clear_agent_pid, notification.create_for_target, notification.clear

New v2 methods added

  • workspace.set_agent_pid
  • workspace.report_meta_block
  • workspace.clear_meta_block
  • workspace.list_meta_blocks
  • workspace.reset_sidebar
  • (notification.clear extended with an optional workspace_id, not new but changed)

Couldn't / didn't migrate

  • Nothing in scope was left on v1. Everything the CLI itself calls now goes through v2.
  • client.send(command: "auth ...") (password auth) is untouched — it wasn't part of the inventoried verb list and touching auth felt out of scope for a "same behavior, different wire protocol" PR.
  • v1 handlers in TerminalController.swift are intentionally untouched (per the task's off-limits list) — tests/ and Resources/shell-integration/ still call v1 directly and migrate in a follow-up PR, at which point v1 removal becomes safe.

Test Plan

  • xcodebuild -scheme programa -configuration Debug build → BUILD SUCCEEDED
  • xcodebuild -scheme programa-cli -configuration Debug build → BUILD SUCCEEDED
  • xcodebuild -scheme programa-unit -configuration Debug build-for-testing → TEST BUILD SUCCEEDED
  • CI (python tests_v2/ suites exercise the CLI's v2-backed commands end-to-end)

Rewires the last v1 socket call sites in the CLI (window/surface commands,
notifications, sidebar-metadata family, Claude/Codex hook helpers) onto v2
JSON-RPC, and adds the handful of v2 methods that were still missing for full
parity. CLI flags, output text, and exit codes are unchanged for users — only
the wire protocol underneath changed.

- sendV1Command / forwardSidebarMetadataCommand are deleted; every dispatch
  case now calls client.sendV2(method:params:) and reconstructs the old
  plain-text output from the v2 JSON result client-side.
- Added workspace.set_agent_pid, workspace.report_meta_block,
  workspace.clear_meta_block, workspace.list_meta_blocks, and
  workspace.reset_sidebar to TerminalController.swift (v1 handlers untouched).
  report_meta/clear_meta/list_meta needed no new method — they're v1 aliases
  of set_status/clear_status/list_status. read_screen needed no new method —
  surface.read_text already covers it.
- notification.clear gained an optional workspace_id so clear-notifications
  (and the Claude/Codex hook cleanup paths) can still scope to one workspace
  instead of clearing everyone's notifications.

Part of the v1-deletion sequence (see docs/v2-api-migration.md); v1 handlers
in TerminalController.swift are untouched and still serve tests/ and shell
integration, which migrate in a follow-up PR.
@arzafran arzafran merged commit f6bd6a2 into main Jul 8, 2026
8 checks passed
arzafran added a commit that referenced this pull request Jul 8, 2026
v2 JSON-RPC is now the only socket protocol. All consumers were migrated
first (CLI in #74, shell integration in #72, tests in #71/#73; the remote
daemon was already v2-only), so this deletes the v1 line dispatch itself
and everything that only existed to serve it.

- TerminalController.processCommand now dispatches JSON unconditionally;
  a non-JSON line gets a terse v1_removed error instead of being routed
  to the old space-delimited command switch.
- Deletes the v1 switch (~90 cases) and every handler function that
  becomes unreferenced, plus their v1-only parsing helpers
  (parseOptions/parseOptionsNoStop, resolveTabForReport,
  withReportTargetSurface, upsertSidebarMetadata/clearSidebarMetadata/
  listSidebarMetadata, schedulePanelMetadataMutation,
  parseReadScreenArgs). Debug handlers that v2's debug.* methods reuse
  as their implementation core (setShortcut, simulateShortcut,
  activateApp, isTerminalFocused, readTerminalText, renderStats,
  layoutDebug, bonsplit/empty-panel/flash counters,
  focusFromNotification, panelSnapshot(Reset), captureScreenshot) are
  kept, since they're still live v2 entry points, not v1 relics.
  Self.socketFastPathState and tailTerminalLines/
  readTerminalTextBase64(terminalPanel:) stay too - v2 surface-telemetry
  and screen-read methods depend on them directly.
- auth was already a connection-level preamble (authResponseIfNeeded,
  handled before any protocol dispatch) supporting both a raw
  auth-plus-password line and v2 auth.login; only the CLI's raw-line
  call needed migrating, which this does (auth.login now).
- Removes the now-unreachable isV2:false focus-intent allowlist
  (focusIntentV1Commands) and updates the one unit test that exercised
  it directly to cover the v2 equivalent instead.
- Docs: v2-api-migration.md collapses to a short removal note plus the
  v1->v2 name mapping (kept for reference); socket-focus-steal-audit.todo.md
  and agent-browser-port-spec.md get historical annotations; CLAUDE.md's
  socket-threading-policy examples are reworded to v2 method names.

TerminalController.swift: 12834 -> 9615 lines (-3219). Net repo diff:
+156/-3410 across 7 files.

Breaking change: any external script or tool that still speaks the old
space-delimited socket protocol directly (rather than through the CLI)
will now get a v1_removed JSON error instead of a response. Use the CLI
or the v2 JSON-RPC protocol described in docs/v2-api-migration.md.
@arzafran arzafran deleted the refactor/cli-v2-migration branch July 10, 2026 16:04
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