#!/usr/bin/env node 'use strict'; const readline = require('readline'); const { WORKSPACE, WORKSPACE_NAME, PROMPT, COLOR_ENABLED, RESET } = require('./lib/env'); const { loadSystemPrompt } = require('./lib/system_prompt'); const { createState } = require('./lib/state'); const { handleCommand } = require('./lib/commands'); const { createAssistantSimulator } = require('./lib/assistant_sim'); const { openCommandMenu } = require('./lib/ui/command_menu'); const SHOW_REASONING = process.env.EA_REASONING !== '0'; const SYSTEM_PROMPT = loadSystemPrompt(); void SYSTEM_PROMPT; // demo only const state = createState(); const simulateAssistantReply = createAssistantSimulator(state, { showReasoning: SHOW_REASONING, }); console.log(''); console.log('eagent demo'); console.log(`model: kimi | allow: full_access | cwd: ${WORKSPACE_NAME}`); console.log(''); let rl = null; let commandMenuActive = false; let closingExplicit = false; let menuSearchTerm = ''; let menuJustClosedAt = 0; let menuInjectedCommand = null; readline.emitKeypressEvents(process.stdin); if (process.stdin.isTTY) process.stdin.setRawMode(true); initReadline(); process.stdin.on('keypress', (str) => { if (commandMenuActive) return; if (str === '/' && (rl.line === '' || rl.line === '/')) { commandMenuActive = true; menuSearchTerm = ''; void openCommandMenu({ rl, prompt: PROMPT, pageSize: 6, colorEnabled: COLOR_ENABLED, resetAnsi: RESET, onInput: (input) => { menuSearchTerm = input || ''; }, }) .then((result) => { if (result && result.chosen) { menuInjectedCommand = result.chosen; menuSearchTerm = ''; } }) .finally(() => { commandMenuActive = false; menuJustClosedAt = Date.now(); drainStdin(); rl.line = ''; rl.cursor = 0; rl.prompt(); if (menuInjectedCommand) { const injected = menuInjectedCommand; menuInjectedCommand = null; setImmediate(() => injectLine(injected)); } }); } }); function initReadline() { if (rl) { try { rl.removeAllListeners(); } catch (_) {} } rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: true, }); process.stdin.resume(); rl.setPrompt(PROMPT); rl.prompt(); rl.on('line', async (line) => { if (commandMenuActive) { rl.prompt(); return; } const input = line.trim(); if (menuJustClosedAt) { const tooOld = Date.now() - menuJustClosedAt > 800; const normalizedMenu = String(menuSearchTerm).trim().replace(/^\/+/, ''); const normalizedInput = input.replace(/^\/+/, ''); if (!tooOld && (!normalizedMenu ? input === '' : normalizedInput === normalizedMenu)) { menuJustClosedAt = 0; rl.prompt(); return; } menuJustClosedAt = 0; } if (!input) { rl.prompt(); return; } if (input.startsWith('/')) { await handleCommand(input, state, { rl, workspacePath: WORKSPACE, markClosing: () => { closingExplicit = true; }, }); rl.prompt(); return; } console.log(`用户:${line}`); console.log(''); await simulateAssistantReply(input); rl.prompt(); }); rl.on('close', () => { process.stdout.write('\n'); if (closingExplicit) { process.exit(0); } closingExplicit = false; initReadline(); }); } function drainStdin() { if (!process.stdin.isTTY) return; process.stdin.pause(); // Drain any buffered input from the command menu. while (process.stdin.read() !== null) {} process.stdin.resume(); } function injectLine(text) { if (!rl) return; rl.write(text); rl.write('\n'); }