token-pilot 0.12.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/.claude-plugin/hooks/hooks.json +9 -0
  2. package/.claude-plugin/marketplace.json +2 -2
  3. package/.claude-plugin/plugin.json +2 -2
  4. package/CHANGELOG.md +30 -1
  5. package/README.md +28 -7
  6. package/dist/config/defaults.js +12 -0
  7. package/dist/core/architecture-fingerprint.d.ts +34 -0
  8. package/dist/core/architecture-fingerprint.js +127 -0
  9. package/dist/core/budget-planner.d.ts +21 -0
  10. package/dist/core/budget-planner.js +68 -0
  11. package/dist/core/confidence.d.ts +31 -0
  12. package/dist/core/confidence.js +99 -0
  13. package/dist/core/context-registry.d.ts +14 -0
  14. package/dist/core/context-registry.js +55 -0
  15. package/dist/core/decision-trace.d.ts +31 -0
  16. package/dist/core/decision-trace.js +45 -0
  17. package/dist/core/intent-classifier.d.ts +13 -0
  18. package/dist/core/intent-classifier.js +44 -0
  19. package/dist/core/policy-engine.d.ts +41 -0
  20. package/dist/core/policy-engine.js +76 -0
  21. package/dist/core/session-analytics.d.ts +8 -0
  22. package/dist/core/session-analytics.js +86 -7
  23. package/dist/core/session-cache.d.ts +74 -0
  24. package/dist/core/session-cache.js +162 -0
  25. package/dist/core/validation.d.ts +3 -0
  26. package/dist/core/validation.js +3 -0
  27. package/dist/git/file-watcher.d.ts +6 -0
  28. package/dist/git/file-watcher.js +18 -2
  29. package/dist/git/watcher.d.ts +3 -0
  30. package/dist/git/watcher.js +6 -0
  31. package/dist/handlers/code-audit.d.ts +7 -2
  32. package/dist/handlers/code-audit.js +19 -5
  33. package/dist/handlers/explore-area.d.ts +10 -0
  34. package/dist/handlers/explore-area.js +39 -13
  35. package/dist/handlers/find-unused.d.ts +3 -0
  36. package/dist/handlers/find-unused.js +3 -2
  37. package/dist/handlers/find-usages.d.ts +7 -0
  38. package/dist/handlers/find-usages.js +36 -5
  39. package/dist/handlers/module-info.d.ts +3 -0
  40. package/dist/handlers/module-info.js +22 -2
  41. package/dist/handlers/project-overview.d.ts +1 -1
  42. package/dist/handlers/project-overview.js +18 -2
  43. package/dist/handlers/read-for-edit.d.ts +3 -0
  44. package/dist/handlers/read-for-edit.js +185 -3
  45. package/dist/handlers/read-range.d.ts +1 -1
  46. package/dist/handlers/read-range.js +16 -1
  47. package/dist/handlers/read-symbol.d.ts +1 -1
  48. package/dist/handlers/read-symbol.js +26 -2
  49. package/dist/handlers/related-files.d.ts +11 -0
  50. package/dist/handlers/related-files.js +178 -42
  51. package/dist/handlers/smart-read-many.js +70 -16
  52. package/dist/handlers/smart-read.js +10 -1
  53. package/dist/handlers/test-summary.js +26 -3
  54. package/dist/hooks/installer.d.ts +12 -8
  55. package/dist/hooks/installer.js +24 -8
  56. package/dist/index.d.ts +16 -1
  57. package/dist/index.js +61 -55
  58. package/dist/server.js +395 -30
  59. package/dist/types.d.ts +12 -0
  60. package/package.json +5 -3
  61. package/start.sh +28 -27
  62. package/dist/handlers/class-hierarchy.d.ts +0 -11
  63. package/dist/handlers/class-hierarchy.js +0 -28
  64. package/dist/handlers/export-ast-index.d.ts +0 -22
  65. package/dist/handlers/export-ast-index.js +0 -175
  66. package/dist/handlers/find-implementations.d.ts +0 -11
  67. package/dist/handlers/find-implementations.js +0 -27
  68. package/dist/handlers/search-code.d.ts +0 -14
  69. package/dist/handlers/search-code.js +0 -32
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
3
3
  import { readFileSync } from 'node:fs';
4
4
  import { execFile } from 'node:child_process';
5
5
  import { promisify } from 'node:util';
6
+ import { fileURLToPath } from 'node:url';
6
7
  import { createServer } from './server.js';
7
8
  import { installHook, uninstallHook } from './hooks/installer.js';
8
9
  import { findBinary, installBinary, checkBinaryUpdate, isNewerVersion } from './ast-index/binary-manager.js';
@@ -10,14 +11,14 @@ import { loadConfig } from './config/loader.js';
10
11
  import { isDangerousRoot } from './core/validation.js';
11
12
  const execFileAsync = promisify(execFile);
12
13
  const HOOK_DENY_THRESHOLD = 500;
13
- const CODE_EXTENSIONS = new Set([
14
+ export const CODE_EXTENSIONS = new Set([
14
15
  'ts', 'tsx', 'js', 'jsx', 'mjs', 'py', 'go', 'rs', 'java', 'kt', 'kts',
15
16
  'swift', 'cs', 'cpp', 'cc', 'cxx', 'hpp', 'c', 'h', 'php', 'rb', 'scala',
16
17
  'dart', 'lua', 'sh', 'bash', 'sql', 'r', 'vue', 'svelte', 'pl', 'pm',
17
18
  'ex', 'exs', 'groovy', 'm', 'proto', 'bsl',
18
19
  'lisp', 'lsp', 'cl', 'asd',
19
20
  ]);
20
- function getVersion() {
21
+ export function getVersion() {
21
22
  try {
22
23
  const pkgPath = new URL('../package.json', import.meta.url).pathname;
23
24
  const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
@@ -27,50 +28,48 @@ function getVersion() {
27
28
  return '0.0.0';
28
29
  }
29
30
  }
30
- const args = process.argv.slice(2);
31
- switch (args[0]) {
32
- case 'hook-read':
33
- handleHookRead(args[1]);
34
- break;
35
- case 'hook-edit':
36
- handleHookEdit();
37
- break;
38
- case 'install-hook':
39
- handleInstallHook(args[1] || process.cwd());
40
- break;
41
- case 'uninstall-hook':
42
- handleUninstallHook(args[1] || process.cwd());
43
- break;
44
- case 'install-ast-index':
45
- handleInstallAstIndex();
46
- break;
47
- case 'doctor':
48
- handleDoctor();
49
- break;
50
- case 'init':
51
- handleInit(args[1] || process.cwd());
52
- break;
53
- case '--version':
54
- case '-v':
55
- console.log(getVersion());
56
- process.exit(0);
57
- break;
58
- case '--help':
59
- case '-h':
60
- printHelp();
61
- break;
62
- default:
63
- startServer().catch(err => {
64
- console.error(`[token-pilot] Fatal: ${err instanceof Error ? err.message : err}`);
65
- process.exit(1);
66
- });
67
- break;
31
+ export async function main(cliArgs = process.argv.slice(2)) {
32
+ switch (cliArgs[0]) {
33
+ case 'hook-read':
34
+ handleHookRead(cliArgs[1]);
35
+ return;
36
+ case 'hook-edit':
37
+ handleHookEdit();
38
+ return;
39
+ case 'install-hook':
40
+ await handleInstallHook(cliArgs[1] || process.cwd());
41
+ return;
42
+ case 'uninstall-hook':
43
+ await handleUninstallHook(cliArgs[1] || process.cwd());
44
+ return;
45
+ case 'install-ast-index':
46
+ await handleInstallAstIndex();
47
+ return;
48
+ case 'doctor':
49
+ await handleDoctor();
50
+ return;
51
+ case 'init':
52
+ await handleInit(cliArgs[1] || process.cwd());
53
+ return;
54
+ case '--version':
55
+ case '-v':
56
+ console.log(getVersion());
57
+ process.exit(0);
58
+ return;
59
+ case '--help':
60
+ case '-h':
61
+ printHelp();
62
+ return;
63
+ default:
64
+ await startServer(cliArgs);
65
+ return;
66
+ }
68
67
  }
69
- async function startServer() {
70
- let projectRoot = args[0] || process.cwd();
68
+ export async function startServer(cliArgs = process.argv.slice(2)) {
69
+ let projectRoot = cliArgs[0] || process.cwd();
71
70
  // Detect git root for reliable project root
72
71
  // Try multiple sources: args[0] → INIT_CWD (npm/npx invoking dir) → PWD → cwd
73
- if (!args[0]) {
72
+ if (!cliArgs[0]) {
74
73
  const candidates = [
75
74
  process.env.INIT_CWD, // npm/npx sets this to invoking directory
76
75
  process.env.PWD, // shell working directory (may differ from cwd)
@@ -140,7 +139,7 @@ async function startServer() {
140
139
  process.exit(0);
141
140
  });
142
141
  }
143
- function handleHookRead(filePathArg) {
142
+ export function handleHookRead(filePathArg) {
144
143
  // Parse stdin (Claude Code hook format) to get tool_input
145
144
  let filePath = filePathArg;
146
145
  let hasOffset = false;
@@ -193,7 +192,7 @@ function handleHookRead(filePathArg) {
193
192
  process.stdout.write(deny);
194
193
  process.exit(0);
195
194
  }
196
- function handleHookEdit() {
195
+ export function handleHookEdit() {
197
196
  // Parse stdin for Edit tool_input
198
197
  let filePath;
199
198
  try {
@@ -223,17 +222,17 @@ function handleHookEdit() {
223
222
  process.stdout.write(context);
224
223
  process.exit(0);
225
224
  }
226
- async function handleInstallHook(projectRoot) {
225
+ export async function handleInstallHook(projectRoot) {
227
226
  const result = await installHook(projectRoot);
228
227
  console.log(result.message);
229
- process.exit(result.installed ? 0 : 1);
228
+ process.exit(result.fatal ? 1 : 0);
230
229
  }
231
- async function handleUninstallHook(projectRoot) {
230
+ export async function handleUninstallHook(projectRoot) {
232
231
  const result = await uninstallHook(projectRoot);
233
232
  console.log(result.message);
234
- process.exit(result.removed ? 0 : 1);
233
+ process.exit(result.fatal ? 1 : 0);
235
234
  }
236
- async function handleInstallAstIndex() {
235
+ export async function handleInstallAstIndex() {
237
236
  const status = await findBinary();
238
237
  if (status.available) {
239
238
  // Check if update is available
@@ -256,7 +255,7 @@ async function handleInstallAstIndex() {
256
255
  process.exit(1);
257
256
  }
258
257
  }
259
- async function handleDoctor() {
258
+ export async function handleDoctor() {
260
259
  const version = getVersion();
261
260
  const { existsSync } = await import('node:fs');
262
261
  const { join } = await import('node:path');
@@ -324,7 +323,7 @@ async function handleDoctor() {
324
323
  console.log('');
325
324
  process.exit(0);
326
325
  }
327
- async function handleInit(targetDir) {
326
+ export async function handleInit(targetDir) {
328
327
  const { existsSync, readFileSync: readFs, writeFileSync } = await import('node:fs');
329
328
  const { join } = await import('node:path');
330
329
  const mcpPath = join(targetDir, '.mcp.json');
@@ -379,7 +378,7 @@ async function handleInit(targetDir) {
379
378
  // ──────────────────────────────────────────────
380
379
  // Update checking
381
380
  // ──────────────────────────────────────────────
382
- async function checkNpmLatest(packageName) {
381
+ export async function checkNpmLatest(packageName) {
383
382
  try {
384
383
  const controller = new AbortController();
385
384
  const timeout = setTimeout(() => controller.abort(), 3000);
@@ -396,7 +395,7 @@ async function checkNpmLatest(packageName) {
396
395
  return null;
397
396
  }
398
397
  }
399
- async function checkAllUpdates(config, binaryStatus) {
398
+ export async function checkAllUpdates(config, binaryStatus) {
400
399
  if (!config.updates.checkOnStartup)
401
400
  return;
402
401
  const [tpLatest, astUpdate, cmLatest] = await Promise.allSettled([
@@ -427,7 +426,7 @@ async function checkAllUpdates(config, binaryStatus) {
427
426
  // On startup, we only notify if explicitly useful.
428
427
  }
429
428
  }
430
- function printHelp() {
429
+ export function printHelp() {
431
430
  console.log(`token-pilot v${getVersion()} — MCP server for token-efficient code reading
432
431
 
433
432
  Usage:
@@ -450,4 +449,11 @@ MCP Tools (18):
450
449
  `);
451
450
  process.exit(0);
452
451
  }
452
+ const isDirectRun = process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1];
453
+ if (isDirectRun) {
454
+ main().catch(err => {
455
+ console.error(`[token-pilot] Fatal: ${err instanceof Error ? err.message : err}`);
456
+ process.exit(1);
457
+ });
458
+ }
453
459
  //# sourceMappingURL=index.js.map