Skip to content
Open
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ A skill is a folder with a `SKILL.md` describing a task in enough detail that an
| [`fix-pr-comments`](skills/fix-pr-comments) | Fetches review comments from a GitHub PR, triages them, and fixes each one test-first — write a failing test capturing the reviewer's concern, make it pass, then resolve the thread. Handles skip-reason replies for feedback you're not taking. |
| [`write-a-pitch`](skills/write-a-pitch) | Collaborates with you on a [Shape Up](https://basecamp.com/shapeup) pitch — problem, appetite, solution, rabbit holes, no-gos. Explores your codebase so the pitch is grounded in real code, and aims for a pitch complete enough that an agent could generate a spec from it. |
| [`chip-handoff`](skills/chip-handoff) | Summarizes the current conversation and hands it to a fresh session as a clickable task chip, rather than writing a handoff file you have to shuttle around yourself. |
| [`second-opinion`](skills/second-opinion) | Sends your whole session, verbatim, to a different agent CLI — Codex, Cursor, or Claude Code — and reports its answer back unedited alongside where it disagrees. The transcript goes over as-is rather than as a summary, so the other model can reject the framing rather than just pick between the options you already settled on. |
| [`writing-tighten`](skills/writing-tighten) | Checks a draft against nine prose rules — kill the warm-up, cut 10%, no adverbs, active voice, concrete over abstract — one pass per rule. Reports what each pass found and applies only the fixes you pick, so the edit stays yours. Command-only; it won't fire on its own. |

`fix-pr-comments` needs the [`gh`](https://cli.github.com) CLI. `chip-handoff` is the one skill here that isn't portable — it depends on the `spawn_task` tool, which only exists in the Claude Code desktop app.
`fix-pr-comments` needs the [`gh`](https://cli.github.com) CLI. `second-opinion` needs at least one other agent CLI installed (`codex`, `cursor-agent`, or `claude`) and `jq` to extract the transcript; it sends the session to another vendor, so read the privacy note in its `SKILL.md` before using it on anything sensitive. `chip-handoff` is the one skill here that isn't portable — it depends on the `spawn_task` tool, which only exists in the Claude Code desktop app.

`writing-tighten`'s rules are adapted from Kaguura Gichuru's [20,585 New Subscribers in 90 Days](https://kaguura.substack.com/p/90-days-20585-new-subscribers-heres). The essay-structure and audience-growth advice in that piece was left out — this is only the repeatable prose rules.

Expand Down
41 changes: 41 additions & 0 deletions skills/second-opinion/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
name: second-opinion
description: Ask a different AI and read its take.
disable-model-invocation: true
argument-hint: "[harness] [model] [effort] — e.g. codex gpt-5.6-sol high"
---

# Second opinion

Put a question to a **different harness** — a different model — and bring back its take. Copy-paste your session into it as is, no changes.

## 1. Export the transcript

Dump this session's conversation to `.scratch/second-opinion/<slug>.transcript.md`, `<slug>` naming the question (outside a repo, use a temp file). See [`transcripts.md`](transcripts.md) for the extraction recipe for the harness you're running in.

Close with a rule and the live question in full, then: *and challenge any claim above you think is wrong*. It's the last thing read, and it has to outrank everything above it — a bare "Answer Q2" doesn't. Disagreement comes for free, but a pinned question keeps the other harness inside the frame; that clause is what buys back the licence to attack it.

The transcript ships everything it contains — command output, file contents, whatever your tool calls returned — to another vendor's CLI. If anything in this session shouldn't travel, say so and let the user decide before you send.

**Done when:** the file reads as the conversation, in order, including the recommendations you gave along the way.

## 2. Ask the other harness

The invocation takes `[harness] [model] [effort]`, each optional. For what wasn't given, ask the user which harness — naming the ones installed here other than the one you're running in — and let the CLI use its own default model and effort.

Run it read-only from the repo root, feed the transcript in as the prompt, and capture the answer to `<slug>.answer.md`. Background it; these take minutes.

## 3. Report the divergence

Give the user, in order:

1. **The answer, verbatim** — the whole of what came back, copied through unedited.
2. **Compare** — the specific claim, weighting, and assumptions.

Check any repo fact it asserts that you hadn't, and say what you found.

Hold both takes open.

## 4. Resume

Return to the grilling question and wait for the user's answer.
39 changes: 39 additions & 0 deletions skills/second-opinion/transcripts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Exporting the current session's transcript

Each harness persists its own sessions locally. Use the recipe for the one you're running in.

Keep assistant and user text; reduce tool calls to a one-line marker so the reader can see where legwork happened without drowning in tool output.

Drop skill bodies. They arrive as user messages but they're instructions to *this* agent, not conversation — and the other harness will read them as its own. Left in, a skill's closing line ("ask the user which harness") outranks your appended question, and the answer comes back addressed to that instead.

## Claude Code

Sessions live in `~/.claude/projects/<slug>/<uuid>.jsonl`, where `<slug>` is the working directory with every `/` and `.` replaced by `-`. The current session is the most recently modified file there.

```bash
SLUG=$(pwd | sed 's/[/.]/-/g')
SESSION=$(ls -t ~/.claude/projects/"$SLUG"/*.jsonl | head -1)
jq -r '
select(.type=="user" or .type=="assistant") | select(.isSidechain|not)
| (.message.role // .type) as $role
| ((.message.content // []) | if type=="string" then [{type:"text",text:.}] else . end)
| map(if .type=="text" then .text
elif .type=="tool_use" then "[tool: " + .name + "]"
else empty end) | join("\n")
| select(length>0)
| select(test("^Base directory for this skill:|<command-name>")|not)
| "\n## " + $role + "\n\n" + .
' "$SESSION" > .scratch/second-opinion/<slug>.transcript.md
```

## Codex

Sessions live under `~/.codex/sessions/<year>/<month>/<day>/`, most recent last. Same JSONL shape in outline — inspect one line first and adjust the filter to the keys you find.

## Cursor

Chats live under `~/.cursor/chats/`. Inspect the store before writing a filter; the layout differs from the JSONL harnesses.

## If extraction fails

Don't reconstruct the conversation from memory — a remembered transcript is a summary, and a summary is the briefing this skill exists to avoid. Tell the user extraction failed, and ask them to paste the conversation into a file instead.