project-compass 4.3.6 → 4.3.8
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/AGENTS.md +1121 -22
- package/ARCHITECTURE.md +826 -10
- package/CONTRIBUTING.md +974 -10
- package/PROJECT_CONTEXT.md +404 -0
- package/README.md +637 -67
- package/assets/screenshots/ai_mode.png +0 -0
- package/assets/screenshots/art_bar.png +0 -0
- package/assets/screenshots/help_structure.png +0 -0
- package/assets/screenshots/home.png +0 -0
- package/assets/screenshots/languages_checker_omni_studio.png +0 -0
- package/assets/screenshots/task_manager.png +0 -0
- package/commands.md +841 -104
- package/package.json +5 -4
- package/src/cli.js +310 -169
- package/src/components/AIHorizon.js +138 -255
- package/src/components/Footer.js +8 -64
- package/src/components/Header.js +8 -47
- package/src/components/Navigator.js +16 -70
- package/src/components/PackageRegistry.js +4 -3
- package/src/components/ProjectArchitect.js +6 -1
- package/src/components/TaskManager.js +12 -70
- package/src/detectors/dotnet.js +3 -2
- package/src/detectors/frameworks.js +28 -28
- package/src/detectors/go.js +6 -6
- package/src/detectors/java.js +2 -1
- package/src/detectors/node.js +3 -2
- package/src/detectors/php.js +1 -1
- package/src/detectors/python.js +11 -4
- package/src/detectors/ruby.js +1 -1
- package/src/detectors/rust.js +2 -2
- package/src/detectors/utils.js +6 -7
- package/src/projectDetection.js +41 -5
- package/assets/screenshots/architect.jpg +0 -0
- package/assets/screenshots/artboard.jpg +0 -0
- package/assets/screenshots/exit-confirm.jpg +0 -0
- package/assets/screenshots/navigator.jpg +0 -0
- package/assets/screenshots/overlays.jpg +0 -0
- package/assets/screenshots/registry.jpg +0 -0
- package/assets/screenshots/studio.jpg +0 -0
- package/assets/screenshots/taskmanager.jpg +0 -0
- package/src/store/useProjectStore.js +0 -32
package/AGENTS.md
CHANGED
|
@@ -1,34 +1,1133 @@
|
|
|
1
1
|
# AGENTS.md - Project Compass Workspace
|
|
2
2
|
|
|
3
|
-
Welcome to Project Compass. This file provides context for AI agents (Clawdy, Claude, Copilot, etc.) working on this repository.
|
|
3
|
+
Welcome to Project Compass. This file provides **COMPLETE** context for AI agents (Clawdy, Claude, Copilot, GPT, etc.) working on this repository.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
1. [Overview](#overview)
|
|
10
|
+
2. [Version Information](#version-information)
|
|
11
|
+
3. [Project Structure](#project-structure)
|
|
12
|
+
4. [Tech Stack](#tech-stack)
|
|
13
|
+
5. [Development Rules](#development-rules)
|
|
14
|
+
6. [File Reference Quick Links](#file-reference-quick-links)
|
|
15
|
+
7. [CLI Arguments (Complete List)](#cli-arguments-complete-list)
|
|
16
|
+
8. [TUI Keyboard Shortcuts (Complete List)](#tui-keyboard-shortcuts-complete-list)
|
|
17
|
+
9. [Supported Languages](#supported-languages)
|
|
18
|
+
10. [Built-in Frameworks](#built-in-frameworks)
|
|
19
|
+
11. [Recent Fixes (v4.3.6)](#recent-fixes-v436)
|
|
20
|
+
12. [Component Details](#component-details)
|
|
21
|
+
13. [Detection System](#detection-system)
|
|
22
|
+
14. [State Management](#state-management)
|
|
23
|
+
15. [Command Execution Flow](#command-execution-flow)
|
|
24
|
+
16. [Configuration System](#configuration-system)
|
|
25
|
+
17. [Known Issues & TODO](#known-issues--todo)
|
|
26
|
+
18. [Testing Checklist](#testing-checklist)
|
|
27
|
+
|
|
28
|
+
---
|
|
4
29
|
|
|
5
30
|
## Overview
|
|
6
|
-
|
|
31
|
+
|
|
32
|
+
**Project Compass** is a futuristic project navigator and runner designed for modern polygot development. It provides a high-fidelity terminal UI (using Ink) to manage complex workspaces with integrated Agentic AI intelligence.
|
|
33
|
+
|
|
34
|
+
**Version:** 4.3.7
|
|
35
|
+
**Last Updated:** 2026-05-10
|
|
36
|
+
**Author:** Satyaa & Clawdy
|
|
37
|
+
**License:** MIT
|
|
38
|
+
**Repository:** https://github.com/CrimsonDevil333333/project-compass
|
|
39
|
+
|
|
40
|
+
### Key Features
|
|
41
|
+
|
|
42
|
+
- **Multi-Language Detection**: Node.js, Python, Rust, Go, Java, PHP, Ruby, .NET
|
|
43
|
+
- **40+ Framework Plugins**: Next.js, FastAPI, Django, Spring Boot, etc.
|
|
44
|
+
- **AI Integration**: OpenRouter, Gemini, Claude, Ollama support
|
|
45
|
+
- **TUI + CLI Modes**: Full terminal UI + complete CLI (non-TUI) support
|
|
46
|
+
- **Task Management**: Background process orchestration with live log streaming
|
|
47
|
+
- **Package Management**: Native package manager detection and management
|
|
48
|
+
- **Project Scaffolding**: 8+ templates for new projects
|
|
49
|
+
- **Environment Health Check**: Runtime version auditing
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Version Information
|
|
54
|
+
|
|
55
|
+
| Attribute | Value |
|
|
56
|
+
|-----------|-------|
|
|
57
|
+
| **Version** | 4.3.7 |
|
|
58
|
+
| **NPM Package** | `project-compass` |
|
|
59
|
+
| **Node.js Requirement** | ^18.0.0 (ESM support) |
|
|
60
|
+
| **Build Status** | Stable |
|
|
61
|
+
| **Platform Support** | Linux, macOS, Windows (with caveats) |
|
|
62
|
+
| **Last Release** | 2026-05-10 |
|
|
63
|
+
|
|
64
|
+
---
|
|
7
65
|
|
|
8
66
|
## Project Structure
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
67
|
+
|
|
68
|
+
### Root Directory
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
project-compass/
|
|
72
|
+
├── package.json # NPM package config (v4.3.6)
|
|
73
|
+
├── README.md # Main documentation (COMPREHENSIVE)
|
|
74
|
+
├── ARCHITECTURE.md # Architecture documentation (DETAILED)
|
|
75
|
+
├── commands.md # All commands & shortcuts (COMPLETE)
|
|
76
|
+
├── CONTRIBUTING.md # Contribution guidelines (DETAILED)
|
|
77
|
+
├── AGENTS.md # THIS FILE (AI agent context)
|
|
78
|
+
├── PROJECT_CONTEXT.md # Technical context for agents
|
|
79
|
+
├── LICENSE # MIT License
|
|
80
|
+
├── eslint.config.cjs # ESLint configuration
|
|
81
|
+
├── assets/ # Screenshots and branding
|
|
82
|
+
├── src/
|
|
83
|
+
│ ├── cli.js # Entry point (840+ lines)
|
|
84
|
+
│ ├── projectDetection.js # Orchestrator (189 lines)
|
|
85
|
+
│ ├── configPaths.js # Config directory paths (13 lines)
|
|
86
|
+
│ ├── detectors/
|
|
87
|
+
│ │ ├── utils.js # Shared utilities (148 lines)
|
|
88
|
+
│ │ ├── node.js # Node.js detection (140 lines)
|
|
89
|
+
│ │ ├── python.js # Python detection (208 lines)
|
|
90
|
+
│ │ ├── rust.js # Rust detection (136 lines)
|
|
91
|
+
│ │ ├── go.js # Go detection
|
|
92
|
+
│ │ ├── java.js # Java detection
|
|
93
|
+
│ │ ├── php.js # PHP detection
|
|
94
|
+
│ │ ├── ruby.js # Ruby detection
|
|
95
|
+
│ │ ├── dotnet.js # .NET detection
|
|
96
|
+
│ │ ├── generic.js # Generic fallback
|
|
97
|
+
│ │ ├── compass-config.js # Project config loader (39 lines)
|
|
98
|
+
│ │ └── frameworks.js # 40+ built-in plugins (877 lines)
|
|
99
|
+
│ └── components/
|
|
100
|
+
│ ├── Navigator.js # Paginated project list (110 lines)
|
|
101
|
+
│ ├── Header.js # Top bar with logo (60 lines)
|
|
102
|
+
│ ├── Footer.js # Bottom bar with stdin (81 lines)
|
|
103
|
+
│ ├── TaskManager.js # Orbit Task Manager (82 lines)
|
|
104
|
+
│ ├── PackageRegistry.js # Dependency management (156 lines)
|
|
105
|
+
│ ├── ProjectArchitect.js # Scaffolding (113 lines)
|
|
106
|
+
│ ├── AIHorizon.js # AI analysis (426 lines)
|
|
107
|
+
│ └── Studio.js # Environment check (64 lines)
|
|
108
|
+
├── node_modules/ # Dependencies (NOT in repo)
|
|
109
|
+
└── ~/.project-compass/ # User config directory (NOT in repo)
|
|
110
|
+
├── config.json # Main configuration
|
|
111
|
+
└── plugins.json # Custom framework plugins
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Key Files for AI Agents
|
|
115
|
+
|
|
116
|
+
| File | Lines | Purpose | When to Read |
|
|
117
|
+
|------|-------|---------|----------------|
|
|
118
|
+
| `src/cli.js` | 1-840 | Main app, all state, input handling | Working on TUI, CLI, or state |
|
|
119
|
+
| `src/projectDetection.js` | 1-189 | Detection orchestrator | Working on detection system |
|
|
120
|
+
| `src/detectors/utils.js` | 1-148 | Shared utilities | Working on detectors |
|
|
121
|
+
| `src/detectors/frameworks.js` | 1-877 | Framework plugins | Working on framework detection |
|
|
122
|
+
| `src/components/AIHorizon.js` | 1-426 | AI analysis | Working on AI features |
|
|
123
|
+
| `src/components/Navigator.js` | 1-110 | Project list | Working on navigation |
|
|
124
|
+
| `src/components/TaskManager.js` | 1-82 | Task management | Working on tasks |
|
|
125
|
+
| `AGENTS.md` | 1-600+ | THIS FILE | Start here for context |
|
|
126
|
+
| `PROJECT_CONTEXT.md` | 1-400+ | Technical context | Deep technical work |
|
|
127
|
+
|
|
128
|
+
---
|
|
19
129
|
|
|
20
130
|
## Tech Stack
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
131
|
+
|
|
132
|
+
### Runtime & Framework
|
|
133
|
+
|
|
134
|
+
| Technology | Version | Purpose | Documentation |
|
|
135
|
+
|------------|---------|---------|---------------|
|
|
136
|
+
| **Node.js** | ^18.0.0 | Runtime (ESM modules) | https://nodejs.org |
|
|
137
|
+
| **React** | ^18.2.0 | UI framework (for CLI) | https://react.dev |
|
|
138
|
+
| **Ink** | ^5.1.0 | React for CLI (TUI) | https://github.com/vadimdemedes/ink |
|
|
139
|
+
| **kleur** | ^4.1.5 | Terminal colors | https://github.com/lukeedgar/kleur |
|
|
140
|
+
| **execa** | ^9.5.2 | Process execution | https://github.com/sindresorhus/execa |
|
|
141
|
+
| **fast-glob** | ^3.3.3 | File searching | https://github.com/mrmlnc/fast-glob |
|
|
142
|
+
|
|
143
|
+
### Native APIs Used
|
|
144
|
+
|
|
145
|
+
| API | Purpose | Usage |
|
|
146
|
+
|-----|---------|-------|
|
|
147
|
+
| `fs` | File system operations | Reading manifests, writing config |
|
|
148
|
+
| `path` | Path manipulation | Resolving paths, joining |
|
|
149
|
+
| `fetch` | HTTP requests | AI provider API calls |
|
|
150
|
+
| `setInterval/setTimeout` | Timers | Startup animation, scroll |
|
|
151
|
+
| `process` | Process info | Exit codes, signals |
|
|
152
|
+
|
|
153
|
+
---
|
|
26
154
|
|
|
27
155
|
## Development Rules
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
156
|
+
|
|
157
|
+
### 1. Zero Mock Data
|
|
158
|
+
|
|
159
|
+
Always aim for live system/project data.
|
|
160
|
+
|
|
161
|
+
- ✅ Read actual project files
|
|
162
|
+
- ✅ Use real `package.json`, `pyproject.toml`, etc.
|
|
163
|
+
- ❌ No hardcoded sample data in production code
|
|
164
|
+
|
|
165
|
+
### 2. ESM Only
|
|
166
|
+
|
|
167
|
+
Use `import/export` (no CommonJS).
|
|
168
|
+
|
|
169
|
+
```javascript
|
|
170
|
+
// ✅ Correct
|
|
171
|
+
import { something } from './module.js';
|
|
172
|
+
export default function() { /* ... */ };
|
|
173
|
+
|
|
174
|
+
// ❌ Wrong
|
|
175
|
+
const something = require('./module');
|
|
176
|
+
module.exports = function() { /* ... */ };
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 3. Paging Rules
|
|
180
|
+
|
|
181
|
+
Use `config.maxVisibleProjects` (default: 3) for navigation logic.
|
|
182
|
+
|
|
183
|
+
- **Navigator pagination**: Pages of `maxVisibleProjects` projects
|
|
184
|
+
- **Page Up/Down**: Jump full pages
|
|
185
|
+
- **Boundary guards**: Prevent out-of-bounds selection
|
|
186
|
+
|
|
187
|
+
### 4. Port Logic
|
|
188
|
+
|
|
189
|
+
Respect `projectMeta` in `config.json` for manual port assignments.
|
|
190
|
+
|
|
191
|
+
```javascript
|
|
192
|
+
// Reading port
|
|
193
|
+
const port = config.projectMeta?.[project.path]?.port || '3000';
|
|
194
|
+
|
|
195
|
+
// Saving port
|
|
196
|
+
setConfig((prev) => ({
|
|
197
|
+
...prev,
|
|
198
|
+
projectMeta: {
|
|
199
|
+
...prev.projectMeta,
|
|
200
|
+
[project.path]: { ...prev.projectMeta?.[project.path], port: portVal }
|
|
201
|
+
}
|
|
202
|
+
}));
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### 5. No Hallucinations
|
|
206
|
+
|
|
207
|
+
Framework matchers MUST use `dependencyMatches()` not `hasProjectFile()` for detection.
|
|
208
|
+
|
|
209
|
+
```javascript
|
|
210
|
+
// ✅ Correct (v4.3.6+)
|
|
211
|
+
match(project) {
|
|
212
|
+
return dependencyMatches(project, 'fastapi');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// ❌ Wrong (causes hallucinations)
|
|
216
|
+
match(project) {
|
|
217
|
+
return dependencyMatches(project, 'fastapi') || hasProjectFile(project.path, 'main.py');
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### 6. Component Pattern
|
|
222
|
+
|
|
223
|
+
Use `React.createElement` (aliased as `create`), not JSX.
|
|
224
|
+
|
|
225
|
+
```javascript
|
|
226
|
+
// ✅ Correct
|
|
227
|
+
const create = React.createElement;
|
|
228
|
+
return create(Box, {flexDirection: 'column'},
|
|
229
|
+
create(Text, {color: 'cyan'}, 'Hello'));
|
|
230
|
+
|
|
231
|
+
// ❌ Wrong (no JSX in this project)
|
|
232
|
+
return <Box><Text>Hello</Text></Box>;
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## File Reference Quick Links
|
|
238
|
+
|
|
239
|
+
| File | Line Numbers | Purpose |
|
|
240
|
+
|------|-------------|---------|
|
|
241
|
+
| `src/cli.js` | 1-840 | Main app, all state, input handling |
|
|
242
|
+
| | 38-45 | `saveConfig()` |
|
|
243
|
+
| | 47-65 | `loadConfig()` |
|
|
244
|
+
| | 67-90 | `useScanner(rootPath)` |
|
|
245
|
+
| | 92-105 | `buildDetailCommands()` |
|
|
246
|
+
| | 107-119 | `CursorText` component |
|
|
247
|
+
| | 121-161 | `OutputPanel` component |
|
|
248
|
+
| | 163-763 | `Compass` React component |
|
|
249
|
+
| | 324-592 | `useInput` handler (ALL keyboard shortcuts) |
|
|
250
|
+
| | 766-781 | `parseArgs()` |
|
|
251
|
+
| | 783-840+ | `main()` |
|
|
252
|
+
| `src/projectDetection.js` | 1-189 | Detection orchestrator |
|
|
253
|
+
| | 31-71 | `loadUserFrameworks()` |
|
|
254
|
+
| | 75-81 | `getFrameworkPlugins()` |
|
|
255
|
+
| | 83-112 | `matchesPlugin()` |
|
|
256
|
+
| | 114-144 | `applyFrameworkPlugins()` |
|
|
257
|
+
| | 146-180 | `discoverProjects()` |
|
|
258
|
+
| `src/configPaths.js` | 1-13 | Config paths |
|
|
259
|
+
| `src/detectors/utils.js` | 1-148 | Shared utilities |
|
|
260
|
+
| | 5-13 | `checkBinary()` |
|
|
261
|
+
| | 15-17 | `hasProjectFile()` |
|
|
262
|
+
| | 28-80 | `getPackageManager()` |
|
|
263
|
+
| | 82-92 | `resolveScriptCommand()` |
|
|
264
|
+
| | 94-108 | `dependencyMatches()` |
|
|
265
|
+
| | 110-126 | `parseCommandTokens()` |
|
|
266
|
+
| `src/detectors/frameworks.js` | 1-877 | Framework plugins |
|
|
267
|
+
| | 319-340 | FastAPI framework |
|
|
268
|
+
| | 341-361 | Flask framework |
|
|
269
|
+
| | 362-383 | Django framework |
|
|
270
|
+
| | 468-540 | Rust frameworks |
|
|
271
|
+
| | 559-630 | Go frameworks |
|
|
272
|
+
| | 631-696 | Java frameworks |
|
|
273
|
+
| | 697-790 | PHP frameworks |
|
|
274
|
+
| | 752-788 | Ruby frameworks |
|
|
275
|
+
| | 790-826 | .NET frameworks |
|
|
276
|
+
| `src/detectors/compass-config.js` | 1-39 | Project config loader |
|
|
277
|
+
| `src/components/AIHorizon.js` | 1-426 | AI analysis |
|
|
278
|
+
| | 16-28 | State variables |
|
|
279
|
+
| | 31-40 | `readProjectFile()` |
|
|
280
|
+
| | 42-72 | `buildProjectContext()` |
|
|
281
|
+
| | 74-192 | `runRealAnalysis()` |
|
|
282
|
+
| | 221-329 | `useInput` handler |
|
|
283
|
+
| `src/components/Navigator.js` | 1-110 | Project list |
|
|
284
|
+
| `src/components/TaskManager.js` | 1-82 | Task management |
|
|
285
|
+
| `src/components/PackageRegistry.js` | 1-156 | Package management |
|
|
286
|
+
| `src/components/ProjectArchitect.js` | 1-113 | Scaffolding |
|
|
287
|
+
| `src/components/Studio.js` | 1-64 | Environment check |
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## CLI Arguments (Complete List)
|
|
292
|
+
|
|
293
|
+
### All CLI Arguments
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
# Basic usage
|
|
297
|
+
project-compass # Launch TUI (default: navigator)
|
|
298
|
+
project-compass --help # Show help (-h)
|
|
299
|
+
project-compass --version # Show version (-v)
|
|
300
|
+
project-compass --dir /path/to/ws # Specify working directory
|
|
301
|
+
|
|
302
|
+
# Direct view launch
|
|
303
|
+
project-compass --studio # Launch in Studio view
|
|
304
|
+
project-compass --ai # Launch in AI Horizon view
|
|
305
|
+
project-compass --task # Launch in Task Manager view
|
|
306
|
+
project-compass --tasks # Alias for --task
|
|
307
|
+
|
|
308
|
+
# Project detection (no TUI)
|
|
309
|
+
project-compass --mode test # Legacy test mode
|
|
310
|
+
project-compass --list-projects # Enhanced listing (RECOMMENDED)
|
|
311
|
+
project-compass --list-projects --json # JSON output
|
|
312
|
+
project-compass --project-info 0 # Project info by index
|
|
313
|
+
project-compass --project-info 0 --json # JSON output
|
|
314
|
+
|
|
315
|
+
# Run commands (no TUI)
|
|
316
|
+
project-compass --run "cmd" --dir /path # Run command directly
|
|
317
|
+
|
|
318
|
+
# Package management (no TUI)
|
|
319
|
+
project-compass --add-pkg "pkg" --dir /path # Add package
|
|
320
|
+
project-compass --remove-pkg "pkg" --dir /path # Remove package
|
|
321
|
+
|
|
322
|
+
# Project scaffolding (no TUI)
|
|
323
|
+
project-compass --scaffold <template> --name <n> --dir <d>
|
|
324
|
+
|
|
325
|
+
# Environment check (no TUI)
|
|
326
|
+
project-compass --studio-check # Check runtimes
|
|
327
|
+
|
|
328
|
+
# AI analysis (requires TUI)
|
|
329
|
+
project-compass --ai-analyze # Shows message to use TUI mode
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### All Scaffolding Templates
|
|
333
|
+
|
|
334
|
+
| Template | Command |
|
|
335
|
+
|----------|---------|
|
|
336
|
+
| `nextjs` | `npx create-next-app@latest <path>` |
|
|
337
|
+
| `nextjs-bun` | `bun create next-app <path>` |
|
|
338
|
+
| `react-vite` | `pnpm create vite <path> --template react` |
|
|
339
|
+
| `react-vite-npm` | `npm create vite@latest <path> -- --template react` |
|
|
340
|
+
| `vue-vite` | `npm create vite@latest <path> -- --template vue` |
|
|
341
|
+
| `rust` | `cargo new <path>` |
|
|
342
|
+
| `django` | `django-admin startproject <name> <path>` |
|
|
343
|
+
| `python-basic` | `mkdir -p <path>` |
|
|
344
|
+
| `go` | `go mod init <name>` in new dir |
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## TUI Keyboard Shortcuts (Complete List)
|
|
349
|
+
|
|
350
|
+
### Navigation (All Modes)
|
|
351
|
+
|
|
352
|
+
| Key | Action | Context |
|
|
353
|
+
|-----|--------|---------|
|
|
354
|
+
| `↑` / `↓` | Move project focus | Navigator |
|
|
355
|
+
| `PgUp` / `PgDn` | Jump full project page | Navigator |
|
|
356
|
+
| `Enter` | Toggle project Detail View / Switch back | Navigator |
|
|
357
|
+
| `Esc` | **Global Back**: Return to Main Navigator | Global |
|
|
358
|
+
| `?` | Toggle help overlay | Navigator |
|
|
359
|
+
| `Shift+Q` | **Quit** application (confirms if tasks running) | Global |
|
|
360
|
+
| `Ctrl+C` | Interrupt running command | When process running |
|
|
361
|
+
|
|
362
|
+
### Quick Actions (Detail View Only)
|
|
363
|
+
|
|
364
|
+
| Key | Action | Command |
|
|
365
|
+
|-----|--------|---------|
|
|
366
|
+
| `0` | **Quick AI Analysis** | Switch to AI Horizon |
|
|
367
|
+
| `B` | **Build** project | `commands.build` |
|
|
368
|
+
| `T` | **Test** project | `commands.test` |
|
|
369
|
+
| `R` | **Run** project | `commands.run` |
|
|
370
|
+
| `I` | **Install** dependencies | `commands.install` |
|
|
371
|
+
| `1-9` | **Run numbered commands** | `detailShortcutMap` |
|
|
372
|
+
| `Shift+1-9` (A-Z) | **Run commands 10+** | `detailShortcutMap` |
|
|
373
|
+
|
|
374
|
+
### View Toggles
|
|
375
|
+
|
|
376
|
+
| Key | Action | Target View |
|
|
377
|
+
|-----|--------|--------------|
|
|
378
|
+
| `Shift+O` | **AI Horizon** Dashboard | `ai` |
|
|
379
|
+
| `Shift+T` | **Orbit Task Manager** | `tasks` |
|
|
380
|
+
| `Shift+P` | **Package Registry** | `registry` |
|
|
381
|
+
| `Shift+N` | **Project Architect** | `architect` |
|
|
382
|
+
| `Shift+A` | **Omni-Studio** | `studio` |
|
|
383
|
+
|
|
384
|
+
### UI Toggles (Saved to Config)
|
|
385
|
+
|
|
386
|
+
| Key | Action | Config Key |
|
|
387
|
+
|-----|--------|----------|
|
|
388
|
+
| `Shift+B` | Toggle **Art Board** visibility | `showArtBoard` |
|
|
389
|
+
| `Shift+H` | Toggle **Help Cards** UI | `showHelpCards` |
|
|
390
|
+
| `Shift+S` | Toggle **Structure Guide** | `showStructureGuide` |
|
|
391
|
+
|
|
392
|
+
### Task Management
|
|
393
|
+
|
|
394
|
+
| Key | Action | Context |
|
|
395
|
+
|-----|--------|---------|
|
|
396
|
+
| `Shift+K` | **Kill** running process | Task Manager |
|
|
397
|
+
| `Shift+R` | **Rename** task / Configure Port | Task Manager / Detail View |
|
|
398
|
+
| `Shift+D` | **Detach** from active task | Navigator |
|
|
399
|
+
| `Shift+X` | **Clear** active task output logs | Navigator |
|
|
400
|
+
| `Shift+E` | **Export** logs to `.txt` file | Navigator |
|
|
401
|
+
| `Shift+L` | **Rerun** the last executed command | Navigator |
|
|
402
|
+
| `↑` / `↓` | Move focus between tasks | Task Manager |
|
|
403
|
+
| `Enter` | Select/deselect task | Task Manager |
|
|
404
|
+
|
|
405
|
+
### Log Scrolling
|
|
406
|
+
|
|
407
|
+
| Key | Action |
|
|
408
|
+
|-----|--------|
|
|
409
|
+
| `Shift+↑` | Scroll output logs up |
|
|
410
|
+
| `Shift+↓` | Scroll output logs down |
|
|
411
|
+
|
|
412
|
+
### Project Configuration
|
|
413
|
+
|
|
414
|
+
| Key | Action | Context |
|
|
415
|
+
|-----|--------|---------|
|
|
416
|
+
| `Shift+R` | **Configure Port** / Rename task | Detail View / Task Manager |
|
|
417
|
+
| `Shift+C` | **Add Custom Command** (`label\|cmd`) | Detail View |
|
|
418
|
+
|
|
419
|
+
### Stdin Input (When Process Running)
|
|
420
|
+
|
|
421
|
+
| Key | Action |
|
|
422
|
+
|-----|--------|
|
|
423
|
+
| Type | Feed stdin to process |
|
|
424
|
+
| `Enter` | Submit stdin buffer + `\n` |
|
|
425
|
+
| `Backspace` / `Delete` | Delete character before cursor |
|
|
426
|
+
| `←` / `→` | Move cursor left/right |
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## Supported Languages
|
|
431
|
+
|
|
432
|
+
### Detection Priority Order
|
|
433
|
+
|
|
434
|
+
| Language | Priority | Manifest Files | Binaries | Package Manager |
|
|
435
|
+
|----------|----------|----------------|----------|-----------------|
|
|
436
|
+
| **Node.js** | 100 | `package.json` | `node`, `npm` | npm/yarn/pnpm/bun |
|
|
437
|
+
| **Python** | 95 | `pyproject.toml`, `requirements.txt`, `setup.py`, `Pipfile`, `manage.py` | `python3`, `python`, `uv` | uv/poetry/pipenv/pip |
|
|
438
|
+
| **Rust** | 90 | `Cargo.toml` | `cargo`, `rustc` | cargo |
|
|
439
|
+
| **Go** | 85 | `go.mod` | `go` | go |
|
|
440
|
+
| **Java** | 80 | `pom.xml`, `build.gradle`, `build.gradle.kts` | `java`, `mvn`, `gradle` | maven/gradle |
|
|
441
|
+
| **PHP** | 75 | `composer.json` | `php`, `composer` | composer |
|
|
442
|
+
| **Ruby** | 70 | `Gemfile` | `ruby`, `bundle` | bundler |
|
|
443
|
+
| **.NET** | 65 | `*.csproj`, `*.fsproj` | `dotnet` | dotnet |
|
|
444
|
+
| **Generic** | 10 | `Makefile`, `build.sh` | (varies) | (none) |
|
|
445
|
+
|
|
446
|
+
### Package Manager Auto-Detection
|
|
447
|
+
|
|
448
|
+
#### Node.js
|
|
449
|
+
```javascript
|
|
450
|
+
// Detection order (first found wins):
|
|
451
|
+
1. bun.lockb || bun.lock → bun
|
|
452
|
+
2. pnpm-lock.yaml → pnpm
|
|
453
|
+
3. yarn.lock → yarn
|
|
454
|
+
4. package-lock.json → npm
|
|
455
|
+
5. default: npm
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
#### Python
|
|
459
|
+
```javascript
|
|
460
|
+
// Detection order:
|
|
461
|
+
1. uv.lock && checkBinary('uv') → uv
|
|
462
|
+
2. poetry.lock → poetry
|
|
463
|
+
3. Pipfile.lock → pipenv
|
|
464
|
+
4. requirements.txt → pip
|
|
465
|
+
5. default: pip
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
## Built-in Frameworks
|
|
471
|
+
|
|
472
|
+
### Node.js Frameworks (15+)
|
|
473
|
+
|
|
474
|
+
| Framework | Icon | Priority | Commands | Auto-Detected |
|
|
475
|
+
|-----------|------|----------|----------|---------------|
|
|
476
|
+
| **Next.js** | 🧭 | 115 | install, dev, build, test, start | ✅ |
|
|
477
|
+
| **React** | ⚛️ | 112 | install, dev, build, test | ✅ |
|
|
478
|
+
| **Vue.js** | 🟩 | 111 | install, dev, build, test | ✅ |
|
|
479
|
+
| **NestJS** | 🛡️ | 110 | install, dev, build, test | ✅ |
|
|
480
|
+
| **Nuxt** | 🟢 | 110 | install, dev, build, generate | ✅ |
|
|
481
|
+
| **Express** | 🚂 | 108 | install, start, dev | ✅ |
|
|
482
|
+
| **Svelte** | 🧡 | 109 | install, dev, build, test | ✅ |
|
|
483
|
+
| **Astro** | 🚀 | 108 | install, dev, build, preview | ✅ |
|
|
484
|
+
| **Fastify** | ⚡ | 107 | install, start, dev | ✅ |
|
|
485
|
+
| **Koa** | 🎋 | 106 | install, start | ✅ |
|
|
486
|
+
| **Vite** | ⚡ | 100 | install, dev, build, preview | ✅ |
|
|
487
|
+
| **Tailwind CSS** | 🎨 | 50 | init | ✅ |
|
|
488
|
+
| **Prisma** | ◮ | 50 | install, generate, studio | ✅ |
|
|
489
|
+
| **tRPC** | 🔌 | 45 | dev, build | ✅ |
|
|
490
|
+
| **GraphQL** | ◼️ | 48 | start, dev | ✅ |
|
|
491
|
+
|
|
492
|
+
### Python Frameworks (12+)
|
|
493
|
+
|
|
494
|
+
| Framework | Icon | Priority | Commands | Auto-Detected |
|
|
495
|
+
|-----------|------|----------|----------|---------------|
|
|
496
|
+
| **FastAPI** | ⚡ | 112 | install, run (uvicorn), test | ✅ |
|
|
497
|
+
| **Flask** | 🌶️ | 111 | install, run, test | ✅ |
|
|
498
|
+
| **Django** | 🌿 | 110 | install, runserver, test, migrate | ✅ |
|
|
499
|
+
| **Sanic** | 🚀 | 106 | run, test | ✅ |
|
|
500
|
+
| **AioHTTP** | 🔄 | 105 | test | ✅ |
|
|
501
|
+
| **Tornado** | 🌪️ | 104 | run, test | ✅ |
|
|
502
|
+
| **Pytest** | ✅ | 50 | run, coverage | ✅ |
|
|
503
|
+
| **SQLAlchemy** | 🗄️ | 48 | test | ✅ |
|
|
504
|
+
| **Pandas** | 🐼 | 45 | test | ✅ |
|
|
505
|
+
| **PyTorch** | 🔥 | 45 | test | ✅ |
|
|
506
|
+
| **TensorFlow** | 🧠 | 45 | test | ✅ |
|
|
507
|
+
|
|
508
|
+
### Rust Frameworks (9+)
|
|
509
|
+
|
|
510
|
+
| Framework | Icon | Priority | Commands | Auto-Detected |
|
|
511
|
+
|-----------|------|----------|----------|---------------|
|
|
512
|
+
| **Actix Web** | 🎭 | 110 | fetch, run, test, build | ✅ |
|
|
513
|
+
| **Axum** | 🗡️ | 108 | fetch, run, test | ✅ |
|
|
514
|
+
| **Rocket** | 🚀 | 105 | fetch, run, test | ✅ |
|
|
515
|
+
| **Warp** | 🌀 | 104 | run, test | ✅ |
|
|
516
|
+
| **Tokio** | ⚡ | 50 | run, test | ✅ |
|
|
517
|
+
| **Serde** | 🔄 | - | - | ✅ |
|
|
518
|
+
| **SQLx** | 🗄️ | - | - | ✅ |
|
|
519
|
+
| **Diesel** | 🛢️ | - | - | ✅ |
|
|
520
|
+
| **Tonic** | 🎵 | - | - | ✅ |
|
|
521
|
+
| **Tower** | 🏰 | - | - | ✅ |
|
|
522
|
+
|
|
523
|
+
### Go Frameworks (4+)
|
|
524
|
+
|
|
525
|
+
| Framework | Icon | Priority | Commands | Auto-Detected |
|
|
526
|
+
|-----------|------|----------|----------|---------------|
|
|
527
|
+
| **Gin** | 🍸 | 110 | mod tidy, run, test, build | ✅ |
|
|
528
|
+
| **Fiber** | 🔥 | 109 | run, test | ✅ |
|
|
529
|
+
| **Echo** | 🔊 | 108 | run, test | ✅ |
|
|
530
|
+
| **Chi** | 🤝 | 105 | run, test | ✅ |
|
|
531
|
+
|
|
532
|
+
### Java Frameworks (3+)
|
|
533
|
+
|
|
534
|
+
| Framework | Icon | Priority | Commands | Auto-Detected |
|
|
535
|
+
|-----------|------|----------|----------|---------------|
|
|
536
|
+
| **Spring Boot** | 🍃 | 115 | install, run, test, build | ✅ |
|
|
537
|
+
| **Quarkus** | ⚡ | 108 | dev, build, test | ✅ |
|
|
538
|
+
| **Micronaut** | 🚀 | 106 | run, test | ✅ |
|
|
539
|
+
|
|
540
|
+
### PHP Frameworks (3+)
|
|
541
|
+
|
|
542
|
+
| Framework | Icon | Priority | Commands | Auto-Detected |
|
|
543
|
+
|-----------|------|----------|----------|---------------|
|
|
544
|
+
| **Laravel** | 🧡 | 110 | install, serve, test, migrate | ✅ |
|
|
545
|
+
| **Symfony** | 🎵 | 108 | install, server:start, test | ✅ |
|
|
546
|
+
| **CodeIgniter** | 🔥 | 104 | test | ✅ |
|
|
547
|
+
|
|
548
|
+
### Ruby Frameworks (2+)
|
|
549
|
+
|
|
550
|
+
| Framework | Icon | Priority | Commands | Auto-Detected |
|
|
551
|
+
|-----------|------|----------|----------|---------------|
|
|
552
|
+
| **Ruby on Rails** | 🛤️ | 110 | install, server, test, migrate | ✅ |
|
|
553
|
+
| **Sinatra** | 🎷 | 105 | install, rackup | ✅ |
|
|
554
|
+
|
|
555
|
+
### .NET Frameworks (2+)
|
|
556
|
+
|
|
557
|
+
| Framework | Icon | Priority | Commands | Auto-Detected |
|
|
558
|
+
|-----------|------|----------|----------|---------------|
|
|
559
|
+
| **ASP.NET Core** | 🔷 | 110 | restore, run, test, build | ✅ |
|
|
560
|
+
| **Blazor** | 🌀 | 105 | run, build | ✅ |
|
|
561
|
+
|
|
562
|
+
---
|
|
563
|
+
|
|
564
|
+
## Recent Fixes (v4.3.6)
|
|
565
|
+
|
|
566
|
+
### 1. Framework Hallucination Bug FIXED
|
|
567
|
+
|
|
568
|
+
**Problem**: Projects without frameworks were showing random frameworks (e.g., simple Python project with `main.py` was detected as FastAPI).
|
|
569
|
+
|
|
570
|
+
**Root Cause**: Framework matchers in `frameworks.js` used file existence (`hasProjectFile`) instead of dependency matching.
|
|
571
|
+
|
|
572
|
+
**Fix Applied** (src/detectors/frameworks.js):
|
|
573
|
+
- `fastapi` matcher (line 328): Removed `|| hasProjectFile(project.path, 'main.py')`
|
|
574
|
+
- `django` matcher (line 370): Removed `|| hasProjectFile(project.path, 'manage.py')`
|
|
575
|
+
- `spring-boot` matcher: Removed `|| hasProjectFile(project.path, 'pom.xml') || hasProjectFile(project.path, 'build.gradle')`
|
|
576
|
+
- `quarkus` matcher: Removed `|| hasProjectFile(project.path, 'pom.xml')`
|
|
577
|
+
- `micronaut` matcher: Removed `|| hasProjectFile(project.path, 'pom.xml')`
|
|
578
|
+
- `rails` matcher: Changed to use `dependencyMatches(project, 'rails')` instead of file checks
|
|
579
|
+
- `sinatra` matcher: Removed `|| hasProjectFile(project.path, 'config.ru')`
|
|
580
|
+
- `.NET` matchers: Now use dependency checks instead of `*.csproj` file existence.
|
|
581
|
+
|
|
582
|
+
**Result**: Projects without explicit framework dependencies now correctly show `Frameworks: none`.
|
|
583
|
+
|
|
584
|
+
### 2. compass-config.js Integration
|
|
585
|
+
|
|
586
|
+
**Problem**: `compass-config.js` existed but was never integrated into project detection.
|
|
587
|
+
|
|
588
|
+
**Fix Applied** (src/projectDetection.js):
|
|
589
|
+
- Added import of `loadProjectConfig` in `projectDetection.js`
|
|
590
|
+
- Integrated into `discoverProjects()` function to load `compass.config.js` from project directories
|
|
591
|
+
- Project-specific commands and frameworks from `compass.config.js` are now merged into project data.
|
|
592
|
+
|
|
593
|
+
### 3. AI Horizon Improvements
|
|
594
|
+
|
|
595
|
+
**Problem**: AI Horizon didn't properly show raw AI output and had poor JSON parsing.
|
|
596
|
+
|
|
597
|
+
**Fix Applied** (src/components/AIHorizon.js):
|
|
598
|
+
- Added `rawAIResponse` state to store raw AI output
|
|
599
|
+
- Improved JSON parsing to handle markdown code blocks (```json ... ```)
|
|
600
|
+
- Raw AI response is now displayed in the UI during review step
|
|
601
|
+
- Better error messages showing partial AI response if JSON parsing fails.
|
|
602
|
+
|
|
603
|
+
### 4. Node.js Detector Fixed
|
|
604
|
+
|
|
605
|
+
**Problem**: `node.js` detector was adding "Node.js" as a framework.
|
|
606
|
+
|
|
607
|
+
**Fix Applied** (src/detectors/node.js):
|
|
608
|
+
- Detector now only adds framework if it's not the generic "Node.js" type
|
|
609
|
+
- Projects using plain Node.js without frameworks now show `Frameworks: none`.
|
|
610
|
+
|
|
611
|
+
### 5. Framework Deduplication
|
|
612
|
+
|
|
613
|
+
**Problem**: `applyFrameworkPlugins()` could add duplicate frameworks.
|
|
614
|
+
|
|
615
|
+
**Fix Applied** (src/projectDetection.js):
|
|
616
|
+
- Added check to avoid adding duplicate frameworks
|
|
617
|
+
- Now preserves detector-detected frameworks and merges with plugin-detected ones.
|
|
618
|
+
|
|
619
|
+
---
|
|
620
|
+
|
|
621
|
+
## Recent Fixes (Post-v4.3.6)
|
|
622
|
+
|
|
623
|
+
### 1. Python Binary Detection Bug FIXED
|
|
624
|
+
|
|
625
|
+
**Problem**: `python.js` checked if ALL of `['python3', 'python', 'uv']` binaries existed, causing false "Runtime missing" warnings when only `python` or `python3` was available.
|
|
626
|
+
|
|
627
|
+
**Root Cause**: `binaries.filter(b => !checkBinary(b))` treats alternate Python binary names as separate requirements.
|
|
628
|
+
|
|
629
|
+
**Fix Applied** (src/detectors/python.js:126-135):
|
|
630
|
+
```javascript
|
|
631
|
+
const hasPython3 = checkBinary('python3');
|
|
632
|
+
const hasPython = checkBinary('python');
|
|
633
|
+
const hasUv = checkBinary('uv');
|
|
634
|
+
const hasRuntime = hasPython3 || hasPython || hasUv;
|
|
635
|
+
const missingBinaries = hasRuntime ? [] : ['python'];
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
**Result**: Only shows "Runtime missing" if NO Python runtime exists at all.
|
|
639
|
+
|
|
640
|
+
### 2. Removed Unused Store
|
|
641
|
+
|
|
642
|
+
**Problem**: `src/store/useProjectStore.js` existed but was never imported anywhere.
|
|
643
|
+
|
|
644
|
+
**Fix Applied**: Removed `src/store/useProjectStore.js` - dead code cleanup.
|
|
645
|
+
|
|
646
|
+
### 3. Pagination Default Values Fixed
|
|
647
|
+
|
|
648
|
+
**Problem**: Inconsistent defaults:
|
|
649
|
+
- Config default: `maxVisibleProjects: 3`
|
|
650
|
+
- `Navigator.js` prop default: `2`
|
|
651
|
+
- `cli.js` pageLimit fallback: `2`
|
|
652
|
+
|
|
653
|
+
**Fix Applied**:
|
|
654
|
+
- `Navigator.js:11`: Changed from `maxVisibleProjects = 2` to `maxVisibleProjects = 3`
|
|
655
|
+
- `cli.js:543`: Changed from `config.maxVisibleProjects || 2` to `config.maxVisibleProjects || 3`
|
|
656
|
+
|
|
657
|
+
---
|
|
658
|
+
|
|
659
|
+
## Component Details
|
|
660
|
+
|
|
661
|
+
### Entry Point: `src/cli.js`
|
|
662
|
+
|
|
663
|
+
**Lines**: 840+
|
|
664
|
+
**Purpose**: Main entry point, argument parsing, global state management, input handling.
|
|
665
|
+
|
|
666
|
+
#### Key Functions:
|
|
667
|
+
|
|
668
|
+
| Function | Lines | Purpose |
|
|
669
|
+
|----------|-------|---------|
|
|
670
|
+
| `parseArgs()` | 766-781 | Parse CLI arguments |
|
|
671
|
+
| `main()` | 783-840+ | Main async entry |
|
|
672
|
+
| `saveConfig()` | 38-45 | Persist config to disk |
|
|
673
|
+
| `loadConfig()` | 47-65 | Load config from `~/.project-compass/config.json` |
|
|
674
|
+
| `useScanner()` | 67-90 | Async project detection |
|
|
675
|
+
| `buildDetailCommands()` | 92-105 | Build commands for detail view |
|
|
676
|
+
| `CursorText()` | 107-119 | Reusable text input with cursor |
|
|
677
|
+
| `OutputPanel` | 121-161 | Log output display |
|
|
678
|
+
| `Compass` | 163-763 | Main React component |
|
|
679
|
+
| `runProjectCommand()` | 264-310 | Execute project command |
|
|
680
|
+
| `addLogToTask()` | 203-216 | Append to task logs |
|
|
681
|
+
| `handleKillTask()` | 236-255 | Kill running task |
|
|
682
|
+
| `killAllTasks()` | 257-262 | Kill all running tasks |
|
|
683
|
+
|
|
684
|
+
#### Key React Component: `Compass` (lines 163-763)
|
|
685
|
+
|
|
686
|
+
**State Variables**:
|
|
687
|
+
- `projects` - Detected projects array
|
|
688
|
+
- `selectedIndex` - Currently selected project index
|
|
689
|
+
- `viewMode` - 'list' or 'detail'
|
|
690
|
+
- `mainView` - 'navigator', 'tasks', 'registry', 'architect', 'ai', 'studio'
|
|
691
|
+
- `tasks` - Array of running/completed tasks
|
|
692
|
+
- `activeTaskId` - Currently selected task
|
|
693
|
+
- `config` - Loaded from `~/.project-compass/config.json`
|
|
694
|
+
- `runningProcessMap` - Ref Map of task IDs to child processes
|
|
695
|
+
- `lastCommandRef` - Last executed command for replay (Shift+L)
|
|
696
|
+
|
|
697
|
+
**Hooks Used**:
|
|
698
|
+
- `useScanner(rootPath)` - Async project detection
|
|
699
|
+
- `useInput()` - Global keyboard input handling (lines 324-592)
|
|
700
|
+
- `useState()` - Multiple state variables
|
|
701
|
+
- `useMemo()` - Memoized computations
|
|
702
|
+
- `useCallback()` - Memoized callbacks
|
|
703
|
+
- `useEffect()` - Side effects (timers, scanning)
|
|
704
|
+
|
|
705
|
+
### `Navigator.js` (src/components/Navigator.js)
|
|
706
|
+
|
|
707
|
+
**Props**: `projects`, `selectedIndex`, `rootPath`, `loading`, `error`, `maxVisibleProjects`
|
|
708
|
+
**Lines**: 110
|
|
709
|
+
|
|
710
|
+
**Features**:
|
|
711
|
+
- Paginated project list (page size = `maxVisibleProjects`, default 3)
|
|
712
|
+
- Loading spinner animation
|
|
713
|
+
- Error display
|
|
714
|
+
- Empty state message
|
|
715
|
+
- Framework badges display
|
|
716
|
+
- Missing runtime warnings
|
|
717
|
+
|
|
718
|
+
### `TaskManager.js` (src/components/TaskManager.js)
|
|
719
|
+
|
|
720
|
+
**Props**: `tasks`, `activeTaskId`, `renameMode`, `renameInput`, `renameCursor`, `CursorText`
|
|
721
|
+
**Lines**: 82
|
|
722
|
+
|
|
723
|
+
**Features**:
|
|
724
|
+
- Task list with status colors
|
|
725
|
+
- Active task highlighting
|
|
726
|
+
- Mini log preview (last 5 lines)
|
|
727
|
+
- Task renaming
|
|
728
|
+
- Keyboard shortcuts display
|
|
729
|
+
|
|
730
|
+
### `AIHorizon.js` (src/components/AIHorizon.js)
|
|
731
|
+
|
|
732
|
+
**Props**: `selectedProject`, `CursorText`, `config`, `setConfig`, `saveConfig`
|
|
733
|
+
**Lines**: 426
|
|
734
|
+
|
|
735
|
+
**Features**:
|
|
736
|
+
- Multi-step flow: provider → model → token → analyze → review
|
|
737
|
+
- AI providers: OpenRouter, Gemini, Claude, Ollama
|
|
738
|
+
- Project context building (README, main file, config)
|
|
739
|
+
- Raw AI response display
|
|
740
|
+
- Editable suggestions
|
|
741
|
+
- Config persistence
|
|
742
|
+
|
|
743
|
+
### `PackageRegistry.js` (src/components/PackageRegistry.js)
|
|
744
|
+
|
|
745
|
+
**Props**: `selectedProject`, `projects`, `onRunCommand`, `CursorText`, `onSelectProject`
|
|
746
|
+
**Lines**: 156
|
|
747
|
+
|
|
748
|
+
**Features**:
|
|
749
|
+
- Project selection sub-view
|
|
750
|
+
- Package listing
|
|
751
|
+
- Add/remove packages
|
|
752
|
+
- Python venv creation
|
|
753
|
+
- Native package manager detection
|
|
754
|
+
|
|
755
|
+
### `ProjectArchitect.js` (src/components/ProjectArchitect.js)
|
|
756
|
+
|
|
757
|
+
**Props**: `rootPath`, `onRunCommand`, `CursorText`, `onReturn`
|
|
758
|
+
**Lines**: 113
|
|
759
|
+
|
|
760
|
+
**Features**:
|
|
761
|
+
- 7+ templates (Next.js, React, Vue, Rust, Django, Python, Go)
|
|
762
|
+
- Multi-step: framework → path → name
|
|
763
|
+
- Command execution via Orbit
|
|
764
|
+
|
|
765
|
+
### `Studio.js` (src/components/Studio.js)
|
|
766
|
+
|
|
767
|
+
**Props**: None (checks binaries)
|
|
768
|
+
**Lines**: 64
|
|
769
|
+
|
|
770
|
+
**Features**:
|
|
771
|
+
- Runtime version checking
|
|
772
|
+
- 8 languages checked (Node, npm, Python, Rust, Go, Java, PHP, Ruby, .NET)
|
|
773
|
+
- Status display (✓/✗)
|
|
774
|
+
|
|
775
|
+
---
|
|
776
|
+
|
|
777
|
+
## Detection System
|
|
778
|
+
|
|
779
|
+
### How Detection Works
|
|
780
|
+
|
|
781
|
+
1. **User runs**: `project-compass` or `node src/cli.js`
|
|
782
|
+
2. **`parseArgs()`** (line 766): Parse CLI arguments
|
|
783
|
+
3. **`main()`** (line 783): Entry point
|
|
784
|
+
4. **`useScanner(rootPath)`** (line 67): Async effect
|
|
785
|
+
5. **`discoverProjects(root)`** (projectDetection.js:146):
|
|
786
|
+
- Iterate through `detectors` array (priority order)
|
|
787
|
+
- For each detector, use `fast-glob` to find manifest files
|
|
788
|
+
- Run `detector.build(projectPath, manifest)` to get project object
|
|
789
|
+
- Load `compass.config.js` (if exists) and merge
|
|
790
|
+
- Apply `applyFrameworkPlugins()` to add framework commands
|
|
791
|
+
- Return sorted array (by priority)
|
|
792
|
+
6. **State Update**: Projects stored in `Compass` component state
|
|
793
|
+
7. **UI Render**: Ink components display projects
|
|
794
|
+
|
|
795
|
+
### Detector Interface
|
|
796
|
+
|
|
797
|
+
Each detector in `src/detectors/` exports:
|
|
798
|
+
|
|
799
|
+
```javascript
|
|
800
|
+
export default {
|
|
801
|
+
type: 'python', // Language identifier
|
|
802
|
+
label: 'Python', // Display name
|
|
803
|
+
icon: '🐍', // Emoji icon
|
|
804
|
+
priority: 95, // Numeric priority (higher = preferred)
|
|
805
|
+
files: ['pyproject.toml', 'requirements.txt', ...], // Manifest files to match
|
|
806
|
+
binaries: ['python3', 'python', 'uv'], // Required binaries to check
|
|
807
|
+
async build(projectPath, manifest) {
|
|
808
|
+
// Return project object or null
|
|
809
|
+
return {
|
|
810
|
+
id: `${projectPath}::python`,
|
|
811
|
+
path: projectPath,
|
|
812
|
+
name: path.basename(projectPath),
|
|
813
|
+
type: 'Python',
|
|
814
|
+
icon: '🐍',
|
|
815
|
+
priority: this.priority,
|
|
816
|
+
commands: { ... },
|
|
817
|
+
metadata: { ... },
|
|
818
|
+
manifest: path.basename(manifest),
|
|
819
|
+
description: '...',
|
|
820
|
+
missingBinaries: [...],
|
|
821
|
+
frameworks: [...],
|
|
822
|
+
extra: { ... }
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
### Framework Plugin System
|
|
829
|
+
|
|
830
|
+
#### Built-in Frameworks (`src/detectors/frameworks.js`)
|
|
831
|
+
|
|
832
|
+
**40+ frameworks** with the following structure:
|
|
833
|
+
|
|
834
|
+
```javascript
|
|
835
|
+
{
|
|
836
|
+
id: 'fastapi',
|
|
837
|
+
name: 'FastAPI',
|
|
838
|
+
icon: '⚡',
|
|
839
|
+
description: 'Modern fast web framework for Python',
|
|
840
|
+
languages: ['Python'], // Which languages this applies to
|
|
841
|
+
priority: 112, // Plugin priority (boosts project priority)
|
|
842
|
+
match(project) {
|
|
843
|
+
// Return true if this framework is detected
|
|
844
|
+
return dependencyMatches(project, 'fastapi'); // ✅ Use dependencyMatches()
|
|
845
|
+
},
|
|
846
|
+
commands(project) {
|
|
847
|
+
// Return commands specific to this framework
|
|
848
|
+
return {
|
|
849
|
+
install: { label: 'FastAPI deps', command: ['pip', 'install', '-r', 'requirements.txt'], source: 'framework' },
|
|
850
|
+
run: { label: 'FastAPI dev', command: ['uvicorn', 'main:app', '--reload'], source: 'framework' },
|
|
851
|
+
test: { label: 'FastAPI test', command: ['pytest'], source: 'framework' }
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
#### Custom Plugins (`~/.project-compass/plugins.json`)
|
|
858
|
+
|
|
859
|
+
Users can add custom framework plugins:
|
|
860
|
+
|
|
861
|
+
```json
|
|
862
|
+
{
|
|
863
|
+
"plugins": [
|
|
864
|
+
{
|
|
865
|
+
"name": "My Framework",
|
|
866
|
+
"icon": "🚀",
|
|
867
|
+
"languages": ["Node.js"],
|
|
868
|
+
"files": ["my-framework.config.js"],
|
|
869
|
+
"dependencies": ["my-framework"],
|
|
870
|
+
"priority": 100,
|
|
871
|
+
"commands": {
|
|
872
|
+
"dev": { "label": "Dev", "command": ["my-cli", "dev"] }
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
]
|
|
876
|
+
}
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
---
|
|
880
|
+
|
|
881
|
+
## State Management
|
|
882
|
+
|
|
883
|
+
### Current Implementation (in `Compass` component)
|
|
884
|
+
|
|
885
|
+
All state is managed directly in the `Compass` component:
|
|
886
|
+
|
|
887
|
+
```javascript
|
|
888
|
+
const [projects, setProjects] = useState([]);
|
|
889
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
890
|
+
const [viewMode, setViewMode] = useState('list');
|
|
891
|
+
const [mainView, setMainView] = useState(initialView);
|
|
892
|
+
const [tasks, setTasks] = useState([]);
|
|
893
|
+
const [activeTaskId, setActiveTaskId] = useState(null);
|
|
894
|
+
const [logOffset, setLogOffset] = useState(0);
|
|
895
|
+
const [customMode, setCustomMode] = useState(false);
|
|
896
|
+
const [portConfigMode, setPortConfigMode] = useState(false);
|
|
897
|
+
// ... more state variables
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
---
|
|
903
|
+
|
|
904
|
+
## Command Execution Flow
|
|
905
|
+
|
|
906
|
+
### Execution Flow
|
|
907
|
+
|
|
908
|
+
```
|
|
909
|
+
User presses key (B/T/R/I or Enter on detail view)
|
|
910
|
+
↓
|
|
911
|
+
useInput handler in Compass component (src/cli.js:324-592)
|
|
912
|
+
↓
|
|
913
|
+
runProjectCommand(commandMeta, project)
|
|
914
|
+
↓
|
|
915
|
+
execa(commandMeta.command[0], commandMeta.command.slice(1), {
|
|
916
|
+
cwd: project.path,
|
|
917
|
+
env: process.env,
|
|
918
|
+
stdin: 'pipe', // For interactive input
|
|
919
|
+
detached: process.platform !== 'win32' // For proper cleanup
|
|
920
|
+
})
|
|
921
|
+
↓
|
|
922
|
+
subprocess.stdout?.on('data', ...) // Stream stdout
|
|
923
|
+
subprocess.stderr?.on('data', ...) // Stream stderr
|
|
924
|
+
↓
|
|
925
|
+
addLogToTask(taskId, line) // Append to task logs
|
|
926
|
+
↓
|
|
927
|
+
Task status updates: 'running' → 'finished' / 'failed' / 'killed'
|
|
928
|
+
```
|
|
929
|
+
|
|
930
|
+
### Task Object Structure
|
|
931
|
+
|
|
932
|
+
```javascript
|
|
933
|
+
{
|
|
934
|
+
id: 'task-' + Date.now(), // Unique task ID
|
|
935
|
+
name: `${project.name} · ${commandLabel}`, // Display name
|
|
936
|
+
status: 'running' | 'finished' | 'failed' | 'killed',
|
|
937
|
+
logs: ['line1', 'line2', ...], // Log lines (capped at 500)
|
|
938
|
+
project: 'Project Name' // Source project name
|
|
939
|
+
}
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
### Process Management
|
|
943
|
+
|
|
944
|
+
- **Process Map**: `runningProcessMap` (useRef Map)
|
|
945
|
+
- Stores references to child processes
|
|
946
|
+
- Key: taskId
|
|
947
|
+
- Value: execa subprocess object
|
|
948
|
+
|
|
949
|
+
- **Kill Process** (`handleKillTask`):
|
|
950
|
+
- Windows: `taskkill /pid <pid> /f /t`
|
|
951
|
+
- Unix: `process.kill(-pid, 'SIGKILL')` (process group)
|
|
952
|
+
- Fallback: `proc.kill('SIGKILL')`
|
|
953
|
+
|
|
954
|
+
- **Kill All** (`killAllTasks`):
|
|
955
|
+
- Iterates `runningProcessMap`
|
|
956
|
+
- Kills each process
|
|
957
|
+
- Clears the map
|
|
958
|
+
|
|
959
|
+
---
|
|
960
|
+
|
|
961
|
+
## Configuration System
|
|
962
|
+
|
|
963
|
+
### Config File: `~/.project-compass/config.json`
|
|
964
|
+
|
|
965
|
+
```json
|
|
966
|
+
{
|
|
967
|
+
"customCommands": {
|
|
968
|
+
"/path/to/project": [
|
|
969
|
+
{ "label": "My Command", "command": ["echo", "hello"], "source": "custom" }
|
|
970
|
+
]
|
|
971
|
+
},
|
|
972
|
+
"showArtBoard": true,
|
|
973
|
+
"showHelpCards": false,
|
|
974
|
+
"showStructureGuide": false,
|
|
975
|
+
"maxVisibleProjects": 3,
|
|
976
|
+
"aiProvider": "openrouter",
|
|
977
|
+
"aiModel": "deepseek/deepseek-r1",
|
|
978
|
+
"aiToken": "your-api-token-here",
|
|
979
|
+
"projectMeta": {
|
|
980
|
+
"/path/to/project": { "port": "3000" }
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
```
|
|
984
|
+
|
|
985
|
+
### Configuration Options
|
|
986
|
+
|
|
987
|
+
| Option | Type | Default | Description |
|
|
988
|
+
|--------|------|---------|-------------|
|
|
989
|
+
| `customCommands` | Object | `{}` | Per-project custom commands |
|
|
990
|
+
| `showArtBoard` | Boolean | `true` | Show/hide the art board |
|
|
991
|
+
| `showHelpCards` | Boolean | `false` | Show/hide help cards |
|
|
992
|
+
| `showStructureGuide` | Boolean | `false` | Show/hide structure guide |
|
|
993
|
+
| `maxVisibleProjects` | Number | `3` | Projects per page in navigator |
|
|
994
|
+
| `aiProvider` | String | `"openrouter"` | AI provider ID |
|
|
995
|
+
| `aiModel` | String | `"deepseek/deepseek-r1"` | AI model to use |
|
|
996
|
+
| `aiToken` | String | `""` | API token for AI provider |
|
|
997
|
+
| `projectMeta` | Object | `{}` | Per-project metadata (ports, etc.) |
|
|
998
|
+
|
|
999
|
+
### Loading & Saving
|
|
1000
|
+
|
|
1001
|
+
```javascript
|
|
1002
|
+
function loadConfig() {
|
|
1003
|
+
try {
|
|
1004
|
+
if (fs.existsSync(CONFIG_PATH)) {
|
|
1005
|
+
const payload = fs.readFileSync(CONFIG_PATH, 'utf-8');
|
|
1006
|
+
const parsed = JSON.parse(payload || '{}');
|
|
1007
|
+
return {
|
|
1008
|
+
customCommands: {},
|
|
1009
|
+
showArtBoard: true,
|
|
1010
|
+
showHelpCards: false,
|
|
1011
|
+
showStructureGuide: false,
|
|
1012
|
+
maxVisibleProjects: 3,
|
|
1013
|
+
...parsed,
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
} catch (error) {
|
|
1017
|
+
console.error(`Ignoring corrupt config: ${error.message}`);
|
|
1018
|
+
}
|
|
1019
|
+
return { customCommands: {}, showArtBoard: true, showHelpCards: false, showStructureGuide: false, maxVisibleProjects: 3 };
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
function saveConfig(config) {
|
|
1023
|
+
try {
|
|
1024
|
+
ensureConfigDir();
|
|
1025
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
1026
|
+
} catch (error) {
|
|
1027
|
+
console.error(`Unable to persist config: ${error.message}`);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
```
|
|
1031
|
+
|
|
1032
|
+
### Project-Specific Config: `compass.config.js`
|
|
1033
|
+
|
|
1034
|
+
Create in your project root:
|
|
1035
|
+
|
|
1036
|
+
```javascript
|
|
1037
|
+
export default {
|
|
1038
|
+
commands: {
|
|
1039
|
+
custom: {
|
|
1040
|
+
label: 'My Command',
|
|
1041
|
+
command: ['echo', 'hello'],
|
|
1042
|
+
source: 'config'
|
|
1043
|
+
}
|
|
1044
|
+
},
|
|
1045
|
+
frameworks: [
|
|
1046
|
+
{ name: 'MyFramework', icon: '🚀' }
|
|
1047
|
+
]
|
|
1048
|
+
};
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
This file is:
|
|
1052
|
+
1. Checked during `discoverProjects()`
|
|
1053
|
+
2. Loaded via dynamic `import()` (ESM)
|
|
1054
|
+
3. Merged into project data (commands + frameworks)
|
|
1055
|
+
4. Applied BEFORE framework plugin detection
|
|
32
1056
|
|
|
33
1057
|
---
|
|
34
|
-
|
|
1058
|
+
|
|
1059
|
+
## Known Issues & TODO
|
|
1060
|
+
|
|
1061
|
+
### Known Issues
|
|
1062
|
+
|
|
1063
|
+
1. **Config Loading**: `loadConfig()` is called in `useState(() => loadConfig())`
|
|
1064
|
+
- If config file is corrupted, falls back to defaults but doesn't persist the fix
|
|
1065
|
+
|
|
1066
|
+
2. **Process Killing on Windows**: Line 242 in `cli.js`
|
|
1067
|
+
- May not properly kill child processes on Windows
|
|
1068
|
+
|
|
1069
|
+
3. **Log Buffer Memory**: Capped at 500 lines, but truncation happens in `addLogToTask`
|
|
1070
|
+
- If many tasks run simultaneously, memory could grow
|
|
1071
|
+
|
|
1072
|
+
4. **fast-glob Depth**: `projectDetection.js` line 155
|
|
1073
|
+
- `deep: 5` could miss deeply nested projects or be slow on large directories
|
|
1074
|
+
|
|
1075
|
+
5. **AI JSON Parsing**: `AIHorizon.js` line 173
|
|
1076
|
+
- Regex may fail on malformed JSON or if AI returns code blocks
|
|
1077
|
+
|
|
1078
|
+
### TODO (Future Enhancements)
|
|
1079
|
+
|
|
1080
|
+
1. **Add More Detectors**: Flutter, Elixir, Swift, Haskell
|
|
1081
|
+
2. **Improve Log Viewing**: Search/filter, click to expand, export per-task
|
|
1082
|
+
3. **Enhanced AI Integration**: Stream AI responses, more providers, cache suggestions
|
|
1083
|
+
4. **Configuration UI**: Settings view for config.json options
|
|
1084
|
+
5. **Task Dependencies**: Allow tasks to depend on other tasks
|
|
1085
|
+
6. **Project Groups/Tags**: Tag projects, filter by tag
|
|
1086
|
+
7. **WebSocket/Real-time Updates**: Watch for file changes, hot-reload plugins.json
|
|
1087
|
+
|
|
1088
|
+
---
|
|
1089
|
+
|
|
1090
|
+
## Testing Checklist
|
|
1091
|
+
|
|
1092
|
+
### Before Committing
|
|
1093
|
+
|
|
1094
|
+
- [ ] Run `npm run lint` - Must pass with 0 errors
|
|
1095
|
+
- [ ] Run `npm run test` - Project detection works
|
|
1096
|
+
- [ ] Test all CLI arguments (see CLI Arguments section)
|
|
1097
|
+
- [ ] Test all TUI keyboard shortcuts (see TUI Keyboard Shortcuts section)
|
|
1098
|
+
- [ ] Test with projects WITHOUT frameworks (should show "none")
|
|
1099
|
+
- [ ] Test with projects WITH frameworks (should detect correctly)
|
|
1100
|
+
- [ ] Test AI Horizon with real API token
|
|
1101
|
+
- [ ] Test package management (add/remove)
|
|
1102
|
+
- [ ] Test project scaffolding
|
|
1103
|
+
- [ ] Test task management (kill, rename, export)
|
|
1104
|
+
- [ ] Update ALL markdown files with changes
|
|
1105
|
+
- [ ] Use conventional commit messages (`feat:`, `fix:`, `docs:`, `refactor:`)
|
|
1106
|
+
|
|
1107
|
+
### Quick Test Commands
|
|
1108
|
+
|
|
1109
|
+
```bash
|
|
1110
|
+
# Lint
|
|
1111
|
+
npm run lint
|
|
1112
|
+
|
|
1113
|
+
# Project detection
|
|
1114
|
+
node src/cli.js --list-projects --dir /path/to/workspace
|
|
1115
|
+
|
|
1116
|
+
# CLI run
|
|
1117
|
+
node src/cli.js --run "echo test" --dir /tmp
|
|
1118
|
+
|
|
1119
|
+
# Package management
|
|
1120
|
+
node src/cli.js --add-pkg "express" --dir /path/to/project
|
|
1121
|
+
|
|
1122
|
+
# Scaffolding
|
|
1123
|
+
node src/cli.js --scaffold python-basic --name test --dir /tmp
|
|
1124
|
+
|
|
1125
|
+
# Environment check
|
|
1126
|
+
node src/cli.js --studio-check
|
|
1127
|
+
|
|
1128
|
+
# TUI mode
|
|
1129
|
+
npm start
|
|
1130
|
+
```
|
|
1131
|
+
|
|
1132
|
+
---
|
|
1133
|
+
|