memorydetective 1.2.0 → 1.3.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/CHANGELOG.md +44 -1
- package/README.md +37 -1
- package/USAGE.md +39 -23
- package/dist/cli.js +1 -1
- package/dist/index.js +34 -25
- package/dist/index.js.map +1 -1
- package/dist/runtime/suggestions.d.ts +44 -0
- package/dist/runtime/suggestions.js +161 -0
- package/dist/runtime/suggestions.js.map +1 -0
- package/dist/tools/analyzeMemgraph.d.ts +3 -1
- package/dist/tools/analyzeMemgraph.js +8 -0
- package/dist/tools/analyzeMemgraph.js.map +1 -1
- package/dist/tools/classifyCycle.d.ts +8 -1
- package/dist/tools/classifyCycle.js +28 -3
- package/dist/tools/classifyCycle.js.map +1 -1
- package/dist/tools/findRetainers.d.ts +3 -1
- package/dist/tools/findRetainers.js +5 -0
- package/dist/tools/findRetainers.js.map +1 -1
- package/dist/tools/getInvestigationPlaybook.d.ts +43 -0
- package/dist/tools/getInvestigationPlaybook.js +220 -0
- package/dist/tools/getInvestigationPlaybook.js.map +1 -0
- package/dist/tools/reachableFromCycle.d.ts +4 -2
- package/dist/tools/reachableFromCycle.js +14 -1
- package/dist/tools/reachableFromCycle.js.map +1 -1
- package/dist/tools/swift/findSymbolReferences.d.ts +2 -2
- package/dist/tools/swift/getHoverInfo.d.ts +2 -2
- package/dist/tools/swift/getSymbolDefinition.d.ts +6 -6
- package/dist/tools/swift/searchPattern.d.ts +2 -2
- package/dist/types.d.ts +14 -0
- package/package.json +1 -1
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for building `suggestedNextCalls` arrays. Centralized so multiple
|
|
3
|
+
* tools agree on the same heuristics for "which class is most actionable"
|
|
4
|
+
* and "which followup is most useful".
|
|
5
|
+
*/
|
|
6
|
+
/** Class names that are SwiftUI / Foundation internals; never the user's code. */
|
|
7
|
+
const STDLIB_PREFIXES = [
|
|
8
|
+
"Swift.",
|
|
9
|
+
"SwiftUI.",
|
|
10
|
+
"Foundation.",
|
|
11
|
+
"Combine.",
|
|
12
|
+
"_Concurrency.",
|
|
13
|
+
"_DictionaryStorage",
|
|
14
|
+
"Closure",
|
|
15
|
+
"ForEach",
|
|
16
|
+
"Modified",
|
|
17
|
+
"AsyncImage",
|
|
18
|
+
"StoredLocation",
|
|
19
|
+
"LocationBox",
|
|
20
|
+
"TagIndex",
|
|
21
|
+
"AnyHashable",
|
|
22
|
+
"WeakBox",
|
|
23
|
+
"AnyLocation",
|
|
24
|
+
"MutableBox",
|
|
25
|
+
"AGSubgraph",
|
|
26
|
+
"NSURL",
|
|
27
|
+
"NSObject",
|
|
28
|
+
"NSDictionary",
|
|
29
|
+
"NSMutableArray",
|
|
30
|
+
"NSMutableDictionary",
|
|
31
|
+
"NSHashTable",
|
|
32
|
+
"NSLock",
|
|
33
|
+
"CFDictionary",
|
|
34
|
+
"_NSURL",
|
|
35
|
+
"__NS",
|
|
36
|
+
];
|
|
37
|
+
/** True when this class name looks like the user's own code (not stdlib / system). */
|
|
38
|
+
export function looksAppLevel(className) {
|
|
39
|
+
if (!className)
|
|
40
|
+
return false;
|
|
41
|
+
return !STDLIB_PREFIXES.some((p) => className.startsWith(p));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* From a list of class names in a cycle, pick the most likely "the thing the
|
|
45
|
+
* user wrote" — the dominant app-level class. Used to seed swift* followups.
|
|
46
|
+
*/
|
|
47
|
+
export function pickPrimaryAppClass(classNames) {
|
|
48
|
+
for (const name of classNames) {
|
|
49
|
+
if (looksAppLevel(name))
|
|
50
|
+
return name;
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
/** Pull primary app-level class from a CycleSummary's chain. */
|
|
55
|
+
export function primaryAppClassFor(summary) {
|
|
56
|
+
return pickPrimaryAppClass(summary.classesInChain);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Build a suggestedNextCalls array for `classifyCycle`'s output.
|
|
60
|
+
* Maps the matched pattern + the cycle root to the most useful followups.
|
|
61
|
+
*/
|
|
62
|
+
export function suggestionsForClassification(opts) {
|
|
63
|
+
const out = [];
|
|
64
|
+
// Pattern → likely fix-locator regex.
|
|
65
|
+
const patternToRegex = patternToCodeSearchRegex(opts.patternId);
|
|
66
|
+
if (patternToRegex) {
|
|
67
|
+
out.push({
|
|
68
|
+
tool: "swiftSearchPattern",
|
|
69
|
+
args: {
|
|
70
|
+
pattern: patternToRegex,
|
|
71
|
+
// Caller fills in filePath; we leave a placeholder so the agent
|
|
72
|
+
// notices and substitutes.
|
|
73
|
+
filePath: "<set to a candidate Swift file in your project>",
|
|
74
|
+
},
|
|
75
|
+
why: `Locate the code construct implicated by ${opts.patternId ?? "the matched pattern"}. The regex matches the SwiftUI / Combine signal that produces this cycle.`,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
if (opts.appLevelClass) {
|
|
79
|
+
out.push({
|
|
80
|
+
tool: "swiftGetSymbolDefinition",
|
|
81
|
+
args: {
|
|
82
|
+
symbolName: opts.appLevelClass,
|
|
83
|
+
candidatePaths: ["<set to a Sources/ or app target directory>"],
|
|
84
|
+
},
|
|
85
|
+
why: `Jump to the declaration of ${opts.appLevelClass}, the user-defined type captured in this cycle.`,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Map a pattern id to a Swift regex that surfaces the offending code.
|
|
92
|
+
* Returns `null` when we don't have a clean pattern → regex translation
|
|
93
|
+
* (better to omit a hint than to suggest a broken one).
|
|
94
|
+
*/
|
|
95
|
+
function patternToCodeSearchRegex(patternId) {
|
|
96
|
+
switch (patternId) {
|
|
97
|
+
case "swiftui.tag-index-projection":
|
|
98
|
+
return "\\.tag\\(";
|
|
99
|
+
case "swiftui.foreach-state-tap":
|
|
100
|
+
return "ForEach\\b[\\s\\S]{0,200}?\\.onTapGesture";
|
|
101
|
+
case "closure.viewmodel-wrapped-strong":
|
|
102
|
+
return "_viewModel\\.wrappedValue";
|
|
103
|
+
case "viewcontroller.uinavigationcontroller-host":
|
|
104
|
+
return "UIHostingController|dismantleUIViewController";
|
|
105
|
+
case "combine.sink-store-self-capture":
|
|
106
|
+
return "\\.sink\\s*\\{";
|
|
107
|
+
case "concurrency.task-without-weak-self":
|
|
108
|
+
return "Task\\s*\\{";
|
|
109
|
+
case "notificationcenter.observer-strong":
|
|
110
|
+
return "addObserver\\s*\\(\\s*forName";
|
|
111
|
+
case "swiftui.dictstorage-weakbox-cycle":
|
|
112
|
+
// Internal SwiftUI; no user-code surface to point at directly.
|
|
113
|
+
return null;
|
|
114
|
+
default:
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/** Build suggestion to call swiftFindSymbolReferences for a class name. */
|
|
119
|
+
export function suggestionFindReferences(opts) {
|
|
120
|
+
return {
|
|
121
|
+
tool: "swiftFindSymbolReferences",
|
|
122
|
+
args: {
|
|
123
|
+
symbolName: opts.symbolName,
|
|
124
|
+
filePath: opts.filePath ?? "<set to the file where the symbol is declared>",
|
|
125
|
+
},
|
|
126
|
+
why: `Find every callsite of ${opts.symbolName} in the project. Useful to compare capture-list patterns across callsites.`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/** Build suggestion to call swiftGetSymbolDefinition for a class name. */
|
|
130
|
+
export function suggestionGetDefinition(opts) {
|
|
131
|
+
return {
|
|
132
|
+
tool: "swiftGetSymbolDefinition",
|
|
133
|
+
args: {
|
|
134
|
+
symbolName: opts.symbolName,
|
|
135
|
+
candidatePaths: opts.candidatePaths ?? [
|
|
136
|
+
"<set to Sources/ or app target directories>",
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
why: `Locate where ${opts.symbolName} is declared in the project.`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/** Build suggestion to call classifyCycle (used after analyzeMemgraph). */
|
|
143
|
+
export function suggestionClassifyCycle(opts) {
|
|
144
|
+
return {
|
|
145
|
+
tool: "classifyCycle",
|
|
146
|
+
args: { path: opts.path },
|
|
147
|
+
why: "Match each ROOT CYCLE against the built-in pattern catalog to get a named antipattern + concrete fix hint.",
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/** Build suggestion to call reachableFromCycle (used after analyzeMemgraph). */
|
|
151
|
+
export function suggestionReachableFromCycle(opts) {
|
|
152
|
+
return {
|
|
153
|
+
tool: "reachableFromCycle",
|
|
154
|
+
args: {
|
|
155
|
+
path: opts.path,
|
|
156
|
+
cycleIndex: opts.cycleIndex ?? 0,
|
|
157
|
+
},
|
|
158
|
+
why: "Confirm which app-level class is the actual culprit (the cycle root) versus collateral retained dependencies.",
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=suggestions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggestions.js","sourceRoot":"","sources":["../../src/runtime/suggestions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { type Verbosity } from "../parsers/shortenClassName.js";
|
|
3
|
-
import type { LeaksReport } from "../types.js";
|
|
3
|
+
import type { LeaksReport, NextCallSuggestion } from "../types.js";
|
|
4
4
|
export declare const analyzeMemgraphSchema: z.ZodObject<{
|
|
5
5
|
path: z.ZodString;
|
|
6
6
|
fullChains: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -49,6 +49,8 @@ export interface AnalyzeMemgraphResult {
|
|
|
49
49
|
fullReport?: LeaksReport;
|
|
50
50
|
/** Plain-English diagnosis (one liner). */
|
|
51
51
|
diagnosis: string;
|
|
52
|
+
/** Pipeline hints — chain `classifyCycle` next, then `reachableFromCycle` to scope blame. */
|
|
53
|
+
suggestedNextCalls?: NextCallSuggestion[];
|
|
52
54
|
}
|
|
53
55
|
/**
|
|
54
56
|
* Pure function: take a `leaks` stdout string and a source path, produce a structured analysis.
|
|
@@ -4,6 +4,7 @@ import { resolve as resolvePath } from "node:path";
|
|
|
4
4
|
import { runCommand } from "../runtime/exec.js";
|
|
5
5
|
import { parseLeaksOutput, rootCyclesOnly } from "../parsers/leaksOutput.js";
|
|
6
6
|
import { shortenForVerbosity, } from "../parsers/shortenClassName.js";
|
|
7
|
+
import { suggestionClassifyCycle, suggestionReachableFromCycle, } from "../runtime/suggestions.js";
|
|
7
8
|
export const analyzeMemgraphSchema = z.object({
|
|
8
9
|
path: z
|
|
9
10
|
.string()
|
|
@@ -34,6 +35,12 @@ export function summarizeLeaks(leaksText, path, fullChains = false, verbosity =
|
|
|
34
35
|
const roots = rootCyclesOnly(report.cycles);
|
|
35
36
|
const cycles = roots.map((c) => summarizeCycle(c, verbosity, maxClassesInChain));
|
|
36
37
|
const diagnosis = buildDiagnosis(report, cycles);
|
|
38
|
+
const suggestedNextCalls = cycles.length > 0
|
|
39
|
+
? [
|
|
40
|
+
suggestionClassifyCycle({ path }),
|
|
41
|
+
suggestionReachableFromCycle({ path, cycleIndex: 0 }),
|
|
42
|
+
]
|
|
43
|
+
: [];
|
|
37
44
|
return {
|
|
38
45
|
ok: true,
|
|
39
46
|
path,
|
|
@@ -49,6 +56,7 @@ export function summarizeLeaks(leaksText, path, fullChains = false, verbosity =
|
|
|
49
56
|
cycles,
|
|
50
57
|
...(fullChains ? { fullReport: report } : {}),
|
|
51
58
|
diagnosis,
|
|
59
|
+
...(suggestedNextCalls.length > 0 ? { suggestedNextCalls } : {}),
|
|
52
60
|
};
|
|
53
61
|
}
|
|
54
62
|
function summarizeCycle(node, verbosity, maxClassesInChain) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzeMemgraph.js","sourceRoot":"","sources":["../../src/tools/analyzeMemgraph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EACL,mBAAmB,GAEpB,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"analyzeMemgraph.js","sourceRoot":"","sources":["../../src/tools/analyzeMemgraph.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type { CycleNode, LeaksReport } from "../types.js";
|
|
2
|
+
import type { CycleNode, LeaksReport, NextCallSuggestion } from "../types.js";
|
|
3
3
|
export declare const classifyCycleSchema: z.ZodObject<{
|
|
4
4
|
path: z.ZodString;
|
|
5
5
|
maxResults: z.ZodDefault<z.ZodNumber>;
|
|
@@ -37,6 +37,12 @@ export interface ClassifyCycleResult {
|
|
|
37
37
|
path: string;
|
|
38
38
|
totalCycles: number;
|
|
39
39
|
classified: CycleClassification[];
|
|
40
|
+
/**
|
|
41
|
+
* Suggested next tool calls based on the highest-confidence pattern hit.
|
|
42
|
+
* Each entry has pre-populated args and a one-sentence rationale —
|
|
43
|
+
* the orchestrator can chain them without re-reasoning over the result.
|
|
44
|
+
*/
|
|
45
|
+
suggestedNextCalls?: NextCallSuggestion[];
|
|
40
46
|
}
|
|
41
47
|
interface PatternDefinition {
|
|
42
48
|
id: string;
|
|
@@ -51,6 +57,7 @@ export declare const PATTERNS: PatternDefinition[];
|
|
|
51
57
|
export declare function classifyReport(report: LeaksReport, maxResults?: number): {
|
|
52
58
|
totalCycles: number;
|
|
53
59
|
classified: CycleClassification[];
|
|
60
|
+
classNamesByIndex: string[][];
|
|
54
61
|
};
|
|
55
62
|
export declare function classifyCycle(input: ClassifyCycleInput): Promise<ClassifyCycleResult>;
|
|
56
63
|
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { runLeaksAndParse } from "../runtime/leaks.js";
|
|
3
3
|
import { rootCyclesOnly, walkCycles } from "../parsers/leaksOutput.js";
|
|
4
|
+
import { pickPrimaryAppClass, suggestionsForClassification, } from "../runtime/suggestions.js";
|
|
4
5
|
export const classifyCycleSchema = z.object({
|
|
5
6
|
path: z.string().min(1).describe("Absolute path to a `.memgraph` file."),
|
|
6
7
|
maxResults: z
|
|
@@ -102,6 +103,7 @@ export const PATTERNS = [
|
|
|
102
103
|
/** Pure: classify each ROOT CYCLE in the parsed report. */
|
|
103
104
|
export function classifyReport(report, maxResults = 20) {
|
|
104
105
|
const roots = rootCyclesOnly(report.cycles);
|
|
106
|
+
const classNamesByIndex = [];
|
|
105
107
|
const classified = roots
|
|
106
108
|
.slice(0, maxResults)
|
|
107
109
|
.map((root) => {
|
|
@@ -110,6 +112,7 @@ export function classifyReport(report, maxResults = 20) {
|
|
|
110
112
|
if (node.className)
|
|
111
113
|
allClasses.add(node.className);
|
|
112
114
|
}
|
|
115
|
+
classNamesByIndex.push(Array.from(allClasses));
|
|
113
116
|
const matches = [];
|
|
114
117
|
for (const p of PATTERNS) {
|
|
115
118
|
const conf = p.match(root, allClasses);
|
|
@@ -133,11 +136,33 @@ export function classifyReport(report, maxResults = 20) {
|
|
|
133
136
|
allMatches: matches,
|
|
134
137
|
};
|
|
135
138
|
});
|
|
136
|
-
return { totalCycles: roots.length, classified };
|
|
139
|
+
return { totalCycles: roots.length, classified, classNamesByIndex };
|
|
137
140
|
}
|
|
138
141
|
export async function classifyCycle(input) {
|
|
139
142
|
const { report, resolvedPath } = await runLeaksAndParse(input.path);
|
|
140
|
-
const { totalCycles, classified } = classifyReport(report, input.maxResults ?? 20);
|
|
141
|
-
|
|
143
|
+
const { totalCycles, classified, classNamesByIndex } = classifyReport(report, input.maxResults ?? 20);
|
|
144
|
+
// Build suggestedNextCalls based on the highest-confidence match across
|
|
145
|
+
// all cycles. Picks the first cycle with a primary match (cycles are
|
|
146
|
+
// emitted in descending leak-count order, so this is the dominant one).
|
|
147
|
+
const suggestedNextCalls = [];
|
|
148
|
+
for (let i = 0; i < classified.length; i++) {
|
|
149
|
+
const c = classified[i];
|
|
150
|
+
if (!c.primaryMatch)
|
|
151
|
+
continue;
|
|
152
|
+
const appLevel = pickPrimaryAppClass(classNamesByIndex[i] ?? []);
|
|
153
|
+
suggestedNextCalls.push(...suggestionsForClassification({
|
|
154
|
+
patternId: c.primaryMatch.patternId,
|
|
155
|
+
rootClass: c.rootClass,
|
|
156
|
+
appLevelClass: appLevel,
|
|
157
|
+
}));
|
|
158
|
+
break; // one cycle's worth is enough
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
ok: true,
|
|
162
|
+
path: resolvedPath,
|
|
163
|
+
totalCycles,
|
|
164
|
+
classified,
|
|
165
|
+
...(suggestedNextCalls.length > 0 ? { suggestedNextCalls } : {}),
|
|
166
|
+
};
|
|
142
167
|
}
|
|
143
168
|
//# sourceMappingURL=classifyCycle.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classifyCycle.js","sourceRoot":"","sources":["../../src/tools/classifyCycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"classifyCycle.js","sourceRoot":"","sources":["../../src/tools/classifyCycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type { LeaksReport } from "../types.js";
|
|
2
|
+
import type { LeaksReport, NextCallSuggestion } from "../types.js";
|
|
3
3
|
export declare const findRetainersSchema: z.ZodObject<{
|
|
4
4
|
path: z.ZodString;
|
|
5
5
|
className: z.ZodString;
|
|
@@ -33,6 +33,8 @@ export interface FindRetainersResult {
|
|
|
33
33
|
className: string;
|
|
34
34
|
totalMatches: number;
|
|
35
35
|
retainers: RetainerChain[];
|
|
36
|
+
/** Pipeline hint — once you know who retains the class, locate it in source. */
|
|
37
|
+
suggestedNextCalls?: NextCallSuggestion[];
|
|
36
38
|
}
|
|
37
39
|
/**
|
|
38
40
|
* Walk the cycle forest and collect every parent-path that ends in a node whose
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { runLeaksAndParse } from "../runtime/leaks.js";
|
|
3
|
+
import { suggestionGetDefinition } from "../runtime/suggestions.js";
|
|
3
4
|
export const findRetainersSchema = z.object({
|
|
4
5
|
path: z.string().min(1).describe("Absolute path to a `.memgraph` file."),
|
|
5
6
|
className: z
|
|
@@ -48,12 +49,16 @@ export function findRetainersIn(report, needle, maxResults = 10) {
|
|
|
48
49
|
export async function findRetainers(input) {
|
|
49
50
|
const { report, resolvedPath } = await runLeaksAndParse(input.path);
|
|
50
51
|
const { totalMatches, retainers } = findRetainersIn(report, input.className, input.maxResults ?? 10);
|
|
52
|
+
const suggestedNextCalls = totalMatches > 0
|
|
53
|
+
? [suggestionGetDefinition({ symbolName: input.className })]
|
|
54
|
+
: [];
|
|
51
55
|
return {
|
|
52
56
|
ok: true,
|
|
53
57
|
path: resolvedPath,
|
|
54
58
|
className: input.className,
|
|
55
59
|
totalMatches,
|
|
56
60
|
retainers,
|
|
61
|
+
...(suggestedNextCalls.length > 0 ? { suggestedNextCalls } : {}),
|
|
57
62
|
};
|
|
58
63
|
}
|
|
59
64
|
//# sourceMappingURL=findRetainers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findRetainers.js","sourceRoot":"","sources":["../../src/tools/findRetainers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"findRetainers.js","sourceRoot":"","sources":["../../src/tools/findRetainers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Meta-tool: returns the canonical investigation sequence for a known
|
|
4
|
+
* problem class. Lets a fresh LLM agent jump straight to the right pipeline
|
|
5
|
+
* without rediscovering the order from tool descriptions.
|
|
6
|
+
*
|
|
7
|
+
* Each playbook is a versioned, declarative sequence of tool calls with a
|
|
8
|
+
* stable `step` number, a `purpose` line, and `argsTemplate` showing which
|
|
9
|
+
* args matter most. The agent fills in concrete values from the user's
|
|
10
|
+
* context (file paths, class names, etc.).
|
|
11
|
+
*/
|
|
12
|
+
export declare const PlaybookKindEnum: z.ZodEnum<["memgraph-leak", "perf-hangs", "ui-jank", "app-launch-slow", "verify-fix"]>;
|
|
13
|
+
export declare const getInvestigationPlaybookSchema: z.ZodObject<{
|
|
14
|
+
kind: z.ZodEnum<["memgraph-leak", "perf-hangs", "ui-jank", "app-launch-slow", "verify-fix"]>;
|
|
15
|
+
}, "strip", z.ZodTypeAny, {
|
|
16
|
+
kind: "memgraph-leak" | "perf-hangs" | "ui-jank" | "app-launch-slow" | "verify-fix";
|
|
17
|
+
}, {
|
|
18
|
+
kind: "memgraph-leak" | "perf-hangs" | "ui-jank" | "app-launch-slow" | "verify-fix";
|
|
19
|
+
}>;
|
|
20
|
+
export type GetInvestigationPlaybookInput = z.infer<typeof getInvestigationPlaybookSchema>;
|
|
21
|
+
export type PlaybookKind = z.infer<typeof PlaybookKindEnum>;
|
|
22
|
+
export interface PlaybookStep {
|
|
23
|
+
step: number;
|
|
24
|
+
tool: string;
|
|
25
|
+
purpose: string;
|
|
26
|
+
argsTemplate: Record<string, unknown>;
|
|
27
|
+
/** Optional notes about how to interpret the result before moving to the next step. */
|
|
28
|
+
resultGuidance?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface Playbook {
|
|
31
|
+
kind: PlaybookKind;
|
|
32
|
+
summary: string;
|
|
33
|
+
steps: PlaybookStep[];
|
|
34
|
+
/** Pointers to alternative playbooks the agent might want next. */
|
|
35
|
+
seeAlso?: PlaybookKind[];
|
|
36
|
+
}
|
|
37
|
+
export interface GetInvestigationPlaybookResult {
|
|
38
|
+
ok: boolean;
|
|
39
|
+
playbook: Playbook;
|
|
40
|
+
}
|
|
41
|
+
export declare function getInvestigationPlaybook(input: GetInvestigationPlaybookInput): Promise<GetInvestigationPlaybookResult>;
|
|
42
|
+
/** Exposed for tests. */
|
|
43
|
+
export declare const PLAYBOOK_KINDS: PlaybookKind[];
|