phewsh 0.15.26 → 0.15.27

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.
@@ -492,15 +492,22 @@ async function main() {
492
492
  let installed = [];
493
493
  try { installed = listHarnesses().filter(h => h.installed).map(h => h.id); } catch { /* best-effort */ }
494
494
 
495
+ let bestKeeper = null;
496
+ try {
497
+ const br = learning.bestRoute(outcomeStats({ project: projectName }), { minSample: 4 });
498
+ if (br) bestKeeper = { route: br.route, label: continuity.labelFor(br.route), keptRate: br.keptRate, total: br.total };
499
+ } catch { /* best-effort */ }
500
+
495
501
  return {
496
502
  hasIntentDir: fs.existsSync(path.join(process.cwd(), '.intent')),
497
503
  intentFileCount: intentFiles.length,
498
504
  pendingOutcomes: pending,
499
505
  installedHarnesses: installed,
500
- route,
506
+ route: route?.id || route,
501
507
  turnsThisSession: Math.floor(messages.length / 2),
502
508
  seqStale,
503
509
  ambientOn,
510
+ bestKeeper,
504
511
  };
505
512
  }
506
513
 
@@ -1094,10 +1101,23 @@ async function main() {
1094
1101
  if (n === 5) {
1095
1102
  console.log('');
1096
1103
  console.log(` ${b(cream('Ask another model — switch the route'))}`);
1104
+ let mStats = null, best = null;
1105
+ try {
1106
+ mStats = outcomeStats({ project: projectName });
1107
+ best = learning.bestRoute(mStats, { minSample: 3 });
1108
+ } catch { /* best-effort */ }
1109
+ // Only celebrate a route that actually holds up (≥50% kept) — a star on
1110
+ // a poor rate would be dishonest. The badge shows regardless.
1111
+ const starRoute = best && best.keptRate >= 0.5 ? best.route : null;
1097
1112
  for (const h of harnesses) {
1098
- if (h.installed) console.log(` ${teal('/use ' + h.id.padEnd(12))} ${sage(h.label)} ${slate('(' + h.auth + ')')}`);
1113
+ if (!h.installed) continue;
1114
+ const badge = mStats ? learning.keptBadge(mStats, h.id) : '';
1115
+ const star = starRoute === h.id ? ` ${green('★ keeps best')}` : '';
1116
+ const rec = badge ? ` ${slate('· ' + badge)}` : '';
1117
+ console.log(` ${teal('/use ' + h.id.padEnd(12))} ${sage(h.label)} ${slate('(' + h.auth + ')')}${rec}${star}`);
1099
1118
  }
1100
1119
  if (config?.apiKey) console.log(` ${teal('/use api'.padEnd(17))} ${sage('Direct API')} ${slate('(your key)')}`);
1120
+ if (starRoute) console.log(` ${slate('★ = highest kept-rate in your record so far')}`);
1101
1121
  console.log('');
1102
1122
  rl.prompt();
1103
1123
  return;
package/lib/suggest.js CHANGED
@@ -38,6 +38,7 @@ function suggestAll(s = {}) {
38
38
  turnsThisSession = 0,
39
39
  seqStale = false,
40
40
  ambientOn = false,
41
+ bestKeeper = null, // { route, label, keptRate, total } from the record, or null
41
42
  } = s;
42
43
 
43
44
  const out = [];
@@ -88,6 +89,18 @@ function suggestAll(s = {}) {
88
89
  });
89
90
  }
90
91
 
92
+ // 4b. The record has a clear favorite that isn't your current route —
93
+ // auto-weighting: lean on what actually holds for you.
94
+ if (bestKeeper && bestKeeper.route !== route && bestKeeper.total >= 4 && bestKeeper.keptRate >= 0.6) {
95
+ out.push({
96
+ id: 'prefer-best-route',
97
+ priority: 55,
98
+ message: `${bestKeeper.label || bestKeeper.route} keeps best in your record (${Math.round(bestKeeper.keptRate * 100)}%, ${bestKeeper.total} labeled).`,
99
+ command: `/use ${bestKeeper.route}`,
100
+ why: 'The record weights routing — lean on the tool whose work you actually keep.',
101
+ });
102
+ }
103
+
91
104
  // 5. Ambient off — continuity that costs nothing once turned on.
92
105
  if (hasIntentDir && !ambientOn && installedHarnesses.includes('claude-code')) {
93
106
  out.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phewsh",
3
- "version": "0.15.26",
3
+ "version": "0.15.27",
4
4
  "description": "Turn intent into action. Structure your thinking, execute your next step.",
5
5
  "bin": {
6
6
  "phewsh": "bin/phewsh.js"