@memlab/mcp-server 2.18.1 → 2.86.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.
- package/README.md +30 -16
- package/bin/.eslintrc.js +26 -0
- package/bin/memlab-cli.js +313 -0
- package/dist/anonymized-snapshot.d.ts +75 -0
- package/dist/anonymized-snapshot.d.ts.map +1 -0
- package/dist/anonymized-snapshot.js +101 -0
- package/dist/anonymized-snapshot.js.map +1 -0
- package/dist/artifact-classes.d.ts +86 -0
- package/dist/artifact-classes.d.ts.map +1 -0
- package/dist/artifact-classes.js +261 -0
- package/dist/artifact-classes.js.map +1 -0
- package/dist/capture-mode.d.ts +60 -0
- package/dist/capture-mode.d.ts.map +1 -0
- package/dist/capture-mode.js +39 -0
- package/dist/capture-mode.js.map +1 -0
- package/dist/eval-hints.d.ts +41 -0
- package/dist/eval-hints.d.ts.map +1 -0
- package/dist/eval-hints.js +115 -0
- package/dist/eval-hints.js.map +1 -0
- package/dist/guardrail.d.ts.map +1 -1
- package/dist/guardrail.js +13 -0
- package/dist/guardrail.js.map +1 -1
- package/dist/heap-budget.d.ts +32 -0
- package/dist/heap-budget.d.ts.map +1 -0
- package/dist/heap-budget.js +90 -0
- package/dist/heap-budget.js.map +1 -0
- package/dist/heap-shapes.d.ts +148 -0
- package/dist/heap-shapes.d.ts.map +1 -0
- package/dist/heap-shapes.js +193 -0
- package/dist/heap-shapes.js.map +1 -0
- package/dist/heap-state.d.ts +109 -2
- package/dist/heap-state.d.ts.map +1 -1
- package/dist/heap-state.js +194 -3
- package/dist/heap-state.js.map +1 -1
- package/dist/index.js +102 -1
- package/dist/index.js.map +1 -1
- package/dist/progress.d.ts +25 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +46 -0
- package/dist/progress.js.map +1 -0
- package/dist/react-shapes.d.ts +42 -0
- package/dist/react-shapes.d.ts.map +1 -0
- package/dist/react-shapes.js +149 -0
- package/dist/react-shapes.js.map +1 -0
- package/dist/result-handles.d.ts +11 -0
- package/dist/result-handles.d.ts.map +1 -0
- package/dist/result-handles.js +77 -0
- package/dist/result-handles.js.map +1 -0
- package/dist/server-version.d.ts +19 -0
- package/dist/server-version.d.ts.map +1 -0
- package/dist/server-version.js +19 -0
- package/dist/server-version.js.map +1 -0
- package/dist/snapshot-borrow.d.ts +67 -0
- package/dist/snapshot-borrow.d.ts.map +1 -0
- package/dist/snapshot-borrow.js +113 -0
- package/dist/snapshot-borrow.js.map +1 -0
- package/dist/string-index.d.ts +55 -0
- package/dist/string-index.d.ts.map +1 -0
- package/dist/string-index.js +99 -0
- package/dist/string-index.js.map +1 -0
- package/dist/tool-registry.d.ts +42 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +20 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tools/analyze-run.d.ts +12 -0
- package/dist/tools/analyze-run.d.ts.map +1 -0
- package/dist/tools/analyze-run.js +404 -0
- package/dist/tools/analyze-run.js.map +1 -0
- package/dist/tools/anonymize-snapshot.d.ts +12 -0
- package/dist/tools/anonymize-snapshot.d.ts.map +1 -0
- package/dist/tools/anonymize-snapshot.js +159 -0
- package/dist/tools/anonymize-snapshot.js.map +1 -0
- package/dist/tools/app-config.d.ts +12 -0
- package/dist/tools/app-config.d.ts.map +1 -0
- package/dist/tools/app-config.js +217 -0
- package/dist/tools/app-config.js.map +1 -0
- package/dist/tools/app-heap.d.ts +30 -0
- package/dist/tools/app-heap.d.ts.map +1 -0
- package/dist/tools/app-heap.js +106 -0
- package/dist/tools/app-heap.js.map +1 -0
- package/dist/tools/artifact-budget.d.ts +12 -0
- package/dist/tools/artifact-budget.d.ts.map +1 -0
- package/dist/tools/artifact-budget.js +219 -0
- package/dist/tools/artifact-budget.js.map +1 -0
- package/dist/tools/async-census.d.ts +12 -0
- package/dist/tools/async-census.d.ts.map +1 -0
- package/dist/tools/async-census.js +243 -0
- package/dist/tools/async-census.js.map +1 -0
- package/dist/tools/auto-investigate.d.ts.map +1 -1
- package/dist/tools/auto-investigate.js +54 -5
- package/dist/tools/auto-investigate.js.map +1 -1
- package/dist/tools/batch.d.ts +12 -0
- package/dist/tools/batch.d.ts.map +1 -0
- package/dist/tools/batch.js +196 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/cache-analysis.d.ts +15 -0
- package/dist/tools/cache-analysis.d.ts.map +1 -1
- package/dist/tools/cache-analysis.js +240 -14
- package/dist/tools/cache-analysis.js.map +1 -1
- package/dist/tools/census-diff.d.ts +55 -0
- package/dist/tools/census-diff.d.ts.map +1 -0
- package/dist/tools/census-diff.js +228 -0
- package/dist/tools/census-diff.js.map +1 -0
- package/dist/tools/chain-walk.d.ts +12 -0
- package/dist/tools/chain-walk.d.ts.map +1 -0
- package/dist/tools/chain-walk.js +184 -0
- package/dist/tools/chain-walk.js.map +1 -0
- package/dist/tools/class-histogram.d.ts.map +1 -1
- package/dist/tools/class-histogram.js +14 -3
- package/dist/tools/class-histogram.js.map +1 -1
- package/dist/tools/collection-diff.d.ts +44 -0
- package/dist/tools/collection-diff.d.ts.map +1 -0
- package/dist/tools/collection-diff.js +343 -0
- package/dist/tools/collection-diff.js.map +1 -0
- package/dist/tools/collection-trend.d.ts +55 -0
- package/dist/tools/collection-trend.d.ts.map +1 -0
- package/dist/tools/collection-trend.js +315 -0
- package/dist/tools/collection-trend.js.map +1 -0
- package/dist/tools/detached-dom.d.ts +5 -0
- package/dist/tools/detached-dom.d.ts.map +1 -1
- package/dist/tools/detached-dom.js +368 -22
- package/dist/tools/detached-dom.js.map +1 -1
- package/dist/tools/dev-artifacts.d.ts +62 -6
- package/dist/tools/dev-artifacts.d.ts.map +1 -1
- package/dist/tools/dev-artifacts.js +685 -24
- package/dist/tools/dev-artifacts.js.map +1 -1
- package/dist/tools/diff-snapshots.d.ts.map +1 -1
- package/dist/tools/diff-snapshots.js +18 -2
- package/dist/tools/diff-snapshots.js.map +1 -1
- package/dist/tools/dom-audit.d.ts +37 -0
- package/dist/tools/dom-audit.d.ts.map +1 -0
- package/dist/tools/dom-audit.js +247 -0
- package/dist/tools/dom-audit.js.map +1 -0
- package/dist/tools/dominator-attribution.d.ts +12 -0
- package/dist/tools/dominator-attribution.d.ts.map +1 -0
- package/dist/tools/dominator-attribution.js +189 -0
- package/dist/tools/dominator-attribution.js.map +1 -0
- package/dist/tools/dominator-chain.d.ts +12 -0
- package/dist/tools/dominator-chain.d.ts.map +1 -0
- package/dist/tools/dominator-chain.js +92 -0
- package/dist/tools/dominator-chain.js.map +1 -0
- package/dist/tools/duplicate-objects.d.ts +12 -0
- package/dist/tools/duplicate-objects.d.ts.map +1 -0
- package/dist/tools/duplicate-objects.js +172 -0
- package/dist/tools/duplicate-objects.js.map +1 -0
- package/dist/tools/duplicated-strings.d.ts.map +1 -1
- package/dist/tools/duplicated-strings.js +49 -40
- package/dist/tools/duplicated-strings.js.map +1 -1
- package/dist/tools/eval-across.d.ts +12 -0
- package/dist/tools/eval-across.d.ts.map +1 -0
- package/dist/tools/eval-across.js +135 -0
- package/dist/tools/eval-across.js.map +1 -0
- package/dist/tools/eval.d.ts +79 -0
- package/dist/tools/eval.d.ts.map +1 -1
- package/dist/tools/eval.js +2523 -197
- package/dist/tools/eval.js.map +1 -1
- package/dist/tools/event-listener-leaks.d.ts.map +1 -1
- package/dist/tools/event-listener-leaks.js +42 -17
- package/dist/tools/event-listener-leaks.js.map +1 -1
- package/dist/tools/event-registry.d.ts.map +1 -1
- package/dist/tools/event-registry.js +42 -8
- package/dist/tools/event-registry.js.map +1 -1
- package/dist/tools/explain-delta.d.ts +12 -0
- package/dist/tools/explain-delta.d.ts.map +1 -0
- package/dist/tools/explain-delta.js +221 -0
- package/dist/tools/explain-delta.js.map +1 -0
- package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
- package/dist/tools/find-nodes-by-class.js +112 -13
- package/dist/tools/find-nodes-by-class.js.map +1 -1
- package/dist/tools/finding-index.d.ts +203 -0
- package/dist/tools/finding-index.d.ts.map +1 -0
- package/dist/tools/finding-index.js +566 -0
- package/dist/tools/finding-index.js.map +1 -0
- package/dist/tools/for-each.d.ts.map +1 -1
- package/dist/tools/for-each.js +15 -3
- package/dist/tools/for-each.js.map +1 -1
- package/dist/tools/get-referrers.d.ts.map +1 -1
- package/dist/tools/get-referrers.js +17 -0
- package/dist/tools/get-referrers.js.map +1 -1
- package/dist/tools/get-value.d.ts +16 -0
- package/dist/tools/get-value.d.ts.map +1 -1
- package/dist/tools/get-value.js +96 -2
- package/dist/tools/get-value.js.map +1 -1
- package/dist/tools/hunt-report.d.ts +12 -0
- package/dist/tools/hunt-report.d.ts.map +1 -0
- package/dist/tools/hunt-report.js +186 -0
- package/dist/tools/hunt-report.js.map +1 -0
- package/dist/tools/hypothesis.d.ts +12 -0
- package/dist/tools/hypothesis.d.ts.map +1 -0
- package/dist/tools/hypothesis.js +280 -0
- package/dist/tools/hypothesis.js.map +1 -0
- package/dist/tools/id-space-audit.d.ts +12 -0
- package/dist/tools/id-space-audit.d.ts.map +1 -0
- package/dist/tools/id-space-audit.js +262 -0
- package/dist/tools/id-space-audit.js.map +1 -0
- package/dist/tools/identify.d.ts +12 -0
- package/dist/tools/identify.d.ts.map +1 -0
- package/dist/tools/identify.js +205 -0
- package/dist/tools/identify.js.map +1 -0
- package/dist/tools/identity-diff.d.ts +12 -0
- package/dist/tools/identity-diff.d.ts.map +1 -0
- package/dist/tools/identity-diff.js +188 -0
- package/dist/tools/identity-diff.js.map +1 -0
- package/dist/tools/intern-opportunities.d.ts.map +1 -1
- package/dist/tools/intern-opportunities.js +116 -50
- package/dist/tools/intern-opportunities.js.map +1 -1
- package/dist/tools/ladder-probe.d.ts +65 -0
- package/dist/tools/ladder-probe.d.ts.map +1 -0
- package/dist/tools/ladder-probe.js +445 -0
- package/dist/tools/ladder-probe.js.map +1 -0
- package/dist/tools/ladder.d.ts +33 -0
- package/dist/tools/ladder.d.ts.map +1 -0
- package/dist/tools/ladder.js +266 -0
- package/dist/tools/ladder.js.map +1 -0
- package/dist/tools/largest-objects.d.ts.map +1 -1
- package/dist/tools/largest-objects.js +6 -2
- package/dist/tools/largest-objects.js.map +1 -1
- package/dist/tools/leak-report.d.ts +35 -0
- package/dist/tools/leak-report.d.ts.map +1 -0
- package/dist/tools/leak-report.js +398 -0
- package/dist/tools/leak-report.js.map +1 -0
- package/dist/tools/load-snapshot.d.ts +29 -0
- package/dist/tools/load-snapshot.d.ts.map +1 -1
- package/dist/tools/load-snapshot.js +294 -23
- package/dist/tools/load-snapshot.js.map +1 -1
- package/dist/tools/map-entries.d.ts +12 -0
- package/dist/tools/map-entries.d.ts.map +1 -0
- package/dist/tools/map-entries.js +139 -0
- package/dist/tools/map-entries.js.map +1 -0
- package/dist/tools/match-object.d.ts +12 -0
- package/dist/tools/match-object.d.ts.map +1 -0
- package/dist/tools/match-object.js +165 -0
- package/dist/tools/match-object.js.map +1 -0
- package/dist/tools/metric.d.ts +13 -0
- package/dist/tools/metric.d.ts.map +1 -0
- package/dist/tools/metric.js +185 -0
- package/dist/tools/metric.js.map +1 -0
- package/dist/tools/module-attribution.d.ts +36 -0
- package/dist/tools/module-attribution.d.ts.map +1 -0
- package/dist/tools/module-attribution.js +235 -0
- package/dist/tools/module-attribution.js.map +1 -0
- package/dist/tools/next-measurement.d.ts +26 -0
- package/dist/tools/next-measurement.d.ts.map +1 -0
- package/dist/tools/next-measurement.js +149 -0
- package/dist/tools/next-measurement.js.map +1 -0
- package/dist/tools/object-cost-breakdown.d.ts.map +1 -1
- package/dist/tools/object-cost-breakdown.js +64 -0
- package/dist/tools/object-cost-breakdown.js.map +1 -1
- package/dist/tools/object-shape.d.ts.map +1 -1
- package/dist/tools/object-shape.js +53 -5
- package/dist/tools/object-shape.js.map +1 -1
- package/dist/tools/population-diff.d.ts +57 -0
- package/dist/tools/population-diff.d.ts.map +1 -0
- package/dist/tools/population-diff.js +338 -0
- package/dist/tools/population-diff.js.map +1 -0
- package/dist/tools/population-vs-owners.d.ts +12 -0
- package/dist/tools/population-vs-owners.d.ts.map +1 -0
- package/dist/tools/population-vs-owners.js +183 -0
- package/dist/tools/population-vs-owners.js.map +1 -0
- package/dist/tools/property-names.d.ts +29 -0
- package/dist/tools/property-names.d.ts.map +1 -0
- package/dist/tools/property-names.js +131 -0
- package/dist/tools/property-names.js.map +1 -0
- package/dist/tools/quick-diagnosis.d.ts.map +1 -1
- package/dist/tools/quick-diagnosis.js +7 -1
- package/dist/tools/quick-diagnosis.js.map +1 -1
- package/dist/tools/react-owners.d.ts +12 -0
- package/dist/tools/react-owners.d.ts.map +1 -0
- package/dist/tools/react-owners.js +167 -0
- package/dist/tools/react-owners.js.map +1 -0
- package/dist/tools/react-update-queues.d.ts +12 -0
- package/dist/tools/react-update-queues.d.ts.map +1 -0
- package/dist/tools/react-update-queues.js +173 -0
- package/dist/tools/react-update-queues.js.map +1 -0
- package/dist/tools/replicate.d.ts +49 -0
- package/dist/tools/replicate.d.ts.map +1 -0
- package/dist/tools/replicate.js +241 -0
- package/dist/tools/replicate.js.map +1 -0
- package/dist/tools/retainer-diff.d.ts +12 -0
- package/dist/tools/retainer-diff.d.ts.map +1 -0
- package/dist/tools/retainer-diff.js +168 -0
- package/dist/tools/retainer-diff.js.map +1 -0
- package/dist/tools/retainer-layers.d.ts +23 -0
- package/dist/tools/retainer-layers.d.ts.map +1 -0
- package/dist/tools/retainer-layers.js +179 -0
- package/dist/tools/retainer-layers.js.map +1 -0
- package/dist/tools/retainer-summary.d.ts +18 -0
- package/dist/tools/retainer-summary.d.ts.map +1 -1
- package/dist/tools/retainer-summary.js +210 -51
- package/dist/tools/retainer-summary.js.map +1 -1
- package/dist/tools/retainer-trace.d.ts.map +1 -1
- package/dist/tools/retainer-trace.js +14 -2
- package/dist/tools/retainer-trace.js.map +1 -1
- package/dist/tools/round-audit.d.ts +66 -0
- package/dist/tools/round-audit.d.ts.map +1 -0
- package/dist/tools/round-audit.js +258 -0
- package/dist/tools/round-audit.js.map +1 -0
- package/dist/tools/round-digest.d.ts +12 -0
- package/dist/tools/round-digest.d.ts.map +1 -0
- package/dist/tools/round-digest.js +190 -0
- package/dist/tools/round-digest.js.map +1 -0
- package/dist/tools/script-census.d.ts +12 -0
- package/dist/tools/script-census.d.ts.map +1 -0
- package/dist/tools/script-census.js +182 -0
- package/dist/tools/script-census.js.map +1 -0
- package/dist/tools/search-nodes.d.ts.map +1 -1
- package/dist/tools/search-nodes.js +5 -1
- package/dist/tools/search-nodes.js.map +1 -1
- package/dist/tools/search-strings.d.ts.map +1 -1
- package/dist/tools/search-strings.js +53 -7
- package/dist/tools/search-strings.js.map +1 -1
- package/dist/tools/sequence-analysis.d.ts +53 -0
- package/dist/tools/sequence-analysis.d.ts.map +1 -1
- package/dist/tools/sequence-analysis.js +313 -89
- package/dist/tools/sequence-analysis.js.map +1 -1
- package/dist/tools/server-status.d.ts.map +1 -1
- package/dist/tools/server-status.js +4 -1
- package/dist/tools/server-status.js.map +1 -1
- package/dist/tools/settle-check.d.ts +12 -0
- package/dist/tools/settle-check.d.ts.map +1 -0
- package/dist/tools/settle-check.js +188 -0
- package/dist/tools/settle-check.js.map +1 -0
- package/dist/tools/shape-histogram.d.ts.map +1 -1
- package/dist/tools/shape-histogram.js +9 -2
- package/dist/tools/shape-histogram.js.map +1 -1
- package/dist/tools/sliced-strings.d.ts.map +1 -1
- package/dist/tools/sliced-strings.js +2 -1
- package/dist/tools/sliced-strings.js.map +1 -1
- package/dist/tools/snapshots.d.ts.map +1 -1
- package/dist/tools/snapshots.js +24 -6
- package/dist/tools/snapshots.js.map +1 -1
- package/dist/tools/sparse-elements.d.ts +12 -0
- package/dist/tools/sparse-elements.d.ts.map +1 -0
- package/dist/tools/sparse-elements.js +215 -0
- package/dist/tools/sparse-elements.js.map +1 -0
- package/dist/tools/stale-collections.d.ts +17 -0
- package/dist/tools/stale-collections.d.ts.map +1 -1
- package/dist/tools/stale-collections.js +28 -0
- package/dist/tools/stale-collections.js.map +1 -1
- package/dist/tools/string-patterns.d.ts.map +1 -1
- package/dist/tools/string-patterns.js +7 -5
- package/dist/tools/string-patterns.js.map +1 -1
- package/dist/tools/tools-index.d.ts +12 -0
- package/dist/tools/tools-index.d.ts.map +1 -0
- package/dist/tools/tools-index.js +492 -0
- package/dist/tools/tools-index.js.map +1 -0
- package/dist/tools/trace-all.d.ts +42 -0
- package/dist/tools/trace-all.d.ts.map +1 -0
- package/dist/tools/trace-all.js +263 -0
- package/dist/tools/trace-all.js.map +1 -0
- package/dist/tools/unit-cost.d.ts +12 -0
- package/dist/tools/unit-cost.d.ts.map +1 -0
- package/dist/tools/unit-cost.js +219 -0
- package/dist/tools/unit-cost.js.map +1 -0
- package/dist/tools/verify-fix.d.ts +23 -0
- package/dist/tools/verify-fix.d.ts.map +1 -0
- package/dist/tools/verify-fix.js +219 -0
- package/dist/tools/verify-fix.js.map +1 -0
- package/dist/tools/weakmap-entries.d.ts.map +1 -1
- package/dist/tools/weakmap-entries.js +6 -1
- package/dist/tools/weakmap-entries.js.map +1 -1
- package/dist/tools/weakref-census.d.ts +15 -0
- package/dist/tools/weakref-census.d.ts.map +1 -0
- package/dist/tools/weakref-census.js +147 -0
- package/dist/tools/weakref-census.js.map +1 -0
- package/dist/tools/what-if.d.ts +12 -0
- package/dist/tools/what-if.d.ts.map +1 -0
- package/dist/tools/what-if.js +285 -0
- package/dist/tools/what-if.js.map +1 -0
- package/dist/utils.d.ts +238 -3
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +507 -15
- package/dist/utils.js.map +1 -1
- package/package.json +7 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-index.d.ts","sourceRoot":"","sources":["../../src/tools/finding-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import crypto from 'crypto';
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { formatNumber, markdownTable, errorResult, toolResult, } from '../utils.js';
|
|
15
|
+
/**
|
|
16
|
+
* A cross-round index of leak findings, keyed by a normalized retainer-path
|
|
17
|
+
* signature.
|
|
18
|
+
*
|
|
19
|
+
* The problem this solves is the most expensive one a hunt hits: rounds
|
|
20
|
+
* re-discover leaks that are already known or already fixed. One measured round
|
|
21
|
+
* produced three findings — a listener accumulation, a completion-map grower and
|
|
22
|
+
* a module-registry grower — all three of which were known, two already fixed
|
|
23
|
+
* behind gates, and the first only visible because the gated fixes were not
|
|
24
|
+
* enabled. That is an entire round spent re-deriving history.
|
|
25
|
+
*
|
|
26
|
+
* Why a retainer-path signature rather than the class name: the class that grows
|
|
27
|
+
* is rarely distinctive (`Object`, `Array`, `(object properties)` are the top
|
|
28
|
+
* growers in almost every heap), while the PATH that retains it is. Node ids,
|
|
29
|
+
* array indices and per-instance scope ids differ per capture, so they are
|
|
30
|
+
* stripped; what remains — the ordered edge names and class names — is stable
|
|
31
|
+
* across captures of the same leak and different between different leaks.
|
|
32
|
+
*
|
|
33
|
+
* Deliberately local (a JSON file), not a service: the index is only useful if
|
|
34
|
+
* it is written by default on every round, and anything requiring a backend
|
|
35
|
+
* would not be. It is seeded from prior runs' manifests.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Where the index lives, most specific wins.
|
|
39
|
+
*
|
|
40
|
+
* The default is a per-machine home directory, and that default is the reason
|
|
41
|
+
* the tool has already produced a wrong verdict: an index with no history
|
|
42
|
+
* answers `check` with **NEW** for a finding that is fully documented and
|
|
43
|
+
* already has a fix diff. A home-dir file cannot be shared, does not survive a
|
|
44
|
+
* host change, and is empty on every new devserver — so the failure recurs for
|
|
45
|
+
* every operator rather than once.
|
|
46
|
+
*
|
|
47
|
+
* `MEMLAB_FINDINGS_INDEX` therefore points at a checked-in, shared file, and
|
|
48
|
+
* `workstream` scopes several of them side by side. The home-dir path is kept as
|
|
49
|
+
* the fallback so nothing that already works breaks.
|
|
50
|
+
*/
|
|
51
|
+
export function resolveIndexPath(workstream) {
|
|
52
|
+
const override = process.env.MEMLAB_FINDINGS_INDEX;
|
|
53
|
+
if (override != null && override !== '') {
|
|
54
|
+
if (workstream == null || workstream === '')
|
|
55
|
+
return override;
|
|
56
|
+
// Treat the override as a directory when a workstream is named, so one
|
|
57
|
+
// shared location can hold several workstreams without collision.
|
|
58
|
+
return override.endsWith('.json')
|
|
59
|
+
? override.replace(/\.json$/, `.${workstream}.json`)
|
|
60
|
+
: path.join(override, `findings.${workstream}.json`);
|
|
61
|
+
}
|
|
62
|
+
const base = path.join(process.env.HOME ?? '/tmp', '.memlab-mcp');
|
|
63
|
+
return path.join(base, workstream != null && workstream !== ''
|
|
64
|
+
? `findings.${workstream}.json`
|
|
65
|
+
: 'findings.json');
|
|
66
|
+
}
|
|
67
|
+
function loadIndex(indexPath) {
|
|
68
|
+
try {
|
|
69
|
+
if (fs.existsSync(indexPath)) {
|
|
70
|
+
const parsed = JSON.parse(fs.readFileSync(indexPath, 'utf8'));
|
|
71
|
+
if (parsed != null && typeof parsed === 'object') {
|
|
72
|
+
const idx = parsed;
|
|
73
|
+
return {
|
|
74
|
+
version: idx.version ?? 1,
|
|
75
|
+
findings: idx.findings ?? {},
|
|
76
|
+
combos_driven: idx.combos_driven ?? {},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// A corrupt index must not block a hunt — but it must not be silently
|
|
83
|
+
// erased either: returning empty here means the next `record` overwrites
|
|
84
|
+
// the file wholesale and every prior fingerprint is gone, which defeats the
|
|
85
|
+
// one thing this tool exists to do. Preserve it for recovery first.
|
|
86
|
+
try {
|
|
87
|
+
if (fs.existsSync(indexPath)) {
|
|
88
|
+
fs.renameSync(indexPath, `${indexPath}.corrupt`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// Best effort; a failed rename must not block the hunt either.
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// A brand-new index is seeded with the artifact families rather than left
|
|
96
|
+
// empty, so the very first `check` can answer KNOWN for a population that is
|
|
97
|
+
// documented and is not app memory. Seeding on CREATION (not on every load)
|
|
98
|
+
// means a caller who deliberately removes one keeps it removed.
|
|
99
|
+
const fresh = { version: 1, findings: {}, combos_driven: {} };
|
|
100
|
+
importFindings(fresh, builtinSeedFindings());
|
|
101
|
+
return fresh;
|
|
102
|
+
}
|
|
103
|
+
function saveIndex(indexPath, idx) {
|
|
104
|
+
fs.mkdirSync(path.dirname(indexPath), { recursive: true });
|
|
105
|
+
fs.writeFileSync(indexPath, JSON.stringify(idx, null, 2));
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Findings accepted by `action: "import"`.
|
|
109
|
+
*
|
|
110
|
+
* Loose on purpose: the source is a hand-maintained team document or a previous
|
|
111
|
+
* round's notes, and rejecting a row for a missing optional field would mean the
|
|
112
|
+
* bootstrap does not happen at all — which is the status quo this fixes.
|
|
113
|
+
*/
|
|
114
|
+
const IMPORTED_FINDING_SCHEMA = z.object({
|
|
115
|
+
retainer_path: z.string().optional(),
|
|
116
|
+
signature: z.string().optional(),
|
|
117
|
+
growing_classes: z.array(z.string()).optional(),
|
|
118
|
+
round: z.string().optional(),
|
|
119
|
+
status: z.enum(['new', 'known', 'fixed']).optional(),
|
|
120
|
+
fixed_behind: z.string().optional(),
|
|
121
|
+
note: z.string().optional(),
|
|
122
|
+
});
|
|
123
|
+
export function importFindings(index, incoming) {
|
|
124
|
+
let imported = 0;
|
|
125
|
+
let updated = 0;
|
|
126
|
+
const skipped = [];
|
|
127
|
+
incoming.forEach((raw, i) => {
|
|
128
|
+
const source = raw.retainer_path ?? raw.signature;
|
|
129
|
+
if (source == null || source === '') {
|
|
130
|
+
skipped.push(`entry ${i}: neither retainer_path nor signature`);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// A `signature` is already normalized by definition; normalizing again is a
|
|
134
|
+
// no-op on well-formed input and repairs a hand-written one.
|
|
135
|
+
const signature = normalizeRetainerPath(source);
|
|
136
|
+
const classes = raw.growing_classes ?? [];
|
|
137
|
+
const fingerprint = fingerprintOf(signature, classes);
|
|
138
|
+
const existing = index.findings[fingerprint];
|
|
139
|
+
const round = raw.round ?? 'imported';
|
|
140
|
+
index.findings[fingerprint] = {
|
|
141
|
+
fingerprint,
|
|
142
|
+
signature,
|
|
143
|
+
growing_classes: classes,
|
|
144
|
+
first_seen_round: existing?.first_seen_round ?? round,
|
|
145
|
+
last_seen_round: round,
|
|
146
|
+
status: raw.status ?? existing?.status ?? 'known',
|
|
147
|
+
fixed_behind: raw.fixed_behind ?? existing?.fixed_behind,
|
|
148
|
+
note: raw.note ?? existing?.note,
|
|
149
|
+
// An import is history, not a sighting: it must not inflate seen_count
|
|
150
|
+
// for a finding this operator has never actually observed.
|
|
151
|
+
seen_count: existing?.seen_count ?? 1,
|
|
152
|
+
};
|
|
153
|
+
if (existing)
|
|
154
|
+
updated++;
|
|
155
|
+
else
|
|
156
|
+
imported++;
|
|
157
|
+
});
|
|
158
|
+
return { imported, updated, skipped };
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Normalize a retainer path into a signature that is stable across captures.
|
|
162
|
+
*
|
|
163
|
+
* Strips exactly the things that differ per capture and nothing else:
|
|
164
|
+
* - `@12345` node ids, including the ` @…`-suffixed Context/scope names;
|
|
165
|
+
* - numeric array indices (`[47]`, `.47`), which depend on insertion order;
|
|
166
|
+
* - hex/long digit runs inside names (ids embedded in keys, e.g. a chat id).
|
|
167
|
+
*/
|
|
168
|
+
export function normalizeRetainerPath(raw) {
|
|
169
|
+
return (raw
|
|
170
|
+
.replace(/@\d+/g, '@')
|
|
171
|
+
.replace(/\[\d+\]/g, '[i]')
|
|
172
|
+
// Broad lookahead: retainer paths carry trailing `)`, `]`, `>` and the
|
|
173
|
+
// separator inserted below, so a `\\s|$|\\.`-only lookahead leaves `.47)` /
|
|
174
|
+
// `.47>` unnormalized and feeds per-capture noise into the fingerprint.
|
|
175
|
+
.replace(/\.\d+(?=[^\w]|$)/g, '.i')
|
|
176
|
+
.replace(/\b\d{4,}\b/g, 'N')
|
|
177
|
+
.replace(/\s*(-->|--|→|->)\s*/g, ' > ')
|
|
178
|
+
// `-->` would otherwise match `--` and `->` in turn, doubling the separator.
|
|
179
|
+
.replace(/(?: > )+/g, ' > ')
|
|
180
|
+
.replace(/\s+/g, ' ')
|
|
181
|
+
.trim());
|
|
182
|
+
}
|
|
183
|
+
export function fingerprintOf(signature, classes) {
|
|
184
|
+
const material = `${signature}||${[...classes].sort().join(',')}`;
|
|
185
|
+
return crypto.createHash('sha1').update(material).digest('hex').slice(0, 12);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Artifact families every hunt re-derives, seeded into a fresh index.
|
|
189
|
+
*
|
|
190
|
+
* An empty index answers NEW to everything — including populations that are
|
|
191
|
+
* documented, well understood, and not app memory at all. That makes the first
|
|
192
|
+
* `check` of a workstream actively misleading rather than merely unhelpful, and
|
|
193
|
+
* hand-seeding never happens because it is a step nobody is prompted to take.
|
|
194
|
+
*
|
|
195
|
+
* These entries are deliberately the GENERIC, tool-detectable families (the
|
|
196
|
+
* same taxonomy `artifact-classes.ts` classifies, plus the two dev-build
|
|
197
|
+
* registries `dev_artifacts` detects). They are marked `known` rather than
|
|
198
|
+
* `fixed`: they are not defects to be fixed, they are populations a hunt must
|
|
199
|
+
* subtract. Anything app-specific belongs in a real `action: "import"`.
|
|
200
|
+
*/
|
|
201
|
+
export function builtinSeedFindings() {
|
|
202
|
+
const seed = (signature, growing_classes, note) => ({
|
|
203
|
+
signature,
|
|
204
|
+
growing_classes,
|
|
205
|
+
round: 'builtin',
|
|
206
|
+
status: 'known',
|
|
207
|
+
note,
|
|
208
|
+
});
|
|
209
|
+
return [
|
|
210
|
+
seed('V8 JIT/compile warmup structures', [
|
|
211
|
+
'Code',
|
|
212
|
+
'BytecodeArray',
|
|
213
|
+
'FeedbackVector',
|
|
214
|
+
'ScopeInfo',
|
|
215
|
+
'InstructionStream',
|
|
216
|
+
], 'Exercising new code paths during a hunt JIT-compiles them, so this family climbs every step without being an app leak. Not a finding.'),
|
|
217
|
+
seed('Blink accessibility cache inflated by automation', ['AXObjectCacheImpl', 'AXNodeObject', 'AXDirtyObject'], 'CDP-driven automation builds the a11y tree. These co-retain detached DOM, so retainer traces can route through them and mislead.'),
|
|
218
|
+
seed('CDP inspector network log', ['NetworkResourcesData', 'XHRReplayData', 'PerformanceResourceTiming'], 'Every request made while CDP is attached is retained by the DevToolsSession for the session. A dev build that polls grows this forever. Not app memory.'),
|
|
219
|
+
seed('CDP inspector performance timeline', ['PerformanceLongTaskTiming', 'PerformanceScriptTiming', 'LayoutShift'], 'Accumulates because something is observing it, not because the app leaks.'),
|
|
220
|
+
seed('CDP inspector console retention', ['ConsoleMessage'], 'Console-retained memory scales with how much the app logs, not with what it holds. A dev build logging per cycle produces a clean linear "leak" that does not exist in production.'),
|
|
221
|
+
seed('Captured Error stacks (React DEV owner stacks)', ['StackFrameInfo', 'ErrorStackData'], 'Usually React DEV `_debugStack` or dev-build logging capturing a stack per record. Dev-build only, but a production build can legitimately grow these — check before dismissing.'),
|
|
222
|
+
seed('React Fast Refresh registries (dev-only)', ['allFamiliesByID', 'allFamiliesByType', 'allSignaturesByType'], 'Dev-only hot-reload bookkeeping. The backing tables are large and sparse and V8 never shrinks an EphemeronHashTable, so they present as a big anonymous array at the top of a leak report.'),
|
|
223
|
+
seed('Automation/tool bridge bundle', ['(concatenated string)', '(string)'], 'The browser-automation bridge is re-evaluated per call and its source is retained per copy. Presents as many megabytes of duplicated script text that no production user ever loads.'),
|
|
224
|
+
];
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Known entries that share a growing class with the candidate.
|
|
228
|
+
*
|
|
229
|
+
* The fingerprint is an EXACT match on signature + class set, which is right for
|
|
230
|
+
* "have we filed this before" and useless for "is this population a known
|
|
231
|
+
* artifact". Measured against a freshly-seeded index: a realistic check —
|
|
232
|
+
* retainer path `(GC roots) > (Global handles) > Object.allSignaturesByType`,
|
|
233
|
+
* growing class `allSignaturesByType` — returned NEW, even though the React Fast
|
|
234
|
+
* Refresh registry entry naming that exact class was sitting in the index. A
|
|
235
|
+
* caller has to reproduce the seeded signature string verbatim to get a hit,
|
|
236
|
+
* which nobody will ever do, so without this the seeding is decorative.
|
|
237
|
+
*
|
|
238
|
+
* Reported ALONGSIDE the NEW verdict rather than replacing it: a class overlap
|
|
239
|
+
* is a lead, not an identification, and silently converting NEW to KNOWN on one
|
|
240
|
+
* shared class name would suppress real findings.
|
|
241
|
+
*/
|
|
242
|
+
export function relatedByClass(index, classes, excludeFingerprint) {
|
|
243
|
+
if (classes.length === 0)
|
|
244
|
+
return [];
|
|
245
|
+
const wanted = new Set(classes);
|
|
246
|
+
return Object.values(index.findings)
|
|
247
|
+
.filter(f => f.fingerprint !== excludeFingerprint)
|
|
248
|
+
.map(f => ({
|
|
249
|
+
f,
|
|
250
|
+
shared: f.growing_classes.filter(c => wanted.has(c)),
|
|
251
|
+
}))
|
|
252
|
+
.filter(x => x.shared.length > 0)
|
|
253
|
+
.sort((a, b) => b.shared.length - a.shared.length)
|
|
254
|
+
.slice(0, 5)
|
|
255
|
+
.map(x => x.f);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Does the index hold anything beyond the generic built-in artifact families?
|
|
259
|
+
*
|
|
260
|
+
* `loadIndex` seeds a fresh index with those families, so a plain
|
|
261
|
+
* `Object.keys(findings).length === 0` is never true and every "is this index
|
|
262
|
+
* usable" guard built on it silently never fires. The question that actually
|
|
263
|
+
* matters is whether the index carries history for THIS app; built-in entries
|
|
264
|
+
* are stamped `first_seen_round: 'builtin'` and say nothing about it.
|
|
265
|
+
*/
|
|
266
|
+
export function hasAppHistory(index) {
|
|
267
|
+
return Object.values(index.findings).some(f => f.first_seen_round !== 'builtin');
|
|
268
|
+
}
|
|
269
|
+
export function loadFindingIndex(workstream) {
|
|
270
|
+
const indexPath = resolveIndexPath(workstream);
|
|
271
|
+
return { index: loadIndex(indexPath), indexPath };
|
|
272
|
+
}
|
|
273
|
+
export function lookupFinding(retainerPath, classes, workstream) {
|
|
274
|
+
return lookupFindingIn(loadFindingIndex(workstream), retainerPath, classes);
|
|
275
|
+
}
|
|
276
|
+
export function lookupFindingIn(loaded, retainerPath, classes) {
|
|
277
|
+
const { index, indexPath } = loaded;
|
|
278
|
+
const signature = normalizeRetainerPath(retainerPath);
|
|
279
|
+
const classList = [...classes];
|
|
280
|
+
const fingerprint = fingerprintOf(signature, classList);
|
|
281
|
+
const hit = index.findings[fingerprint];
|
|
282
|
+
const indexEmpty = !hasAppHistory(index);
|
|
283
|
+
if (hit) {
|
|
284
|
+
return {
|
|
285
|
+
verdict: hit.status === 'fixed' ? 'KNOWN-AND-FIXED' : 'KNOWN',
|
|
286
|
+
fixedBehind: hit.fixed_behind,
|
|
287
|
+
note: hit.note,
|
|
288
|
+
round: hit.first_seen_round,
|
|
289
|
+
related: [],
|
|
290
|
+
indexEmpty,
|
|
291
|
+
indexPath,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
verdict: 'NEW',
|
|
296
|
+
related: relatedByClass(index, classList, fingerprint).map(f => `${f.growing_classes.join(', ')}${f.fixed_behind ? ` (fixed behind ${f.fixed_behind})` : ''}`),
|
|
297
|
+
indexEmpty,
|
|
298
|
+
indexPath,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
/** One-line renderer for an inline verdict badge. */
|
|
302
|
+
export function renderFindingVerdict(l) {
|
|
303
|
+
if (l.verdict === 'KNOWN-AND-FIXED') {
|
|
304
|
+
return `\`KNOWN-AND-FIXED\`${l.fixedBehind ? ` — fixed behind \`${l.fixedBehind}\`; confirm the gate is ON in this capture before treating it as a finding` : ''}`;
|
|
305
|
+
}
|
|
306
|
+
if (l.verdict === 'KNOWN') {
|
|
307
|
+
return `\`KNOWN\`${l.round ? ` — first seen ${l.round}` : ''}${l.note ? `: ${l.note}` : ''}`;
|
|
308
|
+
}
|
|
309
|
+
const related = l.related.length > 0
|
|
310
|
+
? ` (but shares a growing class with: ${l.related.slice(0, 2).join('; ')} — a lead, not an identification)`
|
|
311
|
+
: '';
|
|
312
|
+
return `\`NEW\`${related}`;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* The banner to print once per report when the index cannot support a verdict.
|
|
316
|
+
*/
|
|
317
|
+
export function findingIndexEmptyBanner(indexPath) {
|
|
318
|
+
return (`> ⚠️ **The findings index at \`${indexPath}\` is EMPTY, so every \`NEW\` below means "not in an empty list" and carries no information.** ` +
|
|
319
|
+
'Seed it with `memlab_finding_index({action: "import"})` before trusting any verdict here. ' +
|
|
320
|
+
'An unseeded index is how a round spends itself re-deriving a finding that was already filed and already fixed.');
|
|
321
|
+
}
|
|
322
|
+
export function registerFindingIndex(server) {
|
|
323
|
+
server.tool('memlab_finding_index', 'Fingerprint a leak finding by its retainer path and check it against findings from previous rounds, so a hunt does not spend itself re-discovering a known or already-fixed leak. ' +
|
|
324
|
+
'This is the highest-cost failure a leak hunt has: a measured round produced three findings that were all already known — two already fixed behind gates — which is an entire round spent re-deriving history. Class names cannot detect that (`Object` and `Array` top every heap); the retainer PATH can, so the fingerprint is a normalized path signature with node ids, array indices and per-capture scope ids stripped. ' +
|
|
325
|
+
'Actions: "check" fingerprints a candidate and reports NEW / KNOWN / KNOWN-AND-FIXED; "record" adds it; "import" bootstraps history in bulk from a team doc or a JSON file; "list" prints the index; "cover" records which combos a round drove, so the "do not repeat covered combos" rule stops depending on someone remembering.\n\n' +
|
|
326
|
+
'IMPORTANT: a verdict of NEW is only as good as the index behind it. A newly-created index is pre-seeded with the generic ARTIFACT families (JIT warmup, CDP network/perf/console retention, a11y caches, React Fast Refresh registries, captured Error stacks, the automation bridge bundle), so the first `check` can already answer KNOWN for a population that is documented and is not app memory — but it knows nothing about YOUR app. Seed that with `action: "import"` before trusting the first `check` of a workstream. Set `MEMLAB_FINDINGS_INDEX` to a checked-in path to share the index across hosts and operators instead of keeping it in a per-machine home directory.', {
|
|
327
|
+
action: z
|
|
328
|
+
.enum(['check', 'record', 'list', 'cover', 'import'])
|
|
329
|
+
.describe('"check" (fingerprint + look up, no write), "record" (add/update), "import" (bulk-seed history), "list", "cover" (log combos driven in a round).'),
|
|
330
|
+
retainer_path: z
|
|
331
|
+
.string()
|
|
332
|
+
.optional()
|
|
333
|
+
.describe("The finding's retainer path, as printed by memlab_retainer_summary / memlab_retainer_trace. Required for check and record."),
|
|
334
|
+
growing_classes: z
|
|
335
|
+
.array(z.string())
|
|
336
|
+
.optional()
|
|
337
|
+
.default([])
|
|
338
|
+
.describe('Classes that grew across the ladder for this finding. Folded into the fingerprint so the same path holding a different class set is a different finding.'),
|
|
339
|
+
round: z
|
|
340
|
+
.string()
|
|
341
|
+
.optional()
|
|
342
|
+
.describe('Round identifier (e.g. "r59"), recorded as first/last seen.'),
|
|
343
|
+
status: z
|
|
344
|
+
.enum(['new', 'known', 'fixed'])
|
|
345
|
+
.optional()
|
|
346
|
+
.default('known')
|
|
347
|
+
.describe('Status to record. Use "fixed" together with fixed_behind.'),
|
|
348
|
+
fixed_behind: z
|
|
349
|
+
.string()
|
|
350
|
+
.optional()
|
|
351
|
+
.describe('Gate/ABProp the fix sits behind, if it is fixed.'),
|
|
352
|
+
note: z
|
|
353
|
+
.string()
|
|
354
|
+
.optional()
|
|
355
|
+
.describe('Free-text note stored with the finding.'),
|
|
356
|
+
combos: z
|
|
357
|
+
.array(z.string())
|
|
358
|
+
.optional()
|
|
359
|
+
.default([])
|
|
360
|
+
.describe('For action "cover": combo names driven in this round.'),
|
|
361
|
+
workstream: z
|
|
362
|
+
.string()
|
|
363
|
+
.optional()
|
|
364
|
+
.describe('Scopes the index file, so one shared location can hold several hunts side by side (e.g. "wa-web"). Omit to use the unscoped index.'),
|
|
365
|
+
from: z
|
|
366
|
+
.string()
|
|
367
|
+
.optional()
|
|
368
|
+
.describe('For action "import": path to a JSON file holding either an array of findings or {findings: [...]}. Each entry needs retainer_path (or signature) and may carry growing_classes, round, status, fixed_behind, note.'),
|
|
369
|
+
findings: z
|
|
370
|
+
.array(IMPORTED_FINDING_SCHEMA)
|
|
371
|
+
.optional()
|
|
372
|
+
.describe('For action "import": findings passed inline, for seeding straight from a team doc without writing a file first.'),
|
|
373
|
+
}, async ({ action, retainer_path, growing_classes, round, status, fixed_behind, note, combos, workstream, from, findings, }) => {
|
|
374
|
+
try {
|
|
375
|
+
const indexPath = resolveIndexPath(workstream);
|
|
376
|
+
const index = loadIndex(indexPath);
|
|
377
|
+
if (action === 'import') {
|
|
378
|
+
const incoming = [...(findings ?? [])];
|
|
379
|
+
const fileErrors = [];
|
|
380
|
+
if (from != null && from !== '') {
|
|
381
|
+
if (!fs.existsSync(from)) {
|
|
382
|
+
return errorResult(`import source not found: ${from}`);
|
|
383
|
+
}
|
|
384
|
+
const parsed = JSON.parse(fs.readFileSync(from, 'utf8'));
|
|
385
|
+
const fromFile = Array.isArray(parsed)
|
|
386
|
+
? parsed
|
|
387
|
+
: (parsed?.findings ?? null);
|
|
388
|
+
if (!Array.isArray(fromFile)) {
|
|
389
|
+
return errorResult(`${from} must hold a JSON array of findings, or an object with a "findings" array.`);
|
|
390
|
+
}
|
|
391
|
+
// Validate each row with the SAME schema the inline `findings`
|
|
392
|
+
// argument gets. A bare `as ImportedFinding[]` here let a row whose
|
|
393
|
+
// `growing_classes` is a string reach `fingerprintOf`, which sorts
|
|
394
|
+
// and joins it — producing a fingerprint no real `check` can ever
|
|
395
|
+
// match, and silently defeating the seeding this action exists for.
|
|
396
|
+
// A malformed row is reported as skipped, never cast through.
|
|
397
|
+
fromFile.forEach((row, i) => {
|
|
398
|
+
const parsedRow = IMPORTED_FINDING_SCHEMA.safeParse(row);
|
|
399
|
+
if (parsedRow.success) {
|
|
400
|
+
incoming.push(parsedRow.data);
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
fileErrors.push(`${from} entry ${i}: ${parsedRow.error.issues
|
|
404
|
+
.map(issue => `${issue.path.join('.') || '(root)'} ${issue.message}`)
|
|
405
|
+
.join('; ')}`);
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
if (incoming.length === 0) {
|
|
410
|
+
return errorResult('action "import" needs `findings` (inline) or `from` (a JSON file path).');
|
|
411
|
+
}
|
|
412
|
+
const { imported, updated, skipped } = importFindings(index, incoming);
|
|
413
|
+
skipped.unshift(...fileErrors);
|
|
414
|
+
saveIndex(indexPath, index);
|
|
415
|
+
return toolResult([
|
|
416
|
+
`Imported **${imported} new** and updated **${updated}** finding(s) into \`${indexPath}\`; ` +
|
|
417
|
+
`the index now holds ${formatNumber(Object.keys(index.findings).length)}.`,
|
|
418
|
+
skipped.length > 0
|
|
419
|
+
? `\nSkipped ${skipped.length}:\n${skipped.map(s => `- ${s}`).join('\n')}`
|
|
420
|
+
: '',
|
|
421
|
+
'\n`check` verdicts of NEW are now meaningful for anything this history covers. ' +
|
|
422
|
+
'Imported entries carry `seen_count: 1` — they are history, not sightings by this operator.',
|
|
423
|
+
]
|
|
424
|
+
.filter(Boolean)
|
|
425
|
+
.join('\n'));
|
|
426
|
+
}
|
|
427
|
+
if (action === 'list') {
|
|
428
|
+
const all = Object.values(index.findings);
|
|
429
|
+
if (!hasAppHistory(index)) {
|
|
430
|
+
return toolResult(`The findings index at \`${indexPath}\` is **empty**, so every \`check\` in this ` +
|
|
431
|
+
'session will answer NEW — including for findings that are already documented ' +
|
|
432
|
+
'and already fixed. Seed it first with `action: "import"` from the workstream\'s ' +
|
|
433
|
+
'history, then record findings as you confirm them (`action: "record"`).');
|
|
434
|
+
}
|
|
435
|
+
const rows = all
|
|
436
|
+
.sort((a, b) => b.seen_count - a.seen_count)
|
|
437
|
+
.slice(0, 40)
|
|
438
|
+
.map(f => [
|
|
439
|
+
f.fingerprint,
|
|
440
|
+
f.status === 'fixed'
|
|
441
|
+
? `fixed (${f.fixed_behind ?? '?'})`
|
|
442
|
+
: f.status,
|
|
443
|
+
f.growing_classes.slice(0, 3).join(', ') || '—',
|
|
444
|
+
`${f.first_seen_round}${f.last_seen_round !== f.first_seen_round ? `→${f.last_seen_round}` : ''}`,
|
|
445
|
+
String(f.seen_count),
|
|
446
|
+
f.signature.length > 60
|
|
447
|
+
? f.signature.slice(0, 57) + '…'
|
|
448
|
+
: f.signature,
|
|
449
|
+
]);
|
|
450
|
+
// Sort by round id rather than trusting object insertion order: a
|
|
451
|
+
// re-recorded round moves in the object and "the last 8" silently
|
|
452
|
+
// stops meaning the most recent ones.
|
|
453
|
+
const covered = Object.entries(index.combos_driven)
|
|
454
|
+
.sort((a, b) => a[0].localeCompare(b[0], undefined, { numeric: true }))
|
|
455
|
+
.slice(-8)
|
|
456
|
+
.map(([r, c]) => `${r}: ${c.join(', ')}`);
|
|
457
|
+
return toolResult([
|
|
458
|
+
`## Findings index (${formatNumber(all.length)}) — \`${indexPath}\``,
|
|
459
|
+
'',
|
|
460
|
+
markdownTable([
|
|
461
|
+
'Fingerprint',
|
|
462
|
+
'Status',
|
|
463
|
+
'Classes',
|
|
464
|
+
'Rounds',
|
|
465
|
+
'Seen',
|
|
466
|
+
'Signature',
|
|
467
|
+
], rows, new Set([4])),
|
|
468
|
+
covered.length > 0 ? '\n### Combo coverage by round\n' : '',
|
|
469
|
+
...covered.map(c => `- ${c}`),
|
|
470
|
+
].join('\n'));
|
|
471
|
+
}
|
|
472
|
+
if (action === 'cover') {
|
|
473
|
+
if (!round)
|
|
474
|
+
return errorResult('action "cover" requires a round.');
|
|
475
|
+
index.combos_driven[round] = combos;
|
|
476
|
+
saveIndex(indexPath, index);
|
|
477
|
+
return toolResult(`Recorded ${combos.length} combo(s) driven in ${round}: ${combos.join(', ') || '(none)'}.`);
|
|
478
|
+
}
|
|
479
|
+
if (!retainer_path) {
|
|
480
|
+
return errorResult(`action "${action}" requires a retainer_path.`);
|
|
481
|
+
}
|
|
482
|
+
const signature = normalizeRetainerPath(retainer_path);
|
|
483
|
+
const fingerprint = fingerprintOf(signature, growing_classes);
|
|
484
|
+
const existing = index.findings[fingerprint];
|
|
485
|
+
if (action === 'check') {
|
|
486
|
+
if (!existing) {
|
|
487
|
+
// The single most damaging thing this tool can do is answer NEW from
|
|
488
|
+
// an index that has never been seeded — the verdict looks identical
|
|
489
|
+
// to a real one, and it has already sent a round off to re-derive a
|
|
490
|
+
// documented, already-fixed finding. Say so at the point of use.
|
|
491
|
+
const indexSize = Object.keys(index.findings).length;
|
|
492
|
+
const unreliable = !hasAppHistory(index)
|
|
493
|
+
? [
|
|
494
|
+
'',
|
|
495
|
+
`> ⚠️ **The index at \`${indexPath}\` is EMPTY, so this verdict carries no information.** ` +
|
|
496
|
+
'Every candidate reads as NEW. Seed the workstream history with ' +
|
|
497
|
+
'`action: "import"` before treating a NEW here as evidence of anything.',
|
|
498
|
+
]
|
|
499
|
+
: [];
|
|
500
|
+
const related = relatedByClass(index, growing_classes, fingerprint);
|
|
501
|
+
const relatedLines = related.length === 0
|
|
502
|
+
? []
|
|
503
|
+
: [
|
|
504
|
+
'',
|
|
505
|
+
`### ⚠️ ${related.length} known entr${related.length === 1 ? 'y shares' : 'ies share'} a growing class with this`,
|
|
506
|
+
'',
|
|
507
|
+
...related.map(f => `- **${f.signature}** (${f.first_seen_round}, ${f.status})` +
|
|
508
|
+
` — shares \`${f.growing_classes.filter(c => growing_classes.includes(c)).join('`, `')}\`` +
|
|
509
|
+
(f.note ? `. ${f.note}` : '')),
|
|
510
|
+
'',
|
|
511
|
+
'A shared class is a LEAD, not an identification — the fingerprint above really is new. ' +
|
|
512
|
+
'But if one of these is an artifact family, the population you are looking at is ' +
|
|
513
|
+
'probably not app memory, and that is worth settling before spending the round on it.',
|
|
514
|
+
];
|
|
515
|
+
return toolResult([
|
|
516
|
+
`## NEW finding — fingerprint \`${fingerprint}\``,
|
|
517
|
+
'',
|
|
518
|
+
`Signature: \`${signature}\``,
|
|
519
|
+
...unreliable,
|
|
520
|
+
'',
|
|
521
|
+
`No previous round in this index (${formatNumber(indexSize)} finding(s)) recorded this ` +
|
|
522
|
+
'retainer path with this class set. Confirm it, then `action: "record"` so the next ' +
|
|
523
|
+
'round recognizes it.',
|
|
524
|
+
...relatedLines,
|
|
525
|
+
].join('\n'));
|
|
526
|
+
}
|
|
527
|
+
const label = existing.status === 'fixed'
|
|
528
|
+
? `KNOWN-AND-FIXED-BEHIND(${existing.fixed_behind ?? 'unknown gate'})`
|
|
529
|
+
: `KNOWN (${existing.first_seen_round})`;
|
|
530
|
+
return toolResult([
|
|
531
|
+
`## ${label} — fingerprint \`${fingerprint}\``,
|
|
532
|
+
'',
|
|
533
|
+
`Signature: \`${signature}\``,
|
|
534
|
+
`First seen: ${existing.first_seen_round}; last seen: ${existing.last_seen_round}; seen ${existing.seen_count}×.`,
|
|
535
|
+
existing.note ? `Note: ${existing.note}` : '',
|
|
536
|
+
'',
|
|
537
|
+
existing.status === 'fixed'
|
|
538
|
+
? `**Stop here.** This leak is already fixed behind \`${existing.fixed_behind}\`. If it is still reproducing, the gate is probably not enabled in this run — verify the gating state before treating it as a finding.`
|
|
539
|
+
: '**This is not a new finding.** Check whether the earlier round already root-caused it before spending the rest of this one on it.',
|
|
540
|
+
]
|
|
541
|
+
.filter(Boolean)
|
|
542
|
+
.join('\n'));
|
|
543
|
+
}
|
|
544
|
+
// record
|
|
545
|
+
const roundId = round ?? 'unknown';
|
|
546
|
+
index.findings[fingerprint] = {
|
|
547
|
+
fingerprint,
|
|
548
|
+
signature,
|
|
549
|
+
growing_classes,
|
|
550
|
+
first_seen_round: existing?.first_seen_round ?? roundId,
|
|
551
|
+
last_seen_round: roundId,
|
|
552
|
+
status,
|
|
553
|
+
fixed_behind: fixed_behind ?? existing?.fixed_behind,
|
|
554
|
+
note: note ?? existing?.note,
|
|
555
|
+
seen_count: (existing?.seen_count ?? 0) + 1,
|
|
556
|
+
};
|
|
557
|
+
saveIndex(indexPath, index);
|
|
558
|
+
return toolResult(`Recorded \`${fingerprint}\` as **${status}**${fixed_behind ? ` (behind \`${fixed_behind}\`)` : ''} for round ${roundId}. ` +
|
|
559
|
+
`Signature: \`${signature}\`. The index now holds ${formatNumber(Object.keys(index.findings).length)} finding(s).`);
|
|
560
|
+
}
|
|
561
|
+
catch (err) {
|
|
562
|
+
return errorResult(err);
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
//# sourceMappingURL=finding-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-index.js","sourceRoot":"","sources":["../../src/tools/finding-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"for-each.d.ts","sourceRoot":"","sources":["../../src/tools/for-each.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AA2BvE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+
|
|
1
|
+
{"version":3,"file":"for-each.d.ts","sourceRoot":"","sources":["../../src/tools/for-each.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AA2BvE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+NvD"}
|