Skip to content

chore: add jscpd + knip dead-code/duplication scanners (warn mode) - #195

Merged
isamu merged 1 commit into
mainfrom
chore/add-jscpd-knip
Jul 31, 2026
Merged

chore: add jscpd + knip dead-code/duplication scanners (warn mode)#195
isamu merged 1 commit into
mainfrom
chore/add-jscpd-knip

Conversation

@isamu

@isamu isamu commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds two report-only (warn mode) static-analysis workflows plus a knip config, modeled on
the merged pilot receptron/slashgpt-js#29.
Neither gates CI.

Added

  • .github/workflows/duplication-scan.yamljscpd copy/paste detection. Installs the
    jscpd 5.0.12 binary pinned by SHA256, scans over --format typescript,vue, uploads SARIF to
    GitHub code scanning. No --threshold, so jscpd never fails the job (findings are SARIF
    annotations only). Job permissions: {contents: read, security-events: write, actions: read};
    top-level permissions: contents: read; actions/checkout@v6 + persist-credentials: false;
    the upload-sarif step is continue-on-error: true.
  • .github/workflows/dead-code-scan.yamlknip unused files/exports/deps. Writes the compact
    report to the job summary and forces exit 0 so it can never gate, regardless of future rule
    changes. actions/checkout@v6 + actions/setup-node@v6 (node 22),
    yarn install --frozen-lockfile --network-timeout 120000.
  • knip.jsonc — every rule is warn or off, so knip itself exits 0 (warn mode).
  • package.jsonknip@^6 devDependency (resolves to 6.29.0) + "knip": "knip" script, and
    3 confirmed-dead dependencies removed (see below).
  • .gitignore — ignores jscpd's report/ output so scan artifacts are never committed.

knip config chosen for this repo

  • project: ["src/**/*.{ts,vue}"] — the Vite/Vue client source under analysis. The Express
    backend (server/**) and benchmark/** are intentionally out of scope.
  • entry: not listed. This is a Vite app whose entry is index.html -> src/main.ts; knip's
    built-in vite plugin auto-detects index.html, so listing an entry only produces a "redundant
    entry" hint.
  • ignoreExportsUsedInFile: true, includeEntryExports: false.
  • ignoreDependencies: none. The @gui-chat-plugin/* / @mulmochat-plugin/* plugins
    (including the two github: git-ref deps, @gui-chat-plugin/piano and
    guichat-plugin-akinator) are all statically imported via .../vue subpaths in
    src/tools/index.ts, so knip resolves them and there was nothing structurally invisible to
    silence. unresolved is off, so the /vue subpath imports never surface as noise.

Items to Confirm / Review

knip findings — FIXED (3 dependencies removed)

All three are behavior-preserving and confirmed against external ground truth; the clean-install
CI gates below pass with them gone.

  1. vue-drawing-canvas — zero references anywhere in the repo (src, server, benchmark,
    configs). It is a regular dependency of @gui-chat-plugin/canvas (not a peerDependency), so
    the plugin brings its own copy; it stays in yarn.lock transitively. Removing the direct
    dep is safe.
  2. @types/uuid — redundant stub; uuid@14 bundles its own types (dist/index.d.ts).
  3. @types/dotenv — redundant stub; dotenv@17 bundles its own types (lib/main.d.ts).

knip findings — LEFT (warn), for human judgment

  • Unused dependencies (6): @anthropic-ai/sdk, @google/genai, exa-js, winston,
    winston-daily-rotate-file
    false positives of the src/**-only project scope: each is
    imported by the Express backend under server/** (e.g. server/llm/providers/*,
    server/utils/logger.ts). Do not remove.
  • yauzl — no direct import in src/server, but it is also pinned in resolutions. Whether the
    direct dependency should stay alongside the resolution pin is a maintainer call — left.
  • Unused devDependencies (4): @tailwindcss/postcss, autoprefixer, postcss, ts-node
    the app uses @tailwindcss/vite and there is no postcss.config.*, so the three PostCSS-pipeline
    packages look like leftovers, and ts-node has no reference (tsx is used instead). These are
    build-tooling packages that a config could pull in implicitly, so they are left as follow-up
    candidates rather than removed in a scanner-onboarding PR.
  • Unused files (5): src/components/TextSelectionMenu.vue, src/session/types.ts,
    src/tools/utils/index.ts, src/tools/utils/blankImage.ts, src/tools/utils/htmlTypes.ts

    all substantive, not empty scaffold: a complete 101-line selection-menu component, a session
    adapter type contract, and a shared-utils barrel (+2 modules) from the recent
    move shared plugin code to src/tools/utils refactor. Currently orphaned but plausibly
    mid-refactor / intended surface — left for the maintainer.
  • Unused exports/types (~29) — almost all are barrel re-exports (src/components/settings/index.ts,
    src/tools/backend/index.ts) and plugin/tool helpers that read as an intended module surface.
    Left.

jscpd findings — FIXED: none

37 clones (4.46% duplicated tokens). None are trivial/mechanical; each is real structural
duplication needing a semantic refactor, so all are left reported for a human:

  • Most of the volume is intra-file duplication in server/routes/textLLM.ts (per-provider
    LLM streaming/response handling repeated across branches).
  • src/composables/useGoogleLiveSession.tsuseRealtimeSession.ts / useTextSession.ts
    (22–29 line blocks) — parallel session-adapter boilerplate; deduping means changing the
    abstraction (which src/session/types.ts appears to be heading toward).
  • src/tools/backend/html.tsmarkdown.ts (14 lines) and a src/tools/index.ts self-clone
    (29 lines, plugin-registration list).

Also confirm

  • actions/checkout@v6 in both new workflows matches the pilot pattern, but this repo's
    existing pull_request.yaml uses actions/checkout@v7. If the fleet should track the newest
    action versions, bump both to @v7.
  • SARIF → code scanning upload. The upload-sarif step is continue-on-error: true, so if
    code scanning / GitHub Advanced Security is not enabled for the repo, that one step is skipped
    without failing the job. Enable code scanning to see the annotations.

Verification (clean install)

From a fresh rm -rf node_modules && yarn install --frozen-lockfile (isolated cache):
yarn build OK (vite build + tsc -p server/tsconfig.json), yarn typecheck OK
(vue-tsc --noEmit), yarn lint OK (eslint src server), yarn knip OK (exit 0, warn mode),
jscpd OK (exit 0). --frozen-lockfile succeeded, confirming yarn.lock is in sync after the
3 removals. No build/scan artifacts (dist/, report/) are staged.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Added automated checks to identify unused code and copy/paste duplication during development.
    • Added reporting for code-quality findings in the project’s continuous integration checks.
    • Configured reports to be informational and avoid blocking updates.
    • Removed obsolete project configuration and generated scan reports from version control.

Adds two report-only (warn mode) static-analysis workflows plus knip config,
modeled on the merged pilot receptron/slashgpt-js#29. Neither gates CI.

- .github/workflows/duplication-scan.yaml: jscpd 5.0.12 (SHA-pinned), SARIF to
  code scanning, no --threshold (never fails). continue-on-error on upload.
- .github/workflows/dead-code-scan.yaml: knip report to job summary, forced exit 0.
- knip.jsonc: every rule warn/off; project src/**/*.{ts,vue}.
- package.json: knip@^6 devDep + "knip" script; removed 3 confirmed-dead deps
  (vue-drawing-canvas, @types/uuid, @types/dotenv).
- .gitignore: ignore jscpd report/ output.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@socket-security

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
Addedknip@​6.29.0971009596100

View full report

@socket-security

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm formatly is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: yarn.locknpm/knip@6.29.0npm/formatly@0.3.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/formatly@0.3.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@isamu
isamu merged commit 9a0305a into main Jul 31, 2026
14 checks passed
@isamu
isamu deleted the chore/add-jscpd-knip branch July 31, 2026 07:34
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8f331459-d656-4061-8288-2012d9d5817c

📥 Commits

Reviewing files that changed from the base of the PR and between 0e52441 and cae118e.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (5)
  • .github/workflows/dead-code-scan.yaml
  • .github/workflows/duplication-scan.yaml
  • .gitignore
  • knip.jsonc
  • package.json

📝 Walkthrough

Walkthrough

This PR adds two report-only GitHub Actions workflows: a Knip-based dead-code scan and a jscpd-based duplication scan. It adds a Knip configuration file, a Knip script and devDependency, a .gitignore entry for scan output, and removes three unused dependencies from package.json.

Changes

CI Scanning Workflows

Layer / File(s) Summary
Knip dead-code scan workflow and configuration
.github/workflows/dead-code-scan.yaml, knip.jsonc, package.json
Adds a path-filtered workflow that installs dependencies, runs Knip in report-only mode, writes findings to the job summary, and always exits 0. Adds knip.jsonc configuring warn-level rules for files, dependencies, and exports. Adds a knip script and devDependency to package.json.
jscpd duplication scan workflow
.github/workflows/duplication-scan.yaml, .gitignore
Adds a workflow triggered on pull requests and pushes to main that installs a pinned, SHA256-verified jscpd binary, scans TypeScript and Vue files, and uploads SARIF results to code scanning. Adds a .gitignore rule for the report/ output directory.
Unused dependency cleanup
package.json
Removes the unused vue-drawing-canvas dependency and @types/dotenv, @types/uuid devDependencies.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Trigger as PR/Push Event
  participant Workflow as GitHub Actions
  participant Scanner as Knip/jscpd
  participant Output as Summary/SARIF

  Trigger->>Workflow: trigger on matching paths
  Workflow->>Workflow: checkout code, install dependencies
  Workflow->>Scanner: run scan (report-only)
  Scanner-->>Output: write findings (job summary or SARIF)
  Workflow->>Workflow: exit successfully regardless of findings
Loading
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/add-jscpd-knip

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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