@askexenow/exe-os 0.9.163 → 0.9.164

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.
@@ -4,7 +4,7 @@ import {
4
4
  } from "../chunk-ZKALIEHB.js";
5
5
  import {
6
6
  lightweightSearch
7
- } from "../chunk-FPBEJ2JV.js";
7
+ } from "../chunk-R6GFTKG5.js";
8
8
  import "../chunk-H3KFLVPW.js";
9
9
  import "../chunk-2M3CULM3.js";
10
10
  import "../chunk-MP2AFCGL.js";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  hybridSearch,
4
4
  lightweightSearch
5
- } from "../chunk-FPBEJ2JV.js";
5
+ } from "../chunk-R6GFTKG5.js";
6
6
  import {
7
7
  initStore
8
8
  } from "../chunk-H3KFLVPW.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  lightweightSearch
3
- } from "./chunk-FPBEJ2JV.js";
3
+ } from "./chunk-R6GFTKG5.js";
4
4
  import "./chunk-H3KFLVPW.js";
5
5
  import "./chunk-2M3CULM3.js";
6
6
  import {
@@ -172,8 +172,9 @@ import {
172
172
  } from "./chunk-LHLEFNFW.js";
173
173
  import {
174
174
  hybridSearch,
175
+ lastSearchDegraded,
175
176
  recentRecords
176
- } from "./chunk-FPBEJ2JV.js";
177
+ } from "./chunk-R6GFTKG5.js";
177
178
  import {
178
179
  getActiveAgent
179
180
  } from "./chunk-5G7BZIY3.js";
@@ -437,7 +438,7 @@ function registerRecallMyMemory(server) {
437
438
  results = await recentRecords(agentId, searchOptions, limit);
438
439
  }
439
440
  }
440
- const FEDERATION_THRESHOLD = 3;
441
+ const FEDERATION_THRESHOLD = 5;
441
442
  let federatedCount = 0;
442
443
  if (!recent && query && results.length < FEDERATION_THRESHOLD) {
443
444
  try {
@@ -463,21 +464,25 @@ ${cr.content}`,
463
464
  try {
464
465
  const { getClient: getClient2 } = await import("./lib/database.js");
465
466
  const client = getClient2();
467
+ const terms = query.split(/\s+/).filter((t) => t.length > 2).slice(0, 6);
468
+ const likeConditions = terms.map(() => "(e.name LIKE ? OR e.properties LIKE ? OR r.type LIKE ?)").join(" OR ");
469
+ const likeArgs = terms.flatMap((t) => [`%${t}%`, `%${t}%`, `%${t}%`]);
466
470
  const graphResults = await Promise.race([
467
471
  client.execute({
468
- sql: `SELECT e.name, e.type as entity_type, e.properties as description, r.type as relationship_type, r2.name as related_to
472
+ sql: `SELECT DISTINCT e.name, e.type as entity_type, e.properties as description,
473
+ r.type as relationship_type, r2.name as related_to, r2.type as related_type
469
474
  FROM entities e
470
475
  LEFT JOIN relationships r ON e.id = r.source_entity_id
471
476
  LEFT JOIN entities r2 ON r.target_entity_id = r2.id
472
- WHERE e.name LIKE ? OR e.properties LIKE ?
473
- LIMIT 5`,
474
- args: [`%${query.slice(0, 50)}%`, `%${query.slice(0, 50)}%`]
477
+ WHERE ${likeConditions || "1=0"}
478
+ LIMIT 10`,
479
+ args: likeArgs
475
480
  }),
476
- new Promise((_, rej) => setTimeout(() => rej(new Error("timeout")), 2e3))
481
+ new Promise((_, rej) => setTimeout(() => rej(new Error("timeout")), 3e3))
477
482
  ]);
478
483
  for (let i = 0; i < (graphResults.rows?.length ?? 0); i++) {
479
484
  const gr = graphResults.rows[i];
480
- const relPart = gr.related_to ? ` \u2192 ${gr.relationship_type} \u2192 ${gr.related_to}` : "";
485
+ const relPart = gr.related_to ? ` \u2192 ${gr.relationship_type} \u2192 ${gr.related_to} (${gr.related_type})` : "";
481
486
  results.push({
482
487
  id: `federated-graph-${results.length}`,
483
488
  raw_text: `[graph] ${gr.name} (${gr.entity_type})${relPart}
@@ -517,13 +522,14 @@ ${gr.description ?? ""}`,
517
522
  const federatedNote = federatedCount > 0 ? `
518
523
 
519
524
  [Federated recall: ${federatedCount} result(s) from code_context/graph (memory had < ${FEDERATION_THRESHOLD} matches)]` : "";
525
+ const degradedWarning = !recent && lastSearchDegraded ? '\n\n\u26A0\uFE0F DEGRADED SEARCH: Embedding daemon is offline \u2014 using keyword matching only (no semantic search). Results may be incomplete. Try graph(action="query_relationships") or graph(action="entity_neighbors") for structured/relational queries.' : "";
520
526
  return {
521
527
  content: [
522
528
  {
523
529
  type: "text",
524
530
  text: `Found ${results.length} memories:
525
531
 
526
- ${formatted}${federatedNote}`
532
+ ${formatted}${federatedNote}${degradedWarning}`
527
533
  }
528
534
  ]
529
535
  };
@@ -10,6 +10,7 @@ import {
10
10
 
11
11
  // src/lib/hybrid-search.ts
12
12
  var RRF_K = 60;
13
+ var lastSearchDegraded = false;
13
14
  var _cardinalityCache = /* @__PURE__ */ new Map();
14
15
  var CARDINALITY_TTL_MS = 6e4;
15
16
  async function getCachedCardinality(agentId) {
@@ -173,7 +174,9 @@ async function hybridSearch(queryText, agentId, options) {
173
174
  try {
174
175
  const { embed } = await import("./lib/embedder.js");
175
176
  queryVector = await embed(effectiveQuery);
177
+ lastSearchDegraded = false;
176
178
  } catch {
179
+ lastSearchDegraded = true;
177
180
  if (!process.env.VITEST) {
178
181
  process.stderr.write("[hybrid-search] Embed daemon unavailable \u2014 FTS-only mode\n");
179
182
  }
@@ -966,6 +969,7 @@ async function trajectoryBypass(queryText, agentId, options, limit) {
966
969
  }
967
970
 
968
971
  export {
972
+ lastSearchDegraded,
969
973
  hybridSearch,
970
974
  estimateCardinality,
971
975
  rrfMerge,
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  hybridSearch,
6
6
  lightweightSearch
7
- } from "../chunk-FPBEJ2JV.js";
7
+ } from "../chunk-R6GFTKG5.js";
8
8
  import "../chunk-SH45SJQW.js";
9
9
  import {
10
10
  getActiveAgent
@@ -5,7 +5,7 @@ import "../chunk-YSU7JB7H.js";
5
5
  import {
6
6
  hybridSearch,
7
7
  lightweightSearch
8
- } from "../chunk-FPBEJ2JV.js";
8
+ } from "../chunk-R6GFTKG5.js";
9
9
  import "../chunk-SH45SJQW.js";
10
10
  import {
11
11
  getActiveAgent
@@ -97,7 +97,7 @@ process.stdin.on("end", async () => {
97
97
  query = `last actions on ${projectName}`;
98
98
  header = "## Resuming Session\nHere's where you left off:";
99
99
  try {
100
- const { buildCatchupBrief } = await import("../catchup-brief-MTPBB3KF.js");
100
+ const { buildCatchupBrief } = await import("../catchup-brief-VMGUUTZ4.js");
101
101
  const brief = await buildCatchupBrief(
102
102
  agentId,
103
103
  projectName,
@@ -2302,16 +2302,26 @@ var CLOUD_SYNC_CIRCUIT_BREAK = 10;
2302
2302
  var _cloudSyncConsecutiveFailures = 0;
2303
2303
  var _cloudSyncBackoffMs = 0;
2304
2304
  var _cloudSyncPaused = false;
2305
+ var _cloudSyncPausedAt = 0;
2306
+ var CLOUD_SYNC_AUTO_RECOVERY_MS = 30 * 6e4;
2305
2307
  function startCloudSyncTimer() {
2306
2308
  const tick = async () => {
2307
2309
  fired("cloud_sync");
2308
2310
  if (_cloudSyncPaused) {
2309
- if (_cloudSyncConsecutiveFailures > 0 && _cloudSyncConsecutiveFailures % 20 === 0) {
2310
- process.stderr.write(`[exed] Cloud sync still paused after ${_cloudSyncConsecutiveFailures} failures. Server may be unreachable.
2311
+ if (Date.now() - _cloudSyncPausedAt > CLOUD_SYNC_AUTO_RECOVERY_MS) {
2312
+ process.stderr.write(`[exed] Cloud sync auto-recovery: retrying after ${Math.round(CLOUD_SYNC_AUTO_RECOVERY_MS / 6e4)}m pause
2311
2313
  `);
2314
+ _cloudSyncPaused = false;
2315
+ _cloudSyncConsecutiveFailures = 0;
2316
+ _cloudSyncBackoffMs = 0;
2317
+ } else {
2318
+ if (_cloudSyncConsecutiveFailures > 0 && _cloudSyncConsecutiveFailures % 20 === 0) {
2319
+ process.stderr.write(`[exed] Cloud sync still paused after ${_cloudSyncConsecutiveFailures} failures (auto-retry in ${Math.round((CLOUD_SYNC_AUTO_RECOVERY_MS - (Date.now() - _cloudSyncPausedAt)) / 6e4)}m)
2320
+ `);
2321
+ }
2322
+ _cloudSyncConsecutiveFailures++;
2323
+ return;
2312
2324
  }
2313
- _cloudSyncConsecutiveFailures++;
2314
- return;
2315
2325
  }
2316
2326
  if (_cloudSyncBackoffMs > 0) {
2317
2327
  _cloudSyncBackoffMs = Math.max(0, _cloudSyncBackoffMs - CLOUD_SYNC_INTERVAL_MS);
@@ -2349,6 +2359,7 @@ function startCloudSyncTimer() {
2349
2359
  );
2350
2360
  if (_cloudSyncConsecutiveFailures >= CLOUD_SYNC_CIRCUIT_BREAK) {
2351
2361
  _cloudSyncPaused = true;
2362
+ _cloudSyncPausedAt = Date.now();
2352
2363
  process.stderr.write(
2353
2364
  `[exed] Cloud sync PAUSED after ${CLOUD_SYNC_CIRCUIT_BREAK} consecutive failures. Last error: ${msg}. Will retry when daemon restarts or /exe-cloud sync is run manually.
2354
2365
  `
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  estimateCardinality,
3
3
  hybridSearch,
4
+ lastSearchDegraded,
4
5
  lightweightSearch,
5
6
  recentRecords,
6
7
  rrfMerge,
7
8
  rrfMergeMulti
8
- } from "../chunk-FPBEJ2JV.js";
9
+ } from "../chunk-R6GFTKG5.js";
9
10
  import "../chunk-H3KFLVPW.js";
10
11
  import "../chunk-2M3CULM3.js";
11
12
  import "../chunk-MP2AFCGL.js";
@@ -19,6 +20,7 @@ import "../chunk-MLKGABMK.js";
19
20
  export {
20
21
  estimateCardinality,
21
22
  hybridSearch,
23
+ lastSearchDegraded,
22
24
  lightweightSearch,
23
25
  recentRecords,
24
26
  rrfMerge,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  registerAllTools
3
- } from "../chunk-A4NCK74X.js";
3
+ } from "../chunk-MM3XXKC5.js";
4
4
  import "../chunk-RLHQMWLV.js";
5
5
  import "../chunk-ESRI7MFI.js";
6
6
  import "../chunk-PLNYW6PA.js";
@@ -52,7 +52,7 @@ import "../chunk-T5YT64SZ.js";
52
52
  import "../chunk-MPCICOVG.js";
53
53
  import "../chunk-ZKALIEHB.js";
54
54
  import "../chunk-LHLEFNFW.js";
55
- import "../chunk-FPBEJ2JV.js";
55
+ import "../chunk-R6GFTKG5.js";
56
56
  import "../chunk-5G7BZIY3.js";
57
57
  import "../chunk-G4FDG3LK.js";
58
58
  import "../chunk-CMFLJNP6.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "../chunk-V4TZI6EO.js";
4
4
  import {
5
5
  registerAllTools
6
- } from "../chunk-A4NCK74X.js";
6
+ } from "../chunk-MM3XXKC5.js";
7
7
  import "../chunk-RLHQMWLV.js";
8
8
  import "../chunk-ESRI7MFI.js";
9
9
  import {
@@ -62,7 +62,7 @@ import "../chunk-T5YT64SZ.js";
62
62
  import "../chunk-MPCICOVG.js";
63
63
  import "../chunk-ZKALIEHB.js";
64
64
  import "../chunk-LHLEFNFW.js";
65
- import "../chunk-FPBEJ2JV.js";
65
+ import "../chunk-R6GFTKG5.js";
66
66
  import "../chunk-5G7BZIY3.js";
67
67
  import "../chunk-G4FDG3LK.js";
68
68
  import "../chunk-CMFLJNP6.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askexenow/exe-os",
3
- "version": "0.9.163",
3
+ "version": "0.9.164",
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",
@@ -1,8 +1,8 @@
1
1
  {
2
- "current": "0.9.163",
2
+ "current": "0.9.164",
3
3
  "notes": {
4
- "0.9.163": {
5
- "version": "0.9.163",
4
+ "0.9.164": {
5
+ "version": "0.9.164",
6
6
  "date": "2026-05-30",
7
7
  "features": [
8
8
  "add worktree reaper daemon job to prune orphaned agent worktrees",
@@ -104,8 +104,8 @@
104
104
  "exe-daemon.ts kills old embed.pid process and cleans up"
105
105
  ]
106
106
  },
107
- "0.9.162": {
108
- "version": "0.9.162",
107
+ "0.9.163": {
108
+ "version": "0.9.163",
109
109
  "date": "2026-05-30",
110
110
  "features": [
111
111
  "add worktree reaper daemon job to prune orphaned agent worktrees",
@@ -207,8 +207,8 @@
207
207
  "exe-daemon.ts kills old embed.pid process and cleans up"
208
208
  ]
209
209
  },
210
- "0.9.161": {
211
- "version": "0.9.161",
210
+ "0.9.162": {
211
+ "version": "0.9.162",
212
212
  "date": "2026-05-30",
213
213
  "features": [
214
214
  "add worktree reaper daemon job to prune orphaned agent worktrees",
@@ -238,6 +238,7 @@
238
238
  "blocked task notification — ping dispatcher immediately on status change"
239
239
  ],
240
240
  "fixes": [
241
+ "zombie reaper must never kill TTY-attached sessions + death log",
241
242
  "update readiness gate to check daemon-restart-orchestrator",
242
243
  "resolve TS errors blocking publish — unused import + undefined row",
243
244
  "zombie agent reaper + deferred daemon restart (OOM crash fix)",
@@ -261,8 +262,7 @@
261
262
  "DMR retrieval 20% → 100% — stop words, name filtering, speaker fix",
262
263
  "kill idle Codex/OpenCode sessions instead of sending intercom — enables auto-wake respawn",
263
264
  "suppress daemon auto-reconnect noise — only log after attempt 2+",
264
- "remove E2EE from bug reports — support intake must be readable server-side",
265
- "support API — verified encrypted bug reports work (HTTP 201)"
265
+ "remove E2EE from bug reports — support intake must be readable server-side"
266
266
  ],
267
267
  "security": [
268
268
  "fix shell injection, SSRF, socket leaks, backup validation",
@@ -310,10 +310,12 @@
310
310
  "exe-daemon.ts kills old embed.pid process and cleans up"
311
311
  ]
312
312
  },
313
- "0.9.160": {
314
- "version": "0.9.160",
313
+ "0.9.161": {
314
+ "version": "0.9.161",
315
315
  "date": "2026-05-30",
316
316
  "features": [
317
+ "add worktree reaper daemon job to prune orphaned agent worktrees",
318
+ "add pre-flight gates to close_task — status gate, worktree check, commit recency",
317
319
  "add wiki document ingestion via API for embedding pipeline",
318
320
  "add filtered.* projection targets to projection worker",
319
321
  "verify-stack post-deploy checks — 8 runtime validations",
@@ -336,11 +338,14 @@
336
338
  "update safety + portable backups + restore",
337
339
  "complete deployment readiness — all 14 second-pass blind spots fixed",
338
340
  "production-ready stack — all 15 blind spots fixed",
339
- "blocked task notification — ping dispatcher immediately on status change",
340
- "self-improving skills — usage tracking, success counting, and refinement daemon",
341
- "4 retrieval improvements — query expansion, stop words, contradiction resolution, abstention"
341
+ "blocked task notification — ping dispatcher immediately on status change"
342
342
  ],
343
343
  "fixes": [
344
+ "update readiness gate to check daemon-restart-orchestrator",
345
+ "resolve TS errors blocking publish — unused import + undefined row",
346
+ "zombie agent reaper + deferred daemon restart (OOM crash fix)",
347
+ "idle-kill now reaps Codex/OpenCode sessions (bug 47d1e446)",
348
+ "change orphaned task terminal state from blocked → needs_review",
344
349
  "auto-close temporal guard + session_scope fallback + orphan cleanup safety",
345
350
  "cloud sync skip-bad-rows + age-based orphan hook reaper",
346
351
  "clean unused imports + publish gate fixes for v0.9.159",
@@ -360,12 +365,7 @@
360
365
  "kill idle Codex/OpenCode sessions instead of sending intercom — enables auto-wake respawn",
361
366
  "suppress daemon auto-reconnect noise — only log after attempt 2+",
362
367
  "remove E2EE from bug reports — support intake must be readable server-side",
363
- "support API — verified encrypted bug reports work (HTTP 201)",
364
- "support API accepts encrypted bug reports — prevents HTTP 400",
365
- "Codex agents recheck tasks before stopping — prevents idle-with-open-tasks",
366
- "P0 #13 session_scope in cleanup SELECT + P0 #6 wire review signal files",
367
- "add scope import to prompt-submit — gate pass",
368
- "add writeFileSync import to config.ts"
368
+ "support API — verified encrypted bug reports work (HTTP 201)"
369
369
  ],
370
370
  "security": [
371
371
  "fix shell injection, SSRF, socket leaks, backup validation",
@@ -413,10 +413,12 @@
413
413
  "exe-daemon.ts kills old embed.pid process and cleans up"
414
414
  ]
415
415
  },
416
- "0.9.159": {
417
- "version": "0.9.159",
418
- "date": "2026-05-29",
416
+ "0.9.160": {
417
+ "version": "0.9.160",
418
+ "date": "2026-05-30",
419
419
  "features": [
420
+ "add wiki document ingestion via API for embedding pipeline",
421
+ "add filtered.* projection targets to projection worker",
420
422
  "verify-stack post-deploy checks — 8 runtime validations",
421
423
  "preflight deploy gate + filtered schema + gateway graceful degradation",
422
424
  "harden /exe-afk as primary monitoring tool, deprecate /loop for orchestration",
@@ -439,16 +441,12 @@
439
441
  "production-ready stack — all 15 blind spots fixed",
440
442
  "blocked task notification — ping dispatcher immediately on status change",
441
443
  "self-improving skills — usage tracking, success counting, and refinement daemon",
442
- "4 retrieval improvements — query expansion, stop words, contradiction resolution, abstention",
443
- "competitive roadmap — serverless tier, identity depth, self-improving skills, user modeling",
444
- "run database migrations before container swap in stack-update"
444
+ "4 retrieval improvements — query expansion, stop words, contradiction resolution, abstention"
445
445
  ],
446
446
  "fixes": [
447
- "cloud sync NOT NULL resilience sqlSafeRequired() defaults + per-record error handling, skip bad rows instead of retry storm",
448
- "auto-close temporal guard reject commits older than task creation date, raise threshold 0.6→0.8",
449
- "session_scope fallback listTasks returns unscoped results when scoped query finds 0 after daemon restart",
450
- "orphan task file cleanup safety — 24h threshold (was 1h) + ID-based fallback before deleting",
451
- "blocked task escalation — writeNotification to COO when auto-wake fails 3x and marks task blocked",
447
+ "auto-close temporal guard + session_scope fallback + orphan cleanup safety",
448
+ "cloud sync skip-bad-rows + age-based orphan hook reaper",
449
+ "clean unused imports + publish gate fixes for v0.9.159",
452
450
  "daemon memory cascade — prevent duplicate daemons, reap orphan hooks, cap heap",
453
451
  "auto-inject timeout on tmux capture-pane to prevent session freeze",
454
452
  "auto-wake crash loop — filter boot memories + circuit breaker",
@@ -468,7 +466,9 @@
468
466
  "support API — verified encrypted bug reports work (HTTP 201)",
469
467
  "support API accepts encrypted bug reports — prevents HTTP 400",
470
468
  "Codex agents recheck tasks before stopping — prevents idle-with-open-tasks",
471
- "P0 #13 session_scope in cleanup SELECT + P0 #6 wire review signal files"
469
+ "P0 #13 session_scope in cleanup SELECT + P0 #6 wire review signal files",
470
+ "add scope import to prompt-submit — gate pass",
471
+ "add writeFileSync import to config.ts"
472
472
  ],
473
473
  "security": [
474
474
  "fix shell injection, SSRF, socket leaks, backup validation",
@@ -485,6 +485,8 @@
485
485
  "fix 4 pricing tier bypass vulnerabilities (audit F1-F4)"
486
486
  ],
487
487
  "other": [
488
+ "bump v0.9.160 — cloud sync resilience + orphan reaper + auto-close guard",
489
+ "update release notes with 5 bug fixes from support triage",
488
490
  "bump v0.9.159 — daemon memory cascade fix + session_scope + benchmarks",
489
491
  "arch: customer onboarding automation — exe-os deploy-customer command",
490
492
  "arch: Fleet Operations Roadmap — 8 phases for production safety at scale",
@@ -507,9 +509,7 @@
507
509
  "publish v0.9.144 — ESM require() fix + reliable task signals + OAuth 2.1",
508
510
  "add MCP tool tests for message, cloud-sync, and file-copy",
509
511
  "add coverage for send_message, cloud_sync, file_copy MCP tools (Track A)",
510
- "Recover MCP sessions after daemon restart",
511
- "publish v0.9.143 — all fixes live",
512
- "publish v0.9.142"
512
+ "Recover MCP sessions after daemon restart"
513
513
  ],
514
514
  "migration_notes": [
515
515
  "If daemon goes down, agents will now fail instead of silently",