fix(skills): replace stream-based lookahead with array indexing in list-changed-files.sh#1376
fix(skills): replace stream-based lookahead with array indexing in list-changed-files.sh#1376
Conversation
…st-changed-files.sh - use mapfile to load grep output into array for index-based iteration - prevent inner read from consuming the shared input stream - add || true guards to arithmetic expressions under set -e 🐛 - Generated by Copilot
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1376 +/- ##
==========================================
- Coverage 87.66% 87.65% -0.02%
==========================================
Files 61 61
Lines 9328 9328
==========================================
- Hits 8177 8176 -1
- Misses 1151 1152 +1
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Advisory review, this PR is from a maintainer. Findings are informational only.
Review Summary
✅ This PR meets initial quality standards. The fix is correct, well-scoped, and addresses the root cause of the stream-consumption bug.
Issue Alignment
✅ Fixes #1375. The PR directly targets the identified root cause: a nested read call inside a while read loop that consumed lines from the shared process-substitution stream. When two consecutive diff --git headers appeared without an intervening type-indicator line, the inner read would swallow the next header, silently dropping files from the output. The mapfile-plus-index-based approach is the canonical Bash fix for this class of problem.
PR Template Compliance
✅ All required sections are filled in. Type-of-change checkboxes (Bug fix, Script/automation) correctly reflect the change. The Tests added for new functionality item is appropriately annotated as N/A with rationale. Security and checklist items are correctly scoped.
Coding Standards
✅ The script follows the repository's Bash conventions:
#!/usr/bin/env bashshebang is present.- Copyright and SPDX headers are intact.
set -euo pipefailstrict mode is in place.[[ ... ]]and(( ... ))are used correctly.localscoping is applied to all function-local variables.
Code Quality
✅ The implementation is correct across all cases:
- Back-to-back
diff --git(no type indicator):next_linedoesn't match any type pattern, no spuriousi++is issued, and the outer(( i++ )) || trueadvances normally. - New/deleted file: The type-indicator line is consumed by the inner
(( i++ )) || true, and the outer increment advances to the nextdiff --git. Correct. - Rename (
rename fromin filtered output): The inner increment consumes therename fromline; paths come from thediff --githeader. Correct. - Last line in array (no lookahead possible): Falls through to the
elif [[ "$old_path" != "$new_path" ]]branch for path-mismatch renames. Correct. (( i++ )) || trueguards: Necessary and correct — Bash exits with status 1 when an arithmetic expression evaluates to 0 (post-increment ofi=0returns 0, which is falsy underset -e). The|| trueguard is the right idiom.- Empty input:
mapfileproduces an empty array,count=0, the while loop never executes. Correct.
Action Items
None — the PR is ready to merge.
Note
🔒 Integrity filter blocked 1 item
The following item were blocked because they don't meet the GitHub integrity level.
- #1375
issue_read: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".
To allow these resources, lower min-integrity in your GitHub frontmatter:
tools:
github:
min-integrity: approved # merged | approved | unapproved | none|
@katriendg ... do you know if the powershell version suffers from this as well? |
Fixed a bug in the pr-reference skill's
list-changed-files.shwhere nestedreadcalls inside awhile readloop consumed lines from the shared input stream. When consecutivediff --githeaders appeared without intervening type-indicator lines, the innerreadwould swallow the next header, causing the outer loop to skip files or misclassify change types. The fix replaced the stream-based approach withmapfilearray indexing for correct lookahead behavior.Description
mapfile -t linesto load all grep output into an array before the loop, switching towhile (( i < count ))arithmetic iteration with explicit index-based lookahead vialines[i + 1]|| trueguards to all(( i++ ))arithmetic expressions to preventset -efailures when the pre-increment value evaluates as falsy in Bash^rename\ frommatching, path-mismatch checks, and a fallback for the last entry in the array where no next line existsRelated Issue(s)
Fixes #1375
Type of Change
Select all that apply:
Code & Documentation:
Infrastructure & Configuration:
AI Artifacts:
prompt-builderagent and addressed all feedback.github/instructions/*.instructions.md).github/prompts/*.prompt.md).github/agents/*.agent.md).github/skills/*/SKILL.md)Other:
.ps1,.sh,.py)Sample Prompts (for AI Artifact Contributions)
Testing
extract_files()function's final state matches expected array-indexed iteration pattern with correct|| trueguards and rename detection branches.Checklist
Required Checks
AI Artifact Contributions
/prompt-analyzeto review contributionprompt-builderreviewRequired Automated Checks
The following validation commands must pass before merging:
npm run lint:mdnpm run spell-checknpm run lint:frontmatternpm run validate:skillsnpm run lint:md-linksnpm run lint:psnpm run plugin:generatenpm run docs:testSecurity Considerations
Additional Notes
mapfileapproach trades bounded memory for iteration correctness, which is appropriate since grep output is bounded by the number of files in a diff.2>/dev/null || trueon thegrepinvocation was preserved to handle empty input files gracefully.