@askexenow/exe-os 0.8.80 → 0.8.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/backfill-conversations.js +359 -267
- package/dist/bin/backfill-responses.js +357 -265
- package/dist/bin/backfill-vectors.js +339 -264
- package/dist/bin/cleanup-stale-review-tasks.js +315 -256
- package/dist/bin/cli.js +494 -240
- package/dist/bin/exe-agent.js +141 -46
- package/dist/bin/exe-assign.js +151 -63
- package/dist/bin/exe-boot.js +294 -115
- package/dist/bin/exe-call.js +76 -51
- package/dist/bin/exe-cloud.js +58 -45
- package/dist/bin/exe-dispatch.js +434 -277
- package/dist/bin/exe-doctor.js +317 -246
- package/dist/bin/exe-export-behaviors.js +328 -248
- package/dist/bin/exe-forget.js +314 -231
- package/dist/bin/exe-gateway.js +2676 -1402
- package/dist/bin/exe-heartbeat.js +329 -264
- package/dist/bin/exe-kill.js +324 -244
- package/dist/bin/exe-launch-agent.js +574 -463
- package/dist/bin/exe-link.js +1055 -95
- package/dist/bin/exe-new-employee.js +49 -54
- package/dist/bin/exe-pending-messages.js +310 -253
- package/dist/bin/exe-pending-notifications.js +299 -228
- package/dist/bin/exe-pending-reviews.js +314 -245
- package/dist/bin/exe-rename.js +259 -195
- package/dist/bin/exe-review.js +140 -64
- package/dist/bin/exe-search.js +543 -356
- package/dist/bin/exe-session-cleanup.js +463 -382
- package/dist/bin/exe-settings.js +129 -99
- package/dist/bin/exe-start.sh +6 -6
- package/dist/bin/exe-status.js +95 -36
- package/dist/bin/exe-team.js +116 -51
- package/dist/bin/git-sweep.js +482 -307
- package/dist/bin/graph-backfill.js +357 -245
- package/dist/bin/graph-export.js +324 -244
- package/dist/bin/install.js +33 -10
- package/dist/bin/scan-tasks.js +481 -307
- package/dist/bin/setup.js +1147 -140
- package/dist/bin/shard-migrate.js +321 -241
- package/dist/bin/update.js +1 -7
- package/dist/bin/wiki-sync.js +318 -238
- package/dist/gateway/index.js +2656 -1383
- package/dist/hooks/bug-report-worker.js +641 -472
- package/dist/hooks/commit-complete.js +482 -307
- package/dist/hooks/error-recall.js +363 -135
- package/dist/hooks/exe-heartbeat-hook.js +97 -27
- package/dist/hooks/ingest-worker.js +584 -397
- package/dist/hooks/ingest.js +123 -58
- package/dist/hooks/instructions-loaded.js +212 -82
- package/dist/hooks/notification.js +200 -70
- package/dist/hooks/post-compact.js +199 -81
- package/dist/hooks/pre-compact.js +352 -140
- package/dist/hooks/pre-tool-use.js +416 -278
- package/dist/hooks/prompt-ingest-worker.js +376 -299
- package/dist/hooks/prompt-submit.js +414 -188
- package/dist/hooks/response-ingest-worker.js +408 -338
- package/dist/hooks/session-end.js +209 -83
- package/dist/hooks/session-start.js +382 -158
- package/dist/hooks/stop.js +209 -83
- package/dist/hooks/subagent-stop.js +209 -85
- package/dist/hooks/summary-worker.js +606 -510
- package/dist/index.js +2133 -855
- package/dist/lib/cloud-sync.js +1175 -184
- package/dist/lib/config.js +1 -9
- package/dist/lib/consolidation.js +71 -34
- package/dist/lib/database.js +166 -14
- package/dist/lib/device-registry.js +189 -117
- package/dist/lib/embedder.js +6 -10
- package/dist/lib/employee-templates.js +134 -39
- package/dist/lib/employees.js +30 -7
- package/dist/lib/exe-daemon-client.js +5 -7
- package/dist/lib/exe-daemon.js +514 -152
- package/dist/lib/hybrid-search.js +543 -356
- package/dist/lib/identity-templates.js +15 -15
- package/dist/lib/identity.js +19 -15
- package/dist/lib/license.js +1 -7
- package/dist/lib/messaging.js +157 -135
- package/dist/lib/reminders.js +97 -0
- package/dist/lib/schedules.js +302 -231
- package/dist/lib/skill-learning.js +33 -27
- package/dist/lib/status-brief.js +11 -14
- package/dist/lib/store.js +326 -237
- package/dist/lib/task-router.js +105 -1
- package/dist/lib/tasks.js +233 -116
- package/dist/lib/tmux-routing.js +173 -56
- package/dist/lib/ws-client.js +13 -3
- package/dist/mcp/server.js +2009 -1015
- package/dist/mcp/tools/complete-reminder.js +97 -0
- package/dist/mcp/tools/create-reminder.js +97 -0
- package/dist/mcp/tools/create-task.js +426 -262
- package/dist/mcp/tools/deactivate-behavior.js +119 -44
- package/dist/mcp/tools/list-reminders.js +97 -0
- package/dist/mcp/tools/list-tasks.js +56 -57
- package/dist/mcp/tools/send-message.js +206 -143
- package/dist/mcp/tools/update-task.js +259 -85
- package/dist/runtime/index.js +495 -316
- package/dist/tui/App.js +1128 -919
- package/package.json +2 -10
- package/src/commands/exe/afk.md +8 -8
- package/src/commands/exe/assign.md +1 -1
- package/src/commands/exe/build-adv.md +1 -1
- package/src/commands/exe/call.md +10 -10
- package/src/commands/exe/employee-heartbeat.md +9 -6
- package/src/commands/exe/heartbeat.md +5 -5
- package/src/commands/exe/intercom.md +26 -15
- package/src/commands/exe/launch.md +2 -2
- package/src/commands/exe/new-employee.md +1 -1
- package/src/commands/exe/review.md +2 -2
- package/src/commands/exe/schedule.md +1 -1
- package/src/commands/exe/sessions.md +2 -2
- package/src/commands/exe.md +22 -20
|
@@ -9,7 +9,7 @@ Do not repeatedly attempt tool calls that fail \u2014 switch to planning mode.
|
|
|
9
9
|
`;
|
|
10
10
|
var POST_WORK_CHECKLIST = `
|
|
11
11
|
5. Check for pending reviews (list_tasks status='needs_review' where you are reviewer) \u2014 reviews are work, process before new tasks
|
|
12
|
-
6. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to
|
|
12
|
+
6. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to the COO immediately.
|
|
13
13
|
8. Check for next task \u2014 auto-chain through the queue without waiting
|
|
14
14
|
|
|
15
15
|
## Spawning Rules (mandatory)
|
|
@@ -83,7 +83,7 @@ Never say "I have no memories" without first searching broadly. Your memory may
|
|
|
83
83
|
- **create_task** \u2014 assign work to specialists with clear specs
|
|
84
84
|
- **update_task / close_task** \u2014 finalize reviews, mark work done
|
|
85
85
|
- **store_behavior** \u2014 record corrections as behavioral rules (p0/p1/p2)
|
|
86
|
-
- **update_identity** \u2014 rewrite any agent's identity when role/responsibilities change (
|
|
86
|
+
- **update_identity** \u2014 rewrite any agent's identity when role/responsibilities change (COO/founder only)
|
|
87
87
|
- **get_identity** \u2014 read any agent's identity for coordination
|
|
88
88
|
- **send_message** \u2014 direct intercom to employees
|
|
89
89
|
${PLAN_MODE_COMPAT}
|
|
@@ -94,7 +94,7 @@ ${PLAN_MODE_COMPAT}
|
|
|
94
94
|
3. Call **update_task** with status "done" and a structured result summary
|
|
95
95
|
4. Call **store_memory** with a report: what was done, decisions made, open items
|
|
96
96
|
5. Check for pending reviews (list_tasks status='needs_review' where you are reviewer) \u2014 reviews are work, process before new tasks
|
|
97
|
-
6. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to
|
|
97
|
+
6. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to the COO immediately.
|
|
98
98
|
8. Check for next task \u2014 auto-chain through the queue without waiting
|
|
99
99
|
|
|
100
100
|
## Spawning Rules (mandatory)
|
|
@@ -134,7 +134,7 @@ You are \${agent_id}. CTO. You hold deep context on the entire codebase, archite
|
|
|
134
134
|
|
|
135
135
|
- Long-term maintainability over short-term velocity.
|
|
136
136
|
- If a pattern exists in the codebase, follow it. Don't invent new approaches.
|
|
137
|
-
- Decompose: 3+ independent deliverables \u2192 delegate to
|
|
137
|
+
- Decompose: 3+ independent deliverables \u2192 delegate to engineer instances.
|
|
138
138
|
- Focus review on architecture: backward compatibility, tech debt, consistency with existing patterns.
|
|
139
139
|
- When blocked, report immediately with what you've tried and what you need.
|
|
140
140
|
|
|
@@ -150,7 +150,7 @@ You are \${agent_id}. CTO. You hold deep context on the entire codebase, archite
|
|
|
150
150
|
|
|
151
151
|
## Tools
|
|
152
152
|
|
|
153
|
-
- **create_task** \u2014 assign implementation work to
|
|
153
|
+
- **create_task** \u2014 assign implementation work to engineers with file paths, interfaces, acceptance criteria
|
|
154
154
|
- **list_tasks** \u2014 check engineer queues, monitor progress
|
|
155
155
|
- **update_task** \u2014 mark your own tasks done with result summary
|
|
156
156
|
- **recall_my_memory / ask_team_memory** \u2014 persist and retrieve technical decisions
|
|
@@ -166,7 +166,7 @@ ${PLAN_MODE_COMPAT}
|
|
|
166
166
|
4. Call **update_task** with status "done" and result summary (files changed, tests, decisions)
|
|
167
167
|
5. Call **store_memory** with structured report for org visibility
|
|
168
168
|
6. Check for pending reviews (list_tasks status='needs_review' where you are reviewer) \u2014 reviews are work, process before new tasks
|
|
169
|
-
7. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to
|
|
169
|
+
7. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to the COO immediately.
|
|
170
170
|
8. Check for next task \u2014 auto-chain through the queue
|
|
171
171
|
|
|
172
172
|
## Spawning Rules (mandatory)
|
|
@@ -200,7 +200,7 @@ You are \${agent_id}. CMO. You hold deep context on design, branding, storytelli
|
|
|
200
200
|
- Never ship content without verifying tone, format, and channel requirements.
|
|
201
201
|
- SEO/AEO/GEO considerations on every piece of public content.
|
|
202
202
|
- Commit immediately after verification \u2014 don't wait for approval.
|
|
203
|
-
- Report every completion with structured summary to
|
|
203
|
+
- Report every completion with structured summary to the COO.
|
|
204
204
|
|
|
205
205
|
## Operating Principles
|
|
206
206
|
|
|
@@ -234,7 +234,7 @@ ${PLAN_MODE_COMPAT}
|
|
|
234
234
|
5. Call **update_task** with status "done" and result summary
|
|
235
235
|
6. Call **store_memory** with structured report: deliverables, decisions, brand notes
|
|
236
236
|
7. Check for pending reviews (list_tasks status='needs_review' where you are reviewer) \u2014 reviews are work, process before new tasks
|
|
237
|
-
8. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to
|
|
237
|
+
8. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to the COO immediately.
|
|
238
238
|
9. Check for next task \u2014 auto-chain through the queue
|
|
239
239
|
|
|
240
240
|
## Spawning Rules (mandatory)
|
|
@@ -272,7 +272,7 @@ You are a principal engineer. You write production-grade code with zero shortcut
|
|
|
272
272
|
|
|
273
273
|
## Operating Principles
|
|
274
274
|
|
|
275
|
-
-
|
|
275
|
+
- The CTO specs and reviews. You implement. If the spec is wrong, report it \u2014 don't deviate.
|
|
276
276
|
- Fast, correct, clean \u2014 in that order. Never sacrifice correct for fast.
|
|
277
277
|
- Don't over-engineer. Build what the spec asks for, nothing more.
|
|
278
278
|
- Three similar lines is fine. Don't abstract until there's a fourth.
|
|
@@ -282,7 +282,7 @@ You are a principal engineer. You write production-grade code with zero shortcut
|
|
|
282
282
|
|
|
283
283
|
- Architecture decisions \u2014 that's the CTO
|
|
284
284
|
- Marketing, content, design \u2014 that's the CMO
|
|
285
|
-
- Prioritization, coordination \u2014 that's
|
|
285
|
+
- Prioritization, coordination \u2014 that's the COO
|
|
286
286
|
- You implement. That's it.
|
|
287
287
|
|
|
288
288
|
## Tools
|
|
@@ -301,7 +301,7 @@ ${PLAN_MODE_COMPAT}
|
|
|
301
301
|
5. Call **update_task** with status "done" and result (files changed, tests pass/fail, decisions)
|
|
302
302
|
6. Call **store_memory** with structured report
|
|
303
303
|
7. Check for pending reviews (list_tasks status='needs_review' where you are reviewer) \u2014 reviews are work, process before new tasks
|
|
304
|
-
8. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to
|
|
304
|
+
8. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to the COO immediately.
|
|
305
305
|
9. Check for next task \u2014 auto-chain through the queue
|
|
306
306
|
|
|
307
307
|
## Spawning Rules (mandatory)
|
|
@@ -333,7 +333,7 @@ You are the content production specialist. You turn scripts and creative briefs
|
|
|
333
333
|
## Non-Negotiables
|
|
334
334
|
|
|
335
335
|
- Check budget before generating. Never burn credits without knowing the cost.
|
|
336
|
-
- Follow the script.
|
|
336
|
+
- Follow the script. The CMO's creative brief is your spec. Don't improvise on brand/tone.
|
|
337
337
|
- Match the platform: 16:9 for YouTube, 9:16 for TikTok/Reels, 1:1 for Instagram feed.
|
|
338
338
|
- All final assets go to exe/output/ with clear naming.
|
|
339
339
|
- Commit immediately after verification \u2014 don't wait for approval.
|
|
@@ -343,7 +343,7 @@ You are the content production specialist. You turn scripts and creative briefs
|
|
|
343
343
|
- Iterate in drafts. Use cheaper models for exploration, premium for finals.
|
|
344
344
|
- Naming: {project}-{type}-{version}.{ext}
|
|
345
345
|
- Store production decisions in memory \u2014 which models worked, which prompts produced good results.
|
|
346
|
-
-
|
|
346
|
+
- The CMO directs creatively. The CTO builds tools. You produce. Stay in your lane.
|
|
347
347
|
|
|
348
348
|
## Tools
|
|
349
349
|
|
|
@@ -362,7 +362,7 @@ ${PLAN_MODE_COMPAT}
|
|
|
362
362
|
6. Call **update_task** with status "done" and result summary
|
|
363
363
|
7. Call **store_memory** with structured report: deliverables, models used, cost, decisions
|
|
364
364
|
8. Check for pending reviews (list_tasks status='needs_review' where you are reviewer) \u2014 reviews are work, process before new tasks
|
|
365
|
-
9. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to
|
|
365
|
+
9. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to the COO immediately.
|
|
366
366
|
10. Check for next task \u2014 auto-chain through the queue
|
|
367
367
|
|
|
368
368
|
## Spawning Rules (mandatory)
|
|
@@ -433,7 +433,7 @@ ${PLAN_MODE_COMPAT}
|
|
|
433
433
|
5. Call **update_task** with status "done" and evaluation summary
|
|
434
434
|
6. Call **store_memory** with structured report
|
|
435
435
|
7. Check for pending reviews (list_tasks status='needs_review' where you are reviewer) \u2014 reviews are work, process before new tasks
|
|
436
|
-
8. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to
|
|
436
|
+
8. Check for blocked tasks (list_tasks status='blocked') \u2014 can you unblock it? Do it now. Can't? Escalate to the COO immediately.
|
|
437
437
|
9. Check for next task \u2014 auto-chain through the queue without waiting
|
|
438
438
|
|
|
439
439
|
## Spawning Rules (mandatory)
|
package/dist/lib/identity.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/lib/identity.ts
|
|
2
|
-
import { existsSync as
|
|
2
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
3
3
|
import { readdirSync } from "fs";
|
|
4
|
-
import
|
|
4
|
+
import path3 from "path";
|
|
5
5
|
import { createHash } from "crypto";
|
|
6
6
|
|
|
7
7
|
// src/lib/config.ts
|
|
@@ -64,13 +64,7 @@ var DEFAULT_CONFIG = {
|
|
|
64
64
|
wikiUrl: "",
|
|
65
65
|
wikiApiKey: "",
|
|
66
66
|
wikiSyncIntervalMs: 30 * 60 * 1e3,
|
|
67
|
-
wikiWorkspaceMapping: {
|
|
68
|
-
exe: "Executive",
|
|
69
|
-
yoshi: "Engineering",
|
|
70
|
-
mari: "Marketing",
|
|
71
|
-
tom: "Engineering",
|
|
72
|
-
sasha: "Production"
|
|
73
|
-
},
|
|
67
|
+
wikiWorkspaceMapping: {},
|
|
74
68
|
wikiAutoUpdate: true,
|
|
75
69
|
wikiAutoUpdateThreshold: 0.5,
|
|
76
70
|
wikiAutoUpdateCreateNew: true,
|
|
@@ -97,6 +91,16 @@ var DEFAULT_CONFIG = {
|
|
|
97
91
|
|
|
98
92
|
// src/lib/database.ts
|
|
99
93
|
import { createClient } from "@libsql/client";
|
|
94
|
+
|
|
95
|
+
// src/lib/employees.ts
|
|
96
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
97
|
+
import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
98
|
+
import { execSync } from "child_process";
|
|
99
|
+
import path2 from "path";
|
|
100
|
+
import os2 from "os";
|
|
101
|
+
var EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
|
|
102
|
+
|
|
103
|
+
// src/lib/database.ts
|
|
100
104
|
var _resilientClient = null;
|
|
101
105
|
function getClient() {
|
|
102
106
|
if (!_resilientClient) {
|
|
@@ -106,14 +110,14 @@ function getClient() {
|
|
|
106
110
|
}
|
|
107
111
|
|
|
108
112
|
// src/lib/identity.ts
|
|
109
|
-
var IDENTITY_DIR =
|
|
113
|
+
var IDENTITY_DIR = path3.join(EXE_AI_DIR, "identity");
|
|
110
114
|
function ensureDir() {
|
|
111
|
-
if (!
|
|
115
|
+
if (!existsSync3(IDENTITY_DIR)) {
|
|
112
116
|
mkdirSync(IDENTITY_DIR, { recursive: true });
|
|
113
117
|
}
|
|
114
118
|
}
|
|
115
119
|
function identityPath(agentId) {
|
|
116
|
-
return
|
|
120
|
+
return path3.join(IDENTITY_DIR, `${agentId}.md`);
|
|
117
121
|
}
|
|
118
122
|
function parseFrontmatter(raw) {
|
|
119
123
|
const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
@@ -154,8 +158,8 @@ function contentHash(content) {
|
|
|
154
158
|
}
|
|
155
159
|
function getIdentity(agentId) {
|
|
156
160
|
const filePath = identityPath(agentId);
|
|
157
|
-
if (!
|
|
158
|
-
const raw =
|
|
161
|
+
if (!existsSync3(filePath)) return null;
|
|
162
|
+
const raw = readFileSync3(filePath, "utf-8");
|
|
159
163
|
const { frontmatter, body } = parseFrontmatter(raw);
|
|
160
164
|
return {
|
|
161
165
|
agentId,
|
|
@@ -169,7 +173,7 @@ async function updateIdentity(agentId, content, updatedBy) {
|
|
|
169
173
|
ensureDir();
|
|
170
174
|
const filePath = identityPath(agentId);
|
|
171
175
|
const hash = contentHash(content);
|
|
172
|
-
|
|
176
|
+
writeFileSync2(filePath, content, "utf-8");
|
|
173
177
|
try {
|
|
174
178
|
const client = getClient();
|
|
175
179
|
await client.execute({
|
package/dist/lib/license.js
CHANGED
|
@@ -71,13 +71,7 @@ var DEFAULT_CONFIG = {
|
|
|
71
71
|
wikiUrl: "",
|
|
72
72
|
wikiApiKey: "",
|
|
73
73
|
wikiSyncIntervalMs: 30 * 60 * 1e3,
|
|
74
|
-
wikiWorkspaceMapping: {
|
|
75
|
-
exe: "Executive",
|
|
76
|
-
yoshi: "Engineering",
|
|
77
|
-
mari: "Marketing",
|
|
78
|
-
tom: "Engineering",
|
|
79
|
-
sasha: "Production"
|
|
80
|
-
},
|
|
74
|
+
wikiWorkspaceMapping: {},
|
|
81
75
|
wikiAutoUpdate: true,
|
|
82
76
|
wikiAutoUpdateThreshold: 0.5,
|
|
83
77
|
wikiAutoUpdateCreateNew: true,
|
package/dist/lib/messaging.js
CHANGED
|
@@ -26,6 +26,134 @@ var init_db_retry = __esm({
|
|
|
26
26
|
}
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
+
// src/lib/config.ts
|
|
30
|
+
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
31
|
+
import { readFileSync, existsSync, renameSync } from "fs";
|
|
32
|
+
import path from "path";
|
|
33
|
+
import os from "os";
|
|
34
|
+
function resolveDataDir() {
|
|
35
|
+
if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
|
|
36
|
+
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
37
|
+
const newDir = path.join(os.homedir(), ".exe-os");
|
|
38
|
+
const legacyDir = path.join(os.homedir(), ".exe-mem");
|
|
39
|
+
if (!existsSync(newDir) && existsSync(legacyDir)) {
|
|
40
|
+
try {
|
|
41
|
+
renameSync(legacyDir, newDir);
|
|
42
|
+
process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
|
|
43
|
+
`);
|
|
44
|
+
} catch {
|
|
45
|
+
return legacyDir;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return newDir;
|
|
49
|
+
}
|
|
50
|
+
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG;
|
|
51
|
+
var init_config = __esm({
|
|
52
|
+
"src/lib/config.ts"() {
|
|
53
|
+
"use strict";
|
|
54
|
+
EXE_AI_DIR = resolveDataDir();
|
|
55
|
+
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
56
|
+
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
57
|
+
CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
|
|
58
|
+
LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
|
|
59
|
+
CURRENT_CONFIG_VERSION = 1;
|
|
60
|
+
DEFAULT_CONFIG = {
|
|
61
|
+
config_version: CURRENT_CONFIG_VERSION,
|
|
62
|
+
dbPath: DB_PATH,
|
|
63
|
+
modelFile: "jina-embeddings-v5-small-q4_k_m.gguf",
|
|
64
|
+
embeddingDim: 1024,
|
|
65
|
+
batchSize: 20,
|
|
66
|
+
flushIntervalMs: 1e4,
|
|
67
|
+
autoIngestion: true,
|
|
68
|
+
autoRetrieval: true,
|
|
69
|
+
searchMode: "hybrid",
|
|
70
|
+
hookSearchMode: "hybrid",
|
|
71
|
+
fileGrepEnabled: true,
|
|
72
|
+
splashEffect: true,
|
|
73
|
+
consolidationEnabled: true,
|
|
74
|
+
consolidationIntervalMs: 6 * 60 * 60 * 1e3,
|
|
75
|
+
consolidationModel: "claude-haiku-4-5-20251001",
|
|
76
|
+
consolidationMaxCallsPerRun: 20,
|
|
77
|
+
selfQueryRouter: true,
|
|
78
|
+
selfQueryModel: "claude-haiku-4-5-20251001",
|
|
79
|
+
rerankerEnabled: true,
|
|
80
|
+
scalingRoadmap: {
|
|
81
|
+
rerankerAutoTrigger: {
|
|
82
|
+
enabled: true,
|
|
83
|
+
broadQueryMinCardinality: 5e4,
|
|
84
|
+
fetchTopK: 150,
|
|
85
|
+
returnTopK: 5
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
graphRagEnabled: true,
|
|
89
|
+
wikiEnabled: false,
|
|
90
|
+
wikiUrl: "",
|
|
91
|
+
wikiApiKey: "",
|
|
92
|
+
wikiSyncIntervalMs: 30 * 60 * 1e3,
|
|
93
|
+
wikiWorkspaceMapping: {},
|
|
94
|
+
wikiAutoUpdate: true,
|
|
95
|
+
wikiAutoUpdateThreshold: 0.5,
|
|
96
|
+
wikiAutoUpdateCreateNew: true,
|
|
97
|
+
skillLearning: true,
|
|
98
|
+
skillThreshold: 3,
|
|
99
|
+
skillModel: "claude-haiku-4-5-20251001",
|
|
100
|
+
exeHeartbeat: {
|
|
101
|
+
enabled: true,
|
|
102
|
+
intervalSeconds: 60,
|
|
103
|
+
staleInProgressThresholdHours: 2
|
|
104
|
+
},
|
|
105
|
+
sessionLifecycle: {
|
|
106
|
+
idleKillEnabled: true,
|
|
107
|
+
idleKillTicksRequired: 3,
|
|
108
|
+
idleKillIntercomAckWindowMs: 1e4,
|
|
109
|
+
maxAutoInstances: 10
|
|
110
|
+
},
|
|
111
|
+
autoUpdate: {
|
|
112
|
+
checkOnBoot: true,
|
|
113
|
+
autoInstall: false,
|
|
114
|
+
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// src/lib/employees.ts
|
|
121
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
122
|
+
import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
123
|
+
import { execSync } from "child_process";
|
|
124
|
+
import path2 from "path";
|
|
125
|
+
import os2 from "os";
|
|
126
|
+
function normalizeRole(role) {
|
|
127
|
+
return (role ?? "").trim().toLowerCase();
|
|
128
|
+
}
|
|
129
|
+
function isCoordinatorRole(role) {
|
|
130
|
+
return normalizeRole(role) === normalizeRole(COORDINATOR_ROLE);
|
|
131
|
+
}
|
|
132
|
+
function getCoordinatorEmployee(employees) {
|
|
133
|
+
return employees.find((e) => isCoordinatorRole(e.role));
|
|
134
|
+
}
|
|
135
|
+
function getCoordinatorName(employees = loadEmployeesSync()) {
|
|
136
|
+
return getCoordinatorEmployee(employees)?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
|
|
137
|
+
}
|
|
138
|
+
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
139
|
+
if (!existsSync2(employeesPath)) return [];
|
|
140
|
+
try {
|
|
141
|
+
return JSON.parse(readFileSync2(employeesPath, "utf-8"));
|
|
142
|
+
} catch {
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE;
|
|
147
|
+
var init_employees = __esm({
|
|
148
|
+
"src/lib/employees.ts"() {
|
|
149
|
+
"use strict";
|
|
150
|
+
init_config();
|
|
151
|
+
EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
|
|
152
|
+
DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
|
|
153
|
+
COORDINATOR_ROLE = "COO";
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
29
157
|
// src/lib/database.ts
|
|
30
158
|
import { createClient } from "@libsql/client";
|
|
31
159
|
function getClient() {
|
|
@@ -39,29 +167,30 @@ var init_database = __esm({
|
|
|
39
167
|
"src/lib/database.ts"() {
|
|
40
168
|
"use strict";
|
|
41
169
|
init_db_retry();
|
|
170
|
+
init_employees();
|
|
42
171
|
_resilientClient = null;
|
|
43
172
|
}
|
|
44
173
|
});
|
|
45
174
|
|
|
46
175
|
// src/lib/session-registry.ts
|
|
47
|
-
import
|
|
48
|
-
import
|
|
176
|
+
import path3 from "path";
|
|
177
|
+
import os3 from "os";
|
|
49
178
|
var REGISTRY_PATH;
|
|
50
179
|
var init_session_registry = __esm({
|
|
51
180
|
"src/lib/session-registry.ts"() {
|
|
52
181
|
"use strict";
|
|
53
|
-
REGISTRY_PATH =
|
|
182
|
+
REGISTRY_PATH = path3.join(os3.homedir(), ".exe-os", "session-registry.json");
|
|
54
183
|
}
|
|
55
184
|
});
|
|
56
185
|
|
|
57
186
|
// src/lib/session-key.ts
|
|
58
|
-
import { execSync } from "child_process";
|
|
187
|
+
import { execSync as execSync2 } from "child_process";
|
|
59
188
|
function getSessionKey() {
|
|
60
189
|
if (_cached) return _cached;
|
|
61
190
|
let pid = process.ppid;
|
|
62
191
|
for (let i = 0; i < 10; i++) {
|
|
63
192
|
try {
|
|
64
|
-
const info =
|
|
193
|
+
const info = execSync2(`ps -p ${pid} -o ppid=,comm=`, {
|
|
65
194
|
encoding: "utf8",
|
|
66
195
|
timeout: 2e3
|
|
67
196
|
}).trim();
|
|
@@ -197,7 +326,7 @@ var init_transport = __esm({
|
|
|
197
326
|
});
|
|
198
327
|
|
|
199
328
|
// src/lib/cc-agent-support.ts
|
|
200
|
-
import { execSync as
|
|
329
|
+
import { execSync as execSync3 } from "child_process";
|
|
201
330
|
var init_cc_agent_support = __esm({
|
|
202
331
|
"src/lib/cc-agent-support.ts"() {
|
|
203
332
|
"use strict";
|
|
@@ -226,17 +355,17 @@ var init_provider_table = __esm({
|
|
|
226
355
|
});
|
|
227
356
|
|
|
228
357
|
// src/lib/intercom-queue.ts
|
|
229
|
-
import { readFileSync, writeFileSync, renameSync, existsSync, mkdirSync } from "fs";
|
|
230
|
-
import
|
|
231
|
-
import
|
|
358
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, renameSync as renameSync3, existsSync as existsSync3, mkdirSync } from "fs";
|
|
359
|
+
import path4 from "path";
|
|
360
|
+
import os4 from "os";
|
|
232
361
|
function ensureDir() {
|
|
233
|
-
const dir =
|
|
234
|
-
if (!
|
|
362
|
+
const dir = path4.dirname(QUEUE_PATH);
|
|
363
|
+
if (!existsSync3(dir)) mkdirSync(dir, { recursive: true });
|
|
235
364
|
}
|
|
236
365
|
function readQueue() {
|
|
237
366
|
try {
|
|
238
|
-
if (!
|
|
239
|
-
return JSON.parse(
|
|
367
|
+
if (!existsSync3(QUEUE_PATH)) return [];
|
|
368
|
+
return JSON.parse(readFileSync3(QUEUE_PATH, "utf8"));
|
|
240
369
|
} catch {
|
|
241
370
|
return [];
|
|
242
371
|
}
|
|
@@ -244,8 +373,8 @@ function readQueue() {
|
|
|
244
373
|
function writeQueue(queue) {
|
|
245
374
|
ensureDir();
|
|
246
375
|
const tmp = `${QUEUE_PATH}.tmp`;
|
|
247
|
-
|
|
248
|
-
|
|
376
|
+
writeFileSync2(tmp, JSON.stringify(queue, null, 2));
|
|
377
|
+
renameSync3(tmp, QUEUE_PATH);
|
|
249
378
|
}
|
|
250
379
|
function queueIntercom(targetSession, reason) {
|
|
251
380
|
const queue = readQueue();
|
|
@@ -268,121 +397,9 @@ var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
|
268
397
|
var init_intercom_queue = __esm({
|
|
269
398
|
"src/lib/intercom-queue.ts"() {
|
|
270
399
|
"use strict";
|
|
271
|
-
QUEUE_PATH =
|
|
400
|
+
QUEUE_PATH = path4.join(os4.homedir(), ".exe-os", "intercom-queue.json");
|
|
272
401
|
TTL_MS = 60 * 60 * 1e3;
|
|
273
|
-
INTERCOM_LOG =
|
|
274
|
-
}
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
// src/lib/config.ts
|
|
278
|
-
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
279
|
-
import { readFileSync as readFileSync2, existsSync as existsSync2, renameSync as renameSync2 } from "fs";
|
|
280
|
-
import path3 from "path";
|
|
281
|
-
import os3 from "os";
|
|
282
|
-
function resolveDataDir() {
|
|
283
|
-
if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
|
|
284
|
-
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
285
|
-
const newDir = path3.join(os3.homedir(), ".exe-os");
|
|
286
|
-
const legacyDir = path3.join(os3.homedir(), ".exe-mem");
|
|
287
|
-
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
288
|
-
try {
|
|
289
|
-
renameSync2(legacyDir, newDir);
|
|
290
|
-
process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
|
|
291
|
-
`);
|
|
292
|
-
} catch {
|
|
293
|
-
return legacyDir;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
return newDir;
|
|
297
|
-
}
|
|
298
|
-
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG;
|
|
299
|
-
var init_config = __esm({
|
|
300
|
-
"src/lib/config.ts"() {
|
|
301
|
-
"use strict";
|
|
302
|
-
EXE_AI_DIR = resolveDataDir();
|
|
303
|
-
DB_PATH = path3.join(EXE_AI_DIR, "memories.db");
|
|
304
|
-
MODELS_DIR = path3.join(EXE_AI_DIR, "models");
|
|
305
|
-
CONFIG_PATH = path3.join(EXE_AI_DIR, "config.json");
|
|
306
|
-
LEGACY_LANCE_PATH = path3.join(EXE_AI_DIR, "local.lance");
|
|
307
|
-
CURRENT_CONFIG_VERSION = 1;
|
|
308
|
-
DEFAULT_CONFIG = {
|
|
309
|
-
config_version: CURRENT_CONFIG_VERSION,
|
|
310
|
-
dbPath: DB_PATH,
|
|
311
|
-
modelFile: "jina-embeddings-v5-small-q4_k_m.gguf",
|
|
312
|
-
embeddingDim: 1024,
|
|
313
|
-
batchSize: 20,
|
|
314
|
-
flushIntervalMs: 1e4,
|
|
315
|
-
autoIngestion: true,
|
|
316
|
-
autoRetrieval: true,
|
|
317
|
-
searchMode: "hybrid",
|
|
318
|
-
hookSearchMode: "hybrid",
|
|
319
|
-
fileGrepEnabled: true,
|
|
320
|
-
splashEffect: true,
|
|
321
|
-
consolidationEnabled: true,
|
|
322
|
-
consolidationIntervalMs: 6 * 60 * 60 * 1e3,
|
|
323
|
-
consolidationModel: "claude-haiku-4-5-20251001",
|
|
324
|
-
consolidationMaxCallsPerRun: 20,
|
|
325
|
-
selfQueryRouter: true,
|
|
326
|
-
selfQueryModel: "claude-haiku-4-5-20251001",
|
|
327
|
-
rerankerEnabled: true,
|
|
328
|
-
scalingRoadmap: {
|
|
329
|
-
rerankerAutoTrigger: {
|
|
330
|
-
enabled: true,
|
|
331
|
-
broadQueryMinCardinality: 5e4,
|
|
332
|
-
fetchTopK: 150,
|
|
333
|
-
returnTopK: 5
|
|
334
|
-
}
|
|
335
|
-
},
|
|
336
|
-
graphRagEnabled: true,
|
|
337
|
-
wikiEnabled: false,
|
|
338
|
-
wikiUrl: "",
|
|
339
|
-
wikiApiKey: "",
|
|
340
|
-
wikiSyncIntervalMs: 30 * 60 * 1e3,
|
|
341
|
-
wikiWorkspaceMapping: {
|
|
342
|
-
exe: "Executive",
|
|
343
|
-
yoshi: "Engineering",
|
|
344
|
-
mari: "Marketing",
|
|
345
|
-
tom: "Engineering",
|
|
346
|
-
sasha: "Production"
|
|
347
|
-
},
|
|
348
|
-
wikiAutoUpdate: true,
|
|
349
|
-
wikiAutoUpdateThreshold: 0.5,
|
|
350
|
-
wikiAutoUpdateCreateNew: true,
|
|
351
|
-
skillLearning: true,
|
|
352
|
-
skillThreshold: 3,
|
|
353
|
-
skillModel: "claude-haiku-4-5-20251001",
|
|
354
|
-
exeHeartbeat: {
|
|
355
|
-
enabled: true,
|
|
356
|
-
intervalSeconds: 60,
|
|
357
|
-
staleInProgressThresholdHours: 2
|
|
358
|
-
},
|
|
359
|
-
sessionLifecycle: {
|
|
360
|
-
idleKillEnabled: true,
|
|
361
|
-
idleKillTicksRequired: 3,
|
|
362
|
-
idleKillIntercomAckWindowMs: 1e4,
|
|
363
|
-
maxAutoInstances: 10
|
|
364
|
-
},
|
|
365
|
-
autoUpdate: {
|
|
366
|
-
checkOnBoot: true,
|
|
367
|
-
autoInstall: false,
|
|
368
|
-
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
369
|
-
}
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
// src/lib/employees.ts
|
|
375
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
376
|
-
import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync3, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
377
|
-
import { execSync as execSync3 } from "child_process";
|
|
378
|
-
import path4 from "path";
|
|
379
|
-
import os4 from "os";
|
|
380
|
-
var EMPLOYEES_PATH;
|
|
381
|
-
var init_employees = __esm({
|
|
382
|
-
"src/lib/employees.ts"() {
|
|
383
|
-
"use strict";
|
|
384
|
-
init_config();
|
|
385
|
-
EMPLOYEES_PATH = path4.join(EXE_AI_DIR, "exe-employees.json");
|
|
402
|
+
INTERCOM_LOG = path4.join(os4.homedir(), ".exe-os", "intercom.log");
|
|
386
403
|
}
|
|
387
404
|
});
|
|
388
405
|
|
|
@@ -439,7 +456,7 @@ function employeeSessionName(employee, exeSession, instance) {
|
|
|
439
456
|
exeSession = root;
|
|
440
457
|
} else {
|
|
441
458
|
throw new Error(
|
|
442
|
-
`Invalid
|
|
459
|
+
`Invalid coordinator session "${exeSession}" \u2014 contains a dash but no recognizable root session. Pass a root session name.`
|
|
443
460
|
);
|
|
444
461
|
}
|
|
445
462
|
}
|
|
@@ -453,8 +470,10 @@ function employeeSessionName(employee, exeSession, instance) {
|
|
|
453
470
|
return name;
|
|
454
471
|
}
|
|
455
472
|
function extractRootExe(name) {
|
|
456
|
-
|
|
457
|
-
|
|
473
|
+
if (!name) return null;
|
|
474
|
+
if (!name.includes("-")) return name;
|
|
475
|
+
const parts = name.split("-").filter(Boolean);
|
|
476
|
+
return parts.length > 0 ? parts[parts.length - 1] : null;
|
|
458
477
|
}
|
|
459
478
|
function getParentExe(sessionKey) {
|
|
460
479
|
try {
|
|
@@ -537,12 +556,14 @@ function getSessionState(sessionName) {
|
|
|
537
556
|
}
|
|
538
557
|
}
|
|
539
558
|
function isExeSession(sessionName) {
|
|
540
|
-
|
|
559
|
+
const matchesBaseWithInstance = (baseName) => sessionName === baseName || sessionName.startsWith(baseName) && /^\d+$/.test(sessionName.slice(baseName.length));
|
|
560
|
+
const coordinatorName = getCoordinatorName();
|
|
561
|
+
return matchesBaseWithInstance(coordinatorName) || matchesBaseWithInstance("exe");
|
|
541
562
|
}
|
|
542
563
|
function sendIntercom(targetSession) {
|
|
543
564
|
const transport = getTransport();
|
|
544
565
|
if (isExeSession(targetSession)) {
|
|
545
|
-
logIntercom(`
|
|
566
|
+
logIntercom(`SKIP_COORDINATOR \u2192 ${targetSession} (coordinator sessions use prompt-submit hook)`);
|
|
546
567
|
return "skipped_exe";
|
|
547
568
|
}
|
|
548
569
|
if (isDebounced(targetSession)) {
|
|
@@ -593,6 +614,7 @@ var init_tmux_routing = __esm({
|
|
|
593
614
|
init_provider_table();
|
|
594
615
|
init_intercom_queue();
|
|
595
616
|
init_plan_limits();
|
|
617
|
+
init_employees();
|
|
596
618
|
SPAWN_LOCK_DIR = path7.join(os5.homedir(), ".exe-os", "spawn-locks");
|
|
597
619
|
SESSION_CACHE = path7.join(os5.homedir(), ".exe-os", "session-cache");
|
|
598
620
|
VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
|
|
@@ -716,7 +738,7 @@ async function deliverLocalMessage(messageId) {
|
|
|
716
738
|
try {
|
|
717
739
|
const exeSession = resolveExeSession();
|
|
718
740
|
if (!exeSession) {
|
|
719
|
-
throw new Error("No
|
|
741
|
+
throw new Error("No coordinator session found");
|
|
720
742
|
}
|
|
721
743
|
const sessionName = employeeSessionName(targetAgent, exeSession);
|
|
722
744
|
if (!isEmployeeAlive(sessionName)) {
|