@askexenow/exe-os 0.9.87 → 0.9.89
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/deploy/compose/docker-compose.yml +3 -3
- package/dist/bin/age-ontology-load.js +8 -2
- package/dist/bin/agentic-ontology-backfill.js +11 -0
- package/dist/bin/agentic-reflection-backfill.js +11 -0
- package/dist/bin/agentic-semantic-label.js +11 -0
- package/dist/bin/backfill-conversations.js +12 -0
- package/dist/bin/backfill-responses.js +12 -0
- package/dist/bin/backfill-vectors.js +12 -0
- package/dist/bin/bulk-sync-postgres.js +29 -1
- package/dist/bin/cc-doctor.js +3 -2
- package/dist/bin/cleanup-stale-review-tasks.js +12 -0
- package/dist/bin/cli.js +170 -15
- package/dist/bin/exe-agent.js +1 -0
- package/dist/bin/exe-assign.js +12 -0
- package/dist/bin/exe-boot.js +139 -4
- package/dist/bin/exe-call.js +2 -0
- package/dist/bin/exe-cloud.js +138 -3
- package/dist/bin/exe-dispatch.js +12 -1
- package/dist/bin/exe-doctor.js +12 -0
- package/dist/bin/exe-export-behaviors.js +11 -0
- package/dist/bin/exe-forget.js +12 -0
- package/dist/bin/exe-gateway.js +132 -35
- package/dist/bin/exe-healthcheck.js +2 -1
- package/dist/bin/exe-heartbeat.js +12 -0
- package/dist/bin/exe-kill.js +11 -0
- package/dist/bin/exe-launch-agent.js +11 -0
- package/dist/bin/exe-new-employee.js +4 -2
- package/dist/bin/exe-pending-messages.js +11 -0
- package/dist/bin/exe-pending-notifications.js +12 -0
- package/dist/bin/exe-pending-reviews.js +12 -0
- package/dist/bin/exe-rename.js +12 -0
- package/dist/bin/exe-review.js +12 -0
- package/dist/bin/exe-search.js +12 -0
- package/dist/bin/exe-session-cleanup.js +12 -1
- package/dist/bin/exe-settings.js +3 -0
- package/dist/bin/exe-start-codex.js +13 -2
- package/dist/bin/exe-start-opencode.js +13 -2
- package/dist/bin/exe-status.js +12 -0
- package/dist/bin/exe-team.js +12 -0
- package/dist/bin/git-sweep.js +12 -1
- package/dist/bin/graph-backfill.js +11 -0
- package/dist/bin/graph-export.js +11 -0
- package/dist/bin/graph-layer-benchmark.js +9 -1
- package/dist/bin/intercom-check.js +13 -1
- package/dist/bin/list-providers.js +1 -0
- package/dist/bin/postgres-agentic-reflection-backfill.js +7 -1
- package/dist/bin/postgres-agentic-semantic-backfill.js +7 -1
- package/dist/bin/registry-proxy.js +1 -0
- package/dist/bin/scan-tasks.js +13 -1
- package/dist/bin/setup.js +141 -7
- package/dist/bin/shard-migrate.js +11 -0
- package/dist/bin/stack-update.js +24 -7
- package/dist/bin/update.js +5 -0
- package/dist/gateway/index.js +12 -1
- package/dist/hooks/bug-report-worker.js +12 -1
- package/dist/hooks/codex-stop-task-finalizer.js +12 -1
- package/dist/hooks/commit-complete.js +12 -1
- package/dist/hooks/error-recall.js +11 -0
- package/dist/hooks/ingest.js +11 -0
- package/dist/hooks/instructions-loaded.js +11 -0
- package/dist/hooks/notification.js +11 -0
- package/dist/hooks/post-compact.js +11 -0
- package/dist/hooks/post-tool-combined.js +11 -0
- package/dist/hooks/pre-compact.js +12 -1
- package/dist/hooks/pre-tool-use.js +11 -0
- package/dist/hooks/prompt-submit.js +12 -1
- package/dist/hooks/session-end.js +12 -1
- package/dist/hooks/session-start.js +11 -0
- package/dist/hooks/stop.js +11 -0
- package/dist/hooks/subagent-stop.js +11 -0
- package/dist/hooks/summary-worker.js +137 -3
- package/dist/index.js +12 -1
- package/dist/lib/cloud-sync.js +136 -2
- package/dist/lib/consolidation.js +1 -0
- package/dist/lib/database.js +11 -0
- package/dist/lib/db.js +11 -0
- package/dist/lib/device-registry.js +11 -0
- package/dist/lib/employee-templates.js +1 -0
- package/dist/lib/exe-daemon.js +771 -49
- package/dist/lib/hybrid-search.js +11 -0
- package/dist/lib/identity.js +1 -0
- package/dist/lib/messaging.js +2 -1
- package/dist/lib/reminders.js +1 -0
- package/dist/lib/schedules.js +11 -0
- package/dist/lib/skill-learning.js +1 -0
- package/dist/lib/store.js +11 -0
- package/dist/lib/tasks.js +2 -1
- package/dist/lib/tmux-routing.js +2 -1
- package/dist/lib/token-spend.js +1 -0
- package/dist/lib/ws-client.js +8 -0
- package/dist/mcp/server.js +613 -27
- package/dist/mcp/tools/complete-reminder.js +1 -0
- package/dist/mcp/tools/create-reminder.js +1 -0
- package/dist/mcp/tools/create-task.js +2 -1
- package/dist/mcp/tools/deactivate-behavior.js +1 -0
- package/dist/mcp/tools/list-reminders.js +1 -0
- package/dist/mcp/tools/list-tasks.js +1 -0
- package/dist/mcp/tools/send-message.js +2 -1
- package/dist/mcp/tools/update-task.js +2 -1
- package/dist/runtime/index.js +12 -1
- package/dist/tui/App.js +12 -1
- package/package.json +2 -2
package/dist/bin/exe-agent.js
CHANGED
|
@@ -1271,6 +1271,7 @@ var OllamaProvider = class {
|
|
|
1271
1271
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
1272
1272
|
|
|
1273
1273
|
// src/lib/database.ts
|
|
1274
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
1274
1275
|
import { createClient } from "@libsql/client";
|
|
1275
1276
|
|
|
1276
1277
|
// src/lib/employees.ts
|
package/dist/bin/exe-assign.js
CHANGED
|
@@ -1637,6 +1637,7 @@ __export(database_exports, {
|
|
|
1637
1637
|
isInitialized: () => isInitialized,
|
|
1638
1638
|
setExternalClient: () => setExternalClient
|
|
1639
1639
|
});
|
|
1640
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
1640
1641
|
import { createClient } from "@libsql/client";
|
|
1641
1642
|
async function initDatabase(config) {
|
|
1642
1643
|
if (_walCheckpointTimer) {
|
|
@@ -1678,6 +1679,16 @@ async function initDatabase(config) {
|
|
|
1678
1679
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
1679
1680
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
1680
1681
|
}
|
|
1682
|
+
try {
|
|
1683
|
+
chmodSync2(config.dbPath, 384);
|
|
1684
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
1685
|
+
try {
|
|
1686
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
1687
|
+
} catch {
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
} catch {
|
|
1691
|
+
}
|
|
1681
1692
|
}
|
|
1682
1693
|
function isInitialized() {
|
|
1683
1694
|
return _adapterClient !== null || _client !== null;
|
|
@@ -5366,6 +5377,7 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
5366
5377
|
function isMainModule(importMetaUrl) {
|
|
5367
5378
|
if (process.argv[1] == null) return false;
|
|
5368
5379
|
if (process.argv[1].includes("mcp/server")) return false;
|
|
5380
|
+
if (process.argv[1].includes("exe-daemon")) return false;
|
|
5369
5381
|
try {
|
|
5370
5382
|
const scriptPath = realpathSync(process.argv[1]);
|
|
5371
5383
|
const modulePath = realpathSync(fileURLToPath2(importMetaUrl));
|
package/dist/bin/exe-boot.js
CHANGED
|
@@ -1789,6 +1789,7 @@ __export(database_exports, {
|
|
|
1789
1789
|
isInitialized: () => isInitialized,
|
|
1790
1790
|
setExternalClient: () => setExternalClient
|
|
1791
1791
|
});
|
|
1792
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
1792
1793
|
import { createClient } from "@libsql/client";
|
|
1793
1794
|
async function initDatabase(config) {
|
|
1794
1795
|
if (_walCheckpointTimer) {
|
|
@@ -1830,6 +1831,16 @@ async function initDatabase(config) {
|
|
|
1830
1831
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
1831
1832
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
1832
1833
|
}
|
|
1834
|
+
try {
|
|
1835
|
+
chmodSync2(config.dbPath, 384);
|
|
1836
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
1837
|
+
try {
|
|
1838
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
1839
|
+
} catch {
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
} catch {
|
|
1843
|
+
}
|
|
1833
1844
|
}
|
|
1834
1845
|
function isInitialized() {
|
|
1835
1846
|
return _adapterClient !== null || _client !== null;
|
|
@@ -4947,7 +4958,7 @@ function readQueue() {
|
|
|
4947
4958
|
function writeQueue(queue) {
|
|
4948
4959
|
ensureDir();
|
|
4949
4960
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
4950
|
-
writeFileSync5(tmp, JSON.stringify(queue, null, 2));
|
|
4961
|
+
writeFileSync5(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
|
|
4951
4962
|
renameSync4(tmp, QUEUE_PATH);
|
|
4952
4963
|
}
|
|
4953
4964
|
function queueIntercom(targetSession, reason) {
|
|
@@ -9303,6 +9314,21 @@ var init_crdt_sync = __esm({
|
|
|
9303
9314
|
}
|
|
9304
9315
|
});
|
|
9305
9316
|
|
|
9317
|
+
// src/lib/pg-ssl.ts
|
|
9318
|
+
var pg_ssl_exports = {};
|
|
9319
|
+
__export(pg_ssl_exports, {
|
|
9320
|
+
pgSslConfig: () => pgSslConfig
|
|
9321
|
+
});
|
|
9322
|
+
function pgSslConfig() {
|
|
9323
|
+
if (process.env.EXE_DB_SSL_DISABLED === "true") return {};
|
|
9324
|
+
return { ssl: { rejectUnauthorized: process.env.EXE_DB_SSL_ALLOW_SELFSIGNED !== "true" } };
|
|
9325
|
+
}
|
|
9326
|
+
var init_pg_ssl = __esm({
|
|
9327
|
+
"src/lib/pg-ssl.ts"() {
|
|
9328
|
+
"use strict";
|
|
9329
|
+
}
|
|
9330
|
+
});
|
|
9331
|
+
|
|
9306
9332
|
// src/lib/db-backup.ts
|
|
9307
9333
|
var db_backup_exports = {};
|
|
9308
9334
|
__export(db_backup_exports, {
|
|
@@ -9416,6 +9442,7 @@ __export(cloud_sync_exports, {
|
|
|
9416
9442
|
cloudPull: () => cloudPull,
|
|
9417
9443
|
cloudPullBehaviors: () => cloudPullBehaviors,
|
|
9418
9444
|
cloudPullBlob: () => cloudPullBlob,
|
|
9445
|
+
cloudPullCodeContext: () => cloudPullCodeContext,
|
|
9419
9446
|
cloudPullConversations: () => cloudPullConversations,
|
|
9420
9447
|
cloudPullDocuments: () => cloudPullDocuments,
|
|
9421
9448
|
cloudPullGlobalProcedures: () => cloudPullGlobalProcedures,
|
|
@@ -9425,6 +9452,7 @@ __export(cloud_sync_exports, {
|
|
|
9425
9452
|
cloudPush: () => cloudPush,
|
|
9426
9453
|
cloudPushBehaviors: () => cloudPushBehaviors,
|
|
9427
9454
|
cloudPushBlob: () => cloudPushBlob,
|
|
9455
|
+
cloudPushCodeContext: () => cloudPushCodeContext,
|
|
9428
9456
|
cloudPushConversations: () => cloudPushConversations,
|
|
9429
9457
|
cloudPushDocuments: () => cloudPushDocuments,
|
|
9430
9458
|
cloudPushGlobalProcedures: () => cloudPushGlobalProcedures,
|
|
@@ -9503,7 +9531,8 @@ function loadPgClient() {
|
|
|
9503
9531
|
return new Ctor();
|
|
9504
9532
|
}
|
|
9505
9533
|
const { Pool } = await import("pg");
|
|
9506
|
-
const
|
|
9534
|
+
const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
|
|
9535
|
+
const pool = new Pool({ connectionString: process.env.DATABASE_URL, ...pgSslConfig2() });
|
|
9507
9536
|
return {
|
|
9508
9537
|
async $queryRawUnsafe(query, ...values) {
|
|
9509
9538
|
const result = await pool.query(query, values);
|
|
@@ -10048,6 +10077,17 @@ async function cloudSync(config) {
|
|
|
10048
10077
|
} catch (err) {
|
|
10049
10078
|
logError(`[cloud-sync] DB backup upload error: ${err instanceof Error ? err.message : String(err)}`);
|
|
10050
10079
|
}
|
|
10080
|
+
let codeContextResult = { pushed: 0, pulled: 0 };
|
|
10081
|
+
try {
|
|
10082
|
+
codeContextResult.pushed = await cloudPushCodeContext(config);
|
|
10083
|
+
} catch (err) {
|
|
10084
|
+
logError(`[cloud-sync] Code context push: ${err instanceof Error ? err.message : String(err)}`);
|
|
10085
|
+
}
|
|
10086
|
+
try {
|
|
10087
|
+
codeContextResult.pulled = await cloudPullCodeContext(config);
|
|
10088
|
+
} catch (err) {
|
|
10089
|
+
logError(`[cloud-sync] Code context pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
10090
|
+
}
|
|
10051
10091
|
return {
|
|
10052
10092
|
pushed,
|
|
10053
10093
|
pulled,
|
|
@@ -10057,7 +10097,8 @@ async function cloudSync(config) {
|
|
|
10057
10097
|
tasks: tasksResult,
|
|
10058
10098
|
conversations: conversationsResult,
|
|
10059
10099
|
documents: documentsResult,
|
|
10060
|
-
roster: rosterResult
|
|
10100
|
+
roster: rosterResult,
|
|
10101
|
+
codeContext: codeContextResult
|
|
10061
10102
|
};
|
|
10062
10103
|
}
|
|
10063
10104
|
function recordRosterDeletion(name) {
|
|
@@ -10695,7 +10736,99 @@ async function cloudPullDocuments(config) {
|
|
|
10695
10736
|
}
|
|
10696
10737
|
return { pulled };
|
|
10697
10738
|
}
|
|
10698
|
-
|
|
10739
|
+
async function cloudPushCodeContext(config) {
|
|
10740
|
+
assertSecureEndpoint(config.endpoint);
|
|
10741
|
+
if (!existsSync21(CODE_CONTEXT_DIR)) return 0;
|
|
10742
|
+
const files = readdirSync8(CODE_CONTEXT_DIR).filter(
|
|
10743
|
+
(f) => f.endsWith(".json") && !f.endsWith(".vectors.json") && !f.startsWith(".")
|
|
10744
|
+
);
|
|
10745
|
+
if (files.length === 0) return 0;
|
|
10746
|
+
const metaPath = path25.join(CODE_CONTEXT_DIR, ".sync-meta.json");
|
|
10747
|
+
let syncMeta = {};
|
|
10748
|
+
if (existsSync21(metaPath)) {
|
|
10749
|
+
try {
|
|
10750
|
+
syncMeta = JSON.parse(readFileSync15(metaPath, "utf-8"));
|
|
10751
|
+
} catch {
|
|
10752
|
+
}
|
|
10753
|
+
}
|
|
10754
|
+
let pushed = 0;
|
|
10755
|
+
for (const file of files) {
|
|
10756
|
+
const filePath = path25.join(CODE_CONTEXT_DIR, file);
|
|
10757
|
+
try {
|
|
10758
|
+
const stat = statSync5(filePath);
|
|
10759
|
+
const lastPushed = syncMeta[file] ?? 0;
|
|
10760
|
+
if (stat.mtimeMs <= lastPushed) continue;
|
|
10761
|
+
const content = readFileSync15(filePath, "utf-8");
|
|
10762
|
+
const header = content.substring(0, 300);
|
|
10763
|
+
if (header.includes("/tmp") || header.includes("/var/folders") || header.includes(".worktrees/")) continue;
|
|
10764
|
+
const compressed = compress(Buffer.from(content, "utf8"));
|
|
10765
|
+
const encrypted = encryptSyncBlob(compressed);
|
|
10766
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/push-code-context`, {
|
|
10767
|
+
method: "POST",
|
|
10768
|
+
headers: {
|
|
10769
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
10770
|
+
"Content-Type": "application/json",
|
|
10771
|
+
"X-Device-Id": loadDeviceId()
|
|
10772
|
+
},
|
|
10773
|
+
body: JSON.stringify({ key: file, blob: encrypted })
|
|
10774
|
+
});
|
|
10775
|
+
if (resp.ok) {
|
|
10776
|
+
syncMeta[file] = stat.mtimeMs;
|
|
10777
|
+
pushed++;
|
|
10778
|
+
}
|
|
10779
|
+
} catch {
|
|
10780
|
+
}
|
|
10781
|
+
}
|
|
10782
|
+
if (pushed > 0) {
|
|
10783
|
+
try {
|
|
10784
|
+
writeFileSync12(metaPath, JSON.stringify(syncMeta));
|
|
10785
|
+
} catch {
|
|
10786
|
+
}
|
|
10787
|
+
}
|
|
10788
|
+
return pushed;
|
|
10789
|
+
}
|
|
10790
|
+
async function cloudPullCodeContext(config) {
|
|
10791
|
+
assertSecureEndpoint(config.endpoint);
|
|
10792
|
+
try {
|
|
10793
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/pull-code-context`, {
|
|
10794
|
+
method: "GET",
|
|
10795
|
+
headers: {
|
|
10796
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
10797
|
+
"X-Device-Id": loadDeviceId()
|
|
10798
|
+
}
|
|
10799
|
+
});
|
|
10800
|
+
if (!resp.ok) return 0;
|
|
10801
|
+
const data = await resp.json();
|
|
10802
|
+
if (!data.indexes || data.indexes.length === 0) return 0;
|
|
10803
|
+
mkdirSync13(CODE_CONTEXT_DIR, { recursive: true });
|
|
10804
|
+
let pulled = 0;
|
|
10805
|
+
for (const { key, blob } of data.indexes) {
|
|
10806
|
+
try {
|
|
10807
|
+
if (key.endsWith(".vectors.json")) continue;
|
|
10808
|
+
const localPath = path25.join(CODE_CONTEXT_DIR, key);
|
|
10809
|
+
const compressed = decryptSyncBlob(blob);
|
|
10810
|
+
const content = decompress(compressed).toString("utf8");
|
|
10811
|
+
if (!existsSync21(localPath)) {
|
|
10812
|
+
writeFileSync12(localPath, content, "utf-8");
|
|
10813
|
+
pulled++;
|
|
10814
|
+
} else {
|
|
10815
|
+
const localContent = readFileSync15(localPath, "utf-8");
|
|
10816
|
+
if (localContent.length !== content.length) {
|
|
10817
|
+
writeFileSync12(localPath, content, "utf-8");
|
|
10818
|
+
pulled++;
|
|
10819
|
+
}
|
|
10820
|
+
}
|
|
10821
|
+
} catch {
|
|
10822
|
+
}
|
|
10823
|
+
}
|
|
10824
|
+
return pulled;
|
|
10825
|
+
} catch (err) {
|
|
10826
|
+
process.stderr.write(`[cloud-sync] Code context pull failed: ${err instanceof Error ? err.message : String(err)}
|
|
10827
|
+
`);
|
|
10828
|
+
return 0;
|
|
10829
|
+
}
|
|
10830
|
+
}
|
|
10831
|
+
var LOCALHOST_PATTERNS, FETCH_TIMEOUT_MS, PUSH_BATCH_SIZE, ROSTER_LOCK_PATH, LOCK_STALE_MS, _pgPromise, _pgFailed, CLOUD_REUPLOAD_REQUIRED_MESSAGE, ROSTER_DELETIONS_PATH, CODE_CONTEXT_DIR;
|
|
10699
10832
|
var init_cloud_sync = __esm({
|
|
10700
10833
|
"src/lib/cloud-sync.ts"() {
|
|
10701
10834
|
"use strict";
|
|
@@ -10716,6 +10849,7 @@ var init_cloud_sync = __esm({
|
|
|
10716
10849
|
_pgFailed = false;
|
|
10717
10850
|
CLOUD_REUPLOAD_REQUIRED_MESSAGE = "Cloud sync is blocked because this device rotated its memory encryption key. Run `exe-os cloud reupload` first to re-upload the cloud backup with the new key.";
|
|
10718
10851
|
ROSTER_DELETIONS_PATH = path25.join(EXE_AI_DIR, "roster-deletions.json");
|
|
10852
|
+
CODE_CONTEXT_DIR = path25.join(EXE_AI_DIR, "code-context");
|
|
10719
10853
|
}
|
|
10720
10854
|
});
|
|
10721
10855
|
|
|
@@ -11448,6 +11582,7 @@ import { fileURLToPath as fileURLToPath3 } from "url";
|
|
|
11448
11582
|
function isMainModule(importMetaUrl) {
|
|
11449
11583
|
if (process.argv[1] == null) return false;
|
|
11450
11584
|
if (process.argv[1].includes("mcp/server")) return false;
|
|
11585
|
+
if (process.argv[1].includes("exe-daemon")) return false;
|
|
11451
11586
|
try {
|
|
11452
11587
|
const scriptPath = realpathSync(process.argv[1]);
|
|
11453
11588
|
const modulePath = realpathSync(fileURLToPath3(importMetaUrl));
|
package/dist/bin/exe-call.js
CHANGED
|
@@ -221,6 +221,7 @@ var init_memory = __esm({
|
|
|
221
221
|
});
|
|
222
222
|
|
|
223
223
|
// src/lib/database.ts
|
|
224
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
224
225
|
import { createClient } from "@libsql/client";
|
|
225
226
|
var init_database = __esm({
|
|
226
227
|
"src/lib/database.ts"() {
|
|
@@ -1253,6 +1254,7 @@ import { fileURLToPath } from "url";
|
|
|
1253
1254
|
function isMainModule(importMetaUrl) {
|
|
1254
1255
|
if (process.argv[1] == null) return false;
|
|
1255
1256
|
if (process.argv[1].includes("mcp/server")) return false;
|
|
1257
|
+
if (process.argv[1].includes("exe-daemon")) return false;
|
|
1256
1258
|
try {
|
|
1257
1259
|
const scriptPath = realpathSync(process.argv[1]);
|
|
1258
1260
|
const modulePath = realpathSync(fileURLToPath(importMetaUrl));
|
package/dist/bin/exe-cloud.js
CHANGED
|
@@ -2206,6 +2206,7 @@ __export(database_exports, {
|
|
|
2206
2206
|
isInitialized: () => isInitialized,
|
|
2207
2207
|
setExternalClient: () => setExternalClient
|
|
2208
2208
|
});
|
|
2209
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2209
2210
|
import { createClient } from "@libsql/client";
|
|
2210
2211
|
async function initDatabase(config) {
|
|
2211
2212
|
if (_walCheckpointTimer) {
|
|
@@ -2247,6 +2248,16 @@ async function initDatabase(config) {
|
|
|
2247
2248
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2248
2249
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2249
2250
|
}
|
|
2251
|
+
try {
|
|
2252
|
+
chmodSync2(config.dbPath, 384);
|
|
2253
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2254
|
+
try {
|
|
2255
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
2256
|
+
} catch {
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
} catch {
|
|
2260
|
+
}
|
|
2250
2261
|
}
|
|
2251
2262
|
function isInitialized() {
|
|
2252
2263
|
return _adapterClient !== null || _client !== null;
|
|
@@ -4375,6 +4386,21 @@ var init_crdt_sync = __esm({
|
|
|
4375
4386
|
}
|
|
4376
4387
|
});
|
|
4377
4388
|
|
|
4389
|
+
// src/lib/pg-ssl.ts
|
|
4390
|
+
var pg_ssl_exports = {};
|
|
4391
|
+
__export(pg_ssl_exports, {
|
|
4392
|
+
pgSslConfig: () => pgSslConfig
|
|
4393
|
+
});
|
|
4394
|
+
function pgSslConfig() {
|
|
4395
|
+
if (process.env.EXE_DB_SSL_DISABLED === "true") return {};
|
|
4396
|
+
return { ssl: { rejectUnauthorized: process.env.EXE_DB_SSL_ALLOW_SELFSIGNED !== "true" } };
|
|
4397
|
+
}
|
|
4398
|
+
var init_pg_ssl = __esm({
|
|
4399
|
+
"src/lib/pg-ssl.ts"() {
|
|
4400
|
+
"use strict";
|
|
4401
|
+
}
|
|
4402
|
+
});
|
|
4403
|
+
|
|
4378
4404
|
// src/lib/db-backup.ts
|
|
4379
4405
|
var db_backup_exports = {};
|
|
4380
4406
|
__export(db_backup_exports, {
|
|
@@ -4488,6 +4514,7 @@ __export(cloud_sync_exports, {
|
|
|
4488
4514
|
cloudPull: () => cloudPull,
|
|
4489
4515
|
cloudPullBehaviors: () => cloudPullBehaviors,
|
|
4490
4516
|
cloudPullBlob: () => cloudPullBlob,
|
|
4517
|
+
cloudPullCodeContext: () => cloudPullCodeContext,
|
|
4491
4518
|
cloudPullConversations: () => cloudPullConversations,
|
|
4492
4519
|
cloudPullDocuments: () => cloudPullDocuments,
|
|
4493
4520
|
cloudPullGlobalProcedures: () => cloudPullGlobalProcedures,
|
|
@@ -4497,6 +4524,7 @@ __export(cloud_sync_exports, {
|
|
|
4497
4524
|
cloudPush: () => cloudPush,
|
|
4498
4525
|
cloudPushBehaviors: () => cloudPushBehaviors,
|
|
4499
4526
|
cloudPushBlob: () => cloudPushBlob,
|
|
4527
|
+
cloudPushCodeContext: () => cloudPushCodeContext,
|
|
4500
4528
|
cloudPushConversations: () => cloudPushConversations,
|
|
4501
4529
|
cloudPushDocuments: () => cloudPushDocuments,
|
|
4502
4530
|
cloudPushGlobalProcedures: () => cloudPushGlobalProcedures,
|
|
@@ -4575,7 +4603,8 @@ function loadPgClient() {
|
|
|
4575
4603
|
return new Ctor();
|
|
4576
4604
|
}
|
|
4577
4605
|
const { Pool } = await import("pg");
|
|
4578
|
-
const
|
|
4606
|
+
const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
|
|
4607
|
+
const pool = new Pool({ connectionString: process.env.DATABASE_URL, ...pgSslConfig2() });
|
|
4579
4608
|
return {
|
|
4580
4609
|
async $queryRawUnsafe(query, ...values) {
|
|
4581
4610
|
const result = await pool.query(query, values);
|
|
@@ -5120,6 +5149,17 @@ async function cloudSync(config) {
|
|
|
5120
5149
|
} catch (err) {
|
|
5121
5150
|
logError(`[cloud-sync] DB backup upload error: ${err instanceof Error ? err.message : String(err)}`);
|
|
5122
5151
|
}
|
|
5152
|
+
let codeContextResult = { pushed: 0, pulled: 0 };
|
|
5153
|
+
try {
|
|
5154
|
+
codeContextResult.pushed = await cloudPushCodeContext(config);
|
|
5155
|
+
} catch (err) {
|
|
5156
|
+
logError(`[cloud-sync] Code context push: ${err instanceof Error ? err.message : String(err)}`);
|
|
5157
|
+
}
|
|
5158
|
+
try {
|
|
5159
|
+
codeContextResult.pulled = await cloudPullCodeContext(config);
|
|
5160
|
+
} catch (err) {
|
|
5161
|
+
logError(`[cloud-sync] Code context pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
5162
|
+
}
|
|
5123
5163
|
return {
|
|
5124
5164
|
pushed,
|
|
5125
5165
|
pulled,
|
|
@@ -5129,7 +5169,8 @@ async function cloudSync(config) {
|
|
|
5129
5169
|
tasks: tasksResult,
|
|
5130
5170
|
conversations: conversationsResult,
|
|
5131
5171
|
documents: documentsResult,
|
|
5132
|
-
roster: rosterResult
|
|
5172
|
+
roster: rosterResult,
|
|
5173
|
+
codeContext: codeContextResult
|
|
5133
5174
|
};
|
|
5134
5175
|
}
|
|
5135
5176
|
function recordRosterDeletion(name) {
|
|
@@ -5767,7 +5808,99 @@ async function cloudPullDocuments(config) {
|
|
|
5767
5808
|
}
|
|
5768
5809
|
return { pulled };
|
|
5769
5810
|
}
|
|
5770
|
-
|
|
5811
|
+
async function cloudPushCodeContext(config) {
|
|
5812
|
+
assertSecureEndpoint(config.endpoint);
|
|
5813
|
+
if (!existsSync10(CODE_CONTEXT_DIR)) return 0;
|
|
5814
|
+
const files = readdirSync2(CODE_CONTEXT_DIR).filter(
|
|
5815
|
+
(f) => f.endsWith(".json") && !f.endsWith(".vectors.json") && !f.startsWith(".")
|
|
5816
|
+
);
|
|
5817
|
+
if (files.length === 0) return 0;
|
|
5818
|
+
const metaPath = path10.join(CODE_CONTEXT_DIR, ".sync-meta.json");
|
|
5819
|
+
let syncMeta = {};
|
|
5820
|
+
if (existsSync10(metaPath)) {
|
|
5821
|
+
try {
|
|
5822
|
+
syncMeta = JSON.parse(readFileSync7(metaPath, "utf-8"));
|
|
5823
|
+
} catch {
|
|
5824
|
+
}
|
|
5825
|
+
}
|
|
5826
|
+
let pushed = 0;
|
|
5827
|
+
for (const file of files) {
|
|
5828
|
+
const filePath = path10.join(CODE_CONTEXT_DIR, file);
|
|
5829
|
+
try {
|
|
5830
|
+
const stat = statSync4(filePath);
|
|
5831
|
+
const lastPushed = syncMeta[file] ?? 0;
|
|
5832
|
+
if (stat.mtimeMs <= lastPushed) continue;
|
|
5833
|
+
const content = readFileSync7(filePath, "utf-8");
|
|
5834
|
+
const header = content.substring(0, 300);
|
|
5835
|
+
if (header.includes("/tmp") || header.includes("/var/folders") || header.includes(".worktrees/")) continue;
|
|
5836
|
+
const compressed = compress(Buffer.from(content, "utf8"));
|
|
5837
|
+
const encrypted = encryptSyncBlob(compressed);
|
|
5838
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/push-code-context`, {
|
|
5839
|
+
method: "POST",
|
|
5840
|
+
headers: {
|
|
5841
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
5842
|
+
"Content-Type": "application/json",
|
|
5843
|
+
"X-Device-Id": loadDeviceId()
|
|
5844
|
+
},
|
|
5845
|
+
body: JSON.stringify({ key: file, blob: encrypted })
|
|
5846
|
+
});
|
|
5847
|
+
if (resp.ok) {
|
|
5848
|
+
syncMeta[file] = stat.mtimeMs;
|
|
5849
|
+
pushed++;
|
|
5850
|
+
}
|
|
5851
|
+
} catch {
|
|
5852
|
+
}
|
|
5853
|
+
}
|
|
5854
|
+
if (pushed > 0) {
|
|
5855
|
+
try {
|
|
5856
|
+
writeFileSync5(metaPath, JSON.stringify(syncMeta));
|
|
5857
|
+
} catch {
|
|
5858
|
+
}
|
|
5859
|
+
}
|
|
5860
|
+
return pushed;
|
|
5861
|
+
}
|
|
5862
|
+
async function cloudPullCodeContext(config) {
|
|
5863
|
+
assertSecureEndpoint(config.endpoint);
|
|
5864
|
+
try {
|
|
5865
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/pull-code-context`, {
|
|
5866
|
+
method: "GET",
|
|
5867
|
+
headers: {
|
|
5868
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
5869
|
+
"X-Device-Id": loadDeviceId()
|
|
5870
|
+
}
|
|
5871
|
+
});
|
|
5872
|
+
if (!resp.ok) return 0;
|
|
5873
|
+
const data = await resp.json();
|
|
5874
|
+
if (!data.indexes || data.indexes.length === 0) return 0;
|
|
5875
|
+
mkdirSync5(CODE_CONTEXT_DIR, { recursive: true });
|
|
5876
|
+
let pulled = 0;
|
|
5877
|
+
for (const { key, blob } of data.indexes) {
|
|
5878
|
+
try {
|
|
5879
|
+
if (key.endsWith(".vectors.json")) continue;
|
|
5880
|
+
const localPath = path10.join(CODE_CONTEXT_DIR, key);
|
|
5881
|
+
const compressed = decryptSyncBlob(blob);
|
|
5882
|
+
const content = decompress(compressed).toString("utf8");
|
|
5883
|
+
if (!existsSync10(localPath)) {
|
|
5884
|
+
writeFileSync5(localPath, content, "utf-8");
|
|
5885
|
+
pulled++;
|
|
5886
|
+
} else {
|
|
5887
|
+
const localContent = readFileSync7(localPath, "utf-8");
|
|
5888
|
+
if (localContent.length !== content.length) {
|
|
5889
|
+
writeFileSync5(localPath, content, "utf-8");
|
|
5890
|
+
pulled++;
|
|
5891
|
+
}
|
|
5892
|
+
}
|
|
5893
|
+
} catch {
|
|
5894
|
+
}
|
|
5895
|
+
}
|
|
5896
|
+
return pulled;
|
|
5897
|
+
} catch (err) {
|
|
5898
|
+
process.stderr.write(`[cloud-sync] Code context pull failed: ${err instanceof Error ? err.message : String(err)}
|
|
5899
|
+
`);
|
|
5900
|
+
return 0;
|
|
5901
|
+
}
|
|
5902
|
+
}
|
|
5903
|
+
var LOCALHOST_PATTERNS, FETCH_TIMEOUT_MS, PUSH_BATCH_SIZE, ROSTER_LOCK_PATH, LOCK_STALE_MS, _pgPromise, _pgFailed, CLOUD_REUPLOAD_REQUIRED_MESSAGE, ROSTER_DELETIONS_PATH, CODE_CONTEXT_DIR;
|
|
5771
5904
|
var init_cloud_sync = __esm({
|
|
5772
5905
|
"src/lib/cloud-sync.ts"() {
|
|
5773
5906
|
"use strict";
|
|
@@ -5788,6 +5921,7 @@ var init_cloud_sync = __esm({
|
|
|
5788
5921
|
_pgFailed = false;
|
|
5789
5922
|
CLOUD_REUPLOAD_REQUIRED_MESSAGE = "Cloud sync is blocked because this device rotated its memory encryption key. Run `exe-os cloud reupload` first to re-upload the cloud backup with the new key.";
|
|
5790
5923
|
ROSTER_DELETIONS_PATH = path10.join(EXE_AI_DIR, "roster-deletions.json");
|
|
5924
|
+
CODE_CONTEXT_DIR = path10.join(EXE_AI_DIR, "code-context");
|
|
5791
5925
|
}
|
|
5792
5926
|
});
|
|
5793
5927
|
|
|
@@ -7862,6 +7996,7 @@ import { fileURLToPath } from "url";
|
|
|
7862
7996
|
function isMainModule(importMetaUrl) {
|
|
7863
7997
|
if (process.argv[1] == null) return false;
|
|
7864
7998
|
if (process.argv[1].includes("mcp/server")) return false;
|
|
7999
|
+
if (process.argv[1].includes("exe-daemon")) return false;
|
|
7865
8000
|
try {
|
|
7866
8001
|
const scriptPath = realpathSync(process.argv[1]);
|
|
7867
8002
|
const modulePath = realpathSync(fileURLToPath(importMetaUrl));
|
package/dist/bin/exe-dispatch.js
CHANGED
|
@@ -712,7 +712,7 @@ function readQueue() {
|
|
|
712
712
|
function writeQueue(queue) {
|
|
713
713
|
ensureDir();
|
|
714
714
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
715
|
-
writeFileSync3(tmp, JSON.stringify(queue, null, 2));
|
|
715
|
+
writeFileSync3(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
|
|
716
716
|
renameSync2(tmp, QUEUE_PATH);
|
|
717
717
|
}
|
|
718
718
|
function queueIntercom(targetSession, reason) {
|
|
@@ -2291,6 +2291,7 @@ __export(database_exports, {
|
|
|
2291
2291
|
isInitialized: () => isInitialized,
|
|
2292
2292
|
setExternalClient: () => setExternalClient
|
|
2293
2293
|
});
|
|
2294
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2294
2295
|
import { createClient } from "@libsql/client";
|
|
2295
2296
|
async function initDatabase(config) {
|
|
2296
2297
|
if (_walCheckpointTimer) {
|
|
@@ -2332,6 +2333,16 @@ async function initDatabase(config) {
|
|
|
2332
2333
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2333
2334
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2334
2335
|
}
|
|
2336
|
+
try {
|
|
2337
|
+
chmodSync2(config.dbPath, 384);
|
|
2338
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2339
|
+
try {
|
|
2340
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
2341
|
+
} catch {
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
} catch {
|
|
2345
|
+
}
|
|
2335
2346
|
}
|
|
2336
2347
|
function isInitialized() {
|
|
2337
2348
|
return _adapterClient !== null || _client !== null;
|
package/dist/bin/exe-doctor.js
CHANGED
|
@@ -2745,6 +2745,7 @@ __export(database_exports, {
|
|
|
2745
2745
|
isInitialized: () => isInitialized,
|
|
2746
2746
|
setExternalClient: () => setExternalClient
|
|
2747
2747
|
});
|
|
2748
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2748
2749
|
import { createClient as createClient2 } from "@libsql/client";
|
|
2749
2750
|
async function initDatabase(config) {
|
|
2750
2751
|
if (_walCheckpointTimer) {
|
|
@@ -2786,6 +2787,16 @@ async function initDatabase(config) {
|
|
|
2786
2787
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2787
2788
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2788
2789
|
}
|
|
2790
|
+
try {
|
|
2791
|
+
chmodSync2(config.dbPath, 384);
|
|
2792
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2793
|
+
try {
|
|
2794
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
2795
|
+
} catch {
|
|
2796
|
+
}
|
|
2797
|
+
}
|
|
2798
|
+
} catch {
|
|
2799
|
+
}
|
|
2789
2800
|
}
|
|
2790
2801
|
function isInitialized() {
|
|
2791
2802
|
return _adapterClient !== null || _client !== null;
|
|
@@ -5915,6 +5926,7 @@ import { fileURLToPath } from "url";
|
|
|
5915
5926
|
function isMainModule(importMetaUrl) {
|
|
5916
5927
|
if (process.argv[1] == null) return false;
|
|
5917
5928
|
if (process.argv[1].includes("mcp/server")) return false;
|
|
5929
|
+
if (process.argv[1].includes("exe-daemon")) return false;
|
|
5918
5930
|
try {
|
|
5919
5931
|
const scriptPath = realpathSync(process.argv[1]);
|
|
5920
5932
|
const modulePath = realpathSync(fileURLToPath(importMetaUrl));
|
|
@@ -1778,6 +1778,7 @@ __export(database_exports, {
|
|
|
1778
1778
|
isInitialized: () => isInitialized,
|
|
1779
1779
|
setExternalClient: () => setExternalClient
|
|
1780
1780
|
});
|
|
1781
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
1781
1782
|
import { createClient } from "@libsql/client";
|
|
1782
1783
|
async function initDatabase(config) {
|
|
1783
1784
|
if (_walCheckpointTimer) {
|
|
@@ -1819,6 +1820,16 @@ async function initDatabase(config) {
|
|
|
1819
1820
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
1820
1821
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
1821
1822
|
}
|
|
1823
|
+
try {
|
|
1824
|
+
chmodSync2(config.dbPath, 384);
|
|
1825
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
1826
|
+
try {
|
|
1827
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
1828
|
+
} catch {
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
} catch {
|
|
1832
|
+
}
|
|
1822
1833
|
}
|
|
1823
1834
|
function isInitialized() {
|
|
1824
1835
|
return _adapterClient !== null || _client !== null;
|
package/dist/bin/exe-forget.js
CHANGED
|
@@ -1702,6 +1702,7 @@ __export(database_exports, {
|
|
|
1702
1702
|
isInitialized: () => isInitialized,
|
|
1703
1703
|
setExternalClient: () => setExternalClient
|
|
1704
1704
|
});
|
|
1705
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
1705
1706
|
import { createClient } from "@libsql/client";
|
|
1706
1707
|
async function initDatabase(config) {
|
|
1707
1708
|
if (_walCheckpointTimer) {
|
|
@@ -1743,6 +1744,16 @@ async function initDatabase(config) {
|
|
|
1743
1744
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
1744
1745
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
1745
1746
|
}
|
|
1747
|
+
try {
|
|
1748
|
+
chmodSync2(config.dbPath, 384);
|
|
1749
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
1750
|
+
try {
|
|
1751
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
1752
|
+
} catch {
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
} catch {
|
|
1756
|
+
}
|
|
1746
1757
|
}
|
|
1747
1758
|
function isInitialized() {
|
|
1748
1759
|
return _adapterClient !== null || _client !== null;
|
|
@@ -5782,6 +5793,7 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
5782
5793
|
function isMainModule(importMetaUrl) {
|
|
5783
5794
|
if (process.argv[1] == null) return false;
|
|
5784
5795
|
if (process.argv[1].includes("mcp/server")) return false;
|
|
5796
|
+
if (process.argv[1].includes("exe-daemon")) return false;
|
|
5785
5797
|
try {
|
|
5786
5798
|
const scriptPath = realpathSync(process.argv[1]);
|
|
5787
5799
|
const modulePath = realpathSync(fileURLToPath2(importMetaUrl));
|