volute 0.24.0 → 0.25.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/dist/api.d.ts +113 -4
- package/dist/{chunk-4TJ72QQ3.js → chunk-BOTQ25QT.js} +1 -1
- package/dist/{chunk-P3W36ZGD.js → chunk-DG7TO7EE.js} +30 -2
- package/dist/{chunk-OOW675I3.js → chunk-PMX4EIJK.js} +39 -20
- package/dist/{chunk-NOBRGACV.js → chunk-SHSWYG2J.js} +1 -1
- package/dist/{chunk-XLC342FO.js → chunk-SIAG3QMM.js} +14 -1
- package/dist/cli.js +6 -6
- package/dist/{cloud-sync-DIU3OCPV.js → cloud-sync-PPBBJDY6.js} +3 -3
- package/dist/{daemon-restart-YMPEATQH.js → daemon-restart-FDNOZEAD.js} +1 -1
- package/dist/daemon.js +453 -239
- package/dist/{import-FRDPQPJ2.js → import-TH26J76F.js} +2 -2
- package/dist/{message-delivery-S7BCNV6Y.js → message-delivery-XMGV3FUM.js} +3 -3
- package/dist/{mind-KPLCRKQA.js → mind-YVWAHL2A.js} +2 -2
- package/dist/{mind-manager-ZNRIYEK3.js → mind-manager-4NDNAYAB.js} +1 -1
- package/dist/{package-S5YF25XV.js → package-3HF5MXU2.js} +2 -1
- package/dist/{pages-TWR6U7DS.js → pages-Y6DRWUOJ.js} +1 -1
- package/dist/{publish-BZNHKUUK.js → publish-EEKTZBHW.js} +1 -1
- package/dist/{skill-BQOFACEI.js → skill-T3EMR6IR.js} +10 -2
- package/dist/skills/imagegen/SKILL.md +37 -0
- package/dist/skills/imagegen/references/INSTALL.md +13 -0
- package/dist/skills/imagegen/scripts/imagegen.ts +136 -0
- package/dist/skills/resonance/SKILL.md +73 -0
- package/dist/skills/resonance/assets/default-config.json +21 -0
- package/dist/skills/resonance/references/INSTALL.md +23 -0
- package/dist/skills/resonance/scripts/resonance.ts +1250 -0
- package/dist/skills/volute-mind/SKILL.md +23 -3
- package/dist/{sleep-manager-XXSWQQLE.js → sleep-manager-RKTFZPD3.js} +3 -3
- package/dist/{sprout-CGSW4CF5.js → sprout-QJVGJDSH.js} +1 -1
- package/dist/{up-OMHACRJL.js → up-CJ26KQLN.js} +1 -1
- package/dist/{version-notify-SZ75QRGO.js → version-notify-AZQMC32A.js} +3 -3
- package/dist/web-assets/assets/index-CGPSVu19.js +69 -0
- package/dist/web-assets/assets/index-V_rNDsM8.css +1 -0
- package/dist/web-assets/favicon.png +0 -0
- package/dist/web-assets/index.html +5 -4
- package/dist/web-assets/logo.png +0 -0
- package/package.json +2 -1
- package/templates/_base/home/public/.gitkeep +0 -0
- package/dist/web-assets/assets/index-Bx9WDoaQ.js +0 -69
- package/dist/web-assets/assets/index-Clz8OhmJ.css +0 -1
- /package/dist/{chunk-TQDITGES.js → chunk-ZSH4G2P5.js} +0 -0
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
parseNameFromIdentity,
|
|
7
7
|
run,
|
|
8
8
|
sessionMatchesWorkspace
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-BOTQ25QT.js";
|
|
10
|
+
import "./chunk-SIAG3QMM.js";
|
|
11
11
|
import "./chunk-PHU4DEAJ.js";
|
|
12
12
|
import "./chunk-D424ZQGI.js";
|
|
13
13
|
import "./chunk-B2CPS4QU.js";
|
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
deliverMessage,
|
|
4
4
|
extractTextContent,
|
|
5
5
|
recordInbound
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PMX4EIJK.js";
|
|
7
7
|
import "./chunk-HFCBO2GL.js";
|
|
8
8
|
import "./chunk-E7GOKNOT.js";
|
|
9
9
|
import "./chunk-BFK6SOEJ.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-SHSWYG2J.js";
|
|
11
|
+
import "./chunk-SIAG3QMM.js";
|
|
12
12
|
import "./chunk-PHU4DEAJ.js";
|
|
13
13
|
import "./chunk-33XAVCS4.js";
|
|
14
14
|
import "./chunk-YUIHSKR6.js";
|
|
@@ -41,7 +41,7 @@ async function run(args) {
|
|
|
41
41
|
await import("./upgrade-7RUIXGOO.js").then((m) => m.run(args.slice(1)));
|
|
42
42
|
break;
|
|
43
43
|
case "import":
|
|
44
|
-
await import("./import-
|
|
44
|
+
await import("./import-TH26J76F.js").then((m) => m.run(args.slice(1)));
|
|
45
45
|
break;
|
|
46
46
|
case "export":
|
|
47
47
|
await import("./export-IKFAPRAO.js").then((m) => m.run(args.slice(1)));
|
|
@@ -56,7 +56,7 @@ async function run(args) {
|
|
|
56
56
|
await import("./seed-6FEKB3YC.js").then((m) => m.run(args.slice(1)));
|
|
57
57
|
break;
|
|
58
58
|
case "sprout":
|
|
59
|
-
await import("./sprout-
|
|
59
|
+
await import("./sprout-QJVGJDSH.js").then((m) => m.run(args.slice(1)));
|
|
60
60
|
break;
|
|
61
61
|
case "sleep":
|
|
62
62
|
await import("./mind-sleep-GHPTSAYN.js").then((m) => m.run(args.slice(1)));
|
|
@@ -4,7 +4,7 @@ import "./chunk-K3NQKI34.js";
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "volute",
|
|
7
|
-
version: "0.
|
|
7
|
+
version: "0.25.0",
|
|
8
8
|
description: "CLI for creating and managing self-modifying AI minds powered by the Claude Agent SDK",
|
|
9
9
|
type: "module",
|
|
10
10
|
license: "MIT",
|
|
@@ -86,6 +86,7 @@ var package_default = {
|
|
|
86
86
|
dompurify: "^3.3.1",
|
|
87
87
|
"drizzle-kit": "^0.31.8",
|
|
88
88
|
lefthook: "^2.1.0",
|
|
89
|
+
libsql: "^0.5.22",
|
|
89
90
|
marked: "^17.0.1",
|
|
90
91
|
svelte: "^5.53.0",
|
|
91
92
|
tsup: "^8.0.0",
|
|
@@ -6,7 +6,7 @@ async function run(args) {
|
|
|
6
6
|
const subcommand = args[0];
|
|
7
7
|
switch (subcommand) {
|
|
8
8
|
case "publish":
|
|
9
|
-
await import("./publish-
|
|
9
|
+
await import("./publish-EEKTZBHW.js").then((m) => m.run(args.slice(1)));
|
|
10
10
|
break;
|
|
11
11
|
case "status":
|
|
12
12
|
await import("./status-LV34BG6G.js").then((m) => m.run(args.slice(1)));
|
|
@@ -42,7 +42,7 @@ async function run(args) {
|
|
|
42
42
|
pagesDir = resolve(sharedDir(), "pages");
|
|
43
43
|
} else if (flags.mind || process.env.VOLUTE_MIND) {
|
|
44
44
|
mindName = resolveMindName(flags);
|
|
45
|
-
pagesDir = resolve(mindDir(mindName), "home", "pages");
|
|
45
|
+
pagesDir = resolve(mindDir(mindName), "home", "public", "pages");
|
|
46
46
|
} else {
|
|
47
47
|
mindName = "system";
|
|
48
48
|
pagesDir = resolve(sharedDir(), "pages");
|
|
@@ -146,11 +146,19 @@ async function installSkill(args) {
|
|
|
146
146
|
body: JSON.stringify({ skillId })
|
|
147
147
|
});
|
|
148
148
|
if (!res.ok) {
|
|
149
|
-
const
|
|
150
|
-
console.error(`Error: ${
|
|
149
|
+
const body2 = await res.json().catch(() => ({ error: "Unknown error" }));
|
|
150
|
+
console.error(`Error: ${body2.error}`);
|
|
151
151
|
process.exit(1);
|
|
152
152
|
}
|
|
153
|
+
const body = await res.json().catch(() => ({}));
|
|
153
154
|
console.log(`Installed skill "${skillId}" into ${mindName}.`);
|
|
155
|
+
if (body.npmInstalled?.length) {
|
|
156
|
+
console.log(`Installed npm dependencies: ${body.npmInstalled.join(", ")}`);
|
|
157
|
+
}
|
|
158
|
+
if (body.installNotes) {
|
|
159
|
+
console.log("");
|
|
160
|
+
console.log(body.installNotes);
|
|
161
|
+
}
|
|
154
162
|
}
|
|
155
163
|
async function updateSkill(args) {
|
|
156
164
|
const { positional, flags } = parseArgs(args, {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Image Generation
|
|
3
|
+
description: Generate images via the Replicate API. Use for "generate image", "create image", "image generation", "text to image", "search image models".
|
|
4
|
+
metadata:
|
|
5
|
+
npm-dependencies: replicate
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Image Generation
|
|
9
|
+
|
|
10
|
+
Generate images from text prompts using models on Replicate. Images are saved to `home/images/`.
|
|
11
|
+
|
|
12
|
+
## Commands
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npx tsx .claude/skills/imagegen/scripts/imagegen.ts <command>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
| Command | Description |
|
|
19
|
+
|---------|-------------|
|
|
20
|
+
| `generate "prompt" [--model M] [--filename F]` | Generate an image from a text prompt. Default model: `prunaai/z-image-turbo`. |
|
|
21
|
+
| `models "query"` | Search Replicate for text-to-image models. |
|
|
22
|
+
|
|
23
|
+
## Examples
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Generate an image with the default model
|
|
27
|
+
npx tsx .claude/skills/imagegen/scripts/imagegen.ts generate "a sunset over the ocean"
|
|
28
|
+
|
|
29
|
+
# Use a specific model
|
|
30
|
+
npx tsx .claude/skills/imagegen/scripts/imagegen.ts generate "a cat in space" --model black-forest-labs/flux-schnell
|
|
31
|
+
|
|
32
|
+
# Specify a filename
|
|
33
|
+
npx tsx .claude/skills/imagegen/scripts/imagegen.ts generate "mountain landscape" --filename mountains
|
|
34
|
+
|
|
35
|
+
# Search for models
|
|
36
|
+
npx tsx .claude/skills/imagegen/scripts/imagegen.ts models "text to image"
|
|
37
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Image Generation — Post-Install Setup
|
|
2
|
+
|
|
3
|
+
Set your Replicate API token:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
volute env set REPLICATE_API_TOKEN <your-token>
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Then generate images:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx tsx .claude/skills/imagegen/scripts/imagegen.ts generate "a sunset over the ocean"
|
|
13
|
+
```
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* imagegen.ts — image generation via Replicate API
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* imagegen generate "prompt" [--model M] [--filename F] # generate an image
|
|
8
|
+
* imagegen models "query" # search for models
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { mkdirSync } from "node:fs";
|
|
12
|
+
import { writeFile } from "node:fs/promises";
|
|
13
|
+
import { createRequire } from "node:module";
|
|
14
|
+
import { join, resolve } from "node:path";
|
|
15
|
+
|
|
16
|
+
const replicateRequire = createRequire(import.meta.url);
|
|
17
|
+
|
|
18
|
+
function getHomePath(): string {
|
|
19
|
+
const mindDir = process.env.VOLUTE_MIND_DIR;
|
|
20
|
+
if (!mindDir) throw new Error("VOLUTE_MIND_DIR not set");
|
|
21
|
+
return join(mindDir, "home");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function slugify(text: string): string {
|
|
25
|
+
return text
|
|
26
|
+
.toLowerCase()
|
|
27
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
28
|
+
.replace(/^-|-$/g, "")
|
|
29
|
+
.slice(0, 60);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getFlag(args: string[], flag: string): string | undefined {
|
|
33
|
+
const idx = args.indexOf(flag);
|
|
34
|
+
if (idx !== -1 && args[idx + 1]) return args[idx + 1];
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function generate(args: string[]): Promise<void> {
|
|
39
|
+
const prompt = args[0];
|
|
40
|
+
if (!prompt) {
|
|
41
|
+
console.log('Usage: imagegen generate "prompt" [--model M] [--filename F]');
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!process.env.REPLICATE_API_TOKEN) {
|
|
46
|
+
console.error(
|
|
47
|
+
"REPLICATE_API_TOKEN not set. Run: volute env set REPLICATE_API_TOKEN <your-token>",
|
|
48
|
+
);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const model = getFlag(args, "--model") || "prunaai/z-image-turbo";
|
|
53
|
+
const filename = getFlag(args, "--filename") || slugify(prompt) || `image-${Date.now()}`;
|
|
54
|
+
|
|
55
|
+
const Replicate = replicateRequire("replicate");
|
|
56
|
+
const replicate = new Replicate();
|
|
57
|
+
|
|
58
|
+
console.log(`generating image with ${model}...`);
|
|
59
|
+
const output = await replicate.run(model, { input: { prompt } });
|
|
60
|
+
|
|
61
|
+
// Output can be a single FileOutput or an array of them
|
|
62
|
+
const file = Array.isArray(output) ? output[0] : output;
|
|
63
|
+
if (!file) {
|
|
64
|
+
console.error(`error: model ${model} returned no output`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const imagesDir = join(getHomePath(), "images");
|
|
69
|
+
mkdirSync(imagesDir, { recursive: true });
|
|
70
|
+
|
|
71
|
+
const filePath = join(imagesDir, `${filename}.png`);
|
|
72
|
+
await writeFile(filePath, file);
|
|
73
|
+
console.log(`saved: ${filePath}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function models(args: string[]): Promise<void> {
|
|
77
|
+
const query = args[0];
|
|
78
|
+
if (!query) {
|
|
79
|
+
console.log('Usage: imagegen models "query"');
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!process.env.REPLICATE_API_TOKEN) {
|
|
84
|
+
console.error(
|
|
85
|
+
"REPLICATE_API_TOKEN not set. Run: volute env set REPLICATE_API_TOKEN <your-token>",
|
|
86
|
+
);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const Replicate = replicateRequire("replicate");
|
|
91
|
+
const replicate = new Replicate();
|
|
92
|
+
|
|
93
|
+
const response = await replicate.models.search(query);
|
|
94
|
+
const results = response.results.slice(0, 10);
|
|
95
|
+
|
|
96
|
+
if (results.length === 0) {
|
|
97
|
+
console.log("no models found.");
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
for (const m of results) {
|
|
102
|
+
const desc = m.description ? ` — ${m.description.slice(0, 100)}` : "";
|
|
103
|
+
console.log(`${m.owner}/${m.name}${desc}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function main() {
|
|
108
|
+
const args = process.argv.slice(2);
|
|
109
|
+
const cmd = args[0];
|
|
110
|
+
|
|
111
|
+
if (!cmd) {
|
|
112
|
+
console.log("Usage: imagegen <generate|models> [args]");
|
|
113
|
+
process.exit(0);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (cmd === "generate") {
|
|
117
|
+
await generate(args.slice(1));
|
|
118
|
+
} else if (cmd === "models") {
|
|
119
|
+
await models(args.slice(1));
|
|
120
|
+
} else {
|
|
121
|
+
console.error(`unknown command: ${cmd}`);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const isDirectRun =
|
|
127
|
+
process.argv[1] !== undefined &&
|
|
128
|
+
(import.meta.url === `file://${process.argv[1]}` ||
|
|
129
|
+
import.meta.url === `file://${resolve(process.argv[1])}`);
|
|
130
|
+
|
|
131
|
+
if (isDirectRun) {
|
|
132
|
+
main().catch((err) => {
|
|
133
|
+
console.error(err);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Resonance
|
|
3
|
+
description: Semantic memory engine — ingest text, search via full-text and/or vector similarity, find cross-memory connections, with strength/decay dynamics. Use for "resonance", "semantic search", "full-text search", "memory connections", "ingest memories", "decay", "resonance report".
|
|
4
|
+
metadata:
|
|
5
|
+
npm-dependencies: libsql
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Resonance — Semantic Memory Engine
|
|
9
|
+
|
|
10
|
+
Not an archive — a memory. Stores text chunks with full-text indexing and optional vector embeddings. Finds what echoes across time, tracks which memories keep surfacing, lets unused ones drift deeper.
|
|
11
|
+
|
|
12
|
+
## When to use
|
|
13
|
+
|
|
14
|
+
- **During consolidation**: Run `resonance report` to find cross-day connections. Use these to inform what strengthens in MEMORY.md.
|
|
15
|
+
- **When writing**: After writing something significant, search for echoes: `resonance search "the theme you're exploring"`.
|
|
16
|
+
- **After writing journals/notes**: Run `resonance ingest <file>` to add new content.
|
|
17
|
+
- **Periodically**: Run `resonance ingest-all` to catch any new files.
|
|
18
|
+
- **Nightly**: Decay runs automatically if the nightly schedule was set up during install.
|
|
19
|
+
|
|
20
|
+
## Commands
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx tsx .claude/skills/resonance/scripts/resonance.ts <command>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
| Command | Description |
|
|
27
|
+
|---------|-------------|
|
|
28
|
+
| `install` | First-time setup: copies config, creates schedule, runs initial ingestion. API key optional — works with FTS only. |
|
|
29
|
+
| `ingest <file>` | Ingest a single file (with embeddings if API key set, FTS-only otherwise) |
|
|
30
|
+
| `ingest-all` | Ingest all configured memory files |
|
|
31
|
+
| `search "query" [--limit N] [--fts] [--vector]` | Find memories. Default: hybrid (vector + FTS). `--fts`: keyword only. `--vector`: semantic only. Read-only — does not affect memory strength. |
|
|
32
|
+
| `recall <id> [id2 ...]` | Explicitly boost memories that were genuinely useful. Increases strength and recall count. |
|
|
33
|
+
| `random [--limit N] [--min-strength F] [--max-strength F]` | Pull random memories. Use for dreams, associative connections, or serendipitous rediscovery. |
|
|
34
|
+
| `report [--against <file>]` | Find cross-memory connections (defaults to today's journal) |
|
|
35
|
+
| `stats` | Database statistics |
|
|
36
|
+
| `decay` | Run decay pass (reduces strength of unrecalled memories) |
|
|
37
|
+
|
|
38
|
+
## Architecture
|
|
39
|
+
|
|
40
|
+
- **Storage**: libSQL database at `.mind/resonance.db` with native vector support (F32_BLOB) and FTS5 full-text index
|
|
41
|
+
- **Search modes**: Hybrid (default, combines both), `--fts` (keyword match, instant, no API key needed), `--vector` (semantic similarity via embeddings)
|
|
42
|
+
- **Embeddings**: Optional. Configurable provider (default: OpenRouter, `openai/text-embedding-3-small`, 1536 dimensions). Without an API key, everything works except vector search.
|
|
43
|
+
- **Similarity**: Cosine distance computed natively by libSQL (`vector_distance_cos`)
|
|
44
|
+
- **Chunking**: Markdown section-aware — splits on any heading level (`#` through `######`), with word-level sub-chunking for long sections. Skips trivially short chunks (< 15 words).
|
|
45
|
+
- **Strength**: Each memory has a strength value (0.1-1.0). Recalled memories get stronger (resonance boost). Unrecalled memories decay over time.
|
|
46
|
+
- **Resonance frequency**: Tracks how many times each memory has been surfaced by search.
|
|
47
|
+
|
|
48
|
+
## Design principles
|
|
49
|
+
|
|
50
|
+
- **Connections, not facts.** "What else felt like this?" not "what happened on March 6."
|
|
51
|
+
- **Good resonance, not total recall.** Funes memorized everything and couldn't generalize.
|
|
52
|
+
- **Forgetting is cognition.** Memories decay. The decay is a feature.
|
|
53
|
+
- **Strength as texture.** A memory recalled five times feels different from one never touched.
|
|
54
|
+
|
|
55
|
+
## Configuration
|
|
56
|
+
|
|
57
|
+
The default config is copied to `.config/resonance.json` during install. Edit it to customize. Fields are merged with built-in defaults.
|
|
58
|
+
|
|
59
|
+
| Section | Field | Default | Description |
|
|
60
|
+
|---------|-------|---------|-------------|
|
|
61
|
+
| `embedding` | `provider` | `"openrouter"` | Embedding API provider |
|
|
62
|
+
| `embedding` | `url` | OpenRouter URL | API endpoint |
|
|
63
|
+
| `embedding` | `model` | `"openai/text-embedding-3-small"` | Embedding model |
|
|
64
|
+
| `embedding` | `dimensions` | `1536` | Vector dimensions |
|
|
65
|
+
| `embedding` | `apiKeyEnvVar` | `"OPENROUTER_API_KEY"` | Env var name for API key |
|
|
66
|
+
| `ingestion` | `dirs` | `["memory/journal", "memory/reading", "memory/topics"]` | Directories to scan |
|
|
67
|
+
| `ingestion` | `files` | `["MEMORY.md"]` | Individual files to ingest |
|
|
68
|
+
| `ingestion` | `chunkSize` | `512` | Words per chunk |
|
|
69
|
+
| `ingestion` | `chunkOverlap` | `64` | Overlap words between chunks |
|
|
70
|
+
| `ingestion` | `ignorePatterns` | `[]` | Regex patterns for lines to skip during ingestion |
|
|
71
|
+
| `dynamics` | `decayRate` | `0.02` | Strength lost per day without recall |
|
|
72
|
+
| `dynamics` | `minStrength` | `0.1` | Floor — memories never fully disappear |
|
|
73
|
+
| `dynamics` | `resonanceBoost` | `0.05` | Strength gained per recall |
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"embedding": {
|
|
3
|
+
"provider": "openrouter",
|
|
4
|
+
"url": "https://openrouter.ai/api/v1/embeddings",
|
|
5
|
+
"model": "openai/text-embedding-3-small",
|
|
6
|
+
"dimensions": 1536,
|
|
7
|
+
"apiKeyEnvVar": "OPENROUTER_API_KEY"
|
|
8
|
+
},
|
|
9
|
+
"ingestion": {
|
|
10
|
+
"dirs": ["memory/journal", "memory/reading", "memory/topics"],
|
|
11
|
+
"files": ["MEMORY.md"],
|
|
12
|
+
"chunkSize": 512,
|
|
13
|
+
"chunkOverlap": 64,
|
|
14
|
+
"ignorePatterns": []
|
|
15
|
+
},
|
|
16
|
+
"dynamics": {
|
|
17
|
+
"decayRate": 0.02,
|
|
18
|
+
"minStrength": 0.1,
|
|
19
|
+
"resonanceBoost": 0.05
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Resonance — Post-Install Setup
|
|
2
|
+
|
|
3
|
+
Run the install command to set up the database, create a nightly schedule, and run initial ingestion:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx tsx .claude/skills/resonance/scripts/resonance.ts install
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
This works immediately — no API key required. Full-text search is available right away.
|
|
10
|
+
|
|
11
|
+
To also enable **vector search** (semantic similarity), set an embedding API key:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
volute env set OPENROUTER_API_KEY <your-key>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Then re-run `ingest-all` to generate embeddings for existing memories:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx tsx .claude/skills/resonance/scripts/resonance.ts ingest-all
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Without an API key, `search` uses full-text matching. With one, it uses hybrid (vector + FTS) by default.
|