rea-agents 1.7.0 → 2.0.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 (156) hide show
  1. package/README.md +38 -31
  2. package/dist/application/CapabilityInventory.js +18 -0
  3. package/dist/application/CrossVersionInvestigation.js +10 -6
  4. package/dist/application/Doctor.js +56 -6
  5. package/dist/application/ElectronBoundaryAnalysis.js +96 -0
  6. package/dist/application/ElectronBoundaryGraph.js +9 -0
  7. package/dist/application/ElectronBoundaryGraphContext.js +62 -0
  8. package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
  9. package/dist/application/ElectronBoundaryGraphNative.js +86 -0
  10. package/dist/application/ElectronBoundaryGraphWindows.js +199 -0
  11. package/dist/application/EnhancedTools.js +38 -13
  12. package/dist/application/InvestigationProviders.js +30 -0
  13. package/dist/application/JavaScriptApplicationEvidence.js +26 -0
  14. package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
  15. package/dist/application/JavaScriptApplicationService.js +74 -0
  16. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
  17. package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
  18. package/dist/application/JavaScriptArtifactAnalysis.js +7 -1
  19. package/dist/application/JavaScriptArtifactGraphBuilder.js +59 -16
  20. package/dist/application/JavaScriptArtifactGraphEvidence.js +24 -14
  21. package/dist/application/JavaScriptArtifactReconstruction.js +3 -0
  22. package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -83
  23. package/dist/application/JavaScriptReplayPlanning.js +201 -0
  24. package/dist/application/JavaScriptReplayService.js +266 -0
  25. package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
  26. package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
  27. package/dist/application/ManagedApplicationGraphService.js +55 -0
  28. package/dist/application/ManagedMemberComparisonService.js +122 -0
  29. package/dist/application/ManagedNativeVerificationService.js +39 -0
  30. package/dist/application/ManagedReconstructionService.js +58 -0
  31. package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
  32. package/dist/application/PermissionAuthority.js +1 -1
  33. package/dist/application/ProcessSampling.js +15 -11
  34. package/dist/application/ProjectPermissionStore.js +1 -0
  35. package/dist/application/runtime.js +2 -0
  36. package/dist/browser/CdpCaptureEvents.js +49 -0
  37. package/dist/browser/CdpElectronInspection.js +106 -162
  38. package/dist/browser/CdpElectronProvider.js +5 -1
  39. package/dist/browser/CdpElectronScriptEvents.js +69 -0
  40. package/dist/browser/CdpElectronScripts.js +94 -0
  41. package/dist/browser/CdpElectronWorkers.js +56 -0
  42. package/dist/browser/CdpPageCapture.js +8 -4
  43. package/dist/catalogIdentity.js +4 -1
  44. package/dist/cli.js +388 -0
  45. package/dist/cliApplicationCommands.js +62 -0
  46. package/dist/cliCommandNames.js +13 -0
  47. package/dist/cliElectronCommands.js +103 -1
  48. package/dist/cliJsonInput.js +54 -0
  49. package/dist/config.js +83 -0
  50. package/dist/contracts/applicationToolContracts.js +91 -0
  51. package/dist/contracts/artifactToolContracts.js +5 -9
  52. package/dist/contracts/browserToolContracts.js +14 -62
  53. package/dist/contracts/electronToolContracts.js +45 -19
  54. package/dist/contracts/errorSchemas.js +1 -0
  55. package/dist/contracts/investigationExamples.js +0 -6
  56. package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
  57. package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
  58. package/dist/contracts/managedToolContracts.js +153 -0
  59. package/dist/contracts/managedWorkflowExamples.js +346 -0
  60. package/dist/contracts/managedWorkflowToolContracts.js +203 -0
  61. package/dist/contracts/nativeToolContracts.js +2 -6
  62. package/dist/contracts/promptContracts.js +18 -2
  63. package/dist/contracts/toolContractExamples.js +10 -25
  64. package/dist/contracts/toolContracts.js +47 -45
  65. package/dist/contracts/toolEffects.js +160 -0
  66. package/dist/contracts/toolOutputSchemas.js +46 -31
  67. package/dist/doctorRuntime.js +42 -1
  68. package/dist/domain/artifactComparison.js +3 -4
  69. package/dist/domain/browserObservation.js +3 -0
  70. package/dist/domain/bundleComparison.js +4 -4
  71. package/dist/domain/electronObservation.js +13 -0
  72. package/dist/domain/electronStaticAnalysis.js +9 -0
  73. package/dist/domain/electronStaticAnalysisBrowser.js +194 -0
  74. package/dist/domain/electronStaticAnalysisIpc.js +171 -0
  75. package/dist/domain/electronStaticAnalysisNative.js +164 -0
  76. package/dist/domain/electronStaticAnalysisTypes.js +1 -0
  77. package/dist/domain/electronStaticAnalysisValues.js +103 -0
  78. package/dist/domain/errors.js +67 -1
  79. package/dist/domain/functionComparisonSchemas.js +3 -8
  80. package/dist/domain/inputIssueProjection.js +52 -0
  81. package/dist/domain/javascriptApplicationAnalysis.js +155 -0
  82. package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
  83. package/dist/domain/javascriptApplicationEvidenceSchemas.js +18 -0
  84. package/dist/domain/javascriptApplicationGraph.js +2 -1
  85. package/dist/domain/javascriptApplicationGraphSchemas.js +7 -0
  86. package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
  87. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
  88. package/dist/domain/javascriptApplicationVersionItems.js +221 -0
  89. package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
  90. package/dist/domain/javascriptFeatureSeed.js +140 -0
  91. package/dist/domain/javascriptFeatureTrace.js +232 -0
  92. package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
  93. package/dist/domain/javascriptFeatureTraversal.js +88 -0
  94. package/dist/domain/javascriptNativeHandoff.js +85 -0
  95. package/dist/domain/javascriptReplay.js +361 -0
  96. package/dist/domain/javascriptRuntimeLoadState.js +106 -0
  97. package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
  98. package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
  99. package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
  100. package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
  101. package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
  102. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
  103. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
  104. package/dist/domain/javascriptRuntimeStaticCandidates.js +191 -0
  105. package/dist/domain/javascriptStaticAnalysis.js +31 -43
  106. package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
  107. package/dist/domain/javascriptStaticAnalysisHelpers.js +10 -0
  108. package/dist/domain/javascriptStaticAnalysisState.js +6 -0
  109. package/dist/domain/managedApplicationGraph.js +556 -0
  110. package/dist/domain/managedArtifact.js +444 -0
  111. package/dist/domain/managedMemberComparison.js +565 -0
  112. package/dist/domain/managedNativeVerification.js +408 -0
  113. package/dist/domain/managedReconstruction.js +183 -0
  114. package/dist/domain/managedRuntimeCorrelation.js +175 -0
  115. package/dist/domain/reconstructionVerificationSchemas.js +1 -3
  116. package/dist/dotnet/ManagedArtifactInspector.js +318 -0
  117. package/dist/dotnet/ManagedMemberInspector.js +887 -0
  118. package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
  119. package/dist/dotnet/ManagedMetadataInventory.js +368 -0
  120. package/dist/dotnet/ManagedMetadataLayout.js +322 -0
  121. package/dist/dotnet/ManagedNativeBoundaryInspector.js +391 -0
  122. package/dist/dotnet/ManagedPeReader.js +157 -0
  123. package/dist/dotnet/ManagedReaderFailure.js +10 -0
  124. package/dist/dotnet/ManagedStaticProvider.js +203 -0
  125. package/dist/generatedPackageMetadata.js +2 -2
  126. package/dist/ghidra/GhidraProvider.js +6 -0
  127. package/dist/main.js +14 -0
  128. package/dist/replay/JavaScriptReplayWorker.js +286 -0
  129. package/dist/replay/LinuxJavaScriptReplayRunner.js +434 -0
  130. package/dist/replay/LinuxRuntimeClosure.js +46 -0
  131. package/dist/replay/LinuxSeccompPolicy.js +40 -0
  132. package/dist/replay/ReplayWorkerProtocol.js +55 -0
  133. package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
  134. package/dist/server/createServer.js +52 -0
  135. package/dist/server/registerApplicationTools.js +115 -0
  136. package/dist/server/registerArtifactComparisonTool.js +16 -9
  137. package/dist/server/registerBrowserTools.js +33 -8
  138. package/dist/server/registerBundleComparisonTool.js +17 -20
  139. package/dist/server/registerElectronTools.js +45 -3
  140. package/dist/server/registerEnhancedTools.js +58 -13
  141. package/dist/server/registerEvidenceTools.js +5 -1
  142. package/dist/server/registerFunctionComparisonTool.js +14 -7
  143. package/dist/server/registerInvestigationTools.js +21 -17
  144. package/dist/server/registerManagedTools.js +6 -0
  145. package/dist/server/registerManagedWorkflowTools.js +277 -0
  146. package/dist/server/registerOfficialTools.js +8 -8
  147. package/dist/server/registerProcessComparisonTool.js +25 -47
  148. package/dist/server/registerSessionStatusTool.js +7 -7
  149. package/dist/server/registerSessionTools.js +51 -86
  150. package/dist/server/sessionEvidence.js +14 -19
  151. package/dist/server/toolInputValidation.js +77 -0
  152. package/dist/server/toolRegistrationOptions.js +79 -2
  153. package/dist/server/toolResult.js +25 -17
  154. package/package.json +12 -4
  155. package/scripts/rea.mjs +1 -1
  156. package/skills/rea-analysis/SKILL.md +59 -3
package/dist/cli.js CHANGED
@@ -3,6 +3,11 @@ import { fileURLToPath } from "node:url";
3
3
  import { createInterface } from "node:readline/promises";
4
4
  import { runDoctor } from "./application/Doctor.js";
5
5
  import { runDirectAnalysis, runProviderAnalysis, runSessionStatus, } from "./application/DirectAnalysis.js";
6
+ import { compareManagedMemberPaths } from "./application/ManagedMemberComparisonService.js";
7
+ import { projectManagedApplicationGraphEvidence } from "./application/ManagedApplicationGraphService.js";
8
+ import { verifyManagedNativeBoundariesEvidence } from "./application/ManagedNativeVerificationService.js";
9
+ import { importManagedReconstructionEvidence } from "./application/ManagedReconstructionService.js";
10
+ import { planManagedRuntimeCorrelationEvidence } from "./application/ManagedRuntimeCorrelationService.js";
6
11
  import { runSetup, systemSetupHost, } from "./application/Setup.js";
7
12
  import { runUninstall } from "./application/Uninstall.js";
8
13
  import { runUpgrade, systemUpgradeHost } from "./application/Upgrade.js";
@@ -21,7 +26,9 @@ import { registerPolicyCommands } from "./cliPolicyCommands.js";
21
26
  import { registerBrowserCommands } from "./cliBrowserCommands.js";
22
27
  import { registerAdvancedBrowserCommands } from "./cliBrowserAdvancedCommands.js";
23
28
  import { registerElectronCommands } from "./cliElectronCommands.js";
29
+ import { registerApplicationCommands } from "./cliApplicationCommands.js";
24
30
  import { CLI_COMMANDS } from "./cliCommandNames.js";
31
+ import { parseCliJsonInput } from "./cliJsonInput.js";
25
32
  import { analysisProviderSelectorSchema, } from "./contracts/providerSelection.js";
26
33
  import { createSystemDoctorHost } from "./doctorRuntime.js";
27
34
  /**
@@ -59,6 +66,7 @@ export const createCli = () => {
59
66
  registerCapabilityCommands(cli, logger);
60
67
  registerNativeCommands(cli, logger);
61
68
  registerArtifactCommands(cli, logger);
69
+ registerManagedCommands(cli, logger);
62
70
  registerInvestigationCommands(cli, logger);
63
71
  registerEvidenceCommands(cli, logger);
64
72
  registerReferenceSourceCommand(cli, logger);
@@ -67,6 +75,7 @@ export const createCli = () => {
67
75
  registerBrowserCommands(cli, logger);
68
76
  registerAdvancedBrowserCommands(cli, logger);
69
77
  registerElectronCommands(cli, logger);
78
+ registerApplicationCommands(cli, logger);
70
79
  return cli;
71
80
  };
72
81
  const registerCoreCommands = (cli, logger) => {
@@ -388,6 +397,385 @@ const registerArtifactCommands = (cli, logger) => {
388
397
  }, logger)),
389
398
  });
390
399
  };
400
+ const registerManagedCommands = (cli, logger) => {
401
+ cli.command(CLI_COMMANDS.inspectManagedArtifact, {
402
+ description: "Inspect PE/CLI identity without loading target code",
403
+ args: z.object({
404
+ path: z.string().describe("Managed PE executable or assembly path"),
405
+ }),
406
+ options: z.object({
407
+ referenceOffset: z.number().int().min(0).default(0),
408
+ referenceLimit: z.number().int().min(1).max(500).default(100),
409
+ resourceOffset: z.number().int().min(0).default(0),
410
+ resourceLimit: z.number().int().min(1).max(500).default(100),
411
+ attributeOffset: z.number().int().min(0).default(0),
412
+ attributeLimit: z.number().int().min(1).max(500).default(100),
413
+ maxFileBytes: z
414
+ .number()
415
+ .int()
416
+ .min(4_096)
417
+ .max(1_073_741_824)
418
+ .default(268_435_456),
419
+ maxMetadataBytes: z
420
+ .number()
421
+ .int()
422
+ .min(256)
423
+ .max(268_435_456)
424
+ .default(67_108_864),
425
+ maxTableRows: z.number().int().min(1).max(1_000_000).default(100_000),
426
+ maxHeapItemBytes: z
427
+ .number()
428
+ .int()
429
+ .min(1)
430
+ .max(16_777_216)
431
+ .default(1_048_576),
432
+ }),
433
+ alias: {
434
+ referenceOffset: "reference-offset",
435
+ referenceLimit: "reference-limit",
436
+ resourceOffset: "resource-offset",
437
+ resourceLimit: "resource-limit",
438
+ attributeOffset: "attribute-offset",
439
+ attributeLimit: "attribute-limit",
440
+ maxFileBytes: "max-file-bytes",
441
+ maxMetadataBytes: "max-metadata-bytes",
442
+ maxTableRows: "max-table-rows",
443
+ maxHeapItemBytes: "max-heap-item-bytes",
444
+ },
445
+ run: ({ args, options }) => logCliCommand(logger, "inspect-managed-artifact", () => runProviderAnalysis(args.path, "inspect_managed_artifact", {
446
+ reference_offset: options.referenceOffset,
447
+ reference_limit: options.referenceLimit,
448
+ resource_offset: options.resourceOffset,
449
+ resource_limit: options.resourceLimit,
450
+ attribute_offset: options.attributeOffset,
451
+ attribute_limit: options.attributeLimit,
452
+ max_file_bytes: options.maxFileBytes,
453
+ max_metadata_bytes: options.maxMetadataBytes,
454
+ max_table_rows: options.maxTableRows,
455
+ max_heap_item_bytes: options.maxHeapItemBytes,
456
+ }, logger)),
457
+ });
458
+ cli.command(CLI_COMMANDS.inspectManagedMembers, {
459
+ description: "Inspect PE/CLI metadata members, signatures, and CIL anchors without loading target code",
460
+ args: z.object({
461
+ path: z.string().describe("Managed PE executable or assembly path"),
462
+ }),
463
+ options: z.object({
464
+ typeOffset: z.number().int().min(0).default(0),
465
+ typeLimit: z.number().int().min(1).max(500).default(100),
466
+ methodOffset: z.number().int().min(0).default(0),
467
+ methodLimit: z.number().int().min(1).max(500).default(100),
468
+ fieldOffset: z.number().int().min(0).default(0),
469
+ fieldLimit: z.number().int().min(1).max(500).default(100),
470
+ memberRefOffset: z.number().int().min(0).default(0),
471
+ memberRefLimit: z.number().int().min(1).max(500).default(100),
472
+ edgeOffset: z.number().int().min(0).default(0),
473
+ edgeLimit: z.number().int().min(1).max(1_000).default(250),
474
+ instructionAnchorLimit: z.number().int().min(0).max(500).default(100),
475
+ maxFileBytes: z
476
+ .number()
477
+ .int()
478
+ .min(4_096)
479
+ .max(1_073_741_824)
480
+ .default(268_435_456),
481
+ maxMetadataBytes: z
482
+ .number()
483
+ .int()
484
+ .min(256)
485
+ .max(268_435_456)
486
+ .default(67_108_864),
487
+ maxTableRows: z.number().int().min(1).max(1_000_000).default(100_000),
488
+ maxHeapItemBytes: z
489
+ .number()
490
+ .int()
491
+ .min(1)
492
+ .max(16_777_216)
493
+ .default(1_048_576),
494
+ maxMethodBodyBytes: z
495
+ .number()
496
+ .int()
497
+ .min(1)
498
+ .max(16_777_216)
499
+ .default(1_048_576),
500
+ maxMethodInstructions: z
501
+ .number()
502
+ .int()
503
+ .min(1)
504
+ .max(100_000)
505
+ .default(10_000),
506
+ }),
507
+ alias: {
508
+ typeOffset: "type-offset",
509
+ typeLimit: "type-limit",
510
+ methodOffset: "method-offset",
511
+ methodLimit: "method-limit",
512
+ fieldOffset: "field-offset",
513
+ fieldLimit: "field-limit",
514
+ memberRefOffset: "member-ref-offset",
515
+ memberRefLimit: "member-ref-limit",
516
+ edgeOffset: "edge-offset",
517
+ edgeLimit: "edge-limit",
518
+ instructionAnchorLimit: "instruction-anchor-limit",
519
+ maxFileBytes: "max-file-bytes",
520
+ maxMetadataBytes: "max-metadata-bytes",
521
+ maxTableRows: "max-table-rows",
522
+ maxHeapItemBytes: "max-heap-item-bytes",
523
+ maxMethodBodyBytes: "max-method-body-bytes",
524
+ maxMethodInstructions: "max-method-instructions",
525
+ },
526
+ run: ({ args, options }) => logCliCommand(logger, "inspect-managed-members", () => runProviderAnalysis(args.path, "inspect_managed_members", {
527
+ type_offset: options.typeOffset,
528
+ type_limit: options.typeLimit,
529
+ method_offset: options.methodOffset,
530
+ method_limit: options.methodLimit,
531
+ field_offset: options.fieldOffset,
532
+ field_limit: options.fieldLimit,
533
+ member_ref_offset: options.memberRefOffset,
534
+ member_ref_limit: options.memberRefLimit,
535
+ edge_offset: options.edgeOffset,
536
+ edge_limit: options.edgeLimit,
537
+ instruction_anchor_limit: options.instructionAnchorLimit,
538
+ max_file_bytes: options.maxFileBytes,
539
+ max_metadata_bytes: options.maxMetadataBytes,
540
+ max_table_rows: options.maxTableRows,
541
+ max_heap_item_bytes: options.maxHeapItemBytes,
542
+ max_method_body_bytes: options.maxMethodBodyBytes,
543
+ max_method_instructions: options.maxMethodInstructions,
544
+ }, logger)),
545
+ });
546
+ cli.command(CLI_COMMANDS.inspectManagedNativeBoundaries, {
547
+ description: "Inspect PE/CLI PInvoke and native implementation boundary declarations without loading target code",
548
+ args: z.object({
549
+ path: z.string().describe("Managed PE executable or assembly path"),
550
+ }),
551
+ options: z.object({
552
+ moduleRefOffset: z.number().int().min(0).default(0),
553
+ moduleRefLimit: z.number().int().min(1).max(500).default(100),
554
+ importOffset: z.number().int().min(0).default(0),
555
+ importLimit: z.number().int().min(1).max(500).default(100),
556
+ implementationOffset: z.number().int().min(0).default(0),
557
+ implementationLimit: z.number().int().min(1).max(500).default(100),
558
+ maxFileBytes: z
559
+ .number()
560
+ .int()
561
+ .min(4_096)
562
+ .max(1_073_741_824)
563
+ .default(268_435_456),
564
+ maxMetadataBytes: z
565
+ .number()
566
+ .int()
567
+ .min(256)
568
+ .max(268_435_456)
569
+ .default(67_108_864),
570
+ maxTableRows: z.number().int().min(1).max(1_000_000).default(100_000),
571
+ maxHeapItemBytes: z
572
+ .number()
573
+ .int()
574
+ .min(1)
575
+ .max(16_777_216)
576
+ .default(1_048_576),
577
+ }),
578
+ alias: {
579
+ moduleRefOffset: "module-ref-offset",
580
+ moduleRefLimit: "module-ref-limit",
581
+ importOffset: "import-offset",
582
+ importLimit: "import-limit",
583
+ implementationOffset: "implementation-offset",
584
+ implementationLimit: "implementation-limit",
585
+ maxFileBytes: "max-file-bytes",
586
+ maxMetadataBytes: "max-metadata-bytes",
587
+ maxTableRows: "max-table-rows",
588
+ maxHeapItemBytes: "max-heap-item-bytes",
589
+ },
590
+ run: ({ args, options }) => logCliCommand(logger, "inspect-managed-native-boundaries", () => runProviderAnalysis(args.path, "inspect_managed_native_boundaries", {
591
+ module_ref_offset: options.moduleRefOffset,
592
+ module_ref_limit: options.moduleRefLimit,
593
+ import_offset: options.importOffset,
594
+ import_limit: options.importLimit,
595
+ implementation_offset: options.implementationOffset,
596
+ implementation_limit: options.implementationLimit,
597
+ max_file_bytes: options.maxFileBytes,
598
+ max_metadata_bytes: options.maxMetadataBytes,
599
+ max_table_rows: options.maxTableRows,
600
+ max_heap_item_bytes: options.maxHeapItemBytes,
601
+ }, logger)),
602
+ });
603
+ cli.command(CLI_COMMANDS.compareManagedMembers, {
604
+ description: "Compare two managed PE/CLI member inventories without name-based matching",
605
+ args: z.object({
606
+ leftPath: z
607
+ .string()
608
+ .describe("Baseline managed PE executable or assembly"),
609
+ rightPath: z
610
+ .string()
611
+ .describe("Candidate managed PE executable or assembly"),
612
+ }),
613
+ options: z.object({
614
+ maxMethodMatches: z.number().int().min(1).max(50_000).default(10_000),
615
+ maxFieldMatches: z.number().int().min(0).max(50_000).default(5_000),
616
+ maxCandidates: z.number().int().min(1).max(500).default(50),
617
+ typeLimit: z.number().int().min(1).max(500).default(500),
618
+ methodLimit: z.number().int().min(1).max(500).default(500),
619
+ fieldLimit: z.number().int().min(1).max(500).default(500),
620
+ memberRefLimit: z.number().int().min(1).max(500).default(500),
621
+ edgeLimit: z.number().int().min(1).max(1_000).default(1_000),
622
+ instructionAnchorLimit: z.number().int().min(0).max(500).default(500),
623
+ maxFileBytes: z
624
+ .number()
625
+ .int()
626
+ .min(4_096)
627
+ .max(1_073_741_824)
628
+ .default(268_435_456),
629
+ maxMetadataBytes: z
630
+ .number()
631
+ .int()
632
+ .min(256)
633
+ .max(268_435_456)
634
+ .default(67_108_864),
635
+ maxTableRows: z.number().int().min(1).max(1_000_000).default(100_000),
636
+ maxHeapItemBytes: z
637
+ .number()
638
+ .int()
639
+ .min(1)
640
+ .max(16_777_216)
641
+ .default(1_048_576),
642
+ maxMethodBodyBytes: z
643
+ .number()
644
+ .int()
645
+ .min(1)
646
+ .max(16_777_216)
647
+ .default(1_048_576),
648
+ maxMethodInstructions: z
649
+ .number()
650
+ .int()
651
+ .min(1)
652
+ .max(100_000)
653
+ .default(100_000),
654
+ }),
655
+ alias: {
656
+ maxMethodMatches: "max-method-matches",
657
+ maxFieldMatches: "max-field-matches",
658
+ maxCandidates: "max-candidates",
659
+ typeLimit: "type-limit",
660
+ methodLimit: "method-limit",
661
+ fieldLimit: "field-limit",
662
+ memberRefLimit: "member-ref-limit",
663
+ edgeLimit: "edge-limit",
664
+ instructionAnchorLimit: "instruction-anchor-limit",
665
+ maxFileBytes: "max-file-bytes",
666
+ maxMetadataBytes: "max-metadata-bytes",
667
+ maxTableRows: "max-table-rows",
668
+ maxHeapItemBytes: "max-heap-item-bytes",
669
+ maxMethodBodyBytes: "max-method-body-bytes",
670
+ maxMethodInstructions: "max-method-instructions",
671
+ },
672
+ run: ({ args, options }) => logCliCommand(logger, "compare-managed-members", async () => {
673
+ const result = await compareManagedMemberPaths({
674
+ leftPath: args.leftPath,
675
+ rightPath: args.rightPath,
676
+ comparisonLimits: {
677
+ max_method_matches: options.maxMethodMatches,
678
+ max_field_matches: options.maxFieldMatches,
679
+ max_candidates: options.maxCandidates,
680
+ },
681
+ memberLimits: {
682
+ maxFileBytes: options.maxFileBytes,
683
+ typeOffset: 0,
684
+ typeLimit: options.typeLimit,
685
+ methodOffset: 0,
686
+ methodLimit: options.methodLimit,
687
+ fieldOffset: 0,
688
+ fieldLimit: options.fieldLimit,
689
+ memberRefOffset: 0,
690
+ memberRefLimit: options.memberRefLimit,
691
+ edgeOffset: 0,
692
+ edgeLimit: options.edgeLimit,
693
+ instructionAnchorLimit: options.instructionAnchorLimit,
694
+ maxMetadataBytes: options.maxMetadataBytes,
695
+ maxTableRows: options.maxTableRows,
696
+ maxHeapItemBytes: options.maxHeapItemBytes,
697
+ maxMethodBodyBytes: options.maxMethodBodyBytes,
698
+ maxMethodInstructions: options.maxMethodInstructions,
699
+ },
700
+ });
701
+ return result.ok
702
+ ? result.value
703
+ : {
704
+ error: "Managed member comparison failed",
705
+ ...projectAnalysisError(result.error),
706
+ };
707
+ }),
708
+ });
709
+ cli.command(CLI_COMMANDS.importManagedReconstruction, {
710
+ description: "Import decompiler-produced managed reconstruction against exact static member evidence",
711
+ args: z.object({
712
+ inputJson: z
713
+ .string()
714
+ .describe("Inline managed reconstruction JSON or JSON file path"),
715
+ }),
716
+ run: ({ args }) => logCliCommand(logger, "import-managed-reconstruction", async () => {
717
+ const input = await parseCliJsonInput(args.inputJson, "import-managed-reconstruction");
718
+ if (!input.ok)
719
+ return input.error;
720
+ const result = importManagedReconstructionEvidence(input.value);
721
+ return result.ok ? result.value : projectAnalysisError(result.error);
722
+ }),
723
+ });
724
+ cli.command(CLI_COMMANDS.verifyManagedNativeBoundaries, {
725
+ description: "Verify managed P/Invoke declarations against authenticated native Evidence",
726
+ args: z.object({
727
+ inputJson: z
728
+ .string()
729
+ .describe("Inline managed/native verification JSON or JSON file path"),
730
+ }),
731
+ run: ({ args }) => logCliCommand(logger, "verify-managed-native-boundaries", async () => {
732
+ const input = await parseCliJsonInput(args.inputJson, "verify-managed-native-boundaries");
733
+ if (!input.ok)
734
+ return input.error;
735
+ const result = verifyManagedNativeBoundariesEvidence(input.value);
736
+ return result.ok ? result.value : projectAnalysisError(result.error);
737
+ }),
738
+ });
739
+ cli.command(CLI_COMMANDS.planManagedRuntimeCorrelation, {
740
+ description: "Plan a separately authorized managed runtime-correlation experiment without executing target code",
741
+ args: z.object({
742
+ inputJson: z
743
+ .string()
744
+ .describe("Inline managed runtime-correlation JSON or JSON file path"),
745
+ }),
746
+ run: ({ args }) => logCliCommand(logger, "plan-managed-runtime-correlation", async () => {
747
+ const input = await parseCliJsonInput(args.inputJson, "plan-managed-runtime-correlation");
748
+ if (!input.ok)
749
+ return input.error;
750
+ const config = parseConfig(process.env);
751
+ if (!config.ok)
752
+ return projectAnalysisError(config.error);
753
+ const authority = await loadConfiguredPermissionAuthority(config.value);
754
+ if (!authority.ok)
755
+ return projectAnalysisError(authority.error);
756
+ const result = await planManagedRuntimeCorrelationEvidence({
757
+ policy: config.value.managedRuntimePolicy,
758
+ authority: authority.value,
759
+ }, input.value);
760
+ return result.ok ? result.value : projectAnalysisError(result.error);
761
+ }),
762
+ });
763
+ cli.command(CLI_COMMANDS.projectManagedApplicationGraph, {
764
+ description: "Project authenticated managed static Evidence into an application graph",
765
+ args: z.object({
766
+ inputJson: z
767
+ .string()
768
+ .describe("Inline managed application graph JSON or JSON file path"),
769
+ }),
770
+ run: ({ args }) => logCliCommand(logger, "project-managed-application-graph", async () => {
771
+ const input = await parseCliJsonInput(args.inputJson, "project-managed-application-graph");
772
+ if (!input.ok)
773
+ return input.error;
774
+ const result = projectManagedApplicationGraphEvidence(input.value);
775
+ return result.ok ? result.value : projectAnalysisError(result.error);
776
+ }),
777
+ });
778
+ };
391
779
  const registerNativeCommands = (cli, logger) => {
392
780
  for (const [command, tool] of [
393
781
  [CLI_COMMANDS.inspectMacho, "inspect_macho"],
@@ -0,0 +1,62 @@
1
+ import { Cli, z } from "incur";
2
+ import { compareApplicationVersionsEvidence, traceApplicationFeatureEvidence, } from "./application/JavaScriptApplicationWorkflowService.js";
3
+ import { runControlledReplay } from "./application/JavaScriptReplayService.js";
4
+ import { loadConfiguredPermissionAuthority } from "./application/PermissionConfiguration.js";
5
+ import { CLI_COMMANDS } from "./cliCommandNames.js";
6
+ import { parseCliJsonInput } from "./cliJsonInput.js";
7
+ import { logCliCommand } from "./cliLogging.js";
8
+ import { AnalysisInputError, projectAnalysisError } from "./domain/errors.js";
9
+ import { parseConfig } from "./config.js";
10
+ import { LinuxJavaScriptReplayRunner } from "./replay/LinuxJavaScriptReplayRunner.js";
11
+ import { SystemJavaScriptReplayHost } from "./replay/SystemJavaScriptReplayHost.js";
12
+ /** Register CLI equivalents of provider-neutral application graph workflows. */
13
+ export const registerApplicationCommands = (cli, logger) => {
14
+ registerJsonCommand(cli, logger, CLI_COMMANDS.traceApplicationFeature, "Trace a typed seed through authenticated application Evidence JSON", traceApplicationFeatureEvidence);
15
+ registerJsonCommand(cli, logger, CLI_COMMANDS.compareApplicationVersions, "Compare two authenticated JavaScript Application Graph versions", compareApplicationVersionsEvidence);
16
+ cli.command(CLI_COMMANDS.runControlledReplay, {
17
+ description: "Plan or execute an approved extracted-module replay in the Linux sandbox",
18
+ args: z.object({
19
+ inputJson: z.string().describe("Inline replay JSON or JSON file path"),
20
+ }),
21
+ run: ({ args }) => logCliCommand(logger, CLI_COMMANDS.runControlledReplay, async () => {
22
+ const input = await parseCliJsonInput(args.inputJson, CLI_COMMANDS.runControlledReplay);
23
+ if (!input.ok)
24
+ return input.error;
25
+ const config = parseConfig(process.env);
26
+ if (!config.ok)
27
+ return projectAnalysisError(config.error);
28
+ const authority = await loadConfiguredPermissionAuthority(config.value);
29
+ if (!authority.ok)
30
+ return projectAnalysisError(authority.error);
31
+ const result = await runControlledReplay({
32
+ policy: config.value.javascriptReplayPolicy,
33
+ host: new SystemJavaScriptReplayHost(),
34
+ runner: new LinuxJavaScriptReplayRunner(),
35
+ authority: authority.value,
36
+ }, input.value);
37
+ return result.ok ? result.value : projectAnalysisError(result.error);
38
+ }),
39
+ });
40
+ };
41
+ const registerJsonCommand = (cli, logger, name, description, workflow) => {
42
+ cli.command(name, {
43
+ description,
44
+ args: z.object({
45
+ inputJson: z.string().describe("Inline workflow JSON or JSON file path"),
46
+ }),
47
+ run: ({ args }) => logCliCommand(logger, name, async () => {
48
+ const input = await parseCliJsonInput(args.inputJson, name);
49
+ if (!input.ok)
50
+ return input.error;
51
+ const result = workflow(input.value);
52
+ return result.ok
53
+ ? result.value
54
+ : {
55
+ error: "Application workflow failed",
56
+ ...projectAnalysisError(result.error instanceof AnalysisInputError
57
+ ? result.error
58
+ : new AnalysisInputError(name)),
59
+ };
60
+ }),
61
+ });
62
+ };
@@ -16,6 +16,14 @@ export const CLI_COMMANDS = Object.freeze({
16
16
  importReferenceSource: "import-reference-source",
17
17
  inventoryArtifact: "inventory-artifact",
18
18
  extractArtifact: "extract-artifact",
19
+ inspectManagedArtifact: "inspect-managed-artifact",
20
+ inspectManagedMembers: "inspect-managed-members",
21
+ inspectManagedNativeBoundaries: "inspect-managed-native-boundaries",
22
+ compareManagedMembers: "compare-managed-members",
23
+ verifyManagedNativeBoundaries: "verify-managed-native-boundaries",
24
+ importManagedReconstruction: "import-managed-reconstruction",
25
+ planManagedRuntimeCorrelation: "plan-managed-runtime-correlation",
26
+ projectManagedApplicationGraph: "project-managed-application-graph",
19
27
  inspectMacho: "inspect-macho",
20
28
  inspectSignature: "inspect-signature",
21
29
  listArchitectures: "list-architectures",
@@ -38,6 +46,11 @@ export const CLI_COMMANDS = Object.freeze({
38
46
  compareWebScreenshots: "compare-web-screenshots",
39
47
  listElectronTargets: "list-electron-targets",
40
48
  inspectElectronPage: "inspect-electron-page",
49
+ analyzeJavaScriptApplication: "analyze-javascript-application",
50
+ reconcileJavaScriptRuntime: "reconcile-javascript-runtime",
51
+ traceApplicationFeature: "trace-application-feature",
52
+ compareApplicationVersions: "compare-application-versions",
53
+ runControlledReplay: "run-controlled-replay",
41
54
  });
42
55
  /** Ordered primary CLI inventory; aliases are intentionally excluded. */
43
56
  export const CLI_COMMAND_NAMES = Object.freeze(Object.values(CLI_COMMANDS));
@@ -1,12 +1,16 @@
1
1
  import { Cli, z } from "incur";
2
2
  import { inspectElectronPage, listElectronTargets, } from "./application/ElectronObservationService.js";
3
+ import { analyzeJavaScriptApplication } from "./application/JavaScriptApplicationService.js";
4
+ import { reconcileJavaScriptRuntimeEvidence } from "./application/JavaScriptRuntimeReconciliationService.js";
3
5
  import { loadConfiguredPermissionAuthority } from "./application/PermissionConfiguration.js";
4
6
  import { CdpElectronProvider } from "./browser/CdpElectronProvider.js";
5
7
  import { logCliCommand } from "./cliLogging.js";
6
8
  import { parseConfig } from "./config.js";
7
9
  import { inspectElectronPageInputSchema, listElectronTargetsInputSchema, } from "./domain/electronObservation.js";
10
+ import { analyzeJavaScriptApplicationInputSchema } from "./domain/javascriptApplicationAnalysis.js";
8
11
  import { AnalysisInputError, projectAnalysisError } from "./domain/errors.js";
9
12
  import { CLI_COMMANDS } from "./cliCommandNames.js";
13
+ import { parseCliJsonInput } from "./cliJsonInput.js";
10
14
  const scopeOptions = {
11
15
  allowedFileRoots: z
12
16
  .array(z.string().min(1))
@@ -16,6 +20,28 @@ const scopeOptions = {
16
20
  };
17
21
  /** Register CLI equivalents of the Electron MCP tools. */
18
22
  export const registerElectronCommands = (cli, logger) => {
23
+ registerElectronObservationCommands(cli, logger);
24
+ registerJavaScriptApplicationCommand(cli, logger);
25
+ registerJavaScriptRuntimeReconciliationCommand(cli, logger);
26
+ };
27
+ const registerJavaScriptRuntimeReconciliationCommand = (cli, logger) => {
28
+ cli.command(CLI_COMMANDS.reconcileJavaScriptRuntime, {
29
+ description: "Reconcile static application and passive runtime Evidence JSON",
30
+ args: z.object({
31
+ inputJson: z
32
+ .string()
33
+ .describe("Inline JSON or a JSON file path matching reconcile_javascript_runtime"),
34
+ }),
35
+ run: ({ args }) => logCliCommand(logger, CLI_COMMANDS.reconcileJavaScriptRuntime, async () => {
36
+ const input = await parseCliJsonInput(args.inputJson, "reconcile_javascript_runtime");
37
+ if (!input.ok)
38
+ return input.error;
39
+ const result = reconcileJavaScriptRuntimeEvidence(input.value);
40
+ return result.ok ? result.value : cliError(result.error);
41
+ }),
42
+ });
43
+ };
44
+ const registerElectronObservationCommands = (cli, logger) => {
19
45
  cli.command(CLI_COMMANDS.listElectronTargets, {
20
46
  description: "List root-confined file pages from Electron CDP",
21
47
  args: z.object({ endpoint: z.string() }),
@@ -53,6 +79,7 @@ export const registerElectronCommands = (cli, logger) => {
53
79
  maxDomNodes: z.number().int().min(1).max(10_000).default(2_000),
54
80
  maxScripts: z.number().int().min(1).max(2_000).default(500),
55
81
  maxResources: z.number().int().min(1).max(10_000).default(2_000),
82
+ maxWorkers: z.number().int().min(1).max(5_000).default(500),
56
83
  maxScriptSourceBytes: z
57
84
  .number()
58
85
  .int()
@@ -83,6 +110,7 @@ export const registerElectronCommands = (cli, logger) => {
83
110
  max_dom_nodes: options.maxDomNodes,
84
111
  max_scripts: options.maxScripts,
85
112
  max_resources: options.maxResources,
113
+ max_workers: options.maxWorkers,
86
114
  max_script_source_bytes: options.maxScriptSourceBytes,
87
115
  max_total_script_source_bytes: options.maxTotalScriptSourceBytes,
88
116
  },
@@ -94,6 +122,80 @@ export const registerElectronCommands = (cli, logger) => {
94
122
  }),
95
123
  });
96
124
  };
125
+ const registerJavaScriptApplicationCommand = (cli, logger) => {
126
+ cli.command(CLI_COMMANDS.analyzeJavaScriptApplication, {
127
+ description: "Statically reconstruct an approved JavaScript/Electron application",
128
+ args: z.object({
129
+ path: z.string().describe("Absolute ASAR or extracted application path"),
130
+ }),
131
+ options: z.object({
132
+ approved: z.boolean().default(false),
133
+ format: z.enum(["auto", "asar", "directory"]).default("auto"),
134
+ sourceMapReadApproved: z.boolean().default(false),
135
+ maxEntries: z.number().int().min(1).default(8_000),
136
+ maxTotalArtifactBytes: z
137
+ .number()
138
+ .int()
139
+ .min(1)
140
+ .default(512 * 1_024 * 1_024),
141
+ maxArtifactEntryBytes: z
142
+ .number()
143
+ .int()
144
+ .min(1)
145
+ .default(128 * 1_024 * 1_024),
146
+ maxCompressionRatio: z.number().min(1).default(1_000),
147
+ maxDepth: z.number().int().min(1).default(64),
148
+ maxPathBytes: z.number().int().min(1).default(4_096),
149
+ maxTextFiles: z.number().int().min(1).default(5_000),
150
+ maxTotalTextBytes: z
151
+ .number()
152
+ .int()
153
+ .min(1)
154
+ .default(128 * 1_024 * 1_024),
155
+ maxTextFileBytes: z
156
+ .number()
157
+ .int()
158
+ .min(1)
159
+ .default(8 * 1_024 * 1_024),
160
+ maxAstNodes: z.number().int().min(1).default(2_000_000),
161
+ maxFindings: z.number().int().min(1).default(8_000),
162
+ maxModules: z.number().int().min(1).default(20_000),
163
+ maxSourceMapSources: z.number().int().min(1).default(5_000),
164
+ maxParseMilliseconds: z.number().int().min(1).default(30_000),
165
+ }),
166
+ run: ({ args, options }) => logCliCommand(logger, CLI_COMMANDS.analyzeJavaScriptApplication, async () => {
167
+ const context = await electronContext();
168
+ if (!context.ok)
169
+ return context.error;
170
+ const parsed = analyzeJavaScriptApplicationInputSchema.safeParse({
171
+ input_path: args.path,
172
+ approved: options.approved,
173
+ format: options.format,
174
+ source_map_read_approved: options.sourceMapReadApproved,
175
+ limits: {
176
+ max_entries: options.maxEntries,
177
+ max_total_artifact_bytes: options.maxTotalArtifactBytes,
178
+ max_artifact_entry_bytes: options.maxArtifactEntryBytes,
179
+ max_compression_ratio: options.maxCompressionRatio,
180
+ max_depth: options.maxDepth,
181
+ max_path_bytes: options.maxPathBytes,
182
+ max_text_files: options.maxTextFiles,
183
+ max_total_text_bytes: options.maxTotalTextBytes,
184
+ max_text_file_bytes: options.maxTextFileBytes,
185
+ max_ast_nodes: options.maxAstNodes,
186
+ max_findings: options.maxFindings,
187
+ max_modules: options.maxModules,
188
+ max_source_map_sources: options.maxSourceMapSources,
189
+ max_parse_milliseconds: options.maxParseMilliseconds,
190
+ },
191
+ });
192
+ if (!parsed.success)
193
+ return inputError("analyze_javascript_application");
194
+ const result = await analyzeJavaScriptApplication(context.authority, parsed.data);
195
+ return result.ok ? result.value : cliError(result.error);
196
+ }),
197
+ });
198
+ };
97
199
  const electronContext = async () => {
98
200
  const config = parseConfig(process.env);
99
201
  if (!config.ok)
@@ -110,6 +212,6 @@ const electronContext = async () => {
110
212
  };
111
213
  const inputError = (operation) => cliError(new AnalysisInputError(operation));
112
214
  const cliError = (error) => ({
113
- error: "Electron observation failed",
215
+ error: "Electron analysis failed",
114
216
  ...projectAnalysisError(error),
115
217
  });