@askexenow/exe-os 0.8.40 → 0.8.42
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/dist/bin/backfill-conversations.js +805 -642
- package/dist/bin/backfill-responses.js +804 -641
- package/dist/bin/backfill-vectors.js +791 -634
- package/dist/bin/cleanup-stale-review-tasks.js +788 -631
- package/dist/bin/cli.js +1376 -659
- package/dist/bin/exe-agent.js +20 -1
- package/dist/bin/exe-assign.js +1503 -1343
- package/dist/bin/exe-boot.js +2549 -1784
- package/dist/bin/exe-call.js +39 -1
- package/dist/bin/exe-cloud.js +12 -2
- package/dist/bin/exe-dispatch.js +39 -2
- package/dist/bin/exe-doctor.js +791 -634
- package/dist/bin/exe-export-behaviors.js +792 -637
- package/dist/bin/exe-forget.js +145 -0
- package/dist/bin/exe-gateway.js +2501 -1846
- package/dist/bin/exe-heartbeat.js +147 -1
- package/dist/bin/exe-kill.js +795 -640
- package/dist/bin/exe-launch-agent.js +2168 -2008
- package/dist/bin/exe-link.js +44 -12
- package/dist/bin/exe-new-employee.js +6 -2
- package/dist/bin/exe-pending-messages.js +146 -1
- package/dist/bin/exe-pending-notifications.js +788 -631
- package/dist/bin/exe-pending-reviews.js +176 -1
- package/dist/bin/exe-rename.js +23 -0
- package/dist/bin/exe-review.js +490 -327
- package/dist/bin/exe-search.js +157 -4
- package/dist/bin/exe-session-cleanup.js +2487 -403
- package/dist/bin/exe-settings.js +2 -1
- package/dist/bin/exe-status.js +474 -317
- package/dist/bin/exe-team.js +474 -317
- package/dist/bin/git-sweep.js +2691 -151
- package/dist/bin/graph-backfill.js +794 -637
- package/dist/bin/graph-export.js +798 -641
- package/dist/bin/scan-tasks.js +2951 -44
- package/dist/bin/setup.js +50 -26
- package/dist/bin/shard-migrate.js +792 -637
- package/dist/bin/wiki-sync.js +794 -637
- package/dist/gateway/index.js +2542 -1887
- package/dist/hooks/bug-report-worker.js +2118 -576
- package/dist/hooks/commit-complete.js +2690 -150
- package/dist/hooks/error-recall.js +157 -4
- package/dist/hooks/ingest-worker.js +1455 -803
- package/dist/hooks/instructions-loaded.js +151 -0
- package/dist/hooks/notification.js +153 -2
- package/dist/hooks/post-compact.js +164 -0
- package/dist/hooks/pre-compact.js +3073 -101
- package/dist/hooks/pre-tool-use.js +151 -0
- package/dist/hooks/prompt-ingest-worker.js +1670 -1509
- package/dist/hooks/prompt-submit.js +2650 -1074
- package/dist/hooks/response-ingest-worker.js +154 -6
- package/dist/hooks/session-end.js +153 -2
- package/dist/hooks/session-start.js +157 -4
- package/dist/hooks/stop.js +151 -0
- package/dist/hooks/subagent-stop.js +155 -2
- package/dist/hooks/summary-worker.js +190 -21
- package/dist/index.js +326 -102
- package/dist/lib/cloud-sync.js +31 -10
- package/dist/lib/config.js +2 -0
- package/dist/lib/consolidation.js +69 -2
- package/dist/lib/database.js +19 -0
- package/dist/lib/device-registry.js +19 -0
- package/dist/lib/embedder.js +3 -1
- package/dist/lib/employee-templates.js +20 -1
- package/dist/lib/exe-daemon.js +285 -18
- package/dist/lib/hybrid-search.js +157 -4
- package/dist/lib/messaging.js +39 -2
- package/dist/lib/schedules.js +792 -637
- package/dist/lib/store.js +796 -636
- package/dist/lib/tasks.js +1485 -918
- package/dist/lib/tmux-routing.js +194 -10
- package/dist/mcp/server.js +1643 -924
- package/dist/mcp/tools/create-task.js +2283 -829
- package/dist/mcp/tools/list-tasks.js +2788 -159
- package/dist/mcp/tools/send-message.js +39 -2
- package/dist/mcp/tools/update-task.js +79 -0
- package/dist/runtime/index.js +280 -68
- package/dist/tui/App.js +1485 -645
- package/package.json +3 -2
package/dist/lib/cloud-sync.js
CHANGED
|
@@ -6,7 +6,8 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
// src/lib/cloud-sync.ts
|
|
9
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, existsSync as existsSync5, readdirSync, mkdirSync as mkdirSync2, appendFileSync, unlinkSync } from "fs";
|
|
9
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, existsSync as existsSync5, readdirSync, mkdirSync as mkdirSync2, appendFileSync, unlinkSync, openSync, closeSync } from "fs";
|
|
10
|
+
import crypto2 from "crypto";
|
|
10
11
|
import path5 from "path";
|
|
11
12
|
import { homedir } from "os";
|
|
12
13
|
|
|
@@ -436,17 +437,29 @@ var PUSH_BATCH_SIZE = 5e3;
|
|
|
436
437
|
var ROSTER_LOCK_PATH = path5.join(EXE_AI_DIR, "roster-merge.lock");
|
|
437
438
|
var LOCK_STALE_MS = 3e4;
|
|
438
439
|
async function withRosterLock(fn) {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
440
|
+
try {
|
|
441
|
+
const fd = openSync(ROSTER_LOCK_PATH, "wx");
|
|
442
|
+
closeSync(fd);
|
|
443
|
+
writeFileSync2(ROSTER_LOCK_PATH, String(Date.now()));
|
|
444
|
+
} catch (err) {
|
|
445
|
+
if (err.code === "EEXIST") {
|
|
446
|
+
try {
|
|
447
|
+
const ts = parseInt(readFileSync5(ROSTER_LOCK_PATH, "utf-8"), 10);
|
|
448
|
+
if (Date.now() - ts < LOCK_STALE_MS) {
|
|
449
|
+
throw new Error("Roster merge already in progress \u2014 another sync is running");
|
|
450
|
+
}
|
|
451
|
+
unlinkSync(ROSTER_LOCK_PATH);
|
|
452
|
+
const fd = openSync(ROSTER_LOCK_PATH, "wx");
|
|
453
|
+
closeSync(fd);
|
|
454
|
+
writeFileSync2(ROSTER_LOCK_PATH, String(Date.now()));
|
|
455
|
+
} catch (retryErr) {
|
|
456
|
+
if (retryErr instanceof Error && retryErr.message.includes("already in progress")) throw retryErr;
|
|
443
457
|
throw new Error("Roster merge already in progress \u2014 another sync is running");
|
|
444
458
|
}
|
|
445
|
-
}
|
|
446
|
-
|
|
459
|
+
} else {
|
|
460
|
+
throw err;
|
|
447
461
|
}
|
|
448
462
|
}
|
|
449
|
-
writeFileSync2(ROSTER_LOCK_PATH, String(Date.now()));
|
|
450
463
|
try {
|
|
451
464
|
return await fn();
|
|
452
465
|
} finally {
|
|
@@ -464,7 +477,7 @@ async function fetchWithRetry(url, init) {
|
|
|
464
477
|
try {
|
|
465
478
|
const signal = AbortSignal.timeout(FETCH_TIMEOUT_MS);
|
|
466
479
|
const resp = await fetch(url, { ...init, signal });
|
|
467
|
-
if (resp.status >= 500 && attempt < MAX_RETRIES) {
|
|
480
|
+
if (resp && resp.status >= 500 && attempt < MAX_RETRIES) {
|
|
468
481
|
await new Promise((r) => setTimeout(r, BASE_DELAY_MS * Math.pow(2, attempt)));
|
|
469
482
|
continue;
|
|
470
483
|
}
|
|
@@ -508,6 +521,10 @@ async function cloudPush(records, maxVersion, config) {
|
|
|
508
521
|
},
|
|
509
522
|
body: JSON.stringify({ version: maxVersion, blob })
|
|
510
523
|
});
|
|
524
|
+
if (resp == null) {
|
|
525
|
+
logError("[cloud-sync] PUSH FAILED: no response from server");
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
511
528
|
if (resp.status === 409) {
|
|
512
529
|
logError("[cloud-sync] PUSH VERSION CONFLICT \u2014 re-pull required before next push");
|
|
513
530
|
return false;
|
|
@@ -530,6 +547,10 @@ async function cloudPull(sinceVersion, config) {
|
|
|
530
547
|
},
|
|
531
548
|
body: JSON.stringify({ since_version: sinceVersion })
|
|
532
549
|
});
|
|
550
|
+
if (response == null) {
|
|
551
|
+
logError("[cloud-sync] PULL FAILED: no response from server");
|
|
552
|
+
return { records: [], maxVersion: sinceVersion };
|
|
553
|
+
}
|
|
533
554
|
if (!response.ok) return { records: [], maxVersion: sinceVersion };
|
|
534
555
|
const data = await response.json();
|
|
535
556
|
const allRecords = [];
|
|
@@ -769,7 +790,7 @@ function buildRosterBlob(paths) {
|
|
|
769
790
|
}
|
|
770
791
|
const deletedNames = consumeRosterDeletions();
|
|
771
792
|
const content = JSON.stringify({ roster, identities, config, deletedNames });
|
|
772
|
-
const hash =
|
|
793
|
+
const hash = crypto2.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
773
794
|
return { roster, identities, config, deletedNames, version: hash };
|
|
774
795
|
}
|
|
775
796
|
async function cloudPushRoster(config) {
|
package/dist/lib/config.js
CHANGED
|
@@ -23,6 +23,7 @@ var EXE_AI_DIR = resolveDataDir();
|
|
|
23
23
|
var DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
24
24
|
var MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
25
25
|
var CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
|
|
26
|
+
var COO_AGENT_NAME = "exe";
|
|
26
27
|
var LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
|
|
27
28
|
var CURRENT_CONFIG_VERSION = 1;
|
|
28
29
|
var DEFAULT_CONFIG = {
|
|
@@ -225,6 +226,7 @@ async function loadConfigFrom(configPath) {
|
|
|
225
226
|
export {
|
|
226
227
|
CONFIG_MIGRATIONS,
|
|
227
228
|
CONFIG_PATH,
|
|
229
|
+
COO_AGENT_NAME,
|
|
228
230
|
CURRENT_CONFIG_VERSION,
|
|
229
231
|
DB_PATH,
|
|
230
232
|
EXE_AI_DIR,
|
|
@@ -3,6 +3,22 @@ var __esm = (fn, res) => function __init() {
|
|
|
3
3
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
4
4
|
};
|
|
5
5
|
|
|
6
|
+
// src/lib/db-retry.ts
|
|
7
|
+
var init_db_retry = __esm({
|
|
8
|
+
"src/lib/db-retry.ts"() {
|
|
9
|
+
"use strict";
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// src/lib/database.ts
|
|
14
|
+
import { createClient } from "@libsql/client";
|
|
15
|
+
var init_database = __esm({
|
|
16
|
+
"src/lib/database.ts"() {
|
|
17
|
+
"use strict";
|
|
18
|
+
init_db_retry();
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
6
22
|
// src/lib/config.ts
|
|
7
23
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
|
|
8
24
|
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
@@ -103,8 +119,8 @@ var init_config = __esm({
|
|
|
103
119
|
// src/lib/consolidation.ts
|
|
104
120
|
import { randomUUID } from "crypto";
|
|
105
121
|
|
|
106
|
-
// src/lib/
|
|
107
|
-
|
|
122
|
+
// src/lib/store.ts
|
|
123
|
+
init_database();
|
|
108
124
|
|
|
109
125
|
// src/lib/keychain.ts
|
|
110
126
|
import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
|
|
@@ -115,6 +131,57 @@ import crypto from "crypto";
|
|
|
115
131
|
|
|
116
132
|
// src/lib/store.ts
|
|
117
133
|
init_config();
|
|
134
|
+
|
|
135
|
+
// src/lib/state-bus.ts
|
|
136
|
+
var StateBus = class {
|
|
137
|
+
handlers = /* @__PURE__ */ new Map();
|
|
138
|
+
globalHandlers = /* @__PURE__ */ new Set();
|
|
139
|
+
/** Emit an event to all subscribers */
|
|
140
|
+
emit(event) {
|
|
141
|
+
const typeHandlers = this.handlers.get(event.type);
|
|
142
|
+
if (typeHandlers) {
|
|
143
|
+
for (const handler of typeHandlers) {
|
|
144
|
+
try {
|
|
145
|
+
handler(event);
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
for (const handler of this.globalHandlers) {
|
|
151
|
+
try {
|
|
152
|
+
handler(event);
|
|
153
|
+
} catch {
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/** Subscribe to a specific event type */
|
|
158
|
+
on(type, handler) {
|
|
159
|
+
if (!this.handlers.has(type)) {
|
|
160
|
+
this.handlers.set(type, /* @__PURE__ */ new Set());
|
|
161
|
+
}
|
|
162
|
+
this.handlers.get(type).add(handler);
|
|
163
|
+
}
|
|
164
|
+
/** Subscribe to ALL events */
|
|
165
|
+
onAny(handler) {
|
|
166
|
+
this.globalHandlers.add(handler);
|
|
167
|
+
}
|
|
168
|
+
/** Unsubscribe from a specific event type */
|
|
169
|
+
off(type, handler) {
|
|
170
|
+
this.handlers.get(type)?.delete(handler);
|
|
171
|
+
}
|
|
172
|
+
/** Unsubscribe from ALL events */
|
|
173
|
+
offAny(handler) {
|
|
174
|
+
this.globalHandlers.delete(handler);
|
|
175
|
+
}
|
|
176
|
+
/** Remove all listeners */
|
|
177
|
+
clear() {
|
|
178
|
+
this.handlers.clear();
|
|
179
|
+
this.globalHandlers.clear();
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
var orgBus = new StateBus();
|
|
183
|
+
|
|
184
|
+
// src/lib/store.ts
|
|
118
185
|
function vectorToBlob(vector) {
|
|
119
186
|
const f32 = vector instanceof Float32Array ? vector : new Float32Array(vector);
|
|
120
187
|
return JSON.stringify(Array.from(f32));
|
package/dist/lib/database.js
CHANGED
|
@@ -293,6 +293,13 @@ async function ensureSchema() {
|
|
|
293
293
|
});
|
|
294
294
|
} catch {
|
|
295
295
|
}
|
|
296
|
+
try {
|
|
297
|
+
await client.execute({
|
|
298
|
+
sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
|
|
299
|
+
args: []
|
|
300
|
+
});
|
|
301
|
+
} catch {
|
|
302
|
+
}
|
|
296
303
|
try {
|
|
297
304
|
await client.execute({
|
|
298
305
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
@@ -739,6 +746,18 @@ async function ensureSchema() {
|
|
|
739
746
|
CREATE INDEX IF NOT EXISTS idx_session_kills_agent
|
|
740
747
|
ON session_kills(agent_id);
|
|
741
748
|
`);
|
|
749
|
+
await client.execute(`
|
|
750
|
+
CREATE TABLE IF NOT EXISTS global_procedures (
|
|
751
|
+
id TEXT PRIMARY KEY,
|
|
752
|
+
title TEXT NOT NULL,
|
|
753
|
+
content TEXT NOT NULL,
|
|
754
|
+
priority TEXT NOT NULL DEFAULT 'p0',
|
|
755
|
+
domain TEXT,
|
|
756
|
+
active INTEGER NOT NULL DEFAULT 1,
|
|
757
|
+
created_at TEXT NOT NULL,
|
|
758
|
+
updated_at TEXT NOT NULL
|
|
759
|
+
)
|
|
760
|
+
`);
|
|
742
761
|
await client.executeMultiple(`
|
|
743
762
|
CREATE TABLE IF NOT EXISTS conversations (
|
|
744
763
|
id TEXT PRIMARY KEY,
|
|
@@ -315,6 +315,13 @@ async function ensureSchema() {
|
|
|
315
315
|
});
|
|
316
316
|
} catch {
|
|
317
317
|
}
|
|
318
|
+
try {
|
|
319
|
+
await client.execute({
|
|
320
|
+
sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
|
|
321
|
+
args: []
|
|
322
|
+
});
|
|
323
|
+
} catch {
|
|
324
|
+
}
|
|
318
325
|
try {
|
|
319
326
|
await client.execute({
|
|
320
327
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
@@ -761,6 +768,18 @@ async function ensureSchema() {
|
|
|
761
768
|
CREATE INDEX IF NOT EXISTS idx_session_kills_agent
|
|
762
769
|
ON session_kills(agent_id);
|
|
763
770
|
`);
|
|
771
|
+
await client.execute(`
|
|
772
|
+
CREATE TABLE IF NOT EXISTS global_procedures (
|
|
773
|
+
id TEXT PRIMARY KEY,
|
|
774
|
+
title TEXT NOT NULL,
|
|
775
|
+
content TEXT NOT NULL,
|
|
776
|
+
priority TEXT NOT NULL DEFAULT 'p0',
|
|
777
|
+
domain TEXT,
|
|
778
|
+
active INTEGER NOT NULL DEFAULT 1,
|
|
779
|
+
created_at TEXT NOT NULL,
|
|
780
|
+
updated_at TEXT NOT NULL
|
|
781
|
+
)
|
|
782
|
+
`);
|
|
764
783
|
await client.executeMultiple(`
|
|
765
784
|
CREATE TABLE IF NOT EXISTS conversations (
|
|
766
785
|
id TEXT PRIMARY KEY,
|
package/dist/lib/embedder.js
CHANGED
|
@@ -13,6 +13,7 @@ var config_exports = {};
|
|
|
13
13
|
__export(config_exports, {
|
|
14
14
|
CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
|
|
15
15
|
CONFIG_PATH: () => CONFIG_PATH,
|
|
16
|
+
COO_AGENT_NAME: () => COO_AGENT_NAME,
|
|
16
17
|
CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
|
|
17
18
|
DB_PATH: () => DB_PATH,
|
|
18
19
|
EXE_AI_DIR: () => EXE_AI_DIR,
|
|
@@ -168,7 +169,7 @@ async function loadConfigFrom(configPath) {
|
|
|
168
169
|
return { ...DEFAULT_CONFIG };
|
|
169
170
|
}
|
|
170
171
|
}
|
|
171
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
172
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
172
173
|
var init_config = __esm({
|
|
173
174
|
"src/lib/config.ts"() {
|
|
174
175
|
"use strict";
|
|
@@ -176,6 +177,7 @@ var init_config = __esm({
|
|
|
176
177
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
177
178
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
178
179
|
CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
|
|
180
|
+
COO_AGENT_NAME = "exe";
|
|
179
181
|
LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
|
|
180
182
|
CURRENT_CONFIG_VERSION = 1;
|
|
181
183
|
DEFAULT_CONFIG = {
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
// src/lib/global-procedures.ts
|
|
2
|
+
import { randomUUID } from "crypto";
|
|
3
|
+
|
|
4
|
+
// src/lib/database.ts
|
|
5
|
+
import { createClient } from "@libsql/client";
|
|
6
|
+
|
|
7
|
+
// src/lib/global-procedures.ts
|
|
8
|
+
var _cache = "";
|
|
9
|
+
var _cacheLoaded = false;
|
|
10
|
+
function getGlobalProceduresBlock() {
|
|
11
|
+
if (!_cacheLoaded) return "";
|
|
12
|
+
if (!_cache) return "";
|
|
13
|
+
return `## Organization-Wide Procedures (MANDATORY \u2014 supersedes all other rules)
|
|
14
|
+
|
|
15
|
+
${_cache}
|
|
16
|
+
`;
|
|
17
|
+
}
|
|
18
|
+
|
|
1
19
|
// src/lib/employee-templates.ts
|
|
2
20
|
var BASE_OPERATING_PROCEDURES = `
|
|
3
21
|
EXE OS \u2014 VISION AND NON-NEGOTIABLE PRINCIPLES (above all work):
|
|
@@ -148,7 +166,8 @@ var PROCEDURES_MARKER = "EXE OS \u2014 VISION AND NON-NEGOTIABLE PRINCIPLES";
|
|
|
148
166
|
function getSessionPrompt(storedPrompt) {
|
|
149
167
|
const markerIndex = storedPrompt.indexOf(PROCEDURES_MARKER);
|
|
150
168
|
const rolePrompt = markerIndex >= 0 ? storedPrompt.slice(0, markerIndex).trimEnd() : storedPrompt;
|
|
151
|
-
|
|
169
|
+
const globalBlock = getGlobalProceduresBlock();
|
|
170
|
+
return `${globalBlock}${rolePrompt}
|
|
152
171
|
${BASE_OPERATING_PROCEDURES}`;
|
|
153
172
|
}
|
|
154
173
|
var TEMPLATES = {
|