Back up, verify, reclaim, restore, and review Codex session context across macOS and Windows.
SessionHarbor is an unofficial, local-first Codex plugin and zero-dependency Node.js CLI by Xiaofan Wang. It turns an external drive or mounted NAS into a verified filesystem vault for every stable local Codex rollout.
| Outcome | What SessionHarbor does |
|---|---|
| Back up every Codex session | Incremental, content-addressed backup with SHA-256 read-back and immutable device-owned snapshots. |
| Free local disk space safely | Keeps backup and cleanup separate; old originals become eligible only after inactivity, backup-age, open-file, and fresh verification gates. |
| Restore deleted local conversations | Materializes the verified raw rollout without consuming the vault copy. |
| Bridge multiple Codex computers | Lets macOS and Windows devices inspect verified peer inventories and stage reviewed, evidence-linked context. |
Open a new Codex task and paste the complete pinned prompt for English or 简体中文. A compact version is:
Set up SessionHarbor from https://github.com/WangPeterXF/session-harbor using the pinned v0.3.1
bootstrap prompt. Verify the owner, tag, license, and plugin before installing. Make this task my
SessionHarbor management center, start with the read-only dashboard, and do not mutate any real
session or drive without a separate explicit approval.
The setup verifies WangPeterXF/session-harbor and the pinned release before installing the
repo-local marketplace plugin. Installation, destination initialization, backup publication, local
cleanup, restore, and scheduling remain separate decisions.
AGENTS.md: repository-wide safety invariants, source map, validation, and review rules.docs/agent-index.md: compact task router for installation, operation, and development.llms.txt: small web index pointing to authoritative Markdown sources.llms-full.txt: generated combined context, checked for drift in CI.evals/plugin-discovery.json: five positive and three negative prompts for discovery precision and recall.
Project page: https://wangpeterxf.github.io/session-harbor/
SessionHarbor is source-available for noncommercial use under the PolyForm Noncommercial License 1.0.0. Commercial use requires a separate written license; see commercial licensing. Because the license restricts commercial use, SessionHarbor is not Open Source Initiative (OSI) open-source software.
Version 0.3.1 implements full incremental backup, verified local cleanup, restore, cross-device
continuity, a conversational management dashboard, and multi-mode scheduling. Automated validation uses synthetic Codex homes, temporary
vaults, simulated interruptions, and Mac/Windows path fixtures. Each installation must still pass the
physical-drive checklist before local cleanup is enabled.
SessionHarbor never edits Codex SQLite, session_index.jsonl, generated memories, authentication, or
project files. It does not promise exact sidebar reconstruction. Raw JSONL remains the restore and
evidence source.
The initial cross-platform validation record, Windows defects found during physical-drive testing, and remaining preview limitations are summarized in the v0.3.1 release notes.
The repository includes copy-ready bootstrap prompts for
Chinese and English, pinned to the
official WangPeterXF/session-harbor v0.3.1 release. The prompt asks Codex to verify the pinned
repository and license, add the repository marketplace, install the plugin, read the verified skill
for the current chat, and turn that task into the user's long-lived SessionHarbor management center.
Official Codex behavior makes newly installed plugin skills available to new chats. The bootstrap prompt does not pretend the plugin hot-loaded: it explicitly reads the verified skill in the setup chat so that chat can continue immediately, while later chats use the normal installed plugin.
The management task starts read-only:
session-harbor dashboard --json --limit 50
session-harbor dashboard --state unbacked
session-harbor dashboard --state deleted
session-harbor dashboard --state waiting-backup-ageIt reports cataloged/current/pending backups, local deletions, restorable sessions, retention waits, latest publication, and applied-backup progress. See the management-center workflow.
The settings the project exposes are deliberately separate:
{
"backup": {
"scope": "all",
"allowPartial": true,
"verifyExistingObjects": false
},
"retention": {
"cleanupAfterInactiveDays": 30,
"minimumBackupAgeDays": 7,
"reclaimAction": "keep",
"autoReclaim": false
}
}backup.scope: alwaysall; backup age and file size never filter disaster-recovery coverage.backup.allowPartial: a changing/open session is reported and retried on the next trigger while other stable sessions can still be backed up.backup.verifyExistingObjects:falsemakes insertion/weekly runs compare stable source metadata and stored object sizes, then hash only new or changed content. Set it totruefor a deliberately slower full scrub;verifyand restore always perform cryptographic verification.cleanupAfterInactiveDays: only local sessions inactive for this many days enter cleanup review.minimumBackupAgeDays: keep the local original for this additional safety period after its latest verified backup revision.reclaimAction:keepkeeps the local original indefinitely;linkreplaces it with a reversible link to a stable mounted vault;deleteremoves only the verified local original and remains restorable from the vault.
autoReclaim: lets an explicitly installed schedule include a separate reclaim scope. It is off by default.
backup never deletes or links a local file. cleanup/reclaim is a different command. Delete mode
requires both --apply and --confirm-delete-local; autoReclaim defaults to false.
Legacy config v1-v3 age/grace keys migrate into config v4. Existing reclaim actions are preserved;
new configs default to keep.
Publication follows this order:
- Verify the destination identity marker and stable device identity.
- Read a stable local source and compute SHA-256.
- Copy to a same-directory temporary file, sync it, hash the stored bytes, and publish atomically.
- Publish an immutable snapshot manifest.
- Replace the device-owned head pointer last.
Cleanup is allowed only when the destination copy still matches the current local source, the inactivity and backup-age gates have elapsed, and the source is not open. A missing/mismatched volume, changed source, target conflict, corrupt object, symlinked path component, peer rollback, or unknown contract fails closed. Restore keeps the archive copy.
Fast scheduled backup does not replace periodic integrity verification. Run session-harbor verify
manually after unsafe removal, filesystem errors, or before enabling cleanup; cleanup itself always
re-hashes both local source and vault target before changing the local file.
- Node.js 20 or newer
- A stable filesystem destination such as an exFAT external drive or mounted NAS
- macOS or Windows for the intended two-computer workflow
- Optional:
codex-slimfor lossless zstd compression
Use exchange.storageClass: "stable-mounted" for an external drive/NAS. iCloud, Baidu Netdisk, or
another client-managed synchronized folder must use "client-synced" together with reclaim action
keep; SessionHarbor rejects link/delete reclamation for that class.
Every command below is read-only until its applied form is explicitly used:
node plugins/session-harbor/scripts/session-harbor.mjs \
init --destination /path/to/EXTERNAL_DRIVE/SessionHarbor
node plugins/session-harbor/scripts/session-harbor.mjs doctor --json
node plugins/session-harbor/scripts/session-harbor.mjs device init --json
node plugins/session-harbor/scripts/session-harbor.mjs bridge doctor --json
node plugins/session-harbor/scripts/session-harbor.mjs backup plan --json
node plugins/session-harbor/scripts/session-harbor.mjs cleanup --jsonApplied destination/device initialization, first session publication, and first local reclamation are three separate approvals. See the live-readiness checklist before using a physical drive.
After reviewing the dry-run and granting the corresponding scope:
# Preview and then incrementally back up every stable local session.
session-harbor backup plan
session-harbor backup run --apply
# Preview local reclamation after the configured grace.
session-harbor cleanup --json
# Prefer exactly one target for cleanup pilots.
session-harbor cleanup --session <session-id> --reclaim-action delete --json
# Link mode.
session-harbor cleanup --apply
# Delete mode requires the extra confirmation token.
session-harbor cleanup --apply --confirm-delete-local
session-harbor verify --json
session-harbor restore <session-id> # dry-run
session-harbor restore <session-id> --applyRetention settings can be reviewed and changed independently. settings set is a dry-run unless
--apply is added:
session-harbor settings show
session-harbor settings set --cleanup-after-inactive-days 30 \
--minimum-backup-age-days 7 --reclaim-action keeparchive, reclaim, and policy remain compatibility/advanced commands. --finalize is retained
as a high-risk compatibility override that can bypass the backup-age gate. It
is not emitted by either scheduler.
Each device writes only devices/<its-device-id>/...; no shared database or peer-tree writes are
used.
session-harbor sync status --json
session-harbor sync pull --peer <device-id> --json
session-harbor sync pull --peer <device-id> --include-objects --apply
session-harbor sync export <device-id> <session-id> --output <path>
session-harbor sync export <device-id> <session-id> --output <path> --applyMetadata caching supports an explicitly stale offline view. Raw object caching is opt-in. Peer export materializes a verified JSONL copy but does not mutate Codex indexes or reconstruct its sidebar.
Local reclamation never propagates as a cross-device deletion; immutable evidence remains referenced.
Map different local paths to the same portable project ID:
session-harbor project map session-harbor /local/project/path
session-harbor project map session-harbor /local/project/path --applyThen use the reviewed-memory workflow:
session-harbor memory draft --project session-harbor --input draft.json
session-harbor memory draft --project session-harbor --input draft.json --apply
session-harbor memory approve <draft-id> --project session-harbor
session-harbor memory approve <draft-id> --project session-harbor --apply
session-harbor memory diff --peer <device-id> --project session-harbor
session-harbor memory stage --peer <device-id> --project session-harbor
session-harbor memory stage --peer <device-id> --project session-harbor --apply
session-harbor memory status --project session-harborEvery entry needs a verified session ID, exact session SHA-256, and locator. Drafts remain private;
only approved snapshots become peer-visible. Restricted entries require explicit inclusion at
approval and staging. staged is SessionHarbor context, not native Codex memory and not an adopted
project instruction.
session-harbor migrate codexbridge plan --source /path/to/old/CodexBridge
session-harbor migrate v01 plan --source /path/to/old/SessionHarborThe applied forms create new verified objects and snapshots without changing the old payload or catalog. No migration cleanup command exists.
The Windows handoff protocol keeps each device in its own immutable writer
tree and defines a write-back result format. The Mac prepares a checksummed source snapshot under a
separate SessionHarbor-Handoff directory on the removable drive; Windows copies it to a local NTFS
development directory, tests there, then writes only its own result file back to the handoff folder.
macOS:
node plugins/session-harbor/scripts/launchagent.mjs install \
--config ~/.config/session-harbor/config.json --applyWindows:
node plugins/session-harbor/scripts/windows-task.mjs render `
--config "$HOME\.config\session-harbor\config.json"Install/uninstall remains dry-run without --apply. By default, macOS combines true filesystem-mount
and weekly triggers; Windows combines weekly execution with a configurable 15-minute drive-presence
poll because Task Scheduler has no portable volume-arrival trigger. The command is idempotent and a
missing configured drive is a safe no-op. Use --no-on-mount or --no-weekly to select one mode;
manual backup run --apply is always available. Generated backup schedules never clean local files.
A cleanup schedule must be explicitly requested, and delete scheduling additionally requires
--confirm-delete-local.
npm ci --ignore-scripts
npm run check
npm test
npm pack --dry-run --jsonThe contract schema is in
schemas/session-harbor-contracts-v1.schema.json,
with semantic checks in bridge-contracts.mjs. The design, threat model, milestone evidence, and
release gates are under docs/.
Raw rollouts can contain prompts, code, paths, tool output, images, credentials, and personal data. SHA-256 detects corruption but does not encrypt the drive or authenticate another writer. Use encrypted storage where loss of an unencrypted drive would be unacceptable.
SessionHarbor is not affiliated with or endorsed by OpenAI. See LICENSE, COMMERCIAL-LICENSE.md, PRIVACY.md, TERMS.md, SUPPORT.md, CONTRIBUTING.md, SECURITY.md, and THIRD_PARTY.md.
