aiterm-mcp 0.27.9 → 0.28.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 +54 -48
- package/README.md +59 -55
- package/dist/agent-resolver.js +14 -5
- package/dist/agent-shared.js +18 -5
- package/dist/aiterm-wait-cli.js +1 -1
- package/dist/core.js +171 -22
- package/dist/index.js +110 -58
- package/dist/vendors/codex.js +2 -1
- package/dist/vendors/cursor.js +393 -0
- package/dist/vendors/grok.js +2 -1
- package/package.json +2 -2
package/README.ja.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
> **任意のMCPクライアントから、Claude・Codex・Grok・
|
|
1
|
+
> **任意のMCPクライアントから、Claude Code・Codex CLI・Grok CLI・Cursor Agent CLIを単一のharness APIで永続対話TUIへ起動する。**
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<img src=".github/og.png" alt="Aiterm — 異なる知性が一つの持続する実行現場を共有する森の観測拠点" width="100%">
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
> *(English: [README.md](README.md))*
|
|
18
18
|
|
|
19
|
-
> **あなたの AI に、ほかの AI を操らせる。**
|
|
19
|
+
> **あなたの AI に、ほかの AI を操らせる。** `agent_launch`の1回の呼び出しで、実行基盤harnessとmodelを別々に選び、永続sessionを受け取る。CursorでGPT/Claude/Grokを選んでも、session・hook・transcriptはCursorが所有する。
|
|
20
20
|
>
|
|
21
21
|
> **これは何か:** AI が握る 1 本の永続 MCP 端末——その中に他のコーディングエージェントも起動できる。`ssh`・`docker exec`・REPL・別エージェントの TUI は、すべてその 1 本の端末の中へ「送るだけのテキスト」として入れ子になる。仕組みはあえて素朴——MCP クライアントが相手エージェントの端末を 1 ターンずつ操作するだけ。隠れたプロトコルも・aiterm独自の共有メモリ層も・自律的な交渉も無い。起動したagentは、直接CLIと同じproject/vendorの通常memory・設定を読む。
|
|
22
22
|
>
|
|
@@ -94,7 +94,9 @@ host統合は、kitepon.devの製品開発を支える内部基盤
|
|
|
94
94
|
|
|
95
95
|
**言葉でなく実測で:** 記録済み203テストのベンチマークでは、`pty_read` はコンテキストに載るトークンを生ログの **約 7.1 分の 1** に減らす。しかも pass/fail の判定は畳んでも残る。→ [組み込みシェルツールとの使い分け](#組み込みシェルツールとの使い分け)
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
15ツール: 6つのPTYツール、正規のagent起動入口`agent_launch`、移行用の旧4alias、`agent_configure`、`claude_turn`、`claude_approval`、`diagnostics`。バックエンドはtmuxなので、MCPサーバやAIクライアントが再起動してもsessionは生き残る。
|
|
98
|
+
|
|
99
|
+
**v0.28.0では実行基盤harnessとmodelを分離した。** harnessはagent loop・認証・hook・session・transcriptを所有し、modelはその上で選ぶ。Cursor Agent CLIでGPT/Claude/Grokを選んでも完了契約はCursor方式のまま。Composerは別harnessではなく、`harness:"grok-cli", model:"grok-composer-2.5-fast"`で表す。旧4起動ツールは同じ実装へ流れる互換alias。
|
|
98
100
|
|
|
99
101
|
**v0.25.2ではGrok 4.6を含む同一sessionの連続設定変更を安定化。** Grok Build 1.0.3で
|
|
100
102
|
`/model`の成功通知が再描画により消えても、変更前には無かった要求model/effortが常駐footerへ現れた
|
|
@@ -151,7 +153,7 @@ runtime-error store は canonical dotagents config の `collection.enabled: true
|
|
|
151
153
|
場合だけ収集し、既定OFF、network送信は行いません。tag起点CIのnpm provenance(OIDC Trusted
|
|
152
154
|
Publishing)で公開し、GitHub Release が Official MCP Registry を再登録します。
|
|
153
155
|
|
|
154
|
-
**状態:** 開発継続中 · この分野では新参で、別の形に賭けている([既存手段との比較](#既存手段との比較)参照)· 動作対象は Linux · WSL2 · macOS · Windows
|
|
156
|
+
**状態:** 開発継続中 · この分野では新参で、別の形に賭けている([既存手段との比較](#既存手段との比較)参照)· 動作対象は Linux · WSL2 · macOS · Windows ネイティブ · MIT · [変更履歴](CHANGELOG.md)。
|
|
155
157
|
|
|
156
158
|
## なぜ今
|
|
157
159
|
|
|
@@ -174,14 +176,14 @@ pty_read(id, { wait: true }) → 削減済みの出力を読む(完了
|
|
|
174
176
|
|
|
175
177
|
### 2. その端末の中に他のコーディングエージェントを起動する — オーケストレーションの旗艦
|
|
176
178
|
|
|
177
|
-
同じ
|
|
179
|
+
同じprimitiveが別エージェントのTUIを宿す。`agent_launch`の`harness`はagent loop・認証・hook・session・transcriptを所有する実行基盤、`model`は独立した選択。起動processは直接CLIと同じproject/user環境を使い、通常config、MCP、plugin、skill、permission、trust、memory、historyをcopy・filter・置換しない。
|
|
178
180
|
|
|
179
|
-
|
|
181
|
+
`aiterm.agent-launch-result.v1`は正規`harness`を返し、旧`provider`は互換fieldとして残す。同じ`harness`はagent dispatch、`aiterm-wait`、`agent_configure`、`pty_list`のagent行にも載り、旧vendor/provider/agent fieldは互換用に残る。Codexは通常rollout、Grok CLIは通常session event、Claudeはlaunch固有Stop hook、Cursorは通常agent transcript末尾の`turn_ended`を完了正本に使う。`pty_send`は非ブロックdispatchで、vendor別完了境界を表すopaqueな整数`event_cursor`を返し、完了通知は`aiterm-wait`を親のターンを塞がない別processで受ける。
|
|
180
182
|
|
|
181
|
-
`
|
|
183
|
+
`agent_launch`は任意の`write_scope`も受ける。Codex/Grokのread-onlyは`--sandbox read-only`、Cursorは公式`--mode ask`で実効化する。path説明は同等CLI引数がないためdeclaration-only。
|
|
182
184
|
|
|
183
185
|
```text
|
|
184
|
-
|
|
186
|
+
agent_launch({ harness: "codex-cli", session_name: "codex1", cwd: "/repo",
|
|
185
187
|
prompt: "port test/legacy.py to vitest",
|
|
186
188
|
model: "gpt-5.6-sol", reasoning_effort: "high",
|
|
187
189
|
write_scope: "test/ only; no commit" })
|
|
@@ -192,14 +194,16 @@ $ aiterm-wait --session codex1 --cursor <event_cursor> # exit 0=done / 3=timeo
|
|
|
192
194
|
→ 操舵し、Codex の次の入力境界で返る
|
|
193
195
|
```
|
|
194
196
|
|
|
195
|
-
|
|
197
|
+
正規のharness選択肢:
|
|
196
198
|
|
|
197
|
-
|
|
|
199
|
+
| `harness` | 起動するもの | modelの扱い |
|
|
198
200
|
| --- | --- | --- |
|
|
199
|
-
| `
|
|
200
|
-
| `
|
|
201
|
-
| `
|
|
202
|
-
| `
|
|
201
|
+
| `claude-code` | Claude Code CLI | Claude model/effort |
|
|
202
|
+
| `codex-cli` | Codex CLI | OpenAI model/effort |
|
|
203
|
+
| `grok-cli` | Grok Build CLI | Grok/Composer model、live catalog照合 |
|
|
204
|
+
| `cursor-cli` | Cursor Agent CLI | Cursor catalog上のGPT/Claude/Grok等 |
|
|
205
|
+
|
|
206
|
+
Cursorの`model`は`gpt-5.6-luna`のようなbase model、`reasoning_effort`は`high`のように別指定する。adapterは現行`model-effort` IDを`cursor-agent models`へ照合し、起動中変更はCursor標準model pickerのparameter editorを使う。不在時は別modelへfallbackしない。
|
|
203
207
|
|
|
204
208
|
`env_vars`は環境変数の**名前**だけを並べるallowlistであり、name/value mapではない。aitermは
|
|
205
209
|
launcher起動時に現在のMCP processから各名前を読み、存在する値をshell quoteして、その1回のvendor
|
|
@@ -208,7 +212,7 @@ launcher起動時に現在のMCP processから各名前を読み、存在する
|
|
|
208
212
|
PTYの起動コマンドとして送られ、sessionの`.lastcmd`にも保持されるため、起動先vendorと同じOS userへ
|
|
209
213
|
到達する。秘密転送路ではなく、席identityやworkflow用の非secret変数だけに使う。
|
|
210
214
|
|
|
211
|
-
|
|
215
|
+
選んだharnessのCLIを公式経路で導入・認証しておく。Cursorは`curl https://cursor.com/install -fsS | bash`、`agent login`、更新は`agent update`が公式経路で、Aitermは曖昧な`agent`でなく`cursor-agent`を起動する。CLI不在・未認証・不正引数はsession作成前に明示失敗し、別経路へfallbackしない。
|
|
212
216
|
|
|
213
217
|
portable forkは任意である。`throughline_source_session`を使う場合、`prompt`は必須の新ミッションとなり、
|
|
214
218
|
`launch_operation_id`とは併用できない。aitermは`THROUGHLINE_BIN`、次に`PATH`からThroughlineを解決し、
|
|
@@ -216,7 +220,7 @@ portable forkは任意である。`throughline_source_session`を使う場合、
|
|
|
216
220
|
この経路だけ`throughline >= 0.9.0`が必要で、元sessionのDB所属は変わらない。引数省略時には
|
|
217
221
|
Throughline自体が不要である。
|
|
218
222
|
|
|
219
|
-
エージェント間の隠れたプロトコルは無い。起動した
|
|
223
|
+
エージェント間の隠れたプロトコルは無い。起動したharnessは利用者がattachできるもう1本の永続sessionであり、MCPクライアントが通常のPTY操作で駆動する。
|
|
220
224
|
|
|
221
225
|
## デモ
|
|
222
226
|
|
|
@@ -271,7 +275,7 @@ Throughline自体が不要である。
|
|
|
271
275
|
Claude Code を再起動して、接続を確認:
|
|
272
276
|
|
|
273
277
|
```bash
|
|
274
|
-
/mcp # aiterm が connected・
|
|
278
|
+
/mcp # aiterm が connected・15 ツール公開、と出る
|
|
275
279
|
```
|
|
276
280
|
|
|
277
281
|
最初のセッション——4 回の呼び出しで、1 個の永続端末:
|
|
@@ -286,7 +290,7 @@ pty_close("t1") → 端末を解放
|
|
|
286
290
|
`pty_close` は冪等で、`closed` / `already_closed` のstructured receiptを返す。
|
|
287
291
|
MCP応答を失ったdurable callerも同じ`session_id`への再試行だけでclose結果を確定できる。
|
|
288
292
|
|
|
289
|
-
これだけ。`t1` の端末は本物で永続——`ssh`・`docker exec`・REPL・起動したエージェントの
|
|
293
|
+
これだけ。`t1` の端末は本物で永続——`ssh`・`docker exec`・REPL・起動したエージェントのTUIは、そこに住む「もの」に過ぎない。ワーカー起動も1コールで、`agent_launch({ harness: "codex-cli" })`が返す`session_id`を同じ`pty_read`/`pty_send`で操作する。
|
|
290
294
|
|
|
291
295
|
**グローバル導入や別クライアントが良い場合は:**
|
|
292
296
|
|
|
@@ -300,9 +304,9 @@ claude mcp add --scope user --transport stdio aiterm -- aiterm-mcp
|
|
|
300
304
|
|
|
301
305
|
## ヘッドレス: 端末に人が居ない
|
|
302
306
|
|
|
303
|
-
MCP クライアントが aiterm を stdio 越しにプログラムから駆動するので、上のすべては
|
|
307
|
+
MCP クライアントが aiterm を stdio 越しにプログラムから駆動するので、上のすべては **端末に誰も座らないまま**動く。任意のMCP対応統括役が、自分と同じharnessを含む`agent_launch`を呼び、`pty_read`で結果を読んで次へ進める——無人で。これは、人が操作する端末が向かない場所にこそ aiterm が合うということ:
|
|
304
308
|
|
|
305
|
-
- **複数エージェントのオーケストレーション** — 統括役がサブタスクを Claude / Codex / Grok / Composer
|
|
309
|
+
- **複数エージェントのオーケストレーション** — 統括役がサブタスクを Claude Code / Codex / Grok / Cursor harnessへ渡し、各々を専用の永続セッションに置き、全部を読み戻す。ComposerはGrok CLIのmodel presetとして扱う。
|
|
306
310
|
- **CI** — ジョブのステップがエージェントを起こし、操作し、片付けられる。
|
|
307
311
|
- **cron** — スケジュール実行がエージェントを起動して出力を回収できる。
|
|
308
312
|
|
|
@@ -312,11 +316,11 @@ MCP クライアントが aiterm を stdio 越しにプログラムから駆動
|
|
|
312
316
|
|
|
313
317
|
```mermaid
|
|
314
318
|
flowchart LR
|
|
315
|
-
AI["AI / MCP client<br/>(the orchestrator)"] -->|"pty_send ·
|
|
319
|
+
AI["AI / MCP client<br/>(the orchestrator)"] -->|"pty_send · agent_launch · agent_configure · claude_turn · claude_approval<br/>旧launcher alias · diagnostics"| S["aiterm-mcp<br/>stdio MCP · 15 tools"]
|
|
316
320
|
S -->|"pty_read<br/>token-reduced"| AI
|
|
317
|
-
S -->|"tmux
|
|
321
|
+
S -->|"tmux / psmux<br/>send · capture"| P["persistent PTYs<br/>再起動を跨ぐ"]
|
|
318
322
|
P -->|"ssh · docker · repl"| R["nested<br/>remote · container · REPL"]
|
|
319
|
-
P -->|"launches a fresh PTY per agent"| A["another coding-agent TUI<br/>Claude · Codex · Grok ·
|
|
323
|
+
P -->|"launches a fresh PTY per agent"| A["another coding-agent TUI<br/>Claude · Codex · Grok · Cursor"]
|
|
320
324
|
```
|
|
321
325
|
|
|
322
326
|
primitive は「PTY を 1 個握る」ことだけ。それ以外——SSH・コンテナ・REPL・起動したエージェント TUI——は、永続端末の中で動く「対話的な何か」に過ぎず、同じ `pty_send` / `pty_read` で操作する。各起動ツールは自分専用の新しい PTY を開く。PTY は tmux 上にあるので、MCP サーバや AI クライアントが再起動してもセッションは生き残る。
|
|
@@ -348,10 +352,10 @@ aiterm はセッションの状態も持ち越せる。組み込みツールは
|
|
|
348
352
|
|
|
349
353
|
```text
|
|
350
354
|
組み込みシェル → var= # 空。env は消え、cwd はプロジェクト直下に戻る
|
|
351
|
-
aiterm → cwd=/tmp var=hello123 # 1
|
|
355
|
+
aiterm → cwd=/tmp var=hello123 # 1 本の永続PTYが両方を保つ
|
|
352
356
|
```
|
|
353
357
|
|
|
354
|
-
cd でディレクトリを移り、環境変数を立て、ビルドを走らせる。ssh で一度ログインして、その接続のまま 10 個コマンドを打つ。REPL や起動したエージェントの TUI を 1 ターンずつ操作する。こういう流れは、1
|
|
358
|
+
cd でディレクトリを移り、環境変数を立て、ビルドを走らせる。ssh で一度ログインして、その接続のまま 10 個コマンドを打つ。REPL や起動したエージェントの TUI を 1 ターンずつ操作する。こういう流れは、1 本の永続PTYが状態を握っていて初めて成り立つ。端末に何かを覚えておいてほしいときは、aiterm を使う。
|
|
355
359
|
|
|
356
360
|
<sub>¹ いまのハーネスは ~192 KB の出力をいったんファイルに逃がして、先頭 ~2 KB だけを見せる。そのためトークン数はほぼ並ぶ。aiterm は行数を正確に返すうえ、あとから `line_range="A:B"` で好きな範囲(先頭でも末尾でも)を取り出せる。² `rtk` の grep 縮約は長い行(~80 字)を切り詰めて、あふれを `[+N more]` にまとめる。ざっと眺めるには向くが、全行をそのまま読みたいときは組み込みツールを使う。</sub>
|
|
357
361
|
|
|
@@ -361,15 +365,15 @@ aiterm は 2 つの系譜の交点にいる——端末を操作する MCP サ
|
|
|
361
365
|
|
|
362
366
|
| | **aiterm-mcp** | 1 コマンド毎の往復<br/>(例: `mcp-server-commands`) | terminal / SSH / tmux MCP<br/>(例: `iterm-mcp`, `ssh-mcp`, `tmux-mcp`) | 共有 tmux でエージェント同士<br/>(例: `smux`) |
|
|
363
367
|
| --- | --- | --- | --- | --- |
|
|
364
|
-
| 永続セッション | ✅ tmux・再起動を跨ぐ | ❌ 毎回新シェル | ⚠️ まちまち | ✅ tmux |
|
|
368
|
+
| 永続セッション | ✅ tmux / psmux・再起動を跨ぐ | ❌ 毎回新シェル | ⚠️ まちまち | ✅ tmux |
|
|
365
369
|
| SSH / コンテナ / REPL | `pty_send` 1 回でネスト | 毎コマンド接続し直し | ⚠️ ツールが分かれがち | ✅ tmux(人が操作) |
|
|
366
|
-
| 1 コールで別エージェント起動 | ✅ `
|
|
370
|
+
| 1 コールで別エージェント起動 | ✅ `agent_launch(harness=…)` | ❌ | ❌ | ⚠️ 人が動かす tmux に CLI + skills で参加 |
|
|
367
371
|
| ヘッドレス(人が tmux に居ない) | ✅ MCP 駆動・プログラム的 | ✅ | ⚠️ まちまち | ❌ 人が tmux に居る前提 |
|
|
368
372
|
| MCP ネイティブ(任意の MCP クライアント) | ✅ `claude mcp add` 1 行 | ✅ | ✅(MCP なので) | ❌ tmux 設定 + CLI + Agent Skills |
|
|
369
373
|
| トークン削減読取 | ✅ コマンド別 reducer | ❌ 生出力 | ⚠️ ほぼ無し | ❌ 生 tmux |
|
|
370
374
|
| 完了検出 | 5 層: 終了 / `mark` / `until` / 静止 / timeout | 無し(毎回ブロック) | ⚠️ プロンプト一致・脆い | ❌ エージェントがペインを読む |
|
|
371
375
|
| 破壊コマンド遮断 | ✅ tripwire(`force` で越える) | ❌ | ⚠️ まちまち | ❌ |
|
|
372
|
-
| 人が同時操作 | ✅ 共有
|
|
376
|
+
| 人が同時操作 | ✅ 共有socket/namespace(`attach`) | ❌ | ⚠️ まちまち | ✅(設計の芯) |
|
|
373
377
|
|
|
374
378
|
## aiterm の立ち位置
|
|
375
379
|
|
|
@@ -392,8 +396,10 @@ aiterm は同じ核心の洞察——端末を出会いの場にする——を
|
|
|
392
396
|
| `pty_read` | 出力を削減して読む(既定は増分) | `session_id`, `wait`, `until`, `until_regex`, `timeout`, `screen`, `full`, `lines`, `line_range`, `raw`, `rtk`, `agent_transcript`, `operation_id` |
|
|
393
397
|
| `pty_key` | 制御キーを送る | `session_id`, `key`(`C-c`/`Enter`/`Up`…) |
|
|
394
398
|
| `pty_close` | 冪等に閉じ、`closed` / `already_closed`を返す | `session_id` |
|
|
395
|
-
| `pty_list` |
|
|
396
|
-
| `
|
|
399
|
+
| `pty_list` | セッション一覧(agent行は正規`harness=<id>`と互換`agent=<kind>`を含む) | (なし) |
|
|
400
|
+
| `agent_launch` | harnessとmodelを別軸で選ぶ正規agent起動入口 | `harness`, `prompt?`, `model?`, `reasoning_effort?`, `cwd?`, `write_scope?` |
|
|
401
|
+
| `claude_agent` / `codex_agent` / `grok_agent` / `composer_agent` | deprecated互換alias | 旧launcher引数 |
|
|
402
|
+
| `agent_configure` | 起動中のClaude/Codex/Grok/Composer/Cursorを再起動せずmodel/effort変更 | `session_id`, `model?`, `reasoning_effort?` |
|
|
397
403
|
| `claude_turn` | 相関済みClaude operationをdispatch(issue)または回収(recover) | `action`, `session_id`, `operation_id`, `text?` |
|
|
398
404
|
| `claude_approval` | 現在表示中の相関済みClaude承認UIを検査または応答 | `action`, `session_id`, `operation_id?`, `approval_choice?`, `observed_prompt_digest?` |
|
|
399
405
|
| `diagnostics` | 機械可読 JSON による read-only factory readiness | (なし) |
|
|
@@ -406,31 +412,31 @@ aiterm は同じ核心の洞察——端末を出会いの場にする——を
|
|
|
406
412
|
|
|
407
413
|
consumer は `aiterm-runtime-errors snapshot` を読み、durable ingestion 後に `aiterm-runtime-errors ack --cursor N` を呼ぶ。運用上の明示操作は `resolve|reopen --fingerprint SHA256`。MCP からの収集・diagnostic read は timeout 付き child process に隔離し、FIFOや停止 filesystem が端末本体を止めない。store mutation は期限付き bakery ticket queue で直列化する。各waiterは PID+process start identity+owner token を持つ再利用されない固有ticketを所有するため、死んだownerだけを固有名で除去でき、固定path回収のABAを作らない。queueの期限は正常な前任者を含む総待ち時間ではなく、同じ先頭ownerが進まない時間を測る。通常pollはprocessの生存確認だけを行い、process start identityはblockerがstallした時に照合する。POSIX state は `$XDG_STATE_HOME/aiterm-mcp/`(既定 `~/.local/state/aiterm-mcp/`)へ atomic replacement で置き、every read で owner/mode を再検証する。Windows native は `%LOCALAPPDATA%\aiterm-mcp\` で current SID の非継承 FullControl ACE 1件だけへ DACL を再構築し readback する。今回 Windows は path/DACL/timeout の純粋テストだけであり、新しい実機統合成功は主張しない。
|
|
408
414
|
|
|
409
|
-
###
|
|
415
|
+
### 対話エージェントharness
|
|
410
416
|
|
|
411
|
-
|
|
417
|
+
`agent_launch`は選んだharnessの対話TUIを新しい永続PTYに起動し、`session_id`を返す。harnessはagent loop・認証・hook・session・transcriptを所有し、modelは独立。以後は他sessionと同じ`pty_read`/`pty_send`で操作する。
|
|
412
418
|
|
|
413
|
-
`agent_configure({ session_id, model?, reasoning_effort? })`は
|
|
419
|
+
`agent_configure({ session_id, model?, reasoning_effort? })`はharness標準操作で起動中のClaude/Codex/Grok/Composer/Cursorを変更し、PTYと会話contextを維持する。
|
|
414
420
|
|
|
415
|
-
|
|
|
421
|
+
| `harness` | 起動するもの | modelの扱い |
|
|
416
422
|
| --- | --- | --- |
|
|
417
|
-
| `
|
|
418
|
-
| `
|
|
419
|
-
| `
|
|
420
|
-
| `
|
|
423
|
+
| `claude-code` | Claude Code CLI | Claude model/effort |
|
|
424
|
+
| `codex-cli` | Codex CLI | OpenAI model/effort |
|
|
425
|
+
| `grok-cli` | Grok Build CLI | Grok/Composer model、live catalog照合 |
|
|
426
|
+
| `cursor-cli` | Cursor Agent CLI | Cursor catalog上のGPT/Claude/Grok等 |
|
|
421
427
|
|
|
422
|
-
対応するCLI(`claude
|
|
428
|
+
対応するCLI(`claude`/`codex`/`grok`/`cursor-agent`)の公式導入・認証が必要。前提違反はsession作成前に明示失敗する。全harnessが通常project/user環境と同じ非ブロックdispatch契約を使う。
|
|
423
429
|
|
|
424
430
|
`throughline_source_session`と空でない新ミッション`prompt`を指定すると、Throughlineの読み取り専用
|
|
425
431
|
handoff contextを前置きできる。この任意経路は`throughline >= 0.9.0`を必要とし、
|
|
426
432
|
`launch_operation_id`とは併用不可で、元sessionのDB所属を変更しない。Throughlineは
|
|
427
433
|
`THROUGHLINE_BIN`、次に`PATH`から解決し、不在・不正・空のexportはPTY作成前に明示失敗する。
|
|
428
434
|
|
|
429
|
-
エージェントの回答が画面
|
|
435
|
+
エージェントの回答が画面tailより長ければ、`pty_read({ agent_transcript:true })`で再promptなしに全文回収する。Claudeはlaunch相関Stop hook、Codexは通常rollout、Grokは通常session history、Cursorはlaunch IDでbindした通常agent transcriptから同じturnを回収する。
|
|
430
436
|
|
|
431
437
|
### 完了検出(5 層)
|
|
432
438
|
|
|
433
|
-
`pty_read({ wait: true })`は通常PTYを、process終了/`mark:true` sentinel/`until`一致/shell復帰を伴う出力静止/timeoutの5
|
|
439
|
+
`pty_read({ wait: true })`は通常PTYを、process終了/`mark:true` sentinel/`until`一致/shell復帰を伴う出力静止/timeoutの5層で判定する。agent sessionは第6の正確な層を使い、Codexは通常rollout、Grokは通常session event、Claudeはlaunch相関Stop event、Cursorは通常agent transcriptの`turn_ended`を`aiterm-wait --cursor`が観測する。親はブロックもポーリングもしない。
|
|
434
440
|
|
|
435
441
|
### トークン削減
|
|
436
442
|
|
|
@@ -442,11 +448,11 @@ handoff contextを前置きできる。この任意経路は`throughline >= 0.9.
|
|
|
442
448
|
|
|
443
449
|
`pty_send` は送信前に破壊的コマンド(`rm -rf /`, `mkfs`, `dd of=/dev/…`, `DROP TABLE` 等)を遮断し(`force: true` で越える)、ESC・ブラケットペースト終端などをサニタイズする。`pty_read` は既定で制御文字を無害化して返す(`raw: true` はバイトをそのまま返す)。これは**サンドボックスではなく tripwire**([既知の制約](#既知の制約バグではなく仕様)参照)。
|
|
444
450
|
|
|
445
|
-
1回の `pty_send` が受理する本文はUTF-8で最大64KiB。同一sessionへの送信はaiterm processをまたいで直列化し、chunk同士の混線を防ぐ。全OSで長いPTY入力の欠落を避けるためUTF-8境界を壊さない256-byte単位でpasteし、chunk間に10msのdrain間隔を置く。POSIX shellが前面にいる時のsanitize済み複数行は、改行を含まない単一の`eval`入力へ符号化する。shellがscript全体を所有してから先頭行を実行するため、途中で起動したpager/REPLが後続行を対話キーとして奪わない。単一行、`raw:true`、非shell前面は従来どおり直接PTYへpasteする。agent dispatch
|
|
451
|
+
1回の `pty_send` が受理する本文はUTF-8で最大64KiB。同一sessionへの送信はaiterm processをまたいで直列化し、chunk同士の混線を防ぐ。全OSで長いPTY入力の欠落を避けるためplatformのmultiplexerへUTF-8境界を壊さない256-byte単位でpasteし、chunk間に10msのdrain間隔を置く。POSIX shellが前面にいる時のsanitize済み複数行は、改行を含まない単一の`eval`入力へ符号化する。shellがscript全体を所有してから先頭行を実行するため、途中で起動したpager/REPLが後続行を対話キーとして奪わない。単一行、`raw:true`、非shell前面は従来どおり直接PTYへpasteする。agent dispatchはtmux互換のbracketed paste操作(`paste-buffer -p`)を使う: bracketed paste modeを要求しているpaneへは各chunkを`ESC[200~/201~`で包んで届け、chunk投入中のキー解釈による語中文字化け・submit取り落としを抑える。途中chunkが失敗した場合は部分送信済みであることを明示し、自動でEnterを押さない。送信processの異常終了でlockが残った場合は送信前にfail-closedする。そのsessionを `pty_close` して作り直すか、全sessionを破棄できる場合だけ `pty_kill_all` で安全に掃除する。
|
|
446
452
|
|
|
447
453
|
## 人が覗く
|
|
448
454
|
|
|
449
|
-
セッションは共有
|
|
455
|
+
セッションは共有tmux socket(Windows nativeはpsmux namespace)上にある。`pty_open`/`agent_launch`の戻り値に表示されるattachコマンドで、人間がClaude/Codex/Grok/Cursor harnessの同じ端末へ入り、途中でキーボードを引き取れる。
|
|
450
456
|
|
|
451
457
|
## 要件
|
|
452
458
|
|
|
@@ -454,7 +460,7 @@ handoff contextを前置きできる。この任意経路は`throughline >= 0.9.
|
|
|
454
460
|
- **tmux または psmux**(実行時の前提)
|
|
455
461
|
- **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`** で明示指定する。
|
|
456
462
|
- **Windows ネイティブ**は WSL を使わず、tmux CLI互換の [psmux](https://github.com/psmux/psmux) **3.3.8以上**を直接使う(`winget install marlocarlo.psmux`)。pane shell用に Git for Windows も必要。解決先は **`AITERM_PSMUX`**/**`AITERM_BASH`** で上書きできる。Windows toolはSSHと同じく入れ子で握れ、`pty_send "powershell.exe"`でPowerShellへ入れる。
|
|
457
|
-
-
|
|
463
|
+
- **agent harness**を使う場合: 対応CLIを製品所有者の公式経路で導入・認証する。CursorはmacOS/Linux/WSLで`curl https://cursor.com/install -fsS | bash`、Windows nativeで`irm 'https://cursor.com/install?win32=true' | iex`を使い、`agent login`で認証、`agent update`で更新する。Aitermは`cursor-agent`を起動する。portable forkだけは追加で`throughline >= 0.9.0`が必要。
|
|
458
464
|
- 任意: [`rtk`](https://github.com/rtk-ai/rtk) バイナリ(`pty_send` の `rtk: true` 委譲で使う。無くても動く)
|
|
459
465
|
|
|
460
466
|
## 既知の制約(バグではなく仕様)
|
|
@@ -462,18 +468,18 @@ handoff contextを前置きできる。この任意経路は`throughline >= 0.9.
|
|
|
462
468
|
- **ネスト中(ssh / docker / REPL / 起動したエージェント TUI)は quiescence が原理的に効かない。** 前面コマンドがシェル集合(bash/sh/zsh/fish/dash)の外になるため。ネスト中で `until` も `mark` も無いときは、待っても完了を確定できる信号が無いので、`pty_read({ wait: true })` はフル `timeout` を空費せず出力静止時点で `is_complete=False via nested` と早期に返し、`until`(既定リテラル部分一致・`until_regex: true` で正規表現)か `mark: true`(終了コード付き sentinel・自動検出)の指定を促す。全画面のエージェント TUI なら、出力が落ち着いた時点で `{ screen: true }` を読む。
|
|
463
469
|
- **`is_complete=False` は失敗ではない。** 「timeout 内に完了を観測できなかった」という意味。長時間コマンドでは `timeout` を伸ばすか `until`/`mark` を使う。
|
|
464
470
|
- **破壊ゲートはサンドボックスではなく tripwire。** よくある破壊形だけを弾く。相対パスの `rm`、`$VAR` 展開後に危険化するもの、ssh 先で実行されるコマンドは捕捉しない——起動したコーディングエージェントが自分のセッション内で何をするかも取り締まらない。
|
|
465
|
-
-
|
|
471
|
+
- **agent harnessは実物TUIを起動し、model APIを代理しない。** model・認証・挙動は選んだharnessのもの。隠れたagent間protocolはなく、MCPクライアントがClaude/Codex/Grok/Cursor TUIへ入力を送り出力を読む。
|
|
466
472
|
- **`pty_send({ rtk: true })` は単行コマンドのみ+外部 `rtk` バイナリが必要**(無ければ素通し)。一方 `pty_read({ rtk: true })` の reducer は自前実装で rtk 非依存。
|
|
467
473
|
- **`pytest` reducer は件数・罫線・`FAILURES` ブロック整形が rtk 0.42.0 と byte 一致**(回帰テストで固定)。ただし `-ra`/`-rf` 時の `FAILED` 要約行の理由は**全文を保持する**(rtk 0.42.0 は最初の `" - "` 区切りで切るが、本実装は可読性優先で情報を残すため、この行は意図的に rtk と完全一致させない)。rtk が大出力時に付ける `[full output: …]`(tee ポインタ)行は read 側では再現しない。
|
|
468
474
|
- **tmux は `-f /dev/null` 起動**なので `~/.tmux.conf` を読まない(環境差を排除するため)。
|
|
469
|
-
- **全セッションが単一
|
|
475
|
+
- **全セッションが単一multiplexer endpoint(POSIXは`claude.sock`、Windows nativeは1つのpsmux namespace)を共有する。** platformの`kill-server` commandは全セッションを消す。
|
|
470
476
|
|
|
471
477
|
## 開発
|
|
472
478
|
|
|
473
479
|
```bash
|
|
474
480
|
npm install
|
|
475
481
|
npm run build # tsc → dist/
|
|
476
|
-
npm test # build してから node:test 回帰スイート(tmux 必須)
|
|
482
|
+
npm test # build してから node:test 回帰スイート(tmux または psmux 必須)
|
|
477
483
|
npm link # ローカルで `aiterm-mcp` を PATH に
|
|
478
484
|
```
|
|
479
485
|
|
|
@@ -482,7 +488,7 @@ self-hostedのmacOS native・Linux native・Windows native・WSL2で同じ`npm t
|
|
|
482
488
|
OS別の縮小suiteで代用しません。tag起点のnpm公開は4環境greenとtagged commitの`origin/main`
|
|
483
489
|
祖先確認を通過した後だけ実行します。
|
|
484
490
|
|
|
485
|
-
|
|
491
|
+
共通進行は`src/core.ts`、harness固有は`src/vendors/`、OS差は`src/tmux-runtime.ts`/`src/agent-resolver.ts`、reducerは`src/rtk.ts`、公開面は`src/index.ts`が所有する。設計の出発点と reducer の移植元(pytest reducer は本家 rtk 0.42.0 と一致するよう移植・ただし上記の `FAILED` 行の差異は意図的・回帰テストで固定)は `prototype/python/` を参照。
|
|
486
492
|
|
|
487
493
|
## 試す
|
|
488
494
|
|