@askexenow/exe-os 0.8.36 → 0.8.37
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 +9 -1
- package/dist/bin/backfill-responses.js +9 -1
- package/dist/bin/cli.js +255 -31
- package/dist/bin/exe-assign.js +9 -1
- package/dist/bin/exe-boot.js +554 -23
- package/dist/bin/exe-dispatch.js +43 -3
- package/dist/bin/exe-export-behaviors.js +7 -0
- package/dist/bin/exe-gateway.js +57 -9
- package/dist/bin/exe-heartbeat.js +2 -1
- package/dist/bin/exe-kill.js +7 -0
- package/dist/bin/exe-launch-agent.js +8 -1
- package/dist/bin/exe-link.js +503 -12
- package/dist/bin/exe-pending-messages.js +2 -1
- package/dist/bin/exe-pending-reviews.js +2 -1
- package/dist/bin/exe-review.js +9 -1
- package/dist/bin/exe-search.js +9 -1
- package/dist/bin/exe-session-cleanup.js +11 -2
- package/dist/bin/git-sweep.js +9 -1
- package/dist/bin/graph-backfill.js +7 -0
- package/dist/bin/graph-export.js +7 -0
- package/dist/bin/install.js +35 -5
- package/dist/bin/scan-tasks.js +9 -1
- package/dist/bin/shard-migrate.js +7 -0
- package/dist/bin/wiki-sync.js +7 -0
- package/dist/gateway/index.js +57 -9
- package/dist/hooks/bug-report-worker.js +45 -5
- package/dist/hooks/commit-complete.js +9 -1
- package/dist/hooks/error-recall.js +10 -2
- package/dist/hooks/exe-heartbeat-hook.js +1 -1
- package/dist/hooks/ingest-worker.js +56 -8
- package/dist/hooks/ingest.js +1 -1
- package/dist/hooks/instructions-loaded.js +10 -2
- package/dist/hooks/notification.js +10 -2
- package/dist/hooks/post-compact.js +10 -2
- package/dist/hooks/pre-compact.js +10 -2
- package/dist/hooks/pre-tool-use.js +10 -2
- package/dist/hooks/prompt-ingest-worker.js +9 -1
- package/dist/hooks/prompt-submit.js +56 -8
- package/dist/hooks/response-ingest-worker.js +9 -1
- package/dist/hooks/session-end.js +10 -2
- package/dist/hooks/session-start.js +10 -2
- package/dist/hooks/stop.js +10 -2
- package/dist/hooks/subagent-stop.js +10 -2
- package/dist/hooks/summary-worker.js +512 -13
- package/dist/index.js +65 -15
- package/dist/lib/cloud-sync.js +502 -11
- package/dist/lib/exe-daemon.js +73 -23
- package/dist/lib/hybrid-search.js +9 -1
- package/dist/lib/messaging.js +43 -3
- package/dist/lib/store.js +9 -1
- package/dist/lib/tasks.js +47 -7
- package/dist/lib/tmux-routing.js +45 -3
- package/dist/mcp/server.js +73 -16
- package/dist/mcp/tools/create-task.js +48 -8
- package/dist/mcp/tools/deactivate-behavior.js +1 -1
- package/dist/mcp/tools/list-tasks.js +2 -1
- package/dist/mcp/tools/send-message.js +46 -6
- package/dist/mcp/tools/update-task.js +3 -2
- package/dist/runtime/index.js +54 -4
- package/dist/tui/App.js +54 -4
- package/package.json +2 -2
- package/src/commands/exe/afk.md +116 -0
package/dist/bin/exe-boot.js
CHANGED
|
@@ -2579,6 +2579,42 @@ import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, mkdirSy
|
|
|
2579
2579
|
import path11 from "path";
|
|
2580
2580
|
import os5 from "os";
|
|
2581
2581
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2582
|
+
import { unlinkSync as unlinkSync3 } from "fs";
|
|
2583
|
+
function spawnLockPath(sessionName) {
|
|
2584
|
+
return path11.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
2585
|
+
}
|
|
2586
|
+
function isProcessAlive(pid) {
|
|
2587
|
+
try {
|
|
2588
|
+
process.kill(pid, 0);
|
|
2589
|
+
return true;
|
|
2590
|
+
} catch {
|
|
2591
|
+
return false;
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
function acquireSpawnLock(sessionName) {
|
|
2595
|
+
if (!existsSync10(SPAWN_LOCK_DIR)) {
|
|
2596
|
+
mkdirSync6(SPAWN_LOCK_DIR, { recursive: true });
|
|
2597
|
+
}
|
|
2598
|
+
const lockFile = spawnLockPath(sessionName);
|
|
2599
|
+
if (existsSync10(lockFile)) {
|
|
2600
|
+
try {
|
|
2601
|
+
const lock = JSON.parse(readFileSync9(lockFile, "utf8"));
|
|
2602
|
+
const age = Date.now() - lock.timestamp;
|
|
2603
|
+
if (isProcessAlive(lock.pid) && age < 6e4) {
|
|
2604
|
+
return false;
|
|
2605
|
+
}
|
|
2606
|
+
} catch {
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
writeFileSync5(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
|
|
2610
|
+
return true;
|
|
2611
|
+
}
|
|
2612
|
+
function releaseSpawnLock(sessionName) {
|
|
2613
|
+
try {
|
|
2614
|
+
unlinkSync3(spawnLockPath(sessionName));
|
|
2615
|
+
} catch {
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2582
2618
|
function resolveBehaviorsExporterScript() {
|
|
2583
2619
|
try {
|
|
2584
2620
|
const thisFile = fileURLToPath2(import.meta.url);
|
|
@@ -2659,10 +2695,10 @@ function isEmployeeAlive(sessionName) {
|
|
|
2659
2695
|
}
|
|
2660
2696
|
function findFreeInstance(employeeName, exeSession, maxInstances = 10, isAlive = isEmployeeAlive) {
|
|
2661
2697
|
const base = employeeSessionName(employeeName, exeSession);
|
|
2662
|
-
if (!isAlive(base)) return 0;
|
|
2698
|
+
if (!isAlive(base) && acquireSpawnLock(base)) return 0;
|
|
2663
2699
|
for (let i = 2; i <= maxInstances; i++) {
|
|
2664
2700
|
const candidate = employeeSessionName(employeeName, exeSession, i);
|
|
2665
|
-
if (!isAlive(candidate)) return i;
|
|
2701
|
+
if (!isAlive(candidate) && acquireSpawnLock(candidate)) return i;
|
|
2666
2702
|
}
|
|
2667
2703
|
return null;
|
|
2668
2704
|
}
|
|
@@ -2996,6 +3032,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
2996
3032
|
command: spawnCommand
|
|
2997
3033
|
});
|
|
2998
3034
|
if (spawnResult.error) {
|
|
3035
|
+
releaseSpawnLock(sessionName);
|
|
2999
3036
|
return { sessionName, error: `tmux new-session failed: ${spawnResult.error}` };
|
|
3000
3037
|
}
|
|
3001
3038
|
transport.pipeLog(sessionName, logFile);
|
|
@@ -3033,6 +3070,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3033
3070
|
}
|
|
3034
3071
|
}
|
|
3035
3072
|
if (!booted) {
|
|
3073
|
+
releaseSpawnLock(sessionName);
|
|
3036
3074
|
return { sessionName, error: `${useExeAgent ? "exe-agent" : "claude"} did not boot within 15s` };
|
|
3037
3075
|
}
|
|
3038
3076
|
if (!useExeAgent) {
|
|
@@ -3049,9 +3087,10 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
3049
3087
|
pid: 0,
|
|
3050
3088
|
registeredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3051
3089
|
});
|
|
3090
|
+
releaseSpawnLock(sessionName);
|
|
3052
3091
|
return { sessionName };
|
|
3053
3092
|
}
|
|
3054
|
-
var SESSION_CACHE, BEHAVIORS_EXPORT_TIMEOUT_MS, INTERCOM_DEBOUNCE_MS, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS, BUSY_PATTERN;
|
|
3093
|
+
var SPAWN_LOCK_DIR, SESSION_CACHE, BEHAVIORS_EXPORT_TIMEOUT_MS, INTERCOM_DEBOUNCE_MS, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS, BUSY_PATTERN;
|
|
3055
3094
|
var init_tmux_routing = __esm({
|
|
3056
3095
|
"src/lib/tmux-routing.ts"() {
|
|
3057
3096
|
"use strict";
|
|
@@ -3063,6 +3102,7 @@ var init_tmux_routing = __esm({
|
|
|
3063
3102
|
init_provider_table();
|
|
3064
3103
|
init_intercom_queue();
|
|
3065
3104
|
init_plan_limits();
|
|
3105
|
+
SPAWN_LOCK_DIR = path11.join(os5.homedir(), ".exe-os", "spawn-locks");
|
|
3066
3106
|
SESSION_CACHE = path11.join(os5.homedir(), ".exe-os", "session-cache");
|
|
3067
3107
|
BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
|
|
3068
3108
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
@@ -3662,7 +3702,7 @@ var init_tasks_crud = __esm({
|
|
|
3662
3702
|
|
|
3663
3703
|
// src/lib/tasks-review.ts
|
|
3664
3704
|
import path15 from "path";
|
|
3665
|
-
import { existsSync as existsSync13, readdirSync as readdirSync4, unlinkSync as
|
|
3705
|
+
import { existsSync as existsSync13, readdirSync as readdirSync4, unlinkSync as unlinkSync4 } from "fs";
|
|
3666
3706
|
async function countPendingReviews() {
|
|
3667
3707
|
const client = getClient();
|
|
3668
3708
|
const result = await client.execute({
|
|
@@ -3786,7 +3826,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
3786
3826
|
if (existsSync13(cacheDir)) {
|
|
3787
3827
|
for (const f of readdirSync4(cacheDir)) {
|
|
3788
3828
|
if (f.startsWith("review-notified-")) {
|
|
3789
|
-
|
|
3829
|
+
unlinkSync4(path15.join(cacheDir, f));
|
|
3790
3830
|
}
|
|
3791
3831
|
}
|
|
3792
3832
|
}
|
|
@@ -4345,7 +4385,7 @@ __export(tasks_exports, {
|
|
|
4345
4385
|
writeCheckpoint: () => writeCheckpoint
|
|
4346
4386
|
});
|
|
4347
4387
|
import path17 from "path";
|
|
4348
|
-
import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, unlinkSync as
|
|
4388
|
+
import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, unlinkSync as unlinkSync5 } from "fs";
|
|
4349
4389
|
async function createTask(input) {
|
|
4350
4390
|
const result = await createTaskCore(input);
|
|
4351
4391
|
if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
|
|
@@ -4371,7 +4411,7 @@ async function updateTask(input) {
|
|
|
4371
4411
|
writeFileSync6(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
4372
4412
|
} else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled") {
|
|
4373
4413
|
try {
|
|
4374
|
-
|
|
4414
|
+
unlinkSync5(cachePath);
|
|
4375
4415
|
} catch {
|
|
4376
4416
|
}
|
|
4377
4417
|
}
|
|
@@ -4669,10 +4709,23 @@ var cloud_sync_exports = {};
|
|
|
4669
4709
|
__export(cloud_sync_exports, {
|
|
4670
4710
|
buildRosterBlob: () => buildRosterBlob,
|
|
4671
4711
|
cloudPull: () => cloudPull,
|
|
4712
|
+
cloudPullBehaviors: () => cloudPullBehaviors,
|
|
4713
|
+
cloudPullBlob: () => cloudPullBlob,
|
|
4714
|
+
cloudPullConversations: () => cloudPullConversations,
|
|
4715
|
+
cloudPullDocuments: () => cloudPullDocuments,
|
|
4716
|
+
cloudPullGraphRAG: () => cloudPullGraphRAG,
|
|
4672
4717
|
cloudPullRoster: () => cloudPullRoster,
|
|
4718
|
+
cloudPullTasks: () => cloudPullTasks,
|
|
4673
4719
|
cloudPush: () => cloudPush,
|
|
4720
|
+
cloudPushBehaviors: () => cloudPushBehaviors,
|
|
4721
|
+
cloudPushBlob: () => cloudPushBlob,
|
|
4722
|
+
cloudPushConversations: () => cloudPushConversations,
|
|
4723
|
+
cloudPushDocuments: () => cloudPushDocuments,
|
|
4724
|
+
cloudPushGraphRAG: () => cloudPushGraphRAG,
|
|
4674
4725
|
cloudPushRoster: () => cloudPushRoster,
|
|
4726
|
+
cloudPushTasks: () => cloudPushTasks,
|
|
4675
4727
|
cloudSync: () => cloudSync,
|
|
4728
|
+
mergeConfig: () => mergeConfig,
|
|
4676
4729
|
mergeRosterFromRemote: () => mergeRosterFromRemote
|
|
4677
4730
|
});
|
|
4678
4731
|
import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, existsSync as existsSync14, readdirSync as readdirSync5, mkdirSync as mkdirSync8, appendFileSync as appendFileSync2 } from "fs";
|
|
@@ -4686,6 +4739,17 @@ function logError(msg) {
|
|
|
4686
4739
|
} catch {
|
|
4687
4740
|
}
|
|
4688
4741
|
}
|
|
4742
|
+
async function fetchWithRetry(url, init) {
|
|
4743
|
+
const attempt = async () => {
|
|
4744
|
+
const signal = AbortSignal.timeout(FETCH_TIMEOUT_MS);
|
|
4745
|
+
return fetch(url, { ...init, signal });
|
|
4746
|
+
};
|
|
4747
|
+
const resp = await attempt();
|
|
4748
|
+
if (resp.status >= 500) {
|
|
4749
|
+
return attempt();
|
|
4750
|
+
}
|
|
4751
|
+
return resp;
|
|
4752
|
+
}
|
|
4689
4753
|
function assertSecureEndpoint(endpoint) {
|
|
4690
4754
|
if (endpoint.startsWith("https://")) return;
|
|
4691
4755
|
if (endpoint.startsWith("http://")) {
|
|
@@ -4707,7 +4771,7 @@ async function cloudPush(records, maxVersion, config) {
|
|
|
4707
4771
|
const json = JSON.stringify(records);
|
|
4708
4772
|
const compressed = compress(Buffer.from(json, "utf8"));
|
|
4709
4773
|
const blob = encryptSyncBlob(compressed);
|
|
4710
|
-
const resp = await
|
|
4774
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/push`, {
|
|
4711
4775
|
method: "POST",
|
|
4712
4776
|
headers: {
|
|
4713
4777
|
Authorization: `Bearer ${config.apiKey}`,
|
|
@@ -4725,7 +4789,7 @@ async function cloudPush(records, maxVersion, config) {
|
|
|
4725
4789
|
async function cloudPull(sinceVersion, config) {
|
|
4726
4790
|
assertSecureEndpoint(config.endpoint);
|
|
4727
4791
|
try {
|
|
4728
|
-
const response = await
|
|
4792
|
+
const response = await fetchWithRetry(`${config.endpoint}/sync/pull`, {
|
|
4729
4793
|
method: "POST",
|
|
4730
4794
|
headers: {
|
|
4731
4795
|
Authorization: `Bearer ${config.apiKey}`,
|
|
@@ -4841,20 +4905,87 @@ async function cloudSync(config) {
|
|
|
4841
4905
|
try {
|
|
4842
4906
|
await cloudPushRoster(config);
|
|
4843
4907
|
} catch (err) {
|
|
4844
|
-
|
|
4845
|
-
`);
|
|
4908
|
+
logError(`[cloud-sync] Roster push: ${err instanceof Error ? err.message : String(err)}`);
|
|
4846
4909
|
}
|
|
4847
4910
|
try {
|
|
4848
4911
|
await cloudPullRoster(config);
|
|
4849
4912
|
} catch (err) {
|
|
4850
|
-
|
|
4851
|
-
`);
|
|
4913
|
+
logError(`[cloud-sync] Roster pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
4852
4914
|
}
|
|
4853
|
-
|
|
4915
|
+
let behaviorsResult = { pushed: false, pulled: 0 };
|
|
4916
|
+
try {
|
|
4917
|
+
behaviorsResult.pushed = await cloudPushBehaviors(config);
|
|
4918
|
+
} catch (err) {
|
|
4919
|
+
logError(`[cloud-sync] Behaviors push: ${err instanceof Error ? err.message : String(err)}`);
|
|
4920
|
+
}
|
|
4921
|
+
try {
|
|
4922
|
+
const pullResult2 = await cloudPullBehaviors(config);
|
|
4923
|
+
behaviorsResult.pulled = pullResult2.pulled;
|
|
4924
|
+
} catch (err) {
|
|
4925
|
+
logError(`[cloud-sync] Behaviors pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
4926
|
+
}
|
|
4927
|
+
let graphragResult = { pushed: false, pulled: 0 };
|
|
4928
|
+
try {
|
|
4929
|
+
graphragResult.pushed = await cloudPushGraphRAG(config);
|
|
4930
|
+
} catch (err) {
|
|
4931
|
+
logError(`[cloud-sync] GraphRAG push: ${err instanceof Error ? err.message : String(err)}`);
|
|
4932
|
+
}
|
|
4933
|
+
try {
|
|
4934
|
+
const pullResult2 = await cloudPullGraphRAG(config);
|
|
4935
|
+
graphragResult.pulled = pullResult2.pulled;
|
|
4936
|
+
} catch (err) {
|
|
4937
|
+
logError(`[cloud-sync] GraphRAG pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
4938
|
+
}
|
|
4939
|
+
let tasksResult = { pushed: false, pulled: 0 };
|
|
4940
|
+
try {
|
|
4941
|
+
tasksResult.pushed = await cloudPushTasks(config);
|
|
4942
|
+
} catch (err) {
|
|
4943
|
+
logError(`[cloud-sync] Tasks push: ${err instanceof Error ? err.message : String(err)}`);
|
|
4944
|
+
}
|
|
4945
|
+
try {
|
|
4946
|
+
const pullResult2 = await cloudPullTasks(config);
|
|
4947
|
+
tasksResult.pulled = pullResult2.pulled;
|
|
4948
|
+
} catch (err) {
|
|
4949
|
+
logError(`[cloud-sync] Tasks pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
4950
|
+
}
|
|
4951
|
+
let conversationsResult = { pushed: false, pulled: 0 };
|
|
4952
|
+
try {
|
|
4953
|
+
conversationsResult.pushed = await cloudPushConversations(config);
|
|
4954
|
+
} catch (err) {
|
|
4955
|
+
logError(`[cloud-sync] Conversations push: ${err instanceof Error ? err.message : String(err)}`);
|
|
4956
|
+
}
|
|
4957
|
+
try {
|
|
4958
|
+
const pullResult2 = await cloudPullConversations(config);
|
|
4959
|
+
conversationsResult.pulled = pullResult2.pulled;
|
|
4960
|
+
} catch (err) {
|
|
4961
|
+
logError(`[cloud-sync] Conversations pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
4962
|
+
}
|
|
4963
|
+
let documentsResult = { pushed: false, pulled: 0 };
|
|
4964
|
+
try {
|
|
4965
|
+
documentsResult.pushed = await cloudPushDocuments(config);
|
|
4966
|
+
} catch (err) {
|
|
4967
|
+
logError(`[cloud-sync] Documents push: ${err instanceof Error ? err.message : String(err)}`);
|
|
4968
|
+
}
|
|
4969
|
+
try {
|
|
4970
|
+
const pullResult2 = await cloudPullDocuments(config);
|
|
4971
|
+
documentsResult.pulled = pullResult2.pulled;
|
|
4972
|
+
} catch (err) {
|
|
4973
|
+
logError(`[cloud-sync] Documents pull: ${err instanceof Error ? err.message : String(err)}`);
|
|
4974
|
+
}
|
|
4975
|
+
return {
|
|
4976
|
+
pushed,
|
|
4977
|
+
pulled,
|
|
4978
|
+
behaviors: behaviorsResult,
|
|
4979
|
+
graphrag: graphragResult,
|
|
4980
|
+
tasks: tasksResult,
|
|
4981
|
+
conversations: conversationsResult,
|
|
4982
|
+
documents: documentsResult
|
|
4983
|
+
};
|
|
4854
4984
|
}
|
|
4855
4985
|
function buildRosterBlob(paths) {
|
|
4856
4986
|
const rosterPath = paths?.rosterPath ?? path18.join(EXE_AI_DIR, "exe-employees.json");
|
|
4857
4987
|
const identityDir = paths?.identityDir ?? path18.join(EXE_AI_DIR, "identity");
|
|
4988
|
+
const configPath = paths?.configPath ?? path18.join(EXE_AI_DIR, "config.json");
|
|
4858
4989
|
let roster = [];
|
|
4859
4990
|
if (existsSync14(rosterPath)) {
|
|
4860
4991
|
try {
|
|
@@ -4871,9 +5002,16 @@ function buildRosterBlob(paths) {
|
|
|
4871
5002
|
}
|
|
4872
5003
|
}
|
|
4873
5004
|
}
|
|
4874
|
-
|
|
5005
|
+
let config;
|
|
5006
|
+
if (existsSync14(configPath)) {
|
|
5007
|
+
try {
|
|
5008
|
+
config = JSON.parse(readFileSync12(configPath, "utf-8"));
|
|
5009
|
+
} catch {
|
|
5010
|
+
}
|
|
5011
|
+
}
|
|
5012
|
+
const content = JSON.stringify({ roster, identities, config });
|
|
4875
5013
|
const hash = Buffer.from(content).length;
|
|
4876
|
-
return { roster, identities, version: hash };
|
|
5014
|
+
return { roster, identities, config, version: hash };
|
|
4877
5015
|
}
|
|
4878
5016
|
async function cloudPushRoster(config) {
|
|
4879
5017
|
assertSecureEndpoint(config.endpoint);
|
|
@@ -4892,7 +5030,7 @@ async function cloudPushRoster(config) {
|
|
|
4892
5030
|
const json = JSON.stringify(blob);
|
|
4893
5031
|
const compressed = compress(Buffer.from(json, "utf8"));
|
|
4894
5032
|
const encrypted = encryptSyncBlob(compressed);
|
|
4895
|
-
const resp = await
|
|
5033
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/push-roster`, {
|
|
4896
5034
|
method: "POST",
|
|
4897
5035
|
headers: {
|
|
4898
5036
|
Authorization: `Bearer ${config.apiKey}`,
|
|
@@ -4921,7 +5059,7 @@ async function cloudPushRoster(config) {
|
|
|
4921
5059
|
async function cloudPullRoster(config) {
|
|
4922
5060
|
assertSecureEndpoint(config.endpoint);
|
|
4923
5061
|
try {
|
|
4924
|
-
const resp = await
|
|
5062
|
+
const resp = await fetchWithRetry(`${config.endpoint}/sync/pull-roster`, {
|
|
4925
5063
|
method: "GET",
|
|
4926
5064
|
headers: {
|
|
4927
5065
|
Authorization: `Bearer ${config.apiKey}`,
|
|
@@ -4941,6 +5079,20 @@ async function cloudPullRoster(config) {
|
|
|
4941
5079
|
return { added: 0 };
|
|
4942
5080
|
}
|
|
4943
5081
|
}
|
|
5082
|
+
function mergeConfig(remoteConfig, configPath) {
|
|
5083
|
+
const cfgPath = configPath ?? path18.join(EXE_AI_DIR, "config.json");
|
|
5084
|
+
let local = {};
|
|
5085
|
+
if (existsSync14(cfgPath)) {
|
|
5086
|
+
try {
|
|
5087
|
+
local = JSON.parse(readFileSync12(cfgPath, "utf-8"));
|
|
5088
|
+
} catch {
|
|
5089
|
+
}
|
|
5090
|
+
}
|
|
5091
|
+
const merged = { ...remoteConfig, ...local };
|
|
5092
|
+
const dir = path18.dirname(cfgPath);
|
|
5093
|
+
if (!existsSync14(dir)) mkdirSync8(dir, { recursive: true });
|
|
5094
|
+
writeFileSync7(cfgPath, JSON.stringify(merged, null, 2), "utf-8");
|
|
5095
|
+
}
|
|
4944
5096
|
async function mergeRosterFromRemote(remote, paths) {
|
|
4945
5097
|
const rosterPath = paths?.rosterPath ?? void 0;
|
|
4946
5098
|
const identityDir = paths?.identityDir ?? path18.join(EXE_AI_DIR, "identity");
|
|
@@ -4967,9 +5119,387 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
4967
5119
|
if (added > 0) {
|
|
4968
5120
|
await saveEmployees(localEmployees, rosterPath);
|
|
4969
5121
|
}
|
|
5122
|
+
if (remote.config && Object.keys(remote.config).length > 0) {
|
|
5123
|
+
try {
|
|
5124
|
+
mergeConfig(remote.config, paths?.configPath);
|
|
5125
|
+
} catch {
|
|
5126
|
+
}
|
|
5127
|
+
}
|
|
4970
5128
|
return { added };
|
|
4971
5129
|
}
|
|
4972
|
-
|
|
5130
|
+
async function cloudPushBlob(route, data, metaKey, config) {
|
|
5131
|
+
if (data.length === 0) return { ok: true };
|
|
5132
|
+
assertSecureEndpoint(config.endpoint);
|
|
5133
|
+
const json = JSON.stringify(data);
|
|
5134
|
+
const version = Buffer.from(json).length;
|
|
5135
|
+
try {
|
|
5136
|
+
const client = getClient();
|
|
5137
|
+
const meta = await client.execute({
|
|
5138
|
+
sql: "SELECT value FROM sync_meta WHERE key = ?",
|
|
5139
|
+
args: [metaKey]
|
|
5140
|
+
});
|
|
5141
|
+
const lastVersion = meta.rows.length > 0 ? Number(meta.rows[0].value) : 0;
|
|
5142
|
+
if (version === lastVersion) return { ok: true };
|
|
5143
|
+
} catch {
|
|
5144
|
+
}
|
|
5145
|
+
try {
|
|
5146
|
+
const compressed = compress(Buffer.from(json, "utf8"));
|
|
5147
|
+
const encrypted = encryptSyncBlob(compressed);
|
|
5148
|
+
const resp = await fetchWithRetry(`${config.endpoint}${route}`, {
|
|
5149
|
+
method: "POST",
|
|
5150
|
+
headers: {
|
|
5151
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
5152
|
+
"Content-Type": "application/json",
|
|
5153
|
+
"X-Device-Id": loadDeviceId()
|
|
5154
|
+
},
|
|
5155
|
+
body: JSON.stringify({ blob: encrypted })
|
|
5156
|
+
});
|
|
5157
|
+
if (resp.ok) {
|
|
5158
|
+
try {
|
|
5159
|
+
const client = getClient();
|
|
5160
|
+
await client.execute({
|
|
5161
|
+
sql: "INSERT OR REPLACE INTO sync_meta (key, value) VALUES (?, ?)",
|
|
5162
|
+
args: [metaKey, String(version)]
|
|
5163
|
+
});
|
|
5164
|
+
} catch {
|
|
5165
|
+
}
|
|
5166
|
+
}
|
|
5167
|
+
return { ok: resp.ok };
|
|
5168
|
+
} catch (err) {
|
|
5169
|
+
logError(`[cloud-sync] PUSH ${route}: ${err instanceof Error ? err.message : String(err)}`);
|
|
5170
|
+
return { ok: false };
|
|
5171
|
+
}
|
|
5172
|
+
}
|
|
5173
|
+
async function cloudPullBlob(route, config) {
|
|
5174
|
+
assertSecureEndpoint(config.endpoint);
|
|
5175
|
+
try {
|
|
5176
|
+
const resp = await fetchWithRetry(`${config.endpoint}${route}`, {
|
|
5177
|
+
method: "GET",
|
|
5178
|
+
headers: {
|
|
5179
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
5180
|
+
"X-Device-Id": loadDeviceId()
|
|
5181
|
+
}
|
|
5182
|
+
});
|
|
5183
|
+
if (!resp.ok) return null;
|
|
5184
|
+
const data = await resp.json();
|
|
5185
|
+
if (!data.blob) return null;
|
|
5186
|
+
const compressed = decryptSyncBlob(data.blob);
|
|
5187
|
+
const json = decompress(compressed).toString("utf8");
|
|
5188
|
+
return JSON.parse(json);
|
|
5189
|
+
} catch (err) {
|
|
5190
|
+
logError(`[cloud-sync] PULL ${route}: ${err instanceof Error ? err.message : String(err)}`);
|
|
5191
|
+
return null;
|
|
5192
|
+
}
|
|
5193
|
+
}
|
|
5194
|
+
async function cloudPushBehaviors(config) {
|
|
5195
|
+
const client = getClient();
|
|
5196
|
+
const result = await client.execute("SELECT * FROM behaviors");
|
|
5197
|
+
const rows = result.rows;
|
|
5198
|
+
const { ok } = await cloudPushBlob(
|
|
5199
|
+
"/sync/push-behaviors",
|
|
5200
|
+
rows,
|
|
5201
|
+
"last_behaviors_push_version",
|
|
5202
|
+
config
|
|
5203
|
+
);
|
|
5204
|
+
return ok;
|
|
5205
|
+
}
|
|
5206
|
+
async function cloudPullBehaviors(config) {
|
|
5207
|
+
const remoteBehaviors = await cloudPullBlob(
|
|
5208
|
+
"/sync/pull-behaviors",
|
|
5209
|
+
config
|
|
5210
|
+
);
|
|
5211
|
+
if (!remoteBehaviors || remoteBehaviors.length === 0) return { pulled: 0 };
|
|
5212
|
+
const client = getClient();
|
|
5213
|
+
let pulled = 0;
|
|
5214
|
+
for (const behavior of remoteBehaviors) {
|
|
5215
|
+
const existing = await client.execute({
|
|
5216
|
+
sql: `SELECT COUNT(*) as cnt FROM behaviors
|
|
5217
|
+
WHERE agent_id = ? AND content = ?`,
|
|
5218
|
+
args: [behavior.agent_id, behavior.content]
|
|
5219
|
+
});
|
|
5220
|
+
if (Number(existing.rows[0]?.cnt) > 0) continue;
|
|
5221
|
+
await client.execute({
|
|
5222
|
+
sql: `INSERT OR IGNORE INTO behaviors
|
|
5223
|
+
(id, agent_id, project_name, domain, content, active, priority, created_at, updated_at)
|
|
5224
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5225
|
+
args: [
|
|
5226
|
+
behavior.id,
|
|
5227
|
+
behavior.agent_id,
|
|
5228
|
+
behavior.project_name ?? null,
|
|
5229
|
+
behavior.domain ?? null,
|
|
5230
|
+
behavior.content,
|
|
5231
|
+
behavior.active,
|
|
5232
|
+
behavior.priority ?? "p1",
|
|
5233
|
+
behavior.created_at,
|
|
5234
|
+
behavior.updated_at
|
|
5235
|
+
]
|
|
5236
|
+
});
|
|
5237
|
+
pulled++;
|
|
5238
|
+
}
|
|
5239
|
+
return { pulled };
|
|
5240
|
+
}
|
|
5241
|
+
async function cloudPushGraphRAG(config) {
|
|
5242
|
+
const client = getClient();
|
|
5243
|
+
const [entities, relationships, aliases, entityMems, relMems, hyperedges, hyperedgeNodes] = await Promise.all([
|
|
5244
|
+
client.execute("SELECT * FROM entities"),
|
|
5245
|
+
client.execute("SELECT * FROM relationships"),
|
|
5246
|
+
client.execute("SELECT * FROM entity_aliases"),
|
|
5247
|
+
client.execute("SELECT * FROM entity_memories"),
|
|
5248
|
+
client.execute("SELECT * FROM relationship_memories"),
|
|
5249
|
+
client.execute("SELECT * FROM hyperedges"),
|
|
5250
|
+
client.execute("SELECT * FROM hyperedge_nodes")
|
|
5251
|
+
]);
|
|
5252
|
+
const blob = {
|
|
5253
|
+
entities: entities.rows,
|
|
5254
|
+
relationships: relationships.rows,
|
|
5255
|
+
entity_aliases: aliases.rows,
|
|
5256
|
+
entity_memories: entityMems.rows,
|
|
5257
|
+
relationship_memories: relMems.rows,
|
|
5258
|
+
hyperedges: hyperedges.rows,
|
|
5259
|
+
hyperedge_nodes: hyperedgeNodes.rows
|
|
5260
|
+
};
|
|
5261
|
+
const { ok } = await cloudPushBlob(
|
|
5262
|
+
"/sync/push-graphrag",
|
|
5263
|
+
[blob],
|
|
5264
|
+
"last_graphrag_push_version",
|
|
5265
|
+
config
|
|
5266
|
+
);
|
|
5267
|
+
return ok;
|
|
5268
|
+
}
|
|
5269
|
+
async function cloudPullGraphRAG(config) {
|
|
5270
|
+
const data = await cloudPullBlob(
|
|
5271
|
+
"/sync/pull-graphrag",
|
|
5272
|
+
config
|
|
5273
|
+
);
|
|
5274
|
+
if (!data || data.length === 0) return { pulled: 0 };
|
|
5275
|
+
const blob = data[0];
|
|
5276
|
+
const client = getClient();
|
|
5277
|
+
let pulled = 0;
|
|
5278
|
+
if (blob.entities.length > 0) {
|
|
5279
|
+
const stmts = blob.entities.map((e) => ({
|
|
5280
|
+
sql: `INSERT OR IGNORE INTO entities (id, name, type, first_seen, last_seen, properties)
|
|
5281
|
+
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
5282
|
+
args: [e.id, e.name, e.type, e.first_seen, e.last_seen, e.properties ?? "{}"]
|
|
5283
|
+
}));
|
|
5284
|
+
await client.batch(stmts, "write");
|
|
5285
|
+
pulled += stmts.length;
|
|
5286
|
+
}
|
|
5287
|
+
if (blob.relationships.length > 0) {
|
|
5288
|
+
const stmts = blob.relationships.map((r) => ({
|
|
5289
|
+
sql: `INSERT OR IGNORE INTO relationships
|
|
5290
|
+
(id, source_entity_id, target_entity_id, type, weight, timestamp, properties, confidence, confidence_label)
|
|
5291
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5292
|
+
args: [
|
|
5293
|
+
r.id,
|
|
5294
|
+
r.source_entity_id,
|
|
5295
|
+
r.target_entity_id,
|
|
5296
|
+
r.type,
|
|
5297
|
+
r.weight ?? 1,
|
|
5298
|
+
r.timestamp,
|
|
5299
|
+
r.properties ?? "{}",
|
|
5300
|
+
r.confidence ?? 1,
|
|
5301
|
+
r.confidence_label ?? "extracted"
|
|
5302
|
+
]
|
|
5303
|
+
}));
|
|
5304
|
+
await client.batch(stmts, "write");
|
|
5305
|
+
pulled += stmts.length;
|
|
5306
|
+
}
|
|
5307
|
+
if (blob.entity_aliases.length > 0) {
|
|
5308
|
+
const stmts = blob.entity_aliases.map((a) => ({
|
|
5309
|
+
sql: `INSERT OR IGNORE INTO entity_aliases (alias, canonical_entity_id) VALUES (?, ?)`,
|
|
5310
|
+
args: [a.alias, a.canonical_entity_id]
|
|
5311
|
+
}));
|
|
5312
|
+
await client.batch(stmts, "write");
|
|
5313
|
+
pulled += stmts.length;
|
|
5314
|
+
}
|
|
5315
|
+
if (blob.entity_memories.length > 0) {
|
|
5316
|
+
const stmts = blob.entity_memories.map((em) => ({
|
|
5317
|
+
sql: `INSERT OR IGNORE INTO entity_memories (entity_id, memory_id) VALUES (?, ?)`,
|
|
5318
|
+
args: [em.entity_id, em.memory_id]
|
|
5319
|
+
}));
|
|
5320
|
+
await client.batch(stmts, "write");
|
|
5321
|
+
pulled += stmts.length;
|
|
5322
|
+
}
|
|
5323
|
+
if (blob.relationship_memories.length > 0) {
|
|
5324
|
+
const stmts = blob.relationship_memories.map((rm) => ({
|
|
5325
|
+
sql: `INSERT OR IGNORE INTO relationship_memories (relationship_id, memory_id) VALUES (?, ?)`,
|
|
5326
|
+
args: [rm.relationship_id, rm.memory_id]
|
|
5327
|
+
}));
|
|
5328
|
+
await client.batch(stmts, "write");
|
|
5329
|
+
pulled += stmts.length;
|
|
5330
|
+
}
|
|
5331
|
+
if (blob.hyperedges.length > 0) {
|
|
5332
|
+
const stmts = blob.hyperedges.map((h) => ({
|
|
5333
|
+
sql: `INSERT OR IGNORE INTO hyperedges (id, label, relation, confidence, timestamp)
|
|
5334
|
+
VALUES (?, ?, ?, ?, ?)`,
|
|
5335
|
+
args: [h.id, h.label, h.relation, h.confidence ?? 1, h.timestamp]
|
|
5336
|
+
}));
|
|
5337
|
+
await client.batch(stmts, "write");
|
|
5338
|
+
pulled += stmts.length;
|
|
5339
|
+
}
|
|
5340
|
+
if (blob.hyperedge_nodes.length > 0) {
|
|
5341
|
+
const stmts = blob.hyperedge_nodes.map((hn) => ({
|
|
5342
|
+
sql: `INSERT OR IGNORE INTO hyperedge_nodes (hyperedge_id, entity_id) VALUES (?, ?)`,
|
|
5343
|
+
args: [hn.hyperedge_id, hn.entity_id]
|
|
5344
|
+
}));
|
|
5345
|
+
await client.batch(stmts, "write");
|
|
5346
|
+
pulled += stmts.length;
|
|
5347
|
+
}
|
|
5348
|
+
return { pulled };
|
|
5349
|
+
}
|
|
5350
|
+
async function cloudPushTasks(config) {
|
|
5351
|
+
const client = getClient();
|
|
5352
|
+
const result = await client.execute("SELECT * FROM tasks");
|
|
5353
|
+
const rows = result.rows;
|
|
5354
|
+
const { ok } = await cloudPushBlob(
|
|
5355
|
+
"/sync/push-tasks",
|
|
5356
|
+
rows,
|
|
5357
|
+
"last_tasks_push_version",
|
|
5358
|
+
config
|
|
5359
|
+
);
|
|
5360
|
+
return ok;
|
|
5361
|
+
}
|
|
5362
|
+
async function cloudPullTasks(config) {
|
|
5363
|
+
const remoteTasks = await cloudPullBlob(
|
|
5364
|
+
"/sync/pull-tasks",
|
|
5365
|
+
config
|
|
5366
|
+
);
|
|
5367
|
+
if (!remoteTasks || remoteTasks.length === 0) return { pulled: 0 };
|
|
5368
|
+
const client = getClient();
|
|
5369
|
+
const stmts = remoteTasks.map((t) => ({
|
|
5370
|
+
sql: `INSERT OR IGNORE INTO tasks
|
|
5371
|
+
(id, title, assigned_to, assigned_by, project_name, priority, status, task_file, created_at, updated_at,
|
|
5372
|
+
blocked_by, parent_task_id, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at)
|
|
5373
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5374
|
+
args: [
|
|
5375
|
+
t.id,
|
|
5376
|
+
t.title,
|
|
5377
|
+
t.assigned_to,
|
|
5378
|
+
t.assigned_by,
|
|
5379
|
+
t.project_name,
|
|
5380
|
+
t.priority ?? "p1",
|
|
5381
|
+
t.status ?? "open",
|
|
5382
|
+
t.task_file ?? null,
|
|
5383
|
+
t.created_at,
|
|
5384
|
+
t.updated_at,
|
|
5385
|
+
t.blocked_by ?? null,
|
|
5386
|
+
t.parent_task_id ?? null,
|
|
5387
|
+
t.budget_tokens ?? null,
|
|
5388
|
+
t.budget_fallback_model ?? null,
|
|
5389
|
+
t.tokens_used ?? 0,
|
|
5390
|
+
t.tokens_warned_at ?? null
|
|
5391
|
+
]
|
|
5392
|
+
}));
|
|
5393
|
+
await client.batch(stmts, "write");
|
|
5394
|
+
return { pulled: remoteTasks.length };
|
|
5395
|
+
}
|
|
5396
|
+
async function cloudPushConversations(config) {
|
|
5397
|
+
const client = getClient();
|
|
5398
|
+
const result = await client.execute("SELECT * FROM conversations");
|
|
5399
|
+
const rows = result.rows;
|
|
5400
|
+
const { ok } = await cloudPushBlob(
|
|
5401
|
+
"/sync/push-conversations",
|
|
5402
|
+
rows,
|
|
5403
|
+
"last_conversations_push_version",
|
|
5404
|
+
config
|
|
5405
|
+
);
|
|
5406
|
+
return ok;
|
|
5407
|
+
}
|
|
5408
|
+
async function cloudPullConversations(config) {
|
|
5409
|
+
const remoteConvos = await cloudPullBlob(
|
|
5410
|
+
"/sync/pull-conversations",
|
|
5411
|
+
config
|
|
5412
|
+
);
|
|
5413
|
+
if (!remoteConvos || remoteConvos.length === 0) return { pulled: 0 };
|
|
5414
|
+
const client = getClient();
|
|
5415
|
+
const stmts = remoteConvos.map((c) => ({
|
|
5416
|
+
sql: `INSERT OR IGNORE INTO conversations
|
|
5417
|
+
(id, platform, external_id, sender_id, sender_name, sender_phone, sender_email,
|
|
5418
|
+
recipient_id, channel_id, thread_id, reply_to_id, content_text, content_media,
|
|
5419
|
+
content_metadata, agent_response, agent_name, timestamp, ingested_at)
|
|
5420
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5421
|
+
args: [
|
|
5422
|
+
c.id,
|
|
5423
|
+
c.platform,
|
|
5424
|
+
c.external_id ?? null,
|
|
5425
|
+
c.sender_id,
|
|
5426
|
+
c.sender_name ?? null,
|
|
5427
|
+
c.sender_phone ?? null,
|
|
5428
|
+
c.sender_email ?? null,
|
|
5429
|
+
c.recipient_id ?? null,
|
|
5430
|
+
c.channel_id,
|
|
5431
|
+
c.thread_id ?? null,
|
|
5432
|
+
c.reply_to_id ?? null,
|
|
5433
|
+
c.content_text ?? null,
|
|
5434
|
+
c.content_media ?? null,
|
|
5435
|
+
c.content_metadata ?? null,
|
|
5436
|
+
c.agent_response ?? null,
|
|
5437
|
+
c.agent_name ?? null,
|
|
5438
|
+
c.timestamp,
|
|
5439
|
+
c.ingested_at
|
|
5440
|
+
]
|
|
5441
|
+
}));
|
|
5442
|
+
await client.batch(stmts, "write");
|
|
5443
|
+
return { pulled: remoteConvos.length };
|
|
5444
|
+
}
|
|
5445
|
+
async function cloudPushDocuments(config) {
|
|
5446
|
+
const client = getClient();
|
|
5447
|
+
const [workspaces, documents] = await Promise.all([
|
|
5448
|
+
client.execute("SELECT * FROM workspaces"),
|
|
5449
|
+
client.execute("SELECT * FROM documents")
|
|
5450
|
+
]);
|
|
5451
|
+
const blob = {
|
|
5452
|
+
workspaces: workspaces.rows,
|
|
5453
|
+
documents: documents.rows
|
|
5454
|
+
};
|
|
5455
|
+
const { ok } = await cloudPushBlob(
|
|
5456
|
+
"/sync/push-documents",
|
|
5457
|
+
[blob],
|
|
5458
|
+
"last_documents_push_version",
|
|
5459
|
+
config
|
|
5460
|
+
);
|
|
5461
|
+
return ok;
|
|
5462
|
+
}
|
|
5463
|
+
async function cloudPullDocuments(config) {
|
|
5464
|
+
const data = await cloudPullBlob(
|
|
5465
|
+
"/sync/pull-documents",
|
|
5466
|
+
config
|
|
5467
|
+
);
|
|
5468
|
+
if (!data || data.length === 0) return { pulled: 0 };
|
|
5469
|
+
const blob = data[0];
|
|
5470
|
+
const client = getClient();
|
|
5471
|
+
let pulled = 0;
|
|
5472
|
+
if (blob.workspaces.length > 0) {
|
|
5473
|
+
const stmts = blob.workspaces.map((w) => ({
|
|
5474
|
+
sql: `INSERT OR IGNORE INTO workspaces (id, slug, name, owner_agent_id, created_at, metadata)
|
|
5475
|
+
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
5476
|
+
args: [w.id, w.slug, w.name, w.owner_agent_id ?? null, w.created_at, w.metadata ?? null]
|
|
5477
|
+
}));
|
|
5478
|
+
await client.batch(stmts, "write");
|
|
5479
|
+
pulled += stmts.length;
|
|
5480
|
+
}
|
|
5481
|
+
if (blob.documents.length > 0) {
|
|
5482
|
+
const stmts = blob.documents.map((d) => ({
|
|
5483
|
+
sql: `INSERT OR IGNORE INTO documents
|
|
5484
|
+
(id, workspace_id, filename, mime, source_type, user_id, uploaded_at, metadata)
|
|
5485
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5486
|
+
args: [
|
|
5487
|
+
d.id,
|
|
5488
|
+
d.workspace_id,
|
|
5489
|
+
d.filename,
|
|
5490
|
+
d.mime ?? null,
|
|
5491
|
+
d.source_type ?? null,
|
|
5492
|
+
d.user_id ?? null,
|
|
5493
|
+
d.uploaded_at,
|
|
5494
|
+
d.metadata ?? null
|
|
5495
|
+
]
|
|
5496
|
+
}));
|
|
5497
|
+
await client.batch(stmts, "write");
|
|
5498
|
+
pulled += stmts.length;
|
|
5499
|
+
}
|
|
5500
|
+
return { pulled };
|
|
5501
|
+
}
|
|
5502
|
+
var LOCALHOST_PATTERNS, FETCH_TIMEOUT_MS;
|
|
4973
5503
|
var init_cloud_sync = __esm({
|
|
4974
5504
|
"src/lib/cloud-sync.ts"() {
|
|
4975
5505
|
"use strict";
|
|
@@ -4981,6 +5511,7 @@ var init_cloud_sync = __esm({
|
|
|
4981
5511
|
init_config();
|
|
4982
5512
|
init_employees();
|
|
4983
5513
|
LOCALHOST_PATTERNS = /^(localhost|127\.0\.0\.1|\[::1\])$/i;
|
|
5514
|
+
FETCH_TIMEOUT_MS = 3e4;
|
|
4984
5515
|
}
|
|
4985
5516
|
});
|
|
4986
5517
|
|
|
@@ -5164,7 +5695,7 @@ var init_schedules = __esm({
|
|
|
5164
5695
|
init_employees();
|
|
5165
5696
|
import path19 from "path";
|
|
5166
5697
|
import { mkdir as mkdir5, writeFile as writeFile6 } from "fs/promises";
|
|
5167
|
-
import { existsSync as existsSync15, readFileSync as readFileSync13, readdirSync as readdirSync6, unlinkSync as
|
|
5698
|
+
import { existsSync as existsSync15, readFileSync as readFileSync13, readdirSync as readdirSync6, unlinkSync as unlinkSync6 } from "fs";
|
|
5168
5699
|
import os6 from "os";
|
|
5169
5700
|
|
|
5170
5701
|
// src/lib/employee-templates.ts
|
|
@@ -5721,7 +6252,7 @@ async function boot(options) {
|
|
|
5721
6252
|
for (const f of readdirSync6(exeExeDir)) {
|
|
5722
6253
|
if (f.startsWith("review-") && f.endsWith(".md")) {
|
|
5723
6254
|
try {
|
|
5724
|
-
|
|
6255
|
+
unlinkSync6(path19.join(exeExeDir, f));
|
|
5725
6256
|
} catch {
|
|
5726
6257
|
}
|
|
5727
6258
|
}
|
|
@@ -6323,8 +6854,8 @@ async function boot(options) {
|
|
|
6323
6854
|
try {
|
|
6324
6855
|
const flagPath = path19.join(EXE_AI_DIR, "session-cache", "needs-backfill");
|
|
6325
6856
|
if (existsSync15(flagPath)) {
|
|
6326
|
-
const { unlinkSync:
|
|
6327
|
-
|
|
6857
|
+
const { unlinkSync: unlinkSync7 } = await import("fs");
|
|
6858
|
+
unlinkSync7(flagPath);
|
|
6328
6859
|
}
|
|
6329
6860
|
} catch {
|
|
6330
6861
|
}
|