aiterm-mcp 0.29.9 → 0.29.10
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 +9 -1
- package/README.ja.md +2 -2
- package/README.md +2 -2
- package/dist/core.js +14 -3
- package/dist/harnesses/grok.js +5 -4
- package/dist/index.js +38 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.29.10] - 2026-08-31
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Return `pty_read(agent_transcript:true)` answer text separately as `aiterm.pty-read-result.v1` structured content while preserving the existing human-readable diagnostic suffix.
|
|
15
|
+
- For Grok and Composer, return only the last non-empty assistant message after the last real user row instead of joining tool-use preambles with the final answer.
|
|
16
|
+
|
|
10
17
|
## [0.29.9] - 2026-08-31
|
|
11
18
|
|
|
12
19
|
### Fixed
|
|
@@ -1401,7 +1408,8 @@ prototype (preserved under `prototype/python/` as the porting source and referen
|
|
|
1401
1408
|
`ubuntu-latest` for Node 18/20/22, publishing to npm on `v*` tags with
|
|
1402
1409
|
provenance.
|
|
1403
1410
|
|
|
1404
|
-
[Unreleased]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.
|
|
1411
|
+
[Unreleased]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.10...HEAD
|
|
1412
|
+
[0.29.10]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.9...v0.29.10
|
|
1405
1413
|
[0.29.9]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.8...v0.29.9
|
|
1406
1414
|
[0.29.8]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.7...v0.29.8
|
|
1407
1415
|
[0.29.7]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.6...v0.29.7
|
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.29.
|
|
156
|
+
**状態:** 開発継続中 · 現行公開版 **v0.29.10** · 動作対象は Linux · WSL2 · macOS · Windows ネイティブ · MIT · [変更履歴](CHANGELOG.md)。
|
|
157
157
|
|
|
158
158
|
### 更新と巻き戻し
|
|
159
159
|
|
|
@@ -443,7 +443,7 @@ handoff contextを前置きできる。この任意経路は`throughline >= 0.9.
|
|
|
443
443
|
`launch_operation_id`とは併用不可で、元sessionのDB所属を変更しない。Throughlineは
|
|
444
444
|
`THROUGHLINE_BIN`、次に`PATH`から解決し、不在・不正・空のexportはPTY作成前に明示失敗する。
|
|
445
445
|
|
|
446
|
-
エージェントの回答が画面tailより長ければ、`pty_read({ agent_transcript:true })`で再prompt
|
|
446
|
+
エージェントの回答が画面tailより長ければ、`pty_read({ agent_transcript:true })`で再promptなしに全文回収する。既存の人間向けcontentは診断suffixを維持し、機械呼出し側は`aiterm.pty-read-result.v1`の`structuredContent.text`から回答本文だけを取得する。Claudeはlaunch相関Stop hook、Codexは通常rollout、Grokは最後の実user行以後の最後の空でないassistantメッセージだけ、Cursorはlaunch IDでbindした通常agent transcriptから同じturnを回収する。
|
|
447
447
|
|
|
448
448
|
### 完了検出(5 層)
|
|
449
449
|
|
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.29.
|
|
172
|
+
**Status:** actively maintained · current public release **v0.29.10** · 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
|
|
|
@@ -475,7 +475,7 @@ cannot be combined with `launch_operation_id`, and leaves the source session's d
|
|
|
475
475
|
unchanged. Throughline is resolved through `THROUGHLINE_BIN` and then `PATH`; a missing or invalid
|
|
476
476
|
export fails before the PTY exists instead of silently launching clean.
|
|
477
477
|
|
|
478
|
-
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
|
|
478
|
+
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. The existing human-readable content keeps its diagnostic suffix; machine callers read the answer alone from `structuredContent.text` in `aiterm.pty-read-result.v1`. 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 return the last non-empty assistant message after the last real user row, excluding tool-use preambles; Cursor uses the normal agent transcript bound to the launch ID and current turn. Missing or ambiguous attribution remains an explicit error.
|
|
479
479
|
|
|
480
480
|
### Completion detection (5 layers)
|
|
481
481
|
|
package/dist/core.js
CHANGED
|
@@ -1994,8 +1994,8 @@ async function settlePublishedClaudeCompletionMarker(meta, marker) {
|
|
|
1994
1994
|
}
|
|
1995
1995
|
return active;
|
|
1996
1996
|
}
|
|
1997
|
-
/** agent harness の構造化 transcript
|
|
1998
|
-
export async function
|
|
1997
|
+
/** agent harness の構造化 transcript から直近完了ターンの最終回答と相関情報を読む。 */
|
|
1998
|
+
export async function readAgentTranscriptResult(name, o = {}) {
|
|
1999
1999
|
const meta = loadAgentMetadata(name);
|
|
2000
2000
|
const operationId = o.operation_id == null ? null : validateOperationId(o.operation_id);
|
|
2001
2001
|
if (operationId && meta.kind !== "claude") {
|
|
@@ -2050,7 +2050,18 @@ export async function readAgentTranscript(name, o = {}) {
|
|
|
2050
2050
|
done?.operation_id ? `operation_id=${done.operation_id}` : null,
|
|
2051
2051
|
`raw_chars=${rawChars}`,
|
|
2052
2052
|
].filter(Boolean).join(" ");
|
|
2053
|
-
return
|
|
2053
|
+
return {
|
|
2054
|
+
text: body,
|
|
2055
|
+
display: `${body}\n${outputMeta} [${transcriptMeta}]`,
|
|
2056
|
+
vendor: meta.kind,
|
|
2057
|
+
turn_id: turnId,
|
|
2058
|
+
harness: agentHarness(meta.kind),
|
|
2059
|
+
raw_chars: rawChars,
|
|
2060
|
+
};
|
|
2061
|
+
}
|
|
2062
|
+
/** 人間向け互換表示を維持する。機械利用は readAgentTranscriptResult の text を使う。 */
|
|
2063
|
+
export async function readAgentTranscript(name, o = {}) {
|
|
2064
|
+
return (await readAgentTranscriptResult(name, o)).display;
|
|
2054
2065
|
}
|
|
2055
2066
|
function inferAgentFrontend(name, meta, screen) {
|
|
2056
2067
|
const fg = paneCurrentCommand(name);
|
package/dist/harnesses/grok.js
CHANGED
|
@@ -283,7 +283,7 @@ export function grokFooterHasConfiguration(screen, model, effort) {
|
|
|
283
283
|
return modelLabel !== null || effort !== null;
|
|
284
284
|
});
|
|
285
285
|
}
|
|
286
|
-
// 最後のuser
|
|
286
|
+
// 最後のuser発話以降に確定した最後のassistantメッセージをchat_history.jsonlから抽出する。
|
|
287
287
|
export function grokTranscriptText(meta, readTranscriptLines, transcriptUnavailable) {
|
|
288
288
|
if (!meta.grok_home || !meta.vendor_session_id)
|
|
289
289
|
transcriptUnavailable();
|
|
@@ -307,11 +307,12 @@ export function grokTranscriptText(meta, readTranscriptLines, transcriptUnavaila
|
|
|
307
307
|
// 外部 transcript の壊れた1行は残りの完結行を読む妨げにしない。
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
|
-
|
|
310
|
+
const replies = records
|
|
311
311
|
.slice(lastUser + 1)
|
|
312
312
|
.filter((record) => record?.type === "assistant" && typeof record?.content === "string")
|
|
313
|
-
.map((record) => record.content)
|
|
314
|
-
.
|
|
313
|
+
.map((record) => record.content.trim())
|
|
314
|
+
.filter(Boolean);
|
|
315
|
+
return replies.at(-1) ?? "";
|
|
315
316
|
}
|
|
316
317
|
export function createGrokAgentMetadata(kind, name, cwd, initialPrompt, authPath, writeScope, lineageContext) {
|
|
317
318
|
const launchId = randomBytes(16).toString("hex");
|
package/dist/index.js
CHANGED
|
@@ -239,16 +239,39 @@ server.registerTool("pty_read", {
|
|
|
239
239
|
.nullish()
|
|
240
240
|
.describe("Claude operationの期待ID。agent_transcript:true時だけ指定し、古い別operationの結果を拒否する"),
|
|
241
241
|
},
|
|
242
|
+
outputSchema: {
|
|
243
|
+
schema: z.literal("aiterm.pty-read-result.v1"),
|
|
244
|
+
mode: z.enum(["terminal", "agent_transcript"]),
|
|
245
|
+
session_id: z.string(),
|
|
246
|
+
text: z.string(),
|
|
247
|
+
vendor: z.enum(["claude", "codex", "grok", "composer", "cursor"]).nullable(),
|
|
248
|
+
turn_id: z.string().nullable(),
|
|
249
|
+
harness: z.enum(["claude-code", "codex-cli", "grok-cli", "cursor-cli"]).nullable(),
|
|
250
|
+
raw_chars: z.number().int().nonnegative().nullable(),
|
|
251
|
+
},
|
|
242
252
|
}, async ({ session_id, wait, until, until_regex, timeout, screen, full, lines, line_range, raw, rtk, agent_transcript, operation_id }) => {
|
|
243
253
|
try {
|
|
244
254
|
if (agent_transcript) {
|
|
245
255
|
if (screen || full || rtk || wait || line_range != null) {
|
|
246
256
|
throw new Error("agent_transcript:true は screen / full / rtk / line_range / wait と併用できません。lines のみ指定できます。");
|
|
247
257
|
}
|
|
248
|
-
|
|
258
|
+
const result = await core.readAgentTranscriptResult(session_id, {
|
|
249
259
|
lines: lines ?? null,
|
|
250
260
|
operation_id: operation_id ?? null,
|
|
251
|
-
})
|
|
261
|
+
});
|
|
262
|
+
return {
|
|
263
|
+
content: [{ type: "text", text: result.display }],
|
|
264
|
+
structuredContent: {
|
|
265
|
+
schema: "aiterm.pty-read-result.v1",
|
|
266
|
+
mode: "agent_transcript",
|
|
267
|
+
session_id,
|
|
268
|
+
text: result.text,
|
|
269
|
+
vendor: result.vendor,
|
|
270
|
+
turn_id: result.turn_id,
|
|
271
|
+
harness: result.harness,
|
|
272
|
+
raw_chars: result.raw_chars,
|
|
273
|
+
},
|
|
274
|
+
};
|
|
252
275
|
}
|
|
253
276
|
if (operation_id != null)
|
|
254
277
|
throw new Error("operation_idはagent_transcript:true時だけ指定できます");
|
|
@@ -279,7 +302,19 @@ server.registerTool("pty_read", {
|
|
|
279
302
|
raw,
|
|
280
303
|
rtk,
|
|
281
304
|
});
|
|
282
|
-
return
|
|
305
|
+
return {
|
|
306
|
+
content: [{ type: "text", text: out }],
|
|
307
|
+
structuredContent: {
|
|
308
|
+
schema: "aiterm.pty-read-result.v1",
|
|
309
|
+
mode: "terminal",
|
|
310
|
+
session_id,
|
|
311
|
+
text: out,
|
|
312
|
+
vendor: null,
|
|
313
|
+
turn_id: null,
|
|
314
|
+
harness: null,
|
|
315
|
+
raw_chars: null,
|
|
316
|
+
},
|
|
317
|
+
};
|
|
283
318
|
}
|
|
284
319
|
catch (e) {
|
|
285
320
|
return fail(e);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aiterm-mcp",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.10",
|
|
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": [
|