gemiterm 2.1.1 → 2.2.0-beta.1
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.
- package/LICENSE.md +21 -0
- package/README.md +223 -154
- package/package.json +3 -1
- package/src/cli/commands/auth-command.ts +12 -11
- package/src/cli/commands/delete-command.ts +3 -12
- package/src/cli/commands/export-all-command.ts +15 -15
- package/src/cli/commands/export-command.ts +6 -6
- package/src/cli/commands/fetch-command.ts +17 -17
- package/src/cli/commands/list-command.ts +114 -27
- package/src/cli/commands/profile-command.ts +2 -8
- package/src/cli/utils/interactive-prompt.ts +44 -36
- package/src/cli/utils/prompts.ts +319 -0
- package/src/core/query-handlers.ts +5 -2
- package/src/services/gemini-client-wrapper.ts +1 -1
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 GemiTerm 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.
|
package/README.md
CHANGED
|
@@ -1,268 +1,337 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# GemiTerm
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
### Google Gemini in your terminal — list, search, export, continue, and debate from the command line.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
[](https://www.npmjs.com/package/gemiterm)
|
|
8
|
+
[](https://bun.sh)
|
|
9
|
+
[](https://www.typescriptlang.org/)
|
|
10
|
+
[](LICENSE.md)
|
|
11
|
+
[](#installation)
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
- **Chromium Browser** — GemiTerm uses your system Chrome/Edge if available, otherwise installs Playwright's Chromium automatically
|
|
9
|
-
- **Google Account** with access to [Gemini](https://gemini.google.com)
|
|
13
|
+
**List · Search · Export · Continue · Debate · Automate**
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
[Quick Start](#quick-start) · [Features](#features) · [Cross-Agent Debates](#cross-agent-debates-with-gemini) · [Commands](#commands) · [Configuration](#configuration) · [Contributing](#contributing) · [Acknowledgements](#acknowledgments)
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
</div>
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
bunx gemiterm auth # authenticate with Google
|
|
17
|
-
bunx gemiterm list # list your chats
|
|
18
|
-
```
|
|
19
|
+
---
|
|
19
20
|
|
|
20
|
-
##
|
|
21
|
+
## What is GemiTerm?
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
[Gemini](https://gemini.google.com) is one of the most capable AI assistants available — and almost all of your best conversations with it live **trapped inside the web UI**, with no public API to reach them. GemiTerm is the bridge.
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
bun install gemiterm -g
|
|
26
|
-
```
|
|
25
|
+
It's a fast, scriptable command-line client for the **Google Gemini web app**. Authenticate once, then list, search, fetch, export, continue, and delete chats from your shell. Pipe JSON into other tools. Wire it into CI. Or hand it to your AI coding agent and let it argue trade-offs with Gemini in real time.
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
GemiTerm is built with **[Bun](https://bun.sh)** and TypeScript, ships as a single native binary, and authenticates via Playwright — no Google API key, no rate limits, no quota.
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
gemiterm auth
|
|
32
|
-
gemiterm list
|
|
33
|
-
```
|
|
29
|
+
> **TL;DR:** If you've ever wanted to `grep` your Gemini history, bulk-export months of chats, or have your coding agent debate Gemini about architecture before you commit — GemiTerm is for you.
|
|
34
30
|
|
|
35
|
-
|
|
31
|
+
## Why GemiTerm?
|
|
36
32
|
|
|
37
|
-
|
|
33
|
+
- **No public API? No problem.** GemiTerm drives the real Gemini web app via a headless browser. It sees exactly what you see, including your entire history.
|
|
34
|
+
- **Cross-agent debates built-in.** Spin up a `debate-with-gemini` skill and your coding agent (Claude Code, OpenCode, GitHub Copilot, …) will argue both sides of a technical decision with real Gemini responses, for N rounds. Catch design flaws before they ship.
|
|
35
|
+
- **Scriptable & pipeable.** First-class `text` and `json` output. Works in cron jobs, Makefiles, shell loops, and CI.
|
|
36
|
+
- **Searchable archive.** Bulk-export to Markdown or JSON and run `grep`, `rg`, or your favorite search tool over months of AI conversations.
|
|
37
|
+
- **Multi-profile, multi-account.** Keep work, personal, and side-project identities separate. One CLI, many Gemini accounts.
|
|
38
|
+
- **Single binary, every OS.** Native builds for Windows, Linux, and macOS. No Node, no Python, no runtime to install.
|
|
39
|
+
- **Local-first, private.** Cookies never leave your machine. 7-day freshness window. You own your data.
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
## Features
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
- 🔍 **List & search** — find any Gemini chat by title, date, or content (`--sort`, `--after`, `--before`, `--search`, `--all`, `--all-profiles`)
|
|
44
|
+
- 📥 **Bulk export** — Markdown or JSON, indexed `index.md`, ready for grep and archival
|
|
45
|
+
- 💬 **Continue or start** — interactive REPL or one-shot, with `--prompt-file` for long prompts
|
|
46
|
+
- 🗑️ **Delete with confirmation** — clean up old chats safely (`--force` to skip)
|
|
47
|
+
- 👤 **Multi-profile** — separate identities for work / personal / side-projects, one-click switching
|
|
48
|
+
- 🤖 **AI-agent skills** — plug into OpenCode, Claude Code, GitHub Copilot, and any agent that reads skills
|
|
49
|
+
- 🗣️ **Cross-agent debates** — your agent argues both sides with Gemini, surfaces real agreements and disagreements
|
|
50
|
+
- 📦 **Single binary** — Bun-compiled, no runtime required; works on Windows, Linux, macOS
|
|
51
|
+
- 🔐 **Local cookies** — never uploaded; 7-day freshness window
|
|
44
52
|
|
|
45
|
-
|
|
53
|
+
## Cross-Agent Debates with Gemini
|
|
46
54
|
|
|
47
|
-
|
|
48
|
-
curl -fsSL https://github.com/expert-vision-software/GemiTerm/releases/latest/download/install.sh | bash
|
|
49
|
-
```
|
|
55
|
+
The killer feature isn't just CLI access — it's what your **AI coding agent** can do with it.
|
|
50
56
|
|
|
51
|
-
|
|
57
|
+
GemiTerm ships with a companion **skills package** (`opencode-gemiterm-skills`) that teaches any LLM-powered terminal how to use GemiTerm on demand. Two skills are included:
|
|
52
58
|
|
|
53
|
-
|
|
59
|
+
| Skill | What it does |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| **`gemiterm`** | Search, list, export, and manage your Gemini chats from inside an agent session. |
|
|
62
|
+
| **`debate-with-gemini`** | Run structured multi-turn technical debates with Gemini — perfect for stress-testing architecture decisions, trade-offs, and design choices. |
|
|
54
63
|
|
|
55
|
-
|
|
64
|
+
Install in one command:
|
|
56
65
|
|
|
57
66
|
```bash
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
bun run typecheck # TypeScript type checking
|
|
62
|
-
bun run build # compile to standalone Bun binary
|
|
63
|
-
bun run build:linux # cross-compile for Linux x64
|
|
64
|
-
bun run build:windows # cross-compile for Windows x64
|
|
67
|
+
gemiterm install-skills
|
|
68
|
+
# or, for any agent that supports the skills CLI
|
|
69
|
+
bunx opencode-gemiterm-skills install
|
|
65
70
|
```
|
|
66
71
|
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
bash scripts/install-browser.sh # Linux/macOS
|
|
70
|
-
pwsh scripts/install-browser.ps1 # Windows
|
|
71
|
-
```
|
|
72
|
+
Then in your agent session, just ask:
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
> **You:** "Debate Gemini for/against using SQLite as the primary database for a SaaS app. Context: docs/arch.md. 5 turns."
|
|
74
75
|
|
|
75
|
-
|
|
76
|
+
The agent reads your context, seeds a fresh Gemini chat with the opposing view, and runs a 5-round autonomous back-and-forth:
|
|
76
77
|
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
bun run build:release # minified release binary (dist/gemiterm)
|
|
78
|
+
```
|
|
79
|
+
Debate complete (5 turns). Gemini argued FOR SQLite (simplicity, zero-config).
|
|
80
|
+
I argued AGAINST (concurrency limits, no network access, scaling ceiling).
|
|
81
|
+
Key agreements: fine for prototyping, migrate to Postgres before 100+ concurrent users.
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
- **Linux/macOS**: `dist/gemiterm`
|
|
86
|
-
- **Windows**: `dist/gemiterm.exe`
|
|
84
|
+
Other use cases for `debate-with-gemini`:
|
|
87
85
|
|
|
88
|
-
|
|
86
|
+
- **Validate API design** — "Have Gemini argue against this REST contract. 3 turns."
|
|
87
|
+
- **Review a refactor** — "Stress-test the migration to event-sourcing with Gemini. 4 turns."
|
|
88
|
+
- **Compare libraries** — "Argue both sides of `Zod` vs. `valibot` for this schema. 3 turns."
|
|
89
|
+
- **Continue a previous debate** — "Resume chat `c_abc123` for 3 more turns."
|
|
89
90
|
|
|
90
|
-
The
|
|
91
|
-
- `GemiTerm` — Linux x64 binary
|
|
92
|
-
- `GemiTerm.exe` — Windows x64 binary
|
|
93
|
-
- `install.sh` — POSIX installer script
|
|
94
|
-
- `install.ps1` — Windows PowerShell installer script
|
|
91
|
+
The full skill bundle lives at [`opencode-gemiterm-skills`](https://www.npmjs.com/package/opencode-gemiterm-skills).
|
|
95
92
|
|
|
96
|
-
##
|
|
93
|
+
## Quick Start
|
|
97
94
|
|
|
98
|
-
###
|
|
95
|
+
### Try without installing
|
|
99
96
|
|
|
100
97
|
```bash
|
|
101
|
-
gemiterm auth
|
|
98
|
+
bunx gemiterm auth # sign in to Google
|
|
99
|
+
bunx gemiterm list # show your recent chats
|
|
102
100
|
```
|
|
103
101
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
### Check Status
|
|
102
|
+
### Install globally (recommended for daily use)
|
|
107
103
|
|
|
108
104
|
```bash
|
|
109
|
-
gemiterm
|
|
105
|
+
bun install -g gemiterm
|
|
106
|
+
|
|
107
|
+
gemiterm auth
|
|
108
|
+
gemiterm list
|
|
110
109
|
```
|
|
111
110
|
|
|
112
|
-
|
|
111
|
+
### Install scripts (no Bun required — bootstraps it for you)
|
|
113
112
|
|
|
114
|
-
|
|
113
|
+
**Windows (PowerShell 7+):**
|
|
115
114
|
|
|
116
|
-
```
|
|
117
|
-
|
|
115
|
+
```powershell
|
|
116
|
+
irm https://github.com/expert-vision-software/GemiTerm/releases/latest/download/install.ps1 | iex
|
|
118
117
|
```
|
|
119
118
|
|
|
120
|
-
|
|
121
|
-
- `-n, --limit N`: Maximum number of chats (default: 10)
|
|
122
|
-
- `--offset N`: Skip first N chats (default: 0)
|
|
123
|
-
- `--sort <recent|oldest|alpha>`: Sort order
|
|
124
|
-
- `-s, --search <query>`: Filter by title
|
|
125
|
-
- `--after <date>`: Only chats after this date
|
|
126
|
-
- `--before <date>`: Only chats before this date
|
|
127
|
-
- `--all`: Show all chats (no limit)
|
|
128
|
-
- `--all-profiles`: Merge chats from all profiles
|
|
129
|
-
- `-f, --format <text|json>`: Output format
|
|
130
|
-
- `-p, --path <path>`: Save output to file
|
|
131
|
-
|
|
132
|
-
### Fetch Chat History
|
|
119
|
+
**Linux / macOS:**
|
|
133
120
|
|
|
134
121
|
```bash
|
|
135
|
-
|
|
122
|
+
curl -fsSL https://github.com/expert-vision-software/GemiTerm/releases/latest/download/install.sh | bash
|
|
136
123
|
```
|
|
137
124
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
125
|
+
> **Upgrading from v1.4.1?** Your profiles, cookies, and default profile marker are preserved. See [docs/INSTALL.md](docs/INSTALL.md) for details.
|
|
126
|
+
|
|
127
|
+
See [docs/INSTALL.md](docs/INSTALL.md) for the full guide, uninstall instructions, troubleshooting, and build-from-source steps.
|
|
128
|
+
|
|
129
|
+
## Prerequisites
|
|
130
|
+
|
|
131
|
+
- **[Bun](https://bun.sh)** runtime ≥ 1.0.0 (only required for `bunx` / `bun install` use — not needed for install scripts)
|
|
132
|
+
- **Chromium browser** — GemiTerm prefers your system Chrome / Edge; otherwise it installs Playwright's Chromium automatically (`gemiterm install-browser`)
|
|
133
|
+
- **Google Account** with access to [Gemini](https://gemini.google.com)
|
|
141
134
|
|
|
142
|
-
|
|
135
|
+
## Commands
|
|
136
|
+
|
|
137
|
+
| Command | Alias | Purpose |
|
|
138
|
+
| --- | --- | --- |
|
|
139
|
+
| `gemiterm auth` | `gemiterm login` | Sign in to Google and save cookies |
|
|
140
|
+
| `gemiterm status` | — | Show config dir and profile table |
|
|
141
|
+
| `gemiterm list` | — | List chats (filter, sort, search) |
|
|
142
|
+
| `gemiterm fetch <id>` | — | Fetch a chat's full history |
|
|
143
|
+
| `gemiterm new [message]` | — | Start a new chat (one-shot or REPL) |
|
|
144
|
+
| `gemiterm continue <id> [msg]` | — | Continue an existing chat |
|
|
145
|
+
| `gemiterm export <id>` | — | Export one chat to Markdown / JSON |
|
|
146
|
+
| `gemiterm export-all` | — | Bulk-export all chats with `index.md` |
|
|
147
|
+
| `gemiterm delete <id>` | — | Delete a chat (with confirmation) |
|
|
148
|
+
| `gemiterm profile <sub>` | — | Manage profiles (list / add / delete / rename / default) |
|
|
149
|
+
| `gemiterm install-browser` | — | Install Playwright Chromium |
|
|
150
|
+
| `gemiterm install-skills` | — | Install the cross-agent skills bundle |
|
|
151
|
+
| `gemiterm -v <cmd>` | — | Verbose logging for any command |
|
|
152
|
+
|
|
153
|
+
### `gemiterm list`
|
|
154
|
+
|
|
155
|
+
List, filter, and search your Gemini chats.
|
|
143
156
|
|
|
144
157
|
```bash
|
|
145
|
-
gemiterm
|
|
158
|
+
gemiterm list
|
|
159
|
+
gemiterm list -n 50 --sort alpha
|
|
160
|
+
gemiterm list --search "react server components"
|
|
161
|
+
gemiterm list --after 2026-01-01 --before 2026-06-01
|
|
162
|
+
gemiterm list --all --all-profiles -f json -p chats.json
|
|
146
163
|
```
|
|
147
164
|
|
|
148
|
-
|
|
165
|
+
| Flag | Description |
|
|
166
|
+
| --- | --- |
|
|
167
|
+
| `-n, --limit N` | Max chats to show (default: 10) |
|
|
168
|
+
| `--offset N` | Skip the first N chats |
|
|
169
|
+
| `--sort <recent\|oldest\|alpha>` | Sort order |
|
|
170
|
+
| `-s, --search <query>` | Filter by title |
|
|
171
|
+
| `--after <date>` | Only chats after this date |
|
|
172
|
+
| `--before <date>` | Only chats before this date |
|
|
173
|
+
| `--all` | Show all chats (no limit) |
|
|
174
|
+
| `--all-profiles` | Merge chats from all profiles |
|
|
175
|
+
| `-f, --format <text\|json>` | Output format |
|
|
176
|
+
| `-o, --out <path>` | Save output to file |
|
|
149
177
|
|
|
150
|
-
###
|
|
178
|
+
### `gemiterm fetch <conversation_id>`
|
|
179
|
+
|
|
180
|
+
Fetch a single conversation's full history.
|
|
151
181
|
|
|
152
182
|
```bash
|
|
153
|
-
gemiterm
|
|
183
|
+
gemiterm fetch c_abc123
|
|
184
|
+
gemiterm fetch c_abc123 -f json -o chat.json
|
|
154
185
|
```
|
|
155
186
|
|
|
156
|
-
|
|
157
|
-
|
|
187
|
+
| Flag | Description |
|
|
188
|
+
| --- | --- |
|
|
189
|
+
| `-f, --format <text\|json>` | Output format |
|
|
190
|
+
| `-o, --out <path>` | Save output to file |
|
|
158
191
|
|
|
159
|
-
|
|
192
|
+
### `gemiterm new [message]`
|
|
160
193
|
|
|
161
|
-
|
|
194
|
+
Start a new chat. One-shot if you pass a message; otherwise drops into an interactive REPL.
|
|
162
195
|
|
|
163
196
|
```bash
|
|
164
|
-
gemiterm
|
|
197
|
+
gemiterm new "Explain the CAP theorem like I'm 12"
|
|
198
|
+
gemiterm new --profile work "Draft a status update"
|
|
199
|
+
gemiterm new --prompt-file ./long-prompt.md
|
|
165
200
|
```
|
|
166
201
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
202
|
+
| Flag | Description |
|
|
203
|
+
| --- | --- |
|
|
204
|
+
| `-p, --profile <name>` | Use a specific profile |
|
|
205
|
+
| `-f, --prompt-file <path>` | Read the message from a file (bypasses shell arg-length limits) |
|
|
206
|
+
| `-h, --help` | Show help |
|
|
207
|
+
|
|
208
|
+
### `gemiterm continue <conversation_id> [message]`
|
|
171
209
|
|
|
172
|
-
|
|
210
|
+
Continue an existing chat. With no message, enters an interactive REPL. With no conversation ID, falls back to `list`.
|
|
173
211
|
|
|
174
212
|
```bash
|
|
175
|
-
gemiterm
|
|
213
|
+
gemiterm continue c_abc123
|
|
214
|
+
gemiterm continue c_abc123 "And what about edge cases?"
|
|
215
|
+
gemiterm continue c_abc123 --prompt-file ./refactor-context.md
|
|
176
216
|
```
|
|
177
217
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
-
|
|
181
|
-
|
|
182
|
-
- `-a, --all-profiles`: Export from all profiles
|
|
218
|
+
| Flag | Description |
|
|
219
|
+
| --- | --- |
|
|
220
|
+
| `-f, --prompt-file <path>` | Read the message from a file (bypasses shell arg-length limits) |
|
|
221
|
+
| `-h, --help` | Show help |
|
|
183
222
|
|
|
184
|
-
|
|
223
|
+
> **Long prompts?** On Windows the shell argument limit is roughly 2 048 UTF-16 code units. GemiTerm detects oversized messages and **spills them to a temp file automatically** — or you can use `--prompt-file` explicitly to read from a file you control.
|
|
185
224
|
|
|
186
|
-
###
|
|
225
|
+
### `gemiterm export <conversation_id>`
|
|
226
|
+
|
|
227
|
+
Export a single chat to a file.
|
|
187
228
|
|
|
188
229
|
```bash
|
|
189
|
-
gemiterm
|
|
230
|
+
gemiterm export c_abc123
|
|
231
|
+
gemiterm export c_abc123 -o ./chat.md -f json --include-metadata
|
|
190
232
|
```
|
|
191
233
|
|
|
192
|
-
|
|
193
|
-
|
|
234
|
+
| Flag | Description |
|
|
235
|
+
| --- | --- |
|
|
236
|
+
| `-o, --out <path>` | Custom output file path |
|
|
237
|
+
| `-f, --format <markdown\|json>` | Export format (default: `markdown`) |
|
|
238
|
+
| `--include-metadata` | Include full metadata in the export |
|
|
239
|
+
|
|
240
|
+
### `gemiterm export-all`
|
|
194
241
|
|
|
195
|
-
|
|
242
|
+
Bulk-export every chat (or every chat since a date) with an auto-generated `index.md`.
|
|
196
243
|
|
|
197
244
|
```bash
|
|
198
|
-
gemiterm
|
|
199
|
-
gemiterm
|
|
200
|
-
gemiterm
|
|
201
|
-
gemiterm profile rename <name> <newName> # rename a profile
|
|
202
|
-
gemiterm profile default <name> # set default profile
|
|
245
|
+
gemiterm export-all
|
|
246
|
+
gemiterm export-all --since 2026-01-01 --include-metadata
|
|
247
|
+
gemiterm export-all -o ./exports -a
|
|
203
248
|
```
|
|
204
249
|
|
|
205
|
-
|
|
250
|
+
| Flag | Description |
|
|
251
|
+
| --- | --- |
|
|
252
|
+
| `-o, --out-dir <dir>` | Output directory (default: `./exports`) |
|
|
253
|
+
| `--since <date>` | Only chats newer than this date |
|
|
254
|
+
| `--include-metadata` | Include full metadata |
|
|
255
|
+
| `-a, --all-profiles` | Export from all profiles |
|
|
256
|
+
|
|
257
|
+
### `gemiterm delete <conversation_id>`
|
|
258
|
+
|
|
259
|
+
Delete a chat from your Gemini account. Confirms by default.
|
|
206
260
|
|
|
207
261
|
```bash
|
|
208
|
-
gemiterm
|
|
262
|
+
gemiterm delete c_abc123
|
|
263
|
+
gemiterm delete c_abc123 --force
|
|
209
264
|
```
|
|
210
265
|
|
|
211
|
-
|
|
266
|
+
| Flag | Description |
|
|
267
|
+
| --- | --- |
|
|
268
|
+
| `-f, --force` | Skip the confirmation prompt |
|
|
269
|
+
|
|
270
|
+
### `gemiterm profile <subcommand>`
|
|
212
271
|
|
|
213
|
-
|
|
272
|
+
Manage multiple Gemini profiles (separate Google accounts or isolated cookie stores).
|
|
214
273
|
|
|
215
274
|
```bash
|
|
216
|
-
gemiterm
|
|
275
|
+
gemiterm profile list
|
|
276
|
+
gemiterm profile add work
|
|
277
|
+
gemiterm profile delete work
|
|
278
|
+
gemiterm profile rename work jobs
|
|
279
|
+
gemiterm profile default work
|
|
217
280
|
```
|
|
218
281
|
|
|
219
|
-
|
|
282
|
+
### `gemiterm install-browser`
|
|
283
|
+
|
|
284
|
+
Checks for a system Chrome / Edge first; falls back to Playwright's Chromium. Usually only needed once after install.
|
|
285
|
+
|
|
286
|
+
### `gemiterm install-skills`
|
|
220
287
|
|
|
221
|
-
|
|
288
|
+
Installs the [`opencode-gemiterm-skills`](https://www.npmjs.com/package/opencode-gemiterm-skills) bundle so your AI agent can use GemiTerm (and the `debate-with-gemini` skill) automatically.
|
|
222
289
|
|
|
223
290
|
## Configuration
|
|
224
291
|
|
|
225
|
-
### Configuration
|
|
292
|
+
### Configuration directory
|
|
226
293
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
294
|
+
| Platform | Config dir | Binary location (install script) |
|
|
295
|
+
| --- | --- | --- |
|
|
296
|
+
| Windows | `%APPDATA%\gemiterm\` | `%LOCALAPPDATA%\GemiTerm\` |
|
|
297
|
+
| Linux / macOS | `~/gemiterm/` | `~/.local/bin/gemiterm` |
|
|
230
298
|
|
|
231
299
|
Override with:
|
|
300
|
+
|
|
232
301
|
```bash
|
|
233
302
|
export GEMITERM_CONFIG_DIR=/custom/path
|
|
234
303
|
```
|
|
235
304
|
|
|
236
|
-
### Profile
|
|
305
|
+
### Profile storage
|
|
237
306
|
|
|
238
307
|
```
|
|
239
308
|
gemiterm/
|
|
240
309
|
profiles/
|
|
241
|
-
.default # text file with default profile name
|
|
310
|
+
.default # text file with the default profile name
|
|
242
311
|
<profile-name>/
|
|
243
|
-
storage_state.json #
|
|
312
|
+
storage_state.json # authenticated cookies
|
|
244
313
|
```
|
|
245
314
|
|
|
246
|
-
|
|
315
|
+
Upgrading from v1.4.1 keeps these paths and files unchanged.
|
|
316
|
+
|
|
317
|
+
### Environment variables
|
|
247
318
|
|
|
248
319
|
| Variable | Description | Default |
|
|
249
|
-
|
|
250
|
-
| `GEMITERM_CONFIG_DIR` |
|
|
320
|
+
| --- | --- | --- |
|
|
321
|
+
| `GEMITERM_CONFIG_DIR` | Override the configuration directory | Platform default |
|
|
251
322
|
|
|
252
|
-
##
|
|
323
|
+
## Contributing
|
|
253
324
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
fixtures/ # Shared test fixtures
|
|
266
|
-
```
|
|
325
|
+
Architecture, development workflow, build instructions, and contribution guidelines live in **[CONTRIBUTING.md](CONTRIBUTING.md)**. The agent guide — including the path-mediation rules, the sensitive auth files, and the OpenSpec workflow — lives in **[AGENTS.md](AGENTS.md)**.
|
|
326
|
+
|
|
327
|
+
## Acknowledgments
|
|
328
|
+
|
|
329
|
+
- [Google Gemini](https://gemini.google.com) — the model and web app this CLI wraps
|
|
330
|
+
- [Bun](https://bun.sh) — runtime, bundler, and the path to single-binary distribution
|
|
331
|
+
- [`@playwright/cli`](https://www.npmjs.com/package/@playwright/cli) — the headless browser that powers authentication
|
|
332
|
+
- [OpenCode](https://opencode.ai) and the broader AI-agent ecosystem — for the `debate-with-gemini` use case that inspired the skills bundle
|
|
333
|
+
- [`opencode-gemiterm-skills`](https://www.npmjs.com/package/opencode-gemiterm-skills) — the agent-skills companion package
|
|
334
|
+
|
|
335
|
+
## License
|
|
267
336
|
|
|
268
|
-
|
|
337
|
+
[MIT](LICENSE.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gemiterm",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0-beta.1",
|
|
4
4
|
"module": "index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -42,10 +42,12 @@
|
|
|
42
42
|
"build:release": "bun run scripts/build.ts release"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
+
"@inquirer/testing": "^2.1.0",
|
|
45
46
|
"@types/bun": "^1.3.14",
|
|
46
47
|
"typescript": "^6.0.3"
|
|
47
48
|
},
|
|
48
49
|
"dependencies": {
|
|
50
|
+
"@inquirer/prompts": "^8.5.2",
|
|
49
51
|
"chalk": "^5.6.2",
|
|
50
52
|
"cli-table3": "^0.6.5",
|
|
51
53
|
"commander": "^15.0.0",
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import { createInterface } from "node:readline";
|
|
3
2
|
import type { CliCommand, CliCommandContext } from "../command-registry.ts";
|
|
4
3
|
import { Logger } from "../../infrastructure/logger.ts";
|
|
5
4
|
import { CookieStorage, ProfileManager } from "../../infrastructure/storage.ts";
|
|
@@ -10,6 +9,7 @@ import { getDefaultProfileName, listProfiles, setDefaultProfileName } from "../.
|
|
|
10
9
|
import { GemitermError } from "../../core/errors.ts";
|
|
11
10
|
import { validateProfileName } from "../../infrastructure/validators.ts";
|
|
12
11
|
import { formatProfileTable } from "../../infrastructure/formatters.ts";
|
|
12
|
+
import { text } from "../utils/prompts.ts";
|
|
13
13
|
|
|
14
14
|
export class AuthCommand implements CliCommand {
|
|
15
15
|
readonly name = "auth";
|
|
@@ -90,7 +90,9 @@ export class AuthCommand implements CliCommand {
|
|
|
90
90
|
|
|
91
91
|
switch (choice) {
|
|
92
92
|
case "A": {
|
|
93
|
-
const name = await this.promptInput("Enter profile name"
|
|
93
|
+
const name = await this.promptInput("Enter profile name", {
|
|
94
|
+
validate: (v) => /^[a-zA-Z0-9_-]+$/.test(v) || "Invalid profile name",
|
|
95
|
+
});
|
|
94
96
|
validateProfileName(name.trim());
|
|
95
97
|
if (listProfiles().includes(name.trim())) {
|
|
96
98
|
throw new GemitermError(`Profile '${name.trim()}' already exists.`);
|
|
@@ -131,7 +133,9 @@ export class AuthCommand implements CliCommand {
|
|
|
131
133
|
if (!profiles.includes(oldTrimmed)) {
|
|
132
134
|
throw new GemitermError(`Profile '${oldTrimmed}' does not exist.`);
|
|
133
135
|
}
|
|
134
|
-
const newName = await this.promptInput("Enter new profile name"
|
|
136
|
+
const newName = await this.promptInput("Enter new profile name", {
|
|
137
|
+
validate: (v) => /^[a-zA-Z0-9_-]+$/.test(v) || "Invalid profile name",
|
|
138
|
+
});
|
|
135
139
|
const newTrimmed = newName.trim();
|
|
136
140
|
validateProfileName(newTrimmed);
|
|
137
141
|
profileManager.rename(oldTrimmed, newTrimmed);
|
|
@@ -167,13 +171,10 @@ export class AuthCommand implements CliCommand {
|
|
|
167
171
|
console.log(" -h, --help Show this help message");
|
|
168
172
|
}
|
|
169
173
|
|
|
170
|
-
private promptInput(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
resolve(answer);
|
|
176
|
-
});
|
|
177
|
-
});
|
|
174
|
+
private promptInput(
|
|
175
|
+
prompt: string,
|
|
176
|
+
opts?: { validate?: (value: string) => boolean | string },
|
|
177
|
+
): Promise<string> {
|
|
178
|
+
return text({ message: prompt, validate: opts?.validate });
|
|
178
179
|
}
|
|
179
180
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import {
|
|
2
|
+
import { confirm } from "../utils/prompts.ts";
|
|
3
3
|
import type { CliCommand, CliCommandContext } from "../command-registry.ts";
|
|
4
4
|
import type { Mediator, Command } from "../../core/mediator.ts";
|
|
5
5
|
import { Logger } from "../../infrastructure/logger.ts";
|
|
@@ -126,17 +126,8 @@ export class DeleteCommand implements CliCommand {
|
|
|
126
126
|
return options;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
private promptConfirmation(
|
|
130
|
-
return
|
|
131
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
132
|
-
rl.question(
|
|
133
|
-
`${chalk.cyan(`Delete conversation '${conversationId}'?`)} (yes/no): `,
|
|
134
|
-
(answer) => {
|
|
135
|
-
rl.close();
|
|
136
|
-
resolve(answer.toLowerCase().startsWith("y"));
|
|
137
|
-
},
|
|
138
|
-
);
|
|
139
|
-
});
|
|
129
|
+
private promptConfirmation(question: string): Promise<boolean> {
|
|
130
|
+
return confirm({ message: question, default: false });
|
|
140
131
|
}
|
|
141
132
|
|
|
142
133
|
private showUsage(): void {
|