directory-indexer 0.2.1 → 0.3.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.
@@ -0,0 +1,191 @@
1
+ import { indexDirectories } from "./indexing.js";
2
+ import { getFileContent, searchContent, findSimilarFiles } from "./search.js";
3
+ import { loadConfig } from "./config.js";
4
+ import { getIndexStatus } from "./storage.js";
5
+ import { startMcpServer } from "./mcp.js";
6
+ import { validateIndexPrerequisites, validateSearchPrerequisites, getServiceStatus } from "./prerequisites.js";
7
+ import { resetEnvironment } from "./reset.js";
8
+ async function handleIndex(paths, options) {
9
+ const config = await loadConfig({ verbose: options.verbose });
10
+ await validateIndexPrerequisites(config);
11
+ console.log(`Indexing ${paths.length} ${paths.length === 1 ? "directory" : "directories"}: ${paths.join(", ")}`);
12
+ if (!options.verbose) {
13
+ console.log("Run with --verbose for detailed per-file indexing reports");
14
+ console.log("Indexing can be safely stopped and resumed - progress is automatically saved");
15
+ console.log("You can start using the MCP server while indexing continues");
16
+ console.log("Indexing may take time due to embedding generation - see project README for performance tips");
17
+ }
18
+ const result = await indexDirectories(paths, config);
19
+ console.log(`Indexed ${result.indexed} files, skipped ${result.skipped} files, cleaned up ${result.deleted} deleted files, ${result.failed} failed`);
20
+ if (result.errors.length > 0) {
21
+ console.log(`Errors: [`);
22
+ result.errors.forEach((error) => {
23
+ console.log(` '${error}'`);
24
+ });
25
+ console.log(`]`);
26
+ }
27
+ }
28
+ async function handleSearch(query, options) {
29
+ const config = await loadConfig({ verbose: options.verbose });
30
+ await validateSearchPrerequisites(config);
31
+ const results = await searchContent(query, { limit: options.limit || 10 });
32
+ if (results.length === 0) {
33
+ console.log("No results found");
34
+ return;
35
+ }
36
+ console.log(`Found ${results.length} results:
37
+ `);
38
+ results.forEach((result, index) => {
39
+ console.log(`${index + 1}. ${result.filePath}`);
40
+ console.log(` Score: ${result.score.toFixed(3)} (${result.matchingChunks} chunks)`);
41
+ if (options.showChunks && result.chunks.length > 0) {
42
+ console.log(` Chunks:`);
43
+ result.chunks.forEach((chunk) => {
44
+ console.log(` - Chunk ${chunk.chunkId}: ${chunk.score.toFixed(3)}`);
45
+ });
46
+ }
47
+ console.log();
48
+ });
49
+ }
50
+ async function handleSimilar(filePath, options) {
51
+ const config = await loadConfig({ verbose: options.verbose });
52
+ await validateSearchPrerequisites(config);
53
+ const results = await findSimilarFiles(filePath, options.limit || 10);
54
+ if (results.length === 0) {
55
+ console.log("No similar files found");
56
+ return;
57
+ }
58
+ console.log(`Found ${results.length} similar files:
59
+ `);
60
+ results.forEach((result, index) => {
61
+ console.log(`${index + 1}. ${result.filePath}`);
62
+ console.log(` Similarity: ${result.score.toFixed(3)}`);
63
+ console.log();
64
+ });
65
+ }
66
+ async function handleGet(filePath, options) {
67
+ await loadConfig({ verbose: options.verbose });
68
+ const content = await getFileContent(filePath, options.chunks);
69
+ console.log(content);
70
+ }
71
+ async function handleServe(options) {
72
+ const config = await loadConfig({ verbose: options.verbose });
73
+ await startMcpServer(config);
74
+ }
75
+ async function handleReset(options) {
76
+ const config = await loadConfig({ verbose: options.verbose });
77
+ await resetEnvironment(config, {
78
+ force: options.force,
79
+ verbose: options.verbose
80
+ });
81
+ }
82
+ async function handleStatus(options) {
83
+ const config = await loadConfig({ verbose: options.verbose });
84
+ const [status, serviceStatus] = await Promise.all([
85
+ getIndexStatus(),
86
+ getServiceStatus(config)
87
+ ]);
88
+ console.log("Directory Indexer Status Report");
89
+ console.log("=====================================");
90
+ console.log("");
91
+ console.log("SERVICE STATUS:");
92
+ console.log(` • Qdrant database: ${serviceStatus.qdrant ? "Connected" : "Disconnected"}`);
93
+ console.log(` • Embedding service (${serviceStatus.embeddingProvider}): ${serviceStatus.embedding ? "Connected" : "Disconnected"}`);
94
+ console.log("");
95
+ console.log("OVERVIEW:");
96
+ console.log(` • ${status.directoriesIndexed} directories have been indexed`);
97
+ console.log(` • ${status.filesIndexed} files processed for semantic search`);
98
+ console.log(` • ${status.chunksIndexed} text chunks available for AI search`);
99
+ console.log(` • Database storage: ${status.databaseSize}`);
100
+ console.log(` • Most recent indexing: ${status.lastIndexed || "No indexing performed yet"}`);
101
+ if (status.errors.length > 0) {
102
+ console.log(` • Processing errors encountered: ${status.errors.length}`);
103
+ if (options.verbose) {
104
+ console.log("");
105
+ console.log("RECENT ERRORS:");
106
+ status.errors.slice(0, 5).forEach((error) => {
107
+ console.log(` - ${error}`);
108
+ });
109
+ }
110
+ }
111
+ console.log("");
112
+ console.log("INDEXED DIRECTORIES:");
113
+ if (status.directories.length === 0) {
114
+ console.log(" No directories have been indexed yet.");
115
+ console.log(' Run "directory-indexer index <path>" to start indexing.');
116
+ } else {
117
+ status.directories.forEach((dir) => {
118
+ console.log("");
119
+ console.log(` Directory: ${dir.path}`);
120
+ console.log(` • Indexing status: ${dir.status}`);
121
+ console.log(` • Files processed: ${dir.filesCount}`);
122
+ console.log(` • Searchable chunks: ${dir.chunksCount}`);
123
+ console.log(` • Last indexed: ${dir.lastIndexed || "Never completed"}`);
124
+ if (dir.errors.length > 0) {
125
+ console.log(` • Files with errors: ${dir.errors.length}`);
126
+ if (options.verbose) {
127
+ console.log(" • Recent errors:");
128
+ dir.errors.slice(0, 3).forEach((error) => {
129
+ console.log(` - ${error}`);
130
+ });
131
+ }
132
+ }
133
+ });
134
+ }
135
+ if (status.workspaces.length > 0) {
136
+ console.log("");
137
+ console.log("WORKSPACES:");
138
+ console.log(` • ${status.workspaceHealth.healthy} healthy, ${status.workspaceHealth.warnings} warnings, ${status.workspaceHealth.errors} errors`);
139
+ if (status.workspaceHealth.errors > 0) {
140
+ console.log("");
141
+ console.log("WORKSPACE ERRORS:");
142
+ status.workspaceHealth.criticalIssues.forEach((issue) => {
143
+ console.log(` ❌ ${issue}`);
144
+ });
145
+ }
146
+ if (status.workspaceHealth.recommendations.length > 0) {
147
+ console.log("");
148
+ console.log("WORKSPACE RECOMMENDATIONS:");
149
+ status.workspaceHealth.recommendations.forEach((rec) => {
150
+ console.log(` 💡 ${rec}`);
151
+ });
152
+ }
153
+ if (options.verbose) {
154
+ console.log("");
155
+ console.log("WORKSPACE DETAILS:");
156
+ status.workspaces.forEach((workspace) => {
157
+ console.log("");
158
+ console.log(` Workspace: ${workspace.name}`);
159
+ console.log(` • Status: ${workspace.health.status}`);
160
+ console.log(` • Paths: ${workspace.paths.join(", ")}`);
161
+ console.log(` • Files: ${workspace.filesCount}, Chunks: ${workspace.chunksCount}`);
162
+ if (workspace.health.issues.length > 0) {
163
+ console.log(` • Issues: ${workspace.health.issues.join("; ")}`);
164
+ }
165
+ });
166
+ }
167
+ }
168
+ if (!status.qdrantConsistency.isConsistent) {
169
+ console.log("");
170
+ console.log("SYSTEM STATUS:");
171
+ status.qdrantConsistency.issues.forEach((issue) => {
172
+ console.log(` • ${issue}`);
173
+ });
174
+ console.log("");
175
+ console.log("Note: Status messages above may be normal during setup or active indexing.");
176
+ } else {
177
+ console.log("");
178
+ console.log("SYSTEM STATUS:");
179
+ console.log(" • All systems operational - ready for AI-powered search");
180
+ }
181
+ }
182
+ export {
183
+ handleGet,
184
+ handleIndex,
185
+ handleReset,
186
+ handleSearch,
187
+ handleServe,
188
+ handleSimilar,
189
+ handleStatus
190
+ };
191
+ //# sourceMappingURL=cli-handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-handlers.js","sources":["../src/cli-handlers.ts"],"sourcesContent":["import { indexDirectories } from './indexing.js';\nimport { searchContent, findSimilarFiles, getFileContent } from './search.js';\nimport { loadConfig } from './config.js';\nimport { getIndexStatus } from './storage.js';\nimport { startMcpServer } from './mcp.js';\nimport { validateIndexPrerequisites, validateSearchPrerequisites, getServiceStatus } from './prerequisites.js';\nimport { resetEnvironment } from './reset.js';\n\nexport interface IndexOptions {\n verbose?: boolean;\n}\n\nexport interface SearchOptions {\n limit?: number;\n showChunks?: boolean;\n verbose?: boolean;\n}\n\nexport interface SimilarOptions {\n limit?: number;\n verbose?: boolean;\n}\n\nexport interface GetOptions {\n chunks?: string;\n verbose?: boolean;\n}\n\nexport interface ServeOptions {\n verbose?: boolean;\n}\n\nexport interface ResetOptions {\n force?: boolean;\n verbose?: boolean;\n}\n\nexport interface StatusOptions {\n verbose?: boolean;\n}\n\nexport async function handleIndex(paths: string[], options: IndexOptions): Promise<void> {\n const config = await loadConfig({ verbose: options.verbose });\n await validateIndexPrerequisites(config);\n \n console.log(`Indexing ${paths.length} ${paths.length === 1 ? 'directory' : 'directories'}: ${paths.join(', ')}`);\n if (!options.verbose) {\n console.log('Run with --verbose for detailed per-file indexing reports');\n console.log('Indexing can be safely stopped and resumed - progress is automatically saved');\n console.log('You can start using the MCP server while indexing continues');\n console.log('Indexing may take time due to embedding generation - see project README for performance tips');\n }\n \n const result = await indexDirectories(paths, config);\n console.log(`Indexed ${result.indexed} files, skipped ${result.skipped} files, cleaned up ${result.deleted} deleted files, ${result.failed} failed`);\n \n if (result.errors.length > 0) {\n console.log(`Errors: [`);\n result.errors.forEach(error => {\n console.log(` '${error}'`);\n });\n console.log(`]`);\n }\n}\n\nexport async function handleSearch(query: string, options: SearchOptions): Promise<void> {\n const config = await loadConfig({ verbose: options.verbose });\n await validateSearchPrerequisites(config);\n \n const results = await searchContent(query, { limit: options.limit || 10 });\n \n if (results.length === 0) {\n console.log('No results found');\n return;\n }\n\n console.log(`Found ${results.length} results:\\n`);\n results.forEach((result, index) => {\n console.log(`${index + 1}. ${result.filePath}`);\n console.log(` Score: ${result.score.toFixed(3)} (${result.matchingChunks} chunks)`);\n \n if (options.showChunks && result.chunks.length > 0) {\n console.log(` Chunks:`);\n result.chunks.forEach(chunk => {\n console.log(` - Chunk ${chunk.chunkId}: ${chunk.score.toFixed(3)}`);\n });\n }\n \n console.log();\n });\n}\n\nexport async function handleSimilar(filePath: string, options: SimilarOptions): Promise<void> {\n const config = await loadConfig({ verbose: options.verbose });\n await validateSearchPrerequisites(config);\n \n const results = await findSimilarFiles(filePath, options.limit || 10);\n \n if (results.length === 0) {\n console.log('No similar files found');\n return;\n }\n\n console.log(`Found ${results.length} similar files:\\n`);\n results.forEach((result, index) => {\n console.log(`${index + 1}. ${result.filePath}`);\n console.log(` Similarity: ${result.score.toFixed(3)}`);\n console.log();\n });\n}\n\nexport async function handleGet(filePath: string, options: GetOptions): Promise<void> {\n await loadConfig({ verbose: options.verbose });\n const content = await getFileContent(filePath, options.chunks);\n console.log(content);\n}\n\nexport async function handleServe(options: ServeOptions): Promise<void> {\n const config = await loadConfig({ verbose: options.verbose });\n await startMcpServer(config);\n}\n\nexport async function handleReset(options: ResetOptions): Promise<void> {\n const config = await loadConfig({ verbose: options.verbose });\n await resetEnvironment(config, { \n force: options.force, \n verbose: options.verbose \n });\n}\n\nexport async function handleStatus(options: StatusOptions): Promise<void> {\n const config = await loadConfig({ verbose: options.verbose });\n const [status, serviceStatus] = await Promise.all([\n getIndexStatus(),\n getServiceStatus(config)\n ]);\n \n console.log('Directory Indexer Status Report');\n console.log('=====================================');\n console.log('');\n console.log('SERVICE STATUS:');\n console.log(` • Qdrant database: ${serviceStatus.qdrant ? 'Connected' : 'Disconnected'}`);\n console.log(` • Embedding service (${serviceStatus.embeddingProvider}): ${serviceStatus.embedding ? 'Connected' : 'Disconnected'}`);\n console.log('');\n console.log('OVERVIEW:');\n console.log(` • ${status.directoriesIndexed} directories have been indexed`);\n console.log(` • ${status.filesIndexed} files processed for semantic search`);\n console.log(` • ${status.chunksIndexed} text chunks available for AI search`);\n console.log(` • Database storage: ${status.databaseSize}`);\n console.log(` • Most recent indexing: ${status.lastIndexed || 'No indexing performed yet'}`);\n \n if (status.errors.length > 0) {\n console.log(` • Processing errors encountered: ${status.errors.length}`);\n if (options.verbose) {\n console.log('');\n console.log('RECENT ERRORS:');\n status.errors.slice(0, 5).forEach(error => {\n console.log(` - ${error}`);\n });\n }\n }\n \n console.log('');\n console.log('INDEXED DIRECTORIES:');\n if (status.directories.length === 0) {\n console.log(' No directories have been indexed yet.');\n console.log(' Run \"directory-indexer index <path>\" to start indexing.');\n } else {\n status.directories.forEach(dir => {\n console.log('');\n console.log(` Directory: ${dir.path}`);\n console.log(` • Indexing status: ${dir.status}`);\n console.log(` • Files processed: ${dir.filesCount}`);\n console.log(` • Searchable chunks: ${dir.chunksCount}`);\n console.log(` • Last indexed: ${dir.lastIndexed || 'Never completed'}`);\n if (dir.errors.length > 0) {\n console.log(` • Files with errors: ${dir.errors.length}`);\n if (options.verbose) {\n console.log(' • Recent errors:');\n dir.errors.slice(0, 3).forEach(error => {\n console.log(` - ${error}`);\n });\n }\n }\n });\n }\n \n if (status.workspaces.length > 0) {\n console.log('');\n console.log('WORKSPACES:');\n console.log(` • ${status.workspaceHealth.healthy} healthy, ${status.workspaceHealth.warnings} warnings, ${status.workspaceHealth.errors} errors`);\n \n if (status.workspaceHealth.errors > 0) {\n console.log('');\n console.log('WORKSPACE ERRORS:');\n status.workspaceHealth.criticalIssues.forEach(issue => {\n console.log(` ❌ ${issue}`);\n });\n }\n \n if (status.workspaceHealth.recommendations.length > 0) {\n console.log('');\n console.log('WORKSPACE RECOMMENDATIONS:');\n status.workspaceHealth.recommendations.forEach(rec => {\n console.log(` 💡 ${rec}`);\n });\n }\n \n if (options.verbose) {\n console.log('');\n console.log('WORKSPACE DETAILS:');\n status.workspaces.forEach(workspace => {\n console.log('');\n console.log(` Workspace: ${workspace.name}`);\n console.log(` • Status: ${workspace.health.status}`);\n console.log(` • Paths: ${workspace.paths.join(', ')}`);\n console.log(` • Files: ${workspace.filesCount}, Chunks: ${workspace.chunksCount}`);\n if (workspace.health.issues.length > 0) {\n console.log(` • Issues: ${workspace.health.issues.join('; ')}`);\n }\n });\n }\n }\n\n if (!status.qdrantConsistency.isConsistent) {\n console.log('');\n console.log('SYSTEM STATUS:');\n status.qdrantConsistency.issues.forEach(issue => {\n console.log(` • ${issue}`);\n });\n console.log('');\n console.log('Note: Status messages above may be normal during setup or active indexing.');\n } else {\n console.log('');\n console.log('SYSTEM STATUS:');\n console.log(' • All systems operational - ready for AI-powered search');\n }\n}"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -3,15 +3,9 @@ import { Command } from "commander";
3
3
  import { fileURLToPath } from "url";
4
4
  import { readFileSync } from "fs";
5
5
  import { dirname, join } from "path";
6
- import { indexDirectories } from "./indexing.js";
7
- import { searchContent, findSimilarFiles, getFileContent } from "./search.js";
8
- import { loadConfig } from "./config.js";
9
- import { getIndexStatus } from "./storage.js";
10
- import { startMcpServer } from "./mcp.js";
11
- import { validateIndexPrerequisites, validateSearchPrerequisites, getServiceStatus } from "./prerequisites.js";
12
- import { resetEnvironment } from "./reset.js";
13
- const __dirname = dirname(fileURLToPath(import.meta.url));
14
- const packageJsonPath = join(__dirname, "../package.json");
6
+ import { handleIndex, handleSearch, handleSimilar, handleGet, handleServe, handleReset, handleStatus } from "./cli-handlers.js";
7
+ const __dirname$1 = dirname(fileURLToPath(import.meta.url));
8
+ const packageJsonPath = join(__dirname$1, "../package.json");
15
9
  const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
16
10
  const VERSION = packageJson.version;
17
11
  async function main() {
@@ -19,24 +13,7 @@ async function main() {
19
13
  program.name("directory-indexer").description("AI-powered directory indexing with semantic search").version(VERSION);
20
14
  program.command("index").description("Index directories for semantic search").argument("<paths...>", "Directory paths to index").option("-v, --verbose", "Enable verbose logging").action(async (paths, options) => {
21
15
  try {
22
- const config = await loadConfig({ verbose: options.verbose });
23
- await validateIndexPrerequisites(config);
24
- console.log(`Indexing ${paths.length} ${paths.length === 1 ? "directory" : "directories"}: ${paths.join(", ")}`);
25
- if (!options.verbose) {
26
- console.log("Run with --verbose for detailed per-file indexing reports");
27
- console.log("Indexing can be safely stopped and resumed - progress is automatically saved");
28
- console.log("You can start using the MCP server while indexing continues");
29
- console.log("Indexing may take time due to embedding generation - see project README for performance tips");
30
- }
31
- const result = await indexDirectories(paths, config);
32
- console.log(`Indexed ${result.indexed} files, skipped ${result.skipped} files, cleaned up ${result.deleted} deleted files, ${result.failed} failed`);
33
- if (result.errors.length > 0) {
34
- console.log(`Errors: [`);
35
- result.errors.forEach((error) => {
36
- console.log(` '${error}'`);
37
- });
38
- console.log(`]`);
39
- }
16
+ await handleIndex(paths, options);
40
17
  } catch (error) {
41
18
  console.error("Error indexing directories:", error);
42
19
  process.exit(1);
@@ -44,25 +21,10 @@ async function main() {
44
21
  });
45
22
  program.command("search").description("Search indexed content semantically").argument("<query>", "Search query").option("-l, --limit <number>", "Maximum number of results", "10").option("-c, --show-chunks", "Show individual chunk scores and IDs").option("-v, --verbose", "Enable verbose logging").action(async (query, options) => {
46
23
  try {
47
- const config = await loadConfig({ verbose: options.verbose });
48
- await validateSearchPrerequisites(config);
49
- const results = await searchContent(query, { limit: parseInt(options.limit) });
50
- if (results.length === 0) {
51
- console.log("No results found");
52
- return;
53
- }
54
- console.log(`Found ${results.length} results:
55
- `);
56
- results.forEach((result, index) => {
57
- console.log(`${index + 1}. ${result.filePath}`);
58
- console.log(` Score: ${result.score.toFixed(3)} (${result.matchingChunks} chunks)`);
59
- if (options.showChunks && result.chunks.length > 0) {
60
- console.log(` Chunks:`);
61
- result.chunks.forEach((chunk) => {
62
- console.log(` - Chunk ${chunk.chunkId}: ${chunk.score.toFixed(3)}`);
63
- });
64
- }
65
- console.log();
24
+ await handleSearch(query, {
25
+ limit: parseInt(options.limit),
26
+ showChunks: options.showChunks,
27
+ verbose: options.verbose
66
28
  });
67
29
  } catch (error) {
68
30
  console.error("Error searching content:", error);
@@ -71,19 +33,9 @@ async function main() {
71
33
  });
72
34
  program.command("similar").description("Find files similar to a given file").argument("<file>", "File path to find similar files for").option("-l, --limit <number>", "Maximum number of results", "10").option("-v, --verbose", "Enable verbose logging").action(async (filePath, options) => {
73
35
  try {
74
- const config = await loadConfig({ verbose: options.verbose });
75
- await validateSearchPrerequisites(config);
76
- const results = await findSimilarFiles(filePath, parseInt(options.limit));
77
- if (results.length === 0) {
78
- console.log("No similar files found");
79
- return;
80
- }
81
- console.log(`Found ${results.length} similar files:
82
- `);
83
- results.forEach((result, index) => {
84
- console.log(`${index + 1}. ${result.filePath}`);
85
- console.log(` Similarity: ${result.score.toFixed(3)}`);
86
- console.log();
36
+ await handleSimilar(filePath, {
37
+ limit: parseInt(options.limit),
38
+ verbose: options.verbose
87
39
  });
88
40
  } catch (error) {
89
41
  console.error("Error finding similar files:", error);
@@ -92,9 +44,7 @@ async function main() {
92
44
  });
93
45
  program.command("get").description("Get file content").argument("<file>", "File path to retrieve").option("-c, --chunks <range>", 'Chunk range (e.g., "2-5")').option("-v, --verbose", "Enable verbose logging").action(async (filePath, options) => {
94
46
  try {
95
- await loadConfig({ verbose: options.verbose });
96
- const content = await getFileContent(filePath, options.chunks);
97
- console.log(content);
47
+ await handleGet(filePath, options);
98
48
  } catch (error) {
99
49
  console.error("Error getting file content:", error);
100
50
  process.exit(1);
@@ -102,8 +52,7 @@ async function main() {
102
52
  });
103
53
  program.command("serve").description("Start MCP server").option("-v, --verbose", "Enable verbose logging").action(async (options) => {
104
54
  try {
105
- const config = await loadConfig({ verbose: options.verbose });
106
- await startMcpServer(config);
55
+ await handleServe(options);
107
56
  } catch (error) {
108
57
  console.error("Error starting MCP server:", error);
109
58
  process.exit(1);
@@ -111,11 +60,7 @@ async function main() {
111
60
  });
112
61
  program.command("reset").description("Reset directory-indexer data (database and vector collection)").option("--force", "Skip confirmation prompt").option("-v, --verbose", "Enable verbose logging").action(async (options) => {
113
62
  try {
114
- const config = await loadConfig({ verbose: options.verbose });
115
- await resetEnvironment(config, {
116
- force: options.force,
117
- verbose: options.verbose
118
- });
63
+ await handleReset(options);
119
64
  } catch (error) {
120
65
  if (error instanceof Error && error.message === "Reset cancelled by user") {
121
66
  console.log("\nReset cancelled.");
@@ -127,104 +72,7 @@ async function main() {
127
72
  });
128
73
  program.command("status").description("Show indexing status").option("-v, --verbose", "Enable verbose logging").action(async (options) => {
129
74
  try {
130
- const config = await loadConfig({ verbose: options.verbose });
131
- const [status, serviceStatus] = await Promise.all([
132
- getIndexStatus(),
133
- getServiceStatus(config)
134
- ]);
135
- console.log("Directory Indexer Status Report");
136
- console.log("=====================================");
137
- console.log("");
138
- console.log("SERVICE STATUS:");
139
- console.log(` • Qdrant database: ${serviceStatus.qdrant ? "Connected" : "Disconnected"}`);
140
- console.log(` • Embedding service (${serviceStatus.embeddingProvider}): ${serviceStatus.embedding ? "Connected" : "Disconnected"}`);
141
- console.log("");
142
- console.log("OVERVIEW:");
143
- console.log(` • ${status.directoriesIndexed} directories have been indexed`);
144
- console.log(` • ${status.filesIndexed} files processed for semantic search`);
145
- console.log(` • ${status.chunksIndexed} text chunks available for AI search`);
146
- console.log(` • Database storage: ${status.databaseSize}`);
147
- console.log(` • Most recent indexing: ${status.lastIndexed || "No indexing performed yet"}`);
148
- if (status.errors.length > 0) {
149
- console.log(` • Processing errors encountered: ${status.errors.length}`);
150
- if (options.verbose) {
151
- console.log("");
152
- console.log("RECENT ERRORS:");
153
- status.errors.slice(0, 5).forEach((error) => {
154
- console.log(` - ${error}`);
155
- });
156
- }
157
- }
158
- console.log("");
159
- console.log("INDEXED DIRECTORIES:");
160
- if (status.directories.length === 0) {
161
- console.log(" No directories have been indexed yet.");
162
- console.log(' Run "directory-indexer index <path>" to start indexing.');
163
- } else {
164
- status.directories.forEach((dir) => {
165
- console.log("");
166
- console.log(` Directory: ${dir.path}`);
167
- console.log(` • Indexing status: ${dir.status}`);
168
- console.log(` • Files processed: ${dir.filesCount}`);
169
- console.log(` • Searchable chunks: ${dir.chunksCount}`);
170
- console.log(` • Last indexed: ${dir.lastIndexed || "Never completed"}`);
171
- if (dir.errors.length > 0) {
172
- console.log(` • Files with errors: ${dir.errors.length}`);
173
- if (options.verbose) {
174
- console.log(" • Recent errors:");
175
- dir.errors.slice(0, 3).forEach((error) => {
176
- console.log(` - ${error}`);
177
- });
178
- }
179
- }
180
- });
181
- }
182
- if (status.workspaces.length > 0) {
183
- console.log("");
184
- console.log("WORKSPACES:");
185
- console.log(` • ${status.workspaceHealth.healthy} healthy, ${status.workspaceHealth.warnings} warnings, ${status.workspaceHealth.errors} errors`);
186
- if (status.workspaceHealth.errors > 0) {
187
- console.log("");
188
- console.log("WORKSPACE ERRORS:");
189
- status.workspaceHealth.criticalIssues.forEach((issue) => {
190
- console.log(` ❌ ${issue}`);
191
- });
192
- }
193
- if (status.workspaceHealth.recommendations.length > 0) {
194
- console.log("");
195
- console.log("WORKSPACE RECOMMENDATIONS:");
196
- status.workspaceHealth.recommendations.forEach((rec) => {
197
- console.log(` 💡 ${rec}`);
198
- });
199
- }
200
- if (options.verbose) {
201
- console.log("");
202
- console.log("WORKSPACE DETAILS:");
203
- status.workspaces.forEach((workspace) => {
204
- console.log("");
205
- console.log(` Workspace: ${workspace.name}`);
206
- console.log(` • Status: ${workspace.health.status}`);
207
- console.log(` • Paths: ${workspace.paths.join(", ")}`);
208
- console.log(` • Files: ${workspace.filesCount}, Chunks: ${workspace.chunksCount}`);
209
- if (workspace.health.issues.length > 0) {
210
- console.log(` • Issues: ${workspace.health.issues.join("; ")}`);
211
- }
212
- });
213
- }
214
- }
215
- if (!status.qdrantConsistency.isConsistent) {
216
- console.log("");
217
- console.log("SYSTEM STATUS:");
218
- status.qdrantConsistency.issues.forEach((issue) => {
219
- console.log(` • ${issue}`);
220
- });
221
- console.log("");
222
- console.log("Note: Status messages above may be normal during setup or active indexing.");
223
- } else {
224
- console.log("");
225
- console.log("SYSTEM STATUS:");
226
- console.log(" • All systems operational - ready for AI-powered search");
227
- }
75
+ await handleStatus(options);
228
76
  } catch (error) {
229
77
  console.error("Error getting status:", error);
230
78
  process.exit(1);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { fileURLToPath } from 'url';\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { indexDirectories } from './indexing.js';\nimport { searchContent, findSimilarFiles, getFileContent } from './search.js';\nimport { loadConfig } from './config.js';\nimport { getIndexStatus } from './storage.js';\nimport { startMcpServer } from './mcp.js';\nimport { validateIndexPrerequisites, validateSearchPrerequisites, getServiceStatus } from './prerequisites.js';\nimport { resetEnvironment } from './reset.js';\n\n// Read version from package.json\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst packageJsonPath = join(__dirname, '../package.json');\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\nconst VERSION = packageJson.version;\n\nexport async function main() {\n const program = new Command();\n \n program\n .name('directory-indexer')\n .description('AI-powered directory indexing with semantic search')\n .version(VERSION);\n\n program\n .command('index')\n .description('Index directories for semantic search')\n .argument('<paths...>', 'Directory paths to index')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (paths: string[], options) => {\n try {\n const config = await loadConfig({ verbose: options.verbose });\n await validateIndexPrerequisites(config);\n console.log(`Indexing ${paths.length} ${paths.length === 1 ? 'directory' : 'directories'}: ${paths.join(', ')}`);\n if (!options.verbose) {\n console.log('Run with --verbose for detailed per-file indexing reports');\n console.log('Indexing can be safely stopped and resumed - progress is automatically saved');\n console.log('You can start using the MCP server while indexing continues');\n console.log('Indexing may take time due to embedding generation - see project README for performance tips');\n }\n const result = await indexDirectories(paths, config);\n console.log(`Indexed ${result.indexed} files, skipped ${result.skipped} files, cleaned up ${result.deleted} deleted files, ${result.failed} failed`);\n if (result.errors.length > 0) {\n console.log(`Errors: [`);\n result.errors.forEach(error => {\n console.log(` '${error}'`);\n });\n console.log(`]`);\n }\n } catch (error) {\n console.error('Error indexing directories:', error);\n process.exit(1);\n }\n });\n\n program\n .command('search')\n .description('Search indexed content semantically')\n .argument('<query>', 'Search query')\n .option('-l, --limit <number>', 'Maximum number of results', '10')\n .option('-c, --show-chunks', 'Show individual chunk scores and IDs')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (query: string, options) => {\n try {\n const config = await loadConfig({ verbose: options.verbose });\n await validateSearchPrerequisites(config);\n const results = await searchContent(query, { limit: parseInt(options.limit) });\n \n if (results.length === 0) {\n console.log('No results found');\n return;\n }\n\n console.log(`Found ${results.length} results:\\n`);\n results.forEach((result, index) => {\n console.log(`${index + 1}. ${result.filePath}`);\n console.log(` Score: ${result.score.toFixed(3)} (${result.matchingChunks} chunks)`);\n \n if (options.showChunks && result.chunks.length > 0) {\n console.log(` Chunks:`);\n result.chunks.forEach(chunk => {\n console.log(` - Chunk ${chunk.chunkId}: ${chunk.score.toFixed(3)}`);\n });\n }\n \n console.log();\n });\n } catch (error) {\n console.error('Error searching content:', error);\n process.exit(1);\n }\n });\n\n program\n .command('similar')\n .description('Find files similar to a given file')\n .argument('<file>', 'File path to find similar files for')\n .option('-l, --limit <number>', 'Maximum number of results', '10')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (filePath: string, options) => {\n try {\n const config = await loadConfig({ verbose: options.verbose });\n await validateSearchPrerequisites(config);\n const results = await findSimilarFiles(filePath, parseInt(options.limit));\n \n if (results.length === 0) {\n console.log('No similar files found');\n return;\n }\n\n console.log(`Found ${results.length} similar files:\\n`);\n results.forEach((result, index) => {\n console.log(`${index + 1}. ${result.filePath}`);\n console.log(` Similarity: ${result.score.toFixed(3)}`);\n console.log();\n });\n } catch (error) {\n console.error('Error finding similar files:', error);\n process.exit(1);\n }\n });\n\n program\n .command('get')\n .description('Get file content')\n .argument('<file>', 'File path to retrieve')\n .option('-c, --chunks <range>', 'Chunk range (e.g., \"2-5\")')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (filePath: string, options) => {\n try {\n await loadConfig({ verbose: options.verbose });\n const content = await getFileContent(filePath, options.chunks);\n console.log(content);\n } catch (error) {\n console.error('Error getting file content:', error);\n process.exit(1);\n }\n });\n\n program\n .command('serve')\n .description('Start MCP server')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (options) => {\n try {\n const config = await loadConfig({ verbose: options.verbose });\n await startMcpServer(config);\n } catch (error) {\n console.error('Error starting MCP server:', error);\n process.exit(1);\n }\n });\n\n program\n .command('reset')\n .description('Reset directory-indexer data (database and vector collection)')\n .option('--force', 'Skip confirmation prompt')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (options) => {\n try {\n const config = await loadConfig({ verbose: options.verbose });\n await resetEnvironment(config, { \n force: options.force, \n verbose: options.verbose \n });\n } catch (error) {\n if (error instanceof Error && error.message === 'Reset cancelled by user') {\n console.log('\\nReset cancelled.');\n process.exit(0);\n }\n console.error('Error during reset:', error);\n process.exit(1);\n }\n });\n\n program\n .command('status')\n .description('Show indexing status')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (options) => {\n try {\n const config = await loadConfig({ verbose: options.verbose });\n const [status, serviceStatus] = await Promise.all([\n getIndexStatus(),\n getServiceStatus(config)\n ]);\n \n console.log('Directory Indexer Status Report');\n console.log('=====================================');\n console.log('');\n console.log('SERVICE STATUS:');\n console.log(` • Qdrant database: ${serviceStatus.qdrant ? 'Connected' : 'Disconnected'}`);\n console.log(` • Embedding service (${serviceStatus.embeddingProvider}): ${serviceStatus.embedding ? 'Connected' : 'Disconnected'}`);\n console.log('');\n console.log('OVERVIEW:');\n console.log(` • ${status.directoriesIndexed} directories have been indexed`);\n console.log(` • ${status.filesIndexed} files processed for semantic search`);\n console.log(` • ${status.chunksIndexed} text chunks available for AI search`);\n console.log(` • Database storage: ${status.databaseSize}`);\n console.log(` • Most recent indexing: ${status.lastIndexed || 'No indexing performed yet'}`);\n \n if (status.errors.length > 0) {\n console.log(` • Processing errors encountered: ${status.errors.length}`);\n if (options.verbose) {\n console.log('');\n console.log('RECENT ERRORS:');\n status.errors.slice(0, 5).forEach(error => {\n console.log(` - ${error}`);\n });\n }\n }\n \n console.log('');\n console.log('INDEXED DIRECTORIES:');\n if (status.directories.length === 0) {\n console.log(' No directories have been indexed yet.');\n console.log(' Run \"directory-indexer index <path>\" to start indexing.');\n } else {\n status.directories.forEach(dir => {\n console.log('');\n console.log(` Directory: ${dir.path}`);\n console.log(` • Indexing status: ${dir.status}`);\n console.log(` • Files processed: ${dir.filesCount}`);\n console.log(` • Searchable chunks: ${dir.chunksCount}`);\n console.log(` • Last indexed: ${dir.lastIndexed || 'Never completed'}`);\n if (dir.errors.length > 0) {\n console.log(` • Files with errors: ${dir.errors.length}`);\n if (options.verbose) {\n console.log(' • Recent errors:');\n dir.errors.slice(0, 3).forEach(error => {\n console.log(` - ${error}`);\n });\n }\n }\n });\n }\n \n // Show workspace health information\n if (status.workspaces.length > 0) {\n console.log('');\n console.log('WORKSPACES:');\n console.log(` • ${status.workspaceHealth.healthy} healthy, ${status.workspaceHealth.warnings} warnings, ${status.workspaceHealth.errors} errors`);\n \n if (status.workspaceHealth.errors > 0) {\n console.log('');\n console.log('WORKSPACE ERRORS:');\n status.workspaceHealth.criticalIssues.forEach(issue => {\n console.log(` ❌ ${issue}`);\n });\n }\n \n if (status.workspaceHealth.recommendations.length > 0) {\n console.log('');\n console.log('WORKSPACE RECOMMENDATIONS:');\n status.workspaceHealth.recommendations.forEach(rec => {\n console.log(` 💡 ${rec}`);\n });\n }\n \n if (options.verbose) {\n console.log('');\n console.log('WORKSPACE DETAILS:');\n status.workspaces.forEach(workspace => {\n console.log('');\n console.log(` Workspace: ${workspace.name}`);\n console.log(` • Status: ${workspace.health.status}`);\n console.log(` • Paths: ${workspace.paths.join(', ')}`);\n console.log(` • Files: ${workspace.filesCount}, Chunks: ${workspace.chunksCount}`);\n if (workspace.health.issues.length > 0) {\n console.log(` • Issues: ${workspace.health.issues.join('; ')}`);\n }\n });\n }\n }\n\n if (!status.qdrantConsistency.isConsistent) {\n console.log('');\n console.log('SYSTEM STATUS:');\n status.qdrantConsistency.issues.forEach(issue => {\n console.log(` • ${issue}`);\n });\n console.log('');\n console.log('Note: Status messages above may be normal during setup or active indexing.');\n } else {\n console.log('');\n console.log('SYSTEM STATUS:');\n console.log(' • All systems operational - ready for AI-powered search');\n }\n } catch (error) {\n console.error('Error getting status:', error);\n process.exit(1);\n }\n });\n\n await program.parseAsync();\n}\n\n// Main function is already exported above"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { fileURLToPath } from 'url';\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { \n handleIndex, \n handleSearch, \n handleSimilar, \n handleGet, \n handleServe, \n handleReset, \n handleStatus \n} from './cli-handlers.js';\n\n// Read version from package.json\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst packageJsonPath = join(__dirname, '../package.json');\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\nconst VERSION = packageJson.version;\n\nexport async function main() {\n const program = new Command();\n \n program\n .name('directory-indexer')\n .description('AI-powered directory indexing with semantic search')\n .version(VERSION);\n\n program\n .command('index')\n .description('Index directories for semantic search')\n .argument('<paths...>', 'Directory paths to index')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (paths: string[], options) => {\n try {\n await handleIndex(paths, options);\n } catch (error) {\n console.error('Error indexing directories:', error);\n process.exit(1);\n }\n });\n\n program\n .command('search')\n .description('Search indexed content semantically')\n .argument('<query>', 'Search query')\n .option('-l, --limit <number>', 'Maximum number of results', '10')\n .option('-c, --show-chunks', 'Show individual chunk scores and IDs')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (query: string, options) => {\n try {\n await handleSearch(query, {\n limit: parseInt(options.limit),\n showChunks: options.showChunks,\n verbose: options.verbose\n });\n } catch (error) {\n console.error('Error searching content:', error);\n process.exit(1);\n }\n });\n\n program\n .command('similar')\n .description('Find files similar to a given file')\n .argument('<file>', 'File path to find similar files for')\n .option('-l, --limit <number>', 'Maximum number of results', '10')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (filePath: string, options) => {\n try {\n await handleSimilar(filePath, {\n limit: parseInt(options.limit),\n verbose: options.verbose\n });\n } catch (error) {\n console.error('Error finding similar files:', error);\n process.exit(1);\n }\n });\n\n program\n .command('get')\n .description('Get file content')\n .argument('<file>', 'File path to retrieve')\n .option('-c, --chunks <range>', 'Chunk range (e.g., \"2-5\")')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (filePath: string, options) => {\n try {\n await handleGet(filePath, options);\n } catch (error) {\n console.error('Error getting file content:', error);\n process.exit(1);\n }\n });\n\n program\n .command('serve')\n .description('Start MCP server')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (options) => {\n try {\n await handleServe(options);\n } catch (error) {\n console.error('Error starting MCP server:', error);\n process.exit(1);\n }\n });\n\n program\n .command('reset')\n .description('Reset directory-indexer data (database and vector collection)')\n .option('--force', 'Skip confirmation prompt')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (options) => {\n try {\n await handleReset(options);\n } catch (error) {\n if (error instanceof Error && error.message === 'Reset cancelled by user') {\n console.log('\\nReset cancelled.');\n process.exit(0);\n }\n console.error('Error during reset:', error);\n process.exit(1);\n }\n });\n\n program\n .command('status')\n .description('Show indexing status')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (options) => {\n try {\n await handleStatus(options);\n } catch (error) {\n console.error('Error getting status:', error);\n process.exit(1);\n }\n });\n\n await program.parseAsync();\n}\n\n// Main function is already exported above"],"names":["__dirname"],"mappings":"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"}
package/dist/indexing.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { promises } from "fs";
2
2
  import { join } from "path";
3
- import { normalizePath, getFileInfo, shouldIgnoreFile, isDirectory, isFile, isSupportedFileType } from "./utils.js";
3
+ import { getFileInfo, normalizePath, shouldIgnoreFile, isDirectory, isFile, isSupportedFileType } from "./utils.js";
4
4
  import { loadGitignoreRules } from "./gitignore.js";
5
5
  import { generateEmbedding } from "./embedding.js";
6
6
  import { initializeStorage } from "./storage.js";
7
+ import { log } from "./logger.js";
7
8
  class IndexingError extends Error {
8
9
  constructor(message, cause) {
9
10
  super(message);
@@ -142,6 +143,7 @@ async function indexDirectories(paths, config) {
142
143
  }
143
144
  }
144
145
  if (!config.verbose && totalFiles > 0) {
146
+ console.log("");
145
147
  console.log(`Found ${totalFiles} files to process (checking for changes...)`);
146
148
  }
147
149
  for (const path of paths) {
@@ -151,7 +153,7 @@ async function indexDirectories(paths, config) {
151
153
  const files = await scanDirectory(path, scanOptions);
152
154
  const dirStartIndexed = indexed;
153
155
  const dirStartSkipped = skipped;
154
- const progressInterval = Math.max(10, Math.floor(totalFiles / 20));
156
+ const progressInterval = totalFiles > 1e3 ? 50 : 10;
155
157
  for (const file of files) {
156
158
  try {
157
159
  const existingFile = await sqlite.getFile(file.path);
@@ -163,13 +165,20 @@ async function indexDirectories(paths, config) {
163
165
  console.log(` Skipped: ${file.path} (unchanged)`);
164
166
  }
165
167
  if (!config.verbose && (indexed + skipped) % progressInterval === 0) {
166
- console.log(` Progress: ${indexed + skipped}/${totalFiles} files (${skipped} skipped as unchanged)...`);
168
+ console.log(`Progress: ${indexed + skipped}/${totalFiles} files (${skipped} skipped as unchanged)...`);
167
169
  }
168
170
  continue;
169
171
  }
170
172
  await qdrant.deletePointsByFilePath(file.path);
171
173
  }
172
- const content = await promises.readFile(file.path, "utf-8");
174
+ const rawContent = await promises.readFile(file.path, "utf-8");
175
+ if (rawContent.includes("�")) {
176
+ log("warning", "Skipping non-UTF-8 file", { path: file.path });
177
+ await sqlite.upsertFile(file, [], ["Skipped: file appears to be non-UTF-8 encoded"]);
178
+ skipped++;
179
+ continue;
180
+ }
181
+ const content = rawContent.replace(/\r\n/g, "\n");
173
182
  const chunks = chunkText(content, config.indexing.chunkSize, config.indexing.chunkOverlap);
174
183
  await sqlite.upsertFile(file, chunks);
175
184
  for (let i = 0; i < chunks.length; i++) {
@@ -195,7 +204,7 @@ async function indexDirectories(paths, config) {
195
204
  console.log(` Indexed: ${file.path} (${chunks.length} chunks)`);
196
205
  }
197
206
  if (!config.verbose && (indexed + skipped) % progressInterval === 0) {
198
- console.log(` Progress: ${indexed + skipped}/${totalFiles} files (${skipped} skipped as unchanged)...`);
207
+ console.log(`Progress: ${indexed + skipped}/${totalFiles} files (${skipped} skipped as unchanged)...`);
199
208
  }
200
209
  } catch (error) {
201
210
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -232,9 +241,9 @@ async function indexDirectories(paths, config) {
232
241
  const dirIndexed = indexed - dirStartIndexed;
233
242
  const dirSkipped = skipped - dirStartSkipped;
234
243
  if (config.verbose) {
235
- console.log(` Directory ${path} completed: ${dirIndexed} indexed, ${dirSkipped} skipped`);
244
+ console.log(`Directory ${path} completed: ${dirIndexed} indexed, ${dirSkipped} skipped`);
236
245
  } else {
237
- console.log(` Directory ${path} completed: ${dirFiles} files processed`);
246
+ console.log(`Directory ${path} completed: ${dirFiles} files processed`);
238
247
  }
239
248
  } catch (error) {
240
249
  const normalizedPath = normalizePath(path);