heymark 1.1.1 → 1.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mossland Open Source
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.ko.md ADDED
@@ -0,0 +1,170 @@
1
+ # Heymark
2
+
3
+ AI 코딩 도구별 Skill 문서를 단일 위치에서 관리하고, 각 도구 형식으로 자동 변환하는 도구입니다.
4
+ 한 번 작성한 Markdown 소스를 여러 에이전트 도구에 맞춰 재사용할 수 있습니다.
5
+
6
+ 1. [Overview](#overview)
7
+ 2. [Features](#features)
8
+ 3. [Supported Agent Tools](#supported-agent-tools)
9
+ 4. [Tech Stack](#tech-stack)
10
+ 5. [Heymark Usage](#heymark-usage)
11
+ 6. [Heymark Development](#heymark-development)
12
+
13
+ ## Overview
14
+
15
+ 프로젝트마다 AI 도구별 Skill 파일을 따로 관리하면 문서가 분산되고 유지보수 비용이 커집니다.
16
+ Heymark는 단일 진실 공급원(Single Source of Truth) 원칙으로, 하나의 Markdown 소스를 여러 도구 형식으로 변환합니다.
17
+ 한 번 작성한 Skill을 Cursor, Claude Code, GitHub Copilot, OpenAI Codex, Antigravity에서 바로 사용할 수 있습니다.
18
+
19
+ ## Features
20
+
21
+ - 단일 소스 관리: Markdown 파일 하나로 여러 AI 도구의 Skill을 통합 관리
22
+ - 자동 형식 변환: 각 도구의 네이티브 형식으로 자동 변환 (YAML frontmatter, AGENTS.md 등)
23
+ - 선택적 변환: 필요한 도구만 선택해서 변환 가능
24
+ - NPM 패키지 배포: npx 기반으로 설치 없이 실행 가능
25
+ - 플러그인 구조: 변환 모듈을 추가해 지원 도구 확장 가능
26
+
27
+ ## Supported Agent Tools
28
+
29
+ | Tool | Output Format | Key Features |
30
+ | :------------- | :--------------------------------------- | :------------------------------------------------------- |
31
+ | Cursor | `.cursor/rules/*.mdc` | YAML frontmatter (`description`, `globs`, `alwaysApply`) |
32
+ | Claude Code | `.claude/skills/*/SKILL.md` | Skill 디렉터리 구조 + YAML frontmatter |
33
+ | GitHub Copilot | `.github/instructions/*.instructions.md` | `applyTo` 다중 패턴 매핑 |
34
+ | OpenAI Codex | `.agents/skills/*/SKILL.md` | Skill 디렉터리 구조 + YAML frontmatter |
35
+ | Antigravity | `.agent/skills/*/SKILL.md` | Skill 디렉터리 구조 + YAML frontmatter |
36
+
37
+ ## Tech Stack
38
+
39
+ - Runtime: Node.js
40
+ - Language: JavaScript
41
+ - Core: File system API, YAML frontmatter parsing
42
+
43
+ ## Heymark Usage
44
+
45
+ ### 1. Prepare the Skill Markdown Archive Repository
46
+
47
+ Skill 소스 디렉터리(외부 또는 개인 GitHub 저장소)에 Markdown 파일을 작성하고, YAML frontmatter로 메타데이터를 정의합니다.
48
+
49
+ ```markdown
50
+ ---
51
+ description: "AI assistant behavior guidelines"
52
+ globs: "**/*.ts,**/*.tsx"
53
+ alwaysApply: true
54
+ ---
55
+
56
+ # Skill Title
57
+
58
+ Skill content...
59
+ ```
60
+
61
+ 저장소 구조는 다음처럼 단순하게 구성하면 됩니다.
62
+
63
+ ```text
64
+ my-skills-repository/
65
+ ai-behavior.md
66
+ code-conventions.md
67
+ api-skills.md
68
+ ```
69
+
70
+ Skill 소스는 원격 GitHub 저장소(Public/Private)에서 읽습니다.
71
+
72
+ ### 2. Initial Setup
73
+
74
+ 최초 1회, 사용할 Skill 소스 저장소를 설정합니다.
75
+
76
+ ```bash
77
+ # Skill 소스 설정 (.heymark/config.json 생성)
78
+ npx heymark init <GitHub-저장소-URL>
79
+ ```
80
+
81
+ ```bash
82
+ # HTTPS (Private이면 Git credential/토큰 설정 필요)
83
+ npx heymark init https://github.com/org/my-rules.git
84
+
85
+ # SSH (Private 저장소 권장)
86
+ npx heymark init git@github.com:org/my-rules.git
87
+
88
+ # 저장소 안에서 .md가 하위 폴더에 있을 때
89
+ npx heymark init https://github.com/org/my-rules.git --dir rules --branch main
90
+ ```
91
+
92
+ ### 3. Run
93
+
94
+ 설치 없이 npx로 바로 실행할 수 있습니다.
95
+ Skill은 외부 GitHub 저장소에서 가져오며, 저장소 내 Markdown 파일을 각 AI 도구 형식으로 변환해 현재 프로젝트에 생성합니다.
96
+
97
+ ```bash
98
+ # .heymark/config.json에 설정된 외부 Skill 저장소에서 가져와 모든 도구 형식으로 변환
99
+ # (기존 생성 파일 삭제 후 새로 생성)
100
+ npx heymark
101
+
102
+ # 단일 실행에서만 다른 외부 저장소 사용 (.heymark/config.json 무시)
103
+ npx heymark --source https://github.com/org/other-rules.git
104
+
105
+ # 특정 도구만 변환
106
+ npx heymark -t cursor,claude
107
+
108
+ # 미리보기 (파일 생성 없이 변환 결과만 확인)
109
+ npx heymark --preview
110
+
111
+ # 이전에 생성된 도구별 파일 삭제
112
+ npx heymark --clean
113
+
114
+ # CLI help
115
+ npx heymark --help
116
+ ```
117
+
118
+ ## Heymark Development
119
+
120
+ ### 1. Local Execution
121
+
122
+ ```bash
123
+ # Skill 소스 설정 (최초 1회, GitHub 저장소 URL)
124
+ node scripts/sync.js init https://github.com/org/my-rules.git
125
+
126
+ # 모든 도구 형식으로 변환
127
+ node scripts/sync.js
128
+
129
+ # 단일 실행에서만 다른 저장소 사용
130
+ node scripts/sync.js --source https://github.com/org/other-rules.git
131
+
132
+ # 특정 도구만 변환
133
+ node scripts/sync.js -t cursor,claude
134
+
135
+ # 미리보기 (파일 생성 없이 확인)
136
+ node scripts/sync.js --preview
137
+
138
+ # 생성된 파일 삭제
139
+ node scripts/sync.js --clean
140
+ ```
141
+
142
+ ### 2. Release
143
+
144
+ ```bash
145
+ # NPM 로그인
146
+ npm login
147
+ # Username: your-npm-username
148
+ # Email: your-email@example.com
149
+
150
+ # 1. Skill 수정 후 테스트
151
+ node scripts/sync.js --preview
152
+
153
+ # 2. 버전 업데이트 (자동으로 Git 태그 생성)
154
+ npm version patch # 또는 minor, major
155
+
156
+ # 3. GitHub에 푸시
157
+ git push --follow-tags # 커밋과 태그를 함께 푸시
158
+
159
+ # 4. NPM에 배포
160
+ npm publish
161
+ ```
162
+
163
+ ### 3. Versioning
164
+
165
+ - `patch` (1.0.0 -> 1.0.1): 버그 수정, 오타 수정
166
+ - `minor` (1.0.0 -> 1.1.0): 새 Skill 추가, 기능 개선
167
+ - `major` (1.0.0 -> 2.0.0): 호환성 깨지는 변경
168
+ - `npm version` 명령어는 자동으로 Git 태그를 생성합니다.
169
+ - `git push --follow-tags`는 일반 커밋과 태그를 함께 푸시합니다. (권장)
170
+ - 또는 `git push && git push --tags`로 커밋 푸시 후 모든 태그를 별도로 푸시할 수 있습니다.
package/README.md CHANGED
@@ -1,189 +1,170 @@
1
1
  # Heymark
2
2
 
3
- AI 코딩 도구의 컨벤션을 중앙에서 관리하고, 도구 형식으로 자동 변환하는 시스템.
3
+ Heymark is a tool that manages Skill documentation for AI coding tools in a single location and automatically converts it into each tool format.
4
+ A Markdown source written once can be reused across multiple agent tools.
4
5
 
5
6
  1. [Overview](#overview)
6
7
  2. [Features](#features)
7
- 3. [Tech Stack](#tech-stack)
8
- 4. [Publishing](#publishing)
9
- 5. [Integration](#integration)
10
- 6. [Getting Started](#getting-started)
11
- 7. [Tool Support](#tool-support)
8
+ 3. [Supported Agent Tools](#supported-agent-tools)
9
+ 4. [Tech Stack](#tech-stack)
10
+ 5. [Heymark Usage](#heymark-usage)
11
+ 6. [Heymark Development](#heymark-development)
12
12
 
13
13
  ## Overview
14
14
 
15
- 프로젝트마다 AI 도구별 규칙 파일을 따로 작성하면 관리가 파편화된다.
16
- 시스템은 단일 진실 공급원(Single Source of Truth) 원칙에 따라, 곳에서 작성한 규칙을 여러 AI 도구 형식으로 자동 변환한다.
17
- 규칙을 번만 작성하면 Cursor, Claude Code, GitHub Copilot, OpenAI Codex, Antigravity 등에서 즉시 사용할 수 있다.
15
+ Managing Skill files separately for each AI tool leads to fragmented documentation and higher maintenance costs.
16
+ Heymark follows the Single Source of Truth principle and converts one Markdown source into multiple tool formats.
17
+ A Skill written once can be used immediately in Cursor, Claude Code, GitHub Copilot, OpenAI Codex, and Antigravity.
18
18
 
19
19
  ## Features
20
20
 
21
- - **단일 소스 관리**: 마크다운 파일 하나로 모든 AI 도구의 규칙 통합 관리
22
- - **자동 형식 변환**: 5종 AI 도구의 네이티브 형식으로 자동 변환 (YAML frontmatter, AGENTS.md )
23
- - **선택적 변환**: 특정 도구만 선택하여 변환 가능
24
- - **NPM 패키지 배포**: NPM registry를 통한 public 배포로 간편한 설치 및 버전 관리
25
- - **플러그인 구조**: 변환 모듈 추가만으로 도구 지원 확장
21
+ - Single source management: Manage Skills for multiple AI tools with one Markdown file
22
+ - Automatic format conversion: Convert into each tool's native format (YAML frontmatter, AGENTS.md, etc.)
23
+ - Selective conversion: Convert only the tools you need
24
+ - NPM package distribution: Run with `npx` without installation
25
+ - Plugin structure: Extend supported tools by adding conversion modules
26
26
 
27
- ## Tech Stack
27
+ ## Supported Agent Tools
28
28
 
29
- - **Runtime**: Node.js
30
- - **Language**: JavaScript
31
- - **Core**: File system API, YAML frontmatter parsing
29
+ | Tool | Output Format | Key Features |
30
+ | :------------- | :--------------------------------------- | :------------------------------------------------------- |
31
+ | Cursor | `.cursor/rules/*.mdc` | YAML frontmatter (`description`, `globs`, `alwaysApply`) |
32
+ | Claude Code | `.claude/skills/*/SKILL.md` | Skill directory structure + YAML frontmatter |
33
+ | GitHub Copilot | `.github/instructions/*.instructions.md` | Multi-pattern mapping via `applyTo` |
34
+ | OpenAI Codex | `.agents/skills/*/SKILL.md` | Skill directory structure + YAML frontmatter |
35
+ | Antigravity | `.agent/skills/*/SKILL.md` | Skill directory structure + YAML frontmatter |
32
36
 
33
- ## Publishing
37
+ ## Tech Stack
34
38
 
35
- 패키지 관리자용 가이드 (일반 사용자는 [Integration](#integration) 참고).
39
+ - Runtime: Node.js
40
+ - Language: JavaScript
41
+ - Core: File system API, YAML frontmatter parsing
36
42
 
37
- ### 초기 설정 (한 번만)
43
+ ## Heymark Usage
38
44
 
39
- ```bash
40
- # NPM 로그인
41
- npm login
42
- # Username: your-npm-username
43
- # Email: your-email@example.com
44
- ```
45
+ ### 1. Prepare the Skill Markdown Archive Repository
45
46
 
46
- ### 배포 프로세스
47
+ Create Markdown files in a Skill source directory (external or personal GitHub repository) and define metadata with YAML frontmatter.
47
48
 
48
- ```bash
49
- # 1. 규칙 수정 후 테스트
50
- node scripts/sync.js --preview
51
-
52
- # 2. 버전 업데이트 (자동으로 Git 태그 생성)
53
- npm version patch # 또는 minor, major
49
+ ```markdown
50
+ ---
51
+ description: "AI assistant behavior guidelines"
52
+ globs: "**/*.ts,**/*.tsx"
53
+ alwaysApply: true
54
+ ---
54
55
 
55
- # 3. GitHub에 푸시
56
- git push --follow-tags # 커밋과 태그를 함께 푸시
56
+ # Skill Title
57
57
 
58
- # 4. NPM에 배포
59
- npm publish
58
+ Skill content...
60
59
  ```
61
60
 
62
- **버전 관리:**
63
-
64
- - `patch` (1.0.0 → 1.0.1): 버그 수정, 오타 수정
65
- - `minor` (1.0.0 → 1.1.0): 새 규칙 추가, 기능 개선
66
- - `major` (1.0.0 → 2.0.0): 호환성 깨지는 변경
61
+ You can keep the repository structure simple, as shown below.
67
62
 
68
- **Git 태그 설명:**
63
+ ```text
64
+ my-skills-repository/
65
+ ai-behavior.md
66
+ code-conventions.md
67
+ api-skills.md
68
+ ```
69
69
 
70
- - `npm version` 명령어는 자동으로 Git 태그를 생성합니다
71
- - `git push --follow-tags`: 일반 커밋과 태그를 함께 푸시 (추천)
72
- - 또는 `git push && git push --tags`: 커밋 푸시 후 모든 태그 푸시
70
+ Skill sources are read from a remote GitHub repository (Public/Private).
73
71
 
74
- ## Integration
72
+ ### 2. Initial Setup
75
73
 
76
- Rule/Skill은 **원격 GitHub 저장소(Public/Private)** 에서 읽습니다.
77
- 최초 1회만 설정하면 됩니다.
74
+ For first-time use, configure the Skill source repository once.
78
75
 
79
76
  ```bash
80
- # 규칙 소스 설정 (.heymark/config.json 생성)
81
- npx heymark init <GitHub-저장소-URL>
77
+ # Configure Skill source (.heymark/config.json will be created)
78
+ npx heymark init <GitHub-Repository-URL>
82
79
  ```
83
80
 
84
81
  ```bash
85
- # HTTPS (Private이면 Git credential/토큰 설정 필요)
82
+ # HTTPS (for private repositories, Git credentials/token setup is required)
86
83
  npx heymark init https://github.com/org/my-rules.git
87
84
 
88
- # SSH (Private 저장소 권장)
85
+ # SSH (recommended for private repositories)
89
86
  npx heymark init git@github.com:org/my-rules.git
90
87
 
91
- # 저장소 안에서 .md 하위 폴더에 있을
88
+ # When .md files are in a subdirectory of the repository
92
89
  npx heymark init https://github.com/org/my-rules.git --dir rules --branch main
93
90
  ```
94
91
 
95
- ### Usage with npx
92
+ ### 3. Run
96
93
 
97
- 설치 없이 npx로 바로 실행할 있습니다.
98
- 규칙은 **원격 GitHub 저장소**에서 가져오며, 해당 저장소 안의 마크다운 파일을 AI 도구 형식으로 변환해 현재 프로젝트에 생성합니다.
94
+ You can run it directly with `npx` without installation.
95
+ Skills are fetched from an external GitHub repository, and Markdown files in that repository are converted into each AI tool format and generated in the current project.
99
96
 
100
97
  ```bash
101
- # .heymark/config.json에 설정된 외부 규칙 저장소에서 가져와 모든 도구 형식으로 변환 (기존 생성 파일 삭제 후 새로 생성)
98
+ # Fetch from the external Skill repository configured in .heymark/config.json and convert to all tool formats
99
+ # (delete previously generated files and recreate them)
102
100
  npx heymark
103
101
 
104
- # 이번에만 다른 외부 저장소 사용 (.heymark/config.json 무시)
102
+ # Use a different external repository for this run only (ignore .heymark/config.json)
105
103
  npx heymark --source https://github.com/org/other-rules.git
106
104
 
107
- # 특정 도구만 변환
105
+ # Convert only specific tools
108
106
  npx heymark -t cursor,claude
109
107
 
110
- # 미리보기 (파일 생성 없이 변환 결과만 확인)
108
+ # Preview (check conversion result without creating files)
111
109
  npx heymark --preview
112
110
 
113
- # 이전에 생성된 도구별 파일 삭제
111
+ # Delete tool-specific files generated previously
114
112
  npx heymark --clean
115
113
 
116
- # 도움말
114
+ # CLI help
117
115
  npx heymark --help
118
116
  ```
119
117
 
120
- ## Getting Started
121
-
122
- ### Writing Rules
118
+ ## Heymark Development
123
119
 
124
- 규칙 소스 디렉터리(외부 레포)에 마크다운 파일 작성. YAML frontmatter로 메타데이터 정의:
125
-
126
- ```markdown
127
- ---
128
- description: "AI assistant behavior guidelines"
129
- globs: "**/*.ts,**/*.tsx"
130
- alwaysApply: true
131
- ---
132
-
133
- # Rule Title
134
-
135
- Rule content...
136
- ```
137
-
138
- ### Local Testing
120
+ ### 1. Local Execution
139
121
 
140
122
  ```bash
141
- # 규칙 소스 설정 (최초 1회, GitHub 저장소 URL)
123
+ # Configure Skill source (first-time only, GitHub repository URL)
142
124
  node scripts/sync.js init https://github.com/org/my-rules.git
143
125
 
144
- # 모든 도구 형식으로 변환
126
+ # Convert to all tool formats
145
127
  node scripts/sync.js
146
128
 
147
- # 이번에만 다른 저장소 사용
129
+ # Use a different repository for this run only
148
130
  node scripts/sync.js --source https://github.com/org/other-rules.git
149
131
 
150
- # 특정 도구만 변환
132
+ # Convert only specific tools
151
133
  node scripts/sync.js -t cursor,claude
152
134
 
153
- # 미리보기 (파일 생성 없이 확인)
135
+ # Preview (check without creating files)
154
136
  node scripts/sync.js --preview
155
137
 
156
- # 생성된 파일 삭제
138
+ # Delete generated files
157
139
  node scripts/sync.js --clean
158
140
  ```
159
141
 
160
- ## Tool Support
142
+ ### 2. Release
161
143
 
162
- ### Adding New Tools
144
+ ```bash
145
+ # NPM login
146
+ npm login
147
+ # Username: your-npm-username
148
+ # Email: your-email@example.com
163
149
 
164
- 변환 모듈을 추가하면 자동 인식된다. 필수 export 인터페이스:
150
+ # 1. Test after updating Skills
151
+ node scripts/sync.js --preview
165
152
 
166
- ```javascript
167
- module.exports = {
168
- name: "Tool Name",
169
- output: "output/path/pattern",
170
- generate(rules, projectRoot) {
171
- /* ... */
172
- },
173
- clean(ruleNames, projectRoot) {
174
- /* ... */
175
- },
176
- };
177
- ```
153
+ # 2. Update version (Git tag is created automatically)
154
+ npm version patch # or minor, major
178
155
 
179
- ### Supported Tools
156
+ # 3. Push to GitHub
157
+ git push --follow-tags # push commits and tags together
180
158
 
181
- | Tool | Output Format | Key Features |
182
- | :------------- | :--------------------------------------- | :------------------------------------------------------- |
183
- | Cursor | `.cursor/rules/*.mdc` | YAML frontmatter (`description`, `globs`, `alwaysApply`) |
184
- | Claude Code | `.claude/skills/*/SKILL.md` | 스킬 디렉토리 구조 + YAML frontmatter |
185
- | GitHub Copilot | `.github/instructions/*.instructions.md` | `applyTo` 다중 패턴 매핑 |
186
- | OpenAI Codex | `.agents/skills/*/SKILL.md` | 스킬 디렉토리 구조 + YAML frontmatter |
187
- | Antigravity | `.agent/skills/*/SKILL.md` | 스킬 디렉토리 구조 + YAML frontmatter |
159
+ # 4. Publish to NPM
160
+ npm publish
161
+ ```
162
+
163
+ ### 3. Versioning
188
164
 
189
- Antigravity 스킬 파일 경로: `/.agent/skills/<skill-folder>/SKILL.md`
165
+ - `patch` (1.0.0 -> 1.0.1): Bug fixes, typo fixes
166
+ - `minor` (1.0.0 -> 1.1.0): New Skills, feature improvements
167
+ - `major` (1.0.0 -> 2.0.0): Breaking changes
168
+ - The `npm version` command automatically creates a Git tag.
169
+ - `git push --follow-tags` pushes normal commits and tags together. (Recommended)
170
+ - Alternatively, you can run `git push && git push --tags` to push commits first and then push all tags separately.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "heymark",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Centralized AI coding tool conventions with auto-conversion to multiple formats",
5
5
  "main": "scripts/sync.js",
6
6
  "bin": {
@@ -1,80 +1,80 @@
1
- "use strict";
2
-
3
- const fs = require("fs");
4
- const path = require("path");
5
- const { execSync } = require("child_process");
6
-
7
- const CACHE_DIR_NAME = path.join(".heymark", "cache");
8
-
9
- /**
10
- * 저장소 URL에서 캐시 폴더명으로 쓸 수 있는 문자열 추출
11
- * https://github.com/org/repo -> org-repo
12
- * git@github.com:org/repo.git -> org-repo
13
- */
14
- function sanitizeRepoName(url) {
15
- let s = url.trim();
16
- if (s.endsWith(".git")) s = s.slice(0, -4);
17
- const match =
18
- s.match(/github\.com[:/]([^/]+\/[^/]+?)(?:\/|$)/) || s.match(/([^/]+\/[^/]+?)(?:\/|$)/);
19
- if (match) {
20
- return match[1].replace(/\//g, "-");
21
- }
22
- return s.replace(/[^a-zA-Z0-9._-]/g, "-") || "repo";
23
- }
24
-
25
- /**
26
- * 원격 저장소를 clone 또는 pull하여, 규칙 .md가 있는 로컬 디렉터리 절대 경로를 반환합니다.
27
- * Private repo는 사용자의 git 인증(SSH 키, credential)으로 접근해야 합니다.
28
- * @param {string} projectRoot - 현재 프로젝트 루트
29
- * @param {{ rulesSource: string, branch?: string, rulesSourceDir?: string }} config
30
- * @returns {string} - .md 파일이 있는 디렉터리의 절대 경로
31
- */
32
- function getRulesDirFromRepo(projectRoot, config) {
33
- const url = config.rulesSource;
34
- const branch = config.branch || "main";
35
- const subDir = config.rulesSourceDir || "";
36
-
37
- const cacheBase = path.join(projectRoot, CACHE_DIR_NAME);
38
- const repoName = sanitizeRepoName(url);
39
- const clonePath = path.join(cacheBase, repoName);
40
-
41
- if (!fs.existsSync(clonePath)) {
42
- fs.mkdirSync(cacheBase, { recursive: true });
43
- try {
44
- execSync(`git clone --depth 1 --branch "${branch}" "${url}" "${clonePath}"`, {
45
- stdio: "inherit",
46
- cwd: projectRoot,
47
- });
48
- } catch (err) {
49
- console.error("[Error] Failed to clone rules repository.");
50
- console.error(" For private repos, ensure you have access (SSH key or HTTPS token).");
51
- console.error(" Example: heymark init https://github.com/org/repo.git");
52
- process.exit(1);
53
- }
54
- } else {
55
- try {
56
- execSync(
57
- "git fetch origin && git checkout --quiet . && git pull --quiet origin " + branch,
58
- {
59
- stdio: "pipe",
60
- cwd: clonePath,
61
- }
62
- );
63
- } catch (err) {
64
- // pull 실패 시(네트워크 등) 기존 클론 내용으로 진행
65
- }
66
- }
67
-
68
- const rulesDir = subDir ? path.join(clonePath, subDir) : clonePath;
69
- if (!fs.existsSync(rulesDir) || !fs.statSync(rulesDir).isDirectory()) {
70
- console.error(`[Error] Rules directory not found in repo: ${subDir || "(root)"}`);
71
- process.exit(1);
72
- }
73
- return rulesDir;
74
- }
75
-
76
- module.exports = {
77
- CACHE_DIR_NAME,
78
- getRulesDirFromRepo,
79
- sanitizeRepoName,
80
- };
1
+ "use strict";
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const { execSync } = require("child_process");
6
+
7
+ const CACHE_DIR_NAME = path.join(".heymark", "cache");
8
+
9
+ /**
10
+ * 저장소 URL에서 캐시 폴더명으로 쓸 수 있는 문자열 추출
11
+ * https://github.com/org/repo -> org-repo
12
+ * git@github.com:org/repo.git -> org-repo
13
+ */
14
+ function sanitizeRepoName(url) {
15
+ let s = url.trim();
16
+ if (s.endsWith(".git")) s = s.slice(0, -4);
17
+ const match =
18
+ s.match(/github\.com[:/]([^/]+\/[^/]+?)(?:\/|$)/) || s.match(/([^/]+\/[^/]+?)(?:\/|$)/);
19
+ if (match) {
20
+ return match[1].replace(/\//g, "-");
21
+ }
22
+ return s.replace(/[^a-zA-Z0-9._-]/g, "-") || "repo";
23
+ }
24
+
25
+ /**
26
+ * 원격 저장소를 clone 또는 pull하여, 규칙 .md가 있는 로컬 디렉터리 절대 경로를 반환합니다.
27
+ * Private repo는 사용자의 git 인증(SSH 키, credential)으로 접근해야 합니다.
28
+ * @param {string} projectRoot - 현재 프로젝트 루트
29
+ * @param {{ rulesSource: string, branch?: string, rulesSourceDir?: string }} config
30
+ * @returns {string} - .md 파일이 있는 디렉터리의 절대 경로
31
+ */
32
+ function getRulesDirFromRepo(projectRoot, config) {
33
+ const url = config.rulesSource;
34
+ const branch = config.branch || "main";
35
+ const subDir = config.rulesSourceDir || "";
36
+
37
+ const cacheBase = path.join(projectRoot, CACHE_DIR_NAME);
38
+ const repoName = sanitizeRepoName(url);
39
+ const clonePath = path.join(cacheBase, repoName);
40
+
41
+ if (!fs.existsSync(clonePath)) {
42
+ fs.mkdirSync(cacheBase, { recursive: true });
43
+ try {
44
+ execSync(`git clone --depth 1 --branch "${branch}" "${url}" "${clonePath}"`, {
45
+ stdio: "inherit",
46
+ cwd: projectRoot,
47
+ });
48
+ } catch (err) {
49
+ console.error("[Error] Failed to clone rules repository.");
50
+ console.error(" For private repos, ensure you have access (SSH key or HTTPS token).");
51
+ console.error(" Example: heymark init https://github.com/org/repo.git");
52
+ process.exit(1);
53
+ }
54
+ } else {
55
+ try {
56
+ execSync(
57
+ "git fetch origin && git checkout --quiet . && git pull --quiet origin " + branch,
58
+ {
59
+ stdio: "pipe",
60
+ cwd: clonePath,
61
+ }
62
+ );
63
+ } catch (err) {
64
+ // pull 실패 시(네트워크 등) 기존 클론 내용으로 진행
65
+ }
66
+ }
67
+
68
+ const rulesDir = subDir ? path.join(clonePath, subDir) : clonePath;
69
+ if (!fs.existsSync(rulesDir) || !fs.statSync(rulesDir).isDirectory()) {
70
+ console.error(`[Error] Rules directory not found in repo: ${subDir || "(root)"}`);
71
+ process.exit(1);
72
+ }
73
+ return rulesDir;
74
+ }
75
+
76
+ module.exports = {
77
+ CACHE_DIR_NAME,
78
+ getRulesDirFromRepo,
79
+ sanitizeRepoName,
80
+ };