feat(daemon): add stateful headless daemon mode#20700
feat(daemon): add stateful headless daemon mode#20700h30s wants to merge 6 commits intogoogle-gemini:mainfrom
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the Gemini CLI by introducing a new daemon mode. This mode allows the CLI to operate as a persistent background service, eliminating the overhead of repeated TUI startups and enabling continuous, stateful interactions. Users can now manage the daemon and interact with it via a client, leveraging named sessions to maintain context and current working directory across multiple prompts, which is particularly beneficial for automation workflows. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a stateful headless daemon mode for the Gemini CLI. While a significant feature, it presents critical security vulnerabilities, including unrestricted Unix socket permissions that could lead to session hijacking, and blind trust in the client's Current Working Directory (CWD), enabling potential path traversal for unauthorized information disclosure. These path traversal issues are reinforced by existing guidelines on sanitizing user-provided paths and internal validation in utility functions. Additionally, the implementation has robustness issues such as race conditions during daemon shutdown and incorrect handling of streaming data on the client side. Addressing these concerns is crucial for the security and reliability of this new daemon feature.
|
Can you attach a screencast showing what you've implemented and how it works? |
99dc207 to
81ce1b3
Compare
|
@gsquared94 Here's a screencast of the daemon mode in action: Screencast.From.2026-03-06.21-09-00.mp4 |
|
Apologies for the delay in reviewing, I ran an AI review and it pointed the following issues with this PR SummaryThis PR adds a persistent background daemon mode for the Gemini CLI, communicating via Unix domain sockets. While the feature concept is solid and addresses a real user need (avoiding TUI startup cost for scripting/automation), the implementation has critical security vulnerabilities, several architectural concerns, and a number of coding pattern issues that must be addressed before merge. 🔴 Critical — Security Issues1. Unix Socket Has No Authentication — Any Local User Can Execute Arbitrary AI-Powered ActionsCaution Severity: Critical — Remote Code Execution by any local user daemonServer.ts applies server.listen(socketPath, () => {
fs.chmodSync(socketPath, 0o600); // TOCTOU: socket is world-accessible between listen() and chmod()
});Problems:
Recommendation:
2.
|
| # | Severity | Category | Issue |
|---|---|---|---|
| 1 | 🔴 Critical | Security | No socket authentication — local process RCE |
| 2 | 🔴 Critical | Security | forceInteractive bypasses headless safety |
| 3 | 🔴 Critical | Security | CWD symlink traversal bypass |
| 4 | 🟠 Major | Security | Fragile session name sanitization |
| 5 | 🟠 Major | Architecture | Module-level mutable global state |
| 6 | 🟠 Major | Architecture | Broken concurrent request handling |
| 7 | 🟠 Major | Architecture | No session TTL / resource cleanup |
| 8 | 🟠 Major | Architecture | Duplicated turn loop |
| 9 | 🟡 Moderate | Pattern | process.exit() from library code |
| 10 | 🟡 Moderate | Pattern | Unsafe type casting of IPC messages |
| 11 | 🟡 Moderate | Security | Non-cryptographic prompt_id |
| 12 | 🟡 Moderate | Security | Error message information disclosure |
| 13 | 🟡 Moderate | UX | Ambiguous flag combinations |
| 14 | 🟡 Moderate | Quality | Minimal test coverage |
| 15 | 🔵 Minor | Pattern | Hardcoded session limit |
| 16 | 🔵 Minor | Pattern | Inconsistent newlines |
| 17 | 🔵 Minor | UX | Non-configurable socket path |
| 18 | 🔵 Minor | Bug | Missing socket.end() after errors |
| 19 | 🔵 Minor | Ops | No PID file |
Overall Recommendation: This PR should not be merged in its current state. The socket authentication gap (Issue No. 1) combined with forceInteractive (Issue No. 2) creates a scenario where any local process can instruct the AI to execute arbitrary shell commands with the daemon owner's privileges and without any user confirmation gate. These are the minimum blockers. Issues 3, 5, 6, 7, and 8 should also be addressed before merge.
|
@gsquared94 PTAL |
Please fix the CI failures. |
Done! |
Summary
This PR introduces a stateful headless Daemon Mode for the Gemini CLI, allowing seamless, continuous CLI context and automation without the interactive TUI startup penalty.
Details
Introduces
--daemon,--daemon-status,--daemon-stopto manage the background server.Introduces
--client,--session,--close,--verboseto establish communication with the daemon via Unix sockets. Context and CWD are retained per named session.Related Issues
Fixes #15338
How to Validate
npm run start -- --daemonnpm run start -- --client --session test "what is 2+2"npm run start -- --client --session test "multiply that by 4"Pre-Merge Checklist
npm run
npx
Docker
Podman
Seatbelt