Skip to content
14 changes: 10 additions & 4 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ responsibility rather than by framework or build order.
```text
Application/ App lifecycle and display selection
Companion/ Idle/terminal presentation state and transparent panel
Agent/ Coding-agent request construction and delivery state
Terminal/
Core/ ANSI parsing, buffer, paging, input encoding, value types
PTY/ Pseudoterminal process and non-blocking I/O boundary
Expand All @@ -19,14 +20,19 @@ Assets/ Processed application and companion artwork
Dependency direction is intentionally one-way:

```text
Application + Companion -> Terminal Rendering -> Terminal Workspace/Session -> PTY + Core
Application + Companion -> Agent + Terminal Rendering -> Terminal Workspace/Session -> PTY + Core
```

`TerminalWorkspaceModel` is the only owner of tab/split topology. Every leaf
maps to exactly one `TerminalSessionModel` and one `TerminalSessionID`-derived
persistence file; views route focus and raw input to that leaf only. It never
`MikuPanelCoordinator` owns one `TerminalSessionModel` for the one visible
embedded PTY. Views route focus and raw input to that session only; it never
creates another `NSWindow`.

`AgentWorkspaceModel` is the UI-side owner of a coding-agent request. It
constructs only supported provider/approval commands, hands them to the active
`TerminalSessionModel`, and records the request in conversation history only
after the PTY reports delivery for the matching request token. It does not own
or create a second PTY, panel, or window.

`Terminal/Core` contains deterministic terminal behavior and must not import
SwiftUI, AppKit, Metal, or process-launch concerns. UI and process boundaries
belong to their named directories; this keeps parser and buffer changes
Expand Down
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Contributing to MikuCode

Thanks for helping improve MikuCode. Contributions should make the macOS single-session terminal and companion UI clearer, more reliable, or more accessible while keeping its focused scope.
Thanks for helping improve MikuCode. Contributions should make the macOS
coding-agent workspace, local embedded terminal, or companion UI clearer,
more reliable, or more accessible while keeping its focused one-panel scope.

This private repository requires a GitHub-authorized account for cloning and contributing.

Expand Down
52 changes: 28 additions & 24 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ the Dock. Development `swift run` output is not part of the product UI.
| --- | --- | --- |
| `idle` | Transparent panel; a centered front-facing chibi Miku stays still, changes to attentive eye contact on hover, and reveals a terminal bubble | Stopped |
| `opening` | Same panel transitions to the active composition | Stopped |
| `terminal` | Screen-sized, borderless, normal-level panel with a large speech-bubble local-terminal workspace, compact MikuCode header, and Miku right rail | Each visible leaf is running and the focused pane is directly focused |
| `closing` | Active composition leaves the same panel | PTYs stopped, drained, and persisted |
| `terminal` | Screen-sized, borderless, normal-level panel with a large dark sky-blue speech-bubble coding-agent workspace, compact MikuCode header, and Miku right rail | The coordinator-owned local PTY runs whether its embedded view is shown or hidden |
| `closing` | Active composition leaves the same panel | The local PTY stops, drains, and persists |

Repeated or out-of-order events are no-ops. Command-W and panel-close requests
use the close transition and return to `idle`.
Expand All @@ -33,23 +33,28 @@ use the close transition and return to `idle`.
reveals a small speech-bubble terminal affordance. The companion never walks,
slides, or bobs in idle; only the intentional gaze state changes.
Clicking either Miku herself or that bubble begins the terminal transition.
- In terminal state, the bubble header contains `miku-code`, a horizontally
scrollable selected-tab strip, the actual focused-PTY state, and one close
control. `Command-T` creates a tab, `Command-D` splits the focused pane to
the right, and `Shift-Command-D` splits it below; these actions retain the
one-panel, one-bubble composition. Hovering expanded Miku reveals a close
- In terminal state, the bubble opens as a coding-agent workspace: a compact
MikuCode logo mark gives way to prompt history, a provider/approval composer, and
a terminal toggle. Codex and Claude support `Plan`, `Accept`, and `Auto`;
the workspace only records a request after its token-matched PTY delivery.
The terminal toggle reveals that same local PTY inside the bubble—never a
second window. Hovering expanded Miku reveals a close
marker. Clicking either close
target stops the terminal and returns the same running app to its small idle
companion at the floating layer; it only returns behind other apps after the
app itself loses focus, and never quits MikuCode.
- The terminal header is an agent-workspace cue, not a toolbar: it contains the
app name, tab navigation, the actual focused-PTY state, and one close
control. There are no traffic
lights, provider selectors, paging/search controls, or permanent Clear,
Interrupt, or Send buttons. Command-F opens the only transient text field: a
compact in-bubble terminal finder. Command-G and Shift-Command-G navigate
its case-insensitive matches across output pages; Escape restores terminal
focus and removes the finder.
- The workspace header is an agent-workspace cue, not a toolbar: it contains
the logo mark, local-shell status, an embedded-terminal toggle, and one close
control. The composer is a measured bottom dock: provider and approval chips
remain distinct from a full-width prompt field and labelled send action at all
supported bubble sizes. Codex uses a cool gray signal, Claude orange, and
Plan/Accept/Auto each retain distinct semantic colors. Command-F opens the only
transient terminal text field: a compact in-bubble finder. Command-G and
Shift-Command-G navigate its case-insensitive matches across output pages;
Escape restores terminal focus and removes the finder.
- The speech-bubble tail owns a reserved header inset; terminal and close controls
never sit beneath it, and the focused-Miku close target begins after a fixed gap
beyond the workspace frame. No interactive target is allowed to overlap another.
- The speech bubble resizes directly from its edges and corners. Its frame stays
inside a 24-point display inset and preserves a minimum right-side Miku rail;
native directional cursors expose the otherwise unobtrusive resize targets.
Expand All @@ -66,21 +71,20 @@ event monitor is used.

PTY output is read without blocking, input is bounded and drained through a
write source, resize is sent through `TIOCSWINSZ`, and shutdown sends `SIGHUP`
with a bounded `SIGKILL` fallback. Each workspace leaf owns its own PTY and
bounded snapshot; the tab/split/focus layout and per-session snapshots persist
on close and restore on the next launch.
with a bounded `SIGKILL` fallback. The coordinator-owned PTY and its bounded
snapshot persist on close and restore on the next launch.

## Visual tokens

The visual system uses a 4-point spacing base. Idle is transparent; active
surfaces use a graphite two-stop bubble, a translucent rim, a restrained teal
shadow, and white terminal text. The header uses compact rounded app type with
monospaced `agent terminal` and PTY state labels, making the surface read as a
surfaces use flat dark sky-blue tones, a translucent cyan rim with a slow opacity
pulse, a restrained teal shadow, and white terminal text. The header uses modern
SF app type with small monospaced agent labels, making the surface read as a
coding-agent workspace rather than a generic terminal emulator. The app icon is a separate
terminal-and-Miku asset; the desktop companion contains only the 2D Miku
character. Idle artwork stays centered and still above a subtle teal ground
shadow. Its only idle motion is an intentional crossfade to an attentive gaze
on hover; opening, active terminal, and closing states use the focus frame as
the deliberate zoom transition. ANSI colors
are confined to terminal output. Reduce Motion removes companion float and
state transitions while preserving state changes.
the deliberate zoom transition. ANSI colors are confined to terminal output.
Reduce Motion removes companion float and state transitions while preserving
state changes.
38 changes: 21 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
# MikuCode

MikuCode is a macOS menu-bar-style companion that becomes a focused local PTY
terminal in place. One transparent, persistent `NSPanel` owns both states:
the idle panel shows Miku on the display under the pointer, and the active panel
fills the display with a speech-bubble terminal and Miku on the right.
MikuCode is a macOS coding-agent desktop with an integrated local PTY. One
transparent, persistent `NSPanel` owns both states: the idle panel shows Miku
on the display under the pointer, and the active panel fills the display with a
dark sky-blue speech-bubble workspace and Miku on the right.

## Behavior

- The PTY output view is selectable and receives keyboard input directly.
- Miku stays still and front-facing in her idle area. Hovering crossfades to an
attentive gaze and reveals a small terminal speech bubble; selecting either
Miku or that bubble opens the full terminal in the same panel.
- The expanded terminal uses the default MikuCode theme with a compact
`miku-code` header, a horizontally scrollable tab strip, and one close
button. `Command-T` opens a new local shell tab; `Command-D` splits the
focused terminal to the right; `Shift-Command-D` splits it below. Each leaf
owns an independent PTY, transcript, current directory, and persisted
session snapshot. Selecting the expanded Miku or the
close button returns the same running app to its small idle Miku without
- The expanded workspace uses the default MikuCode theme with a compact
`miku-code` header, one embedded-terminal toggle, and one close button. The
coordinator owns one local PTY, transcript, current directory, and persisted
session snapshot. Selecting the expanded Miku or the close button returns
the same running app to its small idle Miku without
sending it behind other windows; it returns to the desktop layer only after
the app loses focus, and never quits MikuCode.
- The agent workspace starts with a centered MikuCode mark and a focused
prompt composer. Choose Codex or Claude plus `Plan`, `Accept`, or `Auto`;
the request is written to the integrated PTY only after the local terminal
can accept it. The terminal button expands or hides that same embedded PTY
below the conversation—no second window is created.
- Printable keys, control sequences, paste, resize, paging, find, clear, and
interrupt use terminal keyboard actions. Command-F opens a compact transient
finder inside the terminal bubble; Command-G and Shift-Command-G move between
Expand All @@ -44,9 +47,9 @@ in [ARCHITECTURE.md](ARCHITECTURE.md).

- `MikuPanelCoordinator` retains the single panel and applies the presentation
state machine.
- `TerminalWorkspaceModel` owns tabs, focused-pane splits, per-session
storage, and workspace restoration while retaining one outer speech bubble.
- `TerminalPanel` embeds an individual terminal pane.
- `AgentWorkspaceModel` owns provider/approval selection and only records an
agent prompt after its PTY write is confirmed.
- `TerminalPanel` embeds the coordinator-owned terminal pane.
- `TerminalSessionModel` owns one PTY lifecycle, buffering, persistence, and
terminal updates.
- `PTYProcess` uses `forkpty`, a bounded non-blocking output/input path, and
Expand All @@ -73,9 +76,10 @@ Requirements: macOS 14 or later, Swift 6 or later, and a local POSIX shell.

## Scope

MikuCode provides local shell tabs and focused-pane splits inside one panel.
Remote connections, profiles, SSH, editor features, tab closing/reordering,
and complete terminal compatibility are out of scope. The protocol
MikuCode provides one local shell and coding-agent prompts inside one panel.
Remote connections, profiles, SSH, editor features, terminal tabs/splits,
provider-specific session restoration, and complete terminal compatibility are
out of scope. The protocol
intentionally covers a focused subset of UTF-8, ANSI SGR, cursor movement,
erasure, and bracketed paste behavior.

Expand Down
Loading