@askexenow/exe-os 0.9.54 → 0.9.56
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 +65 -0
- package/dist/bin/backfill-responses.js +65 -0
- package/dist/bin/backfill-vectors.js +65 -0
- package/dist/bin/cleanup-stale-review-tasks.js +91 -8
- package/dist/bin/cli.js +79 -1
- package/dist/bin/exe-assign.js +65 -0
- package/dist/bin/exe-boot.js +332 -190
- package/dist/bin/exe-dispatch.js +245 -103
- package/dist/bin/exe-doctor.js +114 -3
- package/dist/bin/exe-export-behaviors.js +72 -0
- package/dist/bin/exe-forget.js +65 -0
- package/dist/bin/exe-gateway.js +242 -100
- package/dist/bin/exe-heartbeat.js +103 -20
- package/dist/bin/exe-kill.js +65 -0
- package/dist/bin/exe-launch-agent.js +72 -0
- package/dist/bin/exe-pending-messages.js +113 -30
- package/dist/bin/exe-pending-notifications.js +116 -33
- package/dist/bin/exe-pending-reviews.js +118 -35
- package/dist/bin/exe-rename.js +65 -0
- package/dist/bin/exe-review.js +65 -0
- package/dist/bin/exe-search.js +65 -0
- package/dist/bin/exe-session-cleanup.js +233 -91
- package/dist/bin/exe-start-codex.js +72 -0
- package/dist/bin/exe-start-opencode.js +72 -0
- package/dist/bin/exe-status.js +91 -8
- package/dist/bin/exe-team.js +65 -0
- package/dist/bin/git-sweep.js +247 -105
- package/dist/bin/graph-backfill.js +65 -0
- package/dist/bin/graph-export.js +65 -0
- package/dist/bin/intercom-check.js +235 -93
- package/dist/bin/scan-tasks.js +253 -111
- package/dist/bin/shard-migrate.js +65 -0
- package/dist/gateway/index.js +231 -89
- package/dist/hooks/bug-report-worker.js +223 -81
- package/dist/hooks/codex-stop-task-finalizer.js +122 -39
- package/dist/hooks/commit-complete.js +245 -103
- package/dist/hooks/error-recall.js +65 -0
- package/dist/hooks/ingest.js +65 -0
- package/dist/hooks/instructions-loaded.js +65 -0
- package/dist/hooks/notification.js +65 -0
- package/dist/hooks/post-compact.js +113 -30
- package/dist/hooks/post-tool-combined.js +65 -0
- package/dist/hooks/pre-compact.js +248 -106
- package/dist/hooks/pre-tool-use.js +134 -51
- package/dist/hooks/prompt-submit.js +241 -92
- package/dist/hooks/session-end.js +256 -114
- package/dist/hooks/session-start.js +118 -35
- package/dist/hooks/stop.js +125 -42
- package/dist/hooks/subagent-stop.js +113 -30
- package/dist/hooks/summary-worker.js +174 -91
- package/dist/index.js +268 -119
- package/dist/lib/exe-daemon.js +493 -307
- package/dist/lib/hybrid-search.js +65 -0
- package/dist/lib/messaging.js +32 -14
- package/dist/lib/schedules.js +65 -0
- package/dist/lib/store.js +65 -0
- package/dist/lib/tasks.js +180 -103
- package/dist/lib/tmux-routing.js +180 -103
- package/dist/mcp/server.js +468 -282
- package/dist/mcp/tools/create-task.js +194 -117
- package/dist/mcp/tools/list-tasks.js +45 -27
- package/dist/mcp/tools/send-message.js +36 -18
- package/dist/mcp/tools/update-task.js +189 -112
- package/dist/runtime/index.js +254 -105
- package/dist/tui/App.js +291 -149
- package/package.json +1 -1
|
@@ -2729,6 +2729,7 @@ var init_database = __esm({
|
|
|
2729
2729
|
// src/lib/shard-manager.ts
|
|
2730
2730
|
var shard_manager_exports = {};
|
|
2731
2731
|
__export(shard_manager_exports, {
|
|
2732
|
+
auditShardHealth: () => auditShardHealth,
|
|
2732
2733
|
disposeShards: () => disposeShards,
|
|
2733
2734
|
ensureShardSchema: () => ensureShardSchema,
|
|
2734
2735
|
getOpenShardCount: () => getOpenShardCount,
|
|
@@ -2795,6 +2796,70 @@ function listShards() {
|
|
|
2795
2796
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
2796
2797
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
2797
2798
|
}
|
|
2799
|
+
async function auditShardHealth(options = {}) {
|
|
2800
|
+
if (!_encryptionKey) {
|
|
2801
|
+
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
2802
|
+
}
|
|
2803
|
+
const repair = options.repair === true;
|
|
2804
|
+
const dryRun = options.dryRun === true;
|
|
2805
|
+
const names = listShards();
|
|
2806
|
+
const shards = [];
|
|
2807
|
+
for (const name of names) {
|
|
2808
|
+
const dbPath = path7.join(SHARDS_DIR, `${name}.db`);
|
|
2809
|
+
const stat2 = statSync2(dbPath);
|
|
2810
|
+
const item = {
|
|
2811
|
+
name,
|
|
2812
|
+
path: dbPath,
|
|
2813
|
+
ok: false,
|
|
2814
|
+
unreadable: false,
|
|
2815
|
+
error: null,
|
|
2816
|
+
size: stat2.size,
|
|
2817
|
+
mtime: stat2.mtime.toISOString(),
|
|
2818
|
+
memoryCount: null
|
|
2819
|
+
};
|
|
2820
|
+
const client = createClient2({
|
|
2821
|
+
url: `file:${dbPath}`,
|
|
2822
|
+
encryptionKey: _encryptionKey
|
|
2823
|
+
});
|
|
2824
|
+
try {
|
|
2825
|
+
await client.execute("SELECT COUNT(*) as cnt FROM sqlite_schema");
|
|
2826
|
+
const hasMemories = await client.execute(
|
|
2827
|
+
"SELECT COUNT(*) as cnt FROM sqlite_schema WHERE type = 'table' AND name = 'memories'"
|
|
2828
|
+
);
|
|
2829
|
+
if (Number(hasMemories.rows[0]?.cnt ?? 0) > 0) {
|
|
2830
|
+
const mem = await client.execute("SELECT COUNT(*) as cnt FROM memories");
|
|
2831
|
+
item.memoryCount = Number(mem.rows[0]?.cnt ?? 0);
|
|
2832
|
+
}
|
|
2833
|
+
item.ok = true;
|
|
2834
|
+
} catch (err) {
|
|
2835
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2836
|
+
item.error = message;
|
|
2837
|
+
item.unreadable = /SQLITE_NOTADB|file is not a database/i.test(message);
|
|
2838
|
+
if (item.unreadable && repair && !dryRun) {
|
|
2839
|
+
client.close();
|
|
2840
|
+
_shards.delete(name);
|
|
2841
|
+
_shardLastAccess.delete(name);
|
|
2842
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2843
|
+
const archivedPath = path7.join(SHARDS_DIR, `${name}.db.broken-${stamp}`);
|
|
2844
|
+
renameSync3(dbPath, archivedPath);
|
|
2845
|
+
item.archivedPath = archivedPath;
|
|
2846
|
+
}
|
|
2847
|
+
} finally {
|
|
2848
|
+
try {
|
|
2849
|
+
client.close();
|
|
2850
|
+
} catch {
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
shards.push(item);
|
|
2854
|
+
}
|
|
2855
|
+
return {
|
|
2856
|
+
total: shards.length,
|
|
2857
|
+
ok: shards.filter((s) => s.ok).length,
|
|
2858
|
+
unreadable: shards.filter((s) => s.unreadable).length,
|
|
2859
|
+
archived: shards.filter((s) => Boolean(s.archivedPath)).length,
|
|
2860
|
+
shards
|
|
2861
|
+
};
|
|
2862
|
+
}
|
|
2798
2863
|
async function ensureShardSchema(client) {
|
|
2799
2864
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
2800
2865
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
@@ -2729,6 +2729,7 @@ var init_database = __esm({
|
|
|
2729
2729
|
// src/lib/shard-manager.ts
|
|
2730
2730
|
var shard_manager_exports = {};
|
|
2731
2731
|
__export(shard_manager_exports, {
|
|
2732
|
+
auditShardHealth: () => auditShardHealth,
|
|
2732
2733
|
disposeShards: () => disposeShards,
|
|
2733
2734
|
ensureShardSchema: () => ensureShardSchema,
|
|
2734
2735
|
getOpenShardCount: () => getOpenShardCount,
|
|
@@ -2795,6 +2796,70 @@ function listShards() {
|
|
|
2795
2796
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
2796
2797
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
2797
2798
|
}
|
|
2799
|
+
async function auditShardHealth(options = {}) {
|
|
2800
|
+
if (!_encryptionKey) {
|
|
2801
|
+
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
2802
|
+
}
|
|
2803
|
+
const repair = options.repair === true;
|
|
2804
|
+
const dryRun = options.dryRun === true;
|
|
2805
|
+
const names = listShards();
|
|
2806
|
+
const shards = [];
|
|
2807
|
+
for (const name of names) {
|
|
2808
|
+
const dbPath = path7.join(SHARDS_DIR, `${name}.db`);
|
|
2809
|
+
const stat2 = statSync2(dbPath);
|
|
2810
|
+
const item = {
|
|
2811
|
+
name,
|
|
2812
|
+
path: dbPath,
|
|
2813
|
+
ok: false,
|
|
2814
|
+
unreadable: false,
|
|
2815
|
+
error: null,
|
|
2816
|
+
size: stat2.size,
|
|
2817
|
+
mtime: stat2.mtime.toISOString(),
|
|
2818
|
+
memoryCount: null
|
|
2819
|
+
};
|
|
2820
|
+
const client = createClient2({
|
|
2821
|
+
url: `file:${dbPath}`,
|
|
2822
|
+
encryptionKey: _encryptionKey
|
|
2823
|
+
});
|
|
2824
|
+
try {
|
|
2825
|
+
await client.execute("SELECT COUNT(*) as cnt FROM sqlite_schema");
|
|
2826
|
+
const hasMemories = await client.execute(
|
|
2827
|
+
"SELECT COUNT(*) as cnt FROM sqlite_schema WHERE type = 'table' AND name = 'memories'"
|
|
2828
|
+
);
|
|
2829
|
+
if (Number(hasMemories.rows[0]?.cnt ?? 0) > 0) {
|
|
2830
|
+
const mem = await client.execute("SELECT COUNT(*) as cnt FROM memories");
|
|
2831
|
+
item.memoryCount = Number(mem.rows[0]?.cnt ?? 0);
|
|
2832
|
+
}
|
|
2833
|
+
item.ok = true;
|
|
2834
|
+
} catch (err) {
|
|
2835
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2836
|
+
item.error = message;
|
|
2837
|
+
item.unreadable = /SQLITE_NOTADB|file is not a database/i.test(message);
|
|
2838
|
+
if (item.unreadable && repair && !dryRun) {
|
|
2839
|
+
client.close();
|
|
2840
|
+
_shards.delete(name);
|
|
2841
|
+
_shardLastAccess.delete(name);
|
|
2842
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2843
|
+
const archivedPath = path7.join(SHARDS_DIR, `${name}.db.broken-${stamp}`);
|
|
2844
|
+
renameSync3(dbPath, archivedPath);
|
|
2845
|
+
item.archivedPath = archivedPath;
|
|
2846
|
+
}
|
|
2847
|
+
} finally {
|
|
2848
|
+
try {
|
|
2849
|
+
client.close();
|
|
2850
|
+
} catch {
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
shards.push(item);
|
|
2854
|
+
}
|
|
2855
|
+
return {
|
|
2856
|
+
total: shards.length,
|
|
2857
|
+
ok: shards.filter((s) => s.ok).length,
|
|
2858
|
+
unreadable: shards.filter((s) => s.unreadable).length,
|
|
2859
|
+
archived: shards.filter((s) => Boolean(s.archivedPath)).length,
|
|
2860
|
+
shards
|
|
2861
|
+
};
|
|
2862
|
+
}
|
|
2798
2863
|
async function ensureShardSchema(client) {
|
|
2799
2864
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
2800
2865
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
@@ -2725,6 +2725,7 @@ var init_database = __esm({
|
|
|
2725
2725
|
// src/lib/shard-manager.ts
|
|
2726
2726
|
var shard_manager_exports = {};
|
|
2727
2727
|
__export(shard_manager_exports, {
|
|
2728
|
+
auditShardHealth: () => auditShardHealth,
|
|
2728
2729
|
disposeShards: () => disposeShards,
|
|
2729
2730
|
ensureShardSchema: () => ensureShardSchema,
|
|
2730
2731
|
getOpenShardCount: () => getOpenShardCount,
|
|
@@ -2791,6 +2792,70 @@ function listShards() {
|
|
|
2791
2792
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
2792
2793
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
2793
2794
|
}
|
|
2795
|
+
async function auditShardHealth(options = {}) {
|
|
2796
|
+
if (!_encryptionKey) {
|
|
2797
|
+
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
2798
|
+
}
|
|
2799
|
+
const repair = options.repair === true;
|
|
2800
|
+
const dryRun = options.dryRun === true;
|
|
2801
|
+
const names = listShards();
|
|
2802
|
+
const shards = [];
|
|
2803
|
+
for (const name of names) {
|
|
2804
|
+
const dbPath = path7.join(SHARDS_DIR, `${name}.db`);
|
|
2805
|
+
const stat = statSync2(dbPath);
|
|
2806
|
+
const item = {
|
|
2807
|
+
name,
|
|
2808
|
+
path: dbPath,
|
|
2809
|
+
ok: false,
|
|
2810
|
+
unreadable: false,
|
|
2811
|
+
error: null,
|
|
2812
|
+
size: stat.size,
|
|
2813
|
+
mtime: stat.mtime.toISOString(),
|
|
2814
|
+
memoryCount: null
|
|
2815
|
+
};
|
|
2816
|
+
const client = createClient2({
|
|
2817
|
+
url: `file:${dbPath}`,
|
|
2818
|
+
encryptionKey: _encryptionKey
|
|
2819
|
+
});
|
|
2820
|
+
try {
|
|
2821
|
+
await client.execute("SELECT COUNT(*) as cnt FROM sqlite_schema");
|
|
2822
|
+
const hasMemories = await client.execute(
|
|
2823
|
+
"SELECT COUNT(*) as cnt FROM sqlite_schema WHERE type = 'table' AND name = 'memories'"
|
|
2824
|
+
);
|
|
2825
|
+
if (Number(hasMemories.rows[0]?.cnt ?? 0) > 0) {
|
|
2826
|
+
const mem = await client.execute("SELECT COUNT(*) as cnt FROM memories");
|
|
2827
|
+
item.memoryCount = Number(mem.rows[0]?.cnt ?? 0);
|
|
2828
|
+
}
|
|
2829
|
+
item.ok = true;
|
|
2830
|
+
} catch (err) {
|
|
2831
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2832
|
+
item.error = message;
|
|
2833
|
+
item.unreadable = /SQLITE_NOTADB|file is not a database/i.test(message);
|
|
2834
|
+
if (item.unreadable && repair && !dryRun) {
|
|
2835
|
+
client.close();
|
|
2836
|
+
_shards.delete(name);
|
|
2837
|
+
_shardLastAccess.delete(name);
|
|
2838
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2839
|
+
const archivedPath = path7.join(SHARDS_DIR, `${name}.db.broken-${stamp}`);
|
|
2840
|
+
renameSync3(dbPath, archivedPath);
|
|
2841
|
+
item.archivedPath = archivedPath;
|
|
2842
|
+
}
|
|
2843
|
+
} finally {
|
|
2844
|
+
try {
|
|
2845
|
+
client.close();
|
|
2846
|
+
} catch {
|
|
2847
|
+
}
|
|
2848
|
+
}
|
|
2849
|
+
shards.push(item);
|
|
2850
|
+
}
|
|
2851
|
+
return {
|
|
2852
|
+
total: shards.length,
|
|
2853
|
+
ok: shards.filter((s) => s.ok).length,
|
|
2854
|
+
unreadable: shards.filter((s) => s.unreadable).length,
|
|
2855
|
+
archived: shards.filter((s) => Boolean(s.archivedPath)).length,
|
|
2856
|
+
shards
|
|
2857
|
+
};
|
|
2858
|
+
}
|
|
2794
2859
|
async function ensureShardSchema(client) {
|
|
2795
2860
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
2796
2861
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
@@ -3287,6 +3287,7 @@ var init_memory_write_governor = __esm({
|
|
|
3287
3287
|
// src/lib/shard-manager.ts
|
|
3288
3288
|
var shard_manager_exports = {};
|
|
3289
3289
|
__export(shard_manager_exports, {
|
|
3290
|
+
auditShardHealth: () => auditShardHealth,
|
|
3290
3291
|
disposeShards: () => disposeShards,
|
|
3291
3292
|
ensureShardSchema: () => ensureShardSchema,
|
|
3292
3293
|
getOpenShardCount: () => getOpenShardCount,
|
|
@@ -3353,6 +3354,70 @@ function listShards() {
|
|
|
3353
3354
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
3354
3355
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
3355
3356
|
}
|
|
3357
|
+
async function auditShardHealth(options = {}) {
|
|
3358
|
+
if (!_encryptionKey) {
|
|
3359
|
+
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
3360
|
+
}
|
|
3361
|
+
const repair = options.repair === true;
|
|
3362
|
+
const dryRun = options.dryRun === true;
|
|
3363
|
+
const names = listShards();
|
|
3364
|
+
const shards = [];
|
|
3365
|
+
for (const name of names) {
|
|
3366
|
+
const dbPath = path7.join(SHARDS_DIR, `${name}.db`);
|
|
3367
|
+
const stat = statSync2(dbPath);
|
|
3368
|
+
const item = {
|
|
3369
|
+
name,
|
|
3370
|
+
path: dbPath,
|
|
3371
|
+
ok: false,
|
|
3372
|
+
unreadable: false,
|
|
3373
|
+
error: null,
|
|
3374
|
+
size: stat.size,
|
|
3375
|
+
mtime: stat.mtime.toISOString(),
|
|
3376
|
+
memoryCount: null
|
|
3377
|
+
};
|
|
3378
|
+
const client = createClient2({
|
|
3379
|
+
url: `file:${dbPath}`,
|
|
3380
|
+
encryptionKey: _encryptionKey
|
|
3381
|
+
});
|
|
3382
|
+
try {
|
|
3383
|
+
await client.execute("SELECT COUNT(*) as cnt FROM sqlite_schema");
|
|
3384
|
+
const hasMemories = await client.execute(
|
|
3385
|
+
"SELECT COUNT(*) as cnt FROM sqlite_schema WHERE type = 'table' AND name = 'memories'"
|
|
3386
|
+
);
|
|
3387
|
+
if (Number(hasMemories.rows[0]?.cnt ?? 0) > 0) {
|
|
3388
|
+
const mem = await client.execute("SELECT COUNT(*) as cnt FROM memories");
|
|
3389
|
+
item.memoryCount = Number(mem.rows[0]?.cnt ?? 0);
|
|
3390
|
+
}
|
|
3391
|
+
item.ok = true;
|
|
3392
|
+
} catch (err) {
|
|
3393
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3394
|
+
item.error = message;
|
|
3395
|
+
item.unreadable = /SQLITE_NOTADB|file is not a database/i.test(message);
|
|
3396
|
+
if (item.unreadable && repair && !dryRun) {
|
|
3397
|
+
client.close();
|
|
3398
|
+
_shards.delete(name);
|
|
3399
|
+
_shardLastAccess.delete(name);
|
|
3400
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3401
|
+
const archivedPath = path7.join(SHARDS_DIR, `${name}.db.broken-${stamp}`);
|
|
3402
|
+
renameSync3(dbPath, archivedPath);
|
|
3403
|
+
item.archivedPath = archivedPath;
|
|
3404
|
+
}
|
|
3405
|
+
} finally {
|
|
3406
|
+
try {
|
|
3407
|
+
client.close();
|
|
3408
|
+
} catch {
|
|
3409
|
+
}
|
|
3410
|
+
}
|
|
3411
|
+
shards.push(item);
|
|
3412
|
+
}
|
|
3413
|
+
return {
|
|
3414
|
+
total: shards.length,
|
|
3415
|
+
ok: shards.filter((s) => s.ok).length,
|
|
3416
|
+
unreadable: shards.filter((s) => s.unreadable).length,
|
|
3417
|
+
archived: shards.filter((s) => Boolean(s.archivedPath)).length,
|
|
3418
|
+
shards
|
|
3419
|
+
};
|
|
3420
|
+
}
|
|
3356
3421
|
async function ensureShardSchema(client) {
|
|
3357
3422
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
3358
3423
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
@@ -4820,10 +4885,27 @@ var init_plan_limits = __esm({
|
|
|
4820
4885
|
}
|
|
4821
4886
|
});
|
|
4822
4887
|
|
|
4823
|
-
// src/lib/
|
|
4824
|
-
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync12, appendFileSync, readdirSync as readdirSync2 } from "fs";
|
|
4825
|
-
import path13 from "path";
|
|
4888
|
+
// src/lib/agent-symlinks.ts
|
|
4826
4889
|
import os9 from "os";
|
|
4890
|
+
import path13 from "path";
|
|
4891
|
+
import {
|
|
4892
|
+
existsSync as existsSync12,
|
|
4893
|
+
lstatSync,
|
|
4894
|
+
mkdirSync as mkdirSync5,
|
|
4895
|
+
readlinkSync as readlinkSync2,
|
|
4896
|
+
symlinkSync as symlinkSync2
|
|
4897
|
+
} from "fs";
|
|
4898
|
+
var init_agent_symlinks = __esm({
|
|
4899
|
+
"src/lib/agent-symlinks.ts"() {
|
|
4900
|
+
"use strict";
|
|
4901
|
+
init_employees();
|
|
4902
|
+
}
|
|
4903
|
+
});
|
|
4904
|
+
|
|
4905
|
+
// src/lib/tmux-routing.ts
|
|
4906
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, existsSync as existsSync13, appendFileSync, readdirSync as readdirSync2 } from "fs";
|
|
4907
|
+
import path14 from "path";
|
|
4908
|
+
import os10 from "os";
|
|
4827
4909
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4828
4910
|
function getMySession() {
|
|
4829
4911
|
return getTransport().getMySession();
|
|
@@ -4836,7 +4918,7 @@ function extractRootExe(name) {
|
|
|
4836
4918
|
}
|
|
4837
4919
|
function getParentExe(sessionKey) {
|
|
4838
4920
|
try {
|
|
4839
|
-
const data = JSON.parse(readFileSync9(
|
|
4921
|
+
const data = JSON.parse(readFileSync9(path14.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
4840
4922
|
return data.parentExe || null;
|
|
4841
4923
|
} catch {
|
|
4842
4924
|
return null;
|
|
@@ -4879,10 +4961,11 @@ var init_tmux_routing = __esm({
|
|
|
4879
4961
|
init_intercom_queue();
|
|
4880
4962
|
init_plan_limits();
|
|
4881
4963
|
init_employees();
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4964
|
+
init_agent_symlinks();
|
|
4965
|
+
SPAWN_LOCK_DIR = path14.join(os10.homedir(), ".exe-os", "spawn-locks");
|
|
4966
|
+
SESSION_CACHE = path14.join(os10.homedir(), ".exe-os", "session-cache");
|
|
4967
|
+
INTERCOM_LOG2 = path14.join(os10.homedir(), ".exe-os", "intercom.log");
|
|
4968
|
+
DEBOUNCE_FILE = path14.join(SESSION_CACHE, "intercom-debounce.json");
|
|
4886
4969
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
4887
4970
|
}
|
|
4888
4971
|
});
|
package/dist/bin/cli.js
CHANGED
|
@@ -7157,6 +7157,7 @@ var init_memory_write_governor = __esm({
|
|
|
7157
7157
|
// src/lib/shard-manager.ts
|
|
7158
7158
|
var shard_manager_exports = {};
|
|
7159
7159
|
__export(shard_manager_exports, {
|
|
7160
|
+
auditShardHealth: () => auditShardHealth,
|
|
7160
7161
|
disposeShards: () => disposeShards,
|
|
7161
7162
|
ensureShardSchema: () => ensureShardSchema,
|
|
7162
7163
|
getOpenShardCount: () => getOpenShardCount,
|
|
@@ -7223,6 +7224,70 @@ function listShards() {
|
|
|
7223
7224
|
if (!existsSync15(SHARDS_DIR)) return [];
|
|
7224
7225
|
return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
7225
7226
|
}
|
|
7227
|
+
async function auditShardHealth(options = {}) {
|
|
7228
|
+
if (!_encryptionKey) {
|
|
7229
|
+
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
7230
|
+
}
|
|
7231
|
+
const repair = options.repair === true;
|
|
7232
|
+
const dryRun = options.dryRun === true;
|
|
7233
|
+
const names = listShards();
|
|
7234
|
+
const shards = [];
|
|
7235
|
+
for (const name of names) {
|
|
7236
|
+
const dbPath = path15.join(SHARDS_DIR, `${name}.db`);
|
|
7237
|
+
const stat2 = statSync4(dbPath);
|
|
7238
|
+
const item = {
|
|
7239
|
+
name,
|
|
7240
|
+
path: dbPath,
|
|
7241
|
+
ok: false,
|
|
7242
|
+
unreadable: false,
|
|
7243
|
+
error: null,
|
|
7244
|
+
size: stat2.size,
|
|
7245
|
+
mtime: stat2.mtime.toISOString(),
|
|
7246
|
+
memoryCount: null
|
|
7247
|
+
};
|
|
7248
|
+
const client = createClient2({
|
|
7249
|
+
url: `file:${dbPath}`,
|
|
7250
|
+
encryptionKey: _encryptionKey
|
|
7251
|
+
});
|
|
7252
|
+
try {
|
|
7253
|
+
await client.execute("SELECT COUNT(*) as cnt FROM sqlite_schema");
|
|
7254
|
+
const hasMemories = await client.execute(
|
|
7255
|
+
"SELECT COUNT(*) as cnt FROM sqlite_schema WHERE type = 'table' AND name = 'memories'"
|
|
7256
|
+
);
|
|
7257
|
+
if (Number(hasMemories.rows[0]?.cnt ?? 0) > 0) {
|
|
7258
|
+
const mem = await client.execute("SELECT COUNT(*) as cnt FROM memories");
|
|
7259
|
+
item.memoryCount = Number(mem.rows[0]?.cnt ?? 0);
|
|
7260
|
+
}
|
|
7261
|
+
item.ok = true;
|
|
7262
|
+
} catch (err) {
|
|
7263
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
7264
|
+
item.error = message;
|
|
7265
|
+
item.unreadable = /SQLITE_NOTADB|file is not a database/i.test(message);
|
|
7266
|
+
if (item.unreadable && repair && !dryRun) {
|
|
7267
|
+
client.close();
|
|
7268
|
+
_shards.delete(name);
|
|
7269
|
+
_shardLastAccess.delete(name);
|
|
7270
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
7271
|
+
const archivedPath = path15.join(SHARDS_DIR, `${name}.db.broken-${stamp}`);
|
|
7272
|
+
renameSync3(dbPath, archivedPath);
|
|
7273
|
+
item.archivedPath = archivedPath;
|
|
7274
|
+
}
|
|
7275
|
+
} finally {
|
|
7276
|
+
try {
|
|
7277
|
+
client.close();
|
|
7278
|
+
} catch {
|
|
7279
|
+
}
|
|
7280
|
+
}
|
|
7281
|
+
shards.push(item);
|
|
7282
|
+
}
|
|
7283
|
+
return {
|
|
7284
|
+
total: shards.length,
|
|
7285
|
+
ok: shards.filter((s) => s.ok).length,
|
|
7286
|
+
unreadable: shards.filter((s) => s.unreadable).length,
|
|
7287
|
+
archived: shards.filter((s) => Boolean(s.archivedPath)).length,
|
|
7288
|
+
shards
|
|
7289
|
+
};
|
|
7290
|
+
}
|
|
7226
7291
|
async function ensureShardSchema(client) {
|
|
7227
7292
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
7228
7293
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
@@ -13296,7 +13361,19 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
13296
13361
|
_resetCcAgentSupportCache();
|
|
13297
13362
|
const hasAgentFlag = claudeSupportsAgentFlag();
|
|
13298
13363
|
if (hasAgentFlag) {
|
|
13299
|
-
|
|
13364
|
+
const symlink = ensureAgentSymlink(employeeName);
|
|
13365
|
+
if (symlink.action === "created" || symlink.action === "already_correct") {
|
|
13366
|
+
identityFlag = ` --agent ${employeeName}`;
|
|
13367
|
+
} else if (existsSync24(identityPath2)) {
|
|
13368
|
+
identityFlag = ` --append-system-prompt-file ${identityPath2}`;
|
|
13369
|
+
legacyFallbackWarned = true;
|
|
13370
|
+
process.stderr.write(
|
|
13371
|
+
`[tmux-routing] WARN: ~/.claude/agents/${employeeName}.md is not the exe-os identity symlink (${symlink.conflict}). Using authoritative ${identityPath2} via --append-system-prompt-file.
|
|
13372
|
+
`
|
|
13373
|
+
);
|
|
13374
|
+
} else {
|
|
13375
|
+
identityFlag = ` --agent ${employeeName}`;
|
|
13376
|
+
}
|
|
13300
13377
|
} else if (existsSync24(identityPath2)) {
|
|
13301
13378
|
identityFlag = ` --append-system-prompt-file ${identityPath2}`;
|
|
13302
13379
|
legacyFallbackWarned = true;
|
|
@@ -13485,6 +13562,7 @@ var init_tmux_routing = __esm({
|
|
|
13485
13562
|
init_intercom_queue();
|
|
13486
13563
|
init_plan_limits();
|
|
13487
13564
|
init_employees();
|
|
13565
|
+
init_agent_symlinks();
|
|
13488
13566
|
SPAWN_LOCK_DIR = path29.join(os15.homedir(), ".exe-os", "spawn-locks");
|
|
13489
13567
|
SESSION_CACHE = path29.join(os15.homedir(), ".exe-os", "session-cache");
|
|
13490
13568
|
BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
|
package/dist/bin/exe-assign.js
CHANGED
|
@@ -2739,6 +2739,7 @@ var init_database = __esm({
|
|
|
2739
2739
|
// src/lib/shard-manager.ts
|
|
2740
2740
|
var shard_manager_exports = {};
|
|
2741
2741
|
__export(shard_manager_exports, {
|
|
2742
|
+
auditShardHealth: () => auditShardHealth,
|
|
2742
2743
|
disposeShards: () => disposeShards,
|
|
2743
2744
|
ensureShardSchema: () => ensureShardSchema,
|
|
2744
2745
|
getOpenShardCount: () => getOpenShardCount,
|
|
@@ -2805,6 +2806,70 @@ function listShards() {
|
|
|
2805
2806
|
if (!existsSync7(SHARDS_DIR)) return [];
|
|
2806
2807
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
2807
2808
|
}
|
|
2809
|
+
async function auditShardHealth(options = {}) {
|
|
2810
|
+
if (!_encryptionKey) {
|
|
2811
|
+
throw new Error("Shard manager not initialized. Call initShardManager() first.");
|
|
2812
|
+
}
|
|
2813
|
+
const repair = options.repair === true;
|
|
2814
|
+
const dryRun = options.dryRun === true;
|
|
2815
|
+
const names = listShards();
|
|
2816
|
+
const shards = [];
|
|
2817
|
+
for (const name of names) {
|
|
2818
|
+
const dbPath = path7.join(SHARDS_DIR, `${name}.db`);
|
|
2819
|
+
const stat = statSync2(dbPath);
|
|
2820
|
+
const item = {
|
|
2821
|
+
name,
|
|
2822
|
+
path: dbPath,
|
|
2823
|
+
ok: false,
|
|
2824
|
+
unreadable: false,
|
|
2825
|
+
error: null,
|
|
2826
|
+
size: stat.size,
|
|
2827
|
+
mtime: stat.mtime.toISOString(),
|
|
2828
|
+
memoryCount: null
|
|
2829
|
+
};
|
|
2830
|
+
const client = createClient2({
|
|
2831
|
+
url: `file:${dbPath}`,
|
|
2832
|
+
encryptionKey: _encryptionKey
|
|
2833
|
+
});
|
|
2834
|
+
try {
|
|
2835
|
+
await client.execute("SELECT COUNT(*) as cnt FROM sqlite_schema");
|
|
2836
|
+
const hasMemories = await client.execute(
|
|
2837
|
+
"SELECT COUNT(*) as cnt FROM sqlite_schema WHERE type = 'table' AND name = 'memories'"
|
|
2838
|
+
);
|
|
2839
|
+
if (Number(hasMemories.rows[0]?.cnt ?? 0) > 0) {
|
|
2840
|
+
const mem = await client.execute("SELECT COUNT(*) as cnt FROM memories");
|
|
2841
|
+
item.memoryCount = Number(mem.rows[0]?.cnt ?? 0);
|
|
2842
|
+
}
|
|
2843
|
+
item.ok = true;
|
|
2844
|
+
} catch (err) {
|
|
2845
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2846
|
+
item.error = message;
|
|
2847
|
+
item.unreadable = /SQLITE_NOTADB|file is not a database/i.test(message);
|
|
2848
|
+
if (item.unreadable && repair && !dryRun) {
|
|
2849
|
+
client.close();
|
|
2850
|
+
_shards.delete(name);
|
|
2851
|
+
_shardLastAccess.delete(name);
|
|
2852
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2853
|
+
const archivedPath = path7.join(SHARDS_DIR, `${name}.db.broken-${stamp}`);
|
|
2854
|
+
renameSync3(dbPath, archivedPath);
|
|
2855
|
+
item.archivedPath = archivedPath;
|
|
2856
|
+
}
|
|
2857
|
+
} finally {
|
|
2858
|
+
try {
|
|
2859
|
+
client.close();
|
|
2860
|
+
} catch {
|
|
2861
|
+
}
|
|
2862
|
+
}
|
|
2863
|
+
shards.push(item);
|
|
2864
|
+
}
|
|
2865
|
+
return {
|
|
2866
|
+
total: shards.length,
|
|
2867
|
+
ok: shards.filter((s) => s.ok).length,
|
|
2868
|
+
unreadable: shards.filter((s) => s.unreadable).length,
|
|
2869
|
+
archived: shards.filter((s) => Boolean(s.archivedPath)).length,
|
|
2870
|
+
shards
|
|
2871
|
+
};
|
|
2872
|
+
}
|
|
2808
2873
|
async function ensureShardSchema(client) {
|
|
2809
2874
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
2810
2875
|
await client.execute("PRAGMA busy_timeout = 30000");
|