aiterm-mcp 0.29.31 → 0.30.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/CHANGELOG.md +8 -1
- package/README.ja.md +3 -1
- package/README.md +3 -1
- package/dist/core.js +31 -0
- package/dist/index.js +17 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.30.0] - 2026-09-04
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `pty_send`(agent dispatch)、`agent_steer`、`agent_launch`に`image`(画像ファイルの絶対パスの配列)を追加した。aitermが本文末尾へ添付行を付け、Claude Code/Codex/Grok/Cursorはいずれも自分のfile読取toolでそのpathを画像として開く(実測 2026-09-04)。呼出し側が入力欄へパスを先打鍵する等のharness別手順を持つ必要を無くす。相対パス・未対応拡張子・不在fileは送信前にtyped errorで拒否し、通常PTY送信とforce送信では指定できない。
|
|
15
|
+
|
|
10
16
|
## [0.29.31] - 2026-09-04
|
|
11
17
|
|
|
12
18
|
### Fixed
|
|
@@ -1540,7 +1546,8 @@ prototype (preserved under `prototype/python/` as the porting source and referen
|
|
|
1540
1546
|
`ubuntu-latest` for Node 18/20/22, publishing to npm on `v*` tags with
|
|
1541
1547
|
provenance.
|
|
1542
1548
|
|
|
1543
|
-
[Unreleased]: https://github.com/kitepon/aiterm-mcp/compare/v0.
|
|
1549
|
+
[Unreleased]: https://github.com/kitepon/aiterm-mcp/compare/v0.30.0...HEAD
|
|
1550
|
+
[0.30.0]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.31...v0.30.0
|
|
1544
1551
|
[0.29.31]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.30...v0.29.31
|
|
1545
1552
|
[0.29.30]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.29...v0.29.30
|
|
1546
1553
|
[0.29.29]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.28...v0.29.29
|
package/README.ja.md
CHANGED
|
@@ -153,7 +153,7 @@ runtime-error store は canonical dotagents config の `collection.enabled: true
|
|
|
153
153
|
場合だけ収集し、既定OFF、network送信は行いません。tag起点CIのnpm provenance(OIDC Trusted
|
|
154
154
|
Publishing)で公開し、GitHub Release が Official MCP Registry を再登録します。
|
|
155
155
|
|
|
156
|
-
**状態:** 開発継続中 · 現行公開版 **v0.
|
|
156
|
+
**状態:** 開発継続中 · 現行公開版 **v0.30.0** · 動作対象は Linux · WSL2 · macOS · Windows ネイティブ · MIT · [変更履歴](CHANGELOG.md)。
|
|
157
157
|
|
|
158
158
|
### 更新と巻き戻し
|
|
159
159
|
|
|
@@ -189,6 +189,8 @@ pty_read(id, { wait: true }) → 削減済みの出力を読む(完了
|
|
|
189
189
|
|
|
190
190
|
`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で受ける。Cursorのsubmitキーはadapterが現行CLIのextended keyboard protocolへ変換する。送信textがCursorのcomposerへ残った場合は成功receiptを返さず失敗する。
|
|
191
191
|
|
|
192
|
+
`agent_launch`・`pty_send`(agent dispatch)・`agent_steer`は任意の`image`(画像ファイルの絶対パスの配列。png/jpg/jpeg/gif/webp)を受ける。aitermが本文末尾へ添付行を付け、どのharnessも自分のfile読取toolでそのpathを画像として開く。呼出し側はharness別の添付手順を覚えない。不正なpathは送信前に拒否する。
|
|
193
|
+
|
|
192
194
|
`agent_launch`は任意の`write_scope`も受ける。Codex/Grokのread-onlyは`--sandbox read-only`、Cursorは公式`--mode ask`で実効化する。path説明は同等CLI引数がないためdeclaration-only。
|
|
193
195
|
|
|
194
196
|
```text
|
package/README.md
CHANGED
|
@@ -169,7 +169,7 @@ collection is off by default and performs no network I/O. It ships via
|
|
|
169
169
|
tag-triggered CI with npm provenance (OIDC Trusted Publishing); the GitHub
|
|
170
170
|
Release re-registers the Official MCP Registry entry.
|
|
171
171
|
|
|
172
|
-
**Status:** actively maintained · current public release **v0.
|
|
172
|
+
**Status:** actively maintained · current public release **v0.30.0** · runs on Linux · WSL2 · macOS · native Windows (tmux on POSIX, the tmux-CLI-compatible [psmux](https://github.com/psmux/psmux) on native Windows — no WSL required) · MIT · see the [CHANGELOG](CHANGELOG.md).
|
|
173
173
|
|
|
174
174
|
### Update and rollback
|
|
175
175
|
|
|
@@ -211,6 +211,8 @@ The same primitive hosts another agent's TUI. `agent_launch` starts a selected e
|
|
|
211
211
|
|
|
212
212
|
The human-readable launch text is accompanied by an `aiterm.agent-launch-result.v1` structured receipt containing the canonical `harness`; the old `provider` field remains for compatibility. The same `harness` is carried by agent dispatch, `aiterm-wait`, `agent_configure`, and agent rows in `pty_list`, while their old vendor/provider/agent fields remain compatibility fields. Codex completion comes from its normal durable rollout transcript, Grok CLI from its normal session events, Claude Code from a launch-specific Stop hook settings addition, and Cursor from its normal agent transcript's terminal `turn_ended` record. Sending to any agent session is a non-blocking **dispatch** — the call returns immediately with an opaque, harness-specific integer `event_cursor`, and completion arrives via [`aiterm-wait`](#completion-push-for-parent-agents-aiterm-wait). The Cursor adapter translates submit into the current CLI's extended keyboard protocol. If submitted text remains in Cursor's composer, its dispatch fails instead of returning a successful receipt.
|
|
213
213
|
|
|
214
|
+
`agent_launch`, `pty_send` (agent dispatch), and `agent_steer` accept an optional `image`: an array of absolute paths to image files (png/jpg/jpeg/gif/webp). Aiterm appends an attachment block to the prompt, and every harness opens the path with its own file-reading tool and sees the image; the caller never learns harness-specific attachment tricks. Invalid paths are rejected before anything is sent.
|
|
215
|
+
|
|
214
216
|
`agent_launch` accepts an optional `write_scope`: either `"read-only"` or a human-readable description of writable paths. Codex/Grok use `--sandbox read-only`; Cursor uses its official read-only `--mode ask`. A path description remains declaration-only because these CLI launch surfaces provide no equivalent path allowlist flag.
|
|
215
217
|
|
|
216
218
|
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.
|
package/dist/core.js
CHANGED
|
@@ -3049,6 +3049,37 @@ export function __testCodexConfigureChoices(screen, model, effort) {
|
|
|
3049
3049
|
// v0.16.0: 親をブロックする wait 経路は廃止した。send は ready gate と submit 分離を内蔵した
|
|
3050
3050
|
// dispatch として即返り、event_cursor(送信直前のharness完了正本境界)を receipt で返す。
|
|
3051
3051
|
// 完了通知は aiterm-wait(--cursor で境界を渡す)、回収は pty_read / claude_turn recover が担う。
|
|
3052
|
+
const IMAGE_EXTENSIONS = new Set([".png", ".jpg", ".jpeg", ".gif", ".webp"]);
|
|
3053
|
+
/**
|
|
3054
|
+
* 画像添付。Claude Code/Codex/Grok/Cursorの4 harnessは、本文に書かれた画像ファイルの絶対パスを
|
|
3055
|
+
* 自分のfile読取toolで開いて画像として見る(実測 2026-09-04: 赤青の試験画像を全harnessが正しく答えた)。
|
|
3056
|
+
* 入力欄へパスを先打鍵する等のharness別操作は不要であり、呼出し側にharnessの癖を覚えさせない。
|
|
3057
|
+
* 添付の表現とpath検査はこの1箇所だけが所有する。検査は外部入力(呼出し側が渡すpath)の境界。
|
|
3058
|
+
*/
|
|
3059
|
+
export function attachImages(text, images) {
|
|
3060
|
+
if (!images || images.length === 0)
|
|
3061
|
+
return text;
|
|
3062
|
+
const lines = images.map((image, index) => {
|
|
3063
|
+
if (typeof image !== "string" || !path.isAbsolute(image)) {
|
|
3064
|
+
throw new AitermError(`image[${index}] は画像ファイルの絶対パスで指定してください: ${String(image)}`, 2);
|
|
3065
|
+
}
|
|
3066
|
+
if (!IMAGE_EXTENSIONS.has(path.extname(image).toLowerCase())) {
|
|
3067
|
+
throw new AitermError(`image[${index}] の拡張子に対応していません(png/jpg/jpeg/gif/webp): ${image}`, 2);
|
|
3068
|
+
}
|
|
3069
|
+
let st;
|
|
3070
|
+
try {
|
|
3071
|
+
st = fs.statSync(image);
|
|
3072
|
+
}
|
|
3073
|
+
catch {
|
|
3074
|
+
throw new AitermError(`image[${index}] が読めません: ${image}`, 2);
|
|
3075
|
+
}
|
|
3076
|
+
if (!st.isFile())
|
|
3077
|
+
throw new AitermError(`image[${index}] はfileではありません: ${image}`, 2);
|
|
3078
|
+
return `[aiterm 添付画像 ${index + 1}/${images.length}] ${image}`;
|
|
3079
|
+
});
|
|
3080
|
+
const body = text.trim().length > 0 ? text : "添付画像を確認してください。";
|
|
3081
|
+
return `${body}\n\n${lines.join("\n")}\n添付画像は上のファイルを読んで確認する。`;
|
|
3082
|
+
}
|
|
3052
3083
|
export async function dispatchAgentTurn(name, text, o = {}) {
|
|
3053
3084
|
assertSessionName(name);
|
|
3054
3085
|
const meta = loadAgentMetadata(name);
|
package/dist/index.js
CHANGED
|
@@ -136,6 +136,11 @@ server.registerTool("pty_send", {
|
|
|
136
136
|
.describe("非Claude agent sessionでは自動dispatchせず素送信する。aiterm相関付きClaudeのactive turnには使えない"),
|
|
137
137
|
rtk: z.boolean().default(false).describe("既知コマンドを rtk 形へ委譲して送る(rtk 不在なら素通し)"),
|
|
138
138
|
raw: z.boolean().default(false).describe("送信前サニタイズを無効化"),
|
|
139
|
+
image: z
|
|
140
|
+
.array(z.string())
|
|
141
|
+
.optional()
|
|
142
|
+
.describe("添付する画像ファイルの絶対パス(png/jpg/jpeg/gif/webp)。agent session への dispatch だけで使え、" +
|
|
143
|
+
"harness別の添付手順はaitermが吸収する。通常PTY送信やforce送信では指定できない"),
|
|
139
144
|
},
|
|
140
145
|
outputSchema: {
|
|
141
146
|
schema: z.literal("aiterm.pty-send-result.v1"),
|
|
@@ -152,7 +157,7 @@ server.registerTool("pty_send", {
|
|
|
152
157
|
// dispatch前に行った pane 入力の回復("fg" / "fg_stopped" / "stty_raw")。通常送信では省略(additive)。
|
|
153
158
|
pane_input_recovery: z.array(z.string()).optional(),
|
|
154
159
|
},
|
|
155
|
-
}, async ({ session_id, text, enter, mark, force, rtk, raw }) => {
|
|
160
|
+
}, async ({ session_id, text, enter, mark, force, rtk, raw, image }) => {
|
|
156
161
|
try {
|
|
157
162
|
if (!force && core.isAgentSession(session_id)) {
|
|
158
163
|
if (enter === false)
|
|
@@ -161,7 +166,7 @@ server.registerTool("pty_send", {
|
|
|
161
166
|
throw new Error("agent session への dispatch は mark:true と併用できません");
|
|
162
167
|
if (rtk)
|
|
163
168
|
throw new Error("agent session への dispatch は rtk:true と併用できません");
|
|
164
|
-
const receipt = await core.dispatchAgentTurn(session_id, text, { raw });
|
|
169
|
+
const receipt = await core.dispatchAgentTurn(session_id, core.attachImages(text, image), { raw });
|
|
165
170
|
const waitProcess = core.agentWaitProcess(receipt.session_id, receipt.event_cursor);
|
|
166
171
|
return {
|
|
167
172
|
content: [
|
|
@@ -186,6 +191,9 @@ server.registerTool("pty_send", {
|
|
|
186
191
|
},
|
|
187
192
|
};
|
|
188
193
|
}
|
|
194
|
+
if (image && image.length > 0) {
|
|
195
|
+
throw new Error("image は agent session への dispatch(forceなし)だけで使えます。通常PTY送信では本文にpathを書いてください");
|
|
196
|
+
}
|
|
189
197
|
const out = core.send(session_id, text, { enter, mark, force, rtk, raw });
|
|
190
198
|
return {
|
|
191
199
|
content: [{ type: "text", text: out }],
|
|
@@ -212,6 +220,7 @@ server.registerTool("agent_steer", {
|
|
|
212
220
|
inputSchema: {
|
|
213
221
|
session_id: z.string(),
|
|
214
222
|
text: z.string().describe("現在のターンへ追加する文字列。UTF-8で最大64KiB"),
|
|
223
|
+
image: z.array(z.string()).optional().describe("添付する画像ファイルの絶対パス(png/jpg/jpeg/gif/webp)"),
|
|
215
224
|
},
|
|
216
225
|
outputSchema: {
|
|
217
226
|
schema: z.literal("aiterm.agent-steer.v1"),
|
|
@@ -221,9 +230,9 @@ server.registerTool("agent_steer", {
|
|
|
221
230
|
harness: z.enum(["codex-cli", "grok-cli"]),
|
|
222
231
|
delivery: z.enum(["steered", "idle"]),
|
|
223
232
|
},
|
|
224
|
-
}, async ({ session_id, text }) => {
|
|
233
|
+
}, async ({ session_id, text, image }) => {
|
|
225
234
|
try {
|
|
226
|
-
const receipt = await core.steerAgentTurn(session_id, text);
|
|
235
|
+
const receipt = await core.steerAgentTurn(session_id, core.attachImages(text, image));
|
|
227
236
|
return {
|
|
228
237
|
content: [{ type: "text", text: `${receipt.delivery} ${receipt.session_id}` }],
|
|
229
238
|
structuredContent: receipt,
|
|
@@ -547,13 +556,14 @@ const agentEnvironmentDesc = `通常CLIと同じHOME・cwd・project/user/local
|
|
|
547
556
|
`delegation depth/lineage、delegation_allowed=trueを注入し、必要な追加委譲は許可する。`;
|
|
548
557
|
async function launchAgent(kind, args) {
|
|
549
558
|
const supportsWriteScope = kind !== "claude";
|
|
550
|
-
const { prompt, throughline_source_session, throughline_supplement_file, model, reasoning_effort, env_vars, cwd, session_name, launch_operation_id, write_scope } = args;
|
|
559
|
+
const { prompt, image, throughline_source_session, throughline_supplement_file, model, reasoning_effort, env_vars, cwd, session_name, launch_operation_id, write_scope } = args;
|
|
551
560
|
try {
|
|
552
561
|
if (!supportsWriteScope && write_scope !== undefined) {
|
|
553
562
|
throw new core.AitermError("claude-code harnessはwrite_scopeに対応していません。指定を外してください", 2);
|
|
554
563
|
}
|
|
564
|
+
const initialPrompt = image && image.length > 0 ? core.attachImages(prompt ?? "", image) : prompt ?? undefined;
|
|
555
565
|
const [sid, hint, eventCursor, submitResidue] = await core.openAgentWithInitialPrompt(kind, {
|
|
556
|
-
prompt:
|
|
566
|
+
prompt: initialPrompt,
|
|
557
567
|
throughline_source_session,
|
|
558
568
|
throughline_supplement_file,
|
|
559
569
|
model: model ?? undefined,
|
|
@@ -663,6 +673,7 @@ server.registerTool("agent_launch", {
|
|
|
663
673
|
inputSchema: {
|
|
664
674
|
harness: z.enum(["claude-code", "codex-cli", "grok-cli", "cursor-cli"]).describe("agent loop・session・hook・transcript・認証を所有する実行基盤"),
|
|
665
675
|
prompt: z.string().nullish().describe("起動時に渡す初手プロンプト(任意)。送信後は待たずに即返る"),
|
|
676
|
+
image: z.array(z.string()).optional().describe("初手プロンプトへ添付する画像ファイルの絶対パス(png/jpg/jpeg/gif/webp)"),
|
|
666
677
|
throughline_source_session: z.string().min(1).optional().describe("同一端末のThroughline sessionから読み取り専用contextを初手へ注入する"),
|
|
667
678
|
throughline_supplement_file: z.string().min(1).optional().describe("Throughline 0.10.8以降へそのまま渡すproject束縛済み長期記憶・知識の補足JSON path"),
|
|
668
679
|
model: z.string().nullish().describe("harnessが選ぶモデル。provider名ではなくlive catalog上のmodel ID"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aiterm-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"mcpName": "io.github.kitepon/aiterm-mcp",
|
|
5
5
|
"description": "Persistent terminal MCP with one harness-based launcher for Claude Code, Codex CLI, Grok CLI, and Cursor Agent CLI, plus durable PTYs for SSH, containers, and REPLs.",
|
|
6
6
|
"keywords": [
|