All jobs

Find Dead Code in a Vue Project

Yes. An agent runs knip over your Vue app, checks each unused file, export and dependency against the type check, build and tests, and reports what is safe to drop.

Run this on RushIn a Project that has your repository.

What the agent does

The agent reads the build and test setup before it runs any tool, because dead-code finders are only as good as their list of entry points. In a Vue app like mutoe/vue3-realworld-example-app, index.html loads src/main.ts, which creates the app with Pinia and the router and registers global components from src/plugins. vite.config.ts aliases src/* and configures Vitest with happy-dom, a setup file at src/setup-tests.ts and coverage through a custom provider; tsconfig.json is strict with noUnusedLocals and noUnusedParameters and references a second config under playwright/. package.json runs on pnpm@10.33.0 with type-check through vue-tsc, lint through ESLint 10, test:unit through Vitest, test:e2e through Playwright, and a generate:api script that regenerates src/services/api.ts from the RealWorld OpenAPI file with swagger-typescript-api. .github/workflows/test.yml runs type-check, lint, build, the unit tests and the e2e suite.

That reading becomes the knip configuration. Entry points are src/main.ts, the Playwright specs and fixtures under playwright/, scripts/merge-coverage.ts, vite.config.ts and the three files under config/. src/services/api.ts is generated, so its unused exports are expected and the report lists them under their own heading rather than as findings; the size-limit and simple-git-hooks entries in package.json are tools the config references, not code. With that in place, knip reports unused files, unused exports and types, and dependencies nothing imports.

Then each candidate is checked, because knip reports what it cannot see, not what is dead. For an unused file, the agent removes it and runs pnpm type-check and pnpm build; for an unused export, it removes the export keyword and runs the same two plus pnpm test:unit, since the spec files next to each component under src/components and src/pages import from them; for an unused dependency, it removes the package and runs the build and the unit tests. A candidate that breaks any of the three is listed as a false positive with the command that failed.

The result is dead-code.md: one table per kind with the path, the line, what referenced it last according to git log, and which checks it passed, and a closing section on what knip could not see, such as components registered globally by name in src/plugins. The repository is left as it was; the removals are tried on a branch inside the sandbox and reverted.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "Find dead code in this Vue app and change nothing in the repository. Read index.html, src/main.ts, src/plugins, vite.config.ts, tsconfig.json, package.json, playwright/tsconfig.json and .github/workflows/test.yml first, and configure knip with every entry point they name, treating src/services/api.ts as generated. Run knip, then check each unused file, export and dependency by removing it on a scratch branch and running pnpm type-check, pnpm build and pnpm test:unit. Write dead-code.md with one table per kind giving the path, the line, the last commit that touched it and the checks that passed, a list of false positives with the command that failed, and a section on what the tool cannot see. Leave the working tree clean.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
  1. Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
  2. Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
  3. Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

What comes back

What comes back is dead-code.md as an artifact on the session, with a url on api.prix.dev that downloads it without a key until url_expires_at, and the same file through the artifacts route with the key. The session's result summarizes the counts per kind. The repository has no new commit and no branch; the transcript ends with a clean git status.

Each row names a path, a line, the commit that last touched it and the three checks it survived, so a reviewer can open the file, confirm nothing imports it, and decide. The generated API client's unused methods are listed apart, as expected, and the false positives explain which check failed, which is often the most useful part for the next person who runs knip.

The transcript holds the knip run with its full output and each check with its output, so a row can be traced to the command that justified it. A follow-up message to the same session can ask for the safe removals to be applied and opened as a pull request, and the sandbox already has the app installed.

Run it on every first Monday of the month

In the console, add an automation to the Project with a schedule trigger set to a cron expression for the first Monday and your timezone, and this prompt. Each run writes a fresh report as its artifact, so the month's new dead code shows up as new rows against the last report.

From your own server, the same request with a webhook_url on the API key posts run.completed when the turn finishes; the handler downloads dead-code.md from the session and files it where the team reads it. An Idempotency-Key built from the month makes a retried request return the same run.

The use case this job follows, with its automation and trigger: Produce a report or file, no repo.

Why run it on Rush?

Running knip is a minute; checking its output is the work, because every candidate needs a type check, a build and a test run after its removal, and a Vite build plus a Vitest run over an app many times over is an afternoon on a laptop. The sandbox installs with pnpm once and runs the loop as many times as there are candidates, and nothing it removes touches your checkout.

The report is only worth reading if each row carries its evidence, and the transcript keeps the commands behind every row. Several front ends can be scanned at once, each in its own sandbox, each producing its own file, up to the key's max_concurrent limit.

Frequently asked questions

Will it delete anything from my repository?

No. The removals happen on a scratch branch inside the sandbox to run the checks, and the branch is discarded; the result is the report. Ask in a follow-up for the safe rows to be applied and the agent opens a pull request from the same sandbox.

Why does the generated API client get its own section?

Because src/services/api.ts is written by swagger-typescript-api from the OpenAPI file and regenerated by the generate:api script, so removing a method from it would come back on the next run. The report lists those unused methods for information and keeps them out of the removal candidates.

Why not just run knip in CI?

Do that too, with the configuration the agent writes, so new dead code is caught at review. The one-off report is for the backlog that exists today, where each row needs the build and test checks before someone removes it, and that is what the run does.

Does it catch unused component props or unused code inside a function?

No. knip works at the file, export and dependency level, and vue-tsc already enforces noUnusedLocals in this project, which covers locals and parameters. Unused props and branches that can never run are a different kind of analysis, and the report's last section says so.