crewkit 1.1.3 → 1.1.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crewkit",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "Context engineering framework for AI-assisted development. One command to set up agents, skills, hooks, rules, and memory for your project.",
5
5
  "type": "module",
6
6
  "bin": {
package/skill/SKILL.md CHANGED
@@ -51,16 +51,36 @@ If `.claude/` or `CLAUDE.md` or `.ai/memory/` exists:
51
51
  3. Report: "Existing setup backed up to `.crewkit-backup/`"
52
52
 
53
53
  ### Create directory structure
54
+ Create directories based on the **selected IDE targets** from Phase 1:
55
+
56
+ **Always:**
57
+ ```
58
+ .ai/
59
+ memory/
60
+ plans/
61
+ .crewkit/
62
+ ```
63
+
64
+ **If Claude Code is a selected target:**
54
65
  ```
55
66
  .claude/
56
67
  agents/
57
68
  hooks/
58
69
  rules/
59
70
  skills/
60
- .ai/
61
- memory/
62
- plans/
63
- .crewkit/
71
+ ```
72
+
73
+ **If GitHub Copilot is a selected target:**
74
+ ```
75
+ .github/
76
+ agents/
77
+ instructions/
78
+ ```
79
+
80
+ **If Cursor is a selected target:**
81
+ ```
82
+ .cursor/
83
+ rules/
64
84
  ```
65
85
 
66
86
  ### Version tracking
@@ -144,22 +164,38 @@ Read `package.json` scripts, CI configs, or Makefiles to find the actual command
144
164
 
145
165
  ### IDE Target Detection
146
166
 
147
- Detect which IDEs are in use or configured in this project:
167
+ Detect which IDEs are available. Check **two sources**: project-level signals AND global install markers.
148
168
 
149
- | IDE | Detection signals |
150
- |-----|------------------|
151
- | Claude Code | **Always** this skill runs inside Claude Code |
152
- | GitHub Copilot | `.github/` directory exists OR `.github/copilot-instructions.md` found |
153
- | Cursor | `.cursor/` directory exists OR `.cursorrules` file found |
169
+ | IDE | Project signals | Global install marker |
170
+ |-----|----------------|----------------------|
171
+ | Claude Code | `.claude/` directory exists | `~/.claude/skills/crewkit-setup/` exists |
172
+ | GitHub Copilot | `.github/` directory exists OR `.github/copilot-instructions.md` found | `~/.copilot/agents/crewkit-setup.md` exists |
173
+ | Cursor | `.cursor/` directory exists OR `.cursorrules` file found | `~/.cursor/crewkit-setup.md` exists |
154
174
 
155
- Save all detected IDE targets to the scan data. Example:
175
+ An IDE is **available** if ANY of its signals match (project OR global).
176
+
177
+ **IDE target selection (exception to zero-questions rule):**
178
+
179
+ If more than one IDE is available, present the user with a choice:
180
+
181
+ > "Multiple IDEs detected. Generate context for which?"
182
+ > - **[1] Claude Code**
183
+ > - **[2] GitHub Copilot**
184
+ > - **[3] Cursor**
185
+ > - **[4] All detected**
186
+ >
187
+ > (Only show IDEs that were detected. Default: all detected.)
188
+
189
+ If only one IDE is available, use it without asking.
190
+
191
+ Save the **selected** IDE targets to scan data. Example:
156
192
  ```
157
- IDE targets: Claude Code (always), GitHub Copilot (detected: .github/ exists), Cursor (not detected)
193
+ IDE targets selected: GitHub Copilot
158
194
  ```
159
195
 
160
196
  **Store results as: `ReconProfile`** — write to `.crewkit/scan-phase1-recon.md` for persistence.
161
197
 
162
- Report: "Phase 1 complete. Detected: [stacks], [CI], [DBs], [build/test commands]."
198
+ Report: "Phase 1 complete. Detected: [stacks], [CI], [DBs], [build/test commands]. IDE target: [selected IDEs]."
163
199
 
164
200
  ---
165
201
 
@@ -409,8 +445,8 @@ Compile all profiles into a single summary and present it to the user.
409
445
  - Test: `[command]`
410
446
  - Dev server: `[command]` (if detected)
411
447
 
412
- ## IDE Targets
413
- - [list each detected IDE — e.g., "Claude Code (always), GitHub Copilot (detected: .github/ exists)"]
448
+ ## IDE Targets (selected)
449
+ - [list selected IDE targets — e.g., "GitHub Copilot" or "Claude Code, Cursor"]
414
450
  ```
415
451
 
416
452
  ### Save profile
@@ -437,9 +473,16 @@ This step is critical for large projects where context compaction may have evict
437
473
 
438
474
  ---
439
475
 
440
- Generate all files in order. This order is designed for **graceful failure** — if the process is interrupted, the user has the most valuable files first.
476
+ Generate files based on the **selected IDE targets** from Phase 1. The generation order is designed for **graceful failure** — if the process is interrupted, the user has the most valuable files first.
441
477
 
442
- **If the user chose [M] (memory only):** generate steps 1-2 (memory + CLAUDE.md), then update the `<!-- crewkit:context-start -->` headers in existing agents (Step 3, header-only — do not overwrite agent body). Stop after that.
478
+ **IDE-conditional generation:**
479
+ - **Step 1** (`.ai/memory/`): ALWAYS — shared across all IDEs.
480
+ - **Steps 2-9** (CLAUDE.md, `.claude/agents/`, `.claude/rules/`, `.claude/settings.json`, `.claude/hooks/`, `.claude/skills/`, `.claude/QUICKSTART.md`, `.mcp.json`): ONLY if **Claude Code** is a selected target.
481
+ - **Step 10** (IDE Adapters): Runs for each non-Claude IDE in the selected targets. Adapters generate directly from scan data + `.ai/memory/` — they do NOT depend on Claude files existing.
482
+
483
+ If the only selected target is GitHub Copilot or Cursor, Steps 2-9 are **skipped entirely**. The adapter generates the IDE-native files directly.
484
+
485
+ **If the user chose [M] (memory only):** generate Step 1 (memory) + the project rules file for the selected IDE (CLAUDE.md / copilot-instructions.md / .cursor/rules/project.md), then update context headers in existing agents. Stop after that.
443
486
 
444
487
  ### Templates directory
445
488
  Templates are located at `~/.claude/skills/crewkit-setup/templates/`. Read them from disk.
@@ -591,6 +634,8 @@ Create empty `lessons-{stack}.md` files for each detected stack.
591
634
 
592
635
  ### Step 2 — `CLAUDE.md` (AI-generated from scan)
593
636
 
637
+ > **Conditional:** Skip this step if Claude Code is NOT a selected IDE target. Jump to Step 10.
638
+
594
639
  Generate the project's root `CLAUDE.md`. This is the most important generated file — it defines the AI's behavior for this project.
595
640
 
596
641
  **Structure:**
@@ -1001,15 +1046,20 @@ For any placeholder tokens, add a comment in the profile or tell the user to fil
1001
1046
 
1002
1047
  ### Step 10 — IDE Adapters
1003
1048
 
1004
- If IDE targets beyond Claude Code were detected in Phase 1 (e.g., GitHub Copilot, Cursor):
1049
+ For each **non-Claude IDE** in the selected targets (GitHub Copilot, Cursor):
1005
1050
 
1006
- 1. For each additional IDE target detected:
1051
+ 1. For each selected non-Claude IDE target:
1007
1052
  a. Determine the adapter file path: `~/.claude/skills/crewkit-setup/adapters/{ide}.md`
1008
1053
  - GitHub Copilot → `adapters/copilot.md`
1009
1054
  - Cursor → `adapters/cursor.md`
1010
1055
  b. If the adapter file does not exist: WARN the user ("Adapter file not found for [IDE] — skipping") and continue to the next IDE. Do not fail.
1011
- c. If the adapter file exists: read it completely, then MANDATORY: follow ALL instructions in it. The adapter reads scan data from `.crewkit/last-scan.md` and uses the already-generated Claude Code files (Steps 1-9) as its source.
1012
- 2. If no additional IDE targets were detected, skip this step entirely.
1056
+ c. If the adapter file exists: read it completely, then MANDATORY: follow ALL instructions in it.
1057
+
1058
+ **Source of truth for adapters (in priority order):**
1059
+ 1. If Claude Code files exist (Steps 2-9 were generated): use them as the primary source, converting content to the target IDE format.
1060
+ 2. If Claude Code files do NOT exist (Claude was not a selected target): generate IDE-native files directly from `.crewkit/last-scan.md` + `.ai/memory/` (Step 1). The adapter instructions describe the expected output format — use scan data to fill in the content instead of reformatting Claude files.
1061
+
1062
+ If no non-Claude IDE targets were selected, skip this step entirely.
1013
1063
 
1014
1064
  **Note:** The adapters do NOT duplicate `.ai/memory/` — that directory is shared across all IDEs without transformation.
1015
1065
 
@@ -1022,8 +1072,12 @@ After all generation steps, run the **Completion Checklist** (at the bottom of t
1022
1072
  ```markdown
1023
1073
  # crewkit setup complete
1024
1074
 
1025
- ## Generated files
1075
+ ## IDE target: [selected IDE(s)]
1076
+
1077
+ ## Generated files (shared)
1026
1078
  - `.ai/memory/` — [N] files (architecture, conventions, commands, testing, lessons, state)
1079
+
1080
+ ## Generated files (Claude Code) — only if selected
1027
1081
  - `CLAUDE.md` — project rules ([N] hard rules)
1028
1082
  - `.claude/agents/` — 5 agents (explorer, architect, coder, tester, reviewer)
1029
1083
  - `.claude/rules/` — [N] rule files ([list stacks])
@@ -1033,20 +1087,29 @@ After all generation steps, run the **Completion Checklist** (at the bottom of t
1033
1087
  - `.claude/napkin.md` — priorities board
1034
1088
  - `.claude/QUICKSTART.md` — onboarding guide
1035
1089
  - `.mcp.json` — [N] MCP servers
1036
- - Validation: [N]/17 checks passed
1090
+
1091
+ ## Generated files (GitHub Copilot) — only if selected
1092
+ - `.github/copilot-instructions.md` — project rules
1093
+ - `.github/instructions/` — [N] per-stack instruction files
1094
+ - `.github/agents/` — 5 agent files
1095
+
1096
+ ## Generated files (Cursor) — only if selected
1097
+ - `.cursor/rules/project.md` — project rules
1098
+ - `.cursor/rules/` — [N] per-stack rule files
1099
+ - `AGENTS.md` — all agents
1100
+
1101
+ ## Validation: [X]/[Y] checks passed
1037
1102
 
1038
1103
  ## Commands detected
1039
1104
  - Build: `[command]`
1040
1105
  - Test: `[command]`
1041
1106
 
1042
- ## Recommended MCPs to configure
1043
- [List MCPs with placeholder tokens that need user input]
1044
-
1045
1107
  ## Next steps
1046
- 1. Review `CLAUDE.md` and adjust rules as needed
1047
- 2. Fill in MCP tokens in `.mcp.json` (if applicable)
1048
- 3. Commit the setup: `git add .claude/ .ai/ CLAUDE.md .mcp.json && git commit -m "chore: add crewkit context engineering setup"`
1049
- 4. Run `/full-workflow <your-first-task>` to test the setup
1108
+ [Adapt next steps to the selected IDE:]
1109
+ - Claude Code: "Review CLAUDE.md run /full-workflow"
1110
+ - Copilot: "Review .github/copilot-instructions.md open Copilot Chat"
1111
+ - Cursor: "Review .cursor/rules/project.md start coding"
1112
+ - All: "Commit the setup"
1050
1113
  ```
1051
1114
 
1052
1115
  ---
@@ -1065,27 +1128,37 @@ After all generation steps, run the **Completion Checklist** (at the bottom of t
1065
1128
 
1066
1129
  Before presenting the Final Report, go through EVERY item. Fix failures before reporting.
1067
1130
 
1068
- ### Content checks
1131
+ ### Content checks (shared — always verify)
1069
1132
  - [ ] `.ai/memory/architecture.md` — has constructor/DI signatures table (if project uses DI)
1070
1133
  - [ ] `.ai/memory/conventions.md` — has Design System section (if frontend detected)
1071
1134
  - [ ] `.ai/memory/testing.md` — has Fakes/Stubs inventory table (if test doubles detected)
1072
1135
  - [ ] `.ai/memory/commands.md` — has build + test + dev commands for ALL detected stacks
1136
+
1137
+ ### Content checks (Claude Code — only if Claude is a selected target)
1073
1138
  - [ ] `CLAUDE.md` — hard rules present, all in English
1074
1139
  - [ ] `.claude/agents/` — all 5 have `crewkit:context-start` header with real project data
1075
1140
  - [ ] `.claude/QUICKSTART.md` — exists with workflow guide
1076
1141
 
1077
- ### Validation checks (run these, don't just assume)
1142
+ ### Validation checks (Claude Code only if Claude is a selected target)
1078
1143
  - [ ] `.claude/settings.json` — read back, verify valid JSON, has Write(.ai/memory/*), has stack permissions, has MCP permissions (Layer 4)
1079
1144
  - [ ] `.mcp.json` — read back, verify valid JSON, has context7
1080
1145
  - [ ] `.claude/hooks/*.sh` — run `bash -n` on each, all 4 pass syntax check
1081
1146
  - [ ] `.claude/rules/` — at least 1 per detected stack, glob patterns match real files in project
1082
1147
  - [ ] `.claude/skills/` — all 4 core skills have SKILL.md
1083
1148
 
1084
- ### Integrity checks
1149
+ ### Content checks (Copilot — only if Copilot is a selected target)
1150
+ - [ ] `.github/copilot-instructions.md` — exists, contains project hard rules, no Claude-specific sections
1151
+ - [ ] `.github/instructions/` — at least 1 per detected stack with `applyTo:` frontmatter
1152
+ - [ ] `.github/agents/` — 5 agent files with `.agent.md` extension, no `model:` lines
1153
+
1154
+ ### Content checks (Cursor — only if Cursor is a selected target)
1155
+ - [ ] `.cursor/rules/project.md` — exists, has `alwaysApply: true` frontmatter, no Claude-specific sections
1156
+ - [ ] `.cursor/rules/` — at least 1 per detected stack with `globs:` frontmatter
1157
+ - [ ] `AGENTS.md` — exists at project root with all 5 agents as `##` sections
1158
+
1159
+ ### Integrity checks (always)
1085
1160
  - [ ] `.crewkit/last-scan.md` — exists with full profile including Domain section
1086
1161
  - [ ] `.crewkit/scan-phase*.md` — all 4 phase files exist with content
1087
1162
  - [ ] No Portuguese in any generated file (only in user-facing output)
1088
- - [ ] If Copilot target detected: `.github/copilot-instructions.md` exists and contains the project hard rules
1089
- - [ ] If Cursor target detected: `.cursor/rules/project.md` exists and has `alwaysApply: true` frontmatter
1090
1163
 
1091
- Report checklist results as: "Validation: X/17 checks passed." If any failed, list which ones and why.
1164
+ Count only the checks applicable to the selected IDE targets. Report as: "Validation: X/Y checks passed." If any failed, list which ones and why.
@@ -3,8 +3,11 @@
3
3
  This adapter is executed during Phase 7, Step 10 of `/crewkit-setup`.
4
4
  You are the AI. Follow every instruction in this file to generate GitHub Copilot-compatible context files.
5
5
 
6
- **Input:** Read `.crewkit/last-scan.md` for the project profile. The Claude Code files generated in Steps 1-9 are your source of truth.
7
- **Output:** Files under `.github/` that mirror the Claude Code setup for GitHub Copilot.
6
+ **Input (two modes):**
7
+ - **With Claude files:** If `CLAUDE.md` and `.claude/` exist (Claude Code was also a target), use them as primary source and reformat for Copilot.
8
+ - **Standalone:** If Claude files do NOT exist, generate directly from `.crewkit/last-scan.md` (project profile) + `.ai/memory/` (architecture, conventions, commands). This is the primary source of truth.
9
+
10
+ **Output:** Files under `.github/` — GitHub Copilot-native context files.
8
11
 
9
12
  ---
10
13
 
@@ -20,15 +23,15 @@ You are the AI. Follow every instruction in this file to generate GitHub Copilot
20
23
 
21
24
  ## Step C1 — `.github/copilot-instructions.md`
22
25
 
23
- **Source:** `CLAUDE.md`
24
- **Transformation:** Reformat for Copilot. Remove the Agent Discipline, Skills (slash commands), Architect Decision Gate, and Test Safety Loop sections — these are Claude Code-specific orchestration mechanics that do not apply to Copilot. Keep the hard rules, overview, memory loading instructions, and output format.
26
+ **Source:** `CLAUDE.md` if it exists, otherwise `.crewkit/last-scan.md` + `.ai/memory/conventions.md`
27
+ **Transformation:** If using CLAUDE.md, reformat for Copilot remove Agent Discipline, Skills (slash commands), Architect Decision Gate, and Test Safety Loop sections (Claude Code-specific). Keep hard rules, overview, memory loading instructions, and output format. If generating from scan data, create the content directly using the project profile and conventions.
25
28
 
26
29
  **Expected output format:**
27
30
  ```markdown
28
31
  # [PROJECT NAME] — Copilot Instructions
29
32
 
30
33
  ## Overview
31
- [1-2 sentences from CLAUDE.md overview — what the project is, main stack]
34
+ [1-2 sentences — what the project is, main stack]
32
35
  [Business domain: what it does, core entities, risk profile]
33
36
 
34
37
  **Stack:** [stacks]
@@ -38,7 +41,7 @@ You are the AI. Follow every instruction in this file to generate GitHub Copilot
38
41
 
39
42
  ## Hard rules (apply to every response)
40
43
 
41
- [Numbered list — copy from CLAUDE.md hard rules verbatim. These are non-negotiable.]
44
+ [Numbered list of non-negotiable rules — from CLAUDE.md or from HIGH confidence patterns in scan data.]
42
45
 
43
46
  1. [Rule 1]
44
47
  2. [Rule 2]
@@ -85,8 +88,8 @@ Always return:
85
88
 
86
89
  ## Step C2 — `.github/instructions/*.instructions.md`
87
90
 
88
- **Source:** `.claude/rules/*.md`
89
- **Transformation:** Convert frontmatter to Copilot format. Keep glob patterns and all rule content unchanged.
91
+ **Source:** `.claude/rules/*.md` if they exist, otherwise generate directly from scan data (detected stacks + HIGH/MEDIUM confidence patterns).
92
+ **Transformation:** If using Claude rules, convert frontmatter to Copilot format keep glob patterns and rule content unchanged. If generating from scan data, create one instructions file per detected stack with appropriate glob patterns and rules.
90
93
 
91
94
  Claude Code frontmatter format:
92
95
  ```markdown
@@ -142,8 +145,8 @@ applyTo: "src/**/*.{js,ts}"
142
145
 
143
146
  ## Step C3 — `.github/agents/*.agent.md`
144
147
 
145
- **Source:** `.claude/agents/*.md`
146
- **Transformation:** Strip `model:` frontmatter line. Keep `name:` and `description:`. Remove the `<!-- crewkit:context-start -->...<!-- crewkit:context-end -->` block — Copilot agents do not use this inline context injection. Keep the full agent role description and instructions.
148
+ **Source:** `.claude/agents/*.md` if they exist, otherwise generate directly from the agent templates at `~/.claude/skills/crewkit-setup/templates/agents/` (or from scan data if templates are unavailable).
149
+ **Transformation:** Strip `model:` frontmatter line. Keep `name:` and `description:`. Remove the `<!-- crewkit:context-start -->...<!-- crewkit:context-end -->` block — Copilot agents do not use this inline context injection. Keep the full agent role description and instructions. When generating from templates, inject project context from `.crewkit/last-scan.md` into each agent.
147
150
 
148
151
  **Copilot agent frontmatter format:**
149
152
  ```markdown
@@ -3,7 +3,10 @@
3
3
  This adapter is executed during Phase 7, Step 10 of `/crewkit-setup`.
4
4
  You are the AI. Follow every instruction in this file to generate Cursor-compatible context files.
5
5
 
6
- **Input:** Read `.crewkit/last-scan.md` for the project profile. The Claude Code files generated in Steps 1-9 are your source of truth.
6
+ **Input (two modes):**
7
+ - **With Claude files:** If `CLAUDE.md` and `.claude/` exist (Claude Code was also a target), use them as primary source and reformat for Cursor.
8
+ - **Standalone:** If Claude files do NOT exist, generate directly from `.crewkit/last-scan.md` (project profile) + `.ai/memory/` (architecture, conventions, commands). This is the primary source of truth.
9
+
7
10
  **Output:** Files under `.cursor/rules/` and `AGENTS.md` at the project root.
8
11
 
9
12
  ---
@@ -20,8 +23,8 @@ You are the AI. Follow every instruction in this file to generate Cursor-compati
20
23
 
21
24
  ## Step U1 — `.cursor/rules/project.md`
22
25
 
23
- **Source:** `CLAUDE.md`
24
- **Transformation:** Reformat for Cursor. Add required frontmatter. Remove agent/skill/hook sections that are Claude Code-specific.
26
+ **Source:** `CLAUDE.md` if it exists, otherwise `.crewkit/last-scan.md` + `.ai/memory/conventions.md`
27
+ **Transformation:** If using CLAUDE.md, reformat for Cursor add required frontmatter, remove agent/skill/hook sections. If generating from scan data, create the content directly using the project profile and conventions.
25
28
 
26
29
  **Required Cursor frontmatter:**
27
30
  ```markdown
@@ -93,8 +96,8 @@ Always return:
93
96
 
94
97
  ## Step U2 — `.cursor/rules/*.md`
95
98
 
96
- **Source:** `.claude/rules/*.md`
97
- **Transformation:** Convert frontmatter to Cursor format. Keep glob patterns and all rule content unchanged.
99
+ **Source:** `.claude/rules/*.md` if they exist, otherwise generate directly from scan data (detected stacks + HIGH/MEDIUM confidence patterns).
100
+ **Transformation:** If using Claude rules, convert frontmatter to Cursor format keep glob patterns and rule content unchanged. If generating from scan data, create one rules file per detected stack with appropriate glob patterns and rules.
98
101
 
99
102
  Claude Code frontmatter format:
100
103
  ```markdown
@@ -150,8 +153,8 @@ globs: "**/*.py"
150
153
 
151
154
  ## Step U3 — `AGENTS.md` (project root)
152
155
 
153
- **Source:** All `.claude/agents/*.md` files
154
- **Transformation:** Concatenate all agents into a single markdown file with `##` sections. Strip `model:` frontmatter from each. Remove the `<!-- crewkit:context-start -->...<!-- crewkit:context-end -->` block from each agent. Keep the `name:` and `description:` from frontmatter and all agent instructions.
156
+ **Source:** `.claude/agents/*.md` if they exist, otherwise generate directly from the agent templates at `~/.claude/skills/crewkit-setup/templates/agents/` (or from scan data if templates are unavailable).
157
+ **Transformation:** Concatenate all agents into a single markdown file with `##` sections. Strip `model:` frontmatter from each. Remove the `<!-- crewkit:context-start -->...<!-- crewkit:context-end -->` block from each agent. Keep the `name:` and `description:` from frontmatter and all agent instructions. When generating from templates, inject project context from `.crewkit/last-scan.md` into each agent.
155
158
 
156
159
  **Output format:**
157
160
  ```markdown
@@ -0,0 +1,142 @@
1
+ ---
2
+ name: crewkit-setup
3
+ description: "Scan your codebase and generate a complete context engineering setup: agents, instructions, memory files, and copilot-instructions.md."
4
+ ---
5
+
6
+ # crewkit-setup
7
+
8
+ Scan the current project and generate a complete context engineering setup tailored to this codebase.
9
+
10
+ **You are the AI executing this.** Follow each phase in order. Do not ask the user questions. Scan, generate, report.
11
+
12
+ ---
13
+
14
+ ## Phase 1 — Reconnaissance
15
+
16
+ Scan the project to identify:
17
+ - **Stack & frameworks**: languages, build tools, test frameworks, package managers
18
+ - **Architecture**: monolith/microservices, key directories, entry points
19
+ - **Existing AI context**: any `.github/`, `.ai/`, `CLAUDE.md`, `AGENTS.md` files
20
+
21
+ Write findings to `.crewkit/scan-phase1-recon.md`.
22
+
23
+ ---
24
+
25
+ ## Phase 2 — Codebase Mapping
26
+
27
+ Read representative source files (3-5 per layer: models, services, controllers, tests). Identify:
28
+ - Naming conventions, code style
29
+ - Core domain concepts and entities
30
+ - Test patterns and coverage approach
31
+ - CI/CD and build commands
32
+
33
+ Write findings to `.crewkit/scan-phase2-map.md`.
34
+
35
+ ---
36
+
37
+ ## Phase 3 — Profile Compilation
38
+
39
+ Synthesize phases 1-2 into a project profile:
40
+ - Stack summary
41
+ - Architecture summary
42
+ - Key commands (build, test, lint)
43
+ - Domain concepts
44
+ - Hard rules to enforce
45
+
46
+ Write profile to `.crewkit/last-scan.md`.
47
+
48
+ ---
49
+
50
+ ## Phase 4 — File Generation
51
+
52
+ Generate all files using the profile from `.crewkit/last-scan.md`.
53
+
54
+ ### Step 1 — `.ai/memory/`
55
+
56
+ Create these files (all in English):
57
+ - `architecture.md` — system design, key components, data flow
58
+ - `conventions.md` — naming rules, patterns, anti-patterns
59
+ - `commands.md` — build, test, lint, run commands with flags
60
+ - `testing.md` — test strategy, frameworks, coverage approach
61
+ - `lessons.md` — known gotchas, non-obvious behaviors
62
+ - `state.md` — current sprint goal, recent changes, open issues
63
+
64
+ ### Step 2 — `.github/copilot-instructions.md`
65
+
66
+ ```markdown
67
+ # [PROJECT NAME] — Copilot Instructions
68
+
69
+ ## Overview
70
+ [1-2 sentences: what the project is, main stack]
71
+
72
+ **Stack:** [stacks]
73
+ **Architecture:** [key patterns]
74
+
75
+ ---
76
+
77
+ ## Hard rules (apply to every response)
78
+
79
+ [Numbered list of non-negotiable rules]
80
+
81
+ Details → `.ai/memory/conventions.md`
82
+
83
+ ---
84
+
85
+ ## Memory
86
+
87
+ - `.ai/memory/architecture.md` — system design
88
+ - `.ai/memory/conventions.md` — coding conventions
89
+ - `.ai/memory/commands.md` — build/test commands
90
+ - `.ai/memory/lessons.md` — known gotchas
91
+ ```
92
+
93
+ ### Step 3 — `.github/instructions/` (per-stack rules)
94
+
95
+ For each detected stack, create `[stack].instructions.md`:
96
+ ```markdown
97
+ ---
98
+ applyTo: "**/*.ts"
99
+ ---
100
+ [Stack-specific rules: error handling, imports, typing, testing patterns]
101
+ ```
102
+
103
+ ### Step 4 — `.github/agents/` (agent definitions)
104
+
105
+ Create one file per agent: `explorer.agent.md`, `architect.agent.md`, `coder.agent.md`, `tester.agent.md`, `reviewer.agent.md`.
106
+
107
+ Each file:
108
+ ```markdown
109
+ ---
110
+ name: [Agent Name]
111
+ description: "[One-line role description]"
112
+ ---
113
+ # [Agent Name]
114
+
115
+ **Role:** [role]
116
+ **Responsibilities:** [responsibilities]
117
+ **Approach:** [how it works]
118
+ **Output:** [what it produces]
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Phase 5 — Completion Report
124
+
125
+ After all files are generated, report to the user:
126
+
127
+ ```
128
+ crewkit-setup complete
129
+
130
+ Generated:
131
+ .ai/memory/ (6 files)
132
+ .github/copilot-instructions.md
133
+ .github/instructions/ (per-stack rules)
134
+ .github/agents/ (5 agents)
135
+
136
+ Stack detected: [stack]
137
+ Architecture: [pattern]
138
+
139
+ Next steps:
140
+ 1. Review .github/copilot-instructions.md — adjust hard rules if needed
141
+ 2. Open Copilot Chat — context is now active
142
+ ```
@@ -0,0 +1,157 @@
1
+ ---
2
+ description: "Context engineering setup — scan codebase and generate AI context files (.cursor/rules, AGENTS.md, .ai/memory)"
3
+ alwaysApply: false
4
+ ---
5
+
6
+ # crewkit-setup
7
+
8
+ Scan the current project and generate a complete context engineering setup tailored to this codebase.
9
+
10
+ **You are the AI executing this.** Follow each phase in order. Do not ask the user questions. Scan, generate, report.
11
+
12
+ ---
13
+
14
+ ## Phase 1 — Reconnaissance
15
+
16
+ Scan the project to identify:
17
+ - **Stack & frameworks**: languages, build tools, test frameworks, package managers
18
+ - **Architecture**: monolith/microservices, key directories, entry points
19
+ - **Existing AI context**: any `.cursor/`, `.github/`, `.ai/`, `CLAUDE.md`, `AGENTS.md` files
20
+
21
+ Write findings to `.crewkit/scan-phase1-recon.md`.
22
+
23
+ ---
24
+
25
+ ## Phase 2 — Codebase Mapping
26
+
27
+ Read representative source files (3-5 per layer: models, services, controllers, tests). Identify:
28
+ - Naming conventions, code style
29
+ - Core domain concepts and entities
30
+ - Test patterns and coverage approach
31
+ - CI/CD and build commands
32
+
33
+ Write findings to `.crewkit/scan-phase2-map.md`.
34
+
35
+ ---
36
+
37
+ ## Phase 3 — Profile Compilation
38
+
39
+ Synthesize phases 1-2 into a project profile:
40
+ - Stack summary
41
+ - Architecture summary
42
+ - Key commands (build, test, lint)
43
+ - Domain concepts
44
+ - Hard rules to enforce
45
+
46
+ Write profile to `.crewkit/last-scan.md`.
47
+
48
+ ---
49
+
50
+ ## Phase 4 — File Generation
51
+
52
+ Generate all files using the profile from `.crewkit/last-scan.md`.
53
+
54
+ ### Step 1 — `.ai/memory/`
55
+
56
+ Create these files (all in English):
57
+ - `architecture.md` — system design, key components, data flow
58
+ - `conventions.md` — naming rules, patterns, anti-patterns
59
+ - `commands.md` — build, test, lint, run commands with flags
60
+ - `testing.md` — test strategy, frameworks, coverage approach
61
+ - `lessons.md` — known gotchas, non-obvious behaviors
62
+ - `state.md` — current sprint goal, recent changes, open issues
63
+
64
+ ### Step 2 — `.cursor/rules/project.md`
65
+
66
+ ```
67
+ ---
68
+ description: "Project rules"
69
+ alwaysApply: true
70
+ ---
71
+ # [PROJECT NAME] — Project Rules
72
+
73
+ ## Overview
74
+ [1-2 sentences: what the project is, main stack]
75
+
76
+ **Stack:** [stacks]
77
+ **Architecture:** [key patterns]
78
+
79
+ ---
80
+
81
+ ## Hard rules
82
+
83
+ [Numbered list of non-negotiable rules from the profile]
84
+
85
+ ---
86
+
87
+ ## Memory
88
+
89
+ Reference files in `.ai/memory/` for detailed context:
90
+ - `.ai/memory/architecture.md` — system design
91
+ - `.ai/memory/conventions.md` — coding conventions
92
+ - `.ai/memory/commands.md` — build/test commands
93
+ ```
94
+
95
+ ### Step 3 — `.cursor/rules/` (per-stack rules)
96
+
97
+ For each detected stack (e.g., `typescript.md`, `python.md`), generate a rules file with:
98
+ ```
99
+ ---
100
+ description: "[Stack] coding rules"
101
+ globs: ["**/*.ts"] (or appropriate glob)
102
+ alwaysApply: false
103
+ ---
104
+ [Stack-specific rules: error handling, imports, typing, testing patterns]
105
+ ```
106
+
107
+ ### Step 4 — `AGENTS.md`
108
+
109
+ Create a single `AGENTS.md` at the project root with all agents as `##` sections:
110
+
111
+ ```markdown
112
+ # Agents
113
+
114
+ ## Explorer
115
+ Role: Codebase reconnaissance and research.
116
+ [...]
117
+
118
+ ## Architect
119
+ Role: System design and planning.
120
+ [...]
121
+
122
+ ## Coder
123
+ Role: Implementation.
124
+ [...]
125
+
126
+ ## Tester
127
+ Role: Test writing and validation.
128
+ [...]
129
+
130
+ ## Reviewer
131
+ Role: Code review and quality.
132
+ [...]
133
+ ```
134
+
135
+ Each agent section should include: Role, Responsibilities, Approach, Output format.
136
+
137
+ ---
138
+
139
+ ## Phase 5 — Completion Report
140
+
141
+ After all files are generated, report to the user:
142
+
143
+ ```
144
+ crewkit-setup complete
145
+
146
+ Generated:
147
+ .ai/memory/ (6 files)
148
+ .cursor/rules/ (project.md + per-stack rules)
149
+ AGENTS.md (5 agents)
150
+
151
+ Stack detected: [stack]
152
+ Architecture: [pattern]
153
+
154
+ Next steps:
155
+ 1. Review .cursor/rules/project.md — adjust hard rules if needed
156
+ 2. Open Cursor and start coding — context is active
157
+ ```
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "analytics",
3
+ "description": "Development metrics and post-mortem analysis",
4
+ "components": {
5
+ "skills": ["dev-metrics", "retro"]
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "quality",
3
+ "description": "Code review, blast radius analysis, and post-mortems",
4
+ "components": {
5
+ "skills": ["review-pr", "impact", "retro"]
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "security",
3
+ "description": "OWASP vulnerability scanning and security hardening",
4
+ "components": {
5
+ "skills": ["security-scan"]
6
+ }
7
+ }
package/src/add.js CHANGED
@@ -1,45 +1,109 @@
1
- import { cpSync, mkdirSync, existsSync } from 'node:fs';
1
+ import { cpSync, mkdirSync, existsSync, readdirSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { homedir } from 'node:os';
4
+ import { CORE_SKILLS } from './constants.js';
4
5
 
5
- const OPTIONAL_SKILLS = ['retro', 'dev-metrics', 'security-scan', 'impact'];
6
+ function getOptionalSkills() {
7
+ const skillsDir = join(homedir(), '.claude', 'skills', 'crewkit-setup', 'templates', 'skills');
8
+ if (!existsSync(skillsDir)) return [];
9
+ return readdirSync(skillsDir, { withFileTypes: true })
10
+ .filter(d => d.isDirectory() && !CORE_SKILLS.includes(d.name))
11
+ .map(d => d.name);
12
+ }
6
13
 
7
- export function add(skillName) {
8
- if (!skillName) {
9
- console.error('Error: skill name is required.');
10
- console.log(`\n Available optional skills:\n${OPTIONAL_SKILLS.map(s => ` - ${s}`).join('\n')}\n`);
14
+ function getAvailablePacks() {
15
+ const packsDir = join(homedir(), '.claude', 'skills', 'crewkit-setup', 'packs');
16
+ if (!existsSync(packsDir)) return [];
17
+ return readdirSync(packsDir, { withFileTypes: true })
18
+ .filter(d => d.isDirectory() && existsSync(join(packsDir, d.name, 'pack.json')))
19
+ .map(d => d.name);
20
+ }
21
+
22
+ function installSkill(skillName) {
23
+ const sourceDir = join(homedir(), '.claude', 'skills', 'crewkit-setup', 'templates', 'skills', skillName);
24
+
25
+ if (!existsSync(sourceDir)) {
26
+ console.error(`Error: source not found at ${sourceDir}`);
27
+ console.log(' Make sure crewkit is installed first: npx crewkit install');
11
28
  process.exit(1);
12
29
  }
13
30
 
14
- if (!OPTIONAL_SKILLS.includes(skillName)) {
15
- console.error(`Error: "${skillName}" is not a known optional skill.`);
16
- console.log(`\n Available optional skills:\n${OPTIONAL_SKILLS.map(s => ` - ${s}`).join('\n')}\n`);
17
- process.exit(1);
31
+ const targetDir = join(process.cwd(), '.claude', 'skills', skillName);
32
+
33
+ if (existsSync(targetDir)) {
34
+ console.log(` Warning: ${targetDir} already exists. Overwriting.`);
18
35
  }
19
36
 
20
- const source = join(homedir(), '.claude', 'skills', 'crewkit-setup', 'templates', 'skills', skillName, 'SKILL.md');
37
+ mkdirSync(targetDir, { recursive: true });
38
+ cpSync(sourceDir, targetDir, { recursive: true, force: true });
39
+
40
+ return targetDir;
41
+ }
42
+
43
+ function installPack(packName) {
44
+ const packJson = join(homedir(), '.claude', 'skills', 'crewkit-setup', 'packs', packName, 'pack.json');
45
+ let pack;
46
+ try {
47
+ pack = JSON.parse(readFileSync(packJson, 'utf8'));
48
+ } catch {
49
+ console.error(`Error: invalid pack.json for "${packName}".`);
50
+ process.exit(1);
51
+ }
52
+ const skills = pack.components?.skills ?? [];
21
53
 
22
- if (!existsSync(source)) {
23
- console.error(`Error: source not found at ${source}`);
54
+ const templatesDir = join(homedir(), '.claude', 'skills', 'crewkit-setup', 'templates', 'skills');
55
+ const missing = skills.filter(s => !existsSync(join(templatesDir, s)));
56
+ if (missing.length) {
57
+ console.error(`Error: pack "${packName}" references missing skills: ${missing.join(', ')}`);
24
58
  console.log(' Make sure crewkit is installed first: npx crewkit install');
25
59
  process.exit(1);
26
60
  }
27
61
 
28
- const targetDir = join(process.cwd(), '.claude', 'skills', skillName);
29
- const target = join(targetDir, 'SKILL.md');
62
+ const installed = [];
63
+ for (const skillName of skills) {
64
+ const targetDir = installSkill(skillName);
65
+ installed.push({ name: skillName, path: targetDir });
66
+ }
30
67
 
31
- if (existsSync(target)) {
32
- console.log(` Warning: ${target} already exists. Overwriting.`);
68
+ console.log(`
69
+ Pack "${packName}" installed (${installed.length} skill${installed.length !== 1 ? 's' : ''})
70
+ `);
71
+ for (const { name, path } of installed) {
72
+ console.log(` /${name} → ${path}`);
33
73
  }
74
+ console.log('');
75
+ }
34
76
 
35
- mkdirSync(targetDir, { recursive: true });
36
- cpSync(source, target);
77
+ export function add(skillName) {
78
+ const availablePacks = getAvailablePacks();
79
+ const optionalSkills = getOptionalSkills();
37
80
 
38
- console.log(`
81
+ if (!skillName) {
82
+ console.error('Error: skill name is required.');
83
+ console.log(`\n Available packs:\n${availablePacks.map(p => ` - ${p}`).join('\n')}`);
84
+ console.log(`\n Available optional skills:\n${optionalSkills.map(s => ` - ${s}`).join('\n')}\n`);
85
+ process.exit(1);
86
+ }
87
+
88
+ if (availablePacks.includes(skillName)) {
89
+ installPack(skillName);
90
+ return;
91
+ }
92
+
93
+ if (optionalSkills.includes(skillName)) {
94
+ const targetDir = installSkill(skillName);
95
+ console.log(`
39
96
  ✓ Skill "${skillName}" installed
40
97
 
41
- Copied to: ${target}
98
+ Copied to: ${targetDir}
42
99
 
43
100
  Use /${skillName} in Claude Code to run it.
44
101
  `);
102
+ return;
103
+ }
104
+
105
+ console.error(`Error: "${skillName}" is not a known pack or optional skill.`);
106
+ console.log(`\n Available packs:\n${availablePacks.map(p => ` - ${p}`).join('\n')}`);
107
+ console.log(`\n Available optional skills:\n${optionalSkills.map(s => ` - ${s}`).join('\n')}\n`);
108
+ process.exit(1);
45
109
  }
package/src/cli.js CHANGED
@@ -1,19 +1,23 @@
1
1
  import { install } from './install.js';
2
2
  import { update } from './update.js';
3
3
  import { add } from './add.js';
4
+ import { list } from './list.js';
4
5
 
5
6
  const HELP = `
6
7
  crewkit — Context engineering for AI-assisted development
7
8
 
8
9
  Commands:
9
- install Install crewkit skill globally (~/.claude/skills/)
10
+ install Install crewkit globally (Claude Code, Copilot, Cursor)
10
11
  update Update to latest version (re-run install)
11
- add <skill> Add an optional skill to the current project
12
+ add <name> Add an optional skill or pack to the current project
13
+ list List all available skills and packs (core + add-ons)
12
14
  help Show this message
13
15
 
14
16
  Usage:
15
17
  npx crewkit install # one-time setup
18
+ npx crewkit list # see all available skills and packs
16
19
  npx crewkit add retro # add optional skill to project
20
+ npx crewkit add quality # add a pack (multiple skills)
17
21
  /crewkit-setup # run in your IDE to scan & calibrate a project
18
22
  `;
19
23
 
@@ -22,14 +26,18 @@ export function run(args) {
22
26
 
23
27
  switch (command) {
24
28
  case 'install':
25
- install();
26
- break;
29
+ install().catch(err => { console.error(err.message); process.exit(1); });
30
+ return;
31
+
27
32
  case 'update':
28
- update();
29
- break;
33
+ update().catch(err => { console.error(err.message); process.exit(1); });
34
+ return;
30
35
  case 'add':
31
36
  add(args[1]);
32
37
  break;
38
+ case 'list':
39
+ list();
40
+ break;
33
41
  case 'help':
34
42
  case '--help':
35
43
  case '-h':
@@ -0,0 +1 @@
1
+ export const CORE_SKILLS = ['full-workflow', 'hotfix', 'explore-and-plan', 'review-pr'];
package/src/detect.js ADDED
@@ -0,0 +1,25 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+
5
+ export function detectTools() {
6
+ const tools = [];
7
+ const home = homedir();
8
+
9
+ if (existsSync(join(home, '.claude'))) {
10
+ const dest = join(home, '.claude', 'skills', 'crewkit-setup');
11
+ tools.push({ id: 'claude', name: 'Claude Code', dest, versionFile: join(dest, '.version') });
12
+ }
13
+
14
+ if (existsSync(join(home, '.copilot'))) {
15
+ const dest = join(home, '.copilot', 'agents');
16
+ tools.push({ id: 'copilot', name: 'GitHub Copilot', dest, versionFile: join(dest, 'crewkit-setup.version') });
17
+ }
18
+
19
+ if (existsSync(join(home, '.cursor'))) {
20
+ const dest = join(home, '.cursor');
21
+ tools.push({ id: 'cursor', name: 'Cursor', dest, versionFile: join(dest, 'crewkit-setup.version') });
22
+ }
23
+
24
+ return tools;
25
+ }
package/src/install.js CHANGED
@@ -1,43 +1,65 @@
1
- import { cpSync, mkdirSync, existsSync, readFileSync, writeFileSync } from 'node:fs';
1
+ import { cpSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from 'node:fs';
2
2
  import { join, dirname } from 'node:path';
3
- import { homedir } from 'node:os';
4
3
  import { fileURLToPath } from 'node:url';
4
+ import { detectTools } from './detect.js';
5
+ import { selectTargets } from './prompt.js';
5
6
 
6
7
  const __filename = fileURLToPath(import.meta.url);
7
8
  const __dirname = dirname(__filename);
8
9
 
9
- export function install() {
10
- const skillSource = join(__dirname, '..', 'skill');
11
- const skillDest = join(homedir(), '.claude', 'skills', 'crewkit-setup');
12
-
13
- // Verify source exists
14
- if (!existsSync(skillSource)) {
15
- console.error('Error: skill/ directory not found. Package may be corrupted.');
16
- process.exit(1);
17
- }
18
-
19
- // Create destination
20
- mkdirSync(skillDest, { recursive: true });
10
+ function readVersion() {
11
+ return JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8')).version;
12
+ }
21
13
 
22
- // Copy skill + templates
23
- cpSync(skillSource, skillDest, { recursive: true, force: true });
14
+ function installClaude(target, version) {
15
+ const skillSource = join(__dirname, '..', 'skill');
16
+ mkdirSync(target.dest, { recursive: true });
17
+ cpSync(skillSource, target.dest, { recursive: true, force: true });
18
+ writeFileSync(target.versionFile, version, 'utf8');
19
+ console.log(` ✓ Claude Code → ${target.dest}`);
20
+ console.log(` Run /crewkit-setup in any project\n`);
21
+ }
24
22
 
25
- // Read version
26
- const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
23
+ function installSingleFile(target, templateFile, outputFile, label, hint, version) {
24
+ const template = join(__dirname, '..', 'skill', templateFile);
25
+ mkdirSync(target.dest, { recursive: true });
26
+ copyFileSync(template, join(target.dest, outputFile));
27
+ writeFileSync(target.versionFile, version, 'utf8');
28
+ console.log(` ✓ ${label} → ${join(target.dest, outputFile)}`);
29
+ console.log(` ${hint}\n`);
30
+ }
27
31
 
28
- // Write version marker
29
- writeFileSync(join(skillDest, '.version'), pkg.version, 'utf8');
32
+ export async function install() {
33
+ const version = readVersion();
34
+ const tools = detectTools();
30
35
 
31
- console.log(`
32
- ✓ crewkit v${pkg.version} installed
36
+ if (tools.length === 0) {
37
+ console.log(`
38
+ No supported AI tools detected.
33
39
 
34
- Skill copied to: ${skillDest}
40
+ crewkit looks for: ~/.claude, ~/.copilot, ~/.cursor
41
+ Install one of these tools and re-run.
42
+ `);
43
+ process.exit(1);
44
+ }
35
45
 
36
- Next: open any project in Claude Code and run:
46
+ const targets = await selectTargets(tools);
37
47
 
38
- /crewkit-setup
48
+ console.log(`\n Installing crewkit v${version}...\n`);
39
49
 
40
- This will scan your codebase and generate a complete
41
- context engineering setup (agents, skills, hooks, rules, memory).
42
- `);
50
+ for (const target of targets) {
51
+ switch (target.id) {
52
+ case 'claude':
53
+ installClaude(target, version);
54
+ break;
55
+ case 'copilot':
56
+ installSingleFile(target, 'copilot-agent.md', 'crewkit-setup.md',
57
+ 'GitHub Copilot ', 'Use @crewkit-setup in Copilot CLI or Chat', version);
58
+ break;
59
+ case 'cursor':
60
+ installSingleFile(target, 'cursor-global.md', 'crewkit-setup.md',
61
+ 'Cursor ', 'Copy to .cursor/rules/ in your projects', version);
62
+ break;
63
+ }
64
+ }
43
65
  }
package/src/list.js ADDED
@@ -0,0 +1,75 @@
1
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { CORE_SKILLS } from './constants.js';
5
+
6
+ function readDescription(skillDir) {
7
+ const skillMd = join(skillDir, 'SKILL.md');
8
+ if (!existsSync(skillMd)) return '';
9
+ const content = readFileSync(skillMd, 'utf8');
10
+ const match = content.match(/^---[\s\S]*?^description:\s*"?(.+?)"?\s*$/m);
11
+ if (!match) return '';
12
+ const desc = match[1].trim();
13
+ return desc.length > 45 ? desc.slice(0, 44) + '…' : desc;
14
+ }
15
+
16
+ function getAvailablePacks() {
17
+ const packsDir = join(homedir(), '.claude', 'skills', 'crewkit-setup', 'packs');
18
+ if (!existsSync(packsDir)) return [];
19
+ return readdirSync(packsDir, { withFileTypes: true })
20
+ .filter(d => d.isDirectory() && existsSync(join(packsDir, d.name, 'pack.json')))
21
+ .map(d => {
22
+ try {
23
+ const pack = JSON.parse(readFileSync(join(packsDir, d.name, 'pack.json'), 'utf8'));
24
+ return { name: d.name, description: pack.description ?? '', skills: pack.components?.skills ?? [] };
25
+ } catch {
26
+ return { name: d.name, description: '(invalid pack.json)', skills: [] };
27
+ }
28
+ });
29
+ }
30
+
31
+ export function list() {
32
+ const skillsDir = join(homedir(), '.claude', 'skills', 'crewkit-setup', 'templates', 'skills');
33
+
34
+ if (!existsSync(skillsDir)) {
35
+ console.error('Error: crewkit templates not found.');
36
+ console.log(' Make sure crewkit is installed first: npx crewkit install');
37
+ process.exit(1);
38
+ }
39
+
40
+ const allDirs = readdirSync(skillsDir, { withFileTypes: true })
41
+ .filter(d => d.isDirectory())
42
+ .map(d => d.name);
43
+
44
+ const coreSkills = CORE_SKILLS.filter(s => allDirs.includes(s));
45
+ const addonSkills = allDirs.filter(s => !CORE_SKILLS.includes(s)).sort();
46
+ const packs = getAvailablePacks();
47
+
48
+ const pad = (name, width) => name + ' '.repeat(Math.max(1, width - name.length));
49
+ const nameWidth = Math.max(...[...coreSkills, ...addonSkills, ...packs.map(p => p.name)].map(s => s.length)) + 2;
50
+
51
+ console.log('\ncrewkit — available components\n');
52
+
53
+ console.log(' Core skills (installed by /crewkit-setup):');
54
+ for (const name of coreSkills) {
55
+ const desc = readDescription(join(skillsDir, name));
56
+ console.log(` ${pad(name, nameWidth)}${desc}`);
57
+ }
58
+
59
+ console.log('\n Add-on skills (install with: npx crewkit add <name>):');
60
+ for (const name of addonSkills) {
61
+ const desc = readDescription(join(skillsDir, name));
62
+ console.log(` ${pad(name, nameWidth)}${desc}`);
63
+ }
64
+
65
+ if (packs.length > 0) {
66
+ console.log('\n Packs (install with: npx crewkit add <name>):');
67
+ for (const { name, description, skills } of packs) {
68
+ const desc = description.length > 45 ? description.slice(0, 44) + '…' : description;
69
+ const contents = skills.length > 0 ? ` [${skills.join(', ')}]` : '';
70
+ console.log(` ${pad(name, nameWidth)}${desc}${contents}`);
71
+ }
72
+ }
73
+
74
+ console.log('');
75
+ }
package/src/prompt.js ADDED
@@ -0,0 +1,32 @@
1
+ import { createInterface } from 'node:readline';
2
+
3
+ function ask(question) {
4
+ return new Promise(resolve => {
5
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
6
+ rl.question(question, answer => {
7
+ rl.close();
8
+ resolve(answer.trim());
9
+ });
10
+ });
11
+ }
12
+
13
+ export async function selectTargets(tools) {
14
+ if (tools.length === 0) return [];
15
+ if (tools.length === 1) return [tools[0]];
16
+
17
+ console.log('\n Multiple AI tools detected. Where do you want to install crewkit?\n');
18
+ tools.forEach((tool, i) => {
19
+ console.log(` [${i + 1}] ${tool.name}`);
20
+ });
21
+ console.log(` [${tools.length + 1}] All of the above`);
22
+ console.log();
23
+
24
+ const answer = await ask(' Your choice: ');
25
+ const num = parseInt(answer, 10);
26
+
27
+ if (num === tools.length + 1) return tools;
28
+ if (num >= 1 && num <= tools.length) return [tools[num - 1]];
29
+
30
+ console.log(' Invalid choice. Installing to all detected tools.');
31
+ return tools;
32
+ }
package/src/update.js CHANGED
@@ -1,27 +1,32 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { join, dirname } from 'node:path';
3
- import { homedir } from 'node:os';
4
3
  import { fileURLToPath } from 'node:url';
4
+ import { detectTools } from './detect.js';
5
5
  import { install } from './install.js';
6
6
 
7
7
  const __filename = fileURLToPath(import.meta.url);
8
8
  const __dirname = dirname(__filename);
9
9
 
10
- export function update() {
11
- const versionFile = join(homedir(), '.claude', 'skills', 'crewkit-setup', '.version');
12
- const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
10
+ function getInstalledVersion() {
11
+ for (const tool of detectTools()) {
12
+ if (existsSync(tool.versionFile)) {
13
+ return readFileSync(tool.versionFile, 'utf8').trim();
14
+ }
15
+ }
16
+ return 'unknown';
17
+ }
13
18
 
19
+ export async function update() {
20
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
14
21
  const newVersion = pkg.version;
15
- const currentVersion = existsSync(versionFile)
16
- ? readFileSync(versionFile, 'utf8').trim()
17
- : 'unknown';
22
+ const currentVersion = getInstalledVersion();
18
23
 
19
24
  if (currentVersion === newVersion) {
20
25
  console.log(` Already up to date (v${newVersion})`);
21
26
  return;
22
27
  }
23
28
 
24
- install();
29
+ await install();
25
30
 
26
31
  const fromLabel = currentVersion === 'unknown' ? 'v0.1 (untracked)' : `v${currentVersion}`;
27
32
  console.log(` Updated: ${fromLabel} → v${newVersion}`);