Skip to content

feat: subagent tab bar with fork agents, useTab hook, and FRANKENCODE.md - #34

Merged
e6qu merged 3 commits into
devfrom
feat/subagent-tabs
Mar 22, 2026
Merged

feat: subagent tab bar with fork agents, useTab hook, and FRANKENCODE.md#34
e6qu merged 3 commits into
devfrom
feat/subagent-tabs

Conversation

@e6qu

@e6qu e6qu commented Mar 22, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a tab bar to the TUI for navigating between the main agent, LLM-spawned subagents, and user-created fork agents. Refactors all tab state into a single useTab hook. Consolidates docs into FRANKENCODE.md.

Tab bar (tab.ts + tabbar.tsx)

  • Tab bar at top of session view: Main │ + │ S1 │ S2 │ F1
  • Tab toggles focus between tab bar and chat prompt
  • Left/Right navigates tabs and immediately shows selected session content
  • Enter/Space on + forks Main's conversation history into a new F-labeled child
  • x kills selected agent, Ctrl+C requires double-press to exit (first press aborts + shows hint)
  • Shift+Tab cycles agent type (Build/Plan/etc.)
  • Click on any tab focuses bar and navigates

Fork agents

  • Created via + button — copies Main's full conversation history
  • Yellow-colored tabs (F1, F2), distinct from LLM-spawned subagents (S1, S2)
  • Cannot spawn subagents (task permission denied + system prompt tells LLM)
  • Manually promptable, persist until user kills with x

useTab hook refactor

  • Single source of truth for all tab state (focused, selected, page, hint) and actions (move, cycle, spawn, kill, ctrlc, toggle, blur, activate, click)
  • Replaces ~130 lines of scattered signals and duplicated logic in session/index.tsx
  • tabbar.tsx simplified to pure renderer with single onClick prop
  • Session keyboard handler reduced to 10-line thin dispatcher

Docs

  • Merged FRANKENCODE_DIFFERENCES.md into FRANKENCODE.md — single consolidated doc
  • Updated cross-references in 8 docs to point to FRANKENCODE.md
  • Added tab bar, fork agents, keybinding changes to FRANKENCODE.md
  • Updated agent visibility table in agents.md with tab bar columns
  • Fixed duplicate See Also links, timer cleanup leak, agent name references

Other fixes

  • Session.fork() accepts parentID to create child forks
  • Permission prompts hidden when tab bar focused, Main tab blinks when pending
  • defaultPrevented check in command dialog handler
  • onCleanup for ctrlc hint timer (memory leak fix)
  • SDK regenerated for fork parentID parameter

Test plan

  • npx tsgo --noEmit — 0 errors (packages/opencode)
  • bun test --timeout 30000 — 1553 pass, 0 fail (+30 new unit tests)
  • bun test/cli/tui/tmux-tui-test.ts — 14 E2E flows pass (+4 new: tab-bar-navigate, tab-bar-fork, tab-bar-kill, ctrl-c-hint)
  • Manual tmux verification via tmux capture-pane: Tab, Left/Right, Enter on +, Down, Ctrl+C double-press, Shift+Tab agent cycling

Adrian Mârza added 3 commits March 22, 2026 18:26
Tab bar at top of session view showing Main, +, subagents (S1-S4), and fork agents (F1-F2):
- Tab toggles focus between tab bar and chat prompt
- Left/Right navigates tabs and immediately shows selected session
- Enter/Space on + forks Main's conversation into a new F-labeled child
- x kills selected agent, Ctrl+C double-press exits app
- Shift+Tab cycles agent type (Build/Plan/Docs)
- Click on any tab focuses tab bar and navigates

Fork agents (F1, F2, ...):
- Created via + button, copy Main's conversation history
- Cannot spawn subagents (task permission denied + system prompt)
- Colored yellow, distinct from LLM-spawned subagents (S1, S2)
- Manually promptable, persist until user kills with x

Architecture:
- useTab hook (tab.ts) — single source of truth for all tab state and actions
- TabBar (tabbar.tsx) — pure renderer with single onClick prop
- session/index.tsx — thin keyboard dispatcher delegating to hook
- 22 unit tests for buildTabs + useTab actions
- 12 E2E tmux flows (2 new: tab-bar-navigate, tab-bar-fork)
- Permission prompts hidden when tab bar focused, Main blinks when pending
- Session.fork() accepts parentID parameter

Docs:
- New docs/FRANKENCODE.md — overview of all Frankencode features
- Updated FRANKENCODE_DIFFERENCES.md — TUI changes, keybinding changes
- Updated agents.md — visibility table with tab bar columns, fork agent row
- Updated README.md — doc map, architecture diagram
- Cross-linked all docs (link, don't copy)
…anup and doc issues

- Merged FRANKENCODE_DIFFERENCES.md into FRANKENCODE.md (single doc)
- Deleted FRANKENCODE_DIFFERENCES.md, updated all cross-references in 8 docs
- Fixed duplicate See Also links in agents.md
- Fixed missing onCleanup for ctrlc timer in tab.ts (memory leak)
- Fixed "Build/Plan/Docs" → "Build/Plan/etc." in docs (Docs agent may not exist)
Unit tests (tab.test.ts — 30 total, 8 new):
- blur() sets focused false
- paginate() updates page
- click on spawn tab calls spawn
- cycle with single session is no-op
- kill on current tab navigates to remaining
- kill on non-current tab removes without navigation
- pending signal (focused + permissions)
- select clamps to valid range

E2E tmux flows (14 total, 2 new):
- tab-bar-kill: create fork, navigate to it, x to kill, verify gone
- ctrl-c-hint: Ctrl+C shows hint, auto-clears after 3s
- Fixed tab-bar-fork: verify Left navigation back to Main
- Fixed slash-threads: lenient wait (ephemeral output)
- Fixed agent-cycle + multi-agent-verify: use Shift+Tab (BTab)
@e6qu e6qu changed the title feat: subagent tabs with fork agents and useTab hook feat: subagent tab bar with fork agents, useTab hook, and FRANKENCODE.md Mar 22, 2026
@e6qu
e6qu merged commit 19e28cb into dev Mar 22, 2026
1 check passed
@e6qu
e6qu deleted the feat/subagent-tabs branch March 22, 2026 17:52
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