Skip to content

ci(ocr-review): make OCR infrastructure failures non-blocking (Fixes #2431) - #2438

Merged
acoliver merged 1 commit into
mainfrom
issue2431
Jul 8, 2026
Merged

ci(ocr-review): make OCR infrastructure failures non-blocking (Fixes #2431)#2438
acoliver merged 1 commit into
mainfrom
issue2431

Conversation

@acoliver

@acoliver acoliver commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

TLDR

Makes the OCR PR review workflow observational for OCR installation/config/provider/runtime/parse failures while preserving mandatory changed-test scope enforcement and inline OCR review comments.

Dive Deeper

This PR hardens .github/workflows/ocr-review.yml so OCR infrastructure failures no longer turn otherwise-valid PRs red. It now:

  • installs pinned OCR into a per-run RUNNER_TEMP prefix and adds the actual local node_modules/.bin path to GITHUB_PATH
  • disables OCR self-update checks for deterministic CI reviews
  • records OCR phase, exit code, stderr excerpts, infrastructure diagnostics, and policy diagnostics as artifacts
  • keeps changed test/spec files included in OCR scope and keeps deleted tests ignored via diff-filter=d
  • treats changed-test scope failures as policy failures that still fail the OCR check
  • treats OCR install/config/preview/review/parse failures as warnings with sticky PR diagnostics and a deduplicated ci/cd tracking issue path
  • preserves inline PR review comments and duplicate suppression
  • moves OCR run cancellation to job-level concurrency so ordinary or unauthorized issue comments cannot cancel real OCR runs
  • makes PR and infrastructure diagnostics redact configured OCR token/URL and common credential patterns

The new scripts/tests/ocr-review-workflow.test.js suite parses the workflow and exercises the workflow contract, sanitizer behavior, and failure classification rules.

Reviewer Test Plan

Reviewers can validate by checking that the workflow:

  1. Uses job-level OCR concurrency after the issue-comment command/authorization filter.
  2. Uses per-run RUNNER_TEMP OCR installation and OCR_NO_UPDATE.
  3. Keeps changed test/spec include rules and the deleted-file diff-filter guard.
  4. Fails only policy failures where changed tests are missing from or excluded by OCR preview.
  5. Posts warnings/sticky diagnostics and deduplicated ci/cd issue notifications for OCR infrastructure failures.
  6. Preserves GitHub inline review comment posting and duplicate suppression.

Local commands run:

npm run format -- .github/workflows/ocr-review.yml scripts/tests/ocr-review-workflow.test.js
npm run test:scripts -- scripts/tests/ocr-review-workflow.test.js
node scripts/lint.js --actionlint
git diff --check
npm run test:scripts
npm run typecheck
npm run lint:eslint-guard
npm run build

Open Code Review was run detached repeatedly with timeout 20 and the final actionable High/Medium findings on changed files were addressed. The final OCR run had only disputed/out-of-scope/low findings; OCR infrastructure failures intentionally remain non-blocking per issue scope.

Known local verification notes:

  • npm run test still fails in unrelated pre-existing areas: providers proactive-renewal tests and one CLI bun-launcher credential-proxy test. Recent main CI for LLxprt Code CI is green, so this appears local/environmental rather than caused by this workflow-only change.
  • npm run lint OOMs locally at the configured 8192MB heap before reporting lint violations. Targeted actionlint and eslint policy guard passed.
  • The prescribed smoke command fails locally with 404 model gpt-5.5 not found for the configured provider/model.

Testing Matrix

🍏 🪟 🐧
npm run ⚠️ focused workflow/script/typecheck/build passed; full test/lint have local pre-existing/environmental failures noted above
npx ✅ actionlint via node scripts/lint.js passed
Docker
Podman - -
Seatbelt - -

Linked issues / bugs

Fixes #2431

Summary by CodeRabbit

  • New Features

    • Enhanced the OCR review workflow with deterministic JS action settings and clearer, phase/exit-code based diagnostics.
    • Improved sticky summary reporting with richer status/diagnostic sections and canonical marker comment handling.
  • Bug Fixes

    • More resilient OCR execution and “Post OCR results” behavior: uses diagnostic markers, strengthens sanitization/redaction, and more accurately classifies policy vs infrastructure failures.
    • Reduced duplicate marker comments while reliably posting sanitized results.
  • Tests

    • Added end-to-end workflow tests and sanitizer/notify verification to validate concurrency, gating logic, artifact handling, and secret redaction.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The OCR review workflow now records phase, policy, and infrastructure diagnostics instead of hard-failing on OCR setup, preview, parse, or posting issues. Sticky summary posting and the infrastructure notification job were rewritten to sanitize output, deduplicate comments, and use the new artifacts. New test helpers and Vitest coverage validate the workflow and sanitization behavior.

Changes

OCR workflow refactor and diagnostics

Layer / File(s) Summary
Workflow controls and failure markers
.github/workflows/ocr-review.yml
Adds permissions, deterministic env settings, concurrency, a policy failure output, and phase/failure marker files for OCR setup and validation steps.
Post results parsing and sticky summary
.github/workflows/ocr-review.yml
Reads diagnostic files, redacts secrets, classifies parse failures, and updates or creates the sticky summary comment with deduplication.
Infrastructure notification job
.github/workflows/ocr-review.yml
Downloads updated artifacts, sanitizes diagnostics, skips policy failures, and uses gh CLI retry logic to manage the infrastructure issue.
Workflow test helpers
scripts/tests/ocr-review-workflow-helpers.js
Adds repository file access, workflow step lookup, credential redaction helpers, function-source extraction, and sanitizer runners for post and notify scripts.
Workflow validation tests
scripts/tests/ocr-review-workflow.test.js
Validates workflow concurrency, command predicates, environment defaults, install and validation behavior, changed-test scoping, post-results sanitization, policy and infrastructure classification, and notification issue behavior.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

Possibly related PRs

Suggested labels: ci/cd

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: making OCR infrastructure failures non-blocking.
Description check ✅ Passed The PR description matches the required template sections and includes TLDR, deeper details, test plan, matrix, and linked issue info.
Linked Issues check ✅ Passed The changes align with #2431 by keeping OCR review non-blocking, preserving inline comments, and retaining changed-test scope rules.
Out of Scope Changes check ✅ Passed The added workflow logic and tests stay within the OCR review hardening scope and do not introduce obvious unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue2431

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the maintainer:e2e:ok Trusted contributor; maintainer-approved E2E run label Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

LLxprt PR Review – PR #2438

Issue Alignment

The PR implements the requested behavior from #2431: OCR infrastructure failures are now non-blocking, while changed-test scope failures remain policy failures that fail the check. It preserves inline review comments and the sticky summary. Evidence: job outputs classify infrastructure vs policy failures; changed-test preview failures write ocr-policy-failure.txt and still exit 1; inline posting/deduplication logic is preserved.

Side Effects

  • New notify-ocr-infrastructure-failure job creates/comments on a ci/cd-labeled issue, which adds repo noise but is scoped to actual OCR infrastructure failures.
  • Diagnostic artifacts now include phase/infra/policy files and are redacted before upload; residual leak risk remains if redaction regexes miss novel secret formats.
  • Workflow timeout added (45m); unlikely to affect PRs that previously completed quickly.

Code Quality

  • Correctness: install/validate/preview/review steps short-circuit after earlier failures via ocr-exit-code.txt; parse failures are marked as infrastructure only after zero-exit OCR.
  • Error handling: every OCR phase has explicit failure paths with warnings and artifact records.
  • Maintainability: large inline bash/JS blocks are harder to maintain; splitting into composite actions or reusable scripts would reduce review surface.
  • Minor inconsistency: changed-test-excluded path fails the job (exit 1) while other infra failures exit 0; this is intentional policy behavior but worth documenting as deliberate.

Tests and Coverage

  • Added 794-line test file plus helper library; tests assert workflow YAML structure, concurrency placement, install path, deterministic env, redaction behavior for both post and notify paths, and artifact handling.
  • Coverage impact: increase — new automated tests cover previously untested workflow behavior and secret-redaction edge cases.

Verdict

Ready — PR resolves #2431, includes meaningful automated tests, and preserves required policy enforcement. Minor follow-ups: consider extracting large workflow scripts to reusable actions for maintainability, and validate redaction coverage against actual provider stderr samples.

Comment thread .github/workflows/ocr-review.yml Outdated
needs: code-review
# Skipped/cancelled superseded OCR runs should not create infrastructure issues;
# completed green runs still check artifacts because OCR runtime failures are non-blocking.
if: ${{ !cancelled() && needs.code-review.result == 'success' }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The notify-ocr-infrastructure-failure job condition only triggers when needs.code-review.result == 'success'. Since all infrastructure failures in the code-review job now use exit 0 (soft failure), the job reports success and the notify job fires correctly for OCR-level infrastructure failures. However, if the code-review job fails for an unexpected reason (e.g., checkout failure, pr-context script error, uncaught exception in the Post step that isn't wrapped in try-catch), the job result will be failure and the notify job will be skipped entirely — even if an infrastructure failure was recorded in artifacts before the unexpected failure occurred. Consider also triggering on failure (e.g., if: ${{ !cancelled() && (needs.code-review.result == 'success' || needs.code-review.result == 'failure') }}), or at minimum documenting this gap so maintainers know unexpected workflow failures won't produce infrastructure issue notifications.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 29fcf74: the notify job now also runs when code-review reports failure, so unexpected post-artifact failures can still create the deduplicated infrastructure diagnostic issue.

ocr-phase.txt
ocr-infrastructure-failure.txt
ocr-policy-failure.txt
if-no-files-found: warn

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing if-no-files-found from error to warn means that if all diagnostic files are missing (e.g., because the Initialize OCR artifact files step didn't run due to an earlier catastrophic failure), the upload step will only emit a warning and the workflow will continue. The notify-ocr-infrastructure-failure job then downloads an empty or non-existent artifact directory and silently skips notification (if [ -d ocr-review-output ] fails → returns 0). This could mask real infrastructure failures where artifacts were never created. Consider keeping if-no-files-found: error for the critical diagnostic files (ocr-exit-code.txt, ocr-phase.txt, ocr-infrastructure-failure.txt) or adding a post-download validation step in the notify job that fails loudly when expected artifacts are missing.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 29fcf74: the notify job now treats missing artifacts after a failed code-review job, or missing critical diagnostic files after a failed code-review job, as infrastructure diagnostics instead of silently skipping notification.

it('notifies a deduplicated ci/cd issue for OCR infrastructure errors', () => {
const notifyJob = workflow.jobs?.['notify-ocr-infrastructure-failure'];
expect(notifyJob?.needs).toBe('code-review');
expect(notifyJob?.['timeout-minutes']).toBe(5);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code-review job does not specify timeout-minutes. GitHub Actions defaults to 360 minutes (6 hours) when this is omitted. For a code review job that should complete in a few minutes, a 6-hour ceiling is excessive — if the OCR CLI or a workflow step hangs (e.g., network stall waiting on the LLM endpoint, a stuck npm install, or a deadlock in the github-script step), the job will consume runner minutes for hours before timing out. The sibling notify-ocr-infrastructure-failure job correctly sets timeout-minutes: 5. Consider adding a reasonable timeout-minutes (e.g., 15–30) to the code-review job as well.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 29fcf74: code-review now has a bounded timeout-minutes value, and the workflow contract test asserts it.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

OpenCodeReview — PR #2438

  • Reviewed head SHA: c910fcf10a045f14e78483e60d0184790aef8e49
  • Merge base: 5fcd1f0747c1702fb07397de0222dd22adabddcf
  • OCR version: open-code-review v1.6.1 (034d512) linux/amd64 built at: 2026-06-25T12:11:53Z https://github.com/alibaba/open-code-review
  • ✅ No findings.
  • Artifacts: download the ocr-review-output artifact from this workflow run for the raw JSON and stderr.

'script should define REDACTION constant',
).toBeTruthy();
const source = [
`const REDACTION = '${redactionMatch?.[1] ?? ''}';`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optional chaining ?. is redundant here. The preceding expect(redactionMatch).toBeTruthy() assertion guarantees redactionMatch is truthy, so redactionMatch[1] can be accessed directly. Consider using redactionMatch[1] ?? '' for clarity.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 29fcf74: removed the redundant optional chaining after the regex match assertion.

Comment thread .github/workflows/ocr-review.yml Outdated
echo "::warning::Failed to create OCR infrastructure issue body file."
return 1
fi
trap 'rm -f "$body_file"' EXIT RETURN

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trap 'rm -f "$body_file"' EXIT RETURN will fire the RETURN trap every time ANY shell function returns (not just notify_ocr_infrastructure_failure). When retry_gh returns at line 1070 (recheck search) or inside create_infrastructure_issue at line 1040, the RETURN trap fires and deletes $body_file before it can be used at line 1081 (gh issue comment --body-file "$body_file") or line 1084 (create_infrastructure_issue "$body_file"). This means the body file will be missing when it's needed most — during the fallback paths after the initial search.

Suggestion: Remove RETURN from the trap and keep only EXIT, or move the trap to only cover the end of the function scope by setting it after all uses of $body_file are complete. Alternatively, set the trap without RETURN and add an explicit rm -f "$body_file" before each return.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 29fcf74: removed RETURN from the trap so nested helper returns cannot delete the issue body file before gh issue comment or create uses it.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 58.4% 58.4% 59.24% 82.05%
Core 78.53% 78.53% 75.54% 83.86%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |    58.4 |    82.05 |   59.24 |    58.4 |                   
 src               |   78.66 |    71.08 |   91.13 |   78.66 |                   
  cli.tsx          |   75.73 |    68.42 |     100 |   75.73 | ...18-220,229-233 
  ...tBootstrap.ts |   96.55 |    85.71 |     100 |   96.55 | 60                
  cliBootstrap.tsx |   65.57 |    63.79 |   89.65 |   65.57 | ...60,863-867,872 
  ...nBootstrap.ts |   71.89 |    63.63 |   83.33 |   71.89 | ...55-265,270-271 
  ...st-helpers.ts |       0 |        0 |       0 |       0 | 1-50              
  ...ractiveCli.ts |   87.86 |     67.5 |      90 |   87.86 | ...22-429,454-456 
  ...liCommands.ts |   97.26 |       70 |     100 |   97.26 | 40-41             
  ...CliSupport.ts |   91.46 |    80.76 |     100 |   91.46 | ...43,361-362,443 
  ...activeAuth.ts |   93.15 |    88.88 |     100 |   93.15 | 44,47-50          
 src/auth          |   98.07 |    81.25 |     100 |   98.07 |                   
  ...gs-adapter.ts |   98.07 |    81.25 |     100 |   98.07 | 76                
 src/commands      |   78.35 |      100 |   44.44 |   78.35 |                   
  extensions.tsx   |   55.88 |      100 |       0 |   55.88 | 25-38,42          
  hooks.ts         |   61.53 |      100 |       0 |   61.53 | 14-17,20          
  mcp.ts           |   94.11 |      100 |      50 |   94.11 | 26                
  skills.tsx       |     100 |      100 |     100 |     100 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
 ...nds/extensions |   73.98 |    92.93 |   67.18 |   73.98 |                   
  config.ts        |   93.93 |    91.83 |     100 |   93.93 | ...72-173,204-209 
  disable.ts       |     100 |      100 |     100 |     100 |                   
  enable.ts        |     100 |      100 |     100 |     100 |                   
  install.ts       |   80.48 |    76.92 |    87.5 |   80.48 | ...63,199,202-209 
  link.ts          |   64.81 |    83.33 |      25 |   64.81 | 31,54-65,67-72    
  list.ts          |      90 |      100 |   33.33 |      90 | 35-37             
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   72.13 |      100 |      70 |   72.13 | 32-80,218-222,225 
  uninstall.ts     |   78.43 |      100 |   66.66 |   78.43 | 54-59,62-66       
  update.ts        |   10.06 |      100 |       0 |   10.06 | ...73-192,194-199 
  utils.ts         |   13.33 |      100 |       0 |   13.33 | 29-60             
  validate.ts      |   89.36 |     87.5 |      75 |   89.36 | 50-53,60,112-116  
 .../hooks/scripts |       0 |        0 |       0 |       0 |                   
  on-start.js      |       0 |        0 |       0 |       0 | 1-8               
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.js       |       0 |        0 |       0 |       0 | 1-60              
 ...commands/hooks |    7.18 |      100 |       0 |    7.18 |                   
  migrate.ts       |    7.18 |      100 |       0 |    7.18 | ...00-210,212-214 
 src/commands/mcp  |   96.95 |    86.15 |   94.44 |   96.95 |                   
  add.ts           |   99.56 |    93.33 |     100 |   99.56 | 142               
  list.ts          |   90.51 |    82.14 |      80 |   90.51 | ...13-115,148-150 
  remove.ts        |     100 |    71.42 |     100 |     100 | 21-25             
 ...ommands/skills |   60.98 |     92.3 |   31.25 |   60.98 |                   
  disable.ts       |      54 |      100 |   33.33 |      54 | 40-52,54-63       
  enable.ts        |   72.22 |      100 |   33.33 |   72.22 | 33-37,39-43       
  install.ts       |   42.69 |      100 |      25 |   42.69 | ...71-100,102-109 
  list.ts          |   84.93 |       80 |   33.33 |   84.93 | ...9,92-96,98-100 
  uninstall.ts     |   57.89 |      100 |   33.33 |   57.89 | 47-64,66-71       
 src/config        |   87.44 |    85.21 |   90.08 |   87.44 |                   
  ...deResolver.ts |   94.54 |    95.45 |     100 |   94.54 | 50-52             
  auth.ts          |   84.21 |    82.35 |     100 |   84.21 | 17-18,21-22,52-53 
  cliArgParser.ts  |   93.36 |    91.11 |     100 |   93.36 | ...22-223,286-289 
  config.ts        |   97.44 |       90 |     100 |   97.44 | 212-213,227-231   
  configBuilder.ts |   95.86 |    95.45 |      90 |   95.86 | ...21-222,263-264 
  ...mentLoader.ts |   83.47 |    53.84 |     100 |   83.47 | ...33-135,143-146 
  extension.ts     |   74.85 |    88.38 |   79.06 |   74.85 | ...28-929,932-933 
  ...iveContext.ts |   93.75 |    91.66 |     100 |   93.75 | 79,81,87-92,232   
  ...iateConfig.ts |   97.45 |      100 |     100 |   97.45 | 155-157           
  keyBindings.ts   |     100 |      100 |     100 |     100 |                   
  ...rverConfig.ts |   83.33 |    94.44 |     100 |   83.33 | 23-39             
  pathMigration.ts |   84.27 |    80.18 |     100 |   84.27 | ...97,703,711-714 
  paths.ts         |     100 |      100 |     100 |     100 |                   
  policy.ts        |   80.76 |      100 |      50 |   80.76 | 45-49             
  ...figRuntime.ts |   88.51 |    87.35 |     100 |   88.51 | ...18-525,536-539 
  ...Ephemerals.ts |   70.27 |    66.66 |      75 |   70.27 | 31-32,44-52       
  ...eBootstrap.ts |   90.42 |    88.13 |     100 |   90.42 | ...44-846,855-856 
  ...Resolution.ts |   78.66 |    76.74 |     100 |   78.66 | ...87-290,303-311 
  ...pplication.ts |   92.48 |       80 |     100 |   92.48 | ...,95-96,113,183 
  ...elResolver.ts |    93.1 |    81.25 |     100 |    93.1 | 41,43-44,80       
  sandboxConfig.ts |   69.81 |    51.48 |   88.46 |   69.81 | ...80-581,593-594 
  ...oxProfiles.ts |    8.53 |      100 |       0 |    8.53 | 47-48,51-129      
  settingPaths.ts  |     100 |      100 |     100 |     100 |                   
  ...validation.ts |   86.99 |    80.62 |     100 |   86.99 | ...02,404,406,408 
  settings.ts      |   83.37 |    85.98 |   69.23 |   83.37 | ...75-476,523-524 
  ...ingsLegacy.ts |    70.9 |    81.81 |     100 |    70.9 | 48-52,56-67       
  ...ingsLoader.ts |   94.11 |    81.39 |     100 |   94.11 | ...78,108-109,137 
  settingsMerge.ts |   99.51 |    95.65 |     100 |   99.51 | 128-129           
  ...Migrations.ts |   95.67 |    91.66 |     100 |   95.67 | 22-24,48-49,55-56 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...Governance.ts |   95.16 |    91.17 |     100 |   95.16 | 47-48,129-132     
  ...tedFolders.ts |   95.58 |       96 |     100 |   95.58 | 93,120-126        
  welcomeConfig.ts |   22.41 |      100 |       0 |   22.41 | ...71,74-79,82-83 
  yargsOptions.ts  |   98.73 |    96.77 |    87.5 |   98.73 | 144,153-156       
 ...fig/extensions |   76.28 |     84.5 |   87.38 |   76.28 |                   
  consent.ts       |   88.03 |    85.71 |     100 |   88.03 | ...76-377,380-381 
  ...ionConsent.ts |   87.38 |    76.66 |     100 |   87.38 | ...,64-67,113-116 
  ...Enablement.ts |   94.02 |       96 |     100 |   94.02 | ...12-218,281-283 
  ...sionLoader.ts |   91.92 |    88.46 |     100 |   91.92 | ...20-221,229-233 
  ...onSettings.ts |     100 |      100 |     100 |     100 |                   
  github.ts        |   61.73 |    81.73 |      68 |   61.73 | ...49-650,660-663 
  hookSchema.ts    |     100 |      100 |     100 |     100 |                   
  ...ntegration.ts |   55.31 |    84.78 |      50 |   55.31 | ...61,402,426-427 
  ...ingsPrompt.ts |      73 |    94.73 |      80 |      73 | 92-121            
  ...ngsStorage.ts |   85.57 |    77.19 |     100 |   85.57 | ...05-306,324-327 
  update.ts        |   69.52 |    52.94 |   85.71 |   69.52 | ...73-201,218-226 
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   95.55 |       90 |     100 |   95.55 | 33-34             
 ...ettings-schema |   99.78 |       60 |     100 |   99.78 |                   
  schema-core.ts   |     100 |      100 |     100 |     100 |                   
  ...extensions.ts |     100 |      100 |     100 |     100 |                   
  ...a-security.ts |   99.44 |       50 |     100 |   99.44 | 16-17             
  schema-tail.ts   |   99.52 |       50 |     100 |   99.52 | 13-14             
  schema-ui.ts     |     100 |      100 |     100 |     100 |                   
  schema.ts        |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/constants     |     100 |      100 |     100 |     100 |                   
  historyLimits.ts |     100 |      100 |     100 |     100 |                   
 src/extensions    |   64.92 |    61.81 |      75 |   64.92 |                   
  ...utoUpdater.ts |   64.92 |    61.81 |      75 |   64.92 | ...69-470,479,481 
 src/generated     |     100 |      100 |     100 |     100 |                   
  git-commit.ts    |     100 |      100 |     100 |     100 |                   
 ...egration-tests |   71.66 |    83.33 |   85.71 |   71.66 |                   
  ...st-helpers.ts |       0 |        0 |       0 |       0 | 1-79              
  test-utils.ts    |   91.97 |     86.2 |    92.3 |   91.97 | ...45,263-264,274 
 src/launcher      |   93.33 |    86.48 |   88.09 |   93.33 |                   
  ...y-resolver.ts |   91.39 |    92.85 |   85.71 |   91.39 | 121-128           
  bun-launcher.ts  |   96.31 |    85.96 |   88.88 |   96.31 | 35-43             
  ...h-resolver.ts |   91.37 |    84.12 |   88.23 |   91.37 | ...26-228,251-252 
 ...viders/logging |   89.31 |    90.24 |   69.23 |   89.31 |                   
  ...rvice-impl.ts |   44.44 |        0 |       0 |   44.44 | 21-22,25-30,36-37 
  git-stats.ts     |   96.46 |     92.5 |     100 |   96.46 | 154-155,195-196   
 src/runtime       |   53.59 |    64.28 |   56.52 |   53.59 |                   
  ...chedClient.ts |    3.37 |      100 |       0 |    3.37 | 29-68,71-123      
  ...lScheduler.ts |   71.83 |    64.28 |   72.22 |   71.83 | ...64-386,402-404 
 src/services      |   85.91 |       85 |   94.87 |   85.91 |                   
  ...mandLoader.ts |   80.74 |    73.33 |      80 |   80.74 | ...07-121,165-183 
  ...andService.ts |     100 |      100 |     100 |     100 |                   
  ...mandLoader.ts |   91.91 |    86.27 |     100 |   91.91 | ...11-216,303-310 
  ...omptLoader.ts |    67.7 |    68.96 |     100 |    67.7 | ...73,179-185,200 
  ...tArgParser.ts |     100 |    94.28 |     100 |     100 | 42,72             
  performResume.ts |   89.11 |    89.18 |     100 |   89.11 | ...59-262,268-269 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...mpt-processors |      98 |     93.1 |     100 |      98 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.88 |    92.72 |     100 |   97.88 | 88-89,273-274     
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...o-continuation |   86.84 |    84.09 |   94.73 |   86.84 |                   
  ...ionService.ts |   86.84 |    84.09 |   94.73 |   86.84 | ...16,583,609-610 
 src/session       |   80.52 |    80.68 |   84.61 |   80.52 |                   
  debugLog.ts      |      60 |       50 |     100 |      60 | 12-16             
  ...rReporting.ts |   72.91 |    66.66 |     100 |   72.91 | 17-19,22-30,37-38 
  ...ractiveUI.tsx |   84.11 |      100 |   66.66 |   84.11 | ...50-252,262-271 
  ...iveSession.ts |   77.05 |    57.89 |      75 |   77.05 | ...40-250,264-281 
  ...tListeners.ts |     100 |      100 |     100 |     100 |                   
  ...alHandlers.ts |   81.37 |    88.57 |      90 |   81.37 | ...,94-97,112-113 
  ...nalCleanup.ts |   85.71 |       50 |     100 |   85.71 | 21                
 src/test-utils    |   76.72 |    82.25 |   37.68 |   76.72 |                   
  assertions.ts    |   76.47 |       50 |     100 |   76.47 | ...40,49-50,59-60 
  async.ts         |       0 |        0 |       0 |       0 | 1-34              
  ...eExtension.ts |     100 |      100 |     100 |     100 |                   
  ...omMatchers.ts |   22.22 |      100 |       0 |   22.22 | 19-49             
  inkFrame.ts      |      65 |    66.66 |   66.66 |      65 | 31-32,40-44       
  mockAgent.ts     |     100 |      100 |      50 |     100 |                   
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  regex.ts         |     100 |      100 |     100 |     100 |                   
  render.tsx       |    93.9 |    96.66 |   24.48 |    93.9 | ...54-159,262-263 
  ...e-testing.tsx |       0 |        0 |       0 |       0 | 1-56              
  ...iderConfig.ts |       0 |        0 |       0 |       0 | 1-19              
 src/ui            |   48.54 |    94.79 |    28.5 |   48.54 |                   
  App.tsx          |   35.84 |      100 |       0 |   35.84 | 70-101,107-114    
  AppContainer.tsx |     100 |      100 |     100 |     100 |                   
  ...erRuntime.tsx |   15.75 |      100 |   16.66 |   15.75 | 72-412            
  ...tionNudge.tsx |       8 |      100 |       0 |       8 | 29-104            
  cliUiRuntime.ts  |   94.64 |    96.96 |   26.01 |   94.64 | ...44,700,717,720 
  colors.ts        |   37.14 |      100 |   20.33 |   37.14 | ...03-304,306-307 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  debug.ts         |     100 |      100 |     100 |     100 |                   
  ...derOptions.ts |     100 |      100 |     100 |     100 |                   
  keyMatchers.ts   |   88.63 |       84 |     100 |   88.63 | 18,20-21,28-29    
  ...ntsEnabled.ts |     100 |      100 |     100 |     100 |                   
  ...submission.ts |     100 |      100 |     100 |     100 |                   
  ...lobalState.ts |     100 |      100 |     100 |     100 |                   
  ...tic-colors.ts |   78.94 |      100 |      60 |   78.94 | 15-16,24-25       
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/commands   |   72.02 |     77.4 |    78.5 |   72.02 |                   
  aboutCommand.ts  |   82.84 |    51.51 |   91.66 |   82.84 | ...92-193,195-196 
  authCommand.ts   |    58.9 |    79.54 |   81.25 |    58.9 | ...91-641,653-656 
  ...urlCommand.ts |      68 |       75 |     100 |      68 | 47-62             
  bugCommand.ts    |   71.23 |    30.76 |     100 |   71.23 | ...99-110,145-153 
  chatCommand.ts   |   70.16 |    74.62 |   66.66 |   70.16 | ...42-543,591-602 
  clearCommand.ts  |   86.44 |    85.71 |     100 |   86.44 | 81-88             
  ...essCommand.ts |   93.47 |    86.04 |     100 |   93.47 | ...,67-71,111-112 
  ...nueCommand.ts |     100 |      100 |     100 |     100 |                   
  copyCommand.ts   |     100 |      100 |     100 |     100 |                   
  debugCommands.ts |   13.81 |      100 |       0 |   13.81 | ...52,459,466,473 
  ...st-helpers.ts |   89.81 |     91.3 |   54.54 |   89.81 | ...4,96-97,99-100 
  ...icsCommand.ts |   78.27 |    52.63 |   94.44 |   78.27 | ...24-527,542-547 
  ...ticsTokens.ts |   92.05 |    90.24 |     100 |   92.05 | ...,63-68,103-104 
  ...ryCommand.tsx |    89.5 |    84.84 |     100 |    89.5 | ...26-134,201-209 
  docsCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...extCommand.ts |   96.22 |    89.65 |     100 |   96.22 | 220-225           
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  ...onsCommand.ts |   41.27 |    88.09 |    62.5 |   41.27 | ...23-380,390-538 
  ...ionSection.ts |   83.33 |    93.33 |     100 |   83.33 | 28-34             
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   79.49 |    80.82 |   92.85 |   79.49 | ...02,511-512,626 
  ideCommand.ts    |   69.87 |    74.28 |   69.23 |   69.87 | ...36-237,240-255 
  initCommand.ts   |   80.76 |    71.42 |   66.66 |   80.76 | 37-41,43-90       
  keyCommand.ts    |   90.05 |    80.76 |     100 |   90.05 | ...97,420-421,520 
  ...ileCommand.ts |    10.9 |      100 |       0 |    10.9 | 22-46,53-141      
  ...ingCommand.ts |   10.27 |      100 |       0 |   10.27 | ...19-572,589-601 
  logoutCommand.ts |   56.52 |    66.66 |      75 |   56.52 | ...-84,97-103,108 
  lspCommand.ts    |    93.8 |    85.36 |     100 |    93.8 | 43,95-100         
  mcpAuth.ts       |   90.43 |       80 |   66.66 |   90.43 | 32-41,86-87       
  mcpCommand.ts    |   96.25 |    87.87 |     100 |   96.25 | 87-92             
  mcpDisplay.ts    |   84.23 |    81.73 |   93.75 |   84.23 | ...49-450,487-488 
  memoryCommand.ts |   87.45 |    75.47 |     100 |   87.45 | ...46,234-248,297 
  modelCommand.ts  |   98.92 |    93.02 |     100 |   98.92 | 120               
  mouseCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...onsCommand.ts |    93.9 |    88.88 |     100 |    93.9 | 58-62             
  ...iesCommand.ts |   97.79 |    87.75 |     100 |   97.79 | 24,34-35          
  ...acyCommand.ts |   61.53 |      100 |       0 |   61.53 | 22-26             
  ...ileCommand.ts |   59.14 |    55.55 |   63.63 |   59.14 | ...90-531,552-568 
  profileLoad.ts   |   52.08 |       60 |    87.5 |   52.08 | ...45,172,183-187 
  ...adBalancer.ts |   81.36 |    84.61 |     100 |   81.36 | ...20-321,347-352 
  ...ileSchemas.ts |   67.11 |    81.81 |     100 |   67.11 | ...18-230,262-267 
  ...derCommand.ts |   54.18 |     32.5 |      75 |   54.18 | ...43-344,353-358 
  quitCommand.ts   |   36.66 |      100 |       0 |   36.66 | 17-36             
  ...oreCommand.ts |   90.27 |    83.33 |     100 |   90.27 | ...70-175,208-213 
  setCommand.ts    |   86.32 |    84.28 |     100 |   86.32 | ...91-200,217-222 
  ...mandSchema.ts |   71.57 |    81.81 |   84.61 |   71.57 | ...05,232-240,295 
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  setupCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   90.47 |    82.85 |     100 |   90.47 | ...13-216,223-227 
  skillsCommand.ts |   82.78 |       75 |     100 |   82.78 | ...91-292,305-306 
  statsCommand.ts  |   57.25 |    86.66 |   58.33 |   57.25 | ...04-216,234-235 
  statsQuota.ts    |   79.47 |       75 |   83.33 |   79.47 | ...15-316,349-353 
  ...entCommand.ts |   76.72 |    69.73 |   81.81 |   76.72 | ...09-615,626-632 
  tasksCommand.ts  |   75.83 |       75 |     100 |   75.83 | ...51-156,202-210 
  ...tupCommand.ts |     100 |      100 |     100 |     100 |                   
  themeCommand.ts  |     100 |      100 |     100 |     100 |                   
  todoCommand.ts   |   82.24 |    72.28 |     100 |   82.24 | ...48-460,468-472 
  ...Formatters.ts |   48.93 |    71.42 |   33.33 |   48.93 | ...5,70-86,92-113 
  ...Operations.ts |   85.93 |    77.77 |   95.23 |   85.93 | ...71-372,410-424 
  ...matCommand.ts |   26.66 |      100 |       0 |   26.66 | 33-92             
  ...keyCommand.ts |   98.88 |     92.3 |     100 |   98.88 | 34                
  ...ileCommand.ts |    99.1 |    94.11 |     100 |    99.1 | 36                
  toolsCommand.ts  |   86.71 |    73.23 |     100 |   86.71 | ...64,295,326-327 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ileCommand.ts |   27.77 |        0 |       0 |   27.77 | 11-23             
  vimCommand.ts    |   44.44 |      100 |       0 |   44.44 | 15-25             
 ...ommands/schema |   96.06 |    92.54 |   94.11 |   96.06 |                   
  index.ts         |   95.84 |    91.58 |     100 |   95.84 | ...07-211,222-223 
  schemaHelpers.ts |   97.02 |    96.22 |     100 |   97.02 | 67-68,115-117     
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/ui/components |   12.22 |    38.81 |     7.7 |   12.22 |                   
  AboutBox.tsx     |   12.19 |      100 |       0 |   12.19 | ...,76-98,102-130 
  AnsiOutput.tsx   |    8.33 |      100 |       0 |    8.33 | 25-90             
  AppHeader.tsx    |   21.87 |      100 |       0 |   21.87 | 27-57             
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  AuthDialog.tsx   |    5.22 |      100 |       0 |    5.22 | ...27-232,235-314 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-63              
  ...Indicator.tsx |   15.15 |      100 |       0 |   15.15 | 17-47             
  ...firmation.tsx |   15.38 |      100 |       0 |   15.38 | 59-134,143-208    
  ...tsDisplay.tsx |   10.37 |      100 |       0 |   10.37 | ...70-110,114-168 
  CliSpinner.tsx   |       0 |        0 |       0 |       0 | 1-22              
  Composer.tsx     |     8.1 |      100 |       0 |     8.1 | 17-32,45-100      
  ...entPrompt.tsx |   18.75 |      100 |       0 |   18.75 | 21-51             
  ...ryDisplay.tsx |   21.05 |      100 |       0 |   21.05 | 17-35             
  ...ryDisplay.tsx |    4.65 |      100 |       0 |    4.65 | 30-108,111-175    
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-37              
  ...gProfiler.tsx |   16.86 |      100 |       0 |   16.86 | ...73-118,122-222 
  ...esDisplay.tsx |   10.52 |      100 |       0 |   10.52 | 24-82             
  ...ogManager.tsx |    5.69 |      100 |       0 |    5.69 | 71-800,804-828    
  ...ngsDialog.tsx |   12.56 |      100 |       0 |   12.56 | ...48-172,176-247 
  ...rBoundary.tsx |   10.07 |        0 |       0 |   10.07 | ...26-171,189-204 
  ...ustDialog.tsx |   16.34 |      100 |       0 |   16.34 | ...2,70-81,84-143 
  Footer.tsx       |    12.6 |        0 |       0 |    12.6 | ...49-653,657-726 
  Header.tsx       |    17.5 |      100 |       0 |    17.5 | 22-62             
  Help.tsx         |    6.84 |      100 |       0 |    6.84 | ...87-190,194-206 
  ...emDisplay.tsx |   12.01 |      100 |       0 |   12.01 | 54-238,241-279    
  ...usDisplay.tsx |       0 |        0 |       0 |       0 | 1-47              
  InputPrompt.tsx  |     100 |       75 |     100 |     100 | 45                
  ...tsDisplay.tsx |    4.36 |      100 |       0 |    4.36 | ...32-226,229-292 
  ...utManager.tsx |       0 |        0 |       0 |       0 | 1-99              
  ...ileDialog.tsx |    8.33 |      100 |       0 |    8.33 | ...8,72-81,85-152 
  ...Indicator.tsx |   14.92 |      100 |       0 |   14.92 | 21-25,35-97       
  ...ingDialog.tsx |    6.68 |      100 |       0 |    6.68 | ...66-383,387-436 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |    3.82 |      100 |       0 |    3.82 | ...79-752,756-842 
  ...tsDisplay.tsx |    3.82 |      100 |       0 |    3.82 | 32-205,208-259    
  ...fications.tsx |   16.66 |      100 |       0 |   16.66 | ...08-139,142-177 
  ...odeDialog.tsx |     7.4 |      100 |       0 |     7.4 | 32-141            
  ...ustDialog.tsx |    5.53 |      100 |       0 |    5.53 | ...36-273,278-313 
  PrepareLabel.tsx |   13.33 |      100 |       0 |   13.33 | 20-48             
  ...ailDialog.tsx |   11.36 |      100 |       0 |   11.36 | ...93-499,503-576 
  ...ineEditor.tsx |    4.34 |      100 |       0 |    4.34 | ...66-552,555-630 
  ...istDialog.tsx |     4.5 |      100 |       0 |     4.5 | ...93-530,533-619 
  ...derDialog.tsx |    2.58 |      100 |       0 |    2.58 | 58-408,411-426    
  ...Indicator.tsx |       0 |        0 |       0 |       0 | 1-21              
  ...ngSpinner.tsx |   33.33 |      100 |       0 |   33.33 | 29-48             
  ...eKeyInput.tsx |       0 |        0 |       0 |       0 | 1-149             
  ...serDialog.tsx |    9.56 |      100 |       0 |    9.56 | ...52-603,611-670 
  ...ryDisplay.tsx |      50 |      100 |       0 |      50 | 15-17             
  ...ngsDialog.tsx |    9.75 |      100 |       0 |    9.75 | 29-105            
  ...putPrompt.tsx |   14.28 |      100 |       0 |   14.28 | 19-58             
  ...Indicator.tsx |   44.44 |      100 |       0 |   44.44 | 12-17             
  ...MoreLines.tsx |   30.43 |      100 |       0 |   30.43 | 18-38             
  StatsDisplay.tsx |    8.98 |      100 |       0 |    8.98 | ...40-445,449-500 
  ...usDisplay.tsx |       0 |        0 |       0 |       0 | 1-59              
  StickyHeader.tsx |    7.14 |      100 |       0 |    7.14 | 20-78             
  ...nsDisplay.tsx |    5.83 |      100 |       0 |    5.83 | 39-91,105-181     
  Table.tsx        |    6.77 |      100 |       0 |    6.77 | 31-36,39-99       
  ThemeDialog.tsx  |    3.96 |      100 |       0 |    3.96 | 51-441,444-500    
  ...dGradient.tsx |      25 |      100 |       0 |      25 | 27-46             
  Tips.tsx         |      16 |      100 |       0 |      16 | 17-45             
  TodoPanel.tsx    |     5.9 |      100 |       0 |     5.9 | ...87-244,247-296 
  ...tsDisplay.tsx |   10.05 |      100 |       0 |   10.05 | ...88-227,230-259 
  ToolsDialog.tsx  |   10.63 |      100 |       0 |   10.63 | ...5,41-47,50-123 
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-22             
  ...ionDialog.tsx |    6.08 |      100 |       0 |    6.08 | 18-104,110-161    
  ...romptHooks.ts |   87.47 |    65.51 |     100 |   87.47 | ...44-348,364-371 
  ...eyHandlers.ts |   24.33 |    33.33 |      50 |   24.33 | ...75-577,581-606 
  ...mptRender.tsx |   53.05 |     31.7 |   72.72 |   53.05 | ...02,314-322,343 
  ...PromptText.ts |   31.08 |    55.55 |   28.57 |   31.08 | ...25-175,179-199 
  ...romptTypes.ts |       0 |        0 |       0 |       0 | 1                 
  ...logActions.ts |    2.59 |      100 |       0 |    2.59 | ...92-562,565-602 
  ...logDisplay.ts |    4.28 |      100 |       0 |    4.28 | 25-120,125-184    
  ...logHelpers.ts |    7.64 |      100 |       0 |    7.64 | ...76-194,201-214 
  ...ialogHooks.ts |     2.8 |      100 |       0 |     2.8 | ...99-600,633-808 
  ...ogKeypress.ts |    1.69 |      100 |       0 |    1.69 | 35-387,482-679    
  ...ialogTypes.ts |       0 |        0 |       0 |       0 | 1                 
  ...alogViews.tsx |    4.13 |      100 |       0 |    4.13 | 31-133,167-378    
  todo-utils.ts    |       0 |        0 |       0 |       0 | 1-7               
 ...leCreateWizard |    18.6 |       50 |       0 |    18.6 |                   
  ...aramsStep.tsx |   13.42 |      100 |       0 |   13.42 | ...33-246,258-342 
  ...ationStep.tsx |    7.23 |      100 |       0 |    7.23 | ...35-571,583-651 
  ...onfigStep.tsx |   13.33 |      100 |       0 |   13.33 | 20-26,37-117      
  ...electStep.tsx |    9.73 |      100 |       0 |    9.73 | ...12-279,295-340 
  ...ationMenu.tsx |       0 |        0 |       0 |       0 | 1-102             
  ...eSaveStep.tsx |    7.73 |      100 |       0 |    7.73 | ...75-304,316-394 
  ...ssSummary.tsx |   12.12 |      100 |       0 |   12.12 | 23-88             
  ...electStep.tsx |   18.18 |      100 |       0 |   18.18 | 29-96             
  TextInput.tsx    |    6.56 |      100 |       0 |    6.56 | ...99-109,117-200 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.tsx        |   14.17 |      100 |       0 |   14.17 | ...97-226,235-319 
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |    5.42 |      100 |       0 |    5.42 | ...59-361,366-383 
  validation.ts    |   11.23 |      100 |       0 |   11.23 | ...97-104,107-111 
 ...gentManagement |    4.22 |      100 |       0 |    4.22 |                   
  ...entWizard.tsx |    2.91 |      100 |       0 |    2.91 | 30-232,237-312    
  ...ionWizard.tsx |    1.44 |      100 |       0 |    1.44 | 30-592,595-676    
  ...eteDialog.tsx |    5.88 |      100 |       0 |    5.88 | 14-94,104-146     
  ...tEditForm.tsx |    1.77 |      100 |       0 |    1.77 | 30-619,622-640    
  ...tListMenu.tsx |    2.94 |      100 |       0 |    2.94 | 15-264,267-348    
  ...tMainMenu.tsx |   16.66 |      100 |       0 |   16.66 | 22-62             
  ...gerDialog.tsx |    2.39 |      100 |       0 |    2.39 | 29-600,603-679    
  ...tShowView.tsx |    4.76 |      100 |       0 |    4.76 | 25-183,186-243    
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...comeOnboarding |   13.67 |        0 |       0 |   13.67 |                   
  ...ethodStep.tsx |   16.86 |      100 |       0 |   16.86 | 38-123            
  ...ationStep.tsx |    7.35 |      100 |       0 |    7.35 | ...1,59-95,98-177 
  ...etionStep.tsx |    9.84 |      100 |       0 |    9.84 | ...,89-99,103-179 
  ...electStep.tsx |   12.12 |      100 |       0 |   12.12 | ...3,67-75,79-143 
  ...electStep.tsx |   34.48 |      100 |       0 |   34.48 | 51-120            
  SkipExitStep.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...omeDialog.tsx |   11.76 |      100 |       0 |   11.76 | 51-118,121-166    
  WelcomeStep.tsx  |    10.2 |      100 |       0 |    10.2 | 23-74             
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
 ...nents/messages |    18.9 |       90 |   15.06 |    18.9 |                   
  AiMessage.tsx    |   14.51 |      100 |       0 |   14.51 | 28-95             
  ...geContent.tsx |   20.83 |      100 |       0 |   20.83 | 26-46             
  ...onMessage.tsx |   12.28 |      100 |       0 |   12.28 | 24-86             
  DiffRenderer.tsx |    3.59 |      100 |       0 |    3.59 | ...81-412,415-433 
  ErrorMessage.tsx |   22.22 |      100 |       0 |   22.22 | 16-31             
  InfoMessage.tsx  |   17.24 |      100 |       0 |   17.24 | 19-44             
  ...rlMessage.tsx |   11.36 |      100 |       0 |   11.36 | 18-65             
  ...geMessage.tsx |     100 |      100 |     100 |     100 |                   
  ...ckDisplay.tsx |      20 |      100 |       0 |      20 | 43-64             
  ...onMessage.tsx |    3.04 |      100 |       0 |    3.04 | 36-552,557-636    
  ...upMessage.tsx |    7.55 |      100 |       0 |    7.55 | ...76-269,273-348 
  ToolMessage.tsx  |    4.37 |      100 |       0 |    4.37 | 38-342,358-428    
  ...ltDisplay.tsx |   92.03 |    88.23 |     100 |   92.03 | 55-69,238-240     
  ToolShared.tsx   |   64.61 |       90 |   33.33 |   64.61 | 78-99,102-105     
  UserMessage.tsx  |     100 |      100 |     100 |     100 |                   
  ...llMessage.tsx |   36.36 |      100 |       0 |   36.36 | 17-25             
  ...ngMessage.tsx |    23.8 |      100 |       0 |    23.8 | 17-34             
 ...ponents/shared |   40.89 |     63.3 |   39.91 |   40.89 |                   
  ...ctionList.tsx |    4.31 |      100 |       0 |    4.31 | 36-123,128-206    
  MaxSizedBox.tsx  |   49.79 |    56.75 |   70.58 |   49.79 | ...63-666,670-673 
  ...tonSelect.tsx |   12.76 |      100 |       0 |   12.76 | 66-113            
  ...lableList.tsx |    5.15 |      100 |       0 |    5.15 | 40-267            
  ...ist.hooks.tsx |    3.81 |      100 |       0 |    3.81 | ...70-795,798-835 
  ...lizedList.tsx |   11.49 |      100 |       0 |   11.49 | 28-112            
  ...List.types.ts |     100 |      100 |     100 |     100 |                   
  ...operations.ts |   75.54 |    48.14 |     100 |   75.54 | ...32-233,256-265 
  ...er-reducer.ts |   28.25 |    51.11 |   33.33 |   28.25 | ...30,632,644,687 
  buffer-types.ts  |     100 |      100 |     100 |     100 |                   
  text-buffer.ts   |   71.75 |    89.18 |   27.86 |   71.75 | ...33-635,654-660 
  ...formations.ts |   42.85 |    71.42 |      80 |   42.85 | ...32-139,163-209 
  ...n-handlers.ts |   33.99 |    61.53 |   23.25 |   33.99 | ...47-755,758-762 
  ...st-helpers.ts |       0 |        0 |       0 |       0 | 1-33              
  ...er-actions.ts |   93.84 |     87.5 |     100 |   93.84 | 91-93,100         
  visual-layout.ts |    90.2 |    72.34 |     100 |    90.2 | ...48-350,372-373 
  ...navigation.ts |   53.38 |    61.53 |   73.68 |   53.38 | ...45-366,389-411 
 ...mponents/views |    9.79 |      100 |       0 |    9.79 |                   
  ChatList.tsx     |   20.58 |      100 |       0 |   20.58 | 24-55             
  ...sionsList.tsx |     7.5 |      100 |       0 |     7.5 | 19-103            
  HooksList.tsx    |   10.67 |      100 |       0 |   10.67 | ...18-129,132-147 
  SkillsList.tsx   |    5.79 |      100 |       0 |    5.79 | 18-103            
 src/ui/constants  |   55.78 |     90.9 |      50 |   55.78 |                   
  ...ollections.ts |     100 |      100 |     100 |     100 |                   
  tips.ts          |       0 |        0 |       0 |       0 | 1-164             
 src/ui/containers |       0 |        0 |       0 |       0 |                   
  ...ontroller.tsx |       0 |        0 |       0 |       0 | 1-357             
  UIStateShell.tsx |       0 |        0 |       0 |       0 | 1-15              
 ...ainer/builders |   98.38 |      100 |   83.33 |   98.38 |                   
  ...dUIActions.ts |     100 |      100 |     100 |     100 |                   
  buildUIState.ts  |     100 |      100 |     100 |     100 |                   
  ...onsBuilder.ts |   66.66 |      100 |       0 |   66.66 | 20-21             
  ...ateBuilder.ts |   66.66 |      100 |       0 |   66.66 | 20-21             
 ...ontainer/hooks |   55.85 |    87.02 |   58.33 |   55.85 |                   
  ...pBootstrap.ts |   93.21 |    58.33 |     100 |   93.21 | ...40-247,251-253 
  useAppDialogs.ts |   41.42 |      100 |   42.85 |   41.42 | ...63,182-398,418 
  ...ntHandlers.ts |     100 |      100 |     100 |     100 |                   
  useAppInput.ts   |    5.78 |      100 |       0 |    5.78 | 104-521,524-528   
  useAppLayout.ts  |    7.69 |      100 |       0 |    7.69 | 93-308,311-314    
  ...reenAction.ts |   13.63 |      100 |       0 |   13.63 | 23-41             
  ...nSelection.ts |      20 |      100 |       0 |      20 | 27-48             
  ...hestration.ts |     100 |      100 |     100 |     100 |                   
  ...references.ts |      10 |      100 |       0 |      10 | 51-104            
  ...itHandling.ts |   89.79 |      100 |     100 |   89.79 | 131-139,143       
  ...textBridge.ts |   33.33 |      100 |       0 |   33.33 | 23-30             
  ...tartHotkey.ts |   26.66 |      100 |       0 |   26.66 | 23-33             
  ...omptSubmit.ts |     100 |      100 |     100 |     100 |                   
  ...utHandling.ts |   98.37 |     91.3 |     100 |   98.37 | 53,166            
  ...yBootstrap.ts |      30 |      100 |       0 |      30 | 28-34             
  ...eybindings.ts |   86.28 |    78.18 |     100 |   86.28 | ...04-206,250-251 
  ...easurement.ts |   15.38 |      100 |       0 |   15.38 | 45-95             
  ...reshAction.ts |   79.16 |     37.5 |     100 |   79.16 | 60,90-93,95-104   
  ...untimeSync.ts |   96.15 |    96.96 |     100 |   96.15 | 204-209           
  ...elTracking.ts |   34.69 |      100 |     100 |   34.69 | 51-95             
  ...laceholder.ts |      15 |      100 |       0 |      15 | 13-18,21-34       
  ...rorTimeout.ts |   17.64 |      100 |       0 |   17.64 | 24-39             
  ...astructure.ts |   73.91 |      100 |      20 |   73.91 | 53,57,61,75-83    
  ...ebugLogger.ts |   17.24 |      100 |       0 |   17.24 | 23-51             
  ...ialization.ts |   72.34 |    84.61 |   66.66 |   72.34 | ...,73-95,134-135 
  ...sAutoReset.ts |     100 |       90 |     100 |     100 | 44                
  ...andActions.ts |     100 |      100 |     100 |     100 |                   
  ...eshManager.ts |     100 |      100 |     100 |     100 |                   
  ...uationFlow.ts |    7.14 |      100 |       0 |    7.14 | 57-160            
  ...csTracking.ts |   95.78 |    80.64 |     100 |   95.78 | ...22-123,174-175 
  ...uthBridges.ts |   17.94 |      100 |   33.33 |   17.94 | ...13-138,142-146 
 src/ui/contexts   |   55.64 |    80.89 |   53.76 |   55.64 |                   
  ...chContext.tsx |   88.23 |    66.66 |     100 |   88.23 | 27-28             
  FocusContext.tsx |       0 |        0 |       0 |       0 | 1-11              
  ...ssContext.tsx |    83.3 |    87.89 |    87.5 |    83.3 | ...21-522,572-573 
  MouseContext.tsx |   78.82 |       75 |      80 |   78.82 | ...00-101,111-117 
  ...erContext.tsx |   94.44 |    63.63 |     100 |   94.44 | 125-128           
  ...owContext.tsx |   21.42 |      100 |   33.33 |   21.42 | 34,40-88          
  ...meContext.tsx |   45.27 |    57.14 |      50 |   45.27 | ...45-246,254-255 
  ...lProvider.tsx |    91.8 |    74.62 |     100 |    91.8 | ...94-495,507-508 
  ...onContext.tsx |     4.4 |      100 |       0 |     4.4 | ...38-393,398-405 
  ...teContext.tsx |       0 |        0 |       0 |       0 | 1-57              
  ...gsContext.tsx |      50 |      100 |       0 |      50 | 15-20             
  ...ngContext.tsx |   42.85 |      100 |       0 |   42.85 | 15-22             
  TodoContext.tsx  |   54.54 |      100 |       0 |   54.54 | 28-31,33-36,39-40 
  TodoProvider.tsx |    3.35 |      100 |       0 |    3.35 | 27-166,169-199    
  ...llContext.tsx |     100 |      100 |       0 |     100 |                   
  ...lProvider.tsx |    6.75 |      100 |       0 |    6.75 | 24-118            
  ...nsContext.tsx |      25 |      100 |       0 |      25 | 203-214,217-222   
  ...teContext.tsx |      50 |       50 |      50 |      50 | 251-260,265-266   
  ...deContext.tsx |   11.11 |      100 |       0 |   11.11 | 30-82,85-90       
 src/ui/editors    |   98.18 |     87.5 |     100 |   98.18 |                   
  ...ngsManager.ts |   98.18 |     87.5 |     100 |   98.18 | 59                
 src/ui/hooks      |    68.2 |    85.47 |   68.53 |    68.2 |                   
  ...st-helpers.ts |   91.47 |    81.25 |   68.57 |   91.47 | ...62-163,182-186 
  ...dProcessor.ts |   82.58 |    86.88 |   77.77 |   82.58 | ...02-204,257-269 
  ...sorHelpers.ts |   83.79 |    80.35 |   96.29 |   83.79 | ...47-649,694-695 
  ...rceHelpers.ts |   55.85 |       50 |   71.42 |   55.85 | ...67-273,278-286 
  ...etionUtils.ts |   53.36 |    88.23 |   64.28 |   53.36 | 57-207,335        
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  keyToAnsi.ts     |    42.5 |      100 |       0 |    42.5 | 27-37,47-61       
  ...etionUtils.ts |     100 |    66.66 |     100 |     100 | 49                
  ...dProcessor.ts |   95.57 |       80 |     100 |   95.57 | ...85-286,418-422 
  ...ndHandlers.ts |   17.54 |    27.27 |   22.22 |   17.54 | ...45-646,651-660 
  ...dPathUtils.ts |    95.7 |    90.52 |     100 |    95.7 | ...25-227,271-272 
  ...dProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...sorSupport.ts |   68.85 |    70.83 |   66.66 |   68.85 | ...81-284,302-309 
  ...tionEffect.ts |   90.76 |    86.56 |   92.85 |   90.76 | ...05-406,419-420 
  ...etionTypes.ts |       0 |        0 |       0 |       0 | 1                 
  toolMapping.ts   |   90.76 |    88.88 |   93.33 |   90.76 | ...95-207,226-228 
  ...st-helpers.ts |   75.93 |    76.66 |      24 |   75.93 | ...76-277,279-280 
  ...nateBuffer.ts |      50 |      100 |       0 |      50 | 16-18             
  ...dScrollbar.ts |   97.82 |      100 |     100 |   97.82 | 153-155           
  ...st-helpers.ts |     100 |      100 |     100 |     100 |                   
  ...Completion.ts |   93.01 |    88.35 |     100 |   93.01 | ...96-597,600-601 
  ...uthCommand.ts |   96.42 |    66.66 |     100 |   96.42 | 21                
  ...tIndicator.ts |     100 |     92.3 |     100 |     100 | 57                
  useBanner.ts     |     100 |    83.33 |     100 |     100 | 22,48             
  ...chedScroll.ts |   16.66 |      100 |       0 |   16.66 | 14-32             
  ...ketedPaste.ts |      20 |      100 |       0 |      20 | 20-38             
  ...ompletion.tsx |   97.24 |    82.75 |    90.9 |   97.24 | ...05-207,210-211 
  useCompletion.ts |    92.4 |     87.5 |     100 |    92.4 | 68-69,93-94,98-99 
  ...leMessages.ts |   96.15 |       90 |     100 |   96.15 | 56-57,63          
  ...ntHandlers.ts |   31.25 |      100 |     100 |   31.25 | 43-70,74-82       
  ...fileDialog.ts |   16.12 |      100 |       0 |   16.12 | 17-47             
  ...orSettings.ts |   11.86 |      100 |       0 |   11.86 | 31-87             
  ...AutoUpdate.ts |    8.33 |      100 |       0 |    8.33 | 18-64             
  ...ionUpdates.ts |   75.17 |    80.64 |   77.77 |   75.17 | ...60-261,289-303 
  ...erDetector.ts |     100 |      100 |     100 |     100 |                   
  useFocus.ts      |     100 |      100 |     100 |     100 |                   
  ...olderTrust.ts |   84.55 |    86.95 |     100 |   84.55 | ...11-113,129-130 
  ...BranchName.ts |     100 |       95 |     100 |     100 | 54                
  ...oryManager.ts |   96.61 |    93.18 |     100 |   96.61 | ...70-171,214-215 
  ...splayState.ts |     100 |      100 |     100 |     100 |                   
  ...stListener.ts |   12.12 |      100 |       0 |   12.12 | 18-51             
  ...ivityTimer.ts |   76.19 |    66.66 |     100 |   76.19 | 30-35             
  ...putHistory.ts |    92.5 |    85.71 |     100 |    92.5 | 62-63,71,93-95    
  ...storyStore.ts |     100 |    94.11 |     100 |     100 | 67                
  useKeypress.ts   |   88.88 |       75 |     100 |   88.88 | 31-32             
  ...rdProtocol.ts |       0 |        0 |       0 |       0 | 1-26              
  ...fileDialog.ts |     5.4 |      100 |       0 |     5.4 | 23-69,72-143      
  ...gIndicator.ts |     100 |      100 |     100 |     100 |                   
  useLogger.ts     |   93.75 |      100 |     100 |   93.75 | 27                
  useMcpStatus.ts  |   90.69 |    66.66 |     100 |   90.69 | 16,30-32          
  ...oryMonitor.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  useMouse.ts      |   77.77 |    66.66 |     100 |   77.77 | 31-34             
  useMouseClick.ts |     100 |      100 |     100 |     100 |                   
  ...eSelection.ts |     2.2 |      100 |       0 |     2.2 | 51-378,381-427    
  ...hestration.ts |     100 |      100 |     100 |     100 |                   
  ...oviderInfo.ts |       0 |        0 |       0 |       0 | 1-85              
  ...odifyTrust.ts |    9.09 |      100 |       0 |    9.09 | 43-134            
  ...raseCycler.ts |   79.72 |    73.33 |     100 |   79.72 | ...69,75-76,92-94 
  ...cySettings.ts |   85.14 |    77.77 |     100 |   85.14 | ...,75-79,109-120 
  ...Management.ts |    1.53 |      100 |       0 |    1.53 | 22-568,571-663    
  ...Completion.ts |   43.02 |    55.55 |      50 |   43.02 | ...91-304,335-344 
  ...iderDialog.ts |    5.71 |      100 |       0 |    5.71 | 39-77,80-151      
  ...lScheduler.ts |   78.36 |    97.36 |      75 |   78.36 | ...75,291-307,464 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  useResponsive.ts |     100 |      100 |     100 |     100 |                   
  ...ompletion.tsx |   69.56 |      100 |     100 |   69.56 | 45-47,51-66,78-81 
  useRewind.ts     |     100 |      100 |     100 |     100 |                   
  ...ectionList.ts |   89.78 |     89.1 |     100 |   89.78 | ...17-423,443-447 
  useSession.ts    |       0 |        0 |       0 |       0 | 1-23              
  ...ionBrowser.ts |     100 |      100 |     100 |     100 |                   
  ...serHelpers.ts |   95.79 |    85.21 |   97.36 |   95.79 | ...37-639,762-763 
  ...erKeypress.ts |   89.87 |    97.29 |   94.11 |   89.87 | 101-108,130-145   
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...hallowMemo.ts |      10 |      100 |       0 |      10 | 9-22,35-47        
  ...ellHistory.ts |   92.17 |    78.78 |     100 |   92.17 | ...81,129-130,140 
  ...Completion.ts |   97.07 |    81.25 |     100 |   97.07 | 71-73,101-102     
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-64              
  ...cessorCore.ts |   74.13 |       60 |     100 |   74.13 | ...20,157,177-204 
  ...ompletion.tsx |   96.73 |    81.39 |     100 |   96.73 | ...,93-94,336-344 
  ...leCallback.ts |     100 |      100 |     100 |     100 |                   
  ...tateAndRef.ts |   59.09 |      100 |     100 |   59.09 | 23-31             
  ...oryRefresh.ts |     100 |      100 |     100 |     100 |                   
  ...rminalSize.ts |   10.34 |      100 |       0 |   10.34 | 15-44,49-85       
  ...emeCommand.ts |    4.29 |      100 |       0 |    4.29 | 25-122,125-199    
  useTimer.ts      |    87.5 |    85.71 |     100 |    87.5 | 44-45,50-52       
  ...ntinuation.ts |   91.24 |    89.74 |     100 |   91.24 | ...27-128,154-164 
  ...ePreserver.ts |   57.14 |      100 |      80 |   57.14 | 58-76             
  ...oolsDialog.ts |    3.57 |      100 |       0 |    3.57 | 25-99,102-185     
  ...Onboarding.ts |    1.92 |      100 |       0 |    1.92 | 79-403,406-487    
  ...eMigration.ts |   11.66 |      100 |       0 |   11.66 | 15-74             
  vim.ts           |   85.73 |     87.8 |    90.9 |   85.73 | ...07-716,832-834 
 ...ks/agentStream |   82.61 |    78.02 |   82.08 |   82.61 |                   
  ...Dispatcher.ts |   47.38 |    35.55 |   56.25 |   47.38 | ...62,364,401-434 
  ...ersistence.ts |    98.3 |    95.34 |     100 |    98.3 | 160-162           
  ...tProcessor.ts |      78 |    77.77 |      80 |      78 | ...47-158,161-163 
  contextLimit.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  queryPreparer.ts |   63.26 |    46.66 |     100 |   63.26 | ...47-148,151-165 
  streamUtils.ts   |   93.01 |    88.78 |    91.3 |   93.01 | ...33-249,425-427 
  thoughtState.ts  |   93.33 |    68.75 |     100 |   93.33 | 70-71,76-77       
  ...ionHandler.ts |     100 |      100 |     100 |     100 |                   
  ...reparation.ts |   96.42 |    88.88 |     100 |   96.42 | 44                
  types.ts         |       0 |        0 |       0 |       0 | 1-17              
  ...ventStream.ts |   87.41 |    88.46 |      60 |   87.41 | ...71-278,297-298 
  ...gentStream.ts |     100 |      100 |      80 |     100 |                   
  ...mLifecycle.ts |   84.25 |    63.33 |      80 |   84.25 | ...31-232,261-266 
  ...hestration.ts |   99.18 |      100 |   88.88 |   99.18 | 112-113           
  ...ntHandlers.ts |   70.84 |    95.83 |   84.21 |   70.84 | ...37,446-455,514 
  ...treamState.ts |   79.53 |       50 |     100 |   79.53 | ...76,197,233-234 
  ...ubmitQuery.ts |    92.5 |    82.75 |   86.66 |    92.5 | ...10-511,533-535 
 src/ui/layouts    |   83.55 |    56.89 |   83.33 |   83.55 |                   
  ...AppLayout.tsx |   81.18 |    71.42 |   83.33 |   81.18 | ...91-205,321-359 
  ...utHelpers.tsx |   86.31 |     54.9 |   95.23 |   86.31 | ...88-789,810-838 
  ...ainContent.ts |   23.52 |      100 |       0 |   23.52 | 16-22,25-28,31-34 
 ...noninteractive |   74.07 |      100 |    7.14 |   74.07 |                   
  ...eractiveUi.ts |   74.07 |      100 |    7.14 |   74.07 | 17-19,23-24,27-28 
 src/ui/privacy    |   19.41 |        0 |       0 |   19.41 |                   
  ...acyNotice.tsx |       0 |        0 |       0 |       0 | 1-140             
  ...acyNotice.tsx |       0 |        0 |       0 |       0 | 1-59              
  ...acyNotice.tsx |   12.19 |      100 |       0 |   12.19 | 16-62             
  ...acyNotice.tsx |   35.42 |      100 |       0 |   35.42 | 77-172,180-235    
  ...acyNotice.tsx |   19.35 |      100 |       0 |   19.35 | 22-53,56-58       
 src/ui/reducers   |    79.5 |    91.66 |      50 |    79.5 |                   
  appReducer.ts    |     100 |      100 |     100 |     100 |                   
  ...ionReducer.ts |       0 |        0 |       0 |       0 | 1-52              
 src/ui/state      |   52.63 |    30.76 |      50 |   52.63 |                   
  extensions.ts    |   52.63 |    30.76 |      50 |   52.63 | ...28,130,134-149 
 src/ui/themes     |   99.04 |    85.65 |   97.61 |   99.04 |                   
  ansi-light.ts    |     100 |      100 |     100 |     100 |                   
  ansi.ts          |     100 |      100 |     100 |     100 |                   
  atom-one-dark.ts |     100 |      100 |     100 |     100 |                   
  ayu-light.ts     |     100 |      100 |     100 |     100 |                   
  ayu.ts           |     100 |      100 |     100 |     100 |                   
  color-utils.ts   |     100 |      100 |     100 |     100 |                   
  default-light.ts |     100 |      100 |     100 |     100 |                   
  default.ts       |     100 |      100 |     100 |     100 |                   
  dracula.ts       |     100 |      100 |     100 |     100 |                   
  github-dark.ts   |     100 |      100 |     100 |     100 |                   
  github-light.ts  |     100 |      100 |     100 |     100 |                   
  googlecode.ts    |     100 |      100 |     100 |     100 |                   
  green-screen.ts  |     100 |      100 |     100 |     100 |                   
  no-color.ts      |     100 |      100 |     100 |     100 |                   
  ...c-resolver.ts |     100 |      100 |     100 |     100 |                   
  ...tic-tokens.ts |     100 |      100 |     100 |     100 |                   
  ...-of-purple.ts |     100 |      100 |     100 |     100 |                   
  theme-compat.ts  |     100 |       50 |     100 |     100 | 79                
  theme-manager.ts |   88.55 |    82.81 |     100 |   88.55 | ...03-312,317-318 
  theme.ts         |   99.09 |     81.3 |   94.11 |   99.09 | 282-283,702-703   
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/types      |       0 |        0 |       0 |       0 |                   
  ...ngMetadata.ts |       0 |        0 |       0 |       0 |                   
 src/ui/utils      |   62.63 |    89.04 |   73.88 |   62.63 |                   
  ...Colorizer.tsx |    5.64 |      100 |       0 |    5.64 | ...27-168,180-249 
  ...olePatcher.ts |   72.09 |      100 |   83.33 |   72.09 | 50-61             
  ...nRenderer.tsx |   96.88 |    87.87 |     100 |   96.88 | ...69-271,275-277 
  ...wnDisplay.tsx |       5 |      100 |       0 |       5 | ...90-717,728-732 
  ...eRenderer.tsx |   11.17 |      100 |       0 |   11.17 | ...34-387,394-427 
  ...tGenerator.ts |     100 |    95.45 |   83.33 |     100 | 129               
  ...ketedPaste.ts |      60 |      100 |       0 |      60 | 13-14,17-18       
  clipboard.ts     |   97.29 |    84.61 |     100 |   97.29 | 40                
  ...boardUtils.ts |   62.28 |    76.74 |   83.33 |   62.28 | ...52-266,336-338 
  commandUtils.ts  |   93.02 |    94.44 |   96.15 |   93.02 | ...31-235,316-324 
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  displayUtils.ts  |     100 |      100 |     100 |     100 |                   
  formatters.ts    |   90.47 |    95.23 |     100 |   90.47 | 57-60             
  fuzzyFilter.ts   |     100 |    96.55 |     100 |     100 | 84                
  highlight.ts     |   77.69 |    97.29 |      60 |   77.69 | 146-172,176-181   
  ...xportUtils.ts |   98.47 |    92.85 |     100 |   98.47 | 139-140           
  ...storyItems.ts |   99.08 |    94.59 |     100 |   99.08 | 79                
  input.ts         |   84.28 |    94.44 |   66.66 |   84.28 | 73-80,106-113     
  isNarrowWidth.ts |      50 |      100 |       0 |      50 | 13-14             
  ...nUtilities.ts |   66.66 |     87.5 |     100 |   66.66 | 75-94,103-104     
  modelIdentity.ts |   99.23 |    98.18 |   84.61 |   99.23 | 169               
  mouse.ts         |   83.05 |    72.41 |     100 |   83.05 | ...94,201,214-215 
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  ...opDetector.ts |       0 |        0 |       0 |       0 | 1-210             
  responsive.ts    |   73.39 |    76.66 |   83.33 |   73.39 | ...00-108,111-125 
  rewindFileOps.ts |   92.34 |    71.79 |     100 |   92.34 | ...48-251,291-295 
  ...putHandler.ts |   94.44 |    91.12 |     100 |   94.44 | ...15-316,386-387 
  ...ityManager.ts |    94.9 |    85.71 |    90.9 |    94.9 | ...28,352,380,391 
  ...alContract.ts |     100 |      100 |     100 |     100 |                   
  terminalLinks.ts |     100 |      100 |     100 |     100 |                   
  ...colCleanup.ts |   95.23 |       75 |     100 |   95.23 | 38                
  ...lSequences.ts |     100 |      100 |     100 |     100 |                   
  terminalSetup.ts |   10.72 |      100 |    7.14 |   10.72 | 80-419            
  textUtils.ts     |   81.88 |     85.1 |   88.88 |   81.88 | ...,53-68,156-157 
  ...Formatters.ts |       0 |        0 |       0 |       0 | 1-50              
  ...icsTracker.ts |     100 |    94.44 |     100 |     100 | 38                
  ui-sizing.ts     |      16 |      100 |       0 |      16 | 11-23,26-36       
  updateCheck.ts   |     100 |    94.11 |     100 |     100 | 34,45             
 src/utils         |   61.67 |    88.87 |      75 |   61.67 |                   
  ...ionContext.ts |   76.92 |       75 |     100 |   76.92 | 38-41,63-66,81-84 
  ...Formatting.ts |   94.36 |    93.54 |     100 |   94.36 | 49-50,71-72       
  bootstrap.ts     |     100 |      100 |     100 |     100 |                   
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  cleanup.ts       |   67.74 |       80 |      60 |   67.74 | ...66-68,71,85-94 
  coalesce.ts      |     100 |      100 |     100 |     100 |                   
  commands.ts      |   51.78 |    71.42 |     100 |   51.78 | 25-26,57-85       
  commentJson.ts   |    92.3 |     92.5 |     100 |    92.3 | 94-102            
  ...ScopeUtils.ts |   27.58 |      100 |       0 |   27.58 | 24-41,58-86       
  ...icSettings.ts |   88.07 |     87.5 |     100 |   88.07 | ...73,85-88,91-94 
  ...arResolver.ts |   96.72 |    96.42 |     100 |   96.72 | 118-119           
  errors.ts        |   94.87 |       88 |     100 |   94.87 | 53-54,95-96       
  events.ts        |     100 |      100 |     100 |     100 |                   
  ...lativeTime.ts |     100 |      100 |     100 |     100 |                   
  gitUtils.ts      |   93.54 |       85 |     100 |   93.54 | 61-62,77-80       
  ...AutoUpdate.ts |   69.37 |    80.76 |   77.77 |   69.37 | ...67-268,282-347 
  ...lationInfo.ts |   99.49 |     98.3 |     100 |   99.49 | 58                
  math.ts          |   66.66 |      100 |       0 |   66.66 | 15                
  ...stentState.ts |   95.31 |    84.21 |     100 |   95.31 | 42,63-64          
  readStdin.ts     |   81.03 |    91.66 |   83.33 |   81.03 | 32-39,51-53       
  refusalNotice.ts |     100 |      100 |     100 |     100 |                   
  relaunch.ts      |     100 |      100 |     100 |     100 |                   
  resolvePath.ts   |   66.66 |       25 |     100 |   66.66 | 12-13,16,18-19    
  ...containers.ts |    4.69 |      100 |       0 |    4.69 | ...35-655,659-685 
  ...entrypoint.ts |    9.87 |      100 |       0 |    9.87 | 19-48,51-100      
  sandbox-env.ts   |   74.65 |    77.14 |   66.66 |   74.65 | ...52-153,161-162 
  sandbox-exec.ts  |    8.45 |      100 |    12.5 |    8.45 | 56-321,338-427    
  sandbox-image.ts |    3.96 |      100 |       0 |    3.96 | 12-128            
  ...box-podman.ts |   74.59 |    94.73 |   77.77 |   74.59 | ...49-259,325-398 
  ...x-seatbelt.ts |     8.2 |      100 |       0 |     8.2 | 34-310            
  sandbox-ssh.ts   |   78.84 |    81.13 |     100 |   78.84 | ...06-307,371-375 
  sandbox.ts       |   13.23 |      100 |       0 |   13.23 | 47-111            
  ...st-helpers.ts |     100 |      100 |     100 |     100 |                   
  ...ionCleanup.ts |   88.34 |    83.11 |     100 |   88.34 | ...47-248,331-332 
  sessionUtils.ts  |    8.86 |      100 |       0 |    8.86 | 52-122,129-143    
  settingsUtils.ts |   85.67 |    91.34 |   94.28 |   85.67 | ...61-489,528-529 
  ...ttingSaver.ts |    1.92 |      100 |       0 |    1.92 | 11-32,40-85       
  skillSettings.ts |   86.13 |       88 |     100 |   86.13 | 99-107,134-138    
  skillUtils.ts    |   71.33 |    70.96 |   83.33 |   71.33 | ...88-189,203-224 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdinSafety.ts   |   91.39 |    86.48 |     100 |   91.39 | ...66-167,170,245 
  terminalTheme.ts |     100 |      100 |     100 |     100 |                   
  typeGuards.ts    |   65.38 |      100 |      75 |   65.38 | 26-34             
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  version.ts       |     100 |      100 |     100 |     100 |                   
  windowTitle.ts   |     100 |      100 |     100 |     100 |                   
 src/utils/privacy |   66.15 |       70 |   76.19 |   66.15 |                   
  ...taRedactor.ts |   81.91 |    71.42 |      80 |   81.91 | ...08-610,616-637 
  ...acyManager.ts |       0 |        0 |       0 |       0 | 1-176             
 ...ed-integration |   74.58 |    76.07 |   76.29 |   74.58 |                   
  ...temService.ts |     100 |      100 |     100 |     100 |                   
  ...tent-utils.ts |    7.01 |       50 |   14.28 |    7.01 | ...06-117,120-166 
  zed-helpers.ts   |      42 |    55.55 |      50 |      42 | ...59-166,168-170 
  ...h-resolver.ts |   73.57 |    55.05 |   95.23 |   73.57 | ...81-587,591-615 
  ...st-helpers.ts |    98.4 |      100 |   56.66 |    98.4 | 184-186           
  ...ol-handler.ts |   87.65 |     80.9 |   96.15 |   87.65 | ...16-318,365-378 
  ...ntegration.ts |   79.53 |    79.39 |   80.95 |   79.53 | ...13-814,842-844 
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   78.53 |    83.86 |   75.54 |   78.53 |                   
 src               |     100 |      100 |     100 |     100 |                   
  ...-factories.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/__mocks__/fs  |       0 |        0 |       0 |       0 |                   
  promises.ts      |       0 |        0 |       0 |       0 | 1-48              
 src/adapters      |     100 |      100 |     100 |     100 |                   
  ...eamAdapter.ts |     100 |      100 |     100 |     100 |                   
 src/code_assist   |   80.88 |    80.57 |   82.14 |   80.88 |                   
  codeAssist.ts    |   17.24 |      100 |       0 |   17.24 | 22-44,51-59       
  ...orAdapters.ts |   92.26 |    71.11 |   88.88 |   92.26 | ...05-207,272-275 
  converter.ts     |   95.54 |    93.02 |     100 |   95.54 | 186-190,219-220   
  ...nAIWrapper.ts |     100 |      100 |     100 |     100 |                   
  ...al-storage.ts |   95.86 |    79.48 |     100 |   95.86 | 27-28,86,110,139  
  server.ts        |   48.16 |    72.72 |      50 |   48.16 | ...15-256,259-262 
  setup.ts         |   86.09 |    73.07 |     100 |   86.09 | ...57-159,183-189 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/commands      |     100 |      100 |     100 |     100 |                   
  extensions.ts    |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/config        |   70.55 |     78.6 |    58.5 |   70.55 |                   
  ...tLifecycle.ts |   95.42 |    94.59 |     100 |   95.42 | ...57-158,222-224 
  ...skServices.ts |    9.19 |      100 |       0 |    9.19 | ...5,62-80,89-129 
  config.ts        |      60 |    73.17 |   57.14 |      60 | ...38-747,772-779 
  configBase.ts    |   68.81 |    72.09 |   72.72 |   68.81 | ...48-255,257-261 
  ...igBaseCore.ts |   69.16 |    94.28 |      44 |   69.16 | ...88-789,791-792 
  ...onstructor.ts |   96.91 |    88.88 |     100 |   96.91 | ...93-494,497-498 
  ...estHarness.ts |   93.15 |    95.45 |   83.33 |   93.15 | 229-239,245-248   
  configTypes.ts   |      58 |      100 |      50 |      58 | 199-239           
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...ngsHelpers.ts |   62.16 |       40 |     100 |   62.16 | ...31,35-36,42-43 
  index.ts         |       0 |        0 |       0 |       0 | 1-42              
  ...ntegration.ts |   63.22 |    75.47 |   73.68 |   63.22 | ...17,434,443,452 
  models.ts        |     100 |      100 |     100 |     100 |                   
  ...rSingleton.ts |   76.22 |    70.37 |   56.25 |   76.22 | ...94,397-400,408 
  ...entManager.ts |   50.76 |    68.91 |   65.21 |   50.76 | ...52-653,679-703 
  ...ingsParser.ts |   41.37 |    33.33 |     100 |   41.37 | 31-48             
  ...tryFactory.ts |   84.69 |    76.92 |   69.23 |   84.69 | ...62,478,496-512 
  types.ts         |       0 |        0 |       0 |       0 |                   
 ...nfirmation-bus |   83.33 |       50 |      50 |   83.33 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-2               
  message-bus.ts   |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   79.27 |    76.52 |   87.14 |   79.27 |                   
  ...ssionTypes.ts |       0 |        0 |       0 |       0 | 1-90              
  ...ntContract.ts |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   97.43 |    92.59 |     100 |   97.43 | 92-93             
  ...okTriggers.ts |   47.39 |     61.9 |   66.66 |   47.39 | ...51,253,299-304 
  ...acyAliases.ts |     100 |      100 |     100 |     100 |                   
  ...igBoundary.ts |       0 |        0 |       0 |       0 | 1                 
  ...okTriggers.ts |   96.09 |    84.37 |     100 |   96.09 | ...22,161,208,250 
  logger.ts        |   78.22 |    80.19 |   94.44 |   78.22 | ...56-470,513-525 
  prompts.ts       |   82.85 |     58.9 |    91.3 |   82.85 | ...55,558,619-620 
  subagentTypes.ts |   83.11 |    68.42 |   77.77 |   83.11 | ...03-304,319-320 
  tokenLimits.ts   |     100 |      100 |     100 |     100 |                   
  ...erContract.ts |     100 |      100 |     100 |     100 |                   
  turn.ts          |     100 |      100 |     100 |     100 |                   
 ...re/compression |   29.71 |    33.33 |   14.28 |   29.71 |                   
  ...nDirective.ts |    6.25 |      100 |       0 |    6.25 | 22-62             
  types.ts         |   34.96 |    33.33 |   16.66 |   34.96 | ...20-421,434-436 
 src/debug         |   61.53 |        0 |       0 |   61.53 |                   
  ...ionManager.ts |     100 |      100 |     100 |     100 |                   
  DebugLogger.ts   |     100 |      100 |     100 |     100 |                   
  FileOutput.ts    |     100 |      100 |     100 |     100 |                   
  ...ionManager.ts |       0 |        0 |       0 |       0 | 1-6               
  ...FileOutput.ts |       0 |        0 |       0 |       0 | 1-6               
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/filters       |   97.79 |    95.58 |     100 |   97.79 |                   
  EmojiFilter.ts   |   97.79 |    95.58 |     100 |   97.79 | ...55-156,363-364 
 src/hooks         |    84.3 |    85.51 |   82.08 |    84.3 |                   
  errors.ts        |     100 |      100 |     100 |     100 |                   
  ...Aggregator.ts |   90.55 |    81.33 |    87.5 |   90.55 | ...58,377,379,381 
  ...sContracts.ts |       0 |        0 |       0 |       0 | 1                 
  ...entHandler.ts |   91.43 |     87.3 |   93.75 |   91.43 | ...50,782-788,833 
  hookPlanner.ts   |   98.79 |    93.33 |     100 |   98.79 | 103               
  hookRegistry.ts  |   97.19 |    88.31 |     100 |   97.19 | ...97,399,401,403 
  hookRunner.ts    |   84.88 |    87.14 |   86.95 |   84.88 | ...37-439,502-505 
  hookSystem.ts    |    64.2 |    88.88 |      65 |    64.2 | ...49-351,364-366 
  ...Translator.ts |   94.11 |    75.67 |     100 |   94.11 | ...68,479,524,529 
  ...Validators.ts |    92.4 |    89.83 |     100 |    92.4 | 57-59,78-80       
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ssion-hook.ts |   88.88 |    33.33 |     100 |   88.88 | 24,30             
  trustedHooks.ts  |   20.77 |      100 |       0 |   20.77 | ...6,82-90,96-109 
  types.ts         |   63.63 |    89.13 |   60.71 |   63.63 | ...08-509,520-521 
 ...oks/test-utils |       0 |        0 |       0 |       0 |                   
  ...igWithHook.ts |       0 |        0 |       0 |       0 | 1-137             
 src/interfaces    |       0 |        0 |       0 |       0 |                   
  index.ts         |       0 |        0 |       0 |       0 |                   
  ....interface.ts |       0 |        0 |       0 |       0 |                   
 src/llm-types     |   99.49 |    97.97 |     100 |   99.49 |                   
  finishReasons.ts |   97.56 |    83.33 |     100 |   97.56 | 153-154           
  geminiContent.ts |       0 |        0 |       0 |       0 |                   
  grounding.ts     |       0 |        0 |       0 |       0 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  jsonSchema.ts    |     100 |      100 |     100 |     100 |                   
  modelEnvelope.ts |     100 |      100 |     100 |     100 |                   
  modelRequest.ts  |       0 |        0 |       0 |       0 |                   
  ...erApiError.ts |     100 |      100 |     100 |     100 |                   
  ...Embeddings.ts |       0 |        0 |       0 |       0 |                   
  toolCall.ts      |     100 |    98.14 |     100 |     100 | 216               
  ...eclaration.ts |     100 |      100 |     100 |     100 |                   
 src/models        |    83.7 |    92.41 |    87.5 |    83.7 |                   
  hydration.ts     |    4.76 |      100 |       0 |    4.76 | 65-129,151-231    
  index.ts         |     100 |      100 |     100 |     100 |                   
  profiles.ts      |     100 |      100 |     100 |     100 |                   
  ...ntegration.ts |   95.34 |    89.74 |     100 |   95.34 | ...36-137,200-201 
  registry.ts      |    91.4 |    88.88 |      92 |    91.4 | ...72-273,392-403 
  schema.ts        |     100 |      100 |     100 |     100 |                   
  transformer.ts   |     100 |      100 |     100 |     100 |                   
 src/parsers       |   80.75 |    80.71 |   92.85 |   80.75 |                   
  ...CallParser.ts |   84.59 |     80.4 |    92.3 |   84.59 | ...09-810,813-814 
  ...rg-parsing.ts |   83.37 |    85.71 |   90.47 |   83.37 | ...23-425,501-502 
  ...ll-helpers.ts |   73.94 |     79.5 |   92.85 |   73.94 | ...07-508,514-535 
  ...rser-utils.ts |      76 |    73.33 |     100 |      76 | ...09-110,114-119 
 src/policy        |    72.9 |    76.19 |   88.46 |    72.9 |                   
  config.ts        |   68.06 |    77.19 |   86.36 |   68.06 | ...25,381,458-459 
  index.ts         |     100 |      100 |     100 |     100 |                   
  policy-engine.ts |     100 |      100 |     100 |     100 |                   
  ...cy-helpers.ts |   88.88 |    66.66 |     100 |   88.88 | 31-39             
  ...-stringify.ts |     100 |      100 |     100 |     100 |                   
  toml-loader.ts   |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
 src/prompt-config |   82.64 |    87.55 |   82.35 |   82.64 |                   
  ...lateEngine.ts |    94.7 |    89.24 |     100 |    94.7 | ...32-435,446-449 
  index.ts         |       0 |      100 |     100 |       0 | 5-41              
  prompt-cache.ts  |    99.1 |    97.43 |     100 |    99.1 | 236-237           
  ...-installer.ts |   83.82 |    81.87 |    92.3 |   83.82 | ...24-831,863-866 
  prompt-loader.ts |   90.93 |    92.56 |   89.65 |   90.93 | ...15-532,542-543 
  ...t-resolver.ts |   50.38 |       84 |      50 |   50.38 | ...22-423,428-527 
  ...pt-service.ts |   85.32 |    83.18 |   80.95 |   85.32 | ...28,545-552,583 
  ...delegation.ts |   93.54 |     90.9 |     100 |   93.54 | 34-35             
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...onfig/defaults |   56.45 |    45.74 |   85.41 |   56.45 |                   
  core-defaults.ts |      48 |     41.5 |   78.57 |      48 | ...55,365,371-379 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...est-loader.ts |   81.81 |    79.31 |     100 |   81.81 | ...02-108,116-120 
  ...t-warnings.ts |    92.3 |    33.33 |     100 |    92.3 | 18-19             
  ...r-defaults.ts |   52.51 |    35.29 |   84.61 |   52.51 | ...24,334,340-345 
  ...e-defaults.ts |     100 |      100 |     100 |     100 |                   
  tool-defaults.ts |   56.05 |     42.3 |   84.61 |   56.05 | ...82-283,295-300 
 ...nfig/installer |   92.11 |    87.63 |   97.61 |   92.11 |                   
  ...resolution.ts |   96.63 |    92.45 |     100 |   96.63 | ...70-271,317-318 
  ...tory-utils.ts |   95.42 |    90.38 |     100 |   95.42 | ...14-117,154,175 
  file-writer.ts   |   78.78 |    73.68 |     100 |   78.78 | 31-32,51-52,69-78 
  ...operations.ts |   97.46 |    94.44 |     100 |   97.46 | 48-49             
  ...-expansion.ts |   82.67 |    81.81 |      90 |   82.67 | ...,70-71,165-172 
 ...onfig/resolver |   36.86 |    60.86 |   51.85 |   36.86 |                   
  ...ry-scanner.ts |    4.04 |      100 |       0 |    4.04 | ...98-159,163-207 
  fs-adapter.ts    |   39.06 |    66.66 |      50 |   39.06 | ...37,42-47,51-88 
  name-utils.ts    |   71.69 |       60 |   78.57 |   71.69 | ...03-204,208-218 
 src/prompts       |      30 |      100 |      25 |      30 |                   
  mcp-prompts.ts   |   28.57 |      100 |       0 |   28.57 | 11-15             
  ...t-registry.ts |   30.23 |      100 |   28.57 |   30.23 | ...43,49-56,69-74 
 src/recording     |    90.2 |     86.2 |   98.09 |    90.2 |                   
  ...ntegration.ts |    83.9 |       75 |     100 |    83.9 | ...31-132,143-144 
  ReplayEngine.ts  |   95.78 |       91 |     100 |   95.78 | ...37-342,502-509 
  ...nDiscovery.ts |   91.62 |    87.75 |     100 |   91.62 | ...44-345,360-361 
  ...ockManager.ts |   86.24 |    83.33 |     100 |   86.24 | ...18,233,260-261 
  ...ingService.ts |   82.97 |    92.45 |   95.65 |   82.97 | ...57,390-391,395 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...st-helpers.ts |   91.12 |       90 |   92.85 |   91.12 | 190-200,227-230   
  resumeSession.ts |   93.19 |    89.65 |     100 |   93.19 | ...10-215,246-247 
  ...eanupUtils.ts |      90 |    69.23 |     100 |      90 | ...40-241,267,280 
  ...Management.ts |   88.23 |    85.71 |     100 |   88.23 | 94,108-112        
  types.ts         |       0 |        0 |       0 |       0 |                   
 src/resources     |   95.23 |     92.3 |     100 |   95.23 |                   
  ...e-registry.ts |   95.23 |     92.3 |     100 |   95.23 | 34-35             
 src/runtime       |   82.62 |    86.64 |   81.25 |   82.62 |                   
  ...imeContext.ts |     100 |      100 |     100 |     100 |                   
  ...timeLoader.ts |   86.85 |    73.68 |   81.81 |   86.85 | ...14,218,244-247 
  ...ntimeState.ts |   95.66 |    90.78 |     100 |   95.66 | ...03-504,544-545 
  ...ionContext.ts |   83.54 |    93.33 |   71.42 |   83.54 | ...55-156,167-174 
  ...imeContext.ts |   76.04 |    98.14 |   62.06 |   76.04 | ...98-303,305-312 
  index.ts         |       0 |        0 |       0 |       0 | 1-19              
  ...imeContext.ts |      70 |       90 |     100 |      70 | 88-108            
  ...meAdapters.ts |   66.66 |    95.23 |    92.3 |   66.66 | 77-111            
  ...ateFactory.ts |    90.9 |    71.42 |     100 |    90.9 | ...93,116,126,139 
  ...imeAdapter.ts |   80.55 |    85.71 |   88.88 |   80.55 | 62-69,84-85,88-93 
 ...time/contracts |       0 |        0 |       0 |       0 |                   
  ...lureReason.ts |       0 |        0 |       0 |       0 | 1                 
  ...kContracts.ts |       0 |        0 |       0 |       0 | 1                 
  ...ningOutput.ts |       0 |        0 |       0 |       0 | 1                 
  ...torFactory.ts |       0 |        0 |       0 |       0 | 1                 
  RuntimeModel.ts  |       0 |        0 |       0 |       0 | 1                 
  ...meProvider.ts |       0 |        0 |       0 |       0 | 1                 
  ...oviderChat.ts |       0 |        0 |       0 |       0 | 1                 
  ...derManager.ts |       0 |        0 |       0 |       0 | 1                 
  ...eTokenizer.ts |       0 |        0 |       0 |       0 | 1                 
  ...zerFactory.ts |       0 |        0 |       0 |       0 | 1                 
  ...tryContext.ts |       0 |        0 |       0 |       0 | 1                 
  index.ts         |       0 |        0 |       0 |       0 | 1                 
 ...runtime/errors |   94.87 |    85.71 |   66.66 |   94.87 |                   
  ...viderError.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-14              
 src/safety        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  pathValidator.ts |     100 |      100 |     100 |     100 |                   
 src/scheduler     |       0 |        0 |       0 |       0 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/services      |   84.74 |    86.28 |   88.83 |   84.74 |                   
  ...ardService.ts |   94.23 |    93.75 |     100 |   94.23 | 70,74-75          
  ...utoTrigger.ts |   97.33 |    95.83 |     100 |   97.33 | 127-128           
  ...askManager.ts |   95.81 |    93.93 |     100 |   95.81 | 151-157,365-366   
  ...derService.ts |   98.98 |    97.05 |     100 |   98.98 | 173               
  ...y-analyzer.ts |   83.51 |    79.85 |   87.09 |   83.51 | ...13-641,647-648 
  ...extManager.ts |     100 |    96.29 |     100 |     100 | 63                
  ...nitization.ts |    98.7 |    96.87 |     100 |    98.7 | 172-173           
  ...eryService.ts |     100 |      100 |     100 |     100 |                   
  ...temService.ts |     100 |      100 |     100 |     100 |                   
  ...ts-service.ts |      50 |      100 |       0 |      50 | 41-42,48-49       
  gitService.ts    |   86.72 |    86.95 |      80 |   86.72 | ...34-137,141-145 
  index.ts         |       0 |        0 |       0 |       0 | 1-23              
  ...ionService.ts |   96.43 |    95.08 |     100 |   96.43 | ...27-428,438-439 
  ...pExecution.ts |   88.42 |    78.57 |   83.33 |   88.42 | 65-66,92-100      
  ...lCpHelpers.ts |   87.83 |    87.75 |     100 |   87.83 | ...91,194,253-259 
  ...ionService.ts |   71.21 |    88.23 |    62.5 |   71.21 | ...83-306,365-378 
  ...utionTypes.ts |       0 |        0 |       0 |       0 | 1                 
  ...lExitGuard.ts |     100 |      100 |     100 |     100 |                   
  ...utputUtils.ts |   95.65 |    95.23 |     100 |   95.65 | 34-35             
  ...rocessKill.ts |   88.57 |    88.88 |     100 |   88.57 | 38-41             
  ...yExecution.ts |   96.15 |    93.33 |     100 |   96.15 | 110-111,132-134   
  ...PtyHelpers.ts |   87.03 |    76.19 |    87.5 |   87.03 | ...22,153-154,210 
  ...yLifecycle.ts |   87.68 |    78.12 |   94.73 |   87.68 | ...21,324,378-380 
  shellPtyState.ts |       0 |        0 |       0 |       0 | 1                 
  ...xt-tracker.ts |   94.87 |    88.88 |   85.71 |   94.87 | 54-55             
  ...er-service.ts |       0 |        0 |       0 |       0 | 1-161             
  ...er-service.ts |   68.47 |    48.48 |      80 |   68.47 | ...85-289,311-314 
 ...rvices/history |   83.89 |    85.92 |   88.27 |   83.89 |                   
  ...Converters.ts |   87.65 |    82.48 |   86.36 |   87.65 | ...19-425,447-448 
  HistoryEvents.ts |       0 |        0 |       0 |       0 |                   
  ...oryService.ts |    85.3 |     88.6 |   86.79 |    85.3 | ...03-704,783-784 
  IContent.ts      |   97.64 |    91.17 |     100 |   97.64 | 309-310           
  ...calToolIds.ts |   96.87 |    93.93 |     100 |   96.87 | 36-37             
  ...ebugLogger.ts |   62.41 |       68 |   85.71 |   62.41 | ...33-145,158-162 
  ...Validation.ts |     100 |      100 |     100 |     100 |                   
  ...CloneUtils.ts |   73.07 |    88.46 |   83.33 |   73.07 | ...98-101,106-118 
  ...textWindow.ts |   91.42 |    55.55 |     100 |   91.42 | 59,61-62          
  ...ryCuration.ts |     100 |      100 |     100 |     100 |                   
  ...EventTypes.ts |       0 |        0 |       0 |       0 |                   
  ...erPipeline.ts |     100 |      100 |     100 |     100 |                   
  historyQuery.ts  |   63.63 |       50 |     100 |   63.63 | 27-30             
  ...Estimation.ts |   44.68 |    82.14 |      50 |   44.68 | ...87-196,202-251 
  ...zerAdapter.ts |     100 |     87.5 |     100 |     100 | 73                
  ...malization.ts |    91.7 |    87.12 |     100 |    91.7 | ...26-431,477-485 
  ...oolPairing.ts |   98.59 |     87.5 |     100 |   98.59 | 103               
 src/skills        |   73.86 |       80 |   77.14 |   73.86 |                   
  skillLoader.ts   |   59.42 |    78.94 |   76.92 |   59.42 | ...16-351,363-373 
  skillManager.ts  |   89.68 |    80.88 |   77.27 |   89.68 | ...94-395,401-402 
 src/storage       |   98.69 |    96.87 |     100 |   98.69 |                   
  ...FileWriter.ts |     100 |      100 |     100 |     100 |                   
  ...nceService.ts |   98.65 |    96.87 |     100 |   98.65 | 291-292           
  ...ey-storage.ts |     100 |      100 |     100 |     100 |                   
  secure-store.ts  |     100 |      100 |     100 |     100 |                   
  sessionTypes.ts  |     100 |      100 |     100 |     100 |                   
 src/telemetry     |   15.45 |        0 |       0 |   15.45 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...-exporters.ts |       0 |        0 |       0 |       0 | 1-6               
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-17              
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-110             
  loggers.ts       |     100 |      100 |     100 |     100 |                   
  metrics.ts       |     100 |      100 |     100 |     100 |                   
  sdk.ts           |     100 |      100 |     100 |     100 |                   
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  uiTelemetry.ts   |     100 |      100 |     100 |     100 |                   
 src/test-utils    |   53.21 |    58.82 |   20.86 |   53.21 |                   
  config.ts        |   83.07 |    85.71 |   15.21 |   83.07 | ...,91-96,173-176 
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  mock-tool.ts     |       0 |        0 |       0 |       0 | 1-159             
  ...aceContext.ts |       0 |        0 |       0 |       0 | 1-32              
  ...allOptions.ts |   81.62 |    51.61 |   54.54 |   81.62 | ...83,196,225-228 
  runtime.ts       |   47.03 |    33.33 |    8.82 |   47.03 | ...17-279,287-350 
  tools.ts         |   45.94 |    81.81 |   38.09 |   45.94 | ...15-227,230-237 
 src/todo          |   12.86 |      100 |       0 |   12.86 |                   
  todoFormatter.ts |   12.86 |      100 |       0 |   12.86 | ...03,206-219,222 
 src/tools         |   81.61 |    81.15 |      92 |   81.61 |                   
  ...ey-storage.ts |   81.61 |    81.15 |      92 |   81.61 | ...31-436,445-450 
 ...tools-adapters |   46.39 |    72.31 |   36.09 |   46.39 |                   
  ...iceAdapter.ts |   61.22 |    83.33 |    62.5 |   61.22 | ...52,55-60,65-68 
  ...iceAdapter.ts |   27.58 |      100 |      40 |   27.58 | 21-26,29-37,40-45 
  ...iceAdapter.ts |   22.58 |      100 |      40 |   22.58 | 18-25,28-43,46-47 
  ...iceAdapter.ts |   13.95 |      100 |       0 |   13.95 | ...76,79-80,83-98 
  ...BusAdapter.ts |   73.07 |     90.9 |   81.81 |   73.07 | ...02-126,145-151 
  ...iceAdapter.ts |      60 |        0 |       0 |      60 | ...27,36-37,40-41 
  ...iceAdapter.ts |   53.84 |      100 |      40 |   53.84 | 17-18,21-22,26-27 
  ...ostAdapter.ts |   19.33 |      100 |    8.69 |   19.33 | ...25-241,244-246 
  ...iceAdapter.ts |   15.58 |        0 |       0 |   15.58 | ...9,82-84,87-102 
  ...iceAdapter.ts |   52.94 |      100 |       0 |   52.94 | ...18,21-22,25-26 
  ...iceAdapter.ts |    52.5 |    67.02 |   65.51 |    52.5 | ...43-886,891-894 
  ...iceAdapter.ts |   68.18 |       50 |      50 |   68.18 | 32-36,39-40       
  ...ostAdapter.ts |   30.18 |      100 |   13.04 |   30.18 | ...83-189,192-193 
  ...ageAdapter.ts |   46.15 |      100 |       0 |   46.15 | ...33,36-37,40-41 
  ...ostAdapter.ts |   67.74 |      100 |   54.54 |   67.74 | ...57,60-61,64-65 
  ...iceAdapter.ts |      50 |      100 |   66.66 |      50 | 19-23             
  ...iceHelpers.ts |    56.2 |       50 |      70 |    56.2 | ...90-191,195-196 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/utils         |   84.05 |    86.44 |   85.12 |   84.05 |                   
  LruCache.ts      |    82.6 |      100 |   71.42 |    82.6 | 29-30,33-34       
  asyncIterator.ts |   73.07 |    84.61 |   66.66 |   73.07 | ...71,75-86,93-94 
  bfsFileSearch.ts |   93.61 |    92.85 |     100 |   93.61 | 36-44             
  browser.ts       |    8.69 |      100 |       0 |    8.69 | 17-53             
  bunPtyAdapter.ts |   88.76 |    84.78 |   84.21 |   88.76 | ...27-532,551-554 
  channel.ts       |     100 |      100 |     100 |     100 |                   
  ...pointUtils.ts |      95 |    91.66 |     100 |      95 | 144-151           
  debugLogger.ts   |     100 |      100 |     100 |     100 |                   
  delay.ts         |     100 |      100 |     100 |     100 |                   
  editor.ts        |   95.47 |    90.38 |    90.9 |   95.47 | ...38-239,241-242 
  ...entContext.ts |     100 |      100 |     100 |     100 |                   
  errorParsing.ts  |   92.12 |     87.5 |   95.65 |   92.12 | ...87,218,302-303 
  ...rReporting.ts |   82.35 |       75 |     100 |   82.35 | ...40-142,150-155 
  errors.ts        |   70.12 |    94.73 |   31.25 |   70.12 | ...27-128,189-213 
  events.ts        |   67.54 |      100 |    64.7 |   67.54 | ...41-346,352-355 
  exitCodes.ts     |     100 |      100 |     100 |     100 |                   
  ...sionLoader.ts |   80.98 |    63.88 |   92.85 |   80.98 | ...70-171,224-232 
  fetch.ts         |   24.32 |      100 |       0 |   24.32 | 23-28,32-86,89-90 
  fileDiffUtils.ts |   94.87 |     90.9 |     100 |   94.87 | 25-26             
  fileUtils.ts     |   93.83 |    90.06 |   95.23 |   93.83 | ...00,469,503-509 
  formatters.ts    |   18.18 |      100 |       0 |   18.18 | 8-16              
  ...eUtilities.ts |   91.17 |    80.19 |   94.11 |   91.17 | ...77-381,415-425 
  ...rStructure.ts |   95.57 |    94.59 |     100 |   95.57 | ...15-216,376-381 
  getPty.ts        |   73.07 |       75 |      50 |   73.07 | 43-49             
  ...noreParser.ts |     100 |      100 |     100 |     100 |                   
  ...ineChanges.ts |       0 |        0 |       0 |       0 | 1-348             
  gitUtils.ts      |   42.55 |    71.42 |      50 |   42.55 | 32-33,40-44,53-80 
  googleErrors.ts  |   77.01 |    73.21 |     100 |   77.01 | ...08,346-347,364 
  ...uotaErrors.ts |   94.94 |    87.25 |     100 |   94.94 | ...76-277,315-316 
  ide-trust.ts     |      60 |      100 |       0 |      60 | 14-15             
  ...rePatterns.ts |     100 |    96.55 |     100 |     100 | 257               
  ...ionManager.ts |     100 |    88.88 |     100 |     100 | 24                
  ...edit-fixer.ts |       0 |        0 |       0 |       0 | 1-158             
  ...yDiscovery.ts |   83.84 |    79.71 |   82.35 |   83.84 | ...42-743,757-768 
  ...tProcessor.ts |   97.19 |    91.86 |   94.44 |   97.19 | ...11-312,406-407 
  ...Inspectors.ts |       0 |        0 |       0 |       0 | 1-39              
  output-format.ts |      40 |      100 |      25 |      40 | ...58-159,169-190 
  package.ts       |     100 |      100 |     100 |     100 |                   
  ...erCoercion.ts |   80.89 |       80 |     100 |   80.89 | ...47-348,351-352 
  partUtils.ts     |   97.29 |    95.65 |     100 |   97.29 | 53-54             
  pathReader.ts    |   22.58 |      100 |       0 |   22.58 | ...22,28-29,41-60 
  paths.ts         |   84.35 |    85.54 |   78.94 |   84.35 | ...91-292,307-317 
  ...rDetection.ts |   52.05 |    78.94 |   83.33 |   52.05 | ...03-104,114-115 
  refusalNotice.ts |     100 |      100 |     100 |     100 |                   
  ...archTarget.ts |   89.58 |    69.23 |     100 |   89.58 | 45-47,65-66       
  retry.ts         |   83.58 |    86.34 |   92.59 |   83.58 | ...58-961,966-967 
  ...thResolver.ts |     100 |      100 |     100 |     100 |                   
  runtime.ts       |     100 |      100 |     100 |     100 |                   
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  sanitization.ts  |     100 |      100 |     100 |     100 |                   
  ...aValidator.ts |   91.22 |    76.36 |     100 |   91.22 | ...51-352,368-379 
  ...r-launcher.ts |   90.29 |    81.81 |     100 |   90.29 | ...92,210,212-213 
  session.ts       |     100 |      100 |     100 |     100 |                   
  shell-parser.ts  |   87.64 |    80.53 |     100 |   87.64 | ...99-600,669-670 
  shell-utils.ts   |   85.99 |     92.7 |      88 |   85.99 | ...51-652,814-822 
  ...Completion.ts |   94.21 |    92.15 |     100 |   94.21 | 71-77             
  stdio.ts         |   83.83 |    56.52 |     100 |   83.83 | ...25-129,138-142 
  ...dleTimeout.ts |   98.24 |    93.93 |     100 |   98.24 | 101-102           
  summarizer.ts    |   98.03 |       90 |     100 |   98.03 | 95                
  ...emEncoding.ts |   94.96 |    88.88 |     100 |   94.96 | ...10,142-143,197 
  terminal.ts      |   34.09 |      100 |       0 |   34.09 | ...55,58-59,62-66 
  ...Serializer.ts |    98.2 |    92.75 |     100 |    98.2 | ...,98-99,181-183 
  testUtils.ts     |      50 |      100 |   33.33 |      50 | ...47,53-58,64-66 
  textUtils.ts     |    12.5 |      100 |       0 |    12.5 | 15-34             
  thoughtUtils.ts  |     100 |      100 |     100 |     100 |                   
  tool-utils.ts    |   68.64 |    77.77 |      80 |   68.64 | ...34-135,156-180 
  ...putLimiter.ts |   95.14 |    81.63 |     100 |   95.14 | ...5-66,78-79,113 
  unicodeUtils.ts  |     100 |      100 |     100 |     100 |                   
  ...untManager.ts |   88.52 |    86.48 |     100 |   88.52 | ...,83-88,104-106 
  version.ts       |     100 |      100 |     100 |     100 |                   
  ...aceContext.ts |   96.85 |    95.23 |    92.3 |   96.85 | 95-96,110-111     
 ...ils/filesearch |   89.81 |    91.52 |   94.59 |   89.81 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |    84.9 |    85.71 |   66.66 |    84.9 | ...12-114,128-133 
  fileSearch.ts    |   86.48 |    89.21 |     100 |   86.48 | ...11-312,360-361 
  ignore.ts        |     100 |      100 |     100 |     100 |                   
  result-cache.ts  |     100 |      100 |     100 |     100 |                   
-------------------|---------|----------|---------|---------|-------------------

For detailed HTML reports, please see the 'coverage-reports-24.x-ubuntu-latest' artifact from the main CI run.

Comment on lines +212 to +213
const source = [
`const REDACTION = '${redactionMatch[1] ?? ''}';`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fallback redactionMatch[1] ?? '' only guards against null/undefined. If the REDACTION constant is accidentally emptied (e.g., const REDACTION = '';), the captured group would be '' (not null), so the ?? won't trigger. This would inject an empty REDACTION constant into the VM, causing redactSecretDiagnostics to silently produce no redactions — masking a security regression. Consider validating that the captured value is non-empty, e.g., expect(redactionMatch[1], 'REDACTION constant should be non-empty').toBeTruthy(); before using it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 10d8b31: the helper now asserts the REDACTION constant is non-empty before constructing the VM source.

Comment on lines +261 to +263
export function runNotifySanitizer(notifyRun, input, token) {
try {
return executeNotifySanitizer(notifyRun, input, token).replace(/\n$/, '');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

runNotifySanitizer does not forward extraEnv to executeNotifySanitizer, so callers cannot test URL redaction (via OCR_LLM_URL) through this wrapper. This is inconsistent with makePostSanitizer, which accepts a url parameter. Consider adding an extraEnv parameter (or a url parameter) to runNotifySanitizer and passing it through, so the notify-path redaction tests can verify URL redaction just like the post-path tests do.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 10d8b31: runNotifySanitizer now forwards extra environment values, and the notify sanitizer has URL redaction coverage.

Comment thread .github/workflows/ocr-review.yml Outdated
Comment on lines +807 to +809
...stderrSection('OCR stderr excerpt', 'ocr-stderr.log'),
'',
...stderrSection('OCR preview stderr excerpt', 'ocr-preview-stderr.log'),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Risk: The stderrSection function posts up to 40 lines / 4000 chars of raw stderr content into PR comments after applying redactSecretDiagnostics. The redaction relies on regex patterns for known secret formats (Authorization headers, api_key=, token=, etc.) plus exact-string matching for OCR_LLM_TOKEN and OCR_LLM_URL. However, if the OCR CLI or npm logs the LLM token or URL in a format not covered by these regexes (e.g., as a URL query parameter like ?key=..., inside a JSON payload, within a stack trace, or as a bare value on a line), the secret would be publicly exposed in the PR comment visible to all collaborators.

Suggestion: Consider one or more of the following mitigations:

  1. Only include stderr excerpts when an infrastructure failure is actually detected (i.e., gate stderrSection calls behind if (infrastructureFailure) or if (!ran)).
  2. Add additional regex patterns for common LLM API URL formats (e.g., \b(key|api[_-]?key|token)\s*[=&]\s*[^\s&]+ for query parameters).
  3. Apply a stricter approach: only post stderr lines that match known diagnostic patterns rather than posting a broad excerpt of all stderr content.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 10d8b31: stderr excerpts are now only added to the PR summary when OCR did not run cleanly or an infrastructure diagnostic exists, and query-parameter key/token patterns are redacted.

Comment thread .github/workflows/ocr-review.yml Outdated
Comment on lines +309 to +312
mark_policy_failure() {
echo "$1" > ocr-policy-failure.txt
: > ocr-infrastructure-failure.txt
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic Issue: mark_policy_failure truncates ocr-infrastructure-failure.txt with : > ocr-infrastructure-failure.txt, which silently erases any infrastructure failure diagnostic recorded earlier in the run (e.g., during the install step). If both an infrastructure failure and a policy failure occur in the same run, the infrastructure diagnostic is lost, making root-cause debugging harder and potentially causing the notify job to misclassify the failure as policy-only.

Suggestion: Preserve the infrastructure failure diagnostic instead of truncating it, or append the policy failure context to a combined diagnostic.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 10d8b31: policy failure marking no longer truncates the infrastructure diagnostic file.

ocr-phase.txt
ocr-infrastructure-failure.txt
ocr-policy-failure.txt
if-no-files-found: warn

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reliability Issue: if-no-files-found was changed from error to warn. While this prevents job failure when artifacts are missing (expected when early setup fails), it also masks cases where expected files like ocr-result.json should exist but don't after a successful OCR run. This reduces visibility into artifact collection failures.

Suggestion: If the intent is to allow missing artifacts during degraded runs, consider keeping warn but add a follow-up check or log message that flags when ocr-result.json is missing and exitCode === 0 (i.e., a successful run that should have produced output).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 10d8b31: the notify job now treats a missing OCR result artifact after a zero-exit review as an infrastructure diagnostic.

Comment on lines +1062 to +1071
create_infrastructure_issue() {
local issue_body_file
issue_body_file="$1"
shift
if retry_gh gh issue create "$@" --body-file "$issue_body_file" --label "ci/cd"; then
return 0
fi
echo "::warning::Failed to create OCR infrastructure issue with ci/cd label; retrying without labels."
retry_gh gh issue create "$@" --body-file "$issue_body_file" || echo "::warning::Failed to create OCR infrastructure issue."
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The notify-ocr-infrastructure-failure job does cd ocr-review-output (line 978) before calling gh issue create and gh issue comment without the --repo flag. The gh CLI infers the target repository from the git remote of the current working directory, but ocr-review-output is a downloaded-artifact subdirectory with no .git repo. This means gh will either fail to determine the repository or walk up to a parent .git that may not correspond to ${{ github.repository }}. Pass --repo "${{ github.repository }}" explicitly (or set GH_REPO env var) to all gh issue create and gh issue comment calls to ensure issues are always created in the correct repository.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit af0f119: the notify step now sets GH_REPO from github.repository so gh issue commands resolve the intended repository even after changing directories.

Comment on lines +1094 to +1095
retry_gh gh issue comment "${EXISTING_ISSUE}" --body-file "$body_file" || echo "::warning::Failed to comment on OCR infrastructure issue."
return 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, gh issue comment calls lack --repo. Since the working directory was changed to ocr-review-output, the gh CLI may not correctly resolve the target repository. Add --repo to both gh issue comment calls.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit af0f119: GH_REPO is now set for the notify step, which covers the gh issue comment calls as well.

Comment on lines +947 to +952
if (length($secret) > 0) {
s/\Q$secret\E/$redaction/g;
}
if (length($url) > 0) {
s/\Q$url\E/$redaction/g;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Perl redaction uses \Q$secret\E for literal escaping. If the secret value itself contains the sequence \E, Perl will terminate the literal quoting early, causing the remainder of the secret to be interpreted as regex metacharacters. This could result in regex errors (causing sanitization to fail) or incomplete redaction, potentially leaking the secret into a GitHub issue body that is publicly visible. Consider handling \E within the secret by splitting and re-quoting, or use a non-regex string replacement approach (e.g., iterating character by character or using index/substr).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit af0f119: the Perl sanitizer now uses quotemeta before exact-value substitution, and the notify redaction test covers a secret containing the E-escape sequence.

Comment on lines +454 to 457
OCR_LLM_TOKEN: ${{ secrets.OCR_LLM_AUTH_TOKEN }}
OCR_LLM_URL: ${{ vars.OCR_LLM_URL }}
with:
script: |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OCR_LLM_TOKEN secret is now passed to the Post OCR results github-script step's environment, which previously did not receive it. While it is used for redaction purposes, this increases the secret's exposure surface — if the script encounters an unhandled exception and dumps process.env, or if a future modification inadvertently logs environment variables, the secret would be exposed in the workflow logs. Consider whether the redaction can be performed without having the raw secret in this step's environment, or add a comment documenting why this is necessary and that process.env must never be logged from this step.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit af0f119: added an explicit workflow note that the OCR endpoint and credential environment values are provided only for redaction and process.env must not be logged from that step.

Comment thread .github/workflows/ocr-review.yml Outdated
Comment on lines +1014 to +1017
elif [ "${CODE_REVIEW_RESULT:-}" = "failure" ]; then
phase="artifact"
infra_failure="phase=artifact; reason=OCR artifacts were unavailable after code-review failed"
echo "::warning::OCR artifacts were unavailable after code-review failed; creating infrastructure notification."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The notify-ocr-infrastructure-failure job's elif branch creates a false-positive infrastructure issue when CODE_REVIEW_RESULT == "failure" and artifacts are unavailable. If the code-review job failed due to a policy failure (e.g., exit 1 in the preview step at line 393 or 401) but the artifact upload itself failed or was skipped, the policy_failure variable will be empty (since artifacts are unavailable), the infra_failure will be set to 'OCR artifacts were unavailable after code-review failed', and the early-return policy check at line 1022 won't trigger. This results in a misleading infrastructure failure issue being created for what was actually a policy violation.

Suggestion: Before entering the elif branch, consider whether the code-review job could have failed for policy reasons. One approach: pass an additional output from the code-review job (via outputs: in the job definition) indicating whether it was a policy failure, and check that output here before creating an infrastructure issue.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 18cea0a: code-review now exposes a policy_failure job output and the notify job checks it before creating missing-artifact infrastructure notifications.

Comment thread .github/workflows/ocr-review.yml Outdated
Comment on lines +192 to +195
mark_infrastructure_failure() {
echo "phase=$1; reason=$2" > ocr-infrastructure-failure.txt
}
OCR_PREFIX="${RUNNER_TEMP}/ocr-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mark_infrastructure_failure bash function is defined identically in four separate steps (install, validate, preview, review). This violates DRY — if the function signature or behavior needs to change, it must be updated in four places. Consider extracting it into a shared script file or sourcing a common helper to reduce maintenance burden and the risk of drift between implementations.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 18cea0a: the repeated mark_infrastructure_failure shell function is now generated once in the initialization step and sourced by the OCR install, validate, preview, and review steps.

ocr-phase.txt
ocr-infrastructure-failure.txt
ocr-policy-failure.txt
if-no-files-found: warn

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if-no-files-found setting was changed from error to warn. This means if the job fails so early that no artifact files are produced, the workflow will not fail on the upload step, and the downstream notify-ocr-infrastructure-failure job will receive no artifacts. While the notify job handles missing artifacts, reducing the upload failure from error to warn decreases visibility into cases where the workflow is fundamentally broken and produces no output at all. Consider keeping if-no-files-found: error (or at minimum warn with an additional explicit check) to surface early-stage failures more prominently.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 18cea0a: retained warning-only artifact upload per issue scope, with explicit notify-job checks for missing diagnostics, zero-exit missing OCR result artifacts, and policy-failure classification to avoid misleading infrastructure issues.

Comment on lines +363 to +369
it('redacts exact OCR secrets with regex metacharacters and backslashes in notify diagnostics', () => {
const notifyRun = commandText(
stepNamed(
workflow.jobs?.['notify-ocr-infrastructure-failure'],
'Notify OCR infrastructure failure issue',
),
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pattern commandText(stepNamed(workflow.jobs?.['notify-ocr-infrastructure-failure'], 'Notify OCR infrastructure failure issue')) is repeated 6 times across tests (lines 364-369, 383-388, 405-410, 425-430, 440-444, 716-720). Consider extracting the notify job and notify step into shared variables in the beforeAll block (e.g., notifyJob and notifyStep), similar to how codeReviewJob is already shared. This reduces duplication and makes the tests more maintainable.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 4178e53: notify job, notify step, and notify script text are now initialized once in beforeAll and reused by the workflow tests.

'REDACTION constant should be non-empty',
).toBeTruthy();
const source = [
`const REDACTION = '${redactionMatch[1]}';`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The REDACTION value extracted from redactionMatch[1] is interpolated directly into a JavaScript string literal without escaping. If the value ever contains a backslash (e.g., \ or \n), the string's semantics change when re-interpreted in the VM context — a literal \n becomes a newline escape, \' could break the string boundary, etc. While the current [REDACTED] constant is safe, this is a latent injection/semantic-corruption bug. Consider using JSON.stringify(redactionMatch[1]) to safely embed the value, e.g., const REDACTION = ${JSON.stringify(redactionMatch[1])};.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 4178e53: the extracted REDACTION constant is now embedded with JSON.stringify before running the sanitizer in the VM context.

Comment on lines +165 to +169
function startsRegexLiteral(source, index) {
return '({[=,:;!&|?+-*%^~<>)]'.includes(
previousSignificantChar(source, index),
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

previousSignificantChar returns '' when no significant character is found (e.g., at the start of source). In startsRegexLiteral, '({[=,:;!&amp;|?+-*%^~&lt;&gt;)]'.includes('') always returns true because String.prototype.includes('') matches any string. This accidentally produces the correct result (a / at the start of source should start a regex), but the behavior is non-obvious and fragile. If previousSignificantChar is ever refactored to return null or undefined, includes(null) / includes(undefined) would return false, silently breaking regex detection. Consider returning null from previousSignificantChar and explicitly checking for it: const prev = previousSignificantChar(source, index); return prev === null || '({[=,:;!&amp;|?+-*%^~&lt;&gt;)]'.includes(prev);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 4178e53: previousSignificantChar now returns null when no character exists, and startsRegexLiteral handles that case explicitly.

Comment on lines +78 to +81
concurrency:
group: >-
ocr-review-${{ github.event.pull_request.number || github.event.issue.number || inputs.pr_number }}
cancel-in-progress: true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the code-review job is missing from the workflow YAML, codeReviewJob will be undefined. Tests that directly access codeReviewJob.concurrency (line 49) would throw an unhelpful TypeError: Cannot read properties of undefined instead of a clear assertion failure. Add an existence check here, consistent with the file's other defensive assertions (e.g., the workflow &amp;&amp; typeof workflow === 'object' check above).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit 4178e53: beforeAll now asserts that the code-review job exists before any tests access its properties.

Comment on lines +610 to +614
const notifyStep = stepNamed(
notifyJob,
'Notify OCR infrastructure failure issue',
);
const notifyRun = normalize(commandText(notifyStep));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable shadowing: notifyStep and notifyRun are redeclared as local const inside this test, shadowing the outer let variables with the same names from beforeAll. This is confusing — readers may think the test uses the outer-scope variables, and it increases the risk of bugs if the test is modified. The outer notifyRun is not normalized (raw commandText output), while this local one is normalized via normalize(commandText(notifyStep)). The subsequent test 'uses UTC dates, backoff retries, and label fallback for infrastructure issues' at line 697 uses the outer notifyRun (non-normalized) and applies normalize() separately. Consider renaming the local variables (e.g., localNotifyStep, normalizedNotifyRun) to avoid shadowing and make the scope distinction explicit.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in commit HEAD after the latest amend: the test now uses the shared notifyStep and notifyRun variables instead of redeclaring/shadowing them locally.

Comment on lines +441 to 444
if [ "$status" -ne 0 ]; then
mark_infrastructure_failure "review" "OCR review command failed"
fi
exit 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All infrastructure failures (OCR installation, command-not-found, version check, configuration validation, preview command failure, and review command failure) use exit 0 with ::warning:: instead of failing the job. Only policy failures (changed test files missing/excluded from review) call core.setFailed. This means if OCR cannot install or the LLM endpoint is unreachable, the workflow will succeed silently and PRs could merge without any automated code review — defeating the entire purpose of this workflow.

Consider making infrastructure failures fail the job (e.g., core.setFailed) or at minimum fail the check, while keeping the diagnostic posting and artifact upload via if: always(). The notify-ocr-infrastructure-failure job is a good mitigation for visibility, but it does not prevent unreviewed PRs from merging.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: issue 2431 explicitly requires OCR infrastructure/provider/script failures to be non-blocking PR checks. The workflow still surfaces these via warnings, sticky PR diagnostics, artifacts, and a deduplicated ci/cd issue notification, while changed-test policy failures remain blocking.

ocr-phase.txt
ocr-infrastructure-failure.txt
ocr-policy-failure.txt
if-no-files-found: warn

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if-no-files-found was changed from error to warn. If the workflow's own diagnostic files (ocr-exit-code.txt, ocr-phase.txt, etc.) are missing, the artifact upload silently succeeds with a warning. This reduces visibility when the error-tracking mechanism itself fails, making it harder to debug infrastructure failures through artifacts. Since this step runs with if: always() after diagnostic steps, most files should exist — but if they don't, that itself is a signal worth surfacing as an error.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: issue 2431 requires missing/pre-initialization artifact cases to avoid failing the PR check. Visibility is preserved by the notify job, which detects missing or incomplete OCR diagnostics and opens/comments on the deduplicated ci/cd infrastructure issue.

Comment on lines +276 to +281
} catch (error) {
const stderr = error.stderr ? String(error.stderr) : '';
throw new Error(`Notify sanitizer execution failed. stderr:\n${stderr}`, {
cause: error,
});
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thrown error message only includes stderr text but omits error.status and error.code, which are valuable for debugging failed sanitizer executions (e.g., distinguishing a non-zero exit from a signal termination). Consider including these in the error message.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the latest amended commit: notify sanitizer failures now include status, code, signal, and stderr in the thrown error, with a regression assertion covering those fields.

'',
);
} catch (error) {
const stderr = error && error.stderr ? String(error.stderr) : '';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent null-checking pattern: the catch block accesses error.stderr directly via error &amp;&amp; error.stderr ? String(error.stderr) : '', while the very next lines use the dedicated errorField() helper for status, code, and signal. The direct access pattern bypasses the typeof error === 'object' and fieldName in error guards that errorField provides. For consistency and safety, use errorField(error, 'stderr') here as well.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the latest amended commit: stderr extraction now uses the same guarded errorField helper as status, code, and signal.

Comment thread .github/workflows/ocr-review.yml Outdated
Comment on lines +510 to +511
.replace(/\b(token\s*[=:]\s*)([^\s,;&]+)/gi, '$1[REDACTED]')
.replace(/\b(secret\s*[=:]\s*)([^\s,;&]+)/gi, '$1[REDACTED]');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generic redaction patterns \b(token\s*[=:]\s*) and \b(secret\s*[=:]\s*) are overly broad and will false-positive on non-credential contexts in diagnostic output. For example, a stderr log line like token=expired or secret mode=enabled would be redacted even though these are not secrets. This could make infrastructure failure diagnostics confusing or unhelpful when troubleshooting. Consider tightening these patterns (e.g., requiring a minimum length for the matched value, or restricting to more specific contexts like api_token=, auth_token=, client_secret=) to reduce false positives while still catching common credential leaks.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the latest amended commit: the JS sanitizer now requires generic token and secret values to look credential-like with a minimum length, while preserving exact-secret and specific token-pattern redaction.

Comment thread .github/workflows/ocr-review.yml Outdated
Comment on lines +976 to +977
s/\b(token\s*[=:]\s*)([^\s,;&]+)/$1$redaction/gi;
s/\b(secret\s*[=:]\s*)([^\s,;&]+)/$1$redaction/gi;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same overly broad token= and secret= patterns are duplicated in the Perl sanitizer. Consider applying the same tightening here for consistency with the JS redaction function.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the latest amended commit: the Perl sanitizer now applies the same tightened generic token and secret value pattern as the JS sanitizer.

echo "install" > ocr-phase.txt
. ./ocr-workflow-helpers.sh
OCR_PREFIX="${RUNNER_TEMP}/ocr-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
if ! npm install --prefix "$OCR_PREFIX" --ignore-scripts @alibaba-group/open-code-review@1.6.1 2>> ocr-stderr.log; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The npm install step does not use any caching mechanism. Each workflow run performs a fresh npm install --prefix which downloads the package and its dependencies. Given the 45-minute timeout and that this runs on every PR review trigger, adding npm caching (e.g., actions/cache keyed on the package name and version, or npm's built-in cache) could improve workflow execution time and reduce flakiness from transient network issues during package download.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: deterministic per-run installation under RUNNER_TEMP is part of the issue 2431 requirement, and adding a new cache layer is a broader performance optimization outside this fix. The install remains pinned and non-updating.

Comment on lines +291 to +296
'Authorization\\s*:\\s*(?:(?:Bearer|Basic|token|ApiKey)\\s+)?',
'x-api-key\\s*:\\s*',
'api[_-]?key\\s*[=:]\\s*',
'[?&](?:key|api[_-]?key|token)=',
'token\\s*[=:]\\s*',
'access[_-]?token\\s*[=:]\\s*',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expectContainsAll assertion list for the PR diagnostics script is missing the refresh[_-]?token, id[_-]?token, and secret regex patterns that are present in the workflow YAML (lines 508-511) and tested for redaction via expectCommonCredentialsRedacted in the helper file. The same omission exists in the notify diagnostics test at line 437-453. If someone removes these three redaction regex patterns from the workflow YAML, the structural expectContainsAll tests won't catch it directly — only the functional redaction tests would catch it indirectly. For consistency and completeness, add these patterns to both assertion lists.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the latest amended commit: the PR diagnostic structural assertions now include refresh token, ID token, secret, and the tightened generic credential-value pattern.

Comment on lines +291 to +296
'Authorization\\s*:\\s*(?:(?:Bearer|Basic|token|ApiKey)\\s+)?',
'x-api-key\\s*:\\s*',
'api[_-]?key\\s*[=:]\\s*',
'[?&](?:key|api[_-]?key|token)=',
'token\\s*[=:]\\s*',
'access[_-]?token\\s*[=:]\\s*',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same omission as in the PR diagnostics test: the refresh[_-]?token, id[_-]?token, and secret redaction regex patterns are present in the workflow YAML's Perl sanitizer but are missing from this expectContainsAll assertion list. The expectCommonCredentialsRedacted helper verifies all three are redacted, but if the corresponding regex patterns are removed from the workflow YAML, only the functional test (not this structural test) would detect the regression. Add the missing patterns for consistency.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the latest amended commit: the notify diagnostic structural assertions now include refresh token, ID token, secret, and the tightened generic credential-value pattern.

Comment on lines +286 to 290
if [ "$missing" -ne 0 ]; then
echo "78" > ocr-exit-code.txt
mark_infrastructure_failure "validate" "OCR configuration is missing required variables or secrets"
exit 0
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing required secrets/variables (OCR_LLM_URL, OCR_LLM_TOKEN, OCR_LLM_MODEL) now exits 0 instead of exit 1. If the 'code-review' job is a required status check in branch protection rules, PRs can be merged without any OCR review when secrets are accidentally removed or misconfigured. The only downstream signal is a GitHub issue created by the notify job, which depends on someone actively monitoring those issues. Consider whether infrastructure failures from missing configuration should at least fail the job (or use a separate, non-blocking status check) rather than silently succeeding, so that the absence of OCR review is visible in the PR status checks.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: issue 2431 explicitly requires OCR provider/configuration/infrastructure failures to be non-blocking. The workflow records the phase and exit code, posts PR diagnostics, uploads artifacts, and notifies the deduplicated ci/cd issue while keeping changed-test policy failures blocking.

Comment thread .github/workflows/ocr-review.yml Outdated
Comment on lines +309 to +312
. ./ocr-workflow-helpers.sh
mark_policy_failure() {
echo "$1" > ocr-policy-failure.txt
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mark_policy_failure() is defined inline in this step's run: block (line 310-312) rather than in the sourced ocr-workflow-helpers.sh helper file where mark_infrastructure_failure() lives. This is inconsistent and creates a maintainability hazard: if another step ever needs to call mark_policy_failure, it won't be available unless redefined. Consider moving mark_policy_failure into ocr-workflow-helpers.sh alongside mark_infrastructure_failure so all shared diagnostic helpers are in one place.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the latest amended commit: mark_policy_failure now lives in ocr-workflow-helpers.sh next to mark_infrastructure_failure and is sourced by the preview step.

Comment on lines +1134 to +1136
create_infrastructure_issue "$body_file" \
--title "${ISSUE_TITLE}"
return 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The notify job uses concurrency: cancel-in-progress: false, meaning concurrent infrastructure failures from different PRs all run to completion. There is a TOCTOU race between the first gh issue list search (line 1095) and gh issue create (line 1134): two concurrent jobs could both fail to find an existing issue and both create new duplicate issues. The recheck before create (line 1120) mitigates but does not fully eliminate the race. Consider using gh issue create --search to atomically search-or-create, or add a final post-create deduplication step that closes duplicate issues with the same title.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: the notify job uses a single repository-wide concurrency group with cancel-in-progress false, so GitHub serializes these notifications rather than running them concurrently. The existing recheck before create remains as an additional duplicate guard.

Comment on lines +167 to +169
return (
previousChar === null || '({[=,:;!&|?+-*%^~<>)]'.includes(previousChar)
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

) is included in the set of characters that can precede a regex literal, but in JavaScript expression context, )/ is typically division (e.g., (a + b) / c), not a regex start. A regex can only follow ) after control-flow statement parentheses (if, while, for, etc.). Including ) here could cause the parser to incorrectly treat division after a closing parenthesis as a regex literal, potentially skipping characters and producing incorrect function body extraction. This is a latent issue that doesn't affect the current workflow code but could cause subtle bugs if the parsed code changes.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the latest amended commit: regex-literal detection no longer treats a closing parenthesis as a regex-start context, and the extractor test now covers division after a parenthesized expression.

Comment thread .github/workflows/ocr-review.yml Outdated
Comment on lines +1056 to +1071
stderr_excerpt=""
if [ -f ocr-stderr.log ]; then
raw_stderr_excerpt="$(head -c 2000 ocr-stderr.log)"
if ! stderr_excerpt="$(sanitize_diagnostics "$raw_stderr_excerpt")"; then
echo "::warning::Failed to sanitize OCR stderr diagnostic; skipping notification."
return 1
fi
fi
preview_stderr_excerpt=""
if [ -f ocr-preview-stderr.log ]; then
raw_preview_stderr_excerpt="$(head -c 2000 ocr-preview-stderr.log)"
if ! preview_stderr_excerpt="$(sanitize_diagnostics "$raw_preview_stderr_excerpt")"; then
echo "::warning::Failed to sanitize OCR preview stderr diagnostic; skipping notification."
return 1
fi
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security risk: The notify-ocr-infrastructure-failure job posts ocr-stderr.log and ocr-preview-stderr.log content (first 2000 bytes each) to a publicly visible GitHub issue. While sanitize_diagnostics redacts exact secret matches and common credential patterns (Authorization headers, api_key=, token=, etc.), the redaction is pattern-based and could miss secrets appearing in unconventional formats — e.g., embedded in JSON error responses from the LLM API ("error":"invalid api_key: sk-xxxx"), in URL path segments, or in stack traces. The ocr review command (line 437) writes its stderr to ocr-stderr.log, and LLM API error responses are a common source of credential leakage in stderr. Consider either: (1) not including raw stderr excerpts in the GitHub issue body (rely on the run URL for debugging instead), or (2) applying a more aggressive redaction that masks any long alphanumeric string resembling a secret token, or (3) posting the issue as a private/collaborator-only notification rather than a public issue.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the latest amended commit: the infrastructure tracking issue no longer includes stderr or preview stderr excerpts. It records phase, exit code, sanitized infrastructure diagnostic, run URL, and artifact reference; raw stderr remains only in the workflow artifact.

Comment on lines +921 to +923
concurrency:
group: ocr-review-infrastructure-issue
cancel-in-progress: false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TOCTOU race condition: The concurrency group ocr-review-infrastructure-issue uses cancel-in-progress: false, allowing multiple notification jobs from different PR failures to run concurrently. While the code performs a double-check (search → comment/create → recheck), there is still a race window between the first gh issue list search and the gh issue create call where two concurrent jobs could both find no existing issue and both create new ones. The recheck before create (line 1120) mitigates but does not eliminate this — both jobs could pass the recheck simultaneously if their searches complete before either creates. Consider using a GitHub Actions environment lock or a unique issue title suffix per failure to avoid duplicate issue creation.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: GitHub Actions concurrency permits only one running job per group, and this notify job uses a single repository-wide group with cancel-in-progress false, so notifications are serialized. The second issue-list recheck remains as an additional duplicate guard.

Comment on lines +453 to +456
# Exact OCR endpoint/credential values are provided only for redaction;
# do not log process.env from this step.
OCR_LLM_TOKEN: ${{ secrets.OCR_LLM_AUTH_TOKEN }}
OCR_LLM_URL: ${{ vars.OCR_LLM_URL }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New secret exposure surface: OCR_LLM_TOKEN and OCR_LLM_URL are newly added to the Post OCR results step's env: block. Previously these secrets were not available to this step at all. While the code uses them only for redaction purposes and the comment says 'do not log process.env from this step,' any unhandled exception or future code change that references process.env in an error path could inadvertently expose secrets in workflow logs. Consider extracting only the secret lengths or pre-hashing them for comparison, rather than passing the raw secret values to this step.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: raw values are required to perform exact-match redaction before posting PR diagnostics. The step does not log process.env, GitHub masks configured secrets in logs, and OCR diagnostics are sanitized before being included in comments.

Comment on lines +210 to +214
const redactionMatch = postScript.match(/const\s+REDACTION\s*=\s*'([^']*)'/);
expect(
redactionMatch,
'script should define REDACTION constant',
).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex /const\s+REDACTION\s*=\s*'([^']*)'/ only matches single-quoted string literals. If the workflow script ever defines REDACTION with double quotes (e.g., const REDACTION = "[REDACTED]") or a template literal, redactionMatch will be null and the subsequent .toBeTruthy() assertion will fail with a generic "script should define REDACTION constant" message that doesn't hint at the quote-style mismatch. Consider also matching double-quoted strings (e.g., /const\s+REDACTION\s*=\s*(['"])([^'"\n]*)\1/) or providing a more descriptive assertion message when the match fails.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the latest amended commit: the REDACTION extractor now accepts both single- and double-quoted string constants and reports a more specific assertion message.

Comment on lines +453 to +456
# Exact OCR endpoint/credential values are provided only for redaction;
# do not log process.env from this step.
OCR_LLM_TOKEN: ${{ secrets.OCR_LLM_AUTH_TOKEN }}
OCR_LLM_URL: ${{ vars.OCR_LLM_URL }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OCR_LLM_TOKEN secret is now passed to the 'Post OCR results' github-script step purely for redaction purposes. While the code comment says 'do not log process.env', there is a risk of secret exposure: if an unhandled JavaScript exception occurs (e.g., a TypeError or ReferenceError in the inline comment posting logic), the github-script action may output error stack traces or environment dumps that include process.env contents. The redactSecretDiagnostics function only redacts strings explicitly passed through it — it does not protect against raw environment variable exposure in uncaught error paths. Consider removing the secret from this step's env entirely and performing redaction in a later step that doesn't have access to the raw secret, or wrap the entire script body in a try/catch that sanitizes any error message before calling core.warning/core.setFailed.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: exact redaction requires raw values in this post step. The script does not log process.env, comments are posted best-effort through explicit sanitized values, and GitHub masks configured secrets in logs.

Comment on lines 869 to 875
if (!ran) {
core.setFailed(`OpenCodeReview failed or produced unparsable output (exit code ${exitCode}).`);
if (policyFailure) {
core.setFailed(`OCR policy failure: ${policyFailure}`);
} else {
core.warning(`OpenCodeReview failed or produced unparsable output (exit code ${exitCode}).`);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Infrastructure failures (install failure, config missing, preview failure, OCR command failure, parse failure) now use exit 0 instead of exit 1, and the 'Post OCR results' step calls core.warning instead of core.setFailed for these cases. This means the code-review job will report 'success' even when OCR completely fails due to infrastructure issues. If branch protection rules require this check to pass, OCR infrastructure failures will go unnoticed — only policy failures (missing/excluded test files) will cause core.setFailed. This is a significant behavioral change that could silently allow infrastructure failures to pass CI gating. Consider whether infrastructure failures should also fail the job (perhaps via the ocr-classification step output), or document this as an intentional design decision.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: this is the explicit issue 2431 requirement. OCR infrastructure/provider/runtime/parse failures must be non-blocking and surfaced via warnings, sticky PR diagnostics, artifacts, and the ci/cd tracking issue; changed-test policy failures still fail the job.

Comment on lines +327 to +332
it('redacts exact OCR secrets with regex metacharacters and backslashes in PR diagnostics', () => {
const postScript = commandText(
stepNamed(codeReviewJob, 'Post OCR results'),
);
const secret = String.raw`tok$^.*+?()[]{}|\slash\end`;
const sanitize = makePostSanitizer(postScript, secret);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pattern commandText(stepNamed(codeReviewJob, 'Post OCR results')) is repeated across 11 test cases. Since codeReviewJob is already available from beforeAll, consider extracting a shared variable (e.g., let postScript;) set in the beforeAll hook, or a local helper function, to reduce duplication and make the tests more maintainable. If the step name ever changes, you'd only need to update one location instead of 11.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the latest amended commit: the workflow tests now initialize the Post OCR results step and script once in beforeAll and reuse the shared values.

ocr-phase.txt
ocr-infrastructure-failure.txt
ocr-policy-failure.txt
if-no-files-found: warn

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing if-no-files-found from error to warn means the workflow will not fail when expected artifact files are missing (e.g., if the 'Initialize OCR artifact files' step fails early or files are lost). The notify-ocr-infrastructure-failure job depends on downloading these artifacts to determine whether an infrastructure failure occurred. With warn, a missing artifact upload is silently accepted, and the downstream notify job's download-artifact step (which has continue-on-error: true) will also silently skip. This creates a gap where infrastructure failures could go entirely undetected if artifacts are lost. Consider keeping if-no-files-found: error for the core diagnostic files (ocr-exit-code.txt, ocr-phase.txt) or at minimum adding a health check in the notify job that surfaces missing diagnostic files as a warning.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: warning-only artifact upload is part of the issue requirement to avoid misleading upload failures before initialization. The notify job separately handles missing or incomplete artifacts and creates diagnostics for failed code-review runs unless a policy failure output is present.

Comment on lines +189 to +196
cat > ocr-workflow-helpers.sh <<'EOF'
mark_infrastructure_failure() {
echo "phase=$1; reason=$2" > ocr-infrastructure-failure.txt
}
mark_policy_failure() {
echo "$1" > ocr-policy-failure.txt
}
EOF

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The heredoc content is indented to match the YAML step indentation level. Because the delimiter is &lt;&lt;'EOF' (not &lt;&lt;-'EOF'), bash does NOT strip leading whitespace from the content lines. This means the generated ocr-workflow-helpers.sh file will contain lines like mark_infrastructure_failure() { with 10 leading spaces, and the closing EOF line will also have leading spaces. Since the closing delimiter must match EOF exactly (without leading whitespace), this EOF with leading spaces will NOT terminate the heredoc — the heredoc will capture everything until it finds a line containing only EOF (with no leading spaces). This will likely cause the heredoc to consume subsequent YAML content or fail. Use &lt;&lt;-'EOF' with tab-indented content, or de-indent the heredoc body and closing delimiter to column 0.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed: this is a YAML block scalar inside a run step; YAML strips the common indentation before bash receives the script. The generated heredoc delimiter is EOF at column 1 in the shell script, and actionlint plus the workflow tests pass.

This was referenced Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer:e2e:ok Trusted contributor; maintainer-approved E2E run

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make OCR PR review non-blocking while preserving inline comments

2 participants