AI協調開発研究ドキュメントの完成と Phase 10.9-β 進捗

【AI協調開発研究】
- AI二重化モデルの学術論文draft完成(workshop_paper_draft.md)
- 「隠れた危機」分析とbirthの原則哲学化
- TyEnv「唯一の真実」協調会話を保存・研究資料に統合
- papers管理構造の整備(wip/under-review/published分離)

【Phase 10.9-β HostCall進捗】
- JitConfigBox: relax_numeric フラグ追加(i64→f64コアーション制御)
- HostcallRegistryBox: 署名検証・白黒リスト・コアーション対応
- JitHostcallRegistryBox: Nyash側レジストリ操作API
- Lower統合: env直読 → jit::config::current() 参照に統一
- 数値緩和設定: NYASH_JIT_HOSTCALL_RELAX_NUMERIC/Config.set_flag

【検証サンプル拡充】
- math.sin/cos/abs/min/max 関数スタイル(examples/jit_math_function_style_*.nyash)
- 境界ケース: 署名不一致・コアーション許可・mutating拒否サンプル
- E2E実証: String.length→allow, Array.push→fallback, math関数の署名一致観測

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm
2025-08-28 12:09:09 +09:00
parent e54561e69f
commit 4e1b595796
133 changed files with 14202 additions and 622 deletions

View File

@ -0,0 +1,178 @@
#!/usr/bin/env node
// claude-hook-wrapper.js
// Claudeバイナリにフックをかけて入出力を横取りするラッパー
const { spawn } = require('child_process');
const path = require('path');
let WebSocket;
try {
WebSocket = require('ws');
} catch (e) {
console.error('FATAL: Cannot find module "ws"');
console.error('Hint: run "npm install" inside tools/codex-tmux-driver');
process.exit(1);
}
const fs = require('fs');
// 設定
const REAL_CLAUDE = process.env.CLAUDE_REAL_BIN || '/home/tomoaki/.volta/tools/image/node/22.16.0/bin/claude';
const HOOK_SERVER = process.env.CLAUDE_HOOK_SERVER || 'ws://localhost:8770';
const LOG_FILE = process.env.CLAUDE_LOG_FILE || '/tmp/claude-hook.log';
const ENABLE_HOOK = process.env.CLAUDE_HOOK_ENABLE !== 'false';
const USE_SCRIPT_PTY = process.env.CLAUDE_USE_SCRIPT_PTY !== 'false'; // デフォルトでPTY有効
// WebSocket接続
let ws = null;
if (ENABLE_HOOK) {
console.error(`[claude-hook] Attempting to connect to ${HOOK_SERVER}...`);
try {
ws = new WebSocket(HOOK_SERVER);
ws.on('open', () => {
log('hook-connect', { url: HOOK_SERVER });
console.error(`[claude-hook] ✅ Successfully connected to ${HOOK_SERVER}`);
});
ws.on('error', (e) => {
console.error(`[claude-hook] ❌ Connection error: ${e?.message || e}`);
});
ws.on('close', () => {
console.error(`[claude-hook] 🔌 Connection closed`);
});
} catch (e) {
console.error(`[claude-hook] ❌ Failed to create WebSocket: ${e}`);
}
}
// ログ関数
function log(type, data) {
const timestamp = new Date().toISOString();
const logEntry = { timestamp, type, data };
// ファイルログ
fs.appendFileSync(LOG_FILE, JSON.stringify(logEntry) + '\n');
// WebSocket送信
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(logEntry));
}
}
// Claudeプロセス起動
if (!fs.existsSync(REAL_CLAUDE)) {
console.error(`FATAL: REAL_CLAUDE not found: ${REAL_CLAUDE}`);
console.error('Set CLAUDE_REAL_BIN to the real Claude binary path.');
process.exit(1);
}
// 引数を渡してClaude起動
const userArgs = process.argv.slice(2);
// script(1) を使って擬似TTY経由で起動Claudeはインタラクティブモードに必要
function shEscape(s) { return `'${String(s).replace(/'/g, `'\\''`)}'`; }
let claudeProcess;
let usingPty = false;
try {
if (USE_SCRIPT_PTY) {
const cmdStr = [REAL_CLAUDE, ...userArgs].map(shEscape).join(' ');
// -q: quiet, -f: flush, -e: return child exit code, -c: command
claudeProcess = spawn('script', ['-qfec', cmdStr, '/dev/null'], {
stdio: ['pipe', 'pipe', 'pipe'],
env: process.env
});
usingPty = true;
log('start-info', { mode: 'pty(script)', cmd: cmdStr });
}
} catch (e) {
// フォールバック
console.error(`[claude-hook] PTY spawn failed: ${e.message}`);
}
if (!claudeProcess) {
claudeProcess = spawn(REAL_CLAUDE, userArgs, {
stdio: ['pipe', 'pipe', 'pipe'],
env: process.env
});
log('start-info', { mode: 'pipe', bin: REAL_CLAUDE, args: userArgs });
}
// 標準入力をClaudeへ
process.stdin.on('data', (chunk) => {
const input = chunk.toString();
log('input', input);
claudeProcess.stdin.write(chunk);
});
// 標準出力
let outputBuffer = '';
claudeProcess.stdout.on('data', (chunk) => {
const data = chunk.toString();
outputBuffer += data;
// 改行で区切って出力をログ
if (data.includes('\n')) {
log('output', outputBuffer);
outputBuffer = '';
}
process.stdout.write(chunk);
});
// エラー出力
claudeProcess.stderr.on('data', (chunk) => {
log('error', chunk.toString());
process.stderr.write(chunk);
});
// プロセス終了
claudeProcess.on('exit', (code, signal) => {
log('exit', { code, signal });
if (ws) {
try {
ws.send(JSON.stringify({
type: 'hook-event',
event: 'claude-exit',
data: { code, signal }
}));
} catch {}
ws.close();
}
process.exit(typeof code === 'number' ? code : 0);
});
// シグナルハンドリング
process.on('SIGINT', () => {
claudeProcess.kill('SIGINT');
});
process.on('SIGTERM', () => {
claudeProcess.kill('SIGTERM');
});
// WebSocketからのメッセージ受信
if (ws) {
ws.on('message', (data) => {
try {
const cmd = JSON.parse(data.toString());
if (cmd.type === 'inject-input') {
// Claudeに入力を注入
log('inject', cmd.data);
claudeProcess.stdin.write(cmd.data + '\n');
}
} catch (e) {
console.error(`[claude-hook] ❌ Error parsing message: ${e}`);
}
});
}
// 起動ログ
log('start', {
args: userArgs,
pid: process.pid,
hookEnabled: ENABLE_HOOK,
usingPty
});
console.error(`[claude-hook] active (pty=${usingPty ? 'on' : 'off'}) REAL_CLAUDE=${REAL_CLAUDE}`);