@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 +61 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +50 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { existsSync, mkdirSync, writeFileSync, readdirSync,
|
|
3
|
-
import { join, isAbsolute, resolve, basename, relative
|
|
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
|
-
|
|
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+([
|
|
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((
|
|
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 {
|
|
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(
|
|
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(
|
|
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);
|