SIGN IN SIGN UP

fix: audit improvements — grace window, DRY errors, broader injection escape, new options

- noProgressTurnsBeforePause (default 2): no-progress counter now accumulates
  across consecutive low-output idle cycles before stopping; counter resets when
  a high-output turn is seen; managed entirely in the idle handler rather than
  split across message.updated
- maxRecentMessages (default 12): messages query limit promoted from hardcoded
  literal to a configurable normalizeOptions option
- applyPromptFailure: extracted shared helper used by both the response.error
  branch and the catch block, eliminating duplicated failure-tracking logic
- escapeGoalText: broadened from escaping only </goal_objective> to escaping
  all XML closing tags (replaceAll("</" → "<\/")) so user goal text cannot
  break any structural tag in buildContinueMessage or the system transform
- testInternals: added applyPromptFailure and logPluginError exports
- tests: 14 new cases covering buildLimitWarning, outputTokensForMessage,
  budgetWrapupNeeded, getSessionID, escapeGoalText (all structural tags),
  stopReason, logPluginError console fallback, applyPromptFailure,
  extractBlockedReason first-line edge case, normalizeOptions boundary inputs
  (0/negative/NaN/null/undefined, budgetWrapupRatio at 0 and 1), grace window
  integration (N-1 stalls allowed, counter reset on high-output turn)
- three existing no-progress tests updated with noProgressTurnsBeforePause: 1
  to preserve their one-strike semantics under the new default

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
W
Willy committed
fdfcb2135f1cec518ffe6b716502fd2e75df0e0b
Parent: 6401483