@wipcomputer/memory-crystal 0.7.30 → 0.7.33

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 (114) hide show
  1. package/SKILL.md +1 -1
  2. package/cloud/wrangler.toml +30 -0
  3. package/dist/bulk-copy.js +1 -1
  4. package/dist/cc-hook.js +3 -3
  5. package/dist/cc-poller.js +2 -2
  6. package/dist/chunk-2GBYLMEF.js +1385 -0
  7. package/dist/chunk-437F27T6.js +97 -0
  8. package/dist/chunk-5I7GMRDN.js +146 -0
  9. package/dist/chunk-CGIDSAJB.js +288 -0
  10. package/dist/chunk-D3MACYZ4.js +108 -0
  11. package/dist/chunk-DFQ72B7M.js +248 -0
  12. package/dist/chunk-NX647OM3.js +310 -0
  13. package/dist/cli.js +62 -7
  14. package/dist/core.d.ts +22 -2
  15. package/dist/core.js +1 -1
  16. package/dist/crypto.js +2 -2
  17. package/dist/crystal-serve.js +3 -3
  18. package/dist/doctor.js +12 -4
  19. package/dist/dream-weaver.js +2 -2
  20. package/dist/file-sync.js +3 -3
  21. package/dist/installer.js +99 -3
  22. package/dist/ldm.js +1 -1
  23. package/dist/llm-XXLYPIOF.js +16 -0
  24. package/dist/mcp-server.js +17 -5
  25. package/dist/migrate.js +1 -1
  26. package/dist/mirror-sync.js +4 -4
  27. package/dist/mlx-setup-XKU67WCT.js +289 -0
  28. package/dist/openclaw.js +16 -5
  29. package/dist/pair.js +2 -2
  30. package/dist/poller.js +5 -5
  31. package/dist/role.js +2 -2
  32. package/dist/search-pipeline-CBV25NX7.js +99 -0
  33. package/dist/staging.js +2 -2
  34. package/package.json +15 -1
  35. package/.env.example +0 -20
  36. package/.publish-skill.json +0 -1
  37. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/.env.example +0 -20
  38. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/.publish-skill.json +0 -1
  39. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/CHANGELOG.md +0 -1297
  40. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/CLA.md +0 -19
  41. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/LICENSE +0 -52
  42. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/README-ENTERPRISE.md +0 -226
  43. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/README.md +0 -151
  44. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/RELAY.md +0 -199
  45. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/SKILL.md +0 -462
  46. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/TECHNICAL.md +0 -656
  47. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-23.md +0 -48
  48. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-25.md +0 -24
  49. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-26.md +0 -7
  50. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-28.md +0 -31
  51. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-29.md +0 -28
  52. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-4.md +0 -64
  53. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-5.md +0 -19
  54. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/cloud/README.md +0 -116
  55. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/cloud/docs/gpt-system-instructions.md +0 -69
  56. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/cloud/migrations/0001_init.sql +0 -52
  57. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/migrations/0001_init.sql +0 -51
  58. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/migrations/0002_cloud_storage.sql +0 -49
  59. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/openclaw.plugin.json +0 -11
  60. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/package-lock.json +0 -4169
  61. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/package.json +0 -61
  62. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/scripts/crystal-capture.sh +0 -29
  63. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/scripts/deploy-cloud.sh +0 -153
  64. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/scripts/ldm-backup.sh +0 -116
  65. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/scripts/migrate-lance-to-sqlite.mjs +0 -218
  66. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/skills/memory/SKILL.md +0 -438
  67. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/wrangler-demo.toml +0 -8
  68. package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/wrangler-mcp.toml +0 -24
  69. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/.env.example +0 -20
  70. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/.publish-skill.json +0 -1
  71. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/CHANGELOG.md +0 -1297
  72. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/CLA.md +0 -19
  73. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/LICENSE +0 -52
  74. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/README-ENTERPRISE.md +0 -226
  75. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/README.md +0 -151
  76. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/RELAY.md +0 -199
  77. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/RELEASE-NOTES-v0.7.30.md +0 -29
  78. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/SKILL.md +0 -462
  79. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/TECHNICAL.md +0 -656
  80. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-23.md +0 -48
  81. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-25.md +0 -24
  82. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-26.md +0 -7
  83. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-28.md +0 -31
  84. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-29.md +0 -28
  85. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-4.md +0 -64
  86. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-5.md +0 -19
  87. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/cloud/README.md +0 -116
  88. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/cloud/docs/gpt-system-instructions.md +0 -69
  89. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/cloud/migrations/0001_init.sql +0 -52
  90. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/migrations/0001_init.sql +0 -51
  91. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/migrations/0002_cloud_storage.sql +0 -49
  92. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/openclaw.plugin.json +0 -11
  93. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/package-lock.json +0 -4169
  94. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/package.json +0 -61
  95. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/scripts/crystal-capture.sh +0 -29
  96. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/scripts/deploy-cloud.sh +0 -153
  97. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/scripts/ldm-backup.sh +0 -116
  98. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/scripts/migrate-lance-to-sqlite.mjs +0 -218
  99. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/skills/memory/SKILL.md +0 -438
  100. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/wrangler-demo.toml +0 -8
  101. package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/wrangler-mcp.toml +0 -24
  102. package/CHANGELOG.md +0 -1329
  103. package/README-ENTERPRISE.md +0 -226
  104. package/RELAY.md +0 -199
  105. package/_trash/RELEASE-NOTES-v0-7-23.md +0 -48
  106. package/_trash/RELEASE-NOTES-v0-7-25.md +0 -24
  107. package/_trash/RELEASE-NOTES-v0-7-26.md +0 -7
  108. package/_trash/RELEASE-NOTES-v0-7-28.md +0 -31
  109. package/_trash/RELEASE-NOTES-v0-7-29.md +0 -28
  110. package/_trash/RELEASE-NOTES-v0-7-4.md +0 -64
  111. package/_trash/RELEASE-NOTES-v0-7-5.md +0 -19
  112. package/_trash/RELEASE-NOTES-v0.7.30.md +0 -29
  113. package/wrangler-demo.toml +0 -8
  114. package/wrangler-mcp.toml +0 -24
@@ -0,0 +1,289 @@
1
+ // src/mlx-setup.ts
2
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
3
+ import { execSync } from "child_process";
4
+ import { join } from "path";
5
+ import { homedir } from "os";
6
+ var HOME = homedir();
7
+ var MLX_PORT = 18791;
8
+ var MLX_MODEL = "mlx-community/Qwen2.5-3B-Instruct-4bit";
9
+ var MLX_STATE_FILE = join(HOME, ".ldm", "state", "mlx-server.json");
10
+ var MLX_PLIST_LABEL = "ai.ldm.mlx-server";
11
+ var MLX_PLIST_PATH = join(HOME, "Library", "LaunchAgents", `${MLX_PLIST_LABEL}.plist`);
12
+ var MLX_LOG_PATH = "/tmp/mlx-server.log";
13
+ function detectPlatform() {
14
+ const platform = process.platform;
15
+ const arch = process.arch;
16
+ if (platform === "darwin") {
17
+ return arch === "arm64" ? "apple-silicon" : "intel-mac";
18
+ }
19
+ if (platform === "linux") return "linux";
20
+ return "other";
21
+ }
22
+ function canRunMlx() {
23
+ return detectPlatform() === "apple-silicon";
24
+ }
25
+ function findPython() {
26
+ const candidates = ["python3", "/opt/homebrew/bin/python3", "/usr/local/bin/python3"];
27
+ for (const cmd of candidates) {
28
+ try {
29
+ const version = execSync(`${cmd} --version 2>&1`, { encoding: "utf-8", timeout: 5e3 }).trim();
30
+ const match = version.match(/Python (\d+)\.(\d+)/);
31
+ if (match && parseInt(match[1]) >= 3 && parseInt(match[2]) >= 10) {
32
+ const realPath = execSync(`which ${cmd} 2>/dev/null`, { encoding: "utf-8", timeout: 3e3 }).trim();
33
+ return realPath || cmd;
34
+ }
35
+ } catch {
36
+ }
37
+ }
38
+ return null;
39
+ }
40
+ function findInstaller() {
41
+ try {
42
+ execSync("uv --version 2>/dev/null", { encoding: "utf-8", timeout: 3e3 });
43
+ return "uv";
44
+ } catch {
45
+ }
46
+ try {
47
+ execSync("pip3 --version 2>/dev/null", { encoding: "utf-8", timeout: 3e3 });
48
+ return "pip3";
49
+ } catch {
50
+ }
51
+ return null;
52
+ }
53
+ function isMlxLmInstalled() {
54
+ try {
55
+ execSync('python3 -c "import mlx_lm" 2>/dev/null', { timeout: 5e3 });
56
+ return true;
57
+ } catch {
58
+ return false;
59
+ }
60
+ }
61
+ function installMlxLm(steps) {
62
+ const installer = findInstaller();
63
+ if (!installer) {
64
+ steps.push("No pip3 or uv found. Cannot install mlx-lm.");
65
+ return false;
66
+ }
67
+ const cmd = installer === "uv" ? "uv pip install mlx-lm" : "pip3 install mlx-lm";
68
+ steps.push(`Installing mlx-lm via ${installer}...`);
69
+ try {
70
+ execSync(cmd, { encoding: "utf-8", timeout: 12e4, stdio: "pipe" });
71
+ steps.push("mlx-lm installed successfully.");
72
+ return true;
73
+ } catch (err) {
74
+ if (installer === "pip3") {
75
+ try {
76
+ execSync("pip3 install --user mlx-lm", { encoding: "utf-8", timeout: 12e4, stdio: "pipe" });
77
+ steps.push("mlx-lm installed (--user) successfully.");
78
+ return true;
79
+ } catch {
80
+ }
81
+ }
82
+ steps.push(`mlx-lm install failed: ${err.message.slice(0, 200)}`);
83
+ return false;
84
+ }
85
+ }
86
+ function isServerRunning() {
87
+ try {
88
+ const state = loadState();
89
+ const port = state?.port || MLX_PORT;
90
+ execSync(`curl -s -o /dev/null -w "%{http_code}" http://localhost:${port}/v1/models`, {
91
+ encoding: "utf-8",
92
+ timeout: 3e3
93
+ });
94
+ return true;
95
+ } catch {
96
+ return false;
97
+ }
98
+ }
99
+ function createLaunchAgent(pythonPath, steps) {
100
+ const plist = `<?xml version="1.0" encoding="UTF-8"?>
101
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
102
+ <plist version="1.0">
103
+ <dict>
104
+ <key>Label</key>
105
+ <string>${MLX_PLIST_LABEL}</string>
106
+ <key>ProgramArguments</key>
107
+ <array>
108
+ <string>${pythonPath}</string>
109
+ <string>-m</string>
110
+ <string>mlx_lm.server</string>
111
+ <string>--model</string>
112
+ <string>${MLX_MODEL}</string>
113
+ <string>--port</string>
114
+ <string>${MLX_PORT}</string>
115
+ </array>
116
+ <key>RunAtLoad</key>
117
+ <true/>
118
+ <key>KeepAlive</key>
119
+ <true/>
120
+ <key>StandardOutPath</key>
121
+ <string>${MLX_LOG_PATH}</string>
122
+ <key>StandardErrorPath</key>
123
+ <string>${MLX_LOG_PATH}</string>
124
+ </dict>
125
+ </plist>`;
126
+ try {
127
+ writeFileSync(MLX_PLIST_PATH, plist);
128
+ execSync(`launchctl load "${MLX_PLIST_PATH}" 2>/dev/null`, { timeout: 5e3 });
129
+ steps.push(`LaunchAgent installed at ${MLX_PLIST_PATH}`);
130
+ steps.push(`MLX server will start on port ${MLX_PORT}`);
131
+ return true;
132
+ } catch (err) {
133
+ steps.push(`LaunchAgent install failed: ${err.message}`);
134
+ return false;
135
+ }
136
+ }
137
+ function startServer(steps) {
138
+ try {
139
+ execSync(`launchctl kickstart -kp gui/$(id -u)/${MLX_PLIST_LABEL} 2>/dev/null`, { timeout: 1e4 });
140
+ steps.push("MLX server started.");
141
+ return true;
142
+ } catch {
143
+ steps.push("MLX server start failed. Check /tmp/mlx-server.log");
144
+ return false;
145
+ }
146
+ }
147
+ function stopServer() {
148
+ try {
149
+ execSync(`launchctl unload "${MLX_PLIST_PATH}" 2>/dev/null`, { timeout: 5e3 });
150
+ return true;
151
+ } catch {
152
+ return false;
153
+ }
154
+ }
155
+ function loadState() {
156
+ try {
157
+ if (existsSync(MLX_STATE_FILE)) {
158
+ return JSON.parse(readFileSync(MLX_STATE_FILE, "utf-8"));
159
+ }
160
+ } catch {
161
+ }
162
+ return null;
163
+ }
164
+ function saveState(state) {
165
+ const dir = join(HOME, ".ldm", "state");
166
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
167
+ writeFileSync(MLX_STATE_FILE, JSON.stringify(state, null, 2) + "\n");
168
+ }
169
+ async function verifyServer(steps) {
170
+ const state = loadState();
171
+ const port = state?.port || MLX_PORT;
172
+ for (let i = 0; i < 15; i++) {
173
+ try {
174
+ const resp = await fetch(`http://localhost:${port}/v1/models`, {
175
+ signal: AbortSignal.timeout(2e3)
176
+ });
177
+ if (resp.ok) {
178
+ const data = await resp.json();
179
+ const model = data?.data?.[0]?.id || "unknown";
180
+ steps.push(`MLX server verified: ${model} on port ${port}`);
181
+ return true;
182
+ }
183
+ } catch {
184
+ }
185
+ await new Promise((r) => setTimeout(r, 2e3));
186
+ }
187
+ steps.push("MLX server did not respond within 30 seconds. Check /tmp/mlx-server.log");
188
+ return false;
189
+ }
190
+ async function setupMlx(options) {
191
+ const steps = [];
192
+ const platform = detectPlatform();
193
+ if (platform !== "apple-silicon") {
194
+ steps.push(`Platform: ${platform}. MLX requires Apple Silicon. Skipping.`);
195
+ return { ok: false, steps };
196
+ }
197
+ steps.push("Platform: Apple Silicon detected.");
198
+ const pythonPath = findPython();
199
+ if (!pythonPath) {
200
+ steps.push("Python 3.10+ not found. Install via: brew install python3");
201
+ return { ok: false, steps };
202
+ }
203
+ steps.push(`Python: ${pythonPath}`);
204
+ if (!isMlxLmInstalled()) {
205
+ if (!options?.yes) {
206
+ steps.push("mlx-lm not installed. Run with --yes to auto-install, or: pip3 install mlx-lm");
207
+ return { ok: false, steps };
208
+ }
209
+ const installed = installMlxLm(steps);
210
+ if (!installed) return { ok: false, steps };
211
+ } else {
212
+ steps.push("mlx-lm: already installed.");
213
+ }
214
+ if (!existsSync(MLX_PLIST_PATH)) {
215
+ const created = createLaunchAgent(pythonPath, steps);
216
+ if (!created) return { ok: false, steps };
217
+ } else {
218
+ steps.push("LaunchAgent: already installed.");
219
+ }
220
+ saveState({
221
+ installed: true,
222
+ port: MLX_PORT,
223
+ model: MLX_MODEL,
224
+ pythonPath,
225
+ installedAt: (/* @__PURE__ */ new Date()).toISOString()
226
+ });
227
+ if (!isServerRunning()) {
228
+ startServer(steps);
229
+ steps.push(`Waiting for model to load (~1.5 GB on first run)...`);
230
+ const verified = await verifyServer(steps);
231
+ if (!verified) {
232
+ steps.push("Server started but not yet responding. It may still be downloading the model.");
233
+ steps.push(`Check: tail -f ${MLX_LOG_PATH}`);
234
+ }
235
+ } else {
236
+ steps.push(`MLX server: already running on port ${MLX_PORT}`);
237
+ }
238
+ return { ok: true, steps };
239
+ }
240
+ function doctorCheck() {
241
+ const platform = detectPlatform();
242
+ if (platform !== "apple-silicon") {
243
+ return { status: "skip", detail: `${platform} (MLX requires Apple Silicon)` };
244
+ }
245
+ const state = loadState();
246
+ if (!state || !state.installed) {
247
+ return {
248
+ status: "warn",
249
+ detail: "not installed",
250
+ fix: "crystal init (will offer MLX setup)"
251
+ };
252
+ }
253
+ if (isServerRunning()) {
254
+ return { status: "ok", detail: `running on port ${state.port} (${state.model})` };
255
+ }
256
+ if (existsSync(MLX_PLIST_PATH)) {
257
+ return {
258
+ status: "warn",
259
+ detail: "installed but not running",
260
+ fix: `launchctl kickstart -kp gui/$(id -u)/${MLX_PLIST_LABEL}`
261
+ };
262
+ }
263
+ return {
264
+ status: "warn",
265
+ detail: "installed but LaunchAgent missing",
266
+ fix: "crystal init (will recreate LaunchAgent)"
267
+ };
268
+ }
269
+ var MLX_CONFIG = {
270
+ port: MLX_PORT,
271
+ model: MLX_MODEL,
272
+ plistPath: MLX_PLIST_PATH,
273
+ logPath: MLX_LOG_PATH,
274
+ stateFile: MLX_STATE_FILE
275
+ };
276
+ export {
277
+ MLX_CONFIG,
278
+ canRunMlx,
279
+ createLaunchAgent,
280
+ detectPlatform,
281
+ doctorCheck,
282
+ installMlxLm,
283
+ isMlxLmInstalled,
284
+ isServerRunning,
285
+ setupMlx,
286
+ startServer,
287
+ stopServer,
288
+ verifyServer
289
+ };
package/dist/openclaw.js CHANGED
@@ -1,21 +1,32 @@
1
1
  import {
2
2
  Crystal,
3
3
  resolveConfig
4
- } from "./chunk-FBQWSDPC.js";
4
+ } from "./chunk-2GBYLMEF.js";
5
5
  import {
6
6
  ensureLdm,
7
7
  resolveStatePath,
8
8
  stateWritePath
9
- } from "./chunk-EXEZZADG.js";
9
+ } from "./chunk-DFQ72B7M.js";
10
10
 
11
11
  // src/dev-update.ts
12
12
  import { execSync } from "child_process";
13
13
  import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
14
14
  import { join, basename } from "path";
15
15
  var HOME = process.env.HOME || "";
16
- var STAFF_DIR = join(HOME, "Documents", "wipcomputer--mac-mini-01", "staff");
17
- var CC_REPOS = join(STAFF_DIR, "Parker", "Claude Code - Mini", "repos");
18
- var LESA_REPOS = join(STAFF_DIR, "L\u0113sa", "repos");
16
+ function resolveWorkspace() {
17
+ const configPath = join(HOME, ".ldm", "config.json");
18
+ if (existsSync(configPath)) {
19
+ try {
20
+ const config = JSON.parse(readFileSync(configPath, "utf-8"));
21
+ if (config.workspace) return config.workspace;
22
+ } catch {
23
+ }
24
+ }
25
+ return join(HOME, "wipcomputerinc");
26
+ }
27
+ var TEAM_DIR = join(resolveWorkspace(), "team");
28
+ var CC_REPOS = join(TEAM_DIR, "cc-mini", "repos");
29
+ var LESA_REPOS = join(TEAM_DIR, "L\u0113sa", "repos");
19
30
  var DEV_UPDATES_DIR = join(CC_REPOS, "wip-dev-updates");
20
31
  var LAST_RUN_PATH = resolveStatePath("dev-update-last-run.json");
21
32
  function loadLastRun() {
package/dist/pair.js CHANGED
@@ -4,8 +4,8 @@ import {
4
4
  encodePairingString,
5
5
  generateRelayKey,
6
6
  loadRelayKey
7
- } from "./chunk-KCQUXVYT.js";
8
- import "./chunk-EXEZZADG.js";
7
+ } from "./chunk-D3MACYZ4.js";
8
+ import "./chunk-DFQ72B7M.js";
9
9
 
10
10
  // src/pair.ts
11
11
  import { existsSync, writeFileSync, mkdirSync, chmodSync } from "fs";
package/dist/poller.js CHANGED
@@ -3,28 +3,28 @@ import {
3
3
  ensureStaging,
4
4
  isNewAgent,
5
5
  markReady
6
- } from "./chunk-ZCQYHTNU.js";
6
+ } from "./chunk-5I7GMRDN.js";
7
7
  import {
8
8
  generateSessionSummary,
9
9
  writeSummaryFile
10
10
  } from "./chunk-Y72C7F6O.js";
11
11
  import {
12
12
  pushFileSync
13
- } from "./chunk-3G3SFYYI.js";
13
+ } from "./chunk-CGIDSAJB.js";
14
14
  import {
15
15
  Crystal,
16
16
  resolveConfig
17
- } from "./chunk-FBQWSDPC.js";
17
+ } from "./chunk-2GBYLMEF.js";
18
18
  import {
19
19
  decryptJSON,
20
20
  encryptJSON,
21
21
  loadRelayKey
22
- } from "./chunk-KCQUXVYT.js";
22
+ } from "./chunk-D3MACYZ4.js";
23
23
  import {
24
24
  ensureLdm,
25
25
  resolveStatePath,
26
26
  stateWritePath
27
- } from "./chunk-EXEZZADG.js";
27
+ } from "./chunk-DFQ72B7M.js";
28
28
 
29
29
  // src/poller.ts
30
30
  import { readFileSync, writeFileSync, appendFileSync, existsSync, mkdirSync } from "fs";
package/dist/role.js CHANGED
@@ -3,8 +3,8 @@ import {
3
3
  detectRole,
4
4
  loadRoleState,
5
5
  promoteToCore
6
- } from "./chunk-3S6TI23B.js";
7
- import "./chunk-EXEZZADG.js";
6
+ } from "./chunk-437F27T6.js";
7
+ import "./chunk-DFQ72B7M.js";
8
8
  export {
9
9
  demoteToNode,
10
10
  detectRole,
@@ -0,0 +1,99 @@
1
+ import {
2
+ detectProvider,
3
+ expandQuery,
4
+ rerankResults
5
+ } from "./chunk-NX647OM3.js";
6
+
7
+ // src/search-pipeline.ts
8
+ var STRONG_SIGNAL_MIN_SCORE = 0.85;
9
+ var STRONG_SIGNAL_MIN_GAP = 0.15;
10
+ var DEFAULT_CANDIDATE_LIMIT = 40;
11
+ async function deepSearch(crystal, query, options = {}) {
12
+ const limit = options.limit || 5;
13
+ const candidateLimit = options.candidateLimit || DEFAULT_CANDIDATE_LIMIT;
14
+ const intent = options.intent;
15
+ const filter = options.filter;
16
+ const explain = options.explain || false;
17
+ const provider = await detectProvider();
18
+ if (provider.provider === "none") {
19
+ return crystal.search(query, limit, filter);
20
+ }
21
+ const db = crystal.sqliteDb;
22
+ if (!db) return crystal.search(query, limit, filter);
23
+ const sinceDate = filter?.since ? crystal.parseSince(filter.since) : void 0;
24
+ const untilDate = filter?.until ? crystal.parseSince(filter.until) : void 0;
25
+ const internalFilter = { ...filter, sinceDate, untilDate };
26
+ const initialFts = crystal.searchFTS(query, 20, internalFilter);
27
+ const topScore = initialFts[0]?.score ?? 0;
28
+ const secondScore = initialFts[1]?.score ?? 0;
29
+ const hasStrongSignal = !intent && initialFts.length > 0 && topScore >= STRONG_SIGNAL_MIN_SCORE && topScore - secondScore >= STRONG_SIGNAL_MIN_GAP;
30
+ const expanded = hasStrongSignal ? [] : await expandQuery(query, intent);
31
+ const allResultLists = [];
32
+ if (initialFts.length > 0) allResultLists.push(initialFts);
33
+ const [queryEmbedding] = await crystal.embed([query]);
34
+ const originalVec = crystal.searchVec(queryEmbedding, 30, internalFilter);
35
+ if (originalVec.length > 0) allResultLists.push(originalVec);
36
+ for (const variation of expanded) {
37
+ if (variation.type === "lex") {
38
+ const ftsResults = crystal.searchFTS(variation.text, 20, internalFilter);
39
+ if (ftsResults.length > 0) allResultLists.push(ftsResults);
40
+ } else {
41
+ const [embedding] = await crystal.embed([variation.text]);
42
+ const vecResults = crystal.searchVec(embedding, 20, internalFilter);
43
+ if (vecResults.length > 0) allResultLists.push(vecResults);
44
+ }
45
+ }
46
+ const weights = allResultLists.map((_, i) => i < 2 ? 2 : 1);
47
+ const fused = crystal.reciprocalRankFusion(allResultLists, weights);
48
+ const candidates = fused.slice(0, candidateLimit);
49
+ if (candidates.length === 0) return [];
50
+ const ftsScoreMap = /* @__PURE__ */ new Map();
51
+ const vecScoreMap = /* @__PURE__ */ new Map();
52
+ if (explain) {
53
+ for (const r of initialFts) ftsScoreMap.set(r.text.slice(0, 200), r.score);
54
+ for (const r of originalVec) vecScoreMap.set(r.text.slice(0, 200), r.score);
55
+ }
56
+ const passages = candidates.map((c) => c.text.slice(0, 500));
57
+ const rerankQuery = intent ? `${intent}: ${query}` : query;
58
+ const reranked = await rerankResults(rerankQuery, passages);
59
+ const now = Date.now();
60
+ const blended = reranked.map((r) => {
61
+ const candidate = candidates[r.index];
62
+ if (!candidate) return null;
63
+ const rrfRank = r.index + 1;
64
+ let rrfWeight;
65
+ if (rrfRank <= 3) rrfWeight = 0.75;
66
+ else if (rrfRank <= 10) rrfWeight = 0.6;
67
+ else rrfWeight = 0.4;
68
+ const rrfScore = 1 / rrfRank;
69
+ const blendedScore = rrfWeight * rrfScore + (1 - rrfWeight) * r.score;
70
+ const ageDays = candidate.created_at ? (now - new Date(candidate.created_at).getTime()) / 864e5 : 0;
71
+ const recency = candidate.created_at ? crystal.recencyWeight(ageDays) : 1;
72
+ const finalScore = blendedScore * recency;
73
+ const freshness = candidate.created_at ? crystal.freshnessLabel(ageDays) : void 0;
74
+ const result = {
75
+ ...candidate,
76
+ score: finalScore,
77
+ freshness
78
+ };
79
+ if (explain) {
80
+ const dedup = candidate.text.slice(0, 200);
81
+ result.explain = {
82
+ fts_score: ftsScoreMap.get(dedup),
83
+ vec_score: vecScoreMap.get(dedup),
84
+ rrf_rank: rrfRank,
85
+ rrf_score: rrfScore,
86
+ rerank_score: r.score,
87
+ recency_weight: recency,
88
+ final_score: finalScore
89
+ };
90
+ }
91
+ return result;
92
+ }).filter((r) => r !== null);
93
+ const sorted = blended.sort((a, b) => b.score - a.score).slice(0, limit);
94
+ const topNormScore = sorted[0]?.score || 1;
95
+ return sorted.map((r) => ({ ...r, score: Math.min(r.score / topNormScore * 0.95, 0.95) }));
96
+ }
97
+ export {
98
+ deepSearch
99
+ };
package/dist/staging.js CHANGED
@@ -7,8 +7,8 @@ import {
7
7
  processAllStaged,
8
8
  processStagedAgent,
9
9
  stagingPaths
10
- } from "./chunk-ZCQYHTNU.js";
11
- import "./chunk-EXEZZADG.js";
10
+ } from "./chunk-5I7GMRDN.js";
11
+ import "./chunk-DFQ72B7M.js";
12
12
  export {
13
13
  ensureStaging,
14
14
  hasStagedData,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/memory-crystal",
3
- "version": "0.7.30",
3
+ "version": "0.7.33",
4
4
  "description": "Sovereign memory system — local-first with ephemeral encrypted relay. Your memory, your machine, your rules.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,7 +17,21 @@
17
17
  "crystal": "dist/cli.js",
18
18
  "crystal-mcp": "dist/mcp-server.js"
19
19
  },
20
+ "files": [
21
+ "dist/",
22
+ "scripts/",
23
+ "skills/",
24
+ "migrations/",
25
+ "cloud/",
26
+ "openclaw.plugin.json",
27
+ "SKILL.md",
28
+ "TECHNICAL.md",
29
+ "README.md",
30
+ "LICENSE",
31
+ "CLA.md"
32
+ ],
20
33
  "scripts": {
34
+ "prepublishOnly": "npm run build",
21
35
  "build": "tsup src/core.ts src/cli.ts src/mcp-server.ts src/openclaw.ts src/migrate.ts src/cc-hook.ts src/cc-poller.ts src/crypto.ts src/pair.ts src/poller.ts src/mirror-sync.ts src/file-sync.ts src/ldm.ts src/summarize.ts src/role.ts src/doctor.ts src/bridge.ts src/discover.ts src/bulk-copy.ts src/oc-backfill.ts src/dream-weaver.ts src/crystal-serve.ts src/staging.ts src/installer.ts --format esm --dts --outDir dist && tsup src/worker.ts --format esm --outDir dist --no-dts && cp scripts/crystal-capture.sh scripts/ldm-backup.sh dist/",
22
36
  "build:local": "tsup src/core.ts src/cli.ts src/mcp-server.ts src/openclaw.ts src/migrate.ts src/cc-hook.ts src/cc-poller.ts src/crypto.ts src/pair.ts src/poller.ts src/mirror-sync.ts src/file-sync.ts src/ldm.ts src/summarize.ts src/role.ts src/doctor.ts src/bridge.ts src/discover.ts src/bulk-copy.ts src/oc-backfill.ts src/dream-weaver.ts src/crystal-serve.ts src/staging.ts src/installer.ts --format esm --dts --outDir dist",
23
37
  "build:worker": "tsup src/worker.ts --format esm --outDir dist --no-dts",
package/.env.example DELETED
@@ -1,20 +0,0 @@
1
- # Memory Crystal — Environment Config
2
- # Copy to ~/.openclaw/memory-crystal/.env and fill in your keys.
3
- # Or skip this and use 1Password (keys auto-resolve from "Agent Secrets" vault).
4
-
5
- # Embedding provider: openai (default), ollama, or google
6
- # CRYSTAL_EMBEDDING_PROVIDER=openai
7
-
8
- # OpenAI (required if provider is openai)
9
- OPENAI_API_KEY=sk-...
10
-
11
- # Google (required if provider is google)
12
- # GOOGLE_API_KEY=AIza...
13
-
14
- # Ollama (only if provider is ollama — runs locally, no key needed)
15
- # CRYSTAL_OLLAMA_HOST=http://localhost:11434
16
- # CRYSTAL_OLLAMA_MODEL=nomic-embed-text
17
-
18
- # Cloud mirror (Phase 2)
19
- # CRYSTAL_REMOTE_URL=https://memory-crystal.your-worker.workers.dev
20
- # CRYSTAL_REMOTE_TOKEN=your-token
@@ -1 +0,0 @@
1
- { "name": "wip-memory-crystal" }
@@ -1,20 +0,0 @@
1
- # Memory Crystal — Environment Config
2
- # Copy to ~/.openclaw/memory-crystal/.env and fill in your keys.
3
- # Or skip this and use 1Password (keys auto-resolve from "Agent Secrets" vault).
4
-
5
- # Embedding provider: openai (default), ollama, or google
6
- # CRYSTAL_EMBEDDING_PROVIDER=openai
7
-
8
- # OpenAI (required if provider is openai)
9
- OPENAI_API_KEY=sk-...
10
-
11
- # Google (required if provider is google)
12
- # GOOGLE_API_KEY=AIza...
13
-
14
- # Ollama (only if provider is ollama — runs locally, no key needed)
15
- # CRYSTAL_OLLAMA_HOST=http://localhost:11434
16
- # CRYSTAL_OLLAMA_MODEL=nomic-embed-text
17
-
18
- # Cloud mirror (Phase 2)
19
- # CRYSTAL_REMOTE_URL=https://memory-crystal.your-worker.workers.dev
20
- # CRYSTAL_REMOTE_TOKEN=your-token
@@ -1 +0,0 @@
1
- { "name": "wip-memory-crystal" }