project-compass 4.0.2 → 4.0.4
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.md +7 -0
- package/package.json +1 -1
- package/src/cli.js +25 -26
- package/src/components/AIHorizon.js +46 -41
package/commands.md
CHANGED
|
@@ -92,3 +92,10 @@ Compass scans for the following manifests and requires their binaries in your PA
|
|
|
92
92
|
- Go (mod init)
|
|
93
93
|
- **Enter**: Confirm selection and move to next step.
|
|
94
94
|
- **Esc / Shift+N**: Exit architect mode.
|
|
95
|
+
|
|
96
|
+
## Advanced Configuration
|
|
97
|
+
|
|
98
|
+
You can manually edit the config file to change defaults:
|
|
99
|
+
- **Location**: `~/.project-compass/config.json`
|
|
100
|
+
- **maxVisibleProjects**: Adjust how many projects appear per page (default: 3).
|
|
101
|
+
- **aiProvider / aiModel / aiToken**: Change your AI intelligence settings.
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -294,7 +294,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
294
294
|
|
|
295
295
|
useInput((input, key) => {
|
|
296
296
|
if (quitConfirm) {
|
|
297
|
-
if (input?.toLowerCase() === 'y') { killAllTasks();
|
|
297
|
+
if (input?.toLowerCase() === 'y') { killAllTasks(); process.stdout.write('\x1b[2J\x1b[0;0H'); exit(); return; }
|
|
298
298
|
if (input?.toLowerCase() === 'n' || key.escape) { setQuitConfirm(false); return; }
|
|
299
299
|
return;
|
|
300
300
|
}
|
|
@@ -468,7 +468,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
468
468
|
return;
|
|
469
469
|
}
|
|
470
470
|
if (shiftCombo('q') || isCtrlC) {
|
|
471
|
-
if (hasRunningTasks) setQuitConfirm(true); else {
|
|
471
|
+
if (hasRunningTasks) setQuitConfirm(true); else { process.stdout.write('\x1b[2J\x1b[0;0H'); exit(); }
|
|
472
472
|
return;
|
|
473
473
|
}
|
|
474
474
|
|
|
@@ -498,10 +498,10 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
498
498
|
}
|
|
499
499
|
});
|
|
500
500
|
|
|
501
|
-
const projectCountLabel = useMemo(() => `${projects.length} project
|
|
501
|
+
const projectCountLabel = useMemo(() => `${projects.length} project${projects.length === 1 ? '' : 's'}`, [projects.length]);
|
|
502
502
|
const toggleHint = config.showHelpCards ? 'Shift+H hide help' : 'Shift+H show help';
|
|
503
|
-
const statusHint = activeTask ? `[
|
|
504
|
-
const orbitHint = mainView === 'tasks' ? 'Tasks View' : `Orbit:
|
|
503
|
+
const statusHint = activeTask ? `[${activeTask.status.toUpperCase()}] ${activeTask.name}` : 'Idle Navigator';
|
|
504
|
+
const orbitHint = mainView === 'tasks' ? 'Tasks View' : `Orbit: ${tasks.length} tasks`;
|
|
505
505
|
const artHint = config.showArtBoard ? 'Shift+B hide art' : 'Shift+B show art';
|
|
506
506
|
|
|
507
507
|
const detailContent = useMemo(() => {
|
|
@@ -511,28 +511,28 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
511
511
|
|
|
512
512
|
const content = [
|
|
513
513
|
create(Box, {key: 'title-row', flexDirection: 'row'},
|
|
514
|
-
create(Text, {color: 'cyan', bold: true},
|
|
514
|
+
create(Text, {color: 'cyan', bold: true}, `${selectedProject.icon} ${selectedProject.name}`),
|
|
515
515
|
selectedProject.missingBinaries && selectedProject.missingBinaries.length > 0 && create(Text, {color: 'red', bold: true}, ' ⚠️ MISSING RUNTIME')
|
|
516
516
|
),
|
|
517
|
-
create(Text, {key: 'manifest', dimColor: true},
|
|
518
|
-
create(Text, {key: 'loc', dimColor: true}, `Location:
|
|
517
|
+
create(Text, {key: 'manifest', dimColor: true}, `${selectedProject.type} · ${selectedProject.manifest || 'detected manifest'}`),
|
|
518
|
+
create(Text, {key: 'loc', dimColor: true}, `Location: ${path.relative(rootPath, selectedProject.path) || '.'}`)
|
|
519
519
|
];
|
|
520
520
|
if (selectedProject.description) content.push(create(Text, {key: 'desc'}, selectedProject.description));
|
|
521
|
-
const frameworks = (selectedProject.frameworks || []).map((lib) =>
|
|
522
|
-
if (frameworks) content.push(create(Text, {key: 'frames', dimColor: true}, `Frameworks:
|
|
521
|
+
const frameworks = (selectedProject.frameworks || []).map((lib) => `${lib.icon} ${lib.name}`).join(', ');
|
|
522
|
+
if (frameworks) content.push(create(Text, {key: 'frames', dimColor: true}, `Frameworks: ${frameworks}`));
|
|
523
523
|
|
|
524
524
|
if (selectedProject.missingBinaries && selectedProject.missingBinaries.length > 0) {
|
|
525
525
|
content.push(
|
|
526
526
|
create(Text, {key: 'm-t', color: 'red', bold: true, marginTop: 1}, 'MISSING BINARIES:'),
|
|
527
|
-
create(Text, {key: 'm-l', color: 'red'}, `Please install:
|
|
527
|
+
create(Text, {key: 'm-l', color: 'red'}, `Please install: ${selectedProject.missingBinaries.join(', ')}`)
|
|
528
528
|
);
|
|
529
529
|
}
|
|
530
530
|
|
|
531
531
|
content.push(create(Text, {key: 'cmd-header', bold: true, marginTop: 1}, 'Commands'));
|
|
532
532
|
detailedIndexed.forEach((command) => {
|
|
533
533
|
content.push(
|
|
534
|
-
create(Text, {key: `d
|
|
535
|
-
create(Text, {key: `dl
|
|
534
|
+
create(Text, {key: `d-${command.shortcut}`}, `${command.shortcut}. ${command.label} ${command.source === 'custom' ? kleur.magenta('(custom)') : command.source === 'framework' ? kleur.cyan('(framework)') : ''}`),
|
|
535
|
+
create(Text, {key: `dl-${command.shortcut}`, dimColor: true}, ` ↳ ${command.command.join(' ')}`)
|
|
536
536
|
);
|
|
537
537
|
});
|
|
538
538
|
content.push(create(Text, {key: 'h-l', dimColor: true, marginTop: 1}, 'Press Shift+C → label|cmd to save custom actions, Enter to close detail view.'));
|
|
@@ -540,17 +540,17 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
540
540
|
}, [viewMode, selectedProject, rootPath, detailedIndexed]);
|
|
541
541
|
|
|
542
542
|
const artTileNodes = useMemo(() => [
|
|
543
|
-
{label: 'Pulse', detail: projectCountLabel, accent: 'magenta', icon: '●', subtext: `Workspace ·
|
|
544
|
-
{label: 'Focus', detail: selectedProject?.name || 'Selection', accent: 'cyan', icon: '◆', subtext:
|
|
545
|
-
{label: 'Orbit', detail:
|
|
543
|
+
{label: 'Pulse', detail: projectCountLabel, accent: 'magenta', icon: '●', subtext: `Workspace · ${path.basename(rootPath) || rootPath}`},
|
|
544
|
+
{label: 'Focus', detail: selectedProject?.name || 'Selection', accent: 'cyan', icon: '◆', subtext: `${selectedProject?.type || 'Stack'}`},
|
|
545
|
+
{label: 'Orbit', detail: `${tasks.length} tasks`, accent: 'yellow', icon: '■', subtext: running ? 'Busy streaming...' : 'Idle'}
|
|
546
546
|
].map(tile => create(Box, {key: tile.label, flexDirection: 'column', padding: 1, marginRight: 1, borderStyle: 'single', borderColor: tile.accent, minWidth: 24},
|
|
547
|
-
create(Text, {color: tile.accent, bold: true},
|
|
547
|
+
create(Text, {color: tile.accent, bold: true}, `${tile.icon} ${tile.label}`),
|
|
548
548
|
create(Text, {bold: true}, tile.detail),
|
|
549
549
|
create(Text, {dimColor: true}, tile.subtext)
|
|
550
550
|
)), [projectCountLabel, rootPath, selectedProject, tasks.length, running]);
|
|
551
551
|
|
|
552
552
|
if (quitConfirm) {
|
|
553
|
-
return create(Box, {flexDirection: 'column', borderStyle: 'round', borderColor: 'red', padding: 1}, create(Text, {bold: true, color: 'red'}, '⚠️ Confirm Exit'), create(Text, null, `There are
|
|
553
|
+
return create(Box, {flexDirection: 'column', borderStyle: 'round', borderColor: 'red', padding: 1}, create(Text, {bold: true, color: 'red'}, '⚠️ Confirm Exit'), create(Text, null, `There are ${tasks.filter(t=>t.status==='running').length} tasks still running in the background.`), create(Text, null, 'Are you sure you want to quit and stop all processes?'), create(Text, {marginTop: 1}, kleur.bold('Y') + ' to Quit, ' + kleur.bold('N') + ' to Cancel'));
|
|
554
554
|
}
|
|
555
555
|
|
|
556
556
|
const renderView = () => {
|
|
@@ -576,16 +576,16 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
576
576
|
create(Box, {flexGrow: 1.3, flexBasis: 0, minWidth: DETAILS_MIN_WIDTH, borderStyle: 'round', borderColor: 'cyan', padding: 1, flexDirection: 'column'}, create(Text, {bold: true, color: 'cyan'}, 'Details'), ...detailContent)
|
|
577
577
|
),
|
|
578
578
|
create(Box, {key: 'output-row', marginTop: 1, flexDirection: 'column'},
|
|
579
|
-
create(Box, {flexDirection: 'row', justifyContent: 'space-between'}, create(Text, {bold: true, color: 'yellow'}, `Output:
|
|
579
|
+
create(Box, {flexDirection: 'row', justifyContent: 'space-between'}, create(Text, {bold: true, color: 'yellow'}, `Output: ${activeTask?.name || 'None'}`), create(Text, {dimColor: true}, logOffset ? `Scrolled ${logOffset} lines` : 'Live log view')),
|
|
580
580
|
create(OutputPanel, {activeTask, logOffset}),
|
|
581
581
|
create(Footer, {toggleHint, running, stdinBuffer, stdinCursor, CursorText})
|
|
582
582
|
),
|
|
583
583
|
config.showHelpCards && create(Box, {key: 'help-cards', marginTop: 1, flexDirection: 'row', justifyContent: 'space-between', flexWrap: 'wrap'}, [
|
|
584
|
-
{label: 'Navigation', color: 'magenta', body: ['
|
|
584
|
+
{label: 'Navigation', color: 'magenta', body: ['↑/↓: focus, PgUp/Dn: Page, Enter: Details', 'Shift+↑ / ↓ scroll output', 'Shift+H toggle help cards', 'Shift+D detach from task']},
|
|
585
585
|
{label: 'Management', color: 'cyan', body: ['Shift+P Package Registry', 'Shift+N Project Architect', 'Shift+X clear / Shift+E export']},
|
|
586
|
-
{label: 'Orbit & AI', color: 'yellow', body: ['Shift+T
|
|
586
|
+
{label: 'Orbit & AI', color: 'yellow', body: ['Shift+T: Tasks, Shift+O: AI, 0: Analyze', 'Shift+A studio / Shift+O AI Horizon', 'Shift+S structure / Shift+Q quit']}
|
|
587
587
|
].map((card, idx) => create(Box, {key: card.label, flexGrow: 1, flexBasis: 0, minWidth: HELP_CARD_MIN_WIDTH, marginRight: idx < 2 ? 1 : 0, marginBottom: 1, borderStyle: 'round', borderColor: card.color, padding: 1, flexDirection: 'column'}, create(Text, {color: card.color, bold: true, marginBottom: 1}, card.label), ...card.body.map((line, lidx) => create(Text, {key: lidx, dimColor: card.color === 'yellow'}, line))))),
|
|
588
|
-
config.showStructureGuide && create(Box, {key: 'structure', flexDirection: 'column', borderStyle: 'round', borderColor: 'blue', marginTop: 1, padding: 1}, create(Text, {color: 'cyan', bold: true}, 'Structure guide · press Shift+S to hide'), ...SCHEMA_GUIDE.map(e => create(Text, {key: e.type, dimColor: true}, `•
|
|
588
|
+
config.showStructureGuide && create(Box, {key: 'structure', flexDirection: 'column', borderStyle: 'round', borderColor: 'blue', marginTop: 1, padding: 1}, create(Text, {color: 'cyan', bold: true}, 'Structure guide · press Shift+S to hide'), ...SCHEMA_GUIDE.map(e => create(Text, {key: e.type, dimColor: true}, `• ${e.icon} ${e.label}: ${e.files.join(', ')}`))),
|
|
589
589
|
showHelp && create(Box, {key: 'overlay', flexDirection: 'column', borderStyle: 'double', borderColor: 'cyan', marginTop: 1, padding: 1}, create(Text, {color: 'cyan', bold: true}, 'Help overlay'), create(Text, null, 'Shift+↑/↓ scrolls logs; Shift+X clears; Shift+E exports; Shift+A Studio; Shift+T Tasks; Shift+D Detach; Shift+B Toggle Art Board; Shift+P Packages; Shift+N Creator; Shift+O AI Horizon.'))
|
|
590
590
|
];
|
|
591
591
|
return create(Box, {flexDirection: 'column'}, ...navigatorBody);
|
|
@@ -618,11 +618,10 @@ async function main() {
|
|
|
618
618
|
if (args.version) {
|
|
619
619
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
620
620
|
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '../package.json'), 'utf-8'));
|
|
621
|
-
console.log(`v
|
|
621
|
+
console.log(`v${pkg.version}`);
|
|
622
622
|
return;
|
|
623
623
|
}
|
|
624
624
|
if (args.help) {
|
|
625
|
-
console.clear();
|
|
626
625
|
console.log(kleur.bold(kleur.magenta('🧭 Project Compass · Premium Developer Cockpit')));
|
|
627
626
|
console.log(kleur.dim('───────────────────────────────────────────────────'));
|
|
628
627
|
console.log('');
|
|
@@ -664,8 +663,8 @@ async function main() {
|
|
|
664
663
|
const rootPath = args.root ? path.resolve(args.root) : process.cwd();
|
|
665
664
|
if (args.mode === 'test') {
|
|
666
665
|
const projects = await discoverProjects(rootPath);
|
|
667
|
-
console.log(`Detected
|
|
668
|
-
projects.forEach((project) => { console.log(` • [
|
|
666
|
+
console.log(`Detected ${projects.length} project(s) under ${rootPath}`);
|
|
667
|
+
projects.forEach((project) => { console.log(` • [${project.type}] ${project.name} (${project.path})`); });
|
|
669
668
|
return;
|
|
670
669
|
}
|
|
671
670
|
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
+
/* global setTimeout */
|
|
1
2
|
import React, {useState, memo} from 'react';
|
|
2
3
|
import {Box, Text, useInput} from 'ink';
|
|
3
4
|
|
|
4
5
|
const create = React.createElement;
|
|
5
6
|
|
|
6
7
|
const AI_PROVIDERS = [
|
|
7
|
-
{ id: 'openrouter', name: 'OpenRouter', endpoint: 'https://openrouter.ai/api/v1'
|
|
8
|
-
{ id: 'gemini', name: 'Google Gemini', endpoint: 'https://generativelanguage.googleapis.com'
|
|
9
|
-
{ id: 'claude', name: 'Anthropic Claude', endpoint: 'https://api.anthropic.com'
|
|
10
|
-
{ id: 'ollama', name: 'Ollama (Local)', endpoint: 'http://localhost:11434'
|
|
8
|
+
{ id: 'openrouter', name: 'OpenRouter', endpoint: 'https://openrouter.ai/api/v1' },
|
|
9
|
+
{ id: 'gemini', name: 'Google Gemini', endpoint: 'https://generativelanguage.googleapis.com' },
|
|
10
|
+
{ id: 'claude', name: 'Anthropic Claude', endpoint: 'https://api.anthropic.com' },
|
|
11
|
+
{ id: 'ollama', name: 'Ollama (Local)', endpoint: 'http://localhost:11434' }
|
|
11
12
|
];
|
|
12
13
|
|
|
13
|
-
const AIHorizon = memo(({
|
|
14
|
+
const AIHorizon = memo(({selectedProject, CursorText, config, setConfig, saveConfig}) => {
|
|
14
15
|
const [step, setStep] = useState(config?.aiToken ? 'analyze' : 'provider');
|
|
15
16
|
const [providerIdx, setProviderIdx] = useState(AI_PROVIDERS.findIndex(p => p.id === (config?.aiProvider || 'openrouter')) || 0);
|
|
16
17
|
const [model, setModel] = useState(config?.aiModel || 'deepseek/deepseek-r1');
|
|
17
18
|
const [token, setToken] = useState(config?.aiToken || '');
|
|
18
19
|
const [cursor, setCursor] = useState(0);
|
|
19
20
|
const [status, setStatus] = useState('ready');
|
|
21
|
+
const [suggestions, setSuggestions] = useState([]);
|
|
20
22
|
|
|
21
23
|
useInput((input, key) => {
|
|
22
24
|
if (step === 'provider') {
|
|
@@ -24,18 +26,14 @@ const AIHorizon = memo(({rootPath, selectedProject, onRunCommand, CursorText, co
|
|
|
24
26
|
if (key.downArrow) setProviderIdx(p => (p + 1) % AI_PROVIDERS.length);
|
|
25
27
|
if (key.return) {
|
|
26
28
|
const nextConfig = { ...config, aiProvider: AI_PROVIDERS[providerIdx].id };
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
setStep('model');
|
|
30
|
-
setCursor(model.length);
|
|
29
|
+
setConfig(nextConfig); saveConfig(nextConfig);
|
|
30
|
+
setStep('model'); setCursor(model.length);
|
|
31
31
|
}
|
|
32
32
|
} else if (step === 'model') {
|
|
33
33
|
if (key.return) {
|
|
34
34
|
const nextConfig = { ...config, aiModel: model };
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
setStep('token');
|
|
38
|
-
setCursor(token.length);
|
|
35
|
+
setConfig(nextConfig); saveConfig(nextConfig);
|
|
36
|
+
setStep('token'); setCursor(token.length);
|
|
39
37
|
}
|
|
40
38
|
if (key.escape) setStep('provider');
|
|
41
39
|
if (key.backspace || key.delete) {
|
|
@@ -46,8 +44,7 @@ const AIHorizon = memo(({rootPath, selectedProject, onRunCommand, CursorText, co
|
|
|
46
44
|
} else if (step === 'token') {
|
|
47
45
|
if (key.return) {
|
|
48
46
|
const nextConfig = { ...config, aiToken: token };
|
|
49
|
-
|
|
50
|
-
if (saveConfig) saveConfig(nextConfig);
|
|
47
|
+
setConfig(nextConfig); saveConfig(nextConfig);
|
|
51
48
|
setStep('analyze');
|
|
52
49
|
}
|
|
53
50
|
if (key.escape) setStep('model');
|
|
@@ -60,31 +57,39 @@ const AIHorizon = memo(({rootPath, selectedProject, onRunCommand, CursorText, co
|
|
|
60
57
|
if (key.return && status === 'ready' && selectedProject) {
|
|
61
58
|
setStatus('busy');
|
|
62
59
|
setTimeout(() => {
|
|
60
|
+
// REAL DNA MAPPING: Check project scripts and suggest real matches
|
|
61
|
+
const scripts = selectedProject.metadata?.scripts || {};
|
|
62
|
+
const suggested = [];
|
|
63
|
+
|
|
64
|
+
if (scripts.build) suggested.push({ label: 'AI Build', command: ['npm', 'run', 'build'] });
|
|
65
|
+
if (scripts.start || scripts.dev) suggested.push({ label: 'AI Run', command: ['npm', 'run', scripts.dev ? 'dev' : 'start'] });
|
|
66
|
+
if (scripts.test) suggested.push({ label: 'AI Test', command: ['npm', 'test'] });
|
|
67
|
+
|
|
68
|
+
// If no scripts found, suggest generic ones based on type
|
|
69
|
+
if (suggested.length === 0) {
|
|
70
|
+
if (selectedProject.type === 'Node.js') suggested.push({ label: 'AI Init', command: ['npm', 'install'] });
|
|
71
|
+
else if (selectedProject.type === 'Python') suggested.push({ label: 'AI Run', command: ['python', 'main.py'] });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
setSuggestions(suggested);
|
|
63
75
|
const projectKey = selectedProject.path;
|
|
64
76
|
const currentCustom = config.customCommands?.[projectKey] || [];
|
|
65
77
|
const nextConfig = {
|
|
66
78
|
...config,
|
|
67
|
-
customCommands: {
|
|
68
|
-
...config.customCommands,
|
|
69
|
-
[projectKey]: [...currentCustom, { label: 'AI: Optimized Run', command: ['npm', 'run', 'dev'] }]
|
|
70
|
-
}
|
|
79
|
+
customCommands: { ...config.customCommands, [projectKey]: [...currentCustom, ...suggested] }
|
|
71
80
|
};
|
|
72
|
-
|
|
73
|
-
if (saveConfig) saveConfig(nextConfig);
|
|
81
|
+
setConfig(nextConfig); saveConfig(nextConfig);
|
|
74
82
|
setStatus('done');
|
|
75
|
-
},
|
|
83
|
+
}, 1200);
|
|
76
84
|
}
|
|
77
85
|
if (input === 'r') {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
if (saveConfig) saveConfig(resetConfig);
|
|
86
|
+
const nextConfig = { ...config, aiToken: '' };
|
|
87
|
+
setConfig(nextConfig); saveConfig(nextConfig);
|
|
81
88
|
setStep('provider');
|
|
82
89
|
}
|
|
83
90
|
}
|
|
84
91
|
});
|
|
85
92
|
|
|
86
|
-
const currentProvider = AI_PROVIDERS[providerIdx];
|
|
87
|
-
|
|
88
93
|
return create(
|
|
89
94
|
Box,
|
|
90
95
|
{flexDirection: 'column', borderStyle: 'double', borderColor: 'magenta', padding: 1, width: '100%'},
|
|
@@ -94,7 +99,7 @@ const AIHorizon = memo(({rootPath, selectedProject, onRunCommand, CursorText, co
|
|
|
94
99
|
Box,
|
|
95
100
|
{flexDirection: 'column'},
|
|
96
101
|
create(Text, {bold: true, marginBottom: 1}, 'Step 1: Select AI Infrastructure'),
|
|
97
|
-
...AI_PROVIDERS.map((p, i) => create(Text, {key: p.id, color: i === providerIdx ? 'cyan' : 'white'}, (i === providerIdx ? '→ ' : ' ') + p.name
|
|
102
|
+
...AI_PROVIDERS.map((p, i) => create(Text, {key: p.id, color: i === providerIdx ? 'cyan' : 'white'}, (i === providerIdx ? '→ ' : ' ') + p.name)),
|
|
98
103
|
create(Text, {dimColor: true, marginTop: 1}, 'Enter: Save & Next')
|
|
99
104
|
),
|
|
100
105
|
|
|
@@ -106,36 +111,36 @@ const AIHorizon = memo(({rootPath, selectedProject, onRunCommand, CursorText, co
|
|
|
106
111
|
create(Text, null, 'Model ID: '),
|
|
107
112
|
create(CursorText, {value: model, cursorIndex: cursor})
|
|
108
113
|
),
|
|
109
|
-
create(Text, {dimColor: true, marginTop: 1}, 'Enter: Save, Esc: Back')
|
|
114
|
+
create(Text, {dimColor: true, marginTop: 1}, 'Enter: Save Model, Esc: Back')
|
|
110
115
|
),
|
|
111
116
|
|
|
112
117
|
step === 'token' && create(
|
|
113
118
|
Box,
|
|
114
119
|
{flexDirection: 'column'},
|
|
115
|
-
create(Text, {bold: true, color: 'red', marginBottom: 1}, 'Step 3:
|
|
116
|
-
create(
|
|
117
|
-
|
|
118
|
-
create(Text, null, 'API Token: '),
|
|
120
|
+
create(Text, {bold: true, color: 'red', marginBottom: 1}, 'Step 3: API Token Authorization'),
|
|
121
|
+
create(Box, {flexDirection: 'row'},
|
|
122
|
+
create(Text, null, 'Token: '),
|
|
119
123
|
create(CursorText, {value: '*'.repeat(token.length), cursorIndex: cursor})
|
|
120
124
|
),
|
|
121
|
-
create(Text, {dimColor: true, marginTop: 1}, 'Enter:
|
|
125
|
+
create(Text, {dimColor: true, marginTop: 1}, 'Enter: Save Token, Esc: Back')
|
|
122
126
|
),
|
|
123
127
|
|
|
124
128
|
step === 'analyze' && create(
|
|
125
129
|
Box,
|
|
126
130
|
{flexDirection: 'column'},
|
|
127
|
-
create(Text, {bold: true, color: 'cyan', marginBottom: 1}, '
|
|
128
|
-
create(Text, {dimColor: true}, '
|
|
131
|
+
create(Text, {bold: true, color: 'cyan', marginBottom: 1}, 'Ready to analyze: ' + (selectedProject ? selectedProject.name : 'No project selected')),
|
|
132
|
+
create(Text, {dimColor: true}, 'Active: ' + config.aiProvider + ' (' + config.aiModel + ')'),
|
|
133
|
+
|
|
129
134
|
create(Box, {marginTop: 1, flexDirection: 'column'},
|
|
130
|
-
status === 'ready' && create(Text, null, 'Press Enter to
|
|
131
|
-
status === 'busy' && create(Text, {color: 'yellow'}, ' ⏳
|
|
135
|
+
status === 'ready' && create(Text, null, 'Press Enter to map project DNA and auto-configure macros.'),
|
|
136
|
+
status === 'busy' && create(Text, {color: 'yellow'}, ' ⏳ Reading manifests... identifying build patterns...'),
|
|
132
137
|
status === 'done' && create(Box, {flexDirection: 'column'},
|
|
133
138
|
create(Text, {color: 'green', bold: true}, ' ✅ DNA Mapped!'),
|
|
134
|
-
create(Text, null, '
|
|
135
|
-
create(Text, {dimColor: true, marginTop: 1}, '
|
|
139
|
+
create(Text, null, ' Identified ' + suggestions.length + ' valid commands based on your workspace structure.'),
|
|
140
|
+
create(Text, {dimColor: true, marginTop: 1}, 'Return to Navigator to use BRIT shortcuts.')
|
|
136
141
|
)
|
|
137
142
|
),
|
|
138
|
-
create(Text, {dimColor: true, marginTop: 1}, 'Esc:
|
|
143
|
+
create(Text, {dimColor: true, marginTop: 1}, 'Esc: Return, R: Reset Credentials')
|
|
139
144
|
)
|
|
140
145
|
);
|
|
141
146
|
});
|