phewsh 0.15.61 → 0.15.63

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.
@@ -439,15 +439,15 @@ async function main() {
439
439
  const dot = teal('●');
440
440
  const tools = `${toolCount} AI tool${toolCount !== 1 ? 's' : ''}`;
441
441
  if (hasProject && toolCount > 1) {
442
- console.log(` ${dot} ${sage('Welcome back. One shared memory of')} ${cream(projectName)}${sage(`, and ${tools} that all read it`)} ${slate('— switch tools mid-thought, nothing re-explained.')}`);
442
+ console.log(` ${dot} ${sage('phew you made it.')} ${slate('shh,')} ${cream(projectName)} ${sage(`and your ${tools} are aligned to one thread`)} ${slate('— switch mid-thought, nothing re-explained.')}`);
443
443
  } else if (hasProject) {
444
- console.log(` ${dot} ${sage('Welcome back. One verified memory of')} ${cream(projectName)} ${sage('— ready for whatever AI tool you reach for next.')}`);
444
+ console.log(` ${dot} ${sage('phew — you made it.')} ${slate('shh,')} ${sage('one verified memory of')} ${cream(projectName)} ${sage('— ready for whatever tool you reach for next.')}`);
445
445
  } else if (toolCount > 1) {
446
- console.log(` ${dot} ${sage(`Welcome — you made it. ${tools} here; this is where they share one thread.`)} ${slate('/init')} ${sage('to begin.')}`);
446
+ console.log(` ${dot} ${sage(`phew — you made it.`)} ${slate('shh,')} ${sage(`time to align your ${tools} to you and get down to business.`)} ${cream('/init')} ${sage('to begin.')}`);
447
447
  } else if (toolCount === 1) {
448
- console.log(` ${dot} ${sage('Welcome — you made it. Add Codex or Gemini and phewsh keeps every tool on the same page.')}`);
448
+ console.log(` ${dot} ${sage('phew — you made it.')} ${slate('shh,')} ${sage('add Codex or Gemini and phewsh keeps every tool aligned to you.')}`);
449
449
  } else {
450
- console.log(` ${dot} ${sage('Welcome — you made it. Install Claude Code, Codex, or Gemini and phewsh keeps them all on the same page.')}`);
450
+ console.log(` ${dot} ${sage('phew — you made it.')} ${slate('shh,')} ${sage('install Claude Code, Codex, or Gemini and phewsh keeps them aligned to you.')}`);
451
451
  }
452
452
  console.log('');
453
453
  } catch { /* the welcome is a flourish, never a blocker */ }
@@ -554,6 +554,8 @@ async function main() {
554
554
  const parts = [cream('HEAD ' + v.shortHead)];
555
555
  parts.push(v.dirtyCount ? peach(`${v.dirtyCount} uncommitted`) : sage('clean'));
556
556
  if (v.driftCommits > 0) parts.push(ember(`⚠ ${v.driftCommits} commit${v.driftCommits !== 1 ? 's' : ''} since .intent updated`));
557
+ // Sharper than recency: the docs still name an older version than shipped.
558
+ if (v.versionDrift) parts.push(ember(`⚠ .intent says ${v.versionDrift.claimed}, shipped ${v.versionDrift.shipped} — /reconcile`));
557
559
  row('VERIFIED', parts.join(slate(' · ')) + slate(' — /truth · /brief'));
558
560
  }
559
561
  } catch { /* the verified row is a glance, never a blocker */ }
@@ -2469,7 +2471,15 @@ async function main() {
2469
2471
  rl.prompt();
2470
2472
  return;
2471
2473
  }
2472
- const target = cmdArg.trim().toLowerCase();
2474
+ // Forgiving aliases — people type the tool's everyday name, not its id.
2475
+ // `/use claude` should just work, not bounce off "Unknown route".
2476
+ const USE_ALIASES = {
2477
+ claude: 'claude-code', cc: 'claude-code', claudecode: 'claude-code',
2478
+ gpt: 'codex', chatgpt: 'codex', openai: 'codex',
2479
+ grokbuild: 'grok',
2480
+ };
2481
+ const raw = cmdArg.trim().toLowerCase();
2482
+ const target = USE_ALIASES[raw] || raw;
2473
2483
  if (target === 'api') {
2474
2484
  if (!config?.apiKey) {
2475
2485
  console.log(` ${ember('!')} ${sage('No API key set — run /key first.')}`);
package/lib/truth.js CHANGED
@@ -273,16 +273,50 @@ async function fetchNpmLatest(packageName, { fetchImpl = global.fetch, timeoutMs
273
273
  // Fast, offline, fail-soft snapshot for the front-door cockpit — no npm fetch,
274
274
  // no file hashing. Answers "what verified truth is loaded?" at a glance so the
275
275
  // product thesis (one verified truth) is visible the moment phewsh opens.
276
+ // Cheap, offline version-claim drift: does the shipped package version sit ahead
277
+ // of the newest version the .intent narrative still claims? This is the SHARP
278
+ // staleness signal the front door was missing — the recency-based "commits since
279
+ // .intent changed" check goes quiet the moment you edit status.md, even if its
280
+ // headline claim is stale. We compare the project's package version (repo root,
281
+ // or a cli/ monorepo child like phewsh itself) to the max version mentioned in
282
+ // status.md/next.md, and only flag when code has shipped PAST the docs.
283
+ function quickVersionDrift(cwd = process.cwd()) {
284
+ try {
285
+ let shipped = null;
286
+ for (const rel of ['package.json', 'cli/package.json']) {
287
+ const p = path.join(cwd, rel);
288
+ if (!fs.existsSync(p)) continue;
289
+ try { shipped = JSON.parse(fs.readFileSync(p, 'utf-8')).version; } catch { /* unreadable */ }
290
+ if (shipped) break;
291
+ }
292
+ if (!shipped) return null;
293
+ let claimed = null;
294
+ for (const rel of ['.intent/status.md', '.intent/next.md']) {
295
+ const p = path.join(cwd, rel);
296
+ if (!fs.existsSync(p)) continue;
297
+ for (const m of fs.readFileSync(p, 'utf-8').matchAll(/\bv?(\d+\.\d+\.\d+)\b/g)) {
298
+ if (!claimed || compareVersions(m[1], claimed) > 0) claimed = m[1];
299
+ }
300
+ }
301
+ if (!claimed) return null;
302
+ return compareVersions(shipped, claimed) > 0 ? { shipped, claimed } : null;
303
+ } catch {
304
+ return null;
305
+ }
306
+ }
307
+
276
308
  function quickVerifiedState(cwd = process.cwd()) {
277
309
  try {
278
310
  const git = gitSnapshot(cwd);
279
- if (!git.available) return { available: false, isRepo: false };
311
+ const versionDrift = quickVersionDrift(cwd);
312
+ if (!git.available) return { available: false, isRepo: false, versionDrift };
280
313
  return {
281
314
  available: true,
282
315
  isRepo: true,
283
316
  shortHead: git.shortHead,
284
317
  dirtyCount: git.tracked.length + git.untracked.length,
285
318
  driftCommits: git.drift?.tracked ? git.drift.commitsSince : 0,
319
+ versionDrift,
286
320
  };
287
321
  } catch {
288
322
  return { available: false, isRepo: false };
@@ -397,5 +431,6 @@ module.exports = {
397
431
  parsePorcelain,
398
432
  projectionInfo,
399
433
  quickVerifiedState,
434
+ quickVersionDrift,
400
435
  statusDrift,
401
436
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phewsh",
3
- "version": "0.15.61",
3
+ "version": "0.15.63",
4
4
  "description": "Turn intent into action. Structure your thinking, execute your next step.",
5
5
  "bin": {
6
6
  "phewsh": "bin/phewsh.js"