@tekmidian/pai 1.0.6 → 1.0.7

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.
Files changed (130) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/auto-route-CAlZ5p-h.mjs +11 -0
  3. package/dist/{auto-route-YaEGVrFl.mjs → auto-route-PDOAYszN.mjs} +2 -2
  4. package/dist/{budget-DEiebT2A.mjs → budget-BXmsSBLI.mjs} +10 -10
  5. package/dist/{caller-identity-C6Nc96iM.mjs → caller-identity-DPDSrZE2.mjs} +2 -2
  6. package/dist/{capacity-B2PgKAg4.mjs → capacity-CThSydrd.mjs} +25 -13
  7. package/dist/{chain-CtK49-Ma.mjs → chain-BvdKqRiZ.mjs} +5 -5
  8. package/dist/cli/index.mjs +182 -111
  9. package/dist/{cockpit-actions-D1OPP6Es.mjs → cockpit-actions-BgdKB9G3.mjs} +19 -19
  10. package/dist/{cockpit-actions-C73mJAJ8.mjs → cockpit-actions-DNl0rKfW.mjs} +14 -14
  11. package/dist/cockpit-memory-CqLPjcWe.mjs +20 -0
  12. package/dist/config/defaults/config.yaml +6 -0
  13. package/dist/config/defaults/workers.yaml +2 -0
  14. package/dist/{config-DLmyEK2q.mjs → config-C2dd2SXS.mjs} +1 -1
  15. package/dist/{config-Bz8pAU5Q.mjs → config-DGV64YJa.mjs} +9 -1
  16. package/dist/{controls-rIItFeIJ.mjs → controls-ByrcupcA.mjs} +14 -14
  17. package/dist/daemon/index.mjs +29 -29
  18. package/dist/{daemon-SoUvPUOf.mjs → daemon-BjgJyJMP.mjs} +22 -22
  19. package/dist/daemon-iymy18Ie.mjs +46 -0
  20. package/dist/daemon-mcp/index.mjs +27 -27
  21. package/dist/{embed-pass-CN1D8MXl.mjs → embed-pass-DdTMn4DH.mjs} +4 -4
  22. package/dist/{endreason-C2-hYK0_.mjs → endreason-BjPom527.mjs} +4 -4
  23. package/dist/{fallback-CwPSCrX8.mjs → fallback-CQ8_CuVu.mjs} +4 -4
  24. package/dist/{health-D0mUAVdw.mjs → health-Bb2U4PNK.mjs} +4 -4
  25. package/dist/hooks/block-sleep-poll.mjs +9 -0
  26. package/dist/hooks/capture-all-events.mjs +38 -7
  27. package/dist/hooks/capture-tool-output.mjs +38 -7
  28. package/dist/hooks/handoff-link.mjs +37 -6
  29. package/dist/hooks/load-project-context.mjs +9 -0
  30. package/dist/hooks/local-model-hint.mjs +9 -0
  31. package/dist/hooks/route-agents-to-worker.mjs +9 -0
  32. package/dist/hooks/security-validator.mjs +124 -28
  33. package/dist/hooks/supervision-banner.mjs +40 -7
  34. package/dist/hooks/worker-edit-repair.mjs +9 -0
  35. package/dist/hooks/worker-guard.mjs +46 -6
  36. package/dist/hooks/worker-note.mjs +47 -7
  37. package/dist/hooks/worker-pool-host.mjs +308 -146
  38. package/dist/hooks/worker-proxy.mjs +9 -0
  39. package/dist/hooks/worker-status-line.mjs +49 -7
  40. package/dist/hooks/worker-supervision.mjs +9 -0
  41. package/dist/hooks/worker-tool-name-repair.mjs +9 -0
  42. package/dist/index.mjs +7 -7
  43. package/dist/kill-tree-BlPw1vaU.mjs +10 -0
  44. package/dist/{kill-tree-DPiMscaY.mjs → kill-tree-DTmiEb3T.mjs} +7 -7
  45. package/dist/{launch-Bn2Zf90h.mjs → launch-CV6oPHI2.mjs} +3 -3
  46. package/dist/{launch-BZT3JDoZ.mjs → launch-Dy8qQnSD.mjs} +3 -3
  47. package/dist/{lessons-CFVU0cwA.mjs → lessons-CdmqZD0G.mjs} +21 -21
  48. package/dist/{local-candidate-DFd4pp-w.mjs → local-candidate-C2FGhf54.mjs} +2 -2
  49. package/dist/{local-instances-KTh8IeOT.mjs → local-instances-GgXydQ2P.mjs} +1 -1
  50. package/dist/{local-tiers-DSlIYvvm.mjs → local-tiers-X_dQfI4Q.mjs} +1 -1
  51. package/dist/{main-config-ops-rda08BCD.mjs → main-config-ops-C_fkINDv.mjs} +2 -2
  52. package/dist/{main-resolver-BKwI0I6H.mjs → main-resolver-CN_sfG1R.mjs} +13 -13
  53. package/dist/{model-inventory-BXv15B0d.mjs → model-inventory-BYNrSTaY.mjs} +10 -10
  54. package/dist/{models-add-5yXTyz3g.mjs → models-add-Dc7VXmcu.mjs} +30 -30
  55. package/dist/operator-IrLbk8hy.mjs +7 -0
  56. package/dist/{operator-Br6GeswF.mjs → operator-lRGvYr3D.mjs} +2 -2
  57. package/dist/{pai-marker-D6OoVbM_.mjs → pai-marker-kA0iM7rP.mjs} +2 -2
  58. package/dist/{pane-audit-DLYy9-4g.mjs → pane-audit-DUuilP1V.mjs} +8 -8
  59. package/dist/{paths-CypxFTfn.mjs → paths-BwfwHOvN.mjs} +2 -2
  60. package/dist/{paths-DIOwNcj-.mjs → paths-CKGYM0Lb.mjs} +2 -2
  61. package/dist/{planner-BzZ_2lc-.mjs → planner-BDHVUkIM.mjs} +22 -22
  62. package/dist/{pool-9EsbKD-U.mjs → pool-CFeHGX7q.mjs} +2 -2
  63. package/dist/{pool-cli-Cy5mlycP.mjs → pool-cli-Bj2TeA-d.mjs} +5 -5
  64. package/dist/{pool-cli-Db0uDwB9.mjs → pool-cli-DOLgPgOM.mjs} +5 -5
  65. package/dist/{project-setup-DHxdJjEc.mjs → project-setup-i5D0xkTn.mjs} +21 -21
  66. package/dist/{providers-BNV7CzC-.mjs → providers-BC2Myo_O.mjs} +5 -5
  67. package/dist/{providers-BH6hQYbU.mjs → providers-C-mnlH1b.mjs} +11 -11
  68. package/dist/{registrable-BwFiqazy.mjs → registrable-Ct0DKNKS.mjs} +6 -6
  69. package/dist/{registrable-Dxs4oKIj.mjs → registrable-D_4qXCnq.mjs} +4 -4
  70. package/dist/{render-jPpMrudf.mjs → render-CbifCwTb.mjs} +175 -65
  71. package/dist/{render-DVGXpfaT.mjs → render-FB4Fv_fi.mjs} +10 -10
  72. package/dist/{root-C8cxhdn9.mjs → root-80ESg6b7.mjs} +21 -21
  73. package/dist/{root-DmOzMeSv.mjs → root-B-ZYiEgi.mjs} +10 -10
  74. package/dist/{route-table-COAmc1nB.mjs → route-table-DcBZCuco.mjs} +10 -10
  75. package/dist/{routing-aJKMIagQ.mjs → routing-CF0wlR-_.mjs} +10 -10
  76. package/dist/{routing-B_cg1_Xx.mjs → routing-CJ8ioPl2.mjs} +10 -10
  77. package/dist/{run-DE9Q0ldN.mjs → run-CAjfKBQV.mjs} +53 -26
  78. package/dist/{scan-CNMcltOX.mjs → scan-ew8M6tTH.mjs} +3 -3
  79. package/dist/{scope-BTWstJ1B.mjs → scope-BRcaPw5D.mjs} +4 -4
  80. package/dist/session-BmQsXF_a.mjs +35 -0
  81. package/dist/{session-HBYOABWU.mjs → session-C1JnDXvP.mjs} +14 -14
  82. package/dist/{session-scan-BZxnYN1v.mjs → session-scan-DWCUKhDM.mjs} +5 -5
  83. package/dist/{session-scan-CX3MKCNg.mjs → session-scan-DihMibI-.mjs} +4 -4
  84. package/dist/{session-usage-CCmPFFa6.mjs → session-usage-BRIWFYPS.mjs} +2 -2
  85. package/dist/{status-D52xC_i0.mjs → status-Bj4yVKj0.mjs} +3 -3
  86. package/dist/{status-Cecau8Ps.mjs → status-DTMT5lyn.mjs} +2 -2
  87. package/dist/{tool-errors-BFw1gv-z.mjs → tool-errors-BOW2n882.mjs} +2 -2
  88. package/dist/{tool-errors-COM2JGEr.mjs → tool-errors-jNJj3Gzm.mjs} +5 -5
  89. package/dist/{viewer-DvBg6N22.mjs → viewer-4BU8w_gK.mjs} +14 -14
  90. package/dist/viewer-D3VEdqhC.mjs +22 -0
  91. package/dist/{wait-C5iWILj_.mjs → wait-BindDA5w.mjs} +3 -3
  92. package/dist/{worker-config-DkONNk_H.mjs → worker-config-CdPmb4_2.mjs} +25 -25
  93. package/dist/{worker-config-BmcJ9R0U.mjs → worker-config-CfV2dgSb.mjs} +29 -29
  94. package/dist/{workers-config-DwzrtdYu.mjs → workers-config-2VipVOYk.mjs} +1 -1
  95. package/dist/{worktree-O_kU6Q3y.mjs → worktree-7ZS3RBf8.mjs} +21 -11
  96. package/gemini-extension.json +1 -1
  97. package/package.json +1 -1
  98. package/pai-plugin.json +1 -1
  99. package/plugins/context-preservation/plugin.json +1 -1
  100. package/plugins/core/plugin.json +1 -1
  101. package/plugins/creative/plugin.json +1 -1
  102. package/plugins/observability/plugin.json +1 -1
  103. package/plugins/productivity/plugin.json +1 -1
  104. package/plugins/semantic-search/plugin.json +1 -1
  105. package/plugins/ui/plugin.json +1 -1
  106. package/plugins/zettelkasten/plugin.json +1 -1
  107. package/src/hooks/ts/lib/rules/builtin/base64-decode-to-shell.rule.yaml +3 -1
  108. package/src/hooks/ts/lib/rules/builtin/chmod-zero.rule.yaml +2 -0
  109. package/src/hooks/ts/lib/rules/builtin/curl-piped-to-shell.rule.yaml +8 -1
  110. package/src/hooks/ts/lib/rules/builtin/find-root-delete.rule.yaml +4 -1
  111. package/src/hooks/ts/lib/rules/builtin/instruction-override-disregard.rule.yaml +2 -0
  112. package/src/hooks/ts/lib/rules/builtin/reverse-shell-dev-tcp.rule.yaml +3 -0
  113. package/src/hooks/ts/lib/rules/builtin/reverse-shell-interactive-bash.rule.yaml +1 -0
  114. package/src/hooks/ts/lib/rules/builtin/rm-recursive-parent.rule.yaml +3 -1
  115. package/src/hooks/ts/lib/rules/builtin/rm-recursive-relative.rule.yaml +2 -1
  116. package/src/hooks/ts/lib/rules/builtin/rm-recursive-root.rule.yaml +4 -1
  117. package/src/hooks/ts/lib/rules/builtin/rm-trailing-tilde.rule.yaml +2 -1
  118. package/src/hooks/ts/lib/rules/builtin.generated.ts +34 -7
  119. package/src/hooks/ts/lib/rules/eval.ts +6 -4
  120. package/src/hooks/ts/lib/rules/lint.ts +7 -1
  121. package/src/hooks/ts/lib/rules/load.ts +55 -20
  122. package/src/hooks/ts/lib/rules/types.ts +2 -0
  123. package/src/hooks/ts/pre-tool-use/security-validator.ts +10 -2
  124. package/dist/auto-route-Bc8xP6TQ.mjs +0 -11
  125. package/dist/cockpit-memory-CLHZD64W.mjs +0 -20
  126. package/dist/daemon-176qA79N.mjs +0 -46
  127. package/dist/kill-tree-Dxei6qlR.mjs +0 -10
  128. package/dist/operator-Bmv5tiHQ.mjs +0 -7
  129. package/dist/session-DgZifjLx.mjs +0 -35
  130. package/dist/viewer-Ce-Xa9L3.mjs +0 -22
@@ -8180,6 +8180,7 @@ function defaultWorkersConfig() {
8180
8180
  cacheKeepaliveSecs: num(w.cacheKeepaliveSecs, 0),
8181
8181
  defaultMaxMinutes: num(w.defaultMaxMinutes, 60),
8182
8182
  waitAlarmMinutes: num(w.waitAlarmMinutes, 120),
8183
+ scanBudgetMs: num(w.scanBudgetMs, 5e3),
8183
8184
  stagger: {
8184
8185
  enabled: bool(stagger.enabled, true),
8185
8186
  localDefaultSec: num(stagger.localDefaultSec, 20),
@@ -8774,6 +8775,13 @@ function parseWorkersConfig(raw, yamlProviders = {}) {
8774
8775
  }
8775
8776
  waitAlarmMinutes = w.waitAlarmMinutes;
8776
8777
  }
8778
+ let scanBudgetMs = d.scanBudgetMs ?? 5e3;
8779
+ if (w.scanBudgetMs !== void 0) {
8780
+ if (typeof w.scanBudgetMs !== "number" || !Number.isInteger(w.scanBudgetMs) || w.scanBudgetMs < 1) {
8781
+ bad(".scanBudgetMs", "must be a positive integer (milliseconds)");
8782
+ }
8783
+ scanBudgetMs = w.scanBudgetMs;
8784
+ }
8777
8785
  const stagger = { ...d.stagger };
8778
8786
  if (w.stagger !== void 0) {
8779
8787
  if (typeof w.stagger !== "object" || w.stagger === null || Array.isArray(w.stagger)) {
@@ -8910,6 +8918,7 @@ function parseWorkersConfig(raw, yamlProviders = {}) {
8910
8918
  cacheKeepaliveSecs,
8911
8919
  defaultMaxMinutes,
8912
8920
  waitAlarmMinutes,
8921
+ scanBudgetMs,
8913
8922
  stagger,
8914
8923
  capacity,
8915
8924
  localIdle,
@@ -10412,20 +10421,50 @@ function wrapTestCommand(command) {
10412
10421
  var REDACTED = "[REDACTED]";
10413
10422
  var REDACTED_RE = String.raw`\[REDACTED\]`;
10414
10423
  var KEY_WORDS = "password|passwd|secret|token|api[_-]?key|credential|auth(?:orization)?|bearer";
10424
+ var PROSE = "is|are|was|were|be|to|of|in|on|for|and|or|the|a|an|that|this|it|not|out|here|there|so|as|at|by|with|if|when|which";
10415
10425
  var VAL = String.raw`(?:"[^"]*"|'[^']*'|[^\s'"]+)`;
10416
10426
  var REDACT_RULES = [
10417
10427
  {
10418
10428
  // `Authorization: Bearer xxx` / `Authorization: Basic xxx` — keep the scheme
10419
10429
  id: "authorization",
10420
- re: /(Authorization\s*:\s*)(Bearer|Basic)\s+(\S+)/gi,
10430
+ re: /(Authorization\s*:\s*)(Bearer|Basic)\s+([^\s'"]+)/gi,
10421
10431
  replace: (_m, head, scheme) => `${head}${scheme} ${REDACTED}`
10422
10432
  },
10433
+ {
10434
+ // `Cookie: a=b; c=d` — keep the cookie names, redact every value
10435
+ id: "cookie",
10436
+ re: /((?:Set-)?Cookie\s*:\s*)([^\n]+)/gi,
10437
+ replace: (_m, head, rest) => `${head}${rest.replace(/([^=;\s'"]+=)[^;'"]*/g, `$1${REDACTED}`)}`
10438
+ },
10423
10439
  {
10424
10440
  // `key=value`, `key: value`, `"key": "value"` — key carries a secret-ish word;
10425
- // the word must be a whole key segment, so `monkeys=` stays untouched
10441
+ // the word must be a whole key segment, so `monkeys=` stays untouched.
10442
+ // The separator may start with the key's closing quote (JSON); it is kept.
10426
10443
  id: "key-value",
10427
- re: new RegExp(String.raw`(?<![A-Za-z0-9])((?:[A-Za-z0-9]+[_-])?(?:${KEY_WORDS})(?![A-Za-z0-9])[A-Za-z0-9_-]*)(\s*[:=]\s*)(?!(?:Bearer|Basic) ${REDACTED_RE})(${VAL})`, "gi"),
10428
- replace: (_m, key, sep) => `${key}${sep}${REDACTED}`
10444
+ re: new RegExp(String.raw`(?<![A-Za-z0-9])((?:[A-Za-z0-9]+[_-])?(?:${KEY_WORDS})(?![A-Za-z0-9])[A-Za-z0-9_-]*)(["']?\s*[:=]\s*)(?!(?:Bearer|Basic) ${REDACTED_RE})(?!(?:${PROSE})\b)(${VAL})`, "gi"),
10445
+ replace: (m, key, sep, val) => {
10446
+ if (/[_-](?:count|length|len|size|limit|max|min|budget)$/i.test(key) && /^\d+$/.test(val)) return m;
10447
+ const q = sep[0] === '"' || sep[0] === "'" ? val[0] : "";
10448
+ return q && (q === '"' || q === "'") ? `${key}${sep}${q}${REDACTED}${q}` : `${key}${sep}${REDACTED}`;
10449
+ }
10450
+ },
10451
+ {
10452
+ // npmrc `//registry/:_authToken=xxx`
10453
+ id: "npm-auth-token",
10454
+ re: new RegExp(String.raw`(_authToken\s*=\s*)(${VAL})`, "g"),
10455
+ replace: (_m, head) => `${head}${REDACTED}`
10456
+ },
10457
+ {
10458
+ // `curl -u user:pass` / `--user user:pass` — keep the user
10459
+ id: "curl-user",
10460
+ re: /(\bcurl\b[^\n]{0,500}?\s(?:-u|--user)[\s=]+['"]?[^\s:'"]+:)([^\s'"]+)/g,
10461
+ replace: (_m, head) => `${head}${REDACTED}`
10462
+ },
10463
+ {
10464
+ // `mysql -phunter2` / `mysqldump -p'hunter2'` — attached password only
10465
+ id: "mysql-p",
10466
+ re: /(\bmysql(?:dump)?\b[^\n]{0,300}?\s-p)('[^']*'|"[^"]*"|[^\s'"-][^\s'"]*)/g,
10467
+ replace: (_m, head) => `${head}${REDACTED}`
10429
10468
  },
10430
10469
  {
10431
10470
  // `export FOO_TOKEN=...` / `FOO_KEY=...` — SCREAMING_SNAKE env style
@@ -10449,19 +10488,20 @@ var REDACT_RULES = [
10449
10488
  // provider token prefixes: sk-ant-, sk-, ghp_/gho_/ghu_/ghs_/ghr_, github_pat_,
10450
10489
  // glpat-, xoxb-/xoxp-/xoxa-, AKIA/ASIA + 16 chars, AIza + 35 chars, JWT (eyJ… three segments)
10451
10490
  id: "token-prefix",
10452
- re: /\b(?:sk-ant-[A-Za-z0-9_-]{20,}|sk-[A-Za-z0-9_-]{20,}|gh[pousr]_[A-Za-z0-9]{30,}|github_pat_[A-Za-z0-9_]{22,}|glpat-[A-Za-z0-9_-]{20,}|xox[bap]-[A-Za-z0-9-]{10,}|(?:AKIA|ASIA)[A-Z0-9]{16}|AIza[A-Za-z0-9_-]{35}(?![A-Za-z0-9_-])|eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)(?![A-Za-z0-9_-])/g,
10491
+ re: /\b(?:sk-ant-[A-Za-z0-9_-]{20,}|sk-[A-Za-z0-9_-]{20,}|gh[pousr]_[A-Za-z0-9]{30,}|github_pat_[A-Za-z0-9_]{22,}|glpat-[A-Za-z0-9_-]{20,}|xox[bap]-[A-Za-z0-9-]{10,}|(?:AKIA|ASIA|AGPA|AIDA|AROA)[A-Z0-9]{16}|[sr]k_(?:live|test)_[A-Za-z0-9]{20,}|npm_[A-Za-z0-9]{36}|hf_[A-Za-z0-9]{30,}|AIza[A-Za-z0-9_-]{35}(?![A-Za-z0-9_-])|eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)(?![A-Za-z0-9_-])/g,
10453
10492
  replace: REDACTED
10454
10493
  },
10455
10494
  {
10456
10495
  // 40+ char opaque base64/hex run, only on a line that also has a secret-ish key word
10457
10496
  id: "long-run",
10458
- re: /\b[A-Za-z0-9+/]{40,}={0,2}(?![\w/])/g,
10497
+ re: /(?<![A-Za-z0-9+/])[A-Za-z0-9+/]{40,4096}={0,2}(?![\w/])/g,
10459
10498
  // a bare 40-hex git SHA stays; it is only redacted as the value of a secret key
10460
10499
  replace: (m) => /^[0-9a-f]{40}$/i.test(m) ? m : REDACTED
10461
10500
  }
10462
10501
  ];
10463
10502
  var LINE_RULES = REDACT_RULES.filter((r) => r.id !== "long-run");
10464
10503
  var LONG_RUN = REDACT_RULES.find((r) => r.id === "long-run");
10504
+ var LONG_RUN_MAX_LINE = 64 * 1024;
10465
10505
  var KEY_LINE = new RegExp(`(?:${KEY_WORDS})`, "i");
10466
10506
 
10467
10507
  // src/hooks/ts/lib/build-gate.ts
@@ -8177,6 +8177,7 @@ function defaultWorkersConfig() {
8177
8177
  cacheKeepaliveSecs: num(w.cacheKeepaliveSecs, 0),
8178
8178
  defaultMaxMinutes: num(w.defaultMaxMinutes, 60),
8179
8179
  waitAlarmMinutes: num(w.waitAlarmMinutes, 120),
8180
+ scanBudgetMs: num(w.scanBudgetMs, 5e3),
8180
8181
  stagger: {
8181
8182
  enabled: bool(stagger.enabled, true),
8182
8183
  localDefaultSec: num(stagger.localDefaultSec, 20),
@@ -8771,6 +8772,13 @@ function parseWorkersConfig(raw, yamlProviders = {}) {
8771
8772
  }
8772
8773
  waitAlarmMinutes = w.waitAlarmMinutes;
8773
8774
  }
8775
+ let scanBudgetMs = d.scanBudgetMs ?? 5e3;
8776
+ if (w.scanBudgetMs !== void 0) {
8777
+ if (typeof w.scanBudgetMs !== "number" || !Number.isInteger(w.scanBudgetMs) || w.scanBudgetMs < 1) {
8778
+ bad(".scanBudgetMs", "must be a positive integer (milliseconds)");
8779
+ }
8780
+ scanBudgetMs = w.scanBudgetMs;
8781
+ }
8774
8782
  const stagger = { ...d.stagger };
8775
8783
  if (w.stagger !== void 0) {
8776
8784
  if (typeof w.stagger !== "object" || w.stagger === null || Array.isArray(w.stagger)) {
@@ -8907,6 +8915,7 @@ function parseWorkersConfig(raw, yamlProviders = {}) {
8907
8915
  cacheKeepaliveSecs,
8908
8916
  defaultMaxMinutes,
8909
8917
  waitAlarmMinutes,
8918
+ scanBudgetMs,
8910
8919
  stagger,
8911
8920
  capacity,
8912
8921
  localIdle,
@@ -9247,20 +9256,50 @@ var PS_MAX_BUFFER = 64 * 1024 * 1024;
9247
9256
  var REDACTED = "[REDACTED]";
9248
9257
  var REDACTED_RE = String.raw`\[REDACTED\]`;
9249
9258
  var KEY_WORDS = "password|passwd|secret|token|api[_-]?key|credential|auth(?:orization)?|bearer";
9259
+ var PROSE = "is|are|was|were|be|to|of|in|on|for|and|or|the|a|an|that|this|it|not|out|here|there|so|as|at|by|with|if|when|which";
9250
9260
  var VAL = String.raw`(?:"[^"]*"|'[^']*'|[^\s'"]+)`;
9251
9261
  var REDACT_RULES = [
9252
9262
  {
9253
9263
  // `Authorization: Bearer xxx` / `Authorization: Basic xxx` — keep the scheme
9254
9264
  id: "authorization",
9255
- re: /(Authorization\s*:\s*)(Bearer|Basic)\s+(\S+)/gi,
9265
+ re: /(Authorization\s*:\s*)(Bearer|Basic)\s+([^\s'"]+)/gi,
9256
9266
  replace: (_m, head, scheme) => `${head}${scheme} ${REDACTED}`
9257
9267
  },
9268
+ {
9269
+ // `Cookie: a=b; c=d` — keep the cookie names, redact every value
9270
+ id: "cookie",
9271
+ re: /((?:Set-)?Cookie\s*:\s*)([^\n]+)/gi,
9272
+ replace: (_m, head, rest) => `${head}${rest.replace(/([^=;\s'"]+=)[^;'"]*/g, `$1${REDACTED}`)}`
9273
+ },
9258
9274
  {
9259
9275
  // `key=value`, `key: value`, `"key": "value"` — key carries a secret-ish word;
9260
- // the word must be a whole key segment, so `monkeys=` stays untouched
9276
+ // the word must be a whole key segment, so `monkeys=` stays untouched.
9277
+ // The separator may start with the key's closing quote (JSON); it is kept.
9261
9278
  id: "key-value",
9262
- re: new RegExp(String.raw`(?<![A-Za-z0-9])((?:[A-Za-z0-9]+[_-])?(?:${KEY_WORDS})(?![A-Za-z0-9])[A-Za-z0-9_-]*)(\s*[:=]\s*)(?!(?:Bearer|Basic) ${REDACTED_RE})(${VAL})`, "gi"),
9263
- replace: (_m, key, sep) => `${key}${sep}${REDACTED}`
9279
+ re: new RegExp(String.raw`(?<![A-Za-z0-9])((?:[A-Za-z0-9]+[_-])?(?:${KEY_WORDS})(?![A-Za-z0-9])[A-Za-z0-9_-]*)(["']?\s*[:=]\s*)(?!(?:Bearer|Basic) ${REDACTED_RE})(?!(?:${PROSE})\b)(${VAL})`, "gi"),
9280
+ replace: (m, key, sep, val) => {
9281
+ if (/[_-](?:count|length|len|size|limit|max|min|budget)$/i.test(key) && /^\d+$/.test(val)) return m;
9282
+ const q = sep[0] === '"' || sep[0] === "'" ? val[0] : "";
9283
+ return q && (q === '"' || q === "'") ? `${key}${sep}${q}${REDACTED}${q}` : `${key}${sep}${REDACTED}`;
9284
+ }
9285
+ },
9286
+ {
9287
+ // npmrc `//registry/:_authToken=xxx`
9288
+ id: "npm-auth-token",
9289
+ re: new RegExp(String.raw`(_authToken\s*=\s*)(${VAL})`, "g"),
9290
+ replace: (_m, head) => `${head}${REDACTED}`
9291
+ },
9292
+ {
9293
+ // `curl -u user:pass` / `--user user:pass` — keep the user
9294
+ id: "curl-user",
9295
+ re: /(\bcurl\b[^\n]{0,500}?\s(?:-u|--user)[\s=]+['"]?[^\s:'"]+:)([^\s'"]+)/g,
9296
+ replace: (_m, head) => `${head}${REDACTED}`
9297
+ },
9298
+ {
9299
+ // `mysql -phunter2` / `mysqldump -p'hunter2'` — attached password only
9300
+ id: "mysql-p",
9301
+ re: /(\bmysql(?:dump)?\b[^\n]{0,300}?\s-p)('[^']*'|"[^"]*"|[^\s'"-][^\s'"]*)/g,
9302
+ replace: (_m, head) => `${head}${REDACTED}`
9264
9303
  },
9265
9304
  {
9266
9305
  // `export FOO_TOKEN=...` / `FOO_KEY=...` — SCREAMING_SNAKE env style
@@ -9284,13 +9323,13 @@ var REDACT_RULES = [
9284
9323
  // provider token prefixes: sk-ant-, sk-, ghp_/gho_/ghu_/ghs_/ghr_, github_pat_,
9285
9324
  // glpat-, xoxb-/xoxp-/xoxa-, AKIA/ASIA + 16 chars, AIza + 35 chars, JWT (eyJ… three segments)
9286
9325
  id: "token-prefix",
9287
- re: /\b(?:sk-ant-[A-Za-z0-9_-]{20,}|sk-[A-Za-z0-9_-]{20,}|gh[pousr]_[A-Za-z0-9]{30,}|github_pat_[A-Za-z0-9_]{22,}|glpat-[A-Za-z0-9_-]{20,}|xox[bap]-[A-Za-z0-9-]{10,}|(?:AKIA|ASIA)[A-Z0-9]{16}|AIza[A-Za-z0-9_-]{35}(?![A-Za-z0-9_-])|eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)(?![A-Za-z0-9_-])/g,
9326
+ re: /\b(?:sk-ant-[A-Za-z0-9_-]{20,}|sk-[A-Za-z0-9_-]{20,}|gh[pousr]_[A-Za-z0-9]{30,}|github_pat_[A-Za-z0-9_]{22,}|glpat-[A-Za-z0-9_-]{20,}|xox[bap]-[A-Za-z0-9-]{10,}|(?:AKIA|ASIA|AGPA|AIDA|AROA)[A-Z0-9]{16}|[sr]k_(?:live|test)_[A-Za-z0-9]{20,}|npm_[A-Za-z0-9]{36}|hf_[A-Za-z0-9]{30,}|AIza[A-Za-z0-9_-]{35}(?![A-Za-z0-9_-])|eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)(?![A-Za-z0-9_-])/g,
9288
9327
  replace: REDACTED
9289
9328
  },
9290
9329
  {
9291
9330
  // 40+ char opaque base64/hex run, only on a line that also has a secret-ish key word
9292
9331
  id: "long-run",
9293
- re: /\b[A-Za-z0-9+/]{40,}={0,2}(?![\w/])/g,
9332
+ re: /(?<![A-Za-z0-9+/])[A-Za-z0-9+/]{40,4096}={0,2}(?![\w/])/g,
9294
9333
  // a bare 40-hex git SHA stays; it is only redacted as the value of a secret key
9295
9334
  replace: (m) => /^[0-9a-f]{40}$/i.test(m) ? m : REDACTED
9296
9335
  }
@@ -9298,11 +9337,12 @@ var REDACT_RULES = [
9298
9337
  var PEM_BLOCK = /-----BEGIN[^-\n]*PRIVATE KEY-----[\s\S]*?(?:-----END[^-\n]*PRIVATE KEY-----|$)/g;
9299
9338
  var LINE_RULES = REDACT_RULES.filter((r) => r.id !== "long-run");
9300
9339
  var LONG_RUN = REDACT_RULES.find((r) => r.id === "long-run");
9340
+ var LONG_RUN_MAX_LINE = 64 * 1024;
9301
9341
  var KEY_LINE = new RegExp(`(?:${KEY_WORDS})`, "i");
9302
9342
  function redactLine(line) {
9303
9343
  let out = line;
9304
9344
  for (const r of LINE_RULES) out = out.replace(r.re, r.replace);
9305
- if (KEY_LINE.test(out)) out = out.replace(LONG_RUN.re, LONG_RUN.replace);
9345
+ if (out.length <= LONG_RUN_MAX_LINE && KEY_LINE.test(out)) out = out.replace(LONG_RUN.re, LONG_RUN.replace);
9306
9346
  return out;
9307
9347
  }
9308
9348
  function redactSecrets(text) {