Skip to content
Back to skills

Capture

ASecurity

Use when the user asks to read a source and make a note for it, create or find an atomic note, or check whether a note already exists. Triggers on "read <url> and make a note", "make a note for", "create (or find) an atomic note", "do we have notes about X?", "check if we have a note for", "capture this", "put together a note", "distill this", and on a bare URL/PDF/tweet/thread handed over with intent to write it up. Covers the whole loop as one arc - search the vault first, read the primary ...

  • 10 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 3, 2026
toolspythongoshellbash

Works with

  • cli
  • mcp

Security analysis

A100/100

Pro scans all 10 files and shows the line behind each finding

Scanned September 30, 2026

npx -y skills add technicalpickles/pickled-claude-plugins --skill capture --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Capture?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Capture
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/technicalpickles-capture/badge)](https://www.skillsdirectory.com/skills/technicalpickles-capture)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: capture
description: Use when the user asks to read a source and make a note for it, create or find an atomic note, or check whether a note already exists. Triggers on "read <url> and make a note", "make a note for", "create (or find) an atomic note", "do we have notes about X?", "check if we have a note for", "capture this", "put together a note", "distill this", and on a bare URL/PDF/tweet/thread handed over with intent to write it up. Covers the whole loop as one arc - search the vault first, read the primary source, write the note through the sb CLI, then offer connections. Use inside an Obsidian vault or anywhere a vault is configured. Do NOT use for draining an accumulated inbox backlog (that is process-inbox), for extracting insights from the current conversation (that is devlog), or for routing already-captured notes to their homes (that is route).
allowed-tools:
  - Read
  - Write(~/.claude/vaults/**/*.md)
  - Edit(~/.claude/vaults/**/*.md)
  - Glob
  - Grep
  - Bash(npx @techpickles/sb:*)
  - mcp__qmd__query
  - mcp__qmd__get
  - mcp__qmd__multi_get
  - mcp__qmd__status
hooks:
  PreToolUse:
    - matcher: "Bash"
      hooks:
        - type: command
          command: "python3 \"${CLAUDE_PLUGIN_ROOT}\"/hooks/check-sb-before-call.py"
---

# Capture

Write a note into the vault from a source the user hands you. One arc, six steps:
**search → read the primary source → create through sb → leave it in the inbox → link connections
→ fold in follow-ups.**

This is the dominant vault interaction. Do not decompose it into separate asks; the user saying
"read this and make a note" means all six steps, and the connect step in particular will not
happen unless this skill runs it.

See [references/note-format.md](references/note-format.md) for frontmatter and body shape.
See [../obsidian/references/sb-cli.md](../obsidian/references/sb-cli.md) for the full sb command surface.

## Step 0: Locate the vault

```bash
npx @techpickles/sb vault info
npx @techpickles/sb config qmd-collection
```

Read the vault's own `CLAUDE.md` if you haven't this session. Vault-specific policy (destinations,
status vocabulary, disambiguation rules) overrides the defaults here.

## Step 1: Search before creating - never skip this

Run a `lex` + `vec` pair through the **qmd MCP tools**, not the shell. (`mcp__qmd__query` is the
working path; shelling out to `qmd` hits Metal-init failures under the sandbox.)

```
mcp__qmd__query
  searches: [{type: 'lex', query: '<topic terms>'},
             {type: 'vec', query: '<what the note would say>'}]
  collection: <from sb config qmd-collection>
  intent: '<why you are searching>'
  rerank: false        # CPU-only box, reranking is not worth the latency here
```

Show the user what already exists - **path + score + snippet** - before anything gets written.
Often the right move is extending a note, not minting one. If a result is a strong match, say so
and ask which way to go instead of quietly creating a duplicate.

### When search comes up empty

A miss is not proof the note is absent. In order:

1. **Basename is the stable identity.** Notes get routed between folders constantly. Search the
   basename across the whole vault (`Glob`/`Grep`) before concluding anything is missing.
2. **Check both inboxes.** `10-19 System & Capture/11 Inbox & triage/` and
   `10-19 System & Capture/11 Inbox/` are separate folders with the same JD code. `sb inbox list`
   only reads the first.
3. **The note may genuinely not exist.** Say that plainly and offer to start one.

### When the user says "that isn't the one"

Do **not** re-run the same query with different phrasing, and do not widen `-n` and hope. Ask for
one distinguishing detail (who made it, where they saw it, what it sits next to) and search on
*that* instead. Re-running near-identical searches has burned entire sessions, including the same
lookup failing twice across two separate sessions.

## Step 2: Read the actual primary source

**Never write a note from search snippets.** Fetch the real thing:

| Source | Tool |
|--------|------|
| Web page | `mcp__lightpanda__markdown {url}` preferred; `WebFetch` as fallback |
| Tweet / thread | `xtweet <url-or-id>` (`-q` for quoted chain, `-r` for replies) |
| PDF or local file | `Read` |
| Notion page | `mcp__notiongusto__notion-fetch` |
| Slack thread | the `slack` skill |

**If you cannot reach the source, or cannot find the thing the user described, stop and say so.**
Do not write a note containing a URL you did not load, a title you inferred, or details you filled
in from background knowledge. Reporting "I couldn't find anything matching this" is the correct
outcome and is more useful than a plausible note that is wrong.

## Step 3: Create the note through sb

```bash
npx @techpickles/sb note create --source auto --title "<title>" --dry-run   # check the path first
npx @techpickles/sb note create --source auto --title "<title>"            # returns JSON with path
```

Then write the body at the returned path with `Write`/`Edit`.

**Do not hand-roll the destination path.** sb resolves the inbox, the zettelkasten timestamp, and
the filename slug (`202608141249 note-title.md` - space after the timestamp, hyphens inside the
slug). Hand-rolled `Write` calls are how captures end up in the inbox the pipeline never reads:
as of 2026-08-14 that had orphaned 46 notes, and untangling it took a single 211-message session.

For a title, prefer the source's own framing over a topic label. `# Glide browser` beats
`# Notes on a keyboard-driven browser`.

## Step 4: Leave it in the inbox for `process-inbox` to route

The note stays where sb put it. Routing is `process-inbox`'s job, not capture's —
don't ask, don't route it, and don't mention that it still needs routing.

This overrides the vault's general "capture: file rough, move on / a wrong-but-close
home beats the global inbox" guidance, which governs notes *the user* files by hand.
Notes *the agent* writes on request stay in the inbox until `process-inbox` picks them
up. Both rules coexist in the vault CLAUDE.md; the scope of the override has
historically been read as ambiguous — first producing a roughly 50/50 split between
inbox and direct-to-area filing, later a per-note routing question duplicating
process-inbox's own batch routing. It is not ambiguous: **agent-written note on
request → inbox, no offer, no mention.**

The exception is an explicit destination named in the same conversation ("put it in
66"). Resolve it the way `route` would rather than hand-rolling a path: run
`sb vault structure`, match the user's phrase against a real destination (JD `area`/
`code` or PARA folder), then `sb note move --from "{note-path}" --to "{destination}/"`.
Never construct the destination path from the user's words alone.

## Step 5: Link connections, append the daily breadcrumb

Connection discovery does not fire on its own, and the user should not have to notice it was
skipped. **Run it every time**, using the step 1 results plus a fresh search from the finished
note's content. Only ever link notes **confirmed to exist** by an actual search hit — never a
`[[link]]` you have not verified, and never a side note created on your own initiative (offer
those, don't make them - see Constraints).

Split what the search turns up by confidence, and don't ask about the confident ones:

- **Confident - add it, don't ask.** The existing note passes either test: **same subject** (same
  tool/person/project/event as the new note, not just a shared theme) or **named in the source**
  (the source text itself references the thing that note covers). Add it under `## Related` with a
  few words on *why* it relates - a bare link list decays - and mention it in your summary
  (`Linked to <note>.`), but don't stop to ask first.
- **Weak - offer, don't add.** Same theme or category but a different subject (e.g. two notes both
  about "self-hosted family tooling" but covering different products). Surface these as a suggestion
  ("Want me to link X too?") and let the user decide.

If in doubt which bucket a match falls in, try writing the "why" clause without the words "theme"
or "similar" - if you can't, it's weak.

Then append the daily-note breadcrumb yourself - this is no longer a yes/no:

1. **Append:**
   ```bash
   npx @techpickles/sb daily append --section "Notes" --content "- [[<note>]] - <one-line why>"
   ```
   One command does the whole job. `sb` creates today's daily note from the vault's configured
   Obsidian daily template when it doesn't exist yet, and matches the existing `## Notes` heading
   when it does. Keep the breadcrumb to links unless asked for more, and do not restructure or
   rewrite the daily note.

   Do not pre-check the note's existence, hand-copy the template, or verify where the line landed.
   Those steps existed to paper over CLI bugs that are fixed; re-adding them is how a one-command
   step turns back into four.

   If the append does fail, say so out loud. A dropped breadcrumb must never be silent now that no
   one is asked before it happens.
2. **Report it in one line**, e.g. `Added breadcrumb to today's daily note.` No ceremony - just
   enough for Josh to see it and undo or adjust. When the response includes `"created": true`, the
   note was seeded from the template verbatim, so any `{{date}}` or placeholder links in it are
   still literal. Leave them alone - that is the template's business, not the breadcrumb's.

For deeper backlink weaving, hand off to the `connect` skill rather than reimplementing it.

## Step 6: Fold in follow-up research on the note you just wrote

If, right after capture, the user asks a question about the thing the note covers ("is there a
release date yet?", "how does this relate to X?"), answer it and then **update the note with the
answer** - don't just answer in chat and leave the note stale. This is still editing the note we
just made, not creating something new, so it doesn't need a yes first. Say what you added in one
line (`Added the October 2026 theater date.`).

This stops once the conversation moves to a genuinely new note or a different source - it covers
direct follow-ups on the note just written, not an open-ended research thread.

## Capturing several sources at once

When the user hands over a batch ("make notes for each of these", "write them up", "atomic notes
for each option/family we found"), dispatch **one subagent per note** so each reads its source in
isolation and cannot cross-contaminate. This is a pattern the user asks for explicitly; default to
it for 3+ sources.

Phrasing like "each option", "separate notes", or "at least the families of them" is standing
permission for the whole batch - don't re-ask per item once the batch is agreed. A single new note
still gets offered, not created outright (see Constraints).

Each subagent: read the primary source, write one note via sb, and report back **path, title,
verified wiki-links used, and anything it could not confirm**. Then do the cross-linking pass
yourself once all notes exist, since connections need the whole set in view.

## Constraints

- **Search first, always.** No note gets written before the user has seen what already exists.
- **Primary sources only.** No note written from a snippet, a memory, or a guess.
- **Never fabricate.** No invented URLs, no unverified `[[links]]`, no filled-in details. Stop and
  report the gap instead.
- **sb owns paths.** No hand-rolled destinations.
- **Inbox by default.** Routing is `process-inbox`'s job — capture never asks or
  routes, except an explicit user-named destination, resolved via `sb vault
  structure` like `route` does, never hand-rolled.
- **Confident links and the breadcrumb are automatic; new notes and weak links are offered.**
  A confident link (same subject, or named in the source) gets added and mentioned, not asked
  about. A weak link (same theme, different subject) and any brand-new note get offered as a
  suggestion, never created outright - unless the user's phrasing already covers the whole batch
  (see "Capturing several sources at once"). The daily-note breadcrumb append happens automatically
  every time regardless.
- **Editing the note just written doesn't need permission.** A confident related link or a
  direct follow-up answer about the note's subject (Step 6) both count as finishing the note
  already in progress, not starting something new.
- **One note, one idea.** If the source carries several distinct ideas, say so and offer to split
  rather than writing one sprawling note.

Files in this skill

  • SKILL.md10.5 KB
  • evals/README.md5.5 KB
  • evals/eval_config.yaml1.6 KB
  • evals/results/2026-08-14-no-pointer.json2.4 KB
  • evals/results/2026-08-14-pointer-scoped-to-create.json4.5 KB
  • evals/results/2026-08-14-pointer-widened.json4.5 KB
  • evals/scenarios/no-route-offer/scenario.yaml6.6 KB
  • evals/trigger-evals.json4 KB
  • evals/trigger_eval.py8.2 KB
  • references/note-format.md3.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.