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 +20 -27
- package/commands/session.js +85 -72
- package/commands/watch.js +12 -12
- package/lib/ui.js +40 -58
- package/package.json +1 -1
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('
|
|
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('
|
|
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('
|
|
83
|
-
console.log(` ${cyan('phewsh')}
|
|
84
|
-
console.log(` ${cyan('phewsh clarify')}
|
|
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('
|
|
88
|
-
console.log(` ${cyan('intent')}
|
|
89
|
-
console.log(` ${cyan('gate')}
|
|
90
|
-
console.log(` ${cyan('context')}
|
|
91
|
-
console.log(` ${cyan('ai')}
|
|
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('
|
|
95
|
-
console.log(` ${cyan('pull')}
|
|
96
|
-
console.log(` ${cyan('
|
|
97
|
-
console.log(` ${cyan('
|
|
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 bridge — run 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('
|
|
100
|
-
console.log(` ${cyan('
|
|
101
|
-
console.log(` ${cyan('link')}
|
|
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(` ${
|
|
104
|
-
console.log(`
|
|
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
|
|
package/commands/session.js
CHANGED
|
@@ -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(`
|
|
219
|
-
console.log(`
|
|
220
|
-
console.log(`
|
|
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
|
-
|
|
231
|
+
statusParts.push(teal('●') + sage(` .intent/ (${intentFiles.length} files)`));
|
|
243
232
|
} else {
|
|
244
|
-
|
|
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
|
-
//
|
|
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
|
|
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
|
|
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(` ${
|
|
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
|
-
|
|
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('
|
|
330
|
-
console.log(` ${teal('/init')} ${sage('Create .intent/
|
|
331
|
-
console.log(` ${teal('/clarify')} ${sage('
|
|
332
|
-
console.log(` ${teal('/gate')} ${sage('
|
|
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/
|
|
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('/
|
|
340
|
-
console.log(` ${teal('/
|
|
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('
|
|
344
|
-
console.log(` ${teal('/
|
|
345
|
-
console.log(` ${teal('/
|
|
346
|
-
console.log(` ${teal('/
|
|
347
|
-
console.log(` ${teal('/
|
|
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('
|
|
352
|
-
console.log(` ${teal('/
|
|
353
|
-
console.log(` ${teal('/
|
|
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(` ${
|
|
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 →
|
|
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 —
|
|
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
|
|
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.
|
|
332
|
-
2.
|
|
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
|
-
|
|
335
|
-
edit
|
|
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
|
-
-
|
|
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('
|
|
356
|
-
console.log(` ${g('
|
|
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
|
|
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(
|
|
15
|
-
const slate = rgb(
|
|
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 = '
|
|
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
|
-
`${
|
|
231
|
-
`${
|
|
232
|
-
`${
|
|
233
|
-
`${
|
|
234
|
-
`${
|
|
235
|
-
`${
|
|
236
|
-
`${
|
|
237
|
-
`${
|
|
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: '
|
|
247
|
+
title: 'The idea',
|
|
248
248
|
body: [
|
|
249
249
|
'',
|
|
250
|
-
`
|
|
251
|
-
` ${
|
|
250
|
+
` Every AI tool you use asks the same question:`,
|
|
251
|
+
` ${slate('"What are you building?"')}`,
|
|
252
252
|
'',
|
|
253
|
-
`
|
|
254
|
-
`
|
|
253
|
+
` ${teal('.intent/')} ${sage('answers it once. Every tool reads it.')}`,
|
|
254
|
+
` Plain markdown. Committed with your code. No lock-in.`,
|
|
255
255
|
'',
|
|
256
|
-
`
|
|
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
|
|
260
|
+
title: 'The files',
|
|
265
261
|
body: [
|
|
266
262
|
'',
|
|
267
263
|
` ${teal('.intent/')}`,
|
|
268
|
-
` ${peach('vision.md')} ${sage('What
|
|
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('
|
|
271
|
-
` ${ember('gate.json')} ${sage('
|
|
266
|
+
` ${peach('next.md')} ${sage('What to do right now')}`,
|
|
267
|
+
` ${ember('gate.json')} ${sage('Constraints: budget, time, skill')}`,
|
|
272
268
|
'',
|
|
273
|
-
` ${
|
|
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: '
|
|
274
|
+
title: 'Sync everywhere',
|
|
278
275
|
body: [
|
|
279
276
|
'',
|
|
280
|
-
`
|
|
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('
|
|
295
|
-
` ${b(cream('Cursor'))} ${sage('
|
|
296
|
-
` ${b(cream('ChatGPT'))} ${sage('
|
|
297
|
-
` ${b(cream('MCP agents'))} ${sage('
|
|
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('
|
|
300
|
-
` ${sage('Switch tools mid-thought. Nothing lost.')}`,
|
|
284
|
+
` ${sage('Switch tools mid-thought. Context follows.')}`,
|
|
301
285
|
]
|
|
302
286
|
},
|
|
303
287
|
{
|
|
304
|
-
title: '
|
|
288
|
+
title: 'Constraints',
|
|
305
289
|
body: [
|
|
306
290
|
'',
|
|
307
|
-
`
|
|
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('
|
|
314
|
-
` ${sage('
|
|
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: '
|
|
301
|
+
title: 'Go',
|
|
319
302
|
body: [
|
|
320
303
|
'',
|
|
321
|
-
` ${teal('
|
|
322
|
-
` ${teal('
|
|
323
|
-
` ${teal('
|
|
324
|
-
` ${teal('
|
|
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('
|
|
327
|
-
` ${sage('The exhale before execution.')}`,
|
|
309
|
+
` ${sage('Intent-driven development. Define once. Work everywhere.')}`,
|
|
328
310
|
]
|
|
329
311
|
},
|
|
330
312
|
];
|