@shakecodeslikecray/whiterose 1.0.0 → 1.0.2

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/dist/cli/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync, mkdirSync, writeFileSync, readdirSync, readFileSync, statSync, rmSync, mkdtempSync, realpathSync } from 'fs';
3
- import { join, isAbsolute, resolve, basename, relative, dirname } from 'path';
2
+ import { readFileSync, existsSync, mkdirSync, writeFileSync, readdirSync, statSync, rmSync, mkdtempSync, realpathSync } from 'fs';
3
+ import { join, dirname, isAbsolute, resolve, basename, relative } from 'path';
4
4
  import chalk3 from 'chalk';
5
5
  import * as readline from 'readline';
6
6
  import { Command } from 'commander';
7
7
  import * as p3 from '@clack/prompts';
8
+ import { fileURLToPath } from 'url';
8
9
  import { execa } from 'execa';
9
10
  import { homedir, tmpdir } from 'os';
10
11
  import fg3 from 'fast-glob';
@@ -467,13 +468,56 @@ var AiderExecutor = class {
467
468
  }
468
469
  }
469
470
  };
471
+ var OLLAMA_TIMEOUT = 6e5;
472
+ var DEFAULT_MODEL = "codellama";
473
+ var OllamaExecutor = class {
474
+ name = "ollama";
475
+ model;
476
+ constructor(model = DEFAULT_MODEL) {
477
+ this.model = model;
478
+ }
479
+ async isAvailable() {
480
+ return isProviderAvailable("ollama");
481
+ }
482
+ async runPrompt(prompt, options) {
483
+ const ollamaCommand = getProviderCommand("ollama");
484
+ try {
485
+ const { stdout, stderr } = await execa(
486
+ ollamaCommand,
487
+ ["run", this.model, prompt],
488
+ {
489
+ cwd: options.cwd,
490
+ timeout: options.timeout || OLLAMA_TIMEOUT,
491
+ env: {
492
+ ...process.env,
493
+ NO_COLOR: "1"
494
+ },
495
+ reject: false
496
+ }
497
+ );
498
+ return {
499
+ output: stdout || "",
500
+ error: stderr || void 0
501
+ };
502
+ } catch (error) {
503
+ if (error.message?.includes("ENOENT")) {
504
+ throw new Error("Ollama not found. Install from: https://ollama.ai");
505
+ }
506
+ if (error.message?.includes("model") && error.message?.includes("not found")) {
507
+ throw new Error(`Ollama model '${this.model}' not found. Run: ollama pull ${this.model}`);
508
+ }
509
+ throw error;
510
+ }
511
+ }
512
+ };
470
513
 
471
514
  // src/providers/executors/index.ts
472
515
  var executors = {
473
516
  "claude-code": () => new ClaudeCodeExecutor(),
474
517
  "codex": () => new CodexExecutor(),
475
518
  "gemini": () => new GeminiExecutor(),
476
- "aider": () => new AiderExecutor()
519
+ "aider": () => new AiderExecutor(),
520
+ "ollama": () => new OllamaExecutor()
477
521
  };
478
522
  function getExecutor(name) {
479
523
  const factory = executors[name];
@@ -2658,7 +2702,10 @@ async function getChangedFiles(cwd, config, options) {
2658
2702
  };
2659
2703
  if (existsSync(cachePath)) {
2660
2704
  try {
2661
- cachedState = JSON.parse(readFileSync(cachePath, "utf-8"));
2705
+ const parsed = JSON.parse(readFileSync(cachePath, "utf-8"));
2706
+ if (Array.isArray(parsed.fileHashes)) {
2707
+ cachedState = parsed;
2708
+ }
2662
2709
  } catch {
2663
2710
  }
2664
2711
  }
@@ -2888,7 +2935,7 @@ function parseListItems(content) {
2888
2935
  return items;
2889
2936
  }
2890
2937
  function parseFeatureSection(section) {
2891
- const titleMatch = section.match(/###\s+([^\[\n]+)(?:\s*\[([^\]]+)\])?/);
2938
+ const titleMatch = section.match(/###\s+([^[\n]+)(?:\s*\[([^\]]+)\])?/);
2892
2939
  if (!titleMatch) return null;
2893
2940
  const name = titleMatch[1].trim();
2894
2941
  const badge = titleMatch[2]?.trim().toLowerCase();
@@ -5427,7 +5474,7 @@ var Dashboard = ({ bugs, onSelectCategory }) => {
5427
5474
  color: categoryColors[category] || "white"
5428
5475
  });
5429
5476
  }
5430
- useInput((input, key) => {
5477
+ useInput((_input, key) => {
5431
5478
  if (key.upArrow) {
5432
5479
  setSelectedIndex((i) => Math.max(0, i - 1));
5433
5480
  } else if (key.downArrow) {
@@ -6092,7 +6139,7 @@ async function createFixBranch(branchName, bug, cwd = process.cwd()) {
6092
6139
  }
6093
6140
  async function commitFix(bug, cwd = process.cwd()) {
6094
6141
  try {
6095
- await execa("git", ["add", bug.file], { cwd, timeout: GIT_TIMEOUT });
6142
+ await execa("git", ["add", "--", bug.file], { cwd, timeout: GIT_TIMEOUT });
6096
6143
  const { stdout: diff } = await execa("git", ["diff", "--cached", "--name-only"], {
6097
6144
  cwd,
6098
6145
  timeout: GIT_TIMEOUT
@@ -6493,7 +6540,7 @@ async function startFixTUI(bugs, config, options, cwd) {
6493
6540
  const handleExit = () => {
6494
6541
  resolve6();
6495
6542
  };
6496
- const { unmount, waitUntilExit } = render(
6543
+ const { waitUntilExit } = render(
6497
6544
  /* @__PURE__ */ jsx(
6498
6545
  App,
6499
6546
  {
@@ -6505,9 +6552,7 @@ async function startFixTUI(bugs, config, options, cwd) {
6505
6552
  }
6506
6553
  )
6507
6554
  );
6508
- waitUntilExit().then(() => {
6509
- resolve6();
6510
- });
6555
+ waitUntilExit().then(resolve6).catch(() => resolve6());
6511
6556
  });
6512
6557
  }
6513
6558
 
@@ -6958,7 +7003,7 @@ function mapSarifLevel(level) {
6958
7003
  return "medium";
6959
7004
  }
6960
7005
  }
6961
- async function refreshCommand(options) {
7006
+ async function refreshCommand(_options) {
6962
7007
  const cwd = process.cwd();
6963
7008
  const whiterosePath = join(cwd, ".whiterose");
6964
7009
  if (!existsSync(whiterosePath)) {
@@ -7211,6 +7256,9 @@ async function clearCommand(options) {
7211
7256
  }
7212
7257
 
7213
7258
  // src/cli/index.ts
7259
+ var __filename$1 = fileURLToPath(import.meta.url);
7260
+ var __dirname$1 = dirname(__filename$1);
7261
+ var pkg = JSON.parse(readFileSync(join(__dirname$1, "../../package.json"), "utf-8"));
7214
7262
  process.setMaxListeners(50);
7215
7263
  var BANNER = `
7216
7264
  ${chalk3.red("\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557")}
@@ -7223,7 +7271,7 @@ ${chalk3.red(" \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D \u255A\u2550\u25
7223
7271
  ${chalk3.dim(` "I've been staring at your code for a long time."`)}
7224
7272
  `;
7225
7273
  var program = new Command();
7226
- program.name("whiterose").description("AI-powered bug hunter that uses your existing LLM subscription").version("0.2.7").hook("preAction", () => {
7274
+ program.name("whiterose").description("AI-powered bug hunter that uses your existing LLM subscription").version(pkg.version).hook("preAction", () => {
7227
7275
  const args = process.argv.slice(2);
7228
7276
  if (!args.includes("--help") && !args.includes("-h") && args.length > 0) {
7229
7277
  console.log(BANNER);