memorix 1.9.1 → 1.9.3
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/CHANGELOG.md +22 -0
- package/README.md +17 -4
- package/README.zh-CN.md +8 -4
- package/dist/cli/index.js +448 -243
- package/dist/index.js +302 -165
- package/dist/maintenance-runner.js +194 -98
- package/dist/media-audio-runner.js +196 -100
- package/dist/media-video-runner.js +194 -98
- package/dist/memcode-runtime/CHANGELOG.md +22 -0
- package/dist/sdk.js +301 -164
- package/dist/vector-backfill-runner.js +194 -98
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +15 -0
- package/docs/ARCHITECTURE.md +23 -0
- package/docs/DEVELOPMENT.md +1 -1
- package/docs/INTEGRATIONS.md +4 -0
- package/docs/PERFORMANCE.md +50 -0
- package/docs/README.md +1 -1
- package/docs/SETUP.md +5 -0
- package/package.json +1 -2
- package/plugins/antigravity/memorix/plugin.json +1 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/hermes/memorix/plugin.yaml +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/server.json +2 -2
- package/src/cli/commands/doctor.ts +78 -17
- package/src/cli/commands/memory.ts +2 -1
- package/src/cli/default-mode.ts +15 -0
- package/src/cli/index.ts +10 -1
- package/src/codegraph/lite-provider.ts +10 -1
- package/src/dashboard/maintenance.ts +11 -2
- package/src/memory/consolidation.ts +15 -6
- package/src/store/mini-skill-store.ts +31 -22
- package/src/store/obs-store.ts +46 -30
- package/src/store/session-store.ts +35 -21
- package/src/store/sqlite-db.ts +16 -7
- package/src/store/sqlite-reliability.ts +87 -0
- package/src/store/sqlite-store.ts +4 -1
- package/assets/star-history-dark.svg +0 -30
- package/assets/star-history-light.svg +0 -30
- package/assets/star-history.json +0 -712
package/dist/sdk.js
CHANGED
|
@@ -468,70 +468,79 @@ function getDatabase(dataDir) {
|
|
|
468
468
|
loadBetterSqlite3();
|
|
469
469
|
fs.mkdirSync(dataDir, { recursive: true });
|
|
470
470
|
const dbPath = path3.join(dataDir, "memorix.db");
|
|
471
|
-
|
|
472
|
-
db2.pragma("journal_mode = WAL");
|
|
473
|
-
db2.pragma("busy_timeout = 5000");
|
|
474
|
-
db2.pragma("foreign_keys = ON");
|
|
475
|
-
db2.exec(CREATE_OBSERVATIONS_TABLE);
|
|
476
|
-
db2.exec(CREATE_MINI_SKILLS_TABLE);
|
|
477
|
-
db2.exec(CREATE_SESSIONS_TABLE);
|
|
478
|
-
db2.exec(CREATE_META_TABLE);
|
|
479
|
-
db2.exec(CREATE_TEAM_AGENTS_TABLE);
|
|
480
|
-
db2.exec(CREATE_TEAM_TASKS_TABLE);
|
|
481
|
-
db2.exec(CREATE_TEAM_TASK_DEPS_TABLE);
|
|
482
|
-
db2.exec(CREATE_TEAM_MESSAGES_TABLE);
|
|
483
|
-
db2.exec(CREATE_TEAM_LOCKS_TABLE);
|
|
484
|
-
db2.exec(CREATE_TEAM_ROLES_TABLE);
|
|
485
|
-
db2.exec(CREATE_GRAPH_ENTITIES_TABLE);
|
|
486
|
-
db2.exec(CREATE_GRAPH_RELATIONS_TABLE);
|
|
487
|
-
db2.exec(CREATE_CHAT_TRANSCRIPT_TABLE);
|
|
488
|
-
db2.exec(CREATE_CODE_FILES_TABLE);
|
|
489
|
-
db2.exec(CREATE_CODE_SYMBOLS_TABLE);
|
|
490
|
-
db2.exec(CREATE_CODE_EDGES_TABLE);
|
|
491
|
-
db2.exec(CREATE_OBSERVATION_CODE_REFS_TABLE);
|
|
492
|
-
db2.exec(CREATE_MAINTENANCE_JOBS_TABLE);
|
|
493
|
-
db2.exec(CREATE_MAINTENANCE_TARGETS_TABLE);
|
|
494
|
-
db2.exec(CREATE_COMPACTION_CHECKPOINTS_TABLE);
|
|
471
|
+
let db2;
|
|
495
472
|
try {
|
|
496
|
-
db2
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
db2.exec(
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
db2.exec(
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
db2.exec(
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
db2.exec(
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
db2.exec(
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
473
|
+
db2 = createDatabase(dbPath);
|
|
474
|
+
db2.pragma("busy_timeout = 5000");
|
|
475
|
+
db2.pragma("journal_mode = WAL");
|
|
476
|
+
db2.pragma("foreign_keys = ON");
|
|
477
|
+
db2.exec(CREATE_OBSERVATIONS_TABLE);
|
|
478
|
+
db2.exec(CREATE_MINI_SKILLS_TABLE);
|
|
479
|
+
db2.exec(CREATE_SESSIONS_TABLE);
|
|
480
|
+
db2.exec(CREATE_META_TABLE);
|
|
481
|
+
db2.exec(CREATE_TEAM_AGENTS_TABLE);
|
|
482
|
+
db2.exec(CREATE_TEAM_TASKS_TABLE);
|
|
483
|
+
db2.exec(CREATE_TEAM_TASK_DEPS_TABLE);
|
|
484
|
+
db2.exec(CREATE_TEAM_MESSAGES_TABLE);
|
|
485
|
+
db2.exec(CREATE_TEAM_LOCKS_TABLE);
|
|
486
|
+
db2.exec(CREATE_TEAM_ROLES_TABLE);
|
|
487
|
+
db2.exec(CREATE_GRAPH_ENTITIES_TABLE);
|
|
488
|
+
db2.exec(CREATE_GRAPH_RELATIONS_TABLE);
|
|
489
|
+
db2.exec(CREATE_CHAT_TRANSCRIPT_TABLE);
|
|
490
|
+
db2.exec(CREATE_CODE_FILES_TABLE);
|
|
491
|
+
db2.exec(CREATE_CODE_SYMBOLS_TABLE);
|
|
492
|
+
db2.exec(CREATE_CODE_EDGES_TABLE);
|
|
493
|
+
db2.exec(CREATE_OBSERVATION_CODE_REFS_TABLE);
|
|
494
|
+
db2.exec(CREATE_MAINTENANCE_JOBS_TABLE);
|
|
495
|
+
db2.exec(CREATE_MAINTENANCE_TARGETS_TABLE);
|
|
496
|
+
db2.exec(CREATE_COMPACTION_CHECKPOINTS_TABLE);
|
|
497
|
+
try {
|
|
498
|
+
db2.exec(`ALTER TABLE mini_skills ADD COLUMN sourceSnapshot TEXT NOT NULL DEFAULT ''`);
|
|
499
|
+
} catch {
|
|
500
|
+
}
|
|
501
|
+
try {
|
|
502
|
+
db2.exec(`ALTER TABLE mini_skills ADD COLUMN updatedAt TEXT`);
|
|
503
|
+
} catch {
|
|
504
|
+
}
|
|
505
|
+
try {
|
|
506
|
+
db2.exec(`ALTER TABLE observations ADD COLUMN createdByAgentId TEXT`);
|
|
507
|
+
} catch {
|
|
508
|
+
}
|
|
509
|
+
try {
|
|
510
|
+
db2.exec(`ALTER TABLE observations ADD COLUMN writeGeneration INTEGER DEFAULT 0`);
|
|
511
|
+
} catch {
|
|
512
|
+
}
|
|
513
|
+
try {
|
|
514
|
+
db2.exec(`ALTER TABLE team_tasks ADD COLUMN required_role TEXT`);
|
|
515
|
+
} catch {
|
|
516
|
+
}
|
|
517
|
+
try {
|
|
518
|
+
db2.exec(`ALTER TABLE team_tasks ADD COLUMN preferred_role TEXT`);
|
|
519
|
+
} catch {
|
|
520
|
+
}
|
|
521
|
+
try {
|
|
522
|
+
db2.exec(`ALTER TABLE team_messages ADD COLUMN to_role TEXT`);
|
|
523
|
+
} catch {
|
|
524
|
+
}
|
|
525
|
+
try {
|
|
526
|
+
db2.exec(`ALTER TABLE team_messages ADD COLUMN handoff_status TEXT`);
|
|
527
|
+
} catch {
|
|
528
|
+
}
|
|
529
|
+
applySchemaMigrations(db2);
|
|
530
|
+
db2.exec(CREATE_INDEXES);
|
|
531
|
+
initializeObservationLexicalIndex(db2);
|
|
532
|
+
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('storage_generation', '0')`).run();
|
|
533
|
+
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('next_id', '1')`).run();
|
|
534
|
+
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('mini_skills_generation', '0')`).run();
|
|
535
|
+
_dbCache.set(normalized, db2);
|
|
536
|
+
return db2;
|
|
537
|
+
} catch (error) {
|
|
538
|
+
try {
|
|
539
|
+
db2?.close();
|
|
540
|
+
} catch {
|
|
541
|
+
}
|
|
542
|
+
throw error;
|
|
526
543
|
}
|
|
527
|
-
applySchemaMigrations(db2);
|
|
528
|
-
db2.exec(CREATE_INDEXES);
|
|
529
|
-
initializeObservationLexicalIndex(db2);
|
|
530
|
-
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('storage_generation', '0')`).run();
|
|
531
|
-
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('next_id', '1')`).run();
|
|
532
|
-
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('mini_skills_generation', '0')`).run();
|
|
533
|
-
_dbCache.set(normalized, db2);
|
|
534
|
-
return db2;
|
|
535
544
|
}
|
|
536
545
|
function closeDatabase(dataDir) {
|
|
537
546
|
const normalized = path3.resolve(dataDir);
|
|
@@ -2369,6 +2378,74 @@ var init_types = __esm({
|
|
|
2369
2378
|
}
|
|
2370
2379
|
});
|
|
2371
2380
|
|
|
2381
|
+
// src/store/sqlite-reliability.ts
|
|
2382
|
+
function isTransientSqliteError(error) {
|
|
2383
|
+
const code = error?.code;
|
|
2384
|
+
if (typeof code === "string") {
|
|
2385
|
+
return /^SQLITE_BUSY(?:_|$)/i.test(code);
|
|
2386
|
+
}
|
|
2387
|
+
return error instanceof Error && /\bdatabase is locked\b|\bdatabase is busy\b/i.test(error.message);
|
|
2388
|
+
}
|
|
2389
|
+
function isSqliteUnavailableError(error) {
|
|
2390
|
+
return error instanceof SqliteUnavailableError || error instanceof Error && /SQLite is not available|better-sqlite3.*failed|node:sqlite.*failed|bun:sqlite.*failed/i.test(error.message);
|
|
2391
|
+
}
|
|
2392
|
+
function degradedReadError(storeName) {
|
|
2393
|
+
return new Error(`[memorix] Cannot read ${storeName}: SQLite backend unavailable (memory is not loaded)`);
|
|
2394
|
+
}
|
|
2395
|
+
function degradedWriteError(storeName) {
|
|
2396
|
+
return new Error(`[memorix] Cannot write ${storeName}: SQLite backend unavailable (degraded mode; read-only)`);
|
|
2397
|
+
}
|
|
2398
|
+
function formatSqliteFailure(error) {
|
|
2399
|
+
return error instanceof Error && error.message ? error.message : String(error);
|
|
2400
|
+
}
|
|
2401
|
+
function delay(ms) {
|
|
2402
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
2403
|
+
}
|
|
2404
|
+
async function retrySqliteBusy(operation, label) {
|
|
2405
|
+
for (let attempt = 0; ; attempt++) {
|
|
2406
|
+
try {
|
|
2407
|
+
return await operation();
|
|
2408
|
+
} catch (error) {
|
|
2409
|
+
if (!isTransientSqliteError(error) || attempt >= SQLITE_BUSY_RETRY_DELAYS_MS.length) throw error;
|
|
2410
|
+
const waitMs = SQLITE_BUSY_RETRY_DELAYS_MS[attempt];
|
|
2411
|
+
console.error(
|
|
2412
|
+
`[memorix] ${label} SQLite busy (attempt ${attempt + 1}/${SQLITE_BUSY_RETRY_DELAYS_MS.length + 1}), retrying in ${waitMs}ms`
|
|
2413
|
+
);
|
|
2414
|
+
await delay(waitMs);
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
}
|
|
2418
|
+
async function initializeSqliteStore(factory, dataDir, label) {
|
|
2419
|
+
try {
|
|
2420
|
+
loadBetterSqlite3();
|
|
2421
|
+
} catch (error) {
|
|
2422
|
+
throw new SqliteUnavailableError(error);
|
|
2423
|
+
}
|
|
2424
|
+
return retrySqliteBusy(async () => {
|
|
2425
|
+
const store = factory();
|
|
2426
|
+
await store.init(dataDir);
|
|
2427
|
+
return store;
|
|
2428
|
+
}, label);
|
|
2429
|
+
}
|
|
2430
|
+
var SQLITE_BUSY_RETRY_DELAYS_MS, SqliteUnavailableError;
|
|
2431
|
+
var init_sqlite_reliability = __esm({
|
|
2432
|
+
"src/store/sqlite-reliability.ts"() {
|
|
2433
|
+
"use strict";
|
|
2434
|
+
init_esm_shims();
|
|
2435
|
+
init_sqlite_db();
|
|
2436
|
+
SQLITE_BUSY_RETRY_DELAYS_MS = [50, 150, 400, 1e3, 2500];
|
|
2437
|
+
SqliteUnavailableError = class extends Error {
|
|
2438
|
+
code = "MEMORIX_SQLITE_UNAVAILABLE";
|
|
2439
|
+
constructor(cause) {
|
|
2440
|
+
super(
|
|
2441
|
+
cause instanceof Error && cause.message ? cause.message : "[memorix] SQLite is unavailable (install a supported SQLite runtime)"
|
|
2442
|
+
);
|
|
2443
|
+
this.name = "SqliteUnavailableError";
|
|
2444
|
+
}
|
|
2445
|
+
};
|
|
2446
|
+
}
|
|
2447
|
+
});
|
|
2448
|
+
|
|
2372
2449
|
// src/store/mini-skill-store.ts
|
|
2373
2450
|
var mini_skill_store_exports = {};
|
|
2374
2451
|
__export(mini_skill_store_exports, {
|
|
@@ -2440,16 +2517,18 @@ async function initMiniSkillStore(dataDir) {
|
|
|
2440
2517
|
if (_store && _storeDataDir === dataDir) return _store;
|
|
2441
2518
|
_store = null;
|
|
2442
2519
|
_storeDataDir = null;
|
|
2520
|
+
let degradedReason = "SQLite runtime unavailable";
|
|
2443
2521
|
try {
|
|
2444
|
-
const store2 = new MiniSkillSqliteStore();
|
|
2445
|
-
await store2.init(dataDir);
|
|
2522
|
+
const store2 = await initializeSqliteStore(() => new MiniSkillSqliteStore(), dataDir, "Mini-skill store");
|
|
2446
2523
|
_store = store2;
|
|
2447
2524
|
_storeDataDir = dataDir;
|
|
2448
2525
|
return store2;
|
|
2449
2526
|
} catch (err) {
|
|
2450
|
-
|
|
2527
|
+
if (!isSqliteUnavailableError(err)) throw err;
|
|
2528
|
+
degradedReason = err instanceof Error ? err.message : String(err);
|
|
2529
|
+
console.error(`[memorix] MiniSkillSqliteStore unavailable, running in degraded read-only mode: ${degradedReason}`);
|
|
2451
2530
|
}
|
|
2452
|
-
const store = new MiniSkillGracefulDegrade();
|
|
2531
|
+
const store = new MiniSkillGracefulDegrade(degradedReason);
|
|
2453
2532
|
await store.init(dataDir);
|
|
2454
2533
|
_store = store;
|
|
2455
2534
|
_storeDataDir = dataDir;
|
|
@@ -2461,6 +2540,7 @@ var init_mini_skill_store = __esm({
|
|
|
2461
2540
|
"use strict";
|
|
2462
2541
|
init_esm_shims();
|
|
2463
2542
|
init_sqlite_db();
|
|
2543
|
+
init_sqlite_reliability();
|
|
2464
2544
|
MiniSkillSqliteStore = class {
|
|
2465
2545
|
db = null;
|
|
2466
2546
|
dataDir = "";
|
|
@@ -2569,7 +2649,7 @@ var init_mini_skill_store = __esm({
|
|
|
2569
2649
|
* SQLite serializes write transactions, so concurrent calls are safely sequenced.
|
|
2570
2650
|
*/
|
|
2571
2651
|
async atomicInsertWithId(skillWithoutId) {
|
|
2572
|
-
|
|
2652
|
+
return retrySqliteBusy(async () => this.db.transaction(() => {
|
|
2573
2653
|
const row = this.stmtGetMeta.get("mini_skills_next_id");
|
|
2574
2654
|
const nextId2 = row ? parseInt(row.value, 10) : 1;
|
|
2575
2655
|
const skill2 = { ...skillWithoutId, id: nextId2 };
|
|
@@ -2578,8 +2658,7 @@ var init_mini_skill_store = __esm({
|
|
|
2578
2658
|
this.stmtBumpGeneration.run();
|
|
2579
2659
|
this.knownGeneration = this.readGeneration();
|
|
2580
2660
|
return skill2;
|
|
2581
|
-
})();
|
|
2582
|
-
return result;
|
|
2661
|
+
})(), "Mini-skill promotion");
|
|
2583
2662
|
}
|
|
2584
2663
|
// ── Freshness ────────────────────────────────────────────────────
|
|
2585
2664
|
async ensureFresh() {
|
|
@@ -2598,10 +2677,17 @@ var init_mini_skill_store = __esm({
|
|
|
2598
2677
|
}
|
|
2599
2678
|
};
|
|
2600
2679
|
MiniSkillGracefulDegrade = class {
|
|
2680
|
+
constructor(reason = "SQLite runtime unavailable") {
|
|
2681
|
+
this.reason = reason;
|
|
2682
|
+
}
|
|
2683
|
+
reason;
|
|
2601
2684
|
warned = false;
|
|
2685
|
+
unavailableRead() {
|
|
2686
|
+
return degradedReadError("mini-skills");
|
|
2687
|
+
}
|
|
2602
2688
|
warn() {
|
|
2603
2689
|
if (!this.warned) {
|
|
2604
|
-
console.error("[memorix] MiniSkillStore: SQLite unavailable \u2014 mini-skills
|
|
2690
|
+
console.error("[memorix] MiniSkillStore: SQLite unavailable \u2014 mini-skills cannot be read or written. Install a supported SQLite runtime.");
|
|
2605
2691
|
this.warned = true;
|
|
2606
2692
|
}
|
|
2607
2693
|
}
|
|
@@ -2609,28 +2695,33 @@ var init_mini_skill_store = __esm({
|
|
|
2609
2695
|
this.warn();
|
|
2610
2696
|
}
|
|
2611
2697
|
async loadAll() {
|
|
2612
|
-
|
|
2698
|
+
throw this.unavailableRead();
|
|
2613
2699
|
}
|
|
2614
2700
|
async loadByProject(_projectId) {
|
|
2615
|
-
|
|
2701
|
+
throw this.unavailableRead();
|
|
2616
2702
|
}
|
|
2617
2703
|
async loadIdCounter() {
|
|
2618
|
-
|
|
2704
|
+
throw this.unavailableRead();
|
|
2619
2705
|
}
|
|
2620
2706
|
async insert(_skill) {
|
|
2621
2707
|
this.warn();
|
|
2708
|
+
throw degradedWriteError("mini-skills");
|
|
2622
2709
|
}
|
|
2623
2710
|
async update(_skill) {
|
|
2624
2711
|
this.warn();
|
|
2712
|
+
throw degradedWriteError("mini-skills");
|
|
2625
2713
|
}
|
|
2626
2714
|
async remove(_id) {
|
|
2627
2715
|
this.warn();
|
|
2716
|
+
throw degradedWriteError("mini-skills");
|
|
2628
2717
|
}
|
|
2629
2718
|
async saveIdCounter(_nextId) {
|
|
2719
|
+
this.warn();
|
|
2720
|
+
throw degradedWriteError("mini-skills");
|
|
2630
2721
|
}
|
|
2631
2722
|
async atomicInsertWithId(skillWithoutId) {
|
|
2632
2723
|
this.warn();
|
|
2633
|
-
|
|
2724
|
+
throw degradedWriteError("mini-skills");
|
|
2634
2725
|
}
|
|
2635
2726
|
async ensureFresh() {
|
|
2636
2727
|
return false;
|
|
@@ -2641,6 +2732,9 @@ var init_mini_skill_store = __esm({
|
|
|
2641
2732
|
getBackendName() {
|
|
2642
2733
|
return "degraded";
|
|
2643
2734
|
}
|
|
2735
|
+
getBackendReason() {
|
|
2736
|
+
return this.reason;
|
|
2737
|
+
}
|
|
2644
2738
|
};
|
|
2645
2739
|
_store = null;
|
|
2646
2740
|
_storeDataDir = null;
|
|
@@ -4843,10 +4937,10 @@ async function fetchWithRetry(url, apiKey, body, options = {}, attempt = 0, nati
|
|
|
4843
4937
|
);
|
|
4844
4938
|
}
|
|
4845
4939
|
if (options.retry !== false && (response.status === 429 || response.status >= 500) && attempt < MAX_RETRIES2) {
|
|
4846
|
-
const
|
|
4940
|
+
const delay3 = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
4847
4941
|
const retryAfter = response.headers.get("retry-after");
|
|
4848
4942
|
const parsedRetryAfter = retryAfter ? parseInt(retryAfter, 10) * 1e3 : NaN;
|
|
4849
|
-
const waitMs = Number.isFinite(parsedRetryAfter) ? parsedRetryAfter :
|
|
4943
|
+
const waitMs = Number.isFinite(parsedRetryAfter) ? parsedRetryAfter : delay3;
|
|
4850
4944
|
console.error(`[memorix] Embedding API ${response.status}, retry ${attempt + 1}/${MAX_RETRIES2} in ${waitMs}ms`);
|
|
4851
4945
|
await waitForRetry(waitMs, options.signal);
|
|
4852
4946
|
return fetchWithRetry(url, apiKey, body, options, attempt + 1, nativeGemini);
|
|
@@ -6878,6 +6972,7 @@ var init_sqlite_store = __esm({
|
|
|
6878
6972
|
"use strict";
|
|
6879
6973
|
init_esm_shims();
|
|
6880
6974
|
init_sqlite_db();
|
|
6975
|
+
init_sqlite_reliability();
|
|
6881
6976
|
init_sqlite_fts();
|
|
6882
6977
|
SqliteBackend = class {
|
|
6883
6978
|
db = null;
|
|
@@ -7155,7 +7250,9 @@ var init_sqlite_store = __esm({
|
|
|
7155
7250
|
// ── Compound atomic operation ────────────────────────────────────
|
|
7156
7251
|
async atomic(fn) {
|
|
7157
7252
|
const run = this._atomicQueue.catch(() => void 0).then(async () => {
|
|
7158
|
-
|
|
7253
|
+
await retrySqliteBusy(async () => {
|
|
7254
|
+
this.db.prepare("BEGIN IMMEDIATE").run();
|
|
7255
|
+
}, "Observation atomic write");
|
|
7159
7256
|
try {
|
|
7160
7257
|
const tx = {
|
|
7161
7258
|
loadAll: async () => this.rawLoadAll(),
|
|
@@ -7254,15 +7351,15 @@ function resetObservationStore() {
|
|
|
7254
7351
|
async function createObservationStore(dataDir) {
|
|
7255
7352
|
try {
|
|
7256
7353
|
const { SqliteBackend: SqliteBackend2 } = await Promise.resolve().then(() => (init_sqlite_store(), sqlite_store_exports));
|
|
7257
|
-
|
|
7258
|
-
await store2.init(dataDir);
|
|
7259
|
-
return store2;
|
|
7354
|
+
return await initializeSqliteStore(() => new SqliteBackend2(), dataDir, "Observation store");
|
|
7260
7355
|
} catch (err) {
|
|
7261
|
-
|
|
7356
|
+
if (!isSqliteUnavailableError(err)) throw err;
|
|
7357
|
+
const reason = formatSqliteFailure(err);
|
|
7358
|
+
console.error(`[memorix] SQLite module unavailable \u2014 degraded mode (reads/writes disabled): ${reason}`);
|
|
7359
|
+
const degraded = new DegradedBackend(reason);
|
|
7360
|
+
await degraded.init(dataDir);
|
|
7361
|
+
return degraded;
|
|
7262
7362
|
}
|
|
7263
|
-
const store = new DegradedBackend();
|
|
7264
|
-
await store.init(dataDir);
|
|
7265
|
-
return store;
|
|
7266
7363
|
}
|
|
7267
7364
|
async function initObservationStore(dataDir) {
|
|
7268
7365
|
if (_store2 && _storeDataDir2 === dataDir) {
|
|
@@ -7286,36 +7383,44 @@ var init_obs_store = __esm({
|
|
|
7286
7383
|
"src/store/obs-store.ts"() {
|
|
7287
7384
|
"use strict";
|
|
7288
7385
|
init_esm_shims();
|
|
7386
|
+
init_sqlite_reliability();
|
|
7289
7387
|
_store2 = null;
|
|
7290
7388
|
_storeDataDir2 = null;
|
|
7291
7389
|
DegradedBackend = class {
|
|
7390
|
+
constructor(reason = "SQLite runtime unavailable") {
|
|
7391
|
+
this.reason = reason;
|
|
7392
|
+
}
|
|
7393
|
+
reason;
|
|
7292
7394
|
dataDir = "";
|
|
7395
|
+
unavailableRead() {
|
|
7396
|
+
return degradedReadError("observations");
|
|
7397
|
+
}
|
|
7293
7398
|
async init(dataDir) {
|
|
7294
7399
|
this.dataDir = dataDir;
|
|
7295
7400
|
}
|
|
7296
7401
|
async loadAll() {
|
|
7297
|
-
|
|
7402
|
+
throw this.unavailableRead();
|
|
7298
7403
|
}
|
|
7299
7404
|
async loadByProject(_projectId, _options) {
|
|
7300
|
-
|
|
7405
|
+
throw this.unavailableRead();
|
|
7301
7406
|
}
|
|
7302
7407
|
async countByProject(_projectId, _options) {
|
|
7303
|
-
|
|
7408
|
+
throw this.unavailableRead();
|
|
7304
7409
|
}
|
|
7305
7410
|
async getById(_id) {
|
|
7306
|
-
|
|
7411
|
+
throw this.unavailableRead();
|
|
7307
7412
|
}
|
|
7308
7413
|
async loadIdCounter() {
|
|
7309
|
-
|
|
7414
|
+
throw this.unavailableRead();
|
|
7310
7415
|
}
|
|
7311
7416
|
async countAll() {
|
|
7312
|
-
|
|
7417
|
+
throw this.unavailableRead();
|
|
7313
7418
|
}
|
|
7314
7419
|
async listProjectIds() {
|
|
7315
|
-
|
|
7420
|
+
throw this.unavailableRead();
|
|
7316
7421
|
}
|
|
7317
7422
|
async searchLexical(_options) {
|
|
7318
|
-
|
|
7423
|
+
throw this.unavailableRead();
|
|
7319
7424
|
}
|
|
7320
7425
|
hasLexicalIndex() {
|
|
7321
7426
|
return false;
|
|
@@ -7324,25 +7429,25 @@ var init_obs_store = __esm({
|
|
|
7324
7429
|
return false;
|
|
7325
7430
|
}
|
|
7326
7431
|
async insert(_obs) {
|
|
7327
|
-
throw
|
|
7432
|
+
throw degradedWriteError("observations");
|
|
7328
7433
|
}
|
|
7329
7434
|
async update(_obs) {
|
|
7330
|
-
throw
|
|
7435
|
+
throw degradedWriteError("observations");
|
|
7331
7436
|
}
|
|
7332
7437
|
async remove(_id) {
|
|
7333
|
-
throw
|
|
7438
|
+
throw degradedWriteError("observations");
|
|
7334
7439
|
}
|
|
7335
7440
|
async bulkReplace(_obs) {
|
|
7336
|
-
throw
|
|
7441
|
+
throw degradedWriteError("observations");
|
|
7337
7442
|
}
|
|
7338
7443
|
async bulkRemoveByIds(_ids) {
|
|
7339
|
-
throw
|
|
7444
|
+
throw degradedWriteError("observations");
|
|
7340
7445
|
}
|
|
7341
7446
|
async saveIdCounter(_nextId) {
|
|
7342
|
-
throw
|
|
7447
|
+
throw degradedWriteError("observations");
|
|
7343
7448
|
}
|
|
7344
7449
|
async atomic(_fn) {
|
|
7345
|
-
throw
|
|
7450
|
+
throw degradedWriteError("observations");
|
|
7346
7451
|
}
|
|
7347
7452
|
async ensureFresh() {
|
|
7348
7453
|
return false;
|
|
@@ -7355,6 +7460,9 @@ var init_obs_store = __esm({
|
|
|
7355
7460
|
getBackendName() {
|
|
7356
7461
|
return "degraded";
|
|
7357
7462
|
}
|
|
7463
|
+
getBackendReason() {
|
|
7464
|
+
return this.reason;
|
|
7465
|
+
}
|
|
7358
7466
|
};
|
|
7359
7467
|
}
|
|
7360
7468
|
});
|
|
@@ -10928,7 +11036,8 @@ function clampCursor(afterId) {
|
|
|
10928
11036
|
}
|
|
10929
11037
|
async function loadConsolidationPage(projectId, options) {
|
|
10930
11038
|
const limit2 = clampBatchSize(options.limit);
|
|
10931
|
-
const
|
|
11039
|
+
const store = options.store ?? getObservationStore();
|
|
11040
|
+
const page = await store.loadByProject(projectId, {
|
|
10932
11041
|
status: "active",
|
|
10933
11042
|
afterId: clampCursor(options.afterId),
|
|
10934
11043
|
limit: limit2 + 1
|
|
@@ -10988,7 +11097,7 @@ async function findConsolidationCandidates(_projectDir, projectId, opts) {
|
|
|
10988
11097
|
return findClusters(page.observations, threshold);
|
|
10989
11098
|
}
|
|
10990
11099
|
async function executeConsolidation(_projectDir, projectId, opts) {
|
|
10991
|
-
const store = getObservationStore();
|
|
11100
|
+
const store = opts?.store ?? getObservationStore();
|
|
10992
11101
|
const page = await loadConsolidationPage(projectId, opts ?? {});
|
|
10993
11102
|
const clusters = findClusters(page.observations, opts?.threshold ?? DEFAULT_SIMILARITY_THRESHOLD);
|
|
10994
11103
|
if (clusters.length === 0) {
|
|
@@ -57008,10 +57117,10 @@ var require_retry3 = __commonJS({
|
|
|
57008
57117
|
if (!await shouldRetryFn(err)) {
|
|
57009
57118
|
return { shouldRetry: false, config: err.config };
|
|
57010
57119
|
}
|
|
57011
|
-
const
|
|
57120
|
+
const delay3 = getNextRetryDelay(config);
|
|
57012
57121
|
err.config.retryConfig.currentRetryAttempt += 1;
|
|
57013
|
-
const backoff = config.retryBackoff ? config.retryBackoff(err,
|
|
57014
|
-
setTimeout(resolve5,
|
|
57122
|
+
const backoff = config.retryBackoff ? config.retryBackoff(err, delay3) : new Promise((resolve5) => {
|
|
57123
|
+
setTimeout(resolve5, delay3);
|
|
57015
57124
|
});
|
|
57016
57125
|
if (config.onRetryAttempt) {
|
|
57017
57126
|
await config.onRetryAttempt(err);
|
|
@@ -98797,7 +98906,7 @@ async function retryBackoff(fn, strategy) {
|
|
|
98797
98906
|
retryInterval = initialInterval * Math.pow(x2, exponent) + Math.random() * 1e3;
|
|
98798
98907
|
}
|
|
98799
98908
|
const d = Math.min(retryInterval, maxInterval);
|
|
98800
|
-
await
|
|
98909
|
+
await delay2(d);
|
|
98801
98910
|
x2++;
|
|
98802
98911
|
}
|
|
98803
98912
|
}
|
|
@@ -98818,8 +98927,8 @@ function retryIntervalFromResponse(res) {
|
|
|
98818
98927
|
}
|
|
98819
98928
|
return 0;
|
|
98820
98929
|
}
|
|
98821
|
-
async function
|
|
98822
|
-
return new Promise((resolve5) => setTimeout(resolve5,
|
|
98930
|
+
async function delay2(delay3) {
|
|
98931
|
+
return new Promise((resolve5) => setTimeout(resolve5, delay3));
|
|
98823
98932
|
}
|
|
98824
98933
|
var defaultBackoff, PermanentError, TemporaryError, codeRangeRE2;
|
|
98825
98934
|
var init_retries = __esm({
|
|
@@ -148928,7 +149037,7 @@ __export(lite_provider_exports, {
|
|
|
148928
149037
|
refreshProjectLite: () => refreshProjectLite
|
|
148929
149038
|
});
|
|
148930
149039
|
import { createHash as createHash10 } from "crypto";
|
|
148931
|
-
import { readdirSync as readdirSync2, readFileSync as readFileSync8, statSync as statSync3 } from "fs";
|
|
149040
|
+
import { existsSync as existsSync12, readdirSync as readdirSync2, readFileSync as readFileSync8, statSync as statSync3 } from "fs";
|
|
148932
149041
|
import { join as join4, relative as relative2 } from "path";
|
|
148933
149042
|
function hashText2(text3) {
|
|
148934
149043
|
return createHash10("sha256").update(text3).digest("hex");
|
|
@@ -148945,6 +149054,9 @@ function resolveMaxFileBytes(value) {
|
|
|
148945
149054
|
if (!Number.isFinite(value)) return DEFAULT_CODEGRAPH_MAX_FILE_BYTES;
|
|
148946
149055
|
return Math.max(1, Math.floor(value));
|
|
148947
149056
|
}
|
|
149057
|
+
function isPythonVirtualenvDir(dir) {
|
|
149058
|
+
return existsSync12(join4(dir, "pyvenv.cfg"));
|
|
149059
|
+
}
|
|
148948
149060
|
function walk(root, exclude, maxFiles) {
|
|
148949
149061
|
const out = [];
|
|
148950
149062
|
const visit = (dir) => {
|
|
@@ -148962,6 +149074,7 @@ function walk(root, exclude, maxFiles) {
|
|
|
148962
149074
|
if (entry.isDirectory()) {
|
|
148963
149075
|
if (entry.name === ".git" || entry.name === ".worktrees" || entry.name === ".tmp" || entry.name === "node_modules") continue;
|
|
148964
149076
|
if (rel === ".claude/worktrees" || rel.startsWith(".claude/worktrees/")) continue;
|
|
149077
|
+
if (isPythonVirtualenvDir(abs)) continue;
|
|
148965
149078
|
visit(abs);
|
|
148966
149079
|
if (out.length >= maxFiles) return;
|
|
148967
149080
|
continue;
|
|
@@ -152858,7 +152971,7 @@ __export(vector_backfill_runner_exports, {
|
|
|
152858
152971
|
import { spawn as spawn4 } from "child_process";
|
|
152859
152972
|
import {
|
|
152860
152973
|
closeSync,
|
|
152861
|
-
existsSync as
|
|
152974
|
+
existsSync as existsSync13,
|
|
152862
152975
|
mkdirSync as mkdirSync2,
|
|
152863
152976
|
openSync,
|
|
152864
152977
|
readFileSync as readFileSync9,
|
|
@@ -152986,7 +153099,7 @@ function releaseVectorBackfillLock(lockPath = process.env.MEMORIX_VECTOR_BACKFIL
|
|
|
152986
153099
|
}
|
|
152987
153100
|
function launchDetachedVectorBackfill(request, options = {}) {
|
|
152988
153101
|
const runnerPath = options.runnerPath ?? resolveVectorBackfillRunnerPath();
|
|
152989
|
-
const exists = options.exists ??
|
|
153102
|
+
const exists = options.exists ?? existsSync13;
|
|
152990
153103
|
if (!exists(runnerPath)) return false;
|
|
152991
153104
|
const lock = acquireVectorBackfillLock(request.dataDir, request.projectId, options.lockPath);
|
|
152992
153105
|
if (!lock) return false;
|
|
@@ -154271,16 +154384,18 @@ async function initSessionStore(dataDir) {
|
|
|
154271
154384
|
if (_store3 && _storeDataDir3 === dataDir) return _store3;
|
|
154272
154385
|
_store3 = null;
|
|
154273
154386
|
_storeDataDir3 = null;
|
|
154387
|
+
let degradedReason = "SQLite runtime unavailable";
|
|
154274
154388
|
try {
|
|
154275
|
-
const store2 = new SessionSqliteStore();
|
|
154276
|
-
await store2.init(dataDir);
|
|
154389
|
+
const store2 = await initializeSqliteStore(() => new SessionSqliteStore(), dataDir, "Session store");
|
|
154277
154390
|
_store3 = store2;
|
|
154278
154391
|
_storeDataDir3 = dataDir;
|
|
154279
154392
|
return store2;
|
|
154280
154393
|
} catch (err) {
|
|
154281
|
-
|
|
154394
|
+
if (!isSqliteUnavailableError(err)) throw err;
|
|
154395
|
+
degradedReason = formatSqliteFailure(err);
|
|
154396
|
+
console.error(`[memorix] SessionSqliteStore unavailable, running in degraded read-only mode: ${degradedReason}`);
|
|
154282
154397
|
}
|
|
154283
|
-
const store = new SessionGracefulDegrade();
|
|
154398
|
+
const store = new SessionGracefulDegrade(degradedReason);
|
|
154284
154399
|
await store.init(dataDir);
|
|
154285
154400
|
_store3 = store;
|
|
154286
154401
|
_storeDataDir3 = dataDir;
|
|
@@ -154292,6 +154407,7 @@ var init_session_store = __esm({
|
|
|
154292
154407
|
"use strict";
|
|
154293
154408
|
init_esm_shims();
|
|
154294
154409
|
init_sqlite_db();
|
|
154410
|
+
init_sqlite_reliability();
|
|
154295
154411
|
SessionSqliteStore = class {
|
|
154296
154412
|
db = null;
|
|
154297
154413
|
dataDir = "";
|
|
@@ -154380,7 +154496,7 @@ var init_session_store = __esm({
|
|
|
154380
154496
|
}
|
|
154381
154497
|
const stmtComplete = this._stmtCompleteActive;
|
|
154382
154498
|
const stmtIns = this.stmtInsert;
|
|
154383
|
-
|
|
154499
|
+
return retrySqliteBusy(async () => this.db.transaction(() => {
|
|
154384
154500
|
let completedCount = 0;
|
|
154385
154501
|
for (const pid of projectIds) {
|
|
154386
154502
|
const info = stmtComplete.run({ pid, now: now3 });
|
|
@@ -154388,18 +154504,24 @@ var init_session_store = __esm({
|
|
|
154388
154504
|
}
|
|
154389
154505
|
stmtIns.run(sessionToRow(newSession));
|
|
154390
154506
|
return completedCount;
|
|
154391
|
-
})();
|
|
154392
|
-
return result;
|
|
154507
|
+
})(), "Session rollover");
|
|
154393
154508
|
}
|
|
154394
154509
|
getBackendName() {
|
|
154395
154510
|
return "sqlite";
|
|
154396
154511
|
}
|
|
154397
154512
|
};
|
|
154398
154513
|
SessionGracefulDegrade = class {
|
|
154514
|
+
constructor(reason = "SQLite runtime unavailable") {
|
|
154515
|
+
this.reason = reason;
|
|
154516
|
+
}
|
|
154517
|
+
reason;
|
|
154399
154518
|
warned = false;
|
|
154519
|
+
unavailableRead() {
|
|
154520
|
+
return degradedReadError("sessions");
|
|
154521
|
+
}
|
|
154400
154522
|
warn() {
|
|
154401
154523
|
if (!this.warned) {
|
|
154402
|
-
console.error("[memorix] SessionStore: SQLite unavailable \u2014 sessions
|
|
154524
|
+
console.error("[memorix] SessionStore: SQLite unavailable \u2014 sessions cannot be read or written. Install a supported SQLite runtime.");
|
|
154403
154525
|
this.warned = true;
|
|
154404
154526
|
}
|
|
154405
154527
|
}
|
|
@@ -154407,33 +154529,39 @@ var init_session_store = __esm({
|
|
|
154407
154529
|
this.warn();
|
|
154408
154530
|
}
|
|
154409
154531
|
async loadAll() {
|
|
154410
|
-
|
|
154532
|
+
throw this.unavailableRead();
|
|
154411
154533
|
}
|
|
154412
154534
|
async getById(_id) {
|
|
154413
|
-
|
|
154535
|
+
throw this.unavailableRead();
|
|
154414
154536
|
}
|
|
154415
154537
|
async loadByProject(_projectId) {
|
|
154416
|
-
|
|
154538
|
+
throw this.unavailableRead();
|
|
154417
154539
|
}
|
|
154418
154540
|
async loadActive(_projectId) {
|
|
154419
|
-
|
|
154541
|
+
throw this.unavailableRead();
|
|
154420
154542
|
}
|
|
154421
154543
|
async insert(_session) {
|
|
154422
154544
|
this.warn();
|
|
154545
|
+
throw degradedWriteError("sessions");
|
|
154423
154546
|
}
|
|
154424
154547
|
async update(_session) {
|
|
154425
154548
|
this.warn();
|
|
154549
|
+
throw degradedWriteError("sessions");
|
|
154426
154550
|
}
|
|
154427
154551
|
async bulkUpdate(_sessions) {
|
|
154428
154552
|
this.warn();
|
|
154553
|
+
throw degradedWriteError("sessions");
|
|
154429
154554
|
}
|
|
154430
154555
|
async atomicRolloverInsert(_newSession, _projectIds, _now) {
|
|
154431
154556
|
this.warn();
|
|
154432
|
-
|
|
154557
|
+
throw degradedWriteError("sessions");
|
|
154433
154558
|
}
|
|
154434
154559
|
getBackendName() {
|
|
154435
154560
|
return "degraded";
|
|
154436
154561
|
}
|
|
154562
|
+
getBackendReason() {
|
|
154563
|
+
return this.reason;
|
|
154564
|
+
}
|
|
154437
154565
|
};
|
|
154438
154566
|
_store3 = null;
|
|
154439
154567
|
_storeDataDir3 = null;
|
|
@@ -155664,7 +155792,7 @@ __export(behavior_exports, {
|
|
|
155664
155792
|
getBehaviorConfig: () => getBehaviorConfig,
|
|
155665
155793
|
resetBehaviorConfigCache: () => resetBehaviorConfigCache
|
|
155666
155794
|
});
|
|
155667
|
-
import { existsSync as
|
|
155795
|
+
import { existsSync as existsSync16, readFileSync as readFileSync11 } from "fs";
|
|
155668
155796
|
import { homedir as homedir22 } from "os";
|
|
155669
155797
|
function isSessionInject(value) {
|
|
155670
155798
|
return value === "full" || value === "minimal" || value === "silent";
|
|
@@ -155675,7 +155803,7 @@ function isFormationMode(value) {
|
|
|
155675
155803
|
function legacyBehavior(homeDir) {
|
|
155676
155804
|
const configPath = getLegacyConfigJsonPath(homeDir);
|
|
155677
155805
|
try {
|
|
155678
|
-
if (!
|
|
155806
|
+
if (!existsSync16(configPath)) return {};
|
|
155679
155807
|
const parsed = JSON.parse(readFileSync11(configPath, "utf-8"));
|
|
155680
155808
|
return parsed.behavior && typeof parsed.behavior === "object" && !Array.isArray(parsed.behavior) ? parsed.behavior : {};
|
|
155681
155809
|
} catch {
|
|
@@ -157029,11 +157157,11 @@ __export(current_facts_exports, {
|
|
|
157029
157157
|
formatGitFact: () => formatGitFact
|
|
157030
157158
|
});
|
|
157031
157159
|
import { execFileSync } from "child_process";
|
|
157032
|
-
import { existsSync as
|
|
157160
|
+
import { existsSync as existsSync17, readFileSync as readFileSync12 } from "fs";
|
|
157033
157161
|
import path29 from "path";
|
|
157034
157162
|
function readTextIfExists(filePath) {
|
|
157035
157163
|
try {
|
|
157036
|
-
if (!
|
|
157164
|
+
if (!existsSync17(filePath)) return null;
|
|
157037
157165
|
return readFileSync12(filePath, "utf8");
|
|
157038
157166
|
} catch {
|
|
157039
157167
|
return null;
|
|
@@ -157324,7 +157452,7 @@ __export(external_provider_exports, {
|
|
|
157324
157452
|
runExternalCodeGraphLifecycle: () => runExternalCodeGraphLifecycle
|
|
157325
157453
|
});
|
|
157326
157454
|
import { spawn as spawn5 } from "child_process";
|
|
157327
|
-
import { existsSync as
|
|
157455
|
+
import { existsSync as existsSync18, readFileSync as readFileSync13 } from "fs";
|
|
157328
157456
|
import { delimiter, dirname as dirname2, extname, isAbsolute as isAbsolute3, join as join20, relative as relative4, resolve as resolve3, sep } from "path";
|
|
157329
157457
|
function boundedTimeout(value) {
|
|
157330
157458
|
if (!Number.isFinite(value)) return DEFAULT_EXTERNAL_CODEGRAPH_TIMEOUT_MS;
|
|
@@ -157361,13 +157489,13 @@ function resolveCommandCandidates(command) {
|
|
|
157361
157489
|
}
|
|
157362
157490
|
function resolveLaunch(command) {
|
|
157363
157491
|
for (const candidate of resolveCommandCandidates(command)) {
|
|
157364
|
-
if (!
|
|
157492
|
+
if (!existsSync18(candidate)) continue;
|
|
157365
157493
|
const extension3 = extname(candidate).toLowerCase();
|
|
157366
157494
|
if (extension3 === ".cmd") {
|
|
157367
157495
|
const bundleRoot = resolve3(dirname2(candidate), "..");
|
|
157368
157496
|
const node = join20(bundleRoot, "node.exe");
|
|
157369
157497
|
const entry = join20(bundleRoot, "lib", "dist", "bin", "codegraph.js");
|
|
157370
|
-
if (
|
|
157498
|
+
if (existsSync18(node) && existsSync18(entry)) {
|
|
157371
157499
|
return { executable: node, prefixArgs: ["--liftoff-only", entry] };
|
|
157372
157500
|
}
|
|
157373
157501
|
try {
|
|
@@ -157376,7 +157504,7 @@ function resolveLaunch(command) {
|
|
|
157376
157504
|
if (match2?.[1]) {
|
|
157377
157505
|
const base = dirname2(candidate).endsWith(sep) ? dirname2(candidate) : dirname2(candidate) + sep;
|
|
157378
157506
|
const entry2 = resolve3(match2[1].replace(/%(?:~)?dp0%?/gi, base));
|
|
157379
|
-
if (
|
|
157507
|
+
if (existsSync18(entry2)) return { executable: process.execPath, prefixArgs: [entry2] };
|
|
157380
157508
|
}
|
|
157381
157509
|
} catch {
|
|
157382
157510
|
}
|
|
@@ -157524,7 +157652,7 @@ async function inspectExternalCodeGraph(input) {
|
|
|
157524
157652
|
const health2 = { state: "disabled", reason: "External CodeGraph is disabled by configuration." };
|
|
157525
157653
|
return { health: health2, quality: providerQuality({ mode, health: health2 }) };
|
|
157526
157654
|
}
|
|
157527
|
-
if (!
|
|
157655
|
+
if (!existsSync18(join20(input.projectRoot, ".codegraph"))) {
|
|
157528
157656
|
const health2 = { state: "not-detected", reason: "No local .codegraph index is present for this project." };
|
|
157529
157657
|
return { health: health2, quality: providerQuality({ mode, health: health2 }) };
|
|
157530
157658
|
}
|
|
@@ -157560,7 +157688,7 @@ async function runExternalCodeGraphLifecycle(input) {
|
|
|
157560
157688
|
};
|
|
157561
157689
|
}
|
|
157562
157690
|
const indexPath = join20(input.projectRoot, ".codegraph");
|
|
157563
|
-
if (input.action === "sync" && !
|
|
157691
|
+
if (input.action === "sync" && !existsSync18(indexPath)) {
|
|
157564
157692
|
const health = { state: "not-detected", reason: "No local .codegraph index is present for this project." };
|
|
157565
157693
|
return {
|
|
157566
157694
|
action: input.action,
|
|
@@ -157570,7 +157698,7 @@ async function runExternalCodeGraphLifecycle(input) {
|
|
|
157570
157698
|
quality: providerQuality({ mode, health })
|
|
157571
157699
|
};
|
|
157572
157700
|
}
|
|
157573
|
-
if (input.action === "init" &&
|
|
157701
|
+
if (input.action === "init" && existsSync18(indexPath)) {
|
|
157574
157702
|
const inspected2 = await inspectExternalCodeGraph(input);
|
|
157575
157703
|
return {
|
|
157576
157704
|
action: input.action,
|
|
@@ -158631,7 +158759,7 @@ __export(auto_context_exports, {
|
|
|
158631
158759
|
formatAutoProjectContextSummary: () => formatAutoProjectContextSummary,
|
|
158632
158760
|
formatLegacyAutoProjectContextPrompt: () => formatLegacyAutoProjectContextPrompt
|
|
158633
158761
|
});
|
|
158634
|
-
import { existsSync as
|
|
158762
|
+
import { existsSync as existsSync19, statSync as statSync5 } from "fs";
|
|
158635
158763
|
import path30 from "path";
|
|
158636
158764
|
function activeProjectObservations(observations2, projectId) {
|
|
158637
158765
|
return observations2.filter((obs) => obs.projectId === projectId && (obs.status ?? "active") === "active");
|
|
@@ -158977,7 +159105,7 @@ function existingLensCandidates(rootPath, lens) {
|
|
|
158977
159105
|
for (const candidate of lensPathCandidates(lens)) {
|
|
158978
159106
|
const absolute = path30.join(rootPath, candidate);
|
|
158979
159107
|
try {
|
|
158980
|
-
if (!
|
|
159108
|
+
if (!existsSync19(absolute)) continue;
|
|
158981
159109
|
const stat5 = statSync5(absolute);
|
|
158982
159110
|
if (stat5.isFile()) out.push(candidate);
|
|
158983
159111
|
if (stat5.isDirectory()) out.push(candidate.replace(/\\/g, "/"));
|
|
@@ -159511,7 +159639,7 @@ var engine_exports2 = {};
|
|
|
159511
159639
|
__export(engine_exports2, {
|
|
159512
159640
|
SkillsEngine: () => SkillsEngine
|
|
159513
159641
|
});
|
|
159514
|
-
import { existsSync as
|
|
159642
|
+
import { existsSync as existsSync20, readFileSync as readFileSync14, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, readdirSync as readdirSync4 } from "fs";
|
|
159515
159643
|
import { join as join21 } from "path";
|
|
159516
159644
|
import { homedir as homedir23 } from "os";
|
|
159517
159645
|
var SKILLS_DIRS, SKILL_WORTHY_TYPES, MIN_OBS_FOR_SKILL, MIN_SCORE_FOR_SKILL, LOW_SIGNAL_TITLE_PATTERNS, LOW_SIGNAL_ENTITY_PATTERNS, COMMAND_TRACE_PATTERNS2, SkillsEngine;
|
|
@@ -159592,7 +159720,7 @@ var init_engine3 = __esm({
|
|
|
159592
159720
|
paths.push(join21(home, dir));
|
|
159593
159721
|
}
|
|
159594
159722
|
for (const skillsRoot of paths) {
|
|
159595
|
-
if (!
|
|
159723
|
+
if (!existsSync20(skillsRoot)) continue;
|
|
159596
159724
|
try {
|
|
159597
159725
|
const entries = readdirSync4(skillsRoot, { withFileTypes: true });
|
|
159598
159726
|
for (const entry of entries) {
|
|
@@ -159600,7 +159728,7 @@ var init_engine3 = __esm({
|
|
|
159600
159728
|
const name = entry.name;
|
|
159601
159729
|
if (seen.has(name)) continue;
|
|
159602
159730
|
const skillMd = join21(skillsRoot, name, "SKILL.md");
|
|
159603
|
-
if (!
|
|
159731
|
+
if (!existsSync20(skillMd)) continue;
|
|
159604
159732
|
try {
|
|
159605
159733
|
const content = readFileSync14(skillMd, "utf-8");
|
|
159606
159734
|
const description = this.parseDescription(content);
|
|
@@ -161401,7 +161529,8 @@ async function executeDeduplicate(context, payload, token) {
|
|
|
161401
161529
|
async function previewConsolidate(context) {
|
|
161402
161530
|
const clusters = await findConsolidationCandidates(
|
|
161403
161531
|
context.projectRoot ?? context.dataDir,
|
|
161404
|
-
context.projectId
|
|
161532
|
+
context.projectId,
|
|
161533
|
+
{ store: context.store }
|
|
161405
161534
|
);
|
|
161406
161535
|
const payload = { clusterIds: normalizeClusters(clusters.map((cluster) => cluster.ids)) };
|
|
161407
161536
|
return {
|
|
@@ -161424,11 +161553,19 @@ async function executeConsolidate(context, payload, token) {
|
|
|
161424
161553
|
const clusterIds = record80.clusterIds.map((ids, index) => payloadIds(ids, `clusterIds[${index}]`));
|
|
161425
161554
|
const normalized = { clusterIds: normalizeClusters(clusterIds) };
|
|
161426
161555
|
verify("consolidate", context.projectId, normalized, token);
|
|
161427
|
-
const current = await findConsolidationCandidates(
|
|
161556
|
+
const current = await findConsolidationCandidates(
|
|
161557
|
+
context.projectRoot ?? context.dataDir,
|
|
161558
|
+
context.projectId,
|
|
161559
|
+
{ store: context.store }
|
|
161560
|
+
);
|
|
161428
161561
|
if (JSON.stringify(normalized.clusterIds) !== JSON.stringify(normalizeClusters(current.map((cluster) => cluster.ids)))) {
|
|
161429
161562
|
throw new DashboardMaintenanceError("Memory changed after the preview. Refresh before consolidating.", 409);
|
|
161430
161563
|
}
|
|
161431
|
-
const result = await executeConsolidation(
|
|
161564
|
+
const result = await executeConsolidation(
|
|
161565
|
+
context.projectRoot ?? context.dataDir,
|
|
161566
|
+
context.projectId,
|
|
161567
|
+
{ store: context.store }
|
|
161568
|
+
);
|
|
161432
161569
|
return { action: "consolidate", projectId: context.projectId, ...result };
|
|
161433
161570
|
}
|
|
161434
161571
|
async function retentionCandidates(context) {
|
|
@@ -162585,7 +162722,7 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
162585
162722
|
}
|
|
162586
162723
|
case "/config": {
|
|
162587
162724
|
const os6 = await import("os");
|
|
162588
|
-
const { existsSync:
|
|
162725
|
+
const { existsSync: existsSync23 } = await import("fs");
|
|
162589
162726
|
const { join: join25 } = await import("path");
|
|
162590
162727
|
const configProjectRoot = effectiveProjectRoot;
|
|
162591
162728
|
const resolved = getResolvedConfig({ projectRoot: configProjectRoot });
|
|
@@ -162613,7 +162750,7 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
162613
162750
|
if (fpath === null) {
|
|
162614
162751
|
files[key] = { exists: false, path: "unavailable", unavailable: true };
|
|
162615
162752
|
} else {
|
|
162616
|
-
files[key] = { exists:
|
|
162753
|
+
files[key] = { exists: existsSync23(fpath), path: fpath };
|
|
162617
162754
|
}
|
|
162618
162755
|
}
|
|
162619
162756
|
} catch {
|
|
@@ -163423,7 +163560,7 @@ var init_task_graph = __esm({
|
|
|
163423
163560
|
|
|
163424
163561
|
// src/orchestrate/context-collector.ts
|
|
163425
163562
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
163426
|
-
import { readFileSync as readFileSync15, existsSync as
|
|
163563
|
+
import { readFileSync as readFileSync15, existsSync as existsSync21 } from "fs";
|
|
163427
163564
|
import { join as join22 } from "path";
|
|
163428
163565
|
function normalizeEntryLimit(value, fallback) {
|
|
163429
163566
|
if (!Number.isSafeInteger(value) || value < 1) return fallback;
|
|
@@ -163500,7 +163637,7 @@ function collectFileTree(projectDir2, maxEntries) {
|
|
|
163500
163637
|
function collectDependencies(projectDir2) {
|
|
163501
163638
|
try {
|
|
163502
163639
|
const pkgPath = join22(projectDir2, "package.json");
|
|
163503
|
-
if (!
|
|
163640
|
+
if (!existsSync21(pkgPath)) return "";
|
|
163504
163641
|
const pkg = JSON.parse(readFileSync15(pkgPath, "utf-8"));
|
|
163505
163642
|
const parts = [];
|
|
163506
163643
|
if (pkg.dependencies && Object.keys(pkg.dependencies).length > 0) {
|
|
@@ -166001,11 +166138,11 @@ __export(hooks_path_exports, {
|
|
|
166001
166138
|
resolveGitDir: () => resolveGitDir,
|
|
166002
166139
|
resolveHooksDir: () => resolveHooksDir
|
|
166003
166140
|
});
|
|
166004
|
-
import { existsSync as
|
|
166141
|
+
import { existsSync as existsSync22, readFileSync as readFileSync16, statSync as statSync6, mkdirSync as mkdirSync6 } from "fs";
|
|
166005
166142
|
import path35 from "path";
|
|
166006
166143
|
function resolveGitDir(projectRoot) {
|
|
166007
166144
|
const dotGit = path35.join(projectRoot, ".git");
|
|
166008
|
-
if (!
|
|
166145
|
+
if (!existsSync22(dotGit)) return null;
|
|
166009
166146
|
const stat5 = statSync6(dotGit);
|
|
166010
166147
|
if (stat5.isDirectory()) {
|
|
166011
166148
|
return dotGit;
|
|
@@ -166017,7 +166154,7 @@ function resolveGitDir(projectRoot) {
|
|
|
166017
166154
|
if (match2) {
|
|
166018
166155
|
const gitdir = match2[1].trim();
|
|
166019
166156
|
const resolved = path35.isAbsolute(gitdir) ? gitdir : path35.resolve(projectRoot, gitdir);
|
|
166020
|
-
if (
|
|
166157
|
+
if (existsSync22(resolved)) {
|
|
166021
166158
|
return resolved;
|
|
166022
166159
|
}
|
|
166023
166160
|
}
|
|
@@ -168233,7 +168370,7 @@ var RulesSyncer = class {
|
|
|
168233
168370
|
|
|
168234
168371
|
// src/workspace/engine.ts
|
|
168235
168372
|
init_esm_shims();
|
|
168236
|
-
import { readFileSync as readFileSync10, readdirSync as readdirSync3, existsSync as
|
|
168373
|
+
import { readFileSync as readFileSync10, readdirSync as readdirSync3, existsSync as existsSync15, cpSync, mkdirSync as mkdirSync4 } from "fs";
|
|
168237
168374
|
import { join as join19 } from "path";
|
|
168238
168375
|
import { homedir as homedir21 } from "os";
|
|
168239
168376
|
|
|
@@ -169185,7 +169322,7 @@ function sanitize(input) {
|
|
|
169185
169322
|
|
|
169186
169323
|
// src/workspace/applier.ts
|
|
169187
169324
|
init_esm_shims();
|
|
169188
|
-
import { existsSync as
|
|
169325
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync3, copyFileSync, writeFileSync as writeFileSync3, unlinkSync as unlinkSync2, renameSync } from "fs";
|
|
169189
169326
|
import { dirname } from "path";
|
|
169190
169327
|
var WorkspaceSyncApplier = class {
|
|
169191
169328
|
/**
|
|
@@ -169211,7 +169348,7 @@ var WorkspaceSyncApplier = class {
|
|
|
169211
169348
|
for (const file of files) {
|
|
169212
169349
|
try {
|
|
169213
169350
|
const dir = dirname(file.filePath);
|
|
169214
|
-
if (!
|
|
169351
|
+
if (!existsSync14(dir)) {
|
|
169215
169352
|
mkdirSync3(dir, { recursive: true });
|
|
169216
169353
|
}
|
|
169217
169354
|
} catch (err) {
|
|
@@ -169220,7 +169357,7 @@ var WorkspaceSyncApplier = class {
|
|
|
169220
169357
|
}
|
|
169221
169358
|
}
|
|
169222
169359
|
for (const file of files) {
|
|
169223
|
-
if (
|
|
169360
|
+
if (existsSync14(file.filePath)) {
|
|
169224
169361
|
try {
|
|
169225
169362
|
const backupPath = file.filePath + `.backup-${Date.now()}`;
|
|
169226
169363
|
copyFileSync(file.filePath, backupPath);
|
|
@@ -169271,7 +169408,7 @@ var WorkspaceSyncApplier = class {
|
|
|
169271
169408
|
cleanBackups(backups) {
|
|
169272
169409
|
for (const backup of backups) {
|
|
169273
169410
|
try {
|
|
169274
|
-
if (
|
|
169411
|
+
if (existsSync14(backup.backupPath)) {
|
|
169275
169412
|
unlinkSync2(backup.backupPath);
|
|
169276
169413
|
}
|
|
169277
169414
|
} catch {
|
|
@@ -169336,7 +169473,7 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
|
|
|
169336
169473
|
}
|
|
169337
169474
|
const merged = /* @__PURE__ */ new Map();
|
|
169338
169475
|
for (const path36 of pathsToCheck) {
|
|
169339
|
-
if (
|
|
169476
|
+
if (existsSync15(path36)) {
|
|
169340
169477
|
try {
|
|
169341
169478
|
const content = readFileSync10(path36, "utf-8");
|
|
169342
169479
|
const servers = adapter.parse(content);
|
|
@@ -169390,7 +169527,7 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
|
|
|
169390
169527
|
const adapter = this.adapters.get(target);
|
|
169391
169528
|
const configPath = adapter.getConfigPath(this.projectRoot);
|
|
169392
169529
|
let configContent;
|
|
169393
|
-
if (target === "antigravity" &&
|
|
169530
|
+
if (target === "antigravity" && existsSync15(configPath)) {
|
|
169394
169531
|
try {
|
|
169395
169532
|
const existing = JSON.parse(readFileSync10(configPath, "utf-8"));
|
|
169396
169533
|
const generated = JSON.parse(adapter.generate(result.mcpServers.scanned));
|
|
@@ -169466,13 +169603,13 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
|
|
|
169466
169603
|
join19(home, dir)
|
|
169467
169604
|
];
|
|
169468
169605
|
for (const skillsRoot of paths) {
|
|
169469
|
-
if (!
|
|
169606
|
+
if (!existsSync15(skillsRoot)) continue;
|
|
169470
169607
|
try {
|
|
169471
169608
|
const entries = readdirSync3(skillsRoot, { withFileTypes: true });
|
|
169472
169609
|
for (const entry of entries) {
|
|
169473
169610
|
if (!entry.isDirectory()) continue;
|
|
169474
169611
|
const skillMd = join19(skillsRoot, entry.name, "SKILL.md");
|
|
169475
|
-
if (!
|
|
169612
|
+
if (!existsSync15(skillMd)) continue;
|
|
169476
169613
|
let description = "";
|
|
169477
169614
|
try {
|
|
169478
169615
|
const content = readFileSync10(skillMd, "utf-8");
|
|
@@ -169521,7 +169658,7 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
|
|
|
169521
169658
|
for (const skill2 of skills) {
|
|
169522
169659
|
if (skill2.sourceAgent === target) continue;
|
|
169523
169660
|
const dest = join19(targetDir, skill2.name);
|
|
169524
|
-
if (
|
|
169661
|
+
if (existsSync15(dest)) {
|
|
169525
169662
|
skipped.push(`${skill2.name} (already exists in ${target})`);
|
|
169526
169663
|
continue;
|
|
169527
169664
|
}
|
|
@@ -169537,7 +169674,7 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
|
|
|
169537
169674
|
scanWorkflows() {
|
|
169538
169675
|
const workflows = [];
|
|
169539
169676
|
const wfDir = join19(this.projectRoot, ".windsurf", "workflows");
|
|
169540
|
-
if (!
|
|
169677
|
+
if (!existsSync15(wfDir)) return workflows;
|
|
169541
169678
|
try {
|
|
169542
169679
|
const files = readdirSync3(wfDir).filter((f3) => f3.endsWith(".md"));
|
|
169543
169680
|
for (const file of files) {
|
|
@@ -169882,7 +170019,7 @@ var MCP_SERVER_INFO_META_KEY = "io.modelcontextprotocol/serverInfo";
|
|
|
169882
170019
|
function getMcpServerInfo() {
|
|
169883
170020
|
return {
|
|
169884
170021
|
name: "memorix",
|
|
169885
|
-
version: true ? "1.9.
|
|
170022
|
+
version: true ? "1.9.3" : "1.0.1"
|
|
169886
170023
|
};
|
|
169887
170024
|
}
|
|
169888
170025
|
function createMcpDiscoverResult(capabilities, serverInfo) {
|
|
@@ -174499,10 +174636,10 @@ Preview: ${analysis.description.slice(0, 300)}${analysis.description.length > 30
|
|
|
174499
174636
|
const { ensureHooksDir: ensureHooksDir2 } = await Promise.resolve().then(() => (init_hooks_path(), hooks_path_exports));
|
|
174500
174637
|
const resolved = ensureHooksDir2(project.rootPath);
|
|
174501
174638
|
if (resolved) {
|
|
174502
|
-
const { existsSync:
|
|
174639
|
+
const { existsSync: existsSync23, readFileSync: readFileSync17, writeFileSync: writeFileSync5, chmodSync } = await import("fs");
|
|
174503
174640
|
const { hookPath } = resolved;
|
|
174504
174641
|
const HOOK_MARKER = "# [memorix-git-hook]";
|
|
174505
|
-
const needsInstall = !
|
|
174642
|
+
const needsInstall = !existsSync23(hookPath) || !readFileSync17(hookPath, "utf-8").includes(HOOK_MARKER);
|
|
174506
174643
|
if (needsInstall) {
|
|
174507
174644
|
const hookScript = `#!/bin/sh
|
|
174508
174645
|
${HOOK_MARKER}
|
|
@@ -174511,7 +174648,7 @@ if command -v memorix >/dev/null 2>&1; then
|
|
|
174511
174648
|
memorix ingest commit --auto >/dev/null 2>&1 &
|
|
174512
174649
|
fi
|
|
174513
174650
|
`;
|
|
174514
|
-
if (
|
|
174651
|
+
if (existsSync23(hookPath)) {
|
|
174515
174652
|
const existing = readFileSync17(hookPath, "utf-8");
|
|
174516
174653
|
writeFileSync5(hookPath, existing.trimEnd() + `
|
|
174517
174654
|
|