aimux-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +743 -0
- package/bin/aimux +2 -0
- package/dist/agent-events.d.ts +20 -0
- package/dist/agent-events.js +2 -0
- package/dist/agent-events.js.map +1 -0
- package/dist/agent-message-parts.d.ts +17 -0
- package/dist/agent-message-parts.js +31 -0
- package/dist/agent-message-parts.js.map +1 -0
- package/dist/agent-output-parser.d.ts +16 -0
- package/dist/agent-output-parser.js +229 -0
- package/dist/agent-output-parser.js.map +1 -0
- package/dist/agent-tracker.d.ts +9 -0
- package/dist/agent-tracker.js +144 -0
- package/dist/agent-tracker.js.map +1 -0
- package/dist/agent-watcher.d.ts +15 -0
- package/dist/agent-watcher.js +2 -0
- package/dist/agent-watcher.js.map +1 -0
- package/dist/attachment-store.d.ts +35 -0
- package/dist/attachment-store.js +129 -0
- package/dist/attachment-store.js.map +1 -0
- package/dist/builtin-metadata-watchers.d.ts +2 -0
- package/dist/builtin-metadata-watchers.js +275 -0
- package/dist/builtin-metadata-watchers.js.map +1 -0
- package/dist/claude-hooks.d.ts +29 -0
- package/dist/claude-hooks.js +106 -0
- package/dist/claude-hooks.js.map +1 -0
- package/dist/config.d.ts +78 -0
- package/dist/config.js +172 -0
- package/dist/config.js.map +1 -0
- package/dist/context/compactor.d.ts +20 -0
- package/dist/context/compactor.js +212 -0
- package/dist/context/compactor.js.map +1 -0
- package/dist/context/context-bridge.d.ts +67 -0
- package/dist/context/context-bridge.js +471 -0
- package/dist/context/context-bridge.js.map +1 -0
- package/dist/context/context-file.d.ts +11 -0
- package/dist/context/context-file.js +93 -0
- package/dist/context/context-file.js.map +1 -0
- package/dist/context/history.d.ts +40 -0
- package/dist/context/history.js +108 -0
- package/dist/context/history.js.map +1 -0
- package/dist/daemon.d.ts +39 -0
- package/dist/daemon.js +344 -0
- package/dist/daemon.js.map +1 -0
- package/dist/dashboard-session-registry.d.ts +47 -0
- package/dist/dashboard-session-registry.js +161 -0
- package/dist/dashboard-session-registry.js.map +1 -0
- package/dist/dashboard-state.d.ts +18 -0
- package/dist/dashboard-state.js +26 -0
- package/dist/dashboard-state.js.map +1 -0
- package/dist/dashboard.d.ts +118 -0
- package/dist/dashboard.js +91 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/debug.d.ts +7 -0
- package/dist/debug.js +41 -0
- package/dist/debug.js.map +1 -0
- package/dist/fast-control.d.ts +45 -0
- package/dist/fast-control.js +174 -0
- package/dist/fast-control.js.map +1 -0
- package/dist/hotkeys.d.ts +44 -0
- package/dist/hotkeys.js +118 -0
- package/dist/hotkeys.js.map +1 -0
- package/dist/http-client.d.ts +10 -0
- package/dist/http-client.js +54 -0
- package/dist/http-client.js.map +1 -0
- package/dist/instance-directory.d.ts +32 -0
- package/dist/instance-directory.js +82 -0
- package/dist/instance-directory.js.map +1 -0
- package/dist/instance-registry.d.ts +38 -0
- package/dist/instance-registry.js +208 -0
- package/dist/instance-registry.js.map +1 -0
- package/dist/key-parser.d.ts +30 -0
- package/dist/key-parser.js +272 -0
- package/dist/key-parser.js.map +1 -0
- package/dist/last-used.d.ts +31 -0
- package/dist/last-used.js +93 -0
- package/dist/last-used.js.map +1 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +2483 -0
- package/dist/main.js.map +1 -0
- package/dist/metadata-server.d.ts +268 -0
- package/dist/metadata-server.js +1379 -0
- package/dist/metadata-server.js.map +1 -0
- package/dist/metadata-store.d.ts +80 -0
- package/dist/metadata-store.js +87 -0
- package/dist/metadata-store.js.map +1 -0
- package/dist/multiplexer.d.ts +471 -0
- package/dist/multiplexer.js +5714 -0
- package/dist/multiplexer.js.map +1 -0
- package/dist/notification-context.d.ts +18 -0
- package/dist/notification-context.js +68 -0
- package/dist/notification-context.js.map +1 -0
- package/dist/notifications.d.ts +38 -0
- package/dist/notifications.js +111 -0
- package/dist/notifications.js.map +1 -0
- package/dist/notify.d.ts +10 -0
- package/dist/notify.js +62 -0
- package/dist/notify.js.map +1 -0
- package/dist/orchestration-actions.d.ts +76 -0
- package/dist/orchestration-actions.js +310 -0
- package/dist/orchestration-actions.js.map +1 -0
- package/dist/orchestration-dispatcher.d.ts +22 -0
- package/dist/orchestration-dispatcher.js +49 -0
- package/dist/orchestration-dispatcher.js.map +1 -0
- package/dist/orchestration-routing.d.ts +20 -0
- package/dist/orchestration-routing.js +78 -0
- package/dist/orchestration-routing.js.map +1 -0
- package/dist/orchestration.d.ts +26 -0
- package/dist/orchestration.js +110 -0
- package/dist/orchestration.js.map +1 -0
- package/dist/osc-notifications.d.ts +15 -0
- package/dist/osc-notifications.js +180 -0
- package/dist/osc-notifications.js.map +1 -0
- package/dist/paths.d.ts +55 -0
- package/dist/paths.js +259 -0
- package/dist/paths.js.map +1 -0
- package/dist/plugin-runtime.d.ts +46 -0
- package/dist/plugin-runtime.js +180 -0
- package/dist/plugin-runtime.js.map +1 -0
- package/dist/project-events.d.ts +36 -0
- package/dist/project-events.js +63 -0
- package/dist/project-events.js.map +1 -0
- package/dist/project-scanner.d.ts +38 -0
- package/dist/project-scanner.js +243 -0
- package/dist/project-scanner.js.map +1 -0
- package/dist/project-service-manifest.d.ts +18 -0
- package/dist/project-service-manifest.js +56 -0
- package/dist/project-service-manifest.js.map +1 -0
- package/dist/recency.d.ts +2 -0
- package/dist/recency.js +34 -0
- package/dist/recency.js.map +1 -0
- package/dist/recorder.d.ts +14 -0
- package/dist/recorder.js +130 -0
- package/dist/recorder.js.map +1 -0
- package/dist/session-bootstrap.d.ts +45 -0
- package/dist/session-bootstrap.js +436 -0
- package/dist/session-bootstrap.js.map +1 -0
- package/dist/session-message-history.d.ts +27 -0
- package/dist/session-message-history.js +105 -0
- package/dist/session-message-history.js.map +1 -0
- package/dist/session-runtime.d.ts +44 -0
- package/dist/session-runtime.js +56 -0
- package/dist/session-runtime.js.map +1 -0
- package/dist/session-semantics.d.ts +35 -0
- package/dist/session-semantics.js +110 -0
- package/dist/session-semantics.js.map +1 -0
- package/dist/status-detector.d.ts +17 -0
- package/dist/status-detector.js +67 -0
- package/dist/status-detector.js.map +1 -0
- package/dist/statusline-model.d.ts +103 -0
- package/dist/statusline-model.js +177 -0
- package/dist/statusline-model.js.map +1 -0
- package/dist/task-dispatcher.d.ts +63 -0
- package/dist/task-dispatcher.js +210 -0
- package/dist/task-dispatcher.js.map +1 -0
- package/dist/task-workflow.d.ts +13 -0
- package/dist/task-workflow.js +153 -0
- package/dist/task-workflow.js.map +1 -0
- package/dist/tasks.d.ts +60 -0
- package/dist/tasks.js +120 -0
- package/dist/tasks.js.map +1 -0
- package/dist/team.d.ts +28 -0
- package/dist/team.js +91 -0
- package/dist/team.js.map +1 -0
- package/dist/terminal-host.d.ts +10 -0
- package/dist/terminal-host.js +52 -0
- package/dist/terminal-host.js.map +1 -0
- package/dist/threads.d.ts +61 -0
- package/dist/threads.js +200 -0
- package/dist/threads.js.map +1 -0
- package/dist/tmux-doctor.d.ts +47 -0
- package/dist/tmux-doctor.js +112 -0
- package/dist/tmux-doctor.js.map +1 -0
- package/dist/tmux-runtime-manager.d.ts +164 -0
- package/dist/tmux-runtime-manager.js +794 -0
- package/dist/tmux-runtime-manager.js.map +1 -0
- package/dist/tmux-session-transport.d.ts +31 -0
- package/dist/tmux-session-transport.js +115 -0
- package/dist/tmux-session-transport.js.map +1 -0
- package/dist/tmux-statusline.d.ts +17 -0
- package/dist/tmux-statusline.js +166 -0
- package/dist/tmux-statusline.js.map +1 -0
- package/dist/tool-output-watchers.d.ts +10 -0
- package/dist/tool-output-watchers.js +190 -0
- package/dist/tool-output-watchers.js.map +1 -0
- package/dist/tui/render/box.d.ts +1 -0
- package/dist/tui/render/box.js +20 -0
- package/dist/tui/render/box.js.map +1 -0
- package/dist/tui/render/text.d.ts +8 -0
- package/dist/tui/render/text.js +92 -0
- package/dist/tui/render/text.js.map +1 -0
- package/dist/tui/screens/dashboard-renderers.d.ts +23 -0
- package/dist/tui/screens/dashboard-renderers.js +411 -0
- package/dist/tui/screens/dashboard-renderers.js.map +1 -0
- package/dist/tui/screens/overlay-renderers.d.ts +10 -0
- package/dist/tui/screens/overlay-renderers.js +274 -0
- package/dist/tui/screens/overlay-renderers.js.map +1 -0
- package/dist/tui/screens/subscreen-renderers.d.ts +9 -0
- package/dist/tui/screens/subscreen-renderers.js +327 -0
- package/dist/tui/screens/subscreen-renderers.js.map +1 -0
- package/dist/workflow.d.ts +19 -0
- package/dist/workflow.js +111 -0
- package/dist/workflow.js.map +1 -0
- package/dist/worktree.d.ts +23 -0
- package/dist/worktree.js +101 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +70 -0
package/README.md
ADDED
|
@@ -0,0 +1,743 @@
|
|
|
1
|
+
# aimux
|
|
2
|
+
|
|
3
|
+
Native CLI agent multiplexer — run multiple AI coding tools side-by-side with their native TUIs intact.
|
|
4
|
+
|
|
5
|
+
aimux uses `tmux` as its terminal runtime substrate. Each project gets its own managed tmux runtime session, each terminal gets its own dashboard client session/window, and each agent runs in its own tmux window while aimux keeps orchestration, worktrees, plans, and metadata on top.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **tmux-backed runtime** — real scrollback, attach/detach, repaint, and terminal compatibility come from tmux instead of a custom multiplexer
|
|
10
|
+
- **Dashboard clients** — each terminal gets its own dashboard tmux client session/window while agent runtime stays shared per project
|
|
11
|
+
- **Agent windows** — each agent gets its own tmux window with its native TUI intact
|
|
12
|
+
- **tmux status integration** — the native tmux status line shows aimux session, task, headline, and metadata state
|
|
13
|
+
- **Metadata API** — scripts and agents can push status, progress, logs, and notifications into the tmux status line
|
|
14
|
+
- **Plugin/watcher seam** — local plugins can watch files or external tools and publish metadata without patching aimux core
|
|
15
|
+
- **Leader key switching in dashboard** — `Ctrl+A` prefix for dashboard actions like create/kill/switch while you are in the aimux dashboard window
|
|
16
|
+
- **Dashboard view** — see all running, offline, and remote agents at a glance
|
|
17
|
+
- **Multi-instance** — run aimux in multiple terminal tabs; agents from other instances appear inline and can be taken over
|
|
18
|
+
- **Agent lifecycle** — two-step kill (`[x]` stops → offline, `[x]` again → graveyard), with `aimux graveyard resurrect` for recovery
|
|
19
|
+
- **Task delegation** — agents can delegate work to each other via `.aimux/tasks/`, with automatic dispatch, completion notifications, and dashboard badges
|
|
20
|
+
- **Threaded orchestration** — direct messages, handoffs, and task assignment all flow through durable `.aimux/threads/` state with queued delivery when recipients are busy
|
|
21
|
+
- **Dashboard orchestration actions** — from the main dashboard, use `S` to send a message, `H` to send a handoff, `T` to assign a task, `o` to jump to the most relevant thread, and `R` to reply when something is waiting on you
|
|
22
|
+
- **Workflow view** — a dedicated workflow screen groups related task/review/revision chains, supports actionable filters, and exposes explicit accept/block/complete/reopen/review controls
|
|
23
|
+
- **Next-action guidance** — dashboard rows and details surface `on me`, `blocked`, family-chain pressure, and the single most relevant next orchestration step
|
|
24
|
+
- **Context sharing** — agents can read each other's conversation history via `.aimux/context/`
|
|
25
|
+
- **Session resume** — resume previous sessions using each tool's native resume (`--resume`) or injected history (`--restore`)
|
|
26
|
+
- **Git worktree support** — first-class worktree management for parallel feature work, with per-worktree agent isolation
|
|
27
|
+
- **Fully config-driven** — all tool behavior (prompt detection, session capture, resume, compaction) is declarative config, not code
|
|
28
|
+
- **Configurable** — global (`~/.aimux/config.json`) and project-level (`.aimux/config.json`) configuration with deep merge
|
|
29
|
+
- **Notifications** — cross-platform notifications (macOS, Linux, Windows) when agents need attention or complete tasks
|
|
30
|
+
- **Project event stream** — each project service exposes an SSE stream for ephemeral alerts and other live GUI/web events
|
|
31
|
+
- **Custom instructions** — `~/AIMUX.md` (global) and `./AIMUX.md` (project) are injected into every agent's preamble
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Clone and build
|
|
37
|
+
git clone https://github.com/TraderSamwise/aimux.git
|
|
38
|
+
cd aimux
|
|
39
|
+
yarn install
|
|
40
|
+
yarn build
|
|
41
|
+
|
|
42
|
+
# Link globally
|
|
43
|
+
yarn link
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Requires Node.js >= 18 and `tmux` in `PATH`.
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Launch dashboard for this terminal client
|
|
52
|
+
aimux
|
|
53
|
+
|
|
54
|
+
# Launch a specific tool in a new tmux agent window
|
|
55
|
+
aimux claude
|
|
56
|
+
aimux codex
|
|
57
|
+
aimux aider
|
|
58
|
+
|
|
59
|
+
# Resume all offline sessions
|
|
60
|
+
aimux --resume
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The per-project tmux session is the long-lived runtime substrate. Aimux no longer tries to build its own PTY multiplexer on top of native TUIs.
|
|
64
|
+
|
|
65
|
+
## Architecture
|
|
66
|
+
|
|
67
|
+
Aimux now distinguishes between:
|
|
68
|
+
|
|
69
|
+
- `tmux` runtime
|
|
70
|
+
- global aimux control-plane daemon
|
|
71
|
+
- daemon-managed project services
|
|
72
|
+
- terminal/desktop/service clients
|
|
73
|
+
|
|
74
|
+
`tmux` still owns the actual agent runtime:
|
|
75
|
+
|
|
76
|
+
- agent windows
|
|
77
|
+
- PTYs
|
|
78
|
+
- scrollback
|
|
79
|
+
- attach/detach
|
|
80
|
+
|
|
81
|
+
The global daemon owns shared control-plane responsibilities:
|
|
82
|
+
|
|
83
|
+
- project discovery and activation
|
|
84
|
+
- supervision of daemon-managed project services
|
|
85
|
+
- desktop/service-facing project discovery
|
|
86
|
+
|
|
87
|
+
Each active project may have one daemon-managed project service. That project service owns:
|
|
88
|
+
|
|
89
|
+
- metadata API lifecycle
|
|
90
|
+
- plugin runtime
|
|
91
|
+
- project `statusline.json` writing
|
|
92
|
+
- project-scoped control-plane sidecars
|
|
93
|
+
|
|
94
|
+
There is no per-project host election anymore. Dashboard processes are clients, not control-plane owners.
|
|
95
|
+
|
|
96
|
+
Desktop/Tauri now talks to the live control plane directly:
|
|
97
|
+
|
|
98
|
+
- daemon HTTP is used for project discovery / service discovery
|
|
99
|
+
- project-service HTTP is used for live project state and awaited lifecycle actions
|
|
100
|
+
- `statusline.json` remains a derived artifact for tmux/status/debugging, not the desktop's primary transport
|
|
101
|
+
- desktop loading state should clear on heartbeat reconciliation of the expected state change, not on HTTP return alone
|
|
102
|
+
|
|
103
|
+
Terminal clients are isolated from each other:
|
|
104
|
+
|
|
105
|
+
- the shared per-project tmux runtime session owns agent windows
|
|
106
|
+
- each terminal gets its own tmux client session and dashboard window
|
|
107
|
+
- dashboard tab, pointer, and load state are terminal-local
|
|
108
|
+
- orchestration, metadata, and plugin sidecars are project-scoped through the daemon-managed project service
|
|
109
|
+
|
|
110
|
+
Useful commands:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
aimux daemon ensure
|
|
114
|
+
aimux daemon status --json
|
|
115
|
+
aimux daemon projects --json
|
|
116
|
+
aimux daemon project-ensure --project /abs/path/to/repo
|
|
117
|
+
|
|
118
|
+
# Compatibility wrapper: ensure the current project's control service
|
|
119
|
+
aimux serve
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Orchestration commands:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
aimux message send "Need UI review on the login flow" --assignee ui --worktree /abs/path/to/worktree
|
|
126
|
+
aimux handoff send "Take over the sidebar polish from here" --tool claude
|
|
127
|
+
aimux task assign "Audit the websocket reconnect path" --assignee reviewer
|
|
128
|
+
aimux handoff accept <threadId>
|
|
129
|
+
aimux handoff complete <threadId>
|
|
130
|
+
aimux task accept <taskId>
|
|
131
|
+
aimux task block <taskId> --reason "Waiting on API decision"
|
|
132
|
+
aimux task complete <taskId>
|
|
133
|
+
aimux task reopen <taskId>
|
|
134
|
+
aimux review approve <taskId>
|
|
135
|
+
aimux review request-changes <taskId> --body "Handle reconnect backoff edge cases"
|
|
136
|
+
aimux thread list
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
GUI-facing lifecycle commands:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Fresh agent using the same spawn flow as the dashboard
|
|
143
|
+
aimux spawn --tool claude --project /abs/path/to/repo --worktree /abs/path/to/worktree --json
|
|
144
|
+
|
|
145
|
+
# Fork an existing live agent with handed-off context
|
|
146
|
+
aimux fork <sessionId> --tool codex --project /abs/path/to/repo --worktree /abs/path/to/worktree --json
|
|
147
|
+
|
|
148
|
+
# Match the dashboard lifecycle
|
|
149
|
+
aimux stop <sessionId> --project /abs/path/to/repo --json
|
|
150
|
+
aimux rename <sessionId> --label "Backend reviewer" --project /abs/path/to/repo --json
|
|
151
|
+
aimux migrate <sessionId> --worktree /abs/path/to/worktree --project /abs/path/to/repo --json
|
|
152
|
+
aimux kill <sessionId> --project /abs/path/to/repo --json
|
|
153
|
+
aimux graveyard send <sessionId> --project /abs/path/to/repo --json
|
|
154
|
+
aimux graveyard resurrect <sessionId> --project /abs/path/to/repo --json
|
|
155
|
+
|
|
156
|
+
# Project-scoped worktree helpers
|
|
157
|
+
aimux worktree list --project /abs/path/to/repo --json
|
|
158
|
+
aimux worktree create feature-x --project /abs/path/to/repo --json
|
|
159
|
+
|
|
160
|
+
# Focus a live agent in tmux
|
|
161
|
+
desktop terminal focus now uses the thin tmux fast-control entrypoint via the project service and terminal client tty
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
HTTP-backed agent I/O helpers:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Send raw input to a running agent through the project service
|
|
168
|
+
aimux host agent-send <sessionId> "hello\r"
|
|
169
|
+
printf 'hello\r' | aimux host agent-send <sessionId> --stdin
|
|
170
|
+
|
|
171
|
+
# Read a tmux pane snapshot for a running agent
|
|
172
|
+
aimux host agent-read <sessionId> --start-line -80
|
|
173
|
+
|
|
174
|
+
# Stream live pane output over SSE through the project service
|
|
175
|
+
aimux host agent-stream <sessionId> --start-line -80 --interval-ms 250
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Ephemeral project events:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# Subscribe to per-project alerts/events over SSE
|
|
182
|
+
curl -N http://127.0.0.1:<project-service-port>/events
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
These commands are additive control-plane helpers on top of the existing `aimux -> tmux -> codex/claude` runtime. They do not replace the native TUI path; they reuse the same session write path and tmux pane capture path through the project HTTP service.
|
|
186
|
+
|
|
187
|
+
For desktop / GUI callers, prefer explicit `--project` usage instead of relying on launcher cwd.
|
|
188
|
+
|
|
189
|
+
Structured message parts:
|
|
190
|
+
|
|
191
|
+
- `POST /agents/input` accepts either plain `data` or ordered `parts`.
|
|
192
|
+
- `parts` currently supports:
|
|
193
|
+
- `{ "type": "text", "text": "..." }`
|
|
194
|
+
- `{ "type": "image", "path": "/abs/path.png", "alt": "..." }`
|
|
195
|
+
- `{ "type": "image", "url": "https://...", "alt": "..." }`
|
|
196
|
+
- `{ "type": "image", "attachmentId": "att_123", "alt": "..." }`
|
|
197
|
+
- Parts preserve inline ordering for GUI / HTTP callers.
|
|
198
|
+
- Today, tmux-backed agent sessions still receive image parts as explicit inline image descriptors in the prompt text. This preserves message structure now, but it is not yet binary image upload/attachment transport.
|
|
199
|
+
|
|
200
|
+
Example:
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"sessionId": "claude-1",
|
|
205
|
+
"parts": [
|
|
206
|
+
{ "type": "text", "text": "Compare these two layouts." },
|
|
207
|
+
{ "type": "image", "url": "https://example.com/a.png", "alt": "first screenshot" },
|
|
208
|
+
{ "type": "text", "text": "The spacing issue is around the header." }
|
|
209
|
+
],
|
|
210
|
+
"submit": true
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Control-plane health:
|
|
215
|
+
|
|
216
|
+
- The desktop UI now surfaces daemon / project-service health and exposes a `Restart control` action.
|
|
217
|
+
- The tmux statusline shows `ctl ok`, `ctl daemon↓`, or `ctl stale`.
|
|
218
|
+
- `ctl stale` means the project-service `statusline.json` snapshot has stopped updating, which usually means the project service died.
|
|
219
|
+
- Manual recovery is still:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
aimux daemon restart
|
|
223
|
+
cd /abs/path/to/repo
|
|
224
|
+
aimux host restart --serve
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Daemon rebuild quirk:
|
|
228
|
+
|
|
229
|
+
- The global daemon and each project service run from the built `dist/` output, not directly from `src/`.
|
|
230
|
+
- If you change project-service HTTP behavior, rebuild first with `yarn build`.
|
|
231
|
+
- If a daemon is already running, restart the daemon too, not just the project service, or the old daemon will keep spawning old project-service code.
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
yarn build
|
|
235
|
+
aimux daemon restart
|
|
236
|
+
cd /abs/path/to/repo
|
|
237
|
+
aimux host restart --serve
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The desktop app now exposes these flows directly over daemon/project-service HTTP:
|
|
241
|
+
|
|
242
|
+
- dashboard worktree/agent management
|
|
243
|
+
- spawn, fork, rename, migrate, stop, kill
|
|
244
|
+
- graveyard browse + resurrect
|
|
245
|
+
- worktree create + remove
|
|
246
|
+
- activity, workflow, threads, plans, and graveyard secondary screens
|
|
247
|
+
- direct message compose, handoff send/accept/complete, and task/review workflow actions
|
|
248
|
+
- thread state updates and per-message delivery visibility
|
|
249
|
+
|
|
250
|
+
For the current source of truth, see [docs/current-architecture.md](docs/current-architecture.md).
|
|
251
|
+
For desktop UI integration details, see [docs/desktop-ui-contract.md](docs/desktop-ui-contract.md).
|
|
252
|
+
For the migration rationale, see [docs/global-control-plane-rfc.md](docs/global-control-plane-rfc.md).
|
|
253
|
+
|
|
254
|
+
## Tmux Compatibility
|
|
255
|
+
|
|
256
|
+
Aimux treats tmux as a managed runtime, not a transparent pass-through. For aimux-owned tmux sessions, aimux applies a fixed compatibility contract instead of inheriting whatever ambient tmux defaults happen to exist on the machine.
|
|
257
|
+
|
|
258
|
+
Managed session policy today:
|
|
259
|
+
|
|
260
|
+
- `prefix = C-a`
|
|
261
|
+
- `prefix2 = C-b`
|
|
262
|
+
- `mouse = on` so tmux can own wheel events and enter pane scrollback reliably
|
|
263
|
+
- `extended-keys = always`
|
|
264
|
+
- `extended-keys-format = csi-u`
|
|
265
|
+
- `terminal-features` includes `xterm*:extkeys`
|
|
266
|
+
- `terminal-features` includes `xterm*:hyperlinks`
|
|
267
|
+
- managed Claude/Codex windows get `allow-passthrough = on`
|
|
268
|
+
- managed Claude/Codex windows get scoped modified-enter bindings for multiline input compatibility
|
|
269
|
+
- managed Claude/Codex windows remap wheel-up into tmux copy-mode scrollback instead of forwarding it into the app
|
|
270
|
+
|
|
271
|
+
This is why aimux can support features like `Ctrl+J`, `Shift+Enter`, and reliable tmux-native wheel scrollback inside managed tmux sessions without depending on user-specific tmux configuration.
|
|
272
|
+
|
|
273
|
+
To inspect the live state for the current project:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
aimux doctor tmux
|
|
277
|
+
aimux doctor tmux --json
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
That reports:
|
|
281
|
+
|
|
282
|
+
- terminal environment like `TERM` and `TERM_PROGRAM`
|
|
283
|
+
- tmux version and current client session
|
|
284
|
+
- observed managed-session options versus expected values
|
|
285
|
+
- required terminal features such as `extkeys` and `hyperlinks`
|
|
286
|
+
- active-window state including `@aimux-tool` and `allow-passthrough`
|
|
287
|
+
|
|
288
|
+
## Hotkeys
|
|
289
|
+
|
|
290
|
+
Hotkey latency note:
|
|
291
|
+
|
|
292
|
+
- dynamic tmux hotkeys now use a small shell transport that prefers local tmux resolution and falls back to project-service control helpers when needed
|
|
293
|
+
- the final window switch still happens in tmux
|
|
294
|
+
- this avoids spawning the heavyweight operator CLI for normal `n/p/s/u/d` navigation
|
|
295
|
+
- dashboard client sessions are kept alive for reuse; exiting a managed dashboard leaves the client instead of destroying the reusable dashboard window
|
|
296
|
+
- stale dashboard artifacts are pruned automatically before open/reload so broken `cat`/`tail` dashboard panes do not poison future attaches
|
|
297
|
+
- the broader latency architecture plan is documented in [docs/latency-architecture-rfc.md](docs/latency-architecture-rfc.md)
|
|
298
|
+
- the current entrypoint split is documented in [docs/latency-entrypoints.md](docs/latency-entrypoints.md)
|
|
299
|
+
|
|
300
|
+
Dashboard hotkeys use the `Ctrl+A` leader prefix:
|
|
301
|
+
|
|
302
|
+
| Key | Action |
|
|
303
|
+
|---|---|
|
|
304
|
+
| `Ctrl+A c` | Create new agent |
|
|
305
|
+
| `Ctrl+A x` | Stop agent (→ offline) or kill offline agent (→ graveyard) |
|
|
306
|
+
| `Ctrl+A w` | Create new worktree |
|
|
307
|
+
| `Ctrl+A W` | Worktree management |
|
|
308
|
+
| `Ctrl+A v` | Request code review for active agent |
|
|
309
|
+
| `Ctrl+A 1-9` | Focus agent by number from the dashboard |
|
|
310
|
+
| `Ctrl+A d` | Return to dashboard window |
|
|
311
|
+
| `Ctrl+A Ctrl+A` | Send literal Ctrl+A inside the dashboard |
|
|
312
|
+
|
|
313
|
+
When you are inside an agent window, tmux owns the terminal. Use normal tmux window navigation or run `aimux` again to return to the dashboard window.
|
|
314
|
+
|
|
315
|
+
Main dashboard orchestration shortcuts:
|
|
316
|
+
|
|
317
|
+
| Key | Action |
|
|
318
|
+
|---|---|
|
|
319
|
+
| `S` | Send direct message from the selected agent row |
|
|
320
|
+
| `H` | Send handoff from the selected agent row |
|
|
321
|
+
| `T` | Assign task from the selected agent row |
|
|
322
|
+
| `o` | Jump to the most relevant thread for the selected agent |
|
|
323
|
+
| `R` | Open quick reply when that agent has something waiting on you |
|
|
324
|
+
|
|
325
|
+
Workflow screen shortcuts:
|
|
326
|
+
|
|
327
|
+
| Key | Action |
|
|
328
|
+
|---|---|
|
|
329
|
+
| `f` | Cycle workflow filters: all / waiting on me / blocked / families |
|
|
330
|
+
| `a` | Accept selected handoff |
|
|
331
|
+
| `c` | Complete selected handoff |
|
|
332
|
+
| `b` | Mark selected thread blocked |
|
|
333
|
+
| `x` | Mark selected thread done |
|
|
334
|
+
| `P` | Approve selected review |
|
|
335
|
+
| `J` | Request changes on selected review |
|
|
336
|
+
| `E` | Reopen selected task chain |
|
|
337
|
+
|
|
338
|
+
Recommended tmux mental model:
|
|
339
|
+
|
|
340
|
+
- the shared project runtime session owns agent windows
|
|
341
|
+
- each terminal gets its own dashboard client session/window
|
|
342
|
+
- aimux metadata, plans, worktrees, and task orchestration sit on top of that runtime
|
|
343
|
+
|
|
344
|
+
For normal tmux users outside aimux, the equivalent setup usually lives in `~/.tmux.conf`. Aimux just codifies that policy inside its own managed sessions so behavior is stable across projects and terminals.
|
|
345
|
+
|
|
346
|
+
## Tmux Status Line
|
|
347
|
+
|
|
348
|
+
Aimux now uses tmux's native status bar instead of an in-terminal custom footer.
|
|
349
|
+
|
|
350
|
+
The managed tmux session config renders:
|
|
351
|
+
|
|
352
|
+
- **left**: aimux project identity
|
|
353
|
+
- **middle**: native tmux window list
|
|
354
|
+
- **right**: aimux session/task/headline/flash metadata
|
|
355
|
+
|
|
356
|
+
This keeps the terminal surface fully tmux-native while still surfacing the old footer's useful information.
|
|
357
|
+
|
|
358
|
+
Status rendering has two practical data paths that must stay visually aligned:
|
|
359
|
+
|
|
360
|
+
- the rich path from `statusline.json` written by the daemon-managed project service
|
|
361
|
+
- the fallback path from live tmux window metadata
|
|
362
|
+
|
|
363
|
+
When extending the footer/status UI, treat both as first-class render sources. The fallback path must carry enough metadata to render the same identity, role, and activity state as the richer dashboard-written path, otherwise the status bar will visibly flicker between styles during updates.
|
|
364
|
+
|
|
365
|
+
For future tool wiring and continuity expectations, see [docs/tool-integration.md](docs/tool-integration.md).
|
|
366
|
+
|
|
367
|
+
## Metadata API
|
|
368
|
+
|
|
369
|
+
Inspired by opensessions, aimux exposes a small project-local metadata API from the daemon-managed project service. The tmux status line reads this state and shows it for the active session.
|
|
370
|
+
|
|
371
|
+
CLI helpers:
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
aimux metadata endpoint
|
|
375
|
+
aimux metadata set-status <session> "Deploying" --tone warn
|
|
376
|
+
aimux metadata set-progress <session> 3 10 --label services
|
|
377
|
+
aimux metadata log <session> "Tests passed" --source ci --tone success
|
|
378
|
+
aimux metadata clear-log <session>
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
The project-service HTTP API also exposes:
|
|
382
|
+
|
|
383
|
+
- `GET /health`
|
|
384
|
+
- `GET /state`
|
|
385
|
+
- `POST /set-status`
|
|
386
|
+
- `POST /set-progress`
|
|
387
|
+
- `POST /log`
|
|
388
|
+
- `POST /clear-log`
|
|
389
|
+
- `POST /notify`
|
|
390
|
+
|
|
391
|
+
Use `aimux metadata endpoint` to get the local base URL for the current project service.
|
|
392
|
+
|
|
393
|
+
## Plugins And Watchers
|
|
394
|
+
|
|
395
|
+
Aimux can load local metadata plugins from:
|
|
396
|
+
|
|
397
|
+
- `~/.aimux/plugins/*.js|*.mjs`
|
|
398
|
+
- `.aimux/plugins/*.js|*.mjs`
|
|
399
|
+
|
|
400
|
+
Each plugin default-exports a factory:
|
|
401
|
+
|
|
402
|
+
```js
|
|
403
|
+
export default function (api) {
|
|
404
|
+
return {
|
|
405
|
+
start() {
|
|
406
|
+
api.metadata.setStatus("codex-abc123", "Watching", "info");
|
|
407
|
+
},
|
|
408
|
+
stop() {}
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Available API today:
|
|
414
|
+
|
|
415
|
+
- `api.projectRoot`
|
|
416
|
+
- `api.projectId`
|
|
417
|
+
- `api.serverHost`
|
|
418
|
+
- `api.serverPort`
|
|
419
|
+
- `api.metadata.setStatus(session, text, tone?)`
|
|
420
|
+
- `api.metadata.setProgress(session, current, total, label?)`
|
|
421
|
+
- `api.metadata.log(session, message, { source?, tone? })`
|
|
422
|
+
- `api.metadata.clearLog(session)`
|
|
423
|
+
|
|
424
|
+
Built-in watchers already publish:
|
|
425
|
+
|
|
426
|
+
- `.aimux/status/{session-id}.md` first-line headline as metadata status
|
|
427
|
+
- `.aimux/plans/{session-id}.md` checkbox completion as metadata progress
|
|
428
|
+
|
|
429
|
+
## Dashboard
|
|
430
|
+
|
|
431
|
+
When you run `aimux` without arguments, aimux ensures the project tmux session exists and switches you to the dashboard window showing all agents across all states:
|
|
432
|
+
|
|
433
|
+
```
|
|
434
|
+
aimux — agent multiplexer
|
|
435
|
+
──────────────────────────────────────
|
|
436
|
+
|
|
437
|
+
● [1] claude — running ←
|
|
438
|
+
● [2] codex — idle
|
|
439
|
+
○ [3] claude — offline
|
|
440
|
+
◈ [4] claude — other tab (PID 54321)
|
|
441
|
+
|
|
442
|
+
──────────────────────────────────────
|
|
443
|
+
↑↓ select Enter focus [c] new [x] stop [q] quit
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
- **Enter** on a running agent switches to that agent's tmux window
|
|
447
|
+
- **Enter** on an offline agent resumes it
|
|
448
|
+
- **Enter** on a remote agent (other tab) takes it over
|
|
449
|
+
- **`[x]`** on running → stops to offline; **`[x]`** on offline → sends to graveyard
|
|
450
|
+
|
|
451
|
+
With worktrees, agents are grouped:
|
|
452
|
+
|
|
453
|
+
```
|
|
454
|
+
(main) — active
|
|
455
|
+
● [1] claude — running ←
|
|
456
|
+
|
|
457
|
+
fix-auth (fix-auth) — active
|
|
458
|
+
● [2] claude — running
|
|
459
|
+
○ [3] codex — offline
|
|
460
|
+
|
|
461
|
+
──────────────────────────────────────
|
|
462
|
+
↑↓ worktrees Enter step in [c] new [w] worktree [q] quit
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
## Context System
|
|
466
|
+
|
|
467
|
+
aimux records each agent's conversation and makes it available to other agents:
|
|
468
|
+
|
|
469
|
+
- **`.aimux/context/{session-id}/live.md`** — rolling window of recent turns
|
|
470
|
+
- **`.aimux/context/{session-id}/summary.md`** — compacted history
|
|
471
|
+
- **`.aimux/context/{session-id}/summary.meta.json`** — summary provenance (source range + digest)
|
|
472
|
+
- **`.aimux/context/{session-id}/summary.checkpoints.jsonl`** — append-only compaction checkpoints
|
|
473
|
+
- **`.aimux/history/{session-id}.jsonl`** — full raw conversation log
|
|
474
|
+
- **`.aimux/plans/{session-id}.md`** — canonical shared plan for that agent
|
|
475
|
+
- **`.aimux/sessions.json`** — all running agents (so agents can discover each other)
|
|
476
|
+
|
|
477
|
+
Agents are told about these files in their startup preamble.
|
|
478
|
+
|
|
479
|
+
These are the canonical agent-facing paths. Runtime-private state stays under `~/.aimux/projects/<project-id>/...` and is not part of the agent contract.
|
|
480
|
+
|
|
481
|
+
In tmux mode, live terminal state comes from tmux itself. `~/.aimux/projects/<project-id>/state.json` is mainly for offline/resume metadata, not live screen ownership.
|
|
482
|
+
|
|
483
|
+
Memory roles are explicit:
|
|
484
|
+
|
|
485
|
+
- `history/*.jsonl` is append-only audit history and is never compacted away
|
|
486
|
+
- `context/*/live.md` is bounded runtime scratch state maintained by aimux from tmux pane snapshots
|
|
487
|
+
- `context/*/summary.md` is a derived, lossy summary for long-horizon memory
|
|
488
|
+
- `summary.meta.json` and `summary.checkpoints.jsonl` preserve compaction provenance so summaries can be traced back to the underlying raw history
|
|
489
|
+
|
|
490
|
+
## Fork And Migrate Semantics
|
|
491
|
+
|
|
492
|
+
Aimux treats `fork` and `migrate` as related but distinct operations:
|
|
493
|
+
|
|
494
|
+
- `fork`
|
|
495
|
+
- always creates a new session id
|
|
496
|
+
- seeds the new session with carried-over `.aimux/context/`, `.aimux/history/`, `.aimux/plans/`, and `.aimux/status/` artifacts
|
|
497
|
+
- opens a handoff thread between source and target
|
|
498
|
+
- `migrate`
|
|
499
|
+
- preserves the same aimux session id
|
|
500
|
+
- prefers native backend resume when the tool truly supports it
|
|
501
|
+
- otherwise falls back to aimux-owned continuity injection from history/live context
|
|
502
|
+
|
|
503
|
+
Tool behavior differs:
|
|
504
|
+
|
|
505
|
+
- `Claude`
|
|
506
|
+
- supports clean preamble injection
|
|
507
|
+
- does **not** support backend-session-id resume in the way aimux originally assumed
|
|
508
|
+
- so `fork` and fallback `migrate` rely on aimux-owned continuity artifacts
|
|
509
|
+
- `Codex`
|
|
510
|
+
- supports backend-session-id resume, so `migrate` usually takes the native resume path
|
|
511
|
+
- does **not** currently have a clean startup handoff flag, so `fork` uses seeded files plus an auto-submitted first-turn kickoff
|
|
512
|
+
|
|
513
|
+
For deeper details, see [docs/tool-integration.md](docs/tool-integration.md).
|
|
514
|
+
|
|
515
|
+
## Shared Plans
|
|
516
|
+
|
|
517
|
+
Aimux standardizes planning per agent/session:
|
|
518
|
+
|
|
519
|
+
- **Canonical path:** `.aimux/plans/{session-id}.md`
|
|
520
|
+
- **Primary key:** session ID, not worktree
|
|
521
|
+
- **Purpose:** lets agents read, audit, annotate, and continue each other's plans without main-checkout/worktree edge cases
|
|
522
|
+
|
|
523
|
+
Each new session gets a stub plan file. Agents are instructed to keep it current using:
|
|
524
|
+
|
|
525
|
+
- `Goal`
|
|
526
|
+
- `Current Status`
|
|
527
|
+
- `Steps`
|
|
528
|
+
- `Notes`
|
|
529
|
+
|
|
530
|
+
## Task Delegation
|
|
531
|
+
|
|
532
|
+
Agents can delegate work to each other through the aimux task system. This is a file-based protocol — agents create task files, aimux dispatches them, and agents report results.
|
|
533
|
+
|
|
534
|
+
### How it works
|
|
535
|
+
|
|
536
|
+
1. **Agent A** creates a task file in `.aimux/tasks/`:
|
|
537
|
+
```json
|
|
538
|
+
{
|
|
539
|
+
"id": "add-login-form",
|
|
540
|
+
"status": "pending",
|
|
541
|
+
"assignedBy": "claude-abc123",
|
|
542
|
+
"description": "Add a login form component",
|
|
543
|
+
"prompt": "Create a React login form at src/components/LoginForm.tsx with email and password fields, validation, and submit handler.",
|
|
544
|
+
"createdAt": "2025-01-15T10:30:00Z",
|
|
545
|
+
"updatedAt": "2025-01-15T10:30:00Z"
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
2. **Aimux detects** the pending task (checks every 2s) and finds an idle agent to handle it
|
|
550
|
+
|
|
551
|
+
3. **The task prompt is injected** into the target agent's stdin — the agent sees it as input and starts working
|
|
552
|
+
|
|
553
|
+
4. **The agent completes the work** and updates the task file with `"status": "done"` and a `"result"` summary
|
|
554
|
+
|
|
555
|
+
5. **Aimux notifies** the original agent that the task is complete
|
|
556
|
+
|
|
557
|
+
### Targeting
|
|
558
|
+
|
|
559
|
+
Tasks can be targeted in three ways:
|
|
560
|
+
|
|
561
|
+
- **Specific agent**: set `assignedTo` to a session ID from `.aimux/sessions.json`
|
|
562
|
+
- **By tool type**: set `tool` to `"claude"`, `"codex"`, or `"aider"` — dispatched to the first idle agent of that type
|
|
563
|
+
- **Any idle agent**: omit both fields — dispatched to any available idle agent
|
|
564
|
+
|
|
565
|
+
### Dashboard indicators
|
|
566
|
+
|
|
567
|
+
- Sessions with active tasks show a purple `⧫` badge with the task description
|
|
568
|
+
- The dashboard footer shows task counts: `[T:2p/1a]` (2 pending, 1 assigned)
|
|
569
|
+
- Flash notifications appear when tasks are assigned, completed, or failed
|
|
570
|
+
|
|
571
|
+
### Using it
|
|
572
|
+
|
|
573
|
+
Just ask your agent to delegate. The preamble tells agents exactly how the protocol works. For example:
|
|
574
|
+
|
|
575
|
+
> "Delegate the test writing to another agent"
|
|
576
|
+
|
|
577
|
+
> "Hand off the CSS cleanup to the codex agent"
|
|
578
|
+
|
|
579
|
+
The agent will create the task file, and aimux handles the rest. This is separate from any native task system in the underlying tools (like Claude Code's internal tasks).
|
|
580
|
+
|
|
581
|
+
## Custom Instructions
|
|
582
|
+
|
|
583
|
+
Create an `AIMUX.md` file to inject instructions into every agent:
|
|
584
|
+
|
|
585
|
+
- **`~/AIMUX.md`** — global instructions (applied to all projects)
|
|
586
|
+
- **`./AIMUX.md`** — project-specific instructions
|
|
587
|
+
|
|
588
|
+
Both are read and appended to the preamble (global first, then project).
|
|
589
|
+
|
|
590
|
+
## Configuration
|
|
591
|
+
|
|
592
|
+
Initialize project config:
|
|
593
|
+
|
|
594
|
+
```bash
|
|
595
|
+
aimux init
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
This creates `.aimux/config.json`. You can also create a global config at `~/.aimux/config.json`. Project config overrides global, which overrides defaults.
|
|
599
|
+
|
|
600
|
+
```json
|
|
601
|
+
{
|
|
602
|
+
"defaultTool": "claude",
|
|
603
|
+
"runtime": {
|
|
604
|
+
"tmux": {
|
|
605
|
+
"sessionPrefix": "aimux"
|
|
606
|
+
}
|
|
607
|
+
},
|
|
608
|
+
"notifications": {
|
|
609
|
+
"enabled": true,
|
|
610
|
+
"onPrompt": true,
|
|
611
|
+
"onError": true,
|
|
612
|
+
"onComplete": true
|
|
613
|
+
},
|
|
614
|
+
"tools": {
|
|
615
|
+
"claude": {
|
|
616
|
+
"command": "claude",
|
|
617
|
+
"args": ["--dangerously-skip-permissions"],
|
|
618
|
+
"enabled": true
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
Tmux runtime:
|
|
625
|
+
|
|
626
|
+
- `sessionPrefix` — deterministic prefix used for managed per-project tmux sessions
|
|
627
|
+
|
|
628
|
+
### Tool Configuration
|
|
629
|
+
|
|
630
|
+
All tool behavior is config-driven. No tool-specific code exists in the multiplexer — adding or customizing a tool only requires config:
|
|
631
|
+
|
|
632
|
+
```json
|
|
633
|
+
{
|
|
634
|
+
"tools": {
|
|
635
|
+
"my-tool": {
|
|
636
|
+
"command": "my-tool",
|
|
637
|
+
"args": ["--some-flag"],
|
|
638
|
+
"enabled": true,
|
|
639
|
+
"preambleFlag": ["--system-prompt"],
|
|
640
|
+
"resumeArgs": ["--resume", "{sessionId}"],
|
|
641
|
+
"resumeFallback": ["--continue"],
|
|
642
|
+
"sessionIdFlag": ["--session-id", "{sessionId}"],
|
|
643
|
+
"sessionCapture": {
|
|
644
|
+
"dir": "{home}/.my-tool/sessions/{yyyy}/{mm}/{dd}",
|
|
645
|
+
"pattern": "([0-9a-f-]+)\\.json$",
|
|
646
|
+
"delayMs": 2000
|
|
647
|
+
},
|
|
648
|
+
"promptPatterns": ["^> $", "^\\$ $"],
|
|
649
|
+
"turnPatterns": ["^[>❯]\\s*(.+)"],
|
|
650
|
+
"compactCommand": "claude --print --output-format text",
|
|
651
|
+
"instructionsFile": "AGENTS.md"
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
| Field | Purpose |
|
|
658
|
+
|---|---|
|
|
659
|
+
| `preambleFlag` | Flag to inject system prompt (e.g. `["--append-system-prompt"]`) |
|
|
660
|
+
| `resumeArgs` | Args to resume a session, with `{sessionId}` placeholder |
|
|
661
|
+
| `resumeFallback` | Fallback resume args when session ID is unavailable |
|
|
662
|
+
| `sessionIdFlag` | Flag to set session ID at spawn time |
|
|
663
|
+
| `sessionCapture` | Filesystem-based session ID capture (dir, regex pattern, delay) |
|
|
664
|
+
| `promptPatterns` | Regex patterns for idle/prompt detection in status bar |
|
|
665
|
+
| `turnPatterns` | Regex patterns for extracting conversation turns from output |
|
|
666
|
+
| `compactCommand` | Shell command for LLM-powered history compaction |
|
|
667
|
+
| `instructionsFile` | File to write preamble to (for tools without system prompt flags) |
|
|
668
|
+
|
|
669
|
+
## Multi-Instance
|
|
670
|
+
|
|
671
|
+
Run aimux in multiple terminal tabs for the same project. Each instance registers in `.aimux/instances.json` with a heartbeat. Agents from other instances appear inline in the dashboard with a `◈` icon.
|
|
672
|
+
|
|
673
|
+
- **Enter** on a remote agent takes it over (resumes in your instance)
|
|
674
|
+
- `--resume` skips agents already owned by another live instance
|
|
675
|
+
- When an instance exits, its agents become offline and visible to other instances
|
|
676
|
+
- Dead instances are auto-pruned via PID checks and heartbeat staleness
|
|
677
|
+
|
|
678
|
+
## Agent Lifecycle
|
|
679
|
+
|
|
680
|
+
Agents have three states: **running**, **offline**, and **graveyarded**.
|
|
681
|
+
|
|
682
|
+
```
|
|
683
|
+
running ──[x]──▶ offline ──[x]──▶ graveyard
|
|
684
|
+
│ │
|
|
685
|
+
◀──Enter── ◀── aimux graveyard resurrect
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
```bash
|
|
689
|
+
# List agents in the graveyard
|
|
690
|
+
aimux graveyard list
|
|
691
|
+
|
|
692
|
+
# Stop to offline
|
|
693
|
+
aimux stop <sessionId>
|
|
694
|
+
|
|
695
|
+
# Send directly to graveyard
|
|
696
|
+
aimux kill <sessionId>
|
|
697
|
+
|
|
698
|
+
# Resurrect an agent back to offline state
|
|
699
|
+
aimux graveyard resurrect <id>
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
Context files (`.aimux/context/`, `.aimux/history/`) are never deleted — only the agent's state changes.
|
|
703
|
+
|
|
704
|
+
## Worktrees
|
|
705
|
+
|
|
706
|
+
aimux manages git worktrees and, by default, creates them inside `.aimux/worktrees/` in the main repo:
|
|
707
|
+
|
|
708
|
+
```bash
|
|
709
|
+
# Spawn a fresh agent
|
|
710
|
+
aimux spawn --tool claude
|
|
711
|
+
|
|
712
|
+
# Fork a live agent into a worktree
|
|
713
|
+
aimux fork <sessionId> --tool codex --worktree /abs/path/to/repo/.aimux/worktrees/fix-auth
|
|
714
|
+
|
|
715
|
+
# Create a worktree
|
|
716
|
+
aimux worktree create fix-auth
|
|
717
|
+
|
|
718
|
+
# List worktrees
|
|
719
|
+
aimux worktree list
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
The create location is configurable via `.aimux/config.json` or `~/.aimux/config.json`:
|
|
723
|
+
|
|
724
|
+
```json
|
|
725
|
+
{
|
|
726
|
+
"worktrees": {
|
|
727
|
+
"baseDir": ".aimux/worktrees"
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
Relative `baseDir` values are resolved from the main repo root. Absolute paths are also supported.
|
|
733
|
+
|
|
734
|
+
## Requirements
|
|
735
|
+
|
|
736
|
+
- macOS (Linux support planned)
|
|
737
|
+
- Node.js >= 18
|
|
738
|
+
- At least one supported AI tool installed: `claude`, `codex`, or `aider`
|
|
739
|
+
- Notifications work out of the box on macOS, Linux, and Windows
|
|
740
|
+
|
|
741
|
+
## License
|
|
742
|
+
|
|
743
|
+
MIT
|