aiterm-mcp 0.22.0 → 0.23.1
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.ja.md +27 -10
- package/README.md +30 -10
- package/dist/core.js +87 -4
- package/dist/index.js +7 -1
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
> **あなたの AI に、ほかの AI を操らせる。** 任意の MCP クライアントから 1 回の呼び出しで、コーディングエージェント(Claude・Codex・Grok・Composer)を永続端末の中に起動し、操作用のセッションを手渡す。何をしているかをトークン削減して読み、次の指示を送る。
|
|
20
20
|
>
|
|
21
|
-
> **これは何か:** AI が握る 1 本の永続 MCP 端末——その中に他のコーディングエージェントも起動できる。`ssh`・`docker exec`・REPL・別エージェントの TUI は、すべてその 1 本の端末の中へ「送るだけのテキスト」として入れ子になる。仕組みはあえて素朴——MCP クライアントが相手エージェントの端末を 1
|
|
21
|
+
> **これは何か:** AI が握る 1 本の永続 MCP 端末——その中に他のコーディングエージェントも起動できる。`ssh`・`docker exec`・REPL・別エージェントの TUI は、すべてその 1 本の端末の中へ「送るだけのテキスト」として入れ子になる。仕組みはあえて素朴——MCP クライアントが相手エージェントの端末を 1 ターンずつ操作するだけ。隠れたプロトコルも・aiterm独自の共有メモリ層も・自律的な交渉も無い。起動したagentは、直接CLIと同じproject/vendorの通常memory・設定を読む。
|
|
22
22
|
>
|
|
23
23
|
> **人が tmux に張り付く必要はない。** aiterm は MCP 越しにプログラムから駆動されるので、「AI が別のエージェントを起動して操作する」のに端末の前に誰も座らなくていい——オーケストレーションのループ・CI ステップ・cron から動かせる。
|
|
24
24
|
>
|
|
@@ -96,6 +96,12 @@ host統合は、kitepon.devの製品開発を支える内部基盤
|
|
|
96
96
|
|
|
97
97
|
13 ツール: 6 つの **PTY ツール**(`pty_open` / `pty_send` / `pty_read` / `pty_key` / `pty_close` / `pty_list`)で 1 本の永続端末を開き・操作し・読む。加えて 4 つの **エージェント起動ツール**(`claude_agent` / `codex_agent` / `grok_agent` / `composer_agent`)が別のコーディングエージェントの TUI を新しい端末の中に起動し、`claude_turn`がdurable caller向けの構造化issue/recoveryを、`claude_approval`が相関済みClaude承認UI中継を、`diagnostics`が安全なfactory readinessを返す。バックエンドは **tmux** なので、MCP サーバや AI クライアントが再起動してもセッションは生き残る。
|
|
98
98
|
|
|
99
|
+
**v0.23.0では、ローカル完結の別vendor向けportable forkを追加した。** どのlauncherでも
|
|
100
|
+
`throughline_source_session`と新しいミッションを`prompt`へ渡すと、PTY作成前にローカルの
|
|
101
|
+
Throughlineから対象sessionの読み取り専用handoff contextを取得する。返された記憶はそのまま
|
|
102
|
+
ミッションの前へ置かれ、元sessionのDB所属は移動もcopyもされない。Throughlineが無い、または
|
|
103
|
+
結果が不正/空ならclean launchへfallbackせず明示失敗する。引数を省略した通常起動は従来どおり。
|
|
104
|
+
|
|
99
105
|
**v0.22.0では4 launcherを完全なプロジェクト共同作業員へ戻した。** 直接CLIを起動した時と同じ
|
|
100
106
|
`HOME`、作業tree、vendor home、project/user/local設定、MCP、plugin、skill、permission、trust、memory、
|
|
101
107
|
session historyをそのまま使う。aitermがlaunchごとに分離するのは完了相関stateだけ。子には
|
|
@@ -167,13 +173,19 @@ $ aiterm-wait --session codex1 --cursor <event_cursor> # exit 0=done / 3=timeo
|
|
|
167
173
|
|
|
168
174
|
| ツール | 起動するもの | 主な引数 |
|
|
169
175
|
| --- | --- | --- |
|
|
170
|
-
| `claude_agent` | Claude Code CLI(Anthropic) | `prompt?`, `model?`, `reasoning_effort?`(`low`/`medium`/`high`/`xhigh`/`max`), `cwd?`, `session_name?` |
|
|
171
|
-
| `codex_agent` | Codex CLI(OpenAI・端末設定/CLI既定、`model?`で上書き) | `prompt?`, `model?`, `reasoning_effort?`(`low`/`medium`/`high`/`xhigh`/`max`/`ultra`), `cwd?`, `session_name?`, `write_scope?` |
|
|
172
|
-
| `grok_agent` | Grok Build(xAI、既定`grok-4.5`、`model?`で上書き) | `prompt?`, `model?`, `reasoning_effort?`は非対応(指定時は明示エラー), `cwd?`, `session_name?`, `write_scope?` |
|
|
173
|
-
| `composer_agent` | Grok Build(xAI、既定`grok-composer-2.5-fast`、`model?`で上書き) | `prompt?`, `model?`, `reasoning_effort?`は非対応(指定時は明示エラー), `cwd?`, `session_name?`, `write_scope?` |
|
|
176
|
+
| `claude_agent` | Claude Code CLI(Anthropic) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?`(`low`/`medium`/`high`/`xhigh`/`max`), `cwd?`, `session_name?` |
|
|
177
|
+
| `codex_agent` | Codex CLI(OpenAI・端末設定/CLI既定、`model?`で上書き) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?`(`low`/`medium`/`high`/`xhigh`/`max`/`ultra`), `cwd?`, `session_name?`, `write_scope?` |
|
|
178
|
+
| `grok_agent` | Grok Build(xAI、既定`grok-4.5`、`model?`で上書き) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?`は非対応(指定時は明示エラー), `cwd?`, `session_name?`, `write_scope?` |
|
|
179
|
+
| `composer_agent` | Grok Build(xAI、既定`grok-composer-2.5-fast`、`model?`で上書き) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?`は非対応(指定時は明示エラー), `cwd?`, `session_name?`, `write_scope?` |
|
|
174
180
|
|
|
175
181
|
各ベンダーのCLIが導入・認証済みであること。CLI不在・不正なmodel/effort・実在しない`cwd`はsession作成前に失敗し、残骸を残さない。ClaudeはさらにPTY作成前に同じCLIの`auth status --json`が`loggedIn:true`を返すことを要求する。4 launcherは通常のvendor credential/config storeをその場で使い、fake `HOME`、private `CODEX_HOME`/`GROK_HOME`、project/user config snapshotを作らない。Claudeだけは完了相関用Stop hook settingsを通常の`user,project,local` settingsへ加算する。Grok/Composerは画面入力欄だけでなく通常sessionの`mcp_init_completed` eventも確認してから送信し、共有MCP初期化中の早送信を防ぐ。相関付きClaudeのactive turn中はC-c以外の`pty_key`と素送信を拒否し、承認UIは`claude_approval`で単発Yes/Noだけを相関付きで中継する。
|
|
176
182
|
|
|
183
|
+
portable forkは任意である。`throughline_source_session`を使う場合、`prompt`は必須の新ミッションとなり、
|
|
184
|
+
`launch_operation_id`とは併用できない。aitermは`THROUGHLINE_BIN`、次に`PATH`からThroughlineを解決し、
|
|
185
|
+
`throughline handoff-context --session <id> --json`のcontextを固定区切りとミッションの前へそのまま置く。
|
|
186
|
+
この経路だけ`throughline >= 0.9.0`が必要で、元sessionのDB所属は変わらない。引数省略時には
|
|
187
|
+
Throughline自体が不要である。
|
|
188
|
+
|
|
177
189
|
エージェント間の隠れたプロトコルは無い。起動したClaude/Codex/Grok/Composerは利用者がattachできるもう1本の永続sessionであり、MCPクライアントが通常のPTY操作で駆動する。
|
|
178
190
|
|
|
179
191
|
## デモ
|
|
@@ -369,13 +381,18 @@ consumer は `aiterm-runtime-errors snapshot` を読み、durable ingestion 後
|
|
|
369
381
|
|
|
370
382
|
| ツール | 起動するもの | 主な引数 |
|
|
371
383
|
| --- | --- | --- |
|
|
372
|
-
| `claude_agent` | Claude Code CLI(Anthropic) | `prompt?`, `model?`, `reasoning_effort?`(`low`/`medium`/`high`/`xhigh`/`max`), `cwd?`, `session_name?` |
|
|
373
|
-
| `codex_agent` | Codex CLI(OpenAI・端末設定/CLI既定、`model?`で上書き) | `prompt?`, `model?`, `reasoning_effort?`(`low`/`medium`/`high`/`xhigh`/`max`/`ultra`), `cwd?`, `session_name?`, `write_scope?` |
|
|
374
|
-
| `grok_agent` | Grok Build(xAI、既定`grok-4.5`、`model?`で上書き) | `prompt?`, `model?`, `reasoning_effort?`は非対応(指定時は明示エラー), `cwd?`, `session_name?`, `write_scope?` |
|
|
375
|
-
| `composer_agent` | Grok Build(xAI、既定`grok-composer-2.5-fast`、`model?`で上書き) | `prompt?`, `model?`, `reasoning_effort?`は非対応(指定時は明示エラー), `cwd?`, `session_name?`, `write_scope?` |
|
|
384
|
+
| `claude_agent` | Claude Code CLI(Anthropic) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?`(`low`/`medium`/`high`/`xhigh`/`max`), `cwd?`, `session_name?` |
|
|
385
|
+
| `codex_agent` | Codex CLI(OpenAI・端末設定/CLI既定、`model?`で上書き) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?`(`low`/`medium`/`high`/`xhigh`/`max`/`ultra`), `cwd?`, `session_name?`, `write_scope?` |
|
|
386
|
+
| `grok_agent` | Grok Build(xAI、既定`grok-4.5`、`model?`で上書き) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?`は非対応(指定時は明示エラー), `cwd?`, `session_name?`, `write_scope?` |
|
|
387
|
+
| `composer_agent` | Grok Build(xAI、既定`grok-composer-2.5-fast`、`model?`で上書き) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?`は非対応(指定時は明示エラー), `cwd?`, `session_name?`, `write_scope?` |
|
|
376
388
|
|
|
377
389
|
対応するCLI(`claude` / `codex` / `grok`)の導入・認証が必要。前提違反はsession作成前に明示失敗する。4 launcherすべてが通常project/user環境と同じ非ブロックdispatch契約を使う。Claude/Codex/Grok/Composerのdepth 1 live smokeと、Claude親→Claude孫のdepth 2 nested delegation smokeはgreenであり、fixtureによる検証とは区別して記録する。
|
|
378
390
|
|
|
391
|
+
`throughline_source_session`と空でない新ミッション`prompt`を指定すると、Throughlineの読み取り専用
|
|
392
|
+
handoff contextを前置きできる。この任意経路は`throughline >= 0.9.0`を必要とし、
|
|
393
|
+
`launch_operation_id`とは併用不可で、元sessionのDB所属を変更しない。Throughlineは
|
|
394
|
+
`THROUGHLINE_BIN`、次に`PATH`から解決し、不在・不正・空のexportはPTY作成前に明示失敗する。
|
|
395
|
+
|
|
379
396
|
エージェントの回答が画面 tailより長ければ、対話callerは`pty_read({ agent_transcript:true })`で再promptなしに全文回収する。Claudeはlaunch相関付きStop hookのowner-only resultを検証し、private transcriptを読まない。Codexは通常rollout transcript、Grok/Composerは通常session historyから同じturnを回収する。不在・非agent・抽出不能は明示エラー。
|
|
380
397
|
|
|
381
398
|
### 完了検出(5 層)
|
|
@@ -404,7 +421,7 @@ consumer は `aiterm-runtime-errors snapshot` を読み、durable ingestion 後
|
|
|
404
421
|
- **tmux**(実行時の前提。`tmux -V` で確認。未導入なら `apt install tmux` / `brew install tmux`)
|
|
405
422
|
- **macOS / Linux / WSL2** は tmux を直接使う。macOS は同梱されないので `brew install tmux` で導入する。MCP クライアントがターミナルでなく **GUI から起動**された場合、Homebrew の bin(Apple Silicon: `/opt/homebrew/bin`、Intel: `/usr/local/bin`)が `PATH` に入らないことがある。その場合 aiterm が自動で探索するか、**`AITERM_TMUX=/path/to/tmux`** で明示指定する。
|
|
406
423
|
- **Windows ネイティブ**には tmux が無いため、aiterm は裏で **WSL の中の tmux** を透過的に使う。[WSL](https://learn.microsoft.com/ja-jp/windows/wsl/) を導入・初期化し、**WSL のディストリ内に tmux を入れる**こと(`sudo apt install tmux`)。`wsl tmux -V` で確認できる。セッション・ソケット・人の `attach` はすべて WSL 側にあり、AI は Windows 側のコマンドから操作するだけ。(Windows のツールは SSH と同じく入れ子で握る: `pty_send "powershell.exe …"` で PowerShell に入る。)
|
|
407
|
-
- **エージェント起動ツール**を使う場合: 対応するベンダー CLI が導入・認証済みであること——`claude_agent` は `claude`、`codex_agent` は `codex`、`grok_agent` / `composer_agent` は `grok
|
|
424
|
+
- **エージェント起動ツール**を使う場合: 対応するベンダー CLI が導入・認証済みであること——`claude_agent` は `claude`、`codex_agent` は `codex`、`grok_agent` / `composer_agent` は `grok`。portable forkだけは追加で`throughline >= 0.9.0`が必要だが、通常のclean launchには不要。(PTY ツールだけ使うなら不要。)
|
|
408
425
|
- 任意: [`rtk`](https://github.com/rtk-ai/rtk) バイナリ(`pty_send` の `rtk: true` 委譲で使う。無くても動く)
|
|
409
426
|
|
|
410
427
|
## 既知の制約(バグではなく仕様)
|
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
> **Let your AI orchestrate other AIs.** From any MCP client, one call spawns a coding agent (Claude, Codex, Grok, or Composer) inside a persistent terminal and hands you a session to drive: read what it's doing token-reduced, send it the next instruction.
|
|
20
20
|
>
|
|
21
|
-
> **What it is:** one persistent MCP terminal your AI drives — and can launch other coding agents into. `ssh`, `docker exec`, a REPL, or another agent's TUI all nest inside that one terminal as just text you send in. The mechanism is deliberately plain — your MCP client drives the other agent's terminal turn by turn: no hidden protocol, no shared
|
|
21
|
+
> **What it is:** one persistent MCP terminal your AI drives — and can launch other coding agents into. `ssh`, `docker exec`, a REPL, or another agent's TUI all nest inside that one terminal as just text you send in. The mechanism is deliberately plain — your MCP client drives the other agent's terminal turn by turn: no hidden protocol, no separate aiterm-owned shared-memory layer, no autonomous negotiation. Launched agents still read the normal project and vendor memory/configuration that a direct CLI launch would use.
|
|
22
22
|
>
|
|
23
23
|
> **No human at a tmux required.** aiterm is driven programmatically over MCP, so an AI can launch and drive another agent with no one sitting in the terminal — from an orchestration loop, a CI step, or a cron job.
|
|
24
24
|
>
|
|
@@ -96,6 +96,13 @@ toolchain behind kitepon.dev's products.
|
|
|
96
96
|
|
|
97
97
|
Thirteen tools: six **PTY tools** — `pty_open` / `pty_send` / `pty_read` / `pty_key` / `pty_close` / `pty_list` — to open, drive, and read one persistent terminal, four **agent launchers** — `claude_agent` / `codex_agent` / `grok_agent` / `composer_agent` — that each start another coding agent's TUI inside a fresh one, `claude_turn` for durable structured issue/recovery, `claude_approval` for correlated Claude approval prompts, and `diagnostics` for safe factory readiness. The backend is **tmux**, so sessions survive even if the MCP server or the AI client restarts.
|
|
98
98
|
|
|
99
|
+
**v0.23.0 adds a local, cross-vendor portable fork.** Pass `throughline_source_session`
|
|
100
|
+
with a mission in `prompt` to any launcher, and aiterm asks the locally installed Throughline
|
|
101
|
+
for that session's read-only handoff context before creating the PTY. The exact returned memory
|
|
102
|
+
is prepended to the mission without moving or copying the source session's database ownership.
|
|
103
|
+
If Throughline is missing or returns an invalid/empty result, launch fails visibly with no clean
|
|
104
|
+
fallback. Omitting the field preserves the ordinary clean launch.
|
|
105
|
+
|
|
99
106
|
**v0.22.0 makes launched agents full project collaborators.** All four launchers now use the
|
|
100
107
|
same normal `HOME`, working tree, vendor home, project/user/local configuration, MCP servers,
|
|
101
108
|
plugins, skills, permissions, trust, memory, and session history as a direct CLI launch. Aiterm
|
|
@@ -185,13 +192,20 @@ One call per model, so the tool name itself tells you which model you get:
|
|
|
185
192
|
|
|
186
193
|
| Tool | Launches | Key args |
|
|
187
194
|
| --- | --- | --- |
|
|
188
|
-
| `claude_agent` | Claude Code CLI (Anthropic) | `prompt?`, `model?`, `reasoning_effort?` (`low`/`medium`/`high`/`xhigh`/`max`), `cwd?`, `session_name?`, `launch_operation_id?` |
|
|
189
|
-
| `codex_agent` | Codex CLI (OpenAI; terminal config/CLI default unless overridden) | `prompt?`, `model?`, `reasoning_effort?` (`low`/`medium`/`high`/`xhigh`/`max`/`ultra`; ultra enables proactive automatic delegation), `cwd?`, `session_name?`, `write_scope?` |
|
|
190
|
-
| `grok_agent` | Grok Build, model `grok-4.5` by default (`model?` overrides) (xAI) | `prompt?`, `model?`, `reasoning_effort?` unsupported (an explicit value is an error; Grok CLI `--effort` is headless-only), `cwd?`, `session_name?`, `write_scope?` |
|
|
191
|
-
| `composer_agent` | Grok Build, model `grok-composer-2.5-fast` by default (`model?` overrides) (xAI) | `prompt?`, `model?`, `reasoning_effort?` unsupported (an explicit value is an error), `cwd?`, `session_name?`, `write_scope?` |
|
|
195
|
+
| `claude_agent` | Claude Code CLI (Anthropic) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?` (`low`/`medium`/`high`/`xhigh`/`max`), `cwd?`, `session_name?`, `launch_operation_id?` |
|
|
196
|
+
| `codex_agent` | Codex CLI (OpenAI; terminal config/CLI default unless overridden) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?` (`low`/`medium`/`high`/`xhigh`/`max`/`ultra`; ultra enables proactive automatic delegation), `cwd?`, `session_name?`, `write_scope?` |
|
|
197
|
+
| `grok_agent` | Grok Build, model `grok-4.5` by default (`model?` overrides) (xAI) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?` unsupported (an explicit value is an error; Grok CLI `--effort` is headless-only), `cwd?`, `session_name?`, `write_scope?` |
|
|
198
|
+
| `composer_agent` | Grok Build, model `grok-composer-2.5-fast` by default (`model?` overrides) (xAI) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?` unsupported (an explicit value is an error), `cwd?`, `session_name?`, `write_scope?` |
|
|
192
199
|
|
|
193
200
|
The vendor CLI must be installed and authenticated (`claude` for `claude_agent`; `codex` for `codex_agent`; `grok` for both Grok tools). aiterm resolves the binary via `CLAUDE_BIN` / `CODEX_BIN` / `GROK_BIN`, then each documented default location, then `PATH`. Prerequisites are checked **before** a session exists: empty `model` values and unsupported effort values are rejected up front; a missing CLI binary or a nonexistent `cwd` fails for all four. Before creating a Claude session, aiterm also requires a successful structured `claude auth status --json` result with `loggedIn: true`; unavailable, malformed, or failed authentication leaves **zero leftover session**. All launchers use the normal vendor-owned credential and configuration stores in place. No launcher creates a fake `HOME`, a private `CODEX_HOME`/`GROK_HOME`, or a snapshot of project/user configuration.
|
|
194
201
|
|
|
202
|
+
Portable fork is optional. When `throughline_source_session` is present, `prompt` is the required
|
|
203
|
+
new mission and `launch_operation_id` cannot be combined with it. aiterm resolves Throughline via
|
|
204
|
+
`THROUGHLINE_BIN` and then `PATH`, runs `throughline handoff-context --session <id> --json`, and
|
|
205
|
+
places its returned context before a fixed separator and the mission. This route requires
|
|
206
|
+
`throughline >= 0.9.0`; it reads the source memory without changing that database's session
|
|
207
|
+
ownership. No Throughline dependency is needed when the field is omitted.
|
|
208
|
+
|
|
195
209
|
Claude and Codex launchers forward `model` and `reasoning_effort` through public CLI flags; Grok/Composer reject `reasoning_effort` because it is headless-only. Pass an absolute path for `cwd` — `~` is not expanded. Durable callers can make a promptless Claude launch exactly replayable by passing an explicit `session_name` and `launch_operation_id`. Claude adds a launch-local settings file only for the correlated Stop hook and loads it together with normal `user,project,local` setting sources; it does not replace normal hooks, MCPs, plugins, permissions, or trust state. The hook event contains no answer body, and the bounded owner-only result is returned by `pty_read({ agent_transcript:true })` without reading Claude's private transcript. While a correlated Claude turn is active, raw sends and non-interrupt keys are rejected. Exact `/login` and `/logout` dispatches are rejected so shared authentication is repaired once in a normal terminal. Codex reads its normal rollout store; Grok/Composer read their normal session event/history files. Before dispatch, Codex waits for an idle TUI, while Grok/Composer additionally require the vendor's structured `mcp_init_completed` event so a visible input box cannot accept a prompt too early. Correlated completion requires POSIX filesystem semantics (Linux, WSL2, macOS).
|
|
196
210
|
|
|
197
211
|
There is no hidden protocol between agents: a launched Claude, Codex, Grok, or Composer is another user-visible persistent terminal session. The MCP client drives that TUI with ordinary PTY operations, and a human can attach to watch or take over.
|
|
@@ -391,13 +405,19 @@ Each launcher starts a specific vendor's interactive coding-agent TUI inside a f
|
|
|
391
405
|
|
|
392
406
|
| Tool | Launches | Key args |
|
|
393
407
|
| --- | --- | --- |
|
|
394
|
-
| `claude_agent` | Claude Code CLI (Anthropic) | `prompt?`, `model?`, `reasoning_effort?` (`low`/`medium`/`high`/`xhigh`/`max`), `cwd?`, `session_name?`, `launch_operation_id?` |
|
|
395
|
-
| `codex_agent` | Codex CLI (OpenAI; terminal config/CLI default unless overridden) | `prompt?`, `model?`, `reasoning_effort?` (`low`/`medium`/`high`/`xhigh`/`max`/`ultra`; ultra enables proactive automatic delegation), `cwd?`, `session_name?`, `write_scope?` |
|
|
396
|
-
| `grok_agent` | Grok Build, model `grok-4.5` by default (`model?` overrides) (xAI) | `prompt?`, `model?`, `reasoning_effort?` unsupported (an explicit value is an error; Grok CLI `--effort` is headless-only), `cwd?`, `session_name?`, `write_scope?` |
|
|
397
|
-
| `composer_agent` | Grok Build, model `grok-composer-2.5-fast` by default (`model?` overrides) (xAI) | `prompt?`, `model?`, `reasoning_effort?` unsupported (an explicit value is an error), `cwd?`, `session_name?`, `write_scope?` |
|
|
408
|
+
| `claude_agent` | Claude Code CLI (Anthropic) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?` (`low`/`medium`/`high`/`xhigh`/`max`), `cwd?`, `session_name?`, `launch_operation_id?` |
|
|
409
|
+
| `codex_agent` | Codex CLI (OpenAI; terminal config/CLI default unless overridden) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?` (`low`/`medium`/`high`/`xhigh`/`max`/`ultra`; ultra enables proactive automatic delegation), `cwd?`, `session_name?`, `write_scope?` |
|
|
410
|
+
| `grok_agent` | Grok Build, model `grok-4.5` by default (`model?` overrides) (xAI) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?` unsupported (an explicit value is an error; Grok CLI `--effort` is headless-only), `cwd?`, `session_name?`, `write_scope?` |
|
|
411
|
+
| `composer_agent` | Grok Build, model `grok-composer-2.5-fast` by default (`model?` overrides) (xAI) | `prompt?`, `throughline_source_session?`, `model?`, `reasoning_effort?` unsupported (an explicit value is an error), `cwd?`, `session_name?`, `write_scope?` |
|
|
398
412
|
|
|
399
413
|
The vendor CLI must be installed and authenticated (`claude` for `claude_agent`; `codex` for `codex_agent`; `grok` for both Grok tools). Binary resolution uses `CLAUDE_BIN` / `CODEX_BIN` / `GROK_BIN`, then each documented default location, then `PATH`. Missing binaries, invalid model/effort values, and nonexistent `cwd` fail before a session is created. Claude additionally requires a structured healthy authentication status before any PTY exists, and correlated Claude sessions reject `/login` and `/logout`; repair authentication once in a normal terminal. All four launchers share the normal project/user environment and the same non-blocking dispatch contract. Claude, Codex, Grok, and Composer depth-1 live smokes and a Claude depth-2 nested-delegation smoke are green; fixture coverage remains a separate claim. Native Windows can launch agents but correlated completion is not supported yet.
|
|
400
414
|
|
|
415
|
+
Set `throughline_source_session` together with a non-empty mission in `prompt` to prepend
|
|
416
|
+
Throughline's read-only handoff context. This optional route requires `throughline >= 0.9.0`,
|
|
417
|
+
cannot be combined with `launch_operation_id`, and leaves the source session's database ownership
|
|
418
|
+
unchanged. Throughline is resolved through `THROUGHLINE_BIN` and then `PATH`; a missing or invalid
|
|
419
|
+
export fails before the PTY exists instead of silently launching clean.
|
|
420
|
+
|
|
401
421
|
When an agent's answer is longer than the on-screen tail (pane height ≈ 24 lines), callers recover it in full with `pty_read({ agent_transcript: true })`. It returns the most recently completed turn's final assistant message in plain text with no re-prompting. Claude reads the bounded owner-only result captured by the launch-correlated Stop hook and verifies its digest/byte count; it never reads Claude's private transcript. Durable machine callers should use `claude_turn`: `issue` sends once, `recover` never sends, `pending` is distinct from unsafe or malformed state, and only `completed` carries the exact verified `raw_output`. Codex uses the normal rollout transcript's `task_complete.turn_id`; Grok/Composer use their normal session history after the last real user row. Missing or ambiguous attribution remains an explicit error.
|
|
402
422
|
|
|
403
423
|
### Completion detection (5 layers)
|
|
@@ -439,7 +459,7 @@ Sessions live on a shared tmux socket. The `tmux -S … attach -t <id>` line pri
|
|
|
439
459
|
- **tmux** (runtime prerequisite; check with `tmux -V`. Install with `apt install tmux` / `brew install tmux`)
|
|
440
460
|
- **macOS / Linux / WSL2** run tmux directly. On macOS install it with `brew install tmux` (stock macOS ships none). If your MCP client is launched from the **GUI** rather than a terminal, Homebrew's bin (`/opt/homebrew/bin` on Apple Silicon, `/usr/local/bin` on Intel) may be off its `PATH`; aiterm auto-searches those locations, or set **`AITERM_TMUX=/path/to/tmux`** to point at it explicitly.
|
|
441
461
|
- **Native Windows** has no tmux, so aiterm transparently runs tmux **inside WSL**. It needs [WSL](https://learn.microsoft.com/windows/wsl/) installed and initialized, with **tmux installed inside your WSL distro** (`sudo apt install tmux`); verify with `wsl tmux -V`. Sessions, the socket, and human `attach` all live on the WSL side — the AI just drives them from the Windows-side command. (You reach Windows tools the same way you reach SSH: `pty_send "powershell.exe …"` nests into PowerShell.)
|
|
442
|
-
- For the **agent launchers**: the corresponding vendor CLI, installed and authenticated — `claude` for `claude_agent`, `codex` for `codex_agent`, `grok` for `grok_agent` / `composer_agent`. (Not needed if you only use the PTY tools.)
|
|
462
|
+
- For the **agent launchers**: the corresponding vendor CLI, installed and authenticated — `claude` for `claude_agent`, `codex` for `codex_agent`, `grok` for `grok_agent` / `composer_agent`. Portable fork additionally needs `throughline >= 0.9.0`; ordinary clean launch does not. (Not needed if you only use the PTY tools.)
|
|
443
463
|
- Optional: the [`rtk`](https://github.com/rtk-ai/rtk) binary (used by `pty_send`'s `rtk: true` delegation; works fine without it)
|
|
444
464
|
|
|
445
465
|
## Known constraints (by design, not bugs)
|
package/dist/core.js
CHANGED
|
@@ -342,9 +342,14 @@ function assertSessionName(name) {
|
|
|
342
342
|
throw new AitermError(`session 名は英数字と _ - のみ・64文字以内にしてください: ${JSON.stringify(name)}`, 2);
|
|
343
343
|
}
|
|
344
344
|
function currentUid() {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
345
|
+
// Windows(native)は process.getuid を持たない。以前はここで throw していたが、
|
|
346
|
+
// agent metadata の存在確認経由で素の pty_send まで巻き込んで全 send を殺していた。
|
|
347
|
+
// Windows の fs.Stats.uid は常に 0 なので、ここも 0 を返せば owner 比較
|
|
348
|
+
// (st.uid !== currentUid()) は自然に通過する。Windows は POSIX owner 検証を
|
|
349
|
+
// 持たない(NTFS ACL は別体系)という既知の制約の明示的受容であり、POSIX 側は
|
|
350
|
+
// getuid をそのまま返すため挙動不変。
|
|
351
|
+
if (typeof process.getuid !== "function")
|
|
352
|
+
return 0;
|
|
348
353
|
return process.getuid();
|
|
349
354
|
}
|
|
350
355
|
function runtimeStateBase() {
|
|
@@ -3752,6 +3757,71 @@ function isUsableExecutableFile(candidate) {
|
|
|
3752
3757
|
return false;
|
|
3753
3758
|
}
|
|
3754
3759
|
}
|
|
3760
|
+
const THROUGHLINE_HANDOFF_CONTEXT_SCHEMA = "throughline.handoff_context.v1";
|
|
3761
|
+
const PORTABLE_FORK_MISSION_SEPARATOR = "\n\n---\n\n## Portable fork mission\n\n";
|
|
3762
|
+
function resolveThroughlineBin() {
|
|
3763
|
+
const fromEnv = process.env.THROUGHLINE_BIN;
|
|
3764
|
+
if (fromEnv)
|
|
3765
|
+
return isUsableExecutableFile(fromEnv) ? fromEnv : null;
|
|
3766
|
+
const resolved = spawnSync(isWin ? "where" : "which", ["throughline"], {
|
|
3767
|
+
encoding: "utf8",
|
|
3768
|
+
}).stdout?.split(/\r?\n/).find(Boolean) ?? null;
|
|
3769
|
+
return resolved && isUsableExecutableFile(resolved) ? resolved : null;
|
|
3770
|
+
}
|
|
3771
|
+
function runThroughlineHandoffContext(bin, sessionId) {
|
|
3772
|
+
if (isWin && /\.(?:cmd|bat)$/i.test(bin)) {
|
|
3773
|
+
const ps1 = path.join(path.dirname(bin), `${path.basename(bin, path.extname(bin))}.ps1`);
|
|
3774
|
+
if (fs.existsSync(ps1)) {
|
|
3775
|
+
return spawnSync("powershell.exe", [
|
|
3776
|
+
"-NoLogo",
|
|
3777
|
+
"-NoProfile",
|
|
3778
|
+
"-NonInteractive",
|
|
3779
|
+
"-ExecutionPolicy",
|
|
3780
|
+
"Bypass",
|
|
3781
|
+
"-File",
|
|
3782
|
+
ps1,
|
|
3783
|
+
"handoff-context",
|
|
3784
|
+
"--session",
|
|
3785
|
+
sessionId,
|
|
3786
|
+
"--json",
|
|
3787
|
+
], { encoding: "utf8" });
|
|
3788
|
+
}
|
|
3789
|
+
}
|
|
3790
|
+
return spawnSync(bin, ["handoff-context", "--session", sessionId, "--json"], {
|
|
3791
|
+
encoding: "utf8",
|
|
3792
|
+
});
|
|
3793
|
+
}
|
|
3794
|
+
export function composePortableForkPrompt(context, mission) {
|
|
3795
|
+
return context + PORTABLE_FORK_MISSION_SEPARATOR + mission;
|
|
3796
|
+
}
|
|
3797
|
+
function portableForkPrompt(sourceSessionId, mission) {
|
|
3798
|
+
const bin = resolveThroughlineBin();
|
|
3799
|
+
if (!bin) {
|
|
3800
|
+
throw new AitermError("Throughline CLIが見つかりません。portable forkのsessionは作成していません", 2);
|
|
3801
|
+
}
|
|
3802
|
+
const result = runThroughlineHandoffContext(bin, sourceSessionId);
|
|
3803
|
+
if (result.error || result.status !== 0) {
|
|
3804
|
+
throw new AitermError("Throughline handoff-contextの取得に失敗しました。portable forkのsessionは作成していません", 2);
|
|
3805
|
+
}
|
|
3806
|
+
let value;
|
|
3807
|
+
try {
|
|
3808
|
+
value = JSON.parse(result.stdout ?? "");
|
|
3809
|
+
}
|
|
3810
|
+
catch {
|
|
3811
|
+
value = null;
|
|
3812
|
+
}
|
|
3813
|
+
if (value === null ||
|
|
3814
|
+
typeof value !== "object" ||
|
|
3815
|
+
Array.isArray(value) ||
|
|
3816
|
+
value.schema !== THROUGHLINE_HANDOFF_CONTEXT_SCHEMA ||
|
|
3817
|
+
value.status !== "ready" ||
|
|
3818
|
+
value.sessionId !== sourceSessionId ||
|
|
3819
|
+
typeof value.context !== "string" ||
|
|
3820
|
+
!value.context.trim()) {
|
|
3821
|
+
throw new AitermError("Throughline handoff-contextの応答が不正です。portable forkのsessionは作成していません", 2);
|
|
3822
|
+
}
|
|
3823
|
+
return composePortableForkPrompt(value.context, mission);
|
|
3824
|
+
}
|
|
3755
3825
|
/** vendor CLI の存在だけを安全に要約する。認証状態・実行出力・解決先 path は返さない。 */
|
|
3756
3826
|
export function vendorLauncherDiagnostic(kind) {
|
|
3757
3827
|
try {
|
|
@@ -4083,7 +4153,20 @@ export function openAgent(kind, opts = {}) {
|
|
|
4083
4153
|
];
|
|
4084
4154
|
}
|
|
4085
4155
|
export async function openAgentWithInitialPrompt(kind, opts = {}) {
|
|
4086
|
-
const
|
|
4156
|
+
const mission = opts.prompt ?? null;
|
|
4157
|
+
const sourceSessionId = opts.throughline_source_session ?? null;
|
|
4158
|
+
if (sourceSessionId !== null && !sourceSessionId.length) {
|
|
4159
|
+
throw new AitermError("throughline_source_sessionが空文字です", 2);
|
|
4160
|
+
}
|
|
4161
|
+
if (sourceSessionId !== null && (mission === null || !mission.trim())) {
|
|
4162
|
+
throw new AitermError("throughline_source_session指定時はpromptにmissionが必要です", 2);
|
|
4163
|
+
}
|
|
4164
|
+
if (sourceSessionId !== null && opts.launch_operation_id != null) {
|
|
4165
|
+
throw new AitermError("throughline_source_sessionはlaunch_operation_idと併用できません", 2);
|
|
4166
|
+
}
|
|
4167
|
+
const prompt = sourceSessionId === null
|
|
4168
|
+
? mission
|
|
4169
|
+
: portableForkPrompt(sourceSessionId, mission);
|
|
4087
4170
|
if (opts.launch_operation_id != null && prompt !== null) {
|
|
4088
4171
|
throw new AitermError("launch_operation_idはpromptなしのClaude相関launchだけで指定できます", 2);
|
|
4089
4172
|
}
|
package/dist/index.js
CHANGED
|
@@ -447,6 +447,11 @@ function registerAgentTool(toolName, kind, desc) {
|
|
|
447
447
|
description: desc,
|
|
448
448
|
inputSchema: {
|
|
449
449
|
prompt: z.string().nullish().describe("起動時に渡す初手プロンプト(任意)。送信後は待たずに即返る"),
|
|
450
|
+
throughline_source_session: z
|
|
451
|
+
.string()
|
|
452
|
+
.min(1)
|
|
453
|
+
.optional()
|
|
454
|
+
.describe("同一端末のThroughline sessionから所有権を変えずに記憶を読み、promptのmissionより前へ注入する"),
|
|
450
455
|
model: z.string().nullish().describe(agentModelDesc(kind)),
|
|
451
456
|
// grok/composer の effort は対話 TUI で無効(headless 専用)=core 側が起動前に明示エラーで拒否。
|
|
452
457
|
// codex は CLI 側の値集合が版で変わるため縛らない(core 側も同方針)。
|
|
@@ -470,10 +475,11 @@ function registerAgentTool(toolName, kind, desc) {
|
|
|
470
475
|
submit_residue: z.boolean().nullable(),
|
|
471
476
|
...writeScopeOutputSchema,
|
|
472
477
|
},
|
|
473
|
-
}, async ({ prompt, model, reasoning_effort, cwd, session_name, launch_operation_id, write_scope }) => {
|
|
478
|
+
}, async ({ prompt, throughline_source_session, model, reasoning_effort, cwd, session_name, launch_operation_id, write_scope }) => {
|
|
474
479
|
try {
|
|
475
480
|
const [sid, hint, eventCursor, submitResidue] = await core.openAgentWithInitialPrompt(kind, {
|
|
476
481
|
prompt: prompt ?? undefined,
|
|
482
|
+
throughline_source_session,
|
|
477
483
|
model: model ?? undefined,
|
|
478
484
|
reasoning_effort: reasoning_effort ?? undefined,
|
|
479
485
|
cwd: cwd ?? undefined,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aiterm-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.1",
|
|
4
4
|
"mcpName": "io.github.kitepon-rgb/aiterm-mcp",
|
|
5
5
|
"description": "Persistent tmux terminal MCP that lets Claude Code drive Codex CLI's interactive TUI, including slash commands and $imagegen. Also runs durable PTY sessions for SSH, containers, REPLs, and coding agents.",
|
|
6
6
|
"keywords": [
|