Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -240,7 +240,7 @@ After an external `codex login` or a manual provider change, run `save <name>` 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
```

Expand All @@ -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 <keyword or id>` | Resume one matching CLI session (by title keyword or session ID) with current provider/model overrides. |
| `resume <keyword or id>` | Resume one matching CLI / VS Code session (by title keyword or session ID) with current provider/model overrides. |
| `delete <name>` | Remove the saved profile; leave active Codex files untouched. |
| `help` | Show built-in help. |

Expand Down
10 changes: 5 additions & 5 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 继续

Expand Down Expand Up @@ -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 会话
```

设备码重新登录的正确顺序是:
Expand All @@ -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` | 查看内置帮助。 |

Expand Down
6 changes: 3 additions & 3 deletions codex-switch
Original file line number Diff line number Diff line change
Expand Up @@ -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 <id> 可跨 provider 恢复)")
Expand Down Expand Up @@ -272,15 +272,15 @@ 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:
rows = cur.execute("""
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:
Expand Down
4 changes: 2 additions & 2 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <id>` 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.

Expand All @@ -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. |
Expand Down
20 changes: 20 additions & 0 deletions tests/test_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Loading