phewsh 0.11.12 → 0.11.14

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/bin/phewsh.js CHANGED
@@ -30,7 +30,7 @@ function showBrand() {
30
30
  console.log('');
31
31
  console.log(` ${b(w('█▀█ █░█ █▀▀ █░█ █▀ █░█'))}`);
32
32
  console.log(` ${b(w('█▀▀ █▀█ ██▄ ▀▄▀ ▄█ █▀█'))}`);
33
- console.log(` ${g('Your project identity for every AI tool.')}`);
33
+ console.log(` ${g('.intent/ — your project\'s working memory for every AI tool.')}`);
34
34
  console.log('');
35
35
 
36
36
  // Context-aware hint
@@ -75,37 +75,30 @@ function showHelp() {
75
75
  const pkg = require('../package.json');
76
76
  showBrand();
77
77
  console.log(` ${g('v' + pkg.version)} · ${g('phewsh.com/cli')}\n`);
78
- console.log(` ${g('─'.repeat(48))}`);
79
- console.log(` ${b('Just type')} ${w('phewsh')} ${b('to start.')} ${g('Everything else is optional.')}`);
80
- console.log(` ${g('─'.repeat(48))}`);
78
+ console.log(` ${g('The loop: define .intent/ → sync → every AI tool reads → work → repeat')}`);
81
79
  console.log('');
82
- console.log(` ${b(w('start here'))}`);
83
- console.log(` ${cyan('phewsh')} Open AI session — type naturally, get guided`);
84
- console.log(` ${cyan('phewsh clarify')} Turn a messy idea into a structured spec`);
85
- console.log(` ${cyan('phewsh login')} Set up identity + API key`);
80
+ console.log(` ${b(w('get started'))}`);
81
+ console.log(` ${cyan('phewsh')} ${g('Open a session — create, plan, and work')}`);
82
+ console.log(` ${cyan('phewsh clarify')} ${g('Turn a messy idea into .intent/ artifacts')}`);
86
83
  console.log('');
87
- console.log(` ${b(w('project'))}`);
88
- console.log(` ${cyan('intent')} ${g('Manage .intent/ artifacts — status, open, evolve')}`);
89
- console.log(` ${cyan('gate')} ${g('Declare constraints (budget, time, skill, urgency)')}`);
90
- console.log(` ${cyan('context')} ${g('Export portable context for any AI tool')}`);
91
- console.log(` ${cyan('ai')} ${g('One-shot AI prompt with .intent/ context')}`);
84
+ console.log(` ${b(w('author .intent/'))}`);
85
+ console.log(` ${cyan('intent')} ${g('Create, view, evolve .intent/ artifacts')}`);
86
+ console.log(` ${cyan('gate')} ${g('Set constraints (budget, time, skill, urgency)')}`);
87
+ console.log(` ${cyan('context')} ${g('Export .intent/ for any AI tool')}`);
88
+ console.log(` ${cyan('ai')} ${g('One-shot prompt with .intent/ context')}`);
92
89
  console.log('');
93
- console.log(` ${b(w('sync'))}`);
94
- console.log(` ${cyan('push')} ${g('Push .intent/ to cloud')}`);
95
- console.log(` ${cyan('pull')} ${g('Pull from cloud to .intent/')}`);
96
- console.log(` ${cyan('watch')} ${g('Live syncCLAUDE.md + web dashboard auto-update')}`);
97
- console.log(` ${cyan('serve')} ${g('Execution bridge for the web app')}`);
90
+ console.log(` ${b(w('sync everywhere'))}`);
91
+ console.log(` ${cyan('watch')} ${g('Auto-sync .intent/ CLAUDE.md + cloud')}`);
92
+ console.log(` ${cyan('push/pull')} ${g('Manual sync to/from phewsh.com/intent')}`);
93
+ console.log(` ${cyan('serve')} ${g('Execution bridgerun from phewsh.com/intent')}`);
94
+ console.log(` ${cyan('mcp')} ${g('Connect AI agents via MCP protocol')}`);
98
95
  console.log('');
99
- console.log(` ${b(w('connect'))}`);
100
- console.log(` ${cyan('mcp')} ${g('Connect AI agents via MCP protocol')}`);
101
- console.log(` ${cyan('link')} ${g('Link local .intent/ to cloud project')}`);
96
+ console.log(` ${b(w('configure'))}`);
97
+ console.log(` ${cyan('login')} ${g('Identity + API key + cloud sync')}`);
98
+ console.log(` ${cyan('link')} ${g('Link local .intent/ to cloud project')}`);
102
99
  console.log('');
103
- console.log(` ${b(w('more'))}`);
104
- console.log(` ${cyan('sap')} ${g('Sustainable AI Protocol usage tracking')}`);
105
- console.log(` ${cyan('style')} ${g('Style identity — ingest, profile, sync')}`);
106
- console.log(` ${cyan('mbhd')} ${g('MBHD music engine')}`);
107
- console.log('');
108
- console.log(` ${g('Works standalone · Inside Claude Code · Inside Cursor · With any MCP agent')}`);
100
+ console.log(` ${g('Works in: Claude Code · Cursor · ChatGPT · any MCP agent')}`);
101
+ console.log(` ${g('No account needed. Account adds sync + sharing.')}`);
109
102
  console.log('');
110
103
  }
111
104
 
@@ -212,23 +212,11 @@ async function main() {
212
212
 
213
213
  // ── First-run welcome ──────────────────────────────────
214
214
  if (!config?.apiKey) {
215
- console.log(` ${b(cream('Welcome.'))}`);
216
- console.log(` ${sage('Your AI already knows your project. No more re-explaining.')}`);
215
+ console.log(` ${b(cream('Welcome to phewsh.'))}`);
217
216
  console.log('');
218
- console.log(` ${cream('To chat, you need an API key.')} ${slate('(not a subscription)')}`);
219
- console.log(` ${slate('ChatGPT Plus / Claude Pro don\'t include API access.')}`);
220
- console.log(` ${slate('API keys are pay-as-you-go both providers offer free credits.')}`);
221
- console.log('');
222
- console.log(` ${teal('1')} ${b(cream('Anthropic'))} ${slate('(recommended)')}`);
223
- console.log(` ${sage('console.anthropic.com/settings/keys')}`);
224
- console.log(` ${slate('Direct Claude access. Best quality. ~$0.01/message.')}`);
225
- console.log('');
226
- console.log(` ${teal('2')} ${b(cream('OpenRouter'))}`);
227
- console.log(` ${sage('openrouter.ai/keys')}`);
228
- console.log(` ${slate('One key → Claude, GPT, Gemini, and more.')}`);
229
- console.log('');
230
- console.log(` ${sage('Got a key?')} ${cream('/key')} ${sage('to paste it in.')}`);
231
- console.log(` ${sage('Curious?')} ${cream('/tour')} ${sage('to explore (no key needed).')}`);
217
+ console.log(` ${teal('/key')} ${sage('Set your API key (takes 10 seconds)')}`);
218
+ console.log(` ${teal('/init')} ${sage('Create .intent/ for this project')}`);
219
+ console.log(` ${teal('/tour')} ${sage('See what this does (no key needed)')}`);
232
220
  console.log('');
233
221
  } else if (!config.apiKey.startsWith('sk-')) {
234
222
  console.log(` ${ember('!')} ${sage('Stored API key looks invalid.')}`);
@@ -237,22 +225,17 @@ async function main() {
237
225
  config.apiKey = null;
238
226
  }
239
227
 
240
- // ── Project status ─────────────────────────────────────
228
+ // ── Project status (compact) ────────────────────────────
229
+ const statusParts = [cream(projectName)];
241
230
  if (intentFiles.length > 0) {
242
- console.log(` ${teal('●')} ${cream(projectName)} ${slate('·')} ${sage(intentFiles.map(f => f.file).join(', '))}`);
231
+ statusParts.push(teal('●') + sage(` .intent/ (${intentFiles.length} files)`));
243
232
  } else {
244
- console.log(` ${teal('●')} ${cream(projectName)} ${slate('·')} ${sage('no .intent/ context')}`);
245
- console.log(` ${slate(' run /init to create .intent/ artifacts')}`);
246
- }
247
- console.log(` ${slate(' model:')} ${sage(MODELS[currentModel].name)}`);
248
- if (config?.email) {
249
- console.log(` ${slate(' user:')} ${sage(config.email)}`);
233
+ statusParts.push(slate('no .intent/ — run /init'));
250
234
  }
235
+ statusParts.push(sage(MODELS[currentModel].name));
236
+ console.log(` ${statusParts.join(slate(' · '))}`);
251
237
 
252
- // ── Interop ────────────────────────────────────────────
253
- ui.interopLine(config, intentFiles);
254
-
255
- // Sync status (non-blocking)
238
+ // Sync status (one-line, non-blocking)
256
239
  if (config?.supabaseUserId && intentFiles.length > 0) {
257
240
  const syncResult = await Promise.race([
258
241
  checkSyncStatus(config),
@@ -260,26 +243,21 @@ async function main() {
260
243
  ]);
261
244
  if (syncResult) {
262
245
  if (syncResult.status === 'cloud-newer') {
263
- console.log(` ${ember('↓')} ${sage('Cloud is newer (' + syncResult.ago + ') — run /pull')}`);
246
+ console.log(` ${ember('↓')} ${sage('Cloud newer (' + syncResult.ago + ') — /pull')}`);
264
247
  } else if (syncResult.status === 'local-newer') {
265
- console.log(` ${ember('↑')} ${sage('Local changes not pushed (' + syncResult.ago + ') run /push')}`);
248
+ console.log(` ${ember('↑')} ${sage('Local changes — /push')}`);
266
249
  } else if (syncResult.status === 'synced') {
267
250
  console.log(` ${teal('↕')} ${slate('synced')}`);
268
- } else if (syncResult.status === 'local-only') {
269
- console.log(` ${slate('↕ not linked to cloud — run /push to sync')}`);
270
251
  }
271
252
  }
272
253
  }
273
254
 
274
255
  console.log('');
275
- ui.divider('line');
276
256
  if (!config?.apiKey) {
277
- console.log(` ${sage('type')} ${cream('/key')} ${sage('to get started ·')} ${cream('/tour')} ${sage('to explore ·')} ${cream('/help')} ${sage('for commands')}`);
257
+ console.log(` ${cream('/key')} ${sage('to start ·')} ${cream('/tour')} ${sage('to explore ·')} ${cream('/help')} ${sage('for more')}`);
278
258
  } else {
279
259
  console.log(` ${ui.randomTip()}`);
280
- console.log(` ${sage('type naturally ·')} ${cream('/help')} ${sage('for commands ·')} ${cream('/quit')} ${sage('to exit')}`);
281
260
  }
282
- ui.divider('line');
283
261
  console.log('');
284
262
 
285
263
  const rl = readline.createInterface({
@@ -307,50 +285,47 @@ async function main() {
307
285
 
308
286
  if (cmd === 'quit' || cmd === 'exit' || cmd === 'q') {
309
287
  const turns = messages.length / 2;
288
+ // Clean up background children
289
+ if (global._phewshChildren) {
290
+ global._phewshChildren.forEach(c => { try { c.kill(); } catch {} });
291
+ }
310
292
  console.log('');
311
- ui.divider('line');
312
293
  console.log(` ${sage('session ended · ' + turns + ' exchanges · ' + (totalPromptTokens + totalCompletionTokens) + ' tokens')}`);
313
- ui.divider('line');
314
294
  console.log('');
315
295
  process.exit(0);
316
296
  }
317
297
 
318
298
  if (cmd === 'help' || cmd === 'h') {
319
299
  console.log('');
320
- ui.divider('line');
321
- console.log(` ${b(cream('Session commands'))}`);
322
- ui.divider('line');
323
- console.log('');
324
- console.log(` ${cream('conversation')}`);
325
- console.log(` ${teal('/clear')} ${sage('Clear conversation history')}`);
326
- console.log(` ${teal('/run')} ${slate('<prompt>')} ${sage('One-shot prompt (no history)')}`);
327
- console.log(` ${teal('/quit')} ${sage('End session')}`);
300
+ console.log(` ${sage('the loop: define .intent/ → sync → work → evolve → repeat')}`);
328
301
  console.log('');
329
- console.log(` ${cream('project')}`);
330
- console.log(` ${teal('/init')} ${sage('Create .intent/ artifacts in this directory')}`);
331
- console.log(` ${teal('/clarify')} ${sage('AI-assisted artifact generation')}`);
332
- console.log(` ${teal('/gate')} ${sage('Declare constraints (budget, time, skill)')}`);
333
- console.log(` ${teal('/export')} ${sage('Export portable context for other AI tools')}`);
302
+ console.log(` ${cream('author .intent/')}`);
303
+ console.log(` ${teal('/init')} ${sage('Create .intent/ for this project')}`);
304
+ console.log(` ${teal('/clarify')} ${sage('Turn ideas into .intent/ artifacts')}`);
305
+ console.log(` ${teal('/gate')} ${sage('Set constraints (budget, time, skill)')}`);
334
306
  console.log(` ${teal('/context')} ${sage('Show loaded .intent/ files')}`);
335
- console.log(` ${teal('/reload')} ${sage('Reload .intent/ context from disk')}`);
336
- console.log(` ${teal('/status')} ${sage('Show session stats')}`);
307
+ console.log(` ${teal('/reload')} ${sage('Reload .intent/ from disk')}`);
337
308
  console.log('');
338
- console.log(` ${cream('sync')}`);
339
- console.log(` ${teal('/push')} ${sage('Push .intent/ to cloud')}`);
340
- console.log(` ${teal('/pull')} ${sage('Pull .intent/ from cloud (reloads context)')}`);
309
+ console.log(` ${cream('sync everywhere')}`);
310
+ console.log(` ${teal('/watch')} ${sage('Sync .intent/ CLAUDE.md + cloud (background)')}`);
311
+ console.log(` ${teal('/export')} ${sage('Export .intent/ for any AI tool')}`);
312
+ console.log(` ${teal('/push')} ${sage('Push to phewsh.com/intent')}`);
313
+ console.log(` ${teal('/pull')} ${sage('Pull from cloud (reloads context)')}`);
314
+ console.log(` ${teal('/serve')} ${sage('Execution bridge for phewsh.com/intent')}`);
341
315
  console.log(` ${teal('/sync')} ${sage('Check sync status')}`);
342
316
  console.log('');
343
- console.log(` ${cream('configuration')}`);
344
- console.log(` ${teal('/login')} ${sage('Set up identity + cloud sync')}`);
345
- console.log(` ${teal('/key')} ${sage('Set or update your API key')}`);
346
- console.log(` ${teal('/model')} ${slate('<name>')} ${sage('Switch model (sonnet, opus, haiku)')}`);
347
- console.log(` ${teal('/models')} ${sage('List available models')}`);
348
- console.log(` ${teal('/provider')} ${sage('Show current provider info')}`);
349
- console.log(` ${teal('/update')} ${sage('Update phewsh to the latest version')}`);
317
+ console.log(` ${cream('session')}`);
318
+ console.log(` ${teal('/run')} ${slate('<prompt>')} ${sage('One-shot prompt (no history)')}`);
319
+ console.log(` ${teal('/clear')} ${sage('Clear conversation')}`);
320
+ console.log(` ${teal('/status')} ${sage('Session stats')}`);
321
+ console.log(` ${teal('/quit')} ${sage('Exit')}`);
350
322
  console.log('');
351
- console.log(` ${cream('explore')}`);
352
- console.log(` ${teal('/tour')} ${sage('Guided walkthrough of PHEWSH')}`);
353
- console.log(` ${teal('/system')} ${sage('Show current system prompt')}`);
323
+ console.log(` ${cream('configure')}`);
324
+ console.log(` ${teal('/key')} ${sage('Set API key')}`);
325
+ console.log(` ${teal('/login')} ${sage('Identity + cloud sync')}`);
326
+ console.log(` ${teal('/model')} ${slate('<name>')} ${sage('Switch model (sonnet, opus, haiku)')}`);
327
+ console.log(` ${teal('/update')} ${sage('Update phewsh')}`);
328
+ console.log(` ${teal('/tour')} ${sage('Quick walkthrough')}`);
354
329
  console.log('');
355
330
  rl.prompt();
356
331
  return;
@@ -716,6 +691,49 @@ async function main() {
716
691
  return;
717
692
  }
718
693
 
694
+ if (cmd === 'watch') {
695
+ if (!fs.existsSync(INTENT_DIR)) {
696
+ console.log(`\n ${ember('!')} ${sage('No .intent/ found. Run /init first.')}\n`);
697
+ rl.prompt();
698
+ return;
699
+ }
700
+ const { spawn } = require('child_process');
701
+ const watchArgs = ['watch'];
702
+ if (cmdArg) watchArgs.push(...cmdArg.split(/\s+/));
703
+ const child = spawn(process.execPath, [path.join(__dirname, '..', 'bin', 'phewsh.js'), ...watchArgs], {
704
+ stdio: 'inherit',
705
+ detached: false,
706
+ });
707
+ child.on('error', (err) => {
708
+ console.log(` ${ember('!')} ${sage('Watch failed:')} ${err.message}`);
709
+ });
710
+ // Store ref so we can clean up on exit
711
+ if (!global._phewshChildren) global._phewshChildren = [];
712
+ global._phewshChildren.push(child);
713
+ console.log(`\n ${teal('●')} ${sage('Watch started — .intent/ syncing in background')}`);
714
+ console.log(` ${slate('CLAUDE.md and cloud will auto-update on changes')}\n`);
715
+ rl.prompt();
716
+ return;
717
+ }
718
+
719
+ if (cmd === 'serve') {
720
+ const { spawn } = require('child_process');
721
+ const serveArgs = ['serve'];
722
+ if (cmdArg) serveArgs.push(...cmdArg.split(/\s+/));
723
+ const child = spawn(process.execPath, [path.join(__dirname, '..', 'bin', 'phewsh.js'), ...serveArgs], {
724
+ stdio: 'inherit',
725
+ detached: false,
726
+ });
727
+ child.on('error', (err) => {
728
+ console.log(` ${ember('!')} ${sage('Serve failed:')} ${err.message}`);
729
+ });
730
+ if (!global._phewshChildren) global._phewshChildren = [];
731
+ global._phewshChildren.push(child);
732
+ console.log(`\n ${teal('●')} ${sage('Serve started — execution bridge running')}\n`);
733
+ rl.prompt();
734
+ return;
735
+ }
736
+
719
737
  if (cmd === 'run') {
720
738
  if (!cmdArg) {
721
739
  console.log(` ${sage('Usage:')} ${cream('/run <prompt>')}`);
@@ -763,12 +781,7 @@ async function main() {
763
781
  // Regular input → send to AI
764
782
  if (!config?.apiKey) {
765
783
  console.log('');
766
- console.log(` ${peach('Almost there.')} ${sage('You need an API key to chat.')}`);
767
- console.log(` ${sage('Type')} ${cream('/key')} ${sage('and paste one in — takes 10 seconds.')}`);
768
- console.log('');
769
- console.log(` ${slate('Get a key:')} ${sage('console.anthropic.com/settings/keys')}`);
770
- console.log(` ${slate('Or try:')} ${sage('openrouter.ai/keys')}`);
771
- console.log(` ${slate('Explore:')} ${cream('/tour')} ${slate('to see what PHEWSH does (no key needed)')}`);
784
+ console.log(` ${sage('Type')} ${cream('/key')} ${sage('to set your API key first.')}`);
772
785
  console.log('');
773
786
  rl.prompt();
774
787
  return;
package/commands/watch.js CHANGED
@@ -2,7 +2,7 @@
2
2
  //
3
3
  // Watches .intent/ for changes and auto-pushes to Supabase + regenerates CLAUDE.md.
4
4
  // This is the backbone of cross-tool continuity:
5
- // edit in terminal → web dashboard updates → Claude Code knows.
5
+ // edit in terminal → phewsh.com/intent updates → Claude Code knows.
6
6
  //
7
7
  // Usage:
8
8
  // phewsh watch Start watching (push + CLAUDE.md)
@@ -85,8 +85,8 @@ function generateClaudeSection() {
85
85
  const decisionGate = gate || projectJson?.decisionGate;
86
86
 
87
87
  sections.push(`# PHEWSH Adaptive Context — ${projectName}`);
88
+ sections.push(`> **Generated file. Do not edit.** Modify .intent/ instead — this section regenerates automatically.`);
88
89
  sections.push(`> Auto-synced by \`phewsh watch\` | ${new Date().toISOString().split('T')[0]}`);
89
- sections.push(`> This section is regenerated on every .intent/ change. Do not edit manually.`);
90
90
  sections.push('');
91
91
 
92
92
  // Project identity
@@ -318,25 +318,25 @@ function watchIntent() {
318
318
 
319
319
  function showHelp() {
320
320
  console.log(`
321
- phewsh watch — Live .intent/ sync daemon
321
+ phewsh watch — Keep AI tools in sync with .intent/
322
322
 
323
323
  Usage:
324
324
  phewsh watch Start watching
325
325
  phewsh watch --no-claude Skip CLAUDE.md regeneration
326
- phewsh watch --no-push Skip cloud push (local CLAUDE.md only)
326
+ phewsh watch --no-push Skip cloud push (local only)
327
327
  phewsh watch --verbose Show detailed sync info
328
328
 
329
329
  What it does:
330
330
  Watches .intent/ for changes and automatically:
331
- 1. Pushes updated artifacts to Supabase (web dashboard updates live)
332
- 2. Regenerates the PHEWSH section in CLAUDE.md (Claude Code stays current)
331
+ 1. Regenerates CLAUDE.md so Claude Code stays current with .intent/
332
+ 2. Pushes to phewsh.com/intent (optional needs account)
333
333
 
334
- This creates the cross-tool continuity loop:
335
- edit gate in terminal -> web dashboard reorganizes -> Claude already knows
334
+ The loop:
335
+ edit .intent/ CLAUDE.md updates cloud mirror updates every tool knows
336
336
 
337
337
  Requirements:
338
338
  - .intent/ directory must exist (run \`phewsh intent --init\`)
339
- - \`phewsh login\` for cloud push (optional CLAUDE.md works without it)
339
+ - Everything works without an account. Account adds cloud sync.
340
340
  `);
341
341
  }
342
342
 
@@ -352,8 +352,8 @@ async function main() {
352
352
  const loggedIn = !!config?.supabaseUserId;
353
353
 
354
354
  console.log('');
355
- console.log(` ${b(w('PHEWSH Watch'))} ${g('v' + require('../package.json').version)}`);
356
- console.log(` ${g('Live .intent/ sync cross-tool continuity')}`);
355
+ console.log(` ${b(w('.intent/ Watch'))} ${g('v' + require('../package.json').version)}`);
356
+ console.log(` ${g('Keeps your AI tools in sync with .intent/')}`);
357
357
  console.log('');
358
358
 
359
359
  // Show what's enabled
@@ -361,7 +361,7 @@ async function main() {
361
361
  if (!flags.noClaude) features.push(`${green('●')} CLAUDE.md auto-sync`);
362
362
  else features.push(`${g('○')} CLAUDE.md ${g('(disabled)')}`);
363
363
 
364
- if (!flags.noPush && loggedIn) features.push(`${green('●')} Cloud push (web dashboard)`);
364
+ if (!flags.noPush && loggedIn) features.push(`${green('●')} Cloud push phewsh.com/intent`);
365
365
  else if (!flags.noPush && !loggedIn) features.push(`${yellow('●')} Cloud push ${g('(not logged in — run phewsh login)')}`);
366
366
  else features.push(`${g('○')} Cloud push ${g('(disabled)')}`);
367
367
 
package/lib/ui.js CHANGED
@@ -11,8 +11,8 @@ const rgbBg = (r, g, b) => (s) => `\x1b[48;2;${r};${g};${b}m${s}\x1b[0m`;
11
11
  // Brand colors — relief, quiet, future
12
12
  const teal = rgb(100, 215, 195); // cool calm — primary
13
13
  const peach = rgb(255, 195, 145); // warm exhale — accent
14
- const sage = rgb(130, 150, 140); // quiet — secondary text
15
- const slate = rgb(80, 90, 88); // whisper — dim text
14
+ const sage = rgb(155, 175, 165); // quiet — secondary text (bumped for readability)
15
+ const slate = rgb(105, 115, 112); // whisper — dim text (bumped for readability)
16
16
  const cream = rgb(240, 235, 225); // clarity — bright text
17
17
  const ember = rgb(220, 140, 90); // glow — warnings/energy
18
18
 
@@ -150,7 +150,7 @@ async function brandReveal(fast = false) {
150
150
  await sleep(100);
151
151
 
152
152
  // Phase 5: Tagline fades in — dim → sage → cream
153
- const tagline = 'relief. quiet execution.';
153
+ const tagline = '.intent/ is your project\'s working memory.';
154
154
  process.stdout.write(` ${slate(tagline)}`);
155
155
  await sleep(200);
156
156
  process.stdout.write(`${clearLine} ${sage(tagline)}`);
@@ -227,14 +227,14 @@ function typewrite(text, speed = 25) {
227
227
 
228
228
  // ── Welcome tips ─────────────────────────────────────────
229
229
  const TIPS = [
230
- `${slate('·')} ${sage('Type')} ${cream('/clarify')} ${sage('to turn a messy idea into a structured spec')}`,
231
- `${slate('·')} ${cream('/gate')} ${sage('sets budget, time, and skill constraints AI respects them')}`,
232
- `${slate('·')} ${sage('Run')} ${cream('phewsh watch')} ${sage('in another tab for live sync to CLAUDE.md')}`,
233
- `${slate('·')} ${cream('/export')} ${sage('creates a portable context file for any AI tool')}`,
234
- `${slate('·')} ${cream('/model opus')} ${sage('for complex reasoning,')} ${cream('/model haiku')} ${sage('for speed')}`,
235
- `${slate('·')} ${sage('Your')} ${cream('.intent/')} ${sage('files are plain markdown edit them anytime')}`,
236
- `${slate('·')} ${cream('phewsh context --copy')} ${sage('puts your project context on the clipboard')}`,
237
- `${slate('·')} ${cream('/tour')} ${sage('walks you through everything PHEWSH can do')}`,
230
+ `${sage('try')} ${cream('/clarify')} ${sage(' turns ideas into .intent/ artifacts')}`,
231
+ `${sage('try')} ${cream('/gate')} ${sage(' set budget/time constraints, AI respects them')}`,
232
+ `${sage('try')} ${cream('/watch')} ${sage(' sync .intent/ to CLAUDE.md in the background')}`,
233
+ `${sage('try')} ${cream('/export')} ${sage(' .intent/ as portable context for any AI tool')}`,
234
+ `${sage('.intent/ is plain markdown edit the files directly anytime')}`,
235
+ `${sage('the loop: define .intent/ sync work evolve repeat')}`,
236
+ `${sage('try')} ${cream('/tour')} ${sage(' quick walkthrough, no key needed')}`,
237
+ `${sage('works in Claude Code, Cursor, ChatGPT, and any MCP agent')}`,
238
238
  ];
239
239
 
240
240
  function randomTip() {
@@ -244,87 +244,69 @@ function randomTip() {
244
244
  // ── Tour content ─────────────────────────────────────────
245
245
  const TOUR_PAGES = [
246
246
  {
247
- title: 'What is PHEWSH?',
247
+ title: 'The idea',
248
248
  body: [
249
249
  '',
250
- ` ${cream('phew')} ${sage('— the relief of not starting from scratch.')}`,
251
- ` ${cream('shh')} ${sage('— it just works. No noise.')}`,
250
+ ` Every AI tool you use asks the same question:`,
251
+ ` ${slate('"What are you building?"')}`,
252
252
  '',
253
- ` PHEWSH gives your project a ${b(cream('portable identity'))}.`,
254
- ` Define what you're building once every AI tool reads it.`,
253
+ ` ${teal('.intent/')} ${sage('answers it once. Every tool reads it.')}`,
254
+ ` Plain markdown. Committed with your code. No lock-in.`,
255
255
  '',
256
- ` It works ${cream('standalone')} as its own AI shell,`,
257
- ` and ${cream('inside')} Claude Code, Cursor, ChatGPT, and any MCP agent.`,
258
- '',
259
- ` ${sage('Your project context lives in')} ${teal('.intent/')} ${sage('— plain markdown.')}`,
260
- ` ${sage('You own them. They travel with your code.')}`,
256
+ ` ${sage('The loop:')} ${cream('define')} ${sage('→')} ${cream('sync')} ${sage('→')} ${cream('work')} ${sage('→')} ${cream('evolve')} ${sage('→')} ${cream('repeat')}`,
261
257
  ]
262
258
  },
263
259
  {
264
- title: 'The .intent/ directory',
260
+ title: 'The files',
265
261
  body: [
266
262
  '',
267
263
  ` ${teal('.intent/')}`,
268
- ` ${peach('vision.md')} ${sage('What this project is and why it exists')}`,
264
+ ` ${peach('vision.md')} ${sage('What you\'re building and why')}`,
269
265
  ` ${peach('plan.md')} ${sage('Strategy, phases, milestones')}`,
270
- ` ${peach('next.md')} ${sage('Current tasks and what to do right now')}`,
271
- ` ${ember('gate.json')} ${sage('Your constraints (budget, time, skill)')}`,
266
+ ` ${peach('next.md')} ${sage('What to do right now')}`,
267
+ ` ${ember('gate.json')} ${sage('Constraints: budget, time, skill')}`,
272
268
  '',
273
- ` ${sage('Create these with')} ${cream('/init')} ${sage('or')} ${cream('/clarify')}`,
269
+ ` ${cream('/init')} ${sage('creates them.')} ${cream('/clarify')} ${sage('authors them with AI.')}`,
270
+ ` ${sage('Or just edit the markdown directly.')}`,
274
271
  ]
275
272
  },
276
273
  {
277
- title: 'Standalone mode',
274
+ title: 'Sync everywhere',
278
275
  body: [
279
276
  '',
280
- ` Run ${cream('phewsh')} and type naturally.`,
281
- ` Every message carries your project's full context.`,
282
- '',
283
- ` ${teal('phewsh')} ${sage('>')} what should I focus on today?`,
284
- ` ${teal('phewsh')} ${sage('>')} is my plan realistic given my budget?`,
285
- ` ${teal('phewsh')} ${sage('>')} break this feature into tasks`,
286
- '',
287
- ` ${sage('The AI doesn\'t need a warmup. It already knows.')}`,
288
- ]
289
- },
290
- {
291
- title: 'Inside other tools',
292
- body: [
277
+ ` ${cream('/watch')} ${sage('syncs .intent/ to your tools in the background:')}`,
293
278
  '',
294
- ` ${b(cream('Claude Code'))} ${sage('phewsh watch auto-updates CLAUDE.md')}`,
295
- ` ${b(cream('Cursor'))} ${sage('phewsh context --file .phewsh.context')}`,
296
- ` ${b(cream('ChatGPT'))} ${sage('phewsh context --copy paste in')}`,
297
- ` ${b(cream('MCP agents'))} ${sage('phewsh mcp setup agents self-brief')}`,
279
+ ` ${b(cream('Claude Code'))} ${sage(' CLAUDE.md auto-updates')}`,
280
+ ` ${b(cream('Cursor'))} ${sage(' /export writes .phewsh.context')}`,
281
+ ` ${b(cream('ChatGPT'))} ${sage(' /export --copy to clipboard')}`,
282
+ ` ${b(cream('MCP agents'))} ${sage(' self-brief from .intent/ via protocol')}`,
298
283
  '',
299
- ` ${sage('Same identity. Every tool. No re-explaining.')}`,
300
- ` ${sage('Switch tools mid-thought. Nothing lost.')}`,
284
+ ` ${sage('Switch tools mid-thought. Context follows.')}`,
301
285
  ]
302
286
  },
303
287
  {
304
- title: 'The Decision Gate',
288
+ title: 'Constraints',
305
289
  body: [
306
290
  '',
307
- ` Before you build, decide ${b(cream('whether'))} to build.`,
308
- ` The gate captures what you can actually spend:`,
291
+ ` ${cream('/gate')} ${sage('captures what you can actually spend:')}`,
309
292
  '',
310
293
  ` ${sage('Budget')} ${cream('$50')} ${sage('Skill')} ${cream('expert')}`,
311
294
  ` ${sage('Time')} ${cream('15 hrs/week')} ${sage('Urgency')} ${cream('high')}`,
312
295
  '',
313
- ` ${sage('These constraints shape every AI response.')}`,
314
- ` ${sage('Run')} ${cream('/gate activate')} ${sage('to set yours.')}`,
296
+ ` ${sage('Every AI response respects these.')}`,
297
+ ` ${sage('Ask "what should I do next?" — the answer fits your reality.')}`,
315
298
  ]
316
299
  },
317
300
  {
318
- title: 'You\'re ready',
301
+ title: 'Go',
319
302
  body: [
320
303
  '',
321
- ` ${teal('')} Type naturally to chat with your project context`,
322
- ` ${teal('')} ${cream('/init')} or ${cream('/clarify')} to create .intent/ artifacts`,
323
- ` ${teal('')} ${cream('/gate')} to set your constraints`,
324
- ` ${teal('')} ${cream('/help')} for all commands`,
304
+ ` ${teal('1.')} ${cream('/init')} ${sage('or')} ${cream('/clarify')} ${sage('— create .intent/')}`,
305
+ ` ${teal('2.')} ${sage('Type naturally context is always loaded')}`,
306
+ ` ${teal('3.')} ${cream('/watch')} ${sage('— sync to all your tools')}`,
307
+ ` ${teal('4.')} ${cream('/gate')} ${sage('— set constraints')}`,
325
308
  '',
326
- ` ${sage('PHEWSH is your project\'s home base.')}`,
327
- ` ${sage('The exhale before execution.')}`,
309
+ ` ${sage('Intent-driven development. Define once. Work everywhere.')}`,
328
310
  ]
329
311
  },
330
312
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phewsh",
3
- "version": "0.11.12",
3
+ "version": "0.11.14",
4
4
  "description": "Turn intent into action. Structure your thinking, execute your next step.",
5
5
  "bin": {
6
6
  "phewsh": "bin/phewsh.js"