obsidian-llm-wiki-cli
August 21, 2026 · View on GitHub
Status: v0.1.0 released (2026-08-12) on npm as
karpathywiki-cli. Headless ingest CLI for the Karpathy LLM Wiki ecosystem. Runs the productionWikiEngine.ingestSourceagainst markdown on disk, with no Obsidian renderer and zeroobsidianimports. Lives outside the plugin repo so the Obsidian marketplace Bot stops flagging Node-CLI structural warnings.
# One command — no config required for known providers
npx karpathywiki-cli ingest --sources ./notes --wiki ./wiki \
--provider deepseek --key sk-... --model deepseek-chat
The karpathywiki-cli package installs the llm-wiki binary (npx karpathywiki-cli ... resolves to it). It reads markdown sources, extracts entities and concepts via an LLM, and writes structured wiki pages (entities/ + concepts/ folders) into your --wiki directory.
Install & run
# Any of these work (the package installs the `llm-wiki` bin):
npx karpathywiki-cli ingest --sources <path> --wiki <path> --provider openai --key sk-...
# or install once:
npm install -g karpathywiki-cli
llm-wiki ingest --sources <path> --wiki <path>
npx llm-wiki does NOT reach this package. npx resolves the argument as an npm package name first, and llm-wiki is already taken on the registry by an unrelated project (so npx llm-wiki installs that third-party package). This package publishes as karpathywiki-cli, which then provides the llm-wiki binary.
Flags
Usage: llm-wiki <command> [options]
Commands:
ingest Ingest sources -> wiki
lint Run wiki health checks (Phase 1.6 placeholder)
--help Show help
--version Show version
ingest options:
--sources <path> source folder, single .md file, or repeated mixed list
(--sources A.md --sources B.md --sources folder/)
--wiki <path> wiki output folder (required; absolute or relative to cwd).
Generated pages land directly under it: entities/ + concepts/
--config <path> path to a settings.json (optional)
--dry-run list files only — never calls the LLM
--provider <id> one-off LLM provider override
--key <key> one-off API key override
--baseurl <url> one-off base URL override (custom endpoints)
--model <model> one-off model override
Config precedence
flags > LLM_WIKI_API_KEY env > --config file > defaults
- Flags are the one-off path — run a single ingest without writing any config.
LLM_WIKI_API_KEYenv var is the script-friendly channel for secrets.--config settings.jsonis the durable path (reuses the plugin'sLLMWikiSettingsJSON shape).- The four override flags mirror the settings fields one-to-one; before any LLM traffic the CLI runs a preflight and prints a copy-pasteable guidance block (exact flag forms + a
settings.jsonexample + the supported-provider list) when the config is incomplete.
Supported providers (12 known — no manual baseUrl needed)
anthropic, openai, gemini, openrouter, deepseek, minimax, kimi, glm, ollama, lmstudio — plus two custom-endpoint interfaces that require a baseUrl: openai-compat (aliases: openai-custom) and anthropic-compatible (alias: anthropic-custom).
Local-only providers (Ollama / LMStudio) accept an empty apiKey. openai-codex and bedrock-* are queued for v0.2.0.
How it relates to the main repo
main repo (green-dalii/obsidian-llm-wiki) | this repo (obsidian-llm-wiki-cli) | |
|---|---|---|
| Holds | The Obsidian plugin (main.js + manifest.json + styles.css) | The headless ingest CLI (karpathywiki-cli on npm, llm-wiki bin) |
| License | Apache-2.0 | Apache-2.0 |
Source of WikiEngine / SchemaManager / prompts / i18n | Authoritative | Borrows via copy (Phase 2 CI sync workflow) |
| Source of CLI flag surface / parser tests | Migrated here at Phase 4 | Authoritative |
| What the user runs | obsidian-llm-wiki plugin in Obsidian (unchanged through v1.27.0) | npx karpathywiki-cli ingest --sources <path> --wiki <path> |
Why a separate repo
The Obsidian marketplace review bot lints the whole repo .ts tree and reports structural Warnings on any Node CLI colocated with an Obsidian plugin (~60 Warnings on the original tools/llm-wiki-cli/). The CLI's console.log output interface, static node: builtin imports, globalThis shim, and fetch-backed requestUrl are not fixable without destroying what the CLI is. The only durable answer is to live outside the Bot's scan scope AND to remove every obsidian import from the CLI source.
The v2.0 plan does both: independent repo, zero obsidian imports, files migrated as copies (not as a submodule), with a per-file sync header tracking verbatim vs adapted status. See SPEC.md for the full architecture and decision log.
Development
git clone https://github.com/green-dalii/obsidian-llm-wiki-cli.git
cd obsidian-llm-wiki-cli
pnpm install
# Gate 1: lint + typecheck + test + build
pnpm lint && pnpm typecheck && pnpm test && pnpm build
# Run the local bundle (same as the published bin)
node dist/bin/llm-wiki.mjs --help
node dist/bin/llm-wiki.mjs ingest --sources <path> --wiki <path> --dry-run
The CLI streams NDJSON events on stdout (start / file / file-result / error / done), so it can be piped into a line-by-line consumer. Diagnostics go to stderr; enable parse-trace diagnostics with LLM_WIKI_DEBUG=1.
Layout
obsidian-llm-wiki-cli/
├── README.md
├── CHANGELOG.md # Keep a Changelog format
├── ROADMAP.md # phase status + resolved open questions
├── SPEC.md # v2.0 architecture
├── docs/archive/ # historical audit reports (e.g. PHASE-1.7-REPORT.md)
├── LICENSE # Apache-2.0 (matches main repo)
├── eslint.config.mjs # ESLint v9 flat config
├── package.json # name: "karpathywiki-cli"
├── tsconfig.json # strict, no extends, ES2022/ESNext/Bundler
├── scripts/
│ └── bundle.mjs # esbuild → dist/bin/llm-wiki.mjs
├── bin/
│ └── llm-wiki.ts # entry point
└── src/
├── cli.ts # arg parsing + dispatch
├── orchestration.ts # runIngest: analyzeSource → generatePage → write
├── settings.ts # loadSettings (JSON + migrations)
├── vault-reader.ts # FsVaultReader
├── vault-writer.ts # FsVaultWriter
├── system-prompts.ts # system prompt builder
├── types.ts # LLMWikiSettings + shared types
├── llm-client/ # factory + 12 known providers + config validator
│ ├── factory.ts
│ ├── config.ts # findConfigProblem + mergeLLMSettings
│ ├── known-providers.ts # provider registry
│ └── provider-*.ts # per-protocol clients
├── core/ # Layer 1: pure algorithms (58 files)
├── ingest/ # source-analyzer + page-generator
├── prompts/ # prompt templates (ingestion, generation, lint, ...)
└── __tests__/ # vitest suite (182 tests)
Migration window
Phase 1 (done) — boot the sibling repo; v0.1.0 published to npm. User-facing pnpm llm-wiki in the main repo keeps working unchanged.
Phase 2 (1–3 months after v0.1) — dual-repo coexistence. New repo absorbs follow-on PRs (e.g. #408, #409); sync workflow goes live; users can pick either install path.
Phase 3 (v1.27.0 MINOR) — DEPRECATION marker on pnpm llm-wiki; 11 READMEs in main repo add "preferred migration to npm package" guidance.
Phase 4 (v1.27.0 MINOR, advanced from the original v1.28.0+ plan by upstream #507) — Demote, not Delete: tools/llm-wiki-cli/ is kept inside the main repo as a dev-only test harness (rewritten to directly reference ../../src/; file header marked UPSTREAM DEV-ONLY TEST WRAPPER). bin.llm-wiki / scripts.ingest are dropped from package.json because the production CLI is now karpathywiki-cli on npm. CHANGELOG BREAKING marker (production entry-point relocation only).
For phase status, see ROADMAP.md. For per-change history, see CHANGELOG.md.
License
Apache License 2.0 — see LICENSE. Same as the main repo. Vendor-borrowed code is Apache-2.0 throughout.
Cross-references
- Main repo: https://github.com/green-dalii/obsidian-llm-wiki
- npm package: https://www.npmjs.com/package/karpathywiki-cli
- Architecture: SPEC.md
- Roadmap: ROADMAP.md
- Changelog: CHANGELOG.md
- v1.26.0 CLI implementation (PR #372): https://github.com/green-dalii/obsidian-llm-wiki/pull/372