perf-skill 0.2.1 → 0.3.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.
Files changed (50) hide show
  1. package/.claude-plugin/README.md +53 -0
  2. package/.claude-plugin/marketplace.json +58 -0
  3. package/.claude-plugin/plugin.json +40 -0
  4. package/CLAUDE.md +164 -0
  5. package/README.md +128 -109
  6. package/SKILL.md +86 -130
  7. package/dist/cli/init.d.ts +19 -3
  8. package/dist/cli/init.d.ts.map +1 -1
  9. package/dist/cli/init.js +107 -10
  10. package/dist/cli/init.js.map +1 -1
  11. package/dist/cli/main.js +72 -49
  12. package/dist/cli/main.js.map +1 -1
  13. package/dist/cli/platforms.d.ts +28 -0
  14. package/dist/cli/platforms.d.ts.map +1 -0
  15. package/dist/cli/platforms.js +238 -0
  16. package/dist/cli/platforms.js.map +1 -0
  17. package/dist/cli/template.d.ts +16 -0
  18. package/dist/cli/template.d.ts.map +1 -0
  19. package/dist/cli/template.js +157 -0
  20. package/dist/cli/template.js.map +1 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +71 -36
  23. package/dist/index.js.map +1 -1
  24. package/dist/llm/client.d.ts +6 -0
  25. package/dist/llm/client.d.ts.map +1 -1
  26. package/dist/llm/client.js +11 -2
  27. package/dist/llm/client.js.map +1 -1
  28. package/dist/llm/index.d.ts +1 -1
  29. package/dist/llm/index.d.ts.map +1 -1
  30. package/dist/llm/index.js +1 -1
  31. package/dist/llm/index.js.map +1 -1
  32. package/dist/skill/handler.d.ts +7 -0
  33. package/dist/skill/handler.d.ts.map +1 -1
  34. package/dist/skill/handler.js +24 -1
  35. package/dist/skill/handler.js.map +1 -1
  36. package/dist/skill/manifest.d.ts +4 -0
  37. package/dist/skill/manifest.d.ts.map +1 -1
  38. package/dist/skill/manifest.js +60 -39
  39. package/dist/skill/manifest.js.map +1 -1
  40. package/dist/types.d.ts +2 -0
  41. package/dist/types.d.ts.map +1 -1
  42. package/package.json +12 -9
  43. package/dist/server/http.d.ts +0 -27
  44. package/dist/server/http.d.ts.map +0 -1
  45. package/dist/server/http.js +0 -285
  46. package/dist/server/http.js.map +0 -1
  47. package/dist/server/utils.d.ts +0 -15
  48. package/dist/server/utils.d.ts.map +0 -1
  49. package/dist/server/utils.js +0 -71
  50. package/dist/server/utils.js.map +0 -1
package/SKILL.md CHANGED
@@ -1,85 +1,80 @@
1
1
  ---
2
2
  name: perf-skill
3
- description: Analyze pprof CPU and heap profiles with AI-powered recommendations, or profile a Node.js entry file and generate a full report. Use when the user has a .pb.gz profile file or wants to profile a Node.js script and get optimization suggestions.
4
- argument-hint: [profile.pb.gz|entry.js] [options]
3
+ description: Convert pprof CPU and heap profiles to structured Markdown and JSON evidence. Use when the user has a .pb.gz profile file and wants to understand performance bottlenecks or compare profiles.
4
+ argument-hint: [profile.pb.gz] [options]
5
5
  allowed-tools: Bash(node *), Bash(npx *), Read, Glob
6
6
  ---
7
7
 
8
- # perf-skill: Performance Profile Analysis Skill
8
+ # perf-skill: Performance Profile Evidence Extractor
9
9
 
10
- Analyze pprof profiles (.pb.gz) to identify performance bottlenecks and generate actionable optimization recommendations.
10
+ Convert pprof profiles (.pb.gz) to structured Markdown and JSON for performance analysis. This tool produces **deterministic, evidence-based output** that you (the agent) can use to generate optimization recommendations.
11
+
12
+ ## Design Philosophy
13
+
14
+ - **Deterministic by default**: No external API calls or LLM dependencies
15
+ - **Evidence-first**: Produces structured hotspots, call paths, and metrics
16
+ - **Agent-friendly**: You (Claude/Cursor/any coding agent) provide the analysis and recommendations based on the evidence
11
17
 
12
18
  ## Quick Start
13
19
 
14
20
  ### Analyze a Single Profile
15
21
 
16
22
  ```bash
17
- # Quick conversion to markdown (no LLM)
18
- npx perf-skill convert $ARGUMENTS
19
-
20
- # Full analysis with AI recommendations
21
- npx perf-skill analyze $ARGUMENTS --mode analyze
22
-
23
- # Output to file
23
+ # Convert profile to structured markdown and JSON (default, no LLM required)
24
24
  npx perf-skill analyze $ARGUMENTS -o analysis.md -j results.json
25
+
26
+ # Or use the convert command (explicitly no LLM)
27
+ npx perf-skill convert $ARGUMENTS -o report.md
25
28
  ```
26
29
 
27
- ### Profile a Node Entry and Analyze (One Command)
30
+ ### Compare Two Profiles (Diff)
28
31
 
29
32
  ```bash
30
- # Default CPU profiling (10s) + analysis
31
- npx perf-skill run slow.mjs
32
-
33
- # Customize duration and output
34
- npx perf-skill run slow.mjs --duration 10s -o analysis.md
35
-
36
- # CPU + Heap profiling (separate reports)
37
- npx perf-skill run slow.mjs --heap --output cpu.md --heap-output heap.md
33
+ # Compare base vs current profile
34
+ npx perf-skill diff base.pb.gz current.pb.gz -o diff.md -j diff.json
38
35
  ```
39
36
 
40
- ### Compare Two Profiles (Diff)
37
+ ### Profile a Node.js Application
41
38
 
42
39
  ```bash
43
- # Compare base vs current profile
44
- npx perf-skill diff base.pb.gz current.pb.gz
40
+ # Profile and convert in one step
41
+ npx perf-skill run slow.mjs --duration 10s -o cpu.md -j cpu.json
45
42
 
46
- # With specific format
47
- npx perf-skill diff base.pb.gz current.pb.gz --format diff-detailed
43
+ # With heap profiling
44
+ npx perf-skill run slow.mjs --heap --output cpu.md --heap-output heap.md
48
45
  ```
49
46
 
47
+ ## Workflow for Performance Analysis
48
+
49
+ 1. **Run perf-skill** to generate evidence (markdown + JSON)
50
+ 2. **Read the output** to understand hotspots and call paths
51
+ 3. **Generate recommendations** based on the evidence (this is YOUR job as the agent)
52
+ 4. **Implement changes** and re-run profiling to verify improvements
53
+
50
54
  ## When to Use This Skill
51
55
 
52
56
  Use `perf-skill` when:
53
57
  - User provides a `.pb.gz` pprof profile file
54
- - User provides a Node.js entry file (`.js/.mjs/.cjs`) and wants an end-to-end performance report
55
58
  - User asks "why is my app slow?" with a profile attached
56
59
  - User wants to compare performance before/after a change
57
60
  - User needs help interpreting profile data
58
61
  - User asks about CPU or memory hotspots
59
62
 
60
- ## Routing
61
-
62
- - If the argument ends with `.pb`, `.pb.gz`, or `.pprof`, run `analyze` or `diff` directly.
63
- - If the argument ends with `.js`, `.mjs`, or `.cjs`, run `perf-skill run <entry>` to generate a CPU profile and analyze it.
64
- - If the user asks for both CPU and heap (including misspellings like "heep" or terms like "memory"/"heap"), add `--heap` and save separate reports (`--output` + `--heap-output`).
65
-
66
63
  ## Available Commands
67
64
 
68
65
  ### `analyze` (default)
69
66
 
70
- Analyze a single profile with optional AI recommendations.
67
+ Convert a profile to structured Markdown. Default mode is `convert-only` (no external dependencies).
71
68
 
72
69
  ```bash
73
70
  perf-skill analyze profile.pb.gz [options]
74
71
  ```
75
72
 
76
- **Options:**
73
+ **Key Options:**
77
74
  - `-f, --format <format>`: Output format (`summary`, `detailed`, `adaptive`)
78
75
  - `-t, --type <type>`: Profile type (`cpu`, `heap`, `auto`)
79
76
  - `-o, --output <file>`: Save markdown to file
80
- - `-j, --json <file>`: Save JSON results to file
81
- - `-m, --mode <mode>`: `convert-only` (no LLM) or `analyze` (with LLM)
82
- - `-s, --source-dir <path>`: Include source code context
77
+ - `-j, --json <file>`: Save JSON results to file (for programmatic access)
83
78
  - `--max-hotspots <n>`: Limit hotspots shown (default: 10)
84
79
  - `--service <name>`: Service name for context
85
80
  - `--scenario <desc>`: Scenario description
@@ -92,15 +87,17 @@ Compare two profiles to find performance regressions.
92
87
  perf-skill diff base.pb.gz current.pb.gz [options]
93
88
  ```
94
89
 
95
- **Options:**
90
+ **Key Options:**
96
91
  - `-f, --format <format>`: `diff-summary`, `diff-detailed`, `diff-adaptive`
97
92
  - `-n, --normalize <mode>`: `none`, `scale-to-base-total`, `per-second`
93
+ - `-o, --output <file>`: Save markdown to file
94
+ - `-j, --json <file>`: Save JSON results to file
98
95
  - `--max-regressions <n>`: Limit regressions shown (default: 10)
99
96
  - `--max-improvements <n>`: Limit improvements shown (default: 5)
100
97
 
101
98
  ### `convert`
102
99
 
103
- Convert profile to markdown without AI analysis (faster).
100
+ Explicitly convert profile to markdown (same as analyze with default settings).
104
101
 
105
102
  ```bash
106
103
  perf-skill convert profile.pb.gz -o report.md
@@ -108,125 +105,84 @@ perf-skill convert profile.pb.gz -o report.md
108
105
 
109
106
  ### `run`
110
107
 
111
- Profile a Node entry file (CPU) and analyze the resulting profile.
108
+ Profile a Node.js entry file and convert the results.
112
109
 
113
110
  ```bash
114
- perf-skill run entry.js [entryArgs...]
111
+ perf-skill run slow.mjs --duration 10s -o cpu.md
115
112
  ```
116
113
 
117
- **Options:**
118
- - `-d, --duration <duration>`: Profiling duration (default: `10s`)
119
- - `--profile-out <file>`: Profile output file (default: `cpu.pb.gz`)
120
- - `--heap`: Also capture heap profile
121
- - `--heap-profile-out <file>`: Heap profile output file (default: `heap.pb.gz`)
122
- - `--heap-output <file>`: Heap markdown output file (default: derived from CPU output or `heap.md`)
123
- - `--heap-json <file>`: Heap JSON output file (optional)
124
- - `--heap-interval-bytes <n>`: Heap sampling interval (bytes, default: `524288`)
125
- - `--heap-stack-depth <n>`: Heap sampling stack depth (default: `64`)
126
- - All `analyze` options (`--format`, `--mode`, `--output`, etc.)
127
-
128
- When `--heap` is enabled and `--output` is omitted, the CLI writes `cpu.md` and `heap.md` instead of printing to stdout.
129
-
130
114
  ### `profile`
131
115
 
132
- Generate a CPU profile for a Node entry file without analysis.
116
+ Only generate profile files without conversion.
133
117
 
134
118
  ```bash
135
- perf-skill profile entry.js [entryArgs...]
136
- ```
137
-
138
- **Options:**
139
- - `-d, --duration <duration>`: Profiling duration (default: `10s`)
140
- - `-o, --output <file>`: Profile output file (default: `cpu.pb.gz`)
141
- - `--heap`: Also capture heap profile
142
- - `--heap-profile-out <file>`: Heap profile output file (default: `heap.pb.gz`)
143
- - `--heap-interval-bytes <n>`: Heap sampling interval (bytes, default: `524288`)
144
- - `--heap-stack-depth <n>`: Heap sampling stack depth (default: `64`)
145
-
146
- ## Programmatic Usage
147
-
148
- ```typescript
149
- import { analyze, diff } from 'perf-skill';
150
-
151
- // Analyze with AI
152
- const result = await analyze('cpu.pb.gz', {
153
- mode: 'analyze',
154
- context: { serviceName: 'api-server' }
155
- });
156
-
157
- console.log(result.markdown);
158
- console.log(result.recommendations);
159
-
160
- // Compare profiles
161
- const diffResult = await diff('base.pb.gz', 'current.pb.gz');
162
- console.log(diffResult.regressions);
119
+ perf-skill profile slow.mjs --duration 10s -o cpu.pb.gz
163
120
  ```
164
121
 
165
122
  ## Understanding the Output
166
123
 
167
- ### Hotspots
168
-
169
- Functions ranked by CPU time or memory allocation:
170
- - **Self%**: Time spent in this function only
171
- - **Cum%**: Time spent in this function + its callees
172
- - **Location**: Source file and line number
173
-
174
- ### Recommendations (AI mode)
124
+ ### Hotspots (JSON structure)
125
+
126
+ ```json
127
+ {
128
+ "hotspots": [
129
+ {
130
+ "rank": 1,
131
+ "function": "processRequest",
132
+ "selfPct": 23.4,
133
+ "cumPct": 67.8,
134
+ "location": "src/handler.ts:142",
135
+ "callPath": ["main", "handleHttp", "processRequest"]
136
+ }
137
+ ]
138
+ }
139
+ ```
175
140
 
176
- Each recommendation includes:
177
- - **Title**: What to do
178
- - **Rationale**: Why (with evidence from the profile)
179
- - **Steps**: How to implement
180
- - **Impact/Risk/Confidence**: Prioritization info
141
+ - **selfPct**: Time/memory spent in this function only (high = expensive work)
142
+ - **cumPct**: Time/memory including callees (high = hot path entry point)
143
+ - **callPath**: Call stack from root to this function
181
144
 
182
- ### Diff Analysis
145
+ ### Diff Analysis (JSON structure)
183
146
 
184
- When comparing profiles:
185
- - **Regressions**: Functions that got slower
186
- - **Improvements**: Functions that got faster
187
- - **Call Path Δ**: Which paths contributed to the change
147
+ ```json
148
+ {
149
+ "regressions": [...],
150
+ "improvements": [...],
151
+ "summary": ["Overall performance regressed by ~5%", "..."]
152
+ }
153
+ ```
188
154
 
189
- ## Collecting Profiles
155
+ ## Tips for Analysis
190
156
 
191
- ### Node.js with @datadog/pprof
157
+ 1. **High self%** = function is doing expensive work directly → optimize the function body
158
+ 2. **High cum%** = function is on a hot path → may need to call faster alternatives or cache
159
+ 3. **Native functions** (like `JSON.parse`) at top → consider streaming/binary alternatives
160
+ 4. **Compare profiles** to find the cause of regressions after code changes
161
+ 5. **Low sample count** → run profiler longer for statistical significance
192
162
 
193
- ```typescript
194
- import * as pprof from '@datadog/pprof';
195
- import { writeFileSync } from 'fs';
196
- import { gzipSync } from 'zlib';
163
+ ## Example Agent Workflow
197
164
 
198
- // CPU profiling (30 seconds)
199
- pprof.time.start({ durationMillis: 30000 });
200
- // ... run your workload ...
201
- const profile = await pprof.time.stop();
202
- writeFileSync('cpu.pb.gz', gzipSync(profile.encode()));
165
+ ```markdown
166
+ User: "My API is slow, here's the profile: cpu.pb.gz"
203
167
 
204
- // Heap profiling
205
- pprof.heap.start(512 * 1024, 64);
206
- // ... run your workload ...
207
- const heapProfile = await pprof.heap.profile();
208
- writeFileSync('heap.pb.gz', gzipSync(heapProfile.encode()));
168
+ Agent:
169
+ 1. Run: `npx perf-skill analyze cpu.pb.gz -o analysis.md -j results.json`
170
+ 2. Read the output files
171
+ 3. Analyze hotspots and generate recommendations:
172
+ - "JSON.parse at 23% - consider streaming JSON parser"
173
+ - "processRequest has high cumulative time - trace callees"
174
+ 4. Implement changes
175
+ 5. Re-profile and use `perf-skill diff` to verify improvement
209
176
  ```
210
177
 
211
- ## Tips
212
-
213
- 1. **Start with `--format summary`** for quick triage
214
- 2. **Use `--mode convert-only`** when you just need the markdown
215
- 3. **Compare profiles** to find the cause of regressions
216
- 4. **Provide context** (`--service`, `--scenario`) for better AI recommendations
217
- 5. **High self%** = function is doing expensive work directly
218
- 6. **High cum%** = function is on a hot path (may be calling slow functions)
219
-
220
178
  ## Requirements
221
179
 
222
- - Node.js >= 22.6.0
223
- - For AI analysis: Set `OPENAI_API_KEY` or configure LLM provider
224
- - CPU profiling uses bundled `@datadog/pprof` (native module); supported on common platforms
180
+ - Node.js >= 20
225
181
 
226
182
  ## Troubleshooting
227
183
 
228
184
  ### "No symbols found"
229
- The profile may be from a production build without debug info. The analysis still works but function names may be mangled.
185
+ The profile may be from a production build without debug info. Analysis still works but function names may be mangled.
230
186
 
231
187
  ### "Native code dominates"
232
188
  If native functions (like `JSON.parse`) are top hotspots, consider:
@@ -1,20 +1,32 @@
1
1
  /**
2
- * CLI init command helpers - install SKILL.md into a target directory
2
+ * CLI init command helpers - install SKILL.md into target directories for multiple AI platforms
3
3
  */
4
+ import { type AIPlatform } from "./platforms.js";
4
5
  export type CursorScope = "user" | "project";
5
6
  export interface InitOptions {
6
7
  target?: string;
7
8
  cursor?: boolean;
9
+ platform?: AIPlatform;
8
10
  scope?: CursorScope;
9
11
  force?: boolean;
10
12
  dryRun?: boolean;
13
+ offline?: boolean;
11
14
  }
12
15
  export interface InstallTarget {
13
- layout: "cursor" | "flat" | "file";
16
+ platform: string;
17
+ layout: "cursor" | "flat" | "file" | "platform";
14
18
  rootDir: string;
15
19
  destDir: string;
16
20
  destFile: string;
17
21
  }
22
+ export interface InitResult {
23
+ success: boolean;
24
+ targets: InstallTarget[];
25
+ errors: Array<{
26
+ platform: string;
27
+ error: string;
28
+ }>;
29
+ }
18
30
  export declare function parseSkillFrontmatterName(markdown: string): string | null;
19
31
  export declare function isReservedCursorDir(targetPath: string): boolean;
20
32
  export declare function resolveInstallTarget(options: {
@@ -25,5 +37,9 @@ export declare function resolveInstallTarget(options: {
25
37
  cwd: string;
26
38
  homeDir: string;
27
39
  }): InstallTarget;
28
- export declare function runInit(options: InitOptions): Promise<InstallTarget>;
40
+ /**
41
+ * Run init command - supports multiple platforms
42
+ */
43
+ export declare function runInit(options: InitOptions): Promise<InitResult>;
44
+ export { AI_PLATFORMS, type AIPlatform } from "./platforms.js";
29
45
  //# sourceMappingURL=init.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAaD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAczE;AAUD,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE/D;AASD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,aAAa,CAmDhB;AAuBD,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAgC1E"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EACL,KAAK,UAAU,EAKhB,MAAM,gBAAgB,CAAC;AAGxB,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAaD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAczE;AAUD,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE/D;AASD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,aAAa,CAuDhB;AA4ED;;GAEG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA4FvE;AAGD,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/cli/init.js CHANGED
@@ -1,10 +1,12 @@
1
1
  /**
2
- * CLI init command helpers - install SKILL.md into a target directory
2
+ * CLI init command helpers - install SKILL.md into target directories for multiple AI platforms
3
3
  */
4
4
  import { access, mkdir, readFile, writeFile } from "node:fs/promises";
5
5
  import { homedir } from "node:os";
6
6
  import { basename, dirname, extname, join, resolve, sep } from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
+ import { AI_PLATFORMS, PLATFORM_CONFIGS, getAllPlatforms, isPlatformValid, } from "./platforms.js";
9
+ import { renderSkillForPlatform, getDestinationPath } from "./template.js";
8
10
  function normalizeFrontmatterValue(value) {
9
11
  const trimmed = value.trim();
10
12
  if ((trimmed.startsWith("\"") && trimmed.endsWith("\"")) ||
@@ -54,6 +56,7 @@ export function resolveInstallTarget(options) {
54
56
  if (target && isMarkdownFile(target)) {
55
57
  const destDir = dirname(target);
56
58
  return {
59
+ platform: "cursor",
57
60
  layout: "file",
58
61
  rootDir: destDir,
59
62
  destDir,
@@ -66,6 +69,7 @@ export function resolveInstallTarget(options) {
66
69
  : target
67
70
  : join(root, options.name);
68
71
  return {
72
+ platform: "cursor",
69
73
  layout: "cursor",
70
74
  rootDir: root,
71
75
  destDir,
@@ -78,6 +82,7 @@ export function resolveInstallTarget(options) {
78
82
  if (isMarkdownFile(target)) {
79
83
  const destDir = dirname(target);
80
84
  return {
85
+ platform: "custom",
81
86
  layout: "file",
82
87
  rootDir: destDir,
83
88
  destDir,
@@ -85,6 +90,7 @@ export function resolveInstallTarget(options) {
85
90
  };
86
91
  }
87
92
  return {
93
+ platform: "custom",
88
94
  layout: "flat",
89
95
  rootDir: target,
90
96
  destDir: target,
@@ -110,30 +116,121 @@ async function loadSkillSource() {
110
116
  const name = parseSkillFrontmatterName(markdown) ?? "perf-skill";
111
117
  return { markdown, name, path: skillPath };
112
118
  }
119
+ /**
120
+ * Install skill for a single platform
121
+ */
122
+ async function installForPlatform(platform, options) {
123
+ const config = PLATFORM_CONFIGS[platform];
124
+ const { destDir, destFile } = getDestinationPath(config, options.cwd, options.scope, options.homeDir);
125
+ const target = {
126
+ platform,
127
+ layout: "platform",
128
+ rootDir: resolve(options.scope === "project" ? options.cwd : options.homeDir, config.folderStructure.root),
129
+ destDir,
130
+ destFile,
131
+ };
132
+ if (options.dryRun) {
133
+ return target;
134
+ }
135
+ // Check for reserved directories
136
+ if (isReservedCursorDir(destDir) || isReservedCursorDir(destFile)) {
137
+ throw new Error("Refusing to install into Cursor's reserved skills-cursor directory.");
138
+ }
139
+ // Create directory
140
+ await mkdir(destDir, { recursive: true });
141
+ // Check if file exists
142
+ if (!options.force && await fileExists(destFile)) {
143
+ throw new Error(`Skill already exists at ${destFile}. Use --force to overwrite.`);
144
+ }
145
+ // Render and write the skill file
146
+ const content = await renderSkillForPlatform(config);
147
+ await writeFile(destFile, content, "utf-8");
148
+ return target;
149
+ }
150
+ /**
151
+ * Run init command - supports multiple platforms
152
+ */
113
153
  export async function runInit(options) {
114
- const { markdown, name } = await loadSkillSource();
115
- if (options.scope && !options.cursor) {
116
- throw new Error("--scope is only supported with --cursor.");
154
+ const cwd = process.cwd();
155
+ const home = homedir();
156
+ const scope = options.scope ?? "project";
157
+ const force = options.force ?? false;
158
+ const dryRun = options.dryRun ?? false;
159
+ // Legacy --cursor flag support (maps to cursor platform)
160
+ if (options.cursor && !options.platform) {
161
+ options.platform = "cursor";
162
+ }
163
+ // If platform specified
164
+ if (options.platform) {
165
+ if (!isPlatformValid(options.platform)) {
166
+ return {
167
+ success: false,
168
+ targets: [],
169
+ errors: [{ platform: options.platform, error: `Invalid platform: ${options.platform}. Valid: ${AI_PLATFORMS.join(", ")}` }],
170
+ };
171
+ }
172
+ // Handle "all" platform
173
+ if (options.platform === "all") {
174
+ const platforms = getAllPlatforms();
175
+ const targets = [];
176
+ const errors = [];
177
+ for (const platform of platforms) {
178
+ try {
179
+ const target = await installForPlatform(platform, { scope, force, dryRun, cwd, homeDir: home });
180
+ targets.push(target);
181
+ }
182
+ catch (error) {
183
+ errors.push({
184
+ platform,
185
+ error: error instanceof Error ? error.message : String(error),
186
+ });
187
+ }
188
+ }
189
+ return {
190
+ success: errors.length === 0,
191
+ targets,
192
+ errors,
193
+ };
194
+ }
195
+ // Single platform
196
+ try {
197
+ const target = await installForPlatform(options.platform, { scope, force, dryRun, cwd, homeDir: home });
198
+ return { success: true, targets: [target], errors: [] };
199
+ }
200
+ catch (error) {
201
+ return {
202
+ success: false,
203
+ targets: [],
204
+ errors: [{ platform: options.platform, error: error instanceof Error ? error.message : String(error) }],
205
+ };
206
+ }
117
207
  }
208
+ // Legacy: no platform specified, use target path or cursor flag
209
+ if (options.scope && !options.cursor && !options.platform) {
210
+ throw new Error("--scope is only supported with --cursor or --platform.");
211
+ }
212
+ const { markdown, name } = await loadSkillSource();
118
213
  const target = resolveInstallTarget({
119
214
  target: options.target,
120
215
  cursor: options.cursor,
121
216
  scope: options.scope,
122
217
  name,
123
- cwd: process.cwd(),
124
- homeDir: homedir(),
218
+ cwd,
219
+ homeDir: home,
125
220
  });
126
221
  if (isReservedCursorDir(target.destDir) || isReservedCursorDir(target.destFile)) {
127
222
  throw new Error("Refusing to install into Cursor's reserved skills-cursor directory.");
128
223
  }
129
- if (options.dryRun) {
130
- return target;
224
+ if (dryRun) {
225
+ return { success: true, targets: [target], errors: [] };
131
226
  }
132
227
  await mkdir(target.destDir, { recursive: true });
133
- if (!options.force && await fileExists(target.destFile)) {
228
+ if (!force && await fileExists(target.destFile)) {
134
229
  throw new Error(`Skill already exists at ${target.destFile}. Use --force to overwrite.`);
135
230
  }
136
231
  await writeFile(target.destFile, markdown, "utf-8");
137
- return target;
232
+ return { success: true, targets: [target], errors: [] };
138
233
  }
234
+ // Re-export types and constants for convenience
235
+ export { AI_PLATFORMS } from "./platforms.js";
139
236
  //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}