@rulemetric/cli 0.2.1 → 0.2.3
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/base-command.js +13 -52
- package/dist/base-command.js.map +7 -1
- package/dist/chunk-2AM54TUK.js +59 -0
- package/dist/chunk-2AM54TUK.js.map +7 -0
- package/dist/chunk-3TIMQ3O6.js +96 -0
- package/dist/chunk-3TIMQ3O6.js.map +7 -0
- package/dist/chunk-4BHDHHKL.js +48 -0
- package/dist/chunk-4BHDHHKL.js.map +7 -0
- package/dist/chunk-4D537GXE.js +99 -0
- package/dist/chunk-4D537GXE.js.map +7 -0
- package/dist/chunk-4SCZK7AL.js +129 -0
- package/dist/chunk-4SCZK7AL.js.map +7 -0
- package/dist/chunk-4WFE4PFP.js +61 -0
- package/dist/chunk-4WFE4PFP.js.map +7 -0
- package/dist/chunk-52WIYRZH.js +73 -0
- package/dist/chunk-52WIYRZH.js.map +7 -0
- package/dist/chunk-7FAA3YNB.js +1549 -0
- package/dist/chunk-7FAA3YNB.js.map +7 -0
- package/dist/chunk-7NYKWN7U.js +12 -0
- package/dist/chunk-7NYKWN7U.js.map +7 -0
- package/dist/chunk-AULP2OWH.js +99 -0
- package/dist/chunk-AULP2OWH.js.map +7 -0
- package/dist/chunk-B5KNTGMJ.js +1788 -0
- package/dist/chunk-B5KNTGMJ.js.map +7 -0
- package/dist/chunk-BD7CY42U.js +23 -0
- package/dist/chunk-BD7CY42U.js.map +7 -0
- package/dist/chunk-BO76WKJR.js +42 -0
- package/dist/chunk-BO76WKJR.js.map +7 -0
- package/dist/chunk-BRD5RUGM.js +53 -0
- package/dist/chunk-BRD5RUGM.js.map +7 -0
- package/dist/chunk-BT6Z6545.js +43 -0
- package/dist/chunk-BT6Z6545.js.map +7 -0
- package/dist/chunk-BZDKEQKU.js +39 -0
- package/dist/chunk-BZDKEQKU.js.map +7 -0
- package/dist/chunk-CROYS75W.js +161 -0
- package/dist/chunk-CROYS75W.js.map +7 -0
- package/dist/chunk-DGHWRQXL.js +17 -0
- package/dist/chunk-DGHWRQXL.js.map +7 -0
- package/dist/chunk-DQ3KELXD.js +74 -0
- package/dist/chunk-DQ3KELXD.js.map +7 -0
- package/dist/chunk-DTFXCHHI.js +108 -0
- package/dist/chunk-DTFXCHHI.js.map +7 -0
- package/dist/chunk-DU73QUS3.js +75 -0
- package/dist/chunk-DU73QUS3.js.map +7 -0
- package/dist/chunk-EHZJ6OXD.js +307 -0
- package/dist/chunk-EHZJ6OXD.js.map +7 -0
- package/dist/chunk-EJOI2ZGU.js +109 -0
- package/dist/chunk-EJOI2ZGU.js.map +7 -0
- package/dist/chunk-EKJ2CABV.js +76 -0
- package/dist/chunk-EKJ2CABV.js.map +7 -0
- package/dist/chunk-EKP32DLN.js +16 -0
- package/dist/chunk-EKP32DLN.js.map +7 -0
- package/dist/chunk-EOOP6WTC.js +148 -0
- package/dist/chunk-EOOP6WTC.js.map +7 -0
- package/dist/chunk-ERPMDAO3.js +20 -0
- package/dist/chunk-ERPMDAO3.js.map +7 -0
- package/dist/chunk-FTJRMUID.js +96 -0
- package/dist/chunk-FTJRMUID.js.map +7 -0
- package/dist/chunk-FZKLLNDS.js +228 -0
- package/dist/chunk-FZKLLNDS.js.map +7 -0
- package/dist/chunk-GQCISMAH.js +157 -0
- package/dist/chunk-GQCISMAH.js.map +7 -0
- package/dist/chunk-IGXX624H.js +55 -0
- package/dist/chunk-IGXX624H.js.map +7 -0
- package/dist/chunk-IJGF2ETG.js +68 -0
- package/dist/chunk-IJGF2ETG.js.map +7 -0
- package/dist/chunk-IWYCRLEK.js +220 -0
- package/dist/chunk-IWYCRLEK.js.map +7 -0
- package/dist/chunk-J7N3DLH6.js +117 -0
- package/dist/chunk-J7N3DLH6.js.map +7 -0
- package/dist/chunk-JX5UI6RW.js +99 -0
- package/dist/chunk-JX5UI6RW.js.map +7 -0
- package/dist/chunk-K3BFZ7KG.js +154 -0
- package/dist/chunk-K3BFZ7KG.js.map +7 -0
- package/dist/chunk-KHJUQFIK.js +51 -0
- package/dist/chunk-KHJUQFIK.js.map +7 -0
- package/dist/chunk-KRBQLMOP.js +41 -0
- package/dist/chunk-KRBQLMOP.js.map +7 -0
- package/dist/chunk-KZRFUXGF.js +145 -0
- package/dist/chunk-KZRFUXGF.js.map +7 -0
- package/dist/chunk-L674RNKQ.js +492 -0
- package/dist/chunk-L674RNKQ.js.map +7 -0
- package/dist/chunk-N52AHNBH.js +47 -0
- package/dist/chunk-N52AHNBH.js.map +7 -0
- package/dist/chunk-NIDLJO6F.js +228 -0
- package/dist/chunk-NIDLJO6F.js.map +7 -0
- package/dist/chunk-NSBPE2FW.js +17 -0
- package/dist/chunk-NSBPE2FW.js.map +7 -0
- package/dist/chunk-OGVORIFM.js +70 -0
- package/dist/chunk-OGVORIFM.js.map +7 -0
- package/dist/chunk-OQSQC7VB.js +77 -0
- package/dist/chunk-OQSQC7VB.js.map +7 -0
- package/dist/chunk-PHLMIZKM.js +153 -0
- package/dist/chunk-PHLMIZKM.js.map +7 -0
- package/dist/chunk-PQU7GZ7A.js +92 -0
- package/dist/chunk-PQU7GZ7A.js.map +7 -0
- package/dist/chunk-PXVQLD7S.js +196 -0
- package/dist/chunk-PXVQLD7S.js.map +7 -0
- package/dist/chunk-QD6X4L4L.js +79 -0
- package/dist/chunk-QD6X4L4L.js.map +7 -0
- package/dist/chunk-QJQS6TUN.js +44 -0
- package/dist/chunk-QJQS6TUN.js.map +7 -0
- package/dist/chunk-QJXAULRC.js +191 -0
- package/dist/chunk-QJXAULRC.js.map +7 -0
- package/dist/chunk-QN34TGD3.js +83 -0
- package/dist/chunk-QN34TGD3.js.map +7 -0
- package/dist/chunk-R5MFHGHR.js +122 -0
- package/dist/chunk-R5MFHGHR.js.map +7 -0
- package/dist/chunk-RH7NHVSK.js +16 -0
- package/dist/chunk-RH7NHVSK.js.map +7 -0
- package/dist/chunk-RJ7BHDLM.js +121 -0
- package/dist/chunk-RJ7BHDLM.js.map +7 -0
- package/dist/chunk-RQ2TMLKG.js +142 -0
- package/dist/chunk-RQ2TMLKG.js.map +7 -0
- package/dist/chunk-S56LOTGQ.js +63 -0
- package/dist/chunk-S56LOTGQ.js.map +7 -0
- package/dist/chunk-UF73WX2J.js +49 -0
- package/dist/chunk-UF73WX2J.js.map +7 -0
- package/dist/chunk-W53GKIZQ.js +50 -0
- package/dist/chunk-W53GKIZQ.js.map +7 -0
- package/dist/chunk-WA4MWYRW.js +254 -0
- package/dist/chunk-WA4MWYRW.js.map +7 -0
- package/dist/chunk-WFULKPEQ.js +269 -0
- package/dist/chunk-WFULKPEQ.js.map +7 -0
- package/dist/chunk-XC6M4CSW.js +44 -0
- package/dist/chunk-XC6M4CSW.js.map +7 -0
- package/dist/chunk-XPUEGHXN.js +243 -0
- package/dist/chunk-XPUEGHXN.js.map +7 -0
- package/dist/chunk-XZXS2W24.js +148 -0
- package/dist/chunk-XZXS2W24.js.map +7 -0
- package/dist/chunk-YBNW7ARH.js +167 -0
- package/dist/chunk-YBNW7ARH.js.map +7 -0
- package/dist/chunk-YNIH3KMU.js +121 -0
- package/dist/chunk-YNIH3KMU.js.map +7 -0
- package/dist/commands/antigravity/backfill.js +135 -0
- package/dist/commands/antigravity/backfill.js.map +7 -0
- package/dist/commands/auth/create-key.js +48 -33
- package/dist/commands/auth/create-key.js.map +7 -1
- package/dist/commands/auth/login.js +58 -46
- package/dist/commands/auth/login.js.map +7 -1
- package/dist/commands/auth/logout.js +28 -13
- package/dist/commands/auth/logout.js.map +7 -1
- package/dist/commands/auth/revoke-key.js +32 -18
- package/dist/commands/auth/revoke-key.js.map +7 -1
- package/dist/commands/auth/status.js +40 -22
- package/dist/commands/auth/status.js.map +7 -1
- package/dist/commands/catalog/index.js +50 -34
- package/dist/commands/catalog/index.js.map +7 -1
- package/dist/commands/catalog/recommend.js +41 -26
- package/dist/commands/catalog/recommend.js.map +7 -1
- package/dist/commands/convert.js +72 -54
- package/dist/commands/convert.js.map +7 -1
- package/dist/commands/converters.js +52 -38
- package/dist/commands/converters.js.map +7 -1
- package/dist/commands/crons/list.js +50 -24
- package/dist/commands/crons/list.js.map +7 -1
- package/dist/commands/crons/run.js +72 -47
- package/dist/commands/crons/run.js.map +7 -1
- package/dist/commands/dashboard.js +45 -24
- package/dist/commands/dashboard.js.map +7 -1
- package/dist/commands/eval-targets/create.js +51 -39
- package/dist/commands/eval-targets/create.js.map +7 -1
- package/dist/commands/eval-targets/list.js +52 -35
- package/dist/commands/eval-targets/list.js.map +7 -1
- package/dist/commands/evals/agent.js +292 -0
- package/dist/commands/evals/agent.js.map +7 -0
- package/dist/commands/evals/benchmark.js +70 -51
- package/dist/commands/evals/benchmark.js.map +7 -1
- package/dist/commands/evals/compare.js +90 -78
- package/dist/commands/evals/compare.js.map +7 -1
- package/dist/commands/evals/create.js +64 -50
- package/dist/commands/evals/create.js.map +7 -1
- package/dist/commands/evals/optimize-description.js +225 -222
- package/dist/commands/evals/optimize-description.js.map +7 -1
- package/dist/commands/evals/optimize.js +206 -196
- package/dist/commands/evals/optimize.js.map +7 -1
- package/dist/commands/evals/run.js +178 -164
- package/dist/commands/evals/run.js.map +7 -1
- package/dist/commands/gateway/ensure.js +33 -19
- package/dist/commands/gateway/ensure.js.map +7 -1
- package/dist/commands/hooks/install.js +335 -275
- package/dist/commands/hooks/install.js.map +7 -1
- package/dist/commands/hooks/run.js +72 -53
- package/dist/commands/hooks/run.js.map +7 -1
- package/dist/commands/hooks/uninstall.js +117 -94
- package/dist/commands/hooks/uninstall.js.map +7 -1
- package/dist/commands/import.js +63 -53
- package/dist/commands/import.js.map +7 -1
- package/dist/commands/instructions/create.js +71 -58
- package/dist/commands/instructions/create.js.map +7 -1
- package/dist/commands/instructions/delete.js +53 -36
- package/dist/commands/instructions/delete.js.map +7 -1
- package/dist/commands/instructions/fork.js +33 -19
- package/dist/commands/instructions/fork.js.map +7 -1
- package/dist/commands/instructions/get.js +66 -49
- package/dist/commands/instructions/get.js.map +7 -1
- package/dist/commands/instructions/list.js +63 -46
- package/dist/commands/instructions/list.js.map +7 -1
- package/dist/commands/instructions/promote.js +41 -27
- package/dist/commands/instructions/promote.js.map +7 -1
- package/dist/commands/instructions/pull.js +37 -21
- package/dist/commands/instructions/pull.js.map +7 -1
- package/dist/commands/instructions/upstream.js +36 -21
- package/dist/commands/instructions/upstream.js.map +7 -1
- package/dist/commands/instructions/versions.js +51 -33
- package/dist/commands/instructions/versions.js.map +7 -1
- package/dist/commands/launcher.js +39 -0
- package/dist/commands/launcher.js.map +7 -0
- package/dist/commands/org/current.js +74 -68
- package/dist/commands/org/current.js.map +7 -1
- package/dist/commands/org/list.js +50 -36
- package/dist/commands/org/list.js.map +7 -1
- package/dist/commands/org/switch.js +69 -51
- package/dist/commands/org/switch.js.map +7 -1
- package/dist/commands/packs/add-instruction.js +36 -22
- package/dist/commands/packs/add-instruction.js.map +7 -1
- package/dist/commands/packs/apply.js +38 -24
- package/dist/commands/packs/apply.js.map +7 -1
- package/dist/commands/packs/create.js +47 -33
- package/dist/commands/packs/create.js.map +7 -1
- package/dist/commands/packs/fork.js +33 -19
- package/dist/commands/packs/fork.js.map +7 -1
- package/dist/commands/packs/get.js +54 -35
- package/dist/commands/packs/get.js.map +7 -1
- package/dist/commands/packs/list.js +64 -47
- package/dist/commands/packs/list.js.map +7 -1
- package/dist/commands/packs/remove-instruction.js +34 -20
- package/dist/commands/packs/remove-instruction.js.map +7 -1
- package/dist/commands/proxy/env.js +126 -116
- package/dist/commands/proxy/env.js.map +7 -1
- package/dist/commands/proxy/logs.js +83 -74
- package/dist/commands/proxy/logs.js.map +7 -1
- package/dist/commands/proxy/restart.js +34 -36
- package/dist/commands/proxy/restart.js.map +7 -1
- package/dist/commands/proxy/setup.js +432 -375
- package/dist/commands/proxy/setup.js.map +7 -1
- package/dist/commands/proxy/start.js +289 -289
- package/dist/commands/proxy/start.js.map +7 -1
- package/dist/commands/proxy/status.js +74 -64
- package/dist/commands/proxy/status.js.map +7 -1
- package/dist/commands/proxy/stop.js +81 -75
- package/dist/commands/proxy/stop.js.map +7 -1
- package/dist/commands/research/backfill.js +58 -0
- package/dist/commands/research/backfill.js.map +7 -0
- package/dist/commands/research/tail-transcript.js +69 -0
- package/dist/commands/research/tail-transcript.js.map +7 -0
- package/dist/commands/service/install.js +639 -405
- package/dist/commands/service/install.js.map +7 -1
- package/dist/commands/service/status.js +178 -111
- package/dist/commands/service/status.js.map +7 -1
- package/dist/commands/service/uninstall.js +85 -110
- package/dist/commands/service/uninstall.js.map +7 -1
- package/dist/commands/sessions/analyze.js +46 -25
- package/dist/commands/sessions/analyze.js.map +7 -1
- package/dist/commands/sessions/end.js +81 -79
- package/dist/commands/sessions/end.js.map +7 -1
- package/dist/commands/sessions/import.js +44 -27
- package/dist/commands/sessions/import.js.map +7 -1
- package/dist/commands/sessions/list.js +46 -33
- package/dist/commands/sessions/list.js.map +7 -1
- package/dist/commands/sessions/start.js +88 -87
- package/dist/commands/sessions/start.js.map +7 -1
- package/dist/commands/signals/report.js +42 -34
- package/dist/commands/signals/report.js.map +7 -1
- package/dist/commands/skills/export-approved.js +44 -30
- package/dist/commands/skills/export-approved.js.map +7 -1
- package/dist/commands/skills/install.js +99 -84
- package/dist/commands/skills/install.js.map +7 -1
- package/dist/commands/skills/list.js +59 -42
- package/dist/commands/skills/list.js.map +7 -1
- package/dist/commands/skills/publish.js +95 -78
- package/dist/commands/skills/publish.js.map +7 -1
- package/dist/commands/skills/search.js +68 -53
- package/dist/commands/skills/search.js.map +7 -1
- package/dist/commands/skills/update.js +52 -39
- package/dist/commands/skills/update.js.map +7 -1
- package/dist/commands/suggestions/accept.js +82 -59
- package/dist/commands/suggestions/accept.js.map +7 -1
- package/dist/commands/suggestions/dismiss.js +44 -26
- package/dist/commands/suggestions/dismiss.js.map +7 -1
- package/dist/commands/suggestions/list.js +59 -39
- package/dist/commands/suggestions/list.js.map +7 -1
- package/dist/commands/suggestions/refresh.js +26 -11
- package/dist/commands/suggestions/refresh.js.map +7 -1
- package/dist/cursor-BGQJ4CWI.js +134 -0
- package/dist/cursor-BGQJ4CWI.js.map +7 -0
- package/dist/dashboard/Dashboard.js +229 -126
- package/dist/dashboard/Dashboard.js.map +7 -1
- package/dist/dashboard/data.js +13 -137
- package/dist/dashboard/data.js.map +7 -1
- package/dist/dashboard/launcher/ActiveJobsList.js +10 -0
- package/dist/dashboard/launcher/ActiveJobsList.js.map +7 -0
- package/dist/dashboard/launcher/LauncherOverlay.js +14 -0
- package/dist/dashboard/launcher/LauncherOverlay.js.map +7 -0
- package/dist/dashboard/launcher/NewLaunchForm.js +10 -0
- package/dist/dashboard/launcher/NewLaunchForm.js.map +7 -0
- package/dist/dashboard/launcher/api.js +14 -0
- package/dist/dashboard/launcher/api.js.map +7 -0
- package/dist/dashboard/launcher/tool-labels.js +10 -0
- package/dist/dashboard/launcher/tool-labels.js.map +7 -0
- package/dist/dashboard/launcher/types.js +1 -0
- package/dist/dashboard/launcher/types.js.map +7 -0
- package/dist/dashboard/launcher/useLaunchJobs.js +9 -0
- package/dist/dashboard/launcher/useLaunchJobs.js.map +7 -0
- package/dist/dashboard/panels/friction.js +10 -22
- package/dist/dashboard/panels/friction.js.map +7 -1
- package/dist/dashboard/panels/insights.js +10 -109
- package/dist/dashboard/panels/insights.js.map +7 -1
- package/dist/dashboard/panels/instructions.js +10 -17
- package/dist/dashboard/panels/instructions.js.map +7 -1
- package/dist/dashboard/panels/outcomes.js +9 -28
- package/dist/dashboard/panels/outcomes.js.map +7 -1
- package/dist/dashboard/panels/overview.js +10 -20
- package/dist/dashboard/panels/overview.js.map +7 -1
- package/dist/dashboard/panels/shared.js +18 -61
- package/dist/dashboard/panels/shared.js.map +7 -1
- package/dist/dashboard/types.js +23 -26
- package/dist/dashboard/types.js.map +7 -1
- package/dist/dist-CSUYFYKI.js +52 -0
- package/dist/dist-CSUYFYKI.js.map +7 -0
- package/dist/index.js +8 -2
- package/dist/index.js.map +7 -1
- package/dist/lib/active-org-refresh.js +15 -108
- package/dist/lib/active-org-refresh.js.map +7 -1
- package/dist/lib/active-org.js +15 -95
- package/dist/lib/active-org.js.map +7 -1
- package/dist/lib/agent-loop.js +44 -0
- package/dist/lib/agent-loop.js.map +7 -0
- package/dist/lib/antigravity-transcript.js +22 -0
- package/dist/lib/antigravity-transcript.js.map +7 -0
- package/dist/lib/api-client.js +21 -92
- package/dist/lib/api-client.js.map +7 -1
- package/dist/lib/auth.js +26 -137
- package/dist/lib/auth.js.map +7 -1
- package/dist/lib/detect-languages.js +8 -113
- package/dist/lib/detect-languages.js.map +7 -1
- package/dist/lib/detect-tmux.js +9 -0
- package/dist/lib/detect-tmux.js.map +7 -0
- package/dist/lib/eval-analyzer.js +9 -89
- package/dist/lib/eval-analyzer.js.map +7 -1
- package/dist/lib/eval-benchmark.js +12 -92
- package/dist/lib/eval-benchmark.js.map +7 -1
- package/dist/lib/eval-conversation-handler.js +13 -200
- package/dist/lib/eval-conversation-handler.js.map +7 -1
- package/dist/lib/eval-executor.js +8 -83
- package/dist/lib/eval-executor.js.map +7 -1
- package/dist/lib/eval-grader.js +9 -123
- package/dist/lib/eval-grader.js.map +7 -1
- package/dist/lib/eval-meta-judge.js +9 -116
- package/dist/lib/eval-meta-judge.js.map +7 -1
- package/dist/lib/eval-trigger-tester.js +11 -96
- package/dist/lib/eval-trigger-tester.js.map +7 -1
- package/dist/lib/eval-worktree.js +8 -87
- package/dist/lib/eval-worktree.js.map +7 -1
- package/dist/lib/gateway-entry.js +20 -18
- package/dist/lib/gateway-entry.js.map +7 -1
- package/dist/lib/gateway-lifecycle.js +22 -97
- package/dist/lib/gateway-lifecycle.js.map +7 -1
- package/dist/lib/gateway.js +12 -216
- package/dist/lib/gateway.js.map +7 -1
- package/dist/lib/handlers/cron-close-stale-sessions.js +18 -7
- package/dist/lib/handlers/cron-close-stale-sessions.js.map +7 -1
- package/dist/lib/handlers/cron-data-integrity-audit.js +21 -15
- package/dist/lib/handlers/cron-data-integrity-audit.js.map +7 -1
- package/dist/lib/handlers/cron-refresh-skills.js +7 -90
- package/dist/lib/handlers/cron-refresh-skills.js.map +7 -1
- package/dist/lib/handlers/cron-suggest-instructions.js +14 -158
- package/dist/lib/handlers/cron-suggest-instructions.js.map +7 -1
- package/dist/lib/handlers/process-announcement.js +11 -0
- package/dist/lib/handlers/process-announcement.js.map +7 -0
- package/dist/lib/handlers/process-changelog.js +11 -0
- package/dist/lib/handlers/process-changelog.js.map +7 -0
- package/dist/lib/handlers/process-conversation.js +14 -35
- package/dist/lib/handlers/process-conversation.js.map +7 -1
- package/dist/lib/handlers/process-eval.js +15 -207
- package/dist/lib/handlers/process-eval.js.map +7 -1
- package/dist/lib/handlers/process-insights.js +14 -300
- package/dist/lib/handlers/process-insights.js.map +7 -1
- package/dist/lib/handlers/process-launch.js +16 -41
- package/dist/lib/handlers/process-launch.js.map +7 -1
- package/dist/lib/handlers/process-run-cleanup.js +13 -0
- package/dist/lib/handlers/process-run-cleanup.js.map +7 -0
- package/dist/lib/handlers/process-send-message.js +10 -0
- package/dist/lib/handlers/process-send-message.js.map +7 -0
- package/dist/lib/handlers/process-session-goal.js +11 -74
- package/dist/lib/handlers/process-session-goal.js.map +7 -1
- package/dist/lib/hooks-config.js +52 -544
- package/dist/lib/hooks-config.js.map +7 -1
- package/dist/lib/insights-prompts.js +12 -145
- package/dist/lib/insights-prompts.js.map +7 -1
- package/dist/lib/job-helpers.js +1 -0
- package/dist/lib/job-helpers.js.map +7 -0
- package/dist/lib/llm-client.js +16 -274
- package/dist/lib/llm-client.js.map +7 -1
- package/dist/lib/manual-tasks.js +22 -0
- package/dist/lib/manual-tasks.js.map +7 -0
- package/dist/lib/output.js +12 -36
- package/dist/lib/output.js.map +7 -1
- package/dist/lib/permanent-job-error.js +10 -23
- package/dist/lib/permanent-job-error.js.map +7 -1
- package/dist/lib/provider-aggregator.js +57 -55
- package/dist/lib/provider-aggregator.js.map +7 -1
- package/dist/lib/research-client.js +12 -0
- package/dist/lib/research-client.js.map +7 -0
- package/dist/lib/skills-loader.js +8 -51
- package/dist/lib/skills-loader.js.map +7 -1
- package/dist/lib/statusline-shim.js +16 -0
- package/dist/lib/statusline-shim.js.map +7 -0
- package/dist/lib/terminal-target-heartbeat.js +15 -0
- package/dist/lib/terminal-target-heartbeat.js.map +7 -0
- package/dist/lib/tmux.js +16 -0
- package/dist/lib/tmux.js.map +7 -0
- package/dist/lib/transcript-rate-limit-watcher.js +22 -0
- package/dist/lib/transcript-rate-limit-watcher.js.map +7 -0
- package/dist/lib/types.js +8 -7
- package/dist/lib/types.js.map +7 -1
- package/dist/lib/version-check.js +10 -106
- package/dist/lib/version-check.js.map +7 -1
- package/dist/lib/which.js +8 -0
- package/dist/lib/which.js.map +7 -0
- package/dist/lib/worktree.js +17 -0
- package/dist/lib/worktree.js.map +7 -0
- package/dist/opencode-IQ7X5YMJ.js +190 -0
- package/dist/opencode-IQ7X5YMJ.js.map +7 -0
- package/oclif.manifest.json +299 -66
- package/package.json +26 -10
- package/dist/base-command.d.ts +0 -12
- package/dist/base-command.d.ts.map +0 -1
- package/dist/commands/auth/create-key.d.ts +0 -11
- package/dist/commands/auth/create-key.d.ts.map +0 -1
- package/dist/commands/auth/login.d.ts +0 -11
- package/dist/commands/auth/login.d.ts.map +0 -1
- package/dist/commands/auth/logout.d.ts +0 -7
- package/dist/commands/auth/logout.d.ts.map +0 -1
- package/dist/commands/auth/revoke-key.d.ts +0 -10
- package/dist/commands/auth/revoke-key.d.ts.map +0 -1
- package/dist/commands/auth/status.d.ts +0 -7
- package/dist/commands/auth/status.d.ts.map +0 -1
- package/dist/commands/catalog/index.d.ts +0 -11
- package/dist/commands/catalog/index.d.ts.map +0 -1
- package/dist/commands/catalog/recommend.d.ts +0 -9
- package/dist/commands/catalog/recommend.d.ts.map +0 -1
- package/dist/commands/convert.d.ts +0 -15
- package/dist/commands/convert.d.ts.map +0 -1
- package/dist/commands/converters.d.ts +0 -12
- package/dist/commands/converters.d.ts.map +0 -1
- package/dist/commands/crons/list.d.ts +0 -7
- package/dist/commands/crons/list.d.ts.map +0 -1
- package/dist/commands/crons/run.d.ts +0 -13
- package/dist/commands/crons/run.d.ts.map +0 -1
- package/dist/commands/dashboard.d.ts +0 -10
- package/dist/commands/dashboard.d.ts.map +0 -1
- package/dist/commands/eval-targets/create.d.ts +0 -14
- package/dist/commands/eval-targets/create.d.ts.map +0 -1
- package/dist/commands/eval-targets/list.d.ts +0 -10
- package/dist/commands/eval-targets/list.d.ts.map +0 -1
- package/dist/commands/evals/benchmark.d.ts +0 -13
- package/dist/commands/evals/benchmark.d.ts.map +0 -1
- package/dist/commands/evals/compare.d.ts +0 -15
- package/dist/commands/evals/compare.d.ts.map +0 -1
- package/dist/commands/evals/create.d.ts +0 -17
- package/dist/commands/evals/create.d.ts.map +0 -1
- package/dist/commands/evals/listen.d.ts +0 -37
- package/dist/commands/evals/listen.d.ts.map +0 -1
- package/dist/commands/evals/listen.js +0 -188
- package/dist/commands/evals/listen.js.map +0 -1
- package/dist/commands/evals/listen.test.d.ts +0 -2
- package/dist/commands/evals/listen.test.d.ts.map +0 -1
- package/dist/commands/evals/listen.test.js +0 -48
- package/dist/commands/evals/listen.test.js.map +0 -1
- package/dist/commands/evals/optimize-description.d.ts +0 -22
- package/dist/commands/evals/optimize-description.d.ts.map +0 -1
- package/dist/commands/evals/optimize.d.ts +0 -22
- package/dist/commands/evals/optimize.d.ts.map +0 -1
- package/dist/commands/evals/run.d.ts +0 -21
- package/dist/commands/evals/run.d.ts.map +0 -1
- package/dist/commands/gateway/ensure.d.ts +0 -7
- package/dist/commands/gateway/ensure.d.ts.map +0 -1
- package/dist/commands/hooks/install.d.ts +0 -16
- package/dist/commands/hooks/install.d.ts.map +0 -1
- package/dist/commands/hooks/run.d.ts +0 -11
- package/dist/commands/hooks/run.d.ts.map +0 -1
- package/dist/commands/hooks/uninstall.d.ts +0 -7
- package/dist/commands/hooks/uninstall.d.ts.map +0 -1
- package/dist/commands/import.d.ts +0 -17
- package/dist/commands/import.d.ts.map +0 -1
- package/dist/commands/instructions/create.d.ts +0 -17
- package/dist/commands/instructions/create.d.ts.map +0 -1
- package/dist/commands/instructions/delete.d.ts +0 -13
- package/dist/commands/instructions/delete.d.ts.map +0 -1
- package/dist/commands/instructions/fork.d.ts +0 -10
- package/dist/commands/instructions/fork.d.ts.map +0 -1
- package/dist/commands/instructions/get.d.ts +0 -15
- package/dist/commands/instructions/get.d.ts.map +0 -1
- package/dist/commands/instructions/list.d.ts +0 -12
- package/dist/commands/instructions/list.d.ts.map +0 -1
- package/dist/commands/instructions/promote.d.ts +0 -14
- package/dist/commands/instructions/promote.d.ts.map +0 -1
- package/dist/commands/instructions/pull.d.ts +0 -9
- package/dist/commands/instructions/pull.d.ts.map +0 -1
- package/dist/commands/instructions/upstream.d.ts +0 -9
- package/dist/commands/instructions/upstream.d.ts.map +0 -1
- package/dist/commands/instructions/versions.d.ts +0 -12
- package/dist/commands/instructions/versions.d.ts.map +0 -1
- package/dist/commands/org/current.d.ts +0 -7
- package/dist/commands/org/current.d.ts.map +0 -1
- package/dist/commands/org/list.d.ts +0 -7
- package/dist/commands/org/list.d.ts.map +0 -1
- package/dist/commands/org/switch.d.ts +0 -13
- package/dist/commands/org/switch.d.ts.map +0 -1
- package/dist/commands/packs/add-instruction.d.ts +0 -11
- package/dist/commands/packs/add-instruction.d.ts.map +0 -1
- package/dist/commands/packs/apply.d.ts +0 -13
- package/dist/commands/packs/apply.d.ts.map +0 -1
- package/dist/commands/packs/create.d.ts +0 -13
- package/dist/commands/packs/create.d.ts.map +0 -1
- package/dist/commands/packs/fork.d.ts +0 -10
- package/dist/commands/packs/fork.d.ts.map +0 -1
- package/dist/commands/packs/get.d.ts +0 -10
- package/dist/commands/packs/get.d.ts.map +0 -1
- package/dist/commands/packs/list.d.ts +0 -22
- package/dist/commands/packs/list.d.ts.map +0 -1
- package/dist/commands/packs/remove-instruction.d.ts +0 -11
- package/dist/commands/packs/remove-instruction.d.ts.map +0 -1
- package/dist/commands/proxy/env.d.ts +0 -14
- package/dist/commands/proxy/env.d.ts.map +0 -1
- package/dist/commands/proxy/logs.d.ts +0 -11
- package/dist/commands/proxy/logs.d.ts.map +0 -1
- package/dist/commands/proxy/restart.d.ts +0 -11
- package/dist/commands/proxy/restart.d.ts.map +0 -1
- package/dist/commands/proxy/setup.d.ts +0 -23
- package/dist/commands/proxy/setup.d.ts.map +0 -1
- package/dist/commands/proxy/start.d.ts +0 -17
- package/dist/commands/proxy/start.d.ts.map +0 -1
- package/dist/commands/proxy/status.d.ts +0 -7
- package/dist/commands/proxy/status.d.ts.map +0 -1
- package/dist/commands/proxy/stop.d.ts +0 -8
- package/dist/commands/proxy/stop.d.ts.map +0 -1
- package/dist/commands/service/install.d.ts +0 -33
- package/dist/commands/service/install.d.ts.map +0 -1
- package/dist/commands/service/install.test.d.ts +0 -2
- package/dist/commands/service/install.test.d.ts.map +0 -1
- package/dist/commands/service/install.test.js +0 -345
- package/dist/commands/service/install.test.js.map +0 -1
- package/dist/commands/service/status.d.ts +0 -6
- package/dist/commands/service/status.d.ts.map +0 -1
- package/dist/commands/service/uninstall.d.ts +0 -6
- package/dist/commands/service/uninstall.d.ts.map +0 -1
- package/dist/commands/sessions/analyze.d.ts +0 -10
- package/dist/commands/sessions/analyze.d.ts.map +0 -1
- package/dist/commands/sessions/end.d.ts +0 -9
- package/dist/commands/sessions/end.d.ts.map +0 -1
- package/dist/commands/sessions/import.d.ts +0 -13
- package/dist/commands/sessions/import.d.ts.map +0 -1
- package/dist/commands/sessions/list.d.ts +0 -11
- package/dist/commands/sessions/list.d.ts.map +0 -1
- package/dist/commands/sessions/start.d.ts +0 -11
- package/dist/commands/sessions/start.d.ts.map +0 -1
- package/dist/commands/signals/report.d.ts +0 -10
- package/dist/commands/signals/report.d.ts.map +0 -1
- package/dist/commands/signals/report.test.d.ts +0 -2
- package/dist/commands/signals/report.test.d.ts.map +0 -1
- package/dist/commands/signals/report.test.js +0 -65
- package/dist/commands/signals/report.test.js.map +0 -1
- package/dist/commands/skills/export-approved.d.ts +0 -10
- package/dist/commands/skills/export-approved.d.ts.map +0 -1
- package/dist/commands/skills/install.d.ts +0 -15
- package/dist/commands/skills/install.d.ts.map +0 -1
- package/dist/commands/skills/list.d.ts +0 -11
- package/dist/commands/skills/list.d.ts.map +0 -1
- package/dist/commands/skills/publish.d.ts +0 -17
- package/dist/commands/skills/publish.d.ts.map +0 -1
- package/dist/commands/skills/search.d.ts +0 -17
- package/dist/commands/skills/search.d.ts.map +0 -1
- package/dist/commands/skills/update.d.ts +0 -10
- package/dist/commands/skills/update.d.ts.map +0 -1
- package/dist/commands/suggestions/accept.d.ts +0 -16
- package/dist/commands/suggestions/accept.d.ts.map +0 -1
- package/dist/commands/suggestions/accept.test.d.ts +0 -2
- package/dist/commands/suggestions/accept.test.d.ts.map +0 -1
- package/dist/commands/suggestions/accept.test.js +0 -52
- package/dist/commands/suggestions/accept.test.js.map +0 -1
- package/dist/commands/suggestions/dismiss.d.ts +0 -10
- package/dist/commands/suggestions/dismiss.d.ts.map +0 -1
- package/dist/commands/suggestions/list.d.ts +0 -10
- package/dist/commands/suggestions/list.d.ts.map +0 -1
- package/dist/commands/suggestions/refresh.d.ts +0 -7
- package/dist/commands/suggestions/refresh.d.ts.map +0 -1
- package/dist/dashboard/Dashboard.d.ts +0 -3
- package/dist/dashboard/Dashboard.d.ts.map +0 -1
- package/dist/dashboard/data.d.ts +0 -11
- package/dist/dashboard/data.d.ts.map +0 -1
- package/dist/dashboard/panels/friction.d.ts +0 -7
- package/dist/dashboard/panels/friction.d.ts.map +0 -1
- package/dist/dashboard/panels/insights.d.ts +0 -8
- package/dist/dashboard/panels/insights.d.ts.map +0 -1
- package/dist/dashboard/panels/instructions.d.ts +0 -9
- package/dist/dashboard/panels/instructions.d.ts.map +0 -1
- package/dist/dashboard/panels/outcomes.d.ts +0 -7
- package/dist/dashboard/panels/outcomes.d.ts.map +0 -1
- package/dist/dashboard/panels/overview.d.ts +0 -8
- package/dist/dashboard/panels/overview.d.ts.map +0 -1
- package/dist/dashboard/panels/shared.d.ts +0 -17
- package/dist/dashboard/panels/shared.d.ts.map +0 -1
- package/dist/dashboard/types.d.ts +0 -80
- package/dist/dashboard/types.d.ts.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/active-org-refresh.d.ts +0 -22
- package/dist/lib/active-org-refresh.d.ts.map +0 -1
- package/dist/lib/active-org-refresh.test.d.ts +0 -2
- package/dist/lib/active-org-refresh.test.d.ts.map +0 -1
- package/dist/lib/active-org-refresh.test.js +0 -190
- package/dist/lib/active-org-refresh.test.js.map +0 -1
- package/dist/lib/active-org.d.ts +0 -43
- package/dist/lib/active-org.d.ts.map +0 -1
- package/dist/lib/active-org.test.d.ts +0 -2
- package/dist/lib/active-org.test.d.ts.map +0 -1
- package/dist/lib/active-org.test.js +0 -147
- package/dist/lib/active-org.test.js.map +0 -1
- package/dist/lib/api-client.d.ts +0 -17
- package/dist/lib/api-client.d.ts.map +0 -1
- package/dist/lib/api-client.test.d.ts +0 -2
- package/dist/lib/api-client.test.d.ts.map +0 -1
- package/dist/lib/api-client.test.js +0 -161
- package/dist/lib/api-client.test.js.map +0 -1
- package/dist/lib/auth.d.ts +0 -27
- package/dist/lib/auth.d.ts.map +0 -1
- package/dist/lib/auth.test.d.ts +0 -2
- package/dist/lib/auth.test.d.ts.map +0 -1
- package/dist/lib/auth.test.js +0 -110
- package/dist/lib/auth.test.js.map +0 -1
- package/dist/lib/cron-registry.d.ts +0 -47
- package/dist/lib/cron-registry.d.ts.map +0 -1
- package/dist/lib/cron-registry.js +0 -102
- package/dist/lib/cron-registry.js.map +0 -1
- package/dist/lib/cron-registry.test.d.ts +0 -2
- package/dist/lib/cron-registry.test.d.ts.map +0 -1
- package/dist/lib/cron-registry.test.js +0 -136
- package/dist/lib/cron-registry.test.js.map +0 -1
- package/dist/lib/cron-runner.d.ts +0 -16
- package/dist/lib/cron-runner.d.ts.map +0 -1
- package/dist/lib/cron-runner.js +0 -68
- package/dist/lib/cron-runner.js.map +0 -1
- package/dist/lib/detect-languages.d.ts +0 -7
- package/dist/lib/detect-languages.d.ts.map +0 -1
- package/dist/lib/detect-languages.test.d.ts +0 -2
- package/dist/lib/detect-languages.test.d.ts.map +0 -1
- package/dist/lib/detect-languages.test.js +0 -29
- package/dist/lib/detect-languages.test.js.map +0 -1
- package/dist/lib/eval-analyzer.d.ts +0 -23
- package/dist/lib/eval-analyzer.d.ts.map +0 -1
- package/dist/lib/eval-benchmark.d.ts +0 -17
- package/dist/lib/eval-benchmark.d.ts.map +0 -1
- package/dist/lib/eval-conversation-handler.d.ts +0 -9
- package/dist/lib/eval-conversation-handler.d.ts.map +0 -1
- package/dist/lib/eval-executor.d.ts +0 -21
- package/dist/lib/eval-executor.d.ts.map +0 -1
- package/dist/lib/eval-executor.test.d.ts +0 -2
- package/dist/lib/eval-executor.test.d.ts.map +0 -1
- package/dist/lib/eval-executor.test.js +0 -8
- package/dist/lib/eval-executor.test.js.map +0 -1
- package/dist/lib/eval-grader.d.ts +0 -38
- package/dist/lib/eval-grader.d.ts.map +0 -1
- package/dist/lib/eval-grader.test.d.ts +0 -2
- package/dist/lib/eval-grader.test.d.ts.map +0 -1
- package/dist/lib/eval-grader.test.js +0 -8
- package/dist/lib/eval-grader.test.js.map +0 -1
- package/dist/lib/eval-meta-judge.d.ts +0 -28
- package/dist/lib/eval-meta-judge.d.ts.map +0 -1
- package/dist/lib/eval-trigger-tester.d.ts +0 -19
- package/dist/lib/eval-trigger-tester.d.ts.map +0 -1
- package/dist/lib/eval-worktree.d.ts +0 -11
- package/dist/lib/eval-worktree.d.ts.map +0 -1
- package/dist/lib/eval-worktree.test.d.ts +0 -2
- package/dist/lib/eval-worktree.test.d.ts.map +0 -1
- package/dist/lib/eval-worktree.test.js +0 -68
- package/dist/lib/eval-worktree.test.js.map +0 -1
- package/dist/lib/gateway-entry.d.ts +0 -3
- package/dist/lib/gateway-entry.d.ts.map +0 -1
- package/dist/lib/gateway-lifecycle.d.ts +0 -9
- package/dist/lib/gateway-lifecycle.d.ts.map +0 -1
- package/dist/lib/gateway.d.ts +0 -11
- package/dist/lib/gateway.d.ts.map +0 -1
- package/dist/lib/graphile-worker-runner.d.ts +0 -124
- package/dist/lib/graphile-worker-runner.d.ts.map +0 -1
- package/dist/lib/graphile-worker-runner.js +0 -530
- package/dist/lib/graphile-worker-runner.js.map +0 -1
- package/dist/lib/graphile-worker-runner.test.d.ts +0 -2
- package/dist/lib/graphile-worker-runner.test.d.ts.map +0 -1
- package/dist/lib/graphile-worker-runner.test.js +0 -153
- package/dist/lib/graphile-worker-runner.test.js.map +0 -1
- package/dist/lib/handlers/cron-close-stale-sessions.d.ts +0 -3
- package/dist/lib/handlers/cron-close-stale-sessions.d.ts.map +0 -1
- package/dist/lib/handlers/cron-data-integrity-audit.d.ts +0 -3
- package/dist/lib/handlers/cron-data-integrity-audit.d.ts.map +0 -1
- package/dist/lib/handlers/cron-refresh-skills.d.ts +0 -3
- package/dist/lib/handlers/cron-refresh-skills.d.ts.map +0 -1
- package/dist/lib/handlers/cron-refresh-skills.test.d.ts +0 -2
- package/dist/lib/handlers/cron-refresh-skills.test.d.ts.map +0 -1
- package/dist/lib/handlers/cron-refresh-skills.test.js +0 -114
- package/dist/lib/handlers/cron-refresh-skills.test.js.map +0 -1
- package/dist/lib/handlers/cron-regenerate-insights.d.ts +0 -3
- package/dist/lib/handlers/cron-regenerate-insights.d.ts.map +0 -1
- package/dist/lib/handlers/cron-regenerate-insights.js +0 -6
- package/dist/lib/handlers/cron-regenerate-insights.js.map +0 -1
- package/dist/lib/handlers/cron-suggest-instructions.d.ts +0 -3
- package/dist/lib/handlers/cron-suggest-instructions.d.ts.map +0 -1
- package/dist/lib/handlers/cron-suggest-instructions.test.d.ts +0 -2
- package/dist/lib/handlers/cron-suggest-instructions.test.d.ts.map +0 -1
- package/dist/lib/handlers/cron-suggest-instructions.test.js +0 -80
- package/dist/lib/handlers/cron-suggest-instructions.test.js.map +0 -1
- package/dist/lib/handlers/process-conversation.d.ts +0 -35
- package/dist/lib/handlers/process-conversation.d.ts.map +0 -1
- package/dist/lib/handlers/process-eval.d.ts +0 -32
- package/dist/lib/handlers/process-eval.d.ts.map +0 -1
- package/dist/lib/handlers/process-insights.d.ts +0 -39
- package/dist/lib/handlers/process-insights.d.ts.map +0 -1
- package/dist/lib/handlers/process-launch.d.ts +0 -29
- package/dist/lib/handlers/process-launch.d.ts.map +0 -1
- package/dist/lib/handlers/process-session-goal.d.ts +0 -29
- package/dist/lib/handlers/process-session-goal.d.ts.map +0 -1
- package/dist/lib/handlers/process-session-goal.test.d.ts +0 -2
- package/dist/lib/handlers/process-session-goal.test.d.ts.map +0 -1
- package/dist/lib/handlers/process-session-goal.test.js +0 -134
- package/dist/lib/handlers/process-session-goal.test.js.map +0 -1
- package/dist/lib/hooks-config.d.ts +0 -119
- package/dist/lib/hooks-config.d.ts.map +0 -1
- package/dist/lib/hooks-config.test.d.ts +0 -2
- package/dist/lib/hooks-config.test.d.ts.map +0 -1
- package/dist/lib/hooks-config.test.js +0 -231
- package/dist/lib/hooks-config.test.js.map +0 -1
- package/dist/lib/insights-prompts.d.ts +0 -13
- package/dist/lib/insights-prompts.d.ts.map +0 -1
- package/dist/lib/llm-client.d.ts +0 -26
- package/dist/lib/llm-client.d.ts.map +0 -1
- package/dist/lib/llm-client.test.d.ts +0 -2
- package/dist/lib/llm-client.test.d.ts.map +0 -1
- package/dist/lib/llm-client.test.js +0 -62
- package/dist/lib/llm-client.test.js.map +0 -1
- package/dist/lib/mirror-writer-db.d.ts +0 -12
- package/dist/lib/mirror-writer-db.d.ts.map +0 -1
- package/dist/lib/mirror-writer-db.js +0 -51
- package/dist/lib/mirror-writer-db.js.map +0 -1
- package/dist/lib/mirror-writer.d.ts +0 -35
- package/dist/lib/mirror-writer.d.ts.map +0 -1
- package/dist/lib/mirror-writer.js +0 -27
- package/dist/lib/mirror-writer.js.map +0 -1
- package/dist/lib/mirror-writer.test.d.ts +0 -2
- package/dist/lib/mirror-writer.test.d.ts.map +0 -1
- package/dist/lib/mirror-writer.test.js +0 -47
- package/dist/lib/mirror-writer.test.js.map +0 -1
- package/dist/lib/output.d.ts +0 -4
- package/dist/lib/output.d.ts.map +0 -1
- package/dist/lib/output.test.d.ts +0 -2
- package/dist/lib/output.test.d.ts.map +0 -1
- package/dist/lib/output.test.js +0 -71
- package/dist/lib/output.test.js.map +0 -1
- package/dist/lib/permanent-job-error.d.ts +0 -17
- package/dist/lib/permanent-job-error.d.ts.map +0 -1
- package/dist/lib/permanent-job-error.test.d.ts +0 -2
- package/dist/lib/permanent-job-error.test.d.ts.map +0 -1
- package/dist/lib/permanent-job-error.test.js +0 -29
- package/dist/lib/permanent-job-error.test.js.map +0 -1
- package/dist/lib/provider-aggregator.d.ts +0 -24
- package/dist/lib/provider-aggregator.d.ts.map +0 -1
- package/dist/lib/provider-aggregator.test.d.ts +0 -2
- package/dist/lib/provider-aggregator.test.d.ts.map +0 -1
- package/dist/lib/provider-aggregator.test.js +0 -103
- package/dist/lib/provider-aggregator.test.js.map +0 -1
- package/dist/lib/skills-loader.d.ts +0 -6
- package/dist/lib/skills-loader.d.ts.map +0 -1
- package/dist/lib/types.d.ts +0 -48
- package/dist/lib/types.d.ts.map +0 -1
- package/dist/lib/version-check.d.ts +0 -11
- package/dist/lib/version-check.d.ts.map +0 -1
- package/dist/test-helpers.d.ts +0 -58
- package/dist/test-helpers.d.ts.map +0 -1
- package/dist/test-helpers.js +0 -58
- package/dist/test-helpers.js.map +0 -1
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PermanentJobError
|
|
3
|
+
} from "./chunk-DGHWRQXL.js";
|
|
4
|
+
import {
|
|
5
|
+
sendEmail
|
|
6
|
+
} from "./chunk-NIDLJO6F.js";
|
|
7
|
+
import {
|
|
8
|
+
announcementDeliveries,
|
|
9
|
+
announcements,
|
|
10
|
+
getDb,
|
|
11
|
+
notificationPreferences,
|
|
12
|
+
profiles
|
|
13
|
+
} from "./chunk-7FAA3YNB.js";
|
|
14
|
+
|
|
15
|
+
// src/lib/handlers/process-announcement.ts
|
|
16
|
+
import { and, asc, eq, gt, isNotNull } from "drizzle-orm";
|
|
17
|
+
var BATCH_SIZE = 100;
|
|
18
|
+
var CONCURRENCY = 10;
|
|
19
|
+
async function processAnnouncement(payload, deps = {}) {
|
|
20
|
+
const db = deps.db ?? getDb();
|
|
21
|
+
const sendEmail2 = deps.sendEmail ?? sendEmail;
|
|
22
|
+
const log = deps.log ?? ((msg) => process.stderr.write(`[process_announcement] ${msg}
|
|
23
|
+
`));
|
|
24
|
+
const webBaseUrl = deps.webBaseUrl ?? process.env.RULEMETRIC_WEB_URL ?? "https://rulemetric.com";
|
|
25
|
+
const { announcementId } = payload;
|
|
26
|
+
const [announcement] = await db.select().from(announcements).where(eq(announcements.id, announcementId)).limit(1);
|
|
27
|
+
if (!announcement) {
|
|
28
|
+
throw new PermanentJobError(`Announcement ${announcementId} not found`);
|
|
29
|
+
}
|
|
30
|
+
if (announcement.status !== "queued" && announcement.status !== "sending") {
|
|
31
|
+
throw new PermanentJobError(
|
|
32
|
+
`Announcement ${announcementId} is in status='${announcement.status}'; expected 'queued' or 'sending'.`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
await db.update(announcements).set({ status: "sending", updatedAt: /* @__PURE__ */ new Date() }).where(eq(announcements.id, announcementId));
|
|
36
|
+
log(`Sending announcement ${announcementId} (${announcement.subject ?? ""})`);
|
|
37
|
+
let sent = 0;
|
|
38
|
+
let failed = 0;
|
|
39
|
+
let skipped = 0;
|
|
40
|
+
let lastUserId = null;
|
|
41
|
+
try {
|
|
42
|
+
while (true) {
|
|
43
|
+
const recipients = await db.select({
|
|
44
|
+
userId: notificationPreferences.userId,
|
|
45
|
+
email: profiles.email,
|
|
46
|
+
unsubscribeToken: notificationPreferences.unsubscribeToken
|
|
47
|
+
}).from(notificationPreferences).innerJoin(profiles, eq(profiles.id, notificationPreferences.userId)).where(
|
|
48
|
+
and(
|
|
49
|
+
eq(notificationPreferences.productAnnouncements, true),
|
|
50
|
+
isNotNull(profiles.email),
|
|
51
|
+
lastUserId ? gt(notificationPreferences.userId, lastUserId) : void 0
|
|
52
|
+
)
|
|
53
|
+
).orderBy(asc(notificationPreferences.userId)).limit(BATCH_SIZE);
|
|
54
|
+
if (recipients.length === 0) break;
|
|
55
|
+
lastUserId = recipients[recipients.length - 1].userId;
|
|
56
|
+
for (let i = 0; i < recipients.length; i += CONCURRENCY) {
|
|
57
|
+
const chunk = recipients.slice(i, i + CONCURRENCY);
|
|
58
|
+
const results = await Promise.allSettled(
|
|
59
|
+
chunk.map(
|
|
60
|
+
(r) => sendOne({
|
|
61
|
+
recipient: r,
|
|
62
|
+
announcement,
|
|
63
|
+
webBaseUrl,
|
|
64
|
+
sendEmail: sendEmail2,
|
|
65
|
+
db
|
|
66
|
+
})
|
|
67
|
+
)
|
|
68
|
+
);
|
|
69
|
+
for (let j = 0; j < results.length; j++) {
|
|
70
|
+
const res = results[j];
|
|
71
|
+
if (res.status === "fulfilled") {
|
|
72
|
+
if (res.value.ok === "sent") sent++;
|
|
73
|
+
else if (res.value.ok === "skipped") skipped++;
|
|
74
|
+
else {
|
|
75
|
+
failed++;
|
|
76
|
+
log(` recipient ${chunk[j].userId}: send failed \u2014 ${res.value.error}`);
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
failed++;
|
|
80
|
+
const reason = res.reason instanceof Error ? res.reason.message : String(res.reason);
|
|
81
|
+
log(` recipient ${chunk[j].userId}: send failed \u2014 ${reason}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (recipients.length < BATCH_SIZE) break;
|
|
86
|
+
}
|
|
87
|
+
const errorSummary = failed > 0 ? `${failed} of ${sent + failed} recipient(s) failed; see announcement_deliveries` : null;
|
|
88
|
+
await db.update(announcements).set({
|
|
89
|
+
status: "sent",
|
|
90
|
+
recipientCount: sent,
|
|
91
|
+
sentAt: /* @__PURE__ */ new Date(),
|
|
92
|
+
error: errorSummary,
|
|
93
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
94
|
+
}).where(eq(announcements.id, announcementId));
|
|
95
|
+
log(`Done: sent=${sent} failed=${failed} skipped=${skipped}`);
|
|
96
|
+
return { sent, failed, skipped };
|
|
97
|
+
} catch (err) {
|
|
98
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
99
|
+
await db.update(announcements).set({
|
|
100
|
+
status: "failed",
|
|
101
|
+
error: message.slice(0, 1e3),
|
|
102
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
103
|
+
}).where(eq(announcements.id, announcementId)).catch(() => {
|
|
104
|
+
});
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async function sendOne(args) {
|
|
109
|
+
const { recipient, announcement, webBaseUrl, sendEmail: sendEmail2, db } = args;
|
|
110
|
+
if (!recipient.email) {
|
|
111
|
+
return { ok: "skipped", reason: "no-email" };
|
|
112
|
+
}
|
|
113
|
+
const reserved = await db.insert(announcementDeliveries).values({
|
|
114
|
+
announcementId: announcement.id,
|
|
115
|
+
userId: recipient.userId,
|
|
116
|
+
email: recipient.email,
|
|
117
|
+
status: "pending"
|
|
118
|
+
}).onConflictDoNothing({
|
|
119
|
+
target: [announcementDeliveries.announcementId, announcementDeliveries.userId]
|
|
120
|
+
}).returning({ id: announcementDeliveries.id });
|
|
121
|
+
if (reserved.length === 0) {
|
|
122
|
+
return { ok: "skipped", reason: "already-claimed" };
|
|
123
|
+
}
|
|
124
|
+
const deliveryId = reserved[0].id;
|
|
125
|
+
const unsubscribeUrl = `${webBaseUrl.replace(/\/$/, "")}/unsubscribe/${recipient.unsubscribeToken}`;
|
|
126
|
+
const html = announcement.htmlBody.replaceAll("{{unsubscribe_url}}", unsubscribeUrl);
|
|
127
|
+
const text = announcement.textBody.replaceAll("{{unsubscribe_url}}", unsubscribeUrl);
|
|
128
|
+
try {
|
|
129
|
+
const result = await sendEmail2({
|
|
130
|
+
to: recipient.email,
|
|
131
|
+
subject: announcement.subject,
|
|
132
|
+
html,
|
|
133
|
+
text,
|
|
134
|
+
fromName: "RuleMetric",
|
|
135
|
+
idempotencyKey: deliveryId
|
|
136
|
+
});
|
|
137
|
+
await db.update(announcementDeliveries).set({
|
|
138
|
+
status: "sent",
|
|
139
|
+
providerId: result.id,
|
|
140
|
+
sentAt: /* @__PURE__ */ new Date()
|
|
141
|
+
}).where(eq(announcementDeliveries.id, deliveryId));
|
|
142
|
+
return { ok: "sent", providerId: result.id };
|
|
143
|
+
} catch (err) {
|
|
144
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
145
|
+
await db.update(announcementDeliveries).set({
|
|
146
|
+
status: "failed",
|
|
147
|
+
error: message.slice(0, 1e3)
|
|
148
|
+
}).where(eq(announcementDeliveries.id, deliveryId)).catch(() => {
|
|
149
|
+
});
|
|
150
|
+
return { ok: "failed", error: message };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export {
|
|
155
|
+
processAnnouncement
|
|
156
|
+
};
|
|
157
|
+
//# sourceMappingURL=chunk-GQCISMAH.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/lib/handlers/process-announcement.ts"],
|
|
4
|
+
"sourcesContent": ["import { and, asc, eq, gt, isNotNull } from 'drizzle-orm';\nimport {\n announcements,\n announcementDeliveries,\n notificationPreferences,\n profiles,\n getDb,\n} from '@rulemetric/db';\nimport { sendEmail as sendEmailDefault } from '@rulemetric/email';\nimport { PermanentJobError } from '../permanent-job-error.js';\n\nconst BATCH_SIZE = 100;\nconst CONCURRENCY = 10;\n\nexport interface ProcessAnnouncementPayload {\n announcementId: string;\n}\n\nexport interface ProcessAnnouncementResult {\n sent: number;\n failed: number;\n skipped: number;\n}\n\ntype SendEmailFn = typeof sendEmailDefault;\n\nexport interface ProcessAnnouncementDeps {\n db?: any;\n sendEmail?: SendEmailFn;\n log?: (msg: string) => void;\n /** Base URL used to build the unsubscribe link. */\n webBaseUrl?: string;\n}\n\n/**\n * Graphile-shaped handler for the `process_announcement` task.\n *\n * Sends a queued product announcement to every user opted in via\n * `notification_preferences.product_announcements = true`. There is no\n * mirror table \u2014 the `announcements` row itself carries lifecycle status\n * (draft \u2192 queued \u2192 sending \u2192 sent / failed).\n *\n * Idempotency (reserve-first pattern):\n * - Per recipient we INSERT the `announcement_deliveries` row with\n * status='pending' BEFORE calling the email provider, using\n * `ON CONFLICT (announcement_id, user_id) DO NOTHING`. If zero rows are\n * returned, another attempt already claimed this recipient \u2014 we skip.\n * This closes the crash window between \"email sent\" and \"delivery row\n * written\" \u2014 even if we never reach the UPDATE, a retry sees the\n * reserved row and does not re-send.\n * - The reserved row's UUID is passed as `idempotencyKey` to sendEmail,\n * so the provider (Resend) dedupes server-side for 24h. Defense in\n * depth: even if the same delivery row got reused across a long\n * retry-storm, the provider would coalesce the requests.\n * - Status='sending' is treated as resumable (a previous attempt\n * crashed mid-stream). Status='sent' or 'failed' throws \u2014 Graphile\n * should not re-fire on a terminal row.\n *\n * Per-recipient failures (sendEmail throws, bad email, provider 5xx) are\n * logged + recorded with status='failed' on the delivery row and DO NOT\n * fail the job. Only DB / auth-level failures escalate, since those\n * indicate the run can't make forward progress at all.\n */\nexport async function processAnnouncement(\n payload: ProcessAnnouncementPayload,\n deps: ProcessAnnouncementDeps = {},\n): Promise<ProcessAnnouncementResult> {\n const db = deps.db ?? getDb();\n const sendEmail = deps.sendEmail ?? sendEmailDefault;\n const log = deps.log ?? ((msg: string) => process.stderr.write(`[process_announcement] ${msg}\\n`));\n const webBaseUrl =\n deps.webBaseUrl ?? process.env.RULEMETRIC_WEB_URL ?? 'https://rulemetric.com';\n\n const { announcementId } = payload;\n\n // 1. Load + validate state\n const [announcement] = await db\n .select()\n .from(announcements)\n .where(eq(announcements.id, announcementId))\n .limit(1);\n\n if (!announcement) {\n throw new PermanentJobError(`Announcement ${announcementId} not found`);\n }\n\n // Allow status='sending' (resume after crash). Reject everything else\n // that isn't 'queued' \u2014 Graphile must not re-send a terminal row.\n if (announcement.status !== 'queued' && announcement.status !== 'sending') {\n throw new PermanentJobError(\n `Announcement ${announcementId} is in status='${announcement.status}'; expected 'queued' or 'sending'.`,\n );\n }\n\n // 2. Flip to 'sending' (idempotent on resume).\n await db\n .update(announcements)\n .set({ status: 'sending', updatedAt: new Date() })\n .where(eq(announcements.id, announcementId));\n\n log(`Sending announcement ${announcementId} (${announcement.subject ?? ''})`);\n\n let sent = 0;\n let failed = 0;\n let skipped = 0;\n let lastUserId: string | null = null;\n\n try {\n // 3. Iterate recipients in deterministic batches (userId ASC).\n while (true) {\n const recipients: Array<{\n userId: string;\n email: string | null;\n unsubscribeToken: string;\n }> = await db\n .select({\n userId: notificationPreferences.userId,\n email: profiles.email,\n unsubscribeToken: notificationPreferences.unsubscribeToken,\n })\n .from(notificationPreferences)\n .innerJoin(profiles, eq(profiles.id, notificationPreferences.userId))\n .where(\n and(\n eq(notificationPreferences.productAnnouncements, true),\n isNotNull(profiles.email),\n lastUserId ? gt(notificationPreferences.userId, lastUserId) : undefined,\n ),\n )\n .orderBy(asc(notificationPreferences.userId))\n .limit(BATCH_SIZE);\n\n if (recipients.length === 0) break;\n lastUserId = recipients[recipients.length - 1].userId;\n\n // 4. Send in concurrent chunks of CONCURRENCY. Each sendOne reserves\n // its own delivery row first; a concurrent retry that lost the\n // race returns ok='skipped'.\n for (let i = 0; i < recipients.length; i += CONCURRENCY) {\n const chunk = recipients.slice(i, i + CONCURRENCY);\n const results = await Promise.allSettled(\n chunk.map((r) =>\n sendOne({\n recipient: r,\n announcement,\n webBaseUrl,\n sendEmail,\n db,\n }),\n ),\n );\n for (let j = 0; j < results.length; j++) {\n const res = results[j];\n if (res.status === 'fulfilled') {\n if (res.value.ok === 'sent') sent++;\n else if (res.value.ok === 'skipped') skipped++;\n else {\n failed++;\n log(` recipient ${chunk[j].userId}: send failed \u2014 ${res.value.error}`);\n }\n } else {\n failed++;\n const reason = res.reason instanceof Error ? res.reason.message : String(res.reason);\n log(` recipient ${chunk[j].userId}: send failed \u2014 ${reason}`);\n }\n }\n }\n\n if (recipients.length < BATCH_SIZE) break;\n }\n\n // 6. Finalize. Mark 'sent' even on partial success \u2014 the admin can see\n // per-recipient deliveries for failure details.\n const errorSummary =\n failed > 0\n ? `${failed} of ${sent + failed} recipient(s) failed; see announcement_deliveries`\n : null;\n await db\n .update(announcements)\n .set({\n status: 'sent',\n recipientCount: sent,\n sentAt: new Date(),\n error: errorSummary,\n updatedAt: new Date(),\n })\n .where(eq(announcements.id, announcementId));\n\n log(`Done: sent=${sent} failed=${failed} skipped=${skipped}`);\n return { sent, failed, skipped };\n } catch (err) {\n // DB / auth-level failure: mark the row 'failed' and rethrow so\n // Graphile counts the attempt.\n const message = err instanceof Error ? err.message : String(err);\n await db\n .update(announcements)\n .set({\n status: 'failed',\n error: message.slice(0, 1000),\n updatedAt: new Date(),\n })\n .where(eq(announcements.id, announcementId))\n .catch(() => {});\n throw err;\n }\n}\n\ntype SendOneResult =\n | { ok: 'sent'; providerId: string }\n | { ok: 'skipped'; reason: 'already-claimed' | 'no-email' }\n | { ok: 'failed'; error: string };\n\nasync function sendOne(args: {\n recipient: { userId: string; email: string | null; unsubscribeToken: string };\n announcement: {\n id: string;\n subject: string;\n htmlBody: string;\n textBody: string;\n };\n webBaseUrl: string;\n sendEmail: SendEmailFn;\n db: any;\n}): Promise<SendOneResult> {\n const { recipient, announcement, webBaseUrl, sendEmail, db } = args;\n\n if (!recipient.email) {\n return { ok: 'skipped', reason: 'no-email' };\n }\n\n // 1. Reserve the delivery row before sending. ON CONFLICT DO NOTHING\n // returns zero rows if another attempt already claimed this recipient,\n // which is our signal to skip (no email, no UPDATE).\n const reserved: Array<{ id: string }> = await db\n .insert(announcementDeliveries)\n .values({\n announcementId: announcement.id,\n userId: recipient.userId,\n email: recipient.email,\n status: 'pending',\n })\n .onConflictDoNothing({\n target: [announcementDeliveries.announcementId, announcementDeliveries.userId],\n })\n .returning({ id: announcementDeliveries.id });\n\n if (reserved.length === 0) {\n return { ok: 'skipped', reason: 'already-claimed' };\n }\n const deliveryId = reserved[0].id;\n\n // 2. Send. The delivery row's UUID is the provider idempotency key \u2014\n // a retry-after-crash that hits the same reserved row will send the\n // same key, and Resend will return the original response instead of\n // actually re-sending the email.\n const unsubscribeUrl = `${webBaseUrl.replace(/\\/$/, '')}/unsubscribe/${recipient.unsubscribeToken}`;\n const html = announcement.htmlBody.replaceAll('{{unsubscribe_url}}', unsubscribeUrl);\n const text = announcement.textBody.replaceAll('{{unsubscribe_url}}', unsubscribeUrl);\n\n try {\n const result = await sendEmail({\n to: recipient.email,\n subject: announcement.subject,\n html,\n text,\n fromName: 'RuleMetric',\n idempotencyKey: deliveryId,\n });\n\n // 3. Promote the reserved row to 'sent'.\n await db\n .update(announcementDeliveries)\n .set({\n status: 'sent',\n providerId: result.id,\n sentAt: new Date(),\n })\n .where(eq(announcementDeliveries.id, deliveryId));\n\n return { ok: 'sent', providerId: result.id };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n // Promote the reserved row to 'failed'. We deliberately don't delete\n // the row \u2014 the reservation IS the dedup record, and the UPDATE keeps\n // a permanent audit trail of the failure reason.\n await db\n .update(announcementDeliveries)\n .set({\n status: 'failed',\n error: message.slice(0, 1000),\n })\n .where(eq(announcementDeliveries.id, deliveryId))\n .catch(() => {});\n return { ok: 'failed', error: message };\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["sendEmail"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runLlmPrompt
|
|
3
|
+
} from "./chunk-FZKLLNDS.js";
|
|
4
|
+
import {
|
|
5
|
+
getDb,
|
|
6
|
+
sessionEvents,
|
|
7
|
+
sessions
|
|
8
|
+
} from "./chunk-7FAA3YNB.js";
|
|
9
|
+
|
|
10
|
+
// src/lib/handlers/process-session-goal.ts
|
|
11
|
+
import { eq, asc, sql } from "drizzle-orm";
|
|
12
|
+
var ACTIVE_WINDOW_MS = 30 * 60 * 1e3;
|
|
13
|
+
var RECENT_WINDOW_MS = 5 * 60 * 1e3;
|
|
14
|
+
var MAX_TURNS = 10;
|
|
15
|
+
var PROMPT = `Given these messages from an AI coding session, write a 1-2 sentence summary of what the user is trying to accomplish. Focus on the goal, not the steps. No preamble.
|
|
16
|
+
|
|
17
|
+
Return strict JSON in the form: {"goalSummary": "..."}`;
|
|
18
|
+
async function processSessionGoal(payload, deps = {}) {
|
|
19
|
+
const db = deps.db ?? getDb();
|
|
20
|
+
const llm = deps.llm ?? runLlmPrompt;
|
|
21
|
+
const now = deps.now ?? Date.now;
|
|
22
|
+
const [s] = await db.select().from(sessions).where(eq(sessions.id, payload.sessionId)).limit(1);
|
|
23
|
+
if (!s) return { skipped: "not_found" };
|
|
24
|
+
const lastAtRows = await db.execute(
|
|
25
|
+
sql`SELECT MAX(timestamp) AS last_at FROM session_events WHERE session_id = ${payload.sessionId}`
|
|
26
|
+
);
|
|
27
|
+
const lastAtRaw = lastAtRows?.[0]?.last_at ?? s.startedAt;
|
|
28
|
+
const lastAt = new Date(lastAtRaw).getTime();
|
|
29
|
+
if (now() - lastAt > ACTIVE_WINDOW_MS) return { skipped: "stale" };
|
|
30
|
+
const analysis = s.analysis ?? {};
|
|
31
|
+
const lastGoalAt = analysis.goalSummaryAt ? new Date(analysis.goalSummaryAt).getTime() : 0;
|
|
32
|
+
if (lastGoalAt && now() - lastGoalAt < RECENT_WINDOW_MS) {
|
|
33
|
+
return { skipped: "recent" };
|
|
34
|
+
}
|
|
35
|
+
const events = await db.select().from(sessionEvents).where(eq(sessionEvents.sessionId, payload.sessionId)).orderBy(asc(sessionEvents.timestamp)).limit(MAX_TURNS * 2);
|
|
36
|
+
const turns = events.filter(
|
|
37
|
+
(e) => e.content && (e.eventType === "user_message" || e.eventType === "assistant_response")
|
|
38
|
+
).map(
|
|
39
|
+
(e) => `${e.eventType === "user_message" ? "USER" : "ASSISTANT"}: ${e.content}`
|
|
40
|
+
).join("\n\n");
|
|
41
|
+
if (!turns) return { skipped: "no_content" };
|
|
42
|
+
const parsed = await llm(PROMPT, turns, 200);
|
|
43
|
+
const summary = typeof parsed?.goalSummary === "string" ? parsed.goalSummary.trim() : "";
|
|
44
|
+
if (!summary) return { skipped: "llm_empty" };
|
|
45
|
+
const goalSummaryAt = new Date(now()).toISOString();
|
|
46
|
+
await db.update(sessions).set({
|
|
47
|
+
analysis: { ...analysis, goalSummary: summary, goalSummaryAt }
|
|
48
|
+
}).where(eq(sessions.id, payload.sessionId));
|
|
49
|
+
return { goalSummary: summary };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export {
|
|
53
|
+
processSessionGoal
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=chunk-IGXX624H.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/lib/handlers/process-session-goal.ts"],
|
|
4
|
+
"sourcesContent": ["import { eq, asc, sql } from 'drizzle-orm';\nimport { sessions, sessionEvents, getDb } from '@rulemetric/db';\nimport { runLlmPrompt } from '../llm-client.js';\n\nconst ACTIVE_WINDOW_MS = 30 * 60 * 1000;\nconst RECENT_WINDOW_MS = 5 * 60 * 1000;\nconst MAX_TURNS = 10;\n\nconst PROMPT = `Given these messages from an AI coding session, write a 1-2 sentence summary of what the user is trying to accomplish. Focus on the goal, not the steps. No preamble.\n\nReturn strict JSON in the form: {\"goalSummary\": \"...\"}`;\n\nexport interface ProcessSessionGoalPayload {\n sessionId: string;\n milestone: 5 | 20 | 50;\n}\n\nexport interface ProcessSessionGoalResult {\n skipped?: 'not_found' | 'stale' | 'recent' | 'no_content' | 'llm_empty';\n goalSummary?: string;\n}\n\nexport interface ProcessSessionGoalDeps {\n db?: any;\n llm?: typeof runLlmPrompt;\n now?: () => number;\n}\n\n/**\n * Fire-and-forget background job triggered at event milestones (5/20/50).\n * Generates a short \"what is the user trying to do\" summary and writes it\n * to `sessions.analysis.goalSummary` + `goalSummaryAt`, preserving any\n * existing analysis keys.\n *\n * Guards:\n * - stale: skip if no activity in last 30 min (session is dead, don't waste an LLM call)\n * - recent: skip if we already generated a summary in the last 5 min (dedup milestone burst)\n *\n * No mirror table \u2014 this is fire-and-forget, similar to crons. Errors\n * propagate so Graphile retries.\n */\nexport async function processSessionGoal(\n payload: ProcessSessionGoalPayload,\n deps: ProcessSessionGoalDeps = {},\n): Promise<ProcessSessionGoalResult> {\n const db = deps.db ?? getDb();\n const llm = deps.llm ?? runLlmPrompt;\n const now = deps.now ?? Date.now;\n\n const [s] = await db\n .select()\n .from(sessions)\n .where(eq(sessions.id, payload.sessionId))\n .limit(1);\n if (!s) return { skipped: 'not_found' };\n\n // Single-roundtrip MAX(timestamp) \u2014 fall back to startedAt if no events yet.\n const lastAtRows = await db.execute(\n sql`SELECT MAX(timestamp) AS last_at FROM session_events WHERE session_id = ${payload.sessionId}`,\n );\n const lastAtRaw = lastAtRows?.[0]?.last_at ?? s.startedAt;\n const lastAt = new Date(lastAtRaw as string | Date).getTime();\n if (now() - lastAt > ACTIVE_WINDOW_MS) return { skipped: 'stale' };\n\n const analysis = (s.analysis ?? {}) as Record<string, unknown>;\n const lastGoalAt = analysis.goalSummaryAt\n ? new Date(analysis.goalSummaryAt as string).getTime()\n : 0;\n if (lastGoalAt && now() - lastGoalAt < RECENT_WINDOW_MS) {\n return { skipped: 'recent' };\n }\n\n const events = await db\n .select()\n .from(sessionEvents)\n .where(eq(sessionEvents.sessionId, payload.sessionId))\n .orderBy(asc(sessionEvents.timestamp))\n .limit(MAX_TURNS * 2);\n\n const turns = (events as Array<{ eventType: string; content: string | null }>)\n .filter(\n (e) =>\n e.content &&\n (e.eventType === 'user_message' || e.eventType === 'assistant_response'),\n )\n .map(\n (e) =>\n `${e.eventType === 'user_message' ? 'USER' : 'ASSISTANT'}: ${e.content}`,\n )\n .join('\\n\\n');\n\n if (!turns) return { skipped: 'no_content' };\n\n // Let LLM errors throw \u2014 Graphile will retry.\n const parsed = await llm(PROMPT, turns, 200);\n const summary =\n typeof parsed?.goalSummary === 'string' ? parsed.goalSummary.trim() : '';\n if (!summary) return { skipped: 'llm_empty' };\n\n const goalSummaryAt = new Date(now()).toISOString();\n await db\n .update(sessions)\n .set({\n analysis: { ...analysis, goalSummary: summary, goalSummaryAt },\n })\n .where(eq(sessions.id, payload.sessionId));\n\n return { goalSummary: summary };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;AAAA,SAAS,IAAI,KAAK,WAAW;AAI7B,IAAM,mBAAmB,KAAK,KAAK;AACnC,IAAM,mBAAmB,IAAI,KAAK;AAClC,IAAM,YAAY;AAElB,IAAM,SAAS;AAAA;AAAA;AAiCf,eAAsB,mBACpB,SACA,OAA+B,CAAC,GACG;AACnC,QAAM,KAAK,KAAK,MAAM,MAAM;AAC5B,QAAM,MAAM,KAAK,OAAO;AACxB,QAAM,MAAM,KAAK,OAAO,KAAK;AAE7B,QAAM,CAAC,CAAC,IAAI,MAAM,GACf,OAAO,EACP,KAAK,QAAQ,EACb,MAAM,GAAG,SAAS,IAAI,QAAQ,SAAS,CAAC,EACxC,MAAM,CAAC;AACV,MAAI,CAAC,EAAG,QAAO,EAAE,SAAS,YAAY;AAGtC,QAAM,aAAa,MAAM,GAAG;AAAA,IAC1B,8EAA8E,QAAQ,SAAS;AAAA,EACjG;AACA,QAAM,YAAY,aAAa,CAAC,GAAG,WAAW,EAAE;AAChD,QAAM,SAAS,IAAI,KAAK,SAA0B,EAAE,QAAQ;AAC5D,MAAI,IAAI,IAAI,SAAS,iBAAkB,QAAO,EAAE,SAAS,QAAQ;AAEjE,QAAM,WAAY,EAAE,YAAY,CAAC;AACjC,QAAM,aAAa,SAAS,gBACxB,IAAI,KAAK,SAAS,aAAuB,EAAE,QAAQ,IACnD;AACJ,MAAI,cAAc,IAAI,IAAI,aAAa,kBAAkB;AACvD,WAAO,EAAE,SAAS,SAAS;AAAA,EAC7B;AAEA,QAAM,SAAS,MAAM,GAClB,OAAO,EACP,KAAK,aAAa,EAClB,MAAM,GAAG,cAAc,WAAW,QAAQ,SAAS,CAAC,EACpD,QAAQ,IAAI,cAAc,SAAS,CAAC,EACpC,MAAM,YAAY,CAAC;AAEtB,QAAM,QAAS,OACZ;AAAA,IACC,CAAC,MACC,EAAE,YACD,EAAE,cAAc,kBAAkB,EAAE,cAAc;AAAA,EACvD,EACC;AAAA,IACC,CAAC,MACC,GAAG,EAAE,cAAc,iBAAiB,SAAS,WAAW,KAAK,EAAE,OAAO;AAAA,EAC1E,EACC,KAAK,MAAM;AAEd,MAAI,CAAC,MAAO,QAAO,EAAE,SAAS,aAAa;AAG3C,QAAM,SAAS,MAAM,IAAI,QAAQ,OAAO,GAAG;AAC3C,QAAM,UACJ,OAAO,QAAQ,gBAAgB,WAAW,OAAO,YAAY,KAAK,IAAI;AACxE,MAAI,CAAC,QAAS,QAAO,EAAE,SAAS,YAAY;AAE5C,QAAM,gBAAgB,IAAI,KAAK,IAAI,CAAC,EAAE,YAAY;AAClD,QAAM,GACH,OAAO,QAAQ,EACf,IAAI;AAAA,IACH,UAAU,EAAE,GAAG,UAAU,aAAa,SAAS,cAAc;AAAA,EAC/D,CAAC,EACA,MAAM,GAAG,SAAS,IAAI,QAAQ,SAAS,CAAC;AAE3C,SAAO,EAAE,aAAa,QAAQ;AAChC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatCost,
|
|
3
|
+
formatTokens
|
|
4
|
+
} from "./chunk-DQ3KELXD.js";
|
|
5
|
+
import {
|
|
6
|
+
GOLD,
|
|
7
|
+
ORANGE
|
|
8
|
+
} from "./chunk-QJQS6TUN.js";
|
|
9
|
+
|
|
10
|
+
// src/dashboard/panels/overview.tsx
|
|
11
|
+
import { Box, Text } from "ink";
|
|
12
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
13
|
+
function Overview({ local, api, label, width }) {
|
|
14
|
+
const sessions = api?.total_sessions ?? local.totalSessions;
|
|
15
|
+
const messages = api?.total_messages ?? 0;
|
|
16
|
+
const inputTokens = api?.total_input_tokens ?? local.totalInputTokens;
|
|
17
|
+
const outputTokens = api?.total_output_tokens ?? local.totalOutputTokens;
|
|
18
|
+
const cacheRead = api?.total_cache_read_tokens ?? local.totalCacheReadTokens;
|
|
19
|
+
const cacheWrite = api?.total_cache_write_tokens ?? local.totalCacheWriteTokens;
|
|
20
|
+
const cost = api?.estimated_cost_usd ?? local.totalCostUSD;
|
|
21
|
+
const daysActive = api?.days_active ?? 0;
|
|
22
|
+
const commits = api?.git_commits ?? 0;
|
|
23
|
+
const allInput = inputTokens + cacheRead + cacheWrite;
|
|
24
|
+
const cacheHit = allInput > 0 ? cacheRead / allInput * 100 : 0;
|
|
25
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: ORANGE, paddingX: 1, width, children: [
|
|
26
|
+
/* @__PURE__ */ jsxs(Text, { wrap: "truncate-end", children: [
|
|
27
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: ORANGE, children: "RuleMetric" }),
|
|
28
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
29
|
+
" ",
|
|
30
|
+
label
|
|
31
|
+
] }),
|
|
32
|
+
api && /* @__PURE__ */ jsx(Text, { color: "#5BF58C", children: " \u25CF API connected" }),
|
|
33
|
+
!api && /* @__PURE__ */ jsx(Text, { color: "#F55B5B", children: " \u25CB API offline" })
|
|
34
|
+
] }),
|
|
35
|
+
/* @__PURE__ */ jsxs(Text, { wrap: "truncate-end", children: [
|
|
36
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: GOLD, children: formatCost(cost) }),
|
|
37
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " cost " }),
|
|
38
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: String(sessions) }),
|
|
39
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " sessions " }),
|
|
40
|
+
messages > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
41
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: messages.toLocaleString() }),
|
|
42
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " messages " })
|
|
43
|
+
] }),
|
|
44
|
+
/* @__PURE__ */ jsxs(Text, { bold: true, children: [
|
|
45
|
+
cacheHit.toFixed(1),
|
|
46
|
+
"%"
|
|
47
|
+
] }),
|
|
48
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " cache hit" })
|
|
49
|
+
] }),
|
|
50
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, wrap: "truncate-end", children: [
|
|
51
|
+
formatTokens(inputTokens),
|
|
52
|
+
" in ",
|
|
53
|
+
formatTokens(outputTokens),
|
|
54
|
+
" out ",
|
|
55
|
+
formatTokens(cacheRead),
|
|
56
|
+
" cached ",
|
|
57
|
+
formatTokens(cacheWrite),
|
|
58
|
+
" written",
|
|
59
|
+
daysActive > 0 ? ` ${daysActive} days active` : "",
|
|
60
|
+
commits > 0 ? ` ${commits} commits` : ""
|
|
61
|
+
] })
|
|
62
|
+
] });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export {
|
|
66
|
+
Overview
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=chunk-IJGF2ETG.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/dashboard/panels/overview.tsx"],
|
|
4
|
+
"sourcesContent": ["import React from 'react';\nimport { Box, Text } from 'ink';\nimport { ORANGE, GOLD } from '../types.js';\nimport type { LocalStats, ApiInsights } from '../types.js';\nimport { formatTokens, formatCost } from './shared.js';\n\nexport function Overview({ local, api, label, width }: {\n local: LocalStats; api: ApiInsights | null; label: string; width: number;\n}) {\n // Prefer API data when available (more complete), fall back to local\n const sessions = api?.total_sessions ?? local.totalSessions;\n const messages = api?.total_messages ?? 0;\n const inputTokens = api?.total_input_tokens ?? local.totalInputTokens;\n const outputTokens = api?.total_output_tokens ?? local.totalOutputTokens;\n const cacheRead = api?.total_cache_read_tokens ?? local.totalCacheReadTokens;\n const cacheWrite = api?.total_cache_write_tokens ?? local.totalCacheWriteTokens;\n const cost = api?.estimated_cost_usd ?? local.totalCostUSD;\n const daysActive = api?.days_active ?? 0;\n const commits = api?.git_commits ?? 0;\n\n const allInput = inputTokens + cacheRead + cacheWrite;\n const cacheHit = allInput > 0 ? (cacheRead / allInput) * 100 : 0;\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={ORANGE} paddingX={1} width={width}>\n <Text wrap=\"truncate-end\">\n <Text bold color={ORANGE}>RuleMetric</Text>\n <Text dimColor> {label}</Text>\n {api && <Text color=\"#5BF58C\"> \u25CF API connected</Text>}\n {!api && <Text color=\"#F55B5B\"> \u25CB API offline</Text>}\n </Text>\n <Text wrap=\"truncate-end\">\n <Text bold color={GOLD}>{formatCost(cost)}</Text>\n <Text dimColor> cost </Text>\n <Text bold>{String(sessions)}</Text>\n <Text dimColor> sessions </Text>\n {messages > 0 && <><Text bold>{messages.toLocaleString()}</Text><Text dimColor> messages </Text></>}\n <Text bold>{cacheHit.toFixed(1)}%</Text>\n <Text dimColor> cache hit</Text>\n </Text>\n <Text dimColor wrap=\"truncate-end\">\n {formatTokens(inputTokens)} in {formatTokens(outputTokens)} out {formatTokens(cacheRead)} cached {formatTokens(cacheWrite)} written\n {daysActive > 0 ? ` ${daysActive} days active` : ''}\n {commits > 0 ? ` ${commits} commits` : ''}\n </Text>\n </Box>\n );\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;AACA,SAAS,KAAK,YAAY;AAyBlB,SAUiB,UAVjB,KACA,YADA;AApBD,SAAS,SAAS,EAAE,OAAO,KAAK,OAAO,MAAM,GAEjD;AAED,QAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,QAAM,WAAW,KAAK,kBAAkB;AACxC,QAAM,cAAc,KAAK,sBAAsB,MAAM;AACrD,QAAM,eAAe,KAAK,uBAAuB,MAAM;AACvD,QAAM,YAAY,KAAK,2BAA2B,MAAM;AACxD,QAAM,aAAa,KAAK,4BAA4B,MAAM;AAC1D,QAAM,OAAO,KAAK,sBAAsB,MAAM;AAC9C,QAAM,aAAa,KAAK,eAAe;AACvC,QAAM,UAAU,KAAK,eAAe;AAEpC,QAAM,WAAW,cAAc,YAAY;AAC3C,QAAM,WAAW,WAAW,IAAK,YAAY,WAAY,MAAM;AAE/D,SACE,qBAAC,OAAI,eAAc,UAAS,aAAY,SAAQ,aAAa,QAAQ,UAAU,GAAG,OAChF;AAAA,yBAAC,QAAK,MAAK,gBACT;AAAA,0BAAC,QAAK,MAAI,MAAC,OAAO,QAAQ,wBAAU;AAAA,MACpC,qBAAC,QAAK,UAAQ,MAAC;AAAA;AAAA,QAAG;AAAA,SAAM;AAAA,MACvB,OAAO,oBAAC,QAAK,OAAM,WAAU,oCAAiB;AAAA,MAC9C,CAAC,OAAO,oBAAC,QAAK,OAAM,WAAU,kCAAe;AAAA,OAChD;AAAA,IACA,qBAAC,QAAK,MAAK,gBACT;AAAA,0BAAC,QAAK,MAAI,MAAC,OAAO,MAAO,qBAAW,IAAI,GAAE;AAAA,MAC1C,oBAAC,QAAK,UAAQ,MAAC,sBAAQ;AAAA,MACvB,oBAAC,QAAK,MAAI,MAAE,iBAAO,QAAQ,GAAE;AAAA,MAC7B,oBAAC,QAAK,UAAQ,MAAC,0BAAY;AAAA,MAC1B,WAAW,KAAK,iCAAE;AAAA,4BAAC,QAAK,MAAI,MAAE,mBAAS,eAAe,GAAE;AAAA,QAAO,oBAAC,QAAK,UAAQ,MAAC,0BAAY;AAAA,SAAO;AAAA,MAClG,qBAAC,QAAK,MAAI,MAAE;AAAA,iBAAS,QAAQ,CAAC;AAAA,QAAE;AAAA,SAAC;AAAA,MACjC,oBAAC,QAAK,UAAQ,MAAC,wBAAU;AAAA,OAC3B;AAAA,IACA,qBAAC,QAAK,UAAQ,MAAC,MAAK,gBACjB;AAAA,mBAAa,WAAW;AAAA,MAAE;AAAA,MAAO,aAAa,YAAY;AAAA,MAAE;AAAA,MAAQ,aAAa,SAAS;AAAA,MAAE;AAAA,MAAW,aAAa,UAAU;AAAA,MAAE;AAAA,MAChI,aAAa,IAAI,MAAM,UAAU,iBAAiB;AAAA,MAClD,UAAU,IAAI,MAAM,OAAO,aAAa;AAAA,OAC3C;AAAA,KACF;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import {
|
|
2
|
+
analyzeEvalResults
|
|
3
|
+
} from "./chunk-3TIMQ3O6.js";
|
|
4
|
+
import {
|
|
5
|
+
gradeEvalOutput
|
|
6
|
+
} from "./chunk-YNIH3KMU.js";
|
|
7
|
+
import {
|
|
8
|
+
executeEval
|
|
9
|
+
} from "./chunk-QN34TGD3.js";
|
|
10
|
+
import {
|
|
11
|
+
apiGet,
|
|
12
|
+
apiPost
|
|
13
|
+
} from "./chunk-EJOI2ZGU.js";
|
|
14
|
+
|
|
15
|
+
// src/lib/eval-conversation-handler.ts
|
|
16
|
+
async function processConversationJob(jobConfig, evalTargetId, logger) {
|
|
17
|
+
const { conversationId, messageId, messageContent } = jobConfig;
|
|
18
|
+
const target = await apiGet(`/api/eval-targets/${evalTargetId}`);
|
|
19
|
+
const evalCases = await apiGet(`/api/eval-targets/${evalTargetId}/evals`);
|
|
20
|
+
const messages = await apiGet(
|
|
21
|
+
`/api/eval-conversations/${conversationId}/messages`
|
|
22
|
+
);
|
|
23
|
+
const msgIdx = messages.findIndex((m) => m.id === messageId);
|
|
24
|
+
if (msgIdx >= 0) {
|
|
25
|
+
const hasResponse = messages.slice(msgIdx + 1).some(
|
|
26
|
+
(m) => m.role === "assistant" && (m.type === "results" || m.type === "proposal" || m.type === "generated" || m.type === "text")
|
|
27
|
+
);
|
|
28
|
+
if (hasResponse) {
|
|
29
|
+
logger(`Message ${messageId} already processed \u2014 skipping (idempotency guard)`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const postMessage = async (content, type, data) => {
|
|
34
|
+
await apiPost(`/api/eval-conversations/${conversationId}/messages/assistant`, {
|
|
35
|
+
content,
|
|
36
|
+
type,
|
|
37
|
+
data
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
const decision = await decideAction(target, evalCases, messages, messageContent, logger);
|
|
41
|
+
logger(`Action: ${decision.action}`);
|
|
42
|
+
switch (decision.action) {
|
|
43
|
+
case "run_evals":
|
|
44
|
+
await handleRunEvals(target, evalCases, conversationId, postMessage, logger);
|
|
45
|
+
break;
|
|
46
|
+
case "generate_cases":
|
|
47
|
+
await handleGenerateCases(target, evalTargetId, conversationId, postMessage, logger);
|
|
48
|
+
break;
|
|
49
|
+
case "analyze_results":
|
|
50
|
+
case "propose_changes":
|
|
51
|
+
await handleAnalyzeAndPropose(target, evalCases, messages, messageContent, conversationId, postMessage, logger);
|
|
52
|
+
break;
|
|
53
|
+
case "respond":
|
|
54
|
+
await postMessage(decision.response, "text");
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function decideAction(target, evalCases, messages, latestMessage, logger) {
|
|
59
|
+
const recentMessages = messages.slice(-10).map(
|
|
60
|
+
(m) => `${m.role}: ${m.content.slice(0, 200)}`
|
|
61
|
+
).join("\n");
|
|
62
|
+
const prompt = `You are an eval assistant. Decide what action to take based on the user's message.
|
|
63
|
+
|
|
64
|
+
## Current State
|
|
65
|
+
- Eval target: "${target.name}" v${target.version} (${target.type})
|
|
66
|
+
- Eval cases: ${evalCases.length} defined${evalCases.length > 0 ? ` (${evalCases.map((e) => e.name).join(", ")})` : ""}
|
|
67
|
+
- Content length: ${target.content.length} chars
|
|
68
|
+
|
|
69
|
+
## Recent Conversation
|
|
70
|
+
${recentMessages}
|
|
71
|
+
|
|
72
|
+
## User's Latest Message
|
|
73
|
+
${latestMessage}
|
|
74
|
+
|
|
75
|
+
## Available Actions
|
|
76
|
+
- run_evals: Run all eval cases against current version (with + without target). Choose this when the user wants to test, evaluate, or see how the instruction performs.
|
|
77
|
+
- generate_cases: Auto-generate eval test cases from the instruction content. Choose this when there are no eval cases (${evalCases.length} currently) or user asks to create/generate tests.
|
|
78
|
+
- analyze_results: Analyze recent eval failures and propose improvements based on user feedback. Choose this when user gives qualitative feedback like "this is wrong", "missing X", etc.
|
|
79
|
+
- propose_changes: Propose specific content edits based on conversation. Choose this when user asks for improvements or changes.
|
|
80
|
+
- respond: Just answer a question without running any evals. Choose this for informational questions.
|
|
81
|
+
|
|
82
|
+
Respond with ONLY valid JSON:
|
|
83
|
+
{"action": "run_evals", "response": "What you want to say to the user", "params": {}}`;
|
|
84
|
+
const result = await executeEval({ prompt, timeout: 3e4 });
|
|
85
|
+
try {
|
|
86
|
+
let jsonStr = result.output.trim();
|
|
87
|
+
const jsonMatch = jsonStr.match(/\{[\s\S]*\}/);
|
|
88
|
+
if (jsonMatch) jsonStr = jsonMatch[0];
|
|
89
|
+
return JSON.parse(jsonStr);
|
|
90
|
+
} catch {
|
|
91
|
+
logger("Failed to parse action decision, defaulting to respond");
|
|
92
|
+
const lower = latestMessage.toLowerCase();
|
|
93
|
+
if (lower.includes("run") || lower.includes("test") || lower.includes("eval")) {
|
|
94
|
+
return { action: "run_evals", response: "Running evals now..." };
|
|
95
|
+
}
|
|
96
|
+
if (lower.includes("generate") || lower.includes("create") || evalCases.length === 0 && lower.includes("start")) {
|
|
97
|
+
return { action: "generate_cases", response: "Generating test cases..." };
|
|
98
|
+
}
|
|
99
|
+
return { action: "respond", response: "I can help you run evals, generate test cases, or analyze results. What would you like to do?" };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async function handleRunEvals(target, evalCases, _conversationId, postMessage, logger) {
|
|
103
|
+
if (evalCases.length === 0) {
|
|
104
|
+
await postMessage(
|
|
105
|
+
"No eval cases exist yet. Would you like me to generate some from the instruction content?",
|
|
106
|
+
"text"
|
|
107
|
+
);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
await postMessage(`Running ${evalCases.length} evals against "${target.name}" v${target.version}...`, "status");
|
|
111
|
+
const results = [];
|
|
112
|
+
for (const eval_ of evalCases) {
|
|
113
|
+
logger(`Running: ${eval_.name} (with_target)`);
|
|
114
|
+
const execResult = await executeEval({
|
|
115
|
+
prompt: eval_.prompt,
|
|
116
|
+
targetContent: target.content,
|
|
117
|
+
timeout: 12e4
|
|
118
|
+
});
|
|
119
|
+
let passed = false;
|
|
120
|
+
let evidence = "";
|
|
121
|
+
if (!execResult.error && eval_.expectations.length > 0) {
|
|
122
|
+
const grading = await gradeEvalOutput({
|
|
123
|
+
prompt: eval_.prompt,
|
|
124
|
+
output: execResult.output,
|
|
125
|
+
expectations: eval_.expectations,
|
|
126
|
+
timeout: 12e4
|
|
127
|
+
});
|
|
128
|
+
const summary = grading?.summary;
|
|
129
|
+
passed = summary?.pass_rate >= 1;
|
|
130
|
+
evidence = grading?.expectations?.map((e) => `${e.passed ? "PASS" : "FAIL"}: ${e.text} \u2014 ${e.evidence}`).join("\n") ?? "";
|
|
131
|
+
}
|
|
132
|
+
results.push({
|
|
133
|
+
evalName: eval_.name,
|
|
134
|
+
passed,
|
|
135
|
+
output: execResult.error ?? execResult.output.slice(0, 2e3),
|
|
136
|
+
expectations: eval_.expectations,
|
|
137
|
+
evidence,
|
|
138
|
+
configuration: "with_target"
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const passedCount = results.filter((r) => r.passed).length;
|
|
142
|
+
const total = results.length;
|
|
143
|
+
await postMessage(
|
|
144
|
+
`${passedCount} of ${total} evals passed (${Math.round(passedCount / total * 100)}%)`,
|
|
145
|
+
"results",
|
|
146
|
+
{
|
|
147
|
+
summary: { passed: passedCount, failed: total - passedCount, total, passRate: passedCount / total },
|
|
148
|
+
results: results.map((r) => ({
|
|
149
|
+
evalName: r.evalName,
|
|
150
|
+
passed: r.passed,
|
|
151
|
+
output: r.output,
|
|
152
|
+
expectations: r.expectations,
|
|
153
|
+
evidence: r.evidence
|
|
154
|
+
}))
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
async function handleGenerateCases(target, _evalTargetId, _conversationId, postMessage, logger) {
|
|
159
|
+
await postMessage("Generating eval cases from instruction content...", "status");
|
|
160
|
+
logger("Calling eval-from-context endpoint");
|
|
161
|
+
const result = await apiPost("/api/eval-from-context", {
|
|
162
|
+
contentHash: "",
|
|
163
|
+
name: target.name,
|
|
164
|
+
type: target.type,
|
|
165
|
+
content: target.content,
|
|
166
|
+
config: { skipBaseline: false, skipGrading: false }
|
|
167
|
+
});
|
|
168
|
+
const cases = result.evals ?? [];
|
|
169
|
+
await postMessage(
|
|
170
|
+
`Generated ${cases.length} eval cases. Review them below:`,
|
|
171
|
+
"generated",
|
|
172
|
+
{
|
|
173
|
+
cases: cases.map((c) => ({
|
|
174
|
+
id: c.id,
|
|
175
|
+
name: c.name,
|
|
176
|
+
prompt: c.prompt,
|
|
177
|
+
expectations: c.expectations
|
|
178
|
+
}))
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
async function handleAnalyzeAndPropose(target, evalCases, messages, userFeedback, _conversationId, postMessage, logger) {
|
|
183
|
+
await postMessage("Analyzing results and preparing improvements...", "status");
|
|
184
|
+
const lastResults = [...messages].reverse().find((m) => m.type === "results");
|
|
185
|
+
const evalResults = lastResults?.data?.results?.map((r) => ({
|
|
186
|
+
evalName: r.evalName,
|
|
187
|
+
prompt: "",
|
|
188
|
+
expectations: r.expectations ?? [],
|
|
189
|
+
grading: {
|
|
190
|
+
summary: { pass_rate: r.passed ? 1 : 0 },
|
|
191
|
+
expectations: r.expectations?.map((e) => ({
|
|
192
|
+
text: e,
|
|
193
|
+
passed: r.passed,
|
|
194
|
+
evidence: r.evidence ?? ""
|
|
195
|
+
}))
|
|
196
|
+
}
|
|
197
|
+
})) ?? [];
|
|
198
|
+
logger(`Analyzing ${evalResults.length} eval results with user feedback`);
|
|
199
|
+
const analysis = await analyzeEvalResults({
|
|
200
|
+
content: target.content,
|
|
201
|
+
evalResults,
|
|
202
|
+
model: void 0,
|
|
203
|
+
timeout: 12e4,
|
|
204
|
+
userFeedback
|
|
205
|
+
});
|
|
206
|
+
await postMessage(
|
|
207
|
+
analysis.overallAssessment,
|
|
208
|
+
"proposal",
|
|
209
|
+
{
|
|
210
|
+
suggestions: analysis.suggestions,
|
|
211
|
+
proposedContent: analysis.proposedContent,
|
|
212
|
+
fromVersion: target.version
|
|
213
|
+
}
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export {
|
|
218
|
+
processConversationJob
|
|
219
|
+
};
|
|
220
|
+
//# sourceMappingURL=chunk-IWYCRLEK.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/lib/eval-conversation-handler.ts"],
|
|
4
|
+
"sourcesContent": ["import { apiGet, apiPost } from './api-client.js';\nimport { executeEval } from './eval-executor.js';\nimport { gradeEvalOutput } from './eval-grader.js';\nimport { analyzeEvalResults } from './eval-analyzer.js';\n\ninterface ConversationMessage {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n type?: string;\n data?: Record<string, unknown>;\n createdAt: string;\n}\n\ninterface EvalTarget {\n id: string;\n name: string;\n type: string;\n content: string;\n description: string;\n version: number;\n}\n\ninterface EvalCase {\n id: string;\n name: string;\n prompt: string;\n expectedOutput: string;\n expectations: string[];\n}\n\ninterface ConversationJobConfig {\n type: 'conversation';\n conversationId: string;\n messageId: string;\n messageContent: string;\n}\n\ninterface ActionDecision {\n action: 'run_evals' | 'generate_cases' | 'analyze_results' | 'propose_changes' | 'respond';\n response: string;\n params?: Record<string, unknown>;\n}\n\nexport async function processConversationJob(\n jobConfig: ConversationJobConfig,\n evalTargetId: string,\n logger: (msg: string) => void,\n): Promise<void> {\n const { conversationId, messageId, messageContent } = jobConfig;\n\n // Fetch context\n const target = await apiGet<EvalTarget>(`/api/eval-targets/${evalTargetId}`);\n const evalCases = await apiGet<EvalCase[]>(`/api/eval-targets/${evalTargetId}/evals`);\n const messages = await apiGet<ConversationMessage[]>(\n `/api/eval-conversations/${conversationId}/messages`,\n );\n\n // Idempotency: check if this message was already processed (has assistant responses after it)\n const msgIdx = messages.findIndex((m) => m.id === messageId);\n if (msgIdx >= 0) {\n const hasResponse = messages.slice(msgIdx + 1).some(\n (m) => m.role === 'assistant' && (m.type === 'results' || m.type === 'proposal' || m.type === 'generated' || m.type === 'text'),\n );\n if (hasResponse) {\n logger(`Message ${messageId} already processed \u2014 skipping (idempotency guard)`);\n return;\n }\n }\n\n // Helper to post assistant messages\n const postMessage = async (content: string, type: string, data?: Record<string, unknown>) => {\n await apiPost(`/api/eval-conversations/${conversationId}/messages/assistant`, {\n content,\n type,\n data,\n });\n };\n\n // Decide what action to take\n const decision = await decideAction(target, evalCases, messages, messageContent, logger);\n\n logger(`Action: ${decision.action}`);\n\n switch (decision.action) {\n case 'run_evals':\n await handleRunEvals(target, evalCases, conversationId, postMessage, logger);\n break;\n\n case 'generate_cases':\n await handleGenerateCases(target, evalTargetId, conversationId, postMessage, logger);\n break;\n\n case 'analyze_results':\n case 'propose_changes':\n await handleAnalyzeAndPropose(target, evalCases, messages, messageContent, conversationId, postMessage, logger);\n break;\n\n case 'respond':\n await postMessage(decision.response, 'text');\n break;\n }\n}\n\nasync function decideAction(\n target: EvalTarget,\n evalCases: EvalCase[],\n messages: ConversationMessage[],\n latestMessage: string,\n logger: (msg: string) => void,\n): Promise<ActionDecision> {\n // Build conversation summary for context\n const recentMessages = messages.slice(-10).map((m) =>\n `${m.role}: ${m.content.slice(0, 200)}`\n ).join('\\n');\n\n const prompt = `You are an eval assistant. Decide what action to take based on the user's message.\n\n## Current State\n- Eval target: \"${target.name}\" v${target.version} (${target.type})\n- Eval cases: ${evalCases.length} defined${evalCases.length > 0 ? ` (${evalCases.map((e) => e.name).join(', ')})` : ''}\n- Content length: ${target.content.length} chars\n\n## Recent Conversation\n${recentMessages}\n\n## User's Latest Message\n${latestMessage}\n\n## Available Actions\n- run_evals: Run all eval cases against current version (with + without target). Choose this when the user wants to test, evaluate, or see how the instruction performs.\n- generate_cases: Auto-generate eval test cases from the instruction content. Choose this when there are no eval cases (${evalCases.length} currently) or user asks to create/generate tests.\n- analyze_results: Analyze recent eval failures and propose improvements based on user feedback. Choose this when user gives qualitative feedback like \"this is wrong\", \"missing X\", etc.\n- propose_changes: Propose specific content edits based on conversation. Choose this when user asks for improvements or changes.\n- respond: Just answer a question without running any evals. Choose this for informational questions.\n\nRespond with ONLY valid JSON:\n{\"action\": \"run_evals\", \"response\": \"What you want to say to the user\", \"params\": {}}`;\n\n const result = await executeEval({ prompt, timeout: 30_000 });\n\n try {\n let jsonStr = result.output.trim();\n const jsonMatch = jsonStr.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) jsonStr = jsonMatch[0];\n return JSON.parse(jsonStr) as ActionDecision;\n } catch {\n logger('Failed to parse action decision, defaulting to respond');\n // Fallback: simple heuristics\n const lower = latestMessage.toLowerCase();\n if (lower.includes('run') || lower.includes('test') || lower.includes('eval')) {\n return { action: 'run_evals', response: 'Running evals now...' };\n }\n if (lower.includes('generate') || lower.includes('create') || (evalCases.length === 0 && lower.includes('start'))) {\n return { action: 'generate_cases', response: 'Generating test cases...' };\n }\n return { action: 'respond', response: 'I can help you run evals, generate test cases, or analyze results. What would you like to do?' };\n }\n}\n\nasync function handleRunEvals(\n target: EvalTarget,\n evalCases: EvalCase[],\n _conversationId: string,\n postMessage: (content: string, type: string, data?: Record<string, unknown>) => Promise<void>,\n logger: (msg: string) => void,\n): Promise<void> {\n if (evalCases.length === 0) {\n await postMessage(\n 'No eval cases exist yet. Would you like me to generate some from the instruction content?',\n 'text',\n );\n return;\n }\n\n await postMessage(`Running ${evalCases.length} evals against \"${target.name}\" v${target.version}...`, 'status');\n\n const results: Array<{\n evalName: string;\n passed: boolean;\n output: string;\n expectations: string[];\n evidence: string;\n configuration: string;\n }> = [];\n\n // Run with_target\n for (const eval_ of evalCases) {\n logger(`Running: ${eval_.name} (with_target)`);\n const execResult = await executeEval({\n prompt: eval_.prompt,\n targetContent: target.content,\n timeout: 120_000,\n });\n\n let passed = false;\n let evidence = '';\n\n if (!execResult.error && eval_.expectations.length > 0) {\n const grading = await gradeEvalOutput({\n prompt: eval_.prompt,\n output: execResult.output,\n expectations: eval_.expectations,\n timeout: 120_000,\n });\n const summary = (grading as any)?.summary;\n passed = summary?.pass_rate >= 1.0;\n evidence = (grading as any)?.expectations\n ?.map((e: any) => `${e.passed ? 'PASS' : 'FAIL'}: ${e.text} \u2014 ${e.evidence}`)\n .join('\\n') ?? '';\n }\n\n results.push({\n evalName: eval_.name,\n passed,\n output: execResult.error ?? execResult.output.slice(0, 2000),\n expectations: eval_.expectations,\n evidence,\n configuration: 'with_target',\n });\n }\n\n const passedCount = results.filter((r) => r.passed).length;\n const total = results.length;\n\n await postMessage(\n `${passedCount} of ${total} evals passed (${Math.round((passedCount / total) * 100)}%)`,\n 'results',\n {\n summary: { passed: passedCount, failed: total - passedCount, total, passRate: passedCount / total },\n results: results.map((r) => ({\n evalName: r.evalName,\n passed: r.passed,\n output: r.output,\n expectations: r.expectations,\n evidence: r.evidence,\n })),\n },\n );\n}\n\nasync function handleGenerateCases(\n target: EvalTarget,\n _evalTargetId: string,\n _conversationId: string,\n postMessage: (content: string, type: string, data?: Record<string, unknown>) => Promise<void>,\n logger: (msg: string) => void,\n): Promise<void> {\n await postMessage('Generating eval cases from instruction content...', 'status');\n\n logger('Calling eval-from-context endpoint');\n\n // Use eval-from-context endpoint\n const result = await apiPost<{\n evalTarget: { id: string };\n evals: Array<{ id: string; name: string; prompt: string; expectations: string[] }>;\n job: { id: string } | null;\n }>('/api/eval-from-context', {\n contentHash: '',\n name: target.name,\n type: target.type,\n content: target.content,\n config: { skipBaseline: false, skipGrading: false },\n });\n\n const cases = result.evals ?? [];\n\n await postMessage(\n `Generated ${cases.length} eval cases. Review them below:`,\n 'generated',\n {\n cases: cases.map((c) => ({\n id: c.id,\n name: c.name,\n prompt: c.prompt,\n expectations: c.expectations,\n })),\n },\n );\n}\n\nasync function handleAnalyzeAndPropose(\n target: EvalTarget,\n evalCases: EvalCase[],\n messages: ConversationMessage[],\n userFeedback: string,\n _conversationId: string,\n postMessage: (content: string, type: string, data?: Record<string, unknown>) => Promise<void>,\n logger: (msg: string) => void,\n): Promise<void> {\n await postMessage('Analyzing results and preparing improvements...', 'status');\n\n // Find the most recent results message for context\n const lastResults = [...messages]\n .reverse()\n .find((m) => m.type === 'results');\n\n const evalResults = (lastResults?.data as any)?.results?.map((r: any) => ({\n evalName: r.evalName,\n prompt: '',\n expectations: r.expectations ?? [],\n grading: {\n summary: { pass_rate: r.passed ? 1 : 0 },\n expectations: r.expectations?.map((e: string) => ({\n text: e,\n passed: r.passed,\n evidence: r.evidence ?? '',\n })),\n },\n })) ?? [];\n\n logger(`Analyzing ${evalResults.length} eval results with user feedback`);\n\n // Include user feedback in the analysis\n const analysis = await analyzeEvalResults({\n content: target.content,\n evalResults,\n model: undefined,\n timeout: 120_000,\n userFeedback,\n });\n\n await postMessage(\n analysis.overallAssessment,\n 'proposal',\n {\n suggestions: analysis.suggestions,\n proposedContent: analysis.proposedContent,\n fromVersion: target.version,\n },\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|