@usepipr/runtime 0.3.2 → 0.3.3
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.
|
@@ -2398,6 +2398,14 @@ type CategorizedFinding = {
|
|
|
2398
2398
|
suggestedFix?: string;
|
|
2399
2399
|
};
|
|
2400
2400
|
|
|
2401
|
+
type ReviewSummary = {
|
|
2402
|
+
headline: string;
|
|
2403
|
+
changeSummary: string[];
|
|
2404
|
+
riskLevel: "low" | "medium" | "high";
|
|
2405
|
+
riskSummary: string;
|
|
2406
|
+
reviewerFocus: string[];
|
|
2407
|
+
};
|
|
2408
|
+
|
|
2401
2409
|
const categorizedFindingSchema = z.strictObject({
|
|
2402
2410
|
title: z.string(),
|
|
2403
2411
|
severity: z.enum(["critical", "high", "medium", "low", "nit"]),
|
|
@@ -2420,6 +2428,14 @@ const categorizedFindingSchema = z.strictObject({
|
|
|
2420
2428
|
suggestedFix: z.string().optional(),
|
|
2421
2429
|
});
|
|
2422
2430
|
|
|
2431
|
+
const reviewSummarySchema = z.strictObject({
|
|
2432
|
+
headline: z.string(),
|
|
2433
|
+
changeSummary: z.array(z.string()).min(1).max(4),
|
|
2434
|
+
riskLevel: z.enum(["low", "medium", "high"]),
|
|
2435
|
+
riskSummary: z.string(),
|
|
2436
|
+
reviewerFocus: z.array(z.string()).max(4),
|
|
2437
|
+
});
|
|
2438
|
+
|
|
2423
2439
|
export default definePipr((pipr) => {
|
|
2424
2440
|
const model = pipr.model({
|
|
2425
2441
|
provider: "deepseek",
|
|
@@ -2433,7 +2449,7 @@ export default definePipr((pipr) => {
|
|
|
2433
2449
|
const reviewOutput = pipr.schema({
|
|
2434
2450
|
id: "review/categorized-findings",
|
|
2435
2451
|
schema: z.strictObject({
|
|
2436
|
-
summary:
|
|
2452
|
+
summary: reviewSummarySchema,
|
|
2437
2453
|
findings: z.array(categorizedFindingSchema),
|
|
2438
2454
|
}),
|
|
2439
2455
|
});
|
|
@@ -2449,6 +2465,11 @@ export default definePipr((pipr) => {
|
|
|
2449
2465
|
medium for important follow-up, low for minor actionable improvements,
|
|
2450
2466
|
and nit only for tiny but concrete issues. Include suggestedFix only when
|
|
2451
2467
|
there is an exact replacement for the selected range.
|
|
2468
|
+
|
|
2469
|
+
Make summary maintainer-facing and scannable: one concrete headline, one
|
|
2470
|
+
to four behavior-focused change bullets, a risk level with rationale, and
|
|
2471
|
+
reviewer focus only for useful human follow-up. Put actionable defects in
|
|
2472
|
+
findings, not only in summary.
|
|
2452
2473
|
\`,
|
|
2453
2474
|
output: reviewOutput,
|
|
2454
2475
|
tools: pipr.tools.readOnly,
|
|
@@ -2477,18 +2498,24 @@ export default definePipr((pipr) => {
|
|
|
2477
2498
|
});
|
|
2478
2499
|
await ctx.comment({
|
|
2479
2500
|
main: [
|
|
2480
|
-
|
|
2501
|
+
"## Summary",
|
|
2481
2502
|
"",
|
|
2482
|
-
|
|
2503
|
+
\`**\${result.summary.headline}**\`,
|
|
2483
2504
|
"",
|
|
2484
|
-
|
|
2505
|
+
summaryTable(result.summary, result.findings.length),
|
|
2506
|
+
"",
|
|
2507
|
+
"## What Changed",
|
|
2508
|
+
"",
|
|
2509
|
+
bulletList(result.summary.changeSummary, "No changed behavior summarized."),
|
|
2510
|
+
"",
|
|
2511
|
+
"## Reviewer Focus",
|
|
2485
2512
|
"",
|
|
2486
|
-
"
|
|
2487
|
-
"<summary>Finding rationales</summary>",
|
|
2513
|
+
bulletList(result.summary.reviewerFocus, "No special reviewer focus."),
|
|
2488
2514
|
"",
|
|
2489
|
-
|
|
2515
|
+
"## Findings",
|
|
2490
2516
|
"",
|
|
2491
|
-
|
|
2517
|
+
findingsTable(result.findings),
|
|
2518
|
+
...(result.findings.length > 0 ? ["", findingRationalesBlock(result.findings)] : []),
|
|
2492
2519
|
].join("\\n"),
|
|
2493
2520
|
inlineFindings,
|
|
2494
2521
|
});
|
|
@@ -2499,6 +2526,23 @@ export default definePipr((pipr) => {
|
|
|
2499
2526
|
pipr.command({ pattern: "@pipr review", permission: "write", task });
|
|
2500
2527
|
});
|
|
2501
2528
|
|
|
2529
|
+
function summaryTable(summary: ReviewSummary, findingCount: number): string {
|
|
2530
|
+
return [
|
|
2531
|
+
"| Outcome | Risk | Risk summary |",
|
|
2532
|
+
"| --- | --- | --- |",
|
|
2533
|
+
\`| \${findingOutcome(findingCount)} | \${labelValue(summary.riskLevel)} | \${tableCell(
|
|
2534
|
+
summary.riskSummary,
|
|
2535
|
+
)} |\`,
|
|
2536
|
+
].join("\\n");
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2539
|
+
function findingOutcome(findingCount: number): string {
|
|
2540
|
+
if (findingCount === 0) {
|
|
2541
|
+
return "No findings";
|
|
2542
|
+
}
|
|
2543
|
+
return findingCount === 1 ? "1 finding" : \`\${findingCount} findings\`;
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2502
2546
|
function findingsTable(findings: CategorizedFinding[]): string {
|
|
2503
2547
|
if (findings.length === 0) {
|
|
2504
2548
|
return [
|
|
@@ -2519,22 +2563,48 @@ function findingsTable(findings: CategorizedFinding[]): string {
|
|
|
2519
2563
|
].join("\\n");
|
|
2520
2564
|
}
|
|
2521
2565
|
|
|
2522
|
-
function
|
|
2566
|
+
function findingRationalesBlock(findings: CategorizedFinding[]): string {
|
|
2523
2567
|
if (findings.length === 0) {
|
|
2524
|
-
return "
|
|
2568
|
+
return "";
|
|
2525
2569
|
}
|
|
2526
|
-
return
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2570
|
+
return [
|
|
2571
|
+
"<details>",
|
|
2572
|
+
"<summary>Finding rationales</summary>",
|
|
2573
|
+
"",
|
|
2574
|
+
findings
|
|
2575
|
+
.map((finding, index) =>
|
|
2576
|
+
[
|
|
2577
|
+
\`### \${index + 1}. \${finding.title}\`,
|
|
2578
|
+
"",
|
|
2579
|
+
\`**Severity:** \${labelValue(finding.severity)}\`,
|
|
2580
|
+
\`**Category:** \${labelValue(finding.category)}\`,
|
|
2581
|
+
"",
|
|
2582
|
+
finding.rationale,
|
|
2583
|
+
].join("\\n"),
|
|
2584
|
+
)
|
|
2585
|
+
.join("\\n\\n"),
|
|
2586
|
+
"",
|
|
2587
|
+
"</details>",
|
|
2588
|
+
].join("\\n");
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
function bulletList(items: string[], emptyText: string): string {
|
|
2592
|
+
if (items.length === 0) {
|
|
2593
|
+
return emptyText;
|
|
2594
|
+
}
|
|
2595
|
+
return items.map((item) => \`- \${lineText(item)}\`).join("\\n");
|
|
2596
|
+
}
|
|
2597
|
+
|
|
2598
|
+
function labelValue(value: string): string {
|
|
2599
|
+
return value.replaceAll("-", " ").replace(/^./, (char) => char.toUpperCase());
|
|
2600
|
+
}
|
|
2601
|
+
|
|
2602
|
+
function lineText(value: string): string {
|
|
2603
|
+
return value.replaceAll("\\n", " ").trim();
|
|
2604
|
+
}
|
|
2605
|
+
|
|
2606
|
+
function tableCell(value: string): string {
|
|
2607
|
+
return lineText(value).replaceAll("|", "\\\\|");
|
|
2538
2608
|
}
|
|
2539
2609
|
`
|
|
2540
2610
|
};
|
|
@@ -2552,15 +2622,25 @@ const securitySastRecipe = {
|
|
|
2552
2622
|
configTs: `import { definePipr } from "@usepipr/sdk";
|
|
2553
2623
|
import type { ReviewFinding } from "@usepipr/sdk";
|
|
2554
2624
|
|
|
2625
|
+
type SecuritySummary = {
|
|
2626
|
+
headline: string;
|
|
2627
|
+
riskLevel: "low" | "medium" | "high";
|
|
2628
|
+
riskSummary: string;
|
|
2629
|
+
reviewerFocus: string[];
|
|
2630
|
+
};
|
|
2631
|
+
|
|
2632
|
+
type SecurityRisk = {
|
|
2633
|
+
title: string;
|
|
2634
|
+
category: "auth" | "injection" | "secret" | "crypto" | "data-exposure" | "other";
|
|
2635
|
+
severity: "low" | "medium" | "high" | "critical";
|
|
2636
|
+
rationale: string;
|
|
2637
|
+
finding?: ReviewFinding;
|
|
2638
|
+
};
|
|
2639
|
+
|
|
2555
2640
|
type SecurityReview = {
|
|
2556
|
-
summary:
|
|
2557
|
-
risks:
|
|
2558
|
-
|
|
2559
|
-
category: "auth" | "injection" | "secret" | "crypto" | "data-exposure" | "other";
|
|
2560
|
-
severity: "low" | "medium" | "high" | "critical";
|
|
2561
|
-
rationale: string;
|
|
2562
|
-
finding?: ReviewFinding;
|
|
2563
|
-
}>;
|
|
2641
|
+
summary: SecuritySummary;
|
|
2642
|
+
risks: SecurityRisk[];
|
|
2643
|
+
diagramMermaid?: string;
|
|
2564
2644
|
};
|
|
2565
2645
|
|
|
2566
2646
|
export default definePipr((pipr) => {
|
|
@@ -2578,7 +2658,20 @@ export default definePipr((pipr) => {
|
|
|
2578
2658
|
additionalProperties: false,
|
|
2579
2659
|
required: ["summary", "risks"],
|
|
2580
2660
|
properties: {
|
|
2581
|
-
summary: {
|
|
2661
|
+
summary: {
|
|
2662
|
+
type: "object",
|
|
2663
|
+
additionalProperties: false,
|
|
2664
|
+
required: ["headline", "riskLevel", "riskSummary", "reviewerFocus"],
|
|
2665
|
+
properties: {
|
|
2666
|
+
headline: { type: "string" },
|
|
2667
|
+
riskLevel: { type: "string", enum: ["low", "medium", "high"] },
|
|
2668
|
+
riskSummary: { type: "string" },
|
|
2669
|
+
reviewerFocus: {
|
|
2670
|
+
type: "array",
|
|
2671
|
+
items: { type: "string" },
|
|
2672
|
+
},
|
|
2673
|
+
},
|
|
2674
|
+
},
|
|
2582
2675
|
risks: {
|
|
2583
2676
|
type: "array",
|
|
2584
2677
|
items: {
|
|
@@ -2610,6 +2703,7 @@ export default definePipr((pipr) => {
|
|
|
2610
2703
|
},
|
|
2611
2704
|
},
|
|
2612
2705
|
},
|
|
2706
|
+
diagramMermaid: { type: "string" },
|
|
2613
2707
|
},
|
|
2614
2708
|
},
|
|
2615
2709
|
});
|
|
@@ -2621,6 +2715,11 @@ export default definePipr((pipr) => {
|
|
|
2621
2715
|
Review for exploitable security issues only. Focus on auth bypasses,
|
|
2622
2716
|
injection, unsafe deserialization, secret exposure, cryptography misuse,
|
|
2623
2717
|
authorization gaps, and data exposure. Do not report hypothetical style issues.
|
|
2718
|
+
Make summary maintainer-facing and scannable with a concrete headline,
|
|
2719
|
+
risk level, risk rationale, and only useful security follow-up. Set
|
|
2720
|
+
diagramMermaid only when a high or critical risk has a concrete source-to-sink
|
|
2721
|
+
path and a small Mermaid flowchart clarifies it. Do not include Markdown
|
|
2722
|
+
fences in diagramMermaid.
|
|
2624
2723
|
\`,
|
|
2625
2724
|
output: securityOutput,
|
|
2626
2725
|
tools: pipr.tools.readOnly,
|
|
@@ -2636,14 +2735,40 @@ export default definePipr((pipr) => {
|
|
|
2636
2735
|
async run(ctx) {
|
|
2637
2736
|
const manifest = await ctx.change.diffManifest({ compressed: true });
|
|
2638
2737
|
const result = await ctx.pi.run(security, { manifest });
|
|
2639
|
-
const inlineFindings = result.risks.flatMap((risk) =>
|
|
2640
|
-
|
|
2738
|
+
const inlineFindings: ReviewFinding[] = result.risks.flatMap((risk) =>
|
|
2739
|
+
risk.finding ? [risk.finding] : [],
|
|
2740
|
+
);
|
|
2741
|
+
const hasHighOrCriticalRisk = result.risks.some(isHighOrCriticalRisk);
|
|
2742
|
+
const hasConcreteHighOrCriticalRisk = result.risks.some(
|
|
2743
|
+
(risk) => isHighOrCriticalRisk(risk) && risk.finding,
|
|
2744
|
+
);
|
|
2745
|
+
if (hasHighOrCriticalRisk) {
|
|
2641
2746
|
ctx.check.fail("High or critical security risk found.");
|
|
2642
2747
|
} else {
|
|
2643
2748
|
ctx.check.pass("No high or critical security risks found.");
|
|
2644
2749
|
}
|
|
2645
2750
|
await ctx.comment({
|
|
2646
|
-
main:
|
|
2751
|
+
main: [
|
|
2752
|
+
"## Summary",
|
|
2753
|
+
"",
|
|
2754
|
+
\`**\${result.summary.headline}**\`,
|
|
2755
|
+
"",
|
|
2756
|
+
securityStatusTable(result.summary, result.risks),
|
|
2757
|
+
"",
|
|
2758
|
+
result.summary.riskSummary,
|
|
2759
|
+
"",
|
|
2760
|
+
"## Reviewer Focus",
|
|
2761
|
+
"",
|
|
2762
|
+
bulletList(result.summary.reviewerFocus, "No special security follow-up."),
|
|
2763
|
+
"",
|
|
2764
|
+
"## Security Risks",
|
|
2765
|
+
"",
|
|
2766
|
+
securityRisksTable(result.risks),
|
|
2767
|
+
...(result.risks.length > 0 ? ["", riskRationalesBlock(result.risks)] : []),
|
|
2768
|
+
...(hasConcreteHighOrCriticalRisk && result.diagramMermaid?.trim()
|
|
2769
|
+
? ["", attackPathDiagramBlock(result.diagramMermaid, hasConcreteHighOrCriticalRisk)]
|
|
2770
|
+
: []),
|
|
2771
|
+
].join("\\n"),
|
|
2647
2772
|
inlineFindings,
|
|
2648
2773
|
});
|
|
2649
2774
|
},
|
|
@@ -2652,6 +2777,122 @@ export default definePipr((pipr) => {
|
|
|
2652
2777
|
pipr.on.changeRequest({ actions: ["opened", "updated", "reopened", "ready"], task });
|
|
2653
2778
|
pipr.command({ pattern: "@pipr security", permission: "write", task });
|
|
2654
2779
|
});
|
|
2780
|
+
|
|
2781
|
+
function securityStatusTable(summary: SecuritySummary, risks: SecurityRisk[]): string {
|
|
2782
|
+
return [
|
|
2783
|
+
"| Status | Summary risk | Max severity | Risks |",
|
|
2784
|
+
"| --- | --- | --- | ---: |",
|
|
2785
|
+
\`| \${risks.some(isHighOrCriticalRisk) ? "Fail" : "Pass"} | \${labelValue(
|
|
2786
|
+
summary.riskLevel,
|
|
2787
|
+
)} | \${maxSeverity(risks)} | \${risks.length} |\`,
|
|
2788
|
+
].join("\\n");
|
|
2789
|
+
}
|
|
2790
|
+
|
|
2791
|
+
function securityRisksTable(risks: SecurityRisk[]): string {
|
|
2792
|
+
if (risks.length === 0) {
|
|
2793
|
+
return [
|
|
2794
|
+
"| Severity | Category | Title |",
|
|
2795
|
+
"| --- | --- | --- |",
|
|
2796
|
+
"| - | - | No security risks found. |",
|
|
2797
|
+
].join("\\n");
|
|
2798
|
+
}
|
|
2799
|
+
return [
|
|
2800
|
+
"| Severity | Category | Title |",
|
|
2801
|
+
"| --- | --- | --- |",
|
|
2802
|
+
...risks.map(
|
|
2803
|
+
(risk) =>
|
|
2804
|
+
\`| \${labelValue(risk.severity)} | \${tableCell(risk.category)} | \${tableCell(risk.title)} |\`,
|
|
2805
|
+
),
|
|
2806
|
+
].join("\\n");
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
function riskRationalesBlock(risks: SecurityRisk[]): string {
|
|
2810
|
+
if (risks.length === 0) {
|
|
2811
|
+
return "";
|
|
2812
|
+
}
|
|
2813
|
+
return [
|
|
2814
|
+
"<details>",
|
|
2815
|
+
"<summary>Risk rationales</summary>",
|
|
2816
|
+
"",
|
|
2817
|
+
risks
|
|
2818
|
+
.map((risk, index) =>
|
|
2819
|
+
[
|
|
2820
|
+
\`### \${index + 1}. \${risk.title}\`,
|
|
2821
|
+
"",
|
|
2822
|
+
\`**Severity:** \${labelValue(risk.severity)}\`,
|
|
2823
|
+
\`**Category:** \${labelValue(risk.category)}\`,
|
|
2824
|
+
"",
|
|
2825
|
+
risk.rationale,
|
|
2826
|
+
].join("\\n"),
|
|
2827
|
+
)
|
|
2828
|
+
.join("\\n\\n"),
|
|
2829
|
+
"",
|
|
2830
|
+
"</details>",
|
|
2831
|
+
].join("\\n");
|
|
2832
|
+
}
|
|
2833
|
+
|
|
2834
|
+
function attackPathDiagramBlock(
|
|
2835
|
+
diagramMermaid: string | undefined,
|
|
2836
|
+
hasConcreteHighOrCriticalRisk: boolean,
|
|
2837
|
+
): string {
|
|
2838
|
+
const diagram = diagramMermaid?.trim();
|
|
2839
|
+
if (!diagram || !hasConcreteHighOrCriticalRisk) {
|
|
2840
|
+
return "";
|
|
2841
|
+
}
|
|
2842
|
+
const fence = markdownFenceFor(diagram);
|
|
2843
|
+
return [
|
|
2844
|
+
"<details>",
|
|
2845
|
+
"<summary>Attack path diagram</summary>",
|
|
2846
|
+
"",
|
|
2847
|
+
\`\${fence}mermaid\`,
|
|
2848
|
+
diagram,
|
|
2849
|
+
fence,
|
|
2850
|
+
"",
|
|
2851
|
+
"</details>",
|
|
2852
|
+
].join("\\n");
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
function maxSeverity(risks: SecurityRisk[]): string {
|
|
2856
|
+
const order: SecurityRisk["severity"][] = ["low", "medium", "high", "critical"];
|
|
2857
|
+
const severity = risks.reduce<SecurityRisk["severity"] | undefined>((current, risk) => {
|
|
2858
|
+
if (!current || order.indexOf(risk.severity) > order.indexOf(current)) {
|
|
2859
|
+
return risk.severity;
|
|
2860
|
+
}
|
|
2861
|
+
return current;
|
|
2862
|
+
}, undefined);
|
|
2863
|
+
return severity ? labelValue(severity) : "None";
|
|
2864
|
+
}
|
|
2865
|
+
|
|
2866
|
+
function isHighOrCriticalRisk(risk: SecurityRisk): boolean {
|
|
2867
|
+
return risk.severity === "high" || risk.severity === "critical";
|
|
2868
|
+
}
|
|
2869
|
+
|
|
2870
|
+
function bulletList(items: string[], emptyText: string): string {
|
|
2871
|
+
if (items.length === 0) {
|
|
2872
|
+
return emptyText;
|
|
2873
|
+
}
|
|
2874
|
+
return items.map((item) => \`- \${lineText(item)}\`).join("\\n");
|
|
2875
|
+
}
|
|
2876
|
+
|
|
2877
|
+
function labelValue(value: string): string {
|
|
2878
|
+
return value.replaceAll("-", " ").replace(/^./, (char) => char.toUpperCase());
|
|
2879
|
+
}
|
|
2880
|
+
|
|
2881
|
+
function lineText(value: string): string {
|
|
2882
|
+
return value.replaceAll("\\n", " ").trim();
|
|
2883
|
+
}
|
|
2884
|
+
|
|
2885
|
+
function tableCell(value: string): string {
|
|
2886
|
+
return lineText(value).replaceAll("|", "\\\\|");
|
|
2887
|
+
}
|
|
2888
|
+
|
|
2889
|
+
function markdownFenceFor(value: string): string {
|
|
2890
|
+
const longestBacktickRun = Math.max(
|
|
2891
|
+
0,
|
|
2892
|
+
...[...value.matchAll(/\`+/g)].map((match) => match[0].length),
|
|
2893
|
+
);
|
|
2894
|
+
return "\`".repeat(Math.max(3, longestBacktickRun + 1));
|
|
2895
|
+
}
|
|
2655
2896
|
`
|
|
2656
2897
|
};
|
|
2657
2898
|
//#endregion
|
|
@@ -2713,8 +2954,8 @@ function isOfficialInitRecipeId(recipe) {
|
|
|
2713
2954
|
//#endregion
|
|
2714
2955
|
//#region src/config/init.ts
|
|
2715
2956
|
const supportedOfficialInitAdapters = ["github"];
|
|
2716
|
-
const defaultWorkflowActionRef = "somus/pipr@v0.3.
|
|
2717
|
-
const defaultSdkVersion = "0.3.
|
|
2957
|
+
const defaultWorkflowActionRef = "somus/pipr@v0.3.3";
|
|
2958
|
+
const defaultSdkVersion = "0.3.3";
|
|
2718
2959
|
const defaultTypesBunVersion = "1.3.14";
|
|
2719
2960
|
function resolveOfficialInitAdapters(adapters) {
|
|
2720
2961
|
if (adapters === void 0) return [...supportedOfficialInitAdapters];
|
|
@@ -4799,10 +5040,10 @@ function buildRepairPrompt(options) {
|
|
|
4799
5040
|
}
|
|
4800
5041
|
//#endregion
|
|
4801
5042
|
//#region package.json
|
|
4802
|
-
var version = "0.3.
|
|
5043
|
+
var version = "0.3.3";
|
|
4803
5044
|
//#endregion
|
|
4804
5045
|
//#region src/review/comment-branding.ts
|
|
4805
|
-
const piprLogoUrl = "https://pipr.run/
|
|
5046
|
+
const piprLogoUrl = "https://pipr.run/images/pipr/pipr-mark.svg";
|
|
4806
5047
|
const piprRepositoryUrl = "https://github.com/somus/pipr";
|
|
4807
5048
|
const mainCommentTitle = `# <img src="${piprLogoUrl}" width="22" height="22" alt=""> Pipr Review`;
|
|
4808
5049
|
const mainCommentTitles = new Set([
|
|
@@ -8311,4 +8552,4 @@ async function runActionCommandWithDependencies(options) {
|
|
|
8311
8552
|
//#endregion
|
|
8312
8553
|
export { runInspectCommand as a, PublicationError as c, listOfficialInitRecipes as d, supportedOfficialInitRecipes as f, piThinkingLevels as g, piRequiredCliFlags as h, runInitCommand as i, isPublishableSuggestedFixSelection as l, piReadOnlyToolNames as m, runActionCommandWithDependencies as n, runLocalReviewCommand as o, piBuiltinToolNames as p, runDryRunCommand as r, runValidateCommand as s, runActionCommand as t, supportedOfficialInitAdapters as u };
|
|
8313
8554
|
|
|
8314
|
-
//# sourceMappingURL=commands-
|
|
8555
|
+
//# sourceMappingURL=commands-C1sVsbEj.mjs.map
|