project-compass 4.0.2 → 4.0.3
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/package.json +1 -1
- package/src/cli.js +21 -21
- package/src/components/AIHorizon.js +2 -1
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -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,7 +576,7 @@ 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
|
),
|
|
@@ -585,7 +585,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
585
585
|
{label: 'Management', color: 'cyan', body: ['Shift+P Package Registry', 'Shift+N Project Architect', 'Shift+X clear / Shift+E export']},
|
|
586
586
|
{label: 'Orbit & AI', color: 'yellow', body: ['Shift+T task manager', '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,7 +618,7 @@ 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) {
|
|
@@ -664,8 +664,8 @@ async function main() {
|
|
|
664
664
|
const rootPath = args.root ? path.resolve(args.root) : process.cwd();
|
|
665
665
|
if (args.mode === 'test') {
|
|
666
666
|
const projects = await discoverProjects(rootPath);
|
|
667
|
-
console.log(`Detected
|
|
668
|
-
projects.forEach((project) => { console.log(` • [
|
|
667
|
+
console.log(`Detected ${projects.length} project(s) under ${rootPath}`);
|
|
668
|
+
projects.forEach((project) => { console.log(` • [${project.type}] ${project.name} (${project.path})`); });
|
|
669
669
|
return;
|
|
670
670
|
}
|
|
671
671
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* global setTimeout */
|
|
1
2
|
import React, {useState, memo} from 'react';
|
|
2
3
|
import {Box, Text, useInput} from 'ink';
|
|
3
4
|
|
|
@@ -10,7 +11,7 @@ const AI_PROVIDERS = [
|
|
|
10
11
|
{ id: 'ollama', name: 'Ollama (Local)', endpoint: 'http://localhost:11434', keyEnv: 'NONE' }
|
|
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');
|