@askexenow/exe-os 0.9.186 → 0.9.188

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.
@@ -11,7 +11,7 @@ import {
11
11
  patchEnv,
12
12
  readCurrentStackVersion,
13
13
  runStackUpdate
14
- } from "../chunk-BV7EZIL4.js";
14
+ } from "../chunk-VKUOC7AR.js";
15
15
  import "../chunk-MVMMULOJ.js";
16
16
  import "../chunk-4GXRETYL.js";
17
17
  import "../chunk-LYH5HE24.js";
@@ -207,7 +207,7 @@ async function main(args) {
207
207
  console.log("[health-gate] Starting rollback...");
208
208
  restorePreDeployBackup();
209
209
  try {
210
- const { rollbackStackUpdate, defaultStackPaths } = await import("../stack-update-LEUGR7HP.js");
210
+ const { rollbackStackUpdate, defaultStackPaths } = await import("../stack-update-VN5SBY4U.js");
211
211
  const paths = defaultStackPaths();
212
212
  await rollbackStackUpdate({
213
213
  manifestRef: paths.manifestRef,
@@ -116,6 +116,10 @@ import {
116
116
  mergeEntities
117
117
  } from "./chunk-GP6G6EQI.js";
118
118
  import {
119
+ fixBloated,
120
+ fixDuplicates,
121
+ fixNullVectors,
122
+ fixShards,
119
123
  formatReport,
120
124
  runAudit
121
125
  } from "./chunk-PN22OPA3.js";
@@ -5515,18 +5519,22 @@ function registerRunMemoryAudit(server) {
5515
5519
  "run_memory_audit",
5516
5520
  {
5517
5521
  title: "Run Memory Audit",
5518
- description: "Run a memory health audit: total counts, per-agent breakdown, null vectors, duplicates, FTS sync status, bloated records, and conflict detection (contradictory/superseded memories).",
5522
+ description: "Run a memory health audit: total counts, per-agent breakdown, null vectors, duplicates, FTS sync status, bloated records, and conflict detection (contradictory/superseded memories). Pass fix=true to apply repairs (delete duplicates, chunk bloated records, rebuild FTS, archive unreadable shards).",
5519
5523
  inputSchema: {
5520
5524
  agent_id: z51.string().optional().describe("Filter audit to a specific agent"),
5521
- project_name: z51.string().optional().describe("Filter audit to a specific project")
5525
+ project_name: z51.string().optional().describe("Filter audit to a specific project"),
5526
+ fix: z51.boolean().optional().default(false).describe("Apply fixes: delete duplicates, chunk bloated records, rebuild FTS, archive shards"),
5527
+ dry_run: z51.boolean().optional().default(false).describe("Preview fixes without applying them")
5522
5528
  }
5523
5529
  },
5524
- async ({ agent_id, project_name }) => {
5530
+ async ({ agent_id, project_name, fix, dry_run }) => {
5525
5531
  try {
5526
5532
  const client = getClient();
5533
+ const shouldFix = fix === true;
5534
+ const isDryRun = dry_run === true;
5527
5535
  const flags = {
5528
- fix: false,
5529
- dryRun: false,
5536
+ fix: shouldFix,
5537
+ dryRun: isDryRun,
5530
5538
  verbose: true,
5531
5539
  conflicts: false,
5532
5540
  // O(n²) — opt-in only via CLI --conflicts
@@ -5534,7 +5542,60 @@ function registerRunMemoryAudit(server) {
5534
5542
  project: project_name
5535
5543
  };
5536
5544
  const report = await runAudit(client, flags);
5537
- const formatted = formatReport(report, flags);
5545
+ let formatted = formatReport(report, flags);
5546
+ if (shouldFix || isDryRun) {
5547
+ const mode = isDryRun ? "[dry-run]" : "[fix]";
5548
+ const fixLog = [`
5549
+ ${mode} Applying repairs...
5550
+ `];
5551
+ if (!isDryRun) {
5552
+ try {
5553
+ const { createBackup: createBackup2 } = await import("./db-backup-7UOCAPHO.js");
5554
+ const backupPath = createBackup2("pre-fix");
5555
+ if (backupPath) {
5556
+ fixLog.push(` Backup created: ${backupPath.split("/").pop()}`);
5557
+ }
5558
+ } catch {
5559
+ fixLog.push(" Warning: backup failed \u2014 proceeding with fix anyway");
5560
+ }
5561
+ }
5562
+ if (report.nullVectors > 0) {
5563
+ fixLog.push(`${mode} Backfilling ${report.nullVectors} null vectors...`);
5564
+ if (!isDryRun) {
5565
+ try {
5566
+ await fixNullVectors();
5567
+ fixLog.push(" Done.");
5568
+ } catch (err) {
5569
+ fixLog.push(` Failed: ${err instanceof Error ? err.message : String(err)}`);
5570
+ }
5571
+ }
5572
+ }
5573
+ if (report.duplicateCount > 0) {
5574
+ fixLog.push(`${mode} Removing ${report.duplicateCount} duplicates...`);
5575
+ const deleted = await fixDuplicates(client, report.duplicates, isDryRun);
5576
+ fixLog.push(` ${isDryRun ? "Would remove" : "Removed"} ${deleted} records.`);
5577
+ }
5578
+ if (report.bloated.length > 0) {
5579
+ fixLog.push(`${mode} Splitting ${report.bloated.length} bloated records...`);
5580
+ const chunks = await fixBloated(client, report.bloated, isDryRun);
5581
+ fixLog.push(` ${isDryRun ? "Would create" : "Created"} ${chunks} chunks.`);
5582
+ }
5583
+ if (!report.fts.inSync) {
5584
+ fixLog.push(`${mode} Rebuilding FTS index...`);
5585
+ if (!isDryRun) {
5586
+ await client.execute("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
5587
+ fixLog.push(" Done.");
5588
+ }
5589
+ }
5590
+ if (report.shards.unreadable > 0) {
5591
+ fixLog.push(`${mode} Archiving ${report.shards.unreadable} unreadable shard(s)...`);
5592
+ const fixed = await fixShards(isDryRun);
5593
+ fixLog.push(` ${isDryRun ? "Would archive" : "Archived"} ${isDryRun ? fixed.unreadable : fixed.archived} shard(s).`);
5594
+ }
5595
+ fixLog.push(`
5596
+ ${mode} Complete.`);
5597
+ formatted += "\n" + fixLog.join("\n");
5598
+ }
5538
5599
  return {
5539
5600
  content: [{ type: "text", text: formatted }]
5540
5601
  };
@@ -503,7 +503,7 @@ async function runStackUpdate(options) {
503
503
  assertBindMountsExist(path.dirname(options.envFile));
504
504
  if (!options.dryRun) {
505
505
  try {
506
- const { runPreflight } = await import("./preflight-3KY5JETE.js");
506
+ const { runPreflight } = await import("./preflight-EAH2MI76.js");
507
507
  const preflightReport = runPreflight({
508
508
  composeFile: options.composeFile,
509
509
  envFile: options.envFile
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  registerAllTools
3
- } from "../chunk-UVGJYMSN.js";
3
+ } from "../chunk-AJOAKMJ5.js";
4
4
  import "../chunk-PLNYW6PA.js";
5
5
  import "../chunk-R4IK2YT3.js";
6
6
  import "../chunk-KEDP4X4H.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "../chunk-V4TZI6EO.js";
4
4
  import {
5
5
  registerAllTools
6
- } from "../chunk-UVGJYMSN.js";
6
+ } from "../chunk-AJOAKMJ5.js";
7
7
  import {
8
8
  initLicenseGate
9
9
  } from "../chunk-PLNYW6PA.js";
@@ -224,7 +224,16 @@ try {
224
224
  _currentMcpVersion = existsSync(MCP_VERSION_PATH) ? readFileSync(MCP_VERSION_PATH, "utf8").trim() : null;
225
225
  } catch {
226
226
  }
227
- const skipHotReload = process.env.EXE_MCP_NO_HOT_RELOAD === "1" || (process.env.AGENT_ROLE || "").toLowerCase().includes("coo");
227
+ let isCooSession = (process.env.AGENT_ROLE || "").toLowerCase().includes("coo");
228
+ if (!isCooSession) {
229
+ try {
230
+ const { getAgentContext } = await import("../agent-context-AZTTMUHP.js");
231
+ const ctx = getAgentContext();
232
+ if (ctx?.agentRole?.toLowerCase().includes("coo")) isCooSession = true;
233
+ } catch {
234
+ }
235
+ }
236
+ const skipHotReload = process.env.EXE_MCP_NO_HOT_RELOAD === "1" || isCooSession;
228
237
  const _versionWatchdog = setInterval(() => {
229
238
  if (skipHotReload) return;
230
239
  try {
@@ -100,8 +100,31 @@ function checkVolumePreservation(composeContent) {
100
100
  for (const req of VOLUME_REQUIREMENTS) {
101
101
  const serviceRegex = new RegExp(`^\\s+${req.service}:`, "m");
102
102
  if (!serviceRegex.test(composeContent)) continue;
103
- const serviceMatch = composeContent.match(new RegExp(`^\\s+${req.service}:[\\s\\S]*?(?=^\\s+\\w+:|^volumes:|^networks:|$)`, "m"));
104
- if (serviceMatch && !serviceMatch[0].includes("volumes:")) {
103
+ const lines = composeContent.split("\n");
104
+ let serviceBlock = "";
105
+ let inService = false;
106
+ let serviceIndent = -1;
107
+ for (const line of lines) {
108
+ if (!inService) {
109
+ const headerMatch = line.match(new RegExp(`^(\\s+)${req.service}:\\s*`));
110
+ if (headerMatch) {
111
+ inService = true;
112
+ serviceIndent = headerMatch[1].length;
113
+ serviceBlock += line + "\n";
114
+ }
115
+ continue;
116
+ }
117
+ if (line.trim() === "" || line.trim().startsWith("#")) {
118
+ serviceBlock += line + "\n";
119
+ continue;
120
+ }
121
+ const currentIndent = line.match(/^(\s*)/)?.[1]?.length ?? 0;
122
+ if (currentIndent <= serviceIndent) {
123
+ break;
124
+ }
125
+ serviceBlock += line + "\n";
126
+ }
127
+ if (serviceBlock && !serviceBlock.includes("volumes:")) {
105
128
  missing.push(`${req.service} (${req.description})`);
106
129
  }
107
130
  }
@@ -20,7 +20,7 @@ import {
20
20
  runStackUpdate,
21
21
  verifyReleaseHealth,
22
22
  verifyStackManifestSignature
23
- } from "./chunk-BV7EZIL4.js";
23
+ } from "./chunk-VKUOC7AR.js";
24
24
  import "./chunk-MVMMULOJ.js";
25
25
  import "./chunk-4GXRETYL.js";
26
26
  import "./chunk-LYH5HE24.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askexenow/exe-os",
3
- "version": "0.9.186",
3
+ "version": "0.9.188",
4
4
  "description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",