pindex 1.0.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 (139) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +767 -0
  3. package/dist/cli/daemon.d.ts +13 -0
  4. package/dist/cli/daemon.d.ts.map +1 -0
  5. package/dist/cli/daemon.js +70 -0
  6. package/dist/cli/daemon.js.map +1 -0
  7. package/dist/cli/index.d.ts +4 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +212 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/init.d.ts +44 -0
  12. package/dist/cli/init.d.ts.map +1 -0
  13. package/dist/cli/init.js +301 -0
  14. package/dist/cli/init.js.map +1 -0
  15. package/dist/cli/project-detector.d.ts +44 -0
  16. package/dist/cli/project-detector.d.ts.map +1 -0
  17. package/dist/cli/project-detector.js +144 -0
  18. package/dist/cli/project-detector.js.map +1 -0
  19. package/dist/cli/setup.d.ts +9 -0
  20. package/dist/cli/setup.d.ts.map +1 -0
  21. package/dist/cli/setup.js +110 -0
  22. package/dist/cli/setup.js.map +1 -0
  23. package/dist/db/database.d.ts +5 -0
  24. package/dist/db/database.d.ts.map +1 -0
  25. package/dist/db/database.js +19 -0
  26. package/dist/db/database.js.map +1 -0
  27. package/dist/db/migrations.d.ts +6 -0
  28. package/dist/db/migrations.d.ts.map +1 -0
  29. package/dist/db/migrations.js +32 -0
  30. package/dist/db/migrations.js.map +1 -0
  31. package/dist/db/queries.d.ts +132 -0
  32. package/dist/db/queries.d.ts.map +1 -0
  33. package/dist/db/queries.js +222 -0
  34. package/dist/db/queries.js.map +1 -0
  35. package/dist/db/schema.d.ts +5 -0
  36. package/dist/db/schema.d.ts.map +1 -0
  37. package/dist/db/schema.js +179 -0
  38. package/dist/db/schema.js.map +1 -0
  39. package/dist/gui/index.d.ts +3 -0
  40. package/dist/gui/index.d.ts.map +1 -0
  41. package/dist/gui/index.js +56 -0
  42. package/dist/gui/index.js.map +1 -0
  43. package/dist/gui/server.d.ts +31 -0
  44. package/dist/gui/server.d.ts.map +1 -0
  45. package/dist/gui/server.js +729 -0
  46. package/dist/gui/server.js.map +1 -0
  47. package/dist/index.d.ts +3 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +93 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/indexer/index.d.ts +38 -0
  52. package/dist/indexer/index.d.ts.map +1 -0
  53. package/dist/indexer/index.js +283 -0
  54. package/dist/indexer/index.js.map +1 -0
  55. package/dist/indexer/parser.d.ts +20 -0
  56. package/dist/indexer/parser.d.ts.map +1 -0
  57. package/dist/indexer/parser.js +431 -0
  58. package/dist/indexer/parser.js.map +1 -0
  59. package/dist/indexer/summarizer.d.ts +15 -0
  60. package/dist/indexer/summarizer.d.ts.map +1 -0
  61. package/dist/indexer/summarizer.js +24 -0
  62. package/dist/indexer/summarizer.js.map +1 -0
  63. package/dist/indexer/watcher.d.ts +25 -0
  64. package/dist/indexer/watcher.d.ts.map +1 -0
  65. package/dist/indexer/watcher.js +54 -0
  66. package/dist/indexer/watcher.js.map +1 -0
  67. package/dist/monitoring/estimator.d.ts +20 -0
  68. package/dist/monitoring/estimator.d.ts.map +1 -0
  69. package/dist/monitoring/estimator.js +94 -0
  70. package/dist/monitoring/estimator.js.map +1 -0
  71. package/dist/monitoring/server.d.ts +20 -0
  72. package/dist/monitoring/server.d.ts.map +1 -0
  73. package/dist/monitoring/server.js +86 -0
  74. package/dist/monitoring/server.js.map +1 -0
  75. package/dist/monitoring/token-logger.d.ts +26 -0
  76. package/dist/monitoring/token-logger.d.ts.map +1 -0
  77. package/dist/monitoring/token-logger.js +47 -0
  78. package/dist/monitoring/token-logger.js.map +1 -0
  79. package/dist/server.d.ts +18 -0
  80. package/dist/server.d.ts.map +1 -0
  81. package/dist/server.js +310 -0
  82. package/dist/server.js.map +1 -0
  83. package/dist/tools/find_usages.d.ts +4 -0
  84. package/dist/tools/find_usages.d.ts.map +1 -0
  85. package/dist/tools/find_usages.js +13 -0
  86. package/dist/tools/find_usages.js.map +1 -0
  87. package/dist/tools/get_context.d.ts +6 -0
  88. package/dist/tools/get_context.d.ts.map +1 -0
  89. package/dist/tools/get_context.js +36 -0
  90. package/dist/tools/get_context.js.map +1 -0
  91. package/dist/tools/get_dependencies.d.ts +4 -0
  92. package/dist/tools/get_dependencies.d.ts.map +1 -0
  93. package/dist/tools/get_dependencies.js +16 -0
  94. package/dist/tools/get_dependencies.js.map +1 -0
  95. package/dist/tools/get_doc_chunk.d.ts +4 -0
  96. package/dist/tools/get_doc_chunk.d.ts.map +1 -0
  97. package/dist/tools/get_doc_chunk.js +32 -0
  98. package/dist/tools/get_doc_chunk.js.map +1 -0
  99. package/dist/tools/get_file_summary.d.ts +4 -0
  100. package/dist/tools/get_file_summary.d.ts.map +1 -0
  101. package/dist/tools/get_file_summary.js +23 -0
  102. package/dist/tools/get_file_summary.js.map +1 -0
  103. package/dist/tools/get_project_overview.d.ts +5 -0
  104. package/dist/tools/get_project_overview.d.ts.map +1 -0
  105. package/dist/tools/get_project_overview.js +60 -0
  106. package/dist/tools/get_project_overview.js.map +1 -0
  107. package/dist/tools/get_symbol.d.ts +4 -0
  108. package/dist/tools/get_symbol.d.ts.map +1 -0
  109. package/dist/tools/get_symbol.js +21 -0
  110. package/dist/tools/get_symbol.js.map +1 -0
  111. package/dist/tools/get_token_stats.d.ts +4 -0
  112. package/dist/tools/get_token_stats.d.ts.map +1 -0
  113. package/dist/tools/get_token_stats.js +6 -0
  114. package/dist/tools/get_token_stats.js.map +1 -0
  115. package/dist/tools/reindex.d.ts +5 -0
  116. package/dist/tools/reindex.d.ts.map +1 -0
  117. package/dist/tools/reindex.js +21 -0
  118. package/dist/tools/reindex.js.map +1 -0
  119. package/dist/tools/save_context.d.ts +4 -0
  120. package/dist/tools/save_context.d.ts.map +1 -0
  121. package/dist/tools/save_context.js +17 -0
  122. package/dist/tools/save_context.js.map +1 -0
  123. package/dist/tools/search_docs.d.ts +4 -0
  124. package/dist/tools/search_docs.d.ts.map +1 -0
  125. package/dist/tools/search_docs.js +42 -0
  126. package/dist/tools/search_docs.js.map +1 -0
  127. package/dist/tools/search_symbols.d.ts +5 -0
  128. package/dist/tools/search_symbols.d.ts.map +1 -0
  129. package/dist/tools/search_symbols.js +36 -0
  130. package/dist/tools/search_symbols.js.map +1 -0
  131. package/dist/tools/start_comparison.d.ts +4 -0
  132. package/dist/tools/start_comparison.d.ts.map +1 -0
  133. package/dist/tools/start_comparison.js +15 -0
  134. package/dist/tools/start_comparison.js.map +1 -0
  135. package/dist/types.d.ts +318 -0
  136. package/dist/types.d.ts.map +1 -0
  137. package/dist/types.js +3 -0
  138. package/dist/types.js.map +1 -0
  139. package/package.json +69 -0
@@ -0,0 +1,301 @@
1
+ import { writeFileSync, existsSync, mkdirSync, readFileSync, appendFileSync, unlinkSync } from 'node:fs';
2
+ import { resolve, join } from 'node:path';
3
+ import { findProjectRoot, getProjectIndexPath, GlobalRegistry, getPindexHome, } from './project-detector.js';
4
+ // ─── .mcp.json generation ─────────────────────────────────────────────────
5
+ export function writeMcpJson(projectRoot, entry) {
6
+ const federationEnv = entry.federatedRepos.length > 0
7
+ ? { FEDERATION_REPOS: entry.federatedRepos.join(':') }
8
+ : {};
9
+ const config = {
10
+ mcpServers: {
11
+ pindex: {
12
+ command: 'pindex-server',
13
+ args: [],
14
+ env: {
15
+ PROJECT_ROOT: entry.path,
16
+ INDEX_PATH: getProjectIndexPath(entry.path),
17
+ MONITORING_PORT: String(entry.monitoringPort),
18
+ AUTO_REINDEX: 'true',
19
+ GENERATE_SUMMARIES: 'false',
20
+ MONITORING_AUTO_OPEN: 'false',
21
+ BASELINE_MODE: 'false',
22
+ TOKEN_PRICE_PER_MILLION: '3.00',
23
+ ...federationEnv,
24
+ },
25
+ },
26
+ },
27
+ };
28
+ const mcpJsonPath = join(projectRoot, '.mcp.json');
29
+ writeFileSync(mcpJsonPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
30
+ }
31
+ // ─── CLAUDE.md injection ───────────────────────────────────────────────────
32
+ const CLAUDE_MD_MARKER = '<!-- pindex -->';
33
+ const CLAUDE_MD_SECTION = `
34
+ ## PindeX – Codebase Navigation
35
+
36
+ Dieses Projekt ist mit PindeX indexiert.
37
+
38
+ **PFLICHT-WORKFLOW** – bei jeder Codebase-Aufgabe:
39
+ 1. **Unbekannte Datei?** → \`mcp__pindex__get_file_summary\` ZUERST, dann ggf. \`get_context\`
40
+ 2. **Symbol suchen?** → \`mcp__pindex__search_symbols\` oder \`find_symbol\`
41
+ 3. **Abhängigkeiten?** → \`mcp__pindex__get_dependencies\`
42
+ 4. **Wo wird etwas verwendet?** → \`mcp__pindex__find_usages\`
43
+ 5. **Projekt-Überblick?** → \`mcp__pindex__get_project_overview\`
44
+
45
+ **VERBOTEN** (solange PindeX verfügbar):
46
+ - \`Read\` auf Quellcode-Dateien ohne vorherigen \`get_file_summary\`-Aufruf
47
+ - \`Glob\`/\`Grep\` zur Symbol-Suche statt \`search_symbols\`
48
+
49
+ **Kontext auslagern:**
50
+ - Wichtige Entscheidungen / Muster → \`mcp__pindex__save_context\` speichern
51
+ - Zu Sessionbeginn → \`mcp__pindex__search_docs\` für gespeicherten Kontext
52
+
53
+ **Fallback:** Falls ein Tool \`null\` zurückgibt → \`Read\`/\`Grep\` als Fallback.
54
+ ${CLAUDE_MD_MARKER}
55
+ `;
56
+ /**
57
+ * Appends the PindeX section to the project's CLAUDE.md (or creates the file).
58
+ * Idempotent: skips if the marker is already present, unless force=true.
59
+ * With force=true the existing section is replaced (useful after PindeX updates).
60
+ */
61
+ export function injectClaudeMdSection(projectRoot, { force = false } = {}) {
62
+ const claudeMdPath = join(projectRoot, 'CLAUDE.md');
63
+ if (existsSync(claudeMdPath)) {
64
+ const existing = readFileSync(claudeMdPath, 'utf-8');
65
+ if (existing.includes(CLAUDE_MD_MARKER)) {
66
+ if (!force)
67
+ return 'skipped';
68
+ // Strip the old section and re-inject with current template
69
+ const stripped = existing.replace(/\n## PindeX[\s\S]*?<!--\s*pindex\s*-->\n?/, '');
70
+ writeFileSync(claudeMdPath, stripped.trimEnd() + CLAUDE_MD_SECTION, 'utf-8');
71
+ return 'updated';
72
+ }
73
+ appendFileSync(claudeMdPath, CLAUDE_MD_SECTION, 'utf-8');
74
+ return 'added';
75
+ }
76
+ else {
77
+ writeFileSync(claudeMdPath, `# CLAUDE.md\n${CLAUDE_MD_SECTION}`, 'utf-8');
78
+ return 'created';
79
+ }
80
+ }
81
+ // ─── .claude/settings.json Hook injection ─────────────────────────────────
82
+ const HOOK_MARKER = 'pindex-hook';
83
+ const PINDEX_HOOKS = {
84
+ hooks: {
85
+ PreToolUse: [
86
+ {
87
+ matcher: 'Read|Glob|Grep',
88
+ hooks: [
89
+ {
90
+ type: 'command',
91
+ // Remind Claude to prefer PindeX tools for source-code exploration
92
+ command: `node -e "const f=process.env.CLAUDE_TOOL_INPUT_FILE_PATH||''; const src=/\\.(ts|tsx|js|jsx|py|java|go|rs|cs|cpp|c|rb|swift|kt)$/i.test(f); if(src) process.stdout.write('[PindeX] Bevorzuge get_file_summary / get_context / search_symbols statt direktem Read. Nur als Fallback Read nutzen.\\n')"`,
93
+ },
94
+ ],
95
+ },
96
+ ],
97
+ },
98
+ };
99
+ /**
100
+ * Writes/merges the PindeX PreToolUse hook into .claude/settings.json.
101
+ * Idempotent: skips if the hook marker is already present.
102
+ */
103
+ export function injectClaudeSettings(projectRoot, { force = false } = {}) {
104
+ const claudeDir = join(projectRoot, '.claude');
105
+ const settingsPath = join(claudeDir, 'settings.json');
106
+ if (!existsSync(claudeDir))
107
+ mkdirSync(claudeDir, { recursive: true });
108
+ if (existsSync(settingsPath)) {
109
+ const raw = readFileSync(settingsPath, 'utf-8');
110
+ if (raw.includes(HOOK_MARKER) && !force)
111
+ return 'skipped';
112
+ let existing;
113
+ try {
114
+ existing = JSON.parse(raw);
115
+ }
116
+ catch {
117
+ existing = {};
118
+ }
119
+ // Deep-merge hooks
120
+ const merged = {
121
+ ...existing,
122
+ hooks: {
123
+ ...existing.hooks,
124
+ PreToolUse: [
125
+ // Remove old pindex hook entries, then re-add
126
+ ...(existing.hooks?.PreToolUse ?? [])
127
+ .filter((h) => !JSON.stringify(h).includes(HOOK_MARKER)),
128
+ { ...PINDEX_HOOKS.hooks.PreToolUse[0], _pindex: HOOK_MARKER },
129
+ ],
130
+ },
131
+ };
132
+ writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
133
+ return 'added';
134
+ }
135
+ else {
136
+ const config = {
137
+ hooks: {
138
+ PreToolUse: [{ ...PINDEX_HOOKS.hooks.PreToolUse[0], _pindex: HOOK_MARKER }],
139
+ },
140
+ };
141
+ writeFileSync(settingsPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
142
+ return 'created';
143
+ }
144
+ }
145
+ // ─── Init project ──────────────────────────────────────────────────────────
146
+ /**
147
+ * Run `pindex` with no arguments in a project directory.
148
+ * Detects project root, registers in global registry, writes .mcp.json.
149
+ */
150
+ export async function initProject(cwd) {
151
+ const projectRoot = findProjectRoot(cwd);
152
+ const registry = new GlobalRegistry();
153
+ const entry = registry.upsert(projectRoot);
154
+ // Ensure the project's DB directory exists
155
+ const dbDir = join(getPindexHome(), 'projects', entry.hash);
156
+ if (!existsSync(dbDir))
157
+ mkdirSync(dbDir, { recursive: true });
158
+ writeMcpJson(projectRoot, entry);
159
+ const claudeResult = injectClaudeMdSection(projectRoot);
160
+ const hooksResult = injectClaudeSettings(projectRoot);
161
+ const relPath = '.mcp.json';
162
+ const claudeStatus = claudeResult === 'created' ? 'created' :
163
+ claudeResult === 'added' ? 'section added' :
164
+ claudeResult === 'updated' ? 'section updated' :
165
+ 'already present';
166
+ const hooksStatus = hooksResult === 'created' ? 'created' :
167
+ hooksResult === 'added' ? 'hook added' :
168
+ 'already present';
169
+ console.log('\n ╔══════════════════════════════════════════╗');
170
+ console.log(' ║ PindeX – Ready ║');
171
+ console.log(' ╚══════════════════════════════════════════╝\n');
172
+ console.log(` Project : ${projectRoot}`);
173
+ console.log(` Index : ~/.pindex/projects/${entry.hash}/index.db`);
174
+ console.log(` Port : ${entry.monitoringPort}`);
175
+ console.log(` Config : ${relPath} (written)`);
176
+ console.log(` CLAUDE.md : ${claudeStatus}`);
177
+ console.log(` Hooks : ${hooksStatus}\n`);
178
+ console.log(' ── Next steps ─────────────────────────────');
179
+ console.log(' 1. Restart Claude Code in this directory');
180
+ console.log(' Claude Code will pick up .mcp.json automatically.');
181
+ console.log(' 2. Open the dashboard: pindex-gui');
182
+ if (entry.federatedRepos.length > 0) {
183
+ console.log(`\n Federated repos (${entry.federatedRepos.length}):`);
184
+ for (const r of entry.federatedRepos)
185
+ console.log(` - ${r}`);
186
+ }
187
+ console.log('\n ══════════════════════════════════════════\n');
188
+ }
189
+ // ─── Cleanup helpers ───────────────────────────────────────────────────────
190
+ /**
191
+ * Removes the PindeX section from CLAUDE.md (if present).
192
+ * Returns 'removed' | 'not_found' | 'skipped' (file didn't exist).
193
+ */
194
+ export function removeClaudeMdSection(projectRoot) {
195
+ const claudeMdPath = join(projectRoot, 'CLAUDE.md');
196
+ if (!existsSync(claudeMdPath))
197
+ return 'skipped';
198
+ const content = readFileSync(claudeMdPath, 'utf-8');
199
+ if (!content.includes(CLAUDE_MD_MARKER))
200
+ return 'not_found';
201
+ const stripped = content.replace(/\n## PindeX[\s\S]*?<!--\s*pindex\s*-->\n?/, '');
202
+ writeFileSync(claudeMdPath, stripped, 'utf-8');
203
+ return 'removed';
204
+ }
205
+ /**
206
+ * Removes the PindeX PreToolUse hook from .claude/settings.json (if present).
207
+ * Returns 'removed' | 'not_found' | 'skipped' (file didn't exist).
208
+ */
209
+ export function removeClaudeSettings(projectRoot) {
210
+ const settingsPath = join(projectRoot, '.claude', 'settings.json');
211
+ if (!existsSync(settingsPath))
212
+ return 'skipped';
213
+ const raw = readFileSync(settingsPath, 'utf-8');
214
+ if (!raw.includes(HOOK_MARKER))
215
+ return 'not_found';
216
+ let existing;
217
+ try {
218
+ existing = JSON.parse(raw);
219
+ }
220
+ catch {
221
+ return 'not_found';
222
+ }
223
+ const hooks = existing.hooks;
224
+ const filtered = (hooks?.PreToolUse ?? []).filter((h) => !JSON.stringify(h).includes(HOOK_MARKER));
225
+ const updated = {
226
+ ...existing,
227
+ hooks: { ...hooks, PreToolUse: filtered },
228
+ };
229
+ // Remove empty PreToolUse array to keep settings.json clean
230
+ if (filtered.length === 0)
231
+ delete updated.hooks.PreToolUse;
232
+ if (Object.keys(updated.hooks).length === 0)
233
+ delete updated.hooks;
234
+ writeFileSync(settingsPath, JSON.stringify(updated, null, 2) + '\n', 'utf-8');
235
+ return 'removed';
236
+ }
237
+ /**
238
+ * Removes .mcp.json from the project root (if present).
239
+ * Returns 'removed' | 'skipped'.
240
+ */
241
+ export function removeMcpJson(projectRoot) {
242
+ const mcpJsonPath = join(projectRoot, '.mcp.json');
243
+ if (!existsSync(mcpJsonPath))
244
+ return 'skipped';
245
+ unlinkSync(mcpJsonPath);
246
+ return 'removed';
247
+ }
248
+ // ─── Add federated repo ────────────────────────────────────────────────────
249
+ /**
250
+ * Link another repository to the current project for cross-repo search.
251
+ * Updates .mcp.json with FEDERATION_REPOS.
252
+ */
253
+ export async function addFederatedRepo(cwd, repoPath) {
254
+ const projectRoot = findProjectRoot(cwd);
255
+ const resolvedRepo = resolve(repoPath);
256
+ if (!existsSync(resolvedRepo)) {
257
+ console.error(`Error: path does not exist: ${resolvedRepo}`);
258
+ process.exit(1);
259
+ }
260
+ if (resolvedRepo === projectRoot) {
261
+ console.error('Error: cannot add the current project as a federated repo.');
262
+ process.exit(1);
263
+ }
264
+ const registry = new GlobalRegistry();
265
+ // Register the federated repo itself (so pindex-gui knows about it too)
266
+ registry.upsert(resolvedRepo);
267
+ // Update current project's federated repos list
268
+ const currentEntry = registry.upsert(projectRoot);
269
+ const existing = currentEntry.federatedRepos;
270
+ if (existing.includes(resolvedRepo)) {
271
+ console.log(`Already linked: ${resolvedRepo}`);
272
+ return;
273
+ }
274
+ const updated = [...existing, resolvedRepo];
275
+ registry.setFederatedRepos(projectRoot, updated);
276
+ // Re-read to get the updated entry
277
+ const updatedEntry = registry.getByPath(projectRoot);
278
+ writeMcpJson(projectRoot, updatedEntry);
279
+ const repoName = resolvedRepo.split('/').pop() ?? resolvedRepo;
280
+ console.log(`\n ✓ Linked: ${repoName} (${resolvedRepo})`);
281
+ console.log(' .mcp.json updated with FEDERATION_REPOS.\n');
282
+ console.log(' Restart Claude Code to activate cross-repo search.\n');
283
+ }
284
+ // ─── Remove federated repo ─────────────────────────────────────────────────
285
+ export async function removeFederatedRepo(cwd, repoPath) {
286
+ const projectRoot = findProjectRoot(cwd);
287
+ const resolvedRepo = resolve(repoPath);
288
+ const registry = new GlobalRegistry();
289
+ const entry = registry.getByPath(projectRoot);
290
+ if (!entry) {
291
+ console.error('Project not registered. Run pindex first.');
292
+ process.exit(1);
293
+ }
294
+ const updated = entry.federatedRepos.filter((r) => r !== resolvedRepo);
295
+ registry.setFederatedRepos(projectRoot, updated);
296
+ const updatedEntry = registry.getByPath(projectRoot);
297
+ writeMcpJson(projectRoot, updatedEntry);
298
+ console.log(`\n ✓ Unlinked: ${resolvedRepo}`);
299
+ console.log(' .mcp.json updated. Restart Claude Code to apply.\n');
300
+ }
301
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /** Returns the global ~/.pindex directory (migrates from ~/.mcp-indexer if present). */
2
+ export declare function getPindexHome(): string;
3
+ /** @deprecated Use getPindexHome() */
4
+ export declare function getMcpIndexerHome(): string;
5
+ /** Returns the projects directory within ~/.pindex. */
6
+ export declare function getProjectsDir(): string;
7
+ /** Returns a deterministic hash for a project path (used as its directory name). */
8
+ export declare function hashProjectPath(projectPath: string): string;
9
+ /** Returns the index DB path for a given project. */
10
+ export declare function getProjectIndexPath(projectPath: string): string;
11
+ /** Returns the meta JSON path for a given project. */
12
+ export declare function getProjectMetaPath(projectPath: string): string;
13
+ export interface ProjectMeta {
14
+ path: string;
15
+ lastIndexed: string | null;
16
+ hash: string;
17
+ }
18
+ /**
19
+ * Walks upward from startDir looking for common project root markers.
20
+ * Returns the directory containing the first marker found, or startDir if none.
21
+ */
22
+ export declare function findProjectRoot(startDir: string): string;
23
+ export interface RegistryEntry {
24
+ path: string;
25
+ hash: string;
26
+ name: string;
27
+ monitoringPort: number;
28
+ federatedRepos: string[];
29
+ addedAt: string;
30
+ }
31
+ export declare class GlobalRegistry {
32
+ private readonly registryPath;
33
+ constructor();
34
+ read(): RegistryEntry[];
35
+ private write;
36
+ /** Add or update a project entry. Returns the (possibly newly assigned) entry. */
37
+ upsert(projectPath: string, extra?: Partial<RegistryEntry>): RegistryEntry;
38
+ /** Update the federated repos list for a project. */
39
+ setFederatedRepos(projectPath: string, repos: string[]): void;
40
+ remove(projectPath: string): void;
41
+ list(): RegistryEntry[];
42
+ getByPath(projectPath: string): RegistryEntry | undefined;
43
+ }
44
+ //# sourceMappingURL=project-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-detector.d.ts","sourceRoot":"","sources":["../../src/cli/project-detector.ts"],"names":[],"mappings":"AAKA,wFAAwF;AACxF,wBAAgB,aAAa,IAAI,MAAM,CAWtC;AAED,sCAAsC;AACtC,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,uDAAuD;AACvD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,qDAAqD;AACrD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED,sDAAsD;AACtD,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgBxD;AASD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAOD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;;IAMtC,IAAI,IAAI,aAAa,EAAE;IAUvB,OAAO,CAAC,KAAK;IAOb,kFAAkF;IAClF,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa;IAiC1E,qDAAqD;IACrD,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAU7D,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAMjC,IAAI,IAAI,aAAa,EAAE;IAIvB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;CAI1D"}
@@ -0,0 +1,144 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { resolve, join, dirname } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync } from 'node:fs';
5
+ /** Returns the global ~/.pindex directory (migrates from ~/.mcp-indexer if present). */
6
+ export function getPindexHome() {
7
+ const newHome = join(homedir(), '.pindex');
8
+ const oldHome = join(homedir(), '.mcp-indexer');
9
+ if (!existsSync(newHome) && existsSync(oldHome)) {
10
+ try {
11
+ renameSync(oldHome, newHome);
12
+ }
13
+ catch {
14
+ // If rename fails (e.g. cross-device), just use the new path
15
+ }
16
+ }
17
+ return newHome;
18
+ }
19
+ /** @deprecated Use getPindexHome() */
20
+ export function getMcpIndexerHome() {
21
+ return getPindexHome();
22
+ }
23
+ /** Returns the projects directory within ~/.pindex. */
24
+ export function getProjectsDir() {
25
+ return join(getPindexHome(), 'projects');
26
+ }
27
+ /** Returns a deterministic hash for a project path (used as its directory name). */
28
+ export function hashProjectPath(projectPath) {
29
+ const normalized = resolve(projectPath);
30
+ return createHash('sha256').update(normalized).digest('hex').substring(0, 8);
31
+ }
32
+ /** Returns the index DB path for a given project. */
33
+ export function getProjectIndexPath(projectPath) {
34
+ const hash = hashProjectPath(projectPath);
35
+ return join(getProjectsDir(), hash, 'index.db');
36
+ }
37
+ /** Returns the meta JSON path for a given project. */
38
+ export function getProjectMetaPath(projectPath) {
39
+ const hash = hashProjectPath(projectPath);
40
+ return join(getProjectsDir(), hash, 'meta.json');
41
+ }
42
+ /**
43
+ * Walks upward from startDir looking for common project root markers.
44
+ * Returns the directory containing the first marker found, or startDir if none.
45
+ */
46
+ export function findProjectRoot(startDir) {
47
+ const markers = ['package.json', '.git', 'go.mod', 'Cargo.toml', 'pyproject.toml', 'pom.xml'];
48
+ let current = resolve(startDir);
49
+ // eslint-disable-next-line no-constant-condition
50
+ while (true) {
51
+ for (const marker of markers) {
52
+ if (existsSync(join(current, marker))) {
53
+ return current;
54
+ }
55
+ }
56
+ const parent = dirname(current);
57
+ if (parent === current)
58
+ break; // filesystem root reached
59
+ current = parent;
60
+ }
61
+ return resolve(startDir);
62
+ }
63
+ /** A deterministic monitoring port for a project, stored in registry to stay stable. */
64
+ function computeDefaultPort(hash) {
65
+ return 7842 + (parseInt(hash.slice(0, 4), 16) % 2000);
66
+ }
67
+ export class GlobalRegistry {
68
+ registryPath;
69
+ constructor() {
70
+ this.registryPath = join(getPindexHome(), 'registry.json');
71
+ }
72
+ read() {
73
+ if (!existsSync(this.registryPath))
74
+ return [];
75
+ try {
76
+ const data = JSON.parse(readFileSync(this.registryPath, 'utf-8'));
77
+ return data.projects ?? [];
78
+ }
79
+ catch {
80
+ return [];
81
+ }
82
+ }
83
+ write(entries) {
84
+ const home = getPindexHome();
85
+ if (!existsSync(home))
86
+ mkdirSync(home, { recursive: true });
87
+ const data = { version: 1, projects: entries };
88
+ writeFileSync(this.registryPath, JSON.stringify(data, null, 2), 'utf-8');
89
+ }
90
+ /** Add or update a project entry. Returns the (possibly newly assigned) entry. */
91
+ upsert(projectPath, extra) {
92
+ const normalizedPath = resolve(projectPath);
93
+ const hash = hashProjectPath(normalizedPath);
94
+ const projects = this.read();
95
+ const existingIdx = projects.findIndex((p) => p.hash === hash);
96
+ if (existingIdx !== -1) {
97
+ const updated = { ...projects[existingIdx], ...extra };
98
+ projects[existingIdx] = updated;
99
+ this.write(projects);
100
+ return updated;
101
+ }
102
+ // Assign a port that isn't already used by another project
103
+ const usedPorts = new Set(projects.map((p) => p.monitoringPort));
104
+ let port = computeDefaultPort(hash);
105
+ while (usedPorts.has(port))
106
+ port++;
107
+ const name = normalizedPath.split('/').pop() ?? normalizedPath;
108
+ const entry = {
109
+ path: normalizedPath,
110
+ hash,
111
+ name,
112
+ monitoringPort: port,
113
+ federatedRepos: [],
114
+ addedAt: new Date().toISOString(),
115
+ ...extra,
116
+ };
117
+ projects.push(entry);
118
+ this.write(projects);
119
+ return entry;
120
+ }
121
+ /** Update the federated repos list for a project. */
122
+ setFederatedRepos(projectPath, repos) {
123
+ const hash = hashProjectPath(resolve(projectPath));
124
+ const projects = this.read();
125
+ const idx = projects.findIndex((p) => p.hash === hash);
126
+ if (idx !== -1) {
127
+ projects[idx].federatedRepos = repos;
128
+ this.write(projects);
129
+ }
130
+ }
131
+ remove(projectPath) {
132
+ const hash = hashProjectPath(resolve(projectPath));
133
+ const projects = this.read().filter((p) => p.hash !== hash);
134
+ this.write(projects);
135
+ }
136
+ list() {
137
+ return this.read();
138
+ }
139
+ getByPath(projectPath) {
140
+ const hash = hashProjectPath(resolve(projectPath));
141
+ return this.read().find((p) => p.hash === hash);
142
+ }
143
+ }
144
+ //# sourceMappingURL=project-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-detector.js","sourceRoot":"","sources":["../../src/cli/project-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /** Writes the default global config file. */
2
+ export declare function writeGlobalConfig(): void;
3
+ /** Writes or merges the MCP server registration into Claude Code's global config. */
4
+ export declare function registerMcpServer(): void;
5
+ /** Installs a systemd user service (Linux). */
6
+ export declare function installSystemdService(execPath: string): void;
7
+ /** Runs the complete one-time setup. */
8
+ export declare function runSetup(): Promise<void>;
9
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AAsBA,6CAA6C;AAC7C,wBAAgB,iBAAiB,IAAI,IAAI,CAQxC;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,IAAI,IAAI,CA4BxC;AAED,+CAA+C;AAC/C,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAmB5D;AAED,wCAAwC;AACxC,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CA+B9C"}
@@ -0,0 +1,110 @@
1
+ import { mkdirSync, existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { homedir, platform } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { getPindexHome } from './project-detector.js';
5
+ const DEFAULT_CONFIG = {
6
+ version: '1.0.0',
7
+ daemon: {
8
+ monitoringPort: 7842,
9
+ autoStart: true,
10
+ },
11
+ indexing: {
12
+ languages: ['typescript', 'javascript'],
13
+ ignore: ['node_modules', '.git', 'dist', 'build', '.next'],
14
+ generateSummaries: false,
15
+ },
16
+ tokenPrice: {
17
+ inputPerMillion: 3.0,
18
+ model: 'claude-sonnet',
19
+ },
20
+ };
21
+ /** Writes the default global config file. */
22
+ export function writeGlobalConfig() {
23
+ const home = getPindexHome();
24
+ if (!existsSync(home))
25
+ mkdirSync(home, { recursive: true });
26
+ const configPath = join(home, 'config.json');
27
+ if (!existsSync(configPath)) {
28
+ writeFileSync(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2), 'utf-8');
29
+ }
30
+ }
31
+ /** Writes or merges the MCP server registration into Claude Code's global config. */
32
+ export function registerMcpServer() {
33
+ const claudeConfigPath = join(homedir(), '.claude', 'claude_code_config.json');
34
+ const mcpServerEntry = {
35
+ 'pindex': {
36
+ command: 'pindex-server',
37
+ args: [],
38
+ env: {},
39
+ },
40
+ };
41
+ let config = {};
42
+ if (existsSync(claudeConfigPath)) {
43
+ try {
44
+ config = JSON.parse(readFileSync(claudeConfigPath, 'utf-8'));
45
+ }
46
+ catch {
47
+ config = {};
48
+ }
49
+ }
50
+ const existing = config.mcpServers ?? {};
51
+ config.mcpServers = { ...existing, ...mcpServerEntry };
52
+ const dir = join(homedir(), '.claude');
53
+ if (!existsSync(dir))
54
+ mkdirSync(dir, { recursive: true });
55
+ writeFileSync(claudeConfigPath, JSON.stringify(config, null, 2), 'utf-8');
56
+ }
57
+ /** Installs a systemd user service (Linux). */
58
+ export function installSystemdService(execPath) {
59
+ const serviceDir = join(homedir(), '.config', 'systemd', 'user');
60
+ if (!existsSync(serviceDir))
61
+ mkdirSync(serviceDir, { recursive: true });
62
+ const serviceContent = `[Unit]
63
+ Description=PindeX MCP Codebase Indexer
64
+ After=network.target
65
+
66
+ [Service]
67
+ Type=simple
68
+ ExecStart=${execPath}
69
+ Restart=on-failure
70
+ StandardOutput=append:${getPindexHome()}/daemon.log
71
+ StandardError=append:${getPindexHome()}/daemon.log
72
+
73
+ [Install]
74
+ WantedBy=default.target
75
+ `;
76
+ writeFileSync(join(serviceDir, 'pindex.service'), serviceContent, 'utf-8');
77
+ }
78
+ /** Runs the complete one-time setup. */
79
+ export async function runSetup() {
80
+ console.log('\n ╔══════════════════════════════════════════╗');
81
+ console.log(' ║ PindeX – Setup ║');
82
+ console.log(' ╚══════════════════════════════════════════╝\n');
83
+ // 1. Write global config
84
+ process.stdout.write(' [1/2] Creating global configuration...');
85
+ writeGlobalConfig();
86
+ console.log(' ✓');
87
+ // 2. Set up autostart (Linux only for now)
88
+ process.stdout.write(' [2/2] Setting up autostart...');
89
+ const plt = platform();
90
+ if (plt === 'linux') {
91
+ try {
92
+ const execPath = process.execPath + ' ' + process.argv[1];
93
+ installSystemdService(execPath);
94
+ console.log(' ✓ (systemd)');
95
+ }
96
+ catch {
97
+ console.log(' ⚠ (skipped – could not write systemd service)');
98
+ }
99
+ }
100
+ else {
101
+ console.log(` ✓ (${plt} – manual start required)`);
102
+ }
103
+ console.log('\n ══════════════════════════════════════════');
104
+ console.log(' ✅ Setup complete!\n');
105
+ console.log(' Next: run pindex in any project directory');
106
+ console.log(' to generate .mcp.json and activate indexing.\n');
107
+ console.log(' Dashboard: pindex-gui');
108
+ console.log(' ══════════════════════════════════════════\n');
109
+ }
110
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"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"}