project-compass 4.0.6 → 4.1.1
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 +58 -5
- package/src/components/AIHorizon.js +1 -1
- package/src/detectors/dotnet.js +13 -0
- package/src/detectors/java.js +2 -2
- package/src/detectors/php.js +13 -0
- package/src/detectors/ruby.js +13 -0
- package/src/projectDetection.js +6 -0
package/package.json
CHANGED
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
|
-
|
|
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,9 +484,26 @@ 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
|
-
|
|
458
|
-
|
|
487
|
+
const clampIndex = (value) => {
|
|
488
|
+
const idx = Math.max(0, Math.min(projects.length - 1, value));
|
|
489
|
+
return isNaN(idx) ? 0 : idx;
|
|
490
|
+
};
|
|
491
|
+
if (key.pageUp && projects.length > pageLimit) {
|
|
492
|
+
console.clear();
|
|
493
|
+
setSelectedIndex((prev) => {
|
|
494
|
+
const next = prev - pageStep;
|
|
495
|
+
return next < 0 ? 0 : next;
|
|
496
|
+
});
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
if (key.pageDown && projects.length > pageLimit) {
|
|
500
|
+
console.clear();
|
|
501
|
+
setSelectedIndex((prev) => {
|
|
502
|
+
const next = prev + pageStep;
|
|
503
|
+
return next >= projects.length ? (Math.floor((projects.length - 1) / pageLimit) * pageLimit) : next;
|
|
504
|
+
});
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
459
507
|
|
|
460
508
|
if (normalizedInput === '?') { console.clear(); setShowHelp((prev) => !prev); return; }
|
|
461
509
|
if (shiftCombo('l') && lastCommandRef.current) { runProjectCommand(lastCommandRef.current.commandMeta, lastCommandRef.current.project); return; }
|
|
@@ -478,7 +526,12 @@ function Compass({rootPath, initialView = 'navigator'}) {
|
|
|
478
526
|
return;
|
|
479
527
|
}
|
|
480
528
|
|
|
481
|
-
|
|
529
|
+
|
|
530
|
+
if (shiftCombo('r') && viewMode === 'detail' && selectedProject) {
|
|
531
|
+
setPortConfigMode(true); setCustomInput(selectedProject.metadata?.port || '3000'); setCustomCursor(String(selectedProject.metadata?.port || '3000').length);
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
if (shiftCombo('c') && viewMode === 'detail' && selectedProject) { setCustomMode(true); setCustomInput(''); setCustomCursor(0); return; }
|
|
482
535
|
|
|
483
536
|
const actionKey = normalizedInput && ACTION_MAP[normalizedInput];
|
|
484
537
|
if (actionKey) {
|
|
@@ -221,7 +221,7 @@ Use the project's detected type (${selectedProject.type}) to ensure commands are
|
|
|
221
221
|
status === 'busy' && create(Text, {color: 'yellow'}, ' ⏳ Contacting AI Agent... mapping project structure...'),
|
|
222
222
|
status === 'done' && create(Box, {flexDirection: 'column'},
|
|
223
223
|
create(Text, {color: 'green', bold: true}, ' ✅ DNA Mapped via AI Agent!'),
|
|
224
|
-
create(Text, null, ' Successfully injected ' + suggestions.length + ' optimized commands
|
|
224
|
+
create(Text, null, ' Successfully injected ' + suggestions.length + ' optimized commands. AI detected potential port conflicts? Checking...'),
|
|
225
225
|
create(Text, {dimColor: true, marginTop: 1}, 'Return to Navigator to use BRIT shortcuts.')
|
|
226
226
|
),
|
|
227
227
|
error && create(Text, {color: 'red', bold: true, marginTop: 1}, ' ✗ AI ERROR: ' + error)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { checkBinary } from './utils.js';
|
|
3
|
+
export default {
|
|
4
|
+
type: 'dotnet', label: '.NET', icon: '🎯', priority: 65, files: ['*.csproj', '*.sln'], binaries: ['dotnet'],
|
|
5
|
+
async build(projectPath, manifest) {
|
|
6
|
+
const missingBinaries = this.binaries.filter(b => !checkBinary(b));
|
|
7
|
+
return {
|
|
8
|
+
id: `${projectPath}::dotnet`, path: projectPath, name: path.basename(projectPath), type: '.NET', icon: '🎯',
|
|
9
|
+
priority: this.priority, commands: { install: { label: 'dotnet restore', command: ['dotnet', 'restore'] } },
|
|
10
|
+
metadata: {}, manifest: path.basename(manifest), description: '', missingBinaries, extra: {}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
};
|
package/src/detectors/java.js
CHANGED
|
@@ -4,7 +4,7 @@ import { checkBinary, hasProjectFile } from './utils.js';
|
|
|
4
4
|
export default {
|
|
5
5
|
type: 'java',
|
|
6
6
|
label: 'Java',
|
|
7
|
-
icon: '
|
|
7
|
+
icon: '☕',
|
|
8
8
|
priority: 80,
|
|
9
9
|
files: ['pom.xml', 'build.gradle', 'build.gradle.kts'],
|
|
10
10
|
binaries: ['java', 'javac'],
|
|
@@ -31,7 +31,7 @@ export default {
|
|
|
31
31
|
path: projectPath,
|
|
32
32
|
name: path.basename(projectPath),
|
|
33
33
|
type: 'Java',
|
|
34
|
-
icon: '
|
|
34
|
+
icon: '☕',
|
|
35
35
|
priority: this.priority,
|
|
36
36
|
commands,
|
|
37
37
|
metadata: {},
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { checkBinary } from './utils.js';
|
|
3
|
+
export default {
|
|
4
|
+
type: 'php', label: 'PHP', icon: '🐘', priority: 65, files: ['composer.json'], binaries: ['php', 'composer'],
|
|
5
|
+
async build(projectPath, manifest) {
|
|
6
|
+
const missingBinaries = this.binaries.filter(b => !checkBinary(b));
|
|
7
|
+
return {
|
|
8
|
+
id: `${projectPath}::php`, path: projectPath, name: path.basename(projectPath), type: 'PHP', icon: '🐘',
|
|
9
|
+
priority: this.priority, commands: { install: { label: 'Composer install', command: ['composer', 'install'] } },
|
|
10
|
+
metadata: {}, manifest: path.basename(manifest), description: '', missingBinaries, extra: {}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { checkBinary } from './utils.js';
|
|
3
|
+
export default {
|
|
4
|
+
type: 'ruby', label: 'Ruby', icon: '💎', priority: 65, files: ['Gemfile'], binaries: ['ruby', 'bundle'],
|
|
5
|
+
async build(projectPath, manifest) {
|
|
6
|
+
const missingBinaries = this.binaries.filter(b => !checkBinary(b));
|
|
7
|
+
return {
|
|
8
|
+
id: `${projectPath}::ruby`, path: projectPath, name: path.basename(projectPath), type: 'Ruby', icon: '💎',
|
|
9
|
+
priority: this.priority, commands: { install: { label: 'Bundle install', command: ['bundle', 'install'] } },
|
|
10
|
+
metadata: {}, manifest: path.basename(manifest), description: '', missingBinaries, extra: {}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
};
|
package/src/projectDetection.js
CHANGED
|
@@ -8,6 +8,9 @@ import pythonDetector from './detectors/python.js';
|
|
|
8
8
|
import rustDetector from './detectors/rust.js';
|
|
9
9
|
import goDetector from './detectors/go.js';
|
|
10
10
|
import javaDetector from './detectors/java.js';
|
|
11
|
+
import phpDetector from './detectors/php.js';
|
|
12
|
+
import rubyDetector from './detectors/ruby.js';
|
|
13
|
+
import dotnetDetector from './detectors/dotnet.js';
|
|
11
14
|
import genericDetector from './detectors/generic.js';
|
|
12
15
|
import { builtInFrameworks } from './detectors/frameworks.js';
|
|
13
16
|
|
|
@@ -19,6 +22,9 @@ const detectors = [
|
|
|
19
22
|
rustDetector,
|
|
20
23
|
goDetector,
|
|
21
24
|
javaDetector,
|
|
25
|
+
phpDetector,
|
|
26
|
+
rubyDetector,
|
|
27
|
+
dotnetDetector,
|
|
22
28
|
genericDetector
|
|
23
29
|
];
|
|
24
30
|
|