@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-RQ2TMLKG.js
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
// src/lib/handlers/cron-refresh-skills.ts
|
|
2
|
-
import {
|
|
3
|
-
fetchAllSources,
|
|
4
|
-
TIER_1_SOURCES,
|
|
5
|
-
TIER_2_SOURCES,
|
|
6
|
-
loadDiscoveredSources
|
|
7
|
-
} from "@rulemetric/skills-registry";
|
|
8
|
-
import { writeFile, mkdir } from "node:fs/promises";
|
|
9
|
-
import os from "node:os";
|
|
10
|
-
import path from "node:path";
|
|
11
|
-
var BATCH_SIZE = 200;
|
|
12
|
-
async function postDiscordAlert(webhookUrl, opts) {
|
|
13
|
-
const color = opts.failed > 0 ? 16096779 : 2278750;
|
|
14
|
-
const title = opts.failed > 0 ? "\u26A0\uFE0F Skills registry refresh (partial failures)" : "\u2705 Skills registry refreshed";
|
|
15
|
-
const embed = {
|
|
16
|
-
title,
|
|
17
|
-
color,
|
|
18
|
-
fields: [
|
|
19
|
-
{ name: "Total skills", value: String(opts.total), inline: true },
|
|
20
|
-
{ name: "Sources", value: String(opts.sources), inline: true },
|
|
21
|
-
{ name: "Duration", value: `${Math.round(opts.durationMs / 1e3)}s`, inline: true },
|
|
22
|
-
{ name: "Inserted", value: String(opts.inserted), inline: true },
|
|
23
|
-
{ name: "Updated", value: String(opts.updated), inline: true },
|
|
24
|
-
{ name: "Unchanged", value: String(opts.unchanged), inline: true },
|
|
25
|
-
...opts.failed > 0 ? [{ name: "Failed", value: String(opts.failed), inline: true }] : []
|
|
26
|
-
],
|
|
27
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
28
|
-
};
|
|
29
|
-
try {
|
|
30
|
-
const res = await fetch(webhookUrl, {
|
|
31
|
-
method: "POST",
|
|
32
|
-
headers: { "Content-Type": "application/json" },
|
|
33
|
-
body: JSON.stringify({ embeds: [embed] })
|
|
34
|
-
});
|
|
35
|
-
if (!res.ok) {
|
|
36
|
-
console.error("[cron-refresh-skills] Discord alert failed", res.status);
|
|
37
|
-
}
|
|
38
|
-
} catch (err) {
|
|
39
|
-
console.error("[cron-refresh-skills] Discord alert threw", err);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
var cronRefreshSkills = async (_payload, helpers) => {
|
|
43
|
-
if (!process.env.GITHUB_TOKEN) {
|
|
44
|
-
helpers.logger.warn(
|
|
45
|
-
"GITHUB_TOKEN unset \u2014 skipping skills registry refresh. Without a token the unauthenticated 60 req/hr cap is too tight for ~351 sources; set GITHUB_TOKEN (5000 req/hr) and re-run."
|
|
46
|
-
);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
const startedAt = Date.now();
|
|
50
|
-
const discovered = loadDiscoveredSources();
|
|
51
|
-
const seen = /* @__PURE__ */ new Set();
|
|
52
|
-
const sources = [...TIER_1_SOURCES, ...TIER_2_SOURCES, ...discovered].filter((s) => {
|
|
53
|
-
if (seen.has(s.repo)) return false;
|
|
54
|
-
seen.add(s.repo);
|
|
55
|
-
return true;
|
|
56
|
-
});
|
|
57
|
-
helpers.logger.info(`Fetching from ${sources.length} sources (T1=${TIER_1_SOURCES.length}, T2=${TIER_2_SOURCES.length}, discovered=${discovered.length})`);
|
|
58
|
-
const result = await fetchAllSources(sources, {
|
|
59
|
-
onProgress: (source, count) => helpers.logger.info(`fetched ${count} from ${source}`)
|
|
60
|
-
});
|
|
61
|
-
const configDir = path.join(os.homedir(), ".config", "rulemetric");
|
|
62
|
-
await mkdir(configDir, { recursive: true });
|
|
63
|
-
const outPath = path.join(configDir, "skills-registry.json");
|
|
64
|
-
await writeFile(
|
|
65
|
-
outPath,
|
|
66
|
-
JSON.stringify({ generatedAt: (/* @__PURE__ */ new Date()).toISOString(), skills: result.entries }, null, 2)
|
|
67
|
-
);
|
|
68
|
-
helpers.logger.info(`Refreshed disk registry: ${result.entries.length} skills`);
|
|
69
|
-
const apiUrl = process.env.RULEMETRIC_API_URL;
|
|
70
|
-
const botToken = process.env.RULEMETRIC_REGISTRY_BOT_TOKEN;
|
|
71
|
-
if (!apiUrl || !botToken) {
|
|
72
|
-
helpers.logger.warn(
|
|
73
|
-
"RULEMETRIC_API_URL or RULEMETRIC_REGISTRY_BOT_TOKEN unset; skipping DB sync"
|
|
74
|
-
);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
let totalInserted = 0;
|
|
78
|
-
let totalUpdated = 0;
|
|
79
|
-
let totalUnchanged = 0;
|
|
80
|
-
let totalFailed = 0;
|
|
81
|
-
for (let i = 0; i < result.entries.length; i += BATCH_SIZE) {
|
|
82
|
-
const batch = result.entries.slice(i, i + BATCH_SIZE).map((s) => ({
|
|
83
|
-
id: s.id,
|
|
84
|
-
name: s.name,
|
|
85
|
-
description: s.description,
|
|
86
|
-
content: s.content,
|
|
87
|
-
source: s.source,
|
|
88
|
-
tags: s.tags,
|
|
89
|
-
category: s.category,
|
|
90
|
-
updatedAt: s.updatedAt,
|
|
91
|
-
sourceUpdatedAt: s.sourceUpdatedAt,
|
|
92
|
-
// source file's last git-commit date (catalog recency sort)
|
|
93
|
-
popularity: s.popularity
|
|
94
|
-
}));
|
|
95
|
-
try {
|
|
96
|
-
const res = await fetch(`${apiUrl}/api/skills/sync-public`, {
|
|
97
|
-
method: "POST",
|
|
98
|
-
headers: {
|
|
99
|
-
"content-type": "application/json",
|
|
100
|
-
authorization: `Bearer ${botToken}`
|
|
101
|
-
},
|
|
102
|
-
body: JSON.stringify({ skills: batch })
|
|
103
|
-
});
|
|
104
|
-
if (!res.ok) {
|
|
105
|
-
helpers.logger.warn(`Batch ${i / BATCH_SIZE} failed: ${res.status} ${await res.text()}`);
|
|
106
|
-
totalFailed += batch.length;
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
const json = await res.json();
|
|
110
|
-
totalInserted += json.inserted;
|
|
111
|
-
totalUpdated += json.updated;
|
|
112
|
-
totalUnchanged += json.unchanged;
|
|
113
|
-
if (json.skipped) {
|
|
114
|
-
helpers.logger.warn(`Batch ${i / BATCH_SIZE}: ${json.skipped} skills skipped (invalid)`);
|
|
115
|
-
totalFailed += json.skipped;
|
|
116
|
-
}
|
|
117
|
-
} catch (err) {
|
|
118
|
-
helpers.logger.warn(`Batch ${i / BATCH_SIZE} threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
119
|
-
totalFailed += batch.length;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
helpers.logger.info(
|
|
123
|
-
`DB sync: inserted=${totalInserted} updated=${totalUpdated} unchanged=${totalUnchanged} failed=${totalFailed}`
|
|
124
|
-
);
|
|
125
|
-
const discordUrl = process.env.DISCORD_WEBHOOK_URL;
|
|
126
|
-
if (discordUrl) {
|
|
127
|
-
await postDiscordAlert(discordUrl, {
|
|
128
|
-
total: result.entries.length,
|
|
129
|
-
inserted: totalInserted,
|
|
130
|
-
updated: totalUpdated,
|
|
131
|
-
unchanged: totalUnchanged,
|
|
132
|
-
failed: totalFailed,
|
|
133
|
-
sources: sources.length,
|
|
134
|
-
durationMs: Date.now() - startedAt
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
export {
|
|
140
|
-
cronRefreshSkills
|
|
141
|
-
};
|
|
142
|
-
//# sourceMappingURL=chunk-RQ2TMLKG.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/handlers/cron-refresh-skills.ts"],
|
|
4
|
-
"sourcesContent": ["import type { JobHelpers } from '../job-helpers.js';\nimport {\n fetchAllSources,\n TIER_1_SOURCES,\n TIER_2_SOURCES,\n loadDiscoveredSources,\n} from '@rulemetric/skills-registry';\nimport { writeFile, mkdir } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nconst BATCH_SIZE = 200;\n\nasync function postDiscordAlert(\n webhookUrl: string,\n opts: {\n total: number;\n inserted: number;\n updated: number;\n unchanged: number;\n failed: number;\n sources: number;\n durationMs: number;\n },\n): Promise<void> {\n const color = opts.failed > 0 ? 0xf59e0b : 0x22c55e;\n const title = opts.failed > 0 ? '\u26A0\uFE0F Skills registry refresh (partial failures)' : '\u2705 Skills registry refreshed';\n const embed = {\n title,\n color,\n fields: [\n { name: 'Total skills', value: String(opts.total), inline: true },\n { name: 'Sources', value: String(opts.sources), inline: true },\n { name: 'Duration', value: `${Math.round(opts.durationMs / 1000)}s`, inline: true },\n { name: 'Inserted', value: String(opts.inserted), inline: true },\n { name: 'Updated', value: String(opts.updated), inline: true },\n { name: 'Unchanged', value: String(opts.unchanged), inline: true },\n ...(opts.failed > 0 ? [{ name: 'Failed', value: String(opts.failed), inline: true }] : []),\n ],\n timestamp: new Date().toISOString(),\n };\n try {\n const res = await fetch(webhookUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ embeds: [embed] }),\n });\n if (!res.ok) {\n console.error('[cron-refresh-skills] Discord alert failed', res.status);\n }\n } catch (err) {\n console.error('[cron-refresh-skills] Discord alert threw', err);\n }\n}\n\nexport const cronRefreshSkills = async (_payload: unknown, helpers: JobHelpers): Promise<void> => {\n // Fail fast when there's no GITHUB_TOKEN. The unauthenticated GitHub API\n // gives 60 req/hr; this cron does 2 calls per source \u00D7 ~351 sources = 702\n // calls. Without a token we'd exhaust the cap on the first batch, hit\n // Octokit's throttle plugin, and (pre-fix) sleep up to 57 min per source\n // waiting for the rate window to reset \u2014 all while holding a graphile\n // concurrency slot. The bounded-retry change in github-fetcher.ts makes\n // that survivable, but we'd still rather skip cleanly than crawl 702 calls\n // just to skip them all individually. Set GITHUB_TOKEN in the worker env\n // (e.g. via launchctl setenv) to enable.\n if (!process.env.GITHUB_TOKEN) {\n helpers.logger.warn(\n 'GITHUB_TOKEN unset \u2014 skipping skills registry refresh. Without a token the unauthenticated 60 req/hr cap is too tight for ~351 sources; set GITHUB_TOKEN (5000 req/hr) and re-run.',\n );\n return;\n }\n\n const startedAt = Date.now();\n\n // Combine all source tiers + the discovered set so the cron's coverage\n // matches the bundled registry. De-dupe by repo to avoid double-fetching\n // when discovered overlaps with explicit sources.\n const discovered = loadDiscoveredSources();\n const seen = new Set<string>();\n const sources = [...TIER_1_SOURCES, ...TIER_2_SOURCES, ...discovered].filter((s) => {\n if (seen.has(s.repo)) return false;\n seen.add(s.repo);\n return true;\n });\n helpers.logger.info(`Fetching from ${sources.length} sources (T1=${TIER_1_SOURCES.length}, T2=${TIER_2_SOURCES.length}, discovered=${discovered.length})`);\n\n const result = await fetchAllSources(sources, {\n onProgress: (source, count) => helpers.logger.info(`fetched ${count} from ${source}`),\n });\n\n // Persist JSON-on-disk view (legacy / fast-path consumers).\n const configDir = path.join(os.homedir(), '.config', 'rulemetric');\n await mkdir(configDir, { recursive: true });\n const outPath = path.join(configDir, 'skills-registry.json');\n await writeFile(\n outPath,\n JSON.stringify({ generatedAt: new Date().toISOString(), skills: result.entries }, null, 2),\n );\n helpers.logger.info(`Refreshed disk registry: ${result.entries.length} skills`);\n\n // Mirror to DB as scope='public' instructions rows so the catalog,\n // recommendations, and suggestion-cron all see one source of truth.\n const apiUrl = process.env.RULEMETRIC_API_URL;\n const botToken = process.env.RULEMETRIC_REGISTRY_BOT_TOKEN;\n if (!apiUrl || !botToken) {\n helpers.logger.warn(\n 'RULEMETRIC_API_URL or RULEMETRIC_REGISTRY_BOT_TOKEN unset; skipping DB sync',\n );\n return;\n }\n\n let totalInserted = 0;\n let totalUpdated = 0;\n let totalUnchanged = 0;\n let totalFailed = 0;\n\n for (let i = 0; i < result.entries.length; i += BATCH_SIZE) {\n const batch = result.entries.slice(i, i + BATCH_SIZE).map((s) => ({\n id: s.id,\n name: s.name,\n description: s.description,\n content: s.content,\n source: s.source,\n tags: s.tags,\n category: s.category,\n updatedAt: s.updatedAt,\n sourceUpdatedAt: s.sourceUpdatedAt, // source file's last git-commit date (catalog recency sort)\n popularity: s.popularity,\n }));\n try {\n const res = await fetch(`${apiUrl}/api/skills/sync-public`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${botToken}`,\n },\n body: JSON.stringify({ skills: batch }),\n });\n if (!res.ok) {\n helpers.logger.warn(`Batch ${i / BATCH_SIZE} failed: ${res.status} ${await res.text()}`);\n totalFailed += batch.length;\n continue;\n }\n const json = (await res.json()) as {\n inserted: number;\n updated: number;\n unchanged: number;\n skipped?: number;\n };\n totalInserted += json.inserted;\n totalUpdated += json.updated;\n totalUnchanged += json.unchanged;\n if (json.skipped) {\n helpers.logger.warn(`Batch ${i / BATCH_SIZE}: ${json.skipped} skills skipped (invalid)`);\n totalFailed += json.skipped;\n }\n } catch (err) {\n helpers.logger.warn(`Batch ${i / BATCH_SIZE} threw: ${err instanceof Error ? err.message : String(err)}`);\n totalFailed += batch.length;\n }\n }\n\n helpers.logger.info(\n `DB sync: inserted=${totalInserted} updated=${totalUpdated} unchanged=${totalUnchanged} failed=${totalFailed}`,\n );\n\n const discordUrl = process.env.DISCORD_WEBHOOK_URL;\n if (discordUrl) {\n await postDiscordAlert(discordUrl, {\n total: result.entries.length,\n inserted: totalInserted,\n updated: totalUpdated,\n unchanged: totalUnchanged,\n failed: totalFailed,\n sources: sources.length,\n durationMs: Date.now() - startedAt,\n });\n }\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-SO3T35U7.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
// src/lib/instruction-snapshot.ts
|
|
2
|
-
import { createHash } from "node:crypto";
|
|
3
|
-
import { readdirSync, readFileSync } from "node:fs";
|
|
4
|
-
import { join, relative } from "node:path";
|
|
5
|
-
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
6
|
-
"node_modules",
|
|
7
|
-
".git",
|
|
8
|
-
"dist",
|
|
9
|
-
"build",
|
|
10
|
-
"out",
|
|
11
|
-
".next",
|
|
12
|
-
"coverage",
|
|
13
|
-
".turbo",
|
|
14
|
-
"vendor",
|
|
15
|
-
".venv"
|
|
16
|
-
]);
|
|
17
|
-
var MAX_FILES = 50;
|
|
18
|
-
var MAX_DEPTH = 8;
|
|
19
|
-
var sha256 = (s) => createHash("sha256").update(s).digest("hex");
|
|
20
|
-
function findClaudeMdFiles(root) {
|
|
21
|
-
const found = [];
|
|
22
|
-
const walk = (dir, depth) => {
|
|
23
|
-
if (found.length >= MAX_FILES || depth > MAX_DEPTH) return;
|
|
24
|
-
let entries;
|
|
25
|
-
try {
|
|
26
|
-
entries = readdirSync(dir, { withFileTypes: true });
|
|
27
|
-
} catch {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
for (const entry of entries) {
|
|
31
|
-
if (found.length >= MAX_FILES) return;
|
|
32
|
-
if (entry.isDirectory()) {
|
|
33
|
-
if (SKIP_DIRS.has(entry.name) || entry.name.startsWith(".")) continue;
|
|
34
|
-
walk(join(dir, entry.name), depth + 1);
|
|
35
|
-
} else if (entry.isFile() && entry.name === "CLAUDE.md") {
|
|
36
|
-
found.push(join(dir, entry.name));
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
walk(root, 0);
|
|
41
|
-
return found.sort();
|
|
42
|
-
}
|
|
43
|
-
function buildInstructionSnapshot(projectDir) {
|
|
44
|
-
const context_items = [];
|
|
45
|
-
const injected_instructions = [];
|
|
46
|
-
for (const filePath of findClaudeMdFiles(projectDir)) {
|
|
47
|
-
let body;
|
|
48
|
-
try {
|
|
49
|
-
body = readFileSync(filePath, "utf-8");
|
|
50
|
-
} catch {
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
if (!body.trim()) continue;
|
|
54
|
-
const instruction_index = injected_instructions.length;
|
|
55
|
-
injected_instructions.push(body);
|
|
56
|
-
context_items.push({
|
|
57
|
-
type: "claude_md",
|
|
58
|
-
name: relative(projectDir, filePath) || "CLAUDE.md",
|
|
59
|
-
content_hash: sha256(body),
|
|
60
|
-
char_count: body.length,
|
|
61
|
-
estimated_tokens: Math.ceil(body.length / 4),
|
|
62
|
-
instruction_index
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
if (context_items.length === 0) return null;
|
|
66
|
-
return {
|
|
67
|
-
provider: "claude_code",
|
|
68
|
-
model: "unknown",
|
|
69
|
-
system_prompt: "",
|
|
70
|
-
system_hash: sha256(""),
|
|
71
|
-
injected_instructions,
|
|
72
|
-
context_items,
|
|
73
|
-
metadata: { source: "hook_instruction_snapshot" }
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export {
|
|
78
|
-
buildInstructionSnapshot
|
|
79
|
-
};
|
|
80
|
-
//# sourceMappingURL=chunk-SO3T35U7.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/instruction-snapshot.ts"],
|
|
4
|
-
"sourcesContent": ["import { createHash } from 'node:crypto';\nimport { readdirSync, readFileSync } from 'node:fs';\nimport { join, relative } from 'node:path';\n\n/**\n * A synthetic instruction snapshot for the hooks-first (zero-proxy) capture path.\n *\n * The proxy captures the *rendered* system prompt and classifies it into\n * `context_items` that `link-instructions` matches on. Hooks-only sessions never\n * hit the proxy, so this reconstructs an equivalent snapshot from the on-disk\n * instruction files (CLAUDE.md) \u2014 enough for `link-instructions` to auto-create\n * and link `claude_md` instructions.\n *\n * LIMITATION (by design): this hashes the RAW file body, whereas the proxy hashes\n * the rendered/normalized system-prompt text, so hook-sourced and proxy-sourced\n * instructions live in different content_hash namespaces and will NOT merge. It is\n * also STATIC \u2014 it cannot see runtime-injected context (skills invoked mid-session,\n * @-imports resolved on demand, subagent prompts). It is a partial, best-effort\n * bridge for zero-proxy users, not proxy parity.\n */\nexport interface InstructionContextItem {\n type: 'claude_md';\n name: string;\n content_hash: string;\n char_count: number;\n estimated_tokens: number;\n instruction_index: number;\n}\n\nexport interface InstructionSnapshot {\n provider: string;\n model: string;\n system_prompt: string;\n system_hash: string;\n injected_instructions: string[];\n context_items: InstructionContextItem[];\n metadata: Record<string, unknown>;\n}\n\nconst SKIP_DIRS = new Set([\n 'node_modules', '.git', 'dist', 'build', 'out', '.next', 'coverage', '.turbo', 'vendor', '.venv',\n]);\nconst MAX_FILES = 50;\nconst MAX_DEPTH = 8;\n\nconst sha256 = (s: string) => createHash('sha256').update(s).digest('hex');\n\n/** Recursively locate CLAUDE.md files, skipping heavy/hidden dirs. */\nfunction findClaudeMdFiles(root: string): string[] {\n const found: string[] = [];\n const walk = (dir: string, depth: number): void => {\n if (found.length >= MAX_FILES || depth > MAX_DEPTH) return;\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (found.length >= MAX_FILES) return;\n if (entry.isDirectory()) {\n if (SKIP_DIRS.has(entry.name) || entry.name.startsWith('.')) continue;\n walk(join(dir, entry.name), depth + 1);\n } else if (entry.isFile() && entry.name === 'CLAUDE.md') {\n found.push(join(dir, entry.name));\n }\n }\n };\n walk(root, 0);\n return found.sort();\n}\n\n/**\n * Build a synthetic context snapshot from a project's on-disk instruction files,\n * ready to `POST /api/sessions/:id/context-snapshots`. Returns null when the\n * project has no non-empty instruction files (nothing to link).\n */\nexport function buildInstructionSnapshot(projectDir: string): InstructionSnapshot | null {\n const context_items: InstructionContextItem[] = [];\n const injected_instructions: string[] = [];\n\n for (const filePath of findClaudeMdFiles(projectDir)) {\n let body: string;\n try {\n body = readFileSync(filePath, 'utf-8');\n } catch {\n continue;\n }\n if (!body.trim()) continue;\n const instruction_index = injected_instructions.length;\n injected_instructions.push(body);\n context_items.push({\n type: 'claude_md',\n name: relative(projectDir, filePath) || 'CLAUDE.md',\n content_hash: sha256(body),\n char_count: body.length,\n estimated_tokens: Math.ceil(body.length / 4),\n instruction_index,\n });\n }\n\n if (context_items.length === 0) return null;\n\n return {\n provider: 'claude_code',\n model: 'unknown',\n system_prompt: '',\n system_hash: sha256(''),\n injected_instructions,\n context_items,\n metadata: { source: 'hook_instruction_snapshot' },\n };\n}\n"],
|
|
5
|
-
"mappings": ";AAAA,SAAS,kBAAkB;AAC3B,SAAS,aAAa,oBAAoB;AAC1C,SAAS,MAAM,gBAAgB;AAqC/B,IAAM,YAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EAAgB;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAO;AAAA,EAAS;AAAA,EAAY;AAAA,EAAU;AAAA,EAAU;AAC3F,CAAC;AACD,IAAM,YAAY;AAClB,IAAM,YAAY;AAElB,IAAM,SAAS,CAAC,MAAc,WAAW,QAAQ,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK;AAGzE,SAAS,kBAAkB,MAAwB;AACjD,QAAM,QAAkB,CAAC;AACzB,QAAM,OAAO,CAAC,KAAa,UAAwB;AACjD,QAAI,MAAM,UAAU,aAAa,QAAQ,UAAW;AACpD,QAAI;AACJ,QAAI;AACF,gBAAU,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAAA,IACpD,QAAQ;AACN;AAAA,IACF;AACA,eAAW,SAAS,SAAS;AAC3B,UAAI,MAAM,UAAU,UAAW;AAC/B,UAAI,MAAM,YAAY,GAAG;AACvB,YAAI,UAAU,IAAI,MAAM,IAAI,KAAK,MAAM,KAAK,WAAW,GAAG,EAAG;AAC7D,aAAK,KAAK,KAAK,MAAM,IAAI,GAAG,QAAQ,CAAC;AAAA,MACvC,WAAW,MAAM,OAAO,KAAK,MAAM,SAAS,aAAa;AACvD,cAAM,KAAK,KAAK,KAAK,MAAM,IAAI,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AACA,OAAK,MAAM,CAAC;AACZ,SAAO,MAAM,KAAK;AACpB;AAOO,SAAS,yBAAyB,YAAgD;AACvF,QAAM,gBAA0C,CAAC;AACjD,QAAM,wBAAkC,CAAC;AAEzC,aAAW,YAAY,kBAAkB,UAAU,GAAG;AACpD,QAAI;AACJ,QAAI;AACF,aAAO,aAAa,UAAU,OAAO;AAAA,IACvC,QAAQ;AACN;AAAA,IACF;AACA,QAAI,CAAC,KAAK,KAAK,EAAG;AAClB,UAAM,oBAAoB,sBAAsB;AAChD,0BAAsB,KAAK,IAAI;AAC/B,kBAAc,KAAK;AAAA,MACjB,MAAM;AAAA,MACN,MAAM,SAAS,YAAY,QAAQ,KAAK;AAAA,MACxC,cAAc,OAAO,IAAI;AAAA,MACzB,YAAY,KAAK;AAAA,MACjB,kBAAkB,KAAK,KAAK,KAAK,SAAS,CAAC;AAAA,MAC3C;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,cAAc,WAAW,EAAG,QAAO;AAEvC,SAAO;AAAA,IACL,UAAU;AAAA,IACV,OAAO;AAAA,IACP,eAAe;AAAA,IACf,aAAa,OAAO,EAAE;AAAA,IACtB;AAAA,IACA;AAAA,IACA,UAAU,EAAE,QAAQ,4BAA4B;AAAA,EAClD;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-UKMLICWS.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DEFAULT_API_URL
|
|
3
|
-
} from "./chunk-ZUJBM6HE.js";
|
|
4
|
-
|
|
5
|
-
// src/dashboard/launcher/api.ts
|
|
6
|
-
function apiUrl() {
|
|
7
|
-
return process.env.RULEMETRIC_API_URL ?? DEFAULT_API_URL;
|
|
8
|
-
}
|
|
9
|
-
function authToken() {
|
|
10
|
-
const t = process.env.RULEMETRIC_API_KEY ?? process.env.RULEMETRIC_ACCESS_TOKEN;
|
|
11
|
-
if (!t) throw new Error("not signed in \u2014 run `rulemetric auth login`");
|
|
12
|
-
return t;
|
|
13
|
-
}
|
|
14
|
-
async function request(path, init) {
|
|
15
|
-
const resp = await fetch(`${apiUrl()}${path}`, {
|
|
16
|
-
...init,
|
|
17
|
-
headers: {
|
|
18
|
-
Authorization: `Bearer ${authToken()}`,
|
|
19
|
-
"Content-Type": "application/json",
|
|
20
|
-
...init?.headers ?? {}
|
|
21
|
-
},
|
|
22
|
-
signal: AbortSignal.timeout(1e4)
|
|
23
|
-
});
|
|
24
|
-
if (!resp.ok) {
|
|
25
|
-
throw new Error(`${resp.status} ${resp.statusText}`);
|
|
26
|
-
}
|
|
27
|
-
return await resp.json();
|
|
28
|
-
}
|
|
29
|
-
function fetchLaunchJobs({ limit }) {
|
|
30
|
-
return request(`/api/launch-jobs?limit=${limit}`);
|
|
31
|
-
}
|
|
32
|
-
function createLaunchJob(payload) {
|
|
33
|
-
return request("/api/launch-jobs", {
|
|
34
|
-
method: "POST",
|
|
35
|
-
body: JSON.stringify(payload)
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
function cancelLaunchJob(id) {
|
|
39
|
-
return request(`/api/launch-jobs/${id}/cancel`, { method: "POST" });
|
|
40
|
-
}
|
|
41
|
-
function listLaunchers() {
|
|
42
|
-
return request("/api/launchers");
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export {
|
|
46
|
-
fetchLaunchJobs,
|
|
47
|
-
createLaunchJob,
|
|
48
|
-
cancelLaunchJob,
|
|
49
|
-
listLaunchers
|
|
50
|
-
};
|
|
51
|
-
//# sourceMappingURL=chunk-UKMLICWS.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/dashboard/launcher/api.ts"],
|
|
4
|
-
"sourcesContent": ["import { DEFAULT_API_URL } from '../../lib/api-client.js';\nimport type { LaunchJob, AvailableLauncher, CreateLaunchPayload } from './types.js';\n\nfunction apiUrl(): string {\n return process.env.RULEMETRIC_API_URL ?? DEFAULT_API_URL;\n}\n\nfunction authToken(): string {\n const t = process.env.RULEMETRIC_API_KEY ?? process.env.RULEMETRIC_ACCESS_TOKEN;\n if (!t) throw new Error('not signed in \u2014 run `rulemetric auth login`');\n return t;\n}\n\nasync function request<T>(path: string, init?: RequestInit): Promise<T> {\n const resp = await fetch(`${apiUrl()}${path}`, {\n ...init,\n headers: {\n Authorization: `Bearer ${authToken()}`,\n 'Content-Type': 'application/json',\n ...(init?.headers ?? {}),\n },\n signal: AbortSignal.timeout(10_000),\n });\n if (!resp.ok) {\n throw new Error(`${resp.status} ${resp.statusText}`);\n }\n return (await resp.json()) as T;\n}\n\nexport function fetchLaunchJobs({ limit }: { limit: number }): Promise<LaunchJob[]> {\n return request<LaunchJob[]>(`/api/launch-jobs?limit=${limit}`);\n}\n\nexport function createLaunchJob(payload: CreateLaunchPayload): Promise<LaunchJob> {\n return request<LaunchJob>('/api/launch-jobs', {\n method: 'POST',\n body: JSON.stringify(payload),\n });\n}\n\nexport function cancelLaunchJob(id: string): Promise<{ ok: true }> {\n return request<{ ok: true }>(`/api/launch-jobs/${id}/cancel`, { method: 'POST' });\n}\n\nexport function listLaunchers(): Promise<AvailableLauncher[]> {\n return request<AvailableLauncher[]>('/api/launchers');\n}\n"],
|
|
5
|
-
"mappings": ";;;;;AAGA,SAAS,SAAiB;AACxB,SAAO,QAAQ,IAAI,sBAAsB;AAC3C;AAEA,SAAS,YAAoB;AAC3B,QAAM,IAAI,QAAQ,IAAI,sBAAsB,QAAQ,IAAI;AACxD,MAAI,CAAC,EAAG,OAAM,IAAI,MAAM,kDAA6C;AACrE,SAAO;AACT;AAEA,eAAe,QAAW,MAAc,MAAgC;AACtE,QAAM,OAAO,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI;AAAA,IAC7C,GAAG;AAAA,IACH,SAAS;AAAA,MACP,eAAe,UAAU,UAAU,CAAC;AAAA,MACpC,gBAAgB;AAAA,MAChB,GAAI,MAAM,WAAW,CAAC;AAAA,IACxB;AAAA,IACA,QAAQ,YAAY,QAAQ,GAAM;AAAA,EACpC,CAAC;AACD,MAAI,CAAC,KAAK,IAAI;AACZ,UAAM,IAAI,MAAM,GAAG,KAAK,MAAM,IAAI,KAAK,UAAU,EAAE;AAAA,EACrD;AACA,SAAQ,MAAM,KAAK,KAAK;AAC1B;AAEO,SAAS,gBAAgB,EAAE,MAAM,GAA4C;AAClF,SAAO,QAAqB,0BAA0B,KAAK,EAAE;AAC/D;AAEO,SAAS,gBAAgB,SAAkD;AAChF,SAAO,QAAmB,oBAAoB;AAAA,IAC5C,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU,OAAO;AAAA,EAC9B,CAAC;AACH;AAEO,SAAS,gBAAgB,IAAmC;AACjE,SAAO,QAAsB,oBAAoB,EAAE,WAAW,EAAE,QAAQ,OAAO,CAAC;AAClF;AAEO,SAAS,gBAA8C;AAC5D,SAAO,QAA6B,gBAAgB;AACtD;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/chunk-VA5FFOS7.js
DELETED
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AT_A_GLANCE_PROMPT,
|
|
3
|
-
FACET_GENERATION_PROMPT,
|
|
4
|
-
RECOMMENDATION_PROMPTS
|
|
5
|
-
} from "./chunk-XZXS2W24.js";
|
|
6
|
-
import {
|
|
7
|
-
detectLlmBackend,
|
|
8
|
-
runLlmPrompt,
|
|
9
|
-
runToolPrompt
|
|
10
|
-
} from "./chunk-DIQUV5FR.js";
|
|
11
|
-
import {
|
|
12
|
-
PermanentJobError
|
|
13
|
-
} from "./chunk-DGHWRQXL.js";
|
|
14
|
-
import {
|
|
15
|
-
apiGet,
|
|
16
|
-
apiPatch,
|
|
17
|
-
apiPost
|
|
18
|
-
} from "./chunk-ZUJBM6HE.js";
|
|
19
|
-
|
|
20
|
-
// src/lib/handlers/process-insights.ts
|
|
21
|
-
async function processInsights(payload, helpers) {
|
|
22
|
-
const { mirrorId, projectPath, projectId, config } = payload;
|
|
23
|
-
const log = (msg) => helpers.logger.info(msg);
|
|
24
|
-
if (config?.sessionId) {
|
|
25
|
-
return processSessionAnalysisInline({ mirrorId, sessionId: config.sessionId }, log);
|
|
26
|
-
}
|
|
27
|
-
log(`Processing insights job ${mirrorId}...`);
|
|
28
|
-
await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {
|
|
29
|
-
status: "running",
|
|
30
|
-
progress: { step: "reading_data" }
|
|
31
|
-
});
|
|
32
|
-
try {
|
|
33
|
-
const { repaired } = await apiPost(
|
|
34
|
-
"/api/sessions/repair-analyzed-at",
|
|
35
|
-
{}
|
|
36
|
-
);
|
|
37
|
-
if (repaired > 0) {
|
|
38
|
-
log(` Repaired analyzed_at on ${repaired} orphan session(s).`);
|
|
39
|
-
}
|
|
40
|
-
} catch (repairErr) {
|
|
41
|
-
log(` Warning: analyzed_at repair failed: ${repairErr instanceof Error ? repairErr.message : String(repairErr)}`);
|
|
42
|
-
}
|
|
43
|
-
const data = await buildDataSummaryFromApi(projectPath, projectId);
|
|
44
|
-
if (!data) {
|
|
45
|
-
throw new PermanentJobError(
|
|
46
|
-
"No session data found \u2014 ensure sessions are captured and enriched."
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
log(` Found ${data.stats.sessions} sessions, generating recommendations...`);
|
|
50
|
-
const FACET_BATCH_SIZE = 20;
|
|
51
|
-
const FACET_HARD_CAP = 200;
|
|
52
|
-
if (detectLlmBackend() !== "none") {
|
|
53
|
-
let totalFaceted = 0;
|
|
54
|
-
try {
|
|
55
|
-
while (totalFaceted < FACET_HARD_CAP) {
|
|
56
|
-
const unfaceted = await apiGet(
|
|
57
|
-
`/api/sessions?hasAnalysis=false&limit=${FACET_BATCH_SIZE}`
|
|
58
|
-
);
|
|
59
|
-
if (unfaceted.length === 0) break;
|
|
60
|
-
log(` Generating facets for ${unfaceted.length} un-analyzed sessions (drained ${totalFaceted} so far)...`);
|
|
61
|
-
for (const session of unfaceted) {
|
|
62
|
-
if (totalFaceted >= FACET_HARD_CAP) break;
|
|
63
|
-
try {
|
|
64
|
-
const events = await apiGet(
|
|
65
|
-
`/api/sessions/${session.id}/events?limit=100`
|
|
66
|
-
);
|
|
67
|
-
if (events.length < 2) {
|
|
68
|
-
totalFaceted++;
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
const eventSummary = events.filter((e) => e.eventType === "user_message" || e.eventType === "human").map((e) => e.content?.slice(0, 200) ?? "").filter(Boolean).join("\n---\n");
|
|
72
|
-
if (!eventSummary) {
|
|
73
|
-
totalFaceted++;
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
const facets = await runLlmPrompt(FACET_GENERATION_PROMPT, eventSummary, 4096);
|
|
77
|
-
if (facets) {
|
|
78
|
-
const userMessageCount = events.filter(
|
|
79
|
-
(e) => e.eventType === "user_message" || e.eventType === "human"
|
|
80
|
-
).length;
|
|
81
|
-
await apiPatch(`/api/sessions/${session.id}/enrich`, {
|
|
82
|
-
analysis: { source: "generated_facets", ...facets },
|
|
83
|
-
analyzedEventCount: events.length,
|
|
84
|
-
analyzedTurnCount: userMessageCount
|
|
85
|
-
});
|
|
86
|
-
log(` Generated facets for session ${session.id} (${session.tool})`);
|
|
87
|
-
}
|
|
88
|
-
totalFaceted++;
|
|
89
|
-
} catch (sessionErr) {
|
|
90
|
-
log(` Failed to generate facets for session ${session.id}: ${sessionErr instanceof Error ? sessionErr.message : String(sessionErr)}`);
|
|
91
|
-
totalFaceted++;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
if (unfaceted.length < FACET_BATCH_SIZE) break;
|
|
95
|
-
}
|
|
96
|
-
} catch (facetErr) {
|
|
97
|
-
log(` Warning: facet generation failed after ${totalFaceted} sessions: ${facetErr instanceof Error ? facetErr.message : String(facetErr)}`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
const recommendations = {};
|
|
101
|
-
const totalPrompts = RECOMMENDATION_PROMPTS.length + 1;
|
|
102
|
-
for (let i = 0; i < RECOMMENDATION_PROMPTS.length; i++) {
|
|
103
|
-
const spec = RECOMMENDATION_PROMPTS[i];
|
|
104
|
-
log(` [${i + 1}/${totalPrompts}] Generating ${spec.name}...`);
|
|
105
|
-
try {
|
|
106
|
-
await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {
|
|
107
|
-
status: "running",
|
|
108
|
-
progress: {
|
|
109
|
-
step: spec.name,
|
|
110
|
-
current: i + 1,
|
|
111
|
-
total: totalPrompts,
|
|
112
|
-
partial: { ...recommendations }
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
} catch (patchErr) {
|
|
116
|
-
log(` Warning: progress update failed for ${spec.name}: ${patchErr instanceof Error ? patchErr.message : String(patchErr)}`);
|
|
117
|
-
}
|
|
118
|
-
log(` Running LLM prompt for ${spec.name}...`);
|
|
119
|
-
const result2 = await runLlmPrompt(spec.prompt, data.summary, spec.maxTokens);
|
|
120
|
-
if (result2) {
|
|
121
|
-
recommendations[spec.name] = result2;
|
|
122
|
-
log(` Got result for ${spec.name}`);
|
|
123
|
-
} else {
|
|
124
|
-
log(` No result for ${spec.name} (LLM returned null)`);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
log(` [${totalPrompts}/${totalPrompts}] Generating at_a_glance...`);
|
|
128
|
-
await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {
|
|
129
|
-
status: "running",
|
|
130
|
-
progress: {
|
|
131
|
-
step: "at_a_glance",
|
|
132
|
-
current: totalPrompts,
|
|
133
|
-
total: totalPrompts,
|
|
134
|
-
partial: { ...recommendations }
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
const glanceData = [
|
|
138
|
-
data.summary,
|
|
139
|
-
recommendations.what_works ? `
|
|
140
|
-
## What Works
|
|
141
|
-
${JSON.stringify(recommendations.what_works)}` : "",
|
|
142
|
-
recommendations.friction_analysis ? `
|
|
143
|
-
## Friction
|
|
144
|
-
${JSON.stringify(recommendations.friction_analysis)}` : "",
|
|
145
|
-
recommendations.suggestions ? `
|
|
146
|
-
## Suggestions
|
|
147
|
-
${JSON.stringify(recommendations.suggestions)}` : "",
|
|
148
|
-
recommendations.on_the_horizon ? `
|
|
149
|
-
## On the Horizon
|
|
150
|
-
${JSON.stringify(recommendations.on_the_horizon)}` : ""
|
|
151
|
-
].join("\n");
|
|
152
|
-
const glance = await runLlmPrompt(AT_A_GLANCE_PROMPT, glanceData, 8192);
|
|
153
|
-
if (glance) {
|
|
154
|
-
recommendations.at_a_glance = glance;
|
|
155
|
-
}
|
|
156
|
-
log(" Uploading results...");
|
|
157
|
-
log(` Done! Recommendations generated for job ${mirrorId}`);
|
|
158
|
-
const result = { recommendations };
|
|
159
|
-
await apiPatch(`/api/insights-jobs/${mirrorId}/state`, { result }).catch((err) => {
|
|
160
|
-
log(`result persist failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
161
|
-
});
|
|
162
|
-
return result;
|
|
163
|
-
}
|
|
164
|
-
async function processSessionAnalysisInline(args, log) {
|
|
165
|
-
const { mirrorId, sessionId } = args;
|
|
166
|
-
log(`Analyzing session ${sessionId} via tool CLI...`);
|
|
167
|
-
await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {
|
|
168
|
-
status: "running",
|
|
169
|
-
progress: { step: "fetching_session" }
|
|
170
|
-
});
|
|
171
|
-
const session = await apiGet(`/api/sessions/${sessionId}`);
|
|
172
|
-
if (session.analysis && session.analysis.source === "session_analysis") {
|
|
173
|
-
log(` Session ${sessionId} already analyzed \u2014 skipping (idempotency guard)`);
|
|
174
|
-
return { sessionId, skipped: true, reason: "already_analyzed" };
|
|
175
|
-
}
|
|
176
|
-
const events = await apiGet(
|
|
177
|
-
`/api/sessions/${sessionId}/events?limit=100`
|
|
178
|
-
);
|
|
179
|
-
if (events.length < 2) {
|
|
180
|
-
throw new PermanentJobError("Session has too few events to analyze");
|
|
181
|
-
}
|
|
182
|
-
const eventSummary = events.filter((e) => e.eventType === "user_message" || e.eventType === "human").map((e) => e.content?.slice(0, 200) ?? "").filter(Boolean).join("\n---\n");
|
|
183
|
-
if (!eventSummary) {
|
|
184
|
-
throw new PermanentJobError("No user messages found in session");
|
|
185
|
-
}
|
|
186
|
-
await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {
|
|
187
|
-
status: "running",
|
|
188
|
-
progress: { step: "running_analysis", tool: session.tool }
|
|
189
|
-
});
|
|
190
|
-
const facets = runToolPrompt(session.tool, FACET_GENERATION_PROMPT, eventSummary);
|
|
191
|
-
if (!facets) {
|
|
192
|
-
throw new Error(`Analysis failed \u2014 ${session.tool} CLI returned no result`);
|
|
193
|
-
}
|
|
194
|
-
const userMessageCount = events.filter(
|
|
195
|
-
(e) => e.eventType === "user_message" || e.eventType === "human"
|
|
196
|
-
).length;
|
|
197
|
-
await apiPatch(`/api/sessions/${sessionId}/enrich`, {
|
|
198
|
-
analysis: { source: "session_analysis", tool: session.tool, ...facets },
|
|
199
|
-
analyzedEventCount: events.length,
|
|
200
|
-
analyzedTurnCount: userMessageCount
|
|
201
|
-
});
|
|
202
|
-
log(` Session ${sessionId} analyzed via ${session.tool}`);
|
|
203
|
-
return { sessionId, tool: session.tool, facets };
|
|
204
|
-
}
|
|
205
|
-
async function buildDataSummaryFromApi(projectPath, projectId) {
|
|
206
|
-
try {
|
|
207
|
-
const params = new URLSearchParams();
|
|
208
|
-
if (projectId) {
|
|
209
|
-
params.set("projectId", projectId);
|
|
210
|
-
} else if (projectPath) {
|
|
211
|
-
params.set("projectPath", projectPath);
|
|
212
|
-
}
|
|
213
|
-
const computed = await apiGet(`/api/insights/compute?${params}`);
|
|
214
|
-
if (!computed || computed.total_sessions === 0) return null;
|
|
215
|
-
const topTools = Object.entries(computed.tool_counts ?? {}).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([t, c]) => `${t}: ${c}`).join(", ");
|
|
216
|
-
const summary = [
|
|
217
|
-
`Sessions: ${computed.total_sessions}, Messages: ${computed.total_messages}, Hours: ${Math.round(computed.total_duration_hours)}`,
|
|
218
|
-
`Top tools: ${topTools}`,
|
|
219
|
-
computed.goal_categories && Object.keys(computed.goal_categories).length > 0 ? `Goals: ${JSON.stringify(computed.goal_categories)}` : "",
|
|
220
|
-
computed.friction && Object.keys(computed.friction).length > 0 ? `Friction: ${JSON.stringify(computed.friction)}` : "",
|
|
221
|
-
computed.outcomes && Object.keys(computed.outcomes).length > 0 ? `Outcomes: ${JSON.stringify(computed.outcomes)}` : "",
|
|
222
|
-
computed.projects && Object.keys(computed.projects).length > 0 ? `Projects: ${JSON.stringify(computed.projects)}` : ""
|
|
223
|
-
].filter(Boolean).join("\n");
|
|
224
|
-
return {
|
|
225
|
-
summary,
|
|
226
|
-
stats: {
|
|
227
|
-
sessions: computed.total_sessions,
|
|
228
|
-
totalMessages: computed.total_messages,
|
|
229
|
-
totalHours: computed.total_duration_hours,
|
|
230
|
-
toolCounts: computed.tool_counts,
|
|
231
|
-
goalCounts: computed.goal_categories,
|
|
232
|
-
frictionCounts: computed.friction
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
} catch {
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
export {
|
|
241
|
-
processInsights
|
|
242
|
-
};
|
|
243
|
-
//# sourceMappingURL=chunk-VA5FFOS7.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/handlers/process-insights.ts"],
|
|
4
|
-
"sourcesContent": ["import type { JobHelpers } from '../job-helpers.js';\nimport { apiGet, apiPost, apiPatch } from '../api-client.js';\nimport { RECOMMENDATION_PROMPTS, AT_A_GLANCE_PROMPT, FACET_GENERATION_PROMPT } from '../insights-prompts.js';\nimport { runLlmPrompt, detectLlmBackend, runToolPrompt } from '../llm-client.js';\nimport { PermanentJobError } from '../permanent-job-error.js';\n\ninterface InsightsPayload {\n mirrorId: string;\n projectPath: string | null;\n // Canonical project identity resolved at enqueue time (best-effort; null when\n // unresolved). When present, the worker scopes its compute call to the\n // cross-path cohort via ?projectId; otherwise it falls back to ?projectPath.\n projectId?: string | null;\n config?: {\n sessionId?: string;\n [key: string]: unknown;\n };\n}\n\n/**\n * Graphile-shaped handler for the `process_insights` task.\n *\n * Lifted from the legacy `insights-worker.ts:processInsightsJob` and\n * `processSessionAnalysisJob`, with the queue plumbing stripped out:\n * - no claim \u2014 Graphile already claimed the job before invoking us\n * - no /complete POST \u2014 we return the result object (or throw)\n * - no \"could not claim\" early-return branches\n *\n * Mid-job progress patches still hit the existing\n * `PATCH /api/insights-jobs/:id/progress` endpoint, just keyed by the\n * mirror row's id.\n *\n * The session-analysis branch (selected when `payload.config.sessionId`\n * is set) lives inline below \u2014 it's a different code path but cheap to\n * keep co-located.\n *\n * The `buildDataSummary*` helpers are duplicated here as private locals;\n * Task 21 will hoist them into a shared `insights-data.ts` once\n * `insights-worker.ts` is deleted.\n *\n * User-facing notifications go through the API's `notifyUser()` path\n * (insert into `notifications` \u2192 Supabase Realtime \u2192 service-worker\n * `showNotification` with a deep-link). The worker no longer fires native\n * `osascript` banners \u2014 those duplicated the browser path, weren't\n * clickable to a URL, and stacked one-per-project on macOS.\n */\nexport async function processInsights(\n payload: InsightsPayload,\n helpers: JobHelpers,\n): Promise<Record<string, unknown>> {\n const { mirrorId, projectPath, projectId, config } = payload;\n const log = (msg: string) => helpers.logger.info(msg);\n\n // Session-analysis branch \u2014 single-session deep analysis through tool CLI\n if (config?.sessionId) {\n return processSessionAnalysisInline({ mirrorId, sessionId: config.sessionId }, log);\n }\n\n log(`Processing insights job ${mirrorId}...`);\n\n // Update status to running\n await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {\n status: 'running',\n progress: { step: 'reading_data' },\n });\n\n // Self-heal orphan analyses missing `analyzed_at`. Without this, the\n // freshness banner on the dashboard nags forever \u2014 the worker's\n // facet-drain query (`hasAnalysis=false`) skips already-analyzed rows,\n // so pre-instrumentation orphans never get touched. Stamps a conservative\n // lower bound (`analyzed_at = started_at`); idempotent on subsequent runs.\n // Best-effort: a failure here must not block the recommendation pass.\n try {\n const { repaired } = await apiPost<{ repaired: number }>(\n '/api/sessions/repair-analyzed-at',\n {},\n );\n if (repaired > 0) {\n log(` Repaired analyzed_at on ${repaired} orphan session(s).`);\n }\n } catch (repairErr) {\n log(` Warning: analyzed_at repair failed: ${repairErr instanceof Error ? repairErr.message : String(repairErr)}`);\n }\n\n // API-based summary is the only source. The previous file-based fallback\n // (`buildDataSummary` reading ~/.claude/usage-data/) was deleted on\n // 2026-05-05 \u2014 it required `rulemetric insights sync` to populate JSON\n // files locally, which nobody ever ran. The DB-derived summary is\n // tool-agnostic and authoritative.\n const data = await buildDataSummaryFromApi(projectPath, projectId);\n if (!data) {\n throw new PermanentJobError(\n 'No session data found \u2014 ensure sessions are captured and enriched.',\n );\n }\n\n log(` Found ${data.stats.sessions} sessions, generating recommendations...`);\n\n // Drain un-analyzed sessions in batches until empty (or until we hit the\n // hard cap, to keep the per-job runtime bounded). Previously this took at\n // most 20 sessions per run, which meant catch-up after a backlog could\n // span days. Batching keeps memory bounded while letting one job clear\n // the entire queue when needed.\n const FACET_BATCH_SIZE = 20;\n const FACET_HARD_CAP = 200; // protect against runaway runtime\n if (detectLlmBackend() !== 'none') {\n let totalFaceted = 0;\n try {\n while (totalFaceted < FACET_HARD_CAP) {\n const unfaceted = await apiGet<Array<{ id: string; tool: string }>>(\n `/api/sessions?hasAnalysis=false&limit=${FACET_BATCH_SIZE}`,\n );\n if (unfaceted.length === 0) break;\n log(` Generating facets for ${unfaceted.length} un-analyzed sessions (drained ${totalFaceted} so far)...`);\n for (const session of unfaceted) {\n if (totalFaceted >= FACET_HARD_CAP) break;\n try {\n const events = await apiGet<Array<{ eventType: string; content: string | null }>>(\n `/api/sessions/${session.id}/events?limit=100`,\n );\n if (events.length < 2) {\n totalFaceted++;\n continue;\n }\n\n const eventSummary = events\n .filter(e => e.eventType === 'user_message' || e.eventType === 'human')\n .map(e => e.content?.slice(0, 200) ?? '')\n .filter(Boolean)\n .join('\\n---\\n');\n\n if (!eventSummary) {\n totalFaceted++;\n continue;\n }\n\n const facets = await runLlmPrompt(FACET_GENERATION_PROMPT, eventSummary, 4096);\n if (facets) {\n const userMessageCount = events.filter(\n e => e.eventType === 'user_message' || e.eventType === 'human',\n ).length;\n await apiPatch(`/api/sessions/${session.id}/enrich`, {\n analysis: { source: 'generated_facets', ...facets },\n analyzedEventCount: events.length,\n analyzedTurnCount: userMessageCount,\n });\n log(` Generated facets for session ${session.id} (${session.tool})`);\n }\n totalFaceted++;\n } catch (sessionErr) {\n log(` Failed to generate facets for session ${session.id}: ${sessionErr instanceof Error ? sessionErr.message : String(sessionErr)}`);\n totalFaceted++; // count it so we don't infinite-loop on a poison row\n }\n }\n // If the batch returned fewer than the requested size, the queue is\n // empty \u2014 break before another fetch.\n if (unfaceted.length < FACET_BATCH_SIZE) break;\n }\n } catch (facetErr) {\n log(` Warning: facet generation failed after ${totalFaceted} sessions: ${facetErr instanceof Error ? facetErr.message : String(facetErr)}`);\n }\n }\n\n // Run recommendation prompts sequentially\n const recommendations: Record<string, unknown> = {};\n const totalPrompts = RECOMMENDATION_PROMPTS.length + 1; // +1 for at_a_glance\n\n // Persist sections-so-far on every progress PATCH so the web UI can render\n // them incrementally \u2014 each prompt takes 30-60s and shipping a label-only\n // progress update for that whole window leaves the page looking dead. The\n // detail page reads `progress.partial` and renders each section card as it\n // arrives.\n for (let i = 0; i < RECOMMENDATION_PROMPTS.length; i++) {\n const spec = RECOMMENDATION_PROMPTS[i];\n log(` [${i + 1}/${totalPrompts}] Generating ${spec.name}...`);\n\n try {\n await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {\n status: 'running',\n progress: {\n step: spec.name,\n current: i + 1,\n total: totalPrompts,\n partial: { ...recommendations },\n },\n });\n } catch (patchErr) {\n log(` Warning: progress update failed for ${spec.name}: ${patchErr instanceof Error ? patchErr.message : String(patchErr)}`);\n }\n\n log(` Running LLM prompt for ${spec.name}...`);\n const result = await runLlmPrompt(spec.prompt, data.summary, spec.maxTokens);\n if (result) {\n recommendations[spec.name] = result;\n log(` Got result for ${spec.name}`);\n } else {\n log(` No result for ${spec.name} (LLM returned null)`);\n }\n }\n\n // At a glance (uses outputs from previous prompts)\n log(` [${totalPrompts}/${totalPrompts}] Generating at_a_glance...`);\n await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {\n status: 'running',\n progress: {\n step: 'at_a_glance',\n current: totalPrompts,\n total: totalPrompts,\n partial: { ...recommendations },\n },\n });\n\n const glanceData = [\n data.summary,\n recommendations.what_works ? `\\n## What Works\\n${JSON.stringify(recommendations.what_works)}` : '',\n recommendations.friction_analysis ? `\\n## Friction\\n${JSON.stringify(recommendations.friction_analysis)}` : '',\n recommendations.suggestions ? `\\n## Suggestions\\n${JSON.stringify(recommendations.suggestions)}` : '',\n recommendations.on_the_horizon ? `\\n## On the Horizon\\n${JSON.stringify(recommendations.on_the_horizon)}` : '',\n ].join('\\n');\n\n const glance = await runLlmPrompt(AT_A_GLANCE_PROMPT, glanceData, 8192);\n if (glance) {\n recommendations.at_a_glance = glance;\n }\n\n log(' Uploading results...');\n log(` Done! Recommendations generated for job ${mirrorId}`);\n\n const result = { recommendations };\n\n // Graphile discards task return values, so persist `{ recommendations }`\n // onto the mirror row here so the dashboard can read it. Best-effort.\n await apiPatch(`/api/insights-jobs/${mirrorId}/state`, { result }).catch((err: unknown) => {\n log(`result persist failed: ${err instanceof Error ? err.message : String(err)}`);\n });\n\n return result;\n}\n\n/**\n * Single-session deep analysis branch. Runs the session's own tool CLI\n * against the captured event stream to produce facets, then enriches the\n * session row.\n *\n * Idempotency guard: if the session already has analysis from a prior\n * `session_analysis` run, we short-circuit. This is independent of the\n * Graphile-side `job_key` dedup added in Task 9 \u2014 that prevents duplicate\n * enqueues; this prevents redoing work even if a different mirrorId\n * targets the same session.\n */\nasync function processSessionAnalysisInline(\n args: { mirrorId: string; sessionId: string },\n log: (msg: string) => void,\n): Promise<Record<string, unknown>> {\n const { mirrorId, sessionId } = args;\n\n log(`Analyzing session ${sessionId} via tool CLI...`);\n\n await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {\n status: 'running',\n progress: { step: 'fetching_session' },\n });\n\n const session = await apiGet<{ id: string; tool: string; analysis: Record<string, unknown> | null }>(`/api/sessions/${sessionId}`);\n\n // Idempotency: skip if session already has analysis from a prior run\n if (session.analysis && (session.analysis as Record<string, unknown>).source === 'session_analysis') {\n log(` Session ${sessionId} already analyzed \u2014 skipping (idempotency guard)`);\n return { sessionId, skipped: true, reason: 'already_analyzed' };\n }\n\n const events = await apiGet<Array<{ eventType: string; content: string | null }>>(\n `/api/sessions/${sessionId}/events?limit=100`,\n );\n\n if (events.length < 2) {\n throw new PermanentJobError('Session has too few events to analyze');\n }\n\n const eventSummary = events\n .filter(e => e.eventType === 'user_message' || e.eventType === 'human')\n .map(e => e.content?.slice(0, 200) ?? '')\n .filter(Boolean)\n .join('\\n---\\n');\n\n if (!eventSummary) {\n throw new PermanentJobError('No user messages found in session');\n }\n\n await apiPatch(`/api/insights-jobs/${mirrorId}/progress`, {\n status: 'running',\n progress: { step: 'running_analysis', tool: session.tool },\n });\n\n // Run through the session's tool CLI\n const facets = runToolPrompt(session.tool, FACET_GENERATION_PROMPT, eventSummary);\n\n if (!facets) {\n throw new Error(`Analysis failed \u2014 ${session.tool} CLI returned no result`);\n }\n\n const userMessageCount = events.filter(\n e => e.eventType === 'user_message' || e.eventType === 'human',\n ).length;\n await apiPatch(`/api/sessions/${sessionId}/enrich`, {\n analysis: { source: 'session_analysis', tool: session.tool, ...facets },\n analyzedEventCount: events.length,\n analyzedTurnCount: userMessageCount,\n });\n\n log(` Session ${sessionId} analyzed via ${session.tool}`);\n\n return { sessionId, tool: session.tool, facets };\n}\n\n// ---------------------------------------------------------------------------\n// Local helpers (copied from `insights-worker.ts`; Task 21 hoists to shared)\n// ---------------------------------------------------------------------------\n\nasync function buildDataSummaryFromApi(projectPath: string | null, projectId?: string | null): Promise<{ summary: string; stats: Record<string, unknown> } | null> {\n try {\n const params = new URLSearchParams();\n // Prefer the canonical project_id \u2014 /api/insights/compute aggregates the\n // project's sessions across every path variant (repo root, /src, worktrees,\n // home-dir captures). Fall back to project_path when no id was resolved.\n if (projectId) {\n params.set('projectId', projectId);\n } else if (projectPath) {\n params.set('projectPath', projectPath);\n }\n\n const computed = await apiGet<{\n total_sessions: number;\n sessions_with_meta: number;\n total_messages: number;\n total_duration_hours: number;\n tool_counts: Record<string, number>;\n goal_categories: Record<string, number>;\n friction: Record<string, number>;\n outcomes: Record<string, number>;\n git_commits: number;\n total_lines_added: number;\n total_lines_removed: number;\n projects: Record<string, number>;\n }>(`/api/insights/compute?${params}`);\n\n if (!computed || computed.total_sessions === 0) return null;\n\n // Build the same text summary format the prompts expect\n const topTools = Object.entries(computed.tool_counts ?? {})\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([t, c]) => `${t}: ${c}`)\n .join(', ');\n\n const summary = [\n `Sessions: ${computed.total_sessions}, Messages: ${computed.total_messages}, Hours: ${Math.round(computed.total_duration_hours)}`,\n `Top tools: ${topTools}`,\n computed.goal_categories && Object.keys(computed.goal_categories).length > 0\n ? `Goals: ${JSON.stringify(computed.goal_categories)}`\n : '',\n computed.friction && Object.keys(computed.friction).length > 0\n ? `Friction: ${JSON.stringify(computed.friction)}`\n : '',\n computed.outcomes && Object.keys(computed.outcomes).length > 0\n ? `Outcomes: ${JSON.stringify(computed.outcomes)}`\n : '',\n computed.projects && Object.keys(computed.projects).length > 0\n ? `Projects: ${JSON.stringify(computed.projects)}`\n : '',\n ].filter(Boolean).join('\\n');\n\n return {\n summary,\n stats: {\n sessions: computed.total_sessions,\n totalMessages: computed.total_messages,\n totalHours: computed.total_duration_hours,\n toolCounts: computed.tool_counts,\n goalCounts: computed.goal_categories,\n frictionCounts: computed.friction,\n },\n };\n } catch {\n return null;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["result"]
|
|
7
|
-
}
|