Commit Graph

1865 Commits

Author SHA1 Message Date
Ray Arayilakath 8b91ac8206 fix: make GitHub Actions setup flow idempotent and stop bundling local changes (#906)
* fix(cli): make GitHub Actions setup flow idempotent and stop bundling local changes (#904)

The setup flow opened duplicate PRs and swept unrelated local changes into
the generated branch. Two root causes in `openWorkflowPullRequest`:

1. Non-idempotent: `findUniqueBranchName` only avoided a *local* branch
   collision by appending a timestamp, and nothing checked for an
   already-open setup PR. A re-run (the workflow file lives only on the prior
   PR's branch, so it's re-written each run) minted `…-<timestamp>` branches
   and opened a second PR. Now we `gh pr list` for an open PR whose head is
   under the setup prefix and surface it (`pr-exists`) instead of opening a
   duplicate.

2. Dirty-tree bundling: `git checkout -b <new> origin/<default>` carries the
   index across and the whole-index `git commit` then committed whatever the
   user had staged (modified app files, a deleted/rewritten lockfile). Now we
   bail (`working-tree-dirty`) when the tree has tracked changes other than
   the workflow file itself, falling back to staging the workflow file. The
   workflow path is excluded from the check so the v1→v2 upgrade flow (which
   modifies the tracked workflow in place) still works.

Both callers handle the new `pr-exists` status; the runner / gh-availability
probe are now injectable for hermetic tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(cli): harden setup-flow fix from adversarial review

Findings from an adversarial review+deslop pass over the #904 fix:

- fix(correctness): normalize `workflowRelative` with `toForwardSlashes` so the
  `:!` exclude pathspec matches git's forward-slash repo paths on Windows.
  Without it, `path.relative` yields backslashes there, git's magic pathspec
  doesn't treat them as separators, and the upgrade flow (tracked workflow
  modified in place) would always report `working-tree-dirty` and never open
  the PR. Applied in `openWorkflowPullRequest` and `stageWorkflowFile`.
- fix(correctness): on the upgrade flow's `pr-exists` path, restore the
  original @v1 workflow content. `pr-exists` returns without touching git
  state, so the @v2 edit written before the call would otherwise linger
  uncommitted — matching the pr-opened path's "bump lives only on the PR
  branch" contract.
- chore: extract the `gh pr list` cap to `GH_PR_LIST_MAX` in constants.ts
  (AGENTS.md: no inline magic numbers).
- test: assert the dirty-tree guard skips add/commit/push (not just checkout),
  the happy path stages ONLY the workflow file (no `git add -A`/`.`), and
  branch-pushed keeps the branch (no `git branch -D`) and restores HEAD.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(cli): trigger duplicate-PR guard on match presence, not URL truthiness

Bot review (Cursor) flagged that the idempotency short-circuit keyed on a
truthy URL: if `gh pr list` returned a matching setup head branch with a
missing/empty `url`, `findExistingSetupPullRequest` returned null and the
flow could still mint a branch and open a duplicate PR — the exact failure
the guard exists to prevent. `gh` always populates `url` for `--json url`, so
this is defensive, but the headline #904 guarantee shouldn't hinge on it.

Return the matched PR object and short-circuit on its existence; use its url
only for the `pr-exists` message (empty when absent). Adds a regression test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 18:15:40 -04:00
Ray Arayilakath 7e10716ae1 refactor(cli): unify onboarding/growth state into a lifecycle framework (#907)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 17:57:55 -04:00
Ray Arayilakath 4560b6dd39 perf(core): propagate V8 compile cache to oxlint batch subprocesses (#893)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 04:17:23 -04:00
Aiden Bai 8bbcca87da chore: vendor deslop-js + deslop-cli into the monorepo (#880) 2026-06-19 01:02:54 -07:00
Ray Arayilakath 350a6edc59 fix(core): support TypeScript 5 alongside 6 (#890)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 03:14:38 -04:00
Skosh 9f733f7cff fix: skip pnpm hardening check for monorepo sub-packages (#879)
* fix: skip pnpm hardening check for monorepo sub-packages

Only check pnpm hardening settings at the workspace root or standalone
pnpm projects. Sub-packages of a pnpm workspace inherit hardening from
the workspace root's pnpm-workspace.yaml, so emitting diagnostics with
synthesized file paths for each sub-package is incorrect.

Fixes #878

Co-authored-by: Skosh <skoshx@users.noreply.github.com>

* chore: add changeset for pnpm hardening fix

Co-authored-by: Skosh <skoshx@users.noreply.github.com>

* chore: format test file

Co-authored-by: Skosh <skoshx@users.noreply.github.com>

* refactor: rename rootDirectory to scanDirectory in checkPnpmHardening

The parameter name was misleading - call sites pass scanDirectory,
not a root directory.

Co-authored-by: Skosh <skoshx@users.noreply.github.com>

* refactor: deslop pnpm-hardening monorepo-skip change

Defer findMonorepoRoot inside the !hasWorkspaceFile guard so the
ancestor walk only runs when its result is used, and fold the
parent-workspace check into one short-circuit condition (one fewer
nesting level, behavior unchanged). Extract expectMissingHardeningWarnings
to collapse four repeated assertion groups in the monorepo test block.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Skosh <skoshx@users.noreply.github.com>
Co-authored-by: Rayhan Noufal Arayilakath <me@rayhanadev.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 23:18:03 -07:00
Ray Arayilakath 439e8e168c fix(ci): address post-merge Bugbot findings (cancel scope, self-test CLI, root-commit diff) (#888)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 01:58:53 -04:00
Ray Arayilakath 242bf69451 ci: action version-bump guard + faster CI (turbo remote cache, concurrency) (#885)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 01:49:22 -04:00
github-actions[bot] 96b5bb4e5b chore: version packages (#827) react-doctor@0.5.7 oxlint-plugin-react-doctor@0.5.7 eslint-plugin-react-doctor@0.5.7 2026-06-19 00:26:04 -04:00
Rayhan Noufal Arayilakath 66133f883c chore(changeset): downgrade fix-group root-cause grouping to a patch bump
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 21:17:03 -07:00
Ray Arayilakath 869f220d97 feat(cli): warn before mass-fixing a migration-scale bucket (#884)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 00:15:38 -04:00
Ray Arayilakath a9d27134c4 feat(cli): group findings a single fix resolves into one root-cause task (#882)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 23:54:18 -04:00
Ray Arayilakath 44db3e0546 fix: bare-name disable handling + server-fetch mutating-method false positive (#859)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 23:30:07 -04:00
Ray Arayilakath 4e06b2ac90 chore(changeset): downgrade clickable-locations to a patch bump (#883)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 23:27:13 -04:00
Ray Arayilakath 740211cf20 feat(action): skip the PR comment + mark the status "skipped" when no React files change (#863)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.2.0
2026-06-18 23:20:34 -04:00
Ray Arayilakath 50999f4a09 feat(cli): add --debug to surface the run's Sentry trace id (#881)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 21:34:12 -04:00
Aiden Bai 5d1347e08f refactor: Effect v4 elegance pass — shared helpers, DRY, magic-number cleanup (#867) 2026-06-18 00:21:59 -07:00
Ray Arayilakath ed0258caa2 test(oxlint-plugin): green the rule suite and run it in CI (#866)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 00:18:55 -04:00
Aiden Bai 93b796d416 refactor: elegance pass — remove dead code, dead branches, and redundant abstractions (#852) 2026-06-17 20:21:41 -07:00
Ray Arayilakath 3f7d0e7ddb fix(no-danger): ship default-off so it stops blanket-flagging safe dangerouslySetInnerHTML (#865)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 23:07:09 -04:00
Ray Arayilakath b8170f814c fix(jsx-key): don't flag element collections passed to non-children props (#862)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 22:33:08 -04:00
Ray Arayilakath 937a7ca8a1 fix(no-inline-exhaustive-style): skip Satori OG image components (#861)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 22:15:43 -04:00
Ray Arayilakath b317164e3e feat(cli): clickable OSC-8 file locations + terminalKind telemetry (#864)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 22:15:11 -04:00
Ray Arayilakath 8057497508 fix(action): resolve PR changed-file paths against the scanned directory (#858) (#860)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2.1.1
2026-06-17 21:17:42 -04:00
Ray Arayilakath 17389ba4fe fix(cli): show the source code frame in why <file>:<line> (#857)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:30:00 -04:00
Aiden Bai 7d9e676e0b fix 2026-06-17 15:50:01 -07:00
Ray Arayilakath 1e260c5d21 fix(cli): show CI + install pitches once per repo, not every scan (#851)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 21:48:29 -04:00
Ray Arayilakath 0053a0283e Revert "feat(rules): add 10 motion, accessibility, and design lint rules (#825)" (#849) 2026-06-16 20:26:21 -04:00
Ray Arayilakath 424d8f9f91 fix(agent-tool-capability-risk): ignore capability keywords in string literals (#838) (#847)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 19:17:25 -04:00
Ray Arayilakath 431e515260 fix(scan): degrade gracefully when react-hooks-js plugin fails to load (#848)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 19:16:59 -04:00
Ray Arayilakath 6b8e756c40 fix(server-sequential-independent-await): count nested-destructuring bindings as a dependency (#839) (#846)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 19:08:22 -04:00
Ray Arayilakath 81bbfcc39a fix(artifact-baas-authority-surface): stop flagging next-sanity studio bundles (#840) (#845)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 18:58:05 -04:00
Ray Arayilakath 5b742fa28c fix(url-prefilled-privileged-action): recognize validators wrapping reads behind a receiver chain (#837) (#843)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 18:46:08 -04:00
Ray Arayilakath eafac9d4f1 fix(cli): recommend --scope changed instead of deprecated --diff (#834) (#844)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 18:45:02 -04:00
Aiden Bai 09dde181c7 feat(rules): add 10 motion, accessibility, and design lint rules (#825)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Rayhan Noufal Arayilakath <me@rayhanadev.com>
2026-06-16 17:21:21 -04:00
Aiden Bai 451beeb284 feat(rules): add 3 mined platform/correctness rules (batch 2) (#828)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Rayhan Noufal Arayilakath <me@rayhanadev.com>
2026-06-16 00:06:34 -04:00
Ray Arayilakath 0a7edbd3d3 chore(skills): add rde-eval runbook for testing rules against the corpus (#836)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 21:07:46 -04:00
devin-ai-integration[bot] b08ca1c919 chore(deps): upgrade oxc-parser to 0.135.0 (#835)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-15 16:35:03 -07:00
Aiden Bai 03301fcdf4 fix(server-auth-actions): recognize custom auth guards by naming convention (#829) (#831) 2026-06-15 15:52:01 -07:00
devin-ai-integration[bot] f45cb297ef fix(dead-code): keep ignore.files files in deslop graph (#830) (#832) 2026-06-15 15:07:56 -07:00
Aiden Bai 8908f98d02 feat(rules): add 8 mined correctness, performance, a11y, and security rules (#826)
* feat(rules): add 8 mined correctness, performance, a11y, and security rules

Mined from a 12-cluster pass over the design/engineering brain and
synthesized into docs/rule-candidates-backlog.md. Ships the highest-signal,
lowest-noise batch, each with adversarial + FP-regression tests:

- no-call-component-as-function (Bugs)
- no-create-ref-in-function-component (Bugs)
- no-async-effect-callback (Bugs)
- no-json-parse-stringify-clone (Performance)
- img-missing-dimensions (Performance)
- no-img-lazy-with-high-fetchpriority (Performance)
- dialog-has-accessible-name (Accessibility)
- auth-token-in-web-storage (Security)

Adds the shared has-jsx-spread-attribute util and registers the three
in-house ported-bucket rules in RULES_NOT_PORTED_FROM_EXTERNAL.

* fix(rules): drop img-missing-dimensions; make component rules shadow-safe

- Drop `img-missing-dimensions`: width/height attributes are only one of
  several valid ways to reserve space (CSS aspect-ratio, container sizing),
  and the authoritative signal lives in stylesheets a static linter can't
  see. This is a runtime check (Lighthouse `unsized-images`), so a syntax
  rule would false-positive on any CSS-sized image.
- `no-call-component-as-function`: resolve the callee through its scope
  symbol instead of by name, so a parameter/local shadowing a component
  name is no longer flagged. The component signal is the binding's
  declaration (same-file component returning JSX) or an imported binding
  also rendered as JSX.
- `no-create-ref-in-function-component`: skip a shadowing local `createRef`
  (only flag React's import / `React.createRef`).
- Adds shadow-safety regression tests for both.

* fix(rules): tag no-call-component-as-function test-noise (eval finding)

An OSS eval sweep (react-use, radix primitives, excalidraw, mantine;
~2.8k diagnostics) showed every real-world hit of this rule was a test
render-helper (`render(Wrapper({...}))` in `.test.tsx`/`.story.tsx`) —
harmless for hookless wrappers and the dominant firing surface. Tag it
`test-noise` so it skips test/story/playground files and only nags
shipped code. The sweep also confirmed dialog-has-accessible-name (2 real
a11y bugs in excalidraw) and no-create-ref-in-function-component (1 real
bug in a mantine story) as true positives with zero false positives.
2026-06-15 05:13:44 -07:00
github-actions[bot] 15238de701 chore: version packages (#821) react-doctor@0.5.6 oxlint-plugin-react-doctor@0.5.6 eslint-plugin-react-doctor@0.5.6 2026-06-15 04:01:19 -07:00
Aiden Bai cf9e05be8e fix(scan): show full file count when handing off to dead-code analysis (#815) (#824) 2026-06-15 02:25:50 -07:00
Aiden Bai ea3b827899 feat(security-scan): add 6 BaaS and CWE rules from security research (#812) 2026-06-15 00:50:47 -07:00
Ray Arayilakath bac7c82950 fix(supply-chain): skip dist-tags and wildcards instead of crashing (#807) (#823)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-14 19:09:50 -04:00
Aiden Bai 5fc0e270c9 fix(security-scan): resolve reported false positives (#813, #814, #816, #817, #818) (#819) 2026-06-14 15:37:53 -07:00
github-actions[bot] daf0579d19 chore: version packages (#810) react-doctor@0.5.5 oxlint-plugin-react-doctor@0.5.5 eslint-plugin-react-doctor@0.5.5 2026-06-13 21:36:52 -07:00
devin-ai-integration[bot] e90eb7acbf fix(tanstack-start): recognize current .validator() server-fn method (#808) (#809)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-13 17:36:42 -07:00
github-actions[bot] f229c75d4b chore: version packages (#806) react-doctor@0.5.4 oxlint-plugin-react-doctor@0.5.4 eslint-plugin-react-doctor@0.5.4 2026-06-13 04:00:14 -07:00
Aiden Bai eacdcf2e65 Add project-level security scan rules (#744)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
Co-authored-by: Rayhan Noufal Arayilakath <me@rayhanadev.com>
2026-06-13 03:57:25 -07:00