@rulemetric/cli 0.7.3 → 0.7.5
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/README.md +10 -8
- package/dist/base-command.js +1 -14
- package/dist/chunk-2JRDG4LJ.js +31 -0
- package/dist/chunk-2TC6WCUT.js +34 -0
- package/dist/chunk-2WLVDSAP.js +2 -0
- package/dist/chunk-32EEBARV.js +1 -0
- package/dist/chunk-3AV3GTMP.js +1 -0
- package/dist/chunk-43YBXX7R.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-7DFNBRLY.js +61 -0
- package/dist/chunk-ARNZQBMX.js +1 -0
- package/dist/chunk-AYUJY37O.js +5 -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-DCLWFGEA.js +1 -0
- package/dist/chunk-DNF4HDI6.js +14 -0
- package/dist/chunk-DPFNJZUO.js +1 -0
- package/dist/chunk-DSO2U4Y6.js +56 -0
- package/dist/chunk-DVN7GFJG.js +1 -0
- package/dist/chunk-G63KMH6U.js +1 -0
- package/dist/chunk-G6XGDHGC.js +2 -0
- package/dist/chunk-GBMF3TP6.js +1 -0
- package/dist/chunk-GY5IJ4RS.js +1 -0
- package/dist/chunk-H2ORWIEY.js +1 -0
- package/dist/chunk-H4SV7FN4.js +1 -0
- package/dist/chunk-HS7X43XE.js +24 -0
- package/dist/{chunk-OQBBVTDG.js → chunk-I2DZGJRR.js} +6 -71
- package/dist/chunk-IZTIYR5Q.js +2 -0
- package/dist/chunk-JAPCCEKF.js +3 -0
- package/dist/chunk-JQTGQXUX.js +1 -0
- package/dist/chunk-KAF3CYRW.js +9 -0
- package/dist/chunk-KKDHD4XA.js +2 -0
- package/dist/chunk-KV325CXF.js +33 -0
- package/dist/chunk-MGHFDHHM.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-N7TGRFVZ.js +70 -0
- package/dist/chunk-NBTC5FNV.js +1 -0
- package/dist/chunk-NEACEHQD.js +1 -0
- package/dist/chunk-NJ5UED3H.js +1 -0
- package/dist/chunk-NVKX36YN.js +3 -0
- package/dist/chunk-O2SDD2WW.js +1 -0
- package/dist/chunk-O6C2UGBY.js +7 -0
- package/dist/chunk-OMXUK4M6.js +1 -0
- package/dist/chunk-PPKPCXJD.js +4 -0
- package/dist/{chunk-XZXS2W24.js → chunk-QFVGUZDO.js} +11 -57
- package/dist/chunk-RDET7CKR.js +1 -0
- package/dist/chunk-RQ424GI6.js +5 -0
- package/dist/chunk-RSKQRVPJ.js +1 -0
- package/dist/chunk-RTWRHIKY.js +7 -0
- package/dist/chunk-SZ62CP55.js +1 -0
- package/dist/chunk-TDD7IOV2.js +1 -0
- package/dist/chunk-TIOKY2IA.js +1 -0
- package/dist/chunk-TQMG647B.js +15 -0
- package/dist/chunk-TU2AR6XO.js +1 -0
- package/dist/chunk-U6ABMRT3.js +9 -0
- package/dist/chunk-U6XEU573.js +1 -0
- package/dist/chunk-UF6US7VU.js +1 -0
- package/dist/chunk-V44SRRYR.js +1 -0
- package/dist/chunk-V5U3E4BZ.js +1 -0
- package/dist/chunk-VAXRCSSH.js +2 -0
- package/dist/chunk-VLOX6KOM.js +1 -0
- package/dist/chunk-VUGRXM7R.js +1 -0
- package/dist/chunk-W2MOTOQE.js +1 -0
- package/dist/chunk-W2MV25SB.js +1 -0
- package/dist/chunk-WLVQJH4E.js +1 -0
- package/dist/chunk-WSCK4WNK.js +1 -0
- package/dist/chunk-XICLXXRH.js +1 -0
- package/dist/chunk-XXDZJ6YI.js +1 -0
- package/dist/chunk-ZL4MZMUK.js +34 -0
- package/dist/chunk-ZLLER3HP.js +1 -0
- package/dist/chunk-ZR3MUNLS.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 +4 -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 -310
- 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 +17 -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 -796
- package/dist/commands/service/status.js +1 -180
- package/dist/commands/service/uninstall.js +1 -119
- package/dist/commands/sessions/analyze.js +1 -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 +2 -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 -47
- 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/ensure-fresh-token.js +1 -0
- 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 -16
- 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 -15
- 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 -12
- 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 -20
- package/dist/lib/manual-tasks-meta.js +1 -8
- package/dist/lib/manual-tasks.js +1 -80
- 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 +12 -34
- package/package.json +9 -8
- 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-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-DIQUV5FR.js +0 -257
- package/dist/chunk-DIQUV5FR.js.map +0 -7
- package/dist/chunk-DMX5YOTM.js +0 -167
- package/dist/chunk-DMX5YOTM.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-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-OCKHW72U.js +0 -55
- package/dist/chunk-OCKHW72U.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-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-RAXRZYOB.js +0 -299
- package/dist/chunk-RAXRZYOB.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-VA5FFOS7.js +0 -243
- package/dist/chunk-VA5FFOS7.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-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-DMX5YOTM.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildRecommendationPrompt
|
|
3
|
-
} from "./chunk-E3BIT53W.js";
|
|
4
|
-
import {
|
|
5
|
-
detectLlmBackend,
|
|
6
|
-
runLlmPrompt
|
|
7
|
-
} from "./chunk-DIQUV5FR.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-DMX5YOTM.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-DNKSVWMD.js
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DIM,
|
|
3
|
-
ORANGE,
|
|
4
|
-
RED
|
|
5
|
-
} from "./chunk-QJQS6TUN.js";
|
|
6
|
-
import {
|
|
7
|
-
toolLabel
|
|
8
|
-
} from "./chunk-RH7NHVSK.js";
|
|
9
|
-
|
|
10
|
-
// src/dashboard/launcher/NewLaunchForm.tsx
|
|
11
|
-
import { useState } from "react";
|
|
12
|
-
import { Box, Text, useInput } from "ink";
|
|
13
|
-
import TextInput from "ink-text-input";
|
|
14
|
-
import SelectInput from "ink-select-input";
|
|
15
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
-
var FIELD_ORDER = ["tool", "project", "mode", "prompt", "submit"];
|
|
17
|
-
function NewLaunchForm({
|
|
18
|
-
launchers,
|
|
19
|
-
defaultProjectPath,
|
|
20
|
-
defaultTool,
|
|
21
|
-
defaultPrompt,
|
|
22
|
-
defaultResumeSessionId,
|
|
23
|
-
focused,
|
|
24
|
-
onSubmit
|
|
25
|
-
}) {
|
|
26
|
-
const [tool, setTool] = useState(defaultTool ?? launchers[0]?.tool ?? "claude_code");
|
|
27
|
-
const [projectPath, setProjectPath] = useState(defaultProjectPath);
|
|
28
|
-
const [mode, setMode] = useState("interactive");
|
|
29
|
-
const [prompt, setPrompt] = useState(defaultPrompt ?? "");
|
|
30
|
-
const [field, setField] = useState("tool");
|
|
31
|
-
const [submitting, setSubmitting] = useState(false);
|
|
32
|
-
const [submitError, setSubmitError] = useState(null);
|
|
33
|
-
const canSubmit = prompt.trim().length > 0 && projectPath.trim().length > 0 && !submitting;
|
|
34
|
-
useInput((input, key) => {
|
|
35
|
-
if (!focused) return;
|
|
36
|
-
if (key.upArrow) {
|
|
37
|
-
const idx = FIELD_ORDER.indexOf(field);
|
|
38
|
-
if (idx > 0) setField(FIELD_ORDER[idx - 1]);
|
|
39
|
-
} else if (key.downArrow) {
|
|
40
|
-
const idx = FIELD_ORDER.indexOf(field);
|
|
41
|
-
if (idx < FIELD_ORDER.length - 1) setField(FIELD_ORDER[idx + 1]);
|
|
42
|
-
} else if (key.return && field === "submit" && canSubmit) {
|
|
43
|
-
void doSubmit();
|
|
44
|
-
} else if (field === "mode" && (input === " " || key.return)) {
|
|
45
|
-
setMode((m) => m === "interactive" ? "headless" : "interactive");
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
async function doSubmit() {
|
|
49
|
-
setSubmitting(true);
|
|
50
|
-
setSubmitError(null);
|
|
51
|
-
try {
|
|
52
|
-
await onSubmit({
|
|
53
|
-
tool,
|
|
54
|
-
config: {
|
|
55
|
-
projectPath,
|
|
56
|
-
prompt,
|
|
57
|
-
mode,
|
|
58
|
-
...defaultResumeSessionId ? { resumeSessionId: defaultResumeSessionId } : {}
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
setPrompt("");
|
|
62
|
-
setSubmitError(null);
|
|
63
|
-
} catch (e) {
|
|
64
|
-
setSubmitError(e instanceof Error ? e.message : String(e));
|
|
65
|
-
} finally {
|
|
66
|
-
setSubmitting(false);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
|
|
70
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: ORANGE, children: "\u25BC New launch" }),
|
|
71
|
-
/* @__PURE__ */ jsxs(Box, { children: [
|
|
72
|
-
/* @__PURE__ */ jsx(Text, { color: field === "tool" && focused ? ORANGE : DIM, children: " Tool: " }),
|
|
73
|
-
field === "tool" && focused ? /* @__PURE__ */ jsx(
|
|
74
|
-
SelectInput,
|
|
75
|
-
{
|
|
76
|
-
items: launchers.map((l) => ({ label: toolLabel(l.tool), value: l.tool })),
|
|
77
|
-
initialIndex: Math.max(0, launchers.findIndex((l) => l.tool === tool)),
|
|
78
|
-
onSelect: (item) => setTool(item.value)
|
|
79
|
-
}
|
|
80
|
-
) : /* @__PURE__ */ jsx(Text, { children: toolLabel(tool) })
|
|
81
|
-
] }),
|
|
82
|
-
/* @__PURE__ */ jsxs(Box, { children: [
|
|
83
|
-
/* @__PURE__ */ jsx(Text, { color: field === "project" && focused ? ORANGE : DIM, children: " Project: " }),
|
|
84
|
-
field === "project" && focused ? /* @__PURE__ */ jsx(TextInput, { value: projectPath, onChange: setProjectPath }) : /* @__PURE__ */ jsx(Text, { children: projectPath })
|
|
85
|
-
] }),
|
|
86
|
-
/* @__PURE__ */ jsxs(Box, { children: [
|
|
87
|
-
/* @__PURE__ */ jsx(Text, { color: field === "mode" && focused ? ORANGE : DIM, children: " Mode: " }),
|
|
88
|
-
/* @__PURE__ */ jsx(Text, { children: mode === "interactive" ? "(\u2022) interactive ( ) headless" : "( ) interactive (\u2022) headless" })
|
|
89
|
-
] }),
|
|
90
|
-
/* @__PURE__ */ jsxs(Box, { children: [
|
|
91
|
-
/* @__PURE__ */ jsx(Text, { color: field === "prompt" && focused ? ORANGE : DIM, children: " Prompt: " }),
|
|
92
|
-
field === "prompt" && focused ? /* @__PURE__ */ jsx(TextInput, { value: prompt, onChange: setPrompt }) : /* @__PURE__ */ jsx(Text, { children: prompt || "(empty)" })
|
|
93
|
-
] }),
|
|
94
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { color: field === "submit" && focused ? ORANGE : DIM, children: [
|
|
95
|
-
canSubmit ? " [ Submit ]" : " [ Submit (disabled) ]",
|
|
96
|
-
submitting ? " \u2026submitting" : ""
|
|
97
|
-
] }) }),
|
|
98
|
-
submitError && /* @__PURE__ */ jsxs(Text, { color: RED, children: [
|
|
99
|
-
" \u2717 ",
|
|
100
|
-
submitError
|
|
101
|
-
] })
|
|
102
|
-
] });
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export {
|
|
106
|
-
NewLaunchForm
|
|
107
|
-
};
|
|
108
|
-
//# sourceMappingURL=chunk-DNKSVWMD.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/dashboard/launcher/NewLaunchForm.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport TextInput from 'ink-text-input';\nimport SelectInput from 'ink-select-input';\nimport { ORANGE, DIM, RED } from '../types.js';\nimport { toolLabel } from './tool-labels.js';\nimport type { AvailableLauncher, CreateLaunchPayload } from './types.js';\n\ntype FormField = 'tool' | 'project' | 'mode' | 'prompt' | 'submit';\nconst FIELD_ORDER: FormField[] = ['tool', 'project', 'mode', 'prompt', 'submit'];\n\nexport function NewLaunchForm({\n launchers,\n defaultProjectPath,\n defaultTool,\n defaultPrompt,\n defaultResumeSessionId,\n focused,\n onSubmit,\n}: {\n launchers: AvailableLauncher[];\n defaultProjectPath: string;\n defaultTool?: string;\n defaultPrompt?: string;\n defaultResumeSessionId?: string;\n focused: boolean;\n onSubmit: (payload: CreateLaunchPayload) => Promise<void>;\n}) {\n const [tool, setTool] = useState(defaultTool ?? launchers[0]?.tool ?? 'claude_code');\n const [projectPath, setProjectPath] = useState(defaultProjectPath);\n const [mode, setMode] = useState<'interactive' | 'headless'>('interactive');\n const [prompt, setPrompt] = useState(defaultPrompt ?? '');\n const [field, setField] = useState<FormField>('tool');\n const [submitting, setSubmitting] = useState(false);\n const [submitError, setSubmitError] = useState<string | null>(null);\n\n const canSubmit = prompt.trim().length > 0 && projectPath.trim().length > 0 && !submitting;\n\n useInput((input, key) => {\n if (!focused) return;\n if (key.upArrow) {\n const idx = FIELD_ORDER.indexOf(field);\n if (idx > 0) setField(FIELD_ORDER[idx - 1]!);\n } else if (key.downArrow) {\n const idx = FIELD_ORDER.indexOf(field);\n if (idx < FIELD_ORDER.length - 1) setField(FIELD_ORDER[idx + 1]!);\n } else if (key.return && field === 'submit' && canSubmit) {\n void doSubmit();\n } else if (field === 'mode' && (input === ' ' || key.return)) {\n setMode((m) => (m === 'interactive' ? 'headless' : 'interactive'));\n }\n });\n\n async function doSubmit() {\n setSubmitting(true);\n setSubmitError(null);\n try {\n await onSubmit({\n tool,\n config: {\n projectPath,\n prompt,\n mode,\n ...(defaultResumeSessionId ? { resumeSessionId: defaultResumeSessionId } : {}),\n },\n });\n setPrompt('');\n setSubmitError(null);\n } catch (e) {\n setSubmitError(e instanceof Error ? e.message : String(e));\n } finally {\n setSubmitting(false);\n }\n }\n\n return (\n <Box flexDirection=\"column\" paddingX={1}>\n <Text bold color={ORANGE}>\u25BC New launch</Text>\n <Box>\n <Text color={field === 'tool' && focused ? ORANGE : DIM}> Tool: </Text>\n {field === 'tool' && focused ? (\n <SelectInput\n items={launchers.map((l) => ({ label: toolLabel(l.tool), value: l.tool }))}\n initialIndex={Math.max(0, launchers.findIndex((l) => l.tool === tool))}\n onSelect={(item) => setTool(item.value)}\n />\n ) : (\n <Text>{toolLabel(tool)}</Text>\n )}\n </Box>\n <Box>\n <Text color={field === 'project' && focused ? ORANGE : DIM}> Project: </Text>\n {field === 'project' && focused ? (\n <TextInput value={projectPath} onChange={setProjectPath} />\n ) : (\n <Text>{projectPath}</Text>\n )}\n </Box>\n <Box>\n <Text color={field === 'mode' && focused ? ORANGE : DIM}> Mode: </Text>\n <Text>{mode === 'interactive' ? '(\u2022) interactive ( ) headless' : '( ) interactive (\u2022) headless'}</Text>\n </Box>\n <Box>\n <Text color={field === 'prompt' && focused ? ORANGE : DIM}> Prompt: </Text>\n {field === 'prompt' && focused ? (\n <TextInput value={prompt} onChange={setPrompt} />\n ) : (\n <Text>{prompt || '(empty)'}</Text>\n )}\n </Box>\n <Box marginTop={1}>\n <Text color={field === 'submit' && focused ? ORANGE : DIM}>\n {canSubmit ? ' [ Submit ]' : ' [ Submit (disabled) ]'}\n {submitting ? ' \u2026submitting' : ''}\n </Text>\n </Box>\n {submitError && <Text color={RED}> \u2717 {submitError}</Text>}\n </Box>\n );\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-DQ3KELXD.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DIM
|
|
3
|
-
} from "./chunk-QJQS6TUN.js";
|
|
4
|
-
|
|
5
|
-
// src/dashboard/panels/shared.tsx
|
|
6
|
-
import { Box, Text } from "ink";
|
|
7
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
function Panel({ title, color, children, width }) {
|
|
9
|
-
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: color, paddingX: 1, width, overflowX: "hidden", children: [
|
|
10
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color, children: title }),
|
|
11
|
-
children
|
|
12
|
-
] });
|
|
13
|
-
}
|
|
14
|
-
function gradientColor(pct) {
|
|
15
|
-
const r = pct <= 0.5 ? Math.round(91 + pct * 2 * (255 - 91)) : 255;
|
|
16
|
-
const g = pct <= 0.5 ? Math.round(158 + pct * 2 * (200 - 158)) : Math.round(200 - (pct - 0.5) * 2 * (200 - 91));
|
|
17
|
-
const b = pct <= 0.5 ? Math.round(245 - pct * 2 * (245 - 91)) : 91;
|
|
18
|
-
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
19
|
-
}
|
|
20
|
-
function HBar({ value, max, width }) {
|
|
21
|
-
if (max === 0) return /* @__PURE__ */ jsx(Text, { color: DIM, children: "\u2591".repeat(width) });
|
|
22
|
-
const filled = Math.round(value / max * width);
|
|
23
|
-
const fillChars = [];
|
|
24
|
-
for (let i = 0; i < Math.min(filled, width); i++) {
|
|
25
|
-
fillChars.push(/* @__PURE__ */ jsx(Text, { color: gradientColor(i / width), children: "\u2588" }, i));
|
|
26
|
-
}
|
|
27
|
-
return /* @__PURE__ */ jsxs(Text, { children: [
|
|
28
|
-
fillChars,
|
|
29
|
-
/* @__PURE__ */ jsx(Text, { color: "#333333", children: "\u2591".repeat(Math.max(width - filled, 0)) })
|
|
30
|
-
] });
|
|
31
|
-
}
|
|
32
|
-
function fit(s, n) {
|
|
33
|
-
return s.length > n ? s.slice(0, n) : s.padEnd(n);
|
|
34
|
-
}
|
|
35
|
-
function formatTokens(n) {
|
|
36
|
-
if (n >= 1e9) return `${(n / 1e9).toFixed(1)}B`;
|
|
37
|
-
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
38
|
-
if (n >= 1e3) return `${(n / 1e3).toFixed(0)}K`;
|
|
39
|
-
return String(n);
|
|
40
|
-
}
|
|
41
|
-
function formatCost(usd) {
|
|
42
|
-
if (usd >= 1e3) return `$${(usd / 1e3).toFixed(1)}K`;
|
|
43
|
-
if (usd >= 1) return `$${usd.toFixed(2)}`;
|
|
44
|
-
if (usd >= 0.01) return `$${usd.toFixed(2)}`;
|
|
45
|
-
return `$${usd.toFixed(3)}`;
|
|
46
|
-
}
|
|
47
|
-
var FRIENDLY_LABELS = {
|
|
48
|
-
fully_achieved: "Fully Achieved",
|
|
49
|
-
mostly_achieved: "Mostly Achieved",
|
|
50
|
-
partially_achieved: "Partially Achieved",
|
|
51
|
-
not_achieved: "Not Achieved",
|
|
52
|
-
unclear_from_transcript: "Unclear",
|
|
53
|
-
misunderstood_request: "Misunderstood Request",
|
|
54
|
-
wrong_approach: "Wrong Approach",
|
|
55
|
-
buggy_code: "Buggy Code",
|
|
56
|
-
user_rejected_action: "User Rejected",
|
|
57
|
-
excessive_changes: "Excessive Changes",
|
|
58
|
-
wrong_file_or_location: "Wrong File/Location",
|
|
59
|
-
slow_or_verbose: "Slow/Verbose",
|
|
60
|
-
tool_failed: "Tool Failed"
|
|
61
|
-
};
|
|
62
|
-
function friendlyLabel(key) {
|
|
63
|
-
return FRIENDLY_LABELS[key] || key.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export {
|
|
67
|
-
Panel,
|
|
68
|
-
HBar,
|
|
69
|
-
fit,
|
|
70
|
-
formatTokens,
|
|
71
|
-
formatCost,
|
|
72
|
-
friendlyLabel
|
|
73
|
-
};
|
|
74
|
-
//# sourceMappingURL=chunk-DQ3KELXD.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/dashboard/panels/shared.tsx"],
|
|
4
|
-
"sourcesContent": ["import React from 'react';\nimport { Box, Text } from 'ink';\nimport { DIM } from '../types.js';\n\nexport function Panel({ title, color, children, width }: {\n title: string; color: string; children: React.ReactNode; width: number;\n}) {\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={color} paddingX={1} width={width} overflowX=\"hidden\">\n <Text bold color={color}>{title}</Text>\n {children}\n </Box>\n );\n}\n\nfunction gradientColor(pct: number): string {\n const r = pct <= 0.5 ? Math.round(91 + pct * 2 * (255 - 91)) : 255;\n const g = pct <= 0.5 ? Math.round(158 + pct * 2 * (200 - 158)) : Math.round(200 - (pct - 0.5) * 2 * (200 - 91));\n const b = pct <= 0.5 ? Math.round(245 - pct * 2 * (245 - 91)) : 91;\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\nexport function HBar({ value, max, width }: { value: number; max: number; width: number }) {\n if (max === 0) return <Text color={DIM}>{'\u2591'.repeat(width)}</Text>;\n const filled = Math.round((value / max) * width);\n const fillChars: React.ReactNode[] = [];\n for (let i = 0; i < Math.min(filled, width); i++) {\n fillChars.push(<Text key={i} color={gradientColor(i / width)}>{'\u2588'}</Text>);\n }\n return (\n <Text>\n {fillChars}\n <Text color=\"#333333\">{'\u2591'.repeat(Math.max(width - filled, 0))}</Text>\n </Text>\n );\n}\n\nexport function fit(s: string, n: number): string {\n return s.length > n ? s.slice(0, n) : s.padEnd(n);\n}\n\nexport function formatTokens(n: number): string {\n if (n >= 1_000_000_000) return `${(n / 1_000_000_000).toFixed(1)}B`;\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(0)}K`;\n return String(n);\n}\n\nexport function formatCost(usd: number): string {\n if (usd >= 1000) return `$${(usd / 1000).toFixed(1)}K`;\n if (usd >= 1) return `$${usd.toFixed(2)}`;\n if (usd >= 0.01) return `$${usd.toFixed(2)}`;\n return `$${usd.toFixed(3)}`;\n}\n\nconst FRIENDLY_LABELS: Record<string, string> = {\n fully_achieved: 'Fully Achieved',\n mostly_achieved: 'Mostly Achieved',\n partially_achieved: 'Partially Achieved',\n not_achieved: 'Not Achieved',\n unclear_from_transcript: 'Unclear',\n misunderstood_request: 'Misunderstood Request',\n wrong_approach: 'Wrong Approach',\n buggy_code: 'Buggy Code',\n user_rejected_action: 'User Rejected',\n excessive_changes: 'Excessive Changes',\n wrong_file_or_location: 'Wrong File/Location',\n slow_or_verbose: 'Slow/Verbose',\n tool_failed: 'Tool Failed',\n};\n\nexport function friendlyLabel(key: string): string {\n return FRIENDLY_LABELS[key] || key.replace(/_/g, ' ').replace(/\\b\\w/g, c => c.toUpperCase());\n}\n"],
|
|
5
|
-
"mappings": ";;;;;AACA,SAAS,KAAK,YAAY;AAOtB,SACE,KADF;AAJG,SAAS,MAAM,EAAE,OAAO,OAAO,UAAU,MAAM,GAEnD;AACD,SACE,qBAAC,OAAI,eAAc,UAAS,aAAY,SAAQ,aAAa,OAAO,UAAU,GAAG,OAAc,WAAU,UACvG;AAAA,wBAAC,QAAK,MAAI,MAAC,OAAe,iBAAM;AAAA,IAC/B;AAAA,KACH;AAEJ;AAEA,SAAS,cAAc,KAAqB;AAC1C,QAAM,IAAI,OAAO,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,GAAG,IAAI;AAC/D,QAAM,IAAI,OAAO,MAAM,KAAK,MAAM,MAAM,MAAM,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM,OAAO,MAAM,OAAO,KAAK,MAAM,GAAG;AAC9G,QAAM,IAAI,OAAO,MAAM,KAAK,MAAM,MAAM,MAAM,KAAK,MAAM,GAAG,IAAI;AAChE,SAAO,IAAI,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC;AAChH;AAEO,SAAS,KAAK,EAAE,OAAO,KAAK,MAAM,GAAkD;AACzF,MAAI,QAAQ,EAAG,QAAO,oBAAC,QAAK,OAAO,KAAM,mBAAI,OAAO,KAAK,GAAE;AAC3D,QAAM,SAAS,KAAK,MAAO,QAAQ,MAAO,KAAK;AAC/C,QAAM,YAA+B,CAAC;AACtC,WAAS,IAAI,GAAG,IAAI,KAAK,IAAI,QAAQ,KAAK,GAAG,KAAK;AAChD,cAAU,KAAK,oBAAC,QAAa,OAAO,cAAc,IAAI,KAAK,GAAI,sBAArC,CAAyC,CAAO;AAAA,EAC5E;AACA,SACE,qBAAC,QACE;AAAA;AAAA,IACD,oBAAC,QAAK,OAAM,WAAW,mBAAI,OAAO,KAAK,IAAI,QAAQ,QAAQ,CAAC,CAAC,GAAE;AAAA,KACjE;AAEJ;AAEO,SAAS,IAAI,GAAW,GAAmB;AAChD,SAAO,EAAE,SAAS,IAAI,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC;AAClD;AAEO,SAAS,aAAa,GAAmB;AAC9C,MAAI,KAAK,IAAe,QAAO,IAAI,IAAI,KAAe,QAAQ,CAAC,CAAC;AAChE,MAAI,KAAK,IAAW,QAAO,IAAI,IAAI,KAAW,QAAQ,CAAC,CAAC;AACxD,MAAI,KAAK,IAAO,QAAO,IAAI,IAAI,KAAO,QAAQ,CAAC,CAAC;AAChD,SAAO,OAAO,CAAC;AACjB;AAEO,SAAS,WAAW,KAAqB;AAC9C,MAAI,OAAO,IAAM,QAAO,KAAK,MAAM,KAAM,QAAQ,CAAC,CAAC;AACnD,MAAI,OAAO,EAAG,QAAO,IAAI,IAAI,QAAQ,CAAC,CAAC;AACvC,MAAI,OAAO,KAAM,QAAO,IAAI,IAAI,QAAQ,CAAC,CAAC;AAC1C,SAAO,IAAI,IAAI,QAAQ,CAAC,CAAC;AAC3B;AAEA,IAAM,kBAA0C;AAAA,EAC9C,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,aAAa;AACf;AAEO,SAAS,cAAc,KAAqB;AACjD,SAAO,gBAAgB,GAAG,KAAK,IAAI,QAAQ,MAAM,GAAG,EAAE,QAAQ,SAAS,OAAK,EAAE,YAAY,CAAC;AAC7F;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-DUJSRBLP.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
announceableEntries,
|
|
3
|
-
parseChangelog
|
|
4
|
-
} from "./chunk-E3BIT53W.js";
|
|
5
|
-
import {
|
|
6
|
-
renderChangelogAnnouncement
|
|
7
|
-
} from "./chunk-QSN77T7C.js";
|
|
8
|
-
import {
|
|
9
|
-
announcements,
|
|
10
|
-
getDb
|
|
11
|
-
} from "./chunk-EI5BHWXA.js";
|
|
12
|
-
|
|
13
|
-
// src/lib/handlers/process-changelog.ts
|
|
14
|
-
import * as fs from "node:fs/promises";
|
|
15
|
-
import * as path from "node:path";
|
|
16
|
-
import { eq } from "drizzle-orm";
|
|
17
|
-
async function findRepoRoot(start) {
|
|
18
|
-
let dir = start;
|
|
19
|
-
for (let i = 0; i < 50; i++) {
|
|
20
|
-
try {
|
|
21
|
-
await fs.stat(path.join(dir, "pnpm-workspace.yaml"));
|
|
22
|
-
return dir;
|
|
23
|
-
} catch {
|
|
24
|
-
}
|
|
25
|
-
const parent = path.dirname(dir);
|
|
26
|
-
if (parent === dir) return null;
|
|
27
|
-
dir = parent;
|
|
28
|
-
}
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
async function readChangelog(explicitPath) {
|
|
32
|
-
if (explicitPath) {
|
|
33
|
-
try {
|
|
34
|
-
return await fs.readFile(explicitPath, "utf-8");
|
|
35
|
-
} catch {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
const root = await findRepoRoot(process.cwd()) ?? process.cwd();
|
|
40
|
-
const p = path.join(root, "CHANGELOG.md");
|
|
41
|
-
try {
|
|
42
|
-
return await fs.readFile(p, "utf-8");
|
|
43
|
-
} catch {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
var PRODUCT_URL = "https://rulemetric.com";
|
|
48
|
-
function renderRow(entry) {
|
|
49
|
-
const date = entry.date ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
50
|
-
const rendered = renderChangelogAnnouncement({
|
|
51
|
-
version: entry.version,
|
|
52
|
-
date,
|
|
53
|
-
sections: entry.sections,
|
|
54
|
-
unsubscribeUrl: "{{unsubscribe_url}}",
|
|
55
|
-
productUrl: PRODUCT_URL
|
|
56
|
-
});
|
|
57
|
-
return {
|
|
58
|
-
version: entry.version,
|
|
59
|
-
releaseDate: date,
|
|
60
|
-
subject: rendered.subject,
|
|
61
|
-
htmlBody: rendered.html,
|
|
62
|
-
textBody: rendered.text,
|
|
63
|
-
sections: entry.sections
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
async function processChangelog(deps = {}) {
|
|
67
|
-
const db = deps.db ?? getDb();
|
|
68
|
-
const logger = deps.logger ?? {
|
|
69
|
-
info: (m) => console.log(m),
|
|
70
|
-
warn: (m) => console.warn(m)
|
|
71
|
-
};
|
|
72
|
-
const md = await readChangelog(deps.changelogPath);
|
|
73
|
-
if (md === null) {
|
|
74
|
-
logger.info("[cron_check_changelog] CHANGELOG.md not found; nothing to do");
|
|
75
|
-
return { createdCount: 0, skippedCount: 0 };
|
|
76
|
-
}
|
|
77
|
-
const parsed = parseChangelog(md);
|
|
78
|
-
const entries = announceableEntries(parsed);
|
|
79
|
-
if (entries.length === 0) {
|
|
80
|
-
logger.info("[cron_check_changelog] No announceable entries; nothing to do");
|
|
81
|
-
return { createdCount: 0, skippedCount: 0 };
|
|
82
|
-
}
|
|
83
|
-
let createdCount = 0;
|
|
84
|
-
let skippedCount = 0;
|
|
85
|
-
for (const entry of entries) {
|
|
86
|
-
const existing = await db.select({ id: announcements.id }).from(announcements).where(eq(announcements.version, entry.version)).limit(1);
|
|
87
|
-
if (existing.length > 0) {
|
|
88
|
-
skippedCount++;
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
const row = renderRow(entry);
|
|
92
|
-
try {
|
|
93
|
-
await db.insert(announcements).values({
|
|
94
|
-
version: row.version,
|
|
95
|
-
releaseDate: row.releaseDate,
|
|
96
|
-
subject: row.subject,
|
|
97
|
-
htmlBody: row.htmlBody,
|
|
98
|
-
textBody: row.textBody,
|
|
99
|
-
sections: row.sections,
|
|
100
|
-
status: "draft"
|
|
101
|
-
});
|
|
102
|
-
createdCount++;
|
|
103
|
-
logger.info(`[cron_check_changelog] Created draft announcement for ${row.version}`);
|
|
104
|
-
} catch (err) {
|
|
105
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
106
|
-
if (/duplicate key|unique/i.test(msg)) {
|
|
107
|
-
skippedCount++;
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
throw err;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
logger.info(
|
|
114
|
-
`[cron_check_changelog] Done: created ${createdCount}, skipped ${skippedCount}`
|
|
115
|
-
);
|
|
116
|
-
return { createdCount, skippedCount };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export {
|
|
120
|
-
processChangelog
|
|
121
|
-
};
|
|
122
|
-
//# sourceMappingURL=chunk-DUJSRBLP.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/handlers/process-changelog.ts"],
|
|
4
|
-
"sourcesContent": ["// Manual handler for `cron_check_changelog`. Reads CHANGELOG.md from the\n// repo root, parses it, and INSERTs one draft `announcements` row per new\n// release version. Idempotent \u2014 running twice in a row creates no\n// duplicates because we check existing rows by `version` (which is also\n// uniquely indexed in the DB).\n//\n// The handler does NOT email anyone and is not scheduled automatically.\n// It only creates `status='draft'` rows. The actual send is a separate\n// manual admin action that enqueues `process_announcement` jobs from the\n// admin UI.\n//\n// Why pure({db, logger}) instead of a worker Task signature: keeps the\n// unit tests trivial (no Graphile helpers to mock) and matches the\n// \"pure handler\" pattern called out in the design brief. The Task\n// adapter in cron-registry.ts wraps this with `wrapCronWithEnvelope`.\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { eq } from 'drizzle-orm';\nimport { announcements, getDb } from '@rulemetric/db';\nimport {\n parseChangelog,\n announceableEntries,\n type ChangelogEntry,\n} from '@rulemetric/core';\nimport { renderChangelogAnnouncement } from '@rulemetric/email';\n\nexport interface ProcessChangelogDeps {\n db?: any;\n logger?: { info: (msg: string) => void; warn: (msg: string) => void };\n /** Override the resolved CHANGELOG path for tests. */\n changelogPath?: string;\n}\n\nexport interface ProcessChangelogResult {\n createdCount: number;\n skippedCount: number;\n}\n\n/**\n * Walk up from `start` looking for a directory that contains\n * `pnpm-workspace.yaml`. Returns null if nothing matches before hitting\n * the filesystem root.\n */\nasync function findRepoRoot(start: string): Promise<string | null> {\n let dir = start;\n // Bound the walk to avoid infinite loops on broken cwds.\n for (let i = 0; i < 50; i++) {\n try {\n await fs.stat(path.join(dir, 'pnpm-workspace.yaml'));\n return dir;\n } catch {\n // not here, keep walking\n }\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n return null;\n}\n\n/**\n * Read CHANGELOG.md. Returns null when the file doesn't exist \u2014 the cron\n * must be a no-op on a fresh checkout (or in test environments where the\n * file may live outside cwd).\n */\nasync function readChangelog(explicitPath: string | undefined): Promise<string | null> {\n if (explicitPath) {\n try {\n return await fs.readFile(explicitPath, 'utf-8');\n } catch {\n return null;\n }\n }\n const root = (await findRepoRoot(process.cwd())) ?? process.cwd();\n const p = path.join(root, 'CHANGELOG.md');\n try {\n return await fs.readFile(p, 'utf-8');\n } catch {\n return null;\n }\n}\n\nconst PRODUCT_URL = 'https://rulemetric.com';\n\n/**\n * Render a draft announcement row from a parsed entry. The\n * `unsubscribeUrl` is left as a literal `{{unsubscribe_url}}` placeholder\n * \u2014 the per-recipient send handler (`process_announcement`) does the\n * actual substitution, so every recipient gets a unique tokenised URL.\n * Same idea for `recipientName`, which is undefined here.\n */\nfunction renderRow(entry: ChangelogEntry): {\n version: string;\n releaseDate: string;\n subject: string;\n htmlBody: string;\n textBody: string;\n sections: ChangelogEntry['sections'];\n} {\n // Entries returned by `announceableEntries` are guaranteed non-Unreleased\n // and have at least one non-empty section, but `date` may still be null\n // when the CHANGELOG heading omitted ` - YYYY-MM-DD`. Fall back to today\n // so we can still insert a draft (admin can correct before sending).\n const date = entry.date ?? new Date().toISOString().slice(0, 10);\n const rendered = renderChangelogAnnouncement({\n version: entry.version,\n date,\n sections: entry.sections,\n unsubscribeUrl: '{{unsubscribe_url}}',\n productUrl: PRODUCT_URL,\n });\n return {\n version: entry.version,\n releaseDate: date,\n subject: rendered.subject,\n htmlBody: rendered.html,\n textBody: rendered.text,\n sections: entry.sections,\n };\n}\n\n/**\n * The cron's actual work. Pure-ish: all side effects routed through the\n * injected `db` and `logger`, both of which default to real\n * implementations so a worker/manual-task wrapper can call this with no\n * arguments.\n */\nexport async function processChangelog(\n deps: ProcessChangelogDeps = {},\n): Promise<ProcessChangelogResult> {\n const db = deps.db ?? getDb();\n const logger = deps.logger ?? {\n info: (m: string) => console.log(m),\n warn: (m: string) => console.warn(m),\n };\n\n const md = await readChangelog(deps.changelogPath);\n if (md === null) {\n logger.info('[cron_check_changelog] CHANGELOG.md not found; nothing to do');\n return { createdCount: 0, skippedCount: 0 };\n }\n\n const parsed = parseChangelog(md);\n const entries = announceableEntries(parsed);\n if (entries.length === 0) {\n logger.info('[cron_check_changelog] No announceable entries; nothing to do');\n return { createdCount: 0, skippedCount: 0 };\n }\n\n let createdCount = 0;\n let skippedCount = 0;\n\n for (const entry of entries) {\n // Dedup by version. The DB also has a UNIQUE constraint on `version`\n // (see announcements schema), so even if two workers raced here the\n // second INSERT would fail loudly \u2014 but we'd rather skip silently.\n const existing = await db\n .select({ id: announcements.id })\n .from(announcements)\n .where(eq(announcements.version, entry.version))\n .limit(1);\n\n if (existing.length > 0) {\n skippedCount++;\n continue;\n }\n\n const row = renderRow(entry);\n try {\n await db.insert(announcements).values({\n version: row.version,\n releaseDate: row.releaseDate,\n subject: row.subject,\n htmlBody: row.htmlBody,\n textBody: row.textBody,\n sections: row.sections,\n status: 'draft',\n });\n createdCount++;\n logger.info(`[cron_check_changelog] Created draft announcement for ${row.version}`);\n } catch (err) {\n // Defensive: a UNIQUE-constraint race still counts as a skip, not a\n // failure. Anything else is unexpected \u2014 re-throw so the worker\n // retries.\n const msg = err instanceof Error ? err.message : String(err);\n if (/duplicate key|unique/i.test(msg)) {\n skippedCount++;\n continue;\n }\n throw err;\n }\n }\n\n logger.info(\n `[cron_check_changelog] Done: created ${createdCount}, skipped ${skippedCount}`,\n );\n return { createdCount, skippedCount };\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;AAgBA,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,SAAS,UAAU;AA0BnB,eAAe,aAAa,OAAuC;AACjE,MAAI,MAAM;AAEV,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,QAAI;AACF,YAAS,QAAU,UAAK,KAAK,qBAAqB,CAAC;AACnD,aAAO;AAAA,IACT,QAAQ;AAAA,IAER;AACA,UAAM,SAAc,aAAQ,GAAG;AAC/B,QAAI,WAAW,IAAK,QAAO;AAC3B,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAOA,eAAe,cAAc,cAA0D;AACrF,MAAI,cAAc;AAChB,QAAI;AACF,aAAO,MAAS,YAAS,cAAc,OAAO;AAAA,IAChD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,OAAQ,MAAM,aAAa,QAAQ,IAAI,CAAC,KAAM,QAAQ,IAAI;AAChE,QAAM,IAAS,UAAK,MAAM,cAAc;AACxC,MAAI;AACF,WAAO,MAAS,YAAS,GAAG,OAAO;AAAA,EACrC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,cAAc;AASpB,SAAS,UAAU,OAOjB;AAKA,QAAM,OAAO,MAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAC/D,QAAM,WAAW,4BAA4B;AAAA,IAC3C,SAAS,MAAM;AAAA,IACf;AAAA,IACA,UAAU,MAAM;AAAA,IAChB,gBAAgB;AAAA,IAChB,YAAY;AAAA,EACd,CAAC;AACD,SAAO;AAAA,IACL,SAAS,MAAM;AAAA,IACf,aAAa;AAAA,IACb,SAAS,SAAS;AAAA,IAClB,UAAU,SAAS;AAAA,IACnB,UAAU,SAAS;AAAA,IACnB,UAAU,MAAM;AAAA,EAClB;AACF;AAQA,eAAsB,iBACpB,OAA6B,CAAC,GACG;AACjC,QAAM,KAAK,KAAK,MAAM,MAAM;AAC5B,QAAM,SAAS,KAAK,UAAU;AAAA,IAC5B,MAAM,CAAC,MAAc,QAAQ,IAAI,CAAC;AAAA,IAClC,MAAM,CAAC,MAAc,QAAQ,KAAK,CAAC;AAAA,EACrC;AAEA,QAAM,KAAK,MAAM,cAAc,KAAK,aAAa;AACjD,MAAI,OAAO,MAAM;AACf,WAAO,KAAK,8DAA8D;AAC1E,WAAO,EAAE,cAAc,GAAG,cAAc,EAAE;AAAA,EAC5C;AAEA,QAAM,SAAS,eAAe,EAAE;AAChC,QAAM,UAAU,oBAAoB,MAAM;AAC1C,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,KAAK,+DAA+D;AAC3E,WAAO,EAAE,cAAc,GAAG,cAAc,EAAE;AAAA,EAC5C;AAEA,MAAI,eAAe;AACnB,MAAI,eAAe;AAEnB,aAAW,SAAS,SAAS;AAI3B,UAAM,WAAW,MAAM,GACpB,OAAO,EAAE,IAAI,cAAc,GAAG,CAAC,EAC/B,KAAK,aAAa,EAClB,MAAM,GAAG,cAAc,SAAS,MAAM,OAAO,CAAC,EAC9C,MAAM,CAAC;AAEV,QAAI,SAAS,SAAS,GAAG;AACvB;AACA;AAAA,IACF;AAEA,UAAM,MAAM,UAAU,KAAK;AAC3B,QAAI;AACF,YAAM,GAAG,OAAO,aAAa,EAAE,OAAO;AAAA,QACpC,SAAS,IAAI;AAAA,QACb,aAAa,IAAI;AAAA,QACjB,SAAS,IAAI;AAAA,QACb,UAAU,IAAI;AAAA,QACd,UAAU,IAAI;AAAA,QACd,UAAU,IAAI;AAAA,QACd,QAAQ;AAAA,MACV,CAAC;AACD;AACA,aAAO,KAAK,yDAAyD,IAAI,OAAO,EAAE;AAAA,IACpF,SAAS,KAAK;AAIZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,UAAI,wBAAwB,KAAK,GAAG,GAAG;AACrC;AACA;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAEA,SAAO;AAAA,IACL,wCAAwC,YAAY,aAAa,YAAY;AAAA,EAC/E;AACA,SAAO,EAAE,cAAc,aAAa;AACtC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|