Skip to content
Back to skills

Walnut Import External Sessions

ASecurity

Import coding-agent sessions started outside Walnut (terminal `claude`, Claude Desktop, codex TUI, other SDK apps) into Walnut as tasks. Use when the user says "import my sessions", "find sessions opened outside Walnut", asks why a session id isn't in Walnut, asks what the "Imported" pill means or why an imported task completed itself, or wants the external-session scan run NOW instead of waiting for the background tick.

  • 32 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added October 1, 2026
developmentgobashgitapidatabase

Works with

  • claude desktop
  • terminal
  • cli
  • api

Security analysis

A100/100

Scanned October 1, 2026

npx -y skills add EvanZhang008/open-walnut --skill walnut-import-external-sessions --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Walnut Import External Sessions?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Walnut Import External Sessions
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/evanzhang008-walnut-import-external-sessions/badge)](https://www.skillsdirectory.com/skills/evanzhang008-walnut-import-external-sessions)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: walnut-import-external-sessions
description: >-
  Import coding-agent sessions started outside Walnut (terminal `claude`,
  Claude Desktop, codex TUI, other SDK apps) into Walnut as tasks. Use when the
  user says "import my sessions", "find sessions opened outside Walnut", asks
  why a session id isn't in Walnut, asks what the "Imported" pill means or why
  an imported task completed itself, or wants the external-session scan run
  NOW instead of waiting for the background tick.
---

# Import External Sessions

Walnut automatically imports sessions that were started outside it (someone ran
`claude` in a terminal, used Claude Desktop or the codex TUI, or another SDK
app spawned sessions). A background job runs every 10 minutes; this skill is
the on-demand path.

Each imported session becomes **its own task**, titled with the session's own
name, grouped under a per-host project: **"Imported from this Mac"** /
**"Imported from \<host\>"**. Inside that project the tasks sit in **one
sub-folder per working directory** (label = the cwd's last two segments, home
collapsed to `~`: `myCode/walnut`, `src/server`, `~/.claude`).

## The imported type (the "Imported" pill)

An imported task carries the tag `walnut:external-sessions`. That tag is the
task's **type**, shown in the task list as an `Imported` pill, and it drives
three automatic behaviours. All of them run inside the same 10-minute tick;
there is no extra timer and no model call.

| Rule | What happens |
|---|---|
| Title | `custom-title` (a `/rename`) beats `ai-title` beats the first user message that is neither a meta line nor a compaction summary, exactly the CLI's own rule. A task still titled with a placeholder (`Claude session 1a2b3c4d` or a compaction summary) is renamed in place the tick its transcript yields a real title. |
| Idle auto-complete | A task whose session has had no activity for `auto_complete_after_days` (default 7) is marked COMPLETE. Rolling: a task imported today is completed the tick it crosses the line. At most 300 per tick, oldest idle first. Only tasks still in an "Imported from …" project: one you moved into your own project is left alone. |
| Adoption | The first message anyone sends to the session removes the tag. The task keeps its project and folder but leaves the imported type: no pill, never auto-completed. Sending to a completed task also reopens it (normal `session:input` rule). |

Existing installs converge on their own: old imports without a folder are filed
into their cwd folder (at most 300 per tick), placeholder titles are re-read by
id (`sessions.describeExternal`, so a transcript older than the scan window is
still fixed) until a real title exists, imports an older scanner took in by
mistake (Walnut's own sessions per the spawn journal, forks, reply-less probes)
are removed together with their session row (each import is re-read once per server start, at most 100 per
tick, open tasks first), and idle imports are swept.

## Run an import now

```bash
curl -s -X POST http://localhost:3456/api/sessions/import-external \
  -H 'Content-Type: application/json' -d '{"days":30}'
```

- `days` widens/narrows the lookback window (default 30).
- Response fields: `imported` new tasks, `retitled` placeholder titles replaced,
  `completed` idle imports auto-completed, `foldered` old imports filed into a
  cwd folder, `removed` imports that were never outside sessions, `skipped` candidates already tracked or excluded. `hostsScanned` /
  `hostsSkipped` say whether a host was reached; a daemon that is not connected
  or too old is skipped. `truncated` means a cap was hit, not that the import is
  finished.

## Check whether a specific session made it in

```bash
walnut sessions --json | grep <session-id-prefix>
```

If it's missing after an import run, the usual reasons:

1. **Host not scanned**: check `hostsSkipped` in the response. The host's
   daemon must be connected and advertise `external-scan-v1`.
2. **Older than the window**: re-run with a bigger `days`.
3. **Directory filter**: SDK sessions under temp directories are never imported;
   `external_session_import.excluded_cwds` (per host) applies to every entry
   point. A host with exclusions configured needs `external-scan-filter-v1`; an
   older daemon is skipped rather than allowed to ignore the rules.

## What gets imported

| Source | Imported? |
|---|---|
| Terminal `claude` / Claude Desktop | Yes, unless a directory rule excludes it |
| codex TUI / Codex Desktop | Yes, unless a directory rule excludes it |
| Other SDK apps | Yes, when the cwd is a real directory and no rule excludes it |
| Walnut's own sessions | Never. It is answered by id, not by guessing. The daemon on each host keeps a **spawn journal**, `~/.open-walnut/local/spawn-journal.jsonl`: one append-only JSON line per session it ever started, under the CLI's own session id, saying how (`new`, `fork` with its `parent`, `resume`) and for whom (the asking Walnut's data dir as `home`, and the `task`). So a session started by ANY Walnut instance on that host (prod, a dev server, an ephemeral test server whose own database is gone) is skipped even when this server holds no record of it, and a removal names who started it. The file stays on its host (git-sync ignores `local/`); at startup the daemon folds older records into it (the per-id marker files it replaced, and its streams captures). Text rules back it up for transcripts older than any record: a programmatic fork (its first message predates earlier lines, copied history), or a Walnut envelope in a user turn (the side-thread cache warm-up, the output-mode reminder) |
| Sessions with no real reply | Never, when the whole transcript was read: a probe or a first turn that only errored has nothing to adopt |
| Subagent sidechains | Never |
| SDK runs under temp directories | Never; a `cli` run in a temp dir needs an explicit rule |

## Configuration

Both keys live under `external_session_import` in the config. Read the existing
section before writing so other hosts' rules survive.

```json
{
  "external_session_import": {
    "auto_complete_after_days": 7,
    "excluded_cwds": { "__local__": ["/tmp/walnut-probes"], "buildbox": ["/home/dev/probes"] }
  }
}
```

- `auto_complete_after_days`: idle window for the sweep; `0` disables it.
- `excluded_cwds`: host alias (`__local__` for this machine) to absolute
  directories. A rule matches the directory and everything under it, not a
  sibling with a similar name. No globs. Rules never delete an already imported
  task or its history; remove a rule and the next scan imports again. One-shot
  Claude probes should run with `--print --no-session-persistence` so they never
  produce a transcript to import.

The `cli` entry point can be inherited by child processes, so it does not prove
a human started the session. Do not delete or merge records on that basis. A
retitle keeps the task id, filing, phase, notes, session links and timestamps;
the scan never modifies a transcript.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.