@grant-vine/wunderkind 0.3.0 → 0.4.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.
Files changed (106) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +156 -36
  3. package/agents/brand-builder.md +16 -2
  4. package/agents/ciso.md +23 -0
  5. package/agents/creative-director.md +14 -0
  6. package/agents/fullstack-wunderkind.md +16 -0
  7. package/agents/marketing-wunderkind.md +14 -0
  8. package/agents/operations-lead.md +15 -0
  9. package/agents/product-wunderkind.md +15 -0
  10. package/agents/qa-specialist.md +14 -0
  11. package/dist/agents/brand-builder.d.ts.map +1 -1
  12. package/dist/agents/brand-builder.js +17 -3
  13. package/dist/agents/brand-builder.js.map +1 -1
  14. package/dist/agents/ciso.d.ts.map +1 -1
  15. package/dist/agents/ciso.js +24 -1
  16. package/dist/agents/ciso.js.map +1 -1
  17. package/dist/agents/creative-director.d.ts.map +1 -1
  18. package/dist/agents/creative-director.js +15 -1
  19. package/dist/agents/creative-director.js.map +1 -1
  20. package/dist/agents/fullstack-wunderkind.d.ts.map +1 -1
  21. package/dist/agents/fullstack-wunderkind.js +17 -1
  22. package/dist/agents/fullstack-wunderkind.js.map +1 -1
  23. package/dist/agents/marketing-wunderkind.d.ts.map +1 -1
  24. package/dist/agents/marketing-wunderkind.js +15 -1
  25. package/dist/agents/marketing-wunderkind.js.map +1 -1
  26. package/dist/agents/operations-lead.d.ts.map +1 -1
  27. package/dist/agents/operations-lead.js +16 -1
  28. package/dist/agents/operations-lead.js.map +1 -1
  29. package/dist/agents/product-wunderkind.d.ts.map +1 -1
  30. package/dist/agents/product-wunderkind.js +16 -1
  31. package/dist/agents/product-wunderkind.js.map +1 -1
  32. package/dist/agents/qa-specialist.d.ts.map +1 -1
  33. package/dist/agents/qa-specialist.js +15 -1
  34. package/dist/agents/qa-specialist.js.map +1 -1
  35. package/dist/cli/cli-installer.d.ts.map +1 -1
  36. package/dist/cli/cli-installer.js +48 -4
  37. package/dist/cli/cli-installer.js.map +1 -1
  38. package/dist/cli/config-manager/index.d.ts +5 -3
  39. package/dist/cli/config-manager/index.d.ts.map +1 -1
  40. package/dist/cli/config-manager/index.js +160 -59
  41. package/dist/cli/config-manager/index.js.map +1 -1
  42. package/dist/cli/gitignore-manager.d.ts +8 -0
  43. package/dist/cli/gitignore-manager.d.ts.map +1 -0
  44. package/dist/cli/gitignore-manager.js +57 -0
  45. package/dist/cli/gitignore-manager.js.map +1 -0
  46. package/dist/cli/index.js +85 -9
  47. package/dist/cli/index.js.map +1 -1
  48. package/dist/cli/memory-commands.d.ts +3 -0
  49. package/dist/cli/memory-commands.d.ts.map +1 -0
  50. package/dist/cli/memory-commands.js +138 -0
  51. package/dist/cli/memory-commands.js.map +1 -0
  52. package/dist/cli/tui-installer.d.ts +2 -1
  53. package/dist/cli/tui-installer.d.ts.map +1 -1
  54. package/dist/cli/tui-installer.js +385 -18
  55. package/dist/cli/tui-installer.js.map +1 -1
  56. package/dist/cli/types.d.ts +43 -0
  57. package/dist/cli/types.d.ts.map +1 -1
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +26 -6
  60. package/dist/index.js.map +1 -1
  61. package/dist/memory/adapters/file.d.ts +21 -0
  62. package/dist/memory/adapters/file.d.ts.map +1 -0
  63. package/dist/memory/adapters/file.js +232 -0
  64. package/dist/memory/adapters/file.js.map +1 -0
  65. package/dist/memory/adapters/mem0.d.ts +37 -0
  66. package/dist/memory/adapters/mem0.d.ts.map +1 -0
  67. package/dist/memory/adapters/mem0.js +171 -0
  68. package/dist/memory/adapters/mem0.js.map +1 -0
  69. package/dist/memory/adapters/sqlite.d.ts +21 -0
  70. package/dist/memory/adapters/sqlite.d.ts.map +1 -0
  71. package/dist/memory/adapters/sqlite.js +198 -0
  72. package/dist/memory/adapters/sqlite.js.map +1 -0
  73. package/dist/memory/adapters/stub.d.ts +20 -0
  74. package/dist/memory/adapters/stub.d.ts.map +1 -0
  75. package/dist/memory/adapters/stub.js +58 -0
  76. package/dist/memory/adapters/stub.js.map +1 -0
  77. package/dist/memory/adapters/types.d.ts +45 -0
  78. package/dist/memory/adapters/types.d.ts.map +1 -0
  79. package/dist/memory/adapters/types.js +2 -0
  80. package/dist/memory/adapters/types.js.map +1 -0
  81. package/dist/memory/adapters/vector.d.ts +29 -0
  82. package/dist/memory/adapters/vector.d.ts.map +1 -0
  83. package/dist/memory/adapters/vector.js +347 -0
  84. package/dist/memory/adapters/vector.js.map +1 -0
  85. package/dist/memory/docker.d.ts +9 -0
  86. package/dist/memory/docker.d.ts.map +1 -0
  87. package/dist/memory/docker.js +43 -0
  88. package/dist/memory/docker.js.map +1 -0
  89. package/dist/memory/format.d.ts +5 -0
  90. package/dist/memory/format.d.ts.map +1 -0
  91. package/dist/memory/format.js +41 -0
  92. package/dist/memory/format.js.map +1 -0
  93. package/dist/memory/index.d.ts +19 -0
  94. package/dist/memory/index.d.ts.map +1 -0
  95. package/dist/memory/index.js +183 -0
  96. package/dist/memory/index.js.map +1 -0
  97. package/dist/memory/slug.d.ts +2 -0
  98. package/dist/memory/slug.d.ts.map +1 -0
  99. package/dist/memory/slug.js +40 -0
  100. package/dist/memory/slug.js.map +1 -0
  101. package/dist/memory/tools.d.ts +3 -0
  102. package/dist/memory/tools.d.ts.map +1 -0
  103. package/dist/memory/tools.js +84 -0
  104. package/dist/memory/tools.js.map +1 -0
  105. package/package.json +13 -3
  106. package/skills/memory-manager/SKILL.md +48 -0
@@ -0,0 +1,183 @@
1
+ import path from "node:path";
2
+ import { homedir } from "node:os";
3
+ import { existsSync } from "node:fs";
4
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
5
+ import { parse } from "jsonc-parser";
6
+ import { zip as fflateZip, unzip as fflateUnzip, strToU8, strFromU8 } from "fflate";
7
+ import { FileAdapter } from "./adapters/file.js";
8
+ import { Mem0Adapter } from "./adapters/mem0.js";
9
+ import { SqliteAdapter } from "./adapters/sqlite.js";
10
+ import { StubAdapter } from "./adapters/stub.js";
11
+ import { VectorAdapter } from "./adapters/vector.js";
12
+ import { generateSlug } from "./format.js";
13
+ import { deriveProjectSlug } from "./slug.js";
14
+ async function loadAdapter(projectDir) {
15
+ const legacyConfigPath = path.join(projectDir, "wunderkind.config.jsonc");
16
+ const projectConfigPath = path.join(projectDir, ".wunderkind", "wunderkind.config.jsonc");
17
+ const globalConfigPath = path.join(homedir(), ".wunderkind", "wunderkind.config.jsonc");
18
+ if (existsSync(legacyConfigPath)) {
19
+ throw new Error("Legacy config found at project root. Move it to .wunderkind/wunderkind.config.jsonc");
20
+ }
21
+ let config = {};
22
+ try {
23
+ config = { ...config, ...parse(await readFile(globalConfigPath, "utf-8")) };
24
+ }
25
+ catch { /* no global config */ }
26
+ try {
27
+ config = { ...config, ...parse(await readFile(projectConfigPath, "utf-8")) };
28
+ }
29
+ catch { /* no project config */ }
30
+ const projectSlug = deriveProjectSlug(projectDir);
31
+ const adapter = config.memoryAdapter ?? "file";
32
+ if (adapter === "file")
33
+ return new FileAdapter(projectDir);
34
+ if (adapter === "sqlite") {
35
+ return new SqliteAdapter(path.join(projectDir, ".wunderkind", "memory.db"));
36
+ }
37
+ if (adapter === "mem0") {
38
+ return new Mem0Adapter({
39
+ url: config.mem0Url ?? "http://localhost:8000",
40
+ projectSlug,
41
+ ...(config.mem0LlmProvider ? { llmProvider: config.mem0LlmProvider } : {}),
42
+ ...(config.mem0LlmModel ? { llmModel: config.mem0LlmModel } : {}),
43
+ ...(config.mem0LlmBaseUrl ? { llmBaseUrl: config.mem0LlmBaseUrl } : {}),
44
+ ...(config.mem0EmbedProvider ? { embedProvider: config.mem0EmbedProvider } : {}),
45
+ ...(config.mem0EmbedModel ? { embedModel: config.mem0EmbedModel } : {}),
46
+ ...(config.mem0EmbedDims ? { embedDims: config.mem0EmbedDims } : {}),
47
+ ...(config.mem0EmbedBaseUrl ? { embedBaseUrl: config.mem0EmbedBaseUrl } : {}),
48
+ ...(config.mem0VectorStore ? { vectorStore: config.mem0VectorStore } : {}),
49
+ ...(config.mem0VectorStoreHost ? { vectorStoreHost: config.mem0VectorStoreHost } : {}),
50
+ ...(config.mem0VectorStorePort ? { vectorStorePort: config.mem0VectorStorePort } : {}),
51
+ ...(config.mem0VectorStoreCollection ? { vectorStoreCollection: config.mem0VectorStoreCollection } : {}),
52
+ });
53
+ }
54
+ if (adapter === "vector") {
55
+ return new VectorAdapter({
56
+ qdrantUrl: config.qdrantUrl ?? "http://localhost:6333",
57
+ model: config.vectorEmbedModel ?? "Xenova/all-MiniLM-L6-v2",
58
+ vectorSize: config.vectorSize ?? 384,
59
+ collectionName: config.vectorCollection ?? "wunderkind-memories",
60
+ projectSlug,
61
+ ...(config.vectorCacheDir ? { cacheDir: config.vectorCacheDir } : {}),
62
+ });
63
+ }
64
+ return new StubAdapter();
65
+ }
66
+ export async function takeNote(projectDir, agent, note, options) {
67
+ const adapter = await loadAdapter(projectDir);
68
+ const entry = {
69
+ agent,
70
+ slug: options?.slug ?? generateSlug(note),
71
+ content: note,
72
+ createdAt: Date.now(),
73
+ pinned: options?.pin ?? false,
74
+ metadata: {},
75
+ };
76
+ return adapter.write(agent, entry);
77
+ }
78
+ export async function searchMemories(projectDir, agent, query) {
79
+ const adapter = await loadAdapter(projectDir);
80
+ return adapter.search(agent, query);
81
+ }
82
+ export async function countMemories(projectDir, agent) {
83
+ const adapter = await loadAdapter(projectDir);
84
+ return adapter.count(agent);
85
+ }
86
+ export async function analyzeStaleMemories(projectDir, agent) {
87
+ const adapter = await loadAdapter(projectDir);
88
+ return adapter.analyzeStale(agent);
89
+ }
90
+ export async function pruneMemories(projectDir, agent, idsToRemove) {
91
+ const adapter = await loadAdapter(projectDir);
92
+ return adapter.prune(agent, idsToRemove);
93
+ }
94
+ export async function memoryStatus(projectDir) {
95
+ const adapter = await loadAdapter(projectDir);
96
+ return adapter.status();
97
+ }
98
+ export async function exportMemories(projectDir, outputPath) {
99
+ const adapter = await loadAdapter(projectDir);
100
+ const agents = await adapter.listAgents();
101
+ const allEntries = [];
102
+ const fileMap = {};
103
+ for (const agent of agents) {
104
+ const entries = await adapter.read(agent);
105
+ allEntries.push(...entries);
106
+ const agentContent = entries
107
+ .map((entry) => `## [${entry.slug}]\n\nid: ${entry.id}\n\n${entry.content}\n\n---\n`)
108
+ .join("\n");
109
+ fileMap[`agents/${agent}.md`] = strToU8(agentContent);
110
+ }
111
+ const projectSlug = deriveProjectSlug(projectDir);
112
+ const manifest = {
113
+ version: "1",
114
+ exportedAt: Date.now(),
115
+ projectSlug,
116
+ adapter: "file",
117
+ agents,
118
+ totalEntries: allEntries.length,
119
+ };
120
+ fileMap["manifest.json"] = strToU8(JSON.stringify(manifest, null, 2));
121
+ fileMap["entries.json"] = strToU8(JSON.stringify(allEntries));
122
+ const zipBytes = await new Promise((resolve, reject) => {
123
+ fflateZip(fileMap, { level: 6 }, (err, data) => {
124
+ if (err)
125
+ reject(err);
126
+ else
127
+ resolve(data);
128
+ });
129
+ });
130
+ const finalPath = outputPath ?? path.join(projectDir, ".wunderkind", "exports", `${Date.now()}.zip`);
131
+ await mkdir(path.dirname(finalPath), { recursive: true });
132
+ await writeFile(finalPath, zipBytes);
133
+ return finalPath;
134
+ }
135
+ export async function importMemories(projectDir, zipPath, strategy) {
136
+ const zipBytes = new Uint8Array(await readFile(zipPath));
137
+ const files = await new Promise((resolve, reject) => {
138
+ fflateUnzip(zipBytes, (err, data) => {
139
+ if (err)
140
+ reject(err);
141
+ else
142
+ resolve(data);
143
+ });
144
+ });
145
+ const entriesRaw = files["entries.json"];
146
+ if (!entriesRaw)
147
+ throw new Error("Invalid zip: missing entries.json");
148
+ const allEntries = JSON.parse(strFromU8(entriesRaw));
149
+ const adapter = await loadAdapter(projectDir);
150
+ let imported = 0;
151
+ let skipped = 0;
152
+ const uniqueAgents = Array.from(new Set(allEntries.map((e) => e.agent)));
153
+ if (strategy === "overwrite") {
154
+ for (const agent of uniqueAgents) {
155
+ await adapter.deleteAll(agent);
156
+ }
157
+ for (const entry of allEntries) {
158
+ const { id: _id, ...rest } = entry;
159
+ await adapter.write(entry.agent, rest);
160
+ imported += 1;
161
+ }
162
+ }
163
+ else {
164
+ const existingSlugs = new Map();
165
+ for (const agent of uniqueAgents) {
166
+ const existing = await adapter.read(agent);
167
+ existingSlugs.set(agent, new Set(existing.map((e) => e.slug)));
168
+ }
169
+ for (const entry of allEntries) {
170
+ const agentSlugs = existingSlugs.get(entry.agent);
171
+ if (agentSlugs?.has(entry.slug)) {
172
+ skipped += 1;
173
+ }
174
+ else {
175
+ const { id: _id, ...rest } = entry;
176
+ await adapter.write(entry.agent, rest);
177
+ imported += 1;
178
+ }
179
+ }
180
+ }
181
+ return { imported, skipped };
182
+ }
183
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function deriveProjectSlug(projectDir: string): string;
2
+ //# sourceMappingURL=slug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slug.d.ts","sourceRoot":"","sources":["../../src/memory/slug.ts"],"names":[],"mappings":"AAGA,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAwC5D"}
@@ -0,0 +1,40 @@
1
+ import { readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ export function deriveProjectSlug(projectDir) {
4
+ let packageName;
5
+ try {
6
+ const content = readFileSync(path.join(projectDir, "package.json"), "utf8");
7
+ const pkg = JSON.parse(content);
8
+ if (typeof pkg.name === "string") {
9
+ packageName = pkg.name;
10
+ }
11
+ }
12
+ catch (err) {
13
+ if (err.code !== "ENOENT") {
14
+ throw err;
15
+ }
16
+ }
17
+ if (packageName) {
18
+ const sanitised = packageName
19
+ .toLowerCase()
20
+ .replace(/[^a-z0-9-]/g, "-")
21
+ .replace(/-+/g, "-")
22
+ .replace(/^-|-$/g, "")
23
+ .slice(0, 63);
24
+ if (sanitised.length > 0) {
25
+ return sanitised;
26
+ }
27
+ }
28
+ const dirname = path.basename(projectDir);
29
+ const sanitised = dirname
30
+ .toLowerCase()
31
+ .replace(/[^a-z0-9-]/g, "-")
32
+ .replace(/-+/g, "-")
33
+ .replace(/^-|-$/g, "")
34
+ .slice(0, 63);
35
+ if (sanitised.length > 0) {
36
+ return sanitised;
37
+ }
38
+ return "wunderkind-project";
39
+ }
40
+ //# sourceMappingURL=slug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slug.js","sourceRoot":"","sources":["../../src/memory/slug.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,MAAM,UAAU,iBAAiB,CAAC,UAAkB;IAClD,IAAI,WAA+B,CAAA;IACnC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAA;QAC3E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC/B,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACjC,WAAW,GAAG,GAAG,CAAC,IAAI,CAAA;QACxB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,SAAS,GAAG,WAAW;aAC1B,WAAW,EAAE;aACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;aAC3B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;aACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;aACrB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAEf,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;IACzC,MAAM,SAAS,GAAG,OAAO;SACtB,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEf,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO,oBAAoB,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from "@opencode-ai/plugin/dist/tool.js";
2
+ export declare function createMemoryTools(): Record<string, ToolDefinition>;
3
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/memory/tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,kCAAkC,CAAA;AASnF,wBAAgB,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAyFlE"}
@@ -0,0 +1,84 @@
1
+ import { tool } from "@opencode-ai/plugin/dist/tool.js";
2
+ import { analyzeStaleMemories, countMemories, pruneMemories, searchMemories, takeNote, } from "./index.js";
3
+ export function createMemoryTools() {
4
+ return {
5
+ wunderkind_take_note: tool({
6
+ description: "Save a note to your persistent memory. Use this to remember project-specific facts, decisions, patterns, and preferences for future sessions.",
7
+ args: {
8
+ note: tool.schema.string().describe("The content to remember"),
9
+ slug: tool.schema
10
+ .string()
11
+ .optional()
12
+ .describe("Short identifier slug (auto-generated if omitted)"),
13
+ pin: tool.schema
14
+ .boolean()
15
+ .optional()
16
+ .describe("Pin this memory so it is never pruned by reduce_noise"),
17
+ },
18
+ async execute(args, context) {
19
+ const options = {};
20
+ if (args.slug !== undefined)
21
+ options.slug = args.slug;
22
+ if (args.pin !== undefined)
23
+ options.pin = args.pin;
24
+ const entry = await takeNote(context.directory, context.agent, args.note, options);
25
+ return `Memory saved [${entry.slug}] (id: ${entry.id})`;
26
+ },
27
+ }),
28
+ wunderkind_search_memories: tool({
29
+ description: "Search your persistent memory for relevant past knowledge. Returns the most relevant memories for your query.",
30
+ args: {
31
+ query: tool.schema.string().describe("What to search for"),
32
+ },
33
+ async execute(args, context) {
34
+ const results = await searchMemories(context.directory, context.agent, args.query);
35
+ if (results.length === 0)
36
+ return "No memories found matching your query.";
37
+ return results
38
+ .map((e) => `[${e.slug}] ${e.content}${e.pinned ? " (pinned)" : ""}`)
39
+ .join("\n\n");
40
+ },
41
+ }),
42
+ wunderkind_count_memories: tool({
43
+ description: "Get a count and summary of your persistent memories.",
44
+ args: {},
45
+ async execute(_args, context) {
46
+ const stats = await countMemories(context.directory, context.agent);
47
+ if (stats.total === 0)
48
+ return "No memories stored yet.";
49
+ const oldest = stats.oldest > 0 ? new Date(stats.oldest).toISOString().split("T")[0] : "—";
50
+ const newest = stats.newest > 0 ? new Date(stats.newest).toISOString().split("T")[0] : "—";
51
+ return `Total: ${stats.total} | Pinned: ${stats.pinned} | Oldest: ${oldest} | Newest: ${newest}`;
52
+ },
53
+ }),
54
+ wunderkind_reduce_noise: tool({
55
+ description: "Analyze your memories for stale entries. Without confirm=true, shows what would be removed. With confirm=true, removes the stale entries.",
56
+ args: {
57
+ confirm: tool.schema
58
+ .boolean()
59
+ .optional()
60
+ .describe("Set to true to actually remove stale memories. Omit or false to preview only."),
61
+ },
62
+ async execute(args, context) {
63
+ const analysis = await analyzeStaleMemories(context.directory, context.agent);
64
+ if (analysis.stale === 0) {
65
+ return `All ${analysis.toKeep.length} memories are current. Nothing to prune.`;
66
+ }
67
+ const preview = analysis.toDrop
68
+ .map((e) => ` - [${e.slug}] ${e.content.slice(0, 80)}...`)
69
+ .join("\n");
70
+ if (!args.confirm) {
71
+ return [
72
+ `Found ${analysis.stale} stale memories to remove (${analysis.pinned} pinned, ${analysis.recent} recent kept):`,
73
+ preview,
74
+ "",
75
+ "Call wunderkind_reduce_noise with confirm=true to proceed.",
76
+ ].join("\n");
77
+ }
78
+ const removed = await pruneMemories(context.directory, context.agent, analysis.toDrop.map((e) => e.id));
79
+ return `Pruned ${removed} memories. Kept ${analysis.toKeep.length} (${analysis.pinned} pinned, ${analysis.recent} recent).`;
80
+ },
81
+ }),
82
+ };
83
+ }
84
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/memory/tools.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grant-vine/wunderkind",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Wunderkind — a generic oh-my-opencode addon package with specialist agents for any software product team",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -26,13 +26,20 @@
26
26
  "scripts": {
27
27
  "build": "tsc && bun run dist/build-agents.js",
28
28
  "dev": "tsc --watch",
29
- "prepublishOnly": "bun run build"
29
+ "prepublishOnly": "bun run build",
30
+ "test": "bun test tests/unit/",
31
+ "test:contract": "bun test tests/",
32
+ "bench": "bun run tests/perf/adapter-benchmark.ts"
30
33
  },
31
34
  "dependencies": {
32
35
  "@clack/prompts": "^0.9.1",
36
+ "@huggingface/transformers": "^3.8.1",
33
37
  "@opencode-ai/plugin": "^1.2.18",
38
+ "@qdrant/js-client-rest": "^1.17.0",
34
39
  "commander": "^13.1.0",
40
+ "fflate": "^0.8.2",
35
41
  "jsonc-parser": "^3.3.1",
42
+ "mem0ai": "^2.2.4",
36
43
  "oh-my-opencode": "^3.10.0",
37
44
  "picocolors": "^1.1.1"
38
45
  },
@@ -52,5 +59,8 @@
52
59
  "repository": {
53
60
  "type": "git",
54
61
  "url": "https://github.com/grant-vine/wunderkind"
55
- }
62
+ },
63
+ "trustedDependencies": [
64
+ "onnxruntime-node"
65
+ ]
56
66
  }
@@ -0,0 +1,48 @@
1
+ # Memory Manager — Wunderkind
2
+
3
+ You have access to four persistent memory tools. Use them to build project knowledge over time.
4
+
5
+ ## Tools
6
+
7
+ ### `wunderkind_take_note`
8
+ Save a fact, decision, or pattern to your persistent memory.
9
+ - `note` (required): what to remember
10
+ - `slug` (optional): short identifier
11
+ - `pin` (optional): true = never auto-pruned
12
+
13
+ Use when you learn something project-specific: a convention, a constraint, a team decision, a recurring pattern.
14
+
15
+ ### `wunderkind_search_memories`
16
+ Find past knowledge relevant to your current task.
17
+ - `query` (required): what to look for
18
+
19
+ Use at the start of a task to check what you already know about the domain.
20
+
21
+ ### `wunderkind_count_memories`
22
+ Get a summary of your stored memories (count, oldest, newest, pinned count).
23
+
24
+ Use to understand the state of your memory before deciding to prune.
25
+
26
+ ### `wunderkind_reduce_noise`
27
+ Analyze and optionally prune stale memories.
28
+ - `confirm` (optional): false = preview only (default), true = actually prune
29
+
30
+ Memories older than 30 days that are not pinned are considered stale. Always preview first, then ask the user before confirming.
31
+
32
+ ## When to Use Memory
33
+
34
+ - **Start of task**: call `wunderkind_search_memories` with the task domain to surface relevant past knowledge
35
+ - **After learning**: call `wunderkind_take_note` to preserve new project facts
36
+ - **Pin important facts**: security policies, architectural decisions, hard constraints → use `pin: true`
37
+ - **Periodic housekeeping**: run `wunderkind_reduce_noise` to review what can be dropped
38
+
39
+ ## Memory Lifecycle
40
+
41
+ 1. Agent learns a project fact
42
+ 2. Calls `wunderkind_take_note` → saved to `.wunderkind/memory/<agent>.md` (or DB if configured)
43
+ 3. Next session: calls `wunderkind_search_memories` → retrieves relevant knowledge
44
+ 4. Over time: calls `wunderkind_reduce_noise` → surfaces stale entries → user confirms pruning
45
+
46
+ ## Adapter Transparency
47
+
48
+ The memory system is adapter-agnostic. The configured adapter (`file`, `sqlite`, or `mem0`) is set in `wunderkind.config.jsonc`. You do not need to know which adapter is active — the tools behave identically.