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
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,16 @@ This skill analyzes the current conversation to extract guidelines that **correc

### Step 0: Load the Conversation

This skill runs in a forked context with no access to the parent conversation. The stop hook message (produced by `on_stop.py`) contains two literal markers:
This skill runs in a forked context with no access to the parent conversation. The stop-hook message (produced by `on_stop.py`) contains one literal marker:

- `The session transcript is at: <path>` — the live session transcript. Take everything between that marker and the next marker (or end of message), strip whitespace and quotes, and use the result as `transcript_path`.
- `The saved trajectory path is: <path>` — the relative path of the saved trajectory copy under `.evolve/trajectories/`. Extract this the same way and remember it as `saved_trajectory_path` — you will attach it to each entity in Step 3.
- `The saved trajectory path is: <path>` — a copy of the session transcript saved inside the project tree at `.evolve/trajectories/claude-transcript_<session-id>.jsonl`. Take everything after the colon, strip surrounding whitespace and quotes, and use the result as `saved_trajectory_path`. You will also attach this exact path to each entity's `trajectory` field in Step 4.

Then read the session transcript:
**Read this file with the `Read` tool — do NOT shell out.** `Read` pages large files natively (use its `offset` / `limit` parameters if needed). Do not use `cat`, `head`, `wc`, `find`, or `python3 -c` loops on the transcript — those trigger a permission prompt for every invocation and are unnecessary.

```bash
cat <transcript_path>
```

**You must read this file to analyze the conversation** — the forked context has no other access to it.
If the saved trajectory file does not exist (e.g., the save-trajectory hook did not run, or no marker was provided), output zero entities and exit. Do NOT fall back to reading the live session transcript under `~/.claude/projects/` — that path is outside the project tree, triggers permission prompts, and may be larger than the fork can consume.

The transcript is JSONL: each line is a separate JSON object. Focus on lines where `"type": "assistant"` or `"type": "human"` to reconstruct the conversation flow. Look for tool calls, errors in tool results, and user corrections.

If no transcript path was provided, fall back to `.evolve/trajectories/`, which may contain either format:

- **`trajectory_*.json`** — a single JSON object with `messages: [{role, content}, …]`. Prefer the most recent one; parse with `json.load`.
- **`claude-transcript_*.jsonl`** — raw Claude JSONL (same format as the primary `transcript_path`). Parse line-by-line.

If no transcript is available at all, output zero entities.

### Step 1: Analyze the Conversation

Review the conversation (loaded from the transcript) and identify:
Expand All @@ -59,7 +47,19 @@ Review the conversation (loaded from the transcript) and identify:

If none of these occurred, **output zero entities**. Not every conversation produces guidelines.

### Step 2: Extract Entities
### Step 2: Review Existing Guidelines

Before extracting, look at what has already been saved for this project. Earlier Stop hooks in the same session (or prior sessions) may have recorded guidelines that cover the same ground — re-extracting them is wasteful and pollutes the library.

Use the **Glob tool** to enumerate existing guideline files: `.evolve/entities/**/*.md`. Then use the **Read tool** to open each match and skim the content + trigger.

**Do NOT use `cat`, `head`, `find`, a `for` loop, or an inline `python3 -c` script for this.** Each shell invocation triggers a permission prompt, and Glob + Read cover the same need without any prompting.

If there are no existing guidelines, skip this step.

With the existing-guideline set in mind, when you proceed to Step 3 you should pick only *complementary* findings — new angles, new failure modes, or finer-grained detail — and drop candidates that restate or near-duplicate anything already saved. (`save_entities.py` will also drop exact-match duplicates at write time, but it cannot catch re-wordings.)

### Step 3: Extract Entities

For each identified shortcut, error, or user correction, create one entity — up to 5 entities; output 0 when none qualify. If more candidates exist, keep only the highest-impact ones.

Expand All @@ -77,7 +77,7 @@ Principles:

4. **For user corrections, use the user's own words** — preserve the specific preference rather than generalizing it

### Step 3: Save Entities
### Step 4: Save Entities

Output entities as JSON and pipe to the save script. The `type` field must always be `"guideline"` — no other types are accepted. Include a `trajectory` field on every entity, set to the `saved_trajectory_path` extracted in Step 0 — this records which session produced the guideline.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ def main():
transcript_path = input_data.get("transcript_path", "")
reason = "Run the /evolve-lite:learn skill."
if transcript_path:
reason += f" The session transcript is at: {transcript_path}"
session_id = Path(transcript_path).stem.removeprefix("claude-transcript_")
if session_id:
saved_trajectory = f".evolve/trajectories/claude-transcript_{session_id}.jsonl"
Expand Down
Loading