waterplane 0.1.6 → 0.1.11
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/CHANGELOG.md +92 -1
- package/README.md +1 -1
- package/SECURITY.md +11 -3
- package/deploy/node-version +1 -1
- package/node_modules/@waterplane/shared/dist/agentfiles.d.ts +17 -0
- package/node_modules/@waterplane/shared/dist/agentfiles.js +58 -4
- package/node_modules/@waterplane/shared/dist/agentfiles.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/alwaysonwords.d.ts +83 -0
- package/node_modules/@waterplane/shared/dist/alwaysonwords.js +209 -0
- package/node_modules/@waterplane/shared/dist/alwaysonwords.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/autocompact.js +1 -1
- package/node_modules/@waterplane/shared/dist/autocompact.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/backendsources.d.ts +11 -1
- package/node_modules/@waterplane/shared/dist/backendsources.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/branchmode.d.ts +27 -0
- package/node_modules/@waterplane/shared/dist/branchmode.js +80 -0
- package/node_modules/@waterplane/shared/dist/branchmode.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/buildstamp.d.ts +37 -0
- package/node_modules/@waterplane/shared/dist/buildstamp.js +95 -0
- package/node_modules/@waterplane/shared/dist/buildstamp.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/burn.d.ts +16 -1
- package/node_modules/@waterplane/shared/dist/burn.js +30 -0
- package/node_modules/@waterplane/shared/dist/burn.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/changebrief.d.ts +61 -0
- package/node_modules/@waterplane/shared/dist/changebrief.js +70 -0
- package/node_modules/@waterplane/shared/dist/changebrief.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/desktopfiles.d.ts +100 -0
- package/node_modules/@waterplane/shared/dist/desktopfiles.js +192 -0
- package/node_modules/@waterplane/shared/dist/desktopfiles.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/exposure.d.ts +175 -0
- package/node_modules/@waterplane/shared/dist/exposure.js +357 -0
- package/node_modules/@waterplane/shared/dist/exposure.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/exposurepush.d.ts +60 -0
- package/node_modules/@waterplane/shared/dist/exposurepush.js +103 -0
- package/node_modules/@waterplane/shared/dist/exposurepush.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/healthindex/commits.d.ts +26 -0
- package/node_modules/@waterplane/shared/dist/healthindex/commits.js +57 -0
- package/node_modules/@waterplane/shared/dist/healthindex/commits.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/healthindex/move.d.ts +25 -0
- package/node_modules/@waterplane/shared/dist/healthindex/move.js +79 -0
- package/node_modules/@waterplane/shared/dist/healthindex/move.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/healthindex/readings.d.ts +53 -0
- package/node_modules/@waterplane/shared/dist/healthindex/readings.js +154 -0
- package/node_modules/@waterplane/shared/dist/healthindex/readings.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/healthindex/repoindex.d.ts +41 -0
- package/node_modules/@waterplane/shared/dist/healthindex/repoindex.js +19 -0
- package/node_modules/@waterplane/shared/dist/healthindex/repoindex.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/healthindex/score.d.ts +26 -0
- package/node_modules/@waterplane/shared/dist/healthindex/score.js +154 -0
- package/node_modules/@waterplane/shared/dist/healthindex/score.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/healthindex/types.d.ts +206 -0
- package/node_modules/@waterplane/shared/dist/healthindex/types.js +58 -0
- package/node_modules/@waterplane/shared/dist/healthindex/types.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/healthindex/vs.d.ts +26 -0
- package/node_modules/@waterplane/shared/dist/healthindex/vs.js +38 -0
- package/node_modules/@waterplane/shared/dist/healthindex/vs.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/healthindex/words.d.ts +28 -0
- package/node_modules/@waterplane/shared/dist/healthindex/words.js +69 -0
- package/node_modules/@waterplane/shared/dist/healthindex/words.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/healthindex.d.ts +15 -411
- package/node_modules/@waterplane/shared/dist/healthindex.js +8 -602
- package/node_modules/@waterplane/shared/dist/healthindex.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/hints.js +5 -0
- package/node_modules/@waterplane/shared/dist/hints.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/index.d.ts +29 -0
- package/node_modules/@waterplane/shared/dist/index.js +29 -0
- package/node_modules/@waterplane/shared/dist/index.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/intent/kind.d.ts +31 -1
- package/node_modules/@waterplane/shared/dist/intent/kind.js +27 -3
- package/node_modules/@waterplane/shared/dist/intent/kind.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/intent.d.ts +1 -1
- package/node_modules/@waterplane/shared/dist/intent.js +1 -1
- package/node_modules/@waterplane/shared/dist/intent.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/launchmodes.d.ts +2 -0
- package/node_modules/@waterplane/shared/dist/launchmodes.js +12 -0
- package/node_modules/@waterplane/shared/dist/launchmodes.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/ledgerspan.d.ts +59 -0
- package/node_modules/@waterplane/shared/dist/ledgerspan.js +99 -0
- package/node_modules/@waterplane/shared/dist/ledgerspan.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/netretry.d.ts +38 -0
- package/node_modules/@waterplane/shared/dist/netretry.js +31 -0
- package/node_modules/@waterplane/shared/dist/netretry.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/netretrycfg.d.ts +12 -0
- package/node_modules/@waterplane/shared/dist/netretrycfg.js +27 -0
- package/node_modules/@waterplane/shared/dist/netretrycfg.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/nodemin.d.ts +6 -4
- package/node_modules/@waterplane/shared/dist/nodemin.js +6 -4
- package/node_modules/@waterplane/shared/dist/nodemin.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/optins.d.ts +35 -1
- package/node_modules/@waterplane/shared/dist/optins.js +39 -1
- package/node_modules/@waterplane/shared/dist/optins.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/plugin/api.d.ts +364 -0
- package/node_modules/@waterplane/shared/dist/plugin/api.js +2 -0
- package/node_modules/@waterplane/shared/dist/plugin/api.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/plugin/backend.d.ts +197 -0
- package/node_modules/@waterplane/shared/dist/plugin/backend.js +9 -0
- package/node_modules/@waterplane/shared/dist/plugin/backend.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/plugin/manifest.d.ts +160 -0
- package/node_modules/@waterplane/shared/dist/plugin/manifest.js +98 -0
- package/node_modules/@waterplane/shared/dist/plugin/manifest.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/plugin/module.d.ts +98 -0
- package/node_modules/@waterplane/shared/dist/plugin/module.js +13 -0
- package/node_modules/@waterplane/shared/dist/plugin/module.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/plugin/version.d.ts +64 -0
- package/node_modules/@waterplane/shared/dist/plugin/version.js +84 -0
- package/node_modules/@waterplane/shared/dist/plugin/version.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/plugin.d.ts +5 -867
- package/node_modules/@waterplane/shared/dist/plugin.js +27 -186
- package/node_modules/@waterplane/shared/dist/plugin.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/pluginlaunch.d.ts +7 -0
- package/node_modules/@waterplane/shared/dist/prview.d.ts +23 -0
- package/node_modules/@waterplane/shared/dist/prview.js +107 -0
- package/node_modules/@waterplane/shared/dist/prview.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/repohealth.d.ts +4 -0
- package/node_modules/@waterplane/shared/dist/repohealth.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/schedule/schedaction.d.ts +29 -0
- package/node_modules/@waterplane/shared/dist/schedule/schedaction.js +22 -0
- package/node_modules/@waterplane/shared/dist/schedule/schedaction.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/schedule/schedclean.js +26 -0
- package/node_modules/@waterplane/shared/dist/schedule/schedclean.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/schedule.d.ts +1 -1
- package/node_modules/@waterplane/shared/dist/schedule.js +1 -1
- package/node_modules/@waterplane/shared/dist/schedule.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/sessionbudget.d.ts +20 -5
- package/node_modules/@waterplane/shared/dist/sessionbudget.js +42 -16
- package/node_modules/@waterplane/shared/dist/sessionbudget.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/weekburn.d.ts +114 -0
- package/node_modules/@waterplane/shared/dist/weekburn.js +205 -0
- package/node_modules/@waterplane/shared/dist/weekburn.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/wire/alwayson.d.ts +64 -0
- package/node_modules/@waterplane/shared/dist/wire/alwayson.js +7 -0
- package/node_modules/@waterplane/shared/dist/wire/alwayson.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/wire/backend.d.ts +4 -0
- package/node_modules/@waterplane/shared/dist/wire/backendtokens.d.ts +6 -0
- package/node_modules/@waterplane/shared/dist/wire/backendtokens.js +0 -9
- package/node_modules/@waterplane/shared/dist/wire/backendtokens.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/wire/costwindow.d.ts +20 -0
- package/node_modules/@waterplane/shared/dist/wire/messages/clienthost.d.ts +15 -1
- package/node_modules/@waterplane/shared/dist/wire/messages/clientsession.d.ts +10 -0
- package/node_modules/@waterplane/shared/dist/wire/messages/hosttools.d.ts +12 -2
- package/node_modules/@waterplane/shared/dist/wire/notify.d.ts +129 -1
- package/node_modules/@waterplane/shared/dist/wire/notify.js +79 -1
- package/node_modules/@waterplane/shared/dist/wire/notify.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/wire/pullrequest.d.ts +42 -0
- package/node_modules/@waterplane/shared/dist/wire/pullrequest.js +2 -0
- package/node_modules/@waterplane/shared/dist/wire/pullrequest.js.map +1 -0
- package/node_modules/@waterplane/shared/dist/wire/repo.d.ts +119 -0
- package/node_modules/@waterplane/shared/dist/wire/repo.js +8 -3
- package/node_modules/@waterplane/shared/dist/wire/repo.js.map +1 -1
- package/node_modules/@waterplane/shared/dist/wire/sent.d.ts +3 -1
- package/node_modules/@waterplane/shared/dist/wire/session/contextspark.d.ts +7 -0
- package/node_modules/@waterplane/shared/dist/wire/session/info.d.ts +4 -1
- package/node_modules/@waterplane/shared/dist/wire/session/launch.d.ts +25 -0
- package/node_modules/@waterplane/shared/dist/wire/session.d.ts +1 -1
- package/node_modules/@waterplane/shared/dist/wire/telemetry.d.ts +4 -0
- package/node_modules/@waterplane/shared/dist/wire/work.d.ts +13 -0
- package/node_modules/@waterplane/shared/dist/wire/work.js.map +1 -1
- package/npm-shrinkwrap.json +3 -3
- package/package.json +2 -2
- package/packages/extensions/scorecard/waterplane-plugin.json +10 -0
- package/packages/host/dist/agentexposure.d.ts +13 -0
- package/packages/host/dist/agentexposure.js +90 -0
- package/packages/host/dist/agentexposure.js.map +1 -0
- package/packages/host/dist/agentintents.js +2 -2
- package/packages/host/dist/agentintents.js.map +1 -1
- package/packages/host/dist/agentwatch.d.ts +3 -7
- package/packages/host/dist/agentwatch.js.map +1 -1
- package/packages/host/dist/alwayson.d.ts +18 -0
- package/packages/host/dist/alwayson.js +159 -0
- package/packages/host/dist/alwayson.js.map +1 -0
- package/packages/host/dist/answergate.d.ts +3 -7
- package/packages/host/dist/answergate.js.map +1 -1
- package/packages/host/dist/attentionstore.d.ts +61 -0
- package/packages/host/dist/attentionstore.js +162 -0
- package/packages/host/dist/attentionstore.js.map +1 -0
- package/packages/host/dist/backends/claude.js +1 -1
- package/packages/host/dist/backends/claude.js.map +1 -1
- package/packages/host/dist/backends/derive.js +1 -0
- package/packages/host/dist/backends/derive.js.map +1 -1
- package/packages/host/dist/backends/registry.js +4 -1
- package/packages/host/dist/backends/registry.js.map +1 -1
- package/packages/host/dist/backends/types.d.ts +2 -0
- package/packages/host/dist/besidespend.d.ts +22 -0
- package/packages/host/dist/besidespend.js +65 -0
- package/packages/host/dist/besidespend.js.map +1 -0
- package/packages/host/dist/boxkit.d.ts +19 -0
- package/packages/host/dist/boxkit.js +38 -0
- package/packages/host/dist/boxkit.js.map +1 -0
- package/packages/host/dist/branchrules.d.ts +14 -0
- package/packages/host/dist/branchrules.js +47 -0
- package/packages/host/dist/branchrules.js.map +1 -0
- package/packages/host/dist/builds.d.ts +31 -1
- package/packages/host/dist/builds.js +55 -3
- package/packages/host/dist/builds.js.map +1 -1
- package/packages/host/dist/buildversions.d.ts +2 -0
- package/packages/host/dist/buildversions.js +36 -0
- package/packages/host/dist/buildversions.js.map +1 -0
- package/packages/host/dist/burnwatch.d.ts +23 -11
- package/packages/host/dist/burnwatch.js +51 -2
- package/packages/host/dist/burnwatch.js.map +1 -1
- package/packages/host/dist/changebrief.d.ts +37 -0
- package/packages/host/dist/changebrief.js +157 -0
- package/packages/host/dist/changebrief.js.map +1 -0
- package/packages/host/dist/cli/index.js +1 -1
- package/packages/host/dist/cli/index.js.map +1 -1
- package/packages/host/dist/clihealth.d.ts +2 -0
- package/packages/host/dist/clihealth.js +11 -2
- package/packages/host/dist/clihealth.js.map +1 -1
- package/packages/host/dist/compliance.d.ts +5 -1
- package/packages/host/dist/compliance.js +70 -31
- package/packages/host/dist/compliance.js.map +1 -1
- package/packages/host/dist/composer.d.ts +3 -1
- package/packages/host/dist/composer.js +3 -1
- package/packages/host/dist/composer.js.map +1 -1
- package/packages/host/dist/ctxlog/ctxcursor.d.ts +36 -1
- package/packages/host/dist/ctxlog/ctxcursor.js +96 -2
- package/packages/host/dist/ctxlog/ctxcursor.js.map +1 -1
- package/packages/host/dist/ctxlog/ctxproject.js +2 -1
- package/packages/host/dist/ctxlog/ctxproject.js.map +1 -1
- package/packages/host/dist/ctxlog/ctxupdate.js +13 -2
- package/packages/host/dist/ctxlog/ctxupdate.js.map +1 -1
- package/packages/host/dist/diskwatch.d.ts +4 -6
- package/packages/host/dist/diskwatch.js +3 -1
- package/packages/host/dist/diskwatch.js.map +1 -1
- package/packages/host/dist/eraseen.d.ts +6 -0
- package/packages/host/dist/eraseen.js +100 -0
- package/packages/host/dist/eraseen.js.map +1 -0
- package/packages/host/dist/exposure.d.ts +56 -0
- package/packages/host/dist/exposure.js +371 -0
- package/packages/host/dist/exposure.js.map +1 -0
- package/packages/host/dist/exposurepush.d.ts +28 -0
- package/packages/host/dist/exposurepush.js +136 -0
- package/packages/host/dist/exposurepush.js.map +1 -0
- package/packages/host/dist/exposurerun.d.ts +18 -0
- package/packages/host/dist/exposurerun.js +126 -0
- package/packages/host/dist/exposurerun.js.map +1 -0
- package/packages/host/dist/exposurewatch.d.ts +29 -0
- package/packages/host/dist/exposurewatch.js +127 -0
- package/packages/host/dist/exposurewatch.js.map +1 -0
- package/packages/host/dist/extensions/scorecard/host/engine.d.mts +54 -0
- package/packages/host/dist/extensions/scorecard/host/engine.mjs +303 -0
- package/packages/host/dist/extensions/scorecard/host/engine.mjs.map +1 -0
- package/packages/host/dist/extensions/scorecard/host/gitslug.d.mts +5 -0
- package/packages/host/dist/extensions/scorecard/host/gitslug.mjs +45 -0
- package/packages/host/dist/extensions/scorecard/host/gitslug.mjs.map +1 -0
- package/packages/host/dist/extensions/scorecard/host/index.d.mts +15 -0
- package/packages/host/dist/extensions/scorecard/host/index.mjs +47 -0
- package/packages/host/dist/extensions/scorecard/host/index.mjs.map +1 -0
- package/packages/host/dist/extensions/scorecard/host/store.d.mts +12 -0
- package/packages/host/dist/extensions/scorecard/host/store.mjs +91 -0
- package/packages/host/dist/extensions/scorecard/host/store.mjs.map +1 -0
- package/packages/host/dist/extensions/scorecard/shared/logic.d.mts +42 -0
- package/packages/host/dist/extensions/scorecard/shared/logic.mjs +170 -0
- package/packages/host/dist/extensions/scorecard/shared/logic.mjs.map +1 -0
- package/packages/host/dist/extensions/scorecard/shared/wire.d.mts +140 -0
- package/packages/host/dist/extensions/scorecard/shared/wire.mjs +29 -0
- package/packages/host/dist/extensions/scorecard/shared/wire.mjs.map +1 -0
- package/packages/host/dist/forge/github.d.ts +3 -0
- package/packages/host/dist/forge/github.js +82 -0
- package/packages/host/dist/forge/github.js.map +1 -0
- package/packages/host/dist/forge/index.d.ts +14 -0
- package/packages/host/dist/forge/index.js +32 -0
- package/packages/host/dist/forge/index.js.map +1 -0
- package/packages/host/dist/forge/types.d.ts +52 -0
- package/packages/host/dist/forge/types.js +2 -0
- package/packages/host/dist/forge/types.js.map +1 -0
- package/packages/host/dist/git.d.ts +36 -3
- package/packages/host/dist/git.js +119 -41
- package/packages/host/dist/git.js.map +1 -1
- package/packages/host/dist/gitnotify.d.ts +24 -0
- package/packages/host/dist/gitnotify.js +60 -0
- package/packages/host/dist/gitnotify.js.map +1 -0
- package/packages/host/dist/healthwatch.d.ts +2 -1
- package/packages/host/dist/healthwatch.js +4 -2
- package/packages/host/dist/healthwatch.js.map +1 -1
- package/packages/host/dist/intents/adapters.js +45 -14
- package/packages/host/dist/intents/adapters.js.map +1 -1
- package/packages/host/dist/intents/contract.d.ts +4 -0
- package/packages/host/dist/intents/contract.js.map +1 -1
- package/packages/host/dist/intents/fire.js +7 -1
- package/packages/host/dist/intents/fire.js.map +1 -1
- package/packages/host/dist/intents/manager.d.ts +3 -3
- package/packages/host/dist/intents/manager.js +2 -2
- package/packages/host/dist/intents/manager.js.map +1 -1
- package/packages/host/dist/intents/watch.d.ts +10 -2
- package/packages/host/dist/intents/watch.js +27 -2
- package/packages/host/dist/intents/watch.js.map +1 -1
- package/packages/host/dist/localcistatus.d.ts +22 -0
- package/packages/host/dist/localcistatus.js +105 -0
- package/packages/host/dist/localcistatus.js.map +1 -0
- package/packages/host/dist/main.js +40 -10
- package/packages/host/dist/main.js.map +1 -1
- package/packages/host/dist/net.d.ts +2 -0
- package/packages/host/dist/net.js +11 -2
- package/packages/host/dist/net.js.map +1 -1
- package/packages/host/dist/netlog.d.ts +40 -0
- package/packages/host/dist/netlog.js +165 -0
- package/packages/host/dist/netlog.js.map +1 -0
- package/packages/host/dist/netretrycfg.d.ts +7 -0
- package/packages/host/dist/netretrycfg.js +51 -0
- package/packages/host/dist/netretrycfg.js.map +1 -0
- package/packages/host/dist/notifyprefs.d.ts +6 -2
- package/packages/host/dist/notifyprefs.js +20 -5
- package/packages/host/dist/notifyprefs.js.map +1 -1
- package/packages/host/dist/notifytypes.d.ts +58 -0
- package/packages/host/dist/notifytypes.js +2 -0
- package/packages/host/dist/notifytypes.js.map +1 -0
- package/packages/host/dist/opendeliveries.js +24 -0
- package/packages/host/dist/opendeliveries.js.map +1 -1
- package/packages/host/dist/optins.d.ts +28 -1
- package/packages/host/dist/optins.js +96 -4
- package/packages/host/dist/optins.js.map +1 -1
- package/packages/host/dist/peers/agentpeer.js +1 -1
- package/packages/host/dist/peers/agentpeer.js.map +1 -1
- package/packages/host/dist/peers/jobs.d.ts +2 -4
- package/packages/host/dist/peers/jobs.js +6 -1
- package/packages/host/dist/peers/jobs.js.map +1 -1
- package/packages/host/dist/plugins/pluginapi.js +2 -0
- package/packages/host/dist/plugins/pluginapi.js.map +1 -1
- package/packages/host/dist/plugins/pluginregistry.d.ts +3 -8
- package/packages/host/dist/plugins/pluginregistry.js +1 -1
- package/packages/host/dist/plugins/pluginregistry.js.map +1 -1
- package/packages/host/dist/protectmain.d.ts +35 -0
- package/packages/host/dist/protectmain.js +73 -0
- package/packages/host/dist/protectmain.js.map +1 -0
- package/packages/host/dist/prpush.d.ts +30 -0
- package/packages/host/dist/prpush.js +171 -0
- package/packages/host/dist/prpush.js.map +1 -0
- package/packages/host/dist/prs.d.ts +70 -0
- package/packages/host/dist/prs.js +328 -0
- package/packages/host/dist/prs.js.map +1 -0
- package/packages/host/dist/push.d.ts +19 -0
- package/packages/host/dist/push.js.map +1 -1
- package/packages/host/dist/render.d.ts +57 -0
- package/packages/host/dist/render.js +57 -39
- package/packages/host/dist/render.js.map +1 -1
- package/packages/host/dist/repohealth.js +5 -2
- package/packages/host/dist/repohealth.js.map +1 -1
- package/packages/host/dist/repohealthapproval.d.ts +3 -0
- package/packages/host/dist/repohealthapproval.js +92 -2
- package/packages/host/dist/repohealthapproval.js.map +1 -1
- package/packages/host/dist/repos.js +7 -1
- package/packages/host/dist/repos.js.map +1 -1
- package/packages/host/dist/reposkill.d.ts +8 -5
- package/packages/host/dist/reposkill.js +16 -11
- package/packages/host/dist/reposkill.js.map +1 -1
- package/packages/host/dist/reposkilltext.d.ts +8 -1
- package/packages/host/dist/reposkilltext.js +72 -3
- package/packages/host/dist/reposkilltext.js.map +1 -1
- package/packages/host/dist/routes/apihost.js +26 -2
- package/packages/host/dist/routes/apihost.js.map +1 -1
- package/packages/host/dist/routes/apiprs.d.ts +2 -0
- package/packages/host/dist/routes/apiprs.js +45 -0
- package/packages/host/dist/routes/apiprs.js.map +1 -0
- package/packages/host/dist/routes/apirepofiles.js +12 -1
- package/packages/host/dist/routes/apirepofiles.js.map +1 -1
- package/packages/host/dist/routes/apirepowork.js +48 -24
- package/packages/host/dist/routes/apirepowork.js.map +1 -1
- package/packages/host/dist/routes/apiroutes.js +2 -1
- package/packages/host/dist/routes/apiroutes.js.map +1 -1
- package/packages/host/dist/routes/apisession.js +24 -0
- package/packages/host/dist/routes/apisession.js.map +1 -1
- package/packages/host/dist/routes/apistats.js +12 -7
- package/packages/host/dist/routes/apistats.js.map +1 -1
- package/packages/host/dist/routes/apisystem.js +23 -1
- package/packages/host/dist/routes/apisystem.js.map +1 -1
- package/packages/host/dist/routes/apitable.d.ts +10 -0
- package/packages/host/dist/routes/apitable.js.map +1 -1
- package/packages/host/dist/routes/apiweekburn.d.ts +2 -0
- package/packages/host/dist/routes/apiweekburn.js +30 -0
- package/packages/host/dist/routes/apiweekburn.js.map +1 -0
- package/packages/host/dist/routes/session.js +4 -0
- package/packages/host/dist/routes/session.js.map +1 -1
- package/packages/host/dist/routes/system.js +33 -6
- package/packages/host/dist/routes/system.js.map +1 -1
- package/packages/host/dist/routes/types.d.ts +29 -21
- package/packages/host/dist/routes/work/workbuild.js +3 -2
- package/packages/host/dist/routes/work/workbuild.js.map +1 -1
- package/packages/host/dist/routes/work/workschedule.js +33 -3
- package/packages/host/dist/routes/work/workschedule.js.map +1 -1
- package/packages/host/dist/screenlog.d.ts +20 -0
- package/packages/host/dist/screenlog.js +40 -0
- package/packages/host/dist/screenlog.js.map +1 -1
- package/packages/host/dist/server/clients.d.ts +14 -24
- package/packages/host/dist/server/clients.js +77 -11
- package/packages/host/dist/server/clients.js.map +1 -1
- package/packages/host/dist/server/ctx.d.ts +2 -0
- package/packages/host/dist/server/ctxseal.d.ts +1 -1
- package/packages/host/dist/server/ctxseal.js +6 -6
- package/packages/host/dist/server/ctxseal.js.map +1 -1
- package/packages/host/dist/server/deliveries.js +4 -2
- package/packages/host/dist/server/deliveries.js.map +1 -1
- package/packages/host/dist/server/http.js +2 -2
- package/packages/host/dist/server/http.js.map +1 -1
- package/packages/host/dist/server/intentDeps.js +4 -1
- package/packages/host/dist/server/intentDeps.js.map +1 -1
- package/packages/host/dist/server/intentEvents.js +9 -4
- package/packages/host/dist/server/intentEvents.js.map +1 -1
- package/packages/host/dist/server/scan.js +23 -1
- package/packages/host/dist/server/scan.js.map +1 -1
- package/packages/host/dist/server/sessionEvents.js +37 -10
- package/packages/host/dist/server/sessionEvents.js.map +1 -1
- package/packages/host/dist/sessions/agentpoll.d.ts +31 -0
- package/packages/host/dist/sessions/agentpoll.js +176 -0
- package/packages/host/dist/sessions/agentpoll.js.map +1 -0
- package/packages/host/dist/sessions/apiretry.d.ts +59 -0
- package/packages/host/dist/sessions/apiretry.js +240 -0
- package/packages/host/dist/sessions/apiretry.js.map +1 -0
- package/packages/host/dist/sessions/askwatch.d.ts +62 -0
- package/packages/host/dist/sessions/askwatch.js +169 -0
- package/packages/host/dist/sessions/askwatch.js.map +1 -0
- package/packages/host/dist/sessions/boxes.d.ts +2 -23
- package/packages/host/dist/sessions/boxes.js +10 -664
- package/packages/host/dist/sessions/boxes.js.map +1 -1
- package/packages/host/dist/sessions/boxread.d.ts +47 -0
- package/packages/host/dist/sessions/boxread.js +628 -0
- package/packages/host/dist/sessions/boxread.js.map +1 -0
- package/packages/host/dist/sessions/core.d.ts +16 -1
- package/packages/host/dist/sessions/ctxseries.js +3 -0
- package/packages/host/dist/sessions/ctxseries.js.map +1 -1
- package/packages/host/dist/sessions/drive.d.ts +20 -6
- package/packages/host/dist/sessions/drive.js +43 -8
- package/packages/host/dist/sessions/drive.js.map +1 -1
- package/packages/host/dist/sessions/knobs.d.ts +8 -0
- package/packages/host/dist/sessions/knobs.js +9 -0
- package/packages/host/dist/sessions/knobs.js.map +1 -1
- package/packages/host/dist/sessions/record.js +7 -2
- package/packages/host/dist/sessions/record.js.map +1 -1
- package/packages/host/dist/sessions/resume.d.ts +17 -0
- package/packages/host/dist/sessions/resume.js +65 -11
- package/packages/host/dist/sessions/resume.js.map +1 -1
- package/packages/host/dist/sessions/roster.js +3 -0
- package/packages/host/dist/sessions/roster.js.map +1 -1
- package/packages/host/dist/sessions/sidechannel.d.ts +1 -1
- package/packages/host/dist/sessions/sidechannel.js +2 -2
- package/packages/host/dist/sessions/turn.d.ts +15 -58
- package/packages/host/dist/sessions/turn.js +17 -356
- package/packages/host/dist/sessions/turn.js.map +1 -1
- package/packages/host/dist/sessions.d.ts +7 -1
- package/packages/host/dist/sessions.js +22 -13
- package/packages/host/dist/sessions.js.map +1 -1
- package/packages/host/dist/settle.d.ts +6 -0
- package/packages/host/dist/settle.js +26 -21
- package/packages/host/dist/settle.js.map +1 -1
- package/packages/host/dist/setupprefs.d.ts +26 -1
- package/packages/host/dist/setupprefs.js +49 -1
- package/packages/host/dist/setupprefs.js.map +1 -1
- package/packages/host/dist/sidecar/sidecarname.d.ts +2 -0
- package/packages/host/dist/sidecar/sidecarname.js +5 -1
- package/packages/host/dist/sidecar/sidecarname.js.map +1 -1
- package/packages/host/dist/sidecar/sidecarroute.d.ts +1 -1
- package/packages/host/dist/sidecar/sidecarroute.js +5 -0
- package/packages/host/dist/sidecar/sidecarroute.js.map +1 -1
- package/packages/host/dist/sidecar.d.ts +1 -1
- package/packages/host/dist/sidecar.js +1 -1
- package/packages/host/dist/sidecar.js.map +1 -1
- package/packages/host/dist/tokenscan.d.ts +4 -0
- package/packages/host/dist/tokenscan.js +6 -1
- package/packages/host/dist/tokenscan.js.map +1 -1
- package/packages/host/dist/tokenstats.js +3 -1
- package/packages/host/dist/tokenstats.js.map +1 -1
- package/packages/host/dist/transcript/transcriptparse.js +6 -1
- package/packages/host/dist/transcript/transcriptparse.js.map +1 -1
- package/packages/host/dist/transcript/transcriptturns.d.ts +29 -0
- package/packages/host/dist/transcript/transcriptturns.js +27 -0
- package/packages/host/dist/transcript/transcriptturns.js.map +1 -1
- package/packages/host/dist/transcript.d.ts +1 -1
- package/packages/host/dist/transcript.js +1 -1
- package/packages/host/dist/transcript.js.map +1 -1
- package/packages/host/dist/usagesources.d.ts +1 -1
- package/packages/host/dist/usagesources.js +7 -2
- package/packages/host/dist/usagesources.js.map +1 -1
- package/packages/host/dist/weekburn.d.ts +75 -0
- package/packages/host/dist/weekburn.js +251 -0
- package/packages/host/dist/weekburn.js.map +1 -0
- package/packages/host/dist/worktreeleftover.d.ts +9 -0
- package/packages/host/dist/worktreeleftover.js +17 -1
- package/packages/host/dist/worktreeleftover.js.map +1 -1
- package/packages/web/dist/assets/demo-C1GHaeTv.js +23 -0
- package/packages/web/dist/assets/icons-DlcvcZoo.js +1 -0
- package/packages/web/dist/assets/index-BBc6xwDA.css +1 -0
- package/packages/web/dist/assets/index-DzQKnksZ.js +169 -0
- package/packages/web/dist/assets/shared-Cl34umPA.js +47 -0
- package/packages/web/dist/assets/{sheets-Bjv2L-cG.css → sheets-DoUhPGK0.css} +1 -1
- package/packages/web/dist/assets/sheets-_3_SvXAx.js +220 -0
- package/packages/web/dist/build-id.txt +1 -1
- package/packages/web/dist/buildstamp.json +1 -0
- package/packages/web/dist/index.html +7 -7
- package/packages/web/dist/sw.js +14 -3
- package/release.json +7 -4
- package/packages/web/dist/assets/demo-CXlqlYE4.js +0 -23
- package/packages/web/dist/assets/icons-BbqDBVjw.js +0 -1
- package/packages/web/dist/assets/index-CgPoyb3Y.css +0 -1
- package/packages/web/dist/assets/index-D5JKj8DK.js +0 -169
- package/packages/web/dist/assets/shared-eyaskl5l.js +0 -47
- package/packages/web/dist/assets/sheets-BzzL2re1.js +0 -204
|
@@ -72,606 +72,12 @@
|
|
|
72
72
|
* the file.
|
|
73
73
|
*/
|
|
74
74
|
/** The five baskets the score reads, in the order the body names them. */
|
|
75
|
-
export
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
* (`contextweight.ts`): the setup sheet calls a repo lean under it, so the index
|
|
84
|
-
* must not call the same repo unhealthy.
|
|
85
|
-
*/
|
|
86
|
-
export const HEALTH_GOOD = {
|
|
87
|
-
/** Line-weighted mean file length, lines. */
|
|
88
|
-
lineMean: 500,
|
|
89
|
-
/** Longest source file, lines. */
|
|
90
|
-
max: 1_000,
|
|
91
|
-
/** Share of source-file edits that rework the previous edit. Provisional. */
|
|
92
|
-
retouch: 0.15,
|
|
93
|
-
/** UNEXPLAINED escape hatches per 1,000 source lines. */
|
|
94
|
-
hatches: 2.0,
|
|
95
|
-
/** Share of source files no test reaches. */
|
|
96
|
-
untested: 0.2,
|
|
97
|
-
};
|
|
98
|
-
/** Context's good line, as a share of the repo's warn line: all of it — the setup sheet calibrated
|
|
99
|
-
* that line so a well-organised repo is NOT flagged; half of it made the two disagree on one number. */
|
|
100
|
-
export const HEALTH_CONTEXT_GOOD_SHARE = 1.0;
|
|
101
|
-
/** The headline never sits more than this many points above its worst entry. */
|
|
102
|
-
export const HEALTH_SCORE_CAP_GAP = 30;
|
|
103
|
-
/** An entry scoring under this is a `warn` alert… */
|
|
104
|
-
export const HEALTH_ALERT_WARN = 50;
|
|
105
|
-
/** …and under this a `severe` one. */
|
|
106
|
-
export const HEALTH_ALERT_SEVERE = 25;
|
|
107
|
-
/** Links of history needed before a move is called at all. */
|
|
108
|
-
export const HEALTH_INDEX_MIN_WEEKS = 8;
|
|
109
|
-
/** Prior rolling four-week windows needed before a MONTH move is called. */
|
|
110
|
-
export const HEALTH_INDEX_MIN_MONTH_WINDOWS = 4;
|
|
111
|
-
/** Width of the month horizon, in weekly points. */
|
|
112
|
-
export const HEALTH_INDEX_MONTH_WEEKS = 4;
|
|
113
|
-
/** A move must sit below this percentile of its own past to be a drop… */
|
|
114
|
-
export const HEALTH_INDEX_LOW_PCT = 10;
|
|
115
|
-
/** …or above this one to be a rise. */
|
|
116
|
-
export const HEALTH_INDEX_HIGH_PCT = 90;
|
|
117
|
-
/** …AND move the score by at least this many points. */
|
|
118
|
-
export const HEALTH_INDEX_MIN_POINTS = 2;
|
|
119
|
-
/**
|
|
120
|
-
* The context-weight warn line when the repo has none of its own: the setup
|
|
121
|
-
* checklist's `DEFAULT_CONTEXT_LIMITS.maxChars` (`contextweight.ts`), restated
|
|
122
|
-
* as a literal so this module carries no import cycle through the index.
|
|
123
|
-
* Pinned equal to it by the test.
|
|
124
|
-
*/
|
|
125
|
-
export const HEALTH_INDEX_DEFAULT_WARN_CHARS = 16_000;
|
|
126
|
-
/** The engine's `context.reason` for a tree with no CLAUDE.md (`metrics/context.mjs`; a tools test pins the two equal). */
|
|
127
|
-
export const HEALTH_NO_CLAUDE_MD = "no CLAUDE.md at this commit";
|
|
128
|
-
const posFinite = (v) => typeof v === "number" && Number.isFinite(v) && v > 0;
|
|
129
|
-
const nonNegFinite = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
|
|
130
|
-
/** `100 · min(1, good / value)`; a value at or under 0 is 100. */
|
|
131
|
-
export function healthScore(value, good) {
|
|
132
|
-
return value <= 0 ? 100 : 100 * Math.min(1, good / value);
|
|
133
|
-
}
|
|
134
|
-
/** The Monday (UTC) of the ISO week holding `day` (`YYYY-MM-DD`), or null for a malformed day. */
|
|
135
|
-
export function isoWeekOf(day) {
|
|
136
|
-
if (typeof day !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(day))
|
|
137
|
-
return null;
|
|
138
|
-
const t = Date.parse(`${day}T00:00:00Z`);
|
|
139
|
-
if (!Number.isFinite(t))
|
|
140
|
-
return null;
|
|
141
|
-
const dow = (new Date(t).getUTCDay() + 6) % 7; // Monday = 0
|
|
142
|
-
return new Date(t - dow * 86_400_000).toISOString().slice(0, 10);
|
|
143
|
-
}
|
|
144
|
-
/** The last row (greatest `ts`) of each ISO week, oldest week first. */
|
|
145
|
-
export function healthWeeks(rows) {
|
|
146
|
-
const byWeek = new Map();
|
|
147
|
-
for (const r of rows) {
|
|
148
|
-
if (!r || typeof r.ts !== "number")
|
|
149
|
-
continue;
|
|
150
|
-
const week = isoWeekOf(r.day);
|
|
151
|
-
if (!week)
|
|
152
|
-
continue;
|
|
153
|
-
const prev = byWeek.get(week);
|
|
154
|
-
if (!prev || r.ts >= prev.ts)
|
|
155
|
-
byWeek.set(week, r);
|
|
156
|
-
}
|
|
157
|
-
return [...byWeek.entries()].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)).map(([week, row]) => ({ week, row }));
|
|
158
|
-
}
|
|
159
|
-
/** The good line of the context entry for a repo's warn line (null = the default). */
|
|
160
|
-
export function healthContextGood(contextWarnChars) {
|
|
161
|
-
return HEALTH_CONTEXT_GOOD_SHARE * (posFinite(contextWarnChars) ? contextWarnChars : HEALTH_INDEX_DEFAULT_WARN_CHARS);
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* One week's values, raw (no epsilon, no floor — `min(1, good/value)` is
|
|
165
|
-
* finite for any value ≥ 0); an entry is absent where its reading is.
|
|
166
|
-
*
|
|
167
|
-
* - `size` is `lineMean` and needs `max` beside it; either missing ⇒ absent.
|
|
168
|
-
* - `untested` is a SHARE: `untested.count / classics.files` — the source-file
|
|
169
|
-
* count of the same tree, which counts test files too, so the share is a
|
|
170
|
-
* floor. A share and not the count, so a repo that grows does not read as
|
|
171
|
-
* slipping just for having more modules.
|
|
172
|
-
* - `hatches` is UNEXPLAINED escapes per kLOC where the row classified them
|
|
173
|
-
* (engine 2026-10-16a on); every occurrence on an older row.
|
|
174
|
-
* - `context` is `claudeMdChars + descChars`; `descChars` null (no counted
|
|
175
|
-
* skills) counts as 0 descriptions.
|
|
176
|
-
*/
|
|
177
|
-
export function healthEntryReadings(row) {
|
|
178
|
-
const values = {};
|
|
179
|
-
let max;
|
|
180
|
-
const sz = row.size?.value;
|
|
181
|
-
// `max` is read on its own: an override REPLACES lineMean and keeps the
|
|
182
|
-
// engine's max, so it must not depend on the engine's lineMean being there.
|
|
183
|
-
// Where `max` is absent size is absent on BOTH paths (an override cannot
|
|
184
|
-
// invent the longest file); where only lineMean is absent, size is absent
|
|
185
|
-
// without an override and the override's value stands with the engine's max.
|
|
186
|
-
// A `max` left without a size value is dropped at the end.
|
|
187
|
-
if (sz && nonNegFinite(sz.max)) {
|
|
188
|
-
max = { value: sz.max, path: typeof sz.maxPath === "string" && sz.maxPath ? sz.maxPath : null };
|
|
189
|
-
}
|
|
190
|
-
if (sz && nonNegFinite(sz.lineMean) && max)
|
|
191
|
-
values.size = sz.lineMean;
|
|
192
|
-
const rate = row.retouch?.value?.rate;
|
|
193
|
-
if (nonNegFinite(rate))
|
|
194
|
-
values.retouch = rate;
|
|
195
|
-
const h = row.hatches;
|
|
196
|
-
const loc = row.classics?.value?.loc;
|
|
197
|
-
if (h?.value && typeof h.value === "object" && posFinite(loc)) {
|
|
198
|
-
let total = 0;
|
|
199
|
-
let ok = true;
|
|
200
|
-
if (h.split && typeof h.split === "object") {
|
|
201
|
-
if (nonNegFinite(h.split.unexplained))
|
|
202
|
-
total = h.split.unexplained;
|
|
203
|
-
else
|
|
204
|
-
ok = false;
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
for (const v of Object.values(h.value)) {
|
|
208
|
-
if (!nonNegFinite(v)) {
|
|
209
|
-
ok = false;
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
total += v;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
if (ok)
|
|
216
|
-
values.hatches = total / (loc / 1000);
|
|
217
|
-
}
|
|
218
|
-
const ctx = row.context?.value;
|
|
219
|
-
const md = ctx?.claudeMdChars;
|
|
220
|
-
const desc = ctx?.descChars;
|
|
221
|
-
// No CLAUDE.md is nothing the repo loads every turn: 0, on the engine's exact words (its skills go unmeasured then).
|
|
222
|
-
if (!ctx && row.context?.reason === HEALTH_NO_CLAUDE_MD)
|
|
223
|
-
values.context = 0;
|
|
224
|
-
else if (nonNegFinite(md) && (desc === null || desc === undefined || nonNegFinite(desc)))
|
|
225
|
-
values.context = md + (typeof desc === "number" ? desc : 0);
|
|
226
|
-
const list = row.untested?.value;
|
|
227
|
-
const files = row.classics?.value?.files;
|
|
228
|
-
if (Array.isArray(list) && posFinite(files) && list.length <= files) {
|
|
229
|
-
values.untested = list.length / files;
|
|
230
|
-
}
|
|
231
|
-
// The repo's own say (`central`): a disabled entry is not in the basket at
|
|
232
|
-
// all; an override REPLACES the engine's value (for size, `lineMean` — the
|
|
233
|
-
// longest file stays measured), and a failed override is absent — never the
|
|
234
|
-
// engine's number standing in for the repo's.
|
|
235
|
-
const c = centralOf(row);
|
|
236
|
-
for (const e of c.disabled) {
|
|
237
|
-
delete values[e];
|
|
238
|
-
if (e === "size")
|
|
239
|
-
max = undefined;
|
|
240
|
-
}
|
|
241
|
-
for (const e of c.overridden) {
|
|
242
|
-
delete values[e];
|
|
243
|
-
const v = row.central?.override?.[e]?.value;
|
|
244
|
-
if (!nonNegFinite(v))
|
|
245
|
-
continue;
|
|
246
|
-
if (e === "size" && !max)
|
|
247
|
-
continue;
|
|
248
|
-
values[e] = v;
|
|
249
|
-
}
|
|
250
|
-
if (values.size === undefined)
|
|
251
|
-
max = undefined;
|
|
252
|
-
return max ? { values, max } : { values };
|
|
253
|
-
}
|
|
254
|
-
/** The five values alone — `healthEntryReadings(row).values`. The warn line is not read here any more (scores read it). */
|
|
255
|
-
export function healthEntryValues(row, _contextWarnChars) {
|
|
256
|
-
return healthEntryReadings(row).values;
|
|
257
|
-
}
|
|
258
|
-
const isEntry = (k) => HEALTH_ENTRIES.includes(k);
|
|
259
|
-
/**
|
|
260
|
-
* What the repo applied on this row: its fingerprint and which entries it
|
|
261
|
-
* disabled or overrode. An entry both disabled and overridden reads disabled
|
|
262
|
-
* (the engine never writes both; a hand-edited row must not count twice).
|
|
263
|
-
*/
|
|
264
|
-
export function centralOf(row) {
|
|
265
|
-
const c = row.central;
|
|
266
|
-
if (!c || typeof c !== "object")
|
|
267
|
-
return { fp: "", disabled: [], overridden: [] };
|
|
268
|
-
const fp = typeof c.fp === "string" ? c.fp : "";
|
|
269
|
-
const keysOf = (o) => o && typeof o === "object" ? Object.keys(o).filter(isEntry) : [];
|
|
270
|
-
const disabled = HEALTH_ENTRIES.filter((e) => keysOf(c.disabled).includes(e));
|
|
271
|
-
const overridden = HEALTH_ENTRIES.filter((e) => keysOf(c.override).includes(e) && !disabled.includes(e));
|
|
272
|
-
return { fp, disabled, overridden };
|
|
273
|
-
}
|
|
274
|
-
function treeOf(row) {
|
|
275
|
-
const v = row.classics?.value;
|
|
276
|
-
return v && nonNegFinite(v.files) && nonNegFinite(v.loc) ? { files: v.files, loc: v.loc } : null;
|
|
277
|
-
}
|
|
278
|
-
const DAY_MS = 86_400_000;
|
|
279
|
-
const daysBetween = (a, b) => Math.round((Date.parse(`${b}T00:00:00Z`) - Date.parse(`${a}T00:00:00Z`)) / DAY_MS);
|
|
280
|
-
// ── words: one wording for the phone and VS Code ────────────────────────────
|
|
281
|
-
/** A whole number with thousands separators, locale-free: `8,397`. */
|
|
282
|
-
const commas = (n) => Math.round(n).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
283
|
-
const pct = (x) => `${Math.round(x * 100)}%`;
|
|
284
|
-
const oneDp = (x) => (Math.round(x * 10) / 10).toFixed(1);
|
|
285
|
-
/** Plain names for an entry, as the cap sentence names it. */
|
|
286
|
-
export const HEALTH_ENTRY_LABEL = {
|
|
287
|
-
size: "file length",
|
|
288
|
-
retouch: "re-touches",
|
|
289
|
-
hatches: "escape hatches",
|
|
290
|
-
context: "CLAUDE.md + skill descriptions",
|
|
291
|
-
untested: "untested modules",
|
|
292
|
-
};
|
|
293
|
-
function alertText(level, subject, value, good, path) {
|
|
294
|
-
const body = (() => {
|
|
295
|
-
switch (subject) {
|
|
296
|
-
case "max":
|
|
297
|
-
return `${path ?? "the longest file"} is ${commas(value)} lines (good: under ${commas(good)})`;
|
|
298
|
-
case "lineMean":
|
|
299
|
-
return `the average line sits in a file of ${commas(value)} lines (good: under ${commas(good)})`;
|
|
300
|
-
case "retouch":
|
|
301
|
-
return `${pct(value)} of recent file edits rework the edit before (good: under ${pct(good)})`;
|
|
302
|
-
case "hatches":
|
|
303
|
-
return `${oneDp(value)} unexplained escape hatches per 1,000 lines (good: under ${oneDp(good)})`;
|
|
304
|
-
case "context":
|
|
305
|
-
return `CLAUDE.md + skill descriptions are ${commas(value)} chars (good: under ${commas(good)})`;
|
|
306
|
-
case "untested":
|
|
307
|
-
return `${pct(value)} of source files have no test reaching them (good: under ${pct(good)})`;
|
|
308
|
-
}
|
|
309
|
-
})();
|
|
310
|
-
return `${level}: ${body}`;
|
|
311
|
-
}
|
|
312
|
-
function alertOf(entry, subject, value, good, path) {
|
|
313
|
-
const score = healthScore(value, good);
|
|
314
|
-
if (!(score < HEALTH_ALERT_WARN))
|
|
315
|
-
return null;
|
|
316
|
-
const level = score < HEALTH_ALERT_SEVERE ? "severe" : "warn";
|
|
317
|
-
const p = path ?? undefined;
|
|
318
|
-
return { level, entry, subject, value, good, score, ...(p ? { path: p } : {}), text: alertText(level, subject, value, good, p) };
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* The cap, said once: `null` when the cap did not set the number. The worst
|
|
322
|
-
* entry's score is derived (`value − HEALTH_SCORE_CAP_GAP`), so the wire
|
|
323
|
-
* summary can be worded from its three fields alone.
|
|
324
|
-
*/
|
|
325
|
-
export function healthCapWords(s) {
|
|
326
|
-
if (!s.cappedBy || !(s.value < s.mean))
|
|
327
|
-
return null;
|
|
328
|
-
const worst = Math.round(s.value - HEALTH_SCORE_CAP_GAP);
|
|
329
|
-
return `Capped at ${Math.round(s.value)} by ${HEALTH_ENTRY_LABEL[s.cappedBy]} (${worst} of 100): the entries average ${Math.round(s.mean)}, and the score stays within ${HEALTH_SCORE_CAP_GAP} of its worst entry.`;
|
|
330
|
-
}
|
|
331
|
-
/** One week's score from its readings; null when any enabled entry is absent, or none is enabled. */
|
|
332
|
-
function scoreWeek(r, disabled, contextWarnChars) {
|
|
333
|
-
const enabled = HEALTH_ENTRIES.filter((e) => !disabled.includes(e));
|
|
334
|
-
if (enabled.length === 0 || enabled.some((e) => r.values[e] === undefined))
|
|
335
|
-
return null;
|
|
336
|
-
const ctxGood = healthContextGood(contextWarnChars);
|
|
337
|
-
const scores = {};
|
|
338
|
-
let sizeParts = null;
|
|
339
|
-
const alerts = [];
|
|
340
|
-
for (const e of enabled) {
|
|
341
|
-
const v = r.values[e];
|
|
342
|
-
if (e === "size") {
|
|
343
|
-
const m = r.max;
|
|
344
|
-
sizeParts = {
|
|
345
|
-
lineMean: { value: v, score: healthScore(v, HEALTH_GOOD.lineMean) },
|
|
346
|
-
max: { value: m.value, score: healthScore(m.value, HEALTH_GOOD.max), path: m.path },
|
|
347
|
-
};
|
|
348
|
-
scores.size = Math.sqrt(sizeParts.lineMean.score * sizeParts.max.score);
|
|
349
|
-
// Size alerts on its sub-readings: the blend is under a line only if one
|
|
350
|
-
// of them is, and the sub-reading is what can be named.
|
|
351
|
-
const a1 = alertOf("size", "lineMean", v, HEALTH_GOOD.lineMean);
|
|
352
|
-
const a2 = alertOf("size", "max", m.value, HEALTH_GOOD.max, m.path);
|
|
353
|
-
if (a1)
|
|
354
|
-
alerts.push(a1);
|
|
355
|
-
if (a2)
|
|
356
|
-
alerts.push(a2);
|
|
357
|
-
continue;
|
|
358
|
-
}
|
|
359
|
-
const good = e === "context" ? ctxGood : HEALTH_GOOD[e];
|
|
360
|
-
scores[e] = healthScore(v, good);
|
|
361
|
-
const a = alertOf(e, e, v, good);
|
|
362
|
-
if (a)
|
|
363
|
-
alerts.push(a);
|
|
364
|
-
}
|
|
365
|
-
const n = enabled.length;
|
|
366
|
-
// A score of 0 cannot occur (good > 0, value finite), so ln is finite.
|
|
367
|
-
const mean = Math.exp(enabled.reduce((s, e) => s + Math.log(scores[e]), 0) / n);
|
|
368
|
-
let worst = enabled[0];
|
|
369
|
-
for (const e of enabled)
|
|
370
|
-
if (scores[e] < scores[worst])
|
|
371
|
-
worst = e;
|
|
372
|
-
const capped = scores[worst] + HEALTH_SCORE_CAP_GAP;
|
|
373
|
-
const index = Math.min(mean, capped);
|
|
374
|
-
alerts.sort((a, b) => a.score - b.score);
|
|
375
|
-
return { index, mean, scores, sizeParts, cappedBy: capped < mean ? worst : null, alerts, enabled };
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* The scored series. `null` when no week has every enabled entry — no score
|
|
379
|
-
* is no series, never a number nobody measured.
|
|
380
|
-
*/
|
|
381
|
-
export function healthIndex(rows, contextWarnChars) {
|
|
382
|
-
const points = [];
|
|
383
|
-
for (const { week, row } of healthWeeks(rows)) {
|
|
384
|
-
const c = centralOf(row);
|
|
385
|
-
const readings = healthEntryReadings(row);
|
|
386
|
-
const s = scoreWeek(readings, c.disabled, contextWarnChars);
|
|
387
|
-
if (!s)
|
|
388
|
-
continue;
|
|
389
|
-
const prereg = typeof row.prereg === "string" ? row.prereg : null;
|
|
390
|
-
const prev = points[points.length - 1];
|
|
391
|
-
const base = {
|
|
392
|
-
week, index: s.index, mean: s.mean, scores: s.scores, sizeParts: s.sizeParts,
|
|
393
|
-
cappedBy: s.cappedBy, alerts: s.alerts, values: readings.values, prereg,
|
|
394
|
-
central: c.fp, disabled: c.disabled, overridden: c.overridden, tree: treeOf(row),
|
|
395
|
-
};
|
|
396
|
-
if (!prev) {
|
|
397
|
-
points.push({ ...base, gap: false, lnLink: null, comparable: 0, contributions: {}, spanDays: null });
|
|
398
|
-
continue;
|
|
399
|
-
}
|
|
400
|
-
const spanDays = daysBetween(prev.week, week);
|
|
401
|
-
const gapReason = prev.prereg !== prereg ? "prereg" : prev.central !== c.fp ? "central" : null;
|
|
402
|
-
if (gapReason) {
|
|
403
|
-
points.push({ ...base, gap: true, lnLink: null, comparable: 0, contributions: {}, spanDays, gapReason });
|
|
404
|
-
continue;
|
|
405
|
-
}
|
|
406
|
-
// Same fingerprint ⇒ same enabled set, so every entry is in both weeks.
|
|
407
|
-
const n = s.enabled.length;
|
|
408
|
-
const contributions = {};
|
|
409
|
-
for (const e of s.enabled) {
|
|
410
|
-
const a = prev.scores[e];
|
|
411
|
-
const b = s.scores[e];
|
|
412
|
-
if (a !== undefined && b !== undefined)
|
|
413
|
-
contributions[e] = (prev.mean * (Math.log(b) - Math.log(a))) / n;
|
|
414
|
-
}
|
|
415
|
-
points.push({
|
|
416
|
-
...base, gap: false, lnLink: Math.log(s.index / prev.index), comparable: n, contributions, spanDays,
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
if (points.length === 0)
|
|
420
|
-
return null;
|
|
421
|
-
return { baselineWeek: points[0].week, points };
|
|
422
|
-
}
|
|
423
|
-
/** One row by the SAME formula a week uses (`scoreWeek`); null when an enabled entry is absent. */
|
|
424
|
-
export function healthRowScore(row, contextWarnChars) {
|
|
425
|
-
const s = scoreWeek(healthEntryReadings(row), centralOf(row).disabled, contextWarnChars);
|
|
426
|
-
return s ? { index: s.index, mean: s.mean, scores: s.scores, cappedBy: s.cappedBy } : null;
|
|
427
|
-
}
|
|
428
|
-
/** Thin to ~`max`: each ISO week's LAST point stays; `ceil(n/max)`-long runs keep their min and max index. At most 2*max + weeks. */
|
|
429
|
-
export function thinCommitPoints(points, max) {
|
|
430
|
-
if (points.length <= max)
|
|
431
|
-
return [...points];
|
|
432
|
-
const keep = new Set();
|
|
433
|
-
const lastOfWeek = new Map();
|
|
434
|
-
points.forEach((p, i) => lastOfWeek.set(p.week, i));
|
|
435
|
-
for (const i of lastOfWeek.values())
|
|
436
|
-
keep.add(i);
|
|
437
|
-
const run = Math.ceil(points.length / Math.max(1, max));
|
|
438
|
-
for (let a = 0; a < points.length; a += run) {
|
|
439
|
-
let lo = a, hi = a;
|
|
440
|
-
const end = Math.min(points.length, a + run);
|
|
441
|
-
for (let i = a; i < end; i++) {
|
|
442
|
-
if (points[i].index < points[lo].index)
|
|
443
|
-
lo = i;
|
|
444
|
-
if (points[i].index > points[hi].index)
|
|
445
|
-
hi = i;
|
|
446
|
-
}
|
|
447
|
-
keep.add(lo);
|
|
448
|
-
keep.add(hi);
|
|
449
|
-
}
|
|
450
|
-
return [...keep].sort((x, y) => x - y).map((i) => points[i]);
|
|
451
|
-
}
|
|
452
|
-
/** Every scorable row as a commit point, thinned to about `max`; `null` when no row scores. */
|
|
453
|
-
export function healthIndexCommits(rows, contextWarnChars, max = 240) {
|
|
454
|
-
const sorted = rows.filter((r) => r && typeof r.ts === "number").sort((a, b) => a.ts - b.ts);
|
|
455
|
-
const all = [];
|
|
456
|
-
let prev = null;
|
|
457
|
-
for (const row of sorted) {
|
|
458
|
-
const week = isoWeekOf(row.day);
|
|
459
|
-
const s = week ? healthRowScore(row, contextWarnChars) : null;
|
|
460
|
-
if (!week || !s)
|
|
461
|
-
continue;
|
|
462
|
-
const prereg = typeof row.prereg === "string" ? row.prereg : null;
|
|
463
|
-
const central = centralOf(row).fp;
|
|
464
|
-
all.push({
|
|
465
|
-
sha7: typeof row.sha === "string" ? row.sha.slice(0, 7) : "",
|
|
466
|
-
day: row.day, ts: row.ts, week, index: s.index, mean: s.mean, cappedBy: s.cappedBy,
|
|
467
|
-
gap: prev !== null && (prev.prereg !== prereg || prev.central !== central),
|
|
468
|
-
});
|
|
469
|
-
prev = { prereg, central };
|
|
470
|
-
}
|
|
471
|
-
if (all.length === 0)
|
|
472
|
-
return null;
|
|
473
|
-
const points = thinCommitPoints(all, max);
|
|
474
|
-
return { points, total: all.length, thinned: points.length < all.length };
|
|
475
|
-
}
|
|
476
|
-
/** `absent` = an older host (no key), `none` = the host looked and nothing scores, else `present`. */
|
|
477
|
-
export function healthCommitsAvailability(view) {
|
|
478
|
-
if (!view || view.commits === undefined)
|
|
479
|
-
return "absent";
|
|
480
|
-
return view.commits && view.commits.points.length > 0 ? "present" : "none";
|
|
481
|
-
}
|
|
482
|
-
/** How far back "vs 12 weeks ago" looks, in weeks. */
|
|
483
|
-
export const HEALTH_INDEX_VS_WEEKS = 12;
|
|
484
|
-
/**
|
|
485
|
-
* "Vs 12 weeks ago": the score at `points[at]` (default the latest) against
|
|
486
|
-
* the LATEST measured point at least `weeks` earlier — however much further
|
|
487
|
-
* back that is, because a week with no commit has no row and the honest
|
|
488
|
-
* comparison names the week it actually used (`then.week`, `weeks`). Null
|
|
489
|
-
* only when no point sits that far back (a series younger than the horizon).
|
|
490
|
-
*
|
|
491
|
-
* Both ends are absolute scores, so the ratio is simply the two numbers —
|
|
492
|
-
* including any prereg or `central` change between them (the point's `gap`
|
|
493
|
-
* says one happened; the caller decides whether to say so).
|
|
494
|
-
*/
|
|
495
|
-
export function healthIndexVs(points, weeks = HEALTH_INDEX_VS_WEEKS, at = points.length - 1) {
|
|
496
|
-
const now = points[at];
|
|
497
|
-
if (!now || !(weeks > 0) || !Number.isFinite(now.index))
|
|
498
|
-
return null;
|
|
499
|
-
const nowT = Date.parse(`${now.week}T00:00:00Z`);
|
|
500
|
-
const target = nowT - weeks * 7 * DAY_MS;
|
|
501
|
-
for (let i = at - 1; i >= 0; i--) {
|
|
502
|
-
const t = Date.parse(`${points[i].week}T00:00:00Z`);
|
|
503
|
-
if (t > target)
|
|
504
|
-
continue;
|
|
505
|
-
const then = points[i];
|
|
506
|
-
if (!(then.index > 0))
|
|
507
|
-
return null;
|
|
508
|
-
return {
|
|
509
|
-
ratio: now.index / then.index,
|
|
510
|
-
delta: now.index - then.index,
|
|
511
|
-
then,
|
|
512
|
-
now,
|
|
513
|
-
weeks: Math.round((nowT - t) / (7 * DAY_MS)),
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
return null;
|
|
517
|
-
}
|
|
518
|
-
/** Linear-interpolated percentile (0–100) of a non-empty list. */
|
|
519
|
-
function percentile(xs, p) {
|
|
520
|
-
const s = [...xs].sort((a, b) => a - b);
|
|
521
|
-
const pos = (p / 100) * (s.length - 1);
|
|
522
|
-
const lo = Math.floor(pos);
|
|
523
|
-
const hi = Math.ceil(pos);
|
|
524
|
-
return s[lo] + (s[hi] - s[lo]) * (pos - lo);
|
|
525
|
-
}
|
|
526
|
-
/**
|
|
527
|
-
* Whether the latest move is unusual for THIS repo: the week's link against
|
|
528
|
-
* the distribution of every earlier link, then (only if the week says nothing)
|
|
529
|
-
* the last four weeks against every earlier rolling four-week change. Both
|
|
530
|
-
* need the percentile AND a minimum number of points, so a dead-flat series
|
|
531
|
-
* cannot call a 0.1-point wobble a drop. Under `HEALTH_INDEX_MIN_WEEKS` links
|
|
532
|
-
* of history there is no distribution to stand on: `kind: null`, with why.
|
|
533
|
-
*/
|
|
534
|
-
export function assessHealthMove(points, opts = {}) {
|
|
535
|
-
const minWeeks = opts.minWeeks ?? HEALTH_INDEX_MIN_WEEKS;
|
|
536
|
-
const minMonth = opts.minMonthWindows ?? HEALTH_INDEX_MIN_MONTH_WINDOWS;
|
|
537
|
-
const lowPct = opts.lowPct ?? HEALTH_INDEX_LOW_PCT;
|
|
538
|
-
const highPct = opts.highPct ?? HEALTH_INDEX_HIGH_PCT;
|
|
539
|
-
const minPts = opts.minPoints ?? HEALTH_INDEX_MIN_POINTS;
|
|
540
|
-
const none = (reason, horizon = null, delta = null) => ({ kind: null, horizon, delta, reason });
|
|
541
|
-
const last = points[points.length - 1];
|
|
542
|
-
if (!last)
|
|
543
|
-
return none("no index yet");
|
|
544
|
-
const links = points.filter((p) => p.lnLink !== null);
|
|
545
|
-
if (links.length < minWeeks) {
|
|
546
|
-
return none(`${links.length} weekly link${links.length === 1 ? "" : "s"} so far; a move is called after ${minWeeks}`);
|
|
547
|
-
}
|
|
548
|
-
// Week: only when the latest point IS a link — a carried week moved nothing.
|
|
549
|
-
if (last.lnLink !== null) {
|
|
550
|
-
const prior = links.slice(0, -1).map((p) => p.lnLink);
|
|
551
|
-
const prevIndex = points[points.length - 2].index;
|
|
552
|
-
const delta = last.index - prevIndex;
|
|
553
|
-
if (last.lnLink < percentile(prior, lowPct) && -delta >= minPts) {
|
|
554
|
-
return { kind: "drop", horizon: "week", delta, reason: `the latest week's link sits below the ${lowPct}th percentile of ${prior.length} earlier weeks` };
|
|
555
|
-
}
|
|
556
|
-
if (last.lnLink > percentile(prior, highPct) && delta >= minPts) {
|
|
557
|
-
return { kind: "rise", horizon: "week", delta, reason: `the latest week's link sits above the ${highPct}th percentile of ${prior.length} earlier weeks` };
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
// Month: ln(index_t / index_{t-4}) against every earlier rolling window.
|
|
561
|
-
const W = HEALTH_INDEX_MONTH_WEEKS;
|
|
562
|
-
const t = points.length - 1;
|
|
563
|
-
if (t < W)
|
|
564
|
-
return none("too few weeks for a four-week reading");
|
|
565
|
-
// A window that spans a `gap` point compares two scores measured under
|
|
566
|
-
// different definitions: it is not a move. Skipped as history, and when the
|
|
567
|
-
// current window is one, no month move is called at all.
|
|
568
|
-
const spansGap = (j) => {
|
|
569
|
-
for (let k = j - W + 1; k <= j; k++)
|
|
570
|
-
if (points[k].gap)
|
|
571
|
-
return true;
|
|
572
|
-
return false;
|
|
573
|
-
};
|
|
574
|
-
if (spansGap(t))
|
|
575
|
-
return none("the last four weeks span a change of definition, so there is no month move to compare");
|
|
576
|
-
const windows = [];
|
|
577
|
-
for (let j = W; j < t; j++)
|
|
578
|
-
if (!spansGap(j))
|
|
579
|
-
windows.push(Math.log(points[j].index / points[j - W].index));
|
|
580
|
-
const monthDelta = last.index - points[t - W].index;
|
|
581
|
-
if (windows.length < minMonth) {
|
|
582
|
-
return none(`${windows.length} earlier four-week window${windows.length === 1 ? "" : "s"}; a month move is called after ${minMonth}`);
|
|
583
|
-
}
|
|
584
|
-
const ln = Math.log(last.index / points[t - W].index);
|
|
585
|
-
if (ln < percentile(windows, lowPct) && -monthDelta >= minPts) {
|
|
586
|
-
return { kind: "drop", horizon: "month", delta: monthDelta, reason: `the last four weeks sit below the ${lowPct}th percentile of ${windows.length} earlier four-week windows` };
|
|
587
|
-
}
|
|
588
|
-
if (ln > percentile(windows, highPct) && monthDelta >= minPts) {
|
|
589
|
-
return { kind: "rise", horizon: "month", delta: monthDelta, reason: `the last four weeks sit above the ${highPct}th percentile of ${windows.length} earlier four-week windows` };
|
|
590
|
-
}
|
|
591
|
-
return none("within this repo's usual range", null, last.lnLink !== null ? last.index - points[t - 1].index : null);
|
|
592
|
-
}
|
|
593
|
-
/** Plain names for an entry's move: [0] when its metric rose (its score fell), [1] when it fell. */
|
|
594
|
-
const ENTRY_WORDS = {
|
|
595
|
-
size: ["files grew longer", "files got shorter"],
|
|
596
|
-
retouch: ["more re-touched files", "fewer re-touched files"],
|
|
597
|
-
hatches: ["more escape hatches", "fewer escape hatches"],
|
|
598
|
-
context: ["CLAUDE.md + skill descriptions grew", "CLAUDE.md + skill descriptions shrank"],
|
|
599
|
-
untested: ["more untested modules", "fewer untested modules"],
|
|
600
|
-
};
|
|
601
|
-
/** A signed whole number with a real minus sign: `−4`, `+3`, `±0`. */
|
|
602
|
-
export function signedPoints(n) {
|
|
603
|
-
const r = Math.round(n);
|
|
604
|
-
if (r === 0)
|
|
605
|
-
return "±0";
|
|
606
|
-
return r < 0 ? `−${-r}` : `+${r}`;
|
|
607
|
-
}
|
|
608
|
-
/**
|
|
609
|
-
* When the latest measured week happened, worded against the week it is now:
|
|
610
|
-
* `this week` only when they are the same ISO week — a week with no commit has
|
|
611
|
-
* no point, so the newest one can be months old — else `in the week of <Monday>`.
|
|
612
|
-
* `currentWeek` absent = the caller did not say, and the claim falls back to
|
|
613
|
-
* naming the week (never a `this week` nobody checked).
|
|
614
|
-
*/
|
|
615
|
-
export function healthWeekWhen(week, currentWeek) {
|
|
616
|
-
return currentWeek && week === currentWeek ? "this week" : `in the week of ${week}`;
|
|
617
|
-
}
|
|
618
|
-
/**
|
|
619
|
-
* The notification and chip wording for a called move. `null` when there is
|
|
620
|
-
* nothing to say (no move called, or no points) — a sentence is never written
|
|
621
|
-
* around a null. `currentWeek` (the ISO week's Monday, `isoWeekOf(today)`)
|
|
622
|
-
* decides whether the latest point may be called "this week".
|
|
623
|
-
*/
|
|
624
|
-
export function healthMoveWords(points, move, currentWeek) {
|
|
625
|
-
const last = points[points.length - 1];
|
|
626
|
-
if (!last || !move.kind || !move.horizon || move.delta === null)
|
|
627
|
-
return null;
|
|
628
|
-
const value = Math.round(last.index);
|
|
629
|
-
const span = move.horizon === "week" ? 1 : HEALTH_INDEX_MONTH_WEEKS;
|
|
630
|
-
const latest = currentWeek && last.week === currentWeek;
|
|
631
|
-
const when = move.horizon === "week"
|
|
632
|
-
? healthWeekWhen(last.week, currentWeek)
|
|
633
|
-
: latest ? "over four weeks" : `over the four weeks to ${last.week}`;
|
|
634
|
-
const sums = {};
|
|
635
|
-
for (const p of points.slice(-span)) {
|
|
636
|
-
for (const e of HEALTH_ENTRIES) {
|
|
637
|
-
const c = p.contributions[e];
|
|
638
|
-
if (c !== undefined)
|
|
639
|
-
sums[e] = (sums[e] ?? 0) + c;
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
const sign = move.kind === "drop" ? -1 : 1;
|
|
643
|
-
const top = HEALTH_ENTRIES
|
|
644
|
-
.filter((e) => (sums[e] ?? 0) * sign > 0)
|
|
645
|
-
.sort((a, b) => Math.abs(sums[b] ?? 0) - Math.abs(sums[a] ?? 0))
|
|
646
|
-
.slice(0, 2)
|
|
647
|
-
.map((e) => `${ENTRY_WORDS[e][move.kind === "drop" ? 0 : 1]} (${signedPoints(sums[e] ?? 0)})`);
|
|
648
|
-
const verb = move.kind === "drop" ? "slipped" : "rose";
|
|
649
|
-
const pts = Math.abs(Math.round(move.delta));
|
|
650
|
-
const body = top.length
|
|
651
|
-
? `The score ${verb} ${pts} point${pts === 1 ? "" : "s"} ${when}: ${top.join(", ")}.`
|
|
652
|
-
: `The score ${verb} ${pts} point${pts === 1 ? "" : "s"} ${when}.`;
|
|
653
|
-
return {
|
|
654
|
-
chip: `Health ${value} ${signedPoints(move.delta)}`,
|
|
655
|
-
title: `Health score ${value} (${signedPoints(move.delta)} ${when})`,
|
|
656
|
-
body,
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
|
-
/** The wire summary for one repo, or null where there is no index (the field stays ABSENT, never 0). */
|
|
660
|
-
export function repoHealthIndexOf(series, move) {
|
|
661
|
-
const pts = series?.points;
|
|
662
|
-
const last = pts?.[pts.length - 1];
|
|
663
|
-
if (!pts || !last)
|
|
664
|
-
return null;
|
|
665
|
-
const prev = pts[pts.length - 2];
|
|
666
|
-
return {
|
|
667
|
-
value: last.index,
|
|
668
|
-
deltaWeek: last.lnLink !== null && prev ? last.index - prev.index : null,
|
|
669
|
-
week: last.week,
|
|
670
|
-
move: move?.kind ?? null,
|
|
671
|
-
mean: last.mean,
|
|
672
|
-
cappedBy: last.cappedBy,
|
|
673
|
-
alert: last.alerts[0]?.level ?? null,
|
|
674
|
-
alertText: last.alerts[0]?.text ?? null,
|
|
675
|
-
};
|
|
676
|
-
}
|
|
75
|
+
export { HEALTH_ENTRIES, HEALTH_GOOD, HEALTH_CONTEXT_GOOD_SHARE, HEALTH_SCORE_CAP_GAP, HEALTH_ALERT_WARN, HEALTH_ALERT_SEVERE, HEALTH_INDEX_MIN_WEEKS, HEALTH_INDEX_MIN_MONTH_WINDOWS, HEALTH_INDEX_MONTH_WEEKS, HEALTH_INDEX_LOW_PCT, HEALTH_INDEX_HIGH_PCT, HEALTH_INDEX_MIN_POINTS, HEALTH_INDEX_DEFAULT_WARN_CHARS, HEALTH_NO_CLAUDE_MD, } from "./healthindex/types.js";
|
|
76
|
+
export { healthScore, isoWeekOf, healthWeeks, healthContextGood, healthEntryReadings, healthEntryValues, centralOf, } from "./healthindex/readings.js";
|
|
77
|
+
export { HEALTH_ENTRY_LABEL, healthCapWords, healthIndex, healthRowScore, } from "./healthindex/score.js";
|
|
78
|
+
export { thinCommitPoints, healthIndexCommits, healthCommitsAvailability, } from "./healthindex/commits.js";
|
|
79
|
+
export { HEALTH_INDEX_VS_WEEKS, healthIndexVs, } from "./healthindex/vs.js";
|
|
80
|
+
export { assessHealthMove, } from "./healthindex/move.js";
|
|
81
|
+
export { signedPoints, healthWeekWhen, healthMoveWords, } from "./healthindex/words.js";
|
|
82
|
+
export { repoHealthIndexOf, } from "./healthindex/repoindex.js";
|
|
677
83
|
//# sourceMappingURL=healthindex.js.map
|