npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-session-sync

v0.2.24

Published

Cross-device sync for DeepSeek Harness sessions: a dedicated git mirror of the session store, append-only three-way merge with keep-both + fork conflict resolution, /sync command, sync_pull/sync_push/sync_status tools, and configurable auto push/pull

Readme

🔄 dsh-session-sync

  • 1024 store channel: npm i -g dsh1024 once, then dsh1024 plugin --profile web add dsh-session-sync (counts toward the deepseek1024.com install ranking). Gitee dshfind OpenSSF Scorecard

Cross-device session sync for DeepSeek Harness — a dedicated git mirror of your session store.

Sync your sessions between devices, keep both sides on any conflict, never lose a turn.

Official repository. This is the only official repository of dsh-session-sync, maintained by PerryLink. Same-name repositories under other accounts are not affiliated.

License DSH plugin dsh-doctor DSH Market Node CI Version npm version npm downloads

English · 简体中文 · Español · Português · हिन्दी


📖 Ecosystem knowledge base — measured data, not marketing: plugin development guide · plugin-selection data · maintenance criteria.

⭐ 如果它帮到了你

这个插件是 DSH 插件家族的一员(40+ 个,全部 Apache-2.0)。如果你在用,给个 star —— 它不会解锁任何功能,但会让下一个人在搜索里更容易找到它。

English: part of a 40+ plugin family for DeepSeek Harness. If it is useful, a star helps the next person find it — nothing is gated behind it.

What is dsh-session-sync?

Cross-device session sync for DeepSeek Harness — a dedicated git mirror of your session store.

Sync your sessions between devices, keep both sides on any conflict, never lose a turn.

Terminal demo of dsh-session-sync: dsh-session-sync — mirror the session store, then /sync

Animated terminal demo of dsh-session-sync

The same run, animated.

Compatibility

| Surface | Status | |---|---| | Harness | DeepSeek Harness dsh-v0.2.1-alpha.1 (GitHub tag, verified 2026-09-25: full gate chain against the pinned 0.1.7-rc.2 peers). npm dependency line 0.1.7-rc.2, peers >=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0 || >=0.1.6-0 <0.2.0 || >=0.1.7-0 <0.2.0. (adapted 2026-10-04): the conflict fork notice carries the plugin's own producer-owned message source kind - the harness retired the shared plugin kind and refuses it on read-back. | | Node | ^22.19.0 \|\| >=24.0.0 | | Platforms | Anywhere git and DSH run (git-based mirror; no platform-specific code) | | Model | Text-only models fully supported; no vision or extra model capability required |

What you get

dsh-session-sync mirrors your DSH session store into a dedicated git worktree and syncs it to a remote you control — no cloud service, no third-party storage:

  • /sync command — status (branch, sanitized remote, ahead/behind, dirty files, forks), diff, log, pull, push, help.
  • sync_status / sync_pull / sync_push tools — the same surface for the model, inside a turn.
  • Append-only conflict resolution — session logs are append-only; on any divergence the plugin keeps both sides (local version kept, remote version preserved as fork files) and never silently overwrites. Diverged sessions can also fork at the session level.
  • Auto modes — pull on start, push after every closed turn, and periodic pull, all configurable and all reversible.
  • Confirmation-gated writes — pull/push ask first (through userQuestions or approval); read-only surfaces never ask; with no answerer the operation fails closed.
device A                              remote (your git repo)                  device B
$DSH_HOME/sessions ──mirror──▶ commit ──push──▶ [sessions] ──pull──▶ merge (keep-both + fork)

Quick start

dsh plugin --profile web add github:PerryLink/dsh-session-sync
# 1. install the bundle into your profile
dsh plugin --profile web add github:PerryLink/dsh-session-sync

# or from npm (published releases)
dsh plugin --profile web add dsh-session-sync

# 2. point it at a private git remote and verify the row
dsh --profile web --dump-config | grep -A2 'id: session-sync'

Then set the remote in your profile patch (a private repository is the baseline) and sync:

- insert:
    - id: session-sync
      name: dsh-session-sync
      config:
        remote: [email protected]:you/your-dsh-sessions.git
> /sync status
> /sync pull
> /sync push

Install & uninstall

  • git channel (latest main): dsh plugin --profile web add github:PerryLink/dsh-session-sync (equivalent to installing from git+https://github.com/PerryLink/dsh-session-sync.git). No build step — index.mjs and lib/ are the shipped artifacts.
  • npm channel (published releases): dsh plugin --profile web add dsh-session-sync.
  • tarball channel: pnpm pack in this repo, then dsh plugin --profile web add ./dsh-session-sync-<version>.tgz.
  • uninstall: dsh plugin --profile web remove dsh-session-sync (or remove the row from the profile patch).

Configuration

All tunables are Schemastery Config fields (changeable from cordis.yml). An id-targeted override replaces the whole row — restate every key you need. cordis.patch.yml documents each key inline.

| Key | Default | Meaning | |---|---|---| | enabled | true | Master switch; false unregisters the command, tools, listeners, and auto modes | | backend | git | Sync backend: git (plaintext mirror) or encrypted (age-encrypted mirror content) | | sessionRoot | '' | Session store root; empty = $DSH_HOME/sessions (both missing fails load) | | repoDir | '' | Sync worktree root; empty = $DSH_HOME/dsh-session-sync/repo | | remote | '' | Remote address (required before pull/push; status/diff work without one) | | branch | main | Remote branch name | | gitBin | git | git executable path | | ageBin | age | age executable path (probed for backend: encrypted; missing degrades to plaintext) | | ageRecipient | '' | age recipient (public key or identity string); empty = cannot encrypt, degrades to plaintext | | ageIdentity | '' | Path to a passphrase-less age secret key for decryption; empty = cannot decrypt, degrades to plaintext | | autoPullOnStart | false | Pull once when the plugin mounts (config is the grant; no re-confirm) | | autoPushOnTurnEnd | false | Push after every closed turn | | pullIntervalMinutes | 0 | Periodic pull every N minutes (0 = off, max 10080) | | confirmVia | auto | Confirmation channel: auto (userQuestions first, then approval), userQuestions, approval | | graceMs | 10000 | Grace period for git kills (ms) | | commandTimeoutMs | 120000 | Per-command timeout (ms) | | maxOutputBytes | 262144 | Per-stream collected-output cap (bytes) | | commitName | dsh-session-sync | Commit author name | | commitEmail | dsh-session-sync@localhost | Commit author email | | registerCommand | true | Register the /sync command | | registerTools | true | Register the sync_* tools when the tools service is present |

Example override in your profile patch:

- insert:
    - id: session-sync
      name: dsh-session-sync
      config:
        remote: [email protected]:you/your-dsh-sessions.git
        branch: main
        autoPushOnTurnEnd: true
        pullIntervalMinutes: 30
        confirmVia: userQuestions

Tools & surfaces

| Surface | Read-only | Needs confirmation | Notes | |---|---|---|---| | /sync status | ✅ | — | Branch, sanitized remote, ahead/behind, dirty files, fork files, last pull/push | | /sync diff | ✅ | — | Uncommitted changes + HEAD..remote stat (read-only) | | /sync log | ✅ | — | Last commits in the sync repository | | /sync pull | | ✅ | Fetch + merge with keep-both semantics; local kept, remote preserved as forks | | /sync push | | ✅ | Mirror + commit + push; never force-pushes, reconciles and retries once on rejection | | sync_status | ✅ | — | Same facts as /sync status for the model | | sync_pull | | ✅ | Model-callable pull | | sync_push | | ✅ | Model-callable push |

Permissions & data

  • Permissions: mutating operations cross the confirmation gate (confirmVia); the plugin never re-implements or bypasses the harness's userQuestions/approval services. Auto modes are covered by the config grant and never re-confirm.
  • Data: sync metadata (device id, last pull/push, last push head, last error) lives in the session-sync storage domain. Session files are copied as opaque bytes — the plugin never parses them. The device id is also written to device.txt in the sync repository for cross-device fork attribution.
  • Session log: sync/push, sync/pull, and sync/conflict are declared in types.d.ts; they are appended only when the host records the types (see Known limitations). Everything written or shown is sanitized. The one durable message the plugin writes — the conflict fork notice — carries the plugin's own producer-owned source kind (dsh-session-sync); the harness retired the shared plugin kind and refuses it when a session is read back.

Security boundaries

  • Never silently overwrite. The append-only three-way merge keeps both sides on any divergence; fork files are never deleted, and git never force-pushes, resets, rebases, or switches branches.
  • Path containment. Files are mirrored as opaque bytes with symlinks refused and every joined path containment-checked (PATH_UNSAFE fails loud).
  • Sanitized output. Remote-URL credentials, tokens, and key=value secrets are redacted before reaching the model or the log; path display refuses anything outside its root.
  • No credential storage. The plugin stores no credentials; git credentials live in your normal git credential helper. age keys are read from paths you configure (ageIdentity); keys never enter the sync repository.
  • Git hardening. Git runs with GIT_TERMINAL_PROMPT=0 and GIT_OPTIONAL_LOCKS=0, deadline- and signal-bounded, with a per-stream output cap.
  • Fail closed. A missing confirmation answerer, a missing remote, or an unsafe path refuses the operation loudly.

Encryption & threat model

backend: encrypted adds an optional age layer above the mirror: session bytes are encrypted into encrypted/**/*.age files before they are committed and pushed, and decrypted back to the local plaintext mirror before merging. The three-way merge always runs on plaintext locally, so the append-only keep-both semantics are unchanged.

What the encryption protects:

  • Mirror content at rest in the remote. The session files you push are age ciphertext; the remote host, its operators, and anyone who clones the repository do not see plaintext session bytes without the private key.

What it does not protect (the boundary):

  • Keys and age identities are yours to manage. The recipient/identity files are never shipped, stored, or rotated by the plugin. If a key leaks, the mirror content it protects is exposed. Use a passphrase-less identity and keep it out of the repository.
  • The remote is still a private repository in practice. git metadata — commit messages, the .gitignore, the encrypted/ path structure, branch names, and push/fetch activity — remains visible to the remote host. Encryption hides the content, not the fact that you sync, nor the shape of your session tree.
  • Plaintext still exists locally. The mirror at <repoDir>/sessions/ is plaintext on disk; encryption protects the transmitted/remote copy, not local disk encryption or the live session store.
  • graceful degradation means plaintext. With backend: encrypted, if age is missing, or ageRecipient/ageIdentity is empty, the plugin falls back to the plaintext git path and warns explicitly in the status/log — it never silently pretends to encrypt. Check /sync status for the warning before trusting the remote as encrypted.

Baseline: with backend: git (the default), session bytes are stored unencrypted in your git remote — use a private repository.

Known limitations

  • Object storage backend reserved. object-storage is an interface placeholder and fails loudly at load; only git and encrypted are implemented.
  • git required. The plugin needs the git executable and the subprocess service; without them, sync operations fail with a clear reason (profiles keep booting).
  • age is optional, external. Encryption depends on the age binary on PATH (or ageBin). No age → plaintext fallback with a warning; a passphrase-protected identity cannot be used (decryption would block on a TTY prompt, so it fails closed).
  • One repoDir per backend. Switching between git and encrypted on the same repoDir is not supported; use a fresh worktree per backend.
  • Session events on 0.1.0-rc.6/0.1.0-rc.8/0.1.1-rc.2/0.1.2-alpha.2/0.1.2-alpha.3/0.1.2-rc.1/0.1.7-alpha.2. The harness does not record sync/* event types, so the session-log appends are skipped (sessions keep loading); the plugin enables them automatically once a host records the types or exposes the ignorable envelope on Session.append.
  • approval between turns. /sync runs between turns, where the approval channel has no open turn to attach to; use confirmVia: userQuestions for command-driven sync, or drive sync through the tools inside a turn. The open-turn check reads the host turnBoundary session projection: a composition without @deepseek-ai/dsh-session-projection cannot verify the turn state and fails closed with that reason.
  • Host-private artifacts stay host-private. session.lock (the harness session lease) and session.migration.*.tmp staging files are never mirrored or deleted — they are runtime state, not syncable content. Session logs (session.jsonl, session.v[1-9]*.jsonl[.zstd]) remain the mirrored payload.

Development

pnpm install                                       # node ^22.19 || >=24
pnpm run typecheck && pnpm run typecheck:ci        # tsc --checkJs against the published 0.1.7-alpha.2 peers
pnpm test                                          # node --test (13 test files; the engine git suite skips without git)
pnpm run verify:self-contained                     # dependency specs resolve from the registry
pnpm run verify:artifacts                          # shipped files present + index.mjs importable
pnpm run check:readmes                             # five-language README consistency
pnpm pack                                          # the published tarball

There is no build step: pure ESM, index.mjs and lib/ are the shipped artifacts.

Topics

dsh, dsh-plugin, deepseek-harness, deepseek, cordis, session-sync, session, git, sync, cross-device

Contributors

  • @PerryLink — creator and maintainer: git mirror engine, append-only keep-both merge, /sync command and sync_* tools, auto modes, sanitizers, and the five-language docs.

PerryLink DSH Plugin Family

This project is one of the 33 actively maintained DeepSeek Harness plugins from PerryLink — the roster is 42, of which 6 are frozen and 3 retired; every one keeps its row below, with the reason in the Status column. If this one helps you, the others likely will too:

| Plugin | One-liner | Status | |---|---|---| | dsh-auto-review | Second-model auto-review on the approval chain, fail-closed by default | | | dsh-autotier | Automatic strong/cheap model-tier routing with deterministic risk guards and a /tier command | | | dsh-background-agents | Durable background child agents with a Web UI sidebar, messaging and interrupt | 🚫 RETIRED — see the note above | | dsh-budget | Cost governance for DeepSeek Harness: budgets, carbon, and latency in one panel. | 🧊 FROZEN — see the repo README | | dsh-catalog | DSH Desktop Market standard catalog source for the PerryLink family | | | dsh-cert-mcp | Read-only MCP server exposing the certification registry: grades, snapshots and five-dimension evidence | | | dsh-checkpoint-rewind | Claude Code /rewind-equivalent: snapshots, session forks, one-shot restore | | | dsh-claude-move | Migrate Claude Code sessions, memory, skills and CLAUDE.md into DSH | 🧊 FROZEN — see the repo README | | dsh-click | Cross-platform native desktop control for DeepSeek Harness — Windows first. | | | dsh-composer-history | Terminal-style input history for the web composer: arrows, Ctrl+R search | | | dsh-data-quality | Dataset quality checks and citation cross-checks (the optional numeric bridge consumed here) | | | dsh-defend | Prompt-injection, jailbreak, and secret-leak defense for DeepSeek Harness. | 🧊 FROZEN — see the repo README | | dsh-doublecheck | Engineering-discipline guard: requirements grill, test gates, adversary review | | | dsh-draw | Unified static-image generation routing for DeepSeek Harness. | 🧊 FROZEN — see the repo README | | dsh-fast | Read-only performance diagnostics for DeepSeek Harness. | | | dsh-fund-research | Deterministic research reports for Chinese public mutual funds | | | dsh-github | GitHub PR/issues integration for DSH, every write gated by approval | | | dsh-industry-research | Industry research orchestration that seals its deliverables through this plugin's ctx.researchReport.assemble | | | dsh-laya | Laya typed decisions (noul/choice/score) as a first-class Cordis service and model-visible tools | | | dsh-library | Local document knowledge base for DeepSeek Harness. | | | dsh-local-ai | Local-model (Ollama) integration for DeepSeek Harness. | | | dsh-lsp-actions | LSP diagnostics, formatting, completion, code actions and rename over language servers | | | dsh-mask | PII masking middleware: anonymize at the model boundary, restore at the display layer | | | dsh-mcp-panel | Read-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors | | | dsh-memento | Approval-gated cross-session memory: ctx.memory seam + SQLite + memory tool | 🧊 FROZEN — see the repo README | | dsh-observe | OpenTelemetry and Langfuse observability exporter for DeepSeek Harness. | | | dsh-output-styles | Claude Code outputStyles-equivalent runtime style switching | | | dsh-permission-rules | Claude Code-style declarative allow/deny/ask permission rules with audit | | | dsh-plugin-certification | Community certification registry with repro-checkable grades and badges | | | dsh-plugin-doctor | Zero-dependency static + sandbox smoke detector for DSH plugins | | | dsh-plugin-guide | Plugin-development knowledge base as an on-demand agent skill | | | dsh-plugin-kit | Shared zero-runtime-dependency toolkit for the PerryLink DSH plugins | | | dsh-plugin-upgrade | One-package, one-corridor-index plugin upgrade skill: routes a repository to the matching closed corridor card | | | dsh-plugin-upgrade-015 | Merged 0.1.3-alpha.1 → 0.1.5-rc.1 upgrade corridor card plus a zero-dependency seam scanner | 🚫 RETIRED — corridors carried by dsh-plugin-upgrade | | dsh-reach | Multi-channel approval/question bridge: WeChat/Telegram/Feishu, session console | 🧊 FROZEN — see the repo README | | dsh-research-report | Verifiable research-report engine: content-addressed evidence ledger and sealed versions | | | dsh-score | Multi-dimensional quality scoring for DeepSeek Harness plugins. | | | dsh-session-pin | Pin sessions in the Web sidebar with durable ordering | 🚫 RETIRED — see the note above | | dsh-session-sync | Cross-device session sync for DeepSeek Harness — a dedicated git mirror of your session store. | | | dsh-skill-pack-security | Security-audit skill pack: secret scan, dependency and supply-chain review | | | dsh-talk | Voice-first session loop for DeepSeek Harness: talk to it, hear it answer. | | | dsh-team-rooms | Cross-session team rooms: shared message bus, task board and timeline | 🚫 RETIRED — see the note above | | dsh-test-drive | Isolated install-and-smoke test drives for DeepSeek Harness plugins. | | | dsh-ticktick | TickTick/Dida365 task bridge: session-header panel + 11 tools | | | dsh-translate | Vendor parameter translation and deterministic JSON repair for DeepSeek Harness. | |

Install from the DSH Desktop Market

All PerryLink plugins are browsable in the built-in DSH Desktop Market: Market → Sources → add source → paste https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json → select it. Installation still goes through the Market's npm-identity verification and your confirmation.

License

LICENSE (Apache License 2.0) © 2026 dsh-session-sync contributors