Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions skills/agent-session-resume/references/antigravity.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,30 @@ Prefer the strongest source for the question being resumed:

If artifacts disagree, prefer the latest artifact that includes concrete verification evidence, then validate against current repository files and git state.

## Safe Reading

Check size before opening any candidate artifact body:

```bash
wc -lc "$HOME/.gemini/antigravity/brain/<conversation-id>/task.md"
```

Read `*.metadata.json` peeks before bodies, and rank candidates by strongest signal before reading: explicit user-supplied path first, then exact repo/workspace match from metadata or workspace storage, then summary/title match, with recency only as a tie-breaker.

For markdown artifacts (`task.md`, `implementation_plan.md`, walkthroughs), map structure first and read only evidence-bearing slices:

```bash
rg -n "^#|^-|TODO|\[x\]|\[ \]|error|failed|verified" path/to/task.md
sed -n '20,80p' path/to/implementation_plan.md
```

If a JSONL transcript or handoff from another agent surfaces in the workspace, project it with the packaged scripts from the skill's `scripts/` directory (next to `SKILL.md`) instead of reading raw lines:

```bash
python3 "$skill_dir/scripts/session-events.py" path/to/transcript.jsonl --limit 200
python3 "$skill_dir/scripts/session-digest.py" path/to/transcript.jsonl
```

## Reading

Read artifacts in chronological order when possible. For local Antigravity data, inspect metadata first, then the smallest task/plan artifacts that explain:
Expand Down
74 changes: 28 additions & 46 deletions skills/agent-session-resume/references/claude-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Use this adapter when the prior session came from Claude Code or when the user points to a `.claude/` directory.

Packaged helper scripts live in the skill's `scripts/` directory, next to `SKILL.md`. Resolve them relative to the skill base directory and set `skill_dir` accordingly before using the commands below.

## Discovery

Start in the current workspace:
Expand All @@ -27,9 +29,11 @@ find "$HOME/.claude/projects" -maxdepth 2 -type f -name '*.jsonl' 2>/dev/null
find "$HOME/.claude" -maxdepth 1 -type f -name 'history.jsonl' 2>/dev/null
```

Claude Code stores full transcripts and prompt history in different places:
Claude Code stores full transcripts, per-session sidecars, and prompt history in different places:

- `~/.claude/projects/<project>/<session>.jsonl`: full conversation transcript with messages, tool calls, and tool results.
- `~/.claude/projects/<project>/<sessionId>/subagents/agent-*.jsonl`: subagent transcripts. When the main transcript delegates work to agents, include these in the evidence set; the main transcript may show only the dispatch and a summary.
- `~/.claude/projects/<project>/<sessionId>/tool-results/*.txt`: large tool outputs spilled to disk. Read these targeted files instead of giant inline transcript lines.
- `~/.claude/history.jsonl`: prompt history used for up-arrow recall, containing prompts with timestamps and project paths.

Use `history.jsonl` as a locator and context supplement, not as a transcript replacement. It can reveal the project path, the user's exact prompts, and nearby session intent even when the matching transcript is hard to identify. When a relevant history entry is used, include the project path or prompt-history clue in the context summary.
Expand All @@ -38,10 +42,19 @@ Treat Claude Code project transcripts as append logs that may still be active. A

Do not treat a `history.jsonl` miss as evidence that no transcript exists. If prompt history does not contain the current cwd or session topic, inspect the cwd-derived `~/.claude/projects/<project>` directory before broadening discovery.

Common useful formats include JSONL transcripts, Markdown exports, text exports, and metadata files. If a session name is provided, search contents and metadata before sorting by time:
Common useful formats include JSONL transcripts, Markdown exports, text exports, and metadata files.

Raw-grep trap: do not grep `~/.claude/projects/` transcript bodies for a topic, skill name, or tool name as a discovery step. Every transcript embeds the available-skills list, plugin descriptions, and other boilerplate inside `system-reminder` blocks, so a topic-shaped `rg` produces mass false positives. Concrete failure shape: `rg -l "agent-session-resume" ~/.claude/projects/` matches roughly 20 unrelated sessions whose only "mention" of the skill is the skills list injected into every conversation. Project user messages first, then search the projected view:

```bash
python3 "$skill_dir/scripts/session-events.py" "$candidate" | rg "text/user" | rg -i "<session name or topic>"
```

For shortlisting candidates by cwd, topic, or time window without opening bodies, use the packaged lister. Time-bounded asks map to `--since` / `--until`, which accept relative windows (`7d`, `12h`) or ISO dates:

```bash
rg -i "<session name>" .claude ~/.claude ~/.claude/history.jsonl 2>/dev/null
python3 "$skill_dir/scripts/session-candidates.py" --platform claude-code --cwd "$(pwd)" --topic "<session name>"
python3 "$skill_dir/scripts/session-candidates.py" --platform claude-code --cwd "$(pwd)" --since 7d --until 1d
```

To filter prompt history by the current workspace path:
Expand Down Expand Up @@ -73,10 +86,9 @@ Do not let prefix siblings outrank an exact cwd match. For example, `~/.claude/p

If no title is provided, sort candidate files by modified time only after applying the stronger path and metadata signals.

When comparing candidate times, normalize to UTC or epoch seconds before deciding which record is newer:
When comparing candidate times, normalize to UTC or epoch seconds before deciding which record is newer. `session-candidates.py` prints every row's `updated_at` normalized to ISO-8601 UTC with seconds precision (e.g. `2026-06-10T00:15:30Z`) on both platforms, so its rows sort chronologically as plain strings, and `session-events.py` prints normalized event timestamps; cross-check against file and repo time:

```bash
jq -r '.timestamp // empty' "$session" | head
stat -f '%m %N' "$session" 2>/dev/null
git log -1 --format='%ct %h %s'
```
Expand Down Expand Up @@ -105,30 +117,19 @@ Use event types to skim before deep reading:

Repeated `ai-title` events should be treated as one title signal per `(sessionId, aiTitle)` pair. Do not count duplicate title rows as progress, task evidence, or user/assistant turns.

For a message-only skim, extract visible user and assistant text plus bounded tool summaries:
For a message-only skim, extract visible user and assistant text plus bounded tool summaries with the packaged projector. It emits one previewed event per line with transcript line references and skips opaque thinking/signature payloads, which add noise and do not normally change task status:

```bash
jq -r '
def text:
if (.message.content | type) == "string" then .message.content
elif (.message.content | type) == "array" then
[.message.content[]
| if .type == "text" then .text
elif .type == "tool_use" then "[tool_use " + .name + "] " + (.input | tostring)
elif .type == "tool_result" then "[tool_result] " + ((.content // "") | tostring | .[0:500])
else empty
end
] | join("\n")
else ""
end;
select(.type == "user" or .type == "assistant" or .type == "system")
| "\n=== \(.timestamp // "") [\(.type)] ===\n\(text)"
' "$session"
python3 "$skill_dir/scripts/session-events.py" "$session" --limit 200
```

Default skims should include assistant `text` blocks and tool-use summaries. Skip opaque thinking/signature payloads unless debugging transcript format behavior; they add noise and do not normally change task status.
For a compact reusable summary with evidence cues, build a digest. It writes a persistent `<transcript>.digest.json` sidecar cache and processes only the appended tail on later runs:

Claude Code may persist oversized tool results outside the JSONL transcript. If a tool result contains a placeholder such as `<persisted-output>` or says the full output was saved to `tool-results/<id>.txt`, treat that sidecar as part of the session record.
```bash
python3 "$skill_dir/scripts/session-digest.py" "$session"
```

Claude Code persists oversized tool results outside the JSONL transcript, under the per-session sidecar directory `~/.claude/projects/<project>/<sessionId>/tool-results/*.txt`. If a tool result contains a placeholder such as `<persisted-output>` or says the full output was saved to `tool-results/<id>.txt`, treat that sidecar as part of the session record. Likewise check `~/.claude/projects/<project>/<sessionId>/subagents/agent-*.jsonl` whenever the main transcript dispatches subagents; project them with `session-events.py` like any other transcript.

Inspect sidecars safely:

Expand All @@ -151,30 +152,11 @@ For large transcript or tool-output files, use an evidence inventory before deep
If the transcript may still be active or was modified during resume, recheck the tail before reporting. Use a bounded projected tail instead of dumping raw JSONL, so the final scan keeps visible messages, tool-use summaries, and tool-result previews while skipping opaque `thinking` or `signature` payloads:

```bash
tail -n 80 "$session" | jq -r '
def projected_content:
if (.message.content | type) == "string" then
{kind: "text", body: .message.content}
elif (.message.content | type) == "array" then
.message.content[]
| if .type == "text" then
{kind: "text", body: .text}
elif .type == "tool_use" then
{kind: "tool_use", body: ((.name // "tool") + " " + ((.input // {}) | tostring))}
elif .type == "tool_result" then
{kind: "tool_result", body: ((.content // "") | tostring | .[0:500])}
else empty
end
else empty
end;

select(.type == "user" or .type == "assistant" or .type == "system")
| . as $event
| projected_content
| "\($event.timestamp // "")\t\($event.type)\t\(.kind)\t\(.body)"
'
python3 "$skill_dir/scripts/session-events.py" "$session" | tail -n 40
```

Re-running `session-digest.py` is also cheap here: its `<transcript>.digest.json` sidecar cache means only the appended tail is processed.

The exact stopping point should come from the final meaningful events, not from the first TODO list. Capture:

- the last user prompt or instruction
Expand Down
56 changes: 24 additions & 32 deletions skills/agent-session-resume/references/codex.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Use this adapter when resuming a Codex session, continuing from a Codex desktop or CLI handoff, or when a Codex conversation summary is present.

Packaged helper scripts live in the skill's `scripts/` directory, next to `SKILL.md`. Resolve them relative to the skill base directory and set `skill_dir` accordingly before using the commands below.

## Discovery

Codex may provide prior context directly in the active conversation, through a compaction summary, or through files in the workspace. Treat injected conversation context as a session record, then validate it against the repository before editing.
Expand All @@ -19,10 +21,16 @@ Codex normally stores conversation transcripts in the user-level Codex home, not
tail -n 40 "${CODEX_HOME:-$HOME/.codex}/session_index.jsonl" 2>/dev/null
```

Use `session_index.jsonl` to shortlist candidate session IDs by thread name, session name, and update time. If a title or topic is known, filter the index before opening transcripts:
Use `session_index.jsonl` to shortlist candidate session IDs by thread name, session name, and update time. Use the packaged candidate lister, which ranks candidates without dumping transcript bodies and accepts `--cwd`, `--topic`, `--since`, and `--until` filters:

```bash
python3 "$skill_dir/scripts/session-candidates.py" --platform codex --cwd "$(pwd)" --topic "<session name or topic>"
```

Warning: `session_index.jsonl` does not cover every transcript. Codex Desktop sub-threads (transcripts with a `parent_thread_id`) never get index entries, so any index-only listing silently omits them. The packaged lister compensates with an mtime fallback sweep over `sessions/YYYY/MM/DD` that surfaces unindexed in-window transcripts as `source=mtime` rows (untitled, so `--topic` cannot match them). On windowed asks where completeness matters, also broaden directly on disk:

```bash
jq -r 'select((.thread_name // "") | test("<session name or topic>"; "i")) | [.updated_at, .id, .thread_name] | @tsv' "${CODEX_HOME:-$HOME/.codex}/session_index.jsonl"
find "${CODEX_HOME:-$HOME/.codex}/sessions" -name '*.jsonl' -newermt '<date, e.g. 2026-06-03>' 2>/dev/null
```

After choosing a candidate ID, resolve it to the transcript file:
Expand Down Expand Up @@ -53,13 +61,7 @@ session="<candidate transcript>"
jq -r 'select(.type == "session_meta") | .payload.cwd // empty' "$session" | head -n 1
```

When checking several candidate transcripts, print a compact `cwd<TAB>file` inventory before ranking:

```bash
for session in path/to/candidates/*.jsonl; do
jq -r --arg file "$session" 'select(.type == "session_meta") | [(.payload.cwd // ""), $file] | @tsv' "$session" | head -n 1
done
```
When checking several candidate transcripts, use `session-candidates.py` (above) to print a compact ranked inventory instead of looping `jq` over every file.

## Candidate Ranking

Expand All @@ -84,10 +86,9 @@ Example:

Use `git status --short --branch` early to understand what already changed. If the active folder is not a git repository, locate the relevant repo from the transcript or user-provided path.

When comparing candidate times, normalize to UTC or epoch seconds before deciding which record is newer:
When comparing candidate times, normalize to UTC or epoch seconds before deciding which record is newer. `session-candidates.py` prints every row's `updated_at` normalized to ISO-8601 UTC with seconds precision (e.g. `2026-06-10T00:15:30Z`) on both platforms; cross-check against file and repo time:

```bash
jq -r '.updated_at // .timestamp // empty' "${CODEX_HOME:-$HOME/.codex}/session_index.jsonl" | head
stat -f '%m %N' "$session_file" 2>/dev/null
git log -1 --format='%ct %h %s'
```
Expand All @@ -104,10 +105,10 @@ Before reading a candidate transcript, check its size and line count:
wc -lc "$session_file"
```

Project metadata with `jq` instead of dumping raw JSONL:
Project metadata and the bounded event stream with the packaged projector instead of dumping raw JSONL. Its first projected event is the `session_meta` routing record (id, cwd, originator, CLI version), followed by previewed user/agent messages, tool calls, and truncated tool output:

```bash
jq -c 'select(.type == "session_meta") | {id: .payload.id, timestamp: .payload.timestamp, cwd: .payload.cwd, originator: .payload.originator, cli_version: .payload.cli_version}' "$session_file" | head -n 1
python3 "$skill_dir/scripts/session-events.py" "$session_file" --limit 200
```

Use event types to decide what to inspect next:
Expand All @@ -131,18 +132,13 @@ sed -n '120,220p' "$session_file"
Do not use broad raw JSONL regex scans as the first evidence pass for Codex transcripts. Matches inside `session_meta`, embedded developer/system instructions, tool schemas, or serialized prompts can look like user-visible TODOs or errors even when they are only context. Project the event stream first, then apply targeted `rg` to that projected view or to a narrowed line range:

```bash
jq -r '
select(.type == "event_msg" or .type == "response_item")
| if .type == "event_msg" and (.payload.type == "user_message" or .payload.type == "agent_message") then
[.timestamp, .payload.type, (.payload.message // .payload.text // "")]
elif .type == "response_item" and .payload.type == "function_call" then
[.timestamp, "tool_call", ((.payload.name // "tool") + " " + ((.payload.arguments // "") | tostring))]
elif .type == "response_item" and .payload.type == "function_call_output" then
[.timestamp, "tool_output", ((.payload.output // .payload.content // "") | tostring | .[0:1000])]
else empty
end
| @tsv
' "$session_file" | rg -n "error|failed|TODO|<file-or-symbol-pattern>"
python3 "$skill_dir/scripts/session-events.py" "$session_file" | rg -n "error|failed|TODO|<file-or-symbol-pattern>"
```

For a compact reusable summary with evidence cues, build a digest. It writes a persistent `<transcript>.digest.json` sidecar cache and processes only the appended tail on later runs, so rechecks of an active transcript stay cheap:

```bash
python3 "$skill_dir/scripts/session-digest.py" "$session_file"
```

Use raw `rg` only after the projection reveals a specific event, file path, command, or line range worth inspecting.
Expand All @@ -155,17 +151,13 @@ Read the current conversation summary, local handoff files, and changed files re
- facts verified from files
- inferences from current repository state

For large Codex JSONL transcripts, start with a message-only skim to orient yourself before deeper review:
For large Codex JSONL transcripts, start with a bounded skim to orient yourself before deeper review:

```bash
jq -r '
select(.type == "event_msg" or .type == "response_item")
| select(.payload.type == "user_message" or .payload.type == "agent_message")
| "\n=== \(.timestamp) [\(.payload.type)] ===\n\(.payload.message // .payload.text // "")"
' "$session_file"
python3 "$skill_dir/scripts/session-events.py" "$session_file" | rg "user_message|agent_message"
```

This intentionally keeps only user and agent messages with timestamps, skipping session metadata, tool calls, tool output, and other large event payloads. Use it as an orientation step, not as a replacement for evidence review: still inspect relevant tool outputs, changed files, git state, tests, and artifacts before continuing work.
This keeps only previewed user and agent messages with timestamps and transcript line references, skipping session metadata and large event payloads. Use it as an orientation step, not as a replacement for evidence review: still inspect relevant tool outputs, changed files, git state, tests, and artifacts before continuing work.

## Resume Notes

Expand Down
26 changes: 26 additions & 0 deletions skills/agent-session-resume/references/cursor.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,32 @@ Read the export in order. Capture:

Cursor export docs say exports include messages/responses, code blocks, file references/context, and chronological conversation flow. Still verify claims against current files and `git status` before editing.

## Safe Reading

Cursor exports and project-scoped artifacts can be large. Check size before reading any candidate body:

```bash
wc -lc path/to/export.md
```

Peek structure and evidence cues before reading bodies, then read only the slices that carry evidence:

```bash
rg -n "^#|^##|TODO|error|failed|stop here" path/to/export.md
sed -n '40,120p' path/to/export.md
```

Rank candidates by strongest signal before opening anything: explicit user-supplied path first, then exact cwd/workspace match, then title match, with recency only as a tie-breaker (see Candidate Ranking below). Do not read whole files to decide between candidates.

If a JSONL transcript surfaces (for example under `~/.cursor/projects/<project>/agent-transcripts/`, or a handoff produced by another agent), project it with the packaged scripts from the skill's `scripts/` directory (next to `SKILL.md`) instead of dumping raw lines:

```bash
python3 "$skill_dir/scripts/session-events.py" path/to/transcript.jsonl --limit 200
python3 "$skill_dir/scripts/session-digest.py" path/to/transcript.jsonl
```

For `terminals/` and other artifact folders, slice bounded ranges with `rg -n` plus `sed -n` rather than reading entire outputs.

## Local Storage Safety

Cursor chat history may be stored locally in SQLite, while Background Agent chats are not part of normal history and may be remote. Local storage formats can be large and unstable.
Expand Down
Loading
Loading