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
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **Which exposure findings earn a push, and which keys the host must remember.** The watch's
|
|
3
|
+
* promise (proposal §2-3): an ALERT is a push the same day, one per new finding, keyed
|
|
4
|
+
* (repo, measure, subject, version). Pure, no clock but the `now` handed in, no file reads — the
|
|
5
|
+
* host (`exposurepush.ts`) owns the store and the sending.
|
|
6
|
+
*
|
|
7
|
+
* - **Pushed once FOREVER.** The remembered set is never pruned: an accept that lapses, or a
|
|
8
|
+
* finding that clears and comes back with the same key, does not push a second time.
|
|
9
|
+
* - **Seeding is silent, per repo.** The store carries a `repos` marker: the first time the sweep
|
|
10
|
+
* sees a repo as WATCHED (first run, late add, re-add, missed runs, no store at all) it remembers
|
|
11
|
+
* that repo's alert keys, pushes none, and marks the repo. Only a marked repo pushes new keys.
|
|
12
|
+
* - **Only open alerts.** `digest` findings and accepted ones (`applyAccepts`, the one reader of an
|
|
13
|
+
* accept) are neither pushed nor remembered, so a digest finding is never "spent".
|
|
14
|
+
* - **Up to {@link EXPOSURE_PUSH_CAP} pushes per repo per sweep**, one per finding; more than that
|
|
15
|
+
* is ONE push naming the count, and every key is remembered.
|
|
16
|
+
*/
|
|
17
|
+
import { applyAccepts, applyTriage } from "./exposure.js";
|
|
18
|
+
export const EXPOSURE_PUSH_CAP = 3;
|
|
19
|
+
/** The dedupe key: (repo, finding.key, version), `\u0000`-joined so no field can fake another.
|
|
20
|
+
* `finding.key` already carries the advisory id and the subject. */
|
|
21
|
+
export const exposurePushKey = (repo, f) => `${repo}\u0000${f.key}\u0000${f.version ?? ""}`;
|
|
22
|
+
/** The attention key of one finding's push, and of a repo's summary push. */
|
|
23
|
+
export const exposureAttentionKey = (repo, findingKey) => `exposure:${repo}:${findingKey}`;
|
|
24
|
+
export const exposureSummaryKey = (repo) => `exposure:${repo}`;
|
|
25
|
+
const LOUD = ["critical", "high"];
|
|
26
|
+
const isLoud = (f) => !!f.severity && LOUD.includes(f.severity);
|
|
27
|
+
export function exposurePushes(series, watched, pushed, now) {
|
|
28
|
+
const push = [];
|
|
29
|
+
const remember = new Set();
|
|
30
|
+
const seenRepos = new Set();
|
|
31
|
+
const resolve = new Set();
|
|
32
|
+
for (const { row, accepts, triage, unreadable } of series) {
|
|
33
|
+
// One repo's bad data must not abort every other repo's pass: it is skipped, nothing remembered for it.
|
|
34
|
+
try {
|
|
35
|
+
if (!row || typeof row.dir !== "string" || typeof row.repo !== "string" || !watched(row.dir))
|
|
36
|
+
continue;
|
|
37
|
+
if (unreadable)
|
|
38
|
+
continue; // nothing is known: push nothing, remember nothing
|
|
39
|
+
const alerts = (Array.isArray(row.findings) ? row.findings : []).filter((f) => f?.level === "alert");
|
|
40
|
+
if (row.firstRun || !pushed.repos.has(row.repo)) {
|
|
41
|
+
for (const f of alerts) {
|
|
42
|
+
const k = exposurePushKey(row.repo, f);
|
|
43
|
+
if (!pushed.keys.has(k))
|
|
44
|
+
remember.add(k);
|
|
45
|
+
}
|
|
46
|
+
if (!pushed.repos.has(row.repo))
|
|
47
|
+
seenRepos.add(row.repo);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const open = applyTriage(applyAccepts(alerts, accepts, now), triage).filter((f) => !f.accepted);
|
|
51
|
+
// Resolve what is no longer open: every remembered key of this repo whose finding is gone.
|
|
52
|
+
const openKeys = new Set(open.map((f) => f.key));
|
|
53
|
+
const prefix = `${row.repo}\u0000`;
|
|
54
|
+
for (const k of pushed.keys) {
|
|
55
|
+
if (!k.startsWith(prefix))
|
|
56
|
+
continue;
|
|
57
|
+
const fk = k.slice(prefix.length).split("\u0000")[0];
|
|
58
|
+
if (!openKeys.has(fk))
|
|
59
|
+
resolve.add(exposureAttentionKey(row.repo, fk));
|
|
60
|
+
}
|
|
61
|
+
if (!open.length)
|
|
62
|
+
resolve.add(exposureSummaryKey(row.repo));
|
|
63
|
+
const seen = new Set();
|
|
64
|
+
const fresh = open.filter((f) => {
|
|
65
|
+
// seen / investigating hold back growth in the SAME app version; a different one reporting the group pushes.
|
|
66
|
+
// A mark with no recorded version holds by key, as before.
|
|
67
|
+
if (f.triage && (f.triage.state === "seen" || f.triage.state === "investigating")
|
|
68
|
+
&& !(f.triage.markedVersion && f.appVersion && f.triage.markedVersion !== f.appVersion))
|
|
69
|
+
return false;
|
|
70
|
+
const k = exposurePushKey(row.repo, f);
|
|
71
|
+
if (pushed.keys.has(k) || remember.has(k) || seen.has(k))
|
|
72
|
+
return false;
|
|
73
|
+
seen.add(k);
|
|
74
|
+
return true;
|
|
75
|
+
});
|
|
76
|
+
if (!fresh.length)
|
|
77
|
+
continue;
|
|
78
|
+
for (const f of fresh)
|
|
79
|
+
remember.add(exposurePushKey(row.repo, f));
|
|
80
|
+
const keys = fresh.map((f) => exposurePushKey(row.repo, f));
|
|
81
|
+
if (fresh.length > EXPOSURE_PUSH_CAP) {
|
|
82
|
+
push.push({
|
|
83
|
+
repo: row.repo, dir: row.dir, keys, attention: fresh.some(isLoud),
|
|
84
|
+
title: `${fresh.length} new exposure findings in ${row.repo}`,
|
|
85
|
+
body: fresh.slice(0, EXPOSURE_PUSH_CAP).map((f) => f.text).join("\n") + `\nand ${fresh.length - EXPOSURE_PUSH_CAP} more, in the exposure watch.`,
|
|
86
|
+
tag: exposureSummaryKey(row.repo), key: exposureSummaryKey(row.repo),
|
|
87
|
+
});
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
for (const f of fresh) {
|
|
91
|
+
push.push({
|
|
92
|
+
repo: row.repo, dir: row.dir, keys: [exposurePushKey(row.repo, f)], attention: isLoud(f),
|
|
93
|
+
title: `${row.repo}: ${f.measure} ${f.subject}${f.version ? "@" + f.version : ""}`,
|
|
94
|
+
body: f.text,
|
|
95
|
+
tag: exposureAttentionKey(row.repo, f.key), key: exposureAttentionKey(row.repo, f.key),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch { /* skip this series */ }
|
|
100
|
+
}
|
|
101
|
+
return { push, remember: [...remember], seenRepos: [...seenRepos], resolve: [...resolve] };
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=exposurepush.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exposurepush.js","sourceRoot":"","sources":["../src/exposurepush.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type HealthEntry, type HealthSeriesRow } from "./types.js";
|
|
2
|
+
export interface HealthCommitPoint {
|
|
3
|
+
sha7: string;
|
|
4
|
+
day: string;
|
|
5
|
+
ts: number;
|
|
6
|
+
week: string;
|
|
7
|
+
index: number;
|
|
8
|
+
mean: number;
|
|
9
|
+
cappedBy: HealthEntry | null;
|
|
10
|
+
/** Prereg or central fingerprint differs from the previous scored row: do not join the line. */
|
|
11
|
+
gap: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface HealthCommitSeries {
|
|
14
|
+
points: HealthCommitPoint[];
|
|
15
|
+
/** Scored rows before thinning. */
|
|
16
|
+
total: number;
|
|
17
|
+
thinned: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** 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. */
|
|
20
|
+
export declare function thinCommitPoints(points: readonly HealthCommitPoint[], max: number): HealthCommitPoint[];
|
|
21
|
+
/** Every scorable row as a commit point, thinned to about `max`; `null` when no row scores. */
|
|
22
|
+
export declare function healthIndexCommits(rows: readonly HealthSeriesRow[], contextWarnChars: number | null, max?: number): HealthCommitSeries | null;
|
|
23
|
+
/** `absent` = an older host (no key), `none` = the host looked and nothing scores, else `present`. */
|
|
24
|
+
export declare function healthCommitsAvailability(view: {
|
|
25
|
+
commits?: HealthCommitSeries | null;
|
|
26
|
+
} | null | undefined): "absent" | "none" | "present";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { isoWeekOf, centralOf } from "./readings.js";
|
|
2
|
+
import { healthRowScore } from "./score.js";
|
|
3
|
+
/** 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. */
|
|
4
|
+
export function thinCommitPoints(points, max) {
|
|
5
|
+
if (points.length <= max)
|
|
6
|
+
return [...points];
|
|
7
|
+
const keep = new Set();
|
|
8
|
+
const lastOfWeek = new Map();
|
|
9
|
+
points.forEach((p, i) => lastOfWeek.set(p.week, i));
|
|
10
|
+
for (const i of lastOfWeek.values())
|
|
11
|
+
keep.add(i);
|
|
12
|
+
const run = Math.ceil(points.length / Math.max(1, max));
|
|
13
|
+
for (let a = 0; a < points.length; a += run) {
|
|
14
|
+
let lo = a, hi = a;
|
|
15
|
+
const end = Math.min(points.length, a + run);
|
|
16
|
+
for (let i = a; i < end; i++) {
|
|
17
|
+
if (points[i].index < points[lo].index)
|
|
18
|
+
lo = i;
|
|
19
|
+
if (points[i].index > points[hi].index)
|
|
20
|
+
hi = i;
|
|
21
|
+
}
|
|
22
|
+
keep.add(lo);
|
|
23
|
+
keep.add(hi);
|
|
24
|
+
}
|
|
25
|
+
return [...keep].sort((x, y) => x - y).map((i) => points[i]);
|
|
26
|
+
}
|
|
27
|
+
/** Every scorable row as a commit point, thinned to about `max`; `null` when no row scores. */
|
|
28
|
+
export function healthIndexCommits(rows, contextWarnChars, max = 240) {
|
|
29
|
+
const sorted = rows.filter((r) => r && typeof r.ts === "number").sort((a, b) => a.ts - b.ts);
|
|
30
|
+
const all = [];
|
|
31
|
+
let prev = null;
|
|
32
|
+
for (const row of sorted) {
|
|
33
|
+
const week = isoWeekOf(row.day);
|
|
34
|
+
const s = week ? healthRowScore(row, contextWarnChars) : null;
|
|
35
|
+
if (!week || !s)
|
|
36
|
+
continue;
|
|
37
|
+
const prereg = typeof row.prereg === "string" ? row.prereg : null;
|
|
38
|
+
const central = centralOf(row).fp;
|
|
39
|
+
all.push({
|
|
40
|
+
sha7: typeof row.sha === "string" ? row.sha.slice(0, 7) : "",
|
|
41
|
+
day: row.day, ts: row.ts, week, index: s.index, mean: s.mean, cappedBy: s.cappedBy,
|
|
42
|
+
gap: prev !== null && (prev.prereg !== prereg || prev.central !== central),
|
|
43
|
+
});
|
|
44
|
+
prev = { prereg, central };
|
|
45
|
+
}
|
|
46
|
+
if (all.length === 0)
|
|
47
|
+
return null;
|
|
48
|
+
const points = thinCommitPoints(all, max);
|
|
49
|
+
return { points, total: all.length, thinned: points.length < all.length };
|
|
50
|
+
}
|
|
51
|
+
/** `absent` = an older host (no key), `none` = the host looked and nothing scores, else `present`. */
|
|
52
|
+
export function healthCommitsAvailability(view) {
|
|
53
|
+
if (!view || view.commits === undefined)
|
|
54
|
+
return "absent";
|
|
55
|
+
return view.commits && view.commits.points.length > 0 ? "present" : "none";
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=commits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commits.js","sourceRoot":"","sources":["../../src/healthindex/commits.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type HealthIndexPoint } from "./types.js";
|
|
2
|
+
export interface HealthMove {
|
|
3
|
+
kind: "drop" | "rise" | null;
|
|
4
|
+
horizon: "week" | "month" | null;
|
|
5
|
+
/** Index points the horizon moved (latest − then); null when there is no comparable move to state. */
|
|
6
|
+
delta: number | null;
|
|
7
|
+
reason: string;
|
|
8
|
+
}
|
|
9
|
+
export interface HealthMoveOpts {
|
|
10
|
+
minWeeks?: number;
|
|
11
|
+
minMonthWindows?: number;
|
|
12
|
+
lowPct?: number;
|
|
13
|
+
highPct?: number;
|
|
14
|
+
minPoints?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Whether the latest move is unusual for THIS repo: the week's link against
|
|
18
|
+
* the distribution of every earlier link, then (only if the week says nothing)
|
|
19
|
+
* the last four weeks against every earlier rolling four-week change. Both
|
|
20
|
+
* need the percentile AND a minimum number of points, so a dead-flat series
|
|
21
|
+
* cannot call a 0.1-point wobble a drop. Under `HEALTH_INDEX_MIN_WEEKS` links
|
|
22
|
+
* of history there is no distribution to stand on: `kind: null`, with why.
|
|
23
|
+
*/
|
|
24
|
+
export declare function assessHealthMove(points: readonly HealthIndexPoint[], opts?: HealthMoveOpts): HealthMove;
|
|
25
|
+
/** Plain names for an entry's move: [0] when its metric rose (its score fell), [1] when it fell. */
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// healthindex/move: The move detector: a drop or rise called only against the series' own past. Barrel: ../healthindex.ts (read the header there).
|
|
2
|
+
import { 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 } from "./types.js";
|
|
3
|
+
/** Linear-interpolated percentile (0–100) of a non-empty list. */
|
|
4
|
+
function percentile(xs, p) {
|
|
5
|
+
const s = [...xs].sort((a, b) => a - b);
|
|
6
|
+
const pos = (p / 100) * (s.length - 1);
|
|
7
|
+
const lo = Math.floor(pos);
|
|
8
|
+
const hi = Math.ceil(pos);
|
|
9
|
+
return s[lo] + (s[hi] - s[lo]) * (pos - lo);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Whether the latest move is unusual for THIS repo: the week's link against
|
|
13
|
+
* the distribution of every earlier link, then (only if the week says nothing)
|
|
14
|
+
* the last four weeks against every earlier rolling four-week change. Both
|
|
15
|
+
* need the percentile AND a minimum number of points, so a dead-flat series
|
|
16
|
+
* cannot call a 0.1-point wobble a drop. Under `HEALTH_INDEX_MIN_WEEKS` links
|
|
17
|
+
* of history there is no distribution to stand on: `kind: null`, with why.
|
|
18
|
+
*/
|
|
19
|
+
export function assessHealthMove(points, opts = {}) {
|
|
20
|
+
const minWeeks = opts.minWeeks ?? HEALTH_INDEX_MIN_WEEKS;
|
|
21
|
+
const minMonth = opts.minMonthWindows ?? HEALTH_INDEX_MIN_MONTH_WINDOWS;
|
|
22
|
+
const lowPct = opts.lowPct ?? HEALTH_INDEX_LOW_PCT;
|
|
23
|
+
const highPct = opts.highPct ?? HEALTH_INDEX_HIGH_PCT;
|
|
24
|
+
const minPts = opts.minPoints ?? HEALTH_INDEX_MIN_POINTS;
|
|
25
|
+
const none = (reason, horizon = null, delta = null) => ({ kind: null, horizon, delta, reason });
|
|
26
|
+
const last = points[points.length - 1];
|
|
27
|
+
if (!last)
|
|
28
|
+
return none("no index yet");
|
|
29
|
+
const links = points.filter((p) => p.lnLink !== null);
|
|
30
|
+
if (links.length < minWeeks) {
|
|
31
|
+
return none(`${links.length} weekly link${links.length === 1 ? "" : "s"} so far; a move is called after ${minWeeks}`);
|
|
32
|
+
}
|
|
33
|
+
// Week: only when the latest point IS a link — a carried week moved nothing.
|
|
34
|
+
if (last.lnLink !== null) {
|
|
35
|
+
const prior = links.slice(0, -1).map((p) => p.lnLink);
|
|
36
|
+
const prevIndex = points[points.length - 2].index;
|
|
37
|
+
const delta = last.index - prevIndex;
|
|
38
|
+
if (last.lnLink < percentile(prior, lowPct) && -delta >= minPts) {
|
|
39
|
+
return { kind: "drop", horizon: "week", delta, reason: `the latest week's link sits below the ${lowPct}th percentile of ${prior.length} earlier weeks` };
|
|
40
|
+
}
|
|
41
|
+
if (last.lnLink > percentile(prior, highPct) && delta >= minPts) {
|
|
42
|
+
return { kind: "rise", horizon: "week", delta, reason: `the latest week's link sits above the ${highPct}th percentile of ${prior.length} earlier weeks` };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Month: ln(index_t / index_{t-4}) against every earlier rolling window.
|
|
46
|
+
const W = HEALTH_INDEX_MONTH_WEEKS;
|
|
47
|
+
const t = points.length - 1;
|
|
48
|
+
if (t < W)
|
|
49
|
+
return none("too few weeks for a four-week reading");
|
|
50
|
+
// A window that spans a `gap` point compares two scores measured under
|
|
51
|
+
// different definitions: it is not a move. Skipped as history, and when the
|
|
52
|
+
// current window is one, no month move is called at all.
|
|
53
|
+
const spansGap = (j) => {
|
|
54
|
+
for (let k = j - W + 1; k <= j; k++)
|
|
55
|
+
if (points[k].gap)
|
|
56
|
+
return true;
|
|
57
|
+
return false;
|
|
58
|
+
};
|
|
59
|
+
if (spansGap(t))
|
|
60
|
+
return none("the last four weeks span a change of definition, so there is no month move to compare");
|
|
61
|
+
const windows = [];
|
|
62
|
+
for (let j = W; j < t; j++)
|
|
63
|
+
if (!spansGap(j))
|
|
64
|
+
windows.push(Math.log(points[j].index / points[j - W].index));
|
|
65
|
+
const monthDelta = last.index - points[t - W].index;
|
|
66
|
+
if (windows.length < minMonth) {
|
|
67
|
+
return none(`${windows.length} earlier four-week window${windows.length === 1 ? "" : "s"}; a month move is called after ${minMonth}`);
|
|
68
|
+
}
|
|
69
|
+
const ln = Math.log(last.index / points[t - W].index);
|
|
70
|
+
if (ln < percentile(windows, lowPct) && -monthDelta >= minPts) {
|
|
71
|
+
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` };
|
|
72
|
+
}
|
|
73
|
+
if (ln > percentile(windows, highPct) && monthDelta >= minPts) {
|
|
74
|
+
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` };
|
|
75
|
+
}
|
|
76
|
+
return none("within this repo's usual range", null, last.lnLink !== null ? last.index - points[t - 1].index : null);
|
|
77
|
+
}
|
|
78
|
+
/** Plain names for an entry's move: [0] when its metric rose (its score fell), [1] when it fell. */
|
|
79
|
+
//# sourceMappingURL=move.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move.js","sourceRoot":"","sources":["../../src/healthindex/move.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type HealthEntry, type HealthSeriesRow } from "./types.js";
|
|
2
|
+
/** `100 · min(1, good / value)`; a value at or under 0 is 100. */
|
|
3
|
+
export declare function healthScore(value: number, good: number): number;
|
|
4
|
+
/** The Monday (UTC) of the ISO week holding `day` (`YYYY-MM-DD`), or null for a malformed day. */
|
|
5
|
+
export declare function isoWeekOf(day: string): string | null;
|
|
6
|
+
/** The last row (greatest `ts`) of each ISO week, oldest week first. */
|
|
7
|
+
export declare function healthWeeks(rows: readonly HealthSeriesRow[]): {
|
|
8
|
+
week: string;
|
|
9
|
+
row: HealthSeriesRow;
|
|
10
|
+
}[];
|
|
11
|
+
/** The good line of the context entry for a repo's warn line (null = the default). */
|
|
12
|
+
export declare function healthContextGood(contextWarnChars: number | null): number;
|
|
13
|
+
/** One week's readings: the five values (size's is `lineMean`), plus size's longest file. */
|
|
14
|
+
export interface HealthEntryReadings {
|
|
15
|
+
values: Partial<Record<HealthEntry, number>>;
|
|
16
|
+
/** The longest file, read beside `lineMean`; absent where size is. */
|
|
17
|
+
max?: {
|
|
18
|
+
value: number;
|
|
19
|
+
path: string | null;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* One week's values, raw (no epsilon, no floor — `min(1, good/value)` is
|
|
24
|
+
* finite for any value ≥ 0); an entry is absent where its reading is.
|
|
25
|
+
*
|
|
26
|
+
* - `size` is `lineMean` and needs `max` beside it; either missing ⇒ absent.
|
|
27
|
+
* - `untested` is a SHARE: `untested.count / classics.files` — the source-file
|
|
28
|
+
* count of the same tree, which counts test files too, so the share is a
|
|
29
|
+
* floor. A share and not the count, so a repo that grows does not read as
|
|
30
|
+
* slipping just for having more modules.
|
|
31
|
+
* - `hatches` is UNEXPLAINED escapes per kLOC where the row classified them
|
|
32
|
+
* (engine 2026-10-16a on); every occurrence on an older row.
|
|
33
|
+
* - `context` is `claudeMdChars + descChars`; `descChars` null (no counted
|
|
34
|
+
* skills) counts as 0 descriptions.
|
|
35
|
+
*/
|
|
36
|
+
export declare function healthEntryReadings(row: HealthSeriesRow): HealthEntryReadings;
|
|
37
|
+
/** The five values alone — `healthEntryReadings(row).values`. The warn line is not read here any more (scores read it). */
|
|
38
|
+
export declare function healthEntryValues(row: HealthSeriesRow, _contextWarnChars?: number | null): Partial<Record<HealthEntry, number>>;
|
|
39
|
+
/**
|
|
40
|
+
* What the repo applied on this row: its fingerprint and which entries it
|
|
41
|
+
* disabled or overrode. An entry both disabled and overridden reads disabled
|
|
42
|
+
* (the engine never writes both; a hand-edited row must not count twice).
|
|
43
|
+
*/
|
|
44
|
+
export declare function centralOf(row: HealthSeriesRow): {
|
|
45
|
+
fp: string;
|
|
46
|
+
disabled: HealthEntry[];
|
|
47
|
+
overridden: HealthEntry[];
|
|
48
|
+
};
|
|
49
|
+
export declare const DAY_MS = 86400000;
|
|
50
|
+
export declare function treeOf(row: HealthSeriesRow): {
|
|
51
|
+
files: number;
|
|
52
|
+
loc: number;
|
|
53
|
+
} | null;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// healthindex/readings: Rows to readings: ISO weeks, the per-entry values, the repo `central` override. Barrel: ../healthindex.ts (read the header there).
|
|
2
|
+
import { HEALTH_ENTRIES, HEALTH_CONTEXT_GOOD_SHARE, HEALTH_INDEX_DEFAULT_WARN_CHARS, HEALTH_NO_CLAUDE_MD } from "./types.js";
|
|
3
|
+
const posFinite = (v) => typeof v === "number" && Number.isFinite(v) && v > 0;
|
|
4
|
+
const nonNegFinite = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
|
|
5
|
+
/** `100 · min(1, good / value)`; a value at or under 0 is 100. */
|
|
6
|
+
export function healthScore(value, good) {
|
|
7
|
+
return value <= 0 ? 100 : 100 * Math.min(1, good / value);
|
|
8
|
+
}
|
|
9
|
+
/** The Monday (UTC) of the ISO week holding `day` (`YYYY-MM-DD`), or null for a malformed day. */
|
|
10
|
+
export function isoWeekOf(day) {
|
|
11
|
+
if (typeof day !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(day))
|
|
12
|
+
return null;
|
|
13
|
+
const t = Date.parse(`${day}T00:00:00Z`);
|
|
14
|
+
if (!Number.isFinite(t))
|
|
15
|
+
return null;
|
|
16
|
+
const dow = (new Date(t).getUTCDay() + 6) % 7; // Monday = 0
|
|
17
|
+
return new Date(t - dow * 86_400_000).toISOString().slice(0, 10);
|
|
18
|
+
}
|
|
19
|
+
/** The last row (greatest `ts`) of each ISO week, oldest week first. */
|
|
20
|
+
export function healthWeeks(rows) {
|
|
21
|
+
const byWeek = new Map();
|
|
22
|
+
for (const r of rows) {
|
|
23
|
+
if (!r || typeof r.ts !== "number")
|
|
24
|
+
continue;
|
|
25
|
+
const week = isoWeekOf(r.day);
|
|
26
|
+
if (!week)
|
|
27
|
+
continue;
|
|
28
|
+
const prev = byWeek.get(week);
|
|
29
|
+
if (!prev || r.ts >= prev.ts)
|
|
30
|
+
byWeek.set(week, r);
|
|
31
|
+
}
|
|
32
|
+
return [...byWeek.entries()].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)).map(([week, row]) => ({ week, row }));
|
|
33
|
+
}
|
|
34
|
+
/** The good line of the context entry for a repo's warn line (null = the default). */
|
|
35
|
+
export function healthContextGood(contextWarnChars) {
|
|
36
|
+
return HEALTH_CONTEXT_GOOD_SHARE * (posFinite(contextWarnChars) ? contextWarnChars : HEALTH_INDEX_DEFAULT_WARN_CHARS);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* One week's values, raw (no epsilon, no floor — `min(1, good/value)` is
|
|
40
|
+
* finite for any value ≥ 0); an entry is absent where its reading is.
|
|
41
|
+
*
|
|
42
|
+
* - `size` is `lineMean` and needs `max` beside it; either missing ⇒ absent.
|
|
43
|
+
* - `untested` is a SHARE: `untested.count / classics.files` — the source-file
|
|
44
|
+
* count of the same tree, which counts test files too, so the share is a
|
|
45
|
+
* floor. A share and not the count, so a repo that grows does not read as
|
|
46
|
+
* slipping just for having more modules.
|
|
47
|
+
* - `hatches` is UNEXPLAINED escapes per kLOC where the row classified them
|
|
48
|
+
* (engine 2026-10-16a on); every occurrence on an older row.
|
|
49
|
+
* - `context` is `claudeMdChars + descChars`; `descChars` null (no counted
|
|
50
|
+
* skills) counts as 0 descriptions.
|
|
51
|
+
*/
|
|
52
|
+
export function healthEntryReadings(row) {
|
|
53
|
+
const values = {};
|
|
54
|
+
let max;
|
|
55
|
+
const sz = row.size?.value;
|
|
56
|
+
// `max` is read on its own: an override REPLACES lineMean and keeps the
|
|
57
|
+
// engine's max, so it must not depend on the engine's lineMean being there.
|
|
58
|
+
// Where `max` is absent size is absent on BOTH paths (an override cannot
|
|
59
|
+
// invent the longest file); where only lineMean is absent, size is absent
|
|
60
|
+
// without an override and the override's value stands with the engine's max.
|
|
61
|
+
// A `max` left without a size value is dropped at the end.
|
|
62
|
+
if (sz && nonNegFinite(sz.max)) {
|
|
63
|
+
max = { value: sz.max, path: typeof sz.maxPath === "string" && sz.maxPath ? sz.maxPath : null };
|
|
64
|
+
}
|
|
65
|
+
if (sz && nonNegFinite(sz.lineMean) && max)
|
|
66
|
+
values.size = sz.lineMean;
|
|
67
|
+
const rate = row.retouch?.value?.rate;
|
|
68
|
+
if (nonNegFinite(rate))
|
|
69
|
+
values.retouch = rate;
|
|
70
|
+
const h = row.hatches;
|
|
71
|
+
const loc = row.classics?.value?.loc;
|
|
72
|
+
if (h?.value && typeof h.value === "object" && posFinite(loc)) {
|
|
73
|
+
let total = 0;
|
|
74
|
+
let ok = true;
|
|
75
|
+
if (h.split && typeof h.split === "object") {
|
|
76
|
+
if (nonNegFinite(h.split.unexplained))
|
|
77
|
+
total = h.split.unexplained;
|
|
78
|
+
else
|
|
79
|
+
ok = false;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
for (const v of Object.values(h.value)) {
|
|
83
|
+
if (!nonNegFinite(v)) {
|
|
84
|
+
ok = false;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
total += v;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (ok)
|
|
91
|
+
values.hatches = total / (loc / 1000);
|
|
92
|
+
}
|
|
93
|
+
const ctx = row.context?.value;
|
|
94
|
+
const md = ctx?.claudeMdChars;
|
|
95
|
+
const desc = ctx?.descChars;
|
|
96
|
+
// No CLAUDE.md is nothing the repo loads every turn: 0, on the engine's exact words (its skills go unmeasured then).
|
|
97
|
+
if (!ctx && row.context?.reason === HEALTH_NO_CLAUDE_MD)
|
|
98
|
+
values.context = 0;
|
|
99
|
+
else if (nonNegFinite(md) && (desc === null || desc === undefined || nonNegFinite(desc)))
|
|
100
|
+
values.context = md + (typeof desc === "number" ? desc : 0);
|
|
101
|
+
const list = row.untested?.value;
|
|
102
|
+
const files = row.classics?.value?.files;
|
|
103
|
+
if (Array.isArray(list) && posFinite(files) && list.length <= files) {
|
|
104
|
+
values.untested = list.length / files;
|
|
105
|
+
}
|
|
106
|
+
// The repo's own say (`central`): a disabled entry is not in the basket at
|
|
107
|
+
// all; an override REPLACES the engine's value (for size, `lineMean` — the
|
|
108
|
+
// longest file stays measured), and a failed override is absent — never the
|
|
109
|
+
// engine's number standing in for the repo's.
|
|
110
|
+
const c = centralOf(row);
|
|
111
|
+
for (const e of c.disabled) {
|
|
112
|
+
delete values[e];
|
|
113
|
+
if (e === "size")
|
|
114
|
+
max = undefined;
|
|
115
|
+
}
|
|
116
|
+
for (const e of c.overridden) {
|
|
117
|
+
delete values[e];
|
|
118
|
+
const v = row.central?.override?.[e]?.value;
|
|
119
|
+
if (!nonNegFinite(v))
|
|
120
|
+
continue;
|
|
121
|
+
if (e === "size" && !max)
|
|
122
|
+
continue;
|
|
123
|
+
values[e] = v;
|
|
124
|
+
}
|
|
125
|
+
if (values.size === undefined)
|
|
126
|
+
max = undefined;
|
|
127
|
+
return max ? { values, max } : { values };
|
|
128
|
+
}
|
|
129
|
+
/** The five values alone — `healthEntryReadings(row).values`. The warn line is not read here any more (scores read it). */
|
|
130
|
+
export function healthEntryValues(row, _contextWarnChars) {
|
|
131
|
+
return healthEntryReadings(row).values;
|
|
132
|
+
}
|
|
133
|
+
const isEntry = (k) => HEALTH_ENTRIES.includes(k);
|
|
134
|
+
/**
|
|
135
|
+
* What the repo applied on this row: its fingerprint and which entries it
|
|
136
|
+
* disabled or overrode. An entry both disabled and overridden reads disabled
|
|
137
|
+
* (the engine never writes both; a hand-edited row must not count twice).
|
|
138
|
+
*/
|
|
139
|
+
export function centralOf(row) {
|
|
140
|
+
const c = row.central;
|
|
141
|
+
if (!c || typeof c !== "object")
|
|
142
|
+
return { fp: "", disabled: [], overridden: [] };
|
|
143
|
+
const fp = typeof c.fp === "string" ? c.fp : "";
|
|
144
|
+
const keysOf = (o) => o && typeof o === "object" ? Object.keys(o).filter(isEntry) : [];
|
|
145
|
+
const disabled = HEALTH_ENTRIES.filter((e) => keysOf(c.disabled).includes(e));
|
|
146
|
+
const overridden = HEALTH_ENTRIES.filter((e) => keysOf(c.override).includes(e) && !disabled.includes(e));
|
|
147
|
+
return { fp, disabled, overridden };
|
|
148
|
+
}
|
|
149
|
+
export const DAY_MS = 86_400_000;
|
|
150
|
+
export function treeOf(row) {
|
|
151
|
+
const v = row.classics?.value;
|
|
152
|
+
return v && nonNegFinite(v.files) && nonNegFinite(v.loc) ? { files: v.files, loc: v.loc } : null;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=readings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readings.js","sourceRoot":"","sources":["../../src/healthindex/readings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type HealthEntry, type HealthIndexSeries } from "./types.js";
|
|
2
|
+
import { type HealthCommitSeries } from "./commits.js";
|
|
3
|
+
import { type HealthMove } from "./move.js";
|
|
4
|
+
import { type HealthWords } from "./words.js";
|
|
5
|
+
export interface RepoHealthIndex {
|
|
6
|
+
/** The latest headline score, 0–100. */
|
|
7
|
+
value: number;
|
|
8
|
+
/** The latest week's move in score points; null on a gap week or the first scored week. */
|
|
9
|
+
deltaWeek: number | null;
|
|
10
|
+
/** The latest week's Monday. */
|
|
11
|
+
week: string;
|
|
12
|
+
move: "drop" | "rise" | null;
|
|
13
|
+
/** The mean before the cap, so `healthCapWords` can be said from this summary alone. */
|
|
14
|
+
mean?: number;
|
|
15
|
+
/** The entry holding the score down when the cap set it, else null. */
|
|
16
|
+
cappedBy?: HealthEntry | null;
|
|
17
|
+
/** The worst alert level on the latest week; null when nothing is under the warn line. */
|
|
18
|
+
alert?: "warn" | "severe" | null;
|
|
19
|
+
/** That worst alert's sentence; null with it. */
|
|
20
|
+
alertText?: string | null;
|
|
21
|
+
}
|
|
22
|
+
/** The wire summary for one repo, or null where there is no index (the field stays ABSENT, never 0). */
|
|
23
|
+
export declare function repoHealthIndexOf(series: HealthIndexSeries | null, move?: HealthMove | null): RepoHealthIndex | null;
|
|
24
|
+
/**
|
|
25
|
+
* `GET /api/repos/:id/healthindex` — the whole scored series for the phone's
|
|
26
|
+
* chart (the latest point carries the alerts and `cappedBy`), the called move
|
|
27
|
+
* and its words. `series: null` + `reason` when there is no series file or no
|
|
28
|
+
* scored week yet; never a made-up number.
|
|
29
|
+
*/
|
|
30
|
+
export interface HealthIndexResponse {
|
|
31
|
+
series: HealthIndexSeries | null;
|
|
32
|
+
move: HealthMove | null;
|
|
33
|
+
words: HealthWords | null;
|
|
34
|
+
/** ISO time of the last weekly refresh this host ran for the repo, if any. */
|
|
35
|
+
lastRefresh: string | null;
|
|
36
|
+
reason?: string;
|
|
37
|
+
/** Context per request by ISO week (`healthspend.ts`); absent with no ledger (older host; VS Code before its first log scan). */
|
|
38
|
+
spend?: import("../healthspend.js").HealthSpendWeek[];
|
|
39
|
+
/** Scored commits, thinned. ABSENT only on an older host; null = no row scores (or no series). */
|
|
40
|
+
commits?: HealthCommitSeries | null;
|
|
41
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** The wire summary for one repo, or null where there is no index (the field stays ABSENT, never 0). */
|
|
2
|
+
export function repoHealthIndexOf(series, move) {
|
|
3
|
+
const pts = series?.points;
|
|
4
|
+
const last = pts?.[pts.length - 1];
|
|
5
|
+
if (!pts || !last)
|
|
6
|
+
return null;
|
|
7
|
+
const prev = pts[pts.length - 2];
|
|
8
|
+
return {
|
|
9
|
+
value: last.index,
|
|
10
|
+
deltaWeek: last.lnLink !== null && prev ? last.index - prev.index : null,
|
|
11
|
+
week: last.week,
|
|
12
|
+
move: move?.kind ?? null,
|
|
13
|
+
mean: last.mean,
|
|
14
|
+
cappedBy: last.cappedBy,
|
|
15
|
+
alert: last.alerts[0]?.level ?? null,
|
|
16
|
+
alertText: last.alerts[0]?.text ?? null,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=repoindex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repoindex.js","sourceRoot":"","sources":["../../src/healthindex/repoindex.ts"],"names":[],"mappings":"AA2BA,wGAAwG;AACxG,MAAM,UAAU,iBAAiB,CAAC,MAAgC,EAAE,IAAwB;IAC1F,MAAM,GAAG,GAAG,MAAM,EAAE,MAAM,CAAC;IAC3B,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACnC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjC,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;QACxE,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI;QACxB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;QACpC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,IAAI;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type HealthEntry, type HealthSeriesRow, type HealthIndexSeries } from "./types.js";
|
|
2
|
+
/** Plain names for an entry, as the cap sentence names it. */
|
|
3
|
+
export declare const HEALTH_ENTRY_LABEL: Record<HealthEntry, string>;
|
|
4
|
+
/**
|
|
5
|
+
* The cap, said once: `null` when the cap did not set the number. The worst
|
|
6
|
+
* entry's score is derived (`value − HEALTH_SCORE_CAP_GAP`), so the wire
|
|
7
|
+
* summary can be worded from its three fields alone.
|
|
8
|
+
*/
|
|
9
|
+
export declare function healthCapWords(s: {
|
|
10
|
+
value: number;
|
|
11
|
+
mean: number;
|
|
12
|
+
cappedBy: HealthEntry | null;
|
|
13
|
+
}): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* The scored series. `null` when no week has every enabled entry — no score
|
|
16
|
+
* is no series, never a number nobody measured.
|
|
17
|
+
*/
|
|
18
|
+
export declare function healthIndex(rows: readonly HealthSeriesRow[], contextWarnChars: number | null): HealthIndexSeries | null;
|
|
19
|
+
/** One row by the SAME formula a week uses (`scoreWeek`); null when an enabled entry is absent. */
|
|
20
|
+
export declare function healthRowScore(row: HealthSeriesRow, contextWarnChars: number | null): {
|
|
21
|
+
index: number;
|
|
22
|
+
mean: number;
|
|
23
|
+
scores: Partial<Record<HealthEntry, number>>;
|
|
24
|
+
cappedBy: HealthEntry | null;
|
|
25
|
+
} | null;
|
|
26
|
+
/** One scored commit (a series row) for the phone's commits axis. No lnLink, contributions or move. */
|