aiterm-mcp 0.21.4 → 0.23.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.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
  >
@@ -94,21 +94,30 @@ host統合は、kitepon.devの製品開発を支える内部基盤
94
94
 
95
95
  **言葉でなく実測で:** 記録済み203テストのベンチマークでは、`pty_read` はコンテキストに載るトークンを生ログの **約 7.1 分の 1** に減らす。しかも pass/fail の判定は畳んでも残る。→ [組み込みシェルツールとの使い分け](#組み込みシェルツールとの使い分け)
96
96
 
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`がmanaged Claudeの相関済み承認UI中継を、`diagnostics`が安全なfactory readinessを返す。バックエンドは **tmux** なので、MCP サーバや AI クライアントが再起動してもセッションは生き残る。
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.21.4ではfresh managed Claudeからuser scope MCPを復元。** 通常hook、plugin、permission、
100
- project/local MCPの隔離は維持し、`~/.claude.json`で既にuser scope登録された`mcpServers`だけを
101
- owner-onlyのlaunch設定へsnapshotする。破損したuser MCP設定は、toolなしで黙って起動せずsession作成前に失敗する。
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
+
105
+ **v0.22.0では4 launcherを完全なプロジェクト共同作業員へ戻した。** 直接CLIを起動した時と同じ
106
+ `HOME`、作業tree、vendor home、project/user/local設定、MCP、plugin、skill、permission、trust、memory、
107
+ session historyをそのまま使う。aitermがlaunchごとに分離するのは完了相関stateだけ。子には
108
+ `role=subagent`、親session、delegation depth、lineage、`delegation_allowed=true`を注入する。
109
+ 孫以降への再委譲は禁止せず、孫はdepth 2と伸びたlineageを受け取る。既存receiptの
110
+ `managed_completion`は後方互換fieldとして残るが、意味は「完了相関あり」であり環境隔離ではない。
102
111
 
103
112
  **v0.21.3ではCodexの完了経路からStop hookを撤去。** Codexの完了通知と最終回答の帰属は、
104
113
  root rollout transcriptへ永続化される`task_complete.turn_id`をdispatch byte境界以後から観測する。
105
114
  hookの実行ファイルが壊れたり消えたりしても`aiterm-wait`は座礁しない。v0.21.0では外部agent launcherへ
106
115
  明示的な`write_scope`能力宣言を追加し、v0.21.3で指定したscopeと実効性がstructured launch receiptへ
107
- 確実に残るよう修正した。v0.20.3では、壊れた認証から複数のmanaged Claude/Fable
116
+ 確実に残るよう修正した。v0.20.3では、壊れた認証から複数の相関付きClaude/Fable
108
117
  sessionが同時にloginへ流れる問題を修理し、新規Claude起動はPTY作成前にvendor所有の共有認証を検証する。
109
118
  v0.20では、待たずに一度だけ観測する
110
119
  `aiterm-wait --timeout 0` の未完了を、実際に待って終わらなかった`timeout`と区別し、
111
- `running`(exit 5)で返すようにしました。v0.19系では相関済みmanaged Claude approval中継を追加し、
120
+ `running`(exit 5)で返すようにしました。v0.19系では相関済みClaude approval中継を追加し、
112
121
  複数行shell配送を維持し、native Windowsのfactory diagnosticsを拡張しました。
113
122
  v0.16/0.17以来、親エージェントはaiterm上で一切ブロックしません:
114
123
  agent session への send は常に非ブロック dispatch になり、完了待ちは `aiterm-wait` 一本
@@ -142,7 +151,9 @@ pty_read(id, { wait: true }) → 削減済みの出力を読む(完了
142
151
 
143
152
  ### 2. その端末の中に他のコーディングエージェントを起動する — オーケストレーションの旗艦
144
153
 
145
- 同じ primitive が別エージェントの TUI を宿す。4 つの起動ツールが、Claude/Codex/Grok/Composer の対話 TUI を新しい永続端末の中に起動し、`session_id` を返す。既存の人間向けtextに加えて`aiterm.agent-launch-result.v1` structured receiptも返すため、durable callerは表示文字列を解析せずsession handleを取得できる。以後は同じ `pty_read` / `pty_send` で継続操作する。**起動は常に managed**で、Codexはroot rollout transcriptの`task_complete`、Claude/Grokは隔離されたmanaged Stop hookを完了正本に使う。agent session への `pty_send` は非ブロックの **dispatch** になり `event_cursor` 入り receipt を即返す。完了通知は `aiterm-wait --session <id> --cursor <event_cursor>` をホストのバックグラウンドタスクとして実行し、exit 時に receipt の `outcome` で判定する(exit 0=done / 3=timeout=未完了・既定600秒 / 4=closed。親はブロックもポーリングもしない)。起動時 `prompt` を渡した launch は structured receipt にコピペ可能な `wait_command` と `event_cursor`、そして `submit_residue` 観測を含む(true=prompt が composer に未 submit で残存している疑い=案内に従い画面確認から復旧 / false=残存観測せず・成立の保証ではない / null=対象外)。dispatch receipt にも同じ観測が付く。durable machine callerは`claude_turn({ action:"issue"|"recover", session_id, operation_id, ... })`を使い、人間向けerror文字列を解析せず`accepted`/`pending`/`completed`/`unknown`を判定できる。recoveryは再送せず、検証済み完了だけがexact `raw_output`を持つ。通常の`pty_send`/`pty_read`は対話callerと人間向けに維持する。`C-c`後もClaude markerを保持し、Stopが来なければsessionをcloseする。`claude_agent` と `codex_agent` の初回 `prompt` は ready gate 経由で送信して待たずに返る(Grok/Composer は argv 渡し)。手動でキー操作したい場合は `pty_open` で素の端末を開き vendor CLI を自分で起動する。
154
+ 同じ primitive が別エージェントの TUI を宿す。4 つの起動ツールが、Claude/Codex/Grok/Composer の対話 TUI を新しい永続端末の中に起動し、`session_id` を返す。起動processは直接CLIと同じproject/user環境を使い、通常config、MCP、plugin、skill、permission、trust、memory、historyをcopy・filter・置換しない。aitermが加えるのは完了相関と、`role=subagent`、親session、delegation depth、lineage、`delegation_allowed=true`を持つ非user instructionだけ。孫以降の委譲も許可され、固定depth capはない。
155
+
156
+ 既存の人間向けtextに加えて`aiterm.agent-launch-result.v1` structured receiptも返すため、durable callerは表示文字列を解析せずsession handleを取得できる。Codexは通常rollout transcriptの`task_complete`、Grok/Composerは通常session event、Claudeは通常settingsへ加算したlaunch固有Stop hookを完了正本に使う。agent sessionへの`pty_send`は非ブロックの **dispatch** になり`event_cursor`入りreceiptを即返す。完了通知は`aiterm-wait --session <id> --cursor <event_cursor>`を親のターンを塞がない別processで受ける。durable machine callerは`claude_turn`を使い、recoveryは再送せず、検証済み完了だけがexact `raw_output`を持つ。
146
157
 
147
158
  `codex_agent`・`grok_agent`・`composer_agent`は任意の`write_scope`(`"read-only"`または書込み許可パスの説明)も受ける。指定値はlaunch receipt・session metadata・`pty_list`へ保存する。Codexの`write_scope:"read-only"`だけは実効能力壁であり、aitermがCLIの`--sandbox read-only`を付ける。Grok/Composerには対応する対話起動sandboxがなく、Codexにもパス説明をallowlistへ変換するフラグがないため、それらは強制済みと偽らず`write_scope_enforcement:"declaration_only_unsupported"`を返す。`write_scope`を省略した起動は従来どおりである。
148
159
 
@@ -162,12 +173,18 @@ $ aiterm-wait --session codex1 --cursor <event_cursor> # exit 0=done / 3=timeo
162
173
 
163
174
  | ツール | 起動するもの | 主な引数 |
164
175
  | --- | --- | --- |
165
- | `claude_agent` | Claude Code CLI(Anthropic) | `prompt?`, `model?`, `reasoning_effort?`(`low`/`medium`/`high`/`xhigh`/`max`), `cwd?`, `session_name?` |
166
- | `codex_agent` | Codex CLI(OpenAI・端末設定/CLI既定、`model?`で上書き) | `prompt?`, `model?`, `reasoning_effort?`(`low`/`medium`/`high`/`xhigh`/`max`/`ultra`), `cwd?`, `session_name?`, `write_scope?` |
167
- | `grok_agent` | Grok Build(xAI、既定`grok-4.5`、`model?`で上書き) | `prompt?`, `model?`, `reasoning_effort?`は非対応(指定時は明示エラー), `cwd?`, `session_name?`, `write_scope?` |
168
- | `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?` |
169
180
 
170
- 各ベンダーの CLI が導入・認証済みであること(`claude_agent` は `claude`、`codex_agent` は `codex`、Grok 系は `grok`)。バイナリは `CLAUDE_BIN` / `CODEX_BIN` / `GROK_BIN`、各既定path、`PATH` の順で解決する。CLI不在・不正なmodel/effort・実在しない`cwd`はsession作成前に失敗し、残骸を残さない。Claudeはさらに、PTY作成前に同じCLIの`auth status --json`が`loggedIn:true`を返すことを要求する。未認証・malformed・失敗exit・timeoutは残骸ゼロで失敗し、正常なvendor所有の共有認証は複数sessionから利用する。managed Claudeへのexact `/login`・`/logout`は通常dispatchとforce送信の双方で副作用前に拒否するため、認証は通常端末で一度だけ修理する。Claudeは通常settingsを継承しないlaunch専用settingsとStop hookを使う一方、user scopeの`mcpServers`だけは`~/.claude.json`から別のowner-only launch configへsnapshotし`--mcp-config`で渡す。project/local MCPは継承しない。本文なしeventとowner-only bounded resultを分離し、`pty_read({ agent_transcript:true })`はdigestとbyte数を検証したresultだけを返してClaude private transcriptを読まない。後着resultは同じsessionからprompt再送なしで回収できる。managed Claudeのactive turn中はC-c以外の`pty_key`と素送信を拒否する。Claudeが`Do you want to proceed?`を表示したら、`claude_approval(action:"inspect", ...)`で画面digestを取得し、表示内容を判断してから、そのdigestと`approve_once`または`deny`を`respond`へ渡す。同じoperation・同じ画面が維持されている時だけ入力し、任意文字列や恒久許可選択肢は中継しない。中断は`C-c`、解除は`pty_close`。
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だけを相関付きで中継する。
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自体が不要である。
171
188
 
172
189
  エージェント間の隠れたプロトコルは無い。起動したClaude/Codex/Grok/Composerは利用者がattachできるもう1本の永続sessionであり、MCPクライアントが通常のPTY操作で駆動する。
173
190
 
@@ -346,8 +363,8 @@ aiterm は同じ核心の洞察——端末を出会いの場にする——を
346
363
  | `pty_key` | 制御キーを送る | `session_id`, `key`(`C-c`/`Enter`/`Up`…) |
347
364
  | `pty_close` | 冪等に閉じ、`closed` / `already_closed`を返す | `session_id` |
348
365
  | `pty_list` | セッション一覧 | (なし) |
349
- | `claude_turn` | 相関済みmanaged Claude operationをdispatch(issue)または回収(recover) | `action`, `session_id`, `operation_id`, `text?` |
350
- | `claude_approval` | 現在表示中の相関済みmanaged Claude承認UIを検査または応答 | `action`, `session_id`, `operation_id?`, `approval_choice?`, `observed_prompt_digest?` |
366
+ | `claude_turn` | 相関済みClaude operationをdispatch(issue)または回収(recover) | `action`, `session_id`, `operation_id`, `text?` |
367
+ | `claude_approval` | 現在表示中の相関済みClaude承認UIを検査または応答 | `action`, `session_id`, `operation_id?`, `approval_choice?`, `observed_prompt_digest?` |
351
368
  | `diagnostics` | 機械可読 JSON による read-only factory readiness | (なし) |
352
369
 
353
370
  `diagnostics` は PTY やエージェントを起動しない。パッケージ版、MCP 呼出 readiness、read-only な PTY 一覧要約、bounded runtime-error-store status、任意 vendor launcher の可用性だけを返す。path・環境値・認証情報・コマンド本文・PTY 出力・raw log は意図的に返さない。通常未設定の任意依存は `not_applicable`、安全に確定できない状態は `unverified` と表す。
@@ -364,18 +381,23 @@ consumer は `aiterm-runtime-errors snapshot` を読み、durable ingestion 後
364
381
 
365
382
  | ツール | 起動するもの | 主な引数 |
366
383
  | --- | --- | --- |
367
- | `claude_agent` | Claude Code CLI(Anthropic) | `prompt?`, `model?`, `reasoning_effort?`(`low`/`medium`/`high`/`xhigh`/`max`), `cwd?`, `session_name?` |
368
- | `codex_agent` | Codex CLI(OpenAI・端末設定/CLI既定、`model?`で上書き) | `prompt?`, `model?`, `reasoning_effort?`(`low`/`medium`/`high`/`xhigh`/`max`/`ultra`), `cwd?`, `session_name?`, `write_scope?` |
369
- | `grok_agent` | Grok Build(xAI、既定`grok-4.5`、`model?`で上書き) | `prompt?`, `model?`, `reasoning_effort?`は非対応(指定時は明示エラー), `cwd?`, `session_name?`, `write_scope?` |
370
- | `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?` |
388
+
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による検証とは区別して記録する。
371
390
 
372
- 対応するCLI(`claude` / `codex` / `grok`)の導入・認証が必要。解決順は`CLAUDE_BIN` / `CODEX_BIN` / `GROK_BIN`、既定path、`PATH`。前提違反はsession作成前に明示失敗する。ClaudeはPTY作成前に構造化認証statusも検証し、managed session内の`/login`・`/logout`を拒否する。4 launcherすべてが同じ非ブロックdispatch契約を使い、Claude/Codexの初回promptはready gate経由で送信される。Claudeはisolated managed settingsとhook-captured resultを使い、private transcriptへ依存しない。Claude/Codex/Grok/Composerのlive smokeはすべてgreenであり、fixtureによる検証とは区別して記録する。
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作成前に明示失敗する。
373
395
 
374
- エージェントの回答が画面 tailより長ければ、対話callerは`pty_read({ agent_transcript:true })`で再promptなしに全文回収する。Claudeはmanaged Stop hookがowner-only resultへ保存した本文をdigest/byte数で検証して返し、private transcriptを読まない。durable machine callerは`claude_turn`を使う。`issue`は一度だけ送信し、`recover`は決して再送せず、`pending`を破損やidentity不一致と区別する。検証済みの`completed`だけがexact `raw_output`を持ち、`unknown`は未dispatchと帰属不能を区別する。不一致・破損は成功statusへ丸めずtool errorのままにする。IDなしの対話turnも匿名markerで直列化するため、現在Stop待ちの間に古い回答を返さない。Codexはroot rollout transcriptの`task_complete.turn_id`で完了と最終回答を同じturnへ帰属し、Grok/Composerは最後の実user行より後ろのassistant行を採る。不在・非agent・抽出不能は明示エラー。
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・抽出不能は明示エラー。
375
397
 
376
398
  ### 完了検出(5 層)
377
399
 
378
- `pty_read({ wait: true })` は、プロセス終了 / `mark:true` sentinel の自動検出(後述)/ `until` 一致(**既定はリテラル部分一致**、`until_regex: true` で正規表現)/ 出力静止 ∧ シェル復帰(quiescence)/ timeout の 5 層で「コマンドが終わったか」を判定する。ネスト中(SSH・コンテナ・REPL・起動したエージェントの TUI の中)はシェル復帰判定が効かないので、`until` で内側プロンプトを指定するか、`mark: true` で送れば `pty_read({ wait: true })` が sentinel を自動検出する(until 不要・ネストでも効く)——全画面のエージェント TUI なら、出力が落ち着いた時点で `{ screen: true }` を読む。agent session は第6の正確な層を使う: Codexは`pty_send` dispatchが返したtranscript byte境界以後の`task_complete`を、Claude/Grokはevent-file境界以後のmanaged hook eventを`aiterm-wait --cursor`が観測する(親はブロックもポーリングもしない)。`pty_send` の送信前 ready 失敗は MCP エラー、launcher の初回 prompt ready 失敗は `initial_prompt=not_sent` を返す。完結した構造化JSONL行が壊れていた場合は、`aiterm-wait` receipt の `malformed_events` に数えられる。
400
+ `pty_read({ wait: true })`は通常PTYを5層で判定し、agent sessionは第6の正確な層を使う。Codexは通常rolloutの`task_complete`、Grok/Composerは通常sessionの`turn_ended`、Claudeは通常settingsへ加算したlaunch相関Stop eventを`aiterm-wait --cursor`が観測する。親はブロックもポーリングもしない。Grok/Composerは`mcp_init_completed`確認前に入力欄が見えても送信しない。
379
401
 
380
402
  ### トークン削減
381
403
 
@@ -399,7 +421,7 @@ consumer は `aiterm-runtime-errors snapshot` を読み、durable ingestion 後
399
421
  - **tmux**(実行時の前提。`tmux -V` で確認。未導入なら `apt install tmux` / `brew install tmux`)
400
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`** で明示指定する。
401
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 に入る。)
402
- - **エージェント起動ツール**を使う場合: 対応するベンダー CLI が導入・認証済みであること——`claude_agent` は `claude`、`codex_agent` は `codex`、`grok_agent` / `composer_agent` は `grok`。(PTY ツールだけ使うなら不要。)
424
+ - **エージェント起動ツール**を使う場合: 対応するベンダー CLI が導入・認証済みであること——`claude_agent` は `claude`、`codex_agent` は `codex`、`grok_agent` / `composer_agent` は `grok`。portable forkだけは追加で`throughline >= 0.9.0`が必要だが、通常のclean launchには不要。(PTY ツールだけ使うなら不要。)
403
425
  - 任意: [`rtk`](https://github.com/rtk-ai/rtk) バイナリ(`pty_send` の `rtk: true` 委譲で使う。無くても動く)
404
426
 
405
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 memory, no autonomous negotiation.
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
  >
@@ -94,13 +94,23 @@ toolchain behind kitepon.dev's products.
94
94
 
95
95
  **Measured, not claimed:** in the recorded 203-test benchmark, a `pty_read` puts **~7.1× fewer tokens** in your context than the raw log — and the pass/fail verdict survives the fold. → [When to reach for it vs. the built-in shell](#when-to-reach-for-it-vs-the-built-in-shell)
96
96
 
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 managed-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.
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.21.4 restores user-scoped MCPs in fresh managed Claude sessions.** Aiterm keeps
100
- normal hooks, plugins, permissions, and project/local MCPs isolated, while snapshotting only
101
- the already user-scoped `mcpServers` from `~/.claude.json` into an owner-only launch config.
102
- Malformed user MCP config fails before a session is created instead of silently launching
103
- Claude without its tools.
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
+
106
+ **v0.22.0 makes launched agents full project collaborators.** All four launchers now use the
107
+ same normal `HOME`, working tree, vendor home, project/user/local configuration, MCP servers,
108
+ plugins, skills, permissions, trust, memory, and session history as a direct CLI launch. Aiterm
109
+ isolates only its own per-launch completion correlation state. Every child is told that it is a
110
+ sub-agent and receives its parent session, delegation depth, lineage, and
111
+ `delegation_allowed=true`; a child may delegate further, while the lineage makes reflexive
112
+ self-copy loops visible and avoidable. The historical `managed_completion` receipt field remains
113
+ for API compatibility and means “completion correlation enabled,” not environment isolation.
104
114
 
105
115
  **v0.21.3 removes Codex Stop hooks from the completion path.** Codex completion and
106
116
  final-message attribution now come from the root rollout transcript's durable
@@ -109,12 +119,12 @@ hook executable can no longer strand `aiterm-wait`. v0.21.0 added explicit
109
119
  `write_scope` declarations for external-agent launchers; v0.21.3 also fixes their
110
120
  structured launch receipts so a supplied scope and its enforcement status are retained.
111
121
  v0.20.3 prevents concurrent
112
- managed Claude/Fable sessions from turning one broken login into many competing login
122
+ correlated Claude/Fable sessions from turning one broken login into many competing login
113
123
  flows. Every new Claude launch verifies the
114
124
  vendor-owned shared credential store before creating a PTY, while healthy credentials
115
125
  remain reusable across concurrent and repeated sessions. The v0.20 line also distinguishes
116
126
  a non-blocking `aiterm-wait --timeout 0` observation (`running`, exit 5) from a real timed-out
117
- wait. The v0.19 line added the correlated managed-Claude approval relay,
127
+ wait. The v0.19 line added the correlated Claude approval relay,
118
128
  preserved multiline shell delivery, and extended factory diagnostics on native
119
129
  Windows. As of v0.16/0.17 a parent agent never blocks on aiterm:
120
130
  every send to an agent session is a non-blocking dispatch, completion is one
@@ -128,7 +138,7 @@ collection is off by default and performs no network I/O. It ships via
128
138
  tag-triggered CI with npm provenance (OIDC Trusted Publishing); the GitHub
129
139
  Release re-registers the Official MCP Registry entry.
130
140
 
131
- **Status:** actively maintained · the newcomer here, betting on a different shape (see [vs. the alternatives](#vs-the-alternatives)) · runs on Linux · WSL2 · macOS · native Windows for the core PTY tools (managed completion is POSIX/WSL/macOS only for now) · MIT · see the [CHANGELOG](CHANGELOG.md).
141
+ **Status:** actively maintained · the newcomer here, betting on a different shape (see [vs. the alternatives](#vs-the-alternatives)) · runs on Linux · WSL2 · macOS · native Windows for the core PTY tools (correlated agent completion is POSIX/WSL/macOS only for now) · MIT · see the [CHANGELOG](CHANGELOG.md).
132
142
 
133
143
  ## Why now
134
144
 
@@ -157,11 +167,13 @@ pty_read(id, { wait: true }) → read the token-reduced output, completion
157
167
 
158
168
  ### 2. Launch other coding agents into that terminal — the orchestration flagship
159
169
 
160
- The same primitive hosts another agent's TUI. Four launchers each start one vendor's interactive coding-agent TUI inside a fresh persistent terminal and return a `session_id`. Their existing human-readable text is accompanied by an `aiterm.agent-launch-result.v1` structured receipt, so durable callers never parse display text for the session handle; when the launch carries an initial `prompt`, the receipt also includes the `event_cursor`, a ready-made `wait_command` for the completion waiter, and a `submit_residue` observation (`true` = the prompt is likely still sitting unsubmitted in the composer — the hint explains recovery; `false` = no residue observed, not a proof of submission; `null` = not applicable). From there you drive it with the same `pty_read` / `pty_send` you'd use on any shell: read its output token-reduced, send it the next step. (The TUIs are full-screen apps, so `pty_read({ screen: true })` gives you the rendered view.) Every launch is **managed**: Codex completion comes from its own durable rollout transcript's `task_complete`; Claude and Grok use isolated managed Stop hooks. Sending to an agent session is a non-blocking **dispatch** — the call returns immediately with an `event_cursor`, and completion arrives via [`aiterm-wait`](#completion-push-for-parent-agents-aiterm-wait). Durable machine callers use `claude_turn({ action: "issue" | "recover", session_id, operation_id, ... })`: it returns fixed `accepted` / `pending` / `completed` / `unknown` states without parsing human-facing errors, never resends during recovery, and includes exact `raw_output` only for a verified completion. The same operation ID is carried through the dispatch receipt, active marker, Stop event, and result. The ordinary `pty_send` / `pty_read` surface remains available for interactive callers and humans. `C-c` keeps the marker for a delayed Claude Stop; if no Stop arrives, close the session. An initial `prompt` on `claude_agent`/`codex_agent` is submitted through the same ready gate and the launcher returns without waiting; on Grok/Composer it is passed on the CLI's argv. This needs the vendor's own CLI installed and authenticated — see [Requirements](#requirements).
170
+ The same primitive hosts another agent's TUI. Four launchers each start one vendor's interactive coding-agent TUI inside a fresh persistent terminal and return a `session_id`. The launched process sees the same project and user environment as a direct CLI invocation: normal configuration, MCPs, plugins, skills, permissions, trust decisions, memory, and history are not copied, filtered, or replaced. Aiterm adds only completion correlation and a non-user sub-agent context containing `role=subagent`, the parent session, delegation depth, lineage, and `delegation_allowed=true`. Nested delegation is supported: a grandchild receives depth 2 and the extended lineage rather than being forbidden from launching another agent.
171
+
172
+ The human-readable launch text is accompanied by an `aiterm.agent-launch-result.v1` structured receipt, so durable callers never parse display text for the session handle; when the launch carries an initial `prompt`, the receipt also includes the `event_cursor`, a ready-made `wait_command` for the completion waiter, and a `submit_residue` observation (`true` = the prompt is likely still sitting unsubmitted in the composer — the hint explains recovery; `false` = no residue observed, not a proof of submission; `null` = not applicable). From there you drive it with the same `pty_read` / `pty_send` you'd use on any shell. Codex completion comes from its normal durable rollout transcript's `task_complete`; Grok/Composer use their normal session events; Claude receives a launch-specific Stop hook settings addition while still loading normal user/project/local settings. Sending to an agent session is a non-blocking **dispatch** — the call returns immediately with an `event_cursor`, and completion arrives via [`aiterm-wait`](#completion-push-for-parent-agents-aiterm-wait). Durable machine callers use `claude_turn({ action: "issue" | "recover", session_id, operation_id, ... })`: it returns fixed `accepted` / `pending` / `completed` / `unknown` states without parsing human-facing errors, never resends during recovery, and includes exact `raw_output` only for a verified completion. An initial `prompt` on `claude_agent`/`codex_agent` is submitted through the same ready gate and the launcher returns without waiting; on Grok/Composer it is passed on the CLI's argv. This needs the vendor's own CLI installed and authenticated — see [Requirements](#requirements).
161
173
 
162
174
  `codex_agent`, `grok_agent`, and `composer_agent` also accept an optional `write_scope`: either `"read-only"` or a human-readable description of writable paths. A supplied value is retained in the launch receipt, session metadata, and `pty_list`. For Codex, `write_scope: "read-only"` is an effective boundary: aiterm adds the CLI's `--sandbox read-only` flag. Grok/Composer have no corresponding interactive-launch sandbox, and Codex has no path-description allowlist flag; those cases return `write_scope_enforcement: "declaration_only_unsupported"` rather than claiming enforcement. Omitting `write_scope` preserves prior behavior.
163
175
 
164
- For a managed Claude turn stopped at `Do you want to proceed?`, use `claude_approval(action: "inspect", ...)` to capture the active operation and SHA-256 screen digest, review the displayed command, then call `respond` with that exact digest and either `approve_once` or `deny`. The relay rechecks the operation and screen under the send lock, never exposes arbitrary input or permanent approval, keeps the active marker intact, and records a prompt-free owner-only receipt. `pty_send(force: true)` does not bypass this boundary.
176
+ For a correlated Claude turn stopped at `Do you want to proceed?`, use `claude_approval(action: "inspect", ...)` to capture the active operation and SHA-256 screen digest, review the displayed command, then call `respond` with that exact digest and either `approve_once` or `deny`. The relay rechecks the operation and screen under the send lock, never exposes arbitrary input or permanent approval, keeps the active marker intact, and records a prompt-free owner-only receipt. `pty_send(force: true)` does not bypass this boundary.
165
177
 
166
178
  ```text
167
179
  codex_agent({ session_name: "codex1", cwd: "/repo",
@@ -180,14 +192,21 @@ One call per model, so the tool name itself tells you which model you get:
180
192
 
181
193
  | Tool | Launches | Key args |
182
194
  | --- | --- | --- |
183
- | `claude_agent` | Claude Code CLI (Anthropic) | `prompt?`, `model?`, `reasoning_effort?` (`low`/`medium`/`high`/`xhigh`/`max`), `cwd?`, `session_name?`, `launch_operation_id?` |
184
- | `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?` |
185
- | `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?` |
186
- | `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?` |
199
+
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.
187
201
 
188
- 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 `~/.local/bin/claude` / `~/.local/bin/codex` / `~/.grok/bin/grok`, 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**. Claude sessions share the vendor-owned credential store rather than copying credentials per launch, so multiple sessions can reuse one healthy login. Managed Claude rejects exact `/login` and `/logout` dispatches, including forced sends: repair authentication once in a normal terminal, then relaunch any stale unauthenticated sessions. Claude and Codex launchers forward `model` and `reasoning_effort` through their vendor CLI's public 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 a `launch_operation_id` formatted as `sha256:<64 lowercase hex>`. Repeating the identical launch returns the same structured session receipt without starting the CLI twice; a different correlation ID or launch argument for that session fails explicitly. Claude uses launch-local managed settings containing only aiterm's Stop hook: normal user/project/local hooks are not inherited. User-scoped `mcpServers` are copied separately from `~/.claude.json` into a launch-local owner-only config and passed through `--mcp-config`; project/local MCPs remain isolated. 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. A late result remains recoverable from the same session without re-sending the prompt. While a managed Claude turn is active, raw sends and non-interrupt keys are rejected. If Claude displays `Do you want to proceed?`, call `claude_approval(action:"inspect", ...)`, decide from the visible prompt, then call `respond` with the returned digest and either `approve_once` or `deny`. The response is accepted only while the same operation and screen digest remain current; arbitrary text and persistent-allow choices are never relayed. Use `pty_key("C-c")` to interrupt and `pty_close` to abandon the session. For unconstrained manual key-by-key driving, open a plain `pty_open` session and start the vendor CLI yourself. Codex uses a managed `CODEX_HOME`; Grok/Composer isolate their managed homes and pass validated OAuth state through `GROK_AUTH_PATH`. Before the first unbound dispatch, aiterm waits for the vendor TUI's input prompt and fails before sending if it is not ready. Managed completion requires POSIX filesystem semantics (Linux, WSL2, macOS).
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.
189
208
 
190
- The managed Codex home links authentication, privately snapshots `config.toml` and `agents/*.toml` custom-role definitions, and keeps sessions/caches isolated. A symlinked role definition is resolved into a regular-file snapshot rather than shared with the source home. aiterm does not install a Codex Stop hook: the root rollout transcript is the completion source, so a missing hook executable cannot strand `aiterm-wait`.
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).
191
210
 
192
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.
193
212
 
@@ -368,8 +387,8 @@ On top of that sits a productized layer a raw tmux bridge doesn't have: **token-
368
387
  | `pty_key` | Send a control key | `session_id`, `key` (`C-c`/`Enter`/`Up`…) |
369
388
  | `pty_close` | Close idempotently; return `closed` / `already_closed` | `session_id` |
370
389
  | `pty_list` | List sessions (agent rows carry `agent=<kind>` metadata) | (none) |
371
- | `claude_turn` | Issue (dispatch-only) or recover one correlated managed-Claude operation | `action`, `session_id`, `operation_id`, `text?` |
372
- | `claude_approval` | Inspect or answer the current correlated managed-Claude approval prompt | `action`, `session_id`, `operation_id?`, `approval_choice?`, `observed_prompt_digest?` |
390
+ | `claude_turn` | Issue (dispatch-only) or recover one correlated Claude operation | `action`, `session_id`, `operation_id`, `text?` |
391
+ | `claude_approval` | Inspect or answer the current correlated Claude approval prompt | `action`, `session_id`, `operation_id?`, `approval_choice?`, `observed_prompt_digest?` |
373
392
  | `diagnostics` | Read-only factory readiness as machine-readable JSON | (none) |
374
393
 
375
394
  `diagnostics` never starts a PTY or agent. It reports package version, MCP call readiness, a read-only PTY-list summary, bounded runtime-error-store status, and optional vendor-launcher availability. It deliberately excludes paths, environment values, credentials, command text, PTY output, and raw logs; normal unset optional dependencies are `not_applicable`, while an indeterminate probe is `unverified`.
@@ -386,25 +405,31 @@ Each launcher starts a specific vendor's interactive coding-agent TUI inside a f
386
405
 
387
406
  | Tool | Launches | Key args |
388
407
  | --- | --- | --- |
389
- | `claude_agent` | Claude Code CLI (Anthropic) | `prompt?`, `model?`, `reasoning_effort?` (`low`/`medium`/`high`/`xhigh`/`max`), `cwd?`, `session_name?`, `launch_operation_id?` |
390
- | `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?` |
391
- | `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?` |
392
- | `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?` |
393
412
 
394
- 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 managed Claude rejects `/login` and `/logout`; repair authentication once in a normal terminal. All four share the same non-blocking dispatch contract for follow-up turns; `claude_agent`/`codex_agent` submit an initial `prompt` through the ready gate. Claude uses isolated managed settings and a hook-captured bounded result rather than private transcript access. Claude, Codex, Grok, and Composer live smokes are green; fixture coverage remains a separate claim. Native Windows can launch agents but managed completion is not supported yet.
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.
395
414
 
396
- 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 managed 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`. `unknown` distinguishes `operation_not_found` from a receipt whose result can no longer be attributed. Mismatch and corruption remain tool errors rather than being folded into a successful status. ID-less interactive Claude turns are still serialized by an anonymous marker, so an older answer is not returned while the current Stop is pending. Codex uses the root rollout transcript's `task_complete.turn_id` both for completion and final-message attribution; Grok/Composer take the assistant rows after the last real user row. A missing result/transcript, a non-agent session, or an unextractable message is an explicit error, never a silent empty.
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
+
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.
397
422
 
398
423
  ### Completion detection (5 layers)
399
424
 
400
- `pty_read({ wait: true })` decides "is the command done?" via five layers: process exit / a `mark:true` sentinel (auto-detected — see below) / an `until` match (a literal substring by default; pass `until_regex: true` for a regex) / output is quiescent ∧ the shell is back (quiescence) / timeout. While nested (inside SSH, a container, a REPL, or a launched agent's TUI), the "shell is back" check cannot fire, so pass `until` with the inner prompt — or send with `mark: true` and `pty_read({ wait: true })` auto-detects the completion sentinel (no `until` needed, works nested too) — or, for a full-screen agent TUI, read `{ screen: true }` once its output settles. Agent sessions use a sixth exact layer: Codex observes `task_complete` after the dispatch's transcript byte boundary; Claude/Grok observe their managed hook event after the event-file boundary. `aiterm-wait --cursor` performs that vendor-specific observation without the parent blocking or polling. Pre-send readiness failures are MCP errors for `pty_send`, while launch-time initial prompt readiness failures return the session with `initial_prompt=not_sent`. A late completion remains recoverable from the same session with `pty_read({ agent_transcript:true })`, without resending. Malformed complete JSONL records are counted in `malformed_events` for diagnosis rather than treated as done.
425
+ `pty_read({ wait: true })` decides "is the command done?" via five layers: process exit / a `mark:true` sentinel / an `until` match / output quiescence with shell return / timeout. Agent sessions add a sixth exact layer: Codex observes normal rollout `task_complete`; Grok/Composer observe normal session `turn_ended`; Claude observes its additive launch-correlated Stop event. `aiterm-wait --cursor` performs that vendor-specific observation without the parent blocking or polling. Pre-send readiness failures are MCP errors, and late completion remains recoverable without resending.
401
426
 
402
427
  ### Completion push for parent agents (`aiterm-wait`)
403
428
 
404
429
  As of v0.16 a parent agent **never blocks** on aiterm — there is no wait parameter anywhere (v0.17 makes the waiter's exit codes mirror its outcome). The whole flow is dispatch + one universal waiter:
405
430
 
406
- 1. Launch the child (`claude_agent` / `codex_agent` / ...; every launch is managed). Send a turn with plain `pty_send` (or `claude_turn issue` for durable Claude operations). The call passes the TUI ready gate, submits, and returns immediately with an `event_cursor` in its structured receipt — plus a `submit_residue` observation: `true` means the sent text still lingered in the composer after submit (likely stranded; inspect the screen before re-pressing Enter), `false` means no residue was observed (not a proof of submission), `null` means not applicable.
407
- 2. Run `aiterm-wait --session <id> --cursor <event_cursor> [--operation sha256:<64hex>] [--timeout <sec>]` (a launch with an initial `prompt` returns this command ready-made as `wait_command` in its structured receipt). It observes the vendor completion source as a **pure reader**—Codex rollout `task_complete`, or a managed hook event for the other vendors—and exits with a one-line `aiterm.agent-wait-result.v1` receipt. **Exit ≠ done**: the receipt's `outcome` is authoritative, and the exit code mirrors it — `0` = `done`, `3` = `timeout` (the turn is **not** finished; default `--timeout` is 600 s), `4` = `closed`, `1` = error. On `timeout` just re-run the waiter with the same cursor. The `--cursor` boundary makes it start-order independent: no completion can slip past even if the waiter starts late.
431
+ 1. Launch the child (`claude_agent` / `codex_agent` / ...; every launch shares the normal project/user environment and adds only completion correlation plus lineage). Send a turn with plain `pty_send` (or `claude_turn issue` for durable Claude operations). The call passes the TUI ready gate, submits, and returns immediately with an `event_cursor` in its structured receipt.
432
+ 2. Run `aiterm-wait --session <id> --cursor <event_cursor> [--operation sha256:<64hex>] [--timeout <sec>]`. It observes the vendor-native completion source, plus Claude's additive launch hook, as a **pure reader** and exits with a one-line `aiterm.agent-wait-result.v1` receipt. **Exit ≠ done**: the receipt's `outcome` is authoritative (`0` = `done`, `3` = `timeout`, `4` = `closed`, `1` = error).
408
433
  3. **The parent never runs the waiter in its own foreground.** Waiting is correct — but the waiter is a separate process, not the parent's turn. A harness that re-invokes its agent when a background task exits (Claude Code) runs the waiter **in the background** and gets woken with zero polling. So that this is not left to interpretation, aiterm reads `clientInfo.name` from the MCP `initialize` handshake and its receipts name the concrete invocation for the detected host — for Claude Code, literally `Bash(command: "aiterm-wait …", run_in_background: true)`. Unknown or undeclared hosts get the generic "start it as a process that does not block the parent's turn" wording; nothing else about the contract changes. Every receipt leads with the same rule: dispatch and let go, then go do something else or end the turn.
409
434
  4. Collect the result exactly as before: `pty_read(agent_transcript: true)`, or `claude_turn recover` for durable Claude operations. The waiter carries the signal, never the payload.
410
435
 
@@ -434,7 +459,7 @@ Sessions live on a shared tmux socket. The `tmux -S … attach -t <id>` line pri
434
459
  - **tmux** (runtime prerequisite; check with `tmux -V`. Install with `apt install tmux` / `brew install tmux`)
435
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.
436
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.)
437
- - 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.)
438
463
  - Optional: the [`rtk`](https://github.com/rtk-ai/rtk) binary (used by `pty_send`'s `rtk: true` delegation; works fine without it)
439
464
 
440
465
  ## Known constraints (by design, not bugs)
@@ -472,17 +497,16 @@ If aiterm let your AI hand a task to another agent — or saved you a round-trip
472
497
  - **npm:** https://www.npmjs.com/package/aiterm-mcp
473
498
  - **Issues / bug reports:** https://github.com/kitepon-rgb/aiterm-mcp/issues
474
499
 
475
- ## License
500
+ ## Shared agent environment
476
501
 
477
- > Grok OAuthのauth/lock共有は0.9.1当時の契約で、2026-07-14に廃止した。現行はmanaged隔離を維持し、検証済み通常auth正本を`GROK_AUTH_PATH`でvendorへ渡す。aitermはlock・atomic replace・copy-backを所有しない。
502
+ All four launchers use the caller's normal project and user environment. Aiterm does not copy,
503
+ symlink, filter, or replace vendor configuration, authentication, MCP, plugin, skill, permission,
504
+ trust, memory, or history stores. Cleanup removes only aiterm-owned launch metadata and completion
505
+ correlation files.
478
506
 
479
- MIT
480
-
481
- ## Grok OAuth isolation
507
+ ## License
482
508
 
483
- For managed completion, Grok/Composer keep launch-local `GROK_HOME` and fake `HOME`.
484
- The child receives `GROK_AUTH_PATH` pointing at the validated normal auth
485
- canonical file; managed homes never contain auth or lock symlinks/copies.
509
+ MIT
486
510
  aiterm does not create locks or copy credentials back. An inherited
487
511
  `GROK_AUTH_PATH` must be absolute and safe; only an absent default auth file is
488
512
  allowed when `XAI_API_KEY` is set.