diff --git a/README.md b/README.md index 388943b..673eee7 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ **LLM-Friendly Convention Linter for AI Coding Tools** Symphony는 AI 개발환경(IDE, MCP 기반 LLM Tooling)을 위한 정책 기반 코드 컨벤션 검사기입니다. -간단한 설정만으로 프로젝트 규칙을 일관되게 적용하고, LLM 코드 생성 품질을 극대화할 수 있습니다. +간단한 설정만으로 프로젝트 규칙을 일관되게 적용하고, LLM 코드 생성 품질을 향상시킬 수 있습니다. --- @@ -27,7 +27,6 @@ Symphony는 AI 개발환경(IDE, MCP 기반 LLM Tooling)을 위한 정책 기반 - [`edit_convention`](#edit_convention) - [`remove_convention`](#remove_convention) - [`convert`](#convert) - - [컨벤션 파일](#컨벤션-파일) - [요구사항](#요구사항) - [지원 플랫폼](#지원-플랫폼) - [라이선스](#라이선스) @@ -52,6 +51,12 @@ npm install -g @dev-symphony/sym # 2. 프로젝트 초기화 (.sym/ 폴더 생성 + MCP 설정) sym init + +# 3. 컨벤션 관리 +# LLM IDE를 통해 기존 문서나 자연어로 컨벤션을 생성, 관리합니다. '컨벤션 관리' 부분을 참고해 주세요. + +# 4. 컨벤션 적용 +# LLM IDE에서 작업하면, 작업 전 컨벤션을 자동으로 가져오고, 작업 후 컨벤션을 자동으로 검증합니다. ``` --- @@ -60,13 +65,13 @@ sym init 컨벤션은 아래 3가지 방식으로 관리할 수 있습니다: -- **CLI 명령어**: `sym category|convention|import|convert` - **MCP 도구(권장)**: `list_*`, `add_*`, `edit_*`, `remove_*`, `import_convention`, `convert` - **Dashboard**: `sym dash`로 웹에서 편집 +- **CLI 명령어**: `sym category|convention|import|convert` -권장사항: **LLM IDE(Cursor/Claude Code 등)를 사용한다면 MCP 기반 관리**를 권장합니다(조회/편집/변환/검증을 일관된 플로우로 자동화 가능). +권장사항: **LLM IDE(Cursor/Claude Code 등)를 사용한다면 MCP 기반 관리**를 권장합니다. -예시 문장: “`docs/team-standards.md`를 컨벤션에 반영해줘.” +예시 문장: "`docs/team-standards.md`를 컨벤션에 반영해줘." 자세한 내용은 [`docs/CONVENTION_MANAGEMENT.md`](docs/CONVENTION_MANAGEMENT.md)를 참고하세요. @@ -150,44 +155,6 @@ sym init --- -## 컨벤션 파일 - -Symphony는 프로젝트 컨벤션을 **정책 파일(`.sym/user-policy.json`)**로 관리합니다. -아래 명령으로 대시보드를 열어 쉽게 편집할 수 있습니다. - -```bash -sym dashboard -``` - -컨벤션/카테고리를 수정한 후에는 아래 명령으로 린터 설정을 갱신하세요: - -```bash -sym convert -``` - -자세한 관리 방법은 문서에서 확인할 수 있습니다: [`docs/CONVENTION_MANAGEMENT.md`](docs/CONVENTION_MANAGEMENT.md) - -예시 정책 파일: - -```json -{ - "version": "1.0.0", - "rules": [ - { - "say": "Functions should be documented", - "category": "documentation" - }, - { - "say": "Lines should be less than 100 characters", - "category": "formatting", - "params": { "max": 100 } - } - ] -} -``` - ---- - ## 요구사항 - Node.js >= 16.0.0 diff --git a/docs/CONVENTION_MANAGEMENT.md b/docs/CONVENTION_MANAGEMENT.md index 496f00b..b0227c1 100644 --- a/docs/CONVENTION_MANAGEMENT.md +++ b/docs/CONVENTION_MANAGEMENT.md @@ -4,7 +4,7 @@ - **MCP 방식**: Cursor/Claude Code 등 LLM 도구가 MCP 도구를 호출해 규칙/카테고리를 조회·변경 - **Dashboard 방식**: 로컬 웹 대시보드에서 직접 편집 -- **Import 방식**: 기존 문서(마크다운/텍스트/코드)에서 LLM이 컨벤션을 추출해 정책에 병합 +- **CLI 방식**: `sym` command를 사용해 규칙/카테고리를 조회·변경 > 중요: 컨벤션/카테고리를 추가/편집/삭제한 뒤에는 **변환(`convert`)을 실행해** `.sym/code-policy.json` 및 린터 설정 파일을 갱신하는 것을 권장합니다. @@ -156,12 +156,6 @@ sym dashboard sym dash ``` -이 저장소에서 빌드된 바이너리를 사용한다면 다음도 가능합니다: - -```bash -./bin/sym dash -``` - 브라우저에서 `http://localhost:8787`로 접속합니다. ### 카테고리 관리 @@ -173,40 +167,114 @@ sym dash ### 컨벤션(규칙) 관리 - **추가**: 규칙 ID, 설명(say), 카테고리, 언어, 심각도 등을 입력 -- **편집**: 기존 규칙의 속성 수정(언어/카테고리 변경 포함) +- **편집**: 기존 규칙의 속성 수정 - **삭제**: 규칙 삭제 ### 변환 -대시보드에서 `user-policy.json`을 수정한 뒤, 저장을 누르면 convert할지 요청을 합니다. +대시보드에서 저장을 누르면 convert할지 요청을 합니다. --- -## 3) Import로 컨벤션 관리 (문서 → 정책 병합) +## 3) CLI를 사용한 컨벤션/카테고리 관리 -Import는 팀 가이드/보안 규칙/코딩 표준 문서처럼 **이미 존재하는 문서**를 기준으로, LLM이 컨벤션을 추출해 `.sym/user-policy.json`에 병합하는 방식입니다. +CLI 방식은 `sym` 명령어로 **카테고리/컨벤션(규칙)을 조회·추가·편집·삭제**하고, 마지막에 `convert`/`validate`로 파생 산출물 생성 및 검증까지 한 번에 처리하는 방법입니다. -### 권장 흐름(사용자 관점) +### 준비 -1. 문서 준비: 예) `docs/team-standards.md` -2. Import 실행(아래 3가지 방법 중 택1) -3. `convert` 실행(파생 정책/린터 설정 갱신) -4. (선택) `validate` 또는 MCP `validate_code`로 Git 변경사항 검증 +- 프로젝트가 초기화돼 있어야 합니다. -### (A) CLI로 Import (`sym import`) +```bash +sym init +``` + +- (선택) 현재 사용 중인 정책 파일 경로를 확인합니다. ```bash -# 기본: append (기존 유지 + 새 항목 추가) -sym import docs/team-standards.md +sym policy path +``` -# 기존 컨벤션을 비우고 새로 구성하려면 (주의) -sym import docs/team-standards.md --mode clear +### 기본 흐름(권장) -# Import 이후 파생 정책/린터 설정 갱신 +1. 카테고리 조회/정리 +2. 컨벤션(규칙) 조회/정리 +3. **`sym convert` 실행**(파생 정책/린터 설정 갱신) +4. (선택) **`sym validate` 실행**(Git 변경사항 검증) + +### 카테고리 관리 + +```bash +# 목록 +sym category list + +# 추가 +sym category add accessibility "Accessibility rules (WCAG, ARIA, etc.)" + +# 편집(이름/설명) +sym category edit security --description "Updated security rules" +sym category edit old-name --name new-name + +# 삭제(참조 중인 규칙이 있으면 삭제 불가) +sym category remove deprecated-category +``` + +> 팁: 여러 항목을 한 번에 처리해야 한다면 `-f ` 형태의 파일 입력 옵션을 사용할 수 있습니다. + +### 컨벤션(규칙) 관리 + +```bash +# 목록(필터) +sym convention list +sym convention list --category security +sym convention list --language go + +# 추가 +sym convention add SEC-001 "Use parameterized queries" --category security --languages go,python --severity error + +# 편집 +sym convention edit SEC-001 --severity warning +sym convention edit SEC-001 --new-id SEC-001-v2 + +# 삭제 +sym convention remove SEC-001 +``` + +### 변환/검증 + +컨벤션/카테고리를 변경한 뒤에는 파생 정책 및 린터 설정이 최신이 되도록 변환을 실행하는 것을 권장합니다. + +```bash +# 파생 정책/린터 설정 갱신 sym convert + +# 정책 파일을 직접 지정하거나, 출력 디렉토리를 바꾸고 싶다면 +sym convert -i user-policy.json +sym convert -i user-policy.json -o ./custom-dir +``` + +Git 변경사항 기준으로 정책 위반을 검증하려면: + +```bash +sym validate +sym validate --staged +sym validate --policy custom-policy.json +sym validate --timeout 60 ``` -### (B) MCP로 Import (`import_convention`) +--- + +## Import로 컨벤션 관리 (문서 → 정책 병합) + +Import는 팀 가이드/보안 규칙/코딩 표준 문서처럼 **이미 존재하는 문서**를 기준으로, LLM이 컨벤션을 추출해 `.sym/user-policy.json`에 병합하는 방식입니다. + +### 권장 흐름(사용자 관점) + +1. 문서 준비: 예) `docs/team-standards.md` +2. Import 실행(아래 3가지 방법 중 택1) +3. `convert` 실행(파생 정책/린터 설정 갱신) +4. (선택) `validate` 또는 MCP `validate_code`로 Git 변경사항 검증 + +### (A) MCP로 Import (`import_convention`) LLM IDE(Cursor/Claude Code 등)에서 Symphony MCP 도구를 사용할 수 있다면 다음 흐름을 권장합니다: @@ -225,7 +293,20 @@ LLM IDE(Cursor/Claude Code 등)에서 Symphony MCP 도구를 사용할 수 있 > 예: “`docs/team-standards.md`를 컨벤션으로 반영해줘”라고 요청하면, LLM이 `import_convention` → `convert` → (필요 시) `validate_code` 순으로 실행하는 형태를 기대할 수 있습니다. -### (C) Dashboard에서 Import +### (B) Dashboard에서 Import 대시보드(`sym dash` 또는 `./bin/sym dash`)에서도 Import UI를 통해 문서를 선택해 정책에 병합할 수 있습니다. -Import 후에는 저장을 누르면 convert할지 요청을 합니다. +Import 후에는 저장을 누르면 convert할지 사용자에게 요청을 합니다. + +### (C) CLI로 Import (`sym import`) + +```bash +# 기본: append (기존 유지 + 새 항목 추가) +sym import docs/team-standards.md + +# 기존 컨벤션을 비우고 새로 구성하려면 (주의) +sym import docs/team-standards.md --mode clear + +# Import 이후 파생 정책/린터 설정 갱신 +sym convert +``` diff --git a/internal/cmd/convention.go b/internal/cmd/convention.go index 01c1c89..9fc9110 100644 --- a/internal/cmd/convention.go +++ b/internal/cmd/convention.go @@ -58,10 +58,17 @@ Available subcommands: var conventionListCmd = &cobra.Command{ Use: "list", Short: "List all conventions", - Long: `List all conventions with their ID, category, description, and severity. + Long: `List conventions with their ID, category, description, and severity. Conventions are defined in user-policy.json and can be customized by the user. -Run 'sym init' to create default conventions.`, +Run 'sym init' to create default conventions. + +Examples: + sym convention list + sym convention list --category security + sym convention list --languages go + sym convention list --languages go,javascript + sym convention list --category style --languages typescript`, RunE: runConventionList, } @@ -168,9 +175,22 @@ func init() { // Remove command flags conventionRemoveCmd.Flags().StringP("file", "f", "", "JSON file with convention IDs to remove") + + // List command flags + conventionListCmd.Flags().String("category", "", "Filter by category (e.g., security, style, documentation)") + conventionListCmd.Flags().StringSlice("languages", nil, "Filter by programming languages (comma-separated)") } func runConventionList(cmd *cobra.Command, args []string) error { + // Get filter flags + categoryFilter, _ := cmd.Flags().GetString("category") + languagesFilter, _ := cmd.Flags().GetStringSlice("languages") + + // Normalize category: "all" or empty means no filtering + if strings.EqualFold(categoryFilter, "all") { + categoryFilter = "" + } + // Load conventions from user-policy.json userPolicy, err := roles.LoadUserPolicyFromRepo() if err != nil { @@ -186,10 +206,46 @@ func runConventionList(cmd *cobra.Command, args []string) error { return nil } - printTitle("Conventions", fmt.Sprintf("%d conventions available", len(rules))) + // Filter rules + var filteredRules []schema.UserRule + for _, rule := range rules { + // Category filter + if categoryFilter != "" && rule.Category != categoryFilter { + continue + } + + // Languages filter: if both request and rule have languages, check intersection + if len(languagesFilter) > 0 && len(rule.Languages) > 0 { + if !containsAny(rule.Languages, languagesFilter) { + continue + } + } + + filteredRules = append(filteredRules, rule) + } + + // Build filter description for output + filterDesc := "" + if categoryFilter != "" || len(languagesFilter) > 0 { + parts := []string{} + if categoryFilter != "" { + parts = append(parts, fmt.Sprintf("category=%s", categoryFilter)) + } + if len(languagesFilter) > 0 { + parts = append(parts, fmt.Sprintf("languages=%s", strings.Join(languagesFilter, ","))) + } + filterDesc = fmt.Sprintf(" (filtered: %s)", strings.Join(parts, ", ")) + } + + if len(filteredRules) == 0 { + printWarn(fmt.Sprintf("No conventions found%s", filterDesc)) + return nil + } + + printTitle("Conventions", fmt.Sprintf("%d conventions available%s", len(filteredRules), filterDesc)) fmt.Println() - for _, rule := range rules { + for _, rule := range filteredRules { // Format: ID [CATEGORY] (languages): description languages := "" if len(rule.Languages) > 0 { @@ -569,6 +625,18 @@ func runConventionRemove(cmd *cobra.Command, args []string) error { return nil } +// containsAny checks if haystack contains any of the needles. +func containsAny(haystack, needles []string) bool { + for _, needle := range needles { + for _, hay := range haystack { + if hay == needle { + return true + } + } + } + return false +} + // printConventionBatchResult prints the result of a batch operation for conventions. func printConventionBatchResult(action string, succeeded, failed []string) { if len(failed) == 0 && len(succeeded) > 0 { diff --git a/internal/linter/golangcilint/converter.go b/internal/linter/golangcilint/converter.go index 7a4d0fb..63c32a7 100644 --- a/internal/linter/golangcilint/converter.go +++ b/internal/linter/golangcilint/converter.go @@ -210,7 +210,7 @@ func (c *Converter) convertToGolangciLinter(ctx context.Context, rule schema.Use systemPrompt := `You are a golangci-lint v2 configuration expert. Convert natural language Go coding rules to golangci-lint linter or formatter names and settings. CRITICAL: In golangci-lint v2, FORMATTERS and LINTERS are DIFFERENT categories. -- FORMATTERS: Tools that format code (gofmt, goimports, gofumpt, gci, golines, swaggo) +- FORMATTERS: Tools that format code (gofmt, goimports, gofumpt, gci, golines) - LINTERS: Tools that analyze code for issues (errcheck, govet, gosec, etc.) Return ONLY a JSON object (no markdown fences) with this structure: @@ -221,72 +221,76 @@ Return ONLY a JSON object (no markdown fences) with this structure: } === FORMATTERS (is_formatter: true) === -Use these for code formatting rules: -- gofmt: Formats code according to standard Go formatting -- goimports: Formats imports and adds missing imports +- gofmt: Standard Go formatting +- goimports: Formats imports and adds missing ones - gofumpt: Stricter formatting than gofmt -- gci: Import statement formatting with custom ordering -- golines: Fixes long lines by wrapping them -- swaggo: Formats swaggo comments +- gci: Import ordering (settings: {"sections": ["standard", "default", "prefix(github.com/myorg)"]}) +- golines: Line length limiting (settings: {"max-len": 120}) === LINTERS (is_formatter: false) === -Error Handling: -- errcheck: Check for unchecked errors -- wrapcheck: Checks that errors from external packages are wrapped -- nilerr: Finds code that returns nil even if it checks that the error is not nil - -Code Quality: -- govet: Examines Go source code and reports suspicious constructs -- staticcheck: Advanced static analysis (find bugs, performance issues) -- ineffassign: Detects ineffectual assignments -- unused: Checks for unused code -- revive: Fast, configurable linter (replacement for golint) - -Complexity: -- gocyclo: Computes cyclomatic complexity -- gocognit: Computes cognitive complexity -- nestif: Reports deeply nested if statements -- funlen: Detects long functions -- cyclop: Checks function and package cyclomatic complexity - -Performance: -- prealloc: Finds slice declarations that could be preallocated -- bodyclose: Checks whether HTTP response body is closed - -Security: -- gosec: Inspects source code for security problems - -Style: -- stylecheck: Enforces Go style guide -- goconst: Finds repeated strings for constants -- misspell: Finds misspelled English words -- godot: Checks if comments end in a period -- nlreturn: Checks for blank lines before return - -Other Linters: -- dupl: Code clone detection -- gocritic: Checks for bugs, performance and style issues -- gosimple: Simplifies code -- noctx: Finds HTTP requests without context -- unconvert: Removes unnecessary type conversions -- exportloopref: Checks for pointers to loop variables - -Settings examples: -- gocyclo: {"min-complexity": 10} -- gocognit: {"min-complexity": 15} -- funlen: {"lines": 60, "statements": 40} -- gosec: {"severity": "medium", "confidence": "medium"} -- errcheck: {"check-type-assertions": true} -- gofmt: {"simplify": true} -- goimports: {"local-prefixes": "github.com/myorg"} - -CRITICAL RULES: -1. ONLY use actual golangci-lint tools - do NOT invent names -2. For formatting rules (gofmt, goimports, etc.) → set is_formatter: true -3. For analysis/linting rules → set is_formatter: false -4. If no tool can enforce this requirement, return name as empty string "" -5. Settings are optional - only include if the rule specifies parameters +ERROR HANDLING: +- errcheck: Unchecked errors (settings: {"check-type-assertions": true, "check-blank": true}) +- wrapcheck: Errors from external packages must be wrapped +- nilerr: Returns nil even when error is not nil +- err113: Error handling best practices +- errorlint: Error wrapping issues (settings: {"errorf": true}) + +CODE QUALITY: +- govet: Suspicious constructs +- staticcheck: Advanced static analysis (includes style checks formerly in stylecheck) +- ineffassign: Ineffectual assignments +- unused: Unused code detection +- revive: Configurable linter (replacement for golint, can check style/naming) + +COMPLEXITY: +- gocyclo: Cyclomatic complexity (settings: {"min-complexity": 10}) +- gocognit: Cognitive complexity (settings: {"min-complexity": 15}) +- funlen: Function length (settings: {"lines": 60, "statements": 40}) +- nestif: Nested if depth (settings: {"min-complexity": 4}) +- cyclop: Package complexity + +PERFORMANCE: +- prealloc: Slice preallocation opportunities +- bodyclose: HTTP response body closure +- perfsprint: fmt.Sprintf optimization + +SECURITY: +- gosec: Security vulnerabilities (settings: {"severity": "medium", "confidence": "medium"}) + +STYLE & NAMING: +- goconst: Repeated strings for constants (settings: {"min-len": 3, "min-occurrences": 3}) +- misspell: Spelling errors (settings: {"locale": "US"}) +- godot: Comments end with period +- nlreturn: Blank line before return +- varnamelen: Variable name length (settings: {"min-name-length": 3}) +- lll: Line length limit (settings: {"line-length": 120}) + +DOCUMENTATION: +- godoclint: Godoc comment validation + +OTHER: +- dupl: Code duplication (settings: {"threshold": 100}) +- gocritic: Bugs, performance, style issues +- noctx: HTTP requests without context +- unconvert: Unnecessary type conversions +- mnd: Magic number detection (settings: {"checks": ["argument", "case", "condition", "operation", "return", "assign"]}) + +IMPORTANT - REMOVED/CHANGED IN v2: +1. stylecheck is REMOVED - use staticcheck or revive instead +2. gosimple is MERGED into staticcheck +3. typecheck is now built-in (don't use) +4. exportloopref is REMOVED (Go 1.22+ handles this) +5. For style rules, prefer revive (most configurable) or staticcheck + +DECISION GUIDE: +- Error must be checked → errcheck +- Error wrapping → wrapcheck or errorlint +- Style/naming rules → revive (most flexible) or staticcheck +- Line length → lll (linter) or golines (formatter) +- Variable naming → varnamelen or revive +- Security issues → gosec +- Cannot be enforced → return empty name "" Examples: @@ -298,14 +302,6 @@ Output: "settings": {} } -Input: "Imports should be properly organized" -Output: -{ - "name": "goimports", - "is_formatter": true, - "settings": {} -} - Input: "Check for unchecked errors" Output: { @@ -322,14 +318,30 @@ Output: "settings": {"min-complexity": 15} } -Input: "Detect security vulnerabilities" +Input: "Follow Go style guide" Output: { - "name": "gosec", + "name": "staticcheck", "is_formatter": false, "settings": {} } +Input: "Variable names should be descriptive" +Output: +{ + "name": "varnamelen", + "is_formatter": false, + "settings": {"min-name-length": 3} +} + +Input: "Line length should not exceed 120 characters" +Output: +{ + "name": "lll", + "is_formatter": false, + "settings": {"line-length": 120} +} + Input: "File names must be snake_case" Output: { @@ -398,26 +410,30 @@ func validateConfig(config *golangciConfig) error { return nil } -// isValidLinter checks if the name is a known golangci-lint linter (NOT formatter) +// isValidLinter checks if the name is a known golangci-lint v2 linter (NOT formatter) func isValidLinter(name string) bool { validLinters := map[string]bool{ // Error Handling "errcheck": true, "wrapcheck": true, "nilerr": true, "nilnil": true, + "err113": true, "errorlint": true, // Code Quality "govet": true, "staticcheck": true, "ineffassign": true, "unused": true, - "revive": true, "typecheck": true, + "revive": true, // Complexity "gocyclo": true, "gocognit": true, "nestif": true, "funlen": true, "cyclop": true, // Performance - "prealloc": true, "bodyclose": true, + "prealloc": true, "bodyclose": true, "perfsprint": true, // Security "gosec": true, - // Style (NOT formatters) - "stylecheck": true, "goconst": true, "misspell": true, "godot": true, "nlreturn": true, + // Style & Naming + "goconst": true, "misspell": true, "godot": true, "nlreturn": true, + "varnamelen": true, "lll": true, + // Documentation + "godoclint": true, // Other - "dupl": true, "gocritic": true, "gosimple": true, "noctx": true, - "unconvert": true, "exportloopref": true, "goprintffuncname": true, - "rowserrcheck": true, "sqlclosecheck": true, + "dupl": true, "gocritic": true, "noctx": true, + "unconvert": true, "goprintffuncname": true, + "rowserrcheck": true, "sqlclosecheck": true, "mnd": true, } return validLinters[strings.ToLower(name)] diff --git a/npm/README.md b/npm/README.md index 388943b..673eee7 100644 --- a/npm/README.md +++ b/npm/README.md @@ -3,7 +3,7 @@ **LLM-Friendly Convention Linter for AI Coding Tools** Symphony는 AI 개발환경(IDE, MCP 기반 LLM Tooling)을 위한 정책 기반 코드 컨벤션 검사기입니다. -간단한 설정만으로 프로젝트 규칙을 일관되게 적용하고, LLM 코드 생성 품질을 극대화할 수 있습니다. +간단한 설정만으로 프로젝트 규칙을 일관되게 적용하고, LLM 코드 생성 품질을 향상시킬 수 있습니다. --- @@ -27,7 +27,6 @@ Symphony는 AI 개발환경(IDE, MCP 기반 LLM Tooling)을 위한 정책 기반 - [`edit_convention`](#edit_convention) - [`remove_convention`](#remove_convention) - [`convert`](#convert) - - [컨벤션 파일](#컨벤션-파일) - [요구사항](#요구사항) - [지원 플랫폼](#지원-플랫폼) - [라이선스](#라이선스) @@ -52,6 +51,12 @@ npm install -g @dev-symphony/sym # 2. 프로젝트 초기화 (.sym/ 폴더 생성 + MCP 설정) sym init + +# 3. 컨벤션 관리 +# LLM IDE를 통해 기존 문서나 자연어로 컨벤션을 생성, 관리합니다. '컨벤션 관리' 부분을 참고해 주세요. + +# 4. 컨벤션 적용 +# LLM IDE에서 작업하면, 작업 전 컨벤션을 자동으로 가져오고, 작업 후 컨벤션을 자동으로 검증합니다. ``` --- @@ -60,13 +65,13 @@ sym init 컨벤션은 아래 3가지 방식으로 관리할 수 있습니다: -- **CLI 명령어**: `sym category|convention|import|convert` - **MCP 도구(권장)**: `list_*`, `add_*`, `edit_*`, `remove_*`, `import_convention`, `convert` - **Dashboard**: `sym dash`로 웹에서 편집 +- **CLI 명령어**: `sym category|convention|import|convert` -권장사항: **LLM IDE(Cursor/Claude Code 등)를 사용한다면 MCP 기반 관리**를 권장합니다(조회/편집/변환/검증을 일관된 플로우로 자동화 가능). +권장사항: **LLM IDE(Cursor/Claude Code 등)를 사용한다면 MCP 기반 관리**를 권장합니다. -예시 문장: “`docs/team-standards.md`를 컨벤션에 반영해줘.” +예시 문장: "`docs/team-standards.md`를 컨벤션에 반영해줘." 자세한 내용은 [`docs/CONVENTION_MANAGEMENT.md`](docs/CONVENTION_MANAGEMENT.md)를 참고하세요. @@ -150,44 +155,6 @@ sym init --- -## 컨벤션 파일 - -Symphony는 프로젝트 컨벤션을 **정책 파일(`.sym/user-policy.json`)**로 관리합니다. -아래 명령으로 대시보드를 열어 쉽게 편집할 수 있습니다. - -```bash -sym dashboard -``` - -컨벤션/카테고리를 수정한 후에는 아래 명령으로 린터 설정을 갱신하세요: - -```bash -sym convert -``` - -자세한 관리 방법은 문서에서 확인할 수 있습니다: [`docs/CONVENTION_MANAGEMENT.md`](docs/CONVENTION_MANAGEMENT.md) - -예시 정책 파일: - -```json -{ - "version": "1.0.0", - "rules": [ - { - "say": "Functions should be documented", - "category": "documentation" - }, - { - "say": "Lines should be less than 100 characters", - "category": "formatting", - "params": { "max": 100 } - } - ] -} -``` - ---- - ## 요구사항 - Node.js >= 16.0.0 diff --git a/npm/package.json b/npm/package.json index 9f28fb8..40a5e4e 100644 --- a/npm/package.json +++ b/npm/package.json @@ -1,6 +1,6 @@ { "name": "@dev-symphony/sym", - "version": "0.1.11", + "version": "0.1.12", "description": "Symphony - LLM-friendly convention linter for AI coding assistants", "keywords": [ "mcp",