heymark 1.0.1 → 1.1.0

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.
@@ -1,48 +1,41 @@
1
- "use strict";
2
-
3
- const fs = require("fs");
4
- const path = require("path");
5
-
6
- module.exports = {
7
- name: "GitHub Copilot",
8
- output: ".github/instructions/*.instructions.md",
9
-
10
- generate(rules, projectRoot) {
11
- const destDir = path.join(projectRoot, ".github", "instructions");
12
- fs.mkdirSync(destDir, { recursive: true });
13
-
14
- for (const rule of rules) {
15
- const globs = rule.globs
16
- ? rule.globs.split(",").map((g) => g.trim())
17
- : ["**"];
18
-
19
- const applyToLines = globs.map((g) => ` - "${g}"`).join("\n");
20
- const header = `applyTo:\n${applyToLines}\n---`;
21
-
22
- const content = header + "\n\n" + rule.body + "\n";
23
- fs.writeFileSync(
24
- path.join(destDir, `${rule.name}.instructions.md`),
25
- content
26
- );
27
- }
28
-
29
- return rules.length;
30
- },
31
-
32
- clean(ruleNames, projectRoot) {
33
- const cleaned = [];
34
- const destDir = path.join(projectRoot, ".github", "instructions");
35
-
36
- for (const name of ruleNames) {
37
- const filePath = path.join(destDir, `${name}.instructions.md`);
38
- if (fs.existsSync(filePath)) {
39
- fs.unlinkSync(filePath);
40
- cleaned.push(
41
- path.join(".github", "instructions", `${name}.instructions.md`)
42
- );
43
- }
44
- }
45
-
46
- return cleaned;
47
- },
48
- };
1
+ "use strict";
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ module.exports = {
7
+ name: "GitHub Copilot",
8
+ output: ".github/instructions/*.instructions.md",
9
+
10
+ generate(rules, projectRoot) {
11
+ const destDir = path.join(projectRoot, ".github", "instructions");
12
+ fs.mkdirSync(destDir, { recursive: true });
13
+
14
+ for (const rule of rules) {
15
+ const globs = rule.globs ? rule.globs.split(",").map((g) => g.trim()) : ["**"];
16
+
17
+ const applyToLines = globs.map((g) => ` - "${g}"`).join("\n");
18
+ const header = `applyTo:\n${applyToLines}\n---`;
19
+
20
+ const content = header + "\n\n" + rule.body + "\n";
21
+ fs.writeFileSync(path.join(destDir, `${rule.name}.instructions.md`), content);
22
+ }
23
+
24
+ return rules.length;
25
+ },
26
+
27
+ clean(ruleNames, projectRoot) {
28
+ const cleaned = [];
29
+ const destDir = path.join(projectRoot, ".github", "instructions");
30
+
31
+ for (const name of ruleNames) {
32
+ const filePath = path.join(destDir, `${name}.instructions.md`);
33
+ if (fs.existsSync(filePath)) {
34
+ fs.unlinkSync(filePath);
35
+ cleaned.push(path.join(".github", "instructions", `${name}.instructions.md`));
36
+ }
37
+ }
38
+
39
+ return cleaned;
40
+ },
41
+ };
@@ -1,41 +1,41 @@
1
- "use strict";
2
-
3
- const fs = require("fs");
4
- const path = require("path");
5
-
6
- module.exports = {
7
- name: "Cursor",
8
- output: ".cursor/rules/*.mdc",
9
-
10
- generate(rules, projectRoot) {
11
- const destDir = path.join(projectRoot, ".cursor", "rules");
12
- fs.mkdirSync(destDir, { recursive: true });
13
-
14
- for (const rule of rules) {
15
- const lines = ["---", `description: "${rule.description}"`];
16
- if (rule.globs) lines.push(`globs: "${rule.globs}"`);
17
- lines.push(`alwaysApply: ${rule.alwaysApply}`);
18
- lines.push("---");
19
-
20
- const content = lines.join("\n") + "\n\n" + rule.body + "\n";
21
- fs.writeFileSync(path.join(destDir, `${rule.name}.mdc`), content);
22
- }
23
-
24
- return rules.length;
25
- },
26
-
27
- clean(ruleNames, projectRoot) {
28
- const cleaned = [];
29
- const destDir = path.join(projectRoot, ".cursor", "rules");
30
-
31
- for (const name of ruleNames) {
32
- const filePath = path.join(destDir, `${name}.mdc`);
33
- if (fs.existsSync(filePath)) {
34
- fs.unlinkSync(filePath);
35
- cleaned.push(path.join(".cursor", "rules", `${name}.mdc`));
36
- }
37
- }
38
-
39
- return cleaned;
40
- },
41
- };
1
+ "use strict";
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ module.exports = {
7
+ name: "Cursor",
8
+ output: ".cursor/rules/*.mdc",
9
+
10
+ generate(rules, projectRoot) {
11
+ const destDir = path.join(projectRoot, ".cursor", "rules");
12
+ fs.mkdirSync(destDir, { recursive: true });
13
+
14
+ for (const rule of rules) {
15
+ const lines = ["---", `description: "${rule.description}"`];
16
+ if (rule.globs) lines.push(`globs: "${rule.globs}"`);
17
+ lines.push(`alwaysApply: ${rule.alwaysApply}`);
18
+ lines.push("---");
19
+
20
+ const content = lines.join("\n") + "\n\n" + rule.body + "\n";
21
+ fs.writeFileSync(path.join(destDir, `${rule.name}.mdc`), content);
22
+ }
23
+
24
+ return rules.length;
25
+ },
26
+
27
+ clean(ruleNames, projectRoot) {
28
+ const cleaned = [];
29
+ const destDir = path.join(projectRoot, ".cursor", "rules");
30
+
31
+ for (const name of ruleNames) {
32
+ const filePath = path.join(destDir, `${name}.mdc`);
33
+ if (fs.existsSync(filePath)) {
34
+ fs.unlinkSync(filePath);
35
+ cleaned.push(path.join(".cursor", "rules", `${name}.mdc`));
36
+ }
37
+ }
38
+
39
+ return cleaned;
40
+ },
41
+ };
@@ -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