{"id":49273692,"url":"https://github.com/jeremydev87/kratos","last_synced_at":"2026-04-25T15:03:59.796Z","repository":{"id":352051993,"uuid":"1213524527","full_name":"JeremyDev87/kratos","owner":"JeremyDev87","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-24T23:46:21.000Z","size":292,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-25T01:32:14.879Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JeremyDev87.png","metadata":{"files":{"readme":"README.en.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"JeremyDev87"}},"created_at":"2026-04-17T13:25:46.000Z","updated_at":"2026-04-24T23:46:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/JeremyDev87/kratos","commit_stats":null,"previous_names":["jeremydev87/kratos"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/JeremyDev87/kratos","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyDev87%2Fkratos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyDev87%2Fkratos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyDev87%2Fkratos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyDev87%2Fkratos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JeremyDev87","download_url":"https://codeload.github.com/JeremyDev87/kratos/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeremyDev87%2Fkratos/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32265985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T09:15:33.318Z","status":"ssl_error","status_checked_at":"2026-04-25T09:15:31.997Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-25T15:03:52.986Z","updated_at":"2026-04-25T15:03:59.790Z","avatar_url":"https://github.com/JeremyDev87.png","language":"Rust","funding_links":["https://github.com/sponsors/JeremyDev87"],"categories":[],"sub_categories":[],"readme":"# Kratos\n\n[![CI](https://github.com/JeremyDev87/kratos/actions/workflows/ci.yml/badge.svg)](https://github.com/JeremyDev87/kratos/actions/workflows/ci.yml)\n\n[한국어](README.md) | English | [中文](README.zh-CN.md) | [Español](README.es.md) | [日本語](README.ja.md)\n\nDestroy dead code ruthlessly.\n\n[License](LICENSE) · [Contributing](CONTRIBUTING.md) · [Code of Conduct](CODE_OF_CONDUCT.md) · [Security](SECURITY.md) · [Sponsor](https://github.com/sponsors/JeremyDev87)\n\nKratos is a CLI tool for JavaScript and TypeScript projects. It finds unused files, broken imports, unused exports, and orphaned modules, then writes the results to a report. The current implementation combines a Rust core/CLI with an npm launcher, and the npm package `@jeremyfellaz/kratos` loads an optional platform-specific native add-on.\n\nKratos is an analysis tool for a safe cleanup workflow, not an automatic deletion bot. `clean` is dry-run by default, and files are only removed after you review the report and explicitly pass `--apply`.\n\n## Core Capabilities\n\n- Detect unused files and orphaned component/module candidates\n- Detect broken internal imports\n- Detect unused export and import candidates\n- Apply Next.js `app/` / `pages/` route entrypoint heuristics\n- Resolve `tsconfig.json` / `jsconfig.json` `baseUrl` and `paths` aliases\n- Resolve `package.json` `main`, `module`, `types`, `bin`, and `exports` entrypoints\n- Print saved reports as summary, JSON, or Markdown\n- Compare finding changes between two reports\n- Preview safe deletion candidates with a confidence threshold\n\n## Quick Start\n\nFor package users, the default entrypoint is `npx`.\n\n```bash\nnpx @jeremyfellaz/kratos scan ./my-app\nnpx @jeremyfellaz/kratos report ./my-app\nnpx @jeremyfellaz/kratos report ./my-app --format md\nnpx @jeremyfellaz/kratos clean ./my-app --min-confidence 0.9\n```\n\nOnly add `--apply` after reviewing the report and deciding to delete the listed targets.\n\n```bash\nnpx @jeremyfellaz/kratos clean ./my-app --apply --min-confidence 0.9\n```\n\nYou can also compare reports from two points in time.\n\n```bash\nnpx @jeremyfellaz/kratos scan ./my-app --output .kratos/before.json\n# clean up code or switch branches\nnpx @jeremyfellaz/kratos scan ./my-app --output .kratos/after.json\nnpx @jeremyfellaz/kratos diff ./my-app/.kratos/before.json ./my-app/.kratos/after.json\n```\n\nWhen `scan --output` receives a relative path, it is resolved from the scanned root. The default saved report is `\u003croot\u003e/.kratos/latest-report.json`.\n\n## Commands\n\n### `kratos scan [root] [--output path] [--json]`\n\nAnalyzes a project and writes a report JSON file.\n\n- Omit `root` to scan the current working directory.\n- `--output path` sets the report output path.\n- `--json` prints the full report JSON to stdout instead of the console summary.\n- The default output path is `\u003croot\u003e/.kratos/latest-report.json`.\n\n### `kratos report [report-path-or-root] [--format summary|json|md]`\n\nPrints a saved report in a human-readable format or as raw JSON.\n\n- `summary` is the default console summary.\n- `json` pretty-prints the saved report JSON.\n- `md` prints a Markdown report that is easy to share.\n- If the input is a project root, Kratos resolves `.kratos/latest-report.json` automatically.\n\n### `kratos diff [before-report-path-or-root] [after-report-path-or-root] [--format summary|json|md]`\n\nCompares finding changes between two reports.\n\n- The default format is `summary`.\n- `json` prints introduced/resolved/persisted findings in a machine-readable shape.\n- `md` prints a Markdown diff suitable for reviews or issues.\n- Each input can be either a report file path or a project root.\n\n### `kratos clean [report-path-or-root] [--apply] [--min-confidence value]`\n\nPreviews deletion candidates or deletes them.\n\n- Dry-run is the default behavior.\n- Files are deleted only when `--apply` is present.\n- `--min-confidence value` is a confidence threshold from `0.0` to `1.0`.\n- If `--min-confidence` is omitted, Kratos reads `thresholds.cleanMinConfidence` from `kratos.config.json`; when no setting exists, it uses `0.0`.\n\n## Output Examples\n\nScanning `fixtures/demo-app` produces a summary like this.\n\n```text\nKratos scan complete.\n\nRoot: \u003croot\u003e\nFiles scanned: 5\nEntrypoints: 1\nBroken imports: 1\nOrphan files: 2\nDead exports: 3\nUnused imports: 0\nRoute entrypoints: 1\nDeletion candidates: 2\n\nSaved report: \u003croot\u003e/.kratos/latest-report.json\n\nBroken imports:\n- \u003croot\u003e/src/lib/broken.ts -\u003e ./missing-helper\n\nOrphan files:\n- \u003croot\u003e/src/components/DeadWidget.tsx\n- \u003croot\u003e/src/lib/broken.ts\n\nDead exports:\n- \u003croot\u003e/src/components/DeadWidget.tsx#DeadWidget\n- \u003croot\u003e/src/lib/broken.ts#brokenFeature\n- \u003croot\u003e/src/lib/math.ts#multiply\n```\n\n`clean --min-confidence 0.9` separates deletion targets from candidates skipped by the threshold.\n\n```text\nKratos clean dry run.\n\nDeletion targets: 1\n- \u003croot\u003e/src/components/DeadWidget.tsx (confidence 0.92, Component-like module has no inbound references.)\n\nThreshold-skipped targets: 1\n- \u003croot\u003e/src/lib/broken.ts (confidence 0.88, Module has no inbound references and is not treated as an entrypoint.)\n\nRe-run with --apply to delete these files.\n```\n\nComparing identical reports shows no introduced or resolved findings, only persisted counts.\n\n```text\nKratos diff complete.\n\nBefore: \u003cbefore-report\u003e\nAfter: \u003cafter-report\u003e\n\nBroken imports: introduced 0, resolved 0, persisted 1\nOrphan files: introduced 0, resolved 0, persisted 2\nDead exports: introduced 0, resolved 0, persisted 3\nUnused imports: introduced 0, resolved 0, persisted 0\nRoute entrypoints: introduced 0, resolved 0, persisted 1\nDeletion candidates: introduced 0, resolved 0, persisted 2\n\nTotals: introduced 0, resolved 0, persisted 9\n```\n\n## Report Schema\n\n`scan` currently writes `schemaVersion: 2` reports.\n\n```json\n{\n  \"schemaVersion\": 2,\n  \"summary\": {\n    \"filesScanned\": 5,\n    \"entrypoints\": 1,\n    \"brokenImports\": 1,\n    \"orphanFiles\": 2,\n    \"deadExports\": 3,\n    \"unusedImports\": 0,\n    \"routeEntrypoints\": 1,\n    \"deletionCandidates\": 2\n  }\n}\n```\n\n`findings` contains `brokenImports`, `orphanFiles`, `deadExports`, `unusedImports`, `routeEntrypoints`, and `deletionCandidates`. `graph.modules` records analyzed module paths, entrypoint status, and import/export counts.\n\n## Configuration\n\nYou can place `kratos.config.json` in the project root. JSONC-style comments and trailing commas are accepted.\n\n```json\n{\n  \"ignore\": [\"storybook-static\", \"generated\"],\n  \"ignorePatterns\": [\"src/generated/**\", \"!src/generated/keep.ts\"],\n  \"entry\": [\"src/bootstrap.ts\"],\n  \"roots\": [\"src\", \"app\", \"pages\"],\n  \"thresholds\": {\n    \"cleanMinConfidence\": 0.85\n  },\n  \"suppressions\": [\n    {\n      \"kind\": \"deadExport\",\n      \"file\": \"src/components/LazyCard.tsx\",\n      \"export\": \"default\",\n      \"reason\": \"Loaded dynamically by route metadata.\"\n    },\n    {\n      \"kind\": \"brokenImport\",\n      \"file\": \"src/legacy/shim.ts\",\n      \"source\": \"./generated-shim\",\n      \"reason\": \"Generated at deploy time.\"\n    }\n  ]\n}\n```\n\n- `ignore`: directory names added to the default ignore list.\n- `ignorePatterns`: `.gitignore`-style path patterns. Use `!` negation for exceptions.\n- After the default ignored directories, Kratos also reads the project root `.gitignore` automatically, then applies `ignorePatterns` for exceptions or overrides.\n- `entry`: root-relative files forced to be entrypoints.\n- `roots`: root-relative directories that limit scan scope.\n- `thresholds.cleanMinConfidence`: default confidence threshold for `clean`.\n- `suppressions`: findings that should be intentionally ignored. `kind` must be one of `brokenImport`, `orphanFile`, `deadExport`, `unusedImport`, or `deletionCandidate`.\n\nIf `.kratos/suppressions.json` exists, Kratos reads it with the same suppression format. `file` values must be relative to the project root.\n\n## Local Development\n\nRequirements:\n\n- Node.js 18+\n- npm 9+\n- Rust stable toolchain\n\nInstall:\n\n```bash\nnpm install\n```\n\nRecommended verification:\n\n```bash\ncargo test --workspace\nnpm run verify\nnpm run smoke\n```\n\nIn a repository checkout, published native add-on packages may not exist yet, so these commands are safer than `npx @jeremyfellaz/kratos ...`.\n\n```bash\nnpm run scan -- ./fixtures/demo-app\nnpm run report -- ./fixtures/demo-app/.kratos/latest-report.json\nnpm run clean -- ./fixtures/demo-app/.kratos/latest-report.json\ncargo run -p kratos-cli -- diff ./fixtures/demo-app ./fixtures/demo-app\n```\n\n## Distribution\n\n- The root npm package is `@jeremyfellaz/kratos`.\n- The CLI binary name is `kratos`.\n- Platform add-on packages target macOS arm64/x64, Linux x64/arm64, and Windows x64.\n- Root package `optionalDependencies` point to platform add-on packages at the same release version.\n- A raw checkout may not have a native add-on, but the released package launcher loads the add-on for the current platform.\n\n## Release Flow\n\nReleases are driven by semver tags such as `vX.Y.Z` or `vX.Y.Z-prerelease.N`.\n\n- The `Manual Release Bump` workflow prepares a version-only PR that aligns `package.json` and platform `optionalDependencies`.\n- Before tagging, the same commit should pass `cargo test --workspace`, `npm run verify`, and native packaging CI.\n- The `Release Publish` workflow checks out the exact tag ref, verifies the Node package, runs Rust workspace tests, and builds platform native artifacts.\n- Platform add-on npm packages are packed, smoke-tested, and published first; the root package is published last, then the GitHub Release is created or updated.\n- The `Release Published Follow-up` workflow audits whether the published release has a matching successful publish run and release assets. It does not rerun publishing.\n\nActions such as pushing release tags, publishing to npm, or publishing a GitHub Release should only happen after maintainer confirmation.\n\n## Open Source\n\nKratos is open source under the MIT license.\n\n- Use GitHub Issues for bug reports and feature requests.\n- Do not report security issues publicly; follow the process in [SECURITY.md](SECURITY.md).\n- Read [CONTRIBUTING.md](CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) before contributing.\n- If you want to support the project, you can sponsor it through [GitHub Sponsors](https://github.com/sponsors/JeremyDev87).\n\n## Note\n\nKratos combines conservative static analysis with heuristics. Dynamic imports, framework conventions, generated files, and runtime-only entrypoints can vary by project, so review the report and diff before running `--apply`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeremydev87%2Fkratos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeremydev87%2Fkratos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeremydev87%2Fkratos/lists"}