ralph-hero-knowledge-index 0.1.53 → 0.1.55
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/.claude-plugin/plugin.json +1 -1
- package/.mcp.json +1 -1
- package/coverage/lcov-report/chunker.ts.html +1 -1
- package/coverage/lcov-report/config.ts.html +1 -1
- package/coverage/lcov-report/db.ts.html +1 -1
- package/coverage/lcov-report/embedder.ts.html +1 -1
- package/coverage/lcov-report/file-scanner.ts.html +1 -1
- package/coverage/lcov-report/format.ts.html +1 -1
- package/coverage/lcov-report/generate-indexes.ts.html +3 -3
- package/coverage/lcov-report/graph-builder.ts.html +1 -1
- package/coverage/lcov-report/graph-tools.ts.html +3 -3
- package/coverage/lcov-report/hybrid-search.ts.html +1 -1
- package/coverage/lcov-report/ignore.ts.html +1 -1
- package/coverage/lcov-report/index.html +1 -1
- package/coverage/lcov-report/index.ts.html +4 -4
- package/coverage/lcov-report/llm-client.ts.html +1 -1
- package/coverage/lcov-report/parser.ts.html +1 -1
- package/coverage/lcov-report/reindex.ts.html +6 -6
- package/coverage/lcov-report/reranker.ts.html +1 -1
- package/coverage/lcov-report/search.ts.html +1 -1
- package/coverage/lcov-report/think.ts.html +3 -3
- package/coverage/lcov-report/traverse.ts.html +1 -1
- package/coverage/lcov-report/vector-search.ts.html +1 -1
- package/coverage/lcov.info +1 -1
- package/package.json +4 -4
- package/skills/curate/SKILL.md +2 -0
- package/skills/dream-loop/SKILL.md +55 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ralph-knowledge",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.55",
|
|
4
4
|
"description": "Knowledge graph for ralph-hero: semantic search, relationship traversal, and document indexing across thoughts/ documents. Optional companion to ralph-hero.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Chad Dubiel",
|
package/.mcp.json
CHANGED
|
@@ -940,7 +940,7 @@ export function chunkText(text: string, opts: ChunkerOptions = {}): Chunk[] {
|
|
|
940
940
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
941
941
|
Code coverage generated by
|
|
942
942
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
943
|
-
at 2026-
|
|
943
|
+
at 2026-07-26T13:32:06.309Z
|
|
944
944
|
</div>
|
|
945
945
|
<script src="prettify.js"></script>
|
|
946
946
|
<script>
|
|
@@ -385,7 +385,7 @@ export function loadConfig(): KnowledgeConfig {
|
|
|
385
385
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
386
386
|
Code coverage generated by
|
|
387
387
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
388
|
-
at 2026-
|
|
388
|
+
at 2026-07-26T13:32:06.309Z
|
|
389
389
|
</div>
|
|
390
390
|
<script src="prettify.js"></script>
|
|
391
391
|
<script>
|
|
@@ -1897,7 +1897,7 @@ export class KnowledgeDB {
|
|
|
1897
1897
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1898
1898
|
Code coverage generated by
|
|
1899
1899
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1900
|
-
at 2026-
|
|
1900
|
+
at 2026-07-26T13:32:06.309Z
|
|
1901
1901
|
</div>
|
|
1902
1902
|
<script src="prettify.js"></script>
|
|
1903
1903
|
<script>
|
|
@@ -763,7 +763,7 @@ export function prepareTextForEmbedding(
|
|
|
763
763
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
764
764
|
Code coverage generated by
|
|
765
765
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
766
|
-
at 2026-
|
|
766
|
+
at 2026-07-26T13:32:06.309Z
|
|
767
767
|
</div>
|
|
768
768
|
<script src="prettify.js"></script>
|
|
769
769
|
<script>
|
|
@@ -199,7 +199,7 @@ export function findMarkdownFiles(dir: string, matcher?: IgnoreMatcher): string[
|
|
|
199
199
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
200
200
|
Code coverage generated by
|
|
201
201
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
202
|
-
at 2026-
|
|
202
|
+
at 2026-07-26T13:32:06.309Z
|
|
203
203
|
</div>
|
|
204
204
|
<script src="prettify.js"></script>
|
|
205
205
|
<script>
|
|
@@ -295,7 +295,7 @@ export function formatTraverseResults(
|
|
|
295
295
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
296
296
|
Code coverage generated by
|
|
297
297
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
298
|
-
at 2026-
|
|
298
|
+
at 2026-07-26T13:32:06.309Z
|
|
299
299
|
</div>
|
|
300
300
|
<script src="prettify.js"></script>
|
|
301
301
|
<script>
|
|
@@ -670,7 +670,7 @@ export function writeTypeIndex(
|
|
|
670
670
|
const superseded = docs.filter((d) => d.status === "superseded");
|
|
671
671
|
|
|
672
672
|
const sortByDate = (a: ParsedDocument, b: ParsedDocument) =>
|
|
673
|
-
(b.date ?? <span class="branch-1 cbranch-no" title="branch not covered" >"")
|
|
673
|
+
(b.date ?? <span class="branch-1 cbranch-no" title="branch not covered" >"")</span>.localeCompare(a.date ?? <span class="branch-1 cbranch-no" title="branch not covered" >"")</span>;
|
|
674
674
|
active.sort(sortByDate);
|
|
675
675
|
superseded.sort(sortByDate);
|
|
676
676
|
|
|
@@ -791,7 +791,7 @@ export function writeIssueHubs(outDir: string, allDocs: ParsedDocument[]): void
|
|
|
791
791
|
const RECENT_LIMIT = 20;
|
|
792
792
|
|
|
793
793
|
export function writeMasterIndex(outDir: string, allDocs: ParsedDocument[], hasUncategorized = false): void {
|
|
794
|
-
const sorted = [...allDocs].sort((a, b) => (b.date ?? <span class="branch-1 cbranch-no" title="branch not covered" >"")
|
|
794
|
+
const sorted = [...allDocs].sort((a, b) => (b.date ?? <span class="branch-1 cbranch-no" title="branch not covered" >"")</span>.localeCompare(a.date ?? <span class="branch-1 cbranch-no" title="branch not covered" >"")</span>);
|
|
795
795
|
const recent = sorted.slice(0, RECENT_LIMIT);
|
|
796
796
|
|
|
797
797
|
const lines: string[] = [
|
|
@@ -946,7 +946,7 @@ export function generateIndexes(outDir: string, allDocs: ParsedDocument[]): void
|
|
|
946
946
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
947
947
|
Code coverage generated by
|
|
948
948
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
949
|
-
at 2026-
|
|
949
|
+
at 2026-07-26T13:32:06.309Z
|
|
950
950
|
</div>
|
|
951
951
|
<script src="prettify.js"></script>
|
|
952
952
|
<script>
|
|
@@ -292,7 +292,7 @@ export class GraphBuilder {
|
|
|
292
292
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
293
293
|
Code coverage generated by
|
|
294
294
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
295
|
-
at 2026-
|
|
295
|
+
at 2026-07-26T13:32:06.309Z
|
|
296
296
|
</div>
|
|
297
297
|
<script src="prettify.js"></script>
|
|
298
298
|
<script>
|
|
@@ -2386,9 +2386,9 @@ export function registerGraphTools(server: McpServer, db: KnowledgeDB): void {
|
|
|
2386
2386
|
// Run Louvain to partition, then extract the community subgraph
|
|
2387
2387
|
const partition: Record<string, number> =
|
|
2388
2388
|
graph.size > 0
|
|
2389
|
-
? louvain(graph, { rng: () => 0.5 }
|
|
2389
|
+
? louvain(graph, { rng: () => 0.5 })
|
|
2390
2390
|
: // No edges — each node is its own community, numbered by iteration order
|
|
2391
|
-
(() => {
|
|
2391
|
+
(() => <span class="fstat-no" title="function not covered" ><span class="branch-1 cbranch-no" title="branch not covered" >{</span></span>
|
|
2392
2392
|
const p: Record<string, number> = <span class="cstat-no" title="statement not covered" >{};</span>
|
|
2393
2393
|
let idx = <span class="cstat-no" title="statement not covered" >0;</span>
|
|
2394
2394
|
<span class="cstat-no" title="statement not covered" > graph.<span class="fstat-no" title="function not covered" >forEachNode((n</span>) => { <span class="cstat-no" title="statement not covered" >p[n] = idx++; }</span>);</span>
|
|
@@ -2821,7 +2821,7 @@ export function registerGraphTools(server: McpServer, db: KnowledgeDB): void {
|
|
|
2821
2821
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
2822
2822
|
Code coverage generated by
|
|
2823
2823
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
2824
|
-
at 2026-
|
|
2824
|
+
at 2026-07-26T13:32:06.309Z
|
|
2825
2825
|
</div>
|
|
2826
2826
|
<script src="prettify.js"></script>
|
|
2827
2827
|
<script>
|
|
@@ -1606,7 +1606,7 @@ export class HybridSearch {
|
|
|
1606
1606
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1607
1607
|
Code coverage generated by
|
|
1608
1608
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1609
|
-
at 2026-
|
|
1609
|
+
at 2026-07-26T13:32:06.309Z
|
|
1610
1610
|
</div>
|
|
1611
1611
|
<script src="prettify.js"></script>
|
|
1612
1612
|
<script>
|
|
@@ -316,7 +316,7 @@ export function loadIgnoreForRoot(
|
|
|
316
316
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
317
317
|
Code coverage generated by
|
|
318
318
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
319
|
-
at 2026-
|
|
319
|
+
at 2026-07-26T13:32:06.309Z
|
|
320
320
|
</div>
|
|
321
321
|
<script src="prettify.js"></script>
|
|
322
322
|
<script>
|
|
@@ -386,7 +386,7 @@
|
|
|
386
386
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
387
387
|
Code coverage generated by
|
|
388
388
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
389
|
-
at 2026-
|
|
389
|
+
at 2026-07-26T13:32:06.309Z
|
|
390
390
|
</div>
|
|
391
391
|
<script src="prettify.js"></script>
|
|
392
392
|
<script>
|
|
@@ -2052,8 +2052,8 @@ export function createServer(dbPath: string, opts: CreateServerOptions = {}) {
|
|
|
2052
2052
|
// avoid touching the real dream-memories tree or paying the ONNX model
|
|
2053
2053
|
// download in unit tests.
|
|
2054
2054
|
const rememberFs = opts.rememberFs ?? {
|
|
2055
|
-
<span class="fstat-no" title="function not covered" > mkdir: (<span class="cstat-no" title="statement not covered" >
|
|
2056
|
-
<span class="fstat-no" title="function not covered" > write: (p</span>ath: string, <span class="cstat-no" title="statement not covered" >
|
|
2055
|
+
<span class="fstat-no" title="function not covered" > mkdir: (d</span>ir: string) => <span class="cstat-no" title="statement not covered" >mkdirSync(dir, { recursive: true }),</span>
|
|
2056
|
+
<span class="fstat-no" title="function not covered" > write: (p</span>ath: string, body: string) => <span class="cstat-no" title="statement not covered" >writeFileSync(path, body, "utf-8"),</span>
|
|
2057
2057
|
};
|
|
2058
2058
|
const rememberReindexImpl = opts.rememberReindex ?? reindexPath;
|
|
2059
2059
|
const rememberNow = opts.<span class="fstat-no" title="function not covered" ><span class="branch-1 cbranch-no" title="branch not covered" >rememberNow ?? (() => <span class="cstat-no" title="statement not covered" >n</span>ew Date());</span></span>
|
|
@@ -2065,7 +2065,7 @@ export function createServer(dbPath: string, opts: CreateServerOptions = {}) {
|
|
|
2065
2065
|
// fail-open local LLM completion; tests inject a stub via `thinkComplete`.
|
|
2066
2066
|
const thinkComplete =
|
|
2067
2067
|
opts.<span class="fstat-no" title="function not covered" ><span class="branch-1 cbranch-no" title="branch not covered" >thinkComplete ??</span></span>
|
|
2068
|
-
((<span class="cstat-no" title="statement not covered" >
|
|
2068
|
+
((prompt: string) => <span class="cstat-no" title="statement not covered" >createLlmClient().complete(prompt, { maxTokens: 1024 }));</span>
|
|
2069
2069
|
|
|
2070
2070
|
server.tool(
|
|
2071
2071
|
"knowledge_search",
|
|
@@ -2776,7 +2776,7 @@ server.connect(transport).catch(console.error);
|
|
|
2776
2776
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
2777
2777
|
Code coverage generated by
|
|
2778
2778
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
2779
|
-
at 2026-
|
|
2779
|
+
at 2026-07-26T13:32:06.309Z
|
|
2780
2780
|
</div>
|
|
2781
2781
|
<script src="prettify.js"></script>
|
|
2782
2782
|
<script>
|
|
@@ -592,7 +592,7 @@ export function createLlmClient(opts: LlmClientOptions = {}): LlmClient {
|
|
|
592
592
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
593
593
|
Code coverage generated by
|
|
594
594
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
595
|
-
at 2026-
|
|
595
|
+
at 2026-07-26T13:32:06.309Z
|
|
596
596
|
</div>
|
|
597
597
|
<script src="prettify.js"></script>
|
|
598
598
|
<script>
|
|
@@ -622,7 +622,7 @@ export function parseDocument(id: string, path: string, raw: string): ParsedDocu
|
|
|
622
622
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
623
623
|
Code coverage generated by
|
|
624
624
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
625
|
-
at 2026-
|
|
625
|
+
at 2026-07-26T13:32:06.309Z
|
|
626
626
|
</div>
|
|
627
627
|
<script src="prettify.js"></script>
|
|
628
628
|
<script>
|
|
@@ -1894,7 +1894,7 @@ export function <span class="fstat-no" title="function not covered" >resolveDirs
|
|
|
1894
1894
|
const cliDb = <span class="cstat-no" title="statement not covered" >positional.<span class="fstat-no" title="function not covered" >find(a</span> => <span class="cstat-no" title="statement not covered" >a.endsWith(".db"))</span>;</span>
|
|
1895
1895
|
const cliDirs = <span class="cstat-no" title="statement not covered" >positional.<span class="fstat-no" title="function not covered" >filter(a</span> => <span class="cstat-no" title="statement not covered" >!a.endsWith(".db"))</span>;</span>
|
|
1896
1896
|
|
|
1897
|
-
const <span class="cstat-no" title="statement not covered" >
|
|
1897
|
+
const config = <span class="cstat-no" title="statement not covered" >loadConfig()</span>;
|
|
1898
1898
|
|
|
1899
1899
|
const <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" >resolveDbPath = (): string =></span></span>
|
|
1900
1900
|
<span class="cstat-no" title="statement not covered" > cliDb ??</span>
|
|
@@ -1978,9 +1978,9 @@ export async function <span class="fstat-no" title="function not covered" >reind
|
|
|
1978
1978
|
): Promise<{ indexed: boolean }> {
|
|
1979
1979
|
let db: KnowledgeDB | undefined;
|
|
1980
1980
|
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1981
|
-
const <span class="cstat-no" title="statement not covered" >
|
|
1982
|
-
const <span class="cstat-no" title="statement not covered" >
|
|
1983
|
-
const <span class="cstat-no" title="statement not covered" >
|
|
1981
|
+
const absPath = <span class="cstat-no" title="statement not covered" >resolve(filePath);</span>
|
|
1982
|
+
const raw = <span class="cstat-no" title="statement not covered" >readFileSync(absPath, "utf-8");</span>
|
|
1983
|
+
const id = <span class="cstat-no" title="statement not covered" >basename(absPath, ".md");</span>
|
|
1984
1984
|
const relPath = <span class="cstat-no" title="statement not covered" >absPath; // single-path mode — use absolute path verbatim</span>
|
|
1985
1985
|
|
|
1986
1986
|
<span class="cstat-no" title="statement not covered" > db = new KnowledgeDB(dbPath);</span>
|
|
@@ -1989,7 +1989,7 @@ export async function <span class="fstat-no" title="function not covered" >reind
|
|
|
1989
1989
|
const vec = <span class="cstat-no" title="statement not covered" >new VectorSearch(db);</span>
|
|
1990
1990
|
<span class="cstat-no" title="statement not covered" > vec.createIndex();</span>
|
|
1991
1991
|
|
|
1992
|
-
const <span class="cstat-no" title="statement not covered" >
|
|
1992
|
+
const parsed = <span class="cstat-no" title="statement not covered" >parseDocument(id, relPath, raw);</span>
|
|
1993
1993
|
|
|
1994
1994
|
<span class="cstat-no" title="statement not covered" > if (db.documentExists(parsed.id)) {</span>
|
|
1995
1995
|
<span class="cstat-no" title="statement not covered" > fts.deleteFtsEntry(parsed.id);</span>
|
|
@@ -2086,7 +2086,7 @@ const isMain = process.argv[1]?.endsWith("reindex.js");
|
|
|
2086
2086
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
2087
2087
|
Code coverage generated by
|
|
2088
2088
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
2089
|
-
at 2026-
|
|
2089
|
+
at 2026-07-26T13:32:06.309Z
|
|
2090
2090
|
</div>
|
|
2091
2091
|
<script src="prettify.js"></script>
|
|
2092
2092
|
<script>
|
|
@@ -790,7 +790,7 @@ export class Reranker {
|
|
|
790
790
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
791
791
|
Code coverage generated by
|
|
792
792
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
793
|
-
at 2026-
|
|
793
|
+
at 2026-07-26T13:32:06.309Z
|
|
794
794
|
</div>
|
|
795
795
|
<script src="prettify.js"></script>
|
|
796
796
|
<script>
|
|
@@ -814,7 +814,7 @@ export class FtsSearch {
|
|
|
814
814
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
815
815
|
Code coverage generated by
|
|
816
816
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
817
|
-
at 2026-
|
|
817
|
+
at 2026-07-26T13:32:06.309Z
|
|
818
818
|
</div>
|
|
819
819
|
<script src="prettify.js"></script>
|
|
820
820
|
<script>
|
|
@@ -402,7 +402,7 @@ export function buildThinkPrompt(query: string, sources: ThinkSource[]): string
|
|
|
402
402
|
.map((s) => {
|
|
403
403
|
const title = s.title ? ` (${s.title})` : <span class="branch-1 cbranch-no" title="branch not covered" >"";</span>
|
|
404
404
|
const tier = s.tier ? ` {${s.tier}}` : <span class="branch-1 cbranch-no" title="branch not covered" >"";</span>
|
|
405
|
-
const snippet = (s.snippet || <span class="branch-1 cbranch-no" title="branch not covered" >"")
|
|
405
|
+
const snippet = (s.snippet || <span class="branch-1 cbranch-no" title="branch not covered" >"")</span>.slice(0, SNIPPET_CLIP);
|
|
406
406
|
return `[${s.id}]${title}${tier}\n${snippet}`;
|
|
407
407
|
})
|
|
408
408
|
.join("\n\n");
|
|
@@ -428,7 +428,7 @@ export function buildThinkPrompt(query: string, sources: ThinkSource[]): string
|
|
|
428
428
|
export function parseThinkResponse(
|
|
429
429
|
text: string,
|
|
430
430
|
): { answer: string; gaps: string } | null {
|
|
431
|
-
let raw = (text || <span class="branch-1 cbranch-no" title="branch not covered" >"")
|
|
431
|
+
let raw = (text || <span class="branch-1 cbranch-no" title="branch not covered" >"")</span>.trim();
|
|
432
432
|
if (raw.startsWith("```")) {
|
|
433
433
|
const firstNl = raw.indexOf("\n");
|
|
434
434
|
<span class="missing-if-branch" title="else path not taken" >E</span>if (firstNl !== -1) raw = raw.slice(firstNl + 1);
|
|
@@ -514,7 +514,7 @@ export async function think(
|
|
|
514
514
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
515
515
|
Code coverage generated by
|
|
516
516
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
517
|
-
at 2026-
|
|
517
|
+
at 2026-07-26T13:32:06.309Z
|
|
518
518
|
</div>
|
|
519
519
|
<script src="prettify.js"></script>
|
|
520
520
|
<script>
|
|
@@ -487,7 +487,7 @@ export class Traverser {
|
|
|
487
487
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
488
488
|
Code coverage generated by
|
|
489
489
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
490
|
-
at 2026-
|
|
490
|
+
at 2026-07-26T13:32:06.309Z
|
|
491
491
|
</div>
|
|
492
492
|
<script src="prettify.js"></script>
|
|
493
493
|
<script>
|
|
@@ -439,7 +439,7 @@ export class VectorSearch {
|
|
|
439
439
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
440
440
|
Code coverage generated by
|
|
441
441
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
442
|
-
at 2026-
|
|
442
|
+
at 2026-07-26T13:32:06.309Z
|
|
443
443
|
</div>
|
|
444
444
|
<script src="prettify.js"></script>
|
|
445
445
|
<script>
|
package/coverage/lcov.info
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ralph-hero-knowledge-index",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.55",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"graphology-simple-path": "^0.2.0",
|
|
35
35
|
"graphology-traversal": "^0.3.1",
|
|
36
36
|
"graphology-types": "^0.24.8",
|
|
37
|
-
"ignore": "^7.0.
|
|
37
|
+
"ignore": "^7.0.6",
|
|
38
38
|
"sqlite-vec": "^0.1.9",
|
|
39
39
|
"yaml": "^2.9.0",
|
|
40
40
|
"zod": "^3.25.0"
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/better-sqlite3": "^7.6.13",
|
|
44
44
|
"@types/node": "^25.9.1",
|
|
45
|
-
"@vitest/coverage-v8": "^4.1.
|
|
46
|
-
"tsx": "^4.
|
|
45
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
46
|
+
"tsx": "^4.23.1",
|
|
47
47
|
"typescript": "^6.0.3",
|
|
48
48
|
"vitest": "^4.0.0"
|
|
49
49
|
}
|
package/skills/curate/SKILL.md
CHANGED
|
@@ -56,6 +56,8 @@ Scope matters: searching unscoped over a 3000+ document corpus dilutes the signa
|
|
|
56
56
|
|
|
57
57
|
Use `knowledge_search` (semantic) plus `knowledge_central` (find central documents in communities) to surface 5–10 candidate atomic axioms within the chosen domain.
|
|
58
58
|
|
|
59
|
+
**Also read the meta-reflection staging file** `~/projects/thoughts/wiki/_candidates.jsonl` (one JSON object per line: `axiom`, `rationale`, `source_reflection_ids`, `hash`). The weekly `meta_reflect.py` pass (GH-1513) stages pre-distilled wiki candidates here from the reflection tier — treat each as a strong, already-corroborated candidate, but still run it through the full distillation + gates below (staging is a suggestion, never a promotion). Skip any whose `hash` axiom is already an existing wiki entry or already in `_rejected.jsonl`.
|
|
60
|
+
|
|
59
61
|
A candidate is high-signal if it:
|
|
60
62
|
- States a principle in declarative form ("X must Y", "always X", "never X", "the rule is")
|
|
61
63
|
- Recurs across 3+ documents (corroboration is the strongest durability signal)
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Run the dream-loop — the nightly memory-consolidation pipeline that ingests the last window of raw activity (Gemma lab logs, git history, llm-cli transcripts, Claude Code sessions) as memory_tier=raw documents, then clusters them and synthesizes one memory_tier=reflection per cluster. This is the memorykeepers surface that orchestrates the existing scripts/dream/ infra (ingest.py + reflect.py + logrotate.sh)
|
|
3
|
-
argument-hint: "[--since 24h]"
|
|
2
|
+
description: Run, bootstrap, or verify the dream-loop — the nightly memory-consolidation pipeline that ingests the last window of raw activity (Gemma lab logs, git history, llm-cli transcripts, Claude Code sessions) as memory_tier=raw documents, then clusters them and synthesizes one memory_tier=reflection per cluster. This is the memorykeepers surface that orchestrates the existing scripts/dream/ infra (ingest.py + reflect.py + logrotate.sh). Use when the user mentions "dream", "dream-loop", "dream-now", "consolidate memories", "run reflection", "memorykeepers", "ingest raw memories", or wants to manually trigger the memory tiers (raw to reflection) without waiting for the 03:00 launchd fire. Also use for machine wiring and health checks — "bootstrap the dream loop", "set up dream-loop", "install the nightly schedule", "check dream-loop status", "verify the dream loop ran", "did the dream loop ingest anything" — via --mode bootstrap and --mode verify.
|
|
3
|
+
argument-hint: "[--since 24h | --mode bootstrap|verify]"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Dream-Loop — Memory Consolidation (memorykeepers)
|
|
7
7
|
|
|
8
|
-
The dream-loop is the memory-consolidation pipeline for ralph-knowledge. It pulls raw activity into `memory_tier=raw` documents, then clusters them (UMAP/HDBSCAN) and asks a local model to synthesize one `memory_tier=reflection` per cluster. This skill is the
|
|
8
|
+
The dream-loop is the memory-consolidation pipeline for ralph-knowledge. It pulls raw activity into `memory_tier=raw` documents, then clusters them (UMAP/HDBSCAN) and asks a local model to synthesize one `memory_tier=reflection` per cluster. This skill is the memorykeepers surface for the pipeline: a manual run entrypoint by default, plus `--mode bootstrap` (first-time machine wiring) and `--mode verify` (post-run health checks).
|
|
9
|
+
|
|
10
|
+
## Modes
|
|
11
|
+
|
|
12
|
+
| Mode | When | What it does |
|
|
13
|
+
|------|------|--------------|
|
|
14
|
+
| *(default)* run | "run the dream loop", "consolidate memories" | Steps 1–6 below: ingest → reflect → logrotate → report |
|
|
15
|
+
| `--mode bootstrap` | first run on a machine, "bootstrap the dream loop" | Delegates to `scripts/dream/bootstrap.sh`; see **Bootstrap** |
|
|
16
|
+
| `--mode verify` | "did it run?", "check dream-loop status" | Read-only health checks; see **Verify** |
|
|
17
|
+
|
|
18
|
+
Resolve the mode from intent, not just the flag — "set up the dream loop on this machine" is bootstrap, "did last night's run work?" is verify, even without `--mode`.
|
|
9
19
|
|
|
10
20
|
## How you talk
|
|
11
21
|
|
|
@@ -25,7 +35,7 @@ You refuse to:
|
|
|
25
35
|
3. **`~/.ralph/knowledge.config.json` authored** with the `roots` to scan and `dbPath`.
|
|
26
36
|
4. **A local model reachable** at `RALPH_LLM_URL` (default `http://localhost:8000`) for the reflection synthesis step. If the model is unreachable, the pipeline fails open: empty reflections and a single stderr warning — raw ingest still succeeds.
|
|
27
37
|
|
|
28
|
-
If
|
|
38
|
+
If any prerequisite is missing, that is a bootstrap problem, not a run problem — switch to **Bootstrap** below rather than surfacing a bare error.
|
|
29
39
|
|
|
30
40
|
## Workflow
|
|
31
41
|
|
|
@@ -70,8 +80,47 @@ State, as facts with paths and tiers:
|
|
|
70
80
|
- any clusters that crossed the recurring-failure thresholds and would warrant a `process-improvement` follow-up
|
|
71
81
|
- whether the local model was reachable, or whether the run failed open
|
|
72
82
|
|
|
83
|
+
## Bootstrap (`--mode bootstrap`)
|
|
84
|
+
|
|
85
|
+
`scripts/dream/bootstrap.sh` is the single source of truth for machine wiring — it idempotently provisions `~/.ralph/knowledge.config.json`, renders + loads the templated launchd plist for the 03:00 nightly fire, and smoke-tests ingest. Never re-implement its steps inline; when wiring logic changes, it changes in `bootstrap.sh`.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
cd <repo>/scripts/dream && uv sync # python deps (one-time)
|
|
89
|
+
cd <repo>/plugin/ralph-knowledge && npm install && npm run build # indexer (one-time)
|
|
90
|
+
bash <repo>/scripts/dream/bootstrap.sh # config + launchd + smoke ingest
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
After it completes, run the **Verify** checks to confirm the wiring took. `/ralph-knowledge:setup` Step 4 invokes the same script — either surface is fine; they cannot drift because both delegate.
|
|
94
|
+
|
|
95
|
+
**Machine conventions (optional):** if the machine has a model-gate checkout (`~/projects/model-gate`), prefer its surfaces for anything model-adjacent: `model-up <name>` to load the reflection model safely (stop-before-start on :8000), and the gate-aware `dream-now` zsh function as the shell-side equivalent of a full run. Registry of valid model names: `~/projects/models.yml`; setup details: `model-gate/README.md`. Absent model-gate, any OpenAI-compatible server at `RALPH_LLM_URL` works.
|
|
96
|
+
|
|
97
|
+
## Verify (`--mode verify`)
|
|
98
|
+
|
|
99
|
+
Read-only. Run what applies, report as facts with counts and paths:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# DB schema + tier breakdown
|
|
103
|
+
sqlite3 ~/.ralph-hero/knowledge.db "SELECT * FROM meta WHERE key='schema_version'"
|
|
104
|
+
sqlite3 ~/.ralph-hero/knowledge.db "SELECT memory_tier, COUNT(*) FROM documents GROUP BY memory_tier"
|
|
105
|
+
|
|
106
|
+
# Files on disk vs indexed (stale index if these diverge)
|
|
107
|
+
echo "On disk: $(find ~/projects/thoughts/dream-memories -name '*.md' | wc -l)"
|
|
108
|
+
echo "Indexed: $(sqlite3 ~/.ralph-hero/knowledge.db 'SELECT COUNT(*) FROM documents WHERE path LIKE "%dream-memories%"')"
|
|
109
|
+
|
|
110
|
+
# Local model reachability
|
|
111
|
+
curl -fsS http://localhost:8000/v1/models | jq '.data[].id'
|
|
112
|
+
|
|
113
|
+
# launchd nightly job (if installed): PID "-" when idle, exit status 0 after a clean run
|
|
114
|
+
launchctl list | grep dream-loop
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Interpretation notes:
|
|
118
|
+
- `schema_version=3` is **correct, not stale** — the `wiki`-tier CHECK-constraint change is labeled "Migration v4" in `db.ts` but deliberately does not bump the meta stamp.
|
|
119
|
+
- Four tiers exist: `doc` (curated), `raw` (dream ingest), `reflection` (synthesized), `wiki` (human-curated via `/ralph-knowledge:curate`; not writable by the record tool). A healthy post-run breakdown shows raw and reflection counts growing.
|
|
120
|
+
- Zero reflections with nonzero raws usually means the model was unreachable at run time (the pipeline fails open) — check reachability above, then re-run reflect for the window.
|
|
121
|
+
|
|
73
122
|
## Relationship to other surfaces
|
|
74
123
|
|
|
75
|
-
- **Nightly schedule** — `scripts/dream/launchd/com.dubiel.dream-loop.plist.template`, installed by `/ralph-knowledge:setup`
|
|
76
|
-
- **`dream-now`** — a model-gate zsh function that is gate-aware (loads the model first, then ingest + reflect + logrotate). Owned by model-gate, not this plugin.
|
|
124
|
+
- **Nightly schedule** — `scripts/dream/launchd/com.dubiel.dream-loop.plist.template`, installed by `bootstrap.sh` (directly or via `/ralph-knowledge:setup`). Fires at 03:00 daily. This skill is the manual on-demand counterpart.
|
|
125
|
+
- **`dream-now`** — a model-gate zsh function that is gate-aware (loads the model first, then ingest + reflect + logrotate). Owned by model-gate, not this plugin. The default run mode here invokes the scripts directly; point users at `dream-now` when they want the gate-managed shell path.
|
|
77
126
|
- **`/ralph-knowledge:curate`** — the human-gated promotion of reflections into the personal wiki tier. The dream-loop produces reflections; curate (not this skill) decides what becomes canonical.
|