Phase 1 (STEP 1634) recommendation: 「detect / pinout / invoke = 実装可、 verify tool は defer 妥当 (spec 化できない、 Phase 2.5 で 別 arc 起動 提案)、 pin 3+4 は caller 責任 で config 事前準備 (connector が config 変換責任 を 負わない decoupling)」
Phase 2 done: 上記 recommendation そのまま 3 tool 実装、 verify defer。 副作用は invoke({ mode: 'execute' }) のみ (subprocess spawn)、 mode は required で default なし = 呼出側が 毎回 明示的に 選択 する 強制 (STEP 1345 SafetyGate + STEP 1625 陰性対照 と 同族の safety discipline)。
| File | 役割 | Side effect |
|---|---|---|
src/agent-connector/types.ts | AgentName / Pin / PinoutResult / DetectResult / InvokeOptions / InvokeResult 型定義 (全 readonly) | なし |
src/agent-connector/pins-data.ts | Phase 1 (STEP 1634) の 6 pin data を PINS_PHASE1 const で encode + PHASE1_HONEST_SCOPE | なし (static data) |
src/agent-connector/detect.ts | detect(agent) + detectAll() — execFile('claude', ['--version']) で CLI 検出、 semver-ish regex で version 抽出、 where/which で CLI path 抽出 | subprocess spawn (read-only: --version + which 呼出のみ) |
src/agent-connector/pinout.ts | pinout() + pinById(id) + pinsByVerdict(v) + pinsWithInformationLoss() — pins-data.ts を programmatic API 化 | なし (pure function) |
src/agent-connector/invoke.ts | invoke(agent, opts) — dryRun mode で command argv 返却、 execute mode で subprocess spawn + timeout + stdout/stderr/exitCode 返却 | subprocess spawn (execute mode のみ、 dryRun mode は なし) |
src/agent-connector/index.ts | Public re-export | なし |
import { detect, detectAll } from './agent-connector/index.js';
const d = await detect('claude');
// {
// agent: 'claude',
// isAvailable: true,
// cliPath: 'C:\\Users\\user\\.local\\bin\\claude.exe',
// version: '2.1.251',
// rawVersionOutput: '2.1.251 (Claude Code)',
// detectedAt: '2026-09-01T00:47:...Z'
// }
const all = await detectAll();
// { claude: {...isAvailable:true}, codex: {...isAvailable:false, error:'...'} }
import { pinout, pinById, pinsByVerdict } from './agent-connector/index.js';
const p = pinout();
// {
// pins: [ ...6 pin ],
// summary: { total: 6, pass: 3, partial: 1, fail: 2, falsificationRate: 0.333 },
// generatedAt: '...',
// phase1Ref: 'https://rei-aios.pages.dev/tools/step-1634-agent-pinout-phase1/',
// honestScope: [ ...6 items ]
// }
const mcpPin = pinById('mcp_config');
// { id: 'mcp_config', verdict: 'fail', informationLoss: { direction: 'bidirectional', ... } }
const failPins = pinsByVerdict('fail'); // [mcp_config, permission]
import { invoke } from './agent-connector/index.js';
// dryRun mode = argv を 返すのみ、 spawn しない
const dry = await invoke('claude', {
mode: 'dryRun',
prompt: 'summarize this',
outputFormat: 'stream-json',
extraArgs: ['--verbose'],
});
// {
// agent: 'claude', mode: 'dryRun',
// command: ['claude', '-p', '--output-format', 'stream-json', '--verbose', 'summarize this']
// }
// execute mode = 実 CLI spawn (billable + side-effect)
const exec = await invoke('claude', {
mode: 'execute', // ★ REQUIRED、 default なし
prompt: 'ping',
timeoutMs: 30_000,
});
// { agent, mode: 'execute', command, stdout, stderr, exitCode, elapsedMs, timedOut }
InvokeOptions.mode: 'dryRun' | 'execute' は 型レベルで required、 TypeScript の 型検査で 呼出側 が 毎回 明示 する ことを 強制。 「うっかり execute」 を 型で 防ぐ。extraArgs で provider 別 flag を 直接 渡す 前提。 Phase 1 「decoupling」 principle の 実装体現。STEP1639_RUN_EXECUTE=1 env var で のみ execute mode test 実行、 default では skip。 dryRun で argv 構築の 正しさ 十分検証、 execute は billable + side-effect で CI 化避け。spawn(cmd, args, { shell: false }) = shell interpolation なし = injection 防止。| Section | test 内容 | 件数 |
|---|---|---|
| 1. detect | claude available + codex not-installed + detectAll 挙動 | 10 assert |
| 2. pinout | 6 pin 返却 + summary (pass 3 / partial 1 / fail 2 / falsification rate 2/6) | 14 assert |
| 3. pinout helpers | pinById / pinsByVerdict / pinsWithInformationLoss / unknown 挙動 | 10 assert |
| 4. invoke dryRun | argv 構築正確、 claude -p / codex exec / --output-format / extraArgs passthrough | 13 assert |
| 5. invoke execute | opt-in mode の skip 動作 (STEP1639_RUN_EXECUTE=1 で 実行) | 0 assert (skip 状態確認のみ) |
| 6. error handling | codex execute → ENOENT (graceful error return、 throw しない) | 3 assert |
| 7. pin data invariants | 6 pin 全て refutation ≥3 + source valid + fail pin 全て informationLoss あり | 38 assert |
Total: 88 assert PASS / 0 fail。 実行: npm run test:step1639。
=== Section 1: detect === claude: v2.1.251 at C:\Users\user\.local\bin\claude.exe codex: not installed on this PC (expected on Windows dev box)
Phase 1 環境非対称性 (Codex CLI 未 install) を connector が 正しく handle: detect('codex') は isAvailable=false + error message + throw なし、 invoke('codex', {mode:'execute'}) は ENOENT を error field に 収める。
Phase 2 では Phase 1 の pin 4 field を そのまま encode:
pinsWithInformationLoss() で 上記 2 pin を 一覧取得可能。 caller は これを 見て 「直接 pass-through しない、 provider 別 config を 事前準備」 の 判断が できる。
Phase 1 で verify tool の spec 化不能 と 判明:
Phase 2.5 別 arc で defer、 前提条件: (a) 両 CLI の exit code semantics 実測 (b) sandbox / permission 意味論 の cross-provider 共通 subset 定義 (c) 「verify pass」 の 定義自体を rei stack の どの verdict vocabulary (TRUE / NEITHER / N/A) に 落とすかの 判断。
src/mcp/ への tool 追加 は 別 STEP)。 rei-aios MCP に register する なら invoke の execute mode は SafetyGate 越し ラッピング 必要。src/mcp/agent-connector-mcp.ts で detect / pinout tool を expose (invoke は SafetyGate 越し ラッピング 必要、 or defer)。