/notebook-kb
Use the notebook knowledge base (the local SQLite RAG /agy:notebook builds from a folder of documents) to do precise, grounded, cited work — total amounts by category, find every doc that mentions a person/organization, build a timeline, export a table — instead of re-reading
$ npx -y skills add MarcosNahuel/antigravity-plugin-cc --skill notebook-kb --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/notebook-kb
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use the notebook knowledge base (the local SQLite RAG /agy:notebook builds from a folder of documents) to do precise, grounded, cited work — total amounts by category, find every doc that mentions a person/organization, build a timeline, export a table — instead of re-reading
SKILL.md
notebook-kb.SKILL.mdname: notebook-kb
description: Use the notebook knowledge base (the local SQLite RAG /agy:notebook builds from a folder of documents) to do precise, grounded, cited work — total amounts by category, find every doc that mentions a person/organization, build a timeline, export a table — instead of re-reading prose and burning Claude's context. Trigger on "sum the amounts", "which docs mention X", "build a timeline", "who/what/when across these documents", or any aggregate/lookup over an analyzed corpus.
user-invocable: true
notebook-kb — work against the local document RAG
`/agy:notebook <folder> | <objective>` analyzes a folder of documents and compiles a **queryable SQLite database** `docs/agy/notebook/<slug>/notebook.db`: `documents, chunks (+FTS5 / optional vectors), entities, events, relations, citations`. Every fact row carries a `quote` and a source document. This skill is how you USE that DB to do real work — deterministically, with citations, and without pulling the documents back into Claude's context.
Decision gate — when to use the DB
- **Use the DB** (`/agy:notebook-query`) for **structured / aggregate / grounding** work: totals of
amounts by category, "which documents mention <person/org/term>", timelines, entity rosters, exporting a table, verifying a figure against its source. SQL is exact and auditable; prose is not.
- **Use `/agy:notebook-ask`** for an open-ended **prose** answer grounded in the summaries.
- **Build/refresh first** if needed: if `notebook.db` is missing → run `/agy:notebook <folder> |
<objective>`. If it's older than the newest `*.facts.json` → rebuild (Phase 1.5): `python "<plugin>/scripts/notebook_db.py" "<OUTDIR>" "<objective>"` (~1s, pure Python).
How to query (there is NO sqlite3 CLI — always Python, read-only)
python - "<OUTDIR>/notebook.db" "<SQL>" <<'PY'
import sqlite3, sys, json
con = sqlite3.connect("file:%s?mode=ro" % sys.argv[1], uri=True); con.row_factory = sqlite3.Row
try: print(json.dumps([dict(r) for r in con.execute(sys.argv[2])], ensure_ascii=False, indent=2, default=str))
except Exception as e: print("SQL_ERROR: %s" % e)
PYPrefer the `v_*` views (they dedup by `ent_key` and keep citations). The schema + a recetas cookbook live in the `/agy:notebook-query` command file — reuse those queries. Entity taxonomy: `persona | organizacion | monto | fecha | referencia`.
Citation contract (non-negotiable for trustworthy answers)
- **Every claim cites** its source: `doc_ref` (or `basename`) of the document the row came from.
- **A SUM lists its contributing rows** so the total is auditable line by line. Monetary math is in
integer `monto_cents`; divide by 100 only to display (no float drift).
- **0 rows → say "does not appear in the corpus"**, and surface coverage gaps:
`SELECT nn,tipo,basename FROM documents WHERE estado='no_procesado'`. **Never invent** a name, amount, date or reference — if it isn't a row in the DB, it isn't a fact.
Downstream workflows (turn the DB into deliverables)
- **Entity roster** → `SELECT * FROM v_personas` / `v_organizaciones` / `v_referencias`.
- **Timeline** → `SELECT * FROM v_timeline` → a chronological briefing.
- **Export a table** → query amounts by category (or any view), emit a small CSV/JSON, and hand it to
whatever downstream tool or report consumes it — instead of transcribing figures from hundreds of pages by hand. Cross-check a computed total against the DB's `v_montos` total before presenting.
- **Contradiction check** → `/agy:notebook-audit <folder>` flags the same category with conflicting
amounts, the same person/org under two names, the same reference with different values, and gaps.
Semantic search (opt-in)
By default retrieval is **FTS5 keyword** (always on, zero deps). For fuzzy/conceptual questions add a vector layer: build with `/agy:notebook <folder> | <objective> --semantic` (needs `pip install sqlite-vec`; real embeddings need a `GEMINI_API_KEY`, else a keyword-ish lexical fallback). Then `/agy:notebook-query` fuses keyword + vector ranking with RRF. Without it, keyword + structured SQL already answer most aggregate/lookup work.
Long sweeps & cross-session
- **Long document sets** — run `/agy:notebook <folder> | <objective> --background` and check progress
with `/agy:notebook-status <folder>` (% done, ETA, pending docs). The sweep persists state every wave, so it's resumable: re-run `/agy:notebook` and cached docs are skipped. No daemon.
- **Cross-folder in Neon (opt-in)** — to query MANY notebooks together, export one KB to Postgres SQL
with `scripts/notebook_neon.py <OUTDIR> <notebook_name>` (writes `nbkb_export.sql`, an isolated `nbkb` schema), then run it via the Neon MCP (`mcp__neon__run_sql`). Only worth it for cross-folder aggregation; the local `notebook.db` already answers single-folder questions.
Reliability notes
- The DB is **disposable** (gitignored) and always rebuildable from the `.facts.json` sidecars; the
`.md` summaries remain the human source of truth.
- The loader is **tolerant**: malformed/missing sidecars fall back to the `.md` frontmatter and are
logged to `_facts_errors.log` — the document is still queryable by `tipo/fecha/doc_ref`.
Read more
name: notebook-kb description: Use the notebook knowledge base (the local SQLite RAG /agy:notebook builds from a folder of documents) to do precise, grounded, cited work — total amounts by category, find every doc that mentions a person/organization, build a timeline, export a table — instead of re-reading prose and burning Claude's context. Trigger on "sum the amounts", "which docs mention X", "build a timeline", "who/what/when across these documents", or any aggregate/lookup over an analyzed corpus. user-invocable: true
notebook-kb — work against the local document RAG
`/agy:notebook <folder> | <objective>` analyzes a folder of documents and compiles a **queryable SQLite database** `docs/agy/notebook/<slug>/notebook.db`: `documents, chunks (+FTS5 / optional vectors), entities, events, relations, citations`. Every fact row carries a `quote` and a source document. This skill is how you USE that DB to do real work — deterministically, with citations, and without pulling the documents back into Claude's context.
Decision gate — when to use the DB
- **Use the DB** (`/agy:notebook-query`) for **structured / aggregate / grounding** work: totals of
amounts by category, "which documents mention <person/org/term>", timelines, entity rosters, exporting a table, verifying a figure against its source. SQL is exact and auditable; prose is not.
- **Use `/agy:notebook-ask`** for an open-ended **prose** answer grounded in the summaries.
- **Build/refresh first** if needed: if `notebook.db` is missing → run `/agy:notebook <folder> |
<objective>`. If it's older than the newest `*.facts.json` → rebuild (Phase 1.5): `python "<plugin>/scripts/notebook_db.py" "<OUTDIR>" "<objective>"` (~1s, pure Python).
How to query (there is NO sqlite3 CLI — always Python, read-only)
python - "<OUTDIR>/notebook.db" "<SQL>" <<'PY'
import sqlite3, sys, json
con = sqlite3.connect("file:%s?mode=ro" % sys.argv[1], uri=True); con.row_factory = sqlite3.Row
try: print(json.dumps([dict(r) for r in con.execute(sys.argv[2])], ensure_ascii=False, indent=2, default=str))
except Exception as e: print("SQL_ERROR: %s" % e)
PYPrefer the `v_*` views (they dedup by `ent_key` and keep citations). The schema + a recetas cookbook live in the `/agy:notebook-query` command file — reuse those queries. Entity taxonomy: `persona | organizacion | monto | fecha | referencia`.
Citation contract (non-negotiable for trustworthy answers)
- **Every claim cites** its source: `doc_ref` (or `basename`) of the document the row came from.
- **A SUM lists its contributing rows** so the total is auditable line by line. Monetary math is in
integer `monto_cents`; divide by 100 only to display (no float drift).
- **0 rows → say "does not appear in the corpus"**, and surface coverage gaps:
`SELECT nn,tipo,basename FROM documents WHERE estado='no_procesado'`. **Never invent** a name, amount, date or reference — if it isn't a row in the DB, it isn't a fact.
Downstream workflows (turn the DB into deliverables)
- **Entity roster** → `SELECT * FROM v_personas` / `v_organizaciones` / `v_referencias`.
- **Timeline** → `SELECT * FROM v_timeline` → a chronological briefing.
- **Export a table** → query amounts by category (or any view), emit a small CSV/JSON, and hand it to
whatever downstream tool or report consumes it — instead of transcribing figures from hundreds of pages by hand. Cross-check a computed total against the DB's `v_montos` total before presenting.
- **Contradiction check** → `/agy:notebook-audit <folder>` flags the same category with conflicting
amounts, the same person/org under two names, the same reference with different values, and gaps.
Semantic search (opt-in)
By default retrieval is **FTS5 keyword** (always on, zero deps). For fuzzy/conceptual questions add a vector layer: build with `/agy:notebook <folder> | <objective> --semantic` (needs `pip install sqlite-vec`; real embeddings need a `GEMINI_API_KEY`, else a keyword-ish lexical fallback). Then `/agy:notebook-query` fuses keyword + vector ranking with RRF. Without it, keyword + structured SQL already answer most aggregate/lookup work.
Long sweeps & cross-session
- **Long document sets** — run `/agy:notebook <folder> | <objective> --background` and check progress
with `/agy:notebook-status <folder>` (% done, ETA, pending docs). The sweep persists state every wave, so it's resumable: re-run `/agy:notebook` and cached docs are skipped. No daemon.
- **Cross-folder in Neon (opt-in)** — to query MANY notebooks together, export one KB to Postgres SQL
with `scripts/notebook_neon.py <OUTDIR> <notebook_name>` (writes `nbkb_export.sql`, an isolated `nbkb` schema), then run it via the Neon MCP (`mcp__neon__run_sql`). Only worth it for cross-folder aggregation; the local `notebook.db` already answers single-folder questions.
Reliability notes
- The DB is **disposable** (gitignored) and always rebuildable from the `.facts.json` sidecars; the
`.md` summaries remain the human source of truth.
- The loader is **tolerant**: malformed/missing sidecars fall back to the `.md` frontmatter and are
logged to `_facts_errors.log` — the document is still queryable by `tipo/fecha/doc_ref`.
A local NotebookLM, multi-agent deep research, and 21 more commands — for Claude Code, powered by Google Antigravity (agy / Gemini 3.x), the official CLI that replaces the now-deprecated gemini-cli.
Repo: MarcosNahuel/antigravity-plugin-cc

