@askexenow/exe-os 0.8.1 → 0.8.2
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/package.json +1 -1
- package/dist/bin/backfill-responses.js +0 -2064
- package/dist/bin/backfill-vectors.js +0 -1771
- package/dist/bin/cleanup-stale-review-tasks.js +0 -1468
- package/dist/bin/cli.js +0 -21371
- package/dist/bin/exe-agent.js +0 -2016
- package/dist/bin/exe-assign.js +0 -2176
- package/dist/bin/exe-boot.js +0 -6332
- package/dist/bin/exe-call.js +0 -341
- package/dist/bin/exe-cloud.js +0 -861
- package/dist/bin/exe-dispatch.js +0 -1159
- package/dist/bin/exe-doctor.js +0 -1786
- package/dist/bin/exe-export-behaviors.js +0 -1637
- package/dist/bin/exe-forget.js +0 -1784
- package/dist/bin/exe-gateway.js +0 -8140
- package/dist/bin/exe-healthcheck.js +0 -207
- package/dist/bin/exe-heartbeat.js +0 -1778
- package/dist/bin/exe-kill.js +0 -1622
- package/dist/bin/exe-launch-agent.js +0 -1847
- package/dist/bin/exe-link.js +0 -192
- package/dist/bin/exe-new-employee.js +0 -1384
- package/dist/bin/exe-pending-messages.js +0 -1576
- package/dist/bin/exe-pending-notifications.js +0 -1450
- package/dist/bin/exe-pending-reviews.js +0 -1598
- package/dist/bin/exe-repo-drift.js +0 -95
- package/dist/bin/exe-review.js +0 -1742
- package/dist/bin/exe-search.js +0 -3116
- package/dist/bin/exe-session-cleanup.js +0 -3360
- package/dist/bin/exe-settings.js +0 -365
- package/dist/bin/exe-status.js +0 -1661
- package/dist/bin/exe-team.js +0 -1453
- package/dist/bin/git-sweep.js +0 -2441
- package/dist/bin/graph-backfill.js +0 -2111
- package/dist/bin/graph-export.js +0 -1747
- package/dist/bin/install.js +0 -661
- package/dist/bin/list-providers.js +0 -140
- package/dist/bin/scan-tasks.js +0 -2039
- package/dist/bin/setup.js +0 -2717
- package/dist/bin/shard-migrate.js +0 -1637
- package/dist/bin/update.js +0 -98
- package/dist/bin/wiki-sync.js +0 -1657
- package/dist/gateway/index.js +0 -9256
- package/dist/hooks/bug-report-worker.js +0 -2903
- package/dist/hooks/commit-complete.js +0 -2364
- package/dist/hooks/error-recall.js +0 -3327
- package/dist/hooks/exe-heartbeat-hook.js +0 -237
- package/dist/hooks/ingest-worker.js +0 -5065
- package/dist/hooks/ingest.js +0 -695
- package/dist/hooks/instructions-loaded.js +0 -2069
- package/dist/hooks/notification.js +0 -1915
- package/dist/hooks/post-compact.js +0 -1940
- package/dist/hooks/pre-compact.js +0 -1935
- package/dist/hooks/pre-tool-use.js +0 -2380
- package/dist/hooks/prompt-ingest-worker.js +0 -2291
- package/dist/hooks/prompt-submit.js +0 -5189
- package/dist/hooks/response-ingest-worker.js +0 -2431
- package/dist/hooks/session-end.js +0 -2196
- package/dist/hooks/session-start.js +0 -3259
- package/dist/hooks/stop.js +0 -2025
- package/dist/hooks/subagent-stop.js +0 -1915
- package/dist/hooks/summary-worker.js +0 -2931
- package/dist/index.js +0 -12327
- package/dist/lib/cloud-sync.js +0 -500
- package/dist/lib/config.js +0 -235
- package/dist/lib/consolidation.js +0 -481
- package/dist/lib/crypto.js +0 -51
- package/dist/lib/database.js +0 -834
- package/dist/lib/device-registry.js +0 -1009
- package/dist/lib/embedder.js +0 -645
- package/dist/lib/employee-templates.js +0 -570
- package/dist/lib/employees.js +0 -182
- package/dist/lib/error-detector.js +0 -156
- package/dist/lib/exe-daemon-client.js +0 -456
- package/dist/lib/exe-daemon.js +0 -8699
- package/dist/lib/file-grep.js +0 -215
- package/dist/lib/hybrid-search.js +0 -3064
- package/dist/lib/identity-templates.js +0 -441
- package/dist/lib/identity.js +0 -228
- package/dist/lib/keychain.js +0 -145
- package/dist/lib/license.js +0 -382
- package/dist/lib/messaging.js +0 -1389
- package/dist/lib/reminders.js +0 -63
- package/dist/lib/schedules.js +0 -1525
- package/dist/lib/session-registry.js +0 -52
- package/dist/lib/skill-learning.js +0 -488
- package/dist/lib/status-brief.js +0 -240
- package/dist/lib/store.js +0 -1740
- package/dist/lib/task-router.js +0 -128
- package/dist/lib/tasks.js +0 -2585
- package/dist/lib/tmux-routing.js +0 -2969
- package/dist/lib/tmux-status.js +0 -261
- package/dist/lib/tmux-transport.js +0 -83
- package/dist/lib/transport.js +0 -128
- package/dist/lib/ws-auth.js +0 -19
- package/dist/lib/ws-client.js +0 -160
- package/dist/mcp/server.js +0 -10812
- package/dist/mcp/tools/complete-reminder.js +0 -67
- package/dist/mcp/tools/create-reminder.js +0 -52
- package/dist/mcp/tools/create-task.js +0 -1903
- package/dist/mcp/tools/deactivate-behavior.js +0 -268
- package/dist/mcp/tools/list-reminders.js +0 -62
- package/dist/mcp/tools/list-tasks.js +0 -491
- package/dist/mcp/tools/send-message.js +0 -1395
- package/dist/mcp/tools/update-task.js +0 -1807
- package/dist/runtime/index.js +0 -7201
- package/dist/tui/App.js +0 -17874
package/dist/bin/exe-call.js
DELETED
|
@@ -1,341 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/bin/exe-call.ts
|
|
4
|
-
import path3 from "path";
|
|
5
|
-
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
6
|
-
import { execSync as execSync2 } from "child_process";
|
|
7
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
8
|
-
|
|
9
|
-
// src/lib/employees.ts
|
|
10
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
11
|
-
import { existsSync as existsSync2, symlinkSync, readlinkSync } from "fs";
|
|
12
|
-
import { execSync } from "child_process";
|
|
13
|
-
import path2 from "path";
|
|
14
|
-
|
|
15
|
-
// src/lib/config.ts
|
|
16
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
17
|
-
import { readFileSync, existsSync, renameSync } from "fs";
|
|
18
|
-
import path from "path";
|
|
19
|
-
import os from "os";
|
|
20
|
-
function resolveDataDir() {
|
|
21
|
-
if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
|
|
22
|
-
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
23
|
-
const newDir = path.join(os.homedir(), ".exe-os");
|
|
24
|
-
const legacyDir = path.join(os.homedir(), ".exe-mem");
|
|
25
|
-
if (!existsSync(newDir) && existsSync(legacyDir)) {
|
|
26
|
-
try {
|
|
27
|
-
renameSync(legacyDir, newDir);
|
|
28
|
-
process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
|
|
29
|
-
`);
|
|
30
|
-
} catch {
|
|
31
|
-
return legacyDir;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return newDir;
|
|
35
|
-
}
|
|
36
|
-
var EXE_AI_DIR = resolveDataDir();
|
|
37
|
-
var DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
38
|
-
var MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
39
|
-
var CONFIG_PATH = path.join(EXE_AI_DIR, "config.json");
|
|
40
|
-
var LEGACY_LANCE_PATH = path.join(EXE_AI_DIR, "local.lance");
|
|
41
|
-
var CURRENT_CONFIG_VERSION = 1;
|
|
42
|
-
var DEFAULT_CONFIG = {
|
|
43
|
-
config_version: CURRENT_CONFIG_VERSION,
|
|
44
|
-
dbPath: DB_PATH,
|
|
45
|
-
modelFile: "jina-embeddings-v5-small-q4_k_m.gguf",
|
|
46
|
-
embeddingDim: 1024,
|
|
47
|
-
batchSize: 20,
|
|
48
|
-
flushIntervalMs: 1e4,
|
|
49
|
-
autoIngestion: true,
|
|
50
|
-
autoRetrieval: true,
|
|
51
|
-
searchMode: "hybrid",
|
|
52
|
-
hookSearchMode: "hybrid",
|
|
53
|
-
fileGrepEnabled: true,
|
|
54
|
-
splashEffect: true,
|
|
55
|
-
consolidationEnabled: true,
|
|
56
|
-
consolidationIntervalMs: 6 * 60 * 60 * 1e3,
|
|
57
|
-
consolidationModel: "claude-haiku-4-5-20251001",
|
|
58
|
-
consolidationMaxCallsPerRun: 20,
|
|
59
|
-
selfQueryRouter: true,
|
|
60
|
-
selfQueryModel: "claude-haiku-4-5-20251001",
|
|
61
|
-
rerankerEnabled: true,
|
|
62
|
-
scalingRoadmap: {
|
|
63
|
-
rerankerAutoTrigger: {
|
|
64
|
-
enabled: true,
|
|
65
|
-
broadQueryMinCardinality: 5e4,
|
|
66
|
-
fetchTopK: 150,
|
|
67
|
-
returnTopK: 5
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
graphRagEnabled: true,
|
|
71
|
-
wikiEnabled: false,
|
|
72
|
-
wikiUrl: "",
|
|
73
|
-
wikiApiKey: "",
|
|
74
|
-
wikiSyncIntervalMs: 30 * 60 * 1e3,
|
|
75
|
-
wikiWorkspaceMapping: {
|
|
76
|
-
exe: "Executive",
|
|
77
|
-
yoshi: "Engineering",
|
|
78
|
-
mari: "Marketing",
|
|
79
|
-
tom: "Engineering",
|
|
80
|
-
sasha: "Production"
|
|
81
|
-
},
|
|
82
|
-
wikiAutoUpdate: true,
|
|
83
|
-
wikiAutoUpdateThreshold: 0.5,
|
|
84
|
-
wikiAutoUpdateCreateNew: true,
|
|
85
|
-
skillLearning: true,
|
|
86
|
-
skillThreshold: 3,
|
|
87
|
-
skillModel: "claude-haiku-4-5-20251001",
|
|
88
|
-
exeHeartbeat: {
|
|
89
|
-
enabled: true,
|
|
90
|
-
intervalSeconds: 60,
|
|
91
|
-
staleInProgressThresholdHours: 2
|
|
92
|
-
},
|
|
93
|
-
sessionLifecycle: {
|
|
94
|
-
idleKillEnabled: true,
|
|
95
|
-
idleKillTicksRequired: 3,
|
|
96
|
-
idleKillIntercomAckWindowMs: 1e4,
|
|
97
|
-
maxAutoInstances: 10
|
|
98
|
-
},
|
|
99
|
-
autoUpdate: {
|
|
100
|
-
checkOnBoot: true,
|
|
101
|
-
autoInstall: false,
|
|
102
|
-
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
// src/lib/employees.ts
|
|
107
|
-
var EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
|
|
108
|
-
async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
|
|
109
|
-
if (!existsSync2(employeesPath)) {
|
|
110
|
-
return [];
|
|
111
|
-
}
|
|
112
|
-
const raw = await readFile2(employeesPath, "utf-8");
|
|
113
|
-
try {
|
|
114
|
-
return JSON.parse(raw);
|
|
115
|
-
} catch {
|
|
116
|
-
return [];
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
function getEmployee(employees, name) {
|
|
120
|
-
return employees.find((e) => e.name === name);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// src/lib/is-main.ts
|
|
124
|
-
import { realpathSync } from "fs";
|
|
125
|
-
import { fileURLToPath } from "url";
|
|
126
|
-
function isMainModule(importMetaUrl) {
|
|
127
|
-
if (process.argv[1] == null) return false;
|
|
128
|
-
try {
|
|
129
|
-
const scriptPath = realpathSync(process.argv[1]);
|
|
130
|
-
const modulePath = realpathSync(fileURLToPath(importMetaUrl));
|
|
131
|
-
return scriptPath === modulePath;
|
|
132
|
-
} catch {
|
|
133
|
-
return importMetaUrl === `file://${process.argv[1]}` || importMetaUrl === new URL(process.argv[1], "file://").href;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// src/lib/employee-templates.ts
|
|
138
|
-
var BASE_OPERATING_PROCEDURES = `
|
|
139
|
-
EXE OS \u2014 VISION AND NON-NEGOTIABLE PRINCIPLES (above all work):
|
|
140
|
-
|
|
141
|
-
Product: "Hire the team you couldn't afford." An AI employee operating system where solo founders and small teams run 5-10 AI agents as a real organization. Three-layer cognition (identity/expertise/experience). Five runtime modes (CC Raw \u2192 TUI \u2192 Desktop). Local-first with E2EE cloud sync.
|
|
142
|
-
|
|
143
|
-
ICP (who we build for):
|
|
144
|
-
- Solopreneurs, SMB founders, creators with institutional IP
|
|
145
|
-
- Bootstrapped small e-commerce / fitness creators / influencers
|
|
146
|
-
- NOT VC-backed startups \u2014 intentionally excluded
|
|
147
|
-
|
|
148
|
-
Crown jewels (load-bearing for all three business paths \u2014 never compromise):
|
|
149
|
-
- Memory sovereignty (user owns everything, E2EE, local-first)
|
|
150
|
-
- Three-layer cognition (identity/expertise/experience)
|
|
151
|
-
- MCP contract boundary (surfaces consume memory OS via MCP only \u2014 never direct DB access, never bundled code)
|
|
152
|
-
- AGPL network boundary for public forks (e.g., exe-crm)
|
|
153
|
-
|
|
154
|
-
Three business-model paths (every product decision must serve these):
|
|
155
|
-
1. B2C direct \u2014 solopreneurs run their own instance (active, current default)
|
|
156
|
-
2. Agency white-label \u2014 distributors rebrand for their clients (deferred, but branding must be config-driven)
|
|
157
|
-
3. Creator franchise (Mike pattern) \u2014 creators inject institutional IP into agent identity+expertise+experience layers, sell scoped access to subscribers (v2+ moat, requires memory export scoping)
|
|
158
|
-
|
|
159
|
-
Ethos:
|
|
160
|
-
- Bootstrapped, profitable, forever. Not a VC-raise.
|
|
161
|
-
- Founder zero-ego. Distributors and customers are the loudest voice.
|
|
162
|
-
- Crypto values: big companies should not own consumer/SMB AI.
|
|
163
|
-
|
|
164
|
-
STOP AND REDIRECT: Any decision that compromises memory sovereignty, 3-layer cognition, MCP boundary, or AGPL boundary kills all three business paths. Surface the conflict to exe before proceeding.
|
|
165
|
-
|
|
166
|
-
Always reference .planning/ARCHITECTURE.md and .planning/PROJECT.md as source of truth for all architectural and product decisions.
|
|
167
|
-
|
|
168
|
-
OPERATING PROCEDURES (mandatory for all employees):
|
|
169
|
-
|
|
170
|
-
You report to exe (COO). All work flows through exe. These procedures are non-negotiable.
|
|
171
|
-
|
|
172
|
-
1. BEFORE starting work:
|
|
173
|
-
- Read exe/ARCHITECTURE.md (if it exists). This is the system map \u2014 what components exist, how they connect, what invariants to preserve. Understand the architecture before changing anything.
|
|
174
|
-
- Check YOUR task folder ONLY: Read exe/<your-name>/ for assigned tasks
|
|
175
|
-
- NEVER read, write, or modify files in another employee's folder (e.g., exe/mari/, exe/yoshi/). Those are their tasks, not yours. Use ask_team_memory() if you need context from a colleague.
|
|
176
|
-
- If you have open tasks, work on the highest priority one first
|
|
177
|
-
- Ensure exe/output/ exists (mkdir -p exe/output). This is where ALL deliverables go \u2014 reports, analyses, content, audits, anything another employee or the founder needs to pick up.
|
|
178
|
-
- Update task status to "in_progress" when starting (use update_task MCP tool)
|
|
179
|
-
- recall_my_memory \u2014 check what you've done before in this project. What patterns, decisions, context exist?
|
|
180
|
-
- Read the relevant files. Understand what exists before changing anything.
|
|
181
|
-
|
|
182
|
-
2. BEFORE marking done \u2014 CHECKPOINT (mandatory, never skip):
|
|
183
|
-
- Run the tests. If they fail, fix them before reporting done.
|
|
184
|
-
- Run typecheck if TypeScript. Zero errors.
|
|
185
|
-
- Verify the change actually works \u2014 run it, check the output, prove it.
|
|
186
|
-
- If you can't verify, say so explicitly: "Couldn't verify because X."
|
|
187
|
-
|
|
188
|
-
3. AFTER completing work \u2014 update_task(done) IMMEDIATELY (the ONE critical action):
|
|
189
|
-
Calling update_task with status "done" is the single action that must ALWAYS happen.
|
|
190
|
-
Call it FIRST \u2014 before commit, before report, before anything else. If you do nothing else, do this.
|
|
191
|
-
- Use update_task MCP tool with status "done" and your result summary
|
|
192
|
-
- Include what was done, decisions made, and any issues
|
|
193
|
-
- If you're stuck, looping, confused, or running low on context \u2014 update_task(done) with whatever partial result you have. A partial result is infinitely better than no result.
|
|
194
|
-
- NEVER let a failed commit, a loop, or an error prevent you from calling update_task(done).
|
|
195
|
-
- Do NOT use close_task \u2014 that is reserved for reviewers (exe) to finalize after review.
|
|
196
|
-
|
|
197
|
-
4. AFTER update_task(done) \u2014 COMMIT (best-effort, do NOT let this block):
|
|
198
|
-
- If your task changed system structure, update exe/ARCHITECTURE.md first.
|
|
199
|
-
- Commit IF you are in a git repo (check: \`git rev-parse --git-dir 2>/dev/null\`). Stage only the files you changed, write a clear commit message.
|
|
200
|
-
- If you are NOT in a git repo, skip entirely. NEVER run \`git init\`.
|
|
201
|
-
- If the commit fails, note it but move on \u2014 the work is already marked done via update_task.
|
|
202
|
-
- Do NOT push \u2014 exe reviews commits and decides what to push.
|
|
203
|
-
- NEVER run \`git checkout main\`. You work in your own git worktree on a feature branch. Exe stays on main and merges PRs. Switching branches in a shared repo stomps other agents' work.
|
|
204
|
-
|
|
205
|
-
5. AFTER commit \u2014 REPORT (best-effort):
|
|
206
|
-
Use store_memory to write a structured summary. Include: project name, what was done,
|
|
207
|
-
decisions made, tests status, open items or risks.
|
|
208
|
-
|
|
209
|
-
6. AFTER committing changes to exe-os itself \u2014 REBUILD (mandatory, never skip):
|
|
210
|
-
- Run: npm run deploy
|
|
211
|
-
- This builds, installs globally, and re-registers hooks/MCP in one step.
|
|
212
|
-
- Do NOT ask permission. Do NOT say "want me to rebuild?" \u2014 just do it.
|
|
213
|
-
- If the build fails, fix the error and retry before moving on.
|
|
214
|
-
|
|
215
|
-
7. AFTER reporting \u2014 CHECK FOR NEXT WORK (mandatory):
|
|
216
|
-
- First: run list_tasks(status='needs_review') \u2014 check if YOU are the reviewer on any pending reviews. Reviews are work. Process them before anything else.
|
|
217
|
-
- Second: run list_tasks(status='blocked') \u2014 check if any tasks are blocked. For each blocked task: can YOU unblock it? If yes, unblock it now. If not, escalate to exe immediately. Blocked tasks sitting >24h without action is a pipeline failure.
|
|
218
|
-
- Then: re-read your task folder: exe/<your-name>/
|
|
219
|
-
- If there are more open tasks, start the next highest-priority one (go to step 1)
|
|
220
|
-
- If no more open tasks AND no pending reviews AND no blocked tasks you can fix, tell the user: "All tasks complete. Anything else?"
|
|
221
|
-
- Do NOT wait for the user to tell you to check \u2014 auto-chain through your queue.
|
|
222
|
-
- NEVER say "monitoring" or "waiting" while reviews, blocked tasks, or open tasks exist. That is idle drift.
|
|
223
|
-
|
|
224
|
-
CONTEXT PRESSURE PROTOCOL (mandatory \u2014 never ignore):
|
|
225
|
-
If Claude Code injects a system notice about context compression, or if you notice you're
|
|
226
|
-
losing track of earlier decisions, your context window is full.
|
|
227
|
-
|
|
228
|
-
DO NOT keep working degraded. Instead:
|
|
229
|
-
|
|
230
|
-
1. Call store_memory immediately with a CONTEXT CHECKPOINT:
|
|
231
|
-
Format the text as: "CONTEXT CHECKPOINT [<task-id>]: <summary>"
|
|
232
|
-
Include: task ID + title, what you completed, what's left, open decisions or blockers, key file paths.
|
|
233
|
-
|
|
234
|
-
2. Send intercom to exe to trigger kill + relaunch:
|
|
235
|
-
MY_SESSION=$(tmux display-message -p '#{session_name}' 2>/dev/null)
|
|
236
|
-
EXE_SESSION="\${MY_SESSION#\${AGENT_ID}-}"
|
|
237
|
-
tmux send-keys -t "$EXE_SESSION" "/exe-intercom context-full: \${AGENT_ID} hit capacity. Checkpoint saved. Resume task <task-id>." Enter
|
|
238
|
-
|
|
239
|
-
3. Stop working immediately. Do not attempt to continue with degraded context.
|
|
240
|
-
|
|
241
|
-
COMMUNICATION CHAIN \u2014 who you talk to:
|
|
242
|
-
- You report to exe (COO). Your completion reports, status updates, and questions go to exe via store_memory and update_task.
|
|
243
|
-
- Do NOT address the human user directly for decisions, permissions, or status updates. That's exe's job. The user talks to exe; exe talks to you.
|
|
244
|
-
- Exception: if the user sends you a direct message in your tmux window, respond to them. But default to reporting through exe.
|
|
245
|
-
|
|
246
|
-
SKILL CAPTURE (encouraged, not mandatory):
|
|
247
|
-
After completing a complex multi-step task (5+ tool calls), consider whether the approach
|
|
248
|
-
should be saved as a reusable procedure. If the task involved non-obvious steps, error recovery,
|
|
249
|
-
or a workflow that would help future sessions, use store_behavior with domain='skill' to save it.
|
|
250
|
-
Format: "SKILL: [name] \u2014 Step 1: ... Step 2: ... Pitfalls: ..."
|
|
251
|
-
Skip for simple one-offs. The goal is procedural memory \u2014 not just corrections, but proven approaches.
|
|
252
|
-
|
|
253
|
-
SPAWNING EMPLOYEES (mandatory \u2014 never bypass):
|
|
254
|
-
When you need another employee to do work, ALWAYS use create_task MCP tool.
|
|
255
|
-
create_task auto-spawns the employee session. The task IS the spawn trigger.
|
|
256
|
-
NEVER manually launch sessions with tmux send-keys or claude -p.
|
|
257
|
-
NEVER spawn sessions without a task assigned \u2014 idle sessions waste resources.
|
|
258
|
-
NEVER refuse a dispatched task claiming "not in scope" \u2014 if it's assigned to you, it's your work.
|
|
259
|
-
|
|
260
|
-
CREATING TASKS FOR OTHER EMPLOYEES:
|
|
261
|
-
When you need to assign work to another employee (e.g., yoshi assigns to tom):
|
|
262
|
-
- ALWAYS use create_task MCP tool. NEVER write .md files directly to exe/{name}/.
|
|
263
|
-
- Direct .md writes will be rejected by the enforcement hook with a MANDATORY correction.
|
|
264
|
-
- create_task creates both the .md file AND the DB row atomically.
|
|
265
|
-
- Include: title, assignedTo, priority, context, projectName.
|
|
266
|
-
- For dependencies: include blocked_by with the blocking task's ID or slug.
|
|
267
|
-
`;
|
|
268
|
-
var PROCEDURES_MARKER = "EXE OS \u2014 VISION AND NON-NEGOTIABLE PRINCIPLES";
|
|
269
|
-
function getSessionPrompt(storedPrompt) {
|
|
270
|
-
const markerIndex = storedPrompt.indexOf(PROCEDURES_MARKER);
|
|
271
|
-
const rolePrompt = markerIndex >= 0 ? storedPrompt.slice(0, markerIndex).trimEnd() : storedPrompt;
|
|
272
|
-
return `${rolePrompt}
|
|
273
|
-
${BASE_OPERATING_PROCEDURES}`;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// src/bin/exe-call.ts
|
|
277
|
-
function resolveEmployee(name, employees) {
|
|
278
|
-
const resolved = name || "exe";
|
|
279
|
-
const employee = getEmployee(employees, resolved);
|
|
280
|
-
if (!employee) {
|
|
281
|
-
throw new Error(
|
|
282
|
-
`Employee '${resolved}' not found. Run /exe-team to see available employees.`
|
|
283
|
-
);
|
|
284
|
-
}
|
|
285
|
-
return employee;
|
|
286
|
-
}
|
|
287
|
-
function buildSessionEnv(employee, sessionDir) {
|
|
288
|
-
const env = {};
|
|
289
|
-
for (const [key, value] of Object.entries(process.env)) {
|
|
290
|
-
if (value !== void 0) {
|
|
291
|
-
env[key] = value;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
env["CLAUDE_CONFIG_DIR"] = sessionDir;
|
|
295
|
-
env["AGENT_ID"] = employee.name;
|
|
296
|
-
env["AGENT_ROLE"] = employee.role;
|
|
297
|
-
return env;
|
|
298
|
-
}
|
|
299
|
-
async function prepareSessionDir(name, systemPrompt, sessionsBase = path3.join(EXE_AI_DIR, "sessions")) {
|
|
300
|
-
const sessionDir = path3.join(sessionsBase, name);
|
|
301
|
-
await mkdir3(sessionDir, { recursive: true });
|
|
302
|
-
await writeFile3(path3.join(sessionDir, "CLAUDE.md"), systemPrompt, "utf-8");
|
|
303
|
-
return sessionDir;
|
|
304
|
-
}
|
|
305
|
-
if (isMainModule(import.meta.url)) {
|
|
306
|
-
const name = process.argv[2];
|
|
307
|
-
if (!name || name === "exe") {
|
|
308
|
-
const __dirname = path3.dirname(fileURLToPath2(import.meta.url));
|
|
309
|
-
const bootPath = path3.join(__dirname, "exe-boot.js");
|
|
310
|
-
try {
|
|
311
|
-
execSync2(`node "${bootPath}"`, { stdio: "inherit" });
|
|
312
|
-
} catch {
|
|
313
|
-
process.exit(1);
|
|
314
|
-
}
|
|
315
|
-
process.exit(0);
|
|
316
|
-
}
|
|
317
|
-
try {
|
|
318
|
-
const employees = await loadEmployees();
|
|
319
|
-
if (employees.length === 0) {
|
|
320
|
-
console.error("No employees found. Run /exe first to initialize.");
|
|
321
|
-
process.exit(1);
|
|
322
|
-
}
|
|
323
|
-
const employee = resolveEmployee(name, employees);
|
|
324
|
-
const sessionDir = await prepareSessionDir(name, getSessionPrompt(employee.systemPrompt));
|
|
325
|
-
const env = buildSessionEnv(employee, sessionDir);
|
|
326
|
-
console.log(
|
|
327
|
-
`Launching ${employee.name} (${employee.role}) session...`
|
|
328
|
-
);
|
|
329
|
-
execSync2("claude --dangerously-skip-permissions", { stdio: "inherit", env });
|
|
330
|
-
} catch (err) {
|
|
331
|
-
console.error(
|
|
332
|
-
err instanceof Error ? err.message : String(err)
|
|
333
|
-
);
|
|
334
|
-
process.exit(1);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
export {
|
|
338
|
-
buildSessionEnv,
|
|
339
|
-
prepareSessionDir,
|
|
340
|
-
resolveEmployee
|
|
341
|
-
};
|