$npx -y skills add entireio/skills --skill session-crosslinkUse when an agent session ran outside the repo whose commits should record it — e.g. launched from a higher-level folder, a non-Entire repo, or one repo but editing another — to attach the session to each affected Entire-enabled repo's HEAD commit.
| 1 | # Session Crosslink |
| 2 | |
| 3 | ## Response Format |
| 4 | |
| 5 | Begin the first response to this skill invocation with the line: |
| 6 | |
| 7 | `Entire Session Crosslink:` |
| 8 | |
| 9 | followed by a blank line, then the content. Apply the header to the **first response of the invocation only** — not on follow-up turns and not on error / early-exit responses (no session resolved, no affected repos found). |
| 10 | |
| 11 | ## STOP — Read these rules before doing ANYTHING |
| 12 | |
| 13 | 1. **Do NOT ask clarifying questions until the resolver/discovery steps have run.** The session id and candidate repo list usually resolve from `entire session current --json` plus what the user said. Only ask if both come back empty. |
| 14 | 2. **Do NOT run `entire session attach` without showing the preview table first.** The whole point of this skill is preview-then-confirm. `attach` amends the target repo's HEAD; previewing wrong means amending the wrong commit. |
| 15 | 3. **Always `cd` into the target repo before running `entire session attach`.** The CLI resolves the repo from cwd. Use one `cd … && entire session attach …` per call so each invocation hits the right repo. |
| 16 | |
| 17 | Required CLI: `entire` 0.6.2+. No special flags needed — this skill works against the shipped CLI via cwd-scoped `entire session attach`. |
| 18 | |
| 19 | ## Flow |
| 20 | |
| 21 | ### Step 1: Resolve the session id |
| 22 | |
| 23 | Try each strategy in order until one returns a session id. |
| 24 | |
| 25 | **Strategy A: Entire-enabled cwd.** |
| 26 | |
| 27 | ```bash |
| 28 | entire session current --json |
| 29 | ``` |
| 30 | |
| 31 | If the output is valid JSON **and** has a non-empty `session_id`, read `session_id` and `agent` and continue with those values. If the JSON parses but `session_id` is missing or empty, treat Strategy A as failed and fall through to B — don't proceed to attach with no session id. |
| 32 | |
| 33 | **Strategy B: Entire-enabled sibling repo.** If the user named a repo that has Entire enabled (e.g. `the foo repo`), `cd` there and re-try `entire session current --json`. The session state lives wherever the session was tracked. |
| 34 | |
| 35 | **Strategy C: Runtime-specific transcript directory.** If neither A nor B works, the session was never recorded by Entire and you must read it from the agent runtime: |
| 36 | |
| 37 | - **Claude Code:** transcripts live at `~/.claude/projects/<encoded-cwd>/<session-id>.jsonl`. Encoded cwd is the launch directory with `/` → `-`. The most recent `.jsonl` file under the project directory matching the agent's launch cwd is this session. Read the basename minus `.jsonl` as `session_id`. Set `agent` to `claude-code`. |
| 38 | - **Codex:** check `$CODEX_HOME/sessions/` or `~/.codex/sessions/`. Set `agent` to `codex`. |
| 39 | - **Other runtimes:** ask the user for the session id. |
| 40 | |
| 41 | Record `agent` so Step 4 can pass `--agent <name>` to attach. |
| 42 | |
| 43 | **If all strategies fail:** print "Could not resolve a session id — pass one explicitly or run from an Entire-enabled directory" and stop. |
| 44 | |
| 45 | ### Step 2: Discover affected repos |
| 46 | |
| 47 | Build a candidate set, union from these sources, then de-duplicate by path: |
| 48 | |
| 49 | 1. **From the user's message**: any repo paths or aliases the user named explicitly (e.g. "the foo repo and the bar api"). Resolve aliases via the user's `CLAUDE.md` or treat as filesystem paths. |
| 50 | |
| 51 | 2. **From sibling repos under the launch directory** (only if launch dir is NOT Entire-enabled): list immediate subdirectories that have their own `.git` and a `.entire/settings.json`. |
| 52 | |
| 53 | 3. **From the agent's edit history in this session**: any repo whose files were edited during the session — derive from the agent's own context. If unsure, ask the user. |
| 54 | |
| 55 | For each candidate, run `entire status --json` (with cwd inside that repo) and decide: |
| 56 | |
| 57 | - `"enabled": true` → keep. |
| 58 | - `"enabled": false` with a settings-parse error (`unknown field "..."`) → keep. Status fails noisily on misconfigured local settings even when attach would succeed. |
| 59 | - `"enabled": false` with no error → drop. Repo opted out of Entire. |
| 60 | |
| 61 | If the candidate set is empty, ask the user which repos to crosslink. |
| 62 | |
| 63 | ### Step 3: Compute the preview locally |
| 64 | |
| 65 | For each candidate, inspect git and the session store to compute the action — same logic `entire session attach` uses internally, but without amending anything: |
| 66 | |
| 67 | ```bash |
| 68 | # Get HEAD hash and message |
| 69 | HEAD_HASH=$(git -C <repo> rev-parse HEAD) |
| 70 | HEAD_MSG=$(git -C <repo> log -1 --format=%B HEAD) |
| 71 | |
| 72 | # Existing Entire-Checkpoint trailer on HEAD, if any |
| 73 | EXISTING_TRAILER=$(printf '%s\n' "$HEAD_MSG" | grep -E '^Entire-Checkpoint:' | tail -1 | awk '{print $2}') |
| 74 | |
| 75 | # Is the session already tracked in this repo's store? |
| 76 | STATE_FILE=<repo>/.git/entire-sessions/<session-id>.json |
| 77 | ``` |
| 78 | |
| 79 | Decide the action per repo: |
| 80 | |
| 81 | - Both `STATE_FILE` exists AND its `last_checkpoint_id` field is non-empty → `would_skip_existing_in_state`. Attach is a no-op; report that. |
| 82 | - HEAD has an `EXISTING_TRAILER` → `would_link_existing_in_head`. |