Conversation
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…m in CI Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
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
1. Issue
Link to the associated GitHub issue:
Closes #110
Full path to the refactored file:
packages/opencode/src/tool/json-schema.tsWhat do you think this file does?
It converts a tool's Effect
Schemainto the JSON Schema document that is sent to LLM providers as the tool'sparameters.fromSchemaasks Effect for a draft-2020-12 document, thennormalizerewrites it into the "wire shape" providers accept (dropsadditionalProperties: true, stripsnullfrom optional fields, collapses trivialanyOf/allOfunions, bounds integers to the safe range) and finally inlines local$defsreferences.What is the scope of your refactoring within that file?
Only
normalize()(previously lines 28–79). Its logic is now split intonormalize(happy path) plus four helpers directly below it:normalizeChildren,collapseAnyOf,flattenAllOf,boundIntegerRange, and a smallisNonFiniteEnumpredicate.fromSchema,fromTool, the$refinlining and the existing predicates are untouched.Which Qlty‑reported issue did you address?
Function with high complexity (count = 29): normalizeatpackages/opencode/src/tool/json-schema.ts:28(the same function was also flaggedFunction with many returns (count = 9)). File total complexity BEFORE: 60.2. Refactoring
How did the specific issue you chose impact the codebase’s maintainability?
normalizewas one 50-line function that did six unrelated rewrites in a single pass with 9 exit points, aforloop that mutatedrequiredbookkeeping, and several deeply nestedifchains. To know which rule produced a given output you had to trace the whole function, and adding a new rewrite meant threading another branch into the same block.What changes did you make to resolve the issue?
normalizenow reads as the happy path: recurse into arrays/non-objects, normalize children, dropadditionalProperties: true, apply the first matchinganyOf/allOfrewrite (and re-normalize its result), else bound integers.normalizeChildrenowns the "which properties are optional" bookkeeping (requiredset +stripNullper property) usingObject.fromEntries/mapinstead of a mutable loop.collapseAnyOfholds the three union simplifications (null stripping, non-finite-number enum collapse, empty struct union, single-member union) and returns either a replacement schema orundefined.flattenAllOfandboundIntegerRangehold the remaining two rules.isNonFiniteEnumreplaces a repeated inlineisRecord(x) && Array.isArray(x.enum) && x.enum.every(isNonFiniteNumber)expression.Behavior is unchanged: every existing snapshot in
test/tool/parameters.test.tsstill matches, and I diffedToolJsonSchema.fromSchemaoutput for representative schemas (optional/nullable fields,Schema.Number, empty structs,allOfconstraints, integers, nested arrays) betweenmainand this branch before deleting the probe.How do your changes improve maintainability? Did you consider alternatives?
Each rewrite rule now has a name, a single responsibility and at most three exits, so a reader can find "why did
nulldisappear" by openingcollapseAnyOfinstead of the whole function, and a new rule is one more helper in the??chain. Qlty no longer reports any function-level smell in the file and total complexity drops 60 → 54. I considered (a) a table of[predicate, rewrite]pairs iterated in order, which was more abstract than the five concrete rules warrant, and (b) only extracting theanyOfblock, which would have leftnormalizeat ~7 returns; the current split matches the repo's "happy path + helpers below" style guide.3. Validation
How did you validate that the change is correct?
bun test test/tool/parameters.test.ts test/tool/registry.test.tsfrompackages/opencode: 79 pass, 0 fail. The existing 16 JSON Schema snapshots for every built-in tool exercisenormalizeend to end; these are the tests that would break if any rewrite changed output for real tool schemas.test/tool/parameters.test.ts→describe("JSON Schema (wire shape)"), one per extracted rule: null stripping only on optional fields, non-finitenumberunion collapse, empty-struct union collapse,allOfflattening, explicit integermaximumpreserved, and pass-through of non-object schema values. Together with the snapshots these cover every line ofnormalizeand its helpers (see coverage below), so a reviewer can trust that both the common tool schemas and each individual rule still produce the same wire shape.bun typecheckandbun lintfrompackages/opencodepass;bun prettier --checkpasses.Run tool JSON Schema testsstep in.github/workflows/test.yml(the existingbun turbo teststep already runs them but uses--only-failures, which hides passing test names in the CI log).Attach a screenshot of the test coverage showing the lines were executed by the tests.
bun test test/tool/parameters.test.ts --coverage --coverage-reporter=lcov+genhtml:json-schema.ts95.7% lines; every line ofnormalizeand the new helpers (28–87) is hit. The only uncovered lines arefromTool(covered byregistry.test.ts) and two$refedge branches unrelated to this change.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.