bugzero 0.0.33 → 0.0.35

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > bugzero@0.0.33 build /home/runner/work/Bugzero/Bugzero/apps/bugzero
2
+ > bugzero@0.0.35 build /home/runner/work/Bugzero/Bugzero/apps/bugzero
3
3
  > tsup src/index.ts --format cjs --dts
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -7,8 +7,8 @@
7
7
  CLI tsup v8.5.1
8
8
  CLI Target: es2022
9
9
  CJS Build start
10
- CJS dist/index.js 77.80 KB
11
- CJS ⚡️ Build success in 33ms
10
+ CJS dist/index.js 79.68 KB
11
+ CJS ⚡️ Build success in 54ms
12
12
  DTS Build start
13
- DTS ⚡️ Build success in 784ms
13
+ DTS ⚡️ Build success in 1265ms
14
14
  DTS dist/index.d.ts 20.00 B
package/README.md CHANGED
@@ -13,11 +13,15 @@
13
13
 
14
14
  **BugZero** is an autonomous, AI-powered CLI that detects and repairs build, lint, and test failures — locally or as a GitHub Action that opens the fix as a pull request.
15
15
 
16
+ <img src="https://raw.githubusercontent.com/Saksham1800t/Bugzero/main/apps/bugzero/demo.svg" alt="Animated terminal demo of bugzero rescue detecting and fixing a TypeScript build error" width="700" />
17
+
18
+ <sub>Illustrative animation of a <code>bugzero rescue</code> run using the tool's real log output format.</sub>
19
+
16
20
  </div>
17
21
 
18
22
  ---
19
23
 
20
- ## ⚡ Quick Start
24
+ ## Quick Start
21
25
 
22
26
  ```bash
23
27
  npm install -g bugzero
@@ -33,11 +37,11 @@ That's it — BugZero runs your build, diagnoses the failure, generates a patch,
33
37
 
34
38
  Modern applications fail at build and deployment time for reasons that are repetitive, predictable, and ultimately fixable by a knowledgeable agent. BugZero bridges the gap between raw compiler output and working code — automatically.
35
39
 
36
- - 🔁 **No more debugging the same TypeScript error twice.** The agent reads the error, finds the file, generates the fix, and verifies it.
37
- - 🛡️ **Safe by design.** Every modified file gets a `.opspilot.bak` backup, and a multi-file fix is applied and rolled back as one atomic unit.
38
- - 🎯 **Forgiving, not brittle.** If the AI's suggested patch doesn't match the file byte-for-byte, BugZero falls back to whitespace-normalized and similarity-scored matching before giving up.
39
- - 🧠 **Model agnostic.** DeepSeek, Claude, Gemini, GPT-4o, Llama, or any model on OpenRouter.
40
- - 🤖 **CI-native.** Run it as a GitHub Action instead of a local CLI, and let it open the fix as a PR.
40
+ - **No more debugging the same TypeScript error twice.** The agent reads the error, finds the file, generates the fix, and verifies it.
41
+ - **Safe by design.** Every modified file gets a `.opspilot.bak` backup, and a multi-file fix is applied and rolled back as one atomic unit.
42
+ - **Forgiving, not brittle.** If the AI's suggested patch doesn't match the file byte-for-byte, BugZero falls back to whitespace-normalized and similarity-scored matching before giving up.
43
+ - **Model agnostic.** DeepSeek, Claude, Gemini, GPT-4o, Llama, or any model on OpenRouter.
44
+ - **CI-native.** Run it as a GitHub Action instead of a local CLI, and let it open the fix as a PR.
41
45
 
42
46
  ---
43
47
 
@@ -84,13 +88,14 @@ bugzero rescue
84
88
 
85
89
  ---
86
90
 
87
- ## ✨ Key Features
91
+ ## Key Features
88
92
 
89
93
  | Feature | Description |
90
94
  |---|---|
91
95
  | Autonomous repair loop | Runs analyze, patch, verify in a stateful LangGraph graph |
92
96
  | Multi-model support | DeepSeek, Claude, GPT-4o, Gemini, Llama via OpenRouter |
93
97
  | Framework detection | Automatically identifies your project's tooling setup |
98
+ | Package manager detection | Runs build/lint/test with npm, pnpm, yarn, or bun — whichever the target project actually uses |
94
99
  | **Multi-file patches** | A single fix attempt can edit several files at once, applied atomically — if any file's patch fails, every file touched in that attempt is rolled back |
95
100
  | **Fuzzy patch matching** | Falls back from exact match to whitespace-normalized and similarity-scored matching when the AI's snippet doesn't match the file verbatim |
96
101
  | Safe file patching | Every modified file receives a `.opspilot.bak` backup |
@@ -102,7 +107,7 @@ bugzero rescue
102
107
 
103
108
  ---
104
109
 
105
- ## 🤖 GitHub Action Mode
110
+ ## GitHub Action Mode
106
111
 
107
112
  Instead of running BugZero on your machine, run it in CI: when a check fails, it opens a pull request with the fix instead of patching your local checkout.
108
113
 
@@ -260,7 +265,7 @@ BugZero provides clear, actionable output for common failure modes:
260
265
  ---
261
266
 
262
267
  <details>
263
- <summary><strong>🛠️ Development Setup</strong> (contributing to BugZero itself)</summary>
268
+ <summary><strong>Development Setup</strong> (contributing to BugZero itself)</summary>
264
269
 
265
270
  Clone the repository and install dependencies. This project uses a pnpm monorepo managed by Turborepo, with a Vitest test suite and GitHub Actions CI.
266
271
 
package/demo.svg ADDED
@@ -0,0 +1,81 @@
1
+ <svg viewBox="0 0 700 520" xmlns="http://www.w3.org/2000/svg" font-family="SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace">
2
+ <title>bugzero rescue demo</title>
3
+ <desc>Illustrative animation of "bugzero rescue" fixing a small TypeScript error. Log lines are the tool's real output format; the example error is a stand-in, not a captured recording.</desc>
4
+
5
+ <style>
6
+ text { font-size: 13px; }
7
+ .prompt { fill: #58a6ff; }
8
+ .out { fill: #c9d1d9; }
9
+ .ok { fill: #3fb950; }
10
+ .dim { fill: #8b949e; }
11
+ .dot { }
12
+ .titlebar-label { fill: #8b949e; font-size: 12px; }
13
+
14
+ @keyframes gA { 0% { opacity: 0; } 2% { opacity: 1; } 90% { opacity: 1; } 97% { opacity: 0; } 100% { opacity: 0; } }
15
+ @keyframes gB { 0%, 6% { opacity: 0; } 9% { opacity: 1; } 90% { opacity: 1; } 97% { opacity: 0; } 100% { opacity: 0; } }
16
+ @keyframes gC { 0%, 16% { opacity: 0; } 19% { opacity: 1; } 90% { opacity: 1; } 97% { opacity: 0; } 100% { opacity: 0; } }
17
+ @keyframes gD { 0%, 26% { opacity: 0; } 29% { opacity: 1; } 90% { opacity: 1; } 97% { opacity: 0; } 100% { opacity: 0; } }
18
+ @keyframes gE { 0%, 38% { opacity: 0; } 41% { opacity: 1; } 90% { opacity: 1; } 97% { opacity: 0; } 100% { opacity: 0; } }
19
+ @keyframes gF { 0%, 48% { opacity: 0; } 50% { opacity: 1; } 90% { opacity: 1; } 97% { opacity: 0; } 100% { opacity: 0; } }
20
+ @keyframes gG { 0%, 56% { opacity: 0; } 59% { opacity: 1; } 90% { opacity: 1; } 97% { opacity: 0; } 100% { opacity: 0; } }
21
+
22
+ .groupA { animation: gA 14s ease-in-out infinite; }
23
+ .groupB { animation: gB 14s ease-in-out infinite; }
24
+ .groupC { animation: gC 14s ease-in-out infinite; }
25
+ .groupD { animation: gD 14s ease-in-out infinite; }
26
+ .groupE { animation: gE 14s ease-in-out infinite; }
27
+ .groupF { animation: gF 14s ease-in-out infinite; }
28
+ .groupG { animation: gG 14s ease-in-out infinite; }
29
+ </style>
30
+
31
+ <rect x="0" y="0" width="700" height="520" rx="10" fill="#0d1117" />
32
+ <rect x="0" y="0" width="700" height="34" rx="10" fill="#161b22" />
33
+ <rect x="0" y="24" width="700" height="10" fill="#161b22" />
34
+
35
+ <circle class="dot" cx="20" cy="17" r="6" fill="#ff5f56" />
36
+ <circle class="dot" cx="40" cy="17" r="6" fill="#ffbd2e" />
37
+ <circle class="dot" cx="60" cy="17" r="6" fill="#27c93f" />
38
+ <text class="titlebar-label" x="350" y="21" text-anchor="middle">bugzero rescue</text>
39
+
40
+ <g class="groupA">
41
+ <text class="prompt" x="18" y="54">$ bugzero rescue --path ./demo-project</text>
42
+ </g>
43
+
44
+ <g class="groupB">
45
+ <text class="out" x="18" y="83">🤖 BugZero Fix</text>
46
+ <text class="out" x="18" y="102"> Path: ./demo-project</text>
47
+ <text class="out" x="18" y="121"> Framework: typescript</text>
48
+ <text class="out" x="18" y="140"> Max attempts: 3</text>
49
+ </g>
50
+
51
+ <g class="groupC">
52
+ <text class="out" x="18" y="169">[BugZero] Running validation pipeline in: ./demo-project</text>
53
+ <text class="out" x="18" y="188">[BugZero] Running build...</text>
54
+ <text class="out" x="18" y="207">[BugZero] Detected 1 error(s) (type: typescript)</text>
55
+ </g>
56
+
57
+ <g class="groupD">
58
+ <text class="out" x="18" y="236">[BugZero] Attempt 1/3 — asking AI…</text>
59
+ </g>
60
+
61
+ <g class="groupE">
62
+ <text class="out" x="18" y="265">[BugZero] Patching 1 file: src/sum.ts</text>
63
+ <text class="out" x="18" y="284">[BugZero] Reason: Fixed subtraction typo in the sum() function</text>
64
+ <text class="out" x="18" y="303">[BugZero] Backup saved to: src/sum.ts.opspilot.bak</text>
65
+ <text class="out" x="18" y="322">[BugZero] Re-running validation pipeline to verify fix…</text>
66
+ </g>
67
+
68
+ <g class="groupF">
69
+ <text class="ok" x="18" y="351">[BugZero] ✅ Validation succeeded!</text>
70
+ </g>
71
+
72
+ <g class="groupG">
73
+ <text class="dim" x="18" y="380">──────────────────────────────────────────────</text>
74
+ <text class="ok" x="18" y="399">✅ Build fixed after 1 attempt(s)!</text>
75
+ <text class="out" x="18" y="418"> Model: deepseek/deepseek-chat</text>
76
+ <text class="out" x="18" y="437"> Tokens: Prompt: 812 | Completion: 96 | Total: 908</text>
77
+ <text class="out" x="18" y="456"> File: src/sum.ts</text>
78
+ <text class="out" x="18" y="475"> Reason: Fixed subtraction typo in the sum() function</text>
79
+ <text class="out" x="18" y="494"> Root cause: sum() used the - operator instead of +</text>
80
+ </g>
81
+ </svg>
package/dist/index.js CHANGED
@@ -466,6 +466,8 @@ var require_dist2 = __commonJS({
466
466
  var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
467
467
  var index_exports = {};
468
468
  __export(index_exports, {
469
+ detectPackageManager: () => detectPackageManager3,
470
+ getRunScriptCommand: () => getRunScriptCommand,
469
471
  parseErrors: () => parseErrors,
470
472
  runBuild: () => runBuild,
471
473
  runCommand: () => runCommand,
@@ -474,6 +476,39 @@ var require_dist2 = __commonJS({
474
476
  runValidationPipeline: () => runValidationPipeline
475
477
  });
476
478
  module2.exports = __toCommonJS(index_exports);
479
+ var import_fs = __toESM2(require("fs"));
480
+ var import_path2 = __toESM2(require("path"));
481
+ var VALID_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
482
+ var LOCKFILE_MANAGERS = [
483
+ { file: "pnpm-workspace.yaml", manager: "pnpm" },
484
+ { file: "pnpm-lock.yaml", manager: "pnpm" },
485
+ { file: "yarn.lock", manager: "yarn" },
486
+ { file: "bun.lockb", manager: "bun" },
487
+ { file: "bun.lock", manager: "bun" },
488
+ { file: "package-lock.json", manager: "npm" }
489
+ ];
490
+ function detectPackageManager3(cwd = process.cwd()) {
491
+ try {
492
+ const pkgPath = import_path2.default.join(cwd, "package.json");
493
+ if (import_fs.default.existsSync(pkgPath)) {
494
+ const pkg = JSON.parse(import_fs.default.readFileSync(pkgPath, "utf-8"));
495
+ if (typeof pkg.packageManager === "string") {
496
+ const name = pkg.packageManager.split("@")[0].trim();
497
+ if (VALID_MANAGERS.includes(name)) {
498
+ return name;
499
+ }
500
+ }
501
+ }
502
+ } catch {
503
+ }
504
+ for (const { file, manager } of LOCKFILE_MANAGERS) {
505
+ if (import_fs.default.existsSync(import_path2.default.join(cwd, file))) return manager;
506
+ }
507
+ return "npm";
508
+ }
509
+ function getRunScriptCommand(manager, script) {
510
+ return `${manager} run ${script}`;
511
+ }
477
512
  async function runCommand(command, cwd) {
478
513
  const { execa } = await import("execa");
479
514
  try {
@@ -497,9 +532,9 @@ var require_dist2 = __commonJS({
497
532
  };
498
533
  }
499
534
  }
500
- var runBuild = (cwd) => runCommand("npm run build", cwd);
501
- var runLint = (cwd) => runCommand("npm run lint", cwd);
502
- var runTests = (cwd) => runCommand("npm run test", cwd);
535
+ var runBuild = (cwd) => runCommand(getRunScriptCommand(detectPackageManager3(cwd), "build"), cwd);
536
+ var runLint = (cwd) => runCommand(getRunScriptCommand(detectPackageManager3(cwd), "lint"), cwd);
537
+ var runTests = (cwd) => runCommand(getRunScriptCommand(detectPackageManager3(cwd), "test"), cwd);
503
538
  var TS_ERROR_RE = /^(.+)\((\d+),(\d+)\):\s+error\s+TS\d+:\s+(.+)$/gm;
504
539
  var ESLINT_ERROR_RE = /^\s+(\d+):(\d+)\s+error\s+(.+)$/gm;
505
540
  var JEST_FAIL_RE = /● (.+)/g;
@@ -549,15 +584,15 @@ var require_dist2 = __commonJS({
549
584
  }
550
585
  return errors;
551
586
  }
552
- var import_fs = __toESM2(require("fs"));
553
- var import_path2 = __toESM2(require("path"));
587
+ var import_fs2 = __toESM2(require("fs"));
588
+ var import_path22 = __toESM2(require("path"));
554
589
  async function runValidationPipeline(cwd) {
555
590
  const targetCwd = cwd ?? process.cwd();
556
591
  let scripts = [];
557
592
  try {
558
- const pkgPath = import_path2.default.resolve(targetCwd, "package.json");
559
- if (import_fs.default.existsSync(pkgPath)) {
560
- const pkg = JSON.parse(import_fs.default.readFileSync(pkgPath, "utf-8"));
593
+ const pkgPath = import_path22.default.resolve(targetCwd, "package.json");
594
+ if (import_fs2.default.existsSync(pkgPath)) {
595
+ const pkg = JSON.parse(import_fs2.default.readFileSync(pkgPath, "utf-8"));
561
596
  scripts = Object.keys(pkg.scripts || {});
562
597
  }
563
598
  } catch {
@@ -1375,6 +1410,7 @@ var require_dist7 = __commonJS({
1375
1410
  var index_exports = {};
1376
1411
  __export(index_exports, {
1377
1412
  detectFramework: () => detectFramework2,
1413
+ detectPackageManager: () => import_analyzers2.detectPackageManager,
1378
1414
  orchestrate: () => orchestrate2,
1379
1415
  orchestrateAndFix: () => orchestrateAndFix2
1380
1416
  });
@@ -1707,6 +1743,7 @@ ${rawOutput}
1707
1743
  console.log("\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
1708
1744
  }
1709
1745
  }
1746
+ var import_analyzers2 = require_dist2();
1710
1747
  }
1711
1748
  });
1712
1749
 
@@ -1721,10 +1758,12 @@ program.command("hunt").description("Run build, lint, and tests \u2014 report is
1721
1758
  try {
1722
1759
  const cwd = import_path.default.resolve(opts.path);
1723
1760
  const framework = (0, import_core.detectFramework)(cwd);
1761
+ const packageManager = (0, import_core.detectPackageManager)(cwd);
1724
1762
  console.log(`
1725
1763
  \u{1F50D} BugZero \u2014 Analyzing project`);
1726
1764
  console.log(` Path: ${cwd}`);
1727
- console.log(` Framework: ${framework}
1765
+ console.log(` Framework: ${framework}`);
1766
+ console.log(` Package manager: ${packageManager}
1728
1767
  `);
1729
1768
  const { build, lint, test } = await (0, import_core.orchestrate)({ cwd });
1730
1769
  console.log("\u2500\u2500 Pipeline Summary \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
@@ -1749,10 +1788,12 @@ program.command("rescue").description("Detect build failures and automatically a
1749
1788
  const maxAttempts = parseInt(opts.maxAttempts, 10);
1750
1789
  const dryRun = opts.dryRun;
1751
1790
  const framework = (0, import_core.detectFramework)(cwd);
1791
+ const packageManager = (0, import_core.detectPackageManager)(cwd);
1752
1792
  console.log(`
1753
1793
  \u{1F916} BugZero Fix`);
1754
1794
  console.log(` Path: ${cwd}`);
1755
1795
  console.log(` Framework: ${framework}`);
1796
+ console.log(` Package manager: ${packageManager}`);
1756
1797
  console.log(` Max attempts: ${maxAttempts}`);
1757
1798
  if (dryRun) console.log(` Mode: DRY RUN (no files will be modified)`);
1758
1799
  console.log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bugzero",
3
- "version": "0.0.33",
3
+ "version": "0.0.35",
4
4
  "description": "An autonomous, AI-powered CLI tool for automatic build error detection and repair.",
5
5
  "license": "MIT",
6
6
  "bin": {
package/src/index.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  import "@opspilot/config"; // loads .env before anything else
4
4
  import { Command } from "commander";
5
5
  import path from "path";
6
- import { orchestrate, orchestrateAndFix, detectFramework } from "@opspilot/core";
6
+ import { orchestrate, orchestrateAndFix, detectFramework, detectPackageManager } from "@opspilot/core";
7
7
 
8
8
 
9
9
  const program = new Command();
@@ -22,10 +22,12 @@ program
22
22
  try {
23
23
  const cwd = path.resolve(opts.path);
24
24
  const framework = detectFramework(cwd);
25
+ const packageManager = detectPackageManager(cwd);
25
26
 
26
27
  console.log(`\n🔍 BugZero — Analyzing project`);
27
28
  console.log(` Path: ${cwd}`);
28
- console.log(` Framework: ${framework}\n`);
29
+ console.log(` Framework: ${framework}`);
30
+ console.log(` Package manager: ${packageManager}\n`);
29
31
 
30
32
  const { build, lint, test } = await orchestrate({ cwd });
31
33
 
@@ -57,10 +59,12 @@ program
57
59
  const maxAttempts = parseInt(opts.maxAttempts, 10);
58
60
  const dryRun: boolean = opts.dryRun;
59
61
  const framework = detectFramework(cwd);
62
+ const packageManager = detectPackageManager(cwd);
60
63
 
61
64
  console.log(`\n🤖 BugZero Fix`);
62
65
  console.log(` Path: ${cwd}`);
63
66
  console.log(` Framework: ${framework}`);
67
+ console.log(` Package manager: ${packageManager}`);
64
68
  console.log(` Max attempts: ${maxAttempts}`);
65
69
  if (dryRun) console.log(` Mode: DRY RUN (no files will be modified)`);
66
70
  console.log();