@askexenow/exe-os 0.9.264 → 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.
- package/deploy/compose/.env.example +4 -2
- package/deploy/compose/docker-compose.yml +6 -4
- package/deploy/compose/generate-env.ts +5 -2
- package/dist/active-agent-2XJJZFEW.js +25 -0
- package/dist/active-agent-JZ4PHIAK.js +26 -0
- package/dist/agentic-ontology-J4B525DT.js +25 -0
- package/dist/backfill-metadata-TWEC6BJD.js +597 -0
- package/dist/backfill-metadata-VGZLCJWZ.js +597 -0
- package/dist/backfill-metadata-WM46YQZL.js +597 -0
- package/dist/behaviors-BPIVFAGY.js +25 -0
- package/dist/bin/agentic-ontology-backfill.js +5 -5
- package/dist/bin/agentic-reflection-backfill.js +6 -6
- package/dist/bin/agentic-semantic-label.js +5 -5
- package/dist/bin/backfill-conversations.js +4 -4
- package/dist/bin/backfill-responses.js +4 -4
- package/dist/bin/backfill-vectors.js +5 -5
- package/dist/bin/bulk-sync-postgres.js +6 -6
- package/dist/bin/cc-doctor.js +6 -1
- package/dist/bin/cleanup-stale-review-tasks.js +9 -9
- package/dist/bin/cli.js +15 -15
- package/dist/bin/exe-agent-config.js +2 -2
- package/dist/bin/exe-agent.js +4 -4
- package/dist/bin/exe-assign.js +5 -5
- package/dist/bin/exe-boot.js +16 -16
- package/dist/bin/exe-call.js +4 -4
- package/dist/bin/exe-cloud.js +4 -4
- package/dist/bin/exe-dispatch.js +9 -9
- package/dist/bin/exe-doctor.js +1 -1
- package/dist/bin/exe-export-behaviors.js +7 -7
- package/dist/bin/exe-forget.js +6 -6
- package/dist/bin/exe-gateway.js +7 -7
- package/dist/bin/exe-healthcheck.js +6 -1
- package/dist/bin/exe-heartbeat.js +10 -10
- package/dist/bin/exe-kill.js +12 -12
- package/dist/bin/exe-launch-agent.js +16 -16
- package/dist/bin/exe-new-employee.js +6 -6
- package/dist/bin/exe-pending-messages.js +10 -10
- package/dist/bin/exe-pending-notifications.js +9 -9
- package/dist/bin/exe-pending-reviews.js +12 -10
- package/dist/bin/exe-rename.js +4 -4
- package/dist/bin/exe-review.js +11 -11
- package/dist/bin/exe-search.js +5 -5
- package/dist/bin/exe-session-cleanup.js +14 -14
- package/dist/bin/exe-settings.js +4 -4
- package/dist/bin/exe-start-codex.js +11 -11
- package/dist/bin/exe-start-opencode.js +8 -8
- package/dist/bin/exe-status.js +10 -10
- package/dist/bin/exe-team.js +3 -3
- package/dist/bin/git-sweep.js +10 -10
- package/dist/bin/graph-backfill.js +4 -4
- package/dist/bin/graph-export.js +5 -5
- package/dist/bin/import-history.js +7 -7
- package/dist/bin/install.js +6 -6
- package/dist/bin/intercom-check.js +6 -5
- package/dist/bin/mcp-sessions.js +2 -2
- package/dist/bin/orchestration-metrics.js +4 -4
- package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
- package/dist/bin/postgres-agentic-semantic-backfill.js +1 -1
- package/dist/bin/scan-tasks.js +9 -9
- package/dist/bin/setup.js +1 -1
- package/dist/bin/shard-migrate.js +4 -4
- package/dist/capacity-monitor-3QORC56J.js +49 -0
- package/dist/capacity-monitor-FWRBCZCZ.js +49 -0
- package/dist/capacity-monitor-FZORNXTA.js +49 -0
- package/dist/catchup-brief-242H63OP.js +151 -0
- package/dist/catchup-brief-PRKHIRWW.js +151 -0
- package/dist/catchup-brief-T7W2ARRB.js +151 -0
- package/dist/catchup-brief-VJDLXJHJ.js +151 -0
- package/dist/chunk-2FDYA3GS.js +75 -0
- package/dist/chunk-2GU3NYMB.js +813 -0
- package/dist/chunk-2V33IVZF.js +1148 -0
- package/dist/chunk-2VT7Z2E2.js +197 -0
- package/dist/chunk-2W5NQOQJ.js +333 -0
- package/dist/chunk-32QR5EHE.js +244 -0
- package/dist/chunk-3DBROKA6.js +382 -0
- package/dist/chunk-3DS2YHAT.js +204 -0
- package/dist/chunk-3L6XLN4V.js +1090 -0
- package/dist/chunk-3O2ZD7YV.js +227 -0
- package/dist/chunk-3T4PNG5O.js +447 -0
- package/dist/chunk-3W324KN7.js +13696 -0
- package/dist/chunk-43O2PZH7.js +214 -0
- package/dist/chunk-4AHL6I7X.js +284 -0
- package/dist/chunk-4IATAIAF.js +89 -0
- package/dist/chunk-5GBPXJIH.js +50 -0
- package/dist/chunk-5IXN2532.js +58 -0
- package/dist/chunk-5M4F2FVD.js +204 -0
- package/dist/chunk-5SH5TR45.js +731 -0
- package/dist/chunk-5TANMPI4.js +377 -0
- package/dist/chunk-5XGMTWKW.js +128 -0
- package/dist/chunk-67E5WIMW.js +333 -0
- package/dist/chunk-6AQAILCS.js +13696 -0
- package/dist/chunk-6NRJIARA.js +346 -0
- package/dist/chunk-6O22GTSE.js +1148 -0
- package/dist/chunk-72KQJZBH.js +382 -0
- package/dist/chunk-7B2AENJ3.js +1345 -0
- package/dist/chunk-7GKMYFVR.js +551 -0
- package/dist/chunk-7HUGVJHW.js +1021 -0
- package/dist/chunk-7HWBGXDV.js +333 -0
- package/dist/chunk-7O5CMDP6.js +1345 -0
- package/dist/chunk-7P2JKEO3.js +382 -0
- package/dist/chunk-7ROGPDW6.js +197 -0
- package/dist/chunk-7ZMLNURG.js +513 -0
- package/dist/chunk-A3G4UXNA.js +280 -0
- package/dist/chunk-A4T6U3XZ.js +371 -0
- package/dist/chunk-A4UY44T7.js +486 -0
- package/dist/chunk-ADJNRFEK.js +13696 -0
- package/dist/chunk-AVJTW67M.js +513 -0
- package/dist/chunk-AZHPQGSI.js +159 -0
- package/dist/chunk-B6RC7DAC.js +1090 -0
- package/dist/chunk-BAOJLZVC.js +244 -0
- package/dist/chunk-BCUMPA7J.js +159 -0
- package/dist/chunk-BH2ST7KK.js +183 -0
- package/dist/chunk-BQAC3GCO.js +127 -0
- package/dist/chunk-C4BIYP5C.js +129 -0
- package/dist/chunk-CBUZG6OC.js +89 -0
- package/dist/chunk-CGQRWCCP.js +81 -0
- package/dist/chunk-CIWJRYIC.js +244 -0
- package/dist/chunk-CLX4WQHT.js +214 -0
- package/dist/chunk-CZO2DGGF.js +214 -0
- package/dist/chunk-D4CQZL46.js +76 -0
- package/dist/chunk-D55SXO3N.js +3951 -0
- package/dist/chunk-DEBLYXA2.js +56 -0
- package/dist/chunk-EDNUE5L3.js +38 -0
- package/dist/chunk-EPDSRI6O.js +284 -0
- package/dist/chunk-ESNHLTLC.js +1073 -0
- package/dist/chunk-EU34R2A3.js +1073 -0
- package/dist/chunk-FICUAZEA.js +128 -0
- package/dist/chunk-FP6U5PSY.js +818 -0
- package/dist/chunk-G4KEDLSM.js +488 -0
- package/dist/chunk-G55UTKFR.js +89 -0
- package/dist/chunk-GIJUXLK5.js +330 -0
- package/dist/chunk-GVSSEGIV.js +348 -0
- package/dist/chunk-GYOOZ725.js +330 -0
- package/dist/chunk-HCULUL4D.js +447 -0
- package/dist/chunk-HDRQKH7R.js +1051 -0
- package/dist/chunk-HHBN7Y7R.js +197 -0
- package/dist/chunk-IODP4JNE.js +551 -0
- package/dist/chunk-IQBXQ7GF.js +1073 -0
- package/dist/chunk-ITF6GEJI.js +2091 -0
- package/dist/chunk-IXHVSWLM.js +58 -0
- package/dist/chunk-IZ6LCET7.js +58 -0
- package/dist/chunk-J3ZFONT4.js +1921 -0
- package/dist/chunk-JEOFG274.js +394 -0
- package/dist/chunk-JH7ISOIJ.js +33 -0
- package/dist/chunk-JVRMAVPN.js +731 -0
- package/dist/chunk-KBYRYSXT.js +3951 -0
- package/dist/chunk-KECNXWD6.js +1051 -0
- package/dist/chunk-KIYCHS35.js +128 -0
- package/dist/chunk-KUP3D6G2.js +1345 -0
- package/dist/chunk-KXS5HHDH.js +54 -0
- package/dist/chunk-LPG3U5UW.js +731 -0
- package/dist/chunk-LVZW4WQY.js +221 -0
- package/dist/chunk-LWOCCDSB.js +240 -0
- package/dist/chunk-M4HRKRSE.js +30 -0
- package/dist/chunk-MPG5DR3K.js +244 -0
- package/dist/chunk-NH6TPXZV.js +13696 -0
- package/dist/chunk-NOG2LVBA.js +159 -0
- package/dist/chunk-NP3CYOEY.js +290 -0
- package/dist/chunk-O5TZI7OZ.js +50 -0
- package/dist/chunk-OVQOKLYA.js +210 -0
- package/dist/chunk-OW26ML36.js +1148 -0
- package/dist/chunk-P2DOIWQG.js +260 -0
- package/dist/chunk-P2QTTEYP.js +3951 -0
- package/dist/chunk-P5IKFL7B.js +85 -0
- package/dist/chunk-PD2LUPHD.js +377 -0
- package/dist/chunk-PF5EFIAH.js +818 -0
- package/dist/chunk-PK3NFO76.js +551 -0
- package/dist/chunk-Q3N4KHLM.js +330 -0
- package/dist/chunk-QHQTMWYH.js +54 -0
- package/dist/chunk-QKMFMJTU.js +171 -0
- package/dist/chunk-QNYOPM2L.js +1921 -0
- package/dist/chunk-R77M74QM.js +13696 -0
- package/dist/chunk-RHZ2CRJU.js +3556 -0
- package/dist/chunk-RLR4LVO5.js +1090 -0
- package/dist/chunk-RMDDSWFH.js +495 -0
- package/dist/chunk-RPLEZ74B.js +95 -0
- package/dist/chunk-RXMVPGH2.js +346 -0
- package/dist/chunk-S2ARWNS6.js +135 -0
- package/dist/chunk-SHPIATX7.js +90 -0
- package/dist/chunk-SPOA7EOD.js +81 -0
- package/dist/chunk-SQUZ3TI2.js +668 -0
- package/dist/chunk-SUGBKORD.js +1148 -0
- package/dist/chunk-T2XD7XL2.js +346 -0
- package/dist/chunk-TAIYLROT.js +127 -0
- package/dist/chunk-TCD4XCBS.js +495 -0
- package/dist/chunk-TK23WXKB.js +128 -0
- package/dist/chunk-TOVXER6J.js +76 -0
- package/dist/chunk-TSBMSHMM.js +163 -0
- package/dist/chunk-U776PBU6.js +488 -0
- package/dist/chunk-UIPAZYP7.js +171 -0
- package/dist/chunk-UTVNIAOF.js +284 -0
- package/dist/chunk-VF6VT4MR.js +70 -0
- package/dist/chunk-VZXLYUKS.js +171 -0
- package/dist/chunk-WIAHPJDS.js +58 -0
- package/dist/chunk-WM5ELLT4.js +54 -0
- package/dist/chunk-WUUSPOCC.js +1921 -0
- package/dist/chunk-WXHAMPK4.js +81 -0
- package/dist/chunk-WXW4GF6M.js +495 -0
- package/dist/chunk-WYNZ23XH.js +262 -0
- package/dist/chunk-WZOQLU2Y.js +127 -0
- package/dist/chunk-X24GBZKR.js +157 -0
- package/dist/chunk-X5FRF5MG.js +13696 -0
- package/dist/chunk-XBPLYFBA.js +204 -0
- package/dist/chunk-XDGKFXFW.js +363 -0
- package/dist/chunk-XIT6ONPY.js +630 -0
- package/dist/{chunk-YGOUKUNX.js → chunk-XLYBSXWS.js} +2 -1
- package/dist/chunk-XNRJ5JHU.js +377 -0
- package/dist/chunk-XREWTPZM.js +123 -0
- package/dist/chunk-XURCA5VD.js +297 -0
- package/dist/chunk-Y55VFZJB.js +50 -0
- package/dist/chunk-YIH2YMWP.js +76 -0
- package/dist/chunk-YZMCCT73.js +97 -0
- package/dist/chunk-ZTP3VV23.js +447 -0
- package/dist/co-activation-JOYR73H2.js +72 -0
- package/dist/co-occurrence-G7RRJ3DB.js +74 -0
- package/dist/core-memory-6KK55Z65.js +110 -0
- package/dist/core-memory-QRS6GBXL.js +110 -0
- package/dist/core-memory-QXMQ5I7S.js +110 -0
- package/dist/crdt-sync-QWK65Z5A.js +33 -0
- package/dist/crm-webhook-BNUS3USD.js +10 -0
- package/dist/crm-webhook-CH5W633Y.js +10 -0
- package/dist/crm-webhook-ZTIRFVAH.js +10 -0
- package/dist/cto-delegation-gate-DNZJGBS7.js +206 -0
- package/dist/cto-delegation-gate-XY3NMGTE.js +206 -0
- package/dist/cto-delegation-gate-YI3LK7VY.js +206 -0
- package/dist/daemon-orchestration-7LVOHYKA.js +135 -0
- package/dist/daemon-orchestration-LS62JMTI.js +135 -0
- package/dist/daemon-orchestration-SDQNWI3K.js +135 -0
- package/dist/db-backup-5ENHDNZI.js +33 -0
- package/dist/dreaming-PGJOCGAM.js +32 -0
- package/dist/dreaming-UNHHGOU3.js +32 -0
- package/dist/dreaming-ZBKE2GFX.js +32 -0
- package/dist/exe-drift-QQJMUQXA.js +68 -0
- package/dist/exe-export-BEZZSQB4.js +73 -0
- package/dist/exe-export-JNSQRIWI.js +73 -0
- package/dist/exe-export-TQGI2VBT.js +73 -0
- package/dist/exe-import-2SR2UP3D.js +76 -0
- package/dist/exe-import-73Q4VLFK.js +76 -0
- package/dist/exe-import-AVGWQZLU.js +76 -0
- package/dist/exe-key-6JHEINOM.js +579 -0
- package/dist/exe-key-RIRPIFK6.js +579 -0
- package/dist/exe-key-WR6QEHYO.js +579 -0
- package/dist/exe-snapshot-NDMDQJOH.js +164 -0
- package/dist/exe-snapshot-PVCBPMPJ.js +164 -0
- package/dist/exe-snapshot-U6K3J6BD.js +164 -0
- package/dist/fast-db-init-22OBOPTN.js +7 -0
- package/dist/fast-db-init-M6ZYYGAL.js +7 -0
- package/dist/fast-db-init-ZHRRYI7M.js +7 -0
- package/dist/gateway/index.js +8 -8
- package/dist/git-staleness-4DGYC3RY.js +110 -0
- package/dist/git-task-sweep-64KSWRUI.js +40 -0
- package/dist/git-task-sweep-CUR7R2ZM.js +40 -0
- package/dist/git-task-sweep-YG3IVGK3.js +40 -0
- package/dist/global-procedures-TYDNKM7V.js +20 -0
- package/dist/graph-auto-extract-I6B5HWTP.js +162 -0
- package/dist/hooks/bug-report-worker.js +11 -11
- package/dist/hooks/codex-stop-task-finalizer.js +11 -11
- package/dist/hooks/commit-complete.js +11 -11
- package/dist/hooks/error-recall.js +6 -6
- package/dist/hooks/exe-heartbeat-hook.js +3 -3
- package/dist/hooks/ingest.js +6 -6
- package/dist/hooks/instructions-loaded.js +4 -4
- package/dist/hooks/manifest.json +19 -19
- package/dist/hooks/notification.js +4 -4
- package/dist/hooks/post-compact.js +10 -10
- package/dist/hooks/post-tool-combined.js +5 -5
- package/dist/hooks/pre-compact.js +11 -11
- package/dist/hooks/pre-tool-use.js +14 -14
- package/dist/hooks/prompt-submit.js +27 -22
- package/dist/hooks/session-end.js +15 -15
- package/dist/hooks/session-start.js +10 -10
- package/dist/hooks/stop.js +14 -14
- package/dist/hooks/subagent-stop.js +10 -10
- package/dist/hooks/summary-worker.js +14 -14
- package/dist/index.js +17 -17
- package/dist/installer-4LP73C3M.js +38 -0
- package/dist/installer-AUVLNS4D.js +296 -0
- package/dist/installer-KCRLQSQH.js +38 -0
- package/dist/installer-KGXYUOIV.js +296 -0
- package/dist/installer-UI6TNJGO.js +342 -0
- package/dist/installer-Z7NPD4PD.js +342 -0
- package/dist/lib/cloud-sync.js +4 -4
- package/dist/lib/consolidation.js +5 -5
- package/dist/lib/database.js +2 -2
- package/dist/lib/db-daemon-client.js +6 -0
- package/dist/lib/db.js +2 -2
- package/dist/lib/employee-templates.js +4 -4
- package/dist/lib/employees.js +2 -2
- package/dist/lib/exe-daemon.js +39 -38
- package/dist/lib/hybrid-search.js +5 -5
- package/dist/lib/identity.js +2 -2
- package/dist/lib/messaging.js +9 -9
- package/dist/lib/reminders.js +3 -3
- package/dist/lib/schedules.js +5 -5
- package/dist/lib/session-registry.js +4 -4
- package/dist/lib/skill-learning.js +4 -4
- package/dist/lib/store.js +4 -4
- package/dist/lib/task-router.js +3 -3
- package/dist/lib/tasks.js +10 -10
- package/dist/lib/tmux-routing.js +8 -8
- package/dist/lib/token-spend.js +3 -3
- package/dist/mcp/register-tools.js +53 -52
- package/dist/mcp/server.js +54 -53
- package/dist/mcp/tools/complete-reminder.js +4 -4
- package/dist/mcp/tools/create-reminder.js +4 -4
- package/dist/mcp/tools/create-task.js +12 -12
- package/dist/mcp/tools/deactivate-behavior.js +5 -5
- package/dist/mcp/tools/list-reminders.js +4 -4
- package/dist/mcp/tools/list-tasks.js +12 -12
- package/dist/mcp/tools/send-message.js +11 -11
- package/dist/mcp/tools/update-task.js +11 -11
- package/dist/mcp-http-config-LN5ITKGS.js +27 -0
- package/dist/mcp-http-config-V43VHNEH.js +27 -0
- package/dist/memory-cards-S36DCEY4.js +174 -0
- package/dist/memory-graph-extractor-66YL4V4B.js +17 -0
- package/dist/memory-poisoning-defense-MXWE6CTY.js +225 -0
- package/dist/memory-reflection-W676LUX5.js +238 -0
- package/dist/notifications-45QSHDFA.js +45 -0
- package/dist/notifications-OFLXZTDZ.js +45 -0
- package/dist/notifications-XAV4V7T5.js +45 -0
- package/dist/orchestration-events-MJLWJ2H2.js +25 -0
- package/dist/orchestrator-7XBMFK7D.js +33 -0
- package/dist/orchestrator-AIAKV5ST.js +33 -0
- package/dist/orchestrator-VK7D6I36.js +33 -0
- package/dist/pipeline-router-DXH5QVUH.js +13 -0
- package/dist/pipeline-router-EV6C5S33.js +13 -0
- package/dist/pipeline-router-MQKRNCTR.js +13 -0
- package/dist/plan-limits-TQMLKZBG.js +26 -0
- package/dist/project-boot-4XTXHDG4.js +299 -0
- package/dist/projection-worker-NAYVNSI4.js +964 -0
- package/dist/reranker-CJW3UYE2.js +19 -0
- package/dist/reranker-KHZI7HQK.js +19 -0
- package/dist/reranker-UPMS3OX7.js +19 -0
- package/dist/reranker-ZN73HWSB.js +19 -0
- package/dist/review-polling-3UEZSPNT.js +124 -0
- package/dist/review-polling-KBDX3ILL.js +124 -0
- package/dist/review-polling-RL75XLAY.js +124 -0
- package/dist/runtime/index.js +11 -11
- package/dist/session-events-2CHOLA6D.js +36 -0
- package/dist/session-events-HM22KEHN.js +36 -0
- package/dist/session-events-ZULAN4XL.js +36 -0
- package/dist/session-kill-telemetry-LUPVYGZX.js +29 -0
- package/dist/session-scope-EPZZZHHJ.js +86 -0
- package/dist/session-scope-V2RSOTDU.js +86 -0
- package/dist/session-scope-ZGE6GHMS.js +86 -0
- package/dist/setup-wizard-KNWH54HW.js +12 -0
- package/dist/skill-refinement-BSX6Q6IN.js +157 -0
- package/dist/skill-refinement-C4GNWV4F.js +157 -0
- package/dist/skill-refinement-CAUIE4YM.js +157 -0
- package/dist/steward-gate-MZ2DV36N.js +13 -0
- package/dist/task-enforcement-6OMXG6EA.js +333 -0
- package/dist/task-enforcement-JFSF6QDD.js +333 -0
- package/dist/task-enforcement-JRTAOYZT.js +333 -0
- package/dist/task-scope-4HJSCJ7L.js +35 -0
- package/dist/task-scope-7HYE4AS6.js +35 -0
- package/dist/task-scope-GNCB2GAM.js +35 -0
- package/dist/tasks-crud-JJL6MMJF.js +77 -0
- package/dist/tasks-crud-KMIPDHBZ.js +77 -0
- package/dist/tasks-crud-MZIOYF3R.js +77 -0
- package/dist/tasks-notify-5D6LF52K.js +38 -0
- package/dist/tasks-notify-7KNZ4ULO.js +38 -0
- package/dist/tasks-notify-JNGGXFUY.js +38 -0
- package/dist/tasks-review-N6I5UC7G.js +47 -0
- package/dist/tasks-review-U5VEV4Y7.js +47 -0
- package/dist/tasks-review-USHAMO5N.js +47 -0
- package/dist/telemetry-upload-BIB5TJA4.js +739 -0
- package/dist/telemetry-upload-BV2M2NND.js +739 -0
- package/dist/telemetry-upload-Y7QPDJW4.js +739 -0
- package/dist/token-budget-2LUZOFO7.js +84 -0
- package/dist/tool-telemetry-5JT6DPVK.js +17 -0
- package/dist/tui/App.js +16 -16
- package/dist/tui-data-DMAKZMGD.js +258 -0
- package/dist/tui-data-X7NI6ZQ3.js +258 -0
- package/dist/tui-data-ZSB5DDEY.js +258 -0
- package/dist/wiki-acl-QHGGWX63.js +111 -0
- package/dist/worker-gate-4XKUOFWO.js +21 -0
- package/dist/worker-gate-TPZBOXOA.js +21 -0
- package/dist/worker-gate-TXLX33PX.js +21 -0
- package/dist/workflow-engine-3PIT3Y56.js +28 -0
- package/dist/workflow-engine-F3URLOPA.js +28 -0
- package/dist/workflow-engine-OFOL446Z.js +28 -0
- package/dist/worktree-V3NVP7MV.js +26 -0
- package/dist/worktree-sweep-2CADL43Y.js +19 -0
- package/package.json +1 -1
- package/release-notes.json +27 -25
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
import {
|
|
2
|
+
vectorToBlob
|
|
3
|
+
} from "./chunk-PF5EFIAH.js";
|
|
4
|
+
import {
|
|
5
|
+
extractKeywords,
|
|
6
|
+
keywordsToString
|
|
7
|
+
} from "./chunk-CHCA3ZM2.js";
|
|
8
|
+
import {
|
|
9
|
+
isCoordinatorName
|
|
10
|
+
} from "./chunk-RHZ2CRJU.js";
|
|
11
|
+
|
|
12
|
+
// src/lib/consolidation.ts
|
|
13
|
+
import { randomUUID } from "crypto";
|
|
14
|
+
async function selectUnconsolidated(client, limit = 200) {
|
|
15
|
+
const result = await client.execute({
|
|
16
|
+
sql: `SELECT id, agent_id, project_name, tool_name, raw_text, timestamp, memory_type, session_scope
|
|
17
|
+
FROM memories
|
|
18
|
+
WHERE consolidated = 0
|
|
19
|
+
AND COALESCE(memory_type, 'raw') != 'procedure'
|
|
20
|
+
ORDER BY timestamp DESC
|
|
21
|
+
LIMIT ?`,
|
|
22
|
+
args: [limit]
|
|
23
|
+
});
|
|
24
|
+
return result.rows.map((row) => ({
|
|
25
|
+
id: row.id,
|
|
26
|
+
agent_id: row.agent_id,
|
|
27
|
+
project_name: row.project_name,
|
|
28
|
+
tool_name: row.tool_name,
|
|
29
|
+
raw_text: row.raw_text,
|
|
30
|
+
timestamp: row.timestamp,
|
|
31
|
+
memory_type: row.memory_type ?? null,
|
|
32
|
+
session_scope: row.session_scope ?? null
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
function dominantMemoryType(memories) {
|
|
36
|
+
const counts = /* @__PURE__ */ new Map();
|
|
37
|
+
for (const m of memories) {
|
|
38
|
+
const type = m.memory_type ?? "raw";
|
|
39
|
+
counts.set(type, (counts.get(type) ?? 0) + 1);
|
|
40
|
+
}
|
|
41
|
+
let best = "observation";
|
|
42
|
+
let bestCount = 0;
|
|
43
|
+
for (const [type, count] of counts) {
|
|
44
|
+
if (count > bestCount || count === bestCount && type !== "raw") {
|
|
45
|
+
best = type;
|
|
46
|
+
bestCount = count;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return best;
|
|
50
|
+
}
|
|
51
|
+
function groupMemories(memories) {
|
|
52
|
+
const byProject = /* @__PURE__ */ new Map();
|
|
53
|
+
for (const mem of memories) {
|
|
54
|
+
const key = `${mem.agent_id}::${mem.project_name}`;
|
|
55
|
+
const list = byProject.get(key) ?? [];
|
|
56
|
+
list.push(mem);
|
|
57
|
+
byProject.set(key, list);
|
|
58
|
+
}
|
|
59
|
+
const clusters = [];
|
|
60
|
+
for (const [key, projectMemories] of byProject) {
|
|
61
|
+
const [agentId, projectName] = key.split("::");
|
|
62
|
+
const byDay = /* @__PURE__ */ new Map();
|
|
63
|
+
for (const mem of projectMemories) {
|
|
64
|
+
const day = mem.timestamp.slice(0, 10);
|
|
65
|
+
const list = byDay.get(day) ?? [];
|
|
66
|
+
list.push(mem);
|
|
67
|
+
byDay.set(day, list);
|
|
68
|
+
}
|
|
69
|
+
for (const [day, dayMemories] of byDay) {
|
|
70
|
+
if (dayMemories.length < 3) continue;
|
|
71
|
+
if (dayMemories.length <= 15) {
|
|
72
|
+
clusters.push({
|
|
73
|
+
agentId,
|
|
74
|
+
projectName,
|
|
75
|
+
dateRange: day,
|
|
76
|
+
memories: dayMemories
|
|
77
|
+
});
|
|
78
|
+
} else {
|
|
79
|
+
for (let i = 0; i < dayMemories.length; i += 12) {
|
|
80
|
+
const chunk = dayMemories.slice(i, i + 12);
|
|
81
|
+
clusters.push({
|
|
82
|
+
agentId,
|
|
83
|
+
projectName,
|
|
84
|
+
dateRange: day,
|
|
85
|
+
memories: chunk
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return clusters;
|
|
92
|
+
}
|
|
93
|
+
var ROLE_PROMPTS = {
|
|
94
|
+
"COO": `Extract EXACTLY THREE types of insights:
|
|
95
|
+
1. KEY DECISIONS \u2014 choices that were made and why (at most 3)
|
|
96
|
+
2. RECURRING PATTERNS \u2014 actions or approaches that repeated (at most 3)
|
|
97
|
+
3. OPEN QUESTIONS \u2014 things that seem unresolved or risky (at most 2)`,
|
|
98
|
+
"CTO": `Extract EXACTLY THREE types of insights:
|
|
99
|
+
1. ARCHITECTURE DECISIONS \u2014 design choices, tradeoffs, delegation patterns (at most 3)
|
|
100
|
+
2. REVIEW OUTCOMES \u2014 what was approved, rejected, or flagged during code review (at most 3)
|
|
101
|
+
3. TECHNICAL DEBT \u2014 unresolved issues, deferred work, risks identified (at most 2)`,
|
|
102
|
+
"Principal Engineer": `Extract EXACTLY THREE types of insights:
|
|
103
|
+
1. CODE DECISIONS \u2014 implementation choices, patterns used, bugs fixed (at most 3)
|
|
104
|
+
2. FILE CHANGES \u2014 key files modified and why (at most 3)
|
|
105
|
+
3. BLOCKERS \u2014 things that slowed down or prevented progress (at most 2)`,
|
|
106
|
+
"Staff Code Reviewer": `Extract EXACTLY THREE types of insights:
|
|
107
|
+
1. AUDIT FINDINGS \u2014 issues found, severity, fix status (at most 3)
|
|
108
|
+
2. RECURRING ISSUES \u2014 patterns that keep appearing across reviews (at most 3)
|
|
109
|
+
3. QUALITY SIGNALS \u2014 areas of the codebase that are strong or weak (at most 2)`,
|
|
110
|
+
"CMO": `Extract EXACTLY THREE types of insights:
|
|
111
|
+
1. DESIGN DECISIONS \u2014 brand, layout, typography, or content choices made (at most 3)
|
|
112
|
+
2. CONTENT STRATEGY \u2014 messaging, SEO, platform-specific decisions (at most 3)
|
|
113
|
+
3. BRAND ALIGNMENT \u2014 consistency issues or guidelines established (at most 2)`,
|
|
114
|
+
"AI Product Lead": `Extract EXACTLY THREE types of insights:
|
|
115
|
+
1. RESEARCH FINDINGS \u2014 tools, repos, or models evaluated with conclusions (at most 3)
|
|
116
|
+
2. COMPETITIVE GAPS \u2014 features or patterns worth adopting from competitors (at most 3)
|
|
117
|
+
3. BUILD RECOMMENDATIONS \u2014 what to build, skip, or watch (at most 2)`
|
|
118
|
+
};
|
|
119
|
+
var DEFAULT_ROLE_PROMPT = `Extract EXACTLY THREE types of insights:
|
|
120
|
+
1. KEY DECISIONS \u2014 choices that were made and why (at most 3)
|
|
121
|
+
2. RECURRING PATTERNS \u2014 actions or approaches that repeated (at most 3)
|
|
122
|
+
3. OPEN QUESTIONS \u2014 things that seem unresolved or risky (at most 2)`;
|
|
123
|
+
function buildConsolidationPrompt(cluster, agentRole) {
|
|
124
|
+
const snippets = cluster.memories.map((m, i) => {
|
|
125
|
+
return `${i + 1}. [${m.tool_name}] ${m.raw_text}`;
|
|
126
|
+
}).join("\n");
|
|
127
|
+
const rolePrompt = agentRole && ROLE_PROMPTS[agentRole] || DEFAULT_ROLE_PROMPT;
|
|
128
|
+
return `You are reviewing a set of work memories from an AI coding agent.
|
|
129
|
+
These are raw tool call records from ${cluster.dateRange}.
|
|
130
|
+
|
|
131
|
+
Agent: ${cluster.agentId} | Project: ${cluster.projectName} | Date: ${cluster.dateRange}
|
|
132
|
+
|
|
133
|
+
MEMORIES:
|
|
134
|
+
${snippets}
|
|
135
|
+
|
|
136
|
+
${rolePrompt}
|
|
137
|
+
|
|
138
|
+
IMPORTANT: Preserve all specific names, file paths, technical terms, and proper nouns exactly as they appear. Front-load the most important terms in the first sentence of your summary. Never replace specific terms with generic descriptions (e.g. write "hybrid-search.ts" not "the search file", write "extractKeywords" not "the extraction function").
|
|
139
|
+
|
|
140
|
+
Format each as a single sentence. Be specific \u2014 include file names,
|
|
141
|
+
function names, and concrete details. Skip if no insight for a category.`;
|
|
142
|
+
}
|
|
143
|
+
async function consolidateCluster(cluster, model, agentRole) {
|
|
144
|
+
const Anthropic = (await import("@anthropic-ai/sdk")).default;
|
|
145
|
+
const client = new Anthropic();
|
|
146
|
+
const prompt = buildConsolidationPrompt(cluster, agentRole);
|
|
147
|
+
const response = await client.messages.create({
|
|
148
|
+
model,
|
|
149
|
+
max_tokens: 300,
|
|
150
|
+
messages: [{ role: "user", content: prompt }]
|
|
151
|
+
});
|
|
152
|
+
const textBlock = response.content.find((b) => b.type === "text");
|
|
153
|
+
return textBlock?.text ?? "";
|
|
154
|
+
}
|
|
155
|
+
async function storeConsolidation(client, cluster, synthesisText, embedFn) {
|
|
156
|
+
const consolidatedId = randomUUID();
|
|
157
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
158
|
+
const rawText = `CONSOLIDATION [${cluster.dateRange}, ${cluster.projectName}]:
|
|
159
|
+
|
|
160
|
+
${synthesisText}`;
|
|
161
|
+
let vector = null;
|
|
162
|
+
if (embedFn) {
|
|
163
|
+
try {
|
|
164
|
+
vector = await embedFn(rawText);
|
|
165
|
+
} catch {
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const memoryType = dominantMemoryType(cluster.memories);
|
|
169
|
+
const scopes = new Set(cluster.memories.map((m) => m.session_scope ?? null));
|
|
170
|
+
const sessionScope = scopes.size === 1 ? cluster.memories[0]?.session_scope ?? null : null;
|
|
171
|
+
const keywords = keywordsToString(extractKeywords(rawText));
|
|
172
|
+
const insertSql = vector ? `INSERT INTO memories
|
|
173
|
+
(id, agent_id, agent_role, session_id, timestamp,
|
|
174
|
+
tool_name, project_name, has_error, raw_text, vector, version, consolidated, importance, memory_type, session_scope, keywords)
|
|
175
|
+
VALUES (?, ?, 'consolidation', 'daemon-consolidation', ?, 'consolidation', ?, 0, ?, vector32(?), 0, 1, 9, ?, ?, ?)` : `INSERT INTO memories
|
|
176
|
+
(id, agent_id, agent_role, session_id, timestamp,
|
|
177
|
+
tool_name, project_name, has_error, raw_text, vector, version, consolidated, importance, memory_type, session_scope, keywords)
|
|
178
|
+
VALUES (?, ?, 'consolidation', 'daemon-consolidation', ?, 'consolidation', ?, 0, ?, NULL, 0, 1, 9, ?, ?, ?)`;
|
|
179
|
+
const insertArgs = vector ? [consolidatedId, cluster.agentId, now, cluster.projectName, rawText, vectorToBlob(vector), memoryType, sessionScope, keywords] : [consolidatedId, cluster.agentId, now, cluster.projectName, rawText, memoryType, sessionScope, keywords];
|
|
180
|
+
await client.execute({ sql: insertSql, args: insertArgs });
|
|
181
|
+
const sourceIds = cluster.memories.map((m) => m.id);
|
|
182
|
+
const linkStmts = sourceIds.map((sourceId) => ({
|
|
183
|
+
sql: `INSERT INTO consolidations (id, consolidated_memory_id, source_memory_id, created_at)
|
|
184
|
+
VALUES (?, ?, ?, ?)`,
|
|
185
|
+
args: [randomUUID(), consolidatedId, sourceId, now]
|
|
186
|
+
}));
|
|
187
|
+
const placeholders = sourceIds.map(() => "?").join(",");
|
|
188
|
+
const markStmt = {
|
|
189
|
+
sql: `UPDATE memories SET consolidated = 1, status = 'archived' WHERE id IN (${placeholders})`,
|
|
190
|
+
args: sourceIds
|
|
191
|
+
};
|
|
192
|
+
await client.batch([...linkStmts, markStmt], "write");
|
|
193
|
+
return { consolidatedMemoryId: consolidatedId, sourceIds, rawText };
|
|
194
|
+
}
|
|
195
|
+
var WIKI_FETCH_TIMEOUT_MS = 1e4;
|
|
196
|
+
async function pushToWiki(consolidation, config) {
|
|
197
|
+
if (!config.wikiEnabled || !config.wikiAutoUpdate) {
|
|
198
|
+
return { updated: false };
|
|
199
|
+
}
|
|
200
|
+
const apiUrl = config.wikiUrl || process.env.EXE_WIKI_API_URL;
|
|
201
|
+
const apiKey = config.wikiApiKey || process.env.EXE_WIKI_API_KEY;
|
|
202
|
+
if (!apiUrl || !apiKey) {
|
|
203
|
+
return { updated: false };
|
|
204
|
+
}
|
|
205
|
+
const workspace = config.wikiWorkspaceMapping[consolidation.projectName] ?? consolidation.projectName;
|
|
206
|
+
try {
|
|
207
|
+
const listRes = await fetch(
|
|
208
|
+
`${apiUrl}/v1/workspace/${encodeURIComponent(workspace)}/documents`,
|
|
209
|
+
{
|
|
210
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
211
|
+
signal: AbortSignal.timeout(WIKI_FETCH_TIMEOUT_MS)
|
|
212
|
+
}
|
|
213
|
+
);
|
|
214
|
+
if (!listRes.ok) {
|
|
215
|
+
return { updated: false, error: `Workspace "${workspace}" not accessible (${listRes.status})` };
|
|
216
|
+
}
|
|
217
|
+
const listJson = await listRes.json();
|
|
218
|
+
const docs = listJson.documents ?? listJson.localFiles?.items ?? [];
|
|
219
|
+
const contentLines = consolidation.rawText.split("\n").filter((l) => l.trim() && !l.startsWith("CONSOLIDATION") && !l.match(/^[A-Z\s]+:$/)).join(" ");
|
|
220
|
+
const keywords = contentLines.toLowerCase().replace(/[^a-z0-9\s]/g, "").split(/\s+/).filter((w) => w.length > 3);
|
|
221
|
+
let bestMatch = null;
|
|
222
|
+
for (const doc of docs) {
|
|
223
|
+
if (!doc.id || !doc.title) continue;
|
|
224
|
+
const titleWords = doc.title.toLowerCase().replace(/[^a-z0-9\s]/g, "").split(/\s+/).filter((w) => w.length > 3);
|
|
225
|
+
if (titleWords.length === 0) continue;
|
|
226
|
+
const matchCount = titleWords.filter(
|
|
227
|
+
(tw) => keywords.some((k) => k.includes(tw) || tw.includes(k))
|
|
228
|
+
).length;
|
|
229
|
+
const score = matchCount / titleWords.length;
|
|
230
|
+
if (score > (bestMatch?.score ?? 0)) {
|
|
231
|
+
bestMatch = { id: doc.id, title: doc.title, score };
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (bestMatch && bestMatch.score >= config.wikiAutoUpdateThreshold) {
|
|
235
|
+
const updateRes = await fetch(`${apiUrl}/v1/document/raw-text`, {
|
|
236
|
+
method: "POST",
|
|
237
|
+
headers: {
|
|
238
|
+
"Content-Type": "application/json",
|
|
239
|
+
Authorization: `Bearer ${apiKey}`
|
|
240
|
+
},
|
|
241
|
+
body: JSON.stringify({
|
|
242
|
+
textContent: consolidation.rawText,
|
|
243
|
+
metadata: { title: bestMatch.title, appendTo: bestMatch.id },
|
|
244
|
+
workspaceSlugs: [workspace]
|
|
245
|
+
}),
|
|
246
|
+
signal: AbortSignal.timeout(WIKI_FETCH_TIMEOUT_MS)
|
|
247
|
+
});
|
|
248
|
+
if (updateRes.ok) {
|
|
249
|
+
process.stderr.write(
|
|
250
|
+
`[consolidation] Wiki auto-updated: ${workspace}/${bestMatch.title}
|
|
251
|
+
`
|
|
252
|
+
);
|
|
253
|
+
return { updated: true, action: "updated", page: bestMatch.title };
|
|
254
|
+
}
|
|
255
|
+
return { updated: false, error: `Update failed (${updateRes.status})` };
|
|
256
|
+
}
|
|
257
|
+
if (config.wikiAutoUpdateCreateNew) {
|
|
258
|
+
const title = `Consolidated Insights \u2014 ${consolidation.projectName} (${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)})`;
|
|
259
|
+
const createRes = await fetch(`${apiUrl}/v1/document/raw-text`, {
|
|
260
|
+
method: "POST",
|
|
261
|
+
headers: {
|
|
262
|
+
"Content-Type": "application/json",
|
|
263
|
+
Authorization: `Bearer ${apiKey}`
|
|
264
|
+
},
|
|
265
|
+
body: JSON.stringify({
|
|
266
|
+
textContent: consolidation.rawText,
|
|
267
|
+
metadata: { title },
|
|
268
|
+
workspaceSlugs: [workspace]
|
|
269
|
+
}),
|
|
270
|
+
signal: AbortSignal.timeout(WIKI_FETCH_TIMEOUT_MS)
|
|
271
|
+
});
|
|
272
|
+
if (createRes.ok) {
|
|
273
|
+
process.stderr.write(
|
|
274
|
+
`[consolidation] Wiki page created: ${workspace}/${title}
|
|
275
|
+
`
|
|
276
|
+
);
|
|
277
|
+
return { updated: true, action: "created", page: title };
|
|
278
|
+
}
|
|
279
|
+
return { updated: false, error: `Create failed (${createRes.status})` };
|
|
280
|
+
}
|
|
281
|
+
return { updated: false };
|
|
282
|
+
} catch (err) {
|
|
283
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
284
|
+
process.stderr.write(`[consolidation] Wiki push failed: ${msg}
|
|
285
|
+
`);
|
|
286
|
+
return { updated: false, error: msg };
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
async function runConsolidation(client, options) {
|
|
290
|
+
const memories = await selectUnconsolidated(client);
|
|
291
|
+
if (memories.length < 20) {
|
|
292
|
+
return { clustersProcessed: 0, memoriesConsolidated: 0 };
|
|
293
|
+
}
|
|
294
|
+
const roleMap = {};
|
|
295
|
+
try {
|
|
296
|
+
const { loadEmployeesSync } = await import("./lib/employees.js");
|
|
297
|
+
const employees = loadEmployeesSync();
|
|
298
|
+
for (const e of employees) {
|
|
299
|
+
roleMap[e.name] = e.role;
|
|
300
|
+
}
|
|
301
|
+
} catch {
|
|
302
|
+
}
|
|
303
|
+
const clusters = groupMemories(memories);
|
|
304
|
+
let clustersProcessed = 0;
|
|
305
|
+
let memoriesConsolidated = 0;
|
|
306
|
+
for (const cluster of clusters) {
|
|
307
|
+
if (clustersProcessed >= options.maxCalls) break;
|
|
308
|
+
if (cluster.memories.length < 3) continue;
|
|
309
|
+
try {
|
|
310
|
+
const isCoordinator = isCoordinatorName(cluster.agentId);
|
|
311
|
+
const agentRole = roleMap[cluster.agentId];
|
|
312
|
+
const dedupCount = await dedupCluster(client, cluster, options.embedFn);
|
|
313
|
+
memoriesConsolidated += dedupCount;
|
|
314
|
+
const synthesis = await consolidateCluster(cluster, options.model, agentRole);
|
|
315
|
+
if (!synthesis.trim()) {
|
|
316
|
+
if (dedupCount > 0) clustersProcessed++;
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
const result = await storeConsolidation(client, cluster, synthesis, options.embedFn);
|
|
320
|
+
if (isCoordinator && options.wikiConfig) {
|
|
321
|
+
await pushToWiki(
|
|
322
|
+
{ ...result, projectName: cluster.projectName },
|
|
323
|
+
options.wikiConfig
|
|
324
|
+
).catch((err) => {
|
|
325
|
+
process.stderr.write(
|
|
326
|
+
`[consolidation] Wiki push error (non-fatal): ${err instanceof Error ? err.message : String(err)}
|
|
327
|
+
`
|
|
328
|
+
);
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
if (isCoordinator) {
|
|
332
|
+
const sourceIds = result.sourceIds;
|
|
333
|
+
if (sourceIds.length > 0) {
|
|
334
|
+
const placeholders = sourceIds.map(() => "?").join(",");
|
|
335
|
+
await client.execute({
|
|
336
|
+
sql: `UPDATE memories SET status = 'archived' WHERE id IN (${placeholders})`,
|
|
337
|
+
args: sourceIds
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
clustersProcessed++;
|
|
342
|
+
memoriesConsolidated += cluster.memories.length;
|
|
343
|
+
} catch (err) {
|
|
344
|
+
process.stderr.write(
|
|
345
|
+
`[consolidation] Cluster failed (${cluster.projectName}/${cluster.dateRange}): ${err instanceof Error ? err.message : String(err)}
|
|
346
|
+
`
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return { clustersProcessed, memoriesConsolidated };
|
|
351
|
+
}
|
|
352
|
+
async function dedupCluster(client, cluster, embedFn) {
|
|
353
|
+
if (!embedFn || cluster.memories.length < 2) return 0;
|
|
354
|
+
const vectors = [];
|
|
355
|
+
for (const mem of cluster.memories) {
|
|
356
|
+
try {
|
|
357
|
+
const v = await embedFn(mem.raw_text);
|
|
358
|
+
vectors.push({ id: mem.id, vector: v });
|
|
359
|
+
} catch {
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (vectors.length < 2) return 0;
|
|
363
|
+
const toArchive = /* @__PURE__ */ new Set();
|
|
364
|
+
for (let i = 0; i < vectors.length; i++) {
|
|
365
|
+
if (toArchive.has(vectors[i].id)) continue;
|
|
366
|
+
for (let j = i + 1; j < vectors.length; j++) {
|
|
367
|
+
if (toArchive.has(vectors[j].id)) continue;
|
|
368
|
+
const sim = cosineSimilarity(vectors[i].vector, vectors[j].vector);
|
|
369
|
+
if (sim > 0.95) {
|
|
370
|
+
toArchive.add(vectors[j].id);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
if (toArchive.size === 0) return 0;
|
|
375
|
+
const ids = [...toArchive];
|
|
376
|
+
const placeholders = ids.map(() => "?").join(",");
|
|
377
|
+
await client.execute({
|
|
378
|
+
sql: `UPDATE memories SET status = 'archived', consolidated = 1 WHERE id IN (${placeholders})`,
|
|
379
|
+
args: ids
|
|
380
|
+
});
|
|
381
|
+
const survivors = vectors.filter((v) => !toArchive.has(v.id)).map((v) => v.id);
|
|
382
|
+
if (survivors.length > 0) {
|
|
383
|
+
const survivorPlaceholders = survivors.map(() => "?").join(",");
|
|
384
|
+
await client.execute({
|
|
385
|
+
sql: `UPDATE memories SET confidence = MIN(1.0, COALESCE(confidence, 0.7) + 0.1) WHERE id IN (${survivorPlaceholders})`,
|
|
386
|
+
args: survivors
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
return ids.length;
|
|
390
|
+
}
|
|
391
|
+
function cosineSimilarity(a, b) {
|
|
392
|
+
let dot = 0, normA = 0, normB = 0;
|
|
393
|
+
for (let i = 0; i < a.length; i++) {
|
|
394
|
+
dot += a[i] * b[i];
|
|
395
|
+
normA += a[i] * a[i];
|
|
396
|
+
normB += b[i] * b[i];
|
|
397
|
+
}
|
|
398
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
399
|
+
return denom === 0 ? 0 : dot / denom;
|
|
400
|
+
}
|
|
401
|
+
async function isUserIdle(client, idleMinutes = 30) {
|
|
402
|
+
const result = await client.execute({
|
|
403
|
+
sql: `SELECT MAX(timestamp) as last_activity
|
|
404
|
+
FROM memories
|
|
405
|
+
WHERE tool_name != 'consolidation'
|
|
406
|
+
AND timestamp >= datetime('now', '-1 day')`,
|
|
407
|
+
args: []
|
|
408
|
+
});
|
|
409
|
+
const lastActivity = result.rows[0]?.last_activity;
|
|
410
|
+
if (!lastActivity) return true;
|
|
411
|
+
const lastMs = new Date(lastActivity).getTime();
|
|
412
|
+
const now = Date.now();
|
|
413
|
+
return now - lastMs >= idleMinutes * 60 * 1e3;
|
|
414
|
+
}
|
|
415
|
+
async function countUnconsolidated(client) {
|
|
416
|
+
const result = await client.execute({
|
|
417
|
+
sql: `SELECT COUNT(*) as cnt FROM memories
|
|
418
|
+
WHERE consolidated = 0
|
|
419
|
+
AND COALESCE(memory_type, 'raw') != 'procedure'`,
|
|
420
|
+
args: []
|
|
421
|
+
});
|
|
422
|
+
return Number(result.rows[0]?.cnt ?? 0);
|
|
423
|
+
}
|
|
424
|
+
var INTERCOM_NOISE_PATTERNS = [
|
|
425
|
+
/^\/exe-intercom\b/i,
|
|
426
|
+
/^You have pending notifications\.\s*Run list_tasks/i,
|
|
427
|
+
/^You have open tasks\.\s*Run list_tasks/i,
|
|
428
|
+
/^You have a new P\d+ task/i,
|
|
429
|
+
/^You have more open tasks to dispatch/i,
|
|
430
|
+
/^No new tasks\.\s*(Standing by|Idle|Dashboard)/i,
|
|
431
|
+
/^You have pending tasks\.\s*Start your/i
|
|
432
|
+
];
|
|
433
|
+
async function deduplicateIntercomMemories(client) {
|
|
434
|
+
const noiseResult = await client.execute({
|
|
435
|
+
sql: `SELECT id, raw_text FROM memories
|
|
436
|
+
WHERE COALESCE(status, 'active') = 'active'
|
|
437
|
+
AND (
|
|
438
|
+
raw_text LIKE '/exe-intercom%'
|
|
439
|
+
OR raw_text LIKE 'You have pending notifications.%'
|
|
440
|
+
OR raw_text LIKE 'You have open tasks.%'
|
|
441
|
+
OR raw_text LIKE 'You have a new P_ task%'
|
|
442
|
+
OR raw_text LIKE 'You have more open tasks to dispatch%'
|
|
443
|
+
OR raw_text LIKE 'No new tasks.%'
|
|
444
|
+
OR raw_text LIKE 'You have pending tasks.%'
|
|
445
|
+
)`,
|
|
446
|
+
args: []
|
|
447
|
+
});
|
|
448
|
+
const toArchive = [];
|
|
449
|
+
for (const row of noiseResult.rows) {
|
|
450
|
+
const text = row.raw_text.trim();
|
|
451
|
+
if (INTERCOM_NOISE_PATTERNS.some((p) => p.test(text))) {
|
|
452
|
+
toArchive.push(row.id);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
if (toArchive.length === 0) return 0;
|
|
456
|
+
const BATCH = 500;
|
|
457
|
+
for (let i = 0; i < toArchive.length; i += BATCH) {
|
|
458
|
+
const batch = toArchive.slice(i, i + BATCH);
|
|
459
|
+
const placeholders = batch.map(() => "?").join(",");
|
|
460
|
+
await client.execute({
|
|
461
|
+
sql: `UPDATE memories SET status = 'archived'
|
|
462
|
+
WHERE id IN (${placeholders})
|
|
463
|
+
AND COALESCE(status, 'active') = 'active'`,
|
|
464
|
+
args: batch
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
return toArchive.length;
|
|
468
|
+
}
|
|
469
|
+
var TRACE_TOOLS = ["Bash", "Read", "Edit", "Grep", "Write", "Glob", "apply_patch"];
|
|
470
|
+
async function sweepExpiredTraces(client) {
|
|
471
|
+
const placeholders = TRACE_TOOLS.map(() => "?").join(",");
|
|
472
|
+
const result = await client.execute({
|
|
473
|
+
sql: `DELETE FROM memories
|
|
474
|
+
WHERE tool_name IN (${placeholders})
|
|
475
|
+
AND COALESCE(memory_type, 'raw') = 'raw'
|
|
476
|
+
AND timestamp < datetime('now', '-7 days')
|
|
477
|
+
AND COALESCE(importance, 0) < 7`,
|
|
478
|
+
args: TRACE_TOOLS
|
|
479
|
+
});
|
|
480
|
+
return result.rowsAffected;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export {
|
|
484
|
+
selectUnconsolidated,
|
|
485
|
+
groupMemories,
|
|
486
|
+
buildConsolidationPrompt,
|
|
487
|
+
consolidateCluster,
|
|
488
|
+
storeConsolidation,
|
|
489
|
+
pushToWiki,
|
|
490
|
+
runConsolidation,
|
|
491
|
+
isUserIdle,
|
|
492
|
+
countUnconsolidated,
|
|
493
|
+
deduplicateIntercomMemories,
|
|
494
|
+
sweepExpiredTraces
|
|
495
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getCurrentSessionScope,
|
|
3
|
+
strictSessionScopeFilter
|
|
4
|
+
} from "./chunk-D55SXO3N.js";
|
|
5
|
+
import {
|
|
6
|
+
getProjectName
|
|
7
|
+
} from "./chunk-OPU3NYOO.js";
|
|
8
|
+
|
|
9
|
+
// src/lib/session-events.ts
|
|
10
|
+
import { randomUUID } from "crypto";
|
|
11
|
+
async function ensureSessionEventsTable(client) {
|
|
12
|
+
await client.execute(`
|
|
13
|
+
CREATE TABLE IF NOT EXISTS session_events (
|
|
14
|
+
id TEXT PRIMARY KEY,
|
|
15
|
+
agent_id TEXT NOT NULL,
|
|
16
|
+
agent_role TEXT NOT NULL,
|
|
17
|
+
session_id TEXT NOT NULL,
|
|
18
|
+
session_scope TEXT,
|
|
19
|
+
project_name TEXT NOT NULL,
|
|
20
|
+
event_index INTEGER NOT NULL,
|
|
21
|
+
event_type TEXT NOT NULL,
|
|
22
|
+
tool_name TEXT,
|
|
23
|
+
tool_use_id TEXT,
|
|
24
|
+
content TEXT NOT NULL,
|
|
25
|
+
payload_json TEXT,
|
|
26
|
+
has_error INTEGER NOT NULL DEFAULT 0,
|
|
27
|
+
created_at TEXT NOT NULL
|
|
28
|
+
)
|
|
29
|
+
`);
|
|
30
|
+
await client.execute(`
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
|
|
32
|
+
ON session_events(agent_id, created_at DESC)
|
|
33
|
+
`);
|
|
34
|
+
await client.execute(`
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_session_index
|
|
36
|
+
ON session_events(session_id, event_index)
|
|
37
|
+
`);
|
|
38
|
+
await client.execute(`
|
|
39
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
|
|
40
|
+
ON session_events(session_scope, agent_id, created_at DESC)
|
|
41
|
+
`);
|
|
42
|
+
}
|
|
43
|
+
async function recordSessionEvent(client, input) {
|
|
44
|
+
if (!input.content || input.content.trim().length === 0) return;
|
|
45
|
+
await ensureSessionEventsTable(client);
|
|
46
|
+
const maxResult = await client.execute({
|
|
47
|
+
sql: "SELECT COALESCE(MAX(event_index), 0) AS max_index FROM session_events WHERE session_id = ?",
|
|
48
|
+
args: [input.sessionId]
|
|
49
|
+
});
|
|
50
|
+
const currentMax = Number(maxResult.rows[0]?.max_index ?? 0);
|
|
51
|
+
const eventIndex = Number.isFinite(currentMax) ? currentMax + 1 : 1;
|
|
52
|
+
await client.execute({
|
|
53
|
+
sql: `INSERT INTO session_events (
|
|
54
|
+
id, agent_id, agent_role, session_id, session_scope, project_name,
|
|
55
|
+
event_index, event_type, tool_name, tool_use_id, content,
|
|
56
|
+
payload_json, has_error, created_at
|
|
57
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
58
|
+
args: [
|
|
59
|
+
randomUUID(),
|
|
60
|
+
input.agentId,
|
|
61
|
+
input.agentRole,
|
|
62
|
+
input.sessionId,
|
|
63
|
+
input.sessionScope ?? getCurrentSessionScope(),
|
|
64
|
+
input.projectName ?? getProjectName(input.cwd),
|
|
65
|
+
eventIndex,
|
|
66
|
+
input.eventType,
|
|
67
|
+
input.toolName ?? null,
|
|
68
|
+
input.toolUseId ?? null,
|
|
69
|
+
input.content,
|
|
70
|
+
input.payloadJson ?? null,
|
|
71
|
+
input.hasError ? 1 : 0,
|
|
72
|
+
input.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
73
|
+
]
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async function listRecentSessionEvents(client, options) {
|
|
77
|
+
await ensureSessionEventsTable(client);
|
|
78
|
+
const conditions = ["agent_id = ?"];
|
|
79
|
+
const args = [options.agentId];
|
|
80
|
+
if (options.sessionId) {
|
|
81
|
+
conditions.push("session_id = ?");
|
|
82
|
+
args.push(options.sessionId);
|
|
83
|
+
}
|
|
84
|
+
if (options.eventType) {
|
|
85
|
+
conditions.push("event_type = ?");
|
|
86
|
+
args.push(options.eventType);
|
|
87
|
+
}
|
|
88
|
+
if (options.projectName && options.projectName !== "all") {
|
|
89
|
+
conditions.push("project_name = ?");
|
|
90
|
+
args.push(options.projectName);
|
|
91
|
+
}
|
|
92
|
+
const scope = strictSessionScopeFilter(options.sessionScope);
|
|
93
|
+
const where = `WHERE ${conditions.join(" AND ")}${scope.sql}`;
|
|
94
|
+
args.push(...scope.args);
|
|
95
|
+
args.push(Math.min(Math.max(options.limit ?? 20, 1), 100));
|
|
96
|
+
const result = await client.execute({
|
|
97
|
+
sql: `SELECT id, agent_id, agent_role, session_id, session_scope,
|
|
98
|
+
project_name, event_index, event_type, tool_name, tool_use_id,
|
|
99
|
+
content, payload_json, has_error, created_at
|
|
100
|
+
FROM session_events
|
|
101
|
+
${where}
|
|
102
|
+
ORDER BY created_at DESC, event_index DESC
|
|
103
|
+
LIMIT ?`,
|
|
104
|
+
args
|
|
105
|
+
});
|
|
106
|
+
return result.rows.map((row) => ({
|
|
107
|
+
id: String(row.id),
|
|
108
|
+
agentId: String(row.agent_id),
|
|
109
|
+
agentRole: String(row.agent_role),
|
|
110
|
+
sessionId: String(row.session_id),
|
|
111
|
+
sessionScope: row.session_scope == null ? null : String(row.session_scope),
|
|
112
|
+
projectName: String(row.project_name),
|
|
113
|
+
eventIndex: Number(row.event_index),
|
|
114
|
+
eventType: String(row.event_type),
|
|
115
|
+
toolName: row.tool_name == null ? null : String(row.tool_name),
|
|
116
|
+
toolUseId: row.tool_use_id == null ? null : String(row.tool_use_id),
|
|
117
|
+
content: String(row.content),
|
|
118
|
+
payloadJson: row.payload_json == null ? null : String(row.payload_json),
|
|
119
|
+
hasError: Number(row.has_error) === 1,
|
|
120
|
+
createdAt: String(row.created_at)
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export {
|
|
125
|
+
ensureSessionEventsTable,
|
|
126
|
+
recordSessionEvent,
|
|
127
|
+
listRecentSessionEvents
|
|
128
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {
|
|
2
|
+
fastDbInit
|
|
3
|
+
} from "./chunk-SPOA7EOD.js";
|
|
4
|
+
import {
|
|
5
|
+
sessionScopeFilter
|
|
6
|
+
} from "./chunk-D55SXO3N.js";
|
|
7
|
+
import {
|
|
8
|
+
formatStatusAll,
|
|
9
|
+
formatStatusDeep,
|
|
10
|
+
getEmployeeStatuses,
|
|
11
|
+
inTmux
|
|
12
|
+
} from "./chunk-CX6GL3ZJ.js";
|
|
13
|
+
import {
|
|
14
|
+
getClient,
|
|
15
|
+
isCoordinatorRole,
|
|
16
|
+
loadEmployees
|
|
17
|
+
} from "./chunk-QQZMP6QL.js";
|
|
18
|
+
import {
|
|
19
|
+
isMainModule
|
|
20
|
+
} from "./chunk-6Y4B3QF6.js";
|
|
21
|
+
|
|
22
|
+
// src/bin/exe-status.ts
|
|
23
|
+
async function status(targetEmployee) {
|
|
24
|
+
if (!inTmux()) {
|
|
25
|
+
return "Not in a tmux session. Start tmux first: tmux new-session -s work";
|
|
26
|
+
}
|
|
27
|
+
const employees = await loadEmployees();
|
|
28
|
+
const names = employees.filter((e) => !isCoordinatorRole(e.role)).map((e) => e.name);
|
|
29
|
+
const roles = new Map(employees.map((e) => [e.name, e.role ?? ""]));
|
|
30
|
+
await fastDbInit();
|
|
31
|
+
const client = getClient();
|
|
32
|
+
const taskMap = /* @__PURE__ */ new Map();
|
|
33
|
+
try {
|
|
34
|
+
const esScope = sessionScopeFilter();
|
|
35
|
+
const result = await client.execute({
|
|
36
|
+
sql: `SELECT assigned_to, title, priority FROM tasks
|
|
37
|
+
WHERE status = 'in_progress'${esScope.sql}
|
|
38
|
+
ORDER BY priority ASC, created_at ASC`,
|
|
39
|
+
args: [...esScope.args]
|
|
40
|
+
});
|
|
41
|
+
for (const row of result.rows) {
|
|
42
|
+
const assignee = String(row.assigned_to);
|
|
43
|
+
if (!taskMap.has(assignee)) {
|
|
44
|
+
taskMap.set(assignee, {
|
|
45
|
+
title: String(row.title),
|
|
46
|
+
priority: String(row.priority)
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} catch {
|
|
51
|
+
}
|
|
52
|
+
if (targetEmployee) {
|
|
53
|
+
if (!names.includes(targetEmployee)) {
|
|
54
|
+
return `Employee "${targetEmployee}" not found. Available: ${names.join(", ")}`;
|
|
55
|
+
}
|
|
56
|
+
const statuses2 = getEmployeeStatuses([targetEmployee]);
|
|
57
|
+
const s = statuses2[0];
|
|
58
|
+
return formatStatusDeep(s, taskMap.get(targetEmployee), roles.get(targetEmployee) ?? "");
|
|
59
|
+
}
|
|
60
|
+
const statuses = getEmployeeStatuses(names);
|
|
61
|
+
return formatStatusAll(statuses, taskMap, roles);
|
|
62
|
+
}
|
|
63
|
+
if (isMainModule(import.meta.url)) {
|
|
64
|
+
const target = process.argv[2];
|
|
65
|
+
status(target).then((output) => {
|
|
66
|
+
process.stdout.write(output + "\n");
|
|
67
|
+
}).catch((err) => {
|
|
68
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}
|
|
69
|
+
`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export {
|
|
75
|
+
status
|
|
76
|
+
};
|