@askexenow/exe-os 0.9.127 → 0.9.129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/active-agent-3FDJYREJ.js +22 -0
- package/dist/active-agent-WC7YK3L5.js +23 -0
- package/dist/agent-context-CDWUZEXY.js +11 -0
- package/dist/agent-loop-G4VUR5ME.js +10 -0
- package/dist/agentic-ontology-2VYNTMNO.js +25 -0
- package/dist/backfill-metadata-OJWOCLSZ.js +601 -0
- package/dist/background-jobs-LGRDXGXC.js +25 -0
- package/dist/bash-Y5PEW5UQ.js +8 -0
- package/dist/behaviors-CSB2YLDT.js +22 -0
- package/dist/bin/age-ontology-load.js +10 -258
- package/dist/bin/agentic-ontology-backfill.js +23 -5296
- package/dist/bin/agentic-reflection-backfill.js +19 -4739
- package/dist/bin/agentic-semantic-label.js +28 -4723
- package/dist/bin/backfill-conversations.js +42 -5543
- package/dist/bin/backfill-responses.js +41 -5542
- package/dist/bin/backfill-vectors.js +43 -4795
- package/dist/bin/bulk-sync-postgres.js +22 -5313
- package/dist/bin/cc-doctor.js +10 -602
- package/dist/bin/cleanup-stale-review-tasks.js +32 -6803
- package/dist/bin/cli.js +169 -38993
- package/dist/bin/exe-agent-config.js +21 -253
- package/dist/bin/exe-agent.js +63 -2429
- package/dist/bin/exe-assign.js +34 -5810
- package/dist/bin/exe-boot.js +180 -12726
- package/dist/bin/exe-call.js +48 -1409
- package/dist/bin/exe-cloud.js +64 -8516
- package/dist/bin/exe-dispatch.js +35 -10818
- package/dist/bin/exe-doctor.js +24 -7537
- package/dist/bin/exe-export-behaviors.js +18 -6122
- package/dist/bin/exe-forget.js +22 -6274
- package/dist/bin/exe-gateway.js +62 -15286
- package/dist/bin/exe-healthcheck.js +9 -602
- package/dist/bin/exe-heartbeat.js +51 -6898
- package/dist/bin/exe-kill.js +30 -5961
- package/dist/bin/exe-launch-agent.js +101 -6788
- package/dist/bin/exe-new-employee.js +42 -3774
- package/dist/bin/exe-pending-messages.js +28 -6833
- package/dist/bin/exe-pending-notifications.js +31 -6869
- package/dist/bin/exe-pending-reviews.js +38 -6910
- package/dist/bin/exe-rename.js +57 -5766
- package/dist/bin/exe-review.js +29 -5948
- package/dist/bin/exe-search.js +22 -7692
- package/dist/bin/exe-session-cleanup.js +52 -11147
- package/dist/bin/exe-settings.js +35 -524
- package/dist/bin/exe-start-codex.js +70 -6641
- package/dist/bin/exe-start-opencode.js +54 -6584
- package/dist/bin/exe-status.js +26 -7081
- package/dist/bin/exe-support.js +10 -546
- package/dist/bin/exe-team.js +18 -5942
- package/dist/bin/git-sweep.js +26 -10909
- package/dist/bin/graph-backfill.js +24 -5979
- package/dist/bin/graph-export.js +31 -6128
- package/dist/bin/graph-layer-benchmark.js +4 -8
- package/dist/bin/install.js +47 -2322
- package/dist/bin/intercom-check.js +25 -11501
- package/dist/bin/list-providers.js +4 -18
- package/dist/bin/postgres-agentic-reflection-backfill.js +14 -357
- package/dist/bin/postgres-agentic-semantic-backfill.js +14 -404
- package/dist/bin/pre-publish.js +4 -298
- package/dist/bin/registry-proxy.js +8 -172
- package/dist/bin/scan-tasks.js +47 -10881
- package/dist/bin/setup.js +6 -9492
- package/dist/bin/shard-migrate.js +30 -5149
- package/dist/bin/stack-update.js +75 -203
- package/dist/bin/update.js +20 -654
- package/dist/capacity-monitor-3GZIHLB4.js +46 -0
- package/dist/catchup-brief-67QDCINS.js +148 -0
- package/dist/chunk-2QD7KBJN.js +664 -0
- package/dist/chunk-2WGSIVI4.js +149 -0
- package/dist/chunk-35TVNLJI.js +57 -0
- package/dist/chunk-3SYV36U5.js +47 -0
- package/dist/chunk-46SQTBQW.js +207 -0
- package/dist/chunk-4CMVLKEI.js +171 -0
- package/dist/chunk-4FLUOZTR.js +116 -0
- package/dist/chunk-4NYQAS33.js +17 -0
- package/dist/chunk-4QNPADWL.js +902 -0
- package/dist/chunk-4Y6QZBEO.js +58 -0
- package/dist/chunk-557C2IGL.js +0 -0
- package/dist/chunk-55S56YDO.js +305 -0
- package/dist/chunk-5BS5ELMC.js +85 -0
- package/dist/chunk-5DHM77JE.js +256 -0
- package/dist/chunk-5QTWQKNF.js +137 -0
- package/dist/chunk-6A7P74QV.js +53 -0
- package/dist/chunk-6BFIFI5F.js +45 -0
- package/dist/chunk-6KFICEAT.js +20 -0
- package/dist/chunk-6LKDJ5WX.js +317 -0
- package/dist/chunk-6M5II4EV.js +148 -0
- package/dist/chunk-6QEFN3DV.js +302 -0
- package/dist/chunk-6WTMJAG3.js +171 -0
- package/dist/chunk-6Y4B3QF6.js +19 -0
- package/dist/chunk-7RK3AYJE.js +163 -0
- package/dist/chunk-7TCP2XTP.js +390 -0
- package/dist/chunk-A2NZP64U.js +2307 -0
- package/dist/chunk-AFYIYM2K.js +322 -0
- package/dist/chunk-AJWFPKQS.js +573 -0
- package/dist/chunk-AVE2B4DQ.js +140 -0
- package/dist/chunk-B4TT2QQA.js +87 -0
- package/dist/chunk-BCMOO4OQ.js +1066 -0
- package/dist/chunk-BU3ID2WT.js +432 -0
- package/dist/chunk-CFIM43JH.js +862 -0
- package/dist/chunk-CURJUF3W.js +66 -0
- package/dist/chunk-DC4ZD76Y.js +288 -0
- package/dist/chunk-DL52JPGF.js +706 -0
- package/dist/chunk-DRSC6ZRA.js +36 -0
- package/dist/chunk-E2Q4Y22A.js +86 -0
- package/dist/chunk-ECGTESAP.js +236 -0
- package/dist/chunk-EHOJUXYG.js +365 -0
- package/dist/chunk-EIT6J37V.js +119 -0
- package/dist/chunk-ELE2C7L4.js +31 -0
- package/dist/chunk-EQSQ4HBW.js +9 -0
- package/dist/chunk-FWFFZGSC.js +94 -0
- package/dist/chunk-GCNWCYJI.js +249 -0
- package/dist/chunk-GGTUUI7J.js +6 -0
- package/dist/chunk-GU56L7OY.js +223 -0
- package/dist/chunk-HF25XPZE.js +83 -0
- package/dist/chunk-HOKOOBDL.js +52 -0
- package/dist/chunk-HP43GLZ6.js +89 -0
- package/dist/chunk-HSRM6PNM.js +682 -0
- package/dist/chunk-HVRTW3OP.js +164 -0
- package/dist/chunk-IHDHL5ML.js +125 -0
- package/dist/chunk-IHF5RXJM.js +168 -0
- package/dist/chunk-IJ73YE73.js +409 -0
- package/dist/chunk-INO4ZD5Y.js +162 -0
- package/dist/chunk-IRQTM7DY.js +475 -0
- package/dist/chunk-JD4FAPYG.js +1208 -0
- package/dist/chunk-JN44LQ53.js +316 -0
- package/dist/chunk-JQ6TLNIV.js +133 -0
- package/dist/chunk-JT76KRZQ.js +35 -0
- package/dist/chunk-K6OEWZTB.js +262 -0
- package/dist/chunk-KCUYRZSX.js +72 -0
- package/dist/chunk-KFQGP6VL.js +33 -0
- package/dist/chunk-KRLOFIPI.js +83 -0
- package/dist/chunk-KVPG5UT6.js +305 -0
- package/dist/chunk-L3TB7CC3.js +170 -0
- package/dist/chunk-L4X5EUHR.js +283 -0
- package/dist/chunk-LAN26C3W.js +655 -0
- package/dist/chunk-LPGBKR4H.js +54 -0
- package/dist/chunk-LVNMOVGD.js +132 -0
- package/dist/chunk-LX5WEEZ7.js +157 -0
- package/dist/chunk-MBH42QNH.js +295 -0
- package/dist/chunk-MFO7MNSD.js +102 -0
- package/dist/chunk-MILTNDZH.js +736 -0
- package/dist/chunk-MJAE4NB7.js +1090 -0
- package/dist/chunk-MLCUPTP7.js +132 -0
- package/dist/chunk-MPURH6JI.js +445 -0
- package/dist/chunk-MVBWW2EO.js +89 -0
- package/dist/chunk-MZIGUUDQ.js +42 -0
- package/dist/chunk-N3DTSVKE.js +157 -0
- package/dist/chunk-N5RRQOAC.js +134 -0
- package/dist/chunk-N7L33TED.js +1664 -0
- package/dist/chunk-NDYSNVI5.js +122 -0
- package/dist/chunk-NEAHEC5G.js +155 -0
- package/dist/chunk-NGVOA6ZQ.js +84 -0
- package/dist/chunk-NHK5KW6Y.js +193 -0
- package/dist/chunk-NMQKGFEP.js +458 -0
- package/dist/chunk-NPT4EHZK.js +352 -0
- package/dist/chunk-NXFJHTED.js +55 -0
- package/dist/chunk-NZLCDI6Y.js +216 -0
- package/dist/chunk-O377P7GM.js +100 -0
- package/dist/chunk-O4VFZRA5.js +33 -0
- package/dist/chunk-O7YD7JYE.js +237 -0
- package/dist/chunk-OFK72LTZ.js +81 -0
- package/dist/chunk-ORCCI2VV.js +140 -0
- package/dist/chunk-OVQR4KMC.js +579 -0
- package/dist/chunk-P3CVUMEH.js +54 -0
- package/dist/chunk-P4HIF72O.js +30 -0
- package/dist/chunk-PEDLSJBL.js +1039 -0
- package/dist/chunk-PFICKZZ5.js +219 -0
- package/dist/chunk-PGW7TIV6.js +142 -0
- package/dist/chunk-PJHHFJAN.js +63 -0
- package/dist/chunk-PP4SNOJ5.js +471 -0
- package/dist/chunk-PRKVT4KN.js +90 -0
- package/dist/chunk-Q2O4VJHH.js +305 -0
- package/dist/chunk-Q36CMZIX.js +38 -0
- package/dist/chunk-Q3V7K4ME.js +149 -0
- package/dist/chunk-QGYPJGHB.js +81 -0
- package/dist/chunk-R23EMFJV.js +198 -0
- package/dist/chunk-R4M6XCMU.js +39 -0
- package/dist/chunk-R4WMF32C.js +81 -0
- package/dist/chunk-RJT7H2KR.js +349 -0
- package/dist/chunk-RJZMRZNV.js +280 -0
- package/dist/chunk-RMFDPCA2.js +72 -0
- package/dist/chunk-RUG3N6P4.js +292 -0
- package/dist/chunk-RWO327FJ.js +84 -0
- package/dist/chunk-SG7EFHQ7.js +108 -0
- package/dist/chunk-SH45SJQW.js +0 -0
- package/dist/chunk-SPKE5ANC.js +42 -0
- package/dist/chunk-SVMFVPBF.js +104 -0
- package/dist/chunk-SVXDCELZ.js +163 -0
- package/dist/chunk-TMEE7AT7.js +72 -0
- package/dist/chunk-TWYEE4FB.js +125 -0
- package/dist/chunk-TYLF4LSW.js +110 -0
- package/dist/chunk-V4TZI6EO.js +60 -0
- package/dist/chunk-VFZTXKQI.js +372 -0
- package/dist/chunk-VQ4K2MLM.js +199 -0
- package/dist/chunk-VU447UAO.js +173 -0
- package/dist/chunk-WMC3TXJF.js +50 -0
- package/dist/chunk-WPOA7XAE.js +84 -0
- package/dist/chunk-WZQ4CPRG.js +64 -0
- package/dist/chunk-X2IMCCM5.js +49 -0
- package/dist/chunk-X2Z5GT3V.js +118 -0
- package/dist/chunk-XEKO37NM.js +43 -0
- package/dist/chunk-XUHFQHGZ.js +505 -0
- package/dist/chunk-YGAAZN3E.js +47 -0
- package/dist/chunk-YKOW7KMK.js +558 -0
- package/dist/chunk-YOQKMB6N.js +145 -0
- package/dist/chunk-YZFZDJWZ.js +107 -0
- package/dist/chunk-ZBY4AUD4.js +10342 -0
- package/dist/chunk-ZOJYPNCM.js +127 -0
- package/dist/chunk-ZS7MGQSD.js +1494 -0
- package/dist/chunk-ZTZQ5A6B.js +191 -0
- package/dist/code-context-index-HXGC4IJL.js +28 -0
- package/dist/content-extractor-UVZXRIPC.js +8 -0
- package/dist/conversation-entity-extractor-HKSNDF4L.js +113 -0
- package/dist/conversation-wiki-populator-NKDAQEZ5.js +105 -0
- package/dist/crdt-sync-T7MHVQCS.js +33 -0
- package/dist/crm-bridge-Q5JBVJ6P.js +19 -0
- package/dist/crm-webhook-OAFTLJYA.js +10 -0
- package/dist/cto-delegation-gate-XWHZCUJH.js +208 -0
- package/dist/daemon-auth-GWUXTUYO.js +15 -0
- package/dist/daemon-orchestration-2C3TVOHO.js +91 -0
- package/dist/daemon-protocol-RLH2XM2K.js +19 -0
- package/dist/db-backup-CH2KG3JY.js +23 -0
- package/dist/devtools-PLJCAU53.js +8 -0
- package/dist/discord-G4BQJ2VX.js +7 -0
- package/dist/email-XMRNMFXR.js +137 -0
- package/dist/entity-boost-IOER4VRR.js +249 -0
- package/dist/exe-drift-2IJFQV43.js +68 -0
- package/dist/exe-export-Y2RFXGNB.js +71 -0
- package/dist/exe-import-LN6PE2YT.js +74 -0
- package/dist/exe-key-DHKBWLIT.js +571 -0
- package/dist/exe-org-F7LZRHFB.js +73 -0
- package/dist/factory-YTD23AW7.js +67 -0
- package/dist/fast-db-init-IIP6EGWT.js +7 -0
- package/dist/file-edit-FJVEO7XZ.js +8 -0
- package/dist/file-read-Q2NH3J35.js +8 -0
- package/dist/file-write-UNSFXNH4.js +8 -0
- package/dist/gateway/index.js +87 -16563
- package/dist/gateway-client-APTYJNCL.js +11 -0
- package/dist/git-staleness-I2BUEDE2.js +111 -0
- package/dist/git-task-sweep-UEOTXRW4.js +35 -0
- package/dist/glob-GRMXLDMB.js +7 -0
- package/dist/global-procedures-MFE5LGRF.js +19 -0
- package/dist/graph-query-657O5JYJ.js +25 -0
- package/dist/graph-rag-ZE5N7C65.js +28 -0
- package/dist/grep-NBV6SKYZ.js +7 -0
- package/dist/hooks/bug-report-worker.js +41 -10823
- package/dist/hooks/codex-stop-task-finalizer.js +38 -9055
- package/dist/hooks/commit-complete.js +32 -10914
- package/dist/hooks/error-recall.js +35 -7955
- package/dist/hooks/exe-heartbeat-hook.js +17 -327
- package/dist/hooks/ingest-worker.js +16 -565
- package/dist/hooks/ingest.js +98 -11436
- package/dist/hooks/instructions-loaded.js +25 -6209
- package/dist/hooks/notification.js +16 -6098
- package/dist/hooks/post-compact.js +34 -7041
- package/dist/hooks/post-tool-combined.js +27 -9751
- package/dist/hooks/pre-compact.js +38 -11130
- package/dist/hooks/pre-tool-use.js +61 -7233
- package/dist/hooks/prompt-submit.js +113 -13358
- package/dist/hooks/session-end.js +57 -11503
- package/dist/hooks/session-start.js +46 -9423
- package/dist/hooks/stop.js +70 -7210
- package/dist/hooks/subagent-stop.js +33 -6897
- package/dist/hooks/summary-worker.js +86 -8629
- package/dist/hooks-KD3N2D7P.js +9 -0
- package/dist/imessage-L7WKA2WD.js +7 -0
- package/dist/index.js +49 -19391
- package/dist/installer-5N24GXFB.js +32 -0
- package/dist/installer-QSD76YRY.js +291 -0
- package/dist/installer-ZPQUKHU5.js +331 -0
- package/dist/intercom-queue-PEEGAJ33.js +19 -0
- package/dist/key-backup-status-57UB74DU.js +41 -0
- package/dist/lib/agent-config.js +19 -224
- package/dist/lib/cloud-sync.js +44 -5398
- package/dist/lib/cloudflare-dns.js +7 -111
- package/dist/lib/config.js +18 -278
- package/dist/lib/consolidation.js +21 -1047
- package/dist/lib/crypto.js +7 -45
- package/dist/lib/database.js +20 -2932
- package/dist/lib/db-daemon-client.js +24 -460
- package/dist/lib/db.js +22 -2932
- package/dist/lib/device-registry.js +20 -2992
- package/dist/lib/embedder.js +14 -822
- package/dist/lib/employee-templates.js +21 -1102
- package/dist/lib/employees.js +30 -497
- package/dist/lib/error-detector.js +9 -149
- package/dist/lib/exe-daemon-client.js +16 -570
- package/dist/lib/exe-daemon.js +509 -18398
- package/dist/lib/file-grep.js +2 -0
- package/dist/lib/hybrid-search.js +18 -7674
- package/dist/lib/identity-templates.js +2 -0
- package/dist/lib/identity.js +13 -309
- package/dist/lib/keychain.js +9 -499
- package/dist/lib/license.js +21 -549
- package/dist/lib/messaging.js +35 -1631
- package/dist/lib/post-tool-memory.js +8 -370
- package/dist/lib/registry-proxy.js +8 -155
- package/dist/lib/reminders.js +11 -231
- package/dist/lib/runtime-table.js +7 -20
- package/dist/lib/schedules.js +16 -4614
- package/dist/lib/session-registry.js +9 -57
- package/dist/lib/session-wrappers.js +3 -127
- package/dist/lib/skill-learning.js +20 -2101
- package/dist/lib/status-brief.js +4 -368
- package/dist/lib/store.js +25 -5593
- package/dist/lib/task-router.js +12 -254
- package/dist/lib/tasks.js +44 -5801
- package/dist/lib/tmux-routing.js +45 -5804
- package/dist/lib/tmux-status.js +16 -248
- package/dist/lib/tmux-transport.js +6 -90
- package/dist/lib/token-spend.js +9 -337
- package/dist/lib/transport.js +8 -134
- package/dist/lib/ws-auth.js +6 -14
- package/dist/lib/ws-client.js +4 -22
- package/dist/license-gate-NXXDOOAQ.js +14 -0
- package/dist/mcp/register-tools.js +90 -32454
- package/dist/mcp/server.js +139 -32625
- package/dist/mcp/tools/complete-reminder.js +10 -237
- package/dist/mcp/tools/create-reminder.js +10 -222
- package/dist/mcp/tools/create-task.js +28 -6730
- package/dist/mcp/tools/deactivate-behavior.js +13 -476
- package/dist/mcp/tools/list-reminders.js +10 -232
- package/dist/mcp/tools/list-tasks.js +28 -1571
- package/dist/mcp/tools/send-message.js +25 -1672
- package/dist/mcp/tools/update-task.js +27 -6123
- package/dist/mcp-diagnostics-OOZ3TDPY.js +200 -0
- package/dist/memory-cards-RIL5BZHK.js +175 -0
- package/dist/memory-queue-JYIJ7TMQ.js +13 -0
- package/dist/memory-queue-client-PE7757HU.js +14 -0
- package/dist/notifications-CJFULBMN.js +42 -0
- package/dist/orchestration-phase-Y2TYNW5H.js +23 -0
- package/dist/orchestrator-RXIPT6PZ.js +29 -0
- package/dist/permission-presets-WI524OSE.js +25 -0
- package/dist/permissions-TYT6YMNZ.js +14 -0
- package/dist/pg-ssl-KFHNJPGO.js +7 -0
- package/dist/plan-limits-5WY5YK6X.js +27 -0
- package/dist/preferences-MW3BYTQ5.js +10 -0
- package/dist/project-name-PL2ZDWNU.js +11 -0
- package/dist/projection-worker-OY4WYZW6.js +661 -0
- package/dist/reranker-LFJ73RRS.js +19 -0
- package/dist/review-gate-E6K7QQE5.js +120 -0
- package/dist/runtime/index.js +82 -13408
- package/dist/self-query-router-IZANO632.js +83 -0
- package/dist/session-events-TQ6S5KQN.js +32 -0
- package/dist/session-kill-telemetry-46YIJWE2.js +30 -0
- package/dist/session-scope-3MYK3YRV.js +34 -0
- package/dist/setup-wizard-ZJ7UCRBP.js +12 -0
- package/dist/shard-manager-RCFZ6RXY.js +29 -0
- package/dist/signal-XN2C7PIG.js +7 -0
- package/dist/slack-Z77TFJCK.js +7 -0
- package/dist/task-enforcement-337DZI3I.js +252 -0
- package/dist/task-scanner-IMIR3T7T.js +11 -0
- package/dist/task-scope-MUU4KXE6.js +32 -0
- package/dist/tasks-crud-PMLK3MM4.js +53 -0
- package/dist/tasks-review-56LVKKNL.js +44 -0
- package/dist/telegram-CRPZO7JT.js +7 -0
- package/dist/telemetry-SPVGPKU7.js +9 -0
- package/dist/tool-capability-index-XNBSDCH3.js +10 -0
- package/dist/tool-gates-LGH6CSY4.js +14 -0
- package/dist/tool-gates-W7SZCYTX.js +13 -0
- package/dist/tool-registry-436LVVLY.js +11 -0
- package/dist/tool-telemetry-L77WNAYT.js +15 -0
- package/dist/tui/App.js +253 -14668
- package/dist/tui-data-SB45REYU.js +161 -0
- package/dist/update-check-LZGZISRJ.js +11 -0
- package/dist/webhook-VVP7KQVC.js +96 -0
- package/dist/whatsapp-J6QNDBGY.js +9 -0
- package/dist/whatsapp-accounts-RTJF3LM6.js +15 -0
- package/dist/wiki-client-EKCIKCVC.js +136 -0
- package/dist/worker-gate-UYNN62GJ.js +19 -0
- package/dist/worktree-4T4BPWPN.js +205 -0
- package/package.json +1 -1
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
// src/gateway/crm-bridge.ts
|
|
2
|
+
var config = null;
|
|
3
|
+
var disabledLogged = false;
|
|
4
|
+
function initCRMBridge() {
|
|
5
|
+
const apiToken = process.env.CRM_API_TOKEN;
|
|
6
|
+
if (!apiToken) {
|
|
7
|
+
if (!disabledLogged) {
|
|
8
|
+
console.log("[crm-bridge] Disabled \u2014 CRM_API_TOKEN not set");
|
|
9
|
+
disabledLogged = true;
|
|
10
|
+
}
|
|
11
|
+
config = null;
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
const graphqlUrl = process.env.CRM_GRAPHQL_URL || "http://localhost:3000";
|
|
15
|
+
config = { graphqlUrl, apiToken };
|
|
16
|
+
console.log(`[crm-bridge] Enabled \u2014 pushing to ${graphqlUrl}`);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
function isCRMBridgeEnabled() {
|
|
20
|
+
return config !== null;
|
|
21
|
+
}
|
|
22
|
+
async function gqlRequest(query, variables) {
|
|
23
|
+
const res = await fetch(`${config.graphqlUrl}/api`, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: {
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
Authorization: `Bearer ${config.apiToken}`
|
|
28
|
+
},
|
|
29
|
+
body: JSON.stringify({ query, variables }),
|
|
30
|
+
signal: AbortSignal.timeout(3e4)
|
|
31
|
+
});
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
throw new Error(`CRM GraphQL request failed: ${res.status} ${res.statusText}`);
|
|
34
|
+
}
|
|
35
|
+
return res.json();
|
|
36
|
+
}
|
|
37
|
+
async function findPersonByContact(platform, senderId) {
|
|
38
|
+
const isEmail = platform === "email";
|
|
39
|
+
const query = isEmail ? `query FindPerson($value: String!) {
|
|
40
|
+
people(filter: { emails: { primaryEmail: { eq: $value } } }, first: 1) {
|
|
41
|
+
edges { node { id } }
|
|
42
|
+
}
|
|
43
|
+
}` : `query FindPerson($value: String!) {
|
|
44
|
+
people(filter: { phones: { primaryPhoneNumber: { eq: $value } } }, first: 1) {
|
|
45
|
+
edges { node { id } }
|
|
46
|
+
}
|
|
47
|
+
}`;
|
|
48
|
+
const res = await gqlRequest(query, { value: senderId });
|
|
49
|
+
if (res.errors && res.errors.length > 0) {
|
|
50
|
+
console.error("[crm-bridge] findPerson error:", res.errors[0].message);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const edges = res.data?.people?.edges;
|
|
54
|
+
return edges && edges.length > 0 ? edges[0].node.id : null;
|
|
55
|
+
}
|
|
56
|
+
async function createPerson(platform, senderId, senderName) {
|
|
57
|
+
const firstName = senderName?.split(" ")[0] || "";
|
|
58
|
+
const lastName = senderName?.split(" ").slice(1).join(" ") || "";
|
|
59
|
+
const isEmail = platform === "email";
|
|
60
|
+
const input = {
|
|
61
|
+
name: { firstName, lastName }
|
|
62
|
+
};
|
|
63
|
+
if (isEmail) {
|
|
64
|
+
input.emails = { primaryEmail: senderId, additionalEmails: [] };
|
|
65
|
+
} else {
|
|
66
|
+
input.phones = {
|
|
67
|
+
primaryPhoneNumber: senderId,
|
|
68
|
+
primaryPhoneCountryCode: "",
|
|
69
|
+
primaryPhoneCallingCode: "",
|
|
70
|
+
additionalPhones: []
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const query = `
|
|
74
|
+
mutation CreatePerson($input: PersonCreateInput!) {
|
|
75
|
+
createPerson(data: $input) {
|
|
76
|
+
id
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
`;
|
|
80
|
+
const res = await gqlRequest(query, {
|
|
81
|
+
input
|
|
82
|
+
});
|
|
83
|
+
if (res.errors && res.errors.length > 0) {
|
|
84
|
+
console.error("[crm-bridge] createPerson error:", res.errors[0].message);
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
return res.data?.createPerson?.id ?? null;
|
|
88
|
+
}
|
|
89
|
+
async function createTimelineActivity(personId, params) {
|
|
90
|
+
const channelLabel = params.platform.charAt(0).toUpperCase() + params.platform.slice(1);
|
|
91
|
+
const label = params.direction === "inbound" ? "message from" : "conversation with";
|
|
92
|
+
const input = {
|
|
93
|
+
name: `${channelLabel} ${label} ${params.senderName || params.senderId}`,
|
|
94
|
+
happensAt: params.timestamp,
|
|
95
|
+
properties: {
|
|
96
|
+
channel: params.platform,
|
|
97
|
+
senderId: params.senderId,
|
|
98
|
+
senderName: params.senderName || null,
|
|
99
|
+
messageText: params.messageText,
|
|
100
|
+
agentResponse: params.agentResponse || null,
|
|
101
|
+
agentName: params.agentName || null,
|
|
102
|
+
threadId: `${params.platform}:${params.senderId}`,
|
|
103
|
+
direction: params.direction,
|
|
104
|
+
accountId: params.accountId || null
|
|
105
|
+
},
|
|
106
|
+
targetPersonId: personId
|
|
107
|
+
};
|
|
108
|
+
const query = `
|
|
109
|
+
mutation CreateTimelineActivity($input: TimelineActivityCreateInput!) {
|
|
110
|
+
createTimelineActivity(data: $input) {
|
|
111
|
+
id
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
`;
|
|
115
|
+
const res = await gqlRequest(
|
|
116
|
+
query,
|
|
117
|
+
{ input }
|
|
118
|
+
);
|
|
119
|
+
if (res.errors && res.errors.length > 0) {
|
|
120
|
+
console.error(
|
|
121
|
+
"[crm-bridge] createTimelineActivity error:",
|
|
122
|
+
res.errors[0].message
|
|
123
|
+
);
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
async function pushConversationToCRM(params) {
|
|
129
|
+
if (!config) return;
|
|
130
|
+
try {
|
|
131
|
+
let personId = await findPersonByContact(params.platform, params.senderId);
|
|
132
|
+
if (!personId) {
|
|
133
|
+
personId = await createPerson(
|
|
134
|
+
params.platform,
|
|
135
|
+
params.senderId,
|
|
136
|
+
params.senderName
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
if (!personId) {
|
|
140
|
+
console.error("[crm-bridge] Failed to find or create person for", params.senderId);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const ok = await createTimelineActivity(personId, {
|
|
144
|
+
...params,
|
|
145
|
+
direction: "conversation"
|
|
146
|
+
});
|
|
147
|
+
if (ok) {
|
|
148
|
+
console.log(
|
|
149
|
+
`[crm-bridge] Pushed ${params.platform}/${params.senderId} \u2192 person ${personId}`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
} catch (err) {
|
|
153
|
+
console.error("[crm-bridge] Push failed:", err instanceof Error ? err.message : err);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async function pushInboundMessageToCRM(params) {
|
|
157
|
+
if (!config) return;
|
|
158
|
+
try {
|
|
159
|
+
let personId = await findPersonByContact(params.platform, params.senderId);
|
|
160
|
+
if (!personId) {
|
|
161
|
+
personId = await createPerson(
|
|
162
|
+
params.platform,
|
|
163
|
+
params.senderId,
|
|
164
|
+
params.senderName
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
if (!personId) {
|
|
168
|
+
console.error("[crm-bridge] Failed to find or create person for", params.senderId);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const ok = await createTimelineActivity(personId, {
|
|
172
|
+
...params,
|
|
173
|
+
direction: "inbound"
|
|
174
|
+
});
|
|
175
|
+
if (ok) {
|
|
176
|
+
console.log(
|
|
177
|
+
`[crm-bridge] Inbound ${params.platform}/${params.senderId} \u2192 person ${personId}`
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
} catch (err) {
|
|
181
|
+
console.error("[crm-bridge] Inbound push failed:", err instanceof Error ? err.message : err);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
async function pushGatewayEventToCRM(params) {
|
|
185
|
+
if (!config) return;
|
|
186
|
+
try {
|
|
187
|
+
let personId = await findPersonByContact(params.platform, params.senderId);
|
|
188
|
+
if (!personId) {
|
|
189
|
+
personId = await createPerson(
|
|
190
|
+
params.platform,
|
|
191
|
+
params.senderId,
|
|
192
|
+
params.senderName
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
if (!personId) {
|
|
196
|
+
console.error("[crm-bridge] Failed to find or create person for", params.senderId);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const channelLabel = params.platform.charAt(0).toUpperCase() + params.platform.slice(1);
|
|
200
|
+
const categoryLabel = params.dataCategory.replace(/_/g, " ");
|
|
201
|
+
const input = {
|
|
202
|
+
name: `${channelLabel} ${categoryLabel} \u2014 ${params.senderName || params.senderId}`,
|
|
203
|
+
happensAt: params.timestamp,
|
|
204
|
+
properties: {
|
|
205
|
+
channel: params.platform,
|
|
206
|
+
dataCategory: params.dataCategory,
|
|
207
|
+
senderId: params.senderId,
|
|
208
|
+
senderName: params.senderName || null,
|
|
209
|
+
accountId: params.accountId || null,
|
|
210
|
+
direction: "inbound",
|
|
211
|
+
...params.eventData
|
|
212
|
+
},
|
|
213
|
+
targetPersonId: personId
|
|
214
|
+
};
|
|
215
|
+
const query = `
|
|
216
|
+
mutation CreateTimelineActivity($input: TimelineActivityCreateInput!) {
|
|
217
|
+
createTimelineActivity(data: $input) {
|
|
218
|
+
id
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
`;
|
|
222
|
+
const res = await gqlRequest(
|
|
223
|
+
query,
|
|
224
|
+
{ input }
|
|
225
|
+
);
|
|
226
|
+
if (res.errors && res.errors.length > 0) {
|
|
227
|
+
console.error(
|
|
228
|
+
"[crm-bridge] pushGatewayEvent error:",
|
|
229
|
+
res.errors[0].message
|
|
230
|
+
);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
console.log(
|
|
234
|
+
`[crm-bridge] Event ${params.dataCategory} ${params.platform}/${params.senderId} \u2192 person ${personId}`
|
|
235
|
+
);
|
|
236
|
+
} catch (err) {
|
|
237
|
+
console.error("[crm-bridge] Event push failed:", err instanceof Error ? err.message : err);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export {
|
|
242
|
+
initCRMBridge,
|
|
243
|
+
isCRMBridgeEnabled,
|
|
244
|
+
findPersonByContact,
|
|
245
|
+
createPerson,
|
|
246
|
+
pushConversationToCRM,
|
|
247
|
+
pushInboundMessageToCRM,
|
|
248
|
+
pushGatewayEventToCRM
|
|
249
|
+
};
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
// src/lib/tool-gates.ts
|
|
2
|
+
var TOOL_GATES = {
|
|
3
|
+
core: [],
|
|
4
|
+
// all agents — recall, store, ask_team, commit, search, session, consolidate, cardinality, behavior, identity, decisions
|
|
5
|
+
tasks: [],
|
|
6
|
+
// all agents — create, list, get, update, close, checkpoint, resume
|
|
7
|
+
comms: [],
|
|
8
|
+
// all agents — send_message, acknowledge
|
|
9
|
+
reminders: [],
|
|
10
|
+
// all agents — create, list, complete, reminder
|
|
11
|
+
"graph-read": [],
|
|
12
|
+
// all agents — query_relationships, get_entity_neighbors, get_hot_entities, get_graph_stats, find_similar_trajectories, code_context
|
|
13
|
+
"graph-write": ["COO", "CTO"],
|
|
14
|
+
// merge_entities, export_graph
|
|
15
|
+
wiki: ["COO", "Wiki Agent"],
|
|
16
|
+
// read/list curated wiki pages
|
|
17
|
+
crm: ["COO", "CRM Agent"],
|
|
18
|
+
// CRM read/list/get and legacy add/list/get person
|
|
19
|
+
"raw-data": ["COO", "CTO", "Gateway Agent", "CRM Agent", "Wiki Agent"],
|
|
20
|
+
// capped read-only raw landing-pad access
|
|
21
|
+
documents: ["COO", "CTO", "Wiki Agent"],
|
|
22
|
+
// ingest, list, purge, set_importance, rerank
|
|
23
|
+
gateway: ["COO", "Gateway Agent"],
|
|
24
|
+
// send_whatsapp, query_conversations, query_company_brain, company_actions
|
|
25
|
+
admin: ["COO"],
|
|
26
|
+
// deploy, backup, daemon health, auto-wake, worker gate, memory audit, consolidation, cloud sync, agent config, list employees, agent spend, sessions, session kills
|
|
27
|
+
licensing: ["COO"],
|
|
28
|
+
// get/create/list/activate license
|
|
29
|
+
orchestration: ["COO"]
|
|
30
|
+
// triggers, load_skill, starter_pack, export/import orchestration, global procedures
|
|
31
|
+
};
|
|
32
|
+
var TOOL_CATEGORIES = {
|
|
33
|
+
// core
|
|
34
|
+
registerMemory: "core",
|
|
35
|
+
registerRecallMyMemory: "core",
|
|
36
|
+
registerAskTeamMemory: "core",
|
|
37
|
+
registerGetSessionContext: "core",
|
|
38
|
+
registerGetMemoryById: "core",
|
|
39
|
+
registerStoreMemory: "core",
|
|
40
|
+
registerCommitMemory: "core",
|
|
41
|
+
registerSearchEverything: "core",
|
|
42
|
+
registerConsolidateMemories: "core",
|
|
43
|
+
registerGetMemoryCardinality: "core",
|
|
44
|
+
registerStoreBehavior: "core",
|
|
45
|
+
registerListBehaviors: "core",
|
|
46
|
+
registerDeactivateBehavior: "core",
|
|
47
|
+
registerBehavior: "core",
|
|
48
|
+
registerStoreDecision: "core",
|
|
49
|
+
registerGetDecision: "core",
|
|
50
|
+
registerCreateBugReport: "core",
|
|
51
|
+
registerSupportTools: "core",
|
|
52
|
+
registerCliParityTools: "admin",
|
|
53
|
+
registerGetSessionEvents: "core",
|
|
54
|
+
registerGetLastAssistantResponse: "core",
|
|
55
|
+
registerCodeContext: "graph-read",
|
|
56
|
+
// consolidated tools
|
|
57
|
+
registerDecision: "core",
|
|
58
|
+
registerSession: "core",
|
|
59
|
+
registerSupportConsolidated: "core",
|
|
60
|
+
registerDiagnostics: "admin",
|
|
61
|
+
registerListBugReports: "admin",
|
|
62
|
+
registerGetBugReport: "admin",
|
|
63
|
+
registerTriageBugReport: "admin",
|
|
64
|
+
registerIdentity: "core",
|
|
65
|
+
registerGetIdentity: "core",
|
|
66
|
+
registerUpdateIdentity: "core",
|
|
67
|
+
// tasks
|
|
68
|
+
registerTask: "tasks",
|
|
69
|
+
registerCreateTask: "tasks",
|
|
70
|
+
registerListTasks: "tasks",
|
|
71
|
+
registerUpdateTask: "tasks",
|
|
72
|
+
registerCloseTask: "tasks",
|
|
73
|
+
registerGetTask: "tasks",
|
|
74
|
+
registerCheckpointTask: "tasks",
|
|
75
|
+
registerResumeEmployee: "tasks",
|
|
76
|
+
// comms
|
|
77
|
+
registerMessage: "comms",
|
|
78
|
+
registerSendMessage: "comms",
|
|
79
|
+
registerAcknowledgeMessages: "comms",
|
|
80
|
+
// reminders
|
|
81
|
+
registerCreateReminder: "reminders",
|
|
82
|
+
registerListReminders: "reminders",
|
|
83
|
+
registerCompleteReminder: "reminders",
|
|
84
|
+
registerReminder: "reminders",
|
|
85
|
+
// graph-read
|
|
86
|
+
registerGraph: "graph-read",
|
|
87
|
+
registerQueryRelationships: "graph-read",
|
|
88
|
+
registerGetEntityNeighbors: "graph-read",
|
|
89
|
+
registerGetHotEntities: "graph-read",
|
|
90
|
+
registerGetGraphStats: "graph-read",
|
|
91
|
+
registerFindSimilarTrajectories: "graph-read",
|
|
92
|
+
// graph-write
|
|
93
|
+
registerMergeEntities: "graph-write",
|
|
94
|
+
registerExportGraph: "graph-write",
|
|
95
|
+
// wiki
|
|
96
|
+
registerWiki: "wiki",
|
|
97
|
+
registerCreateWikiPage: "wiki",
|
|
98
|
+
registerListWikiPages: "wiki",
|
|
99
|
+
registerGetWikiPage: "wiki",
|
|
100
|
+
// crm
|
|
101
|
+
registerCrm: "crm",
|
|
102
|
+
registerRawData: "raw-data",
|
|
103
|
+
registerAddPerson: "crm",
|
|
104
|
+
registerListPeople: "crm",
|
|
105
|
+
registerGetPerson: "crm",
|
|
106
|
+
// documents
|
|
107
|
+
registerDocument: "documents",
|
|
108
|
+
registerIngestDocument: "documents",
|
|
109
|
+
registerListDocuments: "documents",
|
|
110
|
+
registerPurgeDocument: "documents",
|
|
111
|
+
registerSetDocumentImportance: "documents",
|
|
112
|
+
registerRerankDocuments: "documents",
|
|
113
|
+
// gateway
|
|
114
|
+
registerGateway: "gateway",
|
|
115
|
+
registerSendWhatsapp: "gateway",
|
|
116
|
+
registerQueryConversations: "gateway",
|
|
117
|
+
registerQueryCompanyBrain: "gateway",
|
|
118
|
+
registerCompanyActions: "gateway",
|
|
119
|
+
// admin
|
|
120
|
+
registerConfig: "admin",
|
|
121
|
+
registerDeployClient: "admin",
|
|
122
|
+
registerBackupVps: "admin",
|
|
123
|
+
registerGetDaemonHealth: "admin",
|
|
124
|
+
registerMcpPing: "core",
|
|
125
|
+
registerGetAutoWakeStatus: "admin",
|
|
126
|
+
registerGetWorkerGate: "admin",
|
|
127
|
+
registerRunMemoryAudit: "admin",
|
|
128
|
+
registerRunConsolidation: "admin",
|
|
129
|
+
registerCloudSync: "admin",
|
|
130
|
+
registerOrchestrationPhase: "admin",
|
|
131
|
+
registerSetAgentConfig: "admin",
|
|
132
|
+
registerListEmployees: "admin",
|
|
133
|
+
registerGetAgentSpend: "admin",
|
|
134
|
+
registerListAgentSessions: "admin",
|
|
135
|
+
registerGetSessionKills: "admin",
|
|
136
|
+
// licensing
|
|
137
|
+
registerGetLicenseStatus: "licensing",
|
|
138
|
+
registerCreateLicense: "licensing",
|
|
139
|
+
registerListLicenses: "licensing",
|
|
140
|
+
registerActivateLicense: "licensing",
|
|
141
|
+
// orchestration
|
|
142
|
+
registerCreateTrigger: "orchestration",
|
|
143
|
+
registerListTriggers: "orchestration",
|
|
144
|
+
registerApplyStarterPack: "orchestration",
|
|
145
|
+
registerLoadSkill: "orchestration",
|
|
146
|
+
registerExportOrchestration: "orchestration",
|
|
147
|
+
registerImportOrchestration: "orchestration",
|
|
148
|
+
registerCompanyProcedure: "orchestration",
|
|
149
|
+
registerGlobalProcedure: "orchestration",
|
|
150
|
+
registerStoreGlobalProcedure: "orchestration",
|
|
151
|
+
registerListGlobalProcedures: "orchestration",
|
|
152
|
+
registerDeactivateGlobalProcedure: "orchestration"
|
|
153
|
+
};
|
|
154
|
+
var PLAN_TIERS = {
|
|
155
|
+
free: 0,
|
|
156
|
+
pro: 1,
|
|
157
|
+
team: 2,
|
|
158
|
+
agency: 3,
|
|
159
|
+
enterprise: 4
|
|
160
|
+
};
|
|
161
|
+
var PLAN_GATES = {
|
|
162
|
+
core: "free",
|
|
163
|
+
tasks: "free",
|
|
164
|
+
comms: "free",
|
|
165
|
+
reminders: "free",
|
|
166
|
+
"graph-read": "free",
|
|
167
|
+
licensing: "free",
|
|
168
|
+
// always allow checking/managing own license
|
|
169
|
+
"graph-write": "pro",
|
|
170
|
+
wiki: "pro",
|
|
171
|
+
crm: "pro",
|
|
172
|
+
"raw-data": "pro",
|
|
173
|
+
documents: "pro",
|
|
174
|
+
gateway: "pro",
|
|
175
|
+
admin: "pro",
|
|
176
|
+
orchestration: "pro"
|
|
177
|
+
};
|
|
178
|
+
function isToolAllowedForPlan(registerFnName, plan) {
|
|
179
|
+
const category = TOOL_CATEGORIES[registerFnName];
|
|
180
|
+
if (!category) return true;
|
|
181
|
+
const requiredPlan = PLAN_GATES[category] ?? "free";
|
|
182
|
+
return PLAN_TIERS[plan] >= PLAN_TIERS[requiredPlan];
|
|
183
|
+
}
|
|
184
|
+
var CHIEF_OF_STAFF_READ_TOOLS = /* @__PURE__ */ new Set([
|
|
185
|
+
"registerRecallMyMemory",
|
|
186
|
+
"registerAskTeamMemory",
|
|
187
|
+
"registerGetMemoryById",
|
|
188
|
+
"registerGetSessionContext",
|
|
189
|
+
"registerGetSessionEvents",
|
|
190
|
+
"registerGetLastAssistantResponse",
|
|
191
|
+
"registerSearchEverything",
|
|
192
|
+
"registerGetDecision",
|
|
193
|
+
"registerGetIdentity",
|
|
194
|
+
"registerMcpPing",
|
|
195
|
+
"registerListTasks",
|
|
196
|
+
"registerGetTask",
|
|
197
|
+
"registerListReminders",
|
|
198
|
+
"registerQueryConversations",
|
|
199
|
+
"registerQueryCompanyBrain"
|
|
200
|
+
]);
|
|
201
|
+
function isChiefOfStaffRole(role) {
|
|
202
|
+
const normalized = (role ?? "").trim().toLowerCase();
|
|
203
|
+
return normalized === "chief of staff" || normalized === "executive assistant";
|
|
204
|
+
}
|
|
205
|
+
function isToolAllowed(registerFnName) {
|
|
206
|
+
const role = process.env.AGENT_ROLE;
|
|
207
|
+
if (!role) return true;
|
|
208
|
+
if (isChiefOfStaffRole(role)) {
|
|
209
|
+
return CHIEF_OF_STAFF_READ_TOOLS.has(registerFnName);
|
|
210
|
+
}
|
|
211
|
+
const category = TOOL_CATEGORIES[registerFnName];
|
|
212
|
+
if (!category) return true;
|
|
213
|
+
const allowedRoles = TOOL_GATES[category];
|
|
214
|
+
if (!allowedRoles || allowedRoles.length === 0) return true;
|
|
215
|
+
return allowedRoles.includes(role);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export {
|
|
219
|
+
TOOL_GATES,
|
|
220
|
+
TOOL_CATEGORIES,
|
|
221
|
+
isToolAllowedForPlan,
|
|
222
|
+
isToolAllowed
|
|
223
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// src/runtime/permission-presets.ts
|
|
2
|
+
var CTO_PRESET = {
|
|
3
|
+
defaultMode: "allow",
|
|
4
|
+
rules: []
|
|
5
|
+
};
|
|
6
|
+
var COO_PRESET = {
|
|
7
|
+
defaultMode: "deny",
|
|
8
|
+
rules: [
|
|
9
|
+
{ tool: "Read", decision: "allow" },
|
|
10
|
+
{ tool: "Glob", decision: "allow" },
|
|
11
|
+
{ tool: "Grep", decision: "allow" },
|
|
12
|
+
{ tool: "mcp__exe-os__*", decision: "allow" },
|
|
13
|
+
{ tool: "mcp__exe-mem__*", decision: "allow" }
|
|
14
|
+
]
|
|
15
|
+
};
|
|
16
|
+
var CMO_PRESET = {
|
|
17
|
+
defaultMode: "deny",
|
|
18
|
+
rules: [
|
|
19
|
+
{ tool: "Read", decision: "allow" },
|
|
20
|
+
{ tool: "Glob", decision: "allow" },
|
|
21
|
+
{ tool: "Grep", decision: "allow" },
|
|
22
|
+
{ tool: "Write", pattern: "exe/output/*", decision: "allow" },
|
|
23
|
+
{ tool: "mcp__exe-os__*", decision: "allow" },
|
|
24
|
+
{ tool: "mcp__exe-mem__*", decision: "allow" }
|
|
25
|
+
]
|
|
26
|
+
};
|
|
27
|
+
var PRINCIPAL_ENGINEER_PRESET = {
|
|
28
|
+
defaultMode: "allow",
|
|
29
|
+
rules: [
|
|
30
|
+
{ tool: "Bash", pattern: "rm -rf *", decision: "deny" },
|
|
31
|
+
{ tool: "Bash", pattern: "sudo *", decision: "deny" }
|
|
32
|
+
]
|
|
33
|
+
};
|
|
34
|
+
var CONTENT_SPECIALIST_PRESET = {
|
|
35
|
+
...CMO_PRESET
|
|
36
|
+
};
|
|
37
|
+
var PERMISSION_PRESETS = {
|
|
38
|
+
CTO: CTO_PRESET,
|
|
39
|
+
COO: COO_PRESET,
|
|
40
|
+
CMO: CMO_PRESET,
|
|
41
|
+
"Principal Engineer": PRINCIPAL_ENGINEER_PRESET,
|
|
42
|
+
"Content Production Specialist": CONTENT_SPECIALIST_PRESET
|
|
43
|
+
};
|
|
44
|
+
function matchToolPattern(toolName, pattern) {
|
|
45
|
+
if (pattern === "*") return true;
|
|
46
|
+
if (!pattern.includes("*")) return toolName === pattern;
|
|
47
|
+
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
48
|
+
return new RegExp(`^${escaped}$`).test(toolName);
|
|
49
|
+
}
|
|
50
|
+
function matchInputPattern(input, pattern) {
|
|
51
|
+
if (!pattern.includes("*")) return input === pattern;
|
|
52
|
+
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
53
|
+
return new RegExp(`^${escaped}$`).test(input);
|
|
54
|
+
}
|
|
55
|
+
function evaluatePermission(config, toolName, toolInput) {
|
|
56
|
+
for (const rule of config.rules) {
|
|
57
|
+
if (!matchToolPattern(toolName, rule.tool)) continue;
|
|
58
|
+
if (rule.pattern) {
|
|
59
|
+
if (toolInput && matchInputPattern(toolInput, rule.pattern)) {
|
|
60
|
+
return { decision: rule.decision, rule };
|
|
61
|
+
}
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
return { decision: rule.decision, rule };
|
|
65
|
+
}
|
|
66
|
+
return { decision: config.defaultMode };
|
|
67
|
+
}
|
|
68
|
+
function getPresetByRole(role) {
|
|
69
|
+
return PERMISSION_PRESETS[role];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export {
|
|
73
|
+
CTO_PRESET,
|
|
74
|
+
COO_PRESET,
|
|
75
|
+
CMO_PRESET,
|
|
76
|
+
PRINCIPAL_ENGINEER_PRESET,
|
|
77
|
+
CONTENT_SPECIALIST_PRESET,
|
|
78
|
+
PERMISSION_PRESETS,
|
|
79
|
+
matchToolPattern,
|
|
80
|
+
matchInputPattern,
|
|
81
|
+
evaluatePermission,
|
|
82
|
+
getPresetByRole
|
|
83
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// src/lib/crypto.ts
|
|
2
|
+
import crypto from "crypto";
|
|
3
|
+
var ALGORITHM = "aes-256-gcm";
|
|
4
|
+
var IV_LENGTH = 12;
|
|
5
|
+
var TAG_LENGTH = 16;
|
|
6
|
+
var SYNC_HKDF_INFO = "exe-mem-sync-v2";
|
|
7
|
+
var _syncKey = null;
|
|
8
|
+
function initSyncCrypto(masterKey) {
|
|
9
|
+
if (masterKey.length !== 32) {
|
|
10
|
+
throw new Error(`Master key must be 32 bytes, got ${masterKey.length}`);
|
|
11
|
+
}
|
|
12
|
+
_syncKey = Buffer.from(
|
|
13
|
+
crypto.hkdfSync("sha256", masterKey, "", SYNC_HKDF_INFO, 32)
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
function isSyncCryptoInitialized() {
|
|
17
|
+
return _syncKey !== null;
|
|
18
|
+
}
|
|
19
|
+
function requireSyncKey() {
|
|
20
|
+
if (!_syncKey) {
|
|
21
|
+
throw new Error("Sync crypto not initialized. Call initSyncCrypto(masterKey) first.");
|
|
22
|
+
}
|
|
23
|
+
return _syncKey;
|
|
24
|
+
}
|
|
25
|
+
function encryptSyncBlob(data) {
|
|
26
|
+
const key = requireSyncKey();
|
|
27
|
+
const iv = crypto.randomBytes(IV_LENGTH);
|
|
28
|
+
const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
|
|
29
|
+
const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
|
|
30
|
+
const tag = cipher.getAuthTag();
|
|
31
|
+
return Buffer.concat([iv, encrypted, tag]).toString("base64");
|
|
32
|
+
}
|
|
33
|
+
function decryptSyncBlob(ciphertext) {
|
|
34
|
+
const key = requireSyncKey();
|
|
35
|
+
const combined = Buffer.from(ciphertext, "base64");
|
|
36
|
+
if (combined.length < IV_LENGTH + TAG_LENGTH) {
|
|
37
|
+
throw new Error("Sync blob too short to contain IV + tag");
|
|
38
|
+
}
|
|
39
|
+
const iv = combined.subarray(0, IV_LENGTH);
|
|
40
|
+
const tag = combined.subarray(combined.length - TAG_LENGTH);
|
|
41
|
+
const encrypted = combined.subarray(IV_LENGTH, combined.length - TAG_LENGTH);
|
|
42
|
+
const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
|
|
43
|
+
decipher.setAuthTag(tag);
|
|
44
|
+
return Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
initSyncCrypto,
|
|
49
|
+
isSyncCryptoInitialized,
|
|
50
|
+
encryptSyncBlob,
|
|
51
|
+
decryptSyncBlob
|
|
52
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__esm
|
|
3
|
+
} from "./chunk-KFQGP6VL.js";
|
|
4
|
+
|
|
5
|
+
// src/lib/session-key.ts
|
|
6
|
+
import { execSync } from "child_process";
|
|
7
|
+
function normalizeCommand(command) {
|
|
8
|
+
const trimmed = command.trim().toLowerCase();
|
|
9
|
+
const parts = trimmed.split(/[\\/]/);
|
|
10
|
+
return parts[parts.length - 1] ?? trimmed;
|
|
11
|
+
}
|
|
12
|
+
function detectRuntimeFromCommand(command) {
|
|
13
|
+
const normalized = normalizeCommand(command);
|
|
14
|
+
for (const [runtime, commands] of Object.entries(RUNTIME_COMMANDS)) {
|
|
15
|
+
if (commands.includes(normalized)) {
|
|
16
|
+
return runtime;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
function resolveRuntimeProcess() {
|
|
22
|
+
let pid = process.ppid;
|
|
23
|
+
for (let i = 0; i < 10; i++) {
|
|
24
|
+
try {
|
|
25
|
+
const info = execSync(`ps -p ${pid} -o ppid=,comm=`, {
|
|
26
|
+
encoding: "utf8",
|
|
27
|
+
timeout: 2e3
|
|
28
|
+
}).trim();
|
|
29
|
+
const match = info.match(/^\s*(\d+)\s+(.+)$/);
|
|
30
|
+
if (!match) break;
|
|
31
|
+
const [, ppid, cmd] = match;
|
|
32
|
+
const runtime = detectRuntimeFromCommand(cmd ?? "");
|
|
33
|
+
if (runtime) {
|
|
34
|
+
return { pid: String(pid), runtime };
|
|
35
|
+
}
|
|
36
|
+
pid = parseInt(ppid, 10);
|
|
37
|
+
if (pid <= 1) break;
|
|
38
|
+
} catch {
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
function getSessionRuntime() {
|
|
45
|
+
if (process.env.EXE_RUNTIME) {
|
|
46
|
+
const envRuntime = process.env.EXE_RUNTIME.toLowerCase();
|
|
47
|
+
if (envRuntime === "claude" || envRuntime === "codex" || envRuntime === "opencode") {
|
|
48
|
+
return envRuntime;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (_cachedRuntime) return _cachedRuntime;
|
|
52
|
+
const resolved = resolveRuntimeProcess();
|
|
53
|
+
_cachedRuntime = resolved?.runtime ?? null;
|
|
54
|
+
return _cachedRuntime;
|
|
55
|
+
}
|
|
56
|
+
function getSessionKey() {
|
|
57
|
+
if (_cached) return _cached;
|
|
58
|
+
if (process.env.EXE_SESSION_KEY) {
|
|
59
|
+
_cached = process.env.EXE_SESSION_KEY;
|
|
60
|
+
return _cached;
|
|
61
|
+
}
|
|
62
|
+
const resolved = resolveRuntimeProcess();
|
|
63
|
+
if (resolved) {
|
|
64
|
+
_cachedRuntime = resolved.runtime;
|
|
65
|
+
_cached = resolved.pid;
|
|
66
|
+
return _cached;
|
|
67
|
+
}
|
|
68
|
+
_cached = process.env.CLAUDE_CODE_SSE_PORT ?? String(process.ppid);
|
|
69
|
+
return _cached;
|
|
70
|
+
}
|
|
71
|
+
var _cached, _cachedRuntime, RUNTIME_COMMANDS;
|
|
72
|
+
var init_session_key = __esm({
|
|
73
|
+
"src/lib/session-key.ts"() {
|
|
74
|
+
"use strict";
|
|
75
|
+
_cached = null;
|
|
76
|
+
_cachedRuntime = null;
|
|
77
|
+
RUNTIME_COMMANDS = {
|
|
78
|
+
claude: ["claude", "claude.exe", "claude-native"],
|
|
79
|
+
codex: ["codex"],
|
|
80
|
+
opencode: ["opencode"]
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
export {
|
|
86
|
+
getSessionRuntime,
|
|
87
|
+
getSessionKey,
|
|
88
|
+
init_session_key
|
|
89
|
+
};
|