@askexenow/exe-os 0.9.267 → 0.9.268
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.customer.example +10 -0
- package/deploy/compose/docker-compose.yml +5 -6
- package/dist/active-agent-CA6YCKRU.js +25 -0
- package/dist/active-agent-S55CV6MK.js +26 -0
- package/dist/active-agent-T4IMZLH4.js +25 -0
- package/dist/active-agent-USYNCT45.js +26 -0
- package/dist/agentic-ontology-AZVW3ZYE.js +25 -0
- package/dist/backfill-metadata-556UWRQK.js +597 -0
- package/dist/backfill-metadata-Q5QBN45Z.js +597 -0
- package/dist/behaviors-CPS3PGWK.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 +5 -5
- package/dist/bin/backfill-responses.js +5 -5
- package/dist/bin/backfill-vectors.js +6 -6
- package/dist/bin/bulk-sync-postgres.js +6 -6
- package/dist/bin/cc-doctor.js +4 -4
- package/dist/bin/cleanup-stale-review-tasks.js +9 -9
- package/dist/bin/cli.js +16 -16
- package/dist/bin/exe-agent-config.js +2 -2
- package/dist/bin/exe-agent.js +4 -4
- package/dist/bin/exe-assign.js +7 -7
- 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 +4 -4
- package/dist/bin/exe-heartbeat.js +9 -9
- 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 +9 -9
- 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 +4 -4
- 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/bin/stack-update.js +2 -2
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/capacity-monitor-WP4XXR7R.js +49 -0
- package/dist/capacity-monitor-ZGQ54TJG.js +49 -0
- package/dist/catchup-brief-X6O7W2YR.js +151 -0
- package/dist/catchup-brief-Z7SNTGLV.js +151 -0
- package/dist/chunk-23MJ2AJJ.js +227 -0
- package/dist/chunk-2NIJORQE.js +1335 -0
- package/dist/chunk-32RG5ZJN.js +3955 -0
- package/dist/chunk-3VTC7TJF.js +128 -0
- package/dist/chunk-3ZXL2KBT.js +1073 -0
- package/dist/chunk-44MXQ47E.js +185 -0
- package/dist/chunk-474SY5VD.js +159 -0
- package/dist/chunk-4LMI7RAW.js +1345 -0
- package/dist/chunk-4OH73UXH.js +1090 -0
- package/dist/chunk-4TOJXBXG.js +1073 -0
- package/dist/chunk-52UCKTIS.js +333 -0
- package/dist/chunk-5CHJKN6Y.js +668 -0
- package/dist/chunk-5MOYMGS5.js +818 -0
- package/dist/chunk-5ZSES6UA.js +363 -0
- package/dist/chunk-6HTXA4IM.js +394 -0
- package/dist/chunk-6L5DS7XO.js +394 -0
- package/dist/chunk-6TZCFZNG.js +171 -0
- package/dist/chunk-6WKV4F6L.js +1021 -0
- package/dist/chunk-7EOWAMTZ.js +69 -0
- package/dist/chunk-7MKEEX3T.js +2091 -0
- package/dist/chunk-7QYTIVXO.js +1051 -0
- package/dist/chunk-7SLLNRR3.js +129 -0
- package/dist/chunk-7V53QH5T.js +204 -0
- package/dist/chunk-7XDVTUTI.js +50 -0
- package/dist/chunk-A2E2TBDU.js +330 -0
- package/dist/chunk-A4DKFB77.js +159 -0
- package/dist/chunk-AUUJONUS.js +58 -0
- package/dist/chunk-B4YGGOCL.js +284 -0
- package/dist/chunk-BVYP37Y3.js +1345 -0
- package/dist/chunk-BXY5Y3RI.js +3955 -0
- package/dist/chunk-C3MK24X5.js +13696 -0
- package/dist/chunk-C74ZXYPJ.js +123 -0
- package/dist/chunk-CBO7IM7Q.js +135 -0
- package/dist/chunk-DIZLK77N.js +240 -0
- package/dist/chunk-DLTODKBW.js +1921 -0
- package/dist/chunk-DNJVH7A7.js +221 -0
- package/dist/chunk-E2FPTCL5.js +297 -0
- package/dist/chunk-E5USG7Z4.js +54 -0
- package/dist/chunk-E64IJVDT.js +85 -0
- package/dist/chunk-EFGQ72GA.js +76 -0
- package/dist/chunk-EODAYF7M.js +97 -0
- package/dist/chunk-EOKBXGMP.js +495 -0
- package/dist/chunk-EPYHCDZZ.js +551 -0
- package/dist/chunk-FHLIK2XG.js +38 -0
- package/dist/chunk-FO6CLTAL.js +128 -0
- package/dist/chunk-FSBNZ5YU.js +244 -0
- package/dist/chunk-FSGO7ADD.js +333 -0
- package/dist/chunk-G5L6YLG4.js +85 -0
- package/dist/chunk-GHPZEKDK.js +447 -0
- package/dist/chunk-GLSNVF6N.js +97 -0
- package/dist/chunk-GQ2XYRG3.js +163 -0
- package/dist/chunk-HGTXRRBK.js +230 -0
- package/dist/chunk-HILKCYA4.js +97 -0
- package/dist/chunk-HYI4PN4J.js +1148 -0
- package/dist/chunk-IDMLHBCK.js +1090 -0
- package/dist/chunk-IOVGBFTA.js +159 -0
- package/dist/chunk-ISAHJV4Z.js +346 -0
- package/dist/chunk-IXQ3XIG2.js +197 -0
- package/dist/chunk-JJ4VDZ5E.js +377 -0
- package/dist/chunk-JJOBSWJY.js +214 -0
- package/dist/chunk-JNRIWD5S.js +604 -0
- package/dist/chunk-JP45GCVR.js +630 -0
- package/dist/chunk-JWMFB6XM.js +244 -0
- package/dist/chunk-K7W4TYMT.js +33 -0
- package/dist/chunk-KFYOA37Q.js +562 -0
- package/dist/chunk-KUACUU74.js +58 -0
- package/dist/chunk-LHBWJIFR.js +290 -0
- package/dist/chunk-LMUDBSYR.js +551 -0
- package/dist/chunk-LSV3ODBA.js +13696 -0
- package/dist/chunk-M7GR2WO4.js +81 -0
- package/dist/chunk-MCBSXDR4.js +513 -0
- package/dist/chunk-MGJ2Z7QJ.js +127 -0
- package/dist/chunk-MUA24YMF.js +382 -0
- package/dist/chunk-MWDTPILI.js +204 -0
- package/dist/chunk-N4OGW6LW.js +731 -0
- package/dist/chunk-NBXL2BL5.js +330 -0
- package/dist/chunk-NT6A3EBV.js +1051 -0
- package/dist/chunk-ONEJTZID.js +348 -0
- package/dist/chunk-OREDDY5Y.js +513 -0
- package/dist/chunk-OSXQTCW5.js +55 -0
- package/dist/chunk-P2Q6UT2C.js +128 -0
- package/dist/chunk-PDIODWQM.js +731 -0
- package/dist/chunk-Q3NKXRHX.js +30 -0
- package/dist/chunk-QIEJRCF3.js +1148 -0
- package/dist/chunk-QILNBNN2.js +284 -0
- package/dist/chunk-QS7R2M4A.js +54 -0
- package/dist/chunk-RSIDQBIG.js +210 -0
- package/dist/chunk-SD6UFZRH.js +280 -0
- package/dist/chunk-SDL5IADB.js +76 -0
- package/dist/chunk-SFSGDC7D.js +81 -0
- package/dist/chunk-SHXHDHAX.js +127 -0
- package/dist/chunk-SQ5NFDBG.js +197 -0
- package/dist/chunk-SR34TKRT.js +214 -0
- package/dist/chunk-SYKAF5B3.js +185 -0
- package/dist/chunk-T2WWBFOX.js +447 -0
- package/dist/chunk-TINMRD3X.js +157 -0
- package/dist/chunk-TMV776ZJ.js +244 -0
- package/dist/chunk-TN45CTOI.js +70 -0
- package/dist/chunk-TYXB66FM.js +56 -0
- package/dist/chunk-UNCGZXPU.js +3556 -0
- package/dist/chunk-VAYBTLN4.js +50 -0
- package/dist/chunk-VGYL7CN2.js +260 -0
- package/dist/chunk-VIGJN5ZP.js +75 -0
- package/dist/chunk-WCFKKE7C.js +1921 -0
- package/dist/chunk-WEUOMPUC.js +346 -0
- package/dist/chunk-WRL6CIH2.js +262 -0
- package/dist/chunk-WS77NXRB.js +89 -0
- package/dist/chunk-XSRBNOLY.js +377 -0
- package/dist/chunk-XZLMH7QF.js +371 -0
- package/dist/chunk-YAITGMJO.js +89 -0
- package/dist/chunk-YDT3SUWK.js +171 -0
- package/dist/chunk-YG77F6MB.js +382 -0
- package/dist/chunk-YLWI3SAX.js +495 -0
- package/dist/chunk-YML4D7JL.js +818 -0
- package/dist/co-activation-V4G7RCBA.js +72 -0
- package/dist/co-occurrence-7AQY66CT.js +74 -0
- package/dist/code-context-index-GWAZ4PKV.js +30 -0
- package/dist/core-memory-FEVKN2AT.js +110 -0
- package/dist/core-memory-ISYNYO7T.js +110 -0
- package/dist/crdt-sync-INN5CLWY.js +33 -0
- package/dist/crm-webhook-2WGEYYAM.js +10 -0
- package/dist/crm-webhook-D7IORFLD.js +10 -0
- package/dist/cto-delegation-gate-2CMVCQW4.js +206 -0
- package/dist/cto-delegation-gate-DIMFA42F.js +206 -0
- package/dist/daemon-orchestration-G5HGOMGQ.js +135 -0
- package/dist/daemon-orchestration-IDK4LYVS.js +135 -0
- package/dist/db-backup-QDXIAYHX.js +33 -0
- package/dist/dreaming-A5QYLE67.js +32 -0
- package/dist/dreaming-CPFMD5SH.js +32 -0
- package/dist/entity-boost-BEVW2KFT.js +356 -0
- package/dist/exe-drift-Y6SN4EXZ.js +68 -0
- package/dist/exe-export-K4ZU3KZO.js +73 -0
- package/dist/exe-export-MZXEN45T.js +73 -0
- package/dist/exe-import-PWVIL5NW.js +76 -0
- package/dist/exe-import-R3AKAHWQ.js +76 -0
- package/dist/exe-key-BQVOD3YE.js +579 -0
- package/dist/exe-key-HXOWRGJT.js +579 -0
- package/dist/exe-snapshot-6URR2ANA.js +164 -0
- package/dist/exe-snapshot-C5JSC536.js +164 -0
- package/dist/fast-db-init-2CWMIQWR.js +7 -0
- package/dist/fast-db-init-UVZ2J5GS.js +7 -0
- package/dist/gateway/index.js +8 -8
- package/dist/git-staleness-VM6FPEQB.js +110 -0
- package/dist/git-task-sweep-ANHNEX7E.js +40 -0
- package/dist/git-task-sweep-R5BYJC3Y.js +40 -0
- package/dist/global-procedures-TLT6PO6L.js +20 -0
- package/dist/graph-auto-extract-BULI4PBB.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-worker.js +2 -2
- package/dist/hooks/ingest.js +6 -6
- package/dist/hooks/instructions-loaded.js +4 -4
- package/dist/hooks/manifest.json +20 -20
- package/dist/hooks/notification.js +4 -4
- package/dist/hooks/post-compact.js +10 -10
- package/dist/hooks/post-tool-combined.js +6 -6
- package/dist/hooks/pre-compact.js +13 -13
- package/dist/hooks/pre-tool-use.js +14 -14
- package/dist/hooks/prompt-submit.js +21 -21
- package/dist/hooks/session-end.js +18 -18
- package/dist/hooks/session-start.js +10 -10
- package/dist/hooks/stop.js +17 -17
- package/dist/hooks/subagent-stop.js +10 -10
- package/dist/hooks/summary-worker.js +16 -16
- package/dist/index.js +17 -17
- package/dist/installer-BEMMHBG5.js +342 -0
- package/dist/installer-CZWRBJ3Y.js +38 -0
- package/dist/installer-H43E54BM.js +38 -0
- package/dist/installer-HXKOP4YR.js +296 -0
- package/dist/installer-JAEYJUZW.js +342 -0
- package/dist/installer-ZPA6QLAX.js +296 -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 +1 -1
- package/dist/lib/db.js +2 -2
- package/dist/lib/embedder.js +2 -2
- package/dist/lib/employee-templates.js +4 -4
- package/dist/lib/employees.js +2 -2
- package/dist/lib/exe-daemon-client.js +1 -1
- package/dist/lib/exe-daemon.js +35 -35
- 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 +57 -57
- package/dist/mcp/server.js +58 -58
- 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-44D7MOF6.js +27 -0
- package/dist/mcp-http-config-TCDXI6LL.js +27 -0
- package/dist/memory-cards-NNFQKOQI.js +174 -0
- package/dist/memory-graph-extractor-6VIBIUZM.js +17 -0
- package/dist/memory-poisoning-defense-P6WG3SNX.js +225 -0
- package/dist/memory-queue-client-O57KWE6B.js +16 -0
- package/dist/memory-reflection-FDJQ5ZDA.js +238 -0
- package/dist/message-queue-client-NITLPOBU.js +92 -0
- package/dist/notifications-4NS7LYYR.js +45 -0
- package/dist/notifications-L4NHSF2U.js +45 -0
- package/dist/orchestration-events-SSAWHTVL.js +25 -0
- package/dist/orchestrator-P3BTGGVB.js +33 -0
- package/dist/orchestrator-WNQFM4DU.js +33 -0
- package/dist/pipeline-router-AYPUBNHD.js +13 -0
- package/dist/pipeline-router-I7SA5NCJ.js +13 -0
- package/dist/plan-limits-GW3HHMGQ.js +26 -0
- package/dist/project-boot-TLNZDC2S.js +299 -0
- package/dist/projection-worker-MZFBSWCU.js +964 -0
- package/dist/reranker-IP2FXTLK.js +19 -0
- package/dist/reranker-RZB6XAOK.js +19 -0
- package/dist/review-polling-PRKTKLVD.js +124 -0
- package/dist/review-polling-TLFRX3H3.js +124 -0
- package/dist/runtime/index.js +11 -11
- package/dist/session-events-SOGVDZH6.js +36 -0
- package/dist/session-events-WHSKIP26.js +36 -0
- package/dist/session-kill-telemetry-AHFZUYJG.js +29 -0
- package/dist/session-scope-DNCP34ND.js +86 -0
- package/dist/session-scope-YWB765YV.js +86 -0
- package/dist/setup-wizard-IZSKLVWW.js +12 -0
- package/dist/skill-refinement-34DIUMPK.js +157 -0
- package/dist/skill-refinement-KB7RN46L.js +157 -0
- package/dist/stack-update-PQGX7KLH.js +52 -0
- package/dist/steward-gate-GX35HOTT.js +13 -0
- package/dist/task-enforcement-7NLUA7NZ.js +333 -0
- package/dist/task-enforcement-CO3UKUD3.js +333 -0
- package/dist/task-scope-4NTALPYO.js +35 -0
- package/dist/task-scope-J4QQT3DP.js +35 -0
- package/dist/tasks-crud-OJNNAL4F.js +77 -0
- package/dist/tasks-crud-T5DP4DUU.js +77 -0
- package/dist/tasks-notify-22255SAJ.js +38 -0
- package/dist/tasks-notify-ZVA4WIY5.js +38 -0
- package/dist/tasks-review-HMSWMG5X.js +47 -0
- package/dist/tasks-review-ODCDMDYP.js +47 -0
- package/dist/telemetry-upload-LCDD763H.js +739 -0
- package/dist/telemetry-upload-ZJOGSCD3.js +739 -0
- package/dist/token-budget-KQDJ5ZE5.js +84 -0
- package/dist/tool-capability-index-ZDDBVQT5.js +10 -0
- package/dist/tool-telemetry-AAUJQIIB.js +17 -0
- package/dist/tui/App.js +16 -16
- package/dist/tui-data-OYJAJYE4.js +258 -0
- package/dist/tui-data-QFMDLK6B.js +258 -0
- package/dist/wiki-acl-SH3BRQC2.js +111 -0
- package/dist/worker-gate-C366DEJR.js +21 -0
- package/dist/worker-gate-UZKHTBG7.js +21 -0
- package/dist/workflow-engine-5WGLCTKB.js +28 -0
- package/dist/workflow-engine-LNQ6G5E2.js +28 -0
- package/dist/worktree-BD7NDIDS.js +26 -0
- package/dist/worktree-sweep-6QFFMZUV.js +19 -0
- package/package.json +2 -2
- package/release-notes.json +30 -13
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import {
|
|
2
|
+
lightweightSearch
|
|
3
|
+
} from "./chunk-QIEJRCF3.js";
|
|
4
|
+
import "./chunk-YML4D7JL.js";
|
|
5
|
+
import "./chunk-CHCA3ZM2.js";
|
|
6
|
+
import "./chunk-OVQOKLYA.js";
|
|
7
|
+
import "./chunk-Y25OJWOQ.js";
|
|
8
|
+
import {
|
|
9
|
+
sessionScopeFilter,
|
|
10
|
+
strictSessionScopeFilter
|
|
11
|
+
} from "./chunk-32RG5ZJN.js";
|
|
12
|
+
import "./chunk-A3G4UXNA.js";
|
|
13
|
+
import "./chunk-5CHYEKMH.js";
|
|
14
|
+
import "./chunk-4JERP7NT.js";
|
|
15
|
+
import "./chunk-TSBMSHMM.js";
|
|
16
|
+
import "./chunk-MVW62NIZ.js";
|
|
17
|
+
import "./chunk-OYNKIAVW.js";
|
|
18
|
+
import "./chunk-CX6GL3ZJ.js";
|
|
19
|
+
import "./chunk-XIT6ONPY.js";
|
|
20
|
+
import "./chunk-XJUUWHVN.js";
|
|
21
|
+
import "./chunk-NGP6LSV2.js";
|
|
22
|
+
import "./chunk-C4BIYP5C.js";
|
|
23
|
+
import "./chunk-CVYC6DUW.js";
|
|
24
|
+
import "./chunk-OPU3NYOO.js";
|
|
25
|
+
import "./chunk-GJV3WDWM.js";
|
|
26
|
+
import "./chunk-MP2AFCGL.js";
|
|
27
|
+
import "./chunk-VF6VT4MR.js";
|
|
28
|
+
import "./chunk-HYZV25LY.js";
|
|
29
|
+
import {
|
|
30
|
+
getClient
|
|
31
|
+
} from "./chunk-RHZ2CRJU.js";
|
|
32
|
+
import "./chunk-2I23RPSI.js";
|
|
33
|
+
import "./chunk-P2DOIWQG.js";
|
|
34
|
+
import "./chunk-FXU7JOXK.js";
|
|
35
|
+
import "./chunk-K333WOW4.js";
|
|
36
|
+
import "./chunk-MOZ2YQ54.js";
|
|
37
|
+
import "./chunk-VXIMSRTO.js";
|
|
38
|
+
import "./chunk-LYH5HE24.js";
|
|
39
|
+
import "./chunk-MLKGABMK.js";
|
|
40
|
+
|
|
41
|
+
// src/lib/catchup-brief.ts
|
|
42
|
+
import { execSync } from "child_process";
|
|
43
|
+
var HEADER = "## Catchup Brief\nHere's what happened while you were offline:";
|
|
44
|
+
var DEFAULT_LOOKBACK_MS = 60 * 60 * 1e3;
|
|
45
|
+
var MAX_BRIEF_CHARS = 2e3;
|
|
46
|
+
var MAX_CHECKPOINT_CHARS = 500;
|
|
47
|
+
var MAX_MESSAGE_CHARS = 100;
|
|
48
|
+
function clipText(text, maxChars) {
|
|
49
|
+
if (text.length <= maxChars) return text;
|
|
50
|
+
if (maxChars <= 1) return "\u2026";
|
|
51
|
+
return `${text.slice(0, maxChars - 1).trimEnd()}\u2026`;
|
|
52
|
+
}
|
|
53
|
+
function clampSections(header, sections, maxChars) {
|
|
54
|
+
const bounded = [];
|
|
55
|
+
let remaining = Math.max(0, maxChars - header.length);
|
|
56
|
+
for (const section of sections) {
|
|
57
|
+
const separatorChars = 2;
|
|
58
|
+
if (remaining <= separatorChars) break;
|
|
59
|
+
remaining -= separatorChars;
|
|
60
|
+
if (section.length <= remaining) {
|
|
61
|
+
bounded.push(section);
|
|
62
|
+
remaining -= section.length;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const clipped = clipText(section, remaining);
|
|
66
|
+
if (clipped.trim().length > 0) bounded.push(clipped);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
return bounded;
|
|
70
|
+
}
|
|
71
|
+
async function buildCatchupBrief(agentId, projectName, cwd, sessionScope) {
|
|
72
|
+
const sections = [];
|
|
73
|
+
let lastTimestamp = new Date(Date.now() - DEFAULT_LOOKBACK_MS).toISOString();
|
|
74
|
+
try {
|
|
75
|
+
const checkpointMemories = await lightweightSearch(
|
|
76
|
+
"CONTEXT CHECKPOINT",
|
|
77
|
+
agentId,
|
|
78
|
+
{ projectName, limit: 1 }
|
|
79
|
+
);
|
|
80
|
+
const checkpoint = checkpointMemories[0];
|
|
81
|
+
if (checkpoint?.timestamp) {
|
|
82
|
+
lastTimestamp = checkpoint.timestamp;
|
|
83
|
+
}
|
|
84
|
+
if (checkpoint?.raw_text) {
|
|
85
|
+
sections.push(
|
|
86
|
+
`### Last Checkpoint
|
|
87
|
+
${clipText(checkpoint.raw_text, MAX_CHECKPOINT_CHARS)}`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
} catch {
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
const gitLog = execSync(
|
|
94
|
+
`git log --oneline --since=${JSON.stringify(lastTimestamp)} --format="%h %an: %s" | head -10`,
|
|
95
|
+
{ cwd, timeout: 3e3, encoding: "utf-8" }
|
|
96
|
+
).trim();
|
|
97
|
+
if (gitLog) {
|
|
98
|
+
sections.push(`### Git Activity Since You Left
|
|
99
|
+
\`\`\`
|
|
100
|
+
${gitLog}
|
|
101
|
+
\`\`\``);
|
|
102
|
+
}
|
|
103
|
+
} catch {
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const client = getClient();
|
|
107
|
+
const taskScope = sessionScopeFilter(sessionScope);
|
|
108
|
+
const taskChanges = await client.execute({
|
|
109
|
+
sql: `SELECT title, status, priority FROM tasks
|
|
110
|
+
WHERE assigned_to = ? AND project_name = ?
|
|
111
|
+
AND updated_at > ? AND status IN ('open', 'in_progress')${taskScope.sql}
|
|
112
|
+
ORDER BY priority ASC, updated_at DESC LIMIT 5`,
|
|
113
|
+
args: [agentId, projectName, lastTimestamp, ...taskScope.args]
|
|
114
|
+
});
|
|
115
|
+
if (taskChanges.rows.length > 0) {
|
|
116
|
+
const taskLines = taskChanges.rows.map((row) => {
|
|
117
|
+
const record = row;
|
|
118
|
+
return `- [${String(record.priority).toUpperCase()}] ${String(record.title)} (${String(record.status)})`;
|
|
119
|
+
}).join("\n");
|
|
120
|
+
sections.push(`### Your Task Queue
|
|
121
|
+
${taskLines}`);
|
|
122
|
+
}
|
|
123
|
+
} catch {
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const client = getClient();
|
|
127
|
+
const messageScope = strictSessionScopeFilter(sessionScope);
|
|
128
|
+
const messages = await client.execute({
|
|
129
|
+
sql: `SELECT from_agent, content, created_at FROM messages
|
|
130
|
+
WHERE target_agent = ? AND status = 'pending'${messageScope.sql}
|
|
131
|
+
ORDER BY created_at DESC LIMIT 3`,
|
|
132
|
+
args: [agentId, ...messageScope.args]
|
|
133
|
+
});
|
|
134
|
+
if (messages.rows.length > 0) {
|
|
135
|
+
const msgLines = messages.rows.map((row) => {
|
|
136
|
+
const record = row;
|
|
137
|
+
return `- From ${String(record.from_agent)}: ${clipText(String(record.content ?? ""), MAX_MESSAGE_CHARS)}`;
|
|
138
|
+
}).join("\n");
|
|
139
|
+
sections.push(`### Unread Messages
|
|
140
|
+
${msgLines}`);
|
|
141
|
+
}
|
|
142
|
+
} catch {
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
header: HEADER,
|
|
146
|
+
sections: clampSections(HEADER, sections, MAX_BRIEF_CHARS)
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
export {
|
|
150
|
+
buildCatchupBrief
|
|
151
|
+
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import {
|
|
2
|
+
lightweightSearch
|
|
3
|
+
} from "./chunk-HYI4PN4J.js";
|
|
4
|
+
import "./chunk-5MOYMGS5.js";
|
|
5
|
+
import "./chunk-CHCA3ZM2.js";
|
|
6
|
+
import "./chunk-RSIDQBIG.js";
|
|
7
|
+
import "./chunk-Y25OJWOQ.js";
|
|
8
|
+
import {
|
|
9
|
+
sessionScopeFilter,
|
|
10
|
+
strictSessionScopeFilter
|
|
11
|
+
} from "./chunk-BXY5Y3RI.js";
|
|
12
|
+
import "./chunk-SD6UFZRH.js";
|
|
13
|
+
import "./chunk-5CHYEKMH.js";
|
|
14
|
+
import "./chunk-4JERP7NT.js";
|
|
15
|
+
import "./chunk-GQ2XYRG3.js";
|
|
16
|
+
import "./chunk-MVW62NIZ.js";
|
|
17
|
+
import "./chunk-OYNKIAVW.js";
|
|
18
|
+
import "./chunk-CX6GL3ZJ.js";
|
|
19
|
+
import "./chunk-JP45GCVR.js";
|
|
20
|
+
import "./chunk-XJUUWHVN.js";
|
|
21
|
+
import "./chunk-NGP6LSV2.js";
|
|
22
|
+
import "./chunk-7SLLNRR3.js";
|
|
23
|
+
import "./chunk-CVYC6DUW.js";
|
|
24
|
+
import "./chunk-OPU3NYOO.js";
|
|
25
|
+
import "./chunk-GJV3WDWM.js";
|
|
26
|
+
import "./chunk-MP2AFCGL.js";
|
|
27
|
+
import "./chunk-TN45CTOI.js";
|
|
28
|
+
import "./chunk-HYZV25LY.js";
|
|
29
|
+
import {
|
|
30
|
+
getClient
|
|
31
|
+
} from "./chunk-UNCGZXPU.js";
|
|
32
|
+
import "./chunk-2I23RPSI.js";
|
|
33
|
+
import "./chunk-VGYL7CN2.js";
|
|
34
|
+
import "./chunk-FXU7JOXK.js";
|
|
35
|
+
import "./chunk-K333WOW4.js";
|
|
36
|
+
import "./chunk-MOZ2YQ54.js";
|
|
37
|
+
import "./chunk-VXIMSRTO.js";
|
|
38
|
+
import "./chunk-LYH5HE24.js";
|
|
39
|
+
import "./chunk-MLKGABMK.js";
|
|
40
|
+
|
|
41
|
+
// src/lib/catchup-brief.ts
|
|
42
|
+
import { execSync } from "child_process";
|
|
43
|
+
var HEADER = "## Catchup Brief\nHere's what happened while you were offline:";
|
|
44
|
+
var DEFAULT_LOOKBACK_MS = 60 * 60 * 1e3;
|
|
45
|
+
var MAX_BRIEF_CHARS = 2e3;
|
|
46
|
+
var MAX_CHECKPOINT_CHARS = 500;
|
|
47
|
+
var MAX_MESSAGE_CHARS = 100;
|
|
48
|
+
function clipText(text, maxChars) {
|
|
49
|
+
if (text.length <= maxChars) return text;
|
|
50
|
+
if (maxChars <= 1) return "\u2026";
|
|
51
|
+
return `${text.slice(0, maxChars - 1).trimEnd()}\u2026`;
|
|
52
|
+
}
|
|
53
|
+
function clampSections(header, sections, maxChars) {
|
|
54
|
+
const bounded = [];
|
|
55
|
+
let remaining = Math.max(0, maxChars - header.length);
|
|
56
|
+
for (const section of sections) {
|
|
57
|
+
const separatorChars = 2;
|
|
58
|
+
if (remaining <= separatorChars) break;
|
|
59
|
+
remaining -= separatorChars;
|
|
60
|
+
if (section.length <= remaining) {
|
|
61
|
+
bounded.push(section);
|
|
62
|
+
remaining -= section.length;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const clipped = clipText(section, remaining);
|
|
66
|
+
if (clipped.trim().length > 0) bounded.push(clipped);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
return bounded;
|
|
70
|
+
}
|
|
71
|
+
async function buildCatchupBrief(agentId, projectName, cwd, sessionScope) {
|
|
72
|
+
const sections = [];
|
|
73
|
+
let lastTimestamp = new Date(Date.now() - DEFAULT_LOOKBACK_MS).toISOString();
|
|
74
|
+
try {
|
|
75
|
+
const checkpointMemories = await lightweightSearch(
|
|
76
|
+
"CONTEXT CHECKPOINT",
|
|
77
|
+
agentId,
|
|
78
|
+
{ projectName, limit: 1 }
|
|
79
|
+
);
|
|
80
|
+
const checkpoint = checkpointMemories[0];
|
|
81
|
+
if (checkpoint?.timestamp) {
|
|
82
|
+
lastTimestamp = checkpoint.timestamp;
|
|
83
|
+
}
|
|
84
|
+
if (checkpoint?.raw_text) {
|
|
85
|
+
sections.push(
|
|
86
|
+
`### Last Checkpoint
|
|
87
|
+
${clipText(checkpoint.raw_text, MAX_CHECKPOINT_CHARS)}`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
} catch {
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
const gitLog = execSync(
|
|
94
|
+
`git log --oneline --since=${JSON.stringify(lastTimestamp)} --format="%h %an: %s" | head -10`,
|
|
95
|
+
{ cwd, timeout: 3e3, encoding: "utf-8" }
|
|
96
|
+
).trim();
|
|
97
|
+
if (gitLog) {
|
|
98
|
+
sections.push(`### Git Activity Since You Left
|
|
99
|
+
\`\`\`
|
|
100
|
+
${gitLog}
|
|
101
|
+
\`\`\``);
|
|
102
|
+
}
|
|
103
|
+
} catch {
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const client = getClient();
|
|
107
|
+
const taskScope = sessionScopeFilter(sessionScope);
|
|
108
|
+
const taskChanges = await client.execute({
|
|
109
|
+
sql: `SELECT title, status, priority FROM tasks
|
|
110
|
+
WHERE assigned_to = ? AND project_name = ?
|
|
111
|
+
AND updated_at > ? AND status IN ('open', 'in_progress')${taskScope.sql}
|
|
112
|
+
ORDER BY priority ASC, updated_at DESC LIMIT 5`,
|
|
113
|
+
args: [agentId, projectName, lastTimestamp, ...taskScope.args]
|
|
114
|
+
});
|
|
115
|
+
if (taskChanges.rows.length > 0) {
|
|
116
|
+
const taskLines = taskChanges.rows.map((row) => {
|
|
117
|
+
const record = row;
|
|
118
|
+
return `- [${String(record.priority).toUpperCase()}] ${String(record.title)} (${String(record.status)})`;
|
|
119
|
+
}).join("\n");
|
|
120
|
+
sections.push(`### Your Task Queue
|
|
121
|
+
${taskLines}`);
|
|
122
|
+
}
|
|
123
|
+
} catch {
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const client = getClient();
|
|
127
|
+
const messageScope = strictSessionScopeFilter(sessionScope);
|
|
128
|
+
const messages = await client.execute({
|
|
129
|
+
sql: `SELECT from_agent, content, created_at FROM messages
|
|
130
|
+
WHERE target_agent = ? AND status = 'pending'${messageScope.sql}
|
|
131
|
+
ORDER BY created_at DESC LIMIT 3`,
|
|
132
|
+
args: [agentId, ...messageScope.args]
|
|
133
|
+
});
|
|
134
|
+
if (messages.rows.length > 0) {
|
|
135
|
+
const msgLines = messages.rows.map((row) => {
|
|
136
|
+
const record = row;
|
|
137
|
+
return `- From ${String(record.from_agent)}: ${clipText(String(record.content ?? ""), MAX_MESSAGE_CHARS)}`;
|
|
138
|
+
}).join("\n");
|
|
139
|
+
sections.push(`### Unread Messages
|
|
140
|
+
${msgLines}`);
|
|
141
|
+
}
|
|
142
|
+
} catch {
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
header: HEADER,
|
|
146
|
+
sections: clampSections(HEADER, sections, MAX_BRIEF_CHARS)
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
export {
|
|
150
|
+
buildCatchupBrief
|
|
151
|
+
};
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getClient
|
|
3
|
+
} from "./chunk-UNCGZXPU.js";
|
|
4
|
+
|
|
5
|
+
// src/lib/token-spend.ts
|
|
6
|
+
import { readdir, stat } from "fs/promises";
|
|
7
|
+
import { createReadStream } from "fs";
|
|
8
|
+
import { createInterface } from "readline";
|
|
9
|
+
import path from "path";
|
|
10
|
+
import os from "os";
|
|
11
|
+
var MODEL_PRICING = {
|
|
12
|
+
// Opus 4.5+ ($5/$25 — Anthropic price drop from original Opus 4)
|
|
13
|
+
"claude-opus-4-7": { input: 5 / 1e6, output: 25 / 1e6, cacheRead: 0.5 / 1e6, cacheWrite: 6.25 / 1e6 },
|
|
14
|
+
"claude-opus-4-6": { input: 5 / 1e6, output: 25 / 1e6, cacheRead: 0.5 / 1e6, cacheWrite: 6.25 / 1e6 },
|
|
15
|
+
"claude-opus-4-5": { input: 5 / 1e6, output: 25 / 1e6, cacheRead: 0.5 / 1e6, cacheWrite: 6.25 / 1e6 },
|
|
16
|
+
// Opus 4.0/4.1 (legacy $15/$75)
|
|
17
|
+
"claude-opus-4-1": { input: 15 / 1e6, output: 75 / 1e6, cacheRead: 1.5 / 1e6, cacheWrite: 18.75 / 1e6 },
|
|
18
|
+
"claude-opus-4": { input: 15 / 1e6, output: 75 / 1e6, cacheRead: 1.5 / 1e6, cacheWrite: 18.75 / 1e6 },
|
|
19
|
+
// Sonnet 4.x
|
|
20
|
+
"claude-sonnet-4": { input: 3 / 1e6, output: 15 / 1e6, cacheRead: 0.3 / 1e6, cacheWrite: 3.75 / 1e6 },
|
|
21
|
+
// Sonnet 3.7/3.5
|
|
22
|
+
"claude-3-7-sonnet": { input: 3 / 1e6, output: 15 / 1e6, cacheRead: 0.3 / 1e6, cacheWrite: 3.75 / 1e6 },
|
|
23
|
+
"claude-3-5-sonnet": { input: 3 / 1e6, output: 15 / 1e6, cacheRead: 0.3 / 1e6, cacheWrite: 3.75 / 1e6 },
|
|
24
|
+
// Haiku 4.5
|
|
25
|
+
"claude-haiku-4-5": { input: 1 / 1e6, output: 5 / 1e6, cacheRead: 0.1 / 1e6, cacheWrite: 1.25 / 1e6 },
|
|
26
|
+
// Haiku 3.5
|
|
27
|
+
"claude-3-5-haiku": { input: 0.8 / 1e6, output: 4 / 1e6, cacheRead: 0.08 / 1e6, cacheWrite: 1 / 1e6 },
|
|
28
|
+
// Opus 3
|
|
29
|
+
"claude-3-opus": { input: 15 / 1e6, output: 75 / 1e6, cacheRead: 1.5 / 1e6, cacheWrite: 18.75 / 1e6 },
|
|
30
|
+
// Sonnet 3
|
|
31
|
+
"claude-3-sonnet": { input: 3 / 1e6, output: 15 / 1e6, cacheRead: 0.3 / 1e6, cacheWrite: 3.75 / 1e6 },
|
|
32
|
+
// Haiku 3
|
|
33
|
+
"claude-3-haiku": { input: 0.25 / 1e6, output: 1.25 / 1e6, cacheRead: 0.03 / 1e6, cacheWrite: 0.3 / 1e6 }
|
|
34
|
+
};
|
|
35
|
+
var DEFAULT_PRICING = MODEL_PRICING["claude-sonnet-4"];
|
|
36
|
+
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
37
|
+
var JSONL_INDEX_TTL_MS = 5 * 60 * 1e3;
|
|
38
|
+
var USAGE_CACHE_MAX_ENTRIES = 1e4;
|
|
39
|
+
var _spendCache = /* @__PURE__ */ new Map();
|
|
40
|
+
var _spendInFlight = /* @__PURE__ */ new Map();
|
|
41
|
+
var _usageCache = /* @__PURE__ */ new Map();
|
|
42
|
+
var _usageInFlight = /* @__PURE__ */ new Map();
|
|
43
|
+
var _jsonlPathIndex = null;
|
|
44
|
+
function yieldToEventLoop() {
|
|
45
|
+
return new Promise((resolve) => setImmediate(resolve));
|
|
46
|
+
}
|
|
47
|
+
function getPricing(model) {
|
|
48
|
+
if (MODEL_PRICING[model]) return MODEL_PRICING[model];
|
|
49
|
+
const stripped = model.replace(/-\d{8}$/, "");
|
|
50
|
+
if (MODEL_PRICING[stripped]) return MODEL_PRICING[stripped];
|
|
51
|
+
const sortedKeys = Object.keys(MODEL_PRICING).sort((a, b) => b.length - a.length);
|
|
52
|
+
for (const key of sortedKeys) {
|
|
53
|
+
if (model.includes(key)) return MODEL_PRICING[key];
|
|
54
|
+
}
|
|
55
|
+
return DEFAULT_PRICING;
|
|
56
|
+
}
|
|
57
|
+
async function getAgentSpend(period = "7d") {
|
|
58
|
+
const cached = _spendCache.get(period);
|
|
59
|
+
if (cached && Date.now() < cached.expires) {
|
|
60
|
+
return cached.result;
|
|
61
|
+
}
|
|
62
|
+
const inFlight = _spendInFlight.get(period);
|
|
63
|
+
if (inFlight) return inFlight;
|
|
64
|
+
const promise = computeAgentSpend(period).finally(() => _spendInFlight.delete(period));
|
|
65
|
+
_spendInFlight.set(period, promise);
|
|
66
|
+
return promise;
|
|
67
|
+
}
|
|
68
|
+
async function computeAgentSpend(period) {
|
|
69
|
+
const cutoff = periodToCutoff(period);
|
|
70
|
+
const client = getClient();
|
|
71
|
+
const dbResult = await client.execute({
|
|
72
|
+
sql: `SELECT session_uuid, agent_id FROM session_agent_map WHERE started_at >= ?`,
|
|
73
|
+
args: [cutoff]
|
|
74
|
+
});
|
|
75
|
+
if (dbResult.rows.length === 0) return [];
|
|
76
|
+
const sessionAgent = /* @__PURE__ */ new Map();
|
|
77
|
+
for (const row of dbResult.rows) {
|
|
78
|
+
sessionAgent.set(row.session_uuid, row.agent_id);
|
|
79
|
+
}
|
|
80
|
+
const jsonlPaths = await getClaudeSessionJsonlIndex();
|
|
81
|
+
if (jsonlPaths.size === 0) return [];
|
|
82
|
+
const agentTotals = /* @__PURE__ */ new Map();
|
|
83
|
+
let processed = 0;
|
|
84
|
+
for (const [sessionUuid, agentId] of sessionAgent) {
|
|
85
|
+
const jsonlPath = jsonlPaths.get(sessionUuid);
|
|
86
|
+
if (!jsonlPath) continue;
|
|
87
|
+
try {
|
|
88
|
+
const usage = await extractSessionUsageCached(jsonlPath);
|
|
89
|
+
if (usage.input === 0 && usage.output === 0) continue;
|
|
90
|
+
const totals = agentTotals.get(agentId) ?? {
|
|
91
|
+
input: 0,
|
|
92
|
+
output: 0,
|
|
93
|
+
cacheRead: 0,
|
|
94
|
+
cacheCreate: 0,
|
|
95
|
+
costUSD: 0,
|
|
96
|
+
sessions: /* @__PURE__ */ new Set()
|
|
97
|
+
};
|
|
98
|
+
totals.input += usage.input;
|
|
99
|
+
totals.output += usage.output;
|
|
100
|
+
totals.cacheRead += usage.cacheRead;
|
|
101
|
+
totals.cacheCreate += usage.cacheCreate;
|
|
102
|
+
totals.costUSD += usage.costUSD;
|
|
103
|
+
totals.sessions.add(sessionUuid);
|
|
104
|
+
agentTotals.set(agentId, totals);
|
|
105
|
+
} catch {
|
|
106
|
+
}
|
|
107
|
+
processed++;
|
|
108
|
+
if (processed % 25 === 0) await yieldToEventLoop();
|
|
109
|
+
}
|
|
110
|
+
const result = Array.from(agentTotals.entries()).map(([agentId, t]) => ({
|
|
111
|
+
agentId,
|
|
112
|
+
inputTokens: t.input,
|
|
113
|
+
outputTokens: t.output,
|
|
114
|
+
cacheReadTokens: t.cacheRead,
|
|
115
|
+
cacheCreationTokens: t.cacheCreate,
|
|
116
|
+
costUSD: t.costUSD,
|
|
117
|
+
sessions: t.sessions.size,
|
|
118
|
+
period
|
|
119
|
+
})).sort((a, b) => b.costUSD - a.costUSD);
|
|
120
|
+
_spendCache.set(period, { result, expires: Date.now() + CACHE_TTL_MS });
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
async function getClaudeSessionJsonlIndex() {
|
|
124
|
+
if (_jsonlPathIndex && Date.now() < _jsonlPathIndex.expires) {
|
|
125
|
+
return _jsonlPathIndex.paths;
|
|
126
|
+
}
|
|
127
|
+
const claudeDir = path.join(os.homedir(), ".claude", "projects");
|
|
128
|
+
const paths = /* @__PURE__ */ new Map();
|
|
129
|
+
let projectDirs = [];
|
|
130
|
+
try {
|
|
131
|
+
const entries = await readdir(claudeDir, { withFileTypes: true });
|
|
132
|
+
projectDirs = entries.filter((entry) => entry.isDirectory()).map((entry) => path.join(claudeDir, entry.name));
|
|
133
|
+
} catch {
|
|
134
|
+
_jsonlPathIndex = { expires: Date.now() + JSONL_INDEX_TTL_MS, paths };
|
|
135
|
+
return paths;
|
|
136
|
+
}
|
|
137
|
+
let scanned = 0;
|
|
138
|
+
for (const dir of projectDirs) {
|
|
139
|
+
try {
|
|
140
|
+
const files = await readdir(dir);
|
|
141
|
+
for (const file of files) {
|
|
142
|
+
if (!file.endsWith(".jsonl")) continue;
|
|
143
|
+
paths.set(file.slice(0, -".jsonl".length), path.join(dir, file));
|
|
144
|
+
}
|
|
145
|
+
} catch {
|
|
146
|
+
}
|
|
147
|
+
scanned++;
|
|
148
|
+
if (scanned % 25 === 0) await yieldToEventLoop();
|
|
149
|
+
}
|
|
150
|
+
_jsonlPathIndex = { expires: Date.now() + JSONL_INDEX_TTL_MS, paths };
|
|
151
|
+
return paths;
|
|
152
|
+
}
|
|
153
|
+
async function extractSessionUsageCached(jsonlPath) {
|
|
154
|
+
const st = await stat(jsonlPath);
|
|
155
|
+
const cached = _usageCache.get(jsonlPath);
|
|
156
|
+
if (cached && cached.mtimeMs === st.mtimeMs && cached.size === st.size) {
|
|
157
|
+
return cached.usage;
|
|
158
|
+
}
|
|
159
|
+
const existing = _usageInFlight.get(jsonlPath);
|
|
160
|
+
if (existing) return existing;
|
|
161
|
+
const promise = extractSessionUsage(jsonlPath).then((usage) => {
|
|
162
|
+
_usageCache.set(jsonlPath, { mtimeMs: st.mtimeMs, size: st.size, usage });
|
|
163
|
+
pruneUsageCache();
|
|
164
|
+
return usage;
|
|
165
|
+
}).finally(() => _usageInFlight.delete(jsonlPath));
|
|
166
|
+
_usageInFlight.set(jsonlPath, promise);
|
|
167
|
+
return promise;
|
|
168
|
+
}
|
|
169
|
+
function pruneUsageCache() {
|
|
170
|
+
if (_usageCache.size <= USAGE_CACHE_MAX_ENTRIES) return;
|
|
171
|
+
const overflow = _usageCache.size - USAGE_CACHE_MAX_ENTRIES;
|
|
172
|
+
let removed = 0;
|
|
173
|
+
for (const key of _usageCache.keys()) {
|
|
174
|
+
_usageCache.delete(key);
|
|
175
|
+
removed++;
|
|
176
|
+
if (removed >= overflow) break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async function extractSessionUsage(jsonlPath) {
|
|
180
|
+
let input = 0;
|
|
181
|
+
let output = 0;
|
|
182
|
+
let cacheRead = 0;
|
|
183
|
+
let cacheCreate = 0;
|
|
184
|
+
let costUSD = 0;
|
|
185
|
+
const seenMessageIds = /* @__PURE__ */ new Set();
|
|
186
|
+
const rl = createInterface({
|
|
187
|
+
input: createReadStream(jsonlPath, { encoding: "utf8" }),
|
|
188
|
+
crlfDelay: Infinity
|
|
189
|
+
});
|
|
190
|
+
for await (const line of rl) {
|
|
191
|
+
if (!line.includes('"type":"assistant"')) continue;
|
|
192
|
+
try {
|
|
193
|
+
const record = JSON.parse(line);
|
|
194
|
+
if (record.type !== "assistant") continue;
|
|
195
|
+
const messageId = record.message?.id;
|
|
196
|
+
if (messageId) {
|
|
197
|
+
if (seenMessageIds.has(messageId)) continue;
|
|
198
|
+
seenMessageIds.add(messageId);
|
|
199
|
+
}
|
|
200
|
+
const usage = record.message?.usage;
|
|
201
|
+
if (!usage) continue;
|
|
202
|
+
const model = record.message?.model ?? "";
|
|
203
|
+
const pricing = getPricing(model);
|
|
204
|
+
const inp = usage.input_tokens ?? 0;
|
|
205
|
+
const out = usage.output_tokens ?? 0;
|
|
206
|
+
const cr = usage.cache_read_input_tokens ?? 0;
|
|
207
|
+
const cc = usage.cache_creation_input_tokens ?? 0;
|
|
208
|
+
input += inp;
|
|
209
|
+
output += out;
|
|
210
|
+
cacheRead += cr;
|
|
211
|
+
cacheCreate += cc;
|
|
212
|
+
if (pricing) {
|
|
213
|
+
costUSD += inp * pricing.input + out * pricing.output + cr * pricing.cacheRead + cc * pricing.cacheWrite;
|
|
214
|
+
}
|
|
215
|
+
} catch {
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return { input, output, cacheRead, cacheCreate, costUSD };
|
|
219
|
+
}
|
|
220
|
+
function periodToCutoff(period) {
|
|
221
|
+
const ms = { "24h": 864e5, "7d": 6048e5, "30d": 2592e6 }[period];
|
|
222
|
+
return new Date(Date.now() - ms).toISOString();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export {
|
|
226
|
+
getAgentSpend
|
|
227
|
+
};
|