Skip to content

Commit 587750c

Browse files
authored
refactor(env): remove OPENCLI_KEEP_TAB (#1509)
`OPENCLI_KEEP_TAB` was a debugging shortcut, not a config dimension. It let users override `--keep-tab` globally via the shell environment, which contradicts the per-command lifecycle model: `siteSession:'persistent'` already pins persistent site tabs as a hard adapter-metadata constraint, and `--keep-tab true|false` covers the ad-hoc override case. The env just leaked process state across every browser command in the shell. Changes: - src/execution.ts: `resolveKeepTab()` drops the `normalizeBooleanOption('OPENCLI_KEEP_TAB', process.env.OPENCLI_KEEP_TAB)` fallback. `--keep-tab` is now the single user override. - src/execution.test.ts: two regression tests rewritten to use the `executeCommand(cmd, {}, false, { keepTab: 'true' })` signature instead of the env. Logic and assertions unchanged. - README.md / README.zh-CN.md / skills/opencli-usage/SKILL.md: drop the env table row. `--keep-tab` documentation stays. - CHANGELOG.md: BREAKING entry under Unreleased. Note: the 1.7.15 CHANGELOG entry still references the env historically; that's intentional, historical entries are not retroactively edited. Verification: - npx tsc --noEmit pass - npx vitest run --project unit --project extension → 1144/1145 pass (1 unrelated skip) - typed-error-lint baseline 189 - silent-column-drop baseline 103
1 parent a77e058 commit 587750c

6 files changed

Lines changed: 6 additions & 18 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
### ⚠ BREAKING CHANGES
1010

1111
* **browser** — replace the `--session <name>` flag with a `<session>` positional argument that immediately follows `browser`. `opencli browser work click 12` instead of `opencli browser --session work click 12`; `opencli browser work bind` instead of `opencli browser bind --session work`. Required-flag semantics are now encoded structurally as a positional, matching the Docker/git convention for required operation-target identifiers. The internal `--session` flag is preserved for the daemon protocol and for direct `program.parseAsync` callers but is no longer part of the user-facing surface.
12+
* **env** — remove `OPENCLI_KEEP_TAB`. The flag was a debugging shortcut, not a config dimension: `--keep-tab true|false` on the command line is the single source of truth, and adapter `siteSession: 'persistent'` already pins persistent site tabs as a hard constraint. Removing the env eliminates a globally-leaking process state that overrode every browser command in the shell.
1213

1314
## [1.7.18](https://github.com/jackwener/opencli/compare/v1.7.17...v1.7.18) (2026-05-12)
1415

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,6 @@ OpenCLI is not only for websites. It can also:
199199
| `OPENCLI_DAEMON_PORT` | `19825` | HTTP port for the daemon-extension bridge |
200200
| `OPENCLI_PROFILE` || Browser Bridge profile alias/contextId to use when multiple Chrome profiles are connected |
201201
| `OPENCLI_WINDOW` | command default | Set to `foreground` or `background` to override Browser Bridge window placement. Browser-backed commands also accept `--window <foreground\|background>`. |
202-
| `OPENCLI_KEEP_TAB` | command default | Set to `true` or `false` to keep or release the browser tab lease after a browser-backed adapter command. Browser-backed adapter commands also accept `--keep-tab <true\|false>`. |
203202
| `OPENCLI_BROWSER_CONNECT_TIMEOUT` | `30` | Seconds to wait for browser connection |
204203
| `OPENCLI_BROWSER_COMMAND_TIMEOUT` | `60` | Seconds to wait for a single browser command |
205204
| `OPENCLI_CDP_ENDPOINT` || Chrome DevTools Protocol endpoint for remote browser or Electron apps |

README.zh-CN.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ OpenCLI 不只是网站 CLI,还可以:
182182
|------|--------|------|
183183
| `OPENCLI_DAEMON_PORT` | `19825` | daemon-extension 通信端口 |
184184
| `OPENCLI_WINDOW` | 命令默认值 | 设为 `foreground``background` 来覆盖 Browser Bridge 窗口位置。浏览器型命令也支持 `--window <foreground\|background>` |
185-
| `OPENCLI_KEEP_TAB` | 命令默认值 | 设为 `true``false` 来控制浏览器型 adapter 命令结束后是否保留 tab lease。浏览器型 adapter 命令也支持 `--keep-tab <true\|false>` |
186185
| `OPENCLI_BROWSER_CONNECT_TIMEOUT` | `30` | 浏览器连接超时(秒) |
187186
| `OPENCLI_BROWSER_COMMAND_TIMEOUT` | `60` | 单个浏览器命令超时(秒) |
188187
| `OPENCLI_CDP_ENDPOINT` || Chrome DevTools Protocol 端点,用于远程浏览器或 Electron 应用 |

skills/opencli-usage/SKILL.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ A few commands override the default via `cmd.defaultFormat` (e.g. chat commands
8383
| `OPENCLI_CDP_ENDPOINT` || Manual CDP endpoint override (dev / remote Chrome / Electron). |
8484
| `OPENCLI_CACHE_DIR` | `~/.opencli/cache` | Network capture + browser-state cache. |
8585
| `OPENCLI_WINDOW` | command-specific | `foreground` or `background` browser window mode. |
86-
| `OPENCLI_KEEP_TAB` | command-specific | `true` or `false`; controls whether browser tab leases are kept after a command. |
8786
| `OPENCLI_VERBOSE` | `false` | Verbose logging (also triggered by `-v`). |
8887

8988
## Self-repair

src/execution.test.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -440,15 +440,13 @@ describe('executeCommand — non-browser timeout', () => {
440440
vi.restoreAllMocks();
441441
});
442442

443-
it('skips closeWindow when OPENCLI_KEEP_TAB=true (success path)', async () => {
443+
it('skips closeWindow when --keep-tab=true (success path)', async () => {
444444
const closeWindow = vi.fn().mockResolvedValue(undefined);
445445
const mockPage = { closeWindow } as any;
446446

447447
vi.spyOn(capRouting, 'shouldUseBrowserSession').mockReturnValue(true);
448448
vi.spyOn(runtime, 'browserSession').mockImplementation(async (_Factory, fn) => fn(mockPage));
449449

450-
const prev = process.env.OPENCLI_KEEP_TAB;
451-
process.env.OPENCLI_KEEP_TAB = 'true';
452450
try {
453451
const cmd = cli({
454452
site: 'test-execution',
@@ -459,24 +457,20 @@ describe('executeCommand — non-browser timeout', () => {
459457
func: async () => [{ ok: true }],
460458
});
461459

462-
await executeCommand(cmd, {});
460+
await executeCommand(cmd, {}, false, { keepTab: 'true' });
463461
expect(closeWindow).not.toHaveBeenCalled();
464462
} finally {
465-
if (prev === undefined) delete process.env.OPENCLI_KEEP_TAB;
466-
else process.env.OPENCLI_KEEP_TAB = prev;
467463
vi.restoreAllMocks();
468464
}
469465
});
470466

471-
it('skips closeWindow when OPENCLI_KEEP_TAB=true (failure path)', async () => {
467+
it('skips closeWindow when --keep-tab=true (failure path)', async () => {
472468
const closeWindow = vi.fn().mockResolvedValue(undefined);
473469
const mockPage = { closeWindow } as any;
474470

475471
vi.spyOn(capRouting, 'shouldUseBrowserSession').mockReturnValue(true);
476472
vi.spyOn(runtime, 'browserSession').mockImplementation(async (_Factory, fn) => fn(mockPage));
477473

478-
const prev = process.env.OPENCLI_KEEP_TAB;
479-
process.env.OPENCLI_KEEP_TAB = 'true';
480474
try {
481475
const cmd = cli({
482476
site: 'test-execution',
@@ -487,11 +481,9 @@ describe('executeCommand — non-browser timeout', () => {
487481
func: async () => { throw new Error('adapter failure'); },
488482
});
489483

490-
await expect(executeCommand(cmd, {})).rejects.toThrow('adapter failure');
484+
await expect(executeCommand(cmd, {}, false, { keepTab: 'true' })).rejects.toThrow('adapter failure');
491485
expect(closeWindow).not.toHaveBeenCalled();
492486
} finally {
493-
if (prev === undefined) delete process.env.OPENCLI_KEEP_TAB;
494-
else process.env.OPENCLI_KEEP_TAB = prev;
495487
vi.restoreAllMocks();
496488
}
497489
});

src/execution.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -511,9 +511,7 @@ function normalizeBooleanOption(name: string, raw: unknown): boolean | null {
511511

512512
function resolveKeepTab(siteSession: SiteSessionMode, rawOption?: unknown): boolean {
513513
if (siteSession === 'persistent') return true;
514-
return normalizeBooleanOption('--keep-tab', rawOption)
515-
?? normalizeBooleanOption('OPENCLI_KEEP_TAB', process.env.OPENCLI_KEEP_TAB)
516-
?? false;
514+
return normalizeBooleanOption('--keep-tab', rawOption) ?? false;
517515
}
518516

519517
function normalizeWindowMode(name: string, raw: unknown): BrowserWindowMode | null {

0 commit comments

Comments
 (0)