@askexenow/exe-os 0.9.265 → 0.9.266

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.
Files changed (318) hide show
  1. package/deploy/compose/.env.example +4 -2
  2. package/deploy/compose/docker-compose.yml +6 -4
  3. package/deploy/compose/generate-env.ts +5 -2
  4. package/dist/active-agent-2XJJZFEW.js +25 -0
  5. package/dist/active-agent-JZ4PHIAK.js +26 -0
  6. package/dist/agentic-ontology-J4B525DT.js +25 -0
  7. package/dist/backfill-metadata-TWEC6BJD.js +597 -0
  8. package/dist/backfill-metadata-VGZLCJWZ.js +597 -0
  9. package/dist/behaviors-BPIVFAGY.js +25 -0
  10. package/dist/bin/agentic-ontology-backfill.js +5 -5
  11. package/dist/bin/agentic-reflection-backfill.js +6 -6
  12. package/dist/bin/agentic-semantic-label.js +5 -5
  13. package/dist/bin/backfill-conversations.js +4 -4
  14. package/dist/bin/backfill-responses.js +4 -4
  15. package/dist/bin/backfill-vectors.js +5 -5
  16. package/dist/bin/bulk-sync-postgres.js +6 -6
  17. package/dist/bin/cc-doctor.js +6 -1
  18. package/dist/bin/cleanup-stale-review-tasks.js +9 -9
  19. package/dist/bin/cli.js +15 -15
  20. package/dist/bin/exe-agent-config.js +2 -2
  21. package/dist/bin/exe-agent.js +4 -4
  22. package/dist/bin/exe-assign.js +5 -5
  23. package/dist/bin/exe-boot.js +16 -16
  24. package/dist/bin/exe-call.js +4 -4
  25. package/dist/bin/exe-cloud.js +4 -4
  26. package/dist/bin/exe-dispatch.js +9 -9
  27. package/dist/bin/exe-doctor.js +1 -1
  28. package/dist/bin/exe-export-behaviors.js +7 -7
  29. package/dist/bin/exe-forget.js +6 -6
  30. package/dist/bin/exe-gateway.js +7 -7
  31. package/dist/bin/exe-healthcheck.js +6 -1
  32. package/dist/bin/exe-heartbeat.js +9 -9
  33. package/dist/bin/exe-kill.js +12 -12
  34. package/dist/bin/exe-launch-agent.js +16 -16
  35. package/dist/bin/exe-new-employee.js +6 -6
  36. package/dist/bin/exe-pending-messages.js +10 -10
  37. package/dist/bin/exe-pending-notifications.js +9 -9
  38. package/dist/bin/exe-pending-reviews.js +9 -9
  39. package/dist/bin/exe-rename.js +4 -4
  40. package/dist/bin/exe-review.js +11 -11
  41. package/dist/bin/exe-search.js +5 -5
  42. package/dist/bin/exe-session-cleanup.js +14 -14
  43. package/dist/bin/exe-settings.js +4 -4
  44. package/dist/bin/exe-start-codex.js +11 -11
  45. package/dist/bin/exe-start-opencode.js +8 -8
  46. package/dist/bin/exe-status.js +10 -10
  47. package/dist/bin/exe-team.js +3 -3
  48. package/dist/bin/git-sweep.js +10 -10
  49. package/dist/bin/graph-backfill.js +4 -4
  50. package/dist/bin/graph-export.js +5 -5
  51. package/dist/bin/import-history.js +7 -7
  52. package/dist/bin/install.js +6 -6
  53. package/dist/bin/intercom-check.js +4 -4
  54. package/dist/bin/mcp-sessions.js +2 -2
  55. package/dist/bin/orchestration-metrics.js +4 -4
  56. package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
  57. package/dist/bin/postgres-agentic-semantic-backfill.js +1 -1
  58. package/dist/bin/scan-tasks.js +9 -9
  59. package/dist/bin/setup.js +1 -1
  60. package/dist/bin/shard-migrate.js +4 -4
  61. package/dist/capacity-monitor-3QORC56J.js +49 -0
  62. package/dist/capacity-monitor-FWRBCZCZ.js +49 -0
  63. package/dist/catchup-brief-242H63OP.js +151 -0
  64. package/dist/catchup-brief-T7W2ARRB.js +151 -0
  65. package/dist/catchup-brief-VJDLXJHJ.js +151 -0
  66. package/dist/chunk-2FDYA3GS.js +75 -0
  67. package/dist/chunk-2V33IVZF.js +1148 -0
  68. package/dist/chunk-2W5NQOQJ.js +333 -0
  69. package/dist/chunk-32QR5EHE.js +244 -0
  70. package/dist/chunk-3DBROKA6.js +382 -0
  71. package/dist/chunk-3DS2YHAT.js +204 -0
  72. package/dist/chunk-3O2ZD7YV.js +227 -0
  73. package/dist/chunk-43O2PZH7.js +214 -0
  74. package/dist/chunk-4AHL6I7X.js +284 -0
  75. package/dist/chunk-5GBPXJIH.js +50 -0
  76. package/dist/chunk-5IXN2532.js +58 -0
  77. package/dist/chunk-5SH5TR45.js +731 -0
  78. package/dist/chunk-5XGMTWKW.js +128 -0
  79. package/dist/chunk-6AQAILCS.js +13696 -0
  80. package/dist/chunk-72KQJZBH.js +382 -0
  81. package/dist/chunk-7B2AENJ3.js +1345 -0
  82. package/dist/chunk-7GKMYFVR.js +551 -0
  83. package/dist/chunk-7HUGVJHW.js +1021 -0
  84. package/dist/chunk-7HWBGXDV.js +333 -0
  85. package/dist/chunk-7ROGPDW6.js +197 -0
  86. package/dist/chunk-7ZMLNURG.js +513 -0
  87. package/dist/chunk-A3G4UXNA.js +280 -0
  88. package/dist/chunk-A4T6U3XZ.js +371 -0
  89. package/dist/chunk-ADJNRFEK.js +13696 -0
  90. package/dist/chunk-AVJTW67M.js +513 -0
  91. package/dist/chunk-B6RC7DAC.js +1090 -0
  92. package/dist/chunk-BAOJLZVC.js +244 -0
  93. package/dist/chunk-BCUMPA7J.js +159 -0
  94. package/dist/chunk-BH2ST7KK.js +183 -0
  95. package/dist/chunk-C4BIYP5C.js +129 -0
  96. package/dist/chunk-CBUZG6OC.js +89 -0
  97. package/dist/chunk-CGQRWCCP.js +81 -0
  98. package/dist/chunk-CLX4WQHT.js +214 -0
  99. package/dist/chunk-D4CQZL46.js +76 -0
  100. package/dist/chunk-DEBLYXA2.js +56 -0
  101. package/dist/chunk-EDNUE5L3.js +38 -0
  102. package/dist/chunk-ESNHLTLC.js +1073 -0
  103. package/dist/chunk-FICUAZEA.js +128 -0
  104. package/dist/chunk-FP6U5PSY.js +818 -0
  105. package/dist/chunk-G55UTKFR.js +89 -0
  106. package/dist/chunk-GIJUXLK5.js +330 -0
  107. package/dist/chunk-GVSSEGIV.js +348 -0
  108. package/dist/chunk-GYOOZ725.js +330 -0
  109. package/dist/chunk-HCULUL4D.js +447 -0
  110. package/dist/chunk-HDRQKH7R.js +1051 -0
  111. package/dist/chunk-HHBN7Y7R.js +197 -0
  112. package/dist/chunk-IQBXQ7GF.js +1073 -0
  113. package/dist/chunk-ITF6GEJI.js +2091 -0
  114. package/dist/chunk-IXHVSWLM.js +58 -0
  115. package/dist/chunk-J3ZFONT4.js +1921 -0
  116. package/dist/chunk-JEOFG274.js +394 -0
  117. package/dist/chunk-JH7ISOIJ.js +33 -0
  118. package/dist/chunk-JVRMAVPN.js +731 -0
  119. package/dist/chunk-KBYRYSXT.js +3951 -0
  120. package/dist/chunk-KECNXWD6.js +1051 -0
  121. package/dist/chunk-KIYCHS35.js +128 -0
  122. package/dist/chunk-KUP3D6G2.js +1345 -0
  123. package/dist/chunk-KXS5HHDH.js +54 -0
  124. package/dist/chunk-LVZW4WQY.js +221 -0
  125. package/dist/chunk-LWOCCDSB.js +240 -0
  126. package/dist/chunk-M4HRKRSE.js +30 -0
  127. package/dist/chunk-MPG5DR3K.js +244 -0
  128. package/dist/chunk-NOG2LVBA.js +159 -0
  129. package/dist/chunk-NP3CYOEY.js +290 -0
  130. package/dist/chunk-OVQOKLYA.js +210 -0
  131. package/dist/chunk-OW26ML36.js +1148 -0
  132. package/dist/chunk-P2DOIWQG.js +260 -0
  133. package/dist/chunk-P2QTTEYP.js +3951 -0
  134. package/dist/chunk-P5IKFL7B.js +85 -0
  135. package/dist/chunk-PD2LUPHD.js +377 -0
  136. package/dist/chunk-PF5EFIAH.js +818 -0
  137. package/dist/chunk-PK3NFO76.js +551 -0
  138. package/dist/chunk-QKMFMJTU.js +171 -0
  139. package/dist/chunk-R77M74QM.js +13696 -0
  140. package/dist/chunk-RHZ2CRJU.js +3556 -0
  141. package/dist/chunk-RLR4LVO5.js +1090 -0
  142. package/dist/chunk-RMDDSWFH.js +495 -0
  143. package/dist/chunk-RPLEZ74B.js +95 -0
  144. package/dist/chunk-RXMVPGH2.js +346 -0
  145. package/dist/chunk-S2ARWNS6.js +135 -0
  146. package/dist/chunk-SHPIATX7.js +90 -0
  147. package/dist/chunk-SQUZ3TI2.js +668 -0
  148. package/dist/chunk-SUGBKORD.js +1148 -0
  149. package/dist/chunk-T2XD7XL2.js +346 -0
  150. package/dist/chunk-TAIYLROT.js +127 -0
  151. package/dist/chunk-TCD4XCBS.js +495 -0
  152. package/dist/chunk-TSBMSHMM.js +163 -0
  153. package/dist/chunk-U776PBU6.js +488 -0
  154. package/dist/chunk-UTVNIAOF.js +284 -0
  155. package/dist/chunk-VF6VT4MR.js +70 -0
  156. package/dist/chunk-VZXLYUKS.js +171 -0
  157. package/dist/chunk-WIAHPJDS.js +58 -0
  158. package/dist/chunk-WM5ELLT4.js +54 -0
  159. package/dist/chunk-WUUSPOCC.js +1921 -0
  160. package/dist/chunk-WXHAMPK4.js +81 -0
  161. package/dist/chunk-WYNZ23XH.js +262 -0
  162. package/dist/chunk-WZOQLU2Y.js +127 -0
  163. package/dist/chunk-X24GBZKR.js +157 -0
  164. package/dist/chunk-X5FRF5MG.js +13696 -0
  165. package/dist/chunk-XBPLYFBA.js +204 -0
  166. package/dist/chunk-XDGKFXFW.js +363 -0
  167. package/dist/chunk-XIT6ONPY.js +630 -0
  168. package/dist/chunk-XNRJ5JHU.js +377 -0
  169. package/dist/chunk-XREWTPZM.js +123 -0
  170. package/dist/chunk-XURCA5VD.js +297 -0
  171. package/dist/chunk-Y55VFZJB.js +50 -0
  172. package/dist/chunk-YIH2YMWP.js +76 -0
  173. package/dist/chunk-YZMCCT73.js +97 -0
  174. package/dist/chunk-ZTP3VV23.js +447 -0
  175. package/dist/co-activation-JOYR73H2.js +72 -0
  176. package/dist/co-occurrence-G7RRJ3DB.js +74 -0
  177. package/dist/core-memory-6KK55Z65.js +110 -0
  178. package/dist/core-memory-QRS6GBXL.js +110 -0
  179. package/dist/crdt-sync-QWK65Z5A.js +33 -0
  180. package/dist/crm-webhook-BNUS3USD.js +10 -0
  181. package/dist/crm-webhook-ZTIRFVAH.js +10 -0
  182. package/dist/cto-delegation-gate-DNZJGBS7.js +206 -0
  183. package/dist/cto-delegation-gate-YI3LK7VY.js +206 -0
  184. package/dist/daemon-orchestration-7LVOHYKA.js +135 -0
  185. package/dist/daemon-orchestration-SDQNWI3K.js +135 -0
  186. package/dist/db-backup-5ENHDNZI.js +33 -0
  187. package/dist/dreaming-PGJOCGAM.js +32 -0
  188. package/dist/dreaming-UNHHGOU3.js +32 -0
  189. package/dist/exe-drift-QQJMUQXA.js +68 -0
  190. package/dist/exe-export-BEZZSQB4.js +73 -0
  191. package/dist/exe-export-TQGI2VBT.js +73 -0
  192. package/dist/exe-import-2SR2UP3D.js +76 -0
  193. package/dist/exe-import-73Q4VLFK.js +76 -0
  194. package/dist/exe-key-6JHEINOM.js +579 -0
  195. package/dist/exe-key-RIRPIFK6.js +579 -0
  196. package/dist/exe-snapshot-NDMDQJOH.js +164 -0
  197. package/dist/exe-snapshot-PVCBPMPJ.js +164 -0
  198. package/dist/fast-db-init-22OBOPTN.js +7 -0
  199. package/dist/fast-db-init-M6ZYYGAL.js +7 -0
  200. package/dist/gateway/index.js +8 -8
  201. package/dist/git-staleness-4DGYC3RY.js +110 -0
  202. package/dist/git-task-sweep-CUR7R2ZM.js +40 -0
  203. package/dist/git-task-sweep-YG3IVGK3.js +40 -0
  204. package/dist/global-procedures-TYDNKM7V.js +20 -0
  205. package/dist/graph-auto-extract-I6B5HWTP.js +162 -0
  206. package/dist/hooks/bug-report-worker.js +11 -11
  207. package/dist/hooks/codex-stop-task-finalizer.js +11 -11
  208. package/dist/hooks/commit-complete.js +11 -11
  209. package/dist/hooks/error-recall.js +6 -6
  210. package/dist/hooks/exe-heartbeat-hook.js +3 -3
  211. package/dist/hooks/ingest.js +6 -6
  212. package/dist/hooks/instructions-loaded.js +4 -4
  213. package/dist/hooks/manifest.json +19 -19
  214. package/dist/hooks/notification.js +4 -4
  215. package/dist/hooks/post-compact.js +10 -10
  216. package/dist/hooks/post-tool-combined.js +5 -5
  217. package/dist/hooks/pre-compact.js +11 -11
  218. package/dist/hooks/pre-tool-use.js +14 -14
  219. package/dist/hooks/prompt-submit.js +20 -20
  220. package/dist/hooks/session-end.js +15 -15
  221. package/dist/hooks/session-start.js +10 -10
  222. package/dist/hooks/stop.js +14 -14
  223. package/dist/hooks/subagent-stop.js +10 -10
  224. package/dist/hooks/summary-worker.js +14 -14
  225. package/dist/index.js +17 -17
  226. package/dist/installer-4LP73C3M.js +38 -0
  227. package/dist/installer-AUVLNS4D.js +296 -0
  228. package/dist/installer-KCRLQSQH.js +38 -0
  229. package/dist/installer-KGXYUOIV.js +296 -0
  230. package/dist/installer-UI6TNJGO.js +342 -0
  231. package/dist/installer-Z7NPD4PD.js +342 -0
  232. package/dist/lib/cloud-sync.js +4 -4
  233. package/dist/lib/consolidation.js +5 -5
  234. package/dist/lib/database.js +2 -2
  235. package/dist/lib/db-daemon-client.js +6 -0
  236. package/dist/lib/db.js +2 -2
  237. package/dist/lib/employee-templates.js +4 -4
  238. package/dist/lib/employees.js +2 -2
  239. package/dist/lib/exe-daemon.js +39 -38
  240. package/dist/lib/hybrid-search.js +5 -5
  241. package/dist/lib/identity.js +2 -2
  242. package/dist/lib/messaging.js +9 -9
  243. package/dist/lib/reminders.js +3 -3
  244. package/dist/lib/schedules.js +5 -5
  245. package/dist/lib/session-registry.js +4 -4
  246. package/dist/lib/skill-learning.js +4 -4
  247. package/dist/lib/store.js +4 -4
  248. package/dist/lib/task-router.js +3 -3
  249. package/dist/lib/tasks.js +10 -10
  250. package/dist/lib/tmux-routing.js +8 -8
  251. package/dist/lib/token-spend.js +3 -3
  252. package/dist/mcp/register-tools.js +53 -52
  253. package/dist/mcp/server.js +54 -53
  254. package/dist/mcp/tools/complete-reminder.js +4 -4
  255. package/dist/mcp/tools/create-reminder.js +4 -4
  256. package/dist/mcp/tools/create-task.js +12 -12
  257. package/dist/mcp/tools/deactivate-behavior.js +5 -5
  258. package/dist/mcp/tools/list-reminders.js +4 -4
  259. package/dist/mcp/tools/list-tasks.js +12 -12
  260. package/dist/mcp/tools/send-message.js +11 -11
  261. package/dist/mcp/tools/update-task.js +11 -11
  262. package/dist/mcp-http-config-LN5ITKGS.js +27 -0
  263. package/dist/mcp-http-config-V43VHNEH.js +27 -0
  264. package/dist/memory-cards-S36DCEY4.js +174 -0
  265. package/dist/memory-graph-extractor-66YL4V4B.js +17 -0
  266. package/dist/memory-poisoning-defense-MXWE6CTY.js +225 -0
  267. package/dist/memory-reflection-W676LUX5.js +238 -0
  268. package/dist/notifications-OFLXZTDZ.js +45 -0
  269. package/dist/notifications-XAV4V7T5.js +45 -0
  270. package/dist/orchestration-events-MJLWJ2H2.js +25 -0
  271. package/dist/orchestrator-AIAKV5ST.js +33 -0
  272. package/dist/orchestrator-VK7D6I36.js +33 -0
  273. package/dist/pipeline-router-DXH5QVUH.js +13 -0
  274. package/dist/pipeline-router-EV6C5S33.js +13 -0
  275. package/dist/plan-limits-TQMLKZBG.js +26 -0
  276. package/dist/project-boot-4XTXHDG4.js +299 -0
  277. package/dist/projection-worker-NAYVNSI4.js +964 -0
  278. package/dist/reranker-KHZI7HQK.js +19 -0
  279. package/dist/reranker-UPMS3OX7.js +19 -0
  280. package/dist/reranker-ZN73HWSB.js +19 -0
  281. package/dist/review-polling-3UEZSPNT.js +124 -0
  282. package/dist/review-polling-KBDX3ILL.js +124 -0
  283. package/dist/runtime/index.js +11 -11
  284. package/dist/session-events-2CHOLA6D.js +36 -0
  285. package/dist/session-events-HM22KEHN.js +36 -0
  286. package/dist/session-kill-telemetry-LUPVYGZX.js +29 -0
  287. package/dist/session-scope-EPZZZHHJ.js +86 -0
  288. package/dist/session-scope-ZGE6GHMS.js +86 -0
  289. package/dist/setup-wizard-KNWH54HW.js +12 -0
  290. package/dist/skill-refinement-C4GNWV4F.js +157 -0
  291. package/dist/skill-refinement-CAUIE4YM.js +157 -0
  292. package/dist/steward-gate-MZ2DV36N.js +13 -0
  293. package/dist/task-enforcement-6OMXG6EA.js +333 -0
  294. package/dist/task-enforcement-JFSF6QDD.js +333 -0
  295. package/dist/task-scope-4HJSCJ7L.js +35 -0
  296. package/dist/task-scope-7HYE4AS6.js +35 -0
  297. package/dist/tasks-crud-JJL6MMJF.js +77 -0
  298. package/dist/tasks-crud-KMIPDHBZ.js +77 -0
  299. package/dist/tasks-notify-5D6LF52K.js +38 -0
  300. package/dist/tasks-notify-JNGGXFUY.js +38 -0
  301. package/dist/tasks-review-N6I5UC7G.js +47 -0
  302. package/dist/tasks-review-USHAMO5N.js +47 -0
  303. package/dist/telemetry-upload-BV2M2NND.js +739 -0
  304. package/dist/telemetry-upload-Y7QPDJW4.js +739 -0
  305. package/dist/token-budget-2LUZOFO7.js +84 -0
  306. package/dist/tool-telemetry-5JT6DPVK.js +17 -0
  307. package/dist/tui/App.js +16 -16
  308. package/dist/tui-data-DMAKZMGD.js +258 -0
  309. package/dist/tui-data-X7NI6ZQ3.js +258 -0
  310. package/dist/wiki-acl-QHGGWX63.js +111 -0
  311. package/dist/worker-gate-4XKUOFWO.js +21 -0
  312. package/dist/worker-gate-TPZBOXOA.js +21 -0
  313. package/dist/workflow-engine-F3URLOPA.js +28 -0
  314. package/dist/workflow-engine-OFOL446Z.js +28 -0
  315. package/dist/worktree-V3NVP7MV.js +26 -0
  316. package/dist/worktree-sweep-2CADL43Y.js +19 -0
  317. package/package.json +1 -1
  318. package/release-notes.json +16 -15
@@ -0,0 +1,333 @@
1
+ import {
2
+ executeAction,
3
+ substituteTemplate
4
+ } from "./chunk-3DBROKA6.js";
5
+
6
+ // src/automation/workflow-engine.ts
7
+ import { randomUUID } from "crypto";
8
+ var _definitions = /* @__PURE__ */ new Map();
9
+ var _instances = /* @__PURE__ */ new Map();
10
+ function createWorkflowDefinition(input) {
11
+ const def = {
12
+ id: randomUUID().slice(0, 12),
13
+ ...input,
14
+ created_at: (/* @__PURE__ */ new Date()).toISOString()
15
+ };
16
+ def.steps = def.steps.map((s, i) => ({ ...s, index: s.index || i + 1 }));
17
+ _definitions.set(def.id, def);
18
+ return def;
19
+ }
20
+ function getWorkflowDefinition(id) {
21
+ return _definitions.get(id);
22
+ }
23
+ function listWorkflowDefinitions() {
24
+ return [..._definitions.values()];
25
+ }
26
+ function buildTemplateContext(instance) {
27
+ const ctx = { ...instance.context };
28
+ const stepMap = {};
29
+ for (const sr of instance.step_results) {
30
+ stepMap[String(sr.step_index)] = {
31
+ status: sr.status,
32
+ result: sr.result,
33
+ error: sr.error
34
+ };
35
+ }
36
+ ctx.step = stepMap;
37
+ return ctx;
38
+ }
39
+ function resolveActionParams(action, context) {
40
+ const resolved = {};
41
+ for (const [key, val] of Object.entries(action.params)) {
42
+ resolved[key] = substituteTemplate(val, context);
43
+ }
44
+ return { ...action, params: resolved };
45
+ }
46
+ function startWorkflow(definitionId, context = {}) {
47
+ const def = _definitions.get(definitionId);
48
+ if (!def) throw new Error(`Workflow definition "${definitionId}" not found`);
49
+ const instance = {
50
+ id: randomUUID().slice(0, 12),
51
+ definition_id: definitionId,
52
+ status: "running",
53
+ current_step: 1,
54
+ step_results: [],
55
+ context,
56
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
57
+ updated_at: (/* @__PURE__ */ new Date()).toISOString()
58
+ };
59
+ _instances.set(instance.id, instance);
60
+ return instance;
61
+ }
62
+ function getWorkflowInstance(id) {
63
+ return _instances.get(id);
64
+ }
65
+ function listWorkflowInstances(status) {
66
+ const all = [..._instances.values()];
67
+ return status ? all.filter((i) => i.status === status) : all;
68
+ }
69
+ async function advanceWorkflow(instanceId) {
70
+ const instance = _instances.get(instanceId);
71
+ if (!instance) throw new Error(`Workflow instance "${instanceId}" not found`);
72
+ if (instance.status !== "running") {
73
+ throw new Error(`Workflow "${instanceId}" is ${instance.status}, cannot advance`);
74
+ }
75
+ const def = _definitions.get(instance.definition_id);
76
+ if (!def) throw new Error(`Workflow definition "${instance.definition_id}" not found`);
77
+ const step = def.steps.find((s) => s.index === instance.current_step);
78
+ if (!step) {
79
+ instance.status = "completed";
80
+ instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
81
+ return instance;
82
+ }
83
+ const templateCtx = buildTemplateContext(instance);
84
+ const stepResult = {
85
+ step_index: step.index,
86
+ status: "success",
87
+ started_at: (/* @__PURE__ */ new Date()).toISOString()
88
+ };
89
+ switch (step.type) {
90
+ case "execute_action": {
91
+ const action = step.action ?? buildActionFromConnector(step);
92
+ if (!action) {
93
+ stepResult.status = "failed";
94
+ stepResult.error = "No action defined for execute_action step";
95
+ break;
96
+ }
97
+ const resolvedAction = resolveActionParams(action, templateCtx);
98
+ const result = await executeAction(resolvedAction, templateCtx);
99
+ stepResult.status = result.success ? "success" : "failed";
100
+ stepResult.result = result;
101
+ stepResult.error = result.error;
102
+ if (!result.success) {
103
+ instance.status = "failed";
104
+ }
105
+ break;
106
+ }
107
+ case "wait_for_approval": {
108
+ const { createTask } = await import("./lib/tasks.js");
109
+ const { getCoordinatorName } = await import("./lib/employees.js");
110
+ const message = step.approval_message ? substituteTemplate(step.approval_message, templateCtx) : `Workflow "${def.name}" step ${step.index} ("${step.name}") requires approval.`;
111
+ const task = await createTask({
112
+ title: `[Workflow Approval] ${def.name}: ${step.name}`,
113
+ assignedTo: getCoordinatorName(),
114
+ assignedBy: "workflow-engine",
115
+ projectName: "exe-os",
116
+ priority: "p1",
117
+ context: `${message}
118
+
119
+ **Workflow:** ${def.name} (${instance.id})
120
+ **Step:** ${step.index} \u2014 ${step.name}
121
+
122
+ To approve: call approve_workflow_step with instance_id="${instance.id}"
123
+ To reject: call approve_workflow_step with instance_id="${instance.id}" approved=false`,
124
+ baseDir: process.cwd()
125
+ });
126
+ instance.approval_task_id = task.id;
127
+ instance.status = "waiting_approval";
128
+ stepResult.status = "pending_approval";
129
+ break;
130
+ }
131
+ case "conditional": {
132
+ if (!step.condition) {
133
+ stepResult.status = "failed";
134
+ stepResult.error = "No condition defined for conditional step";
135
+ break;
136
+ }
137
+ const resolvedExpr = substituteTemplate(step.condition.expression, templateCtx);
138
+ const conditionMet = evaluateSimpleExpression(resolvedExpr);
139
+ stepResult.result = { expression: resolvedExpr, met: conditionMet };
140
+ if (conditionMet && step.condition.then_step) {
141
+ instance.current_step = step.condition.then_step;
142
+ stepResult.completed_at = (/* @__PURE__ */ new Date()).toISOString();
143
+ instance.step_results.push(stepResult);
144
+ instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
145
+ return instance;
146
+ } else if (!conditionMet && step.condition.else_step) {
147
+ instance.current_step = step.condition.else_step;
148
+ stepResult.completed_at = (/* @__PURE__ */ new Date()).toISOString();
149
+ instance.step_results.push(stepResult);
150
+ instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
151
+ return instance;
152
+ }
153
+ break;
154
+ }
155
+ }
156
+ stepResult.completed_at = (/* @__PURE__ */ new Date()).toISOString();
157
+ instance.step_results.push(stepResult);
158
+ if (instance.status === "running") {
159
+ const nextStep = def.steps.find((s) => s.index > step.index);
160
+ if (nextStep) {
161
+ instance.current_step = nextStep.index;
162
+ } else {
163
+ instance.status = "completed";
164
+ }
165
+ }
166
+ instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
167
+ return instance;
168
+ }
169
+ async function runWorkflow(instanceId) {
170
+ let instance = _instances.get(instanceId);
171
+ if (!instance) throw new Error(`Workflow instance "${instanceId}" not found`);
172
+ while (instance.status === "running") {
173
+ instance = await advanceWorkflow(instanceId);
174
+ }
175
+ return instance;
176
+ }
177
+ async function approveWorkflowStep(instanceId, approved = true) {
178
+ const instance = _instances.get(instanceId);
179
+ if (!instance) throw new Error(`Workflow instance "${instanceId}" not found`);
180
+ if (instance.status !== "waiting_approval") {
181
+ throw new Error(`Workflow "${instanceId}" is not waiting for approval (status: ${instance.status})`);
182
+ }
183
+ const pendingResult = instance.step_results.find(
184
+ (sr) => sr.step_index === instance.current_step && sr.status === "pending_approval"
185
+ );
186
+ if (pendingResult) {
187
+ pendingResult.status = approved ? "approved" : "failed";
188
+ pendingResult.completed_at = (/* @__PURE__ */ new Date()).toISOString();
189
+ pendingResult.result = { approved };
190
+ }
191
+ if (!approved) {
192
+ instance.status = "cancelled";
193
+ instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
194
+ return instance;
195
+ }
196
+ const def = _definitions.get(instance.definition_id);
197
+ if (!def) throw new Error(`Workflow definition "${instance.definition_id}" not found`);
198
+ const currentStep = def.steps.find((s) => s.index === instance.current_step);
199
+ const nextStep = currentStep ? def.steps.find((s) => s.index > currentStep.index) : void 0;
200
+ if (nextStep) {
201
+ instance.current_step = nextStep.index;
202
+ instance.status = "running";
203
+ } else {
204
+ instance.status = "completed";
205
+ }
206
+ instance.approval_task_id = void 0;
207
+ instance.updated_at = (/* @__PURE__ */ new Date()).toISOString();
208
+ if (instance.status === "running") {
209
+ return runWorkflow(instanceId);
210
+ }
211
+ return instance;
212
+ }
213
+ function buildActionFromConnector(step) {
214
+ if (!step.connector || !step.operation) return null;
215
+ const params = {};
216
+ if (step.payload) {
217
+ for (const [k, v] of Object.entries(step.payload)) {
218
+ params[k] = String(v);
219
+ }
220
+ }
221
+ params._connector = step.connector;
222
+ params._operation = step.operation;
223
+ return {
224
+ type: "mcp_tool",
225
+ params
226
+ };
227
+ }
228
+ function evaluateSimpleExpression(expr) {
229
+ const operators = ["==", "!=", ">=", "<=", ">", "<"];
230
+ for (const op of operators) {
231
+ const idx = expr.indexOf(op);
232
+ if (idx === -1) continue;
233
+ const left = expr.slice(0, idx).trim();
234
+ const right = expr.slice(idx + op.length).trim();
235
+ switch (op) {
236
+ case "==":
237
+ return left === right;
238
+ case "!=":
239
+ return left !== right;
240
+ case ">":
241
+ return Number(left) > Number(right);
242
+ case "<":
243
+ return Number(left) < Number(right);
244
+ case ">=":
245
+ return Number(left) >= Number(right);
246
+ case "<=":
247
+ return Number(left) <= Number(right);
248
+ }
249
+ }
250
+ return expr.trim() !== "" && expr.trim() !== "false" && expr.trim() !== "0";
251
+ }
252
+ async function persistWorkflows() {
253
+ try {
254
+ const { getClient } = await import("./lib/database.js");
255
+ const client = getClient();
256
+ for (const def of _definitions.values()) {
257
+ await client.execute({
258
+ sql: `INSERT OR REPLACE INTO workflow_definitions (id, name, description, steps, trigger_event, created_at)
259
+ VALUES (?, ?, ?, ?, ?, ?)`,
260
+ args: [def.id, def.name, def.description ?? null, JSON.stringify(def.steps), def.trigger_event ?? null, def.created_at]
261
+ });
262
+ }
263
+ for (const inst of _instances.values()) {
264
+ await client.execute({
265
+ sql: `INSERT OR REPLACE INTO workflow_instances
266
+ (id, definition_id, status, current_step, step_results, context, approval_task_id, created_at, updated_at)
267
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
268
+ args: [
269
+ inst.id,
270
+ inst.definition_id,
271
+ inst.status,
272
+ inst.current_step,
273
+ JSON.stringify(inst.step_results),
274
+ JSON.stringify(inst.context),
275
+ inst.approval_task_id ?? null,
276
+ inst.created_at,
277
+ inst.updated_at
278
+ ]
279
+ });
280
+ }
281
+ } catch (e) {
282
+ process.stderr.write(`[workflow-engine] persist failed: ${e instanceof Error ? e.message : String(e)}
283
+ `);
284
+ }
285
+ }
286
+ async function loadWorkflows() {
287
+ try {
288
+ const { getClient } = await import("./lib/database.js");
289
+ const client = getClient();
290
+ const defs = await client.execute("SELECT * FROM workflow_definitions");
291
+ for (const row of defs.rows) {
292
+ const def = {
293
+ id: String(row.id),
294
+ name: String(row.name),
295
+ description: String(row.description),
296
+ steps: JSON.parse(String(row.steps)),
297
+ trigger_event: String(row.trigger_event),
298
+ created_at: String(row.created_at)
299
+ };
300
+ _definitions.set(def.id, def);
301
+ }
302
+ const insts = await client.execute("SELECT * FROM workflow_instances WHERE status NOT IN ('completed', 'cancelled')");
303
+ for (const row of insts.rows) {
304
+ const inst = {
305
+ id: String(row.id),
306
+ definition_id: String(row.definition_id),
307
+ status: String(row.status),
308
+ current_step: Number(row.current_step),
309
+ step_results: JSON.parse(String(row.step_results)),
310
+ context: JSON.parse(String(row.context)),
311
+ approval_task_id: row.approval_task_id ? String(row.approval_task_id) : void 0,
312
+ created_at: String(row.created_at),
313
+ updated_at: String(row.updated_at)
314
+ };
315
+ _instances.set(inst.id, inst);
316
+ }
317
+ } catch {
318
+ }
319
+ }
320
+
321
+ export {
322
+ createWorkflowDefinition,
323
+ getWorkflowDefinition,
324
+ listWorkflowDefinitions,
325
+ startWorkflow,
326
+ getWorkflowInstance,
327
+ listWorkflowInstances,
328
+ advanceWorkflow,
329
+ runWorkflow,
330
+ approveWorkflowStep,
331
+ persistWorkflows,
332
+ loadWorkflows
333
+ };
@@ -0,0 +1,244 @@
1
+ import {
2
+ getClient
3
+ } from "./chunk-RHZ2CRJU.js";
4
+
5
+ // src/lib/behaviors.ts
6
+ import crypto from "crypto";
7
+ async function storeBehavior(opts) {
8
+ try {
9
+ const { loadEmployeesSync, baseAgentName } = await import("./lib/employees.js");
10
+ const roster = loadEmployeesSync();
11
+ if (roster.length > 0) {
12
+ const base = baseAgentName(opts.agentId, roster);
13
+ if (!roster.some((e) => e.name === opts.agentId || e.name === base)) {
14
+ process.stderr.write(
15
+ `[behaviors] WARNING: Agent "${opts.agentId}" not found in roster. Storing behavior anyway \u2014 may be orphaned.
16
+ `
17
+ );
18
+ }
19
+ }
20
+ } catch {
21
+ }
22
+ const client = getClient();
23
+ const id = crypto.randomUUID();
24
+ const now = (/* @__PURE__ */ new Date()).toISOString();
25
+ const duplicate = await client.execute({
26
+ sql: `SELECT id FROM behaviors
27
+ WHERE agent_id = ?
28
+ AND COALESCE(domain, '') = COALESCE(?, '')
29
+ AND COALESCE(project_name, '') = COALESCE(?, '')
30
+ AND active = 1
31
+ AND lower(trim(content)) = lower(trim(?))
32
+ ORDER BY updated_at DESC
33
+ LIMIT 1`,
34
+ args: [opts.agentId, opts.domain ?? null, opts.projectName ?? null, opts.content]
35
+ });
36
+ const existingId = duplicate.rows[0]?.id;
37
+ if (existingId) return String(existingId);
38
+ let vector = null;
39
+ if (!process.env.VITEST) {
40
+ try {
41
+ const { embed } = await import("./lib/embedder.js");
42
+ const vec = await embed(opts.content);
43
+ vector = new Float32Array(vec);
44
+ } catch {
45
+ }
46
+ }
47
+ let createdByDevice = null;
48
+ try {
49
+ const { loadDeviceId } = await import("./lib/license.js");
50
+ createdByDevice = loadDeviceId() ?? null;
51
+ } catch {
52
+ }
53
+ const createdByAgent = process.env.AGENT_ID ?? null;
54
+ const sourceSessionId = process.env.CLAUDE_SESSION_ID ?? process.env.SESSION_ID ?? null;
55
+ let deviceId = null;
56
+ if (opts.deviceScoped) {
57
+ try {
58
+ const { loadDeviceId } = await import("./lib/license.js");
59
+ deviceId = loadDeviceId() ?? null;
60
+ } catch {
61
+ }
62
+ }
63
+ await client.execute({
64
+ sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector, created_by_agent, created_by_device, source_session_id, device_id)
65
+ VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?)`,
66
+ args: [id, opts.agentId, opts.projectName ?? null, opts.domain ?? null, opts.priority ?? "p1", opts.content, now, now, vector ? vector.buffer : null, createdByAgent, createdByDevice, sourceSessionId, deviceId]
67
+ });
68
+ return id;
69
+ }
70
+ async function listBehaviors(agentId, projectName, limit = 30) {
71
+ const client = getClient();
72
+ let currentDeviceId = null;
73
+ try {
74
+ const { loadDeviceId } = await import("./lib/license.js");
75
+ currentDeviceId = loadDeviceId() ?? null;
76
+ } catch {
77
+ }
78
+ const result = await client.execute({
79
+ sql: `SELECT id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector, created_by_agent, created_by_device, source_session_id, device_id
80
+ FROM behaviors
81
+ WHERE agent_id = ? AND active = 1
82
+ AND (project_name IS NULL OR project_name = ?)
83
+ AND (device_id IS NULL OR device_id = ?)
84
+ ORDER BY
85
+ CASE WHEN priority = 'p0' THEN 0
86
+ WHEN priority = 'p1' THEN 1
87
+ ELSE 2 END,
88
+ CASE
89
+ WHEN lower(coalesce(domain, '')) IN ('identity', 'title', 'role') THEN 0
90
+ WHEN lower(content) LIKE '%identity%' THEN 0
91
+ WHEN lower(content) LIKE '%title%' THEN 0
92
+ WHEN lower(content) LIKE '%who are you%' THEN 0
93
+ ELSE 1
94
+ END,
95
+ updated_at DESC
96
+ LIMIT ?`,
97
+ args: [agentId, projectName ?? "", currentDeviceId ?? "", limit]
98
+ });
99
+ return result.rows.map((r) => ({
100
+ id: String(r.id),
101
+ agent_id: String(r.agent_id),
102
+ project_name: r.project_name ? String(r.project_name) : null,
103
+ domain: r.domain ? String(r.domain) : null,
104
+ priority: String(r.priority || "p1"),
105
+ content: String(r.content),
106
+ active: Number(r.active),
107
+ created_at: String(r.created_at),
108
+ updated_at: String(r.updated_at),
109
+ vector: r.vector ? Array.from(new Float32Array(r.vector)) : null,
110
+ created_by_agent: r.created_by_agent ? String(r.created_by_agent) : null,
111
+ created_by_device: r.created_by_device ? String(r.created_by_device) : null,
112
+ source_session_id: r.source_session_id ? String(r.source_session_id) : null,
113
+ device_id: r.device_id ? String(r.device_id) : null
114
+ }));
115
+ }
116
+ async function listBehaviorsByDomain(agentId, domain) {
117
+ const client = getClient();
118
+ const result = await client.execute({
119
+ sql: `SELECT id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector
120
+ FROM behaviors
121
+ WHERE agent_id = ? AND domain = ? AND active = 1`,
122
+ args: [agentId, domain]
123
+ });
124
+ return result.rows.map((r) => ({
125
+ id: String(r.id),
126
+ agent_id: String(r.agent_id),
127
+ project_name: r.project_name ? String(r.project_name) : null,
128
+ domain: r.domain ? String(r.domain) : null,
129
+ priority: String(r.priority || "p1"),
130
+ content: String(r.content),
131
+ active: Number(r.active),
132
+ created_at: String(r.created_at),
133
+ updated_at: String(r.updated_at),
134
+ vector: r.vector ? Array.from(new Float32Array(r.vector)) : null,
135
+ created_by_agent: r.created_by_agent ? String(r.created_by_agent) : null,
136
+ created_by_device: r.created_by_device ? String(r.created_by_device) : null,
137
+ source_session_id: r.source_session_id ? String(r.source_session_id) : null,
138
+ device_id: r.device_id ? String(r.device_id) : null
139
+ }));
140
+ }
141
+ async function listBehaviorsSince(agentId, sinceIso, projectName, limit = 15) {
142
+ const client = getClient();
143
+ let currentDeviceId = null;
144
+ try {
145
+ const { loadDeviceId } = await import("./lib/license.js");
146
+ currentDeviceId = loadDeviceId() ?? null;
147
+ } catch {
148
+ }
149
+ const result = await client.execute({
150
+ sql: `SELECT id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector, created_by_agent, created_by_device, source_session_id, device_id
151
+ FROM behaviors
152
+ WHERE agent_id = ? AND active = 1
153
+ AND (project_name IS NULL OR project_name = ?)
154
+ AND (device_id IS NULL OR device_id = ?)
155
+ AND (created_at > ? OR updated_at > ?)
156
+ ORDER BY
157
+ CASE WHEN priority = 'p0' THEN 0
158
+ WHEN priority = 'p1' THEN 1
159
+ ELSE 2 END,
160
+ updated_at DESC
161
+ LIMIT ?`,
162
+ args: [agentId, projectName ?? "", currentDeviceId ?? "", sinceIso, sinceIso, limit]
163
+ });
164
+ return result.rows.map((r) => ({
165
+ id: String(r.id),
166
+ agent_id: String(r.agent_id),
167
+ project_name: r.project_name ? String(r.project_name) : null,
168
+ domain: r.domain ? String(r.domain) : null,
169
+ priority: String(r.priority || "p1"),
170
+ content: String(r.content),
171
+ active: Number(r.active),
172
+ created_at: String(r.created_at),
173
+ updated_at: String(r.updated_at),
174
+ vector: r.vector ? Array.from(new Float32Array(r.vector)) : null,
175
+ created_by_agent: r.created_by_agent ? String(r.created_by_agent) : null,
176
+ created_by_device: r.created_by_device ? String(r.created_by_device) : null,
177
+ source_session_id: r.source_session_id ? String(r.source_session_id) : null,
178
+ device_id: r.device_id ? String(r.device_id) : null
179
+ }));
180
+ }
181
+ async function listSharedSkills(currentAgentId, projectName, limit = 30) {
182
+ const client = getClient();
183
+ let currentDeviceId = null;
184
+ try {
185
+ const { loadDeviceId } = await import("./lib/license.js");
186
+ currentDeviceId = loadDeviceId() ?? null;
187
+ } catch {
188
+ }
189
+ const result = await client.execute({
190
+ sql: `SELECT id, agent_id, project_name, domain, priority, content, active, created_at, updated_at, vector, created_by_agent, created_by_device, source_session_id, device_id
191
+ FROM behaviors
192
+ WHERE domain = 'skill' AND active = 1
193
+ AND (project_name IS NULL OR project_name = ?)
194
+ AND (device_id IS NULL OR device_id = ?)
195
+ ORDER BY
196
+ CASE WHEN agent_id = ? THEN 0 ELSE 1 END,
197
+ updated_at DESC
198
+ LIMIT ?`,
199
+ args: [projectName ?? "", currentDeviceId ?? "", currentAgentId, limit]
200
+ });
201
+ return result.rows.map((r) => ({
202
+ id: String(r.id),
203
+ agent_id: String(r.agent_id),
204
+ project_name: r.project_name ? String(r.project_name) : null,
205
+ domain: r.domain ? String(r.domain) : null,
206
+ priority: String(r.priority || "p1"),
207
+ content: String(r.content),
208
+ active: Number(r.active),
209
+ created_at: String(r.created_at),
210
+ updated_at: String(r.updated_at),
211
+ vector: r.vector ? Array.from(new Float32Array(r.vector)) : null,
212
+ created_by_agent: r.created_by_agent ? String(r.created_by_agent) : null,
213
+ created_by_device: r.created_by_device ? String(r.created_by_device) : null,
214
+ source_session_id: r.source_session_id ? String(r.source_session_id) : null,
215
+ device_id: r.device_id ? String(r.device_id) : null,
216
+ shared: String(r.agent_id) !== currentAgentId
217
+ }));
218
+ }
219
+ async function deactivateBehavior(id) {
220
+ const client = getClient();
221
+ const result = await client.execute({
222
+ sql: `UPDATE behaviors SET active = 0, updated_at = ? WHERE id = ? AND active = 1`,
223
+ args: [(/* @__PURE__ */ new Date()).toISOString(), id]
224
+ });
225
+ return (result.rowsAffected ?? 0) > 0;
226
+ }
227
+ async function reactivateBehavior(id) {
228
+ const client = getClient();
229
+ const result = await client.execute({
230
+ sql: `UPDATE behaviors SET active = 1, updated_at = ? WHERE id = ? AND active = 0`,
231
+ args: [(/* @__PURE__ */ new Date()).toISOString(), id]
232
+ });
233
+ return (result.rowsAffected ?? 0) > 0;
234
+ }
235
+
236
+ export {
237
+ storeBehavior,
238
+ listBehaviors,
239
+ listBehaviorsByDomain,
240
+ listBehaviorsSince,
241
+ listSharedSkills,
242
+ deactivateBehavior,
243
+ reactivateBehavior
244
+ };