@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
|
@@ -2286,6 +2286,7 @@ __export(database_exports, {
|
|
|
2286
2286
|
isInitialized: () => isInitialized,
|
|
2287
2287
|
setExternalClient: () => setExternalClient
|
|
2288
2288
|
});
|
|
2289
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2289
2290
|
import { createClient } from "@libsql/client";
|
|
2290
2291
|
async function initDatabase(config) {
|
|
2291
2292
|
if (_walCheckpointTimer) {
|
|
@@ -2327,6 +2328,16 @@ async function initDatabase(config) {
|
|
|
2327
2328
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2328
2329
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2329
2330
|
}
|
|
2331
|
+
try {
|
|
2332
|
+
chmodSync2(config.dbPath, 384);
|
|
2333
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2334
|
+
try {
|
|
2335
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
2336
|
+
} catch {
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
} catch {
|
|
2340
|
+
}
|
|
2330
2341
|
}
|
|
2331
2342
|
function isInitialized() {
|
|
2332
2343
|
return _adapterClient !== null || _client !== null;
|
|
@@ -2112,6 +2112,7 @@ __export(database_exports, {
|
|
|
2112
2112
|
isInitialized: () => isInitialized,
|
|
2113
2113
|
setExternalClient: () => setExternalClient
|
|
2114
2114
|
});
|
|
2115
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2115
2116
|
import { createClient } from "@libsql/client";
|
|
2116
2117
|
async function initDatabase(config) {
|
|
2117
2118
|
if (_walCheckpointTimer) {
|
|
@@ -2153,6 +2154,16 @@ async function initDatabase(config) {
|
|
|
2153
2154
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2154
2155
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2155
2156
|
}
|
|
2157
|
+
try {
|
|
2158
|
+
chmodSync2(config.dbPath, 384);
|
|
2159
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2160
|
+
try {
|
|
2161
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
2162
|
+
} catch {
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
} catch {
|
|
2166
|
+
}
|
|
2156
2167
|
}
|
|
2157
2168
|
function isInitialized() {
|
|
2158
2169
|
return _adapterClient !== null || _client !== null;
|
|
@@ -7323,7 +7334,7 @@ function readQueue() {
|
|
|
7323
7334
|
function writeQueue(queue) {
|
|
7324
7335
|
ensureDir();
|
|
7325
7336
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
7326
|
-
writeFileSync7(tmp, JSON.stringify(queue, null, 2));
|
|
7337
|
+
writeFileSync7(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
|
|
7327
7338
|
renameSync4(tmp, QUEUE_PATH);
|
|
7328
7339
|
}
|
|
7329
7340
|
function queueIntercom(targetSession, reason) {
|
|
@@ -785,7 +785,7 @@ function readQueue() {
|
|
|
785
785
|
function writeQueue(queue) {
|
|
786
786
|
ensureDir();
|
|
787
787
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
788
|
-
writeFileSync6(tmp, JSON.stringify(queue, null, 2));
|
|
788
|
+
writeFileSync6(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
|
|
789
789
|
renameSync3(tmp, QUEUE_PATH);
|
|
790
790
|
}
|
|
791
791
|
function queueIntercom(targetSession, reason) {
|
|
@@ -2293,6 +2293,7 @@ __export(database_exports, {
|
|
|
2293
2293
|
isInitialized: () => isInitialized,
|
|
2294
2294
|
setExternalClient: () => setExternalClient
|
|
2295
2295
|
});
|
|
2296
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2296
2297
|
import { createClient } from "@libsql/client";
|
|
2297
2298
|
async function initDatabase(config) {
|
|
2298
2299
|
if (_walCheckpointTimer) {
|
|
@@ -2334,6 +2335,16 @@ async function initDatabase(config) {
|
|
|
2334
2335
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2335
2336
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2336
2337
|
}
|
|
2338
|
+
try {
|
|
2339
|
+
chmodSync2(config.dbPath, 384);
|
|
2340
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2341
|
+
try {
|
|
2342
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
2343
|
+
} catch {
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
} catch {
|
|
2347
|
+
}
|
|
2337
2348
|
}
|
|
2338
2349
|
function isInitialized() {
|
|
2339
2350
|
return _adapterClient !== null || _client !== null;
|
|
@@ -2112,6 +2112,7 @@ __export(database_exports, {
|
|
|
2112
2112
|
isInitialized: () => isInitialized,
|
|
2113
2113
|
setExternalClient: () => setExternalClient
|
|
2114
2114
|
});
|
|
2115
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2115
2116
|
import { createClient } from "@libsql/client";
|
|
2116
2117
|
async function initDatabase(config) {
|
|
2117
2118
|
if (_walCheckpointTimer) {
|
|
@@ -2153,6 +2154,16 @@ async function initDatabase(config) {
|
|
|
2153
2154
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2154
2155
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2155
2156
|
}
|
|
2157
|
+
try {
|
|
2158
|
+
chmodSync2(config.dbPath, 384);
|
|
2159
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2160
|
+
try {
|
|
2161
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
2162
|
+
} catch {
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
} catch {
|
|
2166
|
+
}
|
|
2156
2167
|
}
|
|
2157
2168
|
function isInitialized() {
|
|
2158
2169
|
return _adapterClient !== null || _client !== null;
|
package/dist/hooks/stop.js
CHANGED
|
@@ -2034,6 +2034,7 @@ __export(database_exports, {
|
|
|
2034
2034
|
isInitialized: () => isInitialized,
|
|
2035
2035
|
setExternalClient: () => setExternalClient
|
|
2036
2036
|
});
|
|
2037
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2037
2038
|
import { createClient } from "@libsql/client";
|
|
2038
2039
|
async function initDatabase(config) {
|
|
2039
2040
|
if (_walCheckpointTimer) {
|
|
@@ -2075,6 +2076,16 @@ async function initDatabase(config) {
|
|
|
2075
2076
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2076
2077
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2077
2078
|
}
|
|
2079
|
+
try {
|
|
2080
|
+
chmodSync2(config.dbPath, 384);
|
|
2081
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2082
|
+
try {
|
|
2083
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
2084
|
+
} catch {
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
} catch {
|
|
2088
|
+
}
|
|
2078
2089
|
}
|
|
2079
2090
|
function isInitialized() {
|
|
2080
2091
|
return _adapterClient !== null || _client !== null;
|
|
@@ -2006,6 +2006,7 @@ __export(database_exports, {
|
|
|
2006
2006
|
isInitialized: () => isInitialized,
|
|
2007
2007
|
setExternalClient: () => setExternalClient
|
|
2008
2008
|
});
|
|
2009
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2009
2010
|
import { createClient } from "@libsql/client";
|
|
2010
2011
|
async function initDatabase(config) {
|
|
2011
2012
|
if (_walCheckpointTimer) {
|
|
@@ -2047,6 +2048,16 @@ async function initDatabase(config) {
|
|
|
2047
2048
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2048
2049
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2049
2050
|
}
|
|
2051
|
+
try {
|
|
2052
|
+
chmodSync2(config.dbPath, 384);
|
|
2053
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2054
|
+
try {
|
|
2055
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
2056
|
+
} catch {
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
2059
|
+
} catch {
|
|
2060
|
+
}
|
|
2050
2061
|
}
|
|
2051
2062
|
function isInitialized() {
|
|
2052
2063
|
return _adapterClient !== null || _client !== null;
|
|
@@ -1773,6 +1773,7 @@ __export(database_exports, {
|
|
|
1773
1773
|
isInitialized: () => isInitialized,
|
|
1774
1774
|
setExternalClient: () => setExternalClient
|
|
1775
1775
|
});
|
|
1776
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
1776
1777
|
import { createClient } from "@libsql/client";
|
|
1777
1778
|
async function initDatabase(config) {
|
|
1778
1779
|
if (_walCheckpointTimer) {
|
|
@@ -1814,6 +1815,16 @@ async function initDatabase(config) {
|
|
|
1814
1815
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
1815
1816
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
1816
1817
|
}
|
|
1818
|
+
try {
|
|
1819
|
+
chmodSync2(config.dbPath, 384);
|
|
1820
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
1821
|
+
try {
|
|
1822
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
1823
|
+
} catch {
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
} catch {
|
|
1827
|
+
}
|
|
1817
1828
|
}
|
|
1818
1829
|
function isInitialized() {
|
|
1819
1830
|
return _adapterClient !== null || _client !== null;
|
|
@@ -5921,6 +5932,21 @@ var init_crdt_sync = __esm({
|
|
|
5921
5932
|
}
|
|
5922
5933
|
});
|
|
5923
5934
|
|
|
5935
|
+
// src/lib/pg-ssl.ts
|
|
5936
|
+
var pg_ssl_exports = {};
|
|
5937
|
+
__export(pg_ssl_exports, {
|
|
5938
|
+
pgSslConfig: () => pgSslConfig
|
|
5939
|
+
});
|
|
5940
|
+
function pgSslConfig() {
|
|
5941
|
+
if (process.env.EXE_DB_SSL_DISABLED === "true") return {};
|
|
5942
|
+
return { ssl: { rejectUnauthorized: process.env.EXE_DB_SSL_ALLOW_SELFSIGNED !== "true" } };
|
|
5943
|
+
}
|
|
5944
|
+
var init_pg_ssl = __esm({
|
|
5945
|
+
"src/lib/pg-ssl.ts"() {
|
|
5946
|
+
"use strict";
|
|
5947
|
+
}
|
|
5948
|
+
});
|
|
5949
|
+
|
|
5924
5950
|
// src/lib/db-backup.ts
|
|
5925
5951
|
var db_backup_exports = {};
|
|
5926
5952
|
__export(db_backup_exports, {
|
|
@@ -6034,6 +6060,7 @@ __export(cloud_sync_exports, {
|
|
|
6034
6060
|
cloudPull: () => cloudPull,
|
|
6035
6061
|
cloudPullBehaviors: () => cloudPullBehaviors,
|
|
6036
6062
|
cloudPullBlob: () => cloudPullBlob,
|
|
6063
|
+
cloudPullCodeContext: () => cloudPullCodeContext,
|
|
6037
6064
|
cloudPullConversations: () => cloudPullConversations,
|
|
6038
6065
|
cloudPullDocuments: () => cloudPullDocuments,
|
|
6039
6066
|
cloudPullGlobalProcedures: () => cloudPullGlobalProcedures,
|
|
@@ -6043,6 +6070,7 @@ __export(cloud_sync_exports, {
|
|
|
6043
6070
|
cloudPush: () => cloudPush,
|
|
6044
6071
|
cloudPushBehaviors: () => cloudPushBehaviors,
|
|
6045
6072
|
cloudPushBlob: () => cloudPushBlob,
|
|
6073
|
+
cloudPushCodeContext: () => cloudPushCodeContext,
|
|
6046
6074
|
cloudPushConversations: () => cloudPushConversations,
|
|
6047
6075
|
cloudPushDocuments: () => cloudPushDocuments,
|
|
6048
6076
|
cloudPushGlobalProcedures: () => cloudPushGlobalProcedures,
|
|
@@ -6121,7 +6149,8 @@ function loadPgClient() {
|
|
|
6121
6149
|
return new Ctor();
|
|
6122
6150
|
}
|
|
6123
6151
|
const { Pool } = await import("pg");
|
|
6124
|
-
const
|
|
6152
|
+
const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
|
|
6153
|
+
const pool = new Pool({ connectionString: process.env.DATABASE_URL, ...pgSslConfig2() });
|
|
6125
6154
|
return {
|
|
6126
6155
|
async $queryRawUnsafe(query, ...values) {
|
|
6127
6156
|
const result = await pool.query(query, values);
|
|
@@ -6666,6 +6695,17 @@ async function cloudSync(config) {
|
|
|
6666
6695
|
} catch (err) {
|
|
6667
6696
|
logError(`[cloud-sync] DB backup upload error: ${err instanceof Error ? err.message : String(err)}`);
|
|
6668
6697
|
}
|
|
6698
|
+
let codeContextResult = { pushed: 0, pulled: 0 };
|
|
6699
|
+
try {
|
|
6700
|
+
codeContextResult.pushed = await cloudPushCodeContext(config);
|
|
6701
|
+
} catch (err) {
|
|
6702
|
+
logError(`[cloud-sync] Code context push: ${err instanceof Error ? err.message : String(err)}`);
|
|
6703
|
+
}
|
|
6704
|
+
try {
|
|
6705
|
+
codeContextResult.pulled = await cloudPullCodeContext(config);
|
|
6706
|
+
} catch (err) {
|
|
6707
|
+
logError(`[cloud-sync] Code context pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
6708
|
+
}
|
|
6669
6709
|
return {
|
|
6670
6710
|
pushed,
|
|
6671
6711
|
pulled,
|
|
@@ -6675,7 +6715,8 @@ async function cloudSync(config) {
|
|
|
6675
6715
|
tasks: tasksResult,
|
|
6676
6716
|
conversations: conversationsResult,
|
|
6677
6717
|
documents: documentsResult,
|
|
6678
|
-
roster: rosterResult
|
|
6718
|
+
roster: rosterResult,
|
|
6719
|
+
codeContext: codeContextResult
|
|
6679
6720
|
};
|
|
6680
6721
|
}
|
|
6681
6722
|
function recordRosterDeletion(name) {
|
|
@@ -7313,7 +7354,99 @@ async function cloudPullDocuments(config) {
|
|
|
7313
7354
|
}
|
|
7314
7355
|
return { pulled };
|
|
7315
7356
|
}
|
|
7316
|
-
|
|
7357
|
+
async function cloudPushCodeContext(config) {
|
|
7358
|
+
assertSecureEndpoint(config.endpoint);
|
|
7359
|
+
if (!existsSync19(CODE_CONTEXT_DIR)) return 0;
|
|
7360
|
+
const files = readdirSync6(CODE_CONTEXT_DIR).filter(
|
|
7361
|
+
(f) => f.endsWith(".json") && !f.endsWith(".vectors.json") && !f.startsWith(".")
|
|
7362
|
+
);
|
|
7363
|
+
if (files.length === 0) return 0;
|
|
7364
|
+
const metaPath = path20.join(CODE_CONTEXT_DIR, ".sync-meta.json");
|
|
7365
|
+
let syncMeta = {};
|
|
7366
|
+
if (existsSync19(metaPath)) {
|
|
7367
|
+
try {
|
|
7368
|
+
syncMeta = JSON.parse(readFileSync13(metaPath, "utf-8"));
|
|
7369
|
+
} catch {
|
|
7370
|
+
}
|
|
7371
|
+
}
|
|
7372
|
+
let pushed = 0;
|
|
7373
|
+
for (const file of files) {
|
|
7374
|
+
const filePath = path20.join(CODE_CONTEXT_DIR, file);
|
|
7375
|
+
try {
|
|
7376
|
+
const stat = statSync6(filePath);
|
|
7377
|
+
const lastPushed = syncMeta[file] ?? 0;
|
|
7378
|
+
if (stat.mtimeMs <= lastPushed) continue;
|
|
7379
|
+
const content = readFileSync13(filePath, "utf-8");
|
|
7380
|
+
const header = content.substring(0, 300);
|
|
7381
|
+
if (header.includes("/tmp") || header.includes("/var/folders") || header.includes(".worktrees/")) continue;
|
|
7382
|
+
const compressed = compress(Buffer.from(content, "utf8"));
|
|
7383
|
+
const encrypted = encryptSyncBlob(compressed);
|
|
7384
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/push-code-context`, {
|
|
7385
|
+
method: "POST",
|
|
7386
|
+
headers: {
|
|
7387
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
7388
|
+
"Content-Type": "application/json",
|
|
7389
|
+
"X-Device-Id": loadDeviceId()
|
|
7390
|
+
},
|
|
7391
|
+
body: JSON.stringify({ key: file, blob: encrypted })
|
|
7392
|
+
});
|
|
7393
|
+
if (resp.ok) {
|
|
7394
|
+
syncMeta[file] = stat.mtimeMs;
|
|
7395
|
+
pushed++;
|
|
7396
|
+
}
|
|
7397
|
+
} catch {
|
|
7398
|
+
}
|
|
7399
|
+
}
|
|
7400
|
+
if (pushed > 0) {
|
|
7401
|
+
try {
|
|
7402
|
+
writeFileSync9(metaPath, JSON.stringify(syncMeta));
|
|
7403
|
+
} catch {
|
|
7404
|
+
}
|
|
7405
|
+
}
|
|
7406
|
+
return pushed;
|
|
7407
|
+
}
|
|
7408
|
+
async function cloudPullCodeContext(config) {
|
|
7409
|
+
assertSecureEndpoint(config.endpoint);
|
|
7410
|
+
try {
|
|
7411
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/pull-code-context`, {
|
|
7412
|
+
method: "GET",
|
|
7413
|
+
headers: {
|
|
7414
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
7415
|
+
"X-Device-Id": loadDeviceId()
|
|
7416
|
+
}
|
|
7417
|
+
});
|
|
7418
|
+
if (!resp.ok) return 0;
|
|
7419
|
+
const data = await resp.json();
|
|
7420
|
+
if (!data.indexes || data.indexes.length === 0) return 0;
|
|
7421
|
+
mkdirSync10(CODE_CONTEXT_DIR, { recursive: true });
|
|
7422
|
+
let pulled = 0;
|
|
7423
|
+
for (const { key, blob } of data.indexes) {
|
|
7424
|
+
try {
|
|
7425
|
+
if (key.endsWith(".vectors.json")) continue;
|
|
7426
|
+
const localPath = path20.join(CODE_CONTEXT_DIR, key);
|
|
7427
|
+
const compressed = decryptSyncBlob(blob);
|
|
7428
|
+
const content = decompress(compressed).toString("utf8");
|
|
7429
|
+
if (!existsSync19(localPath)) {
|
|
7430
|
+
writeFileSync9(localPath, content, "utf-8");
|
|
7431
|
+
pulled++;
|
|
7432
|
+
} else {
|
|
7433
|
+
const localContent = readFileSync13(localPath, "utf-8");
|
|
7434
|
+
if (localContent.length !== content.length) {
|
|
7435
|
+
writeFileSync9(localPath, content, "utf-8");
|
|
7436
|
+
pulled++;
|
|
7437
|
+
}
|
|
7438
|
+
}
|
|
7439
|
+
} catch {
|
|
7440
|
+
}
|
|
7441
|
+
}
|
|
7442
|
+
return pulled;
|
|
7443
|
+
} catch (err) {
|
|
7444
|
+
process.stderr.write(`[cloud-sync] Code context pull failed: ${err instanceof Error ? err.message : String(err)}
|
|
7445
|
+
`);
|
|
7446
|
+
return 0;
|
|
7447
|
+
}
|
|
7448
|
+
}
|
|
7449
|
+
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;
|
|
7317
7450
|
var init_cloud_sync = __esm({
|
|
7318
7451
|
"src/lib/cloud-sync.ts"() {
|
|
7319
7452
|
"use strict";
|
|
@@ -7334,6 +7467,7 @@ var init_cloud_sync = __esm({
|
|
|
7334
7467
|
_pgFailed = false;
|
|
7335
7468
|
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.";
|
|
7336
7469
|
ROSTER_DELETIONS_PATH = path20.join(EXE_AI_DIR, "roster-deletions.json");
|
|
7470
|
+
CODE_CONTEXT_DIR = path20.join(EXE_AI_DIR, "code-context");
|
|
7337
7471
|
}
|
|
7338
7472
|
});
|
|
7339
7473
|
|
package/dist/index.js
CHANGED
|
@@ -1069,7 +1069,7 @@ function readQueue() {
|
|
|
1069
1069
|
function writeQueue(queue) {
|
|
1070
1070
|
ensureDir();
|
|
1071
1071
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
1072
|
-
writeFileSync4(tmp, JSON.stringify(queue, null, 2));
|
|
1072
|
+
writeFileSync4(tmp, JSON.stringify(queue, null, 2), { mode: 384 });
|
|
1073
1073
|
renameSync3(tmp, QUEUE_PATH);
|
|
1074
1074
|
}
|
|
1075
1075
|
function queueIntercom(targetSession, reason) {
|
|
@@ -2511,6 +2511,7 @@ __export(database_exports, {
|
|
|
2511
2511
|
isInitialized: () => isInitialized,
|
|
2512
2512
|
setExternalClient: () => setExternalClient
|
|
2513
2513
|
});
|
|
2514
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
2514
2515
|
import { createClient } from "@libsql/client";
|
|
2515
2516
|
async function initDatabase(config2) {
|
|
2516
2517
|
if (_walCheckpointTimer) {
|
|
@@ -2552,6 +2553,16 @@ async function initDatabase(config2) {
|
|
|
2552
2553
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
2553
2554
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
2554
2555
|
}
|
|
2556
|
+
try {
|
|
2557
|
+
chmodSync2(config2.dbPath, 384);
|
|
2558
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
2559
|
+
try {
|
|
2560
|
+
chmodSync2(config2.dbPath + suffix, 384);
|
|
2561
|
+
} catch {
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
} catch {
|
|
2565
|
+
}
|
|
2555
2566
|
}
|
|
2556
2567
|
function isInitialized() {
|
|
2557
2568
|
return _adapterClient !== null || _client !== null;
|
package/dist/lib/cloud-sync.js
CHANGED
|
@@ -1425,6 +1425,7 @@ __export(database_exports, {
|
|
|
1425
1425
|
isInitialized: () => isInitialized,
|
|
1426
1426
|
setExternalClient: () => setExternalClient
|
|
1427
1427
|
});
|
|
1428
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
1428
1429
|
import { createClient } from "@libsql/client";
|
|
1429
1430
|
async function initDatabase(config) {
|
|
1430
1431
|
if (_walCheckpointTimer) {
|
|
@@ -1466,6 +1467,16 @@ async function initDatabase(config) {
|
|
|
1466
1467
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
1467
1468
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
1468
1469
|
}
|
|
1470
|
+
try {
|
|
1471
|
+
chmodSync2(config.dbPath, 384);
|
|
1472
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
1473
|
+
try {
|
|
1474
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
1475
|
+
} catch {
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
} catch {
|
|
1479
|
+
}
|
|
1469
1480
|
}
|
|
1470
1481
|
function isInitialized() {
|
|
1471
1482
|
return _adapterClient !== null || _client !== null;
|
|
@@ -3048,6 +3059,21 @@ var init_crdt_sync = __esm({
|
|
|
3048
3059
|
}
|
|
3049
3060
|
});
|
|
3050
3061
|
|
|
3062
|
+
// src/lib/pg-ssl.ts
|
|
3063
|
+
var pg_ssl_exports = {};
|
|
3064
|
+
__export(pg_ssl_exports, {
|
|
3065
|
+
pgSslConfig: () => pgSslConfig
|
|
3066
|
+
});
|
|
3067
|
+
function pgSslConfig() {
|
|
3068
|
+
if (process.env.EXE_DB_SSL_DISABLED === "true") return {};
|
|
3069
|
+
return { ssl: { rejectUnauthorized: process.env.EXE_DB_SSL_ALLOW_SELFSIGNED !== "true" } };
|
|
3070
|
+
}
|
|
3071
|
+
var init_pg_ssl = __esm({
|
|
3072
|
+
"src/lib/pg-ssl.ts"() {
|
|
3073
|
+
"use strict";
|
|
3074
|
+
}
|
|
3075
|
+
});
|
|
3076
|
+
|
|
3051
3077
|
// src/lib/keychain.ts
|
|
3052
3078
|
var keychain_exports = {};
|
|
3053
3079
|
__export(keychain_exports, {
|
|
@@ -3801,7 +3827,8 @@ function loadPgClient() {
|
|
|
3801
3827
|
return new Ctor();
|
|
3802
3828
|
}
|
|
3803
3829
|
const { Pool } = await import("pg");
|
|
3804
|
-
const
|
|
3830
|
+
const { pgSslConfig: pgSslConfig2 } = await Promise.resolve().then(() => (init_pg_ssl(), pg_ssl_exports));
|
|
3831
|
+
const pool = new Pool({ connectionString: process.env.DATABASE_URL, ...pgSslConfig2() });
|
|
3805
3832
|
return {
|
|
3806
3833
|
async $queryRawUnsafe(query, ...values) {
|
|
3807
3834
|
const result = await pool.query(query, values);
|
|
@@ -4347,6 +4374,17 @@ async function cloudSync(config) {
|
|
|
4347
4374
|
} catch (err) {
|
|
4348
4375
|
logError(`[cloud-sync] DB backup upload error: ${err instanceof Error ? err.message : String(err)}`);
|
|
4349
4376
|
}
|
|
4377
|
+
let codeContextResult = { pushed: 0, pulled: 0 };
|
|
4378
|
+
try {
|
|
4379
|
+
codeContextResult.pushed = await cloudPushCodeContext(config);
|
|
4380
|
+
} catch (err) {
|
|
4381
|
+
logError(`[cloud-sync] Code context push: ${err instanceof Error ? err.message : String(err)}`);
|
|
4382
|
+
}
|
|
4383
|
+
try {
|
|
4384
|
+
codeContextResult.pulled = await cloudPullCodeContext(config);
|
|
4385
|
+
} catch (err) {
|
|
4386
|
+
logError(`[cloud-sync] Code context pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
4387
|
+
}
|
|
4350
4388
|
return {
|
|
4351
4389
|
pushed,
|
|
4352
4390
|
pulled,
|
|
@@ -4356,7 +4394,8 @@ async function cloudSync(config) {
|
|
|
4356
4394
|
tasks: tasksResult,
|
|
4357
4395
|
conversations: conversationsResult,
|
|
4358
4396
|
documents: documentsResult,
|
|
4359
|
-
roster: rosterResult
|
|
4397
|
+
roster: rosterResult,
|
|
4398
|
+
codeContext: codeContextResult
|
|
4360
4399
|
};
|
|
4361
4400
|
}
|
|
4362
4401
|
var ROSTER_DELETIONS_PATH = path10.join(EXE_AI_DIR, "roster-deletions.json");
|
|
@@ -4995,6 +5034,99 @@ async function cloudPullDocuments(config) {
|
|
|
4995
5034
|
}
|
|
4996
5035
|
return { pulled };
|
|
4997
5036
|
}
|
|
5037
|
+
var CODE_CONTEXT_DIR = path10.join(EXE_AI_DIR, "code-context");
|
|
5038
|
+
async function cloudPushCodeContext(config) {
|
|
5039
|
+
assertSecureEndpoint(config.endpoint);
|
|
5040
|
+
if (!existsSync10(CODE_CONTEXT_DIR)) return 0;
|
|
5041
|
+
const files = readdirSync2(CODE_CONTEXT_DIR).filter(
|
|
5042
|
+
(f) => f.endsWith(".json") && !f.endsWith(".vectors.json") && !f.startsWith(".")
|
|
5043
|
+
);
|
|
5044
|
+
if (files.length === 0) return 0;
|
|
5045
|
+
const metaPath = path10.join(CODE_CONTEXT_DIR, ".sync-meta.json");
|
|
5046
|
+
let syncMeta = {};
|
|
5047
|
+
if (existsSync10(metaPath)) {
|
|
5048
|
+
try {
|
|
5049
|
+
syncMeta = JSON.parse(readFileSync7(metaPath, "utf-8"));
|
|
5050
|
+
} catch {
|
|
5051
|
+
}
|
|
5052
|
+
}
|
|
5053
|
+
let pushed = 0;
|
|
5054
|
+
for (const file of files) {
|
|
5055
|
+
const filePath = path10.join(CODE_CONTEXT_DIR, file);
|
|
5056
|
+
try {
|
|
5057
|
+
const stat = statSync4(filePath);
|
|
5058
|
+
const lastPushed = syncMeta[file] ?? 0;
|
|
5059
|
+
if (stat.mtimeMs <= lastPushed) continue;
|
|
5060
|
+
const content = readFileSync7(filePath, "utf-8");
|
|
5061
|
+
const header = content.substring(0, 300);
|
|
5062
|
+
if (header.includes("/tmp") || header.includes("/var/folders") || header.includes(".worktrees/")) continue;
|
|
5063
|
+
const compressed = compress(Buffer.from(content, "utf8"));
|
|
5064
|
+
const encrypted = encryptSyncBlob(compressed);
|
|
5065
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/push-code-context`, {
|
|
5066
|
+
method: "POST",
|
|
5067
|
+
headers: {
|
|
5068
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
5069
|
+
"Content-Type": "application/json",
|
|
5070
|
+
"X-Device-Id": loadDeviceId()
|
|
5071
|
+
},
|
|
5072
|
+
body: JSON.stringify({ key: file, blob: encrypted })
|
|
5073
|
+
});
|
|
5074
|
+
if (resp.ok) {
|
|
5075
|
+
syncMeta[file] = stat.mtimeMs;
|
|
5076
|
+
pushed++;
|
|
5077
|
+
}
|
|
5078
|
+
} catch {
|
|
5079
|
+
}
|
|
5080
|
+
}
|
|
5081
|
+
if (pushed > 0) {
|
|
5082
|
+
try {
|
|
5083
|
+
writeFileSync5(metaPath, JSON.stringify(syncMeta));
|
|
5084
|
+
} catch {
|
|
5085
|
+
}
|
|
5086
|
+
}
|
|
5087
|
+
return pushed;
|
|
5088
|
+
}
|
|
5089
|
+
async function cloudPullCodeContext(config) {
|
|
5090
|
+
assertSecureEndpoint(config.endpoint);
|
|
5091
|
+
try {
|
|
5092
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/pull-code-context`, {
|
|
5093
|
+
method: "GET",
|
|
5094
|
+
headers: {
|
|
5095
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
5096
|
+
"X-Device-Id": loadDeviceId()
|
|
5097
|
+
}
|
|
5098
|
+
});
|
|
5099
|
+
if (!resp.ok) return 0;
|
|
5100
|
+
const data = await resp.json();
|
|
5101
|
+
if (!data.indexes || data.indexes.length === 0) return 0;
|
|
5102
|
+
mkdirSync5(CODE_CONTEXT_DIR, { recursive: true });
|
|
5103
|
+
let pulled = 0;
|
|
5104
|
+
for (const { key, blob } of data.indexes) {
|
|
5105
|
+
try {
|
|
5106
|
+
if (key.endsWith(".vectors.json")) continue;
|
|
5107
|
+
const localPath = path10.join(CODE_CONTEXT_DIR, key);
|
|
5108
|
+
const compressed = decryptSyncBlob(blob);
|
|
5109
|
+
const content = decompress(compressed).toString("utf8");
|
|
5110
|
+
if (!existsSync10(localPath)) {
|
|
5111
|
+
writeFileSync5(localPath, content, "utf-8");
|
|
5112
|
+
pulled++;
|
|
5113
|
+
} else {
|
|
5114
|
+
const localContent = readFileSync7(localPath, "utf-8");
|
|
5115
|
+
if (localContent.length !== content.length) {
|
|
5116
|
+
writeFileSync5(localPath, content, "utf-8");
|
|
5117
|
+
pulled++;
|
|
5118
|
+
}
|
|
5119
|
+
}
|
|
5120
|
+
} catch {
|
|
5121
|
+
}
|
|
5122
|
+
}
|
|
5123
|
+
return pulled;
|
|
5124
|
+
} catch (err) {
|
|
5125
|
+
process.stderr.write(`[cloud-sync] Code context pull failed: ${err instanceof Error ? err.message : String(err)}
|
|
5126
|
+
`);
|
|
5127
|
+
return 0;
|
|
5128
|
+
}
|
|
5129
|
+
}
|
|
4998
5130
|
export {
|
|
4999
5131
|
CLOUD_REUPLOAD_REQUIRED_MESSAGE,
|
|
5000
5132
|
assertSecureEndpoint,
|
|
@@ -5003,6 +5135,7 @@ export {
|
|
|
5003
5135
|
cloudPull,
|
|
5004
5136
|
cloudPullBehaviors,
|
|
5005
5137
|
cloudPullBlob,
|
|
5138
|
+
cloudPullCodeContext,
|
|
5006
5139
|
cloudPullConversations,
|
|
5007
5140
|
cloudPullDocuments,
|
|
5008
5141
|
cloudPullGlobalProcedures,
|
|
@@ -5012,6 +5145,7 @@ export {
|
|
|
5012
5145
|
cloudPush,
|
|
5013
5146
|
cloudPushBehaviors,
|
|
5014
5147
|
cloudPushBlob,
|
|
5148
|
+
cloudPushCodeContext,
|
|
5015
5149
|
cloudPushConversations,
|
|
5016
5150
|
cloudPushDocuments,
|
|
5017
5151
|
cloudPushGlobalProcedures,
|
package/dist/lib/database.js
CHANGED
|
@@ -670,6 +670,7 @@ var init_db_daemon_client = __esm({
|
|
|
670
670
|
});
|
|
671
671
|
|
|
672
672
|
// src/lib/database.ts
|
|
673
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
673
674
|
import { createClient } from "@libsql/client";
|
|
674
675
|
|
|
675
676
|
// src/lib/db-retry.ts
|
|
@@ -1381,6 +1382,16 @@ async function initDatabase(config) {
|
|
|
1381
1382
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
1382
1383
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
1383
1384
|
}
|
|
1385
|
+
try {
|
|
1386
|
+
chmodSync2(config.dbPath, 384);
|
|
1387
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
1388
|
+
try {
|
|
1389
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
1390
|
+
} catch {
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
} catch {
|
|
1394
|
+
}
|
|
1384
1395
|
}
|
|
1385
1396
|
function isInitialized() {
|
|
1386
1397
|
return _adapterClient !== null || _client !== null;
|
package/dist/lib/db.js
CHANGED
|
@@ -670,6 +670,7 @@ var init_db_daemon_client = __esm({
|
|
|
670
670
|
});
|
|
671
671
|
|
|
672
672
|
// src/lib/database.ts
|
|
673
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
673
674
|
import { createClient } from "@libsql/client";
|
|
674
675
|
|
|
675
676
|
// src/lib/db-retry.ts
|
|
@@ -1381,6 +1382,16 @@ async function initDatabase(config) {
|
|
|
1381
1382
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
1382
1383
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
1383
1384
|
}
|
|
1385
|
+
try {
|
|
1386
|
+
chmodSync2(config.dbPath, 384);
|
|
1387
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
1388
|
+
try {
|
|
1389
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
1390
|
+
} catch {
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
} catch {
|
|
1394
|
+
}
|
|
1384
1395
|
}
|
|
1385
1396
|
function isInitialized() {
|
|
1386
1397
|
return _adapterClient !== null || _client !== null;
|
|
@@ -1370,6 +1370,7 @@ __export(database_exports, {
|
|
|
1370
1370
|
isInitialized: () => isInitialized,
|
|
1371
1371
|
setExternalClient: () => setExternalClient
|
|
1372
1372
|
});
|
|
1373
|
+
import { chmodSync as chmodSync2 } from "fs";
|
|
1373
1374
|
import { createClient } from "@libsql/client";
|
|
1374
1375
|
async function initDatabase(config) {
|
|
1375
1376
|
if (_walCheckpointTimer) {
|
|
@@ -1411,6 +1412,16 @@ async function initDatabase(config) {
|
|
|
1411
1412
|
if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") {
|
|
1412
1413
|
_adapterClient = await createPrismaDbAdapter(_resilientClient);
|
|
1413
1414
|
}
|
|
1415
|
+
try {
|
|
1416
|
+
chmodSync2(config.dbPath, 384);
|
|
1417
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
1418
|
+
try {
|
|
1419
|
+
chmodSync2(config.dbPath + suffix, 384);
|
|
1420
|
+
} catch {
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
} catch {
|
|
1424
|
+
}
|
|
1414
1425
|
}
|
|
1415
1426
|
function isInitialized() {
|
|
1416
1427
|
return _adapterClient !== null || _client !== null;
|