aiterm-mcp 0.43.6 → 0.43.7

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,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.43.7] - 2026-09-29
11
+
12
+ ### 修正
13
+
14
+ - Cursor CLIの親で、子の回答が作業中にもidle中にも届かなかった(Linux・macOS)。Cursor CLIはMCPを削った環境で起動し、hookと背景の受信processは画面側の環境で起動する。state rootの置き場(XDG_RUNTIME_DIR・TMPDIR・AITERM_STATE_BASE)が割れ、hookが配送記録を見つけられずに何もしていなかった。hookと受信processは、同じ利用者の置き場の候補のうち配送記録のある方を使う(aiterm-steer-delivery 0.1.8)。
15
+ - Cursor CLIのmodelはtool結果のstructuredContentを見ないため、idle中に受け取る背景コマンド(wait_process)を知らずにターンを終えていた。Cursor親への結果の本文にもそのコマンド行を書く。
16
+
10
17
  ## [0.43.6] - 2026-09-29
11
18
 
12
19
  ### 修正
@@ -1900,7 +1907,8 @@ prototype (preserved under `prototype/python/` as the porting source and referen
1900
1907
  `ubuntu-latest` for Node 18/20/22, publishing to npm on `v*` tags with
1901
1908
  provenance.
1902
1909
 
1903
- [Unreleased]: https://github.com/kitepon/aiterm-mcp/compare/v0.43.6...HEAD
1910
+ [Unreleased]: https://github.com/kitepon/aiterm-mcp/compare/v0.43.7...HEAD
1911
+ [0.43.7]: https://github.com/kitepon/aiterm-mcp/compare/v0.43.6...v0.43.7
1904
1912
  [0.43.6]: https://github.com/kitepon/aiterm-mcp/compare/v0.43.5...v0.43.6
1905
1913
  [0.43.5]: https://github.com/kitepon/aiterm-mcp/compare/v0.43.4...v0.43.5
1906
1914
  [0.43.4]: https://github.com/kitepon/aiterm-mcp/compare/v0.43.3...v0.43.4
package/README.ja.md CHANGED
@@ -203,7 +203,7 @@ runtime-error store は canonical dotagents config の `collection.enabled: true
203
203
  場合だけ収集し、既定OFF、network送信は行いません。tag起点CIのnpm provenance(OIDC Trusted
204
204
  Publishing)で公開し、GitHub Release が Official MCP Registry を再登録します。
205
205
 
206
- **状態:** 開発継続中 · 現行公開版 **v0.43.6** · 動作対象は Linux · WSL2 · macOS · Windows ネイティブ · MIT · [変更履歴](CHANGELOG.md)。
206
+ **状態:** 開発継続中 · 現行公開版 **v0.43.7** · 動作対象は Linux · WSL2 · macOS · Windows ネイティブ · MIT · [変更履歴](CHANGELOG.md)。
207
207
 
208
208
  ### 更新と巻き戻し
209
209
 
package/README.md CHANGED
@@ -217,7 +217,7 @@ collection is off by default and performs no network I/O. It ships via
217
217
  tag-triggered CI with npm provenance (OIDC Trusted Publishing); the GitHub
218
218
  Release re-registers the Official MCP Registry entry.
219
219
 
220
- **Status:** actively maintained · current public release **v0.43.6** · 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).
220
+ **Status:** actively maintained · current public release **v0.43.7** · 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).
221
221
 
222
222
  ### Update and rollback
223
223
 
@@ -1,6 +1,7 @@
1
1
  // harness中立の共有プリミティブ。core と harnesses/ の両方が依存する最下層で、
2
2
  // tmux-runtime / errors 以外の内部moduleへ依存しない(依存方向: core → harnesses → agent-shared)。
3
3
  import * as fs from "node:fs";
4
+ import * as os from "node:os";
4
5
  import * as path from "node:path";
5
6
  import { randomBytes } from "node:crypto";
6
7
  import { AitermError } from "./errors.js";
@@ -99,6 +100,16 @@ export function stateRoot() {
99
100
  const base = runtimeStateBase();
100
101
  return path.join(base, `aiterm-mcp-${uid}`);
101
102
  }
103
+ /**
104
+ * 同じ利用者のAitermが使いうるstate rootの候補(先頭はこのprocessのもの)。
105
+ * Cursor CLIはMCPを削った環境(XDG_RUNTIME_DIR・TMPDIR・AITERM_STATE_BASE無し)で起動し、hookと背景processは画面側の環境で起動する。
106
+ * 置き場は環境で決まるので両者で割れる。hook側はこの候補のうち配送記録のある置き場を使う。
107
+ */
108
+ export function stateRootCandidates() {
109
+ const name = `aiterm-mcp-${currentUid()}`;
110
+ const bases = [runtimeStateBase(), process.env.AITERM_STATE_BASE, process.env.XDG_RUNTIME_DIR, os.tmpdir(), process.platform === "win32" ? undefined : "/tmp"];
111
+ return [...new Set(bases.filter((base) => typeof base === "string" && base !== "").map(base => path.join(base, name)))];
112
+ }
102
113
  export function ensureStateRoot() {
103
114
  // state root は OS が与えるper-user runtime dir(Windows隔離時TMPDIR/XDG_RUNTIME_DIR/os.tmpdir())の下に作る。
104
115
  // 以前はここで symlink・owner・mode を検査していたが、共有 /tmp に敵対的な同居主体がいる
package/dist/core.js CHANGED
@@ -2620,7 +2620,7 @@ export function agentDispatchGuide(session, cursor) {
2620
2620
  const parent = autoDeliveryParent();
2621
2621
  if (parent === "Cursor") {
2622
2622
  return "回答はこの会話へ自動で届く。作業を続ければ次のツール返りに差し込まれる。" +
2623
- "ターンを終える前にreceiptのwait_processを背景(block_until_ms: 0)で起動しておけば、idle中に完了しても起きられる。" +
2623
+ "ターンを終える前に、この結果のwait_processのコマンドを背景(block_until_ms: 0)で起動しておけば、idle中に完了しても起きられる。" +
2624
2624
  "ポーリング・pty_read(agent_transcript:true)は不要。";
2625
2625
  }
2626
2626
  if (parent) {
@@ -2,5 +2,7 @@
2
2
  // Cursorが起動する公式hook。MCP stdioとは別processで、差し込み文をstdoutのJSONへ返す。本体はaiterm-steer-delivery。
3
3
  import { isDirectExecution, runCursorHookMain } from "aiterm-steer-delivery";
4
4
  import { AITERM_PROFILE } from "./steer-profile.js";
5
+ import { cursorHookRoots } from "./cursor-parent-receiver.js";
6
+ // Cursor CLIではMCPとhookの環境が違い、state rootが割れる。候補の置き場すべてで結び付けと差し込みを行う。
5
7
  if (isDirectExecution(import.meta.url))
6
- await runCursorHookMain(AITERM_PROFILE);
8
+ await runCursorHookMain(AITERM_PROFILE, cursorHookRoots());
@@ -2,12 +2,19 @@
2
2
  // Cursor親がidleのとき、背景で起動して回答本文の到着を待つ受け口。本体はaiterm-steer-delivery。
3
3
  import { fileURLToPath } from "node:url";
4
4
  import * as steer from "aiterm-steer-delivery";
5
- import { cursorHookRoot } from "./cursor-parent-receiver.js";
5
+ import { cursorHookRoots } from "./cursor-parent-receiver.js";
6
6
  export function cursorReceiveProcess(deliveryId, executable = process.execPath) {
7
7
  return steer.cursorReceiveProcess(fileURLToPath(import.meta.url), deliveryId, executable);
8
8
  }
9
+ /** 背景processの起動情報を、親のshellへ書ける1行にする(Windowsの既定shellはPowerShell)。 */
10
+ export function waitProcessCommandLine(wait, platform = process.platform) {
11
+ const values = [wait.executable, ...wait.args];
12
+ if (platform === "win32")
13
+ return `& ${values.map(value => `'${value.replace(/'/g, "''")}'`).join(" ")}`;
14
+ return values.map(value => `'${value.replace(/'/g, "'\\''")}'`).join(" ");
15
+ }
9
16
  export async function main(argv) {
10
- return steer.runCursorReceive(cursorHookRoot(), argv);
17
+ return steer.runCursorReceive(cursorHookRoots(), argv);
11
18
  }
12
19
  if (steer.isDirectExecution(import.meta.url)) {
13
20
  main(process.argv.slice(2)).then(code => { process.exitCode = code; }).catch(error => {
@@ -3,7 +3,7 @@
3
3
  import * as path from "node:path";
4
4
  import { z } from "zod";
5
5
  import * as steer from "aiterm-steer-delivery";
6
- import { ensureStateRoot } from "./agent-shared.js";
6
+ import { ensureStateRoot, stateRootCandidates } from "./agent-shared.js";
7
7
  import { AITERM_PROFILE } from "./steer-profile.js";
8
8
  // 配送記録の検証はAitermのzodで行う(パッケージのschemaと同じ形)。
9
9
  export const cursorParentSchema = z.object({ kind: z.literal("cursor"), hook_root: z.string() }).strict();
@@ -12,6 +12,10 @@ export const { isCursorMcpClient, cursorHooksFile, prepareCursorDelivery, submit
12
12
  export function cursorHookRoot(state = ensureStateRoot()) {
13
13
  return path.join(state, "cursor-parent-hooks");
14
14
  }
15
+ /** hookと受信processが配送記録を探す置き場(先頭はこのprocessのもの)。理由は stateRootCandidates。 */
16
+ export function cursorHookRoots() {
17
+ return stateRootCandidates().map(state => cursorHookRoot(state));
18
+ }
15
19
  export function cursorParentHooksRegistered(document) { return steer.cursorParentHooksRegistered(AITERM_PROFILE, document); }
16
20
  export function verifyCursorParent(parent, hooksFile = cursorHooksFile()) { steer.verifyCursorParent(AITERM_PROFILE, parent, hooksFile); }
17
21
  export function cursorParentFromRequest(clientName, options = {}) {
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ import { acceptRemote, callRemoteTool, observeRemoteAgentDone, remoteInputDescri
20
20
  import { codexParentFromRequest } from "./codex-parent-receiver.js";
21
21
  import { claudeParentFromRequest } from "./claude-parent-receiver.js";
22
22
  import { cursorParentFromRequest, isCursorMcpClient } from "./cursor-parent-receiver.js";
23
+ import { waitProcessCommandLine } from "./cursor-parent-receive.js";
23
24
  import { INTERIM_RESULT_META_KEY, interimRequestFromMeta } from "./interim-words.js";
24
25
  // package.json の version を実行時に読み、MCP initialize で配るサーバ版と一致させる。
25
26
  // createRequire を使うのは、import 属性 `with { type: "json" }` が Node 18.20+ 限定で
@@ -50,7 +51,11 @@ async function deliveryForRequest(extra, remote = false) {
50
51
  }
51
52
  function deliveryIdLine(delivery) {
52
53
  const id = delivery?.result()?.delivery_id;
53
- return id ? `\ndelivery_id=${id}` : "";
54
+ if (!id)
55
+ return "";
56
+ // Cursor CLIのmodelはtool結果のstructuredContentを見ないので、idle中に受け取る背景コマンドも本文に書く。
57
+ const wait = delivery?.wait_process();
58
+ return `\ndelivery_id=${id}` + (wait ? `\nwait_process(ターンを終える前に背景で起動): ${waitProcessCommandLine(wait)}` : "");
54
59
  }
55
60
  function completionWait(delivery, session, eventCursor) {
56
61
  if (eventCursor === null)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiterm-mcp",
3
- "version": "0.43.6",
3
+ "version": "0.43.7",
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": [
@@ -70,7 +70,7 @@
70
70
  },
71
71
  "dependencies": {
72
72
  "@modelcontextprotocol/sdk": "^1.29.0",
73
- "aiterm-steer-delivery": "^0.1.7",
73
+ "aiterm-steer-delivery": "^0.1.8",
74
74
  "ws": "8.21.3",
75
75
  "zod": "^4.4.3"
76
76
  },