project-compass 4.1.0 → 4.1.2

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/README.md CHANGED
@@ -30,7 +30,7 @@ npm install -g project-compass
30
30
  ### 🏗️ Project Architect (`Shift+N`)
31
31
  - **Modern Templates**: Scaffold high-performance projects with built-in support for **Bun, Next.js, Vite, Rust, and Django**.
32
32
 
33
- ### 🤖 AI Horizon (`Shift+O` or `0`)
33
+ ### 🔌 Manual Infrastructure\n- **Port Mapping**: Hit `Shift + R` in details to manually assign ports to projects. Settings are saved persistently.\n\n### 🤖 AI Horizon (`Shift+O` or `0`)
34
34
  - **Intelligence Persistence**: Configure your provider (**OpenRouter, Gemini, Claude, Ollama**) once; Compass remembers your settings.
35
35
  - **Deep DNA Analysis**: Press `0` on any project to analyze its structure.
36
36
  - **Auto-Config (BRIT)**: AI automatically detects and configures missing **Build, Run, Install, and Test** commands, saving them directly to your `config.json`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-compass",
3
- "version": "4.1.0",
3
+ "version": "4.1.2",
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
@@ -153,6 +153,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
153
153
  const [activeTaskId, setActiveTaskId] = useState(null);
154
154
  const [logOffset, setLogOffset] = useState(0);
155
155
  const [customMode, setCustomMode] = useState(false);
156
+ const [portConfigMode, setPortConfigMode] = useState(false);
156
157
  const [customInput, setCustomInput] = useState('');
157
158
  const [customCursor, setCustomCursor] = useState(0);
158
159
  const [renameMode, setRenameMode] = useState(false);
@@ -301,7 +302,37 @@ function Compass({rootPath, initialView = 'navigator'}) {
301
302
 
302
303
  const isCtrlC = (key.ctrl && input === 'c') || input === '\u0003';
303
304
 
304
- if (customMode) {
305
+
306
+ if (portConfigMode) {
307
+ if (key.return) {
308
+ const portVal = customInput.trim();
309
+ if (selectedProject && portVal) {
310
+ setConfig((prev) => {
311
+ const projectKey = selectedProject.path;
312
+ const existingMeta = prev.projectMeta?.[projectKey] || {};
313
+ const nextConfig = { ...prev, projectMeta: { ...prev.projectMeta, [projectKey]: { ...existingMeta, port: portVal } } };
314
+ saveConfig(nextConfig);
315
+ return nextConfig;
316
+ });
317
+ }
318
+ setPortConfigMode(false); setCustomInput(''); setCustomCursor(0);
319
+ return;
320
+ }
321
+ if (key.escape) { setPortConfigMode(false); setCustomInput(''); setCustomCursor(0); return; }
322
+ if (key.backspace || key.delete) {
323
+ if (customCursor > 0) {
324
+ setCustomInput((prev) => prev.slice(0, customCursor - 1) + prev.slice(customCursor));
325
+ setCustomCursor(c => Math.max(0, c - 1));
326
+ }
327
+ return;
328
+ }
329
+ if (input && /[0-9]/.test(input)) {
330
+ setCustomInput((prev) => prev.slice(0, customCursor) + input + prev.slice(customCursor));
331
+ setCustomCursor(c => c + input.length);
332
+ }
333
+ return;
334
+ }
335
+ if (customMode) {
305
336
  if (key.return) {
306
337
  const raw = customInput.trim();
307
338
  const selProj = selectedProject;
@@ -453,10 +484,7 @@ function Compass({rootPath, initialView = 'navigator'}) {
453
484
 
454
485
  const pageLimit = config.maxVisibleProjects || 3;
455
486
  const pageStep = Math.max(1, pageLimit);
456
- const clampIndex = (value) => {
457
- const idx = Math.max(0, Math.min(projects.length - 1, value));
458
- return isNaN(idx) ? 0 : idx;
459
- };
487
+
460
488
  if (key.pageUp && projects.length > pageLimit) {
461
489
  console.clear();
462
490
  setSelectedIndex((prev) => {
@@ -495,7 +523,12 @@ function Compass({rootPath, initialView = 'navigator'}) {
495
523
  return;
496
524
  }
497
525
 
498
- if (shiftCombo('c') && viewMode === 'detail' && selectedProject) { setCustomMode(true); setCustomInput(''); setCustomCursor(0); return; }
526
+
527
+ if (shiftCombo('r') && viewMode === 'detail' && selectedProject) {
528
+ setPortConfigMode(true); setCustomInput(selectedProject.metadata?.port || '3000'); setCustomCursor(String(selectedProject.metadata?.port || '3000').length);
529
+ return;
530
+ }
531
+ if (shiftCombo('c') && viewMode === 'detail' && selectedProject) { setCustomMode(true); setCustomInput(''); setCustomCursor(0); return; }
499
532
 
500
533
  const actionKey = normalizedInput && ACTION_MAP[normalizedInput];
501
534
  if (actionKey) {
@@ -1,4 +1,4 @@
1
- /* global setTimeout, fetch */
1
+ /* global fetch */
2
2
  import React, {useState, memo} from 'react';
3
3
  import {Box, Text, useInput} from 'ink';
4
4