aiterm-mcp 0.29.24 → 0.29.26
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 +15 -1
- package/README.ja.md +1 -1
- package/README.md +1 -1
- package/dist/core.js +68 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.29.26] - 2026-09-02
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Cursorの冷間起動時は、貼り付けたpromptがcomposerへ反映されたことを確認してからEnterを送り、入力準備前の早送信による未配達を防ぐ。
|
|
15
|
+
|
|
16
|
+
## [0.29.25] - 2026-09-02
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- 無人Claude起動時に最初だけ表示されるBypass Permissions確認を進め、続くworkspace trust確認と初回promptまで一度の起動で完了する。
|
|
21
|
+
|
|
10
22
|
## [0.29.24] - 2026-09-02
|
|
11
23
|
|
|
12
24
|
### Fixed
|
|
@@ -1494,7 +1506,9 @@ prototype (preserved under `prototype/python/` as the porting source and referen
|
|
|
1494
1506
|
`ubuntu-latest` for Node 18/20/22, publishing to npm on `v*` tags with
|
|
1495
1507
|
provenance.
|
|
1496
1508
|
|
|
1497
|
-
[Unreleased]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.
|
|
1509
|
+
[Unreleased]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.26...HEAD
|
|
1510
|
+
[0.29.26]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.25...v0.29.26
|
|
1511
|
+
[0.29.25]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.24...v0.29.25
|
|
1498
1512
|
[0.29.24]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.23...v0.29.24
|
|
1499
1513
|
[0.29.23]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.22...v0.29.23
|
|
1500
1514
|
[0.29.22]: https://github.com/kitepon/aiterm-mcp/compare/v0.29.21...v0.29.22
|
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.26** · 動作対象は Linux · WSL2 · macOS · Windows ネイティブ · MIT · [変更履歴](CHANGELOG.md)。
|
|
157
157
|
|
|
158
158
|
### 更新と巻き戻し
|
|
159
159
|
|
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.26** · 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
|
|
package/dist/core.js
CHANGED
|
@@ -61,6 +61,8 @@ const AGENT_SUBMIT_RESIDUE_POLL_MS = 300;
|
|
|
61
61
|
const AGENT_SUBMIT_RESIDUE_MAX_SAMPLES = 5;
|
|
62
62
|
const AGENT_SUBMIT_RESIDUE_TAIL_CHARS = 32;
|
|
63
63
|
const AGENT_SUBMIT_RESIDUE_MIN_TAIL_CHARS = 8;
|
|
64
|
+
const CURSOR_PROMPT_VISIBLE_POLL_MS = 100;
|
|
65
|
+
const CURSOR_PROMPT_VISIBLE_MAX_SAMPLES = 50;
|
|
64
66
|
// 出力削減(RTK の CAP 思想を移植)
|
|
65
67
|
const MAX_LINES_BEFORE_ELIDE = 60;
|
|
66
68
|
const HEAD_LINES = 30;
|
|
@@ -2354,7 +2356,8 @@ function isAgentTuiActionRequired(kind, screen) {
|
|
|
2354
2356
|
if (kind === "claude") {
|
|
2355
2357
|
return /new MCP servers? found in this project/iu.test(screen)
|
|
2356
2358
|
|| screen.includes("Is this a project you created or one you trust")
|
|
2357
|
-
|| screen.includes("trust this folder")
|
|
2359
|
+
|| screen.includes("trust this folder")
|
|
2360
|
+
|| (screen.includes("Claude Code running in Bypass Permissions mode") && screen.includes("Yes, I accept"));
|
|
2358
2361
|
}
|
|
2359
2362
|
return false;
|
|
2360
2363
|
}
|
|
@@ -2363,6 +2366,14 @@ function isClaudeWorkspaceTrustScreen(screen) {
|
|
|
2363
2366
|
&& screen.includes("No, exit")
|
|
2364
2367
|
&& screen.includes("Yes, I trust this folder");
|
|
2365
2368
|
}
|
|
2369
|
+
function isClaudeBypassPermissionsScreen(screen) {
|
|
2370
|
+
return screen.includes("Claude Code running in Bypass Permissions mode")
|
|
2371
|
+
&& screen.includes("No, exit")
|
|
2372
|
+
&& screen.includes("Yes, I accept");
|
|
2373
|
+
}
|
|
2374
|
+
function isClaudeManagedLaunchConfirmation(screen) {
|
|
2375
|
+
return isClaudeWorkspaceTrustScreen(screen) || isClaudeBypassPermissionsScreen(screen);
|
|
2376
|
+
}
|
|
2366
2377
|
async function waitAgentTuiReadyImpl(kind, sample, sleepFn, opts = {}) {
|
|
2367
2378
|
const timeoutMs = opts.timeoutMs ?? AGENT_TUI_READY_TIMEOUT_MS;
|
|
2368
2379
|
const pollMs = opts.pollMs ?? AGENT_TUI_READY_POLL_MS;
|
|
@@ -2471,6 +2482,22 @@ async function detectAgentSubmitResidueImpl(kind, text, sample, sleepFn, opts =
|
|
|
2471
2482
|
async function detectAgentSubmitResidue(name, kind, text) {
|
|
2472
2483
|
return detectAgentSubmitResidueImpl(kind, text, () => captureScreen(name, AGENT_TUI_READY_LINES), sleep);
|
|
2473
2484
|
}
|
|
2485
|
+
async function waitCursorPromptVisibleImpl(text, sample, sleepFn, opts = {}) {
|
|
2486
|
+
const tail = agentSubmitResidueTail(text) ?? normalizeResidueText(text);
|
|
2487
|
+
const pollMs = opts.pollMs ?? CURSOR_PROMPT_VISIBLE_POLL_MS;
|
|
2488
|
+
const maxSamples = opts.maxSamples ?? CURSOR_PROMPT_VISIBLE_MAX_SAMPLES;
|
|
2489
|
+
for (let i = 0; i < maxSamples; i++) {
|
|
2490
|
+
if (agentSubmitResidueOnScreen("cursor", sample(), tail) === true) {
|
|
2491
|
+
return { visible: true, samples: i + 1 };
|
|
2492
|
+
}
|
|
2493
|
+
if (i < maxSamples - 1)
|
|
2494
|
+
await sleepFn(pollMs);
|
|
2495
|
+
}
|
|
2496
|
+
return { visible: false, samples: maxSamples };
|
|
2497
|
+
}
|
|
2498
|
+
async function waitCursorPromptVisible(name, text) {
|
|
2499
|
+
return waitCursorPromptVisibleImpl(text, () => captureScreen(name, AGENT_TUI_READY_LINES), sleep);
|
|
2500
|
+
}
|
|
2474
2501
|
export function agentSubmitResidueWarning(name, residue) {
|
|
2475
2502
|
if (residue !== true)
|
|
2476
2503
|
return "";
|
|
@@ -2549,13 +2576,23 @@ export async function __testDetectAgentSubmitResidue(kind, text, samples, opts =
|
|
|
2549
2576
|
}, opts);
|
|
2550
2577
|
return { ...result, sleeps };
|
|
2551
2578
|
}
|
|
2579
|
+
export async function __testWaitCursorPromptVisible(text, samples, opts = {}) {
|
|
2580
|
+
if (samples.length === 0)
|
|
2581
|
+
throw new AitermError("Cursor prompt反映待ちのtest samplesが空です", 2);
|
|
2582
|
+
let i = 0;
|
|
2583
|
+
const sleeps = [];
|
|
2584
|
+
const result = await waitCursorPromptVisibleImpl(text, () => samples[Math.min(i++, samples.length - 1)], async (ms) => {
|
|
2585
|
+
sleeps.push(ms);
|
|
2586
|
+
}, opts);
|
|
2587
|
+
return { ...result, sleeps };
|
|
2588
|
+
}
|
|
2552
2589
|
export function __testSetAgentTuiReadyStableSamples(value) {
|
|
2553
2590
|
if (value !== null && (!Number.isInteger(value) || value < 1 || value > 1000)) {
|
|
2554
2591
|
throw new AitermError("test ready stable samplesが不正です", 2);
|
|
2555
2592
|
}
|
|
2556
2593
|
agentTuiReadyStableSamplesTestOverride = value;
|
|
2557
2594
|
}
|
|
2558
|
-
async function sendAgentPromptText(name, text) {
|
|
2595
|
+
async function sendAgentPromptText(name, text, kind) {
|
|
2559
2596
|
send(name, text, {
|
|
2560
2597
|
enter: false,
|
|
2561
2598
|
force: true,
|
|
@@ -2565,7 +2602,16 @@ async function sendAgentPromptText(name, text) {
|
|
|
2565
2602
|
preserveAgentOperation: true,
|
|
2566
2603
|
bracketedPaste: true,
|
|
2567
2604
|
});
|
|
2568
|
-
|
|
2605
|
+
if (kind === "cursor") {
|
|
2606
|
+
const visible = await waitCursorPromptVisible(name, text);
|
|
2607
|
+
if (!visible.visible) {
|
|
2608
|
+
throw new AitermError(`vendor=cursor session=${name}\n` +
|
|
2609
|
+
"送信promptがCursorのcomposerへ反映されたことを確認できないため、Enterは送信していません。", 2);
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
else {
|
|
2613
|
+
await sleep(AGENT_SUBMIT_DELAY_MS);
|
|
2614
|
+
}
|
|
2569
2615
|
sendKey(name, "Enter", { preserveAgentOperation: true });
|
|
2570
2616
|
}
|
|
2571
2617
|
export async function sendInitialAgentPrompt(name, text, o = {}) {
|
|
@@ -2579,9 +2625,9 @@ export async function sendInitialAgentPrompt(name, text, o = {}) {
|
|
|
2579
2625
|
}
|
|
2580
2626
|
setInitialPromptState(meta, "not_sent");
|
|
2581
2627
|
let ready = await waitAgentTuiReady(name, meta, o.ready_timeout ?? AGENT_TUI_READY_TIMEOUT_MS);
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2628
|
+
// 無人Claude起動でCLI自身が順に出す、bypass mode確認とworkspace trustだけを
|
|
2629
|
+
// 起動処理の一部として進める。通常turn中の権限確認やMCP承認には触れない。
|
|
2630
|
+
for (let confirmations = 0; !ready.ready && meta.kind === "claude" && confirmations < 3 && isClaudeManagedLaunchConfirmation(ready.lastScreen); confirmations++) {
|
|
2585
2631
|
sendKey(name, "Down", { preserveAgentOperation: true });
|
|
2586
2632
|
await sleep(AGENT_SUBMIT_DELAY_MS);
|
|
2587
2633
|
sendKey(name, "Enter", { preserveAgentOperation: true });
|
|
@@ -2605,7 +2651,7 @@ export async function sendInitialAgentPrompt(name, text, o = {}) {
|
|
|
2605
2651
|
prepareSendText(text, { raw: false });
|
|
2606
2652
|
reserveAnonymousClaudeTurn(meta);
|
|
2607
2653
|
}
|
|
2608
|
-
await sendAgentPromptText(name, promptText);
|
|
2654
|
+
await sendAgentPromptText(name, promptText, meta.kind);
|
|
2609
2655
|
setInitialPromptState(meta, "pending");
|
|
2610
2656
|
}
|
|
2611
2657
|
catch (e) {
|
|
@@ -2742,12 +2788,12 @@ export async function configureAgent(name, opts) {
|
|
|
2742
2788
|
// Cursor TUIの `/model <base model>` はmodelを直接切り替える一方、flatten済みcatalog ID
|
|
2743
2789
|
// (例: gpt-5.6-luna-high)を渡すとno matchesのfilter画面へ入る。effortは標準model pickerの
|
|
2744
2790
|
// parameter editorで選び、同じsessionと会話contextを保つ。
|
|
2745
|
-
await sendAgentPromptText(name, `/model ${model}
|
|
2791
|
+
await sendAgentPromptText(name, `/model ${model}`, meta.kind);
|
|
2746
2792
|
const modelReady = await waitAgentTuiReady(name, meta, AGENT_TUI_READY_TIMEOUT_MS);
|
|
2747
2793
|
if (!modelReady.ready)
|
|
2748
2794
|
throw new AitermError("Cursorのmodel変更完了を確認できません", 2);
|
|
2749
2795
|
if (effort) {
|
|
2750
|
-
await sendAgentPromptText(name, "/model");
|
|
2796
|
+
await sendAgentPromptText(name, "/model", meta.kind);
|
|
2751
2797
|
await waitForScreenText(name, "Available models");
|
|
2752
2798
|
sendMenuChoice(name, "Tab");
|
|
2753
2799
|
const parameterScreen = await waitForScreenText(name, "Edit Parameters");
|
|
@@ -2886,8 +2932,19 @@ export async function dispatchAgentTurn(name, text, o = {}) {
|
|
|
2886
2932
|
preserveAgentOperation: meta.kind === "claude",
|
|
2887
2933
|
bracketedPaste: true,
|
|
2888
2934
|
});
|
|
2889
|
-
//
|
|
2890
|
-
|
|
2935
|
+
// Cursorの冷間起動ではbracketed pasteの反映が250msを超えることがある。本文がcomposerへ
|
|
2936
|
+
// 現れた実測をsubmit条件にし、未反映のままEnterだけを失う競合を作らない。
|
|
2937
|
+
if (meta.kind === "cursor") {
|
|
2938
|
+
const visible = await waitCursorPromptVisible(name, dispatchText);
|
|
2939
|
+
if (!visible.visible) {
|
|
2940
|
+
throw new AitermError(`vendor=cursor session=${name}\n` +
|
|
2941
|
+
"送信promptがCursorのcomposerへ反映されたことを確認できないため、Enterは送信していません。", 2);
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
else {
|
|
2945
|
+
// Codex TUI は literal text 投入直後の Enter を取り落とすことがある。agent 経路だけ submit を分離する。
|
|
2946
|
+
await sleep(AGENT_SUBMIT_DELAY_MS);
|
|
2947
|
+
}
|
|
2891
2948
|
sendKey(name, "Enter", { preserveAgentOperation: meta.kind === "claude" });
|
|
2892
2949
|
const residue = await detectAgentSubmitResidue(name, meta.kind, dispatchText);
|
|
2893
2950
|
assertAgentSubmitDelivered(name, meta.kind, residue);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aiterm-mcp",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.26",
|
|
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": [
|