From ac6fc29509a98f70e4b134f2722441cc554693e5 Mon Sep 17 00:00:00 2001 From: EchoTreee <2024140044@mails.szu.edu.cn> Date: Tue, 22 Sep 2026 16:36:59 +0800 Subject: [PATCH] feat: include VS Code (vscode) sessions in sessions and resume Sessions created from the VS Code Codex extension have source='vscode', which the previous cli/exec filter hid. Include vscode in sessions (list) and resume (interactive), so those conversations are no longer invisible. --- CHANGELOG.md | 1 + README.md | 6 +++--- README.zh-CN.md | 10 +++++----- codex-switch | 6 +++--- docs/usage.md | 4 ++-- tests/test_smoke.py | 20 ++++++++++++++++++++ 6 files changed, 34 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7e5166..1763b0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Added +- `sessions` and `resume` now include VS Code (`source = 'vscode'`) sessions alongside CLI sessions, so sessions created from the VS Code Codex extension are no longer invisible. - `resume` accepts a session ID or ID prefix (hex/hyphen, 8+ characters) in addition to a title keyword. - Optional herdr companion recommendations in both READMEs and parallel guides, including pane setup and the distinction between detaching and restarting an agent. - Six core benefits at the top of both READMEs, plus bilingual parallel-workflow guides covering worktrees, startup identities, token snapshots, and safe timing for recovery. diff --git a/README.md b/README.md index 3033741..31fb1be 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ In the author's reported workflow, Codex's `/resume` picker filters by `model_pr First save and verify both profiles in the same home. Here, `relay` and `official` are saved profile names; choose a title keyword matching exactly one CLI session. ```bash -codex-switch sessions # list CLI / exec sessions across providers +codex-switch sessions # list CLI / exec / VS Code sessions across providers codex-switch use relay # activate the saved relay configuration codex-switch resume "parser" # continue with its provider/model @@ -240,7 +240,7 @@ After an external `codex login` or a manual provider change, run `save ` b ```bash codex-switch list # saved profiles; * marks the recorded active one codex-switch status # local paths, account ID, and provider -codex-switch sessions # local CLI / exec sessions +codex-switch sessions # local CLI / exec / VS Code sessions codex-switch resume "parser" # resume by title keyword or session ID ``` @@ -257,7 +257,7 @@ See [provider setup, recovery, and troubleshooting](docs/usage.md) for the next | `list` | Show saved profiles and the recorded active profile. | | `status` | Show local file locations and account/provider metadata. | | `sessions` | List local sessions from the expected SQLite schema. | -| `resume ` | Resume one matching CLI session (by title keyword or session ID) with current provider/model overrides. | +| `resume ` | Resume one matching CLI / VS Code session (by title keyword or session ID) with current provider/model overrides. | | `delete ` | Remove the saved profile; leave active Codex files untouched. | | `help` | Show built-in help. | diff --git a/README.zh-CN.md b/README.zh-CN.md index 52fb9da..576dd19 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -146,10 +146,10 @@ codex-switch save relay ### 同一个对话,双向切换线路继续 -先在同一 Codex home 下保存并验证两套 profile。下面的 `relay` 和 `official` 是已保存的 profile 名字;关键词需唯一匹配一个 CLI 会话。 +先在同一 Codex home 下保存并验证两套 profile。下面的 `relay` 和 `official` 是已保存的 profile 名字;关键词需唯一匹配一个 CLI / VS Code 会话。 ```bash -codex-switch sessions # 列出 CLI / exec 会话,不按 provider 过滤 +codex-switch sessions # 列出 CLI / exec / VS Code 会话,不按 provider 过滤 codex-switch use relay # 切换到保存好的中转站配置 codex-switch resume "parser" # 自动用当前 provider/model 继续 @@ -240,8 +240,8 @@ codex ```bash codex-switch list # 查看已保存的 profile,* 表示记录的活跃项 codex-switch status # 查看本地路径、账号 ID 和 provider -codex-switch sessions # 列出本地 CLI / exec 会话 -codex-switch resume "parser" # 标题关键词或会话 ID,需唯一匹配一个 CLI 会话 +codex-switch sessions # 列出本地 CLI / exec / VS Code 会话 +codex-switch resume "parser" # 标题关键词或会话 ID,需唯一匹配一个 CLI / VS Code 会话 ``` 设备码重新登录的正确顺序是: @@ -263,7 +263,7 @@ codex-switch relogin --device-auth work | `list` | 列出 profile 和记录的活跃项。 | | `status` | 查看本地文件路径和账号/provider 元信息。 | | `sessions` | 从预期的 SQLite 表结构读取本地会话。 | -| `resume <关键词或ID>` | 用当前 provider/model 参数恢复唯一匹配的 CLI 会话(按标题关键词或会话 ID)。 | +| `resume <关键词或ID>` | 用当前 provider/model 参数恢复唯一匹配的 CLI / VS Code 会话(按标题关键词或会话 ID)。 | | `delete <名字>` | 删除已保存的 profile,不删除当前 Codex 登录文件。 | | `help` | 查看内置帮助。 | diff --git a/codex-switch b/codex-switch index 6b514c1..b6f7a84 100755 --- a/codex-switch +++ b/codex-switch @@ -242,7 +242,7 @@ rows = cur.execute(""" SELECT datetime(updated_at,'unixepoch','localtime'), model_provider, id, COALESCE(title,''), source FROM threads - WHERE source IN ('cli','exec') + WHERE source IN ('cli','exec','vscode') ORDER BY updated_at DESC """).fetchall() print(f"当前 provider:{prov}(* = 与当前 provider 一致;无 * 的会话用 codex resume 可跨 provider 恢复)") @@ -272,7 +272,7 @@ if by_id: SELECT id, COALESCE(title,''), model_provider, datetime(updated_at,'unixepoch','localtime') FROM threads - WHERE source='cli' AND lower(id) LIKE ? + WHERE source IN ('cli','vscode') AND lower(id) LIKE ? ORDER BY updated_at DESC """, (kw + '%',)).fetchall() else: @@ -280,7 +280,7 @@ else: SELECT id, COALESCE(title,''), model_provider, datetime(updated_at,'unixepoch','localtime') FROM threads - WHERE source='cli' AND lower(COALESCE(title,'')) LIKE ? + WHERE source IN ('cli','vscode') AND lower(COALESCE(title,'')) LIKE ? ORDER BY updated_at DESC """, (f"%{kw}%",)).fetchall() for r in rows: diff --git a/docs/usage.md b/docs/usage.md index fa5c592..c5c1aa3 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -49,7 +49,7 @@ codex-switch sessions codex-switch resume "parser regression" ``` -`sessions` reads CLI and exec sessions from the expected local database **without a provider or working-directory filter**. The `*` marker identifies the current provider; it does not exclude other providers. `resume` also searches across providers: it matches CLI session titles with SQLite `LIKE` (`%` and `_` act as wildcards), or — when the argument is a session-ID-shaped prefix (hex/hyphen, 8+ characters) — it matches session IDs by prefix instead. Zero or multiple matches stop with an error instead of choosing a session automatically. Use a more specific keyword or a longer ID prefix if necessary. +`sessions` reads CLI, exec, and VS Code sessions from the expected local database **without a provider or working-directory filter**. The `*` marker identifies the current provider; it does not exclude other providers. `resume` also searches across providers: it matches CLI / VS Code session titles with SQLite `LIKE` (`%` and `_` act as wildcards), or — when the argument is a session-ID-shaped prefix (hex/hyphen, 8+ characters) — it matches session IDs by prefix instead. Zero or multiple matches stop with an error instead of choosing a session automatically. Use a more specific keyword or a longer ID prefix if necessary. With a single match, the script runs `codex resume ` with `-c` overrides from the active configuration. A provider override is always supplied; a model override is supplied if the script finds a model. The database lookup itself is read-only. Once launched, Codex may update session state. @@ -69,7 +69,7 @@ Distinguish the verified script behavior from Codex's persistence behavior: | Layer | Behavior and evidence | | --- | --- | -| `codex-switch sessions` | Its SQL has a source filter (`cli` / `exec`), but no provider or working-directory filter. | +| `codex-switch sessions` | Its SQL has a source filter (`cli` / `exec` / `vscode`), but no provider or working-directory filter. | | `codex-switch resume` | Its SQL searches CLI titles without a provider filter. It opens SQLite in read-only mode, then invokes `codex resume` with configuration overrides. | | Codex CLI | The [official command reference](https://learn.chatgpt.com/docs/developer-commands?surface=cli#codex-resume) documents resume by ID and global overrides. Local `codex-cli 0.153.4` help also confirms `-c key=value`. | | Provider writeback and picker filtering | Reported by the author for their workflow; the official reference does not promise these database details across versions. No live cross-provider validation was performed for this documentation update. | diff --git a/tests/test_smoke.py b/tests/test_smoke.py index 0b916a1..346d261 100644 --- a/tests/test_smoke.py +++ b/tests/test_smoke.py @@ -208,6 +208,26 @@ def test_resume_multiline_title_counts_once(self): "-c", 'model_provider="new-provider"', "-c", 'model="new-model"', ]) + def test_sessions_and_resume_include_vscode(self): + self.seed(provider="new-provider", model="new-model") + with closing(sqlite3.connect(self.home / "state_5.sqlite")) as db: + db.execute( + "CREATE TABLE threads " + "(id TEXT, title TEXT, model_provider TEXT, updated_at INTEGER, source TEXT)" + ) + db.executemany("INSERT INTO threads VALUES (?, ?, ?, ?, ?)", [ + ("fixture-vscode", "Editor session", "openai", 1700000000, "vscode"), + ]) + db.commit() + # vscode 会话应出现在 sessions 列表里 + self.assertIn("fixture-vscode", self.run_cli("sessions")) + # 也能按标题关键词恢复 + self.run_cli("resume", "Editor") + self.assertEqual(json.loads(self.calls.read_text()), [ + "resume", "fixture-vscode", + "-c", 'model_provider="new-provider"', "-c", 'model="new-model"', + ]) + def test_installer_from_another_directory_and_destination_with_spaces(self): destination = self.base / "custom bin" result = subprocess.run(