feat(javascript): return a retained summary view on request (#1568)

analyze_javascript_application returns the complete application graph
inline, which repeats tens of kilobytes even for a few source lines and
exceeds the default 10 MiB MCP frame for a 300-function source file.

The new optional detail input keeps complete delivery by default. With
detail "summary" the server records the complete analysis Evidence in
the session and returns its inspect_analysis_view summary, whose
parent_evidence_id lets callers page modules, select items, or pass the
retained reference to application workflows. A server without Evidence
retention refuses summary detail with capability_unavailable rather
than returning a summary whose analysis cannot be reached.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kaoru0822andClaude Opus 5.5 authored and GitHub committed 2026-10-10 07:37:37 -07:00
1 parent 649661dc8b
commit c19e15a2b3
9 files changed
+279 -7

No files matched your search

+1
View File
@@ -468,6 +468,7 @@ const registerObservationTools = ({
});
registerElectronTools(server, {
...common,
evidenceById,
electron: options.electronObservation,
electronActive: options.electronActiveObservation,
observationLoadFailure:
+12 -2
View File
@@ -1,5 +1,7 @@
import type { ToolResultDelivery } from "./toolResult.js";
import type { EvidenceMcpServer } from "./EvidenceMcpServer.js";
import { summarizeRetainedAnalysis } from "../application/analysisView/AnalysisViewService.js";
import type { EvidenceLookup } from "../application/EvidenceInputResolver.js";
import type { EvidenceWriter } from "../application/investigation/InvestigationRecordPort.js";
import {
optionalProviderUnavailable,
@@ -36,6 +38,7 @@ interface ElectronToolRegistration {
readonly electron: ElectronObservationPort | undefined;
readonly electronActive: ElectronActiveObservationPort | undefined;
readonly recordEvidence: EvidenceWriter["recordEvidence"] | undefined;
readonly evidenceById: EvidenceLookup | undefined;
}
interface ElectronToolContext {
@@ -95,8 +98,15 @@ export const registerElectronTools = (
registration,
analyzeContract,
{ input, context },
(parsed, { signal, progress }) =>
analyzeJavaScriptApplicationValidated(parsed, { signal, progress }),
async ({ detail, ...request }, { signal, progress }) => {
const analyzed = await analyzeJavaScriptApplicationValidated(
request,
{ signal, progress },
);
return detail === "summary" && analyzed.ok
? summarizeRetainedAnalysis(analyzed.value, options)
: analyzed;
},
),
);
server.registerTool(