@qazuor/claude-code-config 0.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.
Files changed (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1248 -0
  3. package/dist/bin.cjs +11886 -0
  4. package/dist/bin.cjs.map +1 -0
  5. package/dist/bin.d.cts +1 -0
  6. package/dist/bin.d.ts +1 -0
  7. package/dist/bin.js +11869 -0
  8. package/dist/bin.js.map +1 -0
  9. package/dist/index.cjs +3887 -0
  10. package/dist/index.cjs.map +1 -0
  11. package/dist/index.d.cts +1325 -0
  12. package/dist/index.d.ts +1325 -0
  13. package/dist/index.js +3835 -0
  14. package/dist/index.js.map +1 -0
  15. package/package.json +86 -0
  16. package/templates/.log/notifications.log +1775 -0
  17. package/templates/agents/README.md +164 -0
  18. package/templates/agents/_registry.json +443 -0
  19. package/templates/agents/design/content-writer.md +353 -0
  20. package/templates/agents/design/ux-ui-designer.md +382 -0
  21. package/templates/agents/engineering/astro-engineer.md +293 -0
  22. package/templates/agents/engineering/db-drizzle-engineer.md +360 -0
  23. package/templates/agents/engineering/express-engineer.md +316 -0
  24. package/templates/agents/engineering/fastify-engineer.md +399 -0
  25. package/templates/agents/engineering/hono-engineer.md +263 -0
  26. package/templates/agents/engineering/mongoose-engineer.md +473 -0
  27. package/templates/agents/engineering/nestjs-engineer.md +429 -0
  28. package/templates/agents/engineering/nextjs-engineer.md +451 -0
  29. package/templates/agents/engineering/node-typescript-engineer.md +347 -0
  30. package/templates/agents/engineering/prisma-engineer.md +432 -0
  31. package/templates/agents/engineering/react-senior-dev.md +394 -0
  32. package/templates/agents/engineering/tanstack-start-engineer.md +447 -0
  33. package/templates/agents/engineering/tech-lead.md +269 -0
  34. package/templates/agents/product/product-functional.md +329 -0
  35. package/templates/agents/product/product-technical.md +578 -0
  36. package/templates/agents/quality/debugger.md +514 -0
  37. package/templates/agents/quality/qa-engineer.md +390 -0
  38. package/templates/agents/specialized/enrichment-agent.md +277 -0
  39. package/templates/agents/specialized/i18n-specialist.md +322 -0
  40. package/templates/agents/specialized/seo-ai-specialist.md +387 -0
  41. package/templates/agents/specialized/tech-writer.md +300 -0
  42. package/templates/code-style/.editorconfig +27 -0
  43. package/templates/code-style/.prettierignore +25 -0
  44. package/templates/code-style/.prettierrc +12 -0
  45. package/templates/code-style/biome.json +78 -0
  46. package/templates/code-style/commitlint.config.js +44 -0
  47. package/templates/commands/README.md +175 -0
  48. package/templates/commands/_registry.json +420 -0
  49. package/templates/commands/add-new-entity.md +211 -0
  50. package/templates/commands/audit/accessibility-audit.md +360 -0
  51. package/templates/commands/audit/performance-audit.md +290 -0
  52. package/templates/commands/audit/security-audit.md +231 -0
  53. package/templates/commands/code-check.md +127 -0
  54. package/templates/commands/five-why.md +225 -0
  55. package/templates/commands/formatting/format-markdown.md +197 -0
  56. package/templates/commands/git/commit.md +247 -0
  57. package/templates/commands/meta/create-agent.md +257 -0
  58. package/templates/commands/meta/create-command.md +312 -0
  59. package/templates/commands/meta/create-skill.md +321 -0
  60. package/templates/commands/meta/help.md +318 -0
  61. package/templates/commands/planning/check-completed-tasks.md +224 -0
  62. package/templates/commands/planning/cleanup-issues.md +248 -0
  63. package/templates/commands/planning/planning-cleanup.md +251 -0
  64. package/templates/commands/planning/sync-planning-github.md +133 -0
  65. package/templates/commands/planning/sync-todos-github.md +203 -0
  66. package/templates/commands/quality-check.md +211 -0
  67. package/templates/commands/run-tests.md +159 -0
  68. package/templates/commands/start-feature-plan.md +232 -0
  69. package/templates/commands/start-refactor-plan.md +244 -0
  70. package/templates/commands/sync-planning.md +176 -0
  71. package/templates/commands/update-docs.md +242 -0
  72. package/templates/docs/CHECKPOINT-SYSTEM.md +504 -0
  73. package/templates/docs/INDEX.md +677 -0
  74. package/templates/docs/RECOMMENDED-HOOKS.md +415 -0
  75. package/templates/docs/_registry.json +329 -0
  76. package/templates/docs/diagrams/README.md +220 -0
  77. package/templates/docs/diagrams/agent-hierarchy.mmd +55 -0
  78. package/templates/docs/diagrams/documentation-map.mmd +61 -0
  79. package/templates/docs/diagrams/tools-relationship.mmd +55 -0
  80. package/templates/docs/diagrams/workflow-decision-tree.mmd +38 -0
  81. package/templates/docs/doc-sync.md +533 -0
  82. package/templates/docs/examples/end-to-end-workflow.md +1505 -0
  83. package/templates/docs/glossary.md +495 -0
  84. package/templates/docs/guides/mockup-prompt-engineering.md +644 -0
  85. package/templates/docs/guides/mockup-setup.md +737 -0
  86. package/templates/docs/learnings/README.md +250 -0
  87. package/templates/docs/learnings/common-architectural-patterns.md +123 -0
  88. package/templates/docs/learnings/common-mistakes-to-avoid.md +149 -0
  89. package/templates/docs/learnings/markdown-formatting-standards.md +104 -0
  90. package/templates/docs/learnings/monorepo-command-execution.md +64 -0
  91. package/templates/docs/learnings/optimization-tips.md +146 -0
  92. package/templates/docs/learnings/planning-linear-sync-workflow.md +70 -0
  93. package/templates/docs/learnings/shell-compatibility-fish.md +46 -0
  94. package/templates/docs/learnings/test-organization-structure.md +68 -0
  95. package/templates/docs/mcp-installation.md +613 -0
  96. package/templates/docs/mcp-servers.md +989 -0
  97. package/templates/docs/notification-installation.md +570 -0
  98. package/templates/docs/quick-start.md +354 -0
  99. package/templates/docs/standards/architecture-patterns.md +1064 -0
  100. package/templates/docs/standards/atomic-commits.md +513 -0
  101. package/templates/docs/standards/code-standards.md +993 -0
  102. package/templates/docs/standards/design-standards.md +656 -0
  103. package/templates/docs/standards/documentation-standards.md +1160 -0
  104. package/templates/docs/standards/testing-standards.md +969 -0
  105. package/templates/docs/system-maintenance.md +604 -0
  106. package/templates/docs/templates/PDR-template.md +561 -0
  107. package/templates/docs/templates/TODOs-template.md +534 -0
  108. package/templates/docs/templates/tech-analysis-template.md +800 -0
  109. package/templates/docs/workflows/README.md +519 -0
  110. package/templates/docs/workflows/atomic-task-protocol.md +955 -0
  111. package/templates/docs/workflows/decision-tree.md +482 -0
  112. package/templates/docs/workflows/edge-cases.md +856 -0
  113. package/templates/docs/workflows/phase-1-planning.md +957 -0
  114. package/templates/docs/workflows/phase-2-implementation.md +896 -0
  115. package/templates/docs/workflows/phase-3-validation.md +792 -0
  116. package/templates/docs/workflows/phase-4-finalization.md +927 -0
  117. package/templates/docs/workflows/quick-fix-protocol.md +505 -0
  118. package/templates/docs/workflows/task-atomization.md +537 -0
  119. package/templates/docs/workflows/task-completion-protocol.md +448 -0
  120. package/templates/hooks/on-notification.sh +28 -0
  121. package/templates/schemas/checkpoint.schema.json +97 -0
  122. package/templates/schemas/code-registry.schema.json +84 -0
  123. package/templates/schemas/pdr.schema.json +314 -0
  124. package/templates/schemas/problems.schema.json +55 -0
  125. package/templates/schemas/tech-analysis.schema.json +404 -0
  126. package/templates/schemas/telemetry.schema.json +298 -0
  127. package/templates/schemas/todos.schema.json +234 -0
  128. package/templates/schemas/workflows.schema.json +69 -0
  129. package/templates/scripts/add-changelogs.sh +105 -0
  130. package/templates/scripts/generate-code-registry.ts +270 -0
  131. package/templates/scripts/health-check.sh +343 -0
  132. package/templates/scripts/sync-registry.sh +40 -0
  133. package/templates/scripts/telemetry-report.ts +36 -0
  134. package/templates/scripts/validate-docs.sh +224 -0
  135. package/templates/scripts/validate-registry.sh +225 -0
  136. package/templates/scripts/validate-schemas.ts +283 -0
  137. package/templates/scripts/validate-structure.sh +165 -0
  138. package/templates/scripts/worktree-cleanup.sh +81 -0
  139. package/templates/scripts/worktree-create.sh +63 -0
  140. package/templates/sessions/planning/.gitkeep +0 -0
  141. package/templates/sessions/planning/archived/.gitkeep +0 -0
  142. package/templates/settings.json +202 -0
  143. package/templates/settings.local.json +138 -0
  144. package/templates/skills/README.md +197 -0
  145. package/templates/skills/_registry.json +473 -0
  146. package/templates/skills/audit/accessibility-audit.md +309 -0
  147. package/templates/skills/audit/performance-audit.md +257 -0
  148. package/templates/skills/audit/security-audit.md +217 -0
  149. package/templates/skills/auth/nextauth-patterns.md +308 -0
  150. package/templates/skills/brand-guidelines.md +240 -0
  151. package/templates/skills/documentation/markdown-formatter.md +302 -0
  152. package/templates/skills/git/git-commit-helper.md +321 -0
  153. package/templates/skills/i18n/i18n-patterns.md +251 -0
  154. package/templates/skills/patterns/error-handling-patterns.md +242 -0
  155. package/templates/skills/patterns/tdd-methodology.md +342 -0
  156. package/templates/skills/qa/qa-criteria-validator.md +383 -0
  157. package/templates/skills/qa/web-app-testing.md +398 -0
  158. package/templates/skills/react/react-hook-form-patterns.md +359 -0
  159. package/templates/skills/state/redux-toolkit-patterns.md +272 -0
  160. package/templates/skills/state/tanstack-query-patterns.md +299 -0
  161. package/templates/skills/state/zustand-patterns.md +301 -0
  162. package/templates/skills/tech/mermaid-diagram-specialist.md +195 -0
  163. package/templates/skills/tech/shadcn-specialist.md +252 -0
  164. package/templates/skills/tech/vercel-specialist.md +297 -0
  165. package/templates/skills/testing/api-app-testing.md +254 -0
  166. package/templates/skills/testing/performance-testing.md +275 -0
  167. package/templates/skills/testing/security-testing.md +348 -0
  168. package/templates/skills/utils/add-memory.md +295 -0
  169. package/templates/skills/utils/json-data-auditor.md +283 -0
  170. package/templates/skills/utils/pdf-creator-editor.md +342 -0
  171. package/templates/tools/format-markdown.sh +185 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,3887 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
+
33
+ // node_modules/.pnpm/tsup@8.5.1_postcss@8.5.6_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js
34
+ var init_cjs_shims = __esm({
35
+ "node_modules/.pnpm/tsup@8.5.1_postcss@8.5.6_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js"() {
36
+ "use strict";
37
+ }
38
+ });
39
+
40
+ // src/lib/utils/fs.ts
41
+ async function pathExists(filePath) {
42
+ return import_fs_extra.default.pathExists(filePath);
43
+ }
44
+ async function isDirectory(filePath) {
45
+ try {
46
+ const stat = await import_fs_extra.default.stat(filePath);
47
+ return stat.isDirectory();
48
+ } catch {
49
+ return false;
50
+ }
51
+ }
52
+ async function readJson(filePath) {
53
+ return import_fs_extra.default.readJson(filePath);
54
+ }
55
+ async function writeJson(filePath, data, options) {
56
+ await import_fs_extra.default.ensureDir(import_node_path.default.dirname(filePath));
57
+ await import_fs_extra.default.writeJson(filePath, data, { spaces: options?.spaces ?? 2 });
58
+ }
59
+ async function readFile(filePath) {
60
+ return import_fs_extra.default.readFile(filePath, "utf-8");
61
+ }
62
+ async function writeFile(filePath, content) {
63
+ await import_fs_extra.default.ensureDir(import_node_path.default.dirname(filePath));
64
+ await import_fs_extra.default.writeFile(filePath, content, "utf-8");
65
+ }
66
+ async function copy(src, dest, options) {
67
+ await import_fs_extra.default.ensureDir(import_node_path.default.dirname(dest));
68
+ await import_fs_extra.default.copy(src, dest, { overwrite: options?.overwrite ?? false });
69
+ }
70
+ async function ensureDir(dirPath) {
71
+ await import_fs_extra.default.ensureDir(dirPath);
72
+ }
73
+ async function listFiles(pattern, options) {
74
+ return (0, import_glob.glob)(pattern, {
75
+ cwd: options?.cwd,
76
+ ignore: options?.ignore,
77
+ nodir: true
78
+ });
79
+ }
80
+ async function listDirs(pattern, options) {
81
+ const matches = await (0, import_glob.glob)(pattern, {
82
+ cwd: options?.cwd
83
+ });
84
+ const dirs = [];
85
+ for (const match of matches) {
86
+ const fullPath = options?.cwd ? import_node_path.default.join(options.cwd, match) : match;
87
+ if (await isDirectory(fullPath)) {
88
+ dirs.push(match);
89
+ }
90
+ }
91
+ return dirs;
92
+ }
93
+ function joinPath(...segments) {
94
+ return import_node_path.default.join(...segments);
95
+ }
96
+ function dirname(filePath) {
97
+ return import_node_path.default.dirname(filePath);
98
+ }
99
+ async function backup(src, suffix = ".backup") {
100
+ const backupPath = `${src}${suffix}`;
101
+ await copy(src, backupPath, { overwrite: true });
102
+ return backupPath;
103
+ }
104
+ var import_node_path, import_fs_extra, import_glob;
105
+ var init_fs = __esm({
106
+ "src/lib/utils/fs.ts"() {
107
+ "use strict";
108
+ init_cjs_shims();
109
+ import_node_path = __toESM(require("path"), 1);
110
+ import_fs_extra = __toESM(require("fs-extra"), 1);
111
+ import_glob = require("glob");
112
+ }
113
+ });
114
+
115
+ // src/index.ts
116
+ var src_exports = {};
117
+ __export(src_exports, {
118
+ BUNDLES: () => BUNDLES,
119
+ DEPENDENCIES: () => DEPENDENCIES,
120
+ MCP_SERVERS: () => MCP_SERVERS,
121
+ PERMISSION_PRESETS: () => PERMISSION_PRESETS,
122
+ PLACEHOLDERS: () => PLACEHOLDERS,
123
+ buildTemplateContext: () => buildTemplateContext,
124
+ createDefaultConfig: () => createDefaultConfig,
125
+ detectProject: () => detectProject,
126
+ getAllBundles: () => getAllBundles,
127
+ getBundleById: () => getBundleById,
128
+ hasConfig: () => hasConfig,
129
+ installModules: () => installModules,
130
+ loadRegistry: () => loadRegistry,
131
+ mergeBundleSelection: () => mergeBundleSelection,
132
+ processTemplates: () => processTemplates,
133
+ readConfig: () => readConfig,
134
+ replacePlaceholders: () => replacePlaceholders,
135
+ resolveBundle: () => resolveBundle,
136
+ resolveBundles: () => resolveBundles,
137
+ resolveModules: () => resolveModules,
138
+ writeConfig: () => writeConfig
139
+ });
140
+ module.exports = __toCommonJS(src_exports);
141
+ init_cjs_shims();
142
+
143
+ // src/constants/bundles.ts
144
+ init_cjs_shims();
145
+ var BUNDLES = [
146
+ // ===================
147
+ // STACK BUNDLES
148
+ // ===================
149
+ {
150
+ id: "react-tanstack-stack",
151
+ name: "React + TanStack Stack",
152
+ description: "React with TanStack Router/Start for admin dashboards and SPAs",
153
+ category: "stack",
154
+ longDescription: "Complete stack for building React applications with TanStack Router and Start. Includes React component development, TanStack-specific patterns, and related testing/quality tools.",
155
+ techStack: ["React", "TanStack Start", "TanStack Router", "TanStack Query", "TypeScript"],
156
+ tags: ["react", "tanstack", "admin", "spa"],
157
+ complexity: "comprehensive",
158
+ responsibilities: [
159
+ "React component architecture and best practices",
160
+ "TanStack Router file-based routing patterns",
161
+ "Server state management with TanStack Query",
162
+ "Form handling with React Hook Form + Zod",
163
+ "UI components with Shadcn/Radix primitives"
164
+ ],
165
+ scope: "Full frontend stack for React SPAs and admin dashboards",
166
+ useCases: [
167
+ "Admin dashboards and internal tools",
168
+ "Complex single-page applications",
169
+ "Data-heavy applications with tables/forms",
170
+ "Projects using TanStack ecosystem"
171
+ ],
172
+ moduleDetails: {
173
+ agents: [
174
+ {
175
+ id: "react-senior-dev",
176
+ role: "React Architecture",
177
+ responsibilities: ["Component design", "State management", "Performance optimization"]
178
+ },
179
+ {
180
+ id: "tanstack-start-engineer",
181
+ role: "TanStack Specialist",
182
+ responsibilities: ["Router setup", "Query patterns", "SSR configuration"]
183
+ },
184
+ {
185
+ id: "ux-ui-designer",
186
+ role: "UI/UX Design",
187
+ responsibilities: ["Component styling", "Accessibility", "Design system"]
188
+ }
189
+ ],
190
+ skills: [
191
+ { id: "web-app-testing", purpose: "React Testing Library patterns" },
192
+ { id: "shadcn-specialist", purpose: "Shadcn UI component usage" },
193
+ { id: "accessibility-audit", purpose: "WCAG compliance" },
194
+ { id: "tanstack-query-patterns", purpose: "Query/mutation patterns" },
195
+ { id: "react-hook-form-patterns", purpose: "Form validation patterns" },
196
+ { id: "zustand-patterns", purpose: "Client state management" }
197
+ ],
198
+ commands: [],
199
+ docs: [{ id: "design-standards", topic: "UI/UX design standards" }]
200
+ },
201
+ modules: [
202
+ { id: "react-senior-dev", category: "agents" },
203
+ { id: "tanstack-start-engineer", category: "agents" },
204
+ { id: "ux-ui-designer", category: "agents" },
205
+ { id: "web-app-testing", category: "skills" },
206
+ { id: "shadcn-specialist", category: "skills" },
207
+ { id: "accessibility-audit", category: "skills" },
208
+ { id: "tanstack-query-patterns", category: "skills" },
209
+ { id: "react-hook-form-patterns", category: "skills" },
210
+ { id: "zustand-patterns", category: "skills", optional: true },
211
+ { id: "design-standards", category: "docs", requiredBy: ["ux-ui-designer"], optional: true }
212
+ ]
213
+ },
214
+ {
215
+ id: "astro-react-stack",
216
+ name: "Astro + React Stack",
217
+ description: "Astro with React islands for content-focused websites",
218
+ category: "stack",
219
+ longDescription: "Stack for building fast, content-focused websites with Astro and React components. Perfect for marketing sites, blogs, and documentation sites.",
220
+ techStack: ["Astro", "React", "Tailwind CSS", "MDX", "TypeScript"],
221
+ tags: ["astro", "react", "ssg", "content"],
222
+ complexity: "standard",
223
+ responsibilities: [
224
+ "Static site generation with Astro",
225
+ "Interactive React islands for dynamic content",
226
+ "SEO optimization and meta tags",
227
+ "Performance-first architecture",
228
+ "Content management with MDX"
229
+ ],
230
+ scope: "Content-focused websites with selective interactivity",
231
+ useCases: [
232
+ "Marketing and landing pages",
233
+ "Documentation sites",
234
+ "Blogs and content platforms",
235
+ "Portfolio websites"
236
+ ],
237
+ moduleDetails: {
238
+ agents: [
239
+ {
240
+ id: "astro-engineer",
241
+ role: "Astro Specialist",
242
+ responsibilities: ["Routing", "Islands architecture", "Build optimization"]
243
+ },
244
+ {
245
+ id: "react-senior-dev",
246
+ role: "React Components",
247
+ responsibilities: ["Interactive components", "Client hydration"]
248
+ },
249
+ {
250
+ id: "seo-ai-specialist",
251
+ role: "SEO Optimization",
252
+ responsibilities: ["Meta tags", "Structured data", "Performance"]
253
+ }
254
+ ],
255
+ skills: [
256
+ { id: "web-app-testing", purpose: "Component testing" },
257
+ { id: "vercel-specialist", purpose: "Deployment optimization" },
258
+ { id: "performance-audit", purpose: "Core Web Vitals" }
259
+ ],
260
+ commands: [],
261
+ docs: []
262
+ },
263
+ modules: [
264
+ { id: "astro-engineer", category: "agents" },
265
+ { id: "react-senior-dev", category: "agents" },
266
+ { id: "seo-ai-specialist", category: "agents" },
267
+ { id: "web-app-testing", category: "skills" },
268
+ { id: "vercel-specialist", category: "skills" },
269
+ { id: "performance-audit", category: "skills" }
270
+ ]
271
+ },
272
+ {
273
+ id: "nextjs-prisma-stack",
274
+ name: "Next.js + Prisma Stack",
275
+ description: "Full-stack Next.js with Prisma for modern web apps",
276
+ category: "stack",
277
+ longDescription: "Complete full-stack setup with Next.js App Router and Prisma ORM. Includes React components, Server Actions, and database patterns.",
278
+ techStack: ["Next.js", "React", "Prisma", "Tailwind CSS", "TypeScript"],
279
+ tags: ["nextjs", "prisma", "fullstack", "react"],
280
+ complexity: "comprehensive",
281
+ alternativeTo: ["react-tanstack-stack", "astro-react-stack"],
282
+ responsibilities: [
283
+ "Full-stack React with Next.js App Router",
284
+ "Database modeling with Prisma ORM",
285
+ "Server Actions and API routes",
286
+ "Authentication with NextAuth.js",
287
+ "Deployment on Vercel"
288
+ ],
289
+ scope: "Complete full-stack web application development",
290
+ useCases: [
291
+ "SaaS applications",
292
+ "E-commerce platforms",
293
+ "Full-stack web apps with auth",
294
+ "Projects needing SSR/SSG flexibility"
295
+ ],
296
+ moduleDetails: {
297
+ agents: [
298
+ {
299
+ id: "nextjs-engineer",
300
+ role: "Next.js Specialist",
301
+ responsibilities: ["App Router", "Server Actions", "Caching strategies"]
302
+ },
303
+ {
304
+ id: "react-senior-dev",
305
+ role: "React Components",
306
+ responsibilities: ["Client components", "State management"]
307
+ },
308
+ {
309
+ id: "prisma-engineer",
310
+ role: "Database",
311
+ responsibilities: ["Schema design", "Migrations", "Query optimization"]
312
+ },
313
+ {
314
+ id: "ux-ui-designer",
315
+ role: "UI/UX",
316
+ responsibilities: ["Design system", "Responsive design"]
317
+ }
318
+ ],
319
+ skills: [
320
+ { id: "web-app-testing", purpose: "Next.js testing patterns" },
321
+ { id: "shadcn-specialist", purpose: "UI components" },
322
+ { id: "vercel-specialist", purpose: "Deployment" },
323
+ { id: "tanstack-query-patterns", purpose: "Client data fetching" },
324
+ { id: "react-hook-form-patterns", purpose: "Form handling" },
325
+ { id: "nextauth-patterns", purpose: "Authentication" }
326
+ ],
327
+ commands: [],
328
+ docs: []
329
+ },
330
+ modules: [
331
+ { id: "nextjs-engineer", category: "agents" },
332
+ { id: "react-senior-dev", category: "agents" },
333
+ { id: "prisma-engineer", category: "agents" },
334
+ { id: "ux-ui-designer", category: "agents" },
335
+ { id: "web-app-testing", category: "skills" },
336
+ { id: "shadcn-specialist", category: "skills" },
337
+ { id: "vercel-specialist", category: "skills" },
338
+ { id: "tanstack-query-patterns", category: "skills" },
339
+ { id: "react-hook-form-patterns", category: "skills" },
340
+ { id: "nextauth-patterns", category: "skills", optional: true }
341
+ ]
342
+ },
343
+ {
344
+ id: "express-prisma-stack",
345
+ name: "Express + Prisma API Stack",
346
+ description: "Express backend with Prisma ORM",
347
+ category: "stack",
348
+ longDescription: "Backend stack using Express for APIs and Prisma for database access. Classic, well-documented stack for traditional REST APIs.",
349
+ techStack: ["Express.js", "Prisma", "PostgreSQL", "Zod", "TypeScript"],
350
+ tags: ["express", "prisma", "api", "backend"],
351
+ complexity: "standard",
352
+ alternativeTo: ["hono-drizzle-stack"],
353
+ responsibilities: [
354
+ "RESTful API design with Express",
355
+ "Database access with Prisma ORM",
356
+ "Request validation with Zod",
357
+ "Error handling and logging",
358
+ "Authentication middleware"
359
+ ],
360
+ scope: "Backend API development with traditional Express patterns",
361
+ useCases: [
362
+ "REST APIs for mobile apps",
363
+ "Backend services for SPAs",
364
+ "Microservices",
365
+ "Projects needing Express ecosystem"
366
+ ],
367
+ moduleDetails: {
368
+ agents: [
369
+ {
370
+ id: "express-engineer",
371
+ role: "Express Specialist",
372
+ responsibilities: ["Route design", "Middleware", "Error handling"]
373
+ },
374
+ {
375
+ id: "prisma-engineer",
376
+ role: "Database",
377
+ responsibilities: ["Schema", "Migrations", "Queries"]
378
+ },
379
+ {
380
+ id: "node-typescript-engineer",
381
+ role: "Node.js/TypeScript",
382
+ responsibilities: ["Type safety", "Build config", "Shared packages"]
383
+ }
384
+ ],
385
+ skills: [
386
+ { id: "api-app-testing", purpose: "API testing with supertest" },
387
+ { id: "error-handling-patterns", purpose: "Error middleware" },
388
+ { id: "security-testing", purpose: "Security best practices" }
389
+ ],
390
+ commands: [],
391
+ docs: [{ id: "architecture-patterns", topic: "API architecture patterns" }]
392
+ },
393
+ modules: [
394
+ { id: "express-engineer", category: "agents" },
395
+ { id: "prisma-engineer", category: "agents" },
396
+ { id: "node-typescript-engineer", category: "agents" },
397
+ { id: "api-app-testing", category: "skills" },
398
+ { id: "error-handling-patterns", category: "skills" },
399
+ { id: "security-testing", category: "skills" },
400
+ { id: "architecture-patterns", category: "docs", optional: true }
401
+ ]
402
+ },
403
+ {
404
+ id: "hono-drizzle-stack",
405
+ name: "Hono + Drizzle API Stack",
406
+ description: "Hono API framework with Drizzle ORM for type-safe backends",
407
+ category: "stack",
408
+ longDescription: "Complete backend stack using Hono for APIs and Drizzle for database access. Includes shared TypeScript packages, API testing, and quality tools.",
409
+ techStack: ["Hono", "Drizzle ORM", "PostgreSQL", "Zod", "TypeScript"],
410
+ tags: ["hono", "drizzle", "api", "backend"],
411
+ complexity: "standard",
412
+ alternativeTo: ["express-prisma-stack"],
413
+ responsibilities: [
414
+ "High-performance APIs with Hono",
415
+ "Type-safe database queries with Drizzle",
416
+ "Schema validation with Zod",
417
+ "Edge-ready deployment",
418
+ "Monorepo-friendly architecture"
419
+ ],
420
+ scope: "Modern, type-safe backend API development",
421
+ useCases: [
422
+ "Edge/serverless APIs",
423
+ "Type-safe monorepo backends",
424
+ "High-performance REST APIs",
425
+ "Projects prioritizing type safety"
426
+ ],
427
+ moduleDetails: {
428
+ agents: [
429
+ {
430
+ id: "hono-engineer",
431
+ role: "Hono Specialist",
432
+ responsibilities: ["Route handlers", "Middleware", "OpenAPI integration"]
433
+ },
434
+ {
435
+ id: "db-drizzle-engineer",
436
+ role: "Drizzle Database",
437
+ responsibilities: ["Schema design", "Migrations", "Type-safe queries"]
438
+ },
439
+ {
440
+ id: "node-typescript-engineer",
441
+ role: "TypeScript/Node",
442
+ responsibilities: ["Type inference", "Build setup", "Shared types"]
443
+ }
444
+ ],
445
+ skills: [
446
+ { id: "api-app-testing", purpose: "Hono testing patterns" },
447
+ { id: "error-handling-patterns", purpose: "Error middleware" },
448
+ { id: "security-testing", purpose: "Security validation" }
449
+ ],
450
+ commands: [],
451
+ docs: [{ id: "architecture-patterns", topic: "API architecture patterns" }]
452
+ },
453
+ modules: [
454
+ { id: "hono-engineer", category: "agents" },
455
+ { id: "db-drizzle-engineer", category: "agents" },
456
+ { id: "node-typescript-engineer", category: "agents" },
457
+ { id: "api-app-testing", category: "skills" },
458
+ { id: "error-handling-patterns", category: "skills" },
459
+ { id: "security-testing", category: "skills" },
460
+ { id: "architecture-patterns", category: "docs", optional: true }
461
+ ]
462
+ },
463
+ // ===================
464
+ // TESTING BUNDLES
465
+ // ===================
466
+ {
467
+ id: "testing-complete",
468
+ name: "Complete Testing Suite",
469
+ description: "All testing skills and QA tools for comprehensive test coverage",
470
+ category: "testing",
471
+ longDescription: "Everything you need for a robust testing strategy including TDD methodology, web testing, API testing, performance testing, and QA validation.",
472
+ techStack: ["Vitest", "Playwright", "Testing Library", "MSW"],
473
+ tags: ["testing", "tdd", "qa", "e2e"],
474
+ complexity: "comprehensive",
475
+ responsibilities: [
476
+ "TDD workflow enforcement (Red-Green-Refactor)",
477
+ "Unit, integration, and E2E testing patterns",
478
+ "API testing with mocking and fixtures",
479
+ "Performance testing and benchmarking",
480
+ "QA validation and acceptance criteria"
481
+ ],
482
+ scope: "Complete testing strategy from unit tests to E2E",
483
+ useCases: [
484
+ "Projects requiring 90%+ test coverage",
485
+ "TDD-first development workflow",
486
+ "API-heavy applications needing thorough testing",
487
+ "Projects with QA validation requirements"
488
+ ],
489
+ moduleDetails: {
490
+ agents: [
491
+ {
492
+ id: "qa-engineer",
493
+ role: "Quality Assurance",
494
+ responsibilities: [
495
+ "Test planning and strategy",
496
+ "Acceptance criteria validation",
497
+ "Bug triage and reporting"
498
+ ]
499
+ }
500
+ ],
501
+ skills: [
502
+ { id: "tdd-methodology", purpose: "TDD workflow and best practices" },
503
+ { id: "web-app-testing", purpose: "Frontend testing patterns" },
504
+ { id: "api-app-testing", purpose: "API and backend testing" },
505
+ { id: "performance-testing", purpose: "Performance benchmarks" },
506
+ { id: "qa-criteria-validator", purpose: "Acceptance validation" }
507
+ ],
508
+ commands: [{ id: "run-tests", usage: "/run-tests --coverage" }],
509
+ docs: [{ id: "testing-standards", topic: "Testing conventions and standards" }]
510
+ },
511
+ modules: [
512
+ { id: "qa-engineer", category: "agents" },
513
+ { id: "tdd-methodology", category: "skills" },
514
+ { id: "web-app-testing", category: "skills" },
515
+ { id: "api-app-testing", category: "skills" },
516
+ { id: "performance-testing", category: "skills" },
517
+ { id: "qa-criteria-validator", category: "skills" },
518
+ { id: "run-tests", category: "commands" },
519
+ // Doc required by QA agent and TDD skill
520
+ { id: "testing-standards", category: "docs", requiredBy: ["qa-engineer", "tdd-methodology"] }
521
+ ]
522
+ },
523
+ {
524
+ id: "testing-minimal",
525
+ name: "Minimal Testing",
526
+ description: "Essential testing tools for TDD workflow",
527
+ category: "testing",
528
+ longDescription: "Core testing tools for TDD development without the full QA suite.",
529
+ techStack: ["Vitest", "Testing Library"],
530
+ tags: ["testing", "tdd", "minimal"],
531
+ complexity: "minimal",
532
+ responsibilities: [
533
+ "Basic TDD workflow support",
534
+ "Unit and integration testing",
535
+ "Test execution and reporting"
536
+ ],
537
+ scope: "Essential testing for small to medium projects",
538
+ useCases: [
539
+ "Small projects with basic testing needs",
540
+ "Quick prototypes needing some test coverage",
541
+ "Projects where full QA suite is overkill"
542
+ ],
543
+ moduleDetails: {
544
+ agents: [],
545
+ skills: [
546
+ { id: "tdd-methodology", purpose: "TDD workflow basics" },
547
+ { id: "api-app-testing", purpose: "API testing patterns" }
548
+ ],
549
+ commands: [{ id: "run-tests", usage: "/run-tests" }],
550
+ docs: []
551
+ },
552
+ modules: [
553
+ { id: "tdd-methodology", category: "skills" },
554
+ { id: "api-app-testing", category: "skills" },
555
+ { id: "run-tests", category: "commands" }
556
+ ]
557
+ },
558
+ // ===================
559
+ // QUALITY BUNDLES
560
+ // ===================
561
+ {
562
+ id: "quality-complete",
563
+ name: "Complete Quality Suite",
564
+ description: "Full quality assurance with security, performance, and accessibility audits",
565
+ category: "quality",
566
+ longDescription: "Comprehensive quality assurance bundle including all audit types, code review, and debugging tools.",
567
+ tags: ["quality", "audit", "security", "performance"],
568
+ complexity: "comprehensive",
569
+ responsibilities: [
570
+ "Security vulnerability detection and prevention",
571
+ "Performance profiling and optimization guidance",
572
+ "Accessibility compliance (WCAG) validation",
573
+ "Code quality review and best practices",
574
+ "Bug investigation and debugging assistance"
575
+ ],
576
+ scope: "Complete quality assurance across security, performance, and accessibility",
577
+ useCases: [
578
+ "Enterprise applications with strict security requirements",
579
+ "Public-facing apps needing accessibility compliance",
580
+ "Performance-critical applications",
581
+ "Projects requiring comprehensive code reviews"
582
+ ],
583
+ moduleDetails: {
584
+ agents: [
585
+ {
586
+ id: "qa-engineer",
587
+ role: "Quality Assurance Lead",
588
+ responsibilities: [
589
+ "Test strategy and coverage",
590
+ "Acceptance criteria validation",
591
+ "Quality metrics tracking"
592
+ ]
593
+ },
594
+ {
595
+ id: "debugger",
596
+ role: "Debug Specialist",
597
+ responsibilities: ["Root cause analysis", "Bug reproduction", "Fix verification"]
598
+ }
599
+ ],
600
+ skills: [
601
+ { id: "security-audit", purpose: "OWASP vulnerability scanning" },
602
+ { id: "security-testing", purpose: "Security test patterns" },
603
+ { id: "performance-audit", purpose: "Performance bottleneck detection" },
604
+ { id: "performance-testing", purpose: "Load and stress testing" },
605
+ { id: "accessibility-audit", purpose: "WCAG compliance checking" },
606
+ { id: "qa-criteria-validator", purpose: "Acceptance criteria validation" }
607
+ ],
608
+ commands: [
609
+ { id: "quality-check", usage: "/quality-check" },
610
+ { id: "code-check", usage: "/code-check src/" },
611
+ { id: "review-code", usage: "/review-code --thorough" },
612
+ { id: "review-security", usage: "/review-security" },
613
+ { id: "review-performance", usage: "/review-performance" }
614
+ ],
615
+ docs: [
616
+ { id: "code-standards", topic: "Code quality standards" },
617
+ { id: "atomic-commits", topic: "Atomic commit practices" }
618
+ ]
619
+ },
620
+ modules: [
621
+ { id: "qa-engineer", category: "agents" },
622
+ { id: "debugger", category: "agents" },
623
+ { id: "security-audit", category: "skills" },
624
+ { id: "security-testing", category: "skills" },
625
+ { id: "performance-audit", category: "skills" },
626
+ { id: "performance-testing", category: "skills" },
627
+ { id: "accessibility-audit", category: "skills" },
628
+ { id: "qa-criteria-validator", category: "skills" },
629
+ { id: "quality-check", category: "commands" },
630
+ { id: "code-check", category: "commands" },
631
+ { id: "review-code", category: "commands" },
632
+ { id: "review-security", category: "commands" },
633
+ { id: "review-performance", category: "commands" },
634
+ // Docs required by agents
635
+ { id: "code-standards", category: "docs", requiredBy: ["qa-engineer"] },
636
+ { id: "atomic-commits", category: "docs", optional: true }
637
+ ]
638
+ },
639
+ {
640
+ id: "quality-minimal",
641
+ name: "Minimal Quality",
642
+ description: "Essential quality checks for everyday development",
643
+ category: "quality",
644
+ longDescription: "Core quality tools without the full audit suite.",
645
+ tags: ["quality", "minimal"],
646
+ complexity: "minimal",
647
+ responsibilities: [
648
+ "Basic code quality checks",
649
+ "Quick code reviews",
650
+ "Lint and format validation"
651
+ ],
652
+ scope: "Essential quality checks for day-to-day development",
653
+ useCases: [
654
+ "Small projects with basic quality needs",
655
+ "Quick PRs needing fast review",
656
+ "Projects where full audits are overkill"
657
+ ],
658
+ moduleDetails: {
659
+ agents: [],
660
+ skills: [],
661
+ commands: [
662
+ { id: "quality-check", usage: "/quality-check" },
663
+ { id: "code-check", usage: "/code-check" },
664
+ { id: "review-code", usage: "/review-code" }
665
+ ],
666
+ docs: []
667
+ },
668
+ modules: [
669
+ { id: "quality-check", category: "commands" },
670
+ { id: "code-check", category: "commands" },
671
+ { id: "review-code", category: "commands" }
672
+ ]
673
+ },
674
+ // ===================
675
+ // DATABASE BUNDLES
676
+ // ===================
677
+ {
678
+ id: "drizzle-database",
679
+ name: "Drizzle Database",
680
+ description: "Drizzle ORM with type-safe database patterns",
681
+ category: "database",
682
+ longDescription: "Database development with Drizzle ORM including schema design, migrations, and data validation.",
683
+ techStack: ["Drizzle ORM", "PostgreSQL", "SQLite", "Zod"],
684
+ tags: ["database", "drizzle", "orm"],
685
+ alternativeTo: ["prisma-database", "mongoose-database"],
686
+ modules: [
687
+ { id: "db-drizzle-engineer", category: "agents" },
688
+ { id: "json-data-auditor", category: "skills" }
689
+ ]
690
+ },
691
+ {
692
+ id: "prisma-database",
693
+ name: "Prisma Database",
694
+ description: "Prisma ORM with type-safe database patterns",
695
+ category: "database",
696
+ longDescription: "Database development with Prisma ORM including schema design, migrations, and data validation.",
697
+ techStack: ["Prisma", "PostgreSQL", "MySQL", "SQLite", "MongoDB"],
698
+ tags: ["database", "prisma", "orm"],
699
+ alternativeTo: ["drizzle-database", "mongoose-database"],
700
+ modules: [
701
+ { id: "prisma-engineer", category: "agents" },
702
+ { id: "json-data-auditor", category: "skills" }
703
+ ]
704
+ },
705
+ {
706
+ id: "mongoose-database",
707
+ name: "MongoDB + Mongoose",
708
+ description: "MongoDB with Mongoose ODM",
709
+ category: "database",
710
+ longDescription: "MongoDB development with Mongoose ODM including document schemas and aggregation pipelines.",
711
+ techStack: ["Mongoose", "MongoDB", "TypeScript"],
712
+ tags: ["database", "mongodb", "mongoose", "nosql"],
713
+ alternativeTo: ["drizzle-database", "prisma-database"],
714
+ modules: [
715
+ { id: "mongoose-engineer", category: "agents" },
716
+ { id: "json-data-auditor", category: "skills" }
717
+ ]
718
+ },
719
+ // ===================
720
+ // API BUNDLES
721
+ // ===================
722
+ {
723
+ id: "hono-api",
724
+ name: "Hono API",
725
+ description: "Hono framework for high-performance APIs",
726
+ category: "api",
727
+ longDescription: "API development with Hono framework including middleware, validation, and error handling.",
728
+ techStack: ["Hono", "Zod", "TypeScript"],
729
+ tags: ["api", "hono", "backend"],
730
+ alternativeTo: ["express-api", "fastify-api", "nestjs-api"],
731
+ modules: [
732
+ { id: "hono-engineer", category: "agents" },
733
+ { id: "api-app-testing", category: "skills" },
734
+ { id: "error-handling-patterns", category: "skills" }
735
+ ]
736
+ },
737
+ {
738
+ id: "express-api",
739
+ name: "Express API",
740
+ description: "Express.js framework for REST APIs",
741
+ category: "api",
742
+ longDescription: "API development with Express.js including middleware chains, validation, and error handling.",
743
+ techStack: ["Express.js", "Zod", "TypeScript", "Passport.js"],
744
+ tags: ["api", "express", "backend"],
745
+ alternativeTo: ["hono-api", "fastify-api", "nestjs-api"],
746
+ modules: [
747
+ { id: "express-engineer", category: "agents" },
748
+ { id: "api-app-testing", category: "skills" },
749
+ { id: "error-handling-patterns", category: "skills" }
750
+ ]
751
+ },
752
+ {
753
+ id: "fastify-api",
754
+ name: "Fastify API",
755
+ description: "Fastify framework for high-performance APIs",
756
+ category: "api",
757
+ longDescription: "High-performance API development with Fastify plugin architecture and schema validation.",
758
+ techStack: ["Fastify", "TypeBox", "TypeScript", "Pino"],
759
+ tags: ["api", "fastify", "backend", "performance"],
760
+ alternativeTo: ["hono-api", "express-api", "nestjs-api"],
761
+ modules: [
762
+ { id: "fastify-engineer", category: "agents" },
763
+ { id: "api-app-testing", category: "skills" },
764
+ { id: "error-handling-patterns", category: "skills" }
765
+ ]
766
+ },
767
+ {
768
+ id: "nestjs-api",
769
+ name: "NestJS API",
770
+ description: "NestJS framework for enterprise APIs",
771
+ category: "api",
772
+ longDescription: "Enterprise API development with NestJS dependency injection and modular architecture.",
773
+ techStack: ["NestJS", "TypeScript", "class-validator", "TypeORM"],
774
+ tags: ["api", "nestjs", "backend", "enterprise"],
775
+ alternativeTo: ["hono-api", "express-api", "fastify-api"],
776
+ modules: [
777
+ { id: "nestjs-engineer", category: "agents" },
778
+ { id: "api-app-testing", category: "skills" },
779
+ { id: "error-handling-patterns", category: "skills" }
780
+ ]
781
+ },
782
+ // ===================
783
+ // FRONTEND BUNDLES
784
+ // ===================
785
+ {
786
+ id: "react-ui",
787
+ name: "React UI Development",
788
+ description: "React component development with Shadcn UI",
789
+ category: "frontend",
790
+ longDescription: "React component development bundle with Shadcn UI, accessibility, and design system tools.",
791
+ techStack: ["React", "Shadcn UI", "Tailwind CSS", "Radix UI"],
792
+ tags: ["react", "ui", "components"],
793
+ modules: [
794
+ { id: "react-senior-dev", category: "agents" },
795
+ { id: "ux-ui-designer", category: "agents" },
796
+ { id: "shadcn-specialist", category: "skills" },
797
+ { id: "brand-guidelines", category: "skills" },
798
+ { id: "accessibility-audit", category: "skills" }
799
+ ]
800
+ },
801
+ {
802
+ id: "react-forms",
803
+ name: "React Forms",
804
+ description: "React Hook Form with Zod validation",
805
+ category: "frontend",
806
+ longDescription: "Form handling patterns with React Hook Form and Zod validation. Includes Shadcn form integration.",
807
+ techStack: ["React Hook Form", "Zod", "React", "TypeScript"],
808
+ tags: ["react", "forms", "validation"],
809
+ modules: [
810
+ { id: "react-senior-dev", category: "agents" },
811
+ { id: "react-hook-form-patterns", category: "skills" },
812
+ { id: "shadcn-specialist", category: "skills" }
813
+ ]
814
+ },
815
+ {
816
+ id: "react-state-zustand",
817
+ name: "React State (Zustand)",
818
+ description: "Zustand for lightweight state management",
819
+ category: "frontend",
820
+ longDescription: "State management with Zustand including slices, persist middleware, and TanStack Query integration.",
821
+ techStack: ["Zustand", "TanStack Query", "React", "TypeScript"],
822
+ tags: ["react", "state", "zustand"],
823
+ alternativeTo: ["react-state-redux"],
824
+ modules: [
825
+ { id: "react-senior-dev", category: "agents" },
826
+ { id: "zustand-patterns", category: "skills" },
827
+ { id: "tanstack-query-patterns", category: "skills" }
828
+ ]
829
+ },
830
+ {
831
+ id: "react-state-redux",
832
+ name: "React State (Redux)",
833
+ description: "Redux Toolkit for complex state management",
834
+ category: "frontend",
835
+ longDescription: "State management with Redux Toolkit including RTK Query, async thunks, and enterprise patterns.",
836
+ techStack: ["Redux Toolkit", "RTK Query", "React", "TypeScript"],
837
+ tags: ["react", "state", "redux"],
838
+ alternativeTo: ["react-state-zustand"],
839
+ modules: [
840
+ { id: "react-senior-dev", category: "agents" },
841
+ { id: "redux-toolkit-patterns", category: "skills" },
842
+ { id: "tanstack-query-patterns", category: "skills", optional: true }
843
+ ]
844
+ },
845
+ {
846
+ id: "nextjs-auth",
847
+ name: "Next.js Authentication",
848
+ description: "NextAuth.js authentication for Next.js apps",
849
+ category: "frontend",
850
+ longDescription: "Authentication patterns with NextAuth.js including OAuth providers, credentials, sessions, and RBAC.",
851
+ techStack: ["NextAuth.js", "Auth.js", "Next.js", "Prisma"],
852
+ tags: ["nextjs", "auth", "oauth"],
853
+ modules: [
854
+ { id: "nextjs-engineer", category: "agents" },
855
+ { id: "nextauth-patterns", category: "skills" },
856
+ { id: "security-testing", category: "skills" }
857
+ ]
858
+ },
859
+ {
860
+ id: "nextjs-i18n",
861
+ name: "Next.js Internationalization",
862
+ description: "Multi-language support for Next.js apps",
863
+ category: "frontend",
864
+ longDescription: "Internationalization with next-intl including locale routing, translations, and formatting.",
865
+ techStack: ["next-intl", "Next.js", "React", "TypeScript"],
866
+ tags: ["nextjs", "i18n", "internationalization"],
867
+ modules: [
868
+ { id: "nextjs-engineer", category: "agents" },
869
+ { id: "i18n-specialist", category: "agents", optional: true },
870
+ { id: "i18n-patterns", category: "skills" }
871
+ ]
872
+ },
873
+ // ===================
874
+ // WORKFLOW BUNDLES
875
+ // ===================
876
+ {
877
+ id: "planning-complete",
878
+ name: "Complete Planning Workflow",
879
+ description: "Full planning workflow with PDR, tech analysis, and task tracking",
880
+ category: "workflow",
881
+ longDescription: "Complete planning workflow bundle including product definition, technical analysis, task breakdown, and sync to issue trackers.",
882
+ tags: ["planning", "workflow", "pdr"],
883
+ complexity: "comprehensive",
884
+ responsibilities: [
885
+ "Feature planning from requirements to implementation tasks",
886
+ "Technical analysis and architecture decision documentation",
887
+ "Task breakdown with atomic task methodology",
888
+ "Integration with issue trackers (GitHub, Linear)"
889
+ ],
890
+ scope: "End-to-end planning workflow for features, refactors, and epics",
891
+ useCases: [
892
+ "Starting a new feature from scratch",
893
+ "Planning a major refactor or migration",
894
+ "Breaking down epics into manageable tasks",
895
+ "Documenting technical decisions (ADRs)"
896
+ ],
897
+ moduleDetails: {
898
+ agents: [
899
+ {
900
+ id: "product-functional",
901
+ role: "Product Requirements",
902
+ responsibilities: [
903
+ "Create PDR documents",
904
+ "Define acceptance criteria",
905
+ "User story mapping"
906
+ ]
907
+ },
908
+ {
909
+ id: "product-technical",
910
+ role: "Technical Analysis",
911
+ responsibilities: ["Architecture decisions", "Tech stack evaluation", "Risk assessment"]
912
+ },
913
+ {
914
+ id: "tech-lead",
915
+ role: "Coordination & Task Breakdown",
916
+ responsibilities: ["Task atomization", "Workflow selection", "Team coordination"]
917
+ }
918
+ ],
919
+ skills: [],
920
+ commands: [
921
+ { id: "start-feature-plan", usage: '/start-feature-plan "User authentication"' },
922
+ { id: "start-refactor-plan", usage: '/start-refactor-plan "Database optimization"' },
923
+ { id: "sync-planning", usage: "/sync-planning" }
924
+ ],
925
+ docs: [
926
+ { id: "decision-tree", topic: "Workflow selection guide" },
927
+ { id: "phase-1-planning", topic: "Planning phase methodology" },
928
+ { id: "phase-2-implementation", topic: "Implementation phase guide" },
929
+ { id: "phase-3-validation", topic: "Validation and QA phase" },
930
+ { id: "phase-4-finalization", topic: "Closing and documentation" },
931
+ { id: "pdr-template", topic: "Product Definition Record template" },
932
+ { id: "tech-analysis-template", topic: "Technical analysis template" },
933
+ { id: "todos-template", topic: "Task tracking template" }
934
+ ]
935
+ },
936
+ modules: [
937
+ { id: "product-functional", category: "agents" },
938
+ { id: "product-technical", category: "agents" },
939
+ { id: "tech-lead", category: "agents" },
940
+ { id: "start-feature-plan", category: "commands" },
941
+ { id: "start-refactor-plan", category: "commands" },
942
+ { id: "sync-planning", category: "commands" },
943
+ // Required docs - needed for agents to work properly
944
+ { id: "decision-tree", category: "docs", requiredBy: ["tech-lead"] },
945
+ {
946
+ id: "phase-1-planning",
947
+ category: "docs",
948
+ requiredBy: ["product-functional", "product-technical"]
949
+ },
950
+ { id: "phase-2-implementation", category: "docs", requiredBy: ["tech-lead"] },
951
+ { id: "phase-3-validation", category: "docs" },
952
+ { id: "phase-4-finalization", category: "docs" },
953
+ { id: "pdr-template", category: "docs", requiredBy: ["product-functional"] },
954
+ { id: "tech-analysis-template", category: "docs", requiredBy: ["product-technical"] },
955
+ { id: "todos-template", category: "docs", requiredBy: ["tech-lead"] }
956
+ ]
957
+ },
958
+ {
959
+ id: "documentation-complete",
960
+ name: "Complete Documentation",
961
+ description: "All documentation standards, templates, and writing tools",
962
+ category: "workflow",
963
+ longDescription: "Everything for comprehensive documentation including standards, templates, diagrams, and writing guidelines.",
964
+ tags: ["documentation", "writing", "standards"],
965
+ complexity: "standard",
966
+ responsibilities: [
967
+ "Technical documentation writing",
968
+ "API documentation generation",
969
+ "Architecture diagram creation",
970
+ "Markdown formatting and standards",
971
+ "Glossary and terminology management"
972
+ ],
973
+ scope: "Complete documentation workflow for technical projects",
974
+ useCases: [
975
+ "Creating and maintaining project documentation",
976
+ "Writing API and SDK documentation",
977
+ "Creating architecture diagrams",
978
+ "Standardizing documentation across team"
979
+ ],
980
+ moduleDetails: {
981
+ agents: [
982
+ {
983
+ id: "tech-writer",
984
+ role: "Technical Writer",
985
+ responsibilities: ["Documentation structure", "Content writing", "Style consistency"]
986
+ }
987
+ ],
988
+ skills: [
989
+ { id: "documentation-writer", purpose: "Documentation best practices" },
990
+ { id: "mermaid-diagram-specialist", purpose: "Diagram creation" }
991
+ ],
992
+ commands: [
993
+ { id: "update-docs", usage: "/update-docs" },
994
+ { id: "markdown-format", usage: "/markdown-format" }
995
+ ],
996
+ docs: [
997
+ { id: "documentation-standards", topic: "Documentation conventions" },
998
+ { id: "workflow-diagrams", topic: "Diagram templates" },
999
+ { id: "glossary", topic: "Project terminology" }
1000
+ ]
1001
+ },
1002
+ modules: [
1003
+ { id: "tech-writer", category: "agents" },
1004
+ { id: "documentation-writer", category: "skills" },
1005
+ { id: "mermaid-diagram-specialist", category: "skills" },
1006
+ { id: "update-docs", category: "commands" },
1007
+ { id: "markdown-format", category: "commands" },
1008
+ { id: "documentation-standards", category: "docs", requiredBy: ["tech-writer"] },
1009
+ { id: "workflow-diagrams", category: "docs", optional: true },
1010
+ { id: "glossary", category: "docs", optional: true }
1011
+ ]
1012
+ },
1013
+ {
1014
+ id: "git-workflow",
1015
+ name: "Git Workflow",
1016
+ description: "Git commit conventions and atomic commit practices",
1017
+ category: "workflow",
1018
+ longDescription: "Git workflow tools including conventional commits and atomic commit helpers.",
1019
+ tags: ["git", "commits", "workflow"],
1020
+ complexity: "minimal",
1021
+ responsibilities: [
1022
+ "Conventional commit message formatting",
1023
+ "Atomic commit enforcement",
1024
+ "Commit message generation"
1025
+ ],
1026
+ scope: "Git commit workflow and conventions",
1027
+ useCases: [
1028
+ "Enforcing commit message standards",
1029
+ "Generating semantic commit messages",
1030
+ "Following atomic commit practices"
1031
+ ],
1032
+ moduleDetails: {
1033
+ agents: [],
1034
+ skills: [{ id: "git-commit-helper", purpose: "Commit message patterns" }],
1035
+ commands: [{ id: "commit", usage: "/commit" }],
1036
+ docs: [{ id: "atomic-commits", topic: "Atomic commit guidelines" }]
1037
+ },
1038
+ modules: [
1039
+ { id: "git-commit-helper", category: "skills" },
1040
+ { id: "commit", category: "commands" },
1041
+ { id: "atomic-commits", category: "docs", optional: true }
1042
+ ]
1043
+ },
1044
+ {
1045
+ id: "cicd-github-actions",
1046
+ name: "GitHub Actions CI/CD",
1047
+ description: "GitHub Actions workflows for CI/CD automation",
1048
+ category: "workflow",
1049
+ longDescription: "Complete CI/CD setup with GitHub Actions including testing, quality checks, security scanning, and deployment workflows.",
1050
+ techStack: ["GitHub Actions", "Node.js", "PNPM"],
1051
+ tags: ["cicd", "github", "automation", "devops"],
1052
+ complexity: "standard",
1053
+ responsibilities: [
1054
+ "Continuous Integration workflows",
1055
+ "Automated testing on PRs",
1056
+ "Code quality checks",
1057
+ "Security scanning",
1058
+ "Deployment automation"
1059
+ ],
1060
+ scope: "CI/CD pipeline automation with GitHub Actions",
1061
+ useCases: [
1062
+ "Automating test runs on PRs",
1063
+ "Automated deployments to staging/production",
1064
+ "Code quality gates",
1065
+ "Security vulnerability scanning"
1066
+ ],
1067
+ moduleDetails: {
1068
+ agents: [],
1069
+ skills: [{ id: "github-actions-specialist", purpose: "GitHub Actions workflow patterns" }],
1070
+ commands: [],
1071
+ docs: [{ id: "cicd-workflows", topic: "CI/CD workflow documentation" }]
1072
+ },
1073
+ modules: [
1074
+ { id: "github-actions-specialist", category: "skills", optional: true },
1075
+ { id: "cicd-workflows", category: "docs", optional: true }
1076
+ ]
1077
+ }
1078
+ ];
1079
+ function getAllBundles() {
1080
+ return BUNDLES;
1081
+ }
1082
+ function getBundleById(id) {
1083
+ return BUNDLES.find((b) => b.id === id);
1084
+ }
1085
+
1086
+ // src/constants/mcp-servers.ts
1087
+ init_cjs_shims();
1088
+ var MCP_SERVERS = [
1089
+ // ============================================
1090
+ // DOCUMENTATION
1091
+ // ============================================
1092
+ {
1093
+ id: "context7",
1094
+ name: "Context7",
1095
+ description: "Documentation lookup for libraries and frameworks",
1096
+ package: "@anthropic/context7-mcp",
1097
+ category: "documentation",
1098
+ requiresConfig: false
1099
+ },
1100
+ // ============================================
1101
+ // TESTING & BROWSER AUTOMATION
1102
+ // ============================================
1103
+ {
1104
+ id: "chrome-devtools",
1105
+ name: "Chrome DevTools",
1106
+ description: "Browser automation, debugging, and performance profiling via Chrome DevTools Protocol",
1107
+ package: "@anthropic/chrome-devtools-mcp",
1108
+ category: "testing",
1109
+ requiresConfig: false,
1110
+ installInstructions: "Requires Chrome/Chromium browser installed on the system."
1111
+ },
1112
+ {
1113
+ id: "playwright",
1114
+ name: "Playwright",
1115
+ description: "Cross-browser end-to-end testing and automation",
1116
+ package: "@anthropic/playwright-mcp",
1117
+ category: "testing",
1118
+ requiresConfig: false,
1119
+ installInstructions: "Run `npx playwright install` after setup to install browsers."
1120
+ },
1121
+ {
1122
+ id: "puppeteer",
1123
+ name: "Puppeteer",
1124
+ description: "Headless Chrome automation for testing and scraping",
1125
+ package: "@anthropic/puppeteer-mcp",
1126
+ category: "testing",
1127
+ requiresConfig: false
1128
+ },
1129
+ // ============================================
1130
+ // VERSION CONTROL
1131
+ // ============================================
1132
+ {
1133
+ id: "github",
1134
+ name: "GitHub",
1135
+ description: "GitHub API integration (issues, PRs, repos)",
1136
+ package: "@modelcontextprotocol/server-github",
1137
+ category: "version-control",
1138
+ requiresConfig: true,
1139
+ configFields: [
1140
+ {
1141
+ name: "token",
1142
+ type: "string",
1143
+ required: false,
1144
+ description: "GitHub Personal Access Token",
1145
+ envVar: "GITHUB_TOKEN"
1146
+ }
1147
+ ],
1148
+ installInstructions: "Create a Personal Access Token at https://github.com/settings/tokens with repo, issues, and pull_request scopes."
1149
+ },
1150
+ {
1151
+ id: "gitlab",
1152
+ name: "GitLab",
1153
+ description: "GitLab API integration (issues, MRs, repos)",
1154
+ package: "@anthropic/gitlab-mcp",
1155
+ category: "version-control",
1156
+ requiresConfig: true,
1157
+ configFields: [
1158
+ {
1159
+ name: "token",
1160
+ type: "string",
1161
+ required: false,
1162
+ description: "GitLab Personal Access Token",
1163
+ envVar: "GITLAB_TOKEN"
1164
+ },
1165
+ {
1166
+ name: "baseUrl",
1167
+ type: "string",
1168
+ required: false,
1169
+ description: "GitLab instance URL (default: https://gitlab.com)",
1170
+ default: "https://gitlab.com"
1171
+ }
1172
+ ],
1173
+ installInstructions: "Create a Personal Access Token at GitLab Settings > Access Tokens with api scope."
1174
+ },
1175
+ // ============================================
1176
+ // DATABASES
1177
+ // ============================================
1178
+ {
1179
+ id: "postgres",
1180
+ name: "PostgreSQL",
1181
+ description: "Direct PostgreSQL database access",
1182
+ package: "@modelcontextprotocol/server-postgres",
1183
+ category: "database",
1184
+ requiresConfig: true,
1185
+ configFields: [
1186
+ {
1187
+ name: "connectionString",
1188
+ type: "string",
1189
+ required: false,
1190
+ description: "PostgreSQL connection string",
1191
+ envVar: "DATABASE_URL"
1192
+ }
1193
+ ],
1194
+ installInstructions: "Connection string format: postgresql://user:password@host:port/database"
1195
+ },
1196
+ {
1197
+ id: "neon",
1198
+ name: "Neon",
1199
+ description: "Neon serverless PostgreSQL",
1200
+ package: "@neondatabase/mcp-server-neon",
1201
+ category: "database",
1202
+ requiresConfig: true,
1203
+ configFields: [
1204
+ {
1205
+ name: "apiKey",
1206
+ type: "string",
1207
+ required: false,
1208
+ description: "Neon API Key",
1209
+ envVar: "NEON_API_KEY"
1210
+ }
1211
+ ],
1212
+ installInstructions: "Get your API key from https://console.neon.tech/app/settings/api-keys"
1213
+ },
1214
+ {
1215
+ id: "mongodb",
1216
+ name: "MongoDB",
1217
+ description: "MongoDB document database access",
1218
+ package: "@anthropic/mongodb-mcp",
1219
+ category: "database",
1220
+ requiresConfig: true,
1221
+ configFields: [
1222
+ {
1223
+ name: "connectionString",
1224
+ type: "string",
1225
+ required: false,
1226
+ description: "MongoDB connection string",
1227
+ envVar: "MONGODB_URI"
1228
+ }
1229
+ ],
1230
+ installInstructions: "Connection string format: mongodb://user:password@host:port/database or mongodb+srv://..."
1231
+ },
1232
+ {
1233
+ id: "mysql",
1234
+ name: "MySQL",
1235
+ description: "MySQL/MariaDB database access",
1236
+ package: "@anthropic/mysql-mcp",
1237
+ category: "database",
1238
+ requiresConfig: true,
1239
+ configFields: [
1240
+ {
1241
+ name: "connectionString",
1242
+ type: "string",
1243
+ required: false,
1244
+ description: "MySQL connection string",
1245
+ envVar: "MYSQL_URL"
1246
+ }
1247
+ ],
1248
+ installInstructions: "Connection string format: mysql://user:password@host:port/database"
1249
+ },
1250
+ {
1251
+ id: "sqlite",
1252
+ name: "SQLite",
1253
+ description: "SQLite local database access",
1254
+ package: "@modelcontextprotocol/server-sqlite",
1255
+ category: "database",
1256
+ requiresConfig: true,
1257
+ configFields: [
1258
+ {
1259
+ name: "dbPath",
1260
+ type: "string",
1261
+ required: false,
1262
+ description: "Path to SQLite database file",
1263
+ default: "./data.db"
1264
+ }
1265
+ ]
1266
+ },
1267
+ {
1268
+ id: "supabase",
1269
+ name: "Supabase",
1270
+ description: "Supabase backend-as-a-service (DB, Auth, Storage)",
1271
+ package: "@supabase/mcp-server",
1272
+ category: "database",
1273
+ requiresConfig: true,
1274
+ configFields: [
1275
+ {
1276
+ name: "url",
1277
+ type: "string",
1278
+ required: false,
1279
+ description: "Supabase project URL",
1280
+ envVar: "SUPABASE_URL"
1281
+ },
1282
+ {
1283
+ name: "anonKey",
1284
+ type: "string",
1285
+ required: false,
1286
+ description: "Supabase anon/public key",
1287
+ envVar: "SUPABASE_ANON_KEY"
1288
+ }
1289
+ ],
1290
+ installInstructions: "Find your project URL and anon key in Supabase Dashboard > Settings > API"
1291
+ },
1292
+ // ============================================
1293
+ // CACHE & KEY-VALUE STORES
1294
+ // ============================================
1295
+ {
1296
+ id: "redis",
1297
+ name: "Redis",
1298
+ description: "Redis cache and key-value store",
1299
+ package: "@anthropic/redis-mcp",
1300
+ category: "cache",
1301
+ requiresConfig: true,
1302
+ configFields: [
1303
+ {
1304
+ name: "url",
1305
+ type: "string",
1306
+ required: false,
1307
+ description: "Redis connection URL",
1308
+ envVar: "REDIS_URL",
1309
+ default: "redis://localhost:6379"
1310
+ }
1311
+ ],
1312
+ installInstructions: "Connection URL format: redis://[[user]:password@]host[:port][/db]"
1313
+ },
1314
+ {
1315
+ id: "upstash",
1316
+ name: "Upstash",
1317
+ description: "Upstash serverless Redis and Kafka",
1318
+ package: "@upstash/mcp-server",
1319
+ category: "cache",
1320
+ requiresConfig: true,
1321
+ configFields: [
1322
+ {
1323
+ name: "url",
1324
+ type: "string",
1325
+ required: false,
1326
+ description: "Upstash Redis REST URL",
1327
+ envVar: "UPSTASH_REDIS_REST_URL"
1328
+ },
1329
+ {
1330
+ name: "token",
1331
+ type: "string",
1332
+ required: false,
1333
+ description: "Upstash Redis REST token",
1334
+ envVar: "UPSTASH_REDIS_REST_TOKEN"
1335
+ }
1336
+ ],
1337
+ installInstructions: "Get credentials from https://console.upstash.com"
1338
+ },
1339
+ // ============================================
1340
+ // DEPLOYMENT & INFRASTRUCTURE
1341
+ // ============================================
1342
+ {
1343
+ id: "vercel",
1344
+ name: "Vercel",
1345
+ description: "Vercel deployment and project management",
1346
+ package: "@vercel/mcp",
1347
+ category: "deployment",
1348
+ requiresConfig: true,
1349
+ configFields: [
1350
+ {
1351
+ name: "token",
1352
+ type: "string",
1353
+ required: false,
1354
+ description: "Vercel Access Token",
1355
+ envVar: "VERCEL_TOKEN"
1356
+ }
1357
+ ],
1358
+ installInstructions: "Create an access token at https://vercel.com/account/tokens"
1359
+ },
1360
+ {
1361
+ id: "netlify",
1362
+ name: "Netlify",
1363
+ description: "Netlify deployment and site management",
1364
+ package: "@anthropic/netlify-mcp",
1365
+ category: "deployment",
1366
+ requiresConfig: true,
1367
+ configFields: [
1368
+ {
1369
+ name: "token",
1370
+ type: "string",
1371
+ required: false,
1372
+ description: "Netlify Personal Access Token",
1373
+ envVar: "NETLIFY_TOKEN"
1374
+ }
1375
+ ],
1376
+ installInstructions: "Create a token at https://app.netlify.com/user/applications#personal-access-tokens"
1377
+ },
1378
+ {
1379
+ id: "cloudflare",
1380
+ name: "Cloudflare",
1381
+ description: "Cloudflare Workers, Pages, and DNS management",
1382
+ package: "@cloudflare/mcp-server",
1383
+ category: "deployment",
1384
+ requiresConfig: true,
1385
+ configFields: [
1386
+ {
1387
+ name: "apiToken",
1388
+ type: "string",
1389
+ required: false,
1390
+ description: "Cloudflare API Token",
1391
+ envVar: "CLOUDFLARE_API_TOKEN"
1392
+ },
1393
+ {
1394
+ name: "accountId",
1395
+ type: "string",
1396
+ required: false,
1397
+ description: "Cloudflare Account ID",
1398
+ envVar: "CLOUDFLARE_ACCOUNT_ID"
1399
+ }
1400
+ ],
1401
+ installInstructions: "Create an API token at https://dash.cloudflare.com/profile/api-tokens"
1402
+ },
1403
+ {
1404
+ id: "aws",
1405
+ name: "AWS",
1406
+ description: "Amazon Web Services integration",
1407
+ package: "@anthropic/aws-mcp",
1408
+ category: "infrastructure",
1409
+ requiresConfig: true,
1410
+ configFields: [
1411
+ {
1412
+ name: "accessKeyId",
1413
+ type: "string",
1414
+ required: false,
1415
+ description: "AWS Access Key ID",
1416
+ envVar: "AWS_ACCESS_KEY_ID"
1417
+ },
1418
+ {
1419
+ name: "secretAccessKey",
1420
+ type: "string",
1421
+ required: false,
1422
+ description: "AWS Secret Access Key",
1423
+ envVar: "AWS_SECRET_ACCESS_KEY"
1424
+ },
1425
+ {
1426
+ name: "region",
1427
+ type: "string",
1428
+ required: false,
1429
+ description: "AWS Region",
1430
+ envVar: "AWS_REGION",
1431
+ default: "us-east-1"
1432
+ }
1433
+ ],
1434
+ installInstructions: "Create credentials in AWS IAM Console with appropriate permissions."
1435
+ },
1436
+ {
1437
+ id: "docker",
1438
+ name: "Docker",
1439
+ description: "Docker container management",
1440
+ package: "@anthropic/docker-mcp",
1441
+ category: "infrastructure",
1442
+ requiresConfig: false,
1443
+ installInstructions: "Requires Docker Desktop or Docker Engine installed."
1444
+ },
1445
+ {
1446
+ id: "kubernetes",
1447
+ name: "Kubernetes",
1448
+ description: "Kubernetes cluster management",
1449
+ package: "@anthropic/kubernetes-mcp",
1450
+ category: "infrastructure",
1451
+ requiresConfig: true,
1452
+ configFields: [
1453
+ {
1454
+ name: "kubeconfig",
1455
+ type: "string",
1456
+ required: false,
1457
+ description: "Path to kubeconfig file",
1458
+ default: "~/.kube/config"
1459
+ },
1460
+ {
1461
+ name: "context",
1462
+ type: "string",
1463
+ required: false,
1464
+ description: "Kubernetes context to use"
1465
+ }
1466
+ ],
1467
+ installInstructions: "Requires kubectl installed and configured."
1468
+ },
1469
+ {
1470
+ id: "filesystem",
1471
+ name: "Filesystem",
1472
+ description: "Enhanced filesystem operations",
1473
+ package: "@modelcontextprotocol/server-filesystem",
1474
+ category: "infrastructure",
1475
+ requiresConfig: false
1476
+ },
1477
+ // ============================================
1478
+ // PROJECT MANAGEMENT
1479
+ // ============================================
1480
+ {
1481
+ id: "linear",
1482
+ name: "Linear",
1483
+ description: "Linear project management integration",
1484
+ package: "@anthropic/linear-mcp",
1485
+ category: "project-mgmt",
1486
+ requiresConfig: true,
1487
+ configFields: [
1488
+ {
1489
+ name: "apiKey",
1490
+ type: "string",
1491
+ required: false,
1492
+ description: "Linear API Key",
1493
+ envVar: "LINEAR_API_KEY"
1494
+ }
1495
+ ],
1496
+ installInstructions: "Create an API key at https://linear.app/settings/api"
1497
+ },
1498
+ {
1499
+ id: "jira",
1500
+ name: "Jira",
1501
+ description: "Atlassian Jira issue tracking",
1502
+ package: "@anthropic/jira-mcp",
1503
+ category: "project-mgmt",
1504
+ requiresConfig: true,
1505
+ configFields: [
1506
+ {
1507
+ name: "host",
1508
+ type: "string",
1509
+ required: false,
1510
+ description: "Jira instance URL",
1511
+ envVar: "JIRA_HOST"
1512
+ },
1513
+ {
1514
+ name: "email",
1515
+ type: "string",
1516
+ required: false,
1517
+ description: "Jira account email",
1518
+ envVar: "JIRA_EMAIL"
1519
+ },
1520
+ {
1521
+ name: "token",
1522
+ type: "string",
1523
+ required: false,
1524
+ description: "Jira API Token",
1525
+ envVar: "JIRA_TOKEN"
1526
+ }
1527
+ ],
1528
+ installInstructions: "Create an API token at https://id.atlassian.com/manage-profile/security/api-tokens"
1529
+ },
1530
+ {
1531
+ id: "notion",
1532
+ name: "Notion",
1533
+ description: "Notion workspace, pages, and databases",
1534
+ package: "@anthropic/notion-mcp",
1535
+ category: "project-mgmt",
1536
+ requiresConfig: true,
1537
+ configFields: [
1538
+ {
1539
+ name: "token",
1540
+ type: "string",
1541
+ required: false,
1542
+ description: "Notion Integration Token",
1543
+ envVar: "NOTION_TOKEN"
1544
+ }
1545
+ ],
1546
+ installInstructions: "Create an integration at https://www.notion.so/my-integrations and share pages with it."
1547
+ },
1548
+ {
1549
+ id: "asana",
1550
+ name: "Asana",
1551
+ description: "Asana project and task management",
1552
+ package: "@anthropic/asana-mcp",
1553
+ category: "project-mgmt",
1554
+ requiresConfig: true,
1555
+ configFields: [
1556
+ {
1557
+ name: "token",
1558
+ type: "string",
1559
+ required: false,
1560
+ description: "Asana Personal Access Token",
1561
+ envVar: "ASANA_TOKEN"
1562
+ }
1563
+ ],
1564
+ installInstructions: "Create a PAT at https://app.asana.com/0/my-apps"
1565
+ },
1566
+ // ============================================
1567
+ // MONITORING & OBSERVABILITY
1568
+ // ============================================
1569
+ {
1570
+ id: "sentry",
1571
+ name: "Sentry",
1572
+ description: "Error monitoring and tracking",
1573
+ package: "@sentry/mcp-server",
1574
+ category: "monitoring",
1575
+ requiresConfig: true,
1576
+ configFields: [
1577
+ {
1578
+ name: "authToken",
1579
+ type: "string",
1580
+ required: false,
1581
+ description: "Sentry Auth Token",
1582
+ envVar: "SENTRY_AUTH_TOKEN"
1583
+ },
1584
+ {
1585
+ name: "org",
1586
+ type: "string",
1587
+ required: false,
1588
+ description: "Sentry Organization slug"
1589
+ }
1590
+ ],
1591
+ installInstructions: "Create an auth token at https://sentry.io/settings/account/api/auth-tokens/"
1592
+ },
1593
+ {
1594
+ id: "datadog",
1595
+ name: "Datadog",
1596
+ description: "Datadog monitoring and APM",
1597
+ package: "@anthropic/datadog-mcp",
1598
+ category: "monitoring",
1599
+ requiresConfig: true,
1600
+ configFields: [
1601
+ {
1602
+ name: "apiKey",
1603
+ type: "string",
1604
+ required: false,
1605
+ description: "Datadog API Key",
1606
+ envVar: "DD_API_KEY"
1607
+ },
1608
+ {
1609
+ name: "appKey",
1610
+ type: "string",
1611
+ required: false,
1612
+ description: "Datadog Application Key",
1613
+ envVar: "DD_APP_KEY"
1614
+ },
1615
+ {
1616
+ name: "site",
1617
+ type: "string",
1618
+ required: false,
1619
+ description: "Datadog site (e.g., datadoghq.com)",
1620
+ default: "datadoghq.com"
1621
+ }
1622
+ ],
1623
+ installInstructions: "Find keys at https://app.datadoghq.com/organization-settings/api-keys"
1624
+ },
1625
+ // ============================================
1626
+ // COMMUNICATION
1627
+ // ============================================
1628
+ {
1629
+ id: "slack",
1630
+ name: "Slack",
1631
+ description: "Slack messaging and channel management",
1632
+ package: "@anthropic/slack-mcp",
1633
+ category: "communication",
1634
+ requiresConfig: true,
1635
+ configFields: [
1636
+ {
1637
+ name: "token",
1638
+ type: "string",
1639
+ required: false,
1640
+ description: "Slack Bot Token (xoxb-...)",
1641
+ envVar: "SLACK_BOT_TOKEN"
1642
+ }
1643
+ ],
1644
+ installInstructions: "Create a Slack app at https://api.slack.com/apps and install to your workspace."
1645
+ },
1646
+ {
1647
+ id: "discord",
1648
+ name: "Discord",
1649
+ description: "Discord bot and server management",
1650
+ package: "@anthropic/discord-mcp",
1651
+ category: "communication",
1652
+ requiresConfig: true,
1653
+ configFields: [
1654
+ {
1655
+ name: "token",
1656
+ type: "string",
1657
+ required: false,
1658
+ description: "Discord Bot Token",
1659
+ envVar: "DISCORD_BOT_TOKEN"
1660
+ }
1661
+ ],
1662
+ installInstructions: "Create a bot at https://discord.com/developers/applications"
1663
+ },
1664
+ // ============================================
1665
+ // DESIGN
1666
+ // ============================================
1667
+ {
1668
+ id: "figma",
1669
+ name: "Figma",
1670
+ description: "Figma design file access and inspection",
1671
+ package: "@anthropic/figma-mcp",
1672
+ category: "design",
1673
+ requiresConfig: true,
1674
+ configFields: [
1675
+ {
1676
+ name: "token",
1677
+ type: "string",
1678
+ required: false,
1679
+ description: "Figma Personal Access Token",
1680
+ envVar: "FIGMA_TOKEN"
1681
+ }
1682
+ ],
1683
+ installInstructions: "Create a token at https://www.figma.com/developers/api#access-tokens"
1684
+ },
1685
+ // ============================================
1686
+ // PAYMENTS
1687
+ // ============================================
1688
+ {
1689
+ id: "stripe",
1690
+ name: "Stripe",
1691
+ description: "Stripe payments API integration",
1692
+ package: "@stripe/mcp-server",
1693
+ category: "payments",
1694
+ requiresConfig: true,
1695
+ configFields: [
1696
+ {
1697
+ name: "secretKey",
1698
+ type: "string",
1699
+ required: false,
1700
+ description: "Stripe Secret Key",
1701
+ envVar: "STRIPE_SECRET_KEY"
1702
+ }
1703
+ ],
1704
+ installInstructions: "Find your API keys at https://dashboard.stripe.com/apikeys (use test keys for development)"
1705
+ },
1706
+ // ============================================
1707
+ // SEARCH
1708
+ // ============================================
1709
+ {
1710
+ id: "algolia",
1711
+ name: "Algolia",
1712
+ description: "Algolia search and discovery",
1713
+ package: "@anthropic/algolia-mcp",
1714
+ category: "search",
1715
+ requiresConfig: true,
1716
+ configFields: [
1717
+ {
1718
+ name: "appId",
1719
+ type: "string",
1720
+ required: false,
1721
+ description: "Algolia Application ID",
1722
+ envVar: "ALGOLIA_APP_ID"
1723
+ },
1724
+ {
1725
+ name: "apiKey",
1726
+ type: "string",
1727
+ required: false,
1728
+ description: "Algolia Admin API Key",
1729
+ envVar: "ALGOLIA_API_KEY"
1730
+ }
1731
+ ],
1732
+ installInstructions: "Find credentials at https://www.algolia.com/account/api-keys/"
1733
+ },
1734
+ {
1735
+ id: "elasticsearch",
1736
+ name: "Elasticsearch",
1737
+ description: "Elasticsearch search engine",
1738
+ package: "@anthropic/elasticsearch-mcp",
1739
+ category: "search",
1740
+ requiresConfig: true,
1741
+ configFields: [
1742
+ {
1743
+ name: "node",
1744
+ type: "string",
1745
+ required: false,
1746
+ description: "Elasticsearch node URL",
1747
+ envVar: "ELASTICSEARCH_NODE",
1748
+ default: "http://localhost:9200"
1749
+ },
1750
+ {
1751
+ name: "apiKey",
1752
+ type: "string",
1753
+ required: false,
1754
+ description: "Elasticsearch API Key (optional)",
1755
+ envVar: "ELASTICSEARCH_API_KEY"
1756
+ }
1757
+ ]
1758
+ },
1759
+ // ============================================
1760
+ // AI & ML
1761
+ // ============================================
1762
+ {
1763
+ id: "openai",
1764
+ name: "OpenAI",
1765
+ description: "OpenAI API for GPT and embeddings",
1766
+ package: "@anthropic/openai-mcp",
1767
+ category: "ai",
1768
+ requiresConfig: true,
1769
+ configFields: [
1770
+ {
1771
+ name: "apiKey",
1772
+ type: "string",
1773
+ required: false,
1774
+ description: "OpenAI API Key",
1775
+ envVar: "OPENAI_API_KEY"
1776
+ }
1777
+ ],
1778
+ installInstructions: "Get your API key at https://platform.openai.com/api-keys"
1779
+ },
1780
+ {
1781
+ id: "pinecone",
1782
+ name: "Pinecone",
1783
+ description: "Pinecone vector database for embeddings",
1784
+ package: "@anthropic/pinecone-mcp",
1785
+ category: "ai",
1786
+ requiresConfig: true,
1787
+ configFields: [
1788
+ {
1789
+ name: "apiKey",
1790
+ type: "string",
1791
+ required: false,
1792
+ description: "Pinecone API Key",
1793
+ envVar: "PINECONE_API_KEY"
1794
+ },
1795
+ {
1796
+ name: "environment",
1797
+ type: "string",
1798
+ required: false,
1799
+ description: "Pinecone environment",
1800
+ envVar: "PINECONE_ENVIRONMENT"
1801
+ }
1802
+ ],
1803
+ installInstructions: "Get credentials at https://app.pinecone.io/"
1804
+ },
1805
+ // ============================================
1806
+ // SECURITY
1807
+ // ============================================
1808
+ {
1809
+ id: "vault",
1810
+ name: "HashiCorp Vault",
1811
+ description: "Secrets management with HashiCorp Vault",
1812
+ package: "@anthropic/vault-mcp",
1813
+ category: "security",
1814
+ requiresConfig: true,
1815
+ configFields: [
1816
+ {
1817
+ name: "address",
1818
+ type: "string",
1819
+ required: false,
1820
+ description: "Vault server address",
1821
+ envVar: "VAULT_ADDR",
1822
+ default: "http://127.0.0.1:8200"
1823
+ },
1824
+ {
1825
+ name: "token",
1826
+ type: "string",
1827
+ required: false,
1828
+ description: "Vault token",
1829
+ envVar: "VAULT_TOKEN"
1830
+ }
1831
+ ]
1832
+ }
1833
+ ];
1834
+
1835
+ // src/constants/dependencies.ts
1836
+ init_cjs_shims();
1837
+ var DEPENDENCIES = [
1838
+ {
1839
+ id: "piper-tts",
1840
+ name: "Piper TTS",
1841
+ description: "Text-to-speech for audio notifications",
1842
+ requiredFor: ["hook:notification:audio"],
1843
+ checkCommand: "command -v piper",
1844
+ platforms: {
1845
+ linux: {
1846
+ commands: [
1847
+ "pip install piper-tts",
1848
+ "mkdir -p ~/.local/share/piper/voices",
1849
+ "wget -O ~/.local/share/piper/voices/en_US-hfc_male-medium.onnx https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/hfc_male/medium/en_US-hfc_male-medium.onnx",
1850
+ "wget -O ~/.local/share/piper/voices/en_US-hfc_male-medium.onnx.json https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/hfc_male/medium/en_US-hfc_male-medium.onnx.json"
1851
+ ],
1852
+ notes: "Requires Python 3.9+ and pip",
1853
+ links: ["https://github.com/rhasspy/piper"]
1854
+ },
1855
+ macos: {
1856
+ commands: [
1857
+ "pip3 install piper-tts",
1858
+ "mkdir -p ~/.local/share/piper/voices",
1859
+ "# Download voice files from https://github.com/rhasspy/piper/releases"
1860
+ ],
1861
+ notes: "May need to install portaudio: brew install portaudio",
1862
+ links: ["https://github.com/rhasspy/piper"]
1863
+ }
1864
+ }
1865
+ },
1866
+ {
1867
+ id: "notify-send",
1868
+ name: "libnotify",
1869
+ description: "Desktop notifications for Linux",
1870
+ requiredFor: ["hook:notification:desktop"],
1871
+ checkCommand: "command -v notify-send",
1872
+ platforms: {
1873
+ linux: {
1874
+ commands: [
1875
+ "# Ubuntu/Debian:",
1876
+ "sudo apt install libnotify-bin",
1877
+ "# Fedora:",
1878
+ "sudo dnf install libnotify",
1879
+ "# Arch:",
1880
+ "sudo pacman -S libnotify"
1881
+ ]
1882
+ }
1883
+ }
1884
+ },
1885
+ {
1886
+ id: "terminal-notifier",
1887
+ name: "terminal-notifier",
1888
+ description: "Desktop notifications for macOS",
1889
+ requiredFor: ["hook:notification:desktop"],
1890
+ checkCommand: "command -v terminal-notifier",
1891
+ platforms: {
1892
+ macos: {
1893
+ commands: ["brew install terminal-notifier"],
1894
+ links: ["https://github.com/julienXX/terminal-notifier"]
1895
+ }
1896
+ }
1897
+ },
1898
+ {
1899
+ id: "jq",
1900
+ name: "jq",
1901
+ description: "JSON processor for hook scripts",
1902
+ requiredFor: ["hooks"],
1903
+ checkCommand: "command -v jq",
1904
+ platforms: {
1905
+ linux: {
1906
+ commands: [
1907
+ "# Ubuntu/Debian:",
1908
+ "sudo apt install jq",
1909
+ "# Fedora:",
1910
+ "sudo dnf install jq",
1911
+ "# Arch:",
1912
+ "sudo pacman -S jq"
1913
+ ]
1914
+ },
1915
+ macos: {
1916
+ commands: ["brew install jq"]
1917
+ },
1918
+ windows: {
1919
+ commands: ["choco install jq", "# Or: winget install jqlang.jq"]
1920
+ }
1921
+ }
1922
+ },
1923
+ {
1924
+ id: "aplay",
1925
+ name: "ALSA Utils",
1926
+ description: "Audio playback for Linux",
1927
+ requiredFor: ["hook:notification:audio"],
1928
+ checkCommand: "command -v aplay",
1929
+ platforms: {
1930
+ linux: {
1931
+ commands: [
1932
+ "# Ubuntu/Debian:",
1933
+ "sudo apt install alsa-utils",
1934
+ "# Fedora:",
1935
+ "sudo dnf install alsa-utils",
1936
+ "# Arch:",
1937
+ "sudo pacman -S alsa-utils"
1938
+ ]
1939
+ }
1940
+ }
1941
+ },
1942
+ {
1943
+ id: "afplay",
1944
+ name: "afplay",
1945
+ description: "Audio playback for macOS (built-in)",
1946
+ requiredFor: ["hook:notification:audio"],
1947
+ checkCommand: "command -v afplay",
1948
+ platforms: {
1949
+ macos: {
1950
+ commands: ["# Built-in on macOS, no installation needed"],
1951
+ notes: "afplay is included with macOS by default"
1952
+ }
1953
+ }
1954
+ },
1955
+ {
1956
+ id: "git",
1957
+ name: "Git",
1958
+ description: "Version control system",
1959
+ requiredFor: ["version-control", "remote-templates"],
1960
+ checkCommand: "git --version",
1961
+ platforms: {
1962
+ linux: {
1963
+ commands: [
1964
+ "# Ubuntu/Debian:",
1965
+ "sudo apt install git",
1966
+ "# Fedora:",
1967
+ "sudo dnf install git",
1968
+ "# Arch:",
1969
+ "sudo pacman -S git"
1970
+ ]
1971
+ },
1972
+ macos: {
1973
+ commands: ["brew install git", "# Or: xcode-select --install"]
1974
+ },
1975
+ windows: {
1976
+ commands: ["choco install git", "# Or: winget install Git.Git"],
1977
+ links: ["https://git-scm.com/download/win"]
1978
+ }
1979
+ }
1980
+ },
1981
+ {
1982
+ id: "node",
1983
+ name: "Node.js",
1984
+ description: "JavaScript runtime",
1985
+ requiredFor: ["cli", "mcp-servers"],
1986
+ checkCommand: "node --version",
1987
+ platforms: {
1988
+ linux: {
1989
+ commands: [
1990
+ "# Using nvm (recommended):",
1991
+ "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash",
1992
+ "nvm install --lts",
1993
+ "# Or using package manager:",
1994
+ "sudo apt install nodejs npm"
1995
+ ],
1996
+ links: ["https://nodejs.org/", "https://github.com/nvm-sh/nvm"]
1997
+ },
1998
+ macos: {
1999
+ commands: [
2000
+ "# Using nvm (recommended):",
2001
+ "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash",
2002
+ "nvm install --lts",
2003
+ "# Or using Homebrew:",
2004
+ "brew install node"
2005
+ ],
2006
+ links: ["https://nodejs.org/", "https://github.com/nvm-sh/nvm"]
2007
+ },
2008
+ windows: {
2009
+ commands: ["choco install nodejs-lts", "# Or: winget install OpenJS.NodeJS.LTS"],
2010
+ links: ["https://nodejs.org/"]
2011
+ }
2012
+ }
2013
+ }
2014
+ ];
2015
+
2016
+ // src/constants/placeholders.ts
2017
+ init_cjs_shims();
2018
+ var PLACEHOLDERS = [
2019
+ // Project info placeholders
2020
+ {
2021
+ pattern: /\[Project Name\]/g,
2022
+ configKey: "name",
2023
+ transform: "none",
2024
+ description: "Project name",
2025
+ example: "My Awesome Project",
2026
+ required: true
2027
+ },
2028
+ {
2029
+ pattern: /\[project-name\]/g,
2030
+ configKey: "name",
2031
+ transform: "lowercase",
2032
+ description: "Project name in lowercase with dashes",
2033
+ example: "my-awesome-project",
2034
+ required: true
2035
+ },
2036
+ {
2037
+ pattern: /\[PROJECT_NAME\]/g,
2038
+ configKey: "name",
2039
+ transform: "uppercase",
2040
+ description: "Project name in uppercase with underscores",
2041
+ example: "MY_AWESOME_PROJECT",
2042
+ required: true
2043
+ },
2044
+ {
2045
+ pattern: /\[Project Description\]/g,
2046
+ configKey: "description",
2047
+ transform: "none",
2048
+ description: "Project description",
2049
+ example: "A powerful CLI tool for managing configurations",
2050
+ required: true
2051
+ },
2052
+ {
2053
+ pattern: /your-org/g,
2054
+ configKey: "org",
2055
+ transform: "lowercase",
2056
+ description: "GitHub organization or username",
2057
+ example: "acme-corp",
2058
+ required: true
2059
+ },
2060
+ {
2061
+ pattern: /your-repo/g,
2062
+ configKey: "repo",
2063
+ transform: "lowercase",
2064
+ description: "Repository name",
2065
+ example: "my-project",
2066
+ required: true
2067
+ },
2068
+ {
2069
+ pattern: /example\.com/g,
2070
+ configKey: "domain",
2071
+ transform: "lowercase",
2072
+ description: "Project domain",
2073
+ example: "myproject.com",
2074
+ required: false
2075
+ },
2076
+ // Entity placeholders
2077
+ {
2078
+ pattern: /\[Entity\]/g,
2079
+ configKey: "entityType",
2080
+ transform: "capitalize",
2081
+ description: "Primary entity type (capitalized)",
2082
+ example: "Product",
2083
+ required: true
2084
+ },
2085
+ {
2086
+ pattern: /\[entity\]/g,
2087
+ configKey: "entityType",
2088
+ transform: "lowercase",
2089
+ description: "Primary entity type (lowercase)",
2090
+ example: "product",
2091
+ required: true
2092
+ },
2093
+ {
2094
+ pattern: /\[Entities\]/g,
2095
+ configKey: "entityTypePlural",
2096
+ transform: "capitalize",
2097
+ description: "Primary entity type plural (capitalized)",
2098
+ example: "Products",
2099
+ required: true
2100
+ },
2101
+ {
2102
+ pattern: /\[entities\]/g,
2103
+ configKey: "entityTypePlural",
2104
+ transform: "lowercase",
2105
+ description: "Primary entity type plural (lowercase)",
2106
+ example: "products",
2107
+ required: true
2108
+ },
2109
+ // Location placeholders
2110
+ {
2111
+ pattern: /\[City Name\]/g,
2112
+ configKey: "location",
2113
+ transform: "capitalize",
2114
+ description: "City or location name",
2115
+ example: "San Francisco",
2116
+ required: false
2117
+ },
2118
+ {
2119
+ pattern: /\[Your Region\/Product\]/g,
2120
+ configKey: "location",
2121
+ transform: "none",
2122
+ description: "Region or product area",
2123
+ example: "Bay Area",
2124
+ required: false
2125
+ },
2126
+ {
2127
+ pattern: /\[Your product\/service tagline here\]/g,
2128
+ configKey: "description",
2129
+ transform: "none",
2130
+ description: "Product tagline",
2131
+ example: "The best way to manage your projects",
2132
+ required: false
2133
+ }
2134
+ ];
2135
+ function applyTransform(value, transform) {
2136
+ switch (transform) {
2137
+ case "lowercase":
2138
+ return value.toLowerCase().replace(/\s+/g, "-");
2139
+ case "uppercase":
2140
+ return value.toUpperCase().replace(/\s+/g, "_");
2141
+ case "capitalize":
2142
+ return value.split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
2143
+ case "pluralize":
2144
+ if (value.endsWith("y")) {
2145
+ return `${value.slice(0, -1)}ies`;
2146
+ }
2147
+ if (value.endsWith("s") || value.endsWith("x") || value.endsWith("ch") || value.endsWith("sh")) {
2148
+ return `${value}es`;
2149
+ }
2150
+ return `${value}s`;
2151
+ default:
2152
+ return value;
2153
+ }
2154
+ }
2155
+
2156
+ // src/constants/permissions.ts
2157
+ init_cjs_shims();
2158
+ var DEFAULT_FILE_PERMISSIONS = {
2159
+ readAll: true,
2160
+ writeCode: true,
2161
+ writeConfig: true,
2162
+ writeMarkdown: true,
2163
+ writeOther: false,
2164
+ editTool: true
2165
+ };
2166
+ var TRUST_FILE_PERMISSIONS = {
2167
+ readAll: true,
2168
+ writeCode: true,
2169
+ writeConfig: true,
2170
+ writeMarkdown: true,
2171
+ writeOther: true,
2172
+ editTool: true
2173
+ };
2174
+ var RESTRICTIVE_FILE_PERMISSIONS = {
2175
+ readAll: true,
2176
+ writeCode: false,
2177
+ writeConfig: false,
2178
+ writeMarkdown: true,
2179
+ writeOther: false,
2180
+ editTool: false
2181
+ };
2182
+ var DEFAULT_GIT_PERMISSIONS = {
2183
+ readOnly: true,
2184
+ staging: false,
2185
+ commit: false,
2186
+ push: false,
2187
+ branching: false
2188
+ };
2189
+ var TRUST_GIT_PERMISSIONS = {
2190
+ readOnly: true,
2191
+ staging: true,
2192
+ commit: true,
2193
+ push: false,
2194
+ branching: true
2195
+ };
2196
+ var RESTRICTIVE_GIT_PERMISSIONS = {
2197
+ readOnly: true,
2198
+ staging: false,
2199
+ commit: false,
2200
+ push: false,
2201
+ branching: false
2202
+ };
2203
+ var DEFAULT_BASH_PERMISSIONS = {
2204
+ packageManager: true,
2205
+ testing: true,
2206
+ building: true,
2207
+ docker: false,
2208
+ arbitrary: false
2209
+ };
2210
+ var TRUST_BASH_PERMISSIONS = {
2211
+ packageManager: true,
2212
+ testing: true,
2213
+ building: true,
2214
+ docker: true,
2215
+ arbitrary: true
2216
+ };
2217
+ var RESTRICTIVE_BASH_PERMISSIONS = {
2218
+ packageManager: false,
2219
+ testing: false,
2220
+ building: false,
2221
+ docker: false,
2222
+ arbitrary: false
2223
+ };
2224
+ var DEFAULT_WEB_PERMISSIONS = {
2225
+ fetch: true,
2226
+ search: true
2227
+ };
2228
+ var PERMISSION_PRESETS = {
2229
+ default: {
2230
+ files: DEFAULT_FILE_PERMISSIONS,
2231
+ git: DEFAULT_GIT_PERMISSIONS,
2232
+ bash: DEFAULT_BASH_PERMISSIONS,
2233
+ web: DEFAULT_WEB_PERMISSIONS
2234
+ },
2235
+ trust: {
2236
+ files: TRUST_FILE_PERMISSIONS,
2237
+ git: TRUST_GIT_PERMISSIONS,
2238
+ bash: TRUST_BASH_PERMISSIONS,
2239
+ web: DEFAULT_WEB_PERMISSIONS
2240
+ },
2241
+ restrictive: {
2242
+ files: RESTRICTIVE_FILE_PERMISSIONS,
2243
+ git: RESTRICTIVE_GIT_PERMISSIONS,
2244
+ bash: RESTRICTIVE_BASH_PERMISSIONS,
2245
+ web: DEFAULT_WEB_PERMISSIONS
2246
+ },
2247
+ custom: {
2248
+ files: DEFAULT_FILE_PERMISSIONS,
2249
+ git: DEFAULT_GIT_PERMISSIONS,
2250
+ bash: DEFAULT_BASH_PERMISSIONS,
2251
+ web: DEFAULT_WEB_PERMISSIONS
2252
+ }
2253
+ };
2254
+
2255
+ // src/lib/bundles/resolver.ts
2256
+ init_cjs_shims();
2257
+ function resolveBundle(bundle) {
2258
+ const modules = {
2259
+ agents: [],
2260
+ skills: [],
2261
+ commands: [],
2262
+ docs: []
2263
+ };
2264
+ for (const moduleRef of bundle.modules) {
2265
+ switch (moduleRef.category) {
2266
+ case "agents":
2267
+ modules.agents.push(moduleRef.id);
2268
+ break;
2269
+ case "skills":
2270
+ modules.skills.push(moduleRef.id);
2271
+ break;
2272
+ case "commands":
2273
+ modules.commands.push(moduleRef.id);
2274
+ break;
2275
+ case "docs":
2276
+ modules.docs.push(moduleRef.id);
2277
+ break;
2278
+ }
2279
+ }
2280
+ return {
2281
+ bundle,
2282
+ modules
2283
+ };
2284
+ }
2285
+ function resolveBundles(bundleIds) {
2286
+ const result = {
2287
+ agents: [],
2288
+ skills: [],
2289
+ commands: [],
2290
+ docs: []
2291
+ };
2292
+ const seenModules = {
2293
+ agents: /* @__PURE__ */ new Set(),
2294
+ skills: /* @__PURE__ */ new Set(),
2295
+ commands: /* @__PURE__ */ new Set(),
2296
+ docs: /* @__PURE__ */ new Set()
2297
+ };
2298
+ for (const bundleId of bundleIds) {
2299
+ const bundle = getBundleById(bundleId);
2300
+ if (!bundle) continue;
2301
+ const resolved = resolveBundle(bundle);
2302
+ for (const id of resolved.modules.agents) {
2303
+ if (!seenModules.agents.has(id)) {
2304
+ seenModules.agents.add(id);
2305
+ result.agents.push(id);
2306
+ }
2307
+ }
2308
+ for (const id of resolved.modules.skills) {
2309
+ if (!seenModules.skills.has(id)) {
2310
+ seenModules.skills.add(id);
2311
+ result.skills.push(id);
2312
+ }
2313
+ }
2314
+ for (const id of resolved.modules.commands) {
2315
+ if (!seenModules.commands.has(id)) {
2316
+ seenModules.commands.add(id);
2317
+ result.commands.push(id);
2318
+ }
2319
+ }
2320
+ for (const id of resolved.modules.docs) {
2321
+ if (!seenModules.docs.has(id)) {
2322
+ seenModules.docs.add(id);
2323
+ result.docs.push(id);
2324
+ }
2325
+ }
2326
+ }
2327
+ return result;
2328
+ }
2329
+ function mergeBundleSelection(bundleResult) {
2330
+ const result = resolveBundles(bundleResult.selectedBundles);
2331
+ const seenModules = {
2332
+ agents: new Set(result.agents),
2333
+ skills: new Set(result.skills),
2334
+ commands: new Set(result.commands),
2335
+ docs: new Set(result.docs)
2336
+ };
2337
+ for (const id of bundleResult.additionalModules.agents) {
2338
+ if (!seenModules.agents.has(id)) {
2339
+ result.agents.push(id);
2340
+ }
2341
+ }
2342
+ for (const id of bundleResult.additionalModules.skills) {
2343
+ if (!seenModules.skills.has(id)) {
2344
+ result.skills.push(id);
2345
+ }
2346
+ }
2347
+ for (const id of bundleResult.additionalModules.commands) {
2348
+ if (!seenModules.commands.has(id)) {
2349
+ result.commands.push(id);
2350
+ }
2351
+ }
2352
+ for (const id of bundleResult.additionalModules.docs) {
2353
+ if (!seenModules.docs.has(id)) {
2354
+ result.docs.push(id);
2355
+ }
2356
+ }
2357
+ return result;
2358
+ }
2359
+
2360
+ // src/lib/config/index.ts
2361
+ init_cjs_shims();
2362
+
2363
+ // src/lib/config/reader.ts
2364
+ init_cjs_shims();
2365
+ init_fs();
2366
+
2367
+ // src/lib/utils/logger.ts
2368
+ init_cjs_shims();
2369
+ var import_chalk = __toESM(require("chalk"), 1);
2370
+ var SYMBOLS = {
2371
+ info: import_chalk.default.blue("\u2139"),
2372
+ success: import_chalk.default.green("\u2714"),
2373
+ warn: import_chalk.default.yellow("\u26A0"),
2374
+ error: import_chalk.default.red("\u2716"),
2375
+ debug: import_chalk.default.gray("\u25CF"),
2376
+ arrow: import_chalk.default.cyan("\u2192"),
2377
+ bullet: import_chalk.default.dim("\u2022")
2378
+ };
2379
+ var Logger = class {
2380
+ verbose = false;
2381
+ silent = false;
2382
+ configure(options) {
2383
+ if (options.verbose !== void 0) this.verbose = options.verbose;
2384
+ if (options.silent !== void 0) this.silent = options.silent;
2385
+ }
2386
+ log(level, message, ...args) {
2387
+ if (this.silent && level !== "error") return;
2388
+ if (level === "debug" && !this.verbose) return;
2389
+ const prefix = SYMBOLS[level];
2390
+ const formattedMessage = args.length > 0 ? `${message} ${args.join(" ")}` : message;
2391
+ switch (level) {
2392
+ case "error":
2393
+ console.error(`${prefix} ${import_chalk.default.red(formattedMessage)}`);
2394
+ break;
2395
+ case "warn":
2396
+ console.warn(`${prefix} ${import_chalk.default.yellow(formattedMessage)}`);
2397
+ break;
2398
+ case "success":
2399
+ console.log(`${prefix} ${import_chalk.default.green(formattedMessage)}`);
2400
+ break;
2401
+ case "debug":
2402
+ console.log(`${prefix} ${import_chalk.default.gray(formattedMessage)}`);
2403
+ break;
2404
+ default:
2405
+ console.log(`${prefix} ${formattedMessage}`);
2406
+ }
2407
+ }
2408
+ debug(message, ...args) {
2409
+ this.log("debug", message, ...args);
2410
+ }
2411
+ info(message, ...args) {
2412
+ this.log("info", message, ...args);
2413
+ }
2414
+ success(message, ...args) {
2415
+ this.log("success", message, ...args);
2416
+ }
2417
+ warn(message, ...args) {
2418
+ this.log("warn", message, ...args);
2419
+ }
2420
+ error(message, ...args) {
2421
+ this.log("error", message, ...args);
2422
+ }
2423
+ /**
2424
+ * Print a blank line
2425
+ */
2426
+ newline() {
2427
+ if (!this.silent) console.log();
2428
+ }
2429
+ /**
2430
+ * Print a title/header
2431
+ */
2432
+ title(text) {
2433
+ if (this.silent) return;
2434
+ console.log();
2435
+ console.log(import_chalk.default.bold(import_chalk.default.cyan(text)));
2436
+ console.log(import_chalk.default.dim("\u2500".repeat(Math.min(text.length + 4, 60))));
2437
+ }
2438
+ /**
2439
+ * Print a subtitle
2440
+ */
2441
+ subtitle(text) {
2442
+ if (this.silent) return;
2443
+ console.log();
2444
+ console.log(import_chalk.default.bold(text));
2445
+ }
2446
+ /**
2447
+ * Print a large section header for major transitions
2448
+ * Creates a visually prominent divider between configuration sections
2449
+ */
2450
+ section(text, icon) {
2451
+ if (this.silent) return;
2452
+ const displayIcon = icon || "\u25C6";
2453
+ const width = 60;
2454
+ const border = "\u2550".repeat(width);
2455
+ const innerWidth = width - 4;
2456
+ const paddedText = text.length > innerWidth ? text.slice(0, innerWidth) : text;
2457
+ const leftPad = Math.floor((innerWidth - paddedText.length) / 2);
2458
+ const rightPad = innerWidth - paddedText.length - leftPad;
2459
+ console.log();
2460
+ console.log(import_chalk.default.cyan(`\u2554${border}\u2557`));
2461
+ console.log(import_chalk.default.cyan("\u2551") + " ".repeat(width) + import_chalk.default.cyan("\u2551"));
2462
+ console.log(
2463
+ `${import_chalk.default.cyan("\u2551") + " ".repeat(leftPad + 1) + import_chalk.default.hex("#FED330")(displayIcon)} ${import_chalk.default.bold.white(paddedText)}${" ".repeat(rightPad + 1)}${import_chalk.default.cyan("\u2551")}`
2464
+ );
2465
+ console.log(import_chalk.default.cyan("\u2551") + " ".repeat(width) + import_chalk.default.cyan("\u2551"));
2466
+ console.log(import_chalk.default.cyan(`\u255A${border}\u255D`));
2467
+ console.log();
2468
+ }
2469
+ /**
2470
+ * Print a step in a process
2471
+ */
2472
+ step(stepNumber, totalSteps, message) {
2473
+ if (this.silent) return;
2474
+ const progress = import_chalk.default.dim(`[${stepNumber}/${totalSteps}]`);
2475
+ console.log(`${progress} ${message}`);
2476
+ }
2477
+ /**
2478
+ * Print a list item
2479
+ */
2480
+ item(text, indent = 0) {
2481
+ if (this.silent) return;
2482
+ const spaces = " ".repeat(indent);
2483
+ console.log(`${spaces}${SYMBOLS.bullet} ${text}`);
2484
+ }
2485
+ /**
2486
+ * Print a key-value pair
2487
+ */
2488
+ keyValue(key, value, indent = 0) {
2489
+ if (this.silent) return;
2490
+ const spaces = " ".repeat(indent);
2491
+ console.log(`${spaces}${import_chalk.default.dim(`${key}:`)} ${value}`);
2492
+ }
2493
+ /**
2494
+ * Print an arrow item (for showing changes/actions)
2495
+ */
2496
+ arrow(text, indent = 0) {
2497
+ if (this.silent) return;
2498
+ const spaces = " ".repeat(indent);
2499
+ console.log(`${spaces}${SYMBOLS.arrow} ${text}`);
2500
+ }
2501
+ /**
2502
+ * Print a boxed message
2503
+ */
2504
+ box(title, content) {
2505
+ if (this.silent) return;
2506
+ const maxLength = Math.max(title.length, ...content.map((line) => line.length));
2507
+ const width = Math.min(maxLength + 4, 70);
2508
+ const border = "\u2500".repeat(width - 2);
2509
+ console.log();
2510
+ console.log(import_chalk.default.cyan(`\u250C${border}\u2510`));
2511
+ console.log(import_chalk.default.cyan("\u2502") + import_chalk.default.bold(` ${title.padEnd(width - 3)}`) + import_chalk.default.cyan("\u2502"));
2512
+ console.log(import_chalk.default.cyan(`\u251C${border}\u2524`));
2513
+ for (const line of content) {
2514
+ console.log(`${import_chalk.default.cyan("\u2502")} ${line.padEnd(width - 3)}${import_chalk.default.cyan("\u2502")}`);
2515
+ }
2516
+ console.log(import_chalk.default.cyan(`\u2514${border}\u2518`));
2517
+ console.log();
2518
+ }
2519
+ /**
2520
+ * Print a table
2521
+ */
2522
+ table(headers, rows) {
2523
+ if (this.silent) return;
2524
+ const colWidths = headers.map((h, i) => {
2525
+ const maxRowWidth = Math.max(...rows.map((r) => (r[i] || "").length));
2526
+ return Math.max(h.length, maxRowWidth);
2527
+ });
2528
+ const headerRow = headers.map((h, i) => import_chalk.default.bold(h.padEnd(colWidths[i]))).join(" ");
2529
+ console.log(headerRow);
2530
+ console.log(import_chalk.default.dim(colWidths.map((w) => "\u2500".repeat(w)).join(" ")));
2531
+ for (const row of rows) {
2532
+ const rowStr = row.map((cell, i) => (cell || "").padEnd(colWidths[i])).join(" ");
2533
+ console.log(rowStr);
2534
+ }
2535
+ }
2536
+ /**
2537
+ * Print a colored status
2538
+ */
2539
+ status(label, status) {
2540
+ if (this.silent) return;
2541
+ const statusColors = {
2542
+ success: import_chalk.default.green("\u2714 done"),
2543
+ error: import_chalk.default.red("\u2716 failed"),
2544
+ warn: import_chalk.default.yellow("\u26A0 warning"),
2545
+ pending: import_chalk.default.blue("\u25EF pending"),
2546
+ skip: import_chalk.default.dim("\u25CB skipped")
2547
+ };
2548
+ console.log(` ${label}: ${statusColors[status]}`);
2549
+ }
2550
+ /**
2551
+ * Print instructions
2552
+ */
2553
+ instructions(title, steps) {
2554
+ if (this.silent) return;
2555
+ console.log();
2556
+ console.log(import_chalk.default.bold(import_chalk.default.cyan(title)));
2557
+ console.log();
2558
+ steps.forEach((step, index) => {
2559
+ console.log(` ${import_chalk.default.dim(`${index + 1}.`)} ${step}`);
2560
+ });
2561
+ console.log();
2562
+ }
2563
+ /**
2564
+ * Print a dimmed note
2565
+ */
2566
+ note(text) {
2567
+ if (this.silent) return;
2568
+ console.log(import_chalk.default.dim(` ${text}`));
2569
+ }
2570
+ /**
2571
+ * Print raw text without formatting
2572
+ */
2573
+ raw(text) {
2574
+ if (this.silent) return;
2575
+ console.log(text);
2576
+ }
2577
+ };
2578
+ var logger = new Logger();
2579
+ var colors = {
2580
+ primary: import_chalk.default.cyan,
2581
+ secondary: import_chalk.default.blue,
2582
+ success: import_chalk.default.green,
2583
+ warning: import_chalk.default.yellow,
2584
+ error: import_chalk.default.red,
2585
+ muted: import_chalk.default.dim,
2586
+ bold: import_chalk.default.bold,
2587
+ underline: import_chalk.default.underline
2588
+ };
2589
+
2590
+ // src/lib/config/reader.ts
2591
+ var CONFIG_FILE = "config.json";
2592
+ var CLAUDE_DIR = ".claude";
2593
+ async function readConfig(projectPath) {
2594
+ const configPath = joinPath(projectPath, CLAUDE_DIR, CONFIG_FILE);
2595
+ if (!await pathExists(configPath)) {
2596
+ return null;
2597
+ }
2598
+ try {
2599
+ return await readJson(configPath);
2600
+ } catch (error) {
2601
+ logger.debug(`Failed to read config: ${error}`);
2602
+ return null;
2603
+ }
2604
+ }
2605
+ async function hasConfig(projectPath) {
2606
+ const configPath = joinPath(projectPath, CLAUDE_DIR, CONFIG_FILE);
2607
+ return pathExists(configPath);
2608
+ }
2609
+
2610
+ // src/lib/config/writer.ts
2611
+ init_cjs_shims();
2612
+ init_fs();
2613
+ var CONFIG_FILE2 = "config.json";
2614
+ var CLAUDE_DIR2 = ".claude";
2615
+ async function writeConfig(projectPath, config, options) {
2616
+ const claudePath = joinPath(projectPath, CLAUDE_DIR2);
2617
+ const configPath = joinPath(claudePath, CONFIG_FILE2);
2618
+ await ensureDir(claudePath);
2619
+ if (options?.backup && await pathExists(configPath)) {
2620
+ const backupPath = await backup(configPath, `.backup.${Date.now()}`);
2621
+ logger.debug(`Config backed up to: ${backupPath}`);
2622
+ }
2623
+ await writeJson(configPath, config, { spaces: 2 });
2624
+ logger.debug(`Config written to: ${configPath}`);
2625
+ }
2626
+ function createDefaultConfig(options) {
2627
+ return {
2628
+ version: options.version,
2629
+ templateSource: {
2630
+ type: "local",
2631
+ installedAt: (/* @__PURE__ */ new Date()).toISOString()
2632
+ },
2633
+ project: options.projectInfo,
2634
+ preferences: options.preferences,
2635
+ mcp: {
2636
+ level: "project",
2637
+ servers: []
2638
+ },
2639
+ modules: {
2640
+ agents: { selected: [], excluded: [] },
2641
+ skills: { selected: [], excluded: [] },
2642
+ commands: { selected: [], excluded: [] },
2643
+ docs: { selected: [], excluded: [] }
2644
+ },
2645
+ extras: {
2646
+ schemas: false,
2647
+ scripts: false,
2648
+ hooks: { enabled: false },
2649
+ sessions: false
2650
+ },
2651
+ scaffold: {
2652
+ type: "claude-only",
2653
+ createdStructure: []
2654
+ },
2655
+ customizations: {
2656
+ placeholdersReplaced: false,
2657
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
2658
+ customFiles: []
2659
+ }
2660
+ };
2661
+ }
2662
+
2663
+ // src/lib/config/global-defaults.ts
2664
+ init_cjs_shims();
2665
+ var fs2 = __toESM(require("fs/promises"), 1);
2666
+ var import_node_os = require("os");
2667
+ var path2 = __toESM(require("path"), 1);
2668
+
2669
+ // src/lib/modules/index.ts
2670
+ init_cjs_shims();
2671
+
2672
+ // src/lib/modules/registry.ts
2673
+ init_cjs_shims();
2674
+ init_fs();
2675
+ var REGISTRY_FILE = "_registry.json";
2676
+ async function loadRegistry(templatesPath) {
2677
+ const registry = {
2678
+ agents: [],
2679
+ skills: [],
2680
+ commands: [],
2681
+ docs: []
2682
+ };
2683
+ const categories = ["agents", "skills", "commands", "docs"];
2684
+ for (const category of categories) {
2685
+ const categoryPath = joinPath(templatesPath, category);
2686
+ if (!await pathExists(categoryPath)) {
2687
+ logger.debug(`Category path not found: ${categoryPath}`);
2688
+ continue;
2689
+ }
2690
+ const modules = await loadCategoryModules(categoryPath, category);
2691
+ registry[category] = modules;
2692
+ }
2693
+ return registry;
2694
+ }
2695
+ async function loadCategoryModules(categoryPath, category) {
2696
+ const registryPath = joinPath(categoryPath, REGISTRY_FILE);
2697
+ if (await pathExists(registryPath)) {
2698
+ try {
2699
+ const registryFile = await readJson(registryPath);
2700
+ return registryFile.modules.map((item) => ({
2701
+ id: item.id,
2702
+ name: item.name,
2703
+ description: item.description || "",
2704
+ category,
2705
+ file: item.file,
2706
+ dependencies: item.dependencies || [],
2707
+ tags: item.tags || []
2708
+ }));
2709
+ } catch (error) {
2710
+ logger.debug(`Failed to load registry from ${registryPath}: ${error}`);
2711
+ }
2712
+ }
2713
+ return scanCategoryDirectory(categoryPath, category);
2714
+ }
2715
+ async function scanCategoryDirectory(categoryPath, category) {
2716
+ const modules = [];
2717
+ const subdirs = await listDirs("*", { cwd: categoryPath });
2718
+ for (const subdir of subdirs) {
2719
+ if (subdir.startsWith("_")) continue;
2720
+ const subdirPath = joinPath(categoryPath, subdir);
2721
+ const files = await scanForModuleFiles(subdirPath);
2722
+ for (const file of files) {
2723
+ const id = file.replace(".md", "");
2724
+ modules.push({
2725
+ id,
2726
+ name: formatName(id),
2727
+ description: "",
2728
+ category,
2729
+ file: `${subdir}/${file}`,
2730
+ dependencies: [],
2731
+ tags: [subdir]
2732
+ });
2733
+ }
2734
+ }
2735
+ const rootFiles = await scanForModuleFiles(categoryPath);
2736
+ for (const file of rootFiles) {
2737
+ if (file === REGISTRY_FILE) continue;
2738
+ const id = file.replace(".md", "");
2739
+ modules.push({
2740
+ id,
2741
+ name: formatName(id),
2742
+ description: "",
2743
+ category,
2744
+ file,
2745
+ dependencies: [],
2746
+ tags: []
2747
+ });
2748
+ }
2749
+ return modules;
2750
+ }
2751
+ async function scanForModuleFiles(dirPath) {
2752
+ const { glob: glob2 } = await import("glob");
2753
+ const files = await glob2("*.md", { cwd: dirPath });
2754
+ return files.filter((f) => !f.startsWith("_") && f !== "README.md");
2755
+ }
2756
+ function formatName(id) {
2757
+ return id.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
2758
+ }
2759
+ function getModule(registry, category, id) {
2760
+ return registry[category].find((m) => m.id === id);
2761
+ }
2762
+
2763
+ // src/lib/modules/resolver.ts
2764
+ init_cjs_shims();
2765
+ function resolveModules(registry, category, selectedIds) {
2766
+ const resolved = /* @__PURE__ */ new Map();
2767
+ const unresolved = [];
2768
+ const circular = [];
2769
+ const visiting = /* @__PURE__ */ new Set();
2770
+ let order = 0;
2771
+ function visit(id) {
2772
+ if (resolved.has(id)) return true;
2773
+ if (visiting.has(id)) {
2774
+ circular.push(id);
2775
+ return false;
2776
+ }
2777
+ const module2 = getModule(registry, category, id);
2778
+ if (!module2) {
2779
+ unresolved.push(id);
2780
+ return false;
2781
+ }
2782
+ visiting.add(id);
2783
+ const resolvedDeps = [];
2784
+ for (const depId of module2.dependencies || []) {
2785
+ if (visit(depId)) {
2786
+ resolvedDeps.push(depId);
2787
+ }
2788
+ }
2789
+ visiting.delete(id);
2790
+ resolved.set(id, {
2791
+ ...module2,
2792
+ resolvedDependencies: resolvedDeps,
2793
+ installOrder: order++
2794
+ });
2795
+ return true;
2796
+ }
2797
+ for (const id of selectedIds) {
2798
+ visit(id);
2799
+ }
2800
+ return {
2801
+ resolved: Array.from(resolved.values()).sort((a, b) => a.installOrder - b.installOrder),
2802
+ unresolved,
2803
+ circular
2804
+ };
2805
+ }
2806
+
2807
+ // src/lib/modules/installer.ts
2808
+ init_cjs_shims();
2809
+ init_fs();
2810
+
2811
+ // src/lib/utils/spinner.ts
2812
+ init_cjs_shims();
2813
+ var import_ora = __toESM(require("ora"), 1);
2814
+ var import_picocolors = __toESM(require("picocolors"), 1);
2815
+ var SpinnerManager = class {
2816
+ spinner = null;
2817
+ silent = false;
2818
+ configure(options) {
2819
+ if (options.silent !== void 0) this.silent = options.silent;
2820
+ }
2821
+ /**
2822
+ * Start a spinner with a message
2823
+ */
2824
+ start(text, options) {
2825
+ if (this.silent) return null;
2826
+ this.stop();
2827
+ this.spinner = (0, import_ora.default)({
2828
+ text,
2829
+ color: options?.color || "cyan",
2830
+ spinner: "dots"
2831
+ }).start();
2832
+ return this.spinner;
2833
+ }
2834
+ /**
2835
+ * Update spinner text
2836
+ */
2837
+ text(text) {
2838
+ if (this.spinner) {
2839
+ this.spinner.text = text;
2840
+ }
2841
+ }
2842
+ /**
2843
+ * Stop spinner with success message
2844
+ */
2845
+ succeed(text) {
2846
+ if (this.spinner) {
2847
+ this.spinner.succeed(text);
2848
+ this.spinner = null;
2849
+ }
2850
+ }
2851
+ /**
2852
+ * Stop spinner with failure message
2853
+ */
2854
+ fail(text) {
2855
+ if (this.spinner) {
2856
+ this.spinner.fail(text);
2857
+ this.spinner = null;
2858
+ }
2859
+ }
2860
+ /**
2861
+ * Stop spinner with warning message
2862
+ */
2863
+ warn(text) {
2864
+ if (this.spinner) {
2865
+ this.spinner.warn(text);
2866
+ this.spinner = null;
2867
+ }
2868
+ }
2869
+ /**
2870
+ * Stop spinner with info message
2871
+ */
2872
+ info(text) {
2873
+ if (this.spinner) {
2874
+ this.spinner.info(text);
2875
+ this.spinner = null;
2876
+ }
2877
+ }
2878
+ /**
2879
+ * Stop spinner without message
2880
+ */
2881
+ stop() {
2882
+ if (this.spinner) {
2883
+ this.spinner.stop();
2884
+ this.spinner = null;
2885
+ }
2886
+ }
2887
+ /**
2888
+ * Check if spinner is running
2889
+ */
2890
+ isRunning() {
2891
+ return this.spinner?.isSpinning ?? false;
2892
+ }
2893
+ };
2894
+ var spinner = new SpinnerManager();
2895
+ async function withSpinner(text, operation, options) {
2896
+ if (options?.silent) {
2897
+ return operation();
2898
+ }
2899
+ spinner.start(text);
2900
+ try {
2901
+ const result = await operation();
2902
+ spinner.succeed(options?.successText || text);
2903
+ return result;
2904
+ } catch (error) {
2905
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
2906
+ spinner.fail(options?.failText || `${text} - ${import_picocolors.default.red(errorMessage)}`);
2907
+ throw error;
2908
+ }
2909
+ }
2910
+
2911
+ // src/lib/modules/installer.ts
2912
+ function removeConfigRequiredFromFrontmatter(content) {
2913
+ const frontmatterRegex = /^---\n([\s\S]*?)\n---/;
2914
+ const match = content.match(frontmatterRegex);
2915
+ if (!match) {
2916
+ return content;
2917
+ }
2918
+ const frontmatter = match[1];
2919
+ const configRequiredRegex = /config_required:\s*\n(?:\s+-\s+[^\n]+\n?)*/g;
2920
+ const cleanedFrontmatter = frontmatter.replace(configRequiredRegex, "").trim();
2921
+ const restOfFile = content.slice(match[0].length);
2922
+ if (cleanedFrontmatter.trim() === "") {
2923
+ return restOfFile.trim();
2924
+ }
2925
+ return `---
2926
+ ${cleanedFrontmatter}
2927
+ ---${restOfFile}`;
2928
+ }
2929
+ async function processModuleFile(filePath) {
2930
+ if (!filePath.endsWith(".md")) {
2931
+ return;
2932
+ }
2933
+ try {
2934
+ const content = await readFile(filePath);
2935
+ const cleanedContent = removeConfigRequiredFromFrontmatter(content);
2936
+ if (cleanedContent !== content) {
2937
+ await writeFile(filePath, cleanedContent);
2938
+ logger.debug(`Cleaned config_required from: ${filePath}`);
2939
+ }
2940
+ } catch (error) {
2941
+ logger.debug(`Failed to process module file ${filePath}: ${error}`);
2942
+ }
2943
+ }
2944
+ async function installModules(category, modules, options) {
2945
+ const result = {
2946
+ success: true,
2947
+ installed: [],
2948
+ skipped: [],
2949
+ failed: []
2950
+ };
2951
+ const categorySourcePath = joinPath(options.templatesPath, category);
2952
+ const categoryTargetPath = joinPath(options.targetPath, ".claude", category);
2953
+ if (!options.dryRun) {
2954
+ await ensureDir(categoryTargetPath);
2955
+ }
2956
+ for (const module2 of modules) {
2957
+ try {
2958
+ const sourcePath = joinPath(categorySourcePath, module2.file);
2959
+ const targetPath = joinPath(categoryTargetPath, module2.file);
2960
+ if (!await pathExists(sourcePath)) {
2961
+ result.failed.push({ id: module2.id, error: `Source file not found: ${sourcePath}` });
2962
+ result.success = false;
2963
+ continue;
2964
+ }
2965
+ const targetExists = await pathExists(targetPath);
2966
+ if (targetExists && !options.overwrite) {
2967
+ result.skipped.push(module2.id);
2968
+ continue;
2969
+ }
2970
+ if (options.dryRun) {
2971
+ logger.debug(`Would install: ${module2.id} -> ${targetPath}`);
2972
+ result.installed.push(module2.id);
2973
+ continue;
2974
+ }
2975
+ await ensureDir(dirname(targetPath));
2976
+ await copy(sourcePath, targetPath, { overwrite: options.overwrite });
2977
+ await processModuleFile(targetPath);
2978
+ result.installed.push(module2.id);
2979
+ logger.debug(`Installed: ${module2.id}`);
2980
+ } catch (error) {
2981
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
2982
+ result.failed.push({ id: module2.id, error: errorMessage });
2983
+ result.success = false;
2984
+ }
2985
+ }
2986
+ return result;
2987
+ }
2988
+
2989
+ // src/lib/placeholders/index.ts
2990
+ init_cjs_shims();
2991
+
2992
+ // src/lib/placeholders/replacer.ts
2993
+ init_cjs_shims();
2994
+ init_fs();
2995
+ async function replaceInFile(filePath, projectInfo, placeholders = PLACEHOLDERS) {
2996
+ const replacements = [];
2997
+ let content = await readFile(filePath);
2998
+ let modified = false;
2999
+ for (const placeholder of placeholders) {
3000
+ const value = projectInfo[placeholder.configKey];
3001
+ if (value === void 0 || value === null) {
3002
+ continue;
3003
+ }
3004
+ const transformedValue = applyTransform(String(value), placeholder.transform);
3005
+ const pattern = placeholder.pattern;
3006
+ if (pattern instanceof RegExp) {
3007
+ const matches = content.matchAll(new RegExp(pattern.source, "g"));
3008
+ for (const match of matches) {
3009
+ const lineNumber = getLineNumber(content, match.index ?? 0);
3010
+ replacements.push({
3011
+ file: filePath,
3012
+ line: lineNumber,
3013
+ original: match[0],
3014
+ replacement: transformedValue,
3015
+ placeholder
3016
+ });
3017
+ }
3018
+ if (pattern.test(content)) {
3019
+ content = content.replace(pattern, transformedValue);
3020
+ modified = true;
3021
+ }
3022
+ } else {
3023
+ const regex = new RegExp(escapeRegex(pattern), "g");
3024
+ const matches = content.matchAll(regex);
3025
+ for (const match of matches) {
3026
+ const lineNumber = getLineNumber(content, match.index ?? 0);
3027
+ replacements.push({
3028
+ file: filePath,
3029
+ line: lineNumber,
3030
+ original: match[0],
3031
+ replacement: transformedValue,
3032
+ placeholder
3033
+ });
3034
+ }
3035
+ if (content.includes(pattern)) {
3036
+ content = content.replace(regex, transformedValue);
3037
+ modified = true;
3038
+ }
3039
+ }
3040
+ }
3041
+ if (modified) {
3042
+ await writeFile(filePath, content);
3043
+ }
3044
+ return replacements;
3045
+ }
3046
+ async function replaceInDirectory(dirPath, projectInfo, options) {
3047
+ const extensions = options?.extensions || ["md", "json", "yaml", "yml", "ts", "js", "tsx", "jsx"];
3048
+ const exclude = options?.exclude || ["node_modules", ".git", "dist", "build"];
3049
+ const pattern = `**/*.{${extensions.join(",")}}`;
3050
+ const files = await listFiles(pattern, {
3051
+ cwd: dirPath,
3052
+ ignore: exclude.map((e) => `**/${e}/**`)
3053
+ });
3054
+ const report = {
3055
+ totalFiles: files.length,
3056
+ filesModified: 0,
3057
+ replacements: [],
3058
+ unreplacedPlaceholders: []
3059
+ };
3060
+ for (const file of files) {
3061
+ const filePath = joinPath(dirPath, file);
3062
+ try {
3063
+ const replacements = options?.dryRun ? await scanFile(filePath, projectInfo) : await replaceInFile(filePath, projectInfo);
3064
+ if (replacements.length > 0) {
3065
+ report.filesModified++;
3066
+ report.replacements.push(...replacements);
3067
+ }
3068
+ } catch (error) {
3069
+ logger.debug(`Failed to process ${file}: ${error}`);
3070
+ }
3071
+ }
3072
+ report.unreplacedPlaceholders = findUnreplacedPlaceholders(projectInfo);
3073
+ return report;
3074
+ }
3075
+ async function scanFile(filePath, projectInfo) {
3076
+ const replacements = [];
3077
+ const content = await readFile(filePath);
3078
+ for (const placeholder of PLACEHOLDERS) {
3079
+ const value = projectInfo[placeholder.configKey];
3080
+ if (value === void 0 || value === null) {
3081
+ continue;
3082
+ }
3083
+ const transformedValue = applyTransform(String(value), placeholder.transform);
3084
+ const pattern = placeholder.pattern;
3085
+ const regex = pattern instanceof RegExp ? new RegExp(pattern.source, "g") : new RegExp(escapeRegex(pattern), "g");
3086
+ const matches = content.matchAll(regex);
3087
+ for (const match of matches) {
3088
+ const lineNumber = getLineNumber(content, match.index ?? 0);
3089
+ replacements.push({
3090
+ file: filePath,
3091
+ line: lineNumber,
3092
+ original: match[0],
3093
+ replacement: transformedValue,
3094
+ placeholder
3095
+ });
3096
+ }
3097
+ }
3098
+ return replacements;
3099
+ }
3100
+ async function replacePlaceholders(dirPath, projectInfo, options) {
3101
+ return withSpinner(
3102
+ "Replacing placeholders...",
3103
+ () => replaceInDirectory(dirPath, projectInfo, options),
3104
+ {
3105
+ successText: "Placeholders replaced",
3106
+ silent: options?.silent || options?.dryRun
3107
+ }
3108
+ );
3109
+ }
3110
+ function findUnreplacedPlaceholders(projectInfo) {
3111
+ const unreplaced = [];
3112
+ for (const placeholder of PLACEHOLDERS) {
3113
+ if (!placeholder.required) continue;
3114
+ const value = projectInfo[placeholder.configKey];
3115
+ if (value === void 0 || value === null || value === "") {
3116
+ const patternStr = placeholder.pattern instanceof RegExp ? placeholder.pattern.source : placeholder.pattern;
3117
+ unreplaced.push(patternStr);
3118
+ }
3119
+ }
3120
+ return unreplaced;
3121
+ }
3122
+ function getLineNumber(content, index) {
3123
+ return content.slice(0, index).split("\n").length;
3124
+ }
3125
+ function escapeRegex(str) {
3126
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3127
+ }
3128
+
3129
+ // src/lib/scaffold/detector.ts
3130
+ init_cjs_shims();
3131
+ init_fs();
3132
+ async function detectProject(projectPath) {
3133
+ const signals = [];
3134
+ const packageJsonPath = joinPath(projectPath, "package.json");
3135
+ const hasPackageJson = await pathExists(packageJsonPath);
3136
+ if (!hasPackageJson) {
3137
+ return {
3138
+ detected: false,
3139
+ confidence: "low",
3140
+ signals: [{ file: "package.json", exists: false, indicates: "not a Node.js project" }]
3141
+ };
3142
+ }
3143
+ signals.push({ file: "package.json", exists: true, indicates: "Node.js project" });
3144
+ const packageJson = await readJson(packageJsonPath).catch(() => ({}));
3145
+ const packageManager = await detectPackageManager(projectPath);
3146
+ if (packageManager) {
3147
+ signals.push({
3148
+ file: `${packageManager}-lock`,
3149
+ exists: true,
3150
+ indicates: `${packageManager} package manager`
3151
+ });
3152
+ }
3153
+ const typeResult = await detectProjectType(projectPath, packageJson);
3154
+ const projectType = typeResult.type;
3155
+ signals.push(...typeResult.signals);
3156
+ const confidence = projectType && packageManager ? "high" : projectType || packageManager ? "medium" : "low";
3157
+ const suggestedBundles = suggestBundles(projectType, packageJson);
3158
+ return {
3159
+ detected: true,
3160
+ projectType,
3161
+ packageManager,
3162
+ suggestedBundles,
3163
+ confidence,
3164
+ signals
3165
+ };
3166
+ }
3167
+ async function detectPackageManager(projectPath) {
3168
+ const lockFiles = [
3169
+ { file: "pnpm-lock.yaml", manager: "pnpm" },
3170
+ { file: "yarn.lock", manager: "yarn" },
3171
+ { file: "package-lock.json", manager: "npm" },
3172
+ { file: "bun.lockb", manager: "bun" }
3173
+ ];
3174
+ for (const { file, manager } of lockFiles) {
3175
+ if (await pathExists(joinPath(projectPath, file))) {
3176
+ return manager;
3177
+ }
3178
+ }
3179
+ return void 0;
3180
+ }
3181
+ async function detectProjectType(projectPath, packageJson) {
3182
+ const signals = [];
3183
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
3184
+ if (await pathExists(joinPath(projectPath, "turbo.json")) || await pathExists(joinPath(projectPath, "pnpm-workspace.yaml")) || packageJson.workspaces) {
3185
+ signals.push({ file: "turbo.json/pnpm-workspace.yaml", exists: true, indicates: "monorepo" });
3186
+ return { type: "monorepo", signals };
3187
+ }
3188
+ if (await pathExists(joinPath(projectPath, "astro.config.mjs")) || await pathExists(joinPath(projectPath, "astro.config.ts")) || deps.astro) {
3189
+ signals.push({ file: "astro.config.*", exists: true, indicates: "Astro project" });
3190
+ return { type: "astro", signals };
3191
+ }
3192
+ if (await pathExists(joinPath(projectPath, "next.config.js")) || await pathExists(joinPath(projectPath, "next.config.mjs")) || await pathExists(joinPath(projectPath, "next.config.ts")) || deps.next) {
3193
+ signals.push({ file: "next.config.*", exists: true, indicates: "Next.js project" });
3194
+ return { type: "nextjs", signals };
3195
+ }
3196
+ if ((await pathExists(joinPath(projectPath, "vite.config.ts")) || await pathExists(joinPath(projectPath, "vite.config.js"))) && (deps.react || deps["react-dom"])) {
3197
+ signals.push({ file: "vite.config.*", exists: true, indicates: "Vite project" });
3198
+ signals.push({ file: "react dependency", exists: true, indicates: "React project" });
3199
+ return { type: "vite-react", signals };
3200
+ }
3201
+ if (deps.hono) {
3202
+ signals.push({ file: "hono dependency", exists: true, indicates: "Hono API project" });
3203
+ return { type: "hono", signals };
3204
+ }
3205
+ if (deps.typescript || await pathExists(joinPath(projectPath, "tsconfig.json"))) {
3206
+ signals.push({ file: "tsconfig.json", exists: true, indicates: "TypeScript project" });
3207
+ return { type: "node", signals };
3208
+ }
3209
+ return { type: "node", signals };
3210
+ }
3211
+ function suggestBundles(projectType, packageJson) {
3212
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
3213
+ const suggestedBundles = [];
3214
+ const hasHono = deps.hono || deps["@hono/node-server"];
3215
+ const hasExpress = deps.express;
3216
+ const hasFastify = deps.fastify;
3217
+ const hasNestjs = deps["@nestjs/core"];
3218
+ const hasDrizzle = deps.drizzle || deps["drizzle-orm"];
3219
+ const hasPrisma = deps.prisma || deps["@prisma/client"];
3220
+ const hasMongoose = deps.mongoose;
3221
+ const hasReact = deps.react;
3222
+ const hasTanstack = deps["@tanstack/react-router"] || deps["@tanstack/start"];
3223
+ switch (projectType) {
3224
+ case "astro":
3225
+ suggestedBundles.push("astro-react-stack");
3226
+ break;
3227
+ case "nextjs":
3228
+ if (hasPrisma) {
3229
+ suggestedBundles.push("nextjs-prisma-stack");
3230
+ } else {
3231
+ suggestedBundles.push("react-tanstack-stack");
3232
+ }
3233
+ break;
3234
+ case "vite-react":
3235
+ suggestedBundles.push("react-tanstack-stack");
3236
+ break;
3237
+ case "hono":
3238
+ if (hasDrizzle) {
3239
+ suggestedBundles.push("hono-drizzle-stack");
3240
+ } else if (hasPrisma) {
3241
+ suggestedBundles.push("hono-api");
3242
+ suggestedBundles.push("prisma-database");
3243
+ } else {
3244
+ suggestedBundles.push("hono-api");
3245
+ }
3246
+ break;
3247
+ case "monorepo":
3248
+ if (hasReact && hasTanstack) {
3249
+ suggestedBundles.push("react-tanstack-stack");
3250
+ }
3251
+ if (hasHono && hasDrizzle) {
3252
+ suggestedBundles.push("hono-drizzle-stack");
3253
+ } else if (hasHono) {
3254
+ suggestedBundles.push("hono-api");
3255
+ }
3256
+ break;
3257
+ case "node":
3258
+ if (hasHono) {
3259
+ if (hasDrizzle) {
3260
+ suggestedBundles.push("hono-drizzle-stack");
3261
+ } else {
3262
+ suggestedBundles.push("hono-api");
3263
+ }
3264
+ } else if (hasExpress) {
3265
+ if (hasPrisma) {
3266
+ suggestedBundles.push("express-prisma-stack");
3267
+ } else {
3268
+ suggestedBundles.push("express-api");
3269
+ }
3270
+ } else if (hasFastify) {
3271
+ suggestedBundles.push("fastify-api");
3272
+ } else if (hasNestjs) {
3273
+ suggestedBundles.push("nestjs-api");
3274
+ }
3275
+ break;
3276
+ }
3277
+ if (hasDrizzle && !suggestedBundles.some((b) => b.includes("drizzle"))) {
3278
+ suggestedBundles.push("drizzle-database");
3279
+ }
3280
+ if (hasPrisma && !suggestedBundles.some((b) => b.includes("prisma"))) {
3281
+ suggestedBundles.push("prisma-database");
3282
+ }
3283
+ if (hasMongoose) {
3284
+ suggestedBundles.push("mongoose-database");
3285
+ }
3286
+ if (suggestedBundles.length > 0) {
3287
+ suggestedBundles.push("testing-minimal");
3288
+ suggestedBundles.push("quality-minimal");
3289
+ }
3290
+ suggestedBundles.push("git-workflow");
3291
+ return suggestedBundles;
3292
+ }
3293
+
3294
+ // src/lib/templates/index.ts
3295
+ init_cjs_shims();
3296
+
3297
+ // src/lib/templates/parser.ts
3298
+ init_cjs_shims();
3299
+ var DIRECTIVE_PATTERNS = {
3300
+ // Block directives: {{#type expression}}...{{/type}}
3301
+ block: /\{\{#(if|unless|each|section)\s+([^}]+)\}\}([\s\S]*?)\{\{\/\1\}\}/g,
3302
+ // Include directive: {{> partialName}}
3303
+ include: /\{\{>\s*([^}]+)\}\}/g,
3304
+ // Variable with optional transform: {{variable}} or {{variable | transform}}
3305
+ variable: /\{\{([^#/>][^}|]*?)(?:\s*\|\s*(\w+))?\}\}/g
3306
+ };
3307
+ function parseDirectives(content) {
3308
+ const directives = [];
3309
+ const blockMatches = content.matchAll(DIRECTIVE_PATTERNS.block);
3310
+ for (const match of blockMatches) {
3311
+ const [fullMatch, type, expression, innerContent] = match;
3312
+ const startIndex = match.index ?? 0;
3313
+ directives.push({
3314
+ type,
3315
+ match: fullMatch,
3316
+ expression: expression.trim(),
3317
+ content: innerContent,
3318
+ startIndex,
3319
+ endIndex: startIndex + fullMatch.length,
3320
+ nested: parseDirectives(innerContent)
3321
+ // Recursive parse for nested directives
3322
+ });
3323
+ }
3324
+ const includeMatches = content.matchAll(DIRECTIVE_PATTERNS.include);
3325
+ for (const match of includeMatches) {
3326
+ const [fullMatch, partialName] = match;
3327
+ const startIndex = match.index ?? 0;
3328
+ directives.push({
3329
+ type: "include",
3330
+ match: fullMatch,
3331
+ expression: partialName.trim(),
3332
+ startIndex,
3333
+ endIndex: startIndex + fullMatch.length
3334
+ });
3335
+ }
3336
+ return directives;
3337
+ }
3338
+ function parseExpression(expression) {
3339
+ const comparisonMatch = expression.match(/^(\S+)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);
3340
+ if (comparisonMatch) {
3341
+ const [, variable2, operator, compareValue] = comparisonMatch;
3342
+ return {
3343
+ variable: variable2.trim(),
3344
+ path: variable2.trim().split("."),
3345
+ operator,
3346
+ compareValue: compareValue.trim().replace(/^["']|["']$/g, "")
3347
+ };
3348
+ }
3349
+ if (expression.startsWith("!")) {
3350
+ const variable2 = expression.slice(1).trim();
3351
+ return {
3352
+ variable: variable2,
3353
+ path: variable2.split("."),
3354
+ operator: "!"
3355
+ };
3356
+ }
3357
+ const variable = expression.trim();
3358
+ return {
3359
+ variable,
3360
+ path: variable.split(".")
3361
+ };
3362
+ }
3363
+ function findVariables(content) {
3364
+ const variables = [];
3365
+ const matches = content.matchAll(DIRECTIVE_PATTERNS.variable);
3366
+ for (const match of matches) {
3367
+ const [fullMatch, variable, transform] = match;
3368
+ if (variable.startsWith("#") || variable.startsWith("/") || variable.startsWith(">")) {
3369
+ continue;
3370
+ }
3371
+ variables.push({
3372
+ match: fullMatch,
3373
+ variable: variable.trim(),
3374
+ transform: transform?.trim(),
3375
+ index: match.index ?? 0
3376
+ });
3377
+ }
3378
+ return variables;
3379
+ }
3380
+ function hasDirectives(content) {
3381
+ return /\{\{[#/>]?\s*\w/.test(content);
3382
+ }
3383
+ function validateTemplate(content) {
3384
+ const errors = [];
3385
+ const openBlocks = [];
3386
+ const openMatches = content.matchAll(/\{\{#(if|unless|each|section)\s+[^}]+\}\}/g);
3387
+ for (const match of openMatches) {
3388
+ openBlocks.push({
3389
+ type: match[1],
3390
+ index: match.index ?? 0
3391
+ });
3392
+ }
3393
+ const closeMatches = content.matchAll(/\{\{\/(if|unless|each|section)\}\}/g);
3394
+ const closeBlocks = [];
3395
+ for (const match of closeMatches) {
3396
+ closeBlocks.push(match[1]);
3397
+ }
3398
+ if (openBlocks.length !== closeBlocks.length) {
3399
+ errors.push(
3400
+ `Mismatched block directives: ${openBlocks.length} opening, ${closeBlocks.length} closing`
3401
+ );
3402
+ }
3403
+ const unclosedVars = content.match(/\{\{(?![^}]*\}\})/g);
3404
+ if (unclosedVars) {
3405
+ errors.push(`Found ${unclosedVars.length} unclosed variable reference(s)`);
3406
+ }
3407
+ return {
3408
+ valid: errors.length === 0,
3409
+ errors
3410
+ };
3411
+ }
3412
+
3413
+ // src/lib/templates/evaluator.ts
3414
+ init_cjs_shims();
3415
+ function getContextValue(context, path5) {
3416
+ const parts = path5.split(".");
3417
+ let current = context;
3418
+ for (const part of parts) {
3419
+ if (current === void 0 || current === null) {
3420
+ return void 0;
3421
+ }
3422
+ current = current[part];
3423
+ }
3424
+ return current;
3425
+ }
3426
+ function evaluateCondition(expression, context) {
3427
+ const parsed = parseExpression(expression);
3428
+ if (expression.includes("&&")) {
3429
+ const parts = expression.split("&&").map((p) => p.trim());
3430
+ return parts.every((part) => evaluateCondition(part, context));
3431
+ }
3432
+ if (expression.includes("||")) {
3433
+ const parts = expression.split("||").map((p) => p.trim());
3434
+ return parts.some((part) => evaluateCondition(part, context));
3435
+ }
3436
+ const value = getContextValue(context, parsed.variable);
3437
+ if (parsed.operator === "!") {
3438
+ return !isTruthy(value);
3439
+ }
3440
+ if (parsed.operator && parsed.compareValue !== void 0) {
3441
+ const compareValue = parsed.compareValue;
3442
+ switch (parsed.operator) {
3443
+ case "==":
3444
+ return String(value) === compareValue;
3445
+ case "!=":
3446
+ return String(value) !== compareValue;
3447
+ case ">":
3448
+ return Number(value) > Number(compareValue);
3449
+ case ">=":
3450
+ return Number(value) >= Number(compareValue);
3451
+ case "<":
3452
+ return Number(value) < Number(compareValue);
3453
+ case "<=":
3454
+ return Number(value) <= Number(compareValue);
3455
+ default:
3456
+ return false;
3457
+ }
3458
+ }
3459
+ if (expression.includes(".includes(")) {
3460
+ const match = expression.match(/^(.+?)\.includes\(["'](.+?)["']\)$/);
3461
+ if (match) {
3462
+ const [, arrayPath, searchValue] = match;
3463
+ const arrayValue = getContextValue(context, arrayPath);
3464
+ if (Array.isArray(arrayValue)) {
3465
+ return arrayValue.includes(searchValue);
3466
+ }
3467
+ }
3468
+ return false;
3469
+ }
3470
+ if (expression.startsWith("has ")) {
3471
+ const match = expression.match(/^has\s+(\S+)\s+["']?(.+?)["']?$/);
3472
+ if (match) {
3473
+ const [, arrayPath, searchValue] = match;
3474
+ const arrayValue = getContextValue(context, arrayPath);
3475
+ if (Array.isArray(arrayValue)) {
3476
+ return arrayValue.includes(searchValue);
3477
+ }
3478
+ }
3479
+ return false;
3480
+ }
3481
+ return isTruthy(value);
3482
+ }
3483
+ function isTruthy(value) {
3484
+ if (value === void 0 || value === null) {
3485
+ return false;
3486
+ }
3487
+ if (typeof value === "boolean") {
3488
+ return value;
3489
+ }
3490
+ if (typeof value === "string") {
3491
+ return value.length > 0;
3492
+ }
3493
+ if (typeof value === "number") {
3494
+ return value !== 0;
3495
+ }
3496
+ if (Array.isArray(value)) {
3497
+ return value.length > 0;
3498
+ }
3499
+ if (typeof value === "object") {
3500
+ return Object.keys(value).length > 0;
3501
+ }
3502
+ return Boolean(value);
3503
+ }
3504
+ function getIterable(expression, context) {
3505
+ const value = getContextValue(context, expression);
3506
+ if (Array.isArray(value)) {
3507
+ return value.map((item, index) => ({ item, index }));
3508
+ }
3509
+ if (typeof value === "object" && value !== null) {
3510
+ return Object.entries(value).map(([key, item], index) => ({
3511
+ item,
3512
+ index,
3513
+ key
3514
+ }));
3515
+ }
3516
+ return [];
3517
+ }
3518
+ function applyTemplateTransform(value, transform) {
3519
+ if (value === void 0 || value === null) {
3520
+ return "";
3521
+ }
3522
+ const strValue = Array.isArray(value) ? value.join(", ") : String(value);
3523
+ switch (transform.toLowerCase()) {
3524
+ case "lowercase":
3525
+ case "lower":
3526
+ return strValue.toLowerCase();
3527
+ case "uppercase":
3528
+ case "upper":
3529
+ return strValue.toUpperCase();
3530
+ case "capitalize":
3531
+ case "title":
3532
+ return strValue.split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
3533
+ case "kebab":
3534
+ case "kebabcase":
3535
+ return strValue.toLowerCase().replace(/\s+/g, "-");
3536
+ case "snake":
3537
+ case "snakecase":
3538
+ return strValue.toLowerCase().replace(/\s+/g, "_");
3539
+ case "camel":
3540
+ case "camelcase":
3541
+ return strValue.split(/[\s-_]+/).map(
3542
+ (word, i) => i === 0 ? word.toLowerCase() : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
3543
+ ).join("");
3544
+ case "pascal":
3545
+ case "pascalcase":
3546
+ return strValue.split(/[\s-_]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
3547
+ case "json":
3548
+ return JSON.stringify(value);
3549
+ case "count":
3550
+ return String(Array.isArray(value) ? value.length : strValue.length);
3551
+ case "first":
3552
+ if (Array.isArray(value)) {
3553
+ return String(value[0] ?? "");
3554
+ }
3555
+ return strValue;
3556
+ case "last":
3557
+ if (Array.isArray(value)) {
3558
+ return String(value[value.length - 1] ?? "");
3559
+ }
3560
+ return strValue;
3561
+ case "join":
3562
+ if (Array.isArray(value)) {
3563
+ return value.join(", ");
3564
+ }
3565
+ return strValue;
3566
+ case "joinlines":
3567
+ if (Array.isArray(value)) {
3568
+ return value.join("\n");
3569
+ }
3570
+ return strValue;
3571
+ case "bullet":
3572
+ case "bullets":
3573
+ if (Array.isArray(value)) {
3574
+ return value.map((v) => `- ${v}`).join("\n");
3575
+ }
3576
+ return `- ${strValue}`;
3577
+ case "numbered":
3578
+ if (Array.isArray(value)) {
3579
+ return value.map((v, i) => `${i + 1}. ${v}`).join("\n");
3580
+ }
3581
+ return `1. ${strValue}`;
3582
+ default:
3583
+ return strValue;
3584
+ }
3585
+ }
3586
+ function createLoopContext(parentContext, itemValue, index, key) {
3587
+ return {
3588
+ ...parentContext,
3589
+ item: itemValue,
3590
+ index,
3591
+ key
3592
+ };
3593
+ }
3594
+
3595
+ // src/lib/templates/processor.ts
3596
+ init_cjs_shims();
3597
+ init_fs();
3598
+ function processTemplate(content, context) {
3599
+ const result = {
3600
+ content,
3601
+ modified: false,
3602
+ directivesProcessed: 0,
3603
+ warnings: [],
3604
+ errors: []
3605
+ };
3606
+ const validation = validateTemplate(content);
3607
+ if (!validation.valid) {
3608
+ result.errors.push(...validation.errors);
3609
+ return result;
3610
+ }
3611
+ if (!hasDirectives(content)) {
3612
+ return result;
3613
+ }
3614
+ try {
3615
+ result.content = processBlockDirectives(result.content, context, result);
3616
+ result.content = processVariables(result.content, context, result);
3617
+ result.content = cleanupEmptyLines(result.content);
3618
+ result.modified = result.content !== content;
3619
+ } catch (error) {
3620
+ result.errors.push(`Template processing error: ${error}`);
3621
+ }
3622
+ return result;
3623
+ }
3624
+ function processBlockDirectives(content, context, result) {
3625
+ const directives = parseDirectives(content);
3626
+ const sortedDirectives = [...directives].sort((a, b) => b.startIndex - a.startIndex);
3627
+ for (const directive of sortedDirectives) {
3628
+ const replacement = processDirective(directive, context, result);
3629
+ content = content.slice(0, directive.startIndex) + replacement + content.slice(directive.endIndex);
3630
+ result.directivesProcessed++;
3631
+ }
3632
+ return content;
3633
+ }
3634
+ function processDirective(directive, context, result) {
3635
+ switch (directive.type) {
3636
+ case "if":
3637
+ return processIfDirective(directive, context, result);
3638
+ case "unless":
3639
+ return processUnlessDirective(directive, context, result);
3640
+ case "each":
3641
+ return processEachDirective(directive, context, result);
3642
+ case "section":
3643
+ return processSectionDirective(directive, context, result);
3644
+ case "include":
3645
+ result.warnings.push(`Include directive not yet supported: ${directive.expression}`);
3646
+ return directive.match;
3647
+ default:
3648
+ result.warnings.push(`Unknown directive type: ${directive.type}`);
3649
+ return directive.match;
3650
+ }
3651
+ }
3652
+ function processIfDirective(directive, context, result) {
3653
+ const condition = evaluateCondition(directive.expression, context);
3654
+ if (condition) {
3655
+ const innerContent = directive.content ?? "";
3656
+ const innerResult = processTemplate(innerContent, context);
3657
+ result.warnings.push(...innerResult.warnings);
3658
+ result.errors.push(...innerResult.errors);
3659
+ return innerResult.content;
3660
+ }
3661
+ return "";
3662
+ }
3663
+ function processUnlessDirective(directive, context, result) {
3664
+ const condition = evaluateCondition(directive.expression, context);
3665
+ if (!condition) {
3666
+ const innerContent = directive.content ?? "";
3667
+ const innerResult = processTemplate(innerContent, context);
3668
+ result.warnings.push(...innerResult.warnings);
3669
+ result.errors.push(...innerResult.errors);
3670
+ return innerResult.content;
3671
+ }
3672
+ return "";
3673
+ }
3674
+ function processEachDirective(directive, context, result) {
3675
+ const items = getIterable(directive.expression, context);
3676
+ if (items.length === 0) {
3677
+ return "";
3678
+ }
3679
+ const outputs = [];
3680
+ for (const { item, index, key } of items) {
3681
+ const loopContext = createLoopContext(context, item, index, key);
3682
+ const innerContent = directive.content ?? "";
3683
+ const innerResult = processTemplate(innerContent, loopContext);
3684
+ result.warnings.push(...innerResult.warnings);
3685
+ result.errors.push(...innerResult.errors);
3686
+ outputs.push(innerResult.content);
3687
+ }
3688
+ return outputs.join("");
3689
+ }
3690
+ function processSectionDirective(directive, context, result) {
3691
+ const innerContent = directive.content ?? "";
3692
+ const innerResult = processTemplate(innerContent, context);
3693
+ result.warnings.push(...innerResult.warnings);
3694
+ result.errors.push(...innerResult.errors);
3695
+ return innerResult.content;
3696
+ }
3697
+ function processVariables(content, context, result) {
3698
+ const variables = findVariables(content);
3699
+ const sortedVariables = [...variables].sort((a, b) => b.index - a.index);
3700
+ for (const { match, variable, transform, index } of sortedVariables) {
3701
+ const value = getContextValue(context, variable);
3702
+ if (value !== void 0) {
3703
+ const replacement = transform ? applyTemplateTransform(value, transform) : String(value);
3704
+ content = content.slice(0, index) + replacement + content.slice(index + match.length);
3705
+ result.directivesProcessed++;
3706
+ } else {
3707
+ result.warnings.push(`Variable not found: ${variable}`);
3708
+ }
3709
+ }
3710
+ return content;
3711
+ }
3712
+ function cleanupEmptyLines(content) {
3713
+ return content.replace(/\n{3,}/g, "\n\n").trim();
3714
+ }
3715
+ async function processTemplatesInDirectory(dirPath, context, options) {
3716
+ const extensions = options?.extensions ?? ["md", "json", "yaml", "yml"];
3717
+ const exclude = options?.exclude ?? ["node_modules", ".git", "dist", "build"];
3718
+ const pattern = `**/*.{${extensions.join(",")}}`;
3719
+ const files = await listFiles(pattern, {
3720
+ cwd: dirPath,
3721
+ ignore: exclude.map((e) => `**/${e}/**`)
3722
+ });
3723
+ const report = {
3724
+ totalFiles: files.length,
3725
+ filesModified: 0,
3726
+ totalDirectives: 0,
3727
+ filesWithErrors: [],
3728
+ warnings: []
3729
+ };
3730
+ for (const file of files) {
3731
+ const filePath = joinPath(dirPath, file);
3732
+ try {
3733
+ const content = await readFile(filePath);
3734
+ if (!hasDirectives(content)) {
3735
+ continue;
3736
+ }
3737
+ const result = processTemplate(content, context);
3738
+ if (result.errors.length > 0) {
3739
+ report.filesWithErrors.push(file);
3740
+ report.warnings.push(`${file}: ${result.errors.join(", ")}`);
3741
+ continue;
3742
+ }
3743
+ if (result.modified) {
3744
+ if (!options?.dryRun) {
3745
+ await writeFile(filePath, result.content);
3746
+ }
3747
+ report.filesModified++;
3748
+ }
3749
+ report.totalDirectives += result.directivesProcessed;
3750
+ report.warnings.push(...result.warnings.map((w) => `${file}: ${w}`));
3751
+ } catch (error) {
3752
+ logger.debug(`Failed to process template ${file}: ${error}`);
3753
+ report.filesWithErrors.push(file);
3754
+ }
3755
+ }
3756
+ return report;
3757
+ }
3758
+ async function processTemplates(dirPath, context, options) {
3759
+ return withSpinner(
3760
+ "Processing templates...",
3761
+ () => processTemplatesInDirectory(dirPath, context, options),
3762
+ {
3763
+ successText: "Templates processed",
3764
+ silent: options?.silent ?? options?.dryRun
3765
+ }
3766
+ );
3767
+ }
3768
+
3769
+ // src/lib/templates/context.ts
3770
+ init_cjs_shims();
3771
+ function buildTemplateContext(config) {
3772
+ const getModuleIds2 = (selection) => {
3773
+ return selection?.selected ?? [];
3774
+ };
3775
+ const getMcpServerIds = (servers) => {
3776
+ return servers?.map((s) => s.serverId) ?? [];
3777
+ };
3778
+ const context = {
3779
+ project: {
3780
+ name: config.project?.name,
3781
+ description: config.project?.description,
3782
+ org: config.project?.org,
3783
+ repo: config.project?.repo,
3784
+ domain: config.project?.domain,
3785
+ entityType: config.project?.entityType,
3786
+ location: config.project?.location
3787
+ },
3788
+ modules: {
3789
+ agents: getModuleIds2(config.modules?.agents),
3790
+ skills: getModuleIds2(config.modules?.skills),
3791
+ commands: getModuleIds2(config.modules?.commands),
3792
+ docs: getModuleIds2(config.modules?.docs)
3793
+ },
3794
+ codeStyle: {
3795
+ formatter: config.extras?.codeStyle?.biome ? "biome" : config.extras?.codeStyle?.prettier ? "prettier" : "none",
3796
+ linter: config.extras?.codeStyle?.biome ? "biome" : "none",
3797
+ editorConfig: config.extras?.codeStyle?.editorconfig,
3798
+ commitlint: config.extras?.codeStyle?.commitlint
3799
+ },
3800
+ techStack: {},
3801
+ bundles: [],
3802
+ mcpServers: getMcpServerIds(config.mcp?.servers),
3803
+ custom: {}
3804
+ };
3805
+ context.techStack = inferTechStack(context.modules);
3806
+ return context;
3807
+ }
3808
+ function inferTechStack(modules) {
3809
+ const techStack = {};
3810
+ const allModules = [
3811
+ ...modules.agents,
3812
+ ...modules.skills,
3813
+ ...modules.commands,
3814
+ ...modules.docs
3815
+ ];
3816
+ if (allModules.some((m) => m.includes("nextjs"))) {
3817
+ techStack.framework = "nextjs";
3818
+ } else if (allModules.some((m) => m.includes("astro"))) {
3819
+ techStack.framework = "astro";
3820
+ } else if (allModules.some((m) => m.includes("tanstack-start"))) {
3821
+ techStack.framework = "tanstack-start";
3822
+ } else if (allModules.some((m) => m.includes("react"))) {
3823
+ techStack.framework = "react";
3824
+ }
3825
+ if (allModules.some((m) => m.includes("prisma"))) {
3826
+ techStack.orm = "prisma";
3827
+ } else if (allModules.some((m) => m.includes("drizzle"))) {
3828
+ techStack.orm = "drizzle";
3829
+ } else if (allModules.some((m) => m.includes("mongoose"))) {
3830
+ techStack.orm = "mongoose";
3831
+ }
3832
+ if (allModules.some((m) => m.includes("hono"))) {
3833
+ techStack.database = "hono";
3834
+ } else if (allModules.some((m) => m.includes("express"))) {
3835
+ techStack.database = "express";
3836
+ } else if (allModules.some((m) => m.includes("fastify"))) {
3837
+ techStack.database = "fastify";
3838
+ } else if (allModules.some((m) => m.includes("nestjs"))) {
3839
+ techStack.database = "nestjs";
3840
+ }
3841
+ if (allModules.some((m) => m.includes("testing") || m.includes("tdd"))) {
3842
+ techStack.testing = "vitest";
3843
+ }
3844
+ if (allModules.some((m) => m.includes("vercel"))) {
3845
+ techStack.deployment = "vercel";
3846
+ }
3847
+ return techStack;
3848
+ }
3849
+
3850
+ // src/lib/templates/scanner.ts
3851
+ init_cjs_shims();
3852
+ var fs3 = __toESM(require("fs/promises"), 1);
3853
+ var path3 = __toESM(require("path"), 1);
3854
+
3855
+ // src/constants/template-placeholders.ts
3856
+ init_cjs_shims();
3857
+
3858
+ // src/lib/templates/config-replacer.ts
3859
+ init_cjs_shims();
3860
+ var fs4 = __toESM(require("fs/promises"), 1);
3861
+ var path4 = __toESM(require("path"), 1);
3862
+ var import_ora2 = __toESM(require("ora"), 1);
3863
+ // Annotate the CommonJS export names for ESM import in node:
3864
+ 0 && (module.exports = {
3865
+ BUNDLES,
3866
+ DEPENDENCIES,
3867
+ MCP_SERVERS,
3868
+ PERMISSION_PRESETS,
3869
+ PLACEHOLDERS,
3870
+ buildTemplateContext,
3871
+ createDefaultConfig,
3872
+ detectProject,
3873
+ getAllBundles,
3874
+ getBundleById,
3875
+ hasConfig,
3876
+ installModules,
3877
+ loadRegistry,
3878
+ mergeBundleSelection,
3879
+ processTemplates,
3880
+ readConfig,
3881
+ replacePlaceholders,
3882
+ resolveBundle,
3883
+ resolveBundles,
3884
+ resolveModules,
3885
+ writeConfig
3886
+ });
3887
+ //# sourceMappingURL=index.cjs.map