@bojackduy/opencode-learn 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/LICENSE +25 -0
- package/README.md +151 -0
- package/agents/mermaid-maker.md +61 -0
- package/agents/researcher.md +53 -0
- package/agents/svg-maker.md +65 -0
- package/commands/md_log.md +5 -0
- package/commands/md_unlog.md +5 -0
- package/dist/server.js +1181 -0
- package/dist/tui.js +1528 -0
- package/package.json +92 -0
- package/plugins/learn-tui.tsx +548 -0
- package/plugins/learn.ts +991 -0
- package/scripts/build-tui.ts +20 -0
- package/scripts/install.mjs +250 -0
- package/skills/marker-pdf-parser/README.md +38 -0
- package/skills/marker-pdf-parser/SKILL.md +130 -0
- package/skills/marker-pdf-parser/requirements.txt +1 -0
- package/skills/marker-pdf-parser/scripts/parse_pdf.py +150 -0
- package/skills/notebooklm-lecture-notes/SKILL.md +173 -0
- package/skills/notebooklm-lecture-notes/references/prompts.md +40 -0
- package/skills/teach/SKILL.md +150 -0
- package/skills/visualize/SKILL.md +82 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: notebooklm-lecture-notes
|
|
3
|
+
description: 'Process academic PDFs through NotebookLM MCP and convert into structured lecture notes with proper file indexing and category organization. USE FOR: converting research papers to lecture notes, extracting paper content via NotebookLM, organizing PDF libraries with numbered indexing. DO NOT USE FOR: OCR of scanned documents, general text extraction without NotebookLM, editing PDFs, or creating bibliographic databases.'
|
|
4
|
+
compatibility: Requires notebooklm-mcp MCP server with authenticated Google NotebookLM session and pymupdf Python library for local extraction fallback.
|
|
5
|
+
metadata:
|
|
6
|
+
version: "0.0.1"
|
|
7
|
+
tags:
|
|
8
|
+
- notebooklm
|
|
9
|
+
- pdf-processing
|
|
10
|
+
- lecture-notes
|
|
11
|
+
- academic-research
|
|
12
|
+
- vault-organization
|
|
13
|
+
mcp:
|
|
14
|
+
required:
|
|
15
|
+
- notebooklm-mcp
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# NotebookLM Lecture Notes
|
|
19
|
+
|
|
20
|
+
## When to use
|
|
21
|
+
|
|
22
|
+
Use this skill when the user asks you to:
|
|
23
|
+
|
|
24
|
+
- Read academic PDFs and turn them into structured lecture notes
|
|
25
|
+
- Use NotebookLM to process papers in their vault
|
|
26
|
+
- Extract content from PDF files and rewrite as teaching material
|
|
27
|
+
- Organize and index a collection of research papers with numbering
|
|
28
|
+
- "Process these PDFs through NotebookLM"
|
|
29
|
+
- "Rewrite these papers as lecture notes"
|
|
30
|
+
- "Index and organize my papers folder"
|
|
31
|
+
- "Number these files and group them by category"
|
|
32
|
+
|
|
33
|
+
## When not to use
|
|
34
|
+
|
|
35
|
+
- Simple PDF-to-text extraction without rewriting (use `marker-pdf-parser` or `pdf-extract` instead)
|
|
36
|
+
- OCR of scanned documents with no text layer
|
|
37
|
+
- Editing or annotating the original PDF files
|
|
38
|
+
- Creating citation managers or reference databases
|
|
39
|
+
- Processing non-academic content (manuals, reports, documentation)
|
|
40
|
+
- When NotebookLM MCP is unavailable or unauthenticated
|
|
41
|
+
|
|
42
|
+
## Required inputs
|
|
43
|
+
|
|
44
|
+
- **PDF source folder**: absolute path to directory containing the PDF files
|
|
45
|
+
- **NotebookLM share URL**: a share link from https://notebooklm.google.com with the PDFs already uploaded
|
|
46
|
+
|
|
47
|
+
## Optional inputs
|
|
48
|
+
|
|
49
|
+
- **Category groupings**: how to classify the papers (may suggest, or let user decide)
|
|
50
|
+
- **Numbering scheme**: starting number (default: 02 if 00-01 exist for contextual notes)
|
|
51
|
+
- **Output folder structure**: defaults to vault's `topics/` and `resources/papers/` pattern
|
|
52
|
+
|
|
53
|
+
## Instructions
|
|
54
|
+
|
|
55
|
+
### Phase 1 — Setup
|
|
56
|
+
|
|
57
|
+
1. Ask the user for a NotebookLM share URL if one is not provided. The user must:
|
|
58
|
+
- Open https://notebooklm.google.com
|
|
59
|
+
- Create a notebook or use an existing one
|
|
60
|
+
- Drag-and-drop all target PDFs into the notebook (this MCP cannot upload local files)
|
|
61
|
+
- Click Share → "Anyone with the link" → Copy link
|
|
62
|
+
|
|
63
|
+
2. Add the notebook to the local library:
|
|
64
|
+
```
|
|
65
|
+
notebooklm-mcp_add_notebook(url, name, description)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
3. Select the notebook as active:
|
|
69
|
+
```
|
|
70
|
+
notebooklm-mcp_select_notebook(id)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Phase 2 — Extract & rewrite through NotebookLM
|
|
74
|
+
|
|
75
|
+
For each PDF source in the notebook:
|
|
76
|
+
|
|
77
|
+
1. Ask NotebookLM to rewrite as lecture notes. Use the prompt template from `references/prompts.md`. Send as:
|
|
78
|
+
```
|
|
79
|
+
notebooklm-mcp_ask_question(question, source_format="none")
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
2. Handle timeouts gracefully:
|
|
83
|
+
- The MCP has a hard timeout (~60s) that NotebookLM's browser automation may exceed
|
|
84
|
+
- If a question times out, try splitting the request into parts
|
|
85
|
+
- Ask Part 1 (motivation, definitions, research directions) separately from Part 2 (results, conclusions)
|
|
86
|
+
- If it still times out, inform the user — those PDFs may need direct manual querying in NotebookLM
|
|
87
|
+
|
|
88
|
+
3. Collect each response verbatim — NotebookLM is the rewriting engine, not the agent. Do not summarize, rephrase, or modify the output.
|
|
89
|
+
|
|
90
|
+
### Phase 3 — File management & numbering
|
|
91
|
+
|
|
92
|
+
1. Determine numbering scheme:
|
|
93
|
+
- Check existing `topics/` for current highest number (e.g., 01-mv2026-evaluation-criteria.md)
|
|
94
|
+
- New sources start at the next number (e.g., 02, 03...)
|
|
95
|
+
|
|
96
|
+
2. Rename each PDF to match the numbering:
|
|
97
|
+
```
|
|
98
|
+
Original filename → NN-descriptive-name.pdf
|
|
99
|
+
```
|
|
100
|
+
- NN is the two-digit number matching the topic note
|
|
101
|
+
- Strip special characters (parentheses, underscores where possible)
|
|
102
|
+
- Use kebab-case
|
|
103
|
+
|
|
104
|
+
3. Organize into category subfolders:
|
|
105
|
+
- `resources/papers/<category>/NN-descriptive-name.pdf`
|
|
106
|
+
- `topics/<category>/NN-descriptive-name.md`
|
|
107
|
+
|
|
108
|
+
### Phase 4 — Write output files
|
|
109
|
+
|
|
110
|
+
1. Save each NotebookLM response as a markdown file with frontmatter:
|
|
111
|
+
```markdown
|
|
112
|
+
# Lecture Notes: <Paper Title>
|
|
113
|
+
|
|
114
|
+
**Source:** `<filename>.pdf` (NotebookLM-processed)
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
<NotebookLM response content>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
2. Create subfolder `_index.md` files for each category if they contain multiple entries, listing the included topics.
|
|
122
|
+
|
|
123
|
+
3. Update the vault's `_index.md` (or MOC):
|
|
124
|
+
- Group entries under category subheadings
|
|
125
|
+
- Add a resources table linking topics to source PDFs
|
|
126
|
+
- Update reading order
|
|
127
|
+
|
|
128
|
+
### Phase 5 — Quality check
|
|
129
|
+
|
|
130
|
+
- Each topic file must start with a title heading and source attribution
|
|
131
|
+
- Content must be NotebookLM's output, not the agent's rewriting
|
|
132
|
+
- PDF filenames must match their topic note numbers
|
|
133
|
+
- _index.md must have working relative links to all new files
|
|
134
|
+
|
|
135
|
+
## Examples
|
|
136
|
+
|
|
137
|
+
**User:** "Process these PDFs in /papers/ through NotebookLM and turn them into notes"
|
|
138
|
+
**Behavior:**
|
|
139
|
+
1. Ask for NotebookLM share URL
|
|
140
|
+
2. Add notebook, select it
|
|
141
|
+
3. For each PDF: ask NotebookLM to rewrite → save as `topics/<category>/NN-name.md`
|
|
142
|
+
4. Rename PDFs to match → move to `resources/papers/<category>/`
|
|
143
|
+
5. Update _index.md
|
|
144
|
+
|
|
145
|
+
**User:** "Organize and index my Anh-Duy Research papers"
|
|
146
|
+
**Behavior:**
|
|
147
|
+
1. Examine PDFs in `resources/papers/`
|
|
148
|
+
2. Suggest category groupings (core-systems, evidence-retrieval, security, project-briefs)
|
|
149
|
+
3. Let user confirm → rename → move → update index
|
|
150
|
+
|
|
151
|
+
**User:** "Use NotebookLM to rewrite this one paper for me"
|
|
152
|
+
**Behavior:**
|
|
153
|
+
1. Ask for the paper name and NotebookLM share URL
|
|
154
|
+
2. Ask NotebookLM for that specific source
|
|
155
|
+
3. Save as a single markdown file
|
|
156
|
+
4. Rename corresponding PDF
|
|
157
|
+
5. Link from _index.md
|
|
158
|
+
|
|
159
|
+
## Expected output
|
|
160
|
+
|
|
161
|
+
- Renamed PDF files in `resources/papers/<category>/` with numbered prefixes matching topic notes
|
|
162
|
+
- Markdown lecture notes in `topics/<category>/` with NotebookLM-generated content
|
|
163
|
+
- Updated `_index.md` with grouped entries, resources table, and reading order
|
|
164
|
+
- Each note file has source attribution and clean lecture-note formatting
|
|
165
|
+
|
|
166
|
+
## Safety & constraints
|
|
167
|
+
|
|
168
|
+
- Never modify original PDF file content — only rename and move them
|
|
169
|
+
- Always verify the notebooklm-mcp is authenticated before processing
|
|
170
|
+
- Never summarize or rephrase NotebookLM's output — pass it through verbatim
|
|
171
|
+
- If the MCP times out repeatedly, tell the user honestly rather than falling back to local extraction without consent
|
|
172
|
+
- Do not upload or expose any files through unauthorized channels
|
|
173
|
+
- Keep NotebookLM session count below the max (10) to avoid browser overload
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Lecture Notes Prompt Templates
|
|
2
|
+
|
|
3
|
+
## Full paper → lecture notes
|
|
4
|
+
|
|
5
|
+
Use when the MCP timeout permits a single comprehensive question:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Rewrite the source "<PDF-NAME>" into comprehensive structured lecture notes.
|
|
9
|
+
Rules: NO summarizing, NO skipping — preserve 100% of the information.
|
|
10
|
+
Rewrite in full sentences as if a professor is teaching. Use markdown headings,
|
|
11
|
+
bullet points, tables, code blocks. Capture every concept, definition, finding,
|
|
12
|
+
result, data point, table, and formula. Output the complete lecture notes.
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Split request (for timeout-prone documents)
|
|
16
|
+
|
|
17
|
+
**Part 1 — Context, method, architecture:**
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
From the source "<PDF-NAME>", give me PART 1: the motivation, problem
|
|
21
|
+
definition, related work, system architecture, and methodology. Rewrite as
|
|
22
|
+
structured lecture notes. Full professor teaching style, no summarizing.
|
|
23
|
+
Include all definitions, formulas, and design details.
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Part 2 — Results and conclusions:**
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
From the source "<PDF-NAME>", give me PART 2: the experimental setup,
|
|
30
|
+
datasets, results (all tables and numbers), key insights, ablation studies,
|
|
31
|
+
conclusions, and future work. Rewrite as structured lecture notes. Include
|
|
32
|
+
every data point and finding — no summarizing.
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quick outline (check content first)
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
From the source "<PDF-NAME>", list all section headings and the key bullet
|
|
39
|
+
points under each. Give me the full outline of everything in this document.
|
|
40
|
+
```
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: teach
|
|
3
|
+
description: Teach the user anything so it actually locks in and is understood, not just memorized. Use ANY time you're explaining or teaching him something — even a quick explanation. Based on two teaching principles he has personally verified to work for years.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> **OpenCode port** — original pi skill. In OpenCode: use `quiz` for graded checks, native `question` for open forks, `task` with `subagent_type: "researcher"` for verification, and `md_log`/`md_unlog` tools to mirror to Obsidian. The philosophy and probe→plan→teach loop are unchanged.
|
|
7
|
+
|
|
8
|
+
# Teaching
|
|
9
|
+
|
|
10
|
+
Two principles. They are not tips — they are how you teach him, every time. No other teaching methods come close. Apply them to any explanation, from a one-liner to a deep dive.
|
|
11
|
+
|
|
12
|
+
The goal is never "he can recite the fact." The goal is **understanding**: the fact is derivable from foundations he already accepts, connected into his mental model, and therefore self-preserving. Memorized facts rot. Understood facts don't.
|
|
13
|
+
|
|
14
|
+
## The philosophy (why this works — internalize it)
|
|
15
|
+
|
|
16
|
+
Two brains can hold the same propositions and look identical from the outside (same answers to the same questions). But one holds a pile of **disconnected lone facts** (A). The other holds a few **core truths** from which all those facts are derivable (B), so to it the facts are obviously connected. That connection *is* understanding.
|
|
17
|
+
|
|
18
|
+
- Connected knowledge > disconnected knowledge
|
|
19
|
+
- A graph of dependencies > disjoint lonely nodes
|
|
20
|
+
- Understanding > memorizing
|
|
21
|
+
|
|
22
|
+
Understanding preserves knowledge (it's held in place by its connections), compresses it, and is just plain better. Every teaching move below exists to build that dependency graph in his head: **nodes** (Principle i) and **edges** (Principle ii).
|
|
23
|
+
|
|
24
|
+
The felt goal is **the click**: the moment a pile of lonely facts collapses (compresses) into a few generating ideas — same information, far fewer moving parts. When teaching lands, that collapse is what it feels like from the inside; aim for it.
|
|
25
|
+
|
|
26
|
+
A key mechanism: **the brain won't fully commit to a fact it isn't sure is safe to lock in.** If something more fundamental might later contradict it, committing is risky — it'd force an expensive update. So the brain hedges, and the fact never really lands. Both principles below remove that risk in different ways.
|
|
27
|
+
|
|
28
|
+
## Principle i — Unconditional truths first
|
|
29
|
+
|
|
30
|
+
Start from the ground. Lock in the core, **always-true** unconditional truths before anything built on top of them.
|
|
31
|
+
|
|
32
|
+
Why start here? **Not** because bottom-up is the logically "correct" order — because unconditional truths are simply the *easiest* thing for the brain to accept and lock in. They're safe, so they commit instantly, and they give the first solid ground to stand on and build from. Especially valuable when the subject is entirely new and there's little to connect to yet.
|
|
33
|
+
|
|
34
|
+
**Terminology — keep these distinct, and don't overuse "axiom."** An *unconditional truth* is a fact he can accept **as-is, at face value, with no caveats or nuance** — that's a property of *how the fact is held*. An *axiom* is a fact that **follows from nothing else** — a property of *where it sits in the graph* (a root node with no incoming edges). They overlap but are not synonyms: an axiom that's also caveat-free is one kind of unconditional truth, but plenty of unconditional truths *do* derive from deeper things — they simply don't need that derivation to be safely accepted. Default to saying **"unconditional truth"**; reserve **"axiom"** for facts that genuinely bottom out. Don't call something an axiom just because it sounds foundational.
|
|
35
|
+
|
|
36
|
+
- Find the few hard facts he can take at face value — often first principles that don't depend on anything else, though they needn't be true roots. There may be very few. That's fine; small and solid beats large and shaky.
|
|
37
|
+
- They must be simple enough to be accepted **as-is, without nuance or caveats**. No "well, usually…". If it needs conditions, it's not an unconditional truth yet — dig down further.
|
|
38
|
+
- These can be committed to *instantly and safely*, because nothing more fundamental will come along to contradict them. That safety is what makes them lock in.
|
|
39
|
+
- Build everything else up from these, explicitly, so he can see each new fact resting on the foundation.
|
|
40
|
+
|
|
41
|
+
**Confirm the foundation before building on it.** Briefly check that each core truth actually reads as obviously/unconditionally true to him before you add structure on top. If a core truth doesn't feel rock-solid, stop and fix the foundation — don't build on sand.
|
|
42
|
+
|
|
43
|
+
**Two especially strong forms of unconditional truth to reach for:**
|
|
44
|
+
- **Universal statements** — *"all X are Y"* or *"no X is Y"*. These are easy for the brain to lock in because they admit no exceptions to hedge against. A clean atomic-unit version (*"ALL X is done through {____}"*, e.g. *"ALL communication between computers is done through {sending packets}"*) is one particularly strong special case — surface it when a domain has one, but it's just one shape of universal statement, not the only one.
|
|
45
|
+
- **Real definitions** — a genuine definition is a great place to start. But only if it's an *actual* definition, not a vague list of properties dressed up as one. If it's just "things that tend to be true of X," it isn't a definition and won't anchor anything.
|
|
46
|
+
|
|
47
|
+
Don't force either where there isn't a clean one.
|
|
48
|
+
|
|
49
|
+
## Principle ii — "How could I have discovered this?"
|
|
50
|
+
|
|
51
|
+
Facts feel arbitrary when there's no visible reason they *had* to be this way. "Why does it need to be like this? Feels arbitrary." The brain won't commit to arbitrary-feeling info. The fix: make it feel discovered, not decreed.
|
|
52
|
+
|
|
53
|
+
Walk him through how he **could have discovered the thing himself**. Every step must be *motivated*:
|
|
54
|
+
|
|
55
|
+
- Start from square one: **why are we even doing this?** What core problem sends us down this path?
|
|
56
|
+
- Motivate every intermediate step too: why try *this* formula? why manipulate the equation *this* way? What could have led someone to this approach in the first place?
|
|
57
|
+
- The output is turning **disconnected propositions → connected propositions** — adding the edges to the graph.
|
|
58
|
+
|
|
59
|
+
3Blue1Brown (Grant Sanderson) is the master reference for this. Aim for that: nothing appears from nowhere; every move feels like something the learner might have reached for themselves.
|
|
60
|
+
|
|
61
|
+
### Socratic vs expository — adaptive
|
|
62
|
+
|
|
63
|
+
Choose per topic and per his apparent energy:
|
|
64
|
+
- **Socratic** — pose the motivating problem and let him attempt the discovery before you reveal. More effortful, stronger locking-in. Default to this when he can plausibly reason his way there. "Let him attempt it" is about *who* speaks first, not about grading: if the question you pose has a definite right answer (even as an open-ended prompt he answers freely, which you then frame as multiple-choice), it's still gradable — use `quiz`, not `question`. Reserve `question` for genuine no-right-answer forks (preferences, direction, what he wants next).
|
|
65
|
+
- **Expository** — you narrate the motivated discovery path yourself (3B1B style), no back-and-forth needed. Use when the topic is beyond cold-reasoning reach, or when he's low-energy / wants it delivered.
|
|
66
|
+
|
|
67
|
+
When unsure, lean Socratic for things he can clearly reason about; otherwise narrate.
|
|
68
|
+
|
|
69
|
+
## The process: probe → plan → teach
|
|
70
|
+
|
|
71
|
+
The two principles are *how* you teach. This is *when* — the shape of a teaching session. Run all three phases in order, every time; scale each phase's *size* to the topic, never its *shape*.
|
|
72
|
+
|
|
73
|
+
**Accuracy is non-negotiable — verify, don't wing it from memory.** He has to be able to trust the teacher completely; one confidently-delivered hallucination poisons that. Working from memory alone is where LLMs invent things, so: **the moment you are even slightly unsure of any fact, name, date, formula, definition, or claim, stop and confirm it with a quick `researcher` subagent (via `task` with `subagent_type: "researcher"`) before you say it.** Pausing to verify is always acceptable — accuracy beats flow, every time. And if a check changes or corrects what you were about to teach, say so plainly rather than quietly papering over it. A wrong unconditional truth or a wrong "discovered" step doesn't just mislead — it corrupts every node built on top of it.
|
|
74
|
+
|
|
75
|
+
### Writing quiz options — a construction procedure (applies to every `quiz`)
|
|
76
|
+
|
|
77
|
+
The tool already tells you to keep options even. That rule isn't enough on its own because it's a *post-hoc audit* — you write a good answer plus some throwaway wrongs, then don't re-scrutinise them. The tell is baked in before any check runs. So don't audit afterwards; **build the options so evenness is automatic**:
|
|
78
|
+
|
|
79
|
+
1. **Every option is a bare claim — no justification anywhere.** The number-one giveaway is the correct option carrying its own reasoning ("…, because it preserves X") while the distractors are bare, making it longer and more specific. Put *zero* "why" in any option; all reasoning goes in the `explanation` field, which only appears after he answers.
|
|
80
|
+
2. **Write the correct claim first, then mutate it into each distractor.** Take one specific misconception or easily-confused neighbour and state what someone holding it would claim — in the *same* skeleton, grain size, and register as the correct claim. Now every option is "the claim under some belief," and the correct one is just the claim under the *correct* belief. Parallelism falls out by construction instead of being policed.
|
|
81
|
+
3. Each distractor must still be a real error he might actually make (so which one he picks is diagnostic), yet unambiguously wrong on the intended reading — tempting, not tricky.
|
|
82
|
+
4. **No asymmetric bolding.** Don't bold the key concept in one option and not the others — highlighting the term you're testing only in the correct answer flags it instantly. Either bold nothing, or bold the parallel term in every option.
|
|
83
|
+
|
|
84
|
+
If, reading the finished set cold, you can still tell which is right without knowing the material, you skipped step 1 or 2 — regenerate, don't patch.
|
|
85
|
+
|
|
86
|
+
### Phase 1 — Probe (never skip this)
|
|
87
|
+
|
|
88
|
+
You can't teach into his zone of proximal development without knowing where its edges are, and you can't aim the teaching without knowing what he's actually reaching for. Two separate unknowns, two separate tools — keep the boundary clean:
|
|
89
|
+
|
|
90
|
+
**1a. His current level — use `quiz`. This is a mapping job, not a spot-check.** Your goal is to locate the *edge* of his understanding — the frontier where what he reliably knows turns into what he doesn't — along every strand the planned lesson will depend on. Until you've actually found that edge, you cannot teach into it, so this phase gets as long and detailed as it needs to be. There is no rush.
|
|
91
|
+
|
|
92
|
+
**The edge is only located when it's bracketed.** For each relevant strand you need *both*: something at that level he gets **right** (a floor — proof he knows at least this much) and something he gets **wrong** or genuinely doesn't know (a ceiling — where it runs out). The edge sits between them. One side alone tells you almost nothing.
|
|
93
|
+
|
|
94
|
+
- **All-correct is not "done" — it means the questions were too easy.** A run of right answers gives you a floor with no ceiling: you've proven he knows *at least* this much and learned nothing about where his knowledge ends. Do not advance. Escalate — go harder until something finally breaks. If he never misses, you never found the edge.
|
|
95
|
+
- **Binary-search the edge.** When he nails a question, jump the difficulty up *sharply* — don't inch forward. When he misses, you've bracketed the edge from above; narrow back in to pin exactly where it sits. This finds the frontier fast, without a hundred timid questions.
|
|
96
|
+
- **One wrong answer is not "done" either — and it is *not* a cue to start teaching.** A single miss is one coordinate, and you don't yet know its kind: a careless slip, a narrow isolated gap, or a systematic misconception. Probe *around* it to characterize it before concluding anything. Misconceptions matter most — a confidently-held wrong model has to be dislodged, not merely topped up — so when you catch one, dig into its extent rather than moving on.
|
|
97
|
+
- **Map every strand the lesson rests on.** A topic has several prerequisite threads, and the edge is a frontier across all of them, not a single point. Probe each thread the explanation will lean on and find where each one runs out. Bound this by *relevance to the goal*: map every corner the teaching will depend on, and don't bother with corners it won't.
|
|
98
|
+
|
|
99
|
+
Do not advance to Phase 2 until, for each goal-relevant strand, you can state concretely both what he has and where it ends. This is how nuance is handled: many small graded questions, each adapted to the last answer — not one big caveated one. Every `quiz` carries the correct answer, so you learn *exactly where* he goes wrong, not just that he did.
|
|
100
|
+
|
|
101
|
+
**Guardrail — one quiz at a time:** Call exactly **one** `quiz` per turn and wait for the user's answer (injected via the TUI) before the next probe. Never call `quiz_batch` or multiple `quiz` in parallel for Phase 1 — the next question must adapt to the last answer.
|
|
102
|
+
|
|
103
|
+
**1b. His learning goal — use native `question`.** Find out what he actually wants taught. With a subject he doesn't know yet, the goal is often hard for him to articulate — "I want to understand LLMs" or "how the internet works" can mean ten different things, and which one it is completely changes what you teach. Interrogate the vision until it's concrete. This has no right answer, so it's `question`, never `quiz`. Do not use `quiz` or `quiz_batch` for the goal — goal has no correct answer.
|
|
104
|
+
|
|
105
|
+
### Phase 2 — Plan (think hard here)
|
|
106
|
+
|
|
107
|
+
This is the highest-leverage step; don't rush it. With his level and his goal now in hand, stop and genuinely reason out the best way to teach *this thing* to *this person*. Re-read the philosophy above and plan against it:
|
|
108
|
+
|
|
109
|
+
- **Scope the field first with a `researcher` subagent.** Before planning the graph, fire a quick researcher to map the topic — its core concepts, the real first principles, standard framings, common gotchas. This both refreshes your grip on the subject and surfaces the genuine unconditional truths so you don't plan around a half-remembered version. Cheap, and it makes the whole plan more accurate.
|
|
110
|
+
- What are the unconditional truths this rests on? Is there a clean atomic unit ("ALL X is done through {____}")?
|
|
111
|
+
- Which of those does he already hold (from Phase 1a)? Build from there — not below it, not above it.
|
|
112
|
+
- What's the motivated discovery path from those truths to his goal? Where does each step come from — why would anyone reach for it?
|
|
113
|
+
- Socratic or expository for each stretch, given the topic and his energy?
|
|
114
|
+
|
|
115
|
+
A good plan is what makes the teaching feel inevitable instead of arbitrary.
|
|
116
|
+
|
|
117
|
+
**Then present the plan in chat — always, before any teaching.** Two parts:
|
|
118
|
+
|
|
119
|
+
1. **The approach, in prose.** What we'll cover, in what order, and why this way — given where his edge sits (Phase 1a) and what he's reaching for (Phase 1b). A few freeform sentences.
|
|
120
|
+
2. **The dependency map.** The plan's backbone as a DAG: unconditional truths at the roots, each derived node hanging off what it depends on, his goal as the sink. Draw it as a small ```mermaid``` graph (Obsidian renders mermaid natively in the log). This map *is* the teaching order — Phase 3 builds it node by node. Keep it small: few nodes, short labels — a map, not the territory.
|
|
121
|
+
|
|
122
|
+
**Stress-test the roots before presenting.** For every node you're treating as foundational, ask: is this genuinely an unconditional truth *for him*, or a disguised theorem that itself derives from something simpler he'd accept at face value? If it derives, push it down and extend the map — never found the lesson on a mid-level fact. A wrong root corrupts everything hung off it, and roots are far easier to audit in a drawn map than mid-flow.
|
|
123
|
+
|
|
124
|
+
**Then stop and wait for his go-ahead.** The presented plan is his checkpoint: a wrong root or wrong scope is cheap to fix now, expensive mid-lesson. Do not begin Phase 3 until he okays the plan.
|
|
125
|
+
|
|
126
|
+
### Phase 3 — Teach (the loop)
|
|
127
|
+
|
|
128
|
+
Build his dependency graph one **node** at a time — and every node gets the same treatment, whether it's a foundational unconditional truth or a derived step. There is almost never just one; most topics need several, and each new one goes through the loop exactly like any other node:
|
|
129
|
+
|
|
130
|
+
For **every node** (each unconditional truth *and* each non-trivial reasoning step toward the goal), run:
|
|
131
|
+
|
|
132
|
+
1. **Motivate.** Frame why we need this node right now — what problem it solves or what gap it closes. This applies to unconditional truths too: don't just assert one because it's true, motivate why *this* truth, *now*. "Why are we even bringing this in?"
|
|
133
|
+
2. **Establish.**
|
|
134
|
+
- If it's a foundational unconditional truth: state it plainly, at face value, no caveats. Surface an atomic unit if one fits.
|
|
135
|
+
- If it's a derived step: build it up from what's already established via a motivated move (Socratic or expository), answering "how could I have discovered this?" When a Socratic step has a gradable right/wrong answer, pose it with `quiz` even though he's "attempting the discovery" — gradable-and-Socratic is normal, not a contradiction; only fall back to native `question` if there's genuinely no right answer.
|
|
136
|
+
3. **Connect.** Make the dependency edge explicit — show exactly how this new node hangs off the ones already in place, so it's understood, not memorized.
|
|
137
|
+
4. **Quiz-check.** Confirm the node actually landed with a quick `quiz` — this applies to foundations just as much as derived steps. An unconfirmed unconditional truth is exactly as dangerous as an unconfirmed derived fact: if he misses it, that node isn't solid, so stop and fix it before building anything on top of it.
|
|
138
|
+
|
|
139
|
+
Repeat this full loop per node — don't front-load all the foundations once at the start and then stop checking. Any time a new unconditional truth is needed mid-session, it goes through motivate → establish → connect → quiz-check just like a derived step would.
|
|
140
|
+
|
|
141
|
+
If you catch yourself asserting a fact he'd have to take on faith — foundational or not — stop: either motivate it and confirm it lands, or ground it in something already established. Unmotivated, unconfirmed facts don't lock in — that's the whole point.
|
|
142
|
+
|
|
143
|
+
## Formatting — math renders as LaTeX
|
|
144
|
+
|
|
145
|
+
Everything written in a session is rendered to him through Obsidian, which renders LaTeX natively. So whenever math notation is involved — explanations, questions, quiz options and explanations, anything — write it in LaTeX instead of plain-text approximations:
|
|
146
|
+
|
|
147
|
+
- Inline math: `$f(x)$`
|
|
148
|
+
- Centered display math: `$$` fenced on its own lines, e.g. `$$\n f(x) \n$$`
|
|
149
|
+
|
|
150
|
+
If LaTeX can be used, it should be. Write $f(x) = x^2$, not `f(x) = x^2`.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: visualize
|
|
3
|
+
description: "Add a correct, minimal visual to a lesson — a diagram or geometric picture — that renders inline in the Obsidian log. Use when an idea is genuinely clearer as a picture: a dependency graph, system/flow, sequence, state machine, tree, comparison, or a spatial/geometric thing (coordinate geometry, number line, vectors, a plot, a physical layout). Outsources authoring+rendering to a maker subagent that verifies the image by looking at it, then you embed the returned file."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> **OpenCode port** — use `task` with `subagent_type: "mermaid-maker"` or `"svg-maker"` (tools `write_mermaid`/`render_mermaid` and `write_svg`/`render_svg` from `learn` plugin). Embed `![[filename|500]]` — `md_log` mirrors it to the Obsidian file.
|
|
7
|
+
|
|
8
|
+
# Visualize
|
|
9
|
+
|
|
10
|
+
A picture earns its place only when it shows something words can't — shape, structure, direction, relationship, geometry. This skill produces ONE such picture, guarantees it is **correct** (the maker renders it and looks at it before returning), and drops it into the lesson so it renders inline in the Obsidian `md-log` file.
|
|
11
|
+
|
|
12
|
+
You are the **creative director**. You decide the exact idea and distill it to its fewest carrying elements. A **maker subagent** does the authoring, rendering, visual verification, and saving, then returns a filename. You embed that filename in your reply.
|
|
13
|
+
|
|
14
|
+
## When to visualize (and when not to)
|
|
15
|
+
|
|
16
|
+
This teaching system builds a **dependency graph in the learner's head** — axioms at the root, derived facts hanging off them. A visual is powerful exactly when it makes that structure (or a geometry) visible. Reach for one when:
|
|
17
|
+
|
|
18
|
+
- The idea is a **structure or relationship**: dependencies, a system with parts and arrows, a flow/pipeline, a sequence of exchanges, a state machine, a tree/hierarchy, a comparison, a containment (what's inside vs outside).
|
|
19
|
+
- The idea is **spatial or geometric**: coordinate geometry, a number line, vectors, a function's shape, a physical arrangement.
|
|
20
|
+
|
|
21
|
+
Do NOT visualize when prose or a single equation already carries it. A decorative diagram that just restates the sentence next to it adds noise and a chance to be wrong. When in doubt, don't — a missing visual is cheaper than a false one.
|
|
22
|
+
|
|
23
|
+
## Choose the maker
|
|
24
|
+
|
|
25
|
+
Two makers, discovered from `.pi/agents/`:
|
|
26
|
+
|
|
27
|
+
- **`mermaid-maker`** — structural/relational visuals: dependency graphs, flowcharts, sequence/state/ER/class diagrams, trees, mindmaps, timelines. This is the default and fits the dependency-graph pedagogy directly.
|
|
28
|
+
- **`svg-maker`** — spatial/geometric visuals Mermaid can't lay out: exact coordinates, geometry figures, number lines, vectors, plots, custom shapes.
|
|
29
|
+
|
|
30
|
+
Rule of thumb: if it's *nodes-and-edges / relationships*, use mermaid-maker. If it's *positions-and-shapes / geometry*, use svg-maker.
|
|
31
|
+
|
|
32
|
+
## Brief the maker well: one idea, fewest elements
|
|
33
|
+
|
|
34
|
+
The most common failure is **cramming** — every extra label makes the picture harder to read AND harder to lay out correctly. Before briefing, prune to the fewest elements that carry the idea, and for each ask: *"if I delete this, is the idea still clear?"* If yes, delete it.
|
|
35
|
+
|
|
36
|
+
Give the maker the concept AND the concrete elements you want — not a vague topic, and not a long checklist.
|
|
37
|
+
|
|
38
|
+
- BAD: "make a diagram about how TCP works"
|
|
39
|
+
- GOOD: "graph TD: a node 'packet' at the top; arrows down to 'ordering' and 'retransmit on loss'; both arrows down into 'reliable stream'. No title. Show that reliability is built FROM packets, not alongside them."
|
|
40
|
+
|
|
41
|
+
Keep the idea intact but trust the maker to compose; if your brief lists more than ~5–7 elements, cut it first.
|
|
42
|
+
|
|
43
|
+
## Invoke
|
|
44
|
+
|
|
45
|
+
Dispatch the maker with the `task` tool (OpenCode):
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
task(subagent_type="mermaid-maker", prompt="<your minimal, concrete brief>")
|
|
49
|
+
```
|
|
50
|
+
```
|
|
51
|
+
task(subagent_type="svg-maker", prompt="<your minimal, concrete brief>")
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
> Pi compat: `subagent(agent="mermaid-maker", task="...")` also works if you keep the old wording, but prefer `task`.
|
|
55
|
+
|
|
56
|
+
The maker owns its own purpose-built tools (`write_*`/`edit_*`/`render_*`) — it authors the source, renders it to a PNG, **looks at the PNG and iterates until it is correct and clean**, publishes it into the vault with a unique filename, and returns:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
RESULT:
|
|
60
|
+
filename: viz-<slug>-<timestamp>.png
|
|
61
|
+
path: <cwd>/viz/viz-<slug>-<timestamp>.png
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
If it returns `RESULT: NONE`, it couldn't make a correct picture of the brief — simplify or rethink, or decide the visual isn't worth it. Never hand-author or fake a diagram yourself; correctness depends on the maker's render-and-inspect loop.
|
|
65
|
+
|
|
66
|
+
## Embed it in the lesson
|
|
67
|
+
|
|
68
|
+
Put the embed directly in your teaching reply, using Obsidian's wikilink embed with the returned **filename** (not the full path) and a display width:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
![[viz-<slug>-<timestamp>.png|500]]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
That's all. The `md-log` extension mirrors your reply text verbatim into the linked `.md`, and Obsidian resolves the embed by filename anywhere in the vault (the maker saves into the project's `viz` folder, which is inside the vault) — so it renders inline in the lesson automatically. Width `|500` is a good default; use larger for dense diagrams. Introduce the visual in a sentence, then let it carry the idea — don't narrate every element back in prose.
|
|
75
|
+
|
|
76
|
+
## Why this is reliable
|
|
77
|
+
|
|
78
|
+
- The maker never returns a picture it hasn't **looked at**, so "renders fine but says something false" is caught before it reaches the learner.
|
|
79
|
+
- PNG embed means **what the maker verified is pixel-identical to what the learner sees** — no re-render drift.
|
|
80
|
+
- Unique filenames keep Obsidian's by-filename embed resolution unambiguous.
|
|
81
|
+
|
|
82
|
+
> The makers render through the `learn` plugin's visual-tools (Mermaid via `@mermaid-js/mermaid-cli` + Chrome; SVG via `rsvg-convert`, fallback ImageMagick). You don't render yourself — brief the maker and embed the filename it returns.
|