@askexenow/exe-os 0.8.0 → 0.8.1
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/README.md +178 -79
- package/dist/bin/backfill-responses.js +160 -8
- package/dist/bin/backfill-vectors.js +130 -1
- package/dist/bin/cleanup-stale-review-tasks.js +130 -1
- package/dist/bin/cli.js +10111 -7540
- package/dist/bin/exe-agent.js +159 -1
- package/dist/bin/exe-assign.js +235 -16
- package/dist/bin/exe-boot.js +344 -472
- package/dist/bin/exe-call.js +145 -1
- package/dist/bin/exe-cloud.js +11 -0
- package/dist/bin/exe-dispatch.js +37 -24
- package/dist/bin/exe-doctor.js +130 -1
- package/dist/bin/exe-export-behaviors.js +150 -7
- package/dist/bin/exe-forget.js +822 -665
- package/dist/bin/exe-gateway.js +470 -62
- package/dist/bin/exe-heartbeat.js +133 -2
- package/dist/bin/exe-kill.js +150 -7
- package/dist/bin/exe-launch-agent.js +150 -7
- package/dist/bin/exe-new-employee.js +756 -224
- package/dist/bin/exe-pending-messages.js +132 -2
- package/dist/bin/exe-pending-notifications.js +130 -1
- package/dist/bin/exe-pending-reviews.js +132 -2
- package/dist/bin/exe-review.js +160 -8
- package/dist/bin/exe-search.js +2473 -2008
- package/dist/bin/exe-session-cleanup.js +238 -51
- package/dist/bin/exe-settings.js +11 -0
- package/dist/bin/exe-status.js +130 -1
- package/dist/bin/exe-team.js +130 -1
- package/dist/bin/git-sweep.js +272 -16
- package/dist/bin/graph-backfill.js +150 -7
- package/dist/bin/graph-export.js +150 -7
- package/dist/bin/install.js +5 -0
- package/dist/bin/scan-tasks.js +238 -19
- package/dist/bin/setup.js +1776 -10
- package/dist/bin/shard-migrate.js +150 -7
- package/dist/bin/update.js +9 -6
- package/dist/bin/wiki-sync.js +150 -7
- package/dist/gateway/index.js +470 -62
- package/dist/hooks/bug-report-worker.js +195 -35
- package/dist/hooks/commit-complete.js +272 -16
- package/dist/hooks/error-recall.js +2313 -1847
- package/dist/hooks/exe-heartbeat-hook.js +5 -0
- package/dist/hooks/ingest-worker.js +330 -58
- package/dist/hooks/ingest.js +11 -0
- package/dist/hooks/instructions-loaded.js +199 -10
- package/dist/hooks/notification.js +199 -10
- package/dist/hooks/post-compact.js +199 -10
- package/dist/hooks/pre-compact.js +199 -10
- package/dist/hooks/pre-tool-use.js +199 -10
- package/dist/hooks/prompt-ingest-worker.js +179 -14
- package/dist/hooks/prompt-submit.js +781 -285
- package/dist/hooks/response-ingest-worker.js +1900 -1405
- package/dist/hooks/session-end.js +456 -12
- package/dist/hooks/session-start.js +2188 -1724
- package/dist/hooks/stop.js +200 -10
- package/dist/hooks/subagent-stop.js +199 -10
- package/dist/hooks/summary-worker.js +604 -334
- package/dist/index.js +554 -61
- package/dist/lib/cloud-sync.js +5 -0
- package/dist/lib/config.js +13 -0
- package/dist/lib/consolidation.js +5 -0
- package/dist/lib/database.js +104 -0
- package/dist/lib/device-registry.js +109 -0
- package/dist/lib/embedder.js +13 -0
- package/dist/lib/employee-templates.js +53 -26
- package/dist/lib/employees.js +5 -0
- package/dist/lib/exe-daemon-client.js +5 -0
- package/dist/lib/exe-daemon.js +493 -79
- package/dist/lib/file-grep.js +20 -4
- package/dist/lib/hybrid-search.js +1435 -190
- package/dist/lib/identity-templates.js +126 -5
- package/dist/lib/identity.js +5 -0
- package/dist/lib/license.js +5 -0
- package/dist/lib/messaging.js +37 -24
- package/dist/lib/schedules.js +130 -1
- package/dist/lib/skill-learning.js +11 -0
- package/dist/lib/status-brief.js +5 -0
- package/dist/lib/store.js +199 -10
- package/dist/lib/task-router.js +72 -6
- package/dist/lib/tasks.js +179 -50
- package/dist/lib/tmux-routing.js +179 -46
- package/dist/mcp/server.js +2129 -1855
- package/dist/mcp/tools/create-task.js +86 -36
- package/dist/mcp/tools/deactivate-behavior.js +5 -0
- package/dist/mcp/tools/list-tasks.js +39 -11
- package/dist/mcp/tools/send-message.js +37 -24
- package/dist/mcp/tools/update-task.js +153 -38
- package/dist/runtime/index.js +451 -59
- package/dist/tui/App.js +454 -59
- package/package.json +1 -1
package/dist/lib/cloud-sync.js
CHANGED
package/dist/lib/config.js
CHANGED
|
@@ -81,6 +81,11 @@ var DEFAULT_CONFIG = {
|
|
|
81
81
|
idleKillTicksRequired: 3,
|
|
82
82
|
idleKillIntercomAckWindowMs: 1e4,
|
|
83
83
|
maxAutoInstances: 10
|
|
84
|
+
},
|
|
85
|
+
autoUpdate: {
|
|
86
|
+
checkOnBoot: true,
|
|
87
|
+
autoInstall: false,
|
|
88
|
+
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
84
89
|
}
|
|
85
90
|
};
|
|
86
91
|
function migrateLegacyConfig(raw) {
|
|
@@ -138,6 +143,11 @@ function normalizeSessionLifecycle(raw) {
|
|
|
138
143
|
const userSL = raw.sessionLifecycle ?? {};
|
|
139
144
|
raw.sessionLifecycle = { ...defaultSL, ...userSL };
|
|
140
145
|
}
|
|
146
|
+
function normalizeAutoUpdate(raw) {
|
|
147
|
+
const defaultAU = DEFAULT_CONFIG.autoUpdate;
|
|
148
|
+
const userAU = raw.autoUpdate ?? {};
|
|
149
|
+
raw.autoUpdate = { ...defaultAU, ...userAU };
|
|
150
|
+
}
|
|
141
151
|
async function loadConfig() {
|
|
142
152
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
143
153
|
await mkdir(dir, { recursive: true });
|
|
@@ -160,6 +170,7 @@ async function loadConfig() {
|
|
|
160
170
|
}
|
|
161
171
|
normalizeScalingRoadmap(migratedCfg);
|
|
162
172
|
normalizeSessionLifecycle(migratedCfg);
|
|
173
|
+
normalizeAutoUpdate(migratedCfg);
|
|
163
174
|
const config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
|
|
164
175
|
if (config.dbPath.startsWith("~")) {
|
|
165
176
|
config.dbPath = config.dbPath.replace(/^~/, os.homedir());
|
|
@@ -182,6 +193,7 @@ function loadConfigSync() {
|
|
|
182
193
|
const { config: migratedCfg } = migrateConfig(parsed);
|
|
183
194
|
normalizeScalingRoadmap(migratedCfg);
|
|
184
195
|
normalizeSessionLifecycle(migratedCfg);
|
|
196
|
+
normalizeAutoUpdate(migratedCfg);
|
|
185
197
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
|
|
186
198
|
} catch {
|
|
187
199
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
|
|
@@ -201,6 +213,7 @@ async function loadConfigFrom(configPath) {
|
|
|
201
213
|
const { config: migratedCfg } = migrateConfig(parsed);
|
|
202
214
|
normalizeScalingRoadmap(migratedCfg);
|
|
203
215
|
normalizeSessionLifecycle(migratedCfg);
|
|
216
|
+
normalizeAutoUpdate(migratedCfg);
|
|
204
217
|
return { ...DEFAULT_CONFIG, ...migratedCfg };
|
|
205
218
|
} catch {
|
|
206
219
|
return { ...DEFAULT_CONFIG };
|
package/dist/lib/database.js
CHANGED
|
@@ -211,6 +211,27 @@ async function ensureSchema() {
|
|
|
211
211
|
});
|
|
212
212
|
} catch {
|
|
213
213
|
}
|
|
214
|
+
try {
|
|
215
|
+
await client.execute({
|
|
216
|
+
sql: `ALTER TABLE tasks ADD COLUMN checkpoint TEXT`,
|
|
217
|
+
args: []
|
|
218
|
+
});
|
|
219
|
+
} catch {
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
await client.execute({
|
|
223
|
+
sql: `ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER NOT NULL DEFAULT 0`,
|
|
224
|
+
args: []
|
|
225
|
+
});
|
|
226
|
+
} catch {
|
|
227
|
+
}
|
|
228
|
+
try {
|
|
229
|
+
await client.execute({
|
|
230
|
+
sql: `ALTER TABLE tasks ADD COLUMN complexity TEXT NOT NULL DEFAULT 'standard'`,
|
|
231
|
+
args: []
|
|
232
|
+
});
|
|
233
|
+
} catch {
|
|
234
|
+
}
|
|
214
235
|
try {
|
|
215
236
|
await client.execute({
|
|
216
237
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
@@ -621,6 +642,15 @@ async function ensureSchema() {
|
|
|
621
642
|
} catch {
|
|
622
643
|
}
|
|
623
644
|
}
|
|
645
|
+
for (const col of [
|
|
646
|
+
"ALTER TABLE memories ADD COLUMN source_path TEXT",
|
|
647
|
+
"ALTER TABLE memories ADD COLUMN source_type TEXT DEFAULT 'text'"
|
|
648
|
+
]) {
|
|
649
|
+
try {
|
|
650
|
+
await client.execute(col);
|
|
651
|
+
} catch {
|
|
652
|
+
}
|
|
653
|
+
}
|
|
624
654
|
await client.executeMultiple(`
|
|
625
655
|
CREATE INDEX IF NOT EXISTS idx_memories_workspace
|
|
626
656
|
ON memories(workspace_id);
|
|
@@ -685,6 +715,34 @@ async function ensureSchema() {
|
|
|
685
715
|
CREATE INDEX IF NOT EXISTS idx_conversations_channel
|
|
686
716
|
ON conversations(channel_id);
|
|
687
717
|
`);
|
|
718
|
+
try {
|
|
719
|
+
await client.execute({
|
|
720
|
+
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
721
|
+
args: []
|
|
722
|
+
});
|
|
723
|
+
} catch {
|
|
724
|
+
}
|
|
725
|
+
try {
|
|
726
|
+
await client.execute({
|
|
727
|
+
sql: `ALTER TABLE tasks ADD COLUMN budget_fallback_model TEXT`,
|
|
728
|
+
args: []
|
|
729
|
+
});
|
|
730
|
+
} catch {
|
|
731
|
+
}
|
|
732
|
+
try {
|
|
733
|
+
await client.execute({
|
|
734
|
+
sql: `ALTER TABLE tasks ADD COLUMN tokens_used INTEGER DEFAULT 0`,
|
|
735
|
+
args: []
|
|
736
|
+
});
|
|
737
|
+
} catch {
|
|
738
|
+
}
|
|
739
|
+
try {
|
|
740
|
+
await client.execute({
|
|
741
|
+
sql: `ALTER TABLE tasks ADD COLUMN tokens_warned_at INTEGER`,
|
|
742
|
+
args: []
|
|
743
|
+
});
|
|
744
|
+
} catch {
|
|
745
|
+
}
|
|
688
746
|
await client.executeMultiple(`
|
|
689
747
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
690
748
|
content_text,
|
|
@@ -711,6 +769,52 @@ async function ensureSchema() {
|
|
|
711
769
|
VALUES (new.rowid, new.content_text, new.sender_name, new.agent_response);
|
|
712
770
|
END;
|
|
713
771
|
`);
|
|
772
|
+
try {
|
|
773
|
+
await client.execute({
|
|
774
|
+
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
775
|
+
args: []
|
|
776
|
+
});
|
|
777
|
+
} catch {
|
|
778
|
+
}
|
|
779
|
+
try {
|
|
780
|
+
await client.execute(
|
|
781
|
+
`CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`
|
|
782
|
+
);
|
|
783
|
+
} catch {
|
|
784
|
+
}
|
|
785
|
+
try {
|
|
786
|
+
await client.execute({
|
|
787
|
+
sql: `UPDATE memories SET tier = 1 WHERE tool_name = 'commit_to_long_term_memory' AND importance >= 8 AND tier = 3`,
|
|
788
|
+
args: []
|
|
789
|
+
});
|
|
790
|
+
await client.execute({
|
|
791
|
+
sql: `UPDATE memories SET tier = 2 WHERE tool_name IN ('store_memory', 'manual') AND importance >= 5 AND tier = 3`,
|
|
792
|
+
args: []
|
|
793
|
+
});
|
|
794
|
+
} catch {
|
|
795
|
+
}
|
|
796
|
+
try {
|
|
797
|
+
await client.execute({
|
|
798
|
+
sql: `ALTER TABLE memories ADD COLUMN supersedes_id TEXT`,
|
|
799
|
+
args: []
|
|
800
|
+
});
|
|
801
|
+
} catch {
|
|
802
|
+
}
|
|
803
|
+
try {
|
|
804
|
+
await client.execute(
|
|
805
|
+
`CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL`
|
|
806
|
+
);
|
|
807
|
+
} catch {
|
|
808
|
+
}
|
|
809
|
+
for (const col of [
|
|
810
|
+
"ALTER TABLE tasks ADD COLUMN checkpoint TEXT",
|
|
811
|
+
"ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER DEFAULT 0"
|
|
812
|
+
]) {
|
|
813
|
+
try {
|
|
814
|
+
await client.execute(col);
|
|
815
|
+
} catch {
|
|
816
|
+
}
|
|
817
|
+
}
|
|
714
818
|
}
|
|
715
819
|
var disposeTurso = disposeDatabase;
|
|
716
820
|
async function disposeDatabase() {
|
|
@@ -229,6 +229,27 @@ async function ensureSchema() {
|
|
|
229
229
|
});
|
|
230
230
|
} catch {
|
|
231
231
|
}
|
|
232
|
+
try {
|
|
233
|
+
await client.execute({
|
|
234
|
+
sql: `ALTER TABLE tasks ADD COLUMN checkpoint TEXT`,
|
|
235
|
+
args: []
|
|
236
|
+
});
|
|
237
|
+
} catch {
|
|
238
|
+
}
|
|
239
|
+
try {
|
|
240
|
+
await client.execute({
|
|
241
|
+
sql: `ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER NOT NULL DEFAULT 0`,
|
|
242
|
+
args: []
|
|
243
|
+
});
|
|
244
|
+
} catch {
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
await client.execute({
|
|
248
|
+
sql: `ALTER TABLE tasks ADD COLUMN complexity TEXT NOT NULL DEFAULT 'standard'`,
|
|
249
|
+
args: []
|
|
250
|
+
});
|
|
251
|
+
} catch {
|
|
252
|
+
}
|
|
232
253
|
try {
|
|
233
254
|
await client.execute({
|
|
234
255
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
@@ -639,6 +660,15 @@ async function ensureSchema() {
|
|
|
639
660
|
} catch {
|
|
640
661
|
}
|
|
641
662
|
}
|
|
663
|
+
for (const col of [
|
|
664
|
+
"ALTER TABLE memories ADD COLUMN source_path TEXT",
|
|
665
|
+
"ALTER TABLE memories ADD COLUMN source_type TEXT DEFAULT 'text'"
|
|
666
|
+
]) {
|
|
667
|
+
try {
|
|
668
|
+
await client.execute(col);
|
|
669
|
+
} catch {
|
|
670
|
+
}
|
|
671
|
+
}
|
|
642
672
|
await client.executeMultiple(`
|
|
643
673
|
CREATE INDEX IF NOT EXISTS idx_memories_workspace
|
|
644
674
|
ON memories(workspace_id);
|
|
@@ -703,6 +733,34 @@ async function ensureSchema() {
|
|
|
703
733
|
CREATE INDEX IF NOT EXISTS idx_conversations_channel
|
|
704
734
|
ON conversations(channel_id);
|
|
705
735
|
`);
|
|
736
|
+
try {
|
|
737
|
+
await client.execute({
|
|
738
|
+
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
739
|
+
args: []
|
|
740
|
+
});
|
|
741
|
+
} catch {
|
|
742
|
+
}
|
|
743
|
+
try {
|
|
744
|
+
await client.execute({
|
|
745
|
+
sql: `ALTER TABLE tasks ADD COLUMN budget_fallback_model TEXT`,
|
|
746
|
+
args: []
|
|
747
|
+
});
|
|
748
|
+
} catch {
|
|
749
|
+
}
|
|
750
|
+
try {
|
|
751
|
+
await client.execute({
|
|
752
|
+
sql: `ALTER TABLE tasks ADD COLUMN tokens_used INTEGER DEFAULT 0`,
|
|
753
|
+
args: []
|
|
754
|
+
});
|
|
755
|
+
} catch {
|
|
756
|
+
}
|
|
757
|
+
try {
|
|
758
|
+
await client.execute({
|
|
759
|
+
sql: `ALTER TABLE tasks ADD COLUMN tokens_warned_at INTEGER`,
|
|
760
|
+
args: []
|
|
761
|
+
});
|
|
762
|
+
} catch {
|
|
763
|
+
}
|
|
706
764
|
await client.executeMultiple(`
|
|
707
765
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
708
766
|
content_text,
|
|
@@ -729,6 +787,52 @@ async function ensureSchema() {
|
|
|
729
787
|
VALUES (new.rowid, new.content_text, new.sender_name, new.agent_response);
|
|
730
788
|
END;
|
|
731
789
|
`);
|
|
790
|
+
try {
|
|
791
|
+
await client.execute({
|
|
792
|
+
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
793
|
+
args: []
|
|
794
|
+
});
|
|
795
|
+
} catch {
|
|
796
|
+
}
|
|
797
|
+
try {
|
|
798
|
+
await client.execute(
|
|
799
|
+
`CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`
|
|
800
|
+
);
|
|
801
|
+
} catch {
|
|
802
|
+
}
|
|
803
|
+
try {
|
|
804
|
+
await client.execute({
|
|
805
|
+
sql: `UPDATE memories SET tier = 1 WHERE tool_name = 'commit_to_long_term_memory' AND importance >= 8 AND tier = 3`,
|
|
806
|
+
args: []
|
|
807
|
+
});
|
|
808
|
+
await client.execute({
|
|
809
|
+
sql: `UPDATE memories SET tier = 2 WHERE tool_name IN ('store_memory', 'manual') AND importance >= 5 AND tier = 3`,
|
|
810
|
+
args: []
|
|
811
|
+
});
|
|
812
|
+
} catch {
|
|
813
|
+
}
|
|
814
|
+
try {
|
|
815
|
+
await client.execute({
|
|
816
|
+
sql: `ALTER TABLE memories ADD COLUMN supersedes_id TEXT`,
|
|
817
|
+
args: []
|
|
818
|
+
});
|
|
819
|
+
} catch {
|
|
820
|
+
}
|
|
821
|
+
try {
|
|
822
|
+
await client.execute(
|
|
823
|
+
`CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL`
|
|
824
|
+
);
|
|
825
|
+
} catch {
|
|
826
|
+
}
|
|
827
|
+
for (const col of [
|
|
828
|
+
"ALTER TABLE tasks ADD COLUMN checkpoint TEXT",
|
|
829
|
+
"ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER DEFAULT 0"
|
|
830
|
+
]) {
|
|
831
|
+
try {
|
|
832
|
+
await client.execute(col);
|
|
833
|
+
} catch {
|
|
834
|
+
}
|
|
835
|
+
}
|
|
732
836
|
}
|
|
733
837
|
async function disposeDatabase() {
|
|
734
838
|
if (_client) {
|
|
@@ -835,6 +939,11 @@ var DEFAULT_CONFIG = {
|
|
|
835
939
|
idleKillTicksRequired: 3,
|
|
836
940
|
idleKillIntercomAckWindowMs: 1e4,
|
|
837
941
|
maxAutoInstances: 10
|
|
942
|
+
},
|
|
943
|
+
autoUpdate: {
|
|
944
|
+
checkOnBoot: true,
|
|
945
|
+
autoInstall: false,
|
|
946
|
+
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
838
947
|
}
|
|
839
948
|
};
|
|
840
949
|
|
package/dist/lib/embedder.js
CHANGED
|
@@ -89,6 +89,11 @@ function normalizeSessionLifecycle(raw) {
|
|
|
89
89
|
const userSL = raw.sessionLifecycle ?? {};
|
|
90
90
|
raw.sessionLifecycle = { ...defaultSL, ...userSL };
|
|
91
91
|
}
|
|
92
|
+
function normalizeAutoUpdate(raw) {
|
|
93
|
+
const defaultAU = DEFAULT_CONFIG.autoUpdate;
|
|
94
|
+
const userAU = raw.autoUpdate ?? {};
|
|
95
|
+
raw.autoUpdate = { ...defaultAU, ...userAU };
|
|
96
|
+
}
|
|
92
97
|
async function loadConfig() {
|
|
93
98
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
94
99
|
await mkdir(dir, { recursive: true });
|
|
@@ -111,6 +116,7 @@ async function loadConfig() {
|
|
|
111
116
|
}
|
|
112
117
|
normalizeScalingRoadmap(migratedCfg);
|
|
113
118
|
normalizeSessionLifecycle(migratedCfg);
|
|
119
|
+
normalizeAutoUpdate(migratedCfg);
|
|
114
120
|
const config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
|
|
115
121
|
if (config.dbPath.startsWith("~")) {
|
|
116
122
|
config.dbPath = config.dbPath.replace(/^~/, os.homedir());
|
|
@@ -133,6 +139,7 @@ function loadConfigSync() {
|
|
|
133
139
|
const { config: migratedCfg } = migrateConfig(parsed);
|
|
134
140
|
normalizeScalingRoadmap(migratedCfg);
|
|
135
141
|
normalizeSessionLifecycle(migratedCfg);
|
|
142
|
+
normalizeAutoUpdate(migratedCfg);
|
|
136
143
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
|
|
137
144
|
} catch {
|
|
138
145
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
|
|
@@ -152,6 +159,7 @@ async function loadConfigFrom(configPath) {
|
|
|
152
159
|
const { config: migratedCfg } = migrateConfig(parsed);
|
|
153
160
|
normalizeScalingRoadmap(migratedCfg);
|
|
154
161
|
normalizeSessionLifecycle(migratedCfg);
|
|
162
|
+
normalizeAutoUpdate(migratedCfg);
|
|
155
163
|
return { ...DEFAULT_CONFIG, ...migratedCfg };
|
|
156
164
|
} catch {
|
|
157
165
|
return { ...DEFAULT_CONFIG };
|
|
@@ -223,6 +231,11 @@ var init_config = __esm({
|
|
|
223
231
|
idleKillTicksRequired: 3,
|
|
224
232
|
idleKillIntercomAckWindowMs: 1e4,
|
|
225
233
|
maxAutoInstances: 10
|
|
234
|
+
},
|
|
235
|
+
autoUpdate: {
|
|
236
|
+
checkOnBoot: true,
|
|
237
|
+
autoInstall: false,
|
|
238
|
+
checkIntervalMs: 24 * 60 * 60 * 1e3
|
|
226
239
|
}
|
|
227
240
|
};
|
|
228
241
|
CONFIG_MIGRATIONS = [
|
|
@@ -76,11 +76,14 @@ You report to exe (COO). All work flows through exe. These procedures are non-ne
|
|
|
76
76
|
- Do NOT ask permission. Do NOT say "want me to rebuild?" \u2014 just do it.
|
|
77
77
|
- If the build fails, fix the error and retry before moving on.
|
|
78
78
|
|
|
79
|
-
7. AFTER reporting \u2014 CHECK FOR NEXT
|
|
80
|
-
-
|
|
79
|
+
7. AFTER reporting \u2014 CHECK FOR NEXT WORK (mandatory):
|
|
80
|
+
- 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.
|
|
81
|
+
- 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.
|
|
82
|
+
- Then: re-read your task folder: exe/<your-name>/
|
|
81
83
|
- If there are more open tasks, start the next highest-priority one (go to step 1)
|
|
82
|
-
- If no more open tasks, tell the user: "All tasks complete. Anything else?"
|
|
84
|
+
- If no more open tasks AND no pending reviews AND no blocked tasks you can fix, tell the user: "All tasks complete. Anything else?"
|
|
83
85
|
- Do NOT wait for the user to tell you to check \u2014 auto-chain through your queue.
|
|
86
|
+
- NEVER say "monitoring" or "waiting" while reviews, blocked tasks, or open tasks exist. That is idle drift.
|
|
84
87
|
|
|
85
88
|
CONTEXT PRESSURE PROTOCOL (mandatory \u2014 never ignore):
|
|
86
89
|
If Claude Code injects a system notice about context compression, or if you notice you're
|
|
@@ -111,6 +114,13 @@ or a workflow that would help future sessions, use store_behavior with domain='s
|
|
|
111
114
|
Format: "SKILL: [name] \u2014 Step 1: ... Step 2: ... Pitfalls: ..."
|
|
112
115
|
Skip for simple one-offs. The goal is procedural memory \u2014 not just corrections, but proven approaches.
|
|
113
116
|
|
|
117
|
+
SPAWNING EMPLOYEES (mandatory \u2014 never bypass):
|
|
118
|
+
When you need another employee to do work, ALWAYS use create_task MCP tool.
|
|
119
|
+
create_task auto-spawns the employee session. The task IS the spawn trigger.
|
|
120
|
+
NEVER manually launch sessions with tmux send-keys or claude -p.
|
|
121
|
+
NEVER spawn sessions without a task assigned \u2014 idle sessions waste resources.
|
|
122
|
+
NEVER refuse a dispatched task claiming "not in scope" \u2014 if it's assigned to you, it's your work.
|
|
123
|
+
|
|
114
124
|
CREATING TASKS FOR OTHER EMPLOYEES:
|
|
115
125
|
When you need to assign work to another employee (e.g., yoshi assigns to tom):
|
|
116
126
|
- ALWAYS use create_task MCP tool. NEVER write .md files directly to exe/{name}/.
|
|
@@ -133,6 +143,14 @@ After every specialist task: verify tests ran, behavior was checked, and a memor
|
|
|
133
143
|
Use recall_my_memory and ask_team_memory constantly. Store your own summaries (decisions, priorities, assignments) after every session.`,
|
|
134
144
|
createdAt: "2026-01-01T00:00:00.000Z"
|
|
135
145
|
};
|
|
146
|
+
var TEMPLATE_VERSION = 1;
|
|
147
|
+
var PROCEDURES_MARKER = "EXE OS \u2014 VISION AND NON-NEGOTIABLE PRINCIPLES";
|
|
148
|
+
function getSessionPrompt(storedPrompt) {
|
|
149
|
+
const markerIndex = storedPrompt.indexOf(PROCEDURES_MARKER);
|
|
150
|
+
const rolePrompt = markerIndex >= 0 ? storedPrompt.slice(0, markerIndex).trimEnd() : storedPrompt;
|
|
151
|
+
return `${rolePrompt}
|
|
152
|
+
${BASE_OPERATING_PROCEDURES}`;
|
|
153
|
+
}
|
|
136
154
|
var TEMPLATES = {
|
|
137
155
|
yoshi: {
|
|
138
156
|
name: "yoshi",
|
|
@@ -202,8 +220,7 @@ ROLE BOUNDARIES \u2014 stay in your lane:
|
|
|
202
220
|
- You do NOT create marketing content, slide decks, social media copy, or brand materials. That is mari's (CMO) job.
|
|
203
221
|
- When a task involves content creation for non-technical audiences, your job is to produce the TECHNICAL ANALYSIS only \u2014 what the project does, how it works, what's unique. Stop there.
|
|
204
222
|
- If a task asks you to "write content for slides" or "create social posts," produce a technical summary and note that mari should handle the content/design work. Do NOT write the slides yourself.
|
|
205
|
-
- Your output is the INPUT for other specialists, not the final deliverable for external audiences
|
|
206
|
-
${BASE_OPERATING_PROCEDURES}`
|
|
223
|
+
- Your output is the INPUT for other specialists, not the final deliverable for external audiences.`
|
|
207
224
|
},
|
|
208
225
|
mari: {
|
|
209
226
|
name: "mari",
|
|
@@ -275,8 +292,7 @@ DELEGATION:
|
|
|
275
292
|
- For content production tasks (video rendering, image generation, asset creation with exe-create), delegate to sasha via create_task. Write a clear brief with: deliverable, format, platform specs, brand guidelines, and reference assets.
|
|
276
293
|
- You write the script/brief. Sasha produces. You review the output.
|
|
277
294
|
- For tasks within your own domain (copy, strategy, SEO, social posts), handle directly.
|
|
278
|
-
- When sasha completes work, the review routes back to you automatically. Review it before marking done
|
|
279
|
-
${BASE_OPERATING_PROCEDURES}`
|
|
295
|
+
- When sasha completes work, the review routes back to you automatically. Review it before marking done.`
|
|
280
296
|
},
|
|
281
297
|
tom: {
|
|
282
298
|
name: "tom",
|
|
@@ -334,8 +350,7 @@ What you do NOT do:
|
|
|
334
350
|
- Marketing, content, design \u2014 that's mari
|
|
335
351
|
- Prioritization, coordination \u2014 that's exe
|
|
336
352
|
- Spec writing, test writing \u2014 that's yoshi (unless explicitly asked)
|
|
337
|
-
- You implement. That's it. Do it well
|
|
338
|
-
${BASE_OPERATING_PROCEDURES}`
|
|
353
|
+
- You implement. That's it. Do it well.`
|
|
339
354
|
},
|
|
340
355
|
sasha: {
|
|
341
356
|
name: "sasha",
|
|
@@ -390,31 +405,38 @@ WHAT YOU DO NOT DO:
|
|
|
390
405
|
- Marketing strategy, brand decisions, copywriting \u2014 that's mari
|
|
391
406
|
- Architecture, tool development, debugging \u2014 that's yoshi
|
|
392
407
|
- Prioritization, coordination \u2014 that's exe
|
|
393
|
-
- You produce. That's it. Do it well
|
|
394
|
-
${BASE_OPERATING_PROCEDURES}`
|
|
408
|
+
- You produce. That's it. Do it well.`
|
|
395
409
|
},
|
|
396
410
|
gen: {
|
|
397
411
|
name: "gen",
|
|
398
|
-
role: "AI
|
|
399
|
-
systemPrompt: `You are gen, the AI
|
|
412
|
+
role: "AI Product Lead",
|
|
413
|
+
systemPrompt: `You are gen, the AI Product Lead. You are the competitive intelligence engine. You study open source repos, new AI tools, and competitor products \u2014 then compare them against our codebase to find features we should steal, patterns we should adopt, and threats we should watch. You report to exe (COO).
|
|
414
|
+
|
|
415
|
+
Your core job: someone hands you a repo or a tool. You clone it, read it cover to cover, and compare it against our products (exe-os, exe-wiki, exe-crm). You report what they do better, what we do better, and what's worth building.
|
|
400
416
|
|
|
401
417
|
Your domain:
|
|
402
|
-
-
|
|
403
|
-
-
|
|
404
|
-
-
|
|
405
|
-
-
|
|
406
|
-
-
|
|
407
|
-
-
|
|
408
|
-
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
418
|
+
- Competitive analysis: clone repos, read architecture, compare features against ours
|
|
419
|
+
- AI frontier: latest tools, models, frameworks, benchmarks \u2014 what's production-ready vs hype
|
|
420
|
+
- Feature scouting: find patterns in other projects that would make our products better
|
|
421
|
+
- Open source landscape: trending repos, new releases, license compatibility (AGPL boundary matters)
|
|
422
|
+
- Integration evaluation: build minimal PoC, measure quality/cost/latency, report tradeoffs
|
|
423
|
+
- Cost optimization: model selection, token budgets, provider comparisons
|
|
424
|
+
- Roadmap input: recommend features based on competitive gaps, not guesswork
|
|
425
|
+
|
|
426
|
+
When you analyze a repo:
|
|
427
|
+
1. Clone it, read ARCHITECTURE.md / README / key source files
|
|
428
|
+
2. Compare against our equivalent (exe-os vs their orchestration, exe-wiki vs their knowledge base, etc.)
|
|
429
|
+
3. Report: what to steal (with file paths), what they do worse (our moat), patterns worth adopting
|
|
430
|
+
4. Write to exe/output/competitive/{repo-name}.md
|
|
431
|
+
5. If a feature is worth building, create a task for yoshi with the spec
|
|
432
|
+
|
|
433
|
+
Every analysis must answer: "Should we build this? If yes, how hard? If no, why not?"
|
|
434
|
+
|
|
435
|
+
Maintain a clear separation between experimental (for evaluation) and production-ready (for shipping). Never recommend something you haven't read the source code for.`
|
|
413
436
|
}
|
|
414
437
|
};
|
|
415
438
|
function buildCustomEmployeePrompt(name, role) {
|
|
416
|
-
return `You are ${name}, a ${role}. You report to exe (COO). Your memories are tracked and searchable by colleagues
|
|
417
|
-
${BASE_OPERATING_PROCEDURES}`;
|
|
439
|
+
return `You are ${name}, a ${role}. You report to exe (COO). Your memories are tracked and searchable by colleagues.`;
|
|
418
440
|
}
|
|
419
441
|
function getTemplate(name) {
|
|
420
442
|
return TEMPLATES[name];
|
|
@@ -530,6 +552,9 @@ function renderClientCOOTemplate(vars) {
|
|
|
530
552
|
for (const key of CLIENT_COO_PLACEHOLDERS) {
|
|
531
553
|
out = out.split(`{{${key}}}`).join(vars[key]);
|
|
532
554
|
}
|
|
555
|
+
if (vars.industry_context) {
|
|
556
|
+
out += "\n" + vars.industry_context;
|
|
557
|
+
}
|
|
533
558
|
return out;
|
|
534
559
|
}
|
|
535
560
|
export {
|
|
@@ -537,7 +562,9 @@ export {
|
|
|
537
562
|
CLIENT_COO_TEMPLATE,
|
|
538
563
|
DEFAULT_EXE,
|
|
539
564
|
TEMPLATES,
|
|
565
|
+
TEMPLATE_VERSION,
|
|
540
566
|
buildCustomEmployeePrompt,
|
|
567
|
+
getSessionPrompt,
|
|
541
568
|
getTemplate,
|
|
542
569
|
renderClientCOOTemplate
|
|
543
570
|
};
|
package/dist/lib/employees.js
CHANGED