aiterm-mcp 0.55.1 → 0.55.2

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 CHANGED
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.55.2] - 2026-10-06
11
+
12
+ ### 修正
13
+
14
+ - 会話欄か入力欄に`esc to interrupt`の語があるだけのClaude Codeを、動作中と読まない(ADR 0095)。回答や依頼文に
15
+ この語がある席は、turnが終わった後も`pty_observe`が`busy`を返し続けていた。起動時promptにこの語があると、送る前に
16
+ 開始を確認した事になっていた。動作中の印として数えるのは、Claude Codeが自分で出す足元の行と進行行だけにする。
17
+ 動いている間の読みは変わらない。
18
+ - 会話欄に`esc to interrupt`の語があるだけのCodexを、動作中と読まない(ADR 0095)。回答にこの語が残ったCodexの席は、
19
+ 止まった後も`pty_observe`が`busy`を返し、次の`pty_send`が差し込み(`agent_steer`)として返っていた。Codexは文を
20
+ 新しいturnとして処理するが、呼び出し側には完了待ちの手段も親への配送も渡らなかった。動作中の印として数えるのは、
21
+ Codexが自分で出す形(`(5s • esc to interrupt)`。括弧の中に経過時間、`•`、語)だけにする。
22
+
10
23
  ## [0.55.1] - 2026-10-06
11
24
 
12
25
  ### 修正
@@ -2270,7 +2283,8 @@ prototype (preserved under `prototype/python/` as the porting source and referen
2270
2283
  `ubuntu-latest` for Node 18/20/22, publishing to npm on `v*` tags with
2271
2284
  provenance.
2272
2285
 
2273
- [Unreleased]: https://github.com/kitepon/aiterm-mcp/compare/v0.55.1...HEAD
2286
+ [Unreleased]: https://github.com/kitepon/aiterm-mcp/compare/v0.55.2...HEAD
2287
+ [0.55.2]: https://github.com/kitepon/aiterm-mcp/compare/v0.55.1...v0.55.2
2274
2288
  [0.55.1]: https://github.com/kitepon/aiterm-mcp/compare/v0.55.0...v0.55.1
2275
2289
  [0.55.0]: https://github.com/kitepon/aiterm-mcp/compare/v0.54.0...v0.55.0
2276
2290
  [0.54.0]: https://github.com/kitepon/aiterm-mcp/compare/v0.53.2...v0.54.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.55.1** · 動作対象は Linux · WSL2 · macOS · Windows ネイティブ · MIT · [変更履歴](CHANGELOG.md)。
212
+ **状態:** 開発継続中 · 現行公開版 **v0.55.2** · 動作対象は Linux · WSL2 · macOS · Windows ネイティブ · MIT · [変更履歴](CHANGELOG.md)。
213
213
 
214
214
  ### 更新と巻き戻し
215
215
 
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.55.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).
226
+ **Status:** actively maintained · current public release **v0.55.2** · 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
 
package/dist/core.js CHANGED
@@ -22,7 +22,7 @@ import { isWin, SOCKDIR, tmuxCommand, sendPsmuxPayload, loadPtyBufferChunk, past
22
22
  import { sleep, currentUid, runtimeStateBase, safeStatSize, readFileRange, writeJson0600, createEmpty0600, shq, LAUNCH_ID_RE, AGENT_DONE_POLL_MS, AGENT_RATE_LIMIT_POLL_MS, pollGate, AGENT_EVENT_MAX_BYTES, assertSessionName, agentsDir, agentEventPath, agentMetadataPath, writeAgentMetadata, AGENT_EVENT_TAIL_BYTES, agentLabel, agentHarness, subagentInstruction, agentLineageFields, } from "./agent-shared.js";
23
23
  import { catalogUnavailable } from "./model-catalog.js";
24
24
  import { grokAuthPlan, grokAuthStatus, grokAuthPane, realGrokHome, resolveAndValidateGrokAuth, assertGrokModelAvailable, grokModelChoices, grokEventsTranscript, latestGrokCompletion, observeGrokDone, buildGrokAgentCmd, grokLaunchNote, grokEnvTokens, grokTuiReady, grokTuiBusy, grokPaneObservation, grokRateLimitDialog, grokStartupAction, grokLaunchBlockingDialog, assertGrokSandboxNotRejected, GROK_COMPOSER_MARKER_RE, grokFooterHasConfiguration, grokTranscriptText, createGrokAgentMetadata, } from "./harnesses/grok.js";
25
- import { codexAuthPlan, codexAuthStatus, codexAuthPane, bindCodexTranscriptSession, latestCodexCompletion, observeCodexDone, buildCodexAgentCmd, codexLaunchNote, codexTuiReady, codexPaneObservation, codexHelperProcess, codexRateLimitModelSwitchDialog, codexApprovalDialog, codexStartupAction, CODEX_COMPOSER_MARKER_RE, codexModelChoice, codexEffortChoice, codexMoreReasoningChoice, codexTranscriptText, createCodexAgentMetadata, codexModelChoices, } from "./harnesses/codex.js";
25
+ import { codexAuthPlan, codexAuthStatus, codexAuthPane, bindCodexTranscriptSession, latestCodexCompletion, observeCodexDone, buildCodexAgentCmd, codexLaunchNote, codexTuiReady, codexPaneObservation, codexTuiBusy, codexHelperProcess, codexRateLimitModelSwitchDialog, codexApprovalDialog, codexStartupAction, CODEX_COMPOSER_MARKER_RE, codexModelChoice, codexEffortChoice, codexMoreReasoningChoice, codexTranscriptText, createCodexAgentMetadata, codexModelChoices, } from "./harnesses/codex.js";
26
26
  import { claudeAuthPlan, claudeAuthStatus, claudeAuthPane, OPERATION_ID_RE, CLAUDE_RESULT_MAX_BYTES, CLAUDE_EFFORTS, agentManagedClaudeSettingsPath, agentClaudeResultPath, agentClaudeOperationPath, agentClaudeApprovalReceiptPath, agentClaudeDispatchReceiptPath, validateOperationId, readClaudeResultText, assertClaudeAuthenticationReady, claudeModelChoices, buildClaudeAgentCmd, claudeLaunchNote, claudeTuiReady, claudePaneObservation, claudeUsageLimit, claudeStartupAction, claudeLoginMethodMenu, CLAUDE_COMPOSER_MARKER_RE, createClaudeAgentMetadata, claudeSessionTranscriptPath, claudeApiErrorFromLine, claudeApiErrorAfter, } from "./harnesses/claude.js";
27
27
  import { cursorAuthPlan, cursorAuthStatus, cursorAuthPane, bindCursorTranscriptSession, cursorTurnBoundary, latestCursorCompletion, observeCursorDone, cursorTranscriptText, assertCursorAuthenticationReady, assertCursorModelAvailable, cursorModelChoices, buildCursorAgentCmd, cursorAgentArgv, cursorPwshLaunchLine, cursorPromptWithLineage, createCursorAgentMetadata, cursorLaunchNote, cursorEffortNavigation, cursorTuiReady, cursorPaneObservation, cursorPromptHooksRunning, cursorUsageLimit, CURSOR_SUBMIT_SEQUENCE, CURSOR_COMPOSER_CONTENT_MARKER_RE, validateCursorModelEffort, } from "./harnesses/cursor.js";
28
28
  import { readInterimWords, recordInterimBoundary } from "./interim-words.js";
@@ -3103,7 +3103,9 @@ function isAgentTuiReady(kind, screen) {
3103
3103
  function isAgentTuiBusy(kind, screen) {
3104
3104
  if (kind === "cursor")
3105
3105
  return /ctrl\+c to stop/i.test(screen);
3106
- if (kind === "codex" || kind === "claude")
3106
+ if (kind === "codex")
3107
+ return codexTuiBusy(screen);
3108
+ if (kind === "claude")
3107
3109
  return /esc to interrupt/i.test(screen);
3108
3110
  if (kind === "grok") {
3109
3111
  return grokTuiBusy(screen);
@@ -308,7 +308,30 @@ function claudeTurnProgress(screen) {
308
308
  // 足元の「esc to interrupt」は、貼り付けの知らせ(paste again to expand)へ置き換わる間は出ない。複数行のpromptを
309
309
  // 送った後の約8秒がそうで、その間は動いているのに入力待ちと読んでいた(2.1.291、2026-10-06)。進行行も動作中の印にする。
310
310
  export function claudeTuiBusy(screen) {
311
- return /esc to interrupt/i.test(screen.split("\n").slice(-32).join("\n")) || claudeTurnProgress(screen);
311
+ return claudeInterruptHint(screen) || claudeTurnProgress(screen);
312
+ }
313
+ // 「esc to interrupt」は、Claude Codeが動いている間に自分で出す印である。会話欄(回答・依頼文・道具の出力)や、
314
+ // 入力欄へ打ちかけの文にこの語があっても、動作中の印にしない。Aitermの中身を話している席は、止まった後も
315
+ // 画面にこの語が残り、動作中と読まれ続けていた。
316
+ // 入力欄(すぐ上が罫線の「❯」行)を見つけた時は、次の行だけを見る。
317
+ // - 入力欄の下の罫線より後(足元の行)。
318
+ // - 入力欄より上の、行頭から始まる行(古い版の進行行「✻ Musing… (esc to interrupt)」)。会話欄の行は
319
+ // 回答の印(「●」。macOSは「⏺」)か依頼文の印(「❯」「>」)で始まるか、字下げされている。
320
+ // 会話欄と見分けられない行は、今までどおり印にする(動いている席を入力待ちと読む方が害が大きい)。
321
+ // 入力欄の無い画面も、今までどおり末尾のどこにあっても印にする。
322
+ const CLAUDE_INTERRUPT_HINT_RE = /esc to interrupt/i;
323
+ function claudeInterruptHint(screen) {
324
+ const lines = screen.split("\n").slice(-32);
325
+ const rule = /^\s*─{8,}\s*$/u;
326
+ let marker = lines.length - 1;
327
+ while (marker >= 0 && !CLAUDE_COMPOSER_MARKER_RE.test(lines[marker]))
328
+ marker--;
329
+ if (marker <= 0 || !rule.test(lines[marker - 1]))
330
+ return CLAUDE_INTERRUPT_HINT_RE.test(lines.join("\n"));
331
+ const below = lines.findIndex((line, i) => i > marker && rule.test(line));
332
+ const footer = below < 0 ? marker + 1 : below + 1;
333
+ return lines.some((line, i) => CLAUDE_INTERRUPT_HINT_RE.test(line)
334
+ && (i >= footer || (i < marker - 1 && !/^(?:\s|[●⏺❯>])/u.test(line))));
312
335
  }
313
336
  export function claudePaneObservation(screen) {
314
337
  const tail = screen.split("\n").slice(-32).join("\n");
@@ -433,6 +433,15 @@ export function codexHelperProcess(command) {
433
433
  const first = /^(?:"([^"]+)"|(\S+))/.exec(command);
434
434
  return path.posix.basename((first?.[1] ?? first?.[2] ?? "").replace(/\\/g, "/")).replace(/\.exe$/i, "") === "codex-code-mode-host";
435
435
  }
436
+ // Codexは動いている間、入力欄の上へ「◦ Working (5s • esc to interrupt)」の行を出す。見出しの文は作業の内容で変わるが、
437
+ // 括弧の中(経過時間、「•」、「esc to interrupt」)の形は変わらない。動作中の印として数えるのは、この形だけにする。
438
+ // 会話欄(回答・依頼文)に「esc to interrupt」の語があるだけの席を動作中と読むと、止まっている席への送信が
439
+ // 差し込みになり、その回の完了が呼び出し側へ届かない(Codex 0.160.1の実物、2026-10-06)。
440
+ // Codexは動作中の行と回答の行が同じ印(•)で始まるので、行頭の印では見分けられない。
441
+ const CODEX_INTERRUPT_HINT_RE = /\((?:\d+\s*[hms]\s*)+•\s*esc to interrupt\)/i;
442
+ export function codexTuiBusy(screen) {
443
+ return CODEX_INTERRUPT_HINT_RE.test(screen);
444
+ }
436
445
  export function codexPaneObservation(screen) {
437
446
  const failure = codexStartupFailure(screen);
438
447
  if (failure)
@@ -444,7 +453,7 @@ export function codexPaneObservation(screen) {
444
453
  const lastDialog = [...tail.matchAll(CODEX_MODAL_MARKER)].at(-1)?.index ?? -1;
445
454
  const modal = lastDialog > lastComposer;
446
455
  if (!modal) {
447
- if (/esc to interrupt/i.test(tail))
456
+ if (codexTuiBusy(tail))
448
457
  return { state: "busy", reason: "turn_running" };
449
458
  if (codexTuiReady(tail))
450
459
  return { state: "idle", reason: "composer_ready" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiterm-mcp",
3
- "version": "0.55.1",
3
+ "version": "0.55.2",
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": [