@askexenow/exe-os 0.8.85 → 0.8.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cleanup-stale-review-tasks.js +57 -19
- package/dist/bin/cli.js +510 -340
- package/dist/bin/exe-agent-config.js +242 -0
- package/dist/bin/exe-agent.js +3 -3
- package/dist/bin/exe-boot.js +344 -346
- package/dist/bin/exe-dispatch.js +375 -250
- package/dist/bin/exe-forget.js +5 -1
- package/dist/bin/exe-gateway.js +260 -135
- package/dist/bin/exe-healthcheck.js +133 -1
- package/dist/bin/exe-heartbeat.js +72 -31
- package/dist/bin/exe-link.js +25 -2
- package/dist/bin/exe-new-employee.js +22 -0
- package/dist/bin/exe-pending-messages.js +55 -17
- package/dist/bin/exe-pending-reviews.js +57 -19
- package/dist/bin/exe-search.js +6 -2
- package/dist/bin/exe-session-cleanup.js +260 -135
- package/dist/bin/exe-start-codex.js +2598 -0
- package/dist/bin/exe-start.sh +15 -3
- package/dist/bin/exe-status.js +57 -19
- package/dist/bin/git-sweep.js +391 -266
- package/dist/bin/install.js +22 -0
- package/dist/bin/scan-tasks.js +394 -269
- package/dist/bin/setup.js +50 -5
- package/dist/gateway/index.js +257 -132
- package/dist/hooks/bug-report-worker.js +242 -117
- package/dist/hooks/commit-complete.js +389 -264
- package/dist/hooks/error-recall.js +6 -2
- package/dist/hooks/ingest-worker.js +314 -193
- package/dist/hooks/post-compact.js +84 -46
- package/dist/hooks/pre-compact.js +272 -147
- package/dist/hooks/pre-tool-use.js +104 -66
- package/dist/hooks/prompt-submit.js +126 -66
- package/dist/hooks/session-end.js +277 -152
- package/dist/hooks/session-start.js +70 -28
- package/dist/hooks/stop.js +90 -52
- package/dist/hooks/subagent-stop.js +84 -46
- package/dist/hooks/summary-worker.js +175 -114
- package/dist/index.js +296 -171
- package/dist/lib/agent-config.js +167 -0
- package/dist/lib/cloud-sync.js +25 -2
- package/dist/lib/exe-daemon.js +338 -213
- package/dist/lib/hybrid-search.js +7 -2
- package/dist/lib/messaging.js +95 -39
- package/dist/lib/runtime-table.js +16 -0
- package/dist/lib/session-wrappers.js +22 -0
- package/dist/lib/tasks.js +242 -117
- package/dist/lib/tmux-routing.js +314 -189
- package/dist/mcp/server.js +573 -274
- package/dist/mcp/tools/create-task.js +260 -135
- package/dist/mcp/tools/list-tasks.js +68 -30
- package/dist/mcp/tools/send-message.js +100 -44
- package/dist/mcp/tools/update-task.js +123 -67
- package/dist/runtime/index.js +276 -151
- package/dist/tui/App.js +479 -354
- package/package.json +1 -1
- package/src/commands/exe/agent-config.md +27 -0
- package/src/commands/exe/cc-doctor.md +10 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// src/lib/agent-config.ts
|
|
2
|
+
import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2, mkdirSync } from "fs";
|
|
3
|
+
import path2 from "path";
|
|
4
|
+
|
|
5
|
+
// src/lib/config.ts
|
|
6
|
+
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
7
|
+
import { readFileSync, existsSync, renameSync } from "fs";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import os from "os";
|
|
10
|
+
function resolveDataDir() {
|
|
11
|
+
if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
|
|
12
|
+
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
13
|
+
const newDir = path.join(os.homedir(), ".exe-os");
|
|
14
|
+
const legacyDir = path.join(os.homedir(), ".exe-mem");
|
|
15
|
+
if (!existsSync(newDir) && existsSync(legacyDir)) {
|
|
16
|
+
try {
|
|
17
|
+
renameSync(legacyDir, newDir);
|
|
18
|
+
process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
|
|
19
|
+
`);
|
|
20
|
+
} catch {
|
|
21
|
+
return legacyDir;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return newDir;
|
|
25
|
+
}
|
|
26
|
+
var EXE_AI_DIR = resolveDataDir();
|
|
27
|
+
var DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
28
|
+
var MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
29
|
+
var CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
|
|
30
|
+
var LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
|
|
31
|
+
var CURRENT_CONFIG_VERSION = 1;
|
|
32
|
+
var DEFAULT_CONFIG = {
|
|
33
|
+
config_version: CURRENT_CONFIG_VERSION,
|
|
34
|
+
dbPath: DB_PATH,
|
|
35
|
+
modelFile: "jina-embeddings-v5-small-q4_k_m.gguf",
|
|
36
|
+
embeddingDim: 1024,
|
|
37
|
+
batchSize: 20,
|
|
38
|
+
flushIntervalMs: 1e4,
|
|
39
|
+
autoIngestion: true,
|
|
40
|
+
autoRetrieval: true,
|
|
41
|
+
searchMode: "hybrid",
|
|
42
|
+
hookSearchMode: "hybrid",
|
|
43
|
+
fileGrepEnabled: true,
|
|
44
|
+
splashEffect: true,
|
|
45
|
+
consolidationEnabled: true,
|
|
46
|
+
consolidationIntervalMs: 6 * 60 * 60 * 1e3,
|
|
47
|
+
consolidationModel: "claude-haiku-4-5-20251001",
|
|
48
|
+
consolidationMaxCallsPerRun: 20,
|
|
49
|
+
selfQueryRouter: true,
|
|
50
|
+
selfQueryModel: "claude-haiku-4-5-20251001",
|
|
51
|
+
rerankerEnabled: true,
|
|
52
|
+
scalingRoadmap: {
|
|
53
|
+
rerankerAutoTrigger: {
|
|
54
|
+
enabled: true,
|
|
55
|
+
broadQueryMinCardinality: 5e4,
|
|
56
|
+
fetchTopK: 150,
|
|
57
|
+
returnTopK: 5
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
graphRagEnabled: true,
|
|
61
|
+
wikiEnabled: false,
|
|
62
|
+
wikiUrl: "",
|
|
63
|
+
wikiApiKey: "",
|
|
64
|
+
wikiSyncIntervalMs: 30 * 60 * 1e3,
|
|
65
|
+
wikiWorkspaceMapping: {},
|
|
66
|
+
wikiAutoUpdate: true,
|
|
67
|
+
wikiAutoUpdateThreshold: 0.5,
|
|
68
|
+
wikiAutoUpdateCreateNew: true,
|
|
69
|
+
skillLearning: true,
|
|
70
|
+
skillThreshold: 3,
|
|
71
|
+
skillModel: "claude-haiku-4-5-20251001",
|
|
72
|
+
exeHeartbeat: {
|
|
73
|
+
enabled: true,
|
|
74
|
+
intervalSeconds: 60,
|
|
75
|
+
staleInProgressThresholdHours: 2
|
|
76
|
+
},
|
|
77
|
+
sessionLifecycle: {
|
|
78
|
+
idleKillEnabled: true,
|
|
79
|
+
idleKillTicksRequired: 3,
|
|
80
|
+
idleKillIntercomAckWindowMs: 1e4,
|
|
81
|
+
maxAutoInstances: 10
|
|
82
|
+
},
|
|
83
|
+
autoUpdate: {
|
|
84
|
+
checkOnBoot: true,
|
|
85
|
+
autoInstall: false,
|
|
86
|
+
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// src/lib/runtime-table.ts
|
|
91
|
+
var RUNTIME_TABLE = {
|
|
92
|
+
codex: {
|
|
93
|
+
binary: "codex",
|
|
94
|
+
launchMode: "exec",
|
|
95
|
+
autoApproveFlag: "--full-auto",
|
|
96
|
+
inlineFlag: "--no-alt-screen",
|
|
97
|
+
apiKeyEnv: "OPENAI_API_KEY",
|
|
98
|
+
defaultModel: "gpt-5.4"
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
var DEFAULT_RUNTIME = "claude";
|
|
102
|
+
|
|
103
|
+
// src/lib/agent-config.ts
|
|
104
|
+
var AGENT_CONFIG_PATH = path2.join(EXE_AI_DIR, "agent-config.json");
|
|
105
|
+
var KNOWN_RUNTIMES = {
|
|
106
|
+
claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-3.5"],
|
|
107
|
+
codex: ["gpt-5.4", "gpt-5.5", "o3", "o4-mini"],
|
|
108
|
+
opencode: ["minimax-m2.7"]
|
|
109
|
+
};
|
|
110
|
+
var DEFAULT_MODELS = {
|
|
111
|
+
claude: "claude-opus-4",
|
|
112
|
+
codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
|
|
113
|
+
opencode: "minimax-m2.7"
|
|
114
|
+
};
|
|
115
|
+
function loadAgentConfig() {
|
|
116
|
+
if (!existsSync2(AGENT_CONFIG_PATH)) return {};
|
|
117
|
+
try {
|
|
118
|
+
return JSON.parse(readFileSync2(AGENT_CONFIG_PATH, "utf-8"));
|
|
119
|
+
} catch {
|
|
120
|
+
return {};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function saveAgentConfig(config) {
|
|
124
|
+
const dir = path2.dirname(AGENT_CONFIG_PATH);
|
|
125
|
+
if (!existsSync2(dir)) mkdirSync(dir, { recursive: true });
|
|
126
|
+
writeFileSync(AGENT_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
127
|
+
}
|
|
128
|
+
function getAgentRuntime(agentId) {
|
|
129
|
+
const config = loadAgentConfig();
|
|
130
|
+
const entry = config[agentId];
|
|
131
|
+
if (entry) return entry;
|
|
132
|
+
return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
|
|
133
|
+
}
|
|
134
|
+
function setAgentRuntime(agentId, runtime, model) {
|
|
135
|
+
const knownModels = KNOWN_RUNTIMES[runtime];
|
|
136
|
+
if (!knownModels) {
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
error: `Unknown runtime "${runtime}". Valid: ${Object.keys(KNOWN_RUNTIMES).join(", ")}`
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (!knownModels.includes(model)) {
|
|
143
|
+
return {
|
|
144
|
+
ok: false,
|
|
145
|
+
error: `Unknown model "${model}" for runtime "${runtime}". Valid: ${knownModels.join(", ")}`
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const config = loadAgentConfig();
|
|
149
|
+
config[agentId] = { runtime, model };
|
|
150
|
+
saveAgentConfig(config);
|
|
151
|
+
return { ok: true };
|
|
152
|
+
}
|
|
153
|
+
function clearAgentRuntime(agentId) {
|
|
154
|
+
const config = loadAgentConfig();
|
|
155
|
+
delete config[agentId];
|
|
156
|
+
saveAgentConfig(config);
|
|
157
|
+
}
|
|
158
|
+
export {
|
|
159
|
+
AGENT_CONFIG_PATH,
|
|
160
|
+
DEFAULT_MODELS,
|
|
161
|
+
KNOWN_RUNTIMES,
|
|
162
|
+
clearAgentRuntime,
|
|
163
|
+
getAgentRuntime,
|
|
164
|
+
loadAgentConfig,
|
|
165
|
+
saveAgentConfig,
|
|
166
|
+
setAgentRuntime
|
|
167
|
+
};
|
package/dist/lib/cloud-sync.js
CHANGED
|
@@ -2621,10 +2621,18 @@ function buildRosterBlob(paths) {
|
|
|
2621
2621
|
} catch {
|
|
2622
2622
|
}
|
|
2623
2623
|
}
|
|
2624
|
+
let agentConfig;
|
|
2625
|
+
const agentConfigPath = path7.join(EXE_AI_DIR, "agent-config.json");
|
|
2626
|
+
if (existsSync7(agentConfigPath)) {
|
|
2627
|
+
try {
|
|
2628
|
+
agentConfig = JSON.parse(readFileSync6(agentConfigPath, "utf-8"));
|
|
2629
|
+
} catch {
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2624
2632
|
const deletedNames = consumeRosterDeletions();
|
|
2625
|
-
const content = JSON.stringify({ roster, identities, config, deletedNames });
|
|
2633
|
+
const content = JSON.stringify({ roster, identities, config, agentConfig, deletedNames });
|
|
2626
2634
|
const hash = crypto2.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
2627
|
-
return { roster, identities, config, deletedNames, version: hash };
|
|
2635
|
+
return { roster, identities, config, agentConfig, deletedNames, version: hash };
|
|
2628
2636
|
}
|
|
2629
2637
|
async function cloudPushRoster(config) {
|
|
2630
2638
|
assertSecureEndpoint(config.endpoint);
|
|
@@ -2762,6 +2770,21 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
2762
2770
|
} catch {
|
|
2763
2771
|
}
|
|
2764
2772
|
}
|
|
2773
|
+
if (remote.agentConfig && Object.keys(remote.agentConfig).length > 0) {
|
|
2774
|
+
try {
|
|
2775
|
+
const agentConfigPath = path7.join(EXE_AI_DIR, "agent-config.json");
|
|
2776
|
+
let local = {};
|
|
2777
|
+
if (existsSync7(agentConfigPath)) {
|
|
2778
|
+
try {
|
|
2779
|
+
local = JSON.parse(readFileSync6(agentConfigPath, "utf-8"));
|
|
2780
|
+
} catch {
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
const merged = { ...remote.agentConfig, ...local };
|
|
2784
|
+
writeFileSync4(agentConfigPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
2785
|
+
} catch {
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2765
2788
|
return { added, identitiesUpdated };
|
|
2766
2789
|
});
|
|
2767
2790
|
}
|