gemiterm 2.0.0 → 2.1.0

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 (150) hide show
  1. package/README.md +32 -9
  2. package/package.json +13 -4
  3. package/src/cli/command-registry.ts +66 -62
  4. package/src/cli/commands/install-skills-command.ts +35 -0
  5. package/src/cli/index.ts +19 -44
  6. package/src/infrastructure/cli-parser.ts +77 -0
  7. package/src/services/skills-cli-driver.ts +58 -0
  8. package/src/services/skills-service.ts +52 -0
  9. package/.env +0 -2
  10. package/.github/workflows/manual-release.yml +0 -34
  11. package/.github/workflows/release.yml +0 -198
  12. package/.github/workflows/test.yml +0 -29
  13. package/.opencode/commands/opsx-apply.md +0 -152
  14. package/.opencode/commands/opsx-archive.md +0 -157
  15. package/.opencode/commands/opsx-explore.md +0 -169
  16. package/.opencode/commands/opsx-propose.md +0 -104
  17. package/.opencode/commands/opsx-sync.md +0 -140
  18. package/.opencode/commands/search-intelligently.md +0 -9
  19. package/.opencode/opencode.json +0 -20
  20. package/.opencode/skills/intellisearch/.version +0 -1
  21. package/.opencode/skills/intellisearch/SKILL.md +0 -84
  22. package/.opencode/skills/intellisearch/references/brave-search.md +0 -67
  23. package/.opencode/skills/intellisearch/references/ddg-search.md +0 -79
  24. package/.opencode/skills/intellisearch/references/deepwiki-tools.md +0 -246
  25. package/.opencode/skills/intellisearch/references/examples.md +0 -97
  26. package/.opencode/skills/intellisearch/references/gh-cli.md +0 -143
  27. package/.opencode/skills/intellisearch/references/google-search.md +0 -40
  28. package/.opencode/skills/intellisearch/references/search-workflow.md +0 -143
  29. package/.opencode/skills/intellisearch/references/workflow.md +0 -115
  30. package/.opencode/skills/openspec-apply-change/SKILL.md +0 -159
  31. package/.opencode/skills/openspec-archive-change/SKILL.md +0 -117
  32. package/.opencode/skills/openspec-explore/SKILL.md +0 -287
  33. package/.opencode/skills/openspec-propose/SKILL.md +0 -111
  34. package/.opencode/skills/openspec-sync-specs/SKILL.md +0 -147
  35. package/.serena/project.yml +0 -133
  36. package/AGENTS.md +0 -136
  37. package/CHANGELOG.md +0 -3
  38. package/bun.lock +0 -105
  39. package/docs/INSTALL.md +0 -185
  40. package/docs/PLAYWRIGHT_CLI_API.md +0 -306
  41. package/docs/python-release-for-reference.md +0 -175
  42. package/examples/sample_json_export.json +0 -32
  43. package/examples/sample_markdown_export.md +0 -221
  44. package/examples/usage_examples.sh +0 -222
  45. package/install.ps1 +0 -264
  46. package/install.sh +0 -275
  47. package/openspec/MAESTRO_MIGRATION.md +0 -180
  48. package/openspec/changes/archive/2026-06-08-command-spec-conformance/.openspec.yaml +0 -2
  49. package/openspec/changes/archive/2026-06-08-command-spec-conformance/design.md +0 -194
  50. package/openspec/changes/archive/2026-06-08-command-spec-conformance/proposal.md +0 -52
  51. package/openspec/changes/archive/2026-06-08-command-spec-conformance/specs/multi-profile-conversations/spec.md +0 -133
  52. package/openspec/changes/archive/2026-06-08-command-spec-conformance/tasks.md +0 -95
  53. package/openspec/changes/archive/2026-06-09-refactor-interactive-prompt-loop/.openspec.yaml +0 -2
  54. package/openspec/changes/archive/2026-06-09-refactor-interactive-prompt-loop/design.md +0 -28
  55. package/openspec/changes/archive/2026-06-09-refactor-interactive-prompt-loop/proposal.md +0 -22
  56. package/openspec/changes/archive/2026-06-09-refactor-interactive-prompt-loop/specs/interactive-prompt-loop/spec.md +0 -35
  57. package/openspec/changes/archive/2026-06-09-refactor-interactive-prompt-loop/tasks.md +0 -28
  58. package/openspec/changes/archive/2026-06-09-replace-gemini-api-placeholder-with-gemini-reverse/.openspec.yaml +0 -2
  59. package/openspec/changes/archive/2026-06-09-replace-gemini-api-placeholder-with-gemini-reverse/design.md +0 -323
  60. package/openspec/changes/archive/2026-06-09-replace-gemini-api-placeholder-with-gemini-reverse/proposal.md +0 -122
  61. package/openspec/changes/archive/2026-06-09-replace-gemini-api-placeholder-with-gemini-reverse/specs/no-capability-changes/spec.md +0 -29
  62. package/openspec/changes/archive/2026-06-09-replace-gemini-api-placeholder-with-gemini-reverse/tasks.md +0 -172
  63. package/openspec/changes/archive/2026-06-09-v2-install-migration/.openspec.yaml +0 -2
  64. package/openspec/changes/archive/2026-06-09-v2-install-migration/design.md +0 -241
  65. package/openspec/changes/archive/2026-06-09-v2-install-migration/proposal.md +0 -41
  66. package/openspec/changes/archive/2026-06-09-v2-install-migration/specs/v2-installer/spec.md +0 -205
  67. package/openspec/changes/archive/2026-06-09-v2-install-migration/tasks.md +0 -97
  68. package/openspec/changes/commander-cli-parser/.openspec.yaml +0 -2
  69. package/openspec/changes/commander-cli-parser/design.md +0 -107
  70. package/openspec/changes/commander-cli-parser/proposal.md +0 -31
  71. package/openspec/changes/commander-cli-parser/specs/cli/spec.md +0 -48
  72. package/openspec/changes/commander-cli-parser/tasks.md +0 -33
  73. package/openspec/changes/cross-platform-build-and-ci/.openspec.yaml +0 -2
  74. package/openspec/changes/cross-platform-build-and-ci/design.md +0 -213
  75. package/openspec/changes/cross-platform-build-and-ci/proposal.md +0 -50
  76. package/openspec/changes/cross-platform-build-and-ci/specs/path-and-file-mediation/spec.md +0 -335
  77. package/openspec/changes/cross-platform-build-and-ci/specs/release-pipeline/spec.md +0 -95
  78. package/openspec/changes/cross-platform-build-and-ci/tasks.md +0 -164
  79. package/openspec/config.yaml +0 -20
  80. package/openspec/specs/auth/spec.md +0 -394
  81. package/openspec/specs/cli/spec.md +0 -108
  82. package/openspec/specs/commands/spec.md +0 -409
  83. package/openspec/specs/configuration/spec.md +0 -130
  84. package/openspec/specs/conversations/spec.md +0 -139
  85. package/openspec/specs/domain-model/spec.md +0 -128
  86. package/openspec/specs/formatters/spec.md +0 -158
  87. package/openspec/specs/install-browser/spec.md +0 -146
  88. package/openspec/specs/interactive-prompt-loop/spec.md +0 -41
  89. package/openspec/specs/logger/spec.md +0 -71
  90. package/openspec/specs/mediator/spec.md +0 -72
  91. package/openspec/specs/multi-profile-conversations/spec.md +0 -145
  92. package/openspec/specs/path-utils/spec.md +0 -101
  93. package/openspec/specs/profiles/spec.md +0 -94
  94. package/openspec/specs/storage/spec.md +0 -198
  95. package/openspec/specs/testing/spec.md +0 -237
  96. package/openspec/specs/v2-installer/spec.md +0 -205
  97. package/openspec/specs/validators/spec.md +0 -65
  98. package/scripts/build.ts +0 -88
  99. package/scripts/clean-build.ps1 +0 -4
  100. package/scripts/clean-build.sh +0 -5
  101. package/scripts/install-browser.ps1 +0 -5
  102. package/scripts/install-browser.sh +0 -6
  103. package/scripts/lint-path-mediation.ps1 +0 -65
  104. package/scripts/lint-path-mediation.sh +0 -40
  105. package/tests/cli/auth-command.test.ts +0 -220
  106. package/tests/cli/command-registry.test.ts +0 -67
  107. package/tests/cli/continue-command.test.ts +0 -100
  108. package/tests/cli/delete-command.test.ts +0 -128
  109. package/tests/cli/export-all-command.test.ts +0 -375
  110. package/tests/cli/install-browser-command.test.ts +0 -48
  111. package/tests/cli/list-command.test.ts +0 -179
  112. package/tests/cli/new-command.test.ts +0 -139
  113. package/tests/cli/status-command.test.ts +0 -106
  114. package/tests/core/query-handlers.test.ts +0 -187
  115. package/tests/fixtures/auth-fixtures.ts +0 -98
  116. package/tests/fixtures/chat-fixtures.ts +0 -87
  117. package/tests/infrastructure/cli-table.test.ts +0 -107
  118. package/tests/infrastructure/formatters.test.ts +0 -202
  119. package/tests/infrastructure/io.test.ts +0 -197
  120. package/tests/infrastructure/logger.test.ts +0 -74
  121. package/tests/infrastructure/storage.test.ts +0 -335
  122. package/tests/infrastructure/validators.test.ts +0 -67
  123. package/tests/integration/commands/auth.test.ts +0 -186
  124. package/tests/integration/commands/continue.test.ts +0 -130
  125. package/tests/integration/commands/delete.test.ts +0 -140
  126. package/tests/integration/commands/export.test.ts +0 -266
  127. package/tests/integration/commands/fetch.test.ts +0 -238
  128. package/tests/integration/commands/list.test.ts +0 -281
  129. package/tests/integration/commands/profile.test.ts +0 -258
  130. package/tests/integration/commands/status.test.ts +0 -223
  131. package/tests/integration/installer-script-shape.test.ts +0 -67
  132. package/tests/parity/compare-outputs.ts +0 -359
  133. package/tests/parity/test-commands-parity.ps1 +0 -82
  134. package/tests/parity/test-commands-parity.sh +0 -61
  135. package/tests/services/auth-service.test.ts +0 -315
  136. package/tests/services/cookie-monitor.test.ts +0 -229
  137. package/tests/services/cookie-storage-service.test.ts +0 -230
  138. package/tests/services/gemini-client-wrapper.test.ts +0 -688
  139. package/tests/services/install-browser-service.test.ts +0 -83
  140. package/tests/services/playwright-cli-driver.test.ts +0 -468
  141. package/tests/services/profile-auth-manager.test.ts +0 -334
  142. package/tests/services/profile-service.test.ts +0 -224
  143. package/tests/setup.ts +0 -95
  144. package/tests/smoke/smoke.test.ts +0 -52
  145. package/tests/unit/config.test.ts +0 -159
  146. package/tests/unit/errors.test.ts +0 -119
  147. package/tests/unit/formatters.test.ts +0 -316
  148. package/tests/unit/mediator.test.ts +0 -152
  149. package/tests/unit/path-utils.test.ts +0 -289
  150. package/tsconfig.json +0 -16
package/docs/INSTALL.md DELETED
@@ -1,185 +0,0 @@
1
- # Installation Guide
2
-
3
- The installer scripts are attached to every GitHub release by the `release.yml` workflow. If you see a 404 on the one-liner URL, the release pipeline (owned by the `cross-platform-build-and-ci` change) may not have attached the scripts; check the GitHub release page directly.
4
-
5
- ## Install
6
-
7
- **Windows** (PowerShell 7+):
8
-
9
- ```powershell
10
- irm https://github.com/expert-vision-software/GemiTerm/releases/latest/download/install.ps1 | iex
11
- ```
12
-
13
- **Linux / WSL**:
14
-
15
- ```bash
16
- curl -fsSL https://github.com/expert-vision-software/GemiTerm/releases/latest/download/install.sh | bash
17
- ```
18
-
19
- > **Recommended install via package manager.** If you have `bun` or `npm` on PATH, the installer will detect it and prompt: "It is recommended to install via bun or npm package manager. Are you sure you want to continue with binary install?" Answer `y` to proceed with the binary drop, or install via:
20
- > - `bun i -g gemiterm`
21
- > - `npm i -g gemiterm`
22
- >
23
- > The prompt is suppressed when stdin is not a TTY (e.g. the `curl | bash` one-liner flow), so unattended installs proceed.
24
-
25
- ## Upgrade from v1.4.1
26
-
27
- Your profiles, cookies, and default-profile marker are preserved. The installer replaces the binary in place; it does **NOT** touch `%APPDATA%\gemiterm\` (Windows) or `~/gemiterm/` (POSIX). This is verified by the path-resolution logic in `src/infrastructure/path-utils.ts` — the v2.0.0 binary reads from the same config directory that v1.4.1 wrote to.
28
-
29
- On Windows, the v1.4.1 Python config lived at `%USERPROFILE%\.config\gemiterm\` (Python's `Path.home() / ".config/gemiterm"` has no Windows branch). When the installer detects a v1.4.1 config at that path and no v2.0.0 config at `%APPDATA%\gemiterm\`, it copies the tree forward automatically. The v1.4.1 directory is left in place as a safety net — you can delete it manually after verifying the migration.
30
-
31
- On POSIX, the v1.4.1 Python config lived at `~/.config/gemiterm/`. v2.0.0 reads from `~/gemiterm/`. The installer performs the same one-time copy-forward when it detects the old path.
32
-
33
- If you have the Python v1.4.1 version installed via `pip`, the installer will detect it and ask you to run `pip uninstall gemiterm` first. Your config data is safe and will be preserved through the uninstall/reinstall cycle.
34
-
35
- ## Uninstall
36
-
37
- **Windows**:
38
-
39
- ```powershell
40
- pwsh -File install.ps1 -Uninstall
41
- ```
42
-
43
- **Linux / WSL**:
44
-
45
- ```bash
46
- bash install.sh --uninstall
47
- ```
48
-
49
- Uninstall removes the binary and PATH entry but **preserves** your config directory (profiles, cookies, default-profile marker). Re-installing afterward will find the same profiles as before.
50
-
51
- ## Data Paths
52
-
53
- | Path | Windows | Linux / WSL |
54
- |------|---------|-------------|
55
- | **Binary** | `$env:LOCALAPPDATA\GemiTerm\GemiTerm.exe` | `~/.local/bin/gemiterm` |
56
- | **Config** | `%APPDATA%\gemiterm\` | `~/gemiterm/` |
57
- | **Chromium cache** | `$env:LOCALAPPDATA\ms-playwright\` | `~/.cache/ms-playwright/` |
58
-
59
- > **Note:** On Windows, the install directory is **capital G** (`GemiTerm`) while the config directory is **lowercase** (`gemiterm`). This matches the v1.4.1 convention and is intentional.
60
-
61
- ## Tag Override (Canary / RC Installs)
62
-
63
- To install a specific release instead of the latest:
64
-
65
- **Windows**:
66
-
67
- ```powershell
68
- pwsh -File install.ps1 -Tag v2.0.0-rc.1
69
- ```
70
-
71
- **Linux / WSL**:
72
-
73
- ```bash
74
- GEMITERM_TAG=v2.0.0-rc.1 bash install.sh
75
- ```
76
-
77
- ## Custom Install Directory
78
-
79
- **Windows**:
80
-
81
- ```powershell
82
- pwsh -File install.ps1 -InstallDir D:\Tools\GemiTerm
83
- ```
84
-
85
- **Linux / WSL**:
86
-
87
- ```bash
88
- GEMITERM_INSTALL_DIR=~/.local/bin bash install.sh
89
- ```
90
-
91
- ## Troubleshooting
92
-
93
- ### PATH did not refresh in current shell
94
-
95
- After installing, if `gemiterm` is not found:
96
-
97
- **Windows** — reload your PATH in the current PowerShell session:
98
-
99
- ```powershell
100
- $env:Path = [Environment]::GetEnvironmentVariable('Path', 'User')
101
- gemiterm --version
102
- ```
103
-
104
- Or open a new terminal.
105
-
106
- **Linux / WSL** — source the env snippet:
107
-
108
- ```bash
109
- source ~/gemiterm/env.sh
110
- gemiterm --version
111
- ```
112
-
113
- Or open a new terminal.
114
-
115
- ### Chromium installation fails
116
-
117
- The installer runs `bunx @playwright/cli install chromium` as part of the install flow. If it fails:
118
-
119
- 1. Check your network connection (Chromium is ~100 MB).
120
- 2. Re-run the installer.
121
- 3. Or manually run: `bunx @playwright/cli install chromium`
122
-
123
- ### Cannot reach GitHub releases
124
-
125
- If the installer cannot contact `api.github.com`:
126
-
127
- 1. Check your network connection.
128
- 2. Use the **Build from source** instructions below.
129
-
130
- ### Bun not installed
131
-
132
- The installer automatically bootstraps [Bun](https://bun.sh) if it is not found. If the bootstrap fails:
133
-
134
- 1. Install Bun manually from [bun.sh](https://bun.sh).
135
- 2. Re-run the installer.
136
-
137
- ### fish / nushell users
138
-
139
- The POSIX installer appends a `source` line to `~/.bashrc` and `~/.zshrc`. For other shells, add the PATH manually:
140
-
141
- **fish** (`~/.config/fish/config.fish`):
142
-
143
- ```fish
144
- set -gx PATH ~/.local/bin $PATH
145
- ```
146
-
147
- **nushell** (`~/.config/nushell/config.nu`):
148
-
149
- ```nu
150
- $env.PATH = ($env.PATH | prepend ~/.local/bin)
151
- ```
152
-
153
- ## Build from Source
154
-
155
- Requires [Bun](https://bun.sh) 1.3.13 or later.
156
-
157
- ```bash
158
- git clone https://github.com/expert-vision-software/GemiTerm.git
159
- cd GemiTerm
160
- bun install
161
- bun run build
162
- ```
163
-
164
- The resulting binary is at `dist/gemiterm` (Linux/macOS) or `dist/gemiterm.exe` (Windows). Move it to the install path:
165
-
166
- **Linux / WSL**:
167
-
168
- ```bash
169
- mkdir -p ~/.local/bin
170
- mv dist/gemiterm ~/.local/bin/gemiterm
171
- chmod +x ~/.local/bin/gemiterm
172
- ```
173
-
174
- **Windows**:
175
-
176
- ```powershell
177
- mkdir $env:LOCALAPPDATA\GemiTerm
178
- Move-Item dist\gemiterm.exe $env:LOCALAPPDATA\GemiTerm\GemiTerm.exe
179
- ```
180
-
181
- Then install Chromium:
182
-
183
- ```bash
184
- bunx @playwright/cli install chromium
185
- ```
@@ -1,306 +0,0 @@
1
- # playwright-cli API Reference
2
-
3
- > Source: [microsoft/playwright-cli](https://github.com/microsoft/playwright-cli)
4
- > Verified against: `@playwright/cli` (installed via `bunx --bun @playwright/cli --help`)
5
-
6
- ## Architecture
7
-
8
- - **Daemon-based**: `open` returns immediately; the browser runs as a background process.
9
- - **Session-based**: Every command targets a browser session via `-s=<name>`. Without `-s`, commands hit the unnamed **default session**.
10
- - **Session resolution priority**: `-s=<name>` flag → `PLAYWRIGHT_CLI_SESSION` env var → default session.
11
-
12
- ## Session Management
13
-
14
- ```bash
15
- playwright-cli list # list all active sessions
16
- playwright-cli -s=myprofile list # list details for one session
17
- playwright-cli close # close the default session
18
- playwright-cli close-all # close all sessions gracefully
19
- playwright-cli kill-all # force-kill all sessions
20
- playwright-cli delete-data # wipe persistent profile data for a session
21
- ```
22
-
23
- ## Core Commands
24
-
25
- ### `open [url]`
26
-
27
- Opens a headed browser and navigates to the URL. **Returns immediately** (daemon-style).
28
-
29
- ```bash
30
- playwright-cli open https://example.com
31
- playwright-cli -s=myprofile open --browser=chromium --headed --persistent --profile=/path/to/dir https://example.com
32
- ```
33
-
34
- | Flag | Description | Values |
35
- |---|---|---|
36
- | `--browser` | Browser engine | `chromium`, `firefox`, `webkit`, `msedge` |
37
- | `--headed` | Show the browser UI (default: headless) | flag |
38
- | `--persistent` | Persist profile to disk on close | flag |
39
- | `--profile=<path>` | Custom user-data directory path | absolute path |
40
- | `--config=<file>` | Path to config file | default: `.playwright/cli.config.json` |
41
- | `--extension` | Connect via browser extension | flag |
42
-
43
- ### `goto <url>`
44
-
45
- Navigate the current session to a URL (must target an open session):
46
-
47
- ```bash
48
- playwright-cli -s=myprofile goto https://other.example.com
49
- ```
50
-
51
- ### `close` / `detach` / `attach`
52
-
53
- ```bash
54
- playwright-cli -s=myprofile close # graceful close
55
- playwright-cli -s=myprofile detach # detach CLI but keep browser running
56
- playwright-cli attach myprofile # re-attach to a running session
57
- ```
58
-
59
- ## Input Commands
60
-
61
- All input commands target an active session and operate on element references obtained from `snapshot`.
62
-
63
- ```bash
64
- playwright-cli -s=myprofile click <ref> [button]
65
- playwright-cli -s=myprofile type <text>
66
- playwright-cli -s=myprofile fill <ref> <text>
67
- playwright-cli -s=myprofile press <key> # e.g. Enter, Tab, Escape
68
- playwright-cli -s=myprofile hover <ref>
69
- playwright-cli -s=myprofile select <ref> <val>
70
- playwright-cli -s=myprofile upload <file>
71
- playwright-cli -s=myprofile check <ref> / uncheck <ref>
72
- playwright-cli -s=myprofile drag <startRef> <endRef>
73
- playwright-cli -s=myprofile drop <ref>
74
- playwright-cli -s=myprofile dialog-accept [prompt]
75
- playwright-cli -s=myprofile dialog-dismiss
76
- ```
77
-
78
- ## Storage & State Commands
79
-
80
- ### `state-save [filename]`
81
-
82
- Exports the current session's cookies + localStorage to a JSON file. **Writes directly to disk.**
83
-
84
- ```bash
85
- playwright-cli -s=myprofile state-save auth.json
86
- playwright-cli -s=myprofile state-save # auto-name: storage-state-{timestamp}.json
87
- ```
88
-
89
- The output JSON matches Playwright's `StorageState` format:
90
-
91
- ```jsonc
92
- {
93
- "cookies": [{ "name": "...", "value": "...", "domain": "...", "path": "/", "expires": -1, "httpOnly": true, "secure": true, "sameSite": "Lax" }],
94
- "origins": [{ "origin": "https://example.com", "localStorage": [{ "name": "...", "value": "..." }] }]
95
- }
96
- ```
97
-
98
- ### `state-load <filename>`
99
-
100
- Imports cookies and localStorage from a JSON file into the current session. **Must be called after the browser is open.**
101
-
102
- ```bash
103
- playwright-cli -s=myprofile state-load auth.json
104
- ```
105
-
106
- ### `cookie-list` / `cookie-get` / `cookie-set` / `cookie-delete` / `cookie-clear`
107
-
108
- ```bash
109
- playwright-cli -s=myprofile cookie-list # text table output
110
- playwright-cli -s=myprofile cookie-list --json # JSON output
111
- playwright-cli -s=myprofile cookie-list --domain=google.com # filter by domain
112
- playwright-cli -s=myprofile cookie-get "__Secure-1PSID"
113
- playwright-cli -s=myprofile cookie-set "name" "value" --domain=.example.com --secure --httpOnly
114
- playwright-cli -s=myprofile cookie-delete "name"
115
- playwright-cli -s=myprofile cookie-clear
116
- ```
117
-
118
- **Important**: `cookie-list` outputs a human-readable text table by default. The `--json` flag (undocumented in `--help`, silently supported) wraps that text in a JSON object: `{"result": "<text>"}` — it does **not** emit a JSON array of cookie objects. See [Cookie-list output format](#cookie-list-output-format) below for the real shapes.
119
-
120
- ### Cookie-list output format
121
-
122
- `cookie-list` is one of the most-misused commands because `--json` does not return what its name suggests.
123
-
124
- **Default output (no flag)** — one cookie per line, no header:
125
- ```
126
- __Secure-1PSID=abc123 (domain: .google.com, path: /)
127
- __Secure-1PSIDTS=xyz789 (domain: .google.com, path: /)
128
- ```
129
-
130
- **With `--json`** — single-line wrapper whose `result` field is the same text as above:
131
- ```json
132
- {"result": "__Secure-1PSID=abc123 (domain: .google.com, path: /)\n__Secure-1PSIDTS=xyz789 (domain: .google.com, path: /)\n"}
133
- ```
134
-
135
- **Empty state** — the literal line `No cookies found` (and with `--json`, `{"result": "No cookies found\n"}`).
136
-
137
- **What's missing from the text format:** `expires`, `httpOnly`, `secure`, `sameSite`. If you need those, use `run-code` with `page.context().cookies()` or call `state-save` and parse the resulting file.
138
-
139
- **Note:** `--json` is not listed in `cookie-list --help` but is silently supported. Verified in `@playwright/cli` v0.1.13.
140
-
141
- ## Evaluation & Snapshots
142
-
143
- ### `eval <func> [ref]`
144
-
145
- Run JavaScript on the page and print the result.
146
-
147
- ```bash
148
- playwright-cli -s=myprofile eval "document.title"
149
- playwright-cli -s=myprofile eval "document.querySelector('textarea') !== null"
150
- playwright-cli -s=myprofile eval "window.location.href"
151
- ```
152
-
153
- ### `snapshot [target]`
154
-
155
- Captures a page snapshot for obtaining element references. **Returns YAML/HTML, NOT JSON.**
156
-
157
- ```bash
158
- playwright-cli -s=myprofile snapshot # full page → stdout/YAML
159
- playwright-cli -s=myprofile snapshot --filename=snap.yaml # save to file
160
- playwright-cli -s=myprofile snapshot "div.main" # target a specific element
161
- ```
162
-
163
- > ⚠️ `snapshot` does **not** return an accessibility (AX) tree. Use `eval` with DOM queries for conditional logic like login detection.
164
-
165
- ### `run-code [code]`
166
-
167
- Run a Playwright code snippet with access to the `page` object.
168
-
169
- ```bash
170
- playwright-cli -s=myprofile run-code "async page => {
171
- const title = await page.title();
172
- return title;
173
- }"
174
- ```
175
-
176
- ## Navigation Commands
177
-
178
- ```bash
179
- playwright-cli -s=myprofile go-back
180
- playwright-cli -s=myprofile go-forward
181
- playwright-cli -s=myprofile reload
182
- ```
183
-
184
- ## Tab Management
185
-
186
- ```bash
187
- playwright-cli -s=myprofile tab-list
188
- playwright-cli -s=myprofile tab-new [url]
189
- playwright-cli -s=myprofile tab-close [index]
190
- playwright-cli -s=myprofile tab-select <index>
191
- ```
192
-
193
- ## Global Flags
194
-
195
- | Flag | Description |
196
- |---|---|
197
- | `-s=<name>` | Target a named session |
198
- | `--json` | Output as JSON (applies to most read commands) |
199
- | `--raw` | Output only the value, no status wrapper |
200
- | `--config=<file>` | Use a specific config file |
201
- | `--help [command]` | Show help |
202
- | `--version` | Print version |
203
-
204
- ## Configuration File
205
-
206
- Located at `.playwright/cli.config.json` by default:
207
-
208
- ```jsonc
209
- {
210
- "browser": {
211
- "browserName": "chromium", // chromium | firefox | webkit
212
- "isolated": false, // true = in-memory only (no persistence)
213
- "userDataDir": "/path/to/dir", // persistent profile directory
214
- "launchOptions": {
215
- "headless": false,
216
- "channel": "chrome", // use system Chrome instead of bundled Chromium
217
- "executablePath": "/path/to/browser"
218
- },
219
- "contextOptions": {
220
- "viewport": { "width": 1280, "height": 720 }
221
- }
222
- },
223
- "outputDir": "./output",
224
- "outputMode": "stdout", // stdout | file
225
- "console": { "level": "info" },
226
- "testIdAttribute": "data-testid"
227
- }
228
- ```
229
-
230
- ## Output Format Reference
231
-
232
- | Command | Default Output | With `--json` |
233
- |---|---|---|
234
- | `cookie-list` | Text table (name, value, domain, flags) | JSON wrapper `{"result": "<text>"}` (not an array) |
235
- | `snapshot` | YAML/HTML (not AX tree) | JSON status wrapper |
236
- | `state-save` | Writes file to disk, confirmation on stdout | N/A |
237
- | `eval` | Raw JS return value | JSON status wrapper |
238
- | `list` | Text session info | JSON session objects |
239
-
240
- ## Persistence Behavior
241
-
242
- - `--persistent` / `--profile=<dir>`: Profile data is **automatically saved** when the browser closes. Reopening with the same profile preserves cookies, localStorage, etc.
243
- - `state-save`: **Explicit export** to a portable JSON file. Needed when you want to share state across different profile directories or import into non-CLI Playwright contexts.
244
- - For cookie scraping: use `state-save` to export to `.auth/<profile>.json`. The persistent profile is only for the browser's own session continuity.
245
-
246
- ## Common Patterns
247
-
248
- ### Login Detection (eval)
249
-
250
- ```bash
251
- # Check for Gemini prompt textarea
252
- playwright-cli -s=gemini eval "document.querySelector('textarea[aria-label*=\"prompt\" i]') !== null"
253
-
254
- # Check URL
255
- playwright-cli -s=gemini eval "window.location.href"
256
- ```
257
-
258
- > Tip: cookie-based detection (poll `cookie-list` for `__Secure-1PSID`) is more reliable than DOM probes because cookies are observable even when the page is still mid-render. See [Cookie-list output format](#cookie-list-output-format) for how to parse the response.
259
-
260
- ### Cookie Scraping Pipeline
261
-
262
- ```bash
263
- # 1. Open headed browser with persistent profile
264
- playwright-cli -s=mysess open --headed --persistent --profile=./.auth/profiles/gemini https://gemini.google.com/app
265
-
266
- # 2. User logs in manually...
267
-
268
- # 3. Export state to portable JSON
269
- playwright-cli -s=mysess state-save .auth/gemini.json
270
-
271
- # 4. Close the session
272
- playwright-cli -s=mysess close
273
- ```
274
-
275
- ### Re-verify a Saved Login
276
-
277
- ```bash
278
- # 1. Open browser (can use same persistent profile or fresh)
279
- playwright-cli -s=mysess open --headed https://gemini.google.com/app
280
-
281
- # 2. Inject saved state
282
- playwright-cli -s=mysess state-load .auth/gemini.json
283
-
284
- # 3. Reload page to apply cookies
285
- playwright-cli -s=mysess reload
286
-
287
- ## Common Pitfalls
288
-
289
- Things that look right but will silently break your code. Verified against `@playwright/cli` v0.1.13.
290
-
291
- ### `cookie-list --json` is not a JSON array
292
-
293
- It's a wrapper `{"result": "<text>"}` around the same human-readable text. Calling `JSON.parse` and treating the result as an array will always yield zero cookies, and your login detection will time out without any visible error. See [Cookie-list output format](#cookie-list-output-format).
294
-
295
- ### `eval` results are wrapped unless you pass `--raw`
296
-
297
- `playwright-cli -s=X eval "..."` returns a JSON status envelope, e.g. `{"status":"success","result":"..."}`. To get the raw return value, append `--raw`. Required whenever you compare an eval result to a literal string (e.g. `=== "true"`).
298
-
299
- ### `open` is fire-and-forget (daemon-style)
300
-
301
- `playwright-cli open <url>` returns as soon as the browser process has been launched, not when the page is loaded. If you start polling the session immediately after, your first `eval` / `cookie-list` may race the still-spawning daemon and throw. Either delay the first poll or use the `state-save` round-trip to wait for the page to be ready.
302
-
303
- ### `--profile` requires an absolute path
304
-
305
- Relative paths are accepted by the CLI but the resulting profile directory is not portable across working directories and may not be picked up by subsequent runs.
306
- ```
@@ -1,175 +0,0 @@
1
- name: Release
2
-
3
- on:
4
- push:
5
- tags:
6
- - 'v*'
7
- workflow_dispatch:
8
- inputs:
9
- skip_publish:
10
- description: 'Skip PyPI publish (for testing)'
11
- type: boolean
12
- default: false
13
- skip_release:
14
- description: 'Skip GitHub release (for testing)'
15
- type: boolean
16
- default: true
17
- tag:
18
- description: 'Tag for release (e.g. v1.0.8) - only needed for workflow_dispatch'
19
- type: string
20
- default: ''
21
-
22
- jobs:
23
- test:
24
- name: Test
25
- runs-on: ubuntu-latest
26
- steps:
27
- - uses: actions/checkout@v4
28
- - uses: actions/setup-python@v5
29
- with:
30
- python-version: '3.12'
31
- - name: Install deps
32
- run: |
33
- pip install -e ".[dev]"
34
- - name: Run tests
35
- run: pytest -v
36
-
37
- build-linux:
38
- name: Build (Linux)
39
- needs: test
40
- runs-on: ubuntu-latest
41
-
42
- steps:
43
- - uses: actions/checkout@v4
44
- - uses: actions/setup-python@v5
45
- with:
46
- python-version: '3.12'
47
-
48
- - name: Build package
49
- run: pip install build && python -m build
50
-
51
- - name: Install dependencies
52
- run: pip install rich click playwright gemini-webapi pyinstaller
53
-
54
- - name: Build executable
55
- run: |
56
- pythonPath=$(python -c "import site; print(site.getsitepackages()[0])")
57
- pyinstaller --onefile --name GemiTerm --add-data "src/gemiterm:gemiterm" --paths "$pythonPath" --hidden-import=rich --hidden-import=rich.console --hidden-import=rich.progress --hidden-import=rich.table --hidden-import=rich.panel --hidden-import=rich.markdown --hidden-import=rich.syntax --hidden-import=click --hidden-import=playwright --hidden-import=gemini_webapi --hidden-import=gemini_webapi_async src/gemiterm/__main__.py
58
-
59
- - name: Verify build
60
- run: |
61
- exeSize=$(stat -c%s dist/GemiTerm)
62
- exeSizeMB=$((exeSize / 1024 / 1024))
63
- echo "GemiTerm size: $exeSizeMB MB"
64
- if [ "$exeSizeMB" -lt 20 ]; then
65
- echo "ERROR: Exe is too small ($exeSizeMB MB). Dependencies may not be bundled."
66
- exit 1
67
- fi
68
- echo "Build verification passed"
69
-
70
- - name: Upload artifact
71
- uses: actions/upload-artifact@v4
72
- with:
73
- name: GemiTerm
74
- path: dist/GemiTerm
75
-
76
- build-windows:
77
- name: Build (Windows)
78
- needs: test
79
- runs-on: windows-latest
80
-
81
- steps:
82
- - uses: actions/checkout@v4
83
- - uses: actions/setup-python@v5
84
- with:
85
- python-version: '3.12'
86
-
87
- - name: Build package
88
- run: pip install build && python -m build
89
-
90
- - name: Install dependencies
91
- run: pip install rich click playwright gemini-webapi pyinstaller
92
-
93
- - name: Build executable
94
- run: |
95
- $pythonPath = python -c "import site; print(site.getsitepackages()[0])"
96
- pyinstaller --onefile --name GemiTerm --add-data "src/gemiterm;gemiterm" --paths "$pythonPath" --hidden-import=rich --hidden-import=rich.console --hidden-import=rich.progress --hidden-import=rich.table --hidden-import=rich.panel --hidden-import=rich.markdown --hidden-import=rich.syntax --hidden-import=click --hidden-import=playwright --hidden-import=gemini_webapi --hidden-import=gemini_webapi_async src/gemiterm/__main__.py
97
-
98
- - name: Verify build
99
- run: |
100
- $exeSize = (Get-Item dist/GemiTerm.exe).Length / 1MB
101
- Write-Host "GemiTerm.exe size: $exeSize MB"
102
- if ($exeSize -lt 20) {
103
- Write-Host "ERROR: Exe is too small ($exeSize MB). Dependencies may not be bundled."
104
- exit 1
105
- }
106
- Write-Host "Build verification passed"
107
-
108
- - name: Upload artifact
109
- uses: actions/upload-artifact@v4
110
- with:
111
- name: GemiTerm.exe
112
- path: dist/GemiTerm.exe
113
-
114
- publish:
115
- name: Publish to PyPI
116
- needs: [build-linux, build-windows]
117
- runs-on: ubuntu-latest
118
- if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.skip_publish) }}
119
- permissions:
120
- id-token: write
121
- contents: read
122
-
123
- steps:
124
- - uses: actions/checkout@v4
125
-
126
- - uses: actions/setup-python@v5
127
- with:
128
- python-version: '3.12'
129
-
130
- - name: Build package
131
- run: pip install build && python -m build
132
-
133
- - name: Publish to PyPI
134
- uses: pypa/gh-action-pypi-publish@release/v1
135
- with:
136
- password: ${{ secrets.OIDC_PYPI_TOKEN }}
137
-
138
- release:
139
- name: Create Release
140
- needs: [build-linux, build-windows]
141
- runs-on: ubuntu-latest
142
- if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.skip_release) }}
143
- permissions:
144
- contents: write
145
-
146
- steps:
147
- - uses: actions/checkout@v4
148
-
149
- - name: Download Linux binary
150
- uses: actions/download-artifact@v4
151
- with:
152
- name: GemiTerm
153
- path: dist
154
-
155
- - name: Download Windows binary
156
- uses: actions/download-artifact@v4
157
- with:
158
- name: GemiTerm.exe
159
- path: dist
160
-
161
- - name: Determine tag
162
- id: tag
163
- run: |
164
- if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ "${{ inputs.tag }}" != "" ]; then
165
- echo "tag=${{ inputs.tag }}" >> $GITHUB_OUTPUT
166
- else
167
- echo "tag=${{ github.ref_name }}" >> $GITHUB_OUTPUT
168
- fi
169
-
170
- - name: Create Release
171
- uses: softprops/action-gh-release@v2
172
- with:
173
- tag_name: ${{ steps.tag.outputs.tag }}
174
- files: dist/*
175
- generate_release_notes: true
@@ -1,32 +0,0 @@
1
- {
2
- "conversation_id": "sample_conversation_456",
3
- "title": "API Design Discussion",
4
- "export_date": "2026-03-21T15:00:00",
5
- "metadata": {
6
- "message_count": 4,
7
- "first_message": "2026-03-21T14:45:00",
8
- "last_message": "2026-03-21T15:00:00"
9
- },
10
- "messages": [
11
- {
12
- "role": "user",
13
- "content": "What are the best practices for designing a REST API?",
14
- "timestamp": "2026-03-21T14:45:00"
15
- },
16
- {
17
- "role": "model",
18
- "content": "Here are the key REST API best practices:\n\n## 1. Use Proper HTTP Methods\n\n| Method | Usage |\n|--------|-------|\n| GET | Retrieve resources |\n| POST | Create new resources |\n| PUT | Update entire resources |\n| PATCH | Partial updates |\n| DELETE | Remove resources |\n\n## 2. Use Nouns for Endpoints\n\n```\n# Good\nGET /users\nGET /users/123\n\n# Avoid\nGET /getUsers\nGET /user/123\n```\n\n## 3. Use Proper Status Codes\n\n- 200 OK - Success\n- 201 Created - Resource created\n- 400 Bad Request - Invalid input\n- 401 Unauthorized - Not authenticated\n- 404 Not Found - Resource doesn't exist\n- 500 Internal Server Error - Server issue",
19
- "timestamp": "2026-03-21T14:46:30"
20
- },
21
- {
22
- "role": "user",
23
- "content": "How should we handle pagination?",
24
- "timestamp": "2026-03-21T14:50:00"
25
- },
26
- {
27
- "role": "model",
28
- "content": "For pagination, I recommend cursor-based pagination for large datasets:\n\n```json\n{\n \"data\": [...],\n \"pagination\": {\n \"next_cursor\": \"eyJpZCI6MTIzfQ==\",\n \"has_more\": true,\n \"total_count\": 1042\n }\n}\n```\n\n## Comparison\n\n| Type | Pros | Cons |\n|------|------|------|\n| Offset | Simple, random access | Performance issues at scale |\n| Cursor | Efficient, consistent | No random access |\n| Page | Familiar to users | Inflexible |\n\nUse cursor-based pagination when:\n- Dealing with large datasets (millions of rows)\n- Real-time data where offset skips items\n- Infinite scroll interfaces\n\nUse offset pagination when:\n- Small datasets\n- User needs to jump to specific pages\n- Analytics or reporting use cases",
29
- "timestamp": "2026-03-21T15:00:00"
30
- }
31
- ]
32
- }