perf-skill 0.0.1 → 0.2.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 (116) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +414 -0
  3. package/SKILL.md +238 -0
  4. package/dist/cli/main.d.ts +6 -0
  5. package/dist/cli/main.d.ts.map +1 -0
  6. package/dist/cli/main.js +353 -0
  7. package/dist/cli/main.js.map +1 -0
  8. package/dist/cli/options.d.ts +37 -0
  9. package/dist/cli/options.d.ts.map +1 -0
  10. package/dist/cli/options.js +54 -0
  11. package/dist/cli/options.js.map +1 -0
  12. package/dist/convert/converter.d.ts +39 -0
  13. package/dist/convert/converter.d.ts.map +1 -0
  14. package/dist/convert/converter.js +99 -0
  15. package/dist/convert/converter.js.map +1 -0
  16. package/dist/convert/extract.d.ts +32 -0
  17. package/dist/convert/extract.d.ts.map +1 -0
  18. package/dist/convert/extract.js +235 -0
  19. package/dist/convert/extract.js.map +1 -0
  20. package/dist/convert/index.d.ts +7 -0
  21. package/dist/convert/index.d.ts.map +1 -0
  22. package/dist/convert/index.js +7 -0
  23. package/dist/convert/index.js.map +1 -0
  24. package/dist/convert/sanitize.d.ts +60 -0
  25. package/dist/convert/sanitize.d.ts.map +1 -0
  26. package/dist/convert/sanitize.js +169 -0
  27. package/dist/convert/sanitize.js.map +1 -0
  28. package/dist/diff/engine.d.ts +76 -0
  29. package/dist/diff/engine.d.ts.map +1 -0
  30. package/dist/diff/engine.js +386 -0
  31. package/dist/diff/engine.js.map +1 -0
  32. package/dist/diff/index.d.ts +6 -0
  33. package/dist/diff/index.d.ts.map +1 -0
  34. package/dist/diff/index.js +6 -0
  35. package/dist/diff/index.js.map +1 -0
  36. package/dist/diff/markdown.d.ts +16 -0
  37. package/dist/diff/markdown.d.ts.map +1 -0
  38. package/dist/diff/markdown.js +342 -0
  39. package/dist/diff/markdown.js.map +1 -0
  40. package/dist/index.d.ts +52 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +247 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/llm/client.d.ts +39 -0
  45. package/dist/llm/client.d.ts.map +1 -0
  46. package/dist/llm/client.js +270 -0
  47. package/dist/llm/client.js.map +1 -0
  48. package/dist/llm/index.d.ts +8 -0
  49. package/dist/llm/index.d.ts.map +1 -0
  50. package/dist/llm/index.js +8 -0
  51. package/dist/llm/index.js.map +1 -0
  52. package/dist/llm/prompt.d.ts +32 -0
  53. package/dist/llm/prompt.d.ts.map +1 -0
  54. package/dist/llm/prompt.js +146 -0
  55. package/dist/llm/prompt.js.map +1 -0
  56. package/dist/llm/schema.d.ts +150 -0
  57. package/dist/llm/schema.d.ts.map +1 -0
  58. package/dist/llm/schema.js +131 -0
  59. package/dist/llm/schema.js.map +1 -0
  60. package/dist/llm/validate.d.ts +33 -0
  61. package/dist/llm/validate.d.ts.map +1 -0
  62. package/dist/llm/validate.js +241 -0
  63. package/dist/llm/validate.js.map +1 -0
  64. package/dist/profile/duration.d.ts +2 -0
  65. package/dist/profile/duration.d.ts.map +1 -0
  66. package/dist/profile/duration.js +24 -0
  67. package/dist/profile/duration.js.map +1 -0
  68. package/dist/profile/preload.d.ts +2 -0
  69. package/dist/profile/preload.d.ts.map +1 -0
  70. package/dist/profile/preload.js +100 -0
  71. package/dist/profile/preload.js.map +1 -0
  72. package/dist/profile/runner.d.ts +22 -0
  73. package/dist/profile/runner.d.ts.map +1 -0
  74. package/dist/profile/runner.js +88 -0
  75. package/dist/profile/runner.js.map +1 -0
  76. package/dist/server/http.d.ts +27 -0
  77. package/dist/server/http.d.ts.map +1 -0
  78. package/dist/server/http.js +285 -0
  79. package/dist/server/http.js.map +1 -0
  80. package/dist/server/utils.d.ts +15 -0
  81. package/dist/server/utils.d.ts.map +1 -0
  82. package/dist/server/utils.js +71 -0
  83. package/dist/server/utils.js.map +1 -0
  84. package/dist/skill/handler.d.ts +77 -0
  85. package/dist/skill/handler.d.ts.map +1 -0
  86. package/dist/skill/handler.js +91 -0
  87. package/dist/skill/handler.js.map +1 -0
  88. package/dist/skill/index.d.ts +6 -0
  89. package/dist/skill/index.d.ts.map +1 -0
  90. package/dist/skill/index.js +6 -0
  91. package/dist/skill/index.js.map +1 -0
  92. package/dist/skill/manifest.d.ts +17 -0
  93. package/dist/skill/manifest.d.ts.map +1 -0
  94. package/dist/skill/manifest.js +231 -0
  95. package/dist/skill/manifest.js.map +1 -0
  96. package/dist/types.d.ts +260 -0
  97. package/dist/types.d.ts.map +1 -0
  98. package/dist/types.js +5 -0
  99. package/dist/types.js.map +1 -0
  100. package/dist/utils/fs.d.ts +52 -0
  101. package/dist/utils/fs.d.ts.map +1 -0
  102. package/dist/utils/fs.js +106 -0
  103. package/dist/utils/fs.js.map +1 -0
  104. package/dist/utils/index.d.ts +7 -0
  105. package/dist/utils/index.d.ts.map +1 -0
  106. package/dist/utils/index.js +7 -0
  107. package/dist/utils/index.js.map +1 -0
  108. package/dist/utils/limits.d.ts +38 -0
  109. package/dist/utils/limits.d.ts.map +1 -0
  110. package/dist/utils/limits.js +86 -0
  111. package/dist/utils/limits.js.map +1 -0
  112. package/dist/utils/logger.d.ts +21 -0
  113. package/dist/utils/logger.d.ts.map +1 -0
  114. package/dist/utils/logger.js +82 -0
  115. package/dist/utils/logger.js.map +1 -0
  116. package/package.json +70 -6
@@ -0,0 +1,353 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * perf-skill CLI - Analyze pprof profiles with AI assistance
4
+ */
5
+ import { Command } from "commander";
6
+ import { writeFile } from "node:fs/promises";
7
+ import { join, parse, resolve } from "node:path";
8
+ import { analyze, diff } from "../index.js";
9
+ import { parseDurationInput, runCpuProfile } from "../profile/runner.js";
10
+ import { setLogLevel } from "../utils/logger.js";
11
+ import { validateProfileExtension } from "../utils/limits.js";
12
+ import { buildAnalyzeOptions, buildConvertOptions, buildDiffOptions, } from "./options.js";
13
+ const program = new Command();
14
+ program
15
+ .name("perf-skill")
16
+ .description("Analyze pprof profiles with AI-powered recommendations")
17
+ .version("1.0.0");
18
+ function parseOptionalInt(value) {
19
+ if (value === undefined)
20
+ return undefined;
21
+ const parsed = Number.parseInt(value, 10);
22
+ return Number.isFinite(parsed) ? parsed : undefined;
23
+ }
24
+ function deriveSiblingPath(basePath, suffix, defaultExt) {
25
+ const parsed = parse(basePath);
26
+ const ext = parsed.ext || defaultExt;
27
+ const name = parsed.ext ? parsed.name : parsed.base;
28
+ const filename = `${name}.${suffix}${ext}`;
29
+ return parsed.dir ? join(parsed.dir, filename) : filename;
30
+ }
31
+ async function executeAnalyze(profilePath, opts) {
32
+ if (opts.verbose) {
33
+ setLogLevel("debug");
34
+ }
35
+ const resolvedPath = resolve(profilePath);
36
+ validateProfileExtension(resolvedPath);
37
+ const options = buildAnalyzeOptions(opts);
38
+ if (opts.llmProvider || opts.llmModel) {
39
+ options.llm = {
40
+ provider: opts.llmProvider ?? "openai",
41
+ model: opts.llmModel || "gpt-5.2",
42
+ };
43
+ }
44
+ console.log(`Analyzing ${profilePath}...`);
45
+ const result = await analyze(resolvedPath, options);
46
+ if (opts.output) {
47
+ await writeFile(opts.output, result.markdown, "utf-8");
48
+ console.log(`Markdown saved to ${opts.output}`);
49
+ }
50
+ else {
51
+ console.log("\n" + result.markdown);
52
+ }
53
+ if (opts.json) {
54
+ const jsonResult = {
55
+ profileMeta: result.profileMeta,
56
+ hotspots: result.hotspots,
57
+ recommendations: result.recommendations,
58
+ nextSteps: result.nextSteps,
59
+ metrics: result.metrics,
60
+ };
61
+ await writeFile(opts.json, JSON.stringify(jsonResult, null, 2), "utf-8");
62
+ console.log(`JSON saved to ${opts.json}`);
63
+ }
64
+ if (opts.output) {
65
+ console.log(`\nFound ${result.hotspots.length} hotspots`);
66
+ if (result.recommendations) {
67
+ console.log(`Generated ${result.recommendations.length} recommendations`);
68
+ }
69
+ if (result.metrics) {
70
+ console.log(`Processing time: ${result.metrics.totalMs.toFixed(0)}ms`);
71
+ }
72
+ }
73
+ }
74
+ // Analyze command (default)
75
+ program
76
+ .command("analyze", { isDefault: true })
77
+ .description("Analyze a single pprof profile")
78
+ .argument("<profile>", "Path to pprof profile (.pb.gz)")
79
+ .option("-f, --format <format>", "Output format: summary, detailed, adaptive", "adaptive")
80
+ .option("-t, --type <type>", "Profile type: cpu, heap, auto", "auto")
81
+ .option("-o, --output <file>", "Output markdown file")
82
+ .option("-j, --json <file>", "Output JSON results file")
83
+ .option("-s, --source-dir <path>", "Source directory for code context")
84
+ .option("--no-source", "Disable source code inclusion")
85
+ .option("--max-hotspots <n>", "Maximum hotspots to show", "10")
86
+ .option("-m, --mode <mode>", "Mode: convert-only, analyze", "analyze")
87
+ .option("--llm-provider <provider>", "LLM provider: openai, azure-openai, anthropic, custom")
88
+ .option("--llm-model <model>", "LLM model name")
89
+ .option("--service <name>", "Service name for context")
90
+ .option("--scenario <desc>", "Scenario description")
91
+ .option("--slo <target>", "Target SLO")
92
+ .option("--no-redact", "Disable redaction of sensitive information")
93
+ .option("-v, --verbose", "Enable verbose logging")
94
+ .action(async (profilePath, opts) => {
95
+ try {
96
+ await executeAnalyze(profilePath, opts);
97
+ }
98
+ catch (error) {
99
+ console.error("Error:", error instanceof Error ? error.message : error);
100
+ process.exit(1);
101
+ }
102
+ });
103
+ // Run command (profile + analyze)
104
+ program
105
+ .command("run")
106
+ .description("Profile a Node entry file and analyze the resulting CPU profile")
107
+ .argument("<entry>", "Entry file to run (js/mjs/cjs)")
108
+ .argument("[entryArgs...]", "Arguments passed to the entry file")
109
+ .option("-d, --duration <duration>", "CPU profile duration (e.g. 10s, 5000ms)", "10s")
110
+ .option("--profile-out <file>", "Profile output file", "cpu.pb.gz")
111
+ .option("--heap", "Also capture a heap profile")
112
+ .option("--heap-profile-out <file>", "Heap profile output file", "heap.pb.gz")
113
+ .option("--heap-interval-bytes <n>", "Heap sampling interval in bytes")
114
+ .option("--heap-stack-depth <n>", "Heap sampling stack depth")
115
+ .option("--heap-output <file>", "Heap markdown output file")
116
+ .option("--heap-json <file>", "Heap JSON output file")
117
+ .option("-f, --format <format>", "Output format: summary, detailed, adaptive", "adaptive")
118
+ .option("-t, --type <type>", "Profile type: cpu, heap, auto", "auto")
119
+ .option("-o, --output <file>", "Output markdown file")
120
+ .option("-j, --json <file>", "Output JSON results file")
121
+ .option("-s, --source-dir <path>", "Source directory for code context")
122
+ .option("--no-source", "Disable source code inclusion")
123
+ .option("--max-hotspots <n>", "Maximum hotspots to show", "10")
124
+ .option("-m, --mode <mode>", "Mode: convert-only, analyze", "analyze")
125
+ .option("--llm-provider <provider>", "LLM provider: openai, azure-openai, anthropic, custom")
126
+ .option("--llm-model <model>", "LLM model name")
127
+ .option("--service <name>", "Service name for context")
128
+ .option("--scenario <desc>", "Scenario description")
129
+ .option("--slo <target>", "Target SLO")
130
+ .option("--no-redact", "Disable redaction of sensitive information")
131
+ .option("-v, --verbose", "Enable verbose logging")
132
+ .action(async (entryPath, entryArgs, opts) => {
133
+ try {
134
+ if (opts.verbose) {
135
+ setLogLevel("debug");
136
+ }
137
+ const durationMs = parseDurationInput(opts.duration);
138
+ const profilePath = resolve(opts.profileOut);
139
+ const heapEnabled = Boolean(opts.heap);
140
+ const heapIntervalBytes = parseOptionalInt(opts.heapIntervalBytes);
141
+ const heapStackDepth = parseOptionalInt(opts.heapStackDepth);
142
+ const cpuOutput = opts.output ?? (heapEnabled ? "cpu.md" : undefined);
143
+ const cpuJson = opts.json;
144
+ const heapOutput = heapEnabled
145
+ ? opts.heapOutput ?? (opts.output ? deriveSiblingPath(opts.output, "heap", ".md") : "heap.md")
146
+ : undefined;
147
+ const heapJson = heapEnabled
148
+ ? opts.heapJson ?? (cpuJson ? deriveSiblingPath(cpuJson, "heap", ".json") : undefined)
149
+ : undefined;
150
+ console.log(`Profiling ${entryPath} for ${opts.duration}...`);
151
+ const { heapProfilePath } = await runCpuProfile({
152
+ entryPath,
153
+ entryArgs,
154
+ durationMs,
155
+ outPath: profilePath,
156
+ enableHeap: heapEnabled,
157
+ heapOutPath: heapEnabled ? resolve(opts.heapProfileOut) : undefined,
158
+ heapIntervalBytes,
159
+ heapStackDepth,
160
+ });
161
+ await executeAnalyze(profilePath, { ...opts, output: cpuOutput, json: cpuJson, type: "cpu" });
162
+ if (heapEnabled && heapProfilePath) {
163
+ await executeAnalyze(heapProfilePath, { ...opts, output: heapOutput, json: heapJson, type: "heap" });
164
+ }
165
+ }
166
+ catch (error) {
167
+ console.error("Error:", error instanceof Error ? error.message : error);
168
+ process.exit(1);
169
+ }
170
+ });
171
+ // Profile-only command
172
+ program
173
+ .command("profile")
174
+ .description("Generate a CPU profile for a Node entry file")
175
+ .argument("<entry>", "Entry file to run (js/mjs/cjs)")
176
+ .argument("[entryArgs...]", "Arguments passed to the entry file")
177
+ .option("-d, --duration <duration>", "CPU profile duration (e.g. 10s, 5000ms)", "10s")
178
+ .option("-o, --output <file>", "Profile output file", "cpu.pb.gz")
179
+ .option("--heap", "Also capture a heap profile")
180
+ .option("--heap-profile-out <file>", "Heap profile output file", "heap.pb.gz")
181
+ .option("--heap-interval-bytes <n>", "Heap sampling interval in bytes")
182
+ .option("--heap-stack-depth <n>", "Heap sampling stack depth")
183
+ .option("-v, --verbose", "Enable verbose logging")
184
+ .action(async (entryPath, entryArgs, opts) => {
185
+ if (opts.verbose) {
186
+ setLogLevel("debug");
187
+ }
188
+ try {
189
+ const durationMs = parseDurationInput(opts.duration);
190
+ const profilePath = resolve(opts.output);
191
+ const heapEnabled = Boolean(opts.heap);
192
+ const heapIntervalBytes = parseOptionalInt(opts.heapIntervalBytes);
193
+ const heapStackDepth = parseOptionalInt(opts.heapStackDepth);
194
+ console.log(`Profiling ${entryPath} for ${opts.duration}...`);
195
+ const { heapProfilePath } = await runCpuProfile({
196
+ entryPath,
197
+ entryArgs,
198
+ durationMs,
199
+ outPath: profilePath,
200
+ enableHeap: heapEnabled,
201
+ heapOutPath: heapEnabled ? resolve(opts.heapProfileOut) : undefined,
202
+ heapIntervalBytes,
203
+ heapStackDepth,
204
+ });
205
+ console.log(`Profile saved to ${profilePath}`);
206
+ if (heapEnabled && heapProfilePath) {
207
+ console.log(`Heap profile saved to ${heapProfilePath}`);
208
+ }
209
+ }
210
+ catch (error) {
211
+ console.error("Error:", error instanceof Error ? error.message : error);
212
+ process.exit(1);
213
+ }
214
+ });
215
+ // Diff command
216
+ program
217
+ .command("diff")
218
+ .description("Compare two pprof profiles")
219
+ .argument("<base>", "Path to base profile (.pb.gz)")
220
+ .argument("<current>", "Path to current profile (.pb.gz)")
221
+ .option("-f, --format <format>", "Output format: diff-summary, diff-detailed, diff-adaptive", "diff-adaptive")
222
+ .option("-o, --output <file>", "Output markdown file")
223
+ .option("-j, --json <file>", "Output JSON results file")
224
+ .option("-n, --normalize <mode>", "Normalize mode: none, scale-to-base-total, per-second", "scale-to-base-total")
225
+ .option("--max-regressions <n>", "Maximum regressions to show", "10")
226
+ .option("--max-improvements <n>", "Maximum improvements to show", "5")
227
+ .option("--max-decompressed-bytes <n>", "Maximum decompressed profile size in bytes")
228
+ .option("-m, --mode <mode>", "Mode: convert-only, analyze", "convert-only")
229
+ .option("--llm-provider <provider>", "LLM provider for analysis")
230
+ .option("--llm-model <model>", "LLM model name")
231
+ .option("--service <name>", "Service name for context")
232
+ .option("--changes <desc>", "Recent changes description")
233
+ .option("-v, --verbose", "Enable verbose logging")
234
+ .action(async (basePath, currentPath, opts) => {
235
+ if (opts.verbose) {
236
+ setLogLevel("debug");
237
+ }
238
+ try {
239
+ const resolvedBase = resolve(basePath);
240
+ const resolvedCurrent = resolve(currentPath);
241
+ validateProfileExtension(resolvedBase);
242
+ validateProfileExtension(resolvedCurrent);
243
+ const options = buildDiffOptions(opts);
244
+ console.log(`Comparing ${basePath} vs ${currentPath}...`);
245
+ const result = await diff(resolvedBase, resolvedCurrent, options);
246
+ // Output markdown
247
+ if (opts.output) {
248
+ await writeFile(opts.output, result.markdown, "utf-8");
249
+ console.log(`Markdown saved to ${opts.output}`);
250
+ }
251
+ else {
252
+ console.log("\n" + result.markdown);
253
+ }
254
+ // Output JSON
255
+ if (opts.json) {
256
+ const jsonResult = {
257
+ baseMeta: result.baseMeta,
258
+ currentMeta: result.currentMeta,
259
+ regressions: result.regressions,
260
+ improvements: result.improvements,
261
+ summary: result.summary,
262
+ recommendations: result.recommendations,
263
+ metrics: result.metrics,
264
+ };
265
+ await writeFile(opts.json, JSON.stringify(jsonResult, null, 2), "utf-8");
266
+ console.log(`JSON saved to ${opts.json}`);
267
+ }
268
+ // Print summary to stderr if outputting to file
269
+ if (opts.output) {
270
+ console.log(`\nFound ${result.regressions.length} regressions, ${result.improvements.length} improvements`);
271
+ }
272
+ }
273
+ catch (error) {
274
+ console.error("Error:", error instanceof Error ? error.message : error);
275
+ process.exit(1);
276
+ }
277
+ });
278
+ // Convert command (no LLM)
279
+ program
280
+ .command("convert")
281
+ .description("Convert pprof profile to markdown (no AI analysis)")
282
+ .argument("<profile>", "Path to pprof profile (.pb.gz)")
283
+ .option("-f, --format <format>", "Output format: summary, detailed, adaptive", "adaptive")
284
+ .option("-t, --type <type>", "Profile type: cpu, heap, auto", "auto")
285
+ .option("-o, --output <file>", "Output markdown file")
286
+ .option("-s, --source-dir <path>", "Source directory for code context")
287
+ .option("--no-source", "Disable source code inclusion")
288
+ .option("--max-hotspots <n>", "Maximum hotspots to show", "10")
289
+ .option("--no-redact", "Disable redaction of sensitive information")
290
+ .option("-v, --verbose", "Enable verbose logging")
291
+ .action(async (profilePath, opts) => {
292
+ if (opts.verbose) {
293
+ setLogLevel("debug");
294
+ }
295
+ try {
296
+ const resolvedPath = resolve(profilePath);
297
+ validateProfileExtension(resolvedPath);
298
+ const options = buildConvertOptions(opts);
299
+ console.log(`Converting ${profilePath}...`);
300
+ const result = await analyze(resolvedPath, options);
301
+ if (opts.output) {
302
+ await writeFile(opts.output, result.markdown, "utf-8");
303
+ console.log(`Markdown saved to ${opts.output}`);
304
+ }
305
+ else {
306
+ console.log("\n" + result.markdown);
307
+ }
308
+ }
309
+ catch (error) {
310
+ console.error("Error:", error instanceof Error ? error.message : error);
311
+ process.exit(1);
312
+ }
313
+ });
314
+ // Server command
315
+ program
316
+ .command("server")
317
+ .description("Start HTTP API server")
318
+ .option("-p, --port <port>", "Port to listen on", "3000")
319
+ .option("-h, --host <host>", "Host to bind to", "0.0.0.0")
320
+ .option("--cors", "Enable CORS")
321
+ .option("--no-cors", "Disable CORS")
322
+ .option("--cors-origin <origin>", "CORS origin(s), comma-separated or '*'")
323
+ .option("--helmet", "Enable helmet security headers")
324
+ .option("--no-helmet", "Disable helmet security headers")
325
+ .option("--rate-limit", "Enable rate limiting")
326
+ .option("--no-rate-limit", "Disable rate limiting")
327
+ .option("--rate-limit-max <n>", "Rate limit max requests per window")
328
+ .option("--rate-limit-window-ms <ms>", "Rate limit window in ms")
329
+ .option("-v, --verbose", "Enable verbose logging")
330
+ .action(async (opts) => {
331
+ if (opts.verbose) {
332
+ setLogLevel("debug");
333
+ }
334
+ try {
335
+ const { startServer } = await import("../server/http.js");
336
+ await startServer({
337
+ port: parseInt(opts.port, 10),
338
+ host: opts.host,
339
+ enableCors: opts.cors,
340
+ corsOrigin: opts.corsOrigin,
341
+ enableHelmet: opts.helmet,
342
+ enableRateLimit: opts.rateLimit,
343
+ rateLimitMax: opts.rateLimitMax ? parseInt(opts.rateLimitMax, 10) : undefined,
344
+ rateLimitWindowMs: opts.rateLimitWindowMs ? parseInt(opts.rateLimitWindowMs, 10) : undefined,
345
+ });
346
+ }
347
+ catch (error) {
348
+ console.error("Error:", error instanceof Error ? error.message : error);
349
+ process.exit(1);
350
+ }
351
+ });
352
+ program.parse();
353
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * CLI option builders (pure helpers for testing)
3
+ */
4
+ import type { AnalyzeOptions, DiffOptions, LLMConfig } from "../types.js";
5
+ export interface AnalyzeCommandOptions {
6
+ format: AnalyzeOptions["format"];
7
+ type: AnalyzeOptions["profileType"];
8
+ maxHotspots: string;
9
+ sourceDir?: string;
10
+ source?: boolean;
11
+ mode: AnalyzeOptions["mode"];
12
+ redact: boolean;
13
+ service?: string;
14
+ scenario?: string;
15
+ slo?: string;
16
+ llmProvider?: LLMConfig["provider"];
17
+ llmModel?: string;
18
+ }
19
+ export interface ConvertCommandOptions {
20
+ format: AnalyzeOptions["format"];
21
+ type: AnalyzeOptions["profileType"];
22
+ maxHotspots: string;
23
+ sourceDir?: string;
24
+ source?: boolean;
25
+ redact: boolean;
26
+ }
27
+ export interface DiffCommandOptions {
28
+ format: DiffOptions["format"];
29
+ normalize: DiffOptions["normalize"];
30
+ maxRegressions: string;
31
+ maxImprovements: string;
32
+ maxDecompressedBytes?: string;
33
+ }
34
+ export declare function buildAnalyzeOptions(opts: AnalyzeCommandOptions): AnalyzeOptions;
35
+ export declare function buildConvertOptions(opts: ConvertCommandOptions): AnalyzeOptions;
36
+ export declare function buildDiffOptions(opts: DiffCommandOptions): DiffOptions;
37
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/cli/options.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAkB,MAAM,aAAa,CAAC;AAE1F,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACjC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACjC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAgBD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,qBAAqB,GAAG,cAAc,CAe/E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,qBAAqB,GAAG,cAAc,CAU/E;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,GAAG,WAAW,CAStE"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * CLI option builders (pure helpers for testing)
3
+ */
4
+ function parseOptionalInt(value) {
5
+ if (value === undefined)
6
+ return undefined;
7
+ const parsed = parseInt(value, 10);
8
+ return Number.isFinite(parsed) ? parsed : undefined;
9
+ }
10
+ function buildLimits(opts) {
11
+ const maxDecompressedBytes = parseOptionalInt(opts.maxDecompressedBytes);
12
+ if (maxDecompressedBytes === undefined) {
13
+ return undefined;
14
+ }
15
+ return { maxDecompressedBytes };
16
+ }
17
+ export function buildAnalyzeOptions(opts) {
18
+ return {
19
+ format: opts.format,
20
+ profileType: opts.type,
21
+ maxHotspots: parseInt(opts.maxHotspots, 10),
22
+ sourceDir: opts.sourceDir,
23
+ includeSource: opts.source,
24
+ mode: opts.mode,
25
+ redact: opts.redact,
26
+ context: {
27
+ serviceName: opts.service,
28
+ scenario: opts.scenario,
29
+ targetSLO: opts.slo,
30
+ },
31
+ };
32
+ }
33
+ export function buildConvertOptions(opts) {
34
+ return {
35
+ format: opts.format,
36
+ profileType: opts.type,
37
+ maxHotspots: parseInt(opts.maxHotspots, 10),
38
+ sourceDir: opts.sourceDir,
39
+ includeSource: opts.source,
40
+ mode: "convert-only",
41
+ redact: opts.redact,
42
+ };
43
+ }
44
+ export function buildDiffOptions(opts) {
45
+ const limits = buildLimits(opts);
46
+ return {
47
+ format: opts.format,
48
+ normalize: opts.normalize,
49
+ maxRegressions: parseInt(opts.maxRegressions, 10),
50
+ maxImprovements: parseInt(opts.maxImprovements, 10),
51
+ limits,
52
+ };
53
+ }
54
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/cli/options.ts"],"names":[],"mappings":"AAAA;;GAEG;AAoCH,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACtD,CAAC;AAED,SAAS,WAAW,CAAC,IAAuC;IAC1D,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACzE,IAAI,oBAAoB,KAAK,SAAS,EAAE,CAAC;QACvC,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAA2B;IAC7D,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,WAAW,EAAE,IAAI,CAAC,IAAI;QACtB,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QAC3C,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,aAAa,EAAE,IAAI,CAAC,MAAM;QAC1B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE;YACP,WAAW,EAAE,IAAI,CAAC,OAAO;YACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,IAAI,CAAC,GAAG;SACpB;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAA2B;IAC7D,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,WAAW,EAAE,IAAI,CAAC,IAAI;QACtB,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QAC3C,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,aAAa,EAAE,IAAI,CAAC,MAAM;QAC1B,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAwB;IACvD,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QACjD,eAAe,EAAE,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACnD,MAAM;KACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Core converter module - wraps pprof-to-md library
3
+ */
4
+ import type { ConvertOptions, ProfileMeta } from "../types.js";
5
+ import { type SanitizeOptions } from "./sanitize.js";
6
+ import type { Hotspot } from "../types.js";
7
+ export interface ConvertResult {
8
+ /** Generated markdown */
9
+ markdown: string;
10
+ /** Original markdown before sanitization */
11
+ rawMarkdown: string;
12
+ /** Extracted hotspots */
13
+ hotspots: Hotspot[];
14
+ /** Profile metadata */
15
+ meta?: ProfileMeta;
16
+ /** Processing time in ms */
17
+ durationMs: number;
18
+ }
19
+ export interface FullConvertOptions extends ConvertOptions {
20
+ /** Maximum profile size in bytes */
21
+ maxProfileBytes?: number;
22
+ /** Maximum markdown output characters */
23
+ maxMarkdownChars?: number;
24
+ /** Sanitization options */
25
+ sanitize?: SanitizeOptions;
26
+ }
27
+ /**
28
+ * Convert a pprof profile buffer to markdown
29
+ */
30
+ export declare function convertProfileToMarkdown(profileBytes: Uint8Array | Buffer, options?: FullConvertOptions): Promise<ConvertResult>;
31
+ /**
32
+ * Convert profile from file path
33
+ */
34
+ export declare function convertProfileFromPath(profilePath: string, options?: FullConvertOptions): Promise<ConvertResult>;
35
+ /**
36
+ * Convert profile from base64 string
37
+ */
38
+ export declare function convertProfileFromBase64(base64: string, options?: FullConvertOptions): Promise<ConvertResult>;
39
+ //# sourceMappingURL=converter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../../src/convert/converter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/D,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAEvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,uBAAuB;IACvB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD,oCAAoC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,YAAY,EAAE,UAAU,GAAG,MAAM,EACjC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,aAAa,CAAC,CAwFxB;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,aAAa,CAAC,CAIxB;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,aAAa,CAAC,CAGxB"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Core converter module - wraps pprof-to-md library
3
+ */
4
+ import { convert as pprofToMd } from "pprof-to-md";
5
+ import { getProfileExtension, withTempFile } from "../utils/fs.js";
6
+ import { logger } from "../utils/logger.js";
7
+ import { checkSizeLimit, resolveLimits } from "../utils/limits.js";
8
+ import { sanitizeMarkdown } from "./sanitize.js";
9
+ import { extractHotspots, extractProfileMeta } from "./extract.js";
10
+ /**
11
+ * Convert a pprof profile buffer to markdown
12
+ */
13
+ export async function convertProfileToMarkdown(profileBytes, options = {}) {
14
+ const startTime = performance.now();
15
+ const limits = resolveLimits(options);
16
+ // Check input size
17
+ checkSizeLimit(profileBytes, limits.maxProfileBytes, "Profile");
18
+ logger.debug("Converting profile to markdown", {
19
+ profileBytes: profileBytes.length,
20
+ format: options.format ?? "adaptive",
21
+ profileType: options.profileType ?? "auto",
22
+ });
23
+ const pprofProfileType = options.profileType === "auto" ? undefined : options.profileType;
24
+ const tempExt = getProfileExtension(profileBytes);
25
+ // Convert using pprof-to-md (requires file path)
26
+ const rawMarkdown = await withTempFile(profileBytes, async (tempPath) => {
27
+ // pprof-to-md convert function
28
+ const md = await Promise.resolve(pprofToMd(tempPath, {
29
+ format: options.format ?? "adaptive",
30
+ profileType: pprofProfileType,
31
+ maxHotspots: options.maxHotspots ?? 10,
32
+ sourceDir: options.sourceDir,
33
+ includeSource: options.includeSource !== false,
34
+ }));
35
+ return md;
36
+ }, "pprof", tempExt);
37
+ logger.debug("Raw markdown generated", { chars: rawMarkdown.length });
38
+ // Check if markdown exceeds limit and needs format downgrade
39
+ let markdown = rawMarkdown;
40
+ let usedFormat = options.format ?? "adaptive";
41
+ if (rawMarkdown.length > limits.maxMarkdownChars) {
42
+ logger.info("Markdown exceeds limit, downgrading to summary format", {
43
+ chars: rawMarkdown.length,
44
+ limit: limits.maxMarkdownChars,
45
+ });
46
+ // Retry with summary format and fewer hotspots
47
+ markdown = await withTempFile(profileBytes, async (tempPath) => {
48
+ const md = await Promise.resolve(pprofToMd(tempPath, {
49
+ format: "summary",
50
+ profileType: pprofProfileType,
51
+ maxHotspots: Math.min(options.maxHotspots ?? 10, 10),
52
+ sourceDir: options.sourceDir,
53
+ includeSource: false, // Disable source for smaller output
54
+ }));
55
+ return md;
56
+ }, "pprof", tempExt);
57
+ usedFormat = "summary";
58
+ }
59
+ // Extract metadata and hotspots from markdown
60
+ const meta = extractProfileMeta(markdown);
61
+ const hotspots = extractHotspots(markdown);
62
+ // Sanitize markdown
63
+ const sanitizedMarkdown = sanitizeMarkdown(markdown, {
64
+ ...options.sanitize,
65
+ maxChars: limits.maxMarkdownChars,
66
+ maxSourceLines: limits.maxSourceLinesPerFile,
67
+ baseDir: options.sourceDir,
68
+ });
69
+ const durationMs = performance.now() - startTime;
70
+ logger.info("Profile conversion complete", {
71
+ durationMs: Math.round(durationMs),
72
+ format: usedFormat,
73
+ hotspotsFound: hotspots.length,
74
+ outputChars: sanitizedMarkdown.length,
75
+ });
76
+ return {
77
+ markdown: sanitizedMarkdown,
78
+ rawMarkdown,
79
+ hotspots,
80
+ meta,
81
+ durationMs,
82
+ };
83
+ }
84
+ /**
85
+ * Convert profile from file path
86
+ */
87
+ export async function convertProfileFromPath(profilePath, options = {}) {
88
+ const { readFile } = await import("node:fs/promises");
89
+ const profileBytes = await readFile(profilePath);
90
+ return convertProfileToMarkdown(profileBytes, options);
91
+ }
92
+ /**
93
+ * Convert profile from base64 string
94
+ */
95
+ export async function convertProfileFromBase64(base64, options = {}) {
96
+ const buffer = Buffer.from(base64, "base64");
97
+ return convertProfileToMarkdown(buffer, options);
98
+ }
99
+ //# sourceMappingURL=converter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.js","sourceRoot":"","sources":["../../src/convert/converter.ts"],"names":[],"mappings":"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"}