@askexenow/exe-os 0.9.64 → 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 +2280 -1199
- 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 +116 -7
- 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 +310 -178
- 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 +412 -157
- 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 +195 -79
- package/dist/index.js +24 -0
- package/dist/lib/agent-config.js +4 -0
- package/dist/lib/cloud-sync.js +50 -6
- 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 +1144 -480
- 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 +1045 -427
- 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,
|
|
@@ -5679,31 +5706,43 @@ function logError(msg) {
|
|
|
5679
5706
|
} catch {
|
|
5680
5707
|
}
|
|
5681
5708
|
}
|
|
5709
|
+
function isTruthyEnv(value) {
|
|
5710
|
+
return /^(1|true|yes|on)$/i.test(value ?? "");
|
|
5711
|
+
}
|
|
5682
5712
|
function loadPgClient() {
|
|
5683
5713
|
if (_pgFailed) return null;
|
|
5684
|
-
const postgresUrl = process.env.DATABASE_URL;
|
|
5685
5714
|
const configPath = path20.join(EXE_AI_DIR, "config.json");
|
|
5686
5715
|
let cloudPostgresUrl;
|
|
5716
|
+
let configEnabled = false;
|
|
5687
5717
|
try {
|
|
5688
5718
|
if (existsSync19(configPath)) {
|
|
5689
5719
|
const cfg = JSON.parse(readFileSync13(configPath, "utf8"));
|
|
5690
5720
|
cloudPostgresUrl = cfg.cloud?.postgresUrl;
|
|
5691
|
-
|
|
5692
|
-
_pgFailed = true;
|
|
5693
|
-
return null;
|
|
5694
|
-
}
|
|
5721
|
+
configEnabled = cfg.cloud?.syncToPostgres === true;
|
|
5695
5722
|
}
|
|
5696
5723
|
} catch {
|
|
5697
5724
|
}
|
|
5698
|
-
const
|
|
5725
|
+
const envEnabled = isTruthyEnv(process.env.EXE_CLOUD_SYNC_TO_POSTGRES);
|
|
5726
|
+
if (!envEnabled && !configEnabled) {
|
|
5727
|
+
return null;
|
|
5728
|
+
}
|
|
5729
|
+
const url = process.env.DATABASE_URL || cloudPostgresUrl;
|
|
5699
5730
|
if (!url) {
|
|
5700
5731
|
_pgFailed = true;
|
|
5701
5732
|
return null;
|
|
5702
5733
|
}
|
|
5703
5734
|
if (!_pgPromise) {
|
|
5704
5735
|
_pgPromise = (async () => {
|
|
5736
|
+
if (!process.env.DATABASE_URL) process.env.DATABASE_URL = url;
|
|
5705
5737
|
const { createRequire: createRequire3 } = await import("module");
|
|
5706
5738
|
const { pathToFileURL: pathToFileURL3 } = await import("url");
|
|
5739
|
+
const explicitPath = process.env.EXE_OS_PRISMA_CLIENT_PATH;
|
|
5740
|
+
if (explicitPath) {
|
|
5741
|
+
const mod2 = await import(pathToFileURL3(explicitPath).href);
|
|
5742
|
+
const Ctor2 = mod2.PrismaClient ?? mod2.default?.PrismaClient;
|
|
5743
|
+
if (!Ctor2) throw new Error(`No PrismaClient at ${explicitPath}`);
|
|
5744
|
+
return new Ctor2();
|
|
5745
|
+
}
|
|
5707
5746
|
const exeDbRoot = process.env.EXE_DB_ROOT ?? path20.join(homedir2(), "exe-db");
|
|
5708
5747
|
const req = createRequire3(path20.join(exeDbRoot, "package.json"));
|
|
5709
5748
|
const entry = req.resolve("@prisma/client");
|
|
@@ -5880,6 +5919,24 @@ async function cloudPull(sinceVersion, config) {
|
|
|
5880
5919
|
return { records: [], maxVersion: sinceVersion };
|
|
5881
5920
|
}
|
|
5882
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
|
+
}
|
|
5883
5940
|
async function cloudSync(config) {
|
|
5884
5941
|
if (!isSyncCryptoInitialized()) {
|
|
5885
5942
|
try {
|
|
@@ -5900,6 +5957,12 @@ async function cloudSync(config) {
|
|
|
5900
5957
|
} catch {
|
|
5901
5958
|
throw new Error("[cloud-sync] Database not initialized. Call initStore() before cloudSync().");
|
|
5902
5959
|
}
|
|
5960
|
+
try {
|
|
5961
|
+
if (await getCloudRelinkRequired(client)) throw new Error(CLOUD_RELINK_REQUIRED_MESSAGE);
|
|
5962
|
+
} catch (err) {
|
|
5963
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
5964
|
+
if (msg.includes("Paused after key rotation")) throw err;
|
|
5965
|
+
}
|
|
5903
5966
|
try {
|
|
5904
5967
|
const { getRawClient: getRawClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
5905
5968
|
await getRawClient2().execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
@@ -6827,7 +6890,7 @@ async function cloudPullDocuments(config) {
|
|
|
6827
6890
|
}
|
|
6828
6891
|
return { pulled };
|
|
6829
6892
|
}
|
|
6830
|
-
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;
|
|
6831
6894
|
var init_cloud_sync = __esm({
|
|
6832
6895
|
"src/lib/cloud-sync.ts"() {
|
|
6833
6896
|
"use strict";
|
|
@@ -6846,6 +6909,7 @@ var init_cloud_sync = __esm({
|
|
|
6846
6909
|
LOCK_STALE_MS = 3e4;
|
|
6847
6910
|
_pgPromise = null;
|
|
6848
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.";
|
|
6849
6913
|
ROSTER_DELETIONS_PATH = path20.join(EXE_AI_DIR, "roster-deletions.json");
|
|
6850
6914
|
}
|
|
6851
6915
|
});
|
|
@@ -6952,46 +7016,6 @@ function vectorToBlob(vector) {
|
|
|
6952
7016
|
// src/adapters/claude/hooks/summary-worker.ts
|
|
6953
7017
|
init_database();
|
|
6954
7018
|
init_notifications();
|
|
6955
|
-
|
|
6956
|
-
// src/lib/memory-queue-client.ts
|
|
6957
|
-
init_exe_daemon_client();
|
|
6958
|
-
|
|
6959
|
-
// src/lib/memory-queue.ts
|
|
6960
|
-
init_config();
|
|
6961
|
-
import { appendFileSync as appendFileSync2, readFileSync as readFileSync11, renameSync as renameSync5, unlinkSync as unlinkSync4, existsSync as existsSync15, statSync as statSync3 } from "fs";
|
|
6962
|
-
import path16 from "path";
|
|
6963
|
-
var QUEUE_PATH2 = path16.join(EXE_AI_DIR, "memory-queue.jsonl");
|
|
6964
|
-
var PROCESSING_PATH = QUEUE_PATH2 + ".processing";
|
|
6965
|
-
var TTL_MS2 = 24 * 60 * 60 * 1e3;
|
|
6966
|
-
function enqueueMemory(entry) {
|
|
6967
|
-
appendFileSync2(QUEUE_PATH2, JSON.stringify(entry) + "\n");
|
|
6968
|
-
}
|
|
6969
|
-
|
|
6970
|
-
// src/lib/memory-queue-client.ts
|
|
6971
|
-
async function writeMemoryViaDaemon(entry) {
|
|
6972
|
-
if (process.env.EXE_IS_DAEMON === "1") {
|
|
6973
|
-
enqueueMemory(entry);
|
|
6974
|
-
return false;
|
|
6975
|
-
}
|
|
6976
|
-
if (!isClientConnected()) {
|
|
6977
|
-
enqueueMemory(entry);
|
|
6978
|
-
return false;
|
|
6979
|
-
}
|
|
6980
|
-
try {
|
|
6981
|
-
const response = await sendDaemonRequest({
|
|
6982
|
-
type: "write-memory",
|
|
6983
|
-
entry
|
|
6984
|
-
});
|
|
6985
|
-
if (response.ok) return true;
|
|
6986
|
-
enqueueMemory(entry);
|
|
6987
|
-
return false;
|
|
6988
|
-
} catch {
|
|
6989
|
-
enqueueMemory(entry);
|
|
6990
|
-
return false;
|
|
6991
|
-
}
|
|
6992
|
-
}
|
|
6993
|
-
|
|
6994
|
-
// src/adapters/claude/hooks/summary-worker.ts
|
|
6995
7019
|
init_task_scope();
|
|
6996
7020
|
init_employees();
|
|
6997
7021
|
import { execSync as execSync5 } from "child_process";
|
|
@@ -7078,6 +7102,119 @@ function buildAutoCheckpoint(input) {
|
|
|
7078
7102
|
};
|
|
7079
7103
|
}
|
|
7080
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
|
+
|
|
7081
7218
|
// src/adapters/claude/hooks/summary-worker.ts
|
|
7082
7219
|
async function main() {
|
|
7083
7220
|
const agentId = process.env.AGENT_ID ?? "default";
|
|
@@ -7136,15 +7273,8 @@ async function main() {
|
|
|
7136
7273
|
taskRows = tasks.rows;
|
|
7137
7274
|
} catch {
|
|
7138
7275
|
}
|
|
7139
|
-
const
|
|
7140
|
-
|
|
7141
|
-
agentRole,
|
|
7142
|
-
sessionId: `auto-summary-${Date.now()}`,
|
|
7143
|
-
projectName: primaryProject,
|
|
7144
|
-
reason: "periodic",
|
|
7145
|
-
memories: result.rows,
|
|
7146
|
-
tasks: taskRows
|
|
7147
|
-
});
|
|
7276
|
+
const summarySessionId = `auto-summary-${Date.now()}`;
|
|
7277
|
+
let summaryText = "";
|
|
7148
7278
|
let limitReached = false;
|
|
7149
7279
|
try {
|
|
7150
7280
|
const { assertMemoryLimit: assertMemoryLimit2 } = await Promise.resolve().then(() => (init_plan_limits(), plan_limits_exports));
|
|
@@ -7162,30 +7292,16 @@ async function main() {
|
|
|
7162
7292
|
}
|
|
7163
7293
|
if (limitReached) {
|
|
7164
7294
|
} else {
|
|
7165
|
-
await
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
importance: 7,
|
|
7174
|
-
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
|
|
7175
7303
|
});
|
|
7176
|
-
|
|
7177
|
-
await writeMemoryViaDaemon({
|
|
7178
|
-
raw_text: decisionText,
|
|
7179
|
-
agent_id: agentId,
|
|
7180
|
-
agent_role: agentRole,
|
|
7181
|
-
session_id: `auto-decision-${Date.now()}`,
|
|
7182
|
-
tool_name: "auto-decision",
|
|
7183
|
-
project_name: primaryProject,
|
|
7184
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7185
|
-
importance: 8,
|
|
7186
|
-
memory_type: "decision"
|
|
7187
|
-
});
|
|
7188
|
-
}
|
|
7304
|
+
summaryText = checkpointResult.checkpointText;
|
|
7189
7305
|
if (!canCoordinate(agentId, agentRole)) {
|
|
7190
7306
|
let totalErrors = 0;
|
|
7191
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