@askexenow/exe-os 0.9.65 → 0.9.66
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/stack-manifests/v0.9.json +4 -4
- package/dist/bin/backfill-conversations.js +22 -0
- package/dist/bin/backfill-responses.js +22 -0
- package/dist/bin/backfill-vectors.js +22 -0
- package/dist/bin/cleanup-stale-review-tasks.js +22 -0
- package/dist/bin/cli.js +2263 -1203
- package/dist/bin/exe-agent-config.js +4 -0
- package/dist/bin/exe-agent.js +16 -0
- package/dist/bin/exe-assign.js +22 -0
- package/dist/bin/exe-boot.js +93 -5
- package/dist/bin/exe-call.js +16 -0
- package/dist/bin/exe-cloud.js +6671 -464
- package/dist/bin/exe-dispatch.js +24 -0
- package/dist/bin/exe-doctor.js +2845 -1223
- package/dist/bin/exe-export-behaviors.js +24 -0
- package/dist/bin/exe-forget.js +22 -0
- package/dist/bin/exe-gateway.js +24 -0
- package/dist/bin/exe-heartbeat.js +23 -0
- package/dist/bin/exe-kill.js +22 -0
- package/dist/bin/exe-launch-agent.js +24 -0
- package/dist/bin/exe-link.js +287 -176
- package/dist/bin/exe-new-employee.js +127 -1
- package/dist/bin/exe-pending-messages.js +22 -0
- package/dist/bin/exe-pending-notifications.js +22 -0
- package/dist/bin/exe-pending-reviews.js +22 -0
- package/dist/bin/exe-rename.js +22 -0
- package/dist/bin/exe-review.js +22 -0
- package/dist/bin/exe-search.js +24 -0
- package/dist/bin/exe-session-cleanup.js +24 -0
- package/dist/bin/exe-settings.js +10 -0
- package/dist/bin/exe-start-codex.js +135 -1
- package/dist/bin/exe-start-opencode.js +149 -1
- package/dist/bin/exe-status.js +22 -0
- package/dist/bin/exe-team.js +22 -0
- package/dist/bin/git-sweep.js +24 -0
- package/dist/bin/graph-backfill.js +22 -0
- package/dist/bin/graph-export.js +22 -0
- package/dist/bin/install.js +115 -1
- package/dist/bin/intercom-check.js +24 -0
- package/dist/bin/scan-tasks.js +24 -0
- package/dist/bin/setup.js +389 -155
- package/dist/bin/shard-migrate.js +22 -0
- package/dist/bin/update.js +4 -0
- package/dist/gateway/index.js +24 -0
- package/dist/hooks/bug-report-worker.js +135 -42
- package/dist/hooks/codex-stop-task-finalizer.js +24 -0
- package/dist/hooks/commit-complete.js +24 -0
- package/dist/hooks/error-recall.js +24 -0
- package/dist/hooks/exe-heartbeat-hook.js +4 -0
- package/dist/hooks/ingest-worker.js +4 -0
- package/dist/hooks/ingest.js +23 -0
- package/dist/hooks/instructions-loaded.js +22 -0
- package/dist/hooks/notification.js +22 -0
- package/dist/hooks/post-compact.js +22 -0
- package/dist/hooks/post-tool-combined.js +24 -0
- package/dist/hooks/pre-compact.js +260 -109
- package/dist/hooks/pre-tool-use.js +22 -0
- package/dist/hooks/prompt-submit.js +24 -0
- package/dist/hooks/session-end.js +161 -122
- package/dist/hooks/session-start.js +142 -0
- package/dist/hooks/stop.js +23 -0
- package/dist/hooks/subagent-stop.js +22 -0
- package/dist/hooks/summary-worker.js +172 -77
- package/dist/index.js +24 -0
- package/dist/lib/agent-config.js +4 -0
- package/dist/lib/cloud-sync.js +27 -4
- package/dist/lib/config.js +12 -0
- package/dist/lib/consolidation.js +4 -0
- package/dist/lib/database.js +4 -0
- package/dist/lib/db-daemon-client.js +4 -0
- package/dist/lib/db.js +4 -0
- package/dist/lib/device-registry.js +4 -0
- package/dist/lib/embedder.js +12 -0
- package/dist/lib/employee-templates.js +16 -0
- package/dist/lib/employees.js +4 -0
- package/dist/lib/exe-daemon-client.js +4 -0
- package/dist/lib/exe-daemon.js +1058 -453
- package/dist/lib/hybrid-search.js +24 -0
- package/dist/lib/identity.js +4 -0
- package/dist/lib/license.js +4 -0
- package/dist/lib/messaging.js +4 -0
- package/dist/lib/reminders.js +4 -0
- package/dist/lib/schedules.js +22 -0
- package/dist/lib/skill-learning.js +12 -0
- package/dist/lib/status-brief.js +39 -0
- package/dist/lib/store.js +22 -0
- package/dist/lib/task-router.js +4 -0
- package/dist/lib/tasks.js +12 -0
- package/dist/lib/tmux-routing.js +12 -0
- package/dist/lib/token-spend.js +4 -0
- package/dist/mcp/server.js +1022 -425
- package/dist/mcp/tools/complete-reminder.js +4 -0
- package/dist/mcp/tools/create-reminder.js +4 -0
- package/dist/mcp/tools/create-task.js +12 -0
- package/dist/mcp/tools/deactivate-behavior.js +4 -0
- package/dist/mcp/tools/list-reminders.js +4 -0
- package/dist/mcp/tools/list-tasks.js +4 -0
- package/dist/mcp/tools/send-message.js +4 -0
- package/dist/mcp/tools/update-task.js +12 -0
- package/dist/runtime/index.js +24 -0
- package/dist/tui/App.js +24 -0
- package/package.json +3 -2
- package/src/commands/exe/cloud.md +15 -8
- package/src/commands/exe/link.md +7 -6
- package/stack.release.json +2 -2
package/dist/hooks/stop.js
CHANGED
|
@@ -134,6 +134,11 @@ function normalizeAutoUpdate(raw) {
|
|
|
134
134
|
const userAU = raw.autoUpdate ?? {};
|
|
135
135
|
raw.autoUpdate = { ...defaultAU, ...userAU };
|
|
136
136
|
}
|
|
137
|
+
function normalizeOrchestration(raw) {
|
|
138
|
+
const defaultOrg = DEFAULT_CONFIG.orchestration;
|
|
139
|
+
const userOrg = raw.orchestration ?? {};
|
|
140
|
+
raw.orchestration = { ...defaultOrg, ...userOrg };
|
|
141
|
+
}
|
|
137
142
|
async function loadConfig() {
|
|
138
143
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
139
144
|
await ensurePrivateDir(dir);
|
|
@@ -158,6 +163,7 @@ async function loadConfig() {
|
|
|
158
163
|
normalizeScalingRoadmap(migratedCfg);
|
|
159
164
|
normalizeSessionLifecycle(migratedCfg);
|
|
160
165
|
normalizeAutoUpdate(migratedCfg);
|
|
166
|
+
normalizeOrchestration(migratedCfg);
|
|
161
167
|
const config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
|
|
162
168
|
if (config.dbPath.startsWith("~")) {
|
|
163
169
|
config.dbPath = config.dbPath.replace(/^~/, os.homedir());
|
|
@@ -181,6 +187,7 @@ function loadConfigSync() {
|
|
|
181
187
|
normalizeScalingRoadmap(migratedCfg);
|
|
182
188
|
normalizeSessionLifecycle(migratedCfg);
|
|
183
189
|
normalizeAutoUpdate(migratedCfg);
|
|
190
|
+
normalizeOrchestration(migratedCfg);
|
|
184
191
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
|
|
185
192
|
} catch {
|
|
186
193
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
|
|
@@ -252,6 +259,10 @@ var init_config = __esm({
|
|
|
252
259
|
checkOnBoot: true,
|
|
253
260
|
autoInstall: false,
|
|
254
261
|
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
262
|
+
},
|
|
263
|
+
orchestration: {
|
|
264
|
+
phase: "phase_1_coo",
|
|
265
|
+
phaseSetBy: "default"
|
|
255
266
|
}
|
|
256
267
|
};
|
|
257
268
|
CONFIG_MIGRATIONS = [
|
|
@@ -4304,6 +4315,12 @@ var init_platform_procedures = __esm({
|
|
|
4304
4315
|
priority: "p0",
|
|
4305
4316
|
content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
|
|
4306
4317
|
},
|
|
4318
|
+
{
|
|
4319
|
+
title: "Customer orchestration maturity \u2014 recommend, never trap",
|
|
4320
|
+
domain: "workflow",
|
|
4321
|
+
priority: "p1",
|
|
4322
|
+
content: "New customers start best in Phase 1: founder \u2194 coordinator/Chief of Staff, building company context. Suggest Phase 2 executives when domain work repeats; suggest Phase 3 parallel execution only when review/permission gates are ready. This is guidance, not a blocker: users may jump phases anytime. Never overwrite their phase, role titles, identities, or custom org design."
|
|
4323
|
+
},
|
|
4307
4324
|
{
|
|
4308
4325
|
title: "Single dispatch path \u2014 create_task only",
|
|
4309
4326
|
domain: "workflow",
|
|
@@ -4362,6 +4379,12 @@ var init_platform_procedures = __esm({
|
|
|
4362
4379
|
priority: "p0",
|
|
4363
4380
|
content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
|
|
4364
4381
|
},
|
|
4382
|
+
{
|
|
4383
|
+
title: "Commit discipline \u2014 never leave verified work floating",
|
|
4384
|
+
domain: "workflow",
|
|
4385
|
+
priority: "p1",
|
|
4386
|
+
content: "After any code-change batch passes typecheck/tests/build, run git status, summarize changed files, and commit with a clear message before ending the session. If work must remain uncommitted for review/dogfood, explicitly say so, list the files, and state the blocker. Never imply work is complete while verified changes are still floating locally."
|
|
4387
|
+
},
|
|
4365
4388
|
{
|
|
4366
4389
|
title: "Desktop and TUI are the same product",
|
|
4367
4390
|
domain: "architecture",
|
|
@@ -134,6 +134,11 @@ function normalizeAutoUpdate(raw) {
|
|
|
134
134
|
const userAU = raw.autoUpdate ?? {};
|
|
135
135
|
raw.autoUpdate = { ...defaultAU, ...userAU };
|
|
136
136
|
}
|
|
137
|
+
function normalizeOrchestration(raw) {
|
|
138
|
+
const defaultOrg = DEFAULT_CONFIG.orchestration;
|
|
139
|
+
const userOrg = raw.orchestration ?? {};
|
|
140
|
+
raw.orchestration = { ...defaultOrg, ...userOrg };
|
|
141
|
+
}
|
|
137
142
|
async function loadConfig() {
|
|
138
143
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
139
144
|
await ensurePrivateDir(dir);
|
|
@@ -158,6 +163,7 @@ async function loadConfig() {
|
|
|
158
163
|
normalizeScalingRoadmap(migratedCfg);
|
|
159
164
|
normalizeSessionLifecycle(migratedCfg);
|
|
160
165
|
normalizeAutoUpdate(migratedCfg);
|
|
166
|
+
normalizeOrchestration(migratedCfg);
|
|
161
167
|
const config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
|
|
162
168
|
if (config.dbPath.startsWith("~")) {
|
|
163
169
|
config.dbPath = config.dbPath.replace(/^~/, os.homedir());
|
|
@@ -233,6 +239,10 @@ var init_config = __esm({
|
|
|
233
239
|
checkOnBoot: true,
|
|
234
240
|
autoInstall: false,
|
|
235
241
|
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
242
|
+
},
|
|
243
|
+
orchestration: {
|
|
244
|
+
phase: "phase_1_coo",
|
|
245
|
+
phaseSetBy: "default"
|
|
236
246
|
}
|
|
237
247
|
};
|
|
238
248
|
CONFIG_MIGRATIONS = [
|
|
@@ -4285,6 +4295,12 @@ var init_platform_procedures = __esm({
|
|
|
4285
4295
|
priority: "p0",
|
|
4286
4296
|
content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
|
|
4287
4297
|
},
|
|
4298
|
+
{
|
|
4299
|
+
title: "Customer orchestration maturity \u2014 recommend, never trap",
|
|
4300
|
+
domain: "workflow",
|
|
4301
|
+
priority: "p1",
|
|
4302
|
+
content: "New customers start best in Phase 1: founder \u2194 coordinator/Chief of Staff, building company context. Suggest Phase 2 executives when domain work repeats; suggest Phase 3 parallel execution only when review/permission gates are ready. This is guidance, not a blocker: users may jump phases anytime. Never overwrite their phase, role titles, identities, or custom org design."
|
|
4303
|
+
},
|
|
4288
4304
|
{
|
|
4289
4305
|
title: "Single dispatch path \u2014 create_task only",
|
|
4290
4306
|
domain: "workflow",
|
|
@@ -4343,6 +4359,12 @@ var init_platform_procedures = __esm({
|
|
|
4343
4359
|
priority: "p0",
|
|
4344
4360
|
content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
|
|
4345
4361
|
},
|
|
4362
|
+
{
|
|
4363
|
+
title: "Commit discipline \u2014 never leave verified work floating",
|
|
4364
|
+
domain: "workflow",
|
|
4365
|
+
priority: "p1",
|
|
4366
|
+
content: "After any code-change batch passes typecheck/tests/build, run git status, summarize changed files, and commit with a clear message before ending the session. If work must remain uncommitted for review/dogfood, explicitly say so, list the files, and state the blocker. Never imply work is complete while verified changes are still floating locally."
|
|
4367
|
+
},
|
|
4346
4368
|
{
|
|
4347
4369
|
title: "Desktop and TUI are the same product",
|
|
4348
4370
|
domain: "architecture",
|
|
@@ -213,6 +213,11 @@ function normalizeAutoUpdate(raw) {
|
|
|
213
213
|
const userAU = raw.autoUpdate ?? {};
|
|
214
214
|
raw.autoUpdate = { ...defaultAU, ...userAU };
|
|
215
215
|
}
|
|
216
|
+
function normalizeOrchestration(raw) {
|
|
217
|
+
const defaultOrg = DEFAULT_CONFIG.orchestration;
|
|
218
|
+
const userOrg = raw.orchestration ?? {};
|
|
219
|
+
raw.orchestration = { ...defaultOrg, ...userOrg };
|
|
220
|
+
}
|
|
216
221
|
async function loadConfig() {
|
|
217
222
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
218
223
|
await ensurePrivateDir(dir);
|
|
@@ -237,6 +242,7 @@ async function loadConfig() {
|
|
|
237
242
|
normalizeScalingRoadmap(migratedCfg);
|
|
238
243
|
normalizeSessionLifecycle(migratedCfg);
|
|
239
244
|
normalizeAutoUpdate(migratedCfg);
|
|
245
|
+
normalizeOrchestration(migratedCfg);
|
|
240
246
|
const config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
|
|
241
247
|
if (config.dbPath.startsWith("~")) {
|
|
242
248
|
config.dbPath = config.dbPath.replace(/^~/, os.homedir());
|
|
@@ -260,6 +266,7 @@ function loadConfigSync() {
|
|
|
260
266
|
normalizeScalingRoadmap(migratedCfg);
|
|
261
267
|
normalizeSessionLifecycle(migratedCfg);
|
|
262
268
|
normalizeAutoUpdate(migratedCfg);
|
|
269
|
+
normalizeOrchestration(migratedCfg);
|
|
263
270
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
|
|
264
271
|
} catch {
|
|
265
272
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
|
|
@@ -281,6 +288,7 @@ async function loadConfigFrom(configPath) {
|
|
|
281
288
|
normalizeScalingRoadmap(migratedCfg);
|
|
282
289
|
normalizeSessionLifecycle(migratedCfg);
|
|
283
290
|
normalizeAutoUpdate(migratedCfg);
|
|
291
|
+
normalizeOrchestration(migratedCfg);
|
|
284
292
|
return { ...DEFAULT_CONFIG, ...migratedCfg };
|
|
285
293
|
} catch {
|
|
286
294
|
return { ...DEFAULT_CONFIG };
|
|
@@ -352,6 +360,10 @@ var init_config = __esm({
|
|
|
352
360
|
checkOnBoot: true,
|
|
353
361
|
autoInstall: false,
|
|
354
362
|
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
363
|
+
},
|
|
364
|
+
orchestration: {
|
|
365
|
+
phase: "phase_1_coo",
|
|
366
|
+
phaseSetBy: "default"
|
|
355
367
|
}
|
|
356
368
|
};
|
|
357
369
|
CONFIG_MIGRATIONS = [
|
|
@@ -3803,6 +3815,12 @@ var init_platform_procedures = __esm({
|
|
|
3803
3815
|
priority: "p0",
|
|
3804
3816
|
content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
|
|
3805
3817
|
},
|
|
3818
|
+
{
|
|
3819
|
+
title: "Customer orchestration maturity \u2014 recommend, never trap",
|
|
3820
|
+
domain: "workflow",
|
|
3821
|
+
priority: "p1",
|
|
3822
|
+
content: "New customers start best in Phase 1: founder \u2194 coordinator/Chief of Staff, building company context. Suggest Phase 2 executives when domain work repeats; suggest Phase 3 parallel execution only when review/permission gates are ready. This is guidance, not a blocker: users may jump phases anytime. Never overwrite their phase, role titles, identities, or custom org design."
|
|
3823
|
+
},
|
|
3806
3824
|
{
|
|
3807
3825
|
title: "Single dispatch path \u2014 create_task only",
|
|
3808
3826
|
domain: "workflow",
|
|
@@ -3861,6 +3879,12 @@ var init_platform_procedures = __esm({
|
|
|
3861
3879
|
priority: "p0",
|
|
3862
3880
|
content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
|
|
3863
3881
|
},
|
|
3882
|
+
{
|
|
3883
|
+
title: "Commit discipline \u2014 never leave verified work floating",
|
|
3884
|
+
domain: "workflow",
|
|
3885
|
+
priority: "p1",
|
|
3886
|
+
content: "After any code-change batch passes typecheck/tests/build, run git status, summarize changed files, and commit with a clear message before ending the session. If work must remain uncommitted for review/dogfood, explicitly say so, list the files, and state the blocker. Never imply work is complete while verified changes are still floating locally."
|
|
3887
|
+
},
|
|
3864
3888
|
{
|
|
3865
3889
|
title: "Desktop and TUI are the same product",
|
|
3866
3890
|
domain: "architecture",
|
|
@@ -5638,8 +5662,10 @@ var init_db_backup = __esm({
|
|
|
5638
5662
|
// src/lib/cloud-sync.ts
|
|
5639
5663
|
var cloud_sync_exports = {};
|
|
5640
5664
|
__export(cloud_sync_exports, {
|
|
5665
|
+
CLOUD_RELINK_REQUIRED_MESSAGE: () => CLOUD_RELINK_REQUIRED_MESSAGE,
|
|
5641
5666
|
assertSecureEndpoint: () => assertSecureEndpoint,
|
|
5642
5667
|
buildRosterBlob: () => buildRosterBlob,
|
|
5668
|
+
clearCloudRelinkRequired: () => clearCloudRelinkRequired,
|
|
5643
5669
|
cloudPull: () => cloudPull,
|
|
5644
5670
|
cloudPullBehaviors: () => cloudPullBehaviors,
|
|
5645
5671
|
cloudPullBlob: () => cloudPullBlob,
|
|
@@ -5659,6 +5685,7 @@ __export(cloud_sync_exports, {
|
|
|
5659
5685
|
cloudPushRoster: () => cloudPushRoster,
|
|
5660
5686
|
cloudPushTasks: () => cloudPushTasks,
|
|
5661
5687
|
cloudSync: () => cloudSync,
|
|
5688
|
+
getCloudRelinkRequired: () => getCloudRelinkRequired,
|
|
5662
5689
|
mergeConfig: () => mergeConfig,
|
|
5663
5690
|
mergeRosterFromRemote: () => mergeRosterFromRemote,
|
|
5664
5691
|
pushToPostgres: () => pushToPostgres,
|
|
@@ -5892,6 +5919,24 @@ async function cloudPull(sinceVersion, config) {
|
|
|
5892
5919
|
return { records: [], maxVersion: sinceVersion };
|
|
5893
5920
|
}
|
|
5894
5921
|
}
|
|
5922
|
+
async function getCloudRelinkRequired(client = getClient()) {
|
|
5923
|
+
try {
|
|
5924
|
+
await client.execute("CREATE TABLE IF NOT EXISTS sync_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)");
|
|
5925
|
+
const relink = await client.execute("SELECT value FROM sync_meta WHERE key = 'cloud_relink_required' LIMIT 1");
|
|
5926
|
+
return String(relink.rows[0]?.value ?? "") === "1";
|
|
5927
|
+
} catch {
|
|
5928
|
+
return false;
|
|
5929
|
+
}
|
|
5930
|
+
}
|
|
5931
|
+
async function clearCloudRelinkRequired(client = getClient()) {
|
|
5932
|
+
await client.execute("CREATE TABLE IF NOT EXISTS sync_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)");
|
|
5933
|
+
await client.execute("INSERT OR REPLACE INTO sync_meta (key, value) VALUES ('cloud_relink_required', '0')");
|
|
5934
|
+
await client.execute({
|
|
5935
|
+
sql: "INSERT OR REPLACE INTO sync_meta (key, value) VALUES ('cloud_relinked_at', ?)",
|
|
5936
|
+
args: [(/* @__PURE__ */ new Date()).toISOString()]
|
|
5937
|
+
});
|
|
5938
|
+
await client.execute("DELETE FROM sync_meta WHERE key IN ('last_cloud_pull_version', 'last_cloud_push_version')");
|
|
5939
|
+
}
|
|
5895
5940
|
async function cloudSync(config) {
|
|
5896
5941
|
if (!isSyncCryptoInitialized()) {
|
|
5897
5942
|
try {
|
|
@@ -5913,10 +5958,7 @@ async function cloudSync(config) {
|
|
|
5913
5958
|
throw new Error("[cloud-sync] Database not initialized. Call initStore() before cloudSync().");
|
|
5914
5959
|
}
|
|
5915
5960
|
try {
|
|
5916
|
-
|
|
5917
|
-
if (String(relink.rows[0]?.value ?? "") === "1") {
|
|
5918
|
-
throw new Error("[cloud-sync] Paused after key rotation. Re-link/reupload cloud sync with the new recovery phrase before syncing.");
|
|
5919
|
-
}
|
|
5961
|
+
if (await getCloudRelinkRequired(client)) throw new Error(CLOUD_RELINK_REQUIRED_MESSAGE);
|
|
5920
5962
|
} catch (err) {
|
|
5921
5963
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5922
5964
|
if (msg.includes("Paused after key rotation")) throw err;
|
|
@@ -6848,7 +6890,7 @@ async function cloudPullDocuments(config) {
|
|
|
6848
6890
|
}
|
|
6849
6891
|
return { pulled };
|
|
6850
6892
|
}
|
|
6851
|
-
var LOCALHOST_PATTERNS, FETCH_TIMEOUT_MS, PUSH_BATCH_SIZE, ROSTER_LOCK_PATH, LOCK_STALE_MS, _pgPromise, _pgFailed, ROSTER_DELETIONS_PATH;
|
|
6893
|
+
var LOCALHOST_PATTERNS, FETCH_TIMEOUT_MS, PUSH_BATCH_SIZE, ROSTER_LOCK_PATH, LOCK_STALE_MS, _pgPromise, _pgFailed, CLOUD_RELINK_REQUIRED_MESSAGE, ROSTER_DELETIONS_PATH;
|
|
6852
6894
|
var init_cloud_sync = __esm({
|
|
6853
6895
|
"src/lib/cloud-sync.ts"() {
|
|
6854
6896
|
"use strict";
|
|
@@ -6867,6 +6909,7 @@ var init_cloud_sync = __esm({
|
|
|
6867
6909
|
LOCK_STALE_MS = 3e4;
|
|
6868
6910
|
_pgPromise = null;
|
|
6869
6911
|
_pgFailed = false;
|
|
6912
|
+
CLOUD_RELINK_REQUIRED_MESSAGE = "[cloud-sync] Paused after key rotation. Run `exe-os cloud relink --dry-run` for the safe relink checklist.";
|
|
6870
6913
|
ROSTER_DELETIONS_PATH = path20.join(EXE_AI_DIR, "roster-deletions.json");
|
|
6871
6914
|
}
|
|
6872
6915
|
});
|
|
@@ -6973,46 +7016,6 @@ function vectorToBlob(vector) {
|
|
|
6973
7016
|
// src/adapters/claude/hooks/summary-worker.ts
|
|
6974
7017
|
init_database();
|
|
6975
7018
|
init_notifications();
|
|
6976
|
-
|
|
6977
|
-
// src/lib/memory-queue-client.ts
|
|
6978
|
-
init_exe_daemon_client();
|
|
6979
|
-
|
|
6980
|
-
// src/lib/memory-queue.ts
|
|
6981
|
-
init_config();
|
|
6982
|
-
import { appendFileSync as appendFileSync2, readFileSync as readFileSync11, renameSync as renameSync5, unlinkSync as unlinkSync4, existsSync as existsSync15, statSync as statSync3 } from "fs";
|
|
6983
|
-
import path16 from "path";
|
|
6984
|
-
var QUEUE_PATH2 = path16.join(EXE_AI_DIR, "memory-queue.jsonl");
|
|
6985
|
-
var PROCESSING_PATH = QUEUE_PATH2 + ".processing";
|
|
6986
|
-
var TTL_MS2 = 24 * 60 * 60 * 1e3;
|
|
6987
|
-
function enqueueMemory(entry) {
|
|
6988
|
-
appendFileSync2(QUEUE_PATH2, JSON.stringify(entry) + "\n");
|
|
6989
|
-
}
|
|
6990
|
-
|
|
6991
|
-
// src/lib/memory-queue-client.ts
|
|
6992
|
-
async function writeMemoryViaDaemon(entry) {
|
|
6993
|
-
if (process.env.EXE_IS_DAEMON === "1") {
|
|
6994
|
-
enqueueMemory(entry);
|
|
6995
|
-
return false;
|
|
6996
|
-
}
|
|
6997
|
-
if (!isClientConnected()) {
|
|
6998
|
-
enqueueMemory(entry);
|
|
6999
|
-
return false;
|
|
7000
|
-
}
|
|
7001
|
-
try {
|
|
7002
|
-
const response = await sendDaemonRequest({
|
|
7003
|
-
type: "write-memory",
|
|
7004
|
-
entry
|
|
7005
|
-
});
|
|
7006
|
-
if (response.ok) return true;
|
|
7007
|
-
enqueueMemory(entry);
|
|
7008
|
-
return false;
|
|
7009
|
-
} catch {
|
|
7010
|
-
enqueueMemory(entry);
|
|
7011
|
-
return false;
|
|
7012
|
-
}
|
|
7013
|
-
}
|
|
7014
|
-
|
|
7015
|
-
// src/adapters/claude/hooks/summary-worker.ts
|
|
7016
7019
|
init_task_scope();
|
|
7017
7020
|
init_employees();
|
|
7018
7021
|
import { execSync as execSync5 } from "child_process";
|
|
@@ -7099,6 +7102,119 @@ function buildAutoCheckpoint(input) {
|
|
|
7099
7102
|
};
|
|
7100
7103
|
}
|
|
7101
7104
|
|
|
7105
|
+
// src/lib/memory-queue-client.ts
|
|
7106
|
+
init_exe_daemon_client();
|
|
7107
|
+
|
|
7108
|
+
// src/lib/memory-queue.ts
|
|
7109
|
+
init_config();
|
|
7110
|
+
import { appendFileSync as appendFileSync2, readFileSync as readFileSync11, renameSync as renameSync5, unlinkSync as unlinkSync4, existsSync as existsSync15, statSync as statSync3 } from "fs";
|
|
7111
|
+
import path16 from "path";
|
|
7112
|
+
var QUEUE_PATH2 = path16.join(EXE_AI_DIR, "memory-queue.jsonl");
|
|
7113
|
+
var PROCESSING_PATH = QUEUE_PATH2 + ".processing";
|
|
7114
|
+
var TTL_MS2 = 24 * 60 * 60 * 1e3;
|
|
7115
|
+
function enqueueMemory(entry) {
|
|
7116
|
+
appendFileSync2(QUEUE_PATH2, JSON.stringify(entry) + "\n");
|
|
7117
|
+
}
|
|
7118
|
+
|
|
7119
|
+
// src/lib/memory-queue-client.ts
|
|
7120
|
+
async function writeMemoryViaDaemon(entry) {
|
|
7121
|
+
if (process.env.EXE_IS_DAEMON === "1") {
|
|
7122
|
+
enqueueMemory(entry);
|
|
7123
|
+
return false;
|
|
7124
|
+
}
|
|
7125
|
+
if (!isClientConnected()) {
|
|
7126
|
+
enqueueMemory(entry);
|
|
7127
|
+
return false;
|
|
7128
|
+
}
|
|
7129
|
+
try {
|
|
7130
|
+
const response = await sendDaemonRequest({
|
|
7131
|
+
type: "write-memory",
|
|
7132
|
+
entry
|
|
7133
|
+
});
|
|
7134
|
+
if (response.ok) return true;
|
|
7135
|
+
enqueueMemory(entry);
|
|
7136
|
+
return false;
|
|
7137
|
+
} catch {
|
|
7138
|
+
enqueueMemory(entry);
|
|
7139
|
+
return false;
|
|
7140
|
+
}
|
|
7141
|
+
}
|
|
7142
|
+
|
|
7143
|
+
// src/lib/checkpoint-orchestrator.ts
|
|
7144
|
+
function toolNameForReason(reason) {
|
|
7145
|
+
switch (reason) {
|
|
7146
|
+
case "periodic":
|
|
7147
|
+
return "auto-summary";
|
|
7148
|
+
case "session-end":
|
|
7149
|
+
return "SessionEnd";
|
|
7150
|
+
case "pre-compact":
|
|
7151
|
+
return "pre-compact-hook";
|
|
7152
|
+
case "capacity-signal":
|
|
7153
|
+
return "auto-checkpoint";
|
|
7154
|
+
}
|
|
7155
|
+
}
|
|
7156
|
+
function importanceForReason(reason, override) {
|
|
7157
|
+
if (override !== void 0) return override;
|
|
7158
|
+
switch (reason) {
|
|
7159
|
+
case "periodic":
|
|
7160
|
+
return 7;
|
|
7161
|
+
case "session-end":
|
|
7162
|
+
case "pre-compact":
|
|
7163
|
+
case "capacity-signal":
|
|
7164
|
+
return 8;
|
|
7165
|
+
}
|
|
7166
|
+
}
|
|
7167
|
+
function buildContinuityCheckpoint(input) {
|
|
7168
|
+
const { checkpointText, decisionTexts } = buildAutoCheckpoint({
|
|
7169
|
+
agentId: input.agentId,
|
|
7170
|
+
agentRole: input.agentRole,
|
|
7171
|
+
sessionId: input.sessionId,
|
|
7172
|
+
projectName: input.projectName,
|
|
7173
|
+
reason: input.reason,
|
|
7174
|
+
memories: input.memories ?? [],
|
|
7175
|
+
tasks: input.tasks ?? [],
|
|
7176
|
+
maxSamples: input.maxSamples
|
|
7177
|
+
});
|
|
7178
|
+
const extra = input.extraSections?.filter((section) => section.trim().length > 0) ?? [];
|
|
7179
|
+
return {
|
|
7180
|
+
checkpointText: extra.length > 0 ? `${checkpointText}
|
|
7181
|
+
|
|
7182
|
+
${extra.join("\n\n")}` : checkpointText,
|
|
7183
|
+
decisionTexts
|
|
7184
|
+
};
|
|
7185
|
+
}
|
|
7186
|
+
async function writeContinuityCheckpoint(input) {
|
|
7187
|
+
const result = buildContinuityCheckpoint(input);
|
|
7188
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
7189
|
+
await writeMemoryViaDaemon({
|
|
7190
|
+
raw_text: result.checkpointText,
|
|
7191
|
+
agent_id: input.agentId,
|
|
7192
|
+
agent_role: input.agentRole,
|
|
7193
|
+
session_id: input.sessionId,
|
|
7194
|
+
tool_name: toolNameForReason(input.reason),
|
|
7195
|
+
project_name: input.projectName,
|
|
7196
|
+
timestamp: now,
|
|
7197
|
+
importance: importanceForReason(input.reason, input.importance),
|
|
7198
|
+
task_id: input.taskId,
|
|
7199
|
+
memory_type: "checkpoint"
|
|
7200
|
+
});
|
|
7201
|
+
const decisionLimit = input.reason === "periodic" ? 3 : 5;
|
|
7202
|
+
for (const decisionText of result.decisionTexts.slice(0, decisionLimit)) {
|
|
7203
|
+
await writeMemoryViaDaemon({
|
|
7204
|
+
raw_text: decisionText,
|
|
7205
|
+
agent_id: input.agentId,
|
|
7206
|
+
agent_role: input.agentRole,
|
|
7207
|
+
session_id: input.sessionId,
|
|
7208
|
+
tool_name: "auto-decision",
|
|
7209
|
+
project_name: input.projectName,
|
|
7210
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7211
|
+
importance: 8,
|
|
7212
|
+
memory_type: "decision"
|
|
7213
|
+
});
|
|
7214
|
+
}
|
|
7215
|
+
return result;
|
|
7216
|
+
}
|
|
7217
|
+
|
|
7102
7218
|
// src/adapters/claude/hooks/summary-worker.ts
|
|
7103
7219
|
async function main() {
|
|
7104
7220
|
const agentId = process.env.AGENT_ID ?? "default";
|
|
@@ -7157,15 +7273,8 @@ async function main() {
|
|
|
7157
7273
|
taskRows = tasks.rows;
|
|
7158
7274
|
} catch {
|
|
7159
7275
|
}
|
|
7160
|
-
const
|
|
7161
|
-
|
|
7162
|
-
agentRole,
|
|
7163
|
-
sessionId: `auto-summary-${Date.now()}`,
|
|
7164
|
-
projectName: primaryProject,
|
|
7165
|
-
reason: "periodic",
|
|
7166
|
-
memories: result.rows,
|
|
7167
|
-
tasks: taskRows
|
|
7168
|
-
});
|
|
7276
|
+
const summarySessionId = `auto-summary-${Date.now()}`;
|
|
7277
|
+
let summaryText = "";
|
|
7169
7278
|
let limitReached = false;
|
|
7170
7279
|
try {
|
|
7171
7280
|
const { assertMemoryLimit: assertMemoryLimit2 } = await Promise.resolve().then(() => (init_plan_limits(), plan_limits_exports));
|
|
@@ -7183,30 +7292,16 @@ async function main() {
|
|
|
7183
7292
|
}
|
|
7184
7293
|
if (limitReached) {
|
|
7185
7294
|
} else {
|
|
7186
|
-
await
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
|
|
7194
|
-
importance: 7,
|
|
7195
|
-
memory_type: "checkpoint"
|
|
7295
|
+
const checkpointResult = await writeContinuityCheckpoint({
|
|
7296
|
+
agentId,
|
|
7297
|
+
agentRole,
|
|
7298
|
+
sessionId: summarySessionId,
|
|
7299
|
+
projectName: primaryProject,
|
|
7300
|
+
reason: "periodic",
|
|
7301
|
+
memories: result.rows,
|
|
7302
|
+
tasks: taskRows
|
|
7196
7303
|
});
|
|
7197
|
-
|
|
7198
|
-
await writeMemoryViaDaemon({
|
|
7199
|
-
raw_text: decisionText,
|
|
7200
|
-
agent_id: agentId,
|
|
7201
|
-
agent_role: agentRole,
|
|
7202
|
-
session_id: `auto-decision-${Date.now()}`,
|
|
7203
|
-
tool_name: "auto-decision",
|
|
7204
|
-
project_name: primaryProject,
|
|
7205
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7206
|
-
importance: 8,
|
|
7207
|
-
memory_type: "decision"
|
|
7208
|
-
});
|
|
7209
|
-
}
|
|
7304
|
+
summaryText = checkpointResult.checkpointText;
|
|
7210
7305
|
if (!canCoordinate(agentId, agentRole)) {
|
|
7211
7306
|
let totalErrors = 0;
|
|
7212
7307
|
for (const [, data] of projects) {
|
package/dist/index.js
CHANGED
|
@@ -149,6 +149,11 @@ function normalizeAutoUpdate(raw) {
|
|
|
149
149
|
const userAU = raw.autoUpdate ?? {};
|
|
150
150
|
raw.autoUpdate = { ...defaultAU, ...userAU };
|
|
151
151
|
}
|
|
152
|
+
function normalizeOrchestration(raw) {
|
|
153
|
+
const defaultOrg = DEFAULT_CONFIG.orchestration;
|
|
154
|
+
const userOrg = raw.orchestration ?? {};
|
|
155
|
+
raw.orchestration = { ...defaultOrg, ...userOrg };
|
|
156
|
+
}
|
|
152
157
|
async function loadConfig() {
|
|
153
158
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
154
159
|
await ensurePrivateDir(dir);
|
|
@@ -173,6 +178,7 @@ async function loadConfig() {
|
|
|
173
178
|
normalizeScalingRoadmap(migratedCfg);
|
|
174
179
|
normalizeSessionLifecycle(migratedCfg);
|
|
175
180
|
normalizeAutoUpdate(migratedCfg);
|
|
181
|
+
normalizeOrchestration(migratedCfg);
|
|
176
182
|
const config2 = { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db"), ...migratedCfg };
|
|
177
183
|
if (config2.dbPath.startsWith("~")) {
|
|
178
184
|
config2.dbPath = config2.dbPath.replace(/^~/, os2.homedir());
|
|
@@ -196,6 +202,7 @@ function loadConfigSync() {
|
|
|
196
202
|
normalizeScalingRoadmap(migratedCfg);
|
|
197
203
|
normalizeSessionLifecycle(migratedCfg);
|
|
198
204
|
normalizeAutoUpdate(migratedCfg);
|
|
205
|
+
normalizeOrchestration(migratedCfg);
|
|
199
206
|
return { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db"), ...migratedCfg };
|
|
200
207
|
} catch {
|
|
201
208
|
return { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db") };
|
|
@@ -217,6 +224,7 @@ async function loadConfigFrom(configPath) {
|
|
|
217
224
|
normalizeScalingRoadmap(migratedCfg);
|
|
218
225
|
normalizeSessionLifecycle(migratedCfg);
|
|
219
226
|
normalizeAutoUpdate(migratedCfg);
|
|
227
|
+
normalizeOrchestration(migratedCfg);
|
|
220
228
|
return { ...DEFAULT_CONFIG, ...migratedCfg };
|
|
221
229
|
} catch {
|
|
222
230
|
return { ...DEFAULT_CONFIG };
|
|
@@ -288,6 +296,10 @@ var init_config = __esm({
|
|
|
288
296
|
checkOnBoot: true,
|
|
289
297
|
autoInstall: false,
|
|
290
298
|
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
299
|
+
},
|
|
300
|
+
orchestration: {
|
|
301
|
+
phase: "phase_1_coo",
|
|
302
|
+
phaseSetBy: "default"
|
|
291
303
|
}
|
|
292
304
|
};
|
|
293
305
|
CONFIG_MIGRATIONS = [
|
|
@@ -7891,6 +7903,12 @@ var init_platform_procedures = __esm({
|
|
|
7891
7903
|
priority: "p0",
|
|
7892
7904
|
content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
|
|
7893
7905
|
},
|
|
7906
|
+
{
|
|
7907
|
+
title: "Customer orchestration maturity \u2014 recommend, never trap",
|
|
7908
|
+
domain: "workflow",
|
|
7909
|
+
priority: "p1",
|
|
7910
|
+
content: "New customers start best in Phase 1: founder \u2194 coordinator/Chief of Staff, building company context. Suggest Phase 2 executives when domain work repeats; suggest Phase 3 parallel execution only when review/permission gates are ready. This is guidance, not a blocker: users may jump phases anytime. Never overwrite their phase, role titles, identities, or custom org design."
|
|
7911
|
+
},
|
|
7894
7912
|
{
|
|
7895
7913
|
title: "Single dispatch path \u2014 create_task only",
|
|
7896
7914
|
domain: "workflow",
|
|
@@ -7949,6 +7967,12 @@ var init_platform_procedures = __esm({
|
|
|
7949
7967
|
priority: "p0",
|
|
7950
7968
|
content: "exe-build-adv is MANDATORY for ALL work touching 3+ files. Run /exe-build-adv --auto BEFORE implementation. Pipeline: Spec \u2192 AC \u2192 Tests \u2192 Evaluate \u2192 Fix. No multi-file feature ships without pipeline artifacts. No exceptions \u2014 managers reject work without them."
|
|
7951
7969
|
},
|
|
7970
|
+
{
|
|
7971
|
+
title: "Commit discipline \u2014 never leave verified work floating",
|
|
7972
|
+
domain: "workflow",
|
|
7973
|
+
priority: "p1",
|
|
7974
|
+
content: "After any code-change batch passes typecheck/tests/build, run git status, summarize changed files, and commit with a clear message before ending the session. If work must remain uncommitted for review/dogfood, explicitly say so, list the files, and state the blocker. Never imply work is complete while verified changes are still floating locally."
|
|
7975
|
+
},
|
|
7952
7976
|
{
|
|
7953
7977
|
title: "Desktop and TUI are the same product",
|
|
7954
7978
|
domain: "architecture",
|
package/dist/lib/agent-config.js
CHANGED
package/dist/lib/cloud-sync.js
CHANGED
|
@@ -181,6 +181,10 @@ var init_config = __esm({
|
|
|
181
181
|
checkOnBoot: true,
|
|
182
182
|
autoInstall: false,
|
|
183
183
|
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
184
|
+
},
|
|
185
|
+
orchestration: {
|
|
186
|
+
phase: "phase_1_coo",
|
|
187
|
+
phaseSetBy: "default"
|
|
184
188
|
}
|
|
185
189
|
};
|
|
186
190
|
}
|
|
@@ -3634,6 +3638,25 @@ async function cloudPull(sinceVersion, config) {
|
|
|
3634
3638
|
return { records: [], maxVersion: sinceVersion };
|
|
3635
3639
|
}
|
|
3636
3640
|
}
|
|
3641
|
+
var CLOUD_RELINK_REQUIRED_MESSAGE = "[cloud-sync] Paused after key rotation. Run `exe-os cloud relink --dry-run` for the safe relink checklist.";
|
|
3642
|
+
async function getCloudRelinkRequired(client = getClient()) {
|
|
3643
|
+
try {
|
|
3644
|
+
await client.execute("CREATE TABLE IF NOT EXISTS sync_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)");
|
|
3645
|
+
const relink = await client.execute("SELECT value FROM sync_meta WHERE key = 'cloud_relink_required' LIMIT 1");
|
|
3646
|
+
return String(relink.rows[0]?.value ?? "") === "1";
|
|
3647
|
+
} catch {
|
|
3648
|
+
return false;
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
async function clearCloudRelinkRequired(client = getClient()) {
|
|
3652
|
+
await client.execute("CREATE TABLE IF NOT EXISTS sync_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)");
|
|
3653
|
+
await client.execute("INSERT OR REPLACE INTO sync_meta (key, value) VALUES ('cloud_relink_required', '0')");
|
|
3654
|
+
await client.execute({
|
|
3655
|
+
sql: "INSERT OR REPLACE INTO sync_meta (key, value) VALUES ('cloud_relinked_at', ?)",
|
|
3656
|
+
args: [(/* @__PURE__ */ new Date()).toISOString()]
|
|
3657
|
+
});
|
|
3658
|
+
await client.execute("DELETE FROM sync_meta WHERE key IN ('last_cloud_pull_version', 'last_cloud_push_version')");
|
|
3659
|
+
}
|
|
3637
3660
|
async function cloudSync(config) {
|
|
3638
3661
|
if (!isSyncCryptoInitialized()) {
|
|
3639
3662
|
try {
|
|
@@ -3655,10 +3678,7 @@ async function cloudSync(config) {
|
|
|
3655
3678
|
throw new Error("[cloud-sync] Database not initialized. Call initStore() before cloudSync().");
|
|
3656
3679
|
}
|
|
3657
3680
|
try {
|
|
3658
|
-
|
|
3659
|
-
if (String(relink.rows[0]?.value ?? "") === "1") {
|
|
3660
|
-
throw new Error("[cloud-sync] Paused after key rotation. Re-link/reupload cloud sync with the new recovery phrase before syncing.");
|
|
3661
|
-
}
|
|
3681
|
+
if (await getCloudRelinkRequired(client)) throw new Error(CLOUD_RELINK_REQUIRED_MESSAGE);
|
|
3662
3682
|
} catch (err) {
|
|
3663
3683
|
const msg = err instanceof Error ? err.message : String(err);
|
|
3664
3684
|
if (msg.includes("Paused after key rotation")) throw err;
|
|
@@ -4592,8 +4612,10 @@ async function cloudPullDocuments(config) {
|
|
|
4592
4612
|
return { pulled };
|
|
4593
4613
|
}
|
|
4594
4614
|
export {
|
|
4615
|
+
CLOUD_RELINK_REQUIRED_MESSAGE,
|
|
4595
4616
|
assertSecureEndpoint,
|
|
4596
4617
|
buildRosterBlob,
|
|
4618
|
+
clearCloudRelinkRequired,
|
|
4597
4619
|
cloudPull,
|
|
4598
4620
|
cloudPullBehaviors,
|
|
4599
4621
|
cloudPullBlob,
|
|
@@ -4613,6 +4635,7 @@ export {
|
|
|
4613
4635
|
cloudPushRoster,
|
|
4614
4636
|
cloudPushTasks,
|
|
4615
4637
|
cloudSync,
|
|
4638
|
+
getCloudRelinkRequired,
|
|
4616
4639
|
mergeConfig,
|
|
4617
4640
|
mergeRosterFromRemote,
|
|
4618
4641
|
pushToPostgres,
|