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.
- package/commands/session.js +16 -6
- package/lib/truth.js +36 -1
- package/package.json +1 -1
package/commands/session.js
CHANGED
|
@@ -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('
|
|
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('
|
|
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(`
|
|
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('
|
|
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('
|
|
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
|
-
|
|
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
|
-
|
|
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
|
};
|