Files
hakorune/tools/codex-tmux-driver/tmux-codex-controller.js
Moe Charm 4e1b595796 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>
2025-08-28 12:09:09 +09:00

127 lines
3.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// tmux-codex-controller.js
// tmux経由でCodexを完全制御するコントローラー
const { spawn } = require('child_process');
const WebSocket = require('ws');
class TmuxCodexController {
constructor(sessionName = 'codex-8770', port = 8770) {
this.sessionName = sessionName;
this.port = port;
this.hookServerUrl = `ws://localhost:${port}`;
}
// tmuxセッションを作成してCodexを起動
async start() {
console.log('🚀 Starting Codex in tmux...');
// 既存セッションを削除
await this.exec('tmux', ['kill-session', '-t', this.sessionName]).catch(() => {});
// 新しいセッションでCodexを起動対話モード
const cmd = [
'new-session', '-d', '-s', this.sessionName,
`export CODEX_REAL_BIN=/home/tomoaki/.volta/bin/codex && ` +
`export CODEX_HOOK_SERVER=${this.hookServerUrl} && ` +
`export CODEX_HOOK_BANNER=false && ` +
`/home/tomoaki/.volta/bin/codex` // 直接codexを起動対話モード
];
await this.exec('tmux', cmd);
console.log(`✅ Codex started in tmux session: ${this.sessionName}`);
// 起動を待つ
await this.sleep(2000);
}
// tmux経由でキーを送信Enterも送れる
async sendKeys(text, enter = true) {
console.log(`📤 Sending: "${text}"${enter ? ' + Enter' : ''}`);
const args = ['send-keys', '-t', this.sessionName, text];
if (enter) {
args.push('Enter');
}
await this.exec('tmux', args);
}
// 画面内容をキャプチャ
async capture() {
const result = await this.exec('tmux', ['capture-pane', '-t', this.sessionName, '-p']);
return result.stdout;
}
// セッションにアタッチ(デバッグ用)
attach() {
console.log(`📺 Attaching to ${this.sessionName}...`);
spawn('tmux', ['attach', '-t', this.sessionName], { stdio: 'inherit' });
}
// セッションを終了
async stop() {
await this.exec('tmux', ['kill-session', '-t', this.sessionName]);
console.log('👋 Session stopped');
}
// ヘルパー関数
exec(command, args) {
return new Promise((resolve, reject) => {
const proc = spawn(command, args);
let stdout = '';
let stderr = '';
proc.stdout.on('data', (data) => stdout += data);
proc.stderr.on('data', (data) => stderr += data);
proc.on('close', (code) => {
if (code !== 0) {
reject(new Error(`${command} exited with code ${code}: ${stderr}`));
} else {
resolve({ stdout, stderr });
}
});
});
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// 使用例
async function demo() {
const controller = new TmuxCodexController();
try {
// Codexを起動
await controller.start();
// メッセージを送信自動でEnter
await controller.sendKeys('こんにちはNyashプロジェクトから自動挨拶だにゃ🐱');
await controller.sleep(1000);
// もう一つメッセージ
await controller.sendKeys('JIT開発の進捗はどう');
await controller.sleep(1000);
// 画面内容を確認
const screen = await controller.capture();
console.log('\n📺 Current screen:');
console.log(screen);
// デバッグ用にアタッチもできる
// controller.attach();
} catch (err) {
console.error('❌ Error:', err);
}
}
// モジュールとして使えるようにエクスポート
module.exports = TmuxCodexController;
// 直接実行したらデモを実行
if (require.main === module) {
demo();
}