Skip to content
Data
Command

/ingest

Lite ingest — fetch a paper and write a short 4-section triage summary (Key Takeaways, Background, Main Idea & Summary, Critique). No figures, fast.

From plugin
paperloom
964 skills4 agents4 commands

Command definition

ingest.md
description: Lite ingest — fetch a paper and write a short 4-section triage summary (Key Takeaways, Background, Main Idea & Summary, Critique). No figures, fast.
argument-hint: "<url | arxiv-id | doi | pdf-path>"

/paperloom:ingest

Fast, triage-grade ingest. `$ARGUMENTS` is the paper reference.

**Division of labor**: the deterministic steps (fetch, parse, template fill, edge aggregation, logging, stub creation, citation matching) are done by Python scripts in `${CLAUDE_PLUGIN_ROOT}/scripts/`. The LLM is used only for the three remaining semantic subagents: `lite-drafter`, `finding-extractor`, `metadata-extractor`. Per-item LLM loops are forbidden — if you find yourself running an agent N times for N items, stop and shell out to a script.

Step 0 — greet the user

Print exactly: > 📖 Ingesting your paper — this will take a moment. Sit back, get cozy, and maybe grab a coffee ☕️

Step 1 — fetch + extract

Shell out. The script validates the vault, classifies the input, caches the raw file, and produces full + brief text:

"${CLAUDE_PLUGIN_ROOT}/.venv/bin/python3" "${CLAUDE_PLUGIN_ROOT}/scripts/fetch_paper.py" "<vault-path>" "$ARGUMENTS"

Parse the JSON result.

**Early exit — duplicate paper.** If the result has `"already_exists": true`, the paper is already in the vault (matched by arxiv-id, doi, or source-url). Do not run any further steps. Print a short message naming the existing slug, e.g.:

> ⏭️ This paper is already in your vault as `papers/<existing.slug>.md` — skipping ingest.

Then stop.

Otherwise, keep `full_text_path`, `brief_text_path`, `findings_text_path`, `meta_text_path`, `source_url`, `arxiv_id`, `doi` for later steps.

Step 2 — scan vault for context

Run these in parallel (they're independent reads):

"${CLAUDE_PLUGIN_ROOT}/.venv/bin/python3" "${CLAUDE_PLUGIN_ROOT}/scripts/vault_scan.py" fields  "<vault-path>"
"${CLAUDE_PLUGIN_ROOT}/.venv/bin/python3" "${CLAUDE_PLUGIN_ROOT}/scripts/vault_scan.py" papers  "<vault-path>"
"${CLAUDE_PLUGIN_ROOT}/.venv/bin/python3" "${CLAUDE_PLUGIN_ROOT}/scripts/vault_scan.py" authors "<vault-path>"

Hold the outputs: `existing_fields`, `vault_papers`, `existing_authors`.

Step 3 — fan-out: 2 LLM subagents (semantic-only)

Launch in **one parallel message**:

| Agent | Model | Input | Purpose | |---|---|---|---| | `lite-drafter` | `model_reasoning` | `brief_text_path` | returns the 4 sections JSON | | `finding-extractor` | `model_normal` | `findings_text_path` | returns atomic findings JSON. Fed the abstract + intro + method + results + conclusion slice, not the full paper — saves tokens while keeping theoretical / empirical / definitional claims reachable. |

**Do not spawn a citation-linker agent** — bibliographic matching is deterministic and runs in step 6 via `citation_match.py`.

Step 4 — metadata (after lite-drafter)

Once `lite-drafter` returns, spawn `metadata-extractor` (`model_normal`) with:

  • `paper_text_path` = `meta_text_path` (first 2 pages — enough for title/authors/date/venue/quality)
  • `summary_text` = the concatenated markdown returned by `lite-drafter` (for `fields`)
  • `existing_fields` = list from step 2
  • `source_url`, `arxiv_id`, `doi` = from step 1

The agent returns metadata JSON. It does NOT compute `quality.overall` or the slug — the assembly script does both.

Step 5 — assemble the paper page

**Before writing any `/tmp/*.json` payload in this step or step 6/7**, first clear stale files from prior runs in a single Bash call:

rm -f /tmp/paper_payload.json /tmp/findings_payload.json /tmp/stubs_payload.json /tmp/edges_payload.json

Without this, the `Write` tool refuses to overwrite a `/tmp/*.json` file it has not Read in the current conversation, and the ingest stalls.

Write the payload to `/tmp/paper_payload.json` with this **exact shape** (note `metadata` is a nested key — flat layouts will fail with `KeyError: 'metadata'`):

{
  "vault_path": "<vault-path>",
  "source_url": "<source_url from step 1>",
  "metadata": {
    "title": "...",
    "authors": ["Surname, Given", "..."],
    "publication-date": "YYYY-MM-DD",
    "venue": "...",
    "fields": ["nlp", "..."],
    "arxiv-id": "..." ,
    "doi": null,
    "quality": {
      "credibility": 5,
      "experimental-rigor": 5,
      "reproducibility": "code-released",
      "rationale": "..."
    }
  },
  "sections": {
    "key_takeaways": "...",
    "background": "...",
    "main_idea_and_summary": "...",
    "critique": "..."
  },
  "findings": [],
  "relations": {}
}

Then pipe it in:

"${CLAUDE_PLUGIN_ROOT}/.venv/bin/python3" "${CLAUDE_PLUGIN_ROOT}/scripts/assemble_paper.py" --input /tmp/paper_payload.json

The script computes `quality.overall`, generates `slug` if absent, fills `templates/paper-lite.md`, and writes `<vault>/papers/<slug>.md`. It refuses to overwrite unless `overwrite: true` is set in the payload — ask the user first.

Capture the returned `slug`.

Step 6 — in parallel: findings, citations, candidates, stubs

`/tmp/findings_payload.json` shape (note `source_paper`, not `paper_slug`):

{
  "vault_path": "<vault-path>",
  "source_paper": "<slug from step 5>",
  "fields": ["nlp", "..."],
  "findings": [ { "statement": "...", "source-ref": "...", "finding-type": "empirical", "hedging": "asserted", "quote": "..." } ]
}

`/tmp/stubs_payload.json` shape:

{ "vault_path": "<vault-path>", "authors": ["Surname, Given", "..."], "fields": ["nlp", "..."] }

Launch all four at once — they're independent. **6c uses `--exclude-paper <slug>` to keep the just-written findings (from 6a) out of the candidate set, so ordering between 6a and 6c doesn't matter.**

# 6a. Write finding files in one script call.
"${CLAUDE_PLUGIN_ROOT}/.venv/bin/python3" "${CLAUDE_PLUGIN_ROOT}/scripts/assemble_finding.py" --input /tmp/findings_payload.json

# 6b. Deterministic citation matching. Feed vault_papers from step 2.
"${CLAUDE_PLUGIN_ROOT}/.venv/bin/pyth
Read more
@trapoom555
Ships withpaperloom

Claude Code Plugin for Self-maintaining research knowledge graph for Claude Code + Obsidian

Stars on GitHub

Momentum

stars in total
96
Star history of trapoom555/claude-paperloom on GitHub, a chart by star-history.com

Other commands on paperloom.

init

init

Command

Scaffold a new PaperLoom at the configured path (or at an optional path argument). Idempotent — fills missing files without…

@trapoom555@trapoom555Install Command
lint

lint

Command

Scan the vault for orphan pages, frontmatter schema drift, duplicate findings, unmarked contradictions, and stale wikilinks.…

@trapoom555@trapoom555Install Command
query

query

Command

Ask a question of the research vault. Searches papers and findings, synthesizes an answer with wikilink citations.

@trapoom555@trapoom555Install Command

More commands from other plugins.

COMMANDS.generated

COMMANDS.generated

Command

<!-- Generated from backend/logic/schema.py. Do not edit. Run `hogli build:projections`. -->

posthog2w41k
@posthog@posthogInstall Command
recall
Auto-invoked

recall

Command

Search past session observations and lessons for relevant context. Wrap the `memory_smart_search` and `memory_lesson_recall` MCP…

@rohitg00@rohitg00Install Command