@askexenow/exe-os 0.9.161 → 0.9.163

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.
@@ -5,12 +5,32 @@ import {
5
5
  import "../chunk-MLKGABMK.js";
6
6
 
7
7
  // src/bin/deferred-daemon-restart.ts
8
- import { existsSync, openSync, closeSync } from "fs";
8
+ import { existsSync, openSync, closeSync, writeFileSync, unlinkSync } from "fs";
9
9
  import { spawn, execSync } from "child_process";
10
10
  import path from "path";
11
11
  import os from "os";
12
12
  var EXE_DIR = path.join(os.homedir(), ".exe-os");
13
13
  var DAEMON_PORT = 48739;
14
+ var DEFERRED_RESTART_PID_PATH = path.join(EXE_DIR, "deferred-restart.pid");
15
+ try {
16
+ writeFileSync(DEFERRED_RESTART_PID_PATH, String(process.pid));
17
+ } catch {
18
+ }
19
+ function cleanupPid() {
20
+ try {
21
+ unlinkSync(DEFERRED_RESTART_PID_PATH);
22
+ } catch {
23
+ }
24
+ }
25
+ process.on("exit", cleanupPid);
26
+ process.on("SIGTERM", () => {
27
+ cleanupPid();
28
+ process.exit(0);
29
+ });
30
+ process.on("SIGINT", () => {
31
+ cleanupPid();
32
+ process.exit(0);
33
+ });
14
34
  var DELAY_MS = parseInt(process.env.EXE_DEFERRED_DELAY_MS ?? "3000", 10);
15
35
  await new Promise((resolve) => setTimeout(resolve, DELAY_MS));
16
36
  process.stderr.write("[deferred-restart] Starting daemon restart...\n");
@@ -27,7 +27,7 @@ import "../chunk-LYH5HE24.js";
27
27
  import "../chunk-MLKGABMK.js";
28
28
 
29
29
  // src/bin/install.ts
30
- import { existsSync, openSync, closeSync } from "fs";
30
+ import { existsSync, openSync, closeSync, writeFileSync, readFileSync, unlinkSync, statSync } from "fs";
31
31
  import { spawn, execSync } from "child_process";
32
32
  import path from "path";
33
33
  import os from "os";
@@ -85,7 +85,35 @@ function spawnDaemonInline(pkgRoot) {
85
85
  }
86
86
  process.stderr.write(healthy ? "exe-os: daemon restarted and healthy\n" : "exe-os: daemon spawned but health check pending\n");
87
87
  }
88
+ var DEFERRED_RESTART_PID_PATH = path.join(EXE_DIR, "deferred-restart.pid");
89
+ function isDeferredRestartRunning() {
90
+ try {
91
+ if (!existsSync(DEFERRED_RESTART_PID_PATH)) return false;
92
+ const pid = parseInt(readFileSync(DEFERRED_RESTART_PID_PATH, "utf8").trim(), 10);
93
+ if (isNaN(pid) || pid <= 0) return false;
94
+ const age = Date.now() - statSync(DEFERRED_RESTART_PID_PATH).mtimeMs;
95
+ if (age > 6e4) {
96
+ try {
97
+ unlinkSync(DEFERRED_RESTART_PID_PATH);
98
+ } catch {
99
+ }
100
+ return false;
101
+ }
102
+ process.kill(pid, 0);
103
+ return true;
104
+ } catch {
105
+ try {
106
+ unlinkSync(DEFERRED_RESTART_PID_PATH);
107
+ } catch {
108
+ }
109
+ return false;
110
+ }
111
+ }
88
112
  function restartDaemon() {
113
+ if (isDeferredRestartRunning()) {
114
+ process.stderr.write("exe-os: deferred restart already running \u2014 skipping duplicate\n");
115
+ return;
116
+ }
89
117
  updateMcpVersionMarker();
90
118
  const pkgRoot = resolvePackageRoot();
91
119
  const deferredScript = path.join(pkgRoot, "dist", "bin", "deferred-daemon-restart.js");
@@ -107,6 +135,12 @@ function restartDaemon() {
107
135
  env: { ...process.env }
108
136
  });
109
137
  child.unref();
138
+ if (child.pid) {
139
+ try {
140
+ writeFileSync(DEFERRED_RESTART_PID_PATH, String(child.pid));
141
+ } catch {
142
+ }
143
+ }
110
144
  if (typeof stderrFd === "number") {
111
145
  try {
112
146
  closeSync(stderrFd);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AUTO_WAKE_MAX_RETRIES
3
- } from "./chunk-BZYHF63H.js";
3
+ } from "./chunk-RLHQMWLV.js";
4
4
  import {
5
5
  getToolCapabilityIndex
6
6
  } from "./chunk-ESRI7MFI.js";
@@ -1119,12 +1119,13 @@ function reapZombieAgentProcesses(deps) {
1119
1119
  const reaped = [];
1120
1120
  const procMap = /* @__PURE__ */ new Map();
1121
1121
  for (const line of lines) {
1122
- const match = line.trim().match(/^(\d+)\s+(\d+)\s+(\S+)\s+(.+)$/);
1122
+ const match = line.trim().match(/^(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(.+)$/);
1123
1123
  if (!match) continue;
1124
1124
  procMap.set(parseInt(match[1], 10), {
1125
1125
  ppid: parseInt(match[2], 10),
1126
1126
  etime: match[3],
1127
- args: match[4]
1127
+ tty: match[4],
1128
+ args: match[5]
1128
1129
  });
1129
1130
  }
1130
1131
  const AGENT_PATTERNS = [
@@ -1141,6 +1142,9 @@ function reapZombieAgentProcesses(deps) {
1141
1142
  if (!isAgent) continue;
1142
1143
  const ageSecs = parseEtime(info.etime);
1143
1144
  if (ageSecs < ZOMBIE_AGENT_MAX_AGE_SECS) continue;
1145
+ if (info.tty !== "??" && info.tty !== "-") continue;
1146
+ const wrapperInfo = procMap.get(info.ppid);
1147
+ if (wrapperInfo && wrapperInfo.tty !== "??" && wrapperInfo.tty !== "-") continue;
1144
1148
  let hasLiveSession = false;
1145
1149
  let cur = info.ppid;
1146
1150
  for (let depth = 0; depth < 5; depth++) {
@@ -1222,7 +1226,7 @@ function getRssKb(pid) {
1222
1226
  function createZombieAgentReaperRealDeps() {
1223
1227
  return {
1224
1228
  listProcesses: () => {
1225
- const output = execSync("ps -eo pid,ppid,etime,args", {
1229
+ const output = execSync("ps -eo pid,ppid,etime,tty,args", {
1226
1230
  encoding: "utf8",
1227
1231
  timeout: 5e3
1228
1232
  });
@@ -47,7 +47,7 @@ import {
47
47
  shouldKillIdleSession,
48
48
  shouldKillSession,
49
49
  shouldNudgeEmployee
50
- } from "./chunk-BZYHF63H.js";
50
+ } from "./chunk-RLHQMWLV.js";
51
51
  import "./chunk-FRH7EY2Z.js";
52
52
  import "./chunk-MPCICOVG.js";
53
53
  import "./chunk-7X7HKWH7.js";
@@ -70,6 +70,24 @@ process.stdin.on("end", async () => {
70
70
  }
71
71
  const data = JSON.parse(input);
72
72
  const agent = getActiveAgent();
73
+ try {
74
+ const { appendFileSync } = await import("fs");
75
+ const { join } = await import("path");
76
+ const { homedir } = await import("os");
77
+ const deathLog = join(homedir(), ".exe-os", "session-deaths.log");
78
+ const entry = JSON.stringify({
79
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
80
+ agent: agent.agentId,
81
+ role: agent.agentRole,
82
+ session: data.session_id,
83
+ project: process.env.EXE_PROJECT_NAME ?? process.cwd().split("/").pop() ?? "unknown",
84
+ tty: process.env.TTY ?? process.env.GPG_TTY ?? "unknown",
85
+ pid: process.pid,
86
+ ppid: process.ppid
87
+ });
88
+ appendFileSync(deathLog, entry + "\n");
89
+ } catch {
90
+ }
73
91
  if (agent.agentId !== "default") {
74
92
  try {
75
93
  const { fastDbInit } = await import("../fast-db-init-FLMQJFDI.js");
@@ -1337,8 +1337,9 @@ async function startMcpHttpServer() {
1337
1337
  }, evictDuplicateMcpSessions2 = function(ownerKey, keepSid) {
1338
1338
  for (const [sid, existingOwner] of sessionOwnerKeys.entries()) {
1339
1339
  if (sid !== keepSid && existingOwner === ownerKey) {
1340
+ const age = sessionLastSeen.has(sid) ? Math.round((Date.now() - sessionLastSeen.get(sid)) / 1e3) : -1;
1340
1341
  closeMcpSession2(sid, "duplicate_session_eviction");
1341
- process.stderr.write(`[exed] MCP duplicate session eviction: closed ${sid.slice(0, 8)} for ${ownerKey}
1342
+ process.stderr.write(`[exed] MCP duplicate session eviction: closed ${sid.slice(0, 8)} for ${ownerKey} (age=${age}s, replaced by ${keepSid?.slice(0, 8) ?? "none"})
1342
1343
  `);
1343
1344
  }
1344
1345
  }
@@ -2055,7 +2056,7 @@ function startSessionTTL() {
2055
2056
  if (!await ensureStoreForPolling()) return;
2056
2057
  try {
2057
2058
  const { getClient: getClient2 } = await import("./database.js");
2058
- const { checkSessionTTL, createSessionTTLRealDeps } = await import("../daemon-orchestration-47D3OQQV.js");
2059
+ const { checkSessionTTL, createSessionTTLRealDeps } = await import("../daemon-orchestration-4D2UNHKZ.js");
2059
2060
  const deps = createSessionTTLRealDeps(getClient2);
2060
2061
  const killed = await checkSessionTTL(deps);
2061
2062
  if (killed.length > 0) acted("session_ttl");
@@ -2084,7 +2085,7 @@ function startCooAutoRestart() {
2084
2085
  _cooLastSeen = Date.now();
2085
2086
  try {
2086
2087
  const { getClient: getClient2 } = await import("./database.js");
2087
- const { pollCoordinatorContextRestart, createCoordinatorRestartRealDeps } = await import("../daemon-orchestration-47D3OQQV.js");
2088
+ const { pollCoordinatorContextRestart, createCoordinatorRestartRealDeps } = await import("../daemon-orchestration-4D2UNHKZ.js");
2088
2089
  const deps = createCoordinatorRestartRealDeps(getClient2);
2089
2090
  const restarted = await pollCoordinatorContextRestart(deps, process.cwd());
2090
2091
  if (restarted.length > 0) {
@@ -2202,7 +2203,7 @@ function startIdleKill() {
2202
2203
  const { loadConfigSync } = await import("./config.js");
2203
2204
  const cfg = loadConfigSync();
2204
2205
  const { getClient: getClient2 } = await import("./database.js");
2205
- const { pollIdleKill, createIdleKillRealDeps } = await import("../daemon-orchestration-47D3OQQV.js");
2206
+ const { pollIdleKill, createIdleKillRealDeps } = await import("../daemon-orchestration-4D2UNHKZ.js");
2206
2207
  const deps = createIdleKillRealDeps(
2207
2208
  getClient2,
2208
2209
  cfg.sessionLifecycle.idleKillIntercomAckWindowMs
@@ -2746,7 +2747,7 @@ function startOrphanReaper() {
2746
2747
  const tick = async () => {
2747
2748
  fired("orphan_reaper");
2748
2749
  try {
2749
- const { reapOrphanedMcpProcesses, createOrphanReaperRealDeps } = await import("../daemon-orchestration-47D3OQQV.js");
2750
+ const { reapOrphanedMcpProcesses, createOrphanReaperRealDeps } = await import("../daemon-orchestration-4D2UNHKZ.js");
2750
2751
  const deps = createOrphanReaperRealDeps();
2751
2752
  const reaped = await reapOrphanedMcpProcesses(deps);
2752
2753
  if (reaped.length > 0) acted("orphan_reaper");
@@ -2770,7 +2771,7 @@ function startZombieAgentReaper() {
2770
2771
  const tick = async () => {
2771
2772
  fired("zombie_agent_reaper");
2772
2773
  try {
2773
- const { reapZombieAgentProcesses, createZombieAgentReaperRealDeps } = await import("../daemon-orchestration-47D3OQQV.js");
2774
+ const { reapZombieAgentProcesses, createZombieAgentReaperRealDeps } = await import("../daemon-orchestration-4D2UNHKZ.js");
2774
2775
  const deps = createZombieAgentReaperRealDeps();
2775
2776
  const reaped = reapZombieAgentProcesses(deps);
2776
2777
  if (reaped.length > 0) acted("zombie_agent_reaper");
@@ -2793,7 +2794,7 @@ function startWorktreeReaper() {
2793
2794
  const tick = async () => {
2794
2795
  fired("worktree_reaper");
2795
2796
  try {
2796
- const { reapOrphanedWorktrees, createWorktreeReaperRealDeps } = await import("../daemon-orchestration-47D3OQQV.js");
2797
+ const { reapOrphanedWorktrees, createWorktreeReaperRealDeps } = await import("../daemon-orchestration-4D2UNHKZ.js");
2797
2798
  const deps = await createWorktreeReaperRealDeps();
2798
2799
  const result = await reapOrphanedWorktrees(deps);
2799
2800
  if (result.pruned.length > 0) {
@@ -2824,7 +2825,7 @@ function startAutoWake() {
2824
2825
  if (!await ensureStoreForPolling()) return;
2825
2826
  try {
2826
2827
  const { getClient: getClient2 } = await import("./database.js");
2827
- const { pollOrphanedTasks, createAutoWakeRealDeps } = await import("../daemon-orchestration-47D3OQQV.js");
2828
+ const { pollOrphanedTasks, createAutoWakeRealDeps } = await import("../daemon-orchestration-4D2UNHKZ.js");
2828
2829
  const deps = createAutoWakeRealDeps(getClient2, process.cwd());
2829
2830
  const woken = await pollOrphanedTasks(deps);
2830
2831
  if (woken.length > 0) acted("auto_wake");
@@ -2933,7 +2934,7 @@ function startStuckTaskRelease() {
2933
2934
  if (!await ensureStoreForPolling()) return;
2934
2935
  try {
2935
2936
  const { getClient: getClient2 } = await import("./database.js");
2936
- const { releaseStuckTasks, createStuckTaskRealDeps } = await import("../daemon-orchestration-47D3OQQV.js");
2937
+ const { releaseStuckTasks, createStuckTaskRealDeps } = await import("../daemon-orchestration-4D2UNHKZ.js");
2937
2938
  const deps = createStuckTaskRealDeps(getClient2);
2938
2939
  const released = await releaseStuckTasks(deps);
2939
2940
  if (released.length > 0) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  registerAllTools
3
- } from "../chunk-NP55D5Q6.js";
4
- import "../chunk-BZYHF63H.js";
3
+ } from "../chunk-A4NCK74X.js";
4
+ import "../chunk-RLHQMWLV.js";
5
5
  import "../chunk-ESRI7MFI.js";
6
6
  import "../chunk-PLNYW6PA.js";
7
7
  import "../chunk-MGRHSBXO.js";
@@ -3,8 +3,8 @@ import {
3
3
  } from "../chunk-V4TZI6EO.js";
4
4
  import {
5
5
  registerAllTools
6
- } from "../chunk-NP55D5Q6.js";
7
- import "../chunk-BZYHF63H.js";
6
+ } from "../chunk-A4NCK74X.js";
7
+ import "../chunk-RLHQMWLV.js";
8
8
  import "../chunk-ESRI7MFI.js";
9
9
  import {
10
10
  initLicenseGate
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askexenow/exe-os",
3
- "version": "0.9.161",
3
+ "version": "0.9.163",
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.161",
2
+ "current": "0.9.163",
3
3
  "notes": {
4
- "0.9.161": {
5
- "version": "0.9.161",
4
+ "0.9.163": {
5
+ "version": "0.9.163",
6
6
  "date": "2026-05-30",
7
7
  "features": [
8
8
  "add worktree reaper daemon job to prune orphaned agent worktrees",
@@ -32,6 +32,7 @@
32
32
  "blocked task notification — ping dispatcher immediately on status change"
33
33
  ],
34
34
  "fixes": [
35
+ "zombie reaper must never kill TTY-attached sessions + death log",
35
36
  "update readiness gate to check daemon-restart-orchestrator",
36
37
  "resolve TS errors blocking publish — unused import + undefined row",
37
38
  "zombie agent reaper + deferred daemon restart (OOM crash fix)",
@@ -55,8 +56,7 @@
55
56
  "DMR retrieval 20% → 100% — stop words, name filtering, speaker fix",
56
57
  "kill idle Codex/OpenCode sessions instead of sending intercom — enables auto-wake respawn",
57
58
  "suppress daemon auto-reconnect noise — only log after attempt 2+",
58
- "remove E2EE from bug reports — support intake must be readable server-side",
59
- "support API — verified encrypted bug reports work (HTTP 201)"
59
+ "remove E2EE from bug reports — support intake must be readable server-side"
60
60
  ],
61
61
  "security": [
62
62
  "fix shell injection, SSRF, socket leaks, backup validation",
@@ -104,10 +104,12 @@
104
104
  "exe-daemon.ts kills old embed.pid process and cleans up"
105
105
  ]
106
106
  },
107
- "0.9.160": {
108
- "version": "0.9.160",
107
+ "0.9.162": {
108
+ "version": "0.9.162",
109
109
  "date": "2026-05-30",
110
110
  "features": [
111
+ "add worktree reaper daemon job to prune orphaned agent worktrees",
112
+ "add pre-flight gates to close_task — status gate, worktree check, commit recency",
111
113
  "add wiki document ingestion via API for embedding pipeline",
112
114
  "add filtered.* projection targets to projection worker",
113
115
  "verify-stack post-deploy checks — 8 runtime validations",
@@ -130,11 +132,15 @@
130
132
  "update safety + portable backups + restore",
131
133
  "complete deployment readiness — all 14 second-pass blind spots fixed",
132
134
  "production-ready stack — all 15 blind spots fixed",
133
- "blocked task notification — ping dispatcher immediately on status change",
134
- "self-improving skills — usage tracking, success counting, and refinement daemon",
135
- "4 retrieval improvements — query expansion, stop words, contradiction resolution, abstention"
135
+ "blocked task notification — ping dispatcher immediately on status change"
136
136
  ],
137
137
  "fixes": [
138
+ "zombie reaper must never kill TTY-attached sessions + death log",
139
+ "update readiness gate to check daemon-restart-orchestrator",
140
+ "resolve TS errors blocking publish — unused import + undefined row",
141
+ "zombie agent reaper + deferred daemon restart (OOM crash fix)",
142
+ "idle-kill now reaps Codex/OpenCode sessions (bug 47d1e446)",
143
+ "change orphaned task terminal state from blocked → needs_review",
138
144
  "auto-close temporal guard + session_scope fallback + orphan cleanup safety",
139
145
  "cloud sync skip-bad-rows + age-based orphan hook reaper",
140
146
  "clean unused imports + publish gate fixes for v0.9.159",
@@ -153,13 +159,7 @@
153
159
  "DMR retrieval 20% → 100% — stop words, name filtering, speaker fix",
154
160
  "kill idle Codex/OpenCode sessions instead of sending intercom — enables auto-wake respawn",
155
161
  "suppress daemon auto-reconnect noise — only log after attempt 2+",
156
- "remove E2EE from bug reports — support intake must be readable server-side",
157
- "support API — verified encrypted bug reports work (HTTP 201)",
158
- "support API accepts encrypted bug reports — prevents HTTP 400",
159
- "Codex agents recheck tasks before stopping — prevents idle-with-open-tasks",
160
- "P0 #13 session_scope in cleanup SELECT + P0 #6 wire review signal files",
161
- "add scope import to prompt-submit — gate pass",
162
- "add writeFileSync import to config.ts"
162
+ "remove E2EE from bug reports — support intake must be readable server-side"
163
163
  ],
164
164
  "security": [
165
165
  "fix shell injection, SSRF, socket leaks, backup validation",
@@ -207,10 +207,14 @@
207
207
  "exe-daemon.ts kills old embed.pid process and cleans up"
208
208
  ]
209
209
  },
210
- "0.9.159": {
211
- "version": "0.9.159",
212
- "date": "2026-05-29",
210
+ "0.9.161": {
211
+ "version": "0.9.161",
212
+ "date": "2026-05-30",
213
213
  "features": [
214
+ "add worktree reaper daemon job to prune orphaned agent worktrees",
215
+ "add pre-flight gates to close_task — status gate, worktree check, commit recency",
216
+ "add wiki document ingestion via API for embedding pipeline",
217
+ "add filtered.* projection targets to projection worker",
214
218
  "verify-stack post-deploy checks — 8 runtime validations",
215
219
  "preflight deploy gate + filtered schema + gateway graceful degradation",
216
220
  "harden /exe-afk as primary monitoring tool, deprecate /loop for orchestration",
@@ -231,18 +235,17 @@
231
235
  "update safety + portable backups + restore",
232
236
  "complete deployment readiness — all 14 second-pass blind spots fixed",
233
237
  "production-ready stack — all 15 blind spots fixed",
234
- "blocked task notification — ping dispatcher immediately on status change",
235
- "self-improving skills — usage tracking, success counting, and refinement daemon",
236
- "4 retrieval improvements — query expansion, stop words, contradiction resolution, abstention",
237
- "competitive roadmap — serverless tier, identity depth, self-improving skills, user modeling",
238
- "run database migrations before container swap in stack-update"
238
+ "blocked task notification — ping dispatcher immediately on status change"
239
239
  ],
240
240
  "fixes": [
241
- "cloud sync NOT NULL resilience — sqlSafeRequired() defaults + per-record error handling, skip bad rows instead of retry storm",
242
- "auto-close temporal guard reject commits older than task creation date, raise threshold 0.6→0.8",
243
- "session_scope fallback listTasks returns unscoped results when scoped query finds 0 after daemon restart",
244
- "orphan task file cleanup safety — 24h threshold (was 1h) + ID-based fallback before deleting",
245
- "blocked task escalation writeNotification to COO when auto-wake fails 3x and marks task blocked",
241
+ "update readiness gate to check daemon-restart-orchestrator",
242
+ "resolve TS errors blocking publish unused import + undefined row",
243
+ "zombie agent reaper + deferred daemon restart (OOM crash fix)",
244
+ "idle-kill now reaps Codex/OpenCode sessions (bug 47d1e446)",
245
+ "change orphaned task terminal state from blocked needs_review",
246
+ "auto-close temporal guard + session_scope fallback + orphan cleanup safety",
247
+ "cloud sync skip-bad-rows + age-based orphan hook reaper",
248
+ "clean unused imports + publish gate fixes for v0.9.159",
246
249
  "daemon memory cascade — prevent duplicate daemons, reap orphan hooks, cap heap",
247
250
  "auto-inject timeout on tmux capture-pane to prevent session freeze",
248
251
  "auto-wake crash loop — filter boot memories + circuit breaker",
@@ -259,10 +262,7 @@
259
262
  "kill idle Codex/OpenCode sessions instead of sending intercom — enables auto-wake respawn",
260
263
  "suppress daemon auto-reconnect noise — only log after attempt 2+",
261
264
  "remove E2EE from bug reports — support intake must be readable server-side",
262
- "support API — verified encrypted bug reports work (HTTP 201)",
263
- "support API accepts encrypted bug reports — prevents HTTP 400",
264
- "Codex agents recheck tasks before stopping — prevents idle-with-open-tasks",
265
- "P0 #13 session_scope in cleanup SELECT + P0 #6 wire review signal files"
265
+ "support API — verified encrypted bug reports work (HTTP 201)"
266
266
  ],
267
267
  "security": [
268
268
  "fix shell injection, SSRF, socket leaks, backup validation",
@@ -279,6 +279,8 @@
279
279
  "fix 4 pricing tier bypass vulnerabilities (audit F1-F4)"
280
280
  ],
281
281
  "other": [
282
+ "bump v0.9.160 — cloud sync resilience + orphan reaper + auto-close guard",
283
+ "update release notes with 5 bug fixes from support triage",
282
284
  "bump v0.9.159 — daemon memory cascade fix + session_scope + benchmarks",
283
285
  "arch: customer onboarding automation — exe-os deploy-customer command",
284
286
  "arch: Fleet Operations Roadmap — 8 phases for production safety at scale",
@@ -301,71 +303,69 @@
301
303
  "publish v0.9.144 — ESM require() fix + reliable task signals + OAuth 2.1",
302
304
  "add MCP tool tests for message, cloud-sync, and file-copy",
303
305
  "add coverage for send_message, cloud_sync, file_copy MCP tools (Track A)",
304
- "Recover MCP sessions after daemon restart",
305
- "publish v0.9.143 — all fixes live",
306
- "publish v0.9.142"
306
+ "Recover MCP sessions after daemon restart"
307
307
  ],
308
308
  "migration_notes": [
309
309
  "If daemon goes down, agents will now fail instead of silently",
310
310
  "exe-daemon.ts kills old embed.pid process and cleans up"
311
311
  ]
312
312
  },
313
- "0.9.158": {
314
- "version": "0.9.158",
315
- "date": "2026-05-28",
313
+ "0.9.160": {
314
+ "version": "0.9.160",
315
+ "date": "2026-05-30",
316
316
  "features": [
317
+ "add wiki document ingestion via API for embedding pipeline",
318
+ "add filtered.* projection targets to projection worker",
319
+ "verify-stack post-deploy checks — 8 runtime validations",
320
+ "preflight deploy gate + filtered schema + gateway graceful degradation",
321
+ "harden /exe-afk as primary monitoring tool, deprecate /loop for orchestration",
322
+ "add --judge-model flag to LoCoMo harness",
323
+ "dashboard.askexe.com — customer credits dashboard (backend + frontend)",
324
+ "config persistence contract — document + enforce what survives stack updates",
325
+ "add persona depth to identity — tone, vocabulary, response_style, communication_patterns",
326
+ "4 BEAM improvements — o4-mini judge, entity expansion, temporal prompts, contradiction detection",
327
+ "DMR 100% + BEAM 35% — full results with Claude Sonnet judge",
328
+ "session_scope read paths — search filter + backfill + tests",
329
+ "add session_scope filtering to memory read paths + MCP tools + backfill",
330
+ "classify prompt memories as conversation type + enrich session-end captures",
331
+ "add session_scope column to memories table — schema migration + all write paths",
332
+ "fix Codex integration + add --codex to all 4 harnesses",
333
+ "add checkpoint/resume support for long LoCoMo runs",
334
+ "add Codex GPT-5.5 judge, pre-embedding, expanded retrieval, production prompts",
317
335
  "stack manifest 0.9.10 — all new images for customer deployment",
318
336
  "update safety + portable backups + restore",
319
337
  "complete deployment readiness — all 14 second-pass blind spots fixed",
320
338
  "production-ready stack — all 15 blind spots fixed",
321
339
  "blocked task notification — ping dispatcher immediately on status change",
322
340
  "self-improving skills — usage tracking, success counting, and refinement daemon",
323
- "4 retrieval improvements — query expansion, stop words, contradiction resolution, abstention",
324
- "competitive roadmap — serverless tier, identity depth, self-improving skills, user modeling",
325
- "run database migrations before container swap in stack-update",
326
- "graph auto-extract from ARCHITECTURE.md — regex-based entity/relationship extraction",
327
- "migrate cloud.askexe.com → api.askexe.com as canonical endpoint",
328
- "federated recall — code_context + graph fallback when memory results weak",
329
- "migrate cloud.askexe.com → api.askexe.com across all src/ defaults",
330
- "rolling restart in stack-update — one service at a time with health verification",
331
- "DMR benchmark harness + LoCoMo improvements for v0.9.145 evaluation",
332
- "Windows/WSL support — WezTerm config + WSL detection in setup wizard",
333
- "queryTaskRows() consolidation — single scoped query path for all task list operations",
334
- "review signal files — reliable reviewer notification on update_task(done)",
335
- "Ghostty-native notifications via OSC 9 — no more Script Editor popup",
336
- "device-scoped behaviors — device_id column + filter in loading",
337
- "dispatch reliability — 45s boot timeout, dispatch ack signals, agent heartbeat",
338
- "setup wizard headless mode + daemon health check after restart",
339
- "device-scoped behaviors — add device_id column + filter on load",
340
- "gateway prompt injection defense — 3-tier security hardening",
341
- "add diagnostics(action=\"merge_agent_memories\") for reassigning memories across agent IDs"
341
+ "4 retrieval improvements — query expansion, stop words, contradiction resolution, abstention"
342
342
  ],
343
343
  "fixes": [
344
+ "auto-close temporal guard + session_scope fallback + orphan cleanup safety",
345
+ "cloud sync skip-bad-rows + age-based orphan hook reaper",
346
+ "clean unused imports + publish gate fixes for v0.9.159",
347
+ "daemon memory cascade — prevent duplicate daemons, reap orphan hooks, cap heap",
348
+ "auto-inject timeout on tmux capture-pane to prevent session freeze",
349
+ "auto-wake crash loop — filter boot memories + circuit breaker",
350
+ "Codex numbered instances use baseAgentName for identity resolution",
351
+ "auto-chain project scope + writeNotification on needs_review",
352
+ "persist WhatsApp auth in Docker volume — prevent data loss on update",
353
+ "wake idle codex sessions on pending tasks",
354
+ "fix daemon MCP session heap leak",
355
+ "include typescript as runtime dependency",
356
+ "remove direct Postgres license validation — CF Worker is the only path",
357
+ "gateway stop_grace_period 45s — prevent SIGKILL during message drain",
358
+ "filter person names from FTS queries to prevent speaker-prefix pollution",
359
+ "DMR retrieval 20% → 100% — stop words, name filtering, speaker fix",
360
+ "kill idle Codex/OpenCode sessions instead of sending intercom — enables auto-wake respawn",
361
+ "suppress daemon auto-reconnect noise — only log after attempt 2+",
362
+ "remove E2EE from bug reports — support intake must be readable server-side",
344
363
  "support API — verified encrypted bug reports work (HTTP 201)",
345
364
  "support API accepts encrypted bug reports — prevents HTTP 400",
346
365
  "Codex agents recheck tasks before stopping — prevents idle-with-open-tasks",
347
366
  "P0 #13 session_scope in cleanup SELECT + P0 #6 wire review signal files",
348
367
  "add scope import to prompt-submit — gate pass",
349
- "add writeFileSync import to config.ts",
350
- "persist cloud endpoint migration to config.json — stop logging on every boot",
351
- "include memory_type in pushToPostgres metadata — was stripped on sync",
352
- "add scope import to daemon-orchestration — satisfies customer-readiness gate",
353
- "skill-refinement.ts — correct writeMemory field names + updateIdentity 3rd arg",
354
- "make skill lifecycle fields optional on Behavior interface — unblocks publish",
355
- "session isolation for tmux kill — block cross-scope session kills",
356
- "session-scope daemon, push, capacity, and cleanup (P0 #7-#13)",
357
- "add memory_type to crdt-sync MemoryRecord interface — unblocks publish",
358
- "session-scope daemon, push, capacity, cleanup (P0 #7-#9, #13)",
359
- "include memory_type in cloud sync push/pull + fix backfill re-sync",
360
- "session-scope signal file system — prevent cross-session task/review bleed",
361
- "session-scope notification routing — use row.session_scope over ambient",
362
- "daemon NEVER guesses session from tmux — header-only routing",
363
- "3 daemon bugs — context-full TTL override, API watchdog kill-after-3, idle-kill verify",
364
- "federated recall always searches code_context + graph — count threshold was useless",
365
- "make cross-repo guardrail task-aware — allow multi-repo work when task scope permits",
366
- "ONE postgres — replace crm-postgres with exe-db across entire stack",
367
- "smart session-scoping gate + last boot cleanup leak + triage_bug docs",
368
- "add shipped_version to support triage + clean platform procedures"
368
+ "add writeFileSync import to config.ts"
369
369
  ],
370
370
  "security": [
371
371
  "fix shell injection, SSRF, socket leaks, backup validation",
@@ -382,6 +382,15 @@
382
382
  "fix 4 pricing tier bypass vulnerabilities (audit F1-F4)"
383
383
  ],
384
384
  "other": [
385
+ "bump v0.9.160 — cloud sync resilience + orphan reaper + auto-close guard",
386
+ "update release notes with 5 bug fixes from support triage",
387
+ "bump v0.9.159 — daemon memory cascade fix + session_scope + benchmarks",
388
+ "arch: customer onboarding automation — exe-os deploy-customer command",
389
+ "arch: Fleet Operations Roadmap — 8 phases for production safety at scale",
390
+ "arch: add filtered table pipeline + pre-flight deploy system to roadmap",
391
+ "add EXE-OS-STACK.md — complete 6-repo deployment map",
392
+ "cache tmux session (5 calls → 1) + offset daemon timers",
393
+ "cut agent boot from 4min to <30s — merge Bash blocks + parallel DB queries",
385
394
  "rename memory schema → graph across codebase",
386
395
  "unified access control — admin token + GoTrue across all services",
387
396
  "capture data pipeline spec — raw → filter → wiki + CRM projection",
@@ -397,26 +406,34 @@
397
406
  "publish v0.9.144 — ESM require() fix + reliable task signals + OAuth 2.1",
398
407
  "add MCP tool tests for message, cloud-sync, and file-copy",
399
408
  "add coverage for send_message, cloud_sync, file_copy MCP tools (Track A)",
400
- "Recover MCP sessions after daemon restart",
401
- "publish v0.9.143 — all fixes live",
402
- "publish v0.9.142",
403
- "publish v0.9.141",
404
- "ops: journalctl rotation + certbot expiry alerting",
405
- "revert: daemon heap back to 33% of RAM — no artificial cap",
406
- "v0.9.140 publish + heap cap 4GB (was 33% unbounded)",
407
- "PG-1 cross-repo entity federation design document",
408
- "add lint step + automated npm publish workflow",
409
- "audit: scoped SQL + package budget + TUI vendored + TODO classification"
409
+ "Recover MCP sessions after daemon restart"
410
410
  ],
411
411
  "migration_notes": [
412
412
  "If daemon goes down, agents will now fail instead of silently",
413
413
  "exe-daemon.ts kills old embed.pid process and cleans up"
414
414
  ]
415
415
  },
416
- "0.9.157": {
417
- "version": "0.9.157",
418
- "date": "2026-05-28",
416
+ "0.9.159": {
417
+ "version": "0.9.159",
418
+ "date": "2026-05-29",
419
419
  "features": [
420
+ "verify-stack post-deploy checks — 8 runtime validations",
421
+ "preflight deploy gate + filtered schema + gateway graceful degradation",
422
+ "harden /exe-afk as primary monitoring tool, deprecate /loop for orchestration",
423
+ "add --judge-model flag to LoCoMo harness",
424
+ "dashboard.askexe.com — customer credits dashboard (backend + frontend)",
425
+ "config persistence contract — document + enforce what survives stack updates",
426
+ "add persona depth to identity — tone, vocabulary, response_style, communication_patterns",
427
+ "4 BEAM improvements — o4-mini judge, entity expansion, temporal prompts, contradiction detection",
428
+ "DMR 100% + BEAM 35% — full results with Claude Sonnet judge",
429
+ "session_scope read paths — search filter + backfill + tests",
430
+ "add session_scope filtering to memory read paths + MCP tools + backfill",
431
+ "classify prompt memories as conversation type + enrich session-end captures",
432
+ "add session_scope column to memories table — schema migration + all write paths",
433
+ "fix Codex integration + add --codex to all 4 harnesses",
434
+ "add checkpoint/resume support for long LoCoMo runs",
435
+ "add Codex GPT-5.5 judge, pre-embedding, expanded retrieval, production prompts",
436
+ "stack manifest 0.9.10 — all new images for customer deployment",
420
437
  "update safety + portable backups + restore",
421
438
  "complete deployment readiness — all 14 second-pass blind spots fixed",
422
439
  "production-ready stack — all 15 blind spots fixed",
@@ -424,51 +441,34 @@
424
441
  "self-improving skills — usage tracking, success counting, and refinement daemon",
425
442
  "4 retrieval improvements — query expansion, stop words, contradiction resolution, abstention",
426
443
  "competitive roadmap — serverless tier, identity depth, self-improving skills, user modeling",
427
- "run database migrations before container swap in stack-update",
428
- "graph auto-extract from ARCHITECTURE.md — regex-based entity/relationship extraction",
429
- "migrate cloud.askexe.com → api.askexe.com as canonical endpoint",
430
- "federated recall — code_context + graph fallback when memory results weak",
431
- "migrate cloud.askexe.com → api.askexe.com across all src/ defaults",
432
- "rolling restart in stack-update — one service at a time with health verification",
433
- "DMR benchmark harness + LoCoMo improvements for v0.9.145 evaluation",
434
- "Windows/WSL support — WezTerm config + WSL detection in setup wizard",
435
- "queryTaskRows() consolidation — single scoped query path for all task list operations",
436
- "review signal files — reliable reviewer notification on update_task(done)",
437
- "Ghostty-native notifications via OSC 9 — no more Script Editor popup",
438
- "device-scoped behaviors — device_id column + filter in loading",
439
- "dispatch reliability — 45s boot timeout, dispatch ack signals, agent heartbeat",
440
- "setup wizard headless mode + daemon health check after restart",
441
- "device-scoped behaviors — add device_id column + filter on load",
442
- "gateway prompt injection defense — 3-tier security hardening",
443
- "add diagnostics(action=\"merge_agent_memories\") for reassigning memories across agent IDs",
444
- "add task dependency tree visualization (action=dependency_tree)"
444
+ "run database migrations before container swap in stack-update"
445
445
  ],
446
446
  "fixes": [
447
- "add scope import to prompt-submitgate pass",
448
- "add writeFileSync import to config.ts",
449
- "persist cloud endpoint migration to config.json stop logging on every boot",
450
- "include memory_type in pushToPostgres metadata — was stripped on sync",
451
- "add scope import to daemon-orchestration satisfies customer-readiness gate",
452
- "skill-refinement.tscorrect writeMemory field names + updateIdentity 3rd arg",
453
- "make skill lifecycle fields optional on Behavior interface — unblocks publish",
454
- "session isolation for tmux kill block cross-scope session kills",
455
- "session-scope daemon, push, capacity, and cleanup (P0 #7-#13)",
456
- "add memory_type to crdt-sync MemoryRecord interface — unblocks publish",
457
- "session-scope daemon, push, capacity, cleanup (P0 #7-#9, #13)",
458
- "include memory_type in cloud sync push/pull + fix backfill re-sync",
459
- "session-scope signal file system — prevent cross-session task/review bleed",
460
- "session-scope notification routing use row.session_scope over ambient",
461
- "daemon NEVER guesses session from tmux header-only routing",
462
- "3 daemon bugscontext-full TTL override, API watchdog kill-after-3, idle-kill verify",
463
- "federated recall always searches code_context + graph count threshold was useless",
464
- "make cross-repo guardrail task-awareallow multi-repo work when task scope permits",
465
- "ONE postgres replace crm-postgres with exe-db across entire stack",
466
- "smart session-scoping gate + last boot cleanup leak + triage_bug docs",
467
- "add shipped_version to support triage + clean platform procedures",
468
- "close remaining session-scoping findings from Bob's audit",
469
- "close 3 more session-scoping leaks from Bob's audit (LEAK-4, LEAK-7, LEAK-8)",
470
- "diagnostics check_update ENOENT + healthcheck timeout",
471
- "close 8 session-scoping leaks daemon ALS trust + review cleanup + close-task + inbox"
447
+ "cloud sync NOT NULL resiliencesqlSafeRequired() 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 safety24h threshold (was 1h) + ID-based fallback before deleting",
451
+ "blocked task escalation — writeNotification to COO when auto-wake fails 3x and marks task blocked",
452
+ "daemon memory cascade prevent duplicate daemons, reap orphan hooks, cap heap",
453
+ "auto-inject timeout on tmux capture-pane to prevent session freeze",
454
+ "auto-wake crash loop filter boot memories + circuit breaker",
455
+ "Codex numbered instances use baseAgentName for identity resolution",
456
+ "auto-chain project scope + writeNotification on needs_review",
457
+ "persist WhatsApp auth in Docker volume prevent data loss on update",
458
+ "wake idle codex sessions on pending tasks",
459
+ "fix daemon MCP session heap leak",
460
+ "include typescript as runtime dependency",
461
+ "remove direct Postgres license validationCF Worker is the only path",
462
+ "gateway stop_grace_period 45sprevent SIGKILL during message drain",
463
+ "filter person names from FTS queries to prevent speaker-prefix pollution",
464
+ "DMR retrieval 20% 100% stop words, name filtering, speaker fix",
465
+ "kill idle Codex/OpenCode sessions instead of sending intercom enables auto-wake respawn",
466
+ "suppress daemon auto-reconnect noise only log after attempt 2+",
467
+ "remove E2EE from bug reports — support intake must be readable server-side",
468
+ "support API verified encrypted bug reports work (HTTP 201)",
469
+ "support API accepts encrypted bug reports prevents HTTP 400",
470
+ "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"
472
472
  ],
473
473
  "security": [
474
474
  "fix shell injection, SSRF, socket leaks, backup validation",
@@ -485,6 +485,13 @@
485
485
  "fix 4 pricing tier bypass vulnerabilities (audit F1-F4)"
486
486
  ],
487
487
  "other": [
488
+ "bump v0.9.159 — daemon memory cascade fix + session_scope + benchmarks",
489
+ "arch: customer onboarding automation — exe-os deploy-customer command",
490
+ "arch: Fleet Operations Roadmap — 8 phases for production safety at scale",
491
+ "arch: add filtered table pipeline + pre-flight deploy system to roadmap",
492
+ "add EXE-OS-STACK.md — complete 6-repo deployment map",
493
+ "cache tmux session (5 calls → 1) + offset daemon timers",
494
+ "cut agent boot from 4min to <30s — merge Bash blocks + parallel DB queries",
488
495
  "rename memory schema → graph across codebase",
489
496
  "unified access control — admin token + GoTrue across all services",
490
497
  "capture data pipeline spec — raw → filter → wiki + CRM projection",
@@ -502,14 +509,7 @@
502
509
  "add coverage for send_message, cloud_sync, file_copy MCP tools (Track A)",
503
510
  "Recover MCP sessions after daemon restart",
504
511
  "publish v0.9.143 — all fixes live",
505
- "publish v0.9.142",
506
- "publish v0.9.141",
507
- "ops: journalctl rotation + certbot expiry alerting",
508
- "revert: daemon heap back to 33% of RAM — no artificial cap",
509
- "v0.9.140 publish + heap cap 4GB (was 33% unbounded)",
510
- "PG-1 cross-repo entity federation design document",
511
- "add lint step + automated npm publish workflow",
512
- "audit: scoped SQL + package budget + TUI vendored + TODO classification"
512
+ "publish v0.9.142"
513
513
  ],
514
514
  "migration_notes": [
515
515
  "If daemon goes down, agents will now fail instead of silently",