@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.
- package/SKILL.md +1 -1
- package/cloud/wrangler.toml +30 -0
- package/dist/bulk-copy.js +1 -1
- package/dist/cc-hook.js +3 -3
- package/dist/cc-poller.js +2 -2
- package/dist/chunk-2GBYLMEF.js +1385 -0
- package/dist/chunk-437F27T6.js +97 -0
- package/dist/chunk-5I7GMRDN.js +146 -0
- package/dist/chunk-CGIDSAJB.js +288 -0
- package/dist/chunk-D3MACYZ4.js +108 -0
- package/dist/chunk-DFQ72B7M.js +248 -0
- package/dist/chunk-NX647OM3.js +310 -0
- package/dist/cli.js +62 -7
- package/dist/core.d.ts +22 -2
- package/dist/core.js +1 -1
- package/dist/crypto.js +2 -2
- package/dist/crystal-serve.js +3 -3
- package/dist/doctor.js +12 -4
- package/dist/dream-weaver.js +2 -2
- package/dist/file-sync.js +3 -3
- package/dist/installer.js +99 -3
- package/dist/ldm.js +1 -1
- package/dist/llm-XXLYPIOF.js +16 -0
- package/dist/mcp-server.js +17 -5
- package/dist/migrate.js +1 -1
- package/dist/mirror-sync.js +4 -4
- package/dist/mlx-setup-XKU67WCT.js +289 -0
- package/dist/openclaw.js +16 -5
- package/dist/pair.js +2 -2
- package/dist/poller.js +5 -5
- package/dist/role.js +2 -2
- package/dist/search-pipeline-CBV25NX7.js +99 -0
- package/dist/staging.js +2 -2
- package/package.json +15 -1
- package/.env.example +0 -20
- package/.publish-skill.json +0 -1
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/.env.example +0 -20
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/.publish-skill.json +0 -1
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/CHANGELOG.md +0 -1297
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/CLA.md +0 -19
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/LICENSE +0 -52
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/README-ENTERPRISE.md +0 -226
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/README.md +0 -151
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/RELAY.md +0 -199
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/SKILL.md +0 -462
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/TECHNICAL.md +0 -656
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-23.md +0 -48
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-25.md +0 -24
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-26.md +0 -7
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-28.md +0 -31
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-29.md +0 -28
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-4.md +0 -64
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/_trash/RELEASE-NOTES-v0-7-5.md +0 -19
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/cloud/README.md +0 -116
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/cloud/docs/gpt-system-instructions.md +0 -69
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/cloud/migrations/0001_init.sql +0 -52
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/migrations/0001_init.sql +0 -51
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/migrations/0002_cloud_storage.sql +0 -49
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/openclaw.plugin.json +0 -11
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/package-lock.json +0 -4169
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/package.json +0 -61
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/scripts/crystal-capture.sh +0 -29
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/scripts/deploy-cloud.sh +0 -153
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/scripts/ldm-backup.sh +0 -116
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/scripts/migrate-lance-to-sqlite.mjs +0 -218
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/skills/memory/SKILL.md +0 -438
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/wrangler-demo.toml +0 -8
- package/.worktrees/memory-crystal-private--cc-mini-fix-home-fallback/wrangler-mcp.toml +0 -24
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/.env.example +0 -20
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/.publish-skill.json +0 -1
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/CHANGELOG.md +0 -1297
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/CLA.md +0 -19
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/LICENSE +0 -52
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/README-ENTERPRISE.md +0 -226
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/README.md +0 -151
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/RELAY.md +0 -199
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/RELEASE-NOTES-v0.7.30.md +0 -29
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/SKILL.md +0 -462
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/TECHNICAL.md +0 -656
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-23.md +0 -48
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-25.md +0 -24
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-26.md +0 -7
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-28.md +0 -31
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-29.md +0 -28
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-4.md +0 -64
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/_trash/RELEASE-NOTES-v0-7-5.md +0 -19
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/cloud/README.md +0 -116
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/cloud/docs/gpt-system-instructions.md +0 -69
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/cloud/migrations/0001_init.sql +0 -52
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/migrations/0001_init.sql +0 -51
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/migrations/0002_cloud_storage.sql +0 -49
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/openclaw.plugin.json +0 -11
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/package-lock.json +0 -4169
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/package.json +0 -61
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/scripts/crystal-capture.sh +0 -29
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/scripts/deploy-cloud.sh +0 -153
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/scripts/ldm-backup.sh +0 -116
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/scripts/migrate-lance-to-sqlite.mjs +0 -218
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/skills/memory/SKILL.md +0 -438
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/wrangler-demo.toml +0 -8
- package/.worktrees/memory-crystal-private--cc-mini-release-notes-v0.7.30/wrangler-mcp.toml +0 -24
- package/CHANGELOG.md +0 -1329
- package/README-ENTERPRISE.md +0 -226
- package/RELAY.md +0 -199
- package/_trash/RELEASE-NOTES-v0-7-23.md +0 -48
- package/_trash/RELEASE-NOTES-v0-7-25.md +0 -24
- package/_trash/RELEASE-NOTES-v0-7-26.md +0 -7
- package/_trash/RELEASE-NOTES-v0-7-28.md +0 -31
- package/_trash/RELEASE-NOTES-v0-7-29.md +0 -28
- package/_trash/RELEASE-NOTES-v0-7-4.md +0 -64
- package/_trash/RELEASE-NOTES-v0-7-5.md +0 -19
- package/_trash/RELEASE-NOTES-v0.7.30.md +0 -29
- package/wrangler-demo.toml +0 -8
- package/wrangler-mcp.toml +0 -24
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
Crystal,
|
|
4
4
|
createCrystal,
|
|
5
5
|
resolveConfig
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2GBYLMEF.js";
|
|
7
7
|
import {
|
|
8
8
|
deployBackupScript,
|
|
9
9
|
ensureLdm,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
installCron,
|
|
13
13
|
ldmPaths,
|
|
14
14
|
removeCron
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-DFQ72B7M.js";
|
|
16
16
|
|
|
17
17
|
// src/cli.ts
|
|
18
18
|
import { existsSync, copyFileSync, symlinkSync, lstatSync, unlinkSync, readFileSync, readdirSync, statSync } from "fs";
|
|
@@ -23,7 +23,7 @@ var USAGE = `
|
|
|
23
23
|
crystal \u2014 Sovereign memory system
|
|
24
24
|
|
|
25
25
|
Commands:
|
|
26
|
-
crystal search <query> [-n limit] [--agent <id>] [--since <time>] [--
|
|
26
|
+
crystal search <query> [-n limit] [--agent <id>] [--since <time>] [--until <date>] [--intent <context>] [--candidates <n>] [--explain] [--provider <openai|ollama|google>]
|
|
27
27
|
crystal remember <text> [--category fact|preference|event|opinion|skill]
|
|
28
28
|
crystal forget <id>
|
|
29
29
|
crystal status [--provider <openai|ollama|google>]
|
|
@@ -43,6 +43,10 @@ Commands:
|
|
|
43
43
|
crystal backup setup Install daily backup (LaunchAgent, 03:00)
|
|
44
44
|
crystal backup --keep <n> Keep last n backups (default: 7)
|
|
45
45
|
|
|
46
|
+
crystal mlx setup [--yes] Install MLX local LLM (Apple Silicon only)
|
|
47
|
+
crystal mlx status Show MLX server status
|
|
48
|
+
crystal mlx stop Stop MLX server
|
|
49
|
+
|
|
46
50
|
crystal bridge setup Install + register Bridge MCP server
|
|
47
51
|
crystal bridge status Show Bridge install state
|
|
48
52
|
|
|
@@ -71,11 +75,24 @@ async function main() {
|
|
|
71
75
|
console.log(USAGE);
|
|
72
76
|
process.exit(0);
|
|
73
77
|
}
|
|
78
|
+
if (args[0] === "--version" || args[0] === "-v") {
|
|
79
|
+
try {
|
|
80
|
+
const { readFileSync: readFileSync2 } = await import("fs");
|
|
81
|
+
const { dirname, join: join2 } = await import("path");
|
|
82
|
+
const { fileURLToPath } = await import("url");
|
|
83
|
+
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
84
|
+
const pkg = JSON.parse(readFileSync2(join2(thisDir, "..", "package.json"), "utf-8"));
|
|
85
|
+
console.log(pkg.version);
|
|
86
|
+
} catch {
|
|
87
|
+
console.log("unknown");
|
|
88
|
+
}
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
74
91
|
const command = args[0];
|
|
75
92
|
const flags = {};
|
|
76
93
|
let positional = [];
|
|
77
94
|
for (let i = 1; i < args.length; i++) {
|
|
78
|
-
if (args[i] === "--dry-run" || args[i] === "--yes" || args[i] === "-y" || args[i] === "--skip-discover" || args[i] === "--include-secrets" || args[i] === "--deep" || args[i] === "--core" || args[i] === "--node" || args[i] === "--update") {
|
|
95
|
+
if (args[i] === "--dry-run" || args[i] === "--yes" || args[i] === "-y" || args[i] === "--skip-discover" || args[i] === "--include-secrets" || args[i] === "--deep" || args[i] === "--core" || args[i] === "--node" || args[i] === "--update" || args[i] === "--explain") {
|
|
79
96
|
flags[args[i].replace(/^-+/, "")] = "true";
|
|
80
97
|
} else if (args[i].startsWith("--") || args[i] === "-n") {
|
|
81
98
|
const key = args[i].replace(/^-+/, "");
|
|
@@ -156,7 +173,7 @@ ${fails === 0 && warns === 0 ? "All checks passed." : `${fails} failures, ${warn
|
|
|
156
173
|
console.log("Backup LaunchAgent installed.");
|
|
157
174
|
console.log(` Runs daily at 03:00`);
|
|
158
175
|
console.log(` Plist: ${plistPath}`);
|
|
159
|
-
console.log(` Log: /
|
|
176
|
+
console.log(` Log: ~/.ldm/logs/ldm-backup.log`);
|
|
160
177
|
} catch (err) {
|
|
161
178
|
console.error(`Setup failed: ${err.message}`);
|
|
162
179
|
process.exit(1);
|
|
@@ -295,6 +312,36 @@ Resuming capture cron...`);
|
|
|
295
312
|
}
|
|
296
313
|
return;
|
|
297
314
|
}
|
|
315
|
+
if (command === "mlx") {
|
|
316
|
+
const subCmd = positional[0] || "status";
|
|
317
|
+
const { setupMlx, isServerRunning, stopServer, doctorCheck, MLX_CONFIG } = await import("./mlx-setup-XKU67WCT.js");
|
|
318
|
+
if (subCmd === "setup") {
|
|
319
|
+
const yes = "yes" in flags || "y" in flags;
|
|
320
|
+
const result = await setupMlx({ yes });
|
|
321
|
+
for (const step of result.steps) {
|
|
322
|
+
console.log(` ${result.ok ? "[OK]" : "[!!]"} ${step}`);
|
|
323
|
+
}
|
|
324
|
+
if (!result.ok) process.exit(1);
|
|
325
|
+
} else if (subCmd === "status") {
|
|
326
|
+
const check = doctorCheck();
|
|
327
|
+
const icon = check.status === "ok" ? "[OK]" : check.status === "warn" ? "[!!]" : "[XX]";
|
|
328
|
+
console.log(`MLX LLM: ${icon} ${check.detail}`);
|
|
329
|
+
if (check.fix) console.log(` Fix: ${check.fix}`);
|
|
330
|
+
console.log(` Port: ${MLX_CONFIG.port}`);
|
|
331
|
+
console.log(` Model: ${MLX_CONFIG.model}`);
|
|
332
|
+
console.log(` Log: ${MLX_CONFIG.logPath}`);
|
|
333
|
+
} else if (subCmd === "stop") {
|
|
334
|
+
if (stopServer()) {
|
|
335
|
+
console.log("MLX server stopped.");
|
|
336
|
+
} else {
|
|
337
|
+
console.log("MLX server was not running.");
|
|
338
|
+
}
|
|
339
|
+
} else {
|
|
340
|
+
console.error(`Unknown mlx subcommand: ${subCmd}. Use: setup, status, stop`);
|
|
341
|
+
process.exit(1);
|
|
342
|
+
}
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
298
345
|
if (command === "bridge") {
|
|
299
346
|
const { isBridgeInstalled, isBridgeRegistered, registerBridgeMcp, registerBridgeDesktop, isBridgeDesktopRegistered } = await import("./bridge.js");
|
|
300
347
|
const subCmd = positional[0] || "status";
|
|
@@ -371,7 +418,11 @@ Resuming capture cron...`);
|
|
|
371
418
|
const filter = {};
|
|
372
419
|
if (flags.agent) filter.agent_id = flags.agent;
|
|
373
420
|
if (flags.since) filter.since = flags.since;
|
|
374
|
-
|
|
421
|
+
if (flags.until) filter.until = flags.until;
|
|
422
|
+
const intent = flags.intent;
|
|
423
|
+
const candidateLimit = flags.candidates ? parseInt(flags.candidates, 10) : void 0;
|
|
424
|
+
const explainMode = "explain" in flags;
|
|
425
|
+
const results = await crystal.deepSearch(query, limit, filter, { intent, candidateLimit, explain: explainMode });
|
|
375
426
|
if (results.length === 0) {
|
|
376
427
|
console.log("No results found.");
|
|
377
428
|
} else {
|
|
@@ -383,6 +434,10 @@ Resuming capture cron...`);
|
|
|
383
434
|
const fresh = r.freshness ? `${icon[r.freshness]} ${r.freshness}, ` : "";
|
|
384
435
|
console.log(`[${i + 1}] (${fresh}${score}% match, ${r.agent_id}, ${date}, ${r.role})`);
|
|
385
436
|
console.log(r.text.slice(0, 300) + (r.text.length > 300 ? "..." : ""));
|
|
437
|
+
if (explainMode && r.explain) {
|
|
438
|
+
const e = r.explain;
|
|
439
|
+
console.log(` explain: fts=${e.fts_score?.toFixed(3) || "n/a"} vec=${e.vec_score?.toFixed(3) || "n/a"} rrf_rank=${e.rrf_rank} rerank=${e.rerank_score.toFixed(3)} recency=${e.recency_weight.toFixed(3)} final=${e.final_score.toFixed(4)}`);
|
|
440
|
+
}
|
|
386
441
|
console.log("---");
|
|
387
442
|
}
|
|
388
443
|
}
|
|
@@ -832,7 +887,7 @@ Backfill summary:`);
|
|
|
832
887
|
(dry run, no embeddings created)`);
|
|
833
888
|
return;
|
|
834
889
|
}
|
|
835
|
-
let role = "
|
|
890
|
+
let role = "core";
|
|
836
891
|
try {
|
|
837
892
|
const { detectRole } = await import("./role.js");
|
|
838
893
|
role = detectRole().role;
|
package/dist/core.d.ts
CHANGED
|
@@ -65,6 +65,11 @@ interface SearchResult {
|
|
|
65
65
|
created_at: string;
|
|
66
66
|
freshness?: "fresh" | "recent" | "aging" | "stale";
|
|
67
67
|
}
|
|
68
|
+
/** Pre-expanded query for unified search API. Skip LLM expansion when you know what you want. */
|
|
69
|
+
interface StructuredQuery {
|
|
70
|
+
type: 'lex' | 'vec' | 'hyde';
|
|
71
|
+
text: string;
|
|
72
|
+
}
|
|
68
73
|
interface CrystalStatus {
|
|
69
74
|
chunks: number;
|
|
70
75
|
memories: number;
|
|
@@ -149,13 +154,28 @@ declare class Crystal {
|
|
|
149
154
|
agent_id?: string;
|
|
150
155
|
source_type?: string;
|
|
151
156
|
since?: string;
|
|
157
|
+
until?: string;
|
|
152
158
|
}): Promise<SearchResult[]>;
|
|
153
159
|
/** Deep search: query expansion + LLM re-ranking + position-aware blending.
|
|
154
|
-
* Falls back to standard search if no LLM provider is available.
|
|
160
|
+
* Falls back to standard search if no LLM provider is available.
|
|
161
|
+
* Supports intent disambiguation, candidateLimit tuning, and explain traces. */
|
|
155
162
|
deepSearch(query: string, limit?: number, filter?: {
|
|
156
163
|
agent_id?: string;
|
|
157
164
|
source_type?: string;
|
|
158
165
|
since?: string;
|
|
166
|
+
until?: string;
|
|
167
|
+
}, options?: {
|
|
168
|
+
intent?: string;
|
|
169
|
+
candidateLimit?: number;
|
|
170
|
+
explain?: boolean;
|
|
171
|
+
}): Promise<SearchResult[]>;
|
|
172
|
+
/** Structured search: pass pre-expanded queries to skip LLM expansion.
|
|
173
|
+
* Each query is typed (lex, vec, hyde) and searched independently, then fused with RRF. */
|
|
174
|
+
structuredSearch(queries: StructuredQuery[], limit?: number, filter?: {
|
|
175
|
+
agent_id?: string;
|
|
176
|
+
source_type?: string;
|
|
177
|
+
since?: string;
|
|
178
|
+
until?: string;
|
|
159
179
|
}): Promise<SearchResult[]>;
|
|
160
180
|
/** Vector search via sqlite-vec. Two-step pattern: MATCH first, then JOIN. */
|
|
161
181
|
private searchVec;
|
|
@@ -229,4 +249,4 @@ declare class RemoteCrystal {
|
|
|
229
249
|
/** Create the appropriate Crystal instance based on config. */
|
|
230
250
|
declare function createCrystal(config: CrystalConfig): Crystal | RemoteCrystal;
|
|
231
251
|
|
|
232
|
-
export { type Chunk, Crystal, type CrystalConfig, type CrystalStatus, type ExportedChunk, type Memory, RemoteCrystal, type SearchResult, type SourceCollection, type SourceFile, type SourcesStatus, type SyncResult, createCrystal, resolveConfig };
|
|
252
|
+
export { type Chunk, Crystal, type CrystalConfig, type CrystalStatus, type ExportedChunk, type Memory, RemoteCrystal, type SearchResult, type SourceCollection, type SourceFile, type SourcesStatus, type StructuredQuery, type SyncResult, createCrystal, resolveConfig };
|
package/dist/core.js
CHANGED
package/dist/crypto.js
CHANGED
package/dist/crystal-serve.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ldmPaths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-DFQ72B7M.js";
|
|
5
5
|
|
|
6
6
|
// src/crystal-serve.ts
|
|
7
7
|
import { createServer } from "http";
|
|
@@ -158,12 +158,12 @@ function handleStatus(_req, res) {
|
|
|
158
158
|
} catch {
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
|
-
let role = "
|
|
161
|
+
let role = "core";
|
|
162
162
|
const rolePath = join(paths.state, "role.json");
|
|
163
163
|
if (existsSync(rolePath)) {
|
|
164
164
|
try {
|
|
165
165
|
const r = JSON.parse(readFileSync(rolePath, "utf-8"));
|
|
166
|
-
role = r.role || "
|
|
166
|
+
role = r.role || "core";
|
|
167
167
|
} catch {
|
|
168
168
|
}
|
|
169
169
|
}
|
package/dist/doctor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
detectRole
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-437F27T6.js";
|
|
4
4
|
import {
|
|
5
5
|
isBridgeInstalled,
|
|
6
6
|
isBridgeRegistered
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
ldmPaths,
|
|
10
10
|
resolveStatePath
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-DFQ72B7M.js";
|
|
12
12
|
|
|
13
13
|
// src/doctor.ts
|
|
14
14
|
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
@@ -35,6 +35,14 @@ async function runDoctor() {
|
|
|
35
35
|
checks.push(checkBridge());
|
|
36
36
|
checks.push(checkLdmDirectory(paths));
|
|
37
37
|
checks.push(checkPrivateMode());
|
|
38
|
+
try {
|
|
39
|
+
const { doctorCheck } = await import("./mlx-setup-XKU67WCT.js");
|
|
40
|
+
const mlx = doctorCheck();
|
|
41
|
+
if (mlx.status !== "skip") {
|
|
42
|
+
checks.push({ name: "MLX LLM", status: mlx.status, detail: mlx.detail, fix: mlx.fix });
|
|
43
|
+
}
|
|
44
|
+
} catch {
|
|
45
|
+
}
|
|
38
46
|
return checks;
|
|
39
47
|
}
|
|
40
48
|
function checkOpEmbeddings() {
|
|
@@ -202,8 +210,8 @@ function checkCaptureCron() {
|
|
|
202
210
|
};
|
|
203
211
|
}
|
|
204
212
|
function checkRelayConfig(role) {
|
|
205
|
-
if (role.role === "
|
|
206
|
-
return { name: "Relay", status: "ok", detail: "not needed (
|
|
213
|
+
if (role.role === "core" && !role.relayUrl) {
|
|
214
|
+
return { name: "Relay", status: "ok", detail: "not needed (core, no relay configured)" };
|
|
207
215
|
}
|
|
208
216
|
if (role.role === "node") {
|
|
209
217
|
if (!role.relayUrl) {
|
package/dist/dream-weaver.js
CHANGED
package/dist/file-sync.js
CHANGED
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
pullFileSync,
|
|
6
6
|
pushFileSync,
|
|
7
7
|
saveFileSyncState
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-CGIDSAJB.js";
|
|
9
|
+
import "./chunk-D3MACYZ4.js";
|
|
10
|
+
import "./chunk-DFQ72B7M.js";
|
|
11
11
|
export {
|
|
12
12
|
compareManifest,
|
|
13
13
|
generateManifest,
|
package/dist/installer.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
loadAgentConfig,
|
|
8
8
|
saveAgentConfig,
|
|
9
9
|
scaffoldLdm
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-DFQ72B7M.js";
|
|
11
11
|
|
|
12
12
|
// src/installer.ts
|
|
13
13
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, cpSync, copyFileSync, readdirSync, statSync } from "fs";
|
|
@@ -119,7 +119,7 @@ function detectInstallState() {
|
|
|
119
119
|
cronInstalled = crontab.includes("crystal-capture");
|
|
120
120
|
} catch {
|
|
121
121
|
}
|
|
122
|
-
const role = "
|
|
122
|
+
const role = "core";
|
|
123
123
|
const relayKeyExists = existsSync(join(LDM_ROOT, "secrets", "crystal-relay-key"));
|
|
124
124
|
return {
|
|
125
125
|
ldmExists: existsSync(LDM_ROOT),
|
|
@@ -385,7 +385,7 @@ function bootstrapLdmOs(steps) {
|
|
|
385
385
|
steps.push("LDM OS installed.");
|
|
386
386
|
return true;
|
|
387
387
|
} catch {
|
|
388
|
-
steps.push("LDM OS install skipped (npm offline or permissions issue). Using
|
|
388
|
+
steps.push("LDM OS install skipped (npm offline or permissions issue). Using core mode.");
|
|
389
389
|
return false;
|
|
390
390
|
}
|
|
391
391
|
}
|
|
@@ -599,6 +599,19 @@ async function runInstallOrUpdate(options) {
|
|
|
599
599
|
} catch (err) {
|
|
600
600
|
steps.push(`Backup script failed: ${err.message}`);
|
|
601
601
|
}
|
|
602
|
+
try {
|
|
603
|
+
const { canRunMlx, isMlxLmInstalled, isServerRunning } = await import("./mlx-setup-XKU67WCT.js");
|
|
604
|
+
if (canRunMlx()) {
|
|
605
|
+
if (isServerRunning()) {
|
|
606
|
+
steps.push("MLX LLM: already running");
|
|
607
|
+
} else if (isMlxLmInstalled()) {
|
|
608
|
+
steps.push("MLX LLM: installed but not running. Start with: launchctl kickstart -kp gui/$(id -u)/ai.ldm.mlx-server");
|
|
609
|
+
} else {
|
|
610
|
+
steps.push('MLX LLM: Apple Silicon detected. Run "crystal mlx setup" to install local LLM for free, fast, offline search quality.');
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
} catch {
|
|
614
|
+
}
|
|
602
615
|
if (!ldmDelegated && state.ocDetected) {
|
|
603
616
|
try {
|
|
604
617
|
const ocResult = deployToOpenClaw();
|
|
@@ -620,6 +633,24 @@ async function runInstallOrUpdate(options) {
|
|
|
620
633
|
steps.push(`OC MCP config failed: ${err.message}`);
|
|
621
634
|
}
|
|
622
635
|
}
|
|
636
|
+
if (!options.role && process.stdin.isTTY) {
|
|
637
|
+
const { createInterface } = await import("readline");
|
|
638
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
639
|
+
const answer = await new Promise((resolve) => {
|
|
640
|
+
rl.question("\n Is this your primary machine (always on), or adding a device?\n [1] Primary (Crystal Core)\n [2] Adding a device (Crystal Node)\n > ", resolve);
|
|
641
|
+
});
|
|
642
|
+
rl.close();
|
|
643
|
+
if (answer.trim() === "2") {
|
|
644
|
+
options.role = "node";
|
|
645
|
+
const rl2 = createInterface({ input: process.stdin, output: process.stdout });
|
|
646
|
+
options.pairCode = await new Promise((resolve) => {
|
|
647
|
+
rl2.question(' Pairing code from Core (run "crystal pair" on Core): ', resolve);
|
|
648
|
+
});
|
|
649
|
+
rl2.close();
|
|
650
|
+
} else {
|
|
651
|
+
options.role = "core";
|
|
652
|
+
}
|
|
653
|
+
}
|
|
623
654
|
if (options.role === "core") {
|
|
624
655
|
try {
|
|
625
656
|
const { promoteToCore } = await import("./role.js");
|
|
@@ -646,6 +677,71 @@ async function runInstallOrUpdate(options) {
|
|
|
646
677
|
steps.push(`Pairing failed: ${err.message}`);
|
|
647
678
|
}
|
|
648
679
|
}
|
|
680
|
+
if (options.role === "node" || process.env.CRYSTAL_RELAY_URL) {
|
|
681
|
+
const secretsDir = join(LDM_ROOT, "secrets");
|
|
682
|
+
const envPath = join(secretsDir, "crystal-relay.env");
|
|
683
|
+
if (!existsSync(envPath)) {
|
|
684
|
+
const relayUrl = "https://memory-crystal-relay.wipcomputer.workers.dev";
|
|
685
|
+
let token = "";
|
|
686
|
+
try {
|
|
687
|
+
const saTokenPath = join(OC_ROOT, "secrets", "op-sa-token");
|
|
688
|
+
if (existsSync(saTokenPath)) {
|
|
689
|
+
const saToken = readFileSync(saTokenPath, "utf8").trim();
|
|
690
|
+
token = execSync(
|
|
691
|
+
`OP_SERVICE_ACCOUNT_TOKEN=${saToken} op item get "Memory Crystal Relay Auth Tokens" --vault "Agent Secrets" --fields label=${agentId}-token --reveal 2>/dev/null`,
|
|
692
|
+
{ encoding: "utf8", timeout: 15e3 }
|
|
693
|
+
).trim();
|
|
694
|
+
}
|
|
695
|
+
} catch {
|
|
696
|
+
}
|
|
697
|
+
if (!token && process.stdin.isTTY) {
|
|
698
|
+
const { createInterface } = await import("readline");
|
|
699
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
700
|
+
token = await new Promise((resolve) => {
|
|
701
|
+
rl.question(" Relay auth token: ", resolve);
|
|
702
|
+
});
|
|
703
|
+
rl.close();
|
|
704
|
+
token = token.trim();
|
|
705
|
+
}
|
|
706
|
+
if (token) {
|
|
707
|
+
mkdirSync(secretsDir, { recursive: true });
|
|
708
|
+
writeFileSync(envPath, `export CRYSTAL_RELAY_URL=${relayUrl}
|
|
709
|
+
export CRYSTAL_RELAY_TOKEN=${token}
|
|
710
|
+
export CRYSTAL_AGENT_ID=${agentId}
|
|
711
|
+
`);
|
|
712
|
+
process.env.CRYSTAL_RELAY_URL = relayUrl;
|
|
713
|
+
process.env.CRYSTAL_RELAY_TOKEN = token;
|
|
714
|
+
steps.push("Relay config written to ~/.ldm/secrets/crystal-relay.env");
|
|
715
|
+
const shellProfile = join(HOME, ".zshrc");
|
|
716
|
+
const sourceLine = `source ${envPath}`;
|
|
717
|
+
let alreadySourced = false;
|
|
718
|
+
try {
|
|
719
|
+
alreadySourced = readFileSync(shellProfile, "utf8").includes(sourceLine);
|
|
720
|
+
} catch {
|
|
721
|
+
}
|
|
722
|
+
if (!alreadySourced && process.stdin.isTTY) {
|
|
723
|
+
const { createInterface: createRL } = await import("readline");
|
|
724
|
+
const rl2 = createRL({ input: process.stdin, output: process.stdout });
|
|
725
|
+
const ans = await new Promise((resolve) => {
|
|
726
|
+
rl2.question(" Add relay config to ~/.zshrc? [Y/n] ", resolve);
|
|
727
|
+
});
|
|
728
|
+
rl2.close();
|
|
729
|
+
if (ans.trim().toLowerCase() !== "n") {
|
|
730
|
+
const { appendFileSync } = await import("fs");
|
|
731
|
+
appendFileSync(shellProfile, `
|
|
732
|
+
# Memory Crystal relay
|
|
733
|
+
${sourceLine}
|
|
734
|
+
`);
|
|
735
|
+
steps.push("Added relay source to ~/.zshrc");
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
} else {
|
|
739
|
+
steps.push("No relay token. Set CRYSTAL_RELAY_TOKEN manually.");
|
|
740
|
+
}
|
|
741
|
+
} else {
|
|
742
|
+
steps.push("Relay config exists at ~/.ldm/secrets/crystal-relay.env");
|
|
743
|
+
}
|
|
744
|
+
}
|
|
649
745
|
if (hasLdmCli) {
|
|
650
746
|
steps.push('Tip: Run "ldm install" to see more components you can add.');
|
|
651
747
|
} else if (!ldmDelegated) {
|
package/dist/ldm.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
detectProvider,
|
|
3
|
+
expandQuery,
|
|
4
|
+
hasSampling,
|
|
5
|
+
rerankResults,
|
|
6
|
+
setLLMCacheDb,
|
|
7
|
+
setSamplingServer
|
|
8
|
+
} from "./chunk-NX647OM3.js";
|
|
9
|
+
export {
|
|
10
|
+
detectProvider,
|
|
11
|
+
expandQuery,
|
|
12
|
+
hasSampling,
|
|
13
|
+
rerankResults,
|
|
14
|
+
setLLMCacheDb,
|
|
15
|
+
setSamplingServer
|
|
16
|
+
};
|
package/dist/mcp-server.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
setSamplingServer
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-NX647OM3.js";
|
|
5
5
|
import {
|
|
6
6
|
RemoteCrystal,
|
|
7
7
|
createCrystal,
|
|
8
8
|
resolveConfig
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-2GBYLMEF.js";
|
|
10
10
|
import {
|
|
11
11
|
resolveStatePath,
|
|
12
12
|
stateWritePath
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-DFQ72B7M.js";
|
|
14
14
|
|
|
15
15
|
// src/mcp-server.ts
|
|
16
16
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -63,7 +63,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
63
63
|
limit: { type: "number", description: "Max results (default: 5)" },
|
|
64
64
|
agent_id: { type: "string", description: 'Filter by agent (e.g. "main", "claude-code")' },
|
|
65
65
|
time_filter: { type: "string", description: 'Only return results newer than this. Relative ("24h", "7d", "30d") or ISO date.' },
|
|
66
|
-
|
|
66
|
+
until: { type: "string", description: 'Only return results older than this. ISO date (e.g. "2026-03-25"). Use with time_filter for date ranges.' },
|
|
67
|
+
quality: { type: "string", enum: ["fast", "deep"], description: 'Search quality mode. "fast" (default) uses hybrid search. "deep" adds LLM query expansion + re-ranking.' },
|
|
68
|
+
intent: { type: "string", description: 'Disambiguate the query without adding search terms. E.g. query "security" + intent "1Password automation" steers toward 1Password results.' },
|
|
69
|
+
candidate_limit: { type: "number", description: "Number of candidates for LLM re-ranking (default: 40). More = better recall, slower." },
|
|
70
|
+
explain: { type: "boolean", description: "Return per-result scoring breakdown (FTS, vector, RRF, rerank, recency scores)." }
|
|
67
71
|
},
|
|
68
72
|
required: ["query"]
|
|
69
73
|
}
|
|
@@ -141,6 +145,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
141
145
|
const { name, arguments: args } = request.params;
|
|
142
146
|
try {
|
|
143
147
|
await crystal.init();
|
|
148
|
+
if (!isRemote && crystal.sqliteDb) {
|
|
149
|
+
const { setLLMCacheDb } = await import("./llm-XXLYPIOF.js");
|
|
150
|
+
setLLMCacheDb(crystal.sqliteDb);
|
|
151
|
+
}
|
|
144
152
|
switch (name) {
|
|
145
153
|
case "crystal_search": {
|
|
146
154
|
const query = args?.query;
|
|
@@ -148,7 +156,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
148
156
|
const filter = {};
|
|
149
157
|
if (args?.agent_id) filter.agent_id = args.agent_id;
|
|
150
158
|
if (args?.time_filter) filter.since = args.time_filter;
|
|
151
|
-
|
|
159
|
+
if (args?.until) filter.until = args.until;
|
|
160
|
+
const intent = args?.intent;
|
|
161
|
+
const candidateLimit = args?.candidate_limit;
|
|
162
|
+
const explain = args?.explain;
|
|
163
|
+
const results = isRemote ? await crystal.search(query, limit, filter) : await crystal.deepSearch(query, limit, filter, { intent, candidateLimit, explain });
|
|
152
164
|
logSearchMetric("crystal_search", query, results.length);
|
|
153
165
|
if (results.length === 0) {
|
|
154
166
|
return { content: [{ type: "text", text: "No results found." }] };
|
package/dist/migrate.js
CHANGED
package/dist/mirror-sync.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
pullFileSync
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CGIDSAJB.js";
|
|
5
5
|
import {
|
|
6
6
|
Crystal,
|
|
7
7
|
resolveConfig
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-2GBYLMEF.js";
|
|
9
9
|
import {
|
|
10
10
|
decryptJSON,
|
|
11
11
|
loadRelayKey
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-D3MACYZ4.js";
|
|
13
13
|
import {
|
|
14
14
|
ldmPaths,
|
|
15
15
|
resolveStatePath,
|
|
16
16
|
stateWritePath
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-DFQ72B7M.js";
|
|
18
18
|
|
|
19
19
|
// src/mirror-sync.ts
|
|
20
20
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|