token-pilot 0.15.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.js CHANGED
@@ -19,6 +19,7 @@ const execFilePromise = promisify(execFile);
19
19
  import { FileWatcher } from './git/file-watcher.js';
20
20
  import { handleSmartRead } from './handlers/smart-read.js';
21
21
  import { handleReadSymbol } from './handlers/read-symbol.js';
22
+ import { handleReadSymbols } from './handlers/read-symbols.js';
22
23
  import { handleReadRange } from './handlers/read-range.js';
23
24
  import { handleReadDiff } from './handlers/read-diff.js';
24
25
  import { handleFindUsages } from './handlers/find-usages.js';
@@ -40,7 +41,7 @@ import { estimateTokens } from './core/token-estimator.js';
40
41
  import { checkPolicy, isFullReadTool } from './core/policy-engine.js';
41
42
  import { MCP_INSTRUCTIONS, TOOL_DEFINITIONS } from './server/tool-definitions.js';
42
43
  import { createTokenEstimates } from './server/token-estimates.js';
43
- import { validateSmartReadArgs, validateReadSymbolArgs, validateReadRangeArgs, validateReadDiffArgs, validateFindUsagesArgs, validateSmartReadManyArgs, validateReadForEditArgs, validateRelatedFilesArgs, validateOutlineArgs, validateFindUnusedArgs, validateCodeAuditArgs, validateProjectOverviewArgs, validateModuleInfoArgs, validateSmartDiffArgs, validateExploreAreaArgs, validateSmartLogArgs, validateTestSummaryArgs, } from './core/validation.js';
44
+ import { validateSmartReadArgs, validateReadSymbolArgs, validateReadSymbolsArgs, validateReadRangeArgs, validateReadDiffArgs, validateFindUsagesArgs, validateSmartReadManyArgs, validateReadForEditArgs, validateRelatedFilesArgs, validateOutlineArgs, validateFindUnusedArgs, validateCodeAuditArgs, validateProjectOverviewArgs, validateModuleInfoArgs, validateSmartDiffArgs, validateExploreAreaArgs, validateSmartLogArgs, validateTestSummaryArgs, } from './core/validation.js';
44
45
  export async function createServer(projectRoot, options) {
45
46
  const config = await loadConfig(projectRoot);
46
47
  const astIndex = new AstIndexClient(projectRoot, config.astIndex.timeout, {
@@ -145,6 +146,7 @@ export async function createServer(projectRoot, options) {
145
146
  }
146
147
  // Session analytics
147
148
  const analytics = new SessionAnalytics();
149
+ analytics.setProjectRoot(projectRoot);
148
150
  // Session cache (tool-result-level caching, invalidated by file/AST/git changes)
149
151
  const sessionCache = config.sessionCache.enabled
150
152
  ? new SessionCache(config.sessionCache.maxEntries)
@@ -288,6 +290,15 @@ export async function createServer(projectRoot, options) {
288
290
  recordWithTrace({ tool: 'read_symbol', path: symArgs.path, tokensReturned: symTokens, tokensWouldBe: fullTokensSym || symTokens, timestamp: Date.now(), savingsCategory: detectSavingsCategory(symText), absPath: resolve(projectRoot, symArgs.path), args: symArgs });
289
291
  return symResult;
290
292
  }
293
+ case 'read_symbols': {
294
+ const rsArgs = validateReadSymbolsArgs(args);
295
+ const rsResult = await handleReadSymbols(rsArgs, projectRoot, symbolResolver, fileCache, contextRegistry, astIndex, config.smartRead.advisoryReminders);
296
+ const rsText = rsResult.content[0]?.text ?? '';
297
+ const rsTokens = estimateTokens(rsText);
298
+ const fullTokensRs = await fullFileTokens(rsArgs.path);
299
+ recordWithTrace({ tool: 'read_symbols', path: rsArgs.path, tokensReturned: rsTokens, tokensWouldBe: fullTokensRs || rsTokens, timestamp: Date.now(), savingsCategory: 'compression', absPath: resolve(projectRoot, rsArgs.path), args: rsArgs });
300
+ return rsResult;
301
+ }
291
302
  case 'read_range': {
292
303
  const rangeArgs = validateReadRangeArgs(args);
293
304
  const rangeResult = await handleReadRange(rangeArgs, projectRoot, fileCache, contextRegistry, config.smartRead.advisoryReminders);
@@ -343,7 +354,7 @@ export async function createServer(projectRoot, options) {
343
354
  recordWithTrace({ tool: 'find_usages', path: usagesArgs.symbol, tokensReturned: cachedUsages.tokenEstimate, tokensWouldBe: cachedUsages.tokensWouldBe ?? cachedUsages.tokenEstimate, timestamp: Date.now(), sessionCacheHit: true, savingsCategory: 'cache', args: usagesArgs });
344
355
  return cachedUsages.result;
345
356
  }
346
- const usagesResult = await handleFindUsages(usagesArgs, astIndex);
357
+ const usagesResult = await handleFindUsages(usagesArgs, astIndex, projectRoot);
347
358
  const usagesText = usagesResult.content[0]?.text ?? '';
348
359
  const usagesTokens = estimateTokens(usagesText);
349
360
  const usagesWouldBe = await estimateFindUsagesWorkflowTokens(usagesResult.meta.files);
@@ -447,8 +458,10 @@ export async function createServer(projectRoot, options) {
447
458
  });
448
459
  return outlineResult;
449
460
  }
450
- case 'session_analytics':
451
- return { content: [{ type: 'text', text: `TOKEN PILOT v${pkgVersion}\n\n${analytics.report()}` }] };
461
+ case 'session_analytics': {
462
+ const verbose = args?.verbose === true;
463
+ return { content: [{ type: 'text', text: `TOKEN PILOT v${pkgVersion}\n\n${analytics.report(verbose)}` }] };
464
+ }
452
465
  case 'find_unused': {
453
466
  const unusedArgs = validateFindUnusedArgs(args);
454
467
  const cachedUnused = sessionCache?.get('find_unused', unusedArgs);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "token-pilot",
3
- "version": "0.15.0",
3
+ "version": "0.16.1",
4
4
  "description": "Save up to 80% tokens when AI reads code — MCP server for token-efficient code navigation, AST-aware structural reading instead of dumping full files into context window",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",