aiterm-mcp 0.51.0 → 0.51.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/CHANGELOG.md +12 -1
- package/README.ja.md +3 -2
- package/README.md +3 -2
- package/dist/core.js +46 -6
- package/docs/DESIGN.md +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.51.1] - 2026-10-04
|
|
11
|
+
|
|
12
|
+
### 修正
|
|
13
|
+
|
|
14
|
+
- `pty_observe`の`activity.post_startup_process_count`で、harnessが立て直した起動時のprocessを数えない(ADR 0083)。
|
|
15
|
+
Cursorは起動時にstdioのMCPを立て、最初のつなぎが済むと止めて立て直す。つながるのが遅いMCPがあると、立て直しが
|
|
16
|
+
起動完了の後になり、何もしていない席で数が残っていた(実物で、直結3・中継ごし4)。起動時のprocessが終了していて、
|
|
17
|
+
同じ親の下に同じargvで立っているprocessは、その立て直しとして扱う。その下で動くprocessは今までどおり数える。
|
|
18
|
+
この版より前のAitermが起動したagentは、今までどおり数える。
|
|
19
|
+
|
|
10
20
|
## [0.51.0] - 2026-10-04
|
|
11
21
|
|
|
12
22
|
### 追加
|
|
@@ -2050,7 +2060,8 @@ prototype (preserved under `prototype/python/` as the porting source and referen
|
|
|
2050
2060
|
`ubuntu-latest` for Node 18/20/22, publishing to npm on `v*` tags with
|
|
2051
2061
|
provenance.
|
|
2052
2062
|
|
|
2053
|
-
[Unreleased]: https://github.com/kitepon/aiterm-mcp/compare/v0.51.
|
|
2063
|
+
[Unreleased]: https://github.com/kitepon/aiterm-mcp/compare/v0.51.1...HEAD
|
|
2064
|
+
[0.51.1]: https://github.com/kitepon/aiterm-mcp/compare/v0.51.0...v0.51.1
|
|
2054
2065
|
[0.51.0]: https://github.com/kitepon/aiterm-mcp/compare/v0.50.0...v0.51.0
|
|
2055
2066
|
[0.50.0]: https://github.com/kitepon/aiterm-mcp/compare/v0.49.0...v0.50.0
|
|
2056
2067
|
[0.49.0]: https://github.com/kitepon/aiterm-mcp/compare/v0.48.0...v0.49.0
|
package/README.ja.md
CHANGED
|
@@ -209,7 +209,7 @@ runtime-error store は canonical dotagents config の `collection.enabled: true
|
|
|
209
209
|
場合だけ収集し、既定OFF、network送信は行いません。tag起点CIのnpm provenance(OIDC Trusted
|
|
210
210
|
Publishing)で公開し、GitHub Release が Official MCP Registry を再登録します。
|
|
211
211
|
|
|
212
|
-
**状態:** 開発継続中 · 現行公開版 **v0.51.
|
|
212
|
+
**状態:** 開発継続中 · 現行公開版 **v0.51.1** · 動作対象は Linux · WSL2 · macOS · Windows ネイティブ · MIT · [変更履歴](CHANGELOG.md)。
|
|
213
213
|
|
|
214
214
|
### 更新と巻き戻し
|
|
215
215
|
|
|
@@ -519,7 +519,8 @@ sessionへ登録する名前の配列で、`pty_list({ env_keys: ["JOB_OWNER"] }
|
|
|
519
519
|
agent sessionを閉じると失うものは、次の2項目で分かる。`activity.post_startup_process_count`は、`agent_launch`の起動準備が
|
|
520
520
|
完了した時点(初手を送る前)に居なかったprocessの数。起動直後の1分に始めた裏の作業も数える。数えないものは2つ。Codex自身の
|
|
521
521
|
補助process(`codex-code-mode-host`)と、中継`mcp-lazy`の直接の子(初めて使う時に起こすMCPの本体と、先行起動の判定)。
|
|
522
|
-
その下で動くprocess
|
|
522
|
+
その下で動くprocessは数える。harnessが立て直した起動時のprocess(終了した起動時のprocessと同じ親の下に、同じargvで立ったもの。
|
|
523
|
+
つなぎ直したMCPなど)も数えない。`pending_child_deliveries`は、そのsessionが親として待っていて、まだ届け終えていない
|
|
523
524
|
子の結果の数。呼び出した側が誰でも付く。どちらも、分からない時はnull(通常PTY、harnessのprocessを特定できない時。
|
|
524
525
|
processの数は0.48.0以前が起動したagentも)。別端末が旧版の時は項目ごと無い。nullと項目なしは「分からない」で、0ではない。
|
|
525
526
|
|
package/README.md
CHANGED
|
@@ -223,7 +223,7 @@ collection is off by default and performs no network I/O. It ships via
|
|
|
223
223
|
tag-triggered CI with npm provenance (OIDC Trusted Publishing); the GitHub
|
|
224
224
|
Release re-registers the Official MCP Registry entry.
|
|
225
225
|
|
|
226
|
-
**Status:** actively maintained · current public release **v0.51.
|
|
226
|
+
**Status:** actively maintained · current public release **v0.51.1** · 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).
|
|
227
227
|
|
|
228
228
|
### Update and rollback
|
|
229
229
|
|
|
@@ -552,7 +552,8 @@ Two fields tell a caller what closing an agent session would lose. `activity.pos
|
|
|
552
552
|
processes in the session that did not exist when `agent_launch` finished startup (before the first prompt), so background work
|
|
553
553
|
started in the first minute is counted too. Two kinds of process are not counted: Codex's own `codex-code-mode-host` helper, and
|
|
554
554
|
the direct children of an `mcp-lazy` relay (the MCP server it starts on first use and its wake predicate). What runs below them
|
|
555
|
-
is counted.
|
|
555
|
+
is counted. A startup process that the harness restarted (a process with the same parent and the same arguments as a startup
|
|
556
|
+
process that has exited, such as a reconnected MCP server) is not counted either. `pending_child_deliveries`
|
|
556
557
|
is the number of sub-agent results this session is still waiting for as a parent, whoever the caller is. Both are null when
|
|
557
558
|
Aiterm cannot tell (ordinary terminals, agents launched by 0.48.0 or earlier for the process count, or an unresolved harness
|
|
558
559
|
process), and may be absent when a remote host runs an older Aiterm. Treat null or absent as unknown, not as zero.
|
package/dist/core.js
CHANGED
|
@@ -1077,17 +1077,53 @@ export function selectHarnessProcesses(meta, rows, subtree) {
|
|
|
1077
1077
|
});
|
|
1078
1078
|
return roots;
|
|
1079
1079
|
}
|
|
1080
|
+
const processKey = (row) => `${row.pid}:${row.started_identity}`;
|
|
1081
|
+
/** 起動完了の控えに入れたprocessの、親とargvのdigest。控えた後に終了したprocessは入らない。 */
|
|
1082
|
+
export function startupProcessShapes(identities, rows) {
|
|
1083
|
+
const byPid = new Map(rows.map(row => [row.pid, row]));
|
|
1084
|
+
const byKey = new Map(rows.map(row => [processKey(row), row]));
|
|
1085
|
+
return identities.flatMap(identity => {
|
|
1086
|
+
const row = byKey.get(identity);
|
|
1087
|
+
if (!row)
|
|
1088
|
+
return [];
|
|
1089
|
+
const parent = parentProcess(row, byPid);
|
|
1090
|
+
return [{ identity, parent: parent ? processKey(parent) : null, argv_digest: row.argv_digest }];
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1080
1093
|
// 起動完了の控えに無いprocessの数。harnessと中継が自分のために立てるprocessは、利用者の作業ではないので数えない。
|
|
1081
1094
|
// その下で動くprocessは数える。
|
|
1082
|
-
|
|
1095
|
+
// harnessは起動の足場(MCP、language server)を自分で立て直す。控えた後に立て直されると、控えに無いprocessとして残る。
|
|
1096
|
+
// 控えの物が終了していて、同じ親の下に同じargvで立ったprocessは、その立て直しとして数えない。
|
|
1097
|
+
// 親も立て直されている時は、立て直された親の下を見る。終了した控え1つにつき、数えないのは1つまで。
|
|
1098
|
+
export function postStartupProcessCount(kind, activityRows, rows, startup, shapes = []) {
|
|
1083
1099
|
const byPid = new Map(rows.map(row => [row.pid, row]));
|
|
1084
1100
|
const relayChild = (row) => {
|
|
1085
1101
|
const parent = parentProcess(row, byPid);
|
|
1086
1102
|
return parent !== undefined && lazyRelayProcess(parent.command);
|
|
1087
1103
|
};
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
.
|
|
1104
|
+
const present = new Set(activityRows.map(processKey));
|
|
1105
|
+
const added = new Map(activityRows
|
|
1106
|
+
.filter(row => !startup.has(processKey(row)) && !(kind === "codex" && codexHelperProcess(row.command)) && !relayChild(row))
|
|
1107
|
+
.map(row => [processKey(row), row]));
|
|
1108
|
+
const gone = shapes.filter(shape => startup.has(shape.identity) && !present.has(shape.identity));
|
|
1109
|
+
const replacedBy = new Map();
|
|
1110
|
+
for (let changed = gone.length > 0; changed;) {
|
|
1111
|
+
changed = false;
|
|
1112
|
+
for (const [key, row] of added) {
|
|
1113
|
+
const parent = parentProcess(row, byPid);
|
|
1114
|
+
if (!parent)
|
|
1115
|
+
continue;
|
|
1116
|
+
const parentKey = processKey(parent);
|
|
1117
|
+
const original = gone.find(shape => !replacedBy.has(shape.identity) && shape.argv_digest === row.argv_digest
|
|
1118
|
+
&& shape.parent !== null && (shape.parent === parentKey || replacedBy.get(shape.parent) === parentKey));
|
|
1119
|
+
if (!original)
|
|
1120
|
+
continue;
|
|
1121
|
+
replacedBy.set(original.identity, key);
|
|
1122
|
+
added.delete(key);
|
|
1123
|
+
changed = true;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
return added.size;
|
|
1091
1127
|
}
|
|
1092
1128
|
export function observeSession(name, cursor) {
|
|
1093
1129
|
assertSessionName(name);
|
|
@@ -1190,7 +1226,8 @@ export function observeSession(name, cursor) {
|
|
|
1190
1226
|
background_cpu_seconds: Object.values(backgroundCpu).reduce((sum, cpu) => sum + cpu, 0),
|
|
1191
1227
|
background_cpu_delta_seconds: comparable ? Object.entries(backgroundCpu).reduce((sum, [identity, cpu]) => sum + cpu - (previous.background_processes[identity] ?? 0), 0) : null,
|
|
1192
1228
|
background_cpu_delta_complete: comparable ? Object.keys(previous.background_processes).every(identity => identity in backgroundCpu) : null,
|
|
1193
|
-
post_startup_process_count: startup
|
|
1229
|
+
post_startup_process_count: startup
|
|
1230
|
+
? postStartupProcessCount(meta.kind, activityRows, rows, startup, meta.startup_process_shapes) : null,
|
|
1194
1231
|
};
|
|
1195
1232
|
return result;
|
|
1196
1233
|
}
|
|
@@ -2013,8 +2050,10 @@ function loadAgentMetadata(name) {
|
|
|
2013
2050
|
initial_prompt_delivery: m.initial_prompt_delivery, initial_prompt_cursor: m.initial_prompt_cursor,
|
|
2014
2051
|
};
|
|
2015
2052
|
const executableFields = m.agent_executable === undefined ? {} : { agent_executable: m.agent_executable };
|
|
2053
|
+
const startupShapes = Array.isArray(m.startup_process_shapes) && m.startup_process_shapes.every((shape) => shape && typeof shape.identity === "string" && (shape.parent === null || typeof shape.parent === "string") && typeof shape.argv_digest === "string")
|
|
2054
|
+
? { startup_process_shapes: m.startup_process_shapes } : {};
|
|
2016
2055
|
const startupFields = Array.isArray(m.startup_processes) && m.startup_processes.every((identity) => typeof identity === "string")
|
|
2017
|
-
? { startup_processes: m.startup_processes } : {};
|
|
2056
|
+
? { startup_processes: m.startup_processes, ...startupShapes } : {};
|
|
2018
2057
|
if (m.kind === "claude") {
|
|
2019
2058
|
const expectedSettings = agentManagedClaudeSettingsPath(name, m.launch_id);
|
|
2020
2059
|
const expectedResult = agentClaudeResultPath(name, m.launch_id);
|
|
@@ -3235,6 +3274,7 @@ async function prepareAgentInput(name, meta, options) {
|
|
|
3235
3274
|
// ここまでに居るprocessは起動時の足場(harness・MCP・起動時hook)。初手を送る前に控える。
|
|
3236
3275
|
if (live.activity.cursor !== null) {
|
|
3237
3276
|
meta.startup_processes = Object.keys(decodeActivityCursor(live.activity.cursor, name).processes);
|
|
3277
|
+
meta.startup_process_shapes = startupProcessShapes(meta.startup_processes, readRuntimeProcesses());
|
|
3238
3278
|
writeAgentMetadata(meta);
|
|
3239
3279
|
}
|
|
3240
3280
|
return { status: "ready", reason: "composer_ready" };
|
package/docs/DESIGN.md
CHANGED
|
@@ -55,6 +55,7 @@ POSIXの停止状態はOSのprocess表から取得し、SIGSTOP中は残画面
|
|
|
55
55
|
sessionを閉じると失うものは数で返す(ADR 0080)。`activity.post_startup_process_count`は起動完了の時点に居なかったprocessの数、
|
|
56
56
|
`pending_child_deliveries`はそのsessionが親として待つ未配送の数。数えられない時はnullで、0と区別する。
|
|
57
57
|
harnessと中継が自分のために立てるprocessは数えない(Codexの`codex-code-mode-host`、中継`mcp-lazy`の直接の子。ADR 0082)。その下は数える。
|
|
58
|
+
harnessが同じ親の下に同じargvで立て直した起動時のprocessも数えない(ADR 0083)。
|
|
58
59
|
中継の後ろで眠っている本体を配送の引き取りのために起こすかは、`aiterm-delivery-wake`が返す(ADR 0082)。
|
|
59
60
|
Claude Codeの入力待ちは、起動時の見出しが取得範囲から流れ出た後も、入力欄の形(`❯`行の上下の罫線)で読む。
|
|
60
61
|
画面本文とargv本文は返さず、活動cursorには画面digestとprocess別CPUだけを持たせる。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aiterm-mcp",
|
|
3
|
-
"version": "0.51.
|
|
3
|
+
"version": "0.51.1",
|
|
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": [
|