aiterm-mcp 0.25.1 → 0.25.3
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/README.ja.md +5 -0
- package/README.md +5 -0
- package/dist/core.js +35 -5
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -96,6 +96,11 @@ host統合は、kitepon.devの製品開発を支える内部基盤
|
|
|
96
96
|
|
|
97
97
|
14 ツール: 6 つの **PTY ツール**(`pty_open` / `pty_send` / `pty_read` / `pty_key` / `pty_close` / `pty_list`)で 1 本の永続端末を開き・操作し・読む。加えて 4 つの **エージェント起動ツール**(`claude_agent` / `codex_agent` / `grok_agent` / `composer_agent`)が別のコーディングエージェントの TUI を新しい端末の中に起動し、`agent_configure`が起動中のClaude/Codex/Grok/Composerのmodel・effortを再起動なしで変更し、`claude_turn`がdurable caller向けの構造化issue/recoveryを、`claude_approval`が相関済みClaude承認UI中継を、`diagnostics`が安全なfactory readinessを返す。バックエンドは **tmux** なので、MCP サーバや AI クライアントが再起動してもセッションは生き残る。
|
|
98
98
|
|
|
99
|
+
**v0.25.2ではGrok 4.6を含む同一sessionの連続設定変更を安定化。** Grok Build 1.0.3で
|
|
100
|
+
`/model`の成功通知が再描画により消えても、変更前には無かった要求model/effortが常駐footerへ現れた
|
|
101
|
+
最終状態を確認する。caller側のretry、再起動、失敗の成功丸めは不要で、`grok-4.6`は従来どおり
|
|
102
|
+
明示`model`としてlive catalog照合後に起動・変更できる。
|
|
103
|
+
|
|
99
104
|
**v0.25.0ではGrok/Composerへ共通launcher制御を同等実装。** 起動時`reasoning_effort`、
|
|
100
105
|
`write_scope:"read-only"`の`--sandbox read-only`強制、`agent_configure`による同一session内の
|
|
101
106
|
model/effort変更に対応した。明示したGrok/Composer modelとComposer既定modelはPTY作成前に
|
package/README.md
CHANGED
|
@@ -96,6 +96,11 @@ toolchain behind kitepon.dev's products.
|
|
|
96
96
|
|
|
97
97
|
Fourteen tools: six **PTY tools** — `pty_open` / `pty_send` / `pty_read` / `pty_key` / `pty_close` / `pty_list` — to open, drive, and read one persistent terminal, four **agent launchers** — `claude_agent` / `codex_agent` / `grok_agent` / `composer_agent` — that each start another coding agent's TUI inside a fresh one, `agent_configure` to change a running Claude/Codex/Grok/Composer session's model and effort without restarting it, `claude_turn` for durable structured issue/recovery, `claude_approval` for correlated Claude approval prompts, and `diagnostics` for safe factory readiness. The backend is **tmux**, so sessions survive even if the MCP server or the AI client restarts.
|
|
98
98
|
|
|
99
|
+
**v0.25.2 stabilizes repeated in-place configuration changes, including Grok 4.6.** If Grok Build
|
|
100
|
+
1.0.3 redraws before its `/model` success notice can be observed, aiterm confirms the requested model/effort
|
|
101
|
+
from the persistent footer when that state was absent before the command. Callers do not retry, restart, or
|
|
102
|
+
round a failure into success; explicit `grok-4.6` launch and configuration still pass the live catalog check.
|
|
103
|
+
|
|
99
104
|
**v0.25.0 gives Grok and Composer the same shared launcher controls.** Their launchers now pass
|
|
100
105
|
`reasoning_effort`, enforce `write_scope: "read-only"` with `--sandbox read-only`, and support
|
|
101
106
|
in-place model/effort changes through `agent_configure`. Before creating a PTY, aiterm checks an
|
package/dist/core.js
CHANGED
|
@@ -1625,7 +1625,11 @@ function resolveAndValidateGrokAuth(srcHome) {
|
|
|
1625
1625
|
try {
|
|
1626
1626
|
fd = fs.openSync(authPath, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_NONBLOCK);
|
|
1627
1627
|
const st = fs.fstatSync(fd);
|
|
1628
|
-
|
|
1628
|
+
// Windows の fs.Stats.mode は POSIX permission bit を持たず、常に 666/777 相当を報告する
|
|
1629
|
+
// (NTFS ACL は別体系)。currentUid と同じ既知制約の明示的受容として、Windows では
|
|
1630
|
+
// group/other bit 検証を行わない。isFile・nlink・owner・size・O_NOFOLLOW・realpath 検証は共通に維持する。
|
|
1631
|
+
const worldAccessible = !isWin && (st.mode & 0o077) !== 0;
|
|
1632
|
+
if (!st.isFile() || st.nlink !== 1 || st.uid !== currentUid() || worldAccessible || st.size > GROK_AUTH_MAX_BYTES) {
|
|
1629
1633
|
throw new AitermError("Grok 認証正本の安全検証に失敗しました", 2);
|
|
1630
1634
|
}
|
|
1631
1635
|
const value = JSON.parse(fs.readFileSync(fd, "utf8"));
|
|
@@ -1643,7 +1647,8 @@ function resolveAndValidateGrokAuth(srcHome) {
|
|
|
1643
1647
|
// /tmp のような root 所有 + sticky の共有 directory は、本人所有の private な
|
|
1644
1648
|
// 直下 directory を他 UID が rename/unlink できないため許可する。sticky 無しの
|
|
1645
1649
|
// group/other writable 祖先は path swap が可能なので従来どおり拒否する。
|
|
1646
|
-
|
|
1650
|
+
// Windows は directory も mode bit を持たない(常に 777 相当)ため、同じ受容で除外する。
|
|
1651
|
+
const writableByOthers = !isWin && (dirSt.mode & 0o022) !== 0;
|
|
1647
1652
|
const protectedSharedRoot = dirSt.uid === 0 && (dirSt.mode & 0o1000) !== 0;
|
|
1648
1653
|
if (!dirSt.isDirectory()
|
|
1649
1654
|
|| dirSt.isSymbolicLink()
|
|
@@ -3629,8 +3634,24 @@ function lineCounts(screen) {
|
|
|
3629
3634
|
}
|
|
3630
3635
|
return counts;
|
|
3631
3636
|
}
|
|
3632
|
-
|
|
3637
|
+
function grokFooterHasConfiguration(screen, model, effort) {
|
|
3638
|
+
const modelMatch = model?.match(/^grok-(\d+(?:\.\d+)*)$/) ?? null;
|
|
3639
|
+
if (model && !modelMatch)
|
|
3640
|
+
return false;
|
|
3641
|
+
const modelLabel = modelMatch ? `Grok ${modelMatch[1]}` : null;
|
|
3642
|
+
return screen.split("\n").some((line) => {
|
|
3643
|
+
if (!line.includes("·"))
|
|
3644
|
+
return false;
|
|
3645
|
+
if (modelLabel && !line.includes(`${modelLabel} (`))
|
|
3646
|
+
return false;
|
|
3647
|
+
if (effort && !line.includes(`(${effort})`))
|
|
3648
|
+
return false;
|
|
3649
|
+
return modelLabel !== null || effort !== null;
|
|
3650
|
+
});
|
|
3651
|
+
}
|
|
3652
|
+
async function waitForGrokConfigurationResult(name, before, model, effort, timeoutMs = 3_000) {
|
|
3633
3653
|
const beforeCounts = lineCounts(before);
|
|
3654
|
+
const footerAlreadyMatched = grokFooterHasConfiguration(before, model, effort);
|
|
3634
3655
|
const deadline = performance.now() + timeoutMs;
|
|
3635
3656
|
do {
|
|
3636
3657
|
const screen = captureScreen(name, AGENT_TUI_READY_LINES);
|
|
@@ -3647,6 +3668,10 @@ async function waitForGrokConfigurationResult(name, before, timeoutMs = 3_000) {
|
|
|
3647
3668
|
throw new AitermError(`Grokの設定変更に失敗しました: ${error}`, 2);
|
|
3648
3669
|
if (added.some((line) => /^(?:Switched to |✓?\s*Default model:)/.test(line)))
|
|
3649
3670
|
return;
|
|
3671
|
+
// Grok Build 1.0.3では成功通知が次の再描画で消えることがある。変更前には無かった
|
|
3672
|
+
// target model/effortが常駐footerへ現れた場合も、vendor自身の最終状態として受理する。
|
|
3673
|
+
if (!footerAlreadyMatched && grokFooterHasConfiguration(screen, model, effort))
|
|
3674
|
+
return;
|
|
3650
3675
|
await sleep(100);
|
|
3651
3676
|
} while (performance.now() < deadline);
|
|
3652
3677
|
throw new AitermError(`${agentLabel(loadAgentMetadata(name).kind)} の設定変更完了を確認できません`, 2);
|
|
@@ -3740,7 +3765,7 @@ export async function configureAgent(name, opts) {
|
|
|
3740
3765
|
: `/effort ${effort}`;
|
|
3741
3766
|
const before = captureScreen(name, AGENT_TUI_READY_LINES);
|
|
3742
3767
|
await sendAgentPromptText(name, command);
|
|
3743
|
-
await waitForGrokConfigurationResult(name, before);
|
|
3768
|
+
await waitForGrokConfigurationResult(name, before, model, effort);
|
|
3744
3769
|
return {
|
|
3745
3770
|
schema: "aiterm.agent-configure-result.v1",
|
|
3746
3771
|
session_id: name,
|
|
@@ -4214,8 +4239,13 @@ function agentEnvPrefix(meta, sid, envVars = []) {
|
|
|
4214
4239
|
if (meta.kind === "codex") {
|
|
4215
4240
|
return common.join(" ") + " ";
|
|
4216
4241
|
}
|
|
4242
|
+
// Windows では起動コマンドが WSL 内 bash で走るため、検証済み auth 正本の Windows ドライブパスを
|
|
4243
|
+
// bin/cwd と同じく /mnt/c/... 形へ変換して渡す。変換しないと WSL 側 grok が正本を開けず接続で停止する。
|
|
4244
|
+
const grokAuthForCmd = meta.grok_auth_path && isWin && isWindowsDrivePath(meta.grok_auth_path)
|
|
4245
|
+
? toWslPath(meta.grok_auth_path)
|
|
4246
|
+
: meta.grok_auth_path;
|
|
4217
4247
|
return [
|
|
4218
|
-
...(
|
|
4248
|
+
...(grokAuthForCmd ? [`GROK_AUTH_PATH=${shq(grokAuthForCmd)}`] : []),
|
|
4219
4249
|
"GROK_DISABLE_AUTOUPDATER=1",
|
|
4220
4250
|
...common,
|
|
4221
4251
|
].join(" ") + " ";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aiterm-mcp",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.3",
|
|
4
4
|
"mcpName": "io.github.kitepon/aiterm-mcp",
|
|
5
5
|
"description": "Persistent tmux terminal MCP for launching and driving Claude, Codex, Grok, or Composer from any MCP client, cross-vendor or same-vendor. Also runs durable PTY sessions for SSH, containers, and REPLs.",
|
|
6
6
|
"keywords": [
|