rea-agents 3.0.0 → 3.1.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 (219) hide show
  1. package/README.md +14 -16
  2. package/dist/application/AnalysisContextQueries.js +21 -9
  3. package/dist/application/ApplicationWorkflowEvidenceResolver.js +19 -11
  4. package/dist/application/ArtifactInventory/policy.js +17 -0
  5. package/dist/application/ArtifactInventory/reader.js +1 -4
  6. package/dist/application/ArtifactInventory/scanCanonical.js +0 -3
  7. package/dist/application/ArtifactInventory/scanReader.js +7 -7
  8. package/dist/application/ArtifactInventory/types.js +1 -5
  9. package/dist/application/BinarySession.js +14 -16
  10. package/dist/application/BinarySessionRecords.js +31 -5
  11. package/dist/application/BinarySessionStatus.js +11 -5
  12. package/dist/application/BrowserEvidence.js +3 -5
  13. package/dist/application/CapabilityClientRequirements.js +26 -0
  14. package/dist/application/CapabilityInventory.js +134 -63
  15. package/dist/application/CrossVersionInventory.js +7 -6
  16. package/dist/application/ElectronActiveEvidence.js +55 -0
  17. package/dist/application/ElectronActiveObservationPort.js +1 -0
  18. package/dist/application/ElectronActiveObservationService.js +81 -0
  19. package/dist/application/EnhancedTools.js +22 -20
  20. package/dist/application/EvidenceBundleCommands.js +5 -1
  21. package/dist/application/EvidenceLedger.js +8 -1
  22. package/dist/application/JavaScriptReplayPermission.js +1 -1
  23. package/dist/application/JavaScriptReplayService.js +23 -15
  24. package/dist/application/ManagedRuntimeCorrelationService.js +9 -5
  25. package/dist/application/NodeRuntimeCharacterizationService.js +8 -9
  26. package/dist/application/ProcessCaptureLifecycle.js +5 -0
  27. package/dist/application/ProcessCli.js +2 -1
  28. package/dist/application/ProcessHarness.js +8 -3
  29. package/dist/application/ProcessNormalization.js +2 -1
  30. package/dist/application/ProjectPermissionStore.js +1 -0
  31. package/dist/application/ReferenceSourceImport.js +2 -2
  32. package/dist/application/SetupClientConfiguration.js +6 -1
  33. package/dist/application/WindowsCapabilities.js +5 -4
  34. package/dist/artifacts/ArtifactProvider.js +8 -10
  35. package/dist/artifacts/SafeOutputTree.js +7 -8
  36. package/dist/browser/CdpCaptureStorageFingerprints.js +10 -7
  37. package/dist/browser/CdpElectronInspection.js +3 -1
  38. package/dist/browser/JavaScriptRuntimeScope.js +5 -0
  39. package/dist/browser/PlaywrightElectronActiveActions.js +324 -0
  40. package/dist/browser/PlaywrightElectronActiveProvider.js +294 -0
  41. package/dist/browser/PlaywrightScenarioBrowser.js +4 -4
  42. package/dist/browser/PlaywrightScenarioSession.js +4 -4
  43. package/dist/browser/SensitiveTextCapture.js +1 -1
  44. package/dist/browser/V8InspectorCaptureProjection.js +1 -0
  45. package/dist/browser/V8InspectorProvider.js +3 -3
  46. package/dist/catalogIdentity.js +12 -6
  47. package/dist/cli/managedCommands.js +1 -1
  48. package/dist/cliApplicationCommands.js +2 -2
  49. package/dist/cliBrowserAdvancedCommands.js +11 -5
  50. package/dist/cliBrowserCommands.js +14 -7
  51. package/dist/cliCommandNames.js +1 -0
  52. package/dist/cliElectronCommands.js +46 -4
  53. package/dist/cliJavaScriptRuntimeCommands.js +14 -6
  54. package/dist/cliObservationOptions.js +4 -0
  55. package/dist/cliPolicyCommands.js +1 -0
  56. package/dist/config/browserScenario.js +77 -0
  57. package/dist/config/electronAutomation.js +35 -0
  58. package/dist/config/environment.js +6 -0
  59. package/dist/config/javascriptReplay.js +41 -0
  60. package/dist/config/managedRuntime.js +25 -0
  61. package/dist/config/parseConfig.js +56 -200
  62. package/dist/config/parsers.js +10 -1
  63. package/dist/config/passiveObservation.js +157 -0
  64. package/dist/config/processCapture.js +47 -0
  65. package/dist/contracts/applicationToolContracts.js +2 -5
  66. package/dist/contracts/applicationWorkflowInputContracts.js +86 -96
  67. package/dist/contracts/artifactToolContracts.js +27 -34
  68. package/dist/contracts/browserToolContracts.js +2 -2
  69. package/dist/contracts/electronToolContracts.js +30 -1
  70. package/dist/contracts/enhancedInputs.js +13 -29
  71. package/dist/contracts/functionWorkflowToolContracts.js +2 -3
  72. package/dist/contracts/managedToolContracts.js +4 -9
  73. package/dist/contracts/managedWorkflowExamples.js +12 -9
  74. package/dist/contracts/managedWorkflowToolContracts.js +30 -27
  75. package/dist/contracts/nativeToolContracts.js +2 -3
  76. package/dist/contracts/sessionToolSchemas.js +61 -0
  77. package/dist/contracts/toolContractExamples.js +1 -0
  78. package/dist/contracts/toolContractHelpers.js +23 -0
  79. package/dist/contracts/toolContracts.js +5 -77
  80. package/dist/contracts/toolEffects.js +15 -0
  81. package/dist/contracts/toolOutputSchemaGroups.js +17 -2
  82. package/dist/contracts/toolOutputSchemaPrimitives.js +76 -26
  83. package/dist/contracts/toolSchemaMetadata.js +128 -0
  84. package/dist/doctorRuntime.js +1 -1
  85. package/dist/domain/androidApplication.js +2 -0
  86. package/dist/domain/appleApplication.js +2 -0
  87. package/dist/domain/binaryTarget.js +7 -5
  88. package/dist/domain/binaryTargetTypes.js +1 -0
  89. package/dist/domain/browserCaptureComparison.js +21 -69
  90. package/dist/domain/browserObservation.js +22 -9
  91. package/dist/domain/bytecodeProvider.js +33 -35
  92. package/dist/domain/callPath.js +3 -2
  93. package/dist/domain/conformanceReplay.js +3 -3
  94. package/dist/domain/conformanceTrustGate.js +151 -16
  95. package/dist/domain/customProtocolCapture.js +3 -3
  96. package/dist/domain/electronActiveObservation.js +277 -0
  97. package/dist/domain/electronObservation.js +15 -11
  98. package/dist/domain/electronStaticAnalysisValues.js +4 -1
  99. package/dist/domain/eventProcessTree.js +82 -79
  100. package/dist/domain/functionComparisonNormalization.js +15 -8
  101. package/dist/domain/functionDossierEvidence.js +9 -4
  102. package/dist/domain/hopperValues.js +68 -71
  103. package/dist/domain/inputIssueProjection.js +4 -1
  104. package/dist/domain/investigationWorkspace.js +16 -15
  105. package/dist/domain/javascriptExportShapeComparisonSchemas.js +2 -2
  106. package/dist/domain/javascriptReplay.js +79 -63
  107. package/dist/domain/javascriptRuntimeObservation.js +1 -0
  108. package/dist/domain/javascriptRuntimeReconciliationActive.js +89 -0
  109. package/dist/domain/javascriptRuntimeReconciliationGraph.js +11 -10
  110. package/dist/domain/javascriptRuntimeReconciliationMatching.js +57 -49
  111. package/dist/domain/javascriptRuntimeReconciliationParsing.js +5 -1
  112. package/dist/domain/javascriptRuntimeReconciliationResult.js +21 -14
  113. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
  114. package/dist/domain/knownPageCoverage.js +15 -7
  115. package/dist/domain/nativeApiBoundary.js +15 -7
  116. package/dist/domain/nodeRuntimeCharacterization.js +14 -13
  117. package/dist/domain/processCaptureReactiveValidation.js +8 -3
  118. package/dist/domain/processCaptureValidation.js +7 -3
  119. package/dist/domain/processComparison.js +12 -7
  120. package/dist/domain/processObservation.js +5 -6
  121. package/dist/domain/processReactiveMatching.js +14 -7
  122. package/dist/domain/processReactiveTransition.js +9 -3
  123. package/dist/domain/processScenario.js +6 -3
  124. package/dist/domain/processTraceComparison.js +3 -2
  125. package/dist/domain/protocolCapture.js +8 -6
  126. package/dist/domain/reconstructionReadinessSchemas.js +30 -2
  127. package/dist/domain/referenceSourceImportParsing.js +2 -2
  128. package/dist/domain/replayMachineRuntime.js +5 -3
  129. package/dist/domain/sourceToBundleComparison.js +2 -2
  130. package/dist/domain/sourceToBundleComparisonSchemas.js +8 -8
  131. package/dist/domain/sourceToBundleSignals.js +7 -1
  132. package/dist/domain/staticRuntimeCorrelation.js +7 -5
  133. package/dist/domain/webBundleAnalysis.js +14 -14
  134. package/dist/domain/webCaptureDiff.js +15 -12
  135. package/dist/dotnet/ManagedNativeBoundaryInspector.js +2 -3
  136. package/dist/generatedMcpToolCatalog.js +1 -1
  137. package/dist/generatedPackageMetadata.js +1 -1
  138. package/dist/ghidra/GhidraClient.js +1 -1
  139. package/dist/ghidra/GhidraClientStartup.js +1 -1
  140. package/dist/ghidra/GhidraFunctionValues.js +17 -15
  141. package/dist/ghidra/GhidraInventoryValues.js +57 -47
  142. package/dist/ghidra/GhidraProvider.js +18 -10
  143. package/dist/ghidra/GhidraProviderCapabilities.js +5 -1
  144. package/dist/ghidra/GhidraSocketConnection.js +1 -1
  145. package/dist/ghidra/protocol.js +19 -42
  146. package/dist/hopper/BridgeLauncher.js +3 -1
  147. package/dist/hopper/HopperAnalysisProfile.js +2 -4
  148. package/dist/hopper/HopperCleanup.js +5 -6
  149. package/dist/hopper/HopperClient.js +1 -1
  150. package/dist/hopper/HopperProvider.js +0 -14
  151. package/dist/hopper/LinuxPrivateDisplayProbe.js +16 -10
  152. package/dist/main/reload.js +1 -6
  153. package/dist/main/state.js +0 -14
  154. package/dist/main/transport.js +30 -37
  155. package/dist/main.js +17 -15
  156. package/dist/mcpDoctor.js +2 -24
  157. package/dist/process/PrivateRuntimeRoot.js +17 -0
  158. package/dist/process/ProcessOwnership.js +64 -128
  159. package/dist/process/ProcessOwnershipIdentity.js +13 -0
  160. package/dist/process/ProcessOwnershipObservation.js +88 -0
  161. package/dist/process/ProcessOwnershipProcessTree.js +22 -0
  162. package/dist/process/ProviderDeadline.js +8 -12
  163. package/dist/process/WindowsAuthority.js +32 -0
  164. package/dist/reference/ReferenceSourceReader.js +3 -3
  165. package/dist/reference/ReferenceSourceReaderEntries.js +2 -2
  166. package/dist/replay/JavaScriptReplayWorker.js +95 -11
  167. package/dist/replay/JavaScriptReplayWorkerTypes.js +1 -0
  168. package/dist/replay/LinuxJavaScriptReplayRunner.js +10 -15
  169. package/dist/replay/ReplayOutcome.js +26 -15
  170. package/dist/replay/ReplayWorkerProtocol.js +34 -29
  171. package/dist/server/createServer.js +158 -94
  172. package/dist/server/mcpClientMetadata.js +32 -0
  173. package/dist/server/registerApplicationTools/characterization.js +6 -13
  174. package/dist/server/registerApplicationTools/compareExportShapes.js +2 -7
  175. package/dist/server/registerApplicationTools/compareSourceToBundle.js +2 -7
  176. package/dist/server/registerApplicationTools/compareVersions.js +3 -8
  177. package/dist/server/registerApplicationTools/controlledReplay.js +6 -11
  178. package/dist/server/registerApplicationTools/coverage.js +13 -19
  179. package/dist/server/registerApplicationTools/obligationLedger.js +1 -6
  180. package/dist/server/registerApplicationTools/readiness.js +1 -6
  181. package/dist/server/registerApplicationTools/traceFeature.js +3 -8
  182. package/dist/server/registerApplicationTools/traceSemantics.js +1 -6
  183. package/dist/server/registerArtifactComparisonTool.js +12 -16
  184. package/dist/server/registerBrowserScenarioTool.js +1 -6
  185. package/dist/server/registerBrowserTools.js +37 -79
  186. package/dist/server/registerBundleComparisonTool.js +10 -14
  187. package/dist/server/registerCloseLifecycleTool.js +6 -14
  188. package/dist/server/registerElectronTools.js +30 -47
  189. package/dist/server/registerEnhancedTools.js +114 -122
  190. package/dist/server/registerEvidenceTools.js +5 -9
  191. package/dist/server/registerFunctionComparisonTool.js +11 -15
  192. package/dist/server/registerInvestigationTools.js +41 -57
  193. package/dist/server/registerJavaScriptRuntimeObservationTools.js +13 -27
  194. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -9
  195. package/dist/server/registerManagedWorkflowTools/contract.js +2 -3
  196. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -8
  197. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +3 -8
  198. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +8 -13
  199. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +4 -9
  200. package/dist/server/registerOfficialTools.js +8 -9
  201. package/dist/server/registerProcessComparisonTool.js +19 -24
  202. package/dist/server/registerReplayMachineTool.js +4 -10
  203. package/dist/server/registerSessionRecordTools.js +69 -40
  204. package/dist/server/registerSessionStatusTool.js +13 -28
  205. package/dist/server/registerSessionTools.js +36 -52
  206. package/dist/server/sessionAvailabilityPolicy.js +2 -1
  207. package/dist/server/sessionToolPolicies.js +1 -5
  208. package/dist/server/toolRegistrationOptions.js +4 -192
  209. package/dist/server/toolResult.js +2 -18
  210. package/package.json +22 -14
  211. package/scripts/electron-active-hook-boundaries.cjs +394 -0
  212. package/scripts/electron-active-hook.cjs +501 -0
  213. package/scripts/rea.mjs +1 -11
  214. package/skills/reverse-engineer-anything/SKILL.md +2 -2
  215. package/dist/server/DynamicToolAvailability.js +0 -70
  216. package/dist/server/LazyToolCatalog.js +0 -134
  217. package/dist/server/hydrateServerTools.js +0 -191
  218. package/dist/server/toolInputValidation.js +0 -77
  219. package/scripts/package-runner-bootstrap.mjs +0 -72
@@ -0,0 +1,61 @@
1
+ import { z } from "zod";
2
+ import { artifactComparisonInputSchema } from "../domain/artifactComparison.js";
3
+ import { bundleComparisonInputSchema } from "../domain/bundleComparison.js";
4
+ import { callPathInputSchema } from "../domain/callPath.js";
5
+ import { changedBehaviorInputSchema } from "../domain/changedBehavior.js";
6
+ import { functionComparisonInputSchema } from "../domain/functionComparison.js";
7
+ import { jsonValueSchema } from "../domain/jsonValue.js";
8
+ import { processScenarioSchema } from "../domain/processCapture.js";
9
+ import { processTraceSpecificationSchema } from "../domain/processTraceComparison.js";
10
+ import { recordUnknownInputSchema } from "../domain/residualUnknown.js";
11
+ import { reconstructionVerificationInputSchema } from "../domain/reconstructionVerification.js";
12
+ import { replayMachineRunInputSchema } from "../domain/replayMachineRun.js";
13
+ import { staticRuntimeCorrelationInputSchema } from "../domain/staticRuntimeCorrelation.js";
14
+ import { updateUnknownInputSchema } from "../domain/residualUnknown.js";
15
+ import { openBinaryInputSchema, closeBinaryInputSchema, } from "./sessionLifecycleInputs.js";
16
+ import { binarySessionInputSchema } from "./sessionStatusContract.js";
17
+ /** Retain the current canonical Evidence bundle as a session resource. */
18
+ export const snapshotEvidenceBundleInputSchema = z.strictObject({});
19
+ /** Release one session-retained immutable Evidence bundle. */
20
+ export const releaseEvidenceBundleInputSchema = z.strictObject({
21
+ bundle_digest: z.string().regex(/^[a-f0-9]{64}$/u),
22
+ });
23
+ /** Optional document selection for volatile navigation context. */
24
+ export const navigationContextInputSchema = z.strictObject({
25
+ document: z.string().min(1).optional(),
26
+ });
27
+ /** Explicit reproducible address context query. */
28
+ export const addressContextInputSchema = z.strictObject({
29
+ address: z.string().min(1),
30
+ document: z.string().min(1).optional(),
31
+ });
32
+ /** Session-owned Evidence bundle import options. */
33
+ export const importEvidenceBundleInputSchema = z.strictObject({
34
+ path: z.string().min(1),
35
+ });
36
+ /** Evidence references for deterministic process comparison. */
37
+ export const processComparisonInputSchema = z.strictObject({
38
+ left_evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u),
39
+ right_evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u),
40
+ trace_spec: processTraceSpecificationSchema.optional(),
41
+ max_capture_age_ms: z.number().int().nonnegative().optional(),
42
+ unknown_registry_approved: z
43
+ .literal(true)
44
+ .optional()
45
+ .describe("Explicit approval to record capture disagreement durably"),
46
+ });
47
+ /** Residual-unknown list filters. */
48
+ export const listUnknownsInputSchema = z.strictObject({
49
+ status: z
50
+ .enum(["open", "investigating", "blocked", "contradicted", "resolved"])
51
+ .optional(),
52
+ severity: z.enum(["low", "medium", "high", "critical"]).optional(),
53
+ domain: z.string().trim().min(1).max(100).optional(),
54
+ offset: z.number().int().min(0).default(0),
55
+ limit: z.number().int().min(1).max(500).default(100),
56
+ });
57
+ /** Exact residual-unknown identity to revalidate. */
58
+ export const verifyUnknownResolutionInputSchema = z.strictObject({
59
+ unknown_id: z.string().regex(/^unk_[a-f0-9]{64}$/u),
60
+ });
61
+ export { artifactComparisonInputSchema, binarySessionInputSchema, bundleComparisonInputSchema, callPathInputSchema, changedBehaviorInputSchema, closeBinaryInputSchema, functionComparisonInputSchema, jsonValueSchema, openBinaryInputSchema, processScenarioSchema, reconstructionVerificationInputSchema, recordUnknownInputSchema, replayMachineRunInputSchema, staticRuntimeCorrelationInputSchema, updateUnknownInputSchema, };
@@ -39,6 +39,7 @@ export const TOOL_EXAMPLE_OVERRIDES = {
39
39
  export_evidence_bundle: { path: "/tmp/evidence.json" },
40
40
  inspect_address_context: { address: "0x1000" },
41
41
  import_evidence_bundle: { path: "evidence.json" },
42
+ release_evidence_bundle: { bundle_digest: "a".repeat(64) },
42
43
  capture_process_scenario: {
43
44
  approved: true,
44
45
  executable: "/usr/bin/true",
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ import { jsonValueSchema } from "../domain/jsonValue.js";
3
+ import { TOOL_EXAMPLE_OVERRIDES } from "./toolContractExamples.js";
4
+ export const document = z.string().optional().describe("The document name");
5
+ export const address = z
6
+ .string()
7
+ .describe("A provider-normalized address; default memory uses 0x-prefixed hexadecimal");
8
+ export const optionalAddress = address.optional();
9
+ export const procedure = z.string().describe("The procedure name or address");
10
+ export const pagination = {
11
+ offset: z.number().int().min(0).default(0),
12
+ limit: z.number().int().min(1).max(500).default(100),
13
+ };
14
+ const exampleInputSchema = z.record(z.string(), jsonValueSchema);
15
+ export const examplesFor = (name, inputSchema) => {
16
+ const parsed = inputSchema.parse(TOOL_EXAMPLE_OVERRIDES[name] ?? {});
17
+ return [
18
+ {
19
+ title: `Example ${name.replaceAll("_", " ")} request`,
20
+ input: exampleInputSchema.parse(parsed),
21
+ },
22
+ ];
23
+ };
@@ -1,19 +1,6 @@
1
1
  import { z } from "zod";
2
- import { jsonValueSchema } from "../domain/jsonValue.js";
3
- import { processScenarioSchema } from "../domain/processCapture.js";
4
- import { recordUnknownInputSchema, updateUnknownInputSchema, } from "../domain/residualUnknown.js";
5
- import { artifactComparisonInputSchema } from "../domain/artifactComparison.js";
6
- import { functionComparisonInputSchema } from "../domain/functionComparison.js";
7
- import { bundleComparisonInputSchema } from "../domain/bundleComparison.js";
8
- import { changedBehaviorInputSchema } from "../domain/changedBehavior.js";
9
- import { callPathInputSchema } from "../domain/callPath.js";
10
- import { staticRuntimeCorrelationInputSchema } from "../domain/staticRuntimeCorrelation.js";
11
- import { reconstructionVerificationInputSchema } from "../domain/reconstructionVerification.js";
12
- import { replayMachineRunInputSchema } from "../domain/replayMachineRun.js";
13
- import { processTraceSpecificationSchema } from "../domain/processTraceComparison.js";
14
2
  import { enhancedInputSchemas } from "./enhancedInputs.js";
15
3
  import { enhancedOutputSchemas, officialOutputSchemas, requireOutputSchema, sessionOutputSchemas, } from "./toolOutputSchemas.js";
16
- import { TOOL_EXAMPLE_OVERRIDES } from "./toolContractExamples.js";
17
4
  import { NATIVE_TOOL_CONTRACTS } from "./nativeToolContracts.js";
18
5
  import { ARTIFACT_TOOL_CONTRACTS } from "./artifactToolContracts.js";
19
6
  import { MANAGED_TOOL_CONTRACTS } from "./managedToolContracts.js";
@@ -22,34 +9,14 @@ import { BROWSER_PROVIDER_TOOL_CONTRACTS } from "./browserProviderToolContracts.
22
9
  import { ELECTRON_TOOL_CONTRACTS } from "./electronToolContracts.js";
23
10
  import { JAVASCRIPT_RUNTIME_OBSERVATION_TOOL_CONTRACTS } from "./javascriptRuntimeObservationToolContracts.js";
24
11
  import { APPLICATION_TOOL_CONTRACTS } from "./applicationToolContracts.js";
25
- import { closeBinaryInputSchema, openBinaryInputSchema, } from "./sessionLifecycleInputs.js";
12
+ import { addressContextInputSchema, artifactComparisonInputSchema, binarySessionInputSchema, bundleComparisonInputSchema, callPathInputSchema, changedBehaviorInputSchema, closeBinaryInputSchema, functionComparisonInputSchema, importEvidenceBundleInputSchema, listUnknownsInputSchema, navigationContextInputSchema, openBinaryInputSchema, processComparisonInputSchema, processScenarioSchema, reconstructionVerificationInputSchema, recordUnknownInputSchema, releaseEvidenceBundleInputSchema, replayMachineRunInputSchema, snapshotEvidenceBundleInputSchema, staticRuntimeCorrelationInputSchema, updateUnknownInputSchema, verifyUnknownResolutionInputSchema, } from "./sessionToolSchemas.js";
13
+ import { address, document, examplesFor, optionalAddress, pagination, procedure, } from "./toolContractHelpers.js";
26
14
  import { toolContractMetadata } from "./toolEffects.js";
27
- import { binarySessionInputSchema } from "./sessionStatusContract.js";
28
15
  import { functionInstructionInputSchema } from "./functionInstructionContract.js";
29
16
  import { HOPPER_MEMORY_TOOL_DEFINITIONS } from "./hopperMemoryContracts.js";
30
17
  import { analysisSearchInput } from "./analysisSearchContract.js";
31
18
  import { FUNCTION_WORKFLOW_TOOL_CONTRACTS } from "./functionWorkflowToolContracts.js";
32
- export { binarySessionInputSchema } from "./sessionStatusContract.js";
33
- const document = z.string().optional().describe("The document name");
34
- const address = z
35
- .string()
36
- .describe("A provider-normalized address; default memory uses 0x-prefixed hexadecimal");
37
- const optionalAddress = address.optional();
38
- const procedure = z.string().describe("The procedure name or address");
39
- const pagination = {
40
- offset: z.number().int().min(0).default(0),
41
- limit: z.number().int().min(1).max(500).default(100),
42
- };
43
- const exampleInputSchema = z.record(z.string(), jsonValueSchema);
44
- const examplesFor = (name, inputSchema) => {
45
- const parsed = inputSchema.parse(TOOL_EXAMPLE_OVERRIDES[name] ?? {});
46
- return [
47
- {
48
- title: `Example ${name.replaceAll("_", " ")} request`,
49
- input: exampleInputSchema.parse(parsed),
50
- },
51
- ];
52
- };
19
+ export { addressContextInputSchema, binarySessionInputSchema, importEvidenceBundleInputSchema, listUnknownsInputSchema, navigationContextInputSchema, processComparisonInputSchema, releaseEvidenceBundleInputSchema, snapshotEvidenceBundleInputSchema, verifyUnknownResolutionInputSchema, } from "./sessionToolSchemas.js";
53
20
  const official = (name, description, inputSchema) => {
54
21
  const trackedInputSchema = inputSchema.extend({
55
22
  unknown_registry_approved: z
@@ -150,46 +117,6 @@ export const exportEvidenceBundleInputSchema = z.strictObject({
150
117
  path: z.string().min(1),
151
118
  overwrite: z.boolean().default(false),
152
119
  });
153
- /** Retain the current canonical Evidence bundle as a session resource. */
154
- export const snapshotEvidenceBundleInputSchema = z.strictObject({});
155
- /** Optional document selection for volatile navigation context. */
156
- export const navigationContextInputSchema = z.strictObject({
157
- document: z.string().min(1).optional(),
158
- });
159
- /** Explicit reproducible address context query. */
160
- export const addressContextInputSchema = z.strictObject({
161
- address: z.string().min(1),
162
- document: z.string().min(1).optional(),
163
- });
164
- /** Session-owned Evidence bundle import options. */
165
- export const importEvidenceBundleInputSchema = z.strictObject({
166
- path: z.string().min(1),
167
- });
168
- /** Evidence references for deterministic process comparison. */
169
- export const processComparisonInputSchema = z.strictObject({
170
- left_evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u),
171
- right_evidence_id: z.string().regex(/^ev_[a-f0-9]{64}$/u),
172
- trace_spec: processTraceSpecificationSchema.optional(),
173
- max_capture_age_ms: z.number().int().nonnegative().optional(),
174
- unknown_registry_approved: z
175
- .literal(true)
176
- .optional()
177
- .describe("Explicit approval to record capture disagreement durably"),
178
- });
179
- /** Residual-unknown list filters. */
180
- export const listUnknownsInputSchema = z.strictObject({
181
- status: z
182
- .enum(["open", "investigating", "blocked", "contradicted", "resolved"])
183
- .optional(),
184
- severity: z.enum(["low", "medium", "high", "critical"]).optional(),
185
- domain: z.string().trim().min(1).max(100).optional(),
186
- offset: z.number().int().min(0).default(0),
187
- limit: z.number().int().min(1).max(500).default(100),
188
- });
189
- /** Exact residual-unknown identity to revalidate. */
190
- export const verifyUnknownResolutionInputSchema = z.strictObject({
191
- unknown_id: z.string().regex(/^unk_[a-f0-9]{64}$/u),
192
- });
193
120
  /** Target lifecycle tools available only on the long-lived MCP adapter. */
194
121
  export const SESSION_TOOL_CONTRACTS = [
195
122
  session("open_binary", "Open a local executable, application bundle, archive, JavaScript, source map, plist, or analysis database after validation. provider_id selects one deep provider or deterministic auto selection; the binding remains stable until close or an explicit switch, with no failure fallback. An optional snapshot v2 is imported atomically and must match the binary identity, concrete provider, and canonical analysis profile exactly.", openBinaryInputSchema),
@@ -212,7 +139,8 @@ export const SESSION_TOOL_CONTRACTS = [
212
139
  session("verify_unknown_resolution", "Revalidate the current residual-unknown head against live bundled evidence, exact authority/confidence/environment requirements, and revision integrity. Withdrawn and out-of-scope dispositions are not truth claims.", verifyUnknownResolutionInputSchema),
213
140
  session("run_replay_machine", "Evaluate ordered HTTP and WebSocket events directly against one validated finite replay machine without opening sockets or launching a target. Returns every decision, a capture-value-free transition journal, one redacted action table entry per used transition, captured aliases, final state, and exact configured and consumed limits.", replayMachineRunInputSchema),
214
141
  session("snapshot_evidence_bundle", "Retain the current canonical Evidence v2 bundle as an immutable session resource. Returns a compact digest summary and exact opaque URI; copy that URI unchanged and call MCP resources/read (Codex: read_mcp_resource) for the full bundle. Repeating an unchanged snapshot is idempotent.", snapshotEvidenceBundleInputSchema),
215
- session("get_navigation_context", "Return the selected document, current address, and containing/current procedure in one coherent provider-neutral request. A cursor outside any procedure returns procedure: null. Scalar navigation getters remain available for evaluation and compatibility.", navigationContextInputSchema),
142
+ session("release_evidence_bundle", "Release one immutable session-retained Evidence v2 bundle by exact digest. This is the recovery operation when bounded bundle retention is exhausted; releasing an unknown digest is idempotent and reports released: false.", releaseEvidenceBundleInputSchema),
143
+ session("get_navigation_context", "Compose the selected document, current address, and containing/current procedure into one provider-neutral result. The result reflects sequential provider observations, not an atomic cursor snapshot; a cursor outside any procedure returns procedure: null. Scalar navigation getters remain available for evaluation and compatibility.", navigationContextInputSchema),
216
144
  session("inspect_address_context", "Inspect one explicit reproducible address for its analyzed name, containing procedure, regular and inline comments, and matching bookmarks. Each unsupported facet returns a typed unavailable outcome; xrefs, assembly, and pseudocode remain separate bounded follow-ups.", addressContextInputSchema),
217
145
  ];
218
146
  /** Complete ordered public inventory used by registration and verification. */
@@ -107,6 +107,16 @@ export const TOOL_EFFECTS = {
107
107
  }),
108
108
  list_electron_targets: browserEvidence,
109
109
  inspect_electron_page: browserEvidence,
110
+ capture_electron_scenario: effects({
111
+ mutatesTarget: true,
112
+ mutatesSession: true,
113
+ writesFilesystem: true,
114
+ launchesProcess: true,
115
+ accessesNetwork: true,
116
+ changesUiState: true,
117
+ mayDiscardData: true,
118
+ idempotent: false,
119
+ }),
110
120
  list_javascript_runtime_targets: browserEvidence,
111
121
  observe_javascript_runtime: browserEvidence,
112
122
  analyze_javascript_application: evidence,
@@ -151,6 +161,10 @@ export const TOOL_EFFECTS = {
151
161
  mayDiscardData: true,
152
162
  }),
153
163
  snapshot_evidence_bundle: effects({ mutatesSession: true }),
164
+ release_evidence_bundle: effects({
165
+ mutatesSession: true,
166
+ mayDiscardData: true,
167
+ }),
154
168
  get_navigation_context: effects({ mutatesSession: true }),
155
169
  inspect_address_context: effects({ mutatesSession: true }),
156
170
  import_evidence_bundle: effects({ mutatesSession: true }),
@@ -158,6 +172,7 @@ export const TOOL_EFFECTS = {
158
172
  mutatesSession: true,
159
173
  writesFilesystem: true,
160
174
  launchesProcess: true,
175
+ accessesNetwork: true,
161
176
  idempotent: false,
162
177
  }),
163
178
  compare_process_captures: sessionEvidence,
@@ -22,7 +22,7 @@ import { staticRuntimeCorrelationResultSchema } from "../domain/staticRuntimeCor
22
22
  import { reconstructionVerificationResultSchema } from "../domain/reconstructionVerification.js";
23
23
  import { replayMachineRunOutputSchema } from "../domain/replayMachineRun.js";
24
24
  import { analysisErrorProjectionSchema } from "./errorSchemas.js";
25
- import { addressList, analysisActivity, addressedEntry, bounded, containingProcedureResolution, clientFeatureAvailabilitySchema, functionDossierOutput, graphNode, lifecycleResultOf, nullableText, pageOutput, procedureIdentity, procedureInfoOutput, evidenceResultOf as resultOf, searchPageOutput, segmentOutput, sessionProvider, providerIdentity, toolAvailability, symbolDiscoveryOutput, targetFormatSchema, targetKindSchema, } from "./toolOutputSchemaPrimitives.js";
25
+ import { addressList, addressedEntry, analysisActivity, bounded, containingProcedureResolution, clientFeatureAvailabilitySchema, functionDossierOutput, graphNode, lifecycleResultOf, nullableText, pageOutput, procedureIdentity, procedureInfoOutput, evidenceResultOf as resultOf, searchPageOutput, segmentOutput, sessionProvider, providerIdentity, toolAvailability, symbolDiscoveryOutput, targetFormatSchema, targetKindSchema, } from "./toolOutputSchemaPrimitives.js";
26
26
  const contextFacetSchema = z.discriminatedUnion("state", [
27
27
  z.object({ state: z.literal("available"), value: jsonValueSchema }),
28
28
  z.object({
@@ -31,6 +31,14 @@ const contextFacetSchema = z.discriminatedUnion("state", [
31
31
  remediation: z.string(),
32
32
  }),
33
33
  ]);
34
+ const bookmarkFacetSchema = z.discriminatedUnion("state", [
35
+ z.object({ state: z.literal("available"), value: z.array(addressedEntry) }),
36
+ z.object({
37
+ state: z.literal("unavailable"),
38
+ reason: z.string(),
39
+ remediation: z.string(),
40
+ }),
41
+ ]);
34
42
  /** Exact structured-content schemas shared by direct analysis providers. */
35
43
  export const officialOutputSchemas = {
36
44
  address_name: resultOf(nullableText),
@@ -315,8 +323,14 @@ export const sessionOutputSchemas = {
315
323
  bytes: z.number().int().min(0),
316
324
  records: z.number().int().min(0),
317
325
  unknowns: z.number().int().min(0),
326
+ scope: z.literal("session"),
327
+ survives_session: z.literal(false),
318
328
  bundle_uri: z.string().regex(/^rea:\/\/evidence-bundle\/[a-f0-9]{64}$/u),
319
329
  })),
330
+ release_evidence_bundle: lifecycleResultOf(z.object({
331
+ bundle_digest: z.string().regex(/^[a-f0-9]{64}$/u),
332
+ released: z.boolean(),
333
+ })),
320
334
  get_navigation_context: lifecycleResultOf(z.object({
321
335
  document: z.string(),
322
336
  address: z.string(),
@@ -329,10 +343,11 @@ export const sessionOutputSchemas = {
329
343
  procedure: contextFacetSchema,
330
344
  comment: contextFacetSchema,
331
345
  inline_comment: contextFacetSchema,
332
- bookmarks: contextFacetSchema,
346
+ bookmarks: bookmarkFacetSchema,
333
347
  })),
334
348
  import_evidence_bundle: lifecycleResultOf(z.object({
335
349
  imported: z.number().int().min(0),
350
+ unknowns_added: z.number().int().min(0),
336
351
  total: z.number().int().min(0),
337
352
  })),
338
353
  capture_process_scenario: resultOf(processCaptureSchema),
@@ -42,11 +42,8 @@ export const targetKindSchema = z.enum([
42
42
  "archive",
43
43
  "artifact",
44
44
  ]);
45
- const providerCapability = z.object({
45
+ const providerCapabilityFacts = {
46
46
  operation: z.string(),
47
- available: z.boolean(),
48
- reason: z.string().nullable(),
49
- availability_code: z.enum(PROVIDER_REJECTION_CODES).nullable(),
50
47
  input_contract_version: z.number().int().min(1),
51
48
  output_contract_version: z.number().int().min(1),
52
49
  pagination: z.enum(["none", "offset", "cursor"]),
@@ -66,7 +63,21 @@ const providerCapability = z.object({
66
63
  timeout_ms: z.number().int().min(0).nullable(),
67
64
  }),
68
65
  limitations: z.array(z.string()),
69
- });
66
+ };
67
+ export const providerCapability = z.discriminatedUnion("available", [
68
+ z.object({
69
+ ...providerCapabilityFacts,
70
+ available: z.literal(true),
71
+ reason: z.null(),
72
+ availability_code: z.null(),
73
+ }),
74
+ z.object({
75
+ ...providerCapabilityFacts,
76
+ available: z.literal(false),
77
+ reason: z.string().nullable(),
78
+ availability_code: z.enum(PROVIDER_REJECTION_CODES).nullable(),
79
+ }),
80
+ ]);
70
81
  export const providerIdentity = z.object({
71
82
  id: z.string(),
72
83
  name: z.string(),
@@ -182,21 +193,25 @@ export const clientFeatureAvailabilitySchema = z.object({
182
193
  roots: z.boolean(),
183
194
  sampling: z.boolean(),
184
195
  });
185
- export const toolAvailability = z.object({
196
+ const toolAvailabilityMode = z.discriminatedUnion("available", [
197
+ z.object({
198
+ name: z.string(),
199
+ available: z.literal(true),
200
+ missing_operations: z.array(z.string()).max(0),
201
+ remediation: z.null(),
202
+ }),
203
+ z.object({
204
+ name: z.string(),
205
+ available: z.literal(false),
206
+ missing_operations: z.array(z.string()).min(1),
207
+ remediation: z.string().nullable(),
208
+ }),
209
+ ]);
210
+ const toolAvailabilityFacts = {
186
211
  name: z.string(),
187
212
  surface: z.string(),
188
- available: z.boolean(),
189
- reason: z.enum([
190
- "available",
191
- "client_capability_missing",
192
- "target_required",
193
- "provider_missing",
194
- "provider_unavailable",
195
- "target_unsupported",
196
- "unsupported_host",
197
- "policy_disabled",
198
- ]),
199
- remediation: z.string().nullable(),
213
+ default_mode_available: z.boolean().optional(),
214
+ modes: z.array(toolAvailabilityMode).optional(),
200
215
  client_requirements: z.object({
201
216
  required: z.array(clientFeatureNameSchema),
202
217
  optional: z.array(clientFeatureNameSchema),
@@ -219,7 +234,30 @@ export const toolAvailability = z.object({
219
234
  idempotent: z.boolean(),
220
235
  open_world: z.boolean(),
221
236
  }),
222
- });
237
+ };
238
+ export const toolUnavailabilityReason = z.enum([
239
+ "client_capability_missing",
240
+ "target_required",
241
+ "provider_missing",
242
+ "provider_unavailable",
243
+ "target_unsupported",
244
+ "unsupported_host",
245
+ "policy_disabled",
246
+ ]);
247
+ export const toolAvailability = z.discriminatedUnion("available", [
248
+ z.object({
249
+ ...toolAvailabilityFacts,
250
+ available: z.literal(true),
251
+ reason: z.literal("available"),
252
+ remediation: z.null(),
253
+ }),
254
+ z.object({
255
+ ...toolAvailabilityFacts,
256
+ available: z.literal(false),
257
+ reason: toolUnavailabilityReason,
258
+ remediation: z.string().nullable(),
259
+ }),
260
+ ]);
223
261
  export const sessionProvider = z.object({
224
262
  provider: providerIdentity,
225
263
  providers: z.array(providerIdentity),
@@ -315,13 +353,25 @@ const availableMemoryPermissions = z.object({
315
353
  available: z.literal(true),
316
354
  source: z.literal("ghidra-memory-block"),
317
355
  });
318
- export const bounded = (item) => z.object({
319
- items: z.array(item),
320
- total: z.number().int().min(0).nullable(),
321
- returned: z.number().int().min(0),
322
- truncated: z.boolean(),
323
- next_offset: z.number().int().min(0).nullable(),
324
- });
356
+ export const bounded = (item) => {
357
+ const facts = {
358
+ items: z.array(item),
359
+ total: z.number().int().min(0).nullable(),
360
+ returned: z.number().int().min(0),
361
+ };
362
+ return z.discriminatedUnion("truncated", [
363
+ z.object({
364
+ ...facts,
365
+ truncated: z.literal(false),
366
+ next_offset: z.null(),
367
+ }),
368
+ z.object({
369
+ ...facts,
370
+ truncated: z.literal(true),
371
+ next_offset: z.number().int().min(0).nullable(),
372
+ }),
373
+ ]);
374
+ };
325
375
  const addressedValue = z.object({
326
376
  address: z.string(),
327
377
  value: z.string(),
@@ -0,0 +1,128 @@
1
+ import { z } from "zod";
2
+ const PROPERTY_DESCRIPTIONS = {
3
+ addresses: "Ordered provider-normalized procedure addresses to analyze.",
4
+ approved: "Explicit operator approval to perform this operation.",
5
+ after: "The later or right-hand observation to compare.",
6
+ before: "The earlier or left-hand observation to compare.",
7
+ boundary_id: "Exact reconstruction boundary identifier to evaluate.",
8
+ case_sensitive: "Whether text matching distinguishes uppercase and lowercase.",
9
+ cdp_endpoint: "Approved literal loopback Chrome DevTools Protocol endpoint.",
10
+ comment: "Exact analyst comment text to write.",
11
+ comparisons: "Validated comparison Evidence records to aggregate.",
12
+ coverage: "Exact reconstruction-coverage commitment to verify.",
13
+ detail: "Requested response detail level.",
14
+ direction: "Direction in which to traverse or compare relationships.",
15
+ document: "Exact provider document or program identity.",
16
+ error: "Structured, caller-actionable error when the operation fails.",
17
+ evidence: "Evidence v2 record produced by this operation.",
18
+ evidence_id: "Stable identifier of the recorded Evidence v2 observation.",
19
+ evidence_uri: "Session resource URI for the recorded Evidence v2 observation.",
20
+ executable: "Approved absolute path of the executable to run.",
21
+ format: "Declared input artifact format.",
22
+ name: "Exact name used by this operation.",
23
+ pattern: "Text or bounded pattern used to filter matching results.",
24
+ phase: "Current plan or execution phase of the operation.",
25
+ plan: "Content-bound execution plan and its approval commitment.",
26
+ query: "Non-empty feature or text query to investigate.",
27
+ question: "Concrete unresolved question to retain for later investigation.",
28
+ result: "Primary structured result returned by this operation.",
29
+ left: "Left-hand input used for comparison or differential execution.",
30
+ limit: "Maximum number of results to return in this page.",
31
+ limits: "Bounded resource-consumption and result-size limits for this operation.",
32
+ mode: "Operation mode that selects the requested behavior.",
33
+ offset: "Zero-based index of the first result to return.",
34
+ overwrite: "Whether an existing destination may be replaced.",
35
+ path: "Local filesystem path used by this operation.",
36
+ provider_id: "Exact deep-analysis provider ID, or automatic selection when omitted.",
37
+ right: "Right-hand input used for comparison or differential execution.",
38
+ schema_version: "Version of this structured result schema.",
39
+ source_evidence: "Evidence records supporting the prepared source transformation.",
40
+ status: "Current lifecycle or verification status.",
41
+ summary: "Concise evidence-backed summary of the result.",
42
+ symbols: "Ordered bounded Swift symbols to demangle.",
43
+ target_id: "Exact authorized CDP target identifier.",
44
+ unknown_id: "Exact residual-unknown identifier.",
45
+ unknown_registry_approved: "Explicit approval to record bounded residual uncertainty in the session registry.",
46
+ workspace_path: "Approved local path of the persistent investigation workspace.",
47
+ };
48
+ /** Attach caller guidance to a canonical schema for the SDK wire projection. */
49
+ export const toolInputSchemaWithMetadata = (contract) => {
50
+ const schema = contract.inputSchema.meta(z.globalRegistry.get(contract.inputSchema) ?? {});
51
+ const standard = schema["~standard"];
52
+ const inputJsonSchema = standard.jsonSchema?.input;
53
+ if (inputJsonSchema === undefined)
54
+ throw new TypeError("Tool input schema does not expose Standard JSON Schema");
55
+ // Zod's input projection drops root metadata when a descendant transforms.
56
+ // Preserve the parser and let the SDK own conversion of everything else.
57
+ Object.defineProperty(schema, "~standard", {
58
+ value: {
59
+ ...standard,
60
+ jsonSchema: {
61
+ ...standard.jsonSchema,
62
+ input: (options) => ({
63
+ ...describeProperties(inputJsonSchema(options)),
64
+ examples: contract.examples.map(({ input }) => input),
65
+ }),
66
+ },
67
+ },
68
+ });
69
+ return schema;
70
+ };
71
+ const describeProperties = (value) => Object.fromEntries(Object.entries(value).map(([key, child]) => {
72
+ if (key !== "properties" || !isObject(child))
73
+ return [key, describeValue(child)];
74
+ return [
75
+ key,
76
+ Object.fromEntries(Object.entries(child).map(([property, propertySchema]) => [
77
+ property,
78
+ isObject(propertySchema) &&
79
+ typeof propertySchema.description !== "string"
80
+ ? {
81
+ ...describeProperties(propertySchema),
82
+ description: fallbackPropertyDescription(property),
83
+ }
84
+ : describeValue(propertySchema),
85
+ ])),
86
+ ];
87
+ }));
88
+ const describeValue = (value) => {
89
+ if (Array.isArray(value))
90
+ return value.map(describeValue);
91
+ return isObject(value) ? describeProperties(value) : value;
92
+ };
93
+ const fallbackPropertyDescription = (property) => {
94
+ const explicit = PROPERTY_DESCRIPTIONS[property];
95
+ if (explicit !== undefined)
96
+ return explicit;
97
+ const words = property.replaceAll("_", " ");
98
+ if (property.endsWith("_approved"))
99
+ return `Explicit operator approval for ${words.slice(0, -9)}.`;
100
+ if (property.endsWith("_offset"))
101
+ return `Zero-based index of the first ${words.slice(0, -7)} to return.`;
102
+ if (property.endsWith("_limit"))
103
+ return `Maximum number of ${words.slice(0, -6)} entries to return.`;
104
+ if (property.startsWith("max_"))
105
+ return `Maximum permitted ${words.slice(4)} for this operation.`;
106
+ if (property.startsWith("include_"))
107
+ return `Whether to include ${words.slice(8)} in the result.`;
108
+ if (property.startsWith("expected_"))
109
+ return `Expected ${words.slice(9)} used to reject stale or mismatched input.`;
110
+ if (property.endsWith("_sha256"))
111
+ return `Exact SHA-256 digest of ${words.slice(0, -7)}.`;
112
+ if (property.endsWith("_evidence_id"))
113
+ return `Exact Evidence v2 identifier for the ${words.slice(0, -12)} observation.`;
114
+ if (property.endsWith("_evidence_ids"))
115
+ return `Ordered Evidence v2 identifiers for the ${words.slice(0, -13)} observations.`;
116
+ if (property.endsWith("_path"))
117
+ return `Local filesystem path for ${words.slice(0, -5)}.`;
118
+ if (property.endsWith("_uri"))
119
+ return `Canonical URI for ${words.slice(0, -4)}.`;
120
+ if (property.endsWith("_bytes"))
121
+ return `Bounded byte count for ${words.slice(0, -6)}.`;
122
+ if (property.endsWith("_root") || property.endsWith("_roots"))
123
+ return `Approved canonical filesystem ${words}.`;
124
+ if (property.startsWith("is_") || property.startsWith("has_"))
125
+ return `Whether ${words}.`;
126
+ return `Value for ${words}.`;
127
+ };
128
+ const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -58,7 +58,7 @@ const inspectJavaScriptReplay = async () => {
58
58
  detail: config.error.message,
59
59
  remediation: "Fix the reported REA_JAVASCRIPT_REPLAY_* configuration.",
60
60
  };
61
- if (!config.value.javascriptReplayPolicy.enabled)
61
+ if (config.value.javascriptReplayPolicy.status === "disabled")
62
62
  return {
63
63
  name: "javascript-replay",
64
64
  ok: true,
@@ -146,6 +146,8 @@ const classify = (all) => ({
146
146
  });
147
147
  const retain = (groups, maximum) => {
148
148
  let remaining = maximum;
149
+ // SAFETY: the projection preserves every key from Groups and replaces only
150
+ // each readonly Component array with a bounded mutable Component array.
149
151
  return Object.fromEntries(Object.entries(groups).map(([key, values]) => {
150
152
  const selected = [...values]
151
153
  .sort((left, right) => compare(left.path, right.path))
@@ -140,6 +140,8 @@ const classifyComponents = (all, roots) => {
140
140
  };
141
141
  const retainComponents = (groups, maximum) => {
142
142
  let remaining = maximum;
143
+ // SAFETY: the projection preserves every key from Groups and replaces only
144
+ // each readonly Component array with a bounded mutable Component array.
143
145
  return Object.fromEntries(Object.entries(groups).map(([key, values]) => {
144
146
  const retained = [...values]
145
147
  .sort((left, right) => compare(left.path, right.path))
@@ -36,14 +36,16 @@ export const parseBinaryTarget = async (input, cwd = process.cwd(), hostArchitec
36
36
  format: "analysis-database",
37
37
  });
38
38
  const artifactFormat = await detectArtifactFormat(path, handle);
39
- if (artifactFormat !== undefined)
40
- return ok({
39
+ if (artifactFormat !== undefined) {
40
+ const identity = {
41
41
  path,
42
42
  sourcePath: canonical,
43
43
  sha256: await sha256Handle(handle),
44
- kind: isArchiveFormat(artifactFormat) ? "archive" : "artifact",
45
- format: artifactFormat,
46
- });
44
+ };
45
+ return isArchiveFormat(artifactFormat)
46
+ ? ok({ ...identity, kind: "archive", format: artifactFormat })
47
+ : ok({ ...identity, kind: "artifact", format: artifactFormat });
48
+ }
47
49
  const detected = await readExecutableMetadata(handle, hostArchitecture);
48
50
  if (!detected.ok)
49
51
  return err(new BinaryTargetError(path, detected.error));
@@ -0,0 +1 @@
1
+ export {};