@wrongstack/core 0.309.0 → 0.309.1

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.
@@ -1751,6 +1751,14 @@ var PATTERNS = [
1751
1751
  anchor: "sk-ant-"
1752
1752
  },
1753
1753
  { type: "openai_key", regex: /(?<![A-Za-z0-9])sk-(?:proj-)?[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g, anchor: "sk-" },
1754
+ {
1755
+ // `xai` is a first-class provider in this codebase, but its key shape was
1756
+ // absent here — so the one credential format WrongStack itself hands users
1757
+ // was the one the scrubber could not recognize (audit 2026-08-20).
1758
+ type: "xai_key",
1759
+ regex: /(?<![A-Za-z0-9])xai-[A-Za-z0-9]{20,}(?![A-Za-z0-9])/g,
1760
+ anchor: "xai-"
1761
+ },
1754
1762
  { type: "github_pat", regex: /(?<![A-Za-z0-9])ghp_[A-Za-z0-9]{36,}(?![A-Za-z0-9])/g, anchor: "ghp_" },
1755
1763
  { type: "github_pat_v2", regex: /(?<![A-Za-z0-9])github_pat_[A-Za-z0-9_]{50,}(?![A-Za-z0-9])/g, anchor: "github_pat_" },
1756
1764
  { type: "aws_access_key", regex: /(?<![A-Za-z0-9])AKIA[0-9A-Z]{16}(?![A-Za-z0-9])/g, anchor: "AKIA" },
@@ -1841,8 +1849,8 @@ var PATTERNS = [
1841
1849
  // replacement so the separator between adjacent secrets is preserved
1842
1850
  // rather than collapsed. Capture groups are therefore: 1=leading
1843
1851
  // delimiter, 2=key name, 3=value.
1844
- regex: /(^|\s)([A-Z_]{4,}(?:KEY|TOKEN|SECRET|PASSWORD|PWD))\s*[:=]\s*['"]?([A-Za-z0-9_/+=-]{20,512})['"]?(?=\s|$)/g,
1845
- anchor: ["KEY", "TOKEN", "SECRET", "PASSWORD", "PWD"]
1852
+ regex: /(^|\s)([A-Z_]{4,}(?:KEY|TOKEN|SECRET|PASSWORD|PWD|PASSPHRASE))\s*[:=]\s*['"]?([A-Za-z0-9_/+=-]{20,512})['"]?(?=\s|$)/g,
1853
+ anchor: ["KEY", "TOKEN", "SECRET", "PASSWORD", "PWD", "PASSPHRASE"]
1846
1854
  },
1847
1855
  {
1848
1856
  type: "json_credential_key",
@@ -1959,6 +1967,27 @@ var JSON_CREDENTIAL_REGEX = PATTERNS.find((p) => p.type === "json_credential_key
1959
1967
  var COMBINED_REPLACEMENTS = SIMPLE_PATTERNS.map((p) => `[REDACTED:${p.type}]`);
1960
1968
  var SCRUB_CHUNK_BYTES = 64 * 1024;
1961
1969
  var SCRUB_OVERLAP_BYTES = 1024;
1970
+ var PEM_PRIVATE_KEY_BEGIN_RE = /-----BEGIN (?:RSA|EC|OPENSSH|DSA|PGP)? ?PRIVATE KEY-----/;
1971
+ var PEM_END_MARKER = "-----END";
1972
+ var MAX_PEM_BLOCK_BYTES = 64 * 1024;
1973
+ var PEM_END_LINE_TOLERANCE = 64;
1974
+ function extendChunkBoundaryPastPem(text, chunkStart, proposedEnd) {
1975
+ const head = text.slice(chunkStart, proposedEnd);
1976
+ const lastBegin = head.lastIndexOf("-----BEGIN ");
1977
+ if (lastBegin === -1) return proposedEnd;
1978
+ const fromBegin = text.slice(chunkStart + lastBegin);
1979
+ const marker = PEM_PRIVATE_KEY_BEGIN_RE.exec(fromBegin);
1980
+ if (!marker || marker.index !== 0) return proposedEnd;
1981
+ const bodyStart = marker[0].length;
1982
+ const cap = Math.min(text.length, chunkStart + lastBegin + MAX_PEM_BLOCK_BYTES);
1983
+ const closeIdx = fromBegin.indexOf(PEM_END_MARKER, bodyStart);
1984
+ if (closeIdx === -1 || chunkStart + lastBegin + closeIdx >= cap + PEM_END_LINE_TOLERANCE) {
1985
+ return proposedEnd;
1986
+ }
1987
+ const lineEnd = fromBegin.indexOf("\n", closeIdx);
1988
+ const end = lineEnd === -1 ? text.length : chunkStart + lastBegin + lineEnd + 1;
1989
+ return Math.max(proposedEnd, end);
1990
+ }
1962
1991
  var PATTERN_ANCHORS = [
1963
1992
  ...new Set(
1964
1993
  PATTERNS.flatMap(
@@ -1995,6 +2024,7 @@ var DefaultSecretScrubber = class {
1995
2024
  }
1996
2025
  }
1997
2026
  end = safe === -1 ? end : safe + 1;
2027
+ end = extendChunkBoundaryPastPem(text, i, end);
1998
2028
  }
1999
2029
  out.push(this.scrubOne(text.slice(i, end)));
2000
2030
  i = end;
@@ -6240,6 +6270,7 @@ function maybeAppendPendingNextSteps(ctx, res) {
6240
6270
  // src/prompts/prompt-journal.ts
6241
6271
  import * as fs5 from "node:fs/promises";
6242
6272
  import * as path11 from "node:path";
6273
+ var defaultScrubber2 = new DefaultSecretScrubber();
6243
6274
  async function ensureGitignore(projectRoot) {
6244
6275
  const gitignorePath = path11.join(projectRoot, ".gitignore");
6245
6276
  try {
@@ -6267,7 +6298,9 @@ async function recordPromptJournalEntry(opts) {
6267
6298
  const monthStr = dateStr.slice(0, 7);
6268
6299
  const sessionId = opts.sessionId && opts.sessionId.trim() ? opts.sessionId.trim() : "general";
6269
6300
  const id = `pmt_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
6270
- const content = opts.content ?? "";
6301
+ const content = defaultScrubber2.scrub(opts.content ?? "");
6302
+ const rawContent = typeof opts.rawContent === "string" && opts.rawContent.length > 0 ? defaultScrubber2.scrub(opts.rawContent) : opts.rawContent;
6303
+ const decisionReason = typeof opts.decisionReason === "string" && opts.decisionReason.length > 0 ? defaultScrubber2.scrub(opts.decisionReason) : opts.decisionReason;
6271
6304
  const lines = content.split("\n");
6272
6305
  const characterCount = content.length;
6273
6306
  const lineCount = lines.length;
@@ -6280,7 +6313,7 @@ async function recordPromptJournalEntry(opts) {
6280
6313
  role: opts.role ?? (opts.category === "system_prompt" ? "system" : "user"),
6281
6314
  category: opts.category,
6282
6315
  content,
6283
- rawContent: opts.rawContent,
6316
+ rawContent,
6284
6317
  metadata: {
6285
6318
  model: opts.model,
6286
6319
  provider: opts.provider,
@@ -6291,7 +6324,7 @@ async function recordPromptJournalEntry(opts) {
6291
6324
  activeTools: opts.activeTools,
6292
6325
  contextFiles: opts.contextFiles,
6293
6326
  durationMs: opts.durationMs,
6294
- decisionReason: opts.decisionReason,
6327
+ decisionReason,
6295
6328
  tags: opts.tags
6296
6329
  }
6297
6330
  };
@@ -8891,10 +8924,7 @@ function createAgentToolHandler(a) {
8891
8924
  } catch {
8892
8925
  }
8893
8926
  }
8894
- if (decision === "yes") {
8895
- const p = a.permission;
8896
- p.allowOnce?.({ tool: tool.name, pattern: result.suggestedPattern });
8897
- } else if (decision === "no") {
8927
+ if (decision === "no") {
8898
8928
  const p = a.permission;
8899
8929
  p.denyOnce?.({ tool: tool.name, pattern: result.suggestedPattern });
8900
8930
  }