session-steward 0.11.0 → 0.11.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.11.2] - 2026-09-23
4
+
5
+ ### Added
6
+
7
+ - Added `session-steward update` with version output and a sudo prompt when needed.
8
+
9
+ ### Changed
10
+
11
+ - Updated compatibility coverage for current Codex and Claude releases, including Codex memory v2 storage.
12
+
13
+ ## [0.11.1] - 2026-09-14
14
+
15
+ ### Added
16
+
17
+ - Added Official MCP Registry metadata and a package-name MCP launch command for registry clients.
18
+
3
19
  ## [0.11.0] - 2026-09-14
4
20
 
5
21
  ### Added
@@ -168,6 +184,8 @@
168
184
  - Support for custom Codex home folders and a saved folder preference.
169
185
  - Streaming and bounded-memory discovery for large session collections and transcripts.
170
186
 
187
+ [0.11.2]: https://github.com/mallikcheripally/session-steward/compare/v0.11.1...v0.11.2
188
+ [0.11.1]: https://github.com/mallikcheripally/session-steward/compare/v0.11.0...v0.11.1
171
189
  [0.11.0]: https://github.com/mallikcheripally/session-steward/compare/v0.10.3...v0.11.0
172
190
  [0.10.3]: https://github.com/mallikcheripally/session-steward/compare/v0.10.2...v0.10.3
173
191
  [0.10.2]: https://github.com/mallikcheripally/session-steward/compare/v0.10.1...v0.10.2
package/README.md CHANGED
@@ -4,355 +4,212 @@
4
4
  [![Build status](https://img.shields.io/github/actions/workflow/status/mallikcheripally/session-steward/validate.yml?branch=main&style=flat-square&label=build)](https://github.com/mallikcheripally/session-steward/actions/workflows/validate.yml)
5
5
  [![License: MIT](https://img.shields.io/npm/l/session-steward?style=flat-square)](https://github.com/mallikcheripally/session-steward/blob/main/LICENSE)
6
6
 
7
- A local Codex and Claude Code session manager for safely reviewing, backing up, and deleting old sessions from a browser UI or terminal CLI, or through MCP with ChatGPT or Claude.
7
+ Session Steward is a local session manager for Codex and Claude Code. It helps you find old or large sessions across workspaces, decide what is worth keeping, and clean up the related records it recognizes. You can use it with browser UI or terminal CLI, or through MCP with ChatGPT or Claude.
8
8
 
9
- AI coding tools can accumulate hundreds or thousands of local sessions. A session may leave behind transcripts, history, logs, checkpoints, and linked artifacts, so manual cleanup can easily miss related data.
9
+ Codex can delete a session, and Claude Code can purge a project. Built-in deletion works when you already know what should go. Session Steward helps when the hard part is reviewing many sessions across both tools.
10
10
 
11
- Session Steward makes session cleanup safer by finding those records, showing what cleanup will affect, creating a local backup, removing supported data, and verifying the result afterward. Session Steward runs locally.
11
+ - Find inactive or large sessions across workspaces. Switch between Codex and Claude Code, then filter by archive status, name, or session ID.
12
+ - Open a session before deciding. See a distilled timeline of recent messages, file changes, commands, and command results, plus recognized storage and token use.
13
+ - Clean selected sessions using a plan you review first, with a local backup, verification afterward, and recovery when cleanup needs attention.
12
14
 
13
- ![Session Steward cleanup demo](https://raw.githubusercontent.com/mallikcheripally/session-steward/main/docs/session-steward-demo.gif)
14
-
15
- ## Manage local Codex and Claude Code sessions
16
-
17
- - Review and clean up sessions from the browser, terminal, ChatGPT, or Claude through MCP.
18
- - Switch between Codex and Claude Code without installing another package.
19
- - See session counts and the storage used by recognized session files.
20
- - Find sessions inactive for 30, 60, or 90 days.
21
- - Filter active or archived sessions by workspace, name, or session ID.
22
- - Mark important sessions or workspaces Keep so cleanup skips them.
23
- - Inspect session details and affected records before deletion.
24
- - Read a session timeline of what you asked, what changed, and which commands ran.
25
- - See how many tokens a session used, split into fresh input, cached input, cache writes, and output.
26
- - Choose standard or thorough cleanup.
27
- - Use custom Codex or Claude home folders across browser and terminal sessions.
28
-
29
- ## Safe by default
30
-
31
- - Cleanup happens entirely on your computer.
32
- - Only records included in the reviewed cleanup plan are removed.
33
- - A local recovery backup is created before anything changes.
34
- - Cleanup is verified before the backup is removed.
35
- - Unrecognized storage is reported and left untouched.
36
- - Thorough cleanup is unavailable when the detected storage format is not supported.
37
- - Cleanup stays local and does not upload session contents.
38
-
39
- ### Keep important sessions
15
+ ## Try Session Steward locally
40
16
 
41
- Mark a session or workspace Keep and Session Steward skips it during manual and scheduled cleanup. A workspace Keep also covers descendant folders and future sessions there.
17
+ Try the browser app for one run without installing it globally:
42
18
 
43
- It protects against Session Steward cleanup only. Codex or Claude Code can still remove the data.
19
+ Session Steward requires Node.js 24.15 or newer.
44
20
 
45
- ### Session Steward does not remove
46
-
47
- - Sign-in data or saved API credentials
48
- - Configuration, plugins, caches, or custom prompt files
49
- - Project files, Git repositories, or worktrees
50
- - Sessions outside the reviewed cleanup plan
51
- - Conversations stored in your ChatGPT or Claude account
52
- - Claude Code worktrees, branches, repositories, remote sessions, SSH sessions, or Cowork data
53
-
54
- At startup, Session Steward may contact the public npm registry to check for a newer version.
21
+ ```bash
22
+ npx session-steward@latest
23
+ ```
55
24
 
56
- ## Install and get started
25
+ The browser app listens only on `127.0.0.1` and does not upload session contents.
57
26
 
58
- Session Steward supports macOS, Linux, and Windows and requires Node.js 24.15 or newer.
27
+ ![Session Steward cleanup demo](https://raw.githubusercontent.com/mallikcheripally/session-steward/main/docs/session-steward-demo.gif)
59
28
 
60
- Install it globally:
29
+ For ongoing use, install it globally:
61
30
 
62
31
  ```bash
63
32
  npm install --global session-steward
64
33
  ```
65
34
 
66
- Then launch it:
67
-
68
- ```bash
69
- session-steward
70
- ```
35
+ The global install provides four commands:
71
36
 
72
- Or try it without installing:
37
+ | Command | Use it for |
38
+ | --- | --- |
39
+ | `session-steward` | Browser interface |
40
+ | `session-steward-cli` | Interactive terminal and JSON output |
41
+ | `session-steward-mcp` | MCP session management |
42
+ | `session-steward-scheduler` | Automatic session cleanup |
73
43
 
74
- ```bash
75
- npx session-steward@latest
76
- ```
44
+ Session Steward supports macOS, Linux, and Windows. Run `session-steward` to open the browser interface. Leave its terminal open while you use it; press `Ctrl+C` to stop it.
77
45
 
78
- Session Steward opens in your browser, listens only on `127.0.0.1`, and detects `~/.codex` and `~/.claude` by default. Claude Code CLI and local Claude Desktop sessions are detected on macOS and Windows; the Claude Code CLI is also supported on Linux. On Windows, these resolve to `%USERPROFILE%\.codex` and `%USERPROFILE%\.claude`.
46
+ ## Find old and large Codex and Claude Code sessions
79
47
 
80
- When run inside WSL, Session Steward uses the Linux home folder and manages sessions stored there. Run it from Windows to manage sessions in your Windows profile.
48
+ Session Steward reads the local session folders already used by Codex and Claude Code. It looks for `~/.codex` and `~/.claude` by default and lets you switch providers from the same interface.
81
49
 
82
- To clean up sessions:
50
+ You can:
83
51
 
84
- 1. Review the detected sessions.
85
- 2. Select one or more sessions.
86
- 3. Choose a cleanup option.
87
- 4. Review exactly what will be removed.
88
- 5. Close any selected sessions that may still be active.
89
- 6. Confirm the cleanup.
52
+ - filter by inactivity, exact workspace, active or archived status, name, or session ID;
53
+ - see recognized session-owned storage by session and workspace, then sort by size;
54
+ - browse session timeline of recent messages, file changes, commands, and command results;
55
+ - inspect fresh input, cached input, cache writes, output, and recorded reasoning tokens;
56
+ - mark a session or workspace **Keep** so manual and scheduled cleanup skip it.
90
57
 
91
- Keep the terminal open while using Session Steward. Press `Ctrl+C` to stop it.
58
+ A workspace Keep covers that folder, its descendants, and future sessions there. Keep affects Session Steward cleanup only. Codex or Claude Code can still remove their own data.
92
59
 
93
- ## Cleanup and recovery
60
+ ## Why not just delete sessions one at a time?
94
61
 
95
- ### Standard cleanup
62
+ The native delete commands are useful when you already know what should go. They do not cover the same cross-workspace review and cleanup job.
96
63
 
97
- Recommended for routine removal. It removes supported transcripts, history, registry entries, logs, and linked session artifacts belonging to the selected sessions.
64
+ A session can have more than its transcript. Depending on the provider and storage version, it may also have history or registry entries, logs, checkpoints, and other linked records. Removing a JSONL file by hand can leave those records behind.
98
65
 
99
- ### Thorough cleanup
66
+ Session Steward starts from the session instead of a file path. It finds supported related records, shows them in one cleanup plan, and leaves storage it does not recognize alone. You can review several candidates together without treating every old session as safe to delete.
100
67
 
101
- Includes standard cleanup and removes additional recognized session-owned data. For Codex this can include supported Desktop references, memory outputs, and goal records. For Claude Code this includes recognized file checkpoints.
68
+ ## Use the browser, CLI, or MCP
102
69
 
103
- Thorough cleanup is unavailable when Session Steward finds storage it does not recognize. Standard cleanup remains available for supported records that can be identified safely.
70
+ ### Browser
104
71
 
105
- ### Recovery backups
72
+ Run:
106
73
 
107
- A temporary backup is created inside the active provider folder under `session-steward-backups/`.
74
+ ```bash
75
+ session-steward
76
+ ```
108
77
 
109
- After cleanup is successfully verified, the backup is removed automatically. If cleanup fails, Session Steward keeps the backup and lets you restore the sessions, keep the backup, or delete it.
78
+ Choose Codex or Claude Code, filter or search the list, and open sessions you are unsure about. When you select sessions for cleanup, the browser shows the affected records before asking for confirmation.
110
79
 
111
- Before restoring, the current versions of affected files are saved separately to provide another recovery point.
80
+ Use `session-steward --no-open` to start without opening a browser automatically. Open the local address printed in the terminal.
112
81
 
113
- ## Terminal CLI
82
+ ### Terminal CLI
114
83
 
115
- Start the interactive terminal interface:
84
+ Start the interactive terminal:
116
85
 
117
86
  ```bash
118
87
  session-steward-cli
119
88
  ```
120
89
 
121
- Use Claude Code instead of Codex:
90
+ Use Claude Code instead of Codex, or return a limited JSON result for another tool:
122
91
 
123
92
  ```bash
124
93
  session-steward-cli --provider claude-code
125
- ```
126
-
127
- List sessions as JSON:
128
-
129
- ```bash
130
94
  session-steward-cli --json --limit 10
131
95
  ```
132
96
 
133
- <details>
134
- <summary>More terminal options</summary>
135
-
136
- Show session and workspace storage totals:
97
+ Filter with options such as `--inactive-days 60`, `--archive-status archived`, or `--workspace /path/to/project`. Use `--events` for the timeline, `--tokens` for token use, and `--sort size` for the largest sessions first. Run `session-steward-cli --help` for every option.
137
98
 
138
- ```bash
139
- session-steward-cli --overview
140
- ```
141
-
142
- Add `--json` when the output will be read by another tool.
99
+ ### MCP with ChatGPT, Codex, or Claude Code
143
100
 
144
- Find sessions inactive for at least 60 days:
101
+ Connect the local MCP server once:
145
102
 
146
103
  ```bash
147
- session-steward-cli --inactive-days 60
148
- ```
149
-
150
- Show only archived sessions:
151
-
152
- ```bash
153
- session-steward-cli --archive-status archived
104
+ codex mcp add session-steward -- session-steward-mcp
154
105
  ```
155
106
 
156
- Show sessions from one exact workspace:
107
+ Or connect it to Claude Code:
157
108
 
158
109
  ```bash
159
- session-steward-cli --workspace /path/to/project
110
+ claude mcp add --scope user session-steward -- session-steward-mcp
160
111
  ```
161
112
 
162
- Use `--include-internals` to include subagents and `--include-supporting` to include supporting sessions. Session sizes are shown in the interactive list, and `--sort size` places the largest sessions first.
113
+ Registry installers can start the same server without a global install using `npx session-steward@latest mcp`.
163
114
 
164
- Start with `--events` to read what happened inside a session — what you asked, what the assistant concluded, which files changed, and which commands ran or failed. In the interactive list, `inspect <number>` then shows that session's timeline:
115
+ You can then ask your client to find inactive sessions, compare recognized session storage between Codex and Claude Code, inspect a session, keep a workspace, clean exact sessions, restore a backup, or manage a cleanup schedule.
165
116
 
166
- ```bash
167
- session-steward-cli --events --events-limit 50
168
- ```
117
+ Session Steward marks cleanup, restore, and schedule management as destructive MCP actions so the client can apply its configured approval policy.
169
118
 
170
- With `--json`, each session carries its own `events`, plus a `coverage` summary of how much of the transcript was recognized:
119
+ Scheduled cleanup continues in the background after you close the client. You can ask to pause, resume, run, change, or remove a schedule. Before uninstalling Session Steward, stop scheduled cleanup:
171
120
 
172
121
  ```bash
173
- session-steward-cli --json --limit 5 --events
174
- ```
175
-
176
- Use `--tokens` to count what a session spent. The total is split into fresh input, cached input, cache writes, and output, with reasoning reported as a share of output where the provider records it:
177
-
178
- ```bash
179
- session-steward-cli --tokens
180
- ```
181
-
182
- In the interactive list, `tokens` toggles the same breakdown into `inspect`. With `--json`, each session carries a `tokens` object:
183
-
184
- ```bash
185
- session-steward-cli --json --limit 5 --tokens
186
- ```
187
-
188
- Cached input usually dominates, because the whole conversation is re-sent on every turn. A forked session reports its own work separately from the tokens it inherited from the session it branched from, so the two are never added together.
189
-
190
- The interactive terminal accepts the same filters:
191
-
192
- ```text
193
- inactive 30
194
- inactive 60
195
- inactive 90
196
- archive active
197
- archive archived
198
- workspace /path/to/project
199
- internals
200
- supporting
201
- tokens
202
- keep 3
203
- unkeep 3
204
- keep-workspace /path/to/project
205
- unkeep-workspace /path/to/project
206
- cleanup standard
207
- cleanup thorough
208
- overview
209
- backups
122
+ session-steward-scheduler --stop
210
123
  ```
211
124
 
212
- Run `inactive`, `archive`, or `workspace` without a value to clear that filter.
125
+ For another MCP client, configure a local stdio server named `session-steward` with the command `session-steward-mcp`.
213
126
 
214
- `keep` and `unkeep` accept session selectors. `keep-workspace` and
215
- `unkeep-workspace` accept a full path.
127
+ The MCP process uses Session Steward's saved provider folders or the defaults when none are saved. Its server command can set startup folders with `--codex-home` or `--claude-home`, and its `manage_settings` tool can change the saved folders. A one-time browser or CLI override does not carry into a later MCP process.
216
128
 
217
- `backups` lists recovery backups retained after an interrupted or unsuccessful cleanup. Use `restore <number>` to restore one, or `delete-backup <number>` to remove it permanently. Both actions require an explicit confirmation.
129
+ The MCP server runs locally, but session details can contain messages, commands, file names, and workspace paths. Your MCP client may send that information to its AI provider.
218
130
 
219
- </details>
131
+ ## Review what will be deleted first
220
132
 
221
- Use `session-steward-cli --help` to see all available options.
133
+ For a manual cleanup:
222
134
 
223
- ## Clean up sessions with ChatGPT or Claude
135
+ 1. Select the sessions.
136
+ 2. Close any selected sessions that may still be active.
137
+ 3. Review the cleanup plan Session Steward builds.
138
+ 4. Confirm the plan.
139
+ 5. Session Steward creates a local recovery backup.
140
+ 6. It removes only supported records in the reviewed plan.
141
+ 7. It checks whether those records are gone.
224
142
 
225
- Connect Session Steward once, then ask ChatGPT or Claude to find old or large
226
- sessions, delete them safely, restore a backup, or clean sessions automatically
227
- on a schedule.
143
+ Every interface revalidates the selected sessions before changing data. If Session Steward can detect that a selected session is active, preflight or cleanup stops. When detection is unavailable, it warns you to confirm that the selected sessions are closed.
228
144
 
229
- Connect it to ChatGPT and Codex:
145
+ ### Standard and thorough cleanup
230
146
 
231
- ```bash
232
- codex mcp add session-steward -- session-steward-mcp
233
- ```
147
+ **Standard cleanup** removes supported transcripts, history, registry entries, logs, and linked artifacts belonging to the selected sessions. It is the routine option.
234
148
 
235
- Connect it to Claude Code:
149
+ **Thorough cleanup** also removes additional recognized session-owned data. For Codex, that can include supported Desktop references, memory outputs, and goal records. For Claude Code, it includes recognized file checkpoints.
236
150
 
237
- ```bash
238
- claude mcp add --scope user session-steward -- session-steward-mcp
239
- ```
151
+ Thorough cleanup is unavailable when the detected storage layout is not supported. Standard cleanup can still remove records that Session Steward can identify safely.
240
152
 
241
- You can then ask things like:
242
-
243
- - “Find sessions I have not used in 60 days.”
244
- - “Show sessions from this workspace, largest first.”
245
- - “Delete those sessions.”
246
- - “Keep this session from Session Steward cleanup.”
247
- - “Keep every session in this workspace.”
248
- - “Every 12 days, delete sessions I have not used in 45 days.”
249
- - “Restore my latest backup.”
250
-
251
- Cleanup uses the same local backup and verification checks as the browser and
252
- terminal. Codex or Claude Code asks for approval before cleanup, restore, or
253
- schedule changes.
254
-
255
- Scheduled cleanup continues in the background after you close Codex or Claude
256
- Code. You can ask to pause, resume, run, change, or remove a schedule. Before
257
- uninstalling Session Steward, stop scheduled cleanup:
258
-
259
- ```bash
260
- session-steward-scheduler --stop
261
- ```
262
-
263
- Check or remove the MCP connection at any time:
264
-
265
- ```bash
266
- codex mcp list
267
- codex mcp remove session-steward
153
+ <details>
154
+ <summary>Backup and restore behavior</summary>
268
155
 
269
- claude mcp list
270
- claude mcp remove --scope user session-steward
271
- ```
156
+ Recovery backups are stored under `session-steward-backups/` inside the active provider folder.
272
157
 
273
- For another MCP client, add a local server named `session-steward`:
158
+ If cleanup from the browser or interactive terminal needs attention, the backup is kept until you decide whether to restore it. The browser offers **Restore**, and the terminal reports the backup for the `restore` command. MCP and scheduled cleanup try to restore automatically.
274
159
 
275
- ```json
276
- {
277
- "mcpServers": {
278
- "session-steward": {
279
- "command": "session-steward-mcp"
280
- }
281
- }
282
- }
283
- ```
160
+ After successful cleanup, Session Steward removes the recovery backup when it can. A restore first creates a temporary safety backup of the current files, then tries to remove both backups if the restore succeeds. If a restore or backup removal cannot complete, recovery data remains and Session Steward reports it.
284
161
 
285
- The MCP server uses the same provider folders selected in the browser or
286
- terminal.
162
+ </details>
287
163
 
288
- ### Privacy
164
+ ### What cleanup leaves alone
289
165
 
290
- The MCP server runs locally. Session details can include messages, commands,
291
- file names, and workspace paths, and your MCP client may send that information
292
- to its AI provider.
166
+ - Sign-in data and saved API credentials
167
+ - Configuration, plugins, caches, and custom prompt files
168
+ - Project files, Git repositories, and worktrees
169
+ - Sessions outside the reviewed cleanup plan
170
+ - Conversations stored in your ChatGPT or Claude account
171
+ - Claude Code worktrees, branches, repositories, remote sessions, SSH sessions, and Cowork data
293
172
 
294
- ## Use a custom provider folder
173
+ ## Provider folders and platform support
295
174
 
296
- The browser interface displays the active provider folder. Select **Change** to choose another existing folder and remember it for later browser and terminal sessions.
175
+ The browser shows the active provider folder. Select **Change** to choose another existing folder and save it for later browser, terminal, and MCP sessions.
297
176
 
298
- For a one-time override:
177
+ For a one-time browser override:
299
178
 
300
179
  ```bash
301
180
  session-steward --codex-home /path/to/.codex
302
- ```
303
-
304
- For Claude Code:
305
-
306
- ```bash
307
181
  session-steward --claude-home /path/to/.claude
308
182
  ```
309
183
 
310
- The command-line override applies only to that run and does not replace your saved folder.
184
+ The CLI and MCP commands accept the same flags. An override applies only to that process and does not replace the saved folder.
311
185
 
312
- ## Other commands
186
+ Codex and Claude Code CLI sessions are supported on macOS, Linux, and Windows. Local Claude Desktop sessions are also supported on macOS and Windows. On Windows, the default provider folders are `%USERPROFILE%\.codex` and `%USERPROFILE%\.claude`; both standalone and Microsoft Store Claude Desktop data locations are detected.
313
187
 
314
- Start without automatically opening the browser:
188
+ Inside WSL, Session Steward uses the Linux home folder. Run it from Windows to manage sessions in your Windows profile.
315
189
 
316
- ```bash
317
- session-steward --no-open
318
- ```
190
+ Archiving a Claude Desktop session does not delete it. It remains available until it is explicitly included in cleanup. Session Steward does not remove Claude worktrees.
319
191
 
320
- Update Session Steward:
321
-
322
- ```bash
323
- npm install --global session-steward@latest
324
- ```
325
-
326
- Uninstall it:
192
+ ## Update or uninstall
327
193
 
328
194
  ```bash
195
+ session-steward update
329
196
  npm uninstall --global session-steward
330
197
  ```
331
198
 
332
- Uninstalling Session Steward does not remove provider sessions, recovery backups, or saved folder preferences.
199
+ If npm needs root access, the update command asks before retrying with `sudo`.
200
+
201
+ Uninstalling does not remove provider sessions, recovery backups, or saved folder preferences.
333
202
 
334
203
  ## Troubleshooting
335
204
 
336
- - **The browser did not open:** Run `session-steward --no-open`, then open the local address shown in the terminal.
205
+ - **The browser did not open:** Run `session-steward --no-open`, then open the local address printed in the terminal.
337
206
  - **No sessions were found:** Check the selected provider and displayed home folder. Use **Change** or pass a one-time home-folder override.
338
- - **Thorough cleanup is unavailable:** Review the compatibility details. Unrecognized storage is left untouched, but standard cleanup may still be available.
207
+ - **Thorough cleanup is unavailable:** Unrecognized storage stays unchanged, while standard cleanup may still be available.
339
208
  - **Your Node.js version is too old:** Install Node.js 24.15 or newer and run Session Steward again.
340
209
 
341
- ## Development
210
+ ## Benchmarks
342
211
 
343
- ```bash
344
- git clone https://github.com/mallikcheripally/session-steward.git
345
- cd session-steward
346
- npm install
347
- npm test
348
- npm run build
349
- ```
350
-
351
- ## Performance and scale
352
-
353
- Session Steward uses paginated listings, incremental transcript reads, and bounded caches to remain responsive with large session libraries.
354
-
355
- Current synthetic benchmarks on an arm64 Mac with Node.js 24.15.0:
212
+ Current benchmarks on an arm64 Mac with Node.js 24.15.0:
356
213
 
357
214
  | Scenario | Scale | Time | Measured memory growth |
358
215
  | --- | ---: | ---: | ---: |
@@ -374,11 +231,7 @@ Results vary with hardware, disk speed, and session layout. Tests and benchmarks
374
231
 
375
232
  ## Support
376
233
 
377
- Codex, Claude Code CLI, and local Claude Code Desktop sessions are supported. Claude Desktop archive is not treated as deletion, and Session Steward never removes its worktrees. On Windows, both the standalone and Microsoft Store Claude Desktop data locations are detected.
378
-
379
- Use [GitHub Issues](https://github.com/mallikcheripally/session-steward/issues) to report a bug, request a provider, or share a storage format that Session Steward does not recognize.
380
-
381
- See the [changelog](https://github.com/mallikcheripally/session-steward/blob/main/CHANGELOG.md) for published release history.
234
+ Use [GitHub Issues](https://github.com/mallikcheripally/session-steward/issues) to report a bug, request a provider, or share a storage format that Session Steward does not recognize. See the [changelog](https://github.com/mallikcheripally/session-steward/blob/main/CHANGELOG.md) for release history.
382
235
 
383
236
  Session Steward is an independent project and is not affiliated with or endorsed by OpenAI or Anthropic.
384
237
 
@@ -10,20 +10,48 @@ import { findAvailableUpdate, formatUpdateNotice } from "../lib/update-check.mjs
10
10
 
11
11
  assertSupportedNode();
12
12
 
13
- const { values } = parseArgs({
14
- allowPositionals: false,
15
- options: {
16
- "codex-home": { type: "string" },
17
- "claude-home": { type: "string" },
18
- help: { short: "h", type: "boolean" },
19
- "no-open": { type: "boolean", default: false },
20
- port: { type: "string" },
21
- version: { short: "v", type: "boolean" },
22
- },
23
- });
24
-
25
- if (values.help) {
26
- process.stdout.write(`Usage: session-steward [options]
13
+ if (process.argv[2] === "mcp") {
14
+ process.argv.splice(2, 1);
15
+ await import("./session-steward-mcp.mjs");
16
+ } else if (process.argv[2] === "update") {
17
+ process.argv.splice(2, 1);
18
+ if (process.argv.length !== 2) {
19
+ process.stderr.write("Usage: session-steward update\n");
20
+ process.exitCode = 1;
21
+ } else {
22
+ const { updateSessionSteward } = await import("../lib/self-update.mjs");
23
+ try {
24
+ process.exitCode = await updateSessionSteward();
25
+ } catch (error) {
26
+ process.stderr.write(`Could not run the update: ${error.message}\n`);
27
+ process.exitCode = 1;
28
+ }
29
+ }
30
+ } else {
31
+ await startBrowser();
32
+ }
33
+
34
+ async function startBrowser() {
35
+ const { values } = parseArgs({
36
+ allowPositionals: false,
37
+ options: {
38
+ "codex-home": { type: "string" },
39
+ "claude-home": { type: "string" },
40
+ help: { short: "h", type: "boolean" },
41
+ "no-open": { type: "boolean", default: false },
42
+ port: { type: "string" },
43
+ version: { short: "v", type: "boolean" },
44
+ },
45
+ });
46
+
47
+ if (values.help) {
48
+ process.stdout.write(`Usage: session-steward [options]
49
+ session-steward mcp [options]
50
+ session-steward update
51
+
52
+ Commands:
53
+ mcp Run the MCP server over stdio
54
+ update Install the latest version with npm
27
55
 
28
56
  Options:
29
57
  --codex-home <path> Use a custom Codex session folder
@@ -33,44 +61,45 @@ Options:
33
61
  -h, --help Show this help
34
62
  -v, --version Show the installed version
35
63
  `);
36
- process.exit(0);
37
- }
64
+ return;
65
+ }
38
66
 
39
- if (values.version) {
40
- process.stdout.write(`${packageMetadata.version}\n`);
41
- process.exit(0);
42
- }
67
+ if (values.version) {
68
+ process.stdout.write(`${packageMetadata.version}\n`);
69
+ return;
70
+ }
43
71
 
44
- const { startLocalServer } = await import("../lib/server.mjs");
45
- const port = values.port === undefined ? 0 : Number.parseInt(values.port, 10);
46
- const availableUpdate = await findAvailableUpdate({ packageMetadata });
72
+ const { startLocalServer } = await import("../lib/server.mjs");
73
+ const port = values.port === undefined ? 0 : Number.parseInt(values.port, 10);
74
+ const availableUpdate = await findAvailableUpdate({ packageMetadata });
47
75
 
48
- if (availableUpdate) {
49
- process.stdout.write(`${formatUpdateNotice(availableUpdate)}\n`);
50
- }
76
+ if (availableUpdate) {
77
+ process.stdout.write(`${formatUpdateNotice(availableUpdate)}\n`);
78
+ }
51
79
 
52
- const server = await startLocalServer({
53
- claudeHome: values["claude-home"],
54
- codexHome: values["codex-home"],
55
- port,
56
- });
57
-
58
- process.stdout.write(`Session Steward is running at http://127.0.0.1:${server.port}\n`);
59
-
60
- if (!values["no-open"]) {
61
- const url = `http://127.0.0.1:${server.port}`;
62
- const invocation = getBrowserOpenInvocation(url);
63
-
64
- if (invocation) {
65
- const opener = spawn(invocation.command, invocation.args, {
66
- detached: true,
67
- stdio: "ignore",
68
- windowsHide: invocation.windowsHide,
69
- });
70
- opener.unref();
71
- } else {
72
- process.stdout.write(`Open ${url} in a browser.\n`);
80
+ const server = await startLocalServer({
81
+ claudeHome: values["claude-home"],
82
+ codexHome: values["codex-home"],
83
+ port,
84
+ });
85
+
86
+ process.stdout.write(`Session Steward is running at http://127.0.0.1:${server.port}\n`);
87
+
88
+ if (!values["no-open"]) {
89
+ const url = `http://127.0.0.1:${server.port}`;
90
+ const invocation = getBrowserOpenInvocation(url);
91
+
92
+ if (invocation) {
93
+ const opener = spawn(invocation.command, invocation.args, {
94
+ detached: true,
95
+ stdio: "ignore",
96
+ windowsHide: invocation.windowsHide,
97
+ });
98
+ opener.unref();
99
+ } else {
100
+ process.stdout.write(`Open ${url} in a browser.\n`);
101
+ }
73
102
  }
74
- }
75
103
 
76
- process.stdout.write("Press Ctrl+C to stop.\n");
104
+ process.stdout.write("Press Ctrl+C to stop.\n");
105
+ }
@@ -19,15 +19,15 @@ const PROVIDER_ID = "claude-code";
19
19
  const COMPATIBILITY_PROFILE = Object.freeze({
20
20
  id: "claude-local-store-2026-08",
21
21
  builtFor: {
22
- claudeCli: ["2.1.199", "2.1.220", "2.1.228", "2.1.237", "2.1.267"],
23
- claudeDesktop: ["1.24012.9", "1.28929.0", "1.32885.1", "1.40609.0", "1.49585.0"],
22
+ claudeCli: ["2.1.199", "2.1.220", "2.1.228", "2.1.237", "2.1.267", "2.1.280"],
23
+ claudeDesktop: ["1.24012.9", "1.28929.0", "1.32885.1", "1.40609.0", "1.49585.0", "2.2553.1"],
24
24
  },
25
25
  });
26
26
  const SUPPORTED_ENTRYPOINTS = new Set(["cli", "claude-desktop"]);
27
27
  const SHARED_DESKTOP_STATE_FILES = new Set(["scheduled-tasks.json"]);
28
28
  const KNOWN_TOP_LEVEL = new Set([
29
29
  ".DS_Store", ".last-cleanup", ".last-update-result.json", "agents", "backups", "cache", "commands", "debug", "downloads", "file-history", "history.jsonl", "history.jsonl.lock",
30
- "ide", "paste-cache", "plans", "plugins", "projects", "session-env", "sessions", "settings.json",
30
+ "ide", "image-cache", "paste-cache", "plans", "plugins", "projects", "session-env", "sessions", "settings.json",
31
31
  "settings.local.json", "shell-snapshots", "skills", "stats-cache.json", "tasks", "telemetry",
32
32
  "todos", "uploads", "usage-data", "mcp-needs-auth-cache.json", "session-steward-backups",
33
33
  ]);
@@ -4,12 +4,24 @@ import path from "node:path";
4
4
  import { queryRows } from "../../storage/sqlite.mjs";
5
5
 
6
6
  const CACHE_TTL_MS = 2_000;
7
+ const MEMORY_TABLES = [
8
+ { name: "stage1_outputs", requiredColumns: ["thread_id"] },
9
+ {
10
+ name: "jobs",
11
+ optional: true,
12
+ requiredColumns: [
13
+ "kind", "job_key", "status", "worker_id", "ownership_token", "started_at",
14
+ "finished_at", "lease_until", "retry_at", "retry_remaining", "last_error",
15
+ "input_watermark", "last_success_watermark",
16
+ ],
17
+ },
18
+ ];
7
19
 
8
20
  export const CODEX_DATABASE_PROFILE = Object.freeze({
9
- id: "codex-local-store-2026-08",
21
+ id: "codex-local-store-2026-09",
10
22
  builtFor: {
11
- chatgptDesktop: ["26.727.40816", "26.803.61601", "26.818.21641", "26.818.22352", "26.825.41651", "26.903.61454", "26.903.71938"],
12
- codexCli: ["0.144.1", "0.146.0", "0.147.0", "0.148.0", "0.153.4", "0.154.0"],
23
+ chatgptDesktop: ["26.727.40816", "26.803.61601", "26.818.21641", "26.818.22352", "26.825.41651", "26.903.61454", "26.903.71938", "26.917.51856"],
24
+ codexCli: ["0.144.1", "0.146.0", "0.147.0", "0.148.0", "0.153.4", "0.154.0", "0.156.1"],
13
25
  },
14
26
  });
15
27
 
@@ -30,28 +42,13 @@ const SCHEMA_REQUIREMENTS = Object.freeze({
30
42
  fallback: "memories_1.sqlite",
31
43
  pattern: /^memories_(\d+)\.sqlite$/u,
32
44
  required: false,
33
- tables: [
34
- { name: "stage1_outputs", requiredColumns: ["thread_id"] },
35
- {
36
- name: "jobs",
37
- optional: true,
38
- requiredColumns: [
39
- "kind",
40
- "job_key",
41
- "status",
42
- "worker_id",
43
- "ownership_token",
44
- "started_at",
45
- "finished_at",
46
- "lease_until",
47
- "retry_at",
48
- "retry_remaining",
49
- "last_error",
50
- "input_watermark",
51
- "last_success_watermark",
52
- ],
53
- },
54
- ],
45
+ tables: MEMORY_TABLES,
46
+ },
47
+ memoriesV2: {
48
+ fallback: "memories_v2_1.sqlite",
49
+ pattern: /^memories_v2_(\d+)\.sqlite$/u,
50
+ required: false,
51
+ tables: MEMORY_TABLES,
55
52
  },
56
53
  goals: {
57
54
  fallback: "goals_1.sqlite",
@@ -479,7 +479,7 @@ export function getCodexPaths(codexHomeInput, { refresh = false } = {}) {
479
479
  const archivedSessionsDirectory = path.join(codexHome, "archived_sessions");
480
480
  const sessionsDirectory = path.join(codexHome, "sessions");
481
481
  const resolution = resolveCodexDatabases(codexHome, { refresh });
482
- const { goals, logs, memories, queue, state, threadHistory } = resolution.families;
482
+ const { goals, logs, memories, memoriesV2, queue, state, threadHistory } = resolution.families;
483
483
  const stateDatabasePath = state.primary?.path ?? path.join(codexHome, "state_5.sqlite");
484
484
  const logsDatabasePath = logs.primary?.path ?? path.join(codexHome, "logs_2.sqlite");
485
485
  const memoryDatabasePath = memories.primary?.path ?? path.join(codexHome, "memories_1.sqlite");
@@ -500,7 +500,8 @@ export function getCodexPaths(codexHomeInput, { refresh = false } = {}) {
500
500
  logsDatabasePath,
501
501
  logsDatabasePaths: allValidDatabases(logs).map((database) => database.path),
502
502
  memoryDatabasePath,
503
- memoryDatabasePaths: allValidDatabases(memories).map((database) => database.path),
503
+ memoryDatabasePaths: [memories, memoriesV2].flatMap((family) =>
504
+ allValidDatabases(family).map((database) => database.path)),
504
505
  queueDatabasePath,
505
506
  queueDatabasePaths: allValidDatabases(queue).map((database) => database.path),
506
507
  resolvedDatabases: databaseFamilySummary(resolution),
@@ -971,6 +972,8 @@ function stateSchema(database) {
971
972
  ? database.tables.thread_dynamic_tools
972
973
  : inspectSqliteTable(database.path, "thread_dynamic_tools");
973
974
  const schema = {
975
+ attachmentTables: ["thread_artifacts", "thread_attachments"]
976
+ .filter((tableName) => inspectSqliteTable(database.path, tableName).exists),
974
977
  columns,
975
978
  hasDynamicTools: Boolean(dynamicTools?.exists),
976
979
  hasSpawnEdges: Boolean(spawn?.exists),
@@ -2408,6 +2411,9 @@ export async function fingerprintSessionDeletion({ plan, scope, store }) {
2408
2411
 
2409
2412
  for (const database of store.stateDatabases ?? [{ path: store.stateDatabasePath }]) {
2410
2413
  fingerprintRowsForIds(hash, database.path, "threads", "id", plan.ids);
2414
+ for (const tableName of stateSchema(database).attachmentTables) {
2415
+ fingerprintRowsForIds(hash, database.path, tableName, "thread_id", plan.ids);
2416
+ }
2411
2417
  if (stateSchema(database).hasDynamicTools) {
2412
2418
  fingerprintRowsForIds(hash, database.path, "thread_dynamic_tools", "thread_id", plan.ids);
2413
2419
  }
@@ -0,0 +1,95 @@
1
+ import { spawn } from "node:child_process";
2
+ import { createInterface } from "node:readline/promises";
3
+
4
+ import packageMetadata from "../package.json" with { type: "json" };
5
+ import { getCommandInvocation } from "./platform.mjs";
6
+
7
+ const PACKAGE_SPEC = `${packageMetadata.name}@latest`;
8
+ const INSTALL_ARGS = ["install", "--global", PACKAGE_SPEC];
9
+ const VERSION_ARGS = ["list", "--global", "--depth=0", "--json", packageMetadata.name];
10
+
11
+ async function runCommand(command, args, { captureStdout = false, platform, stderr, stdout }) {
12
+ const invocation = getCommandInvocation(command, args, { platform });
13
+
14
+ return new Promise((resolve, reject) => {
15
+ const child = spawn(invocation.command, invocation.args, {
16
+ stdio: ["inherit", "pipe", "pipe"],
17
+ windowsHide: invocation.windowsHide,
18
+ });
19
+ let errorOutput = "";
20
+ let output = "";
21
+
22
+ child.stdout.on("data", (chunk) => {
23
+ if (captureStdout) output = (output + chunk.toString()).slice(-16_384);
24
+ else stdout.write(chunk);
25
+ });
26
+ child.stderr.on("data", (chunk) => {
27
+ stderr.write(chunk);
28
+ errorOutput = (errorOutput + chunk.toString()).slice(-8_192);
29
+ });
30
+ child.on("error", reject);
31
+ child.on("close", (exitCode) => resolve({ exitCode: exitCode ?? 1, errorOutput, output }));
32
+ });
33
+ }
34
+
35
+ async function confirmSudo({ stdin, stdout }) {
36
+ const prompt = createInterface({ input: stdin, output: stdout });
37
+ try {
38
+ const answer = await prompt.question("Retry the update with sudo? [y/N] ");
39
+ return /^(?:y|yes)$/iu.test(answer.trim());
40
+ } finally {
41
+ prompt.close();
42
+ }
43
+ }
44
+
45
+ export async function updateSessionSteward({
46
+ confirm = confirmSudo,
47
+ currentVersion = packageMetadata.version,
48
+ platform = process.platform,
49
+ run = runCommand,
50
+ stdin = process.stdin,
51
+ stdout = process.stdout,
52
+ stderr = process.stderr,
53
+ } = {}) {
54
+ stdout.write(`Current version: ${currentVersion}\nUpdating Session Steward with npm...\n`);
55
+ let result = await run("npm", INSTALL_ARGS, { platform, stderr, stdout });
56
+ let usedSudo = false;
57
+
58
+ if (result.exitCode !== 0 && /\b(?:EACCES|EPERM)\b/u.test(result.errorOutput)) {
59
+ if (platform === "win32") {
60
+ stderr.write("Global npm install needs permission. Open an elevated terminal and run session-steward update.\n");
61
+ } else if (stdin.isTTY && stdout.isTTY) {
62
+ stdout.write("The global npm install needs elevated permission.\n");
63
+ if (await confirm({ stdin, stdout })) {
64
+ usedSudo = true;
65
+ result = await run("sudo", ["npm", ...INSTALL_ARGS], { platform, stderr, stdout });
66
+ }
67
+ } else {
68
+ stderr.write("Global npm install needs elevated permission. Run sudo session-steward update in a terminal.\n");
69
+ }
70
+ }
71
+
72
+ if (result.exitCode === 0) {
73
+ let installedVersion;
74
+ try {
75
+ const versionResult = await run(
76
+ usedSudo ? "sudo" : "npm",
77
+ usedSudo ? ["npm", ...VERSION_ARGS] : VERSION_ARGS,
78
+ { captureStdout: true, platform, stderr, stdout },
79
+ );
80
+ if (versionResult.exitCode === 0) {
81
+ installedVersion = JSON.parse(versionResult.output)?.dependencies?.[packageMetadata.name]?.version;
82
+ }
83
+ } catch {
84
+ // Installation succeeded, but npm could not confirm the installed version.
85
+ }
86
+
87
+ if (typeof installedVersion === "string" && /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.+-]+)?$/u.test(installedVersion)) {
88
+ stdout.write(`Updated version: ${installedVersion}\n`);
89
+ } else {
90
+ stderr.write("Update completed, but the installed version could not be confirmed. Run session-steward --version.\n");
91
+ }
92
+ }
93
+
94
+ return result.exitCode;
95
+ }
@@ -80,6 +80,6 @@ export async function findAvailableUpdate({
80
80
  }
81
81
  }
82
82
 
83
- export function formatUpdateNotice({ latestVersion, packageName }) {
84
- return `Session Steward ${latestVersion} is available. Update with: npm install -g ${packageName}@latest`;
83
+ export function formatUpdateNotice({ latestVersion }) {
84
+ return `Session Steward ${latestVersion} is available. Update with: session-steward update`;
85
85
  }
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "session-steward",
3
- "version": "0.11.0",
4
- "description": "Codex and Claude Code session manager - browse, back up, and delete old sessions. Local browser UI + CLI.",
3
+ "version": "0.11.2",
4
+ "mcpName": "io.github.mallikcheripally/session-steward",
5
+ "description": "Codex and Claude Code session manager - browse and delete old sessions. Browser UI + CLI + MCP",
5
6
  "license": "MIT",
6
7
  "author": "Mallik Cheripally",
7
8
  "type": "module",
@@ -22,17 +23,19 @@
22
23
  "codex-cli",
23
24
  "codex-sessions",
24
25
  "codex-cleanup",
26
+ "codex-session-manager",
25
27
  "openai-codex",
26
28
  "chatgpt-desktop",
27
29
  "claude-code",
28
30
  "claude-code-sessions",
29
31
  "claude-code-cleanup",
32
+ "claude-code-session-manager",
30
33
  "claude-desktop",
31
34
  "session-cleanup",
32
35
  "session-history",
33
36
  "session-manager",
34
- "disk-space",
35
- "disk-cleanup"
37
+ "automatic-session-cleanup",
38
+ "mcp-server"
36
39
  ],
37
40
  "os": [
38
41
  "darwin",