stellavault 0.4.4 → 0.5.0
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 +52 -16
- package/SECURITY.md +50 -0
- package/dist/stellavault.js +8968 -0
- package/package.json +70 -33
- package/.env.example +0 -12
- package/CHANGELOG.md +0 -106
- package/CLAUDE.md +0 -42
- package/CONTRIBUTING.md +0 -65
- package/index.html +0 -509
- package/packages/cli/bin/ekh.js +0 -2
- package/packages/cli/bin/stellavault.js +0 -2
- package/packages/cli/dist/commands/adr-cmd.d.ts +0 -7
- package/packages/cli/dist/commands/adr-cmd.js +0 -45
- package/packages/cli/dist/commands/ask-cmd.d.ts +0 -5
- package/packages/cli/dist/commands/ask-cmd.js +0 -36
- package/packages/cli/dist/commands/autopilot-cmd.d.ts +0 -4
- package/packages/cli/dist/commands/autopilot-cmd.js +0 -76
- package/packages/cli/dist/commands/brief-cmd.d.ts +0 -2
- package/packages/cli/dist/commands/brief-cmd.js +0 -82
- package/packages/cli/dist/commands/capture-cmd.d.ts +0 -7
- package/packages/cli/dist/commands/capture-cmd.js +0 -31
- package/packages/cli/dist/commands/card-cmd.d.ts +0 -4
- package/packages/cli/dist/commands/card-cmd.js +0 -26
- package/packages/cli/dist/commands/clip-cmd.d.ts +0 -4
- package/packages/cli/dist/commands/clip-cmd.js +0 -151
- package/packages/cli/dist/commands/cloud-cmd.d.ts +0 -4
- package/packages/cli/dist/commands/cloud-cmd.js +0 -64
- package/packages/cli/dist/commands/compile-cmd.d.ts +0 -6
- package/packages/cli/dist/commands/compile-cmd.js +0 -30
- package/packages/cli/dist/commands/contradictions-cmd.d.ts +0 -2
- package/packages/cli/dist/commands/contradictions-cmd.js +0 -34
- package/packages/cli/dist/commands/decay-cmd.d.ts +0 -2
- package/packages/cli/dist/commands/decay-cmd.js +0 -48
- package/packages/cli/dist/commands/digest-cmd.d.ts +0 -5
- package/packages/cli/dist/commands/digest-cmd.js +0 -136
- package/packages/cli/dist/commands/draft-cmd.d.ts +0 -6
- package/packages/cli/dist/commands/draft-cmd.js +0 -110
- package/packages/cli/dist/commands/duplicates-cmd.d.ts +0 -4
- package/packages/cli/dist/commands/duplicates-cmd.js +0 -30
- package/packages/cli/dist/commands/federate-cmd.d.ts +0 -5
- package/packages/cli/dist/commands/federate-cmd.js +0 -247
- package/packages/cli/dist/commands/fleeting-cmd.d.ts +0 -4
- package/packages/cli/dist/commands/fleeting-cmd.js +0 -45
- package/packages/cli/dist/commands/flush-cmd.d.ts +0 -2
- package/packages/cli/dist/commands/flush-cmd.js +0 -58
- package/packages/cli/dist/commands/gaps-cmd.d.ts +0 -2
- package/packages/cli/dist/commands/gaps-cmd.js +0 -33
- package/packages/cli/dist/commands/graph-cmd.d.ts +0 -2
- package/packages/cli/dist/commands/graph-cmd.js +0 -89
- package/packages/cli/dist/commands/index-cmd.d.ts +0 -2
- package/packages/cli/dist/commands/index-cmd.js +0 -57
- package/packages/cli/dist/commands/ingest-cmd.d.ts +0 -9
- package/packages/cli/dist/commands/ingest-cmd.js +0 -195
- package/packages/cli/dist/commands/init-cmd.d.ts +0 -2
- package/packages/cli/dist/commands/init-cmd.js +0 -161
- package/packages/cli/dist/commands/learn-cmd.d.ts +0 -2
- package/packages/cli/dist/commands/learn-cmd.js +0 -48
- package/packages/cli/dist/commands/lint-cmd.d.ts +0 -2
- package/packages/cli/dist/commands/lint-cmd.js +0 -61
- package/packages/cli/dist/commands/pack-cmd.d.ts +0 -15
- package/packages/cli/dist/commands/pack-cmd.js +0 -93
- package/packages/cli/dist/commands/review-cmd.d.ts +0 -4
- package/packages/cli/dist/commands/review-cmd.js +0 -107
- package/packages/cli/dist/commands/search-cmd.d.ts +0 -4
- package/packages/cli/dist/commands/search-cmd.js +0 -38
- package/packages/cli/dist/commands/serve-cmd.d.ts +0 -2
- package/packages/cli/dist/commands/serve-cmd.js +0 -14
- package/packages/cli/dist/commands/session-cmd.d.ts +0 -7
- package/packages/cli/dist/commands/session-cmd.js +0 -95
- package/packages/cli/dist/commands/status-cmd.d.ts +0 -2
- package/packages/cli/dist/commands/status-cmd.js +0 -33
- package/packages/cli/dist/commands/sync-cmd.d.ts +0 -5
- package/packages/cli/dist/commands/sync-cmd.js +0 -62
- package/packages/cli/dist/commands/vault-cmd.d.ts +0 -10
- package/packages/cli/dist/commands/vault-cmd.js +0 -54
- package/packages/cli/dist/index.d.ts +0 -2
- package/packages/cli/dist/index.js +0 -233
- package/packages/cli/package.json +0 -24
- package/packages/core/dist/api/dashboard.d.ts +0 -3
- package/packages/core/dist/api/dashboard.js +0 -135
- package/packages/core/dist/api/graph-data.d.ts +0 -11
- package/packages/core/dist/api/graph-data.js +0 -255
- package/packages/core/dist/api/pwa.d.ts +0 -3
- package/packages/core/dist/api/pwa.js +0 -77
- package/packages/core/dist/api/server.d.ts +0 -16
- package/packages/core/dist/api/server.js +0 -1122
- package/packages/core/dist/capture/voice.d.ts +0 -24
- package/packages/core/dist/capture/voice.js +0 -135
- package/packages/core/dist/cloud/index.d.ts +0 -3
- package/packages/core/dist/cloud/index.js +0 -2
- package/packages/core/dist/cloud/sync.d.ts +0 -29
- package/packages/core/dist/cloud/sync.js +0 -137
- package/packages/core/dist/config.d.ts +0 -35
- package/packages/core/dist/config.js +0 -63
- package/packages/core/dist/federation/credits.d.ts +0 -26
- package/packages/core/dist/federation/credits.js +0 -56
- package/packages/core/dist/federation/identity.d.ts +0 -14
- package/packages/core/dist/federation/identity.js +0 -74
- package/packages/core/dist/federation/index.d.ts +0 -7
- package/packages/core/dist/federation/index.js +0 -5
- package/packages/core/dist/federation/node.d.ts +0 -31
- package/packages/core/dist/federation/node.js +0 -216
- package/packages/core/dist/federation/privacy.d.ts +0 -8
- package/packages/core/dist/federation/privacy.js +0 -40
- package/packages/core/dist/federation/reputation.d.ts +0 -37
- package/packages/core/dist/federation/reputation.js +0 -139
- package/packages/core/dist/federation/search.d.ts +0 -19
- package/packages/core/dist/federation/search.js +0 -101
- package/packages/core/dist/federation/sharing.d.ts +0 -72
- package/packages/core/dist/federation/sharing.js +0 -246
- package/packages/core/dist/federation/trust.d.ts +0 -15
- package/packages/core/dist/federation/trust.js +0 -60
- package/packages/core/dist/federation/types.d.ts +0 -40
- package/packages/core/dist/federation/types.js +0 -3
- package/packages/core/dist/i18n/index.d.ts +0 -6
- package/packages/core/dist/i18n/index.js +0 -81
- package/packages/core/dist/i18n/note-strings.d.ts +0 -5
- package/packages/core/dist/i18n/note-strings.js +0 -94
- package/packages/core/dist/index.d.ts +0 -123
- package/packages/core/dist/index.js +0 -74
- package/packages/core/dist/indexer/chunker.d.ts +0 -14
- package/packages/core/dist/indexer/chunker.js +0 -148
- package/packages/core/dist/indexer/embedder.d.ts +0 -8
- package/packages/core/dist/indexer/embedder.js +0 -3
- package/packages/core/dist/indexer/index.d.ts +0 -28
- package/packages/core/dist/indexer/index.js +0 -74
- package/packages/core/dist/indexer/local-embedder.d.ts +0 -3
- package/packages/core/dist/indexer/local-embedder.js +0 -29
- package/packages/core/dist/indexer/scanner.d.ts +0 -11
- package/packages/core/dist/indexer/scanner.js +0 -148
- package/packages/core/dist/indexer/watcher.d.ts +0 -19
- package/packages/core/dist/indexer/watcher.js +0 -49
- package/packages/core/dist/intelligence/ask-engine.d.ts +0 -24
- package/packages/core/dist/intelligence/ask-engine.js +0 -142
- package/packages/core/dist/intelligence/auto-linker.d.ts +0 -19
- package/packages/core/dist/intelligence/auto-linker.js +0 -126
- package/packages/core/dist/intelligence/code-linker.d.ts +0 -20
- package/packages/core/dist/intelligence/code-linker.js +0 -88
- package/packages/core/dist/intelligence/contradiction-detector.d.ts +0 -20
- package/packages/core/dist/intelligence/contradiction-detector.js +0 -115
- package/packages/core/dist/intelligence/decay-engine.d.ts +0 -27
- package/packages/core/dist/intelligence/decay-engine.js +0 -190
- package/packages/core/dist/intelligence/draft-generator.d.ts +0 -25
- package/packages/core/dist/intelligence/draft-generator.js +0 -277
- package/packages/core/dist/intelligence/duplicate-detector.d.ts +0 -20
- package/packages/core/dist/intelligence/duplicate-detector.js +0 -55
- package/packages/core/dist/intelligence/file-extractors.d.ts +0 -13
- package/packages/core/dist/intelligence/file-extractors.js +0 -155
- package/packages/core/dist/intelligence/fsrs.d.ts +0 -43
- package/packages/core/dist/intelligence/fsrs.js +0 -70
- package/packages/core/dist/intelligence/gap-detector.d.ts +0 -25
- package/packages/core/dist/intelligence/gap-detector.js +0 -78
- package/packages/core/dist/intelligence/ingest-pipeline.d.ts +0 -32
- package/packages/core/dist/intelligence/ingest-pipeline.js +0 -245
- package/packages/core/dist/intelligence/knowledge-lint.d.ts +0 -27
- package/packages/core/dist/intelligence/knowledge-lint.js +0 -132
- package/packages/core/dist/intelligence/learning-path.d.ts +0 -31
- package/packages/core/dist/intelligence/learning-path.js +0 -53
- package/packages/core/dist/intelligence/notifications.d.ts +0 -31
- package/packages/core/dist/intelligence/notifications.js +0 -65
- package/packages/core/dist/intelligence/predictive-gaps.d.ts +0 -14
- package/packages/core/dist/intelligence/predictive-gaps.js +0 -74
- package/packages/core/dist/intelligence/semantic-versioning.d.ts +0 -37
- package/packages/core/dist/intelligence/semantic-versioning.js +0 -68
- package/packages/core/dist/intelligence/types.d.ts +0 -28
- package/packages/core/dist/intelligence/types.js +0 -3
- package/packages/core/dist/intelligence/wiki-compiler.d.ts +0 -30
- package/packages/core/dist/intelligence/wiki-compiler.js +0 -222
- package/packages/core/dist/intelligence/youtube-extractor.d.ts +0 -29
- package/packages/core/dist/intelligence/youtube-extractor.js +0 -321
- package/packages/core/dist/intelligence/zettelkasten.d.ts +0 -59
- package/packages/core/dist/intelligence/zettelkasten.js +0 -234
- package/packages/core/dist/mcp/custom-tools.d.ts +0 -29
- package/packages/core/dist/mcp/custom-tools.js +0 -70
- package/packages/core/dist/mcp/index.d.ts +0 -2
- package/packages/core/dist/mcp/index.js +0 -2
- package/packages/core/dist/mcp/server.d.ts +0 -51
- package/packages/core/dist/mcp/server.js +0 -174
- package/packages/core/dist/mcp/tools/agentic-graph.d.ts +0 -93
- package/packages/core/dist/mcp/tools/agentic-graph.js +0 -116
- package/packages/core/dist/mcp/tools/ask.d.ts +0 -29
- package/packages/core/dist/mcp/tools/ask.js +0 -43
- package/packages/core/dist/mcp/tools/brief.d.ts +0 -31
- package/packages/core/dist/mcp/tools/brief.js +0 -39
- package/packages/core/dist/mcp/tools/decay.d.ts +0 -33
- package/packages/core/dist/mcp/tools/decay.js +0 -32
- package/packages/core/dist/mcp/tools/decision-journal.d.ts +0 -78
- package/packages/core/dist/mcp/tools/decision-journal.js +0 -79
- package/packages/core/dist/mcp/tools/detect-gaps.d.ts +0 -24
- package/packages/core/dist/mcp/tools/detect-gaps.js +0 -47
- package/packages/core/dist/mcp/tools/export.d.ts +0 -29
- package/packages/core/dist/mcp/tools/export.js +0 -60
- package/packages/core/dist/mcp/tools/federated-search.d.ts +0 -29
- package/packages/core/dist/mcp/tools/federated-search.js +0 -36
- package/packages/core/dist/mcp/tools/generate-claude-md.d.ts +0 -35
- package/packages/core/dist/mcp/tools/generate-claude-md.js +0 -107
- package/packages/core/dist/mcp/tools/generate-draft.d.ts +0 -34
- package/packages/core/dist/mcp/tools/generate-draft.js +0 -120
- package/packages/core/dist/mcp/tools/get-document.d.ts +0 -35
- package/packages/core/dist/mcp/tools/get-document.js +0 -25
- package/packages/core/dist/mcp/tools/get-evolution.d.ts +0 -28
- package/packages/core/dist/mcp/tools/get-evolution.js +0 -70
- package/packages/core/dist/mcp/tools/get-related.d.ts +0 -32
- package/packages/core/dist/mcp/tools/get-related.js +0 -33
- package/packages/core/dist/mcp/tools/learning-path.d.ts +0 -23
- package/packages/core/dist/mcp/tools/learning-path.js +0 -45
- package/packages/core/dist/mcp/tools/link-code.d.ts +0 -34
- package/packages/core/dist/mcp/tools/link-code.js +0 -44
- package/packages/core/dist/mcp/tools/list-topics.d.ts +0 -15
- package/packages/core/dist/mcp/tools/list-topics.js +0 -18
- package/packages/core/dist/mcp/tools/search.d.ts +0 -39
- package/packages/core/dist/mcp/tools/search.js +0 -29
- package/packages/core/dist/mcp/tools/snapshot.d.ts +0 -47
- package/packages/core/dist/mcp/tools/snapshot.js +0 -84
- package/packages/core/dist/multi-vault/index.d.ts +0 -26
- package/packages/core/dist/multi-vault/index.js +0 -80
- package/packages/core/dist/pack/creator.d.ts +0 -21
- package/packages/core/dist/pack/creator.js +0 -105
- package/packages/core/dist/pack/exporter.d.ts +0 -4
- package/packages/core/dist/pack/exporter.js +0 -18
- package/packages/core/dist/pack/importer.d.ts +0 -10
- package/packages/core/dist/pack/importer.js +0 -55
- package/packages/core/dist/pack/index.d.ts +0 -6
- package/packages/core/dist/pack/index.js +0 -5
- package/packages/core/dist/pack/marketplace.d.ts +0 -14
- package/packages/core/dist/pack/marketplace.js +0 -90
- package/packages/core/dist/pack/pii-masker.d.ts +0 -7
- package/packages/core/dist/pack/pii-masker.js +0 -29
- package/packages/core/dist/pack/types.d.ts +0 -36
- package/packages/core/dist/pack/types.js +0 -3
- package/packages/core/dist/plugins/index.d.ts +0 -35
- package/packages/core/dist/plugins/index.js +0 -57
- package/packages/core/dist/plugins/webhooks.d.ts +0 -30
- package/packages/core/dist/plugins/webhooks.js +0 -79
- package/packages/core/dist/search/adaptive.d.ts +0 -16
- package/packages/core/dist/search/adaptive.js +0 -67
- package/packages/core/dist/search/bm25.d.ts +0 -4
- package/packages/core/dist/search/bm25.js +0 -10
- package/packages/core/dist/search/index.d.ts +0 -15
- package/packages/core/dist/search/index.js +0 -64
- package/packages/core/dist/search/rrf.d.ts +0 -7
- package/packages/core/dist/search/rrf.js +0 -21
- package/packages/core/dist/search/semantic.d.ts +0 -5
- package/packages/core/dist/search/semantic.js +0 -6
- package/packages/core/dist/store/index.d.ts +0 -3
- package/packages/core/dist/store/index.js +0 -2
- package/packages/core/dist/store/sqlite-vec.d.ts +0 -6
- package/packages/core/dist/store/sqlite-vec.js +0 -251
- package/packages/core/dist/store/types.d.ts +0 -20
- package/packages/core/dist/store/types.js +0 -3
- package/packages/core/dist/team/index.d.ts +0 -25
- package/packages/core/dist/team/index.js +0 -97
- package/packages/core/dist/types/chunk.d.ts +0 -23
- package/packages/core/dist/types/chunk.js +0 -3
- package/packages/core/dist/types/document.d.ts +0 -23
- package/packages/core/dist/types/document.js +0 -3
- package/packages/core/dist/types/graph.d.ts +0 -39
- package/packages/core/dist/types/graph.js +0 -3
- package/packages/core/dist/types/index.d.ts +0 -5
- package/packages/core/dist/types/index.js +0 -2
- package/packages/core/dist/types/search.d.ts +0 -39
- package/packages/core/dist/types/search.js +0 -3
- package/packages/core/dist/utils/retry.d.ts +0 -25
- package/packages/core/dist/utils/retry.js +0 -59
- package/packages/core/package.json +0 -67
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
// stellavault digest — 주간 지식 활동 리포트
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { loadConfig, createKnowledgeHub, DecayEngine } from '@stellavault/core';
|
|
4
|
-
export async function digestCommand(options) {
|
|
5
|
-
const config = loadConfig();
|
|
6
|
-
const hub = createKnowledgeHub(config);
|
|
7
|
-
const days = parseInt(options.days ?? '7', 10);
|
|
8
|
-
await hub.store.initialize();
|
|
9
|
-
const db = hub.store.getDb();
|
|
10
|
-
if (!db) {
|
|
11
|
-
console.error(chalk.red('❌ DB 접근 불가'));
|
|
12
|
-
process.exit(1);
|
|
13
|
-
}
|
|
14
|
-
console.log(chalk.green(`\n📊 지식 활동 리포트 (최근 ${days}일)`));
|
|
15
|
-
console.log(chalk.dim('─'.repeat(50)));
|
|
16
|
-
// 1. 접근 통계
|
|
17
|
-
const accessStats = db.prepare(`
|
|
18
|
-
SELECT access_type, COUNT(*) as cnt
|
|
19
|
-
FROM access_log WHERE accessed_at > datetime('now', '-${days} days')
|
|
20
|
-
GROUP BY access_type
|
|
21
|
-
`).all();
|
|
22
|
-
const totalAccess = accessStats.reduce((s, r) => s + r.cnt, 0);
|
|
23
|
-
console.log(`\n🔍 총 접근: ${chalk.bold(String(totalAccess))}회`);
|
|
24
|
-
for (const r of accessStats) {
|
|
25
|
-
const icon = r.access_type === 'view' ? '👁️' : r.access_type === 'search' ? '🔍' : '🤖';
|
|
26
|
-
console.log(` ${icon} ${r.access_type}: ${r.cnt}회`);
|
|
27
|
-
}
|
|
28
|
-
// 2. 가장 많이 본 노트
|
|
29
|
-
const topDocs = db.prepare(`
|
|
30
|
-
SELECT al.document_id, d.title, COUNT(*) as cnt
|
|
31
|
-
FROM access_log al
|
|
32
|
-
JOIN documents d ON d.id = al.document_id
|
|
33
|
-
WHERE al.accessed_at > datetime('now', '-${days} days')
|
|
34
|
-
GROUP BY al.document_id
|
|
35
|
-
ORDER BY cnt DESC LIMIT 10
|
|
36
|
-
`).all();
|
|
37
|
-
if (topDocs.length > 0) {
|
|
38
|
-
console.log(chalk.dim(`\n📄 가장 많이 접근한 노트:`));
|
|
39
|
-
for (const d of topDocs) {
|
|
40
|
-
const bar = '█'.repeat(Math.min(d.cnt, 20));
|
|
41
|
-
console.log(` ${chalk.cyan(bar)} ${d.cnt}회 ${d.title}`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
// 3. 일별 활동량
|
|
45
|
-
const dailyActivity = db.prepare(`
|
|
46
|
-
SELECT date(accessed_at) as day, COUNT(*) as cnt
|
|
47
|
-
FROM access_log WHERE accessed_at > datetime('now', '-${days} days')
|
|
48
|
-
GROUP BY day ORDER BY day
|
|
49
|
-
`).all();
|
|
50
|
-
if (dailyActivity.length > 0) {
|
|
51
|
-
console.log(chalk.dim('\n📅 일별 활동:'));
|
|
52
|
-
const maxCnt = Math.max(...dailyActivity.map((d) => d.cnt));
|
|
53
|
-
for (const d of dailyActivity) {
|
|
54
|
-
const barLen = Math.round((d.cnt / maxCnt) * 20);
|
|
55
|
-
const bar = '█'.repeat(barLen) + '░'.repeat(20 - barLen);
|
|
56
|
-
console.log(` ${d.day.slice(5)} ${chalk.green(bar)} ${d.cnt}`);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
// 4. type별 분포
|
|
60
|
-
const typeStats = db.prepare(`
|
|
61
|
-
SELECT d.type, COUNT(DISTINCT al.document_id) as cnt
|
|
62
|
-
FROM access_log al
|
|
63
|
-
JOIN documents d ON d.id = al.document_id
|
|
64
|
-
WHERE al.accessed_at > datetime('now', '-${days} days')
|
|
65
|
-
GROUP BY d.type ORDER BY cnt DESC
|
|
66
|
-
`).all();
|
|
67
|
-
if (typeStats.length > 0) {
|
|
68
|
-
console.log(chalk.dim('\n📊 접근한 노트 유형:'));
|
|
69
|
-
for (const t of typeStats) {
|
|
70
|
-
console.log(` ${t.type}: ${t.cnt}개`);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
// 5. 감쇠 변화
|
|
74
|
-
const decayEngine = new DecayEngine(db);
|
|
75
|
-
const report = await decayEngine.computeAll();
|
|
76
|
-
console.log(`\n🧠 건강도: R=${report.averageR} | 감쇠 ${report.decayingCount}개 | 위험 ${report.criticalCount}개`);
|
|
77
|
-
console.log(chalk.dim('\n═'.repeat(50)));
|
|
78
|
-
// --visual: Mermaid 다이어그램 + 요약을 .md로 저장
|
|
79
|
-
if (options.visual) {
|
|
80
|
-
const { writeFileSync, mkdirSync, existsSync } = await import('node:fs');
|
|
81
|
-
const { join, resolve } = await import('node:path');
|
|
82
|
-
const outputDir = resolve(config.vaultPath, '_stellavault/digests');
|
|
83
|
-
if (!existsSync(outputDir))
|
|
84
|
-
mkdirSync(outputDir, { recursive: true });
|
|
85
|
-
const date = new Date().toISOString().split('T')[0];
|
|
86
|
-
const filename = `digest-${date}.md`;
|
|
87
|
-
const outputPath = join(outputDir, filename);
|
|
88
|
-
// Mermaid 파이 차트
|
|
89
|
-
const pieData = (typeStats.length > 0 ? typeStats : [{ type: 'note', cnt: 1 }])
|
|
90
|
-
.map((t) => ` "${t.type}" : ${t.cnt}`)
|
|
91
|
-
.join('\n');
|
|
92
|
-
// Mermaid 타임라인
|
|
93
|
-
const timelineData = dailyActivity
|
|
94
|
-
.map((d) => ` ${d.day.slice(5)} : ${d.cnt}`)
|
|
95
|
-
.join('\n');
|
|
96
|
-
const md = [
|
|
97
|
-
'---',
|
|
98
|
-
`title: "Weekly Digest — ${date}"`,
|
|
99
|
-
'type: digest',
|
|
100
|
-
`date: ${new Date().toISOString()}`,
|
|
101
|
-
'source: stellavault-digest',
|
|
102
|
-
'---',
|
|
103
|
-
'',
|
|
104
|
-
`# Weekly Knowledge Digest — ${date}`,
|
|
105
|
-
'',
|
|
106
|
-
`## Summary`,
|
|
107
|
-
`- Total access: **${totalAccess}** in ${days} days`,
|
|
108
|
-
`- Average R: **${report.averageR.toFixed(2)}**`,
|
|
109
|
-
`- Decaying: ${report.decayingCount} | Critical: ${report.criticalCount}`,
|
|
110
|
-
'',
|
|
111
|
-
'## Activity by Type',
|
|
112
|
-
'```mermaid',
|
|
113
|
-
'pie title Note Types Accessed',
|
|
114
|
-
pieData,
|
|
115
|
-
'```',
|
|
116
|
-
'',
|
|
117
|
-
'## Daily Activity',
|
|
118
|
-
'```mermaid',
|
|
119
|
-
'xychart-beta',
|
|
120
|
-
` title "Daily Activity (${days} days)"`,
|
|
121
|
-
' x-axis [' + dailyActivity.map((d) => `"${d.day.slice(5)}"`).join(', ') + ']',
|
|
122
|
-
' y-axis "Access Count"',
|
|
123
|
-
' bar [' + dailyActivity.map((d) => d.cnt).join(', ') + ']',
|
|
124
|
-
'```',
|
|
125
|
-
'',
|
|
126
|
-
topDocs.length > 0 ? '## Most Accessed Notes\n' + topDocs.map((d) => `1. **${d.title}** — ${d.cnt} times`).join('\n') : '',
|
|
127
|
-
'',
|
|
128
|
-
'---',
|
|
129
|
-
`*Generated by \`stellavault digest --visual\` on ${new Date().toISOString()}*`,
|
|
130
|
-
].filter(Boolean).join('\n');
|
|
131
|
-
writeFileSync(outputPath, md, 'utf-8');
|
|
132
|
-
console.log(chalk.green(`\nVisual digest saved: ${filename}`));
|
|
133
|
-
console.log(chalk.dim(`Open in Obsidian to see Mermaid charts.`));
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
//# sourceMappingURL=digest-cmd.js.map
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
// stellavault draft — Express: 지식에서 초안 생성
|
|
2
|
-
// 카파시 자가 컴파일 → 외부 표현의 출구
|
|
3
|
-
// 두 가지 모드: rule-based (무료) + --ai (Claude API로 실제 글 생성)
|
|
4
|
-
import chalk from 'chalk';
|
|
5
|
-
import { loadConfig } from '@stellavault/core';
|
|
6
|
-
import { generateDraft } from '@stellavault/core/intelligence/draft-generator';
|
|
7
|
-
export async function draftCommand(topic, options) {
|
|
8
|
-
const config = loadConfig();
|
|
9
|
-
if (!config.vaultPath) {
|
|
10
|
-
console.error(chalk.red('No vault configured. Run `stellavault init` first.'));
|
|
11
|
-
process.exit(1);
|
|
12
|
-
}
|
|
13
|
-
const format = (options.format ?? 'blog');
|
|
14
|
-
try {
|
|
15
|
-
// Step 1: rule-based 초안 생성 (스캐폴딩 + 소스 수집)
|
|
16
|
-
// Blueprint 파싱: "Chapter 1:tag1,tag2; Chapter 2:tag3" 형식
|
|
17
|
-
let blueprint;
|
|
18
|
-
if (options.blueprint) {
|
|
19
|
-
blueprint = options.blueprint.split(';').map(s => {
|
|
20
|
-
const [title, tagsStr] = s.split(':').map(p => p.trim());
|
|
21
|
-
return { title, tags: tagsStr?.split(',').map(t => t.trim()) };
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
const result = generateDraft(config.vaultPath, { topic, format, blueprint }, config.folders);
|
|
25
|
-
if (options.ai) {
|
|
26
|
-
// Step 2: --ai 모드 → Claude API로 실제 글 생성
|
|
27
|
-
console.log(chalk.dim(' AI mode: generating with Claude...'));
|
|
28
|
-
await enhanceWithAI(config.vaultPath, result.filePath, topic ?? 'knowledge', format);
|
|
29
|
-
}
|
|
30
|
-
console.log(chalk.green(`Draft generated: ${result.title}`));
|
|
31
|
-
console.log(chalk.dim(` Format: ${format}`));
|
|
32
|
-
console.log(chalk.dim(` Mode: ${options.ai ? 'AI-enhanced (Claude)' : 'rule-based'}`));
|
|
33
|
-
console.log(chalk.dim(` Saved: ${result.filePath}`));
|
|
34
|
-
console.log(chalk.dim(` Words: ${result.wordCount}`));
|
|
35
|
-
console.log(chalk.dim(` Sources: ${result.sourceCount} documents`));
|
|
36
|
-
if (result.concepts.length > 0) {
|
|
37
|
-
console.log(chalk.dim(` Concepts: ${result.concepts.join(', ')}`));
|
|
38
|
-
}
|
|
39
|
-
console.log('');
|
|
40
|
-
console.log(chalk.dim(`Next steps:`));
|
|
41
|
-
console.log(chalk.dim(` Edit in Obsidian, then promote:`));
|
|
42
|
-
console.log(chalk.cyan(` stellavault promote ${result.filePath} --to literature`));
|
|
43
|
-
if (!options.ai) {
|
|
44
|
-
console.log(chalk.dim(` Or use --ai for Claude-enhanced draft, or MCP generate-draft in Claude Code.`));
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
catch (err) {
|
|
48
|
-
console.error(chalk.red(err instanceof Error ? err.message : 'Draft generation failed'));
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
async function enhanceWithAI(vaultPath, draftPath, topic, format) {
|
|
53
|
-
const { readFileSync, writeFileSync } = await import('node:fs');
|
|
54
|
-
const { resolve } = await import('node:path');
|
|
55
|
-
const fullPath = resolve(vaultPath, draftPath);
|
|
56
|
-
const scaffold = readFileSync(fullPath, 'utf-8');
|
|
57
|
-
// Extract source excerpts from scaffold
|
|
58
|
-
const excerpts = scaffold
|
|
59
|
-
.split('\n')
|
|
60
|
-
.filter(l => l.startsWith('> '))
|
|
61
|
-
.map(l => l.slice(2))
|
|
62
|
-
.join('\n');
|
|
63
|
-
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
64
|
-
if (!apiKey) {
|
|
65
|
-
console.error(chalk.yellow(' ANTHROPIC_API_KEY not set. Falling back to rule-based draft.'));
|
|
66
|
-
console.error(chalk.yellow(' Set it with: export ANTHROPIC_API_KEY=sk-ant-...'));
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
try {
|
|
70
|
-
const Anthropic = (await import('@anthropic-ai/sdk')).default;
|
|
71
|
-
const client = new Anthropic({ apiKey });
|
|
72
|
-
const message = await client.messages.create({
|
|
73
|
-
model: 'claude-sonnet-4-20250514',
|
|
74
|
-
max_tokens: 4096,
|
|
75
|
-
messages: [{
|
|
76
|
-
role: 'user',
|
|
77
|
-
content: `You are writing a ${format} about "${topic}" based ONLY on the following knowledge notes.
|
|
78
|
-
Do not add information beyond what's in the notes. Write in the same language as the source material.
|
|
79
|
-
Use [[title]] wikilink format for citations.
|
|
80
|
-
|
|
81
|
-
SOURCE NOTES:
|
|
82
|
-
${excerpts.slice(0, 8000)}
|
|
83
|
-
|
|
84
|
-
Write a complete, well-structured ${format}. No TODO placeholders.`,
|
|
85
|
-
}],
|
|
86
|
-
});
|
|
87
|
-
const aiContent = message.content[0];
|
|
88
|
-
if (aiContent.type === 'text') {
|
|
89
|
-
const enhanced = `---
|
|
90
|
-
title: "Draft: ${topic}"
|
|
91
|
-
type: draft
|
|
92
|
-
format: ${format}
|
|
93
|
-
mode: ai-enhanced
|
|
94
|
-
sources: ${excerpts.split('\n').length} excerpts
|
|
95
|
-
created: ${new Date().toISOString()}
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
${aiContent.text}
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
*Generated by \`stellavault draft --ai\` using Claude API at ${new Date().toISOString()}*
|
|
102
|
-
`;
|
|
103
|
-
writeFileSync(fullPath, enhanced, 'utf-8');
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
catch (err) {
|
|
107
|
-
console.error(chalk.yellow(` AI enhancement failed: ${err instanceof Error ? err.message : 'unknown'}. Keeping rule-based draft.`));
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
//# sourceMappingURL=draft-cmd.js.map
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// Design Ref: stellavault duplicates — 중복/유사 노트 탐지 CLI
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { loadConfig, createKnowledgeHub, detectDuplicates } from '@stellavault/core';
|
|
4
|
-
export async function duplicatesCommand(options) {
|
|
5
|
-
const config = loadConfig();
|
|
6
|
-
const hub = createKnowledgeHub(config);
|
|
7
|
-
const threshold = parseFloat(options.threshold ?? '0.88');
|
|
8
|
-
console.error(chalk.dim('⏳ Scanning for duplicates...'));
|
|
9
|
-
await hub.store.initialize();
|
|
10
|
-
await hub.embedder.initialize();
|
|
11
|
-
const pairs = await detectDuplicates(hub.store, threshold, 20);
|
|
12
|
-
if (pairs.length === 0) {
|
|
13
|
-
console.log(chalk.green('\n✨ 중복 노트가 없습니다!'));
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
console.log(chalk.yellow(`\n🔍 유사 노트 ${pairs.length}쌍 발견 (threshold: ${threshold})`));
|
|
17
|
-
console.log(chalk.dim('─'.repeat(60)));
|
|
18
|
-
for (let i = 0; i < pairs.length; i++) {
|
|
19
|
-
const p = pairs[i];
|
|
20
|
-
const pct = Math.round(p.similarity * 100);
|
|
21
|
-
const color = pct >= 95 ? chalk.red : chalk.yellow;
|
|
22
|
-
console.log(`\n${chalk.bold(`[${i + 1}]`)} ${color(`${pct}% 유사`)}`);
|
|
23
|
-
console.log(` A: ${chalk.cyan(p.docA.title)}`);
|
|
24
|
-
console.log(` ${chalk.dim(p.docA.filePath)}`);
|
|
25
|
-
console.log(` B: ${chalk.cyan(p.docB.title)}`);
|
|
26
|
-
console.log(` ${chalk.dim(p.docB.filePath)}`);
|
|
27
|
-
}
|
|
28
|
-
console.log(chalk.dim('\n💡 Obsidian에서 직접 병합하거나 삭제하세요'));
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=duplicates-cmd.js.map
|
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
// Design Ref: §6 — sv federate CLI (대화형 모드)
|
|
2
|
-
// Plan SC: SC1-SC5
|
|
3
|
-
import { createInterface } from 'node:readline';
|
|
4
|
-
import chalk from 'chalk';
|
|
5
|
-
import { loadConfig, createSqliteVecStore, createLocalEmbedder, FederationNode, FederatedSearch, getOrCreateIdentity, getSharingSummary, setTagLevel, setFolderLevel, setNodeLevel, getPendingRequests, approveRequest, denyRequest, } from '@stellavault/core';
|
|
6
|
-
export async function federateJoinCommand(options) {
|
|
7
|
-
const config = loadConfig();
|
|
8
|
-
const identity = getOrCreateIdentity(options.name);
|
|
9
|
-
console.log('');
|
|
10
|
-
console.log(chalk.bold(' ✦ Stellavault Federation'));
|
|
11
|
-
console.log(chalk.dim(` Node: ${identity.displayName} (${identity.peerId})`));
|
|
12
|
-
console.log('');
|
|
13
|
-
// 로컬 스토어 초기화 (검색 응답용)
|
|
14
|
-
const store = createSqliteVecStore(config.dbPath);
|
|
15
|
-
await store.initialize();
|
|
16
|
-
const embedder = createLocalEmbedder(config.embedding.localModel);
|
|
17
|
-
await embedder.initialize();
|
|
18
|
-
// 통계 수집
|
|
19
|
-
const stats = await store.getStats();
|
|
20
|
-
const topics = await store.getTopics();
|
|
21
|
-
// Federation 노드 시작
|
|
22
|
-
const node = new FederationNode(options.name);
|
|
23
|
-
node.setLocalStats(stats.documentCount, topics.slice(0, 5).map((t) => t.topic));
|
|
24
|
-
const search = new FederatedSearch(node, store, embedder);
|
|
25
|
-
search.startResponder();
|
|
26
|
-
// 이벤트 리스너
|
|
27
|
-
node.on('joined', (info) => {
|
|
28
|
-
console.log(chalk.green(` ✦ Joined federation network`));
|
|
29
|
-
console.log(chalk.dim(` Topic: ${info.topic}`));
|
|
30
|
-
console.log(chalk.dim(` Waiting for peers...\n`));
|
|
31
|
-
});
|
|
32
|
-
node.on('peer_joined', (peer) => {
|
|
33
|
-
console.log(chalk.cyan(` → Peer found: ${peer.displayName} (${peer.documentCount} docs) [${peer.peerId}]`));
|
|
34
|
-
});
|
|
35
|
-
node.on('peer_left', (info) => {
|
|
36
|
-
console.log(chalk.yellow(` ← Peer left: ${info.peerId}`));
|
|
37
|
-
});
|
|
38
|
-
node.on('search_request', () => {
|
|
39
|
-
// 검색 요청 수신 로깅 (응답은 FederatedSearch.startResponder가 처리)
|
|
40
|
-
});
|
|
41
|
-
await node.join();
|
|
42
|
-
// 대화형 모드
|
|
43
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
44
|
-
const prompt = () => rl.question(chalk.dim('federation> '), handleInput);
|
|
45
|
-
async function handleInput(line) {
|
|
46
|
-
const parts = line.trim().split(/\s+/);
|
|
47
|
-
const cmd = parts[0];
|
|
48
|
-
switch (cmd) {
|
|
49
|
-
case 'search': {
|
|
50
|
-
const query = parts.slice(1).join(' ');
|
|
51
|
-
if (!query) {
|
|
52
|
-
console.log(chalk.yellow(' Usage: search <query>'));
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
const start = Date.now();
|
|
56
|
-
console.log(chalk.dim(` Searching ${node.peerCount} peers...`));
|
|
57
|
-
const results = await search.search(query, { limit: 5, timeout: 5000 });
|
|
58
|
-
const elapsed = Date.now() - start;
|
|
59
|
-
if (results.length === 0) {
|
|
60
|
-
console.log(chalk.yellow(` No results from peers. (${elapsed}ms)`));
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
console.log('');
|
|
64
|
-
for (const r of results) {
|
|
65
|
-
const simColor = r.similarity >= 0.7 ? chalk.green : r.similarity >= 0.4 ? chalk.yellow : chalk.dim;
|
|
66
|
-
console.log(` ${simColor(`${Math.round(r.similarity * 100)}%`)} ${chalk.bold(r.title)} ${chalk.dim(`[${r.peerName}]`)}`);
|
|
67
|
-
console.log(` ${chalk.dim(r.snippet)}...`);
|
|
68
|
-
}
|
|
69
|
-
console.log(chalk.dim(`\n ${results.length} results from ${new Set(results.map(r => r.peerId)).size} peers (${elapsed}ms)`));
|
|
70
|
-
}
|
|
71
|
-
break;
|
|
72
|
-
}
|
|
73
|
-
case 'peers': {
|
|
74
|
-
const peers = node.getPeers();
|
|
75
|
-
if (peers.length === 0) {
|
|
76
|
-
console.log(chalk.yellow(' No peers connected'));
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
console.log('');
|
|
80
|
-
for (const p of peers) {
|
|
81
|
-
console.log(` ${chalk.cyan(p.displayName)} ${chalk.dim(`(${p.documentCount} docs)`)} [${p.peerId}]`);
|
|
82
|
-
if (p.topTopics.length > 0) {
|
|
83
|
-
console.log(` ${chalk.dim(p.topTopics.map(t => `#${t}`).join(' '))}`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
console.log(chalk.dim(`\n ${peers.length} peer(s) connected`));
|
|
87
|
-
}
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
case 'status': {
|
|
91
|
-
console.log('');
|
|
92
|
-
console.log(` ${chalk.bold('Node:')} ${identity.displayName} (${identity.peerId})`);
|
|
93
|
-
console.log(` ${chalk.bold('Docs:')} ${stats.documentCount}`);
|
|
94
|
-
console.log(` ${chalk.bold('Peers:')} ${node.peerCount}`);
|
|
95
|
-
console.log(` ${chalk.bold('Running:')} ${node.isRunning ? chalk.green('yes') : chalk.red('no')}`);
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
case 'connect': {
|
|
99
|
-
const addr = parts[1];
|
|
100
|
-
if (!addr || !addr.includes(':')) {
|
|
101
|
-
console.log(chalk.yellow(' Usage: connect <host:port>'));
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
const [host, portStr] = addr.split(':');
|
|
105
|
-
try {
|
|
106
|
-
console.log(chalk.dim(` Connecting to ${addr}...`));
|
|
107
|
-
await node.joinDirect(host, parseInt(portStr, 10));
|
|
108
|
-
console.log(chalk.green(` Connected to ${addr}`));
|
|
109
|
-
}
|
|
110
|
-
catch (err) {
|
|
111
|
-
console.log(chalk.red(` Failed: ${err instanceof Error ? err.message : err}`));
|
|
112
|
-
}
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
case 'sharing': {
|
|
116
|
-
console.log('\n' + chalk.bold(' Sharing Settings'));
|
|
117
|
-
console.log(' ' + getSharingSummary().split('\n').join('\n '));
|
|
118
|
-
console.log('');
|
|
119
|
-
break;
|
|
120
|
-
}
|
|
121
|
-
case 'set-tag': {
|
|
122
|
-
const tag = parts[1];
|
|
123
|
-
const lvl = parseInt(parts[2], 10);
|
|
124
|
-
if (!tag || isNaN(lvl) || lvl < 0 || lvl > 4) {
|
|
125
|
-
console.log(chalk.yellow(' Usage: set-tag <tag> <0-4>'));
|
|
126
|
-
break;
|
|
127
|
-
}
|
|
128
|
-
setTagLevel(tag, lvl);
|
|
129
|
-
console.log(chalk.green(` #${tag} → Level ${lvl}`));
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
case 'set-folder': {
|
|
133
|
-
const folder = parts[1];
|
|
134
|
-
const lvl = parseInt(parts[2], 10);
|
|
135
|
-
if (!folder || isNaN(lvl) || lvl < 0 || lvl > 4) {
|
|
136
|
-
console.log(chalk.yellow(' Usage: set-folder <folder> <0-4>'));
|
|
137
|
-
break;
|
|
138
|
-
}
|
|
139
|
-
setFolderLevel(folder, lvl);
|
|
140
|
-
console.log(chalk.green(` ${folder} → Level ${lvl}`));
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
case 'set-level': {
|
|
144
|
-
const lvl = parseInt(parts[1], 10);
|
|
145
|
-
if (isNaN(lvl) || lvl < 0 || lvl > 4) {
|
|
146
|
-
console.log(chalk.yellow(' Usage: set-level <0-4> (your node sharing level)'));
|
|
147
|
-
break;
|
|
148
|
-
}
|
|
149
|
-
setNodeLevel(lvl);
|
|
150
|
-
console.log(chalk.green(` My node level → ${lvl}`));
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
case 'requests': {
|
|
154
|
-
const pending = getPendingRequests();
|
|
155
|
-
if (pending.length === 0) {
|
|
156
|
-
console.log(chalk.dim(' No pending requests'));
|
|
157
|
-
break;
|
|
158
|
-
}
|
|
159
|
-
console.log(`\n ${pending.length} pending full-text requests:`);
|
|
160
|
-
for (const r of pending) {
|
|
161
|
-
console.log(` ${r.requestId.slice(0, 8)} — "${r.documentTitle}" from ${r.fromName} (${r.requestedAt.slice(0, 10)})`);
|
|
162
|
-
}
|
|
163
|
-
break;
|
|
164
|
-
}
|
|
165
|
-
case 'approve': {
|
|
166
|
-
const reqId = parts[1];
|
|
167
|
-
if (!reqId) {
|
|
168
|
-
console.log(chalk.yellow(' Usage: approve <request-id>'));
|
|
169
|
-
break;
|
|
170
|
-
}
|
|
171
|
-
const match = getPendingRequests().find(r => r.requestId.startsWith(reqId));
|
|
172
|
-
if (match && approveRequest(match.requestId))
|
|
173
|
-
console.log(chalk.green(` Approved: ${match.documentTitle}`));
|
|
174
|
-
else
|
|
175
|
-
console.log(chalk.red(' Request not found'));
|
|
176
|
-
break;
|
|
177
|
-
}
|
|
178
|
-
case 'deny': {
|
|
179
|
-
const reqId = parts[1];
|
|
180
|
-
if (!reqId) {
|
|
181
|
-
console.log(chalk.yellow(' Usage: deny <request-id>'));
|
|
182
|
-
break;
|
|
183
|
-
}
|
|
184
|
-
const match = getPendingRequests().find(r => r.requestId.startsWith(reqId));
|
|
185
|
-
if (match && denyRequest(match.requestId))
|
|
186
|
-
console.log(chalk.green(` Denied: ${match.documentTitle}`));
|
|
187
|
-
else
|
|
188
|
-
console.log(chalk.red(' Request not found'));
|
|
189
|
-
break;
|
|
190
|
-
}
|
|
191
|
-
case 'leave':
|
|
192
|
-
case 'quit':
|
|
193
|
-
case 'exit': {
|
|
194
|
-
console.log(chalk.dim(' Leaving federation...'));
|
|
195
|
-
await node.leave();
|
|
196
|
-
await store.close();
|
|
197
|
-
rl.close();
|
|
198
|
-
process.exit(0);
|
|
199
|
-
return; // don't re-prompt
|
|
200
|
-
}
|
|
201
|
-
case 'help': {
|
|
202
|
-
console.log('');
|
|
203
|
-
console.log(' Commands:');
|
|
204
|
-
console.log(` ${chalk.cyan('search <query>')} Search across all connected peers`);
|
|
205
|
-
console.log(` ${chalk.cyan('peers')} List connected peers`);
|
|
206
|
-
console.log(` ${chalk.cyan('status')} Show node info`);
|
|
207
|
-
console.log(` ${chalk.cyan('connect <ip:port>')} Connect to peer directly`);
|
|
208
|
-
console.log(` ${chalk.cyan('sharing')} Show sharing settings`);
|
|
209
|
-
console.log(` ${chalk.cyan('set-tag <t> <0-4>')} Set tag sharing level`);
|
|
210
|
-
console.log(` ${chalk.cyan('set-folder <f> <0-4>')} Set folder sharing level`);
|
|
211
|
-
console.log(` ${chalk.cyan('set-level <0-4>')} Set your node level`);
|
|
212
|
-
console.log(` ${chalk.cyan('requests')} Show pending full-text requests`);
|
|
213
|
-
console.log(` ${chalk.cyan('approve <id>')} Approve a request`);
|
|
214
|
-
console.log(` ${chalk.cyan('deny <id>')} Deny a request`);
|
|
215
|
-
console.log(` ${chalk.cyan('leave')} Disconnect and exit`);
|
|
216
|
-
break;
|
|
217
|
-
}
|
|
218
|
-
default: {
|
|
219
|
-
if (cmd)
|
|
220
|
-
console.log(chalk.dim(` Unknown command: ${cmd}. Type 'help' for commands.`));
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
prompt(); // 다음 입력 대기
|
|
225
|
-
}
|
|
226
|
-
// Ctrl+C 처리
|
|
227
|
-
process.on('SIGINT', async () => {
|
|
228
|
-
console.log(chalk.dim('\n Leaving federation...'));
|
|
229
|
-
await node.leave();
|
|
230
|
-
await store.close();
|
|
231
|
-
process.exit(0);
|
|
232
|
-
});
|
|
233
|
-
prompt();
|
|
234
|
-
}
|
|
235
|
-
// 단순 상태 조회 (join 없이)
|
|
236
|
-
export async function federateStatusCommand() {
|
|
237
|
-
const identity = getOrCreateIdentity();
|
|
238
|
-
const config = loadConfig();
|
|
239
|
-
console.log('');
|
|
240
|
-
console.log(chalk.bold(' ✦ Federation Identity'));
|
|
241
|
-
console.log(` PeerID: ${identity.peerId}`);
|
|
242
|
-
console.log(` Name: ${identity.displayName}`);
|
|
243
|
-
console.log(` Since: ${identity.createdAt}`);
|
|
244
|
-
console.log(` DB: ${config.dbPath}`);
|
|
245
|
-
console.log('');
|
|
246
|
-
}
|
|
247
|
-
//# sourceMappingURL=federate-cmd.js.map
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// stellavault fleeting — 찰나 메모 즉시 캡처
|
|
2
|
-
// "떠오른 생각을 raw/ 폴더에 즉시 저장"
|
|
3
|
-
import chalk from 'chalk';
|
|
4
|
-
import { loadConfig } from '@stellavault/core';
|
|
5
|
-
import { writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
6
|
-
import { join, resolve } from 'node:path';
|
|
7
|
-
export async function fleetingCommand(text, options) {
|
|
8
|
-
if (!text || text.trim().length < 2) {
|
|
9
|
-
console.error(chalk.yellow('Usage: stellavault fleeting "your idea here" [--tags tag1,tag2]'));
|
|
10
|
-
process.exit(1);
|
|
11
|
-
}
|
|
12
|
-
const config = loadConfig();
|
|
13
|
-
const rawDir = resolve(config.vaultPath, 'raw');
|
|
14
|
-
if (!existsSync(rawDir))
|
|
15
|
-
mkdirSync(rawDir, { recursive: true });
|
|
16
|
-
const now = new Date();
|
|
17
|
-
const timestamp = now.toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
18
|
-
const slug = text.slice(0, 40).replace(/[^a-zA-Z0-9가-힣\s]/g, '').replace(/\s+/g, '-').toLowerCase();
|
|
19
|
-
const filename = `${timestamp}-${slug}.md`;
|
|
20
|
-
const filePath = join(rawDir, filename);
|
|
21
|
-
// path traversal 방지
|
|
22
|
-
if (!resolve(filePath).startsWith(resolve(rawDir))) {
|
|
23
|
-
console.error(chalk.red('Invalid file path'));
|
|
24
|
-
process.exit(1);
|
|
25
|
-
}
|
|
26
|
-
const tags = options.tags ? options.tags.split(',').map(t => t.trim()) : [];
|
|
27
|
-
const content = [
|
|
28
|
-
'---',
|
|
29
|
-
`title: "${text.slice(0, 80)}"`,
|
|
30
|
-
'type: fleeting',
|
|
31
|
-
`created: ${now.toISOString()}`,
|
|
32
|
-
`tags: [${tags.map(t => `"${t}"`).join(', ')}]`,
|
|
33
|
-
'---',
|
|
34
|
-
'',
|
|
35
|
-
text,
|
|
36
|
-
'',
|
|
37
|
-
'---',
|
|
38
|
-
`*Captured via \`stellavault fleeting\` at ${now.toLocaleString('ko-KR')}*`,
|
|
39
|
-
].join('\n');
|
|
40
|
-
writeFileSync(filePath, content, 'utf-8');
|
|
41
|
-
console.log(chalk.green(`Captured: ${filename}`));
|
|
42
|
-
console.log(chalk.dim(`Location: raw/${filename}`));
|
|
43
|
-
console.log(chalk.dim('Run `stellavault compile` to process into wiki.'));
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=fleeting-cmd.js.map
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
// stellavault flush — Daily Logs → Wiki 플러시 (카파시의 Flush Process)
|
|
2
|
-
// Raw daily logs에서 개념/연결 추출 → wiki 갱신
|
|
3
|
-
// "소스 코드를 실행 파일로 컴파일하듯, 원시 데이터를 구조화된 지식으로 변환"
|
|
4
|
-
import chalk from 'chalk';
|
|
5
|
-
import { loadConfig } from '@stellavault/core';
|
|
6
|
-
import { readdirSync, readFileSync, existsSync } from 'node:fs';
|
|
7
|
-
import { resolve, join } from 'node:path';
|
|
8
|
-
export async function flushCommand() {
|
|
9
|
-
const config = loadConfig();
|
|
10
|
-
if (!config.vaultPath) {
|
|
11
|
-
console.error(chalk.red('No vault configured. Run `stellavault init` first.'));
|
|
12
|
-
process.exit(1);
|
|
13
|
-
}
|
|
14
|
-
const folders = config.folders;
|
|
15
|
-
const logDir = resolve(config.vaultPath, folders.fleeting, '_daily-logs');
|
|
16
|
-
if (!existsSync(logDir)) {
|
|
17
|
-
console.log(chalk.yellow('No daily logs found. Use `stellavault session-save` or let Claude Code hooks capture sessions.'));
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
// 1. Daily logs 수집
|
|
21
|
-
const logFiles = readdirSync(logDir).filter(f => f.startsWith('daily-log-') && f.endsWith('.md'));
|
|
22
|
-
if (logFiles.length === 0) {
|
|
23
|
-
console.log(chalk.yellow('No daily log files found.'));
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
console.log(chalk.dim(`Found ${logFiles.length} daily logs`));
|
|
27
|
-
// 2. 모든 로그에서 세션 요약 추출
|
|
28
|
-
let totalSessions = 0;
|
|
29
|
-
const allContent = [];
|
|
30
|
-
for (const file of logFiles) {
|
|
31
|
-
const content = readFileSync(join(logDir, file), 'utf-8');
|
|
32
|
-
const sessions = content.split(/^## Session/m).slice(1);
|
|
33
|
-
totalSessions += sessions.length;
|
|
34
|
-
allContent.push(content);
|
|
35
|
-
}
|
|
36
|
-
console.log(chalk.dim(`Total sessions: ${totalSessions}`));
|
|
37
|
-
// 3. Compile: raw/ 전체 (daily-logs 포함) → wiki
|
|
38
|
-
try {
|
|
39
|
-
const { compileWiki } = await import('@stellavault/core/intelligence/wiki-compiler');
|
|
40
|
-
const rawDir = resolve(config.vaultPath, folders.fleeting);
|
|
41
|
-
const wikiDir = resolve(config.vaultPath, folders.wiki);
|
|
42
|
-
const result = compileWiki(rawDir, wikiDir);
|
|
43
|
-
console.log(chalk.green(`Flush complete!`));
|
|
44
|
-
console.log(chalk.dim(` Daily logs: ${logFiles.length} files, ${totalSessions} sessions`));
|
|
45
|
-
console.log(chalk.dim(` Wiki articles: ${result.wikiArticles.length}`));
|
|
46
|
-
console.log(chalk.dim(` Concepts extracted: ${result.concepts.length}`));
|
|
47
|
-
if (result.concepts.length > 0) {
|
|
48
|
-
console.log(chalk.dim(` Top concepts: ${result.concepts.slice(0, 8).join(', ')}`));
|
|
49
|
-
}
|
|
50
|
-
console.log(chalk.dim(` Index: ${result.indexFile}`));
|
|
51
|
-
}
|
|
52
|
-
catch (err) {
|
|
53
|
-
console.error(chalk.red(`Flush failed: ${err instanceof Error ? err.message : 'unknown'}`));
|
|
54
|
-
process.exit(1);
|
|
55
|
-
}
|
|
56
|
-
console.log(chalk.dim(' Tip: Run `stellavault lint` to check knowledge health'));
|
|
57
|
-
}
|
|
58
|
-
//# sourceMappingURL=flush-cmd.js.map
|