gemini-deep-research 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. gemini_deep_research-0.1.0/.gitignore +86 -0
  2. gemini_deep_research-0.1.0/LICENSE +21 -0
  3. gemini_deep_research-0.1.0/PKG-INFO +172 -0
  4. gemini_deep_research-0.1.0/README.md +130 -0
  5. gemini_deep_research-0.1.0/pyproject.toml +173 -0
  6. gemini_deep_research-0.1.0/src/gdr/__init__.py +7 -0
  7. gemini_deep_research-0.1.0/src/gdr/__main__.py +13 -0
  8. gemini_deep_research-0.1.0/src/gdr/cli.py +76 -0
  9. gemini_deep_research-0.1.0/src/gdr/commands/__init__.py +5 -0
  10. gemini_deep_research-0.1.0/src/gdr/commands/_common.py +147 -0
  11. gemini_deep_research-0.1.0/src/gdr/commands/cancel.py +66 -0
  12. gemini_deep_research-0.1.0/src/gdr/commands/config.py +338 -0
  13. gemini_deep_research-0.1.0/src/gdr/commands/doctor.py +241 -0
  14. gemini_deep_research-0.1.0/src/gdr/commands/follow_up.py +78 -0
  15. gemini_deep_research-0.1.0/src/gdr/commands/ls.py +150 -0
  16. gemini_deep_research-0.1.0/src/gdr/commands/plan.py +189 -0
  17. gemini_deep_research-0.1.0/src/gdr/commands/research.py +716 -0
  18. gemini_deep_research-0.1.0/src/gdr/commands/resume.py +169 -0
  19. gemini_deep_research-0.1.0/src/gdr/commands/show.py +139 -0
  20. gemini_deep_research-0.1.0/src/gdr/commands/status.py +106 -0
  21. gemini_deep_research-0.1.0/src/gdr/config.py +226 -0
  22. gemini_deep_research-0.1.0/src/gdr/constants.py +56 -0
  23. gemini_deep_research-0.1.0/src/gdr/core/__init__.py +1 -0
  24. gemini_deep_research-0.1.0/src/gdr/core/client.py +112 -0
  25. gemini_deep_research-0.1.0/src/gdr/core/inputs.py +236 -0
  26. gemini_deep_research-0.1.0/src/gdr/core/models.py +219 -0
  27. gemini_deep_research-0.1.0/src/gdr/core/persistence.py +184 -0
  28. gemini_deep_research-0.1.0/src/gdr/core/planning.py +243 -0
  29. gemini_deep_research-0.1.0/src/gdr/core/rendering.py +420 -0
  30. gemini_deep_research-0.1.0/src/gdr/core/requests.py +120 -0
  31. gemini_deep_research-0.1.0/src/gdr/core/security.py +262 -0
  32. gemini_deep_research-0.1.0/src/gdr/core/streaming.py +372 -0
  33. gemini_deep_research-0.1.0/src/gdr/errors.py +59 -0
  34. gemini_deep_research-0.1.0/src/gdr/ui/__init__.py +1 -0
  35. gemini_deep_research-0.1.0/src/gdr/ui/live.py +218 -0
  36. gemini_deep_research-0.1.0/src/gdr/ui/progress.py +169 -0
  37. gemini_deep_research-0.1.0/tests/__init__.py +0 -0
  38. gemini_deep_research-0.1.0/tests/conftest.py +8 -0
  39. gemini_deep_research-0.1.0/tests/fixtures/streams/disconnect_mid_text.jsonl +7 -0
  40. gemini_deep_research-0.1.0/tests/fixtures/streams/happy_path.jsonl +10 -0
  41. gemini_deep_research-0.1.0/tests/fixtures/streams/mid_stream_error.jsonl +4 -0
  42. gemini_deep_research-0.1.0/tests/fixtures/streams/out_of_order.jsonl +6 -0
  43. gemini_deep_research-0.1.0/tests/fixtures/streams/thought_image_text.jsonl +16 -0
  44. gemini_deep_research-0.1.0/tests/unit/__init__.py +0 -0
  45. gemini_deep_research-0.1.0/tests/unit/test_cancel_command.py +89 -0
  46. gemini_deep_research-0.1.0/tests/unit/test_cli.py +36 -0
  47. gemini_deep_research-0.1.0/tests/unit/test_client.py +77 -0
  48. gemini_deep_research-0.1.0/tests/unit/test_commands_common.py +77 -0
  49. gemini_deep_research-0.1.0/tests/unit/test_config.py +188 -0
  50. gemini_deep_research-0.1.0/tests/unit/test_config_command.py +200 -0
  51. gemini_deep_research-0.1.0/tests/unit/test_doctor_command.py +170 -0
  52. gemini_deep_research-0.1.0/tests/unit/test_follow_up_command.py +131 -0
  53. gemini_deep_research-0.1.0/tests/unit/test_inputs.py +300 -0
  54. gemini_deep_research-0.1.0/tests/unit/test_live.py +203 -0
  55. gemini_deep_research-0.1.0/tests/unit/test_ls_command.py +137 -0
  56. gemini_deep_research-0.1.0/tests/unit/test_models.py +174 -0
  57. gemini_deep_research-0.1.0/tests/unit/test_persistence.py +171 -0
  58. gemini_deep_research-0.1.0/tests/unit/test_plan_command.py +274 -0
  59. gemini_deep_research-0.1.0/tests/unit/test_planning.py +248 -0
  60. gemini_deep_research-0.1.0/tests/unit/test_progress.py +146 -0
  61. gemini_deep_research-0.1.0/tests/unit/test_rendering.py +415 -0
  62. gemini_deep_research-0.1.0/tests/unit/test_requests.py +208 -0
  63. gemini_deep_research-0.1.0/tests/unit/test_research_command.py +1034 -0
  64. gemini_deep_research-0.1.0/tests/unit/test_resume_command.py +189 -0
  65. gemini_deep_research-0.1.0/tests/unit/test_security.py +226 -0
  66. gemini_deep_research-0.1.0/tests/unit/test_show_command.py +145 -0
  67. gemini_deep_research-0.1.0/tests/unit/test_status_command.py +130 -0
  68. gemini_deep_research-0.1.0/tests/unit/test_streaming.py +217 -0
@@ -0,0 +1,86 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+
7
+ # Distribution / packaging
8
+ .Python
9
+ build/
10
+ dist/
11
+ *.egg-info/
12
+ *.egg
13
+ .eggs/
14
+ wheels/
15
+ share/python-wheels/
16
+ MANIFEST
17
+
18
+ # Virtual environments
19
+ venv/
20
+ .venv/
21
+ env/
22
+ ENV/
23
+ .env
24
+ .env.*
25
+ !.env.example
26
+
27
+ # PyInstaller
28
+ *.manifest
29
+ *.spec
30
+
31
+ # Installer logs
32
+ pip-log.txt
33
+ pip-delete-this-directory.txt
34
+
35
+ # Unit test / coverage
36
+ htmlcov/
37
+ .tox/
38
+ .nox/
39
+ .coverage
40
+ .coverage.*
41
+ .cache
42
+ nosetests.xml
43
+ coverage.xml
44
+ *.cover
45
+ *.py,cover
46
+ .hypothesis/
47
+ .pytest_cache/
48
+
49
+ # Ruff / mypy caches
50
+ .mypy_cache/
51
+ .ruff_cache/
52
+ .dmypy.json
53
+ dmypy.json
54
+
55
+ # uv (note: uv.lock is committed for reproducibility)
56
+ .uv/
57
+
58
+ # Jupyter / IPython
59
+ .ipynb_checkpoints
60
+ profile_default/
61
+ ipython_config.py
62
+
63
+ # Editors / IDEs
64
+ .vscode/
65
+ .idea/
66
+ *.swp
67
+ *.swo
68
+ *.sublime-workspace
69
+ *.sublime-project
70
+
71
+ # OS
72
+ .DS_Store
73
+ Thumbs.db
74
+ Desktop.ini
75
+
76
+ # Claude Code local state
77
+ .claude/
78
+
79
+ # Project-local scratch
80
+ scratch/
81
+ tmp/
82
+ *.log
83
+
84
+ # Local config accidentally copied into repo
85
+ .gdr/
86
+ gdr-reports/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 gdr contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,172 @@
1
+ Metadata-Version: 2.4
2
+ Name: gemini-deep-research
3
+ Version: 0.1.0
4
+ Summary: Unofficial terminal-first client for Google's Gemini Deep Research and Deep Research Max agents (not affiliated with Google).
5
+ Project-URL: Homepage, https://github.com/johnswyou/gemini-deep-research
6
+ Project-URL: Repository, https://github.com/johnswyou/gemini-deep-research
7
+ Project-URL: Issues, https://github.com/johnswyou/gemini-deep-research/issues
8
+ Author: gdr contributors
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: agent,ai,cli,deep-research,gemini,google,llm,research
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
25
+ Classifier: Topic :: Software Development
26
+ Classifier: Topic :: Utilities
27
+ Requires-Python: >=3.10
28
+ Requires-Dist: google-genai>=1.55.0
29
+ Requires-Dist: httpx>=0.27.0
30
+ Requires-Dist: platformdirs>=4.2.0
31
+ Requires-Dist: pydantic>=2.7.0
32
+ Requires-Dist: rich>=13.7.0
33
+ Requires-Dist: tomli>=2.0.0; python_version < '3.11'
34
+ Requires-Dist: typer>=0.12.0
35
+ Provides-Extra: dev
36
+ Requires-Dist: mypy>=1.10; extra == 'dev'
37
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
38
+ Requires-Dist: pytest-mock>=3.14; extra == 'dev'
39
+ Requires-Dist: pytest>=8.0; extra == 'dev'
40
+ Requires-Dist: ruff>=0.6; extra == 'dev'
41
+ Description-Content-Type: text/markdown
42
+
43
+ # gdr — Gemini Deep Research CLI
44
+
45
+ > **Status:** Alpha. APIs and commands may change before v1.0.
46
+
47
+ > **Disclaimer:** Unofficial, community-built CLI. Not affiliated with, endorsed by, or sponsored by Google LLC. "Gemini" and "Deep Research" are trademarks of Google LLC, used here nominatively to describe the APIs this tool interacts with.
48
+
49
+ A terminal-first client for Google's **Gemini Deep Research** and **Deep Research Max** agents. Run long-horizon research tasks from your shell and get cleanly organized artifacts — markdown reports, charts, citations, and a full transcript — saved to disk.
50
+
51
+ `gdr` is a thin, honest wrapper over the [`google-genai`](https://github.com/googleapis/python-genai) SDK. The SDK does the work; `gdr` adds ergonomics: streaming UI, safe config/secret management, local history, a collaborative planning flow, resume-after-disconnect, and safe MCP wiring.
52
+
53
+ ## Why
54
+
55
+ Deep Research tasks run for 5–60 minutes. Running them from a web UI means keeping a browser tab open. `gdr` decouples the task from your terminal session: start a research run, live-stream thought summaries, walk away, resume later by ID, and get artifacts on disk that fit into any downstream pipeline.
56
+
57
+ ## Install
58
+
59
+ ```bash
60
+ # With pipx (recommended — isolated install)
61
+ pipx install gemini-deep-research
62
+
63
+ # With uv tool
64
+ uv tool install gemini-deep-research
65
+
66
+ # From source (dev)
67
+ git clone https://github.com/johnswyou/gemini-deep-research
68
+ cd gemini-deep-research
69
+ uv sync --extra dev
70
+ uv run gdr --help
71
+ ```
72
+
73
+ ## Quickstart
74
+
75
+ ```bash
76
+ export GEMINI_API_KEY=... # get one at https://aistudio.google.com/apikey
77
+
78
+ # One-line research with the fast agent
79
+ gdr research "Latest trends in RISC-V adoption"
80
+
81
+ # Maximum-quality agent for due diligence
82
+ gdr research --max "Competitive landscape of EV batteries"
83
+
84
+ # Review and refine the agent's plan before it spends tokens
85
+ gdr research --plan "Impact of AI on semiconductor supply chain"
86
+
87
+ # Ground in your own documents
88
+ gdr research --file ~/Downloads/10k.pdf \
89
+ "Compare risk factors vs our 2024 filing"
90
+ ```
91
+
92
+ Each run produces a timestamped directory under `~/gdr-reports/` containing `report.md`, `sources.json`, `transcript.json`, `metadata.json`, and any generated images.
93
+
94
+ ## Command reference
95
+
96
+ | Command | Purpose |
97
+ | --- | --- |
98
+ | `gdr research <query>` | Run a research task (fast agent by default, `--max` for Max) |
99
+ | `gdr research --plan <query>` | Collaborative planning — review and refine the plan before execution |
100
+ | `gdr status <id>` | Check the status of a running or completed task |
101
+ | `gdr resume <id>` | Re-attach to a running task after Ctrl+C or disconnect |
102
+ | `gdr follow-up <id> <question>` | Ask a follow-up using the previous interaction as context |
103
+ | `gdr plan refine <id> <feedback>` | Iterate on a pending plan without executing |
104
+ | `gdr plan approve <id>` | Approve and execute a pending plan |
105
+ | `gdr cancel <id>` | Cancel a running task |
106
+ | `gdr ls` | List recent interactions |
107
+ | `gdr show <id>` | Render a saved artifact |
108
+ | `gdr config {path,get,set,edit}` | Manage the TOML config file |
109
+ | `gdr doctor [--fix]` | Diagnose and optionally repair your setup |
110
+
111
+ Run `gdr --help` or `gdr <command> --help` for full flag reference.
112
+
113
+ See [`docs/USAGE.md`](docs/USAGE.md) for long-form command documentation,
114
+ [`docs/MCP.md`](docs/MCP.md) for MCP server integration, and
115
+ [`docs/TROUBLESHOOTING.md`](docs/TROUBLESHOOTING.md) for common failure
116
+ modes and recovery recipes. Runnable demos live in [`examples/`](examples/).
117
+
118
+ ## Configuration
119
+
120
+ Config lives at `~/.config/gdr/config.toml`. Run `gdr doctor --fix` to scaffold it. Environment variables referenced with `env:VAR_NAME` are expanded at load time so secrets stay out of the file.
121
+
122
+ ```toml
123
+ api_key = "env:GEMINI_API_KEY"
124
+ default_agent = "deep-research-preview-04-2026"
125
+ output_dir = "~/gdr-reports"
126
+ auto_open = true
127
+ confirm_max = true # prompt before running the Max agent
128
+ default_tools = ["google_search", "url_context", "code_execution"]
129
+ thinking_summaries = "auto" # "auto" or "none"
130
+ visualization = "auto" # "auto" or "off"
131
+ safe_untrusted = true # auto-strip dangerous tools when --file/--url is used
132
+
133
+ [mcp_servers.factset]
134
+ url = "https://mcp.factset.com"
135
+ headers.Authorization = "Bearer env:FACTSET_TOKEN"
136
+ ```
137
+
138
+ ## Safety
139
+
140
+ Deep Research agents can read files and the public web. `gdr` ships with:
141
+
142
+ - **Redaction** of MCP auth headers and API keys from `transcript.json`.
143
+ - **Path confinement**: all artifacts land under the configured `output_dir`; slug names are sanitized.
144
+ - **Header validation** for MCP servers (no CRLF injection, no reserved names).
145
+ - **`--untrusted-input`** flag that disables `code_execution` and `mcp_server` tools for a run — use when grounding in attacker-controlled files or URLs.
146
+
147
+ See [`docs/MCP.md`](docs/MCP.md) for the MCP security model and
148
+ [`docs/TROUBLESHOOTING.md`](docs/TROUBLESHOOTING.md) for the
149
+ `--untrusted-input` recipe.
150
+
151
+ ## Development
152
+
153
+ ```bash
154
+ uv sync --extra dev
155
+ uv run ruff check .
156
+ uv run mypy src
157
+ uv run pytest -q
158
+ ```
159
+
160
+ ## Roadmap
161
+
162
+ Deferred to v1.1: HTML/PDF export, cost estimation, SQLite history
163
+ backend, interactive setup wizard. See `docs/USAGE.md` for the
164
+ currently-shipping surface.
165
+
166
+ ## License
167
+
168
+ MIT. See [`LICENSE`](LICENSE).
169
+
170
+ ## Credits
171
+
172
+ Built on [Google's Gemini Interactions API](https://ai.google.dev/gemini-api/docs/interactions) and the [`google-genai`](https://github.com/googleapis/python-genai) Python SDK.
@@ -0,0 +1,130 @@
1
+ # gdr — Gemini Deep Research CLI
2
+
3
+ > **Status:** Alpha. APIs and commands may change before v1.0.
4
+
5
+ > **Disclaimer:** Unofficial, community-built CLI. Not affiliated with, endorsed by, or sponsored by Google LLC. "Gemini" and "Deep Research" are trademarks of Google LLC, used here nominatively to describe the APIs this tool interacts with.
6
+
7
+ A terminal-first client for Google's **Gemini Deep Research** and **Deep Research Max** agents. Run long-horizon research tasks from your shell and get cleanly organized artifacts — markdown reports, charts, citations, and a full transcript — saved to disk.
8
+
9
+ `gdr` is a thin, honest wrapper over the [`google-genai`](https://github.com/googleapis/python-genai) SDK. The SDK does the work; `gdr` adds ergonomics: streaming UI, safe config/secret management, local history, a collaborative planning flow, resume-after-disconnect, and safe MCP wiring.
10
+
11
+ ## Why
12
+
13
+ Deep Research tasks run for 5–60 minutes. Running them from a web UI means keeping a browser tab open. `gdr` decouples the task from your terminal session: start a research run, live-stream thought summaries, walk away, resume later by ID, and get artifacts on disk that fit into any downstream pipeline.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ # With pipx (recommended — isolated install)
19
+ pipx install gemini-deep-research
20
+
21
+ # With uv tool
22
+ uv tool install gemini-deep-research
23
+
24
+ # From source (dev)
25
+ git clone https://github.com/johnswyou/gemini-deep-research
26
+ cd gemini-deep-research
27
+ uv sync --extra dev
28
+ uv run gdr --help
29
+ ```
30
+
31
+ ## Quickstart
32
+
33
+ ```bash
34
+ export GEMINI_API_KEY=... # get one at https://aistudio.google.com/apikey
35
+
36
+ # One-line research with the fast agent
37
+ gdr research "Latest trends in RISC-V adoption"
38
+
39
+ # Maximum-quality agent for due diligence
40
+ gdr research --max "Competitive landscape of EV batteries"
41
+
42
+ # Review and refine the agent's plan before it spends tokens
43
+ gdr research --plan "Impact of AI on semiconductor supply chain"
44
+
45
+ # Ground in your own documents
46
+ gdr research --file ~/Downloads/10k.pdf \
47
+ "Compare risk factors vs our 2024 filing"
48
+ ```
49
+
50
+ Each run produces a timestamped directory under `~/gdr-reports/` containing `report.md`, `sources.json`, `transcript.json`, `metadata.json`, and any generated images.
51
+
52
+ ## Command reference
53
+
54
+ | Command | Purpose |
55
+ | --- | --- |
56
+ | `gdr research <query>` | Run a research task (fast agent by default, `--max` for Max) |
57
+ | `gdr research --plan <query>` | Collaborative planning — review and refine the plan before execution |
58
+ | `gdr status <id>` | Check the status of a running or completed task |
59
+ | `gdr resume <id>` | Re-attach to a running task after Ctrl+C or disconnect |
60
+ | `gdr follow-up <id> <question>` | Ask a follow-up using the previous interaction as context |
61
+ | `gdr plan refine <id> <feedback>` | Iterate on a pending plan without executing |
62
+ | `gdr plan approve <id>` | Approve and execute a pending plan |
63
+ | `gdr cancel <id>` | Cancel a running task |
64
+ | `gdr ls` | List recent interactions |
65
+ | `gdr show <id>` | Render a saved artifact |
66
+ | `gdr config {path,get,set,edit}` | Manage the TOML config file |
67
+ | `gdr doctor [--fix]` | Diagnose and optionally repair your setup |
68
+
69
+ Run `gdr --help` or `gdr <command> --help` for full flag reference.
70
+
71
+ See [`docs/USAGE.md`](docs/USAGE.md) for long-form command documentation,
72
+ [`docs/MCP.md`](docs/MCP.md) for MCP server integration, and
73
+ [`docs/TROUBLESHOOTING.md`](docs/TROUBLESHOOTING.md) for common failure
74
+ modes and recovery recipes. Runnable demos live in [`examples/`](examples/).
75
+
76
+ ## Configuration
77
+
78
+ Config lives at `~/.config/gdr/config.toml`. Run `gdr doctor --fix` to scaffold it. Environment variables referenced with `env:VAR_NAME` are expanded at load time so secrets stay out of the file.
79
+
80
+ ```toml
81
+ api_key = "env:GEMINI_API_KEY"
82
+ default_agent = "deep-research-preview-04-2026"
83
+ output_dir = "~/gdr-reports"
84
+ auto_open = true
85
+ confirm_max = true # prompt before running the Max agent
86
+ default_tools = ["google_search", "url_context", "code_execution"]
87
+ thinking_summaries = "auto" # "auto" or "none"
88
+ visualization = "auto" # "auto" or "off"
89
+ safe_untrusted = true # auto-strip dangerous tools when --file/--url is used
90
+
91
+ [mcp_servers.factset]
92
+ url = "https://mcp.factset.com"
93
+ headers.Authorization = "Bearer env:FACTSET_TOKEN"
94
+ ```
95
+
96
+ ## Safety
97
+
98
+ Deep Research agents can read files and the public web. `gdr` ships with:
99
+
100
+ - **Redaction** of MCP auth headers and API keys from `transcript.json`.
101
+ - **Path confinement**: all artifacts land under the configured `output_dir`; slug names are sanitized.
102
+ - **Header validation** for MCP servers (no CRLF injection, no reserved names).
103
+ - **`--untrusted-input`** flag that disables `code_execution` and `mcp_server` tools for a run — use when grounding in attacker-controlled files or URLs.
104
+
105
+ See [`docs/MCP.md`](docs/MCP.md) for the MCP security model and
106
+ [`docs/TROUBLESHOOTING.md`](docs/TROUBLESHOOTING.md) for the
107
+ `--untrusted-input` recipe.
108
+
109
+ ## Development
110
+
111
+ ```bash
112
+ uv sync --extra dev
113
+ uv run ruff check .
114
+ uv run mypy src
115
+ uv run pytest -q
116
+ ```
117
+
118
+ ## Roadmap
119
+
120
+ Deferred to v1.1: HTML/PDF export, cost estimation, SQLite history
121
+ backend, interactive setup wizard. See `docs/USAGE.md` for the
122
+ currently-shipping surface.
123
+
124
+ ## License
125
+
126
+ MIT. See [`LICENSE`](LICENSE).
127
+
128
+ ## Credits
129
+
130
+ Built on [Google's Gemini Interactions API](https://ai.google.dev/gemini-api/docs/interactions) and the [`google-genai`](https://github.com/googleapis/python-genai) Python SDK.
@@ -0,0 +1,173 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.25"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "gemini-deep-research"
7
+ version = "0.1.0"
8
+ description = "Unofficial terminal-first client for Google's Gemini Deep Research and Deep Research Max agents (not affiliated with Google)."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [{ name = "gdr contributors" }]
13
+ keywords = ["gemini", "deep-research", "cli", "llm", "google", "ai", "research", "agent"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "Intended Audience :: Science/Research",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
28
+ "Topic :: Software Development",
29
+ "Topic :: Utilities",
30
+ ]
31
+ dependencies = [
32
+ "google-genai>=1.55.0",
33
+ "typer>=0.12.0",
34
+ "rich>=13.7.0",
35
+ "pydantic>=2.7.0",
36
+ "platformdirs>=4.2.0",
37
+ "httpx>=0.27.0",
38
+ "tomli>=2.0.0; python_version < '3.11'",
39
+ ]
40
+
41
+ [project.optional-dependencies]
42
+ dev = [
43
+ "pytest>=8.0",
44
+ "pytest-cov>=5.0",
45
+ "pytest-mock>=3.14",
46
+ "ruff>=0.6",
47
+ "mypy>=1.10",
48
+ ]
49
+
50
+ [project.scripts]
51
+ gdr = "gdr.cli:app"
52
+
53
+ [project.urls]
54
+ Homepage = "https://github.com/johnswyou/gemini-deep-research"
55
+ Repository = "https://github.com/johnswyou/gemini-deep-research"
56
+ Issues = "https://github.com/johnswyou/gemini-deep-research/issues"
57
+
58
+ [tool.hatch.build.targets.wheel]
59
+ packages = ["src/gdr"]
60
+
61
+ [tool.hatch.build.targets.sdist]
62
+ include = [
63
+ "src/gdr",
64
+ "tests",
65
+ "README.md",
66
+ "LICENSE",
67
+ "pyproject.toml",
68
+ ]
69
+
70
+ # ---------------------------------------------------------------------------
71
+ # Ruff (lint + format)
72
+ # ---------------------------------------------------------------------------
73
+ [tool.ruff]
74
+ line-length = 100
75
+ target-version = "py310"
76
+ src = ["src", "tests"]
77
+
78
+ [tool.ruff.lint]
79
+ select = [
80
+ "E", # pycodestyle errors
81
+ "W", # pycodestyle warnings
82
+ "F", # pyflakes
83
+ "I", # isort
84
+ "B", # flake8-bugbear
85
+ "UP", # pyupgrade
86
+ "N", # pep8-naming
87
+ "RUF", # ruff-specific
88
+ "SIM", # flake8-simplify
89
+ "PTH", # flake8-use-pathlib
90
+ "C4", # flake8-comprehensions
91
+ "PL", # pylint
92
+ "TID", # flake8-tidy-imports
93
+ ]
94
+ ignore = [
95
+ "E501", # line length handled by formatter
96
+ "PLR0913", # too many arguments — CLI commands legitimately have many
97
+ "PLR2004", # magic value comparisons — readable in tests
98
+ ]
99
+
100
+ [tool.ruff.lint.per-file-ignores]
101
+ "tests/**" = ["PLR", "B011"]
102
+ "src/gdr/cli.py" = ["PLC0415"]
103
+
104
+ [tool.ruff.lint.flake8-bugbear]
105
+ # Typer's idiom requires `typer.Option(...)` / `typer.Argument(...)` in
106
+ # default values of command functions. These calls are side-effect-free
107
+ # metadata constructors, so the bugbear B008 warning is spurious here.
108
+ extend-immutable-calls = ["typer.Option", "typer.Argument"]
109
+
110
+ [tool.ruff.format]
111
+ quote-style = "double"
112
+
113
+ # ---------------------------------------------------------------------------
114
+ # Mypy (strict typing)
115
+ # ---------------------------------------------------------------------------
116
+ [tool.mypy]
117
+ python_version = "3.10"
118
+ strict = true
119
+ warn_unused_ignores = true
120
+ warn_return_any = true
121
+ disallow_untyped_defs = true
122
+ disallow_any_generics = true
123
+ no_implicit_optional = true
124
+ check_untyped_defs = true
125
+ pretty = true
126
+ show_error_codes = true
127
+ mypy_path = "src"
128
+ packages = ["gdr"]
129
+ explicit_package_bases = true
130
+
131
+ [[tool.mypy.overrides]]
132
+ module = ["google.*", "google.genai.*"]
133
+ ignore_missing_imports = true
134
+
135
+ [[tool.mypy.overrides]]
136
+ # `tomli` is only imported on Python 3.10; we run mypy on 3.11+.
137
+ module = "tomli"
138
+ ignore_missing_imports = true
139
+
140
+ [[tool.mypy.overrides]]
141
+ module = "tests.*"
142
+ disallow_untyped_defs = false
143
+
144
+ # ---------------------------------------------------------------------------
145
+ # Pytest
146
+ # ---------------------------------------------------------------------------
147
+ [tool.pytest.ini_options]
148
+ minversion = "8.0"
149
+ addopts = [
150
+ "-ra",
151
+ "--strict-markers",
152
+ "--strict-config",
153
+ ]
154
+ testpaths = ["tests"]
155
+ pythonpath = ["src"]
156
+ markers = [
157
+ "live: tests that hit the real Gemini API (requires GEMINI_API_KEY and RUN_LIVE_TESTS=1)",
158
+ ]
159
+
160
+ # ---------------------------------------------------------------------------
161
+ # Coverage
162
+ # ---------------------------------------------------------------------------
163
+ [tool.coverage.run]
164
+ source = ["src/gdr"]
165
+ branch = true
166
+
167
+ [tool.coverage.report]
168
+ exclude_lines = [
169
+ "pragma: no cover",
170
+ "raise NotImplementedError",
171
+ "if TYPE_CHECKING:",
172
+ "if __name__ == .__main__.:",
173
+ ]
@@ -0,0 +1,7 @@
1
+ """gdr — a terminal client for Google's Gemini Deep Research agents."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __version__ = "0.1.0"
6
+
7
+ __all__ = ["__version__"]
@@ -0,0 +1,13 @@
1
+ """Entry point for `python -m gdr`."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from gdr.cli import app
6
+
7
+
8
+ def main() -> None:
9
+ app()
10
+
11
+
12
+ if __name__ == "__main__":
13
+ main()
@@ -0,0 +1,76 @@
1
+ """Typer app root for the gdr CLI.
2
+
3
+ This module wires up the top-level application and registers subcommands.
4
+ Subcommands live in `gdr.commands.*` and are added here as each phase lands.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import typer
10
+
11
+ from gdr import __version__
12
+ from gdr.commands import (
13
+ cancel,
14
+ doctor,
15
+ follow_up,
16
+ ls,
17
+ plan,
18
+ research,
19
+ resume,
20
+ show,
21
+ status,
22
+ )
23
+ from gdr.commands import (
24
+ config as config_cmd,
25
+ )
26
+ from gdr.constants import APP_DESCRIPTION, APP_NAME
27
+
28
+ app = typer.Typer(
29
+ name=APP_NAME,
30
+ help=APP_DESCRIPTION,
31
+ no_args_is_help=True,
32
+ add_completion=True,
33
+ rich_markup_mode="rich",
34
+ context_settings={"help_option_names": ["-h", "--help"]},
35
+ )
36
+
37
+
38
+ def _version_callback(value: bool) -> None:
39
+ if value:
40
+ typer.echo(f"{APP_NAME} {__version__}")
41
+ raise typer.Exit
42
+
43
+
44
+ @app.callback()
45
+ def main(
46
+ _version: bool = typer.Option(
47
+ False,
48
+ "--version",
49
+ "-V",
50
+ callback=_version_callback,
51
+ is_eager=True,
52
+ help="Show the installed gdr version and exit.",
53
+ ),
54
+ ) -> None:
55
+ """Gemini Deep Research from your terminal.
56
+
57
+ Run `gdr research <query>` to start. See `gdr --help` for the full command
58
+ list once more commands are registered in later phases.
59
+ """
60
+
61
+
62
+ # Subcommands — each module exposes a `run` function or a Typer sub-app.
63
+ app.command(name="research", help="Run a Deep Research task and save artifacts to disk.")(
64
+ research.run
65
+ )
66
+ app.add_typer(plan.app, name="plan")
67
+ app.command(name="ls", help="List recent interactions from the local store.")(ls.run)
68
+ app.command(name="show", help="Print a saved artifact from a prior research run.")(show.run)
69
+ app.command(name="status", help="Check the current status of an interaction.")(status.run)
70
+ app.command(name="resume", help="Reattach to a running or completed interaction.")(resume.run)
71
+ app.command(
72
+ name="follow-up", help="Ask a follow-up question using a prior interaction as context."
73
+ )(follow_up.run)
74
+ app.command(name="cancel", help="Cancel an in-progress interaction.")(cancel.run)
75
+ app.add_typer(config_cmd.app, name="config")
76
+ app.command(name="doctor", help="Validate the local environment for gdr.")(doctor.run)
@@ -0,0 +1,5 @@
1
+ """Top-level CLI command implementations.
2
+
3
+ Each subcommand lives in its own module (e.g. `gdr.commands.research`) and is
4
+ registered on the Typer app in `gdr.cli`.
5
+ """