Skip to content

chore: adopt the oxc toolchain, share release tooling with sf-formula-parser - #297

Open
paustint wants to merge 8 commits into
mainfrom
chore/dep-upgrade-and-docs-improvement
Open

chore: adopt the oxc toolchain, share release tooling with sf-formula-parser#297
paustint wants to merge 8 commits into
mainfrom
chore/dep-upgrade-and-docs-improvement

Conversation

@paustint

Copy link
Copy Markdown
Collaborator

Tooling, release process, docs and the dependency upgrade. One user-facing fix: JSDoc is restored in the published type declarations.

Six commits, each self-contained:

Commit What
chore: adopt the oxc toolchain and upgrade dependencies Prettier → oxfmt, oxlint added, TypeScript 7, .npmignore removed
fix: resolve everything oxlint flagged No behavior change to the library
build: enable isolatedDeclarations and keep JSDoc in declarations Restores hover docs for consumers
ci: enforce formatting, linting and a changelog entry Pre-commit hook, CI gates, changelog guard
ci: derive the release version from the changelog derive-increment.mjs, tasks/scripts/
docs: add copy buttons, llms.txt and AGENTS.md Docs site work, README correction

Highlights

removeComments was stripping every JSDoc block from dist/types — editors showed no documentation on hover for any exported symbol. Removing it costs 12 KB of declaration output and leaves the JavaScript bundles untouched, since esbuild builds those. This is the one change consumers will notice.

oxlint is new herecorrectness, suspicious and perf run as errors. style and pedantic stay off because on a hand-written recursive-descent parser they ask for the code to be restructured rather than pointing at defects. Two disabled rules are genuine false positives, each documented inline.

.npmignore removed. files in package.json takes precedence, so it had no effect — npm pack --dry-run produces a byte-identical 21-file tarball without it (same shasum). It had also drifted, listing CHANGELOG.md and AUTHORS.md as excluded while files ships both. files is an allowlist, which is the safer default.

The release commit identity was unresolvable. Commits were authored by Release Workflow <support@getjetstream.app>, which is not a GitHub account. The identity now derives from the App token, so release commits are attributed to the bot with its avatar.

⚠️ Before merging

The release workflow authenticates with client-id instead of the deprecated app-id and needs a CLIENT_ID secret. Org-wide secrets should cover this, but worth confirming.

Shared with sf-formula-parser

scripts/derive-increment.mjs, scripts/release.mjs, .githooks/pre-commit, and the ci, release and changelog workflows are now identical in both repos (each names the other in a header comment). Companion PR: jetstreamapp/sf-formula-parser#59

Verification

format:check, lint, typecheck, build all pass; 2273 tests green.

Replace Prettier with oxfmt and add oxlint, which the repository did not
have at all. Config moves from .prettierrc to .oxfmtrc.json, every option
carried over except the no-op insertPragma, with .oxlintrc.json alongside.

oxlint runs correctness, suspicious and perf as errors. style and pedantic
stay off: on a hand-written recursive-descent parser they ask for the code
to be restructured rather than pointing at defects. Disabled rules carry
their reason inline, including two false positives -
no-unmodified-loop-condition does not see that the paren-matching loops
mutate parenCount.right, and no-await-in-loop flags polling loops whose
iterations are sequential by design.

Upgrade to TypeScript 7 and the latest esbuild, release-it and tsx. Drop
npm-run-all and lodash.get, add @vitest/coverage-v8, and rename
vitest.config.ts to .mts since it is ESM while the root package is
CommonJS.

Remove .npmignore: files in package.json takes precedence, so it had no
effect - npm pack produces a byte identical 21 file tarball without it -
and it had drifted, listing CHANGELOG.md and AUTHORS.md as excluded while
files ships both.
No behavior change to the published library. A redundant double negation,
a ? true : false ternary, an unused local and an unused catch binding
removed; new Array(n).fill(' ').join('') in pad() became ' '.repeat(n);
three shadowed variables renamed.

In the tests, the performance benchmark had no assertion and now checks
that every iteration actually parsed, two toThrow() calls gained the
message matcher their neighbours already used, and unused imports were
dropped.
removeComments dropped every JSDoc block from dist/types, so editors
showed no documentation on hover for any exported symbol. Removing it
restores them for 12 KB of declaration output and leaves the JavaScript
bundles untouched, since esbuild builds those.

isolatedDeclarations is on and the target is ES2022, matching
sf-formula-parser. The target only affects emitted declarations and
esbuild was already producing es2020/es2022 bundles, so the shipped
JavaScript is unchanged.

tsconfig.typecheck.json covers tests, scripts and the cli, which the
build's declaration-only tsconfig.json excludes.
A pre-commit hook blocks commits whose staged files are unformatted or
fail lint, running both so one attempt reports everything to fix.

CI gates on format:check, lint and typecheck alongside the tests and
build, because the hook can be bypassed with --no-verify. It installs with
npm ci rather than npm install, and runs on pushes to main and on pull
requests instead of on every push.

A Changelog workflow requires an [Unreleased] entry on pull requests that
touch published code. That section decides the version, so a change nobody
wrote down was previously only noticed at release time. Touching the file
is not enough: the check runs derive-increment.mjs, so an edit that leaves
the section unclassifiable fails too. The skip-changelog label opts out.
derive-increment.mjs reads the [Unreleased] section and maps its headings
to an increment: Breaking Changes is a major, Added and Deprecated a
minor, Changed, Removed, Fixed and Security a patch. Only headings are
read, never the entry text - scanning the body for a word like BREAKING
fires on ordinary prose, and an entry that merely mentions a breaking
change would silently turn a patch into a major. An unrecognized heading
is an error rather than a guess.

npm run release starts a release from the terminal, verifying main is
clean and matches origin, printing the plan for confirmation, then
dispatching the workflow and tailing the run. The release still runs in
CI, which holds the publish credentials; release-it moves to release:ci.

The workflow now matches the Jetstream monorepo: it authenticates with
client-id rather than the deprecated app-id, and derives the commit
identity from the token instead of the unresolvable Release Workflow
<support@getjetstream.app>. app-slug names the committer and the App's
numeric user id forms the address GitHub links back to the App, so
release commits carry the bot's avatar. Actions are pinned to commit
SHAs, since a tag can be repointed and a SHA cannot.

tasks/ is renamed to scripts/ so the layout matches sf-formula-parser.
The playground's parse, compose and utility function output, and the
install command on the home page, reveal a copy to clipboard button on
hover, matching the one Docusaurus already renders on markdown code
blocks. The site publishes llms.txt and llms-full.txt via
docusaurus-plugin-llms, with links in the footer.

CLAUDE.md becomes AGENTS.md and records the formatter and linter
workflow, the release rules, and the two constraints that are not obvious
from the code: "type": "module" must not be added to the root
package.json, and docs/ is a separate npm project.

The README still described commander, chevrotain and lodash.get as
dependencies of the library. Those went away in 8.0.0; the package has no
runtime dependencies.
Copilot AI lite review requested due to automatic review settings August 17, 2026 13:26
@socket-security

socket-security Bot commented Aug 17, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​docusaurus/​faster@​3.10.2991006898100
Updatedesbuild@​0.28.1 ⏵ 0.28.292 +110073 +190100
Added@​vitest/​coverage-v8@​4.1.10991007999100
Updatedtsx@​4.23.9 ⏵ 4.23.12100 +1210081 +194 -1100
Addedoxfmt@​0.63.0861008896100
Addeddocusaurus-plugin-llms@​0.5.18610010091100
Updatedtypescript@​6.0.3 ⏵ 7.0.29910089 -1100100 +10
Addedoxlint@​1.78.0991009196100
Updatedrelease-it@​21.0.1 ⏵ 21.0.299 +110010094 +1100

View full report

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR modernizes the repository’s tooling and release process around the oxc toolchain and shared automation with sf-formula-parser, while also restoring consumer-visible JSDoc in published type declarations.

Changes:

  • Adopt oxfmt/oxlint, add pre-commit enforcement, and update CI to gate on format/lint/typecheck/tests/build.
  • Update TypeScript config/build pipeline (TypeScript 7, isolatedDeclarations, preserve JSDoc in emitted .d.ts).
  • Share/standardize changelog-driven release tooling and improve docs UX (copy buttons, llms.txt generation).

Reviewed changes

Copilot reviewed 43 out of 48 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
vitest.config.mts Centralizes Vitest include pattern and test timeout.
tsconfig.typecheck.json Adds full-tree typecheck config for src/tests/scripts/cli without emitting.
tsconfig.json Enables isolatedDeclarations, preserves JSDoc in d.ts, bumps target to ES2022.
test/test.spec.ts Adjusts tests for stricter typing (where!).
test/public-utils.spec.ts Removes lodash.get dependency from tests and tightens throw assertions.
test/performance-test.spec.ts Adds assertion to ensure all iterations parsed successfully.
test/lexer.spec.ts Formatting cleanup and more specific error assertions / lint annotations.
test/cli.spec.ts Avoids shadowing resolve by renaming promise resolver.
src/utils.ts Minor refactors, adds explicit return types for exported functions.
src/parser/parser.ts Removes unused local and unused catch binding.
src/composer/composer.ts Simplifies boolean coercion for config.format.
src/api/public-utils.ts Minor boolean simplification and variable renaming for clarity.
scripts/wait-for-npm-version.mjs Small style cleanup in helper sleep function.
scripts/release.mjs Adds changelog-derived release dispatcher/tailer script.
scripts/derive-increment.mjs Adds changelog heading parser to derive semver bump.
scripts/copy-test-cases-to-docs.ts Ensures generated JSON includes trailing newline for format checks.
scripts/build.mjs Moves build orchestration into shared esbuild-based script.
README.md Updates dependency/runtime-deps statement and formatter note.
package.json Updates scripts for oxc toolchain, release flow, typecheck, and Vitest usage.
docs/static/sample-queries-json.json Regenerates sample query list output formatting.
docs/src/pages/index.tsx Adds install command copy button to homepage hero.
docs/src/pages/index.module.css Adds styling for copy button integration in hero install pill.
docs/src/components/Utilities/Highlight.tsx Adds optional copy button support to custom code highlighting.
docs/src/components/Utilities/Highlight.module.css Adds positioning/hover styling for highlight copy button.
docs/src/components/Utilities/CopyButton.tsx Introduces reusable copy-to-clipboard button component.
docs/src/components/Utilities/CopyButton.module.css Provides copy button visuals and copied-state transitions.
docs/src/components/SoqlList/index.tsx Disables copy button for picker rows where it would obscure content.
docs/src/components/HomepageFeatures/styles.module.css Formatting update for multi-line transition property.
docs/scripts/serve-csp.mjs Minor style cleanup in path resolution logic.
docs/scripts/generate-csp.mjs Minor style cleanup and formatting consistency.
docs/package.json Adds llms plugin and aligns TypeScript version.
docs/package-lock.json Lockfile updates for added docs dependencies.
docs/docusaurus.config.ts Enables Docusaurus v4 future flags and llms plugin + footer links.
docs/docs/overview.md Formatting updates to published type snippets.
CONTRIBUTING.md Updates contributor workflow to use npm run format.
CHANGELOG.md Adds detailed unreleased entries documenting tooling/release/docs changes and JSDoc fix.
AUTHORS.md Normalizes list formatting.
AGENTS.md Documents repo-wide formatting/linting/types/release workflows.
.release-it.json Ensures release commits bypass pre-commit hook and updates script paths.
.oxlintrc.json Introduces oxlint config with scoped overrides and ignores.
.oxfmtrc.json Introduces oxfmt config schema and package.json sort behavior.
.npmignore Removes denylist in favor of files allowlist in package.json.
.github/workflows/release.yml Updates/pins release workflow; derives version and uses GitHub App identity.
.github/workflows/ci.yml Adds format/lint/typecheck gates and conditional docs build job.
.github/workflows/changelog.yml Enforces changelog entry for published-code changes unless skipped.
.githooks/pre-commit Adds pre-commit hook to enforce formatting and lint on staged files.
.claude/settings.json Aligns agent tool permissions with the new npm scripts/toolchain.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/src/components/Utilities/CopyButton.tsx Outdated
Copilot AI review requested due to automatic review settings August 17, 2026 13:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

The CLI suite spawns dist/cli/index.js, so running tests before the build
left 36 of its cases executing a binary that did not exist yet. The
previous workflow built first; that ordering was lost when this file was
made identical across both repositories.

Building first is the right order regardless: tests then run against a
build that is known to have succeeded.
Copilot AI review requested due to automatic review settings August 17, 2026 23:27
@paustint
paustint force-pushed the chore/dep-upgrade-and-docs-improvement branch from 3278ae4 to 163565d Compare August 17, 2026 23:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 44 out of 49 changed files in this pull request and generated no new comments.

Suppressed comments (2)

README.md:35

  • README still claims Node 11+ compatibility, but this PR's build now targets ES2022 (scripts/build.mjs) and the source uses ES2020+ operators (e.g. ??). Unless the build is meant to downlevel for Node 11, the documented minimum Node version should be raised to match what the published bundles require.
**Node**: version 11 or higher, or a polyfill for [Array.flat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat)  
**Browser**: Tested in all modern browsers, may not work with older browsers.

This library has no runtime dependencies - the parser, composer, formatter and cli are all self contained.

CONTRIBUTING.md:17

  • This section still instructs contributors to branch from and target the "master" branch, but the repo tooling/workflows in this PR are based on "main" (e.g. release/CI). Update both references to avoid sending contributors to a non-existent branch.
  - Run `npm run format` before committing - a pre-commit hook rejects unformatted files
    (`npm install` enables it, and `npm run format:check` reports without writing)
- open a Pull Request for the master branch

@paustint

Copy link
Copy Markdown
Collaborator Author

Went through Copilot's suppressed (low-confidence) comments — both were valid:

  • README.md:35 — fixed. The Node 11 claim was stale, though not quite for the reason given: the build targets es2022 but the source tops out at ES2020 syntax (??, ?.), so the real floor is Node 14, not an ES2022 one. Stated Node 20 rather than 14 since that is the oldest release still in maintenance and the only kind this is tested on. Dropped the Array.flat polyfill note, which no longer buys anything.
  • CONTRIBUTING.md:12,17 — fixed, master does not exist on this repo. Also caught the same dead branch in the README's contribution guidelines link.

Both recorded under ### Fixed in the changelog.

Copilot AI review requested due to automatic review settings August 18, 2026 12:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 44 out of 49 changed files in this pull request and generated no new comments.

Suppressed comments (1)

.github/workflows/ci.yml:22

  • CI currently runs tests only on Node 24, but the README states the supported minimum is Node 20. Without running CI on Node 20 (or a version range), regressions against the advertised minimum can slip in unnoticed. Consider using a Node version matrix (at least 20 + latest) for the main test job.
      - name: Use Node.js 24
        uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
        with:
          node-version: 24
          cache: npm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants