sdtk-brain-kit
v0.4.2
Published
Standalone local-first second-brain vault CLI: immutable raw/ sources compiled into a markdown wiki/ knowledge layer, maintained by rails (ingest, compile, lint, search, graph viewer) while your agent is the knowledge engine.
Readme
sdtk-brain-kit
sdtk-brain is a standalone, local-first second-brain vault CLI. One job:
turn a folder of immutable sources (raw/) into a compiled markdown knowledge
layer (wiki/) that you — and your AI agent — can search, lint, and browse as
a graph. The agent reading the vault (per its CLAUDE.md contract) is the
knowledge engine; this CLI provides the deterministic rails only.
Package version in this source snapshot: 0.4.1
CLI command: sdtk-brain
Standalone by design: not part of the sdtk-kit umbrella, installs no agent
skills, makes no network calls, needs no entitlement. It shares its graph
builder and viewer with SDTK-WIKI at build time (byte-identity is CI-guarded).
Install
npm install -g sdtk-brain-kit
sdtk-brain --versionQuick start
mkdir my-vault && cd my-vault
sdtk-brain init # raw/ + wiki/ + workspace/ + CLAUDE.md
cp ~/some-article.md raw/inbox/
sdtk-brain ingest raw/inbox
sdtk-brain compile --mode safe # source-bounded preview: sources + canonical repositories
sdtk-brain compile --mode safe --apply
# Use --include-references only when the expanded semantic graph is intended.
# Historical generated dashboard repair is explicit and hash-pinned:
# sdtk-brain compile --mode safe --repair-source-bounded
# sdtk-brain compile --mode safe --repair-source-bounded --apply
sdtk-brain search "topic"
sdtk-brain open # build the graph viewer (opens viewer.html locally)
sdtk-brain serve --print-url # or serve it over local HTTP
# Already have a vault from before this CLI?
sdtk-brain adopt --apply # onboard it without rewriting your .gitignoreCommands
sdtk-brain init [--vault <path>] scaffold a vault (refuses non-empty non-vault targets)
--update-gitignore append a `.brain/` entry to an existing .gitignore (idempotent)
sdtk-brain adopt [--apply] onboard an EXISTING vault: append `.brain/` to .gitignore
--profile legacy|strict (append-only) + write .brain/adoption.json. Preview without --apply.
sdtk-brain ingest <file|dir> semantic extraction over raw sources (report-first)
sdtk-brain compile --mode safe [--apply] [--include-references] compile extraction into wiki/ pages
--include-references opt in to linked repositories, semantic analysis, and dashboards
--repair-source-bounded [--apply] repair only two hash-pinned historical generated dashboards
--skip-conflicts (with ordinary --apply) apply only the non-conflicting remainder;
drifted pages stay untouched + reported
sdtk-brain search [--json] "<q>" deterministic search over the vault wiki
sdtk-brain lint [--profile legacy] [--json] report-first hygiene (orphans, links, stale, contradictions)
sdtk-brain maintain --mode safe lint + discover + compile preview in one pass
sdtk-brain discover --plan gap-analysis plan
sdtk-brain enrich --source github --mode review review-only external repo metadata
sdtk-brain open [--no-open] build the graph viewer (opens a local file)
sdtk-brain serve [--bind 127.0.0.1] [--port 4785] [--print-url] serve the built viewer over local HTTP
sdtk-brain status [--json] vault status: adoption mode + graph freshnessAdopting an existing vault
A vault that already existed before this CLI keeps its own .gitignore and its
own wiki schema. init never rewrites an existing .gitignore — it only
warns when the generated .brain/ machine-state tree would be left untracked.
Run sdtk-brain adopt to onboard it:
sdtk-brain adopt # preview: shows the .gitignore + marker changes
sdtk-brain adopt --apply # append `.brain/` once (existing lines preserved),
# write .brain/adoption.jsonadopt never touches raw/ or wiki/ content, and is idempotent.
Lint profiles
- strict (default when the vault looks current) — every page is held to the full SDTK-BRAIN frontmatter schema.
- legacy (default when adoption records it, or when most pages predate the
schema) — schema-migration debt (
missing aliases/tags/source_refs, missing sections) is reported under a "Migration required" heading and excluded from the defect count. Strict checks are not disabled: broken links, contradictions, mojibake, duplicates and thin pages are still reported.
Lint reads two content stores and tags every finding with its corpus:
wiki (the canonical <vault>/wiki) and atlas (the generated .brain/pages
mirror). The summary carries per-corpus counts; legacy mode breaks findings into
canonical wiki defects, atlas-derived defects, and migration debt.
External / blob: / data: / mailto: URLs and fragment-only or query-only
links are never counted as broken internal links.
Each run writes an immutable report named
.brain/reports/lint-report-<UTC-timestamp>-<profile>.md — a legacy run and a
strict run on the same day no longer overwrite one file.
sdtk-brain lint --json prints a machine-readable summary (total_findings /
defect_findings / migration_findings / corpus_breakdown / content_roots
/ per-category by_corpus).
Serving the viewer
open builds .brain/graph/ and opens viewer.html as a local file. When you
need a real URL (remote shell, container, sharing on localhost), use serve:
sdtk-brain serve --print-url # -> http://127.0.0.1:4785/viewer.html
sdtk-brain serve --bind 127.0.0.1 --port 4785Loopback by default, static files only, path-jailed to .brain/graph/.
No tunnelling — a non-loopback --bind is accepted but warns loudly that it
exposes the vault contents on the network.
There is deliberately no ask command: open the vault in your agent (or
Obsidian) and ask there — grounded synthesis is the agent's job.
Vault layout
raw/ immutable sources (inbox, articles, papers, repos, notes, meetings, archive)
wiki/ compiled knowledge (sources, concepts, entities, comparisons, syntheses, …)
workspace/ scratch
CLAUDE.md the agent operating contract
.brain/ machine state (reports, graph, provenance) — never edit by handBoundaries
- 100% local: no LLM, no network, no telemetry, no entitlement
- never mutates
raw/content;.brain/is CLI-owned machine state - a vault is a standalone folder —
initrefuses non-empty non-vault targets
