DEV Community

Cover image for Pick up waiting AI work without digging through finished sessions
uehara
uehara

Posted on

Pick up waiting AI work without digging through finished sessions

claude --resume lets you go back to an earlier Claude Code conversation started in the same folder, by picking it from a list. The catch is that list: sessions still waiting for an answer sit beside sessions that already finished, and nothing marks which ones are still waiting. So I stopped closing waiting sessions at all.

The problem is not specific to Claude Code. Anyone who hands work to an AI coding agent, Claude Code, Codex or another, ends up with sessions that are only waiting: for a review, for another repository, for a person. Codex has a similar codex resume picker.

This is a write-up of the skill I built for that, eln-park. It is part of ELN workflow, the in-house plugin suite we use with Claude Code. eln-park relies on Claude Code hooks (scripts Claude Code runs automatically at fixed moments), so today it runs on Claude Code only. The idea itself, a note left behind by a waiting session and a list to pick from next time, would apply to any AI agent. I added it in October 2026, after the series overview, Ship discipline as skills, not documents — introducing the 165 skills of ELN workflow, was published in September, so it is not one of those 165. Think of this as an addendum to that series.

The short version

  • The list holds only work that still has a next step. Finished conversations never show up in it. eln-park writes a small record, a resume note, for each piece of waiting work, and lists only those notes.
  • Each note says what it is waiting for. It holds the title, what the session is waiting for, the next step, a handover note and where the conversation log lives, so closing the session loses nothing.
  • If you forget, the note writes itself. Our Claude Code ends every reply with a short status summary (percent done, what is left). If the latest summary says the work is unfinished, a resume note is created the next time Claude Code starts in that repository.
  • Starting Claude Code shows the list. A new session in the same repository starts with the resume notes, newest first. Say "continue 1" and the new session claims note 1.
  • It refuses to hand you the wrong work. If another session is still working on that note, if your branch does not match the note's branch, or if this session already holds another note, the claim is refused with the reason.
  • You never handle session IDs. The mechanism picks the ID up on its own. You see a per-repository number and a title. To reopen the original conversation itself, you type cpark 1 in a terminal.

The screens below are real output, captured in an isolated test setup so none of my real notes was touched. The command lines are tidied for reading (some argument values are shortened to "…"), the long path of the test folder is replaced with /work, and the grey italic lines starting with # are scene notes I added, not tool output; everything else is printed by the tool as is. The tool's own screens say "tab" for a session, "parked" for a saved note, and "card" for the note itself; those words are quoted as printed.

What you see

When a session hands work off and starts waiting, you type /eln-park. Claude writes the resume note (a title, the kind of wait, the next step and a handover note) and ends with a line saying the note is saved and the work will be in the list next time.

Terminal (recomposed from real output in an isolated test setup, captured October 27, 2026, with the display language set to English by ELN_PARK_LANG=en): in session A, on branch feat/iam-least-privilege, typing /eln-park makes Claude run  raw `eln-park.sh park` endraw  with the title "Least-privilege IAM policy — waiting for infra-ops handoff reply", the wait kind manual, the next step and a handover note file (some argument values shortened to "…"). The tool answers with its fixed wording, "Parked: [1] …" and "You can close this tab. It shows up in the list next time you open this repo."

The title has a fixed shape: what the work is, then what it is waiting for. The skill's own instructions give a bad example, "infra fix", and a good one, "IAM policy least privilege, waiting for infra-ops to answer the handoff" (translated). The title is what lets you tell two similar continuations apart.

The next time you start Claude Code in that repository, the list is the first thing you see:

Terminal (recomposed from real output in an isolated test setup, captured October 27, 2026, with the display language set to English by ELN_PARK_LANG=en): what the SessionStart hook prints when a new Claude Code session C starts in the same repository. Under the tool's heading "🅿️ Parked work (demo-app)" are two notes: [2] Payment webhook signature check, waiting: unknown ❔, feat/billing-webhook, next: Address review comments and merge, 0m ago (auto); and [1] Least-privilege IAM policy — waiting for infra-ops handoff reply, waiting: manual asked infra-ops for the allow list ❔, feat/iam-least-privilege, next: rewrite the policy from their allow list, 0m ago. The last line says: Say "continue N" to resume in this tab. To reopen the original conversation, run  raw `cpark N` endraw  in the terminal.

What the list shows per note Example
Number [2] — counts up per repository, never reused
Title "Payment webhook signature check"
What it waits for, and its last known state "unknown ❔"
Branch feat/billing-webhook
Next step "Address review comments and merge"
Age, and how it was written "0m ago (auto)"

Nobody wrote note [2] by hand. Session B opened a pull request and was closed with a summary of "80% done, unmerged PR #12", so starting session C turned it into a note, titled with the summary's task name.

The list appears only on a fresh start or /clear, not after compaction or a resume. It goes both to the screen and to Claude's context, along with instructions for what to do when you say "continue N". It shows up to eight notes; more are summarized as "N more" and cpark shows them all. A blue marker means another session is working on that note, and notes older than 14 days are labelled. Git worktrees of the same repository share one list.

There are two ways to continue, and you pick one. To continue in the new session, you say "continue 1": Claude claims the note first and only then reads it, so that it never starts on work another session is already doing, or on the wrong branch. To reopen the original conversation instead, you skip that and type cpark 1 in a terminal. cpark also refuses when another session is still working on the note.

Continue in the new session cpark 1 in a terminal
Conversation new session, handover loaded original session reopened
Folder current session's moves to the original folder first (claude --resume only finds a conversation from the folder it was started in)
Account current the Claude Code account recorded on the note
Branch mismatch refused refused, with the git switch to run
Worktree deleted not relevant offers to recreate it
Conversation log deleted read from the backup restored from the backup first

Continuing in the new session loads the note's current wait status, branch, folder, next step, the handover note, the last 20 status summaries, and the last few messages of the original conversation (up to six, 1,500 characters each). The backup is a hard link to the conversation log, so the content survives even if Claude Code removes the original file; it is removed only when no note points to it. cpark is installed once with eln-park.sh install, and the name avoids clashing with cc, the C compiler.

Terminal (recomposed from real output in an isolated test setup, captured October 27, 2026, with the display language set to English by ELN_PARK_LANG=en): eln-park.sh brief 1 after the claim. Under the note's title come the wait, the branch and folder (/work/demo-app) and the next step; then "Handoff notes" (goal, decision, what it waits on, next step), "Progress (recap history)" with one summary at task 60%, and the last two messages of the original conversation.

Session IDs never appear in any of this. Claude Code passes the ID to hooks and to the shell, so eln-park records it itself, and cpark hands it to claude --resume without showing it.

What it refuses

A claim is refused when:

  • the branch differs. Continuing a feature branch's work on main puts the changes on the wrong branch. The refusal tells you to switch, or to use cpark 1. If the note's branch no longer exists, the claim goes through on the current branch and says so.
  • another session is working on it. Two sessions continuing the same work produce two versions of the truth.
  • this session already holds a note. One session, one note.

When refused, Claude passes on the reason and stops. The skill tells it not to work around the refusal. If you describe the work instead of giving a number, Claude finds the note by title, and asks one question if more than one matches.

Terminal (recomposed from real output in an isolated test setup, captured October 27, 2026, with the display language set to English by ELN_PARK_LANG=en): claim 1 from session C on main is refused with the tool's wording "this card is work on branch  raw `feat/iam-least-privilege` endraw , but this tab is  raw `main` endraw ". After switching the branch, the claim succeeds ("Claimed: [1] …"). The same claim from another session D is refused with the tool's wording "[1] is in use in another tab", and list now shows "🔵 in use in another tab" on note [1].

How a note gets written when you forget

Typing /eln-park every time would be ideal. In practice, I mostly just close the session. So:

  1. After every reply, a Stop hook writes a small record for that session: its ID, folder, branch, and the status summary at the end of the reply.
  2. When the session ends, the SessionEnd hook only marks it as ended. That hook gets very little time (1.5 seconds by default, per Claude Code's documented hook behavior at the time), so it does nothing else.
  3. The next time Claude Code starts in that repository (or you run cpark and similar commands), the ended sessions are processed.

The rule:

  • Unfinished: the summary says less than 100%, or the "remaining" line lists something (such as an unmerged pull request). A pull request waiting for review is unfinished even at 100%. A resume note is created, titled with the summary's task name.
  • Finished: 100% and nothing remaining. Any note that session was holding is archived.
  • No summary anywhere in the session: nothing happens. If only the last reply lacks a summary, the latest earlier summary is used.

It deliberately does not look at git status, because another session may be using the same folder. Whether a session is still alive is decided by its process, not by elapsed time, so a session that has been waiting for hours is still alive. Sessions killed along with the terminal are picked up as well.

Live status checks, and cleaning up

Only when you load a note (brief) or list notes with cpark in a terminal does eln-park check what the note is waiting for: a request in UseSources (our own task tracker), an Asana task, or a pull request. Startup never touches the network. A UseSources request that is done or changed state, an Asana task that is completed, a pull request that is merged or closed, or a new comment (or review) shows ✅; no movement shows ⏳. Checks stop after 5 seconds and show ❔ "timed out". A source that cannot be read also shows ❔, never ⏳, so "nothing happened" and "could not look" stay different; for UseSources requests the reason is shown too.

We now send work with a clear scope to our automation system instead of keeping it in a local session. The handoff procedure ends by writing a resume note, with the request as what the note waits for. Since version 0.410.0 (October 23, 2026), a request that is done is marked ✅ and labelled ready to continue (in the English display added in a later version, "✅ Done — ready to continue"). The skill says to check the actual result, the pull request or comment, before continuing.

done 1 moves a note to the archive, where restore 1 can bring it back for 90 days. prune archives notes older than a given number of days. A note that another session is working on cannot be archived with done; that works after that session is closed, or automatically when a finished summary comes in. Since version 0.413.2 (October 27, 2026), done also works from the session that claimed the note.

Why I built it

I built eln-park on October 4, 2026, because of three problems I kept running into.

  1. The resume list could not tell waiting work from finished work. This was the main one. Claude Code stores conversations locally, and claude --resume without an ID shows a picker of past sessions from that folder. Nothing in it marks which ones are still waiting, what they are waiting for, or whether the answer has arrived. With several pieces of work going in one repository, I could not tell which entry was the one waiting for me.
  2. So sessions that are waiting pile up. I run several Claude Code sessions against the same repository. When one hands work to someone else (another repository's agent, a pull request reviewer, a person) it has nothing to do until the answer comes back. But I could not close it. Start something else in a new session, hit another wait, and now there are two sessions I cannot close.
  3. Session IDs did not help. claude --resume <id> takes you straight back, but that means writing IDs down, and a growing list of IDs is its own mess. Two unfinished infrastructure fixes look the same by ID.

So the conversations were never really at risk. What was missing was a list of only the waiting work, each item saying what it waits for, so the right one can be picked without remembering anything.

Wrapping up

I kept waiting sessions open because closing them meant losing track of what came next: the resume list mixes waiting and finished conversations. eln-park writes "what came next" down as a resume note, lists only those notes the next time you start, writes one for you when you forget, and refuses when you are about to pick up the wrong work. This one is built for Claude Code, but the same idea fits Codex or any other agent. If you solve the same problem differently, I would like to hear how.


Articles on ELN workflow — our in-house plugin suite that enforces AI development quality — will continue as a series. If you are interested, please like and follow.

Our products: https://www.eln.ne.jp/products


EarthLink Network builds its own products to run the whole company on AI — each one born from a need along the way. See the full index of what we build:

→ The 18 products EarthLink Network builds in-house

For more about the company and each product, visit www.eln.ne.jp.

Top comments (0)