@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
|
@@ -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 config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
|
|
177
183
|
if (config.dbPath.startsWith("~")) {
|
|
178
184
|
config.dbPath = config.dbPath.replace(/^~/, os.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: path.join(dir, "memories.db"), ...migratedCfg };
|
|
200
207
|
} catch {
|
|
201
208
|
return { ...DEFAULT_CONFIG, dbPath: path.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 = [
|
|
@@ -6934,15 +6946,15 @@ var init_task_scope = __esm({
|
|
|
6934
6946
|
|
|
6935
6947
|
// src/lib/keychain.ts
|
|
6936
6948
|
import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
|
|
6937
|
-
import { existsSync as
|
|
6949
|
+
import { existsSync as existsSync18 } from "fs";
|
|
6938
6950
|
import { execSync as execSync8 } from "child_process";
|
|
6939
|
-
import
|
|
6951
|
+
import path22 from "path";
|
|
6940
6952
|
import os13 from "os";
|
|
6941
6953
|
function getKeyDir() {
|
|
6942
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ??
|
|
6954
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path22.join(os13.homedir(), ".exe-os");
|
|
6943
6955
|
}
|
|
6944
6956
|
function getKeyPath() {
|
|
6945
|
-
return
|
|
6957
|
+
return path22.join(getKeyDir(), "master.key");
|
|
6946
6958
|
}
|
|
6947
6959
|
function macKeychainGet() {
|
|
6948
6960
|
if (process.platform !== "darwin") return null;
|
|
@@ -7090,7 +7102,7 @@ async function getMasterKey() {
|
|
|
7090
7102
|
}
|
|
7091
7103
|
}
|
|
7092
7104
|
const keyPath = getKeyPath();
|
|
7093
|
-
if (!
|
|
7105
|
+
if (!existsSync18(keyPath)) {
|
|
7094
7106
|
process.stderr.write(
|
|
7095
7107
|
`[keychain] Key not found at ${keyPath} (HOME=${os13.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
7096
7108
|
`
|
|
@@ -7364,12 +7376,12 @@ __export(shard_manager_exports, {
|
|
|
7364
7376
|
listShards: () => listShards,
|
|
7365
7377
|
shardExists: () => shardExists
|
|
7366
7378
|
});
|
|
7367
|
-
import
|
|
7368
|
-
import { existsSync as
|
|
7379
|
+
import path23 from "path";
|
|
7380
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync10, readdirSync as readdirSync5, renameSync as renameSync5, statSync as statSync3 } from "fs";
|
|
7369
7381
|
import { createClient as createClient2 } from "@libsql/client";
|
|
7370
7382
|
function initShardManager(encryptionKey) {
|
|
7371
7383
|
_encryptionKey = encryptionKey;
|
|
7372
|
-
if (!
|
|
7384
|
+
if (!existsSync19(SHARDS_DIR)) {
|
|
7373
7385
|
mkdirSync10(SHARDS_DIR, { recursive: true });
|
|
7374
7386
|
}
|
|
7375
7387
|
_shardingEnabled = true;
|
|
@@ -7399,7 +7411,7 @@ function getShardClient(projectName) {
|
|
|
7399
7411
|
while (_shards.size >= MAX_OPEN_SHARDS) {
|
|
7400
7412
|
evictLRU();
|
|
7401
7413
|
}
|
|
7402
|
-
const dbPath =
|
|
7414
|
+
const dbPath = path23.join(SHARDS_DIR, `${safeName}.db`);
|
|
7403
7415
|
const client = createClient2({
|
|
7404
7416
|
url: `file:${dbPath}`,
|
|
7405
7417
|
encryptionKey: _encryptionKey
|
|
@@ -7410,13 +7422,13 @@ function getShardClient(projectName) {
|
|
|
7410
7422
|
}
|
|
7411
7423
|
function shardExists(projectName) {
|
|
7412
7424
|
const safeName = safeShardName(projectName);
|
|
7413
|
-
return
|
|
7425
|
+
return existsSync19(path23.join(SHARDS_DIR, `${safeName}.db`));
|
|
7414
7426
|
}
|
|
7415
7427
|
function safeShardName(projectName) {
|
|
7416
7428
|
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
7417
7429
|
}
|
|
7418
7430
|
function listShards() {
|
|
7419
|
-
if (!
|
|
7431
|
+
if (!existsSync19(SHARDS_DIR)) return [];
|
|
7420
7432
|
return readdirSync5(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
7421
7433
|
}
|
|
7422
7434
|
async function auditShardHealth(options = {}) {
|
|
@@ -7428,8 +7440,8 @@ async function auditShardHealth(options = {}) {
|
|
|
7428
7440
|
const names = listShards();
|
|
7429
7441
|
const shards = [];
|
|
7430
7442
|
for (const name of names) {
|
|
7431
|
-
const dbPath =
|
|
7432
|
-
const stat =
|
|
7443
|
+
const dbPath = path23.join(SHARDS_DIR, `${name}.db`);
|
|
7444
|
+
const stat = statSync3(dbPath);
|
|
7433
7445
|
const item = {
|
|
7434
7446
|
name,
|
|
7435
7447
|
path: dbPath,
|
|
@@ -7463,8 +7475,8 @@ async function auditShardHealth(options = {}) {
|
|
|
7463
7475
|
_shards.delete(name);
|
|
7464
7476
|
_shardLastAccess.delete(name);
|
|
7465
7477
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
7466
|
-
const archivedPath =
|
|
7467
|
-
|
|
7478
|
+
const archivedPath = path23.join(SHARDS_DIR, `${name}.db.broken-${stamp}`);
|
|
7479
|
+
renameSync5(dbPath, archivedPath);
|
|
7468
7480
|
item.archivedPath = archivedPath;
|
|
7469
7481
|
}
|
|
7470
7482
|
} finally {
|
|
@@ -7680,12 +7692,12 @@ async function getReadyShardClient(projectName) {
|
|
|
7680
7692
|
client.close();
|
|
7681
7693
|
_shards.delete(safeName);
|
|
7682
7694
|
_shardLastAccess.delete(safeName);
|
|
7683
|
-
const dbPath =
|
|
7684
|
-
if (
|
|
7685
|
-
const stat =
|
|
7695
|
+
const dbPath = path23.join(SHARDS_DIR, `${safeName}.db`);
|
|
7696
|
+
if (existsSync19(dbPath)) {
|
|
7697
|
+
const stat = statSync3(dbPath);
|
|
7686
7698
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
7687
|
-
const archivedPath =
|
|
7688
|
-
|
|
7699
|
+
const archivedPath = path23.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
7700
|
+
renameSync5(dbPath, archivedPath);
|
|
7689
7701
|
process.stderr.write(
|
|
7690
7702
|
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
7691
7703
|
`
|
|
@@ -7752,7 +7764,7 @@ var init_shard_manager = __esm({
|
|
|
7752
7764
|
"src/lib/shard-manager.ts"() {
|
|
7753
7765
|
"use strict";
|
|
7754
7766
|
init_config();
|
|
7755
|
-
SHARDS_DIR =
|
|
7767
|
+
SHARDS_DIR = path23.join(EXE_AI_DIR, "shards");
|
|
7756
7768
|
SHARD_IDLE_MS = 5 * 60 * 1e3;
|
|
7757
7769
|
MAX_OPEN_SHARDS = 10;
|
|
7758
7770
|
EVICTION_INTERVAL_MS = 60 * 1e3;
|
|
@@ -7802,6 +7814,12 @@ var init_platform_procedures = __esm({
|
|
|
7802
7814
|
priority: "p0",
|
|
7803
7815
|
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."
|
|
7804
7816
|
},
|
|
7817
|
+
{
|
|
7818
|
+
title: "Customer orchestration maturity \u2014 recommend, never trap",
|
|
7819
|
+
domain: "workflow",
|
|
7820
|
+
priority: "p1",
|
|
7821
|
+
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."
|
|
7822
|
+
},
|
|
7805
7823
|
{
|
|
7806
7824
|
title: "Single dispatch path \u2014 create_task only",
|
|
7807
7825
|
domain: "workflow",
|
|
@@ -7860,6 +7878,12 @@ var init_platform_procedures = __esm({
|
|
|
7860
7878
|
priority: "p0",
|
|
7861
7879
|
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."
|
|
7862
7880
|
},
|
|
7881
|
+
{
|
|
7882
|
+
title: "Commit discipline \u2014 never leave verified work floating",
|
|
7883
|
+
domain: "workflow",
|
|
7884
|
+
priority: "p1",
|
|
7885
|
+
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."
|
|
7886
|
+
},
|
|
7863
7887
|
{
|
|
7864
7888
|
title: "Desktop and TUI are the same product",
|
|
7865
7889
|
domain: "architecture",
|
|
@@ -8867,78 +8891,6 @@ var init_fast_db_init = __esm({
|
|
|
8867
8891
|
}
|
|
8868
8892
|
});
|
|
8869
8893
|
|
|
8870
|
-
// src/lib/memory-queue.ts
|
|
8871
|
-
import { appendFileSync as appendFileSync2, readFileSync as readFileSync15, renameSync as renameSync5, unlinkSync as unlinkSync9, existsSync as existsSync19, statSync as statSync3 } from "fs";
|
|
8872
|
-
import path23 from "path";
|
|
8873
|
-
function enqueueMemory(entry) {
|
|
8874
|
-
appendFileSync2(QUEUE_PATH2, JSON.stringify(entry) + "\n");
|
|
8875
|
-
}
|
|
8876
|
-
var QUEUE_PATH2, PROCESSING_PATH, TTL_MS2;
|
|
8877
|
-
var init_memory_queue = __esm({
|
|
8878
|
-
"src/lib/memory-queue.ts"() {
|
|
8879
|
-
"use strict";
|
|
8880
|
-
init_config();
|
|
8881
|
-
QUEUE_PATH2 = path23.join(EXE_AI_DIR, "memory-queue.jsonl");
|
|
8882
|
-
PROCESSING_PATH = QUEUE_PATH2 + ".processing";
|
|
8883
|
-
TTL_MS2 = 24 * 60 * 60 * 1e3;
|
|
8884
|
-
}
|
|
8885
|
-
});
|
|
8886
|
-
|
|
8887
|
-
// src/lib/memory-queue-client.ts
|
|
8888
|
-
var memory_queue_client_exports = {};
|
|
8889
|
-
__export(memory_queue_client_exports, {
|
|
8890
|
-
batchWriteMemoryViaDaemon: () => batchWriteMemoryViaDaemon,
|
|
8891
|
-
writeMemoryViaDaemon: () => writeMemoryViaDaemon
|
|
8892
|
-
});
|
|
8893
|
-
async function writeMemoryViaDaemon(entry) {
|
|
8894
|
-
if (process.env.EXE_IS_DAEMON === "1") {
|
|
8895
|
-
enqueueMemory(entry);
|
|
8896
|
-
return false;
|
|
8897
|
-
}
|
|
8898
|
-
if (!isClientConnected()) {
|
|
8899
|
-
enqueueMemory(entry);
|
|
8900
|
-
return false;
|
|
8901
|
-
}
|
|
8902
|
-
try {
|
|
8903
|
-
const response = await sendDaemonRequest({
|
|
8904
|
-
type: "write-memory",
|
|
8905
|
-
entry
|
|
8906
|
-
});
|
|
8907
|
-
if (response.ok) return true;
|
|
8908
|
-
enqueueMemory(entry);
|
|
8909
|
-
return false;
|
|
8910
|
-
} catch {
|
|
8911
|
-
enqueueMemory(entry);
|
|
8912
|
-
return false;
|
|
8913
|
-
}
|
|
8914
|
-
}
|
|
8915
|
-
async function batchWriteMemoryViaDaemon(entries) {
|
|
8916
|
-
if (entries.length === 0) return 0;
|
|
8917
|
-
if (process.env.EXE_IS_DAEMON === "1" || !isClientConnected()) {
|
|
8918
|
-
for (const entry of entries) enqueueMemory(entry);
|
|
8919
|
-
return 0;
|
|
8920
|
-
}
|
|
8921
|
-
try {
|
|
8922
|
-
const response = await sendDaemonRequest({
|
|
8923
|
-
type: "batch-write-memory",
|
|
8924
|
-
entries
|
|
8925
|
-
});
|
|
8926
|
-
if (response.ok) return response.count ?? entries.length;
|
|
8927
|
-
for (const entry of entries) enqueueMemory(entry);
|
|
8928
|
-
return 0;
|
|
8929
|
-
} catch {
|
|
8930
|
-
for (const entry of entries) enqueueMemory(entry);
|
|
8931
|
-
return 0;
|
|
8932
|
-
}
|
|
8933
|
-
}
|
|
8934
|
-
var init_memory_queue_client = __esm({
|
|
8935
|
-
"src/lib/memory-queue-client.ts"() {
|
|
8936
|
-
"use strict";
|
|
8937
|
-
init_exe_daemon_client();
|
|
8938
|
-
init_memory_queue();
|
|
8939
|
-
}
|
|
8940
|
-
});
|
|
8941
|
-
|
|
8942
8894
|
// src/lib/git-staleness.ts
|
|
8943
8895
|
var git_staleness_exports = {};
|
|
8944
8896
|
__export(git_staleness_exports, {
|
|
@@ -9486,6 +9438,119 @@ function buildAutoCheckpoint(input2) {
|
|
|
9486
9438
|
};
|
|
9487
9439
|
}
|
|
9488
9440
|
|
|
9441
|
+
// src/lib/memory-queue-client.ts
|
|
9442
|
+
init_exe_daemon_client();
|
|
9443
|
+
|
|
9444
|
+
// src/lib/memory-queue.ts
|
|
9445
|
+
init_config();
|
|
9446
|
+
import { appendFileSync as appendFileSync2, readFileSync as readFileSync15, renameSync as renameSync4, unlinkSync as unlinkSync9, existsSync as existsSync17, statSync as statSync2 } from "fs";
|
|
9447
|
+
import path21 from "path";
|
|
9448
|
+
var QUEUE_PATH2 = path21.join(EXE_AI_DIR, "memory-queue.jsonl");
|
|
9449
|
+
var PROCESSING_PATH = QUEUE_PATH2 + ".processing";
|
|
9450
|
+
var TTL_MS2 = 24 * 60 * 60 * 1e3;
|
|
9451
|
+
function enqueueMemory(entry) {
|
|
9452
|
+
appendFileSync2(QUEUE_PATH2, JSON.stringify(entry) + "\n");
|
|
9453
|
+
}
|
|
9454
|
+
|
|
9455
|
+
// src/lib/memory-queue-client.ts
|
|
9456
|
+
async function writeMemoryViaDaemon(entry) {
|
|
9457
|
+
if (process.env.EXE_IS_DAEMON === "1") {
|
|
9458
|
+
enqueueMemory(entry);
|
|
9459
|
+
return false;
|
|
9460
|
+
}
|
|
9461
|
+
if (!isClientConnected()) {
|
|
9462
|
+
enqueueMemory(entry);
|
|
9463
|
+
return false;
|
|
9464
|
+
}
|
|
9465
|
+
try {
|
|
9466
|
+
const response = await sendDaemonRequest({
|
|
9467
|
+
type: "write-memory",
|
|
9468
|
+
entry
|
|
9469
|
+
});
|
|
9470
|
+
if (response.ok) return true;
|
|
9471
|
+
enqueueMemory(entry);
|
|
9472
|
+
return false;
|
|
9473
|
+
} catch {
|
|
9474
|
+
enqueueMemory(entry);
|
|
9475
|
+
return false;
|
|
9476
|
+
}
|
|
9477
|
+
}
|
|
9478
|
+
|
|
9479
|
+
// src/lib/checkpoint-orchestrator.ts
|
|
9480
|
+
function toolNameForReason(reason) {
|
|
9481
|
+
switch (reason) {
|
|
9482
|
+
case "periodic":
|
|
9483
|
+
return "auto-summary";
|
|
9484
|
+
case "session-end":
|
|
9485
|
+
return "SessionEnd";
|
|
9486
|
+
case "pre-compact":
|
|
9487
|
+
return "pre-compact-hook";
|
|
9488
|
+
case "capacity-signal":
|
|
9489
|
+
return "auto-checkpoint";
|
|
9490
|
+
}
|
|
9491
|
+
}
|
|
9492
|
+
function importanceForReason(reason, override) {
|
|
9493
|
+
if (override !== void 0) return override;
|
|
9494
|
+
switch (reason) {
|
|
9495
|
+
case "periodic":
|
|
9496
|
+
return 7;
|
|
9497
|
+
case "session-end":
|
|
9498
|
+
case "pre-compact":
|
|
9499
|
+
case "capacity-signal":
|
|
9500
|
+
return 8;
|
|
9501
|
+
}
|
|
9502
|
+
}
|
|
9503
|
+
function buildContinuityCheckpoint(input2) {
|
|
9504
|
+
const { checkpointText, decisionTexts } = buildAutoCheckpoint({
|
|
9505
|
+
agentId: input2.agentId,
|
|
9506
|
+
agentRole: input2.agentRole,
|
|
9507
|
+
sessionId: input2.sessionId,
|
|
9508
|
+
projectName: input2.projectName,
|
|
9509
|
+
reason: input2.reason,
|
|
9510
|
+
memories: input2.memories ?? [],
|
|
9511
|
+
tasks: input2.tasks ?? [],
|
|
9512
|
+
maxSamples: input2.maxSamples
|
|
9513
|
+
});
|
|
9514
|
+
const extra = input2.extraSections?.filter((section) => section.trim().length > 0) ?? [];
|
|
9515
|
+
return {
|
|
9516
|
+
checkpointText: extra.length > 0 ? `${checkpointText}
|
|
9517
|
+
|
|
9518
|
+
${extra.join("\n\n")}` : checkpointText,
|
|
9519
|
+
decisionTexts
|
|
9520
|
+
};
|
|
9521
|
+
}
|
|
9522
|
+
async function writeContinuityCheckpoint(input2) {
|
|
9523
|
+
const result = buildContinuityCheckpoint(input2);
|
|
9524
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9525
|
+
await writeMemoryViaDaemon({
|
|
9526
|
+
raw_text: result.checkpointText,
|
|
9527
|
+
agent_id: input2.agentId,
|
|
9528
|
+
agent_role: input2.agentRole,
|
|
9529
|
+
session_id: input2.sessionId,
|
|
9530
|
+
tool_name: toolNameForReason(input2.reason),
|
|
9531
|
+
project_name: input2.projectName,
|
|
9532
|
+
timestamp: now,
|
|
9533
|
+
importance: importanceForReason(input2.reason, input2.importance),
|
|
9534
|
+
task_id: input2.taskId,
|
|
9535
|
+
memory_type: "checkpoint"
|
|
9536
|
+
});
|
|
9537
|
+
const decisionLimit = input2.reason === "periodic" ? 3 : 5;
|
|
9538
|
+
for (const decisionText of result.decisionTexts.slice(0, decisionLimit)) {
|
|
9539
|
+
await writeMemoryViaDaemon({
|
|
9540
|
+
raw_text: decisionText,
|
|
9541
|
+
agent_id: input2.agentId,
|
|
9542
|
+
agent_role: input2.agentRole,
|
|
9543
|
+
session_id: input2.sessionId,
|
|
9544
|
+
tool_name: "auto-decision",
|
|
9545
|
+
project_name: input2.projectName,
|
|
9546
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9547
|
+
importance: 8,
|
|
9548
|
+
memory_type: "decision"
|
|
9549
|
+
});
|
|
9550
|
+
}
|
|
9551
|
+
return result;
|
|
9552
|
+
}
|
|
9553
|
+
|
|
9489
9554
|
// src/adapters/claude/hooks/session-end.ts
|
|
9490
9555
|
if (!process.env.AGENT_ID) {
|
|
9491
9556
|
process.env.AGENT_ID = "default";
|
|
@@ -9535,7 +9600,7 @@ Orphaned tasks at session end: ${orphanResult.rows.map((r) => `"${String(r.title
|
|
|
9535
9600
|
ORDER BY priority ASC, updated_at DESC LIMIT 10`,
|
|
9536
9601
|
args: [agent.agentId, ...seScope.args]
|
|
9537
9602
|
});
|
|
9538
|
-
|
|
9603
|
+
await writeContinuityCheckpoint({
|
|
9539
9604
|
agentId: agent.agentId,
|
|
9540
9605
|
agentRole: agent.agentRole,
|
|
9541
9606
|
sessionId: data.session_id,
|
|
@@ -9543,35 +9608,9 @@ Orphaned tasks at session end: ${orphanResult.rows.map((r) => `"${String(r.title
|
|
|
9543
9608
|
reason: "session-end",
|
|
9544
9609
|
memories: recent.rows,
|
|
9545
9610
|
tasks: taskRows.rows,
|
|
9546
|
-
maxSamples: 12
|
|
9611
|
+
maxSamples: 12,
|
|
9612
|
+
extraSections: orphanInfo ? [`## Session-End Warnings${orphanInfo}`] : []
|
|
9547
9613
|
});
|
|
9548
|
-
const { writeMemoryViaDaemon: writeMemoryViaDaemon2 } = await Promise.resolve().then(() => (init_memory_queue_client(), memory_queue_client_exports));
|
|
9549
|
-
await writeMemoryViaDaemon2({
|
|
9550
|
-
raw_text: `${checkpointText}${orphanInfo ? `
|
|
9551
|
-
|
|
9552
|
-
## Session-End Warnings${orphanInfo}` : ""}`,
|
|
9553
|
-
agent_id: agent.agentId,
|
|
9554
|
-
agent_role: agent.agentRole,
|
|
9555
|
-
session_id: data.session_id,
|
|
9556
|
-
tool_name: "SessionEnd",
|
|
9557
|
-
project_name: projectName,
|
|
9558
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9559
|
-
importance: 8,
|
|
9560
|
-
memory_type: "checkpoint"
|
|
9561
|
-
});
|
|
9562
|
-
for (const decisionText of decisionTexts.slice(0, 5)) {
|
|
9563
|
-
await writeMemoryViaDaemon2({
|
|
9564
|
-
raw_text: decisionText,
|
|
9565
|
-
agent_id: agent.agentId,
|
|
9566
|
-
agent_role: agent.agentRole,
|
|
9567
|
-
session_id: data.session_id,
|
|
9568
|
-
tool_name: "auto-decision",
|
|
9569
|
-
project_name: projectName,
|
|
9570
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9571
|
-
importance: 8,
|
|
9572
|
-
memory_type: "decision"
|
|
9573
|
-
});
|
|
9574
|
-
}
|
|
9575
9614
|
try {
|
|
9576
9615
|
const { clearSessionFileReads: clearSessionFileReads2 } = await Promise.resolve().then(() => (init_git_staleness(), git_staleness_exports));
|
|
9577
9616
|
await clearSessionFileReads2(data.session_id);
|
|
@@ -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 config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
|
|
177
183
|
if (config.dbPath.startsWith("~")) {
|
|
178
184
|
config.dbPath = config.dbPath.replace(/^~/, os.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: path.join(dir, "memories.db"), ...migratedCfg };
|
|
200
207
|
} catch {
|
|
201
208
|
return { ...DEFAULT_CONFIG, dbPath: path.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 = [
|
|
@@ -4238,6 +4250,12 @@ var init_platform_procedures = __esm({
|
|
|
4238
4250
|
priority: "p0",
|
|
4239
4251
|
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."
|
|
4240
4252
|
},
|
|
4253
|
+
{
|
|
4254
|
+
title: "Customer orchestration maturity \u2014 recommend, never trap",
|
|
4255
|
+
domain: "workflow",
|
|
4256
|
+
priority: "p1",
|
|
4257
|
+
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."
|
|
4258
|
+
},
|
|
4241
4259
|
{
|
|
4242
4260
|
title: "Single dispatch path \u2014 create_task only",
|
|
4243
4261
|
domain: "workflow",
|
|
@@ -4296,6 +4314,12 @@ var init_platform_procedures = __esm({
|
|
|
4296
4314
|
priority: "p0",
|
|
4297
4315
|
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."
|
|
4298
4316
|
},
|
|
4317
|
+
{
|
|
4318
|
+
title: "Commit discipline \u2014 never leave verified work floating",
|
|
4319
|
+
domain: "workflow",
|
|
4320
|
+
priority: "p1",
|
|
4321
|
+
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."
|
|
4322
|
+
},
|
|
4299
4323
|
{
|
|
4300
4324
|
title: "Desktop and TUI are the same product",
|
|
4301
4325
|
domain: "architecture",
|
|
@@ -8055,6 +8079,115 @@ var init_identity = __esm({
|
|
|
8055
8079
|
}
|
|
8056
8080
|
});
|
|
8057
8081
|
|
|
8082
|
+
// src/lib/orchestration-phase.ts
|
|
8083
|
+
var orchestration_phase_exports = {};
|
|
8084
|
+
__export(orchestration_phase_exports, {
|
|
8085
|
+
ORCHESTRATION_PHASES: () => ORCHESTRATION_PHASES,
|
|
8086
|
+
applyDefaultOrchestrationPhase: () => applyDefaultOrchestrationPhase,
|
|
8087
|
+
getConfigOrchestrationPhase: () => getConfigOrchestrationPhase,
|
|
8088
|
+
getOrchestrationPhaseInfo: () => getOrchestrationPhaseInfo,
|
|
8089
|
+
loadOrchestrationPhase: () => loadOrchestrationPhase,
|
|
8090
|
+
normalizeOrchestrationPhase: () => normalizeOrchestrationPhase,
|
|
8091
|
+
phaseReminderLine: () => phaseReminderLine,
|
|
8092
|
+
setOrchestrationPhase: () => setOrchestrationPhase
|
|
8093
|
+
});
|
|
8094
|
+
function normalizeOrchestrationPhase(input2) {
|
|
8095
|
+
if (typeof input2 !== "string") return "phase_1_coo";
|
|
8096
|
+
const normalized = input2.trim().toLowerCase().replace(/\s+/g, "_");
|
|
8097
|
+
if (["1", "phase1", "phase_1", "coo", "coo_mode", "chief_of_staff", "phase_1_coo"].includes(normalized)) {
|
|
8098
|
+
return "phase_1_coo";
|
|
8099
|
+
}
|
|
8100
|
+
if (["2", "phase2", "phase_2", "executives", "executive", "executive_bench", "phase_2_executives"].includes(normalized)) {
|
|
8101
|
+
return "phase_2_executives";
|
|
8102
|
+
}
|
|
8103
|
+
if (["3", "phase3", "phase_3", "parallel", "parallel_org", "parallel_execution", "phase_3_parallel_org"].includes(normalized)) {
|
|
8104
|
+
return "phase_3_parallel_org";
|
|
8105
|
+
}
|
|
8106
|
+
if (ORCHESTRATION_PHASES.includes(normalized)) return normalized;
|
|
8107
|
+
return "phase_1_coo";
|
|
8108
|
+
}
|
|
8109
|
+
function getOrchestrationPhaseInfo(phase) {
|
|
8110
|
+
return PHASE_INFO[normalizeOrchestrationPhase(phase)];
|
|
8111
|
+
}
|
|
8112
|
+
function getConfigOrchestrationPhase(config) {
|
|
8113
|
+
const orchestration = config.orchestration;
|
|
8114
|
+
return normalizeOrchestrationPhase(orchestration?.phase);
|
|
8115
|
+
}
|
|
8116
|
+
function applyDefaultOrchestrationPhase(config) {
|
|
8117
|
+
if (!config.orchestration) {
|
|
8118
|
+
config.orchestration = {
|
|
8119
|
+
phase: "phase_1_coo",
|
|
8120
|
+
phaseSetAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8121
|
+
phaseSetBy: "setup-default"
|
|
8122
|
+
};
|
|
8123
|
+
return config;
|
|
8124
|
+
}
|
|
8125
|
+
if (!config.orchestration.phase) {
|
|
8126
|
+
config.orchestration = {
|
|
8127
|
+
...config.orchestration,
|
|
8128
|
+
phase: "phase_1_coo",
|
|
8129
|
+
phaseSetAt: config.orchestration.phaseSetAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
8130
|
+
phaseSetBy: config.orchestration.phaseSetBy ?? "setup-default"
|
|
8131
|
+
};
|
|
8132
|
+
}
|
|
8133
|
+
return config;
|
|
8134
|
+
}
|
|
8135
|
+
async function loadOrchestrationPhase() {
|
|
8136
|
+
const config = await loadConfig();
|
|
8137
|
+
return getOrchestrationPhaseInfo(config.orchestration?.phase);
|
|
8138
|
+
}
|
|
8139
|
+
async function setOrchestrationPhase(phaseInput, setBy = "user") {
|
|
8140
|
+
const config = await loadConfig();
|
|
8141
|
+
const phase = normalizeOrchestrationPhase(phaseInput);
|
|
8142
|
+
config.orchestration = {
|
|
8143
|
+
...config.orchestration ?? {},
|
|
8144
|
+
phase,
|
|
8145
|
+
phaseSetAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8146
|
+
phaseSetBy: setBy
|
|
8147
|
+
};
|
|
8148
|
+
await saveConfig(config);
|
|
8149
|
+
return getOrchestrationPhaseInfo(phase);
|
|
8150
|
+
}
|
|
8151
|
+
function phaseReminderLine(phase) {
|
|
8152
|
+
const info = getOrchestrationPhaseInfo(phase);
|
|
8153
|
+
return `${info.shortLabel}: ${info.focus}. ${info.nextSuggestion}`;
|
|
8154
|
+
}
|
|
8155
|
+
var ORCHESTRATION_PHASES, PHASE_INFO;
|
|
8156
|
+
var init_orchestration_phase = __esm({
|
|
8157
|
+
"src/lib/orchestration-phase.ts"() {
|
|
8158
|
+
"use strict";
|
|
8159
|
+
init_config();
|
|
8160
|
+
ORCHESTRATION_PHASES = [
|
|
8161
|
+
"phase_1_coo",
|
|
8162
|
+
"phase_2_executives",
|
|
8163
|
+
"phase_3_parallel_org"
|
|
8164
|
+
];
|
|
8165
|
+
PHASE_INFO = {
|
|
8166
|
+
phase_1_coo: {
|
|
8167
|
+
phase: "phase_1_coo",
|
|
8168
|
+
shortLabel: "Phase 1 \u2014 COO mode",
|
|
8169
|
+
label: "Phase 1 \u2014 COO / Chief of Staff mode",
|
|
8170
|
+
focus: "building company context before delegation",
|
|
8171
|
+
nextSuggestion: "Unlock executives when technical, marketing, ops, legal, or finance work repeats."
|
|
8172
|
+
},
|
|
8173
|
+
phase_2_executives: {
|
|
8174
|
+
phase: "phase_2_executives",
|
|
8175
|
+
shortLabel: "Phase 2 \u2014 Executive bench",
|
|
8176
|
+
label: "Phase 2 \u2014 Executive bench",
|
|
8177
|
+
focus: "COO works with domain executives like CTO/CMO before specialist fan-out",
|
|
8178
|
+
nextSuggestion: "Unlock parallel execution when review gates, permissions, and workflows are ready."
|
|
8179
|
+
},
|
|
8180
|
+
phase_3_parallel_org: {
|
|
8181
|
+
phase: "phase_3_parallel_org",
|
|
8182
|
+
shortLabel: "Phase 3 \u2014 Parallel org",
|
|
8183
|
+
label: "Phase 3 \u2014 Parallel execution org",
|
|
8184
|
+
focus: "executives can delegate to specialists in parallel with review gates",
|
|
8185
|
+
nextSuggestion: "Keep review/CI/permission gates healthy; downgrade anytime if you want simpler COO-only mode."
|
|
8186
|
+
}
|
|
8187
|
+
};
|
|
8188
|
+
}
|
|
8189
|
+
});
|
|
8190
|
+
|
|
8058
8191
|
// src/adapters/claude/hooks/session-start.ts
|
|
8059
8192
|
init_config();
|
|
8060
8193
|
import path21 from "path";
|
|
@@ -8236,6 +8369,15 @@ You are **${title}**${role ? ` (${role})` : ""}. ${firstLine}
|
|
|
8236
8369
|
} catch {
|
|
8237
8370
|
}
|
|
8238
8371
|
}
|
|
8372
|
+
try {
|
|
8373
|
+
const { loadOrchestrationPhase: loadOrchestrationPhase2 } = await Promise.resolve().then(() => (init_orchestration_phase(), orchestration_phase_exports));
|
|
8374
|
+
const phase = await loadOrchestrationPhase2();
|
|
8375
|
+
additionalContext += `## Orchestration Phase
|
|
8376
|
+
${phase.label}. Focus: ${phase.focus}. This is guidance, not a blocker; the user can switch phases anytime. ${phase.nextSuggestion}
|
|
8377
|
+
|
|
8378
|
+
`;
|
|
8379
|
+
} catch {
|
|
8380
|
+
}
|
|
8239
8381
|
if (memories.length > 0) {
|
|
8240
8382
|
const brief = memories.map(
|
|
8241
8383
|
(m) => `[${m.timestamp}] ${m.tool_name}: ${m.raw_text.slice(0, 200)}`
|