Skip to main content

s-continue

Cheaper and faster than /compact. Restores previous session context from Claude Code AND Codex transcripts by reading them directly — no LLM calls, no token cost. Also auto-loads a handoff written by /s-compact, if one exists. Triggers on "s-continue", "restore context", "what was I doing", "pick up where I left off", "resume work", "previous session", "codex session".

الانتقال إلى التثبيت

معلومات المصدر

المستودع
ww-w-ai/marketplace
آخر نشاط في المصدر
٢٥ أغسطس ٢٠٢٦ في ٠٦:٠٢
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٠
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
2 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
s-continue
description
Cheaper and faster than /compact. Restores previous session context from Claude Code AND Codex transcripts by reading them directly — no LLM calls, no token cost. Also auto-loads a handoff written by /s-compact, if one exists. Triggers on "s-continue", "restore context", "what was I doing", "pick up where I left off", "resume work", "previous session", "codex session".
when_to_use
Use when starting a new session and want to pick up previous work, including work left unfinished in Codex — the read-side pair of /s-compact (end a session with /s-compact → start the next with /s-continue). Triggers on "s-continue", "restore context", "what was I doing", "pick up where I left off", "resume work", "previous session", "codex session".
Restore context from previous sessions so the user can pick up where they left off — without the cost of /compact. **Two tools, one history.** Sessions come from Claude Code (`~/.claude/projects/`) and from Codex (`~/.codex/sessions/`). A Codex rollout is rewritten into the shape Claude Code writes, one output line per input line, so both are read by the same code and an `L{n}` marker still points at the Codex original's line. Work stopped in one tool is therefore resumable in the other. ## Help **ONLY show help if the user's argument literally contains the word "help" (e.g. `/s-continue help`). If no argument or any other argument is given, SKIP this section entirely and proceed to Step 1.** If the user provides "help" as argument, show usage summary and stop: ``` /s-continue — Restore context from previous sessions (zero LLM calls) Options: (nothing) Show session list (Claude Code + Codex), pick which to restore - Current session with context-loss events appears as #0 [default] - Press Enter to restore just #0, or add more numbers last Quick restore: - Current session if it had /compact or auto-compact - Otherwise, most recent other session claude|codex Restrict the list to one tool help Show this help Examples: /s-continue /s-continue last /s-continue codex /s-continue codex : rust migration ``` Do not run any analysis or restoration. Just display the help text and stop. ## Language Detect the user's language from their message accompanying the /s-continue invocation. If no message was provided (bare `/s-continue`), detect the dominant language from the session list's firstMsg/lastMsg content after Step 1 runs. All UI messages (session list header, selection prompt, progress updates, final reference note) MUST be in the detected language. The examples below are in English — translate naturally, don't transliterate. ## Quick Restore: `/s-continue last` If the user invoked `/s-continue last`, skip the session list entirely. Run list-sessions with `--limit 3` (same flags as Step 1). Then pick automatically based on the `isCurrent` and `hasContextLoss` fields: - **If the current session has context-loss** (`isCurrent: true` AND `hasContextLoss: true`) → auto-pick the CURRENT session. Its pre-context-loss content is what needs restoration. - **Otherwise** → auto-pick the most recent session where `isCurrent: false` (the previous session). - **If no valid target** (current session has no context-loss AND no previous sessions exist) → print "No previous sessions found in this project." and stop. Jump directly to Step 3 with the selected session. No user prompt needed. ## Step 1: List & Select If `/s-continue last` was used, skip this step (see above). Run the list-sessions script to get main sessions only (subtask/system-only sessions are filtered out). Requires Node.js. ```bash PROJECT_HASH=$(echo "${PWD}" | sed 's/[^a-zA-Z0-9]/-/g') TRANSCRIPTS_DIR="${HOME}/.claude/projects/${PROJECT_HASH}" PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT}}" node "${PLUGIN_ROOT}/scripts/list-sessions.js" "${TRANSCRIPTS_DIR}" \ --source all --cwd "${PWD}" --current-source claude --limit 11 --offset 0 ``` **Resolving `PLUGIN_ROOT`.** Claude Code exports `CLAUDE_PLUGIN_ROOT`; Codex does not always export `CODEX_PLUGIN_ROOT`. If both are empty, use the directory that contains THIS `SKILL.md`, two levels up — the host tells you that path when it loads the skill. Do not guess an install location. When this skill runs under Codex, pass `--current-source codex` instead of `claude` in every command below. `--current-source` names the tool this skill is running in, so `isCurrent` marks the session being written right now instead of whichever transcript happens to be newest. `--source` takes `all` (default for this skill), `claude`, or `codex`. Pass `codex` or `claude` when the user named one tool. Codex keeps every session in one global tree, so `--cwd` is what scopes them to this project; Codex subagent rollouts are excluded, the same way Claude subtask transcripts are. Each result carries `source` (`claude` | `codex`) and, for Codex, `originalPath` (the rollout the line numbers belong to) alongside `path` (the normalized copy the other scripts read). The script outputs JSON. If the script returns an empty array, display "No previous sessions found in this project." and stop. **Current session identification**: The script sets `isCurrent: true` on the session whose JSONL is most recently modified (the one being actively written). This is reliable even after auto-compact (unlike firstMsg comparison, which fails because the LLM's first visible message becomes the summary). **Case A/B/C/D list display**: - Look at the session with `isCurrent: true`: - If `hasContextLoss: true` → **display it as #0 [default]** (with `📍` marker plus any `@@`/`+`/`++` event badges). #1..N are other sessions. - If `hasContextLoss: false` → **exclude it entirely from the list** (its full content is in live memory, nothing to restore). #1..N are other sessions. - If no other sessions exist and current has context-loss → **auto-restore current session, skip list display** (Case C). - If no other sessions exist and current has no context-loss → print "No previous sessions found in this project." and stop (Case D). Format each session for display (preserve existing Case A/B/C/D logic — current session #0 with context-loss marker, etc.): ``` 📂 Found {N} previous sessions in this project (Claude Code + Codex). Pick the ones you want to restore — Claude will read them and bring the context into this session so you can continue where you left off. 💡 Tip: Selecting 1-2 sessions is fast (almost always faster than /compact). Selecting many sessions takes longer, but still no LLM summarization needed. | # | Tool | Started | Last active | First message | Last message | Size | |---|------|---------|-------------|---------------|--------------|------| | 1 | CC | Mar 31 09:00 | today 14:05 | "improve the skill..." | "ok go ahead..." | 122KB · 3 msgs | | 2 | Codex | Mar 31 08:30 | today 13:59 | "local agent actually..." | "let me test the skill..." | 2.1MB · 82 msgs | | ... | | | | | | | Enter: - numbers only (e.g., "1,3" or "1-4") — fast restore - numbers + ":" + topic (e.g., "1,3 : PDCA implementation") — topic-based restore (slower, more accurate) - "more" for pagination - (empty) for default 💡 Topic search adds an LLM step so it takes longer, but restores specific memories more accurately. ``` Use `--limit N` and `--offset N` for pagination. When the user types "more", re-run list-sessions with `--offset` increased by 10 (the limit). Numbers continue sequentially across pages. Wait for user selection before proceeding. This avoids preprocessing sessions the user doesn't need. ## Step 2: Parse Input First, if the ARGUMENT to `/s-continue` is `claude` or `codex` (alone or before a `:` topic), that is a source filter, not a selection — re-run Step 1 with `--source claude` or `--source codex` and show the narrowed list. Then split user input on the first `:`: - Left side → numbers part. Parse using existing Case A/B/C/D logic (additive with #0, ranges, comma lists). - Right side (optional) → topic string (trim whitespace). May be absent. Examples: - `1,3` → sessions [1, 3], no topic - `1-4 : PDCA implementation` → sessions [1, 2, 3, 4], topic = "PDCA implementation" - `: error handling` → only #0 (default), topic = "error handling" - `` (empty) → default selection, no topic ## Step 3: Ensure Cache & Preprocess preprocess.js is self-managing: it derives the cache path from the JSONL path, checks format version + mtime, and skips if fresh. Just call it for each selected session. ```bash # For each selected session: ensure compact.txt cache is fresh. # TRANSCRIPT_PATH is the `path` field from list-sessions. node "${PLUGIN_ROOT}/scripts/preprocess.js" "${TRANSCRIPT_PATH}" # Codex sessions only — name the rollout the L{n} markers belong to, so the # footer points a reader at the real file instead of the normalized copy: node "${PLUGIN_ROOT}/scripts/preprocess.js" "${TRANSCRIPT_PATH}" --original "${ORIGINAL_PATH}" ``` The cache file is at: ```bash PROJECT_HASH=$(echo "${PWD}" | sed 's/[^a-zA-Z0-9]/-/g') CACHE_FILE="${HOME}/.claude/super-token-saver-data/${PROJECT_HASH}/${SESSION_ID}/compact.txt" ``` **Current session with context-loss**: The compact.txt contains the FULL session. When reading it, use `lastContextLossLine` from list-sessions.js to filter: only read entries where `L{n} < lastContextLossLine`. Content after the last context-loss event is already in live LLM memory. To extract just the pre-boundary portion without LLM parsing: ```bash awk "/\[Session:.*L${LAST_LOSS_LINE}\]/{exit} 1" "${CACHE_FILE}" ``` **Current session WITHOUT context-loss**: Skip — entire session is in live memory. **Past sessions**: Read the full compact.txt (none of their content is in live memory). The preprocessor (v6) outputs a compact text transcript with `[Session:{sid} {ISO} L{n}]` headers. The `L{n}` is the JSONL line number of the user message — this enables direct seek into the original transcript for topic-based restoration. Preprocessing is instant (< 1 second even for 60MB+ transcripts). ## Step 4: Load Compact No size threshold. Always load all selected compact.txt files. - **No topic** → Read all compact.txt files directly using the Read tool. Content is loaded into conversation context as-is. For files exceeding ~10K tokens, read in chunks using offset/limit parameters. Always read the ENTIRE file — never skip sections. Proceed to Step 6. - **Topic provided** → Do NOT Read compact.txt yet. Proceed to Step 5 (topic-based restoration). ## Step 5: Topic-Based Original Restoration **Goal**: Load compact.txt with the top 20 most topic-relevant truncated turns replaced by their full JSONL originals. The original compact.txt files are never modified — the assembled result is written to a temp file. ### Step 5a: Extract user turn list Extract all user message headers from compact.txt files programmatically (no LLM Read needed): ```bash python3 << 'PYEOF' import json, os, re sessions = [ # (session_id, compact_path) — dynamically populated ] results = [] for sid, path in sessions: with open(os.path.expanduser(path)) as f: content = f.read() for m in re.finditer( r'\[Session:([a-f0-9]+) (\S+) L(\d+)\].*?User: "(.*?)"', content ): results.append({ "sid": m.group(1), "ts": m.group(2), "line": int(m.group(3)), "msg": m.group(4)[:300] }) print(json.dumps(results, ensure_ascii=False)) PYEOF ``` ### Step 5b: LLM selects top 20 Read the JSON output from Step 5a. For each user turn, judge topic relevance. Select the **top 20 most relevant** turns (by topic match strength). Output a list of `(sid, line)` pairs. If fewer than 20 turns match, include only those that match. If zero match, skip to Step 4 no-topic path (load compact as-is). ### Step 5c: Batch extract originals Extract all 20 matched turns' originals from JSONL files in **a single python script** (one pass per JSONL file): **`jsonl_path` is the `path` field from list-sessions, never `originalPath`.** For a Codex session those differ: the extractor below parses the shape Claude Code writes, so handing it the raw Codex rollout produces empty user text instead of an error — a silent, plausible-looking failure. The normalized copy carries the same line numbers, so `L{n}` still lands on the right turn. ```bash python3 << 'PYEOF' import json, sys # Dynamically populated: { "sid": { "jsonl_path": "...", "lines": [40, 83, ...] } } # jsonl_path = list-sessions `path` (the normalized copy for Codex), NOT `originalPath`. extractions = {} results = {} for sid, info in extractions.items(): target_lines = set(info["lines"]) all_lines = {} with open(info["jsonl_path"]) as f: for i, raw in enumerate(f, 1): if i in target_lines or any(i > t for t in target_lines): all_lines[i] = raw for target_line in info["lines"]: d = json.loads(all_lines.get(target_line, '{}')) # Extract user content content = d.get("message", {}).get("content", "") if isinstance(content, list): user_text = " ".join( b["text"] for b in content if isinstance(b, dict) and b.get("type") == "text" )[:3000] else: user_text = str(content)[:3000] # Find assistant responses until next user turn assistants = [] for j in range(target_line + 1, target_line + 100): if j not in all_lines: continue row = json.loads(all_lines[j]) if row.get("type") == "user": break msg = row.get("message", {}) if msg.get("role") == "assistant": texts = [] for b in (msg.get("content", []) if isinstance(msg.get("content"), list) else []): if isinstance(b, dict) and b.get("type") == "text" and b.get("text", "").strip(): texts.append(b["text"][:3000]) if texts: assistants.append("\n".join(texts)) key = f"{sid}_L{target_line}" results[key] = {"user": user_text, "assistants": assistants} # Write to temp file output_path = "/tmp/continue-originals.json" with open(output_path, "w") as f: json.dump(results, f, ensure_ascii=False) print(f"Extracted {len(results)} turns to {output_path}") PYEOF ``` ### Step 5d: Assemble temp file Build the restored document by iterating compact.txt in order, replacing matched turns inline: ```bash python3 << 'PYEOF' import json, re, os # Inputs (dynamically populated) compact_paths = [] # ordered list of compact.txt paths originals_path = "/tmp/continue-originals.json" output_path = "/tmp/continue-restored.txt" with open(originals_path) as f: originals = json.load(f) matched_keys = set(originals.keys())
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub