@shakecodeslikecray/whiterose 0.2.4 → 0.2.5

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
@@ -767,8 +767,13 @@ Set "survived": true if you CANNOT disprove it (it's a real bug).`;
767
767
  if (buffer.trim()) {
768
768
  this.processAgentOutput(buffer, callbacks);
769
769
  }
770
- if (this.fullResponseBuffer && callbacks.onUnderstanding) {
771
- this.tryExtractUnderstandingJson(this.fullResponseBuffer, callbacks);
770
+ if (this.fullResponseBuffer) {
771
+ if (callbacks.onUnderstanding) {
772
+ this.tryExtractUnderstandingJson(this.fullResponseBuffer, callbacks);
773
+ }
774
+ if (callbacks.onBugFound) {
775
+ this.tryExtractBugsJson(this.fullResponseBuffer, callbacks);
776
+ }
772
777
  }
773
778
  this.currentProcess = void 0;
774
779
  }
@@ -931,6 +936,54 @@ Set "survived": true if you CANNOT disprove it (it's a real bug).`;
931
936
  }
932
937
  }
933
938
  }
939
+ // Try to extract bug JSON objects from text without markers
940
+ tryExtractBugsJson(text3, callbacks) {
941
+ const candidates = [];
942
+ let depth = 0;
943
+ let start = -1;
944
+ let inString = false;
945
+ let escapeNext = false;
946
+ for (let i = 0; i < text3.length; i++) {
947
+ const char = text3[i];
948
+ if (escapeNext) {
949
+ escapeNext = false;
950
+ continue;
951
+ }
952
+ if (char === "\\" && inString) {
953
+ escapeNext = true;
954
+ continue;
955
+ }
956
+ if (char === '"' && !escapeNext) {
957
+ inString = !inString;
958
+ continue;
959
+ }
960
+ if (inString) continue;
961
+ if (char === "{") {
962
+ if (depth === 0) {
963
+ start = i;
964
+ }
965
+ depth++;
966
+ } else if (char === "}") {
967
+ depth--;
968
+ if (depth === 0 && start !== -1) {
969
+ const candidate = text3.slice(start, i + 1);
970
+ if (candidate.includes('"file"') && candidate.includes('"line"') && candidate.includes('"title"')) {
971
+ candidates.push(candidate);
972
+ }
973
+ start = -1;
974
+ }
975
+ }
976
+ }
977
+ for (const jsonStr of candidates) {
978
+ try {
979
+ const parsed = JSON.parse(jsonStr);
980
+ if (parsed.file && parsed.line && parsed.title) {
981
+ callbacks.onBugFound?.(jsonStr);
982
+ }
983
+ } catch {
984
+ }
985
+ }
986
+ }
934
987
  // Simple non-agentic mode for short prompts (adversarial validation)
935
988
  async runSimpleClaude(prompt, cwd) {
936
989
  const claudeCommand = getProviderCommand("claude-code");
@@ -4293,7 +4346,7 @@ ${chalk.red(" \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D \u255A\u2550\u255
4293
4346
  ${chalk.dim(` "I've been staring at your code for a long time."`)}
4294
4347
  `;
4295
4348
  var program = new Command();
4296
- program.name("whiterose").description("AI-powered bug hunter that uses your existing LLM subscription").version("0.2.4").hook("preAction", () => {
4349
+ program.name("whiterose").description("AI-powered bug hunter that uses your existing LLM subscription").version("0.2.5").hook("preAction", () => {
4297
4350
  const args = process.argv.slice(2);
4298
4351
  if (!args.includes("--help") && !args.includes("-h") && args.length > 0) {
4299
4352
  console.log(BANNER);