@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
|
@@ -1,7 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/statusline-shim.ts"],
|
|
4
|
-
"sourcesContent": ["import { existsSync, readFileSync, writeFileSync, chmodSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n// Path where the shim script lives \u2014 readable by the `statusLine` config key.\nexport const STATUSLINE_SHIM_PATH = join(homedir(), '.claude', 'statusline-rulemetric.sh');\n\n/**\n * Write ~/.claude/statusline-rulemetric.sh.\n *\n * The script is invoked by Claude Code on every statusline refresh cycle.\n * Claude Code feeds a JSON payload on stdin that includes `rate_limits`\n * (same shape as GET /api/oauth/usage) using its own in-memory token \u2014\n * so freshness is tied to the statusline cadence, not the proxy capturing\n * a stale keychain token.\n *\n * The script:\n * 1. Reads stdin once (Claude Code closes it after the payload).\n * 2. If jq is available, extracts each rate_limit window and POSTs it to\n * POST /api/internal/research/observe as an oauth_usage observation.\n * 3. If a `prevCommand` is supplied (the user's original statusLine value),\n * it is executed with the same stdin forwarded so the user's prompt text\n * is still displayed \u2014 we must chain, not replace.\n * 4. Exits 0 regardless so Claude Code always gets a clean statusline.\n *\n * Auth is read from the same priority chain as the hook scripts:\n * ~/.config/rulemetric/env (RULEMETRIC_ACCESS_TOKEN / RULEMETRIC_API_KEY)\n * RULEMETRIC_API_KEY / RULEMETRIC_ACCESS_TOKEN env vars\n *\n * Returns the path written.\n */\nexport function writeStatuslineShim(prevCommand?: string): string {\n const chainBlock = prevCommand\n ? `\n# Chain to the original statusLine command so the user's prompt is preserved.\necho \"$STDIN_PAYLOAD\" | ${prevCommand}`\n : '';\n\n const script = `#!/usr/bin/env bash\n# RuleMetric statusline shim \u2014 auto-generated by \\`rulemetric hooks install --statusline-usage\\`\n# Captures Claude Code rate_limits from statusline stdin and forwards to the research pipeline.\n# DO NOT EDIT \u2014 re-run \\`rulemetric hooks install --statusline-usage\\` to regenerate.\n\nset -euo pipefail\n\n# Read stdin once (Claude Code closes the pipe after the payload).\nSTDIN_PAYLOAD=\"$(cat)\"\n\n# \u2500\u2500 Auth \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nCONFIG_ENV=\"$HOME/.config/rulemetric/env\"\nif [ -f \"$CONFIG_ENV\" ]; then\n # shellcheck source=/dev/null\n source \"$CONFIG_ENV\"\nfi\n\nAPI_URL=\"\\${RULEMETRIC_API_URL:-https://rulemetric.com}\"\nAUTH_TOKEN=\"\\${RULEMETRIC_ACCESS_TOKEN:-\\${RULEMETRIC_API_KEY:-}}\"\n\nif [ -z \"$AUTH_TOKEN\" ]; then\n # No auth \u2014 still chain so the user's statusline works.\n${chainBlock}\n exit 0\nfi\n\n# \u2500\u2500 Extract + POST rate_limit windows \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\nif ! command -v jq &>/dev/null; then\n # jq missing \u2014 chain and bail; don't break the user's statusline.\n${chainBlock}\n exit 0\nfi\n\nOBSERVED_AT=\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"\nCACHE_DIR=\"$HOME/.config/rulemetric\"\nmkdir -p \"$CACHE_DIR\" 2>/dev/null || true\n\nfor WIRE_KEY in five_hour seven_day seven_day_opus; do\n # Map wire key \u2192 limit_type (case statement avoids bash 4 associative arrays).\n case \"$WIRE_KEY\" in\n five_hour) LIMIT_TYPE=\"five_hour_percent\" ;;\n seven_day) LIMIT_TYPE=\"seven_day_percent\" ;;\n seven_day_opus) LIMIT_TYPE=\"seven_day_opus_percent\" ;;\n *) continue ;;\n esac\n\n # Try both wire shapes:\n # Legacy: { \"rate_limits\": { \"five_hour\": { \"used_percentage\": ..., \"resets_at\": ... } } }\n # Current: { \"five_hour\": { \"used_percentage\": ..., \"resets_at\": ... } }\n WINDOW=\"$(echo \"$STDIN_PAYLOAD\" | jq -c \".rate_limits.\\${WIRE_KEY} // .\\${WIRE_KEY} // empty\" 2>/dev/null || true)\"\n\n if [ -z \"$WINDOW\" ] || [ \"$WINDOW\" = \"null\" ]; then\n continue\n fi\n\n USED_PCT=\"$(echo \"$WINDOW\" | jq '.used_percentage // empty' 2>/dev/null || true)\"\n RESETS_AT_EPOCH=\"$(echo \"$WINDOW\" | jq '.resets_at // empty' 2>/dev/null || true)\"\n\n if [ -z \"$USED_PCT\" ] || [ \"$USED_PCT\" = \"null\" ]; then\n continue\n fi\n\n # Convert unix epoch to ISO-8601 if present.\n if [ -n \"$RESETS_AT_EPOCH\" ] && [ \"$RESETS_AT_EPOCH\" != \"null\" ]; then\n RESETS_AT_ISO=\"$(date -u -r \"$RESETS_AT_EPOCH\" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null \\\n || date -u -d \"@$RESETS_AT_EPOCH\" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null \\\n || echo \"\")\"\n else\n RESETS_AT_ISO=\"\"\n fi\n\n # Skip stale windows. Claude Code can keep re-emitting a cached rate_limits\n # block after the reset time has passed; storing those rows floods the DB and\n # corrupts the \"current limits\" view.\n if [ -n \"$RESETS_AT_EPOCH\" ] && [ \"$RESETS_AT_EPOCH\" != \"null\" ]; then\n NOW_EPOCH=\"$(date -u +%s)\"\n if [ \"$RESETS_AT_EPOCH\" -lt \"$NOW_EPOCH\" ] 2>/dev/null; then\n continue\n fi\n else\n NOW_EPOCH=\"$(date -u +%s)\"\n fi\n\n # Local duplicate suppression mirrors the API's 30-minute freshness floor.\n # The statusline refreshes often; if the same window/value/reset is already\n # posted recently, another POST only burns an API request and DB connection.\n CACHE_FILE=\"$CACHE_DIR/statusline-usage-\\${LIMIT_TYPE}.cache\"\n CACHE_KEY=\"\\${LIMIT_TYPE}|\\${USED_PCT}|\\${RESETS_AT_ISO}\"\n if [ -f \"$CACHE_FILE\" ]; then\n read -r CACHED_AT CACHED_KEY < \"$CACHE_FILE\" || true\n if [ \"\\${CACHED_KEY:-}\" = \"$CACHE_KEY\" ] && [ $((NOW_EPOCH - \\${CACHED_AT:-0})) -lt 1800 ] 2>/dev/null; then\n continue\n fi\n fi\n printf '%s %s\\n' \"$NOW_EPOCH\" \"$CACHE_KEY\" > \"$CACHE_FILE.tmp\" 2>/dev/null \\\n && mv \"$CACHE_FILE.tmp\" \"$CACHE_FILE\" 2>/dev/null || true\n\n PAYLOAD=\"$(jq -nc \\\\\n --arg provider \"anthropic\" \\\\\n --arg plan \"unknown\" \\\\\n --argjson value \"$USED_PCT\" \\\\\n --arg limitType \"$LIMIT_TYPE\" \\\\\n --arg observedAt \"$OBSERVED_AT\" \\\\\n --arg resetsAt \"$RESETS_AT_ISO\" \\\\\n '{\n provider: $provider,\n plan: $plan,\n limitType: $limitType,\n value: $value,\n unit: \"percentage\",\n comparator: \"=\",\n sourceType: \"oauth_usage\",\n sourceUrl: null,\n confidence: 1.0,\n observedAt: $observedAt,\n resetsAt: (if $resetsAt == \"\" then null else $resetsAt end)\n }')\"\n\n curl -sf -o /dev/null \\\\\n -X POST \"$API_URL/api/internal/research/observe\" \\\\\n -H \"Content-Type: application/json\" \\\\\n -H \"Authorization: Bearer $AUTH_TOKEN\" \\\\\n --max-time 3 \\\\\n --data \"$PAYLOAD\" >/dev/null 2>&1 &\ndone\n\n${chainBlock}\nexit 0\n`;\n\n writeFileSync(STATUSLINE_SHIM_PATH, script, { encoding: 'utf-8' });\n chmodSync(STATUSLINE_SHIM_PATH, 0o755);\n return STATUSLINE_SHIM_PATH;\n}\n\n// The settings object shape for statusLine (Claude Code v1.x+).\nexport const STATUSLINE_SETTINGS_VALUE = {\n type: 'command' as const,\n command: STATUSLINE_SHIM_PATH,\n refreshInterval: 30,\n};\n\n/**\n * Read the current statusLine command from a settings object, if any.\n * Returns undefined if not set or already points to the shim (idempotent).\n * Handles both the legacy string form and the current object form.\n */\nexport function readCurrentStatusLine(\n settings: Record<string, unknown>,\n): string | undefined {\n const current = settings.statusLine;\n if (!current) return undefined;\n if (typeof current === 'string') {\n if (current === STATUSLINE_SHIM_PATH) return undefined;\n return current;\n }\n if (typeof current === 'object' && current !== null) {\n const cmd = (current as Record<string, unknown>).command;\n if (typeof cmd !== 'string') return undefined;\n if (cmd === STATUSLINE_SHIM_PATH) return undefined; // already installed\n return cmd;\n }\n return undefined;\n}\n\n/**\n * Remove our statusline shim from a settings object (uninstall). Only deletes\n * `settings.statusLine` when it points at OUR shim \u2014 a user-owned statusLine is\n * left untouched. Returns true iff it removed the shim. Without this, `hooks\n * uninstall` leaves Claude Code POSTing usage to rulemetric.com via the shim\n * even after the hooks + CLI are gone.\n */\nexport function removeStatuslineShim(settings: Record<string, unknown>): boolean {\n if (!isStatuslineShimInstalled(settings)) return false;\n delete settings.statusLine;\n return true;\n}\n\n// The shim's path suffix is identical on every machine \u2014 only the $HOME prefix\n// differs. Forward slashes only: settings files are written with POSIX paths\n// on the platforms the shim supports (the shim itself is a bash script).\nconst STATUSLINE_SHIM_SUFFIX = '/.claude/statusline-rulemetric.sh';\n\n/**\n * Like removeStatuslineShim, but also matches a shim written by ANOTHER\n * machine's install: the statusLine path is $HOME-anchored, so a shared\n * `.claude/settings.json` poisoned by a teammate's install carries THEIR home\n * prefix and the exact-path check misses it. Only our fixed shim filename can\n * match \u2014 a user-owned statusLine is never removed. Returns true iff removed.\n */\nexport function removeStatuslineShimAnyHome(settings: Record<string, unknown>): boolean {\n const current = settings.statusLine;\n const cmd =\n typeof current === 'string'\n ? current\n : typeof current === 'object' && current !== null\n ? (current as Record<string, unknown>).command\n : undefined;\n const isShim =\n typeof cmd === 'string' && (cmd === STATUSLINE_SHIM_PATH || cmd.endsWith(STATUSLINE_SHIM_SUFFIX));\n if (!isShim) return false;\n delete settings.statusLine;\n return true;\n}\n\n/**\n * Returns true if the settings object already points to the shim.\n */\nexport function isStatuslineShimInstalled(settings: Record<string, unknown>): boolean {\n const current = settings.statusLine;\n if (!current) return false;\n if (typeof current === 'string') return current === STATUSLINE_SHIM_PATH;\n if (typeof current === 'object' && current !== null) {\n return (current as Record<string, unknown>).command === STATUSLINE_SHIM_PATH;\n }\n return false;\n}\n"],
|
|
5
|
-
"mappings": ";AAAA,SAAmC,eAAe,iBAAiB;AACnE,SAAS,eAAe;AACxB,SAAS,YAAY;AAGd,IAAM,uBAAuB,KAAK,QAAQ,GAAG,WAAW,0BAA0B;AA0BlF,SAAS,oBAAoB,aAA8B;AAChE,QAAM,aAAa,cACf;AAAA;AAAA,0BAEoB,WAAW,KAC/B;AAEJ,QAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBf,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOV,UAAU;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;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;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiGV,UAAU;AAAA;AAAA;AAIV,gBAAc,sBAAsB,QAAQ,EAAE,UAAU,QAAQ,CAAC;AACjE,YAAU,sBAAsB,GAAK;AACrC,SAAO;AACT;AAGO,IAAM,4BAA4B;AAAA,EACvC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,iBAAiB;AACnB;AAOO,SAAS,sBACd,UACoB;AACpB,QAAM,UAAU,SAAS;AACzB,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,OAAO,YAAY,UAAU;AAC/B,QAAI,YAAY,qBAAsB,QAAO;AAC7C,WAAO;AAAA,EACT;AACA,MAAI,OAAO,YAAY,YAAY,YAAY,MAAM;AACnD,UAAM,MAAO,QAAoC;AACjD,QAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,QAAI,QAAQ,qBAAsB,QAAO;AACzC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AASO,SAAS,qBAAqB,UAA4C;AAC/E,MAAI,CAAC,0BAA0B,QAAQ,EAAG,QAAO;AACjD,SAAO,SAAS;AAChB,SAAO;AACT;AAKA,IAAM,yBAAyB;AASxB,SAAS,4BAA4B,UAA4C;AACtF,QAAM,UAAU,SAAS;AACzB,QAAM,MACJ,OAAO,YAAY,WACf,UACA,OAAO,YAAY,YAAY,YAAY,OACxC,QAAoC,UACrC;AACR,QAAM,SACJ,OAAO,QAAQ,aAAa,QAAQ,wBAAwB,IAAI,SAAS,sBAAsB;AACjG,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,SAAS;AAChB,SAAO;AACT;AAKO,SAAS,0BAA0B,UAA4C;AACpF,QAAM,UAAU,SAAS;AACzB,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,OAAO,YAAY,SAAU,QAAO,YAAY;AACpD,MAAI,OAAO,YAAY,YAAY,YAAY,MAAM;AACnD,WAAQ,QAAoC,YAAY;AAAA,EAC1D;AACA,SAAO;AACT;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-OQSQC7VB.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
// src/lib/detect-languages.ts
|
|
2
|
-
import { existsSync, statSync, readdirSync } from "node:fs";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
var EXCLUDE_DIRS = /* @__PURE__ */ new Set([
|
|
5
|
-
"node_modules",
|
|
6
|
-
".git",
|
|
7
|
-
"dist",
|
|
8
|
-
"build",
|
|
9
|
-
".next",
|
|
10
|
-
".turbo",
|
|
11
|
-
".worktrees",
|
|
12
|
-
"target",
|
|
13
|
-
"venv",
|
|
14
|
-
"__pycache__",
|
|
15
|
-
".cache"
|
|
16
|
-
]);
|
|
17
|
-
var MAX_DEPTH = 3;
|
|
18
|
-
function detectLanguages(projectPath) {
|
|
19
|
-
if (!existsSync(projectPath)) return [];
|
|
20
|
-
const signals = /* @__PURE__ */ new Set();
|
|
21
|
-
const walk = (dir, depth) => {
|
|
22
|
-
if (depth > MAX_DEPTH) return;
|
|
23
|
-
let entries;
|
|
24
|
-
try {
|
|
25
|
-
entries = readdirSync(dir);
|
|
26
|
-
} catch {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
for (const name of entries) {
|
|
30
|
-
if (name === "package.json") signals.add("JavaScript/TypeScript");
|
|
31
|
-
if (name === "tsconfig.json") signals.add("TypeScript-config");
|
|
32
|
-
if (name === "pyproject.toml") signals.add("Python-pyproject");
|
|
33
|
-
if (name === "setup.py") signals.add("Python-setup");
|
|
34
|
-
if (name === "requirements.txt") signals.add("Python-requirements");
|
|
35
|
-
if (name === "Pipfile") signals.add("Python-pipfile");
|
|
36
|
-
if (name === "Cargo.toml") signals.add("Rust-cargo");
|
|
37
|
-
if (name === "go.mod") signals.add("Go-mod");
|
|
38
|
-
if (name === "pom.xml") signals.add("Java-pom");
|
|
39
|
-
if (name === "build.gradle" || name === "build.gradle.kts") signals.add("Java-gradle");
|
|
40
|
-
if (name === "Gemfile") signals.add("Ruby-gemfile");
|
|
41
|
-
if (name === "composer.json") signals.add("PHP-composer");
|
|
42
|
-
if (name.endsWith(".ts") || name.endsWith(".tsx")) signals.add("TypeScript-source");
|
|
43
|
-
if (name.endsWith(".py")) signals.add("Python-source");
|
|
44
|
-
if (name.endsWith(".rs")) signals.add("Rust-source");
|
|
45
|
-
if (name.endsWith(".go")) signals.add("Go-source");
|
|
46
|
-
}
|
|
47
|
-
if (depth >= MAX_DEPTH) return;
|
|
48
|
-
for (const name of entries) {
|
|
49
|
-
if (EXCLUDE_DIRS.has(name)) continue;
|
|
50
|
-
const full = path.join(dir, name);
|
|
51
|
-
try {
|
|
52
|
-
if (statSync(full).isDirectory()) walk(full, depth + 1);
|
|
53
|
-
} catch {
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
walk(projectPath, 0);
|
|
58
|
-
const result = /* @__PURE__ */ new Set();
|
|
59
|
-
if (signals.has("TypeScript-source") || signals.has("TypeScript-config")) {
|
|
60
|
-
result.add("TypeScript");
|
|
61
|
-
} else if (signals.has("JavaScript/TypeScript")) {
|
|
62
|
-
result.add("JavaScript");
|
|
63
|
-
}
|
|
64
|
-
if (signals.has("Python-pyproject") || signals.has("Python-setup") || signals.has("Python-requirements") || signals.has("Python-pipfile") || signals.has("Python-source")) result.add("Python");
|
|
65
|
-
if (signals.has("Rust-cargo") || signals.has("Rust-source")) result.add("Rust");
|
|
66
|
-
if (signals.has("Go-mod") || signals.has("Go-source")) result.add("Go");
|
|
67
|
-
if (signals.has("Java-pom") || signals.has("Java-gradle")) result.add("Java");
|
|
68
|
-
if (signals.has("Ruby-gemfile")) result.add("Ruby");
|
|
69
|
-
if (signals.has("PHP-composer")) result.add("PHP");
|
|
70
|
-
if (signals.size < 2) return [];
|
|
71
|
-
return [...result];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export {
|
|
75
|
-
detectLanguages
|
|
76
|
-
};
|
|
77
|
-
//# sourceMappingURL=chunk-OQSQC7VB.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/detect-languages.ts"],
|
|
4
|
-
"sourcesContent": ["import { existsSync, statSync, readdirSync } from 'node:fs';\nimport path from 'node:path';\n\nconst EXCLUDE_DIRS = new Set([\n 'node_modules', '.git', 'dist', 'build', '.next', '.turbo',\n '.worktrees', 'target', 'venv', '__pycache__', '.cache',\n]);\nconst MAX_DEPTH = 3;\n\n/**\n * Walk a directory up to MAX_DEPTH levels and collect filesystem signals.\n * Returns a deduplicated array of language names. Requires \u22652 distinct\n * signals before the caller scores; one signal is treated as insufficient.\n */\nexport function detectLanguages(projectPath: string): string[] {\n if (!existsSync(projectPath)) return [];\n const signals = new Set<string>();\n\n const walk = (dir: string, depth: number) => {\n if (depth > MAX_DEPTH) return;\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return;\n }\n\n // Inspect file markers at this level. Each marker contributes a *distinct*\n // signal so two files for the same language (e.g. pyproject.toml +\n // requirements.txt) clear the \u22652-signals minimum on their own.\n for (const name of entries) {\n if (name === 'package.json') signals.add('JavaScript/TypeScript');\n if (name === 'tsconfig.json') signals.add('TypeScript-config');\n if (name === 'pyproject.toml') signals.add('Python-pyproject');\n if (name === 'setup.py') signals.add('Python-setup');\n if (name === 'requirements.txt') signals.add('Python-requirements');\n if (name === 'Pipfile') signals.add('Python-pipfile');\n if (name === 'Cargo.toml') signals.add('Rust-cargo');\n if (name === 'go.mod') signals.add('Go-mod');\n if (name === 'pom.xml') signals.add('Java-pom');\n if (name === 'build.gradle' || name === 'build.gradle.kts') signals.add('Java-gradle');\n if (name === 'Gemfile') signals.add('Ruby-gemfile');\n if (name === 'composer.json') signals.add('PHP-composer');\n if (name.endsWith('.ts') || name.endsWith('.tsx')) signals.add('TypeScript-source');\n if (name.endsWith('.py')) signals.add('Python-source');\n if (name.endsWith('.rs')) signals.add('Rust-source');\n if (name.endsWith('.go')) signals.add('Go-source');\n }\n\n if (depth >= MAX_DEPTH) return;\n\n // Recurse into non-excluded subdirectories\n for (const name of entries) {\n if (EXCLUDE_DIRS.has(name)) continue;\n const full = path.join(dir, name);\n try {\n if (statSync(full).isDirectory()) walk(full, depth + 1);\n } catch {\n // skip unreadable\n }\n }\n };\n\n walk(projectPath, 0);\n\n // Collapse the raw signals into language names for the LLM prompt\n const result = new Set<string>();\n if (signals.has('TypeScript-source') || signals.has('TypeScript-config')) {\n result.add('TypeScript');\n } else if (signals.has('JavaScript/TypeScript')) {\n result.add('JavaScript');\n }\n if (\n signals.has('Python-pyproject') ||\n signals.has('Python-setup') ||\n signals.has('Python-requirements') ||\n signals.has('Python-pipfile') ||\n signals.has('Python-source')\n ) result.add('Python');\n if (signals.has('Rust-cargo') || signals.has('Rust-source')) result.add('Rust');\n if (signals.has('Go-mod') || signals.has('Go-source')) result.add('Go');\n if (signals.has('Java-pom') || signals.has('Java-gradle')) result.add('Java');\n if (signals.has('Ruby-gemfile')) result.add('Ruby');\n if (signals.has('PHP-composer')) result.add('PHP');\n\n // The minimum-2-signals gate counts the raw signals, not the\n // normalized language list. A package.json + tsconfig.json + .ts source\n // is three signals \u2192 strong evidence even though the language collapses\n // to one entry. A bare package.json with no .ts/.js source is one signal.\n if (signals.size < 2) return [];\n return [...result];\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-PED7L5GX.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
apiGet,
|
|
3
|
-
apiPost
|
|
4
|
-
} from "./chunk-ZUJBM6HE.js";
|
|
5
|
-
|
|
6
|
-
// src/lib/eval-benchmark.ts
|
|
7
|
-
function computeStats(values) {
|
|
8
|
-
if (values.length === 0) return { mean: 0, stddev: 0, min: 0, max: 0 };
|
|
9
|
-
const mean = values.reduce((a, b) => a + b, 0) / values.length;
|
|
10
|
-
const variance = values.reduce((sum, v) => sum + (v - mean) ** 2, 0) / values.length;
|
|
11
|
-
return {
|
|
12
|
-
mean: Math.round(mean * 1e3) / 1e3,
|
|
13
|
-
stddev: Math.round(Math.sqrt(variance) * 1e3) / 1e3,
|
|
14
|
-
min: Math.min(...values),
|
|
15
|
-
max: Math.max(...values)
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
async function aggregateBenchmark(targetId, iteration) {
|
|
19
|
-
const iterQuery = iteration ? `&iteration=${iteration}` : "";
|
|
20
|
-
const PAGE = 100;
|
|
21
|
-
const runs = [];
|
|
22
|
-
for (let offset = 0; offset < 1e5; offset += PAGE) {
|
|
23
|
-
const page = await apiGet(
|
|
24
|
-
`/api/eval-targets/${targetId}/runs?limit=${PAGE}&offset=${offset}${iterQuery}`
|
|
25
|
-
);
|
|
26
|
-
runs.push(...page);
|
|
27
|
-
if (page.length < PAGE) break;
|
|
28
|
-
}
|
|
29
|
-
const completedRuns = runs.filter((r) => r.status === "completed");
|
|
30
|
-
if (completedRuns.length === 0) {
|
|
31
|
-
return { runSummary: {}, notes: ["No completed runs found"], totalRuns: 0 };
|
|
32
|
-
}
|
|
33
|
-
const byConfig = {};
|
|
34
|
-
for (const run of completedRuns) {
|
|
35
|
-
if (!byConfig[run.configuration]) byConfig[run.configuration] = [];
|
|
36
|
-
byConfig[run.configuration].push(run);
|
|
37
|
-
}
|
|
38
|
-
const runSummary = {};
|
|
39
|
-
const notes = [];
|
|
40
|
-
for (const [config, configRuns] of Object.entries(byConfig)) {
|
|
41
|
-
const passRates = configRuns.filter((r) => Object.keys(r.grading).length > 0).map((r) => r.grading.summary?.pass_rate ?? 0);
|
|
42
|
-
const durations = configRuns.map((r) => r.timing.duration_ms / 1e3).filter((v) => !isNaN(v));
|
|
43
|
-
const tokens = configRuns.map((r) => r.timing.total_tokens ?? 0).filter((v) => v > 0);
|
|
44
|
-
runSummary[config] = {};
|
|
45
|
-
if (passRates.length > 0) runSummary[config].pass_rate = computeStats(passRates);
|
|
46
|
-
if (durations.length > 0) runSummary[config].time_seconds = computeStats(durations);
|
|
47
|
-
if (tokens.length > 0) runSummary[config].tokens = computeStats(tokens);
|
|
48
|
-
}
|
|
49
|
-
if (runSummary.with_target && runSummary.without_target) {
|
|
50
|
-
const delta = {};
|
|
51
|
-
for (const metric of ["pass_rate", "time_seconds", "tokens"]) {
|
|
52
|
-
const withVal = runSummary.with_target[metric]?.mean ?? 0;
|
|
53
|
-
const withoutVal = runSummary.without_target[metric]?.mean ?? 0;
|
|
54
|
-
const diff = withVal - withoutVal;
|
|
55
|
-
delta[metric] = `${diff >= 0 ? "+" : ""}${Math.round(diff * 1e3) / 1e3}`;
|
|
56
|
-
}
|
|
57
|
-
runSummary.delta = delta;
|
|
58
|
-
const passRateDelta = (runSummary.with_target.pass_rate?.mean ?? 0) - (runSummary.without_target.pass_rate?.mean ?? 0);
|
|
59
|
-
if (passRateDelta > 0.1) {
|
|
60
|
-
notes.push(`Target improves pass rate by ${(passRateDelta * 100).toFixed(0)}%`);
|
|
61
|
-
} else if (passRateDelta < -0.1) {
|
|
62
|
-
notes.push(`Target decreases pass rate by ${(Math.abs(passRateDelta) * 100).toFixed(0)}%`);
|
|
63
|
-
} else {
|
|
64
|
-
notes.push("Target has minimal impact on pass rate");
|
|
65
|
-
}
|
|
66
|
-
const timeDelta = (runSummary.with_target.time_seconds?.mean ?? 0) - (runSummary.without_target.time_seconds?.mean ?? 0);
|
|
67
|
-
if (Math.abs(timeDelta) > 5) {
|
|
68
|
-
notes.push(`Target ${timeDelta > 0 ? "adds" : "saves"} ${Math.abs(timeDelta).toFixed(1)}s average execution time`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
for (const [config, stats] of Object.entries(runSummary)) {
|
|
72
|
-
if (config === "delta") continue;
|
|
73
|
-
const passRate = stats.pass_rate;
|
|
74
|
-
if (passRate && passRate.stddev > 0.2) {
|
|
75
|
-
notes.push(`${config} shows high pass rate variance (stddev=${passRate.stddev.toFixed(2)}) \u2014 results may be unreliable`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return { runSummary, notes, totalRuns: completedRuns.length };
|
|
79
|
-
}
|
|
80
|
-
async function postBenchmark(targetId, iteration, result) {
|
|
81
|
-
return apiPost(`/api/eval-targets/${targetId}/benchmarks`, {
|
|
82
|
-
iteration,
|
|
83
|
-
runSummary: result.runSummary,
|
|
84
|
-
notes: result.notes
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export {
|
|
89
|
-
aggregateBenchmark,
|
|
90
|
-
postBenchmark
|
|
91
|
-
};
|
|
92
|
-
//# sourceMappingURL=chunk-PED7L5GX.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/eval-benchmark.ts"],
|
|
4
|
-
"sourcesContent": ["import { apiGet, apiPost } from './api-client.js';\n\ninterface EvalRun {\n id: string;\n evalId: string;\n evalTargetId: string;\n evalTargetVersion: number;\n configuration: string;\n runNumber: number;\n iteration: number;\n status: string;\n outputs: Record<string, unknown>;\n timing: Record<string, unknown>;\n grading: Record<string, unknown>;\n createdAt: string;\n}\n\ninterface Stats {\n mean: number;\n stddev: number;\n min: number;\n max: number;\n}\n\nfunction computeStats(values: number[]): Stats {\n if (values.length === 0) return { mean: 0, stddev: 0, min: 0, max: 0 };\n const mean = values.reduce((a, b) => a + b, 0) / values.length;\n const variance = values.reduce((sum, v) => sum + (v - mean) ** 2, 0) / values.length;\n return {\n mean: Math.round(mean * 1000) / 1000,\n stddev: Math.round(Math.sqrt(variance) * 1000) / 1000,\n min: Math.min(...values),\n max: Math.max(...values),\n };\n}\n\nexport interface BenchmarkResult {\n runSummary: Record<string, Record<string, Stats>>;\n notes: string[];\n totalRuns: number;\n}\n\nexport async function aggregateBenchmark(\n targetId: string,\n iteration?: number,\n): Promise<BenchmarkResult> {\n // Page through ALL runs. The list endpoint caps each page at 100; aggregating\n // over a single truncated page would skew the with/without delta (regression\n // guard \u2014 the 50-row default cap was added 2026-06-22).\n const iterQuery = iteration ? `&iteration=${iteration}` : '';\n const PAGE = 100;\n const runs: EvalRun[] = [];\n for (let offset = 0; offset < 100_000; offset += PAGE) {\n const page = await apiGet<EvalRun[]>(\n `/api/eval-targets/${targetId}/runs?limit=${PAGE}&offset=${offset}${iterQuery}`,\n );\n runs.push(...page);\n if (page.length < PAGE) break;\n }\n\n const completedRuns = runs.filter((r) => r.status === 'completed');\n\n if (completedRuns.length === 0) {\n return { runSummary: {}, notes: ['No completed runs found'], totalRuns: 0 };\n }\n\n // Group by configuration\n const byConfig: Record<string, EvalRun[]> = {};\n for (const run of completedRuns) {\n if (!byConfig[run.configuration]) byConfig[run.configuration] = [];\n byConfig[run.configuration].push(run);\n }\n\n const runSummary: Record<string, Record<string, Stats>> = {};\n const notes: string[] = [];\n\n for (const [config, configRuns] of Object.entries(byConfig)) {\n const passRates = configRuns\n .filter((r) => Object.keys(r.grading).length > 0)\n .map((r) => (r.grading as any).summary?.pass_rate ?? 0);\n const durations = configRuns\n .map((r) => (r.timing as any).duration_ms / 1000)\n .filter((v) => !isNaN(v));\n const tokens = configRuns\n .map((r) => (r.timing as any).total_tokens ?? 0)\n .filter((v) => v > 0);\n\n runSummary[config] = {};\n if (passRates.length > 0) runSummary[config].pass_rate = computeStats(passRates);\n if (durations.length > 0) runSummary[config].time_seconds = computeStats(durations);\n if (tokens.length > 0) runSummary[config].tokens = computeStats(tokens);\n }\n\n // Compute delta if both configurations exist\n if (runSummary.with_target && runSummary.without_target) {\n const delta: Record<string, string> = {};\n for (const metric of ['pass_rate', 'time_seconds', 'tokens']) {\n const withVal = runSummary.with_target[metric]?.mean ?? 0;\n const withoutVal = runSummary.without_target[metric]?.mean ?? 0;\n const diff = withVal - withoutVal;\n delta[metric] = `${diff >= 0 ? '+' : ''}${Math.round(diff * 1000) / 1000}`;\n }\n (runSummary as any).delta = delta;\n\n // Generate analysis notes\n const passRateDelta = (runSummary.with_target.pass_rate?.mean ?? 0) - (runSummary.without_target.pass_rate?.mean ?? 0);\n if (passRateDelta > 0.1) {\n notes.push(`Target improves pass rate by ${(passRateDelta * 100).toFixed(0)}%`);\n } else if (passRateDelta < -0.1) {\n notes.push(`Target decreases pass rate by ${(Math.abs(passRateDelta) * 100).toFixed(0)}%`);\n } else {\n notes.push('Target has minimal impact on pass rate');\n }\n\n const timeDelta = (runSummary.with_target.time_seconds?.mean ?? 0) - (runSummary.without_target.time_seconds?.mean ?? 0);\n if (Math.abs(timeDelta) > 5) {\n notes.push(`Target ${timeDelta > 0 ? 'adds' : 'saves'} ${Math.abs(timeDelta).toFixed(1)}s average execution time`);\n }\n }\n\n // Check for high variance\n for (const [config, stats] of Object.entries(runSummary)) {\n if (config === 'delta') continue;\n const passRate = stats.pass_rate;\n if (passRate && passRate.stddev > 0.2) {\n notes.push(`${config} shows high pass rate variance (stddev=${passRate.stddev.toFixed(2)}) \u2014 results may be unreliable`);\n }\n }\n\n return { runSummary, notes, totalRuns: completedRuns.length };\n}\n\nexport async function postBenchmark(\n targetId: string,\n iteration: number,\n result: BenchmarkResult,\n): Promise<{ id: string }> {\n return apiPost<{ id: string }>(`/api/eval-targets/${targetId}/benchmarks`, {\n iteration,\n runSummary: result.runSummary,\n notes: result.notes,\n });\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-PMI56ED5.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildRecommendationPrompt
|
|
3
|
-
} from "./chunk-E3BIT53W.js";
|
|
4
|
-
import {
|
|
5
|
-
detectLlmBackend,
|
|
6
|
-
runLlmPrompt
|
|
7
|
-
} from "./chunk-FZKLLNDS.js";
|
|
8
|
-
import {
|
|
9
|
-
detectLanguages
|
|
10
|
-
} from "./chunk-OQSQC7VB.js";
|
|
11
|
-
import {
|
|
12
|
-
normalizeProjectPath
|
|
13
|
-
} from "./chunk-EKP32DLN.js";
|
|
14
|
-
import {
|
|
15
|
-
apiGet,
|
|
16
|
-
apiPost
|
|
17
|
-
} from "./chunk-ZUJBM6HE.js";
|
|
18
|
-
|
|
19
|
-
// src/lib/handlers/cron-suggest-instructions.ts
|
|
20
|
-
import { readFileSync } from "node:fs";
|
|
21
|
-
import path from "node:path";
|
|
22
|
-
import os from "node:os";
|
|
23
|
-
var MAX_SUGGESTIONS_PER_PROJECT = 5;
|
|
24
|
-
var MAX_PROJECTS_PER_RUN = Number(process.env.RULEMETRIC_MAX_SUGGESTION_PROJECTS ?? 10);
|
|
25
|
-
var STALE_THRESHOLD_HOURS = 48;
|
|
26
|
-
var MIN_SCORE = 0.5;
|
|
27
|
-
var CONTENT_PREVIEW_CHARS = 400;
|
|
28
|
-
async function checkSkillsRegistryStale() {
|
|
29
|
-
const registryPath = path.join(os.homedir(), ".config", "rulemetric", "skills-registry.json");
|
|
30
|
-
try {
|
|
31
|
-
const raw = readFileSync(registryPath, "utf-8");
|
|
32
|
-
const registry = JSON.parse(raw);
|
|
33
|
-
const ageMs = Date.now() - new Date(registry.generatedAt).getTime();
|
|
34
|
-
return ageMs > STALE_THRESHOLD_HOURS * 60 * 60 * 1e3;
|
|
35
|
-
} catch {
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
var cronSuggestInstructions = async (_payload, helpers) => {
|
|
40
|
-
const backend = detectLlmBackend();
|
|
41
|
-
if (backend === "none") {
|
|
42
|
-
helpers.logger.warn("No LLM backend available (claude CLI missing and ANTHROPIC_API_KEY unset); skipping suggestion compute");
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
helpers.logger.info(`Scoring backend: ${backend}`);
|
|
46
|
-
let projectPaths;
|
|
47
|
-
try {
|
|
48
|
-
const res = await apiGet("/api/sessions/project-paths?limit=" + MAX_PROJECTS_PER_RUN);
|
|
49
|
-
projectPaths = res.projectPaths;
|
|
50
|
-
} catch (err) {
|
|
51
|
-
helpers.logger.warn(`Failed to fetch project paths: ${err instanceof Error ? err.message : String(err)}`);
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
if (projectPaths.length === 0) {
|
|
55
|
-
helpers.logger.info("No recent project paths; nothing to score");
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
const projectIdByPath = /* @__PURE__ */ new Map();
|
|
59
|
-
try {
|
|
60
|
-
const projRes = await apiGet("/api/projects?limit=200");
|
|
61
|
-
for (const p of projRes.projects ?? []) {
|
|
62
|
-
if (p.primaryCheckoutPath) {
|
|
63
|
-
projectIdByPath.set(normalizeProjectPath(p.primaryCheckoutPath), p.id);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
} catch (err) {
|
|
67
|
-
helpers.logger.warn(`Failed to fetch projects for id resolution: ${err instanceof Error ? err.message : String(err)}`);
|
|
68
|
-
}
|
|
69
|
-
const candidates = /* @__PURE__ */ new Map();
|
|
70
|
-
try {
|
|
71
|
-
const catalogRows = await apiGet("/api/catalog?limit=200");
|
|
72
|
-
for (const row of catalogRows) {
|
|
73
|
-
candidates.set(row.id, {
|
|
74
|
-
id: row.id,
|
|
75
|
-
name: row.name,
|
|
76
|
-
description: row.description ?? "",
|
|
77
|
-
tags: row.tags ?? [],
|
|
78
|
-
contentPreview: (row.content ?? "").slice(0, CONTENT_PREVIEW_CHARS)
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
} catch (err) {
|
|
82
|
-
helpers.logger.warn(`Failed to fetch catalog: ${err instanceof Error ? err.message : String(err)}`);
|
|
83
|
-
}
|
|
84
|
-
try {
|
|
85
|
-
const personalRes = await apiGet("/api/instructions?limit=100");
|
|
86
|
-
for (const row of personalRes.instructions ?? []) {
|
|
87
|
-
if (!candidates.has(row.id)) {
|
|
88
|
-
candidates.set(row.id, {
|
|
89
|
-
id: row.id,
|
|
90
|
-
name: row.name,
|
|
91
|
-
description: row.description ?? "",
|
|
92
|
-
tags: row.tags ?? [],
|
|
93
|
-
contentPreview: (row.content ?? "").slice(0, CONTENT_PREVIEW_CHARS)
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
} catch (err) {
|
|
98
|
-
helpers.logger.warn(`Failed to fetch personal instructions: ${err instanceof Error ? err.message : String(err)}`);
|
|
99
|
-
}
|
|
100
|
-
const candidateList = [...candidates.values()];
|
|
101
|
-
if (candidateList.length === 0) {
|
|
102
|
-
helpers.logger.info("No candidate instructions; nothing to score");
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
helpers.logger.info(`Scoring ${candidateList.length} candidates across ${projectPaths.length} project(s)`);
|
|
106
|
-
let scored = 0;
|
|
107
|
-
for (const rawPath of projectPaths) {
|
|
108
|
-
try {
|
|
109
|
-
const projectPath = normalizeProjectPath(rawPath);
|
|
110
|
-
const languages = detectLanguages(projectPath);
|
|
111
|
-
if (languages.length === 0) {
|
|
112
|
-
helpers.logger.info(`Skipping ${projectPath}: insufficient language signals`);
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
const context = {
|
|
116
|
-
name: path.basename(projectPath),
|
|
117
|
-
description: null,
|
|
118
|
-
languages,
|
|
119
|
-
topics: [],
|
|
120
|
-
dependencies: []
|
|
121
|
-
};
|
|
122
|
-
const prompt = buildRecommendationPrompt(context, candidateList);
|
|
123
|
-
const parsed = await runLlmPrompt(prompt, "", 4096);
|
|
124
|
-
if (!parsed) {
|
|
125
|
-
helpers.logger.warn(`LLM returned null for ${projectPath} (backend ${backend})`);
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
const raw = parsed.recommendations ?? [];
|
|
129
|
-
const recommendations = raw.filter((r) => typeof r.instructionId === "string" && typeof r.score === "number" && typeof r.reason === "string").map((r) => ({
|
|
130
|
-
instructionId: r.instructionId,
|
|
131
|
-
score: r.score,
|
|
132
|
-
reason: r.reason
|
|
133
|
-
}));
|
|
134
|
-
const top = recommendations.filter((r) => r.score >= MIN_SCORE).sort((a, b) => b.score - a.score).slice(0, MAX_SUGGESTIONS_PER_PROJECT);
|
|
135
|
-
if (top.length === 0) {
|
|
136
|
-
helpers.logger.info(`No suggestions over threshold for ${projectPath}`);
|
|
137
|
-
continue;
|
|
138
|
-
}
|
|
139
|
-
const projectId = projectIdByPath.get(projectPath);
|
|
140
|
-
await apiPost("/api/instruction-suggestions/batch-upsert", {
|
|
141
|
-
projectPath,
|
|
142
|
-
...projectId ? { projectId } : {},
|
|
143
|
-
suggestions: top.map((r) => ({
|
|
144
|
-
instructionId: r.instructionId,
|
|
145
|
-
score: r.score,
|
|
146
|
-
reason: r.reason
|
|
147
|
-
}))
|
|
148
|
-
});
|
|
149
|
-
scored++;
|
|
150
|
-
} catch (err) {
|
|
151
|
-
helpers.logger.warn(`Failed to score ${rawPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
if (await checkSkillsRegistryStale()) {
|
|
155
|
-
try {
|
|
156
|
-
await apiPost("/api/instruction-suggestions/mark-stale", {});
|
|
157
|
-
helpers.logger.warn("Skills registry is stale (>48h); marked all suggestions stale");
|
|
158
|
-
} catch {
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
helpers.logger.info(`Done: scored ${scored}/${projectPaths.length} projects`);
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
export {
|
|
165
|
-
cronSuggestInstructions
|
|
166
|
-
};
|
|
167
|
-
//# sourceMappingURL=chunk-PMI56ED5.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/handlers/cron-suggest-instructions.ts"],
|
|
4
|
-
"sourcesContent": ["import type { JobHelpers } from '../job-helpers.js';\nimport { readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { apiGet, apiPost } from '../api-client.js';\nimport { runLlmPrompt, detectLlmBackend } from '../llm-client.js';\nimport { buildRecommendationPrompt } from '@rulemetric/core';\nimport { normalizeProjectPath } from '@rulemetric/core/paths';\nimport type { ProjectContext, InstructionCandidate, Recommendation } from '@rulemetric/core';\nimport { detectLanguages } from '../detect-languages.js';\n\nconst MAX_SUGGESTIONS_PER_PROJECT = 5;\nconst MAX_PROJECTS_PER_RUN = Number(process.env.RULEMETRIC_MAX_SUGGESTION_PROJECTS ?? 10);\nconst STALE_THRESHOLD_HOURS = 48;\nconst MIN_SCORE = 0.5;\nconst CONTENT_PREVIEW_CHARS = 400;\n\ninterface CatalogRow {\n id: string;\n name: string;\n description: string | null;\n tags: string[] | null;\n content: string | null;\n scope: string;\n}\n\ninterface ProjectPathsResponse {\n projectPaths: string[];\n}\n\ninterface ProjectRow {\n id: string;\n primaryCheckoutPath: string | null;\n}\n\ninterface ProjectsResponse {\n projects: ProjectRow[];\n}\n\ninterface SkillsRegistryFile {\n generatedAt: string;\n skills: unknown[];\n}\n\ninterface BatchUpsertResponse {\n inserted: number;\n}\n\nasync function checkSkillsRegistryStale(): Promise<boolean> {\n const registryPath = path.join(os.homedir(), '.config', 'rulemetric', 'skills-registry.json');\n try {\n const raw = readFileSync(registryPath, 'utf-8');\n const registry = JSON.parse(raw) as SkillsRegistryFile;\n const ageMs = Date.now() - new Date(registry.generatedAt).getTime();\n return ageMs > STALE_THRESHOLD_HOURS * 60 * 60 * 1000;\n } catch {\n return true;\n }\n}\n\nexport const cronSuggestInstructions = async (_payload: unknown, helpers: JobHelpers): Promise<void> => {\n // Scoring uses the user's locally-installed LLM tooling \u2014 Claude Code CLI\n // when available, otherwise the Anthropic SDK with ANTHROPIC_API_KEY.\n // No third-party LLM_PROVIDER / LLM_API_KEY required. If neither backend\n // is reachable, skip cleanly.\n const backend = detectLlmBackend();\n if (backend === 'none') {\n helpers.logger.warn('No LLM backend available (claude CLI missing and ANTHROPIC_API_KEY unset); skipping suggestion compute');\n return;\n }\n helpers.logger.info(`Scoring backend: ${backend}`);\n\n // 1. Fetch recent project paths\n let projectPaths: string[];\n try {\n const res = await apiGet<ProjectPathsResponse>('/api/sessions/project-paths?limit=' + MAX_PROJECTS_PER_RUN);\n projectPaths = res.projectPaths;\n } catch (err) {\n helpers.logger.warn(`Failed to fetch project paths: ${err instanceof Error ? err.message : String(err)}`);\n return;\n }\n\n if (projectPaths.length === 0) {\n helpers.logger.info('No recent project paths; nothing to score');\n return;\n }\n\n // Best-effort path -> canonical project_id map so the batch-upsert can stamp\n // project_id (migration 00104). Keyed by normalized checkout path. Purely\n // additive: when a path isn't found here we send no projectId and the API\n // resolves it from project_path itself (and NULLs it when unresolved).\n const projectIdByPath = new Map<string, string>();\n try {\n const projRes = await apiGet<ProjectsResponse>('/api/projects?limit=200');\n for (const p of projRes.projects ?? []) {\n if (p.primaryCheckoutPath) {\n projectIdByPath.set(normalizeProjectPath(p.primaryCheckoutPath), p.id);\n }\n }\n } catch (err) {\n helpers.logger.warn(`Failed to fetch projects for id resolution: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n // 2. Fetch candidate instructions: public+org+team from /catalog, plus\n // the user's own (personal+created) from /instructions. Dedup by id.\n const candidates = new Map<string, InstructionCandidate>();\n try {\n const catalogRows = await apiGet<CatalogRow[]>('/api/catalog?limit=200');\n for (const row of catalogRows) {\n candidates.set(row.id, {\n id: row.id,\n name: row.name,\n description: row.description ?? '',\n tags: row.tags ?? [],\n contentPreview: (row.content ?? '').slice(0, CONTENT_PREVIEW_CHARS),\n });\n }\n } catch (err) {\n helpers.logger.warn(`Failed to fetch catalog: ${err instanceof Error ? err.message : String(err)}`);\n }\n try {\n const personalRes = await apiGet<{ instructions: CatalogRow[] }>('/api/instructions?limit=100');\n for (const row of personalRes.instructions ?? []) {\n if (!candidates.has(row.id)) {\n candidates.set(row.id, {\n id: row.id,\n name: row.name,\n description: row.description ?? '',\n tags: row.tags ?? [],\n contentPreview: (row.content ?? '').slice(0, CONTENT_PREVIEW_CHARS),\n });\n }\n }\n } catch (err) {\n helpers.logger.warn(`Failed to fetch personal instructions: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n const candidateList = [...candidates.values()];\n if (candidateList.length === 0) {\n helpers.logger.info('No candidate instructions; nothing to score');\n return;\n }\n helpers.logger.info(`Scoring ${candidateList.length} candidates across ${projectPaths.length} project(s)`);\n\n // 3. Score per project\n let scored = 0;\n for (const rawPath of projectPaths) {\n try {\n const projectPath = normalizeProjectPath(rawPath);\n const languages = detectLanguages(projectPath);\n if (languages.length === 0) {\n helpers.logger.info(`Skipping ${projectPath}: insufficient language signals`);\n continue;\n }\n\n const context: ProjectContext = {\n name: path.basename(projectPath),\n description: null,\n languages,\n topics: [],\n dependencies: [],\n };\n\n const prompt = buildRecommendationPrompt(context, candidateList);\n // runLlmPrompt expects (systemPrompt, data, maxTokens). The recommendation\n // prompt is fully self-contained; pass an empty data block.\n const parsed = await runLlmPrompt(prompt, '', 4096);\n if (!parsed) {\n helpers.logger.warn(`LLM returned null for ${projectPath} (backend ${backend})`);\n continue;\n }\n const raw = (parsed.recommendations ?? []) as Array<Record<string, unknown>>;\n const recommendations: Recommendation[] = raw\n .filter((r) => typeof r.instructionId === 'string' && typeof r.score === 'number' && typeof r.reason === 'string')\n .map((r) => ({\n instructionId: r.instructionId as string,\n score: r.score as number,\n reason: r.reason as string,\n }));\n\n const top = recommendations\n .filter((r) => r.score >= MIN_SCORE)\n .sort((a, b) => b.score - a.score)\n .slice(0, MAX_SUGGESTIONS_PER_PROJECT);\n\n if (top.length === 0) {\n helpers.logger.info(`No suggestions over threshold for ${projectPath}`);\n continue;\n }\n\n // Resolve canonical project_id from the normalized path when known.\n // Best-effort: omitted when unresolved, in which case the API resolves\n // from project_path (and leaves project_id NULL if still unknown).\n const projectId = projectIdByPath.get(projectPath);\n\n await apiPost<BatchUpsertResponse>('/api/instruction-suggestions/batch-upsert', {\n projectPath,\n ...(projectId ? { projectId } : {}),\n suggestions: top.map((r) => ({\n instructionId: r.instructionId,\n score: r.score,\n reason: r.reason,\n })),\n });\n scored++;\n } catch (err) {\n helpers.logger.warn(`Failed to score ${rawPath}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n // 4. Mark stale if registry is old\n if (await checkSkillsRegistryStale()) {\n try {\n await apiPost('/api/instruction-suggestions/mark-stale', {});\n helpers.logger.warn('Skills registry is stale (>48h); marked all suggestions stale');\n } catch {\n // Non-fatal\n }\n }\n\n helpers.logger.info(`Done: scored ${scored}/${projectPaths.length} projects`);\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-QJQS6TUN.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
// src/dashboard/types.ts
|
|
2
|
-
var PERIODS = ["today", "week", "30days", "month", "all"];
|
|
3
|
-
var PERIOD_LABELS = {
|
|
4
|
-
today: "Today",
|
|
5
|
-
week: "7 Days",
|
|
6
|
-
"30days": "30 Days",
|
|
7
|
-
month: "This Month",
|
|
8
|
-
all: "All Time"
|
|
9
|
-
};
|
|
10
|
-
function getDateRange(period) {
|
|
11
|
-
const now = /* @__PURE__ */ new Date();
|
|
12
|
-
const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
|
|
13
|
-
switch (period) {
|
|
14
|
-
case "today":
|
|
15
|
-
return { start: new Date(now.getFullYear(), now.getMonth(), now.getDate()), end };
|
|
16
|
-
case "week":
|
|
17
|
-
return { start: new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7), end };
|
|
18
|
-
case "30days":
|
|
19
|
-
return { start: new Date(now.getFullYear(), now.getMonth(), now.getDate() - 30), end };
|
|
20
|
-
case "month":
|
|
21
|
-
return { start: new Date(now.getFullYear(), now.getMonth(), 1), end };
|
|
22
|
-
case "all":
|
|
23
|
-
return { start: /* @__PURE__ */ new Date(0), end };
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
var ORANGE = "#FF8C42";
|
|
27
|
-
var DIM = "#555555";
|
|
28
|
-
var GOLD = "#FFD700";
|
|
29
|
-
var GREEN = "#5BF58C";
|
|
30
|
-
var RED = "#F55B5B";
|
|
31
|
-
var BLUE = "#5B9EF5";
|
|
32
|
-
|
|
33
|
-
export {
|
|
34
|
-
PERIODS,
|
|
35
|
-
PERIOD_LABELS,
|
|
36
|
-
getDateRange,
|
|
37
|
-
ORANGE,
|
|
38
|
-
DIM,
|
|
39
|
-
GOLD,
|
|
40
|
-
GREEN,
|
|
41
|
-
RED,
|
|
42
|
-
BLUE
|
|
43
|
-
};
|
|
44
|
-
//# sourceMappingURL=chunk-QJQS6TUN.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/dashboard/types.ts"],
|
|
4
|
-
"sourcesContent": ["export type Period = 'today' | 'week' | '30days' | 'month' | 'all';\n\nexport const PERIODS: Period[] = ['today', 'week', '30days', 'month', 'all'];\n\nexport const PERIOD_LABELS: Record<Period, string> = {\n today: 'Today',\n week: '7 Days',\n '30days': '30 Days',\n month: 'This Month',\n all: 'All Time',\n};\n\nexport function getDateRange(period: Period): { start: Date; end: Date } {\n const now = new Date();\n const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);\n switch (period) {\n case 'today': return { start: new Date(now.getFullYear(), now.getMonth(), now.getDate()), end };\n case 'week': return { start: new Date(now.getFullYear(), now.getMonth(), now.getDate() - 7), end };\n case '30days': return { start: new Date(now.getFullYear(), now.getMonth(), now.getDate() - 30), end };\n case 'month': return { start: new Date(now.getFullYear(), now.getMonth(), 1), end };\n case 'all': return { start: new Date(0), end };\n }\n}\n\n// Colors\nexport const ORANGE = '#FF8C42';\nexport const DIM = '#555555';\nexport const GOLD = '#FFD700';\nexport const GREEN = '#5BF58C';\nexport const RED = '#F55B5B';\nexport const BLUE = '#5B9EF5';\n\nexport interface LocalStats {\n totalSessions: number;\n totalCalls: number;\n totalInputTokens: number;\n totalOutputTokens: number;\n totalCacheReadTokens: number;\n totalCacheWriteTokens: number;\n totalCostUSD: number;\n providers: Record<string, number>;\n}\n\nexport interface Suggestion {\n label: string;\n description: string;\n command: string;\n}\n\nexport interface ApiInsights {\n total_sessions: number;\n sessions_with_meta: number;\n sessions_with_analysis: number;\n total_messages: number;\n total_duration_hours: number;\n total_input_tokens: number;\n total_output_tokens: number;\n total_cache_read_tokens: number;\n total_cache_write_tokens: number;\n estimated_cost_usd: number;\n outcomes: Record<string, number>;\n friction: Record<string, number>;\n goal_categories: Record<string, number>;\n tools_used: Record<string, number>;\n tool_counts: Record<string, number>;\n git_commits: number;\n days_active: number;\n messages_per_day: number;\n recommendations?: {\n at_a_glance?: Record<string, string>;\n suggestions?: {\n features_to_try?: Array<{ feature: string; one_liner: string; why_for_you: string; example_code: string }>;\n usage_patterns?: Array<{ title: string; suggestion: string; detail: string; copyable_prompt: string }>;\n claude_md_additions?: Array<{ addition: string; why: string; prompt_scaffold: string }>;\n };\n on_the_horizon?: {\n opportunities?: Array<{ title: string; whats_possible: string; how_to_try: string; copyable_prompt: string }>;\n };\n [key: string]: unknown;\n };\n}\n"],
|
|
5
|
-
"mappings": ";AAEO,IAAM,UAAoB,CAAC,SAAS,QAAQ,UAAU,SAAS,KAAK;AAEpE,IAAM,gBAAwC;AAAA,EACnD,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU;AAAA,EACV,OAAO;AAAA,EACP,KAAK;AACP;AAEO,SAAS,aAAa,QAA4C;AACvE,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,MAAM,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,GAAG,IAAI,QAAQ,GAAG,IAAI,IAAI,IAAI,GAAG;AACtF,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAS,aAAO,EAAE,OAAO,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,GAAG,IAAI,QAAQ,CAAC,GAAG,IAAI;AAAA,IAC9F,KAAK;AAAQ,aAAO,EAAE,OAAO,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,GAAG,IAAI,QAAQ,IAAI,CAAC,GAAG,IAAI;AAAA,IACjG,KAAK;AAAU,aAAO,EAAE,OAAO,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,GAAG,IAAI,QAAQ,IAAI,EAAE,GAAG,IAAI;AAAA,IACpG,KAAK;AAAS,aAAO,EAAE,OAAO,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,GAAG,CAAC,GAAG,IAAI;AAAA,IAClF,KAAK;AAAO,aAAO,EAAE,OAAO,oBAAI,KAAK,CAAC,GAAG,IAAI;AAAA,EAC/C;AACF;AAGO,IAAM,SAAS;AACf,IAAM,MAAM;AACZ,IAAM,OAAO;AACb,IAAM,QAAQ;AACd,IAAM,MAAM;AACZ,IAAM,OAAO;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-QN34TGD3.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
// src/lib/eval-executor.ts
|
|
2
|
-
import { spawn } from "node:child_process";
|
|
3
|
-
async function executeEval(options) {
|
|
4
|
-
const {
|
|
5
|
-
prompt,
|
|
6
|
-
targetContent,
|
|
7
|
-
systemPrompt,
|
|
8
|
-
workDir = process.cwd(),
|
|
9
|
-
timeout = 12e4,
|
|
10
|
-
model
|
|
11
|
-
} = options;
|
|
12
|
-
const args = ["-p", prompt, "--output-format", "json"];
|
|
13
|
-
const sysPrompt = targetContent ?? systemPrompt;
|
|
14
|
-
if (sysPrompt) {
|
|
15
|
-
args.push("--system-prompt", sysPrompt);
|
|
16
|
-
}
|
|
17
|
-
if (model) {
|
|
18
|
-
args.push("--model", model);
|
|
19
|
-
}
|
|
20
|
-
const startTime = Date.now();
|
|
21
|
-
return new Promise((resolve) => {
|
|
22
|
-
const env = { ...process.env };
|
|
23
|
-
delete env.CLAUDECODE;
|
|
24
|
-
delete env.HTTPS_PROXY;
|
|
25
|
-
const proc = spawn("claude", args, {
|
|
26
|
-
cwd: workDir,
|
|
27
|
-
env,
|
|
28
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
29
|
-
});
|
|
30
|
-
let stdout = "";
|
|
31
|
-
let stderr = "";
|
|
32
|
-
proc.stdout.on("data", (data) => {
|
|
33
|
-
stdout += data.toString();
|
|
34
|
-
});
|
|
35
|
-
proc.stderr.on("data", (data) => {
|
|
36
|
-
stderr += data.toString();
|
|
37
|
-
});
|
|
38
|
-
const timer = setTimeout(() => {
|
|
39
|
-
proc.kill("SIGTERM");
|
|
40
|
-
resolve({
|
|
41
|
-
output: stdout,
|
|
42
|
-
exitCode: null,
|
|
43
|
-
durationMs: Date.now() - startTime,
|
|
44
|
-
totalTokens: 0,
|
|
45
|
-
error: `Timed out after ${timeout}ms`
|
|
46
|
-
});
|
|
47
|
-
}, timeout);
|
|
48
|
-
proc.on("close", (code) => {
|
|
49
|
-
clearTimeout(timer);
|
|
50
|
-
const durationMs = Date.now() - startTime;
|
|
51
|
-
let totalTokens = 0;
|
|
52
|
-
let output = stdout;
|
|
53
|
-
try {
|
|
54
|
-
const parsed = JSON.parse(stdout);
|
|
55
|
-
output = parsed.result ?? parsed.content ?? stdout;
|
|
56
|
-
totalTokens = parsed.usage?.total_tokens ?? (parsed.usage?.input_tokens ?? 0) + (parsed.usage?.output_tokens ?? 0);
|
|
57
|
-
} catch {
|
|
58
|
-
}
|
|
59
|
-
resolve({
|
|
60
|
-
output,
|
|
61
|
-
exitCode: code,
|
|
62
|
-
durationMs,
|
|
63
|
-
totalTokens,
|
|
64
|
-
error: code !== 0 ? stderr || `Exit code ${code}` : void 0
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
proc.on("error", (err) => {
|
|
68
|
-
clearTimeout(timer);
|
|
69
|
-
resolve({
|
|
70
|
-
output: "",
|
|
71
|
-
exitCode: null,
|
|
72
|
-
durationMs: Date.now() - startTime,
|
|
73
|
-
totalTokens: 0,
|
|
74
|
-
error: `Failed to spawn claude: ${err.message}`
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export {
|
|
81
|
-
executeEval
|
|
82
|
-
};
|
|
83
|
-
//# sourceMappingURL=chunk-QN34TGD3.js.map
|