heymark 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -86,7 +86,7 @@ npm install --save-dev heymark
86
86
  최초 1회만 설정하면 됩니다.
87
87
 
88
88
  ```bash
89
- # 규칙 소스 설정 (프로젝트 루트에 .heymark.json 생성)
89
+ # 규칙 소스 설정 (.heymark/config.json 생성)
90
90
  npx heymark init <GitHub-저장소-URL>
91
91
  ```
92
92
 
@@ -103,7 +103,13 @@ npx heymark init git@github.com:org/my-rules.git
103
103
  npx heymark init https://github.com/org/my-rules.git --dir rules --branch main
104
104
  ```
105
105
 
106
- 설정은 프로젝트 루트의 `.heymark.json`에 저장됩니다. 이후 `heymark` 실행 시 해당 저장소를 clone/pull 한 뒤 `.md` 파일들을 변환합니다.
106
+ 설정은 **`.heymark/config.json`**에, 캐시(클론된 저장소)는 `.heymark/cache/`에 생성됩니다.
107
+
108
+ ```gitignore
109
+ .heymark/
110
+ ```
111
+
112
+ 이후 `heymark` 실행 시 해당 저장소를 clone/pull 한 뒤 `.md` 파일들을 변환합니다.
107
113
 
108
114
  ### Usage with npx
109
115
 
@@ -111,10 +117,10 @@ npx heymark init https://github.com/org/my-rules.git --dir rules --branch main
111
117
  규칙은 **원격 GitHub 저장소**에서 가져오며, 해당 저장소 안의 마크다운 파일을 각 AI 도구 형식으로 변환해 현재 프로젝트에 생성합니다.
112
118
 
113
119
  ```bash
114
- # .heymark.json에 설정된 외부 규칙 저장소에서 가져와 모든 도구 형식으로 변환 (기존 생성 파일 삭제 후 새로 생성)
120
+ # .heymark/config.json에 설정된 외부 규칙 저장소에서 가져와 모든 도구 형식으로 변환 (기존 생성 파일 삭제 후 새로 생성)
115
121
  npx heymark
116
122
 
117
- # 이번에만 다른 외부 저장소 사용 (.heymark.json 무시)
123
+ # 이번에만 다른 외부 저장소 사용 (.heymark/config.json 무시)
118
124
  npx heymark --source https://github.com/org/other-rules.git
119
125
 
120
126
  # 특정 도구만 변환
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "heymark",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Centralized AI coding tool conventions with auto-conversion to multiple formats",
5
5
  "main": "scripts/sync.js",
6
6
  "bin": {
@@ -27,6 +27,11 @@
27
27
  "url": "https://github.com/i2na"
28
28
  },
29
29
  "contributors": [
30
+ {
31
+ "name": "i2na",
32
+ "email": "yena.e121@gmail.com",
33
+ "url": "https://github.com/i2na"
34
+ },
30
35
  {
31
36
  "name": "yezzero",
32
37
  "email": "yeyeonggim06@gmail.com",
@@ -3,7 +3,10 @@
3
3
  const fs = require("fs");
4
4
  const path = require("path");
5
5
 
6
- const CONFIG_FILENAME = ".heymark.json";
6
+ const CONFIG_DIR = ".heymark";
7
+ const CONFIG_FILENAME = "config.json";
8
+ /** 프로젝트 루트 기준 설정 파일 경로 (표시용) */
9
+ const CONFIG_RELATIVE = path.join(CONFIG_DIR, CONFIG_FILENAME);
7
10
 
8
11
  /**
9
12
  * rulesSource: GitHub 저장소 URL (https://github.com/org/repo 또는 git@github.com:org/repo.git)
@@ -13,12 +16,12 @@ const CONFIG_FILENAME = ".heymark.json";
13
16
  */
14
17
 
15
18
  /**
16
- * 프로젝트 루트에서 .heymark.json을 읽습니다.
19
+ * 프로젝트 루트에서 .heymark/config.json을 읽습니다.
17
20
  * @param {string} projectRoot - 프로젝트 루트 (보통 process.cwd())
18
21
  * @returns {RuleBookConfig | null}
19
22
  */
20
23
  function loadConfig(projectRoot) {
21
- const configPath = path.join(projectRoot, CONFIG_FILENAME);
24
+ const configPath = path.join(projectRoot, CONFIG_DIR, CONFIG_FILENAME);
22
25
  if (!fs.existsSync(configPath)) return null;
23
26
 
24
27
  try {
@@ -38,12 +41,16 @@ function loadConfig(projectRoot) {
38
41
  }
39
42
 
40
43
  /**
41
- * 초기 설정 파일을 생성합니다. (원격 GitHub 저장소 URL 사용)
44
+ * 초기 설정 파일을 생성합니다. (원격 GitHub 저장소 URL 사용) .heymark/config.json에 저장합니다.
42
45
  * @param {string} projectRoot
43
46
  * @param {RuleBookConfig} config - { rulesSource: repoUrl, branch?, rulesSourceDir? }
44
47
  */
45
48
  function writeConfig(projectRoot, config) {
46
- const configPath = path.join(projectRoot, CONFIG_FILENAME);
49
+ const configDir = path.join(projectRoot, CONFIG_DIR);
50
+ if (!fs.existsSync(configDir)) {
51
+ fs.mkdirSync(configDir, { recursive: true });
52
+ }
53
+ const configPath = path.join(configDir, CONFIG_FILENAME);
47
54
  const toWrite = {
48
55
  rulesSource: config.rulesSource,
49
56
  branch: config.branch || "main",
@@ -56,7 +63,9 @@ function writeConfig(projectRoot, config) {
56
63
  }
57
64
 
58
65
  module.exports = {
66
+ CONFIG_DIR,
59
67
  CONFIG_FILENAME,
68
+ CONFIG_RELATIVE,
60
69
  loadConfig,
61
70
  writeConfig,
62
71
  };
@@ -4,7 +4,7 @@ const fs = require("fs");
4
4
  const path = require("path");
5
5
  const { execSync } = require("child_process");
6
6
 
7
- const CACHE_DIR_NAME = ".heymark-cache";
7
+ const CACHE_DIR_NAME = path.join(".heymark", "cache");
8
8
 
9
9
  /**
10
10
  * 저장소 URL에서 캐시 폴더명으로 쓸 수 있는 문자열 추출
package/scripts/sync.js CHANGED
@@ -4,7 +4,7 @@
4
4
  const fs = require("fs");
5
5
  const path = require("path");
6
6
  const { loadRules } = require("./lib/parser");
7
- const { CONFIG_FILENAME, loadConfig, writeConfig } = require("./lib/config");
7
+ const { CONFIG_RELATIVE, loadConfig, writeConfig } = require("./lib/config");
8
8
  const { getRulesDirFromRepo } = require("./lib/repo");
9
9
 
10
10
  const SCRIPT_DIR = __dirname;
@@ -88,11 +88,11 @@ tool-specific configuration files for various AI coding assistants.
88
88
  Same rules everywhere: A computer, B computer, same remote repo.
89
89
 
90
90
  Usage:
91
- heymark init <repo-url> Set rules source (creates ${CONFIG_FILENAME})
91
+ heymark init <repo-url> Set rules source (creates ${CONFIG_RELATIVE})
92
92
  heymark [options] Sync from configured or --source repo
93
93
 
94
94
  Options:
95
- --source, -s <url> GitHub repo URL for this run (overrides ${CONFIG_FILENAME})
95
+ --source, -s <url> GitHub repo URL for this run (overrides ${CONFIG_RELATIVE})
96
96
  --tools, -t <list> Comma-separated tool names (default: all)
97
97
  --clean, -c Remove all generated files
98
98
  --preview, -p Preview what will be generated without writing
@@ -100,7 +100,7 @@ Options:
100
100
 
101
101
  Rules source (in order):
102
102
  1. --source <repo-url>
103
- 2. ${CONFIG_FILENAME} (set via 'heymark init <repo-url>')
103
+ 2. ${CONFIG_RELATIVE} (set via 'heymark init <repo-url>')
104
104
  Private repos: use SSH (git@github.com:org/repo.git) or HTTPS with token.
105
105
 
106
106
  Available tools:
@@ -1,87 +0,0 @@
1
- ---
2
- description: "AI assistant behavior: surgical code changes, communication style, and commenting philosophy"
3
- alwaysApply: true
4
- ---
5
-
6
- # AI Behavior
7
-
8
- ## Code Modification
9
-
10
- - Modify **only** lines directly causing the problem; change the **minimum** required
11
- - **Never** refactor, reorganize, or reformat unrelated code
12
- - Maintain original file structure, patterns, and coding style
13
- - Implement only when **100% certain**; ask clarifying questions if insufficient context
14
- - Present multiple options with trade-offs when several valid solutions exist
15
- - Provide **full, exact code** for all changed lines
16
- - Use `// ... existing code` only for truly unchanged sections
17
- - Never use placeholders (`// TODO: implement`) or omit error handling
18
- - Favor clarity over cleverness; use early returns for error conditions
19
-
20
- ## Commenting
21
-
22
- Code must be self-documenting. Add comments **only** with approved tags:
23
-
24
- | Tag | Usage |
25
- | :-------------- | :------------------------------------------- |
26
- | `@note` | Critical context or non-obvious behavior |
27
- | `@todo(owner):` | Future work with assigned owner (mandatory) |
28
- | `@wip` | Temporary code, remove before merge |
29
- | `@deprecated` | Marked for removal, must specify alternative |
30
-
31
- - English only, lowercase after tags, one line max
32
- - **Prohibited:** decorative separators (`// ===`, `// ---`), obvious statements, chatty explanations, uncommented dead code
33
-
34
- ## Communication
35
-
36
- | Context | Language |
37
- | :---------------------- | :------- |
38
- | User-facing | Korean |
39
- | Code, comments, commits | English |
40
-
41
- - **Tone:** Direct, concise. No filler, no hedging ("maybe", "possibly"), no pleasantries
42
- - **Structure:** Root cause (1-2 sentences) → Solution (code) → Reasoning (only if non-obvious)
43
-
44
- **Bad:** "안녕하세요! 도와드리겠습니다. 이 문제는 여러 원인이 있을 수 있는데..."
45
- **Good:** "`userId`가 `number | undefined`인데 `string`을 기대합니다. 타입 가드를 추가합니다."
46
-
47
- ## Anti-Defensive Coding
48
-
49
- Write for the **expected successful flow**. Trust TypeScript compiler-enforced types. Let errors propagate naturally unless catching is required.
50
-
51
- **Avoid:**
52
-
53
- - Redundant null checks: `if (data && data.user && data.user.name)`
54
- - Unnecessary fallbacks: `const name = user?.name || "Unknown"`
55
- - Blanket try-catch around every function
56
- - Runtime type checks for TS-enforced types: `if (typeof id === 'number')`
57
-
58
- **Exceptions** — defensive code IS appropriate at:
59
-
60
- - Public API boundaries (user input, external API responses)
61
- - Security or financial operations
62
- - Known unreliable sources (legacy systems, third-party APIs)
63
-
64
- ```typescript
65
- // ❌ Over-defensive
66
- function getUserEmail(userId: number): string {
67
- try {
68
- if (!userId || typeof userId !== "number") return "";
69
- const user = database.getUser(userId);
70
- if (!user || !user.email || typeof user.email !== "string") return "";
71
- return user.email || "no-email@example.com";
72
- } catch {
73
- return "";
74
- }
75
- }
76
-
77
- // ✅ Happy path
78
- function getUserEmail(userId: number): string {
79
- return database.getUser(userId).email;
80
- }
81
- ```
82
-
83
- ## Decision Priority
84
-
85
- When rules conflict: **Security** > **User requirements** > **This guide** > **Language conventions** > **Preference**
86
-
87
- When uncertain: ask clarifying questions, state assumptions explicitly, admit knowledge gaps.
@@ -1,98 +0,0 @@
1
- ---
2
- description: "TypeScript and React naming conventions, file structure, and type patterns"
3
- globs: "**/*.ts,**/*.tsx,**/*.js,**/*.jsx"
4
- alwaysApply: true
5
- ---
6
-
7
- # TypeScript & React Conventions
8
-
9
- ## File Naming
10
-
11
- | Type | Convention | Example |
12
- | :---------------- | :----------------------- | :--------------------- |
13
- | Utility / Service | `kebab-case.ts` | `user-service.ts` |
14
- | React Component | `PascalCase.tsx` | `DashboardLayout.tsx` |
15
- | CSS Module | `PascalCase.module.scss` | `Button.module.scss` |
16
- | Test | `*.test.ts(x)` | `user-service.test.ts` |
17
- | Type Definition | `*.types.ts` | `api.types.ts` |
18
- | Constants | `*.constants.ts` | `routes.constants.ts` |
19
-
20
- ## Code Naming
21
-
22
- | Element | Convention | Example |
23
- | :------------- | :--------------------- | :----------------------- |
24
- | Variable | `camelCase` | `userName`, `isActive` |
25
- | Function | `camelCase` | `getUserData()` |
26
- | Constant | `UPPER_SNAKE_CASE` | `API_BASE_URL` |
27
- | Private member | `_camelCase` | `_internalCache` |
28
- | Boolean | `is/has/should` prefix | `isLoading`, `hasAccess` |
29
- | Component | `PascalCase` | `UserCard` |
30
- | Hook | `use` prefix | `useAuth()` |
31
- | HOC | `with` prefix | `withAuth()` |
32
- | Event handler | `handle` prefix | `handleSubmit()` |
33
- | Render helper | `render` prefix | `renderHeader()` |
34
-
35
- ## Types & Interfaces
36
-
37
- | Type | Convention | Example |
38
- | :--------- | :---------------------- | :-------------------------- |
39
- | Interface | `I` + PascalCase | `IUser`, `IApiResponse` |
40
- | Type alias | `T` + PascalCase | `TConfig`, `TRequestBody` |
41
- | Enum | `E` + PascalCase | `EUserRole`, `EStatus` |
42
- | Props | ComponentName + `Props` | `ButtonProps`, `ModalProps` |
43
- | Generic | Single uppercase | `T`, `K`, `V` |
44
-
45
- Usage: **Interface** → object shapes, **Type alias** → unions/intersections, **Enum** → fixed value sets (string values in `UPPER_CASE`)
46
-
47
- ```typescript
48
- interface IUser {
49
- id: number;
50
- email: string;
51
- role: EUserRole;
52
- }
53
-
54
- type TApiResponse<T> = TSuccessResponse<T> | TErrorResponse;
55
-
56
- enum EUserRole {
57
- Admin = "ADMIN",
58
- User = "USER",
59
- Guest = "GUEST",
60
- }
61
- ```
62
-
63
- - Avoid `any`; use `unknown` or generics
64
- - Explicit return types for public API functions
65
- - Use type guards for runtime narrowing
66
-
67
- ## File Structure
68
-
69
- Import order (separate each group with a blank line):
70
-
71
- 1. React / framework (`react`, `next`)
72
- 2. External libraries (`axios`, `lodash`)
73
- 3. Internal aliases (`@/components`, `@/hooks`)
74
- 4. Relative imports (`./`, `../`)
75
- 5. Type-only imports (`import type`)
76
- 6. Styles (`.module.scss`)
77
-
78
- Within-file order: **Imports → Types → Constants → Private helpers → Public exports**
79
-
80
- ## Component Pattern
81
-
82
- ```typescript
83
- // Named function export (preferred over React.FC)
84
- export function UserCard({ userId }: UserCardProps) {
85
- // 1. hooks
86
- // 2. state (descriptive names: isLoading, userData — not loading, data)
87
- // 3. effects (all deps in dependency array)
88
- // 4. handlers (handleXxx)
89
- // 5. render helpers (renderXxx)
90
- // 6. return JSX
91
- }
92
- ```
93
-
94
- ## Formatting
95
-
96
- - Max **100 characters** per line
97
- - Prefer destructuring: `const { email, role } = user`
98
- - Optional chaining `?.` max 2 levels deep
@@ -1,69 +0,0 @@
1
- ---
2
- description: "README document writing guide: structure, style, and format conventions"
3
- globs: "README.md"
4
- alwaysApply: false
5
- ---
6
-
7
- # README Writing Guide
8
-
9
- ## Structure
10
-
11
- README는 다음 순서를 따른다:
12
-
13
- 1. **Title** — 프로젝트를 대표하는 심플한 영어 이름
14
- 2. **Intro** — 1-2줄 한국어 프로젝트 소개
15
- 3. **Table of Contents** — 마크다운 테이블 형태
16
- 4. **Overview** — 프로젝트 배경과 핵심 가치 (3-5문장)
17
- 5. **Features** — 핵심 기능만 (추상적 설명 금지)
18
- 6. **Tech Stack** — 핵심 기술만 (사소한 라이브러리 제외)
19
- 7. **Getting Started** — 설치 및 실행 (최소 단계)
20
-
21
- ## Format
22
-
23
- ### Language
24
-
25
- - 제목, 소제목: **영어**
26
- - 본문: **한국어**
27
- - 코드, 명령어: 영어
28
-
29
- ### Style
30
-
31
- - 이모지 금지
32
- - 장황한 설명 금지; 간결하고 공식적인 어조
33
- - 바뀌기 쉬운 파일명, 변수명, 경로는 언급하지 않음
34
- - HTML 태그 최소화
35
-
36
- ### Table of Contents
37
-
38
- ```markdown
39
- 1. [Overview](#overview)
40
- 2. [Features](#features)
41
- 3. [Tech Stack](#tech-stack)
42
- 4. [Getting Started](#getting-started)
43
- ```
44
-
45
- ### Features
46
-
47
- - 실제로 **구분 가능한 대표 기능**만 나열
48
- - 각 기능은 한 줄 설명
49
- - 추상적 표현 금지: ~~"강력한 성능"~~, ~~"혁신적인 아키텍처"~~
50
-
51
- ### Tech Stack
52
-
53
- - 프레임워크, 언어, 핵심 인프라만
54
- - 유틸 라이브러리, 개발 도구 제외
55
- - 테이블 또는 간단한 리스트
56
-
57
- ### Getting Started
58
-
59
- - Prerequisites (필요 시만)
60
- - 설치 명령어 (코드 블록)
61
- - 실행 명령어 (코드 블록)
62
-
63
- ## Anti-Patterns
64
-
65
- - 7개 이상 섹션의 장황한 README
66
- - 뱃지, 이모지, 장식적 요소
67
- - 추상적 기능 소개
68
- - 자주 변하는 파일명/변수명 언급
69
- - 불필요한 Contributing, License, Changelog 섹션
@@ -1,79 +0,0 @@
1
- ---
2
- description: "Technical research workflow for generating in-depth reports with web search and analysis"
3
- globs: ""
4
- alwaysApply: false
5
- ---
6
-
7
- # Research Workflow
8
-
9
- Activate when user explicitly requests research ("research X", "investigate Y", "compare Z"). Not for simple coding questions, quick fact-checks, debugging, or routine implementation.
10
-
11
- ## Principles
12
-
13
- - Base conclusions on **official docs, technical blogs, papers, whitepapers**
14
- - **Never** speculate or present assumptions as facts
15
- - Cite all sources with direct URLs
16
- - No emojis in research documents
17
- - Explain **how** things work, not just features; identify limitations and edge cases
18
- - Use clear technical language; avoid marketing language ("blazingly fast", "revolutionary")
19
-
20
- ## Process
21
-
22
- ### Phase 1: Multi-Angle Search (5+ queries)
23
-
24
- 1. Official documentation (include version numbers and year)
25
- 2. Technical comparisons and benchmarks
26
- 3. Implementation guides and best practices
27
- 4. Known issues and limitations
28
- 5. Alternative solutions
29
-
30
- Start broad, narrow based on findings.
31
-
32
- ### Phase 2: Deep Extraction
33
-
34
- Fetch full content of 3-5 critical URLs:
35
- - API specs, technical references
36
- - Architecture and system design docs
37
- - Benchmark data, performance analyses
38
- - Security advisories
39
-
40
- ### Phase 3: Synthesis
41
-
42
- - Identify patterns and contradictions across sources
43
- - Evaluate trade-offs between approaches
44
- - Assess feasibility for the specific use case
45
- - Form architectural recommendations
46
-
47
- ## Report Format
48
-
49
- ```
50
- # [Topic]
51
-
52
- **Date:** YYYY-MM-DD
53
- **Scope:** [Brief description]
54
- **Key Finding:** [One sentence]
55
-
56
- ## Executive Summary
57
- 3-5 sentences: what, why, key findings, constraints.
58
-
59
- ## [Thematic Sections]
60
- Organize by theme, not by source:
61
- - Technical Feasibility
62
- - Architecture Considerations
63
- - Performance Characteristics
64
- - Alternative Approaches
65
-
66
- ## Conclusion
67
- Recommendations, next steps, risks/unknowns.
68
-
69
- ## Sources
70
- 1. [Title](URL) - Description
71
- ```
72
-
73
- ## Output
74
-
75
- - **Filename:** descriptive English, kebab-case (`redis-vs-memcached-comparison.md`)
76
- - **Location:** `/research/`, `/docs/research/`, or project root
77
- - **Format:** Markdown with code blocks, mermaid diagrams, comparison tables
78
- - **Language:** English, present tense, active voice, define acronyms on first use
79
- - Include minimal runnable code examples where relevant
@@ -1,71 +0,0 @@
1
- ---
2
- description: "Guide for creating rule documents: structure, token efficiency, and writing principles"
3
- globs: "rules/*.md"
4
- alwaysApply: false
5
- ---
6
-
7
- # Rule Writing Guide
8
-
9
- Rules in `rules/` are consumed by AI coding assistants. Every token loads per request — **brevity is critical**.
10
-
11
- ## Frontmatter
12
-
13
- ```yaml
14
- ---
15
- description: "One-line summary for AI relevance judgment"
16
- globs: "**/*.ts,**/*.tsx" # File patterns for auto-attachment (empty if N/A)
17
- alwaysApply: true # true = always loaded, false = conditional
18
- ---
19
- ```
20
-
21
- - `description`: AI가 자동 로딩 여부를 판단할 때 참조하는 요약
22
- - `globs`: 해당 파일 패턴 작업 시 자동 적용
23
- - `alwaysApply`: 항상 로드 여부
24
-
25
- ## Structure
26
-
27
- 1. **Title** (`# Rule Name`) — short, descriptive
28
- 2. **Scope** (optional) — one sentence on when this rule activates
29
- 3. **Sections** — organized by theme
30
- 4. No redundant sections (stated rules should not be restated as checklists)
31
-
32
- ## Writing Principles
33
-
34
- ### Token Efficiency
35
-
36
- - Every line must be an **actionable instruction**
37
- - Remove meta-sentences: ~~"This rule defines how the AI should..."~~
38
- - Remove knowledge AI already possesses
39
- - **Tables** for mappings (most token-efficient format)
40
- - **Bullet lists** for constraints, not paragraphs
41
- - One code example per concept max; omit if a table already conveys it
42
-
43
- ### Clarity
44
-
45
- - **Imperative voice:** "Use camelCase" not "You should use camelCase"
46
- - **Bold** key terms and constraints
47
- - Concrete examples over abstract descriptions
48
- - No hedging: use "always", "never", "must" — not "try to", "consider"
49
-
50
- ### Completeness
51
-
52
- - Cover all conventions without redundancy
53
- - Include ✅/❌ examples only when the rule is counterintuitive
54
- - Add inline context only when the rule needs explanation
55
-
56
- ## Anti-Patterns
57
-
58
- - Chatty introductions: ~~"Welcome! This document will help you..."~~
59
- - Redundant checklists restating earlier rules
60
- - Over-documenting _why_ a rule exists (unless non-obvious)
61
- - Emojis, excessive separators, decorative formatting
62
- - Stale references to specific file names or paths that change frequently
63
-
64
- ## Quality Test
65
-
66
- A well-written rule document:
67
-
68
- - Can be followed by any AI without ambiguity
69
- - Contains **zero** filler sentences
70
- - Uses ≤50% tokens of a verbose equivalent
71
- - Handles edge cases inline, not in separate sections