Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
P1B: Starter Task: Refactoring PR
Use this pull request template to briefly answer the questions below in one to two sentences each.
Feel free to delete this text at the top after filling out the template.
1. Issue
Link to the associated GitHub issue:
#77
Full path to the refactored file:
packages/opencode/src/acp/content.ts
What do you think this file does?
It converts Agent Client Protocol content blocks into opencode's internal prompt-part format. Given a content block of some type, text, image, resource link, or embedded resource, it produces the corresponding text or file parts that the rest of the app consumes, and the file also handles the reverse conversion (parts back into content chunks).
What is the scope of your refactoring within that file?
The single function contentBlockToParts (line 30). I extracted its per-block-type logic into three new helpers, textBlockToParts, imageBlockToParts, and resourceBlockToParts, leaving contentBlockToParts as a thin switch dispatcher. No other functions were changed.
Which Qlty‑reported issue did you address?
Function with many returns (count = 11) and Function with high complexity (count = 33), both on contentBlockToParts.
2. Refactoring
How did the specific issue you chose impact the codebase’s maintainability?
All four content-block types were handled inline inside one switch, giving contentBlockToParts eleven return points and high complexity. A reader had to hold every block type's logic in their head at once, and changing how one type was handled risked affecting the others.
What changes did you make to resolve the issue?
I moved each case's body verbatim into its own typed helper, textBlockToParts, imageBlockToParts, and resourceBlockToParts, each narrowed to its block type via Extract<ContentBlock, { type: ... }>. contentBlockToParts is now a thin switch that dispatches to the right helper based on block.type.
How do your changes improve maintainability? Did you consider alternatives?
Each block type's logic is now isolated and independently readable, and contentBlockToParts drops below Qlty's many-returns and complexity thresholds. I considered an object/lookup-map dispatch instead of the switch, but the switch preserves TypeScript's discriminated-union narrowing and matches the existing style in this file (e.g. partToContentChunks).
3. Validation
How did you validate that the change is correct?
*The refactor only relocated each branch's code without altering any logic, so behavior is preserved by construction. I added packages/opencode/src/acp/content.test.ts with nine unit tests covering every branch of the dispatcher, text, text with audience flags, all three image paths, resource link, both embedded-resource paths, and the unknown-type default, and all nine pass. qlty smells confirms both target smells on contentBlockToParts are gone after the change.
Note on local tooling: this DevContainer runs on linux-arm64, where the repo's oxlint, tsgo (typecheck), and coverage instrumentation crash on load (segfault / SIGKILL / an unresolved jsonc-parser in config.ts), environment issues unrelated to this change. Lint, typecheck, and coverage therefore run on CI (x64); the CI checks on this PR are the source of truth for those, and the coverage screenshot below is from the CI run.*
Attach a screenshot of the test coverage showing the lines were executed by the tests.


Attach a screenshot showing the tests that cover the change passing during CI

Attach a screenshot of

qlty smells --no-snippets <full/path/to/file.ts>showing fewer reported issues after the changes.