
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
dsh-import-agents
Advanced tools
Import pi / opencode sessions, chat history, and agents into DeepSeek Harness (dsh): slash commands, session-start migration prompt, and a one-click Sync button in the composer.
English · 简体中文
dsh-import-agents imports sessions, chat history, and agents from pi, opencode, codex, and claude-code into DeepSeek Harness (dsh). Imported sessions appear in the session list and can be resumed with the full conversation history as context; custom agents and mode prompts become discoverable dsh skills; a one-click Sync button in the composer runs the whole import.
| Resource | Link |
|---|---|
| 中文文档 | README.zh.md |
| npm package | dsh-import-agents |
| Source code | github.com/Chang-Tong/dsh-import-agents |
$DSH_AGENTS_HOME/skills, with provenance recorded in frontmatter (metadata.source / metadata.kind)./import-all and shows the result inline.cwd (created on demand); /attach-workspaces retro-fits existing imports.pi-<uuid> / oc-<id> / codex-<id> / claude-<id>); re-imports skip what already exists.node:zlib zstd, node:sqlite) plus dsh platform modules.Taken from a clean Docker demo environment (English UI) with sample pi / codex sessions.
The dsh web UI with the Sync button in the composer tool row:

Clicking Sync runs the full import and shows the result inline:

Imported sessions land in a workspace matching their original project folder, with source-tagged titles ([pi], [opencode], [codex], …):

An imported session opens like a native dsh session — text, reasoning, and tool calls are preserved, and you can keep talking:

Tool calls survive the import as real trajectory entries — the Trajectory tab renders a card per call (here a bash call from the imported codex session):

The plugin is published on npm as dsh-import-agents and declares a dsh.bundle, so the official one-command installer activates it automatically.
dsh plugin --profile web add dsh-import-agents
dsh plugin add installs the package and appends it to the profile's bundle list (the layer is active — no manual config). Then restart dsh web and refresh the page.
Every
pnpmverb works throughdsh plugin --profile <name>— e.g.dsh plugin --profile web remove dsh-import-agentsuninstalls.
The <spec> argument is a standard pnpm package spec:
| Source | Command |
|---|---|
| npm (latest) | dsh plugin --profile web add dsh-import-agents |
| npm (exact / range) | dsh plugin --profile web add dsh-import-agents@0.2.4 · @^0.2 |
| GitHub (short) | dsh plugin --profile web add github:Chang-Tong/dsh-import-agents |
| GitHub (pinned commit) | dsh plugin --profile web add github:Chang-Tong/dsh-import-agents#<sha> |
| Git URL | dsh plugin --profile web add git+https://github.com/Chang-Tong/dsh-import-agents.git · #v0.2.4 |
| Local checkout | cd <checkout> && dsh plugin --profile web add . or file:/path/to/dsh-import-agents |
| Dev link | dsh plugin --profile web add link:/path/to/dsh-import-agents |
| Tarball | dsh plugin --profile web add ./dsh-import-agents-0.2.4.tgz (or an https://… URL) |
Notes:
., ../plugin, and their file: / link: forms) are anchored to the invoking directory — add . from a plugin checkout installs that checkout.prepare script, which pnpm ≥ 10 blocks until allowed: the first add fails with an allowBuilds hint — copy the printed key into the profile's pnpm-workspace.yaml and re-run. Installing a built tarball or a local checkout needs no allowance.dsh.bundle join the layer stack automatically; bundle-less packages install as plain dependencies (one-time warning).dsh web — the host plugin registers its slash commands at startup; the client bundle (the Sync button) is served automatically./import-all answers in the input.# optional sanity checks
npm view dsh-import-agents version # latest published version
pnpm list dsh-import-agents # installed in the profile
Disable the session-start migration prompt with
config: { offerOnStart: false }on the inserted row. Source paths and defaults are overridable the same way — see Configuration.
/import-all in the input.Everything is idempotent — run it as often as you like; already-imported sessions are skipped.
| Command | What it does |
|---|---|
/import-pi [options] | Import pi sessions |
/import-opencode [options] | Import opencode sessions |
/import-codex [options] | Import codex sessions |
/import-claude-code [options] | Import claude-code sessions |
/import-agents | Convert pi/opencode agents & prompts into dsh skills |
/import-all [options] | All of the above (4 sources + agents) |
/attach-workspaces | Attach imported sessions to cwd-matched workspaces (retro-fit) |
Options: --limit N · --project <substr> · --since <iso|ms> · --no-tools · --tools-as-text · --tool-truncate N
node import.mjs all # dry-run preview (writes nothing)
node import.mjs all --apply # write sessions + skills
node import.mjs sessions codex --apply --limit 20 # one source at a time
node import.mjs agents --apply # agents/prompts → skills only
node export.mjs # export sessions as Markdown for any agent to read
import.mjs defaults to dry-run; pass --apply to write.all imports pi + opencode + codex + claude-code + agents — the same four sources as the in-GUI /import-all.export.mjs writes $DSH_HOME/exports/<source>/<session-id>.md (--source, --project, --limit, --since, --out, --no-reasoning, --no-tools).flowchart LR
subgraph sources["Local data"]
PI["pi sessions<br/>~/.pi/agent/sessions/*.jsonl"]
OC["opencode sessions<br/>~/.local/share/opencode/opencode.db"]
CX["codex sessions<br/>~/.codex/sessions/**/*.jsonl"]
CC["claude-code sessions<br/>~/.claude/projects/**/*.jsonl"]
AG["pi agents & prompts<br/>opencode agents"]
end
subgraph plugin["dsh-import-agents"]
R["readers<br/>pi / opencode / codex / claude-reader"]
C["convert<br/>turn structure + tool events"]
W["write<br/>dsh JSONL persistence<br/>or ctx.sessionPersistence"]
S["skills<br/>SKILL.md bundles"]
end
subgraph dsh["DeepSeek Harness"]
SL["session list & resume"]
TR["trajectory & tool cards"]
SK["ctx.skills.list()"]
end
PI --> R
OC --> R
CX --> R
CC --> R
AG --> S
R --> C --> W --> SL
W --> TR
S --> SK
The importer is a pure converter: lib/ parses each source format into a normalized message stream, then emits the exact dsh JSONL event layout (checksummed zstd frames, project-dir encoding) — byte-for-byte the format the dsh persistence backend reads back with its own list / load / prepare.
Sessions. Each user message opens a turn (turn/start + user/message); following assistant messages join it with increasing step numbers; every turn closes with turn/end. pi thinking → dsh reasoning blocks. pi toolCall, opencode tool, claude tool_use, codex tool_use → tool-call content blocks plus paired tool/call + tool/result events: the trajectory UI renders call cards, and the placeholder tool/result answers every tool_calls so OpenAI-compatible APIs accept resumed requests. --tools-as-text switches to plain text (no trajectory cards); --no-tools drops tool calls. Mechanical records (step-start, patch, compaction, …) are skipped.
Agents & prompts → skills. Written to $DSH_AGENTS_HOME/skills/<name>/SKILL.md (default ~/.agents/skills/), discoverable via ctx.skills.list(). Name conflicts are renamed <name>-<source> (e.g. k3-reviewer-opencode); existing bundles are only completed, never clobbered; identical content is skipped; frontmatter records metadata.source / metadata.kind.
| Key | Default | Meaning |
|---|---|---|
offerOnStart | true | Ask about migration when a new top-level session starts |
piRoot | ~/.pi/agent/sessions | pi session root |
piAgentRoot | ~/.pi/agent | pi agents & prompts root |
opencodeDb | ~/.local/share/opencode/opencode.db | opencode SQLite path |
opencodeConfig | ~/.config/opencode | opencode agents root |
codexRoot | ~/.codex/sessions | codex session root |
claudeRoot | ~/.claude/projects | claude-code projects root |
skillsRoot | $DSH_AGENTS_HOME/skills | skills output root |
toolTruncate | 1000 | tool-call arguments truncation (chars) |
The migration prompt only fires for brand-new top-level sessions (startup, not subagents) that have a cwd and unimported history. Per-project decisions and the global agents decision are stored in $DSH_HOME/import-pi-opencode-state.json; headless environments without a UI provider silently skip the prompt.
verify.mts — mounts the real dsh JSONL backend + skill provider on staged output (node --import tsx/esm ../dsh-import-agents/verify.mts <sessions-root> <skills-root> from the dsh checkout) → expects SESSIONS ALL PASS / SKILLS ALL PASS.plugin/plugin-test.mts — end-to-end: loads the plugin on a real cordis context, runs the commands and the session-start migration offer, asserts idempotency and state persistence.tests/ — Vitest component tests for the Sync button (sync-button.spec.tsx, sync-button-hide.spec.tsx), plus opencode-reader.spec.ts and attach-workspaces.spec.ts.macos-latest, Node 22): pnpm install → pnpm run build → npx vitest run.pnpm install # devDependencies (esbuild, vitest)
pnpm run build # rebuild lib/client.js (Sync button bundle)
npx vitest run # component tests
Why does Sync say "new imports 0, skipped N"? Idempotency working as intended: those sessions were imported before, so they are skipped. Nothing is duplicated.
Tool call results are missing — why?
The source formats do not store tool results, only the calls. Imports keep the calls as tool-call blocks with placeholder tool/result events, so the trajectory renders cards and resumed requests stay API-legal.
Will it keep asking me to migrate?
Only while unimported sessions exist, and only per project. Once you decline or an import completes, the decision is remembered in $DSH_HOME/import-pi-opencode-state.json.
Why do I need to refresh after a dsh restart? The old page's RPC connection is gone after a restart; commands (and the Sync button) fail until you refresh.
Node version requirement?
Node ≥ 22.19 — same baseline as dsh (node:sqlite, zstd via node:zlib).
MIT — see LICENSE.
FAQs
Import pi / opencode sessions, chat history, and agents into DeepSeek Harness (dsh): slash commands, session-start migration prompt, and a one-click Sync button in the composer.
The npm package dsh-import-agents receives a total of 55 weekly downloads. As such, dsh-import-agents popularity was classified as not popular.
We found that dsh-import-agents demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.