@tyroneross/navgator 0.1.0

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.
Files changed (84) hide show
  1. package/.claude-plugin/plugin.json +10 -0
  2. package/LICENSE +21 -0
  3. package/README.md +486 -0
  4. package/agents/architecture-advisor.md +109 -0
  5. package/commands/nav-check.md +64 -0
  6. package/commands/nav-connections.md +58 -0
  7. package/commands/nav-diagram.md +106 -0
  8. package/commands/nav-export.md +71 -0
  9. package/commands/nav-impact.md +58 -0
  10. package/commands/nav-scan.md +46 -0
  11. package/commands/nav-status.md +44 -0
  12. package/dist/cli/index.d.ts +7 -0
  13. package/dist/cli/index.d.ts.map +1 -0
  14. package/dist/cli/index.js +627 -0
  15. package/dist/cli/index.js.map +1 -0
  16. package/dist/config.d.ts +95 -0
  17. package/dist/config.d.ts.map +1 -0
  18. package/dist/config.js +262 -0
  19. package/dist/config.js.map +1 -0
  20. package/dist/diagram.d.ts +36 -0
  21. package/dist/diagram.d.ts.map +1 -0
  22. package/dist/diagram.js +333 -0
  23. package/dist/diagram.js.map +1 -0
  24. package/dist/index.d.ts +16 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +18 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/scanner.d.ts +57 -0
  29. package/dist/scanner.d.ts.map +1 -0
  30. package/dist/scanner.js +282 -0
  31. package/dist/scanner.js.map +1 -0
  32. package/dist/scanners/connections/ast-scanner.d.ts +26 -0
  33. package/dist/scanners/connections/ast-scanner.d.ts.map +1 -0
  34. package/dist/scanners/connections/ast-scanner.js +430 -0
  35. package/dist/scanners/connections/ast-scanner.js.map +1 -0
  36. package/dist/scanners/connections/service-calls.d.ts +14 -0
  37. package/dist/scanners/connections/service-calls.d.ts.map +1 -0
  38. package/dist/scanners/connections/service-calls.js +719 -0
  39. package/dist/scanners/connections/service-calls.js.map +1 -0
  40. package/dist/scanners/infrastructure/index.d.ts +27 -0
  41. package/dist/scanners/infrastructure/index.d.ts.map +1 -0
  42. package/dist/scanners/infrastructure/index.js +233 -0
  43. package/dist/scanners/infrastructure/index.js.map +1 -0
  44. package/dist/scanners/packages/npm.d.ts +18 -0
  45. package/dist/scanners/packages/npm.d.ts.map +1 -0
  46. package/dist/scanners/packages/npm.js +256 -0
  47. package/dist/scanners/packages/npm.js.map +1 -0
  48. package/dist/scanners/packages/pip.d.ts +14 -0
  49. package/dist/scanners/packages/pip.d.ts.map +1 -0
  50. package/dist/scanners/packages/pip.js +228 -0
  51. package/dist/scanners/packages/pip.js.map +1 -0
  52. package/dist/scanners/prompts/detector.d.ts +119 -0
  53. package/dist/scanners/prompts/detector.d.ts.map +1 -0
  54. package/dist/scanners/prompts/detector.js +617 -0
  55. package/dist/scanners/prompts/detector.js.map +1 -0
  56. package/dist/scanners/prompts/index.d.ts +51 -0
  57. package/dist/scanners/prompts/index.d.ts.map +1 -0
  58. package/dist/scanners/prompts/index.js +340 -0
  59. package/dist/scanners/prompts/index.js.map +1 -0
  60. package/dist/scanners/prompts/types.d.ts +127 -0
  61. package/dist/scanners/prompts/types.d.ts.map +1 -0
  62. package/dist/scanners/prompts/types.js +37 -0
  63. package/dist/scanners/prompts/types.js.map +1 -0
  64. package/dist/setup.d.ts +65 -0
  65. package/dist/setup.d.ts.map +1 -0
  66. package/dist/setup.js +261 -0
  67. package/dist/setup.js.map +1 -0
  68. package/dist/storage.d.ts +147 -0
  69. package/dist/storage.d.ts.map +1 -0
  70. package/dist/storage.js +931 -0
  71. package/dist/storage.js.map +1 -0
  72. package/dist/types.d.ts +296 -0
  73. package/dist/types.d.ts.map +1 -0
  74. package/dist/types.js +55 -0
  75. package/dist/types.js.map +1 -0
  76. package/dist/ui-server.d.ts +17 -0
  77. package/dist/ui-server.d.ts.map +1 -0
  78. package/dist/ui-server.js +815 -0
  79. package/dist/ui-server.js.map +1 -0
  80. package/hooks/hooks.json +57 -0
  81. package/package.json +80 -0
  82. package/scripts/ibr-ui-test.mjs +359 -0
  83. package/scripts/postinstall.cjs +35 -0
  84. package/skills/architecture-awareness/SKILL.md +141 -0
package/dist/setup.js ADDED
@@ -0,0 +1,261 @@
1
+ /**
2
+ * NavGator Setup & Initial Scan
3
+ *
4
+ * Provides a two-phase scanning approach:
5
+ * 1. Fast scan: Quick package detection, basic file structure (instant feedback)
6
+ * 2. Deep scan: Full AST analysis, connection detection, prompt scanning
7
+ *
8
+ * The fast scan uses lightweight regex patterns and file system analysis.
9
+ * The deep scan uses ts-morph AST analysis for accurate detection.
10
+ */
11
+ import * as fs from 'fs';
12
+ import * as path from 'path';
13
+ import { scan, quickScan } from './scanner.js';
14
+ import { getConfig } from './config.js';
15
+ import { generateMermaidDiagram, generateSummaryDiagram } from './diagram.js';
16
+ import { loadGraph } from './storage.js';
17
+ /**
18
+ * Run initial NavGator setup with two-phase scanning
19
+ */
20
+ export async function setup(options = {}) {
21
+ const projectPath = options.projectPath || process.cwd();
22
+ const startTime = Date.now();
23
+ const errors = [];
24
+ const progress = options.onProgress || ((phase, msg) => {
25
+ if (options.verbose) {
26
+ console.log(`[${phase}] ${msg}`);
27
+ }
28
+ });
29
+ let fastScanComplete = false;
30
+ let deepScanComplete = false;
31
+ let componentsFound = 0;
32
+ let connectionsFound = 0;
33
+ let promptsFound = 0;
34
+ let diagram;
35
+ let fastDuration = 0;
36
+ let deepDuration;
37
+ // ==========================================================================
38
+ // PHASE 1: Fast Scan
39
+ // ==========================================================================
40
+ progress('FAST', 'Starting fast scan...');
41
+ const fastStart = Date.now();
42
+ try {
43
+ const fastResult = await quickScan(projectPath);
44
+ componentsFound = fastResult.components.length;
45
+ connectionsFound = fastResult.connections.length;
46
+ fastScanComplete = true;
47
+ fastDuration = Date.now() - fastStart;
48
+ progress('FAST', `Found ${componentsFound} components in ${fastDuration}ms`);
49
+ // Generate initial diagram from fast scan
50
+ if (options.generateDiagram) {
51
+ progress('FAST', 'Generating initial diagram...');
52
+ const config = getConfig();
53
+ const graph = await loadGraph(config);
54
+ if (graph) {
55
+ diagram = generateSummaryDiagram(graph, { maxNodes: 30 });
56
+ progress('FAST', 'Initial diagram generated');
57
+ }
58
+ }
59
+ // Create initial index to mark scan as complete
60
+ await markScanComplete(projectPath, {
61
+ totalComponents: componentsFound,
62
+ totalConnections: connectionsFound,
63
+ phase: 'fast',
64
+ });
65
+ }
66
+ catch (error) {
67
+ const msg = error instanceof Error ? error.message : 'Fast scan failed';
68
+ errors.push(msg);
69
+ progress('FAST', `Error: ${msg}`);
70
+ }
71
+ // ==========================================================================
72
+ // PHASE 2: Deep Scan (if not fastOnly)
73
+ // ==========================================================================
74
+ if (!options.fastOnly) {
75
+ progress('DEEP', 'Starting deep scan with full analysis...');
76
+ const deepStart = Date.now();
77
+ try {
78
+ const deepResult = await scan(projectPath, {
79
+ connections: true,
80
+ prompts: true,
81
+ useAST: true,
82
+ verbose: options.verbose,
83
+ });
84
+ componentsFound = deepResult.components.length;
85
+ connectionsFound = deepResult.connections.length;
86
+ promptsFound = deepResult.promptScan?.prompts.length || 0;
87
+ deepScanComplete = true;
88
+ deepDuration = Date.now() - deepStart;
89
+ progress('DEEP', `Found ${componentsFound} components, ${connectionsFound} connections, ${promptsFound} prompts in ${deepDuration}ms`);
90
+ // Update diagram with deeper analysis
91
+ if (options.generateDiagram) {
92
+ progress('DEEP', 'Updating diagram with full analysis...');
93
+ const config = getConfig();
94
+ const graph = await loadGraph(config);
95
+ if (graph) {
96
+ diagram = generateMermaidDiagram(graph, { maxNodes: 50 });
97
+ progress('DEEP', 'Full diagram generated');
98
+ }
99
+ }
100
+ // Mark deep scan complete
101
+ await markScanComplete(projectPath, {
102
+ totalComponents: componentsFound,
103
+ totalConnections: connectionsFound,
104
+ phase: 'deep',
105
+ });
106
+ }
107
+ catch (error) {
108
+ const msg = error instanceof Error ? error.message : 'Deep scan failed';
109
+ errors.push(msg);
110
+ progress('DEEP', `Error: ${msg}`);
111
+ }
112
+ }
113
+ const totalDuration = Date.now() - startTime;
114
+ return {
115
+ success: fastScanComplete && (options.fastOnly || deepScanComplete),
116
+ fastScanComplete,
117
+ deepScanComplete,
118
+ componentsFound,
119
+ connectionsFound,
120
+ promptsFound,
121
+ diagram,
122
+ duration: {
123
+ fastMs: fastDuration,
124
+ deepMs: deepDuration,
125
+ totalMs: totalDuration,
126
+ },
127
+ errors,
128
+ };
129
+ }
130
+ /**
131
+ * Run fast scan only (for quick initial view)
132
+ */
133
+ export async function fastSetup(projectPath) {
134
+ return setup({
135
+ projectPath,
136
+ fastOnly: true,
137
+ generateDiagram: true,
138
+ });
139
+ }
140
+ /**
141
+ * Run full setup with both phases
142
+ */
143
+ export async function fullSetup(projectPath) {
144
+ return setup({
145
+ projectPath,
146
+ fastOnly: false,
147
+ generateDiagram: true,
148
+ verbose: true,
149
+ });
150
+ }
151
+ /**
152
+ * Check if NavGator has been set up for a project
153
+ */
154
+ export async function isSetupComplete(projectPath) {
155
+ const root = projectPath || process.cwd();
156
+ const indexPath = path.join(root, '.claude', 'architecture', 'index.json');
157
+ try {
158
+ const content = await fs.promises.readFile(indexPath, 'utf-8');
159
+ const index = JSON.parse(content);
160
+ const lastScan = new Date(index.last_scan);
161
+ const hoursSince = (Date.now() - index.last_scan) / (1000 * 60 * 60);
162
+ return {
163
+ hasScanned: true,
164
+ lastScan,
165
+ phase: index.version?.includes('deep') ? 'deep' : 'fast',
166
+ stale: hoursSince > 24,
167
+ };
168
+ }
169
+ catch {
170
+ return {
171
+ hasScanned: false,
172
+ stale: true,
173
+ };
174
+ }
175
+ }
176
+ /**
177
+ * Mark scan as complete in the index
178
+ */
179
+ async function markScanComplete(projectPath, stats) {
180
+ const config = getConfig();
181
+ const archDir = path.join(projectPath, '.claude', 'architecture');
182
+ // Ensure directory exists
183
+ await fs.promises.mkdir(archDir, { recursive: true });
184
+ const indexPath = path.join(archDir, 'index.json');
185
+ let index;
186
+ try {
187
+ const content = await fs.promises.readFile(indexPath, 'utf-8');
188
+ index = JSON.parse(content);
189
+ }
190
+ catch {
191
+ index = {
192
+ version: '1.0.0',
193
+ last_scan: Date.now(),
194
+ project_path: projectPath,
195
+ components: {
196
+ by_name: {},
197
+ by_type: {},
198
+ by_layer: {},
199
+ by_status: {},
200
+ },
201
+ connections: {
202
+ by_type: {},
203
+ by_from: {},
204
+ by_to: {},
205
+ },
206
+ stats: {
207
+ total_components: 0,
208
+ total_connections: 0,
209
+ components_by_type: {},
210
+ connections_by_type: {},
211
+ outdated_count: 0,
212
+ vulnerable_count: 0,
213
+ },
214
+ };
215
+ }
216
+ index.last_scan = Date.now();
217
+ index.version = `1.0.0-${stats.phase}`;
218
+ index.stats.total_components = stats.totalComponents;
219
+ index.stats.total_connections = stats.totalConnections;
220
+ await fs.promises.writeFile(indexPath, JSON.stringify(index, null, 2));
221
+ }
222
+ /**
223
+ * Get setup status for display
224
+ */
225
+ export function formatSetupStatus(result) {
226
+ const lines = [];
227
+ lines.push('');
228
+ lines.push('╔═══════════════════════════════════════════════════════════╗');
229
+ lines.push('║ NavGator Setup Complete ║');
230
+ lines.push('╚═══════════════════════════════════════════════════════════╝');
231
+ lines.push('');
232
+ if (result.success) {
233
+ lines.push('✓ Architecture scan complete');
234
+ lines.push('');
235
+ lines.push(` Components: ${result.componentsFound}`);
236
+ lines.push(` Connections: ${result.connectionsFound}`);
237
+ if (result.promptsFound > 0) {
238
+ lines.push(` AI Prompts: ${result.promptsFound}`);
239
+ }
240
+ lines.push('');
241
+ lines.push(` Fast scan: ${result.duration.fastMs}ms`);
242
+ if (result.duration.deepMs) {
243
+ lines.push(` Deep scan: ${result.duration.deepMs}ms`);
244
+ }
245
+ lines.push(` Total: ${result.duration.totalMs}ms`);
246
+ }
247
+ else {
248
+ lines.push('⚠ Setup completed with errors:');
249
+ for (const error of result.errors) {
250
+ lines.push(` - ${error}`);
251
+ }
252
+ }
253
+ lines.push('');
254
+ lines.push('Next steps:');
255
+ lines.push(' • navgator status - View architecture summary');
256
+ lines.push(' • navgator diagram - Generate visual diagram');
257
+ lines.push(' • navgator impact <x> - See what changes affect');
258
+ lines.push('');
259
+ return lines.join('\n');
260
+ }
261
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * NavGator Storage System
3
+ * File-based persistence for components and connections
4
+ */
5
+ import { ArchitectureComponent, ArchitectureConnection, ArchitectureIndex, ConnectionGraph, NavGatorConfig, NavHashes, FileHashRecord, FileChangeResult } from './types.js';
6
+ /**
7
+ * Store a component to disk
8
+ */
9
+ export declare function storeComponent(component: ArchitectureComponent, config?: NavGatorConfig, projectRoot?: string): Promise<{
10
+ component_id: string;
11
+ file_path: string;
12
+ }>;
13
+ /**
14
+ * Load a component by ID
15
+ */
16
+ export declare function loadComponent(componentId: string, config?: NavGatorConfig, projectRoot?: string): Promise<ArchitectureComponent | null>;
17
+ /**
18
+ * Load all components (parallelized for efficiency)
19
+ */
20
+ export declare function loadAllComponents(config?: NavGatorConfig, projectRoot?: string): Promise<ArchitectureComponent[]>;
21
+ /**
22
+ * Delete a component by ID
23
+ */
24
+ export declare function deleteComponent(componentId: string, config?: NavGatorConfig, projectRoot?: string): Promise<boolean>;
25
+ /**
26
+ * Store a connection to disk
27
+ */
28
+ export declare function storeConnection(connection: ArchitectureConnection, config?: NavGatorConfig, projectRoot?: string): Promise<{
29
+ connection_id: string;
30
+ file_path: string;
31
+ }>;
32
+ /**
33
+ * Load a connection by ID
34
+ */
35
+ export declare function loadConnection(connectionId: string, config?: NavGatorConfig, projectRoot?: string): Promise<ArchitectureConnection | null>;
36
+ /**
37
+ * Load all connections (parallelized for efficiency)
38
+ */
39
+ export declare function loadAllConnections(config?: NavGatorConfig, projectRoot?: string): Promise<ArchitectureConnection[]>;
40
+ /**
41
+ * Delete a connection by ID
42
+ */
43
+ export declare function deleteConnection(connectionId: string, config?: NavGatorConfig, projectRoot?: string): Promise<boolean>;
44
+ /**
45
+ * Build and save the index from current components and connections
46
+ */
47
+ export declare function buildIndex(config?: NavGatorConfig, projectRoot?: string): Promise<ArchitectureIndex>;
48
+ /**
49
+ * Load the index
50
+ */
51
+ export declare function loadIndex(config?: NavGatorConfig, projectRoot?: string): Promise<ArchitectureIndex | null>;
52
+ /**
53
+ * Build the connection graph
54
+ */
55
+ export declare function buildGraph(config?: NavGatorConfig, projectRoot?: string): Promise<ConnectionGraph>;
56
+ /**
57
+ * Build a map of file paths → component IDs for fast lookup in hooks.
58
+ * Sources: component config_files + connection code_reference files + connection locations.
59
+ */
60
+ export declare function buildFileMap(config?: NavGatorConfig, projectRoot?: string): Promise<Record<string, string>>;
61
+ /**
62
+ * Save prompt scan results to prompts.json
63
+ */
64
+ export declare function savePromptScan(promptData: unknown, config?: NavGatorConfig, projectRoot?: string): Promise<void>;
65
+ /**
66
+ * Build a concise markdown summary with pointers to detail files.
67
+ * This is the "hot context" an LLM reads first on cold start.
68
+ */
69
+ export declare function buildSummary(config?: NavGatorConfig, projectRoot?: string, promptScan?: {
70
+ prompts: Array<{
71
+ name: string;
72
+ location: {
73
+ file: string;
74
+ lineStart: number;
75
+ };
76
+ provider?: {
77
+ provider: string;
78
+ model?: string;
79
+ };
80
+ category?: string;
81
+ messages: Array<{
82
+ role: string;
83
+ content: string;
84
+ }>;
85
+ }>;
86
+ summary: {
87
+ totalPrompts: number;
88
+ };
89
+ }): Promise<string>;
90
+ /**
91
+ * Load the graph
92
+ */
93
+ export declare function loadGraph(config?: NavGatorConfig, projectRoot?: string): Promise<ConnectionGraph | null>;
94
+ /**
95
+ * Create a snapshot of current architecture
96
+ */
97
+ export declare function createSnapshot(reason?: string, config?: NavGatorConfig, projectRoot?: string): Promise<{
98
+ snapshot_id: string;
99
+ file_path: string;
100
+ }>;
101
+ /**
102
+ * Store multiple components at once (parallelized for efficiency)
103
+ */
104
+ export declare function storeComponents(components: ArchitectureComponent[], config?: NavGatorConfig, projectRoot?: string): Promise<void>;
105
+ /**
106
+ * Store multiple connections at once (parallelized for efficiency)
107
+ */
108
+ export declare function storeConnections(connections: ArchitectureConnection[], config?: NavGatorConfig, projectRoot?: string): Promise<void>;
109
+ /**
110
+ * Clear all stored data (parallelized for efficiency)
111
+ */
112
+ export declare function clearStorage(config?: NavGatorConfig, projectRoot?: string): Promise<void>;
113
+ /**
114
+ * Get storage statistics
115
+ */
116
+ export declare function getStorageStats(config?: NavGatorConfig, projectRoot?: string): Promise<{
117
+ total_components: number;
118
+ total_connections: number;
119
+ disk_usage_kb: number;
120
+ oldest_timestamp: number | null;
121
+ newest_timestamp: number | null;
122
+ }>;
123
+ /**
124
+ * Compute SHA-256 hash of a file
125
+ */
126
+ export declare function computeFileHash(filePath: string): Promise<string>;
127
+ /**
128
+ * Compute hashes for multiple files (parallelized in batches for efficiency)
129
+ */
130
+ export declare function computeFileHashes(files: string[], projectRoot: string): Promise<Record<string, FileHashRecord>>;
131
+ /**
132
+ * Save file hashes to disk
133
+ */
134
+ export declare function saveHashes(hashes: Record<string, FileHashRecord>, config?: NavGatorConfig, projectRoot?: string): Promise<void>;
135
+ /**
136
+ * Load file hashes from disk
137
+ */
138
+ export declare function loadHashes(config?: NavGatorConfig, projectRoot?: string): Promise<NavHashes | null>;
139
+ /**
140
+ * Detect which files have changed since last scan
141
+ */
142
+ export declare function detectFileChanges(currentFiles: string[], projectRoot: string, config?: NavGatorConfig): Promise<FileChangeResult>;
143
+ /**
144
+ * Get a summary of file changes for display
145
+ */
146
+ export declare function formatFileChangeSummary(changes: FileChangeResult): string;
147
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}