stellavault 0.4.4 → 0.4.5

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/README.md CHANGED
@@ -1,27 +1,27 @@
1
1
  # Stellavault
2
2
 
3
- > **Self-compiling knowledge MCP server** ingest anything, auto-organize into Zettelkasten wiki, and let Claude access your entire knowledge base.
3
+ > **Drop anything. It compiles itself into knowledge.** Claude remembers everything you know.
4
4
 
5
- Drop a PDF, paste a YouTube link, type a thought Stellavault compiles it into structured knowledge, connects the dots, and gives your AI agent full access through 21 MCP tools.
5
+ Self-compiling Zettelkasten MCP server. Ingest PDFs, YouTube, documentsauto-organized into linked wiki. Claude accesses your entire knowledge base. **Your vault files are never modified.**
6
6
 
7
7
  <p align="center">
8
- <img src="images/screenshots/graph-dark-full.png" alt="3D Knowledge Graph" width="800" />
9
- <br><em>Your vault as a neural network. Clusters form constellations.</em>
8
+ <img src="images/screenshots/graph-main-2.png" alt="3D Knowledge Graph" width="800" />
9
+ <br><em>Your vault as a neural network. Local-first, no cloud required.</em>
10
10
  </p>
11
11
 
12
12
  ## Two Core Ideas
13
13
 
14
- **1. "Drop it and forget it"** (Karpathy's Self-Compiling Knowledge)
14
+ **1. "Drop it and forget it"** (Inspired by Karpathy's Self-Compiling Knowledge)
15
15
  ```
16
16
  Any input → auto-classify → raw/ → compile → wiki → connected knowledge
17
17
  ```
18
- PDF, DOCX, YouTube, URL, text — everything goes through the same pipeline. You never manually organize.
18
+ PDF, DOCX, PPTX, XLSX, YouTube (with transcript), URL, text — everything goes through the same pipeline. You never manually organize.
19
19
 
20
- **2. "Claude knows what you know"** (MCP Integration)
20
+ **2. "Claude remembers what you know"** (MCP Integration)
21
21
  ```bash
22
22
  claude mcp add stellavault -- stellavault serve
23
23
  ```
24
- 21 MCP tools give Claude direct access to search, ask, draft, and navigate your entire knowledge base.
24
+ Claude searches, asks, drafts from your vault directly. Local-first no data leaves your machine.
25
25
 
26
26
  ## 5-Minute Setup
27
27
 
@@ -200,19 +200,28 @@ stellavault autopilot # Full cycle: inbox → compile
200
200
  | **Capture** | ingest (URL/YouTube/PDF/DOCX/PPTX/XLSX/text), fleeting, web drag & drop, mobile PWA |
201
201
  | **Organize** | Zettelkasten 3-stage, auto index codes, wikilink auto-connect, configurable folders |
202
202
  | **Distill** | compile (raw→wiki), lint (health score), gaps, contradictions, duplicates |
203
- | **Express** | draft (blog/report/outline), --ai (Claude API), MCP generate-draft (free) |
204
- | **Memory** | FSRS decay tracking, session-save (daily logs), flush (logs→wiki), compounding loop |
205
- | **Search** | hybrid (BM25+vector+RRF), multilingual (50+ langs), ask Q&A |
206
- | **Visualize** | 3D graph, constellation, heatmap, timeline, decay overlay, dark/light |
207
- | **AI Integration** | 21 MCP tools, Claude Code hooks, Anthropic SDK, generate-draft |
208
- | **CLI** | 39+ commands, `sv` alias |
203
+ | **Express** | draft (blog/report/outline/instagram/thread/script), blueprint, --ai, MCP generate-draft |
204
+ | **Memory** | FSRS decay, session-save, flush, compounding loop, ADR templates |
205
+ | **Search** | hybrid (BM25+vector+RRF), multilingual 50+, ask Q&A, quotes mode |
206
+ | **Visualize** | 3D graph, heatmap, timeline, right-click context menu, TipTap WYSIWYG editor |
207
+ | **AI Integration** | 21 MCP tools, Claude Code hooks, Anthropic SDK |
208
+ | **Security** | DOMPurify, YAML sanitize, 50MB guard, SSRF protection |
209
+ | **CLI** | 40+ commands, `sv` alias, batch ingest |
210
+
211
+ ## Security
212
+
213
+ Your vault files are never modified. Stellavault is local-first — no data leaves your machine unless you explicitly use `--ai` (Anthropic API).
214
+
215
+ See [SECURITY.md](SECURITY.md) for full details.
209
216
 
210
217
  ## License
211
218
 
212
- MIT
219
+ MIT — full source code available for audit.
213
220
 
214
221
  ## Links
215
222
 
223
+ - [Landing Page](https://evanciel.github.io/stellavault/)
216
224
  - [Obsidian Plugin](https://github.com/Evanciel/stellavault-obsidian)
217
225
  - [npm](https://www.npmjs.com/package/stellavault)
218
226
  - [GitHub Releases](https://github.com/Evanciel/stellavault/releases)
227
+ - [Security Policy](SECURITY.md)
package/SECURITY.md ADDED
@@ -0,0 +1,50 @@
1
+ # Security Policy
2
+
3
+ ## Data Access
4
+
5
+ Stellavault is **local-first**. Your knowledge stays on your machine.
6
+
7
+ ### What Stellavault reads
8
+ - `.md`, `.txt`, `.pdf`, `.docx`, `.pptx`, `.xlsx` files **inside your configured vault path only**
9
+ - Files are read to build a search index (SQLite-vec database stored in `~/.stellavault/`)
10
+ - **Vault original files are never modified by the indexer** — Stellavault creates its own files in `raw/`, `_wiki/`, `_drafts/` folders
11
+
12
+ ### When network requests occur
13
+ - **YouTube ingest**: fetches video metadata + captions from youtube.com (via yt-dlp)
14
+ - **URL ingest**: fetches the target URL to extract text
15
+ - **`stellavault draft --ai`**: sends vault excerpts to Anthropic API (requires explicit `ANTHROPIC_API_KEY` env var — opt-in only)
16
+ - **MCP serve**: local stdio/HTTP only — no external connections
17
+ - **Embedding model**: downloaded once from Hugging Face on first `stellavault index`, then cached locally
18
+
19
+ ### What never leaves your machine
20
+ - Your vault files
21
+ - Your search index database
22
+ - Your session logs and daily logs
23
+ - Your draft outputs
24
+ - All MCP tool responses
25
+
26
+ ## Vault Safety
27
+
28
+ - **Read-only default**: The search indexer reads files but does not modify them
29
+ - **New files only**: `ingest`, `session-save`, `compile`, `draft` create new `.md` files — they never overwrite existing vault notes
30
+ - **Edit is explicit**: The web UI edit feature and `PUT /api/document` require deliberate user action
31
+ - **Path traversal protection**: All file operations validate paths stay within vault root
32
+ - **Configurable folders**: `raw/`, `_wiki/`, `_literature/` names can be changed in `.stellavault.json`
33
+
34
+ ## Input Sanitization
35
+
36
+ - **DOMPurify**: All markdown rendered in the web UI is sanitized against XSS
37
+ - **YAML sanitization**: Frontmatter values are escaped to prevent injection
38
+ - **File size limit**: 50MB max for binary file extraction
39
+ - **URL validation**: Image URLs restricted to `https://` scheme
40
+ - **SSRF protection**: Private/local IP addresses blocked for URL ingest
41
+
42
+ ## Reporting Vulnerabilities
43
+
44
+ Please report security issues to: https://github.com/Evanciel/stellavault/issues (label: security)
45
+
46
+ Or email: [create a security@stellavault.dev when domain is registered]
47
+
48
+ ## License
49
+
50
+ MIT — full source code is available for audit at https://github.com/Evanciel/stellavault
package/index.html CHANGED
@@ -231,7 +231,7 @@ footer{padding:60px 0;text-align:center}
231
231
  <section class="hero">
232
232
  <div class="graph-visual" id="graphVisual"></div>
233
233
  <div class="hero-inner container">
234
- <div class="hero-badge">open source <span class="sep">&#9679;</span> local-first <span class="sep">&#9679;</span> MIT license</div>
234
+ <div class="hero-badge">local-first <span class="sep">&#9679;</span> vault files never modified <span class="sep">&#9679;</span> MIT</div>
235
235
  <h1>Drop anything.<br>It <em>compiles itself</em><br>into knowledge.</h1>
236
236
  <p class="hero-sub">Self-compiling Zettelkasten MCP server. Ingest PDFs, YouTube, documents&mdash;auto-organized into linked wiki. Claude accesses your entire knowledge base through 21 MCP tools.</p>
237
237
  <div class="hero-cta">
@@ -366,8 +366,8 @@ footer{padding:60px 0;text-align:center}
366
366
  <section class="s-mcp">
367
367
  <div class="container">
368
368
  <div class="section-label reveal">Claude Integration</div>
369
- <h2 class="section-title reveal">21 MCP tools. Claude knows<br>everything you know.</h2>
370
- <p class="section-desc reveal">One command connects your vault to Claude Code. No API key needed.</p>
369
+ <h2 class="section-title reveal">Claude remembers<br>everything you know.</h2>
370
+ <p class="section-desc reveal">One command connects your vault. Claude searches, asks, and drafts from your knowledge. Local-first, no data leaves your machine.</p>
371
371
  <p class="section-desc reveal">One command connects your vault to Claude Code. No API key needed.</p>
372
372
  <div class="mcp-connect reveal"><span class="prompt">$</span> <code>claude mcp add stellavault -- stellavault serve</code></div>
373
373
  <div class="mcp-grid reveal">
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "stellavault",
3
- "version": "0.4.4",
4
- "description": "Self-compiling knowledge MCP server ingest anything, auto-organize into Zettelkasten wiki, search with AI, and let Claude access your entire knowledge base.",
3
+ "version": "0.4.5",
4
+ "description": "Drop anything. It compiles itself into knowledge. Claude remembers everything you know. Local-first MCP server, vault files never modified.",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/Evanciel/stellavault"
@@ -26,7 +26,7 @@ export async function ingestCommand(input, options) {
26
26
  const progress = `[${i + 1}/${files.length}]`;
27
27
  process.stderr.write(`\r${chalk.dim(progress)} ${name}...`);
28
28
  try {
29
- await ingestCommand(file, { ...options, title: undefined });
29
+ await ingestSingleFile(file, options);
30
30
  success++;
31
31
  }
32
32
  catch (err) {
@@ -42,7 +42,14 @@ export async function ingestCommand(input, options) {
42
42
  }
43
43
  return;
44
44
  }
45
- const config = loadConfig();
45
+ await ingestSingleFile(input, options);
46
+ }
47
+ /** 캐시된 config (배치 시 반복 로드 방지) */
48
+ let _configCache = null;
49
+ function getConfig() { return _configCache ?? (_configCache = loadConfig()); }
50
+ /** 단일 파일/URL/텍스트 인제스트 (배치에서 재사용) */
51
+ async function ingestSingleFile(input, options) {
52
+ const config = getConfig();
46
53
  const tags = options.tags?.split(',').map(t => t.trim()) ?? [];
47
54
  const stage = (options.stage ?? 'fleeting');
48
55
  // 입력 타입 감지
@@ -91,8 +98,8 @@ export async function ingestCommand(input, options) {
91
98
  // 일반 URL: HTML → 텍스트 변환
92
99
  let content = input + '\n';
93
100
  try {
94
- const resp = await fetch(input);
95
- const html = await resp.text();
101
+ const resp = await fetch(input, { signal: AbortSignal.timeout(15000) });
102
+ const html = (await resp.text()).slice(0, 500000); // 500KB max
96
103
  const text = html
97
104
  .replace(/<script[\s\S]*?<\/script>/gi, '')
98
105
  .replace(/<style[\s\S]*?<\/style>/gi, '')
@@ -68,7 +68,7 @@ export function generateDraft(vaultPath, options = {}, folders = DEFAULT_FOLDERS
68
68
  bpLines.push(`---\n*Generated by \`stellavault draft --blueprint\` at ${new Date().toISOString()}*`);
69
69
  body = bpLines.join('\n');
70
70
  }
71
- else
71
+ else {
72
72
  switch (format) {
73
73
  case 'outline':
74
74
  body = generateOutline(draftTitle, topConcepts, filteredDocs);
@@ -90,6 +90,7 @@ export function generateDraft(vaultPath, options = {}, folders = DEFAULT_FOLDERS
90
90
  body = generateBlog(draftTitle, topConcepts, filteredDocs);
91
91
  break;
92
92
  }
93
+ } // end else (non-blueprint)
93
94
  const wordCount = body.split(/\s+/).filter(Boolean).length;
94
95
  // _drafts/ 폴더에 저장
95
96
  const draftsDir = resolve(vaultPath, '_drafts');
@@ -95,7 +95,9 @@ export function ingest(vaultPath, input, folders = DEFAULT_FOLDERS) {
95
95
  compileWiki(rawDir, wikiDir);
96
96
  }
97
97
  }
98
- catch { /* compile 실패해도 ingest 성공 */ }
98
+ catch (err) {
99
+ console.warn('[ingest] Auto-compile skipped:', err instanceof Error ? err.message : err);
100
+ }
99
101
  return {
100
102
  savedTo: filePath,
101
103
  stage: autoStage,