@rulemetric/cli 0.7.2 → 0.7.4
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 +1 -14
- package/dist/chunk-2TC6WCUT.js +34 -0
- package/dist/chunk-2UC3ULIG.js +1 -0
- package/dist/chunk-3AV3GTMP.js +1 -0
- package/dist/chunk-4Z5ECCJE.js +1 -0
- package/dist/chunk-5RBLIVBF.js +1 -0
- package/dist/chunk-67QCYUJU.js +1 -0
- package/dist/chunk-6QKI756T.js +2 -0
- package/dist/chunk-6V4WM73L.js +1 -0
- package/dist/chunk-6XEC6474.js +1 -0
- package/dist/chunk-72XLQE3X.js +2 -0
- package/dist/chunk-7DFNBRLY.js +61 -0
- package/dist/chunk-7XQ4VPLC.js +2 -0
- package/dist/chunk-AHRHCERJ.js +1 -0
- package/dist/chunk-ARNZQBMX.js +1 -0
- package/dist/chunk-CADKBP3D.js +58 -0
- package/dist/chunk-CDI5CCHU.js +1 -0
- package/dist/chunk-CNQ5DTNC.js +1 -0
- package/dist/chunk-CRAKDQ4H.js +1 -0
- package/dist/chunk-DNF4HDI6.js +14 -0
- package/dist/chunk-DSO2U4Y6.js +56 -0
- package/dist/chunk-DT4GKEP5.js +5 -0
- package/dist/chunk-DVN7GFJG.js +1 -0
- package/dist/chunk-E4SFUPYR.js +15 -0
- package/dist/chunk-EUHNCVJQ.js +33 -0
- package/dist/chunk-F2VP4B4J.js +1 -0
- package/dist/chunk-FEHM5OKW.js +1 -0
- package/dist/chunk-FHVBTDBM.js +69 -0
- package/dist/chunk-GBMF3TP6.js +1 -0
- package/dist/chunk-GY5IJ4RS.js +1 -0
- package/dist/chunk-HOHD5HY2.js +5 -0
- package/dist/chunk-HP2BUPGS.js +24 -0
- package/dist/{chunk-OQBBVTDG.js → chunk-I2DZGJRR.js} +6 -71
- package/dist/chunk-I4YJ7NTX.js +1 -0
- package/dist/chunk-IY5NXR3N.js +1 -0
- package/dist/chunk-IZTIYR5Q.js +2 -0
- package/dist/chunk-KKDHD4XA.js +2 -0
- package/dist/chunk-LQRYQE6Q.js +4 -0
- package/dist/chunk-M6AJDVCL.js +5 -0
- package/dist/chunk-MGHFDHHM.js +1 -0
- package/dist/chunk-ML36XQW7.js +1 -0
- package/dist/chunk-MODXEGCU.js +1 -0
- package/dist/chunk-MVM6OGAF.js +4 -0
- package/dist/chunk-N7ODX6PO.js +1 -0
- package/dist/chunk-NBTC5FNV.js +1 -0
- package/dist/chunk-NJ5UED3H.js +1 -0
- package/dist/chunk-NVKX36YN.js +3 -0
- package/dist/chunk-NVOTOQBA.js +1 -0
- package/dist/chunk-O7ZMHCMG.js +31 -0
- package/dist/chunk-OMXUK4M6.js +1 -0
- package/dist/chunk-PZS2KOU7.js +1 -0
- package/dist/chunk-RSKQRVPJ.js +1 -0
- package/dist/chunk-RTEATXTP.js +1 -0
- package/dist/chunk-RTWRHIKY.js +7 -0
- package/dist/chunk-RVO4HV3M.js +1 -0
- package/dist/chunk-SBILN45P.js +1 -0
- package/dist/chunk-SZ62CP55.js +1 -0
- package/dist/chunk-T3W5N3BP.js +2 -0
- package/dist/chunk-TDD7IOV2.js +1 -0
- package/dist/chunk-TIQ7DQ3M.js +1 -0
- package/dist/chunk-TU2AR6XO.js +1 -0
- package/dist/chunk-UF6US7VU.js +1 -0
- package/dist/chunk-V5QFOF4F.js +9 -0
- package/dist/chunk-V5U3E4BZ.js +1 -0
- package/dist/chunk-VAFAH6QL.js +1 -0
- package/dist/chunk-VMWY7KHH.js +1 -0
- package/dist/chunk-VUGRXM7R.js +1 -0
- package/dist/{chunk-XZXS2W24.js → chunk-VWEXKDWG.js} +10 -56
- package/dist/chunk-W2MV25SB.js +1 -0
- package/dist/chunk-WJ3H73G6.js +1 -0
- package/dist/chunk-WJUQBMTF.js +9 -0
- package/dist/chunk-WLVQJH4E.js +1 -0
- package/dist/chunk-WPJ2BND4.js +1 -0
- package/dist/chunk-WSCK4WNK.js +1 -0
- package/dist/chunk-Y65CSJFF.js +3 -0
- package/dist/chunk-ZL4MZMUK.js +34 -0
- package/dist/chunk-ZLLER3HP.js +1 -0
- package/dist/chunk-ZXF5NE54.js +1 -0
- package/dist/commands/antigravity/backfill.js +2 -136
- package/dist/commands/auth/create-key.js +1 -52
- package/dist/commands/auth/login.js +1 -85
- package/dist/commands/auth/logout.js +1 -29
- package/dist/commands/auth/revoke-key.js +1 -33
- package/dist/commands/auth/signup.js +1 -89
- package/dist/commands/auth/status.js +1 -42
- package/dist/commands/catalog/index.js +2 -52
- package/dist/commands/catalog/recommend.js +3 -43
- package/dist/commands/convert.js +1 -75
- package/dist/commands/converters.js +1 -54
- package/dist/commands/crons/list.js +1 -41
- package/dist/commands/crons/run.js +2 -76
- package/dist/commands/dashboard.js +1 -46
- package/dist/commands/diagnostics.js +1 -117
- package/dist/commands/eval-targets/create.js +1 -53
- package/dist/commands/eval-targets/list.js +1 -54
- package/dist/commands/evals/agent.js +3 -309
- package/dist/commands/evals/benchmark.js +6 -73
- package/dist/commands/evals/compare.js +13 -96
- package/dist/commands/evals/create.js +1 -67
- package/dist/commands/evals/optimize-description.js +25 -239
- package/dist/commands/evals/optimize.js +5 -211
- package/dist/commands/evals/run.js +3 -183
- package/dist/commands/gateway/ensure.js +1 -104
- package/dist/commands/hooks/emit-instructions.js +1 -25
- package/dist/commands/hooks/install.js +1 -442
- package/dist/commands/hooks/run.js +3 -81
- package/dist/commands/hooks/uninstall.js +2 -156
- package/dist/commands/import.js +1 -66
- package/dist/commands/instructions/create.js +1 -74
- package/dist/commands/instructions/delete.js +1 -55
- package/dist/commands/instructions/fork.js +1 -34
- package/dist/commands/instructions/get.js +1 -68
- package/dist/commands/instructions/list.js +1 -65
- package/dist/commands/instructions/promote.js +1 -42
- package/dist/commands/instructions/pull.js +1 -39
- package/dist/commands/instructions/upstream.js +1 -38
- package/dist/commands/instructions/versions.js +1 -53
- package/dist/commands/launcher.js +1 -40
- package/dist/commands/org/current.js +1 -77
- package/dist/commands/org/list.js +1 -52
- package/dist/commands/org/switch.js +1 -71
- package/dist/commands/packs/add-instruction.js +1 -37
- package/dist/commands/packs/apply.js +1 -39
- package/dist/commands/packs/create.js +1 -50
- package/dist/commands/packs/fork.js +1 -34
- package/dist/commands/packs/get.js +3 -56
- package/dist/commands/packs/list.js +1 -66
- package/dist/commands/packs/remove-instruction.js +1 -35
- package/dist/commands/proxy/env.js +3 -131
- package/dist/commands/proxy/logs.js +3 -85
- package/dist/commands/proxy/restart.js +1 -35
- package/dist/commands/proxy/setup.js +15 -454
- package/dist/commands/proxy/start.js +10 -333
- package/dist/commands/proxy/status.js +1 -78
- package/dist/commands/proxy/stop.js +1 -94
- package/dist/commands/research/backfill.js +1 -59
- package/dist/commands/research/tail-transcript.js +1 -70
- package/dist/commands/service/install.js +57 -781
- package/dist/commands/service/status.js +1 -180
- package/dist/commands/service/uninstall.js +1 -119
- package/dist/commands/sessions/analyze.js +3 -48
- package/dist/commands/sessions/end.js +2 -85
- package/dist/commands/sessions/import.js +1 -46
- package/dist/commands/sessions/list.js +1 -48
- package/dist/commands/sessions/start.js +3 -90
- package/dist/commands/setup.js +3 -150
- package/dist/commands/skills/export-approved.js +1 -46
- package/dist/commands/skills/install.js +4 -107
- package/dist/commands/skills/list.js +4 -65
- package/dist/commands/skills/publish.js +2 -98
- package/dist/commands/skills/search.js +3 -72
- package/dist/commands/skills/update.js +3 -55
- package/dist/commands/suggestions/accept.js +8 -84
- package/dist/commands/suggestions/dismiss.js +1 -45
- package/dist/commands/suggestions/list.js +1 -61
- package/dist/commands/suggestions/refresh.js +1 -27
- package/dist/cursor-T7AMCMKS.js +13 -0
- package/dist/dashboard/Dashboard.js +1 -243
- package/dist/dashboard/data.js +1 -15
- package/dist/dashboard/launcher/ActiveJobsList.js +1 -10
- package/dist/dashboard/launcher/LauncherOverlay.js +1 -16
- package/dist/dashboard/launcher/NewLaunchForm.js +1 -10
- package/dist/dashboard/launcher/api.js +1 -16
- package/dist/dashboard/launcher/tool-labels.js +1 -10
- package/dist/dashboard/launcher/types.js +0 -1
- package/dist/dashboard/launcher/useLaunchJobs.js +1 -11
- package/dist/dashboard/panels/friction.js +1 -10
- package/dist/dashboard/panels/insights.js +1 -10
- package/dist/dashboard/panels/instructions.js +1 -10
- package/dist/dashboard/panels/outcomes.js +1 -10
- package/dist/dashboard/panels/overview.js +1 -10
- package/dist/dashboard/panels/shared.js +1 -19
- package/dist/dashboard/types.js +1 -24
- package/dist/dist-FAVALJ5C.js +1 -0
- package/dist/index.js +1 -8
- package/dist/lib/active-org-refresh.js +1 -15
- package/dist/lib/active-org.js +1 -16
- package/dist/lib/agent-loop.js +1 -46
- package/dist/lib/antigravity-transcript.js +1 -22
- package/dist/lib/api-client.js +1 -23
- package/dist/lib/auth.js +1 -30
- package/dist/lib/capture-hosts.js +1 -8
- package/dist/lib/detect-languages.js +1 -8
- package/dist/lib/detect-tmux.js +1 -9
- package/dist/lib/diagnostics.js +1 -12
- package/dist/lib/editor-proxy-pins.js +1 -14
- package/dist/lib/ensure-api-key.js +1 -11
- package/dist/lib/eval-analyzer.js +1 -9
- package/dist/lib/eval-benchmark.js +1 -12
- package/dist/lib/eval-conversation-handler.js +1 -13
- package/dist/lib/eval-executor.js +1 -8
- package/dist/lib/eval-grader.js +1 -9
- package/dist/lib/eval-meta-judge.js +1 -9
- package/dist/lib/eval-trigger-tester.js +1 -11
- package/dist/lib/eval-worktree.js +1 -8
- package/dist/lib/gateway-entry.js +1 -61
- package/dist/lib/gateway-identity.js +1 -16
- package/dist/lib/gateway-lifecycle.js +1 -32
- package/dist/lib/gateway.js +1 -14
- package/dist/lib/handlers/cron-refresh-pricing.js +1 -0
- package/dist/lib/handlers/cron-refresh-skills.js +1 -8
- package/dist/lib/handlers/cron-suggest-instructions.js +1 -15
- package/dist/lib/handlers/process-announcement.js +1 -11
- package/dist/lib/handlers/process-changelog.js +1 -11
- package/dist/lib/handlers/process-conversation.js +1 -14
- package/dist/lib/handlers/process-eval.js +1 -15
- package/dist/lib/handlers/process-insights.js +1 -14
- package/dist/lib/handlers/process-launch.js +1 -16
- package/dist/lib/handlers/process-run-cleanup.js +1 -13
- package/dist/lib/handlers/process-send-message.js +1 -10
- package/dist/lib/handlers/process-session-goal.js +1 -11
- package/dist/lib/hooks-config.js +1 -81
- package/dist/lib/insights-prompts.js +1 -12
- package/dist/lib/instruction-snapshot.js +1 -8
- package/dist/lib/job-helpers.js +0 -1
- package/dist/lib/llm-client.js +1 -17
- package/dist/lib/manual-tasks-meta.js +1 -8
- package/dist/lib/manual-tasks.js +1 -79
- package/dist/lib/output.js +1 -12
- package/dist/lib/permanent-job-error.js +1 -10
- package/dist/lib/pid-identity.js +1 -14
- package/dist/lib/proxy-respawn.js +1 -12
- package/dist/lib/research-client.js +1 -12
- package/dist/lib/setup-steps.js +1 -33
- package/dist/lib/skills-loader.js +1 -8
- package/dist/lib/statusline-shim.js +1 -20
- package/dist/lib/telemetry.js +1 -16
- package/dist/lib/terminal-target-heartbeat.js +1 -15
- package/dist/lib/tmux.js +1 -16
- package/dist/lib/transcript-rate-limit-watcher.js +1 -22
- package/dist/lib/types.js +1 -8
- package/dist/lib/version-check.js +1 -12
- package/dist/lib/which.js +1 -8
- package/dist/lib/worktree.js +1 -17
- package/dist/opencode-QRJ3BH23.js +1 -0
- package/oclif.manifest.json +135 -135
- package/package.json +8 -7
- package/dist/base-command.js.map +0 -7
- package/dist/chunk-2HK7RGZB.js +0 -82
- package/dist/chunk-2HK7RGZB.js.map +0 -7
- package/dist/chunk-2ORJWTNZ.js +0 -307
- package/dist/chunk-2ORJWTNZ.js.map +0 -7
- package/dist/chunk-37LN5O7M.js +0 -59
- package/dist/chunk-37LN5O7M.js.map +0 -7
- package/dist/chunk-3S7223UR.js +0 -81
- package/dist/chunk-3S7223UR.js.map +0 -7
- package/dist/chunk-3TIMQ3O6.js +0 -96
- package/dist/chunk-3TIMQ3O6.js.map +0 -7
- package/dist/chunk-42GFSAJP.js +0 -32
- package/dist/chunk-42GFSAJP.js.map +0 -7
- package/dist/chunk-4BHDHHKL.js +0 -48
- package/dist/chunk-4BHDHHKL.js.map +0 -7
- package/dist/chunk-4D537GXE.js +0 -99
- package/dist/chunk-4D537GXE.js.map +0 -7
- package/dist/chunk-4LYCDS2N.js +0 -139
- package/dist/chunk-4LYCDS2N.js.map +0 -7
- package/dist/chunk-4SCZK7AL.js +0 -129
- package/dist/chunk-4SCZK7AL.js.map +0 -7
- package/dist/chunk-4XAWK6S2.js +0 -161
- package/dist/chunk-4XAWK6S2.js.map +0 -7
- package/dist/chunk-52WIYRZH.js +0 -73
- package/dist/chunk-52WIYRZH.js.map +0 -7
- package/dist/chunk-5BAOGNUH.js +0 -79
- package/dist/chunk-5BAOGNUH.js.map +0 -7
- package/dist/chunk-5EDMGK3W.js +0 -39
- package/dist/chunk-5EDMGK3W.js.map +0 -7
- package/dist/chunk-6NBS5XFS.js +0 -99
- package/dist/chunk-6NBS5XFS.js.map +0 -7
- package/dist/chunk-7DULPSFU.js +0 -299
- package/dist/chunk-7DULPSFU.js.map +0 -7
- package/dist/chunk-7LVVKQMZ.js +0 -98
- package/dist/chunk-7LVVKQMZ.js.map +0 -7
- package/dist/chunk-7NNFYWKK.js +0 -243
- package/dist/chunk-7NNFYWKK.js.map +0 -7
- package/dist/chunk-7NYKWN7U.js +0 -12
- package/dist/chunk-7NYKWN7U.js.map +0 -7
- package/dist/chunk-BO76WKJR.js +0 -42
- package/dist/chunk-BO76WKJR.js.map +0 -7
- package/dist/chunk-BRD5RUGM.js +0 -53
- package/dist/chunk-BRD5RUGM.js.map +0 -7
- package/dist/chunk-BT6Z6545.js +0 -43
- package/dist/chunk-BT6Z6545.js.map +0 -7
- package/dist/chunk-BZDKEQKU.js +0 -39
- package/dist/chunk-BZDKEQKU.js.map +0 -7
- package/dist/chunk-DGHWRQXL.js +0 -17
- package/dist/chunk-DGHWRQXL.js.map +0 -7
- package/dist/chunk-DNKSVWMD.js +0 -108
- package/dist/chunk-DNKSVWMD.js.map +0 -7
- package/dist/chunk-DQ3KELXD.js +0 -74
- package/dist/chunk-DQ3KELXD.js.map +0 -7
- package/dist/chunk-DUJSRBLP.js +0 -122
- package/dist/chunk-DUJSRBLP.js.map +0 -7
- package/dist/chunk-E3BIT53W.js +0 -154
- package/dist/chunk-E3BIT53W.js.map +0 -7
- package/dist/chunk-EARWG4EV.js +0 -22
- package/dist/chunk-EARWG4EV.js.map +0 -7
- package/dist/chunk-EI5BHWXA.js +0 -1662
- package/dist/chunk-EI5BHWXA.js.map +0 -7
- package/dist/chunk-EJ3YAFDP.js +0 -37
- package/dist/chunk-EJ3YAFDP.js.map +0 -7
- package/dist/chunk-EKJ2CABV.js +0 -76
- package/dist/chunk-EKJ2CABV.js.map +0 -7
- package/dist/chunk-EKP32DLN.js +0 -16
- package/dist/chunk-EKP32DLN.js.map +0 -7
- package/dist/chunk-EYPAAGN5.js +0 -51
- package/dist/chunk-EYPAAGN5.js.map +0 -7
- package/dist/chunk-F5N6CLJJ.js +0 -1995
- package/dist/chunk-F5N6CLJJ.js.map +0 -7
- package/dist/chunk-FZKLLNDS.js +0 -228
- package/dist/chunk-FZKLLNDS.js.map +0 -7
- package/dist/chunk-GIUBARWS.js +0 -99
- package/dist/chunk-GIUBARWS.js.map +0 -7
- package/dist/chunk-GQNJO2P2.js +0 -102
- package/dist/chunk-GQNJO2P2.js.map +0 -7
- package/dist/chunk-IJGF2ETG.js +0 -68
- package/dist/chunk-IJGF2ETG.js.map +0 -7
- package/dist/chunk-ILYDELUE.js +0 -46
- package/dist/chunk-ILYDELUE.js.map +0 -7
- package/dist/chunk-J6QFW4LD.js +0 -55
- package/dist/chunk-J6QFW4LD.js.map +0 -7
- package/dist/chunk-J7N3DLH6.js +0 -117
- package/dist/chunk-J7N3DLH6.js.map +0 -7
- package/dist/chunk-JFDWKLQC.js +0 -23
- package/dist/chunk-JFDWKLQC.js.map +0 -7
- package/dist/chunk-JULOLTZS.js +0 -61
- package/dist/chunk-JULOLTZS.js.map +0 -7
- package/dist/chunk-KJKBDQ4D.js +0 -220
- package/dist/chunk-KJKBDQ4D.js.map +0 -7
- package/dist/chunk-KRBQLMOP.js +0 -41
- package/dist/chunk-KRBQLMOP.js.map +0 -7
- package/dist/chunk-LXKPNATC.js +0 -624
- package/dist/chunk-LXKPNATC.js.map +0 -7
- package/dist/chunk-NSBPE2FW.js +0 -17
- package/dist/chunk-NSBPE2FW.js.map +0 -7
- package/dist/chunk-OK3I555A.js +0 -243
- package/dist/chunk-OK3I555A.js.map +0 -7
- package/dist/chunk-OKWCKCPE.js +0 -414
- package/dist/chunk-OKWCKCPE.js.map +0 -7
- package/dist/chunk-OO7JDFS4.js +0 -157
- package/dist/chunk-OO7JDFS4.js.map +0 -7
- package/dist/chunk-OQBBVTDG.js.map +0 -7
- package/dist/chunk-OQSQC7VB.js +0 -77
- package/dist/chunk-OQSQC7VB.js.map +0 -7
- package/dist/chunk-PED7L5GX.js +0 -92
- package/dist/chunk-PED7L5GX.js.map +0 -7
- package/dist/chunk-PMI56ED5.js +0 -167
- package/dist/chunk-PMI56ED5.js.map +0 -7
- package/dist/chunk-QJQS6TUN.js +0 -44
- package/dist/chunk-QJQS6TUN.js.map +0 -7
- package/dist/chunk-QN34TGD3.js +0 -83
- package/dist/chunk-QN34TGD3.js.map +0 -7
- package/dist/chunk-QSN77T7C.js +0 -250
- package/dist/chunk-QSN77T7C.js.map +0 -7
- package/dist/chunk-R56PH7YE.js +0 -78
- package/dist/chunk-R56PH7YE.js.map +0 -7
- package/dist/chunk-RH7NHVSK.js +0 -16
- package/dist/chunk-RH7NHVSK.js.map +0 -7
- package/dist/chunk-RMTT4KDY.js +0 -191
- package/dist/chunk-RMTT4KDY.js.map +0 -7
- package/dist/chunk-RQ2TMLKG.js +0 -142
- package/dist/chunk-RQ2TMLKG.js.map +0 -7
- package/dist/chunk-SO3T35U7.js +0 -80
- package/dist/chunk-SO3T35U7.js.map +0 -7
- package/dist/chunk-UKMLICWS.js +0 -51
- package/dist/chunk-UKMLICWS.js.map +0 -7
- package/dist/chunk-W2YERO7E.js +0 -170
- package/dist/chunk-W2YERO7E.js.map +0 -7
- package/dist/chunk-W53GKIZQ.js +0 -50
- package/dist/chunk-W53GKIZQ.js.map +0 -7
- package/dist/chunk-WA4MWYRW.js +0 -254
- package/dist/chunk-WA4MWYRW.js.map +0 -7
- package/dist/chunk-XC6M4CSW.js +0 -44
- package/dist/chunk-XC6M4CSW.js.map +0 -7
- package/dist/chunk-XK42ZBDE.js +0 -23
- package/dist/chunk-XK42ZBDE.js.map +0 -7
- package/dist/chunk-XUV6DDBF.js +0 -124
- package/dist/chunk-XUV6DDBF.js.map +0 -7
- package/dist/chunk-XZXS2W24.js.map +0 -7
- package/dist/chunk-Y3WD5CSW.js +0 -49
- package/dist/chunk-Y3WD5CSW.js.map +0 -7
- package/dist/chunk-Y4BJXXYV.js +0 -148
- package/dist/chunk-Y4BJXXYV.js.map +0 -7
- package/dist/chunk-YNIH3KMU.js +0 -121
- package/dist/chunk-YNIH3KMU.js.map +0 -7
- package/dist/chunk-YOBA3NAM.js +0 -55
- package/dist/chunk-YOBA3NAM.js.map +0 -7
- package/dist/chunk-ZUJBM6HE.js +0 -125
- package/dist/chunk-ZUJBM6HE.js.map +0 -7
- package/dist/commands/antigravity/backfill.js.map +0 -7
- package/dist/commands/auth/create-key.js.map +0 -7
- package/dist/commands/auth/login.js.map +0 -7
- package/dist/commands/auth/logout.js.map +0 -7
- package/dist/commands/auth/revoke-key.js.map +0 -7
- package/dist/commands/auth/signup.js.map +0 -7
- package/dist/commands/auth/status.js.map +0 -7
- package/dist/commands/catalog/index.js.map +0 -7
- package/dist/commands/catalog/recommend.js.map +0 -7
- package/dist/commands/convert.js.map +0 -7
- package/dist/commands/converters.js.map +0 -7
- package/dist/commands/crons/list.js.map +0 -7
- package/dist/commands/crons/run.js.map +0 -7
- package/dist/commands/dashboard.js.map +0 -7
- package/dist/commands/diagnostics.js.map +0 -7
- package/dist/commands/eval-targets/create.js.map +0 -7
- package/dist/commands/eval-targets/list.js.map +0 -7
- package/dist/commands/evals/agent.js.map +0 -7
- package/dist/commands/evals/benchmark.js.map +0 -7
- package/dist/commands/evals/compare.js.map +0 -7
- package/dist/commands/evals/create.js.map +0 -7
- package/dist/commands/evals/optimize-description.js.map +0 -7
- package/dist/commands/evals/optimize.js.map +0 -7
- package/dist/commands/evals/run.js.map +0 -7
- package/dist/commands/gateway/ensure.js.map +0 -7
- package/dist/commands/hooks/emit-instructions.js.map +0 -7
- package/dist/commands/hooks/install.js.map +0 -7
- package/dist/commands/hooks/run.js.map +0 -7
- package/dist/commands/hooks/uninstall.js.map +0 -7
- package/dist/commands/import.js.map +0 -7
- package/dist/commands/instructions/create.js.map +0 -7
- package/dist/commands/instructions/delete.js.map +0 -7
- package/dist/commands/instructions/fork.js.map +0 -7
- package/dist/commands/instructions/get.js.map +0 -7
- package/dist/commands/instructions/list.js.map +0 -7
- package/dist/commands/instructions/promote.js.map +0 -7
- package/dist/commands/instructions/pull.js.map +0 -7
- package/dist/commands/instructions/upstream.js.map +0 -7
- package/dist/commands/instructions/versions.js.map +0 -7
- package/dist/commands/launcher.js.map +0 -7
- package/dist/commands/org/current.js.map +0 -7
- package/dist/commands/org/list.js.map +0 -7
- package/dist/commands/org/switch.js.map +0 -7
- package/dist/commands/packs/add-instruction.js.map +0 -7
- package/dist/commands/packs/apply.js.map +0 -7
- package/dist/commands/packs/create.js.map +0 -7
- package/dist/commands/packs/fork.js.map +0 -7
- package/dist/commands/packs/get.js.map +0 -7
- package/dist/commands/packs/list.js.map +0 -7
- package/dist/commands/packs/remove-instruction.js.map +0 -7
- package/dist/commands/proxy/env.js.map +0 -7
- package/dist/commands/proxy/logs.js.map +0 -7
- package/dist/commands/proxy/restart.js.map +0 -7
- package/dist/commands/proxy/setup.js.map +0 -7
- package/dist/commands/proxy/start.js.map +0 -7
- package/dist/commands/proxy/status.js.map +0 -7
- package/dist/commands/proxy/stop.js.map +0 -7
- package/dist/commands/research/backfill.js.map +0 -7
- package/dist/commands/research/tail-transcript.js.map +0 -7
- package/dist/commands/service/install.js.map +0 -7
- package/dist/commands/service/status.js.map +0 -7
- package/dist/commands/service/uninstall.js.map +0 -7
- package/dist/commands/sessions/analyze.js.map +0 -7
- package/dist/commands/sessions/end.js.map +0 -7
- package/dist/commands/sessions/import.js.map +0 -7
- package/dist/commands/sessions/list.js.map +0 -7
- package/dist/commands/sessions/start.js.map +0 -7
- package/dist/commands/setup.js.map +0 -7
- package/dist/commands/skills/export-approved.js.map +0 -7
- package/dist/commands/skills/install.js.map +0 -7
- package/dist/commands/skills/list.js.map +0 -7
- package/dist/commands/skills/publish.js.map +0 -7
- package/dist/commands/skills/search.js.map +0 -7
- package/dist/commands/skills/update.js.map +0 -7
- package/dist/commands/suggestions/accept.js.map +0 -7
- package/dist/commands/suggestions/dismiss.js.map +0 -7
- package/dist/commands/suggestions/list.js.map +0 -7
- package/dist/commands/suggestions/refresh.js.map +0 -7
- package/dist/cursor-BGQJ4CWI.js +0 -134
- package/dist/cursor-BGQJ4CWI.js.map +0 -7
- package/dist/dashboard/Dashboard.js.map +0 -7
- package/dist/dashboard/data.js.map +0 -7
- package/dist/dashboard/launcher/ActiveJobsList.js.map +0 -7
- package/dist/dashboard/launcher/LauncherOverlay.js.map +0 -7
- package/dist/dashboard/launcher/NewLaunchForm.js.map +0 -7
- package/dist/dashboard/launcher/api.js.map +0 -7
- package/dist/dashboard/launcher/tool-labels.js.map +0 -7
- package/dist/dashboard/launcher/types.js.map +0 -7
- package/dist/dashboard/launcher/useLaunchJobs.js.map +0 -7
- package/dist/dashboard/panels/friction.js.map +0 -7
- package/dist/dashboard/panels/insights.js.map +0 -7
- package/dist/dashboard/panels/instructions.js.map +0 -7
- package/dist/dashboard/panels/outcomes.js.map +0 -7
- package/dist/dashboard/panels/overview.js.map +0 -7
- package/dist/dashboard/panels/shared.js.map +0 -7
- package/dist/dashboard/types.js.map +0 -7
- package/dist/dist-UNYP5PJR.js +0 -56
- package/dist/dist-UNYP5PJR.js.map +0 -7
- package/dist/index.js.map +0 -7
- package/dist/lib/active-org-refresh.js.map +0 -7
- package/dist/lib/active-org.js.map +0 -7
- package/dist/lib/agent-loop.js.map +0 -7
- package/dist/lib/antigravity-transcript.js.map +0 -7
- package/dist/lib/api-client.js.map +0 -7
- package/dist/lib/auth.js.map +0 -7
- package/dist/lib/capture-hosts.js.map +0 -7
- package/dist/lib/detect-languages.js.map +0 -7
- package/dist/lib/detect-tmux.js.map +0 -7
- package/dist/lib/diagnostics.js.map +0 -7
- package/dist/lib/editor-proxy-pins.js.map +0 -7
- package/dist/lib/ensure-api-key.js.map +0 -7
- package/dist/lib/eval-analyzer.js.map +0 -7
- package/dist/lib/eval-benchmark.js.map +0 -7
- package/dist/lib/eval-conversation-handler.js.map +0 -7
- package/dist/lib/eval-executor.js.map +0 -7
- package/dist/lib/eval-grader.js.map +0 -7
- package/dist/lib/eval-meta-judge.js.map +0 -7
- package/dist/lib/eval-trigger-tester.js.map +0 -7
- package/dist/lib/eval-worktree.js.map +0 -7
- package/dist/lib/gateway-entry.js.map +0 -7
- package/dist/lib/gateway-identity.js.map +0 -7
- package/dist/lib/gateway-lifecycle.js.map +0 -7
- package/dist/lib/gateway.js.map +0 -7
- package/dist/lib/handlers/cron-refresh-skills.js.map +0 -7
- package/dist/lib/handlers/cron-suggest-instructions.js.map +0 -7
- package/dist/lib/handlers/process-announcement.js.map +0 -7
- package/dist/lib/handlers/process-changelog.js.map +0 -7
- package/dist/lib/handlers/process-conversation.js.map +0 -7
- package/dist/lib/handlers/process-eval.js.map +0 -7
- package/dist/lib/handlers/process-insights.js.map +0 -7
- package/dist/lib/handlers/process-launch.js.map +0 -7
- package/dist/lib/handlers/process-run-cleanup.js.map +0 -7
- package/dist/lib/handlers/process-send-message.js.map +0 -7
- package/dist/lib/handlers/process-session-goal.js.map +0 -7
- package/dist/lib/hooks-config.js.map +0 -7
- package/dist/lib/insights-prompts.js.map +0 -7
- package/dist/lib/instruction-snapshot.js.map +0 -7
- package/dist/lib/job-helpers.js.map +0 -7
- package/dist/lib/llm-client.js.map +0 -7
- package/dist/lib/manual-tasks-meta.js.map +0 -7
- package/dist/lib/manual-tasks.js.map +0 -7
- package/dist/lib/output.js.map +0 -7
- package/dist/lib/permanent-job-error.js.map +0 -7
- package/dist/lib/pid-identity.js.map +0 -7
- package/dist/lib/proxy-respawn.js.map +0 -7
- package/dist/lib/research-client.js.map +0 -7
- package/dist/lib/setup-steps.js.map +0 -7
- package/dist/lib/skills-loader.js.map +0 -7
- package/dist/lib/statusline-shim.js.map +0 -7
- package/dist/lib/telemetry.js.map +0 -7
- package/dist/lib/terminal-target-heartbeat.js.map +0 -7
- package/dist/lib/tmux.js.map +0 -7
- package/dist/lib/transcript-rate-limit-watcher.js.map +0 -7
- package/dist/lib/types.js.map +0 -7
- package/dist/lib/version-check.js.map +0 -7
- package/dist/lib/which.js.map +0 -7
- package/dist/lib/worktree.js.map +0 -7
- package/dist/opencode-IQ7X5YMJ.js +0 -190
- package/dist/opencode-IQ7X5YMJ.js.map +0 -7
package/dist/chunk-WA4MWYRW.js
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
// src/lib/transcript-rate-limit-watcher.ts
|
|
2
|
-
import { promises as fs } from "node:fs";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import os from "node:os";
|
|
5
|
-
var KNOWN_TIMEZONES = /* @__PURE__ */ new Set([
|
|
6
|
-
"America/Phoenix",
|
|
7
|
-
"America/Los_Angeles",
|
|
8
|
-
"America/Denver",
|
|
9
|
-
"America/Chicago",
|
|
10
|
-
"America/New_York",
|
|
11
|
-
"America/Anchorage",
|
|
12
|
-
"America/Toronto",
|
|
13
|
-
"America/Vancouver",
|
|
14
|
-
"America/Mexico_City",
|
|
15
|
-
"America/Sao_Paulo",
|
|
16
|
-
"Europe/London",
|
|
17
|
-
"Europe/Berlin",
|
|
18
|
-
"Europe/Paris",
|
|
19
|
-
"Europe/Madrid",
|
|
20
|
-
"Europe/Amsterdam",
|
|
21
|
-
"Europe/Zurich",
|
|
22
|
-
"Europe/Stockholm",
|
|
23
|
-
"Europe/Athens",
|
|
24
|
-
"Asia/Tokyo",
|
|
25
|
-
"Asia/Shanghai",
|
|
26
|
-
"Asia/Hong_Kong",
|
|
27
|
-
"Asia/Singapore",
|
|
28
|
-
"Asia/Kolkata",
|
|
29
|
-
"Asia/Dubai",
|
|
30
|
-
"Asia/Jerusalem",
|
|
31
|
-
"Australia/Sydney",
|
|
32
|
-
"Australia/Melbourne",
|
|
33
|
-
"Pacific/Auckland",
|
|
34
|
-
"Pacific/Honolulu",
|
|
35
|
-
"UTC"
|
|
36
|
-
]);
|
|
37
|
-
function getTimezoneOffsetMinutes(date, timeZone) {
|
|
38
|
-
try {
|
|
39
|
-
const dtf = new Intl.DateTimeFormat("en-US", {
|
|
40
|
-
timeZone,
|
|
41
|
-
hour12: false,
|
|
42
|
-
year: "numeric",
|
|
43
|
-
month: "2-digit",
|
|
44
|
-
day: "2-digit",
|
|
45
|
-
hour: "2-digit",
|
|
46
|
-
minute: "2-digit",
|
|
47
|
-
second: "2-digit"
|
|
48
|
-
});
|
|
49
|
-
const parts = dtf.formatToParts(date);
|
|
50
|
-
const get = (t) => parts.find((p) => p.type === t)?.value;
|
|
51
|
-
const y = Number(get("year"));
|
|
52
|
-
const mo = Number(get("month"));
|
|
53
|
-
const d = Number(get("day"));
|
|
54
|
-
let h = Number(get("hour"));
|
|
55
|
-
const mi = Number(get("minute"));
|
|
56
|
-
const s = Number(get("second"));
|
|
57
|
-
if (h === 24) h = 0;
|
|
58
|
-
const asUtc = Date.UTC(y, mo - 1, d, h, mi, s);
|
|
59
|
-
return Math.round((asUtc - date.getTime()) / 6e4);
|
|
60
|
-
} catch {
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
function parseResetsAtFromMessage(text, observedAt) {
|
|
65
|
-
const match = text.match(
|
|
66
|
-
/reset(?:s|\s+at)?\s+(?:at\s+)?(\d{1,2})(?::(\d{2}))?\s*(am|pm)?\s*(?:\(([^)]+)\))?/i
|
|
67
|
-
);
|
|
68
|
-
if (!match) return null;
|
|
69
|
-
let hour = parseInt(match[1], 10);
|
|
70
|
-
const minute = match[2] ? parseInt(match[2], 10) : 0;
|
|
71
|
-
const ampm = match[3]?.toLowerCase();
|
|
72
|
-
const tzRaw = match[4]?.trim();
|
|
73
|
-
if (ampm === "pm" && hour < 12) hour += 12;
|
|
74
|
-
if (ampm === "am" && hour === 12) hour = 0;
|
|
75
|
-
if (Number.isNaN(hour) || Number.isNaN(minute) || hour > 23 || minute > 59) return null;
|
|
76
|
-
const timeZone = tzRaw && KNOWN_TIMEZONES.has(tzRaw) ? tzRaw : "UTC";
|
|
77
|
-
const offsetMin = getTimezoneOffsetMinutes(observedAt, timeZone);
|
|
78
|
-
if (offsetMin == null) return null;
|
|
79
|
-
let candidate;
|
|
80
|
-
try {
|
|
81
|
-
const dtf = new Intl.DateTimeFormat("en-CA", {
|
|
82
|
-
timeZone,
|
|
83
|
-
year: "numeric",
|
|
84
|
-
month: "2-digit",
|
|
85
|
-
day: "2-digit"
|
|
86
|
-
});
|
|
87
|
-
const parts = dtf.formatToParts(observedAt);
|
|
88
|
-
const y = Number(parts.find((p) => p.type === "year")?.value);
|
|
89
|
-
const mo = Number(parts.find((p) => p.type === "month")?.value);
|
|
90
|
-
const d = Number(parts.find((p) => p.type === "day")?.value);
|
|
91
|
-
const utcMs = Date.UTC(y, mo - 1, d, hour, minute, 0) - offsetMin * 6e4;
|
|
92
|
-
candidate = new Date(utcMs);
|
|
93
|
-
} catch {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
if (candidate.getTime() <= observedAt.getTime()) {
|
|
97
|
-
candidate = new Date(candidate.getTime() + 24 * 60 * 60 * 1e3);
|
|
98
|
-
}
|
|
99
|
-
return candidate;
|
|
100
|
-
}
|
|
101
|
-
function pickLimitType(observedAt, resetsAt) {
|
|
102
|
-
if (!resetsAt) return "five_hour_percent";
|
|
103
|
-
const deltaMs = resetsAt.getTime() - observedAt.getTime();
|
|
104
|
-
const FIVE_H_30 = 5.5 * 60 * 60 * 1e3;
|
|
105
|
-
return deltaMs <= FIVE_H_30 ? "five_hour_percent" : "seven_day_percent";
|
|
106
|
-
}
|
|
107
|
-
function extractText(entry) {
|
|
108
|
-
const candidates = [];
|
|
109
|
-
if (entry.content) candidates.push(entry.content);
|
|
110
|
-
if (entry.message?.content) candidates.push(entry.message.content);
|
|
111
|
-
for (const c of candidates) {
|
|
112
|
-
if (typeof c === "string") return c;
|
|
113
|
-
if (Array.isArray(c)) {
|
|
114
|
-
for (const part of c) {
|
|
115
|
-
if (part && typeof part === "object" && "text" in part) {
|
|
116
|
-
const t = part.text;
|
|
117
|
-
if (typeof t === "string") return t;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return "";
|
|
123
|
-
}
|
|
124
|
-
function lineToObservation(line, transcriptPath) {
|
|
125
|
-
const trimmed = line.trim();
|
|
126
|
-
if (!trimmed) return null;
|
|
127
|
-
let entry;
|
|
128
|
-
try {
|
|
129
|
-
entry = JSON.parse(trimmed);
|
|
130
|
-
} catch {
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
const is429 = entry.apiErrorStatus === 429 || entry.error === "rate_limit" || entry.isApiErrorMessage === true;
|
|
134
|
-
if (!is429) return null;
|
|
135
|
-
const text = extractText(entry);
|
|
136
|
-
const looksLikeRateLimit = entry.apiErrorStatus === 429 || entry.error === "rate_limit" || /rate.?limit|usage limit|out of (?:extra )?usage|resets?/i.test(text);
|
|
137
|
-
if (!looksLikeRateLimit) return null;
|
|
138
|
-
const observedAt = entry.timestamp ? new Date(entry.timestamp) : /* @__PURE__ */ new Date();
|
|
139
|
-
const safeObservedAt = isNaN(observedAt.getTime()) ? /* @__PURE__ */ new Date() : observedAt;
|
|
140
|
-
const resetsAt = text ? parseResetsAtFromMessage(text, safeObservedAt) : null;
|
|
141
|
-
const limitType = pickLimitType(safeObservedAt, resetsAt);
|
|
142
|
-
return {
|
|
143
|
-
provider: "anthropic",
|
|
144
|
-
plan: "unknown",
|
|
145
|
-
limitType,
|
|
146
|
-
value: 100,
|
|
147
|
-
unit: "percentage",
|
|
148
|
-
comparator: "=",
|
|
149
|
-
resetsAt,
|
|
150
|
-
sourceType: "self_observed_429",
|
|
151
|
-
sourceUrl: transcriptPath ?? null,
|
|
152
|
-
sourceEvidence: {
|
|
153
|
-
line: trimmed,
|
|
154
|
-
sessionId: entry.sessionId ?? null,
|
|
155
|
-
transcriptPath: transcriptPath ?? null
|
|
156
|
-
},
|
|
157
|
-
confidence: 0.9,
|
|
158
|
-
observedAt: safeObservedAt
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
async function tailJsonl(filepath, fromOffset) {
|
|
162
|
-
let stat;
|
|
163
|
-
try {
|
|
164
|
-
stat = await fs.stat(filepath);
|
|
165
|
-
} catch {
|
|
166
|
-
return { observations: [], newOffset: fromOffset };
|
|
167
|
-
}
|
|
168
|
-
let start = fromOffset;
|
|
169
|
-
if (stat.size < fromOffset) start = 0;
|
|
170
|
-
if (stat.size === start) return { observations: [], newOffset: start };
|
|
171
|
-
let fh;
|
|
172
|
-
try {
|
|
173
|
-
fh = await fs.open(filepath, "r");
|
|
174
|
-
} catch {
|
|
175
|
-
return { observations: [], newOffset: fromOffset };
|
|
176
|
-
}
|
|
177
|
-
try {
|
|
178
|
-
const length = stat.size - start;
|
|
179
|
-
const buf = Buffer.alloc(length);
|
|
180
|
-
await fh.read(buf, 0, length, start);
|
|
181
|
-
const text = buf.toString("utf-8");
|
|
182
|
-
const lastNewline = text.lastIndexOf("\n");
|
|
183
|
-
let consumed;
|
|
184
|
-
let newOffset;
|
|
185
|
-
if (lastNewline === -1) {
|
|
186
|
-
return { observations: [], newOffset: start };
|
|
187
|
-
}
|
|
188
|
-
consumed = text.slice(0, lastNewline + 1);
|
|
189
|
-
newOffset = start + Buffer.byteLength(consumed, "utf-8");
|
|
190
|
-
const observations = [];
|
|
191
|
-
for (const line of consumed.split("\n")) {
|
|
192
|
-
const obs = lineToObservation(line, filepath);
|
|
193
|
-
if (obs) observations.push(obs);
|
|
194
|
-
}
|
|
195
|
-
return { observations, newOffset };
|
|
196
|
-
} finally {
|
|
197
|
-
await fh.close();
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
async function* walkJsonl(dir) {
|
|
201
|
-
let entries;
|
|
202
|
-
try {
|
|
203
|
-
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
204
|
-
} catch {
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
for (const e of entries) {
|
|
208
|
-
const full = path.join(dir, e.name);
|
|
209
|
-
if (e.isDirectory()) {
|
|
210
|
-
yield* walkJsonl(full);
|
|
211
|
-
} else if (e.isFile() && e.name.endsWith(".jsonl")) {
|
|
212
|
-
yield full;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
async function scanAllTranscripts(claudeDir = path.join(os.homedir(), ".claude")) {
|
|
217
|
-
const projectsDir = path.join(claudeDir, "projects");
|
|
218
|
-
const out = [];
|
|
219
|
-
for await (const file of walkJsonl(projectsDir)) {
|
|
220
|
-
const { observations } = await tailJsonl(file, 0);
|
|
221
|
-
out.push(...observations);
|
|
222
|
-
}
|
|
223
|
-
return out;
|
|
224
|
-
}
|
|
225
|
-
function offsetCachePath() {
|
|
226
|
-
return path.join(os.homedir(), ".config", "rulemetric", "transcript-offsets.json");
|
|
227
|
-
}
|
|
228
|
-
async function loadOffsets() {
|
|
229
|
-
try {
|
|
230
|
-
const raw = await fs.readFile(offsetCachePath(), "utf-8");
|
|
231
|
-
const parsed = JSON.parse(raw);
|
|
232
|
-
if (parsed && typeof parsed === "object") return parsed;
|
|
233
|
-
return {};
|
|
234
|
-
} catch {
|
|
235
|
-
return {};
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
async function saveOffsets(offsets) {
|
|
239
|
-
const p = offsetCachePath();
|
|
240
|
-
await fs.mkdir(path.dirname(p), { recursive: true });
|
|
241
|
-
await fs.writeFile(p, JSON.stringify(offsets, null, 2), "utf-8");
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export {
|
|
245
|
-
parseResetsAtFromMessage,
|
|
246
|
-
pickLimitType,
|
|
247
|
-
lineToObservation,
|
|
248
|
-
tailJsonl,
|
|
249
|
-
scanAllTranscripts,
|
|
250
|
-
offsetCachePath,
|
|
251
|
-
loadOffsets,
|
|
252
|
-
saveOffsets
|
|
253
|
-
};
|
|
254
|
-
//# sourceMappingURL=chunk-WA4MWYRW.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/transcript-rate-limit-watcher.ts"],
|
|
4
|
-
"sourcesContent": ["// Forward-only watcher for Claude Code transcripts (~/.claude/projects/**/*.jsonl).\n//\n// Two modes:\n// * tailJsonl(path, offset) \u2014 read new bytes since `offset`, emit 429 obs\n// * scanAllTranscripts() \u2014 walk every transcript end-to-end (opt-in backfill)\n//\n// Each rate-limit line surfaces in Claude Code as a synthetic assistant message:\n// {\n// \"type\": \"assistant\",\n// \"isApiErrorMessage\": true,\n// \"apiErrorStatus\": 429,\n// \"error\": \"rate_limit\",\n// \"content\": [{ \"type\": \"text\",\n// \"text\": \"You're out of extra usage \u00B7 resets 12:50pm (America/Phoenix)\" }],\n// \"timestamp\": \"2026-06-02T19:43:00Z\"\n// }\n//\n// We translate each into a ParsedObservation matching the camelCase contract\n// from Phase 2 (`packages/usage-research/src/adapters/types.ts`).\n//\n// Heuristic for limitType: if resetsAt - observedAt fits within 5h30m, it's\n// the 5-hour cap; otherwise (up to 8 days out) it's the 7-day cap. This is\n// best-effort \u2014 the docs scraper + fusion job is the authoritative\n// disambiguator. See concerns at end of file.\n\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\n\nexport interface ParsedObservation {\n provider: 'anthropic';\n plan: string;\n limitType: 'five_hour_percent' | 'seven_day_percent';\n value: number;\n unit: 'percentage';\n comparator: '=' | '>=' | '<=';\n resetsAt: Date | string | null;\n sourceType: 'self_observed_429';\n sourceUrl: string | null;\n sourceEvidence: unknown;\n confidence: number;\n observedAt: Date | string;\n}\n\n// Common Claude-Code-surfaced IANA timezones the synthetic message uses.\n// Anything we recognise gets parsed in that TZ; otherwise we fall back to\n// local-clock interpretation.\nconst KNOWN_TIMEZONES = new Set<string>([\n 'America/Phoenix',\n 'America/Los_Angeles',\n 'America/Denver',\n 'America/Chicago',\n 'America/New_York',\n 'America/Anchorage',\n 'America/Toronto',\n 'America/Vancouver',\n 'America/Mexico_City',\n 'America/Sao_Paulo',\n 'Europe/London',\n 'Europe/Berlin',\n 'Europe/Paris',\n 'Europe/Madrid',\n 'Europe/Amsterdam',\n 'Europe/Zurich',\n 'Europe/Stockholm',\n 'Europe/Athens',\n 'Asia/Tokyo',\n 'Asia/Shanghai',\n 'Asia/Hong_Kong',\n 'Asia/Singapore',\n 'Asia/Kolkata',\n 'Asia/Dubai',\n 'Asia/Jerusalem',\n 'Australia/Sydney',\n 'Australia/Melbourne',\n 'Pacific/Auckland',\n 'Pacific/Honolulu',\n 'UTC',\n]);\n\n/**\n * Compute the offset (in minutes east of UTC) for `date` in `timeZone`.\n * Returns null if the timeZone is unknown to Intl.\n */\nfunction getTimezoneOffsetMinutes(date: Date, timeZone: string): number | null {\n try {\n const dtf = new Intl.DateTimeFormat('en-US', {\n timeZone,\n hour12: false,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n const parts = dtf.formatToParts(date);\n const get = (t: string) => parts.find((p) => p.type === t)?.value;\n const y = Number(get('year'));\n const mo = Number(get('month'));\n const d = Number(get('day'));\n let h = Number(get('hour'));\n const mi = Number(get('minute'));\n const s = Number(get('second'));\n if (h === 24) h = 0;\n const asUtc = Date.UTC(y, mo - 1, d, h, mi, s);\n return Math.round((asUtc - date.getTime()) / 60000);\n } catch {\n return null;\n }\n}\n\n/**\n * Parse \"resets HH:MMam/pm (TZ)\" out of a synthetic 429 message.\n *\n * Strategy:\n * 1. Pull HH:MM, am/pm, optional (timezone) via regex.\n * 2. Pick the wall-clock TZ \u2014 recognised IANA name or UTC fallback.\n * 3. Compute the next occurrence of HH:MM (today or tomorrow, whichever is\n * strictly after `observedAt`) interpreted in that TZ.\n */\nexport function parseResetsAtFromMessage(text: string, observedAt: Date): Date | null {\n // Accept \"resets\" or \"reset at\" or \"resets at\"; allow optional minutes.\n const match = text.match(\n /reset(?:s|\\s+at)?\\s+(?:at\\s+)?(\\d{1,2})(?::(\\d{2}))?\\s*(am|pm)?\\s*(?:\\(([^)]+)\\))?/i,\n );\n if (!match) return null;\n\n let hour = parseInt(match[1], 10);\n const minute = match[2] ? parseInt(match[2], 10) : 0;\n const ampm = match[3]?.toLowerCase();\n const tzRaw = match[4]?.trim();\n\n if (ampm === 'pm' && hour < 12) hour += 12;\n if (ampm === 'am' && hour === 12) hour = 0;\n if (Number.isNaN(hour) || Number.isNaN(minute) || hour > 23 || minute > 59) return null;\n\n const timeZone = tzRaw && KNOWN_TIMEZONES.has(tzRaw) ? tzRaw : 'UTC';\n\n // Probe the TZ offset *near* observedAt so we land on the right DST side.\n const offsetMin = getTimezoneOffsetMinutes(observedAt, timeZone);\n if (offsetMin == null) return null;\n\n // Build today-in-TZ Y/M/D from observedAt rendered in that TZ.\n let candidate: Date;\n try {\n const dtf = new Intl.DateTimeFormat('en-CA', {\n timeZone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n });\n const parts = dtf.formatToParts(observedAt);\n const y = Number(parts.find((p) => p.type === 'year')?.value);\n const mo = Number(parts.find((p) => p.type === 'month')?.value);\n const d = Number(parts.find((p) => p.type === 'day')?.value);\n // Wall-clock target HH:MM in TZ \u2192 UTC epoch.\n const utcMs = Date.UTC(y, mo - 1, d, hour, minute, 0) - offsetMin * 60000;\n candidate = new Date(utcMs);\n } catch {\n return null;\n }\n\n // If the candidate is at or before observedAt, the reset is tomorrow.\n if (candidate.getTime() <= observedAt.getTime()) {\n candidate = new Date(candidate.getTime() + 24 * 60 * 60 * 1000);\n }\n\n return candidate;\n}\n\n/** Distinguish 5-hour vs 7-day window from the reset distance. */\nexport function pickLimitType(\n observedAt: Date,\n resetsAt: Date | null,\n): 'five_hour_percent' | 'seven_day_percent' {\n if (!resetsAt) return 'five_hour_percent';\n const deltaMs = resetsAt.getTime() - observedAt.getTime();\n const FIVE_H_30 = 5.5 * 60 * 60 * 1000;\n return deltaMs <= FIVE_H_30 ? 'five_hour_percent' : 'seven_day_percent';\n}\n\ninterface TranscriptEntry {\n type?: string;\n isApiErrorMessage?: boolean;\n apiErrorStatus?: number;\n error?: string;\n timestamp?: string;\n sessionId?: string;\n content?: unknown;\n message?: { content?: unknown };\n}\n\nfunction extractText(entry: TranscriptEntry): string {\n // Synthetic 429 lines we've seen surface text in two places:\n // 1. top-level `content: [{ type: 'text', text }]`\n // 2. `message.content: ...` (mirrors the assistant.message shape)\n const candidates: unknown[] = [];\n if (entry.content) candidates.push(entry.content);\n if (entry.message?.content) candidates.push(entry.message.content);\n\n for (const c of candidates) {\n if (typeof c === 'string') return c;\n if (Array.isArray(c)) {\n for (const part of c) {\n if (part && typeof part === 'object' && 'text' in part) {\n const t = (part as { text?: unknown }).text;\n if (typeof t === 'string') return t;\n }\n }\n }\n }\n return '';\n}\n\n/**\n * Turn one JSONL line into a ParsedObservation, or null for non-429 lines\n * (and for malformed JSON).\n */\nexport function lineToObservation(\n line: string,\n transcriptPath?: string,\n): ParsedObservation | null {\n const trimmed = line.trim();\n if (!trimmed) return null;\n let entry: TranscriptEntry;\n try {\n entry = JSON.parse(trimmed) as TranscriptEntry;\n } catch {\n return null;\n }\n\n // Must look like a synthetic 429.\n const is429 =\n entry.apiErrorStatus === 429 ||\n entry.error === 'rate_limit' ||\n entry.isApiErrorMessage === true;\n if (!is429) return null;\n\n const text = extractText(entry);\n // Final filter: the message body must mention a reset OR the apiErrorStatus\n // must be 429. (Some isApiErrorMessage lines are 5xx \u2014 skip those.)\n const looksLikeRateLimit =\n entry.apiErrorStatus === 429 ||\n entry.error === 'rate_limit' ||\n /rate.?limit|usage limit|out of (?:extra )?usage|resets?/i.test(text);\n if (!looksLikeRateLimit) return null;\n\n const observedAt = entry.timestamp ? new Date(entry.timestamp) : new Date();\n const safeObservedAt = isNaN(observedAt.getTime()) ? new Date() : observedAt;\n const resetsAt = text ? parseResetsAtFromMessage(text, safeObservedAt) : null;\n const limitType = pickLimitType(safeObservedAt, resetsAt);\n\n return {\n provider: 'anthropic',\n plan: 'unknown',\n limitType,\n value: 100,\n unit: 'percentage',\n comparator: '=',\n resetsAt,\n sourceType: 'self_observed_429',\n sourceUrl: transcriptPath ?? null,\n sourceEvidence: {\n line: trimmed,\n sessionId: entry.sessionId ?? null,\n transcriptPath: transcriptPath ?? null,\n },\n confidence: 0.9,\n observedAt: safeObservedAt,\n };\n}\n\nexport interface TailResult {\n observations: ParsedObservation[];\n newOffset: number;\n}\n\n/**\n * Read the file from byte `fromOffset` onward, parse complete lines, emit any\n * 429 observations, and return the new offset (positioned at the last complete\n * newline \u2014 partial trailing lines are kept for the next tail).\n */\nexport async function tailJsonl(filepath: string, fromOffset: number): Promise<TailResult> {\n let stat;\n try {\n stat = await fs.stat(filepath);\n } catch {\n return { observations: [], newOffset: fromOffset };\n }\n\n // If the file got truncated/rotated, restart from 0.\n let start = fromOffset;\n if (stat.size < fromOffset) start = 0;\n if (stat.size === start) return { observations: [], newOffset: start };\n\n let fh;\n try {\n fh = await fs.open(filepath, 'r');\n } catch {\n return { observations: [], newOffset: fromOffset };\n }\n\n try {\n const length = stat.size - start;\n const buf = Buffer.alloc(length);\n await fh.read(buf, 0, length, start);\n const text = buf.toString('utf-8');\n\n // Find the last newline so we don't half-eat a line still being written.\n const lastNewline = text.lastIndexOf('\\n');\n let consumed: string;\n let newOffset: number;\n if (lastNewline === -1) {\n // No complete line yet.\n return { observations: [], newOffset: start };\n }\n consumed = text.slice(0, lastNewline + 1);\n // The byte length of the consumed slice \u2014 not the char length \u2014 drives the\n // next offset. JSONL transcripts are ASCII-dominant but the reset message\n // contains the \"\u00B7\" character (2 bytes UTF-8), so byteLength matters.\n newOffset = start + Buffer.byteLength(consumed, 'utf-8');\n\n const observations: ParsedObservation[] = [];\n for (const line of consumed.split('\\n')) {\n const obs = lineToObservation(line, filepath);\n if (obs) observations.push(obs);\n }\n return { observations, newOffset };\n } finally {\n await fh.close();\n }\n}\n\nasync function* walkJsonl(dir: string): AsyncGenerator<string> {\n let entries;\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of entries) {\n const full = path.join(dir, e.name);\n if (e.isDirectory()) {\n yield* walkJsonl(full);\n } else if (e.isFile() && e.name.endsWith('.jsonl')) {\n yield full;\n }\n }\n}\n\n/**\n * Scan every Claude Code transcript under `claudeDir` end-to-end. Used by the\n * opt-in `rulemetric research backfill` command \u2014 forward-only tail is the\n * default capture path.\n */\nexport async function scanAllTranscripts(\n claudeDir: string = path.join(os.homedir(), '.claude'),\n): Promise<ParsedObservation[]> {\n const projectsDir = path.join(claudeDir, 'projects');\n const out: ParsedObservation[] = [];\n for await (const file of walkJsonl(projectsDir)) {\n const { observations } = await tailJsonl(file, 0);\n out.push(...observations);\n }\n return out;\n}\n\n// \u2500\u2500 Offset cache \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Stored at ~/.config/rulemetric/transcript-offsets.json. Plain JSON of\n// `{ <absolute_path>: <byte_offset> }`. Read+rewrite is fine \u2014 the file\n// stays tiny (a few hundred bytes per session).\n\nexport function offsetCachePath(): string {\n return path.join(os.homedir(), '.config', 'rulemetric', 'transcript-offsets.json');\n}\n\nexport async function loadOffsets(): Promise<Record<string, number>> {\n try {\n const raw = await fs.readFile(offsetCachePath(), 'utf-8');\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === 'object') return parsed as Record<string, number>;\n return {};\n } catch {\n return {};\n }\n}\n\nexport async function saveOffsets(offsets: Record<string, number>): Promise<void> {\n const p = offsetCachePath();\n await fs.mkdir(path.dirname(p), { recursive: true });\n await fs.writeFile(p, JSON.stringify(offsets, null, 2), 'utf-8');\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-XC6M4CSW.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HBar,
|
|
3
|
-
Panel,
|
|
4
|
-
fit,
|
|
5
|
-
friendlyLabel
|
|
6
|
-
} from "./chunk-DQ3KELXD.js";
|
|
7
|
-
import {
|
|
8
|
-
ORANGE,
|
|
9
|
-
RED
|
|
10
|
-
} from "./chunk-QJQS6TUN.js";
|
|
11
|
-
|
|
12
|
-
// src/dashboard/panels/friction.tsx
|
|
13
|
-
import { Text } from "ink";
|
|
14
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
-
function FrictionPanel({ api, width, barWidth }) {
|
|
16
|
-
if (!api) {
|
|
17
|
-
return /* @__PURE__ */ jsx(Panel, { title: "Friction Points", color: RED, width, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "API offline \u2014 no friction data" }) });
|
|
18
|
-
}
|
|
19
|
-
const friction = api.friction ?? {};
|
|
20
|
-
const sorted = Object.entries(friction).sort(([, a], [, b]) => b - a);
|
|
21
|
-
if (sorted.length === 0) {
|
|
22
|
-
return /* @__PURE__ */ jsx(Panel, { title: "Friction Points", color: ORANGE, width, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No friction detected \u2014 nice!" }) });
|
|
23
|
-
}
|
|
24
|
-
const max = sorted[0][1];
|
|
25
|
-
const total = sorted.reduce((s, [, v]) => s + v, 0);
|
|
26
|
-
const nw = Math.max(8, width - barWidth - 20);
|
|
27
|
-
return /* @__PURE__ */ jsx(Panel, { title: `Friction Points (${total} incidents)`, color: RED, width, children: sorted.map(([key, value]) => {
|
|
28
|
-
const pct = total > 0 ? Math.round(value / total * 100) : 0;
|
|
29
|
-
return /* @__PURE__ */ jsxs(Text, { wrap: "truncate-end", children: [
|
|
30
|
-
/* @__PURE__ */ jsx(HBar, { value, max, width: barWidth }),
|
|
31
|
-
/* @__PURE__ */ jsxs(Text, { color: ORANGE, children: [
|
|
32
|
-
" ",
|
|
33
|
-
fit(friendlyLabel(key), nw)
|
|
34
|
-
] }),
|
|
35
|
-
/* @__PURE__ */ jsx(Text, { children: String(value).padStart(5) }),
|
|
36
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: String(pct + "%").padStart(5) })
|
|
37
|
-
] }, key);
|
|
38
|
-
}) });
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export {
|
|
42
|
-
FrictionPanel
|
|
43
|
-
};
|
|
44
|
-
//# sourceMappingURL=chunk-XC6M4CSW.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/dashboard/panels/friction.tsx"],
|
|
4
|
-
"sourcesContent": ["import React from 'react';\nimport { Text } from 'ink';\nimport { ORANGE, RED, DIM } from '../types.js';\nimport type { ApiInsights } from '../types.js';\nimport { Panel, HBar, fit, friendlyLabel } from './shared.js';\n\nexport function FrictionPanel({ api, width, barWidth }: {\n api: ApiInsights | null; width: number; barWidth: number;\n}) {\n if (!api) {\n return (\n <Panel title=\"Friction Points\" color={RED} width={width}>\n <Text dimColor>API offline \u2014 no friction data</Text>\n </Panel>\n );\n }\n\n const friction = api.friction ?? {};\n const sorted = Object.entries(friction).sort(([, a], [, b]) => b - a);\n if (sorted.length === 0) {\n return (\n <Panel title=\"Friction Points\" color={ORANGE} width={width}>\n <Text dimColor>No friction detected \u2014 nice!</Text>\n </Panel>\n );\n }\n\n const max = sorted[0][1];\n const total = sorted.reduce((s, [, v]) => s + v, 0);\n const nw = Math.max(8, width - barWidth - 20);\n\n return (\n <Panel title={`Friction Points (${total} incidents)`} color={RED} width={width}>\n {sorted.map(([key, value]) => {\n const pct = total > 0 ? Math.round((value / total) * 100) : 0;\n return (\n <Text key={key} wrap=\"truncate-end\">\n <HBar value={value} max={max} width={barWidth} />\n <Text color={ORANGE}> {fit(friendlyLabel(key), nw)}</Text>\n <Text>{String(value).padStart(5)}</Text>\n <Text dimColor>{String(pct + '%').padStart(5)}</Text>\n </Text>\n );\n })}\n </Panel>\n );\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;AACA,SAAS,YAAY;AAWb,cA0BI,YA1BJ;AAND,SAAS,cAAc,EAAE,KAAK,OAAO,SAAS,GAElD;AACD,MAAI,CAAC,KAAK;AACR,WACE,oBAAC,SAAM,OAAM,mBAAkB,OAAO,KAAK,OACzC,8BAAC,QAAK,UAAQ,MAAC,iDAA8B,GAC/C;AAAA,EAEJ;AAEA,QAAM,WAAW,IAAI,YAAY,CAAC;AAClC,QAAM,SAAS,OAAO,QAAQ,QAAQ,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC;AACpE,MAAI,OAAO,WAAW,GAAG;AACvB,WACE,oBAAC,SAAM,OAAM,mBAAkB,OAAO,QAAQ,OAC5C,8BAAC,QAAK,UAAQ,MAAC,+CAA4B,GAC7C;AAAA,EAEJ;AAEA,QAAM,MAAM,OAAO,CAAC,EAAE,CAAC;AACvB,QAAM,QAAQ,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,IAAI,GAAG,CAAC;AAClD,QAAM,KAAK,KAAK,IAAI,GAAG,QAAQ,WAAW,EAAE;AAE5C,SACE,oBAAC,SAAM,OAAO,oBAAoB,KAAK,eAAe,OAAO,KAAK,OAC/D,iBAAO,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AAC5B,UAAM,MAAM,QAAQ,IAAI,KAAK,MAAO,QAAQ,QAAS,GAAG,IAAI;AAC5D,WACE,qBAAC,QAAe,MAAK,gBACnB;AAAA,0BAAC,QAAK,OAAc,KAAU,OAAO,UAAU;AAAA,MAC/C,qBAAC,QAAK,OAAO,QAAQ;AAAA;AAAA,QAAE,IAAI,cAAc,GAAG,GAAG,EAAE;AAAA,SAAE;AAAA,MACnD,oBAAC,QAAM,iBAAO,KAAK,EAAE,SAAS,CAAC,GAAE;AAAA,MACjC,oBAAC,QAAK,UAAQ,MAAE,iBAAO,MAAM,GAAG,EAAE,SAAS,CAAC,GAAE;AAAA,SAJrC,GAKX;AAAA,EAEJ,CAAC,GACH;AAEJ;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-XK42ZBDE.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
processConversationJob
|
|
3
|
-
} from "./chunk-KJKBDQ4D.js";
|
|
4
|
-
import {
|
|
5
|
-
apiPatch
|
|
6
|
-
} from "./chunk-ZUJBM6HE.js";
|
|
7
|
-
|
|
8
|
-
// src/lib/handlers/process-conversation.ts
|
|
9
|
-
async function processConversation(payload, helpers) {
|
|
10
|
-
const { mirrorId, evalTargetId, config } = payload;
|
|
11
|
-
const log = (msg) => helpers.logger.info(msg);
|
|
12
|
-
await processConversationJob(config, evalTargetId, log);
|
|
13
|
-
const result = { type: "conversation", conversationId: config.conversationId };
|
|
14
|
-
await apiPatch(`/api/eval-jobs/${mirrorId}/state`, { result }).catch((err) => {
|
|
15
|
-
log(`result persist failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
16
|
-
});
|
|
17
|
-
return result;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export {
|
|
21
|
-
processConversation
|
|
22
|
-
};
|
|
23
|
-
//# sourceMappingURL=chunk-XK42ZBDE.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/handlers/process-conversation.ts"],
|
|
4
|
-
"sourcesContent": ["import type { JobHelpers } from '../job-helpers.js';\nimport { apiPatch } from '../api-client.js';\nimport { processConversationJob } from '../eval-conversation-handler.js';\n\ninterface ConversationJobConfig {\n type: 'conversation';\n conversationId: string;\n messageId: string;\n messageContent: string;\n}\n\ninterface ConversationPayload {\n mirrorId: string;\n evalTargetId: string;\n config: ConversationJobConfig;\n}\n\n/**\n * Graphile-shaped handler for the `process_conversation` task.\n *\n * Thin wrapper around `eval-conversation-handler.processConversationJob` \u2014\n * the existing function already does all the work (action decision,\n * run_evals/generate_cases/analyze branches, idempotency guard via\n * already-posted assistant messages). The handler just unpacks the payload\n * and threads the helpers' logger through.\n *\n * Mechanical contract vs. the legacy worker:\n * - no claim \u2014 Graphile claimed the job before invoking us\n * - no /complete POST \u2014 we return a small marker on success (matches the\n * `{ type: 'conversation' }` blob the legacy code POSTed)\n * - no surrounding try/catch \u2014 errors propagate to Graphile, which flips\n * the mirror row to `failed` via the runner.events handler\n *\n * Conversation jobs run with `maxAttempts: 1` (set at enqueue time in\n * `apps/api/src/lib/queue.ts`) \u2014 chat is interactive and silent retries\n * would confuse users mid-flow.\n */\nexport async function processConversation(\n payload: ConversationPayload,\n helpers: JobHelpers,\n): Promise<Record<string, unknown>> {\n const { mirrorId, evalTargetId, config } = payload;\n const log = (msg: string) => helpers.logger.info(msg);\n\n await processConversationJob(config, evalTargetId, log);\n const result = { type: 'conversation', conversationId: config.conversationId };\n\n // Graphile discards task return values, so persist a small marker onto\n // the mirror row so the dashboard can tell the job finished. Best-effort.\n await apiPatch(`/api/eval-jobs/${mirrorId}/state`, { result }).catch((err: unknown) => {\n log(`result persist failed: ${err instanceof Error ? err.message : String(err)}`);\n });\n\n return result;\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;AAqCA,eAAsB,oBACpB,SACA,SACkC;AAClC,QAAM,EAAE,UAAU,cAAc,OAAO,IAAI;AAC3C,QAAM,MAAM,CAAC,QAAgB,QAAQ,OAAO,KAAK,GAAG;AAEpD,QAAM,uBAAuB,QAAQ,cAAc,GAAG;AACtD,QAAM,SAAS,EAAE,MAAM,gBAAgB,gBAAgB,OAAO,eAAe;AAI7E,QAAM,SAAS,kBAAkB,QAAQ,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,QAAiB;AACrF,QAAI,0BAA0B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,EAClF,CAAC;AAED,SAAO;AACT;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-XUV6DDBF.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ClaudeCodeAdapter,
|
|
3
|
-
discoverAllSessions
|
|
4
|
-
} from "./chunk-F5N6CLJJ.js";
|
|
5
|
-
import {
|
|
6
|
-
DEFAULT_API_URL
|
|
7
|
-
} from "./chunk-ZUJBM6HE.js";
|
|
8
|
-
|
|
9
|
-
// src/dashboard/data.ts
|
|
10
|
-
import * as fs from "node:fs";
|
|
11
|
-
import * as path from "node:path";
|
|
12
|
-
import * as os from "node:os";
|
|
13
|
-
function ensureEnv() {
|
|
14
|
-
if (process.env.RULEMETRIC_API_KEY || process.env.RULEMETRIC_ACCESS_TOKEN) return;
|
|
15
|
-
const globalEnv = path.join(os.homedir(), ".config", "rulemetric", "env");
|
|
16
|
-
if (loadEnvFile(globalEnv)) return;
|
|
17
|
-
loadEnvFile(path.join(process.cwd(), ".env.local"));
|
|
18
|
-
}
|
|
19
|
-
function loadEnvFile(filePath) {
|
|
20
|
-
try {
|
|
21
|
-
const content = fs.readFileSync(filePath, "utf-8");
|
|
22
|
-
for (const line of content.split("\n")) {
|
|
23
|
-
const trimmed = line.trim();
|
|
24
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
25
|
-
const eqIdx = trimmed.indexOf("=");
|
|
26
|
-
if (eqIdx < 0) continue;
|
|
27
|
-
const key = trimmed.slice(0, eqIdx).trim();
|
|
28
|
-
const value = trimmed.slice(eqIdx + 1).trim();
|
|
29
|
-
if (!process.env[key]) {
|
|
30
|
-
process.env[key] = value;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return !!(process.env.RULEMETRIC_API_KEY || process.env.RULEMETRIC_ACCESS_TOKEN);
|
|
34
|
-
} catch {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
ensureEnv();
|
|
39
|
-
async function loadLocalStats(providerFilter) {
|
|
40
|
-
const stats = {
|
|
41
|
-
totalSessions: 0,
|
|
42
|
-
totalCalls: 0,
|
|
43
|
-
totalInputTokens: 0,
|
|
44
|
-
totalOutputTokens: 0,
|
|
45
|
-
totalCacheReadTokens: 0,
|
|
46
|
-
totalCacheWriteTokens: 0,
|
|
47
|
-
totalCostUSD: 0,
|
|
48
|
-
providers: {}
|
|
49
|
-
};
|
|
50
|
-
const sources = await discoverAllSessions(providerFilter);
|
|
51
|
-
stats.providers = {};
|
|
52
|
-
for (const s of sources) {
|
|
53
|
-
stats.providers[s.provider] = (stats.providers[s.provider] || 0) + 1;
|
|
54
|
-
}
|
|
55
|
-
const adapter = new ClaudeCodeAdapter();
|
|
56
|
-
const claudeSources = sources.filter((s) => s.provider === "claude");
|
|
57
|
-
for (const source of claudeSources) {
|
|
58
|
-
try {
|
|
59
|
-
const files = fs.readdirSync(source.path).filter((f) => f.endsWith(".jsonl"));
|
|
60
|
-
stats.totalSessions += files.length;
|
|
61
|
-
for (const file of files) {
|
|
62
|
-
const content = fs.readFileSync(path.join(source.path, file), "utf-8");
|
|
63
|
-
const parsed = adapter.parse(content);
|
|
64
|
-
for (const event of parsed.events) {
|
|
65
|
-
if (event.tokenUsage) {
|
|
66
|
-
stats.totalCalls++;
|
|
67
|
-
stats.totalInputTokens += event.tokenUsage.input;
|
|
68
|
-
stats.totalOutputTokens += event.tokenUsage.output;
|
|
69
|
-
stats.totalCacheReadTokens += event.tokenUsage.cacheRead ?? 0;
|
|
70
|
-
stats.totalCacheWriteTokens += event.tokenUsage.cacheWrite ?? 0;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
} catch {
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
const inputCostPerM = 15;
|
|
78
|
-
const outputCostPerM = 75;
|
|
79
|
-
stats.totalCostUSD = Math.round((stats.totalInputTokens / 1e6 * inputCostPerM + stats.totalOutputTokens / 1e6 * outputCostPerM + stats.totalCacheReadTokens / 1e6 * (inputCostPerM * 0.1) + stats.totalCacheWriteTokens / 1e6 * (inputCostPerM * 1.25)) * 100) / 100;
|
|
80
|
-
return stats;
|
|
81
|
-
}
|
|
82
|
-
async function loadApiInsights(projectPath) {
|
|
83
|
-
const apiUrl = process.env.RULEMETRIC_API_URL ?? DEFAULT_API_URL;
|
|
84
|
-
const apiKey = process.env.RULEMETRIC_API_KEY;
|
|
85
|
-
const accessToken = process.env.RULEMETRIC_ACCESS_TOKEN;
|
|
86
|
-
const token = apiKey ?? accessToken;
|
|
87
|
-
if (!token) return null;
|
|
88
|
-
const params = new URLSearchParams();
|
|
89
|
-
if (projectPath) params.set("projectPath", projectPath);
|
|
90
|
-
try {
|
|
91
|
-
const resp = await fetch(`${apiUrl}/api/insights/compute?${params}`, {
|
|
92
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
93
|
-
signal: AbortSignal.timeout(5e3)
|
|
94
|
-
});
|
|
95
|
-
if (!resp.ok) return null;
|
|
96
|
-
return await resp.json();
|
|
97
|
-
} catch {
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
async function loadLinkedInstructions(projectPath) {
|
|
102
|
-
const apiUrl = process.env.RULEMETRIC_API_URL ?? DEFAULT_API_URL;
|
|
103
|
-
const token = process.env.RULEMETRIC_API_KEY ?? process.env.RULEMETRIC_ACCESS_TOKEN;
|
|
104
|
-
if (!token) return null;
|
|
105
|
-
const params = new URLSearchParams();
|
|
106
|
-
if (projectPath) params.set("projectPath", projectPath);
|
|
107
|
-
try {
|
|
108
|
-
const resp = await fetch(`${apiUrl}/api/insights/linked-instructions?${params}`, {
|
|
109
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
110
|
-
signal: AbortSignal.timeout(5e3)
|
|
111
|
-
});
|
|
112
|
-
if (!resp.ok) return null;
|
|
113
|
-
return await resp.json();
|
|
114
|
-
} catch {
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export {
|
|
120
|
-
loadLocalStats,
|
|
121
|
-
loadApiInsights,
|
|
122
|
-
loadLinkedInstructions
|
|
123
|
-
};
|
|
124
|
-
//# sourceMappingURL=chunk-XUV6DDBF.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/dashboard/data.ts"],
|
|
4
|
-
"sourcesContent": ["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { discoverAllSessions, ClaudeCodeAdapter } from '@rulemetric/session';\nimport { DEFAULT_API_URL } from '../lib/api-client.js';\nimport type { LocalStats, ApiInsights } from './types.js';\n\n/** Load auth config from env vars \u2192 ~/.config/rulemetric/env \u2192 .env.local */\nfunction ensureEnv(): void {\n if (process.env.RULEMETRIC_API_KEY || process.env.RULEMETRIC_ACCESS_TOKEN) return;\n\n // Try ~/.config/rulemetric/env\n const globalEnv = path.join(os.homedir(), '.config', 'rulemetric', 'env');\n if (loadEnvFile(globalEnv)) return;\n\n // Try .env.local in cwd\n loadEnvFile(path.join(process.cwd(), '.env.local'));\n}\n\nfunction loadEnvFile(filePath: string): boolean {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIdx = trimmed.indexOf('=');\n if (eqIdx < 0) continue;\n const key = trimmed.slice(0, eqIdx).trim();\n const value = trimmed.slice(eqIdx + 1).trim();\n if (!process.env[key]) {\n process.env[key] = value;\n }\n }\n return !!(process.env.RULEMETRIC_API_KEY || process.env.RULEMETRIC_ACCESS_TOKEN);\n } catch {\n return false;\n }\n}\n\n// Load on import\nensureEnv();\n\n/** Read local JSONL files and compute basic stats. */\nexport async function loadLocalStats(providerFilter?: string): Promise<LocalStats> {\n const stats: LocalStats = {\n totalSessions: 0,\n totalCalls: 0,\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalCacheReadTokens: 0,\n totalCacheWriteTokens: 0,\n totalCostUSD: 0,\n providers: {},\n };\n\n const sources = await discoverAllSessions(providerFilter);\n stats.providers = {};\n for (const s of sources) {\n stats.providers[s.provider] = (stats.providers[s.provider] || 0) + 1;\n }\n\n // Parse Claude Code sessions from local JSONL files\n const adapter = new ClaudeCodeAdapter();\n const claudeSources = sources.filter(s => s.provider === 'claude');\n\n for (const source of claudeSources) {\n try {\n const files = fs.readdirSync(source.path).filter(f => f.endsWith('.jsonl'));\n stats.totalSessions += files.length;\n\n for (const file of files) {\n const content = fs.readFileSync(path.join(source.path, file), 'utf-8');\n const parsed = adapter.parse(content);\n\n for (const event of parsed.events) {\n if (event.tokenUsage) {\n stats.totalCalls++;\n stats.totalInputTokens += event.tokenUsage.input;\n stats.totalOutputTokens += event.tokenUsage.output;\n stats.totalCacheReadTokens += event.tokenUsage.cacheRead ?? 0;\n stats.totalCacheWriteTokens += event.tokenUsage.cacheWrite ?? 0;\n }\n }\n }\n } catch {\n // Skip unreadable directories\n }\n }\n\n // Estimate cost (Opus pricing as default)\n const inputCostPerM = 15;\n const outputCostPerM = 75;\n stats.totalCostUSD = Math.round((\n (stats.totalInputTokens / 1_000_000) * inputCostPerM +\n (stats.totalOutputTokens / 1_000_000) * outputCostPerM +\n (stats.totalCacheReadTokens / 1_000_000) * (inputCostPerM * 0.1) +\n (stats.totalCacheWriteTokens / 1_000_000) * (inputCostPerM * 1.25)\n ) * 100) / 100;\n\n return stats;\n}\n\n/** Fetch enriched insights from the API. Returns null if API is unreachable. */\nexport async function loadApiInsights(projectPath?: string): Promise<ApiInsights | null> {\n const apiUrl = process.env.RULEMETRIC_API_URL ?? DEFAULT_API_URL;\n const apiKey = process.env.RULEMETRIC_API_KEY;\n const accessToken = process.env.RULEMETRIC_ACCESS_TOKEN;\n const token = apiKey ?? accessToken;\n if (!token) return null;\n\n const params = new URLSearchParams();\n if (projectPath) params.set('projectPath', projectPath);\n\n try {\n const resp = await fetch(`${apiUrl}/api/insights/compute?${params}`, {\n headers: { Authorization: `Bearer ${token}` },\n signal: AbortSignal.timeout(5000),\n });\n if (!resp.ok) return null;\n return await resp.json() as ApiInsights;\n } catch {\n return null;\n }\n}\n\n/** Fetch linked instructions from the API. */\nexport async function loadLinkedInstructions(projectPath?: string): Promise<Array<{ name: string; linkedSessions: number }> | null> {\n const apiUrl = process.env.RULEMETRIC_API_URL ?? DEFAULT_API_URL;\n const token = process.env.RULEMETRIC_API_KEY ?? process.env.RULEMETRIC_ACCESS_TOKEN;\n if (!token) return null;\n\n const params = new URLSearchParams();\n if (projectPath) params.set('projectPath', projectPath);\n\n try {\n const resp = await fetch(`${apiUrl}/api/insights/linked-instructions?${params}`, {\n headers: { Authorization: `Bearer ${token}` },\n signal: AbortSignal.timeout(5000),\n });\n if (!resp.ok) return null;\n return await resp.json() as Array<{ name: string; linkedSessions: number }>;\n } catch {\n return null;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/insights-prompts.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Recommendation prompts matching Claude Code's /insights structure.\n * Each prompt is sent to `claude -p` with the aggregated stats data.\n */\n\nexport interface PromptSpec {\n name: string;\n prompt: string;\n maxTokens: number;\n}\n\nexport const RECOMMENDATION_PROMPTS: PromptSpec[] = [\n {\n name: 'project_areas',\n prompt: `Analyze this Claude Code usage data and identify project areas.\nRESPOND WITH ONLY A VALID JSON OBJECT:\n{\n \"areas\": [\n {\"name\": \"Area name\", \"session_count\": N, \"description\": \"2-3 sentences about what was worked on and how Claude Code was used.\"}\n ]\n}\nInclude 4-5 areas. Skip internal CC operations.`,\n maxTokens: 8192,\n },\n {\n name: 'interaction_style',\n prompt: `Analyze this Claude Code usage data and describe the user's interaction style.\nRESPOND WITH ONLY A VALID JSON OBJECT:\n{\n \"narrative\": \"2-3 paragraphs analyzing HOW the user interacts with Claude Code. Use second person 'you'. Describe patterns: iterate quickly vs detailed upfront specs? Interrupt often or let Claude run? Include specific examples. Use **bold** for key insights.\",\n \"key_pattern\": \"One sentence summary of most distinctive interaction style\"\n}`,\n maxTokens: 8192,\n },\n {\n name: 'what_works',\n prompt: `Analyze this Claude Code usage data and identify what's working well for this user. Use second person (\"you\").\nRESPOND WITH ONLY A VALID JSON OBJECT:\n{\n \"intro\": \"1 sentence of context\",\n \"impressive_workflows\": [\n {\"title\": \"Short title (3-6 words)\", \"description\": \"2-3 sentences describing the impressive workflow or approach. Use 'you' not 'the user'.\"}\n ]\n}\nInclude 3 impressive workflows.`,\n maxTokens: 8192,\n },\n {\n name: 'friction_analysis',\n prompt: `Analyze this Claude Code usage data and identify friction points for this user. Use second person (\"you\").\nRESPOND WITH ONLY A VALID JSON OBJECT:\n{\n \"intro\": \"1 sentence summarizing friction patterns\",\n \"categories\": [\n {\"category\": \"Concrete category name\", \"description\": \"1-2 sentences explaining this category and what could be done differently. Use 'you' not 'the user'.\", \"examples\": [\"Specific example with consequence\", \"Another example\"]}\n ]\n}\nInclude 3 friction categories with 2 examples each.`,\n maxTokens: 8192,\n },\n {\n name: 'suggestions',\n prompt: `Analyze this Claude Code usage data and suggest improvements.\n## CC FEATURES REFERENCE (pick from these for features_to_try):\n1. **MCP Servers**: Connect Claude to external tools, databases, and APIs via Model Context Protocol.\n - How to use: Run \\`claude mcp add <server-name> -- <command>\\`\n2. **Custom Skills**: Reusable prompts you define as markdown files that run with a single /command.\n - How to use: Create \\`.claude/skills/commit/SKILL.md\\` with instructions. Then type \\`/commit\\` to run it.\n3. **Hooks**: Shell commands that auto-run at specific lifecycle events.\n - How to use: Add to \\`.claude/settings.json\\` under \"hooks\" key.\n4. **Headless Mode**: Run Claude non-interactively from scripts and CI/CD.\n - How to use: \\`claude -p \"fix lint errors\" --allowedTools \"Edit,Read,Bash\"\\`\n5. **Task Agents**: Claude spawns focused sub-agents for complex exploration or parallel work.\n - How to use: Claude auto-invokes when helpful, or ask \"use an agent to explore X\"\nRESPOND WITH ONLY A VALID JSON OBJECT:\n{\n \"claude_md_additions\": [\n {\"addition\": \"A specific line or block to add to CLAUDE.md\", \"why\": \"1 sentence explaining why\", \"prompt_scaffold\": \"Instructions for where to add this\"}\n ],\n \"features_to_try\": [\n {\"feature\": \"Feature name from above\", \"one_liner\": \"What it does\", \"why_for_you\": \"Why this would help YOU\", \"example_code\": \"Actual command or config to copy\"}\n ],\n \"usage_patterns\": [\n {\"title\": \"Short title\", \"suggestion\": \"1-2 sentence summary\", \"detail\": \"3-4 sentences explaining how this applies\", \"copyable_prompt\": \"A specific prompt to copy and try\"}\n ]\n}\nInclude 2-3 items for each category.`,\n maxTokens: 8192,\n },\n {\n name: 'on_the_horizon',\n prompt: `Analyze this Claude Code usage data and identify future opportunities.\nRESPOND WITH ONLY A VALID JSON OBJECT:\n{\n \"intro\": \"1 sentence about evolving AI-assisted development\",\n \"opportunities\": [\n {\"title\": \"Short title (4-8 words)\", \"whats_possible\": \"2-3 ambitious sentences about autonomous workflows\", \"how_to_try\": \"1-2 sentences mentioning relevant tooling\", \"copyable_prompt\": \"Detailed prompt to try\"}\n ]\n}\nInclude 3 opportunities. Think BIG - autonomous workflows, parallel agents, iterating against tests.`,\n maxTokens: 8192,\n },\n {\n name: 'fun_ending',\n prompt: `Analyze this Claude Code usage data and find a memorable moment.\nRESPOND WITH ONLY A VALID JSON OBJECT:\n{\n \"headline\": \"A memorable QUALITATIVE moment from the transcripts - not a statistic. Something human, funny, or surprising.\",\n \"detail\": \"Brief context about when/where this happened\"\n}\nFind something genuinely interesting or amusing from the session summaries.`,\n maxTokens: 8192,\n },\n];\n\nexport const AT_A_GLANCE_PROMPT = `You're writing an \"At a Glance\" summary for a Claude Code usage insights report.\nUse this 4-part structure:\n1. **What's working** - What is the user's unique style and what impactful things have they done? Don't be fluffy.\n2. **What's hindering you** - Split into (a) Claude's fault and (b) user-side friction. Be honest but constructive.\n3. **Quick wins to try** - Specific Claude Code features they could try, or a compelling workflow technique.\n4. **Ambitious workflows for better models** - As models improve, what workflows should they prepare for?\nKeep each section to 2-3 sentences. Use a coaching tone.\nRESPOND WITH ONLY A VALID JSON OBJECT:\n{\n \"whats_working\": \"(refer to instructions above)\",\n \"whats_hindering\": \"(refer to instructions above)\",\n \"quick_wins\": \"(refer to instructions above)\",\n \"ambitious_workflows\": \"(refer to instructions above)\"\n}`;\n\nexport const FACET_GENERATION_PROMPT = `Analyze this coding session and produce a structured analysis.\nThe session is from a non-Claude-Code tool, so analyze the conversation and tool usage patterns.\n\nRESPOND WITH ONLY A VALID JSON OBJECT:\n{\n \"underlying_goal\": \"1-2 sentence description of what the user was trying to accomplish\",\n \"goal_categories\": {\"category\": count},\n \"outcome\": \"achieved|mostly_achieved|partially_achieved|not_achieved|abandoned\",\n \"session_type\": \"quick_task|iterative_refinement|exploration|debugging|greenfield\",\n \"friction_counts\": {\"wrong_approach\": 0, \"tool_failure\": 0, \"excessive_changes\": 0, \"misunderstanding\": 0},\n \"friction_detail\": \"Brief description of any friction encountered, or empty string\",\n \"primary_success\": \"Brief description of main achievement, or empty string\",\n \"brief_summary\": \"2-3 sentence summary of the session\"\n}\n\nGoal categories to use: debugging, feature_development, refactoring, testing, documentation, investigation, exploration, code_review, deployment, configuration, end_to_end_testing, logging_documentation, ui_testing.\n\nOutcome guide:\n- achieved: Task completed successfully\n- mostly_achieved: Main goal done but minor items remain\n- partially_achieved: Some progress but significant work left\n- not_achieved: Attempted but failed\n- abandoned: User gave up or switched tasks`;\n"],
|
|
5
|
-
"mappings": ";AAWO,IAAM,yBAAuC;AAAA,EAClD;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQR,WAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMR,WAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASR,WAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASR,WAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAyBR,WAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASR,WAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOR,WAAW;AAAA,EACb;AACF;AAEO,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAe3B,IAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-Y3WD5CSW.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ApiError,
|
|
3
|
-
apiPost
|
|
4
|
-
} from "./chunk-ZUJBM6HE.js";
|
|
5
|
-
|
|
6
|
-
// src/lib/research-client.ts
|
|
7
|
-
function serializeDate(v) {
|
|
8
|
-
if (v == null) return v ?? null;
|
|
9
|
-
return v instanceof Date ? v.toISOString() : v;
|
|
10
|
-
}
|
|
11
|
-
async function postObservation(obs) {
|
|
12
|
-
const body = {
|
|
13
|
-
provider: obs.provider,
|
|
14
|
-
plan: obs.plan,
|
|
15
|
-
limitType: obs.limitType,
|
|
16
|
-
value: obs.value,
|
|
17
|
-
unit: obs.unit,
|
|
18
|
-
comparator: obs.comparator,
|
|
19
|
-
resetsAt: serializeDate(obs.resetsAt),
|
|
20
|
-
sourceType: obs.sourceType,
|
|
21
|
-
sourceUrl: obs.sourceUrl,
|
|
22
|
-
sourceEvidence: obs.sourceEvidence,
|
|
23
|
-
confidence: obs.confidence,
|
|
24
|
-
observedAt: serializeDate(obs.observedAt)
|
|
25
|
-
};
|
|
26
|
-
return apiPost("/api/internal/research/observe", body);
|
|
27
|
-
}
|
|
28
|
-
async function postObservations(observations) {
|
|
29
|
-
let posted = 0;
|
|
30
|
-
let failed = 0;
|
|
31
|
-
const errors = [];
|
|
32
|
-
for (const obs of observations) {
|
|
33
|
-
try {
|
|
34
|
-
await postObservation(obs);
|
|
35
|
-
posted++;
|
|
36
|
-
} catch (err) {
|
|
37
|
-
failed++;
|
|
38
|
-
const msg = err instanceof ApiError ? `HTTP ${err.statusCode}: ${err.message}` : String(err);
|
|
39
|
-
if (errors.length < 5) errors.push(msg);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return { posted, failed, errors };
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export {
|
|
46
|
-
postObservation,
|
|
47
|
-
postObservations
|
|
48
|
-
};
|
|
49
|
-
//# sourceMappingURL=chunk-Y3WD5CSW.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/research-client.ts"],
|
|
4
|
-
"sourcesContent": ["// Thin wrapper around apiPost for the research observation endpoint. Keeps\n// the body schema (camelCase, Date|string for resetsAt) co-located with the\n// transcript watcher so changes don't drift apart.\n\nimport { apiPost, ApiError } from './api-client.js';\nimport type { ParsedObservation } from './transcript-rate-limit-watcher.js';\n\ninterface ObserveResponse {\n id: string;\n observedAt: string;\n}\n\nfunction serializeDate(v: Date | string | null | undefined): string | null | undefined {\n if (v == null) return v ?? null;\n return v instanceof Date ? v.toISOString() : v;\n}\n\nexport async function postObservation(obs: ParsedObservation): Promise<ObserveResponse> {\n const body: Record<string, unknown> = {\n provider: obs.provider,\n plan: obs.plan,\n limitType: obs.limitType,\n value: obs.value,\n unit: obs.unit,\n comparator: obs.comparator,\n resetsAt: serializeDate(obs.resetsAt),\n sourceType: obs.sourceType,\n sourceUrl: obs.sourceUrl,\n sourceEvidence: obs.sourceEvidence,\n confidence: obs.confidence,\n observedAt: serializeDate(obs.observedAt),\n };\n return apiPost<ObserveResponse>('/api/internal/research/observe', body);\n}\n\n/**\n * POST a batch best-effort. Returns counts. Individual failures are swallowed\n * so a 429 on one observation doesn't lose the rest.\n */\nexport async function postObservations(\n observations: ParsedObservation[],\n): Promise<{ posted: number; failed: number; errors: string[] }> {\n let posted = 0;\n let failed = 0;\n const errors: string[] = [];\n for (const obs of observations) {\n try {\n await postObservation(obs);\n posted++;\n } catch (err) {\n failed++;\n const msg = err instanceof ApiError ? `HTTP ${err.statusCode}: ${err.message}` : String(err);\n if (errors.length < 5) errors.push(msg);\n }\n }\n return { posted, failed, errors };\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;AAYA,SAAS,cAAc,GAAgE;AACrF,MAAI,KAAK,KAAM,QAAO,KAAK;AAC3B,SAAO,aAAa,OAAO,EAAE,YAAY,IAAI;AAC/C;AAEA,eAAsB,gBAAgB,KAAkD;AACtF,QAAM,OAAgC;AAAA,IACpC,UAAU,IAAI;AAAA,IACd,MAAM,IAAI;AAAA,IACV,WAAW,IAAI;AAAA,IACf,OAAO,IAAI;AAAA,IACX,MAAM,IAAI;AAAA,IACV,YAAY,IAAI;AAAA,IAChB,UAAU,cAAc,IAAI,QAAQ;AAAA,IACpC,YAAY,IAAI;AAAA,IAChB,WAAW,IAAI;AAAA,IACf,gBAAgB,IAAI;AAAA,IACpB,YAAY,IAAI;AAAA,IAChB,YAAY,cAAc,IAAI,UAAU;AAAA,EAC1C;AACA,SAAO,QAAyB,kCAAkC,IAAI;AACxE;AAMA,eAAsB,iBACpB,cAC+D;AAC/D,MAAI,SAAS;AACb,MAAI,SAAS;AACb,QAAM,SAAmB,CAAC;AAC1B,aAAW,OAAO,cAAc;AAC9B,QAAI;AACF,YAAM,gBAAgB,GAAG;AACzB;AAAA,IACF,SAAS,KAAK;AACZ;AACA,YAAM,MAAM,eAAe,WAAW,QAAQ,IAAI,UAAU,KAAK,IAAI,OAAO,KAAK,OAAO,GAAG;AAC3F,UAAI,OAAO,SAAS,EAAG,QAAO,KAAK,GAAG;AAAA,IACxC;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,QAAQ,OAAO;AAClC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|