{"id":51012439,"url":"https://github.com/imjuni/shortsword","last_synced_at":"2026-06-21T05:01:28.014Z","repository":{"id":363003718,"uuid":"1257363487","full_name":"imjuni/shortsword","owner":"imjuni","description":"Enforce SFSR constraints for AI-assisted TypeScript codebases","archived":false,"fork":false,"pushed_at":"2026-06-06T23:54:12.000Z","size":101,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-07T01:12:01.963Z","etag":null,"topics":["ai","ai-coding","claude","claude-code","cli","code-quality","harness","harness-engineering","harness-framework","lint","sfsr","shortsword","static-analysis","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/imjuni.png","metadata":{"files":{"readme":"README.ko.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"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}},"created_at":"2026-06-02T15:55:54.000Z","updated_at":"2026-06-06T23:52:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/imjuni/shortsword","commit_stats":null,"previous_names":["imjuni/shortsword"],"tags_count":2,"template":false,"template_full_name":"imjuni/typescript-cli-esm-boilerplate","purl":"pkg:github/imjuni/shortsword","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imjuni%2Fshortsword","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imjuni%2Fshortsword/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imjuni%2Fshortsword/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imjuni%2Fshortsword/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/imjuni","download_url":"https://codeload.github.com/imjuni/shortsword/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imjuni%2Fshortsword/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34594326,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-21T02:00:05.568Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["ai","ai-coding","claude","claude-code","cli","code-quality","harness","harness-engineering","harness-framework","lint","sfsr","shortsword","static-analysis","typescript"],"created_at":"2026-06-21T05:01:27.374Z","updated_at":"2026-06-21T05:01:28.008Z","avatar_url":"https://github.com/imjuni.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shortsword\n\n![ts](https://flat.badgen.net/badge/Built%20With/TypeScript/blue)\n[![Download Status](https://img.shields.io/npm/dw/shortsword.svg)](https://npmcharts.com/compare/shortsword?minimal=true)\n[![Github Star](https://img.shields.io/github/stars/imjuni/shortsword.svg?style=popout)](https://github.com/imjuni/shortsword)\n[![Github Issues](https://img.shields.io/github/issues-raw/imjuni/shortsword.svg)](https://github.com/imjuni/shortsword/issues)\n[![NPM version](https://img.shields.io/npm/v/shortsword.svg)](https://www.npmjs.com/package/shortsword)\n[![License](https://img.shields.io/npm/l/shortsword.svg)](https://github.com/imjuni/shortsword/blob/master/LICENSE)\n[![ci](https://github.com/imjuni/shortsword/actions/workflows/ci.yml/badge.svg)](https://github.com/imjuni/shortsword/actions/workflows/ci.yml)\n[![code style: biome](https://img.shields.io/badge/code_style-biome-60a5fa.svg?style=flat-square)](https://biomejs.dev)\n\nShortsword는 ESLint, Biome과 같이 사용하는 간단한 도구입니다. 한 파일에 많은 코드를 추가하거나 수십 개의 선언을 추가하는 경우 이를 탐지할 수 있는 방법이 있으면 좋을 것 같아서 만들게 되었습니다. 특히 AI를 사용하여 코딩할 때 한 파일에 수십 개의 타입, 함수 등을 추가하는 경우를 보고 규칙을 작성했지만 컨텍스트 이슈로 인해서 이 규칙을 종종 무시하는 경우를 보고 harness로 동작할 수 있는 간단한 도구가 필요하겠다고 생각해서 작성하게 되었습니다.\n\n`--max-statements` 옵션을 사용하여 한 파일에 선언 가능한 최대 statement 개수를 설정할 수 있고, `--max-files`를 사용하여 한 디렉터리에 최대 몇 개까지 파일을 추가할 수 있는지 설정할 수 있습니다. `--use-abs-path` 옵션을 켜면 상대 경로 import를 탐지하여 path alias 또는 package subpath import를 사용하도록 유도할 수 있습니다.\n\nBefore:\n\n```text\nsrc/user.ts \u003e 12 statements\nsrc/features \u003e 24 files\n```\n\nAfter:\n\n```text\nsrc/user/createUser.ts \u003e 2 statements\nsrc/user/updateUser.ts \u003e 2 statements\nsrc/user/deleteUser.ts \u003e 2 statements\nsrc/features/user \u003e 8 files\nsrc/features/auth \u003e 6 files\nsrc/features/billing \u003e 5 files\n```\n\n자, 이제 shortsword를 사용하여 안전하고 즐거운 코딩하세요!\n\n## Usage\n\n```bash\nnpx swd\n```\n\n```bash\nnpx swd -s 2 -f 10 -x \"**/*.test.ts,**/__tests__/**\" -p ./tsconfig.json\n```\n\n## Options\n\n| Option | Alias | Default | Description |\n| --- | --- | ---: | --- |\n| `--max-statements` | `-s` | `2` | 한 파일에 허용할 최대 top-level statement 개수 |\n| `--max-files` | `-f` | `10` | 한 디렉터리에 허용할 최대 TypeScript 파일 개수 |\n| `--use-abs-path` | - | `false` | 상대 경로 import 검사 |\n| `--include` | `-i` | - | 추가로 포함할 glob 패턴 |\n| `--exclude` | `-x` | - | 추가로 제외할 glob 패턴 |\n| `--overrides` | `-o` | - | 특정 glob 패턴에 적용할 옵션 override JSON 배열 |\n| `--project` | `-p` | `./tsconfig.json` | `tsconfig.json` 경로. 검사 대상 파일을 tsconfig.json 기준으로 자동 적용 |\n| `--language` | `-l` | 자동 감지 | 메시지 언어 |\n| `--verbose` | `-v` | `false` | 디버그 로그 출력 |\n\n## Installation\n\n```bash\npnpm add -D shortsword typescript\n```\n\n```bash\nnpm install -D shortsword typescript\n```\n\n## Requirements\n\n- Node.js \u003e= 22\n- TypeScript \u003e= 6\n\n### Configuration\n\nCLI 옵션 대신 설정 파일을 사용할 수 있습니다. Shortsword는 `shortsword.config.ts`, `shortsword.config.js`, `.shortswordrc` 등 설정 파일을 읽습니다.\n\n```ts\nexport default {\n  \"max-statements\": 2,\n  \"max-files\": 10,\n  \"use-abs-path\": false,\n  exclude: [\"**/*.test.ts\", \"**/__tests__/**\", \"**/__test__/**\"],\n  overrides: [\n    {\n      include: [\"src/generated/**\"],\n      \"max-statements\": 10,\n      \"max-files\": 100,\n      \"use-abs-path\": false,\n    },\n  ],\n  project: \"./tsconfig.json\",\n};\n```\n\nCLI 옵션과 설정 파일을 함께 사용하면 CLI 옵션이 우선합니다.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimjuni%2Fshortsword","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fimjuni%2Fshortsword","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimjuni%2Fshortsword/lists"}