@djolex999/vir-cli 0.2.2 → 0.2.3

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/CLAUDE.md +0 -152
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djolex999/vir-cli",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Distills Claude Code sessions into a compounding knowledge vault",
5
5
  "author": "Djordje Marković <djordje@growthq.rs>",
6
6
  "license": "MIT",
package/CLAUDE.md DELETED
@@ -1,152 +0,0 @@
1
- # vir
2
-
3
- Local macOS daemon that distills Claude Code session transcripts into an
4
- Obsidian vault.
5
-
6
- Published to npm as `@djolex999/vir-cli` (scoped). Install:
7
- `npm install -g @djolex999/vir-cli`. Repo: https://github.com/djolex999/vir. Reads `~/.claude/projects/**/*.jsonl`, filters by heuristic,
8
- classifies with Haiku, extracts durable knowledge with Sonnet, writes typed
9
- notes to the vault, maintains an index, and syncs back into CLAUDE.md files.
10
-
11
- ## Stack
12
-
13
- - Node.js ≥ 20, TypeScript strict (`noImplicitAny`, `noUncheckedIndexedAccess`)
14
- - `commander` for CLI, `chalk` for output, `zod` for config validation
15
- - `better-sqlite3` for state (synchronous — no async complexity)
16
- - `@anthropic-ai/sdk` for the Anthropic path; native `fetch` for the Kie path
17
- - macOS `launchd` for the daemon, `osascript` for notifications
18
-
19
- ## Structure
20
-
21
- ```
22
- src/
23
- cli.ts # commander entry — every subcommand wired here
24
- config.ts # ~/.vir/config.json schema + helpers
25
- pipeline/
26
- run.ts # orchestrator (scan → filter → scrub → distill → write)
27
- scanner.ts # walk ~/.claude/projects, SHA-256 each .jsonl
28
- parser.ts # extract assistant/user text, tool calls, files touched
29
- filter.ts # heuristic scorer (length, tools, files, signal words)
30
- scrubber.ts # strip API keys, bearer tokens, absolute paths, emails
31
- distiller.ts # callLLM helper, Haiku classify + Sonnet extract,
32
- # withRateLimitRetry, buildAnthropicClient,
33
- # normalizeModelName
34
- writer.ts # frontmatter + body, wikilink injection, index/log
35
- summarizer.ts # per-project knowledge summaries
36
- types.ts # ParsedSession, Classification, DistilledNote, Category
37
- search/
38
- retriever.ts # unified async search: embeddings → TF-IDF fallback
39
- embedder.ts # Ollama integration (nomic-embed-text), cosine sim
40
- synthesizer.ts # Claude synthesis for `vir query`
41
- lint/
42
- linter.ts # orphans, staleness, contradictions
43
- dedupe/
44
- detector.ts # candidate pairs + LLM judgment
45
- merger.ts # archive / keep / Sonnet-merge
46
- claude/
47
- updater.ts # VIR:START / VIR:END block management
48
- state/
49
- db.ts # better-sqlite3, idempotent migrations
50
- daemon/
51
- launchd.ts # plist render + load/unload via spawnSync('launchctl')
52
- ui/
53
- display.ts # the ONE place console.log lives — palette, glyphs,
54
- # header(), divider(), box(), spinner(), summary(),
55
- # wrap(), sourceRow(), categoryRow()
56
- ```
57
-
58
- ## Key conventions
59
-
60
- - **Path expansion.** All paths from config (`vaultPath`, `claudeProjectsDir`)
61
- must run through `expandHome()` (or `os.homedir()` directly) before use.
62
- Never assume `~/` works in `fs.*`.
63
- - **Per-session try/catch.** The daemon must never die on a single bad
64
- transcript. `pipeline/run.ts` wraps every session iteration and records the
65
- error in the DB so it doesn't keep retrying.
66
- - **Provider routing.**
67
- - `provider: 'anthropic'` → `@anthropic-ai/sdk` (`buildAnthropicClient`).
68
- - `provider: 'kie'` → native `fetch` to `https://api.kie.ai/claude/v1/messages`
69
- with `Authorization: Bearer <kieApiKey>`. The SDK is **not** used for Kie
70
- even with a `baseURL` override — its `x-api-key` header conflicts.
71
- - Both flow through `callLLM(config, client, opts)`.
72
- - **Model names.** `normalizeModelName(model, provider)` collapses any model
73
- that *starts with* a Kie canonical id (`claude-haiku-4-5`,
74
- `claude-sonnet-4-6`) back to the bare id. Fallback strips trailing
75
- `-YYYYMMDD`. Anthropic path passes through untouched.
76
- - **Rate limits.** Every LLM call is wrapped in `withRateLimitRetry()` — three
77
- attempts with `60s / 120s / 240s` backoff on `429` (Anthropic SDK
78
- `APIError.status === 429` and our `HttpError.status === 429` both detected).
79
- Sessions are processed sequentially with a `2s` delay after each successful
80
- distill.
81
- - **State is the source of truth.** `~/.vir/vir.db` records every session by
82
- path with its SHA-256 hash. Reruns are idempotent; a session is only
83
- re-distilled if its file content changes. Migrations are additive only
84
- (`PRAGMA table_info(sessions)` + `ALTER TABLE ADD COLUMN`).
85
- - **VIR:START / VIR:END markers are sacred.** `sync-claude` only mutates bytes
86
- between those markers. When a CLAUDE.md has no block, the new one is
87
- appended; the rest of the file is preserved verbatim.
88
- - **No comments explaining obvious things.** Comment WHY a non-obvious
89
- invariant exists — never WHAT the code does.
90
- - **All user-facing output goes through `ui/display.ts`.** Other modules
91
- must not call `console.log` directly. The pipeline's `fileLog()` writes
92
- to `~/.vir/daemon.log` in plain text regardless of UI mode; the
93
- display module renders only when `!opts.quiet`.
94
- - **Ollama is best-effort.** `writer.maybeEmbed()` and the search path
95
- both probe via `isOllamaAvailableCached()` and silently fall back
96
- (TF-IDF for query; no-op for writer). An embedding failure must never
97
- fail a write.
98
- - **Cost prompts respect intent.** `--yes`, `--daemon`, and
99
- `--rewrite-only` all skip the > 20 new-session confirmation. The
100
- daemon path *never* prompts (it has no tty).
101
- - **`vir init` is an @inquirer/* wizard.** Arrow-key `select` for
102
- provider and models, `input` with `validate` for keys/numbers,
103
- `confirm` for the "create missing path?" flow. Don't fall back to
104
- raw readline here — the rest of the file already imports it for
105
- dedupe/sync-claude/cost prompts, but the init UX is the wizard.
106
- - **`vir run` prints a preflight line.** `N files found · M cached · K
107
- new` shows after the scan in dim text, and the same triple goes to
108
- the daemon log. Diagnoses "fresh DB looks stale" misconfigurations
109
- in one line.
110
-
111
- ## Commands
112
-
113
- ```
114
- vir init # interactive setup
115
- vir run # one pass (used by daemon)
116
- vir run --full # ignore state cache, re-process everything
117
- vir run --rewrite-only # re-render notes from stored content
118
- # (no scan, no LLM, free)
119
- vir run --yes # skip the > 20 sessions cost prompt
120
- vir schedule install # write + load ~/Library/LaunchAgents plist
121
- vir schedule uninstall # unload + remove plist
122
- vir status # daemon state + knowledge base breakdown
123
- vir query "<question>" # embeddings (Ollama) → TF-IDF fallback
124
- # → Claude synthesis
125
- vir embed # generate Ollama embeddings for notes
126
- vir embed --force # regenerate all embeddings
127
- vir summarize <project> # generate per-project summary
128
- vir summarize --all # all projects with notes
129
- vir lint # orphans + stale + contradictions
130
- vir lint --orphans # orphans only (free)
131
- vir lint --stale # staleness only (free)
132
- vir lint --contradictions # contradictions only (Haiku tokens)
133
- vir dedupe # interactive duplicate review + merge
134
- vir sync-claude # diff then confirm CLAUDE.md updates
135
- vir sync-claude --dry-run # diff only, never write
136
- vir sync-claude --force # apply without confirmation
137
- vir sync-claude <project> # specific project only
138
- vir sync-claude --global # only ~/.claude/CLAUDE.md
139
- ```
140
-
141
- ## File locations
142
-
143
- - Config: `~/.vir/config.json`
144
- - State: `~/.vir/vir.db` (better-sqlite3 with WAL). A one-shot rename in
145
- `StateDb`'s constructor moves the pre-rename `~/.vir/state.db` over to
146
- `~/.vir/vir.db` if it's still around — preserves cache, hides the
147
- history of the doc/code mismatch.
148
- - Daemon log: `~/.vir/daemon.log`
149
- - launchd plist: `~/Library/LaunchAgents/lab.growthq.vir.plist`
150
- - Vault notes: `<vaultPath>/<outputDir>/{patterns,gotchas,decisions,tools,projects,archived}/`
151
- - Vault index: `<vaultPath>/<outputDir>/index.md`
152
- - Vault run log: `<vaultPath>/<outputDir>/log.md`