@gracker/smartperfetto 1.0.13 → 1.0.15

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 (175) hide show
  1. package/.env.example +16 -8
  2. package/dist/agent/core/orchestratorTypes.d.ts +10 -0
  3. package/dist/agent/core/orchestratorTypes.d.ts.map +1 -1
  4. package/dist/agent/core/orchestratorTypes.js.map +1 -1
  5. package/dist/agentOpenAI/openAiRuntime.d.ts.map +1 -1
  6. package/dist/agentOpenAI/openAiRuntime.js +11 -1
  7. package/dist/agentOpenAI/openAiRuntime.js.map +1 -1
  8. package/dist/agentOpenAI/openAiToolAdapter.d.ts.map +1 -1
  9. package/dist/agentOpenAI/openAiToolAdapter.js +27 -2
  10. package/dist/agentOpenAI/openAiToolAdapter.js.map +1 -1
  11. package/dist/agentv3/claudeMcpServer.d.ts +15 -1
  12. package/dist/agentv3/claudeMcpServer.d.ts.map +1 -1
  13. package/dist/agentv3/claudeMcpServer.js +311 -5
  14. package/dist/agentv3/claudeMcpServer.js.map +1 -1
  15. package/dist/agentv3/claudeRuntime.d.ts.map +1 -1
  16. package/dist/agentv3/claudeRuntime.js +17 -0
  17. package/dist/agentv3/claudeRuntime.js.map +1 -1
  18. package/dist/agentv3/claudeSystemPrompt.d.ts.map +1 -1
  19. package/dist/agentv3/claudeSystemPrompt.js +9 -0
  20. package/dist/agentv3/claudeSystemPrompt.js.map +1 -1
  21. package/dist/agentv3/mcpToolRegistry.d.ts +14 -2
  22. package/dist/agentv3/mcpToolRegistry.d.ts.map +1 -1
  23. package/dist/agentv3/mcpToolRegistry.js +25 -6
  24. package/dist/agentv3/mcpToolRegistry.js.map +1 -1
  25. package/dist/agentv3/sessionStateSnapshot.d.ts +18 -0
  26. package/dist/agentv3/sessionStateSnapshot.d.ts.map +1 -1
  27. package/dist/agentv3/types.d.ts +5 -0
  28. package/dist/agentv3/types.d.ts.map +1 -1
  29. package/dist/agentv3/types.js.map +1 -1
  30. package/dist/cli-user/bin.js +99 -1
  31. package/dist/cli-user/bin.js.map +1 -1
  32. package/dist/cli-user/commands/analyze.d.ts +3 -0
  33. package/dist/cli-user/commands/analyze.d.ts.map +1 -1
  34. package/dist/cli-user/commands/analyze.js +2 -0
  35. package/dist/cli-user/commands/analyze.js.map +1 -1
  36. package/dist/cli-user/commands/codebase.d.ts +29 -0
  37. package/dist/cli-user/commands/codebase.d.ts.map +1 -0
  38. package/dist/cli-user/commands/codebase.js +152 -0
  39. package/dist/cli-user/commands/codebase.js.map +1 -0
  40. package/dist/cli-user/commands/config.d.ts.map +1 -1
  41. package/dist/cli-user/commands/config.js +4 -1
  42. package/dist/cli-user/commands/config.js.map +1 -1
  43. package/dist/cli-user/services/cliAnalyzeService.d.ts +3 -0
  44. package/dist/cli-user/services/cliAnalyzeService.d.ts.map +1 -1
  45. package/dist/cli-user/services/cliAnalyzeService.js +116 -29
  46. package/dist/cli-user/services/cliAnalyzeService.js.map +1 -1
  47. package/dist/cli-user/services/turnRunner.d.ts +3 -0
  48. package/dist/cli-user/services/turnRunner.d.ts.map +1 -1
  49. package/dist/cli-user/services/turnRunner.js +6 -0
  50. package/dist/cli-user/services/turnRunner.js.map +1 -1
  51. package/dist/cli-user/types.d.ts +5 -0
  52. package/dist/cli-user/types.d.ts.map +1 -1
  53. package/dist/routes/agentRoutes.d.ts.map +1 -1
  54. package/dist/routes/agentRoutes.js +4 -0
  55. package/dist/routes/agentRoutes.js.map +1 -1
  56. package/dist/routes/ragAdminRoutes.d.ts +13 -24
  57. package/dist/routes/ragAdminRoutes.d.ts.map +1 -1
  58. package/dist/routes/ragAdminRoutes.js +266 -11
  59. package/dist/routes/ragAdminRoutes.js.map +1 -1
  60. package/dist/scripts/verifyAgentSseScrolling.js +119 -3
  61. package/dist/scripts/verifyAgentSseScrolling.js.map +1 -1
  62. package/dist/services/aospKnowledgeIngester.d.ts +7 -0
  63. package/dist/services/aospKnowledgeIngester.d.ts.map +1 -1
  64. package/dist/services/aospKnowledgeIngester.js +19 -7
  65. package/dist/services/aospKnowledgeIngester.js.map +1 -1
  66. package/dist/services/auth/codebaseScopes.d.ts +6 -0
  67. package/dist/services/auth/codebaseScopes.d.ts.map +1 -0
  68. package/dist/services/auth/codebaseScopes.js +23 -0
  69. package/dist/services/auth/codebaseScopes.js.map +1 -0
  70. package/dist/services/codebase/codeAwareFeature.d.ts +4 -0
  71. package/dist/services/codebase/codeAwareFeature.d.ts.map +1 -0
  72. package/dist/services/codebase/codeAwareFeature.js +18 -0
  73. package/dist/services/codebase/codeAwareFeature.js.map +1 -0
  74. package/dist/services/codebase/codeLookupLedger.d.ts +37 -0
  75. package/dist/services/codebase/codeLookupLedger.d.ts.map +1 -0
  76. package/dist/services/codebase/codeLookupLedger.js +126 -0
  77. package/dist/services/codebase/codeLookupLedger.js.map +1 -0
  78. package/dist/services/codebase/codebaseRegistry.d.ts +76 -0
  79. package/dist/services/codebase/codebaseRegistry.d.ts.map +1 -0
  80. package/dist/services/codebase/codebaseRegistry.js +164 -0
  81. package/dist/services/codebase/codebaseRegistry.js.map +1 -0
  82. package/dist/services/codebase/defaultCodebaseServices.d.ts +5 -0
  83. package/dist/services/codebase/defaultCodebaseServices.d.ts.map +1 -0
  84. package/dist/services/codebase/defaultCodebaseServices.js +21 -0
  85. package/dist/services/codebase/defaultCodebaseServices.js.map +1 -0
  86. package/dist/services/codebase/patchProposer.d.ts +44 -0
  87. package/dist/services/codebase/patchProposer.d.ts.map +1 -0
  88. package/dist/services/codebase/patchProposer.js +163 -0
  89. package/dist/services/codebase/patchProposer.js.map +1 -0
  90. package/dist/services/codebase/pathSecurityGate.d.ts +33 -0
  91. package/dist/services/codebase/pathSecurityGate.d.ts.map +1 -0
  92. package/dist/services/codebase/pathSecurityGate.js +214 -0
  93. package/dist/services/codebase/pathSecurityGate.js.map +1 -0
  94. package/dist/services/htmlReportGenerator.d.ts +2 -0
  95. package/dist/services/htmlReportGenerator.d.ts.map +1 -1
  96. package/dist/services/htmlReportGenerator.js +67 -0
  97. package/dist/services/htmlReportGenerator.js.map +1 -1
  98. package/dist/services/persistAgentSession.d.ts.map +1 -1
  99. package/dist/services/persistAgentSession.js +19 -0
  100. package/dist/services/persistAgentSession.js.map +1 -1
  101. package/dist/services/rag/aospSourceIngester.d.ts +26 -0
  102. package/dist/services/rag/aospSourceIngester.d.ts.map +1 -0
  103. package/dist/services/rag/aospSourceIngester.js +143 -0
  104. package/dist/services/rag/aospSourceIngester.js.map +1 -0
  105. package/dist/services/rag/appSourceIngester.d.ts +37 -0
  106. package/dist/services/rag/appSourceIngester.d.ts.map +1 -0
  107. package/dist/services/rag/appSourceIngester.js +165 -0
  108. package/dist/services/rag/appSourceIngester.js.map +1 -0
  109. package/dist/services/rag/baseIngester.d.ts +18 -0
  110. package/dist/services/rag/baseIngester.d.ts.map +1 -0
  111. package/dist/services/rag/baseIngester.js +197 -0
  112. package/dist/services/rag/baseIngester.js.map +1 -0
  113. package/dist/services/rag/kernelSourceIngester.d.ts +35 -0
  114. package/dist/services/rag/kernelSourceIngester.d.ts.map +1 -0
  115. package/dist/services/rag/kernelSourceIngester.js +170 -0
  116. package/dist/services/rag/kernelSourceIngester.js.map +1 -0
  117. package/dist/services/rag/lookupResponseFilter.d.ts +42 -0
  118. package/dist/services/rag/lookupResponseFilter.d.ts.map +1 -0
  119. package/dist/services/rag/lookupResponseFilter.js +192 -0
  120. package/dist/services/rag/lookupResponseFilter.js.map +1 -0
  121. package/dist/services/rag/sessionToolResultRegistry.d.ts +25 -0
  122. package/dist/services/rag/sessionToolResultRegistry.d.ts.map +1 -0
  123. package/dist/services/rag/sessionToolResultRegistry.js +57 -0
  124. package/dist/services/rag/sessionToolResultRegistry.js.map +1 -0
  125. package/dist/services/rag/toolResultProjectionFilter.d.ts +18 -0
  126. package/dist/services/rag/toolResultProjectionFilter.d.ts.map +1 -0
  127. package/dist/services/rag/toolResultProjectionFilter.js +33 -0
  128. package/dist/services/rag/toolResultProjectionFilter.js.map +1 -0
  129. package/dist/services/ragStore.d.ts +8 -0
  130. package/dist/services/ragStore.d.ts.map +1 -1
  131. package/dist/services/ragStore.js +77 -8
  132. package/dist/services/ragStore.js.map +1 -1
  133. package/dist/services/rbac.d.ts +1 -1
  134. package/dist/services/rbac.d.ts.map +1 -1
  135. package/dist/services/rbac.js +6 -0
  136. package/dist/services/rbac.js.map +1 -1
  137. package/dist/services/security/codeAwareOutputRegistry.d.ts +6 -0
  138. package/dist/services/security/codeAwareOutputRegistry.d.ts.map +1 -0
  139. package/dist/services/security/codeAwareOutputRegistry.js +55 -0
  140. package/dist/services/security/codeAwareOutputRegistry.js.map +1 -0
  141. package/dist/services/security/llmEchoOutputFilter.d.ts +49 -0
  142. package/dist/services/security/llmEchoOutputFilter.d.ts.map +1 -0
  143. package/dist/services/security/llmEchoOutputFilter.js +133 -0
  144. package/dist/services/security/llmEchoOutputFilter.js.map +1 -0
  145. package/dist/services/security/secretPatterns.d.ts +6 -0
  146. package/dist/services/security/secretPatterns.d.ts.map +1 -0
  147. package/dist/services/security/secretPatterns.js +23 -0
  148. package/dist/services/security/secretPatterns.js.map +1 -0
  149. package/dist/services/symbol/breakpadSymParser.d.ts +19 -0
  150. package/dist/services/symbol/breakpadSymParser.d.ts.map +1 -0
  151. package/dist/services/symbol/breakpadSymParser.js +40 -0
  152. package/dist/services/symbol/breakpadSymParser.js.map +1 -0
  153. package/dist/services/symbol/kallsymsParser.d.ts +12 -0
  154. package/dist/services/symbol/kallsymsParser.d.ts.map +1 -0
  155. package/dist/services/symbol/kallsymsParser.js +41 -0
  156. package/dist/services/symbol/kallsymsParser.js.map +1 -0
  157. package/dist/services/symbol/r8MappingParser.d.ts +40 -0
  158. package/dist/services/symbol/r8MappingParser.d.ts.map +1 -0
  159. package/dist/services/symbol/r8MappingParser.js +99 -0
  160. package/dist/services/symbol/r8MappingParser.js.map +1 -0
  161. package/dist/services/symbol/symbolResolver.d.ts +59 -0
  162. package/dist/services/symbol/symbolResolver.d.ts.map +1 -0
  163. package/dist/services/symbol/symbolResolver.js +147 -0
  164. package/dist/services/symbol/symbolResolver.js.map +1 -0
  165. package/dist/services/symbol/traceSymbolContext.d.ts +14 -0
  166. package/dist/services/symbol/traceSymbolContext.d.ts.map +1 -0
  167. package/dist/services/symbol/traceSymbolContext.js +45 -0
  168. package/dist/services/symbol/traceSymbolContext.js.map +1 -0
  169. package/dist/types/sparkContracts.d.ts +31 -3
  170. package/dist/types/sparkContracts.d.ts.map +1 -1
  171. package/dist/types/sparkContracts.js.map +1 -1
  172. package/package.json +12 -5
  173. package/skills/composite/code_pinpoint.skill.yaml +111 -0
  174. package/strategies/code-aware.template.md +37 -0
  175. package/strategies/prompt-methodology.template.md +2 -0
@@ -37,6 +37,7 @@ var __importStar = (this && this.__importStar) || (function () {
37
37
  })();
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.MIN_PHASE_SUMMARY_CHARS = exports.MCP_NAME_PREFIX = void 0;
40
+ exports.normalizeOptionalToolString = normalizeOptionalToolString;
40
41
  exports.loadLearnedSqlFixPairs = loadLearnedSqlFixPairs;
41
42
  exports.createClaudeMcpServer = createClaudeMcpServer;
42
43
  const claude_agent_sdk_1 = require("@anthropic-ai/claude-agent-sdk");
@@ -73,6 +74,12 @@ const caseLibrary_1 = require("../services/caseLibrary");
73
74
  const scopedKnowledgeStore_1 = require("../services/scopedKnowledgeStore");
74
75
  const mcpToolRegistry_1 = require("./mcpToolRegistry");
75
76
  const runtimePaths_1 = require("../runtimePaths");
77
+ const defaultCodebaseServices_1 = require("../services/codebase/defaultCodebaseServices");
78
+ const codeLookupLedger_1 = require("../services/codebase/codeLookupLedger");
79
+ const patchProposer_1 = require("../services/codebase/patchProposer");
80
+ const codeAwareFeature_1 = require("../services/codebase/codeAwareFeature");
81
+ const lookupResponseFilter_1 = require("../services/rag/lookupResponseFilter");
82
+ const symbolResolver_1 = require("../services/symbol/symbolResolver");
76
83
  /**
77
84
  * Process-wide RagStore singleton, lazily initialized on first MCP tool
78
85
  * call. Backs the `lookup_blog_knowledge` tool (Plan 55) and will back
@@ -207,6 +214,18 @@ function parseOptionalToolArrayInput(value) {
207
214
  }
208
215
  return parseToolArrayInput(value);
209
216
  }
217
+ function normalizeOptionalToolString(value) {
218
+ if (typeof value !== 'string')
219
+ return undefined;
220
+ const trimmed = value.trim();
221
+ if (!trimmed)
222
+ return undefined;
223
+ const normalized = trimmed.toLowerCase();
224
+ if (normalized === 'null' || normalized === 'undefined' || normalized === 'none') {
225
+ return undefined;
226
+ }
227
+ return trimmed;
228
+ }
210
229
  function parseToolStringArrayInput(value) {
211
230
  if (Array.isArray(value)) {
212
231
  return value.filter((entry) => typeof entry === 'string' && entry.trim().length > 0);
@@ -618,6 +637,14 @@ function createClaudeMcpServer(options) {
618
637
  const skillNotesBudget = options.skillNotesBudget;
619
638
  const outputLanguage = options.outputLanguage ?? outputLanguage_1.DEFAULT_OUTPUT_LANGUAGE;
620
639
  const knowledgeScope = options.knowledgeScope;
640
+ const codeAwareMode = (0, codeAwareFeature_1.normalizeCodeAwareMode)(options.codeAwareMode);
641
+ const codebaseIds = Array.from(new Set(options.codebaseIds ?? [])).filter(Boolean);
642
+ const codebaseRegistry = options.codebaseRegistry ?? (0, defaultCodebaseServices_1.getDefaultCodebaseRegistry)();
643
+ const codeLookupLedger = options.codeLookupLedger ?? (options.sessionId ? codeLookupLedger_1.CodeLookupLedger.restore(options.sessionId, 12000, 2) : undefined);
644
+ const toolRequestScope = {
645
+ sessionId: options.sessionId ?? traceId,
646
+ hasCodebaseAccess: codeAwareMode !== 'off' && codebaseIds.length > 0,
647
+ };
621
648
  /** Normalize skill params: ensure process_name ↔ package are both set. */
622
649
  function normalizeSkillParams(params, defaultPackage) {
623
650
  const p = { ...params };
@@ -2295,13 +2322,50 @@ function createClaudeMcpServer(options) {
2295
2322
  'When the result carries `unsupportedReason` (license_blocked, index empty), the agent must say the source is unavailable and must NOT summarize, paraphrase, or invent content.', {
2296
2323
  query: zod_1.z.string().describe('Search query — typically a function or class name, or a behavior description.'),
2297
2324
  top_k: zod_1.z.number().int().min(1).max(20).optional().describe('Maximum hits returned (1-20, default 5).'),
2298
- }, async ({ query, top_k }) => {
2325
+ codebase_id: zod_1.z.string().optional().describe('Optional whitelisted registered AOSP codebase id.'),
2326
+ build_id: zod_1.z.string().optional().describe('Optional native build id filter.'),
2327
+ symbol: zod_1.z.string().optional().describe('Exact symbol filter when known.'),
2328
+ path_prefix: zod_1.z.string().optional().describe('Optional relative source path prefix.'),
2329
+ }, async ({ query, top_k, codebase_id, build_id, symbol, path_prefix }) => {
2330
+ const codebaseId = normalizeOptionalToolString(codebase_id);
2331
+ const buildId = normalizeOptionalToolString(build_id);
2332
+ const symbolExact = normalizeOptionalToolString(symbol);
2333
+ const pathPrefix = normalizeOptionalToolString(path_prefix);
2334
+ if (codebaseId && !codebaseIds.includes(codebaseId)) {
2335
+ return {
2336
+ content: [{ type: 'text', text: JSON.stringify({ success: false, error: 'Requested codebase is not whitelisted for this session' }) }],
2337
+ isError: true,
2338
+ };
2339
+ }
2299
2340
  const store = getRagStore();
2300
2341
  const result = store.search(query, {
2301
2342
  topK: top_k ?? 5,
2302
2343
  kinds: ['aosp'],
2344
+ ...(codebaseId ? { codebaseIds: [codebaseId] } : {}),
2345
+ ...(buildId ? { buildId } : {}),
2346
+ ...(symbolExact ? { symbolExact } : {}),
2347
+ ...(pathPrefix ? { pathPrefix } : {}),
2303
2348
  scope: knowledgeScope,
2304
2349
  });
2350
+ if (result.results.some(hit => hit.chunk?.registryOrigin === 'codebase_registry')) {
2351
+ const scopedResult = {
2352
+ ...result,
2353
+ results: result.results.filter(hit => hit.chunk?.registryOrigin !== 'codebase_registry' ||
2354
+ (hit.chunk.codebaseId && codebaseIds.includes(hit.chunk.codebaseId))),
2355
+ };
2356
+ const filtered = await (0, lookupResponseFilter_1.filterRagLookup)(scopedResult, {
2357
+ toolName: 'lookup_aosp_source',
2358
+ turn: 0,
2359
+ codebaseRegistry,
2360
+ ledger: codeLookupLedger,
2361
+ allowProviderSend: codeAwareMode === 'provider_send',
2362
+ sessionId: options.sessionId,
2363
+ });
2364
+ await codeLookupLedger?.flush();
2365
+ return {
2366
+ content: [{ type: 'text', text: JSON.stringify({ success: true, result: filtered }) }],
2367
+ };
2368
+ }
2305
2369
  return {
2306
2370
  content: [{ type: 'text', text: JSON.stringify(result) }],
2307
2371
  };
@@ -2314,17 +2378,254 @@ function createClaudeMcpServer(options) {
2314
2378
  'Read-only over the RagStore. When the result carries `unsupportedReason` (license_blocked, index empty), the agent must say the source is unavailable and must NOT summarize or invent.', {
2315
2379
  query: zod_1.z.string().describe('Search query — typically a tuning concept or vendor-specific knob.'),
2316
2380
  top_k: zod_1.z.number().int().min(1).max(20).optional().describe('Maximum hits returned (1-20, default 5).'),
2317
- }, async ({ query, top_k }) => {
2381
+ codebase_id: zod_1.z.string().optional().describe('Optional whitelisted registered OEM codebase id.'),
2382
+ vendor: zod_1.z.string().optional().describe('Optional vendor filter.'),
2383
+ }, async ({ query, top_k, codebase_id, vendor }) => {
2384
+ const codebaseId = normalizeOptionalToolString(codebase_id);
2385
+ const vendorId = normalizeOptionalToolString(vendor);
2386
+ if (codebaseId && !codebaseIds.includes(codebaseId)) {
2387
+ return {
2388
+ content: [{ type: 'text', text: JSON.stringify({ success: false, error: 'Requested codebase is not whitelisted for this session' }) }],
2389
+ isError: true,
2390
+ };
2391
+ }
2318
2392
  const store = getRagStore();
2319
2393
  const result = store.search(query, {
2320
2394
  topK: top_k ?? 5,
2321
2395
  kinds: ['oem_sdk'],
2396
+ ...(codebaseId ? { codebaseIds: [codebaseId] } : {}),
2397
+ ...(vendorId ? { vendor: vendorId } : {}),
2322
2398
  scope: knowledgeScope,
2323
2399
  });
2400
+ if (result.results.some(hit => hit.chunk?.registryOrigin === 'codebase_registry')) {
2401
+ const scopedResult = {
2402
+ ...result,
2403
+ results: result.results.filter(hit => hit.chunk?.registryOrigin !== 'codebase_registry' ||
2404
+ (hit.chunk.codebaseId && codebaseIds.includes(hit.chunk.codebaseId))),
2405
+ };
2406
+ const filtered = await (0, lookupResponseFilter_1.filterRagLookup)(scopedResult, {
2407
+ toolName: 'lookup_oem_sdk',
2408
+ turn: 0,
2409
+ codebaseRegistry,
2410
+ ledger: codeLookupLedger,
2411
+ allowProviderSend: codeAwareMode === 'provider_send',
2412
+ sessionId: options.sessionId,
2413
+ });
2414
+ await codeLookupLedger?.flush();
2415
+ return {
2416
+ content: [{ type: 'text', text: JSON.stringify({ success: true, result: filtered }) }],
2417
+ };
2418
+ }
2324
2419
  return {
2325
2420
  content: [{ type: 'text', text: JSON.stringify(result) }],
2326
2421
  };
2327
2422
  }, { annotations: { readOnlyHint: true } });
2423
+ const listCodebases = (0, claude_agent_sdk_1.tool)('list_codebases', 'List the app/AOSP/kernel/OEM codebases explicitly whitelisted for this analysis session. ' +
2424
+ 'Returns metadata only; it never exposes local root paths.', {}, async () => {
2425
+ const allowed = new Set(codebaseIds);
2426
+ const codebases = codebaseRegistry.list()
2427
+ .filter(ref => allowed.has(ref.codebaseId))
2428
+ .map(ref => ({
2429
+ codebaseId: ref.codebaseId,
2430
+ kind: ref.kind,
2431
+ displayName: ref.displayName,
2432
+ indexGeneration: ref.indexGeneration,
2433
+ chunkCount: ref.chunkCount,
2434
+ eligibleForSendToProvider: ref.eligibleForSendToProvider,
2435
+ }));
2436
+ return {
2437
+ content: [{ type: 'text', text: JSON.stringify({ success: true, codebases }) }],
2438
+ };
2439
+ }, { annotations: { readOnlyHint: true } });
2440
+ const lookupAppSource = (0, claude_agent_sdk_1.tool)('lookup_app_source', 'Look up registered app source chunks for this analysis session. ' +
2441
+ 'Only whitelisted codebase IDs are accepted. In metadata_only mode the result carries file/symbol references without snippets.', {
2442
+ query: zod_1.z.string().describe('Natural-language query, symbol, class, method, or file term.'),
2443
+ top_k: zod_1.z.number().int().min(1).max(20).optional().describe('Maximum hits returned (1-20, default 5).'),
2444
+ codebase_id: zod_1.z.string().optional().describe('Restrict to one whitelisted codebase id. Defaults to all session codebases.'),
2445
+ symbol: zod_1.z.string().optional().describe('Exact symbol filter when known.'),
2446
+ file_path: zod_1.z.string().optional().describe('Exact source file path relative to the registered root.'),
2447
+ path_prefix: zod_1.z.string().optional().describe('Restrict lookup to a relative path prefix.'),
2448
+ }, async ({ query, top_k, codebase_id, symbol, file_path, path_prefix }) => {
2449
+ const codebaseId = normalizeOptionalToolString(codebase_id);
2450
+ const symbolExact = normalizeOptionalToolString(symbol);
2451
+ const filePath = normalizeOptionalToolString(file_path);
2452
+ const pathPrefix = normalizeOptionalToolString(path_prefix);
2453
+ const requestedIds = codebaseId ? [codebaseId] : codebaseIds;
2454
+ const allowed = requestedIds.filter(id => codebaseIds.includes(id));
2455
+ if (allowed.length === 0) {
2456
+ return {
2457
+ content: [{
2458
+ type: 'text',
2459
+ text: JSON.stringify({ success: false, error: 'No requested codebase is whitelisted for this session' }),
2460
+ }],
2461
+ isError: true,
2462
+ };
2463
+ }
2464
+ const raw = getRagStore().search(query, {
2465
+ topK: top_k ?? 5,
2466
+ kinds: ['app_source'],
2467
+ codebaseIds: allowed,
2468
+ ...(symbolExact ? { symbolExact } : {}),
2469
+ ...(filePath ? { filePathExact: filePath } : {}),
2470
+ ...(pathPrefix ? { pathPrefix } : {}),
2471
+ scope: knowledgeScope,
2472
+ });
2473
+ const filtered = await (0, lookupResponseFilter_1.filterRagLookup)(raw, {
2474
+ toolName: 'lookup_app_source',
2475
+ turn: 0,
2476
+ codebaseRegistry,
2477
+ ledger: codeLookupLedger,
2478
+ allowProviderSend: codeAwareMode === 'provider_send',
2479
+ sessionId: options.sessionId,
2480
+ });
2481
+ await codeLookupLedger?.flush();
2482
+ return {
2483
+ content: [{ type: 'text', text: JSON.stringify({ success: true, result: filtered }) }],
2484
+ };
2485
+ }, { annotations: { readOnlyHint: true } });
2486
+ const lookupKernelSource = (0, claude_agent_sdk_1.tool)('lookup_kernel_source', 'Use when kernel/vendor source evidence is needed after trace evidence points at binder, scheduler, mm, io, or a kernel symbol. ' +
2487
+ 'Do NOT use for app or AOSP framework code. Prerequisites: a whitelisted kernel_source codebase, vendor or codebase_id, and a path_prefix/subsys. ' +
2488
+ 'Budget: top_k is capped at 20 and metadata_only sessions return CodeRef metadata without snippets. Outcomes: source hits, metadata-only hits, or an explicit unsupportedReason.', {
2489
+ query: zod_1.z.string().describe('Kernel symbol, subsystem, or behavior query.'),
2490
+ top_k: zod_1.z.number().int().min(1).max(20).optional().describe('Maximum hits returned (1-20, default 5).'),
2491
+ codebase_id: zod_1.z.string().optional().describe('Restrict to one whitelisted kernel codebase id.'),
2492
+ vendor: zod_1.z.string().optional().describe('Vendor id. Required when multiple kernel codebases are available and codebase_id is omitted.'),
2493
+ symbol: zod_1.z.string().optional().describe('Exact symbol filter when known.'),
2494
+ path_prefix: zod_1.z.string().optional().describe('Required subsystem path prefix, for example drivers/android/binder.'),
2495
+ }, async ({ query, top_k, codebase_id, vendor, symbol, path_prefix }) => {
2496
+ const codebaseId = normalizeOptionalToolString(codebase_id);
2497
+ const vendorId = normalizeOptionalToolString(vendor);
2498
+ const symbolExact = normalizeOptionalToolString(symbol);
2499
+ const pathPrefix = normalizeOptionalToolString(path_prefix);
2500
+ const requestedIds = codebaseId ? [codebaseId] : codebaseIds;
2501
+ const allowed = requestedIds.filter(id => codebaseIds.includes(id));
2502
+ if (allowed.length === 0) {
2503
+ return {
2504
+ content: [{
2505
+ type: 'text',
2506
+ text: JSON.stringify({ success: false, error: 'No requested codebase is whitelisted for this session' }),
2507
+ }],
2508
+ isError: true,
2509
+ };
2510
+ }
2511
+ const kernelRefs = allowed
2512
+ .map(id => codebaseRegistry.get(id))
2513
+ .filter(ref => ref?.kind === 'kernel_source');
2514
+ const vendors = new Set(kernelRefs.map(ref => ref.vendor).filter(Boolean));
2515
+ if (!codebaseId && !vendorId && vendors.size > 1) {
2516
+ return {
2517
+ content: [{ type: 'text', text: JSON.stringify({
2518
+ success: false,
2519
+ unsupportedReason: 'vendor_required_for_multi_vendor_kernel_lookup',
2520
+ vendors: Array.from(vendors).sort(),
2521
+ }) }],
2522
+ isError: true,
2523
+ };
2524
+ }
2525
+ const raw = getRagStore().search(query, {
2526
+ topK: top_k ?? 5,
2527
+ kinds: ['kernel_source'],
2528
+ codebaseIds: kernelRefs.map(ref => ref.codebaseId),
2529
+ ...(vendorId ? { vendor: vendorId } : {}),
2530
+ ...(symbolExact ? { symbolExact } : {}),
2531
+ ...(pathPrefix ? { pathPrefix } : {}),
2532
+ scope: knowledgeScope,
2533
+ });
2534
+ const filtered = await (0, lookupResponseFilter_1.filterRagLookup)(raw, {
2535
+ toolName: 'lookup_kernel_source',
2536
+ turn: 0,
2537
+ codebaseRegistry,
2538
+ ledger: codeLookupLedger,
2539
+ allowProviderSend: codeAwareMode === 'provider_send',
2540
+ sessionId: options.sessionId,
2541
+ });
2542
+ await codeLookupLedger?.flush();
2543
+ return {
2544
+ content: [{ type: 'text', text: JSON.stringify({ success: true, result: filtered }) }],
2545
+ };
2546
+ }, { annotations: { readOnlyHint: true } });
2547
+ const resolveSymbol = (0, claude_agent_sdk_1.tool)('resolve_symbol', 'Use when trace frames or obfuscated names must be resolved to CodeRef metadata before source lookup. ' +
2548
+ 'Do NOT use to guess file:line when build_id is missing; return the degraded result instead. ' +
2549
+ 'Prerequisites: whitelisted codebase ids and indexed source/symbol metadata. Budget: top_k capped at 20. Outcomes: app, native/AOSP, or kernel candidates with degradation reasons.', {
2550
+ symbol: zod_1.z.string().describe('Class, function, or method name to resolve.'),
2551
+ kind: zod_1.z.enum(['app', 'native', 'kernel']).optional().describe('Resolution domain; default app.'),
2552
+ codebase_id: zod_1.z.string().optional().describe('Restrict to one whitelisted codebase id. Defaults to all session codebases.'),
2553
+ file_path: zod_1.z.string().optional().describe('Optional relative source file path for fallback matching.'),
2554
+ build_id: zod_1.z.string().optional().describe('Optional build id. Missing build id returns a degraded result.'),
2555
+ vendor: zod_1.z.string().optional().describe('Vendor id for kernel lookup.'),
2556
+ top_k: zod_1.z.number().int().min(1).max(20).optional().describe('Maximum candidates returned.'),
2557
+ }, async ({ symbol, kind, codebase_id, file_path, build_id, vendor, top_k }) => {
2558
+ const codebaseId = normalizeOptionalToolString(codebase_id);
2559
+ const filePath = normalizeOptionalToolString(file_path);
2560
+ const buildId = normalizeOptionalToolString(build_id);
2561
+ const vendorId = normalizeOptionalToolString(vendor);
2562
+ const requestedIds = codebaseId ? [codebaseId] : codebaseIds;
2563
+ const allowed = requestedIds.filter(id => codebaseIds.includes(id));
2564
+ if (allowed.length === 0) {
2565
+ return {
2566
+ content: [{
2567
+ type: 'text',
2568
+ text: JSON.stringify({ success: false, error: 'No requested codebase is whitelisted for this session' }),
2569
+ }],
2570
+ isError: true,
2571
+ };
2572
+ }
2573
+ const resolver = new symbolResolver_1.SymbolResolver(getRagStore());
2574
+ const results = allowed.map(id => {
2575
+ const ref = codebaseRegistry.get(id);
2576
+ if (kind === 'kernel' || ref?.kind === 'kernel_source') {
2577
+ return resolver.resolveKernel({
2578
+ symbol,
2579
+ codebaseId: id,
2580
+ vendor: vendorId ?? ref?.vendor,
2581
+ ...(buildId ? { buildId } : {}),
2582
+ topK: top_k ?? 5,
2583
+ });
2584
+ }
2585
+ if (kind === 'native' || ref?.kind === 'aosp') {
2586
+ return resolver.resolveNative({
2587
+ symbol,
2588
+ codebaseId: id,
2589
+ ...(buildId ? { buildId } : {}),
2590
+ topK: top_k ?? 5,
2591
+ });
2592
+ }
2593
+ return resolver.resolveApp({
2594
+ symbol,
2595
+ codebaseId: id,
2596
+ ...(filePath ? { filePath } : {}),
2597
+ ...(buildId ? { buildId } : {}),
2598
+ topK: top_k ?? 5,
2599
+ });
2600
+ });
2601
+ return {
2602
+ content: [{ type: 'text', text: JSON.stringify({
2603
+ success: results.some(result => result.success),
2604
+ results,
2605
+ }) }],
2606
+ };
2607
+ }, { annotations: { readOnlyHint: true } });
2608
+ const proposePatch = (0, claude_agent_sdk_1.tool)('propose_patch', 'Use when the user asks for a concrete fix after successful code lookup. Do NOT use before lookup_app_source/lookup_kernel_source/lookup_aosp_source has returned prior contextChunkIds. ' +
2609
+ 'Prerequisites: all contextChunkIds must belong to one whitelisted codebase and provider_send consent must be enabled. Budget: patch attempts are capped by the session ledger. Outcomes: verified diff, non-copyable sketch, or unverified rejection.', {
2610
+ context_chunk_ids: zod_1.z.array(zod_1.z.string()).min(1).describe('Chunk ids previously returned by a successful source lookup in this session.'),
2611
+ problem: zod_1.z.string().describe('Performance problem the patch should address.'),
2612
+ proposed_diff: zod_1.z.string().optional().describe('Optional unified diff to validate. Only returned to the user if git apply --check passes.'),
2613
+ patch_sketch: zod_1.z.string().optional().describe('Optional high-level sketch when no verified diff is available.'),
2614
+ }, async ({ context_chunk_ids, problem, proposed_diff, patch_sketch }) => {
2615
+ const proposer = new patchProposer_1.PatchProposer(getRagStore(), codebaseRegistry, codeLookupLedger);
2616
+ const result = proposer.propose({
2617
+ contextChunkIds: context_chunk_ids,
2618
+ problem,
2619
+ ...(proposed_diff ? { proposedDiff: proposed_diff } : {}),
2620
+ ...(patch_sketch ? { patchSketch: patch_sketch } : {}),
2621
+ turn: 0,
2622
+ });
2623
+ await codeLookupLedger?.flush();
2624
+ return {
2625
+ content: [{ type: 'text', text: JSON.stringify({ success: result.patchStatus !== 'unverified', result }) }],
2626
+ ...(result.patchStatus === 'unverified' ? { isError: true } : {}),
2627
+ };
2628
+ }, { annotations: { readOnlyHint: false } });
2328
2629
  // recall_project_memory (Plan 44): pure-read recall over project +
2329
2630
  // world memory entries. Strict invariant: handler MUST NOT cause any
2330
2631
  // disk writes; ProjectMemory.recallProjectMemory() is enforced via
@@ -3498,6 +3799,11 @@ function createClaudeMcpServer(options) {
3498
3799
  registry.registerSdk(lookupBlogKnowledge, 'lookup_blog_knowledge', 'public');
3499
3800
  registry.registerSdk(lookupAospSource, 'lookup_aosp_source', 'public');
3500
3801
  registry.registerSdk(lookupOemSdk, 'lookup_oem_sdk', 'public');
3802
+ registry.registerSdk(listCodebases, 'list_codebases', 'requires_codebase_permission');
3803
+ registry.registerSdk(lookupAppSource, 'lookup_app_source', 'requires_codebase_permission');
3804
+ registry.registerSdk(lookupKernelSource, 'lookup_kernel_source', 'requires_codebase_permission');
3805
+ registry.registerSdk(resolveSymbol, 'resolve_symbol', 'requires_codebase_permission');
3806
+ registry.registerSdk(proposePatch, 'propose_patch', 'requires_codebase_permission');
3501
3807
  registry.registerSdk(lookupBaseline, 'lookup_baseline', 'public');
3502
3808
  registry.registerSdk(compareBaselines, 'compare_baselines', 'public');
3503
3809
  registry.registerSdk(recallProjectMemory, 'recall_project_memory', 'public');
@@ -3534,9 +3840,9 @@ function createClaudeMcpServer(options) {
3534
3840
  registry.registerSdk(getComparisonContext, 'get_comparison_context', 'internal');
3535
3841
  }
3536
3842
  return {
3537
- server: registry.buildSdkServer(),
3538
- allowedTools: registry.buildAllowedTools(),
3539
- toolDefinitions: registry.list(),
3843
+ server: registry.buildSdkServer({ scope: toolRequestScope }),
3844
+ allowedTools: registry.buildAllowedTools(toolRequestScope),
3845
+ toolDefinitions: registry.listForRequest(toolRequestScope),
3540
3846
  };
3541
3847
  }
3542
3848
  function evidenceHash(input) {