chore: tooling refresh (type-aware oxlint, lefthook, CI-gated release, dependency bumps) - #153
Merged
Merged
Conversation
…ase plugins - zod 4.5.4 -> 4.6.5 (core, mcp) - @modelcontextprotocol/sdk 1.30.0 -> 1.32.0 - @opencode-ai/plugin 1.18.30 -> 1.18.34 (support-matrix current + CI env; the 1.18.30 floor is unchanged) - oxlint 1.81.0 -> 1.86.0, oxfmt 0.66.0 -> 0.71.0, knip 6.35.1 -> 6.39.0 - @semantic-release/npm 13.2.0, @semantic-release/github 12.0.10 - conventional-changelog-conventionalcommits 8.0.0 -> 9.3.1: 10.x needs conventional-changelog-writer@9, but @semantic-release/release-notes-generator 14.1.1 (latest) still ships writer@8 and fails at render time; 9.3.1 renders identical notes. knip 6.39 now reports the `npm exec -c workit-cursor-session-start` call in the packed-runtime test as an unlisted binary; it is the workit-cursor bin installed into a temp project, so it is ignored like glab. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…aware) and oxfmt
- Add .oxlintrc.json: correctness=error, suspicious+perf=warn with
denyWarnings, explicit eslint/typescript/unicorn/oxc plugins, and
type-aware rules through oxlint-tsgolint 7.0.2003 (bundles typescript-go,
works with TS 7; whole repo lints in ~2 s).
- Add .oxfmtrc.json. Lint and format now walk the repo root and skip
gitignored paths plus ignorePatterns, so package.json no longer repeats the
path list four times, and previously unchecked scripts/ and
packages/*/scripts are covered.
- Fix findings instead of silencing them: sort/reverse -> toSorted/
toReversed (tsconfig target ES2023), no-shadow renames (e.g. locals that
shadowed the `path` module), filter()[0] -> find/findLast, unbound
runtime methods wrapped, needless awaits/assertions/conversions removed,
`${array}` -> join(",").
- Rules turned off carry a justification in the config: no-await-in-loop
(ordered subprocess/lock steps), consistent-function-scoping (style),
no-unsafe-type-assertion (~1k JSON-boundary casts, ratchet later),
no-base-to-string (tsgolint ignores checkUnknown), consistent-return (tsc
already enforces it); in tests, await-thenable (bun-types type
`.resolves/.rejects` as void) and unbound-method (monkeypatch restore).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g hooks pre-commit formats (oxfmt, re-staged) and lints (oxlint, type-aware) only the staged files in parallel: ~0.8 s measured. commit-msg runs commitlint with the conventional config (~0.5 s), since semantic-release and analyze-release-scope read Conventional Commits. Install is opt-in via `bun run hooks:install` and `no_auto_install` is set, because git hooks are shared by every worktree of a clone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e workflows `npx -y react-doctor@latest` resolved a new version on every run, and since 0.9.x it prints "React Doctor is not installed in this project" and exits 0 when react-doctor is not a dependency, so the CI gate scanned nothing. As a pinned devDependency it runs the real scan (~2 s; warnings only, no errors). sync-token-probe.yml was a dispatch-only check to delete "once the token is stable"; the last probe passed on 2026-08-28 and the v2.1.0 manifest-sync PR (#147) was opened with RELEASE_SYNC_TOKEN. windows-inner-suite-probe.yml runs test/workit-core/handoff.test.ts and sdd.test.ts, which no longer exist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s, CI-gated release CI: - `fast` job: one install, then lint (type-aware), format, knip, typecheck, react-doctor, actionlint and zizmor run concurrently (~5 s locally). Typecheck ran in 6 jobs and lint/format hid in a job named `shared`. - `test` job runs a plain `bun test` on Linux after one build, so test/workit-codex, test/workit-mcp, test/opencode-v2 and test/acceptance (never run in CI before) are covered, and new directories cannot escape. - `portability`: core + artifacts on macOS/Windows with one build each. The separate candidate job duplicated test/artifacts/phase-0-candidate. - Builds drop from 5 to 3 (one per OS); typecheck from 6 to 1. - Actions pinned to commit SHAs, persist-credentials: false, permissions default to none per job; actionlint and zizmor (offline) are clean. - PR runs cancel superseded runs; main runs are grouped per commit. Release: - release.yml is now a reusable workflow called by the `release` job in ci.yml with needs: [fast, test, portability], so a commit only publishes after its own CI passed. Secrets are passed explicitly (no inherit). - concurrency group with cancel-in-progress: false, so two merges cannot race on tags. - semantic-release runs from the pinned devDependency (`bun run release`) instead of an unpinned `npx`. - npm provenance: id-token: write plus NPM_CONFIG_PROVENANCE=true; npm still authenticates with NPM_TOKEN. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…loosened by autofix
The type-aware autofixes trusted declared types at untyped JSON/env/host
boundaries:
- no-unnecessary-boolean-literal-compare rewrote `confirmed !== true` to
truthiness in requireConfirmed (OpenCode init apply), migrateLegacyDocs and
YouTrack postUpdate, so `confirmed: "false"`, "no" or 1 passed the gate.
- no-unnecessary-type-conversion / -template-expression dropped String(),
Boolean() and `${}` coercions (hostingApiHostMatches returned undefined
instead of false).
- the no-map-spread suggestion turned `({ ...entry, ... })` inside map()
into Object.assign(entry, ...), mutating the source decisions/fixtures.
Every rewritten `=== true`/`!== true`/`=== false`/`!== false` comparison and
coercion is restored as it was on main (46 lines plus vcs-config and the four
Object.assign sites). The four rules are turned off with the reason in
.oxlintrc.json. Regression tests: confirmation gates reject "false", "no",
"true", 1 and {} (all three fail against the loosened code).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he release candidate pre-merge The CA-21 marketplace check must run on a clean checkout, so it now runs before `bun run build`. The test job also runs `verify:release-candidate` (the same pack-only gate release.yml runs before publishing, ~1.5 s locally), so a broken candidate fails the PR instead of the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pendency install The npm package's postinstall runs `lefthook install`, which ignores no_auto_install and would write into the .git/hooks shared by every worktree. bun already blocks it (lefthook is not in trustedDependencies); pnpm (`pnpm.neverBuiltDependencies`) and yarn (`dependenciesMeta.built: false`) are now opted out explicitly, and npm cannot install this workspace at all (EUNSUPPORTEDPROTOCOL on workspace:*, verified). A project-config test keeps lefthook untrusted and hooks opt-in via `bun run hooks:install`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two coercions dropped by no-unnecessary-type-conversion were missed by the earlier restore (multi-line on main): config locale validation and the YouTrack logTime date argument now match main exactly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts resolved keeping both intents: - package.json: config-driven lint/format scripts and pinned tooling from this branch; #152's knip reachability step and #155's test tiers (`test` = unit, `test:packaging`) and `check` from main; ink devDependency from main. - ci.yml: the new fast/test/portability layout; the Linux test job runs both tiers, which covers #155's `remaining` job (codex, mcp, opencode-v2, acceptance) and every other directory. - Source/test files main rewrote or deleted (#149, #151, #152, #155): main's version taken; lint fixes are re-applied in a follow-up commit. - bun.lock regenerated with bun 1.4.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Safe autofixes (toSorted, unnecessary assertions) plus manual no-shadow renames and typed sort keys on code that arrived with #149/#151/#152/#155. The boolean-compare, type-conversion, template-expression and map-spread rules stay off, so no strict comparison or coercion was rewritten (checked: no removed `=== true`/`!== true`/`=== false`/`!== false`, String(), Boolean() or new Object.assign in the diff). The confirmation-gate test drops its migrateLegacyDocs case: #152 deleted docs-migration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
🎉 This PR is included in version 2.1.5 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
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.
What it does
Slice S7 from
docs/workit-next/plan.md: tooling, CI and release refresh. Five focused commits:build(deps): zod 4.5.4 → 4.6.5,@modelcontextprotocol/sdk1.30.0 → 1.32.0,@opencode-ai/plugin1.18.30 → 1.18.34 (the support-matrixcurrentand CI env move with it; the 1.18.30 floor stays), oxlint 1.86.0, oxfmt 0.71.0, knip 6.39.0,@semantic-release/npm13.2.0 and/github12.0.10. All pins stay exact.conventional-changelog-conventionalcommitsgoes to 9.3.1, not 10.x. 10.x needsconventional-changelog-writer@9.@semantic-release/release-notes-generator14.1.1 (the latest) still ships writer@8, so 10.x fails with a "Missing helper" error at render time. I checked this by rendering notes through the generator: 9.3.1 produces the same output as 8.0.0.schema-depth.test.tspasses on zod 4.6.5 with no changes.chore(lint): adds.oxlintrc.jsonand.oxfmtrc.json, which now hold the list of paths to lint and format. The scripts are justoxlint,oxlint --fix,oxfmtandoxfmt --check. This drops the 4× duplicated path list and addsscripts/andpackages/*/scripts, which were not checked before.denyWarningson.oxlint-tsgolint7.0.2003. It bundles typescript-go, so it works with TS 7, and the whole repo lints in about 2 s.sort/reverse→toSorted/toReversed(tsconfig target is now ES2023)no-shadowrenames, including locals that shadowed thepathmodulefilter()[0]→find/findLastno-await-in-loop,consistent-function-scoping,no-unsafe-type-assertion(about 1k casts at JSON boundaries; to tighten later),no-base-to-string(tsgolint does not honorcheckUnknownyet) andconsistent-return. In tests only:await-thenable(bun-types types.resolves/.rejectsas void) andunbound-method.chore(hooks): lefthook, opt-in withbun run hooks:install.no_auto_install: trueis set because hooks are shared by every worktree of a clone.chore(ci): react-doctor is now a pinned devDependency (0.9.14). The two obsolete probe workflows are deleted (details under CI notes).chore(ci): CI restructure and a release that waits for CI (see below).CI and release
fast checks: one install, then lint, format, knip, typecheck, react-doctor, actionlint and zizmor run in parallel inside one step. Each gate prints its own log section with its exit code and duration.test (ubuntu-latest): one build, then a plainbun test. Every test directory runs. I confirmed thattest/workit-codex,test/workit-mcp,test/opencode-v2andtest/acceptancewere not in any CI job before.test (macos-latest)/test (windows-latest):test/workit-coreandtest/artifacts, same as before.candidatejob is gone: it repeatedphase-0-candidate, whichtest/artifactsalready runs.artifactsjob'sref: head_refcheckout is no longer needed: the phase-9 test already handles a detached HEAD.persist-credentials: falseeverywhere.permissions: {}at the top level, with only what each job needs added per job.release.yml):releasejob in ci.yml. That job only runs afterfast,testandportabilitypass for the same commit on main.inherit.cancel-in-progress: false, so two merges cannot race on tags.bun run release, which uses the pinned semantic-release devDependency instead of an unpinnednpxdownload.id-token: writeplusNPM_CONFIG_PROVENANCE=true.npm publishstill authenticates withNPM_TOKEN; provenance only adds the OIDC attestation. The repo is public and every package'srepository.urlmatches it.Measured (local, Node 24.20.0, bun 1.4.1)
oxlintwith types, whole repo, run alonebun testThe 2 local failures are environmental:
bun testpicks up the sibling worktree../s0-docs, which has nonode_modules. This also fails onmainin this layout.metadata.locktimeout under full-suite load. It passes when its file runs alone (3/3). This is the lock contention that S1 fixes.Also:
actionlintreports nothing, and zizmor 1.30.1 (--offline) reports no findings. One finding is ignored on purpose: zizmor suggests the$/self-repository syntax, which actionlint 1.7.12 rejects. The ignore comment explains this.CI notes / action needed
check (workit-core) (…),check (workit-opencode),check (workit-cursor),check (workit-cli),check (shared)). Those jobs no longer exist, so this PR and the automated manifest-sync PRs will wait on checks that never report. Before merging, change the required checks tofast checks,test (ubuntu-latest),test (macos-latest),test (windows-latest). I did not change repository settings.npx react-doctor@latestprints "React Doctor is not installed in this project" and exits 0. As a pinned devDependency it now runs the real scan. It currently reports warnings only, no errors.bun run check(not plainbun test) putsnode_modules/.binfirst on PATH. That bin folder contains thenpmthat@semantic-release/npmpulls in, so 2 packed-CLI tests fail to resolve the npm CLI when run that way. This already happens onmain. CI callsbun testdirectly, so it is not affected. Follow-up for the test helpers.sync-token-probe.yml: its own note said to delete it once the token was stable. The last probe passed on 2026-08-28, and RELEASE_SYNC_TOKEN opened manifest-sync PR chore(release): sync manifests to v2.1.0 #147.windows-inner-suite-probe.yml: it runshandoff.test.tsandsdd.test.ts, which no longer exist.Review follow-ups (3 more commits)
no-unnecessary-boolean-literal-comparechangedconfirmed !== truechecks into plain truthiness checks in three places:requireConfirmed(OpenCode V2workit_init_apply),migrateLegacyDocs, and YouTrackpostUpdate. After that change,confirmed: "false","no"or1would pass.=== true/!== true/=== false/!== false,String()/Boolean()/${}, andhostingApiHostMatchesreturningBoolean(...)again.no-map-spreadsuggestion had replaced spreads withObject.assign(...), which mutates the original objects (task-engineimportedTaskplus three tests). Those are restored to spreads..oxlintrc.json."false","no","true",1and{}. All three tests fail against the loosened code and pass with the fix.validate:cursor-marketplacenow runs before any build, on a clean checkout (CA-21). The test job now also runsverify:release-candidate(about 1.5 s).lefthook install, which ignoresno_auto_install. It cannot run on dependency install anymore:pnpm.neverBuiltDependenciesand yarn viadependenciesMeta.built: false;EUNSUPPORTEDPROTOCOLonworkspace:*).bun test: 1575 pass / 1 fail. The failure is AR-14, the environmental one caused by the sibling worktree, described above;Quality gates
Checklist
@openclaw/fs-safeare not bumped.🤖 Generated with Claude Code