mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-19 08:14:35 -07:00
7bc0515c7c
- Add gce-startup.sh: self-contained VM startup (install, build, configure, run) - Add start-forever.js: dual-process launcher for local development - Add npm scripts: start:forever, start:bridge - Bind A2A listener to 0.0.0.0 (was 127.0.0.1) for remote bridge access - Pre-configure all headless settings to bypass interactive dialogs - Use .env file + script pseudo-TTY for systemd service
99 lines
2.3 KiB
JavaScript
99 lines
2.3 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* @license
|
|
* Copyright 2026 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import { spawn } from 'node:child_process';
|
|
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
import { join, dirname } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const repoRoot = join(__dirname, '..');
|
|
|
|
const A2A_PORT = process.env.A2A_PORT || '3100';
|
|
const BRIDGE_PORT = process.env.BRIDGE_PORT || '8081';
|
|
|
|
// Ensure .gemini/GEMINI.md exists to skip onboarding dialog
|
|
const geminiDir = join(process.cwd(), '.gemini');
|
|
const geminiMd = join(geminiDir, 'GEMINI.md');
|
|
if (!existsSync(geminiMd)) {
|
|
mkdirSync(geminiDir, { recursive: true });
|
|
writeFileSync(
|
|
geminiMd,
|
|
`---
|
|
sisyphus:
|
|
enabled: true
|
|
idleTimeout: 30
|
|
prompt: "continue with the next task"
|
|
---
|
|
|
|
# Mission
|
|
You are a forever-running autonomous agent.
|
|
Process incoming tasks and answer questions.
|
|
`,
|
|
);
|
|
console.log(`Created ${geminiMd} (skip onboarding)`);
|
|
}
|
|
|
|
console.log('=== Gemini CLI Forever Agent ===');
|
|
console.log(`Agent listener: localhost:${A2A_PORT}`);
|
|
console.log(`Chat bridge: 0.0.0.0:${BRIDGE_PORT}`);
|
|
console.log('');
|
|
|
|
// Start the chat bridge
|
|
const bridgePath = join(
|
|
repoRoot,
|
|
'packages/a2a-server/dist/src/chat-bridge/bridge.js',
|
|
);
|
|
const bridge = spawn('node', [bridgePath], {
|
|
env: {
|
|
...process.env,
|
|
A2A_PORT,
|
|
BRIDGE_PORT,
|
|
A2A_URL: `http://127.0.0.1:${A2A_PORT}`,
|
|
},
|
|
stdio: 'inherit',
|
|
});
|
|
|
|
bridge.on('error', (err) => {
|
|
console.error(`Bridge failed to start: ${err.message}`);
|
|
});
|
|
|
|
// Start the forever agent
|
|
const cliPath = join(repoRoot, 'packages/cli/dist/index.js');
|
|
const agent = spawn(
|
|
'node',
|
|
[cliPath, '--forever', '--a2a-port', A2A_PORT, '--yolo'],
|
|
{
|
|
env: { ...process.env, A2A_PORT },
|
|
stdio: 'inherit',
|
|
},
|
|
);
|
|
|
|
agent.on('error', (err) => {
|
|
console.error(`Agent failed to start: ${err.message}`);
|
|
});
|
|
|
|
// Cleanup on exit
|
|
function cleanup() {
|
|
console.log('\nShutting down...');
|
|
bridge.kill();
|
|
agent.kill();
|
|
}
|
|
|
|
process.on('SIGINT', cleanup);
|
|
process.on('SIGTERM', cleanup);
|
|
|
|
agent.on('exit', (code) => {
|
|
console.log(`Agent exited with code ${code}`);
|
|
bridge.kill();
|
|
process.exit(code || 0);
|
|
});
|
|
|
|
bridge.on('exit', (code) => {
|
|
console.log(`Bridge exited with code ${code}`);
|
|
});
|