project-compass 3.9.4 → 3.9.5

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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  This document lists all supported languages, frameworks, and their built-in commands and keyboard shortcuts.
4
4
 
5
- ## Keyboard Guide (Navigator)
5
+ ## Keyboard Guide (Navigator)\n\n| Key | Action |\n| --- | --- |\n| **Shift+O** | Open **AI Horizon** (Workspace Intelligence) |
6
6
 
7
7
  | Key | Action |
8
8
  | --- | --- |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-compass",
3
- "version": "3.9.4",
3
+ "version": "3.9.5",
4
4
  "description": "Futuristic project navigator and runner for Node, Python, Rust, and Go",
5
5
  "main": "src/cli.js",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -14,6 +14,7 @@ import Studio from './components/Studio.js';
14
14
  import TaskManager from './components/TaskManager.js';
15
15
  import PackageRegistry from './components/PackageRegistry.js';
16
16
  import ProjectArchitect from './components/ProjectArchitect.js';
17
+ import AIHorizon from './components/AIHorizon.js';
17
18
  import Navigator from './components/Navigator.js';
18
19
  import Header from './components/Header.js';
19
20
  import Footer from './components/Footer.js';
@@ -421,7 +422,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
421
422
  return;
422
423
  }
423
424
 
424
- if (mainView === 'registry' || mainView === 'architect') {
425
+ if (mainView === 'registry' || mainView === 'architect' || mainView === 'ai') {
425
426
  return;
426
427
  }
427
428
 
@@ -450,7 +451,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
450
451
  if (key.shift && key.upArrow) { scrollLogs(1); return; }
451
452
  if (key.shift && key.downArrow) { scrollLogs(-1); return; }
452
453
 
453
- const pageStep = Math.max(1, config.maxVisibleProjects || 8);
454
+ const pageStep = Math.max(1, config.maxVisibleProjects || 3);
454
455
  const clampIndex = (value) => Math.max(0, Math.min(projects.length - 1, value));
455
456
  if (key.pageUp && projects.length > 0) { console.clear(); setSelectedIndex((prev) => clampIndex(prev - pageStep)); return; }
456
457
  if (key.pageDown && projects.length > 0) { console.clear(); setSelectedIndex((prev) => clampIndex(prev + pageStep)); return; }
@@ -483,7 +484,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
483
484
  runProjectCommand(detailShortcutMap.get(normalizedInput), selectedProject);
484
485
  return;
485
486
  }
486
- const reserved = ['a', 'p', 'n', 'x', 'e', 'd', 'b', 't', 'q', 'h', 's', 'l', 'c', 'i'];
487
+ const reserved = ['a', 'p', 'n', 'x', 'e', 'd', 'b', 't', 'q', 'h', 's', 'l', 'c', 'i', 'o'];
487
488
  if (key.shift && !reserved.includes(normalizedInput)) {
488
489
  runProjectCommand(detailShortcutMap.get(normalizedInput), selectedProject);
489
490
  return;
@@ -552,6 +553,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
552
553
  case 'tasks': return create(TaskManager, {tasks, activeTaskId, renameMode, renameInput, renameCursor, CursorText});
553
554
  case 'registry': return create(PackageRegistry, {selectedProject, projects, onRunCommand: runProjectCommand, CursorText, onSelectProject: (idx) => setSelectedIndex(idx)});
554
555
  case 'architect': return create(ProjectArchitect, {rootPath, onRunCommand: runProjectCommand, CursorText, onReturn: () => setMainView('navigator')});
556
+ case 'ai': return create(AIHorizon, {rootPath, selectedProject, onRunCommand: runProjectCommand, CursorText});
555
557
  default: {
556
558
  const navigatorBody = [
557
559
  create(Header, {projectCountLabel, rootPath, running, statusHint, toggleHint, orbitHint, artHint}),
@@ -575,10 +577,10 @@ function Compass({rootPath, initialView = 'navigator'}) {
575
577
  config.showHelpCards && create(Box, {key: 'help-cards', marginTop: 1, flexDirection: 'row', justifyContent: 'space-between', flexWrap: 'wrap'}, [
576
578
  {label: 'Navigation', color: 'magenta', body: ['↑ / ↓ move focus, Enter: details', 'Shift+↑ / ↓ scroll output', 'Shift+H toggle help cards', 'Shift+D detach from task']},
577
579
  {label: 'Management', color: 'cyan', body: ['Shift+P Package Registry', 'Shift+N Project Architect', 'Shift+X clear / Shift+E export']},
578
- {label: 'Orbit & Studio', color: 'yellow', body: ['Shift+T task manager', 'Shift+A studio / Shift+B art board', 'Shift+S structure / Shift+Q quit']}
580
+ {label: 'Orbit & AI', color: 'yellow', body: ['Shift+T task manager', 'Shift+A studio / Shift+O AI Horizon', 'Shift+S structure / Shift+Q quit']}
579
581
  ].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))))),
580
582
  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(', ')}`))),
581
- 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.'))
583
+ 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.'))
582
584
  ];
583
585
  return create(Box, {flexDirection: 'column'}, ...navigatorBody);
584
586
  }
@@ -623,10 +625,12 @@ async function main() {
623
625
  console.log(' Shift+T ' + kleur.bold('Orbit Task Manager') + ' - Manage background processes & stream logs');
624
626
  console.log(' Shift+P ' + kleur.bold('Package Registry') + ' - Direct dependency management (add/remove)');
625
627
  console.log(' Shift+N ' + kleur.bold('Project Architect') + ' - Scaffold new projects from templates');
628
+ console.log(' Shift+O ' + kleur.bold('AI Horizon') + ' - Intelligent project analysis & commands');
626
629
  console.log(' Shift+A ' + kleur.bold('Omni-Studio') + ' - Environment & runtime health audit');
627
630
  console.log('');
628
631
  console.log(kleur.bold(kleur.yellow('🎮 Navigation & Details:')));
629
632
  console.log(' ↑ / ↓ Move focus through discovered projects');
633
+ console.log(' PgUp/Dn Jump a full page of projects');
630
634
  console.log(' Enter Toggle deep detail view (manifests, scripts, frameworks)');
631
635
  console.log(' Shift+C Add a persistent custom command to the focused project');
632
636
  console.log(' 1-9 Quick-run numbered scripts in detail view');
@@ -0,0 +1,48 @@
1
+ import React, {useState, memo} from 'react';
2
+ import {Box, Text, useInput} from 'ink';
3
+
4
+ const create = React.createElement;
5
+
6
+ const AI_PROVIDERS = [
7
+ { id: 'ollama', name: 'Ollama (Local)', endpoint: 'http://localhost:11434' },
8
+ { id: 'gemini', name: 'Google Gemini', endpoint: 'api.google.com' },
9
+ { id: 'claude', name: 'Anthropic Claude', endpoint: 'api.anthropic.com' }
10
+ ];
11
+
12
+ const AIHorizon = memo(({rootPath, selectedProject, onRunCommand, CursorText}) => {
13
+ const [step, setStep] = useState('select');
14
+ const [providerIdx, setProviderIdx] = useState(0);
15
+
16
+ useInput((input, key) => {
17
+ if (step === 'select') {
18
+ if (key.upArrow) setProviderIdx(p => (p - 1 + AI_PROVIDERS.length) % AI_PROVIDERS.length);
19
+ if (key.downArrow) setProviderIdx(p => (p + 1) % AI_PROVIDERS.length);
20
+ if (key.return) setStep('analyze');
21
+ }
22
+ });
23
+
24
+ return create(
25
+ Box,
26
+ {flexDirection: 'column', borderStyle: 'double', borderColor: 'magenta', padding: 1, width: '100%'},
27
+ create(Text, {bold: true, color: 'magenta'}, '🤖 AI Horizon | Intelligent Workspace Analysis'),
28
+ create(Text, {dimColor: true, marginBottom: 1}, 'Powering your terminal with agentic intelligence.'),
29
+
30
+ step === 'select' && create(
31
+ Box,
32
+ {flexDirection: 'column'},
33
+ create(Text, {bold: true, marginBottom: 1}, 'Step 1: Select AI Intelligence Engine'),
34
+ ...AI_PROVIDERS.map((p, i) => create(Text, {key: p.id, color: i === providerIdx ? 'cyan' : 'white'}, (i === providerIdx ? '→ ' : ' ') + p.name + ' (' + p.endpoint + ')')),
35
+ create(Text, {dimColor: true, marginTop: 1}, 'Enter: Connect & Analyze Project, Esc: Return')
36
+ ),
37
+
38
+ step === 'analyze' && create(
39
+ Box,
40
+ {flexDirection: 'column'},
41
+ create(Text, {bold: true, color: 'yellow', marginBottom: 1}, 'Analyzing Workspace...'),
42
+ create(Text, null, ' ⏳ Deep scanning project DNA... [AI Synced]'),
43
+ create(Text, {marginTop: 1}, 'Esc: Back to Selection')
44
+ )
45
+ );
46
+ });
47
+
48
+ export default AIHorizon;